return 1;
}
+/* Check if the given basic map is single-valued.
+ * We simply compute
+ *
+ * M \circ M^-1
+ *
+ * and check if the result is a subset of the identity mapping.
+ */
+int isl_basic_map_is_single_valued(__isl_keep isl_basic_map *bmap)
+{
+ isl_space *space;
+ isl_basic_map *test;
+ isl_basic_map *id;
+ int sv;
+
+ sv = isl_basic_map_plain_is_single_valued(bmap);
+ if (sv < 0 || sv)
+ return sv;
+
+ test = isl_basic_map_reverse(isl_basic_map_copy(bmap));
+ test = isl_basic_map_apply_range(test, isl_basic_map_copy(bmap));
+
+ space = isl_basic_map_get_space(bmap);
+ space = isl_space_map_from_set(isl_space_range(space));
+ id = isl_basic_map_identity(space);
+
+ sv = isl_basic_map_is_subset(test, id);
+
+ isl_basic_map_free(test);
+ isl_basic_map_free(id);
+
+ return sv;
+}
+
/* Check if the given map is obviously single-valued.
*/
int isl_map_plain_is_single_valued(__isl_keep isl_map *map)
return isl_map_equate(set, type1, pos1, type2, pos2);
}
-/* Add a constraint imposing that the given two dimensions are equal.
+/* Construct a basic map where the given dimensions are equal to each other.
*/
-__isl_give isl_map *isl_map_equate(__isl_take isl_map *map,
+static __isl_give isl_basic_map *equator(__isl_take isl_space *space,
enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
{
isl_basic_map *bmap = NULL;
int i;
- if (!map)
+ if (!space)
return NULL;
- if (pos1 >= isl_map_dim(map, type1))
- isl_die(map->ctx, isl_error_invalid,
+ if (pos1 >= isl_space_dim(space, type1))
+ isl_die(isl_space_get_ctx(space), isl_error_invalid,
"index out of bounds", goto error);
- if (pos2 >= isl_map_dim(map, type2))
- isl_die(map->ctx, isl_error_invalid,
+ if (pos2 >= isl_space_dim(space, type2))
+ isl_die(isl_space_get_ctx(space), isl_error_invalid,
"index out of bounds", goto error);
- bmap = isl_basic_map_alloc_space(isl_map_get_space(map), 0, 1, 0);
+ bmap = isl_basic_map_alloc_space(isl_space_copy(space), 0, 1, 0);
i = isl_basic_map_alloc_equality(bmap);
if (i < 0)
goto error;
isl_int_set_si(bmap->eq[i][pos1], -1);
isl_int_set_si(bmap->eq[i][pos2], 1);
bmap = isl_basic_map_finalize(bmap);
+ isl_space_free(space);
+ return bmap;
+error:
+ isl_space_free(space);
+ isl_basic_map_free(bmap);
+ return NULL;
+}
+
+/* Add a constraint imposing that the given two dimensions are equal.
+ */
+__isl_give isl_basic_map *isl_basic_map_equate(__isl_take isl_basic_map *bmap,
+ enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
+{
+ isl_basic_map *eq;
+
+ eq = equator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2);
+
+ bmap = isl_basic_map_intersect(bmap, eq);
+
+ return bmap;
+}
+
+/* Add a constraint imposing that the given two dimensions are equal.
+ */
+__isl_give isl_map *isl_map_equate(__isl_take isl_map *map,
+ enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
+{
+ isl_basic_map *bmap;
+
+ bmap = equator(isl_map_get_space(map), type1, pos1, type2, pos2);
map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
return map;
-error:
- isl_basic_map_free(bmap);
- isl_map_free(map);
- return NULL;
}
/* Add a constraint imposing that the given two dimensions have opposite values.