#include <stdio.h>
#include <string.h>
#include <strings.h>
+#include <isl_ctx_private.h>
#include <isl_map_private.h>
#include <isl/set.h>
#include <isl/seq.h>
return bmap;
}
+/* Obtain next token, with some preprocessing.
+ * In particular, evaluate expressions of the form x^y,
+ * with x and y values.
+ */
+static struct isl_token *next_token(struct isl_stream *s)
+{
+ struct isl_token *tok, *tok2;
+
+ tok = isl_stream_next_token(s);
+ if (!tok || tok->type != ISL_TOKEN_VALUE)
+ return tok;
+ if (!isl_stream_eat_if_available(s, '^'))
+ return tok;
+ tok2 = isl_stream_next_token(s);
+ if (!tok2 || tok2->type != ISL_TOKEN_VALUE) {
+ isl_stream_error(s, tok2, "expecting constant value");
+ goto error;
+ }
+
+ isl_int_pow_ui(tok->u.v, tok->u.v, isl_int_get_ui(tok2->u.v));
+
+ isl_token_free(tok2);
+ return tok;
+error:
+ isl_token_free(tok);
+ isl_token_free(tok2);
+ return NULL;
+}
+
static int accept_cst_factor(struct isl_stream *s, isl_int *f)
{
struct isl_token *tok;
- tok = isl_stream_next_token(s);
+ tok = next_token(s);
if (!tok || tok->type != ISL_TOKEN_VALUE) {
isl_stream_error(s, tok, "expecting constant value");
goto error;
struct variable *var;
isl_vec *mod;
- tok = isl_stream_next_token(s);
+ tok = next_token(s);
if (!tok || tok->type != ISL_TOKEN_VALUE) {
isl_stream_error(s, tok, "expecting constant value");
goto error;
struct isl_token *tok = NULL;
isl_vec *aff = NULL;
- tok = isl_stream_next_token(s);
+ tok = next_token(s);
if (!tok) {
isl_stream_error(s, NULL, "unexpected EOF");
goto error;
tok = NULL;
if (read_div_definition(s, v) < 0)
goto error;
+ aff = isl_vec_zero_extend(aff, 1 + v->n);
} else {
isl_stream_error(s, tok, "expecting factor");
goto error;
isl_seq_clr(aff->el, aff->size);
for (;;) {
- tok = isl_stream_next_token(s);
+ tok = next_token(s);
if (!tok) {
isl_stream_error(s, NULL, "unexpected EOF");
goto error;
}
isl_token_free(tok);
- tok = isl_stream_next_token(s);
+ tok = next_token(s);
if (tok && tok->type == '-') {
sign = -sign;
isl_token_free(tok);
int i = 0;
struct isl_token *tok;
- while ((tok = isl_stream_next_token(s)) != NULL) {
+ while ((tok = next_token(s)) != NULL) {
int new_name = 0;
if (tok->type == ISL_TOKEN_IDENT) {
if (isl_stream_eat(s, '/'))
return -1;
- tok = isl_stream_next_token(s);
+ tok = next_token(s);
if (!tok)
return -1;
if (tok->type != ISL_TOKEN_VALUE) {
}
static struct isl_basic_map *add_div_definition(struct isl_stream *s,
- struct vars *v, struct isl_basic_map *bmap, int k)
+ struct vars *v, struct isl_basic_map *bmap, int pos)
{
struct variable *var = v->v;
+ unsigned o_out = isl_basic_map_offset(bmap, isl_dim_out) - 1;
if (read_div_definition(s, v) < 0)
goto error;
- isl_seq_cpy(bmap->div[k], var->def->el, 2 + v->n);
-
- if (isl_basic_map_add_div_constraints(bmap, k) < 0)
+ if (isl_basic_map_add_div_constraints_var(bmap, o_out + pos,
+ var->def->el) < 0)
goto error;
return bmap;
struct isl_token *tok;
while ((tok = isl_stream_next_token(s)) != NULL) {
- int k;
int p;
int n = v->n;
- unsigned total = isl_basic_map_total_dim(bmap);
+ unsigned n_out = isl_basic_map_dim(bmap, isl_dim_out);
if (tok->type != ISL_TOKEN_IDENT)
break;
}
bmap = isl_basic_map_cow(bmap);
+ bmap = isl_basic_map_add(bmap, isl_dim_out, 1);
bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim),
- 1, 0, 2);
-
- if ((k = isl_basic_map_alloc_div(bmap)) < 0)
- goto error;
- isl_seq_clr(bmap->div[k], 1 + 1 + total);
+ 0, 0, 2);
isl_token_free(tok);
tok = isl_stream_next_token(s);
if (tok && tok->type == '=') {
isl_token_free(tok);
- bmap = add_div_definition(s, v, bmap, k);
+ bmap = add_div_definition(s, v, bmap, n_out);
tok = isl_stream_next_token(s);
}
return NULL;
}
-static struct isl_basic_map *add_constraints(struct isl_stream *s,
- struct vars *v, struct isl_basic_map *bmap);
-
-static struct isl_basic_map *add_exists(struct isl_stream *s,
- struct vars *v, struct isl_basic_map *bmap)
-{
- struct isl_token *tok;
- int n = v->n;
- int extra;
- int seen_paren = 0;
- int i;
- unsigned total;
-
- tok = isl_stream_next_token(s);
- if (!tok)
- goto error;
- if (tok->type == '(') {
- seen_paren = 1;
- isl_token_free(tok);
- } else
- isl_stream_push_token(s, tok);
-
- bmap = read_defined_var_list(s, v, bmap);
- if (!bmap)
- goto error;
-
- if (isl_stream_eat(s, ':'))
- goto error;
- bmap = add_constraints(s, v, bmap);
- if (seen_paren && isl_stream_eat(s, ')'))
- goto error;
- return bmap;
-error:
- isl_basic_map_free(bmap);
- return NULL;
-}
-
static __isl_give isl_basic_map *construct_constraint(
__isl_take isl_basic_map *bmap, enum isl_token_type type,
isl_int *left, isl_int *right)
}
}
+/* Add any variables in the variable list "v" that are not already in "bmap"
+ * as output variables in "bmap".
+ */
+static __isl_give isl_basic_map *add_lifted_divs(__isl_take isl_basic_map *bmap,
+ struct vars *v)
+{
+ int i;
+ int extra;
+ struct variable *var;
+
+ extra = v->n - isl_basic_map_total_dim(bmap);
+
+ if (extra == 0)
+ return bmap;
+
+ bmap = isl_basic_map_add(bmap, isl_dim_out, extra);
+ bmap = isl_basic_map_extend_dim(bmap, isl_basic_map_get_dim(bmap),
+ 0, 0, 2 * extra);
+
+ for (i = 0, var = v->v; i < extra; ++i, var = var->next) {
+ var->def = isl_vec_zero_extend(var->def, 2 + v->n);
+ if (!var->def)
+ goto error;
+ if (isl_basic_map_add_div_constraints_var(bmap, var->pos,
+ var->def->el) < 0)
+ goto error;
+ }
+
+ return bmap;
+error:
+ isl_basic_map_free(bmap);
+ return NULL;
+}
+
static struct isl_basic_map *add_constraint(struct isl_stream *s,
struct vars *v, struct isl_basic_map *bmap)
{
struct isl_token *tok = NULL;
struct isl_mat *aff1 = NULL, *aff2 = NULL;
- tok = isl_stream_next_token(s);
- if (!tok)
- goto error;
- if (tok->type == ISL_TOKEN_EXISTS) {
- isl_token_free(tok);
- return add_exists(s, v, bmap);
- }
- isl_stream_push_token(s, tok);
- tok = NULL;
-
bmap = isl_basic_map_cow(bmap);
aff1 = accept_affine_list(s, v);
aff1 = isl_mat_add_zero_cols(aff1, aff2->n_col - aff1->n_col);
if (!aff1)
goto error;
- bmap = add_divs(bmap, v);
+ bmap = add_lifted_divs(bmap, v);
bmap = isl_basic_map_extend_constraints(bmap, 0,
aff1->n_row * aff2->n_row);
for (i = 0; i < aff1->n_row; ++i)
return NULL;
}
-static struct isl_basic_map *add_constraints(struct isl_stream *s,
- struct vars *v, struct isl_basic_map *bmap)
+static isl_map *read_constraint(struct isl_stream *s,
+ struct vars *v, __isl_take isl_basic_map *bmap)
{
- struct isl_token *tok;
+ int n = v->n;
- for (;;) {
- bmap = add_constraint(s, v, bmap);
- if (!bmap)
- return NULL;
- tok = isl_stream_next_token(s);
- if (!tok) {
- isl_stream_error(s, NULL, "unexpected EOF");
- goto error;
- }
- if (tok->type != ISL_TOKEN_AND)
- break;
- isl_token_free(tok);
- }
- isl_stream_push_token(s, tok);
+ if (!bmap)
+ return NULL;
- return bmap;
-error:
- if (tok)
- isl_token_free(tok);
- isl_basic_map_free(bmap);
- return NULL;
+ bmap = isl_basic_set_unwrap(isl_basic_set_lift(isl_basic_map_wrap(bmap)));
+
+ bmap = add_constraint(s, v, bmap);
+ bmap = isl_basic_map_simplify(bmap);
+ bmap = isl_basic_map_finalize(bmap);
+
+ bmap = isl_basic_set_unwrap(isl_basic_map_domain(bmap));
+
+ vars_drop(v, v->n - n);
+
+ return isl_map_from_basic_map(bmap);
}
-static struct isl_basic_map *read_disjunct(struct isl_stream *s,
- struct vars *v, __isl_take isl_dim *dim)
+static struct isl_map *read_disjuncts(struct isl_stream *s,
+ struct vars *v, __isl_take isl_basic_map *bmap);
+
+static __isl_give isl_map *read_exists(struct isl_stream *s,
+ struct vars *v, __isl_take isl_basic_map *bmap)
{
- int seen_paren = 0;
- struct isl_token *tok;
- struct isl_basic_map *bmap;
+ int n = v->n;
+ int seen_paren = isl_stream_eat_if_available(s, '(');
+ isl_map *map = NULL;
- bmap = isl_basic_map_alloc_dim(dim, 0, 0, 0);
- if (!bmap)
- return NULL;
+ bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
+ bmap = read_defined_var_list(s, v, bmap);
- tok = isl_stream_next_token(s);
- if (!tok)
+ if (isl_stream_eat(s, ':'))
goto error;
- if (tok->type == '(') {
- seen_paren = 1;
- isl_token_free(tok);
- } else
- isl_stream_push_token(s, tok);
- bmap = add_constraints(s, v, bmap);
- bmap = isl_basic_map_simplify(bmap);
- bmap = isl_basic_map_finalize(bmap);
+ map = read_disjuncts(s, v, bmap);
+ map = isl_set_unwrap(isl_map_domain(map));
+ bmap = NULL;
+ vars_drop(v, v->n - n);
if (seen_paren && isl_stream_eat(s, ')'))
goto error;
- return bmap;
+ return map;
error:
isl_basic_map_free(bmap);
+ isl_map_free(map);
return NULL;
}
-static struct isl_map *read_disjuncts(struct isl_stream *s,
- struct vars *v, __isl_take isl_dim *dim)
+static __isl_give isl_map *read_conjunct(struct isl_stream *s,
+ struct vars *v, __isl_take isl_basic_map *bmap)
{
- struct isl_token *tok;
- struct isl_map *map;
+ isl_map *map;
- tok = isl_stream_next_token(s);
- if (!tok) {
- isl_stream_error(s, NULL, "unexpected EOF");
- goto error;
+ if (isl_stream_eat_if_available(s, '(')) {
+ map = read_disjuncts(s, v, bmap);
+ if (isl_stream_eat(s, ')'))
+ goto error;
+ return map;
}
- if (tok->type == '}') {
- isl_stream_push_token(s, tok);
- return isl_map_universe(dim);
+
+ if (isl_stream_eat_if_available(s, ISL_TOKEN_EXISTS))
+ return read_exists(s, v, bmap);
+
+ if (isl_stream_eat_if_available(s, ISL_TOKEN_TRUE))
+ return isl_map_from_basic_map(bmap);
+
+ if (isl_stream_eat_if_available(s, ISL_TOKEN_FALSE)) {
+ isl_dim *dim = isl_basic_map_get_dim(bmap);
+ isl_basic_map_free(bmap);
+ return isl_map_empty(dim);
}
- isl_stream_push_token(s, tok);
+
+ return read_constraint(s, v, bmap);
+error:
+ isl_map_free(map);
+ return NULL;
+}
- map = isl_map_empty(isl_dim_copy(dim));
- for (;;) {
- struct isl_basic_map *bmap;
- int n = v->n;
+static __isl_give isl_map *read_conjuncts(struct isl_stream *s,
+ struct vars *v, __isl_take isl_basic_map *bmap)
+{
+ isl_map *map;
+ int negate;
- bmap = read_disjunct(s, v, isl_dim_copy(dim));
- map = isl_map_union(map, isl_map_from_basic_map(bmap));
+ negate = isl_stream_eat_if_available(s, ISL_TOKEN_NOT);
+ map = read_conjunct(s, v, isl_basic_map_copy(bmap));
+ if (negate) {
+ isl_map *t;
+ t = isl_map_from_basic_map(isl_basic_map_copy(bmap));
+ map = isl_map_subtract(t, map);
+ }
- vars_drop(v, v->n - n);
+ while (isl_stream_eat_if_available(s, ISL_TOKEN_AND)) {
+ isl_map *map_i;
- tok = isl_stream_next_token(s);
- if (!tok || tok->type != ISL_TOKEN_OR)
- break;
- isl_token_free(tok);
+ negate = isl_stream_eat_if_available(s, ISL_TOKEN_NOT);
+ map_i = read_conjunct(s, v, isl_basic_map_copy(bmap));
+ if (negate)
+ map = isl_map_subtract(map, map_i);
+ else
+ map = isl_map_intersect(map, map_i);
}
- if (tok)
- isl_stream_push_token(s, tok);
- isl_dim_free(dim);
+ isl_basic_map_free(bmap);
+ return map;
+}
+
+static struct isl_map *read_disjuncts(struct isl_stream *s,
+ struct vars *v, __isl_take isl_basic_map *bmap)
+{
+ struct isl_map *map;
+
+ if (isl_stream_next_token_is(s, '}')) {
+ isl_dim *dim = isl_basic_map_get_dim(bmap);
+ isl_basic_map_free(bmap);
+ return isl_map_universe(dim);
+ }
+
+ map = read_conjuncts(s, v, isl_basic_map_copy(bmap));
+ while (isl_stream_eat_if_available(s, ISL_TOKEN_OR)) {
+ isl_map *map_i;
+
+ map_i = read_conjuncts(s, v, isl_basic_map_copy(bmap));
+ map = isl_map_union(map, map_i);
+ }
+
+ isl_basic_map_free(bmap);
return map;
-error:
- isl_dim_free(dim);
- return NULL;
}
static int polylib_pos_to_isl_pos(__isl_keep isl_basic_map *bmap, int pos)
struct isl_qpolynomial *qp;
struct isl_token *tok;
- tok = isl_stream_next_token(s);
+ tok = next_token(s);
if (!tok) {
isl_stream_error(s, NULL, "unexpected EOF");
return NULL;
tok2 = isl_stream_next_token(s);
if (tok2 && tok2->type == '/') {
isl_token_free(tok2);
- tok2 = isl_stream_next_token(s);
+ tok2 = next_token(s);
if (!tok2 || tok2->type != ISL_TOKEN_VALUE) {
isl_stream_error(s, tok2, "expected denominator");
isl_token_free(tok);
qp = read_factor(s, bmap, v);
for (;;) {
- tok = isl_stream_next_token(s);
+ tok = next_token(s);
if (!tok)
return qp;
goto error;
}
map = isl_map_from_basic_map(isl_basic_map_copy(bmap));
- if (tok->type == ':') {
+ if (tok->type == ':' ||
+ (tok->type == ISL_TOKEN_OR && !strcmp(tok->u.s, "|"))) {
isl_token_free(tok);
map = isl_map_intersect(map,
- read_disjuncts(s, v, isl_basic_map_get_dim(bmap)));
+ read_disjuncts(s, v, isl_basic_map_copy(bmap)));
} else
isl_stream_push_token(s, tok);
return obj;
}
+static int is_rational(struct isl_stream *s)
+{
+ struct isl_token *tok;
+
+ tok = isl_stream_next_token(s);
+ if (!tok)
+ return 0;
+ if (tok->type == ISL_TOKEN_RAT && isl_stream_next_token_is(s, ':')) {
+ isl_token_free(tok);
+ isl_stream_eat(s, ':');
+ return 1;
+ }
+
+ isl_stream_push_token(s, tok);
+
+ return 0;
+}
+
static struct isl_obj obj_read_body(struct isl_stream *s,
__isl_take isl_basic_map *bmap, struct vars *v)
{
struct isl_obj obj = { isl_obj_set, NULL };
int n = v->n;
+ if (is_rational(s))
+ bmap = isl_basic_map_set_rational(bmap);
+
if (!next_is_tuple(s))
return obj_read_poly_or_fold(s, bmap, v, n);
struct vars *v = NULL;
struct isl_obj obj = { isl_obj_set, NULL };
- tok = isl_stream_next_token(s);
+ tok = next_token(s);
if (!tok) {
isl_stream_error(s, NULL, "unexpected EOF");
goto error;
if (!tok || tok->type != ';')
break;
isl_token_free(tok);
+ if (isl_stream_next_token_is(s, '}')) {
+ tok = isl_stream_next_token(s);
+ break;
+ }
}
if (tok && tok->type == '}') {
return NULL;
}
+__isl_give isl_union_map *isl_union_map_read_from_file(isl_ctx *ctx,
+ FILE *input)
+{
+ isl_union_map *umap;
+ struct isl_stream *s = isl_stream_new_file(ctx, input);
+ if (!s)
+ return NULL;
+ umap = isl_stream_read_union_map(s);
+ isl_stream_free(s);
+ return umap;
+}
+
__isl_give isl_union_map *isl_union_map_read_from_str(struct isl_ctx *ctx,
const char *str)
{
return umap;
}
+__isl_give isl_union_set *isl_union_set_read_from_file(isl_ctx *ctx,
+ FILE *input)
+{
+ isl_union_set *uset;
+ struct isl_stream *s = isl_stream_new_file(ctx, input);
+ if (!s)
+ return NULL;
+ uset = isl_stream_read_union_set(s);
+ isl_stream_free(s);
+ return uset;
+}
+
__isl_give isl_union_set *isl_union_set_read_from_str(struct isl_ctx *ctx,
const char *str)
{
return NULL;
}
-static __isl_give isl_vec *vec_read(struct isl_stream *s,
- unsigned input_format)
+static __isl_give isl_vec *vec_read(struct isl_stream *s)
{
- if (input_format == ISL_FORMAT_POLYLIB)
- return isl_vec_read_polylib(s);
- isl_assert(s->ctx, 0, return NULL);
+ return isl_vec_read_polylib(s);
}
-struct isl_vec *isl_vec_read_from_file(struct isl_ctx *ctx,
- FILE *input, unsigned input_format)
+__isl_give isl_vec *isl_vec_read_from_file(isl_ctx *ctx, FILE *input)
{
isl_vec *v;
struct isl_stream *s = isl_stream_new_file(ctx, input);
if (!s)
return NULL;
- v = vec_read(s, input_format);
+ v = vec_read(s);
isl_stream_free(s);
return v;
}