isl_transitive_closure.c: keep track of domains for Floyd-Warshall
[isl.git] / isl_union_map.c
blob152dd811f7f3023670b877a078bdd3161ec0b69d
1 /*
2 * Copyright 2010 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,
8 * 91893 Orsay, France
9 */
11 #include <isl_ctx.h>
12 #include <isl_hash.h>
13 #include <isl_map.h>
14 #include <isl_set.h>
15 #include <isl_dim_private.h>
16 #include <isl_union_map_private.h>
17 #include <isl_union_set.h>
19 static __isl_give isl_union_map *isl_union_map_alloc(__isl_take isl_dim *dim,
20 int size)
22 isl_union_map *umap;
24 if (!dim)
25 return NULL;
27 umap = isl_calloc_type(dim->ctx, isl_union_map);
28 if (!umap)
29 return NULL;
31 umap->ref = 1;
32 umap->dim = dim;
33 if (isl_hash_table_init(dim->ctx, &umap->table, size) < 0)
34 goto error;
36 return umap;
37 error:
38 isl_dim_free(dim);
39 isl_union_map_free(umap);
40 return NULL;
43 __isl_give isl_union_map *isl_union_map_empty(__isl_take isl_dim *dim)
45 return isl_union_map_alloc(dim, 16);
48 __isl_give isl_union_set *isl_union_set_empty(__isl_take isl_dim *dim)
50 return isl_union_map_empty(dim);
53 isl_ctx *isl_union_map_get_ctx(__isl_keep isl_union_map *umap)
55 return umap ? umap->dim->ctx : NULL;
58 __isl_give isl_dim *isl_union_map_get_dim(__isl_keep isl_union_map *umap)
60 if (!umap)
61 return NULL;
62 return isl_dim_copy(umap->dim);
65 __isl_give isl_dim *isl_union_set_get_dim(__isl_keep isl_union_set *uset)
67 return isl_union_map_get_dim(uset);
70 static int free_umap_entry(void **entry, void *user)
72 isl_map *map = *entry;
73 isl_map_free(map);
74 return 0;
77 static int add_map(__isl_take isl_map *map, void *user)
79 isl_union_map **umap = (isl_union_map **)user;
81 *umap = isl_union_map_add_map(*umap, map);
83 return 0;
86 __isl_give isl_union_map *isl_union_map_dup(__isl_keep isl_union_map *umap)
88 isl_union_map *dup;
90 if (!umap)
91 return NULL;
93 dup = isl_union_map_empty(isl_dim_copy(umap->dim));
94 if (isl_union_map_foreach_map(umap, &add_map, &dup) < 0)
95 goto error;
96 return dup;
97 error:
98 isl_union_map_free(dup);
99 return NULL;
102 __isl_give isl_union_map *isl_union_map_cow(__isl_take isl_union_map *umap)
104 if (!umap)
105 return NULL;
107 if (umap->ref == 1)
108 return umap;
109 umap->ref--;
110 return isl_union_map_dup(umap);
113 __isl_give isl_union_map *isl_union_map_union(__isl_take isl_union_map *umap1,
114 __isl_take isl_union_map *umap2)
116 umap1 = isl_union_map_cow(umap1);
118 if (!umap1 || !umap2)
119 goto error;
121 if (isl_union_map_foreach_map(umap2, &add_map, &umap1) < 0)
122 goto error;
124 isl_union_map_free(umap2);
126 return umap1;
127 error:
128 isl_union_map_free(umap1);
129 isl_union_map_free(umap2);
130 return NULL;
133 __isl_give isl_union_set *isl_union_set_union(__isl_take isl_union_set *uset1,
134 __isl_take isl_union_set *uset2)
136 return isl_union_map_union(uset1, uset2);
139 __isl_give isl_union_map *isl_union_map_copy(__isl_keep isl_union_map *umap)
141 if (!umap)
142 return NULL;
144 umap->ref++;
145 return umap;
148 __isl_give isl_union_set *isl_union_set_copy(__isl_keep isl_union_set *uset)
150 return isl_union_map_copy(uset);
153 void isl_union_map_free(__isl_take isl_union_map *umap)
155 if (!umap)
156 return;
158 if (--umap->ref > 0)
159 return;
161 isl_hash_table_foreach(umap->dim->ctx, &umap->table,
162 &free_umap_entry, NULL);
163 isl_hash_table_clear(&umap->table);
164 isl_dim_free(umap->dim);
165 free(umap);
168 void isl_union_set_free(__isl_take isl_union_set *uset)
170 isl_union_map_free(uset);
173 static int has_dim(const void *entry, const void *val)
175 isl_map *map = (isl_map *)entry;
176 isl_dim *dim = (isl_dim *)val;
178 return isl_dim_equal(map->dim, dim);
181 __isl_give isl_union_map *isl_union_map_add_map(__isl_take isl_union_map *umap,
182 __isl_take isl_map *map)
184 uint32_t hash;
185 struct isl_hash_table_entry *entry;
187 if (isl_map_fast_is_empty(map)) {
188 isl_map_free(map);
189 return umap;
192 umap = isl_union_map_cow(umap);
194 if (!map || !umap)
195 goto error;
197 isl_assert(map->ctx, isl_dim_match(map->dim, isl_dim_param, umap->dim,
198 isl_dim_param), goto error);
200 hash = isl_dim_get_hash(map->dim);
201 entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
202 &has_dim, map->dim, 1);
203 if (!entry)
204 goto error;
206 if (!entry->data)
207 entry->data = map;
208 else {
209 entry->data = isl_map_union(entry->data, isl_map_copy(map));
210 if (!entry->data)
211 goto error;
212 isl_map_free(map);
215 return umap;
216 error:
217 isl_map_free(map);
218 isl_union_map_free(umap);
219 return NULL;
222 __isl_give isl_union_set *isl_union_set_add_set(__isl_take isl_union_set *uset,
223 __isl_take isl_set *set)
225 return isl_union_map_add_map(uset, (isl_map *)set);
228 __isl_give isl_union_map *isl_union_map_from_map(__isl_take isl_map *map)
230 isl_dim *dim;
231 isl_union_map *umap;
233 if (!map)
234 return NULL;
236 dim = isl_map_get_dim(map);
237 dim = isl_dim_drop(dim, isl_dim_in, 0, isl_dim_size(dim, isl_dim_in));
238 dim = isl_dim_drop(dim, isl_dim_out, 0, isl_dim_size(dim, isl_dim_out));
239 umap = isl_union_map_empty(dim);
240 umap = isl_union_map_add_map(umap, map);
242 return umap;
245 __isl_give isl_union_set *isl_union_set_from_set(__isl_take isl_set *set)
247 return isl_union_map_from_map((isl_map *)set);
250 struct isl_union_map_foreach_data
252 int (*fn)(__isl_take isl_map *map, void *user);
253 void *user;
256 static int call_on_copy(void **entry, void *user)
258 isl_map *map = *entry;
259 struct isl_union_map_foreach_data *data;
260 data = (struct isl_union_map_foreach_data *)user;
262 return data->fn(isl_map_copy(map), data->user);
265 int isl_union_map_foreach_map(__isl_keep isl_union_map *umap,
266 int (*fn)(__isl_take isl_map *map, void *user), void *user)
268 struct isl_union_map_foreach_data data = { fn, user };
270 if (!umap)
271 return -1;
273 return isl_hash_table_foreach(umap->dim->ctx, &umap->table,
274 &call_on_copy, &data);
277 int isl_union_set_foreach_set(__isl_keep isl_union_set *uset,
278 int (*fn)(__isl_take isl_set *set, void *user), void *user)
280 return isl_union_map_foreach_map(uset,
281 (int(*)(__isl_take isl_map *, void*))fn, user);
284 struct isl_union_set_foreach_point_data {
285 int (*fn)(__isl_take isl_point *pnt, void *user);
286 void *user;
289 static int foreach_point(__isl_take isl_set *set, void *user)
291 struct isl_union_set_foreach_point_data *data = user;
292 int r;
294 r = isl_set_foreach_point(set, data->fn, data->user);
295 isl_set_free(set);
297 return r;
300 int isl_union_set_foreach_point(__isl_keep isl_union_set *uset,
301 int (*fn)(__isl_take isl_point *pnt, void *user), void *user)
303 struct isl_union_set_foreach_point_data data = { fn, user };
304 return isl_union_set_foreach_set(uset, &foreach_point, &data);
307 struct isl_union_map_gen_bin_data {
308 isl_union_map *umap2;
309 isl_union_map *res;
312 static int subtract_entry(void **entry, void *user)
314 struct isl_union_map_gen_bin_data *data = user;
315 uint32_t hash;
316 struct isl_hash_table_entry *entry2;
317 isl_map *map = *entry;
319 hash = isl_dim_get_hash(map->dim);
320 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
321 hash, &has_dim, map->dim, 0);
322 map = isl_map_copy(map);
323 if (entry2) {
324 int empty;
325 map = isl_map_subtract(map, isl_map_copy(entry2->data));
327 empty = isl_map_is_empty(map);
328 if (empty < 0) {
329 isl_map_free(map);
330 return -1;
332 if (empty) {
333 isl_map_free(map);
334 return 0;
337 data->res = isl_union_map_add_map(data->res, map);
339 return 0;
342 static __isl_give isl_union_map *gen_bin_op(__isl_take isl_union_map *umap1,
343 __isl_take isl_union_map *umap2, int (*fn)(void **, void *))
345 struct isl_union_map_gen_bin_data data = { umap2, NULL };
347 if (!umap1 || !umap2)
348 goto error;
350 data.res = isl_union_map_alloc(isl_dim_copy(umap1->dim),
351 umap1->table.n);
352 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
353 fn, &data) < 0)
354 goto error;
356 isl_union_map_free(umap1);
357 isl_union_map_free(umap2);
358 return data.res;
359 error:
360 isl_union_map_free(umap1);
361 isl_union_map_free(umap2);
362 isl_union_map_free(data.res);
363 return NULL;
366 __isl_give isl_union_map *isl_union_map_subtract(
367 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
369 return gen_bin_op(umap1, umap2, &subtract_entry);
372 __isl_give isl_union_set *isl_union_set_subtract(
373 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
375 return isl_union_map_subtract(uset1, uset2);
378 struct isl_union_map_match_bin_data {
379 isl_union_map *umap2;
380 isl_union_map *res;
381 __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*);
384 static int match_bin_entry(void **entry, void *user)
386 struct isl_union_map_match_bin_data *data = user;
387 uint32_t hash;
388 struct isl_hash_table_entry *entry2;
389 isl_map *map = *entry;
390 int empty;
392 hash = isl_dim_get_hash(map->dim);
393 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
394 hash, &has_dim, map->dim, 0);
395 if (!entry2)
396 return 0;
398 map = isl_map_copy(map);
399 map = data->fn(map, isl_map_copy(entry2->data));
401 empty = isl_map_is_empty(map);
402 if (empty < 0) {
403 isl_map_free(map);
404 return -1;
406 if (empty) {
407 isl_map_free(map);
408 return 0;
411 data->res = isl_union_map_add_map(data->res, map);
413 return 0;
416 static __isl_give isl_union_map *match_bin_op(__isl_take isl_union_map *umap1,
417 __isl_take isl_union_map *umap2,
418 __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*))
420 struct isl_union_map_match_bin_data data = { umap2, NULL, fn };
422 if (!umap1 || !umap2)
423 goto error;
425 data.res = isl_union_map_alloc(isl_dim_copy(umap1->dim),
426 umap1->table.n);
427 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
428 &match_bin_entry, &data) < 0)
429 goto error;
431 isl_union_map_free(umap1);
432 isl_union_map_free(umap2);
433 return data.res;
434 error:
435 isl_union_map_free(umap1);
436 isl_union_map_free(umap2);
437 isl_union_map_free(data.res);
438 return NULL;
441 __isl_give isl_union_map *isl_union_map_intersect(
442 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
444 return match_bin_op(umap1, umap2, &isl_map_intersect);
447 __isl_give isl_union_set *isl_union_set_intersect(
448 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
450 return isl_union_map_intersect(uset1, uset2);
453 __isl_give isl_union_map *isl_union_map_gist(__isl_take isl_union_map *umap,
454 __isl_take isl_union_map *context)
456 return match_bin_op(umap, context, &isl_map_gist);
459 __isl_give isl_union_set *isl_union_set_gist(__isl_take isl_union_set *uset,
460 __isl_take isl_union_set *context)
462 return isl_union_map_gist(uset, context);
465 static int intersect_domain_entry(void **entry, void *user)
467 struct isl_union_map_gen_bin_data *data = user;
468 uint32_t hash;
469 struct isl_hash_table_entry *entry2;
470 isl_dim *dim;
471 isl_map *map = *entry;
472 int empty;
474 dim = isl_map_get_dim(map);
475 dim = isl_dim_domain(dim);
476 hash = isl_dim_get_hash(dim);
477 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
478 hash, &has_dim, dim, 0);
479 isl_dim_free(dim);
480 if (!entry2)
481 return 0;
483 map = isl_map_copy(map);
484 map = isl_map_intersect_domain(map, isl_set_copy(entry2->data));
486 empty = isl_map_is_empty(map);
487 if (empty < 0) {
488 isl_map_free(map);
489 return -1;
491 if (empty) {
492 isl_map_free(map);
493 return 0;
496 data->res = isl_union_map_add_map(data->res, map);
498 return 0;
501 __isl_give isl_union_map *isl_union_map_intersect_domain(
502 __isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
504 return gen_bin_op(umap, uset, &intersect_domain_entry);
507 struct isl_union_map_bin_data {
508 isl_union_map *umap2;
509 isl_union_map *res;
510 isl_map *map;
511 int (*fn)(void **entry, void *user);
514 static int apply_range_entry(void **entry, void *user)
516 struct isl_union_map_bin_data *data = user;
517 isl_map *map2 = *entry;
518 int empty;
520 if (!isl_dim_tuple_match(data->map->dim, isl_dim_out,
521 map2->dim, isl_dim_in))
522 return 0;
524 map2 = isl_map_apply_range(isl_map_copy(data->map), isl_map_copy(map2));
526 empty = isl_map_is_empty(map2);
527 if (empty < 0) {
528 isl_map_free(map2);
529 return -1;
531 if (empty) {
532 isl_map_free(map2);
533 return 0;
536 data->res = isl_union_map_add_map(data->res, map2);
538 return 0;
541 static int bin_entry(void **entry, void *user)
543 struct isl_union_map_bin_data *data = user;
544 isl_map *map = *entry;
546 data->map = map;
547 if (isl_hash_table_foreach(data->umap2->dim->ctx, &data->umap2->table,
548 data->fn, data) < 0)
549 return -1;
551 return 0;
554 static __isl_give isl_union_map *bin_op(__isl_take isl_union_map *umap1,
555 __isl_take isl_union_map *umap2, int (*fn)(void **entry, void *user))
557 struct isl_union_map_bin_data data = { umap2, NULL, NULL, fn };
559 if (!umap1 || !umap2)
560 goto error;
562 data.res = isl_union_map_alloc(isl_dim_copy(umap1->dim),
563 umap1->table.n);
564 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
565 &bin_entry, &data) < 0)
566 goto error;
568 isl_union_map_free(umap1);
569 isl_union_map_free(umap2);
570 return data.res;
571 error:
572 isl_union_map_free(umap1);
573 isl_union_map_free(umap2);
574 isl_union_map_free(data.res);
575 return NULL;
578 __isl_give isl_union_map *isl_union_map_apply_range(
579 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
581 return bin_op(umap1, umap2, &apply_range_entry);
584 __isl_give isl_union_set *isl_union_set_apply(
585 __isl_take isl_union_set *uset, __isl_take isl_union_map *umap)
587 return isl_union_map_apply_range(uset, umap);
590 static int product_entry(void **entry, void *user)
592 struct isl_union_map_bin_data *data = user;
593 isl_map *map2 = *entry;
595 map2 = isl_map_product(isl_map_copy(data->map), isl_map_copy(map2));
597 data->res = isl_union_map_add_map(data->res, map2);
599 return 0;
602 __isl_give isl_union_map *isl_union_map_product(__isl_take isl_union_map *umap1,
603 __isl_take isl_union_map *umap2)
605 return bin_op(umap1, umap2, &product_entry);
608 __isl_give isl_union_set *isl_union_set_product(__isl_take isl_union_set *uset1,
609 __isl_take isl_union_set *uset2)
611 return isl_union_map_product(uset1, uset2);
614 __isl_give isl_union_map *isl_union_map_from_range(
615 __isl_take isl_union_set *uset)
617 return uset;
620 __isl_give isl_union_map *isl_union_map_from_domain(
621 __isl_take isl_union_set *uset)
623 return isl_union_map_reverse(isl_union_map_from_range(uset));
626 __isl_give isl_union_map *isl_union_map_from_domain_and_range(
627 __isl_take isl_union_set *domain, __isl_take isl_union_set *range)
629 return isl_union_map_apply_range(isl_union_map_from_domain(domain),
630 isl_union_map_from_range(range));
633 static int reverse_entry(void **entry, void *user)
635 isl_map **map = (isl_map **)entry;
637 *map = isl_map_reverse(*map);
639 return *map ? 0 : -1;
642 static __isl_give isl_union_map *un_op(__isl_take isl_union_map *umap,
643 int (*fn)(void **, void *), int cow)
645 if (cow)
646 umap = isl_union_map_cow(umap);
647 if (!umap)
648 return NULL;
650 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, fn, NULL) < 0)
651 goto error;
653 return umap;
654 error:
655 isl_union_map_free(umap);
656 return NULL;
659 __isl_give isl_union_map *isl_union_map_reverse(__isl_take isl_union_map *umap)
661 return un_op(umap, &reverse_entry, 1);
664 static int affine_entry(void **entry, void *user)
666 isl_map **map = (isl_map **)entry;
668 *map = isl_map_from_basic_map(isl_map_affine_hull(*map));
670 return *map ? 0 : -1;
673 __isl_give isl_union_map *isl_union_map_affine_hull(
674 __isl_take isl_union_map *umap)
676 return un_op(umap, &affine_entry, 1);
679 __isl_give isl_union_set *isl_union_set_affine_hull(
680 __isl_take isl_union_set *uset)
682 return isl_union_map_affine_hull(uset);
685 static int coalesce_entry(void **entry, void *user)
687 isl_map **map = (isl_map **)entry;
689 *map = isl_map_coalesce(*map);
691 return *map ? 0 : -1;
694 __isl_give isl_union_map *isl_union_map_coalesce(
695 __isl_take isl_union_map *umap)
697 return un_op(umap, &coalesce_entry, 0);
700 __isl_give isl_union_set *isl_union_set_coalesce(
701 __isl_take isl_union_set *uset)
703 return isl_union_map_coalesce(uset);
706 static int compute_divs_entry(void **entry, void *user)
708 isl_map **map = (isl_map **)entry;
710 *map = isl_map_compute_divs(*map);
712 return *map ? 0 : -1;
715 __isl_give isl_union_map *isl_union_map_compute_divs(
716 __isl_take isl_union_map *umap)
718 return un_op(umap, &compute_divs_entry, 0);
721 __isl_give isl_union_set *isl_union_set_compute_divs(
722 __isl_take isl_union_set *uset)
724 return isl_union_map_compute_divs(uset);
727 static int lexmin_entry(void **entry, void *user)
729 isl_map **map = (isl_map **)entry;
731 *map = isl_map_lexmin(*map);
733 return *map ? 0 : -1;
736 __isl_give isl_union_map *isl_union_map_lexmin(
737 __isl_take isl_union_map *umap)
739 return un_op(umap, &lexmin_entry, 1);
742 __isl_give isl_union_set *isl_union_set_lexmin(
743 __isl_take isl_union_set *uset)
745 return isl_union_map_lexmin(uset);
748 static int lexmax_entry(void **entry, void *user)
750 isl_map **map = (isl_map **)entry;
752 *map = isl_map_lexmax(*map);
754 return *map ? 0 : -1;
757 __isl_give isl_union_map *isl_union_map_lexmax(
758 __isl_take isl_union_map *umap)
760 return un_op(umap, &lexmax_entry, 1);
763 __isl_give isl_union_set *isl_union_set_lexmax(
764 __isl_take isl_union_set *uset)
766 return isl_union_map_lexmax(uset);
769 static int domain_entry(void **entry, void *user)
771 *entry = isl_map_domain(*entry);
773 return *entry ? 0 : -1;
776 __isl_give isl_union_set *isl_union_map_domain(__isl_take isl_union_map *umap)
778 return un_op(umap, &domain_entry, 1);
781 static int range_entry(void **entry, void *user)
783 *entry = isl_map_range(*entry);
785 return *entry ? 0 : -1;
788 __isl_give isl_union_set *isl_union_map_range(__isl_take isl_union_map *umap)
790 return un_op(umap, &range_entry, 1);
793 static int deltas_entry(void **entry, void *user)
795 isl_map *map = *entry;
796 isl_union_set **res = user;
798 if (!isl_dim_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
799 return 0;
801 *res = isl_union_set_add_set(*res, isl_map_deltas(isl_map_copy(map)));
803 return 0;
806 __isl_give isl_union_set *isl_union_map_deltas(__isl_take isl_union_map *umap)
808 isl_union_set *res;
810 if (!umap)
811 return NULL;
813 res = isl_union_map_alloc(isl_dim_copy(umap->dim), umap->table.n);
814 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
815 &deltas_entry, &res) < 0)
816 goto error;
818 isl_union_map_free(umap);
819 return res;
820 error:
821 isl_union_map_free(umap);
822 isl_union_set_free(res);
823 return NULL;
826 struct isl_union_map_is_subset_data {
827 isl_union_map *umap2;
828 int is_subset;
831 static int is_subset_entry(void **entry, void *user)
833 struct isl_union_map_is_subset_data *data = user;
834 uint32_t hash;
835 struct isl_hash_table_entry *entry2;
836 isl_map *map = *entry;
838 hash = isl_dim_get_hash(map->dim);
839 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
840 hash, &has_dim, map->dim, 0);
841 if (!entry2) {
842 data->is_subset = 0;
843 return -1;
846 data->is_subset = isl_map_is_subset(map, entry2->data);
847 if (data->is_subset < 0 || !data->is_subset)
848 return -1;
850 return 0;
853 int isl_union_map_is_subset(__isl_keep isl_union_map *umap1,
854 __isl_keep isl_union_map *umap2)
856 struct isl_union_map_is_subset_data data = { umap2, 1 };
858 if (!umap1 || !umap2)
859 return -1;
861 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
862 &is_subset_entry, &data) < 0 &&
863 data.is_subset)
864 return -1;
866 return data.is_subset;
869 int isl_union_map_is_equal(__isl_keep isl_union_map *umap1,
870 __isl_keep isl_union_map *umap2)
872 int is_subset;
874 if (!umap1 || !umap2)
875 return -1;
876 is_subset = isl_union_map_is_subset(umap1, umap2);
877 if (is_subset != 1)
878 return is_subset;
879 is_subset = isl_union_map_is_subset(umap2, umap1);
880 return is_subset;
883 int isl_union_map_is_strict_subset(__isl_keep isl_union_map *umap1,
884 __isl_keep isl_union_map *umap2)
886 int is_subset;
888 if (!umap1 || !umap2)
889 return -1;
890 is_subset = isl_union_map_is_subset(umap1, umap2);
891 if (is_subset != 1)
892 return is_subset;
893 is_subset = isl_union_map_is_subset(umap2, umap1);
894 if (is_subset == -1)
895 return is_subset;
896 return !is_subset;
899 static int sample_entry(void **entry, void *user)
901 isl_basic_map **sample = (isl_basic_map **)user;
902 isl_map *map = *entry;
904 *sample = isl_map_sample(isl_map_copy(map));
905 if (!*sample)
906 return -1;
907 if (!isl_basic_map_fast_is_empty(*sample))
908 return -1;
909 return 0;
912 __isl_give isl_basic_map *isl_union_map_sample(__isl_take isl_union_map *umap)
914 isl_basic_map *sample = NULL;
916 if (!umap)
917 return NULL;
919 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
920 &sample_entry, &sample) < 0 &&
921 !sample)
922 goto error;
924 isl_union_map_free(umap);
926 return sample;
927 error:
928 isl_union_map_free(umap);
929 return NULL;
932 __isl_give isl_basic_set *isl_union_set_sample(__isl_take isl_union_set *uset)
934 return (isl_basic_set *)isl_union_map_sample(uset);
937 static int empty_entry(void **entry, void *user)
939 int *empty = user;
940 isl_map *map = *entry;
942 if (isl_map_is_empty(map))
943 return 0;
945 *empty = 0;
947 return -1;
950 __isl_give int isl_union_map_is_empty(__isl_keep isl_union_map *umap)
952 int empty = 1;
954 if (!umap)
955 return -1;
957 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
958 &sample_entry, &empty) < 0 && empty)
959 return -1;
961 return empty;
964 int isl_union_set_is_empty(__isl_keep isl_union_set *uset)
966 return isl_union_map_is_empty(uset);