* Copyright 2008-2009 Katholieke Universiteit Leuven
* Copyright 2010 INRIA Saclay
*
- * Use of this software is governed by the GNU LGPLv2.1 license
+ * Use of this software is governed by the MIT license
*
* Written by Sven Verdoolaege, K.U.Leuven, Departement
* Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
#include <isl_map_private.h>
#include <isl_constraint_private.h>
#include <isl_space_private.h>
-#include <isl_div_private.h>
#include <isl/seq.h>
#include <isl_aff_private.h>
#include <isl_local_space_private.h>
+#include <isl_val_private.h>
+
+#undef BASE
+#define BASE constraint
+
+#include <isl_list_templ.c>
isl_ctx *isl_constraint_get_ctx(__isl_keep isl_constraint *c)
{
}
}
-__isl_give isl_constraint *isl_constraint_alloc(int eq,
+__isl_give isl_constraint *isl_constraint_alloc_vec(int eq,
__isl_take isl_local_space *ls, __isl_take isl_vec *v)
{
isl_constraint *constraint;
return NULL;
}
+__isl_give isl_constraint *isl_constraint_alloc(int eq,
+ __isl_take isl_local_space *ls)
+{
+ isl_ctx *ctx;
+ isl_vec *v;
+
+ if (!ls)
+ return NULL;
+
+ ctx = isl_local_space_get_ctx(ls);
+ v = isl_vec_alloc(ctx, 1 + isl_local_space_dim(ls, isl_dim_all));
+ v = isl_vec_clr(v);
+ return isl_constraint_alloc_vec(eq, ls, v);
+}
+
struct isl_constraint *isl_basic_map_constraint(struct isl_basic_map *bmap,
isl_int **line)
{
if (!v)
goto error;
isl_seq_cpy(v->el, line[0], v->size);
- constraint = isl_constraint_alloc(eq, ls, v);
+ constraint = isl_constraint_alloc_vec(eq, ls, v);
isl_basic_map_free(bmap);
return constraint;
return isl_basic_map_constraint((struct isl_basic_map *)bset, line);
}
-struct isl_constraint *isl_equality_alloc(__isl_take isl_space *dim)
+__isl_give isl_constraint *isl_equality_alloc(__isl_take isl_local_space *ls)
{
- struct isl_basic_map *bmap;
-
- if (!dim)
- return NULL;
-
- bmap = isl_basic_map_alloc_space(dim, 0, 1, 0);
- if (!bmap)
- return NULL;
-
- isl_basic_map_alloc_equality(bmap);
- isl_seq_clr(bmap->eq[0], 1 + isl_basic_map_total_dim(bmap));
- return isl_basic_map_constraint(bmap, &bmap->eq[0]);
+ return isl_constraint_alloc(1, ls);
}
-struct isl_constraint *isl_inequality_alloc(__isl_take isl_space *dim)
+__isl_give isl_constraint *isl_inequality_alloc(__isl_take isl_local_space *ls)
{
- struct isl_basic_map *bmap;
-
- if (!dim)
- return NULL;
-
- bmap = isl_basic_map_alloc_space(dim, 0, 0, 1);
- if (!bmap)
- return NULL;
-
- isl_basic_map_alloc_inequality(bmap);
- isl_seq_clr(bmap->ineq[0], 1 + isl_basic_map_total_dim(bmap));
- return isl_basic_map_constraint(bmap, &bmap->ineq[0]);
+ return isl_constraint_alloc(0, ls);
}
struct isl_constraint *isl_constraint_dup(struct isl_constraint *c)
if (!c)
return NULL;
- return isl_constraint_alloc(c->eq, isl_local_space_copy(c->ls),
+ return isl_constraint_alloc_vec(c->eq, isl_local_space_copy(c->ls),
isl_vec_copy(c->v));
}
return NULL;
}
+/* Return the number of constraints in "bset", i.e., the
+ * number of times isl_basic_set_foreach_constraint will
+ * call the callback.
+ */
+int isl_basic_set_n_constraint(__isl_keep isl_basic_set *bset)
+{
+ if (!bset)
+ return -1;
+
+ return bset->n_eq + bset->n_ineq;
+}
+
int isl_basic_map_foreach_constraint(__isl_keep isl_basic_map *bmap,
int (*fn)(__isl_take isl_constraint *c, void *user), void *user)
{
return constraint ? isl_local_space_get_space(constraint->ls) : NULL;
}
+__isl_give isl_local_space *isl_constraint_get_local_space(
+ __isl_keep isl_constraint *constraint)
+{
+ return constraint ? isl_local_space_copy(constraint->ls) : NULL;
+}
+
int isl_constraint_dim(struct isl_constraint *constraint,
enum isl_dim_type type)
{
return -1;
}
+/* Does the given constraint represent a lower bound on the given
+ * dimension?
+ */
+int isl_constraint_is_lower_bound(__isl_keep isl_constraint *constraint,
+ enum isl_dim_type type, unsigned pos)
+{
+ if (!constraint)
+ return -1;
+
+ if (pos >= isl_local_space_dim(constraint->ls, type))
+ isl_die(isl_constraint_get_ctx(constraint), isl_error_invalid,
+ "position out of bounds", return -1);
+
+ pos += isl_local_space_offset(constraint->ls, type);
+ return isl_int_is_pos(constraint->v->el[pos]);
+}
+
+/* Does the given constraint represent an upper bound on the given
+ * dimension?
+ */
+int isl_constraint_is_upper_bound(__isl_keep isl_constraint *constraint,
+ enum isl_dim_type type, unsigned pos)
+{
+ if (!constraint)
+ return -1;
+
+ if (pos >= isl_local_space_dim(constraint->ls, type))
+ isl_die(isl_constraint_get_ctx(constraint), isl_error_invalid,
+ "position out of bounds", return -1);
+
+ pos += isl_local_space_offset(constraint->ls, type);
+ return isl_int_is_neg(constraint->v->el[pos]);
+}
+
const char *isl_constraint_get_dim_name(__isl_keep isl_constraint *constraint,
enum isl_dim_type type, unsigned pos)
{
isl_int_set(*v, constraint->v->el[0]);
}
+/* Return the constant term of "constraint".
+ */
+__isl_give isl_val *isl_constraint_get_constant_val(
+ __isl_keep isl_constraint *constraint)
+{
+ isl_ctx *ctx;
+
+ if (!constraint)
+ return NULL;
+
+ ctx = isl_constraint_get_ctx(constraint);
+ return isl_val_int_from_isl_int(ctx, constraint->v->el[0]);
+}
+
void isl_constraint_get_coefficient(struct isl_constraint *constraint,
enum isl_dim_type type, int pos, isl_int *v)
{
isl_int_set(*v, constraint->v->el[pos]);
}
-struct isl_div *isl_constraint_div(struct isl_constraint *constraint, int pos)
+/* Return the coefficient of the variable of type "type" at position "pos"
+ * of "constraint".
+ */
+__isl_give isl_val *isl_constraint_get_coefficient_val(
+ __isl_keep isl_constraint *constraint, enum isl_dim_type type, int pos)
+{
+ isl_ctx *ctx;
+
+ if (!constraint)
+ return NULL;
+
+ ctx = isl_constraint_get_ctx(constraint);
+ if (pos < 0 || pos >= isl_local_space_dim(constraint->ls, type))
+ isl_die(ctx, isl_error_invalid,
+ "position out of bounds", return NULL);
+
+ pos += isl_local_space_offset(constraint->ls, type);
+ return isl_val_int_from_isl_int(ctx, constraint->v->el[pos]);
+}
+
+__isl_give isl_aff *isl_constraint_get_div(__isl_keep isl_constraint *constraint,
+ int pos)
{
if (!constraint)
return NULL;
return constraint;
}
+/* Replace the constant term of "constraint" by "v".
+ */
+__isl_give isl_constraint *isl_constraint_set_constant_val(
+ __isl_take isl_constraint *constraint, __isl_take isl_val *v)
+{
+ constraint = isl_constraint_cow(constraint);
+ if (!constraint || !v)
+ goto error;
+ if (!isl_val_is_int(v))
+ isl_die(isl_constraint_get_ctx(constraint), isl_error_invalid,
+ "expecting integer value", goto error);
+ constraint->v = isl_vec_set_element_val(constraint->v, 0, v);
+ if (!constraint->v)
+ constraint = isl_constraint_free(constraint);
+ return constraint;
+error:
+ isl_val_free(v);
+ return isl_constraint_free(constraint);
+}
+
__isl_give isl_constraint *isl_constraint_set_constant_si(
__isl_take isl_constraint *constraint, int v)
{
return constraint;
}
+/* Replace the coefficient of the variable of type "type" at position "pos"
+ * of "constraint" by "v".
+ */
+__isl_give isl_constraint *isl_constraint_set_coefficient_val(
+ __isl_take isl_constraint *constraint,
+ enum isl_dim_type type, int pos, isl_val *v)
+{
+ constraint = isl_constraint_cow(constraint);
+ if (!constraint || !v)
+ goto error;
+ if (!isl_val_is_int(v))
+ isl_die(isl_constraint_get_ctx(constraint), isl_error_invalid,
+ "expecting integer value", goto error);
+
+ if (pos >= isl_local_space_dim(constraint->ls, type))
+ isl_die(isl_constraint_get_ctx(constraint), isl_error_invalid,
+ "position out of bounds", goto error);
+
+ pos += isl_local_space_offset(constraint->ls, type);
+ constraint->v = isl_vec_set_element_val(constraint->v, pos, v);
+ if (!constraint->v)
+ constraint = isl_constraint_free(constraint);
+ return constraint;
+error:
+ isl_val_free(v);
+ return isl_constraint_free(constraint);
+}
+
__isl_give isl_constraint *isl_constraint_set_coefficient_si(
__isl_take isl_constraint *constraint,
enum isl_dim_type type, int pos, int v)
return aff;
}
-/* Construct an equality constraint equating the given affine expression
- * to zero.
+/* Construct an inequality (eq = 0) or equality (eq = 1) constraint from "aff".
+ * In particular, construct aff >= 0 or aff = 0.
+ *
+ * The denominator of "aff" can be ignored.
*/
-__isl_give isl_constraint *isl_equality_from_aff(__isl_take isl_aff *aff)
+static __isl_give isl_constraint *isl_constraint_alloc_aff(int eq,
+ __isl_take isl_aff *aff)
{
- int k;
isl_local_space *ls;
- isl_basic_set *bset;
+ isl_vec *v;
if (!aff)
return NULL;
-
ls = isl_aff_get_domain_local_space(aff);
- bset = isl_basic_set_from_local_space(ls);
- bset = isl_basic_set_extend_constraints(bset, 1, 0);
- k = isl_basic_set_alloc_equality(bset);
- if (k < 0)
- goto error;
-
- isl_seq_cpy(bset->eq[k], aff->v->el + 1, aff->v->size - 1);
+ v = isl_vec_drop_els(isl_vec_copy(aff->v), 0, 1);
isl_aff_free(aff);
- return isl_basic_set_constraint(bset, &bset->eq[k]);
-error:
- isl_aff_free(aff);
- isl_basic_set_free(bset);
- return NULL;
+ return isl_constraint_alloc_vec(eq, ls, v);
+}
+
+/* Construct an equality constraint equating the given affine expression
+ * to zero.
+ */
+__isl_give isl_constraint *isl_equality_from_aff(__isl_take isl_aff *aff)
+{
+ return isl_constraint_alloc_aff(1, aff);
}
/* Construct an inequality constraint enforcing the given affine expression
*/
__isl_give isl_constraint *isl_inequality_from_aff(__isl_take isl_aff *aff)
{
- int k;
- isl_local_space *ls;
- isl_basic_set *bset;
-
- if (!aff)
- return NULL;
-
- ls = isl_aff_get_domain_local_space(aff);
- bset = isl_basic_set_from_local_space(ls);
- bset = isl_basic_set_extend_constraints(bset, 0, 1);
- k = isl_basic_set_alloc_inequality(bset);
- if (k < 0)
- goto error;
-
- isl_seq_cpy(bset->ineq[k], aff->v->el + 1, aff->v->size - 1);
- isl_aff_free(aff);
-
- return isl_basic_set_constraint(bset, &bset->ineq[k]);
-error:
- isl_aff_free(aff);
- isl_basic_set_free(bset);
- return NULL;
+ return isl_constraint_alloc_aff(0, aff);
}