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