From: Sven Verdoolaege Date: Wed, 1 Oct 2008 18:10:23 +0000 (+0200) Subject: add some functions for manipulating constraints X-Git-Tag: isl-0.01~368 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c7afc410b0f1df1261a742c9bb46eabf6b991d01;p=platform%2Fupstream%2Fisl.git add some functions for manipulating constraints --- diff --git a/Makefile.am b/Makefile.am index 46906f1..b0f8847 100644 --- a/Makefile.am +++ b/Makefile.am @@ -36,6 +36,7 @@ libisl_la_SOURCES = \ $(ISL_POLYLIB) \ isl_affine_hull.c \ isl_blk.c \ + isl_constraint.c \ isl_convex_hull.c \ isl_ctx.c \ isl_equalities.c \ @@ -78,6 +79,7 @@ isl_test_LDADD = libisl.la pkginclude_HEADERS = \ include/isl_blk.h \ + include/isl_constraint.h \ include/isl_ctx.h \ include/isl_int.h \ include/isl_list.h \ diff --git a/include/isl_constraint.h b/include/isl_constraint.h new file mode 100644 index 0000000..76a94c3 --- /dev/null +++ b/include/isl_constraint.h @@ -0,0 +1,73 @@ +#ifndef ISL_CONSTRAINT_H +#define ISL_CONSTRAINT_H + +#include "isl_set.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +struct isl_basic_set_constraint { + struct isl_basic_set *bset; + isl_int **line; +}; + +struct isl_basic_set *isl_basic_set_constraint_set( + struct isl_basic_set_constraint constraint); + +struct isl_basic_set_constraint isl_basic_set_constraint_invalid(); +struct isl_basic_set_constraint isl_basic_set_first_constraint( + struct isl_basic_set *bset); +struct isl_basic_set_constraint isl_basic_set_constraint_next( + struct isl_basic_set_constraint constraint); +int isl_basic_set_constraint_is_valid( + struct isl_basic_set_constraint constraint); +int isl_basic_set_constraint_is_equal( + struct isl_basic_set_constraint constraint1, + struct isl_basic_set_constraint constraint2); + +int isl_basic_set_has_defining_equality( + struct isl_basic_set *bset, int pos, + struct isl_basic_set_constraint *constraint); +int isl_basic_set_has_defining_inequalities( + struct isl_basic_set *bset, int pos, + struct isl_basic_set_constraint *lower, + struct isl_basic_set_constraint *upper); + +int isl_basic_set_constraint_nparam( + struct isl_basic_set_constraint constraint); +int isl_basic_set_constraint_dim( + struct isl_basic_set_constraint constraint); +int isl_basic_set_constraint_n_div( + struct isl_basic_set_constraint constraint); + +void isl_basic_set_constraint_get_constant( + struct isl_basic_set_constraint constraint, isl_int *v); +void isl_basic_set_constraint_get_dim( + struct isl_basic_set_constraint constraint, int pos, isl_int *v); +void isl_basic_set_constraint_get_param( + struct isl_basic_set_constraint constraint, int pos, isl_int *v); +void isl_basic_set_constraint_get_div( + struct isl_basic_set_constraint constraint, int pos, isl_int *v); +void isl_basic_set_constraint_set_dim( + struct isl_basic_set_constraint constraint, int pos, isl_int v); +void isl_basic_set_constraint_set_param( + struct isl_basic_set_constraint constraint, int pos, isl_int v); + +void isl_basic_set_constraint_clear(struct isl_basic_set_constraint constraint); + +int isl_basic_set_constraint_is_equality( + struct isl_basic_set_constraint constraint); +int isl_basic_set_constraint_is_dim_lower_bound( + struct isl_basic_set_constraint constraint, int pos); +int isl_basic_set_constraint_is_dim_upper_bound( + struct isl_basic_set_constraint constraint, int pos); + +struct isl_basic_set *isl_basic_set_from_constraint( + struct isl_basic_set_constraint constraint); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/include/isl_int.h b/include/isl_int.h index 48e4bf9..8015a58 100644 --- a/include/isl_int.h +++ b/include/isl_int.h @@ -62,6 +62,7 @@ typedef mpz_t isl_int; #define isl_int_abs_ne(i,j) (mpz_cmpabs(i,j) != 0) #define isl_int_abs_lt(i,j) (mpz_cmpabs(i,j) < 0) #define isl_int_abs_gt(i,j) (mpz_cmpabs(i,j) > 0) +#define isl_int_abs_ge(i,j) (mpz_cmpabs(i,j) >= 0) #define isl_int_is_zero(i) (isl_int_sgn(i) == 0) diff --git a/isl_constraint.c b/isl_constraint.c new file mode 100644 index 0000000..349f62d --- /dev/null +++ b/isl_constraint.c @@ -0,0 +1,288 @@ +#include +#include "isl_map_private.h" + +struct isl_basic_set *isl_basic_set_constraint_set( + struct isl_basic_set_constraint constraint) +{ + return constraint.bset; +} + +struct isl_basic_set_constraint isl_basic_set_constraint_invalid() +{ + struct isl_basic_set_constraint c; + c.bset = NULL; + c.line = NULL; + return c; +} + +struct isl_basic_set_constraint isl_basic_set_first_constraint( + struct isl_basic_set *bset) +{ + struct isl_basic_set_constraint c; + + if (!bset) + return isl_basic_set_constraint_invalid(); + + if (bset->n_eq > 0) { + c.bset = bset; + c.line = &bset->eq[0]; + return c; + } + + if (bset->n_ineq > 0) { + c.bset = bset; + c.line = &bset->ineq[0]; + return c; + } + + return isl_basic_set_constraint_invalid(); +} + +struct isl_basic_set_constraint isl_basic_set_constraint_next( + struct isl_basic_set_constraint constraint) +{ + struct isl_basic_set_constraint c = constraint; + + c.line++; + if (c.line >= c.bset->eq + c.bset->n_eq && c.line < c.bset->ineq) + c.line = c.bset->ineq; + if (c.line >= c.bset->ineq + c.bset->n_ineq) + return isl_basic_set_constraint_invalid(); + return c; +} + +int isl_basic_set_constraint_is_valid( + struct isl_basic_set_constraint constraint) +{ + return constraint.bset != NULL && constraint.line != NULL; +} + +int isl_basic_set_constraint_is_equal( + struct isl_basic_set_constraint constraint1, + struct isl_basic_set_constraint constraint2) +{ + return constraint1.bset == constraint2.bset && + constraint1.line == constraint2.line; +} + +int isl_basic_set_constraint_nparam( + struct isl_basic_set_constraint constraint) +{ + if (!isl_basic_set_constraint_is_valid(constraint)) + return -1; + return constraint.bset->nparam; +} + +int isl_basic_set_constraint_dim( + struct isl_basic_set_constraint constraint) +{ + if (!isl_basic_set_constraint_is_valid(constraint)) + return -1; + return constraint.bset->dim; +} + +int isl_basic_set_constraint_n_div( + struct isl_basic_set_constraint constraint) +{ + if (!isl_basic_set_constraint_is_valid(constraint)) + return -1; + return constraint.bset->n_div; +} + +void isl_basic_set_constraint_get_constant( + struct isl_basic_set_constraint constraint, isl_int *v) +{ + if (!isl_basic_set_constraint_is_valid(constraint)) + return; + isl_int_set(*v, constraint.line[0][0]); +} + +void isl_basic_set_constraint_get_dim( + struct isl_basic_set_constraint constraint, int pos, isl_int *v) +{ + if (!isl_basic_set_constraint_is_valid(constraint)) + return; + isl_assert(constraint.bset->ctx, pos < constraint.bset->dim, return); + isl_int_set(*v, constraint.line[0][1 + constraint.bset->nparam + pos]); +} + +void isl_basic_set_constraint_get_div( + struct isl_basic_set_constraint constraint, int pos, isl_int *v) +{ + if (!isl_basic_set_constraint_is_valid(constraint)) + return; + isl_assert(constraint.bset->ctx, pos < constraint.bset->n_div, return); + isl_int_set(*v, constraint.line[0][1 + constraint.bset->nparam + + constraint.bset->dim + pos]); +} + +void isl_basic_set_constraint_get_param( + struct isl_basic_set_constraint constraint, int pos, isl_int *v) +{ + if (!isl_basic_set_constraint_is_valid(constraint)) + return; + isl_assert(constraint.bset->ctx, pos < constraint.bset->nparam, return); + isl_int_set(*v, constraint.line[0][1 + pos]); +} + +void isl_basic_set_constraint_set_dim( + struct isl_basic_set_constraint constraint, int pos, isl_int v) +{ + if (!isl_basic_set_constraint_is_valid(constraint)) + return; + isl_assert(constraint.bset->ctx, constraint.bset->ref == 1, return); + isl_assert(constraint.bset->ctx, pos < constraint.bset->dim, return); + isl_int_set(constraint.line[0][1 + constraint.bset->nparam + pos], v); +} + +void isl_basic_set_constraint_set_param( + struct isl_basic_set_constraint constraint, int pos, isl_int v) +{ + if (!isl_basic_set_constraint_is_valid(constraint)) + return; + isl_assert(constraint.bset->ctx, constraint.bset->ref == 1, return); + isl_assert(constraint.bset->ctx, pos < constraint.bset->nparam, return); + isl_int_set(constraint.line[0][1 + pos], v); +} + +void isl_basic_set_constraint_clear(struct isl_basic_set_constraint constraint) +{ + struct isl_basic_set *bset = constraint.bset; + unsigned total; + + if (!isl_basic_set_constraint_is_valid(constraint)) + return; + total = bset->nparam + bset->dim + bset->n_div; + isl_seq_clr(constraint.line[0], 1 + total); +} + +int isl_basic_set_constraint_is_equality( + struct isl_basic_set_constraint constraint) +{ + if (!isl_basic_set_constraint_is_valid(constraint)) + return -1; + return constraint.line < constraint.bset->eq + constraint.bset->n_eq; +} + +int isl_basic_set_constraint_is_dim_lower_bound( + struct isl_basic_set_constraint constraint, int pos) +{ + if (!isl_basic_set_constraint_is_valid(constraint)) + return -1; + isl_assert(constraint.bset->ctx, pos < constraint.bset->dim, return -1); + return isl_int_is_pos(constraint.line[0][1+constraint.bset->nparam+pos]); +} + +int isl_basic_set_constraint_is_dim_upper_bound( + struct isl_basic_set_constraint constraint, int pos) +{ + if (!isl_basic_set_constraint_is_valid(constraint)) + return -1; + isl_assert(constraint.bset->ctx, pos < constraint.bset->dim, return -1); + return isl_int_is_neg(constraint.line[0][1+constraint.bset->nparam+pos]); +} + + +struct isl_basic_set *isl_basic_set_from_constraint( + struct isl_basic_set_constraint constraint) +{ + int k; + struct isl_basic_set *bset; + isl_int *c; + unsigned total; + + if (!isl_basic_set_constraint_is_valid(constraint)) + return NULL; + + bset = isl_basic_set_universe(constraint.bset->ctx, + constraint.bset->nparam, constraint.bset->dim); + bset = isl_basic_set_align_divs(bset, constraint.bset); + bset = isl_basic_set_extend(bset, bset->nparam, bset->dim, 0, 1, 1); + if (isl_basic_set_constraint_is_equality(constraint)) { + k = isl_basic_set_alloc_equality(bset); + if (k < 0) + goto error; + c = bset->eq[k]; + } + else { + k = isl_basic_set_alloc_inequality(bset); + if (k < 0) + goto error; + c = bset->ineq[k]; + } + total = bset->nparam + bset->dim + bset->n_div; + isl_seq_cpy(c, constraint.line[0], 1 + total); + return bset; +error: + isl_basic_set_free(bset); + return NULL; +} + +int isl_basic_set_has_defining_equality( + struct isl_basic_set *bset, int pos, + struct isl_basic_set_constraint *constraint) +{ + int i; + + if (!bset) + return -1; + isl_assert(bset->ctx, pos < bset->dim, return -1); + for (i = 0; i < bset->n_eq; ++i) + if (!isl_int_is_zero(bset->eq[i][1 + bset->nparam + pos]) && + isl_seq_first_non_zero(bset->eq[i]+1+bset->nparam+pos+1, + bset->dim-pos-1) == -1) { + constraint->bset = bset; + constraint->line = &bset->eq[i]; + return 1; + } + return 0; +} + +int isl_basic_set_has_defining_inequalities( + struct isl_basic_set *bset, int pos, + struct isl_basic_set_constraint *lower, + struct isl_basic_set_constraint *upper) +{ + int i, j; + unsigned total; + isl_int m; + + if (!bset) + return -1; + isl_assert(bset->ctx, pos < bset->dim, return -1); + total = bset->nparam + bset->dim + bset->n_div; + isl_int_init(m); + for (i = 0; i < bset->n_ineq; ++i) { + if (isl_int_is_zero(bset->ineq[i][1 + bset->nparam + pos])) + continue; + if (isl_int_is_one(bset->ineq[i][1 + bset->nparam + pos])) + continue; + if (isl_int_is_negone(bset->ineq[i][1 + bset->nparam + pos])) + continue; + if (isl_seq_first_non_zero(bset->ineq[i]+1+bset->nparam+pos+1, + bset->dim-pos-1) != -1) + continue; + for (j = i + i; j < bset->n_ineq; ++j) { + if (!isl_seq_is_neg(bset->ineq[i]+1, bset->ineq[j]+1, + total)) + continue; + isl_int_add(m, bset->ineq[i][0], bset->ineq[j][0]); + if (isl_int_abs_ge(m, bset->ineq[i][1+bset->nparam+pos])) + continue; + + lower->bset = bset; + upper->bset = bset; + if (isl_int_is_pos(bset->ineq[i][1+bset->nparam+pos])) { + lower->line = &bset->ineq[i]; + upper->line = &bset->ineq[j]; + } else { + lower->line = &bset->ineq[j]; + upper->line = &bset->ineq[i]; + } + isl_int_clear(m); + return 1; + } + } + isl_int_clear(m); + return 0; +} diff --git a/isl_map.c b/isl_map.c index b62a7b5..1b6aa1f 100644 --- a/isl_map.c +++ b/isl_map.c @@ -3696,6 +3696,9 @@ struct isl_basic_map *isl_basic_map_align_divs( int i; unsigned total = src->nparam + src->n_in + src->n_out + src->n_div; + if (!dst || !src) + goto error; + if (src->n_div == 0) return dst; @@ -3725,6 +3728,13 @@ error: return NULL; } +struct isl_basic_set *isl_basic_set_align_divs( + struct isl_basic_set *dst, struct isl_basic_set *src) +{ + return (struct isl_basic_set *)isl_basic_map_align_divs( + (struct isl_basic_map *)dst, (struct isl_basic_map *)src); +} + struct isl_map *isl_map_align_divs(struct isl_map *map) { int i; diff --git a/isl_map_private.h b/isl_map_private.h index 9cf195f..9782e8c 100644 --- a/isl_map_private.h +++ b/isl_map_private.h @@ -30,6 +30,8 @@ struct isl_map *isl_basic_map_compute_divs(struct isl_basic_map *bmap); struct isl_map *isl_map_compute_divs(struct isl_map *map); struct isl_basic_map *isl_basic_map_align_divs( struct isl_basic_map *dst, struct isl_basic_map *src); +struct isl_basic_set *isl_basic_set_align_divs( + struct isl_basic_set *dst, struct isl_basic_set *src); struct isl_map *isl_map_align_divs(struct isl_map *map); struct isl_basic_map *isl_basic_map_gauss( struct isl_basic_map *bmap, int *progress);