9dca42396aec13890a58b76b6daa77fecde8a8ca
[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 pos)
636 {
637         struct variable *var = v->v;
638         unsigned o_out = isl_basic_map_offset(bmap, isl_dim_out) - 1;
639
640         if (read_div_definition(s, v) < 0)
641                 goto error;
642
643         if (isl_basic_map_add_div_constraints_var(bmap, o_out + pos,
644                                                   var->def->el) < 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 p;
660                 int n = v->n;
661                 unsigned n_out = isl_basic_map_dim(bmap, isl_dim_out);
662
663                 if (tok->type != ISL_TOKEN_IDENT)
664                         break;
665
666                 p = vars_pos(v, tok->u.s, -1);
667                 if (p < 0)
668                         goto error;
669                 if (p < n) {
670                         isl_stream_error(s, tok, "expecting unique identifier");
671                         goto error;
672                 }
673
674                 bmap = isl_basic_map_cow(bmap);
675                 bmap = isl_basic_map_add(bmap, isl_dim_out, 1);
676                 bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim),
677                                                 0, 0, 2);
678
679                 isl_token_free(tok);
680                 tok = isl_stream_next_token(s);
681                 if (tok && tok->type == '=') {
682                         isl_token_free(tok);
683                         bmap = add_div_definition(s, v, bmap, n_out);
684                         tok = isl_stream_next_token(s);
685                 }
686
687                 if (!tok || tok->type != ',')
688                         break;
689
690                 isl_token_free(tok);
691         }
692         if (tok)
693                 isl_stream_push_token(s, tok);
694
695         return bmap;
696 error:
697         isl_token_free(tok);
698         isl_basic_map_free(bmap);
699         return NULL;
700 }
701
702 static int next_is_tuple(struct isl_stream *s)
703 {
704         struct isl_token *tok;
705         int is_tuple;
706
707         tok = isl_stream_next_token(s);
708         if (!tok)
709                 return 0;
710         if (tok->type == '[') {
711                 isl_stream_push_token(s, tok);
712                 return 1;
713         }
714         if (tok->type != ISL_TOKEN_IDENT && !tok->is_keyword) {
715                 isl_stream_push_token(s, tok);
716                 return 0;
717         }
718
719         is_tuple = isl_stream_next_token_is(s, '[');
720
721         isl_stream_push_token(s, tok);
722
723         return is_tuple;
724 }
725
726 static __isl_give isl_basic_map *read_tuple(struct isl_stream *s,
727         __isl_take isl_basic_map *bmap, enum isl_dim_type type, struct vars *v);
728
729 static __isl_give isl_basic_map *read_nested_tuple(struct isl_stream *s,
730         __isl_take isl_basic_map *bmap, struct vars *v)
731 {
732         bmap = read_tuple(s, bmap, isl_dim_in, v);
733         if (isl_stream_eat(s, ISL_TOKEN_TO))
734                 goto error;
735         bmap = read_tuple(s, bmap, isl_dim_out, v);
736         bmap = isl_basic_map_from_range(isl_basic_map_wrap(bmap));
737         return bmap;
738 error:
739         isl_basic_map_free(bmap);
740         return NULL;
741 }
742
743 static __isl_give isl_basic_map *read_tuple(struct isl_stream *s,
744         __isl_take isl_basic_map *bmap, enum isl_dim_type type, struct vars *v)
745 {
746         struct isl_token *tok;
747         char *name = NULL;
748
749         tok = isl_stream_next_token(s);
750         if (tok && (tok->type == ISL_TOKEN_IDENT || tok->is_keyword)) {
751                 name = strdup(tok->u.s);
752                 if (!name)
753                         goto error;
754                 isl_token_free(tok);
755                 tok = isl_stream_next_token(s);
756         }
757         if (!tok || tok->type != '[') {
758                 isl_stream_error(s, tok, "expecting '['");
759                 goto error;
760         }
761         isl_token_free(tok);
762         if (type != isl_dim_param && next_is_tuple(s)) {
763                 isl_dim *dim = isl_basic_map_get_dim(bmap);
764                 int nparam = isl_dim_size(dim, isl_dim_param);
765                 int n_in = isl_dim_size(dim, isl_dim_in);
766                 isl_basic_map *nested;
767                 if (type == isl_dim_out)
768                         dim = isl_dim_move(dim, isl_dim_param, nparam,
769                                                 isl_dim_in, 0, n_in);
770                 nested = isl_basic_map_alloc_dim(dim, 0, 0, 0);
771                 nested = read_nested_tuple(s, nested, v);
772                 if (type == isl_dim_in) {
773                         nested = isl_basic_map_reverse(nested);
774                         bmap = isl_basic_map_intersect(nested, bmap);
775                 } else {
776                         isl_basic_set *bset;
777                         dim = isl_dim_range(isl_basic_map_get_dim(nested));
778                         dim = isl_dim_drop(dim, isl_dim_param, nparam, n_in);
779                         dim = isl_dim_join(isl_basic_map_get_dim(bmap), dim);
780                         bset = isl_basic_map_domain(bmap);
781                         nested = isl_basic_map_reset_dim(nested, dim);
782                         bmap = isl_basic_map_intersect_domain(nested, bset);
783                 }
784         } else
785                 bmap = read_var_list(s, bmap, type, v);
786         tok = isl_stream_next_token(s);
787         if (!tok || tok->type != ']') {
788                 isl_stream_error(s, tok, "expecting ']'");
789                 goto error;
790         }
791         isl_token_free(tok);
792
793         if (name) {
794                 bmap = isl_basic_map_set_tuple_name(bmap, type, name);
795                 free(name);
796         }
797
798         return bmap;
799 error:
800         if (tok)
801                 isl_token_free(tok);
802         isl_basic_map_free(bmap);
803         return NULL;
804 }
805
806 static __isl_give isl_basic_map *construct_constraint(
807         __isl_take isl_basic_map *bmap, enum isl_token_type type,
808         isl_int *left, isl_int *right)
809 {
810         int k;
811         unsigned len;
812         struct isl_ctx *ctx;
813
814         if (!bmap)
815                 return NULL;
816         len = 1 + isl_basic_map_total_dim(bmap);
817         ctx = bmap->ctx;
818
819         k = isl_basic_map_alloc_inequality(bmap);
820         if (k < 0)
821                 goto error;
822         if (type == ISL_TOKEN_LE)
823                 isl_seq_combine(bmap->ineq[k], ctx->negone, left,
824                                                ctx->one, right,
825                                                len);
826         else if (type == ISL_TOKEN_GE)
827                 isl_seq_combine(bmap->ineq[k], ctx->one, left,
828                                                ctx->negone, right,
829                                                len);
830         else if (type == ISL_TOKEN_LT) {
831                 isl_seq_combine(bmap->ineq[k], ctx->negone, left,
832                                                ctx->one, right,
833                                                len);
834                 isl_int_sub_ui(bmap->ineq[k][0], bmap->ineq[k][0], 1);
835         } else if (type == ISL_TOKEN_GT) {
836                 isl_seq_combine(bmap->ineq[k], ctx->one, left,
837                                                ctx->negone, right,
838                                                len);
839                 isl_int_sub_ui(bmap->ineq[k][0], bmap->ineq[k][0], 1);
840         } else {
841                 isl_seq_combine(bmap->ineq[k], ctx->one, left,
842                                                ctx->negone, right,
843                                                len);
844                 isl_basic_map_inequality_to_equality(bmap, k);
845         }
846
847         return bmap;
848 error:
849         isl_basic_map_free(bmap);
850         return NULL;
851 }
852
853 static int is_comparator(struct isl_token *tok)
854 {
855         if (!tok)
856                 return 0;
857
858         switch (tok->type) {
859         case ISL_TOKEN_LT:
860         case ISL_TOKEN_GT:
861         case ISL_TOKEN_LE:
862         case ISL_TOKEN_GE:
863         case '=':
864                 return 1;
865         default:
866                 return 0;
867         }
868 }
869
870 static struct isl_basic_map *add_constraint(struct isl_stream *s,
871         struct vars *v, struct isl_basic_map *bmap)
872 {
873         int i, j;
874         struct isl_token *tok = NULL;
875         struct isl_mat *aff1 = NULL, *aff2 = NULL;
876
877         bmap = isl_basic_map_cow(bmap);
878
879         aff1 = accept_affine_list(s, v);
880         if (!aff1)
881                 goto error;
882         tok = isl_stream_next_token(s);
883         if (!is_comparator(tok)) {
884                 isl_stream_error(s, tok, "missing operator");
885                 if (tok)
886                         isl_stream_push_token(s, tok);
887                 tok = NULL;
888                 goto error;
889         }
890         for (;;) {
891                 aff2 = accept_affine_list(s, v);
892                 if (!aff2)
893                         goto error;
894
895                 aff1 = isl_mat_add_zero_cols(aff1, aff2->n_col - aff1->n_col);
896                 if (!aff1)
897                         goto error;
898                 bmap = add_divs(bmap, v);
899                 bmap = isl_basic_map_extend_constraints(bmap, 0,
900                                                 aff1->n_row * aff2->n_row);
901                 for (i = 0; i < aff1->n_row; ++i)
902                         for (j = 0; j < aff2->n_row; ++j)
903                                 bmap = construct_constraint(bmap, tok->type,
904                                                     aff1->row[i], aff2->row[j]);
905                 isl_token_free(tok);
906                 isl_mat_free(aff1);
907                 aff1 = aff2;
908
909                 tok = isl_stream_next_token(s);
910                 if (!is_comparator(tok)) {
911                         if (tok)
912                                 isl_stream_push_token(s, tok);
913                         break;
914                 }
915         }
916         isl_mat_free(aff1);
917
918         return bmap;
919 error:
920         if (tok)
921                 isl_token_free(tok);
922         isl_mat_free(aff1);
923         isl_mat_free(aff2);
924         isl_basic_map_free(bmap);
925         return NULL;
926 }
927
928 static isl_map *read_constraint(struct isl_stream *s,
929         struct vars *v, __isl_take isl_basic_map *bmap)
930 {
931         int n = v->n;
932
933         if (!bmap)
934                 return NULL;
935
936         bmap = add_constraint(s, v, bmap);
937         bmap = isl_basic_map_simplify(bmap);
938         bmap = isl_basic_map_finalize(bmap);
939
940         vars_drop(v, v->n - n);
941
942         return isl_map_from_basic_map(bmap);
943 error:
944         isl_basic_map_free(bmap);
945         return NULL;
946 }
947
948 static struct isl_map *read_disjuncts(struct isl_stream *s,
949         struct vars *v, __isl_take isl_basic_map *bmap);
950
951 static __isl_give isl_map *read_exists(struct isl_stream *s,
952         struct vars *v, __isl_take isl_basic_map *bmap)
953 {
954         int n = v->n;
955         int seen_paren = isl_stream_eat_if_available(s, '(');
956         isl_map *map = NULL;
957
958         bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
959         bmap = read_defined_var_list(s, v, bmap);
960
961         if (isl_stream_eat(s, ':'))
962                 goto error;
963
964         map = read_disjuncts(s, v, bmap);
965         map = isl_set_unwrap(isl_map_domain(map));
966         bmap = NULL;
967
968         vars_drop(v, v->n - n);
969         if (seen_paren && isl_stream_eat(s, ')'))
970                 goto error;
971
972         return map;
973 error:
974         isl_basic_map_free(bmap);
975         isl_map_free(map);
976         return NULL;
977 }
978
979 static __isl_give isl_map *read_conjunct(struct isl_stream *s,
980         struct vars *v, __isl_take isl_basic_map *bmap)
981 {
982         isl_map *map;
983
984         if (isl_stream_eat_if_available(s, '(')) {
985                 map = read_disjuncts(s, v, bmap);
986                 if (isl_stream_eat(s, ')'))
987                         goto error;
988                 return map;
989         }
990
991         if (isl_stream_eat_if_available(s, ISL_TOKEN_EXISTS))
992                 return read_exists(s, v, bmap);
993                 
994         return read_constraint(s, v, bmap);
995 error:
996         isl_map_free(map);
997         return NULL;
998 }
999
1000 static __isl_give isl_map *read_conjuncts(struct isl_stream *s,
1001         struct vars *v, __isl_take isl_basic_map *bmap)
1002 {
1003         isl_map *map;
1004         int negate;
1005
1006         negate = isl_stream_eat_if_available(s, ISL_TOKEN_NOT);
1007         map = read_conjunct(s, v, isl_basic_map_copy(bmap));
1008         if (negate) {
1009                 isl_map *t;
1010                 t = isl_map_from_basic_map(isl_basic_map_copy(bmap));
1011                 map = isl_map_subtract(t, map);
1012         }
1013
1014         while (isl_stream_eat_if_available(s, ISL_TOKEN_AND)) {
1015                 isl_map *map_i;
1016
1017                 negate = isl_stream_eat_if_available(s, ISL_TOKEN_NOT);
1018                 map_i = read_conjunct(s, v, isl_basic_map_copy(bmap));
1019                 if (negate)
1020                         map = isl_map_subtract(map, map_i);
1021                 else
1022                         map = isl_map_intersect(map, map_i);
1023         }
1024
1025         isl_basic_map_free(bmap);
1026         return map;
1027 }
1028
1029 static struct isl_map *read_disjuncts(struct isl_stream *s,
1030         struct vars *v, __isl_take isl_basic_map *bmap)
1031 {
1032         struct isl_map *map;
1033
1034         if (isl_stream_next_token_is(s, '}')) {
1035                 isl_dim *dim = isl_basic_map_get_dim(bmap);
1036                 isl_basic_map_free(bmap);
1037                 return isl_map_universe(dim);
1038         }
1039
1040         map = read_conjuncts(s, v, isl_basic_map_copy(bmap));
1041         while (isl_stream_eat_if_available(s, ISL_TOKEN_OR)) {
1042                 isl_map *map_i;
1043
1044                 map_i = read_conjuncts(s, v, isl_basic_map_copy(bmap));
1045                 map = isl_map_union(map, map_i);
1046         }
1047
1048         isl_basic_map_free(bmap);
1049         return map;
1050 }
1051
1052 static int polylib_pos_to_isl_pos(__isl_keep isl_basic_map *bmap, int pos)
1053 {
1054         if (pos < isl_basic_map_dim(bmap, isl_dim_out))
1055                 return 1 + isl_basic_map_dim(bmap, isl_dim_param) +
1056                            isl_basic_map_dim(bmap, isl_dim_in) + pos;
1057         pos -= isl_basic_map_dim(bmap, isl_dim_out);
1058
1059         if (pos < isl_basic_map_dim(bmap, isl_dim_in))
1060                 return 1 + isl_basic_map_dim(bmap, isl_dim_param) + pos;
1061         pos -= isl_basic_map_dim(bmap, isl_dim_in);
1062
1063         if (pos < isl_basic_map_dim(bmap, isl_dim_div))
1064                 return 1 + isl_basic_map_dim(bmap, isl_dim_param) +
1065                            isl_basic_map_dim(bmap, isl_dim_in) +
1066                            isl_basic_map_dim(bmap, isl_dim_out) + pos;
1067         pos -= isl_basic_map_dim(bmap, isl_dim_div);
1068
1069         if (pos < isl_basic_map_dim(bmap, isl_dim_param))
1070                 return 1 + pos;
1071
1072         return 0;
1073 }
1074
1075 static __isl_give isl_basic_map *basic_map_read_polylib_constraint(
1076         struct isl_stream *s, __isl_take isl_basic_map *bmap)
1077 {
1078         int j;
1079         struct isl_token *tok;
1080         int type;
1081         int k;
1082         isl_int *c;
1083         unsigned nparam;
1084         unsigned dim;
1085
1086         if (!bmap)
1087                 return NULL;
1088
1089         nparam = isl_basic_map_dim(bmap, isl_dim_param);
1090         dim = isl_basic_map_dim(bmap, isl_dim_out);
1091
1092         tok = isl_stream_next_token(s);
1093         if (!tok || tok->type != ISL_TOKEN_VALUE) {
1094                 isl_stream_error(s, tok, "expecting coefficient");
1095                 if (tok)
1096                         isl_stream_push_token(s, tok);
1097                 goto error;
1098         }
1099         if (!tok->on_new_line) {
1100                 isl_stream_error(s, tok, "coefficient should appear on new line");
1101                 isl_stream_push_token(s, tok);
1102                 goto error;
1103         }
1104
1105         type = isl_int_get_si(tok->u.v);
1106         isl_token_free(tok);
1107
1108         isl_assert(s->ctx, type == 0 || type == 1, goto error);
1109         if (type == 0) {
1110                 k = isl_basic_map_alloc_equality(bmap);
1111                 c = bmap->eq[k];
1112         } else {
1113                 k = isl_basic_map_alloc_inequality(bmap);
1114                 c = bmap->ineq[k];
1115         }
1116         if (k < 0)
1117                 goto error;
1118
1119         for (j = 0; j < 1 + isl_basic_map_total_dim(bmap); ++j) {
1120                 int pos;
1121                 tok = isl_stream_next_token(s);
1122                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
1123                         isl_stream_error(s, tok, "expecting coefficient");
1124                         if (tok)
1125                                 isl_stream_push_token(s, tok);
1126                         goto error;
1127                 }
1128                 if (tok->on_new_line) {
1129                         isl_stream_error(s, tok,
1130                                 "coefficient should not appear on new line");
1131                         isl_stream_push_token(s, tok);
1132                         goto error;
1133                 }
1134                 pos = polylib_pos_to_isl_pos(bmap, j);
1135                 isl_int_set(c[pos], tok->u.v);
1136                 isl_token_free(tok);
1137         }
1138
1139         return bmap;
1140 error:
1141         isl_basic_map_free(bmap);
1142         return NULL;
1143 }
1144
1145 static __isl_give isl_basic_map *basic_map_read_polylib(struct isl_stream *s,
1146         int nparam)
1147 {
1148         int i;
1149         struct isl_token *tok;
1150         struct isl_token *tok2;
1151         int n_row, n_col;
1152         int on_new_line;
1153         unsigned in = 0, out, local = 0;
1154         struct isl_basic_map *bmap = NULL;
1155
1156         if (nparam < 0)
1157                 nparam = 0;
1158
1159         tok = isl_stream_next_token(s);
1160         if (!tok) {
1161                 isl_stream_error(s, NULL, "unexpected EOF");
1162                 return NULL;
1163         }
1164         tok2 = isl_stream_next_token(s);
1165         if (!tok2) {
1166                 isl_token_free(tok);
1167                 isl_stream_error(s, NULL, "unexpected EOF");
1168                 return NULL;
1169         }
1170         if (tok->type != ISL_TOKEN_VALUE || tok2->type != ISL_TOKEN_VALUE) {
1171                 isl_stream_push_token(s, tok2);
1172                 isl_stream_push_token(s, tok);
1173                 isl_stream_error(s, NULL,
1174                                  "expecting constraint matrix dimensions");
1175                 return NULL;
1176         }
1177         n_row = isl_int_get_si(tok->u.v);
1178         n_col = isl_int_get_si(tok2->u.v);
1179         on_new_line = tok2->on_new_line;
1180         isl_token_free(tok2);
1181         isl_token_free(tok);
1182         isl_assert(s->ctx, !on_new_line, return NULL);
1183         isl_assert(s->ctx, n_row >= 0, return NULL);
1184         isl_assert(s->ctx, n_col >= 2 + nparam, return NULL);
1185         tok = isl_stream_next_token_on_same_line(s);
1186         if (tok) {
1187                 if (tok->type != ISL_TOKEN_VALUE) {
1188                         isl_stream_error(s, tok,
1189                                     "expecting number of output dimensions");
1190                         isl_stream_push_token(s, tok);
1191                         goto error;
1192                 }
1193                 out = isl_int_get_si(tok->u.v);
1194                 isl_token_free(tok);
1195
1196                 tok = isl_stream_next_token_on_same_line(s);
1197                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
1198                         isl_stream_error(s, tok,
1199                                     "expecting number of input dimensions");
1200                         if (tok)
1201                                 isl_stream_push_token(s, tok);
1202                         goto error;
1203                 }
1204                 in = isl_int_get_si(tok->u.v);
1205                 isl_token_free(tok);
1206
1207                 tok = isl_stream_next_token_on_same_line(s);
1208                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
1209                         isl_stream_error(s, tok,
1210                                     "expecting number of existentials");
1211                         if (tok)
1212                                 isl_stream_push_token(s, tok);
1213                         goto error;
1214                 }
1215                 local = isl_int_get_si(tok->u.v);
1216                 isl_token_free(tok);
1217
1218                 tok = isl_stream_next_token_on_same_line(s);
1219                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
1220                         isl_stream_error(s, tok,
1221                                     "expecting number of parameters");
1222                         if (tok)
1223                                 isl_stream_push_token(s, tok);
1224                         goto error;
1225                 }
1226                 nparam = isl_int_get_si(tok->u.v);
1227                 isl_token_free(tok);
1228                 if (n_col != 1 + out + in + local + nparam + 1) {
1229                         isl_stream_error(s, NULL,
1230                                     "dimensions don't match");
1231                         goto error;
1232                 }
1233         } else
1234                 out = n_col - 2 - nparam;
1235         bmap = isl_basic_map_alloc(s->ctx, nparam, in, out, local, n_row, n_row);
1236         if (!bmap)
1237                 return NULL;
1238
1239         for (i = 0; i < local; ++i) {
1240                 int k = isl_basic_map_alloc_div(bmap);
1241                 if (k < 0)
1242                         goto error;
1243                 isl_seq_clr(bmap->div[k], 1 + 1 + nparam + in + out + local);
1244         }
1245
1246         for (i = 0; i < n_row; ++i)
1247                 bmap = basic_map_read_polylib_constraint(s, bmap);
1248
1249         tok = isl_stream_next_token_on_same_line(s);
1250         if (tok) {
1251                 isl_stream_error(s, tok, "unexpected extra token on line");
1252                 isl_stream_push_token(s, tok);
1253                 goto error;
1254         }
1255
1256         bmap = isl_basic_map_simplify(bmap);
1257         bmap = isl_basic_map_finalize(bmap);
1258         return bmap;
1259 error:
1260         isl_basic_map_free(bmap);
1261         return NULL;
1262 }
1263
1264 static struct isl_map *map_read_polylib(struct isl_stream *s, int nparam)
1265 {
1266         struct isl_token *tok;
1267         struct isl_token *tok2;
1268         int i, n;
1269         struct isl_map *map;
1270
1271         tok = isl_stream_next_token(s);
1272         if (!tok) {
1273                 isl_stream_error(s, NULL, "unexpected EOF");
1274                 return NULL;
1275         }
1276         tok2 = isl_stream_next_token_on_same_line(s);
1277         if (tok2 && tok2->type == ISL_TOKEN_VALUE) {
1278                 isl_stream_push_token(s, tok2);
1279                 isl_stream_push_token(s, tok);
1280                 return isl_map_from_basic_map(basic_map_read_polylib(s, nparam));
1281         }
1282         if (tok2) {
1283                 isl_stream_error(s, tok2, "unexpected token");
1284                 isl_stream_push_token(s, tok2);
1285                 isl_stream_push_token(s, tok);
1286                 return NULL;
1287         }
1288         n = isl_int_get_si(tok->u.v);
1289         isl_token_free(tok);
1290
1291         isl_assert(s->ctx, n >= 1, return NULL);
1292
1293         map = isl_map_from_basic_map(basic_map_read_polylib(s, nparam));
1294
1295         for (i = 1; map && i < n; ++i)
1296                 map = isl_map_union(map,
1297                         isl_map_from_basic_map(basic_map_read_polylib(s, nparam)));
1298
1299         return map;
1300 }
1301
1302 static int optional_power(struct isl_stream *s)
1303 {
1304         int pow;
1305         struct isl_token *tok;
1306
1307         tok = isl_stream_next_token(s);
1308         if (!tok)
1309                 return 1;
1310         if (tok->type != '^') {
1311                 isl_stream_push_token(s, tok);
1312                 return 1;
1313         }
1314         isl_token_free(tok);
1315         tok = isl_stream_next_token(s);
1316         if (!tok || tok->type != ISL_TOKEN_VALUE) {
1317                 isl_stream_error(s, tok, "expecting exponent");
1318                 if (tok)
1319                         isl_stream_push_token(s, tok);
1320                 return 1;
1321         }
1322         pow = isl_int_get_si(tok->u.v);
1323         isl_token_free(tok);
1324         return pow;
1325 }
1326
1327 static __isl_give isl_div *read_div(struct isl_stream *s,
1328         __isl_take isl_dim *dim, struct vars *v)
1329 {
1330         int n;
1331         isl_basic_map *bmap;
1332
1333         n = v->n;
1334         bmap = isl_basic_map_universe(dim);
1335
1336         if (vars_add_anon(v) < 0)
1337                 goto error;
1338         if (read_div_definition(s, v) < 0)
1339                 goto error;
1340         bmap = add_divs(bmap, v);
1341         bmap = isl_basic_map_order_divs(bmap);
1342         if (!bmap)
1343                 goto error;
1344         vars_drop(v, v->n - n);
1345
1346         return isl_basic_map_div(bmap, bmap->n_div - 1);
1347 error:
1348         isl_basic_map_free(bmap);
1349         return NULL;
1350 }
1351
1352 static __isl_give isl_qpolynomial *read_term(struct isl_stream *s,
1353         __isl_keep isl_basic_map *bmap, struct vars *v);
1354
1355 static __isl_give isl_qpolynomial *read_factor(struct isl_stream *s,
1356         __isl_keep isl_basic_map *bmap, struct vars *v)
1357 {
1358         struct isl_qpolynomial *qp;
1359         struct isl_token *tok;
1360
1361         tok = isl_stream_next_token(s);
1362         if (!tok) {
1363                 isl_stream_error(s, NULL, "unexpected EOF");
1364                 return NULL;
1365         }
1366         if (tok->type == '(') {
1367                 int pow;
1368
1369                 isl_token_free(tok);
1370                 qp = read_term(s, bmap, v);
1371                 if (!qp)
1372                         return NULL;
1373                 if (isl_stream_eat(s, ')'))
1374                         goto error;
1375                 pow = optional_power(s);
1376                 qp = isl_qpolynomial_pow(qp, pow);
1377         } else if (tok->type == ISL_TOKEN_VALUE) {
1378                 struct isl_token *tok2;
1379                 tok2 = isl_stream_next_token(s);
1380                 if (tok2 && tok2->type == '/') {
1381                         isl_token_free(tok2);
1382                         tok2 = isl_stream_next_token(s);
1383                         if (!tok2 || tok2->type != ISL_TOKEN_VALUE) {
1384                                 isl_stream_error(s, tok2, "expected denominator");
1385                                 isl_token_free(tok);
1386                                 isl_token_free(tok2);
1387                                 return NULL;
1388                         }
1389                         qp = isl_qpolynomial_rat_cst(isl_basic_map_get_dim(bmap),
1390                                                     tok->u.v, tok2->u.v);
1391                         isl_token_free(tok2);
1392                 } else {
1393                         isl_stream_push_token(s, tok2);
1394                         qp = isl_qpolynomial_cst(isl_basic_map_get_dim(bmap),
1395                                                 tok->u.v);
1396                 }
1397                 isl_token_free(tok);
1398         } else if (tok->type == ISL_TOKEN_INFTY) {
1399                 isl_token_free(tok);
1400                 qp = isl_qpolynomial_infty(isl_basic_map_get_dim(bmap));
1401         } else if (tok->type == ISL_TOKEN_NAN) {
1402                 isl_token_free(tok);
1403                 qp = isl_qpolynomial_nan(isl_basic_map_get_dim(bmap));
1404         } else if (tok->type == ISL_TOKEN_IDENT) {
1405                 int n = v->n;
1406                 int pos = vars_pos(v, tok->u.s, -1);
1407                 int pow;
1408                 if (pos < 0) {
1409                         isl_token_free(tok);
1410                         return NULL;
1411                 }
1412                 if (pos >= n) {
1413                         vars_drop(v, v->n - n);
1414                         isl_stream_error(s, tok, "unknown identifier");
1415                         isl_token_free(tok);
1416                         return NULL;
1417                 }
1418                 isl_token_free(tok);
1419                 pow = optional_power(s);
1420                 qp = isl_qpolynomial_var_pow(isl_basic_map_get_dim(bmap), pos, pow);
1421         } else if (tok->type == '[') {
1422                 isl_div *div;
1423                 int pow;
1424
1425                 isl_stream_push_token(s, tok);
1426                 div = read_div(s, isl_basic_map_get_dim(bmap), v);
1427                 pow = optional_power(s);
1428                 qp = isl_qpolynomial_div_pow(div, pow);
1429         } else if (tok->type == '-') {
1430                 struct isl_qpolynomial *qp2;
1431
1432                 isl_token_free(tok);
1433                 qp = isl_qpolynomial_cst(isl_basic_map_get_dim(bmap),
1434                                             s->ctx->negone);
1435                 qp2 = read_factor(s, bmap, v);
1436                 qp = isl_qpolynomial_mul(qp, qp2);
1437         } else {
1438                 isl_stream_error(s, tok, "unexpected isl_token");
1439                 isl_stream_push_token(s, tok);
1440                 return NULL;
1441         }
1442
1443         if (isl_stream_eat_if_available(s, '*') ||
1444             isl_stream_next_token_is(s, ISL_TOKEN_IDENT)) {
1445                 struct isl_qpolynomial *qp2;
1446
1447                 qp2 = read_factor(s, bmap, v);
1448                 qp = isl_qpolynomial_mul(qp, qp2);
1449         }
1450
1451         return qp;
1452 error:
1453         isl_qpolynomial_free(qp);
1454         return NULL;
1455 }
1456
1457 static __isl_give isl_qpolynomial *read_term(struct isl_stream *s,
1458         __isl_keep isl_basic_map *bmap, struct vars *v)
1459 {
1460         struct isl_token *tok;
1461         struct isl_qpolynomial *qp;
1462
1463         qp = read_factor(s, bmap, v);
1464
1465         for (;;) {
1466                 tok = isl_stream_next_token(s);
1467                 if (!tok)
1468                         return qp;
1469
1470                 if (tok->type == '+') {
1471                         struct isl_qpolynomial *qp2;
1472
1473                         isl_token_free(tok);
1474                         qp2 = read_factor(s, bmap, v);
1475                         qp = isl_qpolynomial_add(qp, qp2);
1476                 } else if (tok->type == '-') {
1477                         struct isl_qpolynomial *qp2;
1478
1479                         isl_token_free(tok);
1480                         qp2 = read_factor(s, bmap, v);
1481                         qp = isl_qpolynomial_sub(qp, qp2);
1482                 } else if (tok->type == ISL_TOKEN_VALUE &&
1483                             isl_int_is_neg(tok->u.v)) {
1484                         struct isl_qpolynomial *qp2;
1485
1486                         isl_stream_push_token(s, tok);
1487                         qp2 = read_factor(s, bmap, v);
1488                         qp = isl_qpolynomial_add(qp, qp2);
1489                 } else {
1490                         isl_stream_push_token(s, tok);
1491                         break;
1492                 }
1493         }
1494
1495         return qp;
1496 }
1497
1498 static __isl_give isl_map *read_optional_disjuncts(struct isl_stream *s,
1499         __isl_take isl_basic_map *bmap, struct vars *v)
1500 {
1501         struct isl_token *tok;
1502         struct isl_map *map;
1503
1504         tok = isl_stream_next_token(s);
1505         if (!tok) {
1506                 isl_stream_error(s, NULL, "unexpected EOF");
1507                 goto error;
1508         }
1509         map = isl_map_from_basic_map(isl_basic_map_copy(bmap));
1510         if (tok->type == ':' ||
1511             (tok->type == ISL_TOKEN_OR && !strcmp(tok->u.s, "|"))) {
1512                 isl_token_free(tok);
1513                 map = isl_map_intersect(map,
1514                             read_disjuncts(s, v, isl_basic_map_copy(bmap)));
1515         } else
1516                 isl_stream_push_token(s, tok);
1517
1518         isl_basic_map_free(bmap);
1519
1520         return map;
1521 error:
1522         isl_basic_map_free(bmap);
1523         return NULL;
1524 }
1525
1526 static struct isl_obj obj_read_poly(struct isl_stream *s,
1527         __isl_take isl_basic_map *bmap, struct vars *v, int n)
1528 {
1529         struct isl_obj obj = { isl_obj_pw_qpolynomial, NULL };
1530         struct isl_pw_qpolynomial *pwqp;
1531         struct isl_qpolynomial *qp;
1532         struct isl_map *map;
1533         struct isl_set *set;
1534
1535         qp = read_term(s, bmap, v);
1536         map = read_optional_disjuncts(s, bmap, v);
1537         set = isl_map_range(map);
1538
1539         pwqp = isl_pw_qpolynomial_alloc(set, qp);
1540
1541         vars_drop(v, v->n - n);
1542
1543         obj.v = pwqp;
1544         return obj;
1545 }
1546
1547 static struct isl_obj obj_read_poly_or_fold(struct isl_stream *s,
1548         __isl_take isl_basic_map *bmap, struct vars *v, int n)
1549 {
1550         struct isl_obj obj = { isl_obj_pw_qpolynomial_fold, NULL };
1551         struct isl_obj obj_p;
1552         isl_qpolynomial *qp;
1553         isl_qpolynomial_fold *fold = NULL;
1554         isl_pw_qpolynomial_fold *pwf;
1555         isl_map *map;
1556         isl_set *set;
1557
1558         if (!isl_stream_eat_if_available(s, ISL_TOKEN_MAX))
1559                 return obj_read_poly(s, bmap, v, n);
1560
1561         if (isl_stream_eat(s, '('))
1562                 goto error;
1563
1564         qp = read_term(s, bmap, v);
1565         fold = isl_qpolynomial_fold_alloc(isl_fold_max, qp);
1566
1567         while (isl_stream_eat_if_available(s, ',')) {
1568                 isl_qpolynomial_fold *fold_i;
1569                 qp = read_term(s, bmap, v);
1570                 fold_i = isl_qpolynomial_fold_alloc(isl_fold_max, qp);
1571                 fold = isl_qpolynomial_fold_fold(fold, fold_i);
1572         }
1573
1574         if (isl_stream_eat(s, ')'))
1575                 goto error;
1576
1577         map = read_optional_disjuncts(s, bmap, v);
1578         set = isl_map_range(map);
1579         pwf = isl_pw_qpolynomial_fold_alloc(isl_fold_max, set, fold);
1580
1581         vars_drop(v, v->n - n);
1582
1583         obj.v = pwf;
1584         return obj;
1585 error:
1586         isl_basic_map_free(bmap);
1587         isl_qpolynomial_fold_free(fold);
1588         obj.type = isl_obj_none;
1589         return obj;
1590 }
1591
1592 static int is_rational(struct isl_stream *s)
1593 {
1594         struct isl_token *tok;
1595
1596         tok = isl_stream_next_token(s);
1597         if (!tok)
1598                 return 0;
1599         if (tok->type == ISL_TOKEN_RAT && isl_stream_next_token_is(s, ':')) {
1600                 isl_token_free(tok);
1601                 isl_stream_eat(s, ':');
1602                 return 1;
1603         }
1604
1605         isl_stream_push_token(s, tok);
1606
1607         return 0;
1608 }
1609
1610 static struct isl_obj obj_read_body(struct isl_stream *s,
1611         __isl_take isl_basic_map *bmap, struct vars *v)
1612 {
1613         struct isl_map *map = NULL;
1614         struct isl_token *tok;
1615         struct isl_obj obj = { isl_obj_set, NULL };
1616         int n = v->n;
1617
1618         if (is_rational(s))
1619                 bmap = isl_basic_map_set_rational(bmap);
1620
1621         if (!next_is_tuple(s))
1622                 return obj_read_poly_or_fold(s, bmap, v, n);
1623
1624         bmap = read_tuple(s, bmap, isl_dim_in, v);
1625         if (!bmap)
1626                 goto error;
1627         tok = isl_stream_next_token(s);
1628         if (tok && tok->type == ISL_TOKEN_TO) {
1629                 obj.type = isl_obj_map;
1630                 isl_token_free(tok);
1631                 if (!next_is_tuple(s)) {
1632                         bmap = isl_basic_map_reverse(bmap);
1633                         return obj_read_poly_or_fold(s, bmap, v, n);
1634                 }
1635                 bmap = read_tuple(s, bmap, isl_dim_out, v);
1636                 if (!bmap)
1637                         goto error;
1638         } else {
1639                 bmap = isl_basic_map_reverse(bmap);
1640                 if (tok)
1641                         isl_stream_push_token(s, tok);
1642         }
1643
1644         map = read_optional_disjuncts(s, bmap, v);
1645
1646         vars_drop(v, v->n - n);
1647
1648         obj.v = map;
1649         return obj;
1650 error:
1651         isl_basic_map_free(bmap);
1652         obj.type = isl_obj_none;
1653         return obj;
1654 }
1655
1656 static struct isl_obj to_union(isl_ctx *ctx, struct isl_obj obj)
1657 {
1658         if (obj.type == isl_obj_map) {
1659                 obj.v = isl_union_map_from_map(obj.v);
1660                 obj.type = isl_obj_union_map;
1661         } else if (obj.type == isl_obj_set) {
1662                 obj.v = isl_union_set_from_set(obj.v);
1663                 obj.type = isl_obj_union_set;
1664         } else if (obj.type == isl_obj_pw_qpolynomial) {
1665                 obj.v = isl_union_pw_qpolynomial_from_pw_qpolynomial(obj.v);
1666                 obj.type = isl_obj_union_pw_qpolynomial;
1667         } else if (obj.type == isl_obj_pw_qpolynomial_fold) {
1668                 obj.v = isl_union_pw_qpolynomial_fold_from_pw_qpolynomial_fold(obj.v);
1669                 obj.type = isl_obj_union_pw_qpolynomial_fold;
1670         } else
1671                 isl_assert(ctx, 0, goto error);
1672         return obj;
1673 error:
1674         obj.type->free(obj.v);
1675         obj.type = isl_obj_none;
1676         return obj;
1677 }
1678
1679 static struct isl_obj obj_add(struct isl_ctx *ctx,
1680         struct isl_obj obj1, struct isl_obj obj2)
1681 {
1682         if (obj1.type == isl_obj_set && obj2.type == isl_obj_union_set)
1683                 obj1 = to_union(ctx, obj1);
1684         if (obj1.type == isl_obj_union_set && obj2.type == isl_obj_set)
1685                 obj2 = to_union(ctx, obj2);
1686         if (obj1.type == isl_obj_map && obj2.type == isl_obj_union_map)
1687                 obj1 = to_union(ctx, obj1);
1688         if (obj1.type == isl_obj_union_map && obj2.type == isl_obj_map)
1689                 obj2 = to_union(ctx, obj2);
1690         if (obj1.type == isl_obj_pw_qpolynomial &&
1691             obj2.type == isl_obj_union_pw_qpolynomial)
1692                 obj1 = to_union(ctx, obj1);
1693         if (obj1.type == isl_obj_union_pw_qpolynomial &&
1694             obj2.type == isl_obj_pw_qpolynomial)
1695                 obj2 = to_union(ctx, obj2);
1696         if (obj1.type == isl_obj_pw_qpolynomial_fold &&
1697             obj2.type == isl_obj_union_pw_qpolynomial_fold)
1698                 obj1 = to_union(ctx, obj1);
1699         if (obj1.type == isl_obj_union_pw_qpolynomial_fold &&
1700             obj2.type == isl_obj_pw_qpolynomial_fold)
1701                 obj2 = to_union(ctx, obj2);
1702         isl_assert(ctx, obj1.type == obj2.type, goto error);
1703         if (obj1.type == isl_obj_map && !isl_map_has_equal_dim(obj1.v, obj2.v)) {
1704                 obj1 = to_union(ctx, obj1);
1705                 obj2 = to_union(ctx, obj2);
1706         }
1707         if (obj1.type == isl_obj_set && !isl_set_has_equal_dim(obj1.v, obj2.v)) {
1708                 obj1 = to_union(ctx, obj1);
1709                 obj2 = to_union(ctx, obj2);
1710         }
1711         if (obj1.type == isl_obj_pw_qpolynomial &&
1712             !isl_pw_qpolynomial_has_equal_dim(obj1.v, obj2.v)) {
1713                 obj1 = to_union(ctx, obj1);
1714                 obj2 = to_union(ctx, obj2);
1715         }
1716         if (obj1.type == isl_obj_pw_qpolynomial_fold &&
1717             !isl_pw_qpolynomial_fold_has_equal_dim(obj1.v, obj2.v)) {
1718                 obj1 = to_union(ctx, obj1);
1719                 obj2 = to_union(ctx, obj2);
1720         }
1721         obj1.v = obj1.type->add(obj1.v, obj2.v);
1722         return obj1;
1723 error:
1724         obj1.type->free(obj1.v);
1725         obj2.type->free(obj2.v);
1726         obj1.type = isl_obj_none;
1727         obj1.v = NULL;
1728         return obj1;
1729 }
1730
1731 static struct isl_obj obj_read(struct isl_stream *s, int nparam)
1732 {
1733         isl_basic_map *bmap = NULL;
1734         struct isl_token *tok;
1735         struct vars *v = NULL;
1736         struct isl_obj obj = { isl_obj_set, NULL };
1737
1738         tok = isl_stream_next_token(s);
1739         if (!tok) {
1740                 isl_stream_error(s, NULL, "unexpected EOF");
1741                 goto error;
1742         }
1743         if (tok->type == ISL_TOKEN_VALUE) {
1744                 struct isl_token *tok2;
1745                 struct isl_map *map;
1746
1747                 tok2 = isl_stream_next_token(s);
1748                 if (!tok2 || tok2->type != ISL_TOKEN_VALUE ||
1749                     isl_int_is_neg(tok2->u.v)) {
1750                         if (tok2)
1751                                 isl_stream_push_token(s, tok2);
1752                         obj.type = isl_obj_int;
1753                         obj.v = isl_int_obj_alloc(s->ctx, tok->u.v);
1754                         isl_token_free(tok);
1755                         return obj;
1756                 }
1757                 isl_stream_push_token(s, tok2);
1758                 isl_stream_push_token(s, tok);
1759                 map = map_read_polylib(s, nparam);
1760                 if (!map)
1761                         goto error;
1762                 if (isl_map_dim(map, isl_dim_in) > 0)
1763                         obj.type = isl_obj_map;
1764                 obj.v = map;
1765                 return obj;
1766         }
1767         v = vars_new(s->ctx);
1768         if (!v) {
1769                 isl_stream_push_token(s, tok);
1770                 goto error;
1771         }
1772         bmap = isl_basic_map_alloc(s->ctx, 0, 0, 0, 0, 0, 0);
1773         if (tok->type == '[') {
1774                 isl_stream_push_token(s, tok);
1775                 bmap = read_tuple(s, bmap, isl_dim_param, v);
1776                 if (!bmap)
1777                         goto error;
1778                 if (nparam >= 0)
1779                         isl_assert(s->ctx, nparam == v->n, goto error);
1780                 tok = isl_stream_next_token(s);
1781                 if (!tok || tok->type != ISL_TOKEN_TO) {
1782                         isl_stream_error(s, tok, "expecting '->'");
1783                         if (tok)
1784                                 isl_stream_push_token(s, tok);
1785                         goto error;
1786                 }
1787                 isl_token_free(tok);
1788                 tok = isl_stream_next_token(s);
1789         } else if (nparam > 0)
1790                 bmap = isl_basic_map_add(bmap, isl_dim_param, nparam);
1791         if (!tok || tok->type != '{') {
1792                 isl_stream_error(s, tok, "expecting '{'");
1793                 if (tok)
1794                         isl_stream_push_token(s, tok);
1795                 goto error;
1796         }
1797         isl_token_free(tok);
1798
1799         tok = isl_stream_next_token(s);
1800         if (!tok)
1801                 ;
1802         else if (tok->type == ISL_TOKEN_IDENT && !strcmp(tok->u.s, "Sym")) {
1803                 isl_token_free(tok);
1804                 if (isl_stream_eat(s, '='))
1805                         goto error;
1806                 bmap = read_tuple(s, bmap, isl_dim_param, v);
1807                 if (!bmap)
1808                         goto error;
1809                 if (nparam >= 0)
1810                         isl_assert(s->ctx, nparam == v->n, goto error);
1811         } else if (tok->type == '}') {
1812                 obj.type = isl_obj_union_set;
1813                 obj.v = isl_union_set_empty(isl_basic_map_get_dim(bmap));
1814                 isl_token_free(tok);
1815                 goto done;
1816         } else
1817                 isl_stream_push_token(s, tok);
1818
1819         for (;;) {
1820                 struct isl_obj o;
1821                 tok = NULL;
1822                 o = obj_read_body(s, isl_basic_map_copy(bmap), v);
1823                 if (o.type == isl_obj_none || !o.v)
1824                         goto error;
1825                 if (!obj.v)
1826                         obj = o;
1827                 else {
1828                         obj = obj_add(s->ctx, obj, o);
1829                         if (obj.type == isl_obj_none || !obj.v)
1830                                 goto error;
1831                 }
1832                 tok = isl_stream_next_token(s);
1833                 if (!tok || tok->type != ';')
1834                         break;
1835                 isl_token_free(tok);
1836         }
1837
1838         if (tok && tok->type == '}') {
1839                 isl_token_free(tok);
1840         } else {
1841                 isl_stream_error(s, tok, "unexpected isl_token");
1842                 if (tok)
1843                         isl_token_free(tok);
1844                 goto error;
1845         }
1846 done:
1847         vars_free(v);
1848         isl_basic_map_free(bmap);
1849
1850         return obj;
1851 error:
1852         isl_basic_map_free(bmap);
1853         obj.type->free(obj.v);
1854         if (v)
1855                 vars_free(v);
1856         obj.v = NULL;
1857         return obj;
1858 }
1859
1860 struct isl_obj isl_stream_read_obj(struct isl_stream *s)
1861 {
1862         return obj_read(s, -1);
1863 }
1864
1865 __isl_give isl_map *isl_stream_read_map(struct isl_stream *s, int nparam)
1866 {
1867         struct isl_obj obj;
1868         struct isl_map *map;
1869
1870         obj = obj_read(s, nparam);
1871         if (obj.v)
1872                 isl_assert(s->ctx, obj.type == isl_obj_map ||
1873                                    obj.type == isl_obj_set, goto error);
1874
1875         return obj.v;
1876 error:
1877         obj.type->free(obj.v);
1878         return NULL;
1879 }
1880
1881 __isl_give isl_set *isl_stream_read_set(struct isl_stream *s, int nparam)
1882 {
1883         struct isl_obj obj;
1884         struct isl_set *set;
1885
1886         obj = obj_read(s, nparam);
1887         if (obj.v)
1888                 isl_assert(s->ctx, obj.type == isl_obj_set, goto error);
1889
1890         return obj.v;
1891 error:
1892         obj.type->free(obj.v);
1893         return NULL;
1894 }
1895
1896 __isl_give isl_union_map *isl_stream_read_union_map(struct isl_stream *s)
1897 {
1898         struct isl_obj obj;
1899         isl_union_map *umap;
1900
1901         obj = obj_read(s, -1);
1902         if (obj.type == isl_obj_map) {
1903                 obj.type = isl_obj_union_map;
1904                 obj.v = isl_union_map_from_map(obj.v);
1905         }
1906         if (obj.type == isl_obj_set) {
1907                 obj.type = isl_obj_union_set;
1908                 obj.v = isl_union_set_from_set(obj.v);
1909         }
1910         if (obj.v)
1911                 isl_assert(s->ctx, obj.type == isl_obj_union_map ||
1912                                    obj.type == isl_obj_union_set, goto error);
1913
1914         return obj.v;
1915 error:
1916         obj.type->free(obj.v);
1917         return NULL;
1918 }
1919
1920 __isl_give isl_union_set *isl_stream_read_union_set(struct isl_stream *s)
1921 {
1922         struct isl_obj obj;
1923         isl_union_set *uset;
1924
1925         obj = obj_read(s, -1);
1926         if (obj.type == isl_obj_set) {
1927                 obj.type = isl_obj_union_set;
1928                 obj.v = isl_union_set_from_set(obj.v);
1929         }
1930         if (obj.v)
1931                 isl_assert(s->ctx, obj.type == isl_obj_union_set, goto error);
1932
1933         return obj.v;
1934 error:
1935         obj.type->free(obj.v);
1936         return NULL;
1937 }
1938
1939 static struct isl_basic_map *basic_map_read(struct isl_stream *s, int nparam)
1940 {
1941         struct isl_obj obj;
1942         struct isl_map *map;
1943         struct isl_basic_map *bmap;
1944
1945         obj = obj_read(s, nparam);
1946         map = obj.v;
1947         if (!map)
1948                 return NULL;
1949
1950         isl_assert(map->ctx, map->n <= 1, goto error);
1951
1952         if (map->n == 0)
1953                 bmap = isl_basic_map_empty_like_map(map);
1954         else
1955                 bmap = isl_basic_map_copy(map->p[0]);
1956
1957         isl_map_free(map);
1958
1959         return bmap;
1960 error:
1961         isl_map_free(map);
1962         return NULL;
1963 }
1964
1965 __isl_give isl_basic_map *isl_basic_map_read_from_file(isl_ctx *ctx,
1966                 FILE *input, int nparam)
1967 {
1968         struct isl_basic_map *bmap;
1969         struct isl_stream *s = isl_stream_new_file(ctx, input);
1970         if (!s)
1971                 return NULL;
1972         bmap = basic_map_read(s, nparam);
1973         isl_stream_free(s);
1974         return bmap;
1975 }
1976
1977 __isl_give isl_basic_set *isl_basic_set_read_from_file(isl_ctx *ctx,
1978                 FILE *input, int nparam)
1979 {
1980         struct isl_basic_map *bmap;
1981         bmap = isl_basic_map_read_from_file(ctx, input, nparam);
1982         if (!bmap)
1983                 return NULL;
1984         isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
1985         return (struct isl_basic_set *)bmap;
1986 error:
1987         isl_basic_map_free(bmap);
1988         return NULL;
1989 }
1990
1991 struct isl_basic_map *isl_basic_map_read_from_str(struct isl_ctx *ctx,
1992                 const char *str, int nparam)
1993 {
1994         struct isl_basic_map *bmap;
1995         struct isl_stream *s = isl_stream_new_str(ctx, str);
1996         if (!s)
1997                 return NULL;
1998         bmap = basic_map_read(s, nparam);
1999         isl_stream_free(s);
2000         return bmap;
2001 }
2002
2003 struct isl_basic_set *isl_basic_set_read_from_str(struct isl_ctx *ctx,
2004                 const char *str, int nparam)
2005 {
2006         struct isl_basic_map *bmap;
2007         bmap = isl_basic_map_read_from_str(ctx, str, nparam);
2008         if (!bmap)
2009                 return NULL;
2010         isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
2011         return (struct isl_basic_set *)bmap;
2012 error:
2013         isl_basic_map_free(bmap);
2014         return NULL;
2015 }
2016
2017 __isl_give isl_map *isl_map_read_from_file(struct isl_ctx *ctx,
2018                 FILE *input, int nparam)
2019 {
2020         struct isl_map *map;
2021         struct isl_stream *s = isl_stream_new_file(ctx, input);
2022         if (!s)
2023                 return NULL;
2024         map = isl_stream_read_map(s, nparam);
2025         isl_stream_free(s);
2026         return map;
2027 }
2028
2029 __isl_give isl_map *isl_map_read_from_str(struct isl_ctx *ctx,
2030                 const char *str, int nparam)
2031 {
2032         struct isl_map *map;
2033         struct isl_stream *s = isl_stream_new_str(ctx, str);
2034         if (!s)
2035                 return NULL;
2036         map = isl_stream_read_map(s, nparam);
2037         isl_stream_free(s);
2038         return map;
2039 }
2040
2041 __isl_give isl_set *isl_set_read_from_file(struct isl_ctx *ctx,
2042                 FILE *input, int nparam)
2043 {
2044         struct isl_map *map;
2045         map = isl_map_read_from_file(ctx, input, nparam);
2046         if (!map)
2047                 return NULL;
2048         isl_assert(ctx, isl_map_n_in(map) == 0, goto error);
2049         return (struct isl_set *)map;
2050 error:
2051         isl_map_free(map);
2052         return NULL;
2053 }
2054
2055 struct isl_set *isl_set_read_from_str(struct isl_ctx *ctx,
2056                 const char *str, int nparam)
2057 {
2058         struct isl_map *map;
2059         map = isl_map_read_from_str(ctx, str, nparam);
2060         if (!map)
2061                 return NULL;
2062         isl_assert(ctx, isl_map_n_in(map) == 0, goto error);
2063         return (struct isl_set *)map;
2064 error:
2065         isl_map_free(map);
2066         return NULL;
2067 }
2068
2069 __isl_give isl_union_map *isl_union_map_read_from_str(struct isl_ctx *ctx,
2070                 const char *str)
2071 {
2072         isl_union_map *umap;
2073         struct isl_stream *s = isl_stream_new_str(ctx, str);
2074         if (!s)
2075                 return NULL;
2076         umap = isl_stream_read_union_map(s);
2077         isl_stream_free(s);
2078         return umap;
2079 }
2080
2081 __isl_give isl_union_set *isl_union_set_read_from_str(struct isl_ctx *ctx,
2082                 const char *str)
2083 {
2084         isl_union_set *uset;
2085         struct isl_stream *s = isl_stream_new_str(ctx, str);
2086         if (!s)
2087                 return NULL;
2088         uset = isl_stream_read_union_set(s);
2089         isl_stream_free(s);
2090         return uset;
2091 }
2092
2093 static __isl_give isl_vec *isl_vec_read_polylib(struct isl_stream *s)
2094 {
2095         struct isl_vec *vec = NULL;
2096         struct isl_token *tok;
2097         unsigned size;
2098         int j;
2099
2100         tok = isl_stream_next_token(s);
2101         if (!tok || tok->type != ISL_TOKEN_VALUE) {
2102                 isl_stream_error(s, tok, "expecting vector length");
2103                 goto error;
2104         }
2105
2106         size = isl_int_get_si(tok->u.v);
2107         isl_token_free(tok);
2108
2109         vec = isl_vec_alloc(s->ctx, size);
2110
2111         for (j = 0; j < size; ++j) {
2112                 tok = isl_stream_next_token(s);
2113                 if (!tok || tok->type != ISL_TOKEN_VALUE) {
2114                         isl_stream_error(s, tok, "expecting constant value");
2115                         goto error;
2116                 }
2117                 isl_int_set(vec->el[j], tok->u.v);
2118                 isl_token_free(tok);
2119         }
2120
2121         return vec;
2122 error:
2123         isl_token_free(tok);
2124         isl_vec_free(vec);
2125         return NULL;
2126 }
2127
2128 static __isl_give isl_vec *vec_read(struct isl_stream *s,
2129         unsigned input_format)
2130 {
2131         if (input_format == ISL_FORMAT_POLYLIB)
2132                 return isl_vec_read_polylib(s);
2133         isl_assert(s->ctx, 0, return NULL);
2134 }
2135
2136 struct isl_vec *isl_vec_read_from_file(struct isl_ctx *ctx,
2137                 FILE *input, unsigned input_format)
2138 {
2139         isl_vec *v;
2140         struct isl_stream *s = isl_stream_new_file(ctx, input);
2141         if (!s)
2142                 return NULL;
2143         v = vec_read(s, input_format);
2144         isl_stream_free(s);
2145         return v;
2146 }
2147
2148 __isl_give isl_pw_qpolynomial *isl_stream_read_pw_qpolynomial(
2149         struct isl_stream *s)
2150 {
2151         struct isl_obj obj;
2152         struct isl_pw_qpolynomial *pwqp;
2153
2154         obj = obj_read(s, -1);
2155         if (obj.v)
2156                 isl_assert(s->ctx, obj.type == isl_obj_pw_qpolynomial,
2157                            goto error);
2158
2159         return obj.v;
2160 error:
2161         obj.type->free(obj.v);
2162         return NULL;
2163 }
2164
2165 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_read_from_str(isl_ctx *ctx,
2166                 const char *str)
2167 {
2168         isl_pw_qpolynomial *pwqp;
2169         struct isl_stream *s = isl_stream_new_str(ctx, str);
2170         if (!s)
2171                 return NULL;
2172         pwqp = isl_stream_read_pw_qpolynomial(s);
2173         isl_stream_free(s);
2174         return pwqp;
2175 }