d979f1ebfe705e3987bc5af0fa241141de767ccb
[platform/upstream/isl.git] / isl_input.c
1 /*
2  * Copyright 2008-2009 Katholieke Universiteit Leuven
3  * Copyright 2010      INRIA Saclay
4  *
5  * Use of this software is governed by the GNU LGPLv2.1 license
6  *
7  * Written by Sven Verdoolaege, K.U.Leuven, Departement
8  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
9  * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
10  * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France 
11  */
12
13 #include <ctype.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <strings.h>
17 #include <isl_ctx_private.h>
18 #include <isl_map_private.h>
19 #include <isl/set.h>
20 #include <isl/seq.h>
21 #include <isl/div.h>
22 #include <isl/stream.h>
23 #include <isl/obj.h>
24 #include "isl_polynomial_private.h"
25 #include <isl/union_map.h>
26 #include <isl_mat_private.h>
27
28 struct variable {
29         char                    *name;
30         int                      pos;
31         isl_vec                 *def;
32         /* non-zero if variable represents a min (-1) or a max (1) */
33         int                      sign;
34         isl_mat                 *list;
35         struct variable         *next;
36 };
37
38 struct vars {
39         struct isl_ctx  *ctx;
40         int              n;
41         struct variable *v;
42 };
43
44 static struct vars *vars_new(struct isl_ctx *ctx)
45 {
46         struct vars *v;
47         v = isl_alloc_type(ctx, struct vars);
48         if (!v)
49                 return NULL;
50         v->ctx = ctx;
51         v->n = 0;
52         v->v = NULL;
53         return v;
54 }
55
56 static void variable_free(struct variable *var)
57 {
58         while (var) {
59                 struct variable *next = var->next;
60                 isl_mat_free(var->list);
61                 isl_vec_free(var->def);
62                 free(var->name);
63                 free(var);
64                 var = next;
65         }
66 }
67
68 static void vars_free(struct vars *v)
69 {
70         if (!v)
71                 return;
72         variable_free(v->v);
73         free(v);
74 }
75
76 static void vars_drop(struct vars *v, int n)
77 {
78         struct variable *var;
79
80         if (!v || !v->v)
81                 return;
82
83         v->n -= n;
84
85         var = v->v;
86         while (--n >= 0) {
87                 struct variable *next = var->next;
88                 isl_mat_free(var->list);
89                 isl_vec_free(var->def);
90                 free(var->name);
91                 free(var);
92                 var = next;
93         }
94         v->v = var;
95 }
96
97 static struct variable *variable_new(struct vars *v, const char *name, int len,
98                                 int pos)
99 {
100         struct variable *var;
101         var = isl_calloc_type(v->ctx, struct variable);
102         if (!var)
103                 goto error;
104         var->name = strdup(name);
105         var->name[len] = '\0';
106         var->pos = pos;
107         var->def = NULL;
108         var->next = v->v;
109         return var;
110 error:
111         variable_free(v->v);
112         return NULL;
113 }
114
115 static int vars_pos(struct vars *v, const char *s, int len)
116 {
117         int pos;
118         struct variable *q;
119
120         if (len == -1)
121                 len = strlen(s);
122         for (q = v->v; q; q = q->next) {
123                 if (strncmp(q->name, s, len) == 0 && q->name[len] == '\0')
124                         break;
125         }
126         if (q)
127                 pos = q->pos;
128         else {
129                 pos = v->n;
130                 v->v = variable_new(v, s, len, v->n);
131                 if (!v->v)
132                         return -1;
133                 v->n++;
134         }
135         return pos;
136 }
137
138 static int vars_add_anon(struct vars *v)
139 {
140         v->v = variable_new(v, "", 0, v->n);
141
142         if (!v->v)
143                 return -1;
144         v->n++;
145
146         return 0;
147 }
148
149 static __isl_give isl_basic_map *set_name(__isl_take isl_basic_map *bmap,
150         enum isl_dim_type type, unsigned pos, char *name)
151 {
152         char *prime;
153
154         if (!bmap)
155                 return NULL;
156         if (!name)
157                 return bmap;
158
159         prime = strchr(name, '\'');
160         if (prime)
161                 *prime = '\0';
162         bmap = isl_basic_map_set_dim_name(bmap, type, pos, name);
163         if (prime)
164                 *prime = '\'';
165
166         return bmap;
167 }
168
169 /* Obtain next token, with some preprocessing.
170  * In particular, evaluate expressions of the form x^y,
171  * with x and y values.
172  */
173 static struct isl_token *next_token(struct isl_stream *s)
174 {
175         struct isl_token *tok, *tok2;
176
177         tok = isl_stream_next_token(s);
178         if (!tok || tok->type != ISL_TOKEN_VALUE)
179                 return tok;
180         if (!isl_stream_eat_if_available(s, '^'))
181                 return tok;
182         tok2 = isl_stream_next_token(s);
183         if (!tok2 || tok2->type != ISL_TOKEN_VALUE) {
184                 isl_stream_error(s, tok2, "expecting constant value");
185                 goto error;
186         }
187
188         isl_int_pow_ui(tok->u.v, tok->u.v, isl_int_get_ui(tok2->u.v));
189
190         isl_token_free(tok2);
191         return tok;
192 error:
193         isl_token_free(tok);
194         isl_token_free(tok2);
195         return NULL;
196 }
197
198 static int accept_cst_factor(struct isl_stream *s, isl_int *f)
199 {
200         struct isl_token *tok;
201
202         tok = next_token(s);
203         if (!tok || tok->type != ISL_TOKEN_VALUE) {
204                 isl_stream_error(s, tok, "expecting constant value");
205                 goto error;
206         }
207
208         isl_int_mul(*f, *f, tok->u.v);
209
210         isl_token_free(tok);
211
212         if (isl_stream_eat_if_available(s, '*'))
213                 return accept_cst_factor(s, f);
214
215         return 0;
216 error:
217         isl_token_free(tok);
218         return -1;
219 }
220
221 /* Given an affine expression aff, return an affine expression
222  * for aff % d, with d the next token on the stream, which is
223  * assumed to be a constant.
224  *
225  * We introduce an integer division q = [aff/d] and the result
226  * is set to aff - d q.
227  */
228 static __isl_give isl_vec *affine_mod(struct isl_stream *s,
229         struct vars *v, __isl_take isl_vec *aff)
230 {
231         struct isl_token *tok;
232         struct variable *var;
233         isl_vec *mod;
234
235         tok = next_token(s);
236         if (!tok || tok->type != ISL_TOKEN_VALUE) {
237                 isl_stream_error(s, tok, "expecting constant value");
238                 goto error;
239         }
240
241         if (vars_add_anon(v) < 0)
242                 goto error;
243
244         var = v->v;
245
246         var->def = isl_vec_alloc(s->ctx, 2 + v->n);
247         if (!var->def)
248                 goto error;
249         isl_seq_cpy(var->def->el + 1, aff->el, aff->size);
250         isl_int_set_si(var->def->el[1 + aff->size], 0);
251         isl_int_set(var->def->el[0], tok->u.v);
252
253         mod = isl_vec_alloc(v->ctx, 1 + v->n);
254         if (!mod)
255                 goto error;
256
257         isl_seq_cpy(mod->el, aff->el, aff->size);
258         isl_int_neg(mod->el[aff->size], tok->u.v);
259
260         isl_vec_free(aff);
261         isl_token_free(tok);
262         return mod;
263 error:
264         isl_vec_free(aff);
265         isl_token_free(tok);
266         return NULL;
267 }
268
269 static struct isl_vec *accept_affine(struct isl_stream *s, struct vars *v);
270 static int read_div_definition(struct isl_stream *s, struct vars *v);
271 static int read_minmax_definition(struct isl_stream *s, struct vars *v);
272
273 static __isl_give isl_vec *accept_affine_factor(struct isl_stream *s,
274         struct vars *v)
275 {
276         struct isl_token *tok = NULL;
277         isl_vec *aff = NULL;
278
279         tok = next_token(s);
280         if (!tok) {
281                 isl_stream_error(s, NULL, "unexpected EOF");
282                 goto error;
283         }
284         if (tok->type == ISL_TOKEN_IDENT) {
285                 int n = v->n;
286                 int pos = vars_pos(v, tok->u.s, -1);
287                 if (pos < 0)
288                         goto error;
289                 if (pos >= n) {
290                         isl_stream_error(s, tok, "unknown identifier");
291                         goto error;
292                 }
293
294                 aff = isl_vec_alloc(v->ctx, 1 + v->n);
295                 if (!aff)
296                         goto error;
297                 isl_seq_clr(aff->el, aff->size);
298                 isl_int_set_si(aff->el[1 + pos], 1);
299                 isl_token_free(tok);
300         } else if (tok->type == ISL_TOKEN_VALUE) {
301                 if (isl_stream_eat_if_available(s, '*')) {
302                         aff = accept_affine_factor(s, v);
303                         aff = isl_vec_scale(aff, tok->u.v);
304                 } else {
305                         aff = isl_vec_alloc(v->ctx, 1 + v->n);
306                         if (!aff)
307                                 goto error;
308                         isl_seq_clr(aff->el, aff->size);
309                         isl_int_set(aff->el[0], tok->u.v);
310                 }
311                 isl_token_free(tok);
312         } else if (tok->type == '(') {
313                 isl_token_free(tok);
314                 tok = NULL;
315                 aff = accept_affine(s, v);
316                 if (!aff)
317                         goto error;
318                 if (isl_stream_eat(s, ')'))
319                         goto error;
320         } else if (tok->type == '[' ||
321                     tok->type == ISL_TOKEN_FLOORD ||
322                     tok->type == ISL_TOKEN_CEILD) {
323                 int ceil = tok->type == ISL_TOKEN_CEILD;
324                 struct variable *var;
325                 if (vars_add_anon(v) < 0)
326                         goto error;
327                 var = v->v;
328                 aff = isl_vec_alloc(v->ctx, 1 + v->n);
329                 if (!aff)
330                         goto error;
331                 isl_seq_clr(aff->el, aff->size);
332                 isl_int_set_si(aff->el[1 + v->n - 1], ceil ? -1 : 1);
333                 isl_stream_push_token(s, tok);
334                 tok = NULL;
335                 if (read_div_definition(s, v) < 0)
336                         goto error;
337                 if (ceil)
338                         isl_seq_neg(var->def->el + 1, var->def->el + 1,
339                                     var->def->size - 1);
340                 aff = isl_vec_zero_extend(aff, 1 + v->n);
341         } else if (tok->type == ISL_TOKEN_MIN || tok->type == ISL_TOKEN_MAX) {
342                 if (vars_add_anon(v) < 0)
343                         goto error;
344                 aff = isl_vec_alloc(v->ctx, 1 + v->n);
345                 if (!aff)
346                         goto error;
347                 isl_seq_clr(aff->el, aff->size);
348                 isl_int_set_si(aff->el[1 + v->n - 1], 1);
349                 isl_stream_push_token(s, tok);
350                 tok = NULL;
351                 if (read_minmax_definition(s, v) < 0)
352                         goto error;
353                 aff = isl_vec_zero_extend(aff, 1 + v->n);
354         } else {
355                 isl_stream_error(s, tok, "expecting factor");
356                 goto error;
357         }
358         if (isl_stream_eat_if_available(s, '%'))
359                 return affine_mod(s, v, aff);
360         if (isl_stream_eat_if_available(s, '*')) {
361                 isl_int f;
362                 isl_int_init(f);
363                 isl_int_set_si(f, 1);
364                 if (accept_cst_factor(s, &f) < 0) {
365                         isl_int_clear(f);
366                         goto error2;
367                 }
368                 aff = isl_vec_scale(aff, f);
369                 isl_int_clear(f);
370         }
371
372         return aff;
373 error:
374         isl_token_free(tok);
375 error2:
376         isl_vec_free(aff);
377         return NULL;
378 }
379
380 static struct isl_vec *accept_affine(struct isl_stream *s, struct vars *v)
381 {
382         struct isl_token *tok = NULL;
383         struct isl_vec *aff;
384         int sign = 1;
385
386         aff = isl_vec_alloc(v->ctx, 1 + v->n);
387         if (!aff)
388                 return NULL;
389         isl_seq_clr(aff->el, aff->size);
390
391         for (;;) {
392                 tok = next_token(s);
393                 if (!tok) {
394                         isl_stream_error(s, NULL, "unexpected EOF");
395                         goto error;
396                 }
397                 if (tok->type == '-') {
398                         sign = -sign;
399                         isl_token_free(tok);
400                         continue;
401                 }
402                 if (tok->type == '(' || tok->type == '[' ||
403                     tok->type == ISL_TOKEN_MIN || tok->type == ISL_TOKEN_MAX ||
404                     tok->type == ISL_TOKEN_FLOORD ||
405                     tok->type == ISL_TOKEN_CEILD ||
406                     tok->type == ISL_TOKEN_IDENT) {
407                         isl_vec *aff2;
408                         isl_stream_push_token(s, tok);
409                         tok = NULL;
410                         aff2 = accept_affine_factor(s, v);
411                         if (sign < 0)
412                                 aff2 = isl_vec_scale(aff2, s->ctx->negone);
413                         aff = isl_vec_zero_extend(aff, 1 + v->n);
414                         aff = isl_vec_add(aff, aff2);
415                         if (!aff)
416                                 goto error;
417                         sign = 1;
418                 } else if (tok->type == ISL_TOKEN_VALUE) {
419                         if (sign < 0)
420                                 isl_int_neg(tok->u.v, tok->u.v);
421                         if (isl_stream_eat_if_available(s, '*') ||
422                             isl_stream_next_token_is(s, ISL_TOKEN_IDENT)) {
423                                 isl_vec *aff2;
424                                 aff2 = accept_affine_factor(s, v);
425                                 aff2 = isl_vec_scale(aff2, tok->u.v);
426                                 aff = isl_vec_zero_extend(aff, 1 + v->n);
427                                 aff = isl_vec_add(aff, aff2);
428                                 if (!aff)
429                                         goto error;
430                         } else {
431                                 isl_int_add(aff->el[0], aff->el[0], tok->u.v);
432                         }
433                         sign = 1;
434                 } else {
435                         isl_stream_error(s, tok, "unexpected isl_token");
436                         isl_stream_push_token(s, tok);
437                         isl_vec_free(aff);
438                         return NULL;
439                 }
440                 isl_token_free(tok);
441
442                 tok = next_token(s);
443                 if (tok && tok->type == '-') {
444                         sign = -sign;
445                         isl_token_free(tok);
446                 } else if (tok && tok->type == '+') {
447                         /* nothing */
448                         isl_token_free(tok);
449                 } else if (tok && tok->type == ISL_TOKEN_VALUE &&
450                            isl_int_is_neg(tok->u.v)) {
451                         isl_stream_push_token(s, tok);
452                 } else {
453                         if (tok)
454                                 isl_stream_push_token(s, tok);
455                         break;
456                 }
457         }
458
459         return aff;
460 error:
461         isl_token_free(tok);
462         isl_vec_free(aff);
463         return NULL;
464 }
465
466 /* Add any variables in the variable list "v" that are not already in "bmap"
467  * as existentially quantified variables in "bmap".
468  */
469 static __isl_give isl_basic_map *add_divs(__isl_take isl_basic_map *bmap,
470         struct vars *v)
471 {
472         int i;
473         int extra;
474         struct variable *var;
475
476         extra = v->n - isl_basic_map_total_dim(bmap);
477
478         if (extra == 0)
479                 return bmap;
480
481         bmap = isl_basic_map_extend_dim(bmap, isl_basic_map_get_dim(bmap),
482                                         extra, 0, 2 * extra);
483
484         for (i = 0; i < extra; ++i)
485                 if (isl_basic_map_alloc_div(bmap) < 0)
486                         goto error;
487
488         for (i = 0, var = v->v; i < extra; ++i, var = var->next) {
489                 int k = bmap->n_div - 1 - i;
490
491                 isl_seq_cpy(bmap->div[k], var->def->el, var->def->size);
492                 isl_seq_clr(bmap->div[k] + var->def->size,
493                             2 + v->n - var->def->size);
494
495                 if (isl_basic_map_add_div_constraints(bmap, k) < 0)
496                         goto error;
497         }
498
499         return bmap;
500 error:
501         isl_basic_map_free(bmap);
502         return NULL;
503 }
504
505 static __isl_give isl_basic_map *read_var_def(struct isl_stream *s,
506         __isl_take isl_basic_map *bmap, enum isl_dim_type type, struct vars *v)
507 {
508         isl_dim *dim;
509         isl_basic_map *def = NULL;
510         struct isl_vec *vec;
511         int k;
512         int n;
513
514         if (vars_add_anon(v) < 0)
515                 goto error;
516         n = v->n;
517
518         vec = accept_affine(s, v);
519         if (!vec)
520                 goto error;
521
522         dim = isl_basic_map_get_dim(bmap);
523         def = isl_basic_map_universe(dim);
524         def = add_divs(def, v);
525         def = isl_basic_map_extend_constraints(def, 1, 0);
526         k = isl_basic_map_alloc_equality(def);
527         if (k >= 0) {
528                 isl_seq_cpy(def->eq[k], vec->el, vec->size);
529                 isl_int_set_si(def->eq[k][1 + n - 1], -1);
530         }
531         isl_vec_free(vec);
532         if (k < 0)
533                 goto error;
534
535         vars_drop(v, v->n - n);
536
537         def = isl_basic_map_simplify(def);
538         def = isl_basic_map_finalize(def);
539         bmap = isl_basic_map_intersect(bmap, def);
540         return bmap;
541 error:
542         isl_basic_map_free(bmap);
543         isl_basic_map_free(def);
544         return NULL;
545 }
546
547 static __isl_give isl_basic_map *read_var_list(struct isl_stream *s,
548         __isl_take isl_basic_map *bmap, enum isl_dim_type type, struct vars *v)
549 {
550         int i = 0;
551         struct isl_token *tok;
552
553         while ((tok = next_token(s)) != NULL) {
554                 int new_name = 0;
555
556                 if (tok->type == ISL_TOKEN_IDENT) {
557                         int n = v->n;
558                         int p = vars_pos(v, tok->u.s, -1);
559                         if (p < 0)
560                                 goto error;
561                         new_name = p >= n;
562                 }
563
564                 if (new_name) {
565                         bmap = isl_basic_map_add(bmap, type, 1);
566                         bmap = set_name(bmap, type, i, v->v->name);
567                         isl_token_free(tok);
568                 } else if (tok->type == ISL_TOKEN_IDENT ||
569                            tok->type == ISL_TOKEN_VALUE ||
570                            tok->type == '-' ||
571                            tok->type == '(') {
572                         if (type == isl_dim_param) {
573                                 isl_stream_error(s, tok,
574                                                 "expecting unique identifier");
575                                 goto error;
576                         }
577                         isl_stream_push_token(s, tok);
578                         tok = NULL;
579                         bmap = isl_basic_map_add(bmap, type, 1);
580                         bmap = read_var_def(s, bmap, type, v);
581                 } else
582                         break;
583
584                 tok = isl_stream_next_token(s);
585                 if (!tok || tok->type != ',')
586                         break;
587
588                 isl_token_free(tok);
589                 i++;
590         }
591         if (tok)
592                 isl_stream_push_token(s, tok);
593
594         return bmap;
595 error:
596         isl_token_free(tok);
597         isl_basic_map_free(bmap);
598         return NULL;
599 }
600
601 static __isl_give isl_mat *accept_affine_list(struct isl_stream *s,
602         struct vars *v)
603 {
604         struct isl_vec *vec;
605         struct isl_mat *mat;
606         struct isl_token *tok = NULL;
607
608         vec = accept_affine(s, v);
609         mat = isl_mat_from_row_vec(vec);
610         if (!mat)
611                 return NULL;
612
613         for (;;) {
614                 tok = isl_stream_next_token(s);
615                 if (!tok) {
616                         isl_stream_error(s, NULL, "unexpected EOF");
617                         goto error;
618                 }
619                 if (tok->type != ',') {
620                         isl_stream_push_token(s, tok);
621                         break;
622                 }
623                 isl_token_free(tok);
624
625                 vec = accept_affine(s, v);
626                 mat = isl_mat_add_zero_cols(mat, 1 + v->n - isl_mat_cols(mat));
627                 mat = isl_mat_vec_concat(mat, vec);
628                 if (!mat)
629                         return NULL;
630         }
631
632         return mat;
633 error:
634         isl_mat_free(mat);
635         return NULL;
636 }
637
638 static int read_minmax_definition(struct isl_stream *s, struct vars *v)
639 {
640         struct isl_token *tok;
641         struct variable *var;
642
643         var = v->v;
644
645         tok = isl_stream_next_token(s);
646         if (!tok)
647                 return -1;
648         var->sign = tok->type == ISL_TOKEN_MIN ? -1 : 1;
649         isl_token_free(tok);
650
651         if (isl_stream_eat(s, '('))
652                 return -1;
653
654         var->list = accept_affine_list(s, v);
655         if (!var->list)
656                 return -1;
657
658         if (isl_stream_eat(s, ')'))
659                 return -1;
660
661         return 0;
662 }
663
664 static int read_div_definition(struct isl_stream *s, struct vars *v)
665 {
666         struct isl_token *tok;
667         int seen_paren = 0;
668         struct isl_vec *aff;
669         struct variable *var;
670         int fc = 0;
671
672         if (isl_stream_eat_if_available(s, ISL_TOKEN_FLOORD) ||
673             isl_stream_eat_if_available(s, ISL_TOKEN_CEILD)) {
674                 fc = 1;
675                 if (isl_stream_eat(s, '('))
676                         return -1;
677         } else {
678                 if (isl_stream_eat(s, '['))
679                         return -1;
680                 if (isl_stream_eat_if_available(s, '('))
681                         seen_paren = 1;
682         }
683
684         var = v->v;
685
686         aff = accept_affine(s, v);
687         if (!aff)
688                 return -1;
689
690         var->def = isl_vec_alloc(s->ctx, 2 + v->n);
691         if (!var->def) {
692                 isl_vec_free(aff);
693                 return -1;
694         }
695
696         isl_seq_cpy(var->def->el + 1, aff->el, aff->size);
697
698         isl_vec_free(aff);
699
700         if (fc) {
701                 if (isl_stream_eat(s, ','))
702                         return -1;
703         } else {
704                 if (seen_paren && isl_stream_eat(s, ')'))
705                         return -1;
706                 if (isl_stream_eat(s, '/'))
707                         return -1;
708         }
709
710         tok = next_token(s);
711         if (!tok)
712                 return -1;
713         if (tok->type != ISL_TOKEN_VALUE) {
714                 isl_stream_error(s, tok, "expected denominator");
715                 isl_stream_push_token(s, tok);
716                 return -1;
717         }
718         isl_int_set(var->def->el[0], tok->u.v);
719         isl_token_free(tok);
720
721         if (fc) {
722                 if (isl_stream_eat(s, ')'))
723                         return -1;
724         } else {
725                 if (isl_stream_eat(s, ']'))
726                         return -1;
727         }
728
729         return 0;
730 }
731
732 static struct isl_basic_map *add_div_definition(struct isl_stream *s,
733         struct vars *v, struct isl_basic_map *bmap, int pos)
734 {
735         struct variable *var = v->v;
736         unsigned o_out = isl_basic_map_offset(bmap, isl_dim_out) - 1;
737
738         if (read_div_definition(s, v) < 0)
739                 goto error;
740
741         if (isl_basic_map_add_div_constraints_var(bmap, o_out + pos,
742                                                   var->def->el) < 0)
743                 goto error;
744
745         return bmap;
746 error:
747         isl_basic_map_free(bmap);
748         return NULL;
749 }
750
751 static struct isl_basic_map *read_defined_var_list(struct isl_stream *s,
752         struct vars *v, struct isl_basic_map *bmap)
753 {
754         struct isl_token *tok;
755
756         while ((tok = isl_stream_next_token(s)) != NULL) {
757                 int p;
758                 int n = v->n;
759                 unsigned n_out = isl_basic_map_dim(bmap, isl_dim_out);
760
761                 if (tok->type != ISL_TOKEN_IDENT)
762                         break;
763
764                 p = vars_pos(v, tok->u.s, -1);
765                 if (p < 0)
766                         goto error;
767                 if (p < n) {
768                         isl_stream_error(s, tok, "expecting unique identifier");
769                         goto error;
770                 }
771
772                 bmap = isl_basic_map_cow(bmap);
773                 bmap = isl_basic_map_add(bmap, isl_dim_out, 1);
774                 bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim),
775                                                 0, 0, 2);
776
777                 isl_token_free(tok);
778                 tok = isl_stream_next_token(s);
779                 if (tok && tok->type == '=') {
780                         isl_token_free(tok);
781                         bmap = add_div_definition(s, v, bmap, n_out);
782                         tok = isl_stream_next_token(s);
783                 }
784
785                 if (!tok || tok->type != ',')
786                         break;
787
788                 isl_token_free(tok);
789         }
790         if (tok)
791                 isl_stream_push_token(s, tok);
792
793         return bmap;
794 error:
795         isl_token_free(tok);
796         isl_basic_map_free(bmap);
797         return NULL;
798 }
799
800 static int next_is_tuple(struct isl_stream *s)
801 {
802         struct isl_token *tok;
803         int is_tuple;
804
805         tok = isl_stream_next_token(s);
806         if (!tok)
807                 return 0;
808         if (tok->type == '[') {
809                 isl_stream_push_token(s, tok);
810                 return 1;
811         }
812         if (tok->type != ISL_TOKEN_IDENT && !tok->is_keyword) {
813                 isl_stream_push_token(s, tok);
814                 return 0;
815         }
816
817         is_tuple = isl_stream_next_token_is(s, '[');
818
819         isl_stream_push_token(s, tok);
820
821         return is_tuple;
822 }
823
824 static __isl_give isl_basic_map *read_tuple(struct isl_stream *s,
825         __isl_take isl_basic_map *bmap, enum isl_dim_type type, struct vars *v);
826
827 static __isl_give isl_basic_map *read_nested_tuple(struct isl_stream *s,
828         __isl_take isl_basic_map *bmap, struct vars *v)
829 {
830         bmap = read_tuple(s, bmap, isl_dim_in, v);
831         if (isl_stream_eat(s, ISL_TOKEN_TO))
832                 goto error;
833         bmap = read_tuple(s, bmap, isl_dim_out, v);
834         bmap = isl_basic_map_from_range(isl_basic_map_wrap(bmap));
835         return bmap;
836 error:
837         isl_basic_map_free(bmap);
838         return NULL;
839 }
840
841 static __isl_give isl_basic_map *read_tuple(struct isl_stream *s,
842         __isl_take isl_basic_map *bmap, enum isl_dim_type type, struct vars *v)
843 {
844         struct isl_token *tok;
845         char *name = NULL;
846
847         tok = isl_stream_next_token(s);
848         if (tok && (tok->type == ISL_TOKEN_IDENT || tok->is_keyword)) {
849                 name = strdup(tok->u.s);
850                 if (!name)
851                         goto error;
852                 isl_token_free(tok);
853                 tok = isl_stream_next_token(s);
854         }
855         if (!tok || tok->type != '[') {
856                 isl_stream_error(s, tok, "expecting '['");
857                 goto error;
858         }
859         isl_token_free(tok);
860         if (type != isl_dim_param && next_is_tuple(s)) {
861                 isl_dim *dim = isl_basic_map_get_dim(bmap);
862                 int nparam = isl_dim_size(dim, isl_dim_param);
863                 int n_in = isl_dim_size(dim, isl_dim_in);
864                 isl_basic_map *nested;
865                 if (type == isl_dim_out)
866                         dim = isl_dim_move(dim, isl_dim_param, nparam,
867                                                 isl_dim_in, 0, n_in);
868                 nested = isl_basic_map_alloc_dim(dim, 0, 0, 0);
869                 nested = read_nested_tuple(s, nested, v);
870                 if (type == isl_dim_in) {
871                         nested = isl_basic_map_reverse(nested);
872                         bmap = isl_basic_map_intersect(nested, bmap);
873                 } else {
874                         isl_basic_set *bset;
875                         dim = isl_dim_range(isl_basic_map_get_dim(nested));
876                         dim = isl_dim_drop(dim, isl_dim_param, nparam, n_in);
877                         dim = isl_dim_join(isl_basic_map_get_dim(bmap), dim);
878                         bset = isl_basic_map_domain(bmap);
879                         nested = isl_basic_map_reset_dim(nested, dim);
880                         bmap = isl_basic_map_intersect_domain(nested, bset);
881                 }
882         } else
883                 bmap = read_var_list(s, bmap, type, v);
884         tok = isl_stream_next_token(s);
885         if (!tok || tok->type != ']') {
886                 isl_stream_error(s, tok, "expecting ']'");
887                 goto error;
888         }
889         isl_token_free(tok);
890
891         if (name) {
892                 bmap = isl_basic_map_set_tuple_name(bmap, type, name);
893                 free(name);
894         }
895
896         return bmap;
897 error:
898         if (tok)
899                 isl_token_free(tok);
900         isl_basic_map_free(bmap);
901         return NULL;
902 }
903
904 static __isl_give isl_basic_map *construct_constraint(
905         __isl_take isl_basic_map *bmap, enum isl_token_type type,
906         isl_int *left, isl_int *right)
907 {
908         int k;
909         unsigned len;
910         struct isl_ctx *ctx;
911
912         if (!bmap)
913                 return NULL;
914         len = 1 + isl_basic_map_total_dim(bmap);
915         ctx = bmap->ctx;
916
917         k = isl_basic_map_alloc_inequality(bmap);
918         if (k < 0)
919                 goto error;
920         if (type == ISL_TOKEN_LE)
921                 isl_seq_combine(bmap->ineq[k], ctx->negone, left,
922                                                ctx->one, right,
923                                                len);
924         else if (type == ISL_TOKEN_GE)
925                 isl_seq_combine(bmap->ineq[k], ctx->one, left,
926                                                ctx->negone, right,
927                                                len);
928         else if (type == ISL_TOKEN_LT) {
929                 isl_seq_combine(bmap->ineq[k], ctx->negone, left,
930                                                ctx->one, right,
931                                                len);
932                 isl_int_sub_ui(bmap->ineq[k][0], bmap->ineq[k][0], 1);
933         } else if (type == ISL_TOKEN_GT) {
934                 isl_seq_combine(bmap->ineq[k], ctx->one, left,
935                                                ctx->negone, right,
936                                                len);
937                 isl_int_sub_ui(bmap->ineq[k][0], bmap->ineq[k][0], 1);
938         } else {
939                 isl_seq_combine(bmap->ineq[k], ctx->one, left,
940                                                ctx->negone, right,
941                                                len);
942                 isl_basic_map_inequality_to_equality(bmap, k);
943         }
944
945         return bmap;
946 error:
947         isl_basic_map_free(bmap);
948         return NULL;
949 }
950
951 static int is_comparator(struct isl_token *tok)
952 {
953         if (!tok)
954                 return 0;
955
956         switch (tok->type) {
957         case ISL_TOKEN_LT:
958         case ISL_TOKEN_GT:
959         case ISL_TOKEN_LE:
960         case ISL_TOKEN_GE:
961         case '=':
962                 return 1;
963         default:
964                 return 0;
965         }
966 }
967
968 /* Add any variables in the variable list "v" that are not already in "bmap"
969  * as output variables in "bmap".
970  */
971 static __isl_give isl_basic_map *add_lifted_divs(__isl_take isl_basic_map *bmap,
972         struct vars *v)
973 {
974         int i;
975         int extra;
976         struct variable *var;
977
978         extra = v->n - isl_basic_map_total_dim(bmap);
979
980         if (extra == 0)
981                 return bmap;
982
983         bmap = isl_basic_map_add(bmap, isl_dim_out, extra);
984         bmap = isl_basic_map_extend_dim(bmap, isl_basic_map_get_dim(bmap),
985                                         0, 0, 2 * extra);
986
987         for (i = 0, var = v->v; i < extra; ++i, var = var->next) {
988                 if (!var->def)
989                         continue;
990                 var->def = isl_vec_zero_extend(var->def, 2 + v->n);
991                 if (!var->def)
992                         goto error;
993                 if (isl_basic_map_add_div_constraints_var(bmap, var->pos,
994                                                           var->def->el) < 0)
995                         goto error;
996         }
997
998         return bmap;
999 error:
1000         isl_basic_map_free(bmap);
1001         return NULL;
1002 }
1003
1004 static struct isl_basic_map *add_constraint(struct isl_stream *s,
1005         struct vars *v, struct isl_basic_map *bmap)
1006 {
1007         int i, j;
1008         struct isl_token *tok = NULL;
1009         struct isl_mat *aff1 = NULL, *aff2 = NULL;
1010
1011         bmap = isl_basic_map_cow(bmap);
1012
1013         aff1 = accept_affine_list(s, v);
1014         if (!aff1)
1015                 goto error;
1016         tok = isl_stream_next_token(s);
1017         if (!is_comparator(tok)) {
1018                 isl_stream_error(s, tok, "missing operator");
1019                 if (tok)
1020                         isl_stream_push_token(s, tok);
1021                 tok = NULL;
1022                 goto error;
1023         }
1024         for (;;) {
1025                 aff2 = accept_affine_list(s, v);
1026                 if (!aff2)
1027                         goto error;
1028
1029                 aff1 = isl_mat_add_zero_cols(aff1, aff2->n_col - aff1->n_col);
1030                 if (!aff1)
1031                         goto error;
1032                 bmap = add_lifted_divs(bmap, v);
1033                 bmap = isl_basic_map_extend_constraints(bmap, 0,
1034                                                 aff1->n_row * aff2->n_row);
1035                 for (i = 0; i < aff1->n_row; ++i)
1036                         for (j = 0; j < aff2->n_row; ++j)
1037                                 bmap = construct_constraint(bmap, tok->type,
1038                                                     aff1->row[i], aff2->row[j]);
1039                 isl_token_free(tok);
1040                 isl_mat_free(aff1);
1041                 aff1 = aff2;
1042
1043                 tok = isl_stream_next_token(s);
1044                 if (!is_comparator(tok)) {
1045                         if (tok)
1046                                 isl_stream_push_token(s, tok);
1047                         break;
1048                 }
1049         }
1050         isl_mat_free(aff1);
1051
1052         return bmap;
1053 error:
1054         if (tok)
1055                 isl_token_free(tok);
1056         isl_mat_free(aff1);
1057         isl_mat_free(aff2);
1058         isl_basic_map_free(bmap);
1059         return NULL;
1060 }
1061
1062 /* Return first variable, starting at n, representing a min or max,
1063  * or NULL if there is no such variable.
1064  */
1065 static struct variable *first_minmax(struct vars *v, int n)
1066 {
1067         struct variable *first = NULL;
1068         struct variable *var;
1069
1070         for (var = v->v; var && var->pos >= n; var = var->next)
1071                 if (var->list)
1072                         first = var;
1073
1074         return first;
1075 }
1076
1077 /* Check whether the variable at the given position only occurs in
1078  * inequalities and only with the given sign.
1079  */
1080 static int all_coefficients_of_sign(__isl_keep isl_map *map, int pos, int sign)
1081 {
1082         int i, j;
1083
1084         if (!map)
1085                 return -1;
1086
1087         for (i = 0; i < map->n; ++i) {
1088                 isl_basic_map *bmap = map->p[i];
1089
1090                 for (j = 0; j < bmap->n_eq; ++j)
1091                         if (!isl_int_is_zero(bmap->eq[j][1 + pos]))
1092                                 return 0;
1093                 for (j = 0; j < bmap->n_ineq; ++j) {
1094                         int s = isl_int_sgn(bmap->ineq[j][1 + pos]);
1095                         if (s == 0)
1096                                 continue;
1097                         if (s != sign)
1098                                 return 0;
1099                 }
1100         }
1101
1102         return 1;
1103 }
1104
1105 /* Given a variable m which represents a min or a max of n expressions
1106  * b_i, add the constraints
1107  *
1108  *      m <= b_i
1109  *
1110  * in case of a min (var->sign < 0) and m >= b_i in case of a max.
1111  */
1112 static __isl_give isl_map *bound_minmax(__isl_take isl_map *map,
1113         struct variable *var)
1114 {
1115         int i, k;
1116         isl_basic_map *bound;
1117         int total;
1118
1119         total = isl_map_dim(map, isl_dim_all);
1120         bound = isl_basic_map_alloc_dim(isl_map_get_dim(map),
1121                                         0, 0, var->list->n_row);
1122
1123         for (i = 0; i < var->list->n_row; ++i) {
1124                 k = isl_basic_map_alloc_inequality(bound);
1125                 if (k < 0)
1126                         goto error;
1127                 if (var->sign < 0)
1128                         isl_seq_cpy(bound->ineq[k], var->list->row[i],
1129                                     var->list->n_col);
1130                 else
1131                         isl_seq_neg(bound->ineq[k], var->list->row[i],
1132                                     var->list->n_col);
1133                 isl_int_set_si(bound->ineq[k][1 + var->pos], var->sign);
1134                 isl_seq_clr(bound->ineq[k] + var->list->n_col,
1135                             1 + total - var->list->n_col);
1136         }
1137
1138         map = isl_map_intersect(map, isl_map_from_basic_map(bound));
1139
1140         return map;
1141 error:
1142         isl_basic_map_free(bound);
1143         isl_map_free(map);
1144         return NULL;
1145 }
1146
1147 /* Given a variable m which represents a min (or max) of n expressions
1148  * b_i, add constraints that assigns the minimal upper bound to m, i.e.,
1149  * divide the space into cells where one
1150  * of the upper bounds is smaller than all the others and assign
1151  * this upper bound to m.
1152  *
1153  * In particular, if there are n bounds b_i, then the input map
1154  * is split into n pieces, each with the extra constraints
1155  *
1156  *      m = b_i
1157  *      b_i <= b_j      for j > i
1158  *      b_i <  b_j      for j < i
1159  *
1160  * in case of a min (var->sign < 0) and similarly in case of a max.
1161  *
1162  * Note: this function is very similar to set_minimum in isl_tab_pip.c
1163  * Perhaps we should try to merge the two.
1164  */
1165 static __isl_give isl_map *set_minmax(__isl_take isl_map *map,
1166         struct variable *var)
1167 {
1168         int i, j, k;
1169         isl_basic_map *bmap = NULL;
1170         isl_ctx *ctx;
1171         isl_map *split = NULL;
1172         int total;
1173
1174         ctx = isl_map_get_ctx(map);
1175         total = isl_map_dim(map, isl_dim_all);
1176         split = isl_map_alloc_dim(isl_map_get_dim(map),
1177                                 var->list->n_row, ISL_SET_DISJOINT);
1178
1179         for (i = 0; i < var->list->n_row; ++i) {
1180                 bmap = isl_basic_map_alloc_dim(isl_map_get_dim(map), 0,
1181                                                1, var->list->n_row - 1);
1182                 k = isl_basic_map_alloc_equality(bmap);
1183                 if (k < 0)
1184                         goto error;
1185                 isl_seq_cpy(bmap->eq[k], var->list->row[i], var->list->n_col);
1186                 isl_int_set_si(bmap->eq[k][1 + var->pos], -1);
1187                 for (j = 0; j < var->list->n_row; ++j) {
1188                         if (j == i)
1189                                 continue;
1190                         k = isl_basic_map_alloc_inequality(bmap);
1191                         if (k < 0)
1192                                 goto error;
1193                         if (var->sign < 0)
1194                                 isl_seq_combine(bmap->ineq[k],
1195                                                 ctx->one, var->list->row[j],
1196                                                 ctx->negone, var->list->row[i],
1197                                                 var->list->n_col);
1198                         else
1199                                 isl_seq_combine(bmap->ineq[k],
1200                                                 ctx->negone, var->list->row[j],
1201                                                 ctx->one, var->list->row[i],
1202                                                 var->list->n_col);
1203                         isl_seq_clr(bmap->ineq[k] + var->list->n_col,
1204                                     1 + total - var->list->n_col);
1205                         if (j < i)
1206                                 isl_int_sub_ui(bmap->ineq[k][0],
1207                                                bmap->ineq[k][0], 1);
1208                 }
1209                 bmap = isl_basic_map_finalize(bmap);
1210                 split = isl_map_add_basic_map(split, bmap);
1211         }
1212
1213         map = isl_map_intersect(map, split);
1214
1215         return map;
1216 error:
1217         isl_basic_map_free(bmap);
1218         isl_map_free(split);
1219         isl_map_free(map);
1220         return NULL;
1221 }
1222
1223 /* Plug in the definitions of all min and max expressions.
1224  * If a min expression only appears in inequalities and only
1225  * with a positive coefficient, then we can simply bound
1226  * the variable representing the min by its defining terms
1227  * and similarly for a max expression.
1228  * Otherwise, we have to assign the different terms to the
1229  * variable under the condition that the assigned term is smaller
1230  * than the other terms.
1231  */
1232 static __isl_give isl_map *add_minmax(__isl_take isl_map *map,
1233         struct vars *v, int n)
1234 {
1235         int i;
1236         struct variable *var;
1237
1238         while (n < v->n) {
1239                 var = first_minmax(v, n);
1240                 if (!var)
1241                         break;
1242                 if (all_coefficients_of_sign(map, var->pos, -var->sign))
1243                         map = bound_minmax(map, var);
1244                 else
1245                         map = set_minmax(map, var);
1246                 n = var->pos + 1;
1247         }
1248
1249         return map;
1250 }
1251
1252 static isl_map *read_constraint(struct isl_stream *s,
1253         struct vars *v, __isl_take isl_basic_map *bmap)
1254 {
1255         int n = v->n;
1256         isl_map *map;
1257
1258         if (!bmap)
1259                 return NULL;
1260
1261         bmap = isl_basic_set_unwrap(isl_basic_set_lift(isl_basic_map_wrap(bmap)));
1262
1263         bmap = add_constraint(s, v, bmap);
1264         bmap = isl_basic_map_simplify(bmap);
1265         bmap = isl_basic_map_finalize(bmap);
1266
1267         map = isl_map_from_basic_map(bmap);
1268
1269         map = add_minmax(map, v, n);
1270
1271         map = isl_set_unwrap(isl_map_domain(map));
1272
1273         vars_drop(v, v->n - n);
1274
1275         return map;
1276 }
1277
1278 static struct isl_map *read_disjuncts(struct isl_stream *s,
1279         struct vars *v, __isl_take isl_basic_map *bmap);
1280
1281 static __isl_give isl_map *read_exists(struct isl_stream *s,
1282         struct vars *v, __isl_take isl_basic_map *bmap)
1283 {
1284         int n = v->n;
1285         int seen_paren = isl_stream_eat_if_available(s, '(');
1286         isl_map *map = NULL;
1287
1288         bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
1289         bmap = read_defined_var_list(s, v, bmap);
1290
1291         if (isl_stream_eat(s, ':'))
1292                 goto error;
1293
1294         map = read_disjuncts(s, v, bmap);
1295         map = isl_set_unwrap(isl_map_domain(map));
1296         bmap = NULL;
1297
1298         vars_drop(v, v->n - n);
1299         if (seen_paren && isl_stream_eat(s, ')'))
1300                 goto error;
1301
1302         return map;
1303 error:
1304         isl_basic_map_free(bmap);
1305         isl_map_free(map);
1306         return NULL;
1307 }
1308
1309 static __isl_give isl_map *read_conjunct(struct isl_stream *s,
1310         struct vars *v, __isl_take isl_basic_map *bmap)
1311 {
1312         isl_map *map;
1313
1314         if (isl_stream_eat_if_available(s, '(')) {
1315                 map = read_disjuncts(s, v, bmap);
1316                 if (isl_stream_eat(s, ')'))
1317                         goto error;
1318                 return map;
1319         }
1320
1321         if (isl_stream_eat_if_available(s, ISL_TOKEN_EXISTS))
1322                 return read_exists(s, v, bmap);
1323
1324         if (isl_stream_eat_if_available(s, ISL_TOKEN_TRUE))
1325                 return isl_map_from_basic_map(bmap);
1326
1327         if (isl_stream_eat_if_available(s, ISL_TOKEN_FALSE)) {
1328                 isl_dim *dim = isl_basic_map_get_dim(bmap);
1329                 isl_basic_map_free(bmap);
1330                 return isl_map_empty(dim);
1331         }
1332                 
1333         return read_constraint(s, v, bmap);
1334 error:
1335         isl_map_free(map);
1336         return NULL;
1337 }
1338
1339 static __isl_give isl_map *read_conjuncts(struct isl_stream *s,
1340         struct vars *v, __isl_take isl_basic_map *bmap)
1341 {
1342         isl_map *map;
1343         int negate;
1344
1345         negate = isl_stream_eat_if_available(s, ISL_TOKEN_NOT);
1346         map = read_conjunct(s, v, isl_basic_map_copy(bmap));
1347         if (negate) {
1348                 isl_map *t;
1349                 t = isl_map_from_basic_map(isl_basic_map_copy(bmap));
1350                 map = isl_map_subtract(t, map);
1351         }
1352
1353         while (isl_stream_eat_if_available(s, ISL_TOKEN_AND)) {
1354                 isl_map *map_i;
1355
1356                 negate = isl_stream_eat_if_available(s, ISL_TOKEN_NOT);
1357                 map_i = read_conjunct(s, v, isl_basic_map_copy(bmap));
1358                 if (negate)
1359                         map = isl_map_subtract(map, map_i);
1360                 else
1361                         map = isl_map_intersect(map, map_i);
1362         }
1363
1364         isl_basic_map_free(bmap);
1365         return map;
1366 }
1367
1368 static struct isl_map *read_disjuncts(struct isl_stream *s,
1369         struct vars *v, __isl_take isl_basic_map *bmap)
1370 {
1371         struct isl_map *map;
1372
1373         if (isl_stream_next_token_is(s, '}')) {
1374                 isl_dim *dim = isl_basic_map_get_dim(bmap);
1375                 isl_basic_map_free(bmap);
1376                 return isl_map_universe(dim);
1377         }
1378
1379         map = read_conjuncts(s, v, isl_basic_map_copy(bmap));
1380         while (isl_stream_eat_if_available(s, ISL_TOKEN_OR)) {
1381                 isl_map *map_i;
1382
1383                 map_i = read_conjuncts(s, v, isl_basic_map_copy(bmap));
1384                 map = isl_map_union(map, map_i);
1385         }
1386
1387         isl_basic_map_free(bmap);
1388         return map;
1389 }
1390
1391 static int polylib_pos_to_isl_pos(__isl_keep isl_basic_map *bmap, int pos)
1392 {
1393         if (pos < isl_basic_map_dim(bmap, isl_dim_out))
1394                 return 1 + isl_basic_map_dim(bmap, isl_dim_param) +
1395                            isl_basic_map_dim(bmap, isl_dim_in) + pos;
1396         pos -= isl_basic_map_dim(bmap, isl_dim_out);
1397
1398         if (pos < isl_basic_map_dim(bmap, isl_dim_in))
1399                 return 1 + isl_basic_map_dim(bmap, isl_dim_param) + pos;
1400         pos -= isl_basic_map_dim(bmap, isl_dim_in);
1401
1402         if (pos < isl_basic_map_dim(bmap, isl_dim_div))
1403                 return 1 + isl_basic_map_dim(bmap, isl_dim_param) +
1404                            isl_basic_map_dim(bmap, isl_dim_in) +
1405                            isl_basic_map_dim(bmap, isl_dim_out) + pos;
1406         pos -= isl_basic_map_dim(bmap, isl_dim_div);
1407
1408         if (pos < isl_basic_map_dim(bmap, isl_dim_param))
1409                 return 1 + pos;
1410
1411         return 0;
1412 }
1413
1414 static __isl_give isl_basic_map *basic_map_read_polylib_constraint(
1415         struct isl_stream *s, __isl_take isl_basic_map *bmap)
1416 {
1417         int j;
1418         struct isl_token *tok;
1419         int type;
1420         int k;
1421         isl_int *c;
1422         unsigned nparam;
1423         unsigned dim;
1424
1425         if (!bmap)
1426                 return NULL;
1427
1428         nparam = isl_basic_map_dim(bmap, isl_dim_param);
1429         dim = isl_basic_map_dim(bmap, isl_dim_out);
1430
1431         tok = isl_stream_next_token(s);
1432         if (!tok || tok->type != ISL_TOKEN_VALUE) {
1433                 isl_stream_error(s, tok, "expecting coefficient");
1434                 if (tok)
1435                         isl_stream_push_token(s, tok);
1436                 goto error;
1437         }
1438         if (!tok->on_new_line) {
1439                 isl_stream_error(s, tok, "coefficient should appear on new line");
1440                 isl_stream_push_token(s, tok);
1441                 goto error;
1442         }
1443
1444         type = isl_int_get_si(tok->u.v);
1445         isl_token_free(tok);
1446
1447         isl_assert(s->ctx, type == 0 || type == 1, goto error);
1448         if (type == 0) {
1449                 k = isl_basic_map_alloc_equality(bmap);
1450                 c = bmap->eq[k];
1451         } else {
1452                 k = isl_basic_map_alloc_inequality(bmap);
1453                 c = bmap->ineq[k];
1454         }
1455         if (k < 0)
1456                 goto error;
1457
1458         for (j = 0; j < 1 + isl_basic_map_total_dim(bmap); ++j) {
1459                 int pos;
1460                 tok = isl_stream_next_token(s);
1461                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
1462                         isl_stream_error(s, tok, "expecting coefficient");
1463                         if (tok)
1464                                 isl_stream_push_token(s, tok);
1465                         goto error;
1466                 }
1467                 if (tok->on_new_line) {
1468                         isl_stream_error(s, tok,
1469                                 "coefficient should not appear on new line");
1470                         isl_stream_push_token(s, tok);
1471                         goto error;
1472                 }
1473                 pos = polylib_pos_to_isl_pos(bmap, j);
1474                 isl_int_set(c[pos], tok->u.v);
1475                 isl_token_free(tok);
1476         }
1477
1478         return bmap;
1479 error:
1480         isl_basic_map_free(bmap);
1481         return NULL;
1482 }
1483
1484 static __isl_give isl_basic_map *basic_map_read_polylib(struct isl_stream *s,
1485         int nparam)
1486 {
1487         int i;
1488         struct isl_token *tok;
1489         struct isl_token *tok2;
1490         int n_row, n_col;
1491         int on_new_line;
1492         unsigned in = 0, out, local = 0;
1493         struct isl_basic_map *bmap = NULL;
1494
1495         if (nparam < 0)
1496                 nparam = 0;
1497
1498         tok = isl_stream_next_token(s);
1499         if (!tok) {
1500                 isl_stream_error(s, NULL, "unexpected EOF");
1501                 return NULL;
1502         }
1503         tok2 = isl_stream_next_token(s);
1504         if (!tok2) {
1505                 isl_token_free(tok);
1506                 isl_stream_error(s, NULL, "unexpected EOF");
1507                 return NULL;
1508         }
1509         if (tok->type != ISL_TOKEN_VALUE || tok2->type != ISL_TOKEN_VALUE) {
1510                 isl_stream_push_token(s, tok2);
1511                 isl_stream_push_token(s, tok);
1512                 isl_stream_error(s, NULL,
1513                                  "expecting constraint matrix dimensions");
1514                 return NULL;
1515         }
1516         n_row = isl_int_get_si(tok->u.v);
1517         n_col = isl_int_get_si(tok2->u.v);
1518         on_new_line = tok2->on_new_line;
1519         isl_token_free(tok2);
1520         isl_token_free(tok);
1521         isl_assert(s->ctx, !on_new_line, return NULL);
1522         isl_assert(s->ctx, n_row >= 0, return NULL);
1523         isl_assert(s->ctx, n_col >= 2 + nparam, return NULL);
1524         tok = isl_stream_next_token_on_same_line(s);
1525         if (tok) {
1526                 if (tok->type != ISL_TOKEN_VALUE) {
1527                         isl_stream_error(s, tok,
1528                                     "expecting number of output dimensions");
1529                         isl_stream_push_token(s, tok);
1530                         goto error;
1531                 }
1532                 out = isl_int_get_si(tok->u.v);
1533                 isl_token_free(tok);
1534
1535                 tok = isl_stream_next_token_on_same_line(s);
1536                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
1537                         isl_stream_error(s, tok,
1538                                     "expecting number of input dimensions");
1539                         if (tok)
1540                                 isl_stream_push_token(s, tok);
1541                         goto error;
1542                 }
1543                 in = isl_int_get_si(tok->u.v);
1544                 isl_token_free(tok);
1545
1546                 tok = isl_stream_next_token_on_same_line(s);
1547                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
1548                         isl_stream_error(s, tok,
1549                                     "expecting number of existentials");
1550                         if (tok)
1551                                 isl_stream_push_token(s, tok);
1552                         goto error;
1553                 }
1554                 local = isl_int_get_si(tok->u.v);
1555                 isl_token_free(tok);
1556
1557                 tok = isl_stream_next_token_on_same_line(s);
1558                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
1559                         isl_stream_error(s, tok,
1560                                     "expecting number of parameters");
1561                         if (tok)
1562                                 isl_stream_push_token(s, tok);
1563                         goto error;
1564                 }
1565                 nparam = isl_int_get_si(tok->u.v);
1566                 isl_token_free(tok);
1567                 if (n_col != 1 + out + in + local + nparam + 1) {
1568                         isl_stream_error(s, NULL,
1569                                     "dimensions don't match");
1570                         goto error;
1571                 }
1572         } else
1573                 out = n_col - 2 - nparam;
1574         bmap = isl_basic_map_alloc(s->ctx, nparam, in, out, local, n_row, n_row);
1575         if (!bmap)
1576                 return NULL;
1577
1578         for (i = 0; i < local; ++i) {
1579                 int k = isl_basic_map_alloc_div(bmap);
1580                 if (k < 0)
1581                         goto error;
1582                 isl_seq_clr(bmap->div[k], 1 + 1 + nparam + in + out + local);
1583         }
1584
1585         for (i = 0; i < n_row; ++i)
1586                 bmap = basic_map_read_polylib_constraint(s, bmap);
1587
1588         tok = isl_stream_next_token_on_same_line(s);
1589         if (tok) {
1590                 isl_stream_error(s, tok, "unexpected extra token on line");
1591                 isl_stream_push_token(s, tok);
1592                 goto error;
1593         }
1594
1595         bmap = isl_basic_map_simplify(bmap);
1596         bmap = isl_basic_map_finalize(bmap);
1597         return bmap;
1598 error:
1599         isl_basic_map_free(bmap);
1600         return NULL;
1601 }
1602
1603 static struct isl_map *map_read_polylib(struct isl_stream *s, int nparam)
1604 {
1605         struct isl_token *tok;
1606         struct isl_token *tok2;
1607         int i, n;
1608         struct isl_map *map;
1609
1610         tok = isl_stream_next_token(s);
1611         if (!tok) {
1612                 isl_stream_error(s, NULL, "unexpected EOF");
1613                 return NULL;
1614         }
1615         tok2 = isl_stream_next_token_on_same_line(s);
1616         if (tok2 && tok2->type == ISL_TOKEN_VALUE) {
1617                 isl_stream_push_token(s, tok2);
1618                 isl_stream_push_token(s, tok);
1619                 return isl_map_from_basic_map(basic_map_read_polylib(s, nparam));
1620         }
1621         if (tok2) {
1622                 isl_stream_error(s, tok2, "unexpected token");
1623                 isl_stream_push_token(s, tok2);
1624                 isl_stream_push_token(s, tok);
1625                 return NULL;
1626         }
1627         n = isl_int_get_si(tok->u.v);
1628         isl_token_free(tok);
1629
1630         isl_assert(s->ctx, n >= 1, return NULL);
1631
1632         map = isl_map_from_basic_map(basic_map_read_polylib(s, nparam));
1633
1634         for (i = 1; map && i < n; ++i)
1635                 map = isl_map_union(map,
1636                         isl_map_from_basic_map(basic_map_read_polylib(s, nparam)));
1637
1638         return map;
1639 }
1640
1641 static int optional_power(struct isl_stream *s)
1642 {
1643         int pow;
1644         struct isl_token *tok;
1645
1646         tok = isl_stream_next_token(s);
1647         if (!tok)
1648                 return 1;
1649         if (tok->type != '^') {
1650                 isl_stream_push_token(s, tok);
1651                 return 1;
1652         }
1653         isl_token_free(tok);
1654         tok = isl_stream_next_token(s);
1655         if (!tok || tok->type != ISL_TOKEN_VALUE) {
1656                 isl_stream_error(s, tok, "expecting exponent");
1657                 if (tok)
1658                         isl_stream_push_token(s, tok);
1659                 return 1;
1660         }
1661         pow = isl_int_get_si(tok->u.v);
1662         isl_token_free(tok);
1663         return pow;
1664 }
1665
1666 static __isl_give isl_div *read_div(struct isl_stream *s,
1667         __isl_take isl_dim *dim, struct vars *v)
1668 {
1669         int n;
1670         isl_basic_map *bmap;
1671
1672         n = v->n;
1673         bmap = isl_basic_map_universe(dim);
1674
1675         if (vars_add_anon(v) < 0)
1676                 goto error;
1677         if (read_div_definition(s, v) < 0)
1678                 goto error;
1679         bmap = add_divs(bmap, v);
1680         bmap = isl_basic_map_order_divs(bmap);
1681         if (!bmap)
1682                 goto error;
1683         vars_drop(v, v->n - n);
1684
1685         return isl_basic_map_div(bmap, bmap->n_div - 1);
1686 error:
1687         isl_basic_map_free(bmap);
1688         return NULL;
1689 }
1690
1691 static __isl_give isl_qpolynomial *read_term(struct isl_stream *s,
1692         __isl_keep isl_basic_map *bmap, struct vars *v);
1693
1694 static __isl_give isl_qpolynomial *read_factor(struct isl_stream *s,
1695         __isl_keep isl_basic_map *bmap, struct vars *v)
1696 {
1697         struct isl_qpolynomial *qp;
1698         struct isl_token *tok;
1699
1700         tok = next_token(s);
1701         if (!tok) {
1702                 isl_stream_error(s, NULL, "unexpected EOF");
1703                 return NULL;
1704         }
1705         if (tok->type == '(') {
1706                 int pow;
1707
1708                 isl_token_free(tok);
1709                 qp = read_term(s, bmap, v);
1710                 if (!qp)
1711                         return NULL;
1712                 if (isl_stream_eat(s, ')'))
1713                         goto error;
1714                 pow = optional_power(s);
1715                 qp = isl_qpolynomial_pow(qp, pow);
1716         } else if (tok->type == ISL_TOKEN_VALUE) {
1717                 struct isl_token *tok2;
1718                 tok2 = isl_stream_next_token(s);
1719                 if (tok2 && tok2->type == '/') {
1720                         isl_token_free(tok2);
1721                         tok2 = next_token(s);
1722                         if (!tok2 || tok2->type != ISL_TOKEN_VALUE) {
1723                                 isl_stream_error(s, tok2, "expected denominator");
1724                                 isl_token_free(tok);
1725                                 isl_token_free(tok2);
1726                                 return NULL;
1727                         }
1728                         qp = isl_qpolynomial_rat_cst(isl_basic_map_get_dim(bmap),
1729                                                     tok->u.v, tok2->u.v);
1730                         isl_token_free(tok2);
1731                 } else {
1732                         isl_stream_push_token(s, tok2);
1733                         qp = isl_qpolynomial_cst(isl_basic_map_get_dim(bmap),
1734                                                 tok->u.v);
1735                 }
1736                 isl_token_free(tok);
1737         } else if (tok->type == ISL_TOKEN_INFTY) {
1738                 isl_token_free(tok);
1739                 qp = isl_qpolynomial_infty(isl_basic_map_get_dim(bmap));
1740         } else if (tok->type == ISL_TOKEN_NAN) {
1741                 isl_token_free(tok);
1742                 qp = isl_qpolynomial_nan(isl_basic_map_get_dim(bmap));
1743         } else if (tok->type == ISL_TOKEN_IDENT) {
1744                 int n = v->n;
1745                 int pos = vars_pos(v, tok->u.s, -1);
1746                 int pow;
1747                 if (pos < 0) {
1748                         isl_token_free(tok);
1749                         return NULL;
1750                 }
1751                 if (pos >= n) {
1752                         vars_drop(v, v->n - n);
1753                         isl_stream_error(s, tok, "unknown identifier");
1754                         isl_token_free(tok);
1755                         return NULL;
1756                 }
1757                 isl_token_free(tok);
1758                 pow = optional_power(s);
1759                 qp = isl_qpolynomial_var_pow(isl_basic_map_get_dim(bmap), pos, pow);
1760         } else if (tok->type == '[') {
1761                 isl_div *div;
1762                 int pow;
1763
1764                 isl_stream_push_token(s, tok);
1765                 div = read_div(s, isl_basic_map_get_dim(bmap), v);
1766                 pow = optional_power(s);
1767                 qp = isl_qpolynomial_div_pow(div, pow);
1768         } else if (tok->type == '-') {
1769                 struct isl_qpolynomial *qp2;
1770
1771                 isl_token_free(tok);
1772                 qp = isl_qpolynomial_cst(isl_basic_map_get_dim(bmap),
1773                                             s->ctx->negone);
1774                 qp2 = read_factor(s, bmap, v);
1775                 qp = isl_qpolynomial_mul(qp, qp2);
1776         } else {
1777                 isl_stream_error(s, tok, "unexpected isl_token");
1778                 isl_stream_push_token(s, tok);
1779                 return NULL;
1780         }
1781
1782         if (isl_stream_eat_if_available(s, '*') ||
1783             isl_stream_next_token_is(s, ISL_TOKEN_IDENT)) {
1784                 struct isl_qpolynomial *qp2;
1785
1786                 qp2 = read_factor(s, bmap, v);
1787                 qp = isl_qpolynomial_mul(qp, qp2);
1788         }
1789
1790         return qp;
1791 error:
1792         isl_qpolynomial_free(qp);
1793         return NULL;
1794 }
1795
1796 static __isl_give isl_qpolynomial *read_term(struct isl_stream *s,
1797         __isl_keep isl_basic_map *bmap, struct vars *v)
1798 {
1799         struct isl_token *tok;
1800         struct isl_qpolynomial *qp;
1801
1802         qp = read_factor(s, bmap, v);
1803
1804         for (;;) {
1805                 tok = next_token(s);
1806                 if (!tok)
1807                         return qp;
1808
1809                 if (tok->type == '+') {
1810                         struct isl_qpolynomial *qp2;
1811
1812                         isl_token_free(tok);
1813                         qp2 = read_factor(s, bmap, v);
1814                         qp = isl_qpolynomial_add(qp, qp2);
1815                 } else if (tok->type == '-') {
1816                         struct isl_qpolynomial *qp2;
1817
1818                         isl_token_free(tok);
1819                         qp2 = read_factor(s, bmap, v);
1820                         qp = isl_qpolynomial_sub(qp, qp2);
1821                 } else if (tok->type == ISL_TOKEN_VALUE &&
1822                             isl_int_is_neg(tok->u.v)) {
1823                         struct isl_qpolynomial *qp2;
1824
1825                         isl_stream_push_token(s, tok);
1826                         qp2 = read_factor(s, bmap, v);
1827                         qp = isl_qpolynomial_add(qp, qp2);
1828                 } else {
1829                         isl_stream_push_token(s, tok);
1830                         break;
1831                 }
1832         }
1833
1834         return qp;
1835 }
1836
1837 static __isl_give isl_map *read_optional_disjuncts(struct isl_stream *s,
1838         __isl_take isl_basic_map *bmap, struct vars *v)
1839 {
1840         struct isl_token *tok;
1841         struct isl_map *map;
1842
1843         tok = isl_stream_next_token(s);
1844         if (!tok) {
1845                 isl_stream_error(s, NULL, "unexpected EOF");
1846                 goto error;
1847         }
1848         map = isl_map_from_basic_map(isl_basic_map_copy(bmap));
1849         if (tok->type == ':' ||
1850             (tok->type == ISL_TOKEN_OR && !strcmp(tok->u.s, "|"))) {
1851                 isl_token_free(tok);
1852                 map = isl_map_intersect(map,
1853                             read_disjuncts(s, v, isl_basic_map_copy(bmap)));
1854         } else
1855                 isl_stream_push_token(s, tok);
1856
1857         isl_basic_map_free(bmap);
1858
1859         return map;
1860 error:
1861         isl_basic_map_free(bmap);
1862         return NULL;
1863 }
1864
1865 static struct isl_obj obj_read_poly(struct isl_stream *s,
1866         __isl_take isl_basic_map *bmap, struct vars *v, int n)
1867 {
1868         struct isl_obj obj = { isl_obj_pw_qpolynomial, NULL };
1869         struct isl_pw_qpolynomial *pwqp;
1870         struct isl_qpolynomial *qp;
1871         struct isl_map *map;
1872         struct isl_set *set;
1873
1874         qp = read_term(s, bmap, v);
1875         map = read_optional_disjuncts(s, bmap, v);
1876         set = isl_map_range(map);
1877
1878         pwqp = isl_pw_qpolynomial_alloc(set, qp);
1879
1880         vars_drop(v, v->n - n);
1881
1882         obj.v = pwqp;
1883         return obj;
1884 }
1885
1886 static struct isl_obj obj_read_poly_or_fold(struct isl_stream *s,
1887         __isl_take isl_basic_map *bmap, struct vars *v, int n)
1888 {
1889         struct isl_obj obj = { isl_obj_pw_qpolynomial_fold, NULL };
1890         struct isl_obj obj_p;
1891         isl_qpolynomial *qp;
1892         isl_qpolynomial_fold *fold = NULL;
1893         isl_pw_qpolynomial_fold *pwf;
1894         isl_map *map;
1895         isl_set *set;
1896
1897         if (!isl_stream_eat_if_available(s, ISL_TOKEN_MAX))
1898                 return obj_read_poly(s, bmap, v, n);
1899
1900         if (isl_stream_eat(s, '('))
1901                 goto error;
1902
1903         qp = read_term(s, bmap, v);
1904         fold = isl_qpolynomial_fold_alloc(isl_fold_max, qp);
1905
1906         while (isl_stream_eat_if_available(s, ',')) {
1907                 isl_qpolynomial_fold *fold_i;
1908                 qp = read_term(s, bmap, v);
1909                 fold_i = isl_qpolynomial_fold_alloc(isl_fold_max, qp);
1910                 fold = isl_qpolynomial_fold_fold(fold, fold_i);
1911         }
1912
1913         if (isl_stream_eat(s, ')'))
1914                 goto error;
1915
1916         map = read_optional_disjuncts(s, bmap, v);
1917         set = isl_map_range(map);
1918         pwf = isl_pw_qpolynomial_fold_alloc(isl_fold_max, set, fold);
1919
1920         vars_drop(v, v->n - n);
1921
1922         obj.v = pwf;
1923         return obj;
1924 error:
1925         isl_basic_map_free(bmap);
1926         isl_qpolynomial_fold_free(fold);
1927         obj.type = isl_obj_none;
1928         return obj;
1929 }
1930
1931 static int is_rational(struct isl_stream *s)
1932 {
1933         struct isl_token *tok;
1934
1935         tok = isl_stream_next_token(s);
1936         if (!tok)
1937                 return 0;
1938         if (tok->type == ISL_TOKEN_RAT && isl_stream_next_token_is(s, ':')) {
1939                 isl_token_free(tok);
1940                 isl_stream_eat(s, ':');
1941                 return 1;
1942         }
1943
1944         isl_stream_push_token(s, tok);
1945
1946         return 0;
1947 }
1948
1949 static struct isl_obj obj_read_body(struct isl_stream *s,
1950         __isl_take isl_basic_map *bmap, struct vars *v)
1951 {
1952         struct isl_map *map = NULL;
1953         struct isl_token *tok;
1954         struct isl_obj obj = { isl_obj_set, NULL };
1955         int n = v->n;
1956
1957         if (is_rational(s))
1958                 bmap = isl_basic_map_set_rational(bmap);
1959
1960         if (!next_is_tuple(s))
1961                 return obj_read_poly_or_fold(s, bmap, v, n);
1962
1963         bmap = read_tuple(s, bmap, isl_dim_in, v);
1964         if (!bmap)
1965                 goto error;
1966         tok = isl_stream_next_token(s);
1967         if (tok && tok->type == ISL_TOKEN_TO) {
1968                 obj.type = isl_obj_map;
1969                 isl_token_free(tok);
1970                 if (!next_is_tuple(s)) {
1971                         bmap = isl_basic_map_reverse(bmap);
1972                         return obj_read_poly_or_fold(s, bmap, v, n);
1973                 }
1974                 bmap = read_tuple(s, bmap, isl_dim_out, v);
1975                 if (!bmap)
1976                         goto error;
1977         } else {
1978                 bmap = isl_basic_map_reverse(bmap);
1979                 if (tok)
1980                         isl_stream_push_token(s, tok);
1981         }
1982
1983         map = read_optional_disjuncts(s, bmap, v);
1984
1985         vars_drop(v, v->n - n);
1986
1987         obj.v = map;
1988         return obj;
1989 error:
1990         isl_basic_map_free(bmap);
1991         obj.type = isl_obj_none;
1992         return obj;
1993 }
1994
1995 static struct isl_obj to_union(isl_ctx *ctx, struct isl_obj obj)
1996 {
1997         if (obj.type == isl_obj_map) {
1998                 obj.v = isl_union_map_from_map(obj.v);
1999                 obj.type = isl_obj_union_map;
2000         } else if (obj.type == isl_obj_set) {
2001                 obj.v = isl_union_set_from_set(obj.v);
2002                 obj.type = isl_obj_union_set;
2003         } else if (obj.type == isl_obj_pw_qpolynomial) {
2004                 obj.v = isl_union_pw_qpolynomial_from_pw_qpolynomial(obj.v);
2005                 obj.type = isl_obj_union_pw_qpolynomial;
2006         } else if (obj.type == isl_obj_pw_qpolynomial_fold) {
2007                 obj.v = isl_union_pw_qpolynomial_fold_from_pw_qpolynomial_fold(obj.v);
2008                 obj.type = isl_obj_union_pw_qpolynomial_fold;
2009         } else
2010                 isl_assert(ctx, 0, goto error);
2011         return obj;
2012 error:
2013         obj.type->free(obj.v);
2014         obj.type = isl_obj_none;
2015         return obj;
2016 }
2017
2018 static struct isl_obj obj_add(struct isl_ctx *ctx,
2019         struct isl_obj obj1, struct isl_obj obj2)
2020 {
2021         if (obj1.type == isl_obj_set && obj2.type == isl_obj_union_set)
2022                 obj1 = to_union(ctx, obj1);
2023         if (obj1.type == isl_obj_union_set && obj2.type == isl_obj_set)
2024                 obj2 = to_union(ctx, obj2);
2025         if (obj1.type == isl_obj_map && obj2.type == isl_obj_union_map)
2026                 obj1 = to_union(ctx, obj1);
2027         if (obj1.type == isl_obj_union_map && obj2.type == isl_obj_map)
2028                 obj2 = to_union(ctx, obj2);
2029         if (obj1.type == isl_obj_pw_qpolynomial &&
2030             obj2.type == isl_obj_union_pw_qpolynomial)
2031                 obj1 = to_union(ctx, obj1);
2032         if (obj1.type == isl_obj_union_pw_qpolynomial &&
2033             obj2.type == isl_obj_pw_qpolynomial)
2034                 obj2 = to_union(ctx, obj2);
2035         if (obj1.type == isl_obj_pw_qpolynomial_fold &&
2036             obj2.type == isl_obj_union_pw_qpolynomial_fold)
2037                 obj1 = to_union(ctx, obj1);
2038         if (obj1.type == isl_obj_union_pw_qpolynomial_fold &&
2039             obj2.type == isl_obj_pw_qpolynomial_fold)
2040                 obj2 = to_union(ctx, obj2);
2041         isl_assert(ctx, obj1.type == obj2.type, goto error);
2042         if (obj1.type == isl_obj_map && !isl_map_has_equal_dim(obj1.v, obj2.v)) {
2043                 obj1 = to_union(ctx, obj1);
2044                 obj2 = to_union(ctx, obj2);
2045         }
2046         if (obj1.type == isl_obj_set && !isl_set_has_equal_dim(obj1.v, obj2.v)) {
2047                 obj1 = to_union(ctx, obj1);
2048                 obj2 = to_union(ctx, obj2);
2049         }
2050         if (obj1.type == isl_obj_pw_qpolynomial &&
2051             !isl_pw_qpolynomial_has_equal_dim(obj1.v, obj2.v)) {
2052                 obj1 = to_union(ctx, obj1);
2053                 obj2 = to_union(ctx, obj2);
2054         }
2055         if (obj1.type == isl_obj_pw_qpolynomial_fold &&
2056             !isl_pw_qpolynomial_fold_has_equal_dim(obj1.v, obj2.v)) {
2057                 obj1 = to_union(ctx, obj1);
2058                 obj2 = to_union(ctx, obj2);
2059         }
2060         obj1.v = obj1.type->add(obj1.v, obj2.v);
2061         return obj1;
2062 error:
2063         obj1.type->free(obj1.v);
2064         obj2.type->free(obj2.v);
2065         obj1.type = isl_obj_none;
2066         obj1.v = NULL;
2067         return obj1;
2068 }
2069
2070 static struct isl_obj obj_read(struct isl_stream *s, int nparam)
2071 {
2072         isl_basic_map *bmap = NULL;
2073         struct isl_token *tok;
2074         struct vars *v = NULL;
2075         struct isl_obj obj = { isl_obj_set, NULL };
2076
2077         tok = next_token(s);
2078         if (!tok) {
2079                 isl_stream_error(s, NULL, "unexpected EOF");
2080                 goto error;
2081         }
2082         if (tok->type == ISL_TOKEN_VALUE) {
2083                 struct isl_token *tok2;
2084                 struct isl_map *map;
2085
2086                 tok2 = isl_stream_next_token(s);
2087                 if (!tok2 || tok2->type != ISL_TOKEN_VALUE ||
2088                     isl_int_is_neg(tok2->u.v)) {
2089                         if (tok2)
2090                                 isl_stream_push_token(s, tok2);
2091                         obj.type = isl_obj_int;
2092                         obj.v = isl_int_obj_alloc(s->ctx, tok->u.v);
2093                         isl_token_free(tok);
2094                         return obj;
2095                 }
2096                 isl_stream_push_token(s, tok2);
2097                 isl_stream_push_token(s, tok);
2098                 map = map_read_polylib(s, nparam);
2099                 if (!map)
2100                         goto error;
2101                 if (isl_map_dim(map, isl_dim_in) > 0)
2102                         obj.type = isl_obj_map;
2103                 obj.v = map;
2104                 return obj;
2105         }
2106         v = vars_new(s->ctx);
2107         if (!v) {
2108                 isl_stream_push_token(s, tok);
2109                 goto error;
2110         }
2111         bmap = isl_basic_map_alloc(s->ctx, 0, 0, 0, 0, 0, 0);
2112         if (tok->type == '[') {
2113                 isl_stream_push_token(s, tok);
2114                 bmap = read_tuple(s, bmap, isl_dim_param, v);
2115                 if (!bmap)
2116                         goto error;
2117                 if (nparam >= 0)
2118                         isl_assert(s->ctx, nparam == v->n, goto error);
2119                 tok = isl_stream_next_token(s);
2120                 if (!tok || tok->type != ISL_TOKEN_TO) {
2121                         isl_stream_error(s, tok, "expecting '->'");
2122                         if (tok)
2123                                 isl_stream_push_token(s, tok);
2124                         goto error;
2125                 }
2126                 isl_token_free(tok);
2127                 tok = isl_stream_next_token(s);
2128         } else if (nparam > 0)
2129                 bmap = isl_basic_map_add(bmap, isl_dim_param, nparam);
2130         if (!tok || tok->type != '{') {
2131                 isl_stream_error(s, tok, "expecting '{'");
2132                 if (tok)
2133                         isl_stream_push_token(s, tok);
2134                 goto error;
2135         }
2136         isl_token_free(tok);
2137
2138         tok = isl_stream_next_token(s);
2139         if (!tok)
2140                 ;
2141         else if (tok->type == ISL_TOKEN_IDENT && !strcmp(tok->u.s, "Sym")) {
2142                 isl_token_free(tok);
2143                 if (isl_stream_eat(s, '='))
2144                         goto error;
2145                 bmap = read_tuple(s, bmap, isl_dim_param, v);
2146                 if (!bmap)
2147                         goto error;
2148                 if (nparam >= 0)
2149                         isl_assert(s->ctx, nparam == v->n, goto error);
2150         } else if (tok->type == '}') {
2151                 obj.type = isl_obj_union_set;
2152                 obj.v = isl_union_set_empty(isl_basic_map_get_dim(bmap));
2153                 isl_token_free(tok);
2154                 goto done;
2155         } else
2156                 isl_stream_push_token(s, tok);
2157
2158         for (;;) {
2159                 struct isl_obj o;
2160                 tok = NULL;
2161                 o = obj_read_body(s, isl_basic_map_copy(bmap), v);
2162                 if (o.type == isl_obj_none || !o.v)
2163                         goto error;
2164                 if (!obj.v)
2165                         obj = o;
2166                 else {
2167                         obj = obj_add(s->ctx, obj, o);
2168                         if (obj.type == isl_obj_none || !obj.v)
2169                                 goto error;
2170                 }
2171                 tok = isl_stream_next_token(s);
2172                 if (!tok || tok->type != ';')
2173                         break;
2174                 isl_token_free(tok);
2175                 if (isl_stream_next_token_is(s, '}')) {
2176                         tok = isl_stream_next_token(s);
2177                         break;
2178                 }
2179         }
2180
2181         if (tok && tok->type == '}') {
2182                 isl_token_free(tok);
2183         } else {
2184                 isl_stream_error(s, tok, "unexpected isl_token");
2185                 if (tok)
2186                         isl_token_free(tok);
2187                 goto error;
2188         }
2189 done:
2190         vars_free(v);
2191         isl_basic_map_free(bmap);
2192
2193         return obj;
2194 error:
2195         isl_basic_map_free(bmap);
2196         obj.type->free(obj.v);
2197         if (v)
2198                 vars_free(v);
2199         obj.v = NULL;
2200         return obj;
2201 }
2202
2203 struct isl_obj isl_stream_read_obj(struct isl_stream *s)
2204 {
2205         return obj_read(s, -1);
2206 }
2207
2208 __isl_give isl_map *isl_stream_read_map(struct isl_stream *s, int nparam)
2209 {
2210         struct isl_obj obj;
2211         struct isl_map *map;
2212
2213         obj = obj_read(s, nparam);
2214         if (obj.v)
2215                 isl_assert(s->ctx, obj.type == isl_obj_map ||
2216                                    obj.type == isl_obj_set, goto error);
2217
2218         return obj.v;
2219 error:
2220         obj.type->free(obj.v);
2221         return NULL;
2222 }
2223
2224 __isl_give isl_set *isl_stream_read_set(struct isl_stream *s, int nparam)
2225 {
2226         struct isl_obj obj;
2227         struct isl_set *set;
2228
2229         obj = obj_read(s, nparam);
2230         if (obj.v)
2231                 isl_assert(s->ctx, obj.type == isl_obj_set, goto error);
2232
2233         return obj.v;
2234 error:
2235         obj.type->free(obj.v);
2236         return NULL;
2237 }
2238
2239 __isl_give isl_union_map *isl_stream_read_union_map(struct isl_stream *s)
2240 {
2241         struct isl_obj obj;
2242         isl_union_map *umap;
2243
2244         obj = obj_read(s, -1);
2245         if (obj.type == isl_obj_map) {
2246                 obj.type = isl_obj_union_map;
2247                 obj.v = isl_union_map_from_map(obj.v);
2248         }
2249         if (obj.type == isl_obj_set) {
2250                 obj.type = isl_obj_union_set;
2251                 obj.v = isl_union_set_from_set(obj.v);
2252         }
2253         if (obj.v)
2254                 isl_assert(s->ctx, obj.type == isl_obj_union_map ||
2255                                    obj.type == isl_obj_union_set, goto error);
2256
2257         return obj.v;
2258 error:
2259         obj.type->free(obj.v);
2260         return NULL;
2261 }
2262
2263 __isl_give isl_union_set *isl_stream_read_union_set(struct isl_stream *s)
2264 {
2265         struct isl_obj obj;
2266         isl_union_set *uset;
2267
2268         obj = obj_read(s, -1);
2269         if (obj.type == isl_obj_set) {
2270                 obj.type = isl_obj_union_set;
2271                 obj.v = isl_union_set_from_set(obj.v);
2272         }
2273         if (obj.v)
2274                 isl_assert(s->ctx, obj.type == isl_obj_union_set, goto error);
2275
2276         return obj.v;
2277 error:
2278         obj.type->free(obj.v);
2279         return NULL;
2280 }
2281
2282 static struct isl_basic_map *basic_map_read(struct isl_stream *s, int nparam)
2283 {
2284         struct isl_obj obj;
2285         struct isl_map *map;
2286         struct isl_basic_map *bmap;
2287
2288         obj = obj_read(s, nparam);
2289         map = obj.v;
2290         if (!map)
2291                 return NULL;
2292
2293         isl_assert(map->ctx, map->n <= 1, goto error);
2294
2295         if (map->n == 0)
2296                 bmap = isl_basic_map_empty_like_map(map);
2297         else
2298                 bmap = isl_basic_map_copy(map->p[0]);
2299
2300         isl_map_free(map);
2301
2302         return bmap;
2303 error:
2304         isl_map_free(map);
2305         return NULL;
2306 }
2307
2308 __isl_give isl_basic_map *isl_basic_map_read_from_file(isl_ctx *ctx,
2309                 FILE *input, int nparam)
2310 {
2311         struct isl_basic_map *bmap;
2312         struct isl_stream *s = isl_stream_new_file(ctx, input);
2313         if (!s)
2314                 return NULL;
2315         bmap = basic_map_read(s, nparam);
2316         isl_stream_free(s);
2317         return bmap;
2318 }
2319
2320 __isl_give isl_basic_set *isl_basic_set_read_from_file(isl_ctx *ctx,
2321                 FILE *input, int nparam)
2322 {
2323         struct isl_basic_map *bmap;
2324         bmap = isl_basic_map_read_from_file(ctx, input, nparam);
2325         if (!bmap)
2326                 return NULL;
2327         isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
2328         return (struct isl_basic_set *)bmap;
2329 error:
2330         isl_basic_map_free(bmap);
2331         return NULL;
2332 }
2333
2334 struct isl_basic_map *isl_basic_map_read_from_str(struct isl_ctx *ctx,
2335                 const char *str, int nparam)
2336 {
2337         struct isl_basic_map *bmap;
2338         struct isl_stream *s = isl_stream_new_str(ctx, str);
2339         if (!s)
2340                 return NULL;
2341         bmap = basic_map_read(s, nparam);
2342         isl_stream_free(s);
2343         return bmap;
2344 }
2345
2346 struct isl_basic_set *isl_basic_set_read_from_str(struct isl_ctx *ctx,
2347                 const char *str, int nparam)
2348 {
2349         struct isl_basic_map *bmap;
2350         bmap = isl_basic_map_read_from_str(ctx, str, nparam);
2351         if (!bmap)
2352                 return NULL;
2353         isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
2354         return (struct isl_basic_set *)bmap;
2355 error:
2356         isl_basic_map_free(bmap);
2357         return NULL;
2358 }
2359
2360 __isl_give isl_map *isl_map_read_from_file(struct isl_ctx *ctx,
2361                 FILE *input, int nparam)
2362 {
2363         struct isl_map *map;
2364         struct isl_stream *s = isl_stream_new_file(ctx, input);
2365         if (!s)
2366                 return NULL;
2367         map = isl_stream_read_map(s, nparam);
2368         isl_stream_free(s);
2369         return map;
2370 }
2371
2372 __isl_give isl_map *isl_map_read_from_str(struct isl_ctx *ctx,
2373                 const char *str, int nparam)
2374 {
2375         struct isl_map *map;
2376         struct isl_stream *s = isl_stream_new_str(ctx, str);
2377         if (!s)
2378                 return NULL;
2379         map = isl_stream_read_map(s, nparam);
2380         isl_stream_free(s);
2381         return map;
2382 }
2383
2384 __isl_give isl_set *isl_set_read_from_file(struct isl_ctx *ctx,
2385                 FILE *input, int nparam)
2386 {
2387         struct isl_map *map;
2388         map = isl_map_read_from_file(ctx, input, nparam);
2389         if (!map)
2390                 return NULL;
2391         isl_assert(ctx, isl_map_n_in(map) == 0, goto error);
2392         return (struct isl_set *)map;
2393 error:
2394         isl_map_free(map);
2395         return NULL;
2396 }
2397
2398 struct isl_set *isl_set_read_from_str(struct isl_ctx *ctx,
2399                 const char *str, int nparam)
2400 {
2401         struct isl_map *map;
2402         map = isl_map_read_from_str(ctx, str, nparam);
2403         if (!map)
2404                 return NULL;
2405         isl_assert(ctx, isl_map_n_in(map) == 0, goto error);
2406         return (struct isl_set *)map;
2407 error:
2408         isl_map_free(map);
2409         return NULL;
2410 }
2411
2412 __isl_give isl_union_map *isl_union_map_read_from_file(isl_ctx *ctx,
2413         FILE *input)
2414 {
2415         isl_union_map *umap;
2416         struct isl_stream *s = isl_stream_new_file(ctx, input);
2417         if (!s)
2418                 return NULL;
2419         umap = isl_stream_read_union_map(s);
2420         isl_stream_free(s);
2421         return umap;
2422 }
2423
2424 __isl_give isl_union_map *isl_union_map_read_from_str(struct isl_ctx *ctx,
2425                 const char *str)
2426 {
2427         isl_union_map *umap;
2428         struct isl_stream *s = isl_stream_new_str(ctx, str);
2429         if (!s)
2430                 return NULL;
2431         umap = isl_stream_read_union_map(s);
2432         isl_stream_free(s);
2433         return umap;
2434 }
2435
2436 __isl_give isl_union_set *isl_union_set_read_from_file(isl_ctx *ctx,
2437         FILE *input)
2438 {
2439         isl_union_set *uset;
2440         struct isl_stream *s = isl_stream_new_file(ctx, input);
2441         if (!s)
2442                 return NULL;
2443         uset = isl_stream_read_union_set(s);
2444         isl_stream_free(s);
2445         return uset;
2446 }
2447
2448 __isl_give isl_union_set *isl_union_set_read_from_str(struct isl_ctx *ctx,
2449                 const char *str)
2450 {
2451         isl_union_set *uset;
2452         struct isl_stream *s = isl_stream_new_str(ctx, str);
2453         if (!s)
2454                 return NULL;
2455         uset = isl_stream_read_union_set(s);
2456         isl_stream_free(s);
2457         return uset;
2458 }
2459
2460 static __isl_give isl_vec *isl_vec_read_polylib(struct isl_stream *s)
2461 {
2462         struct isl_vec *vec = NULL;
2463         struct isl_token *tok;
2464         unsigned size;
2465         int j;
2466
2467         tok = isl_stream_next_token(s);
2468         if (!tok || tok->type != ISL_TOKEN_VALUE) {
2469                 isl_stream_error(s, tok, "expecting vector length");
2470                 goto error;
2471         }
2472
2473         size = isl_int_get_si(tok->u.v);
2474         isl_token_free(tok);
2475
2476         vec = isl_vec_alloc(s->ctx, size);
2477
2478         for (j = 0; j < size; ++j) {
2479                 tok = isl_stream_next_token(s);
2480                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
2481                         isl_stream_error(s, tok, "expecting constant value");
2482                         goto error;
2483                 }
2484                 isl_int_set(vec->el[j], tok->u.v);
2485                 isl_token_free(tok);
2486         }
2487
2488         return vec;
2489 error:
2490         isl_token_free(tok);
2491         isl_vec_free(vec);
2492         return NULL;
2493 }
2494
2495 static __isl_give isl_vec *vec_read(struct isl_stream *s)
2496 {
2497         return isl_vec_read_polylib(s);
2498 }
2499
2500 __isl_give isl_vec *isl_vec_read_from_file(isl_ctx *ctx, FILE *input)
2501 {
2502         isl_vec *v;
2503         struct isl_stream *s = isl_stream_new_file(ctx, input);
2504         if (!s)
2505                 return NULL;
2506         v = vec_read(s);
2507         isl_stream_free(s);
2508         return v;
2509 }
2510
2511 __isl_give isl_pw_qpolynomial *isl_stream_read_pw_qpolynomial(
2512         struct isl_stream *s)
2513 {
2514         struct isl_obj obj;
2515         struct isl_pw_qpolynomial *pwqp;
2516
2517         obj = obj_read(s, -1);
2518         if (obj.v)
2519                 isl_assert(s->ctx, obj.type == isl_obj_pw_qpolynomial,
2520                            goto error);
2521
2522         return obj.v;
2523 error:
2524         obj.type->free(obj.v);
2525         return NULL;
2526 }
2527
2528 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_read_from_str(isl_ctx *ctx,
2529                 const char *str)
2530 {
2531         isl_pw_qpolynomial *pwqp;
2532         struct isl_stream *s = isl_stream_new_str(ctx, str);
2533         if (!s)
2534                 return NULL;
2535         pwqp = isl_stream_read_pw_qpolynomial(s);
2536         isl_stream_free(s);
2537         return pwqp;
2538 }