2 * Copyright 2008-2009 Katholieke Universiteit Leuven
3 * Copyright 2010 INRIA Saclay
5 * Use of this software is governed by the GNU LGPLv2.1 license
7 * Written by Sven Verdoolaege, K.U.Leuven, Departement
8 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
9 * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
10 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
17 #include "isl_stream.h"
18 #include "isl_map_private.h"
19 #include "isl_input_omega.h"
24 struct variable *next;
33 static struct vars *vars_new(struct isl_ctx *ctx)
36 v = isl_alloc_type(ctx, struct vars);
45 static void variable_free(struct variable *var)
48 struct variable *next = var->next;
55 static void vars_free(struct vars *v)
63 static struct variable *variable_new(struct vars *v, const char *name, int len,
67 var = isl_alloc_type(v->ctx, struct variable);
70 var->name = strdup(name);
71 var->name[len] = '\0';
80 static int vars_pos(struct vars *v, const char *s, int len)
87 for (q = v->v; q; q = q->next) {
88 if (strncmp(q->name, s, len) == 0 && q->name[len] == '\0')
95 v->v = variable_new(v, s, len, v->n);
103 static struct vars *read_var_list(struct isl_stream *s, struct vars *v)
105 struct isl_token *tok;
107 while ((tok = isl_stream_next_token(s)) != NULL) {
111 if (tok->type != ISL_TOKEN_IDENT)
114 p = vars_pos(v, tok->u.s, -1);
118 isl_stream_error(s, tok, "expecting unique identifier");
122 tok = isl_stream_next_token(s);
123 if (!tok || tok->type != ',')
129 isl_stream_push_token(s, tok);
138 static struct vars *read_tuple(struct isl_stream *s, struct vars *v)
140 struct isl_token *tok;
142 tok = isl_stream_next_token(s);
143 if (!tok || tok->type != '[') {
144 isl_stream_error(s, tok, "expecting '['");
148 v = read_var_list(s, v);
149 tok = isl_stream_next_token(s);
150 if (!tok || tok->type != ']') {
151 isl_stream_error(s, tok, "expecting ']'");
164 static struct isl_basic_map *add_constraints(struct isl_stream *s,
165 struct vars **v, struct isl_basic_map *bmap);
167 static struct isl_basic_map *add_exists(struct isl_stream *s,
168 struct vars **v, struct isl_basic_map *bmap)
170 struct isl_token *tok;
177 tok = isl_stream_next_token(s);
180 if (tok->type == '(') {
184 isl_stream_push_token(s, tok);
185 *v = read_var_list(s, *v);
189 bmap = isl_basic_map_cow(bmap);
190 bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim),
192 total = isl_basic_map_total_dim(bmap);
193 for (i = 0; i < extra; ++i) {
195 if ((k = isl_basic_map_alloc_div(bmap)) < 0)
197 isl_seq_clr(bmap->div[k], 1+1+total);
201 if (isl_stream_eat(s, ':'))
203 bmap = add_constraints(s, v, bmap);
204 if (seen_paren && isl_stream_eat(s, ')'))
208 isl_basic_map_free(bmap);
212 static struct isl_basic_map *add_constraint(struct isl_stream *s,
213 struct vars **v, struct isl_basic_map *bmap)
215 unsigned total = isl_basic_map_total_dim(bmap);
220 struct isl_token *tok = NULL;
222 tok = isl_stream_next_token(s);
225 if (tok->type == ISL_TOKEN_EXISTS) {
227 return add_exists(s, v, bmap);
229 isl_stream_push_token(s, tok);
231 bmap = isl_basic_map_cow(bmap);
232 bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
233 k = isl_basic_map_alloc_inequality(bmap);
236 isl_seq_clr(bmap->ineq[k], 1+total);
239 tok = isl_stream_next_token(s);
241 isl_stream_error(s, NULL, "unexpected EOF");
244 if (tok->type == ISL_TOKEN_IDENT) {
246 int pos = vars_pos(*v, tok->u.s, -1);
250 isl_stream_error(s, tok, "unknown identifier");
254 isl_int_add_ui(bmap->ineq[k][1+pos],
255 bmap->ineq[k][1+pos], 1);
257 isl_int_sub_ui(bmap->ineq[k][1+pos],
258 bmap->ineq[k][1+pos], 1);
259 } else if (tok->type == ISL_TOKEN_VALUE) {
260 struct isl_token *tok2;
263 tok2 = isl_stream_next_token(s);
264 if (tok2 && tok2->type == ISL_TOKEN_IDENT) {
265 pos = vars_pos(*v, tok2->u.s, -1);
269 isl_stream_error(s, tok2,
270 "unknown identifier");
271 isl_token_free(tok2);
274 isl_token_free(tok2);
276 isl_stream_push_token(s, tok2);
278 isl_int_neg(tok->u.v, tok->u.v);
279 isl_int_add(bmap->ineq[k][1+pos],
280 bmap->ineq[k][1+pos], tok->u.v);
281 } else if (tok->type == '+') {
283 } else if (tok->type == ISL_TOKEN_LE) {
285 isl_seq_neg(bmap->ineq[k], bmap->ineq[k], 1+total);
286 } else if (tok->type == ISL_TOKEN_GE) {
289 } else if (tok->type == '=') {
291 isl_stream_error(s, tok, "too many operators");
298 isl_stream_push_token(s, tok);
305 isl_stream_error(s, tok, "missing operator");
309 isl_basic_map_inequality_to_equality(bmap, k);
314 isl_basic_map_free(bmap);
318 static struct isl_basic_map *add_constraints(struct isl_stream *s,
319 struct vars **v, struct isl_basic_map *bmap)
321 struct isl_token *tok;
324 bmap = add_constraint(s, v, bmap);
327 tok = isl_stream_next_token(s);
329 isl_stream_error(s, NULL, "unexpected EOF");
332 if (tok->type != ISL_TOKEN_AND)
336 isl_stream_push_token(s, tok);
342 isl_basic_map_free(bmap);
346 static __isl_give isl_basic_map *basic_map_read_polylib_constraint(
347 struct isl_stream *s, __isl_take isl_basic_map *bmap)
350 struct isl_token *tok;
360 nparam = isl_basic_map_dim(bmap, isl_dim_param);
361 dim = isl_basic_map_dim(bmap, isl_dim_out);
363 tok = isl_stream_next_token(s);
364 if (!tok || tok->type != ISL_TOKEN_VALUE) {
365 isl_stream_error(s, tok, "expecting coefficient");
367 isl_stream_push_token(s, tok);
370 if (!tok->on_new_line) {
371 isl_stream_error(s, tok, "coefficient should appear on new line");
372 isl_stream_push_token(s, tok);
376 type = isl_int_get_si(tok->u.v);
379 isl_assert(s->ctx, type == 0 || type == 1, goto error);
381 k = isl_basic_map_alloc_equality(bmap);
384 k = isl_basic_map_alloc_inequality(bmap);
390 for (j = 0; j < dim; ++j) {
391 tok = isl_stream_next_token(s);
392 if (!tok || tok->type != ISL_TOKEN_VALUE) {
393 isl_stream_error(s, tok, "expecting coefficient");
395 isl_stream_push_token(s, tok);
398 isl_int_set(c[1 + nparam + j], tok->u.v);
401 for (j = 0; j < nparam; ++j) {
402 tok = isl_stream_next_token(s);
403 if (!tok || tok->type != ISL_TOKEN_VALUE) {
404 isl_stream_error(s, tok, "expecting coefficient");
406 isl_stream_push_token(s, tok);
409 isl_int_set(c[1 + j], tok->u.v);
412 tok = isl_stream_next_token(s);
413 if (!tok || tok->type != ISL_TOKEN_VALUE) {
414 isl_stream_error(s, tok, "expecting coefficient");
416 isl_stream_push_token(s, tok);
419 isl_int_set(c[0], tok->u.v);
424 isl_basic_map_free(bmap);
428 static __isl_give isl_basic_map *basic_map_read_polylib(struct isl_stream *s,
432 struct isl_token *tok;
433 struct isl_token *tok2;
437 struct isl_basic_map *bmap = NULL;
442 tok = isl_stream_next_token(s);
444 isl_stream_error(s, NULL, "unexpected EOF");
447 tok2 = isl_stream_next_token(s);
450 isl_stream_error(s, NULL, "unexpected EOF");
453 n_row = isl_int_get_si(tok->u.v);
454 n_col = isl_int_get_si(tok2->u.v);
455 on_new_line = tok2->on_new_line;
456 isl_token_free(tok2);
458 isl_assert(s->ctx, !on_new_line, return NULL);
459 isl_assert(s->ctx, n_row >= 0, return NULL);
460 isl_assert(s->ctx, n_col >= 2 + nparam, return NULL);
461 dim = n_col - 2 - nparam;
462 bmap = isl_basic_map_alloc(s->ctx, nparam, 0, dim, 0, n_row, n_row);
466 for (i = 0; i < n_row; ++i)
467 bmap = basic_map_read_polylib_constraint(s, bmap);
469 bmap = isl_basic_map_simplify(bmap);
470 bmap = isl_basic_map_finalize(bmap);
474 static struct isl_map *map_read_polylib(struct isl_stream *s, int nparam)
476 struct isl_token *tok;
477 struct isl_token *tok2;
481 tok = isl_stream_next_token(s);
483 isl_stream_error(s, NULL, "unexpected EOF");
486 tok2 = isl_stream_next_token(s);
489 isl_stream_error(s, NULL, "unexpected EOF");
492 if (!tok2->on_new_line) {
493 isl_stream_push_token(s, tok2);
494 isl_stream_push_token(s, tok);
495 return isl_map_from_basic_map(basic_map_read_polylib(s, nparam));
497 isl_stream_push_token(s, tok2);
498 n = isl_int_get_si(tok->u.v);
501 isl_assert(s->ctx, n >= 1, return NULL);
503 map = isl_map_from_basic_map(basic_map_read_polylib(s, nparam));
505 for (i = 1; i < n; ++i)
506 map = isl_map_union(map,
507 isl_map_from_basic_map(basic_map_read_polylib(s, nparam)));
512 static struct isl_map *map_read(struct isl_stream *s, int nparam)
514 struct isl_basic_map *bmap = NULL;
515 struct isl_token *tok;
516 struct vars *v = NULL;
520 tok = isl_stream_next_token(s);
522 isl_stream_error(s, NULL, "unexpected EOF");
525 if (tok->type == ISL_TOKEN_VALUE) {
526 isl_stream_push_token(s, tok);
527 return map_read_polylib(s, nparam);
529 if (tok->type != '{') {
530 isl_stream_error(s, tok, "expecting '{'");
532 isl_stream_push_token(s, tok);
536 v = vars_new(s->ctx);
537 v = read_tuple(s, v);
541 tok = isl_stream_next_token(s);
542 if (tok && tok->type == ISL_TOKEN_TO) {
544 v = read_tuple(s, v);
550 isl_stream_push_token(s, tok);
554 bmap = isl_basic_map_alloc(s->ctx, 0, n1, n2, 0, 0,0);
557 tok = isl_stream_next_token(s);
558 if (tok && tok->type == ':') {
560 bmap = add_constraints(s, &v, bmap);
561 tok = isl_stream_next_token(s);
563 if (tok && tok->type == '}') {
566 isl_stream_error(s, tok, "unexpected isl_token");
573 bmap = isl_basic_map_simplify(bmap);
574 bmap = isl_basic_map_finalize(bmap);
575 return isl_map_from_basic_map(bmap);
577 isl_basic_map_free(bmap);
583 static struct isl_basic_map *basic_map_read(struct isl_stream *s, int nparam)
586 struct isl_basic_map *bmap;
588 map = map_read(s, nparam);
592 isl_assert(map->ctx, map->n <= 1, goto error);
595 bmap = isl_basic_map_empty_like_map(map);
597 bmap = isl_basic_map_copy(map->p[0]);
607 struct isl_basic_map *isl_basic_map_read_from_file_omega(
608 struct isl_ctx *ctx, FILE *input)
610 struct isl_basic_map *bmap;
611 struct isl_stream *s = isl_stream_new_file(ctx, input);
614 bmap = basic_map_read(s, 0);
619 struct isl_basic_set *isl_basic_set_read_from_file_omega(
620 struct isl_ctx *ctx, FILE *input)
622 struct isl_basic_map *bmap;
623 bmap = isl_basic_map_read_from_file_omega(ctx, input);
626 isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
627 return (struct isl_basic_set *)bmap;
629 isl_basic_map_free(bmap);
633 struct isl_basic_map *isl_basic_map_read_from_str_omega(
634 struct isl_ctx *ctx, const char *str)
636 struct isl_basic_map *bmap;
637 struct isl_stream *s = isl_stream_new_str(ctx, str);
640 bmap = basic_map_read(s, 0);
645 struct isl_basic_set *isl_basic_set_read_from_str_omega(
646 struct isl_ctx *ctx, const char *str)
648 struct isl_basic_map *bmap;
649 bmap = isl_basic_map_read_from_str_omega(ctx, str);
652 isl_assert(ctx, isl_basic_map_n_in(bmap) == 0, goto error);
653 return (struct isl_basic_set *)bmap;
655 isl_basic_map_free(bmap);