4 #include "isl_map_private.h"
6 static struct isl_map *add_cut_constraint(struct isl_map *dst,
7 struct isl_basic_map *src, isl_int *c,
8 unsigned len, int oppose)
10 struct isl_basic_map *copy = NULL;
15 copy = isl_basic_map_copy(src);
16 copy = isl_basic_map_cow(copy);
19 copy = isl_basic_map_extend_constraints(copy, 0, 1);
20 k = isl_basic_map_alloc_inequality(copy);
24 isl_seq_neg(copy->ineq[k], c, len);
26 isl_seq_cpy(copy->ineq[k], c, len);
27 total = 1 + isl_basic_map_total_dim(copy);
28 isl_seq_clr(copy->ineq[k]+len, total - len);
29 isl_inequality_negate(copy, k);
30 copy = isl_basic_map_simplify(copy);
31 copy = isl_basic_map_finalize(copy);
32 is_empty = isl_basic_map_is_empty(copy);
36 dst = isl_map_add(dst, copy);
38 isl_basic_map_free(copy);
41 isl_basic_map_free(copy);
46 static struct isl_map *subtract(struct isl_map *map, struct isl_basic_map *bmap)
50 struct isl_map *rest = NULL;
52 unsigned total = isl_basic_map_total_dim(bmap);
54 map = isl_map_cow(map);
59 if (ISL_F_ISSET(map, ISL_MAP_DISJOINT))
60 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
62 max = map->n * (2 * bmap->n_eq + bmap->n_ineq);
63 rest = isl_map_alloc_dim(isl_dim_copy(map->dim), max, flags);
67 for (i = 0; i < map->n; ++i) {
68 map->p[i] = isl_basic_map_align_divs(map->p[i], bmap);
73 for (j = 0; j < map->n; ++j)
74 map->p[j] = isl_basic_map_cow(map->p[j]);
76 for (i = 0; i < bmap->n_eq; ++i) {
77 for (j = 0; j < map->n; ++j) {
78 rest = add_cut_constraint(rest,
79 map->p[j], bmap->eq[i], 1+total, 0);
83 rest = add_cut_constraint(rest,
84 map->p[j], bmap->eq[i], 1+total, 1);
88 map->p[j] = isl_basic_map_extend_constraints(map->p[j],
92 k = isl_basic_map_alloc_equality(map->p[j]);
95 isl_seq_cpy(map->p[j]->eq[k], bmap->eq[i], 1+total);
96 isl_seq_clr(map->p[j]->eq[k]+1+total,
97 map->p[j]->n_div - bmap->n_div);
101 for (i = 0; i < bmap->n_ineq; ++i) {
102 for (j = 0; j < map->n; ++j) {
103 rest = add_cut_constraint(rest,
104 map->p[j], bmap->ineq[i], 1+total, 0);
108 map->p[j] = isl_basic_map_extend_constraints(map->p[j],
112 k = isl_basic_map_alloc_inequality(map->p[j]);
115 isl_seq_cpy(map->p[j]->ineq[k], bmap->ineq[i], 1+total);
116 isl_seq_clr(map->p[j]->ineq[k]+1+total,
117 map->p[j]->n_div - bmap->n_div);
129 struct isl_map *isl_map_subtract(struct isl_map *map1, struct isl_map *map2)
135 isl_assert(map1->ctx, isl_dim_equal(map1->dim, map2->dim), goto error);
137 if (isl_map_is_empty(map2)) {
142 map1 = isl_map_compute_divs(map1);
143 map2 = isl_map_compute_divs(map2);
147 map1 = isl_map_remove_empty_parts(map1);
148 map2 = isl_map_remove_empty_parts(map2);
150 for (i = 0; map1 && i < map2->n; ++i)
151 map1 = subtract(map1, map2->p[i]);
161 struct isl_set *isl_set_subtract(struct isl_set *set1, struct isl_set *set2)
163 return (struct isl_set *)
165 (struct isl_map *)set1, (struct isl_map *)set2);
168 /* Return 1 if "bmap" contains a single element.
170 int isl_basic_map_is_singleton(__isl_keep isl_basic_map *bmap)
178 return bmap->n_eq == isl_basic_map_total_dim(bmap);
181 /* Return 1 if "map" contains a single element.
183 int isl_map_is_singleton(__isl_keep isl_map *map)
190 return isl_basic_map_is_singleton(map->p[0]);
193 /* Given a singleton basic map, extract the single element
196 static __isl_give isl_vec *singleton_extract_point(__isl_keep isl_basic_map *bmap)
200 struct isl_vec *point;
206 dim = isl_basic_map_total_dim(bmap);
207 isl_assert(bmap->ctx, bmap->n_eq == dim, return NULL);
208 point = isl_vec_alloc(bmap->ctx, 1 + dim);
214 isl_int_set_si(point->el[0], 1);
215 for (j = 0; j < bmap->n_eq; ++j) {
218 isl_assert(bmap->ctx,
219 isl_seq_first_non_zero(bmap->eq[j] + 1, i) == -1,
221 isl_assert(bmap->ctx,
222 isl_int_is_one(bmap->eq[j][1 + i]) ||
223 isl_int_is_negone(bmap->eq[j][1 + i]),
225 isl_assert(bmap->ctx,
226 isl_seq_first_non_zero(bmap->eq[j]+1+i+1, dim-i-1) == -1,
229 isl_int_gcd(m, point->el[0], bmap->eq[j][1 + i]);
230 isl_int_divexact(m, bmap->eq[j][1 + i], m);
232 isl_seq_scale(point->el, point->el, m, 1 + i);
233 isl_int_divexact(m, point->el[0], bmap->eq[j][1 + i]);
235 isl_int_mul(point->el[1 + i], m, bmap->eq[j][0]);
246 /* Return 1 if "bmap" contains the point "point".
247 * "bmap" is assumed to have known divs.
248 * The point is first extended with the divs and then passed
249 * to basic_map_contains.
251 static int basic_map_contains_point(__isl_keep isl_basic_map *bmap,
252 __isl_keep isl_vec *point)
261 if (bmap->n_div == 0)
262 return isl_basic_map_contains(bmap, point);
264 dim = isl_basic_map_total_dim(bmap) - bmap->n_div;
265 vec = isl_vec_alloc(bmap->ctx, 1 + dim + bmap->n_div);
269 isl_seq_cpy(vec->el, point->el, point->size);
270 for (i = 0; i < bmap->n_div; ++i) {
271 isl_seq_inner_product(bmap->div[i] + 1, vec->el,
272 1 + dim + i, &vec->el[1+dim+i]);
273 isl_int_fdiv_q(vec->el[1+dim+i], vec->el[1+dim+i],
277 contains = isl_basic_map_contains(bmap, vec);
283 /* Return 1 is the singleton map "map1" is a subset of "map2",
284 * i.e., if the single element of "map1" is also an element of "map2".
286 static int map_is_singleton_subset(__isl_keep isl_map *map1,
287 __isl_keep isl_map *map2)
291 struct isl_vec *point;
298 point = singleton_extract_point(map1->p[0]);
302 for (i = 0; i < map2->n; ++i) {
303 is_subset = basic_map_contains_point(map2->p[i], point);
312 int isl_map_is_subset(struct isl_map *map1, struct isl_map *map2)
315 struct isl_map *diff;
320 if (isl_map_is_empty(map1))
323 if (isl_map_is_empty(map2))
326 if (isl_map_fast_is_universe(map2))
329 map2 = isl_map_compute_divs(isl_map_copy(map2));
330 if (isl_map_is_singleton(map1)) {
331 is_subset = map_is_singleton_subset(map1, map2);
335 diff = isl_map_subtract(isl_map_copy(map1), map2);
339 is_subset = isl_map_is_empty(diff);
345 int isl_set_is_subset(struct isl_set *set1, struct isl_set *set2)
347 return isl_map_is_subset(
348 (struct isl_map *)set1, (struct isl_map *)set2);