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