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