add isl_union_map_curry
authorSven Verdoolaege <skimo@kotnet.org>
Thu, 29 Mar 2012 14:01:39 +0000 (16:01 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Sun, 6 May 2012 12:33:05 +0000 (14:33 +0200)
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
doc/user.pod
include/isl/map.h
include/isl/space.h
include/isl/union_map.h
isl_map.c
isl_space.c
isl_union_map.c

index f98927e..1914704 100644 (file)
@@ -789,6 +789,8 @@ using the following functions.
                __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.
@@ -1703,6 +1705,14 @@ Check whether the product of domain and range of the given relation
 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
@@ -2278,6 +2288,20 @@ can be constructed using the following function.
 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(
index 7248194..39578d6 100644 (file)
@@ -502,6 +502,11 @@ int isl_map_can_zip(__isl_keep isl_map *map);
 __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);
index 9b54df5..14746d0 100644 (file)
@@ -119,6 +119,9 @@ __isl_give isl_space *isl_space_unwrap(__isl_take isl_space *dim);
 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);
index 4d01c55..8b531f3 100644 (file)
@@ -173,6 +173,7 @@ __isl_give isl_union_set *isl_union_map_wrap(__isl_take isl_union_map *umap);
 __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);
index 6276119..e6cee22 100644 (file)
--- a/isl_map.c
+++ b/isl_map.c
@@ -9818,6 +9818,83 @@ error:
        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.
  */
index c17c96b..0c71724 100644 (file)
@@ -1669,6 +1669,45 @@ error:
        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;
index d27d5c5..b1d0096 100644 (file)
@@ -2249,6 +2249,27 @@ __isl_give isl_union_map *isl_union_map_zip(__isl_take isl_union_map *umap)
        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;