add some functions for manipulating constraints
authorSven Verdoolaege <skimo@kotnet.org>
Wed, 1 Oct 2008 18:10:23 +0000 (20:10 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Tue, 14 Oct 2008 08:22:00 +0000 (10:22 +0200)
Makefile.am
include/isl_constraint.h [new file with mode: 0644]
include/isl_int.h
isl_constraint.c [new file with mode: 0644]
isl_map.c
isl_map_private.h

index 46906f1..b0f8847 100644 (file)
@@ -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 (file)
index 0000000..76a94c3
--- /dev/null
@@ -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
index 48e4bf9..8015a58 100644 (file)
@@ -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 (file)
index 0000000..349f62d
--- /dev/null
@@ -0,0 +1,288 @@
+#include <isl_constraint.h>
+#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;
+}
index b62a7b5..1b6aa1f 100644 (file)
--- 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;
index 9cf195f..9782e8c 100644 (file)
@@ -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);