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