isl_map_read_from_str: parse tuple entries with leading minus sign
[isl.git] / isl_union_map.c
blob96bdc77bbfa1fde777ca49a0bc4d70d82cbeb469
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_ctx *isl_union_set_get_ctx(__isl_keep isl_union_set *uset)
60 return uset ? uset->dim->ctx : NULL;
63 __isl_give isl_dim *isl_union_map_get_dim(__isl_keep isl_union_map *umap)
65 if (!umap)
66 return NULL;
67 return isl_dim_copy(umap->dim);
70 __isl_give isl_dim *isl_union_set_get_dim(__isl_keep isl_union_set *uset)
72 return isl_union_map_get_dim(uset);
75 static int free_umap_entry(void **entry, void *user)
77 isl_map *map = *entry;
78 isl_map_free(map);
79 return 0;
82 static int add_map(__isl_take isl_map *map, void *user)
84 isl_union_map **umap = (isl_union_map **)user;
86 *umap = isl_union_map_add_map(*umap, map);
88 return 0;
91 __isl_give isl_union_map *isl_union_map_dup(__isl_keep isl_union_map *umap)
93 isl_union_map *dup;
95 if (!umap)
96 return NULL;
98 dup = isl_union_map_empty(isl_dim_copy(umap->dim));
99 if (isl_union_map_foreach_map(umap, &add_map, &dup) < 0)
100 goto error;
101 return dup;
102 error:
103 isl_union_map_free(dup);
104 return NULL;
107 __isl_give isl_union_map *isl_union_map_cow(__isl_take isl_union_map *umap)
109 if (!umap)
110 return NULL;
112 if (umap->ref == 1)
113 return umap;
114 umap->ref--;
115 return isl_union_map_dup(umap);
118 __isl_give isl_union_map *isl_union_map_union(__isl_take isl_union_map *umap1,
119 __isl_take isl_union_map *umap2)
121 umap1 = isl_union_map_cow(umap1);
123 if (!umap1 || !umap2)
124 goto error;
126 if (isl_union_map_foreach_map(umap2, &add_map, &umap1) < 0)
127 goto error;
129 isl_union_map_free(umap2);
131 return umap1;
132 error:
133 isl_union_map_free(umap1);
134 isl_union_map_free(umap2);
135 return NULL;
138 __isl_give isl_union_set *isl_union_set_union(__isl_take isl_union_set *uset1,
139 __isl_take isl_union_set *uset2)
141 return isl_union_map_union(uset1, uset2);
144 __isl_give isl_union_map *isl_union_map_copy(__isl_keep isl_union_map *umap)
146 if (!umap)
147 return NULL;
149 umap->ref++;
150 return umap;
153 __isl_give isl_union_set *isl_union_set_copy(__isl_keep isl_union_set *uset)
155 return isl_union_map_copy(uset);
158 void isl_union_map_free(__isl_take isl_union_map *umap)
160 if (!umap)
161 return;
163 if (--umap->ref > 0)
164 return;
166 isl_hash_table_foreach(umap->dim->ctx, &umap->table,
167 &free_umap_entry, NULL);
168 isl_hash_table_clear(&umap->table);
169 isl_dim_free(umap->dim);
170 free(umap);
173 void isl_union_set_free(__isl_take isl_union_set *uset)
175 isl_union_map_free(uset);
178 static int has_dim(const void *entry, const void *val)
180 isl_map *map = (isl_map *)entry;
181 isl_dim *dim = (isl_dim *)val;
183 return isl_dim_equal(map->dim, dim);
186 __isl_give isl_union_map *isl_union_map_add_map(__isl_take isl_union_map *umap,
187 __isl_take isl_map *map)
189 uint32_t hash;
190 struct isl_hash_table_entry *entry;
192 if (isl_map_fast_is_empty(map)) {
193 isl_map_free(map);
194 return umap;
197 umap = isl_union_map_cow(umap);
199 if (!map || !umap)
200 goto error;
202 isl_assert(map->ctx, isl_dim_match(map->dim, isl_dim_param, umap->dim,
203 isl_dim_param), goto error);
205 hash = isl_dim_get_hash(map->dim);
206 entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
207 &has_dim, map->dim, 1);
208 if (!entry)
209 goto error;
211 if (!entry->data)
212 entry->data = map;
213 else {
214 entry->data = isl_map_union(entry->data, isl_map_copy(map));
215 if (!entry->data)
216 goto error;
217 isl_map_free(map);
220 return umap;
221 error:
222 isl_map_free(map);
223 isl_union_map_free(umap);
224 return NULL;
227 __isl_give isl_union_set *isl_union_set_add_set(__isl_take isl_union_set *uset,
228 __isl_take isl_set *set)
230 return isl_union_map_add_map(uset, (isl_map *)set);
233 __isl_give isl_union_map *isl_union_map_from_map(__isl_take isl_map *map)
235 isl_dim *dim;
236 isl_union_map *umap;
238 if (!map)
239 return NULL;
241 dim = isl_map_get_dim(map);
242 dim = isl_dim_drop(dim, isl_dim_in, 0, isl_dim_size(dim, isl_dim_in));
243 dim = isl_dim_drop(dim, isl_dim_out, 0, isl_dim_size(dim, isl_dim_out));
244 umap = isl_union_map_empty(dim);
245 umap = isl_union_map_add_map(umap, map);
247 return umap;
250 __isl_give isl_union_set *isl_union_set_from_set(__isl_take isl_set *set)
252 return isl_union_map_from_map((isl_map *)set);
255 struct isl_union_map_foreach_data
257 int (*fn)(__isl_take isl_map *map, void *user);
258 void *user;
261 static int call_on_copy(void **entry, void *user)
263 isl_map *map = *entry;
264 struct isl_union_map_foreach_data *data;
265 data = (struct isl_union_map_foreach_data *)user;
267 return data->fn(isl_map_copy(map), data->user);
270 int isl_union_map_foreach_map(__isl_keep isl_union_map *umap,
271 int (*fn)(__isl_take isl_map *map, void *user), void *user)
273 struct isl_union_map_foreach_data data = { fn, user };
275 if (!umap)
276 return -1;
278 return isl_hash_table_foreach(umap->dim->ctx, &umap->table,
279 &call_on_copy, &data);
282 int isl_union_set_foreach_set(__isl_keep isl_union_set *uset,
283 int (*fn)(__isl_take isl_set *set, void *user), void *user)
285 return isl_union_map_foreach_map(uset,
286 (int(*)(__isl_take isl_map *, void*))fn, user);
289 struct isl_union_set_foreach_point_data {
290 int (*fn)(__isl_take isl_point *pnt, void *user);
291 void *user;
294 static int foreach_point(__isl_take isl_set *set, void *user)
296 struct isl_union_set_foreach_point_data *data = user;
297 int r;
299 r = isl_set_foreach_point(set, data->fn, data->user);
300 isl_set_free(set);
302 return r;
305 int isl_union_set_foreach_point(__isl_keep isl_union_set *uset,
306 int (*fn)(__isl_take isl_point *pnt, void *user), void *user)
308 struct isl_union_set_foreach_point_data data = { fn, user };
309 return isl_union_set_foreach_set(uset, &foreach_point, &data);
312 struct isl_union_map_gen_bin_data {
313 isl_union_map *umap2;
314 isl_union_map *res;
317 static int subtract_entry(void **entry, void *user)
319 struct isl_union_map_gen_bin_data *data = user;
320 uint32_t hash;
321 struct isl_hash_table_entry *entry2;
322 isl_map *map = *entry;
324 hash = isl_dim_get_hash(map->dim);
325 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
326 hash, &has_dim, map->dim, 0);
327 map = isl_map_copy(map);
328 if (entry2) {
329 int empty;
330 map = isl_map_subtract(map, isl_map_copy(entry2->data));
332 empty = isl_map_is_empty(map);
333 if (empty < 0) {
334 isl_map_free(map);
335 return -1;
337 if (empty) {
338 isl_map_free(map);
339 return 0;
342 data->res = isl_union_map_add_map(data->res, map);
344 return 0;
347 static __isl_give isl_union_map *gen_bin_op(__isl_take isl_union_map *umap1,
348 __isl_take isl_union_map *umap2, int (*fn)(void **, void *))
350 struct isl_union_map_gen_bin_data data = { umap2, NULL };
352 if (!umap1 || !umap2)
353 goto error;
355 data.res = isl_union_map_alloc(isl_dim_copy(umap1->dim),
356 umap1->table.n);
357 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
358 fn, &data) < 0)
359 goto error;
361 isl_union_map_free(umap1);
362 isl_union_map_free(umap2);
363 return data.res;
364 error:
365 isl_union_map_free(umap1);
366 isl_union_map_free(umap2);
367 isl_union_map_free(data.res);
368 return NULL;
371 __isl_give isl_union_map *isl_union_map_subtract(
372 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
374 return gen_bin_op(umap1, umap2, &subtract_entry);
377 __isl_give isl_union_set *isl_union_set_subtract(
378 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
380 return isl_union_map_subtract(uset1, uset2);
383 struct isl_union_map_match_bin_data {
384 isl_union_map *umap2;
385 isl_union_map *res;
386 __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*);
389 static int match_bin_entry(void **entry, void *user)
391 struct isl_union_map_match_bin_data *data = user;
392 uint32_t hash;
393 struct isl_hash_table_entry *entry2;
394 isl_map *map = *entry;
395 int empty;
397 hash = isl_dim_get_hash(map->dim);
398 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
399 hash, &has_dim, map->dim, 0);
400 if (!entry2)
401 return 0;
403 map = isl_map_copy(map);
404 map = data->fn(map, isl_map_copy(entry2->data));
406 empty = isl_map_is_empty(map);
407 if (empty < 0) {
408 isl_map_free(map);
409 return -1;
411 if (empty) {
412 isl_map_free(map);
413 return 0;
416 data->res = isl_union_map_add_map(data->res, map);
418 return 0;
421 static __isl_give isl_union_map *match_bin_op(__isl_take isl_union_map *umap1,
422 __isl_take isl_union_map *umap2,
423 __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*))
425 struct isl_union_map_match_bin_data data = { umap2, NULL, fn };
427 if (!umap1 || !umap2)
428 goto error;
430 data.res = isl_union_map_alloc(isl_dim_copy(umap1->dim),
431 umap1->table.n);
432 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
433 &match_bin_entry, &data) < 0)
434 goto error;
436 isl_union_map_free(umap1);
437 isl_union_map_free(umap2);
438 return data.res;
439 error:
440 isl_union_map_free(umap1);
441 isl_union_map_free(umap2);
442 isl_union_map_free(data.res);
443 return NULL;
446 __isl_give isl_union_map *isl_union_map_intersect(
447 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
449 return match_bin_op(umap1, umap2, &isl_map_intersect);
452 __isl_give isl_union_set *isl_union_set_intersect(
453 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
455 return isl_union_map_intersect(uset1, uset2);
458 __isl_give isl_union_map *isl_union_map_gist(__isl_take isl_union_map *umap,
459 __isl_take isl_union_map *context)
461 return match_bin_op(umap, context, &isl_map_gist);
464 __isl_give isl_union_set *isl_union_set_gist(__isl_take isl_union_set *uset,
465 __isl_take isl_union_set *context)
467 return isl_union_map_gist(uset, context);
470 static int intersect_domain_entry(void **entry, void *user)
472 struct isl_union_map_gen_bin_data *data = user;
473 uint32_t hash;
474 struct isl_hash_table_entry *entry2;
475 isl_dim *dim;
476 isl_map *map = *entry;
477 int empty;
479 dim = isl_map_get_dim(map);
480 dim = isl_dim_domain(dim);
481 hash = isl_dim_get_hash(dim);
482 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
483 hash, &has_dim, dim, 0);
484 isl_dim_free(dim);
485 if (!entry2)
486 return 0;
488 map = isl_map_copy(map);
489 map = isl_map_intersect_domain(map, isl_set_copy(entry2->data));
491 empty = isl_map_is_empty(map);
492 if (empty < 0) {
493 isl_map_free(map);
494 return -1;
496 if (empty) {
497 isl_map_free(map);
498 return 0;
501 data->res = isl_union_map_add_map(data->res, map);
503 return 0;
506 __isl_give isl_union_map *isl_union_map_intersect_domain(
507 __isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
509 return gen_bin_op(umap, uset, &intersect_domain_entry);
512 struct isl_union_map_bin_data {
513 isl_union_map *umap2;
514 isl_union_map *res;
515 isl_map *map;
516 int (*fn)(void **entry, void *user);
519 static int apply_range_entry(void **entry, void *user)
521 struct isl_union_map_bin_data *data = user;
522 isl_map *map2 = *entry;
523 int empty;
525 if (!isl_dim_tuple_match(data->map->dim, isl_dim_out,
526 map2->dim, isl_dim_in))
527 return 0;
529 map2 = isl_map_apply_range(isl_map_copy(data->map), isl_map_copy(map2));
531 empty = isl_map_is_empty(map2);
532 if (empty < 0) {
533 isl_map_free(map2);
534 return -1;
536 if (empty) {
537 isl_map_free(map2);
538 return 0;
541 data->res = isl_union_map_add_map(data->res, map2);
543 return 0;
546 static int bin_entry(void **entry, void *user)
548 struct isl_union_map_bin_data *data = user;
549 isl_map *map = *entry;
551 data->map = map;
552 if (isl_hash_table_foreach(data->umap2->dim->ctx, &data->umap2->table,
553 data->fn, data) < 0)
554 return -1;
556 return 0;
559 static __isl_give isl_union_map *bin_op(__isl_take isl_union_map *umap1,
560 __isl_take isl_union_map *umap2, int (*fn)(void **entry, void *user))
562 struct isl_union_map_bin_data data = { umap2, NULL, NULL, fn };
564 if (!umap1 || !umap2)
565 goto error;
567 data.res = isl_union_map_alloc(isl_dim_copy(umap1->dim),
568 umap1->table.n);
569 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
570 &bin_entry, &data) < 0)
571 goto error;
573 isl_union_map_free(umap1);
574 isl_union_map_free(umap2);
575 return data.res;
576 error:
577 isl_union_map_free(umap1);
578 isl_union_map_free(umap2);
579 isl_union_map_free(data.res);
580 return NULL;
583 __isl_give isl_union_map *isl_union_map_apply_range(
584 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
586 return bin_op(umap1, umap2, &apply_range_entry);
589 __isl_give isl_union_set *isl_union_set_apply(
590 __isl_take isl_union_set *uset, __isl_take isl_union_map *umap)
592 return isl_union_map_apply_range(uset, umap);
595 static int product_entry(void **entry, void *user)
597 struct isl_union_map_bin_data *data = user;
598 isl_map *map2 = *entry;
600 map2 = isl_map_product(isl_map_copy(data->map), isl_map_copy(map2));
602 data->res = isl_union_map_add_map(data->res, map2);
604 return 0;
607 __isl_give isl_union_map *isl_union_map_product(__isl_take isl_union_map *umap1,
608 __isl_take isl_union_map *umap2)
610 return bin_op(umap1, umap2, &product_entry);
613 __isl_give isl_union_set *isl_union_set_product(__isl_take isl_union_set *uset1,
614 __isl_take isl_union_set *uset2)
616 return isl_union_map_product(uset1, uset2);
619 __isl_give isl_union_map *isl_union_map_from_range(
620 __isl_take isl_union_set *uset)
622 return uset;
625 __isl_give isl_union_map *isl_union_map_from_domain(
626 __isl_take isl_union_set *uset)
628 return isl_union_map_reverse(isl_union_map_from_range(uset));
631 __isl_give isl_union_map *isl_union_map_from_domain_and_range(
632 __isl_take isl_union_set *domain, __isl_take isl_union_set *range)
634 return isl_union_map_apply_range(isl_union_map_from_domain(domain),
635 isl_union_map_from_range(range));
638 static __isl_give isl_union_map *un_op(__isl_take isl_union_map *umap,
639 int (*fn)(void **, void *), int cow)
641 if (cow)
642 umap = isl_union_map_cow(umap);
643 if (!umap)
644 return NULL;
646 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, fn, NULL) < 0)
647 goto error;
649 return umap;
650 error:
651 isl_union_map_free(umap);
652 return NULL;
655 static int affine_entry(void **entry, void *user)
657 isl_map **map = (isl_map **)entry;
659 *map = isl_map_from_basic_map(isl_map_affine_hull(*map));
661 return *map ? 0 : -1;
664 __isl_give isl_union_map *isl_union_map_affine_hull(
665 __isl_take isl_union_map *umap)
667 return un_op(umap, &affine_entry, 1);
670 __isl_give isl_union_set *isl_union_set_affine_hull(
671 __isl_take isl_union_set *uset)
673 return isl_union_map_affine_hull(uset);
676 static int coalesce_entry(void **entry, void *user)
678 isl_map **map = (isl_map **)entry;
680 *map = isl_map_coalesce(*map);
682 return *map ? 0 : -1;
685 __isl_give isl_union_map *isl_union_map_coalesce(
686 __isl_take isl_union_map *umap)
688 return un_op(umap, &coalesce_entry, 0);
691 __isl_give isl_union_set *isl_union_set_coalesce(
692 __isl_take isl_union_set *uset)
694 return isl_union_map_coalesce(uset);
697 static int compute_divs_entry(void **entry, void *user)
699 isl_map **map = (isl_map **)entry;
701 *map = isl_map_compute_divs(*map);
703 return *map ? 0 : -1;
706 __isl_give isl_union_map *isl_union_map_compute_divs(
707 __isl_take isl_union_map *umap)
709 return un_op(umap, &compute_divs_entry, 0);
712 __isl_give isl_union_set *isl_union_set_compute_divs(
713 __isl_take isl_union_set *uset)
715 return isl_union_map_compute_divs(uset);
718 static int lexmin_entry(void **entry, void *user)
720 isl_map **map = (isl_map **)entry;
722 *map = isl_map_lexmin(*map);
724 return *map ? 0 : -1;
727 __isl_give isl_union_map *isl_union_map_lexmin(
728 __isl_take isl_union_map *umap)
730 return un_op(umap, &lexmin_entry, 1);
733 __isl_give isl_union_set *isl_union_set_lexmin(
734 __isl_take isl_union_set *uset)
736 return isl_union_map_lexmin(uset);
739 static int lexmax_entry(void **entry, void *user)
741 isl_map **map = (isl_map **)entry;
743 *map = isl_map_lexmax(*map);
745 return *map ? 0 : -1;
748 __isl_give isl_union_map *isl_union_map_lexmax(
749 __isl_take isl_union_map *umap)
751 return un_op(umap, &lexmax_entry, 1);
754 __isl_give isl_union_set *isl_union_set_lexmax(
755 __isl_take isl_union_set *uset)
757 return isl_union_map_lexmax(uset);
760 static __isl_give isl_union_set *cond_un_op(__isl_take isl_union_map *umap,
761 int (*fn)(void **, void *))
763 isl_union_set *res;
765 if (!umap)
766 return NULL;
768 res = isl_union_map_alloc(isl_dim_copy(umap->dim), umap->table.n);
769 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, fn, &res) < 0)
770 goto error;
772 isl_union_map_free(umap);
773 return res;
774 error:
775 isl_union_map_free(umap);
776 isl_union_set_free(res);
777 return NULL;
780 static int reverse_entry(void **entry, void *user)
782 isl_map *map = *entry;
783 isl_union_map **res = user;
785 *res = isl_union_map_add_map(*res, isl_map_reverse(isl_map_copy(map)));
787 return 0;
790 __isl_give isl_union_map *isl_union_map_reverse(__isl_take isl_union_map *umap)
792 return cond_un_op(umap, &reverse_entry);
795 static int domain_entry(void **entry, void *user)
797 isl_map *map = *entry;
798 isl_union_set **res = user;
800 *res = isl_union_set_add_set(*res, isl_map_domain(isl_map_copy(map)));
802 return 0;
805 __isl_give isl_union_set *isl_union_map_domain(__isl_take isl_union_map *umap)
807 return cond_un_op(umap, &domain_entry);
810 static int range_entry(void **entry, void *user)
812 isl_map *map = *entry;
813 isl_union_set **res = user;
815 *res = isl_union_set_add_set(*res, isl_map_range(isl_map_copy(map)));
817 return 0;
820 __isl_give isl_union_set *isl_union_map_range(__isl_take isl_union_map *umap)
822 return cond_un_op(umap, &range_entry);
825 static int deltas_entry(void **entry, void *user)
827 isl_map *map = *entry;
828 isl_union_set **res = user;
830 if (!isl_dim_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
831 return 0;
833 *res = isl_union_set_add_set(*res, isl_map_deltas(isl_map_copy(map)));
835 return 0;
838 __isl_give isl_union_set *isl_union_map_deltas(__isl_take isl_union_map *umap)
840 return cond_un_op(umap, &deltas_entry);
843 static int unwrap_entry(void **entry, void *user)
845 isl_set *set = *entry;
846 isl_union_set **res = user;
848 if (!isl_set_is_wrapping(set))
849 return 0;
851 *res = isl_union_map_add_map(*res, isl_set_unwrap(isl_set_copy(set)));
853 return 0;
856 __isl_give isl_union_map *isl_union_set_unwrap(__isl_take isl_union_set *uset)
858 return cond_un_op(uset, &unwrap_entry);
861 static int wrap_entry(void **entry, void *user)
863 isl_map *map = *entry;
864 isl_union_set **res = user;
866 *res = isl_union_set_add_set(*res, isl_map_wrap(isl_map_copy(map)));
868 return 0;
871 __isl_give isl_union_set *isl_union_map_wrap(__isl_take isl_union_map *umap)
873 return cond_un_op(umap, &wrap_entry);
876 struct isl_union_map_is_subset_data {
877 isl_union_map *umap2;
878 int is_subset;
881 static int is_subset_entry(void **entry, void *user)
883 struct isl_union_map_is_subset_data *data = user;
884 uint32_t hash;
885 struct isl_hash_table_entry *entry2;
886 isl_map *map = *entry;
888 hash = isl_dim_get_hash(map->dim);
889 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
890 hash, &has_dim, map->dim, 0);
891 if (!entry2) {
892 data->is_subset = 0;
893 return -1;
896 data->is_subset = isl_map_is_subset(map, entry2->data);
897 if (data->is_subset < 0 || !data->is_subset)
898 return -1;
900 return 0;
903 int isl_union_map_is_subset(__isl_keep isl_union_map *umap1,
904 __isl_keep isl_union_map *umap2)
906 struct isl_union_map_is_subset_data data = { umap2, 1 };
908 if (!umap1 || !umap2)
909 return -1;
911 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
912 &is_subset_entry, &data) < 0 &&
913 data.is_subset)
914 return -1;
916 return data.is_subset;
919 int isl_union_map_is_equal(__isl_keep isl_union_map *umap1,
920 __isl_keep isl_union_map *umap2)
922 int is_subset;
924 if (!umap1 || !umap2)
925 return -1;
926 is_subset = isl_union_map_is_subset(umap1, umap2);
927 if (is_subset != 1)
928 return is_subset;
929 is_subset = isl_union_map_is_subset(umap2, umap1);
930 return is_subset;
933 int isl_union_map_is_strict_subset(__isl_keep isl_union_map *umap1,
934 __isl_keep isl_union_map *umap2)
936 int is_subset;
938 if (!umap1 || !umap2)
939 return -1;
940 is_subset = isl_union_map_is_subset(umap1, umap2);
941 if (is_subset != 1)
942 return is_subset;
943 is_subset = isl_union_map_is_subset(umap2, umap1);
944 if (is_subset == -1)
945 return is_subset;
946 return !is_subset;
949 static int sample_entry(void **entry, void *user)
951 isl_basic_map **sample = (isl_basic_map **)user;
952 isl_map *map = *entry;
954 *sample = isl_map_sample(isl_map_copy(map));
955 if (!*sample)
956 return -1;
957 if (!isl_basic_map_fast_is_empty(*sample))
958 return -1;
959 return 0;
962 __isl_give isl_basic_map *isl_union_map_sample(__isl_take isl_union_map *umap)
964 isl_basic_map *sample = NULL;
966 if (!umap)
967 return NULL;
969 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
970 &sample_entry, &sample) < 0 &&
971 !sample)
972 goto error;
974 isl_union_map_free(umap);
976 return sample;
977 error:
978 isl_union_map_free(umap);
979 return NULL;
982 __isl_give isl_basic_set *isl_union_set_sample(__isl_take isl_union_set *uset)
984 return (isl_basic_set *)isl_union_map_sample(uset);
987 static int empty_entry(void **entry, void *user)
989 int *empty = user;
990 isl_map *map = *entry;
992 if (isl_map_is_empty(map))
993 return 0;
995 *empty = 0;
997 return -1;
1000 __isl_give int isl_union_map_is_empty(__isl_keep isl_union_map *umap)
1002 int empty = 1;
1004 if (!umap)
1005 return -1;
1007 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
1008 &empty_entry, &empty) < 0 && empty)
1009 return -1;
1011 return empty;
1014 int isl_union_set_is_empty(__isl_keep isl_union_set *uset)
1016 return isl_union_map_is_empty(uset);