From 3f4263c874659483bd16047a64f8491fc1df4ca8 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 5 Oct 2009 23:15:30 +0200 Subject: [PATCH] add isl_set_dim_residue_class --- include/isl_set.h | 2 ++ isl_equalities.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/include/isl_set.h b/include/isl_set.h index c42a0a3..3128966 100644 --- a/include/isl_set.h +++ b/include/isl_set.h @@ -238,6 +238,8 @@ struct isl_set *isl_set_gist(struct isl_set *set, struct isl_basic_set *context); int isl_basic_set_dim_residue_class(struct isl_basic_set *bset, int pos, isl_int *modulo, isl_int *residue); +int isl_set_dim_residue_class(struct isl_set *set, + int pos, isl_int *modulo, isl_int *residue); __isl_give isl_set *isl_set_coalesce(__isl_take isl_set *set); diff --git a/isl_equalities.c b/isl_equalities.c index 1702620..549c1b8 100644 --- a/isl_equalities.c +++ b/isl_equalities.c @@ -619,3 +619,67 @@ error: isl_mat_free(U); return -1; } + +/* Check if dimension dim belongs to a residue class + * i_dim \equiv r mod m + * with m != 1 and if so return m in *modulo and r in *residue. + * As a special case, when i_dim has a fixed value v, then + * *modulo is set to 0 and *residue to v. + * + * If i_dim does not belong to such a residue class, then *modulo + * is set to 1 and *residue is set to 0. + */ +int isl_set_dim_residue_class(struct isl_set *set, + int pos, isl_int *modulo, isl_int *residue) +{ + isl_int m; + isl_int r; + int i; + + if (!set || !modulo || !residue) + return -1; + + if (set->n == 0) { + isl_int_set_si(*modulo, 0); + isl_int_set_si(*residue, 0); + return 0; + } + + if (isl_basic_set_dim_residue_class(set->p[0], pos, modulo, residue)<0) + return -1; + + if (set->n == 1) + return 0; + + if (isl_int_is_one(*modulo)) + return 0; + + isl_int_init(m); + isl_int_init(r); + + for (i = 1; i < set->n; ++i) { + if (isl_basic_set_dim_residue_class(set->p[0], pos, &m, &r) < 0) + goto error; + isl_int_gcd(*modulo, *modulo, m); + if (!isl_int_is_zero(*modulo)) + isl_int_fdiv_r(*residue, *residue, *modulo); + if (isl_int_is_one(*modulo)) + break; + if (!isl_int_is_zero(*modulo)) + isl_int_fdiv_r(r, r, *modulo); + if (isl_int_ne(*residue, r)) { + isl_int_set_si(*modulo, 1); + isl_int_set_si(*residue, 0); + break; + } + } + + isl_int_clear(m); + isl_int_clear(r); + + return 0; +error: + isl_int_clear(m); + isl_int_clear(r); + return -1; +} -- 2.7.4