add isl_set_dim_residue_class
authorSven Verdoolaege <skimo@kotnet.org>
Mon, 5 Oct 2009 21:15:30 +0000 (23:15 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Mon, 5 Oct 2009 21:15:30 +0000 (23:15 +0200)
include/isl_set.h
isl_equalities.c

index c42a0a3..3128966 100644 (file)
@@ -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);
 
index 1702620..549c1b8 100644 (file)
@@ -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;
+}