2 * Copyright 2008-2009 Katholieke Universiteit Leuven
3 * Copyright 2010 INRIA Saclay
4 * Copyright 2012-2014 Ecole Normale Superieure
5 * Copyright 2014 INRIA Rocquencourt
6 * Copyright 2016 INRIA Paris
7 * Copyright 2016 Sven Verdoolaege
8 * Copyright 2018-2019 Cerebras Systems
9 * Copyright 2021-2022 Cerebras Systems
11 * Use of this software is governed by the MIT license
13 * Written by Sven Verdoolaege, K.U.Leuven, Departement
14 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
15 * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
16 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
17 * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
18 * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
19 * B.P. 105 - 78153 Le Chesnay, France
20 * and Centre de Recherche Inria de Paris, 2 rue Simone Iff - Voie DQ12,
21 * CS 42112, 75589 Paris Cedex 12, France
22 * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA
23 * and Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA
27 #include <isl_ctx_private.h>
28 #include <isl_map_private.h>
30 #include <isl_id_private.h>
31 #include <isl/constraint.h>
32 #include "isl_space_private.h"
33 #include "isl_equalities.h"
34 #include <isl_lp_private.h>
38 #include <isl_reordering.h>
39 #include "isl_sample.h"
43 #include <isl_mat_private.h>
44 #include <isl_vec_private.h>
45 #include <isl_dim_map.h>
46 #include <isl_local_space_private.h>
47 #include <isl_aff_private.h>
48 #include <isl_options_private.h>
49 #include <isl_morph.h>
50 #include <isl_val_private.h>
51 #include <isl_printer_private.h>
53 #include <bset_to_bmap.c>
54 #include <bset_from_bmap.c>
55 #include <set_to_map.c>
56 #include <set_from_map.c>
58 /* Treat "bset" as a basic map.
59 * Internally, isl_basic_set is defined to isl_basic_map, so in practice,
60 * this function performs a redundant cast.
62 static __isl_keep
const isl_basic_map
*const_bset_to_bmap(
63 __isl_keep
const isl_basic_set
*bset
)
65 return (const isl_basic_map
*) bset
;
69 #define TYPE isl_basic_map
70 #include "has_single_reference_templ.c"
72 static unsigned pos(__isl_keep isl_space
*space
, enum isl_dim_type type
)
75 case isl_dim_param
: return 1;
76 case isl_dim_in
: return 1 + space
->nparam
;
77 case isl_dim_out
: return 1 + space
->nparam
+ space
->n_in
;
82 isl_size
isl_basic_map_dim(__isl_keep isl_basic_map
*bmap
,
83 enum isl_dim_type type
)
86 return isl_size_error
;
88 case isl_dim_cst
: return 1;
91 case isl_dim_out
: return isl_space_dim(bmap
->dim
, type
);
92 case isl_dim_div
: return bmap
->n_div
;
93 case isl_dim_all
: return isl_basic_map_total_dim(bmap
);
98 /* Return the space of "map".
100 __isl_keep isl_space
*isl_map_peek_space(__isl_keep
const isl_map
*map
)
102 return map
? map
->dim
: NULL
;
105 /* Return the space of "set".
107 __isl_keep isl_space
*isl_set_peek_space(__isl_keep isl_set
*set
)
109 return isl_map_peek_space(set_to_map(set
));
112 isl_size
isl_map_dim(__isl_keep isl_map
*map
, enum isl_dim_type type
)
114 return isl_space_dim(isl_map_peek_space(map
), type
);
117 /* Return the dimensionality of the domain (tuple) of the map.
119 isl_size
isl_map_domain_tuple_dim(__isl_keep isl_map
*map
)
121 return isl_map_dim(map
, isl_dim_in
);
124 /* Return the dimensionality of the range (tuple) of the map.
126 isl_size
isl_map_range_tuple_dim(__isl_keep isl_map
*map
)
128 return isl_map_dim(map
, isl_dim_out
);
131 isl_size
isl_set_dim(__isl_keep isl_set
*set
, enum isl_dim_type type
)
133 return isl_map_dim(set_to_map(set
), type
);
136 /* Return the dimensionality of the (tuple of the) set.
138 isl_size
isl_set_tuple_dim(__isl_keep isl_set
*set
)
140 return isl_set_dim(set
, isl_dim_set
);
143 /* Return the position of the variables of the given type
144 * within the sequence of variables of "bmap".
146 isl_size
isl_basic_map_var_offset(__isl_keep isl_basic_map
*bmap
,
147 enum isl_dim_type type
)
151 space
= isl_basic_map_peek_space(bmap
);
156 case isl_dim_out
: return isl_space_offset(space
, type
);
157 case isl_dim_div
: return isl_space_dim(space
, isl_dim_all
);
160 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
161 "invalid dimension type", return isl_size_error
);
165 /* Return the position of the variables of the given type
166 * within the sequence of variables of "bset".
168 isl_size
isl_basic_set_var_offset(__isl_keep isl_basic_set
*bset
,
169 enum isl_dim_type type
)
171 return isl_basic_map_var_offset(bset_to_bmap(bset
), type
);
174 /* Return the position of the coefficients of the variables of the given type
175 * within the sequence of coefficients of "bmap".
177 unsigned isl_basic_map_offset(__isl_keep isl_basic_map
*bmap
,
178 enum isl_dim_type type
)
181 case isl_dim_cst
: return 0;
185 case isl_dim_div
: return 1 + isl_basic_map_var_offset(bmap
, type
);
190 unsigned isl_basic_set_offset(__isl_keep isl_basic_set
*bset
,
191 enum isl_dim_type type
)
193 return isl_basic_map_offset(bset
, type
);
196 static unsigned map_offset(__isl_keep isl_map
*map
, enum isl_dim_type type
)
198 return pos(map
->dim
, type
);
201 isl_size
isl_basic_set_dim(__isl_keep isl_basic_set
*bset
,
202 enum isl_dim_type type
)
204 return isl_basic_map_dim(bset
, type
);
207 isl_size
isl_basic_set_n_dim(__isl_keep isl_basic_set
*bset
)
209 return isl_basic_set_dim(bset
, isl_dim_set
);
212 isl_size
isl_basic_set_n_param(__isl_keep isl_basic_set
*bset
)
214 return isl_basic_set_dim(bset
, isl_dim_param
);
217 isl_size
isl_basic_set_total_dim(__isl_keep
const isl_basic_set
*bset
)
219 return isl_basic_map_total_dim(const_bset_to_bmap(bset
));
222 isl_size
isl_set_n_dim(__isl_keep isl_set
*set
)
224 return isl_set_dim(set
, isl_dim_set
);
227 isl_size
isl_set_n_param(__isl_keep isl_set
*set
)
229 return isl_set_dim(set
, isl_dim_param
);
232 isl_size
isl_basic_map_total_dim(__isl_keep
const isl_basic_map
*bmap
)
237 return isl_size_error
;
238 dim
= isl_space_dim(bmap
->dim
, isl_dim_all
);
240 return isl_size_error
;
241 return dim
+ bmap
->n_div
;
244 /* Return the number of equality constraints in the description of "bmap".
245 * Return isl_size_error on error.
247 isl_size
isl_basic_map_n_equality(__isl_keep isl_basic_map
*bmap
)
250 return isl_size_error
;
254 /* Return the number of equality constraints in the description of "bset".
255 * Return isl_size_error on error.
257 isl_size
isl_basic_set_n_equality(__isl_keep isl_basic_set
*bset
)
259 return isl_basic_map_n_equality(bset_to_bmap(bset
));
262 /* Return the number of inequality constraints in the description of "bmap".
263 * Return isl_size_error on error.
265 isl_size
isl_basic_map_n_inequality(__isl_keep isl_basic_map
*bmap
)
268 return isl_size_error
;
272 /* Return the number of inequality constraints in the description of "bset".
273 * Return isl_size_error on error.
275 isl_size
isl_basic_set_n_inequality(__isl_keep isl_basic_set
*bset
)
277 return isl_basic_map_n_inequality(bset_to_bmap(bset
));
280 /* Do "bmap1" and "bmap2" have the same parameters?
282 static isl_bool
isl_basic_map_has_equal_params(__isl_keep isl_basic_map
*bmap1
,
283 __isl_keep isl_basic_map
*bmap2
)
285 isl_space
*space1
, *space2
;
287 space1
= isl_basic_map_peek_space(bmap1
);
288 space2
= isl_basic_map_peek_space(bmap2
);
289 return isl_space_has_equal_params(space1
, space2
);
292 /* Do "map1" and "map2" have the same parameters?
294 isl_bool
isl_map_has_equal_params(__isl_keep isl_map
*map1
,
295 __isl_keep isl_map
*map2
)
297 isl_space
*space1
, *space2
;
299 space1
= isl_map_peek_space(map1
);
300 space2
= isl_map_peek_space(map2
);
301 return isl_space_has_equal_params(space1
, space2
);
304 /* Do "map" and "set" have the same parameters?
306 static isl_bool
isl_map_set_has_equal_params(__isl_keep isl_map
*map
,
307 __isl_keep isl_set
*set
)
309 return isl_map_has_equal_params(map
, set_to_map(set
));
312 /* Is the tuple of type "type" of "bmap" the same as the single tuple of "bset"?
314 static isl_bool
isl_basic_map_set_tuple_is_equal(__isl_keep isl_basic_map
*bmap
,
315 enum isl_dim_type type
, __isl_keep isl_basic_set
*bset
)
317 isl_space
*bmap_space
, *bset_space
;
319 bmap_space
= isl_basic_map_peek_space(bmap
);
320 bset_space
= isl_basic_set_peek_space(bset
);
321 return isl_space_tuple_is_equal(bmap_space
, type
,
322 bset_space
, isl_dim_set
);
325 /* Is the tuple of type "type" of "map" the same as the single tuple of "set"?
327 static isl_bool
isl_map_set_tuple_is_equal(__isl_keep isl_map
*map
,
328 enum isl_dim_type type
, __isl_keep isl_set
*set
)
330 return isl_map_tuple_is_equal(map
, type
, set_to_map(set
), isl_dim_set
);
333 isl_bool
isl_map_compatible_domain(__isl_keep isl_map
*map
,
334 __isl_keep isl_set
*set
)
338 return isl_bool_error
;
339 m
= isl_map_has_equal_params(map
, set_to_map(set
));
342 return isl_map_set_tuple_is_equal(map
, isl_dim_in
, set
);
345 isl_bool
isl_basic_map_compatible_domain(__isl_keep isl_basic_map
*bmap
,
346 __isl_keep isl_basic_set
*bset
)
350 return isl_bool_error
;
351 m
= isl_basic_map_has_equal_params(bmap
, bset_to_bmap(bset
));
354 return isl_basic_map_set_tuple_is_equal(bmap
, isl_dim_in
, bset
);
357 isl_bool
isl_map_compatible_range(__isl_keep isl_map
*map
,
358 __isl_keep isl_set
*set
)
362 return isl_bool_error
;
363 m
= isl_map_has_equal_params(map
, set_to_map(set
));
366 return isl_map_set_tuple_is_equal(map
, isl_dim_out
, set
);
369 isl_bool
isl_basic_map_compatible_range(__isl_keep isl_basic_map
*bmap
,
370 __isl_keep isl_basic_set
*bset
)
374 return isl_bool_error
;
375 m
= isl_basic_map_has_equal_params(bmap
, bset_to_bmap(bset
));
378 return isl_basic_map_set_tuple_is_equal(bmap
, isl_dim_out
, bset
);
381 isl_ctx
*isl_basic_map_get_ctx(__isl_keep isl_basic_map
*bmap
)
383 return bmap
? bmap
->ctx
: NULL
;
386 isl_ctx
*isl_basic_set_get_ctx(__isl_keep isl_basic_set
*bset
)
388 return bset
? bset
->ctx
: NULL
;
391 isl_ctx
*isl_map_get_ctx(__isl_keep isl_map
*map
)
393 return map
? map
->ctx
: NULL
;
396 isl_ctx
*isl_set_get_ctx(__isl_keep isl_set
*set
)
398 return set
? set
->ctx
: NULL
;
401 /* Return the space of "bmap".
403 __isl_keep isl_space
*isl_basic_map_peek_space(
404 __isl_keep
const isl_basic_map
*bmap
)
406 return bmap
? bmap
->dim
: NULL
;
409 /* Return the space of "bset".
411 __isl_keep isl_space
*isl_basic_set_peek_space(__isl_keep isl_basic_set
*bset
)
413 return isl_basic_map_peek_space(bset_to_bmap(bset
));
416 __isl_give isl_space
*isl_basic_map_get_space(__isl_keep isl_basic_map
*bmap
)
418 return isl_space_copy(isl_basic_map_peek_space(bmap
));
421 __isl_give isl_space
*isl_basic_set_get_space(__isl_keep isl_basic_set
*bset
)
423 return isl_basic_map_get_space(bset_to_bmap(bset
));
426 /* Return the space of "bmap".
427 * This may be either a copy or the space itself
428 * if there is only one reference to "bmap".
429 * This allows the space to be modified inplace
430 * if both the basic map and its space have only a single reference.
431 * The caller is not allowed to modify "bmap" between this call and
432 * a subsequent call to isl_basic_map_restore_space.
433 * The only exception is that isl_basic_map_free can be called instead.
435 static __isl_give isl_space
*isl_basic_map_take_space(
436 __isl_keep isl_basic_map
*bmap
)
443 return isl_basic_map_get_space(bmap
);
449 /* Set the space of "bmap" to "space", where the space of "bmap" may be missing
450 * due to a preceding call to isl_basic_map_take_space.
451 * However, in this case, "bmap" only has a single reference and
452 * then the call to isl_basic_map_cow has no effect.
454 static __isl_give isl_basic_map
*isl_basic_map_restore_space(
455 __isl_take isl_basic_map
*bmap
, __isl_take isl_space
*space
)
460 if (bmap
->dim
== space
) {
461 isl_space_free(space
);
465 bmap
= isl_basic_map_cow(bmap
);
468 isl_space_free(bmap
->dim
);
473 isl_basic_map_free(bmap
);
474 isl_space_free(space
);
478 /* Extract the divs in "bmap" as a matrix.
480 __isl_give isl_mat
*isl_basic_map_get_divs(__isl_keep isl_basic_map
*bmap
)
488 v_div
= isl_basic_map_var_offset(bmap
, isl_dim_div
);
492 ctx
= isl_basic_map_get_ctx(bmap
);
493 cols
= 1 + 1 + v_div
+ bmap
->n_div
;
494 div
= isl_mat_alloc(ctx
, bmap
->n_div
, cols
);
498 for (i
= 0; i
< bmap
->n_div
; ++i
)
499 isl_seq_cpy(div
->row
[i
], bmap
->div
[i
], cols
);
504 /* Extract the divs in "bset" as a matrix.
506 __isl_give isl_mat
*isl_basic_set_get_divs(__isl_keep isl_basic_set
*bset
)
508 return isl_basic_map_get_divs(bset
);
511 __isl_give isl_local_space
*isl_basic_map_get_local_space(
512 __isl_keep isl_basic_map
*bmap
)
519 div
= isl_basic_map_get_divs(bmap
);
520 return isl_local_space_alloc_div(isl_space_copy(bmap
->dim
), div
);
523 __isl_give isl_local_space
*isl_basic_set_get_local_space(
524 __isl_keep isl_basic_set
*bset
)
526 return isl_basic_map_get_local_space(bset
);
529 /* For each known div d = floor(f/m), add the constraints
532 * -(f-(m-1)) + m d >= 0
534 * Do not finalize the result.
536 static __isl_give isl_basic_map
*add_known_div_constraints(
537 __isl_take isl_basic_map
*bmap
)
542 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
544 return isl_basic_map_free(bmap
);
547 bmap
= isl_basic_map_cow(bmap
);
548 bmap
= isl_basic_map_extend_constraints(bmap
, 0, 2 * n_div
);
551 for (i
= 0; i
< n_div
; ++i
) {
552 if (isl_int_is_zero(bmap
->div
[i
][0]))
554 bmap
= isl_basic_map_add_div_constraints(bmap
, i
);
560 __isl_give isl_basic_map
*isl_basic_map_from_local_space(
561 __isl_take isl_local_space
*ls
)
567 n_div
= isl_local_space_dim(ls
, isl_dim_div
);
569 ls
= isl_local_space_free(ls
);
573 bmap
= isl_basic_map_alloc_space(isl_local_space_get_space(ls
),
574 n_div
, 0, 2 * n_div
);
576 for (i
= 0; i
< n_div
; ++i
)
577 if (isl_basic_map_alloc_div(bmap
) < 0)
580 for (i
= 0; i
< n_div
; ++i
)
581 isl_seq_cpy(bmap
->div
[i
], ls
->div
->row
[i
], ls
->div
->n_col
);
582 bmap
= add_known_div_constraints(bmap
);
584 isl_local_space_free(ls
);
587 isl_local_space_free(ls
);
588 isl_basic_map_free(bmap
);
592 __isl_give isl_basic_set
*isl_basic_set_from_local_space(
593 __isl_take isl_local_space
*ls
)
595 return isl_basic_map_from_local_space(ls
);
598 __isl_give isl_space
*isl_map_get_space(__isl_keep isl_map
*map
)
600 return isl_space_copy(isl_map_peek_space(map
));
603 __isl_give isl_space
*isl_set_get_space(__isl_keep isl_set
*set
)
607 return isl_space_copy(set
->dim
);
610 /* Return the space of "map".
611 * This may be either a copy or the space itself
612 * if there is only one reference to "map".
613 * This allows the space to be modified inplace
614 * if both the map and its space have only a single reference.
615 * The caller is not allowed to modify "map" between this call and
616 * a subsequent call to isl_map_restore_space.
617 * The only exception is that isl_map_free can be called instead.
619 static __isl_give isl_space
*isl_map_take_space(__isl_keep isl_map
*map
)
626 return isl_map_get_space(map
);
632 /* Set the space of "map" to "space", where the space of "map" may be missing
633 * due to a preceding call to isl_map_take_space.
634 * However, in this case, "map" only has a single reference and
635 * then the call to isl_map_cow has no effect.
637 static __isl_give isl_map
*isl_map_restore_space(__isl_take isl_map
*map
,
638 __isl_take isl_space
*space
)
643 if (map
->dim
== space
) {
644 isl_space_free(space
);
648 map
= isl_map_cow(map
);
651 isl_space_free(map
->dim
);
657 isl_space_free(space
);
661 __isl_give isl_basic_map
*isl_basic_map_set_tuple_name(
662 __isl_take isl_basic_map
*bmap
, enum isl_dim_type type
, const char *s
)
666 space
= isl_basic_map_take_space(bmap
);
667 space
= isl_space_set_tuple_name(space
, type
, s
);
668 bmap
= isl_basic_map_restore_space(bmap
, space
);
669 bmap
= isl_basic_map_finalize(bmap
);
673 __isl_give isl_basic_set
*isl_basic_set_set_tuple_name(
674 __isl_take isl_basic_set
*bset
, const char *s
)
676 return isl_basic_map_set_tuple_name(bset
, isl_dim_set
, s
);
679 const char *isl_basic_map_get_tuple_name(__isl_keep isl_basic_map
*bmap
,
680 enum isl_dim_type type
)
682 return bmap
? isl_space_get_tuple_name(bmap
->dim
, type
) : NULL
;
685 __isl_give isl_map
*isl_map_set_tuple_name(__isl_take isl_map
*map
,
686 enum isl_dim_type type
, const char *s
)
691 map
= isl_map_cow(map
);
695 for (i
= 0; i
< map
->n
; ++i
) {
696 map
->p
[i
] = isl_basic_map_set_tuple_name(map
->p
[i
], type
, s
);
701 space
= isl_map_take_space(map
);
702 space
= isl_space_set_tuple_name(space
, type
, s
);
703 map
= isl_map_restore_space(map
, space
);
711 /* Replace the identifier of the tuple of type "type" by "id".
713 __isl_give isl_basic_map
*isl_basic_map_set_tuple_id(
714 __isl_take isl_basic_map
*bmap
,
715 enum isl_dim_type type
, __isl_take isl_id
*id
)
719 space
= isl_basic_map_take_space(bmap
);
720 space
= isl_space_set_tuple_id(space
, type
, id
);
721 bmap
= isl_basic_map_restore_space(bmap
, space
);
722 bmap
= isl_basic_map_finalize(bmap
);
726 /* Replace the identifier of the tuple by "id".
728 __isl_give isl_basic_set
*isl_basic_set_set_tuple_id(
729 __isl_take isl_basic_set
*bset
, __isl_take isl_id
*id
)
731 return isl_basic_map_set_tuple_id(bset
, isl_dim_set
, id
);
734 /* Does the input or output tuple have a name?
736 isl_bool
isl_map_has_tuple_name(__isl_keep isl_map
*map
, enum isl_dim_type type
)
738 return map
? isl_space_has_tuple_name(map
->dim
, type
) : isl_bool_error
;
741 const char *isl_map_get_tuple_name(__isl_keep isl_map
*map
,
742 enum isl_dim_type type
)
744 return map
? isl_space_get_tuple_name(map
->dim
, type
) : NULL
;
747 __isl_give isl_set
*isl_set_set_tuple_name(__isl_take isl_set
*set
,
750 return set_from_map(isl_map_set_tuple_name(set_to_map(set
),
754 __isl_give isl_map
*isl_map_set_tuple_id(__isl_take isl_map
*map
,
755 enum isl_dim_type type
, __isl_take isl_id
*id
)
759 space
= isl_map_take_space(map
);
760 space
= isl_space_set_tuple_id(space
, type
, id
);
761 map
= isl_map_restore_space(map
, space
);
763 return isl_map_reset_space(map
, isl_map_get_space(map
));
766 /* Replace the identifier of the domain tuple of "map" by "id".
768 __isl_give isl_map
*isl_map_set_domain_tuple_id(__isl_take isl_map
*map
,
769 __isl_take isl_id
*id
)
771 return isl_map_set_tuple_id(map
, isl_dim_in
, id
);
774 /* Replace the identifier of the range tuple of "map" by "id".
776 __isl_give isl_map
*isl_map_set_range_tuple_id(__isl_take isl_map
*map
,
777 __isl_take isl_id
*id
)
779 return isl_map_set_tuple_id(map
, isl_dim_out
, id
);
782 __isl_give isl_set
*isl_set_set_tuple_id(__isl_take isl_set
*set
,
783 __isl_take isl_id
*id
)
785 return isl_map_set_tuple_id(set
, isl_dim_set
, id
);
788 __isl_give isl_map
*isl_map_reset_tuple_id(__isl_take isl_map
*map
,
789 enum isl_dim_type type
)
793 space
= isl_map_take_space(map
);
794 space
= isl_space_reset_tuple_id(space
, type
);
795 map
= isl_map_restore_space(map
, space
);
797 return isl_map_reset_space(map
, isl_map_get_space(map
));
800 __isl_give isl_set
*isl_set_reset_tuple_id(__isl_take isl_set
*set
)
802 return isl_map_reset_tuple_id(set
, isl_dim_set
);
805 isl_bool
isl_map_has_tuple_id(__isl_keep isl_map
*map
, enum isl_dim_type type
)
807 return map
? isl_space_has_tuple_id(map
->dim
, type
) : isl_bool_error
;
810 /* Does the domain tuple of "map" have an identifier?
812 isl_bool
isl_map_has_domain_tuple_id(__isl_keep isl_map
*map
)
814 return isl_map_has_tuple_id(map
, isl_dim_in
);
817 /* Does the range tuple of "map" have an identifier?
819 isl_bool
isl_map_has_range_tuple_id(__isl_keep isl_map
*map
)
821 return isl_map_has_tuple_id(map
, isl_dim_out
);
824 __isl_give isl_id
*isl_map_get_tuple_id(__isl_keep isl_map
*map
,
825 enum isl_dim_type type
)
827 return map
? isl_space_get_tuple_id(map
->dim
, type
) : NULL
;
830 /* Return the identifier of the domain tuple of "map", assuming it has one.
832 __isl_give isl_id
*isl_map_get_domain_tuple_id(__isl_keep isl_map
*map
)
834 return isl_map_get_tuple_id(map
, isl_dim_in
);
837 /* Return the identifier of the range tuple of "map", assuming it has one.
839 __isl_give isl_id
*isl_map_get_range_tuple_id(__isl_keep isl_map
*map
)
841 return isl_map_get_tuple_id(map
, isl_dim_out
);
844 isl_bool
isl_set_has_tuple_id(__isl_keep isl_set
*set
)
846 return isl_map_has_tuple_id(set
, isl_dim_set
);
849 __isl_give isl_id
*isl_set_get_tuple_id(__isl_keep isl_set
*set
)
851 return isl_map_get_tuple_id(set
, isl_dim_set
);
854 /* Does the set tuple have a name?
856 isl_bool
isl_set_has_tuple_name(__isl_keep isl_set
*set
)
859 return isl_bool_error
;
860 return isl_space_has_tuple_name(set
->dim
, isl_dim_set
);
864 const char *isl_basic_set_get_tuple_name(__isl_keep isl_basic_set
*bset
)
866 return bset
? isl_space_get_tuple_name(bset
->dim
, isl_dim_set
) : NULL
;
869 const char *isl_set_get_tuple_name(__isl_keep isl_set
*set
)
871 return set
? isl_space_get_tuple_name(set
->dim
, isl_dim_set
) : NULL
;
874 const char *isl_basic_map_get_dim_name(__isl_keep isl_basic_map
*bmap
,
875 enum isl_dim_type type
, unsigned pos
)
877 return bmap
? isl_space_get_dim_name(bmap
->dim
, type
, pos
) : NULL
;
880 const char *isl_basic_set_get_dim_name(__isl_keep isl_basic_set
*bset
,
881 enum isl_dim_type type
, unsigned pos
)
883 return bset
? isl_space_get_dim_name(bset
->dim
, type
, pos
) : NULL
;
886 /* Does the given dimension have a name?
888 isl_bool
isl_map_has_dim_name(__isl_keep isl_map
*map
,
889 enum isl_dim_type type
, unsigned pos
)
892 return isl_bool_error
;
893 return isl_space_has_dim_name(map
->dim
, type
, pos
);
896 const char *isl_map_get_dim_name(__isl_keep isl_map
*map
,
897 enum isl_dim_type type
, unsigned pos
)
899 return map
? isl_space_get_dim_name(map
->dim
, type
, pos
) : NULL
;
902 const char *isl_set_get_dim_name(__isl_keep isl_set
*set
,
903 enum isl_dim_type type
, unsigned pos
)
905 return set
? isl_space_get_dim_name(set
->dim
, type
, pos
) : NULL
;
908 /* Does the given dimension have a name?
910 isl_bool
isl_set_has_dim_name(__isl_keep isl_set
*set
,
911 enum isl_dim_type type
, unsigned pos
)
914 return isl_bool_error
;
915 return isl_space_has_dim_name(set
->dim
, type
, pos
);
918 __isl_give isl_basic_map
*isl_basic_map_set_dim_name(
919 __isl_take isl_basic_map
*bmap
,
920 enum isl_dim_type type
, unsigned pos
, const char *s
)
924 space
= isl_basic_map_take_space(bmap
);
925 space
= isl_space_set_dim_name(space
, type
, pos
, s
);
926 bmap
= isl_basic_map_restore_space(bmap
, space
);
927 return isl_basic_map_finalize(bmap
);
930 __isl_give isl_map
*isl_map_set_dim_name(__isl_take isl_map
*map
,
931 enum isl_dim_type type
, unsigned pos
, const char *s
)
936 map
= isl_map_cow(map
);
940 for (i
= 0; i
< map
->n
; ++i
) {
941 map
->p
[i
] = isl_basic_map_set_dim_name(map
->p
[i
], type
, pos
, s
);
946 space
= isl_map_take_space(map
);
947 space
= isl_space_set_dim_name(space
, type
, pos
, s
);
948 map
= isl_map_restore_space(map
, space
);
956 __isl_give isl_basic_set
*isl_basic_set_set_dim_name(
957 __isl_take isl_basic_set
*bset
,
958 enum isl_dim_type type
, unsigned pos
, const char *s
)
960 return bset_from_bmap(isl_basic_map_set_dim_name(bset_to_bmap(bset
),
964 __isl_give isl_set
*isl_set_set_dim_name(__isl_take isl_set
*set
,
965 enum isl_dim_type type
, unsigned pos
, const char *s
)
967 return set_from_map(isl_map_set_dim_name(set_to_map(set
),
971 isl_bool
isl_basic_map_has_dim_id(__isl_keep isl_basic_map
*bmap
,
972 enum isl_dim_type type
, unsigned pos
)
975 return isl_bool_error
;
976 return isl_space_has_dim_id(bmap
->dim
, type
, pos
);
979 __isl_give isl_id
*isl_basic_set_get_dim_id(__isl_keep isl_basic_set
*bset
,
980 enum isl_dim_type type
, unsigned pos
)
982 return bset
? isl_space_get_dim_id(bset
->dim
, type
, pos
) : NULL
;
985 isl_bool
isl_map_has_dim_id(__isl_keep isl_map
*map
,
986 enum isl_dim_type type
, unsigned pos
)
988 return map
? isl_space_has_dim_id(map
->dim
, type
, pos
) : isl_bool_error
;
991 __isl_give isl_id
*isl_map_get_dim_id(__isl_keep isl_map
*map
,
992 enum isl_dim_type type
, unsigned pos
)
994 return map
? isl_space_get_dim_id(map
->dim
, type
, pos
) : NULL
;
997 isl_bool
isl_set_has_dim_id(__isl_keep isl_set
*set
,
998 enum isl_dim_type type
, unsigned pos
)
1000 return isl_map_has_dim_id(set
, type
, pos
);
1003 __isl_give isl_id
*isl_set_get_dim_id(__isl_keep isl_set
*set
,
1004 enum isl_dim_type type
, unsigned pos
)
1006 return isl_map_get_dim_id(set
, type
, pos
);
1009 __isl_give isl_map
*isl_map_set_dim_id(__isl_take isl_map
*map
,
1010 enum isl_dim_type type
, unsigned pos
, __isl_take isl_id
*id
)
1014 space
= isl_map_take_space(map
);
1015 space
= isl_space_set_dim_id(space
, type
, pos
, id
);
1016 map
= isl_map_restore_space(map
, space
);
1018 return isl_map_reset_space(map
, isl_map_get_space(map
));
1021 __isl_give isl_set
*isl_set_set_dim_id(__isl_take isl_set
*set
,
1022 enum isl_dim_type type
, unsigned pos
, __isl_take isl_id
*id
)
1024 return isl_map_set_dim_id(set
, type
, pos
, id
);
1027 int isl_map_find_dim_by_id(__isl_keep isl_map
*map
, enum isl_dim_type type
,
1028 __isl_keep isl_id
*id
)
1032 return isl_space_find_dim_by_id(map
->dim
, type
, id
);
1035 int isl_set_find_dim_by_id(__isl_keep isl_set
*set
, enum isl_dim_type type
,
1036 __isl_keep isl_id
*id
)
1038 return isl_map_find_dim_by_id(set
, type
, id
);
1041 /* Return the position of the dimension of the given type and name
1043 * Return -1 if no such dimension can be found.
1045 int isl_basic_map_find_dim_by_name(__isl_keep isl_basic_map
*bmap
,
1046 enum isl_dim_type type
, const char *name
)
1050 return isl_space_find_dim_by_name(bmap
->dim
, type
, name
);
1053 int isl_map_find_dim_by_name(__isl_keep isl_map
*map
, enum isl_dim_type type
,
1058 return isl_space_find_dim_by_name(map
->dim
, type
, name
);
1061 int isl_set_find_dim_by_name(__isl_keep isl_set
*set
, enum isl_dim_type type
,
1064 return isl_map_find_dim_by_name(set
, type
, name
);
1067 /* Check whether equality i of bset is a pure stride constraint
1068 * on a single dimension, i.e., of the form
1072 * with k a constant and e an existentially quantified variable.
1074 isl_bool
isl_basic_set_eq_is_stride(__isl_keep isl_basic_set
*bset
, int i
)
1082 nparam
= isl_basic_set_dim(bset
, isl_dim_param
);
1083 d
= isl_basic_set_dim(bset
, isl_dim_set
);
1084 n_div
= isl_basic_set_dim(bset
, isl_dim_div
);
1085 if (nparam
< 0 || d
< 0 || n_div
< 0)
1086 return isl_bool_error
;
1088 if (!isl_int_is_zero(bset
->eq
[i
][0]))
1089 return isl_bool_false
;
1091 if (isl_seq_first_non_zero(bset
->eq
[i
] + 1, nparam
) != -1)
1092 return isl_bool_false
;
1093 pos1
= isl_seq_first_non_zero(bset
->eq
[i
] + 1 + nparam
, d
);
1095 return isl_bool_false
;
1096 if (isl_seq_first_non_zero(bset
->eq
[i
] + 1 + nparam
+ pos1
+ 1,
1097 d
- pos1
- 1) != -1)
1098 return isl_bool_false
;
1100 pos2
= isl_seq_first_non_zero(bset
->eq
[i
] + 1 + nparam
+ d
, n_div
);
1102 return isl_bool_false
;
1103 if (isl_seq_first_non_zero(bset
->eq
[i
] + 1 + nparam
+ d
+ pos2
+ 1,
1104 n_div
- pos2
- 1) != -1)
1105 return isl_bool_false
;
1106 if (!isl_int_is_one(bset
->eq
[i
][1 + nparam
+ pos1
]) &&
1107 !isl_int_is_negone(bset
->eq
[i
][1 + nparam
+ pos1
]))
1108 return isl_bool_false
;
1110 return isl_bool_true
;
1113 /* Reset the user pointer on all identifiers of parameters and tuples
1114 * of the space of "map".
1116 __isl_give isl_map
*isl_map_reset_user(__isl_take isl_map
*map
)
1120 space
= isl_map_get_space(map
);
1121 space
= isl_space_reset_user(space
);
1122 map
= isl_map_reset_space(map
, space
);
1127 /* Reset the user pointer on all identifiers of parameters and tuples
1128 * of the space of "set".
1130 __isl_give isl_set
*isl_set_reset_user(__isl_take isl_set
*set
)
1132 return isl_map_reset_user(set
);
1135 isl_bool
isl_basic_map_is_rational(__isl_keep isl_basic_map
*bmap
)
1138 return isl_bool_error
;
1139 return ISL_F_ISSET(bmap
, ISL_BASIC_MAP_RATIONAL
);
1142 /* Has "map" been marked as a rational map?
1143 * In particular, have all basic maps in "map" been marked this way?
1144 * An empty map is not considered to be rational.
1145 * Maps where only some of the basic maps are marked rational
1148 isl_bool
isl_map_is_rational(__isl_keep isl_map
*map
)
1154 return isl_bool_error
;
1156 return isl_bool_false
;
1157 rational
= isl_basic_map_is_rational(map
->p
[0]);
1160 for (i
= 1; i
< map
->n
; ++i
) {
1161 isl_bool rational_i
;
1163 rational_i
= isl_basic_map_is_rational(map
->p
[i
]);
1166 if (rational
!= rational_i
)
1167 isl_die(isl_map_get_ctx(map
), isl_error_unsupported
,
1168 "mixed rational and integer basic maps "
1169 "not supported", return isl_bool_error
);
1175 /* Has "set" been marked as a rational set?
1176 * In particular, have all basic set in "set" been marked this way?
1177 * An empty set is not considered to be rational.
1178 * Sets where only some of the basic sets are marked rational
1181 isl_bool
isl_set_is_rational(__isl_keep isl_set
*set
)
1183 return isl_map_is_rational(set
);
1186 int isl_basic_set_is_rational(__isl_keep isl_basic_set
*bset
)
1188 return isl_basic_map_is_rational(bset
);
1191 /* Does "bmap" contain any rational points?
1193 * If "bmap" has an equality for each dimension, equating the dimension
1194 * to an integer constant, then it has no rational points, even if it
1195 * is marked as rational.
1197 isl_bool
isl_basic_map_has_rational(__isl_keep isl_basic_map
*bmap
)
1199 isl_bool has_rational
= isl_bool_true
;
1203 return isl_bool_error
;
1204 if (isl_basic_map_plain_is_empty(bmap
))
1205 return isl_bool_false
;
1206 if (!isl_basic_map_is_rational(bmap
))
1207 return isl_bool_false
;
1208 bmap
= isl_basic_map_copy(bmap
);
1209 bmap
= isl_basic_map_implicit_equalities(bmap
);
1210 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
1212 return isl_bool_error
;
1213 if (bmap
->n_eq
== total
) {
1215 for (i
= 0; i
< bmap
->n_eq
; ++i
) {
1216 j
= isl_seq_first_non_zero(bmap
->eq
[i
] + 1, total
);
1219 if (!isl_int_is_one(bmap
->eq
[i
][1 + j
]) &&
1220 !isl_int_is_negone(bmap
->eq
[i
][1 + j
]))
1222 j
= isl_seq_first_non_zero(bmap
->eq
[i
] + 1 + j
+ 1,
1227 if (i
== bmap
->n_eq
)
1228 has_rational
= isl_bool_false
;
1230 isl_basic_map_free(bmap
);
1232 return has_rational
;
1235 /* Does "map" contain any rational points?
1237 isl_bool
isl_map_has_rational(__isl_keep isl_map
*map
)
1240 isl_bool has_rational
;
1243 return isl_bool_error
;
1244 for (i
= 0; i
< map
->n
; ++i
) {
1245 has_rational
= isl_basic_map_has_rational(map
->p
[i
]);
1246 if (has_rational
< 0 || has_rational
)
1247 return has_rational
;
1249 return isl_bool_false
;
1252 /* Does "set" contain any rational points?
1254 isl_bool
isl_set_has_rational(__isl_keep isl_set
*set
)
1256 return isl_map_has_rational(set
);
1259 /* Is this basic set a parameter domain?
1261 isl_bool
isl_basic_set_is_params(__isl_keep isl_basic_set
*bset
)
1264 return isl_bool_error
;
1265 return isl_space_is_params(bset
->dim
);
1268 /* Is this set a parameter domain?
1270 isl_bool
isl_set_is_params(__isl_keep isl_set
*set
)
1273 return isl_bool_error
;
1274 return isl_space_is_params(set
->dim
);
1277 /* Is this map actually a parameter domain?
1278 * Users should never call this function. Outside of isl,
1279 * a map can never be a parameter domain.
1281 isl_bool
isl_map_is_params(__isl_keep isl_map
*map
)
1284 return isl_bool_error
;
1285 return isl_space_is_params(map
->dim
);
1288 static __isl_give isl_basic_map
*basic_map_init(isl_ctx
*ctx
,
1289 __isl_take isl_basic_map
*bmap
, unsigned extra
,
1290 unsigned n_eq
, unsigned n_ineq
)
1293 isl_space
*space
= isl_basic_map_peek_space(bmap
);
1294 isl_size n_var
= isl_space_dim(space
, isl_dim_all
);
1295 size_t row_size
= 1 + n_var
+ extra
;
1301 return isl_basic_map_free(bmap
);
1303 bmap
->block
= isl_blk_alloc(ctx
, (n_ineq
+ n_eq
) * row_size
);
1304 if (isl_blk_is_error(bmap
->block
))
1307 bmap
->ineq
= isl_alloc_array(ctx
, isl_int
*, n_ineq
+ n_eq
);
1308 if ((n_ineq
+ n_eq
) && !bmap
->ineq
)
1312 bmap
->block2
= isl_blk_empty();
1315 bmap
->block2
= isl_blk_alloc(ctx
, extra
* (1 + row_size
));
1316 if (isl_blk_is_error(bmap
->block2
))
1319 bmap
->div
= isl_alloc_array(ctx
, isl_int
*, extra
);
1324 for (i
= 0; i
< n_ineq
+ n_eq
; ++i
)
1325 bmap
->ineq
[i
] = bmap
->block
.data
+ i
* row_size
;
1327 for (i
= 0; i
< extra
; ++i
)
1328 bmap
->div
[i
] = bmap
->block2
.data
+ i
* (1 + row_size
);
1332 bmap
->c_size
= n_eq
+ n_ineq
;
1333 bmap
->eq
= bmap
->ineq
+ n_ineq
;
1334 bmap
->extra
= extra
;
1338 bmap
->sample
= NULL
;
1342 isl_basic_map_free(bmap
);
1346 __isl_give isl_basic_set
*isl_basic_set_alloc(isl_ctx
*ctx
,
1347 unsigned nparam
, unsigned dim
, unsigned extra
,
1348 unsigned n_eq
, unsigned n_ineq
)
1350 struct isl_basic_map
*bmap
;
1353 space
= isl_space_set_alloc(ctx
, nparam
, dim
);
1357 bmap
= isl_basic_map_alloc_space(space
, extra
, n_eq
, n_ineq
);
1358 return bset_from_bmap(bmap
);
1361 __isl_give isl_basic_set
*isl_basic_set_alloc_space(__isl_take isl_space
*space
,
1362 unsigned extra
, unsigned n_eq
, unsigned n_ineq
)
1364 struct isl_basic_map
*bmap
;
1367 isl_assert(space
->ctx
, space
->n_in
== 0, goto error
);
1368 bmap
= isl_basic_map_alloc_space(space
, extra
, n_eq
, n_ineq
);
1369 return bset_from_bmap(bmap
);
1371 isl_space_free(space
);
1375 __isl_give isl_basic_map
*isl_basic_map_alloc_space(__isl_take isl_space
*space
,
1376 unsigned extra
, unsigned n_eq
, unsigned n_ineq
)
1378 struct isl_basic_map
*bmap
;
1382 bmap
= isl_calloc_type(space
->ctx
, struct isl_basic_map
);
1387 return basic_map_init(space
->ctx
, bmap
, extra
, n_eq
, n_ineq
);
1389 isl_space_free(space
);
1393 __isl_give isl_basic_map
*isl_basic_map_alloc(isl_ctx
*ctx
,
1394 unsigned nparam
, unsigned in
, unsigned out
, unsigned extra
,
1395 unsigned n_eq
, unsigned n_ineq
)
1397 struct isl_basic_map
*bmap
;
1400 space
= isl_space_alloc(ctx
, nparam
, in
, out
);
1404 bmap
= isl_basic_map_alloc_space(space
, extra
, n_eq
, n_ineq
);
1408 static __isl_give isl_basic_map
*dup_constraints(__isl_take isl_basic_map
*dst
,
1409 __isl_keep isl_basic_map
*src
)
1412 isl_size total
= isl_basic_map_dim(src
, isl_dim_all
);
1414 if (!dst
|| total
< 0)
1415 return isl_basic_map_free(dst
);
1417 for (i
= 0; i
< src
->n_eq
; ++i
) {
1418 int j
= isl_basic_map_alloc_equality(dst
);
1420 return isl_basic_map_free(dst
);
1421 isl_seq_cpy(dst
->eq
[j
], src
->eq
[i
], 1+total
);
1424 for (i
= 0; i
< src
->n_ineq
; ++i
) {
1425 int j
= isl_basic_map_alloc_inequality(dst
);
1427 return isl_basic_map_free(dst
);
1428 isl_seq_cpy(dst
->ineq
[j
], src
->ineq
[i
], 1+total
);
1431 for (i
= 0; i
< src
->n_div
; ++i
) {
1432 int j
= isl_basic_map_alloc_div(dst
);
1434 return isl_basic_map_free(dst
);
1435 isl_seq_cpy(dst
->div
[j
], src
->div
[i
], 1+1+total
);
1437 ISL_F_SET(dst
, ISL_BASIC_SET_FINAL
);
1441 __isl_give isl_basic_map
*isl_basic_map_dup(__isl_keep isl_basic_map
*bmap
)
1443 struct isl_basic_map
*dup
;
1447 dup
= isl_basic_map_alloc_space(isl_space_copy(bmap
->dim
),
1448 bmap
->n_div
, bmap
->n_eq
, bmap
->n_ineq
);
1449 dup
= dup_constraints(dup
, bmap
);
1452 dup
->flags
= bmap
->flags
;
1453 dup
->sample
= isl_vec_copy(bmap
->sample
);
1457 __isl_give isl_basic_set
*isl_basic_set_dup(__isl_keep isl_basic_set
*bset
)
1459 struct isl_basic_map
*dup
;
1461 dup
= isl_basic_map_dup(bset_to_bmap(bset
));
1462 return bset_from_bmap(dup
);
1465 __isl_give isl_basic_set
*isl_basic_set_copy(__isl_keep isl_basic_set
*bset
)
1467 return bset_from_bmap(isl_basic_map_copy(bset_to_bmap(bset
)));
1470 __isl_give isl_set
*isl_set_copy(__isl_keep isl_set
*set
)
1479 __isl_give isl_basic_map
*isl_basic_map_copy(__isl_keep isl_basic_map
*bmap
)
1484 if (ISL_F_ISSET(bmap
, ISL_BASIC_SET_FINAL
)) {
1488 bmap
= isl_basic_map_dup(bmap
);
1490 ISL_F_SET(bmap
, ISL_BASIC_SET_FINAL
);
1494 __isl_give isl_map
*isl_map_copy(__isl_keep isl_map
*map
)
1503 __isl_null isl_basic_map
*isl_basic_map_free(__isl_take isl_basic_map
*bmap
)
1508 if (--bmap
->ref
> 0)
1511 isl_ctx_deref(bmap
->ctx
);
1513 isl_blk_free(bmap
->ctx
, bmap
->block2
);
1515 isl_blk_free(bmap
->ctx
, bmap
->block
);
1516 isl_vec_free(bmap
->sample
);
1517 isl_space_free(bmap
->dim
);
1523 __isl_null isl_basic_set
*isl_basic_set_free(__isl_take isl_basic_set
*bset
)
1525 return isl_basic_map_free(bset_to_bmap(bset
));
1528 static int room_for_con(__isl_keep isl_basic_map
*bmap
, unsigned n
)
1530 return bmap
->n_eq
+ bmap
->n_ineq
+ n
<= bmap
->c_size
;
1533 /* Check that "bset" does not involve any parameters.
1535 isl_stat
isl_basic_set_check_no_params(__isl_keep isl_basic_set
*bset
)
1539 nparam
= isl_basic_set_dim(bset
, isl_dim_param
);
1541 return isl_stat_error
;
1543 isl_die(isl_basic_set_get_ctx(bset
), isl_error_invalid
,
1544 "basic set should not have any parameters",
1545 return isl_stat_error
);
1549 /* Check that "bset" does not involve any local variables.
1551 isl_stat
isl_basic_set_check_no_locals(__isl_keep isl_basic_set
*bset
)
1555 n_div
= isl_basic_set_dim(bset
, isl_dim_div
);
1557 return isl_stat_error
;
1559 isl_die(isl_basic_set_get_ctx(bset
), isl_error_invalid
,
1560 "basic set should not have any local variables",
1561 return isl_stat_error
);
1566 #define TYPE isl_map
1568 #include "isl_check_named_params_templ.c"
1571 #define TYPE isl_basic_map
1574 #include "isl_check_named_params_templ.c"
1576 /* Check that "bmap1" and "bmap2" have the same parameters,
1577 * reporting an error if they do not.
1579 static isl_stat
isl_basic_map_check_equal_params(
1580 __isl_keep isl_basic_map
*bmap1
, __isl_keep isl_basic_map
*bmap2
)
1584 match
= isl_basic_map_has_equal_params(bmap1
, bmap2
);
1586 return isl_stat_error
;
1588 isl_die(isl_basic_map_get_ctx(bmap1
), isl_error_invalid
,
1589 "parameters don't match", return isl_stat_error
);
1594 #define TYPE isl_map
1596 #include "isl_align_params_bin_templ.c"
1601 #define ARG1 isl_map
1603 #define ARG2 isl_set
1605 #include "isl_align_params_templ.c"
1607 isl_bool
isl_map_align_params_map_map_and_test(__isl_keep isl_map
*map1
,
1608 __isl_keep isl_map
*map2
,
1609 isl_bool (*fn
)(__isl_keep isl_map
*map1
, __isl_keep isl_map
*map2
))
1614 return isl_bool_error
;
1615 if (isl_map_has_equal_params(map1
, map2
))
1616 return fn(map1
, map2
);
1617 if (isl_map_check_named_params(map1
) < 0)
1618 return isl_bool_error
;
1619 if (isl_map_check_named_params(map2
) < 0)
1620 return isl_bool_error
;
1621 map1
= isl_map_copy(map1
);
1622 map2
= isl_map_copy(map2
);
1623 map1
= isl_map_align_params(map1
, isl_map_get_space(map2
));
1624 map2
= isl_map_align_params(map2
, isl_map_get_space(map1
));
1631 int isl_basic_map_alloc_equality(__isl_keep isl_basic_map
*bmap
)
1634 struct isl_ctx
*ctx
;
1636 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
1640 isl_assert(ctx
, room_for_con(bmap
, 1), return -1);
1641 isl_assert(ctx
, (bmap
->eq
- bmap
->ineq
) + bmap
->n_eq
<= bmap
->c_size
,
1643 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NO_REDUNDANT
);
1644 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NO_IMPLICIT
);
1645 ISL_F_CLR(bmap
, ISL_BASIC_MAP_ALL_EQUALITIES
);
1646 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NORMALIZED_DIVS
);
1647 if ((bmap
->eq
- bmap
->ineq
) + bmap
->n_eq
== bmap
->c_size
) {
1649 int j
= isl_basic_map_alloc_inequality(bmap
);
1653 bmap
->ineq
[j
] = bmap
->ineq
[bmap
->n_ineq
- 1];
1654 bmap
->ineq
[bmap
->n_ineq
- 1] = bmap
->eq
[-1];
1661 isl_seq_clr(bmap
->eq
[bmap
->n_eq
] + 1 + total
,
1662 bmap
->extra
- bmap
->n_div
);
1663 return bmap
->n_eq
++;
1666 int isl_basic_set_alloc_equality(__isl_keep isl_basic_set
*bset
)
1668 return isl_basic_map_alloc_equality(bset_to_bmap(bset
));
1671 __isl_give isl_basic_map
*isl_basic_map_free_equality(
1672 __isl_take isl_basic_map
*bmap
, unsigned n
)
1677 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
1678 "invalid number of equalities",
1679 isl_basic_map_free(bmap
));
1684 __isl_give isl_basic_set
*isl_basic_set_free_equality(
1685 __isl_take isl_basic_set
*bset
, unsigned n
)
1687 return bset_from_bmap(isl_basic_map_free_equality(bset_to_bmap(bset
),
1691 /* Drop the equality constraint at position "pos",
1692 * preserving the order of the other equality constraints.
1694 int isl_basic_map_drop_equality(__isl_keep isl_basic_map
*bmap
, unsigned pos
)
1701 isl_assert(bmap
->ctx
, pos
< bmap
->n_eq
, return -1);
1705 for (r
= pos
; r
< bmap
->n_eq
; ++r
)
1706 bmap
->eq
[r
] = bmap
->eq
[r
+ 1];
1707 bmap
->eq
[bmap
->n_eq
] = t
;
1712 /* Turn inequality "pos" of "bmap" into an equality.
1714 * In particular, we move the inequality in front of the equalities
1715 * and move the last inequality in the position of the moved inequality.
1716 * Note that isl_tab_make_equalities_explicit depends on this particular
1717 * change in the ordering of the constraints.
1719 void isl_basic_map_inequality_to_equality(
1720 __isl_keep isl_basic_map
*bmap
, unsigned pos
)
1724 t
= bmap
->ineq
[pos
];
1725 bmap
->ineq
[pos
] = bmap
->ineq
[bmap
->n_ineq
- 1];
1726 bmap
->ineq
[bmap
->n_ineq
- 1] = bmap
->eq
[-1];
1731 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NO_REDUNDANT
);
1732 ISL_F_CLR(bmap
, ISL_BASIC_MAP_SORTED
);
1733 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NORMALIZED_DIVS
);
1734 ISL_F_CLR(bmap
, ISL_BASIC_MAP_ALL_EQUALITIES
);
1737 static int room_for_ineq(__isl_keep isl_basic_map
*bmap
, unsigned n
)
1739 return bmap
->n_ineq
+ n
<= bmap
->eq
- bmap
->ineq
;
1742 int isl_basic_map_alloc_inequality(__isl_keep isl_basic_map
*bmap
)
1745 struct isl_ctx
*ctx
;
1747 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
1751 isl_assert(ctx
, room_for_ineq(bmap
, 1), return -1);
1752 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NO_IMPLICIT
);
1753 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NO_REDUNDANT
);
1754 ISL_F_CLR(bmap
, ISL_BASIC_MAP_SORTED
);
1755 ISL_F_CLR(bmap
, ISL_BASIC_MAP_ALL_EQUALITIES
);
1756 ISL_F_CLR(bmap
, ISL_BASIC_MAP_REDUCED_COEFFICIENTS
);
1757 isl_seq_clr(bmap
->ineq
[bmap
->n_ineq
] + 1 + total
,
1758 bmap
->extra
- bmap
->n_div
);
1759 return bmap
->n_ineq
++;
1762 int isl_basic_set_alloc_inequality(__isl_keep isl_basic_set
*bset
)
1764 return isl_basic_map_alloc_inequality(bset_to_bmap(bset
));
1767 __isl_give isl_basic_map
*isl_basic_map_free_inequality(
1768 __isl_take isl_basic_map
*bmap
, unsigned n
)
1772 if (n
> bmap
->n_ineq
)
1773 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
1774 "invalid number of inequalities",
1775 return isl_basic_map_free(bmap
));
1780 __isl_give isl_basic_set
*isl_basic_set_free_inequality(
1781 __isl_take isl_basic_set
*bset
, unsigned n
)
1783 return bset_from_bmap(isl_basic_map_free_inequality(bset_to_bmap(bset
),
1787 int isl_basic_map_drop_inequality(__isl_keep isl_basic_map
*bmap
, unsigned pos
)
1792 isl_assert(bmap
->ctx
, pos
< bmap
->n_ineq
, return -1);
1794 if (pos
!= bmap
->n_ineq
- 1) {
1795 t
= bmap
->ineq
[pos
];
1796 bmap
->ineq
[pos
] = bmap
->ineq
[bmap
->n_ineq
- 1];
1797 bmap
->ineq
[bmap
->n_ineq
- 1] = t
;
1798 ISL_F_CLR(bmap
, ISL_BASIC_MAP_SORTED
);
1804 int isl_basic_set_drop_inequality(__isl_keep isl_basic_set
*bset
, unsigned pos
)
1806 return isl_basic_map_drop_inequality(bset_to_bmap(bset
), pos
);
1809 __isl_give isl_basic_map
*isl_basic_map_add_eq(__isl_take isl_basic_map
*bmap
,
1816 empty
= isl_basic_map_plain_is_empty(bmap
);
1818 return isl_basic_map_free(bmap
);
1822 bmap
= isl_basic_map_cow(bmap
);
1823 bmap
= isl_basic_map_extend_constraints(bmap
, 1, 0);
1824 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
1826 return isl_basic_map_free(bmap
);
1827 k
= isl_basic_map_alloc_equality(bmap
);
1830 isl_seq_cpy(bmap
->eq
[k
], eq
, 1 + total
);
1833 isl_basic_map_free(bmap
);
1837 __isl_give isl_basic_set
*isl_basic_set_add_eq(__isl_take isl_basic_set
*bset
,
1840 return bset_from_bmap(isl_basic_map_add_eq(bset_to_bmap(bset
), eq
));
1843 __isl_give isl_basic_map
*isl_basic_map_add_ineq(__isl_take isl_basic_map
*bmap
,
1849 bmap
= isl_basic_map_cow(bmap
);
1850 bmap
= isl_basic_map_extend_constraints(bmap
, 0, 1);
1851 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
1853 return isl_basic_map_free(bmap
);
1854 k
= isl_basic_map_alloc_inequality(bmap
);
1857 isl_seq_cpy(bmap
->ineq
[k
], ineq
, 1 + total
);
1860 isl_basic_map_free(bmap
);
1864 __isl_give isl_basic_set
*isl_basic_set_add_ineq(__isl_take isl_basic_set
*bset
,
1867 return bset_from_bmap(isl_basic_map_add_ineq(bset_to_bmap(bset
), ineq
));
1870 int isl_basic_map_alloc_div(__isl_keep isl_basic_map
*bmap
)
1874 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
1877 isl_assert(bmap
->ctx
, bmap
->n_div
< bmap
->extra
, return -1);
1878 isl_seq_clr(bmap
->div
[bmap
->n_div
] + 1 + 1 + total
,
1879 bmap
->extra
- bmap
->n_div
);
1880 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NORMALIZED_DIVS
);
1881 return bmap
->n_div
++;
1884 int isl_basic_set_alloc_div(__isl_keep isl_basic_set
*bset
)
1886 return isl_basic_map_alloc_div(bset_to_bmap(bset
));
1890 #define TYPE isl_basic_map
1891 #include "check_type_range_templ.c"
1893 /* Check that there are "n" dimensions of type "type" starting at "first"
1896 isl_stat
isl_basic_set_check_range(__isl_keep isl_basic_set
*bset
,
1897 enum isl_dim_type type
, unsigned first
, unsigned n
)
1899 return isl_basic_map_check_range(bset_to_bmap(bset
),
1903 /* Insert an extra integer division, prescribed by "div", to "bmap"
1904 * at (integer division) position "pos".
1906 * The integer division is first added at the end and then moved
1907 * into the right position.
1909 __isl_give isl_basic_map
*isl_basic_map_insert_div(
1910 __isl_take isl_basic_map
*bmap
, int pos
, __isl_keep isl_vec
*div
)
1915 bmap
= isl_basic_map_cow(bmap
);
1916 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
1917 if (total
< 0 || !div
)
1918 return isl_basic_map_free(bmap
);
1920 if (div
->size
!= 1 + 1 + total
)
1921 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
1922 "unexpected size", return isl_basic_map_free(bmap
));
1923 if (isl_basic_map_check_range(bmap
, isl_dim_div
, pos
, 0) < 0)
1924 return isl_basic_map_free(bmap
);
1926 bmap
= isl_basic_map_extend(bmap
, 1, 0, 2);
1927 k
= isl_basic_map_alloc_div(bmap
);
1929 return isl_basic_map_free(bmap
);
1930 isl_seq_cpy(bmap
->div
[k
], div
->el
, div
->size
);
1931 isl_int_set_si(bmap
->div
[k
][div
->size
], 0);
1933 for (i
= k
; i
> pos
; --i
)
1934 bmap
= isl_basic_map_swap_div(bmap
, i
, i
- 1);
1939 isl_stat
isl_basic_map_free_div(__isl_keep isl_basic_map
*bmap
, unsigned n
)
1942 return isl_stat_error
;
1943 isl_assert(bmap
->ctx
, n
<= bmap
->n_div
, return isl_stat_error
);
1948 static __isl_give isl_basic_map
*add_constraints(
1949 __isl_take isl_basic_map
*bmap1
, __isl_take isl_basic_map
*bmap2
,
1950 unsigned i_pos
, unsigned o_pos
)
1952 isl_size total
, n_param
, n_in
, n_out
, n_div
;
1953 unsigned o_in
, o_out
;
1956 struct isl_dim_map
*dim_map
;
1958 space
= isl_basic_map_peek_space(bmap2
);
1959 if (!bmap1
|| !space
)
1962 total
= isl_basic_map_dim(bmap1
, isl_dim_all
);
1963 n_param
= isl_basic_map_dim(bmap2
, isl_dim_param
);
1964 n_in
= isl_basic_map_dim(bmap2
, isl_dim_in
);
1965 o_in
= isl_basic_map_offset(bmap1
, isl_dim_in
) - 1 + i_pos
;
1966 n_out
= isl_basic_map_dim(bmap2
, isl_dim_out
);
1967 o_out
= isl_basic_map_offset(bmap1
, isl_dim_out
) - 1 + o_pos
;
1968 n_div
= isl_basic_map_dim(bmap2
, isl_dim_div
);
1969 if (total
< 0 || n_param
< 0 || n_in
< 0 || n_out
< 0 || n_div
< 0)
1971 ctx
= isl_basic_map_get_ctx(bmap1
);
1972 dim_map
= isl_dim_map_alloc(ctx
, total
+ n_div
);
1973 isl_dim_map_dim_range(dim_map
, space
, isl_dim_param
, 0, n_param
, 0);
1974 isl_dim_map_dim_range(dim_map
, space
, isl_dim_in
, 0, n_in
, o_in
);
1975 isl_dim_map_dim_range(dim_map
, space
, isl_dim_out
, 0, n_out
, o_out
);
1976 isl_dim_map_div(dim_map
, bmap2
, total
);
1978 return isl_basic_map_add_constraints_dim_map(bmap1
, bmap2
, dim_map
);
1980 isl_basic_map_free(bmap1
);
1981 isl_basic_map_free(bmap2
);
1985 __isl_give isl_basic_map
*isl_basic_map_extend(__isl_take isl_basic_map
*base
,
1986 unsigned extra
, unsigned n_eq
, unsigned n_ineq
)
1989 struct isl_basic_map
*ext
;
1996 dims_ok
= base
->extra
>= base
->n_div
+ extra
;
1998 if (dims_ok
&& room_for_con(base
, n_eq
+ n_ineq
) &&
1999 room_for_ineq(base
, n_ineq
))
2002 extra
+= base
->extra
;
2004 n_ineq
+= base
->n_ineq
;
2006 space
= isl_basic_map_get_space(base
);
2007 ext
= isl_basic_map_alloc_space(space
, extra
, n_eq
, n_ineq
);
2012 ext
->sample
= isl_vec_copy(base
->sample
);
2013 flags
= base
->flags
;
2014 ext
= add_constraints(ext
, base
, 0, 0);
2017 ISL_F_CLR(ext
, ISL_BASIC_SET_FINAL
);
2023 isl_basic_map_free(base
);
2027 __isl_give isl_basic_set
*isl_basic_set_extend(__isl_take isl_basic_set
*base
,
2028 unsigned extra
, unsigned n_eq
, unsigned n_ineq
)
2030 return bset_from_bmap(isl_basic_map_extend(bset_to_bmap(base
),
2031 extra
, n_eq
, n_ineq
));
2034 __isl_give isl_basic_map
*isl_basic_map_extend_constraints(
2035 __isl_take isl_basic_map
*base
, unsigned n_eq
, unsigned n_ineq
)
2037 return isl_basic_map_extend(base
, 0, n_eq
, n_ineq
);
2040 __isl_give isl_basic_set
*isl_basic_set_extend_constraints(
2041 __isl_take isl_basic_set
*base
, unsigned n_eq
, unsigned n_ineq
)
2043 isl_basic_map
*bmap
= bset_to_bmap(base
);
2044 bmap
= isl_basic_map_extend_constraints(bmap
, n_eq
, n_ineq
);
2045 return bset_from_bmap(bmap
);
2048 __isl_give isl_basic_set
*isl_basic_set_cow(__isl_take isl_basic_set
*bset
)
2050 return bset_from_bmap(isl_basic_map_cow(bset_to_bmap(bset
)));
2053 __isl_give isl_basic_map
*isl_basic_map_cow(__isl_take isl_basic_map
*bmap
)
2058 if (bmap
->ref
> 1) {
2060 bmap
= isl_basic_map_dup(bmap
);
2063 ISL_F_CLR(bmap
, ISL_BASIC_SET_FINAL
);
2067 /* Clear all cached information in "map", either because it is about
2068 * to be modified or because it is being freed.
2069 * Always return the same pointer that is passed in.
2070 * This is needed for the use in isl_map_free.
2072 static __isl_give isl_map
*clear_caches(__isl_take isl_map
*map
)
2074 isl_basic_map_free(map
->cached_simple_hull
[0]);
2075 isl_basic_map_free(map
->cached_simple_hull
[1]);
2076 map
->cached_simple_hull
[0] = NULL
;
2077 map
->cached_simple_hull
[1] = NULL
;
2081 __isl_give isl_set
*isl_set_cow(__isl_take isl_set
*set
)
2083 return isl_map_cow(set
);
2086 /* Return an isl_map that is equal to "map" and that has only
2087 * a single reference.
2089 * If the original input already has only one reference, then
2090 * simply return it, but clear all cached information, since
2091 * it may be rendered invalid by the operations that will be
2092 * performed on the result.
2094 * Otherwise, create a duplicate (without any cached information).
2096 __isl_give isl_map
*isl_map_cow(__isl_take isl_map
*map
)
2102 return clear_caches(map
);
2104 return isl_map_dup(map
);
2107 static void swap_vars(struct isl_blk blk
, isl_int
*a
,
2108 unsigned a_len
, unsigned b_len
)
2110 isl_seq_cpy(blk
.data
, a
+a_len
, b_len
);
2111 isl_seq_cpy(blk
.data
+b_len
, a
, a_len
);
2112 isl_seq_cpy(a
, blk
.data
, b_len
+a_len
);
2115 static __isl_give isl_basic_map
*isl_basic_map_swap_vars(
2116 __isl_take isl_basic_map
*bmap
, unsigned pos
, unsigned n1
, unsigned n2
)
2121 if (isl_basic_map_check_range(bmap
, isl_dim_all
, pos
- 1, n1
+ n2
) < 0)
2124 if (n1
== 0 || n2
== 0)
2127 bmap
= isl_basic_map_cow(bmap
);
2131 blk
= isl_blk_alloc(bmap
->ctx
, n1
+ n2
);
2132 if (isl_blk_is_error(blk
))
2135 for (i
= 0; i
< bmap
->n_eq
; ++i
)
2137 bmap
->eq
[i
] + pos
, n1
, n2
);
2139 for (i
= 0; i
< bmap
->n_ineq
; ++i
)
2141 bmap
->ineq
[i
] + pos
, n1
, n2
);
2143 for (i
= 0; i
< bmap
->n_div
; ++i
)
2145 bmap
->div
[i
]+1 + pos
, n1
, n2
);
2147 isl_blk_free(bmap
->ctx
, blk
);
2149 ISL_F_CLR(bmap
, ISL_BASIC_SET_SORTED
);
2150 bmap
= isl_basic_map_gauss(bmap
, NULL
);
2151 return isl_basic_map_finalize(bmap
);
2153 isl_basic_map_free(bmap
);
2157 /* The given basic map has turned out to be empty.
2158 * Explicitly mark it as such and change the representation
2159 * to a canonical representation of the empty basic map.
2160 * Since the basic map has conflicting constraints,
2161 * it must have at least one constraint, except perhaps
2162 * if it was already explicitly marked as being empty.
2163 * Do nothing in the latter case, i.e., if it has been marked empty and
2164 * has no constraints.
2166 __isl_give isl_basic_map
*isl_basic_map_set_to_empty(
2167 __isl_take isl_basic_map
*bmap
)
2174 n
= isl_basic_map_n_constraint(bmap
);
2175 empty
= isl_basic_map_plain_is_empty(bmap
);
2176 if (n
< 0 || empty
< 0)
2177 return isl_basic_map_free(bmap
);
2178 if (n
== 0 && empty
)
2180 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
2182 return isl_basic_map_free(bmap
);
2183 if (isl_basic_map_free_div(bmap
, bmap
->n_div
) < 0)
2184 return isl_basic_map_free(bmap
);
2185 bmap
= isl_basic_map_free_inequality(bmap
, bmap
->n_ineq
);
2188 if (bmap
->n_eq
> 0) {
2189 bmap
= isl_basic_map_free_equality(bmap
, bmap
->n_eq
- 1);
2193 i
= isl_basic_map_alloc_equality(bmap
);
2197 isl_int_set_si(bmap
->eq
[i
][0], 1);
2198 isl_seq_clr(bmap
->eq
[i
]+1, total
);
2199 ISL_F_SET(bmap
, ISL_BASIC_MAP_EMPTY
);
2200 isl_vec_free(bmap
->sample
);
2201 bmap
->sample
= NULL
;
2202 return isl_basic_map_finalize(bmap
);
2204 isl_basic_map_free(bmap
);
2208 __isl_give isl_basic_set
*isl_basic_set_set_to_empty(
2209 __isl_take isl_basic_set
*bset
)
2211 return bset_from_bmap(isl_basic_map_set_to_empty(bset_to_bmap(bset
)));
2214 __isl_give isl_basic_map
*isl_basic_map_set_rational(
2215 __isl_take isl_basic_map
*bmap
)
2220 if (ISL_F_ISSET(bmap
, ISL_BASIC_MAP_RATIONAL
))
2223 bmap
= isl_basic_map_cow(bmap
);
2227 ISL_F_SET(bmap
, ISL_BASIC_MAP_RATIONAL
);
2229 return isl_basic_map_finalize(bmap
);
2232 __isl_give isl_basic_set
*isl_basic_set_set_rational(
2233 __isl_take isl_basic_set
*bset
)
2235 return isl_basic_map_set_rational(bset
);
2238 __isl_give isl_basic_set
*isl_basic_set_set_integral(
2239 __isl_take isl_basic_set
*bset
)
2244 if (!ISL_F_ISSET(bset
, ISL_BASIC_MAP_RATIONAL
))
2247 bset
= isl_basic_set_cow(bset
);
2251 ISL_F_CLR(bset
, ISL_BASIC_MAP_RATIONAL
);
2253 return isl_basic_set_finalize(bset
);
2256 __isl_give isl_map
*isl_map_set_rational(__isl_take isl_map
*map
)
2260 map
= isl_map_cow(map
);
2263 for (i
= 0; i
< map
->n
; ++i
) {
2264 map
->p
[i
] = isl_basic_map_set_rational(map
->p
[i
]);
2274 __isl_give isl_set
*isl_set_set_rational(__isl_take isl_set
*set
)
2276 return isl_map_set_rational(set
);
2279 /* Given a constraint "c" that expresses a bound
2280 * on the variable at position "pos" in terms of the first "len" variables
2281 * (other than the variable itself if pos < len), extract this bound
2282 * as a function of those first "len" variables.
2284 * That is, the constraint is of one of the following forms
2286 * -e(...) + m x >= 0
2291 * Return (e(...)) / m, with the denominator m in the first position.
2293 static __isl_give isl_vec
*extract_bound_from_constraint(isl_ctx
*ctx
,
2294 isl_int
*c
, int len
, int pos
)
2298 v
= isl_vec_alloc(ctx
, 1 + 1 + len
);
2301 if (isl_int_is_pos(c
[1 + pos
])) {
2302 isl_int_set(v
->el
[0], c
[1 + pos
]);
2303 isl_seq_neg(v
->el
+ 1, c
, 1 + len
);
2305 isl_int_neg(v
->el
[0], c
[1 + pos
]);
2306 isl_seq_cpy(v
->el
+ 1, c
, 1 + len
);
2309 isl_int_set_si(v
->el
[1 + 1 + pos
], 0);
2314 /* Return the position of the last non-zero coefficient of
2315 * inequality constraint "ineq" of "bmap" or length "len",
2316 * given that the coefficient at position "first" is non-zero,
2317 * or that it is known that there is at least one coefficient
2318 * after "first" that is non-zero.
2320 static int extend_last_non_zero(__isl_keep isl_basic_map
*bmap
, int ineq
,
2321 int first
, unsigned len
)
2325 last
= isl_seq_last_non_zero(bmap
->ineq
[ineq
] + 1 + first
+ 1,
2330 return first
+ 1 + last
;
2333 /* Do the inequality constraints "i" and "j" of "bmap"
2334 * form a pair of opposite constraints, in the (first) "len" coefficients?
2336 static int is_constraint_pair(__isl_keep isl_basic_map
*bmap
, int i
, int j
,
2339 return isl_seq_is_neg(bmap
->ineq
[i
] + 1, bmap
->ineq
[j
] + 1, len
);
2342 /* Given that inequality constraints "i" and "j" of "bmap"
2343 * form a pair of opposite constraints
2352 * do they allow for at most "bound" values in that direction?
2353 * That is, is the sum of their constant terms smaller than "bound"?
2355 * "tmp" is a temporary location that can be used to store the sum.
2357 static int constraint_pair_has_bound(__isl_keep isl_basic_map
*bmap
,
2358 int i
, int j
, isl_int bound
, isl_int
*tmp
)
2360 isl_int_add(*tmp
, bmap
->ineq
[i
][0], bmap
->ineq
[j
][0]);
2361 return isl_int_abs_lt(*tmp
, bound
);
2364 /* Return the position of an inequality constraint in "bmap"
2365 * that together with inequality constraint "ineq" forms
2366 * a pair of opposite constraints that allow at most "bound" values
2367 * in their shared direction and that appears before "ineq".
2368 * Return a position beyond the number of inequality constraints
2369 * if no such constraint can be found.
2371 * The constraints of "bmap" are assumed to have been sorted.
2372 * This means that as soon as a constraint is found where the value
2373 * of the last coefficient (in absolute value) is different from that of "ineq",
2374 * no opposite constraint can be found.
2375 * It also means that only the coefficients up to this last coefficient
2376 * need to be compared.
2378 * "pos" is the position of a coefficient that is known to be non-zero.
2379 * If no such position is known a priori, then the value 0 can be passed in.
2380 * "len" is the number of (relevant) coefficients in the constraints.
2381 * "tmp" is a temporary location that can be used to store the sum.
2383 static isl_size
find_earlier_constraint_in_pair(__isl_keep isl_basic_map
*bmap
,
2384 int ineq
, int pos
, int len
, isl_int bound
, isl_int
*tmp
)
2390 n_ineq
= isl_basic_map_n_inequality(bmap
);
2392 return isl_size_error
;
2394 last
= extend_last_non_zero(bmap
, ineq
, pos
, len
);
2396 for (j
= ineq
- 1; j
>= 0; --j
) {
2397 if (!isl_int_abs_eq(bmap
->ineq
[ineq
][1 + last
],
2398 bmap
->ineq
[j
][1 + last
]))
2400 if (!is_constraint_pair(bmap
, ineq
, j
, last
+ 1))
2402 if (constraint_pair_has_bound(bmap
, ineq
, j
, bound
, tmp
))
2410 /* Return the position of an inequality constraint in "bmap"
2411 * that together with inequality constraint "ineq" forms
2412 * a pair of opposite constraints that allow at most "bound" values
2413 * in their shared direction and that appears after "ineq".
2414 * Return a position beyond the number of inequality constraints
2415 * if no such constraint can be found.
2417 * The constraints of "bmap" are assumed to have been sorted.
2418 * This means that as soon as a constraint is found where the value
2419 * of the last coefficient (in absolute value) is different from that of "ineq",
2420 * no opposite constraint can be found.
2421 * It also means that only the coefficients up to this last coefficient
2422 * need to be compared.
2424 * "pos" is the position of a coefficient that is known to be non-zero.
2425 * If no such position is known a priori, then the value 0 can be passed in.
2426 * "len" is the number of (relevant) coefficients in the constraints.
2427 * "tmp" is a temporary location that can be used to store the sum.
2429 static isl_size
find_later_constraint_in_pair(__isl_keep isl_basic_map
*bmap
,
2430 int ineq
, int pos
, int len
, isl_int bound
, isl_int
*tmp
)
2436 n_ineq
= isl_basic_map_n_inequality(bmap
);
2438 return isl_size_error
;
2440 last
= extend_last_non_zero(bmap
, ineq
, pos
, len
);
2442 for (j
= ineq
+ 1; j
< n_ineq
; ++j
) {
2443 if (!isl_int_abs_eq(bmap
->ineq
[ineq
][1 + last
],
2444 bmap
->ineq
[j
][1 + last
]))
2446 if (isl_seq_last_non_zero(bmap
->ineq
[j
] + 1 + last
+ 1,
2447 len
- (last
+ 1)) != -1)
2449 if (!is_constraint_pair(bmap
, ineq
, j
, last
+ 1))
2451 if (constraint_pair_has_bound(bmap
, ineq
, j
, bound
, tmp
))
2459 /* Swap divs "a" and "b" in "bmap" (without modifying any of the constraints
2462 static void swap_div(__isl_keep isl_basic_map
*bmap
, int a
, int b
)
2464 isl_int
*t
= bmap
->div
[a
];
2465 bmap
->div
[a
] = bmap
->div
[b
];
2469 /* Swap divs "a" and "b" in "bmap" and adjust the constraints and
2470 * div definitions accordingly.
2472 __isl_give isl_basic_map
*isl_basic_map_swap_div(__isl_take isl_basic_map
*bmap
,
2478 off
= isl_basic_map_var_offset(bmap
, isl_dim_div
);
2480 return isl_basic_map_free(bmap
);
2482 swap_div(bmap
, a
, b
);
2484 for (i
= 0; i
< bmap
->n_eq
; ++i
)
2485 isl_int_swap(bmap
->eq
[i
][1+off
+a
], bmap
->eq
[i
][1+off
+b
]);
2487 for (i
= 0; i
< bmap
->n_ineq
; ++i
)
2488 isl_int_swap(bmap
->ineq
[i
][1+off
+a
], bmap
->ineq
[i
][1+off
+b
]);
2490 for (i
= 0; i
< bmap
->n_div
; ++i
)
2491 isl_int_swap(bmap
->div
[i
][1+1+off
+a
], bmap
->div
[i
][1+1+off
+b
]);
2492 ISL_F_CLR(bmap
, ISL_BASIC_MAP_SORTED
);
2497 static void constraint_drop_vars(isl_int
*c
, unsigned n
, unsigned rem
)
2499 isl_seq_cpy(c
, c
+ n
, rem
);
2500 isl_seq_clr(c
+ rem
, n
);
2503 /* Drop n dimensions starting at first.
2505 * In principle, this frees up some extra variables as the number
2506 * of columns remains constant, but we would have to extend
2507 * the div array too as the number of rows in this array is assumed
2508 * to be equal to extra.
2510 __isl_give isl_basic_set
*isl_basic_set_drop_dims(
2511 __isl_take isl_basic_set
*bset
, unsigned first
, unsigned n
)
2513 return isl_basic_map_drop(bset_to_bmap(bset
), isl_dim_set
, first
, n
);
2516 /* Move "n" divs starting at "first" to the end of the list of divs.
2518 static __isl_give isl_basic_map
*move_divs_last(__isl_take isl_basic_map
*bmap
,
2519 unsigned first
, unsigned n
)
2524 if (first
+ n
== bmap
->n_div
)
2527 div
= isl_alloc_array(bmap
->ctx
, isl_int
*, n
);
2530 for (i
= 0; i
< n
; ++i
)
2531 div
[i
] = bmap
->div
[first
+ i
];
2532 for (i
= 0; i
< bmap
->n_div
- first
- n
; ++i
)
2533 bmap
->div
[first
+ i
] = bmap
->div
[first
+ n
+ i
];
2534 for (i
= 0; i
< n
; ++i
)
2535 bmap
->div
[bmap
->n_div
- n
+ i
] = div
[i
];
2539 isl_basic_map_free(bmap
);
2544 #define TYPE isl_map
2546 #include "check_type_range_templ.c"
2548 /* Check that there are "n" dimensions of type "type" starting at "first"
2551 isl_stat
isl_set_check_range(__isl_keep isl_set
*set
,
2552 enum isl_dim_type type
, unsigned first
, unsigned n
)
2554 return isl_map_check_range(set_to_map(set
), type
, first
, n
);
2557 /* Drop "n" dimensions of type "type" starting at "first".
2558 * Perform the core computation, without cowing or
2559 * simplifying and finalizing the result.
2561 * In principle, this frees up some extra variables as the number
2562 * of columns remains constant, but we would have to extend
2563 * the div array too as the number of rows in this array is assumed
2564 * to be equal to extra.
2566 __isl_give isl_basic_map
*isl_basic_map_drop_core(
2567 __isl_take isl_basic_map
*bmap
, enum isl_dim_type type
,
2568 unsigned first
, unsigned n
)
2575 if (isl_basic_map_check_range(bmap
, type
, first
, n
) < 0)
2576 return isl_basic_map_free(bmap
);
2578 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
2580 return isl_basic_map_free(bmap
);
2582 offset
= isl_basic_map_offset(bmap
, type
) + first
;
2583 left
= total
- (offset
- 1) - n
;
2584 for (i
= 0; i
< bmap
->n_eq
; ++i
)
2585 constraint_drop_vars(bmap
->eq
[i
]+offset
, n
, left
);
2587 for (i
= 0; i
< bmap
->n_ineq
; ++i
)
2588 constraint_drop_vars(bmap
->ineq
[i
]+offset
, n
, left
);
2590 for (i
= 0; i
< bmap
->n_div
; ++i
)
2591 constraint_drop_vars(bmap
->div
[i
]+1+offset
, n
, left
);
2593 if (type
== isl_dim_div
) {
2594 bmap
= move_divs_last(bmap
, first
, n
);
2597 if (isl_basic_map_free_div(bmap
, n
) < 0)
2598 return isl_basic_map_free(bmap
);
2600 bmap
->dim
= isl_space_drop_dims(bmap
->dim
, type
, first
, n
);
2602 return isl_basic_map_free(bmap
);
2604 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NO_REDUNDANT
);
2605 ISL_F_CLR(bmap
, ISL_BASIC_MAP_SORTED
);
2606 ISL_F_CLR(bmap
, ISL_BASIC_MAP_REDUCED_COEFFICIENTS
);
2610 /* Drop "n" dimensions of type "type" starting at "first".
2612 * In principle, this frees up some extra variables as the number
2613 * of columns remains constant, but we would have to extend
2614 * the div array too as the number of rows in this array is assumed
2615 * to be equal to extra.
2617 __isl_give isl_basic_map
*isl_basic_map_drop(__isl_take isl_basic_map
*bmap
,
2618 enum isl_dim_type type
, unsigned first
, unsigned n
)
2622 if (n
== 0 && !isl_space_is_named_or_nested(bmap
->dim
, type
))
2625 bmap
= isl_basic_map_cow(bmap
);
2629 bmap
= isl_basic_map_drop_core(bmap
, type
, first
, n
);
2631 bmap
= isl_basic_map_simplify(bmap
);
2632 return isl_basic_map_finalize(bmap
);
2635 __isl_give isl_basic_set
*isl_basic_set_drop(__isl_take isl_basic_set
*bset
,
2636 enum isl_dim_type type
, unsigned first
, unsigned n
)
2638 return bset_from_bmap(isl_basic_map_drop(bset_to_bmap(bset
),
2642 /* No longer consider "map" to be normalized.
2644 static __isl_give isl_map
*isl_map_unmark_normalized(__isl_take isl_map
*map
)
2648 ISL_F_CLR(map
, ISL_MAP_NORMALIZED
);
2652 __isl_give isl_map
*isl_map_drop(__isl_take isl_map
*map
,
2653 enum isl_dim_type type
, unsigned first
, unsigned n
)
2658 if (isl_map_check_range(map
, type
, first
, n
) < 0)
2659 return isl_map_free(map
);
2661 if (n
== 0 && !isl_space_is_named_or_nested(map
->dim
, type
))
2663 map
= isl_map_cow(map
);
2667 for (i
= 0; i
< map
->n
; ++i
) {
2668 map
->p
[i
] = isl_basic_map_drop(map
->p
[i
], type
, first
, n
);
2672 map
= isl_map_unmark_normalized(map
);
2674 space
= isl_map_take_space(map
);
2675 space
= isl_space_drop_dims(space
, type
, first
, n
);
2676 map
= isl_map_restore_space(map
, space
);
2684 __isl_give isl_set
*isl_set_drop(__isl_take isl_set
*set
,
2685 enum isl_dim_type type
, unsigned first
, unsigned n
)
2687 return set_from_map(isl_map_drop(set_to_map(set
), type
, first
, n
));
2690 /* Drop the integer division at position "div", which is assumed
2691 * not to appear in any of the constraints or
2692 * in any of the other integer divisions.
2694 * Since the integer division is redundant, there is no need to cow.
2696 __isl_give isl_basic_map
*isl_basic_map_drop_div(
2697 __isl_take isl_basic_map
*bmap
, unsigned div
)
2699 return isl_basic_map_drop_core(bmap
, isl_dim_div
, div
, 1);
2702 /* Eliminate the specified n dimensions starting at first from the
2703 * constraints, without removing the dimensions from the space.
2704 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2706 __isl_give isl_map
*isl_map_eliminate(__isl_take isl_map
*map
,
2707 enum isl_dim_type type
, unsigned first
, unsigned n
)
2714 if (isl_map_check_range(map
, type
, first
, n
) < 0)
2715 return isl_map_free(map
);
2717 map
= isl_map_cow(map
);
2721 for (i
= 0; i
< map
->n
; ++i
) {
2722 map
->p
[i
] = isl_basic_map_eliminate(map
->p
[i
], type
, first
, n
);
2732 /* Eliminate the specified n dimensions starting at first from the
2733 * constraints, without removing the dimensions from the space.
2734 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2736 __isl_give isl_set
*isl_set_eliminate(__isl_take isl_set
*set
,
2737 enum isl_dim_type type
, unsigned first
, unsigned n
)
2739 return set_from_map(isl_map_eliminate(set_to_map(set
), type
, first
, n
));
2742 /* Eliminate the specified n dimensions starting at first from the
2743 * constraints, without removing the dimensions from the space.
2744 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2746 __isl_give isl_set
*isl_set_eliminate_dims(__isl_take isl_set
*set
,
2747 unsigned first
, unsigned n
)
2749 return isl_set_eliminate(set
, isl_dim_set
, first
, n
);
2752 __isl_give isl_basic_map
*isl_basic_map_remove_divs(
2753 __isl_take isl_basic_map
*bmap
)
2757 v_div
= isl_basic_map_var_offset(bmap
, isl_dim_div
);
2759 return isl_basic_map_free(bmap
);
2760 bmap
= isl_basic_map_eliminate_vars(bmap
, v_div
, bmap
->n_div
);
2764 return isl_basic_map_finalize(bmap
);
2767 __isl_give isl_basic_set
*isl_basic_set_remove_divs(
2768 __isl_take isl_basic_set
*bset
)
2770 return bset_from_bmap(isl_basic_map_remove_divs(bset_to_bmap(bset
)));
2773 __isl_give isl_map
*isl_map_remove_divs(__isl_take isl_map
*map
)
2782 map
= isl_map_cow(map
);
2786 for (i
= 0; i
< map
->n
; ++i
) {
2787 map
->p
[i
] = isl_basic_map_remove_divs(map
->p
[i
]);
2797 __isl_give isl_set
*isl_set_remove_divs(__isl_take isl_set
*set
)
2799 return isl_map_remove_divs(set
);
2802 __isl_give isl_basic_map
*isl_basic_map_remove_dims(
2803 __isl_take isl_basic_map
*bmap
, enum isl_dim_type type
,
2804 unsigned first
, unsigned n
)
2806 if (isl_basic_map_check_range(bmap
, type
, first
, n
) < 0)
2807 return isl_basic_map_free(bmap
);
2808 if (n
== 0 && !isl_space_is_named_or_nested(bmap
->dim
, type
))
2810 bmap
= isl_basic_map_eliminate_vars(bmap
,
2811 isl_basic_map_offset(bmap
, type
) - 1 + first
, n
);
2814 if (ISL_F_ISSET(bmap
, ISL_BASIC_MAP_EMPTY
) && type
== isl_dim_div
)
2816 bmap
= isl_basic_map_drop(bmap
, type
, first
, n
);
2820 /* Does the local variable "div" of "bmap" have a known expression
2821 * that involves the "n" variables starting at "first"?
2823 isl_bool
isl_basic_map_div_expr_involves_vars(__isl_keep isl_basic_map
*bmap
,
2824 int div
, unsigned first
, unsigned n
)
2828 unknown
= isl_basic_map_div_is_marked_unknown(bmap
, div
);
2829 if (unknown
< 0 || unknown
)
2830 return isl_bool_not(unknown
);
2831 if (isl_seq_first_non_zero(bmap
->div
[div
] + 1 + 1 + first
, n
) >= 0)
2832 return isl_bool_true
;
2834 return isl_bool_false
;
2837 /* Return true if the definition of the given div (recursively) involves
2838 * any of the given variables.
2840 static isl_bool
div_involves_vars(__isl_keep isl_basic_map
*bmap
, int div
,
2841 unsigned first
, unsigned n
)
2845 isl_size n_div
, v_div
;
2847 involves
= isl_basic_map_div_expr_involves_vars(bmap
, div
, first
, n
);
2848 if (involves
< 0 || involves
)
2851 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
2852 v_div
= isl_basic_map_var_offset(bmap
, isl_dim_div
);
2853 if (n_div
< 0 || v_div
< 0)
2854 return isl_bool_error
;
2855 for (i
= n_div
- 1; i
>= 0; --i
) {
2858 if (isl_int_is_zero(bmap
->div
[div
][1 + 1 + v_div
+ i
]))
2860 involves
= div_involves_vars(bmap
, i
, first
, n
);
2861 if (involves
< 0 || involves
)
2865 return isl_bool_false
;
2868 /* Does the definition of any integer division involve
2869 * any of the given variables?
2871 isl_bool
isl_basic_map_any_div_involves_vars(__isl_keep isl_basic_map
*bmap
,
2872 unsigned first
, unsigned n
)
2877 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
2879 return isl_bool_error
;
2881 for (i
= 0; i
< n_div
; ++i
) {
2884 has
= isl_basic_map_div_expr_involves_vars(bmap
, i
, first
, n
);
2889 return isl_bool_false
;
2892 /* Try and add a lower and/or upper bound on "div" to "bmap"
2893 * based on inequality "i".
2894 * "total" is the total number of variables (excluding the divs).
2895 * "v" is a temporary object that can be used during the calculations.
2896 * If "lb" is set, then a lower bound should be constructed.
2897 * If "ub" is set, then an upper bound should be constructed.
2899 * The calling function has already checked that the inequality does not
2900 * reference "div", but we still need to check that the inequality is
2901 * of the right form. We'll consider the case where we want to construct
2902 * a lower bound. The construction of upper bounds is similar.
2904 * Let "div" be of the form
2906 * q = floor((a + f(x))/d)
2908 * We essentially check if constraint "i" is of the form
2912 * so that we can use it to derive a lower bound on "div".
2913 * However, we allow a slightly more general form
2917 * with the condition that the coefficients of g(x) - f(x) are all
2919 * Rewriting this constraint as
2923 * adding a + f(x) to both sides and dividing by d, we obtain
2925 * (a + f(x))/d >= (a-b)/d + (f(x)-g(x))/d
2927 * Taking the floor on both sides, we obtain
2929 * q >= floor((a-b)/d) + (f(x)-g(x))/d
2933 * (g(x)-f(x))/d + ceil((b-a)/d) + q >= 0
2935 * In the case of an upper bound, we construct the constraint
2937 * (g(x)+f(x))/d + floor((b+a)/d) - q >= 0
2940 static __isl_give isl_basic_map
*insert_bounds_on_div_from_ineq(
2941 __isl_take isl_basic_map
*bmap
, int div
, int i
,
2942 unsigned total
, isl_int v
, int lb
, int ub
)
2946 for (j
= 0; (lb
|| ub
) && j
< total
+ bmap
->n_div
; ++j
) {
2948 isl_int_sub(v
, bmap
->ineq
[i
][1 + j
],
2949 bmap
->div
[div
][1 + 1 + j
]);
2950 lb
= isl_int_is_divisible_by(v
, bmap
->div
[div
][0]);
2953 isl_int_add(v
, bmap
->ineq
[i
][1 + j
],
2954 bmap
->div
[div
][1 + 1 + j
]);
2955 ub
= isl_int_is_divisible_by(v
, bmap
->div
[div
][0]);
2961 bmap
= isl_basic_map_cow(bmap
);
2962 bmap
= isl_basic_map_extend_constraints(bmap
, 0, lb
+ ub
);
2964 int k
= isl_basic_map_alloc_inequality(bmap
);
2967 for (j
= 0; j
< 1 + total
+ bmap
->n_div
; ++j
) {
2968 isl_int_sub(bmap
->ineq
[k
][j
], bmap
->ineq
[i
][j
],
2969 bmap
->div
[div
][1 + j
]);
2970 isl_int_cdiv_q(bmap
->ineq
[k
][j
],
2971 bmap
->ineq
[k
][j
], bmap
->div
[div
][0]);
2973 isl_int_set_si(bmap
->ineq
[k
][1 + total
+ div
], 1);
2976 int k
= isl_basic_map_alloc_inequality(bmap
);
2979 for (j
= 0; j
< 1 + total
+ bmap
->n_div
; ++j
) {
2980 isl_int_add(bmap
->ineq
[k
][j
], bmap
->ineq
[i
][j
],
2981 bmap
->div
[div
][1 + j
]);
2982 isl_int_fdiv_q(bmap
->ineq
[k
][j
],
2983 bmap
->ineq
[k
][j
], bmap
->div
[div
][0]);
2985 isl_int_set_si(bmap
->ineq
[k
][1 + total
+ div
], -1);
2990 isl_basic_map_free(bmap
);
2994 /* This function is called right before "div" is eliminated from "bmap"
2995 * using Fourier-Motzkin.
2996 * Look through the constraints of "bmap" for constraints on the argument
2997 * of the integer division and use them to construct constraints on the
2998 * integer division itself. These constraints can then be combined
2999 * during the Fourier-Motzkin elimination.
3000 * Note that it is only useful to introduce lower bounds on "div"
3001 * if "bmap" already contains upper bounds on "div" as the newly
3002 * introduce lower bounds can then be combined with the pre-existing
3003 * upper bounds. Similarly for upper bounds.
3004 * We therefore first check if "bmap" contains any lower and/or upper bounds
3007 * It is interesting to note that the introduction of these constraints
3008 * can indeed lead to more accurate results, even when compared to
3009 * deriving constraints on the argument of "div" from constraints on "div".
3010 * Consider, for example, the set
3012 * { [i,j,k] : 3 + i + 2j >= 0 and 2 * [(i+2j)/4] <= k }
3014 * The second constraint can be rewritten as
3016 * 2 * [(-i-2j+3)/4] + k >= 0
3018 * from which we can derive
3020 * -i - 2j + 3 >= -2k
3026 * Combined with the first constraint, we obtain
3028 * -3 <= 3 + 2k or k >= -3
3030 * If, on the other hand we derive a constraint on [(i+2j)/4] from
3031 * the first constraint, we obtain
3033 * [(i + 2j)/4] >= [-3/4] = -1
3035 * Combining this constraint with the second constraint, we obtain
3039 static __isl_give isl_basic_map
*insert_bounds_on_div(
3040 __isl_take isl_basic_map
*bmap
, int div
)
3043 int check_lb
, check_ub
;
3050 if (isl_int_is_zero(bmap
->div
[div
][0]))
3053 v_div
= isl_basic_map_var_offset(bmap
, isl_dim_div
);
3055 return isl_basic_map_free(bmap
);
3059 for (i
= 0; (!check_lb
|| !check_ub
) && i
< bmap
->n_ineq
; ++i
) {
3060 int s
= isl_int_sgn(bmap
->ineq
[i
][1 + v_div
+ div
]);
3067 if (!check_lb
&& !check_ub
)
3072 for (i
= 0; bmap
&& i
< bmap
->n_ineq
; ++i
) {
3073 if (!isl_int_is_zero(bmap
->ineq
[i
][1 + v_div
+ div
]))
3076 bmap
= insert_bounds_on_div_from_ineq(bmap
, div
, i
, v_div
, v
,
3077 check_lb
, check_ub
);
3085 /* Remove all divs (recursively) involving any of the given variables
3086 * in their definitions.
3088 static __isl_give isl_basic_map
*remove_divs_involving_vars(
3089 __isl_take isl_basic_map
*bmap
, unsigned first
, unsigned n
)
3093 for (i
= bmap
->n_div
- 1; i
>= 0; --i
) {
3096 involves
= div_involves_vars(bmap
, i
, first
, n
);
3098 return isl_basic_map_free(bmap
);
3101 bmap
= insert_bounds_on_div(bmap
, i
);
3102 bmap
= isl_basic_map_remove_dims(bmap
, isl_dim_div
, i
, 1);
3111 /* Data structure for communicating data between detect_mod and
3112 * substitute_div_mod.
3114 * "pos" is the position of the variable that is being examined.
3116 * "lower_f" is the index of the constraint
3117 * -f(x) + m i + t m n h(alpha) >= 0
3118 * "lower_g" is the index of the constraint
3120 * "m" and "n" correspond to the values in the first constraint.
3121 * "sum" is a temporary variable that is used internally inside detect_mod.
3123 struct isl_detect_mod_data
{
3135 /* Initialize "data".
3137 static void isl_detect_mod_data_init(struct isl_detect_mod_data
*data
)
3139 isl_int_init(data
->m
);
3140 isl_int_init(data
->n
);
3141 isl_int_init(data
->sum
);
3144 /* Free any memory allocated by "data".
3146 static void isl_detect_mod_data_clear(struct isl_detect_mod_data
*data
)
3148 isl_int_clear(data
->sum
);
3149 isl_int_clear(data
->n
);
3150 isl_int_clear(data
->m
);
3153 /* Is the variable at position data->pos
3154 * equal to a specific case of a nested modulo?
3156 * In particular, look for two pairs of constraints
3158 * -f(x) + m i + t m n h(alpha) >= 0
3159 * f(x) - m i - t m n h(alpha) + c >= 0
3166 * where f(x) and g(x) are expressions in the other variables,
3167 * excluding local variables,
3168 * h(alpha) is a non-zero expression in the local variable,
3173 * If these pairs of constraints are found,
3174 * then store the constraint index of the first f-constraint in data->lower_f,
3175 * the index of the first g-constraint in data->lower_g and
3176 * the values m and n in data->m and data->n.
3178 * The constraints are assumed to have been sorted,
3179 * which means that the constraints in a pair are close to each other.
3180 * The sorting also means that the f-constraints appear
3181 * after the g-constraints.
3183 static isl_bool
detect_mod(__isl_keep isl_basic_map
*bmap
,
3184 struct isl_detect_mod_data
*data
)
3189 isl_size v_div
, n_div
, total
;
3191 n_ineq
= isl_basic_map_n_inequality(bmap
);
3192 v_div
= isl_basic_map_var_offset(bmap
, isl_dim_div
);
3193 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
3194 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
3195 if (n_ineq
< 0 || v_div
< 0 || n_div
< 0 || total
< 0)
3196 return isl_bool_error
;
3198 return isl_bool_false
;
3200 for (i
= n_ineq
- 1; i
>= 1; --i
) {
3201 isl_seq_gcd(bmap
->ineq
[i
] + 1 + v_div
, n_div
, &data
->n
);
3202 if (isl_int_is_zero(data
->n
))
3203 return isl_bool_false
;
3204 isl_int_abs(data
->m
, bmap
->ineq
[i
][1 + data
->pos
]);
3205 j
= find_earlier_constraint_in_pair(bmap
, i
, data
->pos
, total
,
3206 data
->m
, &data
->sum
);
3208 return isl_bool_error
;
3211 if (!isl_int_is_divisible_by(data
->n
, data
->m
))
3213 if (isl_int_is_pos(bmap
->ineq
[i
][1 + data
->pos
]))
3217 isl_int_divexact(data
->n
, data
->n
, data
->m
);
3218 isl_int_abs(data
->n
, data
->n
);
3222 return isl_bool_false
;
3223 for (i
= j
- 1; i
>= 1; --i
) {
3226 f
= isl_seq_first_non_zero(bmap
->ineq
[i
] + 1 + v_div
, n_div
);
3229 if (!isl_int_is_one(bmap
->ineq
[i
][1 + data
->pos
]) &&
3230 !isl_int_is_negone(bmap
->ineq
[i
][1 + data
->pos
]))
3232 j
= find_earlier_constraint_in_pair(bmap
, i
, data
->pos
, v_div
,
3233 data
->m
, &data
->sum
);
3235 return isl_bool_error
;
3238 if (isl_int_is_pos(bmap
->ineq
[i
][1 + data
->pos
]))
3245 return isl_bool_false
;
3246 return isl_bool_true
;
3249 /* Given that inequality "ineq" of "bset" expresses a lower bound
3250 * on the variable at position "pos" in terms of the other variables,
3251 * extract this lower bound as a function of those other variables,
3252 * excluding any local variables.
3254 static __isl_give isl_aff
*extract_lower_bound_aff(
3255 __isl_keep isl_basic_set
*bset
, int ineq
, int pos
)
3261 isl_local_space
*ls
;
3263 space
= isl_basic_set_peek_space(bset
);
3264 dim
= isl_space_dim(space
, isl_dim_all
);
3267 ls
= isl_local_space_from_space(isl_space_copy(space
));
3268 ctx
= isl_basic_set_get_ctx(bset
);
3269 v
= extract_bound_from_constraint(ctx
, bset
->ineq
[ineq
], dim
, pos
);
3270 return isl_aff_alloc_vec(ls
, v
);
3273 /* Given that there are two pairs of constraints
3275 * -f(x) + m i + t m n h(alpha) >= 0
3276 * f(x) - m i - t m n h(alpha) + c >= 0
3283 * where f(x) and g(x) are expressions in the other variables,
3284 * excluding local variables,
3285 * h(alpha) is a non-zero expression in the local variable,
3289 * derive an expression for i and plug that into "bmap".
3291 * In particular, the first pair of constraints implies
3293 * 0 <= (-f(x) + m i) % (m n) <= c
3294 * 0 <= (m floor(-f(x)/m) + (-f(x)) mod m + m i) % (m n) <= c
3295 * 0 <= (m floor(-f(x)/m) + m i) % (m n) + (-f(x)) mod m <= c
3296 * 0 <= m ((floor(-f(x)/m) + i) % n) + (-f(x)) mod m <= c
3300 * (floor(-f(x)/m) + i) % n = 0
3302 * because c < m, which can be rewritten to
3304 * (floor(-f(x)/m) + g(x) - g(x) + i) % n = 0
3308 * (-g(x) + i) % n = (-floor(-f(x)/m) - g(x)) % n
3310 * Since 0 <= -g(x) + i <= d < n,
3312 * -g(x) + i = (-floor(-f(x)/m) - g(x)) % n
3316 * i = (-floor(-f(x)/m) - g(x)) % n + g(x)
3318 * Note that the lower bounds on i derived from the original constraints are
3323 * (ignoring local variables).
3325 * The expression for i is plugged into "bmap", which results
3326 * in a basic map equivalent to "bmap" given i is equal to the expression,
3327 * so an equality constraint is added to ensure the meaning is preserved.
3329 static __isl_give isl_basic_map
*substitute_div_mod(
3330 __isl_take isl_basic_map
*bmap
, unsigned pos
,
3331 struct isl_detect_mod_data
*data
)
3334 isl_basic_set
*bset
, *eq
;
3336 isl_aff
*g
, *f
, *aff
, *it
;
3341 v_in
= isl_basic_map_var_offset(bmap
, isl_dim_in
);
3343 return isl_basic_map_free(bmap
);
3345 ctx
= isl_basic_map_get_ctx(bmap
);
3346 bset
= isl_basic_map_wrap(bmap
);
3347 space
= isl_basic_set_get_space(bset
);
3348 g
= extract_lower_bound_aff(bset
, data
->lower_g
, pos
);
3349 f
= extract_lower_bound_aff(bset
, data
->lower_f
, pos
);
3350 ma
= isl_space_identity_multi_aff_on_domain(space
);
3351 aff
= isl_aff_neg(isl_aff_floor(isl_aff_neg(f
)));
3352 aff
= isl_aff_sub(aff
, isl_aff_copy(g
));
3353 v
= isl_val_int_from_isl_int(ctx
, data
->n
);
3354 aff
= isl_aff_mod_val(aff
, v
);
3355 aff
= isl_aff_add(aff
, g
);
3356 it
= isl_multi_aff_get_at(ma
, pos
- v_in
);
3357 eq
= isl_aff_eq_basic_set(it
, isl_aff_copy(aff
));
3358 ma
= isl_multi_aff_set_at(ma
, pos
- v_in
, aff
);
3359 bset
= isl_basic_set_preimage_multi_aff(bset
, ma
);
3360 bset
= isl_basic_set_intersect(bset
, eq
);
3361 return isl_basic_set_unwrap(bset
);
3364 /* Remove all divs (recursively) involving any of the given dimensions
3365 * in their definitions.
3367 * If it is a single input or output dimension that
3368 * should not appear in any integer division expression and
3369 * if there is indeed an integer division expression
3370 * involving that dimension, then check if there are any constraints
3371 * that imply that the given dimension is equal to some expression
3372 * in the other dimensions.
3373 * If so, plug in that expression for the given dimension
3374 * so that the integer division expressions no longer
3375 * involve that dimension.
3377 __isl_give isl_basic_map
*isl_basic_map_remove_divs_involving_dims(
3378 __isl_take isl_basic_map
*bmap
,
3379 enum isl_dim_type type
, unsigned first
, unsigned n
)
3384 struct isl_detect_mod_data data
;
3386 if (isl_basic_map_check_range(bmap
, type
, first
, n
) < 0)
3387 return isl_basic_map_free(bmap
);
3388 off
= isl_basic_map_var_offset(bmap
, type
);
3390 return isl_basic_map_free(bmap
);
3393 if (type
== isl_dim_param
|| type
== isl_dim_div
|| n
!= 1)
3394 return remove_divs_involving_vars(bmap
, first
, n
);
3395 used
= isl_basic_map_any_div_involves_vars(bmap
, first
, n
);
3397 return isl_basic_map_free(bmap
);
3400 bmap
= isl_basic_map_sort_constraints(bmap
);
3401 isl_detect_mod_data_init(&data
);
3403 found
= detect_mod(bmap
, &data
);
3405 bmap
= remove_divs_involving_vars(bmap
, first
, n
);
3407 bmap
= substitute_div_mod(bmap
, first
, &data
);
3408 isl_detect_mod_data_clear(&data
);
3412 __isl_give isl_basic_set
*isl_basic_set_remove_divs_involving_dims(
3413 __isl_take isl_basic_set
*bset
,
3414 enum isl_dim_type type
, unsigned first
, unsigned n
)
3416 return isl_basic_map_remove_divs_involving_dims(bset
, type
, first
, n
);
3419 __isl_give isl_map
*isl_map_remove_divs_involving_dims(__isl_take isl_map
*map
,
3420 enum isl_dim_type type
, unsigned first
, unsigned n
)
3429 map
= isl_map_cow(map
);
3433 for (i
= 0; i
< map
->n
; ++i
) {
3434 map
->p
[i
] = isl_basic_map_remove_divs_involving_dims(map
->p
[i
],
3445 __isl_give isl_set
*isl_set_remove_divs_involving_dims(__isl_take isl_set
*set
,
3446 enum isl_dim_type type
, unsigned first
, unsigned n
)
3448 return set_from_map(isl_map_remove_divs_involving_dims(set_to_map(set
),
3452 /* Does the description of "bmap" depend on the specified dimensions?
3453 * We also check whether the dimensions appear in any of the div definitions.
3454 * In principle there is no need for this check. If the dimensions appear
3455 * in a div definition, they also appear in the defining constraints of that
3458 isl_bool
isl_basic_map_involves_dims(__isl_keep isl_basic_map
*bmap
,
3459 enum isl_dim_type type
, unsigned first
, unsigned n
)
3463 if (isl_basic_map_check_range(bmap
, type
, first
, n
) < 0)
3464 return isl_bool_error
;
3466 first
+= isl_basic_map_offset(bmap
, type
);
3467 for (i
= 0; i
< bmap
->n_eq
; ++i
)
3468 if (isl_seq_first_non_zero(bmap
->eq
[i
] + first
, n
) >= 0)
3469 return isl_bool_true
;
3470 for (i
= 0; i
< bmap
->n_ineq
; ++i
)
3471 if (isl_seq_first_non_zero(bmap
->ineq
[i
] + first
, n
) >= 0)
3472 return isl_bool_true
;
3473 for (i
= 0; i
< bmap
->n_div
; ++i
) {
3474 if (isl_int_is_zero(bmap
->div
[i
][0]))
3476 if (isl_seq_first_non_zero(bmap
->div
[i
] + 1 + first
, n
) >= 0)
3477 return isl_bool_true
;
3480 return isl_bool_false
;
3483 isl_bool
isl_map_involves_dims(__isl_keep isl_map
*map
,
3484 enum isl_dim_type type
, unsigned first
, unsigned n
)
3488 if (isl_map_check_range(map
, type
, first
, n
) < 0)
3489 return isl_bool_error
;
3491 for (i
= 0; i
< map
->n
; ++i
) {
3492 isl_bool involves
= isl_basic_map_involves_dims(map
->p
[i
],
3494 if (involves
< 0 || involves
)
3498 return isl_bool_false
;
3501 isl_bool
isl_basic_set_involves_dims(__isl_keep isl_basic_set
*bset
,
3502 enum isl_dim_type type
, unsigned first
, unsigned n
)
3504 return isl_basic_map_involves_dims(bset
, type
, first
, n
);
3507 isl_bool
isl_set_involves_dims(__isl_keep isl_set
*set
,
3508 enum isl_dim_type type
, unsigned first
, unsigned n
)
3510 return isl_map_involves_dims(set
, type
, first
, n
);
3513 /* Does "bset" involve any local variables, i.e., integer divisions?
3515 static isl_bool
isl_basic_set_involves_locals(__isl_keep isl_basic_set
*bset
)
3519 n
= isl_basic_set_dim(bset
, isl_dim_div
);
3521 return isl_bool_error
;
3522 return isl_bool_ok(n
> 0);
3525 /* isl_set_every_basic_set callback that checks whether "bset"
3526 * is free of local variables.
3528 static isl_bool
basic_set_no_locals(__isl_keep isl_basic_set
*bset
, void *user
)
3530 return isl_bool_not(isl_basic_set_involves_locals(bset
));
3533 /* Does "set" involve any local variables, i.e., integer divisions?
3535 isl_bool
isl_set_involves_locals(__isl_keep isl_set
*set
)
3539 no_locals
= isl_set_every_basic_set(set
, &basic_set_no_locals
, NULL
);
3540 return isl_bool_not(no_locals
);
3543 /* Drop all constraints in bmap that involve any of the dimensions
3544 * first to first+n-1.
3545 * This function only performs the actual removal of constraints.
3547 * This function should not call finalize since it is used by
3548 * remove_redundant_divs, which in turn is called by isl_basic_map_finalize.
3550 __isl_give isl_basic_map
*isl_basic_map_drop_constraints_involving(
3551 __isl_take isl_basic_map
*bmap
, unsigned first
, unsigned n
)
3558 bmap
= isl_basic_map_cow(bmap
);
3563 for (i
= bmap
->n_eq
- 1; i
>= 0; --i
) {
3564 if (isl_seq_first_non_zero(bmap
->eq
[i
] + 1 + first
, n
) == -1)
3566 if (isl_basic_map_drop_equality(bmap
, i
) < 0)
3567 return isl_basic_map_free(bmap
);
3570 for (i
= bmap
->n_ineq
- 1; i
>= 0; --i
) {
3571 if (isl_seq_first_non_zero(bmap
->ineq
[i
] + 1 + first
, n
) == -1)
3573 if (isl_basic_map_drop_inequality(bmap
, i
) < 0)
3574 return isl_basic_map_free(bmap
);
3580 /* Drop all constraints in bset that involve any of the dimensions
3581 * first to first+n-1.
3582 * This function only performs the actual removal of constraints.
3584 __isl_give isl_basic_set
*isl_basic_set_drop_constraints_involving(
3585 __isl_take isl_basic_set
*bset
, unsigned first
, unsigned n
)
3587 return isl_basic_map_drop_constraints_involving(bset
, first
, n
);
3590 /* Drop all constraints in bmap that do not involve any of the dimensions
3591 * first to first + n - 1 of the given type.
3593 __isl_give isl_basic_map
*isl_basic_map_drop_constraints_not_involving_dims(
3594 __isl_take isl_basic_map
*bmap
,
3595 enum isl_dim_type type
, unsigned first
, unsigned n
)
3600 isl_space
*space
= isl_basic_map_get_space(bmap
);
3601 isl_basic_map_free(bmap
);
3602 return isl_basic_map_universe(space
);
3604 bmap
= isl_basic_map_cow(bmap
);
3608 if (isl_basic_map_check_range(bmap
, type
, first
, n
) < 0)
3609 return isl_basic_map_free(bmap
);
3611 first
+= isl_basic_map_offset(bmap
, type
) - 1;
3613 for (i
= bmap
->n_eq
- 1; i
>= 0; --i
) {
3614 if (isl_seq_first_non_zero(bmap
->eq
[i
] + 1 + first
, n
) != -1)
3616 if (isl_basic_map_drop_equality(bmap
, i
) < 0)
3617 return isl_basic_map_free(bmap
);
3620 for (i
= bmap
->n_ineq
- 1; i
>= 0; --i
) {
3621 if (isl_seq_first_non_zero(bmap
->ineq
[i
] + 1 + first
, n
) != -1)
3623 if (isl_basic_map_drop_inequality(bmap
, i
) < 0)
3624 return isl_basic_map_free(bmap
);
3627 bmap
= isl_basic_map_add_known_div_constraints(bmap
);
3631 /* Drop all constraints in bset that do not involve any of the dimensions
3632 * first to first + n - 1 of the given type.
3634 __isl_give isl_basic_set
*isl_basic_set_drop_constraints_not_involving_dims(
3635 __isl_take isl_basic_set
*bset
,
3636 enum isl_dim_type type
, unsigned first
, unsigned n
)
3638 return isl_basic_map_drop_constraints_not_involving_dims(bset
,
3642 /* Drop all constraints in bmap that involve any of the dimensions
3643 * first to first + n - 1 of the given type.
3645 __isl_give isl_basic_map
*isl_basic_map_drop_constraints_involving_dims(
3646 __isl_take isl_basic_map
*bmap
,
3647 enum isl_dim_type type
, unsigned first
, unsigned n
)
3654 if (isl_basic_map_check_range(bmap
, type
, first
, n
) < 0)
3655 return isl_basic_map_free(bmap
);
3657 bmap
= isl_basic_map_remove_divs_involving_dims(bmap
, type
, first
, n
);
3658 first
+= isl_basic_map_offset(bmap
, type
) - 1;
3659 bmap
= isl_basic_map_drop_constraints_involving(bmap
, first
, n
);
3660 bmap
= isl_basic_map_add_known_div_constraints(bmap
);
3664 /* Drop all constraints in bset that involve any of the dimensions
3665 * first to first + n - 1 of the given type.
3667 __isl_give isl_basic_set
*isl_basic_set_drop_constraints_involving_dims(
3668 __isl_take isl_basic_set
*bset
,
3669 enum isl_dim_type type
, unsigned first
, unsigned n
)
3671 return isl_basic_map_drop_constraints_involving_dims(bset
,
3675 /* Drop constraints from "map" by applying "drop" to each basic map.
3677 static __isl_give isl_map
*drop_constraints(__isl_take isl_map
*map
,
3678 enum isl_dim_type type
, unsigned first
, unsigned n
,
3679 __isl_give isl_basic_map
*(*drop
)(__isl_take isl_basic_map
*bmap
,
3680 enum isl_dim_type type
, unsigned first
, unsigned n
))
3684 if (isl_map_check_range(map
, type
, first
, n
) < 0)
3685 return isl_map_free(map
);
3687 map
= isl_map_cow(map
);
3691 for (i
= 0; i
< map
->n
; ++i
) {
3692 map
->p
[i
] = drop(map
->p
[i
], type
, first
, n
);
3694 return isl_map_free(map
);
3698 ISL_F_CLR(map
, ISL_MAP_DISJOINT
);
3703 /* Drop all constraints in map that involve any of the dimensions
3704 * first to first + n - 1 of the given type.
3706 __isl_give isl_map
*isl_map_drop_constraints_involving_dims(
3707 __isl_take isl_map
*map
,
3708 enum isl_dim_type type
, unsigned first
, unsigned n
)
3712 return drop_constraints(map
, type
, first
, n
,
3713 &isl_basic_map_drop_constraints_involving_dims
);
3716 /* Drop all constraints in "map" that do not involve any of the dimensions
3717 * first to first + n - 1 of the given type.
3719 __isl_give isl_map
*isl_map_drop_constraints_not_involving_dims(
3720 __isl_take isl_map
*map
,
3721 enum isl_dim_type type
, unsigned first
, unsigned n
)
3724 isl_space
*space
= isl_map_get_space(map
);
3726 return isl_map_universe(space
);
3728 return drop_constraints(map
, type
, first
, n
,
3729 &isl_basic_map_drop_constraints_not_involving_dims
);
3732 /* Drop all constraints in set that involve any of the dimensions
3733 * first to first + n - 1 of the given type.
3735 __isl_give isl_set
*isl_set_drop_constraints_involving_dims(
3736 __isl_take isl_set
*set
,
3737 enum isl_dim_type type
, unsigned first
, unsigned n
)
3739 return isl_map_drop_constraints_involving_dims(set
, type
, first
, n
);
3742 /* Drop all constraints in "set" that do not involve any of the dimensions
3743 * first to first + n - 1 of the given type.
3745 __isl_give isl_set
*isl_set_drop_constraints_not_involving_dims(
3746 __isl_take isl_set
*set
,
3747 enum isl_dim_type type
, unsigned first
, unsigned n
)
3749 return isl_map_drop_constraints_not_involving_dims(set
, type
, first
, n
);
3752 /* Does local variable "div" of "bmap" have a complete explicit representation?
3753 * Having a complete explicit representation requires not only
3754 * an explicit representation, but also that all local variables
3755 * that appear in this explicit representation in turn have
3756 * a complete explicit representation.
3758 isl_bool
isl_basic_map_div_is_known(__isl_keep isl_basic_map
*bmap
, int div
)
3761 unsigned div_offset
= isl_basic_map_offset(bmap
, isl_dim_div
);
3764 marked
= isl_basic_map_div_is_marked_unknown(bmap
, div
);
3765 if (marked
< 0 || marked
)
3766 return isl_bool_not(marked
);
3768 for (i
= bmap
->n_div
- 1; i
>= 0; --i
) {
3771 if (isl_int_is_zero(bmap
->div
[div
][1 + div_offset
+ i
]))
3773 known
= isl_basic_map_div_is_known(bmap
, i
);
3774 if (known
< 0 || !known
)
3778 return isl_bool_true
;
3781 /* Remove all divs that are unknown or defined in terms of unknown divs.
3783 __isl_give isl_basic_map
*isl_basic_map_remove_unknown_divs(
3784 __isl_take isl_basic_map
*bmap
)
3791 for (i
= bmap
->n_div
- 1; i
>= 0; --i
) {
3792 if (isl_basic_map_div_is_known(bmap
, i
))
3794 bmap
= isl_basic_map_remove_dims(bmap
, isl_dim_div
, i
, 1);
3803 /* Remove all divs that are unknown or defined in terms of unknown divs.
3805 __isl_give isl_basic_set
*isl_basic_set_remove_unknown_divs(
3806 __isl_take isl_basic_set
*bset
)
3808 return isl_basic_map_remove_unknown_divs(bset
);
3811 __isl_give isl_map
*isl_map_remove_unknown_divs(__isl_take isl_map
*map
)
3820 map
= isl_map_cow(map
);
3824 for (i
= 0; i
< map
->n
; ++i
) {
3825 map
->p
[i
] = isl_basic_map_remove_unknown_divs(map
->p
[i
]);
3835 __isl_give isl_set
*isl_set_remove_unknown_divs(__isl_take isl_set
*set
)
3837 return set_from_map(isl_map_remove_unknown_divs(set_to_map(set
)));
3840 __isl_give isl_basic_set
*isl_basic_set_remove_dims(
3841 __isl_take isl_basic_set
*bset
,
3842 enum isl_dim_type type
, unsigned first
, unsigned n
)
3844 isl_basic_map
*bmap
= bset_to_bmap(bset
);
3845 bmap
= isl_basic_map_remove_dims(bmap
, type
, first
, n
);
3846 return bset_from_bmap(bmap
);
3849 __isl_give isl_map
*isl_map_remove_dims(__isl_take isl_map
*map
,
3850 enum isl_dim_type type
, unsigned first
, unsigned n
)
3857 map
= isl_map_cow(map
);
3858 if (isl_map_check_range(map
, type
, first
, n
) < 0)
3859 return isl_map_free(map
);
3861 for (i
= 0; i
< map
->n
; ++i
) {
3862 map
->p
[i
] = isl_basic_map_eliminate_vars(map
->p
[i
],
3863 isl_basic_map_offset(map
->p
[i
], type
) - 1 + first
, n
);
3867 map
= isl_map_drop(map
, type
, first
, n
);
3874 __isl_give isl_set
*isl_set_remove_dims(__isl_take isl_set
*bset
,
3875 enum isl_dim_type type
, unsigned first
, unsigned n
)
3877 return set_from_map(isl_map_remove_dims(set_to_map(bset
),
3881 /* Project out n inputs starting at first using Fourier-Motzkin */
3882 __isl_give isl_map
*isl_map_remove_inputs(__isl_take isl_map
*map
,
3883 unsigned first
, unsigned n
)
3885 return isl_map_remove_dims(map
, isl_dim_in
, first
, n
);
3888 void isl_basic_set_print_internal(__isl_keep isl_basic_set
*bset
,
3889 FILE *out
, int indent
)
3894 fprintf(out
, "null basic set\n");
3898 fprintf(out
, "%*s", indent
, "");
3899 fprintf(out
, "ref: %d, nparam: %d, dim: %d, extra: %d, flags: %x\n",
3900 bset
->ref
, bset
->dim
->nparam
, bset
->dim
->n_out
,
3901 bset
->extra
, bset
->flags
);
3903 p
= isl_printer_to_file(isl_basic_set_get_ctx(bset
), out
);
3904 p
= isl_printer_set_dump(p
, 1);
3905 p
= isl_printer_set_indent(p
, indent
);
3906 p
= isl_printer_start_line(p
);
3907 p
= isl_printer_print_basic_set(p
, bset
);
3908 p
= isl_printer_end_line(p
);
3909 isl_printer_free(p
);
3912 void isl_basic_map_print_internal(__isl_keep isl_basic_map
*bmap
,
3913 FILE *out
, int indent
)
3918 fprintf(out
, "null basic map\n");
3922 fprintf(out
, "%*s", indent
, "");
3923 fprintf(out
, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "
3924 "flags: %x, n_name: %d\n",
3926 bmap
->dim
->nparam
, bmap
->dim
->n_in
, bmap
->dim
->n_out
,
3927 bmap
->extra
, bmap
->flags
, bmap
->dim
->n_id
);
3929 p
= isl_printer_to_file(isl_basic_map_get_ctx(bmap
), out
);
3930 p
= isl_printer_set_dump(p
, 1);
3931 p
= isl_printer_set_indent(p
, indent
);
3932 p
= isl_printer_start_line(p
);
3933 p
= isl_printer_print_basic_map(p
, bmap
);
3934 p
= isl_printer_end_line(p
);
3935 isl_printer_free(p
);
3938 __isl_give isl_basic_map
*isl_inequality_negate(__isl_take isl_basic_map
*bmap
,
3943 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
3945 return isl_basic_map_free(bmap
);
3946 if (pos
>= bmap
->n_ineq
)
3947 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
3948 "invalid position", return isl_basic_map_free(bmap
));
3949 isl_seq_neg(bmap
->ineq
[pos
], bmap
->ineq
[pos
], 1 + total
);
3950 isl_int_sub_ui(bmap
->ineq
[pos
][0], bmap
->ineq
[pos
][0], 1);
3951 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NO_REDUNDANT
);
3952 ISL_F_CLR(bmap
, ISL_BASIC_MAP_SORTED
);
3956 __isl_give isl_set
*isl_set_alloc_space(__isl_take isl_space
*space
, int n
,
3959 if (isl_space_check_is_set(space
) < 0)
3961 return isl_map_alloc_space(space
, n
, flags
);
3963 isl_space_free(space
);
3967 /* Make sure "map" has room for at least "n" more basic maps.
3969 __isl_give isl_map
*isl_map_grow(__isl_take isl_map
*map
, int n
)
3972 struct isl_map
*grown
= NULL
;
3976 isl_assert(map
->ctx
, n
>= 0, goto error
);
3977 if (map
->n
+ n
<= map
->size
)
3979 grown
= isl_map_alloc_space(isl_map_get_space(map
), map
->n
+ n
, map
->flags
);
3982 for (i
= 0; i
< map
->n
; ++i
) {
3983 grown
->p
[i
] = isl_basic_map_copy(map
->p
[i
]);
3991 isl_map_free(grown
);
3996 /* Make sure "set" has room for at least "n" more basic sets.
3998 __isl_give isl_set
*isl_set_grow(__isl_take isl_set
*set
, int n
)
4000 return set_from_map(isl_map_grow(set_to_map(set
), n
));
4003 __isl_give isl_set
*isl_set_from_basic_set(__isl_take isl_basic_set
*bset
)
4005 return isl_map_from_basic_map(bset
);
4008 /* This function performs the same operation as isl_set_from_basic_set,
4009 * but is considered as a function on an isl_basic_set when exported.
4011 __isl_give isl_set
*isl_basic_set_to_set(__isl_take isl_basic_set
*bset
)
4013 return isl_set_from_basic_set(bset
);
4016 __isl_give isl_map
*isl_map_from_basic_map(__isl_take isl_basic_map
*bmap
)
4018 struct isl_map
*map
;
4023 map
= isl_map_alloc_space(isl_space_copy(bmap
->dim
), 1, ISL_MAP_DISJOINT
);
4024 return isl_map_add_basic_map(map
, bmap
);
4027 __isl_give isl_set
*isl_set_add_basic_set(__isl_take isl_set
*set
,
4028 __isl_take isl_basic_set
*bset
)
4030 return set_from_map(isl_map_add_basic_map(set_to_map(set
),
4031 bset_to_bmap(bset
)));
4034 __isl_null isl_set
*isl_set_free(__isl_take isl_set
*set
)
4036 return isl_map_free(set
);
4039 void isl_set_print_internal(__isl_keep isl_set
*set
, FILE *out
, int indent
)
4044 fprintf(out
, "null set\n");
4048 fprintf(out
, "%*s", indent
, "");
4049 fprintf(out
, "ref: %d, n: %d, nparam: %d, dim: %d, flags: %x\n",
4050 set
->ref
, set
->n
, set
->dim
->nparam
, set
->dim
->n_out
,
4052 for (i
= 0; i
< set
->n
; ++i
) {
4053 fprintf(out
, "%*s", indent
, "");
4054 fprintf(out
, "basic set %d:\n", i
);
4055 isl_basic_set_print_internal(set
->p
[i
], out
, indent
+4);
4059 void isl_map_print_internal(__isl_keep isl_map
*map
, FILE *out
, int indent
)
4064 fprintf(out
, "null map\n");
4068 fprintf(out
, "%*s", indent
, "");
4069 fprintf(out
, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, "
4070 "flags: %x, n_name: %d\n",
4071 map
->ref
, map
->n
, map
->dim
->nparam
, map
->dim
->n_in
,
4072 map
->dim
->n_out
, map
->flags
, map
->dim
->n_id
);
4073 for (i
= 0; i
< map
->n
; ++i
) {
4074 fprintf(out
, "%*s", indent
, "");
4075 fprintf(out
, "basic map %d:\n", i
);
4076 isl_basic_map_print_internal(map
->p
[i
], out
, indent
+4);
4080 /* Check that the space of "bset" is the same as that of the domain of "bmap".
4082 static isl_stat
isl_basic_map_check_compatible_domain(
4083 __isl_keep isl_basic_map
*bmap
, __isl_keep isl_basic_set
*bset
)
4087 ok
= isl_basic_map_compatible_domain(bmap
, bset
);
4089 return isl_stat_error
;
4091 isl_die(isl_basic_set_get_ctx(bset
), isl_error_invalid
,
4092 "incompatible spaces", return isl_stat_error
);
4097 __isl_give isl_basic_map
*isl_basic_map_intersect_domain(
4098 __isl_take isl_basic_map
*bmap
, __isl_take isl_basic_set
*bset
)
4100 struct isl_basic_map
*bmap_domain
;
4103 if (isl_basic_map_check_equal_params(bmap
, bset_to_bmap(bset
)) < 0)
4106 dim
= isl_basic_set_dim(bset
, isl_dim_set
);
4110 isl_basic_map_check_compatible_domain(bmap
, bset
) < 0)
4113 bmap
= isl_basic_map_cow(bmap
);
4116 bmap
= isl_basic_map_extend(bmap
,
4117 bset
->n_div
, bset
->n_eq
, bset
->n_ineq
);
4118 bmap_domain
= isl_basic_map_from_domain(bset
);
4119 bmap
= add_constraints(bmap
, bmap_domain
, 0, 0);
4121 bmap
= isl_basic_map_simplify(bmap
);
4122 return isl_basic_map_finalize(bmap
);
4124 isl_basic_map_free(bmap
);
4125 isl_basic_set_free(bset
);
4129 /* Check that the space of "bset" is the same as that of the range of "bmap".
4131 static isl_stat
isl_basic_map_check_compatible_range(
4132 __isl_keep isl_basic_map
*bmap
, __isl_keep isl_basic_set
*bset
)
4136 ok
= isl_basic_map_compatible_range(bmap
, bset
);
4138 return isl_stat_error
;
4140 isl_die(isl_basic_set_get_ctx(bset
), isl_error_invalid
,
4141 "incompatible spaces", return isl_stat_error
);
4146 __isl_give isl_basic_map
*isl_basic_map_intersect_range(
4147 __isl_take isl_basic_map
*bmap
, __isl_take isl_basic_set
*bset
)
4149 struct isl_basic_map
*bmap_range
;
4152 if (isl_basic_map_check_equal_params(bmap
, bset_to_bmap(bset
)) < 0)
4155 dim
= isl_basic_set_dim(bset
, isl_dim_set
);
4158 if (dim
!= 0 && isl_basic_map_check_compatible_range(bmap
, bset
) < 0)
4161 if (isl_basic_set_plain_is_universe(bset
)) {
4162 isl_basic_set_free(bset
);
4166 bmap
= isl_basic_map_cow(bmap
);
4169 bmap
= isl_basic_map_extend(bmap
,
4170 bset
->n_div
, bset
->n_eq
, bset
->n_ineq
);
4171 bmap_range
= bset_to_bmap(bset
);
4172 bmap
= add_constraints(bmap
, bmap_range
, 0, 0);
4174 bmap
= isl_basic_map_simplify(bmap
);
4175 return isl_basic_map_finalize(bmap
);
4177 isl_basic_map_free(bmap
);
4178 isl_basic_set_free(bset
);
4182 isl_bool
isl_basic_map_contains(__isl_keep isl_basic_map
*bmap
,
4183 __isl_keep isl_vec
*vec
)
4189 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
4190 if (total
< 0 || !vec
)
4191 return isl_bool_error
;
4193 if (1 + total
!= vec
->size
)
4194 return isl_bool_false
;
4198 for (i
= 0; i
< bmap
->n_eq
; ++i
) {
4199 isl_seq_inner_product(vec
->el
, bmap
->eq
[i
], 1 + total
, &s
);
4200 if (!isl_int_is_zero(s
)) {
4202 return isl_bool_false
;
4206 for (i
= 0; i
< bmap
->n_ineq
; ++i
) {
4207 isl_seq_inner_product(vec
->el
, bmap
->ineq
[i
], 1 + total
, &s
);
4208 if (isl_int_is_neg(s
)) {
4210 return isl_bool_false
;
4216 return isl_bool_true
;
4219 isl_bool
isl_basic_set_contains(__isl_keep isl_basic_set
*bset
,
4220 __isl_keep isl_vec
*vec
)
4222 return isl_basic_map_contains(bset_to_bmap(bset
), vec
);
4225 __isl_give isl_basic_map
*isl_basic_map_intersect(
4226 __isl_take isl_basic_map
*bmap1
, __isl_take isl_basic_map
*bmap2
)
4228 struct isl_vec
*sample
= NULL
;
4229 isl_space
*space1
, *space2
;
4230 isl_size dim1
, dim2
, nparam1
, nparam2
;
4232 if (isl_basic_map_check_equal_params(bmap1
, bmap2
) < 0)
4234 space1
= isl_basic_map_peek_space(bmap1
);
4235 space2
= isl_basic_map_peek_space(bmap2
);
4236 dim1
= isl_space_dim(space1
, isl_dim_all
);
4237 dim2
= isl_space_dim(space2
, isl_dim_all
);
4238 nparam1
= isl_space_dim(space1
, isl_dim_param
);
4239 nparam2
= isl_space_dim(space2
, isl_dim_param
);
4240 if (dim1
< 0 || dim2
< 0 || nparam1
< 0 || nparam2
< 0)
4242 if (dim1
== nparam1
&& dim2
!= nparam2
)
4243 return isl_basic_map_intersect(bmap2
, bmap1
);
4245 if (dim2
!= nparam2
&&
4246 isl_basic_map_check_equal_space(bmap1
, bmap2
) < 0)
4249 if (isl_basic_map_plain_is_empty(bmap1
)) {
4250 isl_basic_map_free(bmap2
);
4253 if (isl_basic_map_plain_is_empty(bmap2
)) {
4254 isl_basic_map_free(bmap1
);
4258 if (bmap1
->sample
&&
4259 isl_basic_map_contains(bmap1
, bmap1
->sample
) > 0 &&
4260 isl_basic_map_contains(bmap2
, bmap1
->sample
) > 0)
4261 sample
= isl_vec_copy(bmap1
->sample
);
4262 else if (bmap2
->sample
&&
4263 isl_basic_map_contains(bmap1
, bmap2
->sample
) > 0 &&
4264 isl_basic_map_contains(bmap2
, bmap2
->sample
) > 0)
4265 sample
= isl_vec_copy(bmap2
->sample
);
4267 bmap1
= isl_basic_map_cow(bmap1
);
4270 bmap1
= isl_basic_map_extend(bmap1
,
4271 bmap2
->n_div
, bmap2
->n_eq
, bmap2
->n_ineq
);
4272 bmap1
= add_constraints(bmap1
, bmap2
, 0, 0);
4275 isl_vec_free(sample
);
4277 isl_vec_free(bmap1
->sample
);
4278 bmap1
->sample
= sample
;
4281 bmap1
= isl_basic_map_simplify(bmap1
);
4282 return isl_basic_map_finalize(bmap1
);
4285 isl_vec_free(sample
);
4286 isl_basic_map_free(bmap1
);
4287 isl_basic_map_free(bmap2
);
4291 __isl_give isl_basic_set
*isl_basic_set_intersect(
4292 __isl_take isl_basic_set
*bset1
, __isl_take isl_basic_set
*bset2
)
4294 return bset_from_bmap(isl_basic_map_intersect(bset_to_bmap(bset1
),
4295 bset_to_bmap(bset2
)));
4298 /* Intersect the parameter domain of "bmap" with "bset".
4300 * isl_basic_map_intersect handles this as a special case.
4302 __isl_give isl_basic_map
*isl_basic_map_intersect_params(
4303 __isl_take isl_basic_map
*bmap
, __isl_take isl_basic_set
*bset
)
4305 return isl_basic_map_intersect(bmap
, bset
);
4308 __isl_give isl_basic_set
*isl_basic_set_intersect_params(
4309 __isl_take isl_basic_set
*bset1
, __isl_take isl_basic_set
*bset2
)
4311 isl_basic_map
*bmap
;
4313 bmap
= bset_to_bmap(bset1
);
4314 bmap
= isl_basic_map_intersect_params(bmap
, bset2
);
4315 return bset_from_bmap(bmap
);
4318 /* Does "map" consist of a single disjunct, without any local variables?
4320 static isl_bool
is_convex_no_locals(__isl_keep isl_map
*map
)
4325 return isl_bool_error
;
4327 return isl_bool_false
;
4328 n_div
= isl_basic_map_dim(map
->p
[0], isl_dim_div
);
4330 return isl_bool_error
;
4332 return isl_bool_false
;
4333 return isl_bool_true
;
4336 /* Check that "map" consists of a single disjunct, without any local variables.
4338 static isl_stat
check_convex_no_locals(__isl_keep isl_map
*map
)
4342 ok
= is_convex_no_locals(map
);
4344 return isl_stat_error
;
4348 isl_die(isl_map_get_ctx(map
), isl_error_internal
,
4349 "unexpectedly not convex or involving local variables",
4350 return isl_stat_error
);
4353 /* Special case of isl_map_intersect, where both map1 and map2
4354 * are convex, without any divs and such that either map1 or map2
4355 * contains a single constraint. This constraint is then simply
4356 * added to the other map.
4358 static __isl_give isl_map
*map_intersect_add_constraint(
4359 __isl_take isl_map
*map1
, __isl_take isl_map
*map2
)
4361 if (check_convex_no_locals(map1
) < 0 ||
4362 check_convex_no_locals(map2
) < 0)
4365 if (map2
->p
[0]->n_eq
+ map2
->p
[0]->n_ineq
!= 1)
4366 return isl_map_intersect(map2
, map1
);
4368 map1
= isl_map_cow(map1
);
4371 if (isl_map_plain_is_empty(map1
)) {
4375 if (map2
->p
[0]->n_eq
== 1)
4376 map1
->p
[0] = isl_basic_map_add_eq(map1
->p
[0], map2
->p
[0]->eq
[0]);
4378 map1
->p
[0] = isl_basic_map_add_ineq(map1
->p
[0],
4379 map2
->p
[0]->ineq
[0]);
4381 map1
->p
[0] = isl_basic_map_simplify(map1
->p
[0]);
4382 map1
->p
[0] = isl_basic_map_finalize(map1
->p
[0]);
4386 if (isl_basic_map_plain_is_empty(map1
->p
[0])) {
4387 isl_basic_map_free(map1
->p
[0]);
4393 map1
= isl_map_unmark_normalized(map1
);
4401 /* map2 may be either a parameter domain or a map living in the same
4404 static __isl_give isl_map
*map_intersect_internal(__isl_take isl_map
*map1
,
4405 __isl_take isl_map
*map2
)
4411 isl_size dim2
, nparam2
;
4416 if ((isl_map_plain_is_empty(map1
) ||
4417 isl_map_plain_is_universe(map2
)) &&
4418 isl_space_is_equal(map1
->dim
, map2
->dim
)) {
4422 if ((isl_map_plain_is_empty(map2
) ||
4423 isl_map_plain_is_universe(map1
)) &&
4424 isl_space_is_equal(map1
->dim
, map2
->dim
)) {
4429 if (is_convex_no_locals(map1
) == isl_bool_true
&&
4430 is_convex_no_locals(map2
) == isl_bool_true
&&
4431 isl_space_is_equal(map1
->dim
, map2
->dim
) &&
4432 (map1
->p
[0]->n_eq
+ map1
->p
[0]->n_ineq
== 1 ||
4433 map2
->p
[0]->n_eq
+ map2
->p
[0]->n_ineq
== 1))
4434 return map_intersect_add_constraint(map1
, map2
);
4436 equal
= isl_map_plain_is_equal(map1
, map2
);
4444 dim2
= isl_map_dim(map2
, isl_dim_all
);
4445 nparam2
= isl_map_dim(map2
, isl_dim_param
);
4446 if (dim2
< 0 || nparam2
< 0)
4448 if (dim2
!= nparam2
)
4449 isl_assert(map1
->ctx
,
4450 isl_space_is_equal(map1
->dim
, map2
->dim
), goto error
);
4452 if (ISL_F_ISSET(map1
, ISL_MAP_DISJOINT
) &&
4453 ISL_F_ISSET(map2
, ISL_MAP_DISJOINT
))
4454 ISL_FL_SET(flags
, ISL_MAP_DISJOINT
);
4456 result
= isl_map_alloc_space(isl_space_copy(map1
->dim
),
4457 map1
->n
* map2
->n
, flags
);
4460 for (i
= 0; i
< map1
->n
; ++i
)
4461 for (j
= 0; j
< map2
->n
; ++j
) {
4462 struct isl_basic_map
*part
;
4463 part
= isl_basic_map_intersect(
4464 isl_basic_map_copy(map1
->p
[i
]),
4465 isl_basic_map_copy(map2
->p
[j
]));
4466 if (isl_basic_map_is_empty(part
) < 0)
4467 part
= isl_basic_map_free(part
);
4468 result
= isl_map_add_basic_map(result
, part
);
4481 static __isl_give isl_map
*map_intersect(__isl_take isl_map
*map1
,
4482 __isl_take isl_map
*map2
)
4484 if (isl_map_check_equal_space(map1
, map2
) < 0)
4486 return map_intersect_internal(map1
, map2
);
4493 __isl_give isl_map
*isl_map_intersect(__isl_take isl_map
*map1
,
4494 __isl_take isl_map
*map2
)
4496 isl_map_align_params_bin(&map1
, &map2
);
4497 return map_intersect(map1
, map2
);
4500 __isl_give isl_set
*isl_set_intersect(__isl_take isl_set
*set1
,
4501 __isl_take isl_set
*set2
)
4503 return set_from_map(isl_map_intersect(set_to_map(set1
),
4507 /* map_intersect_internal accepts intersections
4508 * with parameter domains, so we can just call that function.
4510 __isl_give isl_map
*isl_map_intersect_params(__isl_take isl_map
*map
,
4511 __isl_take isl_set
*params
)
4513 isl_map_align_params_set(&map
, ¶ms
);
4514 return map_intersect_internal(map
, params
);
4517 __isl_give isl_set
*isl_set_intersect_params(__isl_take isl_set
*set
,
4518 __isl_take isl_set
*params
)
4520 return isl_map_intersect_params(set
, params
);
4523 __isl_give isl_basic_map
*isl_basic_map_reverse(__isl_take isl_basic_map
*bmap
)
4531 bmap
= isl_basic_map_cow(bmap
);
4534 space
= isl_space_reverse(isl_space_copy(bmap
->dim
));
4535 pos
= isl_basic_map_offset(bmap
, isl_dim_in
);
4536 n1
= isl_basic_map_dim(bmap
, isl_dim_in
);
4537 n2
= isl_basic_map_dim(bmap
, isl_dim_out
);
4538 if (n1
< 0 || n2
< 0)
4539 bmap
= isl_basic_map_free(bmap
);
4540 bmap
= isl_basic_map_swap_vars(bmap
, pos
, n1
, n2
);
4541 return isl_basic_map_reset_space(bmap
, space
);
4544 /* Given a basic map where the tuple of type "type" is a wrapped map,
4545 * swap domain and range of that wrapped map.
4547 static __isl_give isl_basic_map
*isl_basic_map_reverse_wrapped(
4548 __isl_take isl_basic_map
*bmap
, enum isl_dim_type type
)
4551 isl_size offset
, n1
, n2
;
4553 space
= isl_basic_map_peek_space(bmap
);
4554 offset
= isl_basic_map_var_offset(bmap
, type
);
4555 n1
= isl_space_wrapped_dim(space
, type
, isl_dim_in
);
4556 n2
= isl_space_wrapped_dim(space
, type
, isl_dim_out
);
4557 if (offset
< 0 || n1
< 0 || n2
< 0)
4558 return isl_basic_map_free(bmap
);
4560 bmap
= isl_basic_map_swap_vars(bmap
, 1 + offset
, n1
, n2
);
4562 space
= isl_basic_map_take_space(bmap
);
4563 space
= isl_space_reverse_wrapped(space
, type
);
4564 bmap
= isl_basic_map_restore_space(bmap
, space
);
4569 /* Given a basic map (A -> B) -> C, return the corresponding basic map
4572 static __isl_give isl_basic_map
*isl_basic_map_domain_reverse(
4573 __isl_take isl_basic_map
*bmap
)
4577 space
= isl_basic_map_peek_space(bmap
);
4578 if (isl_space_check_domain_is_wrapping(space
) < 0)
4579 return isl_basic_map_free(bmap
);
4580 bmap
= isl_basic_map_reverse_wrapped(bmap
, isl_dim_in
);
4585 /* Given a basic map A -> (B -> C), return the corresponding basic map
4588 static __isl_give isl_basic_map
*isl_basic_map_range_reverse(
4589 __isl_take isl_basic_map
*bmap
)
4593 space
= isl_basic_map_peek_space(bmap
);
4594 if (isl_space_check_range_is_wrapping(space
) < 0)
4595 return isl_basic_map_free(bmap
);
4596 bmap
= isl_basic_map_reverse_wrapped(bmap
, isl_dim_out
);
4601 /* Given a basic map that is actually a basic set (A -> B),
4602 * return the corresponding basic set (B -> A) as a basic map.
4604 static __isl_give isl_basic_map
*isl_basic_map_set_reverse(
4605 __isl_take isl_basic_map
*bmap
)
4609 space
= isl_basic_map_peek_space(bmap
);
4610 if (isl_space_check_is_wrapping(space
) < 0)
4611 return isl_basic_map_free(bmap
);
4612 bmap
= isl_basic_map_reverse_wrapped(bmap
, isl_dim_set
);
4617 static __isl_give isl_basic_map
*basic_map_space_reset(
4618 __isl_take isl_basic_map
*bmap
, enum isl_dim_type type
)
4624 if (!isl_space_is_named_or_nested(bmap
->dim
, type
))
4627 space
= isl_basic_map_get_space(bmap
);
4628 space
= isl_space_reset(space
, type
);
4629 bmap
= isl_basic_map_reset_space(bmap
, space
);
4633 __isl_give isl_basic_map
*isl_basic_map_insert_dims(
4634 __isl_take isl_basic_map
*bmap
, enum isl_dim_type type
,
4635 unsigned pos
, unsigned n
)
4637 isl_bool rational
, is_empty
;
4638 isl_space
*res_space
;
4639 struct isl_basic_map
*res
;
4640 struct isl_dim_map
*dim_map
;
4643 enum isl_dim_type t
;
4646 return basic_map_space_reset(bmap
, type
);
4648 is_empty
= isl_basic_map_plain_is_empty(bmap
);
4649 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
4650 if (is_empty
< 0 || total
< 0)
4651 return isl_basic_map_free(bmap
);
4652 res_space
= isl_space_insert_dims(isl_basic_map_get_space(bmap
),
4655 return isl_basic_map_free(bmap
);
4657 isl_basic_map_free(bmap
);
4658 return isl_basic_map_empty(res_space
);
4661 dim_map
= isl_dim_map_alloc(bmap
->ctx
, total
+ n
);
4663 for (t
= isl_dim_param
; t
<= isl_dim_out
; ++t
) {
4667 isl_dim_map_dim(dim_map
, bmap
->dim
, t
, off
);
4669 isl_size size
= isl_basic_map_dim(bmap
, t
);
4671 dim_map
= isl_dim_map_free(dim_map
);
4672 isl_dim_map_dim_range(dim_map
, bmap
->dim
, t
,
4674 isl_dim_map_dim_range(dim_map
, bmap
->dim
, t
,
4675 pos
, size
- pos
, off
+ pos
+ n
);
4677 dim
= isl_space_dim(res_space
, t
);
4679 dim_map
= isl_dim_map_free(dim_map
);
4682 isl_dim_map_div(dim_map
, bmap
, off
);
4684 res
= isl_basic_map_alloc_space(res_space
,
4685 bmap
->n_div
, bmap
->n_eq
, bmap
->n_ineq
);
4686 rational
= isl_basic_map_is_rational(bmap
);
4688 res
= isl_basic_map_free(res
);
4690 res
= isl_basic_map_set_rational(res
);
4691 res
= isl_basic_map_add_constraints_dim_map(res
, bmap
, dim_map
);
4692 return isl_basic_map_finalize(res
);
4695 __isl_give isl_basic_set
*isl_basic_set_insert_dims(
4696 __isl_take isl_basic_set
*bset
,
4697 enum isl_dim_type type
, unsigned pos
, unsigned n
)
4699 return isl_basic_map_insert_dims(bset
, type
, pos
, n
);
4702 __isl_give isl_basic_map
*isl_basic_map_add_dims(__isl_take isl_basic_map
*bmap
,
4703 enum isl_dim_type type
, unsigned n
)
4707 dim
= isl_basic_map_dim(bmap
, type
);
4709 return isl_basic_map_free(bmap
);
4710 return isl_basic_map_insert_dims(bmap
, type
, dim
, n
);
4713 __isl_give isl_basic_set
*isl_basic_set_add_dims(__isl_take isl_basic_set
*bset
,
4714 enum isl_dim_type type
, unsigned n
)
4718 isl_assert(bset
->ctx
, type
!= isl_dim_in
, goto error
);
4719 return isl_basic_map_add_dims(bset
, type
, n
);
4721 isl_basic_set_free(bset
);
4725 static __isl_give isl_map
*map_space_reset(__isl_take isl_map
*map
,
4726 enum isl_dim_type type
)
4730 if (!map
|| !isl_space_is_named_or_nested(map
->dim
, type
))
4733 space
= isl_map_get_space(map
);
4734 space
= isl_space_reset(space
, type
);
4735 map
= isl_map_reset_space(map
, space
);
4739 __isl_give isl_map
*isl_map_insert_dims(__isl_take isl_map
*map
,
4740 enum isl_dim_type type
, unsigned pos
, unsigned n
)
4746 return map_space_reset(map
, type
);
4748 map
= isl_map_cow(map
);
4752 for (i
= 0; i
< map
->n
; ++i
) {
4753 map
->p
[i
] = isl_basic_map_insert_dims(map
->p
[i
], type
, pos
, n
);
4758 space
= isl_map_take_space(map
);
4759 space
= isl_space_insert_dims(space
, type
, pos
, n
);
4760 map
= isl_map_restore_space(map
, space
);
4768 __isl_give isl_set
*isl_set_insert_dims(__isl_take isl_set
*set
,
4769 enum isl_dim_type type
, unsigned pos
, unsigned n
)
4771 return isl_map_insert_dims(set
, type
, pos
, n
);
4774 __isl_give isl_map
*isl_map_add_dims(__isl_take isl_map
*map
,
4775 enum isl_dim_type type
, unsigned n
)
4779 dim
= isl_map_dim(map
, type
);
4781 return isl_map_free(map
);
4782 return isl_map_insert_dims(map
, type
, dim
, n
);
4785 __isl_give isl_set
*isl_set_add_dims(__isl_take isl_set
*set
,
4786 enum isl_dim_type type
, unsigned n
)
4790 isl_assert(set
->ctx
, type
!= isl_dim_in
, goto error
);
4791 return set_from_map(isl_map_add_dims(set_to_map(set
), type
, n
));
4797 __isl_give isl_basic_map
*isl_basic_map_move_dims(
4798 __isl_take isl_basic_map
*bmap
,
4799 enum isl_dim_type dst_type
, unsigned dst_pos
,
4800 enum isl_dim_type src_type
, unsigned src_pos
, unsigned n
)
4803 struct isl_dim_map
*dim_map
;
4804 struct isl_basic_map
*res
;
4805 enum isl_dim_type t
;
4812 bmap
= isl_basic_map_reset(bmap
, src_type
);
4813 bmap
= isl_basic_map_reset(bmap
, dst_type
);
4817 if (isl_basic_map_check_range(bmap
, src_type
, src_pos
, n
) < 0)
4818 return isl_basic_map_free(bmap
);
4820 if (dst_type
== src_type
&& dst_pos
== src_pos
)
4823 isl_assert(bmap
->ctx
, dst_type
!= src_type
, goto error
);
4825 if (pos(bmap
->dim
, dst_type
) + dst_pos
==
4826 pos(bmap
->dim
, src_type
) + src_pos
+
4827 ((src_type
< dst_type
) ? n
: 0)) {
4828 space
= isl_basic_map_take_space(bmap
);
4829 space
= isl_space_move_dims(space
, dst_type
, dst_pos
,
4830 src_type
, src_pos
, n
);
4831 bmap
= isl_basic_map_restore_space(bmap
, space
);
4832 bmap
= isl_basic_map_finalize(bmap
);
4837 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
4839 return isl_basic_map_free(bmap
);
4840 dim_map
= isl_dim_map_alloc(bmap
->ctx
, total
);
4843 space
= isl_basic_map_peek_space(bmap
);
4844 for (t
= isl_dim_param
; t
<= isl_dim_out
; ++t
) {
4845 isl_size size
= isl_space_dim(space
, t
);
4847 dim_map
= isl_dim_map_free(dim_map
);
4848 if (t
== dst_type
) {
4849 isl_dim_map_dim_range(dim_map
, space
, t
,
4852 isl_dim_map_dim_range(dim_map
, space
, src_type
,
4855 isl_dim_map_dim_range(dim_map
, space
, t
,
4856 dst_pos
, size
- dst_pos
, off
);
4857 off
+= size
- dst_pos
;
4858 } else if (t
== src_type
) {
4859 isl_dim_map_dim_range(dim_map
, space
, t
,
4862 isl_dim_map_dim_range(dim_map
, space
, t
,
4863 src_pos
+ n
, size
- src_pos
- n
, off
);
4864 off
+= size
- src_pos
- n
;
4866 isl_dim_map_dim(dim_map
, space
, t
, off
);
4870 isl_dim_map_div(dim_map
, bmap
, off
);
4872 res
= isl_basic_map_alloc_space(isl_basic_map_get_space(bmap
),
4873 bmap
->n_div
, bmap
->n_eq
, bmap
->n_ineq
);
4874 bmap
= isl_basic_map_add_constraints_dim_map(res
, bmap
, dim_map
);
4875 space
= isl_basic_map_take_space(bmap
);
4876 space
= isl_space_move_dims(space
, dst_type
, dst_pos
,
4877 src_type
, src_pos
, n
);
4878 bmap
= isl_basic_map_restore_space(bmap
, space
);
4882 ISL_F_CLR(bmap
, ISL_BASIC_MAP_SORTED
);
4883 bmap
= isl_basic_map_gauss(bmap
, NULL
);
4884 bmap
= isl_basic_map_finalize(bmap
);
4888 isl_basic_map_free(bmap
);
4892 __isl_give isl_basic_set
*isl_basic_set_move_dims(__isl_take isl_basic_set
*bset
,
4893 enum isl_dim_type dst_type
, unsigned dst_pos
,
4894 enum isl_dim_type src_type
, unsigned src_pos
, unsigned n
)
4896 isl_basic_map
*bmap
= bset_to_bmap(bset
);
4897 bmap
= isl_basic_map_move_dims(bmap
, dst_type
, dst_pos
,
4898 src_type
, src_pos
, n
);
4899 return bset_from_bmap(bmap
);
4902 __isl_give isl_set
*isl_set_move_dims(__isl_take isl_set
*set
,
4903 enum isl_dim_type dst_type
, unsigned dst_pos
,
4904 enum isl_dim_type src_type
, unsigned src_pos
, unsigned n
)
4908 isl_assert(set
->ctx
, dst_type
!= isl_dim_in
, goto error
);
4909 return set_from_map(isl_map_move_dims(set_to_map(set
),
4910 dst_type
, dst_pos
, src_type
, src_pos
, n
));
4916 __isl_give isl_map
*isl_map_move_dims(__isl_take isl_map
*map
,
4917 enum isl_dim_type dst_type
, unsigned dst_pos
,
4918 enum isl_dim_type src_type
, unsigned src_pos
, unsigned n
)
4924 map
= isl_map_reset(map
, src_type
);
4925 map
= isl_map_reset(map
, dst_type
);
4929 if (isl_map_check_range(map
, src_type
, src_pos
, n
))
4930 return isl_map_free(map
);
4932 if (dst_type
== src_type
&& dst_pos
== src_pos
)
4935 isl_assert(map
->ctx
, dst_type
!= src_type
, goto error
);
4937 map
= isl_map_cow(map
);
4941 for (i
= 0; i
< map
->n
; ++i
) {
4942 map
->p
[i
] = isl_basic_map_move_dims(map
->p
[i
],
4944 src_type
, src_pos
, n
);
4949 space
= isl_map_take_space(map
);
4950 space
= isl_space_move_dims(space
, dst_type
, dst_pos
,
4951 src_type
, src_pos
, n
);
4952 map
= isl_map_restore_space(map
, space
);
4960 /* Move the specified dimensions to the last columns right before
4961 * the divs. Don't change the dimension specification of bmap.
4962 * That's the responsibility of the caller.
4964 static __isl_give isl_basic_map
*move_last(__isl_take isl_basic_map
*bmap
,
4965 enum isl_dim_type type
, unsigned first
, unsigned n
)
4968 struct isl_dim_map
*dim_map
;
4969 struct isl_basic_map
*res
;
4970 enum isl_dim_type t
;
4976 if (isl_basic_map_offset(bmap
, type
) + first
+ n
==
4977 isl_basic_map_offset(bmap
, isl_dim_div
))
4980 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
4982 return isl_basic_map_free(bmap
);
4983 dim_map
= isl_dim_map_alloc(bmap
->ctx
, total
);
4986 space
= isl_basic_map_peek_space(bmap
);
4987 for (t
= isl_dim_param
; t
<= isl_dim_out
; ++t
) {
4988 isl_size size
= isl_space_dim(space
, t
);
4990 dim_map
= isl_dim_map_free(dim_map
);
4992 isl_dim_map_dim_range(dim_map
, space
, t
,
4995 isl_dim_map_dim_range(dim_map
, space
, t
,
4996 first
, n
, total
- bmap
->n_div
- n
);
4997 isl_dim_map_dim_range(dim_map
, space
, t
,
4998 first
+ n
, size
- (first
+ n
), off
);
4999 off
+= size
- (first
+ n
);
5001 isl_dim_map_dim(dim_map
, space
, t
, off
);
5005 isl_dim_map_div(dim_map
, bmap
, off
+ n
);
5007 res
= isl_basic_map_alloc_space(isl_basic_map_get_space(bmap
),
5008 bmap
->n_div
, bmap
->n_eq
, bmap
->n_ineq
);
5009 res
= isl_basic_map_add_constraints_dim_map(res
, bmap
, dim_map
);
5013 /* Insert "n" rows in the divs of "bmap".
5015 * The number of columns is not changed, which means that the last
5016 * dimensions of "bmap" are being reintepreted as the new divs.
5017 * The space of "bmap" is not adjusted, however, which means
5018 * that "bmap" is left in an inconsistent state. Removing "n" dimensions
5019 * from the space of "bmap" is the responsibility of the caller.
5021 static __isl_give isl_basic_map
*insert_div_rows(__isl_take isl_basic_map
*bmap
,
5029 bmap
= isl_basic_map_cow(bmap
);
5033 row_size
= isl_basic_map_offset(bmap
, isl_dim_div
) + bmap
->extra
;
5034 old
= bmap
->block2
.data
;
5035 bmap
->block2
= isl_blk_extend(bmap
->ctx
, bmap
->block2
,
5036 (bmap
->extra
+ n
) * (1 + row_size
));
5037 if (!bmap
->block2
.data
)
5038 return isl_basic_map_free(bmap
);
5039 new_div
= isl_alloc_array(bmap
->ctx
, isl_int
*, bmap
->extra
+ n
);
5041 return isl_basic_map_free(bmap
);
5042 for (i
= 0; i
< n
; ++i
) {
5043 new_div
[i
] = bmap
->block2
.data
+
5044 (bmap
->extra
+ i
) * (1 + row_size
);
5045 isl_seq_clr(new_div
[i
], 1 + row_size
);
5047 for (i
= 0; i
< bmap
->extra
; ++i
)
5048 new_div
[n
+ i
] = bmap
->block2
.data
+ (bmap
->div
[i
] - old
);
5050 bmap
->div
= new_div
;
5057 /* Drop constraints from "bmap" that only involve the variables
5058 * of "type" in the range [first, first + n] that are not related
5059 * to any of the variables outside that interval.
5060 * These constraints cannot influence the values for the variables
5061 * outside the interval, except in case they cause "bmap" to be empty.
5062 * Only drop the constraints if "bmap" is known to be non-empty.
5064 static __isl_give isl_basic_map
*drop_irrelevant_constraints(
5065 __isl_take isl_basic_map
*bmap
, enum isl_dim_type type
,
5066 unsigned first
, unsigned n
)
5070 isl_size dim
, n_div
;
5073 non_empty
= isl_basic_map_plain_is_non_empty(bmap
);
5075 return isl_basic_map_free(bmap
);
5079 dim
= isl_basic_map_dim(bmap
, isl_dim_all
);
5080 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
5081 if (dim
< 0 || n_div
< 0)
5082 return isl_basic_map_free(bmap
);
5083 groups
= isl_calloc_array(isl_basic_map_get_ctx(bmap
), int, dim
);
5085 return isl_basic_map_free(bmap
);
5086 first
+= isl_basic_map_offset(bmap
, type
) - 1;
5087 for (i
= 0; i
< first
; ++i
)
5089 for (i
= first
+ n
; i
< dim
- n_div
; ++i
)
5092 bmap
= isl_basic_map_drop_unrelated_constraints(bmap
, groups
);
5097 /* Turn the n dimensions of type type, starting at first
5098 * into existentially quantified variables.
5100 * If a subset of the projected out variables are unrelated
5101 * to any of the variables that remain, then the constraints
5102 * involving this subset are simply dropped first.
5104 __isl_give isl_basic_map
*isl_basic_map_project_out(
5105 __isl_take isl_basic_map
*bmap
,
5106 enum isl_dim_type type
, unsigned first
, unsigned n
)
5112 return basic_map_space_reset(bmap
, type
);
5113 if (type
== isl_dim_div
)
5114 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
5115 "cannot project out existentially quantified variables",
5116 return isl_basic_map_free(bmap
));
5118 empty
= isl_basic_map_plain_is_empty(bmap
);
5120 return isl_basic_map_free(bmap
);
5122 bmap
= isl_basic_map_set_to_empty(bmap
);
5124 bmap
= drop_irrelevant_constraints(bmap
, type
, first
, n
);
5128 if (ISL_F_ISSET(bmap
, ISL_BASIC_MAP_RATIONAL
))
5129 return isl_basic_map_remove_dims(bmap
, type
, first
, n
);
5131 if (isl_basic_map_check_range(bmap
, type
, first
, n
) < 0)
5132 return isl_basic_map_free(bmap
);
5134 bmap
= move_last(bmap
, type
, first
, n
);
5135 bmap
= isl_basic_map_cow(bmap
);
5136 bmap
= insert_div_rows(bmap
, n
);
5138 space
= isl_basic_map_take_space(bmap
);
5139 space
= isl_space_drop_dims(space
, type
, first
, n
);
5140 bmap
= isl_basic_map_restore_space(bmap
, space
);
5141 bmap
= isl_basic_map_simplify(bmap
);
5142 bmap
= isl_basic_map_drop_redundant_divs(bmap
);
5143 return isl_basic_map_finalize(bmap
);
5146 /* Turn the n dimensions of type type, starting at first
5147 * into existentially quantified variables.
5149 __isl_give isl_basic_set
*isl_basic_set_project_out(
5150 __isl_take isl_basic_set
*bset
, enum isl_dim_type type
,
5151 unsigned first
, unsigned n
)
5153 return bset_from_bmap(isl_basic_map_project_out(bset_to_bmap(bset
),
5157 /* Turn the n dimensions of type type, starting at first
5158 * into existentially quantified variables.
5160 __isl_give isl_map
*isl_map_project_out(__isl_take isl_map
*map
,
5161 enum isl_dim_type type
, unsigned first
, unsigned n
)
5167 return map_space_reset(map
, type
);
5169 if (isl_map_check_range(map
, type
, first
, n
) < 0)
5170 return isl_map_free(map
);
5172 map
= isl_map_cow(map
);
5176 for (i
= 0; i
< map
->n
; ++i
) {
5177 map
->p
[i
] = isl_basic_map_project_out(map
->p
[i
], type
, first
, n
);
5183 ISL_F_CLR(map
, ISL_MAP_DISJOINT
);
5184 map
= isl_map_unmark_normalized(map
);
5186 space
= isl_map_take_space(map
);
5187 space
= isl_space_drop_dims(space
, type
, first
, n
);
5188 map
= isl_map_restore_space(map
, space
);
5197 #define TYPE isl_map
5198 #include "isl_project_out_all_params_templ.c"
5199 #include "isl_project_out_param_templ.c"
5201 /* Turn all the dimensions of type "type", except the "n" starting at "first"
5202 * into existentially quantified variables.
5204 __isl_give isl_map
*isl_map_project_onto(__isl_take isl_map
*map
,
5205 enum isl_dim_type type
, unsigned first
, unsigned n
)
5209 dim
= isl_map_dim(map
, type
);
5210 if (isl_map_check_range(map
, type
, first
, n
) < 0 || dim
< 0)
5211 return isl_map_free(map
);
5212 map
= isl_map_project_out(map
, type
, first
+ n
, dim
- (first
+ n
));
5213 map
= isl_map_project_out(map
, type
, 0, first
);
5217 /* Turn the n dimensions of type type, starting at first
5218 * into existentially quantified variables.
5220 __isl_give isl_set
*isl_set_project_out(__isl_take isl_set
*set
,
5221 enum isl_dim_type type
, unsigned first
, unsigned n
)
5223 return set_from_map(isl_map_project_out(set_to_map(set
),
5227 /* If "set" involves a parameter with identifier "id",
5228 * then turn it into an existentially quantified variable.
5230 __isl_give isl_set
*isl_set_project_out_param_id(__isl_take isl_set
*set
,
5231 __isl_take isl_id
*id
)
5233 return set_from_map(isl_map_project_out_param_id(set_to_map(set
), id
));
5236 /* If "set" involves any of the parameters with identifiers in "list",
5237 * then turn them into existentially quantified variables.
5239 __isl_give isl_set
*isl_set_project_out_param_id_list(__isl_take isl_set
*set
,
5240 __isl_take isl_id_list
*list
)
5244 map
= set_to_map(set
);
5245 map
= isl_map_project_out_param_id_list(map
, list
);
5246 return set_from_map(map
);
5249 /* Project out all parameters from "set" by existentially quantifying
5252 __isl_give isl_set
*isl_set_project_out_all_params(__isl_take isl_set
*set
)
5254 return set_from_map(isl_map_project_out_all_params(set_to_map(set
)));
5257 /* Return a map that projects the elements in "set" onto their
5258 * "n" set dimensions starting at "first".
5259 * "type" should be equal to isl_dim_set.
5261 __isl_give isl_map
*isl_set_project_onto_map(__isl_take isl_set
*set
,
5262 enum isl_dim_type type
, unsigned first
, unsigned n
)
5267 if (type
!= isl_dim_set
)
5268 isl_die(isl_set_get_ctx(set
), isl_error_invalid
,
5269 "only set dimensions can be projected out", goto error
);
5270 if (isl_set_check_range(set
, type
, first
, n
) < 0)
5271 return isl_set_free(set
);
5273 map
= isl_map_from_domain(set
);
5274 map
= isl_map_add_dims(map
, isl_dim_out
, n
);
5275 for (i
= 0; i
< n
; ++i
)
5276 map
= isl_map_equate(map
, isl_dim_in
, first
+ i
,
5284 static __isl_give isl_basic_map
*add_divs(__isl_take isl_basic_map
*bmap
,
5290 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
5292 return isl_basic_map_free(bmap
);
5293 for (i
= 0; i
< n
; ++i
) {
5294 j
= isl_basic_map_alloc_div(bmap
);
5297 isl_seq_clr(bmap
->div
[j
], 1 + 1 + total
);
5301 isl_basic_map_free(bmap
);
5305 /* Does "bmap2" apply to the range of "bmap1" (ignoring parameters)?
5307 isl_bool
isl_basic_map_applies_range(__isl_keep isl_basic_map
*bmap1
,
5308 __isl_keep isl_basic_map
*bmap2
)
5310 isl_space
*space1
, *space2
;
5312 space1
= isl_basic_map_peek_space(bmap1
);
5313 space2
= isl_basic_map_peek_space(bmap2
);
5314 return isl_space_tuple_is_equal(space1
, isl_dim_out
,
5315 space2
, isl_dim_in
);
5318 /* Check that "bmap2" applies to the range of "bmap1" (ignoring parameters).
5320 static isl_stat
isl_basic_map_check_applies_range(
5321 __isl_keep isl_basic_map
*bmap1
, __isl_keep isl_basic_map
*bmap2
)
5325 equal
= isl_basic_map_applies_range(bmap1
, bmap2
);
5327 return isl_stat_error
;
5329 isl_die(isl_basic_map_get_ctx(bmap1
), isl_error_invalid
,
5330 "spaces don't match", return isl_stat_error
);
5334 __isl_give isl_basic_map
*isl_basic_map_apply_range(
5335 __isl_take isl_basic_map
*bmap1
, __isl_take isl_basic_map
*bmap2
)
5337 isl_space
*space_result
= NULL
;
5338 struct isl_basic_map
*bmap
;
5339 isl_size n_in
, n_out
, n
, nparam
;
5340 unsigned total
, pos
;
5341 struct isl_dim_map
*dim_map1
, *dim_map2
;
5343 if (isl_basic_map_check_equal_params(bmap1
, bmap2
) < 0)
5345 if (isl_basic_map_check_applies_range(bmap1
, bmap2
) < 0)
5348 n_in
= isl_basic_map_dim(bmap1
, isl_dim_in
);
5349 n_out
= isl_basic_map_dim(bmap2
, isl_dim_out
);
5350 n
= isl_basic_map_dim(bmap1
, isl_dim_out
);
5351 nparam
= isl_basic_map_dim(bmap1
, isl_dim_param
);
5352 if (n_in
< 0 || n_out
< 0 || n
< 0 || nparam
< 0)
5355 space_result
= isl_space_join(isl_basic_map_get_space(bmap1
),
5356 isl_basic_map_get_space(bmap2
));
5358 total
= nparam
+ n_in
+ n_out
+ bmap1
->n_div
+ bmap2
->n_div
+ n
;
5359 dim_map1
= isl_dim_map_alloc(bmap1
->ctx
, total
);
5360 dim_map2
= isl_dim_map_alloc(bmap1
->ctx
, total
);
5361 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_param
, pos
= 0);
5362 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_param
, pos
= 0);
5363 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_in
, pos
+= nparam
);
5364 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_out
, pos
+= n_in
);
5365 isl_dim_map_div(dim_map1
, bmap1
, pos
+= n_out
);
5366 isl_dim_map_div(dim_map2
, bmap2
, pos
+= bmap1
->n_div
);
5367 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_out
, pos
+= bmap2
->n_div
);
5368 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_in
, pos
);
5370 bmap
= isl_basic_map_alloc_space(space_result
,
5371 bmap1
->n_div
+ bmap2
->n_div
+ n
,
5372 bmap1
->n_eq
+ bmap2
->n_eq
,
5373 bmap1
->n_ineq
+ bmap2
->n_ineq
);
5374 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap1
, dim_map1
);
5375 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap2
, dim_map2
);
5376 bmap
= add_divs(bmap
, n
);
5377 bmap
= isl_basic_map_simplify(bmap
);
5378 bmap
= isl_basic_map_drop_redundant_divs(bmap
);
5379 return isl_basic_map_finalize(bmap
);
5381 isl_basic_map_free(bmap1
);
5382 isl_basic_map_free(bmap2
);
5386 __isl_give isl_basic_set
*isl_basic_set_apply(__isl_take isl_basic_set
*bset
,
5387 __isl_take isl_basic_map
*bmap
)
5389 if (isl_basic_map_check_compatible_domain(bmap
, bset
) < 0)
5392 return bset_from_bmap(isl_basic_map_apply_range(bset_to_bmap(bset
),
5395 isl_basic_set_free(bset
);
5396 isl_basic_map_free(bmap
);
5400 __isl_give isl_basic_map
*isl_basic_map_apply_domain(
5401 __isl_take isl_basic_map
*bmap1
, __isl_take isl_basic_map
*bmap2
)
5403 if (isl_basic_map_check_equal_params(bmap1
, bmap2
) < 0)
5405 if (!isl_space_tuple_is_equal(bmap1
->dim
, isl_dim_in
,
5406 bmap2
->dim
, isl_dim_in
))
5407 isl_die(isl_basic_map_get_ctx(bmap1
), isl_error_invalid
,
5408 "spaces don't match", goto error
);
5410 bmap1
= isl_basic_map_reverse(bmap1
);
5411 bmap1
= isl_basic_map_apply_range(bmap1
, bmap2
);
5412 return isl_basic_map_reverse(bmap1
);
5414 isl_basic_map_free(bmap1
);
5415 isl_basic_map_free(bmap2
);
5419 /* Given two basic maps A -> f(A) and B -> g(B), construct a basic map
5420 * A \cap B -> f(A) + f(B)
5422 __isl_give isl_basic_map
*isl_basic_map_sum(__isl_take isl_basic_map
*bmap1
,
5423 __isl_take isl_basic_map
*bmap2
)
5425 isl_size n_in
, n_out
, nparam
;
5426 unsigned total
, pos
;
5427 struct isl_basic_map
*bmap
= NULL
;
5428 struct isl_dim_map
*dim_map1
, *dim_map2
;
5431 if (isl_basic_map_check_equal_space(bmap1
, bmap2
) < 0)
5434 nparam
= isl_basic_map_dim(bmap1
, isl_dim_param
);
5435 n_in
= isl_basic_map_dim(bmap1
, isl_dim_in
);
5436 n_out
= isl_basic_map_dim(bmap1
, isl_dim_out
);
5437 if (nparam
< 0 || n_in
< 0 || n_out
< 0)
5440 total
= nparam
+ n_in
+ n_out
+ bmap1
->n_div
+ bmap2
->n_div
+ 2 * n_out
;
5441 dim_map1
= isl_dim_map_alloc(bmap1
->ctx
, total
);
5442 dim_map2
= isl_dim_map_alloc(bmap2
->ctx
, total
);
5443 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_param
, pos
= 0);
5444 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_param
, pos
);
5445 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_in
, pos
+= nparam
);
5446 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_in
, pos
);
5447 isl_dim_map_div(dim_map1
, bmap1
, pos
+= n_in
+ n_out
);
5448 isl_dim_map_div(dim_map2
, bmap2
, pos
+= bmap1
->n_div
);
5449 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_out
, pos
+= bmap2
->n_div
);
5450 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_out
, pos
+= n_out
);
5452 bmap
= isl_basic_map_alloc_space(isl_space_copy(bmap1
->dim
),
5453 bmap1
->n_div
+ bmap2
->n_div
+ 2 * n_out
,
5454 bmap1
->n_eq
+ bmap2
->n_eq
+ n_out
,
5455 bmap1
->n_ineq
+ bmap2
->n_ineq
);
5456 for (i
= 0; i
< n_out
; ++i
) {
5457 int j
= isl_basic_map_alloc_equality(bmap
);
5460 isl_seq_clr(bmap
->eq
[j
], 1+total
);
5461 isl_int_set_si(bmap
->eq
[j
][1+nparam
+n_in
+i
], -1);
5462 isl_int_set_si(bmap
->eq
[j
][1+pos
+i
], 1);
5463 isl_int_set_si(bmap
->eq
[j
][1+pos
-n_out
+i
], 1);
5465 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap1
, dim_map1
);
5466 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap2
, dim_map2
);
5467 bmap
= add_divs(bmap
, 2 * n_out
);
5469 bmap
= isl_basic_map_simplify(bmap
);
5470 return isl_basic_map_finalize(bmap
);
5472 isl_basic_map_free(bmap
);
5473 isl_basic_map_free(bmap1
);
5474 isl_basic_map_free(bmap2
);
5478 /* Given two maps A -> f(A) and B -> g(B), construct a map
5479 * A \cap B -> f(A) + f(B)
5481 __isl_give isl_map
*isl_map_sum(__isl_take isl_map
*map1
,
5482 __isl_take isl_map
*map2
)
5484 struct isl_map
*result
;
5487 if (isl_map_check_equal_space(map1
, map2
) < 0)
5490 result
= isl_map_alloc_space(isl_space_copy(map1
->dim
),
5491 map1
->n
* map2
->n
, 0);
5494 for (i
= 0; i
< map1
->n
; ++i
)
5495 for (j
= 0; j
< map2
->n
; ++j
) {
5496 struct isl_basic_map
*part
;
5497 part
= isl_basic_map_sum(
5498 isl_basic_map_copy(map1
->p
[i
]),
5499 isl_basic_map_copy(map2
->p
[j
]));
5500 if (isl_basic_map_is_empty(part
))
5501 isl_basic_map_free(part
);
5503 result
= isl_map_add_basic_map(result
, part
);
5516 __isl_give isl_set
*isl_set_sum(__isl_take isl_set
*set1
,
5517 __isl_take isl_set
*set2
)
5519 return set_from_map(isl_map_sum(set_to_map(set1
), set_to_map(set2
)));
5522 /* Given a basic map A -> f(A), construct A -> -f(A).
5524 __isl_give isl_basic_map
*isl_basic_map_neg(__isl_take isl_basic_map
*bmap
)
5530 bmap
= isl_basic_map_cow(bmap
);
5531 n
= isl_basic_map_dim(bmap
, isl_dim_out
);
5533 return isl_basic_map_free(bmap
);
5535 off
= isl_basic_map_offset(bmap
, isl_dim_out
);
5536 for (i
= 0; i
< bmap
->n_eq
; ++i
)
5537 for (j
= 0; j
< n
; ++j
)
5538 isl_int_neg(bmap
->eq
[i
][off
+j
], bmap
->eq
[i
][off
+j
]);
5539 for (i
= 0; i
< bmap
->n_ineq
; ++i
)
5540 for (j
= 0; j
< n
; ++j
)
5541 isl_int_neg(bmap
->ineq
[i
][off
+j
], bmap
->ineq
[i
][off
+j
]);
5542 for (i
= 0; i
< bmap
->n_div
; ++i
)
5543 for (j
= 0; j
< n
; ++j
)
5544 isl_int_neg(bmap
->div
[i
][1+off
+j
], bmap
->div
[i
][1+off
+j
]);
5545 bmap
= isl_basic_map_gauss(bmap
, NULL
);
5546 return isl_basic_map_finalize(bmap
);
5549 __isl_give isl_basic_set
*isl_basic_set_neg(__isl_take isl_basic_set
*bset
)
5551 return isl_basic_map_neg(bset
);
5554 /* Given a map A -> f(A), construct A -> -f(A).
5556 __isl_give isl_map
*isl_map_neg(__isl_take isl_map
*map
)
5560 map
= isl_map_cow(map
);
5564 for (i
= 0; i
< map
->n
; ++i
) {
5565 map
->p
[i
] = isl_basic_map_neg(map
->p
[i
]);
5576 __isl_give isl_set
*isl_set_neg(__isl_take isl_set
*set
)
5578 return set_from_map(isl_map_neg(set_to_map(set
)));
5581 /* Given a basic map A -> f(A) and an integer d, construct a basic map
5582 * A -> floor(f(A)/d).
5584 __isl_give isl_basic_map
*isl_basic_map_floordiv(__isl_take isl_basic_map
*bmap
,
5587 isl_size n_in
, n_out
, nparam
;
5588 unsigned total
, pos
;
5589 struct isl_basic_map
*result
= NULL
;
5590 struct isl_dim_map
*dim_map
;
5593 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
5594 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
5595 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
5596 if (nparam
< 0 || n_in
< 0 || n_out
< 0)
5597 return isl_basic_map_free(bmap
);
5599 total
= nparam
+ n_in
+ n_out
+ bmap
->n_div
+ n_out
;
5600 dim_map
= isl_dim_map_alloc(bmap
->ctx
, total
);
5601 isl_dim_map_dim(dim_map
, bmap
->dim
, isl_dim_param
, pos
= 0);
5602 isl_dim_map_dim(dim_map
, bmap
->dim
, isl_dim_in
, pos
+= nparam
);
5603 isl_dim_map_div(dim_map
, bmap
, pos
+= n_in
+ n_out
);
5604 isl_dim_map_dim(dim_map
, bmap
->dim
, isl_dim_out
, pos
+= bmap
->n_div
);
5606 result
= isl_basic_map_alloc_space(isl_space_copy(bmap
->dim
),
5607 bmap
->n_div
+ n_out
,
5608 bmap
->n_eq
, bmap
->n_ineq
+ 2 * n_out
);
5609 result
= isl_basic_map_add_constraints_dim_map(result
, bmap
, dim_map
);
5610 result
= add_divs(result
, n_out
);
5611 for (i
= 0; i
< n_out
; ++i
) {
5613 j
= isl_basic_map_alloc_inequality(result
);
5616 isl_seq_clr(result
->ineq
[j
], 1+total
);
5617 isl_int_neg(result
->ineq
[j
][1+nparam
+n_in
+i
], d
);
5618 isl_int_set_si(result
->ineq
[j
][1+pos
+i
], 1);
5619 j
= isl_basic_map_alloc_inequality(result
);
5622 isl_seq_clr(result
->ineq
[j
], 1+total
);
5623 isl_int_set(result
->ineq
[j
][1+nparam
+n_in
+i
], d
);
5624 isl_int_set_si(result
->ineq
[j
][1+pos
+i
], -1);
5625 isl_int_sub_ui(result
->ineq
[j
][0], d
, 1);
5628 result
= isl_basic_map_simplify(result
);
5629 return isl_basic_map_finalize(result
);
5631 isl_basic_map_free(result
);
5635 /* Given a map A -> f(A) and an integer d, construct a map
5636 * A -> floor(f(A)/d).
5638 __isl_give isl_map
*isl_map_floordiv(__isl_take isl_map
*map
, isl_int d
)
5642 map
= isl_map_cow(map
);
5646 ISL_F_CLR(map
, ISL_MAP_DISJOINT
);
5647 for (i
= 0; i
< map
->n
; ++i
) {
5648 map
->p
[i
] = isl_basic_map_floordiv(map
->p
[i
], d
);
5652 map
= isl_map_unmark_normalized(map
);
5660 /* Given a map A -> f(A) and an integer d, construct a map
5661 * A -> floor(f(A)/d).
5663 __isl_give isl_map
*isl_map_floordiv_val(__isl_take isl_map
*map
,
5664 __isl_take isl_val
*d
)
5668 if (!isl_val_is_int(d
))
5669 isl_die(isl_val_get_ctx(d
), isl_error_invalid
,
5670 "expecting integer denominator", goto error
);
5671 map
= isl_map_floordiv(map
, d
->n
);
5680 static __isl_give isl_basic_map
*var_equal(__isl_take isl_basic_map
*bmap
,
5688 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
5689 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
5690 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
5691 if (total
< 0 || nparam
< 0 || n_in
< 0)
5692 return isl_basic_map_free(bmap
);
5693 i
= isl_basic_map_alloc_equality(bmap
);
5696 isl_seq_clr(bmap
->eq
[i
], 1 + total
);
5697 isl_int_set_si(bmap
->eq
[i
][1+nparam
+pos
], -1);
5698 isl_int_set_si(bmap
->eq
[i
][1+nparam
+n_in
+pos
], 1);
5699 return isl_basic_map_finalize(bmap
);
5701 isl_basic_map_free(bmap
);
5705 /* Add a constraint to "bmap" expressing i_pos < o_pos
5707 static __isl_give isl_basic_map
*var_less(__isl_take isl_basic_map
*bmap
,
5715 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
5716 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
5717 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
5718 if (total
< 0 || nparam
< 0 || n_in
< 0)
5719 return isl_basic_map_free(bmap
);
5720 i
= isl_basic_map_alloc_inequality(bmap
);
5723 isl_seq_clr(bmap
->ineq
[i
], 1 + total
);
5724 isl_int_set_si(bmap
->ineq
[i
][0], -1);
5725 isl_int_set_si(bmap
->ineq
[i
][1+nparam
+pos
], -1);
5726 isl_int_set_si(bmap
->ineq
[i
][1+nparam
+n_in
+pos
], 1);
5727 return isl_basic_map_finalize(bmap
);
5729 isl_basic_map_free(bmap
);
5733 /* Add a constraint to "bmap" expressing i_pos <= o_pos
5735 static __isl_give isl_basic_map
*var_less_or_equal(
5736 __isl_take isl_basic_map
*bmap
, unsigned pos
)
5743 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
5744 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
5745 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
5746 if (total
< 0 || nparam
< 0 || n_in
< 0)
5747 return isl_basic_map_free(bmap
);
5748 i
= isl_basic_map_alloc_inequality(bmap
);
5751 isl_seq_clr(bmap
->ineq
[i
], 1 + total
);
5752 isl_int_set_si(bmap
->ineq
[i
][1+nparam
+pos
], -1);
5753 isl_int_set_si(bmap
->ineq
[i
][1+nparam
+n_in
+pos
], 1);
5754 return isl_basic_map_finalize(bmap
);
5756 isl_basic_map_free(bmap
);
5760 /* Add a constraint to "bmap" expressing i_pos > o_pos
5762 static __isl_give isl_basic_map
*var_more(__isl_take isl_basic_map
*bmap
,
5770 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
5771 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
5772 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
5773 if (total
< 0 || nparam
< 0 || n_in
< 0)
5774 return isl_basic_map_free(bmap
);
5775 i
= isl_basic_map_alloc_inequality(bmap
);
5778 isl_seq_clr(bmap
->ineq
[i
], 1 + total
);
5779 isl_int_set_si(bmap
->ineq
[i
][0], -1);
5780 isl_int_set_si(bmap
->ineq
[i
][1+nparam
+pos
], 1);
5781 isl_int_set_si(bmap
->ineq
[i
][1+nparam
+n_in
+pos
], -1);
5782 return isl_basic_map_finalize(bmap
);
5784 isl_basic_map_free(bmap
);
5788 /* Add a constraint to "bmap" expressing i_pos >= o_pos
5790 static __isl_give isl_basic_map
*var_more_or_equal(
5791 __isl_take isl_basic_map
*bmap
, unsigned pos
)
5798 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
5799 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
5800 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
5801 if (total
< 0 || nparam
< 0 || n_in
< 0)
5802 return isl_basic_map_free(bmap
);
5803 i
= isl_basic_map_alloc_inequality(bmap
);
5806 isl_seq_clr(bmap
->ineq
[i
], 1 + total
);
5807 isl_int_set_si(bmap
->ineq
[i
][1+nparam
+pos
], 1);
5808 isl_int_set_si(bmap
->ineq
[i
][1+nparam
+n_in
+pos
], -1);
5809 return isl_basic_map_finalize(bmap
);
5811 isl_basic_map_free(bmap
);
5815 __isl_give isl_basic_map
*isl_basic_map_equal(
5816 __isl_take isl_space
*space
, unsigned n_equal
)
5819 struct isl_basic_map
*bmap
;
5820 bmap
= isl_basic_map_alloc_space(space
, 0, n_equal
, 0);
5823 for (i
= 0; i
< n_equal
&& bmap
; ++i
)
5824 bmap
= var_equal(bmap
, i
);
5825 return isl_basic_map_finalize(bmap
);
5828 /* Return a relation on of dimension "space" expressing i_[0..pos] << o_[0..pos]
5830 __isl_give isl_basic_map
*isl_basic_map_less_at(__isl_take isl_space
*space
,
5834 struct isl_basic_map
*bmap
;
5835 bmap
= isl_basic_map_alloc_space(space
, 0, pos
, 1);
5838 for (i
= 0; i
< pos
&& bmap
; ++i
)
5839 bmap
= var_equal(bmap
, i
);
5841 bmap
= var_less(bmap
, pos
);
5842 return isl_basic_map_finalize(bmap
);
5845 /* Return a relation on "space" expressing i_[0..pos] <<= o_[0..pos]
5847 __isl_give isl_basic_map
*isl_basic_map_less_or_equal_at(
5848 __isl_take isl_space
*space
, unsigned pos
)
5851 isl_basic_map
*bmap
;
5853 bmap
= isl_basic_map_alloc_space(space
, 0, pos
, 1);
5854 for (i
= 0; i
< pos
; ++i
)
5855 bmap
= var_equal(bmap
, i
);
5856 bmap
= var_less_or_equal(bmap
, pos
);
5857 return isl_basic_map_finalize(bmap
);
5860 /* Return a relation on "space" expressing i_pos > o_pos
5862 __isl_give isl_basic_map
*isl_basic_map_more_at(__isl_take isl_space
*space
,
5866 struct isl_basic_map
*bmap
;
5867 bmap
= isl_basic_map_alloc_space(space
, 0, pos
, 1);
5870 for (i
= 0; i
< pos
&& bmap
; ++i
)
5871 bmap
= var_equal(bmap
, i
);
5873 bmap
= var_more(bmap
, pos
);
5874 return isl_basic_map_finalize(bmap
);
5877 /* Return a relation on "space" expressing i_[0..pos] >>= o_[0..pos]
5879 __isl_give isl_basic_map
*isl_basic_map_more_or_equal_at(
5880 __isl_take isl_space
*space
, unsigned pos
)
5883 isl_basic_map
*bmap
;
5885 bmap
= isl_basic_map_alloc_space(space
, 0, pos
, 1);
5886 for (i
= 0; i
< pos
; ++i
)
5887 bmap
= var_equal(bmap
, i
);
5888 bmap
= var_more_or_equal(bmap
, pos
);
5889 return isl_basic_map_finalize(bmap
);
5892 static __isl_give isl_map
*map_lex_lte_first(__isl_take isl_space
*space
,
5893 unsigned n
, int equal
)
5895 struct isl_map
*map
;
5898 if (n
== 0 && equal
)
5899 return isl_map_universe(space
);
5901 map
= isl_map_alloc_space(isl_space_copy(space
), n
, ISL_MAP_DISJOINT
);
5903 for (i
= 0; i
+ 1 < n
; ++i
)
5904 map
= isl_map_add_basic_map(map
,
5905 isl_basic_map_less_at(isl_space_copy(space
), i
));
5908 map
= isl_map_add_basic_map(map
,
5909 isl_basic_map_less_or_equal_at(space
, n
- 1));
5911 map
= isl_map_add_basic_map(map
,
5912 isl_basic_map_less_at(space
, n
- 1));
5914 isl_space_free(space
);
5919 static __isl_give isl_map
*map_lex_lte(__isl_take isl_space
*space
, int equal
)
5923 return map_lex_lte_first(space
, space
->n_out
, equal
);
5926 __isl_give isl_map
*isl_map_lex_lt_first(__isl_take isl_space
*space
,
5929 return map_lex_lte_first(space
, n
, 0);
5932 __isl_give isl_map
*isl_map_lex_le_first(__isl_take isl_space
*space
,
5935 return map_lex_lte_first(space
, n
, 1);
5938 __isl_give isl_map
*isl_map_lex_lt(__isl_take isl_space
*set_space
)
5940 return map_lex_lte(isl_space_map_from_set(set_space
), 0);
5943 __isl_give isl_map
*isl_map_lex_le(__isl_take isl_space
*set_space
)
5945 return map_lex_lte(isl_space_map_from_set(set_space
), 1);
5948 static __isl_give isl_map
*map_lex_gte_first(__isl_take isl_space
*space
,
5949 unsigned n
, int equal
)
5951 struct isl_map
*map
;
5954 if (n
== 0 && equal
)
5955 return isl_map_universe(space
);
5957 map
= isl_map_alloc_space(isl_space_copy(space
), n
, ISL_MAP_DISJOINT
);
5959 for (i
= 0; i
+ 1 < n
; ++i
)
5960 map
= isl_map_add_basic_map(map
,
5961 isl_basic_map_more_at(isl_space_copy(space
), i
));
5964 map
= isl_map_add_basic_map(map
,
5965 isl_basic_map_more_or_equal_at(space
, n
- 1));
5967 map
= isl_map_add_basic_map(map
,
5968 isl_basic_map_more_at(space
, n
- 1));
5970 isl_space_free(space
);
5975 static __isl_give isl_map
*map_lex_gte(__isl_take isl_space
*space
, int equal
)
5979 return map_lex_gte_first(space
, space
->n_out
, equal
);
5982 __isl_give isl_map
*isl_map_lex_gt_first(__isl_take isl_space
*space
,
5985 return map_lex_gte_first(space
, n
, 0);
5988 __isl_give isl_map
*isl_map_lex_ge_first(__isl_take isl_space
*space
,
5991 return map_lex_gte_first(space
, n
, 1);
5994 __isl_give isl_map
*isl_map_lex_gt(__isl_take isl_space
*set_space
)
5996 return map_lex_gte(isl_space_map_from_set(set_space
), 0);
5999 __isl_give isl_map
*isl_map_lex_ge(__isl_take isl_space
*set_space
)
6001 return map_lex_gte(isl_space_map_from_set(set_space
), 1);
6004 __isl_give isl_map
*isl_set_lex_le_set(__isl_take isl_set
*set1
,
6005 __isl_take isl_set
*set2
)
6008 map
= isl_map_lex_le(isl_set_get_space(set1
));
6009 map
= isl_map_intersect_domain(map
, set1
);
6010 map
= isl_map_intersect_range(map
, set2
);
6014 __isl_give isl_map
*isl_set_lex_lt_set(__isl_take isl_set
*set1
,
6015 __isl_take isl_set
*set2
)
6018 map
= isl_map_lex_lt(isl_set_get_space(set1
));
6019 map
= isl_map_intersect_domain(map
, set1
);
6020 map
= isl_map_intersect_range(map
, set2
);
6024 __isl_give isl_map
*isl_set_lex_ge_set(__isl_take isl_set
*set1
,
6025 __isl_take isl_set
*set2
)
6028 map
= isl_map_lex_ge(isl_set_get_space(set1
));
6029 map
= isl_map_intersect_domain(map
, set1
);
6030 map
= isl_map_intersect_range(map
, set2
);
6034 __isl_give isl_map
*isl_set_lex_gt_set(__isl_take isl_set
*set1
,
6035 __isl_take isl_set
*set2
)
6038 map
= isl_map_lex_gt(isl_set_get_space(set1
));
6039 map
= isl_map_intersect_domain(map
, set1
);
6040 map
= isl_map_intersect_range(map
, set2
);
6044 __isl_give isl_map
*isl_map_lex_le_map(__isl_take isl_map
*map1
,
6045 __isl_take isl_map
*map2
)
6048 map
= isl_map_lex_le(isl_space_range(isl_map_get_space(map1
)));
6049 map
= isl_map_apply_domain(map
, isl_map_reverse(map1
));
6050 map
= isl_map_apply_range(map
, isl_map_reverse(map2
));
6054 __isl_give isl_map
*isl_map_lex_lt_map(__isl_take isl_map
*map1
,
6055 __isl_take isl_map
*map2
)
6058 map
= isl_map_lex_lt(isl_space_range(isl_map_get_space(map1
)));
6059 map
= isl_map_apply_domain(map
, isl_map_reverse(map1
));
6060 map
= isl_map_apply_range(map
, isl_map_reverse(map2
));
6064 __isl_give isl_map
*isl_map_lex_ge_map(__isl_take isl_map
*map1
,
6065 __isl_take isl_map
*map2
)
6068 map
= isl_map_lex_ge(isl_space_range(isl_map_get_space(map1
)));
6069 map
= isl_map_apply_domain(map
, isl_map_reverse(map1
));
6070 map
= isl_map_apply_range(map
, isl_map_reverse(map2
));
6074 __isl_give isl_map
*isl_map_lex_gt_map(__isl_take isl_map
*map1
,
6075 __isl_take isl_map
*map2
)
6078 map
= isl_map_lex_gt(isl_space_range(isl_map_get_space(map1
)));
6079 map
= isl_map_apply_domain(map
, isl_map_reverse(map1
));
6080 map
= isl_map_apply_range(map
, isl_map_reverse(map2
));
6084 /* For the div d = floor(f/m) at position "div", add the constraint
6088 static __isl_give isl_basic_map
*add_upper_div_constraint(
6089 __isl_take isl_basic_map
*bmap
, unsigned div
)
6092 isl_size v_div
= isl_basic_map_var_offset(bmap
, isl_dim_div
);
6096 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
6097 if (v_div
< 0 || n_div
< 0)
6098 return isl_basic_map_free(bmap
);
6100 i
= isl_basic_map_alloc_inequality(bmap
);
6102 return isl_basic_map_free(bmap
);
6103 isl_seq_cpy(bmap
->ineq
[i
], bmap
->div
[div
] + 1, 1 + v_div
+ n_div
);
6104 isl_int_neg(bmap
->ineq
[i
][1 + pos
], bmap
->div
[div
][0]);
6109 /* For the div d = floor(f/m) at position "div", add the constraint
6111 * -(f-(m-1)) + m d >= 0
6113 static __isl_give isl_basic_map
*add_lower_div_constraint(
6114 __isl_take isl_basic_map
*bmap
, unsigned div
)
6117 isl_size v_div
= isl_basic_map_var_offset(bmap
, isl_dim_div
);
6121 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
6122 if (v_div
< 0 || n_div
< 0)
6123 return isl_basic_map_free(bmap
);
6125 i
= isl_basic_map_alloc_inequality(bmap
);
6127 return isl_basic_map_free(bmap
);
6128 isl_seq_neg(bmap
->ineq
[i
], bmap
->div
[div
] + 1, 1 + v_div
+ n_div
);
6129 isl_int_set(bmap
->ineq
[i
][1 + pos
], bmap
->div
[div
][0]);
6130 isl_int_add(bmap
->ineq
[i
][0], bmap
->ineq
[i
][0], bmap
->ineq
[i
][1 + pos
]);
6131 isl_int_sub_ui(bmap
->ineq
[i
][0], bmap
->ineq
[i
][0], 1);
6136 /* For the div d = floor(f/m) at position "pos", add the constraints
6139 * -(f-(m-1)) + m d >= 0
6141 * Note that the second constraint is the negation of
6145 __isl_give isl_basic_map
*isl_basic_map_add_div_constraints(
6146 __isl_take isl_basic_map
*bmap
, unsigned pos
)
6148 bmap
= add_upper_div_constraint(bmap
, pos
);
6149 bmap
= add_lower_div_constraint(bmap
, pos
);
6153 /* For each known div d = floor(f/m), add the constraints
6156 * -(f-(m-1)) + m d >= 0
6158 * Remove duplicate constraints in case of some these div constraints
6159 * already appear in "bmap".
6161 __isl_give isl_basic_map
*isl_basic_map_add_known_div_constraints(
6162 __isl_take isl_basic_map
*bmap
)
6166 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
6168 return isl_basic_map_free(bmap
);
6172 bmap
= add_known_div_constraints(bmap
);
6173 bmap
= isl_basic_map_remove_duplicate_constraints(bmap
, NULL
, 0);
6174 bmap
= isl_basic_map_finalize(bmap
);
6178 /* Add the div constraint of sign "sign" for div "div" of "bmap".
6180 * In particular, if this div is of the form d = floor(f/m),
6181 * then add the constraint
6185 * if sign < 0 or the constraint
6187 * -(f-(m-1)) + m d >= 0
6191 __isl_give isl_basic_map
*isl_basic_map_add_div_constraint(
6192 __isl_take isl_basic_map
*bmap
, unsigned div
, int sign
)
6195 return add_upper_div_constraint(bmap
, div
);
6197 return add_lower_div_constraint(bmap
, div
);
6200 __isl_give isl_basic_set
*isl_basic_map_underlying_set(
6201 __isl_take isl_basic_map
*bmap
)
6207 if (bmap
->dim
->nparam
== 0 && bmap
->dim
->n_in
== 0 &&
6209 !isl_space_is_named_or_nested(bmap
->dim
, isl_dim_in
) &&
6210 !isl_space_is_named_or_nested(bmap
->dim
, isl_dim_out
))
6211 return bset_from_bmap(bmap
);
6212 bmap
= isl_basic_map_cow(bmap
);
6215 space
= isl_basic_map_take_space(bmap
);
6216 space
= isl_space_underlying(space
, bmap
->n_div
);
6217 bmap
= isl_basic_map_restore_space(bmap
, space
);
6220 bmap
->extra
-= bmap
->n_div
;
6222 bmap
= isl_basic_map_finalize(bmap
);
6223 return bset_from_bmap(bmap
);
6225 isl_basic_map_free(bmap
);
6229 __isl_give isl_basic_set
*isl_basic_set_underlying_set(
6230 __isl_take isl_basic_set
*bset
)
6232 return isl_basic_map_underlying_set(bset_to_bmap(bset
));
6235 /* Replace each element in "list" by the result of applying
6236 * isl_basic_map_underlying_set to the element.
6238 __isl_give isl_basic_set_list
*isl_basic_map_list_underlying_set(
6239 __isl_take isl_basic_map_list
*list
)
6244 n
= isl_basic_map_list_n_basic_map(list
);
6248 for (i
= 0; i
< n
; ++i
) {
6249 isl_basic_map
*bmap
;
6250 isl_basic_set
*bset
;
6252 bmap
= isl_basic_map_list_get_basic_map(list
, i
);
6253 bset
= isl_basic_set_underlying_set(bmap
);
6254 list
= isl_basic_set_list_set_basic_set(list
, i
, bset
);
6259 isl_basic_map_list_free(list
);
6263 __isl_give isl_basic_map
*isl_basic_map_overlying_set(
6264 __isl_take isl_basic_set
*bset
, __isl_take isl_basic_map
*like
)
6266 struct isl_basic_map
*bmap
;
6267 struct isl_ctx
*ctx
;
6268 isl_size dim
, bmap_total
;
6275 if (isl_basic_set_check_no_params(bset
) < 0 ||
6276 isl_basic_set_check_no_locals(bset
) < 0)
6278 dim
= isl_basic_set_dim(bset
, isl_dim_set
);
6279 bmap_total
= isl_basic_map_dim(like
, isl_dim_all
);
6280 if (dim
< 0 || bmap_total
< 0)
6282 isl_assert(ctx
, dim
== bmap_total
, goto error
);
6283 if (like
->n_div
== 0) {
6284 isl_space
*space
= isl_basic_map_get_space(like
);
6285 isl_basic_map_free(like
);
6286 return isl_basic_map_reset_space(bset
, space
);
6288 bset
= isl_basic_set_cow(bset
);
6291 total
= dim
+ bset
->extra
;
6292 bmap
= bset_to_bmap(bset
);
6293 isl_space_free(isl_basic_map_take_space(bmap
));
6294 bmap
= isl_basic_map_restore_space(bmap
, isl_basic_map_get_space(like
));
6297 bmap
->n_div
= like
->n_div
;
6298 bmap
->extra
+= like
->n_div
;
6302 ltotal
= total
- bmap
->extra
+ like
->extra
;
6305 bmap
->block2
= isl_blk_extend(ctx
, bmap
->block2
,
6306 bmap
->extra
* (1 + 1 + total
));
6307 if (isl_blk_is_error(bmap
->block2
))
6309 div
= isl_realloc_array(ctx
, bmap
->div
, isl_int
*, bmap
->extra
);
6313 for (i
= 0; i
< bmap
->extra
; ++i
)
6314 bmap
->div
[i
] = bmap
->block2
.data
+ i
* (1 + 1 + total
);
6315 for (i
= 0; i
< like
->n_div
; ++i
) {
6316 isl_seq_cpy(bmap
->div
[i
], like
->div
[i
], 1 + 1 + ltotal
);
6317 isl_seq_clr(bmap
->div
[i
]+1+1+ltotal
, total
- ltotal
);
6319 bmap
= isl_basic_map_add_known_div_constraints(bmap
);
6321 isl_basic_map_free(like
);
6322 bmap
= isl_basic_map_simplify(bmap
);
6323 bmap
= isl_basic_map_finalize(bmap
);
6326 isl_basic_map_free(like
);
6327 isl_basic_set_free(bset
);
6331 __isl_give isl_basic_set
*isl_basic_set_from_underlying_set(
6332 __isl_take isl_basic_set
*bset
, __isl_take isl_basic_set
*like
)
6334 return bset_from_bmap(isl_basic_map_overlying_set(bset
,
6335 bset_to_bmap(like
)));
6338 __isl_give isl_set
*isl_map_underlying_set(__isl_take isl_map
*map
)
6342 map
= isl_map_cow(map
);
6345 map
->dim
= isl_space_cow(map
->dim
);
6349 for (i
= 1; i
< map
->n
; ++i
)
6350 isl_assert(map
->ctx
, map
->p
[0]->n_div
== map
->p
[i
]->n_div
,
6352 for (i
= 0; i
< map
->n
; ++i
) {
6353 map
->p
[i
] = bset_to_bmap(
6354 isl_basic_map_underlying_set(map
->p
[i
]));
6359 map
->dim
= isl_space_underlying(map
->dim
, 0);
6361 isl_space_free(map
->dim
);
6362 map
->dim
= isl_space_copy(map
->p
[0]->dim
);
6366 return set_from_map(map
);
6372 /* Replace the space of "bmap" by "space".
6374 * If the space of "bmap" is identical to "space" (including the identifiers
6375 * of the input and output dimensions), then simply return the original input.
6377 __isl_give isl_basic_map
*isl_basic_map_reset_space(
6378 __isl_take isl_basic_map
*bmap
, __isl_take isl_space
*space
)
6381 isl_space
*bmap_space
;
6383 bmap_space
= isl_basic_map_peek_space(bmap
);
6384 equal
= isl_space_is_equal(bmap_space
, space
);
6385 if (equal
>= 0 && equal
)
6386 equal
= isl_space_has_equal_ids(bmap_space
, space
);
6390 isl_space_free(space
);
6393 isl_space_free(isl_basic_map_take_space(bmap
));
6394 bmap
= isl_basic_map_restore_space(bmap
, space
);
6396 bmap
= isl_basic_map_finalize(bmap
);
6400 isl_basic_map_free(bmap
);
6401 isl_space_free(space
);
6405 __isl_give isl_basic_set
*isl_basic_set_reset_space(
6406 __isl_take isl_basic_set
*bset
, __isl_take isl_space
*space
)
6408 return bset_from_bmap(isl_basic_map_reset_space(bset_to_bmap(bset
),
6412 /* Check that the total dimensions of "map" and "space" are the same.
6414 static isl_stat
check_map_space_equal_total_dim(__isl_keep isl_map
*map
,
6415 __isl_keep isl_space
*space
)
6417 isl_size dim1
, dim2
;
6419 dim1
= isl_map_dim(map
, isl_dim_all
);
6420 dim2
= isl_space_dim(space
, isl_dim_all
);
6421 if (dim1
< 0 || dim2
< 0)
6422 return isl_stat_error
;
6425 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
6426 "total dimensions do not match", return isl_stat_error
);
6429 __isl_give isl_map
*isl_map_reset_space(__isl_take isl_map
*map
,
6430 __isl_take isl_space
*space
)
6434 map
= isl_map_cow(map
);
6438 for (i
= 0; i
< map
->n
; ++i
) {
6439 map
->p
[i
] = isl_basic_map_reset_space(map
->p
[i
],
6440 isl_space_copy(space
));
6444 isl_space_free(isl_map_take_space(map
));
6445 map
= isl_map_restore_space(map
, space
);
6450 isl_space_free(space
);
6454 /* Replace the space of "map" by "space", without modifying
6455 * the dimension of "map".
6457 * If the space of "map" is identical to "space" (including the identifiers
6458 * of the input and output dimensions), then simply return the original input.
6460 __isl_give isl_map
*isl_map_reset_equal_dim_space(__isl_take isl_map
*map
,
6461 __isl_take isl_space
*space
)
6464 isl_space
*map_space
;
6466 map_space
= isl_map_peek_space(map
);
6467 equal
= isl_space_is_equal(map_space
, space
);
6468 if (equal
>= 0 && equal
)
6469 equal
= isl_space_has_equal_ids(map_space
, space
);
6473 isl_space_free(space
);
6476 if (check_map_space_equal_total_dim(map
, space
) < 0)
6478 return isl_map_reset_space(map
, space
);
6481 isl_space_free(space
);
6485 __isl_give isl_set
*isl_set_reset_space(__isl_take isl_set
*set
,
6486 __isl_take isl_space
*space
)
6488 return set_from_map(isl_map_reset_space(set_to_map(set
), space
));
6491 /* Compute the parameter domain of the given basic set.
6493 __isl_give isl_basic_set
*isl_basic_set_params(__isl_take isl_basic_set
*bset
)
6499 is_params
= isl_basic_set_is_params(bset
);
6501 return isl_basic_set_free(bset
);
6505 n
= isl_basic_set_dim(bset
, isl_dim_set
);
6507 return isl_basic_set_free(bset
);
6508 bset
= isl_basic_set_project_out(bset
, isl_dim_set
, 0, n
);
6509 space
= isl_basic_set_get_space(bset
);
6510 space
= isl_space_params(space
);
6511 bset
= isl_basic_set_reset_space(bset
, space
);
6515 /* Construct a zero-dimensional basic set with the given parameter domain.
6517 __isl_give isl_basic_set
*isl_basic_set_from_params(
6518 __isl_take isl_basic_set
*bset
)
6521 space
= isl_basic_set_get_space(bset
);
6522 space
= isl_space_set_from_params(space
);
6523 bset
= isl_basic_set_reset_space(bset
, space
);
6527 /* Compute the parameter domain of the given set.
6529 __isl_give isl_set
*isl_set_params(__isl_take isl_set
*set
)
6531 return isl_map_params(set_to_map(set
));
6534 /* Construct a zero-dimensional set with the given parameter domain.
6536 __isl_give isl_set
*isl_set_from_params(__isl_take isl_set
*set
)
6539 space
= isl_set_get_space(set
);
6540 space
= isl_space_set_from_params(space
);
6541 set
= isl_set_reset_space(set
, space
);
6545 /* Compute the parameter domain of the given map.
6547 __isl_give isl_set
*isl_map_params(__isl_take isl_map
*map
)
6550 isl_size n_in
, n_out
;
6552 n_in
= isl_map_dim(map
, isl_dim_in
);
6553 n_out
= isl_map_dim(map
, isl_dim_out
);
6554 if (n_in
< 0 || n_out
< 0)
6555 return isl_map_free(map
);
6556 map
= isl_map_project_out(map
, isl_dim_in
, 0, n_in
);
6557 map
= isl_map_project_out(map
, isl_dim_out
, 0, n_out
);
6558 space
= isl_map_get_space(map
);
6559 space
= isl_space_params(space
);
6560 map
= isl_map_reset_space(map
, space
);
6564 __isl_give isl_basic_set
*isl_basic_map_domain(__isl_take isl_basic_map
*bmap
)
6569 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
6571 return isl_basic_map_free(bmap
);
6572 space
= isl_space_domain(isl_basic_map_get_space(bmap
));
6574 bmap
= isl_basic_map_project_out(bmap
, isl_dim_out
, 0, n_out
);
6576 return isl_basic_map_reset_space(bmap
, space
);
6579 isl_bool
isl_basic_map_may_be_set(__isl_keep isl_basic_map
*bmap
)
6582 return isl_bool_error
;
6583 return isl_space_may_be_set(bmap
->dim
);
6586 /* Is this basic map actually a set?
6587 * Users should never call this function. Outside of isl,
6588 * the type should indicate whether something is a set or a map.
6590 isl_bool
isl_basic_map_is_set(__isl_keep isl_basic_map
*bmap
)
6593 return isl_bool_error
;
6594 return isl_space_is_set(bmap
->dim
);
6597 __isl_give isl_basic_set
*isl_basic_map_range(__isl_take isl_basic_map
*bmap
)
6601 is_set
= isl_basic_map_is_set(bmap
);
6606 return isl_basic_map_domain(isl_basic_map_reverse(bmap
));
6608 isl_basic_map_free(bmap
);
6612 __isl_give isl_basic_map
*isl_basic_map_domain_map(
6613 __isl_take isl_basic_map
*bmap
)
6617 isl_basic_map
*domain
;
6618 isl_size nparam
, n_in
, n_out
;
6620 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
6621 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
6622 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
6623 if (nparam
< 0 || n_in
< 0 || n_out
< 0)
6624 return isl_basic_map_free(bmap
);
6626 space
= isl_basic_map_get_space(bmap
);
6627 space
= isl_space_from_range(isl_space_domain(space
));
6628 domain
= isl_basic_map_universe(space
);
6630 bmap
= isl_basic_map_from_domain(isl_basic_map_wrap(bmap
));
6631 bmap
= isl_basic_map_apply_range(bmap
, domain
);
6632 bmap
= isl_basic_map_extend_constraints(bmap
, n_in
, 0);
6634 for (i
= 0; i
< n_in
; ++i
)
6635 bmap
= isl_basic_map_equate(bmap
, isl_dim_in
, i
,
6638 bmap
= isl_basic_map_gauss(bmap
, NULL
);
6639 return isl_basic_map_finalize(bmap
);
6642 __isl_give isl_basic_map
*isl_basic_map_range_map(
6643 __isl_take isl_basic_map
*bmap
)
6647 isl_basic_map
*range
;
6648 isl_size nparam
, n_in
, n_out
;
6650 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
6651 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
6652 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
6653 if (nparam
< 0 || n_in
< 0 || n_out
< 0)
6654 return isl_basic_map_free(bmap
);
6656 space
= isl_basic_map_get_space(bmap
);
6657 space
= isl_space_from_range(isl_space_range(space
));
6658 range
= isl_basic_map_universe(space
);
6660 bmap
= isl_basic_map_from_domain(isl_basic_map_wrap(bmap
));
6661 bmap
= isl_basic_map_apply_range(bmap
, range
);
6662 bmap
= isl_basic_map_extend_constraints(bmap
, n_out
, 0);
6664 for (i
= 0; i
< n_out
; ++i
)
6665 bmap
= isl_basic_map_equate(bmap
, isl_dim_in
, n_in
+ i
,
6668 bmap
= isl_basic_map_gauss(bmap
, NULL
);
6669 return isl_basic_map_finalize(bmap
);
6672 int isl_map_may_be_set(__isl_keep isl_map
*map
)
6676 return isl_space_may_be_set(map
->dim
);
6679 /* Is this map actually a set?
6680 * Users should never call this function. Outside of isl,
6681 * the type should indicate whether something is a set or a map.
6683 isl_bool
isl_map_is_set(__isl_keep isl_map
*map
)
6686 return isl_bool_error
;
6687 return isl_space_is_set(map
->dim
);
6690 __isl_give isl_set
*isl_map_range(__isl_take isl_map
*map
)
6695 n_in
= isl_map_dim(map
, isl_dim_in
);
6697 return set_from_map(isl_map_free(map
));
6698 space
= isl_space_range(isl_map_get_space(map
));
6700 map
= isl_map_project_out(map
, isl_dim_in
, 0, n_in
);
6702 return set_from_map(isl_map_reset_space(map
, space
));
6705 /* Transform "map" by applying "fn_space" to its space and "fn_bmap"
6706 * to each of its basic maps.
6708 static __isl_give isl_map
*isl_map_transform(__isl_take isl_map
*map
,
6709 __isl_give isl_space
*(*fn_space
)(__isl_take isl_space
*space
),
6710 __isl_give isl_basic_map
*(*fn_bmap
)(__isl_take isl_basic_map
*bmap
))
6715 map
= isl_map_cow(map
);
6719 for (i
= 0; i
< map
->n
; ++i
) {
6720 map
->p
[i
] = fn_bmap(map
->p
[i
]);
6722 return isl_map_free(map
);
6724 map
= isl_map_unmark_normalized(map
);
6726 space
= isl_map_take_space(map
);
6727 space
= fn_space(space
);
6728 map
= isl_map_restore_space(map
, space
);
6733 __isl_give isl_map
*isl_map_domain_map(__isl_take isl_map
*map
)
6735 return isl_map_transform(map
, &isl_space_domain_map
,
6736 &isl_basic_map_domain_map
);
6739 __isl_give isl_map
*isl_map_range_map(__isl_take isl_map
*map
)
6741 return isl_map_transform(map
, &isl_space_range_map
,
6742 &isl_basic_map_range_map
);
6745 /* Given a wrapped map of the form A[B -> C],
6746 * return the map A[B -> C] -> B.
6748 __isl_give isl_map
*isl_set_wrapped_domain_map(__isl_take isl_set
*set
)
6755 if (!isl_set_has_tuple_id(set
))
6756 return isl_map_domain_map(isl_set_unwrap(set
));
6758 id
= isl_set_get_tuple_id(set
);
6759 map
= isl_map_domain_map(isl_set_unwrap(set
));
6760 map
= isl_map_set_tuple_id(map
, isl_dim_in
, id
);
6765 __isl_give isl_basic_map
*isl_basic_map_from_domain(
6766 __isl_take isl_basic_set
*bset
)
6768 return isl_basic_map_reverse(isl_basic_map_from_range(bset
));
6771 __isl_give isl_basic_map
*isl_basic_map_from_range(
6772 __isl_take isl_basic_set
*bset
)
6775 space
= isl_basic_set_get_space(bset
);
6776 space
= isl_space_from_range(space
);
6777 bset
= isl_basic_set_reset_space(bset
, space
);
6778 return bset_to_bmap(bset
);
6781 /* Create a relation with the given set as range.
6782 * The domain of the created relation is a zero-dimensional
6783 * flat anonymous space.
6785 __isl_give isl_map
*isl_map_from_range(__isl_take isl_set
*set
)
6788 space
= isl_set_get_space(set
);
6789 space
= isl_space_from_range(space
);
6790 set
= isl_set_reset_space(set
, space
);
6791 return set_to_map(set
);
6794 /* Create a relation with the given set as domain.
6795 * The range of the created relation is a zero-dimensional
6796 * flat anonymous space.
6798 __isl_give isl_map
*isl_map_from_domain(__isl_take isl_set
*set
)
6800 return isl_map_reverse(isl_map_from_range(set
));
6803 __isl_give isl_basic_map
*isl_basic_map_from_domain_and_range(
6804 __isl_take isl_basic_set
*domain
, __isl_take isl_basic_set
*range
)
6806 return isl_basic_map_apply_range(isl_basic_map_reverse(domain
), range
);
6809 __isl_give isl_map
*isl_map_from_domain_and_range(__isl_take isl_set
*domain
,
6810 __isl_take isl_set
*range
)
6812 return isl_map_apply_range(isl_map_reverse(domain
), range
);
6815 /* Return a newly allocated isl_map with given space and flags and
6816 * room for "n" basic maps.
6817 * Make sure that all cached information is cleared.
6819 __isl_give isl_map
*isl_map_alloc_space(__isl_take isl_space
*space
, int n
,
6822 struct isl_map
*map
;
6827 isl_die(space
->ctx
, isl_error_internal
,
6828 "negative number of basic maps", goto error
);
6829 map
= isl_calloc(space
->ctx
, struct isl_map
,
6830 sizeof(struct isl_map
) +
6831 (n
- 1) * sizeof(struct isl_basic_map
*));
6835 map
->ctx
= space
->ctx
;
6836 isl_ctx_ref(map
->ctx
);
6844 isl_space_free(space
);
6848 __isl_give isl_basic_map
*isl_basic_map_empty(__isl_take isl_space
*space
)
6850 struct isl_basic_map
*bmap
;
6851 bmap
= isl_basic_map_alloc_space(space
, 0, 1, 0);
6852 bmap
= isl_basic_map_set_to_empty(bmap
);
6856 __isl_give isl_basic_set
*isl_basic_set_empty(__isl_take isl_space
*space
)
6858 struct isl_basic_set
*bset
;
6859 bset
= isl_basic_set_alloc_space(space
, 0, 1, 0);
6860 bset
= isl_basic_set_set_to_empty(bset
);
6864 __isl_give isl_basic_map
*isl_basic_map_universe(__isl_take isl_space
*space
)
6866 struct isl_basic_map
*bmap
;
6867 bmap
= isl_basic_map_alloc_space(space
, 0, 0, 0);
6868 bmap
= isl_basic_map_finalize(bmap
);
6872 __isl_give isl_basic_set
*isl_basic_set_universe(__isl_take isl_space
*space
)
6874 struct isl_basic_set
*bset
;
6875 bset
= isl_basic_set_alloc_space(space
, 0, 0, 0);
6876 bset
= isl_basic_set_finalize(bset
);
6880 __isl_give isl_basic_map
*isl_basic_map_nat_universe(
6881 __isl_take isl_space
*space
)
6884 isl_size total
= isl_space_dim(space
, isl_dim_all
);
6885 isl_basic_map
*bmap
;
6888 space
= isl_space_free(space
);
6889 bmap
= isl_basic_map_alloc_space(space
, 0, 0, total
);
6890 for (i
= 0; i
< total
; ++i
) {
6891 int k
= isl_basic_map_alloc_inequality(bmap
);
6894 isl_seq_clr(bmap
->ineq
[k
], 1 + total
);
6895 isl_int_set_si(bmap
->ineq
[k
][1 + i
], 1);
6899 isl_basic_map_free(bmap
);
6903 __isl_give isl_basic_set
*isl_basic_set_nat_universe(
6904 __isl_take isl_space
*space
)
6906 return isl_basic_map_nat_universe(space
);
6909 __isl_give isl_map
*isl_map_nat_universe(__isl_take isl_space
*space
)
6911 return isl_map_from_basic_map(isl_basic_map_nat_universe(space
));
6914 __isl_give isl_set
*isl_set_nat_universe(__isl_take isl_space
*space
)
6916 return isl_map_nat_universe(space
);
6919 __isl_give isl_map
*isl_map_empty(__isl_take isl_space
*space
)
6921 return isl_map_alloc_space(space
, 0, ISL_MAP_DISJOINT
);
6924 __isl_give isl_set
*isl_set_empty(__isl_take isl_space
*space
)
6926 return isl_set_alloc_space(space
, 0, ISL_MAP_DISJOINT
);
6929 __isl_give isl_map
*isl_map_universe(__isl_take isl_space
*space
)
6931 struct isl_map
*map
;
6934 map
= isl_map_alloc_space(isl_space_copy(space
), 1, ISL_MAP_DISJOINT
);
6935 map
= isl_map_add_basic_map(map
, isl_basic_map_universe(space
));
6939 /* This function performs the same operation as isl_map_universe,
6940 * but is considered as a function on an isl_space when exported.
6942 __isl_give isl_map
*isl_space_universe_map(__isl_take isl_space
*space
)
6944 return isl_map_universe(space
);
6947 __isl_give isl_set
*isl_set_universe(__isl_take isl_space
*space
)
6949 struct isl_set
*set
;
6952 set
= isl_set_alloc_space(isl_space_copy(space
), 1, ISL_MAP_DISJOINT
);
6953 set
= isl_set_add_basic_set(set
, isl_basic_set_universe(space
));
6957 /* This function performs the same operation as isl_set_universe,
6958 * but is considered as a function on an isl_space when exported.
6960 __isl_give isl_set
*isl_space_universe_set(__isl_take isl_space
*space
)
6962 return isl_set_universe(space
);
6965 __isl_give isl_map
*isl_map_dup(__isl_keep isl_map
*map
)
6968 struct isl_map
*dup
;
6972 dup
= isl_map_alloc_space(isl_space_copy(map
->dim
), map
->n
, map
->flags
);
6973 for (i
= 0; i
< map
->n
; ++i
)
6974 dup
= isl_map_add_basic_map(dup
, isl_basic_map_copy(map
->p
[i
]));
6978 __isl_give isl_map
*isl_map_add_basic_map(__isl_take isl_map
*map
,
6979 __isl_take isl_basic_map
*bmap
)
6983 if (isl_basic_map_plain_is_empty(bmap
)) {
6984 isl_basic_map_free(bmap
);
6987 if (isl_map_basic_map_check_equal_space(map
, bmap
) < 0)
6989 isl_assert(map
->ctx
, map
->n
< map
->size
, goto error
);
6990 map
->p
[map
->n
] = bmap
;
6992 map
= isl_map_unmark_normalized(map
);
6998 isl_basic_map_free(bmap
);
7002 __isl_null isl_map
*isl_map_free(__isl_take isl_map
*map
)
7013 isl_ctx_deref(map
->ctx
);
7014 for (i
= 0; i
< map
->n
; ++i
)
7015 isl_basic_map_free(map
->p
[i
]);
7016 isl_space_free(map
->dim
);
7022 static __isl_give isl_basic_map
*isl_basic_map_fix_pos_si(
7023 __isl_take isl_basic_map
*bmap
, unsigned pos
, int value
)
7028 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
7030 return isl_basic_map_free(bmap
);
7032 bmap
= isl_basic_map_cow(bmap
);
7033 bmap
= isl_basic_map_extend_constraints(bmap
, 1, 0);
7034 j
= isl_basic_map_alloc_equality(bmap
);
7037 isl_seq_clr(bmap
->eq
[j
] + 1, total
);
7038 isl_int_set_si(bmap
->eq
[j
][pos
], -1);
7039 isl_int_set_si(bmap
->eq
[j
][0], value
);
7040 bmap
= isl_basic_map_simplify(bmap
);
7041 return isl_basic_map_finalize(bmap
);
7043 isl_basic_map_free(bmap
);
7047 static __isl_give isl_basic_map
*isl_basic_map_fix_pos(
7048 __isl_take isl_basic_map
*bmap
, unsigned pos
, isl_int value
)
7053 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
7055 return isl_basic_map_free(bmap
);
7057 bmap
= isl_basic_map_cow(bmap
);
7058 bmap
= isl_basic_map_extend_constraints(bmap
, 1, 0);
7059 j
= isl_basic_map_alloc_equality(bmap
);
7062 isl_seq_clr(bmap
->eq
[j
] + 1, total
);
7063 isl_int_set_si(bmap
->eq
[j
][pos
], -1);
7064 isl_int_set(bmap
->eq
[j
][0], value
);
7065 bmap
= isl_basic_map_simplify(bmap
);
7066 return isl_basic_map_finalize(bmap
);
7068 isl_basic_map_free(bmap
);
7072 __isl_give isl_basic_map
*isl_basic_map_fix_si(__isl_take isl_basic_map
*bmap
,
7073 enum isl_dim_type type
, unsigned pos
, int value
)
7075 if (isl_basic_map_check_range(bmap
, type
, pos
, 1) < 0)
7076 return isl_basic_map_free(bmap
);
7077 return isl_basic_map_fix_pos_si(bmap
,
7078 isl_basic_map_offset(bmap
, type
) + pos
, value
);
7081 __isl_give isl_basic_map
*isl_basic_map_fix(__isl_take isl_basic_map
*bmap
,
7082 enum isl_dim_type type
, unsigned pos
, isl_int value
)
7084 if (isl_basic_map_check_range(bmap
, type
, pos
, 1) < 0)
7085 return isl_basic_map_free(bmap
);
7086 return isl_basic_map_fix_pos(bmap
,
7087 isl_basic_map_offset(bmap
, type
) + pos
, value
);
7090 /* Fix the value of the variable at position "pos" of type "type" of "bmap"
7091 * to be equal to "v".
7093 __isl_give isl_basic_map
*isl_basic_map_fix_val(__isl_take isl_basic_map
*bmap
,
7094 enum isl_dim_type type
, unsigned pos
, __isl_take isl_val
*v
)
7098 if (!isl_val_is_int(v
))
7099 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
7100 "expecting integer value", goto error
);
7101 if (isl_basic_map_check_range(bmap
, type
, pos
, 1) < 0)
7103 pos
+= isl_basic_map_offset(bmap
, type
);
7104 bmap
= isl_basic_map_fix_pos(bmap
, pos
, v
->n
);
7108 isl_basic_map_free(bmap
);
7113 /* Fix the value of the variable at position "pos" of type "type" of "bset"
7114 * to be equal to "v".
7116 __isl_give isl_basic_set
*isl_basic_set_fix_val(__isl_take isl_basic_set
*bset
,
7117 enum isl_dim_type type
, unsigned pos
, __isl_take isl_val
*v
)
7119 return isl_basic_map_fix_val(bset
, type
, pos
, v
);
7122 __isl_give isl_basic_set
*isl_basic_set_fix_si(__isl_take isl_basic_set
*bset
,
7123 enum isl_dim_type type
, unsigned pos
, int value
)
7125 return bset_from_bmap(isl_basic_map_fix_si(bset_to_bmap(bset
),
7129 __isl_give isl_basic_set
*isl_basic_set_fix(__isl_take isl_basic_set
*bset
,
7130 enum isl_dim_type type
, unsigned pos
, isl_int value
)
7132 return bset_from_bmap(isl_basic_map_fix(bset_to_bmap(bset
),
7136 /* Remove the basic map at position "i" from "map" if this basic map
7137 * is (obviously) empty.
7139 static __isl_give isl_map
*remove_if_empty(__isl_take isl_map
*map
, int i
)
7146 empty
= isl_basic_map_plain_is_empty(map
->p
[i
]);
7148 return isl_map_free(map
);
7152 isl_basic_map_free(map
->p
[i
]);
7155 map
->p
[i
] = map
->p
[map
->n
];
7156 map
= isl_map_unmark_normalized(map
);
7163 /* Perform "fn" on each basic map of "map", where we may not be holding
7164 * the only reference to "map".
7165 * In particular, "fn" should be a semantics preserving operation
7166 * that we want to apply to all copies of "map". We therefore need
7167 * to be careful not to modify "map" in a way that breaks "map"
7168 * in case anything goes wrong.
7170 __isl_give isl_map
*isl_map_inline_foreach_basic_map(__isl_take isl_map
*map
,
7171 __isl_give isl_basic_map
*(*fn
)(__isl_take isl_basic_map
*bmap
))
7173 struct isl_basic_map
*bmap
;
7179 for (i
= map
->n
- 1; i
>= 0; --i
) {
7180 bmap
= isl_basic_map_copy(map
->p
[i
]);
7184 isl_basic_map_free(map
->p
[i
]);
7186 map
= remove_if_empty(map
, i
);
7197 __isl_give isl_map
*isl_map_fix_si(__isl_take isl_map
*map
,
7198 enum isl_dim_type type
, unsigned pos
, int value
)
7202 map
= isl_map_cow(map
);
7203 if (isl_map_check_range(map
, type
, pos
, 1) < 0)
7204 return isl_map_free(map
);
7205 for (i
= map
->n
- 1; i
>= 0; --i
) {
7206 map
->p
[i
] = isl_basic_map_fix_si(map
->p
[i
], type
, pos
, value
);
7207 map
= remove_if_empty(map
, i
);
7211 map
= isl_map_unmark_normalized(map
);
7215 __isl_give isl_set
*isl_set_fix_si(__isl_take isl_set
*set
,
7216 enum isl_dim_type type
, unsigned pos
, int value
)
7218 return set_from_map(isl_map_fix_si(set_to_map(set
), type
, pos
, value
));
7221 __isl_give isl_map
*isl_map_fix(__isl_take isl_map
*map
,
7222 enum isl_dim_type type
, unsigned pos
, isl_int value
)
7226 map
= isl_map_cow(map
);
7227 if (isl_map_check_range(map
, type
, pos
, 1) < 0)
7228 return isl_map_free(map
);
7229 for (i
= 0; i
< map
->n
; ++i
) {
7230 map
->p
[i
] = isl_basic_map_fix(map
->p
[i
], type
, pos
, value
);
7234 map
= isl_map_unmark_normalized(map
);
7241 __isl_give isl_set
*isl_set_fix(__isl_take isl_set
*set
,
7242 enum isl_dim_type type
, unsigned pos
, isl_int value
)
7244 return set_from_map(isl_map_fix(set_to_map(set
), type
, pos
, value
));
7247 /* Fix the value of the variable at position "pos" of type "type" of "map"
7248 * to be equal to "v".
7250 __isl_give isl_map
*isl_map_fix_val(__isl_take isl_map
*map
,
7251 enum isl_dim_type type
, unsigned pos
, __isl_take isl_val
*v
)
7255 map
= isl_map_cow(map
);
7259 if (!isl_val_is_int(v
))
7260 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
7261 "expecting integer value", goto error
);
7262 if (isl_map_check_range(map
, type
, pos
, 1) < 0)
7264 for (i
= map
->n
- 1; i
>= 0; --i
) {
7265 map
->p
[i
] = isl_basic_map_fix_val(map
->p
[i
], type
, pos
,
7267 map
= remove_if_empty(map
, i
);
7271 map
= isl_map_unmark_normalized(map
);
7280 /* Fix the value of the variable at position "pos" of type "type" of "set"
7281 * to be equal to "v".
7283 __isl_give isl_set
*isl_set_fix_val(__isl_take isl_set
*set
,
7284 enum isl_dim_type type
, unsigned pos
, __isl_take isl_val
*v
)
7286 return isl_map_fix_val(set
, type
, pos
, v
);
7289 __isl_give isl_map
*isl_map_fix_input_si(__isl_take isl_map
*map
,
7290 unsigned input
, int value
)
7292 return isl_map_fix_si(map
, isl_dim_in
, input
, value
);
7295 __isl_give isl_set
*isl_set_fix_dim_si(__isl_take isl_set
*set
, unsigned dim
,
7298 return set_from_map(isl_map_fix_si(set_to_map(set
),
7299 isl_dim_set
, dim
, value
));
7302 static __isl_give isl_basic_map
*basic_map_bound_si(
7303 __isl_take isl_basic_map
*bmap
,
7304 enum isl_dim_type type
, unsigned pos
, int value
, int upper
)
7309 if (isl_basic_map_check_range(bmap
, type
, pos
, 1) < 0)
7310 return isl_basic_map_free(bmap
);
7311 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
7313 return isl_basic_map_free(bmap
);
7314 pos
+= isl_basic_map_offset(bmap
, type
);
7315 bmap
= isl_basic_map_cow(bmap
);
7316 bmap
= isl_basic_map_extend_constraints(bmap
, 0, 1);
7317 j
= isl_basic_map_alloc_inequality(bmap
);
7320 isl_seq_clr(bmap
->ineq
[j
], 1 + total
);
7322 isl_int_set_si(bmap
->ineq
[j
][pos
], -1);
7323 isl_int_set_si(bmap
->ineq
[j
][0], value
);
7325 isl_int_set_si(bmap
->ineq
[j
][pos
], 1);
7326 isl_int_set_si(bmap
->ineq
[j
][0], -value
);
7328 bmap
= isl_basic_map_simplify(bmap
);
7329 return isl_basic_map_finalize(bmap
);
7331 isl_basic_map_free(bmap
);
7335 __isl_give isl_basic_map
*isl_basic_map_lower_bound_si(
7336 __isl_take isl_basic_map
*bmap
,
7337 enum isl_dim_type type
, unsigned pos
, int value
)
7339 return basic_map_bound_si(bmap
, type
, pos
, value
, 0);
7342 /* Constrain the values of the given dimension to be no greater than "value".
7344 __isl_give isl_basic_map
*isl_basic_map_upper_bound_si(
7345 __isl_take isl_basic_map
*bmap
,
7346 enum isl_dim_type type
, unsigned pos
, int value
)
7348 return basic_map_bound_si(bmap
, type
, pos
, value
, 1);
7351 static __isl_give isl_map
*map_bound_si(__isl_take isl_map
*map
,
7352 enum isl_dim_type type
, unsigned pos
, int value
, int upper
)
7356 map
= isl_map_cow(map
);
7357 if (isl_map_check_range(map
, type
, pos
, 1) < 0)
7358 return isl_map_free(map
);
7359 for (i
= 0; i
< map
->n
; ++i
) {
7360 map
->p
[i
] = basic_map_bound_si(map
->p
[i
],
7361 type
, pos
, value
, upper
);
7365 map
= isl_map_unmark_normalized(map
);
7372 __isl_give isl_map
*isl_map_lower_bound_si(__isl_take isl_map
*map
,
7373 enum isl_dim_type type
, unsigned pos
, int value
)
7375 return map_bound_si(map
, type
, pos
, value
, 0);
7378 __isl_give isl_map
*isl_map_upper_bound_si(__isl_take isl_map
*map
,
7379 enum isl_dim_type type
, unsigned pos
, int value
)
7381 return map_bound_si(map
, type
, pos
, value
, 1);
7384 __isl_give isl_set
*isl_set_lower_bound_si(__isl_take isl_set
*set
,
7385 enum isl_dim_type type
, unsigned pos
, int value
)
7387 return set_from_map(isl_map_lower_bound_si(set_to_map(set
),
7391 __isl_give isl_set
*isl_set_upper_bound_si(__isl_take isl_set
*set
,
7392 enum isl_dim_type type
, unsigned pos
, int value
)
7394 return isl_map_upper_bound_si(set
, type
, pos
, value
);
7397 /* Bound the given variable of "bmap" from below (or above is "upper"
7398 * is set) to "value".
7400 static __isl_give isl_basic_map
*basic_map_bound(
7401 __isl_take isl_basic_map
*bmap
,
7402 enum isl_dim_type type
, unsigned pos
, isl_int value
, int upper
)
7407 if (isl_basic_map_check_range(bmap
, type
, pos
, 1) < 0)
7408 return isl_basic_map_free(bmap
);
7409 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
7411 return isl_basic_map_free(bmap
);
7412 pos
+= isl_basic_map_offset(bmap
, type
);
7413 bmap
= isl_basic_map_cow(bmap
);
7414 bmap
= isl_basic_map_extend_constraints(bmap
, 0, 1);
7415 j
= isl_basic_map_alloc_inequality(bmap
);
7418 isl_seq_clr(bmap
->ineq
[j
], 1 + total
);
7420 isl_int_set_si(bmap
->ineq
[j
][pos
], -1);
7421 isl_int_set(bmap
->ineq
[j
][0], value
);
7423 isl_int_set_si(bmap
->ineq
[j
][pos
], 1);
7424 isl_int_neg(bmap
->ineq
[j
][0], value
);
7426 bmap
= isl_basic_map_simplify(bmap
);
7427 return isl_basic_map_finalize(bmap
);
7429 isl_basic_map_free(bmap
);
7433 /* Bound the given variable of "map" from below (or above is "upper"
7434 * is set) to "value".
7436 static __isl_give isl_map
*map_bound(__isl_take isl_map
*map
,
7437 enum isl_dim_type type
, unsigned pos
, isl_int value
, int upper
)
7441 map
= isl_map_cow(map
);
7442 if (isl_map_check_range(map
, type
, pos
, 1) < 0)
7443 return isl_map_free(map
);
7444 for (i
= map
->n
- 1; i
>= 0; --i
) {
7445 map
->p
[i
] = basic_map_bound(map
->p
[i
], type
, pos
, value
, upper
);
7446 map
= remove_if_empty(map
, i
);
7450 map
= isl_map_unmark_normalized(map
);
7454 __isl_give isl_map
*isl_map_lower_bound(__isl_take isl_map
*map
,
7455 enum isl_dim_type type
, unsigned pos
, isl_int value
)
7457 return map_bound(map
, type
, pos
, value
, 0);
7460 __isl_give isl_map
*isl_map_upper_bound(__isl_take isl_map
*map
,
7461 enum isl_dim_type type
, unsigned pos
, isl_int value
)
7463 return map_bound(map
, type
, pos
, value
, 1);
7466 __isl_give isl_set
*isl_set_lower_bound(__isl_take isl_set
*set
,
7467 enum isl_dim_type type
, unsigned pos
, isl_int value
)
7469 return isl_map_lower_bound(set
, type
, pos
, value
);
7472 __isl_give isl_set
*isl_set_upper_bound(__isl_take isl_set
*set
,
7473 enum isl_dim_type type
, unsigned pos
, isl_int value
)
7475 return isl_map_upper_bound(set
, type
, pos
, value
);
7478 /* Force the values of the variable at position "pos" of type "type" of "map"
7479 * to be no smaller than "value".
7481 __isl_give isl_map
*isl_map_lower_bound_val(__isl_take isl_map
*map
,
7482 enum isl_dim_type type
, unsigned pos
, __isl_take isl_val
*value
)
7486 if (!isl_val_is_int(value
))
7487 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
7488 "expecting integer value", goto error
);
7489 map
= isl_map_lower_bound(map
, type
, pos
, value
->n
);
7490 isl_val_free(value
);
7493 isl_val_free(value
);
7498 /* Force the values of the variable at position "pos" of type "type" of "set"
7499 * to be no smaller than "value".
7501 __isl_give isl_set
*isl_set_lower_bound_val(__isl_take isl_set
*set
,
7502 enum isl_dim_type type
, unsigned pos
, __isl_take isl_val
*value
)
7506 map
= set_to_map(set
);
7507 return set_from_map(isl_map_lower_bound_val(map
, type
, pos
, value
));
7510 /* Force the values of the variable at position "pos" of type "type" of "map"
7511 * to be no greater than "value".
7513 __isl_give isl_map
*isl_map_upper_bound_val(__isl_take isl_map
*map
,
7514 enum isl_dim_type type
, unsigned pos
, __isl_take isl_val
*value
)
7518 if (!isl_val_is_int(value
))
7519 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
7520 "expecting integer value", goto error
);
7521 map
= isl_map_upper_bound(map
, type
, pos
, value
->n
);
7522 isl_val_free(value
);
7525 isl_val_free(value
);
7530 /* Force the values of the variable at position "pos" of type "type" of "set"
7531 * to be no greater than "value".
7533 __isl_give isl_set
*isl_set_upper_bound_val(__isl_take isl_set
*set
,
7534 enum isl_dim_type type
, unsigned pos
, __isl_take isl_val
*value
)
7538 map
= set_to_map(set
);
7539 return set_from_map(isl_map_upper_bound_val(map
, type
, pos
, value
));
7542 /* If "mv" has an explicit domain, then intersect the domain of "map"
7543 * with this explicit domain.
7545 * An isl_multi_val object never has an explicit domain,
7546 * so simply return "map".
7548 static __isl_give isl_map
*isl_map_intersect_multi_val_explicit_domain(
7549 __isl_take isl_map
*map
, __isl_keep isl_multi_val
*mv
)
7556 #include "isl_map_bound_templ.c"
7558 /* Apply "map_bound" to "set" with the corresponding value in "bound"
7559 * for each set dimension, by treating the set as a map.
7561 static __isl_give isl_set
*set_bound_multi_val(__isl_take isl_set
*set
,
7562 __isl_take isl_multi_val
*bound
,
7563 __isl_give isl_map
*map_bound(__isl_take isl_map
*map
,
7564 unsigned pos
, __isl_take isl_val
*value
))
7568 map
= set_to_map(set
);
7569 return set_from_map(map_bound_multi_val(map
, bound
, map_bound
));
7574 #include "isl_map_bound_templ.c"
7576 /* Apply "map_bound" to "set" with the corresponding value in "bound"
7577 * for each set dimension, by converting the set and the bound
7578 * to objects living in a map space.
7580 static __isl_give isl_set
*set_bound_multi_pw_aff(__isl_take isl_set
*set
,
7581 __isl_take isl_multi_pw_aff
*bound
,
7582 __isl_give isl_map
*set_bound(__isl_take isl_map
*map
,
7583 unsigned pos
, __isl_take TYPE
*value
))
7587 map
= isl_map_from_range(set
);
7588 bound
= isl_multi_pw_aff_from_range(bound
);
7589 map
= map_bound_multi_pw_aff(map
, bound
, set_bound
);
7590 return isl_map_range(map
);
7593 /* Wrapper around isl_map_lower_bound_val for use in map_bound_multi_val,
7594 * setting a bound on the given output dimension.
7596 static __isl_give isl_map
*map_lower_bound_val(__isl_take isl_map
*map
,
7597 unsigned pos
, __isl_take isl_val
*v
)
7599 return isl_map_lower_bound_val(map
, isl_dim_out
, pos
, v
);
7602 /* Force the values of the set dimensions of "set"
7603 * to be no smaller than the corresponding values in "lower".
7605 __isl_give isl_set
*isl_set_lower_bound_multi_val(__isl_take isl_set
*set
,
7606 __isl_take isl_multi_val
*lower
)
7608 return set_bound_multi_val(set
, lower
, &map_lower_bound_val
);
7611 /* Wrapper around isl_map_upper_bound_val for use in map_bound_multi_val,
7612 * setting a bound on the given output dimension.
7614 static __isl_give isl_map
*map_upper_bound_val(__isl_take isl_map
*map
,
7615 unsigned pos
, __isl_take isl_val
*v
)
7617 return isl_map_upper_bound_val(map
, isl_dim_out
, pos
, v
);
7620 /* Force the values of the set dimensions of "set"
7621 * to be no greater than the corresponding values in "upper".
7623 __isl_give isl_set
*isl_set_upper_bound_multi_val(__isl_take isl_set
*set
,
7624 __isl_take isl_multi_val
*upper
)
7626 return set_bound_multi_val(set
, upper
, &map_upper_bound_val
);
7629 /* Force the symbolic constant expression "bound"
7630 * to satisfy the relation "order" with respect to
7631 * the output variable at position "pos" of "map".
7633 * Create an affine expression representing the output variable
7634 * in terms of the range and
7635 * compare it using "order" to "bound" (defined on the domain).
7636 * The result is a relation between elements in domain and range that
7637 * can be intersected with "map".
7639 static __isl_give isl_map
*map_bound_pw_aff(__isl_take isl_map
*map
,
7640 unsigned pos
, __isl_take isl_pw_aff
*bound
,
7641 __isl_give isl_map
*(*order
)(__isl_take isl_pw_aff
*pa1
,
7642 __isl_take isl_pw_aff
*pa2
))
7645 isl_local_space
*ls
;
7648 space
= isl_space_range(isl_map_get_space(map
));
7649 ls
= isl_local_space_from_space(space
);
7650 var
= isl_pw_aff_var_on_domain(ls
, isl_dim_set
, pos
);
7651 map
= isl_map_intersect(map
, order(bound
, var
));
7655 /* Force the values of the output variable at position "pos" of "map"
7656 * to be no smaller than the symbolic constant expression "lower".
7658 static __isl_give isl_map
*map_lower_bound_pw_aff(__isl_take isl_map
*map
,
7659 unsigned pos
, __isl_take isl_pw_aff
*lower
)
7661 return map_bound_pw_aff(map
, pos
, lower
, &isl_pw_aff_le_map
);
7664 /* Force the values of the output variable at position "pos" of "map"
7665 * to be no greater than the symbolic constant expression "upper".
7667 static __isl_give isl_map
*map_upper_bound_pw_aff(__isl_take isl_map
*map
,
7668 unsigned pos
, __isl_take isl_pw_aff
*upper
)
7670 return map_bound_pw_aff(map
, pos
, upper
, &isl_pw_aff_ge_map
);
7673 /* Force the values of the set dimensions of "set"
7674 * to be no smaller than the corresponding constant symbolic expressions
7677 __isl_give isl_set
*isl_set_lower_bound_multi_pw_aff(__isl_take isl_set
*set
,
7678 __isl_take isl_multi_pw_aff
*lower
)
7680 return set_bound_multi_pw_aff(set
, lower
, &map_lower_bound_pw_aff
);
7683 /* Force the values of the set dimensions of "set"
7684 * to be no greater than the corresponding constant symbolic expressions
7687 __isl_give isl_set
*isl_set_upper_bound_multi_pw_aff(__isl_take isl_set
*set
,
7688 __isl_take isl_multi_pw_aff
*upper
)
7690 return set_bound_multi_pw_aff(set
, upper
, &map_upper_bound_pw_aff
);
7693 /* Force the values of the output dimensions of "map"
7694 * to be no smaller than the corresponding constant symbolic expressions
7697 __isl_give isl_map
*isl_map_lower_bound_multi_pw_aff(__isl_take isl_map
*map
,
7698 __isl_take isl_multi_pw_aff
*lower
)
7700 return map_bound_multi_pw_aff(map
, lower
, &map_lower_bound_pw_aff
);
7703 /* Force the values of the output dimensions of "map"
7704 * to be no greater than the corresponding constant symbolic expressions
7707 __isl_give isl_map
*isl_map_upper_bound_multi_pw_aff(__isl_take isl_map
*map
,
7708 __isl_take isl_multi_pw_aff
*upper
)
7710 return map_bound_multi_pw_aff(map
, upper
, &map_upper_bound_pw_aff
);
7713 /* Bound the given variable of "bset" from below (or above is "upper"
7714 * is set) to "value".
7716 static __isl_give isl_basic_set
*isl_basic_set_bound(
7717 __isl_take isl_basic_set
*bset
, enum isl_dim_type type
, unsigned pos
,
7718 isl_int value
, int upper
)
7720 return bset_from_bmap(basic_map_bound(bset_to_bmap(bset
),
7721 type
, pos
, value
, upper
));
7724 /* Bound the given variable of "bset" from below (or above is "upper"
7725 * is set) to "value".
7727 static __isl_give isl_basic_set
*isl_basic_set_bound_val(
7728 __isl_take isl_basic_set
*bset
, enum isl_dim_type type
, unsigned pos
,
7729 __isl_take isl_val
*value
, int upper
)
7733 if (!isl_val_is_int(value
))
7734 isl_die(isl_basic_set_get_ctx(bset
), isl_error_invalid
,
7735 "expecting integer value", goto error
);
7736 bset
= isl_basic_set_bound(bset
, type
, pos
, value
->n
, upper
);
7737 isl_val_free(value
);
7740 isl_val_free(value
);
7741 isl_basic_set_free(bset
);
7745 /* Bound the given variable of "bset" from below to "value".
7747 __isl_give isl_basic_set
*isl_basic_set_lower_bound_val(
7748 __isl_take isl_basic_set
*bset
, enum isl_dim_type type
, unsigned pos
,
7749 __isl_take isl_val
*value
)
7751 return isl_basic_set_bound_val(bset
, type
, pos
, value
, 0);
7754 /* Bound the given variable of "bset" from above to "value".
7756 __isl_give isl_basic_set
*isl_basic_set_upper_bound_val(
7757 __isl_take isl_basic_set
*bset
, enum isl_dim_type type
, unsigned pos
,
7758 __isl_take isl_val
*value
)
7760 return isl_basic_set_bound_val(bset
, type
, pos
, value
, 1);
7763 __isl_give isl_map
*isl_map_reverse(__isl_take isl_map
*map
)
7765 return isl_map_transform(map
, &isl_space_reverse
,
7766 &isl_basic_map_reverse
);
7769 /* Given a map (A -> B) -> C, return the corresponding map (B -> A) -> C.
7771 __isl_give isl_map
*isl_map_domain_reverse(__isl_take isl_map
*map
)
7773 return isl_map_transform(map
, &isl_space_domain_reverse
,
7774 &isl_basic_map_domain_reverse
);
7777 /* Given a map A -> (B -> C), return the corresponding map A -> (C -> B).
7779 __isl_give isl_map
*isl_map_range_reverse(__isl_take isl_map
*map
)
7781 return isl_map_transform(map
, &isl_space_range_reverse
,
7782 &isl_basic_map_range_reverse
);
7785 /* Given a set (A -> B), return the corresponding set (B -> A).
7787 __isl_give isl_set
*isl_set_wrapped_reverse(__isl_take isl_set
*set
)
7789 isl_map
*map
= set_to_map(set
);
7791 map
= isl_map_transform(map
, &isl_space_wrapped_reverse
,
7792 &isl_basic_map_set_reverse
);
7793 return set_from_map(map
);
7797 #define TYPE isl_pw_multi_aff
7799 #define SUFFIX _pw_multi_aff
7801 #define EMPTY isl_pw_multi_aff_empty
7803 #define ADD isl_pw_multi_aff_union_add
7804 #include "isl_map_lexopt_templ.c"
7806 /* Given a map "map", compute the lexicographically minimal
7807 * (or maximal) image element for each domain element in dom,
7808 * in the form of an isl_pw_multi_aff.
7809 * If "empty" is not NULL, then set *empty to those elements in dom that
7810 * do not have an image element.
7811 * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
7812 * should be computed over the domain of "map". "empty" is also NULL
7815 * We first compute the lexicographically minimal or maximal element
7816 * in the first basic map. This results in a partial solution "res"
7817 * and a subset "todo" of dom that still need to be handled.
7818 * We then consider each of the remaining maps in "map" and successively
7819 * update both "res" and "todo".
7820 * If "empty" is NULL, then the todo sets are not needed and therefore
7821 * also not computed.
7823 static __isl_give isl_pw_multi_aff
*isl_map_partial_lexopt_aligned_pw_multi_aff(
7824 __isl_take isl_map
*map
, __isl_take isl_set
*dom
,
7825 __isl_give isl_set
**empty
, unsigned flags
)
7829 isl_pw_multi_aff
*res
;
7832 full
= ISL_FL_ISSET(flags
, ISL_OPT_FULL
);
7833 if (!map
|| (!full
&& !dom
))
7836 if (isl_map_plain_is_empty(map
)) {
7841 return isl_pw_multi_aff_from_map(map
);
7844 res
= basic_map_partial_lexopt_pw_multi_aff(
7845 isl_basic_map_copy(map
->p
[0]),
7846 isl_set_copy(dom
), empty
, flags
);
7850 for (i
= 1; i
< map
->n
; ++i
) {
7851 isl_pw_multi_aff
*res_i
;
7853 res_i
= basic_map_partial_lexopt_pw_multi_aff(
7854 isl_basic_map_copy(map
->p
[i
]),
7855 isl_set_copy(dom
), empty
, flags
);
7857 if (ISL_FL_ISSET(flags
, ISL_OPT_MAX
))
7858 res
= isl_pw_multi_aff_union_lexmax(res
, res_i
);
7860 res
= isl_pw_multi_aff_union_lexmin(res
, res_i
);
7863 todo
= isl_set_intersect(todo
, *empty
);
7882 #define TYPE isl_map
7886 #define EMPTY isl_map_empty
7888 #define ADD isl_map_union_disjoint
7889 #include "isl_map_lexopt_templ.c"
7891 /* Given a map "map", compute the lexicographically minimal
7892 * (or maximal) image element for each domain element in "dom",
7893 * in the form of an isl_map.
7894 * If "empty" is not NULL, then set *empty to those elements in "dom" that
7895 * do not have an image element.
7896 * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
7897 * should be computed over the domain of "map". "empty" is also NULL
7900 * If the input consists of more than one disjunct, then first
7901 * compute the desired result in the form of an isl_pw_multi_aff and
7902 * then convert that into an isl_map.
7904 * This function used to have an explicit implementation in terms
7905 * of isl_maps, but it would continually intersect the domains of
7906 * partial results with the complement of the domain of the next
7907 * partial solution, potentially leading to an explosion in the number
7908 * of disjuncts if there are several disjuncts in the input.
7909 * An even earlier implementation of this function would look for
7910 * better results in the domain of the partial result and for extra
7911 * results in the complement of this domain, which would lead to
7912 * even more splintering.
7914 static __isl_give isl_map
*isl_map_partial_lexopt_aligned(
7915 __isl_take isl_map
*map
, __isl_take isl_set
*dom
,
7916 __isl_give isl_set
**empty
, unsigned flags
)
7919 struct isl_map
*res
;
7920 isl_pw_multi_aff
*pma
;
7922 full
= ISL_FL_ISSET(flags
, ISL_OPT_FULL
);
7923 if (!map
|| (!full
&& !dom
))
7926 if (isl_map_plain_is_empty(map
)) {
7935 res
= basic_map_partial_lexopt(isl_basic_map_copy(map
->p
[0]),
7941 pma
= isl_map_partial_lexopt_aligned_pw_multi_aff(map
, dom
, empty
,
7943 return isl_map_from_pw_multi_aff_internal(pma
);
7952 __isl_give isl_map
*isl_map_partial_lexmax(
7953 __isl_take isl_map
*map
, __isl_take isl_set
*dom
,
7954 __isl_give isl_set
**empty
)
7956 return isl_map_partial_lexopt(map
, dom
, empty
, ISL_OPT_MAX
);
7959 __isl_give isl_map
*isl_map_partial_lexmin(
7960 __isl_take isl_map
*map
, __isl_take isl_set
*dom
,
7961 __isl_give isl_set
**empty
)
7963 return isl_map_partial_lexopt(map
, dom
, empty
, 0);
7966 __isl_give isl_set
*isl_set_partial_lexmin(
7967 __isl_take isl_set
*set
, __isl_take isl_set
*dom
,
7968 __isl_give isl_set
**empty
)
7970 return set_from_map(isl_map_partial_lexmin(set_to_map(set
),
7974 __isl_give isl_set
*isl_set_partial_lexmax(
7975 __isl_take isl_set
*set
, __isl_take isl_set
*dom
,
7976 __isl_give isl_set
**empty
)
7978 return set_from_map(isl_map_partial_lexmax(set_to_map(set
),
7982 /* Compute the lexicographic minimum (or maximum if "flags" includes
7983 * ISL_OPT_MAX) of "bset" over its parametric domain.
7985 __isl_give isl_set
*isl_basic_set_lexopt(__isl_take isl_basic_set
*bset
,
7988 return isl_basic_map_lexopt(bset
, flags
);
7991 __isl_give isl_map
*isl_basic_map_lexmax(__isl_take isl_basic_map
*bmap
)
7993 return isl_basic_map_lexopt(bmap
, ISL_OPT_MAX
);
7996 __isl_give isl_set
*isl_basic_set_lexmin(__isl_take isl_basic_set
*bset
)
7998 return set_from_map(isl_basic_map_lexmin(bset_to_bmap(bset
)));
8001 __isl_give isl_set
*isl_basic_set_lexmax(__isl_take isl_basic_set
*bset
)
8003 return set_from_map(isl_basic_map_lexmax(bset_to_bmap(bset
)));
8006 /* Compute the lexicographic minimum of "bset" over its parametric domain
8007 * for the purpose of quantifier elimination.
8008 * That is, find an explicit representation for all the existentially
8009 * quantified variables in "bset" by computing their lexicographic
8012 static __isl_give isl_set
*isl_basic_set_lexmin_compute_divs(
8013 __isl_take isl_basic_set
*bset
)
8015 return isl_basic_set_lexopt(bset
, ISL_OPT_QE
);
8018 /* Given a basic map with one output dimension, compute the minimum or
8019 * maximum of that dimension as an isl_pw_aff.
8021 * Compute the optimum as a lexicographic optimum over the single
8022 * output dimension and extract the single isl_pw_aff from the result.
8024 static __isl_give isl_pw_aff
*basic_map_dim_opt(__isl_keep isl_basic_map
*bmap
,
8027 isl_pw_multi_aff
*pma
;
8030 bmap
= isl_basic_map_copy(bmap
);
8031 pma
= isl_basic_map_lexopt_pw_multi_aff(bmap
, max
? ISL_OPT_MAX
: 0);
8032 pwaff
= isl_pw_multi_aff_get_pw_aff(pma
, 0);
8033 isl_pw_multi_aff_free(pma
);
8038 /* Compute the minimum or maximum of the given output dimension
8039 * as a function of the parameters and the input dimensions,
8040 * but independently of the other output dimensions.
8042 * We first project out the other output dimension and then compute
8043 * the "lexicographic" maximum in each basic map, combining the results
8044 * using isl_pw_aff_union_max.
8046 static __isl_give isl_pw_aff
*map_dim_opt(__isl_take isl_map
*map
, int pos
,
8053 n_out
= isl_map_dim(map
, isl_dim_out
);
8055 map
= isl_map_free(map
);
8056 map
= isl_map_project_out(map
, isl_dim_out
, pos
+ 1, n_out
- (pos
+ 1));
8057 map
= isl_map_project_out(map
, isl_dim_out
, 0, pos
);
8062 isl_space
*space
= isl_map_get_space(map
);
8064 return isl_pw_aff_empty(space
);
8067 pwaff
= basic_map_dim_opt(map
->p
[0], max
);
8068 for (i
= 1; i
< map
->n
; ++i
) {
8069 isl_pw_aff
*pwaff_i
;
8071 pwaff_i
= basic_map_dim_opt(map
->p
[i
], max
);
8072 pwaff
= isl_pw_aff_union_opt(pwaff
, pwaff_i
, max
);
8080 /* Compute the minimum of the given output dimension as a function of the
8081 * parameters and input dimensions, but independently of
8082 * the other output dimensions.
8084 __isl_give isl_pw_aff
*isl_map_dim_min(__isl_take isl_map
*map
, int pos
)
8086 return map_dim_opt(map
, pos
, 0);
8089 /* Compute the maximum of the given output dimension as a function of the
8090 * parameters and input dimensions, but independently of
8091 * the other output dimensions.
8093 __isl_give isl_pw_aff
*isl_map_dim_max(__isl_take isl_map
*map
, int pos
)
8095 return map_dim_opt(map
, pos
, 1);
8098 /* Compute the minimum or maximum of the given set dimension
8099 * as a function of the parameters,
8100 * but independently of the other set dimensions.
8102 static __isl_give isl_pw_aff
*set_dim_opt(__isl_take isl_set
*set
, int pos
,
8105 return map_dim_opt(set
, pos
, max
);
8108 /* Compute the maximum of the given set dimension as a function of the
8109 * parameters, but independently of the other set dimensions.
8111 __isl_give isl_pw_aff
*isl_set_dim_max(__isl_take isl_set
*set
, int pos
)
8113 return set_dim_opt(set
, pos
, 1);
8116 /* Compute the minimum of the given set dimension as a function of the
8117 * parameters, but independently of the other set dimensions.
8119 __isl_give isl_pw_aff
*isl_set_dim_min(__isl_take isl_set
*set
, int pos
)
8121 return set_dim_opt(set
, pos
, 0);
8124 /* Apply a preimage specified by "mat" on the parameters of "bset".
8125 * bset is assumed to have only parameters and divs.
8127 static __isl_give isl_basic_set
*basic_set_parameter_preimage(
8128 __isl_take isl_basic_set
*bset
, __isl_take isl_mat
*mat
)
8132 nparam
= isl_basic_set_dim(bset
, isl_dim_param
);
8133 if (nparam
< 0 || !mat
)
8136 bset
->dim
= isl_space_cow(bset
->dim
);
8140 isl_assert(bset
->ctx
, mat
->n_row
== 1 + nparam
, goto error
);
8142 bset
->dim
->nparam
= 0;
8143 bset
->dim
->n_out
= nparam
;
8144 bset
= isl_basic_set_preimage(bset
, mat
);
8146 bset
->dim
->nparam
= bset
->dim
->n_out
;
8147 bset
->dim
->n_out
= 0;
8152 isl_basic_set_free(bset
);
8156 /* Apply a preimage specified by "mat" on the parameters of "set".
8157 * set is assumed to have only parameters and divs.
8159 static __isl_give isl_set
*set_parameter_preimage(__isl_take isl_set
*set
,
8160 __isl_take isl_mat
*mat
)
8165 nparam
= isl_set_dim(set
, isl_dim_param
);
8166 if (nparam
< 0 || !mat
)
8169 if (mat
->n_row
!= 1 + nparam
)
8170 isl_die(isl_set_get_ctx(set
), isl_error_internal
,
8171 "unexpected number of rows", goto error
);
8173 space
= isl_set_get_space(set
);
8174 space
= isl_space_move_dims(space
, isl_dim_set
, 0,
8175 isl_dim_param
, 0, nparam
);
8176 set
= isl_set_reset_space(set
, space
);
8177 set
= isl_set_preimage(set
, mat
);
8178 nparam
= isl_set_dim(set
, isl_dim_out
);
8180 set
= isl_set_free(set
);
8181 space
= isl_set_get_space(set
);
8182 space
= isl_space_move_dims(space
, isl_dim_param
, 0,
8183 isl_dim_out
, 0, nparam
);
8184 set
= isl_set_reset_space(set
, space
);
8192 /* Intersect the basic set "bset" with the affine space specified by the
8193 * equalities in "eq".
8195 static __isl_give isl_basic_set
*basic_set_append_equalities(
8196 __isl_take isl_basic_set
*bset
, __isl_take isl_mat
*eq
)
8204 bset
= isl_basic_set_extend(bset
, 0, eq
->n_row
, 0);
8208 len
= isl_basic_set_offset(bset
, isl_dim_div
) + bset
->extra
;
8209 for (i
= 0; i
< eq
->n_row
; ++i
) {
8210 k
= isl_basic_set_alloc_equality(bset
);
8213 isl_seq_cpy(bset
->eq
[k
], eq
->row
[i
], eq
->n_col
);
8214 isl_seq_clr(bset
->eq
[k
] + eq
->n_col
, len
- eq
->n_col
);
8218 bset
= isl_basic_set_gauss(bset
, NULL
);
8219 bset
= isl_basic_set_finalize(bset
);
8224 isl_basic_set_free(bset
);
8228 /* Intersect the set "set" with the affine space specified by the
8229 * equalities in "eq".
8231 static __isl_give isl_set
*set_append_equalities(__isl_take isl_set
*set
,
8232 __isl_take isl_mat
*eq
)
8239 for (i
= 0; i
< set
->n
; ++i
) {
8240 set
->p
[i
] = basic_set_append_equalities(set
->p
[i
],
8253 /* Given a basic set "bset" that only involves parameters and existentially
8254 * quantified variables, return the index of the first equality
8255 * that only involves parameters. If there is no such equality then
8256 * return bset->n_eq.
8258 * This function assumes that isl_basic_set_gauss has been called on "bset".
8260 static int first_parameter_equality(__isl_keep isl_basic_set
*bset
)
8263 isl_size nparam
, n_div
;
8265 nparam
= isl_basic_set_dim(bset
, isl_dim_param
);
8266 n_div
= isl_basic_set_dim(bset
, isl_dim_div
);
8267 if (nparam
< 0 || n_div
< 0)
8270 for (i
= 0, j
= n_div
- 1; i
< bset
->n_eq
&& j
>= 0; --j
) {
8271 if (!isl_int_is_zero(bset
->eq
[i
][1 + nparam
+ j
]))
8278 /* Compute an explicit representation for the existentially quantified
8279 * variables in "bset" by computing the "minimal value" of the set
8280 * variables. Since there are no set variables, the computation of
8281 * the minimal value essentially computes an explicit representation
8282 * of the non-empty part(s) of "bset".
8284 * The input only involves parameters and existentially quantified variables.
8285 * All equalities among parameters have been removed.
8287 * Since the existentially quantified variables in the result are in general
8288 * going to be different from those in the input, we first replace
8289 * them by the minimal number of variables based on their equalities.
8290 * This should simplify the parametric integer programming.
8292 static __isl_give isl_set
*base_compute_divs(__isl_take isl_basic_set
*bset
)
8294 isl_morph
*morph1
, *morph2
;
8300 if (bset
->n_eq
== 0)
8301 return isl_basic_set_lexmin_compute_divs(bset
);
8303 morph1
= isl_basic_set_parameter_compression(bset
);
8304 bset
= isl_morph_basic_set(isl_morph_copy(morph1
), bset
);
8305 bset
= isl_basic_set_lift(bset
);
8306 morph2
= isl_basic_set_variable_compression(bset
, isl_dim_set
);
8307 bset
= isl_morph_basic_set(morph2
, bset
);
8308 n
= isl_basic_set_dim(bset
, isl_dim_set
);
8310 bset
= isl_basic_set_free(bset
);
8311 bset
= isl_basic_set_project_out(bset
, isl_dim_set
, 0, n
);
8313 set
= isl_basic_set_lexmin_compute_divs(bset
);
8315 set
= isl_morph_set(isl_morph_inverse(morph1
), set
);
8320 /* Project the given basic set onto its parameter domain, possibly introducing
8321 * new, explicit, existential variables in the constraints.
8322 * The input has parameters and (possibly implicit) existential variables.
8323 * The output has the same parameters, but only
8324 * explicit existentially quantified variables.
8326 * The actual projection is performed by pip, but pip doesn't seem
8327 * to like equalities very much, so we first remove the equalities
8328 * among the parameters by performing a variable compression on
8329 * the parameters. Afterward, an inverse transformation is performed
8330 * and the equalities among the parameters are inserted back in.
8332 * The variable compression on the parameters may uncover additional
8333 * equalities that were only implicit before. We therefore check
8334 * if there are any new parameter equalities in the result and
8335 * if so recurse. The removal of parameter equalities is required
8336 * for the parameter compression performed by base_compute_divs.
8338 static __isl_give isl_set
*parameter_compute_divs(
8339 __isl_take isl_basic_set
*bset
)
8343 struct isl_mat
*T
, *T2
;
8344 struct isl_set
*set
;
8347 bset
= isl_basic_set_cow(bset
);
8351 if (bset
->n_eq
== 0)
8352 return base_compute_divs(bset
);
8354 bset
= isl_basic_set_gauss(bset
, NULL
);
8357 if (isl_basic_set_plain_is_empty(bset
))
8358 return isl_set_from_basic_set(bset
);
8360 i
= first_parameter_equality(bset
);
8361 if (i
== bset
->n_eq
)
8362 return base_compute_divs(bset
);
8364 nparam
= isl_basic_set_dim(bset
, isl_dim_param
);
8366 return isl_set_from_basic_set(isl_basic_set_free(bset
));
8367 eq
= isl_mat_sub_alloc6(bset
->ctx
, bset
->eq
, i
, bset
->n_eq
- i
,
8369 eq
= isl_mat_cow(eq
);
8370 T
= isl_mat_variable_compression(isl_mat_copy(eq
), &T2
);
8371 if (T
&& T
->n_col
== 0) {
8375 bset
= isl_basic_set_set_to_empty(bset
);
8376 return isl_set_from_basic_set(bset
);
8378 bset
= basic_set_parameter_preimage(bset
, T
);
8380 i
= first_parameter_equality(bset
);
8383 else if (i
== bset
->n_eq
)
8384 set
= base_compute_divs(bset
);
8386 set
= parameter_compute_divs(bset
);
8387 set
= set_parameter_preimage(set
, T2
);
8388 set
= set_append_equalities(set
, eq
);
8392 /* Insert the divs from "ls" before those of "bmap".
8394 * The number of columns is not changed, which means that the last
8395 * dimensions of "bmap" are being reintepreted as the divs from "ls".
8396 * The caller is responsible for removing the same number of dimensions
8397 * from the space of "bmap".
8399 static __isl_give isl_basic_map
*insert_divs_from_local_space(
8400 __isl_take isl_basic_map
*bmap
, __isl_keep isl_local_space
*ls
)
8406 n_div
= isl_local_space_dim(ls
, isl_dim_div
);
8408 return isl_basic_map_free(bmap
);
8412 old_n_div
= bmap
->n_div
;
8413 bmap
= insert_div_rows(bmap
, n_div
);
8417 for (i
= 0; i
< n_div
; ++i
) {
8418 isl_seq_cpy(bmap
->div
[i
], ls
->div
->row
[i
], ls
->div
->n_col
);
8419 isl_seq_clr(bmap
->div
[i
] + ls
->div
->n_col
, old_n_div
);
8425 /* Replace the space of "bmap" by the space and divs of "ls".
8427 * If "ls" has any divs, then we simplify the result since we may
8428 * have discovered some additional equalities that could simplify
8429 * the div expressions.
8431 static __isl_give isl_basic_map
*basic_replace_space_by_local_space(
8432 __isl_take isl_basic_map
*bmap
, __isl_take isl_local_space
*ls
)
8436 bmap
= isl_basic_map_cow(bmap
);
8437 n_div
= isl_local_space_dim(ls
, isl_dim_div
);
8438 if (!bmap
|| n_div
< 0)
8441 bmap
= insert_divs_from_local_space(bmap
, ls
);
8445 isl_space_free(bmap
->dim
);
8446 bmap
->dim
= isl_local_space_get_space(ls
);
8450 isl_local_space_free(ls
);
8452 bmap
= isl_basic_map_simplify(bmap
);
8453 bmap
= isl_basic_map_finalize(bmap
);
8456 isl_basic_map_free(bmap
);
8457 isl_local_space_free(ls
);
8461 /* Replace the space of "map" by the space and divs of "ls".
8463 static __isl_give isl_map
*replace_space_by_local_space(__isl_take isl_map
*map
,
8464 __isl_take isl_local_space
*ls
)
8468 map
= isl_map_cow(map
);
8472 for (i
= 0; i
< map
->n
; ++i
) {
8473 map
->p
[i
] = basic_replace_space_by_local_space(map
->p
[i
],
8474 isl_local_space_copy(ls
));
8478 isl_space_free(isl_map_take_space(map
));
8479 map
= isl_map_restore_space(map
, isl_local_space_get_space(ls
));
8481 isl_local_space_free(ls
);
8484 isl_local_space_free(ls
);
8489 /* Compute an explicit representation for the existentially
8490 * quantified variables for which do not know any explicit representation yet.
8492 * We first sort the existentially quantified variables so that the
8493 * existentially quantified variables for which we already have an explicit
8494 * representation are placed before those for which we do not.
8495 * The input dimensions, the output dimensions and the existentially
8496 * quantified variables for which we already have an explicit
8497 * representation are then turned into parameters.
8498 * compute_divs returns a map with the same parameters and
8499 * no input or output dimensions and the dimension specification
8500 * is reset to that of the input, including the existentially quantified
8501 * variables for which we already had an explicit representation.
8503 static __isl_give isl_map
*compute_divs(__isl_take isl_basic_map
*bmap
)
8505 struct isl_basic_set
*bset
;
8506 struct isl_set
*set
;
8507 struct isl_map
*map
;
8509 isl_local_space
*ls
;
8516 bmap
= isl_basic_map_sort_divs(bmap
);
8517 bmap
= isl_basic_map_cow(bmap
);
8521 n_known
= isl_basic_map_first_unknown_div(bmap
);
8522 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
8523 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
8524 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
8525 if (n_known
< 0 || nparam
< 0 || n_in
< 0 || n_out
< 0)
8526 return isl_map_from_basic_map(isl_basic_map_free(bmap
));
8528 space
= isl_space_set_alloc(bmap
->ctx
,
8529 nparam
+ n_in
+ n_out
+ n_known
, 0);
8533 ls
= isl_basic_map_get_local_space(bmap
);
8534 ls
= isl_local_space_drop_dims(ls
, isl_dim_div
,
8535 n_known
, bmap
->n_div
- n_known
);
8537 for (i
= n_known
; i
< bmap
->n_div
; ++i
)
8538 swap_div(bmap
, i
- n_known
, i
);
8539 bmap
->n_div
-= n_known
;
8540 bmap
->extra
-= n_known
;
8542 bmap
= isl_basic_map_reset_space(bmap
, space
);
8543 bset
= bset_from_bmap(bmap
);
8545 set
= parameter_compute_divs(bset
);
8546 map
= set_to_map(set
);
8547 map
= replace_space_by_local_space(map
, ls
);
8551 isl_basic_map_free(bmap
);
8555 /* Is the integer division at position "div" of "bmap" integral?
8556 * That is, does it have denominator 1?
8558 isl_bool
isl_basic_map_div_is_integral(__isl_keep isl_basic_map
*bmap
, int div
)
8560 if (isl_basic_map_check_range(bmap
, isl_dim_div
, div
, 1) < 0)
8561 return isl_bool_error
;
8562 return isl_int_is_one(bmap
->div
[div
][0]);
8565 /* Remove the explicit representation of local variable "div",
8568 __isl_give isl_basic_map
*isl_basic_map_mark_div_unknown(
8569 __isl_take isl_basic_map
*bmap
, int div
)
8573 unknown
= isl_basic_map_div_is_marked_unknown(bmap
, div
);
8575 return isl_basic_map_free(bmap
);
8579 bmap
= isl_basic_map_cow(bmap
);
8582 isl_int_set_si(bmap
->div
[div
][0], 0);
8586 /* Is local variable "div" of "bmap" marked as not having an explicit
8588 * Note that even if "div" is not marked in this way and therefore
8589 * has an explicit representation, this representation may still
8590 * depend (indirectly) on other local variables that do not
8591 * have an explicit representation.
8593 isl_bool
isl_basic_map_div_is_marked_unknown(__isl_keep isl_basic_map
*bmap
,
8596 if (isl_basic_map_check_range(bmap
, isl_dim_div
, div
, 1) < 0)
8597 return isl_bool_error
;
8598 return isl_int_is_zero(bmap
->div
[div
][0]);
8601 /* Return the position of the first local variable that does not
8602 * have an explicit representation.
8603 * Return the total number of local variables if they all have
8604 * an explicit representation.
8605 * Return -1 on error.
8607 int isl_basic_map_first_unknown_div(__isl_keep isl_basic_map
*bmap
)
8614 for (i
= 0; i
< bmap
->n_div
; ++i
) {
8615 if (!isl_basic_map_div_is_known(bmap
, i
))
8621 /* Return the position of the first local variable that does not
8622 * have an explicit representation.
8623 * Return the total number of local variables if they all have
8624 * an explicit representation.
8625 * Return -1 on error.
8627 int isl_basic_set_first_unknown_div(__isl_keep isl_basic_set
*bset
)
8629 return isl_basic_map_first_unknown_div(bset
);
8632 /* Does "bmap" have an explicit representation for all local variables?
8634 isl_bool
isl_basic_map_divs_known(__isl_keep isl_basic_map
*bmap
)
8639 n
= isl_basic_map_dim(bmap
, isl_dim_div
);
8640 first
= isl_basic_map_first_unknown_div(bmap
);
8641 if (n
< 0 || first
< 0)
8642 return isl_bool_error
;
8646 /* Do all basic maps in "map" have an explicit representation
8647 * for all local variables?
8649 isl_bool
isl_map_divs_known(__isl_keep isl_map
*map
)
8654 return isl_bool_error
;
8656 for (i
= 0; i
< map
->n
; ++i
) {
8657 int known
= isl_basic_map_divs_known(map
->p
[i
]);
8662 return isl_bool_true
;
8665 /* If bmap contains any unknown divs, then compute explicit
8666 * expressions for them. However, this computation may be
8667 * quite expensive, so first try to remove divs that aren't
8670 __isl_give isl_map
*isl_basic_map_compute_divs(__isl_take isl_basic_map
*bmap
)
8673 struct isl_map
*map
;
8675 known
= isl_basic_map_divs_known(bmap
);
8679 return isl_map_from_basic_map(bmap
);
8681 bmap
= isl_basic_map_drop_redundant_divs(bmap
);
8683 known
= isl_basic_map_divs_known(bmap
);
8687 return isl_map_from_basic_map(bmap
);
8689 map
= compute_divs(bmap
);
8692 isl_basic_map_free(bmap
);
8696 __isl_give isl_map
*isl_map_compute_divs(__isl_take isl_map
*map
)
8700 struct isl_map
*res
;
8707 known
= isl_map_divs_known(map
);
8715 res
= isl_basic_map_compute_divs(isl_basic_map_copy(map
->p
[0]));
8716 for (i
= 1 ; i
< map
->n
; ++i
) {
8718 r2
= isl_basic_map_compute_divs(isl_basic_map_copy(map
->p
[i
]));
8719 if (ISL_F_ISSET(map
, ISL_MAP_DISJOINT
))
8720 res
= isl_map_union_disjoint(res
, r2
);
8722 res
= isl_map_union(res
, r2
);
8729 __isl_give isl_set
*isl_basic_set_compute_divs(__isl_take isl_basic_set
*bset
)
8731 return set_from_map(isl_basic_map_compute_divs(bset_to_bmap(bset
)));
8734 __isl_give isl_set
*isl_set_compute_divs(__isl_take isl_set
*set
)
8736 return set_from_map(isl_map_compute_divs(set_to_map(set
)));
8739 __isl_give isl_set
*isl_map_domain(__isl_take isl_map
*map
)
8744 n_out
= isl_map_dim(map
, isl_dim_out
);
8746 return set_from_map(isl_map_free(map
));
8747 space
= isl_space_domain(isl_map_get_space(map
));
8749 map
= isl_map_project_out(map
, isl_dim_out
, 0, n_out
);
8751 return set_from_map(isl_map_reset_space(map
, space
));
8754 /* Return the union of "map1" and "map2", where we assume for now that
8755 * "map1" and "map2" are disjoint. Note that the basic maps inside
8756 * "map1" or "map2" may not be disjoint from each other.
8757 * Also note that this function is also called from isl_map_union,
8758 * which takes care of handling the situation where "map1" and "map2"
8759 * may not be disjoint.
8761 * If one of the inputs is empty, we can simply return the other input.
8762 * Similarly, if one of the inputs is universal, then it is equal to the union.
8764 static __isl_give isl_map
*map_union_disjoint(__isl_take isl_map
*map1
,
8765 __isl_take isl_map
*map2
)
8769 struct isl_map
*map
= NULL
;
8772 if (isl_map_check_equal_space(map1
, map2
) < 0)
8784 is_universe
= isl_map_plain_is_universe(map1
);
8785 if (is_universe
< 0)
8792 is_universe
= isl_map_plain_is_universe(map2
);
8793 if (is_universe
< 0)
8800 if (ISL_F_ISSET(map1
, ISL_MAP_DISJOINT
) &&
8801 ISL_F_ISSET(map2
, ISL_MAP_DISJOINT
))
8802 ISL_FL_SET(flags
, ISL_MAP_DISJOINT
);
8804 map
= isl_map_alloc_space(isl_space_copy(map1
->dim
),
8805 map1
->n
+ map2
->n
, flags
);
8808 for (i
= 0; i
< map1
->n
; ++i
) {
8809 map
= isl_map_add_basic_map(map
,
8810 isl_basic_map_copy(map1
->p
[i
]));
8814 for (i
= 0; i
< map2
->n
; ++i
) {
8815 map
= isl_map_add_basic_map(map
,
8816 isl_basic_map_copy(map2
->p
[i
]));
8830 /* Return the union of "map1" and "map2", where "map1" and "map2" are
8831 * guaranteed to be disjoint by the caller.
8833 * Note that this functions is called from within isl_map_make_disjoint,
8834 * so we have to be careful not to touch the constraints of the inputs
8837 __isl_give isl_map
*isl_map_union_disjoint(__isl_take isl_map
*map1
,
8838 __isl_take isl_map
*map2
)
8840 isl_map_align_params_bin(&map1
, &map2
);
8841 return map_union_disjoint(map1
, map2
);
8844 /* Return the union of "map1" and "map2", where "map1" and "map2" may
8847 * We currently simply call map_union_disjoint, the internal operation
8848 * of which does not really depend on the inputs being disjoint.
8849 * If the result contains more than one basic map, then we clear
8850 * the disjoint flag since the result may contain basic maps from
8851 * both inputs and these are not guaranteed to be disjoint.
8853 * As a special case, if "map1" and "map2" are obviously equal,
8854 * then we simply return "map1".
8856 __isl_give isl_map
*isl_map_union(__isl_take isl_map
*map1
,
8857 __isl_take isl_map
*map2
)
8861 if (isl_map_align_params_bin(&map1
, &map2
) < 0)
8864 equal
= isl_map_plain_is_equal(map1
, map2
);
8872 map1
= map_union_disjoint(map1
, map2
);
8876 ISL_F_CLR(map1
, ISL_MAP_DISJOINT
);
8884 __isl_give isl_set
*isl_set_union_disjoint(
8885 __isl_take isl_set
*set1
, __isl_take isl_set
*set2
)
8887 return set_from_map(isl_map_union_disjoint(set_to_map(set1
),
8891 __isl_give isl_set
*isl_set_union(__isl_take isl_set
*set1
,
8892 __isl_take isl_set
*set2
)
8894 return set_from_map(isl_map_union(set_to_map(set1
), set_to_map(set2
)));
8897 /* Apply "fn" to pairs of elements from "map" and "set" and collect
8898 * the results in a map living in "space".
8900 * "map" and "set" are assumed to be compatible and non-NULL.
8902 static __isl_give isl_map
*map_intersect_set(__isl_take isl_map
*map
,
8903 __isl_take isl_space
*space
, __isl_take isl_set
*set
,
8904 __isl_give isl_basic_map
*fn(__isl_take isl_basic_map
*bmap
,
8905 __isl_take isl_basic_set
*bset
))
8908 struct isl_map
*result
;
8911 if (isl_set_plain_is_universe(set
)) {
8913 return isl_map_reset_equal_dim_space(map
, space
);
8916 if (ISL_F_ISSET(map
, ISL_MAP_DISJOINT
) &&
8917 ISL_F_ISSET(set
, ISL_MAP_DISJOINT
))
8918 ISL_FL_SET(flags
, ISL_MAP_DISJOINT
);
8920 result
= isl_map_alloc_space(space
, map
->n
* set
->n
, flags
);
8921 for (i
= 0; result
&& i
< map
->n
; ++i
)
8922 for (j
= 0; j
< set
->n
; ++j
) {
8923 result
= isl_map_add_basic_map(result
,
8924 fn(isl_basic_map_copy(map
->p
[i
]),
8925 isl_basic_set_copy(set
->p
[j
])));
8935 __isl_give isl_map
*isl_map_intersect_range(__isl_take isl_map
*map
,
8936 __isl_take isl_set
*set
)
8941 isl_map_align_params_set(&map
, &set
);
8942 ok
= isl_map_compatible_range(map
, set
);
8946 isl_die(set
->ctx
, isl_error_invalid
,
8947 "incompatible spaces", goto error
);
8949 space
= isl_map_get_space(map
);
8950 return map_intersect_set(map
, space
, set
,
8951 &isl_basic_map_intersect_range
);
8958 /* Intersect the domain of "map" with "set".
8960 * If the domain dimensions of "map" do not have any identifiers,
8961 * then copy them over from "set".
8963 __isl_give isl_map
*isl_map_intersect_domain(__isl_take isl_map
*map
,
8964 __isl_take isl_set
*set
)
8969 isl_map_align_params_set(&map
, &set
);
8970 ok
= isl_map_compatible_domain(map
, set
);
8974 isl_die(set
->ctx
, isl_error_invalid
,
8975 "incompatible spaces", goto error
);
8977 space
= isl_map_get_space(map
);
8978 space
= isl_space_copy_ids_if_unset(space
, isl_dim_in
,
8979 isl_set_peek_space(set
), isl_dim_set
);
8980 return map_intersect_set(map
, space
, set
,
8981 &isl_basic_map_intersect_domain
);
8991 #include "isl_copy_tuple_id_templ.c"
8993 /* Data structure that specifies how isl_map_intersect_factor
8996 * "preserve_type" is the tuple where the factor differs from
8997 * the input map and of which the identifiers needs
8998 * to be preserved explicitly.
8999 * "other_factor" is used to extract the space of the other factor
9000 * from the space of the product ("map").
9001 * "product" is used to combine the given factor and a universe map
9002 * in the space returned by "other_factor" to produce a map
9003 * that lives in the same space as the input map.
9005 struct isl_intersect_factor_control
{
9006 enum isl_dim_type preserve_type
;
9007 __isl_give isl_space
*(*other_factor
)(__isl_take isl_space
*space
);
9008 __isl_give isl_map
*(*product
)(__isl_take isl_map
*factor
,
9009 __isl_take isl_map
*other
);
9012 /* Given a map "map" in some product space and a map "factor"
9013 * living in some factor space, return the intersection.
9015 * After aligning the parameters,
9016 * the map "factor" is first extended to a map living in the same space
9017 * as "map" and then a regular intersection is computed.
9019 * Note that the extension is computed as a product, which is anonymous
9020 * by default. If "map" has an identifier on the corresponding tuple,
9021 * then this identifier needs to be set on the product
9022 * before the intersection is computed.
9024 static __isl_give isl_map
*isl_map_intersect_factor(
9025 __isl_take isl_map
*map
, __isl_take isl_map
*factor
,
9026 struct isl_intersect_factor_control
*control
)
9030 isl_map
*other
, *product
;
9032 equal
= isl_map_has_equal_params(map
, factor
);
9036 map
= isl_map_align_params(map
, isl_map_get_space(factor
));
9037 factor
= isl_map_align_params(factor
, isl_map_get_space(map
));
9040 space
= isl_map_get_space(map
);
9041 other
= isl_map_universe(control
->other_factor(space
));
9042 product
= control
->product(factor
, other
);
9044 space
= isl_map_peek_space(map
);
9045 product
= isl_map_copy_tuple_id(product
, control
->preserve_type
,
9046 space
, control
->preserve_type
);
9047 return map_intersect(map
, product
);
9050 isl_map_free(factor
);
9054 /* Return the domain product of "map2" and "map1".
9056 static __isl_give isl_map
*isl_map_reverse_domain_product(
9057 __isl_take isl_map
*map1
, __isl_take isl_map
*map2
)
9059 return isl_map_domain_product(map2
, map1
);
9062 /* Return the range product of "map2" and "map1".
9064 static __isl_give isl_map
*isl_map_reverse_range_product(
9065 __isl_take isl_map
*map1
, __isl_take isl_map
*map2
)
9067 return isl_map_range_product(map2
, map1
);
9070 /* Given a map "map" in a space [A -> B] -> C and a map "factor"
9071 * in the space A -> C, return the intersection.
9073 __isl_give isl_map
*isl_map_intersect_domain_factor_domain(
9074 __isl_take isl_map
*map
, __isl_take isl_map
*factor
)
9076 struct isl_intersect_factor_control control
= {
9077 .preserve_type
= isl_dim_in
,
9078 .other_factor
= isl_space_domain_factor_range
,
9079 .product
= isl_map_domain_product
,
9082 return isl_map_intersect_factor(map
, factor
, &control
);
9085 /* Given a map "map" in a space [A -> B] -> C and a map "factor"
9086 * in the space B -> C, return the intersection.
9088 __isl_give isl_map
*isl_map_intersect_domain_factor_range(
9089 __isl_take isl_map
*map
, __isl_take isl_map
*factor
)
9091 struct isl_intersect_factor_control control
= {
9092 .preserve_type
= isl_dim_in
,
9093 .other_factor
= isl_space_domain_factor_domain
,
9094 .product
= isl_map_reverse_domain_product
,
9097 return isl_map_intersect_factor(map
, factor
, &control
);
9100 /* Given a map "map" in a space A -> [B -> C] and a map "factor"
9101 * in the space A -> B, return the intersection.
9103 __isl_give isl_map
*isl_map_intersect_range_factor_domain(
9104 __isl_take isl_map
*map
, __isl_take isl_map
*factor
)
9106 struct isl_intersect_factor_control control
= {
9107 .preserve_type
= isl_dim_out
,
9108 .other_factor
= isl_space_range_factor_range
,
9109 .product
= isl_map_range_product
,
9112 return isl_map_intersect_factor(map
, factor
, &control
);
9115 /* Given a map "map" in a space A -> [B -> C] and a map "factor"
9116 * in the space A -> C, return the intersection.
9118 __isl_give isl_map
*isl_map_intersect_range_factor_range(
9119 __isl_take isl_map
*map
, __isl_take isl_map
*factor
)
9121 struct isl_intersect_factor_control control
= {
9122 .preserve_type
= isl_dim_out
,
9123 .other_factor
= isl_space_range_factor_domain
,
9124 .product
= isl_map_reverse_range_product
,
9127 return isl_map_intersect_factor(map
, factor
, &control
);
9130 /* Given a set "set" in a space [A -> B] and a set "domain"
9131 * in the space A, return the intersection.
9133 * The set "domain" is first extended to a set living in the space
9134 * [A -> B] and then a regular intersection is computed.
9136 __isl_give isl_set
*isl_set_intersect_factor_domain(__isl_take isl_set
*set
,
9137 __isl_take isl_set
*domain
)
9139 struct isl_intersect_factor_control control
= {
9140 .preserve_type
= isl_dim_set
,
9141 .other_factor
= isl_space_factor_range
,
9142 .product
= isl_map_range_product
,
9145 return set_from_map(isl_map_intersect_factor(set_to_map(set
),
9146 set_to_map(domain
), &control
));
9149 /* Given a set "set" in a space [A -> B] and a set "range"
9150 * in the space B, return the intersection.
9152 * The set "range" is first extended to a set living in the space
9153 * [A -> B] and then a regular intersection is computed.
9155 __isl_give isl_set
*isl_set_intersect_factor_range(__isl_take isl_set
*set
,
9156 __isl_take isl_set
*range
)
9158 struct isl_intersect_factor_control control
= {
9159 .preserve_type
= isl_dim_set
,
9160 .other_factor
= isl_space_factor_domain
,
9161 .product
= isl_map_reverse_range_product
,
9164 return set_from_map(isl_map_intersect_factor(set_to_map(set
),
9165 set_to_map(range
), &control
));
9171 #include "isl_copy_tuple_id_templ.c"
9173 /* Given a map "map" in a space [A -> B] -> C and a set "domain"
9174 * in the space A, return the intersection.
9176 * The set "domain" is extended to a set living in the space [A -> B] and
9177 * the domain of "map" is intersected with this set.
9179 * If "map" has an identifier on the domain tuple,
9180 * then this identifier needs to be set on this product
9181 * before the intersection is computed.
9183 __isl_give isl_map
*isl_map_intersect_domain_wrapped_domain(
9184 __isl_take isl_map
*map
, __isl_take isl_set
*domain
)
9189 isl_map_align_params_set(&map
, &domain
);
9190 space
= isl_map_get_space(map
);
9191 space
= isl_space_domain_wrapped_range(space
);
9192 factor
= isl_set_universe(space
);
9193 domain
= isl_set_product(domain
, factor
);
9194 space
= isl_map_peek_space(map
);
9195 domain
= isl_set_copy_tuple_id(domain
, isl_dim_set
, space
, isl_dim_in
);
9196 return isl_map_intersect_domain(map
, domain
);
9199 /* Given a map "map" in a space A -> [B -> C] and a set "domain"
9200 * in the space B, return the intersection.
9202 * The set "domain" is extended to a set living in the space [B -> C] and
9203 * the range of "map" is intersected with this set.
9205 * If "map" has an identifier on the range tuple,
9206 * then this identifier needs to be set on this product
9207 * before the intersection is computed.
9209 __isl_give isl_map
*isl_map_intersect_range_wrapped_domain(
9210 __isl_take isl_map
*map
, __isl_take isl_set
*domain
)
9215 isl_map_align_params_set(&map
, &domain
);
9216 space
= isl_map_get_space(map
);
9217 space
= isl_space_range_wrapped_range(space
);
9218 factor
= isl_set_universe(space
);
9219 domain
= isl_set_product(domain
, factor
);
9220 space
= isl_map_peek_space(map
);
9221 domain
= isl_set_copy_tuple_id(domain
, isl_dim_set
, space
, isl_dim_out
);
9222 return isl_map_intersect_range(map
, domain
);
9225 __isl_give isl_map
*isl_map_apply_domain(__isl_take isl_map
*map1
,
9226 __isl_take isl_map
*map2
)
9228 if (isl_map_align_params_bin(&map1
, &map2
) < 0)
9230 map1
= isl_map_reverse(map1
);
9231 map1
= isl_map_apply_range(map1
, map2
);
9232 return isl_map_reverse(map1
);
9239 __isl_give isl_map
*isl_map_apply_range(__isl_take isl_map
*map1
,
9240 __isl_take isl_map
*map2
)
9243 struct isl_map
*result
;
9246 if (isl_map_align_params_bin(&map1
, &map2
) < 0)
9249 space
= isl_space_join(isl_space_copy(map1
->dim
),
9250 isl_space_copy(map2
->dim
));
9252 result
= isl_map_alloc_space(space
, map1
->n
* map2
->n
, 0);
9255 for (i
= 0; i
< map1
->n
; ++i
)
9256 for (j
= 0; j
< map2
->n
; ++j
) {
9257 result
= isl_map_add_basic_map(result
,
9258 isl_basic_map_apply_range(
9259 isl_basic_map_copy(map1
->p
[i
]),
9260 isl_basic_map_copy(map2
->p
[j
])));
9266 if (result
&& result
->n
<= 1)
9267 ISL_F_SET(result
, ISL_MAP_DISJOINT
);
9275 /* Is "bmap" a transformation, i.e.,
9276 * does it relate elements from the same space.
9278 isl_bool
isl_basic_map_is_transformation(__isl_keep isl_basic_map
*bmap
)
9282 space
= isl_basic_map_peek_space(bmap
);
9283 return isl_space_tuple_is_equal(space
, isl_dim_in
, space
, isl_dim_out
);
9286 /* Check that "bmap" is a transformation, i.e.,
9287 * that it relates elements from the same space.
9289 static isl_stat
isl_basic_map_check_transformation(
9290 __isl_keep isl_basic_map
*bmap
)
9294 equal
= isl_basic_map_is_transformation(bmap
);
9296 return isl_stat_error
;
9298 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
9299 "domain and range don't match", return isl_stat_error
);
9304 * returns range - domain
9306 __isl_give isl_basic_set
*isl_basic_map_deltas(__isl_take isl_basic_map
*bmap
)
9308 isl_space
*target_space
;
9309 struct isl_basic_set
*bset
;
9315 if (isl_basic_map_check_transformation(bmap
) < 0)
9316 return isl_basic_map_free(bmap
);
9317 dim
= isl_basic_map_dim(bmap
, isl_dim_in
);
9318 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
9319 if (dim
< 0 || nparam
< 0)
9321 target_space
= isl_space_domain(isl_basic_map_get_space(bmap
));
9322 bmap
= isl_basic_map_from_range(isl_basic_map_wrap(bmap
));
9323 bmap
= isl_basic_map_add_dims(bmap
, isl_dim_in
, dim
);
9324 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
9326 bmap
= isl_basic_map_free(bmap
);
9327 bmap
= isl_basic_map_extend_constraints(bmap
, dim
, 0);
9328 for (i
= 0; i
< dim
; ++i
) {
9329 int j
= isl_basic_map_alloc_equality(bmap
);
9331 bmap
= isl_basic_map_free(bmap
);
9334 isl_seq_clr(bmap
->eq
[j
], 1 + total
);
9335 isl_int_set_si(bmap
->eq
[j
][1+nparam
+i
], 1);
9336 isl_int_set_si(bmap
->eq
[j
][1+nparam
+dim
+i
], 1);
9337 isl_int_set_si(bmap
->eq
[j
][1+nparam
+2*dim
+i
], -1);
9339 bset
= isl_basic_map_domain(bmap
);
9340 bset
= isl_basic_set_reset_space(bset
, target_space
);
9343 isl_basic_map_free(bmap
);
9347 /* Is the tuple of type "type1" of "map" the same as
9348 * the tuple of type "type2" of "space"?
9350 isl_bool
isl_map_space_tuple_is_equal(__isl_keep isl_map
*map
,
9351 enum isl_dim_type type1
, __isl_keep isl_space
*space
,
9352 enum isl_dim_type type2
)
9354 isl_space
*map_space
;
9356 map_space
= isl_map_peek_space(map
);
9357 return isl_space_tuple_is_equal(map_space
, type1
, space
, type2
);
9360 /* Is the tuple of type "type1" of "map1" the same as
9361 * the tuple of type "type2" of "map2"?
9363 isl_bool
isl_map_tuple_is_equal(__isl_keep isl_map
*map1
,
9364 enum isl_dim_type type1
, __isl_keep isl_map
*map2
,
9365 enum isl_dim_type type2
)
9367 isl_space
*space1
, *space2
;
9369 space1
= isl_map_peek_space(map1
);
9370 space2
= isl_map_peek_space(map2
);
9371 return isl_space_tuple_is_equal(space1
, type1
, space2
, type2
);
9374 /* Is the space of "obj" equal to "space", ignoring parameters?
9376 isl_bool
isl_map_has_space_tuples(__isl_keep isl_map
*map
,
9377 __isl_keep isl_space
*space
)
9379 isl_space
*map_space
;
9381 map_space
= isl_map_peek_space(map
);
9382 return isl_space_has_equal_tuples(map_space
, space
);
9385 /* Check that "map" is a transformation, i.e.,
9386 * that it relates elements from the same space.
9388 isl_stat
isl_map_check_transformation(__isl_keep isl_map
*map
)
9392 equal
= isl_map_tuple_is_equal(map
, isl_dim_in
, map
, isl_dim_out
);
9394 return isl_stat_error
;
9396 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
9397 "domain and range don't match", return isl_stat_error
);
9402 * returns range - domain
9404 __isl_give isl_set
*isl_map_deltas(__isl_take isl_map
*map
)
9408 struct isl_set
*result
;
9410 if (isl_map_check_transformation(map
) < 0)
9412 space
= isl_map_get_space(map
);
9413 space
= isl_space_domain(space
);
9414 result
= isl_set_alloc_space(space
, map
->n
, 0);
9417 for (i
= 0; i
< map
->n
; ++i
)
9418 result
= isl_set_add_basic_set(result
,
9419 isl_basic_map_deltas(isl_basic_map_copy(map
->p
[i
])));
9428 * returns [domain -> range] -> range - domain
9430 __isl_give isl_basic_map
*isl_basic_map_deltas_map(
9431 __isl_take isl_basic_map
*bmap
)
9435 isl_basic_map
*domain
;
9439 if (isl_basic_map_check_transformation(bmap
) < 0)
9440 return isl_basic_map_free(bmap
);
9442 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
9443 n
= isl_basic_map_dim(bmap
, isl_dim_in
);
9444 if (nparam
< 0 || n
< 0)
9445 return isl_basic_map_free(bmap
);
9447 space
= isl_basic_map_get_space(bmap
);
9448 space
= isl_space_from_range(isl_space_domain(space
));
9449 domain
= isl_basic_map_universe(space
);
9451 bmap
= isl_basic_map_from_domain(isl_basic_map_wrap(bmap
));
9452 bmap
= isl_basic_map_apply_range(bmap
, domain
);
9453 bmap
= isl_basic_map_extend_constraints(bmap
, n
, 0);
9455 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
9457 return isl_basic_map_free(bmap
);
9459 for (i
= 0; i
< n
; ++i
) {
9460 k
= isl_basic_map_alloc_equality(bmap
);
9463 isl_seq_clr(bmap
->eq
[k
], 1 + total
);
9464 isl_int_set_si(bmap
->eq
[k
][1 + nparam
+ i
], 1);
9465 isl_int_set_si(bmap
->eq
[k
][1 + nparam
+ n
+ i
], -1);
9466 isl_int_set_si(bmap
->eq
[k
][1 + nparam
+ n
+ n
+ i
], 1);
9469 bmap
= isl_basic_map_gauss(bmap
, NULL
);
9470 return isl_basic_map_finalize(bmap
);
9472 isl_basic_map_free(bmap
);
9477 * returns [domain -> range] -> range - domain
9479 __isl_give isl_map
*isl_map_deltas_map(__isl_take isl_map
*map
)
9481 if (isl_map_check_transformation(map
) < 0)
9482 return isl_map_free(map
);
9484 return isl_map_transform(map
, &isl_space_range_map
,
9485 &isl_basic_map_deltas_map
);
9488 /* Return pairs of elements { x -> y } such that y - x is in "deltas".
9490 __isl_give isl_map
*isl_set_translation(__isl_take isl_set
*deltas
)
9495 space
= isl_space_map_from_set(isl_set_get_space(deltas
));
9496 map
= isl_map_deltas_map(isl_map_universe(space
));
9497 map
= isl_map_intersect_range(map
, deltas
);
9499 return isl_set_unwrap(isl_map_domain(map
));
9502 __isl_give isl_basic_map
*isl_basic_map_identity(__isl_take isl_space
*space
)
9504 isl_size n_in
, n_out
;
9506 n_in
= isl_space_dim(space
, isl_dim_in
);
9507 n_out
= isl_space_dim(space
, isl_dim_out
);
9508 if (n_in
< 0 || n_out
< 0)
9511 isl_die(space
->ctx
, isl_error_invalid
,
9512 "number of input and output dimensions needs to be "
9513 "the same", goto error
);
9514 return isl_basic_map_equal(space
, n_in
);
9516 isl_space_free(space
);
9520 __isl_give isl_map
*isl_map_identity(__isl_take isl_space
*space
)
9522 return isl_map_from_basic_map(isl_basic_map_identity(space
));
9525 __isl_give isl_map
*isl_set_identity(__isl_take isl_set
*set
)
9527 isl_space
*space
= isl_set_get_space(set
);
9529 id
= isl_map_identity(isl_space_map_from_set(space
));
9530 return isl_map_intersect_range(id
, set
);
9533 /* Construct a basic set with all set dimensions having only non-negative
9536 __isl_give isl_basic_set
*isl_basic_set_positive_orthant(
9537 __isl_take isl_space
*space
)
9543 struct isl_basic_set
*bset
;
9545 nparam
= isl_space_dim(space
, isl_dim_param
);
9546 dim
= isl_space_dim(space
, isl_dim_set
);
9547 total
= isl_space_dim(space
, isl_dim_all
);
9548 if (nparam
< 0 || dim
< 0 || total
< 0)
9549 space
= isl_space_free(space
);
9550 bset
= isl_basic_set_alloc_space(space
, 0, 0, dim
);
9553 for (i
= 0; i
< dim
; ++i
) {
9554 int k
= isl_basic_set_alloc_inequality(bset
);
9557 isl_seq_clr(bset
->ineq
[k
], 1 + total
);
9558 isl_int_set_si(bset
->ineq
[k
][1 + nparam
+ i
], 1);
9562 isl_basic_set_free(bset
);
9566 /* Construct the half-space x_pos >= 0.
9568 static __isl_give isl_basic_set
*nonneg_halfspace(__isl_take isl_space
*space
,
9573 isl_basic_set
*nonneg
;
9575 total
= isl_space_dim(space
, isl_dim_all
);
9577 space
= isl_space_free(space
);
9578 nonneg
= isl_basic_set_alloc_space(space
, 0, 0, 1);
9579 k
= isl_basic_set_alloc_inequality(nonneg
);
9582 isl_seq_clr(nonneg
->ineq
[k
], 1 + total
);
9583 isl_int_set_si(nonneg
->ineq
[k
][pos
], 1);
9585 return isl_basic_set_finalize(nonneg
);
9587 isl_basic_set_free(nonneg
);
9591 /* Construct the half-space x_pos <= -1.
9593 static __isl_give isl_basic_set
*neg_halfspace(__isl_take isl_space
*space
,
9600 total
= isl_space_dim(space
, isl_dim_all
);
9602 space
= isl_space_free(space
);
9603 neg
= isl_basic_set_alloc_space(space
, 0, 0, 1);
9604 k
= isl_basic_set_alloc_inequality(neg
);
9607 isl_seq_clr(neg
->ineq
[k
], 1 + total
);
9608 isl_int_set_si(neg
->ineq
[k
][0], -1);
9609 isl_int_set_si(neg
->ineq
[k
][pos
], -1);
9611 return isl_basic_set_finalize(neg
);
9613 isl_basic_set_free(neg
);
9617 __isl_give isl_set
*isl_set_split_dims(__isl_take isl_set
*set
,
9618 enum isl_dim_type type
, unsigned first
, unsigned n
)
9622 isl_basic_set
*nonneg
;
9628 if (isl_set_check_range(set
, type
, first
, n
) < 0)
9629 return isl_set_free(set
);
9631 offset
= pos(set
->dim
, type
);
9632 for (i
= 0; i
< n
; ++i
) {
9633 nonneg
= nonneg_halfspace(isl_set_get_space(set
),
9634 offset
+ first
+ i
);
9635 neg
= neg_halfspace(isl_set_get_space(set
), offset
+ first
+ i
);
9637 set
= isl_set_intersect(set
, isl_basic_set_union(nonneg
, neg
));
9643 static isl_stat
foreach_orthant(__isl_take isl_set
*set
, int *signs
, int first
,
9645 isl_stat (*fn
)(__isl_take isl_set
*orthant
, int *signs
, void *user
),
9651 return isl_stat_error
;
9652 if (isl_set_plain_is_empty(set
)) {
9657 return fn(set
, signs
, user
);
9660 half
= isl_set_from_basic_set(nonneg_halfspace(isl_set_get_space(set
),
9662 half
= isl_set_intersect(half
, isl_set_copy(set
));
9663 if (foreach_orthant(half
, signs
, first
+ 1, len
, fn
, user
) < 0)
9667 half
= isl_set_from_basic_set(neg_halfspace(isl_set_get_space(set
),
9669 half
= isl_set_intersect(half
, set
);
9670 return foreach_orthant(half
, signs
, first
+ 1, len
, fn
, user
);
9673 return isl_stat_error
;
9676 /* Call "fn" on the intersections of "set" with each of the orthants
9677 * (except for obviously empty intersections). The orthant is identified
9678 * by the signs array, with each entry having value 1 or -1 according
9679 * to the sign of the corresponding variable.
9681 isl_stat
isl_set_foreach_orthant(__isl_keep isl_set
*set
,
9682 isl_stat (*fn
)(__isl_take isl_set
*orthant
, int *signs
, void *user
),
9691 return isl_stat_error
;
9692 if (isl_set_plain_is_empty(set
))
9695 nparam
= isl_set_dim(set
, isl_dim_param
);
9696 nvar
= isl_set_dim(set
, isl_dim_set
);
9697 if (nparam
< 0 || nvar
< 0)
9698 return isl_stat_error
;
9700 signs
= isl_alloc_array(set
->ctx
, int, nparam
+ nvar
);
9702 r
= foreach_orthant(isl_set_copy(set
), signs
, 0, nparam
+ nvar
,
9710 isl_bool
isl_set_is_equal(__isl_keep isl_set
*set1
, __isl_keep isl_set
*set2
)
9712 return isl_map_is_equal(set_to_map(set1
), set_to_map(set2
));
9715 isl_bool
isl_basic_map_is_subset(__isl_keep isl_basic_map
*bmap1
,
9716 __isl_keep isl_basic_map
*bmap2
)
9719 struct isl_map
*map1
;
9720 struct isl_map
*map2
;
9722 if (!bmap1
|| !bmap2
)
9723 return isl_bool_error
;
9725 map1
= isl_map_from_basic_map(isl_basic_map_copy(bmap1
));
9726 map2
= isl_map_from_basic_map(isl_basic_map_copy(bmap2
));
9728 is_subset
= isl_map_is_subset(map1
, map2
);
9736 isl_bool
isl_basic_set_is_subset(__isl_keep isl_basic_set
*bset1
,
9737 __isl_keep isl_basic_set
*bset2
)
9739 return isl_basic_map_is_subset(bset1
, bset2
);
9742 isl_bool
isl_basic_map_is_equal(__isl_keep isl_basic_map
*bmap1
,
9743 __isl_keep isl_basic_map
*bmap2
)
9747 if (!bmap1
|| !bmap2
)
9748 return isl_bool_error
;
9749 is_subset
= isl_basic_map_is_subset(bmap1
, bmap2
);
9750 if (is_subset
!= isl_bool_true
)
9752 is_subset
= isl_basic_map_is_subset(bmap2
, bmap1
);
9756 isl_bool
isl_basic_set_is_equal(__isl_keep isl_basic_set
*bset1
,
9757 __isl_keep isl_basic_set
*bset2
)
9759 return isl_basic_map_is_equal(
9760 bset_to_bmap(bset1
), bset_to_bmap(bset2
));
9763 isl_bool
isl_map_is_empty(__isl_keep isl_map
*map
)
9769 return isl_bool_error
;
9770 for (i
= 0; i
< map
->n
; ++i
) {
9771 is_empty
= isl_basic_map_is_empty(map
->p
[i
]);
9773 return isl_bool_error
;
9775 return isl_bool_false
;
9777 return isl_bool_true
;
9780 isl_bool
isl_map_plain_is_empty(__isl_keep isl_map
*map
)
9782 return map
? map
->n
== 0 : isl_bool_error
;
9785 isl_bool
isl_set_plain_is_empty(__isl_keep isl_set
*set
)
9787 return set
? set
->n
== 0 : isl_bool_error
;
9790 isl_bool
isl_set_is_empty(__isl_keep isl_set
*set
)
9792 return isl_map_is_empty(set_to_map(set
));
9796 #define TYPE isl_basic_map
9799 #include "isl_type_has_equal_space_bin_templ.c"
9800 #include "isl_type_check_equal_space_templ.c"
9802 /* Check that "bset1" and "bset2" live in the same space,
9803 * reporting an error if they do not.
9805 isl_stat
isl_basic_set_check_equal_space(__isl_keep isl_basic_set
*bset1
,
9806 __isl_keep isl_basic_set
*bset2
)
9808 return isl_basic_map_check_equal_space(bset_to_bmap(bset1
),
9809 bset_to_bmap(bset1
));
9813 #define TYPE isl_map
9815 #include "isl_type_has_equal_space_bin_templ.c"
9816 #include "isl_type_check_equal_space_templ.c"
9817 #include "isl_type_has_space_templ.c"
9819 isl_bool
isl_set_has_equal_space(__isl_keep isl_set
*set1
,
9820 __isl_keep isl_set
*set2
)
9822 return isl_map_has_equal_space(set_to_map(set1
), set_to_map(set2
));
9826 #define TYPE1 isl_map
9828 #define TYPE2 isl_basic_map
9830 #define TYPE_PAIR isl_map_basic_map
9833 #include "isl_type_has_equal_space_templ.c"
9834 #include "isl_type_check_equal_space_templ.c"
9836 /* Check that "set" and "bset" live in the same space,
9837 * reporting an error if they do not.
9839 isl_stat
isl_set_basic_set_check_equal_space(__isl_keep isl_set
*set
,
9840 __isl_keep isl_basic_set
*bset
)
9842 return isl_map_basic_map_check_equal_space(set_to_map(set
),
9843 bset_to_bmap(bset
));
9846 static isl_bool
map_is_equal(__isl_keep isl_map
*map1
, __isl_keep isl_map
*map2
)
9851 return isl_bool_error
;
9852 is_subset
= isl_map_is_subset(map1
, map2
);
9853 if (is_subset
!= isl_bool_true
)
9855 is_subset
= isl_map_is_subset(map2
, map1
);
9859 /* Is "map1" equal to "map2"?
9861 * First check if they are obviously equal.
9862 * If not, then perform a more detailed analysis.
9864 isl_bool
isl_map_is_equal(__isl_keep isl_map
*map1
, __isl_keep isl_map
*map2
)
9868 equal
= isl_map_plain_is_equal(map1
, map2
);
9869 if (equal
< 0 || equal
)
9871 return isl_map_align_params_map_map_and_test(map1
, map2
, &map_is_equal
);
9874 isl_bool
isl_basic_map_is_strict_subset(__isl_keep isl_basic_map
*bmap1
,
9875 __isl_keep isl_basic_map
*bmap2
)
9879 if (!bmap1
|| !bmap2
)
9880 return isl_bool_error
;
9881 is_subset
= isl_basic_map_is_subset(bmap1
, bmap2
);
9882 if (is_subset
!= isl_bool_true
)
9884 is_subset
= isl_basic_map_is_subset(bmap2
, bmap1
);
9885 return isl_bool_not(is_subset
);
9888 isl_bool
isl_map_is_strict_subset(__isl_keep isl_map
*map1
,
9889 __isl_keep isl_map
*map2
)
9894 return isl_bool_error
;
9895 is_subset
= isl_map_is_subset(map1
, map2
);
9896 if (is_subset
!= isl_bool_true
)
9898 is_subset
= isl_map_is_subset(map2
, map1
);
9899 return isl_bool_not(is_subset
);
9902 isl_bool
isl_set_is_strict_subset(__isl_keep isl_set
*set1
,
9903 __isl_keep isl_set
*set2
)
9905 return isl_map_is_strict_subset(set_to_map(set1
), set_to_map(set2
));
9908 /* Is "bmap" obviously equal to the universe with the same space?
9910 * That is, does it not have any constraints?
9912 isl_bool
isl_basic_map_plain_is_universe(__isl_keep isl_basic_map
*bmap
)
9915 return isl_bool_error
;
9916 return bmap
->n_eq
== 0 && bmap
->n_ineq
== 0;
9919 /* Is "bset" obviously equal to the universe with the same space?
9921 isl_bool
isl_basic_set_plain_is_universe(__isl_keep isl_basic_set
*bset
)
9923 return isl_basic_map_plain_is_universe(bset
);
9926 /* If "c" does not involve any existentially quantified variables,
9927 * then set *univ to false and abort
9929 static isl_stat
involves_divs(__isl_take isl_constraint
*c
, void *user
)
9931 isl_bool
*univ
= user
;
9934 n
= isl_constraint_dim(c
, isl_dim_div
);
9936 c
= isl_constraint_free(c
);
9937 *univ
= isl_constraint_involves_dims(c
, isl_dim_div
, 0, n
);
9938 isl_constraint_free(c
);
9939 if (*univ
< 0 || !*univ
)
9940 return isl_stat_error
;
9944 /* Is "bmap" equal to the universe with the same space?
9946 * First check if it is obviously equal to the universe.
9947 * If not and if there are any constraints not involving
9948 * existentially quantified variables, then it is certainly
9949 * not equal to the universe.
9950 * Otherwise, check if the universe is a subset of "bmap".
9952 isl_bool
isl_basic_map_is_universe(__isl_keep isl_basic_map
*bmap
)
9956 isl_basic_map
*test
;
9958 univ
= isl_basic_map_plain_is_universe(bmap
);
9959 if (univ
< 0 || univ
)
9961 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
9963 return isl_bool_error
;
9965 return isl_bool_false
;
9966 univ
= isl_bool_true
;
9967 if (isl_basic_map_foreach_constraint(bmap
, &involves_divs
, &univ
) < 0 &&
9969 return isl_bool_error
;
9970 if (univ
< 0 || !univ
)
9972 test
= isl_basic_map_universe(isl_basic_map_get_space(bmap
));
9973 univ
= isl_basic_map_is_subset(test
, bmap
);
9974 isl_basic_map_free(test
);
9978 /* Is "bset" equal to the universe with the same space?
9980 isl_bool
isl_basic_set_is_universe(__isl_keep isl_basic_set
*bset
)
9982 return isl_basic_map_is_universe(bset
);
9985 isl_bool
isl_map_plain_is_universe(__isl_keep isl_map
*map
)
9990 return isl_bool_error
;
9992 for (i
= 0; i
< map
->n
; ++i
) {
9993 isl_bool r
= isl_basic_map_plain_is_universe(map
->p
[i
]);
9998 return isl_bool_false
;
10001 isl_bool
isl_set_plain_is_universe(__isl_keep isl_set
*set
)
10003 return isl_map_plain_is_universe(set_to_map(set
));
10006 isl_bool
isl_basic_map_is_empty(__isl_keep isl_basic_map
*bmap
)
10008 struct isl_basic_set
*bset
= NULL
;
10009 struct isl_vec
*sample
= NULL
;
10010 isl_bool empty
, non_empty
;
10013 return isl_bool_error
;
10015 if (ISL_F_ISSET(bmap
, ISL_BASIC_MAP_EMPTY
))
10016 return isl_bool_true
;
10018 if (isl_basic_map_plain_is_universe(bmap
))
10019 return isl_bool_false
;
10021 if (ISL_F_ISSET(bmap
, ISL_BASIC_MAP_RATIONAL
)) {
10022 struct isl_basic_map
*copy
= isl_basic_map_copy(bmap
);
10023 copy
= isl_basic_map_remove_redundancies(copy
);
10024 empty
= isl_basic_map_plain_is_empty(copy
);
10025 isl_basic_map_free(copy
);
10029 non_empty
= isl_basic_map_plain_is_non_empty(bmap
);
10031 return isl_bool_error
;
10033 return isl_bool_false
;
10034 isl_vec_free(bmap
->sample
);
10035 bmap
->sample
= NULL
;
10036 bset
= isl_basic_map_underlying_set(isl_basic_map_copy(bmap
));
10038 return isl_bool_error
;
10039 sample
= isl_basic_set_sample_vec(bset
);
10041 return isl_bool_error
;
10042 empty
= sample
->size
== 0;
10043 isl_vec_free(bmap
->sample
);
10044 bmap
->sample
= sample
;
10046 ISL_F_SET(bmap
, ISL_BASIC_MAP_EMPTY
);
10051 isl_bool
isl_basic_map_plain_is_empty(__isl_keep isl_basic_map
*bmap
)
10054 return isl_bool_error
;
10055 return ISL_F_ISSET(bmap
, ISL_BASIC_MAP_EMPTY
);
10058 isl_bool
isl_basic_set_plain_is_empty(__isl_keep isl_basic_set
*bset
)
10061 return isl_bool_error
;
10062 return ISL_F_ISSET(bset
, ISL_BASIC_SET_EMPTY
);
10065 /* Is "bmap" known to be non-empty?
10067 * That is, is the cached sample still valid?
10069 isl_bool
isl_basic_map_plain_is_non_empty(__isl_keep isl_basic_map
*bmap
)
10074 return isl_bool_error
;
10076 return isl_bool_false
;
10077 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
10079 return isl_bool_error
;
10080 if (bmap
->sample
->size
!= 1 + total
)
10081 return isl_bool_false
;
10082 return isl_basic_map_contains(bmap
, bmap
->sample
);
10085 isl_bool
isl_basic_set_is_empty(__isl_keep isl_basic_set
*bset
)
10087 return isl_basic_map_is_empty(bset_to_bmap(bset
));
10090 __isl_give isl_map
*isl_basic_map_union(__isl_take isl_basic_map
*bmap1
,
10091 __isl_take isl_basic_map
*bmap2
)
10093 struct isl_map
*map
;
10095 if (isl_basic_map_check_equal_space(bmap1
, bmap2
) < 0)
10098 map
= isl_map_alloc_space(isl_space_copy(bmap1
->dim
), 2, 0);
10101 map
= isl_map_add_basic_map(map
, bmap1
);
10102 map
= isl_map_add_basic_map(map
, bmap2
);
10105 isl_basic_map_free(bmap1
);
10106 isl_basic_map_free(bmap2
);
10110 __isl_give isl_set
*isl_basic_set_union(__isl_take isl_basic_set
*bset1
,
10111 __isl_take isl_basic_set
*bset2
)
10113 return set_from_map(isl_basic_map_union(bset_to_bmap(bset1
),
10114 bset_to_bmap(bset2
)));
10117 /* Order divs such that any div only depends on previous divs */
10118 __isl_give isl_basic_map
*isl_basic_map_order_divs(
10119 __isl_take isl_basic_map
*bmap
)
10124 off
= isl_basic_map_var_offset(bmap
, isl_dim_div
);
10126 return isl_basic_map_free(bmap
);
10128 for (i
= 0; i
< bmap
->n_div
; ++i
) {
10130 if (isl_int_is_zero(bmap
->div
[i
][0]))
10132 pos
= isl_seq_first_non_zero(bmap
->div
[i
]+1+1+off
+i
,
10137 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_internal
,
10138 "integer division depends on itself",
10139 return isl_basic_map_free(bmap
));
10140 bmap
= isl_basic_map_swap_div(bmap
, i
, i
+ pos
);
10148 __isl_give isl_map
*isl_map_order_divs(__isl_take isl_map
*map
)
10155 for (i
= 0; i
< map
->n
; ++i
) {
10156 map
->p
[i
] = isl_basic_map_order_divs(map
->p
[i
]);
10167 /* Sort the local variables of "bset".
10169 __isl_give isl_basic_set
*isl_basic_set_sort_divs(
10170 __isl_take isl_basic_set
*bset
)
10172 return bset_from_bmap(isl_basic_map_sort_divs(bset_to_bmap(bset
)));
10175 /* Apply the expansion computed by isl_merge_divs.
10176 * The expansion itself is given by "exp" while the resulting
10177 * list of divs is given by "div".
10179 * Move the integer divisions of "bmap" into the right position
10180 * according to "exp" and then introduce the additional integer
10181 * divisions, adding div constraints.
10182 * The moving should be done first to avoid moving coefficients
10183 * in the definitions of the extra integer divisions.
10185 __isl_give isl_basic_map
*isl_basic_map_expand_divs(
10186 __isl_take isl_basic_map
*bmap
, __isl_take isl_mat
*div
, int *exp
)
10191 bmap
= isl_basic_map_cow(bmap
);
10195 if (div
->n_row
< bmap
->n_div
)
10196 isl_die(isl_mat_get_ctx(div
), isl_error_invalid
,
10197 "not an expansion", goto error
);
10199 n_div
= bmap
->n_div
;
10200 bmap
= isl_basic_map_extend(bmap
, div
->n_row
- n_div
, 0,
10201 2 * (div
->n_row
- n_div
));
10203 for (i
= n_div
; i
< div
->n_row
; ++i
)
10204 if (isl_basic_map_alloc_div(bmap
) < 0)
10207 for (j
= n_div
- 1; j
>= 0; --j
) {
10210 bmap
= isl_basic_map_swap_div(bmap
, j
, exp
[j
]);
10215 for (i
= 0; i
< div
->n_row
; ++i
) {
10216 if (j
< n_div
&& exp
[j
] == i
) {
10219 isl_seq_cpy(bmap
->div
[i
], div
->row
[i
], div
->n_col
);
10220 if (isl_basic_map_div_is_marked_unknown(bmap
, i
))
10222 bmap
= isl_basic_map_add_div_constraints(bmap
, i
);
10231 isl_basic_map_free(bmap
);
10236 /* Apply the expansion computed by isl_merge_divs.
10237 * The expansion itself is given by "exp" while the resulting
10238 * list of divs is given by "div".
10240 __isl_give isl_basic_set
*isl_basic_set_expand_divs(
10241 __isl_take isl_basic_set
*bset
, __isl_take isl_mat
*div
, int *exp
)
10243 return isl_basic_map_expand_divs(bset
, div
, exp
);
10246 /* Look for a div in dst that corresponds to the div "div" in src.
10247 * The divs before "div" in src and dst are assumed to be the same.
10249 * Return the position of the corresponding div in dst
10250 * if there is one. Otherwise, return a position beyond the integer divisions.
10251 * Return -1 on error.
10253 static int find_div(__isl_keep isl_basic_map
*dst
,
10254 __isl_keep isl_basic_map
*src
, unsigned div
)
10260 v_div
= isl_basic_map_var_offset(src
, isl_dim_div
);
10261 n_div
= isl_basic_map_dim(dst
, isl_dim_div
);
10262 if (n_div
< 0 || v_div
< 0)
10264 isl_assert(dst
->ctx
, div
<= n_div
, return -1);
10265 for (i
= div
; i
< n_div
; ++i
)
10266 if (isl_seq_eq(dst
->div
[i
], src
->div
[div
], 1+1+v_div
+div
) &&
10267 isl_seq_first_non_zero(dst
->div
[i
] + 1 + 1 + v_div
+ div
,
10268 n_div
- div
) == -1)
10273 /* Align the divs of "dst" to those of "src", adding divs from "src"
10274 * if needed. That is, make sure that the first src->n_div divs
10275 * of the result are equal to those of src.
10276 * The integer division of "src" are assumed to be ordered.
10278 * The integer divisions are swapped into the right position
10279 * (possibly after adding them first). This may result
10280 * in the remaining integer divisions appearing in the wrong order,
10281 * i.e., with some integer division appearing before
10282 * some other integer division on which it depends.
10283 * The integer divisions therefore need to be ordered.
10284 * This will not affect the integer divisions aligned to those of "src",
10285 * since "src" is assumed to have ordered integer divisions.
10287 * The result is not finalized as by design it will have redundant
10288 * divs if any divs from "src" were copied.
10290 __isl_give isl_basic_map
*isl_basic_map_align_divs(
10291 __isl_take isl_basic_map
*dst
, __isl_keep isl_basic_map
*src
)
10297 isl_size dst_n_div
;
10300 return isl_basic_map_free(dst
);
10302 if (src
->n_div
== 0)
10305 known
= isl_basic_map_divs_known(src
);
10307 return isl_basic_map_free(dst
);
10309 isl_die(isl_basic_map_get_ctx(src
), isl_error_invalid
,
10310 "some src divs are unknown",
10311 return isl_basic_map_free(dst
));
10313 v_div
= isl_basic_map_var_offset(src
, isl_dim_div
);
10315 return isl_basic_map_free(dst
);
10318 dst_n_div
= isl_basic_map_dim(dst
, isl_dim_div
);
10320 dst
= isl_basic_map_free(dst
);
10321 for (i
= 0; i
< src
->n_div
; ++i
) {
10322 int j
= find_div(dst
, src
, i
);
10324 dst
= isl_basic_map_free(dst
);
10325 if (j
== dst_n_div
) {
10327 int extra
= src
->n_div
- i
;
10328 dst
= isl_basic_map_cow(dst
);
10330 return isl_basic_map_free(dst
);
10331 dst
= isl_basic_map_extend(dst
,
10332 extra
, 0, 2 * extra
);
10335 j
= isl_basic_map_alloc_div(dst
);
10337 return isl_basic_map_free(dst
);
10338 isl_seq_cpy(dst
->div
[j
], src
->div
[i
], 1+1+v_div
+i
);
10339 isl_seq_clr(dst
->div
[j
]+1+1+v_div
+i
, dst
->n_div
- i
);
10341 dst
= isl_basic_map_add_div_constraints(dst
, j
);
10343 return isl_basic_map_free(dst
);
10346 dst
= isl_basic_map_swap_div(dst
, i
, j
);
10348 return isl_basic_map_free(dst
);
10350 return isl_basic_map_order_divs(dst
);
10353 __isl_give isl_map
*isl_map_align_divs_internal(__isl_take isl_map
*map
)
10361 map
= isl_map_compute_divs(map
);
10362 map
= isl_map_order_divs(map
);
10363 map
= isl_map_cow(map
);
10367 for (i
= 1; i
< map
->n
; ++i
)
10368 map
->p
[0] = isl_basic_map_align_divs(map
->p
[0], map
->p
[i
]);
10369 for (i
= 1; i
< map
->n
; ++i
) {
10370 map
->p
[i
] = isl_basic_map_align_divs(map
->p
[i
], map
->p
[0]);
10372 return isl_map_free(map
);
10375 map
= isl_map_unmark_normalized(map
);
10379 __isl_give isl_map
*isl_map_align_divs(__isl_take isl_map
*map
)
10381 return isl_map_align_divs_internal(map
);
10384 __isl_give isl_set
*isl_set_align_divs(__isl_take isl_set
*set
)
10386 return set_from_map(isl_map_align_divs_internal(set_to_map(set
)));
10389 /* Align the divs of the basic maps in "map" to those
10390 * of the basic maps in "list", as well as to the other basic maps in "map".
10391 * The elements in "list" are assumed to have known divs.
10393 __isl_give isl_map
*isl_map_align_divs_to_basic_map_list(
10394 __isl_take isl_map
*map
, __isl_keep isl_basic_map_list
*list
)
10399 n
= isl_basic_map_list_n_basic_map(list
);
10400 map
= isl_map_compute_divs(map
);
10401 map
= isl_map_cow(map
);
10403 return isl_map_free(map
);
10407 for (i
= 0; i
< n
; ++i
) {
10408 isl_basic_map
*bmap
;
10410 bmap
= isl_basic_map_list_get_basic_map(list
, i
);
10411 bmap
= isl_basic_map_order_divs(bmap
);
10412 map
->p
[0] = isl_basic_map_align_divs(map
->p
[0], bmap
);
10413 isl_basic_map_free(bmap
);
10416 return isl_map_free(map
);
10418 return isl_map_align_divs_internal(map
);
10421 /* Align the divs of each element of "list" to those of "bmap".
10422 * Both "bmap" and the elements of "list" are assumed to have known divs.
10424 __isl_give isl_basic_map_list
*isl_basic_map_list_align_divs_to_basic_map(
10425 __isl_take isl_basic_map_list
*list
, __isl_keep isl_basic_map
*bmap
)
10430 n
= isl_basic_map_list_n_basic_map(list
);
10431 if (n
< 0 || !bmap
)
10432 return isl_basic_map_list_free(list
);
10434 for (i
= 0; i
< n
; ++i
) {
10435 isl_basic_map
*bmap_i
;
10437 bmap_i
= isl_basic_map_list_get_basic_map(list
, i
);
10438 bmap_i
= isl_basic_map_align_divs(bmap_i
, bmap
);
10439 list
= isl_basic_map_list_set_basic_map(list
, i
, bmap_i
);
10445 __isl_give isl_set
*isl_set_apply( __isl_take isl_set
*set
,
10446 __isl_take isl_map
*map
)
10450 isl_map_align_params_set(&map
, &set
);
10451 ok
= isl_map_compatible_domain(map
, set
);
10455 isl_die(isl_set_get_ctx(set
), isl_error_invalid
,
10456 "incompatible spaces", goto error
);
10457 map
= isl_map_intersect_domain(map
, set
);
10458 set
= isl_map_range(map
);
10466 /* There is no need to cow as removing empty parts doesn't change
10467 * the meaning of the set.
10469 __isl_give isl_map
*isl_map_remove_empty_parts(__isl_take isl_map
*map
)
10476 for (i
= map
->n
- 1; i
>= 0; --i
)
10477 map
= remove_if_empty(map
, i
);
10482 __isl_give isl_set
*isl_set_remove_empty_parts(__isl_take isl_set
*set
)
10484 return set_from_map(isl_map_remove_empty_parts(set_to_map(set
)));
10487 /* Create a binary relation that maps the shared initial "pos" dimensions
10488 * of "bset1" and "bset2" to the remaining dimensions of "bset1" and "bset2".
10490 static __isl_give isl_basic_map
*join_initial(__isl_keep isl_basic_set
*bset1
,
10491 __isl_keep isl_basic_set
*bset2
, int pos
)
10493 isl_basic_map
*bmap1
;
10494 isl_basic_map
*bmap2
;
10496 bmap1
= isl_basic_map_from_range(isl_basic_set_copy(bset1
));
10497 bmap2
= isl_basic_map_from_range(isl_basic_set_copy(bset2
));
10498 bmap1
= isl_basic_map_move_dims(bmap1
, isl_dim_in
, 0,
10499 isl_dim_out
, 0, pos
);
10500 bmap2
= isl_basic_map_move_dims(bmap2
, isl_dim_in
, 0,
10501 isl_dim_out
, 0, pos
);
10502 return isl_basic_map_range_product(bmap1
, bmap2
);
10505 /* Given two basic sets bset1 and bset2, compute the maximal difference
10506 * between the values of dimension pos in bset1 and those in bset2
10507 * for any common value of the parameters and dimensions preceding pos.
10509 static enum isl_lp_result
basic_set_maximal_difference_at(
10510 __isl_keep isl_basic_set
*bset1
, __isl_keep isl_basic_set
*bset2
,
10511 int pos
, isl_int
*opt
)
10513 isl_basic_map
*bmap1
;
10514 struct isl_ctx
*ctx
;
10515 struct isl_vec
*obj
;
10519 enum isl_lp_result res
;
10521 nparam
= isl_basic_set_dim(bset1
, isl_dim_param
);
10522 dim1
= isl_basic_set_dim(bset1
, isl_dim_set
);
10523 if (nparam
< 0 || dim1
< 0 || !bset2
)
10524 return isl_lp_error
;
10526 bmap1
= join_initial(bset1
, bset2
, pos
);
10527 total
= isl_basic_map_dim(bmap1
, isl_dim_all
);
10529 return isl_lp_error
;
10532 obj
= isl_vec_alloc(ctx
, 1 + total
);
10535 isl_seq_clr(obj
->block
.data
, 1 + total
);
10536 isl_int_set_si(obj
->block
.data
[1+nparam
+pos
], 1);
10537 isl_int_set_si(obj
->block
.data
[1+nparam
+pos
+(dim1
-pos
)], -1);
10538 res
= isl_basic_map_solve_lp(bmap1
, 1, obj
->block
.data
, ctx
->one
,
10540 isl_basic_map_free(bmap1
);
10544 isl_basic_map_free(bmap1
);
10545 return isl_lp_error
;
10548 /* Given two _disjoint_ basic sets bset1 and bset2, check whether
10549 * for any common value of the parameters and dimensions preceding pos
10550 * in both basic sets, the values of dimension pos in bset1 are
10551 * smaller or larger than those in bset2.
10554 * 1 if bset1 follows bset2
10555 * -1 if bset1 precedes bset2
10556 * 0 if bset1 and bset2 are incomparable
10557 * -2 if some error occurred.
10559 int isl_basic_set_compare_at(__isl_keep isl_basic_set
*bset1
,
10560 __isl_keep isl_basic_set
*bset2
, int pos
)
10563 enum isl_lp_result res
;
10568 res
= basic_set_maximal_difference_at(bset1
, bset2
, pos
, &opt
);
10570 if (res
== isl_lp_empty
)
10572 else if ((res
== isl_lp_ok
&& isl_int_is_pos(opt
)) ||
10573 res
== isl_lp_unbounded
)
10575 else if (res
== isl_lp_ok
&& isl_int_is_neg(opt
))
10580 isl_int_clear(opt
);
10584 /* Given two basic sets bset1 and bset2, check whether
10585 * for any common value of the parameters and dimensions preceding pos
10586 * there is a value of dimension pos in bset1 that is larger
10587 * than a value of the same dimension in bset2.
10590 * 1 if there exists such a pair
10591 * 0 if there is no such pair, but there is a pair of equal values
10593 * -2 if some error occurred.
10595 int isl_basic_set_follows_at(__isl_keep isl_basic_set
*bset1
,
10596 __isl_keep isl_basic_set
*bset2
, int pos
)
10599 isl_basic_map
*bmap
;
10602 dim1
= isl_basic_set_dim(bset1
, isl_dim_set
);
10605 bmap
= join_initial(bset1
, bset2
, pos
);
10606 bmap
= isl_basic_map_order_ge(bmap
, isl_dim_out
, 0,
10607 isl_dim_out
, dim1
- pos
);
10608 empty
= isl_basic_map_is_empty(bmap
);
10612 isl_basic_map_free(bmap
);
10615 bmap
= isl_basic_map_order_gt(bmap
, isl_dim_out
, 0,
10616 isl_dim_out
, dim1
- pos
);
10617 empty
= isl_basic_map_is_empty(bmap
);
10620 isl_basic_map_free(bmap
);
10625 isl_basic_map_free(bmap
);
10629 /* Given two sets set1 and set2, check whether
10630 * for any common value of the parameters and dimensions preceding pos
10631 * there is a value of dimension pos in set1 that is larger
10632 * than a value of the same dimension in set2.
10635 * 1 if there exists such a pair
10636 * 0 if there is no such pair, but there is a pair of equal values
10638 * -2 if some error occurred.
10640 int isl_set_follows_at(__isl_keep isl_set
*set1
,
10641 __isl_keep isl_set
*set2
, int pos
)
10646 if (!set1
|| !set2
)
10649 for (i
= 0; i
< set1
->n
; ++i
)
10650 for (j
= 0; j
< set2
->n
; ++j
) {
10652 f
= isl_basic_set_follows_at(set1
->p
[i
], set2
->p
[j
], pos
);
10653 if (f
== 1 || f
== -2)
10662 static isl_bool
isl_basic_map_plain_has_fixed_var(
10663 __isl_keep isl_basic_map
*bmap
, unsigned pos
, isl_int
*val
)
10669 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
10671 return isl_bool_error
;
10672 for (i
= 0, d
= total
-1; i
< bmap
->n_eq
&& d
+1 > pos
; ++i
) {
10673 for (; d
+1 > pos
; --d
)
10674 if (!isl_int_is_zero(bmap
->eq
[i
][1+d
]))
10678 if (isl_seq_first_non_zero(bmap
->eq
[i
]+1, d
) != -1)
10679 return isl_bool_false
;
10680 if (isl_seq_first_non_zero(bmap
->eq
[i
]+1+d
+1, total
-d
-1) != -1)
10681 return isl_bool_false
;
10682 if (!isl_int_is_one(bmap
->eq
[i
][1+d
]))
10683 return isl_bool_false
;
10685 isl_int_neg(*val
, bmap
->eq
[i
][0]);
10686 return isl_bool_true
;
10688 return isl_bool_false
;
10691 static isl_bool
isl_map_plain_has_fixed_var(__isl_keep isl_map
*map
,
10692 unsigned pos
, isl_int
*val
)
10700 return isl_bool_error
;
10702 return isl_bool_false
;
10704 return isl_basic_map_plain_has_fixed_var(map
->p
[0], pos
, val
);
10707 fixed
= isl_basic_map_plain_has_fixed_var(map
->p
[0], pos
, &v
);
10708 for (i
= 1; fixed
== isl_bool_true
&& i
< map
->n
; ++i
) {
10709 fixed
= isl_basic_map_plain_has_fixed_var(map
->p
[i
], pos
, &tmp
);
10710 if (fixed
== isl_bool_true
&& isl_int_ne(tmp
, v
))
10711 fixed
= isl_bool_false
;
10714 isl_int_set(*val
, v
);
10715 isl_int_clear(tmp
);
10720 static isl_bool
isl_basic_set_plain_has_fixed_var(
10721 __isl_keep isl_basic_set
*bset
, unsigned pos
, isl_int
*val
)
10723 return isl_basic_map_plain_has_fixed_var(bset_to_bmap(bset
),
10727 isl_bool
isl_basic_map_plain_is_fixed(__isl_keep isl_basic_map
*bmap
,
10728 enum isl_dim_type type
, unsigned pos
, isl_int
*val
)
10730 if (isl_basic_map_check_range(bmap
, type
, pos
, 1) < 0)
10731 return isl_bool_error
;
10732 return isl_basic_map_plain_has_fixed_var(bmap
,
10733 isl_basic_map_offset(bmap
, type
) - 1 + pos
, val
);
10736 /* If "bmap" obviously lies on a hyperplane where the given dimension
10737 * has a fixed value, then return that value.
10738 * Otherwise return NaN.
10740 __isl_give isl_val
*isl_basic_map_plain_get_val_if_fixed(
10741 __isl_keep isl_basic_map
*bmap
,
10742 enum isl_dim_type type
, unsigned pos
)
10750 ctx
= isl_basic_map_get_ctx(bmap
);
10751 v
= isl_val_alloc(ctx
);
10754 fixed
= isl_basic_map_plain_is_fixed(bmap
, type
, pos
, &v
->n
);
10756 return isl_val_free(v
);
10758 isl_int_set_si(v
->d
, 1);
10762 return isl_val_nan(ctx
);
10765 isl_bool
isl_map_plain_is_fixed(__isl_keep isl_map
*map
,
10766 enum isl_dim_type type
, unsigned pos
, isl_int
*val
)
10768 if (isl_map_check_range(map
, type
, pos
, 1) < 0)
10769 return isl_bool_error
;
10770 return isl_map_plain_has_fixed_var(map
,
10771 map_offset(map
, type
) - 1 + pos
, val
);
10774 /* If "map" obviously lies on a hyperplane where the given dimension
10775 * has a fixed value, then return that value.
10776 * Otherwise return NaN.
10778 __isl_give isl_val
*isl_map_plain_get_val_if_fixed(__isl_keep isl_map
*map
,
10779 enum isl_dim_type type
, unsigned pos
)
10787 ctx
= isl_map_get_ctx(map
);
10788 v
= isl_val_alloc(ctx
);
10791 fixed
= isl_map_plain_is_fixed(map
, type
, pos
, &v
->n
);
10793 return isl_val_free(v
);
10795 isl_int_set_si(v
->d
, 1);
10799 return isl_val_nan(ctx
);
10802 /* If "set" obviously lies on a hyperplane where the given dimension
10803 * has a fixed value, then return that value.
10804 * Otherwise return NaN.
10806 __isl_give isl_val
*isl_set_plain_get_val_if_fixed(__isl_keep isl_set
*set
,
10807 enum isl_dim_type type
, unsigned pos
)
10809 return isl_map_plain_get_val_if_fixed(set
, type
, pos
);
10812 /* Return a sequence of values in the same space as "set"
10813 * that are equal to the corresponding set dimensions of "set"
10814 * for those set dimensions that obviously lie on a hyperplane
10815 * where the dimension has a fixed value.
10816 * The other elements are set to NaN.
10818 __isl_give isl_multi_val
*isl_set_get_plain_multi_val_if_fixed(
10819 __isl_keep isl_set
*set
)
10826 space
= isl_space_drop_all_params(isl_set_get_space(set
));
10827 mv
= isl_multi_val_alloc(space
);
10828 n
= isl_multi_val_size(mv
);
10830 return isl_multi_val_free(mv
);
10832 for (i
= 0; i
< n
; ++i
) {
10835 v
= isl_set_plain_get_val_if_fixed(set
, isl_dim_set
, i
);
10836 mv
= isl_multi_val_set_val(mv
, i
, v
);
10842 /* Check if dimension dim has fixed value and if so and if val is not NULL,
10843 * then return this fixed value in *val.
10845 isl_bool
isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_set
*bset
,
10846 unsigned dim
, isl_int
*val
)
10850 nparam
= isl_basic_set_dim(bset
, isl_dim_param
);
10852 return isl_bool_error
;
10853 return isl_basic_set_plain_has_fixed_var(bset
, nparam
+ dim
, val
);
10856 /* Return -1 if the constraint "c1" should be sorted before "c2"
10857 * and 1 if it should be sorted after "c2".
10858 * Return 0 if the two constraints are the same (up to the constant term).
10860 * In particular, if a constraint involves later variables than another
10861 * then it is sorted after this other constraint.
10862 * uset_gist depends on constraints without existentially quantified
10863 * variables sorting first.
10865 * For constraints that have the same latest variable, those
10866 * with the same coefficient for this latest variable (first in absolute value
10867 * and then in actual value) are grouped together.
10868 * This is useful for detecting pairs of constraints that can
10869 * be chained in their printed representation.
10871 * Finally, within a group, constraints are sorted according to
10872 * their coefficients (excluding the constant term).
10874 static int sort_constraint_cmp(const void *p1
, const void *p2
, void *arg
)
10876 isl_int
**c1
= (isl_int
**) p1
;
10877 isl_int
**c2
= (isl_int
**) p2
;
10879 unsigned size
= *(unsigned *) arg
;
10882 l1
= isl_seq_last_non_zero(*c1
+ 1, size
);
10883 l2
= isl_seq_last_non_zero(*c2
+ 1, size
);
10888 cmp
= isl_int_abs_cmp((*c1
)[1 + l1
], (*c2
)[1 + l1
]);
10891 cmp
= isl_int_cmp((*c1
)[1 + l1
], (*c2
)[1 + l1
]);
10895 return isl_seq_cmp(*c1
+ 1, *c2
+ 1, size
);
10898 /* Return -1 if the constraint "c1" of "bmap" is sorted before "c2"
10899 * by isl_basic_map_sort_constraints, 1 if it is sorted after "c2"
10900 * and 0 if the two constraints are the same (up to the constant term).
10902 int isl_basic_map_constraint_cmp(__isl_keep isl_basic_map
*bmap
,
10903 isl_int
*c1
, isl_int
*c2
)
10908 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
10912 return sort_constraint_cmp(&c1
, &c2
, &size
);
10915 __isl_give isl_basic_map
*isl_basic_map_sort_constraints(
10916 __isl_take isl_basic_map
*bmap
)
10923 if (bmap
->n_ineq
== 0)
10925 if (ISL_F_ISSET(bmap
, ISL_BASIC_MAP_SORTED
))
10927 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
10929 return isl_basic_map_free(bmap
);
10931 if (isl_sort(bmap
->ineq
, bmap
->n_ineq
, sizeof(isl_int
*),
10932 &sort_constraint_cmp
, &size
) < 0)
10933 return isl_basic_map_free(bmap
);
10934 ISL_F_SET(bmap
, ISL_BASIC_MAP_SORTED
);
10938 __isl_give isl_basic_set
*isl_basic_set_sort_constraints(
10939 __isl_take isl_basic_set
*bset
)
10941 isl_basic_map
*bmap
= bset_to_bmap(bset
);
10942 return bset_from_bmap(isl_basic_map_sort_constraints(bmap
));
10945 __isl_give isl_basic_map
*isl_basic_map_normalize(
10946 __isl_take isl_basic_map
*bmap
)
10948 bmap
= isl_basic_map_remove_redundancies(bmap
);
10949 bmap
= isl_basic_map_sort_constraints(bmap
);
10952 int isl_basic_map_plain_cmp(__isl_keep isl_basic_map
*bmap1
,
10953 __isl_keep isl_basic_map
*bmap2
)
10957 isl_space
*space1
, *space2
;
10959 if (!bmap1
|| !bmap2
)
10962 if (bmap1
== bmap2
)
10964 space1
= isl_basic_map_peek_space(bmap1
);
10965 space2
= isl_basic_map_peek_space(bmap2
);
10966 cmp
= isl_space_cmp(space1
, space2
);
10969 if (ISL_F_ISSET(bmap1
, ISL_BASIC_MAP_RATIONAL
) !=
10970 ISL_F_ISSET(bmap2
, ISL_BASIC_MAP_RATIONAL
))
10971 return ISL_F_ISSET(bmap1
, ISL_BASIC_MAP_RATIONAL
) ? -1 : 1;
10972 if (ISL_F_ISSET(bmap1
, ISL_BASIC_MAP_EMPTY
) &&
10973 ISL_F_ISSET(bmap2
, ISL_BASIC_MAP_EMPTY
))
10975 if (ISL_F_ISSET(bmap1
, ISL_BASIC_MAP_EMPTY
))
10977 if (ISL_F_ISSET(bmap2
, ISL_BASIC_MAP_EMPTY
))
10979 if (bmap1
->n_eq
!= bmap2
->n_eq
)
10980 return bmap1
->n_eq
- bmap2
->n_eq
;
10981 if (bmap1
->n_ineq
!= bmap2
->n_ineq
)
10982 return bmap1
->n_ineq
- bmap2
->n_ineq
;
10983 if (bmap1
->n_div
!= bmap2
->n_div
)
10984 return bmap1
->n_div
- bmap2
->n_div
;
10985 total
= isl_basic_map_dim(bmap1
, isl_dim_all
);
10988 for (i
= 0; i
< bmap1
->n_eq
; ++i
) {
10989 cmp
= isl_seq_cmp(bmap1
->eq
[i
], bmap2
->eq
[i
], 1+total
);
10993 for (i
= 0; i
< bmap1
->n_ineq
; ++i
) {
10994 cmp
= isl_seq_cmp(bmap1
->ineq
[i
], bmap2
->ineq
[i
], 1+total
);
10998 for (i
= 0; i
< bmap1
->n_div
; ++i
) {
10999 isl_bool unknown1
, unknown2
;
11001 unknown1
= isl_basic_map_div_is_marked_unknown(bmap1
, i
);
11002 unknown2
= isl_basic_map_div_is_marked_unknown(bmap2
, i
);
11003 if (unknown1
< 0 || unknown2
< 0)
11005 if (unknown1
&& unknown2
)
11011 cmp
= isl_seq_cmp(bmap1
->div
[i
], bmap2
->div
[i
], 1+1+total
);
11018 int isl_basic_set_plain_cmp(__isl_keep isl_basic_set
*bset1
,
11019 __isl_keep isl_basic_set
*bset2
)
11021 return isl_basic_map_plain_cmp(bset1
, bset2
);
11024 int isl_set_plain_cmp(__isl_keep isl_set
*set1
, __isl_keep isl_set
*set2
)
11030 if (set1
->n
!= set2
->n
)
11031 return set1
->n
- set2
->n
;
11033 for (i
= 0; i
< set1
->n
; ++i
) {
11034 cmp
= isl_basic_set_plain_cmp(set1
->p
[i
], set2
->p
[i
]);
11042 isl_bool
isl_basic_map_plain_is_equal(__isl_keep isl_basic_map
*bmap1
,
11043 __isl_keep isl_basic_map
*bmap2
)
11045 if (!bmap1
|| !bmap2
)
11046 return isl_bool_error
;
11047 return isl_basic_map_plain_cmp(bmap1
, bmap2
) == 0;
11050 isl_bool
isl_basic_set_plain_is_equal(__isl_keep isl_basic_set
*bset1
,
11051 __isl_keep isl_basic_set
*bset2
)
11053 return isl_basic_map_plain_is_equal(bset_to_bmap(bset1
),
11054 bset_to_bmap(bset2
));
11057 static int qsort_bmap_cmp(const void *p1
, const void *p2
)
11059 isl_basic_map
*bmap1
= *(isl_basic_map
**) p1
;
11060 isl_basic_map
*bmap2
= *(isl_basic_map
**) p2
;
11062 return isl_basic_map_plain_cmp(bmap1
, bmap2
);
11065 /* Sort the basic maps of "map" and remove duplicate basic maps.
11067 * While removing basic maps, we make sure that the basic maps remain
11068 * sorted because isl_map_normalize expects the basic maps of the result
11071 static __isl_give isl_map
*sort_and_remove_duplicates(__isl_take isl_map
*map
)
11075 map
= isl_map_remove_empty_parts(map
);
11078 qsort(map
->p
, map
->n
, sizeof(struct isl_basic_map
*), qsort_bmap_cmp
);
11079 for (i
= map
->n
- 1; i
>= 1; --i
) {
11080 if (!isl_basic_map_plain_is_equal(map
->p
[i
- 1], map
->p
[i
]))
11082 isl_basic_map_free(map
->p
[i
-1]);
11083 for (j
= i
; j
< map
->n
; ++j
)
11084 map
->p
[j
- 1] = map
->p
[j
];
11091 /* Remove obvious duplicates among the basic maps of "map".
11093 * Unlike isl_map_normalize, this function does not remove redundant
11094 * constraints and only removes duplicates that have exactly the same
11095 * constraints in the input. It does sort the constraints and
11096 * the basic maps to ease the detection of duplicates.
11098 * If "map" has already been normalized or if the basic maps are
11099 * disjoint, then there can be no duplicates.
11101 __isl_give isl_map
*isl_map_remove_obvious_duplicates(__isl_take isl_map
*map
)
11104 isl_basic_map
*bmap
;
11110 if (ISL_F_ISSET(map
, ISL_MAP_NORMALIZED
| ISL_MAP_DISJOINT
))
11112 for (i
= 0; i
< map
->n
; ++i
) {
11113 bmap
= isl_basic_map_copy(map
->p
[i
]);
11114 bmap
= isl_basic_map_sort_constraints(bmap
);
11116 return isl_map_free(map
);
11117 isl_basic_map_free(map
->p
[i
]);
11121 map
= sort_and_remove_duplicates(map
);
11125 /* We normalize in place, but if anything goes wrong we need
11126 * to return NULL, so we need to make sure we don't change the
11127 * meaning of any possible other copies of map.
11129 __isl_give isl_map
*isl_map_normalize(__isl_take isl_map
*map
)
11132 struct isl_basic_map
*bmap
;
11136 if (ISL_F_ISSET(map
, ISL_MAP_NORMALIZED
))
11138 for (i
= 0; i
< map
->n
; ++i
) {
11139 bmap
= isl_basic_map_normalize(isl_basic_map_copy(map
->p
[i
]));
11142 isl_basic_map_free(map
->p
[i
]);
11146 map
= sort_and_remove_duplicates(map
);
11148 ISL_F_SET(map
, ISL_MAP_NORMALIZED
);
11155 __isl_give isl_set
*isl_set_normalize(__isl_take isl_set
*set
)
11157 return set_from_map(isl_map_normalize(set_to_map(set
)));
11160 isl_bool
isl_map_plain_is_equal(__isl_keep isl_map
*map1
,
11161 __isl_keep isl_map
*map2
)
11166 if (!map1
|| !map2
)
11167 return isl_bool_error
;
11170 return isl_bool_true
;
11171 equal
= isl_map_has_equal_space(map1
, map2
);
11172 if (equal
< 0 || !equal
)
11175 map1
= isl_map_copy(map1
);
11176 map2
= isl_map_copy(map2
);
11177 map1
= isl_map_normalize(map1
);
11178 map2
= isl_map_normalize(map2
);
11179 if (!map1
|| !map2
)
11181 equal
= map1
->n
== map2
->n
;
11182 for (i
= 0; equal
&& i
< map1
->n
; ++i
) {
11183 equal
= isl_basic_map_plain_is_equal(map1
->p
[i
], map2
->p
[i
]);
11187 isl_map_free(map1
);
11188 isl_map_free(map2
);
11191 isl_map_free(map1
);
11192 isl_map_free(map2
);
11193 return isl_bool_error
;
11196 isl_bool
isl_set_plain_is_equal(__isl_keep isl_set
*set1
,
11197 __isl_keep isl_set
*set2
)
11199 return isl_map_plain_is_equal(set_to_map(set1
), set_to_map(set2
));
11202 /* Return the basic maps in "map" as a list.
11204 __isl_give isl_basic_map_list
*isl_map_get_basic_map_list(
11205 __isl_keep isl_map
*map
)
11209 isl_basic_map_list
*list
;
11213 ctx
= isl_map_get_ctx(map
);
11214 list
= isl_basic_map_list_alloc(ctx
, map
->n
);
11216 for (i
= 0; i
< map
->n
; ++i
) {
11217 isl_basic_map
*bmap
;
11219 bmap
= isl_basic_map_copy(map
->p
[i
]);
11220 list
= isl_basic_map_list_add(list
, bmap
);
11226 /* Return the intersection of the elements in the non-empty list "list".
11227 * All elements are assumed to live in the same space.
11229 __isl_give isl_basic_map
*isl_basic_map_list_intersect(
11230 __isl_take isl_basic_map_list
*list
)
11234 isl_basic_map
*bmap
;
11236 n
= isl_basic_map_list_n_basic_map(list
);
11240 isl_die(isl_basic_map_list_get_ctx(list
), isl_error_invalid
,
11241 "expecting non-empty list", goto error
);
11243 bmap
= isl_basic_map_list_get_basic_map(list
, 0);
11244 for (i
= 1; i
< n
; ++i
) {
11245 isl_basic_map
*bmap_i
;
11247 bmap_i
= isl_basic_map_list_get_basic_map(list
, i
);
11248 bmap
= isl_basic_map_intersect(bmap
, bmap_i
);
11251 isl_basic_map_list_free(list
);
11254 isl_basic_map_list_free(list
);
11258 /* Return the intersection of the elements in the non-empty list "list".
11259 * All elements are assumed to live in the same space.
11261 __isl_give isl_basic_set
*isl_basic_set_list_intersect(
11262 __isl_take isl_basic_set_list
*list
)
11264 return isl_basic_map_list_intersect(list
);
11267 /* Return the union of the elements of "list".
11268 * The list is required to have at least one element.
11270 __isl_give isl_set
*isl_basic_set_list_union(
11271 __isl_take isl_basic_set_list
*list
)
11276 isl_basic_set
*bset
;
11279 n
= isl_basic_set_list_n_basic_set(list
);
11283 isl_die(isl_basic_set_list_get_ctx(list
), isl_error_invalid
,
11284 "expecting non-empty list", goto error
);
11286 bset
= isl_basic_set_list_get_basic_set(list
, 0);
11287 space
= isl_basic_set_get_space(bset
);
11288 isl_basic_set_free(bset
);
11290 set
= isl_set_alloc_space(space
, n
, 0);
11291 for (i
= 0; i
< n
; ++i
) {
11292 bset
= isl_basic_set_list_get_basic_set(list
, i
);
11293 set
= isl_set_add_basic_set(set
, bset
);
11296 isl_basic_set_list_free(list
);
11299 isl_basic_set_list_free(list
);
11303 /* Return the union of the elements in the non-empty list "list".
11304 * All elements are assumed to live in the same space.
11306 __isl_give isl_set
*isl_set_list_union(__isl_take isl_set_list
*list
)
11312 n
= isl_set_list_n_set(list
);
11316 isl_die(isl_set_list_get_ctx(list
), isl_error_invalid
,
11317 "expecting non-empty list", goto error
);
11319 set
= isl_set_list_get_set(list
, 0);
11320 for (i
= 1; i
< n
; ++i
) {
11323 set_i
= isl_set_list_get_set(list
, i
);
11324 set
= isl_set_union(set
, set_i
);
11327 isl_set_list_free(list
);
11330 isl_set_list_free(list
);
11334 __isl_give isl_basic_map
*isl_basic_map_product(
11335 __isl_take isl_basic_map
*bmap1
, __isl_take isl_basic_map
*bmap2
)
11337 isl_space
*space_result
= NULL
;
11338 struct isl_basic_map
*bmap
;
11339 unsigned in1
, in2
, out1
, out2
, nparam
, total
, pos
;
11340 struct isl_dim_map
*dim_map1
, *dim_map2
;
11342 if (isl_basic_map_check_equal_params(bmap1
, bmap2
) < 0)
11344 space_result
= isl_space_product(isl_space_copy(bmap1
->dim
),
11345 isl_space_copy(bmap2
->dim
));
11347 in1
= isl_basic_map_dim(bmap1
, isl_dim_in
);
11348 in2
= isl_basic_map_dim(bmap2
, isl_dim_in
);
11349 out1
= isl_basic_map_dim(bmap1
, isl_dim_out
);
11350 out2
= isl_basic_map_dim(bmap2
, isl_dim_out
);
11351 nparam
= isl_basic_map_dim(bmap1
, isl_dim_param
);
11353 total
= nparam
+ in1
+ in2
+ out1
+ out2
+ bmap1
->n_div
+ bmap2
->n_div
;
11354 dim_map1
= isl_dim_map_alloc(bmap1
->ctx
, total
);
11355 dim_map2
= isl_dim_map_alloc(bmap1
->ctx
, total
);
11356 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_param
, pos
= 0);
11357 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_param
, pos
= 0);
11358 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_in
, pos
+= nparam
);
11359 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_in
, pos
+= in1
);
11360 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_out
, pos
+= in2
);
11361 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_out
, pos
+= out1
);
11362 isl_dim_map_div(dim_map1
, bmap1
, pos
+= out2
);
11363 isl_dim_map_div(dim_map2
, bmap2
, pos
+= bmap1
->n_div
);
11365 bmap
= isl_basic_map_alloc_space(space_result
,
11366 bmap1
->n_div
+ bmap2
->n_div
,
11367 bmap1
->n_eq
+ bmap2
->n_eq
,
11368 bmap1
->n_ineq
+ bmap2
->n_ineq
);
11369 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap1
, dim_map1
);
11370 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap2
, dim_map2
);
11371 bmap
= isl_basic_map_simplify(bmap
);
11372 return isl_basic_map_finalize(bmap
);
11374 isl_basic_map_free(bmap1
);
11375 isl_basic_map_free(bmap2
);
11379 __isl_give isl_basic_map
*isl_basic_map_flat_product(
11380 __isl_take isl_basic_map
*bmap1
, __isl_take isl_basic_map
*bmap2
)
11382 isl_basic_map
*prod
;
11384 prod
= isl_basic_map_product(bmap1
, bmap2
);
11385 prod
= isl_basic_map_flatten(prod
);
11389 __isl_give isl_basic_set
*isl_basic_set_flat_product(
11390 __isl_take isl_basic_set
*bset1
, __isl_take isl_basic_set
*bset2
)
11392 return isl_basic_map_flat_range_product(bset1
, bset2
);
11395 __isl_give isl_basic_map
*isl_basic_map_domain_product(
11396 __isl_take isl_basic_map
*bmap1
, __isl_take isl_basic_map
*bmap2
)
11398 isl_space
*space1
, *space2
;
11399 isl_space
*space_result
= NULL
;
11400 isl_basic_map
*bmap
;
11401 isl_size in1
, in2
, out
, nparam
;
11402 unsigned total
, pos
;
11403 struct isl_dim_map
*dim_map1
, *dim_map2
;
11405 in1
= isl_basic_map_dim(bmap1
, isl_dim_in
);
11406 in2
= isl_basic_map_dim(bmap2
, isl_dim_in
);
11407 out
= isl_basic_map_dim(bmap1
, isl_dim_out
);
11408 nparam
= isl_basic_map_dim(bmap1
, isl_dim_param
);
11409 if (in1
< 0 || in2
< 0 || out
< 0 || nparam
< 0)
11412 space1
= isl_basic_map_get_space(bmap1
);
11413 space2
= isl_basic_map_get_space(bmap2
);
11414 space_result
= isl_space_domain_product(space1
, space2
);
11416 total
= nparam
+ in1
+ in2
+ out
+ bmap1
->n_div
+ bmap2
->n_div
;
11417 dim_map1
= isl_dim_map_alloc(bmap1
->ctx
, total
);
11418 dim_map2
= isl_dim_map_alloc(bmap1
->ctx
, total
);
11419 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_param
, pos
= 0);
11420 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_param
, pos
= 0);
11421 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_in
, pos
+= nparam
);
11422 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_in
, pos
+= in1
);
11423 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_out
, pos
+= in2
);
11424 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_out
, pos
);
11425 isl_dim_map_div(dim_map1
, bmap1
, pos
+= out
);
11426 isl_dim_map_div(dim_map2
, bmap2
, pos
+= bmap1
->n_div
);
11428 bmap
= isl_basic_map_alloc_space(space_result
,
11429 bmap1
->n_div
+ bmap2
->n_div
,
11430 bmap1
->n_eq
+ bmap2
->n_eq
,
11431 bmap1
->n_ineq
+ bmap2
->n_ineq
);
11432 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap1
, dim_map1
);
11433 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap2
, dim_map2
);
11434 bmap
= isl_basic_map_simplify(bmap
);
11435 return isl_basic_map_finalize(bmap
);
11437 isl_basic_map_free(bmap1
);
11438 isl_basic_map_free(bmap2
);
11442 __isl_give isl_basic_map
*isl_basic_map_range_product(
11443 __isl_take isl_basic_map
*bmap1
, __isl_take isl_basic_map
*bmap2
)
11446 isl_space
*space_result
= NULL
;
11447 isl_basic_map
*bmap
;
11448 isl_size in
, out1
, out2
, nparam
;
11449 unsigned total
, pos
;
11450 struct isl_dim_map
*dim_map1
, *dim_map2
;
11452 rational
= isl_basic_map_is_rational(bmap1
);
11453 if (rational
>= 0 && rational
)
11454 rational
= isl_basic_map_is_rational(bmap2
);
11455 in
= isl_basic_map_dim(bmap1
, isl_dim_in
);
11456 out1
= isl_basic_map_dim(bmap1
, isl_dim_out
);
11457 out2
= isl_basic_map_dim(bmap2
, isl_dim_out
);
11458 nparam
= isl_basic_map_dim(bmap1
, isl_dim_param
);
11459 if (in
< 0 || out1
< 0 || out2
< 0 || nparam
< 0 || rational
< 0)
11462 if (isl_basic_map_check_equal_params(bmap1
, bmap2
) < 0)
11465 space_result
= isl_space_range_product(isl_space_copy(bmap1
->dim
),
11466 isl_space_copy(bmap2
->dim
));
11468 total
= nparam
+ in
+ out1
+ out2
+ bmap1
->n_div
+ bmap2
->n_div
;
11469 dim_map1
= isl_dim_map_alloc(bmap1
->ctx
, total
);
11470 dim_map2
= isl_dim_map_alloc(bmap1
->ctx
, total
);
11471 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_param
, pos
= 0);
11472 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_param
, pos
= 0);
11473 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_in
, pos
+= nparam
);
11474 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_in
, pos
);
11475 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_out
, pos
+= in
);
11476 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_out
, pos
+= out1
);
11477 isl_dim_map_div(dim_map1
, bmap1
, pos
+= out2
);
11478 isl_dim_map_div(dim_map2
, bmap2
, pos
+= bmap1
->n_div
);
11480 bmap
= isl_basic_map_alloc_space(space_result
,
11481 bmap1
->n_div
+ bmap2
->n_div
,
11482 bmap1
->n_eq
+ bmap2
->n_eq
,
11483 bmap1
->n_ineq
+ bmap2
->n_ineq
);
11484 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap1
, dim_map1
);
11485 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap2
, dim_map2
);
11487 bmap
= isl_basic_map_set_rational(bmap
);
11488 bmap
= isl_basic_map_simplify(bmap
);
11489 return isl_basic_map_finalize(bmap
);
11491 isl_basic_map_free(bmap1
);
11492 isl_basic_map_free(bmap2
);
11496 __isl_give isl_basic_map
*isl_basic_map_flat_range_product(
11497 __isl_take isl_basic_map
*bmap1
, __isl_take isl_basic_map
*bmap2
)
11499 isl_basic_map
*prod
;
11501 prod
= isl_basic_map_range_product(bmap1
, bmap2
);
11502 prod
= isl_basic_map_flatten_range(prod
);
11506 /* Apply "basic_map_product" to each pair of basic maps in "map1" and "map2"
11507 * and collect the results.
11508 * The result live in the space obtained by calling "space_product"
11509 * on the spaces of "map1" and "map2".
11510 * If "remove_duplicates" is set then the result may contain duplicates
11511 * (even if the inputs do not) and so we try and remove the obvious
11514 static __isl_give isl_map
*map_product(__isl_take isl_map
*map1
,
11515 __isl_take isl_map
*map2
,
11516 __isl_give isl_space
*(*space_product
)(__isl_take isl_space
*left
,
11517 __isl_take isl_space
*right
),
11518 __isl_give isl_basic_map
*(*basic_map_product
)(
11519 __isl_take isl_basic_map
*left
,
11520 __isl_take isl_basic_map
*right
),
11521 int remove_duplicates
)
11523 unsigned flags
= 0;
11524 struct isl_map
*result
;
11528 m
= isl_map_has_equal_params(map1
, map2
);
11532 isl_die(isl_map_get_ctx(map1
), isl_error_invalid
,
11533 "parameters don't match", goto error
);
11535 if (ISL_F_ISSET(map1
, ISL_MAP_DISJOINT
) &&
11536 ISL_F_ISSET(map2
, ISL_MAP_DISJOINT
))
11537 ISL_FL_SET(flags
, ISL_MAP_DISJOINT
);
11539 result
= isl_map_alloc_space(space_product(isl_space_copy(map1
->dim
),
11540 isl_space_copy(map2
->dim
)),
11541 map1
->n
* map2
->n
, flags
);
11544 for (i
= 0; i
< map1
->n
; ++i
)
11545 for (j
= 0; j
< map2
->n
; ++j
) {
11546 struct isl_basic_map
*part
;
11547 part
= basic_map_product(isl_basic_map_copy(map1
->p
[i
]),
11548 isl_basic_map_copy(map2
->p
[j
]));
11549 if (isl_basic_map_is_empty(part
))
11550 isl_basic_map_free(part
);
11552 result
= isl_map_add_basic_map(result
, part
);
11556 if (remove_duplicates
)
11557 result
= isl_map_remove_obvious_duplicates(result
);
11558 isl_map_free(map1
);
11559 isl_map_free(map2
);
11562 isl_map_free(map1
);
11563 isl_map_free(map2
);
11567 /* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
11569 __isl_give isl_map
*isl_map_product(__isl_take isl_map
*map1
,
11570 __isl_take isl_map
*map2
)
11572 isl_map_align_params_bin(&map1
, &map2
);
11573 return map_product(map1
, map2
, &isl_space_product
,
11574 &isl_basic_map_product
, 0);
11577 /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
11579 __isl_give isl_map
*isl_map_flat_product(__isl_take isl_map
*map1
,
11580 __isl_take isl_map
*map2
)
11584 prod
= isl_map_product(map1
, map2
);
11585 prod
= isl_map_flatten(prod
);
11589 /* Given two set A and B, construct its Cartesian product A x B.
11591 __isl_give isl_set
*isl_set_product(__isl_take isl_set
*set1
,
11592 __isl_take isl_set
*set2
)
11594 return isl_map_range_product(set1
, set2
);
11597 __isl_give isl_set
*isl_set_flat_product(__isl_take isl_set
*set1
,
11598 __isl_take isl_set
*set2
)
11600 return isl_map_flat_range_product(set1
, set2
);
11603 /* Given two maps A -> B and C -> D, construct a map [A -> C] -> (B * D)
11605 __isl_give isl_map
*isl_map_domain_product(__isl_take isl_map
*map1
,
11606 __isl_take isl_map
*map2
)
11608 isl_map_align_params_bin(&map1
, &map2
);
11609 return map_product(map1
, map2
, &isl_space_domain_product
,
11610 &isl_basic_map_domain_product
, 1);
11613 /* Given two maps A -> B and C -> D, construct a map (A * C) -> [B -> D]
11615 __isl_give isl_map
*isl_map_range_product(__isl_take isl_map
*map1
,
11616 __isl_take isl_map
*map2
)
11618 isl_map_align_params_bin(&map1
, &map2
);
11619 return map_product(map1
, map2
, &isl_space_range_product
,
11620 &isl_basic_map_range_product
, 1);
11623 /* Given a map of the form [A -> B] -> [C -> D], return the map A -> C.
11625 __isl_give isl_map
*isl_map_factor_domain(__isl_take isl_map
*map
)
11628 isl_size total1
, keep1
, total2
, keep2
;
11630 total1
= isl_map_dim(map
, isl_dim_in
);
11631 total2
= isl_map_dim(map
, isl_dim_out
);
11632 if (total1
< 0 || total2
< 0)
11633 return isl_map_free(map
);
11634 if (!isl_space_domain_is_wrapping(map
->dim
) ||
11635 !isl_space_range_is_wrapping(map
->dim
))
11636 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
11637 "not a product", return isl_map_free(map
));
11639 space
= isl_map_get_space(map
);
11640 space
= isl_space_factor_domain(space
);
11641 keep1
= isl_space_dim(space
, isl_dim_in
);
11642 keep2
= isl_space_dim(space
, isl_dim_out
);
11643 if (keep1
< 0 || keep2
< 0)
11644 map
= isl_map_free(map
);
11645 map
= isl_map_project_out(map
, isl_dim_in
, keep1
, total1
- keep1
);
11646 map
= isl_map_project_out(map
, isl_dim_out
, keep2
, total2
- keep2
);
11647 map
= isl_map_reset_space(map
, space
);
11652 /* Given a map of the form [A -> B] -> [C -> D], return the map B -> D.
11654 __isl_give isl_map
*isl_map_factor_range(__isl_take isl_map
*map
)
11657 isl_size total1
, keep1
, total2
, keep2
;
11659 total1
= isl_map_dim(map
, isl_dim_in
);
11660 total2
= isl_map_dim(map
, isl_dim_out
);
11661 if (total1
< 0 || total2
< 0)
11662 return isl_map_free(map
);
11663 if (!isl_space_domain_is_wrapping(map
->dim
) ||
11664 !isl_space_range_is_wrapping(map
->dim
))
11665 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
11666 "not a product", return isl_map_free(map
));
11668 space
= isl_map_get_space(map
);
11669 space
= isl_space_factor_range(space
);
11670 keep1
= isl_space_dim(space
, isl_dim_in
);
11671 keep2
= isl_space_dim(space
, isl_dim_out
);
11672 if (keep1
< 0 || keep2
< 0)
11673 map
= isl_map_free(map
);
11674 map
= isl_map_project_out(map
, isl_dim_in
, 0, total1
- keep1
);
11675 map
= isl_map_project_out(map
, isl_dim_out
, 0, total2
- keep2
);
11676 map
= isl_map_reset_space(map
, space
);
11681 /* Given a map of the form [A -> B] -> C, return the map A -> C.
11683 __isl_give isl_map
*isl_map_domain_factor_domain(__isl_take isl_map
*map
)
11686 isl_size total
, keep
;
11688 total
= isl_map_dim(map
, isl_dim_in
);
11690 return isl_map_free(map
);
11691 if (!isl_space_domain_is_wrapping(map
->dim
))
11692 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
11693 "domain is not a product", return isl_map_free(map
));
11695 space
= isl_map_get_space(map
);
11696 space
= isl_space_domain_factor_domain(space
);
11697 keep
= isl_space_dim(space
, isl_dim_in
);
11699 map
= isl_map_free(map
);
11700 map
= isl_map_project_out(map
, isl_dim_in
, keep
, total
- keep
);
11701 map
= isl_map_reset_space(map
, space
);
11706 /* Given a map of the form [A -> B] -> C, return the map B -> C.
11708 __isl_give isl_map
*isl_map_domain_factor_range(__isl_take isl_map
*map
)
11711 isl_size total
, keep
;
11713 total
= isl_map_dim(map
, isl_dim_in
);
11715 return isl_map_free(map
);
11716 if (!isl_space_domain_is_wrapping(map
->dim
))
11717 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
11718 "domain is not a product", return isl_map_free(map
));
11720 space
= isl_map_get_space(map
);
11721 space
= isl_space_domain_factor_range(space
);
11722 keep
= isl_space_dim(space
, isl_dim_in
);
11724 map
= isl_map_free(map
);
11725 map
= isl_map_project_out(map
, isl_dim_in
, 0, total
- keep
);
11726 map
= isl_map_reset_space(map
, space
);
11731 /* Given a map A -> [B -> C], extract the map A -> B.
11733 __isl_give isl_map
*isl_map_range_factor_domain(__isl_take isl_map
*map
)
11736 isl_size total
, keep
;
11738 total
= isl_map_dim(map
, isl_dim_out
);
11740 return isl_map_free(map
);
11741 if (!isl_space_range_is_wrapping(map
->dim
))
11742 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
11743 "range is not a product", return isl_map_free(map
));
11745 space
= isl_map_get_space(map
);
11746 space
= isl_space_range_factor_domain(space
);
11747 keep
= isl_space_dim(space
, isl_dim_out
);
11749 map
= isl_map_free(map
);
11750 map
= isl_map_project_out(map
, isl_dim_out
, keep
, total
- keep
);
11751 map
= isl_map_reset_space(map
, space
);
11756 /* Given a map A -> [B -> C], extract the map A -> C.
11758 __isl_give isl_map
*isl_map_range_factor_range(__isl_take isl_map
*map
)
11761 isl_size total
, keep
;
11763 total
= isl_map_dim(map
, isl_dim_out
);
11765 return isl_map_free(map
);
11766 if (!isl_space_range_is_wrapping(map
->dim
))
11767 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
11768 "range is not a product", return isl_map_free(map
));
11770 space
= isl_map_get_space(map
);
11771 space
= isl_space_range_factor_range(space
);
11772 keep
= isl_space_dim(space
, isl_dim_out
);
11774 map
= isl_map_free(map
);
11775 map
= isl_map_project_out(map
, isl_dim_out
, 0, total
- keep
);
11776 map
= isl_map_reset_space(map
, space
);
11781 /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D)
11783 __isl_give isl_map
*isl_map_flat_domain_product(__isl_take isl_map
*map1
,
11784 __isl_take isl_map
*map2
)
11788 prod
= isl_map_domain_product(map1
, map2
);
11789 prod
= isl_map_flatten_domain(prod
);
11793 /* Given two maps A -> B and C -> D, construct a map (A * C) -> (B, D)
11795 __isl_give isl_map
*isl_map_flat_range_product(__isl_take isl_map
*map1
,
11796 __isl_take isl_map
*map2
)
11800 prod
= isl_map_range_product(map1
, map2
);
11801 prod
= isl_map_flatten_range(prod
);
11805 uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map
*bmap
)
11808 uint32_t hash
= isl_hash_init();
11813 bmap
= isl_basic_map_copy(bmap
);
11814 bmap
= isl_basic_map_normalize(bmap
);
11815 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
11818 isl_hash_byte(hash
, bmap
->n_eq
& 0xFF);
11819 for (i
= 0; i
< bmap
->n_eq
; ++i
) {
11821 c_hash
= isl_seq_get_hash(bmap
->eq
[i
], 1 + total
);
11822 isl_hash_hash(hash
, c_hash
);
11824 isl_hash_byte(hash
, bmap
->n_ineq
& 0xFF);
11825 for (i
= 0; i
< bmap
->n_ineq
; ++i
) {
11827 c_hash
= isl_seq_get_hash(bmap
->ineq
[i
], 1 + total
);
11828 isl_hash_hash(hash
, c_hash
);
11830 isl_hash_byte(hash
, bmap
->n_div
& 0xFF);
11831 for (i
= 0; i
< bmap
->n_div
; ++i
) {
11833 if (isl_int_is_zero(bmap
->div
[i
][0]))
11835 isl_hash_byte(hash
, i
& 0xFF);
11836 c_hash
= isl_seq_get_hash(bmap
->div
[i
], 1 + 1 + total
);
11837 isl_hash_hash(hash
, c_hash
);
11839 isl_basic_map_free(bmap
);
11843 uint32_t isl_basic_set_get_hash(__isl_keep isl_basic_set
*bset
)
11845 return isl_basic_map_get_hash(bset_to_bmap(bset
));
11848 uint32_t isl_map_get_hash(__isl_keep isl_map
*map
)
11855 map
= isl_map_copy(map
);
11856 map
= isl_map_normalize(map
);
11860 hash
= isl_hash_init();
11861 for (i
= 0; i
< map
->n
; ++i
) {
11862 uint32_t bmap_hash
;
11863 bmap_hash
= isl_basic_map_get_hash(map
->p
[i
]);
11864 isl_hash_hash(hash
, bmap_hash
);
11872 uint32_t isl_set_get_hash(__isl_keep isl_set
*set
)
11874 return isl_map_get_hash(set_to_map(set
));
11877 /* Return the number of basic maps in the (current) representation of "map".
11879 isl_size
isl_map_n_basic_map(__isl_keep isl_map
*map
)
11881 return map
? map
->n
: isl_size_error
;
11884 isl_size
isl_set_n_basic_set(__isl_keep isl_set
*set
)
11886 return set
? set
->n
: isl_size_error
;
11889 isl_stat
isl_map_foreach_basic_map(__isl_keep isl_map
*map
,
11890 isl_stat (*fn
)(__isl_take isl_basic_map
*bmap
, void *user
), void *user
)
11895 return isl_stat_error
;
11897 for (i
= 0; i
< map
->n
; ++i
)
11898 if (fn(isl_basic_map_copy(map
->p
[i
]), user
) < 0)
11899 return isl_stat_error
;
11901 return isl_stat_ok
;
11904 isl_stat
isl_set_foreach_basic_set(__isl_keep isl_set
*set
,
11905 isl_stat (*fn
)(__isl_take isl_basic_set
*bset
, void *user
), void *user
)
11910 return isl_stat_error
;
11912 for (i
= 0; i
< set
->n
; ++i
)
11913 if (fn(isl_basic_set_copy(set
->p
[i
]), user
) < 0)
11914 return isl_stat_error
;
11916 return isl_stat_ok
;
11919 /* Does "test" succeed on every basic set in "set"?
11921 isl_bool
isl_set_every_basic_set(__isl_keep isl_set
*set
,
11922 isl_bool (*test
)(__isl_keep isl_basic_set
*bset
, void *user
),
11928 return isl_bool_error
;
11930 for (i
= 0; i
< set
->n
; ++i
) {
11933 r
= test(set
->p
[i
], user
);
11938 return isl_bool_true
;
11941 /* Return a list of basic sets, the union of which is equal to "set".
11943 __isl_give isl_basic_set_list
*isl_set_get_basic_set_list(
11944 __isl_keep isl_set
*set
)
11947 isl_basic_set_list
*list
;
11952 list
= isl_basic_set_list_alloc(isl_set_get_ctx(set
), set
->n
);
11953 for (i
= 0; i
< set
->n
; ++i
) {
11954 isl_basic_set
*bset
;
11956 bset
= isl_basic_set_copy(set
->p
[i
]);
11957 list
= isl_basic_set_list_add(list
, bset
);
11963 __isl_give isl_basic_set
*isl_basic_set_lift(__isl_take isl_basic_set
*bset
)
11970 bset
= isl_basic_set_cow(bset
);
11974 space
= isl_basic_set_get_space(bset
);
11975 space
= isl_space_lift(space
, bset
->n_div
);
11978 isl_space_free(bset
->dim
);
11980 bset
->extra
-= bset
->n_div
;
11983 bset
= isl_basic_set_finalize(bset
);
11987 isl_basic_set_free(bset
);
11991 __isl_give isl_set
*isl_set_lift(__isl_take isl_set
*set
)
11997 set
= set_from_map(isl_map_align_divs_internal(set_to_map(set
)));
12002 set
= isl_set_cow(set
);
12006 n_div
= set
->p
[0]->n_div
;
12007 space
= isl_set_get_space(set
);
12008 space
= isl_space_lift(space
, n_div
);
12011 isl_space_free(set
->dim
);
12014 for (i
= 0; i
< set
->n
; ++i
) {
12015 set
->p
[i
] = isl_basic_set_lift(set
->p
[i
]);
12026 int isl_basic_set_size(__isl_keep isl_basic_set
*bset
)
12031 dim
= isl_basic_set_dim(bset
, isl_dim_all
);
12034 size
+= bset
->n_eq
* (1 + dim
);
12035 size
+= bset
->n_ineq
* (1 + dim
);
12036 size
+= bset
->n_div
* (2 + dim
);
12041 int isl_set_size(__isl_keep isl_set
*set
)
12049 for (i
= 0; i
< set
->n
; ++i
)
12050 size
+= isl_basic_set_size(set
->p
[i
]);
12055 /* Check if there is any lower bound (if lower == 0) and/or upper
12056 * bound (if upper == 0) on the specified dim.
12058 static isl_bool
basic_map_dim_is_bounded(__isl_keep isl_basic_map
*bmap
,
12059 enum isl_dim_type type
, unsigned pos
, int lower
, int upper
)
12065 if (isl_basic_map_check_range(bmap
, type
, pos
, 1) < 0)
12066 return isl_bool_error
;
12068 off
= isl_basic_map_var_offset(bmap
, type
);
12070 return isl_bool_error
;
12071 involves
= isl_basic_map_any_div_involves_vars(bmap
, off
+ pos
, 1);
12072 if (involves
< 0 || involves
)
12075 for (i
= 0; i
< bmap
->n_eq
; ++i
)
12076 if (!isl_int_is_zero(bmap
->eq
[i
][1 + off
+ pos
]))
12077 return isl_bool_true
;
12079 for (i
= 0; i
< bmap
->n_ineq
; ++i
) {
12080 int sgn
= isl_int_sgn(bmap
->ineq
[i
][1 + off
+ pos
]);
12087 return lower
&& upper
;
12090 isl_bool
isl_basic_map_dim_is_bounded(__isl_keep isl_basic_map
*bmap
,
12091 enum isl_dim_type type
, unsigned pos
)
12093 return basic_map_dim_is_bounded(bmap
, type
, pos
, 0, 0);
12096 isl_bool
isl_basic_map_dim_has_lower_bound(__isl_keep isl_basic_map
*bmap
,
12097 enum isl_dim_type type
, unsigned pos
)
12099 return basic_map_dim_is_bounded(bmap
, type
, pos
, 0, 1);
12102 isl_bool
isl_basic_map_dim_has_upper_bound(__isl_keep isl_basic_map
*bmap
,
12103 enum isl_dim_type type
, unsigned pos
)
12105 return basic_map_dim_is_bounded(bmap
, type
, pos
, 1, 0);
12108 isl_bool
isl_map_dim_is_bounded(__isl_keep isl_map
*map
,
12109 enum isl_dim_type type
, unsigned pos
)
12114 return isl_bool_error
;
12116 for (i
= 0; i
< map
->n
; ++i
) {
12118 bounded
= isl_basic_map_dim_is_bounded(map
->p
[i
], type
, pos
);
12119 if (bounded
< 0 || !bounded
)
12123 return isl_bool_true
;
12126 /* Return true if the specified dim is involved in both an upper bound
12127 * and a lower bound.
12129 isl_bool
isl_set_dim_is_bounded(__isl_keep isl_set
*set
,
12130 enum isl_dim_type type
, unsigned pos
)
12132 return isl_map_dim_is_bounded(set_to_map(set
), type
, pos
);
12135 /* Does "map" have a bound (according to "fn") for any of its basic maps?
12137 static isl_bool
has_any_bound(__isl_keep isl_map
*map
,
12138 enum isl_dim_type type
, unsigned pos
,
12139 isl_bool (*fn
)(__isl_keep isl_basic_map
*bmap
,
12140 enum isl_dim_type type
, unsigned pos
))
12145 return isl_bool_error
;
12147 for (i
= 0; i
< map
->n
; ++i
) {
12149 bounded
= fn(map
->p
[i
], type
, pos
);
12150 if (bounded
< 0 || bounded
)
12154 return isl_bool_false
;
12157 /* Return 1 if the specified dim is involved in any lower bound.
12159 isl_bool
isl_set_dim_has_any_lower_bound(__isl_keep isl_set
*set
,
12160 enum isl_dim_type type
, unsigned pos
)
12162 return has_any_bound(set
, type
, pos
,
12163 &isl_basic_map_dim_has_lower_bound
);
12166 /* Return 1 if the specified dim is involved in any upper bound.
12168 isl_bool
isl_set_dim_has_any_upper_bound(__isl_keep isl_set
*set
,
12169 enum isl_dim_type type
, unsigned pos
)
12171 return has_any_bound(set
, type
, pos
,
12172 &isl_basic_map_dim_has_upper_bound
);
12175 /* Does "map" have a bound (according to "fn") for all of its basic maps?
12177 static isl_bool
has_bound(__isl_keep isl_map
*map
,
12178 enum isl_dim_type type
, unsigned pos
,
12179 isl_bool (*fn
)(__isl_keep isl_basic_map
*bmap
,
12180 enum isl_dim_type type
, unsigned pos
))
12185 return isl_bool_error
;
12187 for (i
= 0; i
< map
->n
; ++i
) {
12189 bounded
= fn(map
->p
[i
], type
, pos
);
12190 if (bounded
< 0 || !bounded
)
12194 return isl_bool_true
;
12197 /* Return 1 if the specified dim has a lower bound (in each of its basic sets).
12199 isl_bool
isl_set_dim_has_lower_bound(__isl_keep isl_set
*set
,
12200 enum isl_dim_type type
, unsigned pos
)
12202 return has_bound(set
, type
, pos
, &isl_basic_map_dim_has_lower_bound
);
12205 /* Return 1 if the specified dim has an upper bound (in each of its basic sets).
12207 isl_bool
isl_set_dim_has_upper_bound(__isl_keep isl_set
*set
,
12208 enum isl_dim_type type
, unsigned pos
)
12210 return has_bound(set
, type
, pos
, &isl_basic_map_dim_has_upper_bound
);
12213 /* For each of the "n" variables starting at "first", determine
12214 * the sign of the variable and put the results in the first "n"
12215 * elements of the array "signs".
12217 * 1 means that the variable is non-negative
12218 * -1 means that the variable is non-positive
12219 * 0 means the variable attains both positive and negative values.
12221 isl_stat
isl_basic_set_vars_get_sign(__isl_keep isl_basic_set
*bset
,
12222 unsigned first
, unsigned n
, int *signs
)
12224 isl_vec
*bound
= NULL
;
12225 struct isl_tab
*tab
= NULL
;
12226 struct isl_tab_undo
*snap
;
12230 total
= isl_basic_set_dim(bset
, isl_dim_all
);
12231 if (total
< 0 || !signs
)
12232 return isl_stat_error
;
12234 bound
= isl_vec_alloc(bset
->ctx
, 1 + total
);
12235 tab
= isl_tab_from_basic_set(bset
, 0);
12236 if (!bound
|| !tab
)
12239 isl_seq_clr(bound
->el
, bound
->size
);
12240 isl_int_set_si(bound
->el
[0], -1);
12242 snap
= isl_tab_snap(tab
);
12243 for (i
= 0; i
< n
; ++i
) {
12246 isl_int_set_si(bound
->el
[1 + first
+ i
], -1);
12247 if (isl_tab_add_ineq(tab
, bound
->el
) < 0)
12249 empty
= tab
->empty
;
12250 isl_int_set_si(bound
->el
[1 + first
+ i
], 0);
12251 if (isl_tab_rollback(tab
, snap
) < 0)
12259 isl_int_set_si(bound
->el
[1 + first
+ i
], 1);
12260 if (isl_tab_add_ineq(tab
, bound
->el
) < 0)
12262 empty
= tab
->empty
;
12263 isl_int_set_si(bound
->el
[1 + first
+ i
], 0);
12264 if (isl_tab_rollback(tab
, snap
) < 0)
12267 signs
[i
] = empty
? -1 : 0;
12271 isl_vec_free(bound
);
12272 return isl_stat_ok
;
12275 isl_vec_free(bound
);
12276 return isl_stat_error
;
12279 isl_stat
isl_basic_set_dims_get_sign(__isl_keep isl_basic_set
*bset
,
12280 enum isl_dim_type type
, unsigned first
, unsigned n
, int *signs
)
12282 if (!bset
|| !signs
)
12283 return isl_stat_error
;
12284 if (isl_basic_set_check_range(bset
, type
, first
, n
) < 0)
12285 return isl_stat_error
;
12287 first
+= pos(bset
->dim
, type
) - 1;
12288 return isl_basic_set_vars_get_sign(bset
, first
, n
, signs
);
12291 /* Is it possible for the integer division "div" to depend (possibly
12292 * indirectly) on any output dimensions?
12294 * If the div is undefined, then we conservatively assume that it
12295 * may depend on them.
12296 * Otherwise, we check if it actually depends on them or on any integer
12297 * divisions that may depend on them.
12299 static isl_bool
div_may_involve_output(__isl_keep isl_basic_map
*bmap
, int div
)
12302 isl_size n_out
, n_div
;
12303 unsigned o_out
, o_div
;
12305 if (isl_int_is_zero(bmap
->div
[div
][0]))
12306 return isl_bool_true
;
12308 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
12310 return isl_bool_error
;
12311 o_out
= isl_basic_map_offset(bmap
, isl_dim_out
);
12313 if (isl_seq_first_non_zero(bmap
->div
[div
] + 1 + o_out
, n_out
) != -1)
12314 return isl_bool_true
;
12316 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
12318 return isl_bool_error
;
12319 o_div
= isl_basic_map_offset(bmap
, isl_dim_div
);
12321 for (i
= 0; i
< n_div
; ++i
) {
12322 isl_bool may_involve
;
12324 if (isl_int_is_zero(bmap
->div
[div
][1 + o_div
+ i
]))
12326 may_involve
= div_may_involve_output(bmap
, i
);
12327 if (may_involve
< 0 || may_involve
)
12328 return may_involve
;
12331 return isl_bool_false
;
12334 /* Return the first integer division of "bmap" in the range
12335 * [first, first + n[ that may depend on any output dimensions and
12336 * that has a non-zero coefficient in "c" (where the first coefficient
12337 * in "c" corresponds to integer division "first").
12339 static int first_div_may_involve_output(__isl_keep isl_basic_map
*bmap
,
12340 isl_int
*c
, int first
, int n
)
12347 for (k
= first
; k
< first
+ n
; ++k
) {
12348 isl_bool may_involve
;
12350 if (isl_int_is_zero(c
[k
]))
12352 may_involve
= div_may_involve_output(bmap
, k
);
12353 if (may_involve
< 0)
12362 /* Look for a pair of inequality constraints in "bmap" of the form
12364 * -l + i >= 0 or i >= l
12366 * n + l - i >= 0 or i <= l + n
12368 * with n < "m" and i the output dimension at position "pos".
12369 * (Note that n >= 0 as otherwise the two constraints would conflict.)
12370 * Furthermore, "l" is only allowed to involve parameters, input dimensions
12371 * and earlier output dimensions, as well as integer divisions that do
12372 * not involve any of the output dimensions.
12374 * Return the index of the first inequality constraint or bmap->n_ineq
12375 * if no such pair can be found.
12377 static int find_modulo_constraint_pair(__isl_keep isl_basic_map
*bmap
,
12378 int pos
, isl_int m
)
12383 isl_size n_div
, n_out
;
12384 unsigned o_div
, o_out
;
12387 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
12388 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
12389 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
12390 if (total
< 0 || n_out
< 0 || n_div
< 0)
12393 ctx
= isl_basic_map_get_ctx(bmap
);
12394 o_out
= isl_basic_map_offset(bmap
, isl_dim_out
);
12395 o_div
= isl_basic_map_offset(bmap
, isl_dim_div
);
12396 for (i
= 0; i
< bmap
->n_ineq
; ++i
) {
12397 if (!isl_int_abs_eq(bmap
->ineq
[i
][o_out
+ pos
], ctx
->one
))
12399 if (isl_seq_first_non_zero(bmap
->ineq
[i
] + o_out
+ pos
+ 1,
12400 n_out
- (pos
+ 1)) != -1)
12402 if (first_div_may_involve_output(bmap
, bmap
->ineq
[i
] + o_div
,
12405 for (j
= i
+ 1; j
< bmap
->n_ineq
; ++j
) {
12406 if (!isl_int_abs_eq(bmap
->ineq
[j
][o_out
+ pos
],
12409 if (!isl_seq_is_neg(bmap
->ineq
[i
] + 1,
12410 bmap
->ineq
[j
] + 1, total
))
12414 if (j
>= bmap
->n_ineq
)
12416 isl_int_add(bmap
->ineq
[i
][0],
12417 bmap
->ineq
[i
][0], bmap
->ineq
[j
][0]);
12418 less
= isl_int_abs_lt(bmap
->ineq
[i
][0], m
);
12419 isl_int_sub(bmap
->ineq
[i
][0],
12420 bmap
->ineq
[i
][0], bmap
->ineq
[j
][0]);
12423 if (isl_int_is_one(bmap
->ineq
[i
][o_out
+ pos
]))
12429 return bmap
->n_ineq
;
12432 /* Return the index of the equality of "bmap" that defines
12433 * the output dimension "pos" in terms of earlier dimensions.
12434 * The equality may also involve integer divisions, as long
12435 * as those integer divisions are defined in terms of
12436 * parameters or input dimensions.
12437 * In this case, *div is set to the number of integer divisions and
12438 * *ineq is set to the number of inequality constraints (provided
12439 * div and ineq are not NULL).
12441 * The equality may also involve a single integer division involving
12442 * the output dimensions (typically only output dimension "pos") as
12443 * long as the coefficient of output dimension "pos" is 1 or -1 and
12444 * there is a pair of constraints i >= l and i <= l + n, with i referring
12445 * to output dimension "pos", l an expression involving only earlier
12446 * dimensions and n smaller than the coefficient of the integer division
12447 * in the equality. In this case, the output dimension can be defined
12448 * in terms of a modulo expression that does not involve the integer division.
12449 * *div is then set to this single integer division and
12450 * *ineq is set to the index of constraint i >= l.
12452 * Return bmap->n_eq if there is no such equality.
12453 * Return -1 on error.
12455 int isl_basic_map_output_defining_equality(__isl_keep isl_basic_map
*bmap
,
12456 int pos
, int *div
, int *ineq
)
12459 isl_size n_div
, n_out
;
12460 unsigned o_div
, o_out
;
12462 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
12463 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
12464 if (n_out
< 0 || n_div
< 0)
12467 o_out
= isl_basic_map_offset(bmap
, isl_dim_out
);
12468 o_div
= isl_basic_map_offset(bmap
, isl_dim_div
);
12471 *ineq
= bmap
->n_ineq
;
12474 for (j
= 0; j
< bmap
->n_eq
; ++j
) {
12475 if (isl_int_is_zero(bmap
->eq
[j
][o_out
+ pos
]))
12477 if (isl_seq_first_non_zero(bmap
->eq
[j
] + o_out
+ pos
+ 1,
12478 n_out
- (pos
+ 1)) != -1)
12480 k
= first_div_may_involve_output(bmap
, bmap
->eq
[j
] + o_div
,
12484 if (!isl_int_is_one(bmap
->eq
[j
][o_out
+ pos
]) &&
12485 !isl_int_is_negone(bmap
->eq
[j
][o_out
+ pos
]))
12487 if (first_div_may_involve_output(bmap
, bmap
->eq
[j
] + o_div
,
12488 k
+ 1, n_div
- (k
+1)) < n_div
)
12490 l
= find_modulo_constraint_pair(bmap
, pos
,
12491 bmap
->eq
[j
][o_div
+ k
]);
12494 if (l
>= bmap
->n_ineq
)
12506 /* Check if the given basic map is obviously single-valued.
12507 * In particular, for each output dimension, check that there is
12508 * an equality that defines the output dimension in terms of
12509 * earlier dimensions.
12511 isl_bool
isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map
*bmap
)
12516 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
12518 return isl_bool_error
;
12520 for (i
= 0; i
< n_out
; ++i
) {
12523 eq
= isl_basic_map_output_defining_equality(bmap
, i
,
12526 return isl_bool_error
;
12527 if (eq
>= bmap
->n_eq
)
12528 return isl_bool_false
;
12531 return isl_bool_true
;
12534 /* Check if the given basic map is single-valued.
12535 * We simply compute
12539 * and check if the result is a subset of the identity mapping.
12541 isl_bool
isl_basic_map_is_single_valued(__isl_keep isl_basic_map
*bmap
)
12544 isl_basic_map
*test
;
12548 sv
= isl_basic_map_plain_is_single_valued(bmap
);
12552 test
= isl_basic_map_reverse(isl_basic_map_copy(bmap
));
12553 test
= isl_basic_map_apply_range(test
, isl_basic_map_copy(bmap
));
12555 space
= isl_basic_map_get_space(bmap
);
12556 space
= isl_space_map_from_set(isl_space_range(space
));
12557 id
= isl_basic_map_identity(space
);
12559 sv
= isl_basic_map_is_subset(test
, id
);
12561 isl_basic_map_free(test
);
12562 isl_basic_map_free(id
);
12567 /* Check if the given map is obviously single-valued.
12569 isl_bool
isl_map_plain_is_single_valued(__isl_keep isl_map
*map
)
12572 return isl_bool_error
;
12574 return isl_bool_true
;
12576 return isl_bool_false
;
12578 return isl_basic_map_plain_is_single_valued(map
->p
[0]);
12581 /* Check if the given map is single-valued.
12582 * We simply compute
12586 * and check if the result is a subset of the identity mapping.
12588 isl_bool
isl_map_is_single_valued(__isl_keep isl_map
*map
)
12595 sv
= isl_map_plain_is_single_valued(map
);
12599 test
= isl_map_reverse(isl_map_copy(map
));
12600 test
= isl_map_apply_range(test
, isl_map_copy(map
));
12602 space
= isl_space_map_from_set(isl_space_range(isl_map_get_space(map
)));
12603 id
= isl_map_identity(space
);
12605 sv
= isl_map_is_subset(test
, id
);
12607 isl_map_free(test
);
12613 isl_bool
isl_map_is_injective(__isl_keep isl_map
*map
)
12617 map
= isl_map_copy(map
);
12618 map
= isl_map_reverse(map
);
12619 in
= isl_map_is_single_valued(map
);
12625 /* Check if the given map is obviously injective.
12627 isl_bool
isl_map_plain_is_injective(__isl_keep isl_map
*map
)
12631 map
= isl_map_copy(map
);
12632 map
= isl_map_reverse(map
);
12633 in
= isl_map_plain_is_single_valued(map
);
12639 isl_bool
isl_map_is_bijective(__isl_keep isl_map
*map
)
12643 sv
= isl_map_is_single_valued(map
);
12647 return isl_map_is_injective(map
);
12650 isl_bool
isl_set_is_singleton(__isl_keep isl_set
*set
)
12652 return isl_map_is_single_valued(set_to_map(set
));
12655 /* Does "map" only map elements to themselves?
12657 * If the domain and range spaces are different, then "map"
12658 * is considered not to be an identity relation, even if it is empty.
12659 * Otherwise, construct the maximal identity relation and
12660 * check whether "map" is a subset of this relation.
12662 isl_bool
isl_map_is_identity(__isl_keep isl_map
*map
)
12665 isl_bool equal
, is_identity
;
12667 equal
= isl_map_tuple_is_equal(map
, isl_dim_in
, map
, isl_dim_out
);
12668 if (equal
< 0 || !equal
)
12671 id
= isl_map_identity(isl_map_get_space(map
));
12672 is_identity
= isl_map_is_subset(map
, id
);
12675 return is_identity
;
12678 int isl_map_is_translation(__isl_keep isl_map
*map
)
12683 delta
= isl_map_deltas(isl_map_copy(map
));
12684 ok
= isl_set_is_singleton(delta
);
12685 isl_set_free(delta
);
12690 static int unique(isl_int
*p
, unsigned pos
, unsigned len
)
12692 if (isl_seq_first_non_zero(p
, pos
) != -1)
12694 if (isl_seq_first_non_zero(p
+ pos
+ 1, len
- pos
- 1) != -1)
12699 isl_bool
isl_basic_set_is_box(__isl_keep isl_basic_set
*bset
)
12702 isl_size nvar
, ovar
, n_div
;
12704 n_div
= isl_basic_set_dim(bset
, isl_dim_div
);
12706 return isl_bool_error
;
12708 return isl_bool_false
;
12710 nvar
= isl_basic_set_dim(bset
, isl_dim_set
);
12711 ovar
= isl_space_offset(bset
->dim
, isl_dim_set
);
12712 if (nvar
< 0 || ovar
< 0)
12713 return isl_bool_error
;
12714 for (j
= 0; j
< nvar
; ++j
) {
12715 int lower
= 0, upper
= 0;
12716 for (i
= 0; i
< bset
->n_eq
; ++i
) {
12717 if (isl_int_is_zero(bset
->eq
[i
][1 + ovar
+ j
]))
12719 if (!unique(bset
->eq
[i
] + 1 + ovar
, j
, nvar
))
12720 return isl_bool_false
;
12723 if (i
< bset
->n_eq
)
12725 for (i
= 0; i
< bset
->n_ineq
; ++i
) {
12726 if (isl_int_is_zero(bset
->ineq
[i
][1 + ovar
+ j
]))
12728 if (!unique(bset
->ineq
[i
] + 1 + ovar
, j
, nvar
))
12729 return isl_bool_false
;
12730 if (isl_int_is_pos(bset
->ineq
[i
][1 + ovar
+ j
]))
12735 if (!lower
|| !upper
)
12736 return isl_bool_false
;
12739 return isl_bool_true
;
12742 isl_bool
isl_set_is_box(__isl_keep isl_set
*set
)
12745 return isl_bool_error
;
12747 return isl_bool_false
;
12749 return isl_basic_set_is_box(set
->p
[0]);
12752 isl_bool
isl_basic_set_is_wrapping(__isl_keep isl_basic_set
*bset
)
12755 return isl_bool_error
;
12757 return isl_space_is_wrapping(bset
->dim
);
12760 isl_bool
isl_set_is_wrapping(__isl_keep isl_set
*set
)
12763 return isl_bool_error
;
12765 return isl_space_is_wrapping(set
->dim
);
12768 /* Modify the space of "map" through a call to "change".
12769 * If "can_change" is set (not NULL), then first call it to check
12770 * if the modification is allowed, printing the error message "cannot_change"
12773 static __isl_give isl_map
*isl_map_change_space(__isl_take isl_map
*map
,
12774 isl_bool (*can_change
)(__isl_keep isl_map
*map
),
12775 const char *cannot_change
,
12776 __isl_give isl_space
*(*change
)(__isl_take isl_space
*space
))
12784 ok
= can_change
? can_change(map
) : isl_bool_true
;
12786 return isl_map_free(map
);
12788 isl_die(isl_map_get_ctx(map
), isl_error_invalid
, cannot_change
,
12789 return isl_map_free(map
));
12791 space
= change(isl_map_get_space(map
));
12792 map
= isl_map_reset_space(map
, space
);
12797 /* Is the domain of "map" a wrapped relation?
12799 isl_bool
isl_map_domain_is_wrapping(__isl_keep isl_map
*map
)
12802 return isl_bool_error
;
12804 return isl_space_domain_is_wrapping(map
->dim
);
12807 /* Does "map" have a wrapped relation in both domain and range?
12809 isl_bool
isl_map_is_product(__isl_keep isl_map
*map
)
12811 return isl_space_is_product(isl_map_peek_space(map
));
12814 /* Is the range of "map" a wrapped relation?
12816 isl_bool
isl_map_range_is_wrapping(__isl_keep isl_map
*map
)
12819 return isl_bool_error
;
12821 return isl_space_range_is_wrapping(map
->dim
);
12824 __isl_give isl_basic_set
*isl_basic_map_wrap(__isl_take isl_basic_map
*bmap
)
12828 space
= isl_basic_map_take_space(bmap
);
12829 space
= isl_space_wrap(space
);
12830 bmap
= isl_basic_map_restore_space(bmap
, space
);
12832 bmap
= isl_basic_map_finalize(bmap
);
12834 return bset_from_bmap(bmap
);
12837 /* Given a map A -> B, return the set (A -> B).
12839 __isl_give isl_set
*isl_map_wrap(__isl_take isl_map
*map
)
12841 return isl_map_change_space(map
, NULL
, NULL
, &isl_space_wrap
);
12844 __isl_give isl_basic_map
*isl_basic_set_unwrap(__isl_take isl_basic_set
*bset
)
12846 bset
= isl_basic_set_cow(bset
);
12850 bset
->dim
= isl_space_unwrap(bset
->dim
);
12854 bset
= isl_basic_set_finalize(bset
);
12856 return bset_to_bmap(bset
);
12858 isl_basic_set_free(bset
);
12862 /* Given a set (A -> B), return the map A -> B.
12863 * Error out if "set" is not of the form (A -> B).
12865 __isl_give isl_map
*isl_set_unwrap(__isl_take isl_set
*set
)
12867 return isl_map_change_space(set
, &isl_set_is_wrapping
,
12868 "not a wrapping set", &isl_space_unwrap
);
12871 __isl_give isl_basic_map
*isl_basic_map_reset(__isl_take isl_basic_map
*bmap
,
12872 enum isl_dim_type type
)
12876 space
= isl_basic_map_take_space(bmap
);
12877 space
= isl_space_reset(space
, type
);
12878 bmap
= isl_basic_map_restore_space(bmap
, space
);
12880 bmap
= isl_basic_map_mark_final(bmap
);
12885 __isl_give isl_map
*isl_map_reset(__isl_take isl_map
*map
,
12886 enum isl_dim_type type
)
12894 if (!isl_space_is_named_or_nested(map
->dim
, type
))
12897 map
= isl_map_cow(map
);
12901 for (i
= 0; i
< map
->n
; ++i
) {
12902 map
->p
[i
] = isl_basic_map_reset(map
->p
[i
], type
);
12907 space
= isl_map_take_space(map
);
12908 space
= isl_space_reset(space
, type
);
12909 map
= isl_map_restore_space(map
, space
);
12917 __isl_give isl_basic_map
*isl_basic_map_flatten(__isl_take isl_basic_map
*bmap
)
12921 space
= isl_basic_map_take_space(bmap
);
12922 space
= isl_space_flatten(space
);
12923 bmap
= isl_basic_map_restore_space(bmap
, space
);
12925 bmap
= isl_basic_map_mark_final(bmap
);
12930 __isl_give isl_basic_set
*isl_basic_set_flatten(__isl_take isl_basic_set
*bset
)
12932 return bset_from_bmap(isl_basic_map_flatten(bset_to_bmap(bset
)));
12935 __isl_give isl_basic_map
*isl_basic_map_flatten_domain(
12936 __isl_take isl_basic_map
*bmap
)
12940 space
= isl_basic_map_take_space(bmap
);
12941 space
= isl_space_flatten_domain(space
);
12942 bmap
= isl_basic_map_restore_space(bmap
, space
);
12944 bmap
= isl_basic_map_mark_final(bmap
);
12949 __isl_give isl_basic_map
*isl_basic_map_flatten_range(
12950 __isl_take isl_basic_map
*bmap
)
12954 space
= isl_basic_map_take_space(bmap
);
12955 space
= isl_space_flatten_range(space
);
12956 bmap
= isl_basic_map_restore_space(bmap
, space
);
12958 bmap
= isl_basic_map_mark_final(bmap
);
12963 /* Remove any internal structure from the spaces of domain and range of "map".
12965 __isl_give isl_map
*isl_map_flatten(__isl_take isl_map
*map
)
12970 if (!map
->dim
->nested
[0] && !map
->dim
->nested
[1])
12973 return isl_map_change_space(map
, NULL
, NULL
, &isl_space_flatten
);
12976 __isl_give isl_set
*isl_set_flatten(__isl_take isl_set
*set
)
12978 return set_from_map(isl_map_flatten(set_to_map(set
)));
12981 __isl_give isl_map
*isl_set_flatten_map(__isl_take isl_set
*set
)
12983 isl_space
*space
, *flat_space
;
12986 space
= isl_set_get_space(set
);
12987 flat_space
= isl_space_flatten(isl_space_copy(space
));
12988 map
= isl_map_identity(isl_space_join(isl_space_reverse(space
),
12990 map
= isl_map_intersect_domain(map
, set
);
12995 /* Remove any internal structure from the space of the domain of "map".
12997 __isl_give isl_map
*isl_map_flatten_domain(__isl_take isl_map
*map
)
13002 if (!map
->dim
->nested
[0])
13005 return isl_map_change_space(map
, NULL
, NULL
, &isl_space_flatten_domain
);
13008 /* Remove any internal structure from the space of the range of "map".
13010 __isl_give isl_map
*isl_map_flatten_range(__isl_take isl_map
*map
)
13015 if (!map
->dim
->nested
[1])
13018 return isl_map_change_space(map
, NULL
, NULL
, &isl_space_flatten_range
);
13021 /* Reorder the dimensions of "bmap" according to the given dim_map
13022 * and set the dimension specification to "space" and
13023 * perform Gaussian elimination on the result.
13025 __isl_give isl_basic_map
*isl_basic_map_realign(__isl_take isl_basic_map
*bmap
,
13026 __isl_take isl_space
*space
, __isl_take
struct isl_dim_map
*dim_map
)
13028 isl_basic_map
*res
;
13032 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
13033 if (n_div
< 0 || !space
|| !dim_map
)
13036 flags
= bmap
->flags
;
13037 ISL_FL_CLR(flags
, ISL_BASIC_MAP_FINAL
);
13038 ISL_FL_CLR(flags
, ISL_BASIC_MAP_SORTED
);
13039 ISL_FL_CLR(flags
, ISL_BASIC_MAP_NORMALIZED_DIVS
);
13040 res
= isl_basic_map_alloc_space(space
, n_div
, bmap
->n_eq
, bmap
->n_ineq
);
13041 res
= isl_basic_map_add_constraints_dim_map(res
, bmap
, dim_map
);
13043 res
->flags
= flags
;
13044 res
= isl_basic_map_gauss(res
, NULL
);
13045 res
= isl_basic_map_finalize(res
);
13048 isl_dim_map_free(dim_map
);
13049 isl_basic_map_free(bmap
);
13050 isl_space_free(space
);
13054 /* Reorder the dimensions of "map" according to given reordering.
13056 __isl_give isl_map
*isl_map_realign(__isl_take isl_map
*map
,
13057 __isl_take isl_reordering
*r
)
13060 struct isl_dim_map
*dim_map
;
13062 map
= isl_map_cow(map
);
13063 dim_map
= isl_dim_map_from_reordering(r
);
13064 if (!map
|| !r
|| !dim_map
)
13067 for (i
= 0; i
< map
->n
; ++i
) {
13068 struct isl_dim_map
*dim_map_i
;
13071 dim_map_i
= isl_dim_map_extend(dim_map
, map
->p
[i
]);
13073 space
= isl_reordering_get_space(r
);
13074 map
->p
[i
] = isl_basic_map_realign(map
->p
[i
], space
, dim_map_i
);
13080 map
= isl_map_reset_space(map
, isl_reordering_get_space(r
));
13081 map
= isl_map_unmark_normalized(map
);
13083 isl_reordering_free(r
);
13084 isl_dim_map_free(dim_map
);
13087 isl_dim_map_free(dim_map
);
13089 isl_reordering_free(r
);
13093 __isl_give isl_set
*isl_set_realign(__isl_take isl_set
*set
,
13094 __isl_take isl_reordering
*r
)
13096 return set_from_map(isl_map_realign(set_to_map(set
), r
));
13099 __isl_give isl_map
*isl_map_align_params(__isl_take isl_map
*map
,
13100 __isl_take isl_space
*model
)
13105 if (!map
|| !model
)
13108 ctx
= isl_space_get_ctx(model
);
13109 if (!isl_space_has_named_params(model
))
13110 isl_die(ctx
, isl_error_invalid
,
13111 "model has unnamed parameters", goto error
);
13112 if (isl_map_check_named_params(map
) < 0)
13114 aligned
= isl_map_space_has_equal_params(map
, model
);
13119 isl_reordering
*exp
;
13121 space
= isl_map_peek_space(map
);
13122 exp
= isl_parameter_alignment_reordering(space
, model
);
13123 map
= isl_map_realign(map
, exp
);
13126 isl_space_free(model
);
13129 isl_space_free(model
);
13134 __isl_give isl_set
*isl_set_align_params(__isl_take isl_set
*set
,
13135 __isl_take isl_space
*model
)
13137 return isl_map_align_params(set
, model
);
13140 /* Align the parameters of "bmap" to those of "model", introducing
13141 * additional parameters if needed.
13143 __isl_give isl_basic_map
*isl_basic_map_align_params(
13144 __isl_take isl_basic_map
*bmap
, __isl_take isl_space
*model
)
13147 isl_bool equal_params
;
13148 isl_space
*bmap_space
;
13150 if (!bmap
|| !model
)
13153 ctx
= isl_space_get_ctx(model
);
13154 if (!isl_space_has_named_params(model
))
13155 isl_die(ctx
, isl_error_invalid
,
13156 "model has unnamed parameters", goto error
);
13157 if (isl_basic_map_check_named_params(bmap
) < 0)
13159 bmap_space
= isl_basic_map_peek_space(bmap
);
13160 equal_params
= isl_space_has_equal_params(bmap_space
, model
);
13161 if (equal_params
< 0)
13163 if (!equal_params
) {
13164 isl_reordering
*exp
;
13165 struct isl_dim_map
*dim_map
;
13167 exp
= isl_parameter_alignment_reordering(bmap_space
, model
);
13168 dim_map
= isl_dim_map_from_reordering(exp
);
13169 bmap
= isl_basic_map_realign(bmap
,
13170 isl_reordering_get_space(exp
),
13171 isl_dim_map_extend(dim_map
, bmap
));
13172 isl_reordering_free(exp
);
13173 isl_dim_map_free(dim_map
);
13176 isl_space_free(model
);
13179 isl_space_free(model
);
13180 isl_basic_map_free(bmap
);
13184 /* Do "bset" and "space" have the same parameters?
13186 isl_bool
isl_basic_set_space_has_equal_params(__isl_keep isl_basic_set
*bset
,
13187 __isl_keep isl_space
*space
)
13189 isl_space
*bset_space
;
13191 bset_space
= isl_basic_set_peek_space(bset
);
13192 return isl_space_has_equal_params(bset_space
, space
);
13195 /* Do "map" and "space" have the same parameters?
13197 isl_bool
isl_map_space_has_equal_params(__isl_keep isl_map
*map
,
13198 __isl_keep isl_space
*space
)
13200 isl_space
*map_space
;
13202 map_space
= isl_map_peek_space(map
);
13203 return isl_space_has_equal_params(map_space
, space
);
13206 /* Do "set" and "space" have the same parameters?
13208 isl_bool
isl_set_space_has_equal_params(__isl_keep isl_set
*set
,
13209 __isl_keep isl_space
*space
)
13211 return isl_map_space_has_equal_params(set_to_map(set
), space
);
13214 /* Align the parameters of "bset" to those of "model", introducing
13215 * additional parameters if needed.
13217 __isl_give isl_basic_set
*isl_basic_set_align_params(
13218 __isl_take isl_basic_set
*bset
, __isl_take isl_space
*model
)
13220 return isl_basic_map_align_params(bset
, model
);
13224 #define TYPE isl_map
13225 #define isl_map_drop_dims isl_map_drop
13226 #include "isl_drop_unused_params_templ.c"
13228 /* Drop all parameters not referenced by "set".
13230 __isl_give isl_set
*isl_set_drop_unused_params(
13231 __isl_take isl_set
*set
)
13233 return set_from_map(isl_map_drop_unused_params(set_to_map(set
)));
13237 #define TYPE isl_basic_map
13238 #define isl_basic_map_drop_dims isl_basic_map_drop
13239 #include "isl_drop_unused_params_templ.c"
13241 /* Drop all parameters not referenced by "bset".
13243 __isl_give isl_basic_set
*isl_basic_set_drop_unused_params(
13244 __isl_take isl_basic_set
*bset
)
13246 return bset_from_bmap(isl_basic_map_drop_unused_params(
13247 bset_to_bmap(bset
)));
13250 /* Given a tuple of identifiers "tuple" in a space that corresponds
13251 * to that of "set", if any of those identifiers appear as parameters
13252 * in "set", then equate those parameters with the corresponding
13253 * set dimensions and project out the parameters.
13254 * The result therefore has no such parameters.
13256 static __isl_give isl_set
*equate_params(__isl_take isl_set
*set
,
13257 __isl_keep isl_multi_id
*tuple
)
13261 isl_space
*set_space
, *tuple_space
;
13263 set_space
= isl_set_peek_space(set
);
13264 tuple_space
= isl_multi_id_peek_space(tuple
);
13265 if (isl_space_check_equal_tuples(tuple_space
, set_space
) < 0)
13266 return isl_set_free(set
);
13267 n
= isl_multi_id_size(tuple
);
13269 return isl_set_free(set
);
13270 for (i
= 0; i
< n
; ++i
) {
13274 id
= isl_multi_id_get_at(tuple
, i
);
13276 return isl_set_free(set
);
13277 pos
= isl_set_find_dim_by_id(set
, isl_dim_param
, id
);
13281 set
= isl_set_equate(set
, isl_dim_param
, pos
, isl_dim_set
, i
);
13282 set
= isl_set_project_out(set
, isl_dim_param
, pos
, 1);
13287 /* Bind the set dimensions of "set" to parameters with identifiers
13288 * specified by "tuple", living in the same space as "set".
13290 * If no parameters with these identifiers appear in "set" already,
13291 * then the set dimensions are simply reinterpreted as parameters.
13292 * Otherwise, the parameters are first equated to the corresponding
13295 __isl_give isl_set
*isl_set_bind(__isl_take isl_set
*set
,
13296 __isl_take isl_multi_id
*tuple
)
13300 set
= equate_params(set
, tuple
);
13301 space
= isl_set_get_space(set
);
13302 space
= isl_space_bind_set(space
, tuple
);
13303 isl_multi_id_free(tuple
);
13304 set
= isl_set_reset_space(set
, space
);
13309 /* Given a tuple of identifiers "tuple" in a space that corresponds
13310 * to the domain of "map", if any of those identifiers appear as parameters
13311 * in "map", then equate those parameters with the corresponding
13312 * input dimensions and project out the parameters.
13313 * The result therefore has no such parameters.
13315 static __isl_give isl_map
*map_equate_params(__isl_take isl_map
*map
,
13316 __isl_keep isl_multi_id
*tuple
)
13320 isl_space
*map_space
, *tuple_space
;
13322 map_space
= isl_map_peek_space(map
);
13323 tuple_space
= isl_multi_id_peek_space(tuple
);
13324 if (isl_space_check_domain_tuples(tuple_space
, map_space
) < 0)
13325 return isl_map_free(map
);
13326 n
= isl_multi_id_size(tuple
);
13328 return isl_map_free(map
);
13329 for (i
= 0; i
< n
; ++i
) {
13333 id
= isl_multi_id_get_at(tuple
, i
);
13335 return isl_map_free(map
);
13336 pos
= isl_map_find_dim_by_id(map
, isl_dim_param
, id
);
13340 map
= isl_map_equate(map
, isl_dim_param
, pos
, isl_dim_in
, i
);
13341 map
= isl_map_project_out(map
, isl_dim_param
, pos
, 1);
13346 /* Bind the input dimensions of "map" to parameters with identifiers
13347 * specified by "tuple", living in the domain space of "map".
13349 * If no parameters with these identifiers appear in "map" already,
13350 * then the input dimensions are simply reinterpreted as parameters.
13351 * Otherwise, the parameters are first equated to the corresponding
13352 * input dimensions.
13354 __isl_give isl_set
*isl_map_bind_domain(__isl_take isl_map
*map
,
13355 __isl_take isl_multi_id
*tuple
)
13360 map
= map_equate_params(map
, tuple
);
13361 space
= isl_map_get_space(map
);
13362 space
= isl_space_bind_map_domain(space
, tuple
);
13363 isl_multi_id_free(tuple
);
13364 set
= set_from_map(isl_map_reset_space(map
, space
));
13369 /* Bind the output dimensions of "map" to parameters with identifiers
13370 * specified by "tuple", living in the range space of "map".
13372 * Since binding is more easily implemented on the domain,
13373 * bind the input dimensions of the inverse of "map".
13375 __isl_give isl_set
*isl_map_bind_range(__isl_take isl_map
*map
,
13376 __isl_take isl_multi_id
*tuple
)
13378 return isl_map_bind_domain(isl_map_reverse(map
), tuple
);
13381 /* Insert a domain corresponding to "tuple"
13382 * into the nullary or unary relation "set".
13383 * The result has an extra initial tuple and is therefore
13384 * either a unary or binary relation.
13385 * Any parameters with identifiers in "tuple" are reinterpreted
13386 * as the corresponding domain dimensions.
13388 static __isl_give isl_map
*unbind_params_insert_domain(
13389 __isl_take isl_set
*set
, __isl_take isl_multi_id
*tuple
)
13394 space
= isl_set_peek_space(set
);
13395 r
= isl_reordering_unbind_params_insert_domain(space
, tuple
);
13396 isl_multi_id_free(tuple
);
13398 return isl_map_realign(set_to_map(set
), r
);
13401 /* Construct a set with "tuple" as domain from the parameter domain "set".
13402 * Any parameters with identifiers in "tuple" are reinterpreted
13403 * as the corresponding set dimensions.
13405 __isl_give isl_set
*isl_set_unbind_params(__isl_take isl_set
*set
,
13406 __isl_take isl_multi_id
*tuple
)
13408 isl_bool is_params
;
13410 is_params
= isl_set_is_params(set
);
13412 set
= isl_set_free(set
);
13413 else if (!is_params
)
13414 isl_die(isl_set_get_ctx(set
), isl_error_invalid
,
13415 "expecting parameter domain", set
= isl_set_free(set
));
13416 return set_from_map(unbind_params_insert_domain(set
, tuple
));
13419 /* Check that "set" is a proper set, i.e., that it is not a parameter domain.
13421 static isl_stat
isl_set_check_is_set(__isl_keep isl_set
*set
)
13423 isl_bool is_params
;
13425 is_params
= isl_set_is_params(set
);
13427 return isl_stat_error
;
13428 else if (is_params
)
13429 isl_die(isl_set_get_ctx(set
), isl_error_invalid
,
13430 "expecting proper set", return isl_stat_error
);
13432 return isl_stat_ok
;
13435 /* Construct a map with "domain" as domain and "set" as range.
13436 * Any parameters with identifiers in "domain" are reinterpreted
13437 * as the corresponding domain dimensions.
13439 __isl_give isl_map
*isl_set_unbind_params_insert_domain(
13440 __isl_take isl_set
*set
, __isl_take isl_multi_id
*domain
)
13442 if (isl_set_check_is_set(set
) < 0)
13443 set
= isl_set_free(set
);
13444 return unbind_params_insert_domain(set
, domain
);
13447 /* Construct a map with "domain" as domain and "set" as range.
13449 __isl_give isl_map
*isl_set_insert_domain(__isl_take isl_set
*set
,
13450 __isl_take isl_space
*domain
)
13456 if (isl_set_check_is_set(set
) < 0 || isl_space_check_is_set(domain
) < 0)
13457 domain
= isl_space_free(domain
);
13458 dim
= isl_space_dim(domain
, isl_dim_set
);
13460 domain
= isl_space_free(domain
);
13461 space
= isl_set_get_space(set
);
13462 domain
= isl_space_replace_params(domain
, space
);
13463 space
= isl_space_map_from_domain_and_range(domain
, space
);
13465 map
= isl_map_from_range(set
);
13466 map
= isl_map_add_dims(map
, isl_dim_in
, dim
);
13467 map
= isl_map_reset_space(map
, space
);
13472 __isl_give isl_mat
*isl_basic_map_equalities_matrix(
13473 __isl_keep isl_basic_map
*bmap
, enum isl_dim_type c1
,
13474 enum isl_dim_type c2
, enum isl_dim_type c3
,
13475 enum isl_dim_type c4
, enum isl_dim_type c5
)
13477 enum isl_dim_type c
[5] = { c1
, c2
, c3
, c4
, c5
};
13478 struct isl_mat
*mat
;
13483 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
13486 mat
= isl_mat_alloc(bmap
->ctx
, bmap
->n_eq
, total
+ 1);
13489 for (i
= 0; i
< bmap
->n_eq
; ++i
)
13490 for (j
= 0, pos
= 0; j
< 5; ++j
) {
13491 int off
= isl_basic_map_offset(bmap
, c
[j
]);
13492 isl_size dim
= isl_basic_map_dim(bmap
, c
[j
]);
13494 return isl_mat_free(mat
);
13495 for (k
= 0; k
< dim
; ++k
) {
13496 isl_int_set(mat
->row
[i
][pos
],
13497 bmap
->eq
[i
][off
+ k
]);
13505 __isl_give isl_mat
*isl_basic_map_inequalities_matrix(
13506 __isl_keep isl_basic_map
*bmap
, enum isl_dim_type c1
,
13507 enum isl_dim_type c2
, enum isl_dim_type c3
,
13508 enum isl_dim_type c4
, enum isl_dim_type c5
)
13510 enum isl_dim_type c
[5] = { c1
, c2
, c3
, c4
, c5
};
13511 struct isl_mat
*mat
;
13516 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
13519 mat
= isl_mat_alloc(bmap
->ctx
, bmap
->n_ineq
, total
+ 1);
13522 for (i
= 0; i
< bmap
->n_ineq
; ++i
)
13523 for (j
= 0, pos
= 0; j
< 5; ++j
) {
13524 int off
= isl_basic_map_offset(bmap
, c
[j
]);
13525 isl_size dim
= isl_basic_map_dim(bmap
, c
[j
]);
13527 return isl_mat_free(mat
);
13528 for (k
= 0; k
< dim
; ++k
) {
13529 isl_int_set(mat
->row
[i
][pos
],
13530 bmap
->ineq
[i
][off
+ k
]);
13538 __isl_give isl_basic_map
*isl_basic_map_from_constraint_matrices(
13539 __isl_take isl_space
*space
,
13540 __isl_take isl_mat
*eq
, __isl_take isl_mat
*ineq
, enum isl_dim_type c1
,
13541 enum isl_dim_type c2
, enum isl_dim_type c3
,
13542 enum isl_dim_type c4
, enum isl_dim_type c5
)
13544 enum isl_dim_type c
[5] = { c1
, c2
, c3
, c4
, c5
};
13545 isl_basic_map
*bmap
= NULL
;
13552 dim
= isl_space_dim(space
, isl_dim_all
);
13553 if (dim
< 0 || !eq
|| !ineq
)
13556 if (eq
->n_col
!= ineq
->n_col
)
13557 isl_die(space
->ctx
, isl_error_invalid
,
13558 "equalities and inequalities matrices should have "
13559 "same number of columns", goto error
);
13563 if (eq
->n_col
< total
)
13564 isl_die(space
->ctx
, isl_error_invalid
,
13565 "number of columns too small", goto error
);
13567 extra
= eq
->n_col
- total
;
13569 bmap
= isl_basic_map_alloc_space(isl_space_copy(space
), extra
,
13570 eq
->n_row
, ineq
->n_row
);
13573 for (i
= 0; i
< extra
; ++i
) {
13574 k
= isl_basic_map_alloc_div(bmap
);
13577 isl_int_set_si(bmap
->div
[k
][0], 0);
13579 for (i
= 0; i
< eq
->n_row
; ++i
) {
13580 l
= isl_basic_map_alloc_equality(bmap
);
13583 for (j
= 0, pos
= 0; j
< 5; ++j
) {
13584 int off
= isl_basic_map_offset(bmap
, c
[j
]);
13585 isl_size dim
= isl_basic_map_dim(bmap
, c
[j
]);
13588 for (k
= 0; k
< dim
; ++k
) {
13589 isl_int_set(bmap
->eq
[l
][off
+ k
],
13595 for (i
= 0; i
< ineq
->n_row
; ++i
) {
13596 l
= isl_basic_map_alloc_inequality(bmap
);
13599 for (j
= 0, pos
= 0; j
< 5; ++j
) {
13600 int off
= isl_basic_map_offset(bmap
, c
[j
]);
13601 isl_size dim
= isl_basic_map_dim(bmap
, c
[j
]);
13604 for (k
= 0; k
< dim
; ++k
) {
13605 isl_int_set(bmap
->ineq
[l
][off
+ k
],
13606 ineq
->row
[i
][pos
]);
13612 isl_space_free(space
);
13614 isl_mat_free(ineq
);
13616 bmap
= isl_basic_map_simplify(bmap
);
13617 return isl_basic_map_finalize(bmap
);
13619 isl_space_free(space
);
13621 isl_mat_free(ineq
);
13622 isl_basic_map_free(bmap
);
13626 __isl_give isl_mat
*isl_basic_set_equalities_matrix(
13627 __isl_keep isl_basic_set
*bset
, enum isl_dim_type c1
,
13628 enum isl_dim_type c2
, enum isl_dim_type c3
, enum isl_dim_type c4
)
13630 return isl_basic_map_equalities_matrix(bset_to_bmap(bset
),
13631 c1
, c2
, c3
, c4
, isl_dim_in
);
13634 __isl_give isl_mat
*isl_basic_set_inequalities_matrix(
13635 __isl_keep isl_basic_set
*bset
, enum isl_dim_type c1
,
13636 enum isl_dim_type c2
, enum isl_dim_type c3
, enum isl_dim_type c4
)
13638 return isl_basic_map_inequalities_matrix(bset_to_bmap(bset
),
13639 c1
, c2
, c3
, c4
, isl_dim_in
);
13642 __isl_give isl_basic_set
*isl_basic_set_from_constraint_matrices(
13643 __isl_take isl_space
*space
,
13644 __isl_take isl_mat
*eq
, __isl_take isl_mat
*ineq
, enum isl_dim_type c1
,
13645 enum isl_dim_type c2
, enum isl_dim_type c3
, enum isl_dim_type c4
)
13647 isl_basic_map
*bmap
;
13648 bmap
= isl_basic_map_from_constraint_matrices(space
, eq
, ineq
,
13649 c1
, c2
, c3
, c4
, isl_dim_in
);
13650 return bset_from_bmap(bmap
);
13653 isl_bool
isl_basic_map_can_zip(__isl_keep isl_basic_map
*bmap
)
13656 return isl_bool_error
;
13658 return isl_space_can_zip(bmap
->dim
);
13661 isl_bool
isl_map_can_zip(__isl_keep isl_map
*map
)
13664 return isl_bool_error
;
13666 return isl_space_can_zip(map
->dim
);
13669 /* Given a basic map (A -> B) -> (C -> D), return the corresponding basic map
13670 * (A -> C) -> (B -> D).
13672 __isl_give isl_basic_map
*isl_basic_map_zip(__isl_take isl_basic_map
*bmap
)
13682 if (!isl_basic_map_can_zip(bmap
))
13683 isl_die(bmap
->ctx
, isl_error_invalid
,
13684 "basic map cannot be zipped", goto error
);
13685 n_in
= isl_space_dim(bmap
->dim
->nested
[0], isl_dim_in
);
13686 n1
= isl_space_dim(bmap
->dim
->nested
[0], isl_dim_out
);
13687 n2
= isl_space_dim(bmap
->dim
->nested
[1], isl_dim_in
);
13688 if (n_in
< 0 || n1
< 0 || n2
< 0)
13689 return isl_basic_map_free(bmap
);
13690 pos
= isl_basic_map_offset(bmap
, isl_dim_in
) + n_in
;
13691 bmap
= isl_basic_map_cow(bmap
);
13692 bmap
= isl_basic_map_swap_vars(bmap
, pos
, n1
, n2
);
13695 bmap
->dim
= isl_space_zip(bmap
->dim
);
13698 bmap
= isl_basic_map_mark_final(bmap
);
13701 isl_basic_map_free(bmap
);
13705 /* Given a map (A -> B) -> (C -> D), return the corresponding map
13706 * (A -> C) -> (B -> D).
13708 __isl_give isl_map
*isl_map_zip(__isl_take isl_map
*map
)
13713 if (!isl_map_can_zip(map
))
13714 isl_die(map
->ctx
, isl_error_invalid
, "map cannot be zipped",
13717 return isl_map_transform(map
, &isl_space_zip
, &isl_basic_map_zip
);
13723 /* Can we apply isl_basic_map_curry to "bmap"?
13724 * That is, does it have a nested relation in its domain?
13726 isl_bool
isl_basic_map_can_curry(__isl_keep isl_basic_map
*bmap
)
13729 return isl_bool_error
;
13731 return isl_space_can_curry(bmap
->dim
);
13734 /* Can we apply isl_map_curry to "map"?
13735 * That is, does it have a nested relation in its domain?
13737 isl_bool
isl_map_can_curry(__isl_keep isl_map
*map
)
13740 return isl_bool_error
;
13742 return isl_space_can_curry(map
->dim
);
13745 /* Given a basic map (A -> B) -> C, return the corresponding basic map
13748 __isl_give isl_basic_map
*isl_basic_map_curry(__isl_take isl_basic_map
*bmap
)
13754 if (!isl_basic_map_can_curry(bmap
))
13755 isl_die(bmap
->ctx
, isl_error_invalid
,
13756 "basic map cannot be curried", goto error
);
13757 bmap
= isl_basic_map_cow(bmap
);
13760 bmap
->dim
= isl_space_curry(bmap
->dim
);
13763 bmap
= isl_basic_map_mark_final(bmap
);
13766 isl_basic_map_free(bmap
);
13770 /* Given a map (A -> B) -> C, return the corresponding map
13773 __isl_give isl_map
*isl_map_curry(__isl_take isl_map
*map
)
13775 return isl_map_change_space(map
, &isl_map_can_curry
,
13776 "map cannot be curried", &isl_space_curry
);
13779 /* Can isl_map_range_curry be applied to "map"?
13780 * That is, does it have a nested relation in its range,
13781 * the domain of which is itself a nested relation?
13783 isl_bool
isl_map_can_range_curry(__isl_keep isl_map
*map
)
13786 return isl_bool_error
;
13788 return isl_space_can_range_curry(map
->dim
);
13791 /* Given a map A -> ((B -> C) -> D), return the corresponding map
13792 * A -> (B -> (C -> D)).
13794 __isl_give isl_map
*isl_map_range_curry(__isl_take isl_map
*map
)
13796 return isl_map_change_space(map
, &isl_map_can_range_curry
,
13797 "map range cannot be curried",
13798 &isl_space_range_curry
);
13801 /* Can we apply isl_basic_map_uncurry to "bmap"?
13802 * That is, does it have a nested relation in its domain?
13804 isl_bool
isl_basic_map_can_uncurry(__isl_keep isl_basic_map
*bmap
)
13807 return isl_bool_error
;
13809 return isl_space_can_uncurry(bmap
->dim
);
13812 /* Can we apply isl_map_uncurry to "map"?
13813 * That is, does it have a nested relation in its domain?
13815 isl_bool
isl_map_can_uncurry(__isl_keep isl_map
*map
)
13818 return isl_bool_error
;
13820 return isl_space_can_uncurry(map
->dim
);
13823 /* Given a basic map A -> (B -> C), return the corresponding basic map
13826 __isl_give isl_basic_map
*isl_basic_map_uncurry(__isl_take isl_basic_map
*bmap
)
13832 if (!isl_basic_map_can_uncurry(bmap
))
13833 isl_die(bmap
->ctx
, isl_error_invalid
,
13834 "basic map cannot be uncurried",
13835 return isl_basic_map_free(bmap
));
13836 bmap
= isl_basic_map_cow(bmap
);
13839 bmap
->dim
= isl_space_uncurry(bmap
->dim
);
13841 return isl_basic_map_free(bmap
);
13842 bmap
= isl_basic_map_mark_final(bmap
);
13846 /* Given a map A -> (B -> C), return the corresponding map
13849 __isl_give isl_map
*isl_map_uncurry(__isl_take isl_map
*map
)
13851 return isl_map_change_space(map
, &isl_map_can_uncurry
,
13852 "map cannot be uncurried", &isl_space_uncurry
);
13855 __isl_give isl_set
*isl_set_equate(__isl_take isl_set
*set
,
13856 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
13858 return isl_map_equate(set
, type1
, pos1
, type2
, pos2
);
13861 /* Construct a basic map where the given dimensions are equal to each other.
13863 static __isl_give isl_basic_map
*equator(__isl_take isl_space
*space
,
13864 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
13866 isl_basic_map
*bmap
= NULL
;
13870 total
= isl_space_dim(space
, isl_dim_all
);
13872 isl_space_check_range(space
, type1
, pos1
, 1) < 0 ||
13873 isl_space_check_range(space
, type2
, pos2
, 1) < 0)
13876 if (type1
== type2
&& pos1
== pos2
)
13877 return isl_basic_map_universe(space
);
13879 bmap
= isl_basic_map_alloc_space(isl_space_copy(space
), 0, 1, 0);
13880 i
= isl_basic_map_alloc_equality(bmap
);
13883 isl_seq_clr(bmap
->eq
[i
], 1 + total
);
13884 pos1
+= isl_basic_map_offset(bmap
, type1
);
13885 pos2
+= isl_basic_map_offset(bmap
, type2
);
13886 isl_int_set_si(bmap
->eq
[i
][pos1
], -1);
13887 isl_int_set_si(bmap
->eq
[i
][pos2
], 1);
13888 bmap
= isl_basic_map_finalize(bmap
);
13889 isl_space_free(space
);
13892 isl_space_free(space
);
13893 isl_basic_map_free(bmap
);
13897 /* Add a constraint imposing that the given two dimensions are equal.
13899 __isl_give isl_basic_map
*isl_basic_map_equate(__isl_take isl_basic_map
*bmap
,
13900 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
13904 eq
= equator(isl_basic_map_get_space(bmap
), type1
, pos1
, type2
, pos2
);
13906 bmap
= isl_basic_map_intersect(bmap
, eq
);
13911 /* Add a constraint imposing that the given two dimensions are equal.
13913 __isl_give isl_map
*isl_map_equate(__isl_take isl_map
*map
,
13914 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
13916 isl_basic_map
*bmap
;
13918 bmap
= equator(isl_map_get_space(map
), type1
, pos1
, type2
, pos2
);
13920 map
= isl_map_intersect(map
, isl_map_from_basic_map(bmap
));
13925 /* Add a constraint imposing that the given two dimensions have opposite values.
13927 __isl_give isl_map
*isl_map_oppose(__isl_take isl_map
*map
,
13928 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
13930 isl_basic_map
*bmap
= NULL
;
13934 if (isl_map_check_range(map
, type1
, pos1
, 1) < 0)
13935 return isl_map_free(map
);
13936 if (isl_map_check_range(map
, type2
, pos2
, 1) < 0)
13937 return isl_map_free(map
);
13939 total
= isl_map_dim(map
, isl_dim_all
);
13941 return isl_map_free(map
);
13942 bmap
= isl_basic_map_alloc_space(isl_map_get_space(map
), 0, 1, 0);
13943 i
= isl_basic_map_alloc_equality(bmap
);
13946 isl_seq_clr(bmap
->eq
[i
], 1 + total
);
13947 pos1
+= isl_basic_map_offset(bmap
, type1
);
13948 pos2
+= isl_basic_map_offset(bmap
, type2
);
13949 isl_int_set_si(bmap
->eq
[i
][pos1
], 1);
13950 isl_int_set_si(bmap
->eq
[i
][pos2
], 1);
13951 bmap
= isl_basic_map_finalize(bmap
);
13953 map
= isl_map_intersect(map
, isl_map_from_basic_map(bmap
));
13957 isl_basic_map_free(bmap
);
13962 /* Construct a constraint imposing that the value of the first dimension is
13963 * greater than or equal to that of the second.
13965 static __isl_give isl_constraint
*constraint_order_ge(
13966 __isl_take isl_space
*space
, enum isl_dim_type type1
, int pos1
,
13967 enum isl_dim_type type2
, int pos2
)
13971 if (isl_space_check_range(space
, type1
, pos1
, 1) < 0 ||
13972 isl_space_check_range(space
, type2
, pos2
, 1) < 0)
13973 space
= isl_space_free(space
);
13977 c
= isl_constraint_alloc_inequality(isl_local_space_from_space(space
));
13979 if (type1
== type2
&& pos1
== pos2
)
13982 c
= isl_constraint_set_coefficient_si(c
, type1
, pos1
, 1);
13983 c
= isl_constraint_set_coefficient_si(c
, type2
, pos2
, -1);
13988 /* Add a constraint imposing that the value of the first dimension is
13989 * greater than or equal to that of the second.
13991 __isl_give isl_basic_map
*isl_basic_map_order_ge(__isl_take isl_basic_map
*bmap
,
13992 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
13997 if (type1
== type2
&& pos1
== pos2
)
13999 space
= isl_basic_map_get_space(bmap
);
14000 c
= constraint_order_ge(space
, type1
, pos1
, type2
, pos2
);
14001 bmap
= isl_basic_map_add_constraint(bmap
, c
);
14006 /* Add a constraint imposing that the value of the first dimension is
14007 * greater than or equal to that of the second.
14009 __isl_give isl_map
*isl_map_order_ge(__isl_take isl_map
*map
,
14010 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
14015 if (type1
== type2
&& pos1
== pos2
)
14017 space
= isl_map_get_space(map
);
14018 c
= constraint_order_ge(space
, type1
, pos1
, type2
, pos2
);
14019 map
= isl_map_add_constraint(map
, c
);
14024 /* Add a constraint imposing that the value of the first dimension is
14025 * less than or equal to that of the second.
14027 __isl_give isl_map
*isl_map_order_le(__isl_take isl_map
*map
,
14028 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
14030 return isl_map_order_ge(map
, type2
, pos2
, type1
, pos1
);
14033 /* Construct a basic map where the value of the first dimension is
14034 * greater than that of the second.
14036 static __isl_give isl_basic_map
*greator(__isl_take isl_space
*space
,
14037 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
14039 isl_basic_map
*bmap
= NULL
;
14043 if (isl_space_check_range(space
, type1
, pos1
, 1) < 0 ||
14044 isl_space_check_range(space
, type2
, pos2
, 1) < 0)
14047 if (type1
== type2
&& pos1
== pos2
)
14048 return isl_basic_map_empty(space
);
14050 bmap
= isl_basic_map_alloc_space(space
, 0, 0, 1);
14051 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
14052 i
= isl_basic_map_alloc_inequality(bmap
);
14053 if (total
< 0 || i
< 0)
14054 return isl_basic_map_free(bmap
);
14055 isl_seq_clr(bmap
->ineq
[i
], 1 + total
);
14056 pos1
+= isl_basic_map_offset(bmap
, type1
);
14057 pos2
+= isl_basic_map_offset(bmap
, type2
);
14058 isl_int_set_si(bmap
->ineq
[i
][pos1
], 1);
14059 isl_int_set_si(bmap
->ineq
[i
][pos2
], -1);
14060 isl_int_set_si(bmap
->ineq
[i
][0], -1);
14061 bmap
= isl_basic_map_finalize(bmap
);
14065 isl_space_free(space
);
14066 isl_basic_map_free(bmap
);
14070 /* Add a constraint imposing that the value of the first dimension is
14071 * greater than that of the second.
14073 __isl_give isl_basic_map
*isl_basic_map_order_gt(__isl_take isl_basic_map
*bmap
,
14074 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
14078 gt
= greator(isl_basic_map_get_space(bmap
), type1
, pos1
, type2
, pos2
);
14080 bmap
= isl_basic_map_intersect(bmap
, gt
);
14085 /* Add a constraint imposing that the value of the first dimension is
14086 * greater than that of the second.
14088 __isl_give isl_map
*isl_map_order_gt(__isl_take isl_map
*map
,
14089 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
14091 isl_basic_map
*bmap
;
14093 bmap
= greator(isl_map_get_space(map
), type1
, pos1
, type2
, pos2
);
14095 map
= isl_map_intersect(map
, isl_map_from_basic_map(bmap
));
14100 /* Add a constraint imposing that the value of the first dimension is
14101 * smaller than that of the second.
14103 __isl_give isl_map
*isl_map_order_lt(__isl_take isl_map
*map
,
14104 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
14106 return isl_map_order_gt(map
, type2
, pos2
, type1
, pos1
);
14109 __isl_give isl_aff
*isl_basic_map_get_div(__isl_keep isl_basic_map
*bmap
,
14113 isl_local_space
*ls
;
14118 if (!isl_basic_map_divs_known(bmap
))
14119 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
14120 "some divs are unknown", return NULL
);
14122 ls
= isl_basic_map_get_local_space(bmap
);
14123 div
= isl_local_space_get_div(ls
, pos
);
14124 isl_local_space_free(ls
);
14129 __isl_give isl_aff
*isl_basic_set_get_div(__isl_keep isl_basic_set
*bset
,
14132 return isl_basic_map_get_div(bset
, pos
);
14135 /* Plug in "subs" for set dimension "pos" of "set".
14137 __isl_give isl_set
*isl_set_substitute(__isl_take isl_set
*set
,
14138 unsigned pos
, __isl_keep isl_aff
*subs
)
14142 if (set
&& isl_set_plain_is_empty(set
))
14145 ma
= isl_multi_aff_identity_on_domain_space(isl_set_get_space(set
));
14146 ma
= isl_multi_aff_set_aff(ma
, pos
, isl_aff_copy(subs
));
14147 return isl_set_preimage_multi_aff(set
, ma
);
14150 /* Check if the range of "ma" is compatible with the domain or range
14151 * (depending on "type") of "bmap".
14153 static isl_stat
check_basic_map_compatible_range_multi_aff(
14154 __isl_keep isl_basic_map
*bmap
, enum isl_dim_type type
,
14155 __isl_keep isl_multi_aff
*ma
)
14158 isl_space
*ma_space
;
14160 ma_space
= isl_multi_aff_get_space(ma
);
14162 m
= isl_space_has_equal_params(bmap
->dim
, ma_space
);
14166 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
14167 "parameters don't match", goto error
);
14168 m
= isl_space_tuple_is_equal(bmap
->dim
, type
, ma_space
, isl_dim_out
);
14172 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
14173 "spaces don't match", goto error
);
14175 isl_space_free(ma_space
);
14176 return isl_stat_ok
;
14178 isl_space_free(ma_space
);
14179 return isl_stat_error
;
14182 /* Copy the divs from "ma" to "bmap", adding zeros for the "n_before"
14183 * coefficients before the transformed range of dimensions,
14184 * the "n_after" coefficients after the transformed range of dimensions
14185 * and the coefficients of the other divs in "bmap".
14187 static __isl_give isl_basic_map
*set_ma_divs(__isl_take isl_basic_map
*bmap
,
14188 __isl_keep isl_multi_aff
*ma
, int n_before
, int n_after
, int n_div
)
14193 isl_local_space
*ls
;
14198 ls
= isl_aff_get_domain_local_space(ma
->u
.p
[0]);
14199 n_param
= isl_local_space_dim(ls
, isl_dim_param
);
14200 n_set
= isl_local_space_dim(ls
, isl_dim_set
);
14201 if (n_param
< 0 || n_set
< 0)
14202 return isl_basic_map_free(bmap
);
14204 for (i
= 0; i
< n_div
; ++i
) {
14205 int o_bmap
= 0, o_ls
= 0;
14207 isl_seq_cpy(bmap
->div
[i
], ls
->div
->row
[i
], 1 + 1 + n_param
);
14208 o_bmap
+= 1 + 1 + n_param
;
14209 o_ls
+= 1 + 1 + n_param
;
14210 isl_seq_clr(bmap
->div
[i
] + o_bmap
, n_before
);
14211 o_bmap
+= n_before
;
14212 isl_seq_cpy(bmap
->div
[i
] + o_bmap
,
14213 ls
->div
->row
[i
] + o_ls
, n_set
);
14216 isl_seq_clr(bmap
->div
[i
] + o_bmap
, n_after
);
14218 isl_seq_cpy(bmap
->div
[i
] + o_bmap
,
14219 ls
->div
->row
[i
] + o_ls
, n_div
);
14222 isl_seq_clr(bmap
->div
[i
] + o_bmap
, bmap
->n_div
- n_div
);
14223 bmap
= isl_basic_map_add_div_constraints(bmap
, i
);
14228 isl_local_space_free(ls
);
14231 isl_local_space_free(ls
);
14232 return isl_basic_map_free(bmap
);
14235 /* How many stride constraints does "ma" enforce?
14236 * That is, how many of the affine expressions have a denominator
14237 * different from one?
14239 static int multi_aff_strides(__isl_keep isl_multi_aff
*ma
)
14244 for (i
= 0; i
< ma
->n
; ++i
)
14245 if (!isl_int_is_one(ma
->u
.p
[i
]->v
->el
[0]))
14251 /* For each affine expression in ma of the form
14253 * x_i = (f_i y + h_i)/m_i
14255 * with m_i different from one, add a constraint to "bmap"
14258 * f_i y + h_i = m_i alpha_i
14260 * with alpha_i an additional existentially quantified variable.
14262 * The input variables of "ma" correspond to a subset of the variables
14263 * of "bmap". There are "n_before" variables in "bmap" before this
14264 * subset and "n_after" variables after this subset.
14265 * The integer divisions of the affine expressions in "ma" are assumed
14266 * to have been aligned. There are "n_div_ma" of them and
14267 * they appear first in "bmap", straight after the "n_after" variables.
14269 static __isl_give isl_basic_map
*add_ma_strides(
14270 __isl_take isl_basic_map
*bmap
, __isl_keep isl_multi_aff
*ma
,
14271 int n_before
, int n_after
, int n_div_ma
)
14279 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
14280 n_param
= isl_multi_aff_dim(ma
, isl_dim_param
);
14281 n_in
= isl_multi_aff_dim(ma
, isl_dim_in
);
14282 if (total
< 0 || n_param
< 0 || n_in
< 0)
14283 return isl_basic_map_free(bmap
);
14284 for (i
= 0; i
< ma
->n
; ++i
) {
14285 int o_bmap
= 0, o_ma
= 1;
14287 if (isl_int_is_one(ma
->u
.p
[i
]->v
->el
[0]))
14289 div
= isl_basic_map_alloc_div(bmap
);
14290 k
= isl_basic_map_alloc_equality(bmap
);
14291 if (div
< 0 || k
< 0)
14293 isl_int_set_si(bmap
->div
[div
][0], 0);
14294 isl_seq_cpy(bmap
->eq
[k
] + o_bmap
,
14295 ma
->u
.p
[i
]->v
->el
+ o_ma
, 1 + n_param
);
14296 o_bmap
+= 1 + n_param
;
14297 o_ma
+= 1 + n_param
;
14298 isl_seq_clr(bmap
->eq
[k
] + o_bmap
, n_before
);
14299 o_bmap
+= n_before
;
14300 isl_seq_cpy(bmap
->eq
[k
] + o_bmap
,
14301 ma
->u
.p
[i
]->v
->el
+ o_ma
, n_in
);
14304 isl_seq_clr(bmap
->eq
[k
] + o_bmap
, n_after
);
14306 isl_seq_cpy(bmap
->eq
[k
] + o_bmap
,
14307 ma
->u
.p
[i
]->v
->el
+ o_ma
, n_div_ma
);
14308 o_bmap
+= n_div_ma
;
14310 isl_seq_clr(bmap
->eq
[k
] + o_bmap
, 1 + total
- o_bmap
);
14311 isl_int_neg(bmap
->eq
[k
][1 + total
], ma
->u
.p
[i
]->v
->el
[0]);
14317 isl_basic_map_free(bmap
);
14321 /* Replace the domain or range space (depending on "type) of "space" by "set".
14323 static __isl_give isl_space
*isl_space_set(__isl_take isl_space
*space
,
14324 enum isl_dim_type type
, __isl_take isl_space
*set
)
14326 if (type
== isl_dim_in
) {
14327 space
= isl_space_range(space
);
14328 space
= isl_space_map_from_domain_and_range(set
, space
);
14330 space
= isl_space_domain(space
);
14331 space
= isl_space_map_from_domain_and_range(space
, set
);
14337 /* Compute the preimage of the domain or range (depending on "type")
14338 * of "bmap" under the function represented by "ma".
14339 * In other words, plug in "ma" in the domain or range of "bmap".
14340 * The result is a basic map that lives in the same space as "bmap"
14341 * except that the domain or range has been replaced by
14342 * the domain space of "ma".
14344 * If bmap is represented by
14346 * A(p) + S u + B x + T v + C(divs) >= 0,
14348 * where u and x are input and output dimensions if type == isl_dim_out
14349 * while x and v are input and output dimensions if type == isl_dim_in,
14350 * and ma is represented by
14352 * x = D(p) + F(y) + G(divs')
14354 * then the result is
14356 * A(p) + B D(p) + S u + B F(y) + T v + B G(divs') + C(divs) >= 0
14358 * The divs in the input set are similarly adjusted.
14361 * floor((a_i(p) + s u + b_i x + t v + c_i(divs))/n_i)
14365 * floor((a_i(p) + b_i D(p) + s u + b_i F(y) + t v +
14366 * B_i G(divs') + c_i(divs))/n_i)
14368 * If bmap is not a rational map and if F(y) involves any denominators
14370 * x_i = (f_i y + h_i)/m_i
14372 * then additional constraints are added to ensure that we only
14373 * map back integer points. That is we enforce
14375 * f_i y + h_i = m_i alpha_i
14377 * with alpha_i an additional existentially quantified variable.
14379 * We first copy over the divs from "ma".
14380 * Then we add the modified constraints and divs from "bmap".
14381 * Finally, we add the stride constraints, if needed.
14383 __isl_give isl_basic_map
*isl_basic_map_preimage_multi_aff(
14384 __isl_take isl_basic_map
*bmap
, enum isl_dim_type type
,
14385 __isl_take isl_multi_aff
*ma
)
14389 isl_basic_map
*res
= NULL
;
14390 isl_size n_before
, n_after
, n_div_bmap
, n_div_ma
;
14391 isl_int f
, c1
, c2
, g
;
14400 ma
= isl_multi_aff_align_divs(ma
);
14403 if (check_basic_map_compatible_range_multi_aff(bmap
, type
, ma
) < 0)
14406 if (type
== isl_dim_in
) {
14408 n_after
= isl_basic_map_dim(bmap
, isl_dim_out
);
14410 n_before
= isl_basic_map_dim(bmap
, isl_dim_in
);
14413 n_div_bmap
= isl_basic_map_dim(bmap
, isl_dim_div
);
14414 n_div_ma
= ma
->n
? isl_aff_dim(ma
->u
.p
[0], isl_dim_div
) : 0;
14415 if (n_before
< 0 || n_after
< 0 || n_div_bmap
< 0 || n_div_ma
< 0)
14418 space
= isl_multi_aff_get_domain_space(ma
);
14419 space
= isl_space_set(isl_basic_map_get_space(bmap
), type
, space
);
14420 rational
= isl_basic_map_is_rational(bmap
);
14421 strides
= rational
? 0 : multi_aff_strides(ma
);
14422 res
= isl_basic_map_alloc_space(space
, n_div_ma
+ n_div_bmap
+ strides
,
14423 bmap
->n_eq
+ strides
, bmap
->n_ineq
+ 2 * n_div_ma
);
14425 res
= isl_basic_map_set_rational(res
);
14427 for (i
= 0; i
< n_div_ma
+ n_div_bmap
; ++i
)
14428 if (isl_basic_map_alloc_div(res
) < 0)
14431 res
= set_ma_divs(res
, ma
, n_before
, n_after
, n_div_ma
);
14435 for (i
= 0; i
< bmap
->n_eq
; ++i
) {
14436 k
= isl_basic_map_alloc_equality(res
);
14439 if (isl_seq_preimage(res
->eq
[k
], bmap
->eq
[i
], ma
, n_before
,
14440 n_after
, n_div_ma
, n_div_bmap
,
14441 f
, c1
, c2
, g
, 0) < 0)
14445 for (i
= 0; i
< bmap
->n_ineq
; ++i
) {
14446 k
= isl_basic_map_alloc_inequality(res
);
14449 if (isl_seq_preimage(res
->ineq
[k
], bmap
->ineq
[i
], ma
, n_before
,
14450 n_after
, n_div_ma
, n_div_bmap
,
14451 f
, c1
, c2
, g
, 0) < 0)
14455 for (i
= 0; i
< bmap
->n_div
; ++i
) {
14456 if (isl_int_is_zero(bmap
->div
[i
][0])) {
14457 isl_int_set_si(res
->div
[n_div_ma
+ i
][0], 0);
14460 if (isl_seq_preimage(res
->div
[n_div_ma
+ i
], bmap
->div
[i
], ma
,
14461 n_before
, n_after
, n_div_ma
, n_div_bmap
,
14462 f
, c1
, c2
, g
, 1) < 0)
14467 res
= add_ma_strides(res
, ma
, n_before
, n_after
, n_div_ma
);
14473 isl_basic_map_free(bmap
);
14474 isl_multi_aff_free(ma
);
14475 res
= isl_basic_map_simplify(res
);
14476 return isl_basic_map_finalize(res
);
14482 isl_basic_map_free(bmap
);
14483 isl_multi_aff_free(ma
);
14484 isl_basic_map_free(res
);
14488 /* Compute the preimage of "bset" under the function represented by "ma".
14489 * In other words, plug in "ma" in "bset". The result is a basic set
14490 * that lives in the domain space of "ma".
14492 __isl_give isl_basic_set
*isl_basic_set_preimage_multi_aff(
14493 __isl_take isl_basic_set
*bset
, __isl_take isl_multi_aff
*ma
)
14495 return isl_basic_map_preimage_multi_aff(bset
, isl_dim_set
, ma
);
14498 /* Compute the preimage of the domain of "bmap" under the function
14499 * represented by "ma".
14500 * In other words, plug in "ma" in the domain of "bmap".
14501 * The result is a basic map that lives in the same space as "bmap"
14502 * except that the domain has been replaced by the domain space of "ma".
14504 __isl_give isl_basic_map
*isl_basic_map_preimage_domain_multi_aff(
14505 __isl_take isl_basic_map
*bmap
, __isl_take isl_multi_aff
*ma
)
14507 return isl_basic_map_preimage_multi_aff(bmap
, isl_dim_in
, ma
);
14510 /* Compute the preimage of the range of "bmap" under the function
14511 * represented by "ma".
14512 * In other words, plug in "ma" in the range of "bmap".
14513 * The result is a basic map that lives in the same space as "bmap"
14514 * except that the range has been replaced by the domain space of "ma".
14516 __isl_give isl_basic_map
*isl_basic_map_preimage_range_multi_aff(
14517 __isl_take isl_basic_map
*bmap
, __isl_take isl_multi_aff
*ma
)
14519 return isl_basic_map_preimage_multi_aff(bmap
, isl_dim_out
, ma
);
14522 /* Check if the range of "ma" is compatible with the domain or range
14523 * (depending on "type") of "map".
14524 * Return isl_stat_error if anything is wrong.
14526 static isl_stat
check_map_compatible_range_multi_aff(
14527 __isl_keep isl_map
*map
, enum isl_dim_type type
,
14528 __isl_keep isl_multi_aff
*ma
)
14531 isl_space
*ma_space
;
14533 ma_space
= isl_multi_aff_get_space(ma
);
14534 m
= isl_map_space_tuple_is_equal(map
, type
, ma_space
, isl_dim_out
);
14535 isl_space_free(ma_space
);
14537 return isl_stat_error
;
14539 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
14540 "spaces don't match", return isl_stat_error
);
14541 return isl_stat_ok
;
14544 /* Compute the preimage of the domain or range (depending on "type")
14545 * of "map" under the function represented by "ma".
14546 * In other words, plug in "ma" in the domain or range of "map".
14547 * The result is a map that lives in the same space as "map"
14548 * except that the domain or range has been replaced by
14549 * the domain space of "ma".
14551 * The parameters are assumed to have been aligned.
14553 static __isl_give isl_map
*map_preimage_multi_aff(__isl_take isl_map
*map
,
14554 enum isl_dim_type type
, __isl_take isl_multi_aff
*ma
)
14559 map
= isl_map_cow(map
);
14560 ma
= isl_multi_aff_align_divs(ma
);
14563 if (check_map_compatible_range_multi_aff(map
, type
, ma
) < 0)
14566 for (i
= 0; i
< map
->n
; ++i
) {
14567 map
->p
[i
] = isl_basic_map_preimage_multi_aff(map
->p
[i
], type
,
14568 isl_multi_aff_copy(ma
));
14573 space
= isl_multi_aff_get_domain_space(ma
);
14574 space
= isl_space_set(isl_map_get_space(map
), type
, space
);
14576 isl_space_free(isl_map_take_space(map
));
14577 map
= isl_map_restore_space(map
, space
);
14581 isl_multi_aff_free(ma
);
14583 ISL_F_CLR(map
, ISL_MAP_DISJOINT
);
14584 ISL_F_CLR(map
, ISL_SET_NORMALIZED
);
14587 isl_multi_aff_free(ma
);
14592 /* Compute the preimage of the domain or range (depending on "type")
14593 * of "map" under the function represented by "ma".
14594 * In other words, plug in "ma" in the domain or range of "map".
14595 * The result is a map that lives in the same space as "map"
14596 * except that the domain or range has been replaced by
14597 * the domain space of "ma".
14599 __isl_give isl_map
*isl_map_preimage_multi_aff(__isl_take isl_map
*map
,
14600 enum isl_dim_type type
, __isl_take isl_multi_aff
*ma
)
14607 aligned
= isl_map_space_has_equal_params(map
, ma
->space
);
14611 return map_preimage_multi_aff(map
, type
, ma
);
14613 if (isl_map_check_named_params(map
) < 0)
14615 if (!isl_space_has_named_params(ma
->space
))
14616 isl_die(map
->ctx
, isl_error_invalid
,
14617 "unaligned unnamed parameters", goto error
);
14618 map
= isl_map_align_params(map
, isl_multi_aff_get_space(ma
));
14619 ma
= isl_multi_aff_align_params(ma
, isl_map_get_space(map
));
14621 return map_preimage_multi_aff(map
, type
, ma
);
14623 isl_multi_aff_free(ma
);
14624 return isl_map_free(map
);
14627 /* Compute the preimage of "set" under the function represented by "ma".
14628 * In other words, plug in "ma" in "set". The result is a set
14629 * that lives in the domain space of "ma".
14631 __isl_give isl_set
*isl_set_preimage_multi_aff(__isl_take isl_set
*set
,
14632 __isl_take isl_multi_aff
*ma
)
14634 return isl_map_preimage_multi_aff(set
, isl_dim_set
, ma
);
14637 /* Compute the preimage of the domain of "map" under the function
14638 * represented by "ma".
14639 * In other words, plug in "ma" in the domain of "map".
14640 * The result is a map that lives in the same space as "map"
14641 * except that the domain has been replaced by the domain space of "ma".
14643 __isl_give isl_map
*isl_map_preimage_domain_multi_aff(__isl_take isl_map
*map
,
14644 __isl_take isl_multi_aff
*ma
)
14646 return isl_map_preimage_multi_aff(map
, isl_dim_in
, ma
);
14649 /* Compute the preimage of the range of "map" under the function
14650 * represented by "ma".
14651 * In other words, plug in "ma" in the range of "map".
14652 * The result is a map that lives in the same space as "map"
14653 * except that the range has been replaced by the domain space of "ma".
14655 __isl_give isl_map
*isl_map_preimage_range_multi_aff(__isl_take isl_map
*map
,
14656 __isl_take isl_multi_aff
*ma
)
14658 return isl_map_preimage_multi_aff(map
, isl_dim_out
, ma
);
14661 /* Compute the preimage of "map" under the function represented by "pma".
14662 * In other words, plug in "pma" in the domain or range of "map".
14663 * The result is a map that lives in the same space as "map",
14664 * except that the space of type "type" has been replaced by
14665 * the domain space of "pma".
14667 * The parameters of "map" and "pma" are assumed to have been aligned.
14669 static __isl_give isl_map
*isl_map_preimage_pw_multi_aff_aligned(
14670 __isl_take isl_map
*map
, enum isl_dim_type type
,
14671 __isl_take isl_pw_multi_aff
*pma
)
14682 space
= isl_pw_multi_aff_get_domain_space(pma
);
14683 isl_pw_multi_aff_free(pma
);
14684 space
= isl_space_set(isl_map_get_space(map
), type
, space
);
14686 return isl_map_empty(space
);
14689 res
= isl_map_preimage_multi_aff(isl_map_copy(map
), type
,
14690 isl_multi_aff_copy(pma
->p
[0].maff
));
14691 if (type
== isl_dim_in
)
14692 res
= isl_map_intersect_domain(res
,
14693 isl_map_copy(pma
->p
[0].set
));
14695 res
= isl_map_intersect_range(res
,
14696 isl_map_copy(pma
->p
[0].set
));
14698 for (i
= 1; i
< pma
->n
; ++i
) {
14701 res_i
= isl_map_preimage_multi_aff(isl_map_copy(map
), type
,
14702 isl_multi_aff_copy(pma
->p
[i
].maff
));
14703 if (type
== isl_dim_in
)
14704 res_i
= isl_map_intersect_domain(res_i
,
14705 isl_map_copy(pma
->p
[i
].set
));
14707 res_i
= isl_map_intersect_range(res_i
,
14708 isl_map_copy(pma
->p
[i
].set
));
14709 res
= isl_map_union(res
, res_i
);
14712 isl_pw_multi_aff_free(pma
);
14716 isl_pw_multi_aff_free(pma
);
14721 /* Compute the preimage of "map" under the function represented by "pma".
14722 * In other words, plug in "pma" in the domain or range of "map".
14723 * The result is a map that lives in the same space as "map",
14724 * except that the space of type "type" has been replaced by
14725 * the domain space of "pma".
14727 __isl_give isl_map
*isl_map_preimage_pw_multi_aff(__isl_take isl_map
*map
,
14728 enum isl_dim_type type
, __isl_take isl_pw_multi_aff
*pma
)
14735 aligned
= isl_map_space_has_equal_params(map
, pma
->dim
);
14739 return isl_map_preimage_pw_multi_aff_aligned(map
, type
, pma
);
14741 if (isl_map_check_named_params(map
) < 0)
14743 if (isl_pw_multi_aff_check_named_params(pma
) < 0)
14745 map
= isl_map_align_params(map
, isl_pw_multi_aff_get_space(pma
));
14746 pma
= isl_pw_multi_aff_align_params(pma
, isl_map_get_space(map
));
14748 return isl_map_preimage_pw_multi_aff_aligned(map
, type
, pma
);
14750 isl_pw_multi_aff_free(pma
);
14751 return isl_map_free(map
);
14754 /* Compute the preimage of "set" under the function represented by "pma".
14755 * In other words, plug in "pma" in "set". The result is a set
14756 * that lives in the domain space of "pma".
14758 __isl_give isl_set
*isl_set_preimage_pw_multi_aff(__isl_take isl_set
*set
,
14759 __isl_take isl_pw_multi_aff
*pma
)
14761 return isl_map_preimage_pw_multi_aff(set
, isl_dim_set
, pma
);
14764 /* Compute the preimage of the domain of "map" under the function
14765 * represented by "pma".
14766 * In other words, plug in "pma" in the domain of "map".
14767 * The result is a map that lives in the same space as "map",
14768 * except that domain space has been replaced by the domain space of "pma".
14770 __isl_give isl_map
*isl_map_preimage_domain_pw_multi_aff(
14771 __isl_take isl_map
*map
, __isl_take isl_pw_multi_aff
*pma
)
14773 return isl_map_preimage_pw_multi_aff(map
, isl_dim_in
, pma
);
14776 /* Compute the preimage of the range of "map" under the function
14777 * represented by "pma".
14778 * In other words, plug in "pma" in the range of "map".
14779 * The result is a map that lives in the same space as "map",
14780 * except that range space has been replaced by the domain space of "pma".
14782 __isl_give isl_map
*isl_map_preimage_range_pw_multi_aff(
14783 __isl_take isl_map
*map
, __isl_take isl_pw_multi_aff
*pma
)
14785 return isl_map_preimage_pw_multi_aff(map
, isl_dim_out
, pma
);
14788 /* Compute the preimage of "map" under the function represented by "mpa".
14789 * In other words, plug in "mpa" in the domain or range of "map".
14790 * The result is a map that lives in the same space as "map",
14791 * except that the space of type "type" has been replaced by
14792 * the domain space of "mpa".
14794 * If the map does not involve any constraints that refer to the
14795 * dimensions of the substituted space, then the only possible
14796 * effect of "mpa" on the map is to map the space to a different space.
14797 * We create a separate isl_multi_aff to effectuate this change
14798 * in order to avoid spurious splitting of the map along the pieces
14800 * If "mpa" has a non-trivial explicit domain, however,
14801 * then the full substitution should be performed.
14803 __isl_give isl_map
*isl_map_preimage_multi_pw_aff(__isl_take isl_map
*map
,
14804 enum isl_dim_type type
, __isl_take isl_multi_pw_aff
*mpa
)
14808 isl_pw_multi_aff
*pma
;
14810 n
= isl_map_dim(map
, type
);
14814 full
= isl_map_involves_dims(map
, type
, 0, n
);
14815 if (full
>= 0 && !full
)
14816 full
= isl_multi_pw_aff_has_non_trivial_domain(mpa
);
14823 space
= isl_multi_pw_aff_get_space(mpa
);
14824 isl_multi_pw_aff_free(mpa
);
14825 ma
= isl_multi_aff_zero(space
);
14826 return isl_map_preimage_multi_aff(map
, type
, ma
);
14829 pma
= isl_pw_multi_aff_from_multi_pw_aff(mpa
);
14830 return isl_map_preimage_pw_multi_aff(map
, type
, pma
);
14833 isl_multi_pw_aff_free(mpa
);
14837 /* Compute the preimage of "map" under the function represented by "mpa".
14838 * In other words, plug in "mpa" in the domain "map".
14839 * The result is a map that lives in the same space as "map",
14840 * except that domain space has been replaced by the domain space of "mpa".
14842 __isl_give isl_map
*isl_map_preimage_domain_multi_pw_aff(
14843 __isl_take isl_map
*map
, __isl_take isl_multi_pw_aff
*mpa
)
14845 return isl_map_preimage_multi_pw_aff(map
, isl_dim_in
, mpa
);
14848 /* Compute the preimage of "set" by the function represented by "mpa".
14849 * In other words, plug in "mpa" in "set".
14851 __isl_give isl_set
*isl_set_preimage_multi_pw_aff(__isl_take isl_set
*set
,
14852 __isl_take isl_multi_pw_aff
*mpa
)
14854 return isl_map_preimage_multi_pw_aff(set
, isl_dim_set
, mpa
);
14857 /* Given that inequality "ineq" of "bmap" expresses an upper bound
14858 * on the output dimension "pos" in terms of the parameters,
14859 * the input dimensions and possibly some integer divisions,
14860 * but not any other output dimensions, extract this upper bound
14861 * as a function of all dimensions (with zero coefficients
14862 * for the output dimensions).
14864 * That is, the inequality is of the form
14866 * e(...) + c - m x >= 0
14868 * where e does not depend on any other output dimensions.
14869 * Return (e(...) + c) / m, with the denominator m in the first position.
14871 __isl_give isl_vec
*isl_basic_map_inequality_extract_output_upper_bound(
14872 __isl_keep isl_basic_map
*bmap
, int ineq
, int pos
)
14875 isl_size v_out
, total
;
14877 v_out
= isl_basic_map_var_offset(bmap
, isl_dim_out
);
14878 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
14879 if (v_out
< 0 || total
< 0)
14881 ctx
= isl_basic_map_get_ctx(bmap
);
14882 return extract_bound_from_constraint(ctx
, bmap
->ineq
[ineq
],
14883 total
, v_out
+ pos
);
14886 /* Is constraint "c" of "bmap" of the form
14888 * e(...) + c1 - m x >= 0
14892 * -e(...) + c2 + m x >= 0
14894 * where m > 1 and e does not involve any other output variables?
14896 * "v_out" is the offset to the output variables.
14897 * "d" is the position of x among the output variables.
14898 * "v_div" is the offset to the local variables.
14899 * "total" is the total number of variables.
14901 * Since the purpose of this function is to use the constraint
14902 * to express the output variable as an integer division,
14903 * do not allow the constraint to involve any local variables
14904 * that do not have an explicit representation.
14906 static isl_bool
is_potential_div_constraint(__isl_keep isl_basic_map
*bmap
,
14907 isl_int
*c
, int v_out
, int d
, int v_div
, int total
)
14911 if (isl_int_is_zero(c
[1 + v_out
+ d
]))
14912 return isl_bool_false
;
14913 if (isl_int_is_one(c
[1 + v_out
+ d
]))
14914 return isl_bool_false
;
14915 if (isl_int_is_negone(c
[1 + v_out
+ d
]))
14916 return isl_bool_false
;
14917 if (isl_seq_first_non_zero(c
+ 1 + v_out
, d
) != -1)
14918 return isl_bool_false
;
14919 if (isl_seq_first_non_zero(c
+ 1 + v_out
+ d
+ 1,
14920 v_div
- (v_out
+ d
+ 1)) != -1)
14921 return isl_bool_false
;
14922 for (i
= 0; v_div
+ i
< total
; ++i
) {
14923 isl_bool known
, involves
;
14925 if (isl_int_is_zero(c
[1 + v_div
+ i
]))
14927 known
= isl_basic_map_div_is_known(bmap
, i
);
14928 if (known
< 0 || !known
)
14930 involves
= div_involves_vars(bmap
, i
, v_out
, v_div
- v_out
);
14931 if (involves
< 0 || involves
)
14932 return isl_bool_not(involves
);
14934 return isl_bool_true
;
14937 /* Look for a pair of constraints
14939 * e(...) + c1 - m x >= 0 i.e., m x <= e(...) + c1
14943 * -e(...) + c2 + m x >= 0 i.e., m x >= e(...) - c2
14945 * that express that the output dimension x at position "pos"
14946 * is some integer division of an expression in terms of the parameters,
14947 * input dimensions and integer divisions.
14948 * If such a pair can be found, then return the index
14949 * of the upper bound constraint, m x <= e(...) + c1.
14950 * Otherwise, return an index beyond the number of constraints.
14952 * The constraints of "bmap" are assumed to have been sorted.
14954 * In order for the constraints above to express an integer division,
14955 * m needs to be greater than 1 and such that
14957 * c1 + c2 < m i.e., -c2 >= c1 - (m - 1)
14959 * In particular, this ensures that
14961 * x = floor((e(...) + c1) / m)
14963 isl_size
isl_basic_map_find_output_upper_div_constraint(
14964 __isl_keep isl_basic_map
*bmap
, int pos
)
14969 isl_size v_out
, v_div
;
14973 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
14974 v_out
= isl_basic_map_var_offset(bmap
, isl_dim_out
);
14975 v_div
= isl_basic_map_var_offset(bmap
, isl_dim_div
);
14976 n_ineq
= isl_basic_map_n_inequality(bmap
);
14977 if (total
< 0 || v_out
< 0 || v_div
< 0 || n_ineq
< 0)
14978 return isl_size_error
;
14981 for (i
= 0; i
< n_ineq
; ++i
) {
14982 isl_bool potential
;
14984 potential
= is_potential_div_constraint(bmap
, bmap
->ineq
[i
],
14985 v_out
, pos
, v_div
, total
);
14991 j
= find_later_constraint_in_pair(bmap
, i
, v_out
+ pos
, total
,
14992 bmap
->ineq
[i
][1 + v_out
+ pos
], &sum
);
14998 isl_int_clear(sum
);
15002 if (isl_int_is_pos(bmap
->ineq
[j
][1 + v_out
+ pos
]))
15007 isl_int_clear(sum
);
15008 return isl_size_error
;
15011 /* Return a copy of the equality constraints of "bset" as a matrix.
15013 __isl_give isl_mat
*isl_basic_set_extract_equalities(
15014 __isl_keep isl_basic_set
*bset
)
15019 total
= isl_basic_set_dim(bset
, isl_dim_all
);
15023 ctx
= isl_basic_set_get_ctx(bset
);
15024 return isl_mat_sub_alloc6(ctx
, bset
->eq
, 0, bset
->n_eq
, 0, 1 + total
);
15027 /* Are the "n" "coefficients" starting at "first" of the integer division
15028 * expressions at position "pos1" in "bmap1" and "pos2" in "bmap2" equal
15030 * The "coefficient" at position 0 is the denominator.
15031 * The "coefficient" at position 1 is the constant term.
15033 isl_bool
isl_basic_map_equal_div_expr_part(__isl_keep isl_basic_map
*bmap1
,
15034 int pos1
, __isl_keep isl_basic_map
*bmap2
, int pos2
,
15035 unsigned first
, unsigned n
)
15037 if (isl_basic_map_check_range(bmap1
, isl_dim_div
, pos1
, 1) < 0)
15038 return isl_bool_error
;
15039 if (isl_basic_map_check_range(bmap2
, isl_dim_div
, pos2
, 1) < 0)
15040 return isl_bool_error
;
15041 return isl_seq_eq(bmap1
->div
[pos1
] + first
,
15042 bmap2
->div
[pos2
] + first
, n
);
15045 /* Are the integer division expressions at position "pos1" in "bmap1" and
15046 * "pos2" in "bmap2" equal to each other, except that the constant terms
15049 isl_bool
isl_basic_map_equal_div_expr_except_constant(
15050 __isl_keep isl_basic_map
*bmap1
, int pos1
,
15051 __isl_keep isl_basic_map
*bmap2
, int pos2
)
15054 isl_size total
, total2
;
15056 total
= isl_basic_map_dim(bmap1
, isl_dim_all
);
15057 total2
= isl_basic_map_dim(bmap2
, isl_dim_all
);
15058 if (total
< 0 || total2
< 0)
15059 return isl_bool_error
;
15060 if (total
!= total2
)
15061 isl_die(isl_basic_map_get_ctx(bmap1
), isl_error_invalid
,
15062 "incomparable div expressions", return isl_bool_error
);
15063 equal
= isl_basic_map_equal_div_expr_part(bmap1
, pos1
, bmap2
, pos2
,
15065 if (equal
< 0 || !equal
)
15067 equal
= isl_basic_map_equal_div_expr_part(bmap1
, pos1
, bmap2
, pos2
,
15069 if (equal
< 0 || equal
)
15070 return isl_bool_not(equal
);
15071 return isl_basic_map_equal_div_expr_part(bmap1
, pos1
, bmap2
, pos2
,
15075 /* Replace the numerator of the constant term of the integer division
15076 * expression at position "div" in "bmap" by "value".
15077 * The caller guarantees that this does not change the meaning
15080 __isl_give isl_basic_map
*isl_basic_map_set_div_expr_constant_num_si_inplace(
15081 __isl_take isl_basic_map
*bmap
, int div
, int value
)
15083 if (isl_basic_map_check_range(bmap
, isl_dim_div
, div
, 1) < 0)
15084 return isl_basic_map_free(bmap
);
15086 isl_int_set_si(bmap
->div
[div
][1], value
);
15091 /* Is the point "inner" internal to inequality constraint "ineq"
15093 * The point is considered to be internal to the inequality constraint,
15094 * if it strictly lies on the positive side of the inequality constraint,
15095 * or if it lies on the constraint and the constraint is lexico-positive.
15097 static isl_bool
is_internal(__isl_keep isl_vec
*inner
,
15098 __isl_keep isl_basic_set
*bset
, int ineq
)
15104 if (!inner
|| !bset
)
15105 return isl_bool_error
;
15107 ctx
= isl_basic_set_get_ctx(bset
);
15108 isl_seq_inner_product(inner
->el
, bset
->ineq
[ineq
], inner
->size
,
15109 &ctx
->normalize_gcd
);
15110 if (!isl_int_is_zero(ctx
->normalize_gcd
))
15111 return isl_int_is_nonneg(ctx
->normalize_gcd
);
15113 total
= isl_basic_set_dim(bset
, isl_dim_all
);
15115 return isl_bool_error
;
15116 pos
= isl_seq_first_non_zero(bset
->ineq
[ineq
] + 1, total
);
15117 return isl_int_is_pos(bset
->ineq
[ineq
][1 + pos
]);
15120 /* Tighten the inequality constraints of "bset" that are outward with respect
15121 * to the point "vec".
15122 * That is, tighten the constraints that are not satisfied by "vec".
15124 * "vec" is a point internal to some superset S of "bset" that is used
15125 * to make the subsets of S disjoint, by tightening one half of the constraints
15126 * that separate two subsets. In particular, the constraints of S
15127 * are all satisfied by "vec" and should not be tightened.
15128 * Of the internal constraints, those that have "vec" on the outside
15129 * are tightened. The shared facet is included in the adjacent subset
15130 * with the opposite constraint.
15131 * For constraints that saturate "vec", this criterion cannot be used
15132 * to determine which of the two sides should be tightened.
15133 * Instead, the sign of the first non-zero coefficient is used
15134 * to make this choice. Note that this second criterion is never used
15135 * on the constraints of S since "vec" is interior to "S".
15137 __isl_give isl_basic_set
*isl_basic_set_tighten_outward(
15138 __isl_take isl_basic_set
*bset
, __isl_keep isl_vec
*vec
)
15142 bset
= isl_basic_set_cow(bset
);
15145 for (j
= 0; j
< bset
->n_ineq
; ++j
) {
15148 internal
= is_internal(vec
, bset
, j
);
15150 return isl_basic_set_free(bset
);
15153 isl_int_sub_ui(bset
->ineq
[j
][0], bset
->ineq
[j
][0], 1);
15159 /* Replace the variables x of type "type" starting at "first" in "bmap"
15160 * by x' with x = M x' with M the matrix trans.
15161 * That is, replace the corresponding coefficients c by c M.
15163 * The transformation matrix should be a square matrix.
15165 __isl_give isl_basic_map
*isl_basic_map_transform_dims(
15166 __isl_take isl_basic_map
*bmap
, enum isl_dim_type type
, unsigned first
,
15167 __isl_take isl_mat
*trans
)
15171 bmap
= isl_basic_map_cow(bmap
);
15172 if (!bmap
|| !trans
)
15175 if (trans
->n_row
!= trans
->n_col
)
15176 isl_die(trans
->ctx
, isl_error_invalid
,
15177 "expecting square transformation matrix", goto error
);
15178 if (isl_basic_map_check_range(bmap
, type
, first
, trans
->n_row
) < 0)
15181 pos
= isl_basic_map_offset(bmap
, type
) + first
;
15183 if (isl_mat_sub_transform(bmap
->eq
, bmap
->n_eq
, pos
,
15184 isl_mat_copy(trans
)) < 0)
15186 if (isl_mat_sub_transform(bmap
->ineq
, bmap
->n_ineq
, pos
,
15187 isl_mat_copy(trans
)) < 0)
15189 if (isl_mat_sub_transform(bmap
->div
, bmap
->n_div
, 1 + pos
,
15190 isl_mat_copy(trans
)) < 0)
15193 ISL_F_CLR(bmap
, ISL_BASIC_MAP_SORTED
);
15194 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NORMALIZED_DIVS
);
15195 ISL_F_CLR(bmap
, ISL_BASIC_MAP_REDUCED_COEFFICIENTS
);
15197 isl_mat_free(trans
);
15200 isl_mat_free(trans
);
15201 isl_basic_map_free(bmap
);
15205 /* Replace the variables x of type "type" starting at "first" in "bset"
15206 * by x' with x = M x' with M the matrix trans.
15207 * That is, replace the corresponding coefficients c by c M.
15209 * The transformation matrix should be a square matrix.
15211 __isl_give isl_basic_set
*isl_basic_set_transform_dims(
15212 __isl_take isl_basic_set
*bset
, enum isl_dim_type type
, unsigned first
,
15213 __isl_take isl_mat
*trans
)
15215 return isl_basic_map_transform_dims(bset
, type
, first
, trans
);