__isl_take isl_space *domain,
__isl_take isl_space *range);
__isl_give isl_space *isl_space_zip(__isl_take isl_space *space);
+ __isl_give isl_space *isl_space_curry(
+ __isl_take isl_space *space);
Note that if dimensions are added or removed from a space, then
the name and the internal structure are lost.
can be computed,
i.e., whether both domain and range are nested relations.
+=item * Currying
+
+ int isl_basic_map_can_curry(
+ __isl_keep isl_basic_map *bmap);
+ int isl_map_can_curry(__isl_keep isl_map *map);
+
+Check whether the domain of the (basic) relation is a wrapped relation.
+
=back
=head3 Binary Properties
Given a relation with nested relations for domain and range,
interchange the range of the domain with the domain of the range.
+=item * Currying
+
+ __isl_give isl_basic_map *isl_basic_map_curry(
+ __isl_take isl_basic_map *bmap);
+ __isl_give isl_map *isl_map_curry(
+ __isl_take isl_map *map);
+ __isl_give isl_union_map *isl_union_map_curry(
+ __isl_take isl_union_map *umap);
+
+Given a relation with a nested relation for domain,
+move the range of the nested relation out of the domain
+and use it as the domain of a nested relation in the range,
+with the original range as range of this nested relation.
+
=item * Aligning parameters
__isl_give isl_set *isl_set_align_params(
__isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap);
__isl_give isl_map *isl_map_zip(__isl_take isl_map *map);
+int isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap);
+int isl_map_can_curry(__isl_keep isl_map *map);
+__isl_give isl_basic_map *isl_basic_map_curry(__isl_take isl_basic_map *bmap);
+__isl_give isl_map *isl_map_curry(__isl_take isl_map *map);
+
__isl_give isl_map *isl_map_make_disjoint(__isl_take isl_map *map);
__isl_give isl_map *isl_basic_map_compute_divs(__isl_take isl_basic_map *bmap);
__isl_give isl_map *isl_map_compute_divs(__isl_take isl_map *map);
int isl_space_can_zip(__isl_keep isl_space *dim);
__isl_give isl_space *isl_space_zip(__isl_take isl_space *dim);
+int isl_space_can_curry(__isl_keep isl_space *space);
+__isl_give isl_space *isl_space_curry(__isl_take isl_space *space);
+
int isl_space_is_equal(__isl_keep isl_space *dim1, __isl_keep isl_space *dim2);
int isl_space_match(__isl_keep isl_space *dim1, enum isl_dim_type dim1_type,
__isl_keep isl_space *dim2, enum isl_dim_type dim2_type);
__isl_give isl_union_map *isl_union_set_unwrap(__isl_take isl_union_set *uset);
__isl_give isl_union_map *isl_union_map_zip(__isl_take isl_union_map *umap);
+__isl_give isl_union_map *isl_union_map_curry(__isl_take isl_union_map *umap);
__isl_give isl_union_map *isl_union_map_align_params(
__isl_take isl_union_map *umap, __isl_take isl_space *model);
return NULL;
}
+/* Can we apply isl_basic_map_curry to "bmap"?
+ * That is, does it have a nested relation in its domain?
+ */
+int isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap)
+{
+ if (!bmap)
+ return -1;
+
+ return isl_space_can_curry(bmap->dim);
+}
+
+/* Can we apply isl_map_curry to "map"?
+ * That is, does it have a nested relation in its domain?
+ */
+int isl_map_can_curry(__isl_keep isl_map *map)
+{
+ if (!map)
+ return -1;
+
+ return isl_space_can_curry(map->dim);
+}
+
+/* Given a basic map (A -> B) -> C, return the corresponding basic map
+ * A -> (B -> C).
+ */
+__isl_give isl_basic_map *isl_basic_map_curry(__isl_take isl_basic_map *bmap)
+{
+
+ if (!bmap)
+ return NULL;
+
+ if (!isl_basic_map_can_curry(bmap))
+ isl_die(bmap->ctx, isl_error_invalid,
+ "basic map cannot be curried", goto error);
+ bmap->dim = isl_space_curry(bmap->dim);
+ if (!bmap->dim)
+ goto error;
+ return bmap;
+error:
+ isl_basic_map_free(bmap);
+ return NULL;
+}
+
+/* Given a map (A -> B) -> C, return the corresponding map
+ * A -> (B -> C).
+ */
+__isl_give isl_map *isl_map_curry(__isl_take isl_map *map)
+{
+ int i;
+
+ if (!map)
+ return NULL;
+
+ if (!isl_map_can_curry(map))
+ isl_die(map->ctx, isl_error_invalid, "map cannot be curried",
+ goto error);
+
+ map = isl_map_cow(map);
+ if (!map)
+ return NULL;
+
+ for (i = 0; i < map->n; ++i) {
+ map->p[i] = isl_basic_map_curry(map->p[i]);
+ if (!map->p[i])
+ goto error;
+ }
+
+ map->dim = isl_space_curry(map->dim);
+ if (!map->dim)
+ goto error;
+
+ return map;
+error:
+ isl_map_free(map);
+ return NULL;
+}
+
/* Construct a basic map mapping the domain of the affine expression
* to a one-dimensional range prescribed by the affine expression.
*/
return NULL;
}
+/* Can we apply isl_space_curry to "space"?
+ * That is, does it have a nested relation in its domain?
+ */
+int isl_space_can_curry(__isl_keep isl_space *space)
+{
+ if (!space)
+ return -1;
+
+ return !!space->nested[0];
+}
+
+/* Given a space (A -> B) -> C, return the corresponding space
+ * A -> (B -> C).
+ */
+__isl_give isl_space *isl_space_curry(__isl_take isl_space *space)
+{
+ isl_space *dom, *ran;
+ isl_space *dom_dom, *dom_ran;
+
+ if (!space)
+ return NULL;
+
+ if (!isl_space_can_curry(space))
+ isl_die(space->ctx, isl_error_invalid,
+ "space cannot be curried", goto error);
+
+ dom = isl_space_unwrap(isl_space_domain(isl_space_copy(space)));
+ ran = isl_space_range(space);
+ dom_dom = isl_space_domain(isl_space_copy(dom));
+ dom_ran = isl_space_range(dom);
+ ran = isl_space_join(isl_space_from_domain(dom_ran),
+ isl_space_from_range(ran));
+ return isl_space_join(isl_space_from_domain(dom_dom),
+ isl_space_from_range(isl_space_wrap(ran)));
+error:
+ isl_space_free(space);
+ return NULL;
+}
+
int isl_space_has_named_params(__isl_keep isl_space *dim)
{
int i;
return cond_un_op(umap, &zip_entry);
}
+static int curry_entry(void **entry, void *user)
+{
+ isl_map *map = *entry;
+ isl_union_map **res = user;
+
+ if (!isl_map_can_curry(map))
+ return 0;
+
+ *res = isl_union_map_add_map(*res, isl_map_curry(isl_map_copy(map)));
+
+ return 0;
+}
+
+/* Given a union map, take the maps of the form (A -> B) -> C and
+ * return the union of the corresponding maps A -> (B -> C).
+ */
+__isl_give isl_union_map *isl_union_map_curry(__isl_take isl_union_map *umap)
+{
+ return cond_un_op(umap, &curry_entry);
+}
+
static int lift_entry(void **entry, void *user)
{
isl_set *set = *entry;