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