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
9 * Use of this software is governed by the MIT license
11 * Written by Sven Verdoolaege, K.U.Leuven, Departement
12 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
13 * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
14 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
15 * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
16 * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
17 * B.P. 105 - 78153 Le Chesnay, France
18 * and Centre de Recherche Inria de Paris, 2 rue Simone Iff - Voie DQ12,
19 * CS 42112, 75589 Paris Cedex 12, France
23 #include <isl_ctx_private.h>
24 #include <isl_map_private.h>
27 #include <isl/constraint.h>
28 #include "isl_space_private.h"
29 #include "isl_equalities.h"
30 #include <isl_lp_private.h>
34 #include <isl_reordering.h>
35 #include "isl_sample.h"
39 #include <isl_mat_private.h>
40 #include <isl_vec_private.h>
41 #include <isl_dim_map.h>
42 #include <isl_local_space_private.h>
43 #include <isl_aff_private.h>
44 #include <isl_options_private.h>
45 #include <isl_morph.h>
46 #include <isl_val_private.h>
47 #include <isl_printer_private.h>
49 #include <bset_to_bmap.c>
50 #include <bset_from_bmap.c>
51 #include <set_to_map.c>
52 #include <set_from_map.c>
54 /* Treat "bset" as a basic map.
55 * Internally, isl_basic_set is defined to isl_basic_map, so in practice,
56 * this function performs a redundant cast.
58 static __isl_keep
const isl_basic_map
*const_bset_to_bmap(
59 __isl_keep
const isl_basic_set
*bset
)
61 return (const isl_basic_map
*) bset
;
65 #define TYPE isl_basic_map
66 #include "has_single_reference_templ.c"
68 static unsigned pos(__isl_keep isl_space
*dim
, enum isl_dim_type type
)
71 case isl_dim_param
: return 1;
72 case isl_dim_in
: return 1 + dim
->nparam
;
73 case isl_dim_out
: return 1 + dim
->nparam
+ dim
->n_in
;
78 isl_size
isl_basic_map_dim(__isl_keep isl_basic_map
*bmap
,
79 enum isl_dim_type type
)
82 return isl_size_error
;
84 case isl_dim_cst
: return 1;
87 case isl_dim_out
: return isl_space_dim(bmap
->dim
, type
);
88 case isl_dim_div
: return bmap
->n_div
;
89 case isl_dim_all
: return isl_basic_map_total_dim(bmap
);
94 /* Return the space of "map".
96 __isl_keep isl_space
*isl_map_peek_space(__isl_keep
const isl_map
*map
)
98 return map
? map
->dim
: NULL
;
101 /* Return the space of "set".
103 __isl_keep isl_space
*isl_set_peek_space(__isl_keep isl_set
*set
)
105 return isl_map_peek_space(set_to_map(set
));
108 isl_size
isl_map_dim(__isl_keep isl_map
*map
, enum isl_dim_type type
)
110 return isl_space_dim(isl_map_peek_space(map
), type
);
113 isl_size
isl_set_dim(__isl_keep isl_set
*set
, enum isl_dim_type type
)
115 return isl_map_dim(set_to_map(set
), type
);
118 /* Return the position of the variables of the given type
119 * within the sequence of variables of "bmap".
121 isl_size
isl_basic_map_var_offset(__isl_keep isl_basic_map
*bmap
,
122 enum isl_dim_type type
)
126 space
= isl_basic_map_peek_space(bmap
);
128 return isl_size_error
;
133 case isl_dim_out
: return isl_space_offset(space
, type
);
134 case isl_dim_div
: return isl_space_dim(space
, isl_dim_all
);
137 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
138 "invalid dimension type", return isl_size_error
);
142 /* Return the position of the variables of the given type
143 * within the sequence of variables of "bset".
145 isl_size
isl_basic_set_var_offset(__isl_keep isl_basic_set
*bset
,
146 enum isl_dim_type type
)
148 return isl_basic_map_var_offset(bset_to_bmap(bset
), type
);
151 /* Return the position of the coefficients of the variables of the given type
152 * within the sequence of coefficients of "bmap".
154 unsigned isl_basic_map_offset(__isl_keep isl_basic_map
*bmap
,
155 enum isl_dim_type type
)
158 case isl_dim_cst
: return 0;
162 case isl_dim_div
: return 1 + isl_basic_map_var_offset(bmap
, type
);
167 unsigned isl_basic_set_offset(__isl_keep isl_basic_set
*bset
,
168 enum isl_dim_type type
)
170 return isl_basic_map_offset(bset
, type
);
173 static unsigned map_offset(__isl_keep isl_map
*map
, enum isl_dim_type type
)
175 return pos(map
->dim
, type
);
178 isl_size
isl_basic_set_dim(__isl_keep isl_basic_set
*bset
,
179 enum isl_dim_type type
)
181 return isl_basic_map_dim(bset
, type
);
184 isl_size
isl_basic_set_n_dim(__isl_keep isl_basic_set
*bset
)
186 return isl_basic_set_dim(bset
, isl_dim_set
);
189 isl_size
isl_basic_set_n_param(__isl_keep isl_basic_set
*bset
)
191 return isl_basic_set_dim(bset
, isl_dim_param
);
194 isl_size
isl_basic_set_total_dim(__isl_keep
const isl_basic_set
*bset
)
196 return isl_basic_map_total_dim(const_bset_to_bmap(bset
));
199 isl_size
isl_set_n_dim(__isl_keep isl_set
*set
)
201 return isl_set_dim(set
, isl_dim_set
);
204 isl_size
isl_set_n_param(__isl_keep isl_set
*set
)
206 return isl_set_dim(set
, isl_dim_param
);
209 isl_size
isl_basic_map_total_dim(__isl_keep
const isl_basic_map
*bmap
)
214 return isl_size_error
;
215 dim
= isl_space_dim(bmap
->dim
, isl_dim_all
);
217 return isl_size_error
;
218 return dim
+ bmap
->n_div
;
221 /* Return the number of equality constraints in the description of "bmap".
222 * Return -1 on error.
224 int isl_basic_map_n_equality(__isl_keep isl_basic_map
*bmap
)
231 /* Return the number of equality constraints in the description of "bset".
232 * Return -1 on error.
234 int isl_basic_set_n_equality(__isl_keep isl_basic_set
*bset
)
236 return isl_basic_map_n_equality(bset_to_bmap(bset
));
239 /* Return the number of inequality constraints in the description of "bmap".
240 * Return -1 on error.
242 int isl_basic_map_n_inequality(__isl_keep isl_basic_map
*bmap
)
249 /* Return the number of inequality constraints in the description of "bset".
250 * Return -1 on error.
252 int isl_basic_set_n_inequality(__isl_keep isl_basic_set
*bset
)
254 return isl_basic_map_n_inequality(bset_to_bmap(bset
));
257 /* Do "bmap1" and "bmap2" have the same parameters?
259 static isl_bool
isl_basic_map_has_equal_params(__isl_keep isl_basic_map
*bmap1
,
260 __isl_keep isl_basic_map
*bmap2
)
262 isl_space
*space1
, *space2
;
264 space1
= isl_basic_map_peek_space(bmap1
);
265 space2
= isl_basic_map_peek_space(bmap2
);
266 return isl_space_has_equal_params(space1
, space2
);
269 /* Do "map1" and "map2" have the same parameters?
271 isl_bool
isl_map_has_equal_params(__isl_keep isl_map
*map1
,
272 __isl_keep isl_map
*map2
)
274 isl_space
*space1
, *space2
;
276 space1
= isl_map_peek_space(map1
);
277 space2
= isl_map_peek_space(map2
);
278 return isl_space_has_equal_params(space1
, space2
);
281 /* Do "map" and "set" have the same parameters?
283 static isl_bool
isl_map_set_has_equal_params(__isl_keep isl_map
*map
,
284 __isl_keep isl_set
*set
)
286 return isl_map_has_equal_params(map
, set_to_map(set
));
289 isl_bool
isl_map_compatible_domain(__isl_keep isl_map
*map
,
290 __isl_keep isl_set
*set
)
294 return isl_bool_error
;
295 m
= isl_map_has_equal_params(map
, set_to_map(set
));
298 return isl_space_tuple_is_equal(map
->dim
, isl_dim_in
,
299 set
->dim
, isl_dim_set
);
302 isl_bool
isl_basic_map_compatible_domain(__isl_keep isl_basic_map
*bmap
,
303 __isl_keep isl_basic_set
*bset
)
307 return isl_bool_error
;
308 m
= isl_basic_map_has_equal_params(bmap
, bset_to_bmap(bset
));
311 return isl_space_tuple_is_equal(bmap
->dim
, isl_dim_in
,
312 bset
->dim
, isl_dim_set
);
315 isl_bool
isl_map_compatible_range(__isl_keep isl_map
*map
,
316 __isl_keep isl_set
*set
)
320 return isl_bool_error
;
321 m
= isl_map_has_equal_params(map
, set_to_map(set
));
324 return isl_space_tuple_is_equal(map
->dim
, isl_dim_out
,
325 set
->dim
, isl_dim_set
);
328 isl_bool
isl_basic_map_compatible_range(__isl_keep isl_basic_map
*bmap
,
329 __isl_keep isl_basic_set
*bset
)
333 return isl_bool_error
;
334 m
= isl_basic_map_has_equal_params(bmap
, bset_to_bmap(bset
));
337 return isl_space_tuple_is_equal(bmap
->dim
, isl_dim_out
,
338 bset
->dim
, isl_dim_set
);
341 isl_ctx
*isl_basic_map_get_ctx(__isl_keep isl_basic_map
*bmap
)
343 return bmap
? bmap
->ctx
: NULL
;
346 isl_ctx
*isl_basic_set_get_ctx(__isl_keep isl_basic_set
*bset
)
348 return bset
? bset
->ctx
: NULL
;
351 isl_ctx
*isl_map_get_ctx(__isl_keep isl_map
*map
)
353 return map
? map
->ctx
: NULL
;
356 isl_ctx
*isl_set_get_ctx(__isl_keep isl_set
*set
)
358 return set
? set
->ctx
: NULL
;
361 /* Return the space of "bmap".
363 __isl_keep isl_space
*isl_basic_map_peek_space(
364 __isl_keep
const isl_basic_map
*bmap
)
366 return bmap
? bmap
->dim
: NULL
;
369 /* Return the space of "bset".
371 __isl_keep isl_space
*isl_basic_set_peek_space(__isl_keep isl_basic_set
*bset
)
373 return isl_basic_map_peek_space(bset_to_bmap(bset
));
376 __isl_give isl_space
*isl_basic_map_get_space(__isl_keep isl_basic_map
*bmap
)
378 return isl_space_copy(isl_basic_map_peek_space(bmap
));
381 __isl_give isl_space
*isl_basic_set_get_space(__isl_keep isl_basic_set
*bset
)
383 return isl_basic_map_get_space(bset_to_bmap(bset
));
386 /* Extract the divs in "bmap" as a matrix.
388 __isl_give isl_mat
*isl_basic_map_get_divs(__isl_keep isl_basic_map
*bmap
)
396 v_div
= isl_basic_map_var_offset(bmap
, isl_dim_div
);
400 ctx
= isl_basic_map_get_ctx(bmap
);
401 cols
= 1 + 1 + v_div
+ bmap
->n_div
;
402 div
= isl_mat_alloc(ctx
, bmap
->n_div
, cols
);
406 for (i
= 0; i
< bmap
->n_div
; ++i
)
407 isl_seq_cpy(div
->row
[i
], bmap
->div
[i
], cols
);
412 /* Extract the divs in "bset" as a matrix.
414 __isl_give isl_mat
*isl_basic_set_get_divs(__isl_keep isl_basic_set
*bset
)
416 return isl_basic_map_get_divs(bset
);
419 __isl_give isl_local_space
*isl_basic_map_get_local_space(
420 __isl_keep isl_basic_map
*bmap
)
427 div
= isl_basic_map_get_divs(bmap
);
428 return isl_local_space_alloc_div(isl_space_copy(bmap
->dim
), div
);
431 __isl_give isl_local_space
*isl_basic_set_get_local_space(
432 __isl_keep isl_basic_set
*bset
)
434 return isl_basic_map_get_local_space(bset
);
437 /* For each known div d = floor(f/m), add the constraints
440 * -(f-(m-1)) + m d >= 0
442 * Do not finalize the result.
444 static __isl_give isl_basic_map
*add_known_div_constraints(
445 __isl_take isl_basic_map
*bmap
)
450 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
452 return isl_basic_map_free(bmap
);
455 bmap
= isl_basic_map_cow(bmap
);
456 bmap
= isl_basic_map_extend_constraints(bmap
, 0, 2 * n_div
);
459 for (i
= 0; i
< n_div
; ++i
) {
460 if (isl_int_is_zero(bmap
->div
[i
][0]))
462 bmap
= isl_basic_map_add_div_constraints(bmap
, i
);
468 __isl_give isl_basic_map
*isl_basic_map_from_local_space(
469 __isl_take isl_local_space
*ls
)
475 n_div
= isl_local_space_dim(ls
, isl_dim_div
);
477 ls
= isl_local_space_free(ls
);
481 bmap
= isl_basic_map_alloc_space(isl_local_space_get_space(ls
),
482 n_div
, 0, 2 * n_div
);
484 for (i
= 0; i
< n_div
; ++i
)
485 if (isl_basic_map_alloc_div(bmap
) < 0)
488 for (i
= 0; i
< n_div
; ++i
)
489 isl_seq_cpy(bmap
->div
[i
], ls
->div
->row
[i
], ls
->div
->n_col
);
490 bmap
= add_known_div_constraints(bmap
);
492 isl_local_space_free(ls
);
495 isl_local_space_free(ls
);
496 isl_basic_map_free(bmap
);
500 __isl_give isl_basic_set
*isl_basic_set_from_local_space(
501 __isl_take isl_local_space
*ls
)
503 return isl_basic_map_from_local_space(ls
);
506 __isl_give isl_space
*isl_map_get_space(__isl_keep isl_map
*map
)
508 return isl_space_copy(isl_map_peek_space(map
));
511 __isl_give isl_space
*isl_set_get_space(__isl_keep isl_set
*set
)
515 return isl_space_copy(set
->dim
);
518 __isl_give isl_basic_map
*isl_basic_map_set_tuple_name(
519 __isl_take isl_basic_map
*bmap
, enum isl_dim_type type
, const char *s
)
521 bmap
= isl_basic_map_cow(bmap
);
524 bmap
->dim
= isl_space_set_tuple_name(bmap
->dim
, type
, s
);
527 bmap
= isl_basic_map_finalize(bmap
);
530 isl_basic_map_free(bmap
);
534 __isl_give isl_basic_set
*isl_basic_set_set_tuple_name(
535 __isl_take isl_basic_set
*bset
, const char *s
)
537 return isl_basic_map_set_tuple_name(bset
, isl_dim_set
, s
);
540 const char *isl_basic_map_get_tuple_name(__isl_keep isl_basic_map
*bmap
,
541 enum isl_dim_type type
)
543 return bmap
? isl_space_get_tuple_name(bmap
->dim
, type
) : NULL
;
546 __isl_give isl_map
*isl_map_set_tuple_name(__isl_take isl_map
*map
,
547 enum isl_dim_type type
, const char *s
)
551 map
= isl_map_cow(map
);
555 map
->dim
= isl_space_set_tuple_name(map
->dim
, type
, s
);
559 for (i
= 0; i
< map
->n
; ++i
) {
560 map
->p
[i
] = isl_basic_map_set_tuple_name(map
->p
[i
], type
, s
);
571 /* Replace the identifier of the tuple of type "type" by "id".
573 __isl_give isl_basic_map
*isl_basic_map_set_tuple_id(
574 __isl_take isl_basic_map
*bmap
,
575 enum isl_dim_type type
, __isl_take isl_id
*id
)
577 bmap
= isl_basic_map_cow(bmap
);
580 bmap
->dim
= isl_space_set_tuple_id(bmap
->dim
, type
, id
);
582 return isl_basic_map_free(bmap
);
583 bmap
= isl_basic_map_finalize(bmap
);
590 /* Replace the identifier of the tuple by "id".
592 __isl_give isl_basic_set
*isl_basic_set_set_tuple_id(
593 __isl_take isl_basic_set
*bset
, __isl_take isl_id
*id
)
595 return isl_basic_map_set_tuple_id(bset
, isl_dim_set
, id
);
598 /* Does the input or output tuple have a name?
600 isl_bool
isl_map_has_tuple_name(__isl_keep isl_map
*map
, enum isl_dim_type type
)
602 return map
? isl_space_has_tuple_name(map
->dim
, type
) : isl_bool_error
;
605 const char *isl_map_get_tuple_name(__isl_keep isl_map
*map
,
606 enum isl_dim_type type
)
608 return map
? isl_space_get_tuple_name(map
->dim
, type
) : NULL
;
611 __isl_give isl_set
*isl_set_set_tuple_name(__isl_take isl_set
*set
,
614 return set_from_map(isl_map_set_tuple_name(set_to_map(set
),
618 __isl_give isl_map
*isl_map_set_tuple_id(__isl_take isl_map
*map
,
619 enum isl_dim_type type
, __isl_take isl_id
*id
)
621 map
= isl_map_cow(map
);
625 map
->dim
= isl_space_set_tuple_id(map
->dim
, type
, id
);
627 return isl_map_reset_space(map
, isl_space_copy(map
->dim
));
633 __isl_give isl_set
*isl_set_set_tuple_id(__isl_take isl_set
*set
,
634 __isl_take isl_id
*id
)
636 return isl_map_set_tuple_id(set
, isl_dim_set
, id
);
639 __isl_give isl_map
*isl_map_reset_tuple_id(__isl_take isl_map
*map
,
640 enum isl_dim_type type
)
642 map
= isl_map_cow(map
);
646 map
->dim
= isl_space_reset_tuple_id(map
->dim
, type
);
648 return isl_map_reset_space(map
, isl_space_copy(map
->dim
));
651 __isl_give isl_set
*isl_set_reset_tuple_id(__isl_take isl_set
*set
)
653 return isl_map_reset_tuple_id(set
, isl_dim_set
);
656 isl_bool
isl_map_has_tuple_id(__isl_keep isl_map
*map
, enum isl_dim_type type
)
658 return map
? isl_space_has_tuple_id(map
->dim
, type
) : isl_bool_error
;
661 __isl_give isl_id
*isl_map_get_tuple_id(__isl_keep isl_map
*map
,
662 enum isl_dim_type type
)
664 return map
? isl_space_get_tuple_id(map
->dim
, type
) : NULL
;
667 isl_bool
isl_set_has_tuple_id(__isl_keep isl_set
*set
)
669 return isl_map_has_tuple_id(set
, isl_dim_set
);
672 __isl_give isl_id
*isl_set_get_tuple_id(__isl_keep isl_set
*set
)
674 return isl_map_get_tuple_id(set
, isl_dim_set
);
677 /* Does the set tuple have a name?
679 isl_bool
isl_set_has_tuple_name(__isl_keep isl_set
*set
)
682 return isl_bool_error
;
683 return isl_space_has_tuple_name(set
->dim
, isl_dim_set
);
687 const char *isl_basic_set_get_tuple_name(__isl_keep isl_basic_set
*bset
)
689 return bset
? isl_space_get_tuple_name(bset
->dim
, isl_dim_set
) : NULL
;
692 const char *isl_set_get_tuple_name(__isl_keep isl_set
*set
)
694 return set
? isl_space_get_tuple_name(set
->dim
, isl_dim_set
) : NULL
;
697 const char *isl_basic_map_get_dim_name(__isl_keep isl_basic_map
*bmap
,
698 enum isl_dim_type type
, unsigned pos
)
700 return bmap
? isl_space_get_dim_name(bmap
->dim
, type
, pos
) : NULL
;
703 const char *isl_basic_set_get_dim_name(__isl_keep isl_basic_set
*bset
,
704 enum isl_dim_type type
, unsigned pos
)
706 return bset
? isl_space_get_dim_name(bset
->dim
, type
, pos
) : NULL
;
709 /* Does the given dimension have a name?
711 isl_bool
isl_map_has_dim_name(__isl_keep isl_map
*map
,
712 enum isl_dim_type type
, unsigned pos
)
715 return isl_bool_error
;
716 return isl_space_has_dim_name(map
->dim
, type
, pos
);
719 const char *isl_map_get_dim_name(__isl_keep isl_map
*map
,
720 enum isl_dim_type type
, unsigned pos
)
722 return map
? isl_space_get_dim_name(map
->dim
, type
, pos
) : NULL
;
725 const char *isl_set_get_dim_name(__isl_keep isl_set
*set
,
726 enum isl_dim_type type
, unsigned pos
)
728 return set
? isl_space_get_dim_name(set
->dim
, type
, pos
) : NULL
;
731 /* Does the given dimension have a name?
733 isl_bool
isl_set_has_dim_name(__isl_keep isl_set
*set
,
734 enum isl_dim_type type
, unsigned pos
)
737 return isl_bool_error
;
738 return isl_space_has_dim_name(set
->dim
, type
, pos
);
741 __isl_give isl_basic_map
*isl_basic_map_set_dim_name(
742 __isl_take isl_basic_map
*bmap
,
743 enum isl_dim_type type
, unsigned pos
, const char *s
)
745 bmap
= isl_basic_map_cow(bmap
);
748 bmap
->dim
= isl_space_set_dim_name(bmap
->dim
, type
, pos
, s
);
751 return isl_basic_map_finalize(bmap
);
753 isl_basic_map_free(bmap
);
757 __isl_give isl_map
*isl_map_set_dim_name(__isl_take isl_map
*map
,
758 enum isl_dim_type type
, unsigned pos
, const char *s
)
762 map
= isl_map_cow(map
);
766 map
->dim
= isl_space_set_dim_name(map
->dim
, type
, pos
, s
);
770 for (i
= 0; i
< map
->n
; ++i
) {
771 map
->p
[i
] = isl_basic_map_set_dim_name(map
->p
[i
], type
, pos
, s
);
782 __isl_give isl_basic_set
*isl_basic_set_set_dim_name(
783 __isl_take isl_basic_set
*bset
,
784 enum isl_dim_type type
, unsigned pos
, const char *s
)
786 return bset_from_bmap(isl_basic_map_set_dim_name(bset_to_bmap(bset
),
790 __isl_give isl_set
*isl_set_set_dim_name(__isl_take isl_set
*set
,
791 enum isl_dim_type type
, unsigned pos
, const char *s
)
793 return set_from_map(isl_map_set_dim_name(set_to_map(set
),
797 isl_bool
isl_basic_map_has_dim_id(__isl_keep isl_basic_map
*bmap
,
798 enum isl_dim_type type
, unsigned pos
)
801 return isl_bool_error
;
802 return isl_space_has_dim_id(bmap
->dim
, type
, pos
);
805 __isl_give isl_id
*isl_basic_set_get_dim_id(__isl_keep isl_basic_set
*bset
,
806 enum isl_dim_type type
, unsigned pos
)
808 return bset
? isl_space_get_dim_id(bset
->dim
, type
, pos
) : NULL
;
811 isl_bool
isl_map_has_dim_id(__isl_keep isl_map
*map
,
812 enum isl_dim_type type
, unsigned pos
)
814 return map
? isl_space_has_dim_id(map
->dim
, type
, pos
) : isl_bool_error
;
817 __isl_give isl_id
*isl_map_get_dim_id(__isl_keep isl_map
*map
,
818 enum isl_dim_type type
, unsigned pos
)
820 return map
? isl_space_get_dim_id(map
->dim
, type
, pos
) : NULL
;
823 isl_bool
isl_set_has_dim_id(__isl_keep isl_set
*set
,
824 enum isl_dim_type type
, unsigned pos
)
826 return isl_map_has_dim_id(set
, type
, pos
);
829 __isl_give isl_id
*isl_set_get_dim_id(__isl_keep isl_set
*set
,
830 enum isl_dim_type type
, unsigned pos
)
832 return isl_map_get_dim_id(set
, type
, pos
);
835 __isl_give isl_map
*isl_map_set_dim_id(__isl_take isl_map
*map
,
836 enum isl_dim_type type
, unsigned pos
, __isl_take isl_id
*id
)
838 map
= isl_map_cow(map
);
842 map
->dim
= isl_space_set_dim_id(map
->dim
, type
, pos
, id
);
844 return isl_map_reset_space(map
, isl_space_copy(map
->dim
));
850 __isl_give isl_set
*isl_set_set_dim_id(__isl_take isl_set
*set
,
851 enum isl_dim_type type
, unsigned pos
, __isl_take isl_id
*id
)
853 return isl_map_set_dim_id(set
, type
, pos
, id
);
856 int isl_map_find_dim_by_id(__isl_keep isl_map
*map
, enum isl_dim_type type
,
857 __isl_keep isl_id
*id
)
861 return isl_space_find_dim_by_id(map
->dim
, type
, id
);
864 int isl_set_find_dim_by_id(__isl_keep isl_set
*set
, enum isl_dim_type type
,
865 __isl_keep isl_id
*id
)
867 return isl_map_find_dim_by_id(set
, type
, id
);
870 /* Return the position of the dimension of the given type and name
872 * Return -1 if no such dimension can be found.
874 int isl_basic_map_find_dim_by_name(__isl_keep isl_basic_map
*bmap
,
875 enum isl_dim_type type
, const char *name
)
879 return isl_space_find_dim_by_name(bmap
->dim
, type
, name
);
882 int isl_map_find_dim_by_name(__isl_keep isl_map
*map
, enum isl_dim_type type
,
887 return isl_space_find_dim_by_name(map
->dim
, type
, name
);
890 int isl_set_find_dim_by_name(__isl_keep isl_set
*set
, enum isl_dim_type type
,
893 return isl_map_find_dim_by_name(set
, type
, name
);
896 /* Check whether equality i of bset is a pure stride constraint
897 * on a single dimension, i.e., of the form
901 * with k a constant and e an existentially quantified variable.
903 isl_bool
isl_basic_set_eq_is_stride(__isl_keep isl_basic_set
*bset
, int i
)
911 nparam
= isl_basic_set_dim(bset
, isl_dim_param
);
912 d
= isl_basic_set_dim(bset
, isl_dim_set
);
913 n_div
= isl_basic_set_dim(bset
, isl_dim_div
);
914 if (nparam
< 0 || d
< 0 || n_div
< 0)
915 return isl_bool_error
;
917 if (!isl_int_is_zero(bset
->eq
[i
][0]))
918 return isl_bool_false
;
920 if (isl_seq_first_non_zero(bset
->eq
[i
] + 1, nparam
) != -1)
921 return isl_bool_false
;
922 pos1
= isl_seq_first_non_zero(bset
->eq
[i
] + 1 + nparam
, d
);
924 return isl_bool_false
;
925 if (isl_seq_first_non_zero(bset
->eq
[i
] + 1 + nparam
+ pos1
+ 1,
927 return isl_bool_false
;
929 pos2
= isl_seq_first_non_zero(bset
->eq
[i
] + 1 + nparam
+ d
, n_div
);
931 return isl_bool_false
;
932 if (isl_seq_first_non_zero(bset
->eq
[i
] + 1 + nparam
+ d
+ pos2
+ 1,
933 n_div
- pos2
- 1) != -1)
934 return isl_bool_false
;
935 if (!isl_int_is_one(bset
->eq
[i
][1 + nparam
+ pos1
]) &&
936 !isl_int_is_negone(bset
->eq
[i
][1 + nparam
+ pos1
]))
937 return isl_bool_false
;
939 return isl_bool_true
;
942 /* Reset the user pointer on all identifiers of parameters and tuples
943 * of the space of "map".
945 __isl_give isl_map
*isl_map_reset_user(__isl_take isl_map
*map
)
949 space
= isl_map_get_space(map
);
950 space
= isl_space_reset_user(space
);
951 map
= isl_map_reset_space(map
, space
);
956 /* Reset the user pointer on all identifiers of parameters and tuples
957 * of the space of "set".
959 __isl_give isl_set
*isl_set_reset_user(__isl_take isl_set
*set
)
961 return isl_map_reset_user(set
);
964 isl_bool
isl_basic_map_is_rational(__isl_keep isl_basic_map
*bmap
)
967 return isl_bool_error
;
968 return ISL_F_ISSET(bmap
, ISL_BASIC_MAP_RATIONAL
);
971 /* Has "map" been marked as a rational map?
972 * In particular, have all basic maps in "map" been marked this way?
973 * An empty map is not considered to be rational.
974 * Maps where only some of the basic maps are marked rational
977 isl_bool
isl_map_is_rational(__isl_keep isl_map
*map
)
983 return isl_bool_error
;
985 return isl_bool_false
;
986 rational
= isl_basic_map_is_rational(map
->p
[0]);
989 for (i
= 1; i
< map
->n
; ++i
) {
992 rational_i
= isl_basic_map_is_rational(map
->p
[i
]);
995 if (rational
!= rational_i
)
996 isl_die(isl_map_get_ctx(map
), isl_error_unsupported
,
997 "mixed rational and integer basic maps "
998 "not supported", return isl_bool_error
);
1004 /* Has "set" been marked as a rational set?
1005 * In particular, have all basic set in "set" been marked this way?
1006 * An empty set is not considered to be rational.
1007 * Sets where only some of the basic sets are marked rational
1010 isl_bool
isl_set_is_rational(__isl_keep isl_set
*set
)
1012 return isl_map_is_rational(set
);
1015 int isl_basic_set_is_rational(__isl_keep isl_basic_set
*bset
)
1017 return isl_basic_map_is_rational(bset
);
1020 /* Does "bmap" contain any rational points?
1022 * If "bmap" has an equality for each dimension, equating the dimension
1023 * to an integer constant, then it has no rational points, even if it
1024 * is marked as rational.
1026 isl_bool
isl_basic_map_has_rational(__isl_keep isl_basic_map
*bmap
)
1028 isl_bool has_rational
= isl_bool_true
;
1032 return isl_bool_error
;
1033 if (isl_basic_map_plain_is_empty(bmap
))
1034 return isl_bool_false
;
1035 if (!isl_basic_map_is_rational(bmap
))
1036 return isl_bool_false
;
1037 bmap
= isl_basic_map_copy(bmap
);
1038 bmap
= isl_basic_map_implicit_equalities(bmap
);
1039 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
1041 return isl_bool_error
;
1042 if (bmap
->n_eq
== total
) {
1044 for (i
= 0; i
< bmap
->n_eq
; ++i
) {
1045 j
= isl_seq_first_non_zero(bmap
->eq
[i
] + 1, total
);
1048 if (!isl_int_is_one(bmap
->eq
[i
][1 + j
]) &&
1049 !isl_int_is_negone(bmap
->eq
[i
][1 + j
]))
1051 j
= isl_seq_first_non_zero(bmap
->eq
[i
] + 1 + j
+ 1,
1056 if (i
== bmap
->n_eq
)
1057 has_rational
= isl_bool_false
;
1059 isl_basic_map_free(bmap
);
1061 return has_rational
;
1064 /* Does "map" contain any rational points?
1066 isl_bool
isl_map_has_rational(__isl_keep isl_map
*map
)
1069 isl_bool has_rational
;
1072 return isl_bool_error
;
1073 for (i
= 0; i
< map
->n
; ++i
) {
1074 has_rational
= isl_basic_map_has_rational(map
->p
[i
]);
1075 if (has_rational
< 0 || has_rational
)
1076 return has_rational
;
1078 return isl_bool_false
;
1081 /* Does "set" contain any rational points?
1083 isl_bool
isl_set_has_rational(__isl_keep isl_set
*set
)
1085 return isl_map_has_rational(set
);
1088 /* Is this basic set a parameter domain?
1090 isl_bool
isl_basic_set_is_params(__isl_keep isl_basic_set
*bset
)
1093 return isl_bool_error
;
1094 return isl_space_is_params(bset
->dim
);
1097 /* Is this set a parameter domain?
1099 isl_bool
isl_set_is_params(__isl_keep isl_set
*set
)
1102 return isl_bool_error
;
1103 return isl_space_is_params(set
->dim
);
1106 /* Is this map actually a parameter domain?
1107 * Users should never call this function. Outside of isl,
1108 * a map can never be a parameter domain.
1110 isl_bool
isl_map_is_params(__isl_keep isl_map
*map
)
1113 return isl_bool_error
;
1114 return isl_space_is_params(map
->dim
);
1117 static __isl_give isl_basic_map
*basic_map_init(isl_ctx
*ctx
,
1118 __isl_take isl_basic_map
*bmap
, unsigned extra
,
1119 unsigned n_eq
, unsigned n_ineq
)
1122 isl_space
*space
= isl_basic_map_peek_space(bmap
);
1123 isl_size n_var
= isl_space_dim(space
, isl_dim_all
);
1124 size_t row_size
= 1 + n_var
+ extra
;
1130 return isl_basic_map_free(bmap
);
1132 bmap
->block
= isl_blk_alloc(ctx
, (n_ineq
+ n_eq
) * row_size
);
1133 if (isl_blk_is_error(bmap
->block
))
1136 bmap
->ineq
= isl_alloc_array(ctx
, isl_int
*, n_ineq
+ n_eq
);
1137 if ((n_ineq
+ n_eq
) && !bmap
->ineq
)
1141 bmap
->block2
= isl_blk_empty();
1144 bmap
->block2
= isl_blk_alloc(ctx
, extra
* (1 + row_size
));
1145 if (isl_blk_is_error(bmap
->block2
))
1148 bmap
->div
= isl_alloc_array(ctx
, isl_int
*, extra
);
1153 for (i
= 0; i
< n_ineq
+ n_eq
; ++i
)
1154 bmap
->ineq
[i
] = bmap
->block
.data
+ i
* row_size
;
1156 for (i
= 0; i
< extra
; ++i
)
1157 bmap
->div
[i
] = bmap
->block2
.data
+ i
* (1 + row_size
);
1161 bmap
->c_size
= n_eq
+ n_ineq
;
1162 bmap
->eq
= bmap
->ineq
+ n_ineq
;
1163 bmap
->extra
= extra
;
1167 bmap
->sample
= NULL
;
1171 isl_basic_map_free(bmap
);
1175 struct isl_basic_set
*isl_basic_set_alloc(struct isl_ctx
*ctx
,
1176 unsigned nparam
, unsigned dim
, unsigned extra
,
1177 unsigned n_eq
, unsigned n_ineq
)
1179 struct isl_basic_map
*bmap
;
1182 space
= isl_space_set_alloc(ctx
, nparam
, dim
);
1186 bmap
= isl_basic_map_alloc_space(space
, extra
, n_eq
, n_ineq
);
1187 return bset_from_bmap(bmap
);
1190 __isl_give isl_basic_set
*isl_basic_set_alloc_space(__isl_take isl_space
*dim
,
1191 unsigned extra
, unsigned n_eq
, unsigned n_ineq
)
1193 struct isl_basic_map
*bmap
;
1196 isl_assert(dim
->ctx
, dim
->n_in
== 0, goto error
);
1197 bmap
= isl_basic_map_alloc_space(dim
, extra
, n_eq
, n_ineq
);
1198 return bset_from_bmap(bmap
);
1200 isl_space_free(dim
);
1204 __isl_give isl_basic_map
*isl_basic_map_alloc_space(__isl_take isl_space
*space
,
1205 unsigned extra
, unsigned n_eq
, unsigned n_ineq
)
1207 struct isl_basic_map
*bmap
;
1211 bmap
= isl_calloc_type(space
->ctx
, struct isl_basic_map
);
1216 return basic_map_init(space
->ctx
, bmap
, extra
, n_eq
, n_ineq
);
1218 isl_space_free(space
);
1222 struct isl_basic_map
*isl_basic_map_alloc(struct isl_ctx
*ctx
,
1223 unsigned nparam
, unsigned in
, unsigned out
, unsigned extra
,
1224 unsigned n_eq
, unsigned n_ineq
)
1226 struct isl_basic_map
*bmap
;
1229 dim
= isl_space_alloc(ctx
, nparam
, in
, out
);
1233 bmap
= isl_basic_map_alloc_space(dim
, extra
, n_eq
, n_ineq
);
1237 static __isl_give isl_basic_map
*dup_constraints(__isl_take isl_basic_map
*dst
,
1238 __isl_keep isl_basic_map
*src
)
1241 isl_size total
= isl_basic_map_dim(src
, isl_dim_all
);
1243 if (!dst
|| total
< 0)
1244 return isl_basic_map_free(dst
);
1246 for (i
= 0; i
< src
->n_eq
; ++i
) {
1247 int j
= isl_basic_map_alloc_equality(dst
);
1249 return isl_basic_map_free(dst
);
1250 isl_seq_cpy(dst
->eq
[j
], src
->eq
[i
], 1+total
);
1253 for (i
= 0; i
< src
->n_ineq
; ++i
) {
1254 int j
= isl_basic_map_alloc_inequality(dst
);
1256 return isl_basic_map_free(dst
);
1257 isl_seq_cpy(dst
->ineq
[j
], src
->ineq
[i
], 1+total
);
1260 for (i
= 0; i
< src
->n_div
; ++i
) {
1261 int j
= isl_basic_map_alloc_div(dst
);
1263 return isl_basic_map_free(dst
);
1264 isl_seq_cpy(dst
->div
[j
], src
->div
[i
], 1+1+total
);
1266 ISL_F_SET(dst
, ISL_BASIC_SET_FINAL
);
1270 __isl_give isl_basic_map
*isl_basic_map_dup(__isl_keep isl_basic_map
*bmap
)
1272 struct isl_basic_map
*dup
;
1276 dup
= isl_basic_map_alloc_space(isl_space_copy(bmap
->dim
),
1277 bmap
->n_div
, bmap
->n_eq
, bmap
->n_ineq
);
1278 dup
= dup_constraints(dup
, bmap
);
1281 dup
->flags
= bmap
->flags
;
1282 dup
->sample
= isl_vec_copy(bmap
->sample
);
1286 struct isl_basic_set
*isl_basic_set_dup(struct isl_basic_set
*bset
)
1288 struct isl_basic_map
*dup
;
1290 dup
= isl_basic_map_dup(bset_to_bmap(bset
));
1291 return bset_from_bmap(dup
);
1294 __isl_give isl_basic_set
*isl_basic_set_copy(__isl_keep isl_basic_set
*bset
)
1299 if (ISL_F_ISSET(bset
, ISL_BASIC_SET_FINAL
)) {
1303 return isl_basic_set_dup(bset
);
1306 __isl_give isl_set
*isl_set_copy(__isl_keep isl_set
*set
)
1315 __isl_give isl_basic_map
*isl_basic_map_copy(__isl_keep isl_basic_map
*bmap
)
1320 if (ISL_F_ISSET(bmap
, ISL_BASIC_SET_FINAL
)) {
1324 bmap
= isl_basic_map_dup(bmap
);
1326 ISL_F_SET(bmap
, ISL_BASIC_SET_FINAL
);
1330 __isl_give isl_map
*isl_map_copy(__isl_keep isl_map
*map
)
1339 __isl_null isl_basic_map
*isl_basic_map_free(__isl_take isl_basic_map
*bmap
)
1344 if (--bmap
->ref
> 0)
1347 isl_ctx_deref(bmap
->ctx
);
1349 isl_blk_free(bmap
->ctx
, bmap
->block2
);
1351 isl_blk_free(bmap
->ctx
, bmap
->block
);
1352 isl_vec_free(bmap
->sample
);
1353 isl_space_free(bmap
->dim
);
1359 __isl_null isl_basic_set
*isl_basic_set_free(__isl_take isl_basic_set
*bset
)
1361 return isl_basic_map_free(bset_to_bmap(bset
));
1364 static int room_for_con(struct isl_basic_map
*bmap
, unsigned n
)
1366 return bmap
->n_eq
+ bmap
->n_ineq
+ n
<= bmap
->c_size
;
1369 /* Check that "bset" does not involve any parameters.
1371 isl_stat
isl_basic_set_check_no_params(__isl_keep isl_basic_set
*bset
)
1375 nparam
= isl_basic_set_dim(bset
, isl_dim_param
);
1377 return isl_stat_error
;
1379 isl_die(isl_basic_set_get_ctx(bset
), isl_error_invalid
,
1380 "basic set should not have any parameters",
1381 return isl_stat_error
);
1385 /* Check that "bset" does not involve any local variables.
1387 isl_stat
isl_basic_set_check_no_locals(__isl_keep isl_basic_set
*bset
)
1391 n_div
= isl_basic_set_dim(bset
, isl_dim_div
);
1393 return isl_stat_error
;
1395 isl_die(isl_basic_set_get_ctx(bset
), isl_error_invalid
,
1396 "basic set should not have any local variables",
1397 return isl_stat_error
);
1401 /* Check that "map" has only named parameters, reporting an error
1404 isl_stat
isl_map_check_named_params(__isl_keep isl_map
*map
)
1406 return isl_space_check_named_params(isl_map_peek_space(map
));
1409 /* Check that "bmap" has only named parameters, reporting an error
1412 static isl_stat
isl_basic_map_check_named_params(__isl_keep isl_basic_map
*bmap
)
1414 return isl_space_check_named_params(isl_basic_map_peek_space(bmap
));
1417 /* Check that "bmap1" and "bmap2" have the same parameters,
1418 * reporting an error if they do not.
1420 static isl_stat
isl_basic_map_check_equal_params(
1421 __isl_keep isl_basic_map
*bmap1
, __isl_keep isl_basic_map
*bmap2
)
1425 match
= isl_basic_map_has_equal_params(bmap1
, bmap2
);
1427 return isl_stat_error
;
1429 isl_die(isl_basic_map_get_ctx(bmap1
), isl_error_invalid
,
1430 "parameters don't match", return isl_stat_error
);
1434 __isl_give isl_map
*isl_map_align_params_map_map_and(
1435 __isl_take isl_map
*map1
, __isl_take isl_map
*map2
,
1436 __isl_give isl_map
*(*fn
)(__isl_take isl_map
*map1
,
1437 __isl_take isl_map
*map2
))
1441 if (isl_map_has_equal_params(map1
, map2
))
1442 return fn(map1
, map2
);
1443 if (isl_map_check_named_params(map1
) < 0)
1445 if (isl_map_check_named_params(map2
) < 0)
1447 map1
= isl_map_align_params(map1
, isl_map_get_space(map2
));
1448 map2
= isl_map_align_params(map2
, isl_map_get_space(map1
));
1449 return fn(map1
, map2
);
1456 isl_bool
isl_map_align_params_map_map_and_test(__isl_keep isl_map
*map1
,
1457 __isl_keep isl_map
*map2
,
1458 isl_bool (*fn
)(__isl_keep isl_map
*map1
, __isl_keep isl_map
*map2
))
1463 return isl_bool_error
;
1464 if (isl_map_has_equal_params(map1
, map2
))
1465 return fn(map1
, map2
);
1466 if (isl_map_check_named_params(map1
) < 0)
1467 return isl_bool_error
;
1468 if (isl_map_check_named_params(map2
) < 0)
1469 return isl_bool_error
;
1470 map1
= isl_map_copy(map1
);
1471 map2
= isl_map_copy(map2
);
1472 map1
= isl_map_align_params(map1
, isl_map_get_space(map2
));
1473 map2
= isl_map_align_params(map2
, isl_map_get_space(map1
));
1480 int isl_basic_map_alloc_equality(struct isl_basic_map
*bmap
)
1483 struct isl_ctx
*ctx
;
1485 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
1489 isl_assert(ctx
, room_for_con(bmap
, 1), return -1);
1490 isl_assert(ctx
, (bmap
->eq
- bmap
->ineq
) + bmap
->n_eq
<= bmap
->c_size
,
1492 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NO_REDUNDANT
);
1493 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NO_IMPLICIT
);
1494 ISL_F_CLR(bmap
, ISL_BASIC_MAP_ALL_EQUALITIES
);
1495 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NORMALIZED_DIVS
);
1496 if ((bmap
->eq
- bmap
->ineq
) + bmap
->n_eq
== bmap
->c_size
) {
1498 int j
= isl_basic_map_alloc_inequality(bmap
);
1502 bmap
->ineq
[j
] = bmap
->ineq
[bmap
->n_ineq
- 1];
1503 bmap
->ineq
[bmap
->n_ineq
- 1] = bmap
->eq
[-1];
1510 isl_seq_clr(bmap
->eq
[bmap
->n_eq
] + 1 + total
,
1511 bmap
->extra
- bmap
->n_div
);
1512 return bmap
->n_eq
++;
1515 int isl_basic_set_alloc_equality(struct isl_basic_set
*bset
)
1517 return isl_basic_map_alloc_equality(bset_to_bmap(bset
));
1520 __isl_give isl_basic_map
*isl_basic_map_free_equality(
1521 __isl_take isl_basic_map
*bmap
, unsigned n
)
1526 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
1527 "invalid number of equalities",
1528 isl_basic_map_free(bmap
));
1533 __isl_give isl_basic_set
*isl_basic_set_free_equality(
1534 __isl_take isl_basic_set
*bset
, unsigned n
)
1536 return bset_from_bmap(isl_basic_map_free_equality(bset_to_bmap(bset
),
1540 int isl_basic_map_drop_equality(struct isl_basic_map
*bmap
, unsigned pos
)
1545 isl_assert(bmap
->ctx
, pos
< bmap
->n_eq
, return -1);
1547 if (pos
!= bmap
->n_eq
- 1) {
1549 bmap
->eq
[pos
] = bmap
->eq
[bmap
->n_eq
- 1];
1550 bmap
->eq
[bmap
->n_eq
- 1] = t
;
1556 /* Turn inequality "pos" of "bmap" into an equality.
1558 * In particular, we move the inequality in front of the equalities
1559 * and move the last inequality in the position of the moved inequality.
1560 * Note that isl_tab_make_equalities_explicit depends on this particular
1561 * change in the ordering of the constraints.
1563 void isl_basic_map_inequality_to_equality(
1564 struct isl_basic_map
*bmap
, unsigned pos
)
1568 t
= bmap
->ineq
[pos
];
1569 bmap
->ineq
[pos
] = bmap
->ineq
[bmap
->n_ineq
- 1];
1570 bmap
->ineq
[bmap
->n_ineq
- 1] = bmap
->eq
[-1];
1575 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NO_REDUNDANT
);
1576 ISL_F_CLR(bmap
, ISL_BASIC_MAP_SORTED
);
1577 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NORMALIZED_DIVS
);
1578 ISL_F_CLR(bmap
, ISL_BASIC_MAP_ALL_EQUALITIES
);
1581 static int room_for_ineq(struct isl_basic_map
*bmap
, unsigned n
)
1583 return bmap
->n_ineq
+ n
<= bmap
->eq
- bmap
->ineq
;
1586 int isl_basic_map_alloc_inequality(__isl_keep isl_basic_map
*bmap
)
1589 struct isl_ctx
*ctx
;
1591 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
1595 isl_assert(ctx
, room_for_ineq(bmap
, 1), return -1);
1596 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NO_IMPLICIT
);
1597 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NO_REDUNDANT
);
1598 ISL_F_CLR(bmap
, ISL_BASIC_MAP_SORTED
);
1599 ISL_F_CLR(bmap
, ISL_BASIC_MAP_ALL_EQUALITIES
);
1600 isl_seq_clr(bmap
->ineq
[bmap
->n_ineq
] + 1 + total
,
1601 bmap
->extra
- bmap
->n_div
);
1602 return bmap
->n_ineq
++;
1605 int isl_basic_set_alloc_inequality(__isl_keep isl_basic_set
*bset
)
1607 return isl_basic_map_alloc_inequality(bset_to_bmap(bset
));
1610 __isl_give isl_basic_map
*isl_basic_map_free_inequality(
1611 __isl_take isl_basic_map
*bmap
, unsigned n
)
1615 if (n
> bmap
->n_ineq
)
1616 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
1617 "invalid number of inequalities",
1618 return isl_basic_map_free(bmap
));
1623 __isl_give isl_basic_set
*isl_basic_set_free_inequality(
1624 __isl_take isl_basic_set
*bset
, unsigned n
)
1626 return bset_from_bmap(isl_basic_map_free_inequality(bset_to_bmap(bset
),
1630 int isl_basic_map_drop_inequality(struct isl_basic_map
*bmap
, unsigned pos
)
1635 isl_assert(bmap
->ctx
, pos
< bmap
->n_ineq
, return -1);
1637 if (pos
!= bmap
->n_ineq
- 1) {
1638 t
= bmap
->ineq
[pos
];
1639 bmap
->ineq
[pos
] = bmap
->ineq
[bmap
->n_ineq
- 1];
1640 bmap
->ineq
[bmap
->n_ineq
- 1] = t
;
1641 ISL_F_CLR(bmap
, ISL_BASIC_MAP_SORTED
);
1647 int isl_basic_set_drop_inequality(struct isl_basic_set
*bset
, unsigned pos
)
1649 return isl_basic_map_drop_inequality(bset_to_bmap(bset
), pos
);
1652 __isl_give isl_basic_map
*isl_basic_map_add_eq(__isl_take isl_basic_map
*bmap
,
1659 empty
= isl_basic_map_plain_is_empty(bmap
);
1661 return isl_basic_map_free(bmap
);
1665 bmap
= isl_basic_map_cow(bmap
);
1666 bmap
= isl_basic_map_extend_constraints(bmap
, 1, 0);
1667 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
1669 return isl_basic_map_free(bmap
);
1670 k
= isl_basic_map_alloc_equality(bmap
);
1673 isl_seq_cpy(bmap
->eq
[k
], eq
, 1 + total
);
1676 isl_basic_map_free(bmap
);
1680 __isl_give isl_basic_set
*isl_basic_set_add_eq(__isl_take isl_basic_set
*bset
,
1683 return bset_from_bmap(isl_basic_map_add_eq(bset_to_bmap(bset
), eq
));
1686 __isl_give isl_basic_map
*isl_basic_map_add_ineq(__isl_take isl_basic_map
*bmap
,
1692 bmap
= isl_basic_map_cow(bmap
);
1693 bmap
= isl_basic_map_extend_constraints(bmap
, 0, 1);
1694 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
1696 return isl_basic_map_free(bmap
);
1697 k
= isl_basic_map_alloc_inequality(bmap
);
1700 isl_seq_cpy(bmap
->ineq
[k
], ineq
, 1 + total
);
1703 isl_basic_map_free(bmap
);
1707 __isl_give isl_basic_set
*isl_basic_set_add_ineq(__isl_take isl_basic_set
*bset
,
1710 return bset_from_bmap(isl_basic_map_add_ineq(bset_to_bmap(bset
), ineq
));
1713 int isl_basic_map_alloc_div(struct isl_basic_map
*bmap
)
1717 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
1720 isl_assert(bmap
->ctx
, bmap
->n_div
< bmap
->extra
, return -1);
1721 isl_seq_clr(bmap
->div
[bmap
->n_div
] + 1 + 1 + total
,
1722 bmap
->extra
- bmap
->n_div
);
1723 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NORMALIZED_DIVS
);
1724 return bmap
->n_div
++;
1727 int isl_basic_set_alloc_div(struct isl_basic_set
*bset
)
1729 return isl_basic_map_alloc_div(bset_to_bmap(bset
));
1733 #define TYPE isl_basic_map
1734 #include "check_type_range_templ.c"
1736 /* Check that there are "n" dimensions of type "type" starting at "first"
1739 isl_stat
isl_basic_set_check_range(__isl_keep isl_basic_set
*bset
,
1740 enum isl_dim_type type
, unsigned first
, unsigned n
)
1742 return isl_basic_map_check_range(bset_to_bmap(bset
),
1746 /* Insert an extra integer division, prescribed by "div", to "bmap"
1747 * at (integer division) position "pos".
1749 * The integer division is first added at the end and then moved
1750 * into the right position.
1752 __isl_give isl_basic_map
*isl_basic_map_insert_div(
1753 __isl_take isl_basic_map
*bmap
, int pos
, __isl_keep isl_vec
*div
)
1758 bmap
= isl_basic_map_cow(bmap
);
1759 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
1760 if (total
< 0 || !div
)
1761 return isl_basic_map_free(bmap
);
1763 if (div
->size
!= 1 + 1 + total
)
1764 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
1765 "unexpected size", return isl_basic_map_free(bmap
));
1766 if (isl_basic_map_check_range(bmap
, isl_dim_div
, pos
, 0) < 0)
1767 return isl_basic_map_free(bmap
);
1769 bmap
= isl_basic_map_extend_space(bmap
,
1770 isl_basic_map_get_space(bmap
), 1, 0, 2);
1771 k
= isl_basic_map_alloc_div(bmap
);
1773 return isl_basic_map_free(bmap
);
1774 isl_seq_cpy(bmap
->div
[k
], div
->el
, div
->size
);
1775 isl_int_set_si(bmap
->div
[k
][div
->size
], 0);
1777 for (i
= k
; i
> pos
; --i
)
1778 bmap
= isl_basic_map_swap_div(bmap
, i
, i
- 1);
1783 isl_stat
isl_basic_map_free_div(struct isl_basic_map
*bmap
, unsigned n
)
1786 return isl_stat_error
;
1787 isl_assert(bmap
->ctx
, n
<= bmap
->n_div
, return isl_stat_error
);
1792 static __isl_give isl_basic_map
*add_constraints(
1793 __isl_take isl_basic_map
*bmap1
, __isl_take isl_basic_map
*bmap2
,
1794 unsigned i_pos
, unsigned o_pos
)
1796 isl_size total
, n_param
, n_in
, n_out
, n_div
;
1797 unsigned o_in
, o_out
;
1800 struct isl_dim_map
*dim_map
;
1802 space
= isl_basic_map_peek_space(bmap2
);
1803 if (!bmap1
|| !space
)
1806 total
= isl_basic_map_dim(bmap1
, isl_dim_all
);
1807 n_param
= isl_basic_map_dim(bmap2
, isl_dim_param
);
1808 n_in
= isl_basic_map_dim(bmap2
, isl_dim_in
);
1809 o_in
= isl_basic_map_offset(bmap1
, isl_dim_in
) - 1 + i_pos
;
1810 n_out
= isl_basic_map_dim(bmap2
, isl_dim_out
);
1811 o_out
= isl_basic_map_offset(bmap1
, isl_dim_out
) - 1 + o_pos
;
1812 n_div
= isl_basic_map_dim(bmap2
, isl_dim_div
);
1813 if (total
< 0 || n_param
< 0 || n_in
< 0 || n_out
< 0 || n_div
< 0)
1815 ctx
= isl_basic_map_get_ctx(bmap1
);
1816 dim_map
= isl_dim_map_alloc(ctx
, total
+ n_div
);
1817 isl_dim_map_dim_range(dim_map
, space
, isl_dim_param
, 0, n_param
, 0);
1818 isl_dim_map_dim_range(dim_map
, space
, isl_dim_in
, 0, n_in
, o_in
);
1819 isl_dim_map_dim_range(dim_map
, space
, isl_dim_out
, 0, n_out
, o_out
);
1820 isl_dim_map_div(dim_map
, bmap2
, total
);
1822 return isl_basic_map_add_constraints_dim_map(bmap1
, bmap2
, dim_map
);
1824 isl_basic_map_free(bmap1
);
1825 isl_basic_map_free(bmap2
);
1829 struct isl_basic_set
*isl_basic_set_add_constraints(struct isl_basic_set
*bset1
,
1830 struct isl_basic_set
*bset2
, unsigned pos
)
1832 return bset_from_bmap(add_constraints(bset_to_bmap(bset1
),
1833 bset_to_bmap(bset2
), 0, pos
));
1836 __isl_give isl_basic_map
*isl_basic_map_extend_space(
1837 __isl_take isl_basic_map
*base
, __isl_take isl_space
*space
,
1838 unsigned extra
, unsigned n_eq
, unsigned n_ineq
)
1840 struct isl_basic_map
*ext
;
1850 dims_ok
= isl_space_is_equal(base
->dim
, space
) &&
1851 base
->extra
>= base
->n_div
+ extra
;
1853 if (dims_ok
&& room_for_con(base
, n_eq
+ n_ineq
) &&
1854 room_for_ineq(base
, n_ineq
)) {
1855 isl_space_free(space
);
1859 isl_assert(base
->ctx
, base
->dim
->nparam
<= space
->nparam
, goto error
);
1860 isl_assert(base
->ctx
, base
->dim
->n_in
<= space
->n_in
, goto error
);
1861 isl_assert(base
->ctx
, base
->dim
->n_out
<= space
->n_out
, goto error
);
1862 extra
+= base
->extra
;
1864 n_ineq
+= base
->n_ineq
;
1866 ext
= isl_basic_map_alloc_space(space
, extra
, n_eq
, n_ineq
);
1872 ext
->sample
= isl_vec_copy(base
->sample
);
1873 flags
= base
->flags
;
1874 ext
= add_constraints(ext
, base
, 0, 0);
1877 ISL_F_CLR(ext
, ISL_BASIC_SET_FINAL
);
1883 isl_space_free(space
);
1884 isl_basic_map_free(base
);
1888 __isl_give isl_basic_set
*isl_basic_set_extend_space(
1889 __isl_take isl_basic_set
*base
,
1890 __isl_take isl_space
*dim
, unsigned extra
,
1891 unsigned n_eq
, unsigned n_ineq
)
1893 return bset_from_bmap(isl_basic_map_extend_space(bset_to_bmap(base
),
1894 dim
, extra
, n_eq
, n_ineq
));
1897 struct isl_basic_map
*isl_basic_map_extend_constraints(
1898 struct isl_basic_map
*base
, unsigned n_eq
, unsigned n_ineq
)
1902 return isl_basic_map_extend_space(base
, isl_space_copy(base
->dim
),
1906 struct isl_basic_map
*isl_basic_map_extend(struct isl_basic_map
*base
,
1907 unsigned nparam
, unsigned n_in
, unsigned n_out
, unsigned extra
,
1908 unsigned n_eq
, unsigned n_ineq
)
1910 struct isl_basic_map
*bmap
;
1915 dim
= isl_space_alloc(base
->ctx
, nparam
, n_in
, n_out
);
1919 bmap
= isl_basic_map_extend_space(base
, dim
, extra
, n_eq
, n_ineq
);
1922 isl_basic_map_free(base
);
1926 struct isl_basic_set
*isl_basic_set_extend_constraints(
1927 struct isl_basic_set
*base
, unsigned n_eq
, unsigned n_ineq
)
1929 isl_basic_map
*bmap
= bset_to_bmap(base
);
1930 bmap
= isl_basic_map_extend_constraints(bmap
, n_eq
, n_ineq
);
1931 return bset_from_bmap(bmap
);
1934 __isl_give isl_basic_set
*isl_basic_set_cow(__isl_take isl_basic_set
*bset
)
1936 return bset_from_bmap(isl_basic_map_cow(bset_to_bmap(bset
)));
1939 __isl_give isl_basic_map
*isl_basic_map_cow(__isl_take isl_basic_map
*bmap
)
1944 if (bmap
->ref
> 1) {
1946 bmap
= isl_basic_map_dup(bmap
);
1949 ISL_F_CLR(bmap
, ISL_BASIC_SET_FINAL
);
1950 ISL_F_CLR(bmap
, ISL_BASIC_MAP_REDUCED_COEFFICIENTS
);
1955 /* Clear all cached information in "map", either because it is about
1956 * to be modified or because it is being freed.
1957 * Always return the same pointer that is passed in.
1958 * This is needed for the use in isl_map_free.
1960 static __isl_give isl_map
*clear_caches(__isl_take isl_map
*map
)
1962 isl_basic_map_free(map
->cached_simple_hull
[0]);
1963 isl_basic_map_free(map
->cached_simple_hull
[1]);
1964 map
->cached_simple_hull
[0] = NULL
;
1965 map
->cached_simple_hull
[1] = NULL
;
1969 __isl_give isl_set
*isl_set_cow(__isl_take isl_set
*set
)
1971 return isl_map_cow(set
);
1974 /* Return an isl_map that is equal to "map" and that has only
1975 * a single reference.
1977 * If the original input already has only one reference, then
1978 * simply return it, but clear all cached information, since
1979 * it may be rendered invalid by the operations that will be
1980 * performed on the result.
1982 * Otherwise, create a duplicate (without any cached information).
1984 __isl_give isl_map
*isl_map_cow(__isl_take isl_map
*map
)
1990 return clear_caches(map
);
1992 return isl_map_dup(map
);
1995 static void swap_vars(struct isl_blk blk
, isl_int
*a
,
1996 unsigned a_len
, unsigned b_len
)
1998 isl_seq_cpy(blk
.data
, a
+a_len
, b_len
);
1999 isl_seq_cpy(blk
.data
+b_len
, a
, a_len
);
2000 isl_seq_cpy(a
, blk
.data
, b_len
+a_len
);
2003 static __isl_give isl_basic_map
*isl_basic_map_swap_vars(
2004 __isl_take isl_basic_map
*bmap
, unsigned pos
, unsigned n1
, unsigned n2
)
2009 if (isl_basic_map_check_range(bmap
, isl_dim_all
, pos
- 1, n1
+ n2
) < 0)
2012 if (n1
== 0 || n2
== 0)
2015 bmap
= isl_basic_map_cow(bmap
);
2019 blk
= isl_blk_alloc(bmap
->ctx
, n1
+ n2
);
2020 if (isl_blk_is_error(blk
))
2023 for (i
= 0; i
< bmap
->n_eq
; ++i
)
2025 bmap
->eq
[i
] + pos
, n1
, n2
);
2027 for (i
= 0; i
< bmap
->n_ineq
; ++i
)
2029 bmap
->ineq
[i
] + pos
, n1
, n2
);
2031 for (i
= 0; i
< bmap
->n_div
; ++i
)
2033 bmap
->div
[i
]+1 + pos
, n1
, n2
);
2035 isl_blk_free(bmap
->ctx
, blk
);
2037 ISL_F_CLR(bmap
, ISL_BASIC_SET_SORTED
);
2038 bmap
= isl_basic_map_gauss(bmap
, NULL
);
2039 return isl_basic_map_finalize(bmap
);
2041 isl_basic_map_free(bmap
);
2045 __isl_give isl_basic_map
*isl_basic_map_set_to_empty(
2046 __isl_take isl_basic_map
*bmap
)
2051 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
2053 return isl_basic_map_free(bmap
);
2054 if (isl_basic_map_free_div(bmap
, bmap
->n_div
) < 0)
2055 return isl_basic_map_free(bmap
);
2056 bmap
= isl_basic_map_free_inequality(bmap
, bmap
->n_ineq
);
2059 if (bmap
->n_eq
> 0) {
2060 bmap
= isl_basic_map_free_equality(bmap
, bmap
->n_eq
- 1);
2064 i
= isl_basic_map_alloc_equality(bmap
);
2068 isl_int_set_si(bmap
->eq
[i
][0], 1);
2069 isl_seq_clr(bmap
->eq
[i
]+1, total
);
2070 ISL_F_SET(bmap
, ISL_BASIC_MAP_EMPTY
);
2071 isl_vec_free(bmap
->sample
);
2072 bmap
->sample
= NULL
;
2073 return isl_basic_map_finalize(bmap
);
2075 isl_basic_map_free(bmap
);
2079 __isl_give isl_basic_set
*isl_basic_set_set_to_empty(
2080 __isl_take isl_basic_set
*bset
)
2082 return bset_from_bmap(isl_basic_map_set_to_empty(bset_to_bmap(bset
)));
2085 __isl_give isl_basic_map
*isl_basic_map_set_rational(
2086 __isl_take isl_basic_map
*bmap
)
2091 if (ISL_F_ISSET(bmap
, ISL_BASIC_MAP_RATIONAL
))
2094 bmap
= isl_basic_map_cow(bmap
);
2098 ISL_F_SET(bmap
, ISL_BASIC_MAP_RATIONAL
);
2100 return isl_basic_map_finalize(bmap
);
2103 __isl_give isl_basic_set
*isl_basic_set_set_rational(
2104 __isl_take isl_basic_set
*bset
)
2106 return isl_basic_map_set_rational(bset
);
2109 __isl_give isl_basic_set
*isl_basic_set_set_integral(
2110 __isl_take isl_basic_set
*bset
)
2115 if (!ISL_F_ISSET(bset
, ISL_BASIC_MAP_RATIONAL
))
2118 bset
= isl_basic_set_cow(bset
);
2122 ISL_F_CLR(bset
, ISL_BASIC_MAP_RATIONAL
);
2124 return isl_basic_set_finalize(bset
);
2127 __isl_give isl_map
*isl_map_set_rational(__isl_take isl_map
*map
)
2131 map
= isl_map_cow(map
);
2134 for (i
= 0; i
< map
->n
; ++i
) {
2135 map
->p
[i
] = isl_basic_map_set_rational(map
->p
[i
]);
2145 __isl_give isl_set
*isl_set_set_rational(__isl_take isl_set
*set
)
2147 return isl_map_set_rational(set
);
2150 /* Swap divs "a" and "b" in "bmap" (without modifying any of the constraints
2153 static void swap_div(__isl_keep isl_basic_map
*bmap
, int a
, int b
)
2155 isl_int
*t
= bmap
->div
[a
];
2156 bmap
->div
[a
] = bmap
->div
[b
];
2160 /* Swap divs "a" and "b" in "bmap" and adjust the constraints and
2161 * div definitions accordingly.
2163 __isl_give isl_basic_map
*isl_basic_map_swap_div(__isl_take isl_basic_map
*bmap
,
2169 off
= isl_basic_map_var_offset(bmap
, isl_dim_div
);
2171 return isl_basic_map_free(bmap
);
2173 swap_div(bmap
, a
, b
);
2175 for (i
= 0; i
< bmap
->n_eq
; ++i
)
2176 isl_int_swap(bmap
->eq
[i
][1+off
+a
], bmap
->eq
[i
][1+off
+b
]);
2178 for (i
= 0; i
< bmap
->n_ineq
; ++i
)
2179 isl_int_swap(bmap
->ineq
[i
][1+off
+a
], bmap
->ineq
[i
][1+off
+b
]);
2181 for (i
= 0; i
< bmap
->n_div
; ++i
)
2182 isl_int_swap(bmap
->div
[i
][1+1+off
+a
], bmap
->div
[i
][1+1+off
+b
]);
2183 ISL_F_CLR(bmap
, ISL_BASIC_MAP_SORTED
);
2188 static void constraint_drop_vars(isl_int
*c
, unsigned n
, unsigned rem
)
2190 isl_seq_cpy(c
, c
+ n
, rem
);
2191 isl_seq_clr(c
+ rem
, n
);
2194 /* Drop n dimensions starting at first.
2196 * In principle, this frees up some extra variables as the number
2197 * of columns remains constant, but we would have to extend
2198 * the div array too as the number of rows in this array is assumed
2199 * to be equal to extra.
2201 __isl_give isl_basic_set
*isl_basic_set_drop_dims(
2202 __isl_take isl_basic_set
*bset
, unsigned first
, unsigned n
)
2204 return isl_basic_map_drop(bset_to_bmap(bset
), isl_dim_set
, first
, n
);
2207 /* Move "n" divs starting at "first" to the end of the list of divs.
2209 static struct isl_basic_map
*move_divs_last(struct isl_basic_map
*bmap
,
2210 unsigned first
, unsigned n
)
2215 if (first
+ n
== bmap
->n_div
)
2218 div
= isl_alloc_array(bmap
->ctx
, isl_int
*, n
);
2221 for (i
= 0; i
< n
; ++i
)
2222 div
[i
] = bmap
->div
[first
+ i
];
2223 for (i
= 0; i
< bmap
->n_div
- first
- n
; ++i
)
2224 bmap
->div
[first
+ i
] = bmap
->div
[first
+ n
+ i
];
2225 for (i
= 0; i
< n
; ++i
)
2226 bmap
->div
[bmap
->n_div
- n
+ i
] = div
[i
];
2230 isl_basic_map_free(bmap
);
2235 #define TYPE isl_map
2237 #include "check_type_range_templ.c"
2239 /* Check that there are "n" dimensions of type "type" starting at "first"
2242 static isl_stat
isl_set_check_range(__isl_keep isl_set
*set
,
2243 enum isl_dim_type type
, unsigned first
, unsigned n
)
2245 return isl_map_check_range(set_to_map(set
), type
, first
, n
);
2248 /* Drop "n" dimensions of type "type" starting at "first".
2249 * Perform the core computation, without cowing or
2250 * simplifying and finalizing the result.
2252 * In principle, this frees up some extra variables as the number
2253 * of columns remains constant, but we would have to extend
2254 * the div array too as the number of rows in this array is assumed
2255 * to be equal to extra.
2257 __isl_give isl_basic_map
*isl_basic_map_drop_core(
2258 __isl_take isl_basic_map
*bmap
, enum isl_dim_type type
,
2259 unsigned first
, unsigned n
)
2266 if (isl_basic_map_check_range(bmap
, type
, first
, n
) < 0)
2267 return isl_basic_map_free(bmap
);
2269 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
2271 return isl_basic_map_free(bmap
);
2273 offset
= isl_basic_map_offset(bmap
, type
) + first
;
2274 left
= total
- (offset
- 1) - n
;
2275 for (i
= 0; i
< bmap
->n_eq
; ++i
)
2276 constraint_drop_vars(bmap
->eq
[i
]+offset
, n
, left
);
2278 for (i
= 0; i
< bmap
->n_ineq
; ++i
)
2279 constraint_drop_vars(bmap
->ineq
[i
]+offset
, n
, left
);
2281 for (i
= 0; i
< bmap
->n_div
; ++i
)
2282 constraint_drop_vars(bmap
->div
[i
]+1+offset
, n
, left
);
2284 if (type
== isl_dim_div
) {
2285 bmap
= move_divs_last(bmap
, first
, n
);
2288 if (isl_basic_map_free_div(bmap
, n
) < 0)
2289 return isl_basic_map_free(bmap
);
2291 bmap
->dim
= isl_space_drop_dims(bmap
->dim
, type
, first
, n
);
2293 return isl_basic_map_free(bmap
);
2295 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NO_REDUNDANT
);
2296 ISL_F_CLR(bmap
, ISL_BASIC_MAP_SORTED
);
2300 /* Drop "n" dimensions of type "type" starting at "first".
2302 * In principle, this frees up some extra variables as the number
2303 * of columns remains constant, but we would have to extend
2304 * the div array too as the number of rows in this array is assumed
2305 * to be equal to extra.
2307 __isl_give isl_basic_map
*isl_basic_map_drop(__isl_take isl_basic_map
*bmap
,
2308 enum isl_dim_type type
, unsigned first
, unsigned n
)
2312 if (n
== 0 && !isl_space_is_named_or_nested(bmap
->dim
, type
))
2315 bmap
= isl_basic_map_cow(bmap
);
2319 bmap
= isl_basic_map_drop_core(bmap
, type
, first
, n
);
2321 bmap
= isl_basic_map_simplify(bmap
);
2322 return isl_basic_map_finalize(bmap
);
2325 __isl_give isl_basic_set
*isl_basic_set_drop(__isl_take isl_basic_set
*bset
,
2326 enum isl_dim_type type
, unsigned first
, unsigned n
)
2328 return bset_from_bmap(isl_basic_map_drop(bset_to_bmap(bset
),
2332 /* No longer consider "map" to be normalized.
2334 static __isl_give isl_map
*isl_map_unmark_normalized(__isl_take isl_map
*map
)
2338 ISL_F_CLR(map
, ISL_MAP_NORMALIZED
);
2342 __isl_give isl_map
*isl_map_drop(__isl_take isl_map
*map
,
2343 enum isl_dim_type type
, unsigned first
, unsigned n
)
2347 if (isl_map_check_range(map
, type
, first
, n
) < 0)
2348 return isl_map_free(map
);
2350 if (n
== 0 && !isl_space_is_named_or_nested(map
->dim
, type
))
2352 map
= isl_map_cow(map
);
2355 map
->dim
= isl_space_drop_dims(map
->dim
, type
, first
, n
);
2359 for (i
= 0; i
< map
->n
; ++i
) {
2360 map
->p
[i
] = isl_basic_map_drop(map
->p
[i
], type
, first
, n
);
2364 map
= isl_map_unmark_normalized(map
);
2372 __isl_give isl_set
*isl_set_drop(__isl_take isl_set
*set
,
2373 enum isl_dim_type type
, unsigned first
, unsigned n
)
2375 return set_from_map(isl_map_drop(set_to_map(set
), type
, first
, n
));
2378 /* Drop the integer division at position "div", which is assumed
2379 * not to appear in any of the constraints or
2380 * in any of the other integer divisions.
2382 * Since the integer division is redundant, there is no need to cow.
2384 __isl_give isl_basic_map
*isl_basic_map_drop_div(
2385 __isl_take isl_basic_map
*bmap
, unsigned div
)
2387 return isl_basic_map_drop_core(bmap
, isl_dim_div
, div
, 1);
2390 /* Eliminate the specified n dimensions starting at first from the
2391 * constraints, without removing the dimensions from the space.
2392 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2394 __isl_give isl_map
*isl_map_eliminate(__isl_take isl_map
*map
,
2395 enum isl_dim_type type
, unsigned first
, unsigned n
)
2402 if (isl_map_check_range(map
, type
, first
, n
) < 0)
2403 return isl_map_free(map
);
2405 map
= isl_map_cow(map
);
2409 for (i
= 0; i
< map
->n
; ++i
) {
2410 map
->p
[i
] = isl_basic_map_eliminate(map
->p
[i
], type
, first
, n
);
2420 /* Eliminate the specified n dimensions starting at first from the
2421 * constraints, without removing the dimensions from the space.
2422 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2424 __isl_give isl_set
*isl_set_eliminate(__isl_take isl_set
*set
,
2425 enum isl_dim_type type
, unsigned first
, unsigned n
)
2427 return set_from_map(isl_map_eliminate(set_to_map(set
), type
, first
, n
));
2430 /* Eliminate the specified n dimensions starting at first from the
2431 * constraints, without removing the dimensions from the space.
2432 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2434 __isl_give isl_set
*isl_set_eliminate_dims(__isl_take isl_set
*set
,
2435 unsigned first
, unsigned n
)
2437 return isl_set_eliminate(set
, isl_dim_set
, first
, n
);
2440 __isl_give isl_basic_map
*isl_basic_map_remove_divs(
2441 __isl_take isl_basic_map
*bmap
)
2445 v_div
= isl_basic_map_var_offset(bmap
, isl_dim_div
);
2447 return isl_basic_map_free(bmap
);
2448 bmap
= isl_basic_map_eliminate_vars(bmap
, v_div
, bmap
->n_div
);
2452 return isl_basic_map_finalize(bmap
);
2455 __isl_give isl_basic_set
*isl_basic_set_remove_divs(
2456 __isl_take isl_basic_set
*bset
)
2458 return bset_from_bmap(isl_basic_map_remove_divs(bset_to_bmap(bset
)));
2461 __isl_give isl_map
*isl_map_remove_divs(__isl_take isl_map
*map
)
2470 map
= isl_map_cow(map
);
2474 for (i
= 0; i
< map
->n
; ++i
) {
2475 map
->p
[i
] = isl_basic_map_remove_divs(map
->p
[i
]);
2485 __isl_give isl_set
*isl_set_remove_divs(__isl_take isl_set
*set
)
2487 return isl_map_remove_divs(set
);
2490 __isl_give isl_basic_map
*isl_basic_map_remove_dims(
2491 __isl_take isl_basic_map
*bmap
, enum isl_dim_type type
,
2492 unsigned first
, unsigned n
)
2494 if (isl_basic_map_check_range(bmap
, type
, first
, n
) < 0)
2495 return isl_basic_map_free(bmap
);
2496 if (n
== 0 && !isl_space_is_named_or_nested(bmap
->dim
, type
))
2498 bmap
= isl_basic_map_eliminate_vars(bmap
,
2499 isl_basic_map_offset(bmap
, type
) - 1 + first
, n
);
2502 if (ISL_F_ISSET(bmap
, ISL_BASIC_MAP_EMPTY
) && type
== isl_dim_div
)
2504 bmap
= isl_basic_map_drop(bmap
, type
, first
, n
);
2508 /* Return true if the definition of the given div (recursively) involves
2509 * any of the given variables.
2511 static isl_bool
div_involves_vars(__isl_keep isl_basic_map
*bmap
, int div
,
2512 unsigned first
, unsigned n
)
2515 unsigned div_offset
= isl_basic_map_offset(bmap
, isl_dim_div
);
2517 if (isl_int_is_zero(bmap
->div
[div
][0]))
2518 return isl_bool_false
;
2519 if (isl_seq_first_non_zero(bmap
->div
[div
] + 1 + first
, n
) >= 0)
2520 return isl_bool_true
;
2522 for (i
= bmap
->n_div
- 1; i
>= 0; --i
) {
2525 if (isl_int_is_zero(bmap
->div
[div
][1 + div_offset
+ i
]))
2527 involves
= div_involves_vars(bmap
, i
, first
, n
);
2528 if (involves
< 0 || involves
)
2532 return isl_bool_false
;
2535 /* Try and add a lower and/or upper bound on "div" to "bmap"
2536 * based on inequality "i".
2537 * "total" is the total number of variables (excluding the divs).
2538 * "v" is a temporary object that can be used during the calculations.
2539 * If "lb" is set, then a lower bound should be constructed.
2540 * If "ub" is set, then an upper bound should be constructed.
2542 * The calling function has already checked that the inequality does not
2543 * reference "div", but we still need to check that the inequality is
2544 * of the right form. We'll consider the case where we want to construct
2545 * a lower bound. The construction of upper bounds is similar.
2547 * Let "div" be of the form
2549 * q = floor((a + f(x))/d)
2551 * We essentially check if constraint "i" is of the form
2555 * so that we can use it to derive a lower bound on "div".
2556 * However, we allow a slightly more general form
2560 * with the condition that the coefficients of g(x) - f(x) are all
2562 * Rewriting this constraint as
2566 * adding a + f(x) to both sides and dividing by d, we obtain
2568 * (a + f(x))/d >= (a-b)/d + (f(x)-g(x))/d
2570 * Taking the floor on both sides, we obtain
2572 * q >= floor((a-b)/d) + (f(x)-g(x))/d
2576 * (g(x)-f(x))/d + ceil((b-a)/d) + q >= 0
2578 * In the case of an upper bound, we construct the constraint
2580 * (g(x)+f(x))/d + floor((b+a)/d) - q >= 0
2583 static __isl_give isl_basic_map
*insert_bounds_on_div_from_ineq(
2584 __isl_take isl_basic_map
*bmap
, int div
, int i
,
2585 unsigned total
, isl_int v
, int lb
, int ub
)
2589 for (j
= 0; (lb
|| ub
) && j
< total
+ bmap
->n_div
; ++j
) {
2591 isl_int_sub(v
, bmap
->ineq
[i
][1 + j
],
2592 bmap
->div
[div
][1 + 1 + j
]);
2593 lb
= isl_int_is_divisible_by(v
, bmap
->div
[div
][0]);
2596 isl_int_add(v
, bmap
->ineq
[i
][1 + j
],
2597 bmap
->div
[div
][1 + 1 + j
]);
2598 ub
= isl_int_is_divisible_by(v
, bmap
->div
[div
][0]);
2604 bmap
= isl_basic_map_cow(bmap
);
2605 bmap
= isl_basic_map_extend_constraints(bmap
, 0, lb
+ ub
);
2607 int k
= isl_basic_map_alloc_inequality(bmap
);
2610 for (j
= 0; j
< 1 + total
+ bmap
->n_div
; ++j
) {
2611 isl_int_sub(bmap
->ineq
[k
][j
], bmap
->ineq
[i
][j
],
2612 bmap
->div
[div
][1 + j
]);
2613 isl_int_cdiv_q(bmap
->ineq
[k
][j
],
2614 bmap
->ineq
[k
][j
], bmap
->div
[div
][0]);
2616 isl_int_set_si(bmap
->ineq
[k
][1 + total
+ div
], 1);
2619 int k
= isl_basic_map_alloc_inequality(bmap
);
2622 for (j
= 0; j
< 1 + total
+ bmap
->n_div
; ++j
) {
2623 isl_int_add(bmap
->ineq
[k
][j
], bmap
->ineq
[i
][j
],
2624 bmap
->div
[div
][1 + j
]);
2625 isl_int_fdiv_q(bmap
->ineq
[k
][j
],
2626 bmap
->ineq
[k
][j
], bmap
->div
[div
][0]);
2628 isl_int_set_si(bmap
->ineq
[k
][1 + total
+ div
], -1);
2633 isl_basic_map_free(bmap
);
2637 /* This function is called right before "div" is eliminated from "bmap"
2638 * using Fourier-Motzkin.
2639 * Look through the constraints of "bmap" for constraints on the argument
2640 * of the integer division and use them to construct constraints on the
2641 * integer division itself. These constraints can then be combined
2642 * during the Fourier-Motzkin elimination.
2643 * Note that it is only useful to introduce lower bounds on "div"
2644 * if "bmap" already contains upper bounds on "div" as the newly
2645 * introduce lower bounds can then be combined with the pre-existing
2646 * upper bounds. Similarly for upper bounds.
2647 * We therefore first check if "bmap" contains any lower and/or upper bounds
2650 * It is interesting to note that the introduction of these constraints
2651 * can indeed lead to more accurate results, even when compared to
2652 * deriving constraints on the argument of "div" from constraints on "div".
2653 * Consider, for example, the set
2655 * { [i,j,k] : 3 + i + 2j >= 0 and 2 * [(i+2j)/4] <= k }
2657 * The second constraint can be rewritten as
2659 * 2 * [(-i-2j+3)/4] + k >= 0
2661 * from which we can derive
2663 * -i - 2j + 3 >= -2k
2669 * Combined with the first constraint, we obtain
2671 * -3 <= 3 + 2k or k >= -3
2673 * If, on the other hand we derive a constraint on [(i+2j)/4] from
2674 * the first constraint, we obtain
2676 * [(i + 2j)/4] >= [-3/4] = -1
2678 * Combining this constraint with the second constraint, we obtain
2682 static __isl_give isl_basic_map
*insert_bounds_on_div(
2683 __isl_take isl_basic_map
*bmap
, int div
)
2686 int check_lb
, check_ub
;
2693 if (isl_int_is_zero(bmap
->div
[div
][0]))
2696 v_div
= isl_basic_map_var_offset(bmap
, isl_dim_div
);
2698 return isl_basic_map_free(bmap
);
2702 for (i
= 0; (!check_lb
|| !check_ub
) && i
< bmap
->n_ineq
; ++i
) {
2703 int s
= isl_int_sgn(bmap
->ineq
[i
][1 + v_div
+ div
]);
2710 if (!check_lb
&& !check_ub
)
2715 for (i
= 0; bmap
&& i
< bmap
->n_ineq
; ++i
) {
2716 if (!isl_int_is_zero(bmap
->ineq
[i
][1 + v_div
+ div
]))
2719 bmap
= insert_bounds_on_div_from_ineq(bmap
, div
, i
, v_div
, v
,
2720 check_lb
, check_ub
);
2728 /* Remove all divs (recursively) involving any of the given dimensions
2729 * in their definitions.
2731 __isl_give isl_basic_map
*isl_basic_map_remove_divs_involving_dims(
2732 __isl_take isl_basic_map
*bmap
,
2733 enum isl_dim_type type
, unsigned first
, unsigned n
)
2737 if (isl_basic_map_check_range(bmap
, type
, first
, n
) < 0)
2738 return isl_basic_map_free(bmap
);
2739 first
+= isl_basic_map_offset(bmap
, type
);
2741 for (i
= bmap
->n_div
- 1; i
>= 0; --i
) {
2744 involves
= div_involves_vars(bmap
, i
, first
, n
);
2746 return isl_basic_map_free(bmap
);
2749 bmap
= insert_bounds_on_div(bmap
, i
);
2750 bmap
= isl_basic_map_remove_dims(bmap
, isl_dim_div
, i
, 1);
2759 __isl_give isl_basic_set
*isl_basic_set_remove_divs_involving_dims(
2760 __isl_take isl_basic_set
*bset
,
2761 enum isl_dim_type type
, unsigned first
, unsigned n
)
2763 return isl_basic_map_remove_divs_involving_dims(bset
, type
, first
, n
);
2766 __isl_give isl_map
*isl_map_remove_divs_involving_dims(__isl_take isl_map
*map
,
2767 enum isl_dim_type type
, unsigned first
, unsigned n
)
2776 map
= isl_map_cow(map
);
2780 for (i
= 0; i
< map
->n
; ++i
) {
2781 map
->p
[i
] = isl_basic_map_remove_divs_involving_dims(map
->p
[i
],
2792 __isl_give isl_set
*isl_set_remove_divs_involving_dims(__isl_take isl_set
*set
,
2793 enum isl_dim_type type
, unsigned first
, unsigned n
)
2795 return set_from_map(isl_map_remove_divs_involving_dims(set_to_map(set
),
2799 /* Does the description of "bmap" depend on the specified dimensions?
2800 * We also check whether the dimensions appear in any of the div definitions.
2801 * In principle there is no need for this check. If the dimensions appear
2802 * in a div definition, they also appear in the defining constraints of that
2805 isl_bool
isl_basic_map_involves_dims(__isl_keep isl_basic_map
*bmap
,
2806 enum isl_dim_type type
, unsigned first
, unsigned n
)
2810 if (isl_basic_map_check_range(bmap
, type
, first
, n
) < 0)
2811 return isl_bool_error
;
2813 first
+= isl_basic_map_offset(bmap
, type
);
2814 for (i
= 0; i
< bmap
->n_eq
; ++i
)
2815 if (isl_seq_first_non_zero(bmap
->eq
[i
] + first
, n
) >= 0)
2816 return isl_bool_true
;
2817 for (i
= 0; i
< bmap
->n_ineq
; ++i
)
2818 if (isl_seq_first_non_zero(bmap
->ineq
[i
] + first
, n
) >= 0)
2819 return isl_bool_true
;
2820 for (i
= 0; i
< bmap
->n_div
; ++i
) {
2821 if (isl_int_is_zero(bmap
->div
[i
][0]))
2823 if (isl_seq_first_non_zero(bmap
->div
[i
] + 1 + first
, n
) >= 0)
2824 return isl_bool_true
;
2827 return isl_bool_false
;
2830 isl_bool
isl_map_involves_dims(__isl_keep isl_map
*map
,
2831 enum isl_dim_type type
, unsigned first
, unsigned n
)
2835 if (isl_map_check_range(map
, type
, first
, n
) < 0)
2836 return isl_bool_error
;
2838 for (i
= 0; i
< map
->n
; ++i
) {
2839 isl_bool involves
= isl_basic_map_involves_dims(map
->p
[i
],
2841 if (involves
< 0 || involves
)
2845 return isl_bool_false
;
2848 isl_bool
isl_basic_set_involves_dims(__isl_keep isl_basic_set
*bset
,
2849 enum isl_dim_type type
, unsigned first
, unsigned n
)
2851 return isl_basic_map_involves_dims(bset
, type
, first
, n
);
2854 isl_bool
isl_set_involves_dims(__isl_keep isl_set
*set
,
2855 enum isl_dim_type type
, unsigned first
, unsigned n
)
2857 return isl_map_involves_dims(set
, type
, first
, n
);
2860 /* Drop all constraints in bmap that involve any of the dimensions
2861 * first to first+n-1.
2862 * This function only performs the actual removal of constraints.
2864 * This function should not call finalize since it is used by
2865 * remove_redundant_divs, which in turn is called by isl_basic_map_finalize.
2867 __isl_give isl_basic_map
*isl_basic_map_drop_constraints_involving(
2868 __isl_take isl_basic_map
*bmap
, unsigned first
, unsigned n
)
2875 bmap
= isl_basic_map_cow(bmap
);
2880 for (i
= bmap
->n_eq
- 1; i
>= 0; --i
) {
2881 if (isl_seq_first_non_zero(bmap
->eq
[i
] + 1 + first
, n
) == -1)
2883 isl_basic_map_drop_equality(bmap
, i
);
2886 for (i
= bmap
->n_ineq
- 1; i
>= 0; --i
) {
2887 if (isl_seq_first_non_zero(bmap
->ineq
[i
] + 1 + first
, n
) == -1)
2889 isl_basic_map_drop_inequality(bmap
, i
);
2895 /* Drop all constraints in bset that involve any of the dimensions
2896 * first to first+n-1.
2897 * This function only performs the actual removal of constraints.
2899 __isl_give isl_basic_set
*isl_basic_set_drop_constraints_involving(
2900 __isl_take isl_basic_set
*bset
, unsigned first
, unsigned n
)
2902 return isl_basic_map_drop_constraints_involving(bset
, first
, n
);
2905 /* Drop all constraints in bmap that do not involve any of the dimensions
2906 * first to first + n - 1 of the given type.
2908 __isl_give isl_basic_map
*isl_basic_map_drop_constraints_not_involving_dims(
2909 __isl_take isl_basic_map
*bmap
,
2910 enum isl_dim_type type
, unsigned first
, unsigned n
)
2915 isl_space
*space
= isl_basic_map_get_space(bmap
);
2916 isl_basic_map_free(bmap
);
2917 return isl_basic_map_universe(space
);
2919 bmap
= isl_basic_map_cow(bmap
);
2923 if (isl_basic_map_check_range(bmap
, type
, first
, n
) < 0)
2924 return isl_basic_map_free(bmap
);
2926 first
+= isl_basic_map_offset(bmap
, type
) - 1;
2928 for (i
= bmap
->n_eq
- 1; i
>= 0; --i
) {
2929 if (isl_seq_first_non_zero(bmap
->eq
[i
] + 1 + first
, n
) != -1)
2931 isl_basic_map_drop_equality(bmap
, i
);
2934 for (i
= bmap
->n_ineq
- 1; i
>= 0; --i
) {
2935 if (isl_seq_first_non_zero(bmap
->ineq
[i
] + 1 + first
, n
) != -1)
2937 isl_basic_map_drop_inequality(bmap
, i
);
2940 bmap
= isl_basic_map_add_known_div_constraints(bmap
);
2944 /* Drop all constraints in bset that do not involve any of the dimensions
2945 * first to first + n - 1 of the given type.
2947 __isl_give isl_basic_set
*isl_basic_set_drop_constraints_not_involving_dims(
2948 __isl_take isl_basic_set
*bset
,
2949 enum isl_dim_type type
, unsigned first
, unsigned n
)
2951 return isl_basic_map_drop_constraints_not_involving_dims(bset
,
2955 /* Drop all constraints in bmap that involve any of the dimensions
2956 * first to first + n - 1 of the given type.
2958 __isl_give isl_basic_map
*isl_basic_map_drop_constraints_involving_dims(
2959 __isl_take isl_basic_map
*bmap
,
2960 enum isl_dim_type type
, unsigned first
, unsigned n
)
2967 if (isl_basic_map_check_range(bmap
, type
, first
, n
) < 0)
2968 return isl_basic_map_free(bmap
);
2970 bmap
= isl_basic_map_remove_divs_involving_dims(bmap
, type
, first
, n
);
2971 first
+= isl_basic_map_offset(bmap
, type
) - 1;
2972 bmap
= isl_basic_map_drop_constraints_involving(bmap
, first
, n
);
2973 bmap
= isl_basic_map_add_known_div_constraints(bmap
);
2977 /* Drop all constraints in bset that involve any of the dimensions
2978 * first to first + n - 1 of the given type.
2980 __isl_give isl_basic_set
*isl_basic_set_drop_constraints_involving_dims(
2981 __isl_take isl_basic_set
*bset
,
2982 enum isl_dim_type type
, unsigned first
, unsigned n
)
2984 return isl_basic_map_drop_constraints_involving_dims(bset
,
2988 /* Drop constraints from "map" by applying "drop" to each basic map.
2990 static __isl_give isl_map
*drop_constraints(__isl_take isl_map
*map
,
2991 enum isl_dim_type type
, unsigned first
, unsigned n
,
2992 __isl_give isl_basic_map
*(*drop
)(__isl_take isl_basic_map
*bmap
,
2993 enum isl_dim_type type
, unsigned first
, unsigned n
))
2997 if (isl_map_check_range(map
, type
, first
, n
) < 0)
2998 return isl_map_free(map
);
3000 map
= isl_map_cow(map
);
3004 for (i
= 0; i
< map
->n
; ++i
) {
3005 map
->p
[i
] = drop(map
->p
[i
], type
, first
, n
);
3007 return isl_map_free(map
);
3011 ISL_F_CLR(map
, ISL_MAP_DISJOINT
);
3016 /* Drop all constraints in map that involve any of the dimensions
3017 * first to first + n - 1 of the given type.
3019 __isl_give isl_map
*isl_map_drop_constraints_involving_dims(
3020 __isl_take isl_map
*map
,
3021 enum isl_dim_type type
, unsigned first
, unsigned n
)
3025 return drop_constraints(map
, type
, first
, n
,
3026 &isl_basic_map_drop_constraints_involving_dims
);
3029 /* Drop all constraints in "map" that do not involve any of the dimensions
3030 * first to first + n - 1 of the given type.
3032 __isl_give isl_map
*isl_map_drop_constraints_not_involving_dims(
3033 __isl_take isl_map
*map
,
3034 enum isl_dim_type type
, unsigned first
, unsigned n
)
3037 isl_space
*space
= isl_map_get_space(map
);
3039 return isl_map_universe(space
);
3041 return drop_constraints(map
, type
, first
, n
,
3042 &isl_basic_map_drop_constraints_not_involving_dims
);
3045 /* Drop all constraints in set that involve any of the dimensions
3046 * first to first + n - 1 of the given type.
3048 __isl_give isl_set
*isl_set_drop_constraints_involving_dims(
3049 __isl_take isl_set
*set
,
3050 enum isl_dim_type type
, unsigned first
, unsigned n
)
3052 return isl_map_drop_constraints_involving_dims(set
, type
, first
, n
);
3055 /* Drop all constraints in "set" that do not involve any of the dimensions
3056 * first to first + n - 1 of the given type.
3058 __isl_give isl_set
*isl_set_drop_constraints_not_involving_dims(
3059 __isl_take isl_set
*set
,
3060 enum isl_dim_type type
, unsigned first
, unsigned n
)
3062 return isl_map_drop_constraints_not_involving_dims(set
, type
, first
, n
);
3065 /* Does local variable "div" of "bmap" have a complete explicit representation?
3066 * Having a complete explicit representation requires not only
3067 * an explicit representation, but also that all local variables
3068 * that appear in this explicit representation in turn have
3069 * a complete explicit representation.
3071 isl_bool
isl_basic_map_div_is_known(__isl_keep isl_basic_map
*bmap
, int div
)
3074 unsigned div_offset
= isl_basic_map_offset(bmap
, isl_dim_div
);
3077 marked
= isl_basic_map_div_is_marked_unknown(bmap
, div
);
3078 if (marked
< 0 || marked
)
3079 return isl_bool_not(marked
);
3081 for (i
= bmap
->n_div
- 1; i
>= 0; --i
) {
3084 if (isl_int_is_zero(bmap
->div
[div
][1 + div_offset
+ i
]))
3086 known
= isl_basic_map_div_is_known(bmap
, i
);
3087 if (known
< 0 || !known
)
3091 return isl_bool_true
;
3094 /* Remove all divs that are unknown or defined in terms of unknown divs.
3096 __isl_give isl_basic_map
*isl_basic_map_remove_unknown_divs(
3097 __isl_take isl_basic_map
*bmap
)
3104 for (i
= bmap
->n_div
- 1; i
>= 0; --i
) {
3105 if (isl_basic_map_div_is_known(bmap
, i
))
3107 bmap
= isl_basic_map_remove_dims(bmap
, isl_dim_div
, i
, 1);
3116 /* Remove all divs that are unknown or defined in terms of unknown divs.
3118 __isl_give isl_basic_set
*isl_basic_set_remove_unknown_divs(
3119 __isl_take isl_basic_set
*bset
)
3121 return isl_basic_map_remove_unknown_divs(bset
);
3124 __isl_give isl_map
*isl_map_remove_unknown_divs(__isl_take isl_map
*map
)
3133 map
= isl_map_cow(map
);
3137 for (i
= 0; i
< map
->n
; ++i
) {
3138 map
->p
[i
] = isl_basic_map_remove_unknown_divs(map
->p
[i
]);
3148 __isl_give isl_set
*isl_set_remove_unknown_divs(__isl_take isl_set
*set
)
3150 return set_from_map(isl_map_remove_unknown_divs(set_to_map(set
)));
3153 __isl_give isl_basic_set
*isl_basic_set_remove_dims(
3154 __isl_take isl_basic_set
*bset
,
3155 enum isl_dim_type type
, unsigned first
, unsigned n
)
3157 isl_basic_map
*bmap
= bset_to_bmap(bset
);
3158 bmap
= isl_basic_map_remove_dims(bmap
, type
, first
, n
);
3159 return bset_from_bmap(bmap
);
3162 __isl_give isl_map
*isl_map_remove_dims(__isl_take isl_map
*map
,
3163 enum isl_dim_type type
, unsigned first
, unsigned n
)
3170 map
= isl_map_cow(map
);
3171 if (isl_map_check_range(map
, type
, first
, n
) < 0)
3172 return isl_map_free(map
);
3174 for (i
= 0; i
< map
->n
; ++i
) {
3175 map
->p
[i
] = isl_basic_map_eliminate_vars(map
->p
[i
],
3176 isl_basic_map_offset(map
->p
[i
], type
) - 1 + first
, n
);
3180 map
= isl_map_drop(map
, type
, first
, n
);
3187 __isl_give isl_set
*isl_set_remove_dims(__isl_take isl_set
*bset
,
3188 enum isl_dim_type type
, unsigned first
, unsigned n
)
3190 return set_from_map(isl_map_remove_dims(set_to_map(bset
),
3194 /* Project out n inputs starting at first using Fourier-Motzkin */
3195 struct isl_map
*isl_map_remove_inputs(struct isl_map
*map
,
3196 unsigned first
, unsigned n
)
3198 return isl_map_remove_dims(map
, isl_dim_in
, first
, n
);
3201 void isl_basic_set_print_internal(struct isl_basic_set
*bset
,
3202 FILE *out
, int indent
)
3207 fprintf(out
, "null basic set\n");
3211 fprintf(out
, "%*s", indent
, "");
3212 fprintf(out
, "ref: %d, nparam: %d, dim: %d, extra: %d, flags: %x\n",
3213 bset
->ref
, bset
->dim
->nparam
, bset
->dim
->n_out
,
3214 bset
->extra
, bset
->flags
);
3216 p
= isl_printer_to_file(isl_basic_set_get_ctx(bset
), out
);
3217 p
= isl_printer_set_dump(p
, 1);
3218 p
= isl_printer_set_indent(p
, indent
);
3219 p
= isl_printer_start_line(p
);
3220 p
= isl_printer_print_basic_set(p
, bset
);
3221 p
= isl_printer_end_line(p
);
3222 isl_printer_free(p
);
3225 void isl_basic_map_print_internal(struct isl_basic_map
*bmap
,
3226 FILE *out
, int indent
)
3231 fprintf(out
, "null basic map\n");
3235 fprintf(out
, "%*s", indent
, "");
3236 fprintf(out
, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "
3237 "flags: %x, n_name: %d\n",
3239 bmap
->dim
->nparam
, bmap
->dim
->n_in
, bmap
->dim
->n_out
,
3240 bmap
->extra
, bmap
->flags
, bmap
->dim
->n_id
);
3242 p
= isl_printer_to_file(isl_basic_map_get_ctx(bmap
), out
);
3243 p
= isl_printer_set_dump(p
, 1);
3244 p
= isl_printer_set_indent(p
, indent
);
3245 p
= isl_printer_start_line(p
);
3246 p
= isl_printer_print_basic_map(p
, bmap
);
3247 p
= isl_printer_end_line(p
);
3248 isl_printer_free(p
);
3251 __isl_give isl_basic_map
*isl_inequality_negate(__isl_take isl_basic_map
*bmap
,
3256 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
3258 return isl_basic_map_free(bmap
);
3259 if (pos
>= bmap
->n_ineq
)
3260 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
3261 "invalid position", return isl_basic_map_free(bmap
));
3262 isl_seq_neg(bmap
->ineq
[pos
], bmap
->ineq
[pos
], 1 + total
);
3263 isl_int_sub_ui(bmap
->ineq
[pos
][0], bmap
->ineq
[pos
][0], 1);
3264 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NO_REDUNDANT
);
3265 ISL_F_CLR(bmap
, ISL_BASIC_MAP_SORTED
);
3269 __isl_give isl_set
*isl_set_alloc_space(__isl_take isl_space
*space
, int n
,
3272 if (isl_space_check_is_set(space
) < 0)
3274 return isl_map_alloc_space(space
, n
, flags
);
3276 isl_space_free(space
);
3280 /* Make sure "map" has room for at least "n" more basic maps.
3282 __isl_give isl_map
*isl_map_grow(__isl_take isl_map
*map
, int n
)
3285 struct isl_map
*grown
= NULL
;
3289 isl_assert(map
->ctx
, n
>= 0, goto error
);
3290 if (map
->n
+ n
<= map
->size
)
3292 grown
= isl_map_alloc_space(isl_map_get_space(map
), map
->n
+ n
, map
->flags
);
3295 for (i
= 0; i
< map
->n
; ++i
) {
3296 grown
->p
[i
] = isl_basic_map_copy(map
->p
[i
]);
3304 isl_map_free(grown
);
3309 /* Make sure "set" has room for at least "n" more basic sets.
3311 struct isl_set
*isl_set_grow(struct isl_set
*set
, int n
)
3313 return set_from_map(isl_map_grow(set_to_map(set
), n
));
3316 __isl_give isl_set
*isl_set_from_basic_set(__isl_take isl_basic_set
*bset
)
3318 return isl_map_from_basic_map(bset
);
3321 __isl_give isl_map
*isl_map_from_basic_map(__isl_take isl_basic_map
*bmap
)
3323 struct isl_map
*map
;
3328 map
= isl_map_alloc_space(isl_space_copy(bmap
->dim
), 1, ISL_MAP_DISJOINT
);
3329 return isl_map_add_basic_map(map
, bmap
);
3332 __isl_give isl_set
*isl_set_add_basic_set(__isl_take isl_set
*set
,
3333 __isl_take isl_basic_set
*bset
)
3335 return set_from_map(isl_map_add_basic_map(set_to_map(set
),
3336 bset_to_bmap(bset
)));
3339 __isl_null isl_set
*isl_set_free(__isl_take isl_set
*set
)
3341 return isl_map_free(set
);
3344 void isl_set_print_internal(struct isl_set
*set
, FILE *out
, int indent
)
3349 fprintf(out
, "null set\n");
3353 fprintf(out
, "%*s", indent
, "");
3354 fprintf(out
, "ref: %d, n: %d, nparam: %d, dim: %d, flags: %x\n",
3355 set
->ref
, set
->n
, set
->dim
->nparam
, set
->dim
->n_out
,
3357 for (i
= 0; i
< set
->n
; ++i
) {
3358 fprintf(out
, "%*s", indent
, "");
3359 fprintf(out
, "basic set %d:\n", i
);
3360 isl_basic_set_print_internal(set
->p
[i
], out
, indent
+4);
3364 void isl_map_print_internal(struct isl_map
*map
, FILE *out
, int indent
)
3369 fprintf(out
, "null map\n");
3373 fprintf(out
, "%*s", indent
, "");
3374 fprintf(out
, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, "
3375 "flags: %x, n_name: %d\n",
3376 map
->ref
, map
->n
, map
->dim
->nparam
, map
->dim
->n_in
,
3377 map
->dim
->n_out
, map
->flags
, map
->dim
->n_id
);
3378 for (i
= 0; i
< map
->n
; ++i
) {
3379 fprintf(out
, "%*s", indent
, "");
3380 fprintf(out
, "basic map %d:\n", i
);
3381 isl_basic_map_print_internal(map
->p
[i
], out
, indent
+4);
3385 __isl_give isl_basic_map
*isl_basic_map_intersect_domain(
3386 __isl_take isl_basic_map
*bmap
, __isl_take isl_basic_set
*bset
)
3388 struct isl_basic_map
*bmap_domain
;
3391 if (isl_basic_map_check_equal_params(bmap
, bset_to_bmap(bset
)) < 0)
3394 dim
= isl_basic_set_dim(bset
, isl_dim_set
);
3398 isl_assert(bset
->ctx
,
3399 isl_basic_map_compatible_domain(bmap
, bset
), goto error
);
3401 bmap
= isl_basic_map_cow(bmap
);
3404 bmap
= isl_basic_map_extend_space(bmap
, isl_space_copy(bmap
->dim
),
3405 bset
->n_div
, bset
->n_eq
, bset
->n_ineq
);
3406 bmap_domain
= isl_basic_map_from_domain(bset
);
3407 bmap
= add_constraints(bmap
, bmap_domain
, 0, 0);
3409 bmap
= isl_basic_map_simplify(bmap
);
3410 return isl_basic_map_finalize(bmap
);
3412 isl_basic_map_free(bmap
);
3413 isl_basic_set_free(bset
);
3417 /* Check that the space of "bset" is the same as that of the range of "bmap".
3419 static isl_stat
isl_basic_map_check_compatible_range(
3420 __isl_keep isl_basic_map
*bmap
, __isl_keep isl_basic_set
*bset
)
3424 ok
= isl_basic_map_compatible_range(bmap
, bset
);
3426 return isl_stat_error
;
3428 isl_die(isl_basic_set_get_ctx(bset
), isl_error_invalid
,
3429 "incompatible spaces", return isl_stat_error
);
3434 __isl_give isl_basic_map
*isl_basic_map_intersect_range(
3435 __isl_take isl_basic_map
*bmap
, __isl_take isl_basic_set
*bset
)
3437 struct isl_basic_map
*bmap_range
;
3440 if (isl_basic_map_check_equal_params(bmap
, bset_to_bmap(bset
)) < 0)
3443 dim
= isl_basic_set_dim(bset
, isl_dim_set
);
3446 if (dim
!= 0 && isl_basic_map_check_compatible_range(bmap
, bset
) < 0)
3449 if (isl_basic_set_plain_is_universe(bset
)) {
3450 isl_basic_set_free(bset
);
3454 bmap
= isl_basic_map_cow(bmap
);
3457 bmap
= isl_basic_map_extend_space(bmap
, isl_space_copy(bmap
->dim
),
3458 bset
->n_div
, bset
->n_eq
, bset
->n_ineq
);
3459 bmap_range
= bset_to_bmap(bset
);
3460 bmap
= add_constraints(bmap
, bmap_range
, 0, 0);
3462 bmap
= isl_basic_map_simplify(bmap
);
3463 return isl_basic_map_finalize(bmap
);
3465 isl_basic_map_free(bmap
);
3466 isl_basic_set_free(bset
);
3470 isl_bool
isl_basic_map_contains(__isl_keep isl_basic_map
*bmap
,
3471 __isl_keep isl_vec
*vec
)
3477 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
3478 if (total
< 0 || !vec
)
3479 return isl_bool_error
;
3481 if (1 + total
!= vec
->size
)
3482 return isl_bool_false
;
3486 for (i
= 0; i
< bmap
->n_eq
; ++i
) {
3487 isl_seq_inner_product(vec
->el
, bmap
->eq
[i
], 1 + total
, &s
);
3488 if (!isl_int_is_zero(s
)) {
3490 return isl_bool_false
;
3494 for (i
= 0; i
< bmap
->n_ineq
; ++i
) {
3495 isl_seq_inner_product(vec
->el
, bmap
->ineq
[i
], 1 + total
, &s
);
3496 if (isl_int_is_neg(s
)) {
3498 return isl_bool_false
;
3504 return isl_bool_true
;
3507 isl_bool
isl_basic_set_contains(__isl_keep isl_basic_set
*bset
,
3508 __isl_keep isl_vec
*vec
)
3510 return isl_basic_map_contains(bset_to_bmap(bset
), vec
);
3513 __isl_give isl_basic_map
*isl_basic_map_intersect(
3514 __isl_take isl_basic_map
*bmap1
, __isl_take isl_basic_map
*bmap2
)
3516 struct isl_vec
*sample
= NULL
;
3517 isl_space
*space1
, *space2
;
3518 isl_size dim1
, dim2
, nparam1
, nparam2
;
3520 if (isl_basic_map_check_equal_params(bmap1
, bmap2
) < 0)
3522 space1
= isl_basic_map_peek_space(bmap1
);
3523 space2
= isl_basic_map_peek_space(bmap2
);
3524 dim1
= isl_space_dim(space1
, isl_dim_all
);
3525 dim2
= isl_space_dim(space2
, isl_dim_all
);
3526 nparam1
= isl_space_dim(space1
, isl_dim_param
);
3527 nparam2
= isl_space_dim(space2
, isl_dim_param
);
3528 if (dim1
< 0 || dim2
< 0 || nparam1
< 0 || nparam2
< 0)
3530 if (dim1
== nparam1
&& dim2
!= nparam2
)
3531 return isl_basic_map_intersect(bmap2
, bmap1
);
3533 if (dim2
!= nparam2
)
3534 isl_assert(bmap1
->ctx
,
3535 isl_space_is_equal(bmap1
->dim
, bmap2
->dim
), goto error
);
3537 if (isl_basic_map_plain_is_empty(bmap1
)) {
3538 isl_basic_map_free(bmap2
);
3541 if (isl_basic_map_plain_is_empty(bmap2
)) {
3542 isl_basic_map_free(bmap1
);
3546 if (bmap1
->sample
&&
3547 isl_basic_map_contains(bmap1
, bmap1
->sample
) > 0 &&
3548 isl_basic_map_contains(bmap2
, bmap1
->sample
) > 0)
3549 sample
= isl_vec_copy(bmap1
->sample
);
3550 else if (bmap2
->sample
&&
3551 isl_basic_map_contains(bmap1
, bmap2
->sample
) > 0 &&
3552 isl_basic_map_contains(bmap2
, bmap2
->sample
) > 0)
3553 sample
= isl_vec_copy(bmap2
->sample
);
3555 bmap1
= isl_basic_map_cow(bmap1
);
3558 bmap1
= isl_basic_map_extend_space(bmap1
, isl_space_copy(bmap1
->dim
),
3559 bmap2
->n_div
, bmap2
->n_eq
, bmap2
->n_ineq
);
3560 bmap1
= add_constraints(bmap1
, bmap2
, 0, 0);
3563 isl_vec_free(sample
);
3565 isl_vec_free(bmap1
->sample
);
3566 bmap1
->sample
= sample
;
3569 bmap1
= isl_basic_map_simplify(bmap1
);
3570 return isl_basic_map_finalize(bmap1
);
3573 isl_vec_free(sample
);
3574 isl_basic_map_free(bmap1
);
3575 isl_basic_map_free(bmap2
);
3579 struct isl_basic_set
*isl_basic_set_intersect(
3580 struct isl_basic_set
*bset1
, struct isl_basic_set
*bset2
)
3582 return bset_from_bmap(isl_basic_map_intersect(bset_to_bmap(bset1
),
3583 bset_to_bmap(bset2
)));
3586 __isl_give isl_basic_set
*isl_basic_set_intersect_params(
3587 __isl_take isl_basic_set
*bset1
, __isl_take isl_basic_set
*bset2
)
3589 return isl_basic_set_intersect(bset1
, bset2
);
3592 /* Special case of isl_map_intersect, where both map1 and map2
3593 * are convex, without any divs and such that either map1 or map2
3594 * contains a single constraint. This constraint is then simply
3595 * added to the other map.
3597 static __isl_give isl_map
*map_intersect_add_constraint(
3598 __isl_take isl_map
*map1
, __isl_take isl_map
*map2
)
3600 isl_assert(map1
->ctx
, map1
->n
== 1, goto error
);
3601 isl_assert(map2
->ctx
, map1
->n
== 1, goto error
);
3602 isl_assert(map1
->ctx
, map1
->p
[0]->n_div
== 0, goto error
);
3603 isl_assert(map2
->ctx
, map1
->p
[0]->n_div
== 0, goto error
);
3605 if (map2
->p
[0]->n_eq
+ map2
->p
[0]->n_ineq
!= 1)
3606 return isl_map_intersect(map2
, map1
);
3608 map1
= isl_map_cow(map1
);
3611 if (isl_map_plain_is_empty(map1
)) {
3615 if (map2
->p
[0]->n_eq
== 1)
3616 map1
->p
[0] = isl_basic_map_add_eq(map1
->p
[0], map2
->p
[0]->eq
[0]);
3618 map1
->p
[0] = isl_basic_map_add_ineq(map1
->p
[0],
3619 map2
->p
[0]->ineq
[0]);
3621 map1
->p
[0] = isl_basic_map_simplify(map1
->p
[0]);
3622 map1
->p
[0] = isl_basic_map_finalize(map1
->p
[0]);
3626 if (isl_basic_map_plain_is_empty(map1
->p
[0])) {
3627 isl_basic_map_free(map1
->p
[0]);
3633 map1
= isl_map_unmark_normalized(map1
);
3641 /* map2 may be either a parameter domain or a map living in the same
3644 static __isl_give isl_map
*map_intersect_internal(__isl_take isl_map
*map1
,
3645 __isl_take isl_map
*map2
)
3651 isl_size dim2
, nparam2
;
3656 if ((isl_map_plain_is_empty(map1
) ||
3657 isl_map_plain_is_universe(map2
)) &&
3658 isl_space_is_equal(map1
->dim
, map2
->dim
)) {
3662 if ((isl_map_plain_is_empty(map2
) ||
3663 isl_map_plain_is_universe(map1
)) &&
3664 isl_space_is_equal(map1
->dim
, map2
->dim
)) {
3669 if (map1
->n
== 1 && map2
->n
== 1 &&
3670 map1
->p
[0]->n_div
== 0 && map2
->p
[0]->n_div
== 0 &&
3671 isl_space_is_equal(map1
->dim
, map2
->dim
) &&
3672 (map1
->p
[0]->n_eq
+ map1
->p
[0]->n_ineq
== 1 ||
3673 map2
->p
[0]->n_eq
+ map2
->p
[0]->n_ineq
== 1))
3674 return map_intersect_add_constraint(map1
, map2
);
3676 equal
= isl_map_plain_is_equal(map1
, map2
);
3684 dim2
= isl_map_dim(map2
, isl_dim_all
);
3685 nparam2
= isl_map_dim(map2
, isl_dim_param
);
3686 if (dim2
< 0 || nparam2
< 0)
3688 if (dim2
!= nparam2
)
3689 isl_assert(map1
->ctx
,
3690 isl_space_is_equal(map1
->dim
, map2
->dim
), goto error
);
3692 if (ISL_F_ISSET(map1
, ISL_MAP_DISJOINT
) &&
3693 ISL_F_ISSET(map2
, ISL_MAP_DISJOINT
))
3694 ISL_FL_SET(flags
, ISL_MAP_DISJOINT
);
3696 result
= isl_map_alloc_space(isl_space_copy(map1
->dim
),
3697 map1
->n
* map2
->n
, flags
);
3700 for (i
= 0; i
< map1
->n
; ++i
)
3701 for (j
= 0; j
< map2
->n
; ++j
) {
3702 struct isl_basic_map
*part
;
3703 part
= isl_basic_map_intersect(
3704 isl_basic_map_copy(map1
->p
[i
]),
3705 isl_basic_map_copy(map2
->p
[j
]));
3706 if (isl_basic_map_is_empty(part
) < 0)
3707 part
= isl_basic_map_free(part
);
3708 result
= isl_map_add_basic_map(result
, part
);
3721 static __isl_give isl_map
*map_intersect(__isl_take isl_map
*map1
,
3722 __isl_take isl_map
*map2
)
3726 if (!isl_space_is_equal(map1
->dim
, map2
->dim
))
3727 isl_die(isl_map_get_ctx(map1
), isl_error_invalid
,
3728 "spaces don't match", goto error
);
3729 return map_intersect_internal(map1
, map2
);
3736 __isl_give isl_map
*isl_map_intersect(__isl_take isl_map
*map1
,
3737 __isl_take isl_map
*map2
)
3739 return isl_map_align_params_map_map_and(map1
, map2
, &map_intersect
);
3742 struct isl_set
*isl_set_intersect(struct isl_set
*set1
, struct isl_set
*set2
)
3744 return set_from_map(isl_map_intersect(set_to_map(set1
),
3748 /* map_intersect_internal accepts intersections
3749 * with parameter domains, so we can just call that function.
3751 static __isl_give isl_map
*map_intersect_params(__isl_take isl_map
*map
,
3752 __isl_take isl_set
*params
)
3754 return map_intersect_internal(map
, params
);
3757 __isl_give isl_map
*isl_map_intersect_params(__isl_take isl_map
*map1
,
3758 __isl_take isl_map
*map2
)
3760 return isl_map_align_params_map_map_and(map1
, map2
, &map_intersect_params
);
3763 __isl_give isl_set
*isl_set_intersect_params(__isl_take isl_set
*set
,
3764 __isl_take isl_set
*params
)
3766 return isl_map_intersect_params(set
, params
);
3769 __isl_give isl_basic_map
*isl_basic_map_reverse(__isl_take isl_basic_map
*bmap
)
3777 bmap
= isl_basic_map_cow(bmap
);
3780 space
= isl_space_reverse(isl_space_copy(bmap
->dim
));
3781 pos
= isl_basic_map_offset(bmap
, isl_dim_in
);
3782 n1
= isl_basic_map_dim(bmap
, isl_dim_in
);
3783 n2
= isl_basic_map_dim(bmap
, isl_dim_out
);
3784 if (n1
< 0 || n2
< 0)
3785 bmap
= isl_basic_map_free(bmap
);
3786 bmap
= isl_basic_map_swap_vars(bmap
, pos
, n1
, n2
);
3787 return isl_basic_map_reset_space(bmap
, space
);
3790 static __isl_give isl_basic_map
*basic_map_space_reset(
3791 __isl_take isl_basic_map
*bmap
, enum isl_dim_type type
)
3797 if (!isl_space_is_named_or_nested(bmap
->dim
, type
))
3800 space
= isl_basic_map_get_space(bmap
);
3801 space
= isl_space_reset(space
, type
);
3802 bmap
= isl_basic_map_reset_space(bmap
, space
);
3806 __isl_give isl_basic_map
*isl_basic_map_insert_dims(
3807 __isl_take isl_basic_map
*bmap
, enum isl_dim_type type
,
3808 unsigned pos
, unsigned n
)
3810 isl_bool rational
, is_empty
;
3811 isl_space
*res_space
;
3812 struct isl_basic_map
*res
;
3813 struct isl_dim_map
*dim_map
;
3816 enum isl_dim_type t
;
3819 return basic_map_space_reset(bmap
, type
);
3821 is_empty
= isl_basic_map_plain_is_empty(bmap
);
3822 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
3823 if (is_empty
< 0 || total
< 0)
3824 return isl_basic_map_free(bmap
);
3825 res_space
= isl_space_insert_dims(isl_basic_map_get_space(bmap
),
3828 return isl_basic_map_free(bmap
);
3830 isl_basic_map_free(bmap
);
3831 return isl_basic_map_empty(res_space
);
3834 dim_map
= isl_dim_map_alloc(bmap
->ctx
, total
+ n
);
3836 for (t
= isl_dim_param
; t
<= isl_dim_out
; ++t
) {
3840 isl_dim_map_dim(dim_map
, bmap
->dim
, t
, off
);
3842 isl_size size
= isl_basic_map_dim(bmap
, t
);
3844 dim_map
= isl_dim_map_free(dim_map
);
3845 isl_dim_map_dim_range(dim_map
, bmap
->dim
, t
,
3847 isl_dim_map_dim_range(dim_map
, bmap
->dim
, t
,
3848 pos
, size
- pos
, off
+ pos
+ n
);
3850 dim
= isl_space_dim(res_space
, t
);
3852 dim_map
= isl_dim_map_free(dim_map
);
3855 isl_dim_map_div(dim_map
, bmap
, off
);
3857 res
= isl_basic_map_alloc_space(res_space
,
3858 bmap
->n_div
, bmap
->n_eq
, bmap
->n_ineq
);
3859 rational
= isl_basic_map_is_rational(bmap
);
3861 res
= isl_basic_map_free(res
);
3863 res
= isl_basic_map_set_rational(res
);
3864 res
= isl_basic_map_add_constraints_dim_map(res
, bmap
, dim_map
);
3865 return isl_basic_map_finalize(res
);
3868 __isl_give isl_basic_set
*isl_basic_set_insert_dims(
3869 __isl_take isl_basic_set
*bset
,
3870 enum isl_dim_type type
, unsigned pos
, unsigned n
)
3872 return isl_basic_map_insert_dims(bset
, type
, pos
, n
);
3875 __isl_give isl_basic_map
*isl_basic_map_add_dims(__isl_take isl_basic_map
*bmap
,
3876 enum isl_dim_type type
, unsigned n
)
3880 dim
= isl_basic_map_dim(bmap
, type
);
3882 return isl_basic_map_free(bmap
);
3883 return isl_basic_map_insert_dims(bmap
, type
, dim
, n
);
3886 __isl_give isl_basic_set
*isl_basic_set_add_dims(__isl_take isl_basic_set
*bset
,
3887 enum isl_dim_type type
, unsigned n
)
3891 isl_assert(bset
->ctx
, type
!= isl_dim_in
, goto error
);
3892 return isl_basic_map_add_dims(bset
, type
, n
);
3894 isl_basic_set_free(bset
);
3898 static __isl_give isl_map
*map_space_reset(__isl_take isl_map
*map
,
3899 enum isl_dim_type type
)
3903 if (!map
|| !isl_space_is_named_or_nested(map
->dim
, type
))
3906 space
= isl_map_get_space(map
);
3907 space
= isl_space_reset(space
, type
);
3908 map
= isl_map_reset_space(map
, space
);
3912 __isl_give isl_map
*isl_map_insert_dims(__isl_take isl_map
*map
,
3913 enum isl_dim_type type
, unsigned pos
, unsigned n
)
3918 return map_space_reset(map
, type
);
3920 map
= isl_map_cow(map
);
3924 map
->dim
= isl_space_insert_dims(map
->dim
, type
, pos
, n
);
3928 for (i
= 0; i
< map
->n
; ++i
) {
3929 map
->p
[i
] = isl_basic_map_insert_dims(map
->p
[i
], type
, pos
, n
);
3940 __isl_give isl_set
*isl_set_insert_dims(__isl_take isl_set
*set
,
3941 enum isl_dim_type type
, unsigned pos
, unsigned n
)
3943 return isl_map_insert_dims(set
, type
, pos
, n
);
3946 __isl_give isl_map
*isl_map_add_dims(__isl_take isl_map
*map
,
3947 enum isl_dim_type type
, unsigned n
)
3951 dim
= isl_map_dim(map
, type
);
3953 return isl_map_free(map
);
3954 return isl_map_insert_dims(map
, type
, dim
, n
);
3957 __isl_give isl_set
*isl_set_add_dims(__isl_take isl_set
*set
,
3958 enum isl_dim_type type
, unsigned n
)
3962 isl_assert(set
->ctx
, type
!= isl_dim_in
, goto error
);
3963 return set_from_map(isl_map_add_dims(set_to_map(set
), type
, n
));
3969 __isl_give isl_basic_map
*isl_basic_map_move_dims(
3970 __isl_take isl_basic_map
*bmap
,
3971 enum isl_dim_type dst_type
, unsigned dst_pos
,
3972 enum isl_dim_type src_type
, unsigned src_pos
, unsigned n
)
3975 struct isl_dim_map
*dim_map
;
3976 struct isl_basic_map
*res
;
3977 enum isl_dim_type t
;
3984 bmap
= isl_basic_map_reset(bmap
, src_type
);
3985 bmap
= isl_basic_map_reset(bmap
, dst_type
);
3989 if (isl_basic_map_check_range(bmap
, src_type
, src_pos
, n
) < 0)
3990 return isl_basic_map_free(bmap
);
3992 if (dst_type
== src_type
&& dst_pos
== src_pos
)
3995 isl_assert(bmap
->ctx
, dst_type
!= src_type
, goto error
);
3997 if (pos(bmap
->dim
, dst_type
) + dst_pos
==
3998 pos(bmap
->dim
, src_type
) + src_pos
+
3999 ((src_type
< dst_type
) ? n
: 0)) {
4000 bmap
= isl_basic_map_cow(bmap
);
4004 bmap
->dim
= isl_space_move_dims(bmap
->dim
, dst_type
, dst_pos
,
4005 src_type
, src_pos
, n
);
4009 bmap
= isl_basic_map_finalize(bmap
);
4014 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
4016 return isl_basic_map_free(bmap
);
4017 dim_map
= isl_dim_map_alloc(bmap
->ctx
, total
);
4020 space
= isl_basic_map_peek_space(bmap
);
4021 for (t
= isl_dim_param
; t
<= isl_dim_out
; ++t
) {
4022 isl_size size
= isl_space_dim(space
, t
);
4024 dim_map
= isl_dim_map_free(dim_map
);
4025 if (t
== dst_type
) {
4026 isl_dim_map_dim_range(dim_map
, space
, t
,
4029 isl_dim_map_dim_range(dim_map
, space
, src_type
,
4032 isl_dim_map_dim_range(dim_map
, space
, t
,
4033 dst_pos
, size
- dst_pos
, off
);
4034 off
+= size
- dst_pos
;
4035 } else if (t
== src_type
) {
4036 isl_dim_map_dim_range(dim_map
, space
, t
,
4039 isl_dim_map_dim_range(dim_map
, space
, t
,
4040 src_pos
+ n
, size
- src_pos
- n
, off
);
4041 off
+= size
- src_pos
- n
;
4043 isl_dim_map_dim(dim_map
, space
, t
, off
);
4047 isl_dim_map_div(dim_map
, bmap
, off
);
4049 res
= isl_basic_map_alloc_space(isl_basic_map_get_space(bmap
),
4050 bmap
->n_div
, bmap
->n_eq
, bmap
->n_ineq
);
4051 bmap
= isl_basic_map_add_constraints_dim_map(res
, bmap
, dim_map
);
4055 bmap
->dim
= isl_space_move_dims(bmap
->dim
, dst_type
, dst_pos
,
4056 src_type
, src_pos
, n
);
4060 ISL_F_CLR(bmap
, ISL_BASIC_MAP_SORTED
);
4061 bmap
= isl_basic_map_gauss(bmap
, NULL
);
4062 bmap
= isl_basic_map_finalize(bmap
);
4066 isl_basic_map_free(bmap
);
4070 __isl_give isl_basic_set
*isl_basic_set_move_dims(__isl_take isl_basic_set
*bset
,
4071 enum isl_dim_type dst_type
, unsigned dst_pos
,
4072 enum isl_dim_type src_type
, unsigned src_pos
, unsigned n
)
4074 isl_basic_map
*bmap
= bset_to_bmap(bset
);
4075 bmap
= isl_basic_map_move_dims(bmap
, dst_type
, dst_pos
,
4076 src_type
, src_pos
, n
);
4077 return bset_from_bmap(bmap
);
4080 __isl_give isl_set
*isl_set_move_dims(__isl_take isl_set
*set
,
4081 enum isl_dim_type dst_type
, unsigned dst_pos
,
4082 enum isl_dim_type src_type
, unsigned src_pos
, unsigned n
)
4086 isl_assert(set
->ctx
, dst_type
!= isl_dim_in
, goto error
);
4087 return set_from_map(isl_map_move_dims(set_to_map(set
),
4088 dst_type
, dst_pos
, src_type
, src_pos
, n
));
4094 __isl_give isl_map
*isl_map_move_dims(__isl_take isl_map
*map
,
4095 enum isl_dim_type dst_type
, unsigned dst_pos
,
4096 enum isl_dim_type src_type
, unsigned src_pos
, unsigned n
)
4101 map
= isl_map_reset(map
, src_type
);
4102 map
= isl_map_reset(map
, dst_type
);
4106 if (isl_map_check_range(map
, src_type
, src_pos
, n
))
4107 return isl_map_free(map
);
4109 if (dst_type
== src_type
&& dst_pos
== src_pos
)
4112 isl_assert(map
->ctx
, dst_type
!= src_type
, goto error
);
4114 map
= isl_map_cow(map
);
4118 map
->dim
= isl_space_move_dims(map
->dim
, dst_type
, dst_pos
, src_type
, src_pos
, n
);
4122 for (i
= 0; i
< map
->n
; ++i
) {
4123 map
->p
[i
] = isl_basic_map_move_dims(map
->p
[i
],
4125 src_type
, src_pos
, n
);
4136 /* Move the specified dimensions to the last columns right before
4137 * the divs. Don't change the dimension specification of bmap.
4138 * That's the responsibility of the caller.
4140 static __isl_give isl_basic_map
*move_last(__isl_take isl_basic_map
*bmap
,
4141 enum isl_dim_type type
, unsigned first
, unsigned n
)
4144 struct isl_dim_map
*dim_map
;
4145 struct isl_basic_map
*res
;
4146 enum isl_dim_type t
;
4152 if (isl_basic_map_offset(bmap
, type
) + first
+ n
==
4153 isl_basic_map_offset(bmap
, isl_dim_div
))
4156 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
4158 return isl_basic_map_free(bmap
);
4159 dim_map
= isl_dim_map_alloc(bmap
->ctx
, total
);
4162 space
= isl_basic_map_peek_space(bmap
);
4163 for (t
= isl_dim_param
; t
<= isl_dim_out
; ++t
) {
4164 isl_size size
= isl_space_dim(space
, t
);
4166 dim_map
= isl_dim_map_free(dim_map
);
4168 isl_dim_map_dim_range(dim_map
, space
, t
,
4171 isl_dim_map_dim_range(dim_map
, space
, t
,
4172 first
, n
, total
- bmap
->n_div
- n
);
4173 isl_dim_map_dim_range(dim_map
, space
, t
,
4174 first
+ n
, size
- (first
+ n
), off
);
4175 off
+= size
- (first
+ n
);
4177 isl_dim_map_dim(dim_map
, space
, t
, off
);
4181 isl_dim_map_div(dim_map
, bmap
, off
+ n
);
4183 res
= isl_basic_map_alloc_space(isl_basic_map_get_space(bmap
),
4184 bmap
->n_div
, bmap
->n_eq
, bmap
->n_ineq
);
4185 res
= isl_basic_map_add_constraints_dim_map(res
, bmap
, dim_map
);
4189 /* Insert "n" rows in the divs of "bmap".
4191 * The number of columns is not changed, which means that the last
4192 * dimensions of "bmap" are being reintepreted as the new divs.
4193 * The space of "bmap" is not adjusted, however, which means
4194 * that "bmap" is left in an inconsistent state. Removing "n" dimensions
4195 * from the space of "bmap" is the responsibility of the caller.
4197 static __isl_give isl_basic_map
*insert_div_rows(__isl_take isl_basic_map
*bmap
,
4205 bmap
= isl_basic_map_cow(bmap
);
4209 row_size
= isl_basic_map_offset(bmap
, isl_dim_div
) + bmap
->extra
;
4210 old
= bmap
->block2
.data
;
4211 bmap
->block2
= isl_blk_extend(bmap
->ctx
, bmap
->block2
,
4212 (bmap
->extra
+ n
) * (1 + row_size
));
4213 if (!bmap
->block2
.data
)
4214 return isl_basic_map_free(bmap
);
4215 new_div
= isl_alloc_array(bmap
->ctx
, isl_int
*, bmap
->extra
+ n
);
4217 return isl_basic_map_free(bmap
);
4218 for (i
= 0; i
< n
; ++i
) {
4219 new_div
[i
] = bmap
->block2
.data
+
4220 (bmap
->extra
+ i
) * (1 + row_size
);
4221 isl_seq_clr(new_div
[i
], 1 + row_size
);
4223 for (i
= 0; i
< bmap
->extra
; ++i
)
4224 new_div
[n
+ i
] = bmap
->block2
.data
+ (bmap
->div
[i
] - old
);
4226 bmap
->div
= new_div
;
4233 /* Drop constraints from "bmap" that only involve the variables
4234 * of "type" in the range [first, first + n] that are not related
4235 * to any of the variables outside that interval.
4236 * These constraints cannot influence the values for the variables
4237 * outside the interval, except in case they cause "bmap" to be empty.
4238 * Only drop the constraints if "bmap" is known to be non-empty.
4240 static __isl_give isl_basic_map
*drop_irrelevant_constraints(
4241 __isl_take isl_basic_map
*bmap
, enum isl_dim_type type
,
4242 unsigned first
, unsigned n
)
4246 isl_size dim
, n_div
;
4249 non_empty
= isl_basic_map_plain_is_non_empty(bmap
);
4251 return isl_basic_map_free(bmap
);
4255 dim
= isl_basic_map_dim(bmap
, isl_dim_all
);
4256 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
4257 if (dim
< 0 || n_div
< 0)
4258 return isl_basic_map_free(bmap
);
4259 groups
= isl_calloc_array(isl_basic_map_get_ctx(bmap
), int, dim
);
4261 return isl_basic_map_free(bmap
);
4262 first
+= isl_basic_map_offset(bmap
, type
) - 1;
4263 for (i
= 0; i
< first
; ++i
)
4265 for (i
= first
+ n
; i
< dim
- n_div
; ++i
)
4268 bmap
= isl_basic_map_drop_unrelated_constraints(bmap
, groups
);
4273 /* Turn the n dimensions of type type, starting at first
4274 * into existentially quantified variables.
4276 * If a subset of the projected out variables are unrelated
4277 * to any of the variables that remain, then the constraints
4278 * involving this subset are simply dropped first.
4280 __isl_give isl_basic_map
*isl_basic_map_project_out(
4281 __isl_take isl_basic_map
*bmap
,
4282 enum isl_dim_type type
, unsigned first
, unsigned n
)
4287 return basic_map_space_reset(bmap
, type
);
4288 if (type
== isl_dim_div
)
4289 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
4290 "cannot project out existentially quantified variables",
4291 return isl_basic_map_free(bmap
));
4293 empty
= isl_basic_map_plain_is_empty(bmap
);
4295 return isl_basic_map_free(bmap
);
4297 bmap
= isl_basic_map_set_to_empty(bmap
);
4299 bmap
= drop_irrelevant_constraints(bmap
, type
, first
, n
);
4303 if (ISL_F_ISSET(bmap
, ISL_BASIC_MAP_RATIONAL
))
4304 return isl_basic_map_remove_dims(bmap
, type
, first
, n
);
4306 if (isl_basic_map_check_range(bmap
, type
, first
, n
) < 0)
4307 return isl_basic_map_free(bmap
);
4309 bmap
= move_last(bmap
, type
, first
, n
);
4310 bmap
= isl_basic_map_cow(bmap
);
4311 bmap
= insert_div_rows(bmap
, n
);
4315 bmap
->dim
= isl_space_drop_dims(bmap
->dim
, type
, first
, n
);
4318 bmap
= isl_basic_map_simplify(bmap
);
4319 bmap
= isl_basic_map_drop_redundant_divs(bmap
);
4320 return isl_basic_map_finalize(bmap
);
4322 isl_basic_map_free(bmap
);
4326 /* Turn the n dimensions of type type, starting at first
4327 * into existentially quantified variables.
4329 struct isl_basic_set
*isl_basic_set_project_out(struct isl_basic_set
*bset
,
4330 enum isl_dim_type type
, unsigned first
, unsigned n
)
4332 return bset_from_bmap(isl_basic_map_project_out(bset_to_bmap(bset
),
4336 /* Turn the n dimensions of type type, starting at first
4337 * into existentially quantified variables.
4339 __isl_give isl_map
*isl_map_project_out(__isl_take isl_map
*map
,
4340 enum isl_dim_type type
, unsigned first
, unsigned n
)
4345 return map_space_reset(map
, type
);
4347 if (isl_map_check_range(map
, type
, first
, n
) < 0)
4348 return isl_map_free(map
);
4350 map
= isl_map_cow(map
);
4354 map
->dim
= isl_space_drop_dims(map
->dim
, type
, first
, n
);
4358 for (i
= 0; i
< map
->n
; ++i
) {
4359 map
->p
[i
] = isl_basic_map_project_out(map
->p
[i
], type
, first
, n
);
4370 /* Turn all the dimensions of type "type", except the "n" starting at "first"
4371 * into existentially quantified variables.
4373 __isl_give isl_map
*isl_map_project_onto(__isl_take isl_map
*map
,
4374 enum isl_dim_type type
, unsigned first
, unsigned n
)
4378 dim
= isl_map_dim(map
, type
);
4379 if (isl_map_check_range(map
, type
, first
, n
) < 0 || dim
< 0)
4380 return isl_map_free(map
);
4381 map
= isl_map_project_out(map
, type
, first
+ n
, dim
- (first
+ n
));
4382 map
= isl_map_project_out(map
, type
, 0, first
);
4386 /* Turn the n dimensions of type type, starting at first
4387 * into existentially quantified variables.
4389 __isl_give isl_set
*isl_set_project_out(__isl_take isl_set
*set
,
4390 enum isl_dim_type type
, unsigned first
, unsigned n
)
4392 return set_from_map(isl_map_project_out(set_to_map(set
),
4396 /* Return a map that projects the elements in "set" onto their
4397 * "n" set dimensions starting at "first".
4398 * "type" should be equal to isl_dim_set.
4400 __isl_give isl_map
*isl_set_project_onto_map(__isl_take isl_set
*set
,
4401 enum isl_dim_type type
, unsigned first
, unsigned n
)
4406 if (type
!= isl_dim_set
)
4407 isl_die(isl_set_get_ctx(set
), isl_error_invalid
,
4408 "only set dimensions can be projected out", goto error
);
4409 if (isl_set_check_range(set
, type
, first
, n
) < 0)
4410 return isl_set_free(set
);
4412 map
= isl_map_from_domain(set
);
4413 map
= isl_map_add_dims(map
, isl_dim_out
, n
);
4414 for (i
= 0; i
< n
; ++i
)
4415 map
= isl_map_equate(map
, isl_dim_in
, first
+ i
,
4423 static __isl_give isl_basic_map
*add_divs(__isl_take isl_basic_map
*bmap
,
4429 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
4431 return isl_basic_map_free(bmap
);
4432 for (i
= 0; i
< n
; ++i
) {
4433 j
= isl_basic_map_alloc_div(bmap
);
4436 isl_seq_clr(bmap
->div
[j
], 1 + 1 + total
);
4440 isl_basic_map_free(bmap
);
4444 struct isl_basic_map
*isl_basic_map_apply_range(
4445 struct isl_basic_map
*bmap1
, struct isl_basic_map
*bmap2
)
4447 isl_space
*space_result
= NULL
;
4448 struct isl_basic_map
*bmap
;
4449 isl_size n_in
, n_out
, n
, nparam
;
4450 unsigned total
, pos
;
4451 struct isl_dim_map
*dim_map1
, *dim_map2
;
4453 if (isl_basic_map_check_equal_params(bmap1
, bmap2
) < 0)
4455 if (!isl_space_tuple_is_equal(bmap1
->dim
, isl_dim_out
,
4456 bmap2
->dim
, isl_dim_in
))
4457 isl_die(isl_basic_map_get_ctx(bmap1
), isl_error_invalid
,
4458 "spaces don't match", goto error
);
4460 n_in
= isl_basic_map_dim(bmap1
, isl_dim_in
);
4461 n_out
= isl_basic_map_dim(bmap2
, isl_dim_out
);
4462 n
= isl_basic_map_dim(bmap1
, isl_dim_out
);
4463 nparam
= isl_basic_map_dim(bmap1
, isl_dim_param
);
4464 if (n_in
< 0 || n_out
< 0 || n
< 0 || nparam
< 0)
4467 space_result
= isl_space_join(isl_basic_map_get_space(bmap1
),
4468 isl_basic_map_get_space(bmap2
));
4470 total
= nparam
+ n_in
+ n_out
+ bmap1
->n_div
+ bmap2
->n_div
+ n
;
4471 dim_map1
= isl_dim_map_alloc(bmap1
->ctx
, total
);
4472 dim_map2
= isl_dim_map_alloc(bmap1
->ctx
, total
);
4473 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_param
, pos
= 0);
4474 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_param
, pos
= 0);
4475 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_in
, pos
+= nparam
);
4476 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_out
, pos
+= n_in
);
4477 isl_dim_map_div(dim_map1
, bmap1
, pos
+= n_out
);
4478 isl_dim_map_div(dim_map2
, bmap2
, pos
+= bmap1
->n_div
);
4479 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_out
, pos
+= bmap2
->n_div
);
4480 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_in
, pos
);
4482 bmap
= isl_basic_map_alloc_space(space_result
,
4483 bmap1
->n_div
+ bmap2
->n_div
+ n
,
4484 bmap1
->n_eq
+ bmap2
->n_eq
,
4485 bmap1
->n_ineq
+ bmap2
->n_ineq
);
4486 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap1
, dim_map1
);
4487 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap2
, dim_map2
);
4488 bmap
= add_divs(bmap
, n
);
4489 bmap
= isl_basic_map_simplify(bmap
);
4490 bmap
= isl_basic_map_drop_redundant_divs(bmap
);
4491 return isl_basic_map_finalize(bmap
);
4493 isl_basic_map_free(bmap1
);
4494 isl_basic_map_free(bmap2
);
4498 struct isl_basic_set
*isl_basic_set_apply(
4499 struct isl_basic_set
*bset
, struct isl_basic_map
*bmap
)
4504 isl_assert(bset
->ctx
, isl_basic_map_compatible_domain(bmap
, bset
),
4507 return bset_from_bmap(isl_basic_map_apply_range(bset_to_bmap(bset
),
4510 isl_basic_set_free(bset
);
4511 isl_basic_map_free(bmap
);
4515 struct isl_basic_map
*isl_basic_map_apply_domain(
4516 struct isl_basic_map
*bmap1
, struct isl_basic_map
*bmap2
)
4518 if (isl_basic_map_check_equal_params(bmap1
, bmap2
) < 0)
4520 if (!isl_space_tuple_is_equal(bmap1
->dim
, isl_dim_in
,
4521 bmap2
->dim
, isl_dim_in
))
4522 isl_die(isl_basic_map_get_ctx(bmap1
), isl_error_invalid
,
4523 "spaces don't match", goto error
);
4525 bmap1
= isl_basic_map_reverse(bmap1
);
4526 bmap1
= isl_basic_map_apply_range(bmap1
, bmap2
);
4527 return isl_basic_map_reverse(bmap1
);
4529 isl_basic_map_free(bmap1
);
4530 isl_basic_map_free(bmap2
);
4534 /* Given two basic maps A -> f(A) and B -> g(B), construct a basic map
4535 * A \cap B -> f(A) + f(B)
4537 __isl_give isl_basic_map
*isl_basic_map_sum(__isl_take isl_basic_map
*bmap1
,
4538 __isl_take isl_basic_map
*bmap2
)
4540 isl_size n_in
, n_out
, nparam
;
4541 unsigned total
, pos
;
4542 struct isl_basic_map
*bmap
= NULL
;
4543 struct isl_dim_map
*dim_map1
, *dim_map2
;
4546 if (!bmap1
|| !bmap2
)
4549 isl_assert(bmap1
->ctx
, isl_space_is_equal(bmap1
->dim
, bmap2
->dim
),
4552 nparam
= isl_basic_map_dim(bmap1
, isl_dim_param
);
4553 n_in
= isl_basic_map_dim(bmap1
, isl_dim_in
);
4554 n_out
= isl_basic_map_dim(bmap1
, isl_dim_out
);
4555 if (nparam
< 0 || n_in
< 0 || n_out
< 0)
4558 total
= nparam
+ n_in
+ n_out
+ bmap1
->n_div
+ bmap2
->n_div
+ 2 * n_out
;
4559 dim_map1
= isl_dim_map_alloc(bmap1
->ctx
, total
);
4560 dim_map2
= isl_dim_map_alloc(bmap2
->ctx
, total
);
4561 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_param
, pos
= 0);
4562 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_param
, pos
);
4563 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_in
, pos
+= nparam
);
4564 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_in
, pos
);
4565 isl_dim_map_div(dim_map1
, bmap1
, pos
+= n_in
+ n_out
);
4566 isl_dim_map_div(dim_map2
, bmap2
, pos
+= bmap1
->n_div
);
4567 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_out
, pos
+= bmap2
->n_div
);
4568 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_out
, pos
+= n_out
);
4570 bmap
= isl_basic_map_alloc_space(isl_space_copy(bmap1
->dim
),
4571 bmap1
->n_div
+ bmap2
->n_div
+ 2 * n_out
,
4572 bmap1
->n_eq
+ bmap2
->n_eq
+ n_out
,
4573 bmap1
->n_ineq
+ bmap2
->n_ineq
);
4574 for (i
= 0; i
< n_out
; ++i
) {
4575 int j
= isl_basic_map_alloc_equality(bmap
);
4578 isl_seq_clr(bmap
->eq
[j
], 1+total
);
4579 isl_int_set_si(bmap
->eq
[j
][1+nparam
+n_in
+i
], -1);
4580 isl_int_set_si(bmap
->eq
[j
][1+pos
+i
], 1);
4581 isl_int_set_si(bmap
->eq
[j
][1+pos
-n_out
+i
], 1);
4583 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap1
, dim_map1
);
4584 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap2
, dim_map2
);
4585 bmap
= add_divs(bmap
, 2 * n_out
);
4587 bmap
= isl_basic_map_simplify(bmap
);
4588 return isl_basic_map_finalize(bmap
);
4590 isl_basic_map_free(bmap
);
4591 isl_basic_map_free(bmap1
);
4592 isl_basic_map_free(bmap2
);
4596 /* Given two maps A -> f(A) and B -> g(B), construct a map
4597 * A \cap B -> f(A) + f(B)
4599 __isl_give isl_map
*isl_map_sum(__isl_take isl_map
*map1
,
4600 __isl_take isl_map
*map2
)
4602 struct isl_map
*result
;
4608 isl_assert(map1
->ctx
, isl_space_is_equal(map1
->dim
, map2
->dim
), goto error
);
4610 result
= isl_map_alloc_space(isl_space_copy(map1
->dim
),
4611 map1
->n
* map2
->n
, 0);
4614 for (i
= 0; i
< map1
->n
; ++i
)
4615 for (j
= 0; j
< map2
->n
; ++j
) {
4616 struct isl_basic_map
*part
;
4617 part
= isl_basic_map_sum(
4618 isl_basic_map_copy(map1
->p
[i
]),
4619 isl_basic_map_copy(map2
->p
[j
]));
4620 if (isl_basic_map_is_empty(part
))
4621 isl_basic_map_free(part
);
4623 result
= isl_map_add_basic_map(result
, part
);
4636 __isl_give isl_set
*isl_set_sum(__isl_take isl_set
*set1
,
4637 __isl_take isl_set
*set2
)
4639 return set_from_map(isl_map_sum(set_to_map(set1
), set_to_map(set2
)));
4642 /* Given a basic map A -> f(A), construct A -> -f(A).
4644 __isl_give isl_basic_map
*isl_basic_map_neg(__isl_take isl_basic_map
*bmap
)
4650 bmap
= isl_basic_map_cow(bmap
);
4651 n
= isl_basic_map_dim(bmap
, isl_dim_out
);
4653 return isl_basic_map_free(bmap
);
4655 off
= isl_basic_map_offset(bmap
, isl_dim_out
);
4656 for (i
= 0; i
< bmap
->n_eq
; ++i
)
4657 for (j
= 0; j
< n
; ++j
)
4658 isl_int_neg(bmap
->eq
[i
][off
+j
], bmap
->eq
[i
][off
+j
]);
4659 for (i
= 0; i
< bmap
->n_ineq
; ++i
)
4660 for (j
= 0; j
< n
; ++j
)
4661 isl_int_neg(bmap
->ineq
[i
][off
+j
], bmap
->ineq
[i
][off
+j
]);
4662 for (i
= 0; i
< bmap
->n_div
; ++i
)
4663 for (j
= 0; j
< n
; ++j
)
4664 isl_int_neg(bmap
->div
[i
][1+off
+j
], bmap
->div
[i
][1+off
+j
]);
4665 bmap
= isl_basic_map_gauss(bmap
, NULL
);
4666 return isl_basic_map_finalize(bmap
);
4669 __isl_give isl_basic_set
*isl_basic_set_neg(__isl_take isl_basic_set
*bset
)
4671 return isl_basic_map_neg(bset
);
4674 /* Given a map A -> f(A), construct A -> -f(A).
4676 __isl_give isl_map
*isl_map_neg(__isl_take isl_map
*map
)
4680 map
= isl_map_cow(map
);
4684 for (i
= 0; i
< map
->n
; ++i
) {
4685 map
->p
[i
] = isl_basic_map_neg(map
->p
[i
]);
4696 __isl_give isl_set
*isl_set_neg(__isl_take isl_set
*set
)
4698 return set_from_map(isl_map_neg(set_to_map(set
)));
4701 /* Given a basic map A -> f(A) and an integer d, construct a basic map
4702 * A -> floor(f(A)/d).
4704 __isl_give isl_basic_map
*isl_basic_map_floordiv(__isl_take isl_basic_map
*bmap
,
4707 isl_size n_in
, n_out
, nparam
;
4708 unsigned total
, pos
;
4709 struct isl_basic_map
*result
= NULL
;
4710 struct isl_dim_map
*dim_map
;
4713 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
4714 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
4715 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
4716 if (nparam
< 0 || n_in
< 0 || n_out
< 0)
4717 return isl_basic_map_free(bmap
);
4719 total
= nparam
+ n_in
+ n_out
+ bmap
->n_div
+ n_out
;
4720 dim_map
= isl_dim_map_alloc(bmap
->ctx
, total
);
4721 isl_dim_map_dim(dim_map
, bmap
->dim
, isl_dim_param
, pos
= 0);
4722 isl_dim_map_dim(dim_map
, bmap
->dim
, isl_dim_in
, pos
+= nparam
);
4723 isl_dim_map_div(dim_map
, bmap
, pos
+= n_in
+ n_out
);
4724 isl_dim_map_dim(dim_map
, bmap
->dim
, isl_dim_out
, pos
+= bmap
->n_div
);
4726 result
= isl_basic_map_alloc_space(isl_space_copy(bmap
->dim
),
4727 bmap
->n_div
+ n_out
,
4728 bmap
->n_eq
, bmap
->n_ineq
+ 2 * n_out
);
4729 result
= isl_basic_map_add_constraints_dim_map(result
, bmap
, dim_map
);
4730 result
= add_divs(result
, n_out
);
4731 for (i
= 0; i
< n_out
; ++i
) {
4733 j
= isl_basic_map_alloc_inequality(result
);
4736 isl_seq_clr(result
->ineq
[j
], 1+total
);
4737 isl_int_neg(result
->ineq
[j
][1+nparam
+n_in
+i
], d
);
4738 isl_int_set_si(result
->ineq
[j
][1+pos
+i
], 1);
4739 j
= isl_basic_map_alloc_inequality(result
);
4742 isl_seq_clr(result
->ineq
[j
], 1+total
);
4743 isl_int_set(result
->ineq
[j
][1+nparam
+n_in
+i
], d
);
4744 isl_int_set_si(result
->ineq
[j
][1+pos
+i
], -1);
4745 isl_int_sub_ui(result
->ineq
[j
][0], d
, 1);
4748 result
= isl_basic_map_simplify(result
);
4749 return isl_basic_map_finalize(result
);
4751 isl_basic_map_free(result
);
4755 /* Given a map A -> f(A) and an integer d, construct a map
4756 * A -> floor(f(A)/d).
4758 __isl_give isl_map
*isl_map_floordiv(__isl_take isl_map
*map
, isl_int d
)
4762 map
= isl_map_cow(map
);
4766 ISL_F_CLR(map
, ISL_MAP_DISJOINT
);
4767 for (i
= 0; i
< map
->n
; ++i
) {
4768 map
->p
[i
] = isl_basic_map_floordiv(map
->p
[i
], d
);
4772 map
= isl_map_unmark_normalized(map
);
4780 /* Given a map A -> f(A) and an integer d, construct a map
4781 * A -> floor(f(A)/d).
4783 __isl_give isl_map
*isl_map_floordiv_val(__isl_take isl_map
*map
,
4784 __isl_take isl_val
*d
)
4788 if (!isl_val_is_int(d
))
4789 isl_die(isl_val_get_ctx(d
), isl_error_invalid
,
4790 "expecting integer denominator", goto error
);
4791 map
= isl_map_floordiv(map
, d
->n
);
4800 static __isl_give isl_basic_map
*var_equal(__isl_take isl_basic_map
*bmap
,
4808 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
4809 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
4810 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
4811 if (total
< 0 || nparam
< 0 || n_in
< 0)
4812 return isl_basic_map_free(bmap
);
4813 i
= isl_basic_map_alloc_equality(bmap
);
4816 isl_seq_clr(bmap
->eq
[i
], 1 + total
);
4817 isl_int_set_si(bmap
->eq
[i
][1+nparam
+pos
], -1);
4818 isl_int_set_si(bmap
->eq
[i
][1+nparam
+n_in
+pos
], 1);
4819 return isl_basic_map_finalize(bmap
);
4821 isl_basic_map_free(bmap
);
4825 /* Add a constraint to "bmap" expressing i_pos < o_pos
4827 static __isl_give isl_basic_map
*var_less(__isl_take isl_basic_map
*bmap
,
4835 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
4836 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
4837 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
4838 if (total
< 0 || nparam
< 0 || n_in
< 0)
4839 return isl_basic_map_free(bmap
);
4840 i
= isl_basic_map_alloc_inequality(bmap
);
4843 isl_seq_clr(bmap
->ineq
[i
], 1 + total
);
4844 isl_int_set_si(bmap
->ineq
[i
][0], -1);
4845 isl_int_set_si(bmap
->ineq
[i
][1+nparam
+pos
], -1);
4846 isl_int_set_si(bmap
->ineq
[i
][1+nparam
+n_in
+pos
], 1);
4847 return isl_basic_map_finalize(bmap
);
4849 isl_basic_map_free(bmap
);
4853 /* Add a constraint to "bmap" expressing i_pos <= o_pos
4855 static __isl_give isl_basic_map
*var_less_or_equal(
4856 __isl_take isl_basic_map
*bmap
, unsigned pos
)
4863 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
4864 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
4865 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
4866 if (total
< 0 || nparam
< 0 || n_in
< 0)
4867 return isl_basic_map_free(bmap
);
4868 i
= isl_basic_map_alloc_inequality(bmap
);
4871 isl_seq_clr(bmap
->ineq
[i
], 1 + total
);
4872 isl_int_set_si(bmap
->ineq
[i
][1+nparam
+pos
], -1);
4873 isl_int_set_si(bmap
->ineq
[i
][1+nparam
+n_in
+pos
], 1);
4874 return isl_basic_map_finalize(bmap
);
4876 isl_basic_map_free(bmap
);
4880 /* Add a constraint to "bmap" expressing i_pos > o_pos
4882 static __isl_give isl_basic_map
*var_more(__isl_take isl_basic_map
*bmap
,
4890 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
4891 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
4892 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
4893 if (total
< 0 || nparam
< 0 || n_in
< 0)
4894 return isl_basic_map_free(bmap
);
4895 i
= isl_basic_map_alloc_inequality(bmap
);
4898 isl_seq_clr(bmap
->ineq
[i
], 1 + total
);
4899 isl_int_set_si(bmap
->ineq
[i
][0], -1);
4900 isl_int_set_si(bmap
->ineq
[i
][1+nparam
+pos
], 1);
4901 isl_int_set_si(bmap
->ineq
[i
][1+nparam
+n_in
+pos
], -1);
4902 return isl_basic_map_finalize(bmap
);
4904 isl_basic_map_free(bmap
);
4908 /* Add a constraint to "bmap" expressing i_pos >= o_pos
4910 static __isl_give isl_basic_map
*var_more_or_equal(
4911 __isl_take isl_basic_map
*bmap
, unsigned pos
)
4918 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
4919 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
4920 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
4921 if (total
< 0 || nparam
< 0 || n_in
< 0)
4922 return isl_basic_map_free(bmap
);
4923 i
= isl_basic_map_alloc_inequality(bmap
);
4926 isl_seq_clr(bmap
->ineq
[i
], 1 + total
);
4927 isl_int_set_si(bmap
->ineq
[i
][1+nparam
+pos
], 1);
4928 isl_int_set_si(bmap
->ineq
[i
][1+nparam
+n_in
+pos
], -1);
4929 return isl_basic_map_finalize(bmap
);
4931 isl_basic_map_free(bmap
);
4935 __isl_give isl_basic_map
*isl_basic_map_equal(
4936 __isl_take isl_space
*space
, unsigned n_equal
)
4939 struct isl_basic_map
*bmap
;
4940 bmap
= isl_basic_map_alloc_space(space
, 0, n_equal
, 0);
4943 for (i
= 0; i
< n_equal
&& bmap
; ++i
)
4944 bmap
= var_equal(bmap
, i
);
4945 return isl_basic_map_finalize(bmap
);
4948 /* Return a relation on of dimension "space" expressing i_[0..pos] << o_[0..pos]
4950 __isl_give isl_basic_map
*isl_basic_map_less_at(__isl_take isl_space
*space
,
4954 struct isl_basic_map
*bmap
;
4955 bmap
= isl_basic_map_alloc_space(space
, 0, pos
, 1);
4958 for (i
= 0; i
< pos
&& bmap
; ++i
)
4959 bmap
= var_equal(bmap
, i
);
4961 bmap
= var_less(bmap
, pos
);
4962 return isl_basic_map_finalize(bmap
);
4965 /* Return a relation on "space" expressing i_[0..pos] <<= o_[0..pos]
4967 __isl_give isl_basic_map
*isl_basic_map_less_or_equal_at(
4968 __isl_take isl_space
*space
, unsigned pos
)
4971 isl_basic_map
*bmap
;
4973 bmap
= isl_basic_map_alloc_space(space
, 0, pos
, 1);
4974 for (i
= 0; i
< pos
; ++i
)
4975 bmap
= var_equal(bmap
, i
);
4976 bmap
= var_less_or_equal(bmap
, pos
);
4977 return isl_basic_map_finalize(bmap
);
4980 /* Return a relation on "space" expressing i_pos > o_pos
4982 __isl_give isl_basic_map
*isl_basic_map_more_at(__isl_take isl_space
*space
,
4986 struct isl_basic_map
*bmap
;
4987 bmap
= isl_basic_map_alloc_space(space
, 0, pos
, 1);
4990 for (i
= 0; i
< pos
&& bmap
; ++i
)
4991 bmap
= var_equal(bmap
, i
);
4993 bmap
= var_more(bmap
, pos
);
4994 return isl_basic_map_finalize(bmap
);
4997 /* Return a relation on "space" expressing i_[0..pos] >>= o_[0..pos]
4999 __isl_give isl_basic_map
*isl_basic_map_more_or_equal_at(
5000 __isl_take isl_space
*space
, unsigned pos
)
5003 isl_basic_map
*bmap
;
5005 bmap
= isl_basic_map_alloc_space(space
, 0, pos
, 1);
5006 for (i
= 0; i
< pos
; ++i
)
5007 bmap
= var_equal(bmap
, i
);
5008 bmap
= var_more_or_equal(bmap
, pos
);
5009 return isl_basic_map_finalize(bmap
);
5012 static __isl_give isl_map
*map_lex_lte_first(__isl_take isl_space
*space
,
5013 unsigned n
, int equal
)
5015 struct isl_map
*map
;
5018 if (n
== 0 && equal
)
5019 return isl_map_universe(space
);
5021 map
= isl_map_alloc_space(isl_space_copy(space
), n
, ISL_MAP_DISJOINT
);
5023 for (i
= 0; i
+ 1 < n
; ++i
)
5024 map
= isl_map_add_basic_map(map
,
5025 isl_basic_map_less_at(isl_space_copy(space
), i
));
5028 map
= isl_map_add_basic_map(map
,
5029 isl_basic_map_less_or_equal_at(space
, n
- 1));
5031 map
= isl_map_add_basic_map(map
,
5032 isl_basic_map_less_at(space
, n
- 1));
5034 isl_space_free(space
);
5039 static __isl_give isl_map
*map_lex_lte(__isl_take isl_space
*space
, int equal
)
5043 return map_lex_lte_first(space
, space
->n_out
, equal
);
5046 __isl_give isl_map
*isl_map_lex_lt_first(__isl_take isl_space
*dim
, unsigned n
)
5048 return map_lex_lte_first(dim
, n
, 0);
5051 __isl_give isl_map
*isl_map_lex_le_first(__isl_take isl_space
*dim
, unsigned n
)
5053 return map_lex_lte_first(dim
, n
, 1);
5056 __isl_give isl_map
*isl_map_lex_lt(__isl_take isl_space
*set_dim
)
5058 return map_lex_lte(isl_space_map_from_set(set_dim
), 0);
5061 __isl_give isl_map
*isl_map_lex_le(__isl_take isl_space
*set_dim
)
5063 return map_lex_lte(isl_space_map_from_set(set_dim
), 1);
5066 static __isl_give isl_map
*map_lex_gte_first(__isl_take isl_space
*space
,
5067 unsigned n
, int equal
)
5069 struct isl_map
*map
;
5072 if (n
== 0 && equal
)
5073 return isl_map_universe(space
);
5075 map
= isl_map_alloc_space(isl_space_copy(space
), n
, ISL_MAP_DISJOINT
);
5077 for (i
= 0; i
+ 1 < n
; ++i
)
5078 map
= isl_map_add_basic_map(map
,
5079 isl_basic_map_more_at(isl_space_copy(space
), i
));
5082 map
= isl_map_add_basic_map(map
,
5083 isl_basic_map_more_or_equal_at(space
, n
- 1));
5085 map
= isl_map_add_basic_map(map
,
5086 isl_basic_map_more_at(space
, n
- 1));
5088 isl_space_free(space
);
5093 static __isl_give isl_map
*map_lex_gte(__isl_take isl_space
*space
, int equal
)
5097 return map_lex_gte_first(space
, space
->n_out
, equal
);
5100 __isl_give isl_map
*isl_map_lex_gt_first(__isl_take isl_space
*dim
, unsigned n
)
5102 return map_lex_gte_first(dim
, n
, 0);
5105 __isl_give isl_map
*isl_map_lex_ge_first(__isl_take isl_space
*dim
, unsigned n
)
5107 return map_lex_gte_first(dim
, n
, 1);
5110 __isl_give isl_map
*isl_map_lex_gt(__isl_take isl_space
*set_dim
)
5112 return map_lex_gte(isl_space_map_from_set(set_dim
), 0);
5115 __isl_give isl_map
*isl_map_lex_ge(__isl_take isl_space
*set_dim
)
5117 return map_lex_gte(isl_space_map_from_set(set_dim
), 1);
5120 __isl_give isl_map
*isl_set_lex_le_set(__isl_take isl_set
*set1
,
5121 __isl_take isl_set
*set2
)
5124 map
= isl_map_lex_le(isl_set_get_space(set1
));
5125 map
= isl_map_intersect_domain(map
, set1
);
5126 map
= isl_map_intersect_range(map
, set2
);
5130 __isl_give isl_map
*isl_set_lex_lt_set(__isl_take isl_set
*set1
,
5131 __isl_take isl_set
*set2
)
5134 map
= isl_map_lex_lt(isl_set_get_space(set1
));
5135 map
= isl_map_intersect_domain(map
, set1
);
5136 map
= isl_map_intersect_range(map
, set2
);
5140 __isl_give isl_map
*isl_set_lex_ge_set(__isl_take isl_set
*set1
,
5141 __isl_take isl_set
*set2
)
5144 map
= isl_map_lex_ge(isl_set_get_space(set1
));
5145 map
= isl_map_intersect_domain(map
, set1
);
5146 map
= isl_map_intersect_range(map
, set2
);
5150 __isl_give isl_map
*isl_set_lex_gt_set(__isl_take isl_set
*set1
,
5151 __isl_take isl_set
*set2
)
5154 map
= isl_map_lex_gt(isl_set_get_space(set1
));
5155 map
= isl_map_intersect_domain(map
, set1
);
5156 map
= isl_map_intersect_range(map
, set2
);
5160 __isl_give isl_map
*isl_map_lex_le_map(__isl_take isl_map
*map1
,
5161 __isl_take isl_map
*map2
)
5164 map
= isl_map_lex_le(isl_space_range(isl_map_get_space(map1
)));
5165 map
= isl_map_apply_domain(map
, isl_map_reverse(map1
));
5166 map
= isl_map_apply_range(map
, isl_map_reverse(map2
));
5170 __isl_give isl_map
*isl_map_lex_lt_map(__isl_take isl_map
*map1
,
5171 __isl_take isl_map
*map2
)
5174 map
= isl_map_lex_lt(isl_space_range(isl_map_get_space(map1
)));
5175 map
= isl_map_apply_domain(map
, isl_map_reverse(map1
));
5176 map
= isl_map_apply_range(map
, isl_map_reverse(map2
));
5180 __isl_give isl_map
*isl_map_lex_ge_map(__isl_take isl_map
*map1
,
5181 __isl_take isl_map
*map2
)
5184 map
= isl_map_lex_ge(isl_space_range(isl_map_get_space(map1
)));
5185 map
= isl_map_apply_domain(map
, isl_map_reverse(map1
));
5186 map
= isl_map_apply_range(map
, isl_map_reverse(map2
));
5190 __isl_give isl_map
*isl_map_lex_gt_map(__isl_take isl_map
*map1
,
5191 __isl_take isl_map
*map2
)
5194 map
= isl_map_lex_gt(isl_space_range(isl_map_get_space(map1
)));
5195 map
= isl_map_apply_domain(map
, isl_map_reverse(map1
));
5196 map
= isl_map_apply_range(map
, isl_map_reverse(map2
));
5200 /* For the div d = floor(f/m) at position "div", add the constraint
5204 static __isl_give isl_basic_map
*add_upper_div_constraint(
5205 __isl_take isl_basic_map
*bmap
, unsigned div
)
5208 isl_size v_div
= isl_basic_map_var_offset(bmap
, isl_dim_div
);
5212 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
5213 if (v_div
< 0 || n_div
< 0)
5214 return isl_basic_map_free(bmap
);
5216 i
= isl_basic_map_alloc_inequality(bmap
);
5218 return isl_basic_map_free(bmap
);
5219 isl_seq_cpy(bmap
->ineq
[i
], bmap
->div
[div
] + 1, 1 + v_div
+ n_div
);
5220 isl_int_neg(bmap
->ineq
[i
][1 + pos
], bmap
->div
[div
][0]);
5225 /* For the div d = floor(f/m) at position "div", add the constraint
5227 * -(f-(m-1)) + m d >= 0
5229 static __isl_give isl_basic_map
*add_lower_div_constraint(
5230 __isl_take isl_basic_map
*bmap
, unsigned div
)
5233 isl_size v_div
= isl_basic_map_var_offset(bmap
, isl_dim_div
);
5237 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
5238 if (v_div
< 0 || n_div
< 0)
5239 return isl_basic_map_free(bmap
);
5241 i
= isl_basic_map_alloc_inequality(bmap
);
5243 return isl_basic_map_free(bmap
);
5244 isl_seq_neg(bmap
->ineq
[i
], bmap
->div
[div
] + 1, 1 + v_div
+ n_div
);
5245 isl_int_set(bmap
->ineq
[i
][1 + pos
], bmap
->div
[div
][0]);
5246 isl_int_add(bmap
->ineq
[i
][0], bmap
->ineq
[i
][0], bmap
->ineq
[i
][1 + pos
]);
5247 isl_int_sub_ui(bmap
->ineq
[i
][0], bmap
->ineq
[i
][0], 1);
5252 /* For the div d = floor(f/m) at position "pos", add the constraints
5255 * -(f-(m-1)) + m d >= 0
5257 * Note that the second constraint is the negation of
5261 __isl_give isl_basic_map
*isl_basic_map_add_div_constraints(
5262 __isl_take isl_basic_map
*bmap
, unsigned pos
)
5264 bmap
= add_upper_div_constraint(bmap
, pos
);
5265 bmap
= add_lower_div_constraint(bmap
, pos
);
5269 /* For each known div d = floor(f/m), add the constraints
5272 * -(f-(m-1)) + m d >= 0
5274 * Remove duplicate constraints in case of some these div constraints
5275 * already appear in "bmap".
5277 __isl_give isl_basic_map
*isl_basic_map_add_known_div_constraints(
5278 __isl_take isl_basic_map
*bmap
)
5282 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
5284 return isl_basic_map_free(bmap
);
5288 bmap
= add_known_div_constraints(bmap
);
5289 bmap
= isl_basic_map_remove_duplicate_constraints(bmap
, NULL
, 0);
5290 bmap
= isl_basic_map_finalize(bmap
);
5294 /* Add the div constraint of sign "sign" for div "div" of "bmap".
5296 * In particular, if this div is of the form d = floor(f/m),
5297 * then add the constraint
5301 * if sign < 0 or the constraint
5303 * -(f-(m-1)) + m d >= 0
5307 __isl_give isl_basic_map
*isl_basic_map_add_div_constraint(
5308 __isl_take isl_basic_map
*bmap
, unsigned div
, int sign
)
5311 return add_upper_div_constraint(bmap
, div
);
5313 return add_lower_div_constraint(bmap
, div
);
5316 __isl_give isl_basic_set
*isl_basic_map_underlying_set(
5317 __isl_take isl_basic_map
*bmap
)
5321 if (bmap
->dim
->nparam
== 0 && bmap
->dim
->n_in
== 0 &&
5323 !isl_space_is_named_or_nested(bmap
->dim
, isl_dim_in
) &&
5324 !isl_space_is_named_or_nested(bmap
->dim
, isl_dim_out
))
5325 return bset_from_bmap(bmap
);
5326 bmap
= isl_basic_map_cow(bmap
);
5329 bmap
->dim
= isl_space_underlying(bmap
->dim
, bmap
->n_div
);
5332 bmap
->extra
-= bmap
->n_div
;
5334 bmap
= isl_basic_map_finalize(bmap
);
5335 return bset_from_bmap(bmap
);
5337 isl_basic_map_free(bmap
);
5341 __isl_give isl_basic_set
*isl_basic_set_underlying_set(
5342 __isl_take isl_basic_set
*bset
)
5344 return isl_basic_map_underlying_set(bset_to_bmap(bset
));
5347 /* Replace each element in "list" by the result of applying
5348 * isl_basic_map_underlying_set to the element.
5350 __isl_give isl_basic_set_list
*isl_basic_map_list_underlying_set(
5351 __isl_take isl_basic_map_list
*list
)
5356 n
= isl_basic_map_list_n_basic_map(list
);
5360 for (i
= 0; i
< n
; ++i
) {
5361 isl_basic_map
*bmap
;
5362 isl_basic_set
*bset
;
5364 bmap
= isl_basic_map_list_get_basic_map(list
, i
);
5365 bset
= isl_basic_set_underlying_set(bmap
);
5366 list
= isl_basic_set_list_set_basic_set(list
, i
, bset
);
5371 isl_basic_map_list_free(list
);
5375 __isl_give isl_basic_map
*isl_basic_map_overlying_set(
5376 __isl_take isl_basic_set
*bset
, __isl_take isl_basic_map
*like
)
5378 struct isl_basic_map
*bmap
;
5379 struct isl_ctx
*ctx
;
5380 isl_size dim
, bmap_total
;
5387 if (isl_basic_set_check_no_params(bset
) < 0 ||
5388 isl_basic_set_check_no_locals(bset
) < 0)
5390 dim
= isl_basic_set_dim(bset
, isl_dim_set
);
5391 bmap_total
= isl_basic_map_dim(like
, isl_dim_all
);
5392 if (dim
< 0 || bmap_total
< 0)
5394 isl_assert(ctx
, dim
== bmap_total
, goto error
);
5395 if (like
->n_div
== 0) {
5396 isl_space
*space
= isl_basic_map_get_space(like
);
5397 isl_basic_map_free(like
);
5398 return isl_basic_map_reset_space(bset
, space
);
5400 bset
= isl_basic_set_cow(bset
);
5403 total
= dim
+ bset
->extra
;
5404 bmap
= bset_to_bmap(bset
);
5405 isl_space_free(bmap
->dim
);
5406 bmap
->dim
= isl_space_copy(like
->dim
);
5409 bmap
->n_div
= like
->n_div
;
5410 bmap
->extra
+= like
->n_div
;
5414 ltotal
= total
- bmap
->extra
+ like
->extra
;
5417 bmap
->block2
= isl_blk_extend(ctx
, bmap
->block2
,
5418 bmap
->extra
* (1 + 1 + total
));
5419 if (isl_blk_is_error(bmap
->block2
))
5421 div
= isl_realloc_array(ctx
, bmap
->div
, isl_int
*, bmap
->extra
);
5425 for (i
= 0; i
< bmap
->extra
; ++i
)
5426 bmap
->div
[i
] = bmap
->block2
.data
+ i
* (1 + 1 + total
);
5427 for (i
= 0; i
< like
->n_div
; ++i
) {
5428 isl_seq_cpy(bmap
->div
[i
], like
->div
[i
], 1 + 1 + ltotal
);
5429 isl_seq_clr(bmap
->div
[i
]+1+1+ltotal
, total
- ltotal
);
5431 bmap
= isl_basic_map_add_known_div_constraints(bmap
);
5433 isl_basic_map_free(like
);
5434 bmap
= isl_basic_map_simplify(bmap
);
5435 bmap
= isl_basic_map_finalize(bmap
);
5438 isl_basic_map_free(like
);
5439 isl_basic_set_free(bset
);
5443 struct isl_basic_set
*isl_basic_set_from_underlying_set(
5444 struct isl_basic_set
*bset
, struct isl_basic_set
*like
)
5446 return bset_from_bmap(isl_basic_map_overlying_set(bset
,
5447 bset_to_bmap(like
)));
5450 __isl_give isl_set
*isl_map_underlying_set(__isl_take isl_map
*map
)
5454 map
= isl_map_cow(map
);
5457 map
->dim
= isl_space_cow(map
->dim
);
5461 for (i
= 1; i
< map
->n
; ++i
)
5462 isl_assert(map
->ctx
, map
->p
[0]->n_div
== map
->p
[i
]->n_div
,
5464 for (i
= 0; i
< map
->n
; ++i
) {
5465 map
->p
[i
] = bset_to_bmap(
5466 isl_basic_map_underlying_set(map
->p
[i
]));
5471 map
->dim
= isl_space_underlying(map
->dim
, 0);
5473 isl_space_free(map
->dim
);
5474 map
->dim
= isl_space_copy(map
->p
[0]->dim
);
5478 return set_from_map(map
);
5484 /* Replace the space of "bmap" by "space".
5486 * If the space of "bmap" is identical to "space" (including the identifiers
5487 * of the input and output dimensions), then simply return the original input.
5489 __isl_give isl_basic_map
*isl_basic_map_reset_space(
5490 __isl_take isl_basic_map
*bmap
, __isl_take isl_space
*space
)
5493 isl_space
*bmap_space
;
5495 bmap_space
= isl_basic_map_peek_space(bmap
);
5496 equal
= isl_space_is_equal(bmap_space
, space
);
5497 if (equal
>= 0 && equal
)
5498 equal
= isl_space_has_equal_ids(bmap_space
, space
);
5502 isl_space_free(space
);
5505 bmap
= isl_basic_map_cow(bmap
);
5506 if (!bmap
|| !space
)
5509 isl_space_free(bmap
->dim
);
5512 bmap
= isl_basic_map_finalize(bmap
);
5516 isl_basic_map_free(bmap
);
5517 isl_space_free(space
);
5521 __isl_give isl_basic_set
*isl_basic_set_reset_space(
5522 __isl_take isl_basic_set
*bset
, __isl_take isl_space
*dim
)
5524 return bset_from_bmap(isl_basic_map_reset_space(bset_to_bmap(bset
),
5528 /* Check that the total dimensions of "map" and "space" are the same.
5530 static isl_stat
check_map_space_equal_total_dim(__isl_keep isl_map
*map
,
5531 __isl_keep isl_space
*space
)
5533 isl_size dim1
, dim2
;
5535 dim1
= isl_map_dim(map
, isl_dim_all
);
5536 dim2
= isl_space_dim(space
, isl_dim_all
);
5537 if (dim1
< 0 || dim2
< 0)
5538 return isl_stat_error
;
5541 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
5542 "total dimensions do not match", return isl_stat_error
);
5545 __isl_give isl_map
*isl_map_reset_space(__isl_take isl_map
*map
,
5546 __isl_take isl_space
*space
)
5550 map
= isl_map_cow(map
);
5554 for (i
= 0; i
< map
->n
; ++i
) {
5555 map
->p
[i
] = isl_basic_map_reset_space(map
->p
[i
],
5556 isl_space_copy(space
));
5560 isl_space_free(map
->dim
);
5566 isl_space_free(space
);
5570 /* Replace the space of "map" by "space", without modifying
5571 * the dimension of "map".
5573 * If the space of "map" is identical to "space" (including the identifiers
5574 * of the input and output dimensions), then simply return the original input.
5576 __isl_give isl_map
*isl_map_reset_equal_dim_space(__isl_take isl_map
*map
,
5577 __isl_take isl_space
*space
)
5580 isl_space
*map_space
;
5582 map_space
= isl_map_peek_space(map
);
5583 equal
= isl_space_is_equal(map_space
, space
);
5584 if (equal
>= 0 && equal
)
5585 equal
= isl_space_has_equal_ids(map_space
, space
);
5589 isl_space_free(space
);
5592 if (check_map_space_equal_total_dim(map
, space
) < 0)
5594 return isl_map_reset_space(map
, space
);
5597 isl_space_free(space
);
5601 __isl_give isl_set
*isl_set_reset_space(__isl_take isl_set
*set
,
5602 __isl_take isl_space
*dim
)
5604 return set_from_map(isl_map_reset_space(set_to_map(set
), dim
));
5607 /* Compute the parameter domain of the given basic set.
5609 __isl_give isl_basic_set
*isl_basic_set_params(__isl_take isl_basic_set
*bset
)
5615 is_params
= isl_basic_set_is_params(bset
);
5617 return isl_basic_set_free(bset
);
5621 n
= isl_basic_set_dim(bset
, isl_dim_set
);
5623 return isl_basic_set_free(bset
);
5624 bset
= isl_basic_set_project_out(bset
, isl_dim_set
, 0, n
);
5625 space
= isl_basic_set_get_space(bset
);
5626 space
= isl_space_params(space
);
5627 bset
= isl_basic_set_reset_space(bset
, space
);
5631 /* Construct a zero-dimensional basic set with the given parameter domain.
5633 __isl_give isl_basic_set
*isl_basic_set_from_params(
5634 __isl_take isl_basic_set
*bset
)
5637 space
= isl_basic_set_get_space(bset
);
5638 space
= isl_space_set_from_params(space
);
5639 bset
= isl_basic_set_reset_space(bset
, space
);
5643 /* Compute the parameter domain of the given set.
5645 __isl_give isl_set
*isl_set_params(__isl_take isl_set
*set
)
5647 return isl_map_params(set_to_map(set
));
5650 /* Construct a zero-dimensional set with the given parameter domain.
5652 __isl_give isl_set
*isl_set_from_params(__isl_take isl_set
*set
)
5655 space
= isl_set_get_space(set
);
5656 space
= isl_space_set_from_params(space
);
5657 set
= isl_set_reset_space(set
, space
);
5661 /* Compute the parameter domain of the given map.
5663 __isl_give isl_set
*isl_map_params(__isl_take isl_map
*map
)
5666 isl_size n_in
, n_out
;
5668 n_in
= isl_map_dim(map
, isl_dim_in
);
5669 n_out
= isl_map_dim(map
, isl_dim_out
);
5670 if (n_in
< 0 || n_out
< 0)
5671 return isl_map_free(map
);
5672 map
= isl_map_project_out(map
, isl_dim_in
, 0, n_in
);
5673 map
= isl_map_project_out(map
, isl_dim_out
, 0, n_out
);
5674 space
= isl_map_get_space(map
);
5675 space
= isl_space_params(space
);
5676 map
= isl_map_reset_space(map
, space
);
5680 __isl_give isl_basic_set
*isl_basic_map_domain(__isl_take isl_basic_map
*bmap
)
5685 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
5687 return isl_basic_map_free(bmap
);
5688 space
= isl_space_domain(isl_basic_map_get_space(bmap
));
5690 bmap
= isl_basic_map_project_out(bmap
, isl_dim_out
, 0, n_out
);
5692 return isl_basic_map_reset_space(bmap
, space
);
5695 isl_bool
isl_basic_map_may_be_set(__isl_keep isl_basic_map
*bmap
)
5698 return isl_bool_error
;
5699 return isl_space_may_be_set(bmap
->dim
);
5702 /* Is this basic map actually a set?
5703 * Users should never call this function. Outside of isl,
5704 * the type should indicate whether something is a set or a map.
5706 isl_bool
isl_basic_map_is_set(__isl_keep isl_basic_map
*bmap
)
5709 return isl_bool_error
;
5710 return isl_space_is_set(bmap
->dim
);
5713 struct isl_basic_set
*isl_basic_map_range(struct isl_basic_map
*bmap
)
5717 is_set
= isl_basic_map_is_set(bmap
);
5722 return isl_basic_map_domain(isl_basic_map_reverse(bmap
));
5724 isl_basic_map_free(bmap
);
5728 __isl_give isl_basic_map
*isl_basic_map_domain_map(
5729 __isl_take isl_basic_map
*bmap
)
5733 isl_basic_map
*domain
;
5734 isl_size nparam
, n_in
, n_out
;
5736 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
5737 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
5738 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
5739 if (nparam
< 0 || n_in
< 0 || n_out
< 0)
5740 return isl_basic_map_free(bmap
);
5742 space
= isl_basic_map_get_space(bmap
);
5743 space
= isl_space_from_range(isl_space_domain(space
));
5744 domain
= isl_basic_map_universe(space
);
5746 bmap
= isl_basic_map_from_domain(isl_basic_map_wrap(bmap
));
5747 bmap
= isl_basic_map_apply_range(bmap
, domain
);
5748 bmap
= isl_basic_map_extend_constraints(bmap
, n_in
, 0);
5750 for (i
= 0; i
< n_in
; ++i
)
5751 bmap
= isl_basic_map_equate(bmap
, isl_dim_in
, i
,
5754 bmap
= isl_basic_map_gauss(bmap
, NULL
);
5755 return isl_basic_map_finalize(bmap
);
5758 __isl_give isl_basic_map
*isl_basic_map_range_map(
5759 __isl_take isl_basic_map
*bmap
)
5763 isl_basic_map
*range
;
5764 isl_size nparam
, n_in
, n_out
;
5766 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
5767 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
5768 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
5769 if (nparam
< 0 || n_in
< 0 || n_out
< 0)
5770 return isl_basic_map_free(bmap
);
5772 space
= isl_basic_map_get_space(bmap
);
5773 space
= isl_space_from_range(isl_space_range(space
));
5774 range
= isl_basic_map_universe(space
);
5776 bmap
= isl_basic_map_from_domain(isl_basic_map_wrap(bmap
));
5777 bmap
= isl_basic_map_apply_range(bmap
, range
);
5778 bmap
= isl_basic_map_extend_constraints(bmap
, n_out
, 0);
5780 for (i
= 0; i
< n_out
; ++i
)
5781 bmap
= isl_basic_map_equate(bmap
, isl_dim_in
, n_in
+ i
,
5784 bmap
= isl_basic_map_gauss(bmap
, NULL
);
5785 return isl_basic_map_finalize(bmap
);
5788 int isl_map_may_be_set(__isl_keep isl_map
*map
)
5792 return isl_space_may_be_set(map
->dim
);
5795 /* Is this map actually a set?
5796 * Users should never call this function. Outside of isl,
5797 * the type should indicate whether something is a set or a map.
5799 isl_bool
isl_map_is_set(__isl_keep isl_map
*map
)
5802 return isl_bool_error
;
5803 return isl_space_is_set(map
->dim
);
5806 __isl_give isl_set
*isl_map_range(__isl_take isl_map
*map
)
5810 struct isl_set
*set
;
5812 is_set
= isl_map_is_set(map
);
5816 return set_from_map(map
);
5818 map
= isl_map_cow(map
);
5822 set
= set_from_map(map
);
5823 set
->dim
= isl_space_range(set
->dim
);
5826 for (i
= 0; i
< map
->n
; ++i
) {
5827 set
->p
[i
] = isl_basic_map_range(map
->p
[i
]);
5831 ISL_F_CLR(set
, ISL_MAP_DISJOINT
);
5832 ISL_F_CLR(set
, ISL_SET_NORMALIZED
);
5839 __isl_give isl_map
*isl_map_domain_map(__isl_take isl_map
*map
)
5843 map
= isl_map_cow(map
);
5847 map
->dim
= isl_space_domain_map(map
->dim
);
5850 for (i
= 0; i
< map
->n
; ++i
) {
5851 map
->p
[i
] = isl_basic_map_domain_map(map
->p
[i
]);
5855 ISL_F_CLR(map
, ISL_MAP_DISJOINT
);
5856 map
= isl_map_unmark_normalized(map
);
5863 __isl_give isl_map
*isl_map_range_map(__isl_take isl_map
*map
)
5866 isl_space
*range_dim
;
5868 map
= isl_map_cow(map
);
5872 range_dim
= isl_space_range(isl_map_get_space(map
));
5873 range_dim
= isl_space_from_range(range_dim
);
5874 map
->dim
= isl_space_from_domain(isl_space_wrap(map
->dim
));
5875 map
->dim
= isl_space_join(map
->dim
, range_dim
);
5878 for (i
= 0; i
< map
->n
; ++i
) {
5879 map
->p
[i
] = isl_basic_map_range_map(map
->p
[i
]);
5883 ISL_F_CLR(map
, ISL_MAP_DISJOINT
);
5884 map
= isl_map_unmark_normalized(map
);
5891 /* Given a wrapped map of the form A[B -> C],
5892 * return the map A[B -> C] -> B.
5894 __isl_give isl_map
*isl_set_wrapped_domain_map(__isl_take isl_set
*set
)
5901 if (!isl_set_has_tuple_id(set
))
5902 return isl_map_domain_map(isl_set_unwrap(set
));
5904 id
= isl_set_get_tuple_id(set
);
5905 map
= isl_map_domain_map(isl_set_unwrap(set
));
5906 map
= isl_map_set_tuple_id(map
, isl_dim_in
, id
);
5911 __isl_give isl_basic_map
*isl_basic_map_from_domain(
5912 __isl_take isl_basic_set
*bset
)
5914 return isl_basic_map_reverse(isl_basic_map_from_range(bset
));
5917 __isl_give isl_basic_map
*isl_basic_map_from_range(
5918 __isl_take isl_basic_set
*bset
)
5921 space
= isl_basic_set_get_space(bset
);
5922 space
= isl_space_from_range(space
);
5923 bset
= isl_basic_set_reset_space(bset
, space
);
5924 return bset_to_bmap(bset
);
5927 /* Create a relation with the given set as range.
5928 * The domain of the created relation is a zero-dimensional
5929 * flat anonymous space.
5931 __isl_give isl_map
*isl_map_from_range(__isl_take isl_set
*set
)
5934 space
= isl_set_get_space(set
);
5935 space
= isl_space_from_range(space
);
5936 set
= isl_set_reset_space(set
, space
);
5937 return set_to_map(set
);
5940 /* Create a relation with the given set as domain.
5941 * The range of the created relation is a zero-dimensional
5942 * flat anonymous space.
5944 __isl_give isl_map
*isl_map_from_domain(__isl_take isl_set
*set
)
5946 return isl_map_reverse(isl_map_from_range(set
));
5949 __isl_give isl_basic_map
*isl_basic_map_from_domain_and_range(
5950 __isl_take isl_basic_set
*domain
, __isl_take isl_basic_set
*range
)
5952 return isl_basic_map_apply_range(isl_basic_map_reverse(domain
), range
);
5955 __isl_give isl_map
*isl_map_from_domain_and_range(__isl_take isl_set
*domain
,
5956 __isl_take isl_set
*range
)
5958 return isl_map_apply_range(isl_map_reverse(domain
), range
);
5961 /* Return a newly allocated isl_map with given space and flags and
5962 * room for "n" basic maps.
5963 * Make sure that all cached information is cleared.
5965 __isl_give isl_map
*isl_map_alloc_space(__isl_take isl_space
*space
, int n
,
5968 struct isl_map
*map
;
5973 isl_die(space
->ctx
, isl_error_internal
,
5974 "negative number of basic maps", goto error
);
5975 map
= isl_calloc(space
->ctx
, struct isl_map
,
5976 sizeof(struct isl_map
) +
5977 (n
- 1) * sizeof(struct isl_basic_map
*));
5981 map
->ctx
= space
->ctx
;
5982 isl_ctx_ref(map
->ctx
);
5990 isl_space_free(space
);
5994 __isl_give isl_basic_map
*isl_basic_map_empty(__isl_take isl_space
*space
)
5996 struct isl_basic_map
*bmap
;
5997 bmap
= isl_basic_map_alloc_space(space
, 0, 1, 0);
5998 bmap
= isl_basic_map_set_to_empty(bmap
);
6002 __isl_give isl_basic_set
*isl_basic_set_empty(__isl_take isl_space
*space
)
6004 struct isl_basic_set
*bset
;
6005 bset
= isl_basic_set_alloc_space(space
, 0, 1, 0);
6006 bset
= isl_basic_set_set_to_empty(bset
);
6010 __isl_give isl_basic_map
*isl_basic_map_universe(__isl_take isl_space
*space
)
6012 struct isl_basic_map
*bmap
;
6013 bmap
= isl_basic_map_alloc_space(space
, 0, 0, 0);
6014 bmap
= isl_basic_map_finalize(bmap
);
6018 __isl_give isl_basic_set
*isl_basic_set_universe(__isl_take isl_space
*space
)
6020 struct isl_basic_set
*bset
;
6021 bset
= isl_basic_set_alloc_space(space
, 0, 0, 0);
6022 bset
= isl_basic_set_finalize(bset
);
6026 __isl_give isl_basic_map
*isl_basic_map_nat_universe(
6027 __isl_take isl_space
*space
)
6030 isl_size total
= isl_space_dim(space
, isl_dim_all
);
6031 isl_basic_map
*bmap
;
6034 space
= isl_space_free(space
);
6035 bmap
= isl_basic_map_alloc_space(space
, 0, 0, total
);
6036 for (i
= 0; i
< total
; ++i
) {
6037 int k
= isl_basic_map_alloc_inequality(bmap
);
6040 isl_seq_clr(bmap
->ineq
[k
], 1 + total
);
6041 isl_int_set_si(bmap
->ineq
[k
][1 + i
], 1);
6045 isl_basic_map_free(bmap
);
6049 __isl_give isl_basic_set
*isl_basic_set_nat_universe(
6050 __isl_take isl_space
*space
)
6052 return isl_basic_map_nat_universe(space
);
6055 __isl_give isl_map
*isl_map_nat_universe(__isl_take isl_space
*dim
)
6057 return isl_map_from_basic_map(isl_basic_map_nat_universe(dim
));
6060 __isl_give isl_set
*isl_set_nat_universe(__isl_take isl_space
*dim
)
6062 return isl_map_nat_universe(dim
);
6065 __isl_give isl_map
*isl_map_empty(__isl_take isl_space
*space
)
6067 return isl_map_alloc_space(space
, 0, ISL_MAP_DISJOINT
);
6070 __isl_give isl_set
*isl_set_empty(__isl_take isl_space
*space
)
6072 return isl_set_alloc_space(space
, 0, ISL_MAP_DISJOINT
);
6075 __isl_give isl_map
*isl_map_universe(__isl_take isl_space
*space
)
6077 struct isl_map
*map
;
6080 map
= isl_map_alloc_space(isl_space_copy(space
), 1, ISL_MAP_DISJOINT
);
6081 map
= isl_map_add_basic_map(map
, isl_basic_map_universe(space
));
6085 __isl_give isl_set
*isl_set_universe(__isl_take isl_space
*space
)
6087 struct isl_set
*set
;
6090 set
= isl_set_alloc_space(isl_space_copy(space
), 1, ISL_MAP_DISJOINT
);
6091 set
= isl_set_add_basic_set(set
, isl_basic_set_universe(space
));
6095 struct isl_map
*isl_map_dup(struct isl_map
*map
)
6098 struct isl_map
*dup
;
6102 dup
= isl_map_alloc_space(isl_space_copy(map
->dim
), map
->n
, map
->flags
);
6103 for (i
= 0; i
< map
->n
; ++i
)
6104 dup
= isl_map_add_basic_map(dup
, isl_basic_map_copy(map
->p
[i
]));
6108 __isl_give isl_map
*isl_map_add_basic_map(__isl_take isl_map
*map
,
6109 __isl_take isl_basic_map
*bmap
)
6113 if (isl_basic_map_plain_is_empty(bmap
)) {
6114 isl_basic_map_free(bmap
);
6117 isl_assert(map
->ctx
, isl_space_is_equal(map
->dim
, bmap
->dim
), goto error
);
6118 isl_assert(map
->ctx
, map
->n
< map
->size
, goto error
);
6119 map
->p
[map
->n
] = bmap
;
6121 map
= isl_map_unmark_normalized(map
);
6127 isl_basic_map_free(bmap
);
6131 __isl_null isl_map
*isl_map_free(__isl_take isl_map
*map
)
6142 isl_ctx_deref(map
->ctx
);
6143 for (i
= 0; i
< map
->n
; ++i
)
6144 isl_basic_map_free(map
->p
[i
]);
6145 isl_space_free(map
->dim
);
6151 static __isl_give isl_basic_map
*isl_basic_map_fix_pos_si(
6152 __isl_take isl_basic_map
*bmap
, unsigned pos
, int value
)
6157 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
6159 return isl_basic_map_free(bmap
);
6161 bmap
= isl_basic_map_cow(bmap
);
6162 bmap
= isl_basic_map_extend_constraints(bmap
, 1, 0);
6163 j
= isl_basic_map_alloc_equality(bmap
);
6166 isl_seq_clr(bmap
->eq
[j
] + 1, total
);
6167 isl_int_set_si(bmap
->eq
[j
][pos
], -1);
6168 isl_int_set_si(bmap
->eq
[j
][0], value
);
6169 bmap
= isl_basic_map_simplify(bmap
);
6170 return isl_basic_map_finalize(bmap
);
6172 isl_basic_map_free(bmap
);
6176 static __isl_give isl_basic_map
*isl_basic_map_fix_pos(
6177 __isl_take isl_basic_map
*bmap
, unsigned pos
, isl_int value
)
6182 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
6184 return isl_basic_map_free(bmap
);
6186 bmap
= isl_basic_map_cow(bmap
);
6187 bmap
= isl_basic_map_extend_constraints(bmap
, 1, 0);
6188 j
= isl_basic_map_alloc_equality(bmap
);
6191 isl_seq_clr(bmap
->eq
[j
] + 1, total
);
6192 isl_int_set_si(bmap
->eq
[j
][pos
], -1);
6193 isl_int_set(bmap
->eq
[j
][0], value
);
6194 bmap
= isl_basic_map_simplify(bmap
);
6195 return isl_basic_map_finalize(bmap
);
6197 isl_basic_map_free(bmap
);
6201 __isl_give isl_basic_map
*isl_basic_map_fix_si(__isl_take isl_basic_map
*bmap
,
6202 enum isl_dim_type type
, unsigned pos
, int value
)
6204 if (isl_basic_map_check_range(bmap
, type
, pos
, 1) < 0)
6205 return isl_basic_map_free(bmap
);
6206 return isl_basic_map_fix_pos_si(bmap
,
6207 isl_basic_map_offset(bmap
, type
) + pos
, value
);
6210 __isl_give isl_basic_map
*isl_basic_map_fix(__isl_take isl_basic_map
*bmap
,
6211 enum isl_dim_type type
, unsigned pos
, isl_int value
)
6213 if (isl_basic_map_check_range(bmap
, type
, pos
, 1) < 0)
6214 return isl_basic_map_free(bmap
);
6215 return isl_basic_map_fix_pos(bmap
,
6216 isl_basic_map_offset(bmap
, type
) + pos
, value
);
6219 /* Fix the value of the variable at position "pos" of type "type" of "bmap"
6220 * to be equal to "v".
6222 __isl_give isl_basic_map
*isl_basic_map_fix_val(__isl_take isl_basic_map
*bmap
,
6223 enum isl_dim_type type
, unsigned pos
, __isl_take isl_val
*v
)
6227 if (!isl_val_is_int(v
))
6228 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
6229 "expecting integer value", goto error
);
6230 if (isl_basic_map_check_range(bmap
, type
, pos
, 1) < 0)
6232 pos
+= isl_basic_map_offset(bmap
, type
);
6233 bmap
= isl_basic_map_fix_pos(bmap
, pos
, v
->n
);
6237 isl_basic_map_free(bmap
);
6242 /* Fix the value of the variable at position "pos" of type "type" of "bset"
6243 * to be equal to "v".
6245 __isl_give isl_basic_set
*isl_basic_set_fix_val(__isl_take isl_basic_set
*bset
,
6246 enum isl_dim_type type
, unsigned pos
, __isl_take isl_val
*v
)
6248 return isl_basic_map_fix_val(bset
, type
, pos
, v
);
6251 struct isl_basic_set
*isl_basic_set_fix_si(struct isl_basic_set
*bset
,
6252 enum isl_dim_type type
, unsigned pos
, int value
)
6254 return bset_from_bmap(isl_basic_map_fix_si(bset_to_bmap(bset
),
6258 __isl_give isl_basic_set
*isl_basic_set_fix(__isl_take isl_basic_set
*bset
,
6259 enum isl_dim_type type
, unsigned pos
, isl_int value
)
6261 return bset_from_bmap(isl_basic_map_fix(bset_to_bmap(bset
),
6265 struct isl_basic_map
*isl_basic_map_fix_input_si(struct isl_basic_map
*bmap
,
6266 unsigned input
, int value
)
6268 return isl_basic_map_fix_si(bmap
, isl_dim_in
, input
, value
);
6271 struct isl_basic_set
*isl_basic_set_fix_dim_si(struct isl_basic_set
*bset
,
6272 unsigned dim
, int value
)
6274 return bset_from_bmap(isl_basic_map_fix_si(bset_to_bmap(bset
),
6275 isl_dim_set
, dim
, value
));
6278 /* Remove the basic map at position "i" from "map" if this basic map
6279 * is (obviously) empty.
6281 static __isl_give isl_map
*remove_if_empty(__isl_take isl_map
*map
, int i
)
6288 empty
= isl_basic_map_plain_is_empty(map
->p
[i
]);
6290 return isl_map_free(map
);
6294 isl_basic_map_free(map
->p
[i
]);
6297 map
->p
[i
] = map
->p
[map
->n
];
6298 map
= isl_map_unmark_normalized(map
);
6305 /* Perform "fn" on each basic map of "map", where we may not be holding
6306 * the only reference to "map".
6307 * In particular, "fn" should be a semantics preserving operation
6308 * that we want to apply to all copies of "map". We therefore need
6309 * to be careful not to modify "map" in a way that breaks "map"
6310 * in case anything goes wrong.
6312 __isl_give isl_map
*isl_map_inline_foreach_basic_map(__isl_take isl_map
*map
,
6313 __isl_give isl_basic_map
*(*fn
)(__isl_take isl_basic_map
*bmap
))
6315 struct isl_basic_map
*bmap
;
6321 for (i
= map
->n
- 1; i
>= 0; --i
) {
6322 bmap
= isl_basic_map_copy(map
->p
[i
]);
6326 isl_basic_map_free(map
->p
[i
]);
6328 map
= remove_if_empty(map
, i
);
6339 __isl_give isl_map
*isl_map_fix_si(__isl_take isl_map
*map
,
6340 enum isl_dim_type type
, unsigned pos
, int value
)
6344 map
= isl_map_cow(map
);
6345 if (isl_map_check_range(map
, type
, pos
, 1) < 0)
6346 return isl_map_free(map
);
6347 for (i
= map
->n
- 1; i
>= 0; --i
) {
6348 map
->p
[i
] = isl_basic_map_fix_si(map
->p
[i
], type
, pos
, value
);
6349 map
= remove_if_empty(map
, i
);
6353 map
= isl_map_unmark_normalized(map
);
6357 __isl_give isl_set
*isl_set_fix_si(__isl_take isl_set
*set
,
6358 enum isl_dim_type type
, unsigned pos
, int value
)
6360 return set_from_map(isl_map_fix_si(set_to_map(set
), type
, pos
, value
));
6363 __isl_give isl_map
*isl_map_fix(__isl_take isl_map
*map
,
6364 enum isl_dim_type type
, unsigned pos
, isl_int value
)
6368 map
= isl_map_cow(map
);
6369 if (isl_map_check_range(map
, type
, pos
, 1) < 0)
6370 return isl_map_free(map
);
6371 for (i
= 0; i
< map
->n
; ++i
) {
6372 map
->p
[i
] = isl_basic_map_fix(map
->p
[i
], type
, pos
, value
);
6376 map
= isl_map_unmark_normalized(map
);
6383 __isl_give isl_set
*isl_set_fix(__isl_take isl_set
*set
,
6384 enum isl_dim_type type
, unsigned pos
, isl_int value
)
6386 return set_from_map(isl_map_fix(set_to_map(set
), type
, pos
, value
));
6389 /* Fix the value of the variable at position "pos" of type "type" of "map"
6390 * to be equal to "v".
6392 __isl_give isl_map
*isl_map_fix_val(__isl_take isl_map
*map
,
6393 enum isl_dim_type type
, unsigned pos
, __isl_take isl_val
*v
)
6397 map
= isl_map_cow(map
);
6401 if (!isl_val_is_int(v
))
6402 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
6403 "expecting integer value", goto error
);
6404 if (isl_map_check_range(map
, type
, pos
, 1) < 0)
6406 for (i
= map
->n
- 1; i
>= 0; --i
) {
6407 map
->p
[i
] = isl_basic_map_fix_val(map
->p
[i
], type
, pos
,
6409 map
= remove_if_empty(map
, i
);
6413 map
= isl_map_unmark_normalized(map
);
6422 /* Fix the value of the variable at position "pos" of type "type" of "set"
6423 * to be equal to "v".
6425 __isl_give isl_set
*isl_set_fix_val(__isl_take isl_set
*set
,
6426 enum isl_dim_type type
, unsigned pos
, __isl_take isl_val
*v
)
6428 return isl_map_fix_val(set
, type
, pos
, v
);
6431 struct isl_map
*isl_map_fix_input_si(struct isl_map
*map
,
6432 unsigned input
, int value
)
6434 return isl_map_fix_si(map
, isl_dim_in
, input
, value
);
6437 struct isl_set
*isl_set_fix_dim_si(struct isl_set
*set
, unsigned dim
, int value
)
6439 return set_from_map(isl_map_fix_si(set_to_map(set
),
6440 isl_dim_set
, dim
, value
));
6443 static __isl_give isl_basic_map
*basic_map_bound_si(
6444 __isl_take isl_basic_map
*bmap
,
6445 enum isl_dim_type type
, unsigned pos
, int value
, int upper
)
6450 if (isl_basic_map_check_range(bmap
, type
, pos
, 1) < 0)
6451 return isl_basic_map_free(bmap
);
6452 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
6454 return isl_basic_map_free(bmap
);
6455 pos
+= isl_basic_map_offset(bmap
, type
);
6456 bmap
= isl_basic_map_cow(bmap
);
6457 bmap
= isl_basic_map_extend_constraints(bmap
, 0, 1);
6458 j
= isl_basic_map_alloc_inequality(bmap
);
6461 isl_seq_clr(bmap
->ineq
[j
], 1 + total
);
6463 isl_int_set_si(bmap
->ineq
[j
][pos
], -1);
6464 isl_int_set_si(bmap
->ineq
[j
][0], value
);
6466 isl_int_set_si(bmap
->ineq
[j
][pos
], 1);
6467 isl_int_set_si(bmap
->ineq
[j
][0], -value
);
6469 bmap
= isl_basic_map_simplify(bmap
);
6470 return isl_basic_map_finalize(bmap
);
6472 isl_basic_map_free(bmap
);
6476 __isl_give isl_basic_map
*isl_basic_map_lower_bound_si(
6477 __isl_take isl_basic_map
*bmap
,
6478 enum isl_dim_type type
, unsigned pos
, int value
)
6480 return basic_map_bound_si(bmap
, type
, pos
, value
, 0);
6483 /* Constrain the values of the given dimension to be no greater than "value".
6485 __isl_give isl_basic_map
*isl_basic_map_upper_bound_si(
6486 __isl_take isl_basic_map
*bmap
,
6487 enum isl_dim_type type
, unsigned pos
, int value
)
6489 return basic_map_bound_si(bmap
, type
, pos
, value
, 1);
6492 static __isl_give isl_map
*map_bound_si(__isl_take isl_map
*map
,
6493 enum isl_dim_type type
, unsigned pos
, int value
, int upper
)
6497 map
= isl_map_cow(map
);
6498 if (isl_map_check_range(map
, type
, pos
, 1) < 0)
6499 return isl_map_free(map
);
6500 for (i
= 0; i
< map
->n
; ++i
) {
6501 map
->p
[i
] = basic_map_bound_si(map
->p
[i
],
6502 type
, pos
, value
, upper
);
6506 map
= isl_map_unmark_normalized(map
);
6513 __isl_give isl_map
*isl_map_lower_bound_si(__isl_take isl_map
*map
,
6514 enum isl_dim_type type
, unsigned pos
, int value
)
6516 return map_bound_si(map
, type
, pos
, value
, 0);
6519 __isl_give isl_map
*isl_map_upper_bound_si(__isl_take isl_map
*map
,
6520 enum isl_dim_type type
, unsigned pos
, int value
)
6522 return map_bound_si(map
, type
, pos
, value
, 1);
6525 __isl_give isl_set
*isl_set_lower_bound_si(__isl_take isl_set
*set
,
6526 enum isl_dim_type type
, unsigned pos
, int value
)
6528 return set_from_map(isl_map_lower_bound_si(set_to_map(set
),
6532 __isl_give isl_set
*isl_set_upper_bound_si(__isl_take isl_set
*set
,
6533 enum isl_dim_type type
, unsigned pos
, int value
)
6535 return isl_map_upper_bound_si(set
, type
, pos
, value
);
6538 /* Bound the given variable of "bmap" from below (or above is "upper"
6539 * is set) to "value".
6541 static __isl_give isl_basic_map
*basic_map_bound(
6542 __isl_take isl_basic_map
*bmap
,
6543 enum isl_dim_type type
, unsigned pos
, isl_int value
, int upper
)
6548 if (isl_basic_map_check_range(bmap
, type
, pos
, 1) < 0)
6549 return isl_basic_map_free(bmap
);
6550 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
6552 return isl_basic_map_free(bmap
);
6553 pos
+= isl_basic_map_offset(bmap
, type
);
6554 bmap
= isl_basic_map_cow(bmap
);
6555 bmap
= isl_basic_map_extend_constraints(bmap
, 0, 1);
6556 j
= isl_basic_map_alloc_inequality(bmap
);
6559 isl_seq_clr(bmap
->ineq
[j
], 1 + total
);
6561 isl_int_set_si(bmap
->ineq
[j
][pos
], -1);
6562 isl_int_set(bmap
->ineq
[j
][0], value
);
6564 isl_int_set_si(bmap
->ineq
[j
][pos
], 1);
6565 isl_int_neg(bmap
->ineq
[j
][0], value
);
6567 bmap
= isl_basic_map_simplify(bmap
);
6568 return isl_basic_map_finalize(bmap
);
6570 isl_basic_map_free(bmap
);
6574 /* Bound the given variable of "map" from below (or above is "upper"
6575 * is set) to "value".
6577 static __isl_give isl_map
*map_bound(__isl_take isl_map
*map
,
6578 enum isl_dim_type type
, unsigned pos
, isl_int value
, int upper
)
6582 map
= isl_map_cow(map
);
6583 if (isl_map_check_range(map
, type
, pos
, 1) < 0)
6584 return isl_map_free(map
);
6585 for (i
= map
->n
- 1; i
>= 0; --i
) {
6586 map
->p
[i
] = basic_map_bound(map
->p
[i
], type
, pos
, value
, upper
);
6587 map
= remove_if_empty(map
, i
);
6591 map
= isl_map_unmark_normalized(map
);
6595 __isl_give isl_map
*isl_map_lower_bound(__isl_take isl_map
*map
,
6596 enum isl_dim_type type
, unsigned pos
, isl_int value
)
6598 return map_bound(map
, type
, pos
, value
, 0);
6601 __isl_give isl_map
*isl_map_upper_bound(__isl_take isl_map
*map
,
6602 enum isl_dim_type type
, unsigned pos
, isl_int value
)
6604 return map_bound(map
, type
, pos
, value
, 1);
6607 __isl_give isl_set
*isl_set_lower_bound(__isl_take isl_set
*set
,
6608 enum isl_dim_type type
, unsigned pos
, isl_int value
)
6610 return isl_map_lower_bound(set
, type
, pos
, value
);
6613 __isl_give isl_set
*isl_set_upper_bound(__isl_take isl_set
*set
,
6614 enum isl_dim_type type
, unsigned pos
, isl_int value
)
6616 return isl_map_upper_bound(set
, type
, pos
, value
);
6619 /* Force the values of the variable at position "pos" of type "type" of "set"
6620 * to be no smaller than "value".
6622 __isl_give isl_set
*isl_set_lower_bound_val(__isl_take isl_set
*set
,
6623 enum isl_dim_type type
, unsigned pos
, __isl_take isl_val
*value
)
6627 if (!isl_val_is_int(value
))
6628 isl_die(isl_set_get_ctx(set
), isl_error_invalid
,
6629 "expecting integer value", goto error
);
6630 set
= isl_set_lower_bound(set
, type
, pos
, value
->n
);
6631 isl_val_free(value
);
6634 isl_val_free(value
);
6639 /* Force the values of the variable at position "pos" of type "type" of "set"
6640 * to be no greater than "value".
6642 __isl_give isl_set
*isl_set_upper_bound_val(__isl_take isl_set
*set
,
6643 enum isl_dim_type type
, unsigned pos
, __isl_take isl_val
*value
)
6647 if (!isl_val_is_int(value
))
6648 isl_die(isl_set_get_ctx(set
), isl_error_invalid
,
6649 "expecting integer value", goto error
);
6650 set
= isl_set_upper_bound(set
, type
, pos
, value
->n
);
6651 isl_val_free(value
);
6654 isl_val_free(value
);
6659 /* Bound the given variable of "bset" from below (or above is "upper"
6660 * is set) to "value".
6662 static __isl_give isl_basic_set
*isl_basic_set_bound(
6663 __isl_take isl_basic_set
*bset
, enum isl_dim_type type
, unsigned pos
,
6664 isl_int value
, int upper
)
6666 return bset_from_bmap(basic_map_bound(bset_to_bmap(bset
),
6667 type
, pos
, value
, upper
));
6670 /* Bound the given variable of "bset" from below (or above is "upper"
6671 * is set) to "value".
6673 static __isl_give isl_basic_set
*isl_basic_set_bound_val(
6674 __isl_take isl_basic_set
*bset
, enum isl_dim_type type
, unsigned pos
,
6675 __isl_take isl_val
*value
, int upper
)
6679 if (!isl_val_is_int(value
))
6680 isl_die(isl_basic_set_get_ctx(bset
), isl_error_invalid
,
6681 "expecting integer value", goto error
);
6682 bset
= isl_basic_set_bound(bset
, type
, pos
, value
->n
, upper
);
6683 isl_val_free(value
);
6686 isl_val_free(value
);
6687 isl_basic_set_free(bset
);
6691 /* Bound the given variable of "bset" from below to "value".
6693 __isl_give isl_basic_set
*isl_basic_set_lower_bound_val(
6694 __isl_take isl_basic_set
*bset
, enum isl_dim_type type
, unsigned pos
,
6695 __isl_take isl_val
*value
)
6697 return isl_basic_set_bound_val(bset
, type
, pos
, value
, 0);
6700 /* Bound the given variable of "bset" from above to "value".
6702 __isl_give isl_basic_set
*isl_basic_set_upper_bound_val(
6703 __isl_take isl_basic_set
*bset
, enum isl_dim_type type
, unsigned pos
,
6704 __isl_take isl_val
*value
)
6706 return isl_basic_set_bound_val(bset
, type
, pos
, value
, 1);
6709 __isl_give isl_map
*isl_map_reverse(__isl_take isl_map
*map
)
6713 map
= isl_map_cow(map
);
6717 map
->dim
= isl_space_reverse(map
->dim
);
6720 for (i
= 0; i
< map
->n
; ++i
) {
6721 map
->p
[i
] = isl_basic_map_reverse(map
->p
[i
]);
6725 map
= isl_map_unmark_normalized(map
);
6733 #define TYPE isl_pw_multi_aff
6735 #define SUFFIX _pw_multi_aff
6737 #define EMPTY isl_pw_multi_aff_empty
6739 #define ADD isl_pw_multi_aff_union_add
6740 #include "isl_map_lexopt_templ.c"
6742 /* Given a map "map", compute the lexicographically minimal
6743 * (or maximal) image element for each domain element in dom,
6744 * in the form of an isl_pw_multi_aff.
6745 * If "empty" is not NULL, then set *empty to those elements in dom that
6746 * do not have an image element.
6747 * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
6748 * should be computed over the domain of "map". "empty" is also NULL
6751 * We first compute the lexicographically minimal or maximal element
6752 * in the first basic map. This results in a partial solution "res"
6753 * and a subset "todo" of dom that still need to be handled.
6754 * We then consider each of the remaining maps in "map" and successively
6755 * update both "res" and "todo".
6756 * If "empty" is NULL, then the todo sets are not needed and therefore
6757 * also not computed.
6759 static __isl_give isl_pw_multi_aff
*isl_map_partial_lexopt_aligned_pw_multi_aff(
6760 __isl_take isl_map
*map
, __isl_take isl_set
*dom
,
6761 __isl_give isl_set
**empty
, unsigned flags
)
6765 isl_pw_multi_aff
*res
;
6768 full
= ISL_FL_ISSET(flags
, ISL_OPT_FULL
);
6769 if (!map
|| (!full
&& !dom
))
6772 if (isl_map_plain_is_empty(map
)) {
6777 return isl_pw_multi_aff_from_map(map
);
6780 res
= basic_map_partial_lexopt_pw_multi_aff(
6781 isl_basic_map_copy(map
->p
[0]),
6782 isl_set_copy(dom
), empty
, flags
);
6786 for (i
= 1; i
< map
->n
; ++i
) {
6787 isl_pw_multi_aff
*res_i
;
6789 res_i
= basic_map_partial_lexopt_pw_multi_aff(
6790 isl_basic_map_copy(map
->p
[i
]),
6791 isl_set_copy(dom
), empty
, flags
);
6793 if (ISL_FL_ISSET(flags
, ISL_OPT_MAX
))
6794 res
= isl_pw_multi_aff_union_lexmax(res
, res_i
);
6796 res
= isl_pw_multi_aff_union_lexmin(res
, res_i
);
6799 todo
= isl_set_intersect(todo
, *empty
);
6818 #define TYPE isl_map
6822 #define EMPTY isl_map_empty
6824 #define ADD isl_map_union_disjoint
6825 #include "isl_map_lexopt_templ.c"
6827 /* Given a map "map", compute the lexicographically minimal
6828 * (or maximal) image element for each domain element in "dom",
6829 * in the form of an isl_map.
6830 * If "empty" is not NULL, then set *empty to those elements in "dom" that
6831 * do not have an image element.
6832 * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
6833 * should be computed over the domain of "map". "empty" is also NULL
6836 * If the input consists of more than one disjunct, then first
6837 * compute the desired result in the form of an isl_pw_multi_aff and
6838 * then convert that into an isl_map.
6840 * This function used to have an explicit implementation in terms
6841 * of isl_maps, but it would continually intersect the domains of
6842 * partial results with the complement of the domain of the next
6843 * partial solution, potentially leading to an explosion in the number
6844 * of disjuncts if there are several disjuncts in the input.
6845 * An even earlier implementation of this function would look for
6846 * better results in the domain of the partial result and for extra
6847 * results in the complement of this domain, which would lead to
6848 * even more splintering.
6850 static __isl_give isl_map
*isl_map_partial_lexopt_aligned(
6851 __isl_take isl_map
*map
, __isl_take isl_set
*dom
,
6852 __isl_give isl_set
**empty
, unsigned flags
)
6855 struct isl_map
*res
;
6856 isl_pw_multi_aff
*pma
;
6858 full
= ISL_FL_ISSET(flags
, ISL_OPT_FULL
);
6859 if (!map
|| (!full
&& !dom
))
6862 if (isl_map_plain_is_empty(map
)) {
6871 res
= basic_map_partial_lexopt(isl_basic_map_copy(map
->p
[0]),
6877 pma
= isl_map_partial_lexopt_aligned_pw_multi_aff(map
, dom
, empty
,
6879 return isl_map_from_pw_multi_aff(pma
);
6888 __isl_give isl_map
*isl_map_partial_lexmax(
6889 __isl_take isl_map
*map
, __isl_take isl_set
*dom
,
6890 __isl_give isl_set
**empty
)
6892 return isl_map_partial_lexopt(map
, dom
, empty
, ISL_OPT_MAX
);
6895 __isl_give isl_map
*isl_map_partial_lexmin(
6896 __isl_take isl_map
*map
, __isl_take isl_set
*dom
,
6897 __isl_give isl_set
**empty
)
6899 return isl_map_partial_lexopt(map
, dom
, empty
, 0);
6902 __isl_give isl_set
*isl_set_partial_lexmin(
6903 __isl_take isl_set
*set
, __isl_take isl_set
*dom
,
6904 __isl_give isl_set
**empty
)
6906 return set_from_map(isl_map_partial_lexmin(set_to_map(set
),
6910 __isl_give isl_set
*isl_set_partial_lexmax(
6911 __isl_take isl_set
*set
, __isl_take isl_set
*dom
,
6912 __isl_give isl_set
**empty
)
6914 return set_from_map(isl_map_partial_lexmax(set_to_map(set
),
6918 /* Compute the lexicographic minimum (or maximum if "flags" includes
6919 * ISL_OPT_MAX) of "bset" over its parametric domain.
6921 __isl_give isl_set
*isl_basic_set_lexopt(__isl_take isl_basic_set
*bset
,
6924 return isl_basic_map_lexopt(bset
, flags
);
6927 __isl_give isl_map
*isl_basic_map_lexmax(__isl_take isl_basic_map
*bmap
)
6929 return isl_basic_map_lexopt(bmap
, ISL_OPT_MAX
);
6932 __isl_give isl_set
*isl_basic_set_lexmin(__isl_take isl_basic_set
*bset
)
6934 return set_from_map(isl_basic_map_lexmin(bset_to_bmap(bset
)));
6937 __isl_give isl_set
*isl_basic_set_lexmax(__isl_take isl_basic_set
*bset
)
6939 return set_from_map(isl_basic_map_lexmax(bset_to_bmap(bset
)));
6942 /* Compute the lexicographic minimum of "bset" over its parametric domain
6943 * for the purpose of quantifier elimination.
6944 * That is, find an explicit representation for all the existentially
6945 * quantified variables in "bset" by computing their lexicographic
6948 static __isl_give isl_set
*isl_basic_set_lexmin_compute_divs(
6949 __isl_take isl_basic_set
*bset
)
6951 return isl_basic_set_lexopt(bset
, ISL_OPT_QE
);
6954 /* Given a basic map with one output dimension, compute the minimum or
6955 * maximum of that dimension as an isl_pw_aff.
6957 * Compute the optimum as a lexicographic optimum over the single
6958 * output dimension and extract the single isl_pw_aff from the result.
6960 static __isl_give isl_pw_aff
*basic_map_dim_opt(__isl_keep isl_basic_map
*bmap
,
6963 isl_pw_multi_aff
*pma
;
6966 bmap
= isl_basic_map_copy(bmap
);
6967 pma
= isl_basic_map_lexopt_pw_multi_aff(bmap
, max
? ISL_OPT_MAX
: 0);
6968 pwaff
= isl_pw_multi_aff_get_pw_aff(pma
, 0);
6969 isl_pw_multi_aff_free(pma
);
6974 /* Compute the minimum or maximum of the given output dimension
6975 * as a function of the parameters and the input dimensions,
6976 * but independently of the other output dimensions.
6978 * We first project out the other output dimension and then compute
6979 * the "lexicographic" maximum in each basic map, combining the results
6980 * using isl_pw_aff_union_max.
6982 static __isl_give isl_pw_aff
*map_dim_opt(__isl_take isl_map
*map
, int pos
,
6989 n_out
= isl_map_dim(map
, isl_dim_out
);
6991 map
= isl_map_free(map
);
6992 map
= isl_map_project_out(map
, isl_dim_out
, pos
+ 1, n_out
- (pos
+ 1));
6993 map
= isl_map_project_out(map
, isl_dim_out
, 0, pos
);
6998 isl_space
*space
= isl_map_get_space(map
);
7000 return isl_pw_aff_empty(space
);
7003 pwaff
= basic_map_dim_opt(map
->p
[0], max
);
7004 for (i
= 1; i
< map
->n
; ++i
) {
7005 isl_pw_aff
*pwaff_i
;
7007 pwaff_i
= basic_map_dim_opt(map
->p
[i
], max
);
7008 pwaff
= isl_pw_aff_union_opt(pwaff
, pwaff_i
, max
);
7016 /* Compute the minimum of the given output dimension as a function of the
7017 * parameters and input dimensions, but independently of
7018 * the other output dimensions.
7020 __isl_give isl_pw_aff
*isl_map_dim_min(__isl_take isl_map
*map
, int pos
)
7022 return map_dim_opt(map
, pos
, 0);
7025 /* Compute the maximum of the given output dimension as a function of the
7026 * parameters and input dimensions, but independently of
7027 * the other output dimensions.
7029 __isl_give isl_pw_aff
*isl_map_dim_max(__isl_take isl_map
*map
, int pos
)
7031 return map_dim_opt(map
, pos
, 1);
7034 /* Compute the minimum or maximum of the given set dimension
7035 * as a function of the parameters,
7036 * but independently of the other set dimensions.
7038 static __isl_give isl_pw_aff
*set_dim_opt(__isl_take isl_set
*set
, int pos
,
7041 return map_dim_opt(set
, pos
, max
);
7044 /* Compute the maximum of the given set dimension as a function of the
7045 * parameters, but independently of the other set dimensions.
7047 __isl_give isl_pw_aff
*isl_set_dim_max(__isl_take isl_set
*set
, int pos
)
7049 return set_dim_opt(set
, pos
, 1);
7052 /* Compute the minimum of the given set dimension as a function of the
7053 * parameters, but independently of the other set dimensions.
7055 __isl_give isl_pw_aff
*isl_set_dim_min(__isl_take isl_set
*set
, int pos
)
7057 return set_dim_opt(set
, pos
, 0);
7060 /* Apply a preimage specified by "mat" on the parameters of "bset".
7061 * bset is assumed to have only parameters and divs.
7063 static __isl_give isl_basic_set
*basic_set_parameter_preimage(
7064 __isl_take isl_basic_set
*bset
, __isl_take isl_mat
*mat
)
7068 nparam
= isl_basic_set_dim(bset
, isl_dim_param
);
7069 if (nparam
< 0 || !mat
)
7072 bset
->dim
= isl_space_cow(bset
->dim
);
7076 isl_assert(bset
->ctx
, mat
->n_row
== 1 + nparam
, goto error
);
7078 bset
->dim
->nparam
= 0;
7079 bset
->dim
->n_out
= nparam
;
7080 bset
= isl_basic_set_preimage(bset
, mat
);
7082 bset
->dim
->nparam
= bset
->dim
->n_out
;
7083 bset
->dim
->n_out
= 0;
7088 isl_basic_set_free(bset
);
7092 /* Apply a preimage specified by "mat" on the parameters of "set".
7093 * set is assumed to have only parameters and divs.
7095 static __isl_give isl_set
*set_parameter_preimage(__isl_take isl_set
*set
,
7096 __isl_take isl_mat
*mat
)
7101 nparam
= isl_set_dim(set
, isl_dim_param
);
7102 if (nparam
< 0 || !mat
)
7105 if (mat
->n_row
!= 1 + nparam
)
7106 isl_die(isl_set_get_ctx(set
), isl_error_internal
,
7107 "unexpected number of rows", goto error
);
7109 space
= isl_set_get_space(set
);
7110 space
= isl_space_move_dims(space
, isl_dim_set
, 0,
7111 isl_dim_param
, 0, nparam
);
7112 set
= isl_set_reset_space(set
, space
);
7113 set
= isl_set_preimage(set
, mat
);
7114 nparam
= isl_set_dim(set
, isl_dim_out
);
7116 set
= isl_set_free(set
);
7117 space
= isl_set_get_space(set
);
7118 space
= isl_space_move_dims(space
, isl_dim_param
, 0,
7119 isl_dim_out
, 0, nparam
);
7120 set
= isl_set_reset_space(set
, space
);
7128 /* Intersect the basic set "bset" with the affine space specified by the
7129 * equalities in "eq".
7131 static __isl_give isl_basic_set
*basic_set_append_equalities(
7132 __isl_take isl_basic_set
*bset
, __isl_take isl_mat
*eq
)
7140 bset
= isl_basic_set_extend_space(bset
, isl_space_copy(bset
->dim
), 0,
7145 len
= isl_basic_set_offset(bset
, isl_dim_div
) + bset
->extra
;
7146 for (i
= 0; i
< eq
->n_row
; ++i
) {
7147 k
= isl_basic_set_alloc_equality(bset
);
7150 isl_seq_cpy(bset
->eq
[k
], eq
->row
[i
], eq
->n_col
);
7151 isl_seq_clr(bset
->eq
[k
] + eq
->n_col
, len
- eq
->n_col
);
7155 bset
= isl_basic_set_gauss(bset
, NULL
);
7156 bset
= isl_basic_set_finalize(bset
);
7161 isl_basic_set_free(bset
);
7165 /* Intersect the set "set" with the affine space specified by the
7166 * equalities in "eq".
7168 static struct isl_set
*set_append_equalities(struct isl_set
*set
,
7176 for (i
= 0; i
< set
->n
; ++i
) {
7177 set
->p
[i
] = basic_set_append_equalities(set
->p
[i
],
7190 /* Given a basic set "bset" that only involves parameters and existentially
7191 * quantified variables, return the index of the first equality
7192 * that only involves parameters. If there is no such equality then
7193 * return bset->n_eq.
7195 * This function assumes that isl_basic_set_gauss has been called on "bset".
7197 static int first_parameter_equality(__isl_keep isl_basic_set
*bset
)
7200 isl_size nparam
, n_div
;
7202 nparam
= isl_basic_set_dim(bset
, isl_dim_param
);
7203 n_div
= isl_basic_set_dim(bset
, isl_dim_div
);
7204 if (nparam
< 0 || n_div
< 0)
7207 for (i
= 0, j
= n_div
- 1; i
< bset
->n_eq
&& j
>= 0; --j
) {
7208 if (!isl_int_is_zero(bset
->eq
[i
][1 + nparam
+ j
]))
7215 /* Compute an explicit representation for the existentially quantified
7216 * variables in "bset" by computing the "minimal value" of the set
7217 * variables. Since there are no set variables, the computation of
7218 * the minimal value essentially computes an explicit representation
7219 * of the non-empty part(s) of "bset".
7221 * The input only involves parameters and existentially quantified variables.
7222 * All equalities among parameters have been removed.
7224 * Since the existentially quantified variables in the result are in general
7225 * going to be different from those in the input, we first replace
7226 * them by the minimal number of variables based on their equalities.
7227 * This should simplify the parametric integer programming.
7229 static __isl_give isl_set
*base_compute_divs(__isl_take isl_basic_set
*bset
)
7231 isl_morph
*morph1
, *morph2
;
7237 if (bset
->n_eq
== 0)
7238 return isl_basic_set_lexmin_compute_divs(bset
);
7240 morph1
= isl_basic_set_parameter_compression(bset
);
7241 bset
= isl_morph_basic_set(isl_morph_copy(morph1
), bset
);
7242 bset
= isl_basic_set_lift(bset
);
7243 morph2
= isl_basic_set_variable_compression(bset
, isl_dim_set
);
7244 bset
= isl_morph_basic_set(morph2
, bset
);
7245 n
= isl_basic_set_dim(bset
, isl_dim_set
);
7247 bset
= isl_basic_set_free(bset
);
7248 bset
= isl_basic_set_project_out(bset
, isl_dim_set
, 0, n
);
7250 set
= isl_basic_set_lexmin_compute_divs(bset
);
7252 set
= isl_morph_set(isl_morph_inverse(morph1
), set
);
7257 /* Project the given basic set onto its parameter domain, possibly introducing
7258 * new, explicit, existential variables in the constraints.
7259 * The input has parameters and (possibly implicit) existential variables.
7260 * The output has the same parameters, but only
7261 * explicit existentially quantified variables.
7263 * The actual projection is performed by pip, but pip doesn't seem
7264 * to like equalities very much, so we first remove the equalities
7265 * among the parameters by performing a variable compression on
7266 * the parameters. Afterward, an inverse transformation is performed
7267 * and the equalities among the parameters are inserted back in.
7269 * The variable compression on the parameters may uncover additional
7270 * equalities that were only implicit before. We therefore check
7271 * if there are any new parameter equalities in the result and
7272 * if so recurse. The removal of parameter equalities is required
7273 * for the parameter compression performed by base_compute_divs.
7275 static struct isl_set
*parameter_compute_divs(struct isl_basic_set
*bset
)
7279 struct isl_mat
*T
, *T2
;
7280 struct isl_set
*set
;
7283 bset
= isl_basic_set_cow(bset
);
7287 if (bset
->n_eq
== 0)
7288 return base_compute_divs(bset
);
7290 bset
= isl_basic_set_gauss(bset
, NULL
);
7293 if (isl_basic_set_plain_is_empty(bset
))
7294 return isl_set_from_basic_set(bset
);
7296 i
= first_parameter_equality(bset
);
7297 if (i
== bset
->n_eq
)
7298 return base_compute_divs(bset
);
7300 nparam
= isl_basic_set_dim(bset
, isl_dim_param
);
7302 return isl_set_from_basic_set(isl_basic_set_free(bset
));
7303 eq
= isl_mat_sub_alloc6(bset
->ctx
, bset
->eq
, i
, bset
->n_eq
- i
,
7305 eq
= isl_mat_cow(eq
);
7306 T
= isl_mat_variable_compression(isl_mat_copy(eq
), &T2
);
7307 if (T
&& T
->n_col
== 0) {
7311 bset
= isl_basic_set_set_to_empty(bset
);
7312 return isl_set_from_basic_set(bset
);
7314 bset
= basic_set_parameter_preimage(bset
, T
);
7316 i
= first_parameter_equality(bset
);
7319 else if (i
== bset
->n_eq
)
7320 set
= base_compute_divs(bset
);
7322 set
= parameter_compute_divs(bset
);
7323 set
= set_parameter_preimage(set
, T2
);
7324 set
= set_append_equalities(set
, eq
);
7328 /* Insert the divs from "ls" before those of "bmap".
7330 * The number of columns is not changed, which means that the last
7331 * dimensions of "bmap" are being reintepreted as the divs from "ls".
7332 * The caller is responsible for removing the same number of dimensions
7333 * from the space of "bmap".
7335 static __isl_give isl_basic_map
*insert_divs_from_local_space(
7336 __isl_take isl_basic_map
*bmap
, __isl_keep isl_local_space
*ls
)
7342 n_div
= isl_local_space_dim(ls
, isl_dim_div
);
7344 return isl_basic_map_free(bmap
);
7348 old_n_div
= bmap
->n_div
;
7349 bmap
= insert_div_rows(bmap
, n_div
);
7353 for (i
= 0; i
< n_div
; ++i
) {
7354 isl_seq_cpy(bmap
->div
[i
], ls
->div
->row
[i
], ls
->div
->n_col
);
7355 isl_seq_clr(bmap
->div
[i
] + ls
->div
->n_col
, old_n_div
);
7361 /* Replace the space of "bmap" by the space and divs of "ls".
7363 * If "ls" has any divs, then we simplify the result since we may
7364 * have discovered some additional equalities that could simplify
7365 * the div expressions.
7367 static __isl_give isl_basic_map
*basic_replace_space_by_local_space(
7368 __isl_take isl_basic_map
*bmap
, __isl_take isl_local_space
*ls
)
7372 bmap
= isl_basic_map_cow(bmap
);
7373 n_div
= isl_local_space_dim(ls
, isl_dim_div
);
7374 if (!bmap
|| n_div
< 0)
7377 bmap
= insert_divs_from_local_space(bmap
, ls
);
7381 isl_space_free(bmap
->dim
);
7382 bmap
->dim
= isl_local_space_get_space(ls
);
7386 isl_local_space_free(ls
);
7388 bmap
= isl_basic_map_simplify(bmap
);
7389 bmap
= isl_basic_map_finalize(bmap
);
7392 isl_basic_map_free(bmap
);
7393 isl_local_space_free(ls
);
7397 /* Replace the space of "map" by the space and divs of "ls".
7399 static __isl_give isl_map
*replace_space_by_local_space(__isl_take isl_map
*map
,
7400 __isl_take isl_local_space
*ls
)
7404 map
= isl_map_cow(map
);
7408 for (i
= 0; i
< map
->n
; ++i
) {
7409 map
->p
[i
] = basic_replace_space_by_local_space(map
->p
[i
],
7410 isl_local_space_copy(ls
));
7414 isl_space_free(map
->dim
);
7415 map
->dim
= isl_local_space_get_space(ls
);
7419 isl_local_space_free(ls
);
7422 isl_local_space_free(ls
);
7427 /* Compute an explicit representation for the existentially
7428 * quantified variables for which do not know any explicit representation yet.
7430 * We first sort the existentially quantified variables so that the
7431 * existentially quantified variables for which we already have an explicit
7432 * representation are placed before those for which we do not.
7433 * The input dimensions, the output dimensions and the existentially
7434 * quantified variables for which we already have an explicit
7435 * representation are then turned into parameters.
7436 * compute_divs returns a map with the same parameters and
7437 * no input or output dimensions and the dimension specification
7438 * is reset to that of the input, including the existentially quantified
7439 * variables for which we already had an explicit representation.
7441 static __isl_give isl_map
*compute_divs(__isl_take isl_basic_map
*bmap
)
7443 struct isl_basic_set
*bset
;
7444 struct isl_set
*set
;
7445 struct isl_map
*map
;
7447 isl_local_space
*ls
;
7454 bmap
= isl_basic_map_sort_divs(bmap
);
7455 bmap
= isl_basic_map_cow(bmap
);
7459 n_known
= isl_basic_map_first_unknown_div(bmap
);
7460 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
7461 n_in
= isl_basic_map_dim(bmap
, isl_dim_in
);
7462 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
7463 if (n_known
< 0 || nparam
< 0 || n_in
< 0 || n_out
< 0)
7464 return isl_map_from_basic_map(isl_basic_map_free(bmap
));
7466 space
= isl_space_set_alloc(bmap
->ctx
,
7467 nparam
+ n_in
+ n_out
+ n_known
, 0);
7471 ls
= isl_basic_map_get_local_space(bmap
);
7472 ls
= isl_local_space_drop_dims(ls
, isl_dim_div
,
7473 n_known
, bmap
->n_div
- n_known
);
7475 for (i
= n_known
; i
< bmap
->n_div
; ++i
)
7476 swap_div(bmap
, i
- n_known
, i
);
7477 bmap
->n_div
-= n_known
;
7478 bmap
->extra
-= n_known
;
7480 bmap
= isl_basic_map_reset_space(bmap
, space
);
7481 bset
= bset_from_bmap(bmap
);
7483 set
= parameter_compute_divs(bset
);
7484 map
= set_to_map(set
);
7485 map
= replace_space_by_local_space(map
, ls
);
7489 isl_basic_map_free(bmap
);
7493 /* Remove the explicit representation of local variable "div",
7496 __isl_give isl_basic_map
*isl_basic_map_mark_div_unknown(
7497 __isl_take isl_basic_map
*bmap
, int div
)
7501 unknown
= isl_basic_map_div_is_marked_unknown(bmap
, div
);
7503 return isl_basic_map_free(bmap
);
7507 bmap
= isl_basic_map_cow(bmap
);
7510 isl_int_set_si(bmap
->div
[div
][0], 0);
7514 /* Is local variable "div" of "bmap" marked as not having an explicit
7516 * Note that even if "div" is not marked in this way and therefore
7517 * has an explicit representation, this representation may still
7518 * depend (indirectly) on other local variables that do not
7519 * have an explicit representation.
7521 isl_bool
isl_basic_map_div_is_marked_unknown(__isl_keep isl_basic_map
*bmap
,
7524 if (isl_basic_map_check_range(bmap
, isl_dim_div
, div
, 1) < 0)
7525 return isl_bool_error
;
7526 return isl_int_is_zero(bmap
->div
[div
][0]);
7529 /* Return the position of the first local variable that does not
7530 * have an explicit representation.
7531 * Return the total number of local variables if they all have
7532 * an explicit representation.
7533 * Return -1 on error.
7535 int isl_basic_map_first_unknown_div(__isl_keep isl_basic_map
*bmap
)
7542 for (i
= 0; i
< bmap
->n_div
; ++i
) {
7543 if (!isl_basic_map_div_is_known(bmap
, i
))
7549 /* Return the position of the first local variable that does not
7550 * have an explicit representation.
7551 * Return the total number of local variables if they all have
7552 * an explicit representation.
7553 * Return -1 on error.
7555 int isl_basic_set_first_unknown_div(__isl_keep isl_basic_set
*bset
)
7557 return isl_basic_map_first_unknown_div(bset
);
7560 /* Does "bmap" have an explicit representation for all local variables?
7562 isl_bool
isl_basic_map_divs_known(__isl_keep isl_basic_map
*bmap
)
7567 n
= isl_basic_map_dim(bmap
, isl_dim_div
);
7568 first
= isl_basic_map_first_unknown_div(bmap
);
7569 if (n
< 0 || first
< 0)
7570 return isl_bool_error
;
7574 /* Do all basic maps in "map" have an explicit representation
7575 * for all local variables?
7577 isl_bool
isl_map_divs_known(__isl_keep isl_map
*map
)
7582 return isl_bool_error
;
7584 for (i
= 0; i
< map
->n
; ++i
) {
7585 int known
= isl_basic_map_divs_known(map
->p
[i
]);
7590 return isl_bool_true
;
7593 /* If bmap contains any unknown divs, then compute explicit
7594 * expressions for them. However, this computation may be
7595 * quite expensive, so first try to remove divs that aren't
7598 __isl_give isl_map
*isl_basic_map_compute_divs(__isl_take isl_basic_map
*bmap
)
7601 struct isl_map
*map
;
7603 known
= isl_basic_map_divs_known(bmap
);
7607 return isl_map_from_basic_map(bmap
);
7609 bmap
= isl_basic_map_drop_redundant_divs(bmap
);
7611 known
= isl_basic_map_divs_known(bmap
);
7615 return isl_map_from_basic_map(bmap
);
7617 map
= compute_divs(bmap
);
7620 isl_basic_map_free(bmap
);
7624 __isl_give isl_map
*isl_map_compute_divs(__isl_take isl_map
*map
)
7628 struct isl_map
*res
;
7635 known
= isl_map_divs_known(map
);
7643 res
= isl_basic_map_compute_divs(isl_basic_map_copy(map
->p
[0]));
7644 for (i
= 1 ; i
< map
->n
; ++i
) {
7646 r2
= isl_basic_map_compute_divs(isl_basic_map_copy(map
->p
[i
]));
7647 if (ISL_F_ISSET(map
, ISL_MAP_DISJOINT
))
7648 res
= isl_map_union_disjoint(res
, r2
);
7650 res
= isl_map_union(res
, r2
);
7657 __isl_give isl_set
*isl_basic_set_compute_divs(__isl_take isl_basic_set
*bset
)
7659 return set_from_map(isl_basic_map_compute_divs(bset_to_bmap(bset
)));
7662 struct isl_set
*isl_set_compute_divs(struct isl_set
*set
)
7664 return set_from_map(isl_map_compute_divs(set_to_map(set
)));
7667 __isl_give isl_set
*isl_map_domain(__isl_take isl_map
*map
)
7670 struct isl_set
*set
;
7675 map
= isl_map_cow(map
);
7679 set
= set_from_map(map
);
7680 set
->dim
= isl_space_domain(set
->dim
);
7683 for (i
= 0; i
< map
->n
; ++i
) {
7684 set
->p
[i
] = isl_basic_map_domain(map
->p
[i
]);
7688 ISL_F_CLR(set
, ISL_MAP_DISJOINT
);
7689 ISL_F_CLR(set
, ISL_SET_NORMALIZED
);
7696 /* Return the union of "map1" and "map2", where we assume for now that
7697 * "map1" and "map2" are disjoint. Note that the basic maps inside
7698 * "map1" or "map2" may not be disjoint from each other.
7699 * Also note that this function is also called from isl_map_union,
7700 * which takes care of handling the situation where "map1" and "map2"
7701 * may not be disjoint.
7703 * If one of the inputs is empty, we can simply return the other input.
7704 * Similarly, if one of the inputs is universal, then it is equal to the union.
7706 static __isl_give isl_map
*map_union_disjoint(__isl_take isl_map
*map1
,
7707 __isl_take isl_map
*map2
)
7711 struct isl_map
*map
= NULL
;
7717 if (!isl_space_is_equal(map1
->dim
, map2
->dim
))
7718 isl_die(isl_map_get_ctx(map1
), isl_error_invalid
,
7719 "spaces don't match", goto error
);
7730 is_universe
= isl_map_plain_is_universe(map1
);
7731 if (is_universe
< 0)
7738 is_universe
= isl_map_plain_is_universe(map2
);
7739 if (is_universe
< 0)
7746 if (ISL_F_ISSET(map1
, ISL_MAP_DISJOINT
) &&
7747 ISL_F_ISSET(map2
, ISL_MAP_DISJOINT
))
7748 ISL_FL_SET(flags
, ISL_MAP_DISJOINT
);
7750 map
= isl_map_alloc_space(isl_space_copy(map1
->dim
),
7751 map1
->n
+ map2
->n
, flags
);
7754 for (i
= 0; i
< map1
->n
; ++i
) {
7755 map
= isl_map_add_basic_map(map
,
7756 isl_basic_map_copy(map1
->p
[i
]));
7760 for (i
= 0; i
< map2
->n
; ++i
) {
7761 map
= isl_map_add_basic_map(map
,
7762 isl_basic_map_copy(map2
->p
[i
]));
7776 /* Return the union of "map1" and "map2", where "map1" and "map2" are
7777 * guaranteed to be disjoint by the caller.
7779 * Note that this functions is called from within isl_map_make_disjoint,
7780 * so we have to be careful not to touch the constraints of the inputs
7783 __isl_give isl_map
*isl_map_union_disjoint(__isl_take isl_map
*map1
,
7784 __isl_take isl_map
*map2
)
7786 return isl_map_align_params_map_map_and(map1
, map2
, &map_union_disjoint
);
7789 /* Return the union of "map1" and "map2", where "map1" and "map2" may
7790 * not be disjoint. The parameters are assumed to have been aligned.
7792 * We currently simply call map_union_disjoint, the internal operation
7793 * of which does not really depend on the inputs being disjoint.
7794 * If the result contains more than one basic map, then we clear
7795 * the disjoint flag since the result may contain basic maps from
7796 * both inputs and these are not guaranteed to be disjoint.
7798 * As a special case, if "map1" and "map2" are obviously equal,
7799 * then we simply return "map1".
7801 static __isl_give isl_map
*map_union_aligned(__isl_take isl_map
*map1
,
7802 __isl_take isl_map
*map2
)
7809 equal
= isl_map_plain_is_equal(map1
, map2
);
7817 map1
= map_union_disjoint(map1
, map2
);
7821 ISL_F_CLR(map1
, ISL_MAP_DISJOINT
);
7829 /* Return the union of "map1" and "map2", where "map1" and "map2" may
7832 __isl_give isl_map
*isl_map_union(__isl_take isl_map
*map1
,
7833 __isl_take isl_map
*map2
)
7835 return isl_map_align_params_map_map_and(map1
, map2
, &map_union_aligned
);
7838 __isl_give isl_set
*isl_set_union_disjoint(
7839 __isl_take isl_set
*set1
, __isl_take isl_set
*set2
)
7841 return set_from_map(isl_map_union_disjoint(set_to_map(set1
),
7845 struct isl_set
*isl_set_union(struct isl_set
*set1
, struct isl_set
*set2
)
7847 return set_from_map(isl_map_union(set_to_map(set1
), set_to_map(set2
)));
7850 /* Apply "fn" to pairs of elements from "map" and "set" and collect
7853 * "map" and "set" are assumed to be compatible and non-NULL.
7855 static __isl_give isl_map
*map_intersect_set(__isl_take isl_map
*map
,
7856 __isl_take isl_set
*set
,
7857 __isl_give isl_basic_map
*fn(__isl_take isl_basic_map
*bmap
,
7858 __isl_take isl_basic_set
*bset
))
7861 struct isl_map
*result
;
7864 if (isl_set_plain_is_universe(set
)) {
7869 if (ISL_F_ISSET(map
, ISL_MAP_DISJOINT
) &&
7870 ISL_F_ISSET(set
, ISL_MAP_DISJOINT
))
7871 ISL_FL_SET(flags
, ISL_MAP_DISJOINT
);
7873 result
= isl_map_alloc_space(isl_space_copy(map
->dim
),
7874 map
->n
* set
->n
, flags
);
7875 for (i
= 0; result
&& i
< map
->n
; ++i
)
7876 for (j
= 0; j
< set
->n
; ++j
) {
7877 result
= isl_map_add_basic_map(result
,
7878 fn(isl_basic_map_copy(map
->p
[i
]),
7879 isl_basic_set_copy(set
->p
[j
])));
7889 static __isl_give isl_map
*map_intersect_range(__isl_take isl_map
*map
,
7890 __isl_take isl_set
*set
)
7894 ok
= isl_map_compatible_range(map
, set
);
7898 isl_die(set
->ctx
, isl_error_invalid
,
7899 "incompatible spaces", goto error
);
7901 return map_intersect_set(map
, set
, &isl_basic_map_intersect_range
);
7908 __isl_give isl_map
*isl_map_intersect_range(__isl_take isl_map
*map
,
7909 __isl_take isl_set
*set
)
7911 return isl_map_align_params_map_map_and(map
, set
, &map_intersect_range
);
7914 static __isl_give isl_map
*map_intersect_domain(__isl_take isl_map
*map
,
7915 __isl_take isl_set
*set
)
7919 ok
= isl_map_compatible_domain(map
, set
);
7923 isl_die(set
->ctx
, isl_error_invalid
,
7924 "incompatible spaces", goto error
);
7926 return map_intersect_set(map
, set
, &isl_basic_map_intersect_domain
);
7933 __isl_give isl_map
*isl_map_intersect_domain(__isl_take isl_map
*map
,
7934 __isl_take isl_set
*set
)
7936 return isl_map_align_params_map_map_and(map
, set
,
7937 &map_intersect_domain
);
7940 /* Given a map "map" in a space [A -> B] -> C and a map "factor"
7941 * in the space B -> C, return the intersection.
7942 * The parameters are assumed to have been aligned.
7944 * The map "factor" is first extended to a map living in the space
7945 * [A -> B] -> C and then a regular intersection is computed.
7947 static __isl_give isl_map
*map_intersect_domain_factor_range(
7948 __isl_take isl_map
*map
, __isl_take isl_map
*factor
)
7951 isl_map
*ext_factor
;
7953 space
= isl_space_domain_factor_domain(isl_map_get_space(map
));
7954 ext_factor
= isl_map_universe(space
);
7955 ext_factor
= isl_map_domain_product(ext_factor
, factor
);
7956 return map_intersect(map
, ext_factor
);
7959 /* Given a map "map" in a space [A -> B] -> C and a map "factor"
7960 * in the space B -> C, return the intersection.
7962 __isl_give isl_map
*isl_map_intersect_domain_factor_range(
7963 __isl_take isl_map
*map
, __isl_take isl_map
*factor
)
7965 return isl_map_align_params_map_map_and(map
, factor
,
7966 &map_intersect_domain_factor_range
);
7969 /* Given a map "map" in a space A -> [B -> C] and a map "factor"
7970 * in the space A -> C, return the intersection.
7972 * The map "factor" is first extended to a map living in the space
7973 * A -> [B -> C] and then a regular intersection is computed.
7975 static __isl_give isl_map
*map_intersect_range_factor_range(
7976 __isl_take isl_map
*map
, __isl_take isl_map
*factor
)
7979 isl_map
*ext_factor
;
7981 space
= isl_space_range_factor_domain(isl_map_get_space(map
));
7982 ext_factor
= isl_map_universe(space
);
7983 ext_factor
= isl_map_range_product(ext_factor
, factor
);
7984 return isl_map_intersect(map
, ext_factor
);
7987 /* Given a map "map" in a space A -> [B -> C] and a map "factor"
7988 * in the space A -> C, return the intersection.
7990 __isl_give isl_map
*isl_map_intersect_range_factor_range(
7991 __isl_take isl_map
*map
, __isl_take isl_map
*factor
)
7993 return isl_map_align_params_map_map_and(map
, factor
,
7994 &map_intersect_range_factor_range
);
7997 static __isl_give isl_map
*map_apply_domain(__isl_take isl_map
*map1
,
7998 __isl_take isl_map
*map2
)
8002 map1
= isl_map_reverse(map1
);
8003 map1
= isl_map_apply_range(map1
, map2
);
8004 return isl_map_reverse(map1
);
8011 __isl_give isl_map
*isl_map_apply_domain(__isl_take isl_map
*map1
,
8012 __isl_take isl_map
*map2
)
8014 return isl_map_align_params_map_map_and(map1
, map2
, &map_apply_domain
);
8017 static __isl_give isl_map
*map_apply_range(__isl_take isl_map
*map1
,
8018 __isl_take isl_map
*map2
)
8021 struct isl_map
*result
;
8027 space
= isl_space_join(isl_space_copy(map1
->dim
),
8028 isl_space_copy(map2
->dim
));
8030 result
= isl_map_alloc_space(space
, map1
->n
* map2
->n
, 0);
8033 for (i
= 0; i
< map1
->n
; ++i
)
8034 for (j
= 0; j
< map2
->n
; ++j
) {
8035 result
= isl_map_add_basic_map(result
,
8036 isl_basic_map_apply_range(
8037 isl_basic_map_copy(map1
->p
[i
]),
8038 isl_basic_map_copy(map2
->p
[j
])));
8044 if (result
&& result
->n
<= 1)
8045 ISL_F_SET(result
, ISL_MAP_DISJOINT
);
8053 __isl_give isl_map
*isl_map_apply_range(__isl_take isl_map
*map1
,
8054 __isl_take isl_map
*map2
)
8056 return isl_map_align_params_map_map_and(map1
, map2
, &map_apply_range
);
8060 * returns range - domain
8062 __isl_give isl_basic_set
*isl_basic_map_deltas(__isl_take isl_basic_map
*bmap
)
8064 isl_space
*target_space
;
8065 struct isl_basic_set
*bset
;
8073 isl_assert(bmap
->ctx
, isl_space_tuple_is_equal(bmap
->dim
, isl_dim_in
,
8074 bmap
->dim
, isl_dim_out
),
8076 dim
= isl_basic_map_dim(bmap
, isl_dim_in
);
8077 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
8078 if (dim
< 0 || nparam
< 0)
8080 target_space
= isl_space_domain(isl_basic_map_get_space(bmap
));
8081 bmap
= isl_basic_map_from_range(isl_basic_map_wrap(bmap
));
8082 bmap
= isl_basic_map_add_dims(bmap
, isl_dim_in
, dim
);
8083 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
8085 bmap
= isl_basic_map_free(bmap
);
8086 bmap
= isl_basic_map_extend_constraints(bmap
, dim
, 0);
8087 for (i
= 0; i
< dim
; ++i
) {
8088 int j
= isl_basic_map_alloc_equality(bmap
);
8090 bmap
= isl_basic_map_free(bmap
);
8093 isl_seq_clr(bmap
->eq
[j
], 1 + total
);
8094 isl_int_set_si(bmap
->eq
[j
][1+nparam
+i
], 1);
8095 isl_int_set_si(bmap
->eq
[j
][1+nparam
+dim
+i
], 1);
8096 isl_int_set_si(bmap
->eq
[j
][1+nparam
+2*dim
+i
], -1);
8098 bset
= isl_basic_map_domain(bmap
);
8099 bset
= isl_basic_set_reset_space(bset
, target_space
);
8102 isl_basic_map_free(bmap
);
8106 /* Check that domain and range of "map" are the same.
8108 isl_stat
isl_map_check_equal_tuples(__isl_keep isl_map
*map
)
8113 space
= isl_map_peek_space(map
);
8114 equal
= isl_space_tuple_is_equal(space
, isl_dim_in
, space
, isl_dim_out
);
8116 return isl_stat_error
;
8118 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
8119 "domain and range don't match", return isl_stat_error
);
8124 * returns range - domain
8126 __isl_give isl_set
*isl_map_deltas(__isl_take isl_map
*map
)
8130 struct isl_set
*result
;
8135 isl_assert(map
->ctx
, isl_space_tuple_is_equal(map
->dim
, isl_dim_in
,
8136 map
->dim
, isl_dim_out
),
8138 dim
= isl_map_get_space(map
);
8139 dim
= isl_space_domain(dim
);
8140 result
= isl_set_alloc_space(dim
, map
->n
, 0);
8143 for (i
= 0; i
< map
->n
; ++i
)
8144 result
= isl_set_add_basic_set(result
,
8145 isl_basic_map_deltas(isl_basic_map_copy(map
->p
[i
])));
8154 * returns [domain -> range] -> range - domain
8156 __isl_give isl_basic_map
*isl_basic_map_deltas_map(
8157 __isl_take isl_basic_map
*bmap
)
8161 isl_basic_map
*domain
;
8165 if (!isl_space_tuple_is_equal(bmap
->dim
, isl_dim_in
,
8166 bmap
->dim
, isl_dim_out
))
8167 isl_die(bmap
->ctx
, isl_error_invalid
,
8168 "domain and range don't match", goto error
);
8170 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
8171 n
= isl_basic_map_dim(bmap
, isl_dim_in
);
8172 if (nparam
< 0 || n
< 0)
8173 return isl_basic_map_free(bmap
);
8175 space
= isl_basic_map_get_space(bmap
);
8176 space
= isl_space_from_range(isl_space_domain(space
));
8177 domain
= isl_basic_map_universe(space
);
8179 bmap
= isl_basic_map_from_domain(isl_basic_map_wrap(bmap
));
8180 bmap
= isl_basic_map_apply_range(bmap
, domain
);
8181 bmap
= isl_basic_map_extend_constraints(bmap
, n
, 0);
8183 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
8185 return isl_basic_map_free(bmap
);
8187 for (i
= 0; i
< n
; ++i
) {
8188 k
= isl_basic_map_alloc_equality(bmap
);
8191 isl_seq_clr(bmap
->eq
[k
], 1 + total
);
8192 isl_int_set_si(bmap
->eq
[k
][1 + nparam
+ i
], 1);
8193 isl_int_set_si(bmap
->eq
[k
][1 + nparam
+ n
+ i
], -1);
8194 isl_int_set_si(bmap
->eq
[k
][1 + nparam
+ n
+ n
+ i
], 1);
8197 bmap
= isl_basic_map_gauss(bmap
, NULL
);
8198 return isl_basic_map_finalize(bmap
);
8200 isl_basic_map_free(bmap
);
8205 * returns [domain -> range] -> range - domain
8207 __isl_give isl_map
*isl_map_deltas_map(__isl_take isl_map
*map
)
8210 isl_space
*domain_space
;
8212 if (isl_map_check_equal_tuples(map
) < 0)
8213 return isl_map_free(map
);
8215 map
= isl_map_cow(map
);
8219 domain_space
= isl_space_domain(isl_map_get_space(map
));
8220 map
->dim
= isl_space_from_domain(isl_space_wrap(map
->dim
));
8221 map
->dim
= isl_space_join(map
->dim
, isl_space_from_range(domain_space
));
8224 for (i
= 0; i
< map
->n
; ++i
) {
8225 map
->p
[i
] = isl_basic_map_deltas_map(map
->p
[i
]);
8229 map
= isl_map_unmark_normalized(map
);
8236 __isl_give isl_basic_map
*isl_basic_map_identity(__isl_take isl_space
*space
)
8238 isl_size n_in
, n_out
;
8240 n_in
= isl_space_dim(space
, isl_dim_in
);
8241 n_out
= isl_space_dim(space
, isl_dim_out
);
8242 if (n_in
< 0 || n_out
< 0)
8245 isl_die(space
->ctx
, isl_error_invalid
,
8246 "number of input and output dimensions needs to be "
8247 "the same", goto error
);
8248 return isl_basic_map_equal(space
, n_in
);
8250 isl_space_free(space
);
8254 __isl_give isl_map
*isl_map_identity(__isl_take isl_space
*dim
)
8256 return isl_map_from_basic_map(isl_basic_map_identity(dim
));
8259 __isl_give isl_map
*isl_set_identity(__isl_take isl_set
*set
)
8261 isl_space
*dim
= isl_set_get_space(set
);
8263 id
= isl_map_identity(isl_space_map_from_set(dim
));
8264 return isl_map_intersect_range(id
, set
);
8267 /* Construct a basic set with all set dimensions having only non-negative
8270 __isl_give isl_basic_set
*isl_basic_set_positive_orthant(
8271 __isl_take isl_space
*space
)
8277 struct isl_basic_set
*bset
;
8279 nparam
= isl_space_dim(space
, isl_dim_param
);
8280 dim
= isl_space_dim(space
, isl_dim_set
);
8281 total
= isl_space_dim(space
, isl_dim_all
);
8282 if (nparam
< 0 || dim
< 0 || total
< 0)
8283 space
= isl_space_free(space
);
8284 bset
= isl_basic_set_alloc_space(space
, 0, 0, dim
);
8287 for (i
= 0; i
< dim
; ++i
) {
8288 int k
= isl_basic_set_alloc_inequality(bset
);
8291 isl_seq_clr(bset
->ineq
[k
], 1 + total
);
8292 isl_int_set_si(bset
->ineq
[k
][1 + nparam
+ i
], 1);
8296 isl_basic_set_free(bset
);
8300 /* Construct the half-space x_pos >= 0.
8302 static __isl_give isl_basic_set
*nonneg_halfspace(__isl_take isl_space
*space
,
8307 isl_basic_set
*nonneg
;
8309 total
= isl_space_dim(space
, isl_dim_all
);
8311 space
= isl_space_free(space
);
8312 nonneg
= isl_basic_set_alloc_space(space
, 0, 0, 1);
8313 k
= isl_basic_set_alloc_inequality(nonneg
);
8316 isl_seq_clr(nonneg
->ineq
[k
], 1 + total
);
8317 isl_int_set_si(nonneg
->ineq
[k
][pos
], 1);
8319 return isl_basic_set_finalize(nonneg
);
8321 isl_basic_set_free(nonneg
);
8325 /* Construct the half-space x_pos <= -1.
8327 static __isl_give isl_basic_set
*neg_halfspace(__isl_take isl_space
*space
,
8334 total
= isl_space_dim(space
, isl_dim_all
);
8336 space
= isl_space_free(space
);
8337 neg
= isl_basic_set_alloc_space(space
, 0, 0, 1);
8338 k
= isl_basic_set_alloc_inequality(neg
);
8341 isl_seq_clr(neg
->ineq
[k
], 1 + total
);
8342 isl_int_set_si(neg
->ineq
[k
][0], -1);
8343 isl_int_set_si(neg
->ineq
[k
][pos
], -1);
8345 return isl_basic_set_finalize(neg
);
8347 isl_basic_set_free(neg
);
8351 __isl_give isl_set
*isl_set_split_dims(__isl_take isl_set
*set
,
8352 enum isl_dim_type type
, unsigned first
, unsigned n
)
8356 isl_basic_set
*nonneg
;
8362 if (isl_set_check_range(set
, type
, first
, n
) < 0)
8363 return isl_set_free(set
);
8365 offset
= pos(set
->dim
, type
);
8366 for (i
= 0; i
< n
; ++i
) {
8367 nonneg
= nonneg_halfspace(isl_set_get_space(set
),
8368 offset
+ first
+ i
);
8369 neg
= neg_halfspace(isl_set_get_space(set
), offset
+ first
+ i
);
8371 set
= isl_set_intersect(set
, isl_basic_set_union(nonneg
, neg
));
8377 static isl_stat
foreach_orthant(__isl_take isl_set
*set
, int *signs
, int first
,
8379 isl_stat (*fn
)(__isl_take isl_set
*orthant
, int *signs
, void *user
),
8385 return isl_stat_error
;
8386 if (isl_set_plain_is_empty(set
)) {
8391 return fn(set
, signs
, user
);
8394 half
= isl_set_from_basic_set(nonneg_halfspace(isl_set_get_space(set
),
8396 half
= isl_set_intersect(half
, isl_set_copy(set
));
8397 if (foreach_orthant(half
, signs
, first
+ 1, len
, fn
, user
) < 0)
8401 half
= isl_set_from_basic_set(neg_halfspace(isl_set_get_space(set
),
8403 half
= isl_set_intersect(half
, set
);
8404 return foreach_orthant(half
, signs
, first
+ 1, len
, fn
, user
);
8407 return isl_stat_error
;
8410 /* Call "fn" on the intersections of "set" with each of the orthants
8411 * (except for obviously empty intersections). The orthant is identified
8412 * by the signs array, with each entry having value 1 or -1 according
8413 * to the sign of the corresponding variable.
8415 isl_stat
isl_set_foreach_orthant(__isl_keep isl_set
*set
,
8416 isl_stat (*fn
)(__isl_take isl_set
*orthant
, int *signs
, void *user
),
8425 return isl_stat_error
;
8426 if (isl_set_plain_is_empty(set
))
8429 nparam
= isl_set_dim(set
, isl_dim_param
);
8430 nvar
= isl_set_dim(set
, isl_dim_set
);
8431 if (nparam
< 0 || nvar
< 0)
8432 return isl_stat_error
;
8434 signs
= isl_alloc_array(set
->ctx
, int, nparam
+ nvar
);
8436 r
= foreach_orthant(isl_set_copy(set
), signs
, 0, nparam
+ nvar
,
8444 isl_bool
isl_set_is_equal(__isl_keep isl_set
*set1
, __isl_keep isl_set
*set2
)
8446 return isl_map_is_equal(set_to_map(set1
), set_to_map(set2
));
8449 isl_bool
isl_basic_map_is_subset(__isl_keep isl_basic_map
*bmap1
,
8450 __isl_keep isl_basic_map
*bmap2
)
8453 struct isl_map
*map1
;
8454 struct isl_map
*map2
;
8456 if (!bmap1
|| !bmap2
)
8457 return isl_bool_error
;
8459 map1
= isl_map_from_basic_map(isl_basic_map_copy(bmap1
));
8460 map2
= isl_map_from_basic_map(isl_basic_map_copy(bmap2
));
8462 is_subset
= isl_map_is_subset(map1
, map2
);
8470 isl_bool
isl_basic_set_is_subset(__isl_keep isl_basic_set
*bset1
,
8471 __isl_keep isl_basic_set
*bset2
)
8473 return isl_basic_map_is_subset(bset1
, bset2
);
8476 isl_bool
isl_basic_map_is_equal(__isl_keep isl_basic_map
*bmap1
,
8477 __isl_keep isl_basic_map
*bmap2
)
8481 if (!bmap1
|| !bmap2
)
8482 return isl_bool_error
;
8483 is_subset
= isl_basic_map_is_subset(bmap1
, bmap2
);
8484 if (is_subset
!= isl_bool_true
)
8486 is_subset
= isl_basic_map_is_subset(bmap2
, bmap1
);
8490 isl_bool
isl_basic_set_is_equal(__isl_keep isl_basic_set
*bset1
,
8491 __isl_keep isl_basic_set
*bset2
)
8493 return isl_basic_map_is_equal(
8494 bset_to_bmap(bset1
), bset_to_bmap(bset2
));
8497 isl_bool
isl_map_is_empty(__isl_keep isl_map
*map
)
8503 return isl_bool_error
;
8504 for (i
= 0; i
< map
->n
; ++i
) {
8505 is_empty
= isl_basic_map_is_empty(map
->p
[i
]);
8507 return isl_bool_error
;
8509 return isl_bool_false
;
8511 return isl_bool_true
;
8514 isl_bool
isl_map_plain_is_empty(__isl_keep isl_map
*map
)
8516 return map
? map
->n
== 0 : isl_bool_error
;
8519 isl_bool
isl_set_plain_is_empty(__isl_keep isl_set
*set
)
8521 return set
? set
->n
== 0 : isl_bool_error
;
8524 isl_bool
isl_set_is_empty(__isl_keep isl_set
*set
)
8526 return isl_map_is_empty(set_to_map(set
));
8529 isl_bool
isl_map_has_equal_space(__isl_keep isl_map
*map1
,
8530 __isl_keep isl_map
*map2
)
8533 return isl_bool_error
;
8535 return isl_space_is_equal(map1
->dim
, map2
->dim
);
8538 isl_bool
isl_set_has_equal_space(__isl_keep isl_set
*set1
,
8539 __isl_keep isl_set
*set2
)
8542 return isl_bool_error
;
8544 return isl_space_is_equal(set1
->dim
, set2
->dim
);
8547 static isl_bool
map_is_equal(__isl_keep isl_map
*map1
, __isl_keep isl_map
*map2
)
8552 return isl_bool_error
;
8553 is_subset
= isl_map_is_subset(map1
, map2
);
8554 if (is_subset
!= isl_bool_true
)
8556 is_subset
= isl_map_is_subset(map2
, map1
);
8560 /* Is "map1" equal to "map2"?
8562 * First check if they are obviously equal.
8563 * If not, then perform a more detailed analysis.
8565 isl_bool
isl_map_is_equal(__isl_keep isl_map
*map1
, __isl_keep isl_map
*map2
)
8569 equal
= isl_map_plain_is_equal(map1
, map2
);
8570 if (equal
< 0 || equal
)
8572 return isl_map_align_params_map_map_and_test(map1
, map2
, &map_is_equal
);
8575 isl_bool
isl_basic_map_is_strict_subset(
8576 struct isl_basic_map
*bmap1
, struct isl_basic_map
*bmap2
)
8580 if (!bmap1
|| !bmap2
)
8581 return isl_bool_error
;
8582 is_subset
= isl_basic_map_is_subset(bmap1
, bmap2
);
8583 if (is_subset
!= isl_bool_true
)
8585 is_subset
= isl_basic_map_is_subset(bmap2
, bmap1
);
8586 return isl_bool_not(is_subset
);
8589 isl_bool
isl_map_is_strict_subset(__isl_keep isl_map
*map1
,
8590 __isl_keep isl_map
*map2
)
8595 return isl_bool_error
;
8596 is_subset
= isl_map_is_subset(map1
, map2
);
8597 if (is_subset
!= isl_bool_true
)
8599 is_subset
= isl_map_is_subset(map2
, map1
);
8600 return isl_bool_not(is_subset
);
8603 isl_bool
isl_set_is_strict_subset(__isl_keep isl_set
*set1
,
8604 __isl_keep isl_set
*set2
)
8606 return isl_map_is_strict_subset(set_to_map(set1
), set_to_map(set2
));
8609 /* Is "bmap" obviously equal to the universe with the same space?
8611 * That is, does it not have any constraints?
8613 isl_bool
isl_basic_map_plain_is_universe(__isl_keep isl_basic_map
*bmap
)
8616 return isl_bool_error
;
8617 return bmap
->n_eq
== 0 && bmap
->n_ineq
== 0;
8620 /* Is "bset" obviously equal to the universe with the same space?
8622 isl_bool
isl_basic_set_plain_is_universe(__isl_keep isl_basic_set
*bset
)
8624 return isl_basic_map_plain_is_universe(bset
);
8627 /* If "c" does not involve any existentially quantified variables,
8628 * then set *univ to false and abort
8630 static isl_stat
involves_divs(__isl_take isl_constraint
*c
, void *user
)
8632 isl_bool
*univ
= user
;
8635 n
= isl_constraint_dim(c
, isl_dim_div
);
8637 c
= isl_constraint_free(c
);
8638 *univ
= isl_constraint_involves_dims(c
, isl_dim_div
, 0, n
);
8639 isl_constraint_free(c
);
8640 if (*univ
< 0 || !*univ
)
8641 return isl_stat_error
;
8645 /* Is "bmap" equal to the universe with the same space?
8647 * First check if it is obviously equal to the universe.
8648 * If not and if there are any constraints not involving
8649 * existentially quantified variables, then it is certainly
8650 * not equal to the universe.
8651 * Otherwise, check if the universe is a subset of "bmap".
8653 isl_bool
isl_basic_map_is_universe(__isl_keep isl_basic_map
*bmap
)
8657 isl_basic_map
*test
;
8659 univ
= isl_basic_map_plain_is_universe(bmap
);
8660 if (univ
< 0 || univ
)
8662 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
8664 return isl_bool_error
;
8666 return isl_bool_false
;
8667 univ
= isl_bool_true
;
8668 if (isl_basic_map_foreach_constraint(bmap
, &involves_divs
, &univ
) < 0 &&
8670 return isl_bool_error
;
8671 if (univ
< 0 || !univ
)
8673 test
= isl_basic_map_universe(isl_basic_map_get_space(bmap
));
8674 univ
= isl_basic_map_is_subset(test
, bmap
);
8675 isl_basic_map_free(test
);
8679 /* Is "bset" equal to the universe with the same space?
8681 isl_bool
isl_basic_set_is_universe(__isl_keep isl_basic_set
*bset
)
8683 return isl_basic_map_is_universe(bset
);
8686 isl_bool
isl_map_plain_is_universe(__isl_keep isl_map
*map
)
8691 return isl_bool_error
;
8693 for (i
= 0; i
< map
->n
; ++i
) {
8694 isl_bool r
= isl_basic_map_plain_is_universe(map
->p
[i
]);
8699 return isl_bool_false
;
8702 isl_bool
isl_set_plain_is_universe(__isl_keep isl_set
*set
)
8704 return isl_map_plain_is_universe(set_to_map(set
));
8707 isl_bool
isl_basic_map_is_empty(__isl_keep isl_basic_map
*bmap
)
8709 struct isl_basic_set
*bset
= NULL
;
8710 struct isl_vec
*sample
= NULL
;
8711 isl_bool empty
, non_empty
;
8714 return isl_bool_error
;
8716 if (ISL_F_ISSET(bmap
, ISL_BASIC_MAP_EMPTY
))
8717 return isl_bool_true
;
8719 if (isl_basic_map_plain_is_universe(bmap
))
8720 return isl_bool_false
;
8722 if (ISL_F_ISSET(bmap
, ISL_BASIC_MAP_RATIONAL
)) {
8723 struct isl_basic_map
*copy
= isl_basic_map_copy(bmap
);
8724 copy
= isl_basic_map_remove_redundancies(copy
);
8725 empty
= isl_basic_map_plain_is_empty(copy
);
8726 isl_basic_map_free(copy
);
8730 non_empty
= isl_basic_map_plain_is_non_empty(bmap
);
8732 return isl_bool_error
;
8734 return isl_bool_false
;
8735 isl_vec_free(bmap
->sample
);
8736 bmap
->sample
= NULL
;
8737 bset
= isl_basic_map_underlying_set(isl_basic_map_copy(bmap
));
8739 return isl_bool_error
;
8740 sample
= isl_basic_set_sample_vec(bset
);
8742 return isl_bool_error
;
8743 empty
= sample
->size
== 0;
8744 isl_vec_free(bmap
->sample
);
8745 bmap
->sample
= sample
;
8747 ISL_F_SET(bmap
, ISL_BASIC_MAP_EMPTY
);
8752 isl_bool
isl_basic_map_plain_is_empty(__isl_keep isl_basic_map
*bmap
)
8755 return isl_bool_error
;
8756 return ISL_F_ISSET(bmap
, ISL_BASIC_MAP_EMPTY
);
8759 isl_bool
isl_basic_set_plain_is_empty(__isl_keep isl_basic_set
*bset
)
8762 return isl_bool_error
;
8763 return ISL_F_ISSET(bset
, ISL_BASIC_SET_EMPTY
);
8766 /* Is "bmap" known to be non-empty?
8768 * That is, is the cached sample still valid?
8770 isl_bool
isl_basic_map_plain_is_non_empty(__isl_keep isl_basic_map
*bmap
)
8775 return isl_bool_error
;
8777 return isl_bool_false
;
8778 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
8780 return isl_bool_error
;
8781 if (bmap
->sample
->size
!= 1 + total
)
8782 return isl_bool_false
;
8783 return isl_basic_map_contains(bmap
, bmap
->sample
);
8786 isl_bool
isl_basic_set_is_empty(__isl_keep isl_basic_set
*bset
)
8788 return isl_basic_map_is_empty(bset_to_bmap(bset
));
8791 __isl_give isl_map
*isl_basic_map_union(__isl_take isl_basic_map
*bmap1
,
8792 __isl_take isl_basic_map
*bmap2
)
8794 struct isl_map
*map
;
8795 if (!bmap1
|| !bmap2
)
8798 isl_assert(bmap1
->ctx
, isl_space_is_equal(bmap1
->dim
, bmap2
->dim
), goto error
);
8800 map
= isl_map_alloc_space(isl_space_copy(bmap1
->dim
), 2, 0);
8803 map
= isl_map_add_basic_map(map
, bmap1
);
8804 map
= isl_map_add_basic_map(map
, bmap2
);
8807 isl_basic_map_free(bmap1
);
8808 isl_basic_map_free(bmap2
);
8812 struct isl_set
*isl_basic_set_union(
8813 struct isl_basic_set
*bset1
, struct isl_basic_set
*bset2
)
8815 return set_from_map(isl_basic_map_union(bset_to_bmap(bset1
),
8816 bset_to_bmap(bset2
)));
8819 /* Order divs such that any div only depends on previous divs */
8820 __isl_give isl_basic_map
*isl_basic_map_order_divs(
8821 __isl_take isl_basic_map
*bmap
)
8826 off
= isl_basic_map_var_offset(bmap
, isl_dim_div
);
8828 return isl_basic_map_free(bmap
);
8830 for (i
= 0; i
< bmap
->n_div
; ++i
) {
8832 if (isl_int_is_zero(bmap
->div
[i
][0]))
8834 pos
= isl_seq_first_non_zero(bmap
->div
[i
]+1+1+off
+i
,
8839 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_internal
,
8840 "integer division depends on itself",
8841 return isl_basic_map_free(bmap
));
8842 bmap
= isl_basic_map_swap_div(bmap
, i
, i
+ pos
);
8850 struct isl_basic_set
*isl_basic_set_order_divs(struct isl_basic_set
*bset
)
8852 return bset_from_bmap(isl_basic_map_order_divs(bset_to_bmap(bset
)));
8855 __isl_give isl_map
*isl_map_order_divs(__isl_take isl_map
*map
)
8862 for (i
= 0; i
< map
->n
; ++i
) {
8863 map
->p
[i
] = isl_basic_map_order_divs(map
->p
[i
]);
8874 /* Sort the local variables of "bset".
8876 __isl_give isl_basic_set
*isl_basic_set_sort_divs(
8877 __isl_take isl_basic_set
*bset
)
8879 return bset_from_bmap(isl_basic_map_sort_divs(bset_to_bmap(bset
)));
8882 /* Apply the expansion computed by isl_merge_divs.
8883 * The expansion itself is given by "exp" while the resulting
8884 * list of divs is given by "div".
8886 * Move the integer divisions of "bmap" into the right position
8887 * according to "exp" and then introduce the additional integer
8888 * divisions, adding div constraints.
8889 * The moving should be done first to avoid moving coefficients
8890 * in the definitions of the extra integer divisions.
8892 __isl_give isl_basic_map
*isl_basic_map_expand_divs(
8893 __isl_take isl_basic_map
*bmap
, __isl_take isl_mat
*div
, int *exp
)
8898 bmap
= isl_basic_map_cow(bmap
);
8902 if (div
->n_row
< bmap
->n_div
)
8903 isl_die(isl_mat_get_ctx(div
), isl_error_invalid
,
8904 "not an expansion", goto error
);
8906 n_div
= bmap
->n_div
;
8907 bmap
= isl_basic_map_extend_space(bmap
, isl_space_copy(bmap
->dim
),
8908 div
->n_row
- n_div
, 0,
8909 2 * (div
->n_row
- n_div
));
8911 for (i
= n_div
; i
< div
->n_row
; ++i
)
8912 if (isl_basic_map_alloc_div(bmap
) < 0)
8915 for (j
= n_div
- 1; j
>= 0; --j
) {
8918 bmap
= isl_basic_map_swap_div(bmap
, j
, exp
[j
]);
8923 for (i
= 0; i
< div
->n_row
; ++i
) {
8924 if (j
< n_div
&& exp
[j
] == i
) {
8927 isl_seq_cpy(bmap
->div
[i
], div
->row
[i
], div
->n_col
);
8928 if (isl_basic_map_div_is_marked_unknown(bmap
, i
))
8930 bmap
= isl_basic_map_add_div_constraints(bmap
, i
);
8939 isl_basic_map_free(bmap
);
8944 /* Apply the expansion computed by isl_merge_divs.
8945 * The expansion itself is given by "exp" while the resulting
8946 * list of divs is given by "div".
8948 __isl_give isl_basic_set
*isl_basic_set_expand_divs(
8949 __isl_take isl_basic_set
*bset
, __isl_take isl_mat
*div
, int *exp
)
8951 return isl_basic_map_expand_divs(bset
, div
, exp
);
8954 /* Look for a div in dst that corresponds to the div "div" in src.
8955 * The divs before "div" in src and dst are assumed to be the same.
8957 * Return the position of the corresponding div in dst
8958 * if there is one. Otherwise, return a position beyond the integer divisions.
8959 * Return -1 on error.
8961 static int find_div(__isl_keep isl_basic_map
*dst
,
8962 __isl_keep isl_basic_map
*src
, unsigned div
)
8968 v_div
= isl_basic_map_var_offset(src
, isl_dim_div
);
8969 n_div
= isl_basic_map_dim(dst
, isl_dim_div
);
8970 if (n_div
< 0 || v_div
< 0)
8972 isl_assert(dst
->ctx
, div
<= n_div
, return -1);
8973 for (i
= div
; i
< n_div
; ++i
)
8974 if (isl_seq_eq(dst
->div
[i
], src
->div
[div
], 1+1+v_div
+div
) &&
8975 isl_seq_first_non_zero(dst
->div
[i
] + 1 + 1 + v_div
+ div
,
8981 /* Align the divs of "dst" to those of "src", adding divs from "src"
8982 * if needed. That is, make sure that the first src->n_div divs
8983 * of the result are equal to those of src.
8985 * The result is not finalized as by design it will have redundant
8986 * divs if any divs from "src" were copied.
8988 __isl_give isl_basic_map
*isl_basic_map_align_divs(
8989 __isl_take isl_basic_map
*dst
, __isl_keep isl_basic_map
*src
)
8998 return isl_basic_map_free(dst
);
9000 if (src
->n_div
== 0)
9003 known
= isl_basic_map_divs_known(src
);
9005 return isl_basic_map_free(dst
);
9007 isl_die(isl_basic_map_get_ctx(src
), isl_error_invalid
,
9008 "some src divs are unknown",
9009 return isl_basic_map_free(dst
));
9011 v_div
= isl_basic_map_var_offset(src
, isl_dim_div
);
9013 return isl_basic_map_free(dst
);
9015 src
= isl_basic_map_order_divs(isl_basic_map_copy(src
));
9017 return isl_basic_map_free(dst
);
9020 dst_n_div
= isl_basic_map_dim(dst
, isl_dim_div
);
9022 dst
= isl_basic_map_free(dst
);
9023 for (i
= 0; i
< src
->n_div
; ++i
) {
9024 int j
= find_div(dst
, src
, i
);
9026 dst
= isl_basic_map_free(dst
);
9027 if (j
== dst_n_div
) {
9029 int extra
= src
->n_div
- i
;
9030 dst
= isl_basic_map_cow(dst
);
9033 dst
= isl_basic_map_extend_space(dst
,
9034 isl_space_copy(dst
->dim
),
9035 extra
, 0, 2 * extra
);
9038 j
= isl_basic_map_alloc_div(dst
);
9041 isl_seq_cpy(dst
->div
[j
], src
->div
[i
], 1+1+v_div
+i
);
9042 isl_seq_clr(dst
->div
[j
]+1+1+v_div
+i
, dst
->n_div
- i
);
9044 dst
= isl_basic_map_add_div_constraints(dst
, j
);
9049 dst
= isl_basic_map_swap_div(dst
, i
, j
);
9053 isl_basic_map_free(src
);
9056 isl_basic_map_free(src
);
9057 isl_basic_map_free(dst
);
9061 __isl_give isl_map
*isl_map_align_divs_internal(__isl_take isl_map
*map
)
9069 map
= isl_map_compute_divs(map
);
9070 map
= isl_map_cow(map
);
9074 for (i
= 1; i
< map
->n
; ++i
)
9075 map
->p
[0] = isl_basic_map_align_divs(map
->p
[0], map
->p
[i
]);
9076 for (i
= 1; i
< map
->n
; ++i
) {
9077 map
->p
[i
] = isl_basic_map_align_divs(map
->p
[i
], map
->p
[0]);
9079 return isl_map_free(map
);
9082 map
= isl_map_unmark_normalized(map
);
9086 __isl_give isl_map
*isl_map_align_divs(__isl_take isl_map
*map
)
9088 return isl_map_align_divs_internal(map
);
9091 struct isl_set
*isl_set_align_divs(struct isl_set
*set
)
9093 return set_from_map(isl_map_align_divs_internal(set_to_map(set
)));
9096 /* Align the divs of the basic maps in "map" to those
9097 * of the basic maps in "list", as well as to the other basic maps in "map".
9098 * The elements in "list" are assumed to have known divs.
9100 __isl_give isl_map
*isl_map_align_divs_to_basic_map_list(
9101 __isl_take isl_map
*map
, __isl_keep isl_basic_map_list
*list
)
9106 n
= isl_basic_map_list_n_basic_map(list
);
9107 map
= isl_map_compute_divs(map
);
9108 map
= isl_map_cow(map
);
9110 return isl_map_free(map
);
9114 for (i
= 0; i
< n
; ++i
) {
9115 isl_basic_map
*bmap
;
9117 bmap
= isl_basic_map_list_get_basic_map(list
, i
);
9118 map
->p
[0] = isl_basic_map_align_divs(map
->p
[0], bmap
);
9119 isl_basic_map_free(bmap
);
9122 return isl_map_free(map
);
9124 return isl_map_align_divs_internal(map
);
9127 /* Align the divs of each element of "list" to those of "bmap".
9128 * Both "bmap" and the elements of "list" are assumed to have known divs.
9130 __isl_give isl_basic_map_list
*isl_basic_map_list_align_divs_to_basic_map(
9131 __isl_take isl_basic_map_list
*list
, __isl_keep isl_basic_map
*bmap
)
9136 n
= isl_basic_map_list_n_basic_map(list
);
9138 return isl_basic_map_list_free(list
);
9140 for (i
= 0; i
< n
; ++i
) {
9141 isl_basic_map
*bmap_i
;
9143 bmap_i
= isl_basic_map_list_get_basic_map(list
, i
);
9144 bmap_i
= isl_basic_map_align_divs(bmap_i
, bmap
);
9145 list
= isl_basic_map_list_set_basic_map(list
, i
, bmap_i
);
9151 static __isl_give isl_set
*set_apply( __isl_take isl_set
*set
,
9152 __isl_take isl_map
*map
)
9156 ok
= isl_map_compatible_domain(map
, set
);
9160 isl_die(isl_set_get_ctx(set
), isl_error_invalid
,
9161 "incompatible spaces", goto error
);
9162 map
= isl_map_intersect_domain(map
, set
);
9163 set
= isl_map_range(map
);
9171 __isl_give isl_set
*isl_set_apply( __isl_take isl_set
*set
,
9172 __isl_take isl_map
*map
)
9174 return isl_map_align_params_map_map_and(set
, map
, &set_apply
);
9177 /* There is no need to cow as removing empty parts doesn't change
9178 * the meaning of the set.
9180 __isl_give isl_map
*isl_map_remove_empty_parts(__isl_take isl_map
*map
)
9187 for (i
= map
->n
- 1; i
>= 0; --i
)
9188 map
= remove_if_empty(map
, i
);
9193 struct isl_set
*isl_set_remove_empty_parts(struct isl_set
*set
)
9195 return set_from_map(isl_map_remove_empty_parts(set_to_map(set
)));
9198 /* Create a binary relation that maps the shared initial "pos" dimensions
9199 * of "bset1" and "bset2" to the remaining dimensions of "bset1" and "bset2".
9201 static __isl_give isl_basic_map
*join_initial(__isl_keep isl_basic_set
*bset1
,
9202 __isl_keep isl_basic_set
*bset2
, int pos
)
9204 isl_basic_map
*bmap1
;
9205 isl_basic_map
*bmap2
;
9207 bmap1
= isl_basic_map_from_range(isl_basic_set_copy(bset1
));
9208 bmap2
= isl_basic_map_from_range(isl_basic_set_copy(bset2
));
9209 bmap1
= isl_basic_map_move_dims(bmap1
, isl_dim_in
, 0,
9210 isl_dim_out
, 0, pos
);
9211 bmap2
= isl_basic_map_move_dims(bmap2
, isl_dim_in
, 0,
9212 isl_dim_out
, 0, pos
);
9213 return isl_basic_map_range_product(bmap1
, bmap2
);
9216 /* Given two basic sets bset1 and bset2, compute the maximal difference
9217 * between the values of dimension pos in bset1 and those in bset2
9218 * for any common value of the parameters and dimensions preceding pos.
9220 static enum isl_lp_result
basic_set_maximal_difference_at(
9221 __isl_keep isl_basic_set
*bset1
, __isl_keep isl_basic_set
*bset2
,
9222 int pos
, isl_int
*opt
)
9224 isl_basic_map
*bmap1
;
9225 struct isl_ctx
*ctx
;
9226 struct isl_vec
*obj
;
9230 enum isl_lp_result res
;
9232 nparam
= isl_basic_set_dim(bset1
, isl_dim_param
);
9233 dim1
= isl_basic_set_dim(bset1
, isl_dim_set
);
9234 if (nparam
< 0 || dim1
< 0 || !bset2
)
9235 return isl_lp_error
;
9237 bmap1
= join_initial(bset1
, bset2
, pos
);
9238 total
= isl_basic_map_dim(bmap1
, isl_dim_all
);
9240 return isl_lp_error
;
9243 obj
= isl_vec_alloc(ctx
, 1 + total
);
9246 isl_seq_clr(obj
->block
.data
, 1 + total
);
9247 isl_int_set_si(obj
->block
.data
[1+nparam
+pos
], 1);
9248 isl_int_set_si(obj
->block
.data
[1+nparam
+pos
+(dim1
-pos
)], -1);
9249 res
= isl_basic_map_solve_lp(bmap1
, 1, obj
->block
.data
, ctx
->one
,
9251 isl_basic_map_free(bmap1
);
9255 isl_basic_map_free(bmap1
);
9256 return isl_lp_error
;
9259 /* Given two _disjoint_ basic sets bset1 and bset2, check whether
9260 * for any common value of the parameters and dimensions preceding pos
9261 * in both basic sets, the values of dimension pos in bset1 are
9262 * smaller or larger than those in bset2.
9265 * 1 if bset1 follows bset2
9266 * -1 if bset1 precedes bset2
9267 * 0 if bset1 and bset2 are incomparable
9268 * -2 if some error occurred.
9270 int isl_basic_set_compare_at(__isl_keep isl_basic_set
*bset1
,
9271 __isl_keep isl_basic_set
*bset2
, int pos
)
9274 enum isl_lp_result res
;
9279 res
= basic_set_maximal_difference_at(bset1
, bset2
, pos
, &opt
);
9281 if (res
== isl_lp_empty
)
9283 else if ((res
== isl_lp_ok
&& isl_int_is_pos(opt
)) ||
9284 res
== isl_lp_unbounded
)
9286 else if (res
== isl_lp_ok
&& isl_int_is_neg(opt
))
9295 /* Given two basic sets bset1 and bset2, check whether
9296 * for any common value of the parameters and dimensions preceding pos
9297 * there is a value of dimension pos in bset1 that is larger
9298 * than a value of the same dimension in bset2.
9301 * 1 if there exists such a pair
9302 * 0 if there is no such pair, but there is a pair of equal values
9304 * -2 if some error occurred.
9306 int isl_basic_set_follows_at(__isl_keep isl_basic_set
*bset1
,
9307 __isl_keep isl_basic_set
*bset2
, int pos
)
9310 isl_basic_map
*bmap
;
9313 dim1
= isl_basic_set_dim(bset1
, isl_dim_set
);
9316 bmap
= join_initial(bset1
, bset2
, pos
);
9317 bmap
= isl_basic_map_order_ge(bmap
, isl_dim_out
, 0,
9318 isl_dim_out
, dim1
- pos
);
9319 empty
= isl_basic_map_is_empty(bmap
);
9323 isl_basic_map_free(bmap
);
9326 bmap
= isl_basic_map_order_gt(bmap
, isl_dim_out
, 0,
9327 isl_dim_out
, dim1
- pos
);
9328 empty
= isl_basic_map_is_empty(bmap
);
9331 isl_basic_map_free(bmap
);
9336 isl_basic_map_free(bmap
);
9340 /* Given two sets set1 and set2, check whether
9341 * for any common value of the parameters and dimensions preceding pos
9342 * there is a value of dimension pos in set1 that is larger
9343 * than a value of the same dimension in set2.
9346 * 1 if there exists such a pair
9347 * 0 if there is no such pair, but there is a pair of equal values
9349 * -2 if some error occurred.
9351 int isl_set_follows_at(__isl_keep isl_set
*set1
,
9352 __isl_keep isl_set
*set2
, int pos
)
9360 for (i
= 0; i
< set1
->n
; ++i
)
9361 for (j
= 0; j
< set2
->n
; ++j
) {
9363 f
= isl_basic_set_follows_at(set1
->p
[i
], set2
->p
[j
], pos
);
9364 if (f
== 1 || f
== -2)
9373 static isl_bool
isl_basic_map_plain_has_fixed_var(
9374 __isl_keep isl_basic_map
*bmap
, unsigned pos
, isl_int
*val
)
9380 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
9382 return isl_bool_error
;
9383 for (i
= 0, d
= total
-1; i
< bmap
->n_eq
&& d
+1 > pos
; ++i
) {
9384 for (; d
+1 > pos
; --d
)
9385 if (!isl_int_is_zero(bmap
->eq
[i
][1+d
]))
9389 if (isl_seq_first_non_zero(bmap
->eq
[i
]+1, d
) != -1)
9390 return isl_bool_false
;
9391 if (isl_seq_first_non_zero(bmap
->eq
[i
]+1+d
+1, total
-d
-1) != -1)
9392 return isl_bool_false
;
9393 if (!isl_int_is_one(bmap
->eq
[i
][1+d
]))
9394 return isl_bool_false
;
9396 isl_int_neg(*val
, bmap
->eq
[i
][0]);
9397 return isl_bool_true
;
9399 return isl_bool_false
;
9402 static isl_bool
isl_map_plain_has_fixed_var(__isl_keep isl_map
*map
,
9403 unsigned pos
, isl_int
*val
)
9411 return isl_bool_error
;
9413 return isl_bool_false
;
9415 return isl_basic_map_plain_has_fixed_var(map
->p
[0], pos
, val
);
9418 fixed
= isl_basic_map_plain_has_fixed_var(map
->p
[0], pos
, &v
);
9419 for (i
= 1; fixed
== isl_bool_true
&& i
< map
->n
; ++i
) {
9420 fixed
= isl_basic_map_plain_has_fixed_var(map
->p
[i
], pos
, &tmp
);
9421 if (fixed
== isl_bool_true
&& isl_int_ne(tmp
, v
))
9422 fixed
= isl_bool_false
;
9425 isl_int_set(*val
, v
);
9431 static isl_bool
isl_basic_set_plain_has_fixed_var(
9432 __isl_keep isl_basic_set
*bset
, unsigned pos
, isl_int
*val
)
9434 return isl_basic_map_plain_has_fixed_var(bset_to_bmap(bset
),
9438 isl_bool
isl_basic_map_plain_is_fixed(__isl_keep isl_basic_map
*bmap
,
9439 enum isl_dim_type type
, unsigned pos
, isl_int
*val
)
9441 if (isl_basic_map_check_range(bmap
, type
, pos
, 1) < 0)
9442 return isl_bool_error
;
9443 return isl_basic_map_plain_has_fixed_var(bmap
,
9444 isl_basic_map_offset(bmap
, type
) - 1 + pos
, val
);
9447 /* If "bmap" obviously lies on a hyperplane where the given dimension
9448 * has a fixed value, then return that value.
9449 * Otherwise return NaN.
9451 __isl_give isl_val
*isl_basic_map_plain_get_val_if_fixed(
9452 __isl_keep isl_basic_map
*bmap
,
9453 enum isl_dim_type type
, unsigned pos
)
9461 ctx
= isl_basic_map_get_ctx(bmap
);
9462 v
= isl_val_alloc(ctx
);
9465 fixed
= isl_basic_map_plain_is_fixed(bmap
, type
, pos
, &v
->n
);
9467 return isl_val_free(v
);
9469 isl_int_set_si(v
->d
, 1);
9473 return isl_val_nan(ctx
);
9476 isl_bool
isl_map_plain_is_fixed(__isl_keep isl_map
*map
,
9477 enum isl_dim_type type
, unsigned pos
, isl_int
*val
)
9479 if (isl_map_check_range(map
, type
, pos
, 1) < 0)
9480 return isl_bool_error
;
9481 return isl_map_plain_has_fixed_var(map
,
9482 map_offset(map
, type
) - 1 + pos
, val
);
9485 /* If "map" obviously lies on a hyperplane where the given dimension
9486 * has a fixed value, then return that value.
9487 * Otherwise return NaN.
9489 __isl_give isl_val
*isl_map_plain_get_val_if_fixed(__isl_keep isl_map
*map
,
9490 enum isl_dim_type type
, unsigned pos
)
9498 ctx
= isl_map_get_ctx(map
);
9499 v
= isl_val_alloc(ctx
);
9502 fixed
= isl_map_plain_is_fixed(map
, type
, pos
, &v
->n
);
9504 return isl_val_free(v
);
9506 isl_int_set_si(v
->d
, 1);
9510 return isl_val_nan(ctx
);
9513 /* If "set" obviously lies on a hyperplane where the given dimension
9514 * has a fixed value, then return that value.
9515 * Otherwise return NaN.
9517 __isl_give isl_val
*isl_set_plain_get_val_if_fixed(__isl_keep isl_set
*set
,
9518 enum isl_dim_type type
, unsigned pos
)
9520 return isl_map_plain_get_val_if_fixed(set
, type
, pos
);
9523 /* Check if dimension dim has fixed value and if so and if val is not NULL,
9524 * then return this fixed value in *val.
9526 isl_bool
isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_set
*bset
,
9527 unsigned dim
, isl_int
*val
)
9531 nparam
= isl_basic_set_dim(bset
, isl_dim_param
);
9533 return isl_bool_error
;
9534 return isl_basic_set_plain_has_fixed_var(bset
, nparam
+ dim
, val
);
9537 /* Return -1 if the constraint "c1" should be sorted before "c2"
9538 * and 1 if it should be sorted after "c2".
9539 * Return 0 if the two constraints are the same (up to the constant term).
9541 * In particular, if a constraint involves later variables than another
9542 * then it is sorted after this other constraint.
9543 * uset_gist depends on constraints without existentially quantified
9544 * variables sorting first.
9546 * For constraints that have the same latest variable, those
9547 * with the same coefficient for this latest variable (first in absolute value
9548 * and then in actual value) are grouped together.
9549 * This is useful for detecting pairs of constraints that can
9550 * be chained in their printed representation.
9552 * Finally, within a group, constraints are sorted according to
9553 * their coefficients (excluding the constant term).
9555 static int sort_constraint_cmp(const void *p1
, const void *p2
, void *arg
)
9557 isl_int
**c1
= (isl_int
**) p1
;
9558 isl_int
**c2
= (isl_int
**) p2
;
9560 unsigned size
= *(unsigned *) arg
;
9563 l1
= isl_seq_last_non_zero(*c1
+ 1, size
);
9564 l2
= isl_seq_last_non_zero(*c2
+ 1, size
);
9569 cmp
= isl_int_abs_cmp((*c1
)[1 + l1
], (*c2
)[1 + l1
]);
9572 cmp
= isl_int_cmp((*c1
)[1 + l1
], (*c2
)[1 + l1
]);
9576 return isl_seq_cmp(*c1
+ 1, *c2
+ 1, size
);
9579 /* Return -1 if the constraint "c1" of "bmap" is sorted before "c2"
9580 * by isl_basic_map_sort_constraints, 1 if it is sorted after "c2"
9581 * and 0 if the two constraints are the same (up to the constant term).
9583 int isl_basic_map_constraint_cmp(__isl_keep isl_basic_map
*bmap
,
9584 isl_int
*c1
, isl_int
*c2
)
9589 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
9593 return sort_constraint_cmp(&c1
, &c2
, &size
);
9596 __isl_give isl_basic_map
*isl_basic_map_sort_constraints(
9597 __isl_take isl_basic_map
*bmap
)
9604 if (bmap
->n_ineq
== 0)
9606 if (ISL_F_ISSET(bmap
, ISL_BASIC_MAP_SORTED
))
9608 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
9610 return isl_basic_map_free(bmap
);
9612 if (isl_sort(bmap
->ineq
, bmap
->n_ineq
, sizeof(isl_int
*),
9613 &sort_constraint_cmp
, &size
) < 0)
9614 return isl_basic_map_free(bmap
);
9615 ISL_F_SET(bmap
, ISL_BASIC_MAP_SORTED
);
9619 __isl_give isl_basic_set
*isl_basic_set_sort_constraints(
9620 __isl_take isl_basic_set
*bset
)
9622 isl_basic_map
*bmap
= bset_to_bmap(bset
);
9623 return bset_from_bmap(isl_basic_map_sort_constraints(bmap
));
9626 __isl_give isl_basic_map
*isl_basic_map_normalize(
9627 __isl_take isl_basic_map
*bmap
)
9629 bmap
= isl_basic_map_remove_redundancies(bmap
);
9630 bmap
= isl_basic_map_sort_constraints(bmap
);
9633 int isl_basic_map_plain_cmp(__isl_keep isl_basic_map
*bmap1
,
9634 __isl_keep isl_basic_map
*bmap2
)
9638 isl_space
*space1
, *space2
;
9640 if (!bmap1
|| !bmap2
)
9645 space1
= isl_basic_map_peek_space(bmap1
);
9646 space2
= isl_basic_map_peek_space(bmap2
);
9647 cmp
= isl_space_cmp(space1
, space2
);
9650 if (ISL_F_ISSET(bmap1
, ISL_BASIC_MAP_RATIONAL
) !=
9651 ISL_F_ISSET(bmap2
, ISL_BASIC_MAP_RATIONAL
))
9652 return ISL_F_ISSET(bmap1
, ISL_BASIC_MAP_RATIONAL
) ? -1 : 1;
9653 if (ISL_F_ISSET(bmap1
, ISL_BASIC_MAP_EMPTY
) &&
9654 ISL_F_ISSET(bmap2
, ISL_BASIC_MAP_EMPTY
))
9656 if (ISL_F_ISSET(bmap1
, ISL_BASIC_MAP_EMPTY
))
9658 if (ISL_F_ISSET(bmap2
, ISL_BASIC_MAP_EMPTY
))
9660 if (bmap1
->n_eq
!= bmap2
->n_eq
)
9661 return bmap1
->n_eq
- bmap2
->n_eq
;
9662 if (bmap1
->n_ineq
!= bmap2
->n_ineq
)
9663 return bmap1
->n_ineq
- bmap2
->n_ineq
;
9664 if (bmap1
->n_div
!= bmap2
->n_div
)
9665 return bmap1
->n_div
- bmap2
->n_div
;
9666 total
= isl_basic_map_dim(bmap1
, isl_dim_all
);
9669 for (i
= 0; i
< bmap1
->n_eq
; ++i
) {
9670 cmp
= isl_seq_cmp(bmap1
->eq
[i
], bmap2
->eq
[i
], 1+total
);
9674 for (i
= 0; i
< bmap1
->n_ineq
; ++i
) {
9675 cmp
= isl_seq_cmp(bmap1
->ineq
[i
], bmap2
->ineq
[i
], 1+total
);
9679 for (i
= 0; i
< bmap1
->n_div
; ++i
) {
9680 cmp
= isl_seq_cmp(bmap1
->div
[i
], bmap2
->div
[i
], 1+1+total
);
9687 int isl_basic_set_plain_cmp(__isl_keep isl_basic_set
*bset1
,
9688 __isl_keep isl_basic_set
*bset2
)
9690 return isl_basic_map_plain_cmp(bset1
, bset2
);
9693 int isl_set_plain_cmp(__isl_keep isl_set
*set1
, __isl_keep isl_set
*set2
)
9699 if (set1
->n
!= set2
->n
)
9700 return set1
->n
- set2
->n
;
9702 for (i
= 0; i
< set1
->n
; ++i
) {
9703 cmp
= isl_basic_set_plain_cmp(set1
->p
[i
], set2
->p
[i
]);
9711 isl_bool
isl_basic_map_plain_is_equal(__isl_keep isl_basic_map
*bmap1
,
9712 __isl_keep isl_basic_map
*bmap2
)
9714 if (!bmap1
|| !bmap2
)
9715 return isl_bool_error
;
9716 return isl_basic_map_plain_cmp(bmap1
, bmap2
) == 0;
9719 isl_bool
isl_basic_set_plain_is_equal(__isl_keep isl_basic_set
*bset1
,
9720 __isl_keep isl_basic_set
*bset2
)
9722 return isl_basic_map_plain_is_equal(bset_to_bmap(bset1
),
9723 bset_to_bmap(bset2
));
9726 static int qsort_bmap_cmp(const void *p1
, const void *p2
)
9728 isl_basic_map
*bmap1
= *(isl_basic_map
**) p1
;
9729 isl_basic_map
*bmap2
= *(isl_basic_map
**) p2
;
9731 return isl_basic_map_plain_cmp(bmap1
, bmap2
);
9734 /* Sort the basic maps of "map" and remove duplicate basic maps.
9736 * While removing basic maps, we make sure that the basic maps remain
9737 * sorted because isl_map_normalize expects the basic maps of the result
9740 static __isl_give isl_map
*sort_and_remove_duplicates(__isl_take isl_map
*map
)
9744 map
= isl_map_remove_empty_parts(map
);
9747 qsort(map
->p
, map
->n
, sizeof(struct isl_basic_map
*), qsort_bmap_cmp
);
9748 for (i
= map
->n
- 1; i
>= 1; --i
) {
9749 if (!isl_basic_map_plain_is_equal(map
->p
[i
- 1], map
->p
[i
]))
9751 isl_basic_map_free(map
->p
[i
-1]);
9752 for (j
= i
; j
< map
->n
; ++j
)
9753 map
->p
[j
- 1] = map
->p
[j
];
9760 /* Remove obvious duplicates among the basic maps of "map".
9762 * Unlike isl_map_normalize, this function does not remove redundant
9763 * constraints and only removes duplicates that have exactly the same
9764 * constraints in the input. It does sort the constraints and
9765 * the basic maps to ease the detection of duplicates.
9767 * If "map" has already been normalized or if the basic maps are
9768 * disjoint, then there can be no duplicates.
9770 __isl_give isl_map
*isl_map_remove_obvious_duplicates(__isl_take isl_map
*map
)
9773 isl_basic_map
*bmap
;
9779 if (ISL_F_ISSET(map
, ISL_MAP_NORMALIZED
| ISL_MAP_DISJOINT
))
9781 for (i
= 0; i
< map
->n
; ++i
) {
9782 bmap
= isl_basic_map_copy(map
->p
[i
]);
9783 bmap
= isl_basic_map_sort_constraints(bmap
);
9785 return isl_map_free(map
);
9786 isl_basic_map_free(map
->p
[i
]);
9790 map
= sort_and_remove_duplicates(map
);
9794 /* We normalize in place, but if anything goes wrong we need
9795 * to return NULL, so we need to make sure we don't change the
9796 * meaning of any possible other copies of map.
9798 __isl_give isl_map
*isl_map_normalize(__isl_take isl_map
*map
)
9801 struct isl_basic_map
*bmap
;
9805 if (ISL_F_ISSET(map
, ISL_MAP_NORMALIZED
))
9807 for (i
= 0; i
< map
->n
; ++i
) {
9808 bmap
= isl_basic_map_normalize(isl_basic_map_copy(map
->p
[i
]));
9811 isl_basic_map_free(map
->p
[i
]);
9815 map
= sort_and_remove_duplicates(map
);
9817 ISL_F_SET(map
, ISL_MAP_NORMALIZED
);
9824 struct isl_set
*isl_set_normalize(struct isl_set
*set
)
9826 return set_from_map(isl_map_normalize(set_to_map(set
)));
9829 isl_bool
isl_map_plain_is_equal(__isl_keep isl_map
*map1
,
9830 __isl_keep isl_map
*map2
)
9836 return isl_bool_error
;
9839 return isl_bool_true
;
9840 if (!isl_space_is_equal(map1
->dim
, map2
->dim
))
9841 return isl_bool_false
;
9843 map1
= isl_map_copy(map1
);
9844 map2
= isl_map_copy(map2
);
9845 map1
= isl_map_normalize(map1
);
9846 map2
= isl_map_normalize(map2
);
9849 equal
= map1
->n
== map2
->n
;
9850 for (i
= 0; equal
&& i
< map1
->n
; ++i
) {
9851 equal
= isl_basic_map_plain_is_equal(map1
->p
[i
], map2
->p
[i
]);
9861 return isl_bool_error
;
9864 isl_bool
isl_set_plain_is_equal(__isl_keep isl_set
*set1
,
9865 __isl_keep isl_set
*set2
)
9867 return isl_map_plain_is_equal(set_to_map(set1
), set_to_map(set2
));
9870 /* Return the basic maps in "map" as a list.
9872 __isl_give isl_basic_map_list
*isl_map_get_basic_map_list(
9873 __isl_keep isl_map
*map
)
9877 isl_basic_map_list
*list
;
9881 ctx
= isl_map_get_ctx(map
);
9882 list
= isl_basic_map_list_alloc(ctx
, map
->n
);
9884 for (i
= 0; i
< map
->n
; ++i
) {
9885 isl_basic_map
*bmap
;
9887 bmap
= isl_basic_map_copy(map
->p
[i
]);
9888 list
= isl_basic_map_list_add(list
, bmap
);
9894 /* Return the intersection of the elements in the non-empty list "list".
9895 * All elements are assumed to live in the same space.
9897 __isl_give isl_basic_map
*isl_basic_map_list_intersect(
9898 __isl_take isl_basic_map_list
*list
)
9902 isl_basic_map
*bmap
;
9904 n
= isl_basic_map_list_n_basic_map(list
);
9908 isl_die(isl_basic_map_list_get_ctx(list
), isl_error_invalid
,
9909 "expecting non-empty list", goto error
);
9911 bmap
= isl_basic_map_list_get_basic_map(list
, 0);
9912 for (i
= 1; i
< n
; ++i
) {
9913 isl_basic_map
*bmap_i
;
9915 bmap_i
= isl_basic_map_list_get_basic_map(list
, i
);
9916 bmap
= isl_basic_map_intersect(bmap
, bmap_i
);
9919 isl_basic_map_list_free(list
);
9922 isl_basic_map_list_free(list
);
9926 /* Return the intersection of the elements in the non-empty list "list".
9927 * All elements are assumed to live in the same space.
9929 __isl_give isl_basic_set
*isl_basic_set_list_intersect(
9930 __isl_take isl_basic_set_list
*list
)
9932 return isl_basic_map_list_intersect(list
);
9935 /* Return the union of the elements of "list".
9936 * The list is required to have at least one element.
9938 __isl_give isl_set
*isl_basic_set_list_union(
9939 __isl_take isl_basic_set_list
*list
)
9944 isl_basic_set
*bset
;
9947 n
= isl_basic_set_list_n_basic_set(list
);
9951 isl_die(isl_basic_set_list_get_ctx(list
), isl_error_invalid
,
9952 "expecting non-empty list", goto error
);
9954 bset
= isl_basic_set_list_get_basic_set(list
, 0);
9955 space
= isl_basic_set_get_space(bset
);
9956 isl_basic_set_free(bset
);
9958 set
= isl_set_alloc_space(space
, n
, 0);
9959 for (i
= 0; i
< n
; ++i
) {
9960 bset
= isl_basic_set_list_get_basic_set(list
, i
);
9961 set
= isl_set_add_basic_set(set
, bset
);
9964 isl_basic_set_list_free(list
);
9967 isl_basic_set_list_free(list
);
9971 /* Return the union of the elements in the non-empty list "list".
9972 * All elements are assumed to live in the same space.
9974 __isl_give isl_set
*isl_set_list_union(__isl_take isl_set_list
*list
)
9980 n
= isl_set_list_n_set(list
);
9984 isl_die(isl_set_list_get_ctx(list
), isl_error_invalid
,
9985 "expecting non-empty list", goto error
);
9987 set
= isl_set_list_get_set(list
, 0);
9988 for (i
= 1; i
< n
; ++i
) {
9991 set_i
= isl_set_list_get_set(list
, i
);
9992 set
= isl_set_union(set
, set_i
);
9995 isl_set_list_free(list
);
9998 isl_set_list_free(list
);
10002 __isl_give isl_basic_map
*isl_basic_map_product(
10003 __isl_take isl_basic_map
*bmap1
, __isl_take isl_basic_map
*bmap2
)
10005 isl_space
*space_result
= NULL
;
10006 struct isl_basic_map
*bmap
;
10007 unsigned in1
, in2
, out1
, out2
, nparam
, total
, pos
;
10008 struct isl_dim_map
*dim_map1
, *dim_map2
;
10010 if (isl_basic_map_check_equal_params(bmap1
, bmap2
) < 0)
10012 space_result
= isl_space_product(isl_space_copy(bmap1
->dim
),
10013 isl_space_copy(bmap2
->dim
));
10015 in1
= isl_basic_map_dim(bmap1
, isl_dim_in
);
10016 in2
= isl_basic_map_dim(bmap2
, isl_dim_in
);
10017 out1
= isl_basic_map_dim(bmap1
, isl_dim_out
);
10018 out2
= isl_basic_map_dim(bmap2
, isl_dim_out
);
10019 nparam
= isl_basic_map_dim(bmap1
, isl_dim_param
);
10021 total
= nparam
+ in1
+ in2
+ out1
+ out2
+ bmap1
->n_div
+ bmap2
->n_div
;
10022 dim_map1
= isl_dim_map_alloc(bmap1
->ctx
, total
);
10023 dim_map2
= isl_dim_map_alloc(bmap1
->ctx
, total
);
10024 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_param
, pos
= 0);
10025 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_param
, pos
= 0);
10026 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_in
, pos
+= nparam
);
10027 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_in
, pos
+= in1
);
10028 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_out
, pos
+= in2
);
10029 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_out
, pos
+= out1
);
10030 isl_dim_map_div(dim_map1
, bmap1
, pos
+= out2
);
10031 isl_dim_map_div(dim_map2
, bmap2
, pos
+= bmap1
->n_div
);
10033 bmap
= isl_basic_map_alloc_space(space_result
,
10034 bmap1
->n_div
+ bmap2
->n_div
,
10035 bmap1
->n_eq
+ bmap2
->n_eq
,
10036 bmap1
->n_ineq
+ bmap2
->n_ineq
);
10037 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap1
, dim_map1
);
10038 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap2
, dim_map2
);
10039 bmap
= isl_basic_map_simplify(bmap
);
10040 return isl_basic_map_finalize(bmap
);
10042 isl_basic_map_free(bmap1
);
10043 isl_basic_map_free(bmap2
);
10047 __isl_give isl_basic_map
*isl_basic_map_flat_product(
10048 __isl_take isl_basic_map
*bmap1
, __isl_take isl_basic_map
*bmap2
)
10050 isl_basic_map
*prod
;
10052 prod
= isl_basic_map_product(bmap1
, bmap2
);
10053 prod
= isl_basic_map_flatten(prod
);
10057 __isl_give isl_basic_set
*isl_basic_set_flat_product(
10058 __isl_take isl_basic_set
*bset1
, __isl_take isl_basic_set
*bset2
)
10060 return isl_basic_map_flat_range_product(bset1
, bset2
);
10063 __isl_give isl_basic_map
*isl_basic_map_domain_product(
10064 __isl_take isl_basic_map
*bmap1
, __isl_take isl_basic_map
*bmap2
)
10066 isl_space
*space1
, *space2
;
10067 isl_space
*space_result
= NULL
;
10068 isl_basic_map
*bmap
;
10069 isl_size in1
, in2
, out
, nparam
;
10070 unsigned total
, pos
;
10071 struct isl_dim_map
*dim_map1
, *dim_map2
;
10073 in1
= isl_basic_map_dim(bmap1
, isl_dim_in
);
10074 in2
= isl_basic_map_dim(bmap2
, isl_dim_in
);
10075 out
= isl_basic_map_dim(bmap1
, isl_dim_out
);
10076 nparam
= isl_basic_map_dim(bmap1
, isl_dim_param
);
10077 if (in1
< 0 || in2
< 0 || out
< 0 || nparam
< 0)
10080 space1
= isl_basic_map_get_space(bmap1
);
10081 space2
= isl_basic_map_get_space(bmap2
);
10082 space_result
= isl_space_domain_product(space1
, space2
);
10084 total
= nparam
+ in1
+ in2
+ out
+ bmap1
->n_div
+ bmap2
->n_div
;
10085 dim_map1
= isl_dim_map_alloc(bmap1
->ctx
, total
);
10086 dim_map2
= isl_dim_map_alloc(bmap1
->ctx
, total
);
10087 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_param
, pos
= 0);
10088 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_param
, pos
= 0);
10089 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_in
, pos
+= nparam
);
10090 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_in
, pos
+= in1
);
10091 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_out
, pos
+= in2
);
10092 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_out
, pos
);
10093 isl_dim_map_div(dim_map1
, bmap1
, pos
+= out
);
10094 isl_dim_map_div(dim_map2
, bmap2
, pos
+= bmap1
->n_div
);
10096 bmap
= isl_basic_map_alloc_space(space_result
,
10097 bmap1
->n_div
+ bmap2
->n_div
,
10098 bmap1
->n_eq
+ bmap2
->n_eq
,
10099 bmap1
->n_ineq
+ bmap2
->n_ineq
);
10100 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap1
, dim_map1
);
10101 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap2
, dim_map2
);
10102 bmap
= isl_basic_map_simplify(bmap
);
10103 return isl_basic_map_finalize(bmap
);
10105 isl_basic_map_free(bmap1
);
10106 isl_basic_map_free(bmap2
);
10110 __isl_give isl_basic_map
*isl_basic_map_range_product(
10111 __isl_take isl_basic_map
*bmap1
, __isl_take isl_basic_map
*bmap2
)
10114 isl_space
*space_result
= NULL
;
10115 isl_basic_map
*bmap
;
10116 isl_size in
, out1
, out2
, nparam
;
10117 unsigned total
, pos
;
10118 struct isl_dim_map
*dim_map1
, *dim_map2
;
10120 rational
= isl_basic_map_is_rational(bmap1
);
10121 if (rational
>= 0 && rational
)
10122 rational
= isl_basic_map_is_rational(bmap2
);
10123 in
= isl_basic_map_dim(bmap1
, isl_dim_in
);
10124 out1
= isl_basic_map_dim(bmap1
, isl_dim_out
);
10125 out2
= isl_basic_map_dim(bmap2
, isl_dim_out
);
10126 nparam
= isl_basic_map_dim(bmap1
, isl_dim_param
);
10127 if (in
< 0 || out1
< 0 || out2
< 0 || nparam
< 0 || rational
< 0)
10130 if (isl_basic_map_check_equal_params(bmap1
, bmap2
) < 0)
10133 space_result
= isl_space_range_product(isl_space_copy(bmap1
->dim
),
10134 isl_space_copy(bmap2
->dim
));
10136 total
= nparam
+ in
+ out1
+ out2
+ bmap1
->n_div
+ bmap2
->n_div
;
10137 dim_map1
= isl_dim_map_alloc(bmap1
->ctx
, total
);
10138 dim_map2
= isl_dim_map_alloc(bmap1
->ctx
, total
);
10139 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_param
, pos
= 0);
10140 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_param
, pos
= 0);
10141 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_in
, pos
+= nparam
);
10142 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_in
, pos
);
10143 isl_dim_map_dim(dim_map1
, bmap1
->dim
, isl_dim_out
, pos
+= in
);
10144 isl_dim_map_dim(dim_map2
, bmap2
->dim
, isl_dim_out
, pos
+= out1
);
10145 isl_dim_map_div(dim_map1
, bmap1
, pos
+= out2
);
10146 isl_dim_map_div(dim_map2
, bmap2
, pos
+= bmap1
->n_div
);
10148 bmap
= isl_basic_map_alloc_space(space_result
,
10149 bmap1
->n_div
+ bmap2
->n_div
,
10150 bmap1
->n_eq
+ bmap2
->n_eq
,
10151 bmap1
->n_ineq
+ bmap2
->n_ineq
);
10152 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap1
, dim_map1
);
10153 bmap
= isl_basic_map_add_constraints_dim_map(bmap
, bmap2
, dim_map2
);
10155 bmap
= isl_basic_map_set_rational(bmap
);
10156 bmap
= isl_basic_map_simplify(bmap
);
10157 return isl_basic_map_finalize(bmap
);
10159 isl_basic_map_free(bmap1
);
10160 isl_basic_map_free(bmap2
);
10164 __isl_give isl_basic_map
*isl_basic_map_flat_range_product(
10165 __isl_take isl_basic_map
*bmap1
, __isl_take isl_basic_map
*bmap2
)
10167 isl_basic_map
*prod
;
10169 prod
= isl_basic_map_range_product(bmap1
, bmap2
);
10170 prod
= isl_basic_map_flatten_range(prod
);
10174 /* Apply "basic_map_product" to each pair of basic maps in "map1" and "map2"
10175 * and collect the results.
10176 * The result live in the space obtained by calling "space_product"
10177 * on the spaces of "map1" and "map2".
10178 * If "remove_duplicates" is set then the result may contain duplicates
10179 * (even if the inputs do not) and so we try and remove the obvious
10182 static __isl_give isl_map
*map_product(__isl_take isl_map
*map1
,
10183 __isl_take isl_map
*map2
,
10184 __isl_give isl_space
*(*space_product
)(__isl_take isl_space
*left
,
10185 __isl_take isl_space
*right
),
10186 __isl_give isl_basic_map
*(*basic_map_product
)(
10187 __isl_take isl_basic_map
*left
,
10188 __isl_take isl_basic_map
*right
),
10189 int remove_duplicates
)
10191 unsigned flags
= 0;
10192 struct isl_map
*result
;
10196 m
= isl_map_has_equal_params(map1
, map2
);
10200 isl_die(isl_map_get_ctx(map1
), isl_error_invalid
,
10201 "parameters don't match", goto error
);
10203 if (ISL_F_ISSET(map1
, ISL_MAP_DISJOINT
) &&
10204 ISL_F_ISSET(map2
, ISL_MAP_DISJOINT
))
10205 ISL_FL_SET(flags
, ISL_MAP_DISJOINT
);
10207 result
= isl_map_alloc_space(space_product(isl_space_copy(map1
->dim
),
10208 isl_space_copy(map2
->dim
)),
10209 map1
->n
* map2
->n
, flags
);
10212 for (i
= 0; i
< map1
->n
; ++i
)
10213 for (j
= 0; j
< map2
->n
; ++j
) {
10214 struct isl_basic_map
*part
;
10215 part
= basic_map_product(isl_basic_map_copy(map1
->p
[i
]),
10216 isl_basic_map_copy(map2
->p
[j
]));
10217 if (isl_basic_map_is_empty(part
))
10218 isl_basic_map_free(part
);
10220 result
= isl_map_add_basic_map(result
, part
);
10224 if (remove_duplicates
)
10225 result
= isl_map_remove_obvious_duplicates(result
);
10226 isl_map_free(map1
);
10227 isl_map_free(map2
);
10230 isl_map_free(map1
);
10231 isl_map_free(map2
);
10235 /* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
10237 static __isl_give isl_map
*map_product_aligned(__isl_take isl_map
*map1
,
10238 __isl_take isl_map
*map2
)
10240 return map_product(map1
, map2
, &isl_space_product
,
10241 &isl_basic_map_product
, 0);
10244 __isl_give isl_map
*isl_map_product(__isl_take isl_map
*map1
,
10245 __isl_take isl_map
*map2
)
10247 return isl_map_align_params_map_map_and(map1
, map2
, &map_product_aligned
);
10250 /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
10252 __isl_give isl_map
*isl_map_flat_product(__isl_take isl_map
*map1
,
10253 __isl_take isl_map
*map2
)
10257 prod
= isl_map_product(map1
, map2
);
10258 prod
= isl_map_flatten(prod
);
10262 /* Given two set A and B, construct its Cartesian product A x B.
10264 struct isl_set
*isl_set_product(struct isl_set
*set1
, struct isl_set
*set2
)
10266 return isl_map_range_product(set1
, set2
);
10269 __isl_give isl_set
*isl_set_flat_product(__isl_take isl_set
*set1
,
10270 __isl_take isl_set
*set2
)
10272 return isl_map_flat_range_product(set1
, set2
);
10275 /* Given two maps A -> B and C -> D, construct a map [A -> C] -> (B * D)
10277 static __isl_give isl_map
*map_domain_product_aligned(__isl_take isl_map
*map1
,
10278 __isl_take isl_map
*map2
)
10280 return map_product(map1
, map2
, &isl_space_domain_product
,
10281 &isl_basic_map_domain_product
, 1);
10284 /* Given two maps A -> B and C -> D, construct a map (A * C) -> [B -> D]
10286 static __isl_give isl_map
*map_range_product_aligned(__isl_take isl_map
*map1
,
10287 __isl_take isl_map
*map2
)
10289 return map_product(map1
, map2
, &isl_space_range_product
,
10290 &isl_basic_map_range_product
, 1);
10293 __isl_give isl_map
*isl_map_domain_product(__isl_take isl_map
*map1
,
10294 __isl_take isl_map
*map2
)
10296 return isl_map_align_params_map_map_and(map1
, map2
,
10297 &map_domain_product_aligned
);
10300 __isl_give isl_map
*isl_map_range_product(__isl_take isl_map
*map1
,
10301 __isl_take isl_map
*map2
)
10303 return isl_map_align_params_map_map_and(map1
, map2
,
10304 &map_range_product_aligned
);
10307 /* Given a map of the form [A -> B] -> [C -> D], return the map A -> C.
10309 __isl_give isl_map
*isl_map_factor_domain(__isl_take isl_map
*map
)
10312 isl_size total1
, keep1
, total2
, keep2
;
10314 total1
= isl_map_dim(map
, isl_dim_in
);
10315 total2
= isl_map_dim(map
, isl_dim_out
);
10316 if (total1
< 0 || total2
< 0)
10317 return isl_map_free(map
);
10318 if (!isl_space_domain_is_wrapping(map
->dim
) ||
10319 !isl_space_range_is_wrapping(map
->dim
))
10320 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
10321 "not a product", return isl_map_free(map
));
10323 space
= isl_map_get_space(map
);
10324 space
= isl_space_factor_domain(space
);
10325 keep1
= isl_space_dim(space
, isl_dim_in
);
10326 keep2
= isl_space_dim(space
, isl_dim_out
);
10327 if (keep1
< 0 || keep2
< 0)
10328 map
= isl_map_free(map
);
10329 map
= isl_map_project_out(map
, isl_dim_in
, keep1
, total1
- keep1
);
10330 map
= isl_map_project_out(map
, isl_dim_out
, keep2
, total2
- keep2
);
10331 map
= isl_map_reset_space(map
, space
);
10336 /* Given a map of the form [A -> B] -> [C -> D], return the map B -> D.
10338 __isl_give isl_map
*isl_map_factor_range(__isl_take isl_map
*map
)
10341 isl_size total1
, keep1
, total2
, keep2
;
10343 total1
= isl_map_dim(map
, isl_dim_in
);
10344 total2
= isl_map_dim(map
, isl_dim_out
);
10345 if (total1
< 0 || total2
< 0)
10346 return isl_map_free(map
);
10347 if (!isl_space_domain_is_wrapping(map
->dim
) ||
10348 !isl_space_range_is_wrapping(map
->dim
))
10349 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
10350 "not a product", return isl_map_free(map
));
10352 space
= isl_map_get_space(map
);
10353 space
= isl_space_factor_range(space
);
10354 keep1
= isl_space_dim(space
, isl_dim_in
);
10355 keep2
= isl_space_dim(space
, isl_dim_out
);
10356 if (keep1
< 0 || keep2
< 0)
10357 map
= isl_map_free(map
);
10358 map
= isl_map_project_out(map
, isl_dim_in
, 0, total1
- keep1
);
10359 map
= isl_map_project_out(map
, isl_dim_out
, 0, total2
- keep2
);
10360 map
= isl_map_reset_space(map
, space
);
10365 /* Given a map of the form [A -> B] -> C, return the map A -> C.
10367 __isl_give isl_map
*isl_map_domain_factor_domain(__isl_take isl_map
*map
)
10370 isl_size total
, keep
;
10372 total
= isl_map_dim(map
, isl_dim_in
);
10374 return isl_map_free(map
);
10375 if (!isl_space_domain_is_wrapping(map
->dim
))
10376 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
10377 "domain is not a product", return isl_map_free(map
));
10379 space
= isl_map_get_space(map
);
10380 space
= isl_space_domain_factor_domain(space
);
10381 keep
= isl_space_dim(space
, isl_dim_in
);
10383 map
= isl_map_free(map
);
10384 map
= isl_map_project_out(map
, isl_dim_in
, keep
, total
- keep
);
10385 map
= isl_map_reset_space(map
, space
);
10390 /* Given a map of the form [A -> B] -> C, return the map B -> C.
10392 __isl_give isl_map
*isl_map_domain_factor_range(__isl_take isl_map
*map
)
10395 isl_size total
, keep
;
10397 total
= isl_map_dim(map
, isl_dim_in
);
10399 return isl_map_free(map
);
10400 if (!isl_space_domain_is_wrapping(map
->dim
))
10401 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
10402 "domain is not a product", return isl_map_free(map
));
10404 space
= isl_map_get_space(map
);
10405 space
= isl_space_domain_factor_range(space
);
10406 keep
= isl_space_dim(space
, isl_dim_in
);
10408 map
= isl_map_free(map
);
10409 map
= isl_map_project_out(map
, isl_dim_in
, 0, total
- keep
);
10410 map
= isl_map_reset_space(map
, space
);
10415 /* Given a map A -> [B -> C], extract the map A -> B.
10417 __isl_give isl_map
*isl_map_range_factor_domain(__isl_take isl_map
*map
)
10420 isl_size total
, keep
;
10422 total
= isl_map_dim(map
, isl_dim_out
);
10424 return isl_map_free(map
);
10425 if (!isl_space_range_is_wrapping(map
->dim
))
10426 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
10427 "range is not a product", return isl_map_free(map
));
10429 space
= isl_map_get_space(map
);
10430 space
= isl_space_range_factor_domain(space
);
10431 keep
= isl_space_dim(space
, isl_dim_out
);
10433 map
= isl_map_free(map
);
10434 map
= isl_map_project_out(map
, isl_dim_out
, keep
, total
- keep
);
10435 map
= isl_map_reset_space(map
, space
);
10440 /* Given a map A -> [B -> C], extract the map A -> C.
10442 __isl_give isl_map
*isl_map_range_factor_range(__isl_take isl_map
*map
)
10445 isl_size total
, keep
;
10447 total
= isl_map_dim(map
, isl_dim_out
);
10449 return isl_map_free(map
);
10450 if (!isl_space_range_is_wrapping(map
->dim
))
10451 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
10452 "range is not a product", return isl_map_free(map
));
10454 space
= isl_map_get_space(map
);
10455 space
= isl_space_range_factor_range(space
);
10456 keep
= isl_space_dim(space
, isl_dim_out
);
10458 map
= isl_map_free(map
);
10459 map
= isl_map_project_out(map
, isl_dim_out
, 0, total
- keep
);
10460 map
= isl_map_reset_space(map
, space
);
10465 /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D)
10467 __isl_give isl_map
*isl_map_flat_domain_product(__isl_take isl_map
*map1
,
10468 __isl_take isl_map
*map2
)
10472 prod
= isl_map_domain_product(map1
, map2
);
10473 prod
= isl_map_flatten_domain(prod
);
10477 /* Given two maps A -> B and C -> D, construct a map (A * C) -> (B, D)
10479 __isl_give isl_map
*isl_map_flat_range_product(__isl_take isl_map
*map1
,
10480 __isl_take isl_map
*map2
)
10484 prod
= isl_map_range_product(map1
, map2
);
10485 prod
= isl_map_flatten_range(prod
);
10489 uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map
*bmap
)
10492 uint32_t hash
= isl_hash_init();
10497 bmap
= isl_basic_map_copy(bmap
);
10498 bmap
= isl_basic_map_normalize(bmap
);
10499 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
10502 isl_hash_byte(hash
, bmap
->n_eq
& 0xFF);
10503 for (i
= 0; i
< bmap
->n_eq
; ++i
) {
10505 c_hash
= isl_seq_get_hash(bmap
->eq
[i
], 1 + total
);
10506 isl_hash_hash(hash
, c_hash
);
10508 isl_hash_byte(hash
, bmap
->n_ineq
& 0xFF);
10509 for (i
= 0; i
< bmap
->n_ineq
; ++i
) {
10511 c_hash
= isl_seq_get_hash(bmap
->ineq
[i
], 1 + total
);
10512 isl_hash_hash(hash
, c_hash
);
10514 isl_hash_byte(hash
, bmap
->n_div
& 0xFF);
10515 for (i
= 0; i
< bmap
->n_div
; ++i
) {
10517 if (isl_int_is_zero(bmap
->div
[i
][0]))
10519 isl_hash_byte(hash
, i
& 0xFF);
10520 c_hash
= isl_seq_get_hash(bmap
->div
[i
], 1 + 1 + total
);
10521 isl_hash_hash(hash
, c_hash
);
10523 isl_basic_map_free(bmap
);
10527 uint32_t isl_basic_set_get_hash(__isl_keep isl_basic_set
*bset
)
10529 return isl_basic_map_get_hash(bset_to_bmap(bset
));
10532 uint32_t isl_map_get_hash(__isl_keep isl_map
*map
)
10539 map
= isl_map_copy(map
);
10540 map
= isl_map_normalize(map
);
10544 hash
= isl_hash_init();
10545 for (i
= 0; i
< map
->n
; ++i
) {
10546 uint32_t bmap_hash
;
10547 bmap_hash
= isl_basic_map_get_hash(map
->p
[i
]);
10548 isl_hash_hash(hash
, bmap_hash
);
10556 uint32_t isl_set_get_hash(__isl_keep isl_set
*set
)
10558 return isl_map_get_hash(set_to_map(set
));
10561 /* Return the number of basic maps in the (current) representation of "map".
10563 isl_size
isl_map_n_basic_map(__isl_keep isl_map
*map
)
10565 return map
? map
->n
: isl_size_error
;
10568 isl_size
isl_set_n_basic_set(__isl_keep isl_set
*set
)
10570 return set
? set
->n
: isl_size_error
;
10573 isl_stat
isl_map_foreach_basic_map(__isl_keep isl_map
*map
,
10574 isl_stat (*fn
)(__isl_take isl_basic_map
*bmap
, void *user
), void *user
)
10579 return isl_stat_error
;
10581 for (i
= 0; i
< map
->n
; ++i
)
10582 if (fn(isl_basic_map_copy(map
->p
[i
]), user
) < 0)
10583 return isl_stat_error
;
10585 return isl_stat_ok
;
10588 isl_stat
isl_set_foreach_basic_set(__isl_keep isl_set
*set
,
10589 isl_stat (*fn
)(__isl_take isl_basic_set
*bset
, void *user
), void *user
)
10594 return isl_stat_error
;
10596 for (i
= 0; i
< set
->n
; ++i
)
10597 if (fn(isl_basic_set_copy(set
->p
[i
]), user
) < 0)
10598 return isl_stat_error
;
10600 return isl_stat_ok
;
10603 /* Return a list of basic sets, the union of which is equal to "set".
10605 __isl_give isl_basic_set_list
*isl_set_get_basic_set_list(
10606 __isl_keep isl_set
*set
)
10609 isl_basic_set_list
*list
;
10614 list
= isl_basic_set_list_alloc(isl_set_get_ctx(set
), set
->n
);
10615 for (i
= 0; i
< set
->n
; ++i
) {
10616 isl_basic_set
*bset
;
10618 bset
= isl_basic_set_copy(set
->p
[i
]);
10619 list
= isl_basic_set_list_add(list
, bset
);
10625 __isl_give isl_basic_set
*isl_basic_set_lift(__isl_take isl_basic_set
*bset
)
10632 bset
= isl_basic_set_cow(bset
);
10636 space
= isl_basic_set_get_space(bset
);
10637 space
= isl_space_lift(space
, bset
->n_div
);
10640 isl_space_free(bset
->dim
);
10642 bset
->extra
-= bset
->n_div
;
10645 bset
= isl_basic_set_finalize(bset
);
10649 isl_basic_set_free(bset
);
10653 __isl_give isl_set
*isl_set_lift(__isl_take isl_set
*set
)
10659 set
= set_from_map(isl_map_align_divs_internal(set_to_map(set
)));
10664 set
= isl_set_cow(set
);
10668 n_div
= set
->p
[0]->n_div
;
10669 space
= isl_set_get_space(set
);
10670 space
= isl_space_lift(space
, n_div
);
10673 isl_space_free(set
->dim
);
10676 for (i
= 0; i
< set
->n
; ++i
) {
10677 set
->p
[i
] = isl_basic_set_lift(set
->p
[i
]);
10688 int isl_basic_set_size(__isl_keep isl_basic_set
*bset
)
10693 dim
= isl_basic_set_dim(bset
, isl_dim_all
);
10696 size
+= bset
->n_eq
* (1 + dim
);
10697 size
+= bset
->n_ineq
* (1 + dim
);
10698 size
+= bset
->n_div
* (2 + dim
);
10703 int isl_set_size(__isl_keep isl_set
*set
)
10711 for (i
= 0; i
< set
->n
; ++i
)
10712 size
+= isl_basic_set_size(set
->p
[i
]);
10717 /* Check if there is any lower bound (if lower == 0) and/or upper
10718 * bound (if upper == 0) on the specified dim.
10720 static isl_bool
basic_map_dim_is_bounded(__isl_keep isl_basic_map
*bmap
,
10721 enum isl_dim_type type
, unsigned pos
, int lower
, int upper
)
10725 if (isl_basic_map_check_range(bmap
, type
, pos
, 1) < 0)
10726 return isl_bool_error
;
10728 pos
+= isl_basic_map_offset(bmap
, type
);
10730 for (i
= 0; i
< bmap
->n_div
; ++i
) {
10731 if (isl_int_is_zero(bmap
->div
[i
][0]))
10733 if (!isl_int_is_zero(bmap
->div
[i
][1 + pos
]))
10734 return isl_bool_true
;
10737 for (i
= 0; i
< bmap
->n_eq
; ++i
)
10738 if (!isl_int_is_zero(bmap
->eq
[i
][pos
]))
10739 return isl_bool_true
;
10741 for (i
= 0; i
< bmap
->n_ineq
; ++i
) {
10742 int sgn
= isl_int_sgn(bmap
->ineq
[i
][pos
]);
10749 return lower
&& upper
;
10752 isl_bool
isl_basic_map_dim_is_bounded(__isl_keep isl_basic_map
*bmap
,
10753 enum isl_dim_type type
, unsigned pos
)
10755 return basic_map_dim_is_bounded(bmap
, type
, pos
, 0, 0);
10758 isl_bool
isl_basic_map_dim_has_lower_bound(__isl_keep isl_basic_map
*bmap
,
10759 enum isl_dim_type type
, unsigned pos
)
10761 return basic_map_dim_is_bounded(bmap
, type
, pos
, 0, 1);
10764 isl_bool
isl_basic_map_dim_has_upper_bound(__isl_keep isl_basic_map
*bmap
,
10765 enum isl_dim_type type
, unsigned pos
)
10767 return basic_map_dim_is_bounded(bmap
, type
, pos
, 1, 0);
10770 isl_bool
isl_map_dim_is_bounded(__isl_keep isl_map
*map
,
10771 enum isl_dim_type type
, unsigned pos
)
10776 return isl_bool_error
;
10778 for (i
= 0; i
< map
->n
; ++i
) {
10780 bounded
= isl_basic_map_dim_is_bounded(map
->p
[i
], type
, pos
);
10781 if (bounded
< 0 || !bounded
)
10785 return isl_bool_true
;
10788 /* Return true if the specified dim is involved in both an upper bound
10789 * and a lower bound.
10791 isl_bool
isl_set_dim_is_bounded(__isl_keep isl_set
*set
,
10792 enum isl_dim_type type
, unsigned pos
)
10794 return isl_map_dim_is_bounded(set_to_map(set
), type
, pos
);
10797 /* Does "map" have a bound (according to "fn") for any of its basic maps?
10799 static isl_bool
has_any_bound(__isl_keep isl_map
*map
,
10800 enum isl_dim_type type
, unsigned pos
,
10801 isl_bool (*fn
)(__isl_keep isl_basic_map
*bmap
,
10802 enum isl_dim_type type
, unsigned pos
))
10807 return isl_bool_error
;
10809 for (i
= 0; i
< map
->n
; ++i
) {
10811 bounded
= fn(map
->p
[i
], type
, pos
);
10812 if (bounded
< 0 || bounded
)
10816 return isl_bool_false
;
10819 /* Return 1 if the specified dim is involved in any lower bound.
10821 isl_bool
isl_set_dim_has_any_lower_bound(__isl_keep isl_set
*set
,
10822 enum isl_dim_type type
, unsigned pos
)
10824 return has_any_bound(set
, type
, pos
,
10825 &isl_basic_map_dim_has_lower_bound
);
10828 /* Return 1 if the specified dim is involved in any upper bound.
10830 isl_bool
isl_set_dim_has_any_upper_bound(__isl_keep isl_set
*set
,
10831 enum isl_dim_type type
, unsigned pos
)
10833 return has_any_bound(set
, type
, pos
,
10834 &isl_basic_map_dim_has_upper_bound
);
10837 /* Does "map" have a bound (according to "fn") for all of its basic maps?
10839 static isl_bool
has_bound(__isl_keep isl_map
*map
,
10840 enum isl_dim_type type
, unsigned pos
,
10841 isl_bool (*fn
)(__isl_keep isl_basic_map
*bmap
,
10842 enum isl_dim_type type
, unsigned pos
))
10847 return isl_bool_error
;
10849 for (i
= 0; i
< map
->n
; ++i
) {
10851 bounded
= fn(map
->p
[i
], type
, pos
);
10852 if (bounded
< 0 || !bounded
)
10856 return isl_bool_true
;
10859 /* Return 1 if the specified dim has a lower bound (in each of its basic sets).
10861 isl_bool
isl_set_dim_has_lower_bound(__isl_keep isl_set
*set
,
10862 enum isl_dim_type type
, unsigned pos
)
10864 return has_bound(set
, type
, pos
, &isl_basic_map_dim_has_lower_bound
);
10867 /* Return 1 if the specified dim has an upper bound (in each of its basic sets).
10869 isl_bool
isl_set_dim_has_upper_bound(__isl_keep isl_set
*set
,
10870 enum isl_dim_type type
, unsigned pos
)
10872 return has_bound(set
, type
, pos
, &isl_basic_map_dim_has_upper_bound
);
10875 /* For each of the "n" variables starting at "first", determine
10876 * the sign of the variable and put the results in the first "n"
10877 * elements of the array "signs".
10879 * 1 means that the variable is non-negative
10880 * -1 means that the variable is non-positive
10881 * 0 means the variable attains both positive and negative values.
10883 isl_stat
isl_basic_set_vars_get_sign(__isl_keep isl_basic_set
*bset
,
10884 unsigned first
, unsigned n
, int *signs
)
10886 isl_vec
*bound
= NULL
;
10887 struct isl_tab
*tab
= NULL
;
10888 struct isl_tab_undo
*snap
;
10892 total
= isl_basic_set_dim(bset
, isl_dim_all
);
10893 if (total
< 0 || !signs
)
10894 return isl_stat_error
;
10896 bound
= isl_vec_alloc(bset
->ctx
, 1 + total
);
10897 tab
= isl_tab_from_basic_set(bset
, 0);
10898 if (!bound
|| !tab
)
10901 isl_seq_clr(bound
->el
, bound
->size
);
10902 isl_int_set_si(bound
->el
[0], -1);
10904 snap
= isl_tab_snap(tab
);
10905 for (i
= 0; i
< n
; ++i
) {
10908 isl_int_set_si(bound
->el
[1 + first
+ i
], -1);
10909 if (isl_tab_add_ineq(tab
, bound
->el
) < 0)
10911 empty
= tab
->empty
;
10912 isl_int_set_si(bound
->el
[1 + first
+ i
], 0);
10913 if (isl_tab_rollback(tab
, snap
) < 0)
10921 isl_int_set_si(bound
->el
[1 + first
+ i
], 1);
10922 if (isl_tab_add_ineq(tab
, bound
->el
) < 0)
10924 empty
= tab
->empty
;
10925 isl_int_set_si(bound
->el
[1 + first
+ i
], 0);
10926 if (isl_tab_rollback(tab
, snap
) < 0)
10929 signs
[i
] = empty
? -1 : 0;
10933 isl_vec_free(bound
);
10934 return isl_stat_ok
;
10937 isl_vec_free(bound
);
10938 return isl_stat_error
;
10941 isl_stat
isl_basic_set_dims_get_sign(__isl_keep isl_basic_set
*bset
,
10942 enum isl_dim_type type
, unsigned first
, unsigned n
, int *signs
)
10944 if (!bset
|| !signs
)
10945 return isl_stat_error
;
10946 if (isl_basic_set_check_range(bset
, type
, first
, n
) < 0)
10947 return isl_stat_error
;
10949 first
+= pos(bset
->dim
, type
) - 1;
10950 return isl_basic_set_vars_get_sign(bset
, first
, n
, signs
);
10953 /* Is it possible for the integer division "div" to depend (possibly
10954 * indirectly) on any output dimensions?
10956 * If the div is undefined, then we conservatively assume that it
10957 * may depend on them.
10958 * Otherwise, we check if it actually depends on them or on any integer
10959 * divisions that may depend on them.
10961 static isl_bool
div_may_involve_output(__isl_keep isl_basic_map
*bmap
, int div
)
10964 isl_size n_out
, n_div
;
10965 unsigned o_out
, o_div
;
10967 if (isl_int_is_zero(bmap
->div
[div
][0]))
10968 return isl_bool_true
;
10970 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
10972 return isl_bool_error
;
10973 o_out
= isl_basic_map_offset(bmap
, isl_dim_out
);
10975 if (isl_seq_first_non_zero(bmap
->div
[div
] + 1 + o_out
, n_out
) != -1)
10976 return isl_bool_true
;
10978 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
10980 return isl_bool_error
;
10981 o_div
= isl_basic_map_offset(bmap
, isl_dim_div
);
10983 for (i
= 0; i
< n_div
; ++i
) {
10984 isl_bool may_involve
;
10986 if (isl_int_is_zero(bmap
->div
[div
][1 + o_div
+ i
]))
10988 may_involve
= div_may_involve_output(bmap
, i
);
10989 if (may_involve
< 0 || may_involve
)
10990 return may_involve
;
10993 return isl_bool_false
;
10996 /* Return the first integer division of "bmap" in the range
10997 * [first, first + n[ that may depend on any output dimensions and
10998 * that has a non-zero coefficient in "c" (where the first coefficient
10999 * in "c" corresponds to integer division "first").
11001 static int first_div_may_involve_output(__isl_keep isl_basic_map
*bmap
,
11002 isl_int
*c
, int first
, int n
)
11009 for (k
= first
; k
< first
+ n
; ++k
) {
11010 isl_bool may_involve
;
11012 if (isl_int_is_zero(c
[k
]))
11014 may_involve
= div_may_involve_output(bmap
, k
);
11015 if (may_involve
< 0)
11024 /* Look for a pair of inequality constraints in "bmap" of the form
11026 * -l + i >= 0 or i >= l
11028 * n + l - i >= 0 or i <= l + n
11030 * with n < "m" and i the output dimension at position "pos".
11031 * (Note that n >= 0 as otherwise the two constraints would conflict.)
11032 * Furthermore, "l" is only allowed to involve parameters, input dimensions
11033 * and earlier output dimensions, as well as integer divisions that do
11034 * not involve any of the output dimensions.
11036 * Return the index of the first inequality constraint or bmap->n_ineq
11037 * if no such pair can be found.
11039 static int find_modulo_constraint_pair(__isl_keep isl_basic_map
*bmap
,
11040 int pos
, isl_int m
)
11045 isl_size n_div
, n_out
;
11046 unsigned o_div
, o_out
;
11049 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
11050 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
11051 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
11052 if (total
< 0 || n_out
< 0 || n_div
< 0)
11055 ctx
= isl_basic_map_get_ctx(bmap
);
11056 o_out
= isl_basic_map_offset(bmap
, isl_dim_out
);
11057 o_div
= isl_basic_map_offset(bmap
, isl_dim_div
);
11058 for (i
= 0; i
< bmap
->n_ineq
; ++i
) {
11059 if (!isl_int_abs_eq(bmap
->ineq
[i
][o_out
+ pos
], ctx
->one
))
11061 if (isl_seq_first_non_zero(bmap
->ineq
[i
] + o_out
+ pos
+ 1,
11062 n_out
- (pos
+ 1)) != -1)
11064 if (first_div_may_involve_output(bmap
, bmap
->ineq
[i
] + o_div
,
11067 for (j
= i
+ 1; j
< bmap
->n_ineq
; ++j
) {
11068 if (!isl_int_abs_eq(bmap
->ineq
[j
][o_out
+ pos
],
11071 if (!isl_seq_is_neg(bmap
->ineq
[i
] + 1,
11072 bmap
->ineq
[j
] + 1, total
))
11076 if (j
>= bmap
->n_ineq
)
11078 isl_int_add(bmap
->ineq
[i
][0],
11079 bmap
->ineq
[i
][0], bmap
->ineq
[j
][0]);
11080 less
= isl_int_abs_lt(bmap
->ineq
[i
][0], m
);
11081 isl_int_sub(bmap
->ineq
[i
][0],
11082 bmap
->ineq
[i
][0], bmap
->ineq
[j
][0]);
11085 if (isl_int_is_one(bmap
->ineq
[i
][o_out
+ pos
]))
11091 return bmap
->n_ineq
;
11094 /* Return the index of the equality of "bmap" that defines
11095 * the output dimension "pos" in terms of earlier dimensions.
11096 * The equality may also involve integer divisions, as long
11097 * as those integer divisions are defined in terms of
11098 * parameters or input dimensions.
11099 * In this case, *div is set to the number of integer divisions and
11100 * *ineq is set to the number of inequality constraints (provided
11101 * div and ineq are not NULL).
11103 * The equality may also involve a single integer division involving
11104 * the output dimensions (typically only output dimension "pos") as
11105 * long as the coefficient of output dimension "pos" is 1 or -1 and
11106 * there is a pair of constraints i >= l and i <= l + n, with i referring
11107 * to output dimension "pos", l an expression involving only earlier
11108 * dimensions and n smaller than the coefficient of the integer division
11109 * in the equality. In this case, the output dimension can be defined
11110 * in terms of a modulo expression that does not involve the integer division.
11111 * *div is then set to this single integer division and
11112 * *ineq is set to the index of constraint i >= l.
11114 * Return bmap->n_eq if there is no such equality.
11115 * Return -1 on error.
11117 int isl_basic_map_output_defining_equality(__isl_keep isl_basic_map
*bmap
,
11118 int pos
, int *div
, int *ineq
)
11121 isl_size n_div
, n_out
;
11122 unsigned o_div
, o_out
;
11124 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
11125 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
11126 if (n_out
< 0 || n_div
< 0)
11129 o_out
= isl_basic_map_offset(bmap
, isl_dim_out
);
11130 o_div
= isl_basic_map_offset(bmap
, isl_dim_div
);
11133 *ineq
= bmap
->n_ineq
;
11136 for (j
= 0; j
< bmap
->n_eq
; ++j
) {
11137 if (isl_int_is_zero(bmap
->eq
[j
][o_out
+ pos
]))
11139 if (isl_seq_first_non_zero(bmap
->eq
[j
] + o_out
+ pos
+ 1,
11140 n_out
- (pos
+ 1)) != -1)
11142 k
= first_div_may_involve_output(bmap
, bmap
->eq
[j
] + o_div
,
11146 if (!isl_int_is_one(bmap
->eq
[j
][o_out
+ pos
]) &&
11147 !isl_int_is_negone(bmap
->eq
[j
][o_out
+ pos
]))
11149 if (first_div_may_involve_output(bmap
, bmap
->eq
[j
] + o_div
,
11150 k
+ 1, n_div
- (k
+1)) < n_div
)
11152 l
= find_modulo_constraint_pair(bmap
, pos
,
11153 bmap
->eq
[j
][o_div
+ k
]);
11156 if (l
>= bmap
->n_ineq
)
11168 /* Check if the given basic map is obviously single-valued.
11169 * In particular, for each output dimension, check that there is
11170 * an equality that defines the output dimension in terms of
11171 * earlier dimensions.
11173 isl_bool
isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map
*bmap
)
11178 n_out
= isl_basic_map_dim(bmap
, isl_dim_out
);
11180 return isl_bool_error
;
11182 for (i
= 0; i
< n_out
; ++i
) {
11185 eq
= isl_basic_map_output_defining_equality(bmap
, i
,
11188 return isl_bool_error
;
11189 if (eq
>= bmap
->n_eq
)
11190 return isl_bool_false
;
11193 return isl_bool_true
;
11196 /* Check if the given basic map is single-valued.
11197 * We simply compute
11201 * and check if the result is a subset of the identity mapping.
11203 isl_bool
isl_basic_map_is_single_valued(__isl_keep isl_basic_map
*bmap
)
11206 isl_basic_map
*test
;
11210 sv
= isl_basic_map_plain_is_single_valued(bmap
);
11214 test
= isl_basic_map_reverse(isl_basic_map_copy(bmap
));
11215 test
= isl_basic_map_apply_range(test
, isl_basic_map_copy(bmap
));
11217 space
= isl_basic_map_get_space(bmap
);
11218 space
= isl_space_map_from_set(isl_space_range(space
));
11219 id
= isl_basic_map_identity(space
);
11221 sv
= isl_basic_map_is_subset(test
, id
);
11223 isl_basic_map_free(test
);
11224 isl_basic_map_free(id
);
11229 /* Check if the given map is obviously single-valued.
11231 isl_bool
isl_map_plain_is_single_valued(__isl_keep isl_map
*map
)
11234 return isl_bool_error
;
11236 return isl_bool_true
;
11238 return isl_bool_false
;
11240 return isl_basic_map_plain_is_single_valued(map
->p
[0]);
11243 /* Check if the given map is single-valued.
11244 * We simply compute
11248 * and check if the result is a subset of the identity mapping.
11250 isl_bool
isl_map_is_single_valued(__isl_keep isl_map
*map
)
11257 sv
= isl_map_plain_is_single_valued(map
);
11261 test
= isl_map_reverse(isl_map_copy(map
));
11262 test
= isl_map_apply_range(test
, isl_map_copy(map
));
11264 dim
= isl_space_map_from_set(isl_space_range(isl_map_get_space(map
)));
11265 id
= isl_map_identity(dim
);
11267 sv
= isl_map_is_subset(test
, id
);
11269 isl_map_free(test
);
11275 isl_bool
isl_map_is_injective(__isl_keep isl_map
*map
)
11279 map
= isl_map_copy(map
);
11280 map
= isl_map_reverse(map
);
11281 in
= isl_map_is_single_valued(map
);
11287 /* Check if the given map is obviously injective.
11289 isl_bool
isl_map_plain_is_injective(__isl_keep isl_map
*map
)
11293 map
= isl_map_copy(map
);
11294 map
= isl_map_reverse(map
);
11295 in
= isl_map_plain_is_single_valued(map
);
11301 isl_bool
isl_map_is_bijective(__isl_keep isl_map
*map
)
11305 sv
= isl_map_is_single_valued(map
);
11309 return isl_map_is_injective(map
);
11312 isl_bool
isl_set_is_singleton(__isl_keep isl_set
*set
)
11314 return isl_map_is_single_valued(set_to_map(set
));
11317 /* Does "map" only map elements to themselves?
11319 * If the domain and range spaces are different, then "map"
11320 * is considered not to be an identity relation, even if it is empty.
11321 * Otherwise, construct the maximal identity relation and
11322 * check whether "map" is a subset of this relation.
11324 isl_bool
isl_map_is_identity(__isl_keep isl_map
*map
)
11328 isl_bool equal
, is_identity
;
11330 space
= isl_map_get_space(map
);
11331 equal
= isl_space_tuple_is_equal(space
, isl_dim_in
, space
, isl_dim_out
);
11332 isl_space_free(space
);
11333 if (equal
< 0 || !equal
)
11336 id
= isl_map_identity(isl_map_get_space(map
));
11337 is_identity
= isl_map_is_subset(map
, id
);
11340 return is_identity
;
11343 int isl_map_is_translation(__isl_keep isl_map
*map
)
11348 delta
= isl_map_deltas(isl_map_copy(map
));
11349 ok
= isl_set_is_singleton(delta
);
11350 isl_set_free(delta
);
11355 static int unique(isl_int
*p
, unsigned pos
, unsigned len
)
11357 if (isl_seq_first_non_zero(p
, pos
) != -1)
11359 if (isl_seq_first_non_zero(p
+ pos
+ 1, len
- pos
- 1) != -1)
11364 isl_bool
isl_basic_set_is_box(__isl_keep isl_basic_set
*bset
)
11367 isl_size nvar
, n_div
;
11370 n_div
= isl_basic_set_dim(bset
, isl_dim_div
);
11372 return isl_bool_error
;
11374 return isl_bool_false
;
11376 nvar
= isl_basic_set_dim(bset
, isl_dim_set
);
11378 return isl_bool_error
;
11379 ovar
= isl_space_offset(bset
->dim
, isl_dim_set
);
11380 for (j
= 0; j
< nvar
; ++j
) {
11381 int lower
= 0, upper
= 0;
11382 for (i
= 0; i
< bset
->n_eq
; ++i
) {
11383 if (isl_int_is_zero(bset
->eq
[i
][1 + ovar
+ j
]))
11385 if (!unique(bset
->eq
[i
] + 1 + ovar
, j
, nvar
))
11386 return isl_bool_false
;
11389 if (i
< bset
->n_eq
)
11391 for (i
= 0; i
< bset
->n_ineq
; ++i
) {
11392 if (isl_int_is_zero(bset
->ineq
[i
][1 + ovar
+ j
]))
11394 if (!unique(bset
->ineq
[i
] + 1 + ovar
, j
, nvar
))
11395 return isl_bool_false
;
11396 if (isl_int_is_pos(bset
->ineq
[i
][1 + ovar
+ j
]))
11401 if (!lower
|| !upper
)
11402 return isl_bool_false
;
11405 return isl_bool_true
;
11408 isl_bool
isl_set_is_box(__isl_keep isl_set
*set
)
11411 return isl_bool_error
;
11413 return isl_bool_false
;
11415 return isl_basic_set_is_box(set
->p
[0]);
11418 isl_bool
isl_basic_set_is_wrapping(__isl_keep isl_basic_set
*bset
)
11421 return isl_bool_error
;
11423 return isl_space_is_wrapping(bset
->dim
);
11426 isl_bool
isl_set_is_wrapping(__isl_keep isl_set
*set
)
11429 return isl_bool_error
;
11431 return isl_space_is_wrapping(set
->dim
);
11434 /* Modify the space of "map" through a call to "change".
11435 * If "can_change" is set (not NULL), then first call it to check
11436 * if the modification is allowed, printing the error message "cannot_change"
11439 static __isl_give isl_map
*isl_map_change_space(__isl_take isl_map
*map
,
11440 isl_bool (*can_change
)(__isl_keep isl_map
*map
),
11441 const char *cannot_change
,
11442 __isl_give isl_space
*(*change
)(__isl_take isl_space
*space
))
11450 ok
= can_change
? can_change(map
) : isl_bool_true
;
11452 return isl_map_free(map
);
11454 isl_die(isl_map_get_ctx(map
), isl_error_invalid
, cannot_change
,
11455 return isl_map_free(map
));
11457 space
= change(isl_map_get_space(map
));
11458 map
= isl_map_reset_space(map
, space
);
11463 /* Is the domain of "map" a wrapped relation?
11465 isl_bool
isl_map_domain_is_wrapping(__isl_keep isl_map
*map
)
11468 return isl_bool_error
;
11470 return isl_space_domain_is_wrapping(map
->dim
);
11473 /* Does "map" have a wrapped relation in both domain and range?
11475 isl_bool
isl_map_is_product(__isl_keep isl_map
*map
)
11477 return isl_space_is_product(isl_map_peek_space(map
));
11480 /* Is the range of "map" a wrapped relation?
11482 isl_bool
isl_map_range_is_wrapping(__isl_keep isl_map
*map
)
11485 return isl_bool_error
;
11487 return isl_space_range_is_wrapping(map
->dim
);
11490 __isl_give isl_basic_set
*isl_basic_map_wrap(__isl_take isl_basic_map
*bmap
)
11492 bmap
= isl_basic_map_cow(bmap
);
11496 bmap
->dim
= isl_space_wrap(bmap
->dim
);
11500 bmap
= isl_basic_map_finalize(bmap
);
11502 return bset_from_bmap(bmap
);
11504 isl_basic_map_free(bmap
);
11508 /* Given a map A -> B, return the set (A -> B).
11510 __isl_give isl_set
*isl_map_wrap(__isl_take isl_map
*map
)
11512 return isl_map_change_space(map
, NULL
, NULL
, &isl_space_wrap
);
11515 __isl_give isl_basic_map
*isl_basic_set_unwrap(__isl_take isl_basic_set
*bset
)
11517 bset
= isl_basic_set_cow(bset
);
11521 bset
->dim
= isl_space_unwrap(bset
->dim
);
11525 bset
= isl_basic_set_finalize(bset
);
11527 return bset_to_bmap(bset
);
11529 isl_basic_set_free(bset
);
11533 /* Given a set (A -> B), return the map A -> B.
11534 * Error out if "set" is not of the form (A -> B).
11536 __isl_give isl_map
*isl_set_unwrap(__isl_take isl_set
*set
)
11538 return isl_map_change_space(set
, &isl_set_is_wrapping
,
11539 "not a wrapping set", &isl_space_unwrap
);
11542 __isl_give isl_basic_map
*isl_basic_map_reset(__isl_take isl_basic_map
*bmap
,
11543 enum isl_dim_type type
)
11548 if (!isl_space_is_named_or_nested(bmap
->dim
, type
))
11551 bmap
= isl_basic_map_cow(bmap
);
11555 bmap
->dim
= isl_space_reset(bmap
->dim
, type
);
11559 bmap
= isl_basic_map_finalize(bmap
);
11563 isl_basic_map_free(bmap
);
11567 __isl_give isl_map
*isl_map_reset(__isl_take isl_map
*map
,
11568 enum isl_dim_type type
)
11575 if (!isl_space_is_named_or_nested(map
->dim
, type
))
11578 map
= isl_map_cow(map
);
11582 for (i
= 0; i
< map
->n
; ++i
) {
11583 map
->p
[i
] = isl_basic_map_reset(map
->p
[i
], type
);
11587 map
->dim
= isl_space_reset(map
->dim
, type
);
11597 __isl_give isl_basic_map
*isl_basic_map_flatten(__isl_take isl_basic_map
*bmap
)
11602 if (!bmap
->dim
->nested
[0] && !bmap
->dim
->nested
[1])
11605 bmap
= isl_basic_map_cow(bmap
);
11609 bmap
->dim
= isl_space_flatten(bmap
->dim
);
11613 bmap
= isl_basic_map_finalize(bmap
);
11617 isl_basic_map_free(bmap
);
11621 __isl_give isl_basic_set
*isl_basic_set_flatten(__isl_take isl_basic_set
*bset
)
11623 return bset_from_bmap(isl_basic_map_flatten(bset_to_bmap(bset
)));
11626 __isl_give isl_basic_map
*isl_basic_map_flatten_domain(
11627 __isl_take isl_basic_map
*bmap
)
11632 if (!bmap
->dim
->nested
[0])
11635 bmap
= isl_basic_map_cow(bmap
);
11639 bmap
->dim
= isl_space_flatten_domain(bmap
->dim
);
11643 bmap
= isl_basic_map_finalize(bmap
);
11647 isl_basic_map_free(bmap
);
11651 __isl_give isl_basic_map
*isl_basic_map_flatten_range(
11652 __isl_take isl_basic_map
*bmap
)
11657 if (!bmap
->dim
->nested
[1])
11660 bmap
= isl_basic_map_cow(bmap
);
11664 bmap
->dim
= isl_space_flatten_range(bmap
->dim
);
11668 bmap
= isl_basic_map_finalize(bmap
);
11672 isl_basic_map_free(bmap
);
11676 /* Remove any internal structure from the spaces of domain and range of "map".
11678 __isl_give isl_map
*isl_map_flatten(__isl_take isl_map
*map
)
11683 if (!map
->dim
->nested
[0] && !map
->dim
->nested
[1])
11686 return isl_map_change_space(map
, NULL
, NULL
, &isl_space_flatten
);
11689 __isl_give isl_set
*isl_set_flatten(__isl_take isl_set
*set
)
11691 return set_from_map(isl_map_flatten(set_to_map(set
)));
11694 __isl_give isl_map
*isl_set_flatten_map(__isl_take isl_set
*set
)
11696 isl_space
*space
, *flat_space
;
11699 space
= isl_set_get_space(set
);
11700 flat_space
= isl_space_flatten(isl_space_copy(space
));
11701 map
= isl_map_identity(isl_space_join(isl_space_reverse(space
),
11703 map
= isl_map_intersect_domain(map
, set
);
11708 /* Remove any internal structure from the space of the domain of "map".
11710 __isl_give isl_map
*isl_map_flatten_domain(__isl_take isl_map
*map
)
11715 if (!map
->dim
->nested
[0])
11718 return isl_map_change_space(map
, NULL
, NULL
, &isl_space_flatten_domain
);
11721 /* Remove any internal structure from the space of the range of "map".
11723 __isl_give isl_map
*isl_map_flatten_range(__isl_take isl_map
*map
)
11728 if (!map
->dim
->nested
[1])
11731 return isl_map_change_space(map
, NULL
, NULL
, &isl_space_flatten_range
);
11734 /* Reorder the dimensions of "bmap" according to the given dim_map
11735 * and set the dimension specification to "space" and
11736 * perform Gaussian elimination on the result.
11738 __isl_give isl_basic_map
*isl_basic_map_realign(__isl_take isl_basic_map
*bmap
,
11739 __isl_take isl_space
*space
, __isl_take
struct isl_dim_map
*dim_map
)
11741 isl_basic_map
*res
;
11745 n_div
= isl_basic_map_dim(bmap
, isl_dim_div
);
11746 if (n_div
< 0 || !space
|| !dim_map
)
11749 flags
= bmap
->flags
;
11750 ISL_FL_CLR(flags
, ISL_BASIC_MAP_FINAL
);
11751 ISL_FL_CLR(flags
, ISL_BASIC_MAP_SORTED
);
11752 ISL_FL_CLR(flags
, ISL_BASIC_MAP_NORMALIZED_DIVS
);
11753 res
= isl_basic_map_alloc_space(space
, n_div
, bmap
->n_eq
, bmap
->n_ineq
);
11754 res
= isl_basic_map_add_constraints_dim_map(res
, bmap
, dim_map
);
11756 res
->flags
= flags
;
11757 res
= isl_basic_map_gauss(res
, NULL
);
11758 res
= isl_basic_map_finalize(res
);
11761 isl_dim_map_free(dim_map
);
11762 isl_basic_map_free(bmap
);
11763 isl_space_free(space
);
11767 /* Reorder the dimensions of "map" according to given reordering.
11769 __isl_give isl_map
*isl_map_realign(__isl_take isl_map
*map
,
11770 __isl_take isl_reordering
*r
)
11773 struct isl_dim_map
*dim_map
;
11775 map
= isl_map_cow(map
);
11776 dim_map
= isl_dim_map_from_reordering(r
);
11777 if (!map
|| !r
|| !dim_map
)
11780 for (i
= 0; i
< map
->n
; ++i
) {
11781 struct isl_dim_map
*dim_map_i
;
11784 dim_map_i
= isl_dim_map_extend(dim_map
, map
->p
[i
]);
11786 space
= isl_reordering_get_space(r
);
11787 map
->p
[i
] = isl_basic_map_realign(map
->p
[i
], space
, dim_map_i
);
11793 map
= isl_map_reset_space(map
, isl_reordering_get_space(r
));
11794 map
= isl_map_unmark_normalized(map
);
11796 isl_reordering_free(r
);
11797 isl_dim_map_free(dim_map
);
11800 isl_dim_map_free(dim_map
);
11802 isl_reordering_free(r
);
11806 __isl_give isl_set
*isl_set_realign(__isl_take isl_set
*set
,
11807 __isl_take isl_reordering
*r
)
11809 return set_from_map(isl_map_realign(set_to_map(set
), r
));
11812 __isl_give isl_map
*isl_map_align_params(__isl_take isl_map
*map
,
11813 __isl_take isl_space
*model
)
11818 if (!map
|| !model
)
11821 ctx
= isl_space_get_ctx(model
);
11822 if (!isl_space_has_named_params(model
))
11823 isl_die(ctx
, isl_error_invalid
,
11824 "model has unnamed parameters", goto error
);
11825 if (isl_map_check_named_params(map
) < 0)
11827 aligned
= isl_map_space_has_equal_params(map
, model
);
11831 isl_reordering
*exp
;
11833 exp
= isl_parameter_alignment_reordering(map
->dim
, model
);
11834 exp
= isl_reordering_extend_space(exp
, isl_map_get_space(map
));
11835 map
= isl_map_realign(map
, exp
);
11838 isl_space_free(model
);
11841 isl_space_free(model
);
11846 __isl_give isl_set
*isl_set_align_params(__isl_take isl_set
*set
,
11847 __isl_take isl_space
*model
)
11849 return isl_map_align_params(set
, model
);
11852 /* Align the parameters of "bmap" to those of "model", introducing
11853 * additional parameters if needed.
11855 __isl_give isl_basic_map
*isl_basic_map_align_params(
11856 __isl_take isl_basic_map
*bmap
, __isl_take isl_space
*model
)
11859 isl_bool equal_params
;
11861 if (!bmap
|| !model
)
11864 ctx
= isl_space_get_ctx(model
);
11865 if (!isl_space_has_named_params(model
))
11866 isl_die(ctx
, isl_error_invalid
,
11867 "model has unnamed parameters", goto error
);
11868 if (isl_basic_map_check_named_params(bmap
) < 0)
11870 equal_params
= isl_space_has_equal_params(bmap
->dim
, model
);
11871 if (equal_params
< 0)
11873 if (!equal_params
) {
11874 isl_reordering
*exp
;
11875 struct isl_dim_map
*dim_map
;
11877 exp
= isl_parameter_alignment_reordering(bmap
->dim
, model
);
11878 exp
= isl_reordering_extend_space(exp
,
11879 isl_basic_map_get_space(bmap
));
11880 dim_map
= isl_dim_map_from_reordering(exp
);
11881 bmap
= isl_basic_map_realign(bmap
,
11882 isl_reordering_get_space(exp
),
11883 isl_dim_map_extend(dim_map
, bmap
));
11884 isl_reordering_free(exp
);
11885 isl_dim_map_free(dim_map
);
11888 isl_space_free(model
);
11891 isl_space_free(model
);
11892 isl_basic_map_free(bmap
);
11896 /* Do "bset" and "space" have the same parameters?
11898 isl_bool
isl_basic_set_space_has_equal_params(__isl_keep isl_basic_set
*bset
,
11899 __isl_keep isl_space
*space
)
11901 isl_space
*bset_space
;
11903 bset_space
= isl_basic_set_peek_space(bset
);
11904 return isl_space_has_equal_params(bset_space
, space
);
11907 /* Do "map" and "space" have the same parameters?
11909 isl_bool
isl_map_space_has_equal_params(__isl_keep isl_map
*map
,
11910 __isl_keep isl_space
*space
)
11912 isl_space
*map_space
;
11914 map_space
= isl_map_peek_space(map
);
11915 return isl_space_has_equal_params(map_space
, space
);
11918 /* Do "set" and "space" have the same parameters?
11920 isl_bool
isl_set_space_has_equal_params(__isl_keep isl_set
*set
,
11921 __isl_keep isl_space
*space
)
11923 return isl_map_space_has_equal_params(set_to_map(set
), space
);
11926 /* Align the parameters of "bset" to those of "model", introducing
11927 * additional parameters if needed.
11929 __isl_give isl_basic_set
*isl_basic_set_align_params(
11930 __isl_take isl_basic_set
*bset
, __isl_take isl_space
*model
)
11932 return isl_basic_map_align_params(bset
, model
);
11935 /* Drop all parameters not referenced by "map".
11937 __isl_give isl_map
*isl_map_drop_unused_params(__isl_take isl_map
*map
)
11942 n
= isl_map_dim(map
, isl_dim_param
);
11943 if (isl_map_check_named_params(map
) < 0 || n
< 0)
11944 return isl_map_free(map
);
11946 for (i
= n
- 1; i
>= 0; i
--) {
11949 involves
= isl_map_involves_dims(map
, isl_dim_param
, i
, 1);
11951 return isl_map_free(map
);
11953 map
= isl_map_project_out(map
, isl_dim_param
, i
, 1);
11959 /* Drop all parameters not referenced by "set".
11961 __isl_give isl_set
*isl_set_drop_unused_params(
11962 __isl_take isl_set
*set
)
11964 return set_from_map(isl_map_drop_unused_params(set_to_map(set
)));
11967 /* Drop all parameters not referenced by "bmap".
11969 __isl_give isl_basic_map
*isl_basic_map_drop_unused_params(
11970 __isl_take isl_basic_map
*bmap
)
11975 nparam
= isl_basic_map_dim(bmap
, isl_dim_param
);
11976 if (nparam
< 0 || isl_basic_map_check_named_params(bmap
) < 0)
11977 return isl_basic_map_free(bmap
);
11979 for (i
= nparam
- 1; i
>= 0; i
--) {
11982 involves
= isl_basic_map_involves_dims(bmap
,
11983 isl_dim_param
, i
, 1);
11985 return isl_basic_map_free(bmap
);
11987 bmap
= isl_basic_map_drop(bmap
, isl_dim_param
, i
, 1);
11993 /* Drop all parameters not referenced by "bset".
11995 __isl_give isl_basic_set
*isl_basic_set_drop_unused_params(
11996 __isl_take isl_basic_set
*bset
)
11998 return bset_from_bmap(isl_basic_map_drop_unused_params(
11999 bset_to_bmap(bset
)));
12002 __isl_give isl_mat
*isl_basic_map_equalities_matrix(
12003 __isl_keep isl_basic_map
*bmap
, enum isl_dim_type c1
,
12004 enum isl_dim_type c2
, enum isl_dim_type c3
,
12005 enum isl_dim_type c4
, enum isl_dim_type c5
)
12007 enum isl_dim_type c
[5] = { c1
, c2
, c3
, c4
, c5
};
12008 struct isl_mat
*mat
;
12013 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
12016 mat
= isl_mat_alloc(bmap
->ctx
, bmap
->n_eq
, total
+ 1);
12019 for (i
= 0; i
< bmap
->n_eq
; ++i
)
12020 for (j
= 0, pos
= 0; j
< 5; ++j
) {
12021 int off
= isl_basic_map_offset(bmap
, c
[j
]);
12022 isl_size dim
= isl_basic_map_dim(bmap
, c
[j
]);
12024 return isl_mat_free(mat
);
12025 for (k
= 0; k
< dim
; ++k
) {
12026 isl_int_set(mat
->row
[i
][pos
],
12027 bmap
->eq
[i
][off
+ k
]);
12035 __isl_give isl_mat
*isl_basic_map_inequalities_matrix(
12036 __isl_keep isl_basic_map
*bmap
, enum isl_dim_type c1
,
12037 enum isl_dim_type c2
, enum isl_dim_type c3
,
12038 enum isl_dim_type c4
, enum isl_dim_type c5
)
12040 enum isl_dim_type c
[5] = { c1
, c2
, c3
, c4
, c5
};
12041 struct isl_mat
*mat
;
12046 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
12049 mat
= isl_mat_alloc(bmap
->ctx
, bmap
->n_ineq
, total
+ 1);
12052 for (i
= 0; i
< bmap
->n_ineq
; ++i
)
12053 for (j
= 0, pos
= 0; j
< 5; ++j
) {
12054 int off
= isl_basic_map_offset(bmap
, c
[j
]);
12055 isl_size dim
= isl_basic_map_dim(bmap
, c
[j
]);
12057 return isl_mat_free(mat
);
12058 for (k
= 0; k
< dim
; ++k
) {
12059 isl_int_set(mat
->row
[i
][pos
],
12060 bmap
->ineq
[i
][off
+ k
]);
12068 __isl_give isl_basic_map
*isl_basic_map_from_constraint_matrices(
12069 __isl_take isl_space
*space
,
12070 __isl_take isl_mat
*eq
, __isl_take isl_mat
*ineq
, enum isl_dim_type c1
,
12071 enum isl_dim_type c2
, enum isl_dim_type c3
,
12072 enum isl_dim_type c4
, enum isl_dim_type c5
)
12074 enum isl_dim_type c
[5] = { c1
, c2
, c3
, c4
, c5
};
12075 isl_basic_map
*bmap
= NULL
;
12082 dim
= isl_space_dim(space
, isl_dim_all
);
12083 if (dim
< 0 || !eq
|| !ineq
)
12086 if (eq
->n_col
!= ineq
->n_col
)
12087 isl_die(space
->ctx
, isl_error_invalid
,
12088 "equalities and inequalities matrices should have "
12089 "same number of columns", goto error
);
12093 if (eq
->n_col
< total
)
12094 isl_die(space
->ctx
, isl_error_invalid
,
12095 "number of columns too small", goto error
);
12097 extra
= eq
->n_col
- total
;
12099 bmap
= isl_basic_map_alloc_space(isl_space_copy(space
), extra
,
12100 eq
->n_row
, ineq
->n_row
);
12103 for (i
= 0; i
< extra
; ++i
) {
12104 k
= isl_basic_map_alloc_div(bmap
);
12107 isl_int_set_si(bmap
->div
[k
][0], 0);
12109 for (i
= 0; i
< eq
->n_row
; ++i
) {
12110 l
= isl_basic_map_alloc_equality(bmap
);
12113 for (j
= 0, pos
= 0; j
< 5; ++j
) {
12114 int off
= isl_basic_map_offset(bmap
, c
[j
]);
12115 isl_size dim
= isl_basic_map_dim(bmap
, c
[j
]);
12118 for (k
= 0; k
< dim
; ++k
) {
12119 isl_int_set(bmap
->eq
[l
][off
+ k
],
12125 for (i
= 0; i
< ineq
->n_row
; ++i
) {
12126 l
= isl_basic_map_alloc_inequality(bmap
);
12129 for (j
= 0, pos
= 0; j
< 5; ++j
) {
12130 int off
= isl_basic_map_offset(bmap
, c
[j
]);
12131 isl_size dim
= isl_basic_map_dim(bmap
, c
[j
]);
12134 for (k
= 0; k
< dim
; ++k
) {
12135 isl_int_set(bmap
->ineq
[l
][off
+ k
],
12136 ineq
->row
[i
][pos
]);
12142 isl_space_free(space
);
12144 isl_mat_free(ineq
);
12146 bmap
= isl_basic_map_simplify(bmap
);
12147 return isl_basic_map_finalize(bmap
);
12149 isl_space_free(space
);
12151 isl_mat_free(ineq
);
12152 isl_basic_map_free(bmap
);
12156 __isl_give isl_mat
*isl_basic_set_equalities_matrix(
12157 __isl_keep isl_basic_set
*bset
, enum isl_dim_type c1
,
12158 enum isl_dim_type c2
, enum isl_dim_type c3
, enum isl_dim_type c4
)
12160 return isl_basic_map_equalities_matrix(bset_to_bmap(bset
),
12161 c1
, c2
, c3
, c4
, isl_dim_in
);
12164 __isl_give isl_mat
*isl_basic_set_inequalities_matrix(
12165 __isl_keep isl_basic_set
*bset
, enum isl_dim_type c1
,
12166 enum isl_dim_type c2
, enum isl_dim_type c3
, enum isl_dim_type c4
)
12168 return isl_basic_map_inequalities_matrix(bset_to_bmap(bset
),
12169 c1
, c2
, c3
, c4
, isl_dim_in
);
12172 __isl_give isl_basic_set
*isl_basic_set_from_constraint_matrices(
12173 __isl_take isl_space
*dim
,
12174 __isl_take isl_mat
*eq
, __isl_take isl_mat
*ineq
, enum isl_dim_type c1
,
12175 enum isl_dim_type c2
, enum isl_dim_type c3
, enum isl_dim_type c4
)
12177 isl_basic_map
*bmap
;
12178 bmap
= isl_basic_map_from_constraint_matrices(dim
, eq
, ineq
,
12179 c1
, c2
, c3
, c4
, isl_dim_in
);
12180 return bset_from_bmap(bmap
);
12183 isl_bool
isl_basic_map_can_zip(__isl_keep isl_basic_map
*bmap
)
12186 return isl_bool_error
;
12188 return isl_space_can_zip(bmap
->dim
);
12191 isl_bool
isl_map_can_zip(__isl_keep isl_map
*map
)
12194 return isl_bool_error
;
12196 return isl_space_can_zip(map
->dim
);
12199 /* Given a basic map (A -> B) -> (C -> D), return the corresponding basic map
12200 * (A -> C) -> (B -> D).
12202 __isl_give isl_basic_map
*isl_basic_map_zip(__isl_take isl_basic_map
*bmap
)
12212 if (!isl_basic_map_can_zip(bmap
))
12213 isl_die(bmap
->ctx
, isl_error_invalid
,
12214 "basic map cannot be zipped", goto error
);
12215 n_in
= isl_space_dim(bmap
->dim
->nested
[0], isl_dim_in
);
12216 n1
= isl_space_dim(bmap
->dim
->nested
[0], isl_dim_out
);
12217 n2
= isl_space_dim(bmap
->dim
->nested
[1], isl_dim_in
);
12218 if (n_in
< 0 || n1
< 0 || n2
< 0)
12219 return isl_basic_map_free(bmap
);
12220 pos
= isl_basic_map_offset(bmap
, isl_dim_in
) + n_in
;
12221 bmap
= isl_basic_map_cow(bmap
);
12222 bmap
= isl_basic_map_swap_vars(bmap
, pos
, n1
, n2
);
12225 bmap
->dim
= isl_space_zip(bmap
->dim
);
12228 bmap
= isl_basic_map_mark_final(bmap
);
12231 isl_basic_map_free(bmap
);
12235 /* Given a map (A -> B) -> (C -> D), return the corresponding map
12236 * (A -> C) -> (B -> D).
12238 __isl_give isl_map
*isl_map_zip(__isl_take isl_map
*map
)
12245 if (!isl_map_can_zip(map
))
12246 isl_die(map
->ctx
, isl_error_invalid
, "map cannot be zipped",
12249 map
= isl_map_cow(map
);
12253 for (i
= 0; i
< map
->n
; ++i
) {
12254 map
->p
[i
] = isl_basic_map_zip(map
->p
[i
]);
12259 map
->dim
= isl_space_zip(map
->dim
);
12269 /* Can we apply isl_basic_map_curry to "bmap"?
12270 * That is, does it have a nested relation in its domain?
12272 isl_bool
isl_basic_map_can_curry(__isl_keep isl_basic_map
*bmap
)
12275 return isl_bool_error
;
12277 return isl_space_can_curry(bmap
->dim
);
12280 /* Can we apply isl_map_curry to "map"?
12281 * That is, does it have a nested relation in its domain?
12283 isl_bool
isl_map_can_curry(__isl_keep isl_map
*map
)
12286 return isl_bool_error
;
12288 return isl_space_can_curry(map
->dim
);
12291 /* Given a basic map (A -> B) -> C, return the corresponding basic map
12294 __isl_give isl_basic_map
*isl_basic_map_curry(__isl_take isl_basic_map
*bmap
)
12300 if (!isl_basic_map_can_curry(bmap
))
12301 isl_die(bmap
->ctx
, isl_error_invalid
,
12302 "basic map cannot be curried", goto error
);
12303 bmap
= isl_basic_map_cow(bmap
);
12306 bmap
->dim
= isl_space_curry(bmap
->dim
);
12309 bmap
= isl_basic_map_mark_final(bmap
);
12312 isl_basic_map_free(bmap
);
12316 /* Given a map (A -> B) -> C, return the corresponding map
12319 __isl_give isl_map
*isl_map_curry(__isl_take isl_map
*map
)
12321 return isl_map_change_space(map
, &isl_map_can_curry
,
12322 "map cannot be curried", &isl_space_curry
);
12325 /* Can isl_map_range_curry be applied to "map"?
12326 * That is, does it have a nested relation in its range,
12327 * the domain of which is itself a nested relation?
12329 isl_bool
isl_map_can_range_curry(__isl_keep isl_map
*map
)
12332 return isl_bool_error
;
12334 return isl_space_can_range_curry(map
->dim
);
12337 /* Given a map A -> ((B -> C) -> D), return the corresponding map
12338 * A -> (B -> (C -> D)).
12340 __isl_give isl_map
*isl_map_range_curry(__isl_take isl_map
*map
)
12342 return isl_map_change_space(map
, &isl_map_can_range_curry
,
12343 "map range cannot be curried",
12344 &isl_space_range_curry
);
12347 /* Can we apply isl_basic_map_uncurry to "bmap"?
12348 * That is, does it have a nested relation in its domain?
12350 isl_bool
isl_basic_map_can_uncurry(__isl_keep isl_basic_map
*bmap
)
12353 return isl_bool_error
;
12355 return isl_space_can_uncurry(bmap
->dim
);
12358 /* Can we apply isl_map_uncurry to "map"?
12359 * That is, does it have a nested relation in its domain?
12361 isl_bool
isl_map_can_uncurry(__isl_keep isl_map
*map
)
12364 return isl_bool_error
;
12366 return isl_space_can_uncurry(map
->dim
);
12369 /* Given a basic map A -> (B -> C), return the corresponding basic map
12372 __isl_give isl_basic_map
*isl_basic_map_uncurry(__isl_take isl_basic_map
*bmap
)
12378 if (!isl_basic_map_can_uncurry(bmap
))
12379 isl_die(bmap
->ctx
, isl_error_invalid
,
12380 "basic map cannot be uncurried",
12381 return isl_basic_map_free(bmap
));
12382 bmap
= isl_basic_map_cow(bmap
);
12385 bmap
->dim
= isl_space_uncurry(bmap
->dim
);
12387 return isl_basic_map_free(bmap
);
12388 bmap
= isl_basic_map_mark_final(bmap
);
12392 /* Given a map A -> (B -> C), return the corresponding map
12395 __isl_give isl_map
*isl_map_uncurry(__isl_take isl_map
*map
)
12397 return isl_map_change_space(map
, &isl_map_can_uncurry
,
12398 "map cannot be uncurried", &isl_space_uncurry
);
12401 __isl_give isl_set
*isl_set_equate(__isl_take isl_set
*set
,
12402 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
12404 return isl_map_equate(set
, type1
, pos1
, type2
, pos2
);
12407 /* Construct a basic map where the given dimensions are equal to each other.
12409 static __isl_give isl_basic_map
*equator(__isl_take isl_space
*space
,
12410 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
12412 isl_basic_map
*bmap
= NULL
;
12416 total
= isl_space_dim(space
, isl_dim_all
);
12418 isl_space_check_range(space
, type1
, pos1
, 1) < 0 ||
12419 isl_space_check_range(space
, type2
, pos2
, 1) < 0)
12422 if (type1
== type2
&& pos1
== pos2
)
12423 return isl_basic_map_universe(space
);
12425 bmap
= isl_basic_map_alloc_space(isl_space_copy(space
), 0, 1, 0);
12426 i
= isl_basic_map_alloc_equality(bmap
);
12429 isl_seq_clr(bmap
->eq
[i
], 1 + total
);
12430 pos1
+= isl_basic_map_offset(bmap
, type1
);
12431 pos2
+= isl_basic_map_offset(bmap
, type2
);
12432 isl_int_set_si(bmap
->eq
[i
][pos1
], -1);
12433 isl_int_set_si(bmap
->eq
[i
][pos2
], 1);
12434 bmap
= isl_basic_map_finalize(bmap
);
12435 isl_space_free(space
);
12438 isl_space_free(space
);
12439 isl_basic_map_free(bmap
);
12443 /* Add a constraint imposing that the given two dimensions are equal.
12445 __isl_give isl_basic_map
*isl_basic_map_equate(__isl_take isl_basic_map
*bmap
,
12446 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
12450 eq
= equator(isl_basic_map_get_space(bmap
), type1
, pos1
, type2
, pos2
);
12452 bmap
= isl_basic_map_intersect(bmap
, eq
);
12457 /* Add a constraint imposing that the given two dimensions are equal.
12459 __isl_give isl_map
*isl_map_equate(__isl_take isl_map
*map
,
12460 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
12462 isl_basic_map
*bmap
;
12464 bmap
= equator(isl_map_get_space(map
), type1
, pos1
, type2
, pos2
);
12466 map
= isl_map_intersect(map
, isl_map_from_basic_map(bmap
));
12471 /* Add a constraint imposing that the given two dimensions have opposite values.
12473 __isl_give isl_map
*isl_map_oppose(__isl_take isl_map
*map
,
12474 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
12476 isl_basic_map
*bmap
= NULL
;
12480 if (isl_map_check_range(map
, type1
, pos1
, 1) < 0)
12481 return isl_map_free(map
);
12482 if (isl_map_check_range(map
, type2
, pos2
, 1) < 0)
12483 return isl_map_free(map
);
12485 total
= isl_map_dim(map
, isl_dim_all
);
12487 return isl_map_free(map
);
12488 bmap
= isl_basic_map_alloc_space(isl_map_get_space(map
), 0, 1, 0);
12489 i
= isl_basic_map_alloc_equality(bmap
);
12492 isl_seq_clr(bmap
->eq
[i
], 1 + total
);
12493 pos1
+= isl_basic_map_offset(bmap
, type1
);
12494 pos2
+= isl_basic_map_offset(bmap
, type2
);
12495 isl_int_set_si(bmap
->eq
[i
][pos1
], 1);
12496 isl_int_set_si(bmap
->eq
[i
][pos2
], 1);
12497 bmap
= isl_basic_map_finalize(bmap
);
12499 map
= isl_map_intersect(map
, isl_map_from_basic_map(bmap
));
12503 isl_basic_map_free(bmap
);
12508 /* Construct a constraint imposing that the value of the first dimension is
12509 * greater than or equal to that of the second.
12511 static __isl_give isl_constraint
*constraint_order_ge(
12512 __isl_take isl_space
*space
, enum isl_dim_type type1
, int pos1
,
12513 enum isl_dim_type type2
, int pos2
)
12517 if (isl_space_check_range(space
, type1
, pos1
, 1) < 0 ||
12518 isl_space_check_range(space
, type2
, pos2
, 1) < 0)
12519 space
= isl_space_free(space
);
12523 c
= isl_constraint_alloc_inequality(isl_local_space_from_space(space
));
12525 if (type1
== type2
&& pos1
== pos2
)
12528 c
= isl_constraint_set_coefficient_si(c
, type1
, pos1
, 1);
12529 c
= isl_constraint_set_coefficient_si(c
, type2
, pos2
, -1);
12534 /* Add a constraint imposing that the value of the first dimension is
12535 * greater than or equal to that of the second.
12537 __isl_give isl_basic_map
*isl_basic_map_order_ge(__isl_take isl_basic_map
*bmap
,
12538 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
12543 if (type1
== type2
&& pos1
== pos2
)
12545 space
= isl_basic_map_get_space(bmap
);
12546 c
= constraint_order_ge(space
, type1
, pos1
, type2
, pos2
);
12547 bmap
= isl_basic_map_add_constraint(bmap
, c
);
12552 /* Add a constraint imposing that the value of the first dimension is
12553 * greater than or equal to that of the second.
12555 __isl_give isl_map
*isl_map_order_ge(__isl_take isl_map
*map
,
12556 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
12561 if (type1
== type2
&& pos1
== pos2
)
12563 space
= isl_map_get_space(map
);
12564 c
= constraint_order_ge(space
, type1
, pos1
, type2
, pos2
);
12565 map
= isl_map_add_constraint(map
, c
);
12570 /* Add a constraint imposing that the value of the first dimension is
12571 * less than or equal to that of the second.
12573 __isl_give isl_map
*isl_map_order_le(__isl_take isl_map
*map
,
12574 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
12576 return isl_map_order_ge(map
, type2
, pos2
, type1
, pos1
);
12579 /* Construct a basic map where the value of the first dimension is
12580 * greater than that of the second.
12582 static __isl_give isl_basic_map
*greator(__isl_take isl_space
*space
,
12583 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
12585 isl_basic_map
*bmap
= NULL
;
12589 if (isl_space_check_range(space
, type1
, pos1
, 1) < 0 ||
12590 isl_space_check_range(space
, type2
, pos2
, 1) < 0)
12593 if (type1
== type2
&& pos1
== pos2
)
12594 return isl_basic_map_empty(space
);
12596 bmap
= isl_basic_map_alloc_space(space
, 0, 0, 1);
12597 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
12598 i
= isl_basic_map_alloc_inequality(bmap
);
12599 if (total
< 0 || i
< 0)
12600 return isl_basic_map_free(bmap
);
12601 isl_seq_clr(bmap
->ineq
[i
], 1 + total
);
12602 pos1
+= isl_basic_map_offset(bmap
, type1
);
12603 pos2
+= isl_basic_map_offset(bmap
, type2
);
12604 isl_int_set_si(bmap
->ineq
[i
][pos1
], 1);
12605 isl_int_set_si(bmap
->ineq
[i
][pos2
], -1);
12606 isl_int_set_si(bmap
->ineq
[i
][0], -1);
12607 bmap
= isl_basic_map_finalize(bmap
);
12611 isl_space_free(space
);
12612 isl_basic_map_free(bmap
);
12616 /* Add a constraint imposing that the value of the first dimension is
12617 * greater than that of the second.
12619 __isl_give isl_basic_map
*isl_basic_map_order_gt(__isl_take isl_basic_map
*bmap
,
12620 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
12624 gt
= greator(isl_basic_map_get_space(bmap
), type1
, pos1
, type2
, pos2
);
12626 bmap
= isl_basic_map_intersect(bmap
, gt
);
12631 /* Add a constraint imposing that the value of the first dimension is
12632 * greater than that of the second.
12634 __isl_give isl_map
*isl_map_order_gt(__isl_take isl_map
*map
,
12635 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
12637 isl_basic_map
*bmap
;
12639 bmap
= greator(isl_map_get_space(map
), type1
, pos1
, type2
, pos2
);
12641 map
= isl_map_intersect(map
, isl_map_from_basic_map(bmap
));
12646 /* Add a constraint imposing that the value of the first dimension is
12647 * smaller than that of the second.
12649 __isl_give isl_map
*isl_map_order_lt(__isl_take isl_map
*map
,
12650 enum isl_dim_type type1
, int pos1
, enum isl_dim_type type2
, int pos2
)
12652 return isl_map_order_gt(map
, type2
, pos2
, type1
, pos1
);
12655 __isl_give isl_aff
*isl_basic_map_get_div(__isl_keep isl_basic_map
*bmap
,
12659 isl_local_space
*ls
;
12664 if (!isl_basic_map_divs_known(bmap
))
12665 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
12666 "some divs are unknown", return NULL
);
12668 ls
= isl_basic_map_get_local_space(bmap
);
12669 div
= isl_local_space_get_div(ls
, pos
);
12670 isl_local_space_free(ls
);
12675 __isl_give isl_aff
*isl_basic_set_get_div(__isl_keep isl_basic_set
*bset
,
12678 return isl_basic_map_get_div(bset
, pos
);
12681 /* Plug in "subs" for dimension "type", "pos" of "bset".
12683 * Let i be the dimension to replace and let "subs" be of the form
12687 * Any integer division with a non-zero coefficient for i,
12689 * floor((a i + g)/m)
12693 * floor((a f + d g)/(m d))
12695 * Constraints of the form
12703 * We currently require that "subs" is an integral expression.
12704 * Handling rational expressions may require us to add stride constraints
12705 * as we do in isl_basic_set_preimage_multi_aff.
12707 __isl_give isl_basic_set
*isl_basic_set_substitute(
12708 __isl_take isl_basic_set
*bset
,
12709 enum isl_dim_type type
, unsigned pos
, __isl_keep isl_aff
*subs
)
12716 if (bset
&& isl_basic_set_plain_is_empty(bset
))
12719 bset
= isl_basic_set_cow(bset
);
12720 if (!bset
|| !subs
)
12723 ctx
= isl_basic_set_get_ctx(bset
);
12724 if (!isl_space_is_equal(bset
->dim
, subs
->ls
->dim
))
12725 isl_die(ctx
, isl_error_invalid
,
12726 "spaces don't match", goto error
);
12727 n_div
= isl_local_space_dim(subs
->ls
, isl_dim_div
);
12731 isl_die(ctx
, isl_error_unsupported
,
12732 "cannot handle divs yet", goto error
);
12733 if (!isl_int_is_one(subs
->v
->el
[0]))
12734 isl_die(ctx
, isl_error_invalid
,
12735 "can only substitute integer expressions", goto error
);
12737 pos
+= isl_basic_set_offset(bset
, type
);
12741 for (i
= 0; i
< bset
->n_eq
; ++i
) {
12742 if (isl_int_is_zero(bset
->eq
[i
][pos
]))
12744 isl_int_set(v
, bset
->eq
[i
][pos
]);
12745 isl_int_set_si(bset
->eq
[i
][pos
], 0);
12746 isl_seq_combine(bset
->eq
[i
], subs
->v
->el
[0], bset
->eq
[i
],
12747 v
, subs
->v
->el
+ 1, subs
->v
->size
- 1);
12750 for (i
= 0; i
< bset
->n_ineq
; ++i
) {
12751 if (isl_int_is_zero(bset
->ineq
[i
][pos
]))
12753 isl_int_set(v
, bset
->ineq
[i
][pos
]);
12754 isl_int_set_si(bset
->ineq
[i
][pos
], 0);
12755 isl_seq_combine(bset
->ineq
[i
], subs
->v
->el
[0], bset
->ineq
[i
],
12756 v
, subs
->v
->el
+ 1, subs
->v
->size
- 1);
12759 for (i
= 0; i
< bset
->n_div
; ++i
) {
12760 if (isl_int_is_zero(bset
->div
[i
][1 + pos
]))
12762 isl_int_set(v
, bset
->div
[i
][1 + pos
]);
12763 isl_int_set_si(bset
->div
[i
][1 + pos
], 0);
12764 isl_seq_combine(bset
->div
[i
] + 1,
12765 subs
->v
->el
[0], bset
->div
[i
] + 1,
12766 v
, subs
->v
->el
+ 1, subs
->v
->size
- 1);
12767 isl_int_mul(bset
->div
[i
][0], bset
->div
[i
][0], subs
->v
->el
[0]);
12772 bset
= isl_basic_set_simplify(bset
);
12773 return isl_basic_set_finalize(bset
);
12775 isl_basic_set_free(bset
);
12779 /* Plug in "subs" for dimension "type", "pos" of "set".
12781 __isl_give isl_set
*isl_set_substitute(__isl_take isl_set
*set
,
12782 enum isl_dim_type type
, unsigned pos
, __isl_keep isl_aff
*subs
)
12786 if (set
&& isl_set_plain_is_empty(set
))
12789 set
= isl_set_cow(set
);
12793 for (i
= set
->n
- 1; i
>= 0; --i
) {
12794 set
->p
[i
] = isl_basic_set_substitute(set
->p
[i
], type
, pos
, subs
);
12795 set
= set_from_map(remove_if_empty(set_to_map(set
), i
));
12806 /* Check if the range of "ma" is compatible with the domain or range
12807 * (depending on "type") of "bmap".
12809 static isl_stat
check_basic_map_compatible_range_multi_aff(
12810 __isl_keep isl_basic_map
*bmap
, enum isl_dim_type type
,
12811 __isl_keep isl_multi_aff
*ma
)
12814 isl_space
*ma_space
;
12816 ma_space
= isl_multi_aff_get_space(ma
);
12818 m
= isl_space_has_equal_params(bmap
->dim
, ma_space
);
12822 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
12823 "parameters don't match", goto error
);
12824 m
= isl_space_tuple_is_equal(bmap
->dim
, type
, ma_space
, isl_dim_out
);
12828 isl_die(isl_basic_map_get_ctx(bmap
), isl_error_invalid
,
12829 "spaces don't match", goto error
);
12831 isl_space_free(ma_space
);
12832 return isl_stat_ok
;
12834 isl_space_free(ma_space
);
12835 return isl_stat_error
;
12838 /* Copy the divs from "ma" to "bmap", adding zeros for the "n_before"
12839 * coefficients before the transformed range of dimensions,
12840 * the "n_after" coefficients after the transformed range of dimensions
12841 * and the coefficients of the other divs in "bmap".
12843 static __isl_give isl_basic_map
*set_ma_divs(__isl_take isl_basic_map
*bmap
,
12844 __isl_keep isl_multi_aff
*ma
, int n_before
, int n_after
, int n_div
)
12849 isl_local_space
*ls
;
12854 ls
= isl_aff_get_domain_local_space(ma
->u
.p
[0]);
12855 n_param
= isl_local_space_dim(ls
, isl_dim_param
);
12856 n_set
= isl_local_space_dim(ls
, isl_dim_set
);
12857 if (n_param
< 0 || n_set
< 0)
12858 return isl_basic_map_free(bmap
);
12860 for (i
= 0; i
< n_div
; ++i
) {
12861 int o_bmap
= 0, o_ls
= 0;
12863 isl_seq_cpy(bmap
->div
[i
], ls
->div
->row
[i
], 1 + 1 + n_param
);
12864 o_bmap
+= 1 + 1 + n_param
;
12865 o_ls
+= 1 + 1 + n_param
;
12866 isl_seq_clr(bmap
->div
[i
] + o_bmap
, n_before
);
12867 o_bmap
+= n_before
;
12868 isl_seq_cpy(bmap
->div
[i
] + o_bmap
,
12869 ls
->div
->row
[i
] + o_ls
, n_set
);
12872 isl_seq_clr(bmap
->div
[i
] + o_bmap
, n_after
);
12874 isl_seq_cpy(bmap
->div
[i
] + o_bmap
,
12875 ls
->div
->row
[i
] + o_ls
, n_div
);
12878 isl_seq_clr(bmap
->div
[i
] + o_bmap
, bmap
->n_div
- n_div
);
12879 bmap
= isl_basic_map_add_div_constraints(bmap
, i
);
12884 isl_local_space_free(ls
);
12887 isl_local_space_free(ls
);
12888 return isl_basic_map_free(bmap
);
12891 /* How many stride constraints does "ma" enforce?
12892 * That is, how many of the affine expressions have a denominator
12893 * different from one?
12895 static int multi_aff_strides(__isl_keep isl_multi_aff
*ma
)
12900 for (i
= 0; i
< ma
->n
; ++i
)
12901 if (!isl_int_is_one(ma
->u
.p
[i
]->v
->el
[0]))
12907 /* For each affine expression in ma of the form
12909 * x_i = (f_i y + h_i)/m_i
12911 * with m_i different from one, add a constraint to "bmap"
12914 * f_i y + h_i = m_i alpha_i
12916 * with alpha_i an additional existentially quantified variable.
12918 * The input variables of "ma" correspond to a subset of the variables
12919 * of "bmap". There are "n_before" variables in "bmap" before this
12920 * subset and "n_after" variables after this subset.
12921 * The integer divisions of the affine expressions in "ma" are assumed
12922 * to have been aligned. There are "n_div_ma" of them and
12923 * they appear first in "bmap", straight after the "n_after" variables.
12925 static __isl_give isl_basic_map
*add_ma_strides(
12926 __isl_take isl_basic_map
*bmap
, __isl_keep isl_multi_aff
*ma
,
12927 int n_before
, int n_after
, int n_div_ma
)
12935 total
= isl_basic_map_dim(bmap
, isl_dim_all
);
12936 n_param
= isl_multi_aff_dim(ma
, isl_dim_param
);
12937 n_in
= isl_multi_aff_dim(ma
, isl_dim_in
);
12938 if (total
< 0 || n_param
< 0 || n_in
< 0)
12939 return isl_basic_map_free(bmap
);
12940 for (i
= 0; i
< ma
->n
; ++i
) {
12941 int o_bmap
= 0, o_ma
= 1;
12943 if (isl_int_is_one(ma
->u
.p
[i
]->v
->el
[0]))
12945 div
= isl_basic_map_alloc_div(bmap
);
12946 k
= isl_basic_map_alloc_equality(bmap
);
12947 if (div
< 0 || k
< 0)
12949 isl_int_set_si(bmap
->div
[div
][0], 0);
12950 isl_seq_cpy(bmap
->eq
[k
] + o_bmap
,
12951 ma
->u
.p
[i
]->v
->el
+ o_ma
, 1 + n_param
);
12952 o_bmap
+= 1 + n_param
;
12953 o_ma
+= 1 + n_param
;
12954 isl_seq_clr(bmap
->eq
[k
] + o_bmap
, n_before
);
12955 o_bmap
+= n_before
;
12956 isl_seq_cpy(bmap
->eq
[k
] + o_bmap
,
12957 ma
->u
.p
[i
]->v
->el
+ o_ma
, n_in
);
12960 isl_seq_clr(bmap
->eq
[k
] + o_bmap
, n_after
);
12962 isl_seq_cpy(bmap
->eq
[k
] + o_bmap
,
12963 ma
->u
.p
[i
]->v
->el
+ o_ma
, n_div_ma
);
12964 o_bmap
+= n_div_ma
;
12966 isl_seq_clr(bmap
->eq
[k
] + o_bmap
, 1 + total
- o_bmap
);
12967 isl_int_neg(bmap
->eq
[k
][1 + total
], ma
->u
.p
[i
]->v
->el
[0]);
12973 isl_basic_map_free(bmap
);
12977 /* Replace the domain or range space (depending on "type) of "space" by "set".
12979 static __isl_give isl_space
*isl_space_set(__isl_take isl_space
*space
,
12980 enum isl_dim_type type
, __isl_take isl_space
*set
)
12982 if (type
== isl_dim_in
) {
12983 space
= isl_space_range(space
);
12984 space
= isl_space_map_from_domain_and_range(set
, space
);
12986 space
= isl_space_domain(space
);
12987 space
= isl_space_map_from_domain_and_range(space
, set
);
12993 /* Compute the preimage of the domain or range (depending on "type")
12994 * of "bmap" under the function represented by "ma".
12995 * In other words, plug in "ma" in the domain or range of "bmap".
12996 * The result is a basic map that lives in the same space as "bmap"
12997 * except that the domain or range has been replaced by
12998 * the domain space of "ma".
13000 * If bmap is represented by
13002 * A(p) + S u + B x + T v + C(divs) >= 0,
13004 * where u and x are input and output dimensions if type == isl_dim_out
13005 * while x and v are input and output dimensions if type == isl_dim_in,
13006 * and ma is represented by
13008 * x = D(p) + F(y) + G(divs')
13010 * then the result is
13012 * A(p) + B D(p) + S u + B F(y) + T v + B G(divs') + C(divs) >= 0
13014 * The divs in the input set are similarly adjusted.
13017 * floor((a_i(p) + s u + b_i x + t v + c_i(divs))/n_i)
13021 * floor((a_i(p) + b_i D(p) + s u + b_i F(y) + t v +
13022 * B_i G(divs') + c_i(divs))/n_i)
13024 * If bmap is not a rational map and if F(y) involves any denominators
13026 * x_i = (f_i y + h_i)/m_i
13028 * then additional constraints are added to ensure that we only
13029 * map back integer points. That is we enforce
13031 * f_i y + h_i = m_i alpha_i
13033 * with alpha_i an additional existentially quantified variable.
13035 * We first copy over the divs from "ma".
13036 * Then we add the modified constraints and divs from "bmap".
13037 * Finally, we add the stride constraints, if needed.
13039 __isl_give isl_basic_map
*isl_basic_map_preimage_multi_aff(
13040 __isl_take isl_basic_map
*bmap
, enum isl_dim_type type
,
13041 __isl_take isl_multi_aff
*ma
)
13045 isl_basic_map
*res
= NULL
;
13046 isl_size n_before
, n_after
, n_div_bmap
, n_div_ma
;
13047 isl_int f
, c1
, c2
, g
;
13056 ma
= isl_multi_aff_align_divs(ma
);
13059 if (check_basic_map_compatible_range_multi_aff(bmap
, type
, ma
) < 0)
13062 if (type
== isl_dim_in
) {
13064 n_after
= isl_basic_map_dim(bmap
, isl_dim_out
);
13066 n_before
= isl_basic_map_dim(bmap
, isl_dim_in
);
13069 n_div_bmap
= isl_basic_map_dim(bmap
, isl_dim_div
);
13070 n_div_ma
= ma
->n
? isl_aff_dim(ma
->u
.p
[0], isl_dim_div
) : 0;
13071 if (n_before
< 0 || n_after
< 0 || n_div_bmap
< 0 || n_div_ma
< 0)
13074 space
= isl_multi_aff_get_domain_space(ma
);
13075 space
= isl_space_set(isl_basic_map_get_space(bmap
), type
, space
);
13076 rational
= isl_basic_map_is_rational(bmap
);
13077 strides
= rational
? 0 : multi_aff_strides(ma
);
13078 res
= isl_basic_map_alloc_space(space
, n_div_ma
+ n_div_bmap
+ strides
,
13079 bmap
->n_eq
+ strides
, bmap
->n_ineq
+ 2 * n_div_ma
);
13081 res
= isl_basic_map_set_rational(res
);
13083 for (i
= 0; i
< n_div_ma
+ n_div_bmap
; ++i
)
13084 if (isl_basic_map_alloc_div(res
) < 0)
13087 res
= set_ma_divs(res
, ma
, n_before
, n_after
, n_div_ma
);
13091 for (i
= 0; i
< bmap
->n_eq
; ++i
) {
13092 k
= isl_basic_map_alloc_equality(res
);
13095 if (isl_seq_preimage(res
->eq
[k
], bmap
->eq
[i
], ma
, n_before
,
13096 n_after
, n_div_ma
, n_div_bmap
,
13097 f
, c1
, c2
, g
, 0) < 0)
13101 for (i
= 0; i
< bmap
->n_ineq
; ++i
) {
13102 k
= isl_basic_map_alloc_inequality(res
);
13105 if (isl_seq_preimage(res
->ineq
[k
], bmap
->ineq
[i
], ma
, n_before
,
13106 n_after
, n_div_ma
, n_div_bmap
,
13107 f
, c1
, c2
, g
, 0) < 0)
13111 for (i
= 0; i
< bmap
->n_div
; ++i
) {
13112 if (isl_int_is_zero(bmap
->div
[i
][0])) {
13113 isl_int_set_si(res
->div
[n_div_ma
+ i
][0], 0);
13116 if (isl_seq_preimage(res
->div
[n_div_ma
+ i
], bmap
->div
[i
], ma
,
13117 n_before
, n_after
, n_div_ma
, n_div_bmap
,
13118 f
, c1
, c2
, g
, 1) < 0)
13123 res
= add_ma_strides(res
, ma
, n_before
, n_after
, n_div_ma
);
13129 isl_basic_map_free(bmap
);
13130 isl_multi_aff_free(ma
);
13131 res
= isl_basic_map_simplify(res
);
13132 return isl_basic_map_finalize(res
);
13138 isl_basic_map_free(bmap
);
13139 isl_multi_aff_free(ma
);
13140 isl_basic_map_free(res
);
13144 /* Compute the preimage of "bset" under the function represented by "ma".
13145 * In other words, plug in "ma" in "bset". The result is a basic set
13146 * that lives in the domain space of "ma".
13148 __isl_give isl_basic_set
*isl_basic_set_preimage_multi_aff(
13149 __isl_take isl_basic_set
*bset
, __isl_take isl_multi_aff
*ma
)
13151 return isl_basic_map_preimage_multi_aff(bset
, isl_dim_set
, ma
);
13154 /* Compute the preimage of the domain of "bmap" under the function
13155 * represented by "ma".
13156 * In other words, plug in "ma" in the domain of "bmap".
13157 * The result is a basic map that lives in the same space as "bmap"
13158 * except that the domain has been replaced by the domain space of "ma".
13160 __isl_give isl_basic_map
*isl_basic_map_preimage_domain_multi_aff(
13161 __isl_take isl_basic_map
*bmap
, __isl_take isl_multi_aff
*ma
)
13163 return isl_basic_map_preimage_multi_aff(bmap
, isl_dim_in
, ma
);
13166 /* Compute the preimage of the range of "bmap" under the function
13167 * represented by "ma".
13168 * In other words, plug in "ma" in the range of "bmap".
13169 * The result is a basic map that lives in the same space as "bmap"
13170 * except that the range has been replaced by the domain space of "ma".
13172 __isl_give isl_basic_map
*isl_basic_map_preimage_range_multi_aff(
13173 __isl_take isl_basic_map
*bmap
, __isl_take isl_multi_aff
*ma
)
13175 return isl_basic_map_preimage_multi_aff(bmap
, isl_dim_out
, ma
);
13178 /* Check if the range of "ma" is compatible with the domain or range
13179 * (depending on "type") of "map".
13180 * Return isl_stat_error if anything is wrong.
13182 static isl_stat
check_map_compatible_range_multi_aff(
13183 __isl_keep isl_map
*map
, enum isl_dim_type type
,
13184 __isl_keep isl_multi_aff
*ma
)
13187 isl_space
*ma_space
;
13189 ma_space
= isl_multi_aff_get_space(ma
);
13190 m
= isl_space_tuple_is_equal(map
->dim
, type
, ma_space
, isl_dim_out
);
13191 isl_space_free(ma_space
);
13193 return isl_stat_error
;
13195 isl_die(isl_map_get_ctx(map
), isl_error_invalid
,
13196 "spaces don't match", return isl_stat_error
);
13197 return isl_stat_ok
;
13200 /* Compute the preimage of the domain or range (depending on "type")
13201 * of "map" under the function represented by "ma".
13202 * In other words, plug in "ma" in the domain or range of "map".
13203 * The result is a map that lives in the same space as "map"
13204 * except that the domain or range has been replaced by
13205 * the domain space of "ma".
13207 * The parameters are assumed to have been aligned.
13209 static __isl_give isl_map
*map_preimage_multi_aff(__isl_take isl_map
*map
,
13210 enum isl_dim_type type
, __isl_take isl_multi_aff
*ma
)
13215 map
= isl_map_cow(map
);
13216 ma
= isl_multi_aff_align_divs(ma
);
13219 if (check_map_compatible_range_multi_aff(map
, type
, ma
) < 0)
13222 for (i
= 0; i
< map
->n
; ++i
) {
13223 map
->p
[i
] = isl_basic_map_preimage_multi_aff(map
->p
[i
], type
,
13224 isl_multi_aff_copy(ma
));
13229 space
= isl_multi_aff_get_domain_space(ma
);
13230 space
= isl_space_set(isl_map_get_space(map
), type
, space
);
13232 isl_space_free(map
->dim
);
13237 isl_multi_aff_free(ma
);
13239 ISL_F_CLR(map
, ISL_MAP_DISJOINT
);
13240 ISL_F_CLR(map
, ISL_SET_NORMALIZED
);
13243 isl_multi_aff_free(ma
);
13248 /* Compute the preimage of the domain or range (depending on "type")
13249 * of "map" under the function represented by "ma".
13250 * In other words, plug in "ma" in the domain or range of "map".
13251 * The result is a map that lives in the same space as "map"
13252 * except that the domain or range has been replaced by
13253 * the domain space of "ma".
13255 __isl_give isl_map
*isl_map_preimage_multi_aff(__isl_take isl_map
*map
,
13256 enum isl_dim_type type
, __isl_take isl_multi_aff
*ma
)
13263 aligned
= isl_map_space_has_equal_params(map
, ma
->space
);
13267 return map_preimage_multi_aff(map
, type
, ma
);
13269 if (isl_map_check_named_params(map
) < 0)
13271 if (!isl_space_has_named_params(ma
->space
))
13272 isl_die(map
->ctx
, isl_error_invalid
,
13273 "unaligned unnamed parameters", goto error
);
13274 map
= isl_map_align_params(map
, isl_multi_aff_get_space(ma
));
13275 ma
= isl_multi_aff_align_params(ma
, isl_map_get_space(map
));
13277 return map_preimage_multi_aff(map
, type
, ma
);
13279 isl_multi_aff_free(ma
);
13280 return isl_map_free(map
);
13283 /* Compute the preimage of "set" under the function represented by "ma".
13284 * In other words, plug in "ma" in "set". The result is a set
13285 * that lives in the domain space of "ma".
13287 __isl_give isl_set
*isl_set_preimage_multi_aff(__isl_take isl_set
*set
,
13288 __isl_take isl_multi_aff
*ma
)
13290 return isl_map_preimage_multi_aff(set
, isl_dim_set
, ma
);
13293 /* Compute the preimage of the domain of "map" under the function
13294 * represented by "ma".
13295 * In other words, plug in "ma" in the domain of "map".
13296 * The result is a map that lives in the same space as "map"
13297 * except that the domain has been replaced by the domain space of "ma".
13299 __isl_give isl_map
*isl_map_preimage_domain_multi_aff(__isl_take isl_map
*map
,
13300 __isl_take isl_multi_aff
*ma
)
13302 return isl_map_preimage_multi_aff(map
, isl_dim_in
, ma
);
13305 /* Compute the preimage of the range of "map" under the function
13306 * represented by "ma".
13307 * In other words, plug in "ma" in the range of "map".
13308 * The result is a map that lives in the same space as "map"
13309 * except that the range has been replaced by the domain space of "ma".
13311 __isl_give isl_map
*isl_map_preimage_range_multi_aff(__isl_take isl_map
*map
,
13312 __isl_take isl_multi_aff
*ma
)
13314 return isl_map_preimage_multi_aff(map
, isl_dim_out
, ma
);
13317 /* Compute the preimage of "map" under the function represented by "pma".
13318 * In other words, plug in "pma" in the domain or range of "map".
13319 * The result is a map that lives in the same space as "map",
13320 * except that the space of type "type" has been replaced by
13321 * the domain space of "pma".
13323 * The parameters of "map" and "pma" are assumed to have been aligned.
13325 static __isl_give isl_map
*isl_map_preimage_pw_multi_aff_aligned(
13326 __isl_take isl_map
*map
, enum isl_dim_type type
,
13327 __isl_take isl_pw_multi_aff
*pma
)
13336 isl_pw_multi_aff_free(pma
);
13337 res
= isl_map_empty(isl_map_get_space(map
));
13342 res
= isl_map_preimage_multi_aff(isl_map_copy(map
), type
,
13343 isl_multi_aff_copy(pma
->p
[0].maff
));
13344 if (type
== isl_dim_in
)
13345 res
= isl_map_intersect_domain(res
,
13346 isl_map_copy(pma
->p
[0].set
));
13348 res
= isl_map_intersect_range(res
,
13349 isl_map_copy(pma
->p
[0].set
));
13351 for (i
= 1; i
< pma
->n
; ++i
) {
13354 res_i
= isl_map_preimage_multi_aff(isl_map_copy(map
), type
,
13355 isl_multi_aff_copy(pma
->p
[i
].maff
));
13356 if (type
== isl_dim_in
)
13357 res_i
= isl_map_intersect_domain(res_i
,
13358 isl_map_copy(pma
->p
[i
].set
));
13360 res_i
= isl_map_intersect_range(res_i
,
13361 isl_map_copy(pma
->p
[i
].set
));
13362 res
= isl_map_union(res
, res_i
);
13365 isl_pw_multi_aff_free(pma
);
13369 isl_pw_multi_aff_free(pma
);
13374 /* Compute the preimage of "map" under the function represented by "pma".
13375 * In other words, plug in "pma" in the domain or range of "map".
13376 * The result is a map that lives in the same space as "map",
13377 * except that the space of type "type" has been replaced by
13378 * the domain space of "pma".
13380 __isl_give isl_map
*isl_map_preimage_pw_multi_aff(__isl_take isl_map
*map
,
13381 enum isl_dim_type type
, __isl_take isl_pw_multi_aff
*pma
)
13388 aligned
= isl_map_space_has_equal_params(map
, pma
->dim
);
13392 return isl_map_preimage_pw_multi_aff_aligned(map
, type
, pma
);
13394 if (isl_map_check_named_params(map
) < 0)
13396 if (isl_pw_multi_aff_check_named_params(pma
) < 0)
13398 map
= isl_map_align_params(map
, isl_pw_multi_aff_get_space(pma
));
13399 pma
= isl_pw_multi_aff_align_params(pma
, isl_map_get_space(map
));
13401 return isl_map_preimage_pw_multi_aff_aligned(map
, type
, pma
);
13403 isl_pw_multi_aff_free(pma
);
13404 return isl_map_free(map
);
13407 /* Compute the preimage of "set" under the function represented by "pma".
13408 * In other words, plug in "pma" in "set". The result is a set
13409 * that lives in the domain space of "pma".
13411 __isl_give isl_set
*isl_set_preimage_pw_multi_aff(__isl_take isl_set
*set
,
13412 __isl_take isl_pw_multi_aff
*pma
)
13414 return isl_map_preimage_pw_multi_aff(set
, isl_dim_set
, pma
);
13417 /* Compute the preimage of the domain of "map" under the function
13418 * represented by "pma".
13419 * In other words, plug in "pma" in the domain of "map".
13420 * The result is a map that lives in the same space as "map",
13421 * except that domain space has been replaced by the domain space of "pma".
13423 __isl_give isl_map
*isl_map_preimage_domain_pw_multi_aff(
13424 __isl_take isl_map
*map
, __isl_take isl_pw_multi_aff
*pma
)
13426 return isl_map_preimage_pw_multi_aff(map
, isl_dim_in
, pma
);
13429 /* Compute the preimage of the range of "map" under the function
13430 * represented by "pma".
13431 * In other words, plug in "pma" in the range of "map".
13432 * The result is a map that lives in the same space as "map",
13433 * except that range space has been replaced by the domain space of "pma".
13435 __isl_give isl_map
*isl_map_preimage_range_pw_multi_aff(
13436 __isl_take isl_map
*map
, __isl_take isl_pw_multi_aff
*pma
)
13438 return isl_map_preimage_pw_multi_aff(map
, isl_dim_out
, pma
);
13441 /* Compute the preimage of "map" under the function represented by "mpa".
13442 * In other words, plug in "mpa" in the domain or range of "map".
13443 * The result is a map that lives in the same space as "map",
13444 * except that the space of type "type" has been replaced by
13445 * the domain space of "mpa".
13447 * If the map does not involve any constraints that refer to the
13448 * dimensions of the substituted space, then the only possible
13449 * effect of "mpa" on the map is to map the space to a different space.
13450 * We create a separate isl_multi_aff to effectuate this change
13451 * in order to avoid spurious splitting of the map along the pieces
13453 * If "mpa" has a non-trivial explicit domain, however,
13454 * then the full substitution should be performed.
13456 __isl_give isl_map
*isl_map_preimage_multi_pw_aff(__isl_take isl_map
*map
,
13457 enum isl_dim_type type
, __isl_take isl_multi_pw_aff
*mpa
)
13461 isl_pw_multi_aff
*pma
;
13463 n
= isl_map_dim(map
, type
);
13467 full
= isl_map_involves_dims(map
, type
, 0, n
);
13468 if (full
>= 0 && !full
)
13469 full
= isl_multi_pw_aff_has_non_trivial_domain(mpa
);
13476 space
= isl_multi_pw_aff_get_space(mpa
);
13477 isl_multi_pw_aff_free(mpa
);
13478 ma
= isl_multi_aff_zero(space
);
13479 return isl_map_preimage_multi_aff(map
, type
, ma
);
13482 pma
= isl_pw_multi_aff_from_multi_pw_aff(mpa
);
13483 return isl_map_preimage_pw_multi_aff(map
, type
, pma
);
13486 isl_multi_pw_aff_free(mpa
);
13490 /* Compute the preimage of "map" under the function represented by "mpa".
13491 * In other words, plug in "mpa" in the domain "map".
13492 * The result is a map that lives in the same space as "map",
13493 * except that domain space has been replaced by the domain space of "mpa".
13495 __isl_give isl_map
*isl_map_preimage_domain_multi_pw_aff(
13496 __isl_take isl_map
*map
, __isl_take isl_multi_pw_aff
*mpa
)
13498 return isl_map_preimage_multi_pw_aff(map
, isl_dim_in
, mpa
);
13501 /* Compute the preimage of "set" by the function represented by "mpa".
13502 * In other words, plug in "mpa" in "set".
13504 __isl_give isl_set
*isl_set_preimage_multi_pw_aff(__isl_take isl_set
*set
,
13505 __isl_take isl_multi_pw_aff
*mpa
)
13507 return isl_map_preimage_multi_pw_aff(set
, isl_dim_set
, mpa
);
13510 /* Return a copy of the equality constraints of "bset" as a matrix.
13512 __isl_give isl_mat
*isl_basic_set_extract_equalities(
13513 __isl_keep isl_basic_set
*bset
)
13518 total
= isl_basic_set_dim(bset
, isl_dim_all
);
13522 ctx
= isl_basic_set_get_ctx(bset
);
13523 return isl_mat_sub_alloc6(ctx
, bset
->eq
, 0, bset
->n_eq
, 0, 1 + total
);
13526 /* Are the "n" "coefficients" starting at "first" of the integer division
13527 * expressions at position "pos1" in "bmap1" and "pos2" in "bmap2" equal
13529 * The "coefficient" at position 0 is the denominator.
13530 * The "coefficient" at position 1 is the constant term.
13532 isl_bool
isl_basic_map_equal_div_expr_part(__isl_keep isl_basic_map
*bmap1
,
13533 int pos1
, __isl_keep isl_basic_map
*bmap2
, int pos2
,
13534 unsigned first
, unsigned n
)
13536 if (isl_basic_map_check_range(bmap1
, isl_dim_div
, pos1
, 1) < 0)
13537 return isl_bool_error
;
13538 if (isl_basic_map_check_range(bmap2
, isl_dim_div
, pos2
, 1) < 0)
13539 return isl_bool_error
;
13540 return isl_seq_eq(bmap1
->div
[pos1
] + first
,
13541 bmap2
->div
[pos2
] + first
, n
);
13544 /* Are the integer division expressions at position "pos1" in "bmap1" and
13545 * "pos2" in "bmap2" equal to each other, except that the constant terms
13548 isl_bool
isl_basic_map_equal_div_expr_except_constant(
13549 __isl_keep isl_basic_map
*bmap1
, int pos1
,
13550 __isl_keep isl_basic_map
*bmap2
, int pos2
)
13553 isl_size total
, total2
;
13555 total
= isl_basic_map_dim(bmap1
, isl_dim_all
);
13556 total2
= isl_basic_map_dim(bmap2
, isl_dim_all
);
13557 if (total
< 0 || total2
< 0)
13558 return isl_bool_error
;
13559 if (total
!= total2
)
13560 isl_die(isl_basic_map_get_ctx(bmap1
), isl_error_invalid
,
13561 "incomparable div expressions", return isl_bool_error
);
13562 equal
= isl_basic_map_equal_div_expr_part(bmap1
, pos1
, bmap2
, pos2
,
13564 if (equal
< 0 || !equal
)
13566 equal
= isl_basic_map_equal_div_expr_part(bmap1
, pos1
, bmap2
, pos2
,
13568 if (equal
< 0 || equal
)
13569 return isl_bool_not(equal
);
13570 return isl_basic_map_equal_div_expr_part(bmap1
, pos1
, bmap2
, pos2
,
13574 /* Replace the numerator of the constant term of the integer division
13575 * expression at position "div" in "bmap" by "value".
13576 * The caller guarantees that this does not change the meaning
13579 __isl_give isl_basic_map
*isl_basic_map_set_div_expr_constant_num_si_inplace(
13580 __isl_take isl_basic_map
*bmap
, int div
, int value
)
13582 if (isl_basic_map_check_range(bmap
, isl_dim_div
, div
, 1) < 0)
13583 return isl_basic_map_free(bmap
);
13585 isl_int_set_si(bmap
->div
[div
][1], value
);
13590 /* Is the point "inner" internal to inequality constraint "ineq"
13592 * The point is considered to be internal to the inequality constraint,
13593 * if it strictly lies on the positive side of the inequality constraint,
13594 * or if it lies on the constraint and the constraint is lexico-positive.
13596 static isl_bool
is_internal(__isl_keep isl_vec
*inner
,
13597 __isl_keep isl_basic_set
*bset
, int ineq
)
13603 if (!inner
|| !bset
)
13604 return isl_bool_error
;
13606 ctx
= isl_basic_set_get_ctx(bset
);
13607 isl_seq_inner_product(inner
->el
, bset
->ineq
[ineq
], inner
->size
,
13608 &ctx
->normalize_gcd
);
13609 if (!isl_int_is_zero(ctx
->normalize_gcd
))
13610 return isl_int_is_nonneg(ctx
->normalize_gcd
);
13612 total
= isl_basic_set_dim(bset
, isl_dim_all
);
13614 return isl_bool_error
;
13615 pos
= isl_seq_first_non_zero(bset
->ineq
[ineq
] + 1, total
);
13616 return isl_int_is_pos(bset
->ineq
[ineq
][1 + pos
]);
13619 /* Tighten the inequality constraints of "bset" that are outward with respect
13620 * to the point "vec".
13621 * That is, tighten the constraints that are not satisfied by "vec".
13623 * "vec" is a point internal to some superset S of "bset" that is used
13624 * to make the subsets of S disjoint, by tightening one half of the constraints
13625 * that separate two subsets. In particular, the constraints of S
13626 * are all satisfied by "vec" and should not be tightened.
13627 * Of the internal constraints, those that have "vec" on the outside
13628 * are tightened. The shared facet is included in the adjacent subset
13629 * with the opposite constraint.
13630 * For constraints that saturate "vec", this criterion cannot be used
13631 * to determine which of the two sides should be tightened.
13632 * Instead, the sign of the first non-zero coefficient is used
13633 * to make this choice. Note that this second criterion is never used
13634 * on the constraints of S since "vec" is interior to "S".
13636 __isl_give isl_basic_set
*isl_basic_set_tighten_outward(
13637 __isl_take isl_basic_set
*bset
, __isl_keep isl_vec
*vec
)
13641 bset
= isl_basic_set_cow(bset
);
13644 for (j
= 0; j
< bset
->n_ineq
; ++j
) {
13647 internal
= is_internal(vec
, bset
, j
);
13649 return isl_basic_set_free(bset
);
13652 isl_int_sub_ui(bset
->ineq
[j
][0], bset
->ineq
[j
][0], 1);
13658 /* Replace the variables x of type "type" starting at "first" in "bmap"
13659 * by x' with x = M x' with M the matrix trans.
13660 * That is, replace the corresponding coefficients c by c M.
13662 * The transformation matrix should be a square matrix.
13664 __isl_give isl_basic_map
*isl_basic_map_transform_dims(
13665 __isl_take isl_basic_map
*bmap
, enum isl_dim_type type
, unsigned first
,
13666 __isl_take isl_mat
*trans
)
13670 bmap
= isl_basic_map_cow(bmap
);
13671 if (!bmap
|| !trans
)
13674 if (trans
->n_row
!= trans
->n_col
)
13675 isl_die(trans
->ctx
, isl_error_invalid
,
13676 "expecting square transformation matrix", goto error
);
13677 if (isl_basic_map_check_range(bmap
, type
, first
, trans
->n_row
) < 0)
13680 pos
= isl_basic_map_offset(bmap
, type
) + first
;
13682 if (isl_mat_sub_transform(bmap
->eq
, bmap
->n_eq
, pos
,
13683 isl_mat_copy(trans
)) < 0)
13685 if (isl_mat_sub_transform(bmap
->ineq
, bmap
->n_ineq
, pos
,
13686 isl_mat_copy(trans
)) < 0)
13688 if (isl_mat_sub_transform(bmap
->div
, bmap
->n_div
, 1 + pos
,
13689 isl_mat_copy(trans
)) < 0)
13692 ISL_F_CLR(bmap
, ISL_BASIC_MAP_SORTED
);
13693 ISL_F_CLR(bmap
, ISL_BASIC_MAP_NORMALIZED_DIVS
);
13695 isl_mat_free(trans
);
13698 isl_mat_free(trans
);
13699 isl_basic_map_free(bmap
);
13703 /* Replace the variables x of type "type" starting at "first" in "bset"
13704 * by x' with x = M x' with M the matrix trans.
13705 * That is, replace the corresponding coefficients c by c M.
13707 * The transformation matrix should be a square matrix.
13709 __isl_give isl_basic_set
*isl_basic_set_transform_dims(
13710 __isl_take isl_basic_set
*bset
, enum isl_dim_type type
, unsigned first
,
13711 __isl_take isl_mat
*trans
)
13713 return isl_basic_map_transform_dims(bset
, type
, first
, trans
);