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