include/isl/deprecated/*int.h: allow inclusion from C++
[isl.git] / isl_union_map.c
blob3c28324c726cdf3206ae8d92d7853d42de17ff14
1 /*
2 * Copyright 2010-2011 INRIA Saclay
3 * Copyright 2013-2014 Ecole Normale Superieure
5 * Use of this software is governed by the MIT license
7 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
8 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
9 * 91893 Orsay, France
12 #define ISL_DIM_H
13 #include <isl_map_private.h>
14 #include <isl/ctx.h>
15 #include <isl/hash.h>
16 #include <isl/aff.h>
17 #include <isl/map.h>
18 #include <isl/set.h>
19 #include <isl_space_private.h>
20 #include <isl_union_map_private.h>
21 #include <isl/union_set.h>
22 #include <isl/deprecated/union_map_int.h>
24 /* Is this union set a parameter domain?
26 int isl_union_set_is_params(__isl_keep isl_union_set *uset)
28 isl_set *set;
29 int params;
31 if (!uset)
32 return -1;
33 if (uset->table.n != 1)
34 return 0;
36 set = isl_set_from_union_set(isl_union_set_copy(uset));
37 params = isl_set_is_params(set);
38 isl_set_free(set);
39 return params;
42 static __isl_give isl_union_map *isl_union_map_alloc(__isl_take isl_space *dim,
43 int size)
45 isl_union_map *umap;
47 dim = isl_space_params(dim);
48 if (!dim)
49 return NULL;
51 umap = isl_calloc_type(dim->ctx, isl_union_map);
52 if (!umap)
53 return NULL;
55 umap->ref = 1;
56 umap->dim = dim;
57 if (isl_hash_table_init(dim->ctx, &umap->table, size) < 0)
58 return isl_union_map_free(umap);
60 return umap;
63 __isl_give isl_union_map *isl_union_map_empty(__isl_take isl_space *dim)
65 return isl_union_map_alloc(dim, 16);
68 __isl_give isl_union_set *isl_union_set_empty(__isl_take isl_space *dim)
70 return isl_union_map_empty(dim);
73 isl_ctx *isl_union_map_get_ctx(__isl_keep isl_union_map *umap)
75 return umap ? umap->dim->ctx : NULL;
78 isl_ctx *isl_union_set_get_ctx(__isl_keep isl_union_set *uset)
80 return uset ? uset->dim->ctx : NULL;
83 __isl_give isl_space *isl_union_map_get_space(__isl_keep isl_union_map *umap)
85 if (!umap)
86 return NULL;
87 return isl_space_copy(umap->dim);
90 __isl_give isl_space *isl_union_set_get_space(__isl_keep isl_union_set *uset)
92 return isl_union_map_get_space(uset);
95 static int free_umap_entry(void **entry, void *user)
97 isl_map *map = *entry;
98 isl_map_free(map);
99 return 0;
102 static int add_map(__isl_take isl_map *map, void *user)
104 isl_union_map **umap = (isl_union_map **)user;
106 *umap = isl_union_map_add_map(*umap, map);
108 return 0;
111 __isl_give isl_union_map *isl_union_map_dup(__isl_keep isl_union_map *umap)
113 isl_union_map *dup;
115 if (!umap)
116 return NULL;
118 dup = isl_union_map_empty(isl_space_copy(umap->dim));
119 if (isl_union_map_foreach_map(umap, &add_map, &dup) < 0)
120 goto error;
121 return dup;
122 error:
123 isl_union_map_free(dup);
124 return NULL;
127 __isl_give isl_union_map *isl_union_map_cow(__isl_take isl_union_map *umap)
129 if (!umap)
130 return NULL;
132 if (umap->ref == 1)
133 return umap;
134 umap->ref--;
135 return isl_union_map_dup(umap);
138 struct isl_union_align {
139 isl_reordering *exp;
140 isl_union_map *res;
143 static int align_entry(void **entry, void *user)
145 isl_map *map = *entry;
146 isl_reordering *exp;
147 struct isl_union_align *data = user;
149 exp = isl_reordering_extend_space(isl_reordering_copy(data->exp),
150 isl_map_get_space(map));
152 data->res = isl_union_map_add_map(data->res,
153 isl_map_realign(isl_map_copy(map), exp));
155 return 0;
158 /* Align the parameters of umap along those of model.
159 * The result has the parameters of model first, in the same order
160 * as they appear in model, followed by any remaining parameters of
161 * umap that do not appear in model.
163 __isl_give isl_union_map *isl_union_map_align_params(
164 __isl_take isl_union_map *umap, __isl_take isl_space *model)
166 struct isl_union_align data = { NULL, NULL };
168 if (!umap || !model)
169 goto error;
171 if (isl_space_match(umap->dim, isl_dim_param, model, isl_dim_param)) {
172 isl_space_free(model);
173 return umap;
176 model = isl_space_params(model);
177 data.exp = isl_parameter_alignment_reordering(umap->dim, model);
178 if (!data.exp)
179 goto error;
181 data.res = isl_union_map_alloc(isl_space_copy(data.exp->dim),
182 umap->table.n);
183 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
184 &align_entry, &data) < 0)
185 goto error;
187 isl_reordering_free(data.exp);
188 isl_union_map_free(umap);
189 isl_space_free(model);
190 return data.res;
191 error:
192 isl_reordering_free(data.exp);
193 isl_union_map_free(umap);
194 isl_union_map_free(data.res);
195 isl_space_free(model);
196 return NULL;
199 __isl_give isl_union_set *isl_union_set_align_params(
200 __isl_take isl_union_set *uset, __isl_take isl_space *model)
202 return isl_union_map_align_params(uset, model);
205 __isl_give isl_union_map *isl_union_map_union(__isl_take isl_union_map *umap1,
206 __isl_take isl_union_map *umap2)
208 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2));
209 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1));
211 umap1 = isl_union_map_cow(umap1);
213 if (!umap1 || !umap2)
214 goto error;
216 if (isl_union_map_foreach_map(umap2, &add_map, &umap1) < 0)
217 goto error;
219 isl_union_map_free(umap2);
221 return umap1;
222 error:
223 isl_union_map_free(umap1);
224 isl_union_map_free(umap2);
225 return NULL;
228 __isl_give isl_union_set *isl_union_set_union(__isl_take isl_union_set *uset1,
229 __isl_take isl_union_set *uset2)
231 return isl_union_map_union(uset1, uset2);
234 __isl_give isl_union_map *isl_union_map_copy(__isl_keep isl_union_map *umap)
236 if (!umap)
237 return NULL;
239 umap->ref++;
240 return umap;
243 __isl_give isl_union_set *isl_union_set_copy(__isl_keep isl_union_set *uset)
245 return isl_union_map_copy(uset);
248 __isl_null isl_union_map *isl_union_map_free(__isl_take isl_union_map *umap)
250 if (!umap)
251 return NULL;
253 if (--umap->ref > 0)
254 return NULL;
256 isl_hash_table_foreach(umap->dim->ctx, &umap->table,
257 &free_umap_entry, NULL);
258 isl_hash_table_clear(&umap->table);
259 isl_space_free(umap->dim);
260 free(umap);
261 return NULL;
264 __isl_null isl_union_set *isl_union_set_free(__isl_take isl_union_set *uset)
266 return isl_union_map_free(uset);
269 static int has_dim(const void *entry, const void *val)
271 isl_map *map = (isl_map *)entry;
272 isl_space *dim = (isl_space *)val;
274 return isl_space_is_equal(map->dim, dim);
277 __isl_give isl_union_map *isl_union_map_add_map(__isl_take isl_union_map *umap,
278 __isl_take isl_map *map)
280 uint32_t hash;
281 struct isl_hash_table_entry *entry;
283 if (!map || !umap)
284 goto error;
286 if (isl_map_plain_is_empty(map)) {
287 isl_map_free(map);
288 return umap;
291 if (!isl_space_match(map->dim, isl_dim_param, umap->dim, isl_dim_param)) {
292 umap = isl_union_map_align_params(umap, isl_map_get_space(map));
293 map = isl_map_align_params(map, isl_union_map_get_space(umap));
296 umap = isl_union_map_cow(umap);
298 if (!map || !umap)
299 goto error;
301 hash = isl_space_get_hash(map->dim);
302 entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
303 &has_dim, map->dim, 1);
304 if (!entry)
305 goto error;
307 if (!entry->data)
308 entry->data = map;
309 else {
310 entry->data = isl_map_union(entry->data, isl_map_copy(map));
311 if (!entry->data)
312 goto error;
313 isl_map_free(map);
316 return umap;
317 error:
318 isl_map_free(map);
319 isl_union_map_free(umap);
320 return NULL;
323 __isl_give isl_union_set *isl_union_set_add_set(__isl_take isl_union_set *uset,
324 __isl_take isl_set *set)
326 return isl_union_map_add_map(uset, (isl_map *)set);
329 __isl_give isl_union_map *isl_union_map_from_map(__isl_take isl_map *map)
331 isl_space *dim;
332 isl_union_map *umap;
334 if (!map)
335 return NULL;
337 dim = isl_map_get_space(map);
338 dim = isl_space_params(dim);
339 umap = isl_union_map_empty(dim);
340 umap = isl_union_map_add_map(umap, map);
342 return umap;
345 __isl_give isl_union_set *isl_union_set_from_set(__isl_take isl_set *set)
347 return isl_union_map_from_map((isl_map *)set);
350 __isl_give isl_union_map *isl_union_map_from_basic_map(
351 __isl_take isl_basic_map *bmap)
353 return isl_union_map_from_map(isl_map_from_basic_map(bmap));
356 __isl_give isl_union_set *isl_union_set_from_basic_set(
357 __isl_take isl_basic_set *bset)
359 return isl_union_map_from_basic_map(bset);
362 struct isl_union_map_foreach_data
364 int (*fn)(__isl_take isl_map *map, void *user);
365 void *user;
368 static int call_on_copy(void **entry, void *user)
370 isl_map *map = *entry;
371 struct isl_union_map_foreach_data *data;
372 data = (struct isl_union_map_foreach_data *)user;
374 return data->fn(isl_map_copy(map), data->user);
377 int isl_union_map_n_map(__isl_keep isl_union_map *umap)
379 return umap ? umap->table.n : 0;
382 int isl_union_set_n_set(__isl_keep isl_union_set *uset)
384 return uset ? uset->table.n : 0;
387 int isl_union_map_foreach_map(__isl_keep isl_union_map *umap,
388 int (*fn)(__isl_take isl_map *map, void *user), void *user)
390 struct isl_union_map_foreach_data data = { fn, user };
392 if (!umap)
393 return -1;
395 return isl_hash_table_foreach(umap->dim->ctx, &umap->table,
396 &call_on_copy, &data);
399 static int copy_map(void **entry, void *user)
401 isl_map *map = *entry;
402 isl_map **map_p = user;
404 *map_p = isl_map_copy(map);
406 return -1;
409 __isl_give isl_map *isl_map_from_union_map(__isl_take isl_union_map *umap)
411 isl_ctx *ctx;
412 isl_map *map = NULL;
414 if (!umap)
415 return NULL;
416 ctx = isl_union_map_get_ctx(umap);
417 if (umap->table.n != 1)
418 isl_die(ctx, isl_error_invalid,
419 "union map needs to contain elements in exactly "
420 "one space", goto error);
422 isl_hash_table_foreach(ctx, &umap->table, &copy_map, &map);
424 isl_union_map_free(umap);
426 return map;
427 error:
428 isl_union_map_free(umap);
429 return NULL;
432 __isl_give isl_set *isl_set_from_union_set(__isl_take isl_union_set *uset)
434 return isl_map_from_union_map(uset);
437 /* Extract the map in "umap" that lives in the given space (ignoring
438 * parameters).
440 __isl_give isl_map *isl_union_map_extract_map(__isl_keep isl_union_map *umap,
441 __isl_take isl_space *space)
443 uint32_t hash;
444 struct isl_hash_table_entry *entry;
446 space = isl_space_drop_dims(space, isl_dim_param,
447 0, isl_space_dim(space, isl_dim_param));
448 space = isl_space_align_params(space, isl_union_map_get_space(umap));
449 if (!umap || !space)
450 goto error;
452 hash = isl_space_get_hash(space);
453 entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
454 &has_dim, space, 0);
455 if (!entry)
456 return isl_map_empty(space);
457 isl_space_free(space);
458 return isl_map_copy(entry->data);
459 error:
460 isl_space_free(space);
461 return NULL;
464 __isl_give isl_set *isl_union_set_extract_set(__isl_keep isl_union_set *uset,
465 __isl_take isl_space *dim)
467 return (isl_set *)isl_union_map_extract_map(uset, dim);
470 /* Check if umap contains a map in the given space.
472 __isl_give int isl_union_map_contains(__isl_keep isl_union_map *umap,
473 __isl_keep isl_space *dim)
475 uint32_t hash;
476 struct isl_hash_table_entry *entry;
478 if (!umap || !dim)
479 return -1;
481 hash = isl_space_get_hash(dim);
482 entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
483 &has_dim, dim, 0);
484 return !!entry;
487 __isl_give int isl_union_set_contains(__isl_keep isl_union_set *uset,
488 __isl_keep isl_space *dim)
490 return isl_union_map_contains(uset, dim);
493 int isl_union_set_foreach_set(__isl_keep isl_union_set *uset,
494 int (*fn)(__isl_take isl_set *set, void *user), void *user)
496 return isl_union_map_foreach_map(uset,
497 (int(*)(__isl_take isl_map *, void*))fn, user);
500 struct isl_union_set_foreach_point_data {
501 int (*fn)(__isl_take isl_point *pnt, void *user);
502 void *user;
505 static int foreach_point(__isl_take isl_set *set, void *user)
507 struct isl_union_set_foreach_point_data *data = user;
508 int r;
510 r = isl_set_foreach_point(set, data->fn, data->user);
511 isl_set_free(set);
513 return r;
516 int isl_union_set_foreach_point(__isl_keep isl_union_set *uset,
517 int (*fn)(__isl_take isl_point *pnt, void *user), void *user)
519 struct isl_union_set_foreach_point_data data = { fn, user };
520 return isl_union_set_foreach_set(uset, &foreach_point, &data);
523 struct isl_union_map_gen_bin_data {
524 isl_union_map *umap2;
525 isl_union_map *res;
528 static int subtract_entry(void **entry, void *user)
530 struct isl_union_map_gen_bin_data *data = user;
531 uint32_t hash;
532 struct isl_hash_table_entry *entry2;
533 isl_map *map = *entry;
535 hash = isl_space_get_hash(map->dim);
536 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
537 hash, &has_dim, map->dim, 0);
538 map = isl_map_copy(map);
539 if (entry2) {
540 int empty;
541 map = isl_map_subtract(map, isl_map_copy(entry2->data));
543 empty = isl_map_is_empty(map);
544 if (empty < 0) {
545 isl_map_free(map);
546 return -1;
548 if (empty) {
549 isl_map_free(map);
550 return 0;
553 data->res = isl_union_map_add_map(data->res, map);
555 return 0;
558 static __isl_give isl_union_map *gen_bin_op(__isl_take isl_union_map *umap1,
559 __isl_take isl_union_map *umap2, int (*fn)(void **, void *))
561 struct isl_union_map_gen_bin_data data = { NULL, NULL };
563 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2));
564 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1));
566 if (!umap1 || !umap2)
567 goto error;
569 data.umap2 = umap2;
570 data.res = isl_union_map_alloc(isl_space_copy(umap1->dim),
571 umap1->table.n);
572 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
573 fn, &data) < 0)
574 goto error;
576 isl_union_map_free(umap1);
577 isl_union_map_free(umap2);
578 return data.res;
579 error:
580 isl_union_map_free(umap1);
581 isl_union_map_free(umap2);
582 isl_union_map_free(data.res);
583 return NULL;
586 __isl_give isl_union_map *isl_union_map_subtract(
587 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
589 return gen_bin_op(umap1, umap2, &subtract_entry);
592 __isl_give isl_union_set *isl_union_set_subtract(
593 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
595 return isl_union_map_subtract(uset1, uset2);
598 struct isl_union_map_gen_bin_set_data {
599 isl_set *set;
600 isl_union_map *res;
603 static int intersect_params_entry(void **entry, void *user)
605 struct isl_union_map_gen_bin_set_data *data = user;
606 isl_map *map = *entry;
607 int empty;
609 map = isl_map_copy(map);
610 map = isl_map_intersect_params(map, isl_set_copy(data->set));
612 empty = isl_map_is_empty(map);
613 if (empty < 0) {
614 isl_map_free(map);
615 return -1;
618 data->res = isl_union_map_add_map(data->res, map);
620 return 0;
623 static __isl_give isl_union_map *gen_bin_set_op(__isl_take isl_union_map *umap,
624 __isl_take isl_set *set, int (*fn)(void **, void *))
626 struct isl_union_map_gen_bin_set_data data = { NULL, NULL };
628 umap = isl_union_map_align_params(umap, isl_set_get_space(set));
629 set = isl_set_align_params(set, isl_union_map_get_space(umap));
631 if (!umap || !set)
632 goto error;
634 data.set = set;
635 data.res = isl_union_map_alloc(isl_space_copy(umap->dim),
636 umap->table.n);
637 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
638 fn, &data) < 0)
639 goto error;
641 isl_union_map_free(umap);
642 isl_set_free(set);
643 return data.res;
644 error:
645 isl_union_map_free(umap);
646 isl_set_free(set);
647 isl_union_map_free(data.res);
648 return NULL;
651 __isl_give isl_union_map *isl_union_map_intersect_params(
652 __isl_take isl_union_map *umap, __isl_take isl_set *set)
654 return gen_bin_set_op(umap, set, &intersect_params_entry);
657 __isl_give isl_union_set *isl_union_set_intersect_params(
658 __isl_take isl_union_set *uset, __isl_take isl_set *set)
660 return isl_union_map_intersect_params(uset, set);
663 static __isl_give isl_union_map *union_map_intersect_params(
664 __isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
666 return isl_union_map_intersect_params(umap,
667 isl_set_from_union_set(uset));
670 static __isl_give isl_union_map *union_map_gist_params(
671 __isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
673 return isl_union_map_gist_params(umap, isl_set_from_union_set(uset));
676 struct isl_union_map_match_bin_data {
677 isl_union_map *umap2;
678 isl_union_map *res;
679 __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*);
682 static int match_bin_entry(void **entry, void *user)
684 struct isl_union_map_match_bin_data *data = user;
685 uint32_t hash;
686 struct isl_hash_table_entry *entry2;
687 isl_map *map = *entry;
688 int empty;
690 hash = isl_space_get_hash(map->dim);
691 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
692 hash, &has_dim, map->dim, 0);
693 if (!entry2)
694 return 0;
696 map = isl_map_copy(map);
697 map = data->fn(map, isl_map_copy(entry2->data));
699 empty = isl_map_is_empty(map);
700 if (empty < 0) {
701 isl_map_free(map);
702 return -1;
704 if (empty) {
705 isl_map_free(map);
706 return 0;
709 data->res = isl_union_map_add_map(data->res, map);
711 return 0;
714 static __isl_give isl_union_map *match_bin_op(__isl_take isl_union_map *umap1,
715 __isl_take isl_union_map *umap2,
716 __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*))
718 struct isl_union_map_match_bin_data data = { NULL, NULL, fn };
720 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2));
721 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1));
723 if (!umap1 || !umap2)
724 goto error;
726 data.umap2 = umap2;
727 data.res = isl_union_map_alloc(isl_space_copy(umap1->dim),
728 umap1->table.n);
729 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
730 &match_bin_entry, &data) < 0)
731 goto error;
733 isl_union_map_free(umap1);
734 isl_union_map_free(umap2);
735 return data.res;
736 error:
737 isl_union_map_free(umap1);
738 isl_union_map_free(umap2);
739 isl_union_map_free(data.res);
740 return NULL;
743 __isl_give isl_union_map *isl_union_map_intersect(
744 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
746 return match_bin_op(umap1, umap2, &isl_map_intersect);
749 /* Compute the intersection of the two union_sets.
750 * As a special case, if exactly one of the two union_sets
751 * is a parameter domain, then intersect the parameter domain
752 * of the other one with this set.
754 __isl_give isl_union_set *isl_union_set_intersect(
755 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
757 int p1, p2;
759 p1 = isl_union_set_is_params(uset1);
760 p2 = isl_union_set_is_params(uset2);
761 if (p1 < 0 || p2 < 0)
762 goto error;
763 if (!p1 && p2)
764 return union_map_intersect_params(uset1, uset2);
765 if (p1 && !p2)
766 return union_map_intersect_params(uset2, uset1);
767 return isl_union_map_intersect(uset1, uset2);
768 error:
769 isl_union_set_free(uset1);
770 isl_union_set_free(uset2);
771 return NULL;
774 static int gist_params_entry(void **entry, void *user)
776 struct isl_union_map_gen_bin_set_data *data = user;
777 isl_map *map = *entry;
778 int empty;
780 map = isl_map_copy(map);
781 map = isl_map_gist_params(map, isl_set_copy(data->set));
783 empty = isl_map_is_empty(map);
784 if (empty < 0) {
785 isl_map_free(map);
786 return -1;
789 data->res = isl_union_map_add_map(data->res, map);
791 return 0;
794 __isl_give isl_union_map *isl_union_map_gist_params(
795 __isl_take isl_union_map *umap, __isl_take isl_set *set)
797 return gen_bin_set_op(umap, set, &gist_params_entry);
800 __isl_give isl_union_set *isl_union_set_gist_params(
801 __isl_take isl_union_set *uset, __isl_take isl_set *set)
803 return isl_union_map_gist_params(uset, set);
806 __isl_give isl_union_map *isl_union_map_gist(__isl_take isl_union_map *umap,
807 __isl_take isl_union_map *context)
809 return match_bin_op(umap, context, &isl_map_gist);
812 __isl_give isl_union_set *isl_union_set_gist(__isl_take isl_union_set *uset,
813 __isl_take isl_union_set *context)
815 if (isl_union_set_is_params(context))
816 return union_map_gist_params(uset, context);
817 return isl_union_map_gist(uset, context);
820 static __isl_give isl_map *lex_le_set(__isl_take isl_map *set1,
821 __isl_take isl_map *set2)
823 return isl_set_lex_le_set((isl_set *)set1, (isl_set *)set2);
826 static __isl_give isl_map *lex_lt_set(__isl_take isl_map *set1,
827 __isl_take isl_map *set2)
829 return isl_set_lex_lt_set((isl_set *)set1, (isl_set *)set2);
832 __isl_give isl_union_map *isl_union_set_lex_lt_union_set(
833 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
835 return match_bin_op(uset1, uset2, &lex_lt_set);
838 __isl_give isl_union_map *isl_union_set_lex_le_union_set(
839 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
841 return match_bin_op(uset1, uset2, &lex_le_set);
844 __isl_give isl_union_map *isl_union_set_lex_gt_union_set(
845 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
847 return isl_union_map_reverse(isl_union_set_lex_lt_union_set(uset2, uset1));
850 __isl_give isl_union_map *isl_union_set_lex_ge_union_set(
851 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
853 return isl_union_map_reverse(isl_union_set_lex_le_union_set(uset2, uset1));
856 __isl_give isl_union_map *isl_union_map_lex_gt_union_map(
857 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
859 return isl_union_map_reverse(isl_union_map_lex_lt_union_map(umap2, umap1));
862 __isl_give isl_union_map *isl_union_map_lex_ge_union_map(
863 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
865 return isl_union_map_reverse(isl_union_map_lex_le_union_map(umap2, umap1));
868 static int intersect_domain_entry(void **entry, void *user)
870 struct isl_union_map_gen_bin_data *data = user;
871 uint32_t hash;
872 struct isl_hash_table_entry *entry2;
873 isl_space *dim;
874 isl_map *map = *entry;
875 int empty;
877 dim = isl_map_get_space(map);
878 dim = isl_space_domain(dim);
879 hash = isl_space_get_hash(dim);
880 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
881 hash, &has_dim, dim, 0);
882 isl_space_free(dim);
883 if (!entry2)
884 return 0;
886 map = isl_map_copy(map);
887 map = isl_map_intersect_domain(map, isl_set_copy(entry2->data));
889 empty = isl_map_is_empty(map);
890 if (empty < 0) {
891 isl_map_free(map);
892 return -1;
894 if (empty) {
895 isl_map_free(map);
896 return 0;
899 data->res = isl_union_map_add_map(data->res, map);
901 return 0;
904 /* Intersect the domain of "umap" with "uset".
905 * If "uset" is a parameters domain, then intersect the parameter
906 * domain of "umap" with this set.
908 __isl_give isl_union_map *isl_union_map_intersect_domain(
909 __isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
911 if (isl_union_set_is_params(uset))
912 return union_map_intersect_params(umap, uset);
913 return gen_bin_op(umap, uset, &intersect_domain_entry);
916 /* Remove the elements of data->umap2 from the domain of *entry
917 * and add the result to data->res.
919 static int subtract_domain_entry(void **entry, void *user)
921 struct isl_union_map_gen_bin_data *data = user;
922 uint32_t hash;
923 struct isl_hash_table_entry *entry2;
924 isl_space *dim;
925 isl_map *map = *entry;
926 int empty;
928 dim = isl_map_get_space(map);
929 dim = isl_space_domain(dim);
930 hash = isl_space_get_hash(dim);
931 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
932 hash, &has_dim, dim, 0);
933 isl_space_free(dim);
935 map = isl_map_copy(map);
937 if (!entry2) {
938 data->res = isl_union_map_add_map(data->res, map);
939 return 0;
942 map = isl_map_subtract_domain(map, isl_set_copy(entry2->data));
944 empty = isl_map_is_empty(map);
945 if (empty < 0) {
946 isl_map_free(map);
947 return -1;
949 if (empty) {
950 isl_map_free(map);
951 return 0;
954 data->res = isl_union_map_add_map(data->res, map);
956 return 0;
959 /* Remove the elements of "uset" from the domain of "umap".
961 __isl_give isl_union_map *isl_union_map_subtract_domain(
962 __isl_take isl_union_map *umap, __isl_take isl_union_set *dom)
964 return gen_bin_op(umap, dom, &subtract_domain_entry);
967 /* Remove the elements of data->umap2 from the range of *entry
968 * and add the result to data->res.
970 static int subtract_range_entry(void **entry, void *user)
972 struct isl_union_map_gen_bin_data *data = user;
973 uint32_t hash;
974 struct isl_hash_table_entry *entry2;
975 isl_space *space;
976 isl_map *map = *entry;
977 int empty;
979 space = isl_map_get_space(map);
980 space = isl_space_range(space);
981 hash = isl_space_get_hash(space);
982 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
983 hash, &has_dim, space, 0);
984 isl_space_free(space);
986 map = isl_map_copy(map);
988 if (!entry2) {
989 data->res = isl_union_map_add_map(data->res, map);
990 return 0;
993 map = isl_map_subtract_range(map, isl_set_copy(entry2->data));
995 empty = isl_map_is_empty(map);
996 if (empty < 0) {
997 isl_map_free(map);
998 return -1;
1000 if (empty) {
1001 isl_map_free(map);
1002 return 0;
1005 data->res = isl_union_map_add_map(data->res, map);
1007 return 0;
1010 /* Remove the elements of "uset" from the range of "umap".
1012 __isl_give isl_union_map *isl_union_map_subtract_range(
1013 __isl_take isl_union_map *umap, __isl_take isl_union_set *dom)
1015 return gen_bin_op(umap, dom, &subtract_range_entry);
1018 static int gist_domain_entry(void **entry, void *user)
1020 struct isl_union_map_gen_bin_data *data = user;
1021 uint32_t hash;
1022 struct isl_hash_table_entry *entry2;
1023 isl_space *dim;
1024 isl_map *map = *entry;
1025 int empty;
1027 dim = isl_map_get_space(map);
1028 dim = isl_space_domain(dim);
1029 hash = isl_space_get_hash(dim);
1030 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
1031 hash, &has_dim, dim, 0);
1032 isl_space_free(dim);
1033 if (!entry2)
1034 return 0;
1036 map = isl_map_copy(map);
1037 map = isl_map_gist_domain(map, isl_set_copy(entry2->data));
1039 empty = isl_map_is_empty(map);
1040 if (empty < 0) {
1041 isl_map_free(map);
1042 return -1;
1045 data->res = isl_union_map_add_map(data->res, map);
1047 return 0;
1050 /* Compute the gist of "umap" with respect to the domain "uset".
1051 * If "uset" is a parameters domain, then compute the gist
1052 * with respect to this parameter domain.
1054 __isl_give isl_union_map *isl_union_map_gist_domain(
1055 __isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
1057 if (isl_union_set_is_params(uset))
1058 return union_map_gist_params(umap, uset);
1059 return gen_bin_op(umap, uset, &gist_domain_entry);
1062 static int gist_range_entry(void **entry, void *user)
1064 struct isl_union_map_gen_bin_data *data = user;
1065 uint32_t hash;
1066 struct isl_hash_table_entry *entry2;
1067 isl_space *space;
1068 isl_map *map = *entry;
1069 int empty;
1071 space = isl_map_get_space(map);
1072 space = isl_space_range(space);
1073 hash = isl_space_get_hash(space);
1074 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
1075 hash, &has_dim, space, 0);
1076 isl_space_free(space);
1077 if (!entry2)
1078 return 0;
1080 map = isl_map_copy(map);
1081 map = isl_map_gist_range(map, isl_set_copy(entry2->data));
1083 empty = isl_map_is_empty(map);
1084 if (empty < 0) {
1085 isl_map_free(map);
1086 return -1;
1089 data->res = isl_union_map_add_map(data->res, map);
1091 return 0;
1094 /* Compute the gist of "umap" with respect to the range "uset".
1096 __isl_give isl_union_map *isl_union_map_gist_range(
1097 __isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
1099 return gen_bin_op(umap, uset, &gist_range_entry);
1102 static int intersect_range_entry(void **entry, void *user)
1104 struct isl_union_map_gen_bin_data *data = user;
1105 uint32_t hash;
1106 struct isl_hash_table_entry *entry2;
1107 isl_space *dim;
1108 isl_map *map = *entry;
1109 int empty;
1111 dim = isl_map_get_space(map);
1112 dim = isl_space_range(dim);
1113 hash = isl_space_get_hash(dim);
1114 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
1115 hash, &has_dim, dim, 0);
1116 isl_space_free(dim);
1117 if (!entry2)
1118 return 0;
1120 map = isl_map_copy(map);
1121 map = isl_map_intersect_range(map, isl_set_copy(entry2->data));
1123 empty = isl_map_is_empty(map);
1124 if (empty < 0) {
1125 isl_map_free(map);
1126 return -1;
1128 if (empty) {
1129 isl_map_free(map);
1130 return 0;
1133 data->res = isl_union_map_add_map(data->res, map);
1135 return 0;
1138 __isl_give isl_union_map *isl_union_map_intersect_range(
1139 __isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
1141 return gen_bin_op(umap, uset, &intersect_range_entry);
1144 struct isl_union_map_bin_data {
1145 isl_union_map *umap2;
1146 isl_union_map *res;
1147 isl_map *map;
1148 int (*fn)(void **entry, void *user);
1151 static int apply_range_entry(void **entry, void *user)
1153 struct isl_union_map_bin_data *data = user;
1154 isl_map *map2 = *entry;
1155 int empty;
1157 if (!isl_space_tuple_match(data->map->dim, isl_dim_out,
1158 map2->dim, isl_dim_in))
1159 return 0;
1161 map2 = isl_map_apply_range(isl_map_copy(data->map), isl_map_copy(map2));
1163 empty = isl_map_is_empty(map2);
1164 if (empty < 0) {
1165 isl_map_free(map2);
1166 return -1;
1168 if (empty) {
1169 isl_map_free(map2);
1170 return 0;
1173 data->res = isl_union_map_add_map(data->res, map2);
1175 return 0;
1178 static int bin_entry(void **entry, void *user)
1180 struct isl_union_map_bin_data *data = user;
1181 isl_map *map = *entry;
1183 data->map = map;
1184 if (isl_hash_table_foreach(data->umap2->dim->ctx, &data->umap2->table,
1185 data->fn, data) < 0)
1186 return -1;
1188 return 0;
1191 static __isl_give isl_union_map *bin_op(__isl_take isl_union_map *umap1,
1192 __isl_take isl_union_map *umap2, int (*fn)(void **entry, void *user))
1194 struct isl_union_map_bin_data data = { NULL, NULL, NULL, fn };
1196 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2));
1197 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1));
1199 if (!umap1 || !umap2)
1200 goto error;
1202 data.umap2 = umap2;
1203 data.res = isl_union_map_alloc(isl_space_copy(umap1->dim),
1204 umap1->table.n);
1205 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
1206 &bin_entry, &data) < 0)
1207 goto error;
1209 isl_union_map_free(umap1);
1210 isl_union_map_free(umap2);
1211 return data.res;
1212 error:
1213 isl_union_map_free(umap1);
1214 isl_union_map_free(umap2);
1215 isl_union_map_free(data.res);
1216 return NULL;
1219 __isl_give isl_union_map *isl_union_map_apply_range(
1220 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
1222 return bin_op(umap1, umap2, &apply_range_entry);
1225 __isl_give isl_union_map *isl_union_map_apply_domain(
1226 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
1228 umap1 = isl_union_map_reverse(umap1);
1229 umap1 = isl_union_map_apply_range(umap1, umap2);
1230 return isl_union_map_reverse(umap1);
1233 __isl_give isl_union_set *isl_union_set_apply(
1234 __isl_take isl_union_set *uset, __isl_take isl_union_map *umap)
1236 return isl_union_map_apply_range(uset, umap);
1239 static int map_lex_lt_entry(void **entry, void *user)
1241 struct isl_union_map_bin_data *data = user;
1242 isl_map *map2 = *entry;
1244 if (!isl_space_tuple_match(data->map->dim, isl_dim_out,
1245 map2->dim, isl_dim_out))
1246 return 0;
1248 map2 = isl_map_lex_lt_map(isl_map_copy(data->map), isl_map_copy(map2));
1250 data->res = isl_union_map_add_map(data->res, map2);
1252 return 0;
1255 __isl_give isl_union_map *isl_union_map_lex_lt_union_map(
1256 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
1258 return bin_op(umap1, umap2, &map_lex_lt_entry);
1261 static int map_lex_le_entry(void **entry, void *user)
1263 struct isl_union_map_bin_data *data = user;
1264 isl_map *map2 = *entry;
1266 if (!isl_space_tuple_match(data->map->dim, isl_dim_out,
1267 map2->dim, isl_dim_out))
1268 return 0;
1270 map2 = isl_map_lex_le_map(isl_map_copy(data->map), isl_map_copy(map2));
1272 data->res = isl_union_map_add_map(data->res, map2);
1274 return 0;
1277 __isl_give isl_union_map *isl_union_map_lex_le_union_map(
1278 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
1280 return bin_op(umap1, umap2, &map_lex_le_entry);
1283 static int product_entry(void **entry, void *user)
1285 struct isl_union_map_bin_data *data = user;
1286 isl_map *map2 = *entry;
1288 map2 = isl_map_product(isl_map_copy(data->map), isl_map_copy(map2));
1290 data->res = isl_union_map_add_map(data->res, map2);
1292 return 0;
1295 __isl_give isl_union_map *isl_union_map_product(__isl_take isl_union_map *umap1,
1296 __isl_take isl_union_map *umap2)
1298 return bin_op(umap1, umap2, &product_entry);
1301 static int set_product_entry(void **entry, void *user)
1303 struct isl_union_map_bin_data *data = user;
1304 isl_set *set2 = *entry;
1306 set2 = isl_set_product(isl_set_copy(data->map), isl_set_copy(set2));
1308 data->res = isl_union_set_add_set(data->res, set2);
1310 return 0;
1313 __isl_give isl_union_set *isl_union_set_product(__isl_take isl_union_set *uset1,
1314 __isl_take isl_union_set *uset2)
1316 return bin_op(uset1, uset2, &set_product_entry);
1319 static int domain_product_entry(void **entry, void *user)
1321 struct isl_union_map_bin_data *data = user;
1322 isl_map *map2 = *entry;
1324 if (!isl_space_tuple_match(data->map->dim, isl_dim_out,
1325 map2->dim, isl_dim_out))
1326 return 0;
1328 map2 = isl_map_domain_product(isl_map_copy(data->map),
1329 isl_map_copy(map2));
1331 data->res = isl_union_map_add_map(data->res, map2);
1333 return 0;
1336 /* Given two maps A -> B and C -> D, construct a map [A -> C] -> (B * D)
1338 __isl_give isl_union_map *isl_union_map_domain_product(
1339 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
1341 return bin_op(umap1, umap2, &domain_product_entry);
1344 static int range_product_entry(void **entry, void *user)
1346 struct isl_union_map_bin_data *data = user;
1347 isl_map *map2 = *entry;
1349 if (!isl_space_tuple_match(data->map->dim, isl_dim_in,
1350 map2->dim, isl_dim_in))
1351 return 0;
1353 map2 = isl_map_range_product(isl_map_copy(data->map),
1354 isl_map_copy(map2));
1356 data->res = isl_union_map_add_map(data->res, map2);
1358 return 0;
1361 __isl_give isl_union_map *isl_union_map_range_product(
1362 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
1364 return bin_op(umap1, umap2, &range_product_entry);
1367 static int flat_range_product_entry(void **entry, void *user)
1369 struct isl_union_map_bin_data *data = user;
1370 isl_map *map2 = *entry;
1372 if (!isl_space_tuple_match(data->map->dim, isl_dim_in,
1373 map2->dim, isl_dim_in))
1374 return 0;
1376 map2 = isl_map_flat_range_product(isl_map_copy(data->map),
1377 isl_map_copy(map2));
1379 data->res = isl_union_map_add_map(data->res, map2);
1381 return 0;
1384 __isl_give isl_union_map *isl_union_map_flat_range_product(
1385 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
1387 return bin_op(umap1, umap2, &flat_range_product_entry);
1390 static __isl_give isl_union_set *cond_un_op(__isl_take isl_union_map *umap,
1391 int (*fn)(void **, void *))
1393 isl_union_set *res;
1395 if (!umap)
1396 return NULL;
1398 res = isl_union_map_alloc(isl_space_copy(umap->dim), umap->table.n);
1399 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, fn, &res) < 0)
1400 goto error;
1402 isl_union_map_free(umap);
1403 return res;
1404 error:
1405 isl_union_map_free(umap);
1406 isl_union_set_free(res);
1407 return NULL;
1410 static int from_range_entry(void **entry, void *user)
1412 isl_map *set = *entry;
1413 isl_union_set **res = user;
1415 *res = isl_union_map_add_map(*res,
1416 isl_map_from_range(isl_set_copy(set)));
1418 return 0;
1421 __isl_give isl_union_map *isl_union_map_from_range(
1422 __isl_take isl_union_set *uset)
1424 return cond_un_op(uset, &from_range_entry);
1427 __isl_give isl_union_map *isl_union_map_from_domain(
1428 __isl_take isl_union_set *uset)
1430 return isl_union_map_reverse(isl_union_map_from_range(uset));
1433 __isl_give isl_union_map *isl_union_map_from_domain_and_range(
1434 __isl_take isl_union_set *domain, __isl_take isl_union_set *range)
1436 return isl_union_map_apply_range(isl_union_map_from_domain(domain),
1437 isl_union_map_from_range(range));
1440 static __isl_give isl_union_map *un_op(__isl_take isl_union_map *umap,
1441 int (*fn)(void **, void *))
1443 umap = isl_union_map_cow(umap);
1444 if (!umap)
1445 return NULL;
1447 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, fn, NULL) < 0)
1448 goto error;
1450 return umap;
1451 error:
1452 isl_union_map_free(umap);
1453 return NULL;
1456 static int affine_entry(void **entry, void *user)
1458 isl_map **map = (isl_map **)entry;
1460 *map = isl_map_from_basic_map(isl_map_affine_hull(*map));
1462 return *map ? 0 : -1;
1465 __isl_give isl_union_map *isl_union_map_affine_hull(
1466 __isl_take isl_union_map *umap)
1468 return un_op(umap, &affine_entry);
1471 __isl_give isl_union_set *isl_union_set_affine_hull(
1472 __isl_take isl_union_set *uset)
1474 return isl_union_map_affine_hull(uset);
1477 static int polyhedral_entry(void **entry, void *user)
1479 isl_map **map = (isl_map **)entry;
1481 *map = isl_map_from_basic_map(isl_map_polyhedral_hull(*map));
1483 return *map ? 0 : -1;
1486 __isl_give isl_union_map *isl_union_map_polyhedral_hull(
1487 __isl_take isl_union_map *umap)
1489 return un_op(umap, &polyhedral_entry);
1492 __isl_give isl_union_set *isl_union_set_polyhedral_hull(
1493 __isl_take isl_union_set *uset)
1495 return isl_union_map_polyhedral_hull(uset);
1498 static int simple_entry(void **entry, void *user)
1500 isl_map **map = (isl_map **)entry;
1502 *map = isl_map_from_basic_map(isl_map_simple_hull(*map));
1504 return *map ? 0 : -1;
1507 __isl_give isl_union_map *isl_union_map_simple_hull(
1508 __isl_take isl_union_map *umap)
1510 return un_op(umap, &simple_entry);
1513 __isl_give isl_union_set *isl_union_set_simple_hull(
1514 __isl_take isl_union_set *uset)
1516 return isl_union_map_simple_hull(uset);
1519 static int inplace_entry(void **entry, void *user)
1521 __isl_give isl_map *(*fn)(__isl_take isl_map *);
1522 isl_map **map = (isl_map **)entry;
1523 isl_map *copy;
1525 fn = *(__isl_give isl_map *(**)(__isl_take isl_map *)) user;
1526 copy = fn(isl_map_copy(*map));
1527 if (!copy)
1528 return -1;
1530 isl_map_free(*map);
1531 *map = copy;
1533 return 0;
1536 static __isl_give isl_union_map *inplace(__isl_take isl_union_map *umap,
1537 __isl_give isl_map *(*fn)(__isl_take isl_map *))
1539 if (!umap)
1540 return NULL;
1542 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
1543 &inplace_entry, &fn) < 0)
1544 goto error;
1546 return umap;
1547 error:
1548 isl_union_map_free(umap);
1549 return NULL;
1552 __isl_give isl_union_map *isl_union_map_coalesce(
1553 __isl_take isl_union_map *umap)
1555 return inplace(umap, &isl_map_coalesce);
1558 __isl_give isl_union_set *isl_union_set_coalesce(
1559 __isl_take isl_union_set *uset)
1561 return isl_union_map_coalesce(uset);
1564 __isl_give isl_union_map *isl_union_map_detect_equalities(
1565 __isl_take isl_union_map *umap)
1567 return inplace(umap, &isl_map_detect_equalities);
1570 __isl_give isl_union_set *isl_union_set_detect_equalities(
1571 __isl_take isl_union_set *uset)
1573 return isl_union_map_detect_equalities(uset);
1576 __isl_give isl_union_map *isl_union_map_compute_divs(
1577 __isl_take isl_union_map *umap)
1579 return inplace(umap, &isl_map_compute_divs);
1582 __isl_give isl_union_set *isl_union_set_compute_divs(
1583 __isl_take isl_union_set *uset)
1585 return isl_union_map_compute_divs(uset);
1588 static int lexmin_entry(void **entry, void *user)
1590 isl_map **map = (isl_map **)entry;
1592 *map = isl_map_lexmin(*map);
1594 return *map ? 0 : -1;
1597 __isl_give isl_union_map *isl_union_map_lexmin(
1598 __isl_take isl_union_map *umap)
1600 return un_op(umap, &lexmin_entry);
1603 __isl_give isl_union_set *isl_union_set_lexmin(
1604 __isl_take isl_union_set *uset)
1606 return isl_union_map_lexmin(uset);
1609 static int lexmax_entry(void **entry, void *user)
1611 isl_map **map = (isl_map **)entry;
1613 *map = isl_map_lexmax(*map);
1615 return *map ? 0 : -1;
1618 __isl_give isl_union_map *isl_union_map_lexmax(
1619 __isl_take isl_union_map *umap)
1621 return un_op(umap, &lexmax_entry);
1624 __isl_give isl_union_set *isl_union_set_lexmax(
1625 __isl_take isl_union_set *uset)
1627 return isl_union_map_lexmax(uset);
1630 static int universe_entry(void **entry, void *user)
1632 isl_map *map = *entry;
1633 isl_union_map **res = user;
1635 map = isl_map_universe(isl_map_get_space(map));
1636 *res = isl_union_map_add_map(*res, map);
1638 return 0;
1641 __isl_give isl_union_map *isl_union_map_universe(__isl_take isl_union_map *umap)
1643 return cond_un_op(umap, &universe_entry);
1646 __isl_give isl_union_set *isl_union_set_universe(__isl_take isl_union_set *uset)
1648 return isl_union_map_universe(uset);
1651 static int reverse_entry(void **entry, void *user)
1653 isl_map *map = *entry;
1654 isl_union_map **res = user;
1656 *res = isl_union_map_add_map(*res, isl_map_reverse(isl_map_copy(map)));
1658 return 0;
1661 __isl_give isl_union_map *isl_union_map_reverse(__isl_take isl_union_map *umap)
1663 return cond_un_op(umap, &reverse_entry);
1666 static int params_entry(void **entry, void *user)
1668 isl_map *map = *entry;
1669 isl_union_set **res = user;
1671 *res = isl_union_set_add_set(*res, isl_map_params(isl_map_copy(map)));
1673 return 0;
1676 /* Compute the parameter domain of the given union map.
1678 __isl_give isl_set *isl_union_map_params(__isl_take isl_union_map *umap)
1680 int empty;
1682 empty = isl_union_map_is_empty(umap);
1683 if (empty < 0)
1684 goto error;
1685 if (empty) {
1686 isl_space *space;
1687 space = isl_union_map_get_space(umap);
1688 isl_union_map_free(umap);
1689 return isl_set_empty(space);
1691 return isl_set_from_union_set(cond_un_op(umap, &params_entry));
1692 error:
1693 isl_union_map_free(umap);
1694 return NULL;
1697 /* Compute the parameter domain of the given union set.
1699 __isl_give isl_set *isl_union_set_params(__isl_take isl_union_set *uset)
1701 return isl_union_map_params(uset);
1704 static int domain_entry(void **entry, void *user)
1706 isl_map *map = *entry;
1707 isl_union_set **res = user;
1709 *res = isl_union_set_add_set(*res, isl_map_domain(isl_map_copy(map)));
1711 return 0;
1714 __isl_give isl_union_set *isl_union_map_domain(__isl_take isl_union_map *umap)
1716 return cond_un_op(umap, &domain_entry);
1719 static int range_entry(void **entry, void *user)
1721 isl_map *map = *entry;
1722 isl_union_set **res = user;
1724 *res = isl_union_set_add_set(*res, isl_map_range(isl_map_copy(map)));
1726 return 0;
1729 __isl_give isl_union_set *isl_union_map_range(__isl_take isl_union_map *umap)
1731 return cond_un_op(umap, &range_entry);
1734 static int domain_map_entry(void **entry, void *user)
1736 isl_map *map = *entry;
1737 isl_union_set **res = user;
1739 *res = isl_union_map_add_map(*res,
1740 isl_map_domain_map(isl_map_copy(map)));
1742 return 0;
1745 __isl_give isl_union_map *isl_union_map_domain_map(
1746 __isl_take isl_union_map *umap)
1748 return cond_un_op(umap, &domain_map_entry);
1751 static int range_map_entry(void **entry, void *user)
1753 isl_map *map = *entry;
1754 isl_union_set **res = user;
1756 *res = isl_union_map_add_map(*res,
1757 isl_map_range_map(isl_map_copy(map)));
1759 return 0;
1762 __isl_give isl_union_map *isl_union_map_range_map(
1763 __isl_take isl_union_map *umap)
1765 return cond_un_op(umap, &range_map_entry);
1768 static int deltas_entry(void **entry, void *user)
1770 isl_map *map = *entry;
1771 isl_union_set **res = user;
1773 if (!isl_space_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
1774 return 0;
1776 *res = isl_union_set_add_set(*res, isl_map_deltas(isl_map_copy(map)));
1778 return 0;
1781 __isl_give isl_union_set *isl_union_map_deltas(__isl_take isl_union_map *umap)
1783 return cond_un_op(umap, &deltas_entry);
1786 static int deltas_map_entry(void **entry, void *user)
1788 isl_map *map = *entry;
1789 isl_union_map **res = user;
1791 if (!isl_space_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
1792 return 0;
1794 *res = isl_union_map_add_map(*res,
1795 isl_map_deltas_map(isl_map_copy(map)));
1797 return 0;
1800 __isl_give isl_union_map *isl_union_map_deltas_map(
1801 __isl_take isl_union_map *umap)
1803 return cond_un_op(umap, &deltas_map_entry);
1806 static int identity_entry(void **entry, void *user)
1808 isl_set *set = *entry;
1809 isl_union_map **res = user;
1811 *res = isl_union_map_add_map(*res, isl_set_identity(isl_set_copy(set)));
1813 return 0;
1816 __isl_give isl_union_map *isl_union_set_identity(__isl_take isl_union_set *uset)
1818 return cond_un_op(uset, &identity_entry);
1821 static int unwrap_entry(void **entry, void *user)
1823 isl_set *set = *entry;
1824 isl_union_set **res = user;
1826 if (!isl_set_is_wrapping(set))
1827 return 0;
1829 *res = isl_union_map_add_map(*res, isl_set_unwrap(isl_set_copy(set)));
1831 return 0;
1834 __isl_give isl_union_map *isl_union_set_unwrap(__isl_take isl_union_set *uset)
1836 return cond_un_op(uset, &unwrap_entry);
1839 static int wrap_entry(void **entry, void *user)
1841 isl_map *map = *entry;
1842 isl_union_set **res = user;
1844 *res = isl_union_set_add_set(*res, isl_map_wrap(isl_map_copy(map)));
1846 return 0;
1849 __isl_give isl_union_set *isl_union_map_wrap(__isl_take isl_union_map *umap)
1851 return cond_un_op(umap, &wrap_entry);
1854 struct isl_union_map_is_subset_data {
1855 isl_union_map *umap2;
1856 int is_subset;
1859 static int is_subset_entry(void **entry, void *user)
1861 struct isl_union_map_is_subset_data *data = user;
1862 uint32_t hash;
1863 struct isl_hash_table_entry *entry2;
1864 isl_map *map = *entry;
1866 hash = isl_space_get_hash(map->dim);
1867 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
1868 hash, &has_dim, map->dim, 0);
1869 if (!entry2) {
1870 int empty = isl_map_is_empty(map);
1871 if (empty < 0)
1872 return -1;
1873 if (empty)
1874 return 0;
1875 data->is_subset = 0;
1876 return -1;
1879 data->is_subset = isl_map_is_subset(map, entry2->data);
1880 if (data->is_subset < 0 || !data->is_subset)
1881 return -1;
1883 return 0;
1886 int isl_union_map_is_subset(__isl_keep isl_union_map *umap1,
1887 __isl_keep isl_union_map *umap2)
1889 struct isl_union_map_is_subset_data data = { NULL, 1 };
1891 umap1 = isl_union_map_copy(umap1);
1892 umap2 = isl_union_map_copy(umap2);
1893 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2));
1894 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1));
1896 if (!umap1 || !umap2)
1897 goto error;
1899 data.umap2 = umap2;
1900 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
1901 &is_subset_entry, &data) < 0 &&
1902 data.is_subset)
1903 goto error;
1905 isl_union_map_free(umap1);
1906 isl_union_map_free(umap2);
1908 return data.is_subset;
1909 error:
1910 isl_union_map_free(umap1);
1911 isl_union_map_free(umap2);
1912 return -1;
1915 int isl_union_set_is_subset(__isl_keep isl_union_set *uset1,
1916 __isl_keep isl_union_set *uset2)
1918 return isl_union_map_is_subset(uset1, uset2);
1921 int isl_union_map_is_equal(__isl_keep isl_union_map *umap1,
1922 __isl_keep isl_union_map *umap2)
1924 int is_subset;
1926 if (!umap1 || !umap2)
1927 return -1;
1928 is_subset = isl_union_map_is_subset(umap1, umap2);
1929 if (is_subset != 1)
1930 return is_subset;
1931 is_subset = isl_union_map_is_subset(umap2, umap1);
1932 return is_subset;
1935 int isl_union_set_is_equal(__isl_keep isl_union_set *uset1,
1936 __isl_keep isl_union_set *uset2)
1938 return isl_union_map_is_equal(uset1, uset2);
1941 int isl_union_map_is_strict_subset(__isl_keep isl_union_map *umap1,
1942 __isl_keep isl_union_map *umap2)
1944 int is_subset;
1946 if (!umap1 || !umap2)
1947 return -1;
1948 is_subset = isl_union_map_is_subset(umap1, umap2);
1949 if (is_subset != 1)
1950 return is_subset;
1951 is_subset = isl_union_map_is_subset(umap2, umap1);
1952 if (is_subset == -1)
1953 return is_subset;
1954 return !is_subset;
1957 int isl_union_set_is_strict_subset(__isl_keep isl_union_set *uset1,
1958 __isl_keep isl_union_set *uset2)
1960 return isl_union_map_is_strict_subset(uset1, uset2);
1963 static int sample_entry(void **entry, void *user)
1965 isl_basic_map **sample = (isl_basic_map **)user;
1966 isl_map *map = *entry;
1968 *sample = isl_map_sample(isl_map_copy(map));
1969 if (!*sample)
1970 return -1;
1971 if (!isl_basic_map_plain_is_empty(*sample))
1972 return -1;
1973 return 0;
1976 __isl_give isl_basic_map *isl_union_map_sample(__isl_take isl_union_map *umap)
1978 isl_basic_map *sample = NULL;
1980 if (!umap)
1981 return NULL;
1983 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
1984 &sample_entry, &sample) < 0 &&
1985 !sample)
1986 goto error;
1988 if (!sample)
1989 sample = isl_basic_map_empty(isl_union_map_get_space(umap));
1991 isl_union_map_free(umap);
1993 return sample;
1994 error:
1995 isl_union_map_free(umap);
1996 return NULL;
1999 __isl_give isl_basic_set *isl_union_set_sample(__isl_take isl_union_set *uset)
2001 return (isl_basic_set *)isl_union_map_sample(uset);
2004 struct isl_forall_data {
2005 int res;
2006 int (*fn)(__isl_keep isl_map *map);
2009 static int forall_entry(void **entry, void *user)
2011 struct isl_forall_data *data = user;
2012 isl_map *map = *entry;
2014 data->res = data->fn(map);
2015 if (data->res < 0)
2016 return -1;
2018 if (!data->res)
2019 return -1;
2021 return 0;
2024 static int union_map_forall(__isl_keep isl_union_map *umap,
2025 int (*fn)(__isl_keep isl_map *map))
2027 struct isl_forall_data data = { 1, fn };
2029 if (!umap)
2030 return -1;
2032 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
2033 &forall_entry, &data) < 0 && data.res)
2034 return -1;
2036 return data.res;
2039 struct isl_forall_user_data {
2040 int res;
2041 int (*fn)(__isl_keep isl_map *map, void *user);
2042 void *user;
2045 static int forall_user_entry(void **entry, void *user)
2047 struct isl_forall_user_data *data = user;
2048 isl_map *map = *entry;
2050 data->res = data->fn(map, data->user);
2051 if (data->res < 0)
2052 return -1;
2054 if (!data->res)
2055 return -1;
2057 return 0;
2060 /* Check if fn(map, user) returns true for all maps "map" in umap.
2062 static int union_map_forall_user(__isl_keep isl_union_map *umap,
2063 int (*fn)(__isl_keep isl_map *map, void *user), void *user)
2065 struct isl_forall_user_data data = { 1, fn, user };
2067 if (!umap)
2068 return -1;
2070 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
2071 &forall_user_entry, &data) < 0 && data.res)
2072 return -1;
2074 return data.res;
2077 int isl_union_map_is_empty(__isl_keep isl_union_map *umap)
2079 return union_map_forall(umap, &isl_map_is_empty);
2082 int isl_union_set_is_empty(__isl_keep isl_union_set *uset)
2084 return isl_union_map_is_empty(uset);
2087 static int is_subset_of_identity(__isl_keep isl_map *map)
2089 int is_subset;
2090 isl_space *dim;
2091 isl_map *id;
2093 if (!map)
2094 return -1;
2096 if (!isl_space_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
2097 return 0;
2099 dim = isl_map_get_space(map);
2100 id = isl_map_identity(dim);
2102 is_subset = isl_map_is_subset(map, id);
2104 isl_map_free(id);
2106 return is_subset;
2109 /* Check if the given map is single-valued.
2110 * We simply compute
2112 * M \circ M^-1
2114 * and check if the result is a subset of the identity mapping.
2116 int isl_union_map_is_single_valued(__isl_keep isl_union_map *umap)
2118 isl_union_map *test;
2119 int sv;
2121 if (isl_union_map_n_map(umap) == 1) {
2122 isl_map *map;
2123 umap = isl_union_map_copy(umap);
2124 map = isl_map_from_union_map(umap);
2125 sv = isl_map_is_single_valued(map);
2126 isl_map_free(map);
2127 return sv;
2130 test = isl_union_map_reverse(isl_union_map_copy(umap));
2131 test = isl_union_map_apply_range(test, isl_union_map_copy(umap));
2133 sv = union_map_forall(test, &is_subset_of_identity);
2135 isl_union_map_free(test);
2137 return sv;
2140 int isl_union_map_is_injective(__isl_keep isl_union_map *umap)
2142 int in;
2144 umap = isl_union_map_copy(umap);
2145 umap = isl_union_map_reverse(umap);
2146 in = isl_union_map_is_single_valued(umap);
2147 isl_union_map_free(umap);
2149 return in;
2152 /* Represents a map that has a fixed value (v) for one of its
2153 * range dimensions.
2154 * The map in this structure is not reference counted, so it
2155 * is only valid while the isl_union_map from which it was
2156 * obtained is still alive.
2158 struct isl_fixed_map {
2159 isl_int v;
2160 isl_map *map;
2163 static struct isl_fixed_map *alloc_isl_fixed_map_array(isl_ctx *ctx,
2164 int n)
2166 int i;
2167 struct isl_fixed_map *v;
2169 v = isl_calloc_array(ctx, struct isl_fixed_map, n);
2170 if (!v)
2171 return NULL;
2172 for (i = 0; i < n; ++i)
2173 isl_int_init(v[i].v);
2174 return v;
2177 static void free_isl_fixed_map_array(struct isl_fixed_map *v, int n)
2179 int i;
2181 if (!v)
2182 return;
2183 for (i = 0; i < n; ++i)
2184 isl_int_clear(v[i].v);
2185 free(v);
2188 /* Compare the "v" field of two isl_fixed_map structs.
2190 static int qsort_fixed_map_cmp(const void *p1, const void *p2)
2192 const struct isl_fixed_map *e1 = (const struct isl_fixed_map *) p1;
2193 const struct isl_fixed_map *e2 = (const struct isl_fixed_map *) p2;
2195 return isl_int_cmp(e1->v, e2->v);
2198 /* Internal data structure used while checking whether all maps
2199 * in a union_map have a fixed value for a given output dimension.
2200 * v is the list of maps, with the fixed value for the dimension
2201 * n is the number of maps considered so far
2202 * pos is the output dimension under investigation
2204 struct isl_fixed_dim_data {
2205 struct isl_fixed_map *v;
2206 int n;
2207 int pos;
2210 static int fixed_at_pos(__isl_keep isl_map *map, void *user)
2212 struct isl_fixed_dim_data *data = user;
2214 data->v[data->n].map = map;
2215 return isl_map_plain_is_fixed(map, isl_dim_out, data->pos,
2216 &data->v[data->n++].v);
2219 static int plain_injective_on_range(__isl_take isl_union_map *umap,
2220 int first, int n_range);
2222 /* Given a list of the maps, with their fixed values at output dimension "pos",
2223 * check whether the ranges of the maps form an obvious partition.
2225 * We first sort the maps according to their fixed values.
2226 * If all maps have a different value, then we know the ranges form
2227 * a partition.
2228 * Otherwise, we collect the maps with the same fixed value and
2229 * check whether each such collection is obviously injective
2230 * based on later dimensions.
2232 static int separates(struct isl_fixed_map *v, int n,
2233 __isl_take isl_space *dim, int pos, int n_range)
2235 int i;
2237 if (!v)
2238 goto error;
2240 qsort(v, n, sizeof(*v), &qsort_fixed_map_cmp);
2242 for (i = 0; i + 1 < n; ++i) {
2243 int j, k;
2244 isl_union_map *part;
2245 int injective;
2247 for (j = i + 1; j < n; ++j)
2248 if (isl_int_ne(v[i].v, v[j].v))
2249 break;
2251 if (j == i + 1)
2252 continue;
2254 part = isl_union_map_alloc(isl_space_copy(dim), j - i);
2255 for (k = i; k < j; ++k)
2256 part = isl_union_map_add_map(part,
2257 isl_map_copy(v[k].map));
2259 injective = plain_injective_on_range(part, pos + 1, n_range);
2260 if (injective < 0)
2261 goto error;
2262 if (!injective)
2263 break;
2265 i = j - 1;
2268 isl_space_free(dim);
2269 free_isl_fixed_map_array(v, n);
2270 return i + 1 >= n;
2271 error:
2272 isl_space_free(dim);
2273 free_isl_fixed_map_array(v, n);
2274 return -1;
2277 /* Check whether the maps in umap have obviously distinct ranges.
2278 * In particular, check for an output dimension in the range
2279 * [first,n_range) for which all maps have a fixed value
2280 * and then check if these values, possibly along with fixed values
2281 * at later dimensions, entail distinct ranges.
2283 static int plain_injective_on_range(__isl_take isl_union_map *umap,
2284 int first, int n_range)
2286 isl_ctx *ctx;
2287 int n;
2288 struct isl_fixed_dim_data data = { NULL };
2290 ctx = isl_union_map_get_ctx(umap);
2292 n = isl_union_map_n_map(umap);
2293 if (!umap)
2294 goto error;
2296 if (n <= 1) {
2297 isl_union_map_free(umap);
2298 return 1;
2301 if (first >= n_range) {
2302 isl_union_map_free(umap);
2303 return 0;
2306 data.v = alloc_isl_fixed_map_array(ctx, n);
2307 if (!data.v)
2308 goto error;
2310 for (data.pos = first; data.pos < n_range; ++data.pos) {
2311 int fixed;
2312 int injective;
2313 isl_space *dim;
2315 data.n = 0;
2316 fixed = union_map_forall_user(umap, &fixed_at_pos, &data);
2317 if (fixed < 0)
2318 goto error;
2319 if (!fixed)
2320 continue;
2321 dim = isl_union_map_get_space(umap);
2322 injective = separates(data.v, n, dim, data.pos, n_range);
2323 isl_union_map_free(umap);
2324 return injective;
2327 free_isl_fixed_map_array(data.v, n);
2328 isl_union_map_free(umap);
2330 return 0;
2331 error:
2332 free_isl_fixed_map_array(data.v, n);
2333 isl_union_map_free(umap);
2334 return -1;
2337 /* Check whether the maps in umap that map to subsets of "ran"
2338 * have obviously distinct ranges.
2340 static int plain_injective_on_range_wrap(__isl_keep isl_set *ran, void *user)
2342 isl_union_map *umap = user;
2344 umap = isl_union_map_copy(umap);
2345 umap = isl_union_map_intersect_range(umap,
2346 isl_union_set_from_set(isl_set_copy(ran)));
2347 return plain_injective_on_range(umap, 0, isl_set_dim(ran, isl_dim_set));
2350 /* Check if the given union_map is obviously injective.
2352 * In particular, we first check if all individual maps are obviously
2353 * injective and then check if all the ranges of these maps are
2354 * obviously disjoint.
2356 int isl_union_map_plain_is_injective(__isl_keep isl_union_map *umap)
2358 int in;
2359 isl_union_map *univ;
2360 isl_union_set *ran;
2362 in = union_map_forall(umap, &isl_map_plain_is_injective);
2363 if (in < 0)
2364 return -1;
2365 if (!in)
2366 return 0;
2368 univ = isl_union_map_universe(isl_union_map_copy(umap));
2369 ran = isl_union_map_range(univ);
2371 in = union_map_forall_user(ran, &plain_injective_on_range_wrap, umap);
2373 isl_union_set_free(ran);
2375 return in;
2378 int isl_union_map_is_bijective(__isl_keep isl_union_map *umap)
2380 int sv;
2382 sv = isl_union_map_is_single_valued(umap);
2383 if (sv < 0 || !sv)
2384 return sv;
2386 return isl_union_map_is_injective(umap);
2389 static int zip_entry(void **entry, void *user)
2391 isl_map *map = *entry;
2392 isl_union_map **res = user;
2394 if (!isl_map_can_zip(map))
2395 return 0;
2397 *res = isl_union_map_add_map(*res, isl_map_zip(isl_map_copy(map)));
2399 return 0;
2402 __isl_give isl_union_map *isl_union_map_zip(__isl_take isl_union_map *umap)
2404 return cond_un_op(umap, &zip_entry);
2407 static int uncurry_entry(void **entry, void *user)
2409 isl_map *map = *entry;
2410 isl_union_map **res = user;
2412 if (!isl_map_can_uncurry(map))
2413 return 0;
2415 *res = isl_union_map_add_map(*res, isl_map_uncurry(isl_map_copy(map)));
2417 return 0;
2420 /* Given a union map, take the maps of the form A -> (B -> C) and
2421 * return the union of the corresponding maps (A -> B) -> C.
2423 __isl_give isl_union_map *isl_union_map_uncurry(__isl_take isl_union_map *umap)
2425 return cond_un_op(umap, &uncurry_entry);
2428 static int curry_entry(void **entry, void *user)
2430 isl_map *map = *entry;
2431 isl_union_map **res = user;
2433 if (!isl_map_can_curry(map))
2434 return 0;
2436 *res = isl_union_map_add_map(*res, isl_map_curry(isl_map_copy(map)));
2438 return 0;
2441 /* Given a union map, take the maps of the form (A -> B) -> C and
2442 * return the union of the corresponding maps A -> (B -> C).
2444 __isl_give isl_union_map *isl_union_map_curry(__isl_take isl_union_map *umap)
2446 return cond_un_op(umap, &curry_entry);
2449 static int lift_entry(void **entry, void *user)
2451 isl_set *set = *entry;
2452 isl_union_set **res = user;
2454 *res = isl_union_set_add_set(*res, isl_set_lift(isl_set_copy(set)));
2456 return 0;
2459 __isl_give isl_union_set *isl_union_set_lift(__isl_take isl_union_set *uset)
2461 return cond_un_op(uset, &lift_entry);
2464 static int coefficients_entry(void **entry, void *user)
2466 isl_set *set = *entry;
2467 isl_union_set **res = user;
2469 set = isl_set_copy(set);
2470 set = isl_set_from_basic_set(isl_set_coefficients(set));
2471 *res = isl_union_set_add_set(*res, set);
2473 return 0;
2476 __isl_give isl_union_set *isl_union_set_coefficients(
2477 __isl_take isl_union_set *uset)
2479 isl_ctx *ctx;
2480 isl_space *dim;
2481 isl_union_set *res;
2483 if (!uset)
2484 return NULL;
2486 ctx = isl_union_set_get_ctx(uset);
2487 dim = isl_space_set_alloc(ctx, 0, 0);
2488 res = isl_union_map_alloc(dim, uset->table.n);
2489 if (isl_hash_table_foreach(uset->dim->ctx, &uset->table,
2490 &coefficients_entry, &res) < 0)
2491 goto error;
2493 isl_union_set_free(uset);
2494 return res;
2495 error:
2496 isl_union_set_free(uset);
2497 isl_union_set_free(res);
2498 return NULL;
2501 static int solutions_entry(void **entry, void *user)
2503 isl_set *set = *entry;
2504 isl_union_set **res = user;
2506 set = isl_set_copy(set);
2507 set = isl_set_from_basic_set(isl_set_solutions(set));
2508 if (!*res)
2509 *res = isl_union_set_from_set(set);
2510 else
2511 *res = isl_union_set_add_set(*res, set);
2513 if (!*res)
2514 return -1;
2516 return 0;
2519 __isl_give isl_union_set *isl_union_set_solutions(
2520 __isl_take isl_union_set *uset)
2522 isl_union_set *res = NULL;
2524 if (!uset)
2525 return NULL;
2527 if (uset->table.n == 0) {
2528 res = isl_union_set_empty(isl_union_set_get_space(uset));
2529 isl_union_set_free(uset);
2530 return res;
2533 if (isl_hash_table_foreach(uset->dim->ctx, &uset->table,
2534 &solutions_entry, &res) < 0)
2535 goto error;
2537 isl_union_set_free(uset);
2538 return res;
2539 error:
2540 isl_union_set_free(uset);
2541 isl_union_set_free(res);
2542 return NULL;
2545 /* Is the domain space of "map" equal to "space"?
2547 static int domain_match(__isl_keep isl_map *map, __isl_keep isl_space *space)
2549 return isl_space_tuple_match(map->dim, isl_dim_in, space, isl_dim_out);
2552 /* Is the range space of "map" equal to "space"?
2554 static int range_match(__isl_keep isl_map *map, __isl_keep isl_space *space)
2556 return isl_space_tuple_match(map->dim, isl_dim_out, space, isl_dim_out);
2559 /* Is the set space of "map" equal to "space"?
2561 static int set_match(__isl_keep isl_map *map, __isl_keep isl_space *space)
2563 return isl_space_tuple_match(map->dim, isl_dim_set, space, isl_dim_out);
2566 /* Internal data structure for preimage_pw_multi_aff.
2568 * "pma" is the function under which the preimage should be taken.
2569 * "space" is the space of "ma".
2570 * "res" collects the results.
2571 * "fn" computes the preimage for a given map.
2572 * "match" returns true if "fn" can be called.
2574 struct isl_union_map_preimage_data {
2575 isl_space *space;
2576 isl_pw_multi_aff *pma;
2577 isl_union_map *res;
2578 int (*match)(__isl_keep isl_map *map, __isl_keep isl_space *space);
2579 __isl_give isl_map *(*fn)(__isl_take isl_map *map,
2580 __isl_take isl_pw_multi_aff *pma);
2583 /* Call data->fn to compute the preimage of the domain or range of *entry
2584 * under the function represented by data->pma, provided the domain/range
2585 * space of *entry matches the target space of data->pma
2586 * (as given by data->match), and add the result to data->res.
2588 static int preimage_entry(void **entry, void *user)
2590 int m;
2591 isl_map *map = *entry;
2592 struct isl_union_map_preimage_data *data = user;
2593 int empty;
2595 m = data->match(map, data->space);
2596 if (m < 0)
2597 return -1;
2598 if (!m)
2599 return 0;
2601 map = isl_map_copy(map);
2602 map = data->fn(map, isl_pw_multi_aff_copy(data->pma));
2604 empty = isl_map_is_empty(map);
2605 if (empty < 0 || empty) {
2606 isl_map_free(map);
2607 return empty < 0 ? -1 : 0;
2610 data->res = isl_union_map_add_map(data->res, map);
2612 return 0;
2615 /* Compute the preimage of the domain or range of "umap" under the function
2616 * represented by "pma".
2617 * In other words, plug in "pma" in the domain or range of "umap".
2618 * The function "fn" performs the actual preimage computation on a map,
2619 * while "match" determines to which maps the function should be applied.
2621 static __isl_give isl_union_map *preimage_pw_multi_aff(
2622 __isl_take isl_union_map *umap, __isl_take isl_pw_multi_aff *pma,
2623 int (*match)(__isl_keep isl_map *map, __isl_keep isl_space *space),
2624 __isl_give isl_map *(*fn)(__isl_take isl_map *map,
2625 __isl_take isl_pw_multi_aff *pma))
2627 isl_ctx *ctx;
2628 isl_space *space;
2629 struct isl_union_map_preimage_data data;
2631 umap = isl_union_map_align_params(umap,
2632 isl_pw_multi_aff_get_space(pma));
2633 pma = isl_pw_multi_aff_align_params(pma, isl_union_map_get_space(umap));
2635 if (!umap || !pma)
2636 goto error;
2638 ctx = isl_union_map_get_ctx(umap);
2639 space = isl_union_map_get_space(umap);
2640 data.space = isl_pw_multi_aff_get_space(pma);
2641 data.pma = pma;
2642 data.res = isl_union_map_alloc(space, umap->table.n);
2643 data.match = match;
2644 data.fn = fn;
2645 if (isl_hash_table_foreach(ctx, &umap->table, &preimage_entry,
2646 &data) < 0)
2647 data.res = isl_union_map_free(data.res);
2649 isl_space_free(data.space);
2650 isl_union_map_free(umap);
2651 isl_pw_multi_aff_free(pma);
2652 return data.res;
2653 error:
2654 isl_union_map_free(umap);
2655 isl_pw_multi_aff_free(pma);
2656 return NULL;
2659 /* Compute the preimage of the domain of "umap" under the function
2660 * represented by "pma".
2661 * In other words, plug in "pma" in the domain of "umap".
2662 * The result contains maps that live in the same spaces as the maps of "umap"
2663 * with domain space equal to the target space of "pma",
2664 * except that the domain has been replaced by the domain space of "pma".
2666 __isl_give isl_union_map *isl_union_map_preimage_domain_pw_multi_aff(
2667 __isl_take isl_union_map *umap, __isl_take isl_pw_multi_aff *pma)
2669 return preimage_pw_multi_aff(umap, pma, &domain_match,
2670 &isl_map_preimage_domain_pw_multi_aff);
2673 /* Compute the preimage of the range of "umap" under the function
2674 * represented by "pma".
2675 * In other words, plug in "pma" in the range of "umap".
2676 * The result contains maps that live in the same spaces as the maps of "umap"
2677 * with range space equal to the target space of "pma",
2678 * except that the range has been replaced by the domain space of "pma".
2680 __isl_give isl_union_map *isl_union_map_preimage_range_pw_multi_aff(
2681 __isl_take isl_union_map *umap, __isl_take isl_pw_multi_aff *pma)
2683 return preimage_pw_multi_aff(umap, pma, &range_match,
2684 &isl_map_preimage_range_pw_multi_aff);
2687 /* Compute the preimage of "uset" under the function represented by "pma".
2688 * In other words, plug in "pma" in "uset".
2689 * The result contains sets that live in the same spaces as the sets of "uset"
2690 * with space equal to the target space of "pma",
2691 * except that the space has been replaced by the domain space of "pma".
2693 __isl_give isl_union_set *isl_union_set_preimage_pw_multi_aff(
2694 __isl_take isl_union_set *uset, __isl_take isl_pw_multi_aff *pma)
2696 return preimage_pw_multi_aff(uset, pma, &set_match,
2697 &isl_set_preimage_pw_multi_aff);
2700 /* Compute the preimage of the domain of "umap" under the function
2701 * represented by "ma".
2702 * In other words, plug in "ma" in the domain of "umap".
2703 * The result contains maps that live in the same spaces as the maps of "umap"
2704 * with domain space equal to the target space of "ma",
2705 * except that the domain has been replaced by the domain space of "ma".
2707 __isl_give isl_union_map *isl_union_map_preimage_domain_multi_aff(
2708 __isl_take isl_union_map *umap, __isl_take isl_multi_aff *ma)
2710 return isl_union_map_preimage_domain_pw_multi_aff(umap,
2711 isl_pw_multi_aff_from_multi_aff(ma));
2714 /* Compute the preimage of the range of "umap" under the function
2715 * represented by "ma".
2716 * In other words, plug in "ma" in the range of "umap".
2717 * The result contains maps that live in the same spaces as the maps of "umap"
2718 * with range space equal to the target space of "ma",
2719 * except that the range has been replaced by the domain space of "ma".
2721 __isl_give isl_union_map *isl_union_map_preimage_range_multi_aff(
2722 __isl_take isl_union_map *umap, __isl_take isl_multi_aff *ma)
2724 return isl_union_map_preimage_range_pw_multi_aff(umap,
2725 isl_pw_multi_aff_from_multi_aff(ma));
2728 /* Compute the preimage of "uset" under the function represented by "ma".
2729 * In other words, plug in "ma" in "uset".
2730 * The result contains sets that live in the same spaces as the sets of "uset"
2731 * with space equal to the target space of "ma",
2732 * except that the space has been replaced by the domain space of "ma".
2734 __isl_give isl_union_map *isl_union_set_preimage_multi_aff(
2735 __isl_take isl_union_set *uset, __isl_take isl_multi_aff *ma)
2737 return isl_union_set_preimage_pw_multi_aff(uset,
2738 isl_pw_multi_aff_from_multi_aff(ma));
2741 /* Internal data structure for preimage_upma.
2743 * "umap" is the map of which the preimage should be computed.
2744 * "res" collects the results.
2745 * "fn" computes the preimage for a given piecewise multi-affine function.
2747 struct isl_union_map_preimage_upma_data {
2748 isl_union_map *umap;
2749 isl_union_map *res;
2750 __isl_give isl_union_map *(*fn)(__isl_take isl_union_map *umap,
2751 __isl_take isl_pw_multi_aff *pma);
2754 /* Call data->fn to compute the preimage of the domain or range of data->umap
2755 * under the function represented by pma and add the result to data->res.
2757 static int preimage_upma(__isl_take isl_pw_multi_aff *pma, void *user)
2759 struct isl_union_map_preimage_upma_data *data = user;
2760 isl_union_map *umap;
2762 umap = isl_union_map_copy(data->umap);
2763 umap = data->fn(umap, pma);
2764 data->res = isl_union_map_union(data->res, umap);
2766 return data->res ? 0 : -1;
2769 /* Compute the preimage of the domain or range of "umap" under the function
2770 * represented by "upma".
2771 * In other words, plug in "upma" in the domain or range of "umap".
2772 * The function "fn" performs the actual preimage computation
2773 * on a piecewise multi-affine function.
2775 static __isl_give isl_union_map *preimage_union_pw_multi_aff(
2776 __isl_take isl_union_map *umap,
2777 __isl_take isl_union_pw_multi_aff *upma,
2778 __isl_give isl_union_map *(*fn)(__isl_take isl_union_map *umap,
2779 __isl_take isl_pw_multi_aff *pma))
2781 struct isl_union_map_preimage_upma_data data;
2783 data.umap = umap;
2784 data.res = isl_union_map_empty(isl_union_map_get_space(umap));
2785 data.fn = fn;
2786 if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
2787 &preimage_upma, &data) < 0)
2788 data.res = isl_union_map_free(data.res);
2790 isl_union_map_free(umap);
2791 isl_union_pw_multi_aff_free(upma);
2793 return data.res;
2796 /* Compute the preimage of the domain of "umap" under the function
2797 * represented by "upma".
2798 * In other words, plug in "upma" in the domain of "umap".
2799 * The result contains maps that live in the same spaces as the maps of "umap"
2800 * with domain space equal to one of the target spaces of "upma",
2801 * except that the domain has been replaced by one of the the domain spaces that
2802 * corresponds to that target space of "upma".
2804 __isl_give isl_union_map *isl_union_map_preimage_domain_union_pw_multi_aff(
2805 __isl_take isl_union_map *umap,
2806 __isl_take isl_union_pw_multi_aff *upma)
2808 return preimage_union_pw_multi_aff(umap, upma,
2809 &isl_union_map_preimage_domain_pw_multi_aff);
2812 /* Compute the preimage of the range of "umap" under the function
2813 * represented by "upma".
2814 * In other words, plug in "upma" in the range of "umap".
2815 * The result contains maps that live in the same spaces as the maps of "umap"
2816 * with range space equal to one of the target spaces of "upma",
2817 * except that the range has been replaced by one of the the domain spaces that
2818 * corresponds to that target space of "upma".
2820 __isl_give isl_union_map *isl_union_map_preimage_range_union_pw_multi_aff(
2821 __isl_take isl_union_map *umap,
2822 __isl_take isl_union_pw_multi_aff *upma)
2824 return preimage_union_pw_multi_aff(umap, upma,
2825 &isl_union_map_preimage_range_pw_multi_aff);
2828 /* Compute the preimage of "uset" under the function represented by "upma".
2829 * In other words, plug in "upma" in the range of "uset".
2830 * The result contains sets that live in the same spaces as the sets of "uset"
2831 * with space equal to one of the target spaces of "upma",
2832 * except that the space has been replaced by one of the the domain spaces that
2833 * corresponds to that target space of "upma".
2835 __isl_give isl_union_set *isl_union_set_preimage_union_pw_multi_aff(
2836 __isl_take isl_union_set *uset,
2837 __isl_take isl_union_pw_multi_aff *upma)
2839 return preimage_union_pw_multi_aff(uset, upma,
2840 &isl_union_set_preimage_pw_multi_aff);
2843 /* Reset the user pointer on all identifiers of parameters and tuples
2844 * of the space of *entry.
2846 static int reset_user(void **entry, void *user)
2848 isl_map **map = (isl_map **)entry;
2850 *map = isl_map_reset_user(*map);
2852 return *map ? 0 : -1;
2855 /* Reset the user pointer on all identifiers of parameters and tuples
2856 * of the spaces of "umap".
2858 __isl_give isl_union_map *isl_union_map_reset_user(
2859 __isl_take isl_union_map *umap)
2861 umap = isl_union_map_cow(umap);
2862 if (!umap)
2863 return NULL;
2864 umap->dim = isl_space_reset_user(umap->dim);
2865 if (!umap->dim)
2866 return isl_union_map_free(umap);
2867 umap = un_op(umap, &reset_user);
2869 return umap;
2872 /* Reset the user pointer on all identifiers of parameters and tuples
2873 * of the spaces of "uset".
2875 __isl_give isl_union_set *isl_union_set_reset_user(
2876 __isl_take isl_union_set *uset)
2878 return isl_union_map_reset_user(uset);