240
if (vars_add_anon(v) < 0)
245
var->def = isl_vec_alloc(s->ctx, 2 + v->n);
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);
252
mod = isl_vec_alloc(v->ctx, 1 + v->n);
256
isl_seq_cpy(mod->el, aff->el, aff->size);
257
isl_int_neg(mod->el[aff->size], tok->u.v);
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);
272
static __isl_give isl_vec *accept_affine_factor(struct isl_stream *s,
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);
236
aff = isl_pw_aff_sub(aff, q);
241
isl_pw_aff_free(aff);
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);
251
static __isl_give isl_pw_aff *accept_minmax(struct isl_stream *s,
252
__isl_take isl_space *dim, struct vars *v)
254
struct isl_token *tok;
255
isl_pw_aff_list *list = NULL;
258
tok = isl_stream_next_token(s);
261
min = tok->type == ISL_TOKEN_MIN;
264
if (isl_stream_eat(s, '('))
267
list = accept_affine_list(s, isl_space_copy(dim), v);
271
if (isl_stream_eat(s, ')'))
275
return min ? isl_pw_aff_list_min(list) : isl_pw_aff_list_max(list);
278
isl_pw_aff_list_free(list);
282
static __isl_give isl_pw_aff *accept_div(struct isl_stream *s,
283
__isl_take isl_space *dim, struct vars *v)
285
struct isl_token *tok;
289
isl_pw_aff *pwaff = NULL;
291
if (isl_stream_eat_if_available(s, ISL_TOKEN_FLOORD))
293
else if (isl_stream_eat_if_available(s, ISL_TOKEN_CEILD))
296
if (isl_stream_eat(s, '('))
299
if (isl_stream_eat(s, '['))
301
if (isl_stream_eat_if_available(s, '('))
305
pwaff = accept_affine(s, isl_space_copy(dim), v);
308
if (isl_stream_eat(s, ','))
311
if (seen_paren && isl_stream_eat(s, ')'))
313
if (isl_stream_eat(s, '/'))
320
if (tok->type != ISL_TOKEN_VALUE) {
321
isl_stream_error(s, tok, "expected denominator");
322
isl_stream_push_token(s, tok);
325
isl_pw_aff_scale_down(pwaff, tok->u.v);
329
pwaff = isl_pw_aff_ceil(pwaff);
331
pwaff = isl_pw_aff_floor(pwaff);
334
if (isl_stream_eat(s, ')'))
337
if (isl_stream_eat(s, ']'))
345
isl_pw_aff_free(pwaff);
349
static __isl_give isl_pw_aff *accept_affine_factor(struct isl_stream *s,
350
__isl_take isl_space *dim, struct vars *v)
275
352
struct isl_token *tok = NULL;
353
isl_pw_aff *res = NULL;
278
355
tok = next_token(s);
280
357
isl_stream_error(s, NULL, "unexpected EOF");
283
if (tok->type == ISL_TOKEN_IDENT) {
361
if (tok->type == ISL_TOKEN_AFF) {
362
res = isl_pw_aff_copy(tok->u.pwaff);
364
} else if (tok->type == ISL_TOKEN_IDENT) {
285
366
int pos = vars_pos(v, tok->u.s, -1);
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)));
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);
304
aff = isl_vec_alloc(v->ctx, 1 + v->n);
307
isl_seq_clr(aff->el, aff->size);
308
isl_int_set(aff->el[0], tok->u.v);
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);
310
394
isl_token_free(tok);
311
395
} else if (tok->type == '(') {
312
396
isl_token_free(tok);
314
aff = accept_affine(s, v);
398
res = accept_affine(s, isl_space_copy(dim), v);
317
401
if (isl_stream_eat(s, ')'))
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)
327
aff = isl_vec_alloc(v->ctx, 1 + v->n);
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);
334
if (read_div_definition(s, v) < 0)
337
isl_seq_neg(var->def->el + 1, var->def->el + 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)
343
aff = isl_vec_alloc(v->ctx, 1 + v->n);
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);
350
if (read_minmax_definition(s, v) < 0)
352
aff = isl_vec_zero_extend(aff, 1 + v->n);
412
res = accept_minmax(s, isl_space_copy(dim), v);
354
414
isl_stream_error(s, tok, "expecting factor");
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)) {
420
return affine_mod(s, v, res);
359
422
if (isl_stream_eat_if_available(s, '*')) {
460
543
isl_token_free(tok);
465
/* Add any variables in the variable list "v" that are not already in "bmap"
466
* as existentially quantified variables in "bmap".
468
static __isl_give isl_basic_map *add_divs(__isl_take isl_basic_map *bmap,
473
struct variable *var;
475
extra = v->n - isl_basic_map_total_dim(bmap);
480
bmap = isl_basic_map_extend_dim(bmap, isl_basic_map_get_dim(bmap),
481
extra, 0, 2 * extra);
483
for (i = 0; i < extra; ++i)
484
if (isl_basic_map_alloc_div(bmap) < 0)
487
for (i = 0, var = v->v; i < extra; ++i, var = var->next) {
488
int k = bmap->n_div - 1 - i;
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);
494
if (isl_basic_map_add_div_constraints(bmap, k) < 0)
500
isl_basic_map_free(bmap);
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)
508
isl_basic_map *def = NULL;
513
if (vars_add_anon(v) < 0)
517
vec = accept_affine(s, v);
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);
527
isl_seq_cpy(def->eq[k], vec->el, vec->size);
528
isl_int_set_si(def->eq[k][1 + n - 1], -1);
534
vars_drop(v, v->n - n);
536
def = isl_basic_map_simplify(def);
537
def = isl_basic_map_finalize(def);
538
bmap = isl_basic_map_intersect(bmap, def);
541
isl_basic_map_free(bmap);
542
isl_basic_map_free(def);
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);
548
static int is_comparator(struct isl_token *tok)
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);
571
/* Accept a ternary operator, given the first argument.
573
static __isl_give isl_pw_aff *accept_ternary(struct isl_stream *s,
574
__isl_take isl_map *cond, struct vars *v)
577
isl_pw_aff *pwaff1 = NULL, *pwaff2 = NULL;
582
if (isl_stream_eat(s, '?'))
585
dim = isl_space_wrap(isl_map_get_space(cond));
586
pwaff1 = accept_extended_affine(s, dim, v);
590
if (isl_stream_eat(s, ':'))
593
dim = isl_pw_aff_get_domain_space(pwaff1);
594
pwaff2 = accept_extended_affine(s, dim, v);
598
return isl_pw_aff_cond(isl_map_wrap(cond), pwaff1, pwaff2);
601
isl_pw_aff_free(pwaff1);
602
isl_pw_aff_free(pwaff2);
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.
612
static __isl_give isl_pw_aff *accept_extended_affine(struct isl_stream *s,
613
__isl_take isl_space *dim, struct vars *v)
618
struct isl_token *tok;
619
int line = -1, col = -1;
622
tok = isl_stream_next_token(s);
626
isl_stream_push_token(s, tok);
629
pwaff = accept_affine(s, dim, v);
633
tok = isl_stream_next_token(s);
635
return isl_pw_aff_free(pwaff);
637
is_comp = is_comparator(tok);
638
isl_stream_push_token(s, tok);
642
tok = isl_token_new(s->ctx, line, col, 0);
644
return isl_pw_aff_free(pwaff);
645
tok->type = ISL_TOKEN_AFF;
646
tok->u.pwaff = pwaff;
648
space = isl_pw_aff_get_domain_space(pwaff);
649
cond = isl_map_universe(isl_space_unwrap(space));
651
isl_stream_push_token(s, tok);
653
cond = read_disjuncts(s, v, cond);
655
return accept_ternary(s, cond, v);
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)
665
if (type == isl_dim_param)
666
pos = isl_map_dim(map, isl_dim_param);
668
pos = isl_map_dim(map, isl_dim_in);
669
if (type == isl_dim_out)
670
pos += isl_map_dim(map, isl_dim_out);
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));
680
map = isl_map_intersect(map, def_map);
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)
550
689
struct isl_token *tok;
691
if (isl_stream_next_token_is(s, ']'))
692
return isl_map_add_dims(map, type, 0);
552
694
while ((tok = next_token(s)) != NULL) {
553
695
int new_name = 0;
626
768
isl_token_free(tok);
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);
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));
641
static int read_minmax_definition(struct isl_stream *s, struct vars *v)
643
struct isl_token *tok;
644
struct variable *var;
648
tok = isl_stream_next_token(s);
651
var->sign = tok->type == ISL_TOKEN_MIN ? -1 : 1;
654
if (isl_stream_eat(s, '('))
657
var->list = accept_affine_list(s, v);
661
if (isl_stream_eat(s, ')'))
667
static int read_div_definition(struct isl_stream *s, struct vars *v)
669
struct isl_token *tok;
672
struct variable *var;
675
if (isl_stream_eat_if_available(s, ISL_TOKEN_FLOORD) ||
676
isl_stream_eat_if_available(s, ISL_TOKEN_CEILD)) {
678
if (isl_stream_eat(s, '('))
681
if (isl_stream_eat(s, '['))
683
if (isl_stream_eat_if_available(s, '('))
689
aff = accept_affine(s, v);
693
var->def = isl_vec_alloc(s->ctx, 2 + v->n);
699
isl_seq_cpy(var->def->el + 1, aff->el, aff->size);
704
if (isl_stream_eat(s, ','))
707
if (seen_paren && isl_stream_eat(s, ')'))
709
if (isl_stream_eat(s, '/'))
716
if (tok->type != ISL_TOKEN_VALUE) {
717
isl_stream_error(s, tok, "expected denominator");
718
isl_stream_push_token(s, tok);
721
isl_int_set(var->def->el[0], tok->u.v);
725
if (isl_stream_eat(s, ')'))
728
if (isl_stream_eat(s, ']'))
735
static struct isl_basic_map *add_div_definition(struct isl_stream *s,
736
struct vars *v, struct isl_basic_map *bmap, int pos)
738
struct variable *var = v->v;
739
unsigned o_out = isl_basic_map_offset(bmap, isl_dim_out) - 1;
741
if (read_div_definition(s, v) < 0)
744
if (isl_basic_map_add_div_constraints_var(bmap, o_out + pos,
750
isl_basic_map_free(bmap);
754
static struct isl_basic_map *read_defined_var_list(struct isl_stream *s,
755
struct vars *v, struct isl_basic_map *bmap)
781
isl_pw_aff_list_free(list);
785
static __isl_give isl_map *read_defined_var_list(struct isl_stream *s,
786
struct vars *v, __isl_take isl_map *map)
757
788
struct isl_token *tok;
759
790
while ((tok = isl_stream_next_token(s)) != NULL) {
762
unsigned n_out = isl_basic_map_dim(bmap, isl_dim_out);
764
794
if (tok->type != ISL_TOKEN_IDENT)
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);
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)
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))
836
bmap = read_tuple(s, bmap, isl_dim_out, v);
837
bmap = isl_basic_map_from_range(isl_basic_map_wrap(bmap));
863
map = read_tuple(s, map, isl_dim_out, v);
864
return isl_map_wrap(map);
840
isl_basic_map_free(bmap);
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)
847
873
struct isl_token *tok;
848
874
char *name = NULL;
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);
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);
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);
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);
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);
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);
895
bmap = isl_basic_map_set_tuple_name(bmap, type, name);
922
map = isl_map_set_tuple_name(map, type, name);
902
929
isl_token_free(tok);
903
isl_basic_map_free(bmap);
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)
917
len = 1 + isl_basic_map_total_dim(bmap);
920
k = isl_basic_map_alloc_inequality(bmap);
923
940
if (type == ISL_TOKEN_LE)
924
isl_seq_combine(bmap->ineq[k], ctx->negone, left,
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,
931
else if (type == ISL_TOKEN_LT) {
932
isl_seq_combine(bmap->ineq[k], ctx->negone, left,
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,
940
isl_int_sub_ui(bmap->ineq[k][0], bmap->ineq[k][0], 1);
942
isl_seq_combine(bmap->ineq[k], ctx->one, left,
945
isl_basic_map_inequality_to_equality(bmap, k);
950
isl_basic_map_free(bmap);
954
static int is_comparator(struct isl_token *tok)
971
/* Add any variables in the variable list "v" that are not already in "bmap"
972
* as output variables in "bmap".
974
static __isl_give isl_basic_map *add_lifted_divs(__isl_take isl_basic_map *bmap,
979
struct variable *var;
981
extra = v->n - isl_basic_map_total_dim(bmap);
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),
990
for (i = 0, var = v->v; i < extra; ++i, var = var->next) {
993
var->def = isl_vec_zero_extend(var->def, 2 + v->n);
996
if (isl_basic_map_add_div_constraints_var(bmap, var->pos,
1003
isl_basic_map_free(bmap);
1007
static struct isl_basic_map *add_constraint(struct isl_stream *s,
1008
struct vars *v, struct isl_basic_map *bmap)
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));
956
cond = isl_pw_aff_list_eq_set(isl_pw_aff_list_copy(left),
957
isl_pw_aff_list_copy(right));
959
return isl_set_intersect(set, cond);
962
static __isl_give isl_map *add_constraint(struct isl_stream *s,
963
struct vars *v, __isl_take isl_map *map)
1011
965
struct isl_token *tok = NULL;
1012
struct isl_mat *aff1 = NULL, *aff2 = NULL;
1014
bmap = isl_basic_map_cow(bmap);
1016
aff1 = accept_affine_list(s, v);
966
isl_pw_aff_list *list1 = NULL, *list2 = NULL;
969
set = isl_map_wrap(map);
970
list1 = accept_affine_list(s, isl_set_get_space(set), v);
1019
973
tok = isl_stream_next_token(s);
1020
974
if (!is_comparator(tok)) {
998
isl_pw_aff_list_free(list1);
1000
return isl_set_unwrap(set);
1058
1003
isl_token_free(tok);
1061
isl_basic_map_free(bmap);
1065
/* Return first variable, starting at n, representing a min or max,
1066
* or NULL if there is no such variable.
1068
static struct variable *first_minmax(struct vars *v, int n)
1070
struct variable *first = NULL;
1071
struct variable *var;
1073
for (var = v->v; var && var->pos >= n; var = var->next)
1080
/* Check whether the variable at the given position only occurs in
1081
* inequalities and only with the given sign.
1083
static int all_coefficients_of_sign(__isl_keep isl_map *map, int pos, int sign)
1090
for (i = 0; i < map->n; ++i) {
1091
isl_basic_map *bmap = map->p[i];
1093
for (j = 0; j < bmap->n_eq; ++j)
1094
if (!isl_int_is_zero(bmap->eq[j][1 + pos]))
1096
for (j = 0; j < bmap->n_ineq; ++j) {
1097
int s = isl_int_sgn(bmap->ineq[j][1 + pos]);
1108
/* Given a variable m which represents a min or a max of n expressions
1109
* b_i, add the constraints
1113
* in case of a min (var->sign < 0) and m >= b_i in case of a max.
1115
static __isl_give isl_map *bound_minmax(__isl_take isl_map *map,
1116
struct variable *var)
1119
isl_basic_map *bound;
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);
1126
for (i = 0; i < var->list->n_row; ++i) {
1127
k = isl_basic_map_alloc_inequality(bound);
1131
isl_seq_cpy(bound->ineq[k], var->list->row[i],
1134
isl_seq_neg(bound->ineq[k], var->list->row[i],
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);
1141
map = isl_map_intersect(map, isl_map_from_basic_map(bound));
1145
isl_basic_map_free(bound);
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.
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
1160
* b_i <= b_j for j > i
1161
* b_i < b_j for j < i
1163
* in case of a min (var->sign < 0) and similarly in case of a max.
1165
* Note: this function is very similar to set_minimum in isl_tab_pip.c
1166
* Perhaps we should try to merge the two.
1168
static __isl_give isl_map *set_minmax(__isl_take isl_map *map,
1169
struct variable *var)
1172
isl_basic_map *bmap = NULL;
1174
isl_map *split = NULL;
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);
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);
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) {
1193
k = isl_basic_map_alloc_inequality(bmap);
1197
isl_seq_combine(bmap->ineq[k],
1198
ctx->one, var->list->row[j],
1199
ctx->negone, var->list->row[i],
1202
isl_seq_combine(bmap->ineq[k],
1203
ctx->negone, var->list->row[j],
1204
ctx->one, var->list->row[i],
1206
isl_seq_clr(bmap->ineq[k] + var->list->n_col,
1207
1 + total - var->list->n_col);
1209
isl_int_sub_ui(bmap->ineq[k][0],
1210
bmap->ineq[k][0], 1);
1212
bmap = isl_basic_map_finalize(bmap);
1213
split = isl_map_add_basic_map(split, bmap);
1216
map = isl_map_intersect(map, split);
1220
isl_basic_map_free(bmap);
1221
isl_map_free(split);
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.
1235
static __isl_give isl_map *add_minmax(__isl_take isl_map *map,
1236
struct vars *v, int n)
1238
struct variable *var;
1241
var = first_minmax(v, n);
1244
if (all_coefficients_of_sign(map, var->pos, -var->sign))
1245
map = bound_minmax(map, var);
1247
map = set_minmax(map, var);
1254
static isl_map *read_constraint(struct isl_stream *s,
1255
struct vars *v, __isl_take isl_basic_map *bmap)
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)
1270
bmap = add_constraint(s, v, bmap);
1271
bmap = isl_basic_map_simplify(bmap);
1272
bmap = isl_basic_map_finalize(bmap);
1274
map = isl_map_from_basic_map(bmap);
1276
map = add_minmax(map, v, n);
1278
map = isl_set_unwrap(isl_map_domain(map));
1280
vars_drop(v, v->n - n);
1284
isl_basic_map_free(bmap);
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);
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)
1295
1014
int seen_paren = isl_stream_eat_if_available(s, '(');
1296
isl_map *map = NULL;
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);
1301
1019
if (isl_stream_eat(s, ':'))
1304
map = read_disjuncts(s, v, bmap);
1022
map = read_disjuncts(s, v, map);
1305
1023
map = isl_set_unwrap(isl_map_domain(map));
1308
1025
vars_drop(v, v->n - n);
1309
1026
if (seen_paren && isl_stream_eat(s, ')'))
1314
isl_basic_map_free(bmap);
1315
1031
isl_map_free(map);
1035
/* Parse an expression between parentheses and push the result
1036
* back on the stream.
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.
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.
1050
static int resolve_paren_expr(struct isl_stream *s,
1051
struct vars *v, __isl_take isl_map *map)
1053
struct isl_token *tok, *tok2;
1057
tok = isl_stream_next_token(s);
1058
if (!tok || tok->type != '(')
1061
if (isl_stream_next_token_is(s, '('))
1062
if (resolve_paren_expr(s, v, isl_map_copy(map)))
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, ')'))
1072
tok->type = ISL_TOKEN_MAP;
1074
isl_stream_push_token(s, tok);
1078
tok2 = isl_stream_next_token(s);
1083
isl_stream_push_token(s, tok2);
1085
pwaff = accept_affine(s, isl_space_wrap(isl_map_get_space(map)), v);
1089
tok2 = isl_token_new(s->ctx, line, col, 0);
1092
tok2->type = ISL_TOKEN_AFF;
1093
tok2->u.pwaff = pwaff;
1095
if (isl_stream_eat_if_available(s, ')')) {
1096
isl_stream_push_token(s, tok2);
1097
isl_token_free(tok);
1102
isl_stream_push_token(s, tok2);
1104
map = read_disjuncts(s, v, map);
1105
if (isl_stream_eat(s, ')'))
1108
tok->type = ISL_TOKEN_MAP;
1110
isl_stream_push_token(s, tok);
1114
isl_pw_aff_free(pwaff);
1116
isl_token_free(tok);
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)
1124
if (isl_stream_next_token_is(s, '('))
1125
if (resolve_paren_expr(s, v, isl_map_copy(map)))
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);
1134
map = isl_map_copy(tok->u.map);
1135
isl_token_free(tok);
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);
1334
1142
if (isl_stream_eat_if_available(s, ISL_TOKEN_TRUE))
1335
return isl_map_from_basic_map(bmap);
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);
1340
1148
return isl_map_empty(dim);
1343
return read_constraint(s, v, bmap);
1151
return add_constraint(s, v, map);
1345
1153
isl_map_free(map);
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)
1355
1163
negate = isl_stream_eat_if_available(s, ISL_TOKEN_NOT);
1356
map = read_conjunct(s, v, isl_basic_map_copy(bmap));
1359
t = isl_map_from_basic_map(isl_basic_map_copy(bmap));
1360
map = isl_map_subtract(t, map);
1164
res = read_conjunct(s, v, isl_map_copy(map));
1166
res = isl_map_subtract(isl_map_copy(map), res);
1363
1168
while (isl_stream_eat_if_available(s, ISL_TOKEN_AND)) {
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));
1369
map = isl_map_subtract(map, map_i);
1174
res = isl_map_subtract(res, res_i);
1371
map = isl_map_intersect(map, map_i);
1176
res = isl_map_intersect(res, res_i);
1374
isl_basic_map_free(bmap);
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)
1381
struct isl_map *map;
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);
1386
1191
return isl_map_universe(dim);
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)) {
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);
1397
isl_basic_map_free(bmap);
1401
1206
static int polylib_pos_to_isl_pos(__isl_keep isl_basic_map *bmap, int pos)
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;
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);
1802
isl_qpolynomial_free(qp);
1584
isl_pw_qpolynomial_free(pwqp);
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)
1809
1591
struct isl_token *tok;
1810
struct isl_qpolynomial *qp;
1592
isl_pw_qpolynomial *pwqp;
1812
qp = read_factor(s, bmap, v);
1594
pwqp = read_factor(s, map, v);
1815
1597
tok = next_token(s);
1819
1601
if (tok->type == '+') {
1820
struct isl_qpolynomial *qp2;
1602
isl_pw_qpolynomial *pwqp2;
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;
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;
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);
1839
1621
isl_stream_push_token(s, tok);
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)
1850
1632
struct isl_token *tok;
1851
struct isl_map *map;
1853
1634
tok = isl_stream_next_token(s);
1855
1636
isl_stream_error(s, NULL, "unexpected EOF");
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);
1865
1644
isl_stream_push_token(s, tok);
1867
isl_basic_map_free(bmap);
1871
isl_basic_map_free(bmap);
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)
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;
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);
1888
pwqp = isl_pw_qpolynomial_alloc(set, qp);
1663
pwqp = isl_pw_qpolynomial_intersect_domain(pwqp, set);
1890
1665
vars_drop(v, v->n - n);
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)
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;
1675
isl_pw_qpolynomial *pwqp;
1676
isl_pw_qpolynomial_fold *pwf = NULL;
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);
1909
1681
if (isl_stream_eat(s, '('))
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);
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,
1692
pwf = isl_pw_qpolynomial_fold_fold(pwf, pwf_i);
1922
1695
if (isl_stream_eat(s, ')'))
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);
1929
1701
vars_drop(v, v->n - n);
1934
isl_basic_map_free(bmap);
1935
isl_qpolynomial_fold_free(fold);
1707
isl_pw_qpolynomial_fold_free(pwf);
1936
1708
obj.type = isl_obj_none;
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)
1961
struct isl_map *map = NULL;
1962
1733
struct isl_token *tok;
1963
1734
struct isl_obj obj = { isl_obj_set, NULL };
1966
1737
if (is_rational(s))
1967
bmap = isl_basic_map_set_rational(bmap);
1738
map = isl_map_set_rational(map);
1740
if (isl_stream_next_token_is(s, ':')) {
1741
obj.type = isl_obj_set;
1742
obj.v = read_optional_disjuncts(s, map, v);
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);
1972
bmap = read_tuple(s, bmap, isl_dim_in, v);
1749
map = read_tuple(s, map, isl_dim_in, v);
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);
1983
bmap = read_tuple(s, bmap, isl_dim_out, v);
1760
map = read_tuple(s, map, isl_dim_out, v);
1987
bmap = isl_basic_map_reverse(bmap);
1764
map = isl_map_reverse(map);
1989
1766
isl_stream_push_token(s, tok);
1992
map = read_optional_disjuncts(s, bmap, v);
1769
map = read_optional_disjuncts(s, map, v);
1994
1771
vars_drop(v, v->n - n);
1999
isl_basic_map_free(bmap);
2000
1777
obj.type = isl_obj_none;
2093
static __isl_give isl_basic_set *basic_set_read(struct isl_stream *s)
2095
isl_basic_map *bmap;
2096
bmap = basic_map_read(s);
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);
2104
isl_basic_map_free(bmap);
2313
2108
__isl_give isl_basic_map *isl_basic_map_read_from_file(isl_ctx *ctx,
2314
FILE *input, int nparam)
2316
2111
struct isl_basic_map *bmap;
2317
2112
struct isl_stream *s = isl_stream_new_file(ctx, input);
2320
bmap = basic_map_read(s, nparam);
2115
bmap = basic_map_read(s);
2321
2116
isl_stream_free(s);
2325
2120
__isl_give isl_basic_set *isl_basic_set_read_from_file(isl_ctx *ctx,
2326
FILE *input, int nparam)
2328
struct isl_basic_map *bmap;
2329
bmap = isl_basic_map_read_from_file(ctx, input, nparam);
2123
isl_basic_set *bset;
2124
struct isl_stream *s = isl_stream_new_file(ctx, input);
2332
isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
2333
return (struct isl_basic_set *)bmap;
2335
isl_basic_map_free(bmap);
2127
bset = basic_set_read(s);
2339
2132
struct isl_basic_map *isl_basic_map_read_from_str(struct isl_ctx *ctx,
2340
const char *str, int nparam)
2342
2135
struct isl_basic_map *bmap;
2343
2136
struct isl_stream *s = isl_stream_new_str(ctx, str);
2346
bmap = basic_map_read(s, nparam);
2139
bmap = basic_map_read(s);
2347
2140
isl_stream_free(s);
2351
2144
struct isl_basic_set *isl_basic_set_read_from_str(struct isl_ctx *ctx,
2352
const char *str, int nparam)
2354
struct isl_basic_map *bmap;
2355
bmap = isl_basic_map_read_from_str(ctx, str, nparam);
2147
isl_basic_set *bset;
2148
struct isl_stream *s = isl_stream_new_str(ctx, str);
2358
isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
2359
return (struct isl_basic_set *)bmap;
2361
isl_basic_map_free(bmap);
2151
bset = basic_set_read(s);
2365
2156
__isl_give isl_map *isl_map_read_from_file(struct isl_ctx *ctx,
2366
FILE *input, int nparam)
2368
2159
struct isl_map *map;
2369
2160
struct isl_stream *s = isl_stream_new_file(ctx, input);
2372
map = isl_stream_read_map(s, nparam);
2163
map = isl_stream_read_map(s);
2373
2164
isl_stream_free(s);
2377
2168
__isl_give isl_map *isl_map_read_from_str(struct isl_ctx *ctx,
2378
const char *str, int nparam)
2380
2171
struct isl_map *map;
2381
2172
struct isl_stream *s = isl_stream_new_str(ctx, str);
2384
map = isl_stream_read_map(s, nparam);
2175
map = isl_stream_read_map(s);
2385
2176
isl_stream_free(s);
2389
2180
__isl_give isl_set *isl_set_read_from_file(struct isl_ctx *ctx,
2390
FILE *input, int nparam)
2392
struct isl_map *map;
2393
map = isl_map_read_from_file(ctx, input, nparam);
2184
struct isl_stream *s = isl_stream_new_file(ctx, input);
2396
isl_assert(ctx, isl_map_n_in(map) == 0, goto error);
2397
return (struct isl_set *)map;
2187
set = isl_stream_read_set(s);
2403
2192
struct isl_set *isl_set_read_from_str(struct isl_ctx *ctx,
2404
const char *str, int nparam)
2406
struct isl_map *map;
2407
map = isl_map_read_from_str(ctx, str, nparam);
2196
struct isl_stream *s = isl_stream_new_str(ctx, str);
2410
isl_assert(ctx, isl_map_n_in(map) == 0, goto error);
2411
return (struct isl_set *)map;
2199
set = isl_stream_read_set(s);
2417
2204
__isl_give isl_union_map *isl_union_map_read_from_file(isl_ctx *ctx,
2552
2339
isl_stream_free(s);
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.
2348
static __isl_give isl_aff *read_aff_with_dom(struct isl_stream *s,
2349
__isl_take isl_set *dom, struct vars *v)
2351
isl_aff *aff = NULL;
2352
isl_pw_aff *pwaff = NULL;
2354
if (!isl_set_plain_is_universe(dom))
2355
isl_die(s->ctx, isl_error_invalid,
2356
"expecting universe domain", goto error);
2358
if (!isl_set_is_params(dom) && isl_stream_eat(s, ISL_TOKEN_TO))
2361
if (isl_stream_eat(s, '['))
2364
pwaff = accept_affine(s, isl_set_get_space(dom), v);
2366
if (isl_stream_eat(s, ']'))
2368
if (isl_stream_eat(s, '}'))
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);
2381
aff = isl_aff_copy(pwaff->p[0].aff);
2384
isl_pw_aff_free(pwaff);
2389
isl_pw_aff_free(pwaff);
2394
/* Is the next token an identifer not in "v"?
2396
static int next_is_fresh_ident(struct isl_stream *s, struct vars *v)
2400
struct isl_token *tok;
2402
tok = isl_stream_next_token(s);
2405
fresh = tok->type == ISL_TOKEN_IDENT && vars_pos(v, tok->u.s, -1) >= n;
2406
isl_stream_push_token(s, tok);
2408
vars_drop(v, v->n - n);
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.
2423
static __isl_give isl_set *read_aff_domain(struct isl_stream *s,
2424
__isl_take isl_set *dom, struct vars *v)
2426
struct isl_token *tok;
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);
2433
if (!tok || tok->type != '[') {
2434
isl_stream_error(s, tok, "expecting '['");
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);
2441
isl_stream_push_token(s, tok);
2446
isl_stream_push_token(s, tok);
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.
2456
__isl_give isl_aff *isl_stream_read_aff(struct isl_stream *s)
2459
isl_set *dom = NULL;
2461
v = vars_new(s->ctx);
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))
2471
if (isl_stream_eat(s, '{'))
2474
dom = read_aff_domain(s, dom, v);
2475
return read_aff_with_dom(s, dom, v);
2482
/* Read a piecewise affine expression from "s" with domain (space) "dom".
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)
2487
isl_pw_aff *pwaff = NULL;
2489
if (!isl_set_is_params(dom) && isl_stream_eat(s, ISL_TOKEN_TO))
2492
if (isl_stream_eat(s, '['))
2495
pwaff = accept_affine(s, isl_set_get_space(dom), v);
2497
if (isl_stream_eat(s, ']'))
2500
dom = read_optional_disjuncts(s, dom, v);
2501
pwaff = isl_pw_aff_intersect_domain(pwaff, dom);
2506
isl_pw_aff_free(pwaff);
2510
__isl_give isl_pw_aff *isl_stream_read_pw_aff(struct isl_stream *s)
2513
isl_set *dom = NULL;
2515
isl_pw_aff *pa = NULL;
2518
v = vars_new(s->ctx);
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))
2528
if (isl_stream_eat(s, '{'))
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);
2536
while (isl_stream_eat_if_available(s, ';')) {
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);
2544
pa = isl_pw_aff_add(pa, pa_i);
2547
if (isl_stream_eat(s, '}'))
2556
isl_pw_aff_free(pa);
2560
__isl_give isl_aff *isl_aff_read_from_str(isl_ctx *ctx, const char *str)
2563
struct isl_stream *s = isl_stream_new_str(ctx, str);
2566
aff = isl_stream_read_aff(s);
2571
__isl_give isl_pw_aff *isl_pw_aff_read_from_str(isl_ctx *ctx, const char *str)
2574
struct isl_stream *s = isl_stream_new_str(ctx, str);
2577
pa = isl_stream_read_pw_aff(s);
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
2588
__isl_give isl_pw_multi_aff *isl_stream_read_pw_multi_aff(struct isl_stream *s)
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);
2601
obj.type->free(obj.v);
2602
isl_die(s->ctx, isl_error_invalid, "unexpected object type",
2606
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_read_from_str(isl_ctx *ctx,
2609
isl_pw_multi_aff *pma;
2610
struct isl_stream *s = isl_stream_new_str(ctx, str);
2613
pma = isl_stream_read_pw_multi_aff(s);
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.
2623
__isl_give isl_multi_aff *isl_stream_read_multi_aff(struct isl_stream *s)
2625
isl_pw_multi_aff *pma;
2626
isl_multi_aff *maff;
2628
pma = isl_stream_read_pw_multi_aff(s);
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);
2643
__isl_give isl_multi_aff *isl_multi_aff_read_from_str(isl_ctx *ctx,
2646
isl_multi_aff *maff;
2647
struct isl_stream *s = isl_stream_new_str(ctx, str);
2650
maff = isl_stream_read_multi_aff(s);
2655
__isl_give isl_union_pw_qpolynomial *isl_stream_read_union_pw_qpolynomial(
2656
struct isl_stream *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);
2666
isl_assert(s->ctx, obj.type == isl_obj_union_pw_qpolynomial,
2671
obj.type->free(obj.v);
2675
__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_read_from_str(
2676
isl_ctx *ctx, const char *str)
2678
isl_union_pw_qpolynomial *upwqp;
2679
struct isl_stream *s = isl_stream_new_str(ctx, str);
2682
upwqp = isl_stream_read_union_pw_qpolynomial(s);