2 * Copyright 2010-2011 INRIA Saclay
4 * Use of this software is governed by the GNU LGPLv2.1 license
6 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
7 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
12 #include <isl_map_private.h>
17 #include <isl_space_private.h>
18 #include <isl_union_map_private.h>
19 #include <isl/union_set.h>
21 static __isl_give isl_union_map *isl_union_map_alloc(__isl_take isl_space *dim,
29 umap = isl_calloc_type(dim->ctx, isl_union_map);
35 if (isl_hash_table_init(dim->ctx, &umap->table, size) < 0)
41 isl_union_map_free(umap);
45 __isl_give isl_union_map *isl_union_map_empty(__isl_take isl_space *dim)
47 return isl_union_map_alloc(dim, 16);
50 __isl_give isl_union_set *isl_union_set_empty(__isl_take isl_space *dim)
52 return isl_union_map_empty(dim);
55 isl_ctx *isl_union_map_get_ctx(__isl_keep isl_union_map *umap)
57 return umap ? umap->dim->ctx : NULL;
60 isl_ctx *isl_union_set_get_ctx(__isl_keep isl_union_set *uset)
62 return uset ? uset->dim->ctx : NULL;
65 __isl_give isl_space *isl_union_map_get_space(__isl_keep isl_union_map *umap)
69 return isl_space_copy(umap->dim);
72 __isl_give isl_space *isl_union_set_get_space(__isl_keep isl_union_set *uset)
74 return isl_union_map_get_space(uset);
77 static int free_umap_entry(void **entry, void *user)
79 isl_map *map = *entry;
84 static int add_map(__isl_take isl_map *map, void *user)
86 isl_union_map **umap = (isl_union_map **)user;
88 *umap = isl_union_map_add_map(*umap, map);
93 __isl_give isl_union_map *isl_union_map_dup(__isl_keep isl_union_map *umap)
100 dup = isl_union_map_empty(isl_space_copy(umap->dim));
101 if (isl_union_map_foreach_map(umap, &add_map, &dup) < 0)
105 isl_union_map_free(dup);
109 __isl_give isl_union_map *isl_union_map_cow(__isl_take isl_union_map *umap)
117 return isl_union_map_dup(umap);
120 struct isl_union_align {
125 static int align_entry(void **entry, void *user)
127 isl_map *map = *entry;
129 struct isl_union_align *data = user;
131 exp = isl_reordering_extend_space(isl_reordering_copy(data->exp),
132 isl_map_get_space(map));
134 data->res = isl_union_map_add_map(data->res,
135 isl_map_realign(isl_map_copy(map), exp));
140 /* Align the parameters of umap along those of model.
141 * The result has the parameters of model first, in the same order
142 * as they appear in model, followed by any remaining parameters of
143 * umap that do not appear in model.
145 __isl_give isl_union_map *isl_union_map_align_params(
146 __isl_take isl_union_map *umap, __isl_take isl_space *model)
148 struct isl_union_align data = { NULL, NULL };
153 if (isl_space_match(umap->dim, isl_dim_param, model, isl_dim_param)) {
154 isl_space_free(model);
158 model = isl_space_params(model);
159 data.exp = isl_parameter_alignment_reordering(umap->dim, model);
163 data.res = isl_union_map_alloc(isl_space_copy(data.exp->dim),
165 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
166 &align_entry, &data) < 0)
169 isl_reordering_free(data.exp);
170 isl_union_map_free(umap);
171 isl_space_free(model);
174 isl_reordering_free(data.exp);
175 isl_union_map_free(umap);
176 isl_union_map_free(data.res);
177 isl_space_free(model);
181 __isl_give isl_union_set *isl_union_set_align_params(
182 __isl_take isl_union_set *uset, __isl_take isl_space *model)
184 return isl_union_map_align_params(uset, model);
187 __isl_give isl_union_map *isl_union_map_union(__isl_take isl_union_map *umap1,
188 __isl_take isl_union_map *umap2)
190 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2));
191 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1));
193 umap1 = isl_union_map_cow(umap1);
195 if (!umap1 || !umap2)
198 if (isl_union_map_foreach_map(umap2, &add_map, &umap1) < 0)
201 isl_union_map_free(umap2);
205 isl_union_map_free(umap1);
206 isl_union_map_free(umap2);
210 __isl_give isl_union_set *isl_union_set_union(__isl_take isl_union_set *uset1,
211 __isl_take isl_union_set *uset2)
213 return isl_union_map_union(uset1, uset2);
216 __isl_give isl_union_map *isl_union_map_copy(__isl_keep isl_union_map *umap)
225 __isl_give isl_union_set *isl_union_set_copy(__isl_keep isl_union_set *uset)
227 return isl_union_map_copy(uset);
230 void *isl_union_map_free(__isl_take isl_union_map *umap)
238 isl_hash_table_foreach(umap->dim->ctx, &umap->table,
239 &free_umap_entry, NULL);
240 isl_hash_table_clear(&umap->table);
241 isl_space_free(umap->dim);
246 void *isl_union_set_free(__isl_take isl_union_set *uset)
248 return isl_union_map_free(uset);
251 static int has_dim(const void *entry, const void *val)
253 isl_map *map = (isl_map *)entry;
254 isl_space *dim = (isl_space *)val;
256 return isl_space_is_equal(map->dim, dim);
259 __isl_give isl_union_map *isl_union_map_add_map(__isl_take isl_union_map *umap,
260 __isl_take isl_map *map)
263 struct isl_hash_table_entry *entry;
268 if (isl_map_plain_is_empty(map)) {
273 if (!isl_space_match(map->dim, isl_dim_param, umap->dim, isl_dim_param)) {
274 umap = isl_union_map_align_params(umap, isl_map_get_space(map));
275 map = isl_map_align_params(map, isl_union_map_get_space(umap));
278 umap = isl_union_map_cow(umap);
283 hash = isl_space_get_hash(map->dim);
284 entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
285 &has_dim, map->dim, 1);
292 entry->data = isl_map_union(entry->data, isl_map_copy(map));
301 isl_union_map_free(umap);
305 __isl_give isl_union_set *isl_union_set_add_set(__isl_take isl_union_set *uset,
306 __isl_take isl_set *set)
308 return isl_union_map_add_map(uset, (isl_map *)set);
311 __isl_give isl_union_map *isl_union_map_from_map(__isl_take isl_map *map)
319 dim = isl_map_get_space(map);
320 dim = isl_space_params(dim);
321 umap = isl_union_map_empty(dim);
322 umap = isl_union_map_add_map(umap, map);
327 __isl_give isl_union_set *isl_union_set_from_set(__isl_take isl_set *set)
329 return isl_union_map_from_map((isl_map *)set);
332 struct isl_union_map_foreach_data
334 int (*fn)(__isl_take isl_map *map, void *user);
338 static int call_on_copy(void **entry, void *user)
340 isl_map *map = *entry;
341 struct isl_union_map_foreach_data *data;
342 data = (struct isl_union_map_foreach_data *)user;
344 return data->fn(isl_map_copy(map), data->user);
347 int isl_union_map_n_map(__isl_keep isl_union_map *umap)
349 return umap ? umap->table.n : 0;
352 int isl_union_set_n_set(__isl_keep isl_union_set *uset)
354 return uset ? uset->table.n : 0;
357 int isl_union_map_foreach_map(__isl_keep isl_union_map *umap,
358 int (*fn)(__isl_take isl_map *map, void *user), void *user)
360 struct isl_union_map_foreach_data data = { fn, user };
365 return isl_hash_table_foreach(umap->dim->ctx, &umap->table,
366 &call_on_copy, &data);
369 static int copy_map(void **entry, void *user)
371 isl_map *map = *entry;
372 isl_map **map_p = user;
374 *map_p = isl_map_copy(map);
379 __isl_give isl_map *isl_map_from_union_map(__isl_take isl_union_map *umap)
386 ctx = isl_union_map_get_ctx(umap);
387 if (umap->table.n != 1)
388 isl_die(ctx, isl_error_invalid,
389 "union map needs to contain elements in exactly "
390 "one space", return isl_union_map_free(umap));
392 isl_hash_table_foreach(ctx, &umap->table, ©_map, &map);
394 isl_union_map_free(umap);
399 __isl_give isl_set *isl_set_from_union_set(__isl_take isl_union_set *uset)
401 return isl_map_from_union_map(uset);
404 __isl_give isl_map *isl_union_map_extract_map(__isl_keep isl_union_map *umap,
405 __isl_take isl_space *dim)
408 struct isl_hash_table_entry *entry;
413 hash = isl_space_get_hash(dim);
414 entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
417 return isl_map_empty(dim);
419 return isl_map_copy(entry->data);
425 __isl_give isl_set *isl_union_set_extract_set(__isl_keep isl_union_set *uset,
426 __isl_take isl_space *dim)
428 return (isl_set *)isl_union_map_extract_map(uset, dim);
431 /* Check if umap contains a map in the given space.
433 __isl_give int isl_union_map_contains(__isl_keep isl_union_map *umap,
434 __isl_keep isl_space *dim)
437 struct isl_hash_table_entry *entry;
442 hash = isl_space_get_hash(dim);
443 entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
448 __isl_give int isl_union_set_contains(__isl_keep isl_union_set *uset,
449 __isl_keep isl_space *dim)
451 return isl_union_map_contains(uset, dim);
454 int isl_union_set_foreach_set(__isl_keep isl_union_set *uset,
455 int (*fn)(__isl_take isl_set *set, void *user), void *user)
457 return isl_union_map_foreach_map(uset,
458 (int(*)(__isl_take isl_map *, void*))fn, user);
461 struct isl_union_set_foreach_point_data {
462 int (*fn)(__isl_take isl_point *pnt, void *user);
466 static int foreach_point(__isl_take isl_set *set, void *user)
468 struct isl_union_set_foreach_point_data *data = user;
471 r = isl_set_foreach_point(set, data->fn, data->user);
477 int isl_union_set_foreach_point(__isl_keep isl_union_set *uset,
478 int (*fn)(__isl_take isl_point *pnt, void *user), void *user)
480 struct isl_union_set_foreach_point_data data = { fn, user };
481 return isl_union_set_foreach_set(uset, &foreach_point, &data);
484 struct isl_union_map_gen_bin_data {
485 isl_union_map *umap2;
489 static int subtract_entry(void **entry, void *user)
491 struct isl_union_map_gen_bin_data *data = user;
493 struct isl_hash_table_entry *entry2;
494 isl_map *map = *entry;
496 hash = isl_space_get_hash(map->dim);
497 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
498 hash, &has_dim, map->dim, 0);
499 map = isl_map_copy(map);
502 map = isl_map_subtract(map, isl_map_copy(entry2->data));
504 empty = isl_map_is_empty(map);
514 data->res = isl_union_map_add_map(data->res, map);
519 static __isl_give isl_union_map *gen_bin_op(__isl_take isl_union_map *umap1,
520 __isl_take isl_union_map *umap2, int (*fn)(void **, void *))
522 struct isl_union_map_gen_bin_data data = { NULL, NULL };
524 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2));
525 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1));
527 if (!umap1 || !umap2)
531 data.res = isl_union_map_alloc(isl_space_copy(umap1->dim),
533 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
537 isl_union_map_free(umap1);
538 isl_union_map_free(umap2);
541 isl_union_map_free(umap1);
542 isl_union_map_free(umap2);
543 isl_union_map_free(data.res);
547 __isl_give isl_union_map *isl_union_map_subtract(
548 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
550 return gen_bin_op(umap1, umap2, &subtract_entry);
553 __isl_give isl_union_set *isl_union_set_subtract(
554 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
556 return isl_union_map_subtract(uset1, uset2);
559 struct isl_union_map_match_bin_data {
560 isl_union_map *umap2;
562 __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*);
565 static int match_bin_entry(void **entry, void *user)
567 struct isl_union_map_match_bin_data *data = user;
569 struct isl_hash_table_entry *entry2;
570 isl_map *map = *entry;
573 hash = isl_space_get_hash(map->dim);
574 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
575 hash, &has_dim, map->dim, 0);
579 map = isl_map_copy(map);
580 map = data->fn(map, isl_map_copy(entry2->data));
582 empty = isl_map_is_empty(map);
592 data->res = isl_union_map_add_map(data->res, map);
597 static __isl_give isl_union_map *match_bin_op(__isl_take isl_union_map *umap1,
598 __isl_take isl_union_map *umap2,
599 __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*))
601 struct isl_union_map_match_bin_data data = { NULL, NULL, fn };
603 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2));
604 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1));
606 if (!umap1 || !umap2)
610 data.res = isl_union_map_alloc(isl_space_copy(umap1->dim),
612 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
613 &match_bin_entry, &data) < 0)
616 isl_union_map_free(umap1);
617 isl_union_map_free(umap2);
620 isl_union_map_free(umap1);
621 isl_union_map_free(umap2);
622 isl_union_map_free(data.res);
626 __isl_give isl_union_map *isl_union_map_intersect(
627 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
629 return match_bin_op(umap1, umap2, &isl_map_intersect);
632 __isl_give isl_union_set *isl_union_set_intersect(
633 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
635 return isl_union_map_intersect(uset1, uset2);
638 __isl_give isl_union_map *isl_union_map_gist(__isl_take isl_union_map *umap,
639 __isl_take isl_union_map *context)
641 return match_bin_op(umap, context, &isl_map_gist);
644 __isl_give isl_union_set *isl_union_set_gist(__isl_take isl_union_set *uset,
645 __isl_take isl_union_set *context)
647 return isl_union_map_gist(uset, context);
650 static __isl_give isl_map *lex_le_set(__isl_take isl_map *set1,
651 __isl_take isl_map *set2)
653 return isl_set_lex_le_set((isl_set *)set1, (isl_set *)set2);
656 static __isl_give isl_map *lex_lt_set(__isl_take isl_map *set1,
657 __isl_take isl_map *set2)
659 return isl_set_lex_lt_set((isl_set *)set1, (isl_set *)set2);
662 __isl_give isl_union_map *isl_union_set_lex_lt_union_set(
663 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
665 return match_bin_op(uset1, uset2, &lex_lt_set);
668 __isl_give isl_union_map *isl_union_set_lex_le_union_set(
669 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
671 return match_bin_op(uset1, uset2, &lex_le_set);
674 __isl_give isl_union_map *isl_union_set_lex_gt_union_set(
675 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
677 return isl_union_map_reverse(isl_union_set_lex_lt_union_set(uset2, uset1));
680 __isl_give isl_union_map *isl_union_set_lex_ge_union_set(
681 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
683 return isl_union_map_reverse(isl_union_set_lex_le_union_set(uset2, uset1));
686 __isl_give isl_union_map *isl_union_map_lex_gt_union_map(
687 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
689 return isl_union_map_reverse(isl_union_map_lex_lt_union_map(umap2, umap1));
692 __isl_give isl_union_map *isl_union_map_lex_ge_union_map(
693 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
695 return isl_union_map_reverse(isl_union_map_lex_le_union_map(umap2, umap1));
698 static int intersect_domain_entry(void **entry, void *user)
700 struct isl_union_map_gen_bin_data *data = user;
702 struct isl_hash_table_entry *entry2;
704 isl_map *map = *entry;
707 dim = isl_map_get_space(map);
708 dim = isl_space_domain(dim);
709 hash = isl_space_get_hash(dim);
710 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
711 hash, &has_dim, dim, 0);
716 map = isl_map_copy(map);
717 map = isl_map_intersect_domain(map, isl_set_copy(entry2->data));
719 empty = isl_map_is_empty(map);
729 data->res = isl_union_map_add_map(data->res, map);
734 __isl_give isl_union_map *isl_union_map_intersect_domain(
735 __isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
737 return gen_bin_op(umap, uset, &intersect_domain_entry);
740 static int intersect_range_entry(void **entry, void *user)
742 struct isl_union_map_gen_bin_data *data = user;
744 struct isl_hash_table_entry *entry2;
746 isl_map *map = *entry;
749 dim = isl_map_get_space(map);
750 dim = isl_space_range(dim);
751 hash = isl_space_get_hash(dim);
752 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
753 hash, &has_dim, dim, 0);
758 map = isl_map_copy(map);
759 map = isl_map_intersect_range(map, isl_set_copy(entry2->data));
761 empty = isl_map_is_empty(map);
771 data->res = isl_union_map_add_map(data->res, map);
776 __isl_give isl_union_map *isl_union_map_intersect_range(
777 __isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
779 return gen_bin_op(umap, uset, &intersect_range_entry);
782 struct isl_union_map_bin_data {
783 isl_union_map *umap2;
786 int (*fn)(void **entry, void *user);
789 static int apply_range_entry(void **entry, void *user)
791 struct isl_union_map_bin_data *data = user;
792 isl_map *map2 = *entry;
795 if (!isl_space_tuple_match(data->map->dim, isl_dim_out,
796 map2->dim, isl_dim_in))
799 map2 = isl_map_apply_range(isl_map_copy(data->map), isl_map_copy(map2));
801 empty = isl_map_is_empty(map2);
811 data->res = isl_union_map_add_map(data->res, map2);
816 static int bin_entry(void **entry, void *user)
818 struct isl_union_map_bin_data *data = user;
819 isl_map *map = *entry;
822 if (isl_hash_table_foreach(data->umap2->dim->ctx, &data->umap2->table,
829 static __isl_give isl_union_map *bin_op(__isl_take isl_union_map *umap1,
830 __isl_take isl_union_map *umap2, int (*fn)(void **entry, void *user))
832 struct isl_union_map_bin_data data = { NULL, NULL, NULL, fn };
834 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2));
835 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1));
837 if (!umap1 || !umap2)
841 data.res = isl_union_map_alloc(isl_space_copy(umap1->dim),
843 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
844 &bin_entry, &data) < 0)
847 isl_union_map_free(umap1);
848 isl_union_map_free(umap2);
851 isl_union_map_free(umap1);
852 isl_union_map_free(umap2);
853 isl_union_map_free(data.res);
857 __isl_give isl_union_map *isl_union_map_apply_range(
858 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
860 return bin_op(umap1, umap2, &apply_range_entry);
863 __isl_give isl_union_map *isl_union_map_apply_domain(
864 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
866 umap1 = isl_union_map_reverse(umap1);
867 umap1 = isl_union_map_apply_range(umap1, umap2);
868 return isl_union_map_reverse(umap1);
871 __isl_give isl_union_set *isl_union_set_apply(
872 __isl_take isl_union_set *uset, __isl_take isl_union_map *umap)
874 return isl_union_map_apply_range(uset, umap);
877 static int map_lex_lt_entry(void **entry, void *user)
879 struct isl_union_map_bin_data *data = user;
880 isl_map *map2 = *entry;
882 if (!isl_space_tuple_match(data->map->dim, isl_dim_out,
883 map2->dim, isl_dim_out))
886 map2 = isl_map_lex_lt_map(isl_map_copy(data->map), isl_map_copy(map2));
888 data->res = isl_union_map_add_map(data->res, map2);
893 __isl_give isl_union_map *isl_union_map_lex_lt_union_map(
894 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
896 return bin_op(umap1, umap2, &map_lex_lt_entry);
899 static int map_lex_le_entry(void **entry, void *user)
901 struct isl_union_map_bin_data *data = user;
902 isl_map *map2 = *entry;
904 if (!isl_space_tuple_match(data->map->dim, isl_dim_out,
905 map2->dim, isl_dim_out))
908 map2 = isl_map_lex_le_map(isl_map_copy(data->map), isl_map_copy(map2));
910 data->res = isl_union_map_add_map(data->res, map2);
915 __isl_give isl_union_map *isl_union_map_lex_le_union_map(
916 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
918 return bin_op(umap1, umap2, &map_lex_le_entry);
921 static int product_entry(void **entry, void *user)
923 struct isl_union_map_bin_data *data = user;
924 isl_map *map2 = *entry;
926 map2 = isl_map_product(isl_map_copy(data->map), isl_map_copy(map2));
928 data->res = isl_union_map_add_map(data->res, map2);
933 __isl_give isl_union_map *isl_union_map_product(__isl_take isl_union_map *umap1,
934 __isl_take isl_union_map *umap2)
936 return bin_op(umap1, umap2, &product_entry);
939 __isl_give isl_union_set *isl_union_set_product(__isl_take isl_union_set *uset1,
940 __isl_take isl_union_set *uset2)
942 return isl_union_map_product(uset1, uset2);
945 static int range_product_entry(void **entry, void *user)
947 struct isl_union_map_bin_data *data = user;
948 isl_map *map2 = *entry;
950 if (!isl_space_tuple_match(data->map->dim, isl_dim_in,
951 map2->dim, isl_dim_in))
954 map2 = isl_map_range_product(isl_map_copy(data->map),
957 data->res = isl_union_map_add_map(data->res, map2);
962 __isl_give isl_union_map *isl_union_map_range_product(
963 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
965 return bin_op(umap1, umap2, &range_product_entry);
968 static int flat_range_product_entry(void **entry, void *user)
970 struct isl_union_map_bin_data *data = user;
971 isl_map *map2 = *entry;
973 if (!isl_space_tuple_match(data->map->dim, isl_dim_in,
974 map2->dim, isl_dim_in))
977 map2 = isl_map_flat_range_product(isl_map_copy(data->map),
980 data->res = isl_union_map_add_map(data->res, map2);
985 __isl_give isl_union_map *isl_union_map_flat_range_product(
986 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
988 return bin_op(umap1, umap2, &flat_range_product_entry);
991 __isl_give isl_union_map *isl_union_map_from_range(
992 __isl_take isl_union_set *uset)
997 __isl_give isl_union_map *isl_union_map_from_domain(
998 __isl_take isl_union_set *uset)
1000 return isl_union_map_reverse(isl_union_map_from_range(uset));
1003 __isl_give isl_union_map *isl_union_map_from_domain_and_range(
1004 __isl_take isl_union_set *domain, __isl_take isl_union_set *range)
1006 return isl_union_map_apply_range(isl_union_map_from_domain(domain),
1007 isl_union_map_from_range(range));
1010 static __isl_give isl_union_map *un_op(__isl_take isl_union_map *umap,
1011 int (*fn)(void **, void *))
1013 umap = isl_union_map_cow(umap);
1017 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, fn, NULL) < 0)
1022 isl_union_map_free(umap);
1026 static int affine_entry(void **entry, void *user)
1028 isl_map **map = (isl_map **)entry;
1030 *map = isl_map_from_basic_map(isl_map_affine_hull(*map));
1032 return *map ? 0 : -1;
1035 __isl_give isl_union_map *isl_union_map_affine_hull(
1036 __isl_take isl_union_map *umap)
1038 return un_op(umap, &affine_entry);
1041 __isl_give isl_union_set *isl_union_set_affine_hull(
1042 __isl_take isl_union_set *uset)
1044 return isl_union_map_affine_hull(uset);
1047 static int polyhedral_entry(void **entry, void *user)
1049 isl_map **map = (isl_map **)entry;
1051 *map = isl_map_from_basic_map(isl_map_polyhedral_hull(*map));
1053 return *map ? 0 : -1;
1056 __isl_give isl_union_map *isl_union_map_polyhedral_hull(
1057 __isl_take isl_union_map *umap)
1059 return un_op(umap, &polyhedral_entry);
1062 __isl_give isl_union_set *isl_union_set_polyhedral_hull(
1063 __isl_take isl_union_set *uset)
1065 return isl_union_map_polyhedral_hull(uset);
1068 static int simple_entry(void **entry, void *user)
1070 isl_map **map = (isl_map **)entry;
1072 *map = isl_map_from_basic_map(isl_map_simple_hull(*map));
1074 return *map ? 0 : -1;
1077 __isl_give isl_union_map *isl_union_map_simple_hull(
1078 __isl_take isl_union_map *umap)
1080 return un_op(umap, &simple_entry);
1083 __isl_give isl_union_set *isl_union_set_simple_hull(
1084 __isl_take isl_union_set *uset)
1086 return isl_union_map_simple_hull(uset);
1089 static int inplace_entry(void **entry, void *user)
1091 __isl_give isl_map *(*fn)(__isl_take isl_map *);
1092 isl_map **map = (isl_map **)entry;
1095 fn = *(__isl_give isl_map *(**)(__isl_take isl_map *)) user;
1096 copy = fn(isl_map_copy(*map));
1106 static __isl_give isl_union_map *inplace(__isl_take isl_union_map *umap,
1107 __isl_give isl_map *(*fn)(__isl_take isl_map *))
1112 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
1113 &inplace_entry, &fn) < 0)
1118 isl_union_map_free(umap);
1122 __isl_give isl_union_map *isl_union_map_coalesce(
1123 __isl_take isl_union_map *umap)
1125 return inplace(umap, &isl_map_coalesce);
1128 __isl_give isl_union_set *isl_union_set_coalesce(
1129 __isl_take isl_union_set *uset)
1131 return isl_union_map_coalesce(uset);
1134 __isl_give isl_union_map *isl_union_map_detect_equalities(
1135 __isl_take isl_union_map *umap)
1137 return inplace(umap, &isl_map_detect_equalities);
1140 __isl_give isl_union_set *isl_union_set_detect_equalities(
1141 __isl_take isl_union_set *uset)
1143 return isl_union_map_detect_equalities(uset);
1146 __isl_give isl_union_map *isl_union_map_compute_divs(
1147 __isl_take isl_union_map *umap)
1149 return inplace(umap, &isl_map_compute_divs);
1152 __isl_give isl_union_set *isl_union_set_compute_divs(
1153 __isl_take isl_union_set *uset)
1155 return isl_union_map_compute_divs(uset);
1158 static int lexmin_entry(void **entry, void *user)
1160 isl_map **map = (isl_map **)entry;
1162 *map = isl_map_lexmin(*map);
1164 return *map ? 0 : -1;
1167 __isl_give isl_union_map *isl_union_map_lexmin(
1168 __isl_take isl_union_map *umap)
1170 return un_op(umap, &lexmin_entry);
1173 __isl_give isl_union_set *isl_union_set_lexmin(
1174 __isl_take isl_union_set *uset)
1176 return isl_union_map_lexmin(uset);
1179 static int lexmax_entry(void **entry, void *user)
1181 isl_map **map = (isl_map **)entry;
1183 *map = isl_map_lexmax(*map);
1185 return *map ? 0 : -1;
1188 __isl_give isl_union_map *isl_union_map_lexmax(
1189 __isl_take isl_union_map *umap)
1191 return un_op(umap, &lexmax_entry);
1194 __isl_give isl_union_set *isl_union_set_lexmax(
1195 __isl_take isl_union_set *uset)
1197 return isl_union_map_lexmax(uset);
1200 static __isl_give isl_union_set *cond_un_op(__isl_take isl_union_map *umap,
1201 int (*fn)(void **, void *))
1208 res = isl_union_map_alloc(isl_space_copy(umap->dim), umap->table.n);
1209 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, fn, &res) < 0)
1212 isl_union_map_free(umap);
1215 isl_union_map_free(umap);
1216 isl_union_set_free(res);
1220 static int universe_entry(void **entry, void *user)
1222 isl_map *map = *entry;
1223 isl_union_map **res = user;
1225 map = isl_map_universe(isl_map_get_space(map));
1226 *res = isl_union_map_add_map(*res, map);
1231 __isl_give isl_union_map *isl_union_map_universe(__isl_take isl_union_map *umap)
1233 return cond_un_op(umap, &universe_entry);
1236 __isl_give isl_union_set *isl_union_set_universe(__isl_take isl_union_set *uset)
1238 return isl_union_map_universe(uset);
1241 static int reverse_entry(void **entry, void *user)
1243 isl_map *map = *entry;
1244 isl_union_map **res = user;
1246 *res = isl_union_map_add_map(*res, isl_map_reverse(isl_map_copy(map)));
1251 __isl_give isl_union_map *isl_union_map_reverse(__isl_take isl_union_map *umap)
1253 return cond_un_op(umap, &reverse_entry);
1256 static int domain_entry(void **entry, void *user)
1258 isl_map *map = *entry;
1259 isl_union_set **res = user;
1261 *res = isl_union_set_add_set(*res, isl_map_domain(isl_map_copy(map)));
1266 __isl_give isl_union_set *isl_union_map_domain(__isl_take isl_union_map *umap)
1268 return cond_un_op(umap, &domain_entry);
1271 static int range_entry(void **entry, void *user)
1273 isl_map *map = *entry;
1274 isl_union_set **res = user;
1276 *res = isl_union_set_add_set(*res, isl_map_range(isl_map_copy(map)));
1281 __isl_give isl_union_set *isl_union_map_range(__isl_take isl_union_map *umap)
1283 return cond_un_op(umap, &range_entry);
1286 static int domain_map_entry(void **entry, void *user)
1288 isl_map *map = *entry;
1289 isl_union_set **res = user;
1291 *res = isl_union_map_add_map(*res,
1292 isl_map_domain_map(isl_map_copy(map)));
1297 __isl_give isl_union_map *isl_union_map_domain_map(
1298 __isl_take isl_union_map *umap)
1300 return cond_un_op(umap, &domain_map_entry);
1303 static int range_map_entry(void **entry, void *user)
1305 isl_map *map = *entry;
1306 isl_union_set **res = user;
1308 *res = isl_union_map_add_map(*res,
1309 isl_map_range_map(isl_map_copy(map)));
1314 __isl_give isl_union_map *isl_union_map_range_map(
1315 __isl_take isl_union_map *umap)
1317 return cond_un_op(umap, &range_map_entry);
1320 static int deltas_entry(void **entry, void *user)
1322 isl_map *map = *entry;
1323 isl_union_set **res = user;
1325 if (!isl_space_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
1328 *res = isl_union_set_add_set(*res, isl_map_deltas(isl_map_copy(map)));
1333 __isl_give isl_union_set *isl_union_map_deltas(__isl_take isl_union_map *umap)
1335 return cond_un_op(umap, &deltas_entry);
1338 static int deltas_map_entry(void **entry, void *user)
1340 isl_map *map = *entry;
1341 isl_union_map **res = user;
1343 if (!isl_space_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
1346 *res = isl_union_map_add_map(*res,
1347 isl_map_deltas_map(isl_map_copy(map)));
1352 __isl_give isl_union_map *isl_union_map_deltas_map(
1353 __isl_take isl_union_map *umap)
1355 return cond_un_op(umap, &deltas_map_entry);
1358 static int identity_entry(void **entry, void *user)
1360 isl_set *set = *entry;
1361 isl_union_map **res = user;
1363 *res = isl_union_map_add_map(*res, isl_set_identity(isl_set_copy(set)));
1368 __isl_give isl_union_map *isl_union_set_identity(__isl_take isl_union_set *uset)
1370 return cond_un_op(uset, &identity_entry);
1373 static int unwrap_entry(void **entry, void *user)
1375 isl_set *set = *entry;
1376 isl_union_set **res = user;
1378 if (!isl_set_is_wrapping(set))
1381 *res = isl_union_map_add_map(*res, isl_set_unwrap(isl_set_copy(set)));
1386 __isl_give isl_union_map *isl_union_set_unwrap(__isl_take isl_union_set *uset)
1388 return cond_un_op(uset, &unwrap_entry);
1391 static int wrap_entry(void **entry, void *user)
1393 isl_map *map = *entry;
1394 isl_union_set **res = user;
1396 *res = isl_union_set_add_set(*res, isl_map_wrap(isl_map_copy(map)));
1401 __isl_give isl_union_set *isl_union_map_wrap(__isl_take isl_union_map *umap)
1403 return cond_un_op(umap, &wrap_entry);
1406 struct isl_union_map_is_subset_data {
1407 isl_union_map *umap2;
1411 static int is_subset_entry(void **entry, void *user)
1413 struct isl_union_map_is_subset_data *data = user;
1415 struct isl_hash_table_entry *entry2;
1416 isl_map *map = *entry;
1418 hash = isl_space_get_hash(map->dim);
1419 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
1420 hash, &has_dim, map->dim, 0);
1422 data->is_subset = 0;
1426 data->is_subset = isl_map_is_subset(map, entry2->data);
1427 if (data->is_subset < 0 || !data->is_subset)
1433 int isl_union_map_is_subset(__isl_keep isl_union_map *umap1,
1434 __isl_keep isl_union_map *umap2)
1436 struct isl_union_map_is_subset_data data = { NULL, 1 };
1438 umap1 = isl_union_map_copy(umap1);
1439 umap2 = isl_union_map_copy(umap2);
1440 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2));
1441 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1));
1443 if (!umap1 || !umap2)
1447 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
1448 &is_subset_entry, &data) < 0 &&
1452 isl_union_map_free(umap1);
1453 isl_union_map_free(umap2);
1455 return data.is_subset;
1457 isl_union_map_free(umap1);
1458 isl_union_map_free(umap2);
1462 int isl_union_set_is_subset(__isl_keep isl_union_set *uset1,
1463 __isl_keep isl_union_set *uset2)
1465 return isl_union_map_is_subset(uset1, uset2);
1468 int isl_union_map_is_equal(__isl_keep isl_union_map *umap1,
1469 __isl_keep isl_union_map *umap2)
1473 if (!umap1 || !umap2)
1475 is_subset = isl_union_map_is_subset(umap1, umap2);
1478 is_subset = isl_union_map_is_subset(umap2, umap1);
1482 int isl_union_set_is_equal(__isl_keep isl_union_set *uset1,
1483 __isl_keep isl_union_set *uset2)
1485 return isl_union_map_is_equal(uset1, uset2);
1488 int isl_union_map_is_strict_subset(__isl_keep isl_union_map *umap1,
1489 __isl_keep isl_union_map *umap2)
1493 if (!umap1 || !umap2)
1495 is_subset = isl_union_map_is_subset(umap1, umap2);
1498 is_subset = isl_union_map_is_subset(umap2, umap1);
1499 if (is_subset == -1)
1504 int isl_union_set_is_strict_subset(__isl_keep isl_union_set *uset1,
1505 __isl_keep isl_union_set *uset2)
1507 return isl_union_map_is_strict_subset(uset1, uset2);
1510 static int sample_entry(void **entry, void *user)
1512 isl_basic_map **sample = (isl_basic_map **)user;
1513 isl_map *map = *entry;
1515 *sample = isl_map_sample(isl_map_copy(map));
1518 if (!isl_basic_map_plain_is_empty(*sample))
1523 __isl_give isl_basic_map *isl_union_map_sample(__isl_take isl_union_map *umap)
1525 isl_basic_map *sample = NULL;
1530 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
1531 &sample_entry, &sample) < 0 &&
1536 sample = isl_basic_map_empty(isl_union_map_get_space(umap));
1538 isl_union_map_free(umap);
1542 isl_union_map_free(umap);
1546 __isl_give isl_basic_set *isl_union_set_sample(__isl_take isl_union_set *uset)
1548 return (isl_basic_set *)isl_union_map_sample(uset);
1551 struct isl_forall_data {
1553 int (*fn)(__isl_keep isl_map *map);
1556 static int forall_entry(void **entry, void *user)
1558 struct isl_forall_data *data = user;
1559 isl_map *map = *entry;
1561 data->res = data->fn(map);
1571 static int union_map_forall(__isl_keep isl_union_map *umap,
1572 int (*fn)(__isl_keep isl_map *map))
1574 struct isl_forall_data data = { 1, fn };
1579 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
1580 &forall_entry, &data) < 0 && data.res)
1586 struct isl_forall_user_data {
1588 int (*fn)(__isl_keep isl_map *map, void *user);
1592 static int forall_user_entry(void **entry, void *user)
1594 struct isl_forall_user_data *data = user;
1595 isl_map *map = *entry;
1597 data->res = data->fn(map, data->user);
1607 /* Check if fn(map, user) returns true for all maps "map" in umap.
1609 static int union_map_forall_user(__isl_keep isl_union_map *umap,
1610 int (*fn)(__isl_keep isl_map *map, void *user), void *user)
1612 struct isl_forall_user_data data = { 1, fn, user };
1617 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
1618 &forall_user_entry, &data) < 0 && data.res)
1624 int isl_union_map_is_empty(__isl_keep isl_union_map *umap)
1626 return union_map_forall(umap, &isl_map_is_empty);
1629 int isl_union_set_is_empty(__isl_keep isl_union_set *uset)
1631 return isl_union_map_is_empty(uset);
1634 static int is_subset_of_identity(__isl_keep isl_map *map)
1643 if (!isl_space_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
1646 dim = isl_map_get_space(map);
1647 id = isl_map_identity(dim);
1649 is_subset = isl_map_is_subset(map, id);
1656 /* Check if the given map is single-valued.
1661 * and check if the result is a subset of the identity mapping.
1663 int isl_union_map_is_single_valued(__isl_keep isl_union_map *umap)
1665 isl_union_map *test;
1668 if (isl_union_map_n_map(umap) == 1) {
1670 umap = isl_union_map_copy(umap);
1671 map = isl_map_from_union_map(umap);
1672 sv = isl_map_is_single_valued(map);
1677 test = isl_union_map_reverse(isl_union_map_copy(umap));
1678 test = isl_union_map_apply_range(test, isl_union_map_copy(umap));
1680 sv = union_map_forall(test, &is_subset_of_identity);
1682 isl_union_map_free(test);
1687 int isl_union_map_is_injective(__isl_keep isl_union_map *umap)
1691 umap = isl_union_map_copy(umap);
1692 umap = isl_union_map_reverse(umap);
1693 in = isl_union_map_is_single_valued(umap);
1694 isl_union_map_free(umap);
1699 /* Represents a map that has a fixed value (v) for one of its
1701 * The map in this structure is not reference counted, so it
1702 * is only valid while the isl_union_map from which it was
1703 * obtained is still alive.
1705 struct isl_fixed_map {
1710 static struct isl_fixed_map *alloc_isl_fixed_map_array(isl_ctx *ctx,
1714 struct isl_fixed_map *v;
1716 v = isl_calloc_array(ctx, struct isl_fixed_map, n);
1719 for (i = 0; i < n; ++i)
1720 isl_int_init(v[i].v);
1724 static void free_isl_fixed_map_array(struct isl_fixed_map *v, int n)
1730 for (i = 0; i < n; ++i)
1731 isl_int_clear(v[i].v);
1735 /* Compare the "v" field of two isl_fixed_map structs.
1737 static int qsort_fixed_map_cmp(const void *p1, const void *p2)
1739 const struct isl_fixed_map *e1 = (const struct isl_fixed_map *) p1;
1740 const struct isl_fixed_map *e2 = (const struct isl_fixed_map *) p2;
1742 return isl_int_cmp(e1->v, e2->v);
1745 /* Internal data structure used while checking whether all maps
1746 * in a union_map have a fixed value for a given output dimension.
1747 * v is the list of maps, with the fixed value for the dimension
1748 * n is the number of maps considered so far
1749 * pos is the output dimension under investigation
1751 struct isl_fixed_dim_data {
1752 struct isl_fixed_map *v;
1757 static int fixed_at_pos(__isl_keep isl_map *map, void *user)
1759 struct isl_fixed_dim_data *data = user;
1761 data->v[data->n].map = map;
1762 return isl_map_plain_is_fixed(map, isl_dim_out, data->pos,
1763 &data->v[data->n++].v);
1766 static int plain_injective_on_range(__isl_take isl_union_map *umap,
1767 int first, int n_range);
1769 /* Given a list of the maps, with their fixed values at output dimension "pos",
1770 * check whether the ranges of the maps form an obvious partition.
1772 * We first sort the maps according to their fixed values.
1773 * If all maps have a different value, then we know the ranges form
1775 * Otherwise, we collect the maps with the same fixed value and
1776 * check whether each such collection is obviously injective
1777 * based on later dimensions.
1779 static int separates(struct isl_fixed_map *v, int n,
1780 __isl_take isl_space *dim, int pos, int n_range)
1787 qsort(v, n, sizeof(*v), &qsort_fixed_map_cmp);
1789 for (i = 0; i + 1 < n; ++i) {
1791 isl_union_map *part;
1794 for (j = i + 1; j < n; ++j)
1795 if (isl_int_ne(v[i].v, v[j].v))
1801 part = isl_union_map_alloc(isl_space_copy(dim), j - i);
1802 for (k = i; k < j; ++k)
1803 part = isl_union_map_add_map(part,
1804 isl_map_copy(v[k].map));
1806 injective = plain_injective_on_range(part, pos + 1, n_range);
1815 isl_space_free(dim);
1816 free_isl_fixed_map_array(v, n);
1819 isl_space_free(dim);
1820 free_isl_fixed_map_array(v, n);
1824 /* Check whether the maps in umap have obviously distinct ranges.
1825 * In particular, check for an output dimension in the range
1826 * [first,n_range) for which all maps have a fixed value
1827 * and then check if these values, possibly along with fixed values
1828 * at later dimensions, entail distinct ranges.
1830 static int plain_injective_on_range(__isl_take isl_union_map *umap,
1831 int first, int n_range)
1835 struct isl_fixed_dim_data data = { NULL };
1837 ctx = isl_union_map_get_ctx(umap);
1842 n = isl_union_map_n_map(umap);
1844 isl_union_map_free(umap);
1848 if (first >= n_range) {
1849 isl_union_map_free(umap);
1853 data.v = alloc_isl_fixed_map_array(ctx, n);
1857 for (data.pos = first; data.pos < n_range; ++data.pos) {
1863 fixed = union_map_forall_user(umap, &fixed_at_pos, &data);
1868 dim = isl_union_map_get_space(umap);
1869 injective = separates(data.v, n, dim, data.pos, n_range);
1870 isl_union_map_free(umap);
1874 free_isl_fixed_map_array(data.v, n);
1875 isl_union_map_free(umap);
1879 free_isl_fixed_map_array(data.v, n);
1880 isl_union_map_free(umap);
1884 /* Check whether the maps in umap that map to subsets of "ran"
1885 * have obviously distinct ranges.
1887 static int plain_injective_on_range_wrap(__isl_keep isl_set *ran, void *user)
1889 isl_union_map *umap = user;
1891 umap = isl_union_map_copy(umap);
1892 umap = isl_union_map_intersect_range(umap,
1893 isl_union_set_from_set(isl_set_copy(ran)));
1894 return plain_injective_on_range(umap, 0, isl_set_dim(ran, isl_dim_set));
1897 /* Check if the given union_map is obviously injective.
1899 * In particular, we first check if all individual maps are obviously
1900 * injective and then check if all the ranges of these maps are
1901 * obviously disjoint.
1903 int isl_union_map_plain_is_injective(__isl_keep isl_union_map *umap)
1906 isl_union_map *univ;
1909 in = union_map_forall(umap, &isl_map_plain_is_injective);
1915 univ = isl_union_map_universe(isl_union_map_copy(umap));
1916 ran = isl_union_map_range(univ);
1918 in = union_map_forall_user(ran, &plain_injective_on_range_wrap, umap);
1920 isl_union_set_free(ran);
1925 int isl_union_map_is_bijective(__isl_keep isl_union_map *umap)
1929 sv = isl_union_map_is_single_valued(umap);
1933 return isl_union_map_is_injective(umap);
1936 static int zip_entry(void **entry, void *user)
1938 isl_map *map = *entry;
1939 isl_union_map **res = user;
1941 if (!isl_map_can_zip(map))
1944 *res = isl_union_map_add_map(*res, isl_map_zip(isl_map_copy(map)));
1949 __isl_give isl_union_map *isl_union_map_zip(__isl_take isl_union_map *umap)
1951 return cond_un_op(umap, &zip_entry);
1954 static int lift_entry(void **entry, void *user)
1956 isl_set *set = *entry;
1957 isl_union_set **res = user;
1959 *res = isl_union_set_add_set(*res, isl_set_lift(isl_set_copy(set)));
1964 __isl_give isl_union_set *isl_union_set_lift(__isl_take isl_union_set *uset)
1966 return cond_un_op(uset, &lift_entry);
1969 static int coefficients_entry(void **entry, void *user)
1971 isl_set *set = *entry;
1972 isl_union_set **res = user;
1974 set = isl_set_copy(set);
1975 set = isl_set_from_basic_set(isl_set_coefficients(set));
1976 *res = isl_union_set_add_set(*res, set);
1981 __isl_give isl_union_set *isl_union_set_coefficients(
1982 __isl_take isl_union_set *uset)
1991 ctx = isl_union_set_get_ctx(uset);
1992 dim = isl_space_set_alloc(ctx, 0, 0);
1993 res = isl_union_map_alloc(dim, uset->table.n);
1994 if (isl_hash_table_foreach(uset->dim->ctx, &uset->table,
1995 &coefficients_entry, &res) < 0)
1998 isl_union_set_free(uset);
2001 isl_union_set_free(uset);
2002 isl_union_set_free(res);
2006 static int solutions_entry(void **entry, void *user)
2008 isl_set *set = *entry;
2009 isl_union_set **res = user;
2011 set = isl_set_copy(set);
2012 set = isl_set_from_basic_set(isl_set_solutions(set));
2014 *res = isl_union_set_from_set(set);
2016 *res = isl_union_set_add_set(*res, set);
2024 __isl_give isl_union_set *isl_union_set_solutions(
2025 __isl_take isl_union_set *uset)
2027 isl_union_set *res = NULL;
2032 if (uset->table.n == 0) {
2033 res = isl_union_set_empty(isl_union_set_get_space(uset));
2034 isl_union_set_free(uset);
2038 if (isl_hash_table_foreach(uset->dim->ctx, &uset->table,
2039 &solutions_entry, &res) < 0)
2042 isl_union_set_free(uset);
2045 isl_union_set_free(uset);
2046 isl_union_set_free(res);