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