add isl_printer_indent
[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         struct variable *var;
1236
1237         while (n < v->n) {
1238                 var = first_minmax(v, n);
1239                 if (!var)
1240                         break;
1241                 if (all_coefficients_of_sign(map, var->pos, -var->sign))
1242                         map = bound_minmax(map, var);
1243                 else
1244                         map = set_minmax(map, var);
1245                 n = var->pos + 1;
1246         }
1247
1248         return map;
1249 }
1250
1251 static isl_map *read_constraint(struct isl_stream *s,
1252         struct vars *v, __isl_take isl_basic_map *bmap)
1253 {
1254         int n = v->n;
1255         isl_map *map;
1256         unsigned total;
1257
1258         if (!bmap)
1259                 return NULL;
1260
1261         bmap = isl_basic_set_unwrap(isl_basic_set_lift(isl_basic_map_wrap(bmap)));
1262         total = isl_basic_map_total_dim(bmap);
1263         while (v->n < total)
1264                 if (vars_add_anon(v) < 0)
1265                         goto error;
1266
1267         bmap = add_constraint(s, v, bmap);
1268         bmap = isl_basic_map_simplify(bmap);
1269         bmap = isl_basic_map_finalize(bmap);
1270
1271         map = isl_map_from_basic_map(bmap);
1272
1273         map = add_minmax(map, v, n);
1274
1275         map = isl_set_unwrap(isl_map_domain(map));
1276
1277         vars_drop(v, v->n - n);
1278
1279         return map;
1280 error:
1281         isl_basic_map_free(bmap);
1282         return NULL;
1283 }
1284
1285 static struct isl_map *read_disjuncts(struct isl_stream *s,
1286         struct vars *v, __isl_take isl_basic_map *bmap);
1287
1288 static __isl_give isl_map *read_exists(struct isl_stream *s,
1289         struct vars *v, __isl_take isl_basic_map *bmap)
1290 {
1291         int n = v->n;
1292         int seen_paren = isl_stream_eat_if_available(s, '(');
1293         isl_map *map = NULL;
1294
1295         bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
1296         bmap = read_defined_var_list(s, v, bmap);
1297
1298         if (isl_stream_eat(s, ':'))
1299                 goto error;
1300
1301         map = read_disjuncts(s, v, bmap);
1302         map = isl_set_unwrap(isl_map_domain(map));
1303         bmap = NULL;
1304
1305         vars_drop(v, v->n - n);
1306         if (seen_paren && isl_stream_eat(s, ')'))
1307                 goto error;
1308
1309         return map;
1310 error:
1311         isl_basic_map_free(bmap);
1312         isl_map_free(map);
1313         return NULL;
1314 }
1315
1316 static __isl_give isl_map *read_conjunct(struct isl_stream *s,
1317         struct vars *v, __isl_take isl_basic_map *bmap)
1318 {
1319         isl_map *map;
1320
1321         if (isl_stream_eat_if_available(s, '(')) {
1322                 map = read_disjuncts(s, v, bmap);
1323                 if (isl_stream_eat(s, ')'))
1324                         goto error;
1325                 return map;
1326         }
1327
1328         if (isl_stream_eat_if_available(s, ISL_TOKEN_EXISTS))
1329                 return read_exists(s, v, bmap);
1330
1331         if (isl_stream_eat_if_available(s, ISL_TOKEN_TRUE))
1332                 return isl_map_from_basic_map(bmap);
1333
1334         if (isl_stream_eat_if_available(s, ISL_TOKEN_FALSE)) {
1335                 isl_dim *dim = isl_basic_map_get_dim(bmap);
1336                 isl_basic_map_free(bmap);
1337                 return isl_map_empty(dim);
1338         }
1339                 
1340         return read_constraint(s, v, bmap);
1341 error:
1342         isl_map_free(map);
1343         return NULL;
1344 }
1345
1346 static __isl_give isl_map *read_conjuncts(struct isl_stream *s,
1347         struct vars *v, __isl_take isl_basic_map *bmap)
1348 {
1349         isl_map *map;
1350         int negate;
1351
1352         negate = isl_stream_eat_if_available(s, ISL_TOKEN_NOT);
1353         map = read_conjunct(s, v, isl_basic_map_copy(bmap));
1354         if (negate) {
1355                 isl_map *t;
1356                 t = isl_map_from_basic_map(isl_basic_map_copy(bmap));
1357                 map = isl_map_subtract(t, map);
1358         }
1359
1360         while (isl_stream_eat_if_available(s, ISL_TOKEN_AND)) {
1361                 isl_map *map_i;
1362
1363                 negate = isl_stream_eat_if_available(s, ISL_TOKEN_NOT);
1364                 map_i = read_conjunct(s, v, isl_basic_map_copy(bmap));
1365                 if (negate)
1366                         map = isl_map_subtract(map, map_i);
1367                 else
1368                         map = isl_map_intersect(map, map_i);
1369         }
1370
1371         isl_basic_map_free(bmap);
1372         return map;
1373 }
1374
1375 static struct isl_map *read_disjuncts(struct isl_stream *s,
1376         struct vars *v, __isl_take isl_basic_map *bmap)
1377 {
1378         struct isl_map *map;
1379
1380         if (isl_stream_next_token_is(s, '}')) {
1381                 isl_dim *dim = isl_basic_map_get_dim(bmap);
1382                 isl_basic_map_free(bmap);
1383                 return isl_map_universe(dim);
1384         }
1385
1386         map = read_conjuncts(s, v, isl_basic_map_copy(bmap));
1387         while (isl_stream_eat_if_available(s, ISL_TOKEN_OR)) {
1388                 isl_map *map_i;
1389
1390                 map_i = read_conjuncts(s, v, isl_basic_map_copy(bmap));
1391                 map = isl_map_union(map, map_i);
1392         }
1393
1394         isl_basic_map_free(bmap);
1395         return map;
1396 }
1397
1398 static int polylib_pos_to_isl_pos(__isl_keep isl_basic_map *bmap, int pos)
1399 {
1400         if (pos < isl_basic_map_dim(bmap, isl_dim_out))
1401                 return 1 + isl_basic_map_dim(bmap, isl_dim_param) +
1402                            isl_basic_map_dim(bmap, isl_dim_in) + pos;
1403         pos -= isl_basic_map_dim(bmap, isl_dim_out);
1404
1405         if (pos < isl_basic_map_dim(bmap, isl_dim_in))
1406                 return 1 + isl_basic_map_dim(bmap, isl_dim_param) + pos;
1407         pos -= isl_basic_map_dim(bmap, isl_dim_in);
1408
1409         if (pos < isl_basic_map_dim(bmap, isl_dim_div))
1410                 return 1 + isl_basic_map_dim(bmap, isl_dim_param) +
1411                            isl_basic_map_dim(bmap, isl_dim_in) +
1412                            isl_basic_map_dim(bmap, isl_dim_out) + pos;
1413         pos -= isl_basic_map_dim(bmap, isl_dim_div);
1414
1415         if (pos < isl_basic_map_dim(bmap, isl_dim_param))
1416                 return 1 + pos;
1417
1418         return 0;
1419 }
1420
1421 static __isl_give isl_basic_map *basic_map_read_polylib_constraint(
1422         struct isl_stream *s, __isl_take isl_basic_map *bmap)
1423 {
1424         int j;
1425         struct isl_token *tok;
1426         int type;
1427         int k;
1428         isl_int *c;
1429         unsigned nparam;
1430         unsigned dim;
1431
1432         if (!bmap)
1433                 return NULL;
1434
1435         nparam = isl_basic_map_dim(bmap, isl_dim_param);
1436         dim = isl_basic_map_dim(bmap, isl_dim_out);
1437
1438         tok = isl_stream_next_token(s);
1439         if (!tok || tok->type != ISL_TOKEN_VALUE) {
1440                 isl_stream_error(s, tok, "expecting coefficient");
1441                 if (tok)
1442                         isl_stream_push_token(s, tok);
1443                 goto error;
1444         }
1445         if (!tok->on_new_line) {
1446                 isl_stream_error(s, tok, "coefficient should appear on new line");
1447                 isl_stream_push_token(s, tok);
1448                 goto error;
1449         }
1450
1451         type = isl_int_get_si(tok->u.v);
1452         isl_token_free(tok);
1453
1454         isl_assert(s->ctx, type == 0 || type == 1, goto error);
1455         if (type == 0) {
1456                 k = isl_basic_map_alloc_equality(bmap);
1457                 c = bmap->eq[k];
1458         } else {
1459                 k = isl_basic_map_alloc_inequality(bmap);
1460                 c = bmap->ineq[k];
1461         }
1462         if (k < 0)
1463                 goto error;
1464
1465         for (j = 0; j < 1 + isl_basic_map_total_dim(bmap); ++j) {
1466                 int pos;
1467                 tok = isl_stream_next_token(s);
1468                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
1469                         isl_stream_error(s, tok, "expecting coefficient");
1470                         if (tok)
1471                                 isl_stream_push_token(s, tok);
1472                         goto error;
1473                 }
1474                 if (tok->on_new_line) {
1475                         isl_stream_error(s, tok,
1476                                 "coefficient should not appear on new line");
1477                         isl_stream_push_token(s, tok);
1478                         goto error;
1479                 }
1480                 pos = polylib_pos_to_isl_pos(bmap, j);
1481                 isl_int_set(c[pos], tok->u.v);
1482                 isl_token_free(tok);
1483         }
1484
1485         return bmap;
1486 error:
1487         isl_basic_map_free(bmap);
1488         return NULL;
1489 }
1490
1491 static __isl_give isl_basic_map *basic_map_read_polylib(struct isl_stream *s,
1492         int nparam)
1493 {
1494         int i;
1495         struct isl_token *tok;
1496         struct isl_token *tok2;
1497         int n_row, n_col;
1498         int on_new_line;
1499         unsigned in = 0, out, local = 0;
1500         struct isl_basic_map *bmap = NULL;
1501
1502         if (nparam < 0)
1503                 nparam = 0;
1504
1505         tok = isl_stream_next_token(s);
1506         if (!tok) {
1507                 isl_stream_error(s, NULL, "unexpected EOF");
1508                 return NULL;
1509         }
1510         tok2 = isl_stream_next_token(s);
1511         if (!tok2) {
1512                 isl_token_free(tok);
1513                 isl_stream_error(s, NULL, "unexpected EOF");
1514                 return NULL;
1515         }
1516         if (tok->type != ISL_TOKEN_VALUE || tok2->type != ISL_TOKEN_VALUE) {
1517                 isl_stream_push_token(s, tok2);
1518                 isl_stream_push_token(s, tok);
1519                 isl_stream_error(s, NULL,
1520                                  "expecting constraint matrix dimensions");
1521                 return NULL;
1522         }
1523         n_row = isl_int_get_si(tok->u.v);
1524         n_col = isl_int_get_si(tok2->u.v);
1525         on_new_line = tok2->on_new_line;
1526         isl_token_free(tok2);
1527         isl_token_free(tok);
1528         isl_assert(s->ctx, !on_new_line, return NULL);
1529         isl_assert(s->ctx, n_row >= 0, return NULL);
1530         isl_assert(s->ctx, n_col >= 2 + nparam, return NULL);
1531         tok = isl_stream_next_token_on_same_line(s);
1532         if (tok) {
1533                 if (tok->type != ISL_TOKEN_VALUE) {
1534                         isl_stream_error(s, tok,
1535                                     "expecting number of output dimensions");
1536                         isl_stream_push_token(s, tok);
1537                         goto error;
1538                 }
1539                 out = isl_int_get_si(tok->u.v);
1540                 isl_token_free(tok);
1541
1542                 tok = isl_stream_next_token_on_same_line(s);
1543                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
1544                         isl_stream_error(s, tok,
1545                                     "expecting number of input dimensions");
1546                         if (tok)
1547                                 isl_stream_push_token(s, tok);
1548                         goto error;
1549                 }
1550                 in = isl_int_get_si(tok->u.v);
1551                 isl_token_free(tok);
1552
1553                 tok = isl_stream_next_token_on_same_line(s);
1554                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
1555                         isl_stream_error(s, tok,
1556                                     "expecting number of existentials");
1557                         if (tok)
1558                                 isl_stream_push_token(s, tok);
1559                         goto error;
1560                 }
1561                 local = isl_int_get_si(tok->u.v);
1562                 isl_token_free(tok);
1563
1564                 tok = isl_stream_next_token_on_same_line(s);
1565                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
1566                         isl_stream_error(s, tok,
1567                                     "expecting number of parameters");
1568                         if (tok)
1569                                 isl_stream_push_token(s, tok);
1570                         goto error;
1571                 }
1572                 nparam = isl_int_get_si(tok->u.v);
1573                 isl_token_free(tok);
1574                 if (n_col != 1 + out + in + local + nparam + 1) {
1575                         isl_stream_error(s, NULL,
1576                                     "dimensions don't match");
1577                         goto error;
1578                 }
1579         } else
1580                 out = n_col - 2 - nparam;
1581         bmap = isl_basic_map_alloc(s->ctx, nparam, in, out, local, n_row, n_row);
1582         if (!bmap)
1583                 return NULL;
1584
1585         for (i = 0; i < local; ++i) {
1586                 int k = isl_basic_map_alloc_div(bmap);
1587                 if (k < 0)
1588                         goto error;
1589                 isl_seq_clr(bmap->div[k], 1 + 1 + nparam + in + out + local);
1590         }
1591
1592         for (i = 0; i < n_row; ++i)
1593                 bmap = basic_map_read_polylib_constraint(s, bmap);
1594
1595         tok = isl_stream_next_token_on_same_line(s);
1596         if (tok) {
1597                 isl_stream_error(s, tok, "unexpected extra token on line");
1598                 isl_stream_push_token(s, tok);
1599                 goto error;
1600         }
1601
1602         bmap = isl_basic_map_simplify(bmap);
1603         bmap = isl_basic_map_finalize(bmap);
1604         return bmap;
1605 error:
1606         isl_basic_map_free(bmap);
1607         return NULL;
1608 }
1609
1610 static struct isl_map *map_read_polylib(struct isl_stream *s, int nparam)
1611 {
1612         struct isl_token *tok;
1613         struct isl_token *tok2;
1614         int i, n;
1615         struct isl_map *map;
1616
1617         tok = isl_stream_next_token(s);
1618         if (!tok) {
1619                 isl_stream_error(s, NULL, "unexpected EOF");
1620                 return NULL;
1621         }
1622         tok2 = isl_stream_next_token_on_same_line(s);
1623         if (tok2 && tok2->type == ISL_TOKEN_VALUE) {
1624                 isl_stream_push_token(s, tok2);
1625                 isl_stream_push_token(s, tok);
1626                 return isl_map_from_basic_map(basic_map_read_polylib(s, nparam));
1627         }
1628         if (tok2) {
1629                 isl_stream_error(s, tok2, "unexpected token");
1630                 isl_stream_push_token(s, tok2);
1631                 isl_stream_push_token(s, tok);
1632                 return NULL;
1633         }
1634         n = isl_int_get_si(tok->u.v);
1635         isl_token_free(tok);
1636
1637         isl_assert(s->ctx, n >= 1, return NULL);
1638
1639         map = isl_map_from_basic_map(basic_map_read_polylib(s, nparam));
1640
1641         for (i = 1; map && i < n; ++i)
1642                 map = isl_map_union(map,
1643                         isl_map_from_basic_map(basic_map_read_polylib(s, nparam)));
1644
1645         return map;
1646 }
1647
1648 static int optional_power(struct isl_stream *s)
1649 {
1650         int pow;
1651         struct isl_token *tok;
1652
1653         tok = isl_stream_next_token(s);
1654         if (!tok)
1655                 return 1;
1656         if (tok->type != '^') {
1657                 isl_stream_push_token(s, tok);
1658                 return 1;
1659         }
1660         isl_token_free(tok);
1661         tok = isl_stream_next_token(s);
1662         if (!tok || tok->type != ISL_TOKEN_VALUE) {
1663                 isl_stream_error(s, tok, "expecting exponent");
1664                 if (tok)
1665                         isl_stream_push_token(s, tok);
1666                 return 1;
1667         }
1668         pow = isl_int_get_si(tok->u.v);
1669         isl_token_free(tok);
1670         return pow;
1671 }
1672
1673 static __isl_give isl_div *read_div(struct isl_stream *s,
1674         __isl_take isl_dim *dim, struct vars *v)
1675 {
1676         int n;
1677         isl_basic_map *bmap;
1678
1679         n = v->n;
1680         bmap = isl_basic_map_universe(dim);
1681
1682         if (vars_add_anon(v) < 0)
1683                 goto error;
1684         if (read_div_definition(s, v) < 0)
1685                 goto error;
1686         bmap = add_divs(bmap, v);
1687         bmap = isl_basic_map_order_divs(bmap);
1688         if (!bmap)
1689                 goto error;
1690         vars_drop(v, v->n - n);
1691
1692         return isl_basic_map_div(bmap, bmap->n_div - 1);
1693 error:
1694         isl_basic_map_free(bmap);
1695         return NULL;
1696 }
1697
1698 static __isl_give isl_qpolynomial *read_term(struct isl_stream *s,
1699         __isl_keep isl_basic_map *bmap, struct vars *v);
1700
1701 static __isl_give isl_qpolynomial *read_factor(struct isl_stream *s,
1702         __isl_keep isl_basic_map *bmap, struct vars *v)
1703 {
1704         struct isl_qpolynomial *qp;
1705         struct isl_token *tok;
1706
1707         tok = next_token(s);
1708         if (!tok) {
1709                 isl_stream_error(s, NULL, "unexpected EOF");
1710                 return NULL;
1711         }
1712         if (tok->type == '(') {
1713                 int pow;
1714
1715                 isl_token_free(tok);
1716                 qp = read_term(s, bmap, v);
1717                 if (!qp)
1718                         return NULL;
1719                 if (isl_stream_eat(s, ')'))
1720                         goto error;
1721                 pow = optional_power(s);
1722                 qp = isl_qpolynomial_pow(qp, pow);
1723         } else if (tok->type == ISL_TOKEN_VALUE) {
1724                 struct isl_token *tok2;
1725                 tok2 = isl_stream_next_token(s);
1726                 if (tok2 && tok2->type == '/') {
1727                         isl_token_free(tok2);
1728                         tok2 = next_token(s);
1729                         if (!tok2 || tok2->type != ISL_TOKEN_VALUE) {
1730                                 isl_stream_error(s, tok2, "expected denominator");
1731                                 isl_token_free(tok);
1732                                 isl_token_free(tok2);
1733                                 return NULL;
1734                         }
1735                         qp = isl_qpolynomial_rat_cst(isl_basic_map_get_dim(bmap),
1736                                                     tok->u.v, tok2->u.v);
1737                         isl_token_free(tok2);
1738                 } else {
1739                         isl_stream_push_token(s, tok2);
1740                         qp = isl_qpolynomial_cst(isl_basic_map_get_dim(bmap),
1741                                                 tok->u.v);
1742                 }
1743                 isl_token_free(tok);
1744         } else if (tok->type == ISL_TOKEN_INFTY) {
1745                 isl_token_free(tok);
1746                 qp = isl_qpolynomial_infty(isl_basic_map_get_dim(bmap));
1747         } else if (tok->type == ISL_TOKEN_NAN) {
1748                 isl_token_free(tok);
1749                 qp = isl_qpolynomial_nan(isl_basic_map_get_dim(bmap));
1750         } else if (tok->type == ISL_TOKEN_IDENT) {
1751                 int n = v->n;
1752                 int pos = vars_pos(v, tok->u.s, -1);
1753                 int pow;
1754                 if (pos < 0) {
1755                         isl_token_free(tok);
1756                         return NULL;
1757                 }
1758                 if (pos >= n) {
1759                         vars_drop(v, v->n - n);
1760                         isl_stream_error(s, tok, "unknown identifier");
1761                         isl_token_free(tok);
1762                         return NULL;
1763                 }
1764                 isl_token_free(tok);
1765                 pow = optional_power(s);
1766                 qp = isl_qpolynomial_var_pow(isl_basic_map_get_dim(bmap), pos, pow);
1767         } else if (tok->type == '[') {
1768                 isl_div *div;
1769                 int pow;
1770
1771                 isl_stream_push_token(s, tok);
1772                 div = read_div(s, isl_basic_map_get_dim(bmap), v);
1773                 pow = optional_power(s);
1774                 qp = isl_qpolynomial_div_pow(div, pow);
1775         } else if (tok->type == '-') {
1776                 struct isl_qpolynomial *qp2;
1777
1778                 isl_token_free(tok);
1779                 qp = isl_qpolynomial_cst(isl_basic_map_get_dim(bmap),
1780                                             s->ctx->negone);
1781                 qp2 = read_factor(s, bmap, v);
1782                 qp = isl_qpolynomial_mul(qp, qp2);
1783         } else {
1784                 isl_stream_error(s, tok, "unexpected isl_token");
1785                 isl_stream_push_token(s, tok);
1786                 return NULL;
1787         }
1788
1789         if (isl_stream_eat_if_available(s, '*') ||
1790             isl_stream_next_token_is(s, ISL_TOKEN_IDENT)) {
1791                 struct isl_qpolynomial *qp2;
1792
1793                 qp2 = read_factor(s, bmap, v);
1794                 qp = isl_qpolynomial_mul(qp, qp2);
1795         }
1796
1797         return qp;
1798 error:
1799         isl_qpolynomial_free(qp);
1800         return NULL;
1801 }
1802
1803 static __isl_give isl_qpolynomial *read_term(struct isl_stream *s,
1804         __isl_keep isl_basic_map *bmap, struct vars *v)
1805 {
1806         struct isl_token *tok;
1807         struct isl_qpolynomial *qp;
1808
1809         qp = read_factor(s, bmap, v);
1810
1811         for (;;) {
1812                 tok = next_token(s);
1813                 if (!tok)
1814                         return qp;
1815
1816                 if (tok->type == '+') {
1817                         struct isl_qpolynomial *qp2;
1818
1819                         isl_token_free(tok);
1820                         qp2 = read_factor(s, bmap, v);
1821                         qp = isl_qpolynomial_add(qp, qp2);
1822                 } else if (tok->type == '-') {
1823                         struct isl_qpolynomial *qp2;
1824
1825                         isl_token_free(tok);
1826                         qp2 = read_factor(s, bmap, v);
1827                         qp = isl_qpolynomial_sub(qp, qp2);
1828                 } else if (tok->type == ISL_TOKEN_VALUE &&
1829                             isl_int_is_neg(tok->u.v)) {
1830                         struct isl_qpolynomial *qp2;
1831
1832                         isl_stream_push_token(s, tok);
1833                         qp2 = read_factor(s, bmap, v);
1834                         qp = isl_qpolynomial_add(qp, qp2);
1835                 } else {
1836                         isl_stream_push_token(s, tok);
1837                         break;
1838                 }
1839         }
1840
1841         return qp;
1842 }
1843
1844 static __isl_give isl_map *read_optional_disjuncts(struct isl_stream *s,
1845         __isl_take isl_basic_map *bmap, struct vars *v)
1846 {
1847         struct isl_token *tok;
1848         struct isl_map *map;
1849
1850         tok = isl_stream_next_token(s);
1851         if (!tok) {
1852                 isl_stream_error(s, NULL, "unexpected EOF");
1853                 goto error;
1854         }
1855         map = isl_map_from_basic_map(isl_basic_map_copy(bmap));
1856         if (tok->type == ':' ||
1857             (tok->type == ISL_TOKEN_OR && !strcmp(tok->u.s, "|"))) {
1858                 isl_token_free(tok);
1859                 map = isl_map_intersect(map,
1860                             read_disjuncts(s, v, isl_basic_map_copy(bmap)));
1861         } else
1862                 isl_stream_push_token(s, tok);
1863
1864         isl_basic_map_free(bmap);
1865
1866         return map;
1867 error:
1868         isl_basic_map_free(bmap);
1869         return NULL;
1870 }
1871
1872 static struct isl_obj obj_read_poly(struct isl_stream *s,
1873         __isl_take isl_basic_map *bmap, struct vars *v, int n)
1874 {
1875         struct isl_obj obj = { isl_obj_pw_qpolynomial, NULL };
1876         struct isl_pw_qpolynomial *pwqp;
1877         struct isl_qpolynomial *qp;
1878         struct isl_map *map;
1879         struct isl_set *set;
1880
1881         qp = read_term(s, bmap, v);
1882         map = read_optional_disjuncts(s, bmap, v);
1883         set = isl_map_range(map);
1884
1885         pwqp = isl_pw_qpolynomial_alloc(set, qp);
1886
1887         vars_drop(v, v->n - n);
1888
1889         obj.v = pwqp;
1890         return obj;
1891 }
1892
1893 static struct isl_obj obj_read_poly_or_fold(struct isl_stream *s,
1894         __isl_take isl_basic_map *bmap, struct vars *v, int n)
1895 {
1896         struct isl_obj obj = { isl_obj_pw_qpolynomial_fold, NULL };
1897         isl_qpolynomial *qp;
1898         isl_qpolynomial_fold *fold = NULL;
1899         isl_pw_qpolynomial_fold *pwf;
1900         isl_map *map;
1901         isl_set *set;
1902
1903         if (!isl_stream_eat_if_available(s, ISL_TOKEN_MAX))
1904                 return obj_read_poly(s, bmap, v, n);
1905
1906         if (isl_stream_eat(s, '('))
1907                 goto error;
1908
1909         qp = read_term(s, bmap, v);
1910         fold = isl_qpolynomial_fold_alloc(isl_fold_max, qp);
1911
1912         while (isl_stream_eat_if_available(s, ',')) {
1913                 isl_qpolynomial_fold *fold_i;
1914                 qp = read_term(s, bmap, v);
1915                 fold_i = isl_qpolynomial_fold_alloc(isl_fold_max, qp);
1916                 fold = isl_qpolynomial_fold_fold(fold, fold_i);
1917         }
1918
1919         if (isl_stream_eat(s, ')'))
1920                 goto error;
1921
1922         map = read_optional_disjuncts(s, bmap, v);
1923         set = isl_map_range(map);
1924         pwf = isl_pw_qpolynomial_fold_alloc(isl_fold_max, set, fold);
1925
1926         vars_drop(v, v->n - n);
1927
1928         obj.v = pwf;
1929         return obj;
1930 error:
1931         isl_basic_map_free(bmap);
1932         isl_qpolynomial_fold_free(fold);
1933         obj.type = isl_obj_none;
1934         return obj;
1935 }
1936
1937 static int is_rational(struct isl_stream *s)
1938 {
1939         struct isl_token *tok;
1940
1941         tok = isl_stream_next_token(s);
1942         if (!tok)
1943                 return 0;
1944         if (tok->type == ISL_TOKEN_RAT && isl_stream_next_token_is(s, ':')) {
1945                 isl_token_free(tok);
1946                 isl_stream_eat(s, ':');
1947                 return 1;
1948         }
1949
1950         isl_stream_push_token(s, tok);
1951
1952         return 0;
1953 }
1954
1955 static struct isl_obj obj_read_body(struct isl_stream *s,
1956         __isl_take isl_basic_map *bmap, struct vars *v)
1957 {
1958         struct isl_map *map = NULL;
1959         struct isl_token *tok;
1960         struct isl_obj obj = { isl_obj_set, NULL };
1961         int n = v->n;
1962
1963         if (is_rational(s))
1964                 bmap = isl_basic_map_set_rational(bmap);
1965
1966         if (!next_is_tuple(s))
1967                 return obj_read_poly_or_fold(s, bmap, v, n);
1968
1969         bmap = read_tuple(s, bmap, isl_dim_in, v);
1970         if (!bmap)
1971                 goto error;
1972         tok = isl_stream_next_token(s);
1973         if (tok && tok->type == ISL_TOKEN_TO) {
1974                 obj.type = isl_obj_map;
1975                 isl_token_free(tok);
1976                 if (!next_is_tuple(s)) {
1977                         bmap = isl_basic_map_reverse(bmap);
1978                         return obj_read_poly_or_fold(s, bmap, v, n);
1979                 }
1980                 bmap = read_tuple(s, bmap, isl_dim_out, v);
1981                 if (!bmap)
1982                         goto error;
1983         } else {
1984                 bmap = isl_basic_map_reverse(bmap);
1985                 if (tok)
1986                         isl_stream_push_token(s, tok);
1987         }
1988
1989         map = read_optional_disjuncts(s, bmap, v);
1990
1991         vars_drop(v, v->n - n);
1992
1993         obj.v = map;
1994         return obj;
1995 error:
1996         isl_basic_map_free(bmap);
1997         obj.type = isl_obj_none;
1998         return obj;
1999 }
2000
2001 static struct isl_obj to_union(isl_ctx *ctx, struct isl_obj obj)
2002 {
2003         if (obj.type == isl_obj_map) {
2004                 obj.v = isl_union_map_from_map(obj.v);
2005                 obj.type = isl_obj_union_map;
2006         } else if (obj.type == isl_obj_set) {
2007                 obj.v = isl_union_set_from_set(obj.v);
2008                 obj.type = isl_obj_union_set;
2009         } else if (obj.type == isl_obj_pw_qpolynomial) {
2010                 obj.v = isl_union_pw_qpolynomial_from_pw_qpolynomial(obj.v);
2011                 obj.type = isl_obj_union_pw_qpolynomial;
2012         } else if (obj.type == isl_obj_pw_qpolynomial_fold) {
2013                 obj.v = isl_union_pw_qpolynomial_fold_from_pw_qpolynomial_fold(obj.v);
2014                 obj.type = isl_obj_union_pw_qpolynomial_fold;
2015         } else
2016                 isl_assert(ctx, 0, goto error);
2017         return obj;
2018 error:
2019         obj.type->free(obj.v);
2020         obj.type = isl_obj_none;
2021         return obj;
2022 }
2023
2024 static struct isl_obj obj_add(struct isl_ctx *ctx,
2025         struct isl_obj obj1, struct isl_obj obj2)
2026 {
2027         if (obj1.type == isl_obj_set && obj2.type == isl_obj_union_set)
2028                 obj1 = to_union(ctx, obj1);
2029         if (obj1.type == isl_obj_union_set && obj2.type == isl_obj_set)
2030                 obj2 = to_union(ctx, obj2);
2031         if (obj1.type == isl_obj_map && obj2.type == isl_obj_union_map)
2032                 obj1 = to_union(ctx, obj1);
2033         if (obj1.type == isl_obj_union_map && obj2.type == isl_obj_map)
2034                 obj2 = to_union(ctx, obj2);
2035         if (obj1.type == isl_obj_pw_qpolynomial &&
2036             obj2.type == isl_obj_union_pw_qpolynomial)
2037                 obj1 = to_union(ctx, obj1);
2038         if (obj1.type == isl_obj_union_pw_qpolynomial &&
2039             obj2.type == isl_obj_pw_qpolynomial)
2040                 obj2 = to_union(ctx, obj2);
2041         if (obj1.type == isl_obj_pw_qpolynomial_fold &&
2042             obj2.type == isl_obj_union_pw_qpolynomial_fold)
2043                 obj1 = to_union(ctx, obj1);
2044         if (obj1.type == isl_obj_union_pw_qpolynomial_fold &&
2045             obj2.type == isl_obj_pw_qpolynomial_fold)
2046                 obj2 = to_union(ctx, obj2);
2047         isl_assert(ctx, obj1.type == obj2.type, goto error);
2048         if (obj1.type == isl_obj_map && !isl_map_has_equal_dim(obj1.v, obj2.v)) {
2049                 obj1 = to_union(ctx, obj1);
2050                 obj2 = to_union(ctx, obj2);
2051         }
2052         if (obj1.type == isl_obj_set && !isl_set_has_equal_dim(obj1.v, obj2.v)) {
2053                 obj1 = to_union(ctx, obj1);
2054                 obj2 = to_union(ctx, obj2);
2055         }
2056         if (obj1.type == isl_obj_pw_qpolynomial &&
2057             !isl_pw_qpolynomial_has_equal_dim(obj1.v, obj2.v)) {
2058                 obj1 = to_union(ctx, obj1);
2059                 obj2 = to_union(ctx, obj2);
2060         }
2061         if (obj1.type == isl_obj_pw_qpolynomial_fold &&
2062             !isl_pw_qpolynomial_fold_has_equal_dim(obj1.v, obj2.v)) {
2063                 obj1 = to_union(ctx, obj1);
2064                 obj2 = to_union(ctx, obj2);
2065         }
2066         obj1.v = obj1.type->add(obj1.v, obj2.v);
2067         return obj1;
2068 error:
2069         obj1.type->free(obj1.v);
2070         obj2.type->free(obj2.v);
2071         obj1.type = isl_obj_none;
2072         obj1.v = NULL;
2073         return obj1;
2074 }
2075
2076 static struct isl_obj obj_read(struct isl_stream *s, int nparam)
2077 {
2078         isl_basic_map *bmap = NULL;
2079         struct isl_token *tok;
2080         struct vars *v = NULL;
2081         struct isl_obj obj = { isl_obj_set, NULL };
2082
2083         tok = next_token(s);
2084         if (!tok) {
2085                 isl_stream_error(s, NULL, "unexpected EOF");
2086                 goto error;
2087         }
2088         if (tok->type == ISL_TOKEN_VALUE) {
2089                 struct isl_token *tok2;
2090                 struct isl_map *map;
2091
2092                 tok2 = isl_stream_next_token(s);
2093                 if (!tok2 || tok2->type != ISL_TOKEN_VALUE ||
2094                     isl_int_is_neg(tok2->u.v)) {
2095                         if (tok2)
2096                                 isl_stream_push_token(s, tok2);
2097                         obj.type = isl_obj_int;
2098                         obj.v = isl_int_obj_alloc(s->ctx, tok->u.v);
2099                         isl_token_free(tok);
2100                         return obj;
2101                 }
2102                 isl_stream_push_token(s, tok2);
2103                 isl_stream_push_token(s, tok);
2104                 map = map_read_polylib(s, nparam);
2105                 if (!map)
2106                         goto error;
2107                 if (isl_map_dim(map, isl_dim_in) > 0)
2108                         obj.type = isl_obj_map;
2109                 obj.v = map;
2110                 return obj;
2111         }
2112         v = vars_new(s->ctx);
2113         if (!v) {
2114                 isl_stream_push_token(s, tok);
2115                 goto error;
2116         }
2117         bmap = isl_basic_map_alloc(s->ctx, 0, 0, 0, 0, 0, 0);
2118         if (tok->type == '[') {
2119                 isl_stream_push_token(s, tok);
2120                 bmap = read_tuple(s, bmap, isl_dim_param, v);
2121                 if (!bmap)
2122                         goto error;
2123                 if (nparam >= 0)
2124                         isl_assert(s->ctx, nparam == v->n, goto error);
2125                 tok = isl_stream_next_token(s);
2126                 if (!tok || tok->type != ISL_TOKEN_TO) {
2127                         isl_stream_error(s, tok, "expecting '->'");
2128                         if (tok)
2129                                 isl_stream_push_token(s, tok);
2130                         goto error;
2131                 }
2132                 isl_token_free(tok);
2133                 tok = isl_stream_next_token(s);
2134         } else if (nparam > 0)
2135                 bmap = isl_basic_map_add(bmap, isl_dim_param, nparam);
2136         if (!tok || tok->type != '{') {
2137                 isl_stream_error(s, tok, "expecting '{'");
2138                 if (tok)
2139                         isl_stream_push_token(s, tok);
2140                 goto error;
2141         }
2142         isl_token_free(tok);
2143
2144         tok = isl_stream_next_token(s);
2145         if (!tok)
2146                 ;
2147         else if (tok->type == ISL_TOKEN_IDENT && !strcmp(tok->u.s, "Sym")) {
2148                 isl_token_free(tok);
2149                 if (isl_stream_eat(s, '='))
2150                         goto error;
2151                 bmap = read_tuple(s, bmap, isl_dim_param, v);
2152                 if (!bmap)
2153                         goto error;
2154                 if (nparam >= 0)
2155                         isl_assert(s->ctx, nparam == v->n, goto error);
2156         } else if (tok->type == '}') {
2157                 obj.type = isl_obj_union_set;
2158                 obj.v = isl_union_set_empty(isl_basic_map_get_dim(bmap));
2159                 isl_token_free(tok);
2160                 goto done;
2161         } else
2162                 isl_stream_push_token(s, tok);
2163
2164         for (;;) {
2165                 struct isl_obj o;
2166                 tok = NULL;
2167                 o = obj_read_body(s, isl_basic_map_copy(bmap), v);
2168                 if (o.type == isl_obj_none || !o.v)
2169                         goto error;
2170                 if (!obj.v)
2171                         obj = o;
2172                 else {
2173                         obj = obj_add(s->ctx, obj, o);
2174                         if (obj.type == isl_obj_none || !obj.v)
2175                                 goto error;
2176                 }
2177                 tok = isl_stream_next_token(s);
2178                 if (!tok || tok->type != ';')
2179                         break;
2180                 isl_token_free(tok);
2181                 if (isl_stream_next_token_is(s, '}')) {
2182                         tok = isl_stream_next_token(s);
2183                         break;
2184                 }
2185         }
2186
2187         if (tok && tok->type == '}') {
2188                 isl_token_free(tok);
2189         } else {
2190                 isl_stream_error(s, tok, "unexpected isl_token");
2191                 if (tok)
2192                         isl_token_free(tok);
2193                 goto error;
2194         }
2195 done:
2196         vars_free(v);
2197         isl_basic_map_free(bmap);
2198
2199         return obj;
2200 error:
2201         isl_basic_map_free(bmap);
2202         obj.type->free(obj.v);
2203         if (v)
2204                 vars_free(v);
2205         obj.v = NULL;
2206         return obj;
2207 }
2208
2209 struct isl_obj isl_stream_read_obj(struct isl_stream *s)
2210 {
2211         return obj_read(s, -1);
2212 }
2213
2214 __isl_give isl_map *isl_stream_read_map(struct isl_stream *s, int nparam)
2215 {
2216         struct isl_obj obj;
2217
2218         obj = obj_read(s, nparam);
2219         if (obj.v)
2220                 isl_assert(s->ctx, obj.type == isl_obj_map ||
2221                                    obj.type == isl_obj_set, goto error);
2222
2223         return obj.v;
2224 error:
2225         obj.type->free(obj.v);
2226         return NULL;
2227 }
2228
2229 __isl_give isl_set *isl_stream_read_set(struct isl_stream *s, int nparam)
2230 {
2231         struct isl_obj obj;
2232
2233         obj = obj_read(s, nparam);
2234         if (obj.v)
2235                 isl_assert(s->ctx, obj.type == isl_obj_set, goto error);
2236
2237         return obj.v;
2238 error:
2239         obj.type->free(obj.v);
2240         return NULL;
2241 }
2242
2243 __isl_give isl_union_map *isl_stream_read_union_map(struct isl_stream *s)
2244 {
2245         struct isl_obj obj;
2246
2247         obj = obj_read(s, -1);
2248         if (obj.type == isl_obj_map) {
2249                 obj.type = isl_obj_union_map;
2250                 obj.v = isl_union_map_from_map(obj.v);
2251         }
2252         if (obj.type == isl_obj_set) {
2253                 obj.type = isl_obj_union_set;
2254                 obj.v = isl_union_set_from_set(obj.v);
2255         }
2256         if (obj.v)
2257                 isl_assert(s->ctx, obj.type == isl_obj_union_map ||
2258                                    obj.type == isl_obj_union_set, goto error);
2259
2260         return obj.v;
2261 error:
2262         obj.type->free(obj.v);
2263         return NULL;
2264 }
2265
2266 __isl_give isl_union_set *isl_stream_read_union_set(struct isl_stream *s)
2267 {
2268         struct isl_obj obj;
2269
2270         obj = obj_read(s, -1);
2271         if (obj.type == isl_obj_set) {
2272                 obj.type = isl_obj_union_set;
2273                 obj.v = isl_union_set_from_set(obj.v);
2274         }
2275         if (obj.v)
2276                 isl_assert(s->ctx, obj.type == isl_obj_union_set, goto error);
2277
2278         return obj.v;
2279 error:
2280         obj.type->free(obj.v);
2281         return NULL;
2282 }
2283
2284 static struct isl_basic_map *basic_map_read(struct isl_stream *s, int nparam)
2285 {
2286         struct isl_obj obj;
2287         struct isl_map *map;
2288         struct isl_basic_map *bmap;
2289
2290         obj = obj_read(s, nparam);
2291         map = obj.v;
2292         if (!map)
2293                 return NULL;
2294
2295         isl_assert(map->ctx, map->n <= 1, goto error);
2296
2297         if (map->n == 0)
2298                 bmap = isl_basic_map_empty_like_map(map);
2299         else
2300                 bmap = isl_basic_map_copy(map->p[0]);
2301
2302         isl_map_free(map);
2303
2304         return bmap;
2305 error:
2306         isl_map_free(map);
2307         return NULL;
2308 }
2309
2310 __isl_give isl_basic_map *isl_basic_map_read_from_file(isl_ctx *ctx,
2311                 FILE *input, int nparam)
2312 {
2313         struct isl_basic_map *bmap;
2314         struct isl_stream *s = isl_stream_new_file(ctx, input);
2315         if (!s)
2316                 return NULL;
2317         bmap = basic_map_read(s, nparam);
2318         isl_stream_free(s);
2319         return bmap;
2320 }
2321
2322 __isl_give isl_basic_set *isl_basic_set_read_from_file(isl_ctx *ctx,
2323                 FILE *input, int nparam)
2324 {
2325         struct isl_basic_map *bmap;
2326         bmap = isl_basic_map_read_from_file(ctx, input, nparam);
2327         if (!bmap)
2328                 return NULL;
2329         isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
2330         return (struct isl_basic_set *)bmap;
2331 error:
2332         isl_basic_map_free(bmap);
2333         return NULL;
2334 }
2335
2336 struct isl_basic_map *isl_basic_map_read_from_str(struct isl_ctx *ctx,
2337                 const char *str, int nparam)
2338 {
2339         struct isl_basic_map *bmap;
2340         struct isl_stream *s = isl_stream_new_str(ctx, str);
2341         if (!s)
2342                 return NULL;
2343         bmap = basic_map_read(s, nparam);
2344         isl_stream_free(s);
2345         return bmap;
2346 }
2347
2348 struct isl_basic_set *isl_basic_set_read_from_str(struct isl_ctx *ctx,
2349                 const char *str, int nparam)
2350 {
2351         struct isl_basic_map *bmap;
2352         bmap = isl_basic_map_read_from_str(ctx, str, nparam);
2353         if (!bmap)
2354                 return NULL;
2355         isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
2356         return (struct isl_basic_set *)bmap;
2357 error:
2358         isl_basic_map_free(bmap);
2359         return NULL;
2360 }
2361
2362 __isl_give isl_map *isl_map_read_from_file(struct isl_ctx *ctx,
2363                 FILE *input, int nparam)
2364 {
2365         struct isl_map *map;
2366         struct isl_stream *s = isl_stream_new_file(ctx, input);
2367         if (!s)
2368                 return NULL;
2369         map = isl_stream_read_map(s, nparam);
2370         isl_stream_free(s);
2371         return map;
2372 }
2373
2374 __isl_give isl_map *isl_map_read_from_str(struct isl_ctx *ctx,
2375                 const char *str, int nparam)
2376 {
2377         struct isl_map *map;
2378         struct isl_stream *s = isl_stream_new_str(ctx, str);
2379         if (!s)
2380                 return NULL;
2381         map = isl_stream_read_map(s, nparam);
2382         isl_stream_free(s);
2383         return map;
2384 }
2385
2386 __isl_give isl_set *isl_set_read_from_file(struct isl_ctx *ctx,
2387                 FILE *input, int nparam)
2388 {
2389         struct isl_map *map;
2390         map = isl_map_read_from_file(ctx, input, nparam);
2391         if (!map)
2392                 return NULL;
2393         isl_assert(ctx, isl_map_n_in(map) == 0, goto error);
2394         return (struct isl_set *)map;
2395 error:
2396         isl_map_free(map);
2397         return NULL;
2398 }
2399
2400 struct isl_set *isl_set_read_from_str(struct isl_ctx *ctx,
2401                 const char *str, int nparam)
2402 {
2403         struct isl_map *map;
2404         map = isl_map_read_from_str(ctx, str, nparam);
2405         if (!map)
2406                 return NULL;
2407         isl_assert(ctx, isl_map_n_in(map) == 0, goto error);
2408         return (struct isl_set *)map;
2409 error:
2410         isl_map_free(map);
2411         return NULL;
2412 }
2413
2414 __isl_give isl_union_map *isl_union_map_read_from_file(isl_ctx *ctx,
2415         FILE *input)
2416 {
2417         isl_union_map *umap;
2418         struct isl_stream *s = isl_stream_new_file(ctx, input);
2419         if (!s)
2420                 return NULL;
2421         umap = isl_stream_read_union_map(s);
2422         isl_stream_free(s);
2423         return umap;
2424 }
2425
2426 __isl_give isl_union_map *isl_union_map_read_from_str(struct isl_ctx *ctx,
2427                 const char *str)
2428 {
2429         isl_union_map *umap;
2430         struct isl_stream *s = isl_stream_new_str(ctx, str);
2431         if (!s)
2432                 return NULL;
2433         umap = isl_stream_read_union_map(s);
2434         isl_stream_free(s);
2435         return umap;
2436 }
2437
2438 __isl_give isl_union_set *isl_union_set_read_from_file(isl_ctx *ctx,
2439         FILE *input)
2440 {
2441         isl_union_set *uset;
2442         struct isl_stream *s = isl_stream_new_file(ctx, input);
2443         if (!s)
2444                 return NULL;
2445         uset = isl_stream_read_union_set(s);
2446         isl_stream_free(s);
2447         return uset;
2448 }
2449
2450 __isl_give isl_union_set *isl_union_set_read_from_str(struct isl_ctx *ctx,
2451                 const char *str)
2452 {
2453         isl_union_set *uset;
2454         struct isl_stream *s = isl_stream_new_str(ctx, str);
2455         if (!s)
2456                 return NULL;
2457         uset = isl_stream_read_union_set(s);
2458         isl_stream_free(s);
2459         return uset;
2460 }
2461
2462 static __isl_give isl_vec *isl_vec_read_polylib(struct isl_stream *s)
2463 {
2464         struct isl_vec *vec = NULL;
2465         struct isl_token *tok;
2466         unsigned size;
2467         int j;
2468
2469         tok = isl_stream_next_token(s);
2470         if (!tok || tok->type != ISL_TOKEN_VALUE) {
2471                 isl_stream_error(s, tok, "expecting vector length");
2472                 goto error;
2473         }
2474
2475         size = isl_int_get_si(tok->u.v);
2476         isl_token_free(tok);
2477
2478         vec = isl_vec_alloc(s->ctx, size);
2479
2480         for (j = 0; j < size; ++j) {
2481                 tok = isl_stream_next_token(s);
2482                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
2483                         isl_stream_error(s, tok, "expecting constant value");
2484                         goto error;
2485                 }
2486                 isl_int_set(vec->el[j], tok->u.v);
2487                 isl_token_free(tok);
2488         }
2489
2490         return vec;
2491 error:
2492         isl_token_free(tok);
2493         isl_vec_free(vec);
2494         return NULL;
2495 }
2496
2497 static __isl_give isl_vec *vec_read(struct isl_stream *s)
2498 {
2499         return isl_vec_read_polylib(s);
2500 }
2501
2502 __isl_give isl_vec *isl_vec_read_from_file(isl_ctx *ctx, FILE *input)
2503 {
2504         isl_vec *v;
2505         struct isl_stream *s = isl_stream_new_file(ctx, input);
2506         if (!s)
2507                 return NULL;
2508         v = vec_read(s);
2509         isl_stream_free(s);
2510         return v;
2511 }
2512
2513 __isl_give isl_pw_qpolynomial *isl_stream_read_pw_qpolynomial(
2514         struct isl_stream *s)
2515 {
2516         struct isl_obj obj;
2517
2518         obj = obj_read(s, -1);
2519         if (obj.v)
2520                 isl_assert(s->ctx, obj.type == isl_obj_pw_qpolynomial,
2521                            goto error);
2522
2523         return obj.v;
2524 error:
2525         obj.type->free(obj.v);
2526         return NULL;
2527 }
2528
2529 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_read_from_str(isl_ctx *ctx,
2530                 const char *str)
2531 {
2532         isl_pw_qpolynomial *pwqp;
2533         struct isl_stream *s = isl_stream_new_str(ctx, str);
2534         if (!s)
2535                 return NULL;
2536         pwqp = isl_stream_read_pw_qpolynomial(s);
2537         isl_stream_free(s);
2538         return pwqp;
2539 }