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