~ubuntu-branches/ubuntu/trusty/cloog/trusty

« back to all changes in this revision

Viewing changes to isl/isl_input.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2011-12-15 18:39:17 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20111215183917-uqggmujou8wna9js
Tags: 0.17.0-1
New upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
#include <isl_map_private.h>
18
18
#include <isl/set.h>
19
19
#include <isl/seq.h>
20
 
#include <isl/div.h>
21
 
#include <isl/stream.h>
 
20
#include <isl_stream_private.h>
22
21
#include <isl/obj.h>
23
22
#include "isl_polynomial_private.h"
24
23
#include <isl/union_map.h>
25
24
#include <isl_mat_private.h>
 
25
#include <isl_aff_private.h>
 
26
#include <isl/list.h>
26
27
 
27
28
struct variable {
28
29
        char                    *name;
29
30
        int                      pos;
30
 
        isl_vec                 *def;
31
 
        /* non-zero if variable represents a min (-1) or a max (1) */
32
 
        int                      sign;
33
 
        isl_mat                 *list;
34
31
        struct variable         *next;
35
32
};
36
33
 
56
53
{
57
54
        while (var) {
58
55
                struct variable *next = var->next;
59
 
                isl_mat_free(var->list);
60
 
                isl_vec_free(var->def);
61
56
                free(var->name);
62
57
                free(var);
63
58
                var = next;
84
79
        var = v->v;
85
80
        while (--n >= 0) {
86
81
                struct variable *next = var->next;
87
 
                isl_mat_free(var->list);
88
 
                isl_vec_free(var->def);
89
82
                free(var->name);
90
83
                free(var);
91
84
                var = next;
103
96
        var->name = strdup(name);
104
97
        var->name[len] = '\0';
105
98
        var->pos = pos;
106
 
        var->def = NULL;
107
99
        var->next = v->v;
108
100
        return var;
109
101
error:
145
137
        return 0;
146
138
}
147
139
 
148
 
static __isl_give isl_basic_map *set_name(__isl_take isl_basic_map *bmap,
 
140
static __isl_give isl_map *set_name(__isl_take isl_map *map,
149
141
        enum isl_dim_type type, unsigned pos, char *name)
150
142
{
151
143
        char *prime;
152
144
 
153
 
        if (!bmap)
 
145
        if (!map)
154
146
                return NULL;
155
147
        if (!name)
156
 
                return bmap;
 
148
                return map;
157
149
 
158
150
        prime = strchr(name, '\'');
159
151
        if (prime)
160
152
                *prime = '\0';
161
 
        bmap = isl_basic_map_set_dim_name(bmap, type, pos, name);
 
153
        map = isl_map_set_dim_name(map, type, pos, name);
162
154
        if (prime)
163
155
                *prime = '\'';
164
156
 
165
 
        return bmap;
 
157
        return map;
166
158
}
167
159
 
168
160
/* Obtain next token, with some preprocessing.
224
216
 * We introduce an integer division q = [aff/d] and the result
225
217
 * is set to aff - d q.
226
218
 */
227
 
static __isl_give isl_vec *affine_mod(struct isl_stream *s,
228
 
        struct vars *v, __isl_take isl_vec *aff)
 
219
static __isl_give isl_pw_aff *affine_mod(struct isl_stream *s,
 
220
        struct vars *v, __isl_take isl_pw_aff *aff)
229
221
{
230
222
        struct isl_token *tok;
231
 
        struct variable *var;
232
 
        isl_vec *mod;
 
223
        isl_pw_aff *q;
233
224
 
234
225
        tok = next_token(s);
235
226
        if (!tok || tok->type != ISL_TOKEN_VALUE) {
237
228
                goto error;
238
229
        }
239
230
 
240
 
        if (vars_add_anon(v) < 0)
241
 
                goto error;
242
 
 
243
 
        var = v->v;
244
 
 
245
 
        var->def = isl_vec_alloc(s->ctx, 2 + v->n);
246
 
        if (!var->def)
247
 
                goto error;
248
 
        isl_seq_cpy(var->def->el + 1, aff->el, aff->size);
249
 
        isl_int_set_si(var->def->el[1 + aff->size], 0);
250
 
        isl_int_set(var->def->el[0], tok->u.v);
251
 
 
252
 
        mod = isl_vec_alloc(v->ctx, 1 + v->n);
253
 
        if (!mod)
254
 
                goto error;
255
 
 
256
 
        isl_seq_cpy(mod->el, aff->el, aff->size);
257
 
        isl_int_neg(mod->el[aff->size], tok->u.v);
258
 
 
259
 
        isl_vec_free(aff);
260
 
        isl_token_free(tok);
261
 
        return mod;
262
 
error:
263
 
        isl_vec_free(aff);
264
 
        isl_token_free(tok);
265
 
        return NULL;
266
 
}
267
 
 
268
 
static struct isl_vec *accept_affine(struct isl_stream *s, struct vars *v);
269
 
static int read_div_definition(struct isl_stream *s, struct vars *v);
270
 
static int read_minmax_definition(struct isl_stream *s, struct vars *v);
271
 
 
272
 
static __isl_give isl_vec *accept_affine_factor(struct isl_stream *s,
273
 
        struct vars *v)
 
231
        q = isl_pw_aff_copy(aff);
 
232
        q = isl_pw_aff_scale_down(q, tok->u.v);
 
233
        q = isl_pw_aff_floor(q);
 
234
        q = isl_pw_aff_scale(q, tok->u.v);
 
235
 
 
236
        aff = isl_pw_aff_sub(aff, q);
 
237
 
 
238
        isl_token_free(tok);
 
239
        return aff;
 
240
error:
 
241
        isl_pw_aff_free(aff);
 
242
        isl_token_free(tok);
 
243
        return NULL;
 
244
}
 
245
 
 
246
static __isl_give isl_pw_aff *accept_affine(struct isl_stream *s,
 
247
        __isl_take isl_space *dim, struct vars *v);
 
248
static __isl_give isl_pw_aff_list *accept_affine_list(struct isl_stream *s,
 
249
        __isl_take isl_space *dim, struct vars *v);
 
250
 
 
251
static __isl_give isl_pw_aff *accept_minmax(struct isl_stream *s,
 
252
        __isl_take isl_space *dim, struct vars *v)
 
253
{
 
254
        struct isl_token *tok;
 
255
        isl_pw_aff_list *list = NULL;
 
256
        int min;
 
257
 
 
258
        tok = isl_stream_next_token(s);
 
259
        if (!tok)
 
260
                goto error;
 
261
        min = tok->type == ISL_TOKEN_MIN;
 
262
        isl_token_free(tok);
 
263
 
 
264
        if (isl_stream_eat(s, '('))
 
265
                goto error;
 
266
 
 
267
        list = accept_affine_list(s, isl_space_copy(dim), v);
 
268
        if (!list)
 
269
                goto error;
 
270
 
 
271
        if (isl_stream_eat(s, ')'))
 
272
                goto error;
 
273
 
 
274
        isl_space_free(dim);
 
275
        return min ? isl_pw_aff_list_min(list) : isl_pw_aff_list_max(list);
 
276
error:
 
277
        isl_space_free(dim);
 
278
        isl_pw_aff_list_free(list);
 
279
        return NULL;
 
280
}
 
281
 
 
282
static __isl_give isl_pw_aff *accept_div(struct isl_stream *s,
 
283
        __isl_take isl_space *dim, struct vars *v)
 
284
{
 
285
        struct isl_token *tok;
 
286
        int seen_paren = 0;
 
287
        int f = 0;
 
288
        int c = 0;
 
289
        isl_pw_aff *pwaff = NULL;
 
290
 
 
291
        if (isl_stream_eat_if_available(s, ISL_TOKEN_FLOORD))
 
292
                f = 1;
 
293
        else if (isl_stream_eat_if_available(s, ISL_TOKEN_CEILD))
 
294
                c = 1;
 
295
        if (f || c) {
 
296
                if (isl_stream_eat(s, '('))
 
297
                        goto error;
 
298
        } else {
 
299
                if (isl_stream_eat(s, '['))
 
300
                        goto error;
 
301
                if (isl_stream_eat_if_available(s, '('))
 
302
                        seen_paren = 1;
 
303
        }
 
304
 
 
305
        pwaff = accept_affine(s, isl_space_copy(dim), v);
 
306
 
 
307
        if (f || c) {
 
308
                if (isl_stream_eat(s, ','))
 
309
                        goto error;
 
310
        } else {
 
311
                if (seen_paren && isl_stream_eat(s, ')'))
 
312
                        goto error;
 
313
                if (isl_stream_eat(s, '/'))
 
314
                        goto error;
 
315
        }
 
316
 
 
317
        tok = next_token(s);
 
318
        if (!tok)
 
319
                goto error;
 
320
        if (tok->type != ISL_TOKEN_VALUE) {
 
321
                isl_stream_error(s, tok, "expected denominator");
 
322
                isl_stream_push_token(s, tok);
 
323
                goto error;
 
324
        }
 
325
        isl_pw_aff_scale_down(pwaff,  tok->u.v);
 
326
        isl_token_free(tok);
 
327
 
 
328
        if (c)
 
329
                pwaff = isl_pw_aff_ceil(pwaff);
 
330
        else
 
331
                pwaff = isl_pw_aff_floor(pwaff);
 
332
 
 
333
        if (f || c) {
 
334
                if (isl_stream_eat(s, ')'))
 
335
                        goto error;
 
336
        } else {
 
337
                if (isl_stream_eat(s, ']'))
 
338
                        goto error;
 
339
        }
 
340
 
 
341
        isl_space_free(dim);
 
342
        return pwaff;
 
343
error:
 
344
        isl_space_free(dim);
 
345
        isl_pw_aff_free(pwaff);
 
346
        return NULL;
 
347
}
 
348
 
 
349
static __isl_give isl_pw_aff *accept_affine_factor(struct isl_stream *s,
 
350
        __isl_take isl_space *dim, struct vars *v)
274
351
{
275
352
        struct isl_token *tok = NULL;
276
 
        isl_vec *aff = NULL;
 
353
        isl_pw_aff *res = NULL;
277
354
 
278
355
        tok = next_token(s);
279
356
        if (!tok) {
280
357
                isl_stream_error(s, NULL, "unexpected EOF");
281
358
                goto error;
282
359
        }
283
 
        if (tok->type == ISL_TOKEN_IDENT) {
 
360
 
 
361
        if (tok->type == ISL_TOKEN_AFF) {
 
362
                res = isl_pw_aff_copy(tok->u.pwaff);
 
363
                isl_token_free(tok);
 
364
        } else if (tok->type == ISL_TOKEN_IDENT) {
284
365
                int n = v->n;
285
366
                int pos = vars_pos(v, tok->u.s, -1);
 
367
                isl_aff *aff;
 
368
 
286
369
                if (pos < 0)
287
370
                        goto error;
288
371
                if (pos >= n) {
290
373
                        goto error;
291
374
                }
292
375
 
293
 
                aff = isl_vec_alloc(v->ctx, 1 + v->n);
 
376
                aff = isl_aff_zero_on_domain(isl_local_space_from_space(isl_space_copy(dim)));
294
377
                if (!aff)
295
378
                        goto error;
296
 
                isl_seq_clr(aff->el, aff->size);
297
 
                isl_int_set_si(aff->el[1 + pos], 1);
 
379
                isl_int_set_si(aff->v->el[2 + pos], 1);
 
380
                res = isl_pw_aff_from_aff(aff);
298
381
                isl_token_free(tok);
299
382
        } else if (tok->type == ISL_TOKEN_VALUE) {
300
383
                if (isl_stream_eat_if_available(s, '*')) {
301
 
                        aff = accept_affine_factor(s, v);
302
 
                        aff = isl_vec_scale(aff, tok->u.v);
 
384
                        res = accept_affine_factor(s, isl_space_copy(dim), v);
 
385
                        res = isl_pw_aff_scale(res, tok->u.v);
303
386
                } else {
304
 
                        aff = isl_vec_alloc(v->ctx, 1 + v->n);
305
 
                        if (!aff)
306
 
                                goto error;
307
 
                        isl_seq_clr(aff->el, aff->size);
308
 
                        isl_int_set(aff->el[0], tok->u.v);
 
387
                        isl_local_space *ls;
 
388
                        isl_aff *aff;
 
389
                        ls = isl_local_space_from_space(isl_space_copy(dim));
 
390
                        aff = isl_aff_zero_on_domain(ls);
 
391
                        aff = isl_aff_add_constant(aff, tok->u.v);
 
392
                        res = isl_pw_aff_from_aff(aff);
309
393
                }
310
394
                isl_token_free(tok);
311
395
        } else if (tok->type == '(') {
312
396
                isl_token_free(tok);
313
397
                tok = NULL;
314
 
                aff = accept_affine(s, v);
315
 
                if (!aff)
 
398
                res = accept_affine(s, isl_space_copy(dim), v);
 
399
                if (!res)
316
400
                        goto error;
317
401
                if (isl_stream_eat(s, ')'))
318
402
                        goto error;
319
403
        } else if (tok->type == '[' ||
320
404
                    tok->type == ISL_TOKEN_FLOORD ||
321
405
                    tok->type == ISL_TOKEN_CEILD) {
322
 
                int ceil = tok->type == ISL_TOKEN_CEILD;
323
 
                struct variable *var;
324
 
                if (vars_add_anon(v) < 0)
325
 
                        goto error;
326
 
                var = v->v;
327
 
                aff = isl_vec_alloc(v->ctx, 1 + v->n);
328
 
                if (!aff)
329
 
                        goto error;
330
 
                isl_seq_clr(aff->el, aff->size);
331
 
                isl_int_set_si(aff->el[1 + v->n - 1], ceil ? -1 : 1);
332
406
                isl_stream_push_token(s, tok);
333
407
                tok = NULL;
334
 
                if (read_div_definition(s, v) < 0)
335
 
                        goto error;
336
 
                if (ceil)
337
 
                        isl_seq_neg(var->def->el + 1, var->def->el + 1,
338
 
                                    var->def->size - 1);
339
 
                aff = isl_vec_zero_extend(aff, 1 + v->n);
 
408
                res = accept_div(s, isl_space_copy(dim), v);
340
409
        } else if (tok->type == ISL_TOKEN_MIN || tok->type == ISL_TOKEN_MAX) {
341
 
                if (vars_add_anon(v) < 0)
342
 
                        goto error;
343
 
                aff = isl_vec_alloc(v->ctx, 1 + v->n);
344
 
                if (!aff)
345
 
                        goto error;
346
 
                isl_seq_clr(aff->el, aff->size);
347
 
                isl_int_set_si(aff->el[1 + v->n - 1], 1);
348
410
                isl_stream_push_token(s, tok);
349
411
                tok = NULL;
350
 
                if (read_minmax_definition(s, v) < 0)
351
 
                        goto error;
352
 
                aff = isl_vec_zero_extend(aff, 1 + v->n);
 
412
                res = accept_minmax(s, isl_space_copy(dim), v);
353
413
        } else {
354
414
                isl_stream_error(s, tok, "expecting factor");
355
415
                goto error;
356
416
        }
357
 
        if (isl_stream_eat_if_available(s, '%'))
358
 
                return affine_mod(s, v, aff);
 
417
        if (isl_stream_eat_if_available(s, '%') ||
 
418
            isl_stream_eat_if_available(s, ISL_TOKEN_MOD)) {
 
419
                isl_space_free(dim);
 
420
                return affine_mod(s, v, res);
 
421
        }
359
422
        if (isl_stream_eat_if_available(s, '*')) {
360
423
                isl_int f;
361
424
                isl_int_init(f);
364
427
                        isl_int_clear(f);
365
428
                        goto error2;
366
429
                }
367
 
                aff = isl_vec_scale(aff, f);
 
430
                res = isl_pw_aff_scale(res, f);
368
431
                isl_int_clear(f);
369
432
        }
370
433
 
371
 
        return aff;
 
434
        isl_space_free(dim);
 
435
        return res;
372
436
error:
373
437
        isl_token_free(tok);
374
438
error2:
375
 
        isl_vec_free(aff);
 
439
        isl_pw_aff_free(res);
 
440
        isl_space_free(dim);
376
441
        return NULL;
377
442
}
378
443
 
379
 
static struct isl_vec *accept_affine(struct isl_stream *s, struct vars *v)
 
444
static __isl_give isl_pw_aff *add_cst(__isl_take isl_pw_aff *pwaff, isl_int v)
 
445
{
 
446
        isl_aff *aff;
 
447
        isl_space *space;
 
448
 
 
449
        space = isl_pw_aff_get_domain_space(pwaff);
 
450
        aff = isl_aff_zero_on_domain(isl_local_space_from_space(space));
 
451
        aff = isl_aff_add_constant(aff, v);
 
452
 
 
453
        return isl_pw_aff_add(pwaff, isl_pw_aff_from_aff(aff));
 
454
}
 
455
 
 
456
static __isl_give isl_pw_aff *accept_affine(struct isl_stream *s,
 
457
        __isl_take isl_space *dim, struct vars *v)
380
458
{
381
459
        struct isl_token *tok = NULL;
382
 
        struct isl_vec *aff;
 
460
        isl_local_space *ls;
 
461
        isl_pw_aff *res;
383
462
        int sign = 1;
384
463
 
385
 
        aff = isl_vec_alloc(v->ctx, 1 + v->n);
386
 
        if (!aff)
387
 
                return NULL;
388
 
        isl_seq_clr(aff->el, aff->size);
 
464
        ls = isl_local_space_from_space(isl_space_copy(dim));
 
465
        res = isl_pw_aff_from_aff(isl_aff_zero_on_domain(ls));
 
466
        if (!res)
 
467
                goto error;
389
468
 
390
469
        for (;;) {
391
470
                tok = next_token(s);
402
481
                    tok->type == ISL_TOKEN_MIN || tok->type == ISL_TOKEN_MAX ||
403
482
                    tok->type == ISL_TOKEN_FLOORD ||
404
483
                    tok->type == ISL_TOKEN_CEILD ||
405
 
                    tok->type == ISL_TOKEN_IDENT) {
406
 
                        isl_vec *aff2;
 
484
                    tok->type == ISL_TOKEN_IDENT ||
 
485
                    tok->type == ISL_TOKEN_AFF) {
 
486
                        isl_pw_aff *term;
407
487
                        isl_stream_push_token(s, tok);
408
488
                        tok = NULL;
409
 
                        aff2 = accept_affine_factor(s, v);
 
489
                        term = accept_affine_factor(s, isl_space_copy(dim), v);
410
490
                        if (sign < 0)
411
 
                                aff2 = isl_vec_scale(aff2, s->ctx->negone);
412
 
                        aff = isl_vec_zero_extend(aff, 1 + v->n);
413
 
                        aff = isl_vec_add(aff, aff2);
414
 
                        if (!aff)
 
491
                                res = isl_pw_aff_sub(res, term);
 
492
                        else
 
493
                                res = isl_pw_aff_add(res, term);
 
494
                        if (!res)
415
495
                                goto error;
416
496
                        sign = 1;
417
497
                } else if (tok->type == ISL_TOKEN_VALUE) {
419
499
                                isl_int_neg(tok->u.v, tok->u.v);
420
500
                        if (isl_stream_eat_if_available(s, '*') ||
421
501
                            isl_stream_next_token_is(s, ISL_TOKEN_IDENT)) {
422
 
                                isl_vec *aff2;
423
 
                                aff2 = accept_affine_factor(s, v);
424
 
                                aff2 = isl_vec_scale(aff2, tok->u.v);
425
 
                                aff = isl_vec_zero_extend(aff, 1 + v->n);
426
 
                                aff = isl_vec_add(aff, aff2);
427
 
                                if (!aff)
 
502
                                isl_pw_aff *term;
 
503
                                term = accept_affine_factor(s,
 
504
                                                        isl_space_copy(dim), v);
 
505
                                term = isl_pw_aff_scale(term, tok->u.v);
 
506
                                res = isl_pw_aff_add(res, term);
 
507
                                if (!res)
428
508
                                        goto error;
429
509
                        } else {
430
 
                                isl_int_add(aff->el[0], aff->el[0], tok->u.v);
 
510
                                res = add_cst(res, tok->u.v);
431
511
                        }
432
512
                        sign = 1;
433
513
                } else {
434
514
                        isl_stream_error(s, tok, "unexpected isl_token");
435
515
                        isl_stream_push_token(s, tok);
436
 
                        isl_vec_free(aff);
 
516
                        isl_pw_aff_free(res);
 
517
                        isl_space_free(dim);
437
518
                        return NULL;
438
519
                }
439
520
                isl_token_free(tok);
455
536
                }
456
537
        }
457
538
 
458
 
        return aff;
 
539
        isl_space_free(dim);
 
540
        return res;
459
541
error:
 
542
        isl_space_free(dim);
460
543
        isl_token_free(tok);
461
 
        isl_vec_free(aff);
462
 
        return NULL;
463
 
}
464
 
 
465
 
/* Add any variables in the variable list "v" that are not already in "bmap"
466
 
 * as existentially quantified variables in "bmap".
467
 
 */
468
 
static __isl_give isl_basic_map *add_divs(__isl_take isl_basic_map *bmap,
469
 
        struct vars *v)
470
 
{
471
 
        int i;
472
 
        int extra;
473
 
        struct variable *var;
474
 
 
475
 
        extra = v->n - isl_basic_map_total_dim(bmap);
476
 
 
477
 
        if (extra == 0)
478
 
                return bmap;
479
 
 
480
 
        bmap = isl_basic_map_extend_dim(bmap, isl_basic_map_get_dim(bmap),
481
 
                                        extra, 0, 2 * extra);
482
 
 
483
 
        for (i = 0; i < extra; ++i)
484
 
                if (isl_basic_map_alloc_div(bmap) < 0)
485
 
                        goto error;
486
 
 
487
 
        for (i = 0, var = v->v; i < extra; ++i, var = var->next) {
488
 
                int k = bmap->n_div - 1 - i;
489
 
 
490
 
                isl_seq_cpy(bmap->div[k], var->def->el, var->def->size);
491
 
                isl_seq_clr(bmap->div[k] + var->def->size,
492
 
                            2 + v->n - var->def->size);
493
 
 
494
 
                if (isl_basic_map_add_div_constraints(bmap, k) < 0)
495
 
                        goto error;
496
 
        }
497
 
 
498
 
        return bmap;
499
 
error:
500
 
        isl_basic_map_free(bmap);
501
 
        return NULL;
502
 
}
503
 
 
504
 
static __isl_give isl_basic_map *read_var_def(struct isl_stream *s,
505
 
        __isl_take isl_basic_map *bmap, enum isl_dim_type type, struct vars *v)
506
 
{
507
 
        isl_dim *dim;
508
 
        isl_basic_map *def = NULL;
509
 
        struct isl_vec *vec;
510
 
        int k;
511
 
        int n;
512
 
 
513
 
        if (vars_add_anon(v) < 0)
514
 
                goto error;
515
 
        n = v->n;
516
 
 
517
 
        vec = accept_affine(s, v);
518
 
        if (!vec)
519
 
                goto error;
520
 
 
521
 
        dim = isl_basic_map_get_dim(bmap);
522
 
        def = isl_basic_map_universe(dim);
523
 
        def = add_divs(def, v);
524
 
        def = isl_basic_map_extend_constraints(def, 1, 0);
525
 
        k = isl_basic_map_alloc_equality(def);
526
 
        if (k >= 0) {
527
 
                isl_seq_cpy(def->eq[k], vec->el, vec->size);
528
 
                isl_int_set_si(def->eq[k][1 + n - 1], -1);
529
 
        }
530
 
        isl_vec_free(vec);
531
 
        if (k < 0)
532
 
                goto error;
533
 
 
534
 
        vars_drop(v, v->n - n);
535
 
 
536
 
        def = isl_basic_map_simplify(def);
537
 
        def = isl_basic_map_finalize(def);
538
 
        bmap = isl_basic_map_intersect(bmap, def);
539
 
        return bmap;
540
 
error:
541
 
        isl_basic_map_free(bmap);
542
 
        isl_basic_map_free(def);
543
 
        return NULL;
544
 
}
545
 
 
546
 
static __isl_give isl_basic_map *read_var_list(struct isl_stream *s,
547
 
        __isl_take isl_basic_map *bmap, enum isl_dim_type type, struct vars *v)
 
544
        isl_pw_aff_free(res);
 
545
        return NULL;
 
546
}
 
547
 
 
548
static int is_comparator(struct isl_token *tok)
 
549
{
 
550
        if (!tok)
 
551
                return 0;
 
552
 
 
553
        switch (tok->type) {
 
554
        case ISL_TOKEN_LT:
 
555
        case ISL_TOKEN_GT:
 
556
        case ISL_TOKEN_LE:
 
557
        case ISL_TOKEN_GE:
 
558
        case ISL_TOKEN_NE:
 
559
        case '=':
 
560
                return 1;
 
561
        default:
 
562
                return 0;
 
563
        }
 
564
}
 
565
 
 
566
static struct isl_map *read_disjuncts(struct isl_stream *s,
 
567
        struct vars *v, __isl_take isl_map *map);
 
568
static __isl_give isl_pw_aff *accept_extended_affine(struct isl_stream *s,
 
569
        __isl_take isl_space *dim, struct vars *v);
 
570
 
 
571
/* Accept a ternary operator, given the first argument.
 
572
 */
 
573
static __isl_give isl_pw_aff *accept_ternary(struct isl_stream *s,
 
574
        __isl_take isl_map *cond, struct vars *v)
 
575
{
 
576
        isl_space *dim;
 
577
        isl_pw_aff *pwaff1 = NULL, *pwaff2 = NULL;
 
578
 
 
579
        if (!cond)
 
580
                return NULL;
 
581
 
 
582
        if (isl_stream_eat(s, '?'))
 
583
                goto error;
 
584
 
 
585
        dim = isl_space_wrap(isl_map_get_space(cond));
 
586
        pwaff1 = accept_extended_affine(s, dim, v);
 
587
        if (!pwaff1)
 
588
                goto error;
 
589
 
 
590
        if (isl_stream_eat(s, ':'))
 
591
                goto error;
 
592
 
 
593
        dim = isl_pw_aff_get_domain_space(pwaff1);
 
594
        pwaff2 = accept_extended_affine(s, dim, v);
 
595
        if (!pwaff1)
 
596
                goto error;
 
597
 
 
598
        return isl_pw_aff_cond(isl_map_wrap(cond), pwaff1, pwaff2);
 
599
error:
 
600
        isl_map_free(cond);
 
601
        isl_pw_aff_free(pwaff1);
 
602
        isl_pw_aff_free(pwaff2);
 
603
        return NULL;
 
604
}
 
605
 
 
606
/* Accept an affine expression that may involve ternary operators.
 
607
 * We first read an affine expression.
 
608
 * If it is not followed by a comparison operator, we simply return it.
 
609
 * Otherwise, we assume the affine epxression is part of the first
 
610
 * argument of a ternary operator and try to parse that.
 
611
 */
 
612
static __isl_give isl_pw_aff *accept_extended_affine(struct isl_stream *s,
 
613
        __isl_take isl_space *dim, struct vars *v)
 
614
{
 
615
        isl_space *space;
 
616
        isl_map *cond;
 
617
        isl_pw_aff *pwaff;
 
618
        struct isl_token *tok;
 
619
        int line = -1, col = -1;
 
620
        int is_comp;
 
621
 
 
622
        tok = isl_stream_next_token(s);
 
623
        if (tok) {
 
624
                line = tok->line;
 
625
                col = tok->col;
 
626
                isl_stream_push_token(s, tok);
 
627
        }
 
628
 
 
629
        pwaff = accept_affine(s, dim, v);
 
630
        if (!pwaff)
 
631
                return NULL;
 
632
 
 
633
        tok = isl_stream_next_token(s);
 
634
        if (!tok)
 
635
                return isl_pw_aff_free(pwaff);
 
636
 
 
637
        is_comp = is_comparator(tok);
 
638
        isl_stream_push_token(s, tok);
 
639
        if (!is_comp)
 
640
                return pwaff;
 
641
 
 
642
        tok = isl_token_new(s->ctx, line, col, 0);
 
643
        if (!tok)
 
644
                return isl_pw_aff_free(pwaff);
 
645
        tok->type = ISL_TOKEN_AFF;
 
646
        tok->u.pwaff = pwaff;
 
647
 
 
648
        space = isl_pw_aff_get_domain_space(pwaff);
 
649
        cond = isl_map_universe(isl_space_unwrap(space));
 
650
 
 
651
        isl_stream_push_token(s, tok);
 
652
 
 
653
        cond = read_disjuncts(s, v, cond);
 
654
 
 
655
        return accept_ternary(s, cond, v);
 
656
}
 
657
 
 
658
static __isl_give isl_map *read_var_def(struct isl_stream *s,
 
659
        __isl_take isl_map *map, enum isl_dim_type type, struct vars *v)
 
660
{
 
661
        isl_pw_aff *def;
 
662
        int pos;
 
663
        isl_map *def_map;
 
664
 
 
665
        if (type == isl_dim_param)
 
666
                pos = isl_map_dim(map, isl_dim_param);
 
667
        else {
 
668
                pos = isl_map_dim(map, isl_dim_in);
 
669
                if (type == isl_dim_out)
 
670
                        pos += isl_map_dim(map, isl_dim_out);
 
671
                type = isl_dim_in;
 
672
        }
 
673
        --pos;
 
674
 
 
675
        def = accept_extended_affine(s, isl_space_wrap(isl_map_get_space(map)), v);
 
676
        def_map = isl_map_from_pw_aff(def);
 
677
        def_map = isl_map_equate(def_map, type, pos, isl_dim_out, 0);
 
678
        def_map = isl_set_unwrap(isl_map_domain(def_map));
 
679
 
 
680
        map = isl_map_intersect(map, def_map);
 
681
 
 
682
        return map;
 
683
}
 
684
 
 
685
static __isl_give isl_map *read_var_list(struct isl_stream *s,
 
686
        __isl_take isl_map *map, enum isl_dim_type type, struct vars *v)
548
687
{
549
688
        int i = 0;
550
689
        struct isl_token *tok;
551
690
 
 
691
        if (isl_stream_next_token_is(s, ']'))
 
692
                return isl_map_add_dims(map, type, 0);
 
693
 
552
694
        while ((tok = next_token(s)) != NULL) {
553
695
                int new_name = 0;
554
696
 
561
703
                }
562
704
 
563
705
                if (new_name) {
564
 
                        bmap = isl_basic_map_add(bmap, type, 1);
565
 
                        bmap = set_name(bmap, type, i, v->v->name);
 
706
                        map = isl_map_add_dims(map, type, 1);
 
707
                        map = set_name(map, type, i, v->v->name);
566
708
                        isl_token_free(tok);
567
 
                } else if (tok->type == ISL_TOKEN_IDENT ||
568
 
                           tok->type == ISL_TOKEN_VALUE ||
569
 
                           tok->type == '-' ||
570
 
                           tok->type == '(') {
 
709
                        if (isl_stream_eat_if_available(s, '='))
 
710
                                map = read_var_def(s, map, type, v);
 
711
                } else {
571
712
                        if (type == isl_dim_param) {
572
713
                                isl_stream_error(s, tok,
573
714
                                                "expecting unique identifier");
575
716
                        }
576
717
                        isl_stream_push_token(s, tok);
577
718
                        tok = NULL;
578
 
                        bmap = isl_basic_map_add(bmap, type, 1);
579
 
                        bmap = read_var_def(s, bmap, type, v);
580
 
                } else
581
 
                        break;
 
719
                        if (vars_add_anon(v) < 0)
 
720
                                goto error;
 
721
                        map = isl_map_add_dims(map, type, 1);
 
722
                        map = read_var_def(s, map, type, v);
 
723
                }
582
724
 
583
725
                tok = isl_stream_next_token(s);
584
726
                if (tok && tok->type == ']' &&
594
736
        if (tok)
595
737
                isl_stream_push_token(s, tok);
596
738
 
597
 
        return bmap;
 
739
        return map;
598
740
error:
599
741
        isl_token_free(tok);
600
 
        isl_basic_map_free(bmap);
 
742
        isl_map_free(map);
601
743
        return NULL;
602
744
}
603
745
 
604
 
static __isl_give isl_mat *accept_affine_list(struct isl_stream *s,
605
 
        struct vars *v)
 
746
static __isl_give isl_pw_aff_list *accept_affine_list(struct isl_stream *s,
 
747
        __isl_take isl_space *dim, struct vars *v)
606
748
{
607
 
        struct isl_vec *vec;
608
 
        struct isl_mat *mat;
 
749
        isl_pw_aff *pwaff;
 
750
        isl_pw_aff_list *list;
609
751
        struct isl_token *tok = NULL;
610
752
 
611
 
        vec = accept_affine(s, v);
612
 
        mat = isl_mat_from_row_vec(vec);
613
 
        if (!mat)
614
 
                return NULL;
 
753
        pwaff = accept_affine(s, isl_space_copy(dim), v);
 
754
        list = isl_pw_aff_list_from_pw_aff(pwaff);
 
755
        if (!list)
 
756
                goto error;
615
757
 
616
758
        for (;;) {
617
759
                tok = isl_stream_next_token(s);
625
767
                }
626
768
                isl_token_free(tok);
627
769
 
628
 
                vec = accept_affine(s, v);
629
 
                mat = isl_mat_add_zero_cols(mat, 1 + v->n - isl_mat_cols(mat));
630
 
                mat = isl_mat_vec_concat(mat, vec);
631
 
                if (!mat)
 
770
                pwaff = accept_affine(s, isl_space_copy(dim), v);
 
771
                list = isl_pw_aff_list_concat(list,
 
772
                                isl_pw_aff_list_from_pw_aff(pwaff));
 
773
                if (!list)
632
774
                        return NULL;
633
775
        }
634
776
 
635
 
        return mat;
636
 
error:
637
 
        isl_mat_free(mat);
638
 
        return NULL;
639
 
}
640
 
 
641
 
static int read_minmax_definition(struct isl_stream *s, struct vars *v)
642
 
{
643
 
        struct isl_token *tok;
644
 
        struct variable *var;
645
 
 
646
 
        var = v->v;
647
 
 
648
 
        tok = isl_stream_next_token(s);
649
 
        if (!tok)
650
 
                return -1;
651
 
        var->sign = tok->type == ISL_TOKEN_MIN ? -1 : 1;
652
 
        isl_token_free(tok);
653
 
 
654
 
        if (isl_stream_eat(s, '('))
655
 
                return -1;
656
 
 
657
 
        var->list = accept_affine_list(s, v);
658
 
        if (!var->list)
659
 
                return -1;
660
 
 
661
 
        if (isl_stream_eat(s, ')'))
662
 
                return -1;
663
 
 
664
 
        return 0;
665
 
}
666
 
 
667
 
static int read_div_definition(struct isl_stream *s, struct vars *v)
668
 
{
669
 
        struct isl_token *tok;
670
 
        int seen_paren = 0;
671
 
        struct isl_vec *aff;
672
 
        struct variable *var;
673
 
        int fc = 0;
674
 
 
675
 
        if (isl_stream_eat_if_available(s, ISL_TOKEN_FLOORD) ||
676
 
            isl_stream_eat_if_available(s, ISL_TOKEN_CEILD)) {
677
 
                fc = 1;
678
 
                if (isl_stream_eat(s, '('))
679
 
                        return -1;
680
 
        } else {
681
 
                if (isl_stream_eat(s, '['))
682
 
                        return -1;
683
 
                if (isl_stream_eat_if_available(s, '('))
684
 
                        seen_paren = 1;
685
 
        }
686
 
 
687
 
        var = v->v;
688
 
 
689
 
        aff = accept_affine(s, v);
690
 
        if (!aff)
691
 
                return -1;
692
 
 
693
 
        var->def = isl_vec_alloc(s->ctx, 2 + v->n);
694
 
        if (!var->def) {
695
 
                isl_vec_free(aff);
696
 
                return -1;
697
 
        }
698
 
 
699
 
        isl_seq_cpy(var->def->el + 1, aff->el, aff->size);
700
 
 
701
 
        isl_vec_free(aff);
702
 
 
703
 
        if (fc) {
704
 
                if (isl_stream_eat(s, ','))
705
 
                        return -1;
706
 
        } else {
707
 
                if (seen_paren && isl_stream_eat(s, ')'))
708
 
                        return -1;
709
 
                if (isl_stream_eat(s, '/'))
710
 
                        return -1;
711
 
        }
712
 
 
713
 
        tok = next_token(s);
714
 
        if (!tok)
715
 
                return -1;
716
 
        if (tok->type != ISL_TOKEN_VALUE) {
717
 
                isl_stream_error(s, tok, "expected denominator");
718
 
                isl_stream_push_token(s, tok);
719
 
                return -1;
720
 
        }
721
 
        isl_int_set(var->def->el[0], tok->u.v);
722
 
        isl_token_free(tok);
723
 
 
724
 
        if (fc) {
725
 
                if (isl_stream_eat(s, ')'))
726
 
                        return -1;
727
 
        } else {
728
 
                if (isl_stream_eat(s, ']'))
729
 
                        return -1;
730
 
        }
731
 
 
732
 
        return 0;
733
 
}
734
 
 
735
 
static struct isl_basic_map *add_div_definition(struct isl_stream *s,
736
 
        struct vars *v, struct isl_basic_map *bmap, int pos)
737
 
{
738
 
        struct variable *var = v->v;
739
 
        unsigned o_out = isl_basic_map_offset(bmap, isl_dim_out) - 1;
740
 
 
741
 
        if (read_div_definition(s, v) < 0)
742
 
                goto error;
743
 
 
744
 
        if (isl_basic_map_add_div_constraints_var(bmap, o_out + pos,
745
 
                                                  var->def->el) < 0)
746
 
                goto error;
747
 
 
748
 
        return bmap;
749
 
error:
750
 
        isl_basic_map_free(bmap);
751
 
        return NULL;
752
 
}
753
 
 
754
 
static struct isl_basic_map *read_defined_var_list(struct isl_stream *s,
755
 
        struct vars *v, struct isl_basic_map *bmap)
 
777
        isl_space_free(dim);
 
778
        return list;
 
779
error:
 
780
        isl_space_free(dim);
 
781
        isl_pw_aff_list_free(list);
 
782
        return NULL;
 
783
}
 
784
 
 
785
static __isl_give isl_map *read_defined_var_list(struct isl_stream *s,
 
786
        struct vars *v, __isl_take isl_map *map)
756
787
{
757
788
        struct isl_token *tok;
758
789
 
759
790
        while ((tok = isl_stream_next_token(s)) != NULL) {
760
791
                int p;
761
792
                int n = v->n;
762
 
                unsigned n_out = isl_basic_map_dim(bmap, isl_dim_out);
763
793
 
764
794
                if (tok->type != ISL_TOKEN_IDENT)
765
795
                        break;
772
802
                        goto error;
773
803
                }
774
804
 
775
 
                bmap = isl_basic_map_cow(bmap);
776
 
                bmap = isl_basic_map_add(bmap, isl_dim_out, 1);
777
 
                bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim),
778
 
                                                0, 0, 2);
 
805
                map = isl_map_add_dims(map, isl_dim_out, 1);
779
806
 
780
807
                isl_token_free(tok);
781
808
                tok = isl_stream_next_token(s);
782
809
                if (tok && tok->type == '=') {
783
810
                        isl_token_free(tok);
784
 
                        bmap = add_div_definition(s, v, bmap, n_out);
 
811
                        map = read_var_def(s, map, isl_dim_out, v);
785
812
                        tok = isl_stream_next_token(s);
786
813
                }
787
814
 
793
820
        if (tok)
794
821
                isl_stream_push_token(s, tok);
795
822
 
796
 
        return bmap;
 
823
        return map;
797
824
error:
798
825
        isl_token_free(tok);
799
 
        isl_basic_map_free(bmap);
 
826
        isl_map_free(map);
800
827
        return NULL;
801
828
}
802
829
 
824
851
        return is_tuple;
825
852
}
826
853
 
827
 
static __isl_give isl_basic_map *read_tuple(struct isl_stream *s,
828
 
        __isl_take isl_basic_map *bmap, enum isl_dim_type type, struct vars *v);
 
854
static __isl_give isl_map *read_tuple(struct isl_stream *s,
 
855
        __isl_take isl_map *map, enum isl_dim_type type, struct vars *v);
829
856
 
830
 
static __isl_give isl_basic_map *read_nested_tuple(struct isl_stream *s,
831
 
        __isl_take isl_basic_map *bmap, struct vars *v)
 
857
static __isl_give isl_set *read_nested_tuple(struct isl_stream *s,
 
858
        __isl_take isl_map *map, struct vars *v)
832
859
{
833
 
        bmap = read_tuple(s, bmap, isl_dim_in, v);
 
860
        map = read_tuple(s, map, isl_dim_in, v);
834
861
        if (isl_stream_eat(s, ISL_TOKEN_TO))
835
862
                goto error;
836
 
        bmap = read_tuple(s, bmap, isl_dim_out, v);
837
 
        bmap = isl_basic_map_from_range(isl_basic_map_wrap(bmap));
838
 
        return bmap;
 
863
        map = read_tuple(s, map, isl_dim_out, v);
 
864
        return isl_map_wrap(map);
839
865
error:
840
 
        isl_basic_map_free(bmap);
 
866
        isl_map_free(map);
841
867
        return NULL;
842
868
}
843
869
 
844
 
static __isl_give isl_basic_map *read_tuple(struct isl_stream *s,
845
 
        __isl_take isl_basic_map *bmap, enum isl_dim_type type, struct vars *v)
 
870
static __isl_give isl_map *read_tuple(struct isl_stream *s,
 
871
        __isl_take isl_map *map, enum isl_dim_type type, struct vars *v)
846
872
{
847
873
        struct isl_token *tok;
848
874
        char *name = NULL;
861
887
        }
862
888
        isl_token_free(tok);
863
889
        if (type != isl_dim_param && next_is_tuple(s)) {
864
 
                isl_dim *dim = isl_basic_map_get_dim(bmap);
865
 
                int nparam = isl_dim_size(dim, isl_dim_param);
866
 
                int n_in = isl_dim_size(dim, isl_dim_in);
867
 
                isl_basic_map *nested;
868
 
                if (type == isl_dim_out)
869
 
                        dim = isl_dim_move(dim, isl_dim_param, nparam,
 
890
                isl_space *dim = isl_map_get_space(map);
 
891
                int nparam = isl_space_dim(dim, isl_dim_param);
 
892
                int n_in = isl_space_dim(dim, isl_dim_in);
 
893
                isl_set *nested;
 
894
                if (type == isl_dim_out) {
 
895
                        dim = isl_space_move_dims(dim, isl_dim_param, nparam,
870
896
                                                isl_dim_in, 0, n_in);
871
 
                nested = isl_basic_map_alloc_dim(dim, 0, 0, 0);
872
 
                nested = read_nested_tuple(s, nested, v);
 
897
                        dim = isl_space_params(dim);
 
898
                }
 
899
                nested = read_nested_tuple(s, isl_map_universe(dim), v);
873
900
                if (type == isl_dim_in) {
874
 
                        nested = isl_basic_map_reverse(nested);
875
 
                        bmap = isl_basic_map_intersect(nested, bmap);
 
901
                        nested = isl_map_reverse(nested);
 
902
                        map = isl_map_intersect_params(nested, map);
876
903
                } else {
877
 
                        isl_basic_set *bset;
878
 
                        dim = isl_dim_range(isl_basic_map_get_dim(nested));
879
 
                        dim = isl_dim_drop(dim, isl_dim_param, nparam, n_in);
880
 
                        dim = isl_dim_join(isl_basic_map_get_dim(bmap), dim);
881
 
                        bset = isl_basic_map_domain(bmap);
882
 
                        nested = isl_basic_map_reset_dim(nested, dim);
883
 
                        bmap = isl_basic_map_intersect_domain(nested, bset);
 
904
                        isl_set *set;
 
905
                        dim = isl_set_get_space(nested);
 
906
                        dim = isl_space_drop_dims(dim, isl_dim_param, nparam, n_in);
 
907
                        dim = isl_space_join(isl_map_get_space(map), dim);
 
908
                        set = isl_map_domain(map);
 
909
                        nested = isl_map_reset_space(nested, dim);
 
910
                        map = isl_map_intersect_domain(nested, set);
884
911
                }
885
912
        } else
886
 
                bmap = read_var_list(s, bmap, type, v);
 
913
                map = read_var_list(s, map, type, v);
887
914
        tok = isl_stream_next_token(s);
888
915
        if (!tok || tok->type != ']') {
889
916
                isl_stream_error(s, tok, "expecting ']'");
892
919
        isl_token_free(tok);
893
920
 
894
921
        if (name) {
895
 
                bmap = isl_basic_map_set_tuple_name(bmap, type, name);
 
922
                map = isl_map_set_tuple_name(map, type, name);
896
923
                free(name);
897
924
        }
898
925
 
899
 
        return bmap;
 
926
        return map;
900
927
error:
901
928
        if (tok)
902
929
                isl_token_free(tok);
903
 
        isl_basic_map_free(bmap);
 
930
        isl_map_free(map);
904
931
        return NULL;
905
932
}
906
933
 
907
 
static __isl_give isl_basic_map *construct_constraint(
908
 
        __isl_take isl_basic_map *bmap, enum isl_token_type type,
909
 
        isl_int *left, isl_int *right)
 
934
static __isl_give isl_set *construct_constraints(
 
935
        __isl_take isl_set *set, enum isl_token_type type,
 
936
        __isl_keep isl_pw_aff_list *left, __isl_keep isl_pw_aff_list *right)
910
937
{
911
 
        int k;
912
 
        unsigned len;
913
 
        struct isl_ctx *ctx;
914
 
 
915
 
        if (!bmap)
916
 
                return NULL;
917
 
        len = 1 + isl_basic_map_total_dim(bmap);
918
 
        ctx = bmap->ctx;
919
 
 
920
 
        k = isl_basic_map_alloc_inequality(bmap);
921
 
        if (k < 0)
922
 
                goto error;
 
938
        isl_set *cond;
 
939
 
923
940
        if (type == ISL_TOKEN_LE)
924
 
                isl_seq_combine(bmap->ineq[k], ctx->negone, left,
925
 
                                               ctx->one, right,
926
 
                                               len);
 
941
                cond = isl_pw_aff_list_le_set(isl_pw_aff_list_copy(left),
 
942
                                              isl_pw_aff_list_copy(right));
927
943
        else if (type == ISL_TOKEN_GE)
928
 
                isl_seq_combine(bmap->ineq[k], ctx->one, left,
929
 
                                               ctx->negone, right,
930
 
                                               len);
931
 
        else if (type == ISL_TOKEN_LT) {
932
 
                isl_seq_combine(bmap->ineq[k], ctx->negone, left,
933
 
                                               ctx->one, right,
934
 
                                               len);
935
 
                isl_int_sub_ui(bmap->ineq[k][0], bmap->ineq[k][0], 1);
936
 
        } else if (type == ISL_TOKEN_GT) {
937
 
                isl_seq_combine(bmap->ineq[k], ctx->one, left,
938
 
                                               ctx->negone, right,
939
 
                                               len);
940
 
                isl_int_sub_ui(bmap->ineq[k][0], bmap->ineq[k][0], 1);
941
 
        } else {
942
 
                isl_seq_combine(bmap->ineq[k], ctx->one, left,
943
 
                                               ctx->negone, right,
944
 
                                               len);
945
 
                isl_basic_map_inequality_to_equality(bmap, k);
946
 
        }
947
 
 
948
 
        return bmap;
949
 
error:
950
 
        isl_basic_map_free(bmap);
951
 
        return NULL;
952
 
}
953
 
 
954
 
static int is_comparator(struct isl_token *tok)
955
 
{
956
 
        if (!tok)
957
 
                return 0;
958
 
 
959
 
        switch (tok->type) {
960
 
        case ISL_TOKEN_LT:
961
 
        case ISL_TOKEN_GT:
962
 
        case ISL_TOKEN_LE:
963
 
        case ISL_TOKEN_GE:
964
 
        case '=':
965
 
                return 1;
966
 
        default:
967
 
                return 0;
968
 
        }
969
 
}
970
 
 
971
 
/* Add any variables in the variable list "v" that are not already in "bmap"
972
 
 * as output variables in "bmap".
973
 
 */
974
 
static __isl_give isl_basic_map *add_lifted_divs(__isl_take isl_basic_map *bmap,
975
 
        struct vars *v)
976
 
{
977
 
        int i;
978
 
        int extra;
979
 
        struct variable *var;
980
 
 
981
 
        extra = v->n - isl_basic_map_total_dim(bmap);
982
 
 
983
 
        if (extra == 0)
984
 
                return bmap;
985
 
 
986
 
        bmap = isl_basic_map_add(bmap, isl_dim_out, extra);
987
 
        bmap = isl_basic_map_extend_dim(bmap, isl_basic_map_get_dim(bmap),
988
 
                                        0, 0, 2 * extra);
989
 
 
990
 
        for (i = 0, var = v->v; i < extra; ++i, var = var->next) {
991
 
                if (!var->def)
992
 
                        continue;
993
 
                var->def = isl_vec_zero_extend(var->def, 2 + v->n);
994
 
                if (!var->def)
995
 
                        goto error;
996
 
                if (isl_basic_map_add_div_constraints_var(bmap, var->pos,
997
 
                                                          var->def->el) < 0)
998
 
                        goto error;
999
 
        }
1000
 
 
1001
 
        return bmap;
1002
 
error:
1003
 
        isl_basic_map_free(bmap);
1004
 
        return NULL;
1005
 
}
1006
 
 
1007
 
static struct isl_basic_map *add_constraint(struct isl_stream *s,
1008
 
        struct vars *v, struct isl_basic_map *bmap)
1009
 
{
1010
 
        int i, j;
 
944
                cond = isl_pw_aff_list_ge_set(isl_pw_aff_list_copy(left),
 
945
                                              isl_pw_aff_list_copy(right));
 
946
        else if (type == ISL_TOKEN_LT)
 
947
                cond = isl_pw_aff_list_lt_set(isl_pw_aff_list_copy(left),
 
948
                                              isl_pw_aff_list_copy(right));
 
949
        else if (type == ISL_TOKEN_GT)
 
950
                cond = isl_pw_aff_list_gt_set(isl_pw_aff_list_copy(left),
 
951
                                              isl_pw_aff_list_copy(right));
 
952
        else if (type == ISL_TOKEN_NE)
 
953
                cond = isl_pw_aff_list_ne_set(isl_pw_aff_list_copy(left),
 
954
                                              isl_pw_aff_list_copy(right));
 
955
        else
 
956
                cond = isl_pw_aff_list_eq_set(isl_pw_aff_list_copy(left),
 
957
                                              isl_pw_aff_list_copy(right));
 
958
 
 
959
        return isl_set_intersect(set, cond);
 
960
}
 
961
 
 
962
static __isl_give isl_map *add_constraint(struct isl_stream *s,
 
963
        struct vars *v, __isl_take isl_map *map)
 
964
{
1011
965
        struct isl_token *tok = NULL;
1012
 
        struct isl_mat *aff1 = NULL, *aff2 = NULL;
1013
 
 
1014
 
        bmap = isl_basic_map_cow(bmap);
1015
 
 
1016
 
        aff1 = accept_affine_list(s, v);
1017
 
        if (!aff1)
 
966
        isl_pw_aff_list *list1 = NULL, *list2 = NULL;
 
967
        isl_set *set;
 
968
 
 
969
        set = isl_map_wrap(map);
 
970
        list1 = accept_affine_list(s, isl_set_get_space(set), v);
 
971
        if (!list1)
1018
972
                goto error;
1019
973
        tok = isl_stream_next_token(s);
1020
974
        if (!is_comparator(tok)) {
1025
979
                goto error;
1026
980
        }
1027
981
        for (;;) {
1028
 
                aff2 = accept_affine_list(s, v);
1029
 
                if (!aff2)
 
982
                list2 = accept_affine_list(s, isl_set_get_space(set), v);
 
983
                if (!list2)
1030
984
                        goto error;
1031
985
 
1032
 
                aff1 = isl_mat_add_zero_cols(aff1, aff2->n_col - aff1->n_col);
1033
 
                if (!aff1)
1034
 
                        goto error;
1035
 
                bmap = add_lifted_divs(bmap, v);
1036
 
                bmap = isl_basic_map_extend_constraints(bmap, 0,
1037
 
                                                aff1->n_row * aff2->n_row);
1038
 
                for (i = 0; i < aff1->n_row; ++i)
1039
 
                        for (j = 0; j < aff2->n_row; ++j)
1040
 
                                bmap = construct_constraint(bmap, tok->type,
1041
 
                                                    aff1->row[i], aff2->row[j]);
 
986
                set = construct_constraints(set, tok->type, list1, list2);
1042
987
                isl_token_free(tok);
1043
 
                isl_mat_free(aff1);
1044
 
                aff1 = aff2;
 
988
                isl_pw_aff_list_free(list1);
 
989
                list1 = list2;
1045
990
 
1046
991
                tok = isl_stream_next_token(s);
1047
992
                if (!is_comparator(tok)) {
1050
995
                        break;
1051
996
                }
1052
997
        }
1053
 
        isl_mat_free(aff1);
 
998
        isl_pw_aff_list_free(list1);
1054
999
 
1055
 
        return bmap;
 
1000
        return isl_set_unwrap(set);
1056
1001
error:
1057
1002
        if (tok)
1058
1003
                isl_token_free(tok);
1059
 
        isl_mat_free(aff1);
1060
 
        isl_mat_free(aff2);
1061
 
        isl_basic_map_free(bmap);
1062
 
        return NULL;
1063
 
}
1064
 
 
1065
 
/* Return first variable, starting at n, representing a min or max,
1066
 
 * or NULL if there is no such variable.
1067
 
 */
1068
 
static struct variable *first_minmax(struct vars *v, int n)
1069
 
{
1070
 
        struct variable *first = NULL;
1071
 
        struct variable *var;
1072
 
 
1073
 
        for (var = v->v; var && var->pos >= n; var = var->next)
1074
 
                if (var->list)
1075
 
                        first = var;
1076
 
 
1077
 
        return first;
1078
 
}
1079
 
 
1080
 
/* Check whether the variable at the given position only occurs in
1081
 
 * inequalities and only with the given sign.
1082
 
 */
1083
 
static int all_coefficients_of_sign(__isl_keep isl_map *map, int pos, int sign)
1084
 
{
1085
 
        int i, j;
1086
 
 
1087
 
        if (!map)
1088
 
                return -1;
1089
 
 
1090
 
        for (i = 0; i < map->n; ++i) {
1091
 
                isl_basic_map *bmap = map->p[i];
1092
 
 
1093
 
                for (j = 0; j < bmap->n_eq; ++j)
1094
 
                        if (!isl_int_is_zero(bmap->eq[j][1 + pos]))
1095
 
                                return 0;
1096
 
                for (j = 0; j < bmap->n_ineq; ++j) {
1097
 
                        int s = isl_int_sgn(bmap->ineq[j][1 + pos]);
1098
 
                        if (s == 0)
1099
 
                                continue;
1100
 
                        if (s != sign)
1101
 
                                return 0;
1102
 
                }
1103
 
        }
1104
 
 
1105
 
        return 1;
1106
 
}
1107
 
 
1108
 
/* Given a variable m which represents a min or a max of n expressions
1109
 
 * b_i, add the constraints
1110
 
 *
1111
 
 *      m <= b_i
1112
 
 *
1113
 
 * in case of a min (var->sign < 0) and m >= b_i in case of a max.
1114
 
 */
1115
 
static __isl_give isl_map *bound_minmax(__isl_take isl_map *map,
1116
 
        struct variable *var)
1117
 
{
1118
 
        int i, k;
1119
 
        isl_basic_map *bound;
1120
 
        int total;
1121
 
 
1122
 
        total = isl_map_dim(map, isl_dim_all);
1123
 
        bound = isl_basic_map_alloc_dim(isl_map_get_dim(map),
1124
 
                                        0, 0, var->list->n_row);
1125
 
 
1126
 
        for (i = 0; i < var->list->n_row; ++i) {
1127
 
                k = isl_basic_map_alloc_inequality(bound);
1128
 
                if (k < 0)
1129
 
                        goto error;
1130
 
                if (var->sign < 0)
1131
 
                        isl_seq_cpy(bound->ineq[k], var->list->row[i],
1132
 
                                    var->list->n_col);
1133
 
                else
1134
 
                        isl_seq_neg(bound->ineq[k], var->list->row[i],
1135
 
                                    var->list->n_col);
1136
 
                isl_int_set_si(bound->ineq[k][1 + var->pos], var->sign);
1137
 
                isl_seq_clr(bound->ineq[k] + var->list->n_col,
1138
 
                            1 + total - var->list->n_col);
1139
 
        }
1140
 
 
1141
 
        map = isl_map_intersect(map, isl_map_from_basic_map(bound));
1142
 
 
1143
 
        return map;
1144
 
error:
1145
 
        isl_basic_map_free(bound);
1146
 
        isl_map_free(map);
1147
 
        return NULL;
1148
 
}
1149
 
 
1150
 
/* Given a variable m which represents a min (or max) of n expressions
1151
 
 * b_i, add constraints that assigns the minimal upper bound to m, i.e.,
1152
 
 * divide the space into cells where one
1153
 
 * of the upper bounds is smaller than all the others and assign
1154
 
 * this upper bound to m.
1155
 
 *
1156
 
 * In particular, if there are n bounds b_i, then the input map
1157
 
 * is split into n pieces, each with the extra constraints
1158
 
 *
1159
 
 *      m = b_i
1160
 
 *      b_i <= b_j      for j > i
1161
 
 *      b_i <  b_j      for j < i
1162
 
 *
1163
 
 * in case of a min (var->sign < 0) and similarly in case of a max.
1164
 
 *
1165
 
 * Note: this function is very similar to set_minimum in isl_tab_pip.c
1166
 
 * Perhaps we should try to merge the two.
1167
 
 */
1168
 
static __isl_give isl_map *set_minmax(__isl_take isl_map *map,
1169
 
        struct variable *var)
1170
 
{
1171
 
        int i, j, k;
1172
 
        isl_basic_map *bmap = NULL;
1173
 
        isl_ctx *ctx;
1174
 
        isl_map *split = NULL;
1175
 
        int total;
1176
 
 
1177
 
        ctx = isl_map_get_ctx(map);
1178
 
        total = isl_map_dim(map, isl_dim_all);
1179
 
        split = isl_map_alloc_dim(isl_map_get_dim(map),
1180
 
                                var->list->n_row, ISL_SET_DISJOINT);
1181
 
 
1182
 
        for (i = 0; i < var->list->n_row; ++i) {
1183
 
                bmap = isl_basic_map_alloc_dim(isl_map_get_dim(map), 0,
1184
 
                                               1, var->list->n_row - 1);
1185
 
                k = isl_basic_map_alloc_equality(bmap);
1186
 
                if (k < 0)
1187
 
                        goto error;
1188
 
                isl_seq_cpy(bmap->eq[k], var->list->row[i], var->list->n_col);
1189
 
                isl_int_set_si(bmap->eq[k][1 + var->pos], -1);
1190
 
                for (j = 0; j < var->list->n_row; ++j) {
1191
 
                        if (j == i)
1192
 
                                continue;
1193
 
                        k = isl_basic_map_alloc_inequality(bmap);
1194
 
                        if (k < 0)
1195
 
                                goto error;
1196
 
                        if (var->sign < 0)
1197
 
                                isl_seq_combine(bmap->ineq[k],
1198
 
                                                ctx->one, var->list->row[j],
1199
 
                                                ctx->negone, var->list->row[i],
1200
 
                                                var->list->n_col);
1201
 
                        else
1202
 
                                isl_seq_combine(bmap->ineq[k],
1203
 
                                                ctx->negone, var->list->row[j],
1204
 
                                                ctx->one, var->list->row[i],
1205
 
                                                var->list->n_col);
1206
 
                        isl_seq_clr(bmap->ineq[k] + var->list->n_col,
1207
 
                                    1 + total - var->list->n_col);
1208
 
                        if (j < i)
1209
 
                                isl_int_sub_ui(bmap->ineq[k][0],
1210
 
                                               bmap->ineq[k][0], 1);
1211
 
                }
1212
 
                bmap = isl_basic_map_finalize(bmap);
1213
 
                split = isl_map_add_basic_map(split, bmap);
1214
 
        }
1215
 
 
1216
 
        map = isl_map_intersect(map, split);
1217
 
 
1218
 
        return map;
1219
 
error:
1220
 
        isl_basic_map_free(bmap);
1221
 
        isl_map_free(split);
1222
 
        isl_map_free(map);
1223
 
        return NULL;
1224
 
}
1225
 
 
1226
 
/* Plug in the definitions of all min and max expressions.
1227
 
 * If a min expression only appears in inequalities and only
1228
 
 * with a positive coefficient, then we can simply bound
1229
 
 * the variable representing the min by its defining terms
1230
 
 * and similarly for a max expression.
1231
 
 * Otherwise, we have to assign the different terms to the
1232
 
 * variable under the condition that the assigned term is smaller
1233
 
 * than the other terms.
1234
 
 */
1235
 
static __isl_give isl_map *add_minmax(__isl_take isl_map *map,
1236
 
        struct vars *v, int n)
1237
 
{
1238
 
        struct variable *var;
1239
 
 
1240
 
        while (n < v->n) {
1241
 
                var = first_minmax(v, n);
1242
 
                if (!var)
1243
 
                        break;
1244
 
                if (all_coefficients_of_sign(map, var->pos, -var->sign))
1245
 
                        map = bound_minmax(map, var);
1246
 
                else
1247
 
                        map = set_minmax(map, var);
1248
 
                n = var->pos + 1;
1249
 
        }
1250
 
 
1251
 
        return map;
1252
 
}
1253
 
 
1254
 
static isl_map *read_constraint(struct isl_stream *s,
1255
 
        struct vars *v, __isl_take isl_basic_map *bmap)
1256
 
{
1257
 
        int n = v->n;
1258
 
        isl_map *map;
1259
 
        unsigned total;
1260
 
 
1261
 
        if (!bmap)
1262
 
                return NULL;
1263
 
 
1264
 
        bmap = isl_basic_set_unwrap(isl_basic_set_lift(isl_basic_map_wrap(bmap)));
1265
 
        total = isl_basic_map_total_dim(bmap);
1266
 
        while (v->n < total)
1267
 
                if (vars_add_anon(v) < 0)
1268
 
                        goto error;
1269
 
 
1270
 
        bmap = add_constraint(s, v, bmap);
1271
 
        bmap = isl_basic_map_simplify(bmap);
1272
 
        bmap = isl_basic_map_finalize(bmap);
1273
 
 
1274
 
        map = isl_map_from_basic_map(bmap);
1275
 
 
1276
 
        map = add_minmax(map, v, n);
1277
 
 
1278
 
        map = isl_set_unwrap(isl_map_domain(map));
1279
 
 
1280
 
        vars_drop(v, v->n - n);
1281
 
 
1282
 
        return map;
1283
 
error:
1284
 
        isl_basic_map_free(bmap);
1285
 
        return NULL;
1286
 
}
1287
 
 
1288
 
static struct isl_map *read_disjuncts(struct isl_stream *s,
1289
 
        struct vars *v, __isl_take isl_basic_map *bmap);
 
1004
        isl_pw_aff_list_free(list1);
 
1005
        isl_pw_aff_list_free(list2);
 
1006
        isl_set_free(set);
 
1007
        return NULL;
 
1008
}
1290
1009
 
1291
1010
static __isl_give isl_map *read_exists(struct isl_stream *s,
1292
 
        struct vars *v, __isl_take isl_basic_map *bmap)
 
1011
        struct vars *v, __isl_take isl_map *map)
1293
1012
{
1294
1013
        int n = v->n;
1295
1014
        int seen_paren = isl_stream_eat_if_available(s, '(');
1296
 
        isl_map *map = NULL;
1297
1015
 
1298
 
        bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
1299
 
        bmap = read_defined_var_list(s, v, bmap);
 
1016
        map = isl_map_from_domain(isl_map_wrap(map));
 
1017
        map = read_defined_var_list(s, v, map);
1300
1018
 
1301
1019
        if (isl_stream_eat(s, ':'))
1302
1020
                goto error;
1303
1021
 
1304
 
        map = read_disjuncts(s, v, bmap);
 
1022
        map = read_disjuncts(s, v, map);
1305
1023
        map = isl_set_unwrap(isl_map_domain(map));
1306
 
        bmap = NULL;
1307
1024
 
1308
1025
        vars_drop(v, v->n - n);
1309
1026
        if (seen_paren && isl_stream_eat(s, ')'))
1311
1028
 
1312
1029
        return map;
1313
1030
error:
1314
 
        isl_basic_map_free(bmap);
1315
1031
        isl_map_free(map);
1316
1032
        return NULL;
1317
1033
}
1318
1034
 
 
1035
/* Parse an expression between parentheses and push the result
 
1036
 * back on the stream.
 
1037
 *
 
1038
 * The parsed expression may be either an affine expression
 
1039
 * or a condition.  The first type is pushed onto the stream
 
1040
 * as an isl_pw_aff, while the second is pushed as an isl_map.
 
1041
 *
 
1042
 * If the initial token indicates the start of a condition,
 
1043
 * we parse it as such.
 
1044
 * Otherwise, we first parse an affine expression and push
 
1045
 * that onto the stream.  If the affine expression covers the
 
1046
 * entire expression between parentheses, we return.
 
1047
 * Otherwise, we assume that the affine expression is the
 
1048
 * start of a condition and continue parsing.
 
1049
 */
 
1050
static int resolve_paren_expr(struct isl_stream *s,
 
1051
        struct vars *v, __isl_take isl_map *map)
 
1052
{
 
1053
        struct isl_token *tok, *tok2;
 
1054
        int line, col;
 
1055
        isl_pw_aff *pwaff;
 
1056
 
 
1057
        tok = isl_stream_next_token(s);
 
1058
        if (!tok || tok->type != '(')
 
1059
                goto error;
 
1060
 
 
1061
        if (isl_stream_next_token_is(s, '('))
 
1062
                if (resolve_paren_expr(s, v, isl_map_copy(map)))
 
1063
                        goto error;
 
1064
 
 
1065
        if (isl_stream_next_token_is(s, ISL_TOKEN_EXISTS) ||
 
1066
            isl_stream_next_token_is(s, ISL_TOKEN_TRUE) ||
 
1067
            isl_stream_next_token_is(s, ISL_TOKEN_FALSE) ||
 
1068
            isl_stream_next_token_is(s, ISL_TOKEN_MAP)) {
 
1069
                map = read_disjuncts(s, v, map);
 
1070
                if (isl_stream_eat(s, ')'))
 
1071
                        goto error;
 
1072
                tok->type = ISL_TOKEN_MAP;
 
1073
                tok->u.map = map;
 
1074
                isl_stream_push_token(s, tok);
 
1075
                return 0;
 
1076
        }
 
1077
 
 
1078
        tok2 = isl_stream_next_token(s);
 
1079
        if (!tok2)
 
1080
                goto error;
 
1081
        line = tok2->line;
 
1082
        col = tok2->col;
 
1083
        isl_stream_push_token(s, tok2);
 
1084
 
 
1085
        pwaff = accept_affine(s, isl_space_wrap(isl_map_get_space(map)), v);
 
1086
        if (!pwaff)
 
1087
                goto error;
 
1088
 
 
1089
        tok2 = isl_token_new(s->ctx, line, col, 0);
 
1090
        if (!tok2)
 
1091
                goto error2;
 
1092
        tok2->type = ISL_TOKEN_AFF;
 
1093
        tok2->u.pwaff = pwaff;
 
1094
 
 
1095
        if (isl_stream_eat_if_available(s, ')')) {
 
1096
                isl_stream_push_token(s, tok2);
 
1097
                isl_token_free(tok);
 
1098
                isl_map_free(map);
 
1099
                return 0;
 
1100
        }
 
1101
 
 
1102
        isl_stream_push_token(s, tok2);
 
1103
 
 
1104
        map = read_disjuncts(s, v, map);
 
1105
        if (isl_stream_eat(s, ')'))
 
1106
                goto error;
 
1107
 
 
1108
        tok->type = ISL_TOKEN_MAP;
 
1109
        tok->u.map = map;
 
1110
        isl_stream_push_token(s, tok);
 
1111
 
 
1112
        return 0;
 
1113
error2:
 
1114
        isl_pw_aff_free(pwaff);
 
1115
error:
 
1116
        isl_token_free(tok);
 
1117
        isl_map_free(map);
 
1118
        return -1;
 
1119
}
 
1120
 
1319
1121
static __isl_give isl_map *read_conjunct(struct isl_stream *s,
1320
 
        struct vars *v, __isl_take isl_basic_map *bmap)
 
1122
        struct vars *v, __isl_take isl_map *map)
1321
1123
{
1322
 
        isl_map *map;
 
1124
        if (isl_stream_next_token_is(s, '('))
 
1125
                if (resolve_paren_expr(s, v, isl_map_copy(map)))
 
1126
                        goto error;
1323
1127
 
1324
 
        if (isl_stream_eat_if_available(s, '(')) {
1325
 
                map = read_disjuncts(s, v, bmap);
1326
 
                if (isl_stream_eat(s, ')'))
 
1128
        if (isl_stream_next_token_is(s, ISL_TOKEN_MAP)) {
 
1129
                struct isl_token *tok;
 
1130
                tok = isl_stream_next_token(s);
 
1131
                if (!tok)
1327
1132
                        goto error;
 
1133
                isl_map_free(map);
 
1134
                map = isl_map_copy(tok->u.map);
 
1135
                isl_token_free(tok);
1328
1136
                return map;
1329
1137
        }
1330
1138
 
1331
1139
        if (isl_stream_eat_if_available(s, ISL_TOKEN_EXISTS))
1332
 
                return read_exists(s, v, bmap);
 
1140
                return read_exists(s, v, map);
1333
1141
 
1334
1142
        if (isl_stream_eat_if_available(s, ISL_TOKEN_TRUE))
1335
 
                return isl_map_from_basic_map(bmap);
 
1143
                return map;
1336
1144
 
1337
1145
        if (isl_stream_eat_if_available(s, ISL_TOKEN_FALSE)) {
1338
 
                isl_dim *dim = isl_basic_map_get_dim(bmap);
1339
 
                isl_basic_map_free(bmap);
 
1146
                isl_space *dim = isl_map_get_space(map);
 
1147
                isl_map_free(map);
1340
1148
                return isl_map_empty(dim);
1341
1149
        }
1342
1150
                
1343
 
        return read_constraint(s, v, bmap);
 
1151
        return add_constraint(s, v, map);
1344
1152
error:
1345
1153
        isl_map_free(map);
1346
1154
        return NULL;
1347
1155
}
1348
1156
 
1349
1157
static __isl_give isl_map *read_conjuncts(struct isl_stream *s,
1350
 
        struct vars *v, __isl_take isl_basic_map *bmap)
 
1158
        struct vars *v, __isl_take isl_map *map)
1351
1159
{
1352
 
        isl_map *map;
 
1160
        isl_map *res;
1353
1161
        int negate;
1354
1162
 
1355
1163
        negate = isl_stream_eat_if_available(s, ISL_TOKEN_NOT);
1356
 
        map = read_conjunct(s, v, isl_basic_map_copy(bmap));
1357
 
        if (negate) {
1358
 
                isl_map *t;
1359
 
                t = isl_map_from_basic_map(isl_basic_map_copy(bmap));
1360
 
                map = isl_map_subtract(t, map);
1361
 
        }
 
1164
        res = read_conjunct(s, v, isl_map_copy(map));
 
1165
        if (negate)
 
1166
                res = isl_map_subtract(isl_map_copy(map), res);
1362
1167
 
1363
1168
        while (isl_stream_eat_if_available(s, ISL_TOKEN_AND)) {
1364
 
                isl_map *map_i;
 
1169
                isl_map *res_i;
1365
1170
 
1366
1171
                negate = isl_stream_eat_if_available(s, ISL_TOKEN_NOT);
1367
 
                map_i = read_conjunct(s, v, isl_basic_map_copy(bmap));
 
1172
                res_i = read_conjunct(s, v, isl_map_copy(map));
1368
1173
                if (negate)
1369
 
                        map = isl_map_subtract(map, map_i);
 
1174
                        res = isl_map_subtract(res, res_i);
1370
1175
                else
1371
 
                        map = isl_map_intersect(map, map_i);
 
1176
                        res = isl_map_intersect(res, res_i);
1372
1177
        }
1373
1178
 
1374
 
        isl_basic_map_free(bmap);
1375
 
        return map;
 
1179
        isl_map_free(map);
 
1180
        return res;
1376
1181
}
1377
1182
 
1378
1183
static struct isl_map *read_disjuncts(struct isl_stream *s,
1379
 
        struct vars *v, __isl_take isl_basic_map *bmap)
 
1184
        struct vars *v, __isl_take isl_map *map)
1380
1185
{
1381
 
        struct isl_map *map;
 
1186
        isl_map *res;
1382
1187
 
1383
1188
        if (isl_stream_next_token_is(s, '}')) {
1384
 
                isl_dim *dim = isl_basic_map_get_dim(bmap);
1385
 
                isl_basic_map_free(bmap);
 
1189
                isl_space *dim = isl_map_get_space(map);
 
1190
                isl_map_free(map);
1386
1191
                return isl_map_universe(dim);
1387
1192
        }
1388
1193
 
1389
 
        map = read_conjuncts(s, v, isl_basic_map_copy(bmap));
 
1194
        res = read_conjuncts(s, v, isl_map_copy(map));
1390
1195
        while (isl_stream_eat_if_available(s, ISL_TOKEN_OR)) {
1391
 
                isl_map *map_i;
 
1196
                isl_map *res_i;
1392
1197
 
1393
 
                map_i = read_conjuncts(s, v, isl_basic_map_copy(bmap));
1394
 
                map = isl_map_union(map, map_i);
 
1198
                res_i = read_conjuncts(s, v, isl_map_copy(map));
 
1199
                res = isl_map_union(res, res_i);
1395
1200
        }
1396
1201
 
1397
 
        isl_basic_map_free(bmap);
1398
 
        return map;
 
1202
        isl_map_free(map);
 
1203
        return res;
1399
1204
}
1400
1205
 
1401
1206
static int polylib_pos_to_isl_pos(__isl_keep isl_basic_map *bmap, int pos)
1491
1296
        return NULL;
1492
1297
}
1493
1298
 
1494
 
static __isl_give isl_basic_map *basic_map_read_polylib(struct isl_stream *s,
1495
 
        int nparam)
 
1299
static __isl_give isl_basic_map *basic_map_read_polylib(struct isl_stream *s)
1496
1300
{
1497
1301
        int i;
1498
1302
        struct isl_token *tok;
1501
1305
        int on_new_line;
1502
1306
        unsigned in = 0, out, local = 0;
1503
1307
        struct isl_basic_map *bmap = NULL;
1504
 
 
1505
 
        if (nparam < 0)
1506
 
                nparam = 0;
 
1308
        int nparam = 0;
1507
1309
 
1508
1310
        tok = isl_stream_next_token(s);
1509
1311
        if (!tok) {
1610
1412
        return NULL;
1611
1413
}
1612
1414
 
1613
 
static struct isl_map *map_read_polylib(struct isl_stream *s, int nparam)
 
1415
static struct isl_map *map_read_polylib(struct isl_stream *s)
1614
1416
{
1615
1417
        struct isl_token *tok;
1616
1418
        struct isl_token *tok2;
1626
1428
        if (tok2 && tok2->type == ISL_TOKEN_VALUE) {
1627
1429
                isl_stream_push_token(s, tok2);
1628
1430
                isl_stream_push_token(s, tok);
1629
 
                return isl_map_from_basic_map(basic_map_read_polylib(s, nparam));
 
1431
                return isl_map_from_basic_map(basic_map_read_polylib(s));
1630
1432
        }
1631
1433
        if (tok2) {
1632
1434
                isl_stream_error(s, tok2, "unexpected token");
1639
1441
 
1640
1442
        isl_assert(s->ctx, n >= 1, return NULL);
1641
1443
 
1642
 
        map = isl_map_from_basic_map(basic_map_read_polylib(s, nparam));
 
1444
        map = isl_map_from_basic_map(basic_map_read_polylib(s));
1643
1445
 
1644
1446
        for (i = 1; map && i < n; ++i)
1645
1447
                map = isl_map_union(map,
1646
 
                        isl_map_from_basic_map(basic_map_read_polylib(s, nparam)));
 
1448
                        isl_map_from_basic_map(basic_map_read_polylib(s)));
1647
1449
 
1648
1450
        return map;
1649
1451
}
1673
1475
        return pow;
1674
1476
}
1675
1477
 
1676
 
static __isl_give isl_div *read_div(struct isl_stream *s,
1677
 
        __isl_take isl_dim *dim, struct vars *v)
1678
 
{
1679
 
        int n;
1680
 
        isl_basic_map *bmap;
1681
 
 
1682
 
        n = v->n;
1683
 
        bmap = isl_basic_map_universe(dim);
1684
 
 
1685
 
        if (vars_add_anon(v) < 0)
1686
 
                goto error;
1687
 
        if (read_div_definition(s, v) < 0)
1688
 
                goto error;
1689
 
        bmap = add_divs(bmap, v);
1690
 
        bmap = isl_basic_map_order_divs(bmap);
1691
 
        if (!bmap)
1692
 
                goto error;
1693
 
        vars_drop(v, v->n - n);
1694
 
 
1695
 
        return isl_basic_map_div(bmap, bmap->n_div - 1);
1696
 
error:
1697
 
        isl_basic_map_free(bmap);
1698
 
        return NULL;
1699
 
}
1700
 
 
1701
 
static __isl_give isl_qpolynomial *read_term(struct isl_stream *s,
1702
 
        __isl_keep isl_basic_map *bmap, struct vars *v);
1703
 
 
1704
 
static __isl_give isl_qpolynomial *read_factor(struct isl_stream *s,
1705
 
        __isl_keep isl_basic_map *bmap, struct vars *v)
1706
 
{
1707
 
        struct isl_qpolynomial *qp;
 
1478
static __isl_give isl_pw_qpolynomial *read_term(struct isl_stream *s,
 
1479
        __isl_keep isl_map *map, struct vars *v);
 
1480
 
 
1481
static __isl_give isl_pw_qpolynomial *read_factor(struct isl_stream *s,
 
1482
        __isl_keep isl_map *map, struct vars *v)
 
1483
{
 
1484
        isl_pw_qpolynomial *pwqp;
1708
1485
        struct isl_token *tok;
1709
1486
 
1710
1487
        tok = next_token(s);
1716
1493
                int pow;
1717
1494
 
1718
1495
                isl_token_free(tok);
1719
 
                qp = read_term(s, bmap, v);
1720
 
                if (!qp)
 
1496
                pwqp = read_term(s, map, v);
 
1497
                if (!pwqp)
1721
1498
                        return NULL;
1722
1499
                if (isl_stream_eat(s, ')'))
1723
1500
                        goto error;
1724
1501
                pow = optional_power(s);
1725
 
                qp = isl_qpolynomial_pow(qp, pow);
 
1502
                pwqp = isl_pw_qpolynomial_pow(pwqp, pow);
1726
1503
        } else if (tok->type == ISL_TOKEN_VALUE) {
1727
1504
                struct isl_token *tok2;
1728
1505
                tok2 = isl_stream_next_token(s);
 
1506
                isl_qpolynomial *qp;
1729
1507
                if (tok2 && tok2->type == '/') {
1730
1508
                        isl_token_free(tok2);
1731
1509
                        tok2 = next_token(s);
1735
1513
                                isl_token_free(tok2);
1736
1514
                                return NULL;
1737
1515
                        }
1738
 
                        qp = isl_qpolynomial_rat_cst(isl_basic_map_get_dim(bmap),
 
1516
                        qp = isl_qpolynomial_rat_cst_on_domain(isl_map_get_space(map),
1739
1517
                                                    tok->u.v, tok2->u.v);
1740
1518
                        isl_token_free(tok2);
1741
1519
                } else {
1742
1520
                        isl_stream_push_token(s, tok2);
1743
 
                        qp = isl_qpolynomial_cst(isl_basic_map_get_dim(bmap),
 
1521
                        qp = isl_qpolynomial_cst_on_domain(isl_map_get_space(map),
1744
1522
                                                tok->u.v);
1745
1523
                }
1746
1524
                isl_token_free(tok);
 
1525
                pwqp = isl_pw_qpolynomial_from_qpolynomial(qp);
1747
1526
        } else if (tok->type == ISL_TOKEN_INFTY) {
 
1527
                isl_qpolynomial *qp;
1748
1528
                isl_token_free(tok);
1749
 
                qp = isl_qpolynomial_infty(isl_basic_map_get_dim(bmap));
 
1529
                qp = isl_qpolynomial_infty_on_domain(isl_map_get_space(map));
 
1530
                pwqp = isl_pw_qpolynomial_from_qpolynomial(qp);
1750
1531
        } else if (tok->type == ISL_TOKEN_NAN) {
 
1532
                isl_qpolynomial *qp;
1751
1533
                isl_token_free(tok);
1752
 
                qp = isl_qpolynomial_nan(isl_basic_map_get_dim(bmap));
 
1534
                qp = isl_qpolynomial_nan_on_domain(isl_map_get_space(map));
 
1535
                pwqp = isl_pw_qpolynomial_from_qpolynomial(qp);
1753
1536
        } else if (tok->type == ISL_TOKEN_IDENT) {
1754
1537
                int n = v->n;
1755
1538
                int pos = vars_pos(v, tok->u.s, -1);
1756
1539
                int pow;
 
1540
                isl_qpolynomial *qp;
1757
1541
                if (pos < 0) {
1758
1542
                        isl_token_free(tok);
1759
1543
                        return NULL;
1766
1550
                }
1767
1551
                isl_token_free(tok);
1768
1552
                pow = optional_power(s);
1769
 
                qp = isl_qpolynomial_var_pow(isl_basic_map_get_dim(bmap), pos, pow);
 
1553
                qp = isl_qpolynomial_var_pow_on_domain(isl_map_get_space(map), pos, pow);
 
1554
                pwqp = isl_pw_qpolynomial_from_qpolynomial(qp);
1770
1555
        } else if (tok->type == '[') {
1771
 
                isl_div *div;
 
1556
                isl_pw_aff *pwaff;
1772
1557
                int pow;
1773
1558
 
1774
1559
                isl_stream_push_token(s, tok);
1775
 
                div = read_div(s, isl_basic_map_get_dim(bmap), v);
 
1560
                pwaff = accept_affine(s, isl_map_get_space(map), v);
1776
1561
                pow = optional_power(s);
1777
 
                qp = isl_qpolynomial_div_pow(div, pow);
 
1562
                pwqp = isl_pw_qpolynomial_from_pw_aff(pwaff);
 
1563
                pwqp = isl_pw_qpolynomial_pow(pwqp, pow);
1778
1564
        } else if (tok->type == '-') {
1779
 
                struct isl_qpolynomial *qp2;
1780
 
 
1781
1565
                isl_token_free(tok);
1782
 
                qp = isl_qpolynomial_cst(isl_basic_map_get_dim(bmap),
1783
 
                                            s->ctx->negone);
1784
 
                qp2 = read_factor(s, bmap, v);
1785
 
                qp = isl_qpolynomial_mul(qp, qp2);
 
1566
                pwqp = read_factor(s, map, v);
 
1567
                pwqp = isl_pw_qpolynomial_neg(pwqp);
1786
1568
        } else {
1787
1569
                isl_stream_error(s, tok, "unexpected isl_token");
1788
1570
                isl_stream_push_token(s, tok);
1791
1573
 
1792
1574
        if (isl_stream_eat_if_available(s, '*') ||
1793
1575
            isl_stream_next_token_is(s, ISL_TOKEN_IDENT)) {
1794
 
                struct isl_qpolynomial *qp2;
 
1576
                isl_pw_qpolynomial *pwqp2;
1795
1577
 
1796
 
                qp2 = read_factor(s, bmap, v);
1797
 
                qp = isl_qpolynomial_mul(qp, qp2);
 
1578
                pwqp2 = read_factor(s, map, v);
 
1579
                pwqp = isl_pw_qpolynomial_mul(pwqp, pwqp2);
1798
1580
        }
1799
1581
 
1800
 
        return qp;
 
1582
        return pwqp;
1801
1583
error:
1802
 
        isl_qpolynomial_free(qp);
 
1584
        isl_pw_qpolynomial_free(pwqp);
1803
1585
        return NULL;
1804
1586
}
1805
1587
 
1806
 
static __isl_give isl_qpolynomial *read_term(struct isl_stream *s,
1807
 
        __isl_keep isl_basic_map *bmap, struct vars *v)
 
1588
static __isl_give isl_pw_qpolynomial *read_term(struct isl_stream *s,
 
1589
        __isl_keep isl_map *map, struct vars *v)
1808
1590
{
1809
1591
        struct isl_token *tok;
1810
 
        struct isl_qpolynomial *qp;
 
1592
        isl_pw_qpolynomial *pwqp;
1811
1593
 
1812
 
        qp = read_factor(s, bmap, v);
 
1594
        pwqp = read_factor(s, map, v);
1813
1595
 
1814
1596
        for (;;) {
1815
1597
                tok = next_token(s);
1816
1598
                if (!tok)
1817
 
                        return qp;
 
1599
                        return pwqp;
1818
1600
 
1819
1601
                if (tok->type == '+') {
1820
 
                        struct isl_qpolynomial *qp2;
 
1602
                        isl_pw_qpolynomial *pwqp2;
1821
1603
 
1822
1604
                        isl_token_free(tok);
1823
 
                        qp2 = read_factor(s, bmap, v);
1824
 
                        qp = isl_qpolynomial_add(qp, qp2);
 
1605
                        pwqp2 = read_factor(s, map, v);
 
1606
                        pwqp = isl_pw_qpolynomial_add(pwqp, pwqp2);
1825
1607
                } else if (tok->type == '-') {
1826
 
                        struct isl_qpolynomial *qp2;
 
1608
                        isl_pw_qpolynomial *pwqp2;
1827
1609
 
1828
1610
                        isl_token_free(tok);
1829
 
                        qp2 = read_factor(s, bmap, v);
1830
 
                        qp = isl_qpolynomial_sub(qp, qp2);
 
1611
                        pwqp2 = read_factor(s, map, v);
 
1612
                        pwqp = isl_pw_qpolynomial_sub(pwqp, pwqp2);
1831
1613
                } else if (tok->type == ISL_TOKEN_VALUE &&
1832
1614
                            isl_int_is_neg(tok->u.v)) {
1833
 
                        struct isl_qpolynomial *qp2;
 
1615
                        isl_pw_qpolynomial *pwqp2;
1834
1616
 
1835
1617
                        isl_stream_push_token(s, tok);
1836
 
                        qp2 = read_factor(s, bmap, v);
1837
 
                        qp = isl_qpolynomial_add(qp, qp2);
 
1618
                        pwqp2 = read_factor(s, map, v);
 
1619
                        pwqp = isl_pw_qpolynomial_add(pwqp, pwqp2);
1838
1620
                } else {
1839
1621
                        isl_stream_push_token(s, tok);
1840
1622
                        break;
1841
1623
                }
1842
1624
        }
1843
1625
 
1844
 
        return qp;
 
1626
        return pwqp;
1845
1627
}
1846
1628
 
1847
1629
static __isl_give isl_map *read_optional_disjuncts(struct isl_stream *s,
1848
 
        __isl_take isl_basic_map *bmap, struct vars *v)
 
1630
        __isl_take isl_map *map, struct vars *v)
1849
1631
{
1850
1632
        struct isl_token *tok;
1851
 
        struct isl_map *map;
1852
1633
 
1853
1634
        tok = isl_stream_next_token(s);
1854
1635
        if (!tok) {
1855
1636
                isl_stream_error(s, NULL, "unexpected EOF");
1856
1637
                goto error;
1857
1638
        }
1858
 
        map = isl_map_from_basic_map(isl_basic_map_copy(bmap));
1859
1639
        if (tok->type == ':' ||
1860
1640
            (tok->type == ISL_TOKEN_OR && !strcmp(tok->u.s, "|"))) {
1861
1641
                isl_token_free(tok);
1862
 
                map = isl_map_intersect(map,
1863
 
                            read_disjuncts(s, v, isl_basic_map_copy(bmap)));
 
1642
                map = read_disjuncts(s, v, map);
1864
1643
        } else
1865
1644
                isl_stream_push_token(s, tok);
1866
1645
 
1867
 
        isl_basic_map_free(bmap);
1868
 
 
1869
1646
        return map;
1870
1647
error:
1871
 
        isl_basic_map_free(bmap);
 
1648
        isl_map_free(map);
1872
1649
        return NULL;
1873
1650
}
1874
1651
 
1875
1652
static struct isl_obj obj_read_poly(struct isl_stream *s,
1876
 
        __isl_take isl_basic_map *bmap, struct vars *v, int n)
 
1653
        __isl_take isl_map *map, struct vars *v, int n)
1877
1654
{
1878
1655
        struct isl_obj obj = { isl_obj_pw_qpolynomial, NULL };
1879
 
        struct isl_pw_qpolynomial *pwqp;
1880
 
        struct isl_qpolynomial *qp;
1881
 
        struct isl_map *map;
 
1656
        isl_pw_qpolynomial *pwqp;
1882
1657
        struct isl_set *set;
1883
1658
 
1884
 
        qp = read_term(s, bmap, v);
1885
 
        map = read_optional_disjuncts(s, bmap, v);
 
1659
        pwqp = read_term(s, map, v);
 
1660
        map = read_optional_disjuncts(s, map, v);
1886
1661
        set = isl_map_range(map);
1887
1662
 
1888
 
        pwqp = isl_pw_qpolynomial_alloc(set, qp);
 
1663
        pwqp = isl_pw_qpolynomial_intersect_domain(pwqp, set);
1889
1664
 
1890
1665
        vars_drop(v, v->n - n);
1891
1666
 
1894
1669
}
1895
1670
 
1896
1671
static struct isl_obj obj_read_poly_or_fold(struct isl_stream *s,
1897
 
        __isl_take isl_basic_map *bmap, struct vars *v, int n)
 
1672
        __isl_take isl_set *set, struct vars *v, int n)
1898
1673
{
1899
1674
        struct isl_obj obj = { isl_obj_pw_qpolynomial_fold, NULL };
1900
 
        isl_qpolynomial *qp;
1901
 
        isl_qpolynomial_fold *fold = NULL;
1902
 
        isl_pw_qpolynomial_fold *pwf;
1903
 
        isl_map *map;
1904
 
        isl_set *set;
 
1675
        isl_pw_qpolynomial *pwqp;
 
1676
        isl_pw_qpolynomial_fold *pwf = NULL;
1905
1677
 
1906
1678
        if (!isl_stream_eat_if_available(s, ISL_TOKEN_MAX))
1907
 
                return obj_read_poly(s, bmap, v, n);
 
1679
                return obj_read_poly(s, set, v, n);
1908
1680
 
1909
1681
        if (isl_stream_eat(s, '('))
1910
1682
                goto error;
1911
1683
 
1912
 
        qp = read_term(s, bmap, v);
1913
 
        fold = isl_qpolynomial_fold_alloc(isl_fold_max, qp);
 
1684
        pwqp = read_term(s, set, v);
 
1685
        pwf = isl_pw_qpolynomial_fold_from_pw_qpolynomial(isl_fold_max, pwqp);
1914
1686
 
1915
1687
        while (isl_stream_eat_if_available(s, ',')) {
1916
 
                isl_qpolynomial_fold *fold_i;
1917
 
                qp = read_term(s, bmap, v);
1918
 
                fold_i = isl_qpolynomial_fold_alloc(isl_fold_max, qp);
1919
 
                fold = isl_qpolynomial_fold_fold(fold, fold_i);
 
1688
                isl_pw_qpolynomial_fold *pwf_i;
 
1689
                pwqp = read_term(s, set, v);
 
1690
                pwf_i = isl_pw_qpolynomial_fold_from_pw_qpolynomial(isl_fold_max,
 
1691
                                                                        pwqp);
 
1692
                pwf = isl_pw_qpolynomial_fold_fold(pwf, pwf_i);
1920
1693
        }
1921
1694
 
1922
1695
        if (isl_stream_eat(s, ')'))
1923
1696
                goto error;
1924
1697
 
1925
 
        map = read_optional_disjuncts(s, bmap, v);
1926
 
        set = isl_map_range(map);
1927
 
        pwf = isl_pw_qpolynomial_fold_alloc(isl_fold_max, set, fold);
 
1698
        set = read_optional_disjuncts(s, set, v);
 
1699
        pwf = isl_pw_qpolynomial_fold_intersect_domain(pwf, set);
1928
1700
 
1929
1701
        vars_drop(v, v->n - n);
1930
1702
 
1931
1703
        obj.v = pwf;
1932
1704
        return obj;
1933
1705
error:
1934
 
        isl_basic_map_free(bmap);
1935
 
        isl_qpolynomial_fold_free(fold);
 
1706
        isl_set_free(set);
 
1707
        isl_pw_qpolynomial_fold_free(pwf);
1936
1708
        obj.type = isl_obj_none;
1937
1709
        return obj;
1938
1710
}
1956
1728
}
1957
1729
 
1958
1730
static struct isl_obj obj_read_body(struct isl_stream *s,
1959
 
        __isl_take isl_basic_map *bmap, struct vars *v)
 
1731
        __isl_take isl_map *map, struct vars *v)
1960
1732
{
1961
 
        struct isl_map *map = NULL;
1962
1733
        struct isl_token *tok;
1963
1734
        struct isl_obj obj = { isl_obj_set, NULL };
1964
1735
        int n = v->n;
1965
1736
 
1966
1737
        if (is_rational(s))
1967
 
                bmap = isl_basic_map_set_rational(bmap);
 
1738
                map = isl_map_set_rational(map);
 
1739
 
 
1740
        if (isl_stream_next_token_is(s, ':')) {
 
1741
                obj.type = isl_obj_set;
 
1742
                obj.v = read_optional_disjuncts(s, map, v);
 
1743
                return obj;
 
1744
        }
1968
1745
 
1969
1746
        if (!next_is_tuple(s))
1970
 
                return obj_read_poly_or_fold(s, bmap, v, n);
 
1747
                return obj_read_poly_or_fold(s, map, v, n);
1971
1748
 
1972
 
        bmap = read_tuple(s, bmap, isl_dim_in, v);
1973
 
        if (!bmap)
 
1749
        map = read_tuple(s, map, isl_dim_in, v);
 
1750
        if (!map)
1974
1751
                goto error;
1975
1752
        tok = isl_stream_next_token(s);
1976
1753
        if (tok && tok->type == ISL_TOKEN_TO) {
1977
1754
                obj.type = isl_obj_map;
1978
1755
                isl_token_free(tok);
1979
1756
                if (!next_is_tuple(s)) {
1980
 
                        bmap = isl_basic_map_reverse(bmap);
1981
 
                        return obj_read_poly_or_fold(s, bmap, v, n);
 
1757
                        isl_set *set = isl_map_domain(map);
 
1758
                        return obj_read_poly_or_fold(s, set, v, n);
1982
1759
                }
1983
 
                bmap = read_tuple(s, bmap, isl_dim_out, v);
1984
 
                if (!bmap)
 
1760
                map = read_tuple(s, map, isl_dim_out, v);
 
1761
                if (!map)
1985
1762
                        goto error;
1986
1763
        } else {
1987
 
                bmap = isl_basic_map_reverse(bmap);
 
1764
                map = isl_map_reverse(map);
1988
1765
                if (tok)
1989
1766
                        isl_stream_push_token(s, tok);
1990
1767
        }
1991
1768
 
1992
 
        map = read_optional_disjuncts(s, bmap, v);
 
1769
        map = read_optional_disjuncts(s, map, v);
1993
1770
 
1994
1771
        vars_drop(v, v->n - n);
1995
1772
 
1996
1773
        obj.v = map;
1997
1774
        return obj;
1998
1775
error:
1999
 
        isl_basic_map_free(bmap);
 
1776
        isl_map_free(map);
2000
1777
        obj.type = isl_obj_none;
2001
1778
        return obj;
2002
1779
}
2048
1825
            obj2.type == isl_obj_pw_qpolynomial_fold)
2049
1826
                obj2 = to_union(ctx, obj2);
2050
1827
        isl_assert(ctx, obj1.type == obj2.type, goto error);
2051
 
        if (obj1.type == isl_obj_map && !isl_map_has_equal_dim(obj1.v, obj2.v)) {
 
1828
        if (obj1.type == isl_obj_map && !isl_map_has_equal_space(obj1.v, obj2.v)) {
2052
1829
                obj1 = to_union(ctx, obj1);
2053
1830
                obj2 = to_union(ctx, obj2);
2054
1831
        }
2055
 
        if (obj1.type == isl_obj_set && !isl_set_has_equal_dim(obj1.v, obj2.v)) {
 
1832
        if (obj1.type == isl_obj_set && !isl_set_has_equal_space(obj1.v, obj2.v)) {
2056
1833
                obj1 = to_union(ctx, obj1);
2057
1834
                obj2 = to_union(ctx, obj2);
2058
1835
        }
2059
1836
        if (obj1.type == isl_obj_pw_qpolynomial &&
2060
 
            !isl_pw_qpolynomial_has_equal_dim(obj1.v, obj2.v)) {
 
1837
            !isl_pw_qpolynomial_has_equal_space(obj1.v, obj2.v)) {
2061
1838
                obj1 = to_union(ctx, obj1);
2062
1839
                obj2 = to_union(ctx, obj2);
2063
1840
        }
2064
1841
        if (obj1.type == isl_obj_pw_qpolynomial_fold &&
2065
 
            !isl_pw_qpolynomial_fold_has_equal_dim(obj1.v, obj2.v)) {
 
1842
            !isl_pw_qpolynomial_fold_has_equal_space(obj1.v, obj2.v)) {
2066
1843
                obj1 = to_union(ctx, obj1);
2067
1844
                obj2 = to_union(ctx, obj2);
2068
1845
        }
2076
1853
        return obj1;
2077
1854
}
2078
1855
 
2079
 
static struct isl_obj obj_read(struct isl_stream *s, int nparam)
 
1856
static struct isl_obj obj_read(struct isl_stream *s)
2080
1857
{
2081
 
        isl_basic_map *bmap = NULL;
 
1858
        isl_map *map = NULL;
2082
1859
        struct isl_token *tok;
2083
1860
        struct vars *v = NULL;
2084
1861
        struct isl_obj obj = { isl_obj_set, NULL };
2104
1881
                }
2105
1882
                isl_stream_push_token(s, tok2);
2106
1883
                isl_stream_push_token(s, tok);
2107
 
                map = map_read_polylib(s, nparam);
 
1884
                map = map_read_polylib(s);
2108
1885
                if (!map)
2109
1886
                        goto error;
2110
 
                if (isl_map_dim(map, isl_dim_in) > 0)
 
1887
                if (isl_map_may_be_set(map))
 
1888
                        obj.v = isl_map_range(map);
 
1889
                else {
2111
1890
                        obj.type = isl_obj_map;
2112
 
                obj.v = map;
 
1891
                        obj.v = map;
 
1892
                }
2113
1893
                return obj;
2114
1894
        }
2115
1895
        v = vars_new(s->ctx);
2117
1897
                isl_stream_push_token(s, tok);
2118
1898
                goto error;
2119
1899
        }
2120
 
        bmap = isl_basic_map_alloc(s->ctx, 0, 0, 0, 0, 0, 0);
 
1900
        map = isl_map_universe(isl_space_params_alloc(s->ctx, 0));
2121
1901
        if (tok->type == '[') {
2122
1902
                isl_stream_push_token(s, tok);
2123
 
                bmap = read_tuple(s, bmap, isl_dim_param, v);
2124
 
                if (!bmap)
 
1903
                map = read_tuple(s, map, isl_dim_param, v);
 
1904
                if (!map)
2125
1905
                        goto error;
2126
 
                if (nparam >= 0)
2127
 
                        isl_assert(s->ctx, nparam == v->n, goto error);
2128
1906
                tok = isl_stream_next_token(s);
2129
1907
                if (!tok || tok->type != ISL_TOKEN_TO) {
2130
1908
                        isl_stream_error(s, tok, "expecting '->'");
2134
1912
                }
2135
1913
                isl_token_free(tok);
2136
1914
                tok = isl_stream_next_token(s);
2137
 
        } else if (nparam > 0)
2138
 
                bmap = isl_basic_map_add(bmap, isl_dim_param, nparam);
 
1915
        }
2139
1916
        if (!tok || tok->type != '{') {
2140
1917
                isl_stream_error(s, tok, "expecting '{'");
2141
1918
                if (tok)
2151
1928
                isl_token_free(tok);
2152
1929
                if (isl_stream_eat(s, '='))
2153
1930
                        goto error;
2154
 
                bmap = read_tuple(s, bmap, isl_dim_param, v);
2155
 
                if (!bmap)
 
1931
                map = read_tuple(s, map, isl_dim_param, v);
 
1932
                if (!map)
2156
1933
                        goto error;
2157
 
                if (nparam >= 0)
2158
 
                        isl_assert(s->ctx, nparam == v->n, goto error);
2159
1934
        } else if (tok->type == '}') {
2160
1935
                obj.type = isl_obj_union_set;
2161
 
                obj.v = isl_union_set_empty(isl_basic_map_get_dim(bmap));
 
1936
                obj.v = isl_union_set_empty(isl_map_get_space(map));
2162
1937
                isl_token_free(tok);
2163
1938
                goto done;
2164
1939
        } else
2167
1942
        for (;;) {
2168
1943
                struct isl_obj o;
2169
1944
                tok = NULL;
2170
 
                o = obj_read_body(s, isl_basic_map_copy(bmap), v);
 
1945
                o = obj_read_body(s, isl_map_copy(map), v);
2171
1946
                if (o.type == isl_obj_none || !o.v)
2172
1947
                        goto error;
2173
1948
                if (!obj.v)
2197
1972
        }
2198
1973
done:
2199
1974
        vars_free(v);
2200
 
        isl_basic_map_free(bmap);
 
1975
        isl_map_free(map);
2201
1976
 
2202
1977
        return obj;
2203
1978
error:
2204
 
        isl_basic_map_free(bmap);
 
1979
        isl_map_free(map);
2205
1980
        obj.type->free(obj.v);
2206
1981
        if (v)
2207
1982
                vars_free(v);
2211
1986
 
2212
1987
struct isl_obj isl_stream_read_obj(struct isl_stream *s)
2213
1988
{
2214
 
        return obj_read(s, -1);
 
1989
        return obj_read(s);
2215
1990
}
2216
1991
 
2217
 
__isl_give isl_map *isl_stream_read_map(struct isl_stream *s, int nparam)
 
1992
__isl_give isl_map *isl_stream_read_map(struct isl_stream *s)
2218
1993
{
2219
1994
        struct isl_obj obj;
2220
1995
 
2221
 
        obj = obj_read(s, nparam);
 
1996
        obj = obj_read(s);
2222
1997
        if (obj.v)
2223
1998
                isl_assert(s->ctx, obj.type == isl_obj_map ||
2224
1999
                                   obj.type == isl_obj_set, goto error);
2229
2004
        return NULL;
2230
2005
}
2231
2006
 
2232
 
__isl_give isl_set *isl_stream_read_set(struct isl_stream *s, int nparam)
 
2007
__isl_give isl_set *isl_stream_read_set(struct isl_stream *s)
2233
2008
{
2234
2009
        struct isl_obj obj;
2235
2010
 
2236
 
        obj = obj_read(s, nparam);
2237
 
        if (obj.v)
 
2011
        obj = obj_read(s);
 
2012
        if (obj.v) {
 
2013
                if (obj.type == isl_obj_map && isl_map_may_be_set(obj.v)) {
 
2014
                        obj.v = isl_map_range(obj.v);
 
2015
                        obj.type = isl_obj_set;
 
2016
                }
2238
2017
                isl_assert(s->ctx, obj.type == isl_obj_set, goto error);
 
2018
        }
2239
2019
 
2240
2020
        return obj.v;
2241
2021
error:
2247
2027
{
2248
2028
        struct isl_obj obj;
2249
2029
 
2250
 
        obj = obj_read(s, -1);
 
2030
        obj = obj_read(s);
2251
2031
        if (obj.type == isl_obj_map) {
2252
2032
                obj.type = isl_obj_union_map;
2253
2033
                obj.v = isl_union_map_from_map(obj.v);
2270
2050
{
2271
2051
        struct isl_obj obj;
2272
2052
 
2273
 
        obj = obj_read(s, -1);
 
2053
        obj = obj_read(s);
2274
2054
        if (obj.type == isl_obj_set) {
2275
2055
                obj.type = isl_obj_union_set;
2276
2056
                obj.v = isl_union_set_from_set(obj.v);
2284
2064
        return NULL;
2285
2065
}
2286
2066
 
2287
 
static struct isl_basic_map *basic_map_read(struct isl_stream *s, int nparam)
 
2067
static __isl_give isl_basic_map *basic_map_read(struct isl_stream *s)
2288
2068
{
2289
2069
        struct isl_obj obj;
2290
2070
        struct isl_map *map;
2291
2071
        struct isl_basic_map *bmap;
2292
2072
 
2293
 
        obj = obj_read(s, nparam);
 
2073
        obj = obj_read(s);
2294
2074
        map = obj.v;
2295
2075
        if (!map)
2296
2076
                return NULL;
2310
2090
        return NULL;
2311
2091
}
2312
2092
 
 
2093
static __isl_give isl_basic_set *basic_set_read(struct isl_stream *s)
 
2094
{
 
2095
        isl_basic_map *bmap;
 
2096
        bmap = basic_map_read(s);
 
2097
        if (!bmap)
 
2098
                return NULL;
 
2099
        if (!isl_basic_map_may_be_set(bmap))
 
2100
                isl_die(s->ctx, isl_error_invalid,
 
2101
                        "input is not a set", goto error);
 
2102
        return isl_basic_map_range(bmap);
 
2103
error:
 
2104
        isl_basic_map_free(bmap);
 
2105
        return NULL;
 
2106
}
 
2107
 
2313
2108
__isl_give isl_basic_map *isl_basic_map_read_from_file(isl_ctx *ctx,
2314
 
                FILE *input, int nparam)
 
2109
        FILE *input)
2315
2110
{
2316
2111
        struct isl_basic_map *bmap;
2317
2112
        struct isl_stream *s = isl_stream_new_file(ctx, input);
2318
2113
        if (!s)
2319
2114
                return NULL;
2320
 
        bmap = basic_map_read(s, nparam);
 
2115
        bmap = basic_map_read(s);
2321
2116
        isl_stream_free(s);
2322
2117
        return bmap;
2323
2118
}
2324
2119
 
2325
2120
__isl_give isl_basic_set *isl_basic_set_read_from_file(isl_ctx *ctx,
2326
 
                FILE *input, int nparam)
 
2121
        FILE *input)
2327
2122
{
2328
 
        struct isl_basic_map *bmap;
2329
 
        bmap = isl_basic_map_read_from_file(ctx, input, nparam);
2330
 
        if (!bmap)
 
2123
        isl_basic_set *bset;
 
2124
        struct isl_stream *s = isl_stream_new_file(ctx, input);
 
2125
        if (!s)
2331
2126
                return NULL;
2332
 
        isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
2333
 
        return (struct isl_basic_set *)bmap;
2334
 
error:
2335
 
        isl_basic_map_free(bmap);
2336
 
        return NULL;
 
2127
        bset = basic_set_read(s);
 
2128
        isl_stream_free(s);
 
2129
        return bset;
2337
2130
}
2338
2131
 
2339
2132
struct isl_basic_map *isl_basic_map_read_from_str(struct isl_ctx *ctx,
2340
 
                const char *str, int nparam)
 
2133
        const char *str)
2341
2134
{
2342
2135
        struct isl_basic_map *bmap;
2343
2136
        struct isl_stream *s = isl_stream_new_str(ctx, str);
2344
2137
        if (!s)
2345
2138
                return NULL;
2346
 
        bmap = basic_map_read(s, nparam);
 
2139
        bmap = basic_map_read(s);
2347
2140
        isl_stream_free(s);
2348
2141
        return bmap;
2349
2142
}
2350
2143
 
2351
2144
struct isl_basic_set *isl_basic_set_read_from_str(struct isl_ctx *ctx,
2352
 
                const char *str, int nparam)
 
2145
        const char *str)
2353
2146
{
2354
 
        struct isl_basic_map *bmap;
2355
 
        bmap = isl_basic_map_read_from_str(ctx, str, nparam);
2356
 
        if (!bmap)
 
2147
        isl_basic_set *bset;
 
2148
        struct isl_stream *s = isl_stream_new_str(ctx, str);
 
2149
        if (!s)
2357
2150
                return NULL;
2358
 
        isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
2359
 
        return (struct isl_basic_set *)bmap;
2360
 
error:
2361
 
        isl_basic_map_free(bmap);
2362
 
        return NULL;
 
2151
        bset = basic_set_read(s);
 
2152
        isl_stream_free(s);
 
2153
        return bset;
2363
2154
}
2364
2155
 
2365
2156
__isl_give isl_map *isl_map_read_from_file(struct isl_ctx *ctx,
2366
 
                FILE *input, int nparam)
 
2157
        FILE *input)
2367
2158
{
2368
2159
        struct isl_map *map;
2369
2160
        struct isl_stream *s = isl_stream_new_file(ctx, input);
2370
2161
        if (!s)
2371
2162
                return NULL;
2372
 
        map = isl_stream_read_map(s, nparam);
 
2163
        map = isl_stream_read_map(s);
2373
2164
        isl_stream_free(s);
2374
2165
        return map;
2375
2166
}
2376
2167
 
2377
2168
__isl_give isl_map *isl_map_read_from_str(struct isl_ctx *ctx,
2378
 
                const char *str, int nparam)
 
2169
        const char *str)
2379
2170
{
2380
2171
        struct isl_map *map;
2381
2172
        struct isl_stream *s = isl_stream_new_str(ctx, str);
2382
2173
        if (!s)
2383
2174
                return NULL;
2384
 
        map = isl_stream_read_map(s, nparam);
 
2175
        map = isl_stream_read_map(s);
2385
2176
        isl_stream_free(s);
2386
2177
        return map;
2387
2178
}
2388
2179
 
2389
2180
__isl_give isl_set *isl_set_read_from_file(struct isl_ctx *ctx,
2390
 
                FILE *input, int nparam)
 
2181
        FILE *input)
2391
2182
{
2392
 
        struct isl_map *map;
2393
 
        map = isl_map_read_from_file(ctx, input, nparam);
2394
 
        if (!map)
 
2183
        isl_set *set;
 
2184
        struct isl_stream *s = isl_stream_new_file(ctx, input);
 
2185
        if (!s)
2395
2186
                return NULL;
2396
 
        isl_assert(ctx, isl_map_n_in(map) == 0, goto error);
2397
 
        return (struct isl_set *)map;
2398
 
error:
2399
 
        isl_map_free(map);
2400
 
        return NULL;
 
2187
        set = isl_stream_read_set(s);
 
2188
        isl_stream_free(s);
 
2189
        return set;
2401
2190
}
2402
2191
 
2403
2192
struct isl_set *isl_set_read_from_str(struct isl_ctx *ctx,
2404
 
                const char *str, int nparam)
 
2193
        const char *str)
2405
2194
{
2406
 
        struct isl_map *map;
2407
 
        map = isl_map_read_from_str(ctx, str, nparam);
2408
 
        if (!map)
 
2195
        isl_set *set;
 
2196
        struct isl_stream *s = isl_stream_new_str(ctx, str);
 
2197
        if (!s)
2409
2198
                return NULL;
2410
 
        isl_assert(ctx, isl_map_n_in(map) == 0, goto error);
2411
 
        return (struct isl_set *)map;
2412
 
error:
2413
 
        isl_map_free(map);
2414
 
        return NULL;
 
2199
        set = isl_stream_read_set(s);
 
2200
        isl_stream_free(s);
 
2201
        return set;
2415
2202
}
2416
2203
 
2417
2204
__isl_give isl_union_map *isl_union_map_read_from_file(isl_ctx *ctx,
2518
2305
{
2519
2306
        struct isl_obj obj;
2520
2307
 
2521
 
        obj = obj_read(s, -1);
 
2308
        obj = obj_read(s);
2522
2309
        if (obj.v)
2523
2310
                isl_assert(s->ctx, obj.type == isl_obj_pw_qpolynomial,
2524
2311
                           goto error);
2552
2339
        isl_stream_free(s);
2553
2340
        return pwqp;
2554
2341
}
 
2342
 
 
2343
/* Read an affine expression from "s" with domain (space) "dom".
 
2344
 * We call accept_affine to parse a possibly piecewise affine expression
 
2345
 * and then check that the result is a single affine expression on
 
2346
 * a universe domain.
 
2347
 */
 
2348
static __isl_give isl_aff *read_aff_with_dom(struct isl_stream *s,
 
2349
        __isl_take isl_set *dom, struct vars *v)
 
2350
{
 
2351
        isl_aff *aff = NULL;
 
2352
        isl_pw_aff *pwaff = NULL;
 
2353
 
 
2354
        if (!isl_set_plain_is_universe(dom))
 
2355
                isl_die(s->ctx, isl_error_invalid,
 
2356
                        "expecting universe domain", goto error);
 
2357
 
 
2358
        if (!isl_set_is_params(dom) && isl_stream_eat(s, ISL_TOKEN_TO))
 
2359
                goto error;
 
2360
 
 
2361
        if (isl_stream_eat(s, '['))
 
2362
                goto error;
 
2363
 
 
2364
        pwaff = accept_affine(s, isl_set_get_space(dom), v);
 
2365
 
 
2366
        if (isl_stream_eat(s, ']'))
 
2367
                goto error;
 
2368
        if (isl_stream_eat(s, '}'))
 
2369
                goto error;
 
2370
 
 
2371
        if (!pwaff)
 
2372
                goto error;
 
2373
 
 
2374
        if (pwaff->n != 1)
 
2375
                isl_die(s->ctx, isl_error_invalid,
 
2376
                        "expecting single affine expression", goto error);
 
2377
        if (!isl_set_plain_is_universe(pwaff->p[0].set))
 
2378
                isl_die(s->ctx, isl_error_invalid,
 
2379
                        "expecting universe domain", goto error);
 
2380
 
 
2381
        aff = isl_aff_copy(pwaff->p[0].aff);
 
2382
 
 
2383
        vars_free(v);
 
2384
        isl_pw_aff_free(pwaff);
 
2385
        isl_set_free(dom);
 
2386
        return aff;
 
2387
error:
 
2388
        vars_free(v);
 
2389
        isl_pw_aff_free(pwaff);
 
2390
        isl_set_free(dom);
 
2391
        return NULL;
 
2392
}
 
2393
 
 
2394
/* Is the next token an identifer not in "v"?
 
2395
 */
 
2396
static int next_is_fresh_ident(struct isl_stream *s, struct vars *v)
 
2397
{
 
2398
        int n = v->n;
 
2399
        int fresh;
 
2400
        struct isl_token *tok;
 
2401
 
 
2402
        tok = isl_stream_next_token(s);
 
2403
        if (!tok)
 
2404
                return 0;
 
2405
        fresh = tok->type == ISL_TOKEN_IDENT && vars_pos(v, tok->u.s, -1) >= n;
 
2406
        isl_stream_push_token(s, tok);
 
2407
 
 
2408
        vars_drop(v, v->n - n);
 
2409
 
 
2410
        return fresh;
 
2411
}
 
2412
 
 
2413
/* First read the domain of the affine expression, which may be
 
2414
 * a parameter space or a set.
 
2415
 * The tricky part is that we don't know if the domain is a set or not,
 
2416
 * so when we are trying to read the domain, we may actually be reading
 
2417
 * the affine expression itself (defined on a parameter domains)
 
2418
 * If the tuple we are reading is named, we assume it's the domain.
 
2419
 * Also, if inside the tuple, the first thing we find is a nested tuple
 
2420
 * or a new identifier, we again assume it's the domain.
 
2421
 * Otherwise, we assume we are reading an affine expression.
 
2422
 */
 
2423
static __isl_give isl_set *read_aff_domain(struct isl_stream *s,
 
2424
        __isl_take isl_set *dom, struct vars *v)
 
2425
{
 
2426
        struct isl_token *tok;
 
2427
 
 
2428
        tok = isl_stream_next_token(s);
 
2429
        if (tok && (tok->type == ISL_TOKEN_IDENT || tok->is_keyword)) {
 
2430
                isl_stream_push_token(s, tok);
 
2431
                return read_tuple(s, dom, isl_dim_set, v);
 
2432
        }
 
2433
        if (!tok || tok->type != '[') {
 
2434
                isl_stream_error(s, tok, "expecting '['");
 
2435
                goto error;
 
2436
        }
 
2437
        if (next_is_tuple(s) || next_is_fresh_ident(s, v)) {
 
2438
                isl_stream_push_token(s, tok);
 
2439
                dom = read_tuple(s, dom, isl_dim_set, v);
 
2440
        } else
 
2441
                isl_stream_push_token(s, tok);
 
2442
 
 
2443
        return dom;
 
2444
error:
 
2445
        if (tok)
 
2446
                isl_stream_push_token(s, tok);
 
2447
        vars_free(v);
 
2448
        isl_set_free(dom);
 
2449
        return NULL;
 
2450
}
 
2451
 
 
2452
/* Read an affine expression from "s".
 
2453
 * We first read the domain of the affine expression, which may be
 
2454
 * a parameter space or a set, and then call read_aff_with_dom.
 
2455
 */
 
2456
__isl_give isl_aff *isl_stream_read_aff(struct isl_stream *s)
 
2457
{
 
2458
        struct vars *v;
 
2459
        isl_set *dom = NULL;
 
2460
 
 
2461
        v = vars_new(s->ctx);
 
2462
        if (!v)
 
2463
                return NULL;
 
2464
 
 
2465
        dom = isl_set_universe(isl_space_params_alloc(s->ctx, 0));
 
2466
        if (next_is_tuple(s)) {
 
2467
                dom = read_tuple(s, dom, isl_dim_param, v);
 
2468
                if (isl_stream_eat(s, ISL_TOKEN_TO))
 
2469
                        goto error;
 
2470
        }
 
2471
        if (isl_stream_eat(s, '{'))
 
2472
                goto error;
 
2473
 
 
2474
        dom = read_aff_domain(s, dom, v);
 
2475
        return read_aff_with_dom(s, dom, v);
 
2476
error:
 
2477
        vars_free(v);
 
2478
        isl_set_free(dom);
 
2479
        return NULL;
 
2480
}
 
2481
 
 
2482
/* Read a piecewise affine expression from "s" with domain (space) "dom".
 
2483
 */
 
2484
static __isl_give isl_pw_aff *read_pw_aff_with_dom(struct isl_stream *s,
 
2485
        __isl_take isl_set *dom, struct vars *v)
 
2486
{
 
2487
        isl_pw_aff *pwaff = NULL;
 
2488
 
 
2489
        if (!isl_set_is_params(dom) && isl_stream_eat(s, ISL_TOKEN_TO))
 
2490
                goto error;
 
2491
 
 
2492
        if (isl_stream_eat(s, '['))
 
2493
                goto error;
 
2494
 
 
2495
        pwaff = accept_affine(s, isl_set_get_space(dom), v);
 
2496
 
 
2497
        if (isl_stream_eat(s, ']'))
 
2498
                goto error;
 
2499
 
 
2500
        dom = read_optional_disjuncts(s, dom, v);
 
2501
        pwaff = isl_pw_aff_intersect_domain(pwaff, dom);
 
2502
 
 
2503
        return pwaff;
 
2504
error:
 
2505
        isl_set_free(dom);
 
2506
        isl_pw_aff_free(pwaff);
 
2507
        return NULL;
 
2508
}
 
2509
 
 
2510
__isl_give isl_pw_aff *isl_stream_read_pw_aff(struct isl_stream *s)
 
2511
{
 
2512
        struct vars *v;
 
2513
        isl_set *dom = NULL;
 
2514
        isl_set *aff_dom;
 
2515
        isl_pw_aff *pa = NULL;
 
2516
        int n;
 
2517
 
 
2518
        v = vars_new(s->ctx);
 
2519
        if (!v)
 
2520
                return NULL;
 
2521
 
 
2522
        dom = isl_set_universe(isl_space_params_alloc(s->ctx, 0));
 
2523
        if (next_is_tuple(s)) {
 
2524
                dom = read_tuple(s, dom, isl_dim_param, v);
 
2525
                if (isl_stream_eat(s, ISL_TOKEN_TO))
 
2526
                        goto error;
 
2527
        }
 
2528
        if (isl_stream_eat(s, '{'))
 
2529
                goto error;
 
2530
 
 
2531
        n = v->n;
 
2532
        aff_dom = read_aff_domain(s, isl_set_copy(dom), v);
 
2533
        pa = read_pw_aff_with_dom(s, aff_dom, v);
 
2534
        vars_drop(v, v->n - n);
 
2535
 
 
2536
        while (isl_stream_eat_if_available(s, ';')) {
 
2537
                isl_pw_aff *pa_i;
 
2538
 
 
2539
                n = v->n;
 
2540
                aff_dom = read_aff_domain(s, isl_set_copy(dom), v);
 
2541
                pa_i = read_pw_aff_with_dom(s, aff_dom, v);
 
2542
                vars_drop(v, v->n - n);
 
2543
 
 
2544
                pa = isl_pw_aff_add(pa, pa_i);
 
2545
        }
 
2546
 
 
2547
        if (isl_stream_eat(s, '}'))
 
2548
                goto error;
 
2549
 
 
2550
        vars_free(v);
 
2551
        isl_set_free(dom);
 
2552
        return pa;
 
2553
error:
 
2554
        vars_free(v);
 
2555
        isl_set_free(dom);
 
2556
        isl_pw_aff_free(pa);
 
2557
        return NULL;
 
2558
}
 
2559
 
 
2560
__isl_give isl_aff *isl_aff_read_from_str(isl_ctx *ctx, const char *str)
 
2561
{
 
2562
        isl_aff *aff;
 
2563
        struct isl_stream *s = isl_stream_new_str(ctx, str);
 
2564
        if (!s)
 
2565
                return NULL;
 
2566
        aff = isl_stream_read_aff(s);
 
2567
        isl_stream_free(s);
 
2568
        return aff;
 
2569
}
 
2570
 
 
2571
__isl_give isl_pw_aff *isl_pw_aff_read_from_str(isl_ctx *ctx, const char *str)
 
2572
{
 
2573
        isl_pw_aff *pa;
 
2574
        struct isl_stream *s = isl_stream_new_str(ctx, str);
 
2575
        if (!s)
 
2576
                return NULL;
 
2577
        pa = isl_stream_read_pw_aff(s);
 
2578
        isl_stream_free(s);
 
2579
        return pa;
 
2580
}
 
2581
 
 
2582
/* Read an isl_pw_multi_aff from "s".
 
2583
 * We currently read a generic object and if it turns out to be a set or
 
2584
 * a map, we convert that to an isl_pw_multi_aff.
 
2585
 * It would be more efficient if we were to construct the isl_pw_multi_aff
 
2586
 * directly.
 
2587
 */
 
2588
__isl_give isl_pw_multi_aff *isl_stream_read_pw_multi_aff(struct isl_stream *s)
 
2589
{
 
2590
        struct isl_obj obj;
 
2591
 
 
2592
        obj = obj_read(s);
 
2593
        if (!obj.v)
 
2594
                return NULL;
 
2595
 
 
2596
        if (obj.type == isl_obj_map)
 
2597
                return isl_pw_multi_aff_from_map(obj.v);
 
2598
        if (obj.type == isl_obj_set)
 
2599
                return isl_pw_multi_aff_from_set(obj.v);
 
2600
 
 
2601
        obj.type->free(obj.v);
 
2602
        isl_die(s->ctx, isl_error_invalid, "unexpected object type",
 
2603
                return NULL);
 
2604
}
 
2605
 
 
2606
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_read_from_str(isl_ctx *ctx,
 
2607
        const char *str)
 
2608
{
 
2609
        isl_pw_multi_aff *pma;
 
2610
        struct isl_stream *s = isl_stream_new_str(ctx, str);
 
2611
        if (!s)
 
2612
                return NULL;
 
2613
        pma = isl_stream_read_pw_multi_aff(s);
 
2614
        isl_stream_free(s);
 
2615
        return pma;
 
2616
}
 
2617
 
 
2618
/* Read a multi-affine expression from "s".
 
2619
 * We call isl_stream_read_pw_multi_aff to parse a possibly piecewise
 
2620
 * multi-affine expression and then check that the result is
 
2621
 * a single multi-affine expression on a universe domain.
 
2622
 */
 
2623
__isl_give isl_multi_aff *isl_stream_read_multi_aff(struct isl_stream *s)
 
2624
{
 
2625
        isl_pw_multi_aff *pma;
 
2626
        isl_multi_aff *maff;
 
2627
 
 
2628
        pma = isl_stream_read_pw_multi_aff(s);
 
2629
        if (!pma)
 
2630
                return NULL;
 
2631
        if (pma->n != 1)
 
2632
                isl_die(s->ctx, isl_error_invalid,
 
2633
                        "expecting single list of affine expressions",
 
2634
                        return isl_pw_multi_aff_free(pma));
 
2635
        if (!isl_set_plain_is_universe(pma->p[0].set))
 
2636
                isl_die(s->ctx, isl_error_invalid, "expecting universe domain",
 
2637
                        return isl_pw_multi_aff_free(pma));
 
2638
        maff = isl_multi_aff_copy(pma->p[0].maff);
 
2639
        isl_pw_multi_aff_free(pma);
 
2640
        return maff;
 
2641
}
 
2642
 
 
2643
__isl_give isl_multi_aff *isl_multi_aff_read_from_str(isl_ctx *ctx,
 
2644
        const char *str)
 
2645
{
 
2646
        isl_multi_aff *maff;
 
2647
        struct isl_stream *s = isl_stream_new_str(ctx, str);
 
2648
        if (!s)
 
2649
                return NULL;
 
2650
        maff = isl_stream_read_multi_aff(s);
 
2651
        isl_stream_free(s);
 
2652
        return maff;
 
2653
}
 
2654
 
 
2655
__isl_give isl_union_pw_qpolynomial *isl_stream_read_union_pw_qpolynomial(
 
2656
        struct isl_stream *s)
 
2657
{
 
2658
        struct isl_obj obj;
 
2659
 
 
2660
        obj = obj_read(s);
 
2661
        if (obj.type == isl_obj_pw_qpolynomial) {
 
2662
                obj.type = isl_obj_union_pw_qpolynomial;
 
2663
                obj.v = isl_union_pw_qpolynomial_from_pw_qpolynomial(obj.v);
 
2664
        }
 
2665
        if (obj.v)
 
2666
                isl_assert(s->ctx, obj.type == isl_obj_union_pw_qpolynomial,
 
2667
                           goto error);
 
2668
 
 
2669
        return obj.v;
 
2670
error:
 
2671
        obj.type->free(obj.v);
 
2672
        return NULL;
 
2673
}
 
2674
 
 
2675
__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_read_from_str(
 
2676
        isl_ctx *ctx, const char *str)
 
2677
{
 
2678
        isl_union_pw_qpolynomial *upwqp;
 
2679
        struct isl_stream *s = isl_stream_new_str(ctx, str);
 
2680
        if (!s)
 
2681
                return NULL;
 
2682
        upwqp = isl_stream_read_union_pw_qpolynomial(s);
 
2683
        isl_stream_free(s);
 
2684
        return upwqp;
 
2685
}