c914aa9f70223443018f606555cdf9b8d0b66d29
[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 }
973
974 static struct isl_map *read_disjuncts(struct isl_stream *s,
975         struct vars *v, __isl_take isl_basic_map *bmap);
976
977 static __isl_give isl_map *read_exists(struct isl_stream *s,
978         struct vars *v, __isl_take isl_basic_map *bmap)
979 {
980         int n = v->n;
981         int seen_paren = isl_stream_eat_if_available(s, '(');
982         isl_map *map = NULL;
983
984         bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
985         bmap = read_defined_var_list(s, v, bmap);
986
987         if (isl_stream_eat(s, ':'))
988                 goto error;
989
990         map = read_disjuncts(s, v, bmap);
991         map = isl_set_unwrap(isl_map_domain(map));
992         bmap = NULL;
993
994         vars_drop(v, v->n - n);
995         if (seen_paren && isl_stream_eat(s, ')'))
996                 goto error;
997
998         return map;
999 error:
1000         isl_basic_map_free(bmap);
1001         isl_map_free(map);
1002         return NULL;
1003 }
1004
1005 static __isl_give isl_map *read_conjunct(struct isl_stream *s,
1006         struct vars *v, __isl_take isl_basic_map *bmap)
1007 {
1008         isl_map *map;
1009
1010         if (isl_stream_eat_if_available(s, '(')) {
1011                 map = read_disjuncts(s, v, bmap);
1012                 if (isl_stream_eat(s, ')'))
1013                         goto error;
1014                 return map;
1015         }
1016
1017         if (isl_stream_eat_if_available(s, ISL_TOKEN_EXISTS))
1018                 return read_exists(s, v, bmap);
1019
1020         if (isl_stream_eat_if_available(s, ISL_TOKEN_TRUE))
1021                 return isl_map_from_basic_map(bmap);
1022
1023         if (isl_stream_eat_if_available(s, ISL_TOKEN_FALSE)) {
1024                 isl_dim *dim = isl_basic_map_get_dim(bmap);
1025                 isl_basic_map_free(bmap);
1026                 return isl_map_empty(dim);
1027         }
1028                 
1029         return read_constraint(s, v, bmap);
1030 error:
1031         isl_map_free(map);
1032         return NULL;
1033 }
1034
1035 static __isl_give isl_map *read_conjuncts(struct isl_stream *s,
1036         struct vars *v, __isl_take isl_basic_map *bmap)
1037 {
1038         isl_map *map;
1039         int negate;
1040
1041         negate = isl_stream_eat_if_available(s, ISL_TOKEN_NOT);
1042         map = read_conjunct(s, v, isl_basic_map_copy(bmap));
1043         if (negate) {
1044                 isl_map *t;
1045                 t = isl_map_from_basic_map(isl_basic_map_copy(bmap));
1046                 map = isl_map_subtract(t, map);
1047         }
1048
1049         while (isl_stream_eat_if_available(s, ISL_TOKEN_AND)) {
1050                 isl_map *map_i;
1051
1052                 negate = isl_stream_eat_if_available(s, ISL_TOKEN_NOT);
1053                 map_i = read_conjunct(s, v, isl_basic_map_copy(bmap));
1054                 if (negate)
1055                         map = isl_map_subtract(map, map_i);
1056                 else
1057                         map = isl_map_intersect(map, map_i);
1058         }
1059
1060         isl_basic_map_free(bmap);
1061         return map;
1062 }
1063
1064 static struct isl_map *read_disjuncts(struct isl_stream *s,
1065         struct vars *v, __isl_take isl_basic_map *bmap)
1066 {
1067         struct isl_map *map;
1068
1069         if (isl_stream_next_token_is(s, '}')) {
1070                 isl_dim *dim = isl_basic_map_get_dim(bmap);
1071                 isl_basic_map_free(bmap);
1072                 return isl_map_universe(dim);
1073         }
1074
1075         map = read_conjuncts(s, v, isl_basic_map_copy(bmap));
1076         while (isl_stream_eat_if_available(s, ISL_TOKEN_OR)) {
1077                 isl_map *map_i;
1078
1079                 map_i = read_conjuncts(s, v, isl_basic_map_copy(bmap));
1080                 map = isl_map_union(map, map_i);
1081         }
1082
1083         isl_basic_map_free(bmap);
1084         return map;
1085 }
1086
1087 static int polylib_pos_to_isl_pos(__isl_keep isl_basic_map *bmap, int pos)
1088 {
1089         if (pos < isl_basic_map_dim(bmap, isl_dim_out))
1090                 return 1 + isl_basic_map_dim(bmap, isl_dim_param) +
1091                            isl_basic_map_dim(bmap, isl_dim_in) + pos;
1092         pos -= isl_basic_map_dim(bmap, isl_dim_out);
1093
1094         if (pos < isl_basic_map_dim(bmap, isl_dim_in))
1095                 return 1 + isl_basic_map_dim(bmap, isl_dim_param) + pos;
1096         pos -= isl_basic_map_dim(bmap, isl_dim_in);
1097
1098         if (pos < isl_basic_map_dim(bmap, isl_dim_div))
1099                 return 1 + isl_basic_map_dim(bmap, isl_dim_param) +
1100                            isl_basic_map_dim(bmap, isl_dim_in) +
1101                            isl_basic_map_dim(bmap, isl_dim_out) + pos;
1102         pos -= isl_basic_map_dim(bmap, isl_dim_div);
1103
1104         if (pos < isl_basic_map_dim(bmap, isl_dim_param))
1105                 return 1 + pos;
1106
1107         return 0;
1108 }
1109
1110 static __isl_give isl_basic_map *basic_map_read_polylib_constraint(
1111         struct isl_stream *s, __isl_take isl_basic_map *bmap)
1112 {
1113         int j;
1114         struct isl_token *tok;
1115         int type;
1116         int k;
1117         isl_int *c;
1118         unsigned nparam;
1119         unsigned dim;
1120
1121         if (!bmap)
1122                 return NULL;
1123
1124         nparam = isl_basic_map_dim(bmap, isl_dim_param);
1125         dim = isl_basic_map_dim(bmap, isl_dim_out);
1126
1127         tok = isl_stream_next_token(s);
1128         if (!tok || tok->type != ISL_TOKEN_VALUE) {
1129                 isl_stream_error(s, tok, "expecting coefficient");
1130                 if (tok)
1131                         isl_stream_push_token(s, tok);
1132                 goto error;
1133         }
1134         if (!tok->on_new_line) {
1135                 isl_stream_error(s, tok, "coefficient should appear on new line");
1136                 isl_stream_push_token(s, tok);
1137                 goto error;
1138         }
1139
1140         type = isl_int_get_si(tok->u.v);
1141         isl_token_free(tok);
1142
1143         isl_assert(s->ctx, type == 0 || type == 1, goto error);
1144         if (type == 0) {
1145                 k = isl_basic_map_alloc_equality(bmap);
1146                 c = bmap->eq[k];
1147         } else {
1148                 k = isl_basic_map_alloc_inequality(bmap);
1149                 c = bmap->ineq[k];
1150         }
1151         if (k < 0)
1152                 goto error;
1153
1154         for (j = 0; j < 1 + isl_basic_map_total_dim(bmap); ++j) {
1155                 int pos;
1156                 tok = isl_stream_next_token(s);
1157                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
1158                         isl_stream_error(s, tok, "expecting coefficient");
1159                         if (tok)
1160                                 isl_stream_push_token(s, tok);
1161                         goto error;
1162                 }
1163                 if (tok->on_new_line) {
1164                         isl_stream_error(s, tok,
1165                                 "coefficient should not appear on new line");
1166                         isl_stream_push_token(s, tok);
1167                         goto error;
1168                 }
1169                 pos = polylib_pos_to_isl_pos(bmap, j);
1170                 isl_int_set(c[pos], tok->u.v);
1171                 isl_token_free(tok);
1172         }
1173
1174         return bmap;
1175 error:
1176         isl_basic_map_free(bmap);
1177         return NULL;
1178 }
1179
1180 static __isl_give isl_basic_map *basic_map_read_polylib(struct isl_stream *s,
1181         int nparam)
1182 {
1183         int i;
1184         struct isl_token *tok;
1185         struct isl_token *tok2;
1186         int n_row, n_col;
1187         int on_new_line;
1188         unsigned in = 0, out, local = 0;
1189         struct isl_basic_map *bmap = NULL;
1190
1191         if (nparam < 0)
1192                 nparam = 0;
1193
1194         tok = isl_stream_next_token(s);
1195         if (!tok) {
1196                 isl_stream_error(s, NULL, "unexpected EOF");
1197                 return NULL;
1198         }
1199         tok2 = isl_stream_next_token(s);
1200         if (!tok2) {
1201                 isl_token_free(tok);
1202                 isl_stream_error(s, NULL, "unexpected EOF");
1203                 return NULL;
1204         }
1205         if (tok->type != ISL_TOKEN_VALUE || tok2->type != ISL_TOKEN_VALUE) {
1206                 isl_stream_push_token(s, tok2);
1207                 isl_stream_push_token(s, tok);
1208                 isl_stream_error(s, NULL,
1209                                  "expecting constraint matrix dimensions");
1210                 return NULL;
1211         }
1212         n_row = isl_int_get_si(tok->u.v);
1213         n_col = isl_int_get_si(tok2->u.v);
1214         on_new_line = tok2->on_new_line;
1215         isl_token_free(tok2);
1216         isl_token_free(tok);
1217         isl_assert(s->ctx, !on_new_line, return NULL);
1218         isl_assert(s->ctx, n_row >= 0, return NULL);
1219         isl_assert(s->ctx, n_col >= 2 + nparam, return NULL);
1220         tok = isl_stream_next_token_on_same_line(s);
1221         if (tok) {
1222                 if (tok->type != ISL_TOKEN_VALUE) {
1223                         isl_stream_error(s, tok,
1224                                     "expecting number of output dimensions");
1225                         isl_stream_push_token(s, tok);
1226                         goto error;
1227                 }
1228                 out = isl_int_get_si(tok->u.v);
1229                 isl_token_free(tok);
1230
1231                 tok = isl_stream_next_token_on_same_line(s);
1232                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
1233                         isl_stream_error(s, tok,
1234                                     "expecting number of input dimensions");
1235                         if (tok)
1236                                 isl_stream_push_token(s, tok);
1237                         goto error;
1238                 }
1239                 in = isl_int_get_si(tok->u.v);
1240                 isl_token_free(tok);
1241
1242                 tok = isl_stream_next_token_on_same_line(s);
1243                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
1244                         isl_stream_error(s, tok,
1245                                     "expecting number of existentials");
1246                         if (tok)
1247                                 isl_stream_push_token(s, tok);
1248                         goto error;
1249                 }
1250                 local = isl_int_get_si(tok->u.v);
1251                 isl_token_free(tok);
1252
1253                 tok = isl_stream_next_token_on_same_line(s);
1254                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
1255                         isl_stream_error(s, tok,
1256                                     "expecting number of parameters");
1257                         if (tok)
1258                                 isl_stream_push_token(s, tok);
1259                         goto error;
1260                 }
1261                 nparam = isl_int_get_si(tok->u.v);
1262                 isl_token_free(tok);
1263                 if (n_col != 1 + out + in + local + nparam + 1) {
1264                         isl_stream_error(s, NULL,
1265                                     "dimensions don't match");
1266                         goto error;
1267                 }
1268         } else
1269                 out = n_col - 2 - nparam;
1270         bmap = isl_basic_map_alloc(s->ctx, nparam, in, out, local, n_row, n_row);
1271         if (!bmap)
1272                 return NULL;
1273
1274         for (i = 0; i < local; ++i) {
1275                 int k = isl_basic_map_alloc_div(bmap);
1276                 if (k < 0)
1277                         goto error;
1278                 isl_seq_clr(bmap->div[k], 1 + 1 + nparam + in + out + local);
1279         }
1280
1281         for (i = 0; i < n_row; ++i)
1282                 bmap = basic_map_read_polylib_constraint(s, bmap);
1283
1284         tok = isl_stream_next_token_on_same_line(s);
1285         if (tok) {
1286                 isl_stream_error(s, tok, "unexpected extra token on line");
1287                 isl_stream_push_token(s, tok);
1288                 goto error;
1289         }
1290
1291         bmap = isl_basic_map_simplify(bmap);
1292         bmap = isl_basic_map_finalize(bmap);
1293         return bmap;
1294 error:
1295         isl_basic_map_free(bmap);
1296         return NULL;
1297 }
1298
1299 static struct isl_map *map_read_polylib(struct isl_stream *s, int nparam)
1300 {
1301         struct isl_token *tok;
1302         struct isl_token *tok2;
1303         int i, n;
1304         struct isl_map *map;
1305
1306         tok = isl_stream_next_token(s);
1307         if (!tok) {
1308                 isl_stream_error(s, NULL, "unexpected EOF");
1309                 return NULL;
1310         }
1311         tok2 = isl_stream_next_token_on_same_line(s);
1312         if (tok2 && tok2->type == ISL_TOKEN_VALUE) {
1313                 isl_stream_push_token(s, tok2);
1314                 isl_stream_push_token(s, tok);
1315                 return isl_map_from_basic_map(basic_map_read_polylib(s, nparam));
1316         }
1317         if (tok2) {
1318                 isl_stream_error(s, tok2, "unexpected token");
1319                 isl_stream_push_token(s, tok2);
1320                 isl_stream_push_token(s, tok);
1321                 return NULL;
1322         }
1323         n = isl_int_get_si(tok->u.v);
1324         isl_token_free(tok);
1325
1326         isl_assert(s->ctx, n >= 1, return NULL);
1327
1328         map = isl_map_from_basic_map(basic_map_read_polylib(s, nparam));
1329
1330         for (i = 1; map && i < n; ++i)
1331                 map = isl_map_union(map,
1332                         isl_map_from_basic_map(basic_map_read_polylib(s, nparam)));
1333
1334         return map;
1335 }
1336
1337 static int optional_power(struct isl_stream *s)
1338 {
1339         int pow;
1340         struct isl_token *tok;
1341
1342         tok = isl_stream_next_token(s);
1343         if (!tok)
1344                 return 1;
1345         if (tok->type != '^') {
1346                 isl_stream_push_token(s, tok);
1347                 return 1;
1348         }
1349         isl_token_free(tok);
1350         tok = isl_stream_next_token(s);
1351         if (!tok || tok->type != ISL_TOKEN_VALUE) {
1352                 isl_stream_error(s, tok, "expecting exponent");
1353                 if (tok)
1354                         isl_stream_push_token(s, tok);
1355                 return 1;
1356         }
1357         pow = isl_int_get_si(tok->u.v);
1358         isl_token_free(tok);
1359         return pow;
1360 }
1361
1362 static __isl_give isl_div *read_div(struct isl_stream *s,
1363         __isl_take isl_dim *dim, struct vars *v)
1364 {
1365         int n;
1366         isl_basic_map *bmap;
1367
1368         n = v->n;
1369         bmap = isl_basic_map_universe(dim);
1370
1371         if (vars_add_anon(v) < 0)
1372                 goto error;
1373         if (read_div_definition(s, v) < 0)
1374                 goto error;
1375         bmap = add_divs(bmap, v);
1376         bmap = isl_basic_map_order_divs(bmap);
1377         if (!bmap)
1378                 goto error;
1379         vars_drop(v, v->n - n);
1380
1381         return isl_basic_map_div(bmap, bmap->n_div - 1);
1382 error:
1383         isl_basic_map_free(bmap);
1384         return NULL;
1385 }
1386
1387 static __isl_give isl_qpolynomial *read_term(struct isl_stream *s,
1388         __isl_keep isl_basic_map *bmap, struct vars *v);
1389
1390 static __isl_give isl_qpolynomial *read_factor(struct isl_stream *s,
1391         __isl_keep isl_basic_map *bmap, struct vars *v)
1392 {
1393         struct isl_qpolynomial *qp;
1394         struct isl_token *tok;
1395
1396         tok = next_token(s);
1397         if (!tok) {
1398                 isl_stream_error(s, NULL, "unexpected EOF");
1399                 return NULL;
1400         }
1401         if (tok->type == '(') {
1402                 int pow;
1403
1404                 isl_token_free(tok);
1405                 qp = read_term(s, bmap, v);
1406                 if (!qp)
1407                         return NULL;
1408                 if (isl_stream_eat(s, ')'))
1409                         goto error;
1410                 pow = optional_power(s);
1411                 qp = isl_qpolynomial_pow(qp, pow);
1412         } else if (tok->type == ISL_TOKEN_VALUE) {
1413                 struct isl_token *tok2;
1414                 tok2 = isl_stream_next_token(s);
1415                 if (tok2 && tok2->type == '/') {
1416                         isl_token_free(tok2);
1417                         tok2 = next_token(s);
1418                         if (!tok2 || tok2->type != ISL_TOKEN_VALUE) {
1419                                 isl_stream_error(s, tok2, "expected denominator");
1420                                 isl_token_free(tok);
1421                                 isl_token_free(tok2);
1422                                 return NULL;
1423                         }
1424                         qp = isl_qpolynomial_rat_cst(isl_basic_map_get_dim(bmap),
1425                                                     tok->u.v, tok2->u.v);
1426                         isl_token_free(tok2);
1427                 } else {
1428                         isl_stream_push_token(s, tok2);
1429                         qp = isl_qpolynomial_cst(isl_basic_map_get_dim(bmap),
1430                                                 tok->u.v);
1431                 }
1432                 isl_token_free(tok);
1433         } else if (tok->type == ISL_TOKEN_INFTY) {
1434                 isl_token_free(tok);
1435                 qp = isl_qpolynomial_infty(isl_basic_map_get_dim(bmap));
1436         } else if (tok->type == ISL_TOKEN_NAN) {
1437                 isl_token_free(tok);
1438                 qp = isl_qpolynomial_nan(isl_basic_map_get_dim(bmap));
1439         } else if (tok->type == ISL_TOKEN_IDENT) {
1440                 int n = v->n;
1441                 int pos = vars_pos(v, tok->u.s, -1);
1442                 int pow;
1443                 if (pos < 0) {
1444                         isl_token_free(tok);
1445                         return NULL;
1446                 }
1447                 if (pos >= n) {
1448                         vars_drop(v, v->n - n);
1449                         isl_stream_error(s, tok, "unknown identifier");
1450                         isl_token_free(tok);
1451                         return NULL;
1452                 }
1453                 isl_token_free(tok);
1454                 pow = optional_power(s);
1455                 qp = isl_qpolynomial_var_pow(isl_basic_map_get_dim(bmap), pos, pow);
1456         } else if (tok->type == '[') {
1457                 isl_div *div;
1458                 int pow;
1459
1460                 isl_stream_push_token(s, tok);
1461                 div = read_div(s, isl_basic_map_get_dim(bmap), v);
1462                 pow = optional_power(s);
1463                 qp = isl_qpolynomial_div_pow(div, pow);
1464         } else if (tok->type == '-') {
1465                 struct isl_qpolynomial *qp2;
1466
1467                 isl_token_free(tok);
1468                 qp = isl_qpolynomial_cst(isl_basic_map_get_dim(bmap),
1469                                             s->ctx->negone);
1470                 qp2 = read_factor(s, bmap, v);
1471                 qp = isl_qpolynomial_mul(qp, qp2);
1472         } else {
1473                 isl_stream_error(s, tok, "unexpected isl_token");
1474                 isl_stream_push_token(s, tok);
1475                 return NULL;
1476         }
1477
1478         if (isl_stream_eat_if_available(s, '*') ||
1479             isl_stream_next_token_is(s, ISL_TOKEN_IDENT)) {
1480                 struct isl_qpolynomial *qp2;
1481
1482                 qp2 = read_factor(s, bmap, v);
1483                 qp = isl_qpolynomial_mul(qp, qp2);
1484         }
1485
1486         return qp;
1487 error:
1488         isl_qpolynomial_free(qp);
1489         return NULL;
1490 }
1491
1492 static __isl_give isl_qpolynomial *read_term(struct isl_stream *s,
1493         __isl_keep isl_basic_map *bmap, struct vars *v)
1494 {
1495         struct isl_token *tok;
1496         struct isl_qpolynomial *qp;
1497
1498         qp = read_factor(s, bmap, v);
1499
1500         for (;;) {
1501                 tok = next_token(s);
1502                 if (!tok)
1503                         return qp;
1504
1505                 if (tok->type == '+') {
1506                         struct isl_qpolynomial *qp2;
1507
1508                         isl_token_free(tok);
1509                         qp2 = read_factor(s, bmap, v);
1510                         qp = isl_qpolynomial_add(qp, qp2);
1511                 } else if (tok->type == '-') {
1512                         struct isl_qpolynomial *qp2;
1513
1514                         isl_token_free(tok);
1515                         qp2 = read_factor(s, bmap, v);
1516                         qp = isl_qpolynomial_sub(qp, qp2);
1517                 } else if (tok->type == ISL_TOKEN_VALUE &&
1518                             isl_int_is_neg(tok->u.v)) {
1519                         struct isl_qpolynomial *qp2;
1520
1521                         isl_stream_push_token(s, tok);
1522                         qp2 = read_factor(s, bmap, v);
1523                         qp = isl_qpolynomial_add(qp, qp2);
1524                 } else {
1525                         isl_stream_push_token(s, tok);
1526                         break;
1527                 }
1528         }
1529
1530         return qp;
1531 }
1532
1533 static __isl_give isl_map *read_optional_disjuncts(struct isl_stream *s,
1534         __isl_take isl_basic_map *bmap, struct vars *v)
1535 {
1536         struct isl_token *tok;
1537         struct isl_map *map;
1538
1539         tok = isl_stream_next_token(s);
1540         if (!tok) {
1541                 isl_stream_error(s, NULL, "unexpected EOF");
1542                 goto error;
1543         }
1544         map = isl_map_from_basic_map(isl_basic_map_copy(bmap));
1545         if (tok->type == ':' ||
1546             (tok->type == ISL_TOKEN_OR && !strcmp(tok->u.s, "|"))) {
1547                 isl_token_free(tok);
1548                 map = isl_map_intersect(map,
1549                             read_disjuncts(s, v, isl_basic_map_copy(bmap)));
1550         } else
1551                 isl_stream_push_token(s, tok);
1552
1553         isl_basic_map_free(bmap);
1554
1555         return map;
1556 error:
1557         isl_basic_map_free(bmap);
1558         return NULL;
1559 }
1560
1561 static struct isl_obj obj_read_poly(struct isl_stream *s,
1562         __isl_take isl_basic_map *bmap, struct vars *v, int n)
1563 {
1564         struct isl_obj obj = { isl_obj_pw_qpolynomial, NULL };
1565         struct isl_pw_qpolynomial *pwqp;
1566         struct isl_qpolynomial *qp;
1567         struct isl_map *map;
1568         struct isl_set *set;
1569
1570         qp = read_term(s, bmap, v);
1571         map = read_optional_disjuncts(s, bmap, v);
1572         set = isl_map_range(map);
1573
1574         pwqp = isl_pw_qpolynomial_alloc(set, qp);
1575
1576         vars_drop(v, v->n - n);
1577
1578         obj.v = pwqp;
1579         return obj;
1580 }
1581
1582 static struct isl_obj obj_read_poly_or_fold(struct isl_stream *s,
1583         __isl_take isl_basic_map *bmap, struct vars *v, int n)
1584 {
1585         struct isl_obj obj = { isl_obj_pw_qpolynomial_fold, NULL };
1586         struct isl_obj obj_p;
1587         isl_qpolynomial *qp;
1588         isl_qpolynomial_fold *fold = NULL;
1589         isl_pw_qpolynomial_fold *pwf;
1590         isl_map *map;
1591         isl_set *set;
1592
1593         if (!isl_stream_eat_if_available(s, ISL_TOKEN_MAX))
1594                 return obj_read_poly(s, bmap, v, n);
1595
1596         if (isl_stream_eat(s, '('))
1597                 goto error;
1598
1599         qp = read_term(s, bmap, v);
1600         fold = isl_qpolynomial_fold_alloc(isl_fold_max, qp);
1601
1602         while (isl_stream_eat_if_available(s, ',')) {
1603                 isl_qpolynomial_fold *fold_i;
1604                 qp = read_term(s, bmap, v);
1605                 fold_i = isl_qpolynomial_fold_alloc(isl_fold_max, qp);
1606                 fold = isl_qpolynomial_fold_fold(fold, fold_i);
1607         }
1608
1609         if (isl_stream_eat(s, ')'))
1610                 goto error;
1611
1612         map = read_optional_disjuncts(s, bmap, v);
1613         set = isl_map_range(map);
1614         pwf = isl_pw_qpolynomial_fold_alloc(isl_fold_max, set, fold);
1615
1616         vars_drop(v, v->n - n);
1617
1618         obj.v = pwf;
1619         return obj;
1620 error:
1621         isl_basic_map_free(bmap);
1622         isl_qpolynomial_fold_free(fold);
1623         obj.type = isl_obj_none;
1624         return obj;
1625 }
1626
1627 static int is_rational(struct isl_stream *s)
1628 {
1629         struct isl_token *tok;
1630
1631         tok = isl_stream_next_token(s);
1632         if (!tok)
1633                 return 0;
1634         if (tok->type == ISL_TOKEN_RAT && isl_stream_next_token_is(s, ':')) {
1635                 isl_token_free(tok);
1636                 isl_stream_eat(s, ':');
1637                 return 1;
1638         }
1639
1640         isl_stream_push_token(s, tok);
1641
1642         return 0;
1643 }
1644
1645 static struct isl_obj obj_read_body(struct isl_stream *s,
1646         __isl_take isl_basic_map *bmap, struct vars *v)
1647 {
1648         struct isl_map *map = NULL;
1649         struct isl_token *tok;
1650         struct isl_obj obj = { isl_obj_set, NULL };
1651         int n = v->n;
1652
1653         if (is_rational(s))
1654                 bmap = isl_basic_map_set_rational(bmap);
1655
1656         if (!next_is_tuple(s))
1657                 return obj_read_poly_or_fold(s, bmap, v, n);
1658
1659         bmap = read_tuple(s, bmap, isl_dim_in, v);
1660         if (!bmap)
1661                 goto error;
1662         tok = isl_stream_next_token(s);
1663         if (tok && tok->type == ISL_TOKEN_TO) {
1664                 obj.type = isl_obj_map;
1665                 isl_token_free(tok);
1666                 if (!next_is_tuple(s)) {
1667                         bmap = isl_basic_map_reverse(bmap);
1668                         return obj_read_poly_or_fold(s, bmap, v, n);
1669                 }
1670                 bmap = read_tuple(s, bmap, isl_dim_out, v);
1671                 if (!bmap)
1672                         goto error;
1673         } else {
1674                 bmap = isl_basic_map_reverse(bmap);
1675                 if (tok)
1676                         isl_stream_push_token(s, tok);
1677         }
1678
1679         map = read_optional_disjuncts(s, bmap, v);
1680
1681         vars_drop(v, v->n - n);
1682
1683         obj.v = map;
1684         return obj;
1685 error:
1686         isl_basic_map_free(bmap);
1687         obj.type = isl_obj_none;
1688         return obj;
1689 }
1690
1691 static struct isl_obj to_union(isl_ctx *ctx, struct isl_obj obj)
1692 {
1693         if (obj.type == isl_obj_map) {
1694                 obj.v = isl_union_map_from_map(obj.v);
1695                 obj.type = isl_obj_union_map;
1696         } else if (obj.type == isl_obj_set) {
1697                 obj.v = isl_union_set_from_set(obj.v);
1698                 obj.type = isl_obj_union_set;
1699         } else if (obj.type == isl_obj_pw_qpolynomial) {
1700                 obj.v = isl_union_pw_qpolynomial_from_pw_qpolynomial(obj.v);
1701                 obj.type = isl_obj_union_pw_qpolynomial;
1702         } else if (obj.type == isl_obj_pw_qpolynomial_fold) {
1703                 obj.v = isl_union_pw_qpolynomial_fold_from_pw_qpolynomial_fold(obj.v);
1704                 obj.type = isl_obj_union_pw_qpolynomial_fold;
1705         } else
1706                 isl_assert(ctx, 0, goto error);
1707         return obj;
1708 error:
1709         obj.type->free(obj.v);
1710         obj.type = isl_obj_none;
1711         return obj;
1712 }
1713
1714 static struct isl_obj obj_add(struct isl_ctx *ctx,
1715         struct isl_obj obj1, struct isl_obj obj2)
1716 {
1717         if (obj1.type == isl_obj_set && obj2.type == isl_obj_union_set)
1718                 obj1 = to_union(ctx, obj1);
1719         if (obj1.type == isl_obj_union_set && obj2.type == isl_obj_set)
1720                 obj2 = to_union(ctx, obj2);
1721         if (obj1.type == isl_obj_map && obj2.type == isl_obj_union_map)
1722                 obj1 = to_union(ctx, obj1);
1723         if (obj1.type == isl_obj_union_map && obj2.type == isl_obj_map)
1724                 obj2 = to_union(ctx, obj2);
1725         if (obj1.type == isl_obj_pw_qpolynomial &&
1726             obj2.type == isl_obj_union_pw_qpolynomial)
1727                 obj1 = to_union(ctx, obj1);
1728         if (obj1.type == isl_obj_union_pw_qpolynomial &&
1729             obj2.type == isl_obj_pw_qpolynomial)
1730                 obj2 = to_union(ctx, obj2);
1731         if (obj1.type == isl_obj_pw_qpolynomial_fold &&
1732             obj2.type == isl_obj_union_pw_qpolynomial_fold)
1733                 obj1 = to_union(ctx, obj1);
1734         if (obj1.type == isl_obj_union_pw_qpolynomial_fold &&
1735             obj2.type == isl_obj_pw_qpolynomial_fold)
1736                 obj2 = to_union(ctx, obj2);
1737         isl_assert(ctx, obj1.type == obj2.type, goto error);
1738         if (obj1.type == isl_obj_map && !isl_map_has_equal_dim(obj1.v, obj2.v)) {
1739                 obj1 = to_union(ctx, obj1);
1740                 obj2 = to_union(ctx, obj2);
1741         }
1742         if (obj1.type == isl_obj_set && !isl_set_has_equal_dim(obj1.v, obj2.v)) {
1743                 obj1 = to_union(ctx, obj1);
1744                 obj2 = to_union(ctx, obj2);
1745         }
1746         if (obj1.type == isl_obj_pw_qpolynomial &&
1747             !isl_pw_qpolynomial_has_equal_dim(obj1.v, obj2.v)) {
1748                 obj1 = to_union(ctx, obj1);
1749                 obj2 = to_union(ctx, obj2);
1750         }
1751         if (obj1.type == isl_obj_pw_qpolynomial_fold &&
1752             !isl_pw_qpolynomial_fold_has_equal_dim(obj1.v, obj2.v)) {
1753                 obj1 = to_union(ctx, obj1);
1754                 obj2 = to_union(ctx, obj2);
1755         }
1756         obj1.v = obj1.type->add(obj1.v, obj2.v);
1757         return obj1;
1758 error:
1759         obj1.type->free(obj1.v);
1760         obj2.type->free(obj2.v);
1761         obj1.type = isl_obj_none;
1762         obj1.v = NULL;
1763         return obj1;
1764 }
1765
1766 static struct isl_obj obj_read(struct isl_stream *s, int nparam)
1767 {
1768         isl_basic_map *bmap = NULL;
1769         struct isl_token *tok;
1770         struct vars *v = NULL;
1771         struct isl_obj obj = { isl_obj_set, NULL };
1772
1773         tok = next_token(s);
1774         if (!tok) {
1775                 isl_stream_error(s, NULL, "unexpected EOF");
1776                 goto error;
1777         }
1778         if (tok->type == ISL_TOKEN_VALUE) {
1779                 struct isl_token *tok2;
1780                 struct isl_map *map;
1781
1782                 tok2 = isl_stream_next_token(s);
1783                 if (!tok2 || tok2->type != ISL_TOKEN_VALUE ||
1784                     isl_int_is_neg(tok2->u.v)) {
1785                         if (tok2)
1786                                 isl_stream_push_token(s, tok2);
1787                         obj.type = isl_obj_int;
1788                         obj.v = isl_int_obj_alloc(s->ctx, tok->u.v);
1789                         isl_token_free(tok);
1790                         return obj;
1791                 }
1792                 isl_stream_push_token(s, tok2);
1793                 isl_stream_push_token(s, tok);
1794                 map = map_read_polylib(s, nparam);
1795                 if (!map)
1796                         goto error;
1797                 if (isl_map_dim(map, isl_dim_in) > 0)
1798                         obj.type = isl_obj_map;
1799                 obj.v = map;
1800                 return obj;
1801         }
1802         v = vars_new(s->ctx);
1803         if (!v) {
1804                 isl_stream_push_token(s, tok);
1805                 goto error;
1806         }
1807         bmap = isl_basic_map_alloc(s->ctx, 0, 0, 0, 0, 0, 0);
1808         if (tok->type == '[') {
1809                 isl_stream_push_token(s, tok);
1810                 bmap = read_tuple(s, bmap, isl_dim_param, v);
1811                 if (!bmap)
1812                         goto error;
1813                 if (nparam >= 0)
1814                         isl_assert(s->ctx, nparam == v->n, goto error);
1815                 tok = isl_stream_next_token(s);
1816                 if (!tok || tok->type != ISL_TOKEN_TO) {
1817                         isl_stream_error(s, tok, "expecting '->'");
1818                         if (tok)
1819                                 isl_stream_push_token(s, tok);
1820                         goto error;
1821                 }
1822                 isl_token_free(tok);
1823                 tok = isl_stream_next_token(s);
1824         } else if (nparam > 0)
1825                 bmap = isl_basic_map_add(bmap, isl_dim_param, nparam);
1826         if (!tok || tok->type != '{') {
1827                 isl_stream_error(s, tok, "expecting '{'");
1828                 if (tok)
1829                         isl_stream_push_token(s, tok);
1830                 goto error;
1831         }
1832         isl_token_free(tok);
1833
1834         tok = isl_stream_next_token(s);
1835         if (!tok)
1836                 ;
1837         else if (tok->type == ISL_TOKEN_IDENT && !strcmp(tok->u.s, "Sym")) {
1838                 isl_token_free(tok);
1839                 if (isl_stream_eat(s, '='))
1840                         goto error;
1841                 bmap = read_tuple(s, bmap, isl_dim_param, v);
1842                 if (!bmap)
1843                         goto error;
1844                 if (nparam >= 0)
1845                         isl_assert(s->ctx, nparam == v->n, goto error);
1846         } else if (tok->type == '}') {
1847                 obj.type = isl_obj_union_set;
1848                 obj.v = isl_union_set_empty(isl_basic_map_get_dim(bmap));
1849                 isl_token_free(tok);
1850                 goto done;
1851         } else
1852                 isl_stream_push_token(s, tok);
1853
1854         for (;;) {
1855                 struct isl_obj o;
1856                 tok = NULL;
1857                 o = obj_read_body(s, isl_basic_map_copy(bmap), v);
1858                 if (o.type == isl_obj_none || !o.v)
1859                         goto error;
1860                 if (!obj.v)
1861                         obj = o;
1862                 else {
1863                         obj = obj_add(s->ctx, obj, o);
1864                         if (obj.type == isl_obj_none || !obj.v)
1865                                 goto error;
1866                 }
1867                 tok = isl_stream_next_token(s);
1868                 if (!tok || tok->type != ';')
1869                         break;
1870                 isl_token_free(tok);
1871                 if (isl_stream_next_token_is(s, '}')) {
1872                         tok = isl_stream_next_token(s);
1873                         break;
1874                 }
1875         }
1876
1877         if (tok && tok->type == '}') {
1878                 isl_token_free(tok);
1879         } else {
1880                 isl_stream_error(s, tok, "unexpected isl_token");
1881                 if (tok)
1882                         isl_token_free(tok);
1883                 goto error;
1884         }
1885 done:
1886         vars_free(v);
1887         isl_basic_map_free(bmap);
1888
1889         return obj;
1890 error:
1891         isl_basic_map_free(bmap);
1892         obj.type->free(obj.v);
1893         if (v)
1894                 vars_free(v);
1895         obj.v = NULL;
1896         return obj;
1897 }
1898
1899 struct isl_obj isl_stream_read_obj(struct isl_stream *s)
1900 {
1901         return obj_read(s, -1);
1902 }
1903
1904 __isl_give isl_map *isl_stream_read_map(struct isl_stream *s, int nparam)
1905 {
1906         struct isl_obj obj;
1907         struct isl_map *map;
1908
1909         obj = obj_read(s, nparam);
1910         if (obj.v)
1911                 isl_assert(s->ctx, obj.type == isl_obj_map ||
1912                                    obj.type == isl_obj_set, goto error);
1913
1914         return obj.v;
1915 error:
1916         obj.type->free(obj.v);
1917         return NULL;
1918 }
1919
1920 __isl_give isl_set *isl_stream_read_set(struct isl_stream *s, int nparam)
1921 {
1922         struct isl_obj obj;
1923         struct isl_set *set;
1924
1925         obj = obj_read(s, nparam);
1926         if (obj.v)
1927                 isl_assert(s->ctx, obj.type == isl_obj_set, goto error);
1928
1929         return obj.v;
1930 error:
1931         obj.type->free(obj.v);
1932         return NULL;
1933 }
1934
1935 __isl_give isl_union_map *isl_stream_read_union_map(struct isl_stream *s)
1936 {
1937         struct isl_obj obj;
1938         isl_union_map *umap;
1939
1940         obj = obj_read(s, -1);
1941         if (obj.type == isl_obj_map) {
1942                 obj.type = isl_obj_union_map;
1943                 obj.v = isl_union_map_from_map(obj.v);
1944         }
1945         if (obj.type == isl_obj_set) {
1946                 obj.type = isl_obj_union_set;
1947                 obj.v = isl_union_set_from_set(obj.v);
1948         }
1949         if (obj.v)
1950                 isl_assert(s->ctx, obj.type == isl_obj_union_map ||
1951                                    obj.type == isl_obj_union_set, goto error);
1952
1953         return obj.v;
1954 error:
1955         obj.type->free(obj.v);
1956         return NULL;
1957 }
1958
1959 __isl_give isl_union_set *isl_stream_read_union_set(struct isl_stream *s)
1960 {
1961         struct isl_obj obj;
1962         isl_union_set *uset;
1963
1964         obj = obj_read(s, -1);
1965         if (obj.type == isl_obj_set) {
1966                 obj.type = isl_obj_union_set;
1967                 obj.v = isl_union_set_from_set(obj.v);
1968         }
1969         if (obj.v)
1970                 isl_assert(s->ctx, obj.type == isl_obj_union_set, goto error);
1971
1972         return obj.v;
1973 error:
1974         obj.type->free(obj.v);
1975         return NULL;
1976 }
1977
1978 static struct isl_basic_map *basic_map_read(struct isl_stream *s, int nparam)
1979 {
1980         struct isl_obj obj;
1981         struct isl_map *map;
1982         struct isl_basic_map *bmap;
1983
1984         obj = obj_read(s, nparam);
1985         map = obj.v;
1986         if (!map)
1987                 return NULL;
1988
1989         isl_assert(map->ctx, map->n <= 1, goto error);
1990
1991         if (map->n == 0)
1992                 bmap = isl_basic_map_empty_like_map(map);
1993         else
1994                 bmap = isl_basic_map_copy(map->p[0]);
1995
1996         isl_map_free(map);
1997
1998         return bmap;
1999 error:
2000         isl_map_free(map);
2001         return NULL;
2002 }
2003
2004 __isl_give isl_basic_map *isl_basic_map_read_from_file(isl_ctx *ctx,
2005                 FILE *input, int nparam)
2006 {
2007         struct isl_basic_map *bmap;
2008         struct isl_stream *s = isl_stream_new_file(ctx, input);
2009         if (!s)
2010                 return NULL;
2011         bmap = basic_map_read(s, nparam);
2012         isl_stream_free(s);
2013         return bmap;
2014 }
2015
2016 __isl_give isl_basic_set *isl_basic_set_read_from_file(isl_ctx *ctx,
2017                 FILE *input, int nparam)
2018 {
2019         struct isl_basic_map *bmap;
2020         bmap = isl_basic_map_read_from_file(ctx, input, nparam);
2021         if (!bmap)
2022                 return NULL;
2023         isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
2024         return (struct isl_basic_set *)bmap;
2025 error:
2026         isl_basic_map_free(bmap);
2027         return NULL;
2028 }
2029
2030 struct isl_basic_map *isl_basic_map_read_from_str(struct isl_ctx *ctx,
2031                 const char *str, int nparam)
2032 {
2033         struct isl_basic_map *bmap;
2034         struct isl_stream *s = isl_stream_new_str(ctx, str);
2035         if (!s)
2036                 return NULL;
2037         bmap = basic_map_read(s, nparam);
2038         isl_stream_free(s);
2039         return bmap;
2040 }
2041
2042 struct isl_basic_set *isl_basic_set_read_from_str(struct isl_ctx *ctx,
2043                 const char *str, int nparam)
2044 {
2045         struct isl_basic_map *bmap;
2046         bmap = isl_basic_map_read_from_str(ctx, str, nparam);
2047         if (!bmap)
2048                 return NULL;
2049         isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
2050         return (struct isl_basic_set *)bmap;
2051 error:
2052         isl_basic_map_free(bmap);
2053         return NULL;
2054 }
2055
2056 __isl_give isl_map *isl_map_read_from_file(struct isl_ctx *ctx,
2057                 FILE *input, int nparam)
2058 {
2059         struct isl_map *map;
2060         struct isl_stream *s = isl_stream_new_file(ctx, input);
2061         if (!s)
2062                 return NULL;
2063         map = isl_stream_read_map(s, nparam);
2064         isl_stream_free(s);
2065         return map;
2066 }
2067
2068 __isl_give isl_map *isl_map_read_from_str(struct isl_ctx *ctx,
2069                 const char *str, int nparam)
2070 {
2071         struct isl_map *map;
2072         struct isl_stream *s = isl_stream_new_str(ctx, str);
2073         if (!s)
2074                 return NULL;
2075         map = isl_stream_read_map(s, nparam);
2076         isl_stream_free(s);
2077         return map;
2078 }
2079
2080 __isl_give isl_set *isl_set_read_from_file(struct isl_ctx *ctx,
2081                 FILE *input, int nparam)
2082 {
2083         struct isl_map *map;
2084         map = isl_map_read_from_file(ctx, input, nparam);
2085         if (!map)
2086                 return NULL;
2087         isl_assert(ctx, isl_map_n_in(map) == 0, goto error);
2088         return (struct isl_set *)map;
2089 error:
2090         isl_map_free(map);
2091         return NULL;
2092 }
2093
2094 struct isl_set *isl_set_read_from_str(struct isl_ctx *ctx,
2095                 const char *str, int nparam)
2096 {
2097         struct isl_map *map;
2098         map = isl_map_read_from_str(ctx, str, nparam);
2099         if (!map)
2100                 return NULL;
2101         isl_assert(ctx, isl_map_n_in(map) == 0, goto error);
2102         return (struct isl_set *)map;
2103 error:
2104         isl_map_free(map);
2105         return NULL;
2106 }
2107
2108 __isl_give isl_union_map *isl_union_map_read_from_file(isl_ctx *ctx,
2109         FILE *input)
2110 {
2111         isl_union_map *umap;
2112         struct isl_stream *s = isl_stream_new_file(ctx, input);
2113         if (!s)
2114                 return NULL;
2115         umap = isl_stream_read_union_map(s);
2116         isl_stream_free(s);
2117         return umap;
2118 }
2119
2120 __isl_give isl_union_map *isl_union_map_read_from_str(struct isl_ctx *ctx,
2121                 const char *str)
2122 {
2123         isl_union_map *umap;
2124         struct isl_stream *s = isl_stream_new_str(ctx, str);
2125         if (!s)
2126                 return NULL;
2127         umap = isl_stream_read_union_map(s);
2128         isl_stream_free(s);
2129         return umap;
2130 }
2131
2132 __isl_give isl_union_set *isl_union_set_read_from_file(isl_ctx *ctx,
2133         FILE *input)
2134 {
2135         isl_union_set *uset;
2136         struct isl_stream *s = isl_stream_new_file(ctx, input);
2137         if (!s)
2138                 return NULL;
2139         uset = isl_stream_read_union_set(s);
2140         isl_stream_free(s);
2141         return uset;
2142 }
2143
2144 __isl_give isl_union_set *isl_union_set_read_from_str(struct isl_ctx *ctx,
2145                 const char *str)
2146 {
2147         isl_union_set *uset;
2148         struct isl_stream *s = isl_stream_new_str(ctx, str);
2149         if (!s)
2150                 return NULL;
2151         uset = isl_stream_read_union_set(s);
2152         isl_stream_free(s);
2153         return uset;
2154 }
2155
2156 static __isl_give isl_vec *isl_vec_read_polylib(struct isl_stream *s)
2157 {
2158         struct isl_vec *vec = NULL;
2159         struct isl_token *tok;
2160         unsigned size;
2161         int j;
2162
2163         tok = isl_stream_next_token(s);
2164         if (!tok || tok->type != ISL_TOKEN_VALUE) {
2165                 isl_stream_error(s, tok, "expecting vector length");
2166                 goto error;
2167         }
2168
2169         size = isl_int_get_si(tok->u.v);
2170         isl_token_free(tok);
2171
2172         vec = isl_vec_alloc(s->ctx, size);
2173
2174         for (j = 0; j < size; ++j) {
2175                 tok = isl_stream_next_token(s);
2176                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
2177                         isl_stream_error(s, tok, "expecting constant value");
2178                         goto error;
2179                 }
2180                 isl_int_set(vec->el[j], tok->u.v);
2181                 isl_token_free(tok);
2182         }
2183
2184         return vec;
2185 error:
2186         isl_token_free(tok);
2187         isl_vec_free(vec);
2188         return NULL;
2189 }
2190
2191 static __isl_give isl_vec *vec_read(struct isl_stream *s)
2192 {
2193         return isl_vec_read_polylib(s);
2194 }
2195
2196 __isl_give isl_vec *isl_vec_read_from_file(isl_ctx *ctx, FILE *input)
2197 {
2198         isl_vec *v;
2199         struct isl_stream *s = isl_stream_new_file(ctx, input);
2200         if (!s)
2201                 return NULL;
2202         v = vec_read(s);
2203         isl_stream_free(s);
2204         return v;
2205 }
2206
2207 __isl_give isl_pw_qpolynomial *isl_stream_read_pw_qpolynomial(
2208         struct isl_stream *s)
2209 {
2210         struct isl_obj obj;
2211         struct isl_pw_qpolynomial *pwqp;
2212
2213         obj = obj_read(s, -1);
2214         if (obj.v)
2215                 isl_assert(s->ctx, obj.type == isl_obj_pw_qpolynomial,
2216                            goto error);
2217
2218         return obj.v;
2219 error:
2220         obj.type->free(obj.v);
2221         return NULL;
2222 }
2223
2224 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_read_from_str(isl_ctx *ctx,
2225                 const char *str)
2226 {
2227         isl_pw_qpolynomial *pwqp;
2228         struct isl_stream *s = isl_stream_new_str(ctx, str);
2229         if (!s)
2230                 return NULL;
2231         pwqp = isl_stream_read_pw_qpolynomial(s);
2232         isl_stream_free(s);
2233         return pwqp;
2234 }