Home | History | Annotate | Line # | Download | only in dist
      1 /*
      2  * Copyright 2008-2009 Katholieke Universiteit Leuven
      3  * Copyright 2010      INRIA Saclay
      4  * Copyright 2012-2014 Ecole Normale Superieure
      5  * Copyright 2014      INRIA Rocquencourt
      6  * Copyright 2016      INRIA Paris
      7  * Copyright 2016      Sven Verdoolaege
      8  * Copyright 2018-2019 Cerebras Systems
      9  * Copyright 2022      Cerebras Systems
     10  *
     11  * Use of this software is governed by the MIT license
     12  *
     13  * Written by Sven Verdoolaege, K.U.Leuven, Departement
     14  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
     15  * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
     16  * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
     17  * and Ecole Normale Superieure, 45 rue dUlm, 75230 Paris, France
     18  * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
     19  * B.P. 105 - 78153 Le Chesnay, France
     20  * and Centre de Recherche Inria de Paris, 2 rue Simone Iff - Voie DQ12,
     21  * CS 42112, 75589 Paris Cedex 12, France
     22  * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA
     23  */
     24 
     25 #include <string.h>
     26 #include <isl_ctx_private.h>
     27 #include <isl_map_private.h>
     28 #include <isl_blk.h>
     29 #include <isl_id_private.h>
     30 #include <isl/constraint.h>
     31 #include "isl_space_private.h"
     32 #include "isl_equalities.h"
     33 #include <isl_lp_private.h>
     34 #include <isl_seq.h>
     35 #include <isl/set.h>
     36 #include <isl/map.h>
     37 #include <isl_reordering.h>
     38 #include "isl_sample.h"
     39 #include <isl_sort.h>
     40 #include "isl_tab.h"
     41 #include <isl/vec.h>
     42 #include <isl_mat_private.h>
     43 #include <isl_vec_private.h>
     44 #include <isl_dim_map.h>
     45 #include <isl_local_space_private.h>
     46 #include <isl_aff_private.h>
     47 #include <isl_options_private.h>
     48 #include <isl_morph.h>
     49 #include <isl_val_private.h>
     50 #include <isl_printer_private.h>
     51 
     52 #include <bset_to_bmap.c>
     53 #include <bset_from_bmap.c>
     54 #include <set_to_map.c>
     55 #include <set_from_map.c>
     56 
     57 /* Treat "bset" as a basic map.
     58  * Internally, isl_basic_set is defined to isl_basic_map, so in practice,
     59  * this function performs a redundant cast.
     60  */
     61 static __isl_keep const isl_basic_map *const_bset_to_bmap(
     62 	__isl_keep const isl_basic_set *bset)
     63 {
     64 	return (const isl_basic_map *) bset;
     65 }
     66 
     67 #undef TYPE
     68 #define TYPE	isl_basic_map
     69 #include "has_single_reference_templ.c"
     70 
     71 static unsigned pos(__isl_keep isl_space *space, enum isl_dim_type type)
     72 {
     73 	switch (type) {
     74 	case isl_dim_param:	return 1;
     75 	case isl_dim_in:	return 1 + space->nparam;
     76 	case isl_dim_out:	return 1 + space->nparam + space->n_in;
     77 	default:		return 0;
     78 	}
     79 }
     80 
     81 isl_size isl_basic_map_dim(__isl_keep isl_basic_map *bmap,
     82 				enum isl_dim_type type)
     83 {
     84 	if (!bmap)
     85 		return isl_size_error;
     86 	switch (type) {
     87 	case isl_dim_cst:	return 1;
     88 	case isl_dim_param:
     89 	case isl_dim_in:
     90 	case isl_dim_out:	return isl_space_dim(bmap->dim, type);
     91 	case isl_dim_div:	return bmap->n_div;
     92 	case isl_dim_all:	return isl_basic_map_total_dim(bmap);
     93 	default:		return 0;
     94 	}
     95 }
     96 
     97 /* Return the space of "map".
     98  */
     99 __isl_keep isl_space *isl_map_peek_space(__isl_keep const isl_map *map)
    100 {
    101 	return map ? map->dim : NULL;
    102 }
    103 
    104 /* Return the space of "set".
    105  */
    106 __isl_keep isl_space *isl_set_peek_space(__isl_keep isl_set *set)
    107 {
    108 	return isl_map_peek_space(set_to_map(set));
    109 }
    110 
    111 isl_size isl_map_dim(__isl_keep isl_map *map, enum isl_dim_type type)
    112 {
    113 	return isl_space_dim(isl_map_peek_space(map), type);
    114 }
    115 
    116 /* Return the dimensionality of the domain (tuple) of the map.
    117  */
    118 isl_size isl_map_domain_tuple_dim(__isl_keep isl_map *map)
    119 {
    120 	return isl_map_dim(map, isl_dim_in);
    121 }
    122 
    123 /* Return the dimensionality of the range (tuple) of the map.
    124  */
    125 isl_size isl_map_range_tuple_dim(__isl_keep isl_map *map)
    126 {
    127 	return isl_map_dim(map, isl_dim_out);
    128 }
    129 
    130 isl_size isl_set_dim(__isl_keep isl_set *set, enum isl_dim_type type)
    131 {
    132 	return isl_map_dim(set_to_map(set), type);
    133 }
    134 
    135 /* Return the dimensionality of the (tuple of the) set.
    136  */
    137 isl_size isl_set_tuple_dim(__isl_keep isl_set *set)
    138 {
    139 	return isl_set_dim(set, isl_dim_set);
    140 }
    141 
    142 /* Return the position of the variables of the given type
    143  * within the sequence of variables of "bmap".
    144  */
    145 isl_size isl_basic_map_var_offset(__isl_keep isl_basic_map *bmap,
    146 	enum isl_dim_type type)
    147 {
    148 	isl_space *space;
    149 
    150 	space = isl_basic_map_peek_space(bmap);
    151 
    152 	switch (type) {
    153 	case isl_dim_param:
    154 	case isl_dim_in:
    155 	case isl_dim_out:	return isl_space_offset(space, type);
    156 	case isl_dim_div:	return isl_space_dim(space, isl_dim_all);
    157 	case isl_dim_cst:
    158 	default:
    159 		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
    160 			"invalid dimension type", return isl_size_error);
    161 	}
    162 }
    163 
    164 /* Return the position of the variables of the given type
    165  * within the sequence of variables of "bset".
    166  */
    167 isl_size isl_basic_set_var_offset(__isl_keep isl_basic_set *bset,
    168 	enum isl_dim_type type)
    169 {
    170 	return isl_basic_map_var_offset(bset_to_bmap(bset), type);
    171 }
    172 
    173 /* Return the position of the coefficients of the variables of the given type
    174  * within the sequence of coefficients of "bmap".
    175  */
    176 unsigned isl_basic_map_offset(__isl_keep isl_basic_map *bmap,
    177 	enum isl_dim_type type)
    178 {
    179 	switch (type) {
    180 	case isl_dim_cst:	return 0;
    181 	case isl_dim_param:
    182 	case isl_dim_in:
    183 	case isl_dim_out:
    184 	case isl_dim_div:	return 1 + isl_basic_map_var_offset(bmap, type);
    185 	default:		return 0;
    186 	}
    187 }
    188 
    189 unsigned isl_basic_set_offset(__isl_keep isl_basic_set *bset,
    190 					enum isl_dim_type type)
    191 {
    192 	return isl_basic_map_offset(bset, type);
    193 }
    194 
    195 static unsigned map_offset(__isl_keep isl_map *map, enum isl_dim_type type)
    196 {
    197 	return pos(map->dim, type);
    198 }
    199 
    200 isl_size isl_basic_set_dim(__isl_keep isl_basic_set *bset,
    201 				enum isl_dim_type type)
    202 {
    203 	return isl_basic_map_dim(bset, type);
    204 }
    205 
    206 isl_size isl_basic_set_n_dim(__isl_keep isl_basic_set *bset)
    207 {
    208 	return isl_basic_set_dim(bset, isl_dim_set);
    209 }
    210 
    211 isl_size isl_basic_set_n_param(__isl_keep isl_basic_set *bset)
    212 {
    213 	return isl_basic_set_dim(bset, isl_dim_param);
    214 }
    215 
    216 isl_size isl_basic_set_total_dim(__isl_keep const isl_basic_set *bset)
    217 {
    218 	return isl_basic_map_total_dim(const_bset_to_bmap(bset));
    219 }
    220 
    221 isl_size isl_set_n_dim(__isl_keep isl_set *set)
    222 {
    223 	return isl_set_dim(set, isl_dim_set);
    224 }
    225 
    226 isl_size isl_set_n_param(__isl_keep isl_set *set)
    227 {
    228 	return isl_set_dim(set, isl_dim_param);
    229 }
    230 
    231 isl_size isl_basic_map_total_dim(__isl_keep const isl_basic_map *bmap)
    232 {
    233 	isl_size dim;
    234 
    235 	if (!bmap)
    236 		return isl_size_error;
    237 	dim = isl_space_dim(bmap->dim, isl_dim_all);
    238 	if (dim < 0)
    239 		return isl_size_error;
    240 	return dim + bmap->n_div;
    241 }
    242 
    243 /* Return the number of equality constraints in the description of "bmap".
    244  * Return isl_size_error on error.
    245  */
    246 isl_size isl_basic_map_n_equality(__isl_keep isl_basic_map *bmap)
    247 {
    248 	if (!bmap)
    249 		return isl_size_error;
    250 	return bmap->n_eq;
    251 }
    252 
    253 /* Return the number of equality constraints in the description of "bset".
    254  * Return isl_size_error on error.
    255  */
    256 isl_size isl_basic_set_n_equality(__isl_keep isl_basic_set *bset)
    257 {
    258 	return isl_basic_map_n_equality(bset_to_bmap(bset));
    259 }
    260 
    261 /* Return the number of inequality constraints in the description of "bmap".
    262  * Return isl_size_error on error.
    263  */
    264 isl_size isl_basic_map_n_inequality(__isl_keep isl_basic_map *bmap)
    265 {
    266 	if (!bmap)
    267 		return isl_size_error;
    268 	return bmap->n_ineq;
    269 }
    270 
    271 /* Return the number of inequality constraints in the description of "bset".
    272  * Return isl_size_error on error.
    273  */
    274 isl_size isl_basic_set_n_inequality(__isl_keep isl_basic_set *bset)
    275 {
    276 	return isl_basic_map_n_inequality(bset_to_bmap(bset));
    277 }
    278 
    279 /* Do "bmap1" and "bmap2" have the same parameters?
    280  */
    281 static isl_bool isl_basic_map_has_equal_params(__isl_keep isl_basic_map *bmap1,
    282 	__isl_keep isl_basic_map *bmap2)
    283 {
    284 	isl_space *space1, *space2;
    285 
    286 	space1 = isl_basic_map_peek_space(bmap1);
    287 	space2 = isl_basic_map_peek_space(bmap2);
    288 	return isl_space_has_equal_params(space1, space2);
    289 }
    290 
    291 /* Do "map1" and "map2" have the same parameters?
    292  */
    293 isl_bool isl_map_has_equal_params(__isl_keep isl_map *map1,
    294 	__isl_keep isl_map *map2)
    295 {
    296 	isl_space *space1, *space2;
    297 
    298 	space1 = isl_map_peek_space(map1);
    299 	space2 = isl_map_peek_space(map2);
    300 	return isl_space_has_equal_params(space1, space2);
    301 }
    302 
    303 /* Do "map" and "set" have the same parameters?
    304  */
    305 static isl_bool isl_map_set_has_equal_params(__isl_keep isl_map *map,
    306 	__isl_keep isl_set *set)
    307 {
    308 	return isl_map_has_equal_params(map, set_to_map(set));
    309 }
    310 
    311 /* Is the tuple of type "type" of "bmap" the same as the single tuple of "bset"?
    312  */
    313 static isl_bool isl_basic_map_set_tuple_is_equal(__isl_keep isl_basic_map *bmap,
    314 	enum isl_dim_type type, __isl_keep isl_basic_set *bset)
    315 {
    316 	isl_space *bmap_space, *bset_space;
    317 
    318 	bmap_space = isl_basic_map_peek_space(bmap);
    319 	bset_space = isl_basic_set_peek_space(bset);
    320 	return isl_space_tuple_is_equal(bmap_space, type,
    321 					bset_space, isl_dim_set);
    322 }
    323 
    324 /* Is the tuple of type "type" of "map" the same as the single tuple of "set"?
    325  */
    326 static isl_bool isl_map_set_tuple_is_equal(__isl_keep isl_map *map,
    327 	enum isl_dim_type type, __isl_keep isl_set *set)
    328 {
    329 	return isl_map_tuple_is_equal(map, type, set_to_map(set), isl_dim_set);
    330 }
    331 
    332 isl_bool isl_map_compatible_domain(__isl_keep isl_map *map,
    333 	__isl_keep isl_set *set)
    334 {
    335 	isl_bool m;
    336 	if (!map || !set)
    337 		return isl_bool_error;
    338 	m = isl_map_has_equal_params(map, set_to_map(set));
    339 	if (m < 0 || !m)
    340 		return m;
    341 	return isl_map_set_tuple_is_equal(map, isl_dim_in, set);
    342 }
    343 
    344 isl_bool isl_basic_map_compatible_domain(__isl_keep isl_basic_map *bmap,
    345 	__isl_keep isl_basic_set *bset)
    346 {
    347 	isl_bool m;
    348 	if (!bmap || !bset)
    349 		return isl_bool_error;
    350 	m = isl_basic_map_has_equal_params(bmap, bset_to_bmap(bset));
    351 	if (m < 0 || !m)
    352 		return m;
    353 	return isl_basic_map_set_tuple_is_equal(bmap, isl_dim_in, bset);
    354 }
    355 
    356 isl_bool isl_map_compatible_range(__isl_keep isl_map *map,
    357 	__isl_keep isl_set *set)
    358 {
    359 	isl_bool m;
    360 	if (!map || !set)
    361 		return isl_bool_error;
    362 	m = isl_map_has_equal_params(map, set_to_map(set));
    363 	if (m < 0 || !m)
    364 		return m;
    365 	return isl_map_set_tuple_is_equal(map, isl_dim_out, set);
    366 }
    367 
    368 isl_bool isl_basic_map_compatible_range(__isl_keep isl_basic_map *bmap,
    369 	__isl_keep isl_basic_set *bset)
    370 {
    371 	isl_bool m;
    372 	if (!bmap || !bset)
    373 		return isl_bool_error;
    374 	m = isl_basic_map_has_equal_params(bmap, bset_to_bmap(bset));
    375 	if (m < 0 || !m)
    376 		return m;
    377 	return isl_basic_map_set_tuple_is_equal(bmap, isl_dim_out, bset);
    378 }
    379 
    380 isl_ctx *isl_basic_map_get_ctx(__isl_keep isl_basic_map *bmap)
    381 {
    382 	return bmap ? bmap->ctx : NULL;
    383 }
    384 
    385 isl_ctx *isl_basic_set_get_ctx(__isl_keep isl_basic_set *bset)
    386 {
    387 	return bset ? bset->ctx : NULL;
    388 }
    389 
    390 isl_ctx *isl_map_get_ctx(__isl_keep isl_map *map)
    391 {
    392 	return map ? map->ctx : NULL;
    393 }
    394 
    395 isl_ctx *isl_set_get_ctx(__isl_keep isl_set *set)
    396 {
    397 	return set ? set->ctx : NULL;
    398 }
    399 
    400 /* Return the space of "bmap".
    401  */
    402 __isl_keep isl_space *isl_basic_map_peek_space(
    403 	__isl_keep const isl_basic_map *bmap)
    404 {
    405 	return bmap ? bmap->dim : NULL;
    406 }
    407 
    408 /* Return the space of "bset".
    409  */
    410 __isl_keep isl_space *isl_basic_set_peek_space(__isl_keep isl_basic_set *bset)
    411 {
    412 	return isl_basic_map_peek_space(bset_to_bmap(bset));
    413 }
    414 
    415 __isl_give isl_space *isl_basic_map_get_space(__isl_keep isl_basic_map *bmap)
    416 {
    417 	return isl_space_copy(isl_basic_map_peek_space(bmap));
    418 }
    419 
    420 __isl_give isl_space *isl_basic_set_get_space(__isl_keep isl_basic_set *bset)
    421 {
    422 	return isl_basic_map_get_space(bset_to_bmap(bset));
    423 }
    424 
    425 /* Return the space of "bmap".
    426  * This may be either a copy or the space itself
    427  * if there is only one reference to "bmap".
    428  * This allows the space to be modified inplace
    429  * if both the basic map and its space have only a single reference.
    430  * The caller is not allowed to modify "bmap" between this call and
    431  * a subsequent call to isl_basic_map_restore_space.
    432  * The only exception is that isl_basic_map_free can be called instead.
    433  */
    434 static __isl_give isl_space *isl_basic_map_take_space(
    435 	__isl_keep isl_basic_map *bmap)
    436 {
    437 	isl_space *space;
    438 
    439 	if (!bmap)
    440 		return NULL;
    441 	if (bmap->ref != 1)
    442 		return isl_basic_map_get_space(bmap);
    443 	space = bmap->dim;
    444 	bmap->dim = NULL;
    445 	return space;
    446 }
    447 
    448 /* Set the space of "bmap" to "space", where the space of "bmap" may be missing
    449  * due to a preceding call to isl_basic_map_take_space.
    450  * However, in this case, "bmap" only has a single reference and
    451  * then the call to isl_basic_map_cow has no effect.
    452  */
    453 static __isl_give isl_basic_map *isl_basic_map_restore_space(
    454 	__isl_take isl_basic_map *bmap, __isl_take isl_space *space)
    455 {
    456 	if (!bmap || !space)
    457 		goto error;
    458 
    459 	if (bmap->dim == space) {
    460 		isl_space_free(space);
    461 		return bmap;
    462 	}
    463 
    464 	bmap = isl_basic_map_cow(bmap);
    465 	if (!bmap)
    466 		goto error;
    467 	isl_space_free(bmap->dim);
    468 	bmap->dim = space;
    469 
    470 	return bmap;
    471 error:
    472 	isl_basic_map_free(bmap);
    473 	isl_space_free(space);
    474 	return NULL;
    475 }
    476 
    477 /* Extract the divs in "bmap" as a matrix.
    478  */
    479 __isl_give isl_mat *isl_basic_map_get_divs(__isl_keep isl_basic_map *bmap)
    480 {
    481 	int i;
    482 	isl_ctx *ctx;
    483 	isl_mat *div;
    484 	isl_size v_div;
    485 	unsigned cols;
    486 
    487 	v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
    488 	if (v_div < 0)
    489 		return NULL;
    490 
    491 	ctx = isl_basic_map_get_ctx(bmap);
    492 	cols = 1 + 1 + v_div + bmap->n_div;
    493 	div = isl_mat_alloc(ctx, bmap->n_div, cols);
    494 	if (!div)
    495 		return NULL;
    496 
    497 	for (i = 0; i < bmap->n_div; ++i)
    498 		isl_seq_cpy(div->row[i], bmap->div[i], cols);
    499 
    500 	return div;
    501 }
    502 
    503 /* Extract the divs in "bset" as a matrix.
    504  */
    505 __isl_give isl_mat *isl_basic_set_get_divs(__isl_keep isl_basic_set *bset)
    506 {
    507 	return isl_basic_map_get_divs(bset);
    508 }
    509 
    510 __isl_give isl_local_space *isl_basic_map_get_local_space(
    511 	__isl_keep isl_basic_map *bmap)
    512 {
    513 	isl_mat *div;
    514 
    515 	if (!bmap)
    516 		return NULL;
    517 
    518 	div = isl_basic_map_get_divs(bmap);
    519 	return isl_local_space_alloc_div(isl_space_copy(bmap->dim), div);
    520 }
    521 
    522 __isl_give isl_local_space *isl_basic_set_get_local_space(
    523 	__isl_keep isl_basic_set *bset)
    524 {
    525 	return isl_basic_map_get_local_space(bset);
    526 }
    527 
    528 /* For each known div d = floor(f/m), add the constraints
    529  *
    530  *		f - m d >= 0
    531  *		-(f-(m-1)) + m d >= 0
    532  *
    533  * Do not finalize the result.
    534  */
    535 static __isl_give isl_basic_map *add_known_div_constraints(
    536 	__isl_take isl_basic_map *bmap)
    537 {
    538 	int i;
    539 	isl_size n_div;
    540 
    541 	n_div = isl_basic_map_dim(bmap, isl_dim_div);
    542 	if (n_div < 0)
    543 		return isl_basic_map_free(bmap);
    544 	if (n_div == 0)
    545 		return bmap;
    546 	bmap = isl_basic_map_cow(bmap);
    547 	bmap = isl_basic_map_extend_constraints(bmap, 0, 2 * n_div);
    548 	if (!bmap)
    549 		return NULL;
    550 	for (i = 0; i < n_div; ++i) {
    551 		if (isl_int_is_zero(bmap->div[i][0]))
    552 			continue;
    553 		bmap = isl_basic_map_add_div_constraints(bmap, i);
    554 	}
    555 
    556 	return bmap;
    557 }
    558 
    559 __isl_give isl_basic_map *isl_basic_map_from_local_space(
    560 	__isl_take isl_local_space *ls)
    561 {
    562 	int i;
    563 	isl_size n_div;
    564 	isl_basic_map *bmap;
    565 
    566 	n_div = isl_local_space_dim(ls, isl_dim_div);
    567 	if (n_div < 0)
    568 		ls = isl_local_space_free(ls);
    569 	if (!ls)
    570 		return NULL;
    571 
    572 	bmap = isl_basic_map_alloc_space(isl_local_space_get_space(ls),
    573 					n_div, 0, 2 * n_div);
    574 
    575 	for (i = 0; i < n_div; ++i)
    576 		if (isl_basic_map_alloc_div(bmap) < 0)
    577 			goto error;
    578 
    579 	for (i = 0; i < n_div; ++i)
    580 		isl_seq_cpy(bmap->div[i], ls->div->row[i], ls->div->n_col);
    581 	bmap = add_known_div_constraints(bmap);
    582 
    583 	isl_local_space_free(ls);
    584 	return bmap;
    585 error:
    586 	isl_local_space_free(ls);
    587 	isl_basic_map_free(bmap);
    588 	return NULL;
    589 }
    590 
    591 __isl_give isl_basic_set *isl_basic_set_from_local_space(
    592 	__isl_take isl_local_space *ls)
    593 {
    594 	return isl_basic_map_from_local_space(ls);
    595 }
    596 
    597 __isl_give isl_space *isl_map_get_space(__isl_keep isl_map *map)
    598 {
    599 	return isl_space_copy(isl_map_peek_space(map));
    600 }
    601 
    602 __isl_give isl_space *isl_set_get_space(__isl_keep isl_set *set)
    603 {
    604 	if (!set)
    605 		return NULL;
    606 	return isl_space_copy(set->dim);
    607 }
    608 
    609 /* Return the space of "map".
    610  * This may be either a copy or the space itself
    611  * if there is only one reference to "map".
    612  * This allows the space to be modified inplace
    613  * if both the map and its space have only a single reference.
    614  * The caller is not allowed to modify "map" between this call and
    615  * a subsequent call to isl_map_restore_space.
    616  * The only exception is that isl_map_free can be called instead.
    617  */
    618 static __isl_give isl_space *isl_map_take_space(__isl_keep isl_map *map)
    619 {
    620 	isl_space *space;
    621 
    622 	if (!map)
    623 		return NULL;
    624 	if (map->ref != 1)
    625 		return isl_map_get_space(map);
    626 	space = map->dim;
    627 	map->dim = NULL;
    628 	return space;
    629 }
    630 
    631 /* Set the space of "map" to "space", where the space of "map" may be missing
    632  * due to a preceding call to isl_map_take_space.
    633  * However, in this case, "map" only has a single reference and
    634  * then the call to isl_map_cow has no effect.
    635  */
    636 static __isl_give isl_map *isl_map_restore_space(__isl_take isl_map *map,
    637 	__isl_take isl_space *space)
    638 {
    639 	if (!map || !space)
    640 		goto error;
    641 
    642 	if (map->dim == space) {
    643 		isl_space_free(space);
    644 		return map;
    645 	}
    646 
    647 	map = isl_map_cow(map);
    648 	if (!map)
    649 		goto error;
    650 	isl_space_free(map->dim);
    651 	map->dim = space;
    652 
    653 	return map;
    654 error:
    655 	isl_map_free(map);
    656 	isl_space_free(space);
    657 	return NULL;
    658 }
    659 
    660 __isl_give isl_basic_map *isl_basic_map_set_tuple_name(
    661 	__isl_take isl_basic_map *bmap, enum isl_dim_type type, const char *s)
    662 {
    663 	isl_space *space;
    664 
    665 	space = isl_basic_map_take_space(bmap);
    666 	space = isl_space_set_tuple_name(space, type, s);
    667 	bmap = isl_basic_map_restore_space(bmap, space);
    668 	bmap = isl_basic_map_finalize(bmap);
    669 	return bmap;
    670 }
    671 
    672 __isl_give isl_basic_set *isl_basic_set_set_tuple_name(
    673 	__isl_take isl_basic_set *bset, const char *s)
    674 {
    675 	return isl_basic_map_set_tuple_name(bset, isl_dim_set, s);
    676 }
    677 
    678 const char *isl_basic_map_get_tuple_name(__isl_keep isl_basic_map *bmap,
    679 	enum isl_dim_type type)
    680 {
    681 	return bmap ? isl_space_get_tuple_name(bmap->dim, type) : NULL;
    682 }
    683 
    684 __isl_give isl_map *isl_map_set_tuple_name(__isl_take isl_map *map,
    685 	enum isl_dim_type type, const char *s)
    686 {
    687 	int i;
    688 	isl_space *space;
    689 
    690 	map = isl_map_cow(map);
    691 	if (!map)
    692 		return NULL;
    693 
    694 	for (i = 0; i < map->n; ++i) {
    695 		map->p[i] = isl_basic_map_set_tuple_name(map->p[i], type, s);
    696 		if (!map->p[i])
    697 			goto error;
    698 	}
    699 
    700 	space = isl_map_take_space(map);
    701 	space = isl_space_set_tuple_name(space, type, s);
    702 	map = isl_map_restore_space(map, space);
    703 
    704 	return map;
    705 error:
    706 	isl_map_free(map);
    707 	return NULL;
    708 }
    709 
    710 /* Replace the identifier of the tuple of type "type" by "id".
    711  */
    712 __isl_give isl_basic_map *isl_basic_map_set_tuple_id(
    713 	__isl_take isl_basic_map *bmap,
    714 	enum isl_dim_type type, __isl_take isl_id *id)
    715 {
    716 	isl_space *space;
    717 
    718 	space = isl_basic_map_take_space(bmap);
    719 	space = isl_space_set_tuple_id(space, type, id);
    720 	bmap = isl_basic_map_restore_space(bmap, space);
    721 	bmap = isl_basic_map_finalize(bmap);
    722 	return bmap;
    723 }
    724 
    725 /* Replace the identifier of the tuple by "id".
    726  */
    727 __isl_give isl_basic_set *isl_basic_set_set_tuple_id(
    728 	__isl_take isl_basic_set *bset, __isl_take isl_id *id)
    729 {
    730 	return isl_basic_map_set_tuple_id(bset, isl_dim_set, id);
    731 }
    732 
    733 /* Does the input or output tuple have a name?
    734  */
    735 isl_bool isl_map_has_tuple_name(__isl_keep isl_map *map, enum isl_dim_type type)
    736 {
    737 	return map ? isl_space_has_tuple_name(map->dim, type) : isl_bool_error;
    738 }
    739 
    740 const char *isl_map_get_tuple_name(__isl_keep isl_map *map,
    741 	enum isl_dim_type type)
    742 {
    743 	return map ? isl_space_get_tuple_name(map->dim, type) : NULL;
    744 }
    745 
    746 __isl_give isl_set *isl_set_set_tuple_name(__isl_take isl_set *set,
    747 	const char *s)
    748 {
    749 	return set_from_map(isl_map_set_tuple_name(set_to_map(set),
    750 						isl_dim_set, s));
    751 }
    752 
    753 __isl_give isl_map *isl_map_set_tuple_id(__isl_take isl_map *map,
    754 	enum isl_dim_type type, __isl_take isl_id *id)
    755 {
    756 	isl_space *space;
    757 
    758 	space = isl_map_take_space(map);
    759 	space = isl_space_set_tuple_id(space, type, id);
    760 	map = isl_map_restore_space(map, space);
    761 
    762 	return isl_map_reset_space(map, isl_map_get_space(map));
    763 }
    764 
    765 /* Replace the identifier of the domain tuple of "map" by "id".
    766  */
    767 __isl_give isl_map *isl_map_set_domain_tuple_id(__isl_take isl_map *map,
    768 	__isl_take isl_id *id)
    769 {
    770 	return isl_map_set_tuple_id(map, isl_dim_in, id);
    771 }
    772 
    773 /* Replace the identifier of the range tuple of "map" by "id".
    774  */
    775 __isl_give isl_map *isl_map_set_range_tuple_id(__isl_take isl_map *map,
    776 	__isl_take isl_id *id)
    777 {
    778 	return isl_map_set_tuple_id(map, isl_dim_out, id);
    779 }
    780 
    781 __isl_give isl_set *isl_set_set_tuple_id(__isl_take isl_set *set,
    782 	__isl_take isl_id *id)
    783 {
    784 	return isl_map_set_tuple_id(set, isl_dim_set, id);
    785 }
    786 
    787 __isl_give isl_map *isl_map_reset_tuple_id(__isl_take isl_map *map,
    788 	enum isl_dim_type type)
    789 {
    790 	isl_space *space;
    791 
    792 	space = isl_map_take_space(map);
    793 	space = isl_space_reset_tuple_id(space, type);
    794 	map = isl_map_restore_space(map, space);
    795 
    796 	return isl_map_reset_space(map, isl_map_get_space(map));
    797 }
    798 
    799 __isl_give isl_set *isl_set_reset_tuple_id(__isl_take isl_set *set)
    800 {
    801 	return isl_map_reset_tuple_id(set, isl_dim_set);
    802 }
    803 
    804 isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map, enum isl_dim_type type)
    805 {
    806 	return map ? isl_space_has_tuple_id(map->dim, type) : isl_bool_error;
    807 }
    808 
    809 /* Does the domain tuple of "map" have an identifier?
    810  */
    811 isl_bool isl_map_has_domain_tuple_id(__isl_keep isl_map *map)
    812 {
    813 	return isl_map_has_tuple_id(map, isl_dim_in);
    814 }
    815 
    816 /* Does the range tuple of "map" have an identifier?
    817  */
    818 isl_bool isl_map_has_range_tuple_id(__isl_keep isl_map *map)
    819 {
    820 	return isl_map_has_tuple_id(map, isl_dim_out);
    821 }
    822 
    823 __isl_give isl_id *isl_map_get_tuple_id(__isl_keep isl_map *map,
    824 	enum isl_dim_type type)
    825 {
    826 	return map ? isl_space_get_tuple_id(map->dim, type) : NULL;
    827 }
    828 
    829 /* Return the identifier of the domain tuple of "map", assuming it has one.
    830  */
    831 __isl_give isl_id *isl_map_get_domain_tuple_id(__isl_keep isl_map *map)
    832 {
    833 	return isl_map_get_tuple_id(map, isl_dim_in);
    834 }
    835 
    836 /* Return the identifier of the range tuple of "map", assuming it has one.
    837  */
    838 __isl_give isl_id *isl_map_get_range_tuple_id(__isl_keep isl_map *map)
    839 {
    840 	return isl_map_get_tuple_id(map, isl_dim_out);
    841 }
    842 
    843 isl_bool isl_set_has_tuple_id(__isl_keep isl_set *set)
    844 {
    845 	return isl_map_has_tuple_id(set, isl_dim_set);
    846 }
    847 
    848 __isl_give isl_id *isl_set_get_tuple_id(__isl_keep isl_set *set)
    849 {
    850 	return isl_map_get_tuple_id(set, isl_dim_set);
    851 }
    852 
    853 /* Does the set tuple have a name?
    854  */
    855 isl_bool isl_set_has_tuple_name(__isl_keep isl_set *set)
    856 {
    857 	if (!set)
    858 		return isl_bool_error;
    859 	return isl_space_has_tuple_name(set->dim, isl_dim_set);
    860 }
    861 
    862 
    863 const char *isl_basic_set_get_tuple_name(__isl_keep isl_basic_set *bset)
    864 {
    865 	return bset ? isl_space_get_tuple_name(bset->dim, isl_dim_set) : NULL;
    866 }
    867 
    868 const char *isl_set_get_tuple_name(__isl_keep isl_set *set)
    869 {
    870 	return set ? isl_space_get_tuple_name(set->dim, isl_dim_set) : NULL;
    871 }
    872 
    873 const char *isl_basic_map_get_dim_name(__isl_keep isl_basic_map *bmap,
    874 	enum isl_dim_type type, unsigned pos)
    875 {
    876 	return bmap ? isl_space_get_dim_name(bmap->dim, type, pos) : NULL;
    877 }
    878 
    879 const char *isl_basic_set_get_dim_name(__isl_keep isl_basic_set *bset,
    880 	enum isl_dim_type type, unsigned pos)
    881 {
    882 	return bset ? isl_space_get_dim_name(bset->dim, type, pos) : NULL;
    883 }
    884 
    885 /* Does the given dimension have a name?
    886  */
    887 isl_bool isl_map_has_dim_name(__isl_keep isl_map *map,
    888 	enum isl_dim_type type, unsigned pos)
    889 {
    890 	if (!map)
    891 		return isl_bool_error;
    892 	return isl_space_has_dim_name(map->dim, type, pos);
    893 }
    894 
    895 const char *isl_map_get_dim_name(__isl_keep isl_map *map,
    896 	enum isl_dim_type type, unsigned pos)
    897 {
    898 	return map ? isl_space_get_dim_name(map->dim, type, pos) : NULL;
    899 }
    900 
    901 const char *isl_set_get_dim_name(__isl_keep isl_set *set,
    902 	enum isl_dim_type type, unsigned pos)
    903 {
    904 	return set ? isl_space_get_dim_name(set->dim, type, pos) : NULL;
    905 }
    906 
    907 /* Does the given dimension have a name?
    908  */
    909 isl_bool isl_set_has_dim_name(__isl_keep isl_set *set,
    910 	enum isl_dim_type type, unsigned pos)
    911 {
    912 	if (!set)
    913 		return isl_bool_error;
    914 	return isl_space_has_dim_name(set->dim, type, pos);
    915 }
    916 
    917 __isl_give isl_basic_map *isl_basic_map_set_dim_name(
    918 	__isl_take isl_basic_map *bmap,
    919 	enum isl_dim_type type, unsigned pos, const char *s)
    920 {
    921 	isl_space *space;
    922 
    923 	space = isl_basic_map_take_space(bmap);
    924 	space = isl_space_set_dim_name(space, type, pos, s);
    925 	bmap = isl_basic_map_restore_space(bmap, space);
    926 	return isl_basic_map_finalize(bmap);
    927 }
    928 
    929 __isl_give isl_map *isl_map_set_dim_name(__isl_take isl_map *map,
    930 	enum isl_dim_type type, unsigned pos, const char *s)
    931 {
    932 	int i;
    933 	isl_space *space;
    934 
    935 	map = isl_map_cow(map);
    936 	if (!map)
    937 		return NULL;
    938 
    939 	for (i = 0; i < map->n; ++i) {
    940 		map->p[i] = isl_basic_map_set_dim_name(map->p[i], type, pos, s);
    941 		if (!map->p[i])
    942 			goto error;
    943 	}
    944 
    945 	space = isl_map_take_space(map);
    946 	space = isl_space_set_dim_name(space, type, pos, s);
    947 	map = isl_map_restore_space(map, space);
    948 
    949 	return map;
    950 error:
    951 	isl_map_free(map);
    952 	return NULL;
    953 }
    954 
    955 __isl_give isl_basic_set *isl_basic_set_set_dim_name(
    956 	__isl_take isl_basic_set *bset,
    957 	enum isl_dim_type type, unsigned pos, const char *s)
    958 {
    959 	return bset_from_bmap(isl_basic_map_set_dim_name(bset_to_bmap(bset),
    960 							type, pos, s));
    961 }
    962 
    963 __isl_give isl_set *isl_set_set_dim_name(__isl_take isl_set *set,
    964 	enum isl_dim_type type, unsigned pos, const char *s)
    965 {
    966 	return set_from_map(isl_map_set_dim_name(set_to_map(set),
    967 							type, pos, s));
    968 }
    969 
    970 isl_bool isl_basic_map_has_dim_id(__isl_keep isl_basic_map *bmap,
    971 	enum isl_dim_type type, unsigned pos)
    972 {
    973 	if (!bmap)
    974 		return isl_bool_error;
    975 	return isl_space_has_dim_id(bmap->dim, type, pos);
    976 }
    977 
    978 __isl_give isl_id *isl_basic_set_get_dim_id(__isl_keep isl_basic_set *bset,
    979 	enum isl_dim_type type, unsigned pos)
    980 {
    981 	return bset ? isl_space_get_dim_id(bset->dim, type, pos) : NULL;
    982 }
    983 
    984 isl_bool isl_map_has_dim_id(__isl_keep isl_map *map,
    985 	enum isl_dim_type type, unsigned pos)
    986 {
    987 	return map ? isl_space_has_dim_id(map->dim, type, pos) : isl_bool_error;
    988 }
    989 
    990 __isl_give isl_id *isl_map_get_dim_id(__isl_keep isl_map *map,
    991 	enum isl_dim_type type, unsigned pos)
    992 {
    993 	return map ? isl_space_get_dim_id(map->dim, type, pos) : NULL;
    994 }
    995 
    996 isl_bool isl_set_has_dim_id(__isl_keep isl_set *set,
    997 	enum isl_dim_type type, unsigned pos)
    998 {
    999 	return isl_map_has_dim_id(set, type, pos);
   1000 }
   1001 
   1002 __isl_give isl_id *isl_set_get_dim_id(__isl_keep isl_set *set,
   1003 	enum isl_dim_type type, unsigned pos)
   1004 {
   1005 	return isl_map_get_dim_id(set, type, pos);
   1006 }
   1007 
   1008 __isl_give isl_map *isl_map_set_dim_id(__isl_take isl_map *map,
   1009 	enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
   1010 {
   1011 	isl_space *space;
   1012 
   1013 	space = isl_map_take_space(map);
   1014 	space = isl_space_set_dim_id(space, type, pos, id);
   1015 	map = isl_map_restore_space(map, space);
   1016 
   1017 	return isl_map_reset_space(map, isl_map_get_space(map));
   1018 }
   1019 
   1020 __isl_give isl_set *isl_set_set_dim_id(__isl_take isl_set *set,
   1021 	enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
   1022 {
   1023 	return isl_map_set_dim_id(set, type, pos, id);
   1024 }
   1025 
   1026 int isl_map_find_dim_by_id(__isl_keep isl_map *map, enum isl_dim_type type,
   1027 	__isl_keep isl_id *id)
   1028 {
   1029 	if (!map)
   1030 		return -1;
   1031 	return isl_space_find_dim_by_id(map->dim, type, id);
   1032 }
   1033 
   1034 int isl_set_find_dim_by_id(__isl_keep isl_set *set, enum isl_dim_type type,
   1035 	__isl_keep isl_id *id)
   1036 {
   1037 	return isl_map_find_dim_by_id(set, type, id);
   1038 }
   1039 
   1040 /* Return the position of the dimension of the given type and name
   1041  * in "bmap".
   1042  * Return -1 if no such dimension can be found.
   1043  */
   1044 int isl_basic_map_find_dim_by_name(__isl_keep isl_basic_map *bmap,
   1045 	enum isl_dim_type type, const char *name)
   1046 {
   1047 	if (!bmap)
   1048 		return -1;
   1049 	return isl_space_find_dim_by_name(bmap->dim, type, name);
   1050 }
   1051 
   1052 int isl_map_find_dim_by_name(__isl_keep isl_map *map, enum isl_dim_type type,
   1053 	const char *name)
   1054 {
   1055 	if (!map)
   1056 		return -1;
   1057 	return isl_space_find_dim_by_name(map->dim, type, name);
   1058 }
   1059 
   1060 int isl_set_find_dim_by_name(__isl_keep isl_set *set, enum isl_dim_type type,
   1061 	const char *name)
   1062 {
   1063 	return isl_map_find_dim_by_name(set, type, name);
   1064 }
   1065 
   1066 /* Check whether equality i of bset is a pure stride constraint
   1067  * on a single dimension, i.e., of the form
   1068  *
   1069  *	v = k e
   1070  *
   1071  * with k a constant and e an existentially quantified variable.
   1072  */
   1073 isl_bool isl_basic_set_eq_is_stride(__isl_keep isl_basic_set *bset, int i)
   1074 {
   1075 	isl_size nparam;
   1076 	isl_size d;
   1077 	isl_size n_div;
   1078 	int pos1;
   1079 	int pos2;
   1080 
   1081 	nparam = isl_basic_set_dim(bset, isl_dim_param);
   1082 	d = isl_basic_set_dim(bset, isl_dim_set);
   1083 	n_div = isl_basic_set_dim(bset, isl_dim_div);
   1084 	if (nparam < 0 || d < 0 || n_div < 0)
   1085 		return isl_bool_error;
   1086 
   1087 	if (!isl_int_is_zero(bset->eq[i][0]))
   1088 		return isl_bool_false;
   1089 
   1090 	if (isl_seq_first_non_zero(bset->eq[i] + 1, nparam) != -1)
   1091 		return isl_bool_false;
   1092 	pos1 = isl_seq_first_non_zero(bset->eq[i] + 1 + nparam, d);
   1093 	if (pos1 == -1)
   1094 		return isl_bool_false;
   1095 	if (isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + pos1 + 1,
   1096 					d - pos1 - 1) != -1)
   1097 		return isl_bool_false;
   1098 
   1099 	pos2 = isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + d, n_div);
   1100 	if (pos2 == -1)
   1101 		return isl_bool_false;
   1102 	if (isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + d  + pos2 + 1,
   1103 				   n_div - pos2 - 1) != -1)
   1104 		return isl_bool_false;
   1105 	if (!isl_int_is_one(bset->eq[i][1 + nparam + pos1]) &&
   1106 	    !isl_int_is_negone(bset->eq[i][1 + nparam + pos1]))
   1107 		return isl_bool_false;
   1108 
   1109 	return isl_bool_true;
   1110 }
   1111 
   1112 /* Reset the user pointer on all identifiers of parameters and tuples
   1113  * of the space of "map".
   1114  */
   1115 __isl_give isl_map *isl_map_reset_user(__isl_take isl_map *map)
   1116 {
   1117 	isl_space *space;
   1118 
   1119 	space = isl_map_get_space(map);
   1120 	space = isl_space_reset_user(space);
   1121 	map = isl_map_reset_space(map, space);
   1122 
   1123 	return map;
   1124 }
   1125 
   1126 /* Reset the user pointer on all identifiers of parameters and tuples
   1127  * of the space of "set".
   1128  */
   1129 __isl_give isl_set *isl_set_reset_user(__isl_take isl_set *set)
   1130 {
   1131 	return isl_map_reset_user(set);
   1132 }
   1133 
   1134 isl_bool isl_basic_map_is_rational(__isl_keep isl_basic_map *bmap)
   1135 {
   1136 	if (!bmap)
   1137 		return isl_bool_error;
   1138 	return ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
   1139 }
   1140 
   1141 /* Has "map" been marked as a rational map?
   1142  * In particular, have all basic maps in "map" been marked this way?
   1143  * An empty map is not considered to be rational.
   1144  * Maps where only some of the basic maps are marked rational
   1145  * are not allowed.
   1146  */
   1147 isl_bool isl_map_is_rational(__isl_keep isl_map *map)
   1148 {
   1149 	int i;
   1150 	isl_bool rational;
   1151 
   1152 	if (!map)
   1153 		return isl_bool_error;
   1154 	if (map->n == 0)
   1155 		return isl_bool_false;
   1156 	rational = isl_basic_map_is_rational(map->p[0]);
   1157 	if (rational < 0)
   1158 		return rational;
   1159 	for (i = 1; i < map->n; ++i) {
   1160 		isl_bool rational_i;
   1161 
   1162 		rational_i = isl_basic_map_is_rational(map->p[i]);
   1163 		if (rational_i < 0)
   1164 			return rational_i;
   1165 		if (rational != rational_i)
   1166 			isl_die(isl_map_get_ctx(map), isl_error_unsupported,
   1167 				"mixed rational and integer basic maps "
   1168 				"not supported", return isl_bool_error);
   1169 	}
   1170 
   1171 	return rational;
   1172 }
   1173 
   1174 /* Has "set" been marked as a rational set?
   1175  * In particular, have all basic set in "set" been marked this way?
   1176  * An empty set is not considered to be rational.
   1177  * Sets where only some of the basic sets are marked rational
   1178  * are not allowed.
   1179  */
   1180 isl_bool isl_set_is_rational(__isl_keep isl_set *set)
   1181 {
   1182 	return isl_map_is_rational(set);
   1183 }
   1184 
   1185 int isl_basic_set_is_rational(__isl_keep isl_basic_set *bset)
   1186 {
   1187 	return isl_basic_map_is_rational(bset);
   1188 }
   1189 
   1190 /* Does "bmap" contain any rational points?
   1191  *
   1192  * If "bmap" has an equality for each dimension, equating the dimension
   1193  * to an integer constant, then it has no rational points, even if it
   1194  * is marked as rational.
   1195  */
   1196 isl_bool isl_basic_map_has_rational(__isl_keep isl_basic_map *bmap)
   1197 {
   1198 	isl_bool has_rational = isl_bool_true;
   1199 	isl_size total;
   1200 
   1201 	if (!bmap)
   1202 		return isl_bool_error;
   1203 	if (isl_basic_map_plain_is_empty(bmap))
   1204 		return isl_bool_false;
   1205 	if (!isl_basic_map_is_rational(bmap))
   1206 		return isl_bool_false;
   1207 	bmap = isl_basic_map_copy(bmap);
   1208 	bmap = isl_basic_map_implicit_equalities(bmap);
   1209 	total = isl_basic_map_dim(bmap, isl_dim_all);
   1210 	if (total < 0)
   1211 		return isl_bool_error;
   1212 	if (bmap->n_eq == total) {
   1213 		int i, j;
   1214 		for (i = 0; i < bmap->n_eq; ++i) {
   1215 			j = isl_seq_first_non_zero(bmap->eq[i] + 1, total);
   1216 			if (j < 0)
   1217 				break;
   1218 			if (!isl_int_is_one(bmap->eq[i][1 + j]) &&
   1219 			    !isl_int_is_negone(bmap->eq[i][1 + j]))
   1220 				break;
   1221 			j = isl_seq_first_non_zero(bmap->eq[i] + 1 + j + 1,
   1222 						    total - j - 1);
   1223 			if (j >= 0)
   1224 				break;
   1225 		}
   1226 		if (i == bmap->n_eq)
   1227 			has_rational = isl_bool_false;
   1228 	}
   1229 	isl_basic_map_free(bmap);
   1230 
   1231 	return has_rational;
   1232 }
   1233 
   1234 /* Does "map" contain any rational points?
   1235  */
   1236 isl_bool isl_map_has_rational(__isl_keep isl_map *map)
   1237 {
   1238 	int i;
   1239 	isl_bool has_rational;
   1240 
   1241 	if (!map)
   1242 		return isl_bool_error;
   1243 	for (i = 0; i < map->n; ++i) {
   1244 		has_rational = isl_basic_map_has_rational(map->p[i]);
   1245 		if (has_rational < 0 || has_rational)
   1246 			return has_rational;
   1247 	}
   1248 	return isl_bool_false;
   1249 }
   1250 
   1251 /* Does "set" contain any rational points?
   1252  */
   1253 isl_bool isl_set_has_rational(__isl_keep isl_set *set)
   1254 {
   1255 	return isl_map_has_rational(set);
   1256 }
   1257 
   1258 /* Is this basic set a parameter domain?
   1259  */
   1260 isl_bool isl_basic_set_is_params(__isl_keep isl_basic_set *bset)
   1261 {
   1262 	if (!bset)
   1263 		return isl_bool_error;
   1264 	return isl_space_is_params(bset->dim);
   1265 }
   1266 
   1267 /* Is this set a parameter domain?
   1268  */
   1269 isl_bool isl_set_is_params(__isl_keep isl_set *set)
   1270 {
   1271 	if (!set)
   1272 		return isl_bool_error;
   1273 	return isl_space_is_params(set->dim);
   1274 }
   1275 
   1276 /* Is this map actually a parameter domain?
   1277  * Users should never call this function.  Outside of isl,
   1278  * a map can never be a parameter domain.
   1279  */
   1280 isl_bool isl_map_is_params(__isl_keep isl_map *map)
   1281 {
   1282 	if (!map)
   1283 		return isl_bool_error;
   1284 	return isl_space_is_params(map->dim);
   1285 }
   1286 
   1287 static __isl_give isl_basic_map *basic_map_init(isl_ctx *ctx,
   1288 	__isl_take isl_basic_map *bmap, unsigned extra,
   1289 	unsigned n_eq, unsigned n_ineq)
   1290 {
   1291 	int i;
   1292 	isl_space *space = isl_basic_map_peek_space(bmap);
   1293 	isl_size n_var = isl_space_dim(space, isl_dim_all);
   1294 	size_t row_size = 1 + n_var + extra;
   1295 
   1296 	bmap->ctx = ctx;
   1297 	isl_ctx_ref(ctx);
   1298 
   1299 	if (n_var < 0)
   1300 		return isl_basic_map_free(bmap);
   1301 
   1302 	bmap->block = isl_blk_alloc(ctx, (n_ineq + n_eq) * row_size);
   1303 	if (isl_blk_is_error(bmap->block))
   1304 		goto error;
   1305 
   1306 	bmap->ineq = isl_alloc_array(ctx, isl_int *, n_ineq + n_eq);
   1307 	if ((n_ineq + n_eq) && !bmap->ineq)
   1308 		goto error;
   1309 
   1310 	if (extra == 0) {
   1311 		bmap->block2 = isl_blk_empty();
   1312 		bmap->div = NULL;
   1313 	} else {
   1314 		bmap->block2 = isl_blk_alloc(ctx, extra * (1 + row_size));
   1315 		if (isl_blk_is_error(bmap->block2))
   1316 			goto error;
   1317 
   1318 		bmap->div = isl_alloc_array(ctx, isl_int *, extra);
   1319 		if (!bmap->div)
   1320 			goto error;
   1321 	}
   1322 
   1323 	for (i = 0; i < n_ineq + n_eq; ++i)
   1324 		bmap->ineq[i] = bmap->block.data + i * row_size;
   1325 
   1326 	for (i = 0; i < extra; ++i)
   1327 		bmap->div[i] = bmap->block2.data + i * (1 + row_size);
   1328 
   1329 	bmap->ref = 1;
   1330 	bmap->flags = 0;
   1331 	bmap->c_size = n_eq + n_ineq;
   1332 	bmap->eq = bmap->ineq + n_ineq;
   1333 	bmap->extra = extra;
   1334 	bmap->n_eq = 0;
   1335 	bmap->n_ineq = 0;
   1336 	bmap->n_div = 0;
   1337 	bmap->sample = NULL;
   1338 
   1339 	return bmap;
   1340 error:
   1341 	isl_basic_map_free(bmap);
   1342 	return NULL;
   1343 }
   1344 
   1345 __isl_give isl_basic_set *isl_basic_set_alloc(isl_ctx *ctx,
   1346 		unsigned nparam, unsigned dim, unsigned extra,
   1347 		unsigned n_eq, unsigned n_ineq)
   1348 {
   1349 	struct isl_basic_map *bmap;
   1350 	isl_space *space;
   1351 
   1352 	space = isl_space_set_alloc(ctx, nparam, dim);
   1353 	if (!space)
   1354 		return NULL;
   1355 
   1356 	bmap = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
   1357 	return bset_from_bmap(bmap);
   1358 }
   1359 
   1360 __isl_give isl_basic_set *isl_basic_set_alloc_space(__isl_take isl_space *space,
   1361 		unsigned extra, unsigned n_eq, unsigned n_ineq)
   1362 {
   1363 	struct isl_basic_map *bmap;
   1364 	if (!space)
   1365 		return NULL;
   1366 	isl_assert(space->ctx, space->n_in == 0, goto error);
   1367 	bmap = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
   1368 	return bset_from_bmap(bmap);
   1369 error:
   1370 	isl_space_free(space);
   1371 	return NULL;
   1372 }
   1373 
   1374 __isl_give isl_basic_map *isl_basic_map_alloc_space(__isl_take isl_space *space,
   1375 		unsigned extra, unsigned n_eq, unsigned n_ineq)
   1376 {
   1377 	struct isl_basic_map *bmap;
   1378 
   1379 	if (!space)
   1380 		return NULL;
   1381 	bmap = isl_calloc_type(space->ctx, struct isl_basic_map);
   1382 	if (!bmap)
   1383 		goto error;
   1384 	bmap->dim = space;
   1385 
   1386 	return basic_map_init(space->ctx, bmap, extra, n_eq, n_ineq);
   1387 error:
   1388 	isl_space_free(space);
   1389 	return NULL;
   1390 }
   1391 
   1392 __isl_give isl_basic_map *isl_basic_map_alloc(isl_ctx *ctx,
   1393 		unsigned nparam, unsigned in, unsigned out, unsigned extra,
   1394 		unsigned n_eq, unsigned n_ineq)
   1395 {
   1396 	struct isl_basic_map *bmap;
   1397 	isl_space *space;
   1398 
   1399 	space = isl_space_alloc(ctx, nparam, in, out);
   1400 	if (!space)
   1401 		return NULL;
   1402 
   1403 	bmap = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
   1404 	return bmap;
   1405 }
   1406 
   1407 static __isl_give isl_basic_map *dup_constraints(__isl_take isl_basic_map *dst,
   1408 	__isl_keep isl_basic_map *src)
   1409 {
   1410 	int i;
   1411 	isl_size total = isl_basic_map_dim(src, isl_dim_all);
   1412 
   1413 	if (!dst || total < 0)
   1414 		return isl_basic_map_free(dst);
   1415 
   1416 	for (i = 0; i < src->n_eq; ++i) {
   1417 		int j = isl_basic_map_alloc_equality(dst);
   1418 		if (j < 0)
   1419 			return isl_basic_map_free(dst);
   1420 		isl_seq_cpy(dst->eq[j], src->eq[i], 1+total);
   1421 	}
   1422 
   1423 	for (i = 0; i < src->n_ineq; ++i) {
   1424 		int j = isl_basic_map_alloc_inequality(dst);
   1425 		if (j < 0)
   1426 			return isl_basic_map_free(dst);
   1427 		isl_seq_cpy(dst->ineq[j], src->ineq[i], 1+total);
   1428 	}
   1429 
   1430 	for (i = 0; i < src->n_div; ++i) {
   1431 		int j = isl_basic_map_alloc_div(dst);
   1432 		if (j < 0)
   1433 			return isl_basic_map_free(dst);
   1434 		isl_seq_cpy(dst->div[j], src->div[i], 1+1+total);
   1435 	}
   1436 	ISL_F_SET(dst, ISL_BASIC_SET_FINAL);
   1437 	return dst;
   1438 }
   1439 
   1440 __isl_give isl_basic_map *isl_basic_map_dup(__isl_keep isl_basic_map *bmap)
   1441 {
   1442 	struct isl_basic_map *dup;
   1443 
   1444 	if (!bmap)
   1445 		return NULL;
   1446 	dup = isl_basic_map_alloc_space(isl_space_copy(bmap->dim),
   1447 			bmap->n_div, bmap->n_eq, bmap->n_ineq);
   1448 	dup = dup_constraints(dup, bmap);
   1449 	if (!dup)
   1450 		return NULL;
   1451 	dup->flags = bmap->flags;
   1452 	dup->sample = isl_vec_copy(bmap->sample);
   1453 	return dup;
   1454 }
   1455 
   1456 __isl_give isl_basic_set *isl_basic_set_dup(__isl_keep isl_basic_set *bset)
   1457 {
   1458 	struct isl_basic_map *dup;
   1459 
   1460 	dup = isl_basic_map_dup(bset_to_bmap(bset));
   1461 	return bset_from_bmap(dup);
   1462 }
   1463 
   1464 __isl_give isl_basic_set *isl_basic_set_copy(__isl_keep isl_basic_set *bset)
   1465 {
   1466 	return bset_from_bmap(isl_basic_map_copy(bset_to_bmap(bset)));
   1467 }
   1468 
   1469 __isl_give isl_set *isl_set_copy(__isl_keep isl_set *set)
   1470 {
   1471 	if (!set)
   1472 		return NULL;
   1473 
   1474 	set->ref++;
   1475 	return set;
   1476 }
   1477 
   1478 __isl_give isl_basic_map *isl_basic_map_copy(__isl_keep isl_basic_map *bmap)
   1479 {
   1480 	if (!bmap)
   1481 		return NULL;
   1482 
   1483 	if (ISL_F_ISSET(bmap, ISL_BASIC_SET_FINAL)) {
   1484 		bmap->ref++;
   1485 		return bmap;
   1486 	}
   1487 	bmap = isl_basic_map_dup(bmap);
   1488 	if (bmap)
   1489 		ISL_F_SET(bmap, ISL_BASIC_SET_FINAL);
   1490 	return bmap;
   1491 }
   1492 
   1493 __isl_give isl_map *isl_map_copy(__isl_keep isl_map *map)
   1494 {
   1495 	if (!map)
   1496 		return NULL;
   1497 
   1498 	map->ref++;
   1499 	return map;
   1500 }
   1501 
   1502 __isl_null isl_basic_map *isl_basic_map_free(__isl_take isl_basic_map *bmap)
   1503 {
   1504 	if (!bmap)
   1505 		return NULL;
   1506 
   1507 	if (--bmap->ref > 0)
   1508 		return NULL;
   1509 
   1510 	isl_ctx_deref(bmap->ctx);
   1511 	free(bmap->div);
   1512 	isl_blk_free(bmap->ctx, bmap->block2);
   1513 	free(bmap->ineq);
   1514 	isl_blk_free(bmap->ctx, bmap->block);
   1515 	isl_vec_free(bmap->sample);
   1516 	isl_space_free(bmap->dim);
   1517 	free(bmap);
   1518 
   1519 	return NULL;
   1520 }
   1521 
   1522 __isl_null isl_basic_set *isl_basic_set_free(__isl_take isl_basic_set *bset)
   1523 {
   1524 	return isl_basic_map_free(bset_to_bmap(bset));
   1525 }
   1526 
   1527 static int room_for_con(__isl_keep isl_basic_map *bmap, unsigned n)
   1528 {
   1529 	return bmap->n_eq + bmap->n_ineq + n <= bmap->c_size;
   1530 }
   1531 
   1532 /* Check that "bset" does not involve any parameters.
   1533  */
   1534 isl_stat isl_basic_set_check_no_params(__isl_keep isl_basic_set *bset)
   1535 {
   1536 	isl_size nparam;
   1537 
   1538 	nparam = isl_basic_set_dim(bset, isl_dim_param);
   1539 	if (nparam < 0)
   1540 		return isl_stat_error;
   1541 	if (nparam != 0)
   1542 		isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,
   1543 			"basic set should not have any parameters",
   1544 			return isl_stat_error);
   1545 	return isl_stat_ok;
   1546 }
   1547 
   1548 /* Check that "bset" does not involve any local variables.
   1549  */
   1550 isl_stat isl_basic_set_check_no_locals(__isl_keep isl_basic_set *bset)
   1551 {
   1552 	isl_size n_div;
   1553 
   1554 	n_div = isl_basic_set_dim(bset, isl_dim_div);
   1555 	if (n_div < 0)
   1556 		return isl_stat_error;
   1557 	if (n_div != 0)
   1558 		isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,
   1559 			"basic set should not have any local variables",
   1560 			return isl_stat_error);
   1561 	return isl_stat_ok;
   1562 }
   1563 
   1564 #undef TYPE
   1565 #define TYPE isl_map
   1566 
   1567 #include "isl_check_named_params_templ.c"
   1568 
   1569 #undef TYPE
   1570 #define TYPE isl_basic_map
   1571 
   1572 static
   1573 #include "isl_check_named_params_templ.c"
   1574 
   1575 /* Check that "bmap1" and "bmap2" have the same parameters,
   1576  * reporting an error if they do not.
   1577  */
   1578 static isl_stat isl_basic_map_check_equal_params(
   1579 	__isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2)
   1580 {
   1581 	isl_bool match;
   1582 
   1583 	match = isl_basic_map_has_equal_params(bmap1, bmap2);
   1584 	if (match < 0)
   1585 		return isl_stat_error;
   1586 	if (!match)
   1587 		isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,
   1588 			"parameters don't match", return isl_stat_error);
   1589 	return isl_stat_ok;
   1590 }
   1591 
   1592 #undef TYPE
   1593 #define TYPE	isl_map
   1594 
   1595 #include "isl_align_params_bin_templ.c"
   1596 
   1597 #undef SUFFIX
   1598 #define SUFFIX	set
   1599 #undef ARG1
   1600 #define ARG1	isl_map
   1601 #undef ARG2
   1602 #define ARG2	isl_set
   1603 
   1604 #include "isl_align_params_templ.c"
   1605 
   1606 isl_bool isl_map_align_params_map_map_and_test(__isl_keep isl_map *map1,
   1607 	__isl_keep isl_map *map2,
   1608 	isl_bool (*fn)(__isl_keep isl_map *map1, __isl_keep isl_map *map2))
   1609 {
   1610 	isl_bool r;
   1611 
   1612 	if (!map1 || !map2)
   1613 		return isl_bool_error;
   1614 	if (isl_map_has_equal_params(map1, map2))
   1615 		return fn(map1, map2);
   1616 	if (isl_map_check_named_params(map1) < 0)
   1617 		return isl_bool_error;
   1618 	if (isl_map_check_named_params(map2) < 0)
   1619 		return isl_bool_error;
   1620 	map1 = isl_map_copy(map1);
   1621 	map2 = isl_map_copy(map2);
   1622 	map1 = isl_map_align_params(map1, isl_map_get_space(map2));
   1623 	map2 = isl_map_align_params(map2, isl_map_get_space(map1));
   1624 	r = fn(map1, map2);
   1625 	isl_map_free(map1);
   1626 	isl_map_free(map2);
   1627 	return r;
   1628 }
   1629 
   1630 int isl_basic_map_alloc_equality(__isl_keep isl_basic_map *bmap)
   1631 {
   1632 	isl_size total;
   1633 	struct isl_ctx *ctx;
   1634 
   1635 	total = isl_basic_map_dim(bmap, isl_dim_all);
   1636 	if (total < 0)
   1637 		return -1;
   1638 	ctx = bmap->ctx;
   1639 	isl_assert(ctx, room_for_con(bmap, 1), return -1);
   1640 	isl_assert(ctx, (bmap->eq - bmap->ineq) + bmap->n_eq <= bmap->c_size,
   1641 			return -1);
   1642 	ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
   1643 	ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT);
   1644 	ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES);
   1645 	ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
   1646 	if ((bmap->eq - bmap->ineq) + bmap->n_eq == bmap->c_size) {
   1647 		isl_int *t;
   1648 		int j = isl_basic_map_alloc_inequality(bmap);
   1649 		if (j < 0)
   1650 			return -1;
   1651 		t = bmap->ineq[j];
   1652 		bmap->ineq[j] = bmap->ineq[bmap->n_ineq - 1];
   1653 		bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
   1654 		bmap->eq[-1] = t;
   1655 		bmap->n_eq++;
   1656 		bmap->n_ineq--;
   1657 		bmap->eq--;
   1658 		return 0;
   1659 	}
   1660 	isl_seq_clr(bmap->eq[bmap->n_eq] + 1 + total,
   1661 		      bmap->extra - bmap->n_div);
   1662 	return bmap->n_eq++;
   1663 }
   1664 
   1665 int isl_basic_set_alloc_equality(__isl_keep isl_basic_set *bset)
   1666 {
   1667 	return isl_basic_map_alloc_equality(bset_to_bmap(bset));
   1668 }
   1669 
   1670 __isl_give isl_basic_map *isl_basic_map_free_equality(
   1671 	__isl_take isl_basic_map *bmap, unsigned n)
   1672 {
   1673 	if (!bmap)
   1674 		return NULL;
   1675 	if (n > bmap->n_eq)
   1676 		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
   1677 			"invalid number of equalities",
   1678 			isl_basic_map_free(bmap));
   1679 	bmap->n_eq -= n;
   1680 	return bmap;
   1681 }
   1682 
   1683 __isl_give isl_basic_set *isl_basic_set_free_equality(
   1684 	__isl_take isl_basic_set *bset, unsigned n)
   1685 {
   1686 	return bset_from_bmap(isl_basic_map_free_equality(bset_to_bmap(bset),
   1687 							    n));
   1688 }
   1689 
   1690 /* Drop the equality constraint at position "pos",
   1691  * preserving the order of the other equality constraints.
   1692  */
   1693 int isl_basic_map_drop_equality(__isl_keep isl_basic_map *bmap, unsigned pos)
   1694 {
   1695 	isl_int *t;
   1696 	int r;
   1697 
   1698 	if (!bmap)
   1699 		return -1;
   1700 	isl_assert(bmap->ctx, pos < bmap->n_eq, return -1);
   1701 
   1702 	t = bmap->eq[pos];
   1703 	bmap->n_eq--;
   1704 	for (r = pos; r < bmap->n_eq; ++r)
   1705 		bmap->eq[r] = bmap->eq[r + 1];
   1706 	bmap->eq[bmap->n_eq] = t;
   1707 
   1708 	return 0;
   1709 }
   1710 
   1711 /* Turn inequality "pos" of "bmap" into an equality.
   1712  *
   1713  * In particular, we move the inequality in front of the equalities
   1714  * and move the last inequality in the position of the moved inequality.
   1715  * Note that isl_tab_make_equalities_explicit depends on this particular
   1716  * change in the ordering of the constraints.
   1717  */
   1718 void isl_basic_map_inequality_to_equality(
   1719 		__isl_keep isl_basic_map *bmap, unsigned pos)
   1720 {
   1721 	isl_int *t;
   1722 
   1723 	t = bmap->ineq[pos];
   1724 	bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
   1725 	bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
   1726 	bmap->eq[-1] = t;
   1727 	bmap->n_eq++;
   1728 	bmap->n_ineq--;
   1729 	bmap->eq--;
   1730 	ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
   1731 	ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
   1732 	ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
   1733 	ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES);
   1734 }
   1735 
   1736 static int room_for_ineq(__isl_keep isl_basic_map *bmap, unsigned n)
   1737 {
   1738 	return bmap->n_ineq + n <= bmap->eq - bmap->ineq;
   1739 }
   1740 
   1741 int isl_basic_map_alloc_inequality(__isl_keep isl_basic_map *bmap)
   1742 {
   1743 	isl_size total;
   1744 	struct isl_ctx *ctx;
   1745 
   1746 	total = isl_basic_map_dim(bmap, isl_dim_all);
   1747 	if (total < 0)
   1748 		return -1;
   1749 	ctx = bmap->ctx;
   1750 	isl_assert(ctx, room_for_ineq(bmap, 1), return -1);
   1751 	ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT);
   1752 	ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
   1753 	ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
   1754 	ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES);
   1755 	isl_seq_clr(bmap->ineq[bmap->n_ineq] + 1 + total,
   1756 		      bmap->extra - bmap->n_div);
   1757 	return bmap->n_ineq++;
   1758 }
   1759 
   1760 int isl_basic_set_alloc_inequality(__isl_keep isl_basic_set *bset)
   1761 {
   1762 	return isl_basic_map_alloc_inequality(bset_to_bmap(bset));
   1763 }
   1764 
   1765 __isl_give isl_basic_map *isl_basic_map_free_inequality(
   1766 	__isl_take isl_basic_map *bmap, unsigned n)
   1767 {
   1768 	if (!bmap)
   1769 		return NULL;
   1770 	if (n > bmap->n_ineq)
   1771 		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
   1772 			"invalid number of inequalities",
   1773 			return isl_basic_map_free(bmap));
   1774 	bmap->n_ineq -= n;
   1775 	return bmap;
   1776 }
   1777 
   1778 __isl_give isl_basic_set *isl_basic_set_free_inequality(
   1779 	__isl_take isl_basic_set *bset, unsigned n)
   1780 {
   1781 	return bset_from_bmap(isl_basic_map_free_inequality(bset_to_bmap(bset),
   1782 							    n));
   1783 }
   1784 
   1785 int isl_basic_map_drop_inequality(__isl_keep isl_basic_map *bmap, unsigned pos)
   1786 {
   1787 	isl_int *t;
   1788 	if (!bmap)
   1789 		return -1;
   1790 	isl_assert(bmap->ctx, pos < bmap->n_ineq, return -1);
   1791 
   1792 	if (pos != bmap->n_ineq - 1) {
   1793 		t = bmap->ineq[pos];
   1794 		bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
   1795 		bmap->ineq[bmap->n_ineq - 1] = t;
   1796 		ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
   1797 	}
   1798 	bmap->n_ineq--;
   1799 	return 0;
   1800 }
   1801 
   1802 int isl_basic_set_drop_inequality(__isl_keep isl_basic_set *bset, unsigned pos)
   1803 {
   1804 	return isl_basic_map_drop_inequality(bset_to_bmap(bset), pos);
   1805 }
   1806 
   1807 __isl_give isl_basic_map *isl_basic_map_add_eq(__isl_take isl_basic_map *bmap,
   1808 	isl_int *eq)
   1809 {
   1810 	isl_bool empty;
   1811 	isl_size total;
   1812 	int k;
   1813 
   1814 	empty = isl_basic_map_plain_is_empty(bmap);
   1815 	if (empty < 0)
   1816 		return isl_basic_map_free(bmap);
   1817 	if (empty)
   1818 		return bmap;
   1819 
   1820 	bmap = isl_basic_map_cow(bmap);
   1821 	bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
   1822 	total = isl_basic_map_dim(bmap, isl_dim_all);
   1823 	if (total < 0)
   1824 		return isl_basic_map_free(bmap);
   1825 	k = isl_basic_map_alloc_equality(bmap);
   1826 	if (k < 0)
   1827 		goto error;
   1828 	isl_seq_cpy(bmap->eq[k], eq, 1 + total);
   1829 	return bmap;
   1830 error:
   1831 	isl_basic_map_free(bmap);
   1832 	return NULL;
   1833 }
   1834 
   1835 __isl_give isl_basic_set *isl_basic_set_add_eq(__isl_take isl_basic_set *bset,
   1836 	isl_int *eq)
   1837 {
   1838 	return bset_from_bmap(isl_basic_map_add_eq(bset_to_bmap(bset), eq));
   1839 }
   1840 
   1841 __isl_give isl_basic_map *isl_basic_map_add_ineq(__isl_take isl_basic_map *bmap,
   1842 	isl_int *ineq)
   1843 {
   1844 	isl_size total;
   1845 	int k;
   1846 
   1847 	bmap = isl_basic_map_cow(bmap);
   1848 	bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
   1849 	total = isl_basic_map_dim(bmap, isl_dim_all);
   1850 	if (total < 0)
   1851 		return isl_basic_map_free(bmap);
   1852 	k = isl_basic_map_alloc_inequality(bmap);
   1853 	if (k < 0)
   1854 		goto error;
   1855 	isl_seq_cpy(bmap->ineq[k], ineq, 1 + total);
   1856 	return bmap;
   1857 error:
   1858 	isl_basic_map_free(bmap);
   1859 	return NULL;
   1860 }
   1861 
   1862 __isl_give isl_basic_set *isl_basic_set_add_ineq(__isl_take isl_basic_set *bset,
   1863 	isl_int *ineq)
   1864 {
   1865 	return bset_from_bmap(isl_basic_map_add_ineq(bset_to_bmap(bset), ineq));
   1866 }
   1867 
   1868 int isl_basic_map_alloc_div(__isl_keep isl_basic_map *bmap)
   1869 {
   1870 	isl_size total;
   1871 
   1872 	total = isl_basic_map_dim(bmap, isl_dim_all);
   1873 	if (total < 0)
   1874 		return -1;
   1875 	isl_assert(bmap->ctx, bmap->n_div < bmap->extra, return -1);
   1876 	isl_seq_clr(bmap->div[bmap->n_div] + 1 + 1 + total,
   1877 		      bmap->extra - bmap->n_div);
   1878 	ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
   1879 	return bmap->n_div++;
   1880 }
   1881 
   1882 int isl_basic_set_alloc_div(__isl_keep isl_basic_set *bset)
   1883 {
   1884 	return isl_basic_map_alloc_div(bset_to_bmap(bset));
   1885 }
   1886 
   1887 #undef TYPE
   1888 #define TYPE	isl_basic_map
   1889 #include "check_type_range_templ.c"
   1890 
   1891 /* Check that there are "n" dimensions of type "type" starting at "first"
   1892  * in "bset".
   1893  */
   1894 isl_stat isl_basic_set_check_range(__isl_keep isl_basic_set *bset,
   1895 	enum isl_dim_type type, unsigned first, unsigned n)
   1896 {
   1897 	return isl_basic_map_check_range(bset_to_bmap(bset),
   1898 					type, first, n);
   1899 }
   1900 
   1901 /* Insert an extra integer division, prescribed by "div", to "bmap"
   1902  * at (integer division) position "pos".
   1903  *
   1904  * The integer division is first added at the end and then moved
   1905  * into the right position.
   1906  */
   1907 __isl_give isl_basic_map *isl_basic_map_insert_div(
   1908 	__isl_take isl_basic_map *bmap, int pos, __isl_keep isl_vec *div)
   1909 {
   1910 	int i, k;
   1911 	isl_size total;
   1912 
   1913 	bmap = isl_basic_map_cow(bmap);
   1914 	total = isl_basic_map_dim(bmap, isl_dim_all);
   1915 	if (total < 0 || !div)
   1916 		return isl_basic_map_free(bmap);
   1917 
   1918 	if (div->size != 1 + 1 + total)
   1919 		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
   1920 			"unexpected size", return isl_basic_map_free(bmap));
   1921 	if (isl_basic_map_check_range(bmap, isl_dim_div, pos, 0) < 0)
   1922 		return isl_basic_map_free(bmap);
   1923 
   1924 	bmap = isl_basic_map_extend(bmap, 1, 0, 2);
   1925 	k = isl_basic_map_alloc_div(bmap);
   1926 	if (k < 0)
   1927 		return isl_basic_map_free(bmap);
   1928 	isl_seq_cpy(bmap->div[k], div->el, div->size);
   1929 	isl_int_set_si(bmap->div[k][div->size], 0);
   1930 
   1931 	for (i = k; i > pos; --i)
   1932 		bmap = isl_basic_map_swap_div(bmap, i, i - 1);
   1933 
   1934 	return bmap;
   1935 }
   1936 
   1937 isl_stat isl_basic_map_free_div(__isl_keep isl_basic_map *bmap, unsigned n)
   1938 {
   1939 	if (!bmap)
   1940 		return isl_stat_error;
   1941 	isl_assert(bmap->ctx, n <= bmap->n_div, return isl_stat_error);
   1942 	bmap->n_div -= n;
   1943 	return isl_stat_ok;
   1944 }
   1945 
   1946 static __isl_give isl_basic_map *add_constraints(
   1947 	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2,
   1948 	unsigned i_pos, unsigned o_pos)
   1949 {
   1950 	isl_size total, n_param, n_in, n_out, n_div;
   1951 	unsigned o_in, o_out;
   1952 	isl_ctx *ctx;
   1953 	isl_space *space;
   1954 	struct isl_dim_map *dim_map;
   1955 
   1956 	space = isl_basic_map_peek_space(bmap2);
   1957 	if (!bmap1 || !space)
   1958 		goto error;
   1959 
   1960 	total = isl_basic_map_dim(bmap1, isl_dim_all);
   1961 	n_param = isl_basic_map_dim(bmap2, isl_dim_param);
   1962 	n_in = isl_basic_map_dim(bmap2, isl_dim_in);
   1963 	o_in = isl_basic_map_offset(bmap1, isl_dim_in) - 1 + i_pos;
   1964 	n_out = isl_basic_map_dim(bmap2, isl_dim_out);
   1965 	o_out = isl_basic_map_offset(bmap1, isl_dim_out) - 1 + o_pos;
   1966 	n_div = isl_basic_map_dim(bmap2, isl_dim_div);
   1967 	if (total < 0 || n_param < 0 || n_in < 0 || n_out < 0 || n_div < 0)
   1968 		goto error;
   1969 	ctx = isl_basic_map_get_ctx(bmap1);
   1970 	dim_map = isl_dim_map_alloc(ctx, total + n_div);
   1971 	isl_dim_map_dim_range(dim_map, space, isl_dim_param, 0, n_param, 0);
   1972 	isl_dim_map_dim_range(dim_map, space, isl_dim_in, 0, n_in, o_in);
   1973 	isl_dim_map_dim_range(dim_map, space, isl_dim_out, 0, n_out, o_out);
   1974 	isl_dim_map_div(dim_map, bmap2, total);
   1975 
   1976 	return isl_basic_map_add_constraints_dim_map(bmap1, bmap2, dim_map);
   1977 error:
   1978 	isl_basic_map_free(bmap1);
   1979 	isl_basic_map_free(bmap2);
   1980 	return NULL;
   1981 }
   1982 
   1983 __isl_give isl_basic_map *isl_basic_map_extend(__isl_take isl_basic_map *base,
   1984 	unsigned extra, unsigned n_eq, unsigned n_ineq)
   1985 {
   1986 	isl_space *space;
   1987 	struct isl_basic_map *ext;
   1988 	unsigned flags;
   1989 	int dims_ok;
   1990 
   1991 	if (!base)
   1992 		goto error;
   1993 
   1994 	dims_ok = base->extra >= base->n_div + extra;
   1995 
   1996 	if (dims_ok && room_for_con(base, n_eq + n_ineq) &&
   1997 		       room_for_ineq(base, n_ineq))
   1998 		return base;
   1999 
   2000 	extra += base->extra;
   2001 	n_eq += base->n_eq;
   2002 	n_ineq += base->n_ineq;
   2003 
   2004 	space = isl_basic_map_get_space(base);
   2005 	ext = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
   2006 	if (!ext)
   2007 		goto error;
   2008 
   2009 	if (dims_ok)
   2010 		ext->sample = isl_vec_copy(base->sample);
   2011 	flags = base->flags;
   2012 	ext = add_constraints(ext, base, 0, 0);
   2013 	if (ext) {
   2014 		ext->flags = flags;
   2015 		ISL_F_CLR(ext, ISL_BASIC_SET_FINAL);
   2016 	}
   2017 
   2018 	return ext;
   2019 
   2020 error:
   2021 	isl_basic_map_free(base);
   2022 	return NULL;
   2023 }
   2024 
   2025 __isl_give isl_basic_set *isl_basic_set_extend(__isl_take isl_basic_set *base,
   2026 	unsigned extra, unsigned n_eq, unsigned n_ineq)
   2027 {
   2028 	return bset_from_bmap(isl_basic_map_extend(bset_to_bmap(base),
   2029 						    extra, n_eq, n_ineq));
   2030 }
   2031 
   2032 __isl_give isl_basic_map *isl_basic_map_extend_constraints(
   2033 	__isl_take isl_basic_map *base, unsigned n_eq, unsigned n_ineq)
   2034 {
   2035 	return isl_basic_map_extend(base, 0, n_eq, n_ineq);
   2036 }
   2037 
   2038 __isl_give isl_basic_set *isl_basic_set_extend_constraints(
   2039 	__isl_take isl_basic_set *base, unsigned n_eq, unsigned n_ineq)
   2040 {
   2041 	isl_basic_map *bmap = bset_to_bmap(base);
   2042 	bmap = isl_basic_map_extend_constraints(bmap, n_eq, n_ineq);
   2043 	return bset_from_bmap(bmap);
   2044 }
   2045 
   2046 __isl_give isl_basic_set *isl_basic_set_cow(__isl_take isl_basic_set *bset)
   2047 {
   2048 	return bset_from_bmap(isl_basic_map_cow(bset_to_bmap(bset)));
   2049 }
   2050 
   2051 __isl_give isl_basic_map *isl_basic_map_cow(__isl_take isl_basic_map *bmap)
   2052 {
   2053 	if (!bmap)
   2054 		return NULL;
   2055 
   2056 	if (bmap->ref > 1) {
   2057 		bmap->ref--;
   2058 		bmap = isl_basic_map_dup(bmap);
   2059 	}
   2060 	if (bmap) {
   2061 		ISL_F_CLR(bmap, ISL_BASIC_SET_FINAL);
   2062 		ISL_F_CLR(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS);
   2063 	}
   2064 	return bmap;
   2065 }
   2066 
   2067 /* Clear all cached information in "map", either because it is about
   2068  * to be modified or because it is being freed.
   2069  * Always return the same pointer that is passed in.
   2070  * This is needed for the use in isl_map_free.
   2071  */
   2072 static __isl_give isl_map *clear_caches(__isl_take isl_map *map)
   2073 {
   2074 	isl_basic_map_free(map->cached_simple_hull[0]);
   2075 	isl_basic_map_free(map->cached_simple_hull[1]);
   2076 	map->cached_simple_hull[0] = NULL;
   2077 	map->cached_simple_hull[1] = NULL;
   2078 	return map;
   2079 }
   2080 
   2081 __isl_give isl_set *isl_set_cow(__isl_take isl_set *set)
   2082 {
   2083 	return isl_map_cow(set);
   2084 }
   2085 
   2086 /* Return an isl_map that is equal to "map" and that has only
   2087  * a single reference.
   2088  *
   2089  * If the original input already has only one reference, then
   2090  * simply return it, but clear all cached information, since
   2091  * it may be rendered invalid by the operations that will be
   2092  * performed on the result.
   2093  *
   2094  * Otherwise, create a duplicate (without any cached information).
   2095  */
   2096 __isl_give isl_map *isl_map_cow(__isl_take isl_map *map)
   2097 {
   2098 	if (!map)
   2099 		return NULL;
   2100 
   2101 	if (map->ref == 1)
   2102 		return clear_caches(map);
   2103 	map->ref--;
   2104 	return isl_map_dup(map);
   2105 }
   2106 
   2107 static void swap_vars(struct isl_blk blk, isl_int *a,
   2108 			unsigned a_len, unsigned b_len)
   2109 {
   2110 	isl_seq_cpy(blk.data, a+a_len, b_len);
   2111 	isl_seq_cpy(blk.data+b_len, a, a_len);
   2112 	isl_seq_cpy(a, blk.data, b_len+a_len);
   2113 }
   2114 
   2115 static __isl_give isl_basic_map *isl_basic_map_swap_vars(
   2116 	__isl_take isl_basic_map *bmap, unsigned pos, unsigned n1, unsigned n2)
   2117 {
   2118 	int i;
   2119 	struct isl_blk blk;
   2120 
   2121 	if (isl_basic_map_check_range(bmap, isl_dim_all, pos - 1, n1 + n2) < 0)
   2122 		goto error;
   2123 
   2124 	if (n1 == 0 || n2 == 0)
   2125 		return bmap;
   2126 
   2127 	bmap = isl_basic_map_cow(bmap);
   2128 	if (!bmap)
   2129 		return NULL;
   2130 
   2131 	blk = isl_blk_alloc(bmap->ctx, n1 + n2);
   2132 	if (isl_blk_is_error(blk))
   2133 		goto error;
   2134 
   2135 	for (i = 0; i < bmap->n_eq; ++i)
   2136 		swap_vars(blk,
   2137 			  bmap->eq[i] + pos, n1, n2);
   2138 
   2139 	for (i = 0; i < bmap->n_ineq; ++i)
   2140 		swap_vars(blk,
   2141 			  bmap->ineq[i] + pos, n1, n2);
   2142 
   2143 	for (i = 0; i < bmap->n_div; ++i)
   2144 		swap_vars(blk,
   2145 			  bmap->div[i]+1 + pos, n1, n2);
   2146 
   2147 	isl_blk_free(bmap->ctx, blk);
   2148 
   2149 	ISL_F_CLR(bmap, ISL_BASIC_SET_SORTED);
   2150 	bmap = isl_basic_map_gauss(bmap, NULL);
   2151 	return isl_basic_map_finalize(bmap);
   2152 error:
   2153 	isl_basic_map_free(bmap);
   2154 	return NULL;
   2155 }
   2156 
   2157 /* The given basic map has turned out to be empty.
   2158  * Explicitly mark it as such and change the representation
   2159  * to a canonical representation of the empty basic map.
   2160  * Since the basic map has conflicting constraints,
   2161  * it must have at least one constraint, except perhaps
   2162  * if it was already explicitly marked as being empty.
   2163  * Do nothing in the latter case, i.e., if it has been marked empty and
   2164  * has no constraints.
   2165  */
   2166 __isl_give isl_basic_map *isl_basic_map_set_to_empty(
   2167 	__isl_take isl_basic_map *bmap)
   2168 {
   2169 	int i = 0;
   2170 	isl_bool empty;
   2171 	isl_size n;
   2172 	isl_size total;
   2173 
   2174 	n = isl_basic_map_n_constraint(bmap);
   2175 	empty = isl_basic_map_plain_is_empty(bmap);
   2176 	if (n < 0 || empty < 0)
   2177 		return isl_basic_map_free(bmap);
   2178 	if (n == 0 && empty)
   2179 		return bmap;
   2180 	total = isl_basic_map_dim(bmap, isl_dim_all);
   2181 	if (total < 0)
   2182 		return isl_basic_map_free(bmap);
   2183 	if (isl_basic_map_free_div(bmap, bmap->n_div) < 0)
   2184 		return isl_basic_map_free(bmap);
   2185 	bmap = isl_basic_map_free_inequality(bmap, bmap->n_ineq);
   2186 	if (!bmap)
   2187 		return NULL;
   2188 	if (bmap->n_eq > 0) {
   2189 		bmap = isl_basic_map_free_equality(bmap, bmap->n_eq - 1);
   2190 		if (!bmap)
   2191 			return NULL;
   2192 	} else {
   2193 		i = isl_basic_map_alloc_equality(bmap);
   2194 		if (i < 0)
   2195 			goto error;
   2196 	}
   2197 	isl_int_set_si(bmap->eq[i][0], 1);
   2198 	isl_seq_clr(bmap->eq[i]+1, total);
   2199 	ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY);
   2200 	isl_vec_free(bmap->sample);
   2201 	bmap->sample = NULL;
   2202 	return isl_basic_map_finalize(bmap);
   2203 error:
   2204 	isl_basic_map_free(bmap);
   2205 	return NULL;
   2206 }
   2207 
   2208 __isl_give isl_basic_set *isl_basic_set_set_to_empty(
   2209 	__isl_take isl_basic_set *bset)
   2210 {
   2211 	return bset_from_bmap(isl_basic_map_set_to_empty(bset_to_bmap(bset)));
   2212 }
   2213 
   2214 __isl_give isl_basic_map *isl_basic_map_set_rational(
   2215 	__isl_take isl_basic_map *bmap)
   2216 {
   2217 	if (!bmap)
   2218 		return NULL;
   2219 
   2220 	if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL))
   2221 		return bmap;
   2222 
   2223 	bmap = isl_basic_map_cow(bmap);
   2224 	if (!bmap)
   2225 		return NULL;
   2226 
   2227 	ISL_F_SET(bmap, ISL_BASIC_MAP_RATIONAL);
   2228 
   2229 	return isl_basic_map_finalize(bmap);
   2230 }
   2231 
   2232 __isl_give isl_basic_set *isl_basic_set_set_rational(
   2233 	__isl_take isl_basic_set *bset)
   2234 {
   2235 	return isl_basic_map_set_rational(bset);
   2236 }
   2237 
   2238 __isl_give isl_basic_set *isl_basic_set_set_integral(
   2239 	__isl_take isl_basic_set *bset)
   2240 {
   2241 	if (!bset)
   2242 		return NULL;
   2243 
   2244 	if (!ISL_F_ISSET(bset, ISL_BASIC_MAP_RATIONAL))
   2245 		return bset;
   2246 
   2247 	bset = isl_basic_set_cow(bset);
   2248 	if (!bset)
   2249 		return NULL;
   2250 
   2251 	ISL_F_CLR(bset, ISL_BASIC_MAP_RATIONAL);
   2252 
   2253 	return isl_basic_set_finalize(bset);
   2254 }
   2255 
   2256 __isl_give isl_map *isl_map_set_rational(__isl_take isl_map *map)
   2257 {
   2258 	int i;
   2259 
   2260 	map = isl_map_cow(map);
   2261 	if (!map)
   2262 		return NULL;
   2263 	for (i = 0; i < map->n; ++i) {
   2264 		map->p[i] = isl_basic_map_set_rational(map->p[i]);
   2265 		if (!map->p[i])
   2266 			goto error;
   2267 	}
   2268 	return map;
   2269 error:
   2270 	isl_map_free(map);
   2271 	return NULL;
   2272 }
   2273 
   2274 __isl_give isl_set *isl_set_set_rational(__isl_take isl_set *set)
   2275 {
   2276 	return isl_map_set_rational(set);
   2277 }
   2278 
   2279 /* Swap divs "a" and "b" in "bmap" (without modifying any of the constraints
   2280  * of "bmap").
   2281  */
   2282 static void swap_div(__isl_keep isl_basic_map *bmap, int a, int b)
   2283 {
   2284 	isl_int *t = bmap->div[a];
   2285 	bmap->div[a] = bmap->div[b];
   2286 	bmap->div[b] = t;
   2287 }
   2288 
   2289 /* Swap divs "a" and "b" in "bmap" and adjust the constraints and
   2290  * div definitions accordingly.
   2291  */
   2292 __isl_give isl_basic_map *isl_basic_map_swap_div(__isl_take isl_basic_map *bmap,
   2293 	int a, int b)
   2294 {
   2295 	int i;
   2296 	isl_size off;
   2297 
   2298 	off = isl_basic_map_var_offset(bmap, isl_dim_div);
   2299 	if (off < 0)
   2300 		return isl_basic_map_free(bmap);
   2301 
   2302 	swap_div(bmap, a, b);
   2303 
   2304 	for (i = 0; i < bmap->n_eq; ++i)
   2305 		isl_int_swap(bmap->eq[i][1+off+a], bmap->eq[i][1+off+b]);
   2306 
   2307 	for (i = 0; i < bmap->n_ineq; ++i)
   2308 		isl_int_swap(bmap->ineq[i][1+off+a], bmap->ineq[i][1+off+b]);
   2309 
   2310 	for (i = 0; i < bmap->n_div; ++i)
   2311 		isl_int_swap(bmap->div[i][1+1+off+a], bmap->div[i][1+1+off+b]);
   2312 	ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
   2313 
   2314 	return bmap;
   2315 }
   2316 
   2317 static void constraint_drop_vars(isl_int *c, unsigned n, unsigned rem)
   2318 {
   2319 	isl_seq_cpy(c, c + n, rem);
   2320 	isl_seq_clr(c + rem, n);
   2321 }
   2322 
   2323 /* Drop n dimensions starting at first.
   2324  *
   2325  * In principle, this frees up some extra variables as the number
   2326  * of columns remains constant, but we would have to extend
   2327  * the div array too as the number of rows in this array is assumed
   2328  * to be equal to extra.
   2329  */
   2330 __isl_give isl_basic_set *isl_basic_set_drop_dims(
   2331 	__isl_take isl_basic_set *bset, unsigned first, unsigned n)
   2332 {
   2333 	return isl_basic_map_drop(bset_to_bmap(bset), isl_dim_set, first, n);
   2334 }
   2335 
   2336 /* Move "n" divs starting at "first" to the end of the list of divs.
   2337  */
   2338 static __isl_give isl_basic_map *move_divs_last(__isl_take isl_basic_map *bmap,
   2339 	unsigned first, unsigned n)
   2340 {
   2341 	isl_int **div;
   2342 	int i;
   2343 
   2344 	if (first + n == bmap->n_div)
   2345 		return bmap;
   2346 
   2347 	div = isl_alloc_array(bmap->ctx, isl_int *, n);
   2348 	if (!div)
   2349 		goto error;
   2350 	for (i = 0; i < n; ++i)
   2351 		div[i] = bmap->div[first + i];
   2352 	for (i = 0; i < bmap->n_div - first - n; ++i)
   2353 		bmap->div[first + i] = bmap->div[first + n + i];
   2354 	for (i = 0; i < n; ++i)
   2355 		bmap->div[bmap->n_div - n + i] = div[i];
   2356 	free(div);
   2357 	return bmap;
   2358 error:
   2359 	isl_basic_map_free(bmap);
   2360 	return NULL;
   2361 }
   2362 
   2363 #undef TYPE
   2364 #define TYPE	isl_map
   2365 static
   2366 #include "check_type_range_templ.c"
   2367 
   2368 /* Check that there are "n" dimensions of type "type" starting at "first"
   2369  * in "set".
   2370  */
   2371 isl_stat isl_set_check_range(__isl_keep isl_set *set,
   2372 	enum isl_dim_type type, unsigned first, unsigned n)
   2373 {
   2374 	return isl_map_check_range(set_to_map(set), type, first, n);
   2375 }
   2376 
   2377 /* Drop "n" dimensions of type "type" starting at "first".
   2378  * Perform the core computation, without cowing or
   2379  * simplifying and finalizing the result.
   2380  *
   2381  * In principle, this frees up some extra variables as the number
   2382  * of columns remains constant, but we would have to extend
   2383  * the div array too as the number of rows in this array is assumed
   2384  * to be equal to extra.
   2385  */
   2386 __isl_give isl_basic_map *isl_basic_map_drop_core(
   2387 	__isl_take isl_basic_map *bmap, enum isl_dim_type type,
   2388 	unsigned first, unsigned n)
   2389 {
   2390 	int i;
   2391 	unsigned offset;
   2392 	unsigned left;
   2393 	isl_size total;
   2394 
   2395 	if (isl_basic_map_check_range(bmap, type, first, n) < 0)
   2396 		return isl_basic_map_free(bmap);
   2397 
   2398 	total = isl_basic_map_dim(bmap, isl_dim_all);
   2399 	if (total < 0)
   2400 		return isl_basic_map_free(bmap);
   2401 
   2402 	offset = isl_basic_map_offset(bmap, type) + first;
   2403 	left = total - (offset - 1) - n;
   2404 	for (i = 0; i < bmap->n_eq; ++i)
   2405 		constraint_drop_vars(bmap->eq[i]+offset, n, left);
   2406 
   2407 	for (i = 0; i < bmap->n_ineq; ++i)
   2408 		constraint_drop_vars(bmap->ineq[i]+offset, n, left);
   2409 
   2410 	for (i = 0; i < bmap->n_div; ++i)
   2411 		constraint_drop_vars(bmap->div[i]+1+offset, n, left);
   2412 
   2413 	if (type == isl_dim_div) {
   2414 		bmap = move_divs_last(bmap, first, n);
   2415 		if (!bmap)
   2416 			return NULL;
   2417 		if (isl_basic_map_free_div(bmap, n) < 0)
   2418 			return isl_basic_map_free(bmap);
   2419 	} else
   2420 		bmap->dim = isl_space_drop_dims(bmap->dim, type, first, n);
   2421 	if (!bmap->dim)
   2422 		return isl_basic_map_free(bmap);
   2423 
   2424 	ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
   2425 	ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
   2426 	return bmap;
   2427 }
   2428 
   2429 /* Drop "n" dimensions of type "type" starting at "first".
   2430  *
   2431  * In principle, this frees up some extra variables as the number
   2432  * of columns remains constant, but we would have to extend
   2433  * the div array too as the number of rows in this array is assumed
   2434  * to be equal to extra.
   2435  */
   2436 __isl_give isl_basic_map *isl_basic_map_drop(__isl_take isl_basic_map *bmap,
   2437 	enum isl_dim_type type, unsigned first, unsigned n)
   2438 {
   2439 	if (!bmap)
   2440 		return NULL;
   2441 	if (n == 0 && !isl_space_is_named_or_nested(bmap->dim, type))
   2442 		return bmap;
   2443 
   2444 	bmap = isl_basic_map_cow(bmap);
   2445 	if (!bmap)
   2446 		return NULL;
   2447 
   2448 	bmap = isl_basic_map_drop_core(bmap, type, first, n);
   2449 
   2450 	bmap = isl_basic_map_simplify(bmap);
   2451 	return isl_basic_map_finalize(bmap);
   2452 }
   2453 
   2454 __isl_give isl_basic_set *isl_basic_set_drop(__isl_take isl_basic_set *bset,
   2455 	enum isl_dim_type type, unsigned first, unsigned n)
   2456 {
   2457 	return bset_from_bmap(isl_basic_map_drop(bset_to_bmap(bset),
   2458 							type, first, n));
   2459 }
   2460 
   2461 /* No longer consider "map" to be normalized.
   2462  */
   2463 static __isl_give isl_map *isl_map_unmark_normalized(__isl_take isl_map *map)
   2464 {
   2465 	if (!map)
   2466 		return NULL;
   2467 	ISL_F_CLR(map, ISL_MAP_NORMALIZED);
   2468 	return map;
   2469 }
   2470 
   2471 __isl_give isl_map *isl_map_drop(__isl_take isl_map *map,
   2472 	enum isl_dim_type type, unsigned first, unsigned n)
   2473 {
   2474 	int i;
   2475 	isl_space *space;
   2476 
   2477 	if (isl_map_check_range(map, type, first, n) < 0)
   2478 		return isl_map_free(map);
   2479 
   2480 	if (n == 0 && !isl_space_is_named_or_nested(map->dim, type))
   2481 		return map;
   2482 	map = isl_map_cow(map);
   2483 	if (!map)
   2484 		goto error;
   2485 
   2486 	for (i = 0; i < map->n; ++i) {
   2487 		map->p[i] = isl_basic_map_drop(map->p[i], type, first, n);
   2488 		if (!map->p[i])
   2489 			goto error;
   2490 	}
   2491 	map = isl_map_unmark_normalized(map);
   2492 
   2493 	space = isl_map_take_space(map);
   2494 	space = isl_space_drop_dims(space, type, first, n);
   2495 	map = isl_map_restore_space(map, space);
   2496 
   2497 	return map;
   2498 error:
   2499 	isl_map_free(map);
   2500 	return NULL;
   2501 }
   2502 
   2503 __isl_give isl_set *isl_set_drop(__isl_take isl_set *set,
   2504 	enum isl_dim_type type, unsigned first, unsigned n)
   2505 {
   2506 	return set_from_map(isl_map_drop(set_to_map(set), type, first, n));
   2507 }
   2508 
   2509 /* Drop the integer division at position "div", which is assumed
   2510  * not to appear in any of the constraints or
   2511  * in any of the other integer divisions.
   2512  *
   2513  * Since the integer division is redundant, there is no need to cow.
   2514  */
   2515 __isl_give isl_basic_map *isl_basic_map_drop_div(
   2516 	__isl_take isl_basic_map *bmap, unsigned div)
   2517 {
   2518 	return isl_basic_map_drop_core(bmap, isl_dim_div, div, 1);
   2519 }
   2520 
   2521 /* Eliminate the specified n dimensions starting at first from the
   2522  * constraints, without removing the dimensions from the space.
   2523  * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
   2524  */
   2525 __isl_give isl_map *isl_map_eliminate(__isl_take isl_map *map,
   2526 	enum isl_dim_type type, unsigned first, unsigned n)
   2527 {
   2528 	int i;
   2529 
   2530 	if (n == 0)
   2531 		return map;
   2532 
   2533 	if (isl_map_check_range(map, type, first, n) < 0)
   2534 		return isl_map_free(map);
   2535 
   2536 	map = isl_map_cow(map);
   2537 	if (!map)
   2538 		return NULL;
   2539 
   2540 	for (i = 0; i < map->n; ++i) {
   2541 		map->p[i] = isl_basic_map_eliminate(map->p[i], type, first, n);
   2542 		if (!map->p[i])
   2543 			goto error;
   2544 	}
   2545 	return map;
   2546 error:
   2547 	isl_map_free(map);
   2548 	return NULL;
   2549 }
   2550 
   2551 /* Eliminate the specified n dimensions starting at first from the
   2552  * constraints, without removing the dimensions from the space.
   2553  * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
   2554  */
   2555 __isl_give isl_set *isl_set_eliminate(__isl_take isl_set *set,
   2556 	enum isl_dim_type type, unsigned first, unsigned n)
   2557 {
   2558 	return set_from_map(isl_map_eliminate(set_to_map(set), type, first, n));
   2559 }
   2560 
   2561 /* Eliminate the specified n dimensions starting at first from the
   2562  * constraints, without removing the dimensions from the space.
   2563  * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
   2564  */
   2565 __isl_give isl_set *isl_set_eliminate_dims(__isl_take isl_set *set,
   2566 	unsigned first, unsigned n)
   2567 {
   2568 	return isl_set_eliminate(set, isl_dim_set, first, n);
   2569 }
   2570 
   2571 __isl_give isl_basic_map *isl_basic_map_remove_divs(
   2572 	__isl_take isl_basic_map *bmap)
   2573 {
   2574 	isl_size v_div;
   2575 
   2576 	v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
   2577 	if (v_div < 0)
   2578 		return isl_basic_map_free(bmap);
   2579 	bmap = isl_basic_map_eliminate_vars(bmap, v_div, bmap->n_div);
   2580 	if (!bmap)
   2581 		return NULL;
   2582 	bmap->n_div = 0;
   2583 	return isl_basic_map_finalize(bmap);
   2584 }
   2585 
   2586 __isl_give isl_basic_set *isl_basic_set_remove_divs(
   2587 	__isl_take isl_basic_set *bset)
   2588 {
   2589 	return bset_from_bmap(isl_basic_map_remove_divs(bset_to_bmap(bset)));
   2590 }
   2591 
   2592 __isl_give isl_map *isl_map_remove_divs(__isl_take isl_map *map)
   2593 {
   2594 	int i;
   2595 
   2596 	if (!map)
   2597 		return NULL;
   2598 	if (map->n == 0)
   2599 		return map;
   2600 
   2601 	map = isl_map_cow(map);
   2602 	if (!map)
   2603 		return NULL;
   2604 
   2605 	for (i = 0; i < map->n; ++i) {
   2606 		map->p[i] = isl_basic_map_remove_divs(map->p[i]);
   2607 		if (!map->p[i])
   2608 			goto error;
   2609 	}
   2610 	return map;
   2611 error:
   2612 	isl_map_free(map);
   2613 	return NULL;
   2614 }
   2615 
   2616 __isl_give isl_set *isl_set_remove_divs(__isl_take isl_set *set)
   2617 {
   2618 	return isl_map_remove_divs(set);
   2619 }
   2620 
   2621 __isl_give isl_basic_map *isl_basic_map_remove_dims(
   2622 	__isl_take isl_basic_map *bmap, enum isl_dim_type type,
   2623 	unsigned first, unsigned n)
   2624 {
   2625 	if (isl_basic_map_check_range(bmap, type, first, n) < 0)
   2626 		return isl_basic_map_free(bmap);
   2627 	if (n == 0 && !isl_space_is_named_or_nested(bmap->dim, type))
   2628 		return bmap;
   2629 	bmap = isl_basic_map_eliminate_vars(bmap,
   2630 			isl_basic_map_offset(bmap, type) - 1 + first, n);
   2631 	if (!bmap)
   2632 		return bmap;
   2633 	if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY) && type == isl_dim_div)
   2634 		return bmap;
   2635 	bmap = isl_basic_map_drop(bmap, type, first, n);
   2636 	return bmap;
   2637 }
   2638 
   2639 /* Return true if the definition of the given div (recursively) involves
   2640  * any of the given variables.
   2641  */
   2642 static isl_bool div_involves_vars(__isl_keep isl_basic_map *bmap, int div,
   2643 	unsigned first, unsigned n)
   2644 {
   2645 	int i;
   2646 	unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div);
   2647 
   2648 	if (isl_int_is_zero(bmap->div[div][0]))
   2649 		return isl_bool_false;
   2650 	if (isl_seq_first_non_zero(bmap->div[div] + 1 + 1 + first, n) >= 0)
   2651 		return isl_bool_true;
   2652 
   2653 	for (i = bmap->n_div - 1; i >= 0; --i) {
   2654 		isl_bool involves;
   2655 
   2656 		if (isl_int_is_zero(bmap->div[div][1 + div_offset + i]))
   2657 			continue;
   2658 		involves = div_involves_vars(bmap, i, first, n);
   2659 		if (involves < 0 || involves)
   2660 			return involves;
   2661 	}
   2662 
   2663 	return isl_bool_false;
   2664 }
   2665 
   2666 /* Try and add a lower and/or upper bound on "div" to "bmap"
   2667  * based on inequality "i".
   2668  * "total" is the total number of variables (excluding the divs).
   2669  * "v" is a temporary object that can be used during the calculations.
   2670  * If "lb" is set, then a lower bound should be constructed.
   2671  * If "ub" is set, then an upper bound should be constructed.
   2672  *
   2673  * The calling function has already checked that the inequality does not
   2674  * reference "div", but we still need to check that the inequality is
   2675  * of the right form.  We'll consider the case where we want to construct
   2676  * a lower bound.  The construction of upper bounds is similar.
   2677  *
   2678  * Let "div" be of the form
   2679  *
   2680  *	q = floor((a + f(x))/d)
   2681  *
   2682  * We essentially check if constraint "i" is of the form
   2683  *
   2684  *	b + f(x) >= 0
   2685  *
   2686  * so that we can use it to derive a lower bound on "div".
   2687  * However, we allow a slightly more general form
   2688  *
   2689  *	b + g(x) >= 0
   2690  *
   2691  * with the condition that the coefficients of g(x) - f(x) are all
   2692  * divisible by d.
   2693  * Rewriting this constraint as
   2694  *
   2695  *	0 >= -b - g(x)
   2696  *
   2697  * adding a + f(x) to both sides and dividing by d, we obtain
   2698  *
   2699  *	(a + f(x))/d >= (a-b)/d + (f(x)-g(x))/d
   2700  *
   2701  * Taking the floor on both sides, we obtain
   2702  *
   2703  *	q >= floor((a-b)/d) + (f(x)-g(x))/d
   2704  *
   2705  * or
   2706  *
   2707  *	(g(x)-f(x))/d + ceil((b-a)/d) + q >= 0
   2708  *
   2709  * In the case of an upper bound, we construct the constraint
   2710  *
   2711  *	(g(x)+f(x))/d + floor((b+a)/d) - q >= 0
   2712  *
   2713  */
   2714 static __isl_give isl_basic_map *insert_bounds_on_div_from_ineq(
   2715 	__isl_take isl_basic_map *bmap, int div, int i,
   2716 	unsigned total, isl_int v, int lb, int ub)
   2717 {
   2718 	int j;
   2719 
   2720 	for (j = 0; (lb || ub) && j < total + bmap->n_div; ++j) {
   2721 		if (lb) {
   2722 			isl_int_sub(v, bmap->ineq[i][1 + j],
   2723 					bmap->div[div][1 + 1 + j]);
   2724 			lb = isl_int_is_divisible_by(v, bmap->div[div][0]);
   2725 		}
   2726 		if (ub) {
   2727 			isl_int_add(v, bmap->ineq[i][1 + j],
   2728 					bmap->div[div][1 + 1 + j]);
   2729 			ub = isl_int_is_divisible_by(v, bmap->div[div][0]);
   2730 		}
   2731 	}
   2732 	if (!lb && !ub)
   2733 		return bmap;
   2734 
   2735 	bmap = isl_basic_map_cow(bmap);
   2736 	bmap = isl_basic_map_extend_constraints(bmap, 0, lb + ub);
   2737 	if (lb) {
   2738 		int k = isl_basic_map_alloc_inequality(bmap);
   2739 		if (k < 0)
   2740 			goto error;
   2741 		for (j = 0; j < 1 + total + bmap->n_div; ++j) {
   2742 			isl_int_sub(bmap->ineq[k][j], bmap->ineq[i][j],
   2743 					bmap->div[div][1 + j]);
   2744 			isl_int_cdiv_q(bmap->ineq[k][j],
   2745 					bmap->ineq[k][j], bmap->div[div][0]);
   2746 		}
   2747 		isl_int_set_si(bmap->ineq[k][1 + total + div], 1);
   2748 	}
   2749 	if (ub) {
   2750 		int k = isl_basic_map_alloc_inequality(bmap);
   2751 		if (k < 0)
   2752 			goto error;
   2753 		for (j = 0; j < 1 + total + bmap->n_div; ++j) {
   2754 			isl_int_add(bmap->ineq[k][j], bmap->ineq[i][j],
   2755 					bmap->div[div][1 + j]);
   2756 			isl_int_fdiv_q(bmap->ineq[k][j],
   2757 					bmap->ineq[k][j], bmap->div[div][0]);
   2758 		}
   2759 		isl_int_set_si(bmap->ineq[k][1 + total + div], -1);
   2760 	}
   2761 
   2762 	return bmap;
   2763 error:
   2764 	isl_basic_map_free(bmap);
   2765 	return NULL;
   2766 }
   2767 
   2768 /* This function is called right before "div" is eliminated from "bmap"
   2769  * using Fourier-Motzkin.
   2770  * Look through the constraints of "bmap" for constraints on the argument
   2771  * of the integer division and use them to construct constraints on the
   2772  * integer division itself.  These constraints can then be combined
   2773  * during the Fourier-Motzkin elimination.
   2774  * Note that it is only useful to introduce lower bounds on "div"
   2775  * if "bmap" already contains upper bounds on "div" as the newly
   2776  * introduce lower bounds can then be combined with the pre-existing
   2777  * upper bounds.  Similarly for upper bounds.
   2778  * We therefore first check if "bmap" contains any lower and/or upper bounds
   2779  * on "div".
   2780  *
   2781  * It is interesting to note that the introduction of these constraints
   2782  * can indeed lead to more accurate results, even when compared to
   2783  * deriving constraints on the argument of "div" from constraints on "div".
   2784  * Consider, for example, the set
   2785  *
   2786  *	{ [i,j,k] : 3 + i + 2j >= 0 and 2 * [(i+2j)/4] <= k }
   2787  *
   2788  * The second constraint can be rewritten as
   2789  *
   2790  *	2 * [(-i-2j+3)/4] + k >= 0
   2791  *
   2792  * from which we can derive
   2793  *
   2794  *	-i - 2j + 3 >= -2k
   2795  *
   2796  * or
   2797  *
   2798  *	i + 2j <= 3 + 2k
   2799  *
   2800  * Combined with the first constraint, we obtain
   2801  *
   2802  *	-3 <= 3 + 2k	or	k >= -3
   2803  *
   2804  * If, on the other hand we derive a constraint on [(i+2j)/4] from
   2805  * the first constraint, we obtain
   2806  *
   2807  *	[(i + 2j)/4] >= [-3/4] = -1
   2808  *
   2809  * Combining this constraint with the second constraint, we obtain
   2810  *
   2811  *	k >= -2
   2812  */
   2813 static __isl_give isl_basic_map *insert_bounds_on_div(
   2814 	__isl_take isl_basic_map *bmap, int div)
   2815 {
   2816 	int i;
   2817 	int check_lb, check_ub;
   2818 	isl_int v;
   2819 	isl_size v_div;
   2820 
   2821 	if (!bmap)
   2822 		return NULL;
   2823 
   2824 	if (isl_int_is_zero(bmap->div[div][0]))
   2825 		return bmap;
   2826 
   2827 	v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
   2828 	if (v_div < 0)
   2829 		return isl_basic_map_free(bmap);
   2830 
   2831 	check_lb = 0;
   2832 	check_ub = 0;
   2833 	for (i = 0; (!check_lb || !check_ub) && i < bmap->n_ineq; ++i) {
   2834 		int s = isl_int_sgn(bmap->ineq[i][1 + v_div + div]);
   2835 		if (s > 0)
   2836 			check_ub = 1;
   2837 		if (s < 0)
   2838 			check_lb = 1;
   2839 	}
   2840 
   2841 	if (!check_lb && !check_ub)
   2842 		return bmap;
   2843 
   2844 	isl_int_init(v);
   2845 
   2846 	for (i = 0; bmap && i < bmap->n_ineq; ++i) {
   2847 		if (!isl_int_is_zero(bmap->ineq[i][1 + v_div + div]))
   2848 			continue;
   2849 
   2850 		bmap = insert_bounds_on_div_from_ineq(bmap, div, i, v_div, v,
   2851 							check_lb, check_ub);
   2852 	}
   2853 
   2854 	isl_int_clear(v);
   2855 
   2856 	return bmap;
   2857 }
   2858 
   2859 /* Remove all divs (recursively) involving any of the given dimensions
   2860  * in their definitions.
   2861  */
   2862 __isl_give isl_basic_map *isl_basic_map_remove_divs_involving_dims(
   2863 	__isl_take isl_basic_map *bmap,
   2864 	enum isl_dim_type type, unsigned first, unsigned n)
   2865 {
   2866 	int i;
   2867 	isl_size off;
   2868 
   2869 	if (isl_basic_map_check_range(bmap, type, first, n) < 0)
   2870 		return isl_basic_map_free(bmap);
   2871 	off = isl_basic_map_var_offset(bmap, type);
   2872 	if (off < 0)
   2873 		return isl_basic_map_free(bmap);
   2874 	first += off;
   2875 
   2876 	for (i = bmap->n_div - 1; i >= 0; --i) {
   2877 		isl_bool involves;
   2878 
   2879 		involves = div_involves_vars(bmap, i, first, n);
   2880 		if (involves < 0)
   2881 			return isl_basic_map_free(bmap);
   2882 		if (!involves)
   2883 			continue;
   2884 		bmap = insert_bounds_on_div(bmap, i);
   2885 		bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1);
   2886 		if (!bmap)
   2887 			return NULL;
   2888 		i = bmap->n_div;
   2889 	}
   2890 
   2891 	return bmap;
   2892 }
   2893 
   2894 __isl_give isl_basic_set *isl_basic_set_remove_divs_involving_dims(
   2895 	__isl_take isl_basic_set *bset,
   2896 	enum isl_dim_type type, unsigned first, unsigned n)
   2897 {
   2898 	return isl_basic_map_remove_divs_involving_dims(bset, type, first, n);
   2899 }
   2900 
   2901 __isl_give isl_map *isl_map_remove_divs_involving_dims(__isl_take isl_map *map,
   2902 	enum isl_dim_type type, unsigned first, unsigned n)
   2903 {
   2904 	int i;
   2905 
   2906 	if (!map)
   2907 		return NULL;
   2908 	if (map->n == 0)
   2909 		return map;
   2910 
   2911 	map = isl_map_cow(map);
   2912 	if (!map)
   2913 		return NULL;
   2914 
   2915 	for (i = 0; i < map->n; ++i) {
   2916 		map->p[i] = isl_basic_map_remove_divs_involving_dims(map->p[i],
   2917 								type, first, n);
   2918 		if (!map->p[i])
   2919 			goto error;
   2920 	}
   2921 	return map;
   2922 error:
   2923 	isl_map_free(map);
   2924 	return NULL;
   2925 }
   2926 
   2927 __isl_give isl_set *isl_set_remove_divs_involving_dims(__isl_take isl_set *set,
   2928 	enum isl_dim_type type, unsigned first, unsigned n)
   2929 {
   2930 	return set_from_map(isl_map_remove_divs_involving_dims(set_to_map(set),
   2931 							      type, first, n));
   2932 }
   2933 
   2934 /* Does the description of "bmap" depend on the specified dimensions?
   2935  * We also check whether the dimensions appear in any of the div definitions.
   2936  * In principle there is no need for this check.  If the dimensions appear
   2937  * in a div definition, they also appear in the defining constraints of that
   2938  * div.
   2939  */
   2940 isl_bool isl_basic_map_involves_dims(__isl_keep isl_basic_map *bmap,
   2941 	enum isl_dim_type type, unsigned first, unsigned n)
   2942 {
   2943 	int i;
   2944 
   2945 	if (isl_basic_map_check_range(bmap, type, first, n) < 0)
   2946 		return isl_bool_error;
   2947 
   2948 	first += isl_basic_map_offset(bmap, type);
   2949 	for (i = 0; i < bmap->n_eq; ++i)
   2950 		if (isl_seq_first_non_zero(bmap->eq[i] + first, n) >= 0)
   2951 			return isl_bool_true;
   2952 	for (i = 0; i < bmap->n_ineq; ++i)
   2953 		if (isl_seq_first_non_zero(bmap->ineq[i] + first, n) >= 0)
   2954 			return isl_bool_true;
   2955 	for (i = 0; i < bmap->n_div; ++i) {
   2956 		if (isl_int_is_zero(bmap->div[i][0]))
   2957 			continue;
   2958 		if (isl_seq_first_non_zero(bmap->div[i] + 1 + first, n) >= 0)
   2959 			return isl_bool_true;
   2960 	}
   2961 
   2962 	return isl_bool_false;
   2963 }
   2964 
   2965 isl_bool isl_map_involves_dims(__isl_keep isl_map *map,
   2966 	enum isl_dim_type type, unsigned first, unsigned n)
   2967 {
   2968 	int i;
   2969 
   2970 	if (isl_map_check_range(map, type, first, n) < 0)
   2971 		return isl_bool_error;
   2972 
   2973 	for (i = 0; i < map->n; ++i) {
   2974 		isl_bool involves = isl_basic_map_involves_dims(map->p[i],
   2975 							    type, first, n);
   2976 		if (involves < 0 || involves)
   2977 			return involves;
   2978 	}
   2979 
   2980 	return isl_bool_false;
   2981 }
   2982 
   2983 isl_bool isl_basic_set_involves_dims(__isl_keep isl_basic_set *bset,
   2984 	enum isl_dim_type type, unsigned first, unsigned n)
   2985 {
   2986 	return isl_basic_map_involves_dims(bset, type, first, n);
   2987 }
   2988 
   2989 isl_bool isl_set_involves_dims(__isl_keep isl_set *set,
   2990 	enum isl_dim_type type, unsigned first, unsigned n)
   2991 {
   2992 	return isl_map_involves_dims(set, type, first, n);
   2993 }
   2994 
   2995 /* Does "bset" involve any local variables, i.e., integer divisions?
   2996  */
   2997 static isl_bool isl_basic_set_involves_locals(__isl_keep isl_basic_set *bset)
   2998 {
   2999 	isl_size n;
   3000 
   3001 	n = isl_basic_set_dim(bset, isl_dim_div);
   3002 	if (n < 0)
   3003 		return isl_bool_error;
   3004 	return isl_bool_ok(n > 0);
   3005 }
   3006 
   3007 /* isl_set_every_basic_set callback that checks whether "bset"
   3008  * is free of local variables.
   3009  */
   3010 static isl_bool basic_set_no_locals(__isl_keep isl_basic_set *bset, void *user)
   3011 {
   3012 	return isl_bool_not(isl_basic_set_involves_locals(bset));
   3013 }
   3014 
   3015 /* Does "set" involve any local variables, i.e., integer divisions?
   3016  */
   3017 isl_bool isl_set_involves_locals(__isl_keep isl_set *set)
   3018 {
   3019 	isl_bool no_locals;
   3020 
   3021 	no_locals = isl_set_every_basic_set(set, &basic_set_no_locals, NULL);
   3022 	return isl_bool_not(no_locals);
   3023 }
   3024 
   3025 /* Drop all constraints in bmap that involve any of the dimensions
   3026  * first to first+n-1.
   3027  * This function only performs the actual removal of constraints.
   3028  *
   3029  * This function should not call finalize since it is used by
   3030  * remove_redundant_divs, which in turn is called by isl_basic_map_finalize.
   3031  */
   3032 __isl_give isl_basic_map *isl_basic_map_drop_constraints_involving(
   3033 	__isl_take isl_basic_map *bmap, unsigned first, unsigned n)
   3034 {
   3035 	int i;
   3036 
   3037 	if (n == 0)
   3038 		return bmap;
   3039 
   3040 	bmap = isl_basic_map_cow(bmap);
   3041 
   3042 	if (!bmap)
   3043 		return NULL;
   3044 
   3045 	for (i = bmap->n_eq - 1; i >= 0; --i) {
   3046 		if (isl_seq_first_non_zero(bmap->eq[i] + 1 + first, n) == -1)
   3047 			continue;
   3048 		if (isl_basic_map_drop_equality(bmap, i) < 0)
   3049 			return isl_basic_map_free(bmap);
   3050 	}
   3051 
   3052 	for (i = bmap->n_ineq - 1; i >= 0; --i) {
   3053 		if (isl_seq_first_non_zero(bmap->ineq[i] + 1 + first, n) == -1)
   3054 			continue;
   3055 		if (isl_basic_map_drop_inequality(bmap, i) < 0)
   3056 			return isl_basic_map_free(bmap);
   3057 	}
   3058 
   3059 	return bmap;
   3060 }
   3061 
   3062 /* Drop all constraints in bset that involve any of the dimensions
   3063  * first to first+n-1.
   3064  * This function only performs the actual removal of constraints.
   3065  */
   3066 __isl_give isl_basic_set *isl_basic_set_drop_constraints_involving(
   3067 	__isl_take isl_basic_set *bset, unsigned first, unsigned n)
   3068 {
   3069 	return isl_basic_map_drop_constraints_involving(bset, first, n);
   3070 }
   3071 
   3072 /* Drop all constraints in bmap that do not involve any of the dimensions
   3073  * first to first + n - 1 of the given type.
   3074  */
   3075 __isl_give isl_basic_map *isl_basic_map_drop_constraints_not_involving_dims(
   3076 	__isl_take isl_basic_map *bmap,
   3077 	enum isl_dim_type type, unsigned first, unsigned n)
   3078 {
   3079 	int i;
   3080 
   3081 	if (n == 0) {
   3082 		isl_space *space = isl_basic_map_get_space(bmap);
   3083 		isl_basic_map_free(bmap);
   3084 		return isl_basic_map_universe(space);
   3085 	}
   3086 	bmap = isl_basic_map_cow(bmap);
   3087 	if (!bmap)
   3088 		return NULL;
   3089 
   3090 	if (isl_basic_map_check_range(bmap, type, first, n) < 0)
   3091 		return isl_basic_map_free(bmap);
   3092 
   3093 	first += isl_basic_map_offset(bmap, type) - 1;
   3094 
   3095 	for (i = bmap->n_eq - 1; i >= 0; --i) {
   3096 		if (isl_seq_first_non_zero(bmap->eq[i] + 1 + first, n) != -1)
   3097 			continue;
   3098 		if (isl_basic_map_drop_equality(bmap, i) < 0)
   3099 			return isl_basic_map_free(bmap);
   3100 	}
   3101 
   3102 	for (i = bmap->n_ineq - 1; i >= 0; --i) {
   3103 		if (isl_seq_first_non_zero(bmap->ineq[i] + 1 + first, n) != -1)
   3104 			continue;
   3105 		if (isl_basic_map_drop_inequality(bmap, i) < 0)
   3106 			return isl_basic_map_free(bmap);
   3107 	}
   3108 
   3109 	bmap = isl_basic_map_add_known_div_constraints(bmap);
   3110 	return bmap;
   3111 }
   3112 
   3113 /* Drop all constraints in bset that do not involve any of the dimensions
   3114  * first to first + n - 1 of the given type.
   3115  */
   3116 __isl_give isl_basic_set *isl_basic_set_drop_constraints_not_involving_dims(
   3117 	__isl_take isl_basic_set *bset,
   3118 	enum isl_dim_type type, unsigned first, unsigned n)
   3119 {
   3120 	return isl_basic_map_drop_constraints_not_involving_dims(bset,
   3121 							    type, first, n);
   3122 }
   3123 
   3124 /* Drop all constraints in bmap that involve any of the dimensions
   3125  * first to first + n - 1 of the given type.
   3126  */
   3127 __isl_give isl_basic_map *isl_basic_map_drop_constraints_involving_dims(
   3128 	__isl_take isl_basic_map *bmap,
   3129 	enum isl_dim_type type, unsigned first, unsigned n)
   3130 {
   3131 	if (!bmap)
   3132 		return NULL;
   3133 	if (n == 0)
   3134 		return bmap;
   3135 
   3136 	if (isl_basic_map_check_range(bmap, type, first, n) < 0)
   3137 		return isl_basic_map_free(bmap);
   3138 
   3139 	bmap = isl_basic_map_remove_divs_involving_dims(bmap, type, first, n);
   3140 	first += isl_basic_map_offset(bmap, type) - 1;
   3141 	bmap = isl_basic_map_drop_constraints_involving(bmap, first, n);
   3142 	bmap = isl_basic_map_add_known_div_constraints(bmap);
   3143 	return bmap;
   3144 }
   3145 
   3146 /* Drop all constraints in bset that involve any of the dimensions
   3147  * first to first + n - 1 of the given type.
   3148  */
   3149 __isl_give isl_basic_set *isl_basic_set_drop_constraints_involving_dims(
   3150 	__isl_take isl_basic_set *bset,
   3151 	enum isl_dim_type type, unsigned first, unsigned n)
   3152 {
   3153 	return isl_basic_map_drop_constraints_involving_dims(bset,
   3154 							    type, first, n);
   3155 }
   3156 
   3157 /* Drop constraints from "map" by applying "drop" to each basic map.
   3158  */
   3159 static __isl_give isl_map *drop_constraints(__isl_take isl_map *map,
   3160 	enum isl_dim_type type, unsigned first, unsigned n,
   3161 	__isl_give isl_basic_map *(*drop)(__isl_take isl_basic_map *bmap,
   3162 		enum isl_dim_type type, unsigned first, unsigned n))
   3163 {
   3164 	int i;
   3165 
   3166 	if (isl_map_check_range(map, type, first, n) < 0)
   3167 		return isl_map_free(map);
   3168 
   3169 	map = isl_map_cow(map);
   3170 	if (!map)
   3171 		return NULL;
   3172 
   3173 	for (i = 0; i < map->n; ++i) {
   3174 		map->p[i] = drop(map->p[i], type, first, n);
   3175 		if (!map->p[i])
   3176 			return isl_map_free(map);
   3177 	}
   3178 
   3179 	if (map->n > 1)
   3180 		ISL_F_CLR(map, ISL_MAP_DISJOINT);
   3181 
   3182 	return map;
   3183 }
   3184 
   3185 /* Drop all constraints in map that involve any of the dimensions
   3186  * first to first + n - 1 of the given type.
   3187  */
   3188 __isl_give isl_map *isl_map_drop_constraints_involving_dims(
   3189 	__isl_take isl_map *map,
   3190 	enum isl_dim_type type, unsigned first, unsigned n)
   3191 {
   3192 	if (n == 0)
   3193 		return map;
   3194 	return drop_constraints(map, type, first, n,
   3195 				&isl_basic_map_drop_constraints_involving_dims);
   3196 }
   3197 
   3198 /* Drop all constraints in "map" that do not involve any of the dimensions
   3199  * first to first + n - 1 of the given type.
   3200  */
   3201 __isl_give isl_map *isl_map_drop_constraints_not_involving_dims(
   3202 	__isl_take isl_map *map,
   3203 	enum isl_dim_type type, unsigned first, unsigned n)
   3204 {
   3205 	if (n == 0) {
   3206 		isl_space *space = isl_map_get_space(map);
   3207 		isl_map_free(map);
   3208 		return isl_map_universe(space);
   3209 	}
   3210 	return drop_constraints(map, type, first, n,
   3211 			    &isl_basic_map_drop_constraints_not_involving_dims);
   3212 }
   3213 
   3214 /* Drop all constraints in set that involve any of the dimensions
   3215  * first to first + n - 1 of the given type.
   3216  */
   3217 __isl_give isl_set *isl_set_drop_constraints_involving_dims(
   3218 	__isl_take isl_set *set,
   3219 	enum isl_dim_type type, unsigned first, unsigned n)
   3220 {
   3221 	return isl_map_drop_constraints_involving_dims(set, type, first, n);
   3222 }
   3223 
   3224 /* Drop all constraints in "set" that do not involve any of the dimensions
   3225  * first to first + n - 1 of the given type.
   3226  */
   3227 __isl_give isl_set *isl_set_drop_constraints_not_involving_dims(
   3228 	__isl_take isl_set *set,
   3229 	enum isl_dim_type type, unsigned first, unsigned n)
   3230 {
   3231 	return isl_map_drop_constraints_not_involving_dims(set, type, first, n);
   3232 }
   3233 
   3234 /* Does local variable "div" of "bmap" have a complete explicit representation?
   3235  * Having a complete explicit representation requires not only
   3236  * an explicit representation, but also that all local variables
   3237  * that appear in this explicit representation in turn have
   3238  * a complete explicit representation.
   3239  */
   3240 isl_bool isl_basic_map_div_is_known(__isl_keep isl_basic_map *bmap, int div)
   3241 {
   3242 	int i;
   3243 	unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div);
   3244 	isl_bool marked;
   3245 
   3246 	marked = isl_basic_map_div_is_marked_unknown(bmap, div);
   3247 	if (marked < 0 || marked)
   3248 		return isl_bool_not(marked);
   3249 
   3250 	for (i = bmap->n_div - 1; i >= 0; --i) {
   3251 		isl_bool known;
   3252 
   3253 		if (isl_int_is_zero(bmap->div[div][1 + div_offset + i]))
   3254 			continue;
   3255 		known = isl_basic_map_div_is_known(bmap, i);
   3256 		if (known < 0 || !known)
   3257 			return known;
   3258 	}
   3259 
   3260 	return isl_bool_true;
   3261 }
   3262 
   3263 /* Remove all divs that are unknown or defined in terms of unknown divs.
   3264  */
   3265 __isl_give isl_basic_map *isl_basic_map_remove_unknown_divs(
   3266 	__isl_take isl_basic_map *bmap)
   3267 {
   3268 	int i;
   3269 
   3270 	if (!bmap)
   3271 		return NULL;
   3272 
   3273 	for (i = bmap->n_div - 1; i >= 0; --i) {
   3274 		if (isl_basic_map_div_is_known(bmap, i))
   3275 			continue;
   3276 		bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1);
   3277 		if (!bmap)
   3278 			return NULL;
   3279 		i = bmap->n_div;
   3280 	}
   3281 
   3282 	return bmap;
   3283 }
   3284 
   3285 /* Remove all divs that are unknown or defined in terms of unknown divs.
   3286  */
   3287 __isl_give isl_basic_set *isl_basic_set_remove_unknown_divs(
   3288 	__isl_take isl_basic_set *bset)
   3289 {
   3290 	return isl_basic_map_remove_unknown_divs(bset);
   3291 }
   3292 
   3293 __isl_give isl_map *isl_map_remove_unknown_divs(__isl_take isl_map *map)
   3294 {
   3295 	int i;
   3296 
   3297 	if (!map)
   3298 		return NULL;
   3299 	if (map->n == 0)
   3300 		return map;
   3301 
   3302 	map = isl_map_cow(map);
   3303 	if (!map)
   3304 		return NULL;
   3305 
   3306 	for (i = 0; i < map->n; ++i) {
   3307 		map->p[i] = isl_basic_map_remove_unknown_divs(map->p[i]);
   3308 		if (!map->p[i])
   3309 			goto error;
   3310 	}
   3311 	return map;
   3312 error:
   3313 	isl_map_free(map);
   3314 	return NULL;
   3315 }
   3316 
   3317 __isl_give isl_set *isl_set_remove_unknown_divs(__isl_take isl_set *set)
   3318 {
   3319 	return set_from_map(isl_map_remove_unknown_divs(set_to_map(set)));
   3320 }
   3321 
   3322 __isl_give isl_basic_set *isl_basic_set_remove_dims(
   3323 	__isl_take isl_basic_set *bset,
   3324 	enum isl_dim_type type, unsigned first, unsigned n)
   3325 {
   3326 	isl_basic_map *bmap = bset_to_bmap(bset);
   3327 	bmap = isl_basic_map_remove_dims(bmap, type, first, n);
   3328 	return bset_from_bmap(bmap);
   3329 }
   3330 
   3331 __isl_give isl_map *isl_map_remove_dims(__isl_take isl_map *map,
   3332 	enum isl_dim_type type, unsigned first, unsigned n)
   3333 {
   3334 	int i;
   3335 
   3336 	if (n == 0)
   3337 		return map;
   3338 
   3339 	map = isl_map_cow(map);
   3340 	if (isl_map_check_range(map, type, first, n) < 0)
   3341 		return isl_map_free(map);
   3342 
   3343 	for (i = 0; i < map->n; ++i) {
   3344 		map->p[i] = isl_basic_map_eliminate_vars(map->p[i],
   3345 			isl_basic_map_offset(map->p[i], type) - 1 + first, n);
   3346 		if (!map->p[i])
   3347 			goto error;
   3348 	}
   3349 	map = isl_map_drop(map, type, first, n);
   3350 	return map;
   3351 error:
   3352 	isl_map_free(map);
   3353 	return NULL;
   3354 }
   3355 
   3356 __isl_give isl_set *isl_set_remove_dims(__isl_take isl_set *bset,
   3357 	enum isl_dim_type type, unsigned first, unsigned n)
   3358 {
   3359 	return set_from_map(isl_map_remove_dims(set_to_map(bset),
   3360 						type, first, n));
   3361 }
   3362 
   3363 /* Project out n inputs starting at first using Fourier-Motzkin */
   3364 __isl_give isl_map *isl_map_remove_inputs(__isl_take isl_map *map,
   3365 	unsigned first, unsigned n)
   3366 {
   3367 	return isl_map_remove_dims(map, isl_dim_in, first, n);
   3368 }
   3369 
   3370 void isl_basic_set_print_internal(__isl_keep isl_basic_set *bset,
   3371 	FILE *out, int indent)
   3372 {
   3373 	isl_printer *p;
   3374 
   3375 	if (!bset) {
   3376 		fprintf(out, "null basic set\n");
   3377 		return;
   3378 	}
   3379 
   3380 	fprintf(out, "%*s", indent, "");
   3381 	fprintf(out, "ref: %d, nparam: %d, dim: %d, extra: %d, flags: %x\n",
   3382 			bset->ref, bset->dim->nparam, bset->dim->n_out,
   3383 			bset->extra, bset->flags);
   3384 
   3385 	p = isl_printer_to_file(isl_basic_set_get_ctx(bset), out);
   3386 	p = isl_printer_set_dump(p, 1);
   3387 	p = isl_printer_set_indent(p, indent);
   3388 	p = isl_printer_start_line(p);
   3389 	p = isl_printer_print_basic_set(p, bset);
   3390 	p = isl_printer_end_line(p);
   3391 	isl_printer_free(p);
   3392 }
   3393 
   3394 void isl_basic_map_print_internal(__isl_keep isl_basic_map *bmap,
   3395 	FILE *out, int indent)
   3396 {
   3397 	isl_printer *p;
   3398 
   3399 	if (!bmap) {
   3400 		fprintf(out, "null basic map\n");
   3401 		return;
   3402 	}
   3403 
   3404 	fprintf(out, "%*s", indent, "");
   3405 	fprintf(out, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "
   3406 			"flags: %x, n_name: %d\n",
   3407 		bmap->ref,
   3408 		bmap->dim->nparam, bmap->dim->n_in, bmap->dim->n_out,
   3409 		bmap->extra, bmap->flags, bmap->dim->n_id);
   3410 
   3411 	p = isl_printer_to_file(isl_basic_map_get_ctx(bmap), out);
   3412 	p = isl_printer_set_dump(p, 1);
   3413 	p = isl_printer_set_indent(p, indent);
   3414 	p = isl_printer_start_line(p);
   3415 	p = isl_printer_print_basic_map(p, bmap);
   3416 	p = isl_printer_end_line(p);
   3417 	isl_printer_free(p);
   3418 }
   3419 
   3420 __isl_give isl_basic_map *isl_inequality_negate(__isl_take isl_basic_map *bmap,
   3421 	unsigned pos)
   3422 {
   3423 	isl_size total;
   3424 
   3425 	total = isl_basic_map_dim(bmap, isl_dim_all);
   3426 	if (total < 0)
   3427 		return isl_basic_map_free(bmap);
   3428 	if (pos >= bmap->n_ineq)
   3429 		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
   3430 			"invalid position", return isl_basic_map_free(bmap));
   3431 	isl_seq_neg(bmap->ineq[pos], bmap->ineq[pos], 1 + total);
   3432 	isl_int_sub_ui(bmap->ineq[pos][0], bmap->ineq[pos][0], 1);
   3433 	ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
   3434 	ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
   3435 	return bmap;
   3436 }
   3437 
   3438 __isl_give isl_set *isl_set_alloc_space(__isl_take isl_space *space, int n,
   3439 	unsigned flags)
   3440 {
   3441 	if (isl_space_check_is_set(space) < 0)
   3442 		goto error;
   3443 	return isl_map_alloc_space(space, n, flags);
   3444 error:
   3445 	isl_space_free(space);
   3446 	return NULL;
   3447 }
   3448 
   3449 /* Make sure "map" has room for at least "n" more basic maps.
   3450  */
   3451 __isl_give isl_map *isl_map_grow(__isl_take isl_map *map, int n)
   3452 {
   3453 	int i;
   3454 	struct isl_map *grown = NULL;
   3455 
   3456 	if (!map)
   3457 		return NULL;
   3458 	isl_assert(map->ctx, n >= 0, goto error);
   3459 	if (map->n + n <= map->size)
   3460 		return map;
   3461 	grown = isl_map_alloc_space(isl_map_get_space(map), map->n + n, map->flags);
   3462 	if (!grown)
   3463 		goto error;
   3464 	for (i = 0; i < map->n; ++i) {
   3465 		grown->p[i] = isl_basic_map_copy(map->p[i]);
   3466 		if (!grown->p[i])
   3467 			goto error;
   3468 		grown->n++;
   3469 	}
   3470 	isl_map_free(map);
   3471 	return grown;
   3472 error:
   3473 	isl_map_free(grown);
   3474 	isl_map_free(map);
   3475 	return NULL;
   3476 }
   3477 
   3478 /* Make sure "set" has room for at least "n" more basic sets.
   3479  */
   3480 __isl_give isl_set *isl_set_grow(__isl_take isl_set *set, int n)
   3481 {
   3482 	return set_from_map(isl_map_grow(set_to_map(set), n));
   3483 }
   3484 
   3485 __isl_give isl_set *isl_set_from_basic_set(__isl_take isl_basic_set *bset)
   3486 {
   3487 	return isl_map_from_basic_map(bset);
   3488 }
   3489 
   3490 /* This function performs the same operation as isl_set_from_basic_set,
   3491  * but is considered as a function on an isl_basic_set when exported.
   3492  */
   3493 __isl_give isl_set *isl_basic_set_to_set(__isl_take isl_basic_set *bset)
   3494 {
   3495 	return isl_set_from_basic_set(bset);
   3496 }
   3497 
   3498 __isl_give isl_map *isl_map_from_basic_map(__isl_take isl_basic_map *bmap)
   3499 {
   3500 	struct isl_map *map;
   3501 
   3502 	if (!bmap)
   3503 		return NULL;
   3504 
   3505 	map = isl_map_alloc_space(isl_space_copy(bmap->dim), 1, ISL_MAP_DISJOINT);
   3506 	return isl_map_add_basic_map(map, bmap);
   3507 }
   3508 
   3509 __isl_give isl_set *isl_set_add_basic_set(__isl_take isl_set *set,
   3510 						__isl_take isl_basic_set *bset)
   3511 {
   3512 	return set_from_map(isl_map_add_basic_map(set_to_map(set),
   3513 						bset_to_bmap(bset)));
   3514 }
   3515 
   3516 __isl_null isl_set *isl_set_free(__isl_take isl_set *set)
   3517 {
   3518 	return isl_map_free(set);
   3519 }
   3520 
   3521 void isl_set_print_internal(__isl_keep isl_set *set, FILE *out, int indent)
   3522 {
   3523 	int i;
   3524 
   3525 	if (!set) {
   3526 		fprintf(out, "null set\n");
   3527 		return;
   3528 	}
   3529 
   3530 	fprintf(out, "%*s", indent, "");
   3531 	fprintf(out, "ref: %d, n: %d, nparam: %d, dim: %d, flags: %x\n",
   3532 			set->ref, set->n, set->dim->nparam, set->dim->n_out,
   3533 			set->flags);
   3534 	for (i = 0; i < set->n; ++i) {
   3535 		fprintf(out, "%*s", indent, "");
   3536 		fprintf(out, "basic set %d:\n", i);
   3537 		isl_basic_set_print_internal(set->p[i], out, indent+4);
   3538 	}
   3539 }
   3540 
   3541 void isl_map_print_internal(__isl_keep isl_map *map, FILE *out, int indent)
   3542 {
   3543 	int i;
   3544 
   3545 	if (!map) {
   3546 		fprintf(out, "null map\n");
   3547 		return;
   3548 	}
   3549 
   3550 	fprintf(out, "%*s", indent, "");
   3551 	fprintf(out, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, "
   3552 		     "flags: %x, n_name: %d\n",
   3553 			map->ref, map->n, map->dim->nparam, map->dim->n_in,
   3554 			map->dim->n_out, map->flags, map->dim->n_id);
   3555 	for (i = 0; i < map->n; ++i) {
   3556 		fprintf(out, "%*s", indent, "");
   3557 		fprintf(out, "basic map %d:\n", i);
   3558 		isl_basic_map_print_internal(map->p[i], out, indent+4);
   3559 	}
   3560 }
   3561 
   3562 /* Check that the space of "bset" is the same as that of the domain of "bmap".
   3563  */
   3564 static isl_stat isl_basic_map_check_compatible_domain(
   3565 	__isl_keep isl_basic_map *bmap, __isl_keep isl_basic_set *bset)
   3566 {
   3567 	isl_bool ok;
   3568 
   3569 	ok = isl_basic_map_compatible_domain(bmap, bset);
   3570 	if (ok < 0)
   3571 		return isl_stat_error;
   3572 	if (!ok)
   3573 		isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,
   3574 			"incompatible spaces", return isl_stat_error);
   3575 
   3576 	return isl_stat_ok;
   3577 }
   3578 
   3579 __isl_give isl_basic_map *isl_basic_map_intersect_domain(
   3580 	__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *bset)
   3581 {
   3582 	struct isl_basic_map *bmap_domain;
   3583 	isl_size dim;
   3584 
   3585 	if (isl_basic_map_check_equal_params(bmap, bset_to_bmap(bset)) < 0)
   3586 		goto error;
   3587 
   3588 	dim = isl_basic_set_dim(bset, isl_dim_set);
   3589 	if (dim < 0)
   3590 		goto error;
   3591 	if (dim != 0 &&
   3592 	    isl_basic_map_check_compatible_domain(bmap, bset) < 0)
   3593 		goto error;
   3594 
   3595 	bmap = isl_basic_map_cow(bmap);
   3596 	if (!bmap)
   3597 		goto error;
   3598 	bmap = isl_basic_map_extend(bmap,
   3599 			bset->n_div, bset->n_eq, bset->n_ineq);
   3600 	bmap_domain = isl_basic_map_from_domain(bset);
   3601 	bmap = add_constraints(bmap, bmap_domain, 0, 0);
   3602 
   3603 	bmap = isl_basic_map_simplify(bmap);
   3604 	return isl_basic_map_finalize(bmap);
   3605 error:
   3606 	isl_basic_map_free(bmap);
   3607 	isl_basic_set_free(bset);
   3608 	return NULL;
   3609 }
   3610 
   3611 /* Check that the space of "bset" is the same as that of the range of "bmap".
   3612  */
   3613 static isl_stat isl_basic_map_check_compatible_range(
   3614 	__isl_keep isl_basic_map *bmap, __isl_keep isl_basic_set *bset)
   3615 {
   3616 	isl_bool ok;
   3617 
   3618 	ok = isl_basic_map_compatible_range(bmap, bset);
   3619 	if (ok < 0)
   3620 		return isl_stat_error;
   3621 	if (!ok)
   3622 		isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,
   3623 			"incompatible spaces", return isl_stat_error);
   3624 
   3625 	return isl_stat_ok;
   3626 }
   3627 
   3628 __isl_give isl_basic_map *isl_basic_map_intersect_range(
   3629 	__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *bset)
   3630 {
   3631 	struct isl_basic_map *bmap_range;
   3632 	isl_size dim;
   3633 
   3634 	if (isl_basic_map_check_equal_params(bmap, bset_to_bmap(bset)) < 0)
   3635 		goto error;
   3636 
   3637 	dim = isl_basic_set_dim(bset, isl_dim_set);
   3638 	if (dim < 0)
   3639 		goto error;
   3640 	if (dim != 0 && isl_basic_map_check_compatible_range(bmap, bset) < 0)
   3641 		goto error;
   3642 
   3643 	if (isl_basic_set_plain_is_universe(bset)) {
   3644 		isl_basic_set_free(bset);
   3645 		return bmap;
   3646 	}
   3647 
   3648 	bmap = isl_basic_map_cow(bmap);
   3649 	if (!bmap)
   3650 		goto error;
   3651 	bmap = isl_basic_map_extend(bmap,
   3652 			bset->n_div, bset->n_eq, bset->n_ineq);
   3653 	bmap_range = bset_to_bmap(bset);
   3654 	bmap = add_constraints(bmap, bmap_range, 0, 0);
   3655 
   3656 	bmap = isl_basic_map_simplify(bmap);
   3657 	return isl_basic_map_finalize(bmap);
   3658 error:
   3659 	isl_basic_map_free(bmap);
   3660 	isl_basic_set_free(bset);
   3661 	return NULL;
   3662 }
   3663 
   3664 isl_bool isl_basic_map_contains(__isl_keep isl_basic_map *bmap,
   3665 	__isl_keep isl_vec *vec)
   3666 {
   3667 	int i;
   3668 	isl_size total;
   3669 	isl_int s;
   3670 
   3671 	total = isl_basic_map_dim(bmap, isl_dim_all);
   3672 	if (total < 0 || !vec)
   3673 		return isl_bool_error;
   3674 
   3675 	if (1 + total != vec->size)
   3676 		return isl_bool_false;
   3677 
   3678 	isl_int_init(s);
   3679 
   3680 	for (i = 0; i < bmap->n_eq; ++i) {
   3681 		isl_seq_inner_product(vec->el, bmap->eq[i], 1 + total, &s);
   3682 		if (!isl_int_is_zero(s)) {
   3683 			isl_int_clear(s);
   3684 			return isl_bool_false;
   3685 		}
   3686 	}
   3687 
   3688 	for (i = 0; i < bmap->n_ineq; ++i) {
   3689 		isl_seq_inner_product(vec->el, bmap->ineq[i], 1 + total, &s);
   3690 		if (isl_int_is_neg(s)) {
   3691 			isl_int_clear(s);
   3692 			return isl_bool_false;
   3693 		}
   3694 	}
   3695 
   3696 	isl_int_clear(s);
   3697 
   3698 	return isl_bool_true;
   3699 }
   3700 
   3701 isl_bool isl_basic_set_contains(__isl_keep isl_basic_set *bset,
   3702 	__isl_keep isl_vec *vec)
   3703 {
   3704 	return isl_basic_map_contains(bset_to_bmap(bset), vec);
   3705 }
   3706 
   3707 __isl_give isl_basic_map *isl_basic_map_intersect(
   3708 	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
   3709 {
   3710 	struct isl_vec *sample = NULL;
   3711 	isl_space *space1, *space2;
   3712 	isl_size dim1, dim2, nparam1, nparam2;
   3713 
   3714 	if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
   3715 		goto error;
   3716 	space1 = isl_basic_map_peek_space(bmap1);
   3717 	space2 = isl_basic_map_peek_space(bmap2);
   3718 	dim1 = isl_space_dim(space1, isl_dim_all);
   3719 	dim2 = isl_space_dim(space2, isl_dim_all);
   3720 	nparam1 = isl_space_dim(space1, isl_dim_param);
   3721 	nparam2 = isl_space_dim(space2, isl_dim_param);
   3722 	if (dim1 < 0 || dim2 < 0 || nparam1 < 0 || nparam2 < 0)
   3723 		goto error;
   3724 	if (dim1 == nparam1 && dim2 != nparam2)
   3725 		return isl_basic_map_intersect(bmap2, bmap1);
   3726 
   3727 	if (dim2 != nparam2 &&
   3728 	    isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
   3729 		goto error;
   3730 
   3731 	if (isl_basic_map_plain_is_empty(bmap1)) {
   3732 		isl_basic_map_free(bmap2);
   3733 		return bmap1;
   3734 	}
   3735 	if (isl_basic_map_plain_is_empty(bmap2)) {
   3736 		isl_basic_map_free(bmap1);
   3737 		return bmap2;
   3738 	}
   3739 
   3740 	if (bmap1->sample &&
   3741 	    isl_basic_map_contains(bmap1, bmap1->sample) > 0 &&
   3742 	    isl_basic_map_contains(bmap2, bmap1->sample) > 0)
   3743 		sample = isl_vec_copy(bmap1->sample);
   3744 	else if (bmap2->sample &&
   3745 	    isl_basic_map_contains(bmap1, bmap2->sample) > 0 &&
   3746 	    isl_basic_map_contains(bmap2, bmap2->sample) > 0)
   3747 		sample = isl_vec_copy(bmap2->sample);
   3748 
   3749 	bmap1 = isl_basic_map_cow(bmap1);
   3750 	if (!bmap1)
   3751 		goto error;
   3752 	bmap1 = isl_basic_map_extend(bmap1,
   3753 			bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
   3754 	bmap1 = add_constraints(bmap1, bmap2, 0, 0);
   3755 
   3756 	if (!bmap1)
   3757 		isl_vec_free(sample);
   3758 	else if (sample) {
   3759 		isl_vec_free(bmap1->sample);
   3760 		bmap1->sample = sample;
   3761 	}
   3762 
   3763 	bmap1 = isl_basic_map_simplify(bmap1);
   3764 	return isl_basic_map_finalize(bmap1);
   3765 error:
   3766 	if (sample)
   3767 		isl_vec_free(sample);
   3768 	isl_basic_map_free(bmap1);
   3769 	isl_basic_map_free(bmap2);
   3770 	return NULL;
   3771 }
   3772 
   3773 __isl_give isl_basic_set *isl_basic_set_intersect(
   3774 	__isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
   3775 {
   3776 	return bset_from_bmap(isl_basic_map_intersect(bset_to_bmap(bset1),
   3777 							bset_to_bmap(bset2)));
   3778 }
   3779 
   3780 __isl_give isl_basic_set *isl_basic_set_intersect_params(
   3781 	__isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
   3782 {
   3783 	return isl_basic_set_intersect(bset1, bset2);
   3784 }
   3785 
   3786 /* Does "map" consist of a single disjunct, without any local variables?
   3787  */
   3788 static isl_bool is_convex_no_locals(__isl_keep isl_map *map)
   3789 {
   3790 	isl_size n_div;
   3791 
   3792 	if (!map)
   3793 		return isl_bool_error;
   3794 	if (map->n != 1)
   3795 		return isl_bool_false;
   3796 	n_div = isl_basic_map_dim(map->p[0], isl_dim_div);
   3797 	if (n_div < 0)
   3798 		return isl_bool_error;
   3799 	if (n_div != 0)
   3800 		return isl_bool_false;
   3801 	return isl_bool_true;
   3802 }
   3803 
   3804 /* Check that "map" consists of a single disjunct, without any local variables.
   3805  */
   3806 static isl_stat check_convex_no_locals(__isl_keep isl_map *map)
   3807 {
   3808 	isl_bool ok;
   3809 
   3810 	ok = is_convex_no_locals(map);
   3811 	if (ok < 0)
   3812 		return isl_stat_error;
   3813 	if (ok)
   3814 		return isl_stat_ok;
   3815 
   3816 	isl_die(isl_map_get_ctx(map), isl_error_internal,
   3817 		"unexpectedly not convex or involving local variables",
   3818 		return isl_stat_error);
   3819 }
   3820 
   3821 /* Special case of isl_map_intersect, where both map1 and map2
   3822  * are convex, without any divs and such that either map1 or map2
   3823  * contains a single constraint.  This constraint is then simply
   3824  * added to the other map.
   3825  */
   3826 static __isl_give isl_map *map_intersect_add_constraint(
   3827 	__isl_take isl_map *map1, __isl_take isl_map *map2)
   3828 {
   3829 	if (check_convex_no_locals(map1) < 0 ||
   3830 	    check_convex_no_locals(map2) < 0)
   3831 		goto error;
   3832 
   3833 	if (map2->p[0]->n_eq + map2->p[0]->n_ineq != 1)
   3834 		return isl_map_intersect(map2, map1);
   3835 
   3836 	map1 = isl_map_cow(map1);
   3837 	if (!map1)
   3838 		goto error;
   3839 	if (isl_map_plain_is_empty(map1)) {
   3840 		isl_map_free(map2);
   3841 		return map1;
   3842 	}
   3843 	if (map2->p[0]->n_eq == 1)
   3844 		map1->p[0] = isl_basic_map_add_eq(map1->p[0], map2->p[0]->eq[0]);
   3845 	else
   3846 		map1->p[0] = isl_basic_map_add_ineq(map1->p[0],
   3847 							map2->p[0]->ineq[0]);
   3848 
   3849 	map1->p[0] = isl_basic_map_simplify(map1->p[0]);
   3850 	map1->p[0] = isl_basic_map_finalize(map1->p[0]);
   3851 	if (!map1->p[0])
   3852 		goto error;
   3853 
   3854 	if (isl_basic_map_plain_is_empty(map1->p[0])) {
   3855 		isl_basic_map_free(map1->p[0]);
   3856 		map1->n = 0;
   3857 	}
   3858 
   3859 	isl_map_free(map2);
   3860 
   3861 	map1 = isl_map_unmark_normalized(map1);
   3862 	return map1;
   3863 error:
   3864 	isl_map_free(map1);
   3865 	isl_map_free(map2);
   3866 	return NULL;
   3867 }
   3868 
   3869 /* map2 may be either a parameter domain or a map living in the same
   3870  * space as map1.
   3871  */
   3872 static __isl_give isl_map *map_intersect_internal(__isl_take isl_map *map1,
   3873 	__isl_take isl_map *map2)
   3874 {
   3875 	unsigned flags = 0;
   3876 	isl_bool equal;
   3877 	isl_map *result;
   3878 	int i, j;
   3879 	isl_size dim2, nparam2;
   3880 
   3881 	if (!map1 || !map2)
   3882 		goto error;
   3883 
   3884 	if ((isl_map_plain_is_empty(map1) ||
   3885 	     isl_map_plain_is_universe(map2)) &&
   3886 	    isl_space_is_equal(map1->dim, map2->dim)) {
   3887 		isl_map_free(map2);
   3888 		return map1;
   3889 	}
   3890 	if ((isl_map_plain_is_empty(map2) ||
   3891 	     isl_map_plain_is_universe(map1)) &&
   3892 	    isl_space_is_equal(map1->dim, map2->dim)) {
   3893 		isl_map_free(map1);
   3894 		return map2;
   3895 	}
   3896 
   3897 	if (is_convex_no_locals(map1) == isl_bool_true &&
   3898 	    is_convex_no_locals(map2) == isl_bool_true &&
   3899 	    isl_space_is_equal(map1->dim, map2->dim) &&
   3900 	    (map1->p[0]->n_eq + map1->p[0]->n_ineq == 1 ||
   3901 	     map2->p[0]->n_eq + map2->p[0]->n_ineq == 1))
   3902 		return map_intersect_add_constraint(map1, map2);
   3903 
   3904 	equal = isl_map_plain_is_equal(map1, map2);
   3905 	if (equal < 0)
   3906 		goto error;
   3907 	if (equal) {
   3908 		isl_map_free(map2);
   3909 		return map1;
   3910 	}
   3911 
   3912 	dim2 = isl_map_dim(map2, isl_dim_all);
   3913 	nparam2 = isl_map_dim(map2, isl_dim_param);
   3914 	if (dim2 < 0 || nparam2 < 0)
   3915 		goto error;
   3916 	if (dim2 != nparam2)
   3917 		isl_assert(map1->ctx,
   3918 			    isl_space_is_equal(map1->dim, map2->dim), goto error);
   3919 
   3920 	if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
   3921 	    ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
   3922 		ISL_FL_SET(flags, ISL_MAP_DISJOINT);
   3923 
   3924 	result = isl_map_alloc_space(isl_space_copy(map1->dim),
   3925 				map1->n * map2->n, flags);
   3926 	if (!result)
   3927 		goto error;
   3928 	for (i = 0; i < map1->n; ++i)
   3929 		for (j = 0; j < map2->n; ++j) {
   3930 			struct isl_basic_map *part;
   3931 			part = isl_basic_map_intersect(
   3932 				    isl_basic_map_copy(map1->p[i]),
   3933 				    isl_basic_map_copy(map2->p[j]));
   3934 			if (isl_basic_map_is_empty(part) < 0)
   3935 				part = isl_basic_map_free(part);
   3936 			result = isl_map_add_basic_map(result, part);
   3937 			if (!result)
   3938 				goto error;
   3939 		}
   3940 	isl_map_free(map1);
   3941 	isl_map_free(map2);
   3942 	return result;
   3943 error:
   3944 	isl_map_free(map1);
   3945 	isl_map_free(map2);
   3946 	return NULL;
   3947 }
   3948 
   3949 static __isl_give isl_map *map_intersect(__isl_take isl_map *map1,
   3950 	__isl_take isl_map *map2)
   3951 {
   3952 	if (isl_map_check_equal_space(map1, map2) < 0)
   3953 		goto error;
   3954 	return map_intersect_internal(map1, map2);
   3955 error:
   3956 	isl_map_free(map1);
   3957 	isl_map_free(map2);
   3958 	return NULL;
   3959 }
   3960 
   3961 __isl_give isl_map *isl_map_intersect(__isl_take isl_map *map1,
   3962 	__isl_take isl_map *map2)
   3963 {
   3964 	isl_map_align_params_bin(&map1, &map2);
   3965 	return map_intersect(map1, map2);
   3966 }
   3967 
   3968 __isl_give isl_set *isl_set_intersect(__isl_take isl_set *set1,
   3969 	__isl_take isl_set *set2)
   3970 {
   3971 	return set_from_map(isl_map_intersect(set_to_map(set1),
   3972 					      set_to_map(set2)));
   3973 }
   3974 
   3975 /* map_intersect_internal accepts intersections
   3976  * with parameter domains, so we can just call that function.
   3977  */
   3978 __isl_give isl_map *isl_map_intersect_params(__isl_take isl_map *map,
   3979 	__isl_take isl_set *params)
   3980 {
   3981 	isl_map_align_params_set(&map, &params);
   3982 	return map_intersect_internal(map, params);
   3983 }
   3984 
   3985 __isl_give isl_set *isl_set_intersect_params(__isl_take isl_set *set,
   3986 		__isl_take isl_set *params)
   3987 {
   3988 	return isl_map_intersect_params(set, params);
   3989 }
   3990 
   3991 __isl_give isl_basic_map *isl_basic_map_reverse(__isl_take isl_basic_map *bmap)
   3992 {
   3993 	isl_space *space;
   3994 	unsigned pos;
   3995 	isl_size n1, n2;
   3996 
   3997 	if (!bmap)
   3998 		return NULL;
   3999 	bmap = isl_basic_map_cow(bmap);
   4000 	if (!bmap)
   4001 		return NULL;
   4002 	space = isl_space_reverse(isl_space_copy(bmap->dim));
   4003 	pos = isl_basic_map_offset(bmap, isl_dim_in);
   4004 	n1 = isl_basic_map_dim(bmap, isl_dim_in);
   4005 	n2 = isl_basic_map_dim(bmap, isl_dim_out);
   4006 	if (n1 < 0 || n2 < 0)
   4007 		bmap = isl_basic_map_free(bmap);
   4008 	bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
   4009 	return isl_basic_map_reset_space(bmap, space);
   4010 }
   4011 
   4012 /* Given a basic map where the tuple of type "type" is a wrapped map,
   4013  * swap domain and range of that wrapped map.
   4014  */
   4015 static __isl_give isl_basic_map *isl_basic_map_reverse_wrapped(
   4016 	__isl_take isl_basic_map *bmap, enum isl_dim_type type)
   4017 {
   4018 	isl_space *space;
   4019 	isl_size offset, n1, n2;
   4020 
   4021 	space = isl_basic_map_peek_space(bmap);
   4022 	offset = isl_basic_map_var_offset(bmap, type);
   4023 	n1 = isl_space_wrapped_dim(space, type, isl_dim_in);
   4024 	n2 = isl_space_wrapped_dim(space, type, isl_dim_out);
   4025 	if (offset < 0 || n1 < 0 || n2 < 0)
   4026 		return isl_basic_map_free(bmap);
   4027 
   4028 	bmap = isl_basic_map_swap_vars(bmap, 1 + offset, n1, n2);
   4029 
   4030 	space = isl_basic_map_take_space(bmap);
   4031 	space = isl_space_reverse_wrapped(space, type);
   4032 	bmap = isl_basic_map_restore_space(bmap, space);
   4033 
   4034 	return bmap;
   4035 }
   4036 
   4037 /* Given a basic map (A -> B) -> C, return the corresponding basic map
   4038  * (B -> A) -> C.
   4039  */
   4040 static __isl_give isl_basic_map *isl_basic_map_domain_reverse(
   4041 	__isl_take isl_basic_map *bmap)
   4042 {
   4043 	isl_space *space;
   4044 
   4045 	space = isl_basic_map_peek_space(bmap);
   4046 	if (isl_space_check_domain_is_wrapping(space) < 0)
   4047 		return isl_basic_map_free(bmap);
   4048 	bmap = isl_basic_map_reverse_wrapped(bmap, isl_dim_in);
   4049 
   4050 	return bmap;
   4051 }
   4052 
   4053 /* Given a basic map A -> (B -> C), return the corresponding basic map
   4054  * A -> (C -> B).
   4055  */
   4056 static __isl_give isl_basic_map *isl_basic_map_range_reverse(
   4057 	__isl_take isl_basic_map *bmap)
   4058 {
   4059 	isl_space *space;
   4060 
   4061 	space = isl_basic_map_peek_space(bmap);
   4062 	if (isl_space_check_range_is_wrapping(space) < 0)
   4063 		return isl_basic_map_free(bmap);
   4064 	bmap = isl_basic_map_reverse_wrapped(bmap, isl_dim_out);
   4065 
   4066 	return bmap;
   4067 }
   4068 
   4069 /* Given a basic map that is actually a basic set (A -> B),
   4070  * return the corresponding basic set (B -> A) as a basic map.
   4071  */
   4072 static __isl_give isl_basic_map *isl_basic_map_set_reverse(
   4073 	__isl_take isl_basic_map *bmap)
   4074 {
   4075 	isl_space *space;
   4076 
   4077 	space = isl_basic_map_peek_space(bmap);
   4078 	if (isl_space_check_is_wrapping(space) < 0)
   4079 		return isl_basic_map_free(bmap);
   4080 	bmap = isl_basic_map_reverse_wrapped(bmap, isl_dim_set);
   4081 
   4082 	return bmap;
   4083 }
   4084 
   4085 static __isl_give isl_basic_map *basic_map_space_reset(
   4086 	__isl_take isl_basic_map *bmap, enum isl_dim_type type)
   4087 {
   4088 	isl_space *space;
   4089 
   4090 	if (!bmap)
   4091 		return NULL;
   4092 	if (!isl_space_is_named_or_nested(bmap->dim, type))
   4093 		return bmap;
   4094 
   4095 	space = isl_basic_map_get_space(bmap);
   4096 	space = isl_space_reset(space, type);
   4097 	bmap = isl_basic_map_reset_space(bmap, space);
   4098 	return bmap;
   4099 }
   4100 
   4101 __isl_give isl_basic_map *isl_basic_map_insert_dims(
   4102 	__isl_take isl_basic_map *bmap, enum isl_dim_type type,
   4103 	unsigned pos, unsigned n)
   4104 {
   4105 	isl_bool rational, is_empty;
   4106 	isl_space *res_space;
   4107 	struct isl_basic_map *res;
   4108 	struct isl_dim_map *dim_map;
   4109 	isl_size total;
   4110 	unsigned off;
   4111 	enum isl_dim_type t;
   4112 
   4113 	if (n == 0)
   4114 		return basic_map_space_reset(bmap, type);
   4115 
   4116 	is_empty = isl_basic_map_plain_is_empty(bmap);
   4117 	total = isl_basic_map_dim(bmap, isl_dim_all);
   4118 	if (is_empty < 0 || total < 0)
   4119 		return isl_basic_map_free(bmap);
   4120 	res_space = isl_space_insert_dims(isl_basic_map_get_space(bmap),
   4121 					type, pos, n);
   4122 	if (!res_space)
   4123 		return isl_basic_map_free(bmap);
   4124 	if (is_empty) {
   4125 		isl_basic_map_free(bmap);
   4126 		return isl_basic_map_empty(res_space);
   4127 	}
   4128 
   4129 	dim_map = isl_dim_map_alloc(bmap->ctx, total + n);
   4130 	off = 0;
   4131 	for (t = isl_dim_param; t <= isl_dim_out; ++t) {
   4132 		isl_size dim;
   4133 
   4134 		if (t != type) {
   4135 			isl_dim_map_dim(dim_map, bmap->dim, t, off);
   4136 		} else {
   4137 			isl_size size = isl_basic_map_dim(bmap, t);
   4138 			if (size < 0)
   4139 				dim_map = isl_dim_map_free(dim_map);
   4140 			isl_dim_map_dim_range(dim_map, bmap->dim, t,
   4141 						0, pos, off);
   4142 			isl_dim_map_dim_range(dim_map, bmap->dim, t,
   4143 						pos, size - pos, off + pos + n);
   4144 		}
   4145 		dim = isl_space_dim(res_space, t);
   4146 		if (dim < 0)
   4147 			dim_map = isl_dim_map_free(dim_map);
   4148 		off += dim;
   4149 	}
   4150 	isl_dim_map_div(dim_map, bmap, off);
   4151 
   4152 	res = isl_basic_map_alloc_space(res_space,
   4153 			bmap->n_div, bmap->n_eq, bmap->n_ineq);
   4154 	rational = isl_basic_map_is_rational(bmap);
   4155 	if (rational < 0)
   4156 		res = isl_basic_map_free(res);
   4157 	if (rational)
   4158 		res = isl_basic_map_set_rational(res);
   4159 	res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
   4160 	return isl_basic_map_finalize(res);
   4161 }
   4162 
   4163 __isl_give isl_basic_set *isl_basic_set_insert_dims(
   4164 	__isl_take isl_basic_set *bset,
   4165 	enum isl_dim_type type, unsigned pos, unsigned n)
   4166 {
   4167 	return isl_basic_map_insert_dims(bset, type, pos, n);
   4168 }
   4169 
   4170 __isl_give isl_basic_map *isl_basic_map_add_dims(__isl_take isl_basic_map *bmap,
   4171 		enum isl_dim_type type, unsigned n)
   4172 {
   4173 	isl_size dim;
   4174 
   4175 	dim = isl_basic_map_dim(bmap, type);
   4176 	if (dim < 0)
   4177 		return isl_basic_map_free(bmap);
   4178 	return isl_basic_map_insert_dims(bmap, type, dim, n);
   4179 }
   4180 
   4181 __isl_give isl_basic_set *isl_basic_set_add_dims(__isl_take isl_basic_set *bset,
   4182 		enum isl_dim_type type, unsigned n)
   4183 {
   4184 	if (!bset)
   4185 		return NULL;
   4186 	isl_assert(bset->ctx, type != isl_dim_in, goto error);
   4187 	return isl_basic_map_add_dims(bset, type, n);
   4188 error:
   4189 	isl_basic_set_free(bset);
   4190 	return NULL;
   4191 }
   4192 
   4193 static __isl_give isl_map *map_space_reset(__isl_take isl_map *map,
   4194 	enum isl_dim_type type)
   4195 {
   4196 	isl_space *space;
   4197 
   4198 	if (!map || !isl_space_is_named_or_nested(map->dim, type))
   4199 		return map;
   4200 
   4201 	space = isl_map_get_space(map);
   4202 	space = isl_space_reset(space, type);
   4203 	map = isl_map_reset_space(map, space);
   4204 	return map;
   4205 }
   4206 
   4207 __isl_give isl_map *isl_map_insert_dims(__isl_take isl_map *map,
   4208 		enum isl_dim_type type, unsigned pos, unsigned n)
   4209 {
   4210 	int i;
   4211 	isl_space *space;
   4212 
   4213 	if (n == 0)
   4214 		return map_space_reset(map, type);
   4215 
   4216 	map = isl_map_cow(map);
   4217 	if (!map)
   4218 		return NULL;
   4219 
   4220 	for (i = 0; i < map->n; ++i) {
   4221 		map->p[i] = isl_basic_map_insert_dims(map->p[i], type, pos, n);
   4222 		if (!map->p[i])
   4223 			goto error;
   4224 	}
   4225 
   4226 	space = isl_map_take_space(map);
   4227 	space = isl_space_insert_dims(space, type, pos, n);
   4228 	map = isl_map_restore_space(map, space);
   4229 
   4230 	return map;
   4231 error:
   4232 	isl_map_free(map);
   4233 	return NULL;
   4234 }
   4235 
   4236 __isl_give isl_set *isl_set_insert_dims(__isl_take isl_set *set,
   4237 		enum isl_dim_type type, unsigned pos, unsigned n)
   4238 {
   4239 	return isl_map_insert_dims(set, type, pos, n);
   4240 }
   4241 
   4242 __isl_give isl_map *isl_map_add_dims(__isl_take isl_map *map,
   4243 		enum isl_dim_type type, unsigned n)
   4244 {
   4245 	isl_size dim;
   4246 
   4247 	dim = isl_map_dim(map, type);
   4248 	if (dim < 0)
   4249 		return isl_map_free(map);
   4250 	return isl_map_insert_dims(map, type, dim, n);
   4251 }
   4252 
   4253 __isl_give isl_set *isl_set_add_dims(__isl_take isl_set *set,
   4254 		enum isl_dim_type type, unsigned n)
   4255 {
   4256 	if (!set)
   4257 		return NULL;
   4258 	isl_assert(set->ctx, type != isl_dim_in, goto error);
   4259 	return set_from_map(isl_map_add_dims(set_to_map(set), type, n));
   4260 error:
   4261 	isl_set_free(set);
   4262 	return NULL;
   4263 }
   4264 
   4265 __isl_give isl_basic_map *isl_basic_map_move_dims(
   4266 	__isl_take isl_basic_map *bmap,
   4267 	enum isl_dim_type dst_type, unsigned dst_pos,
   4268 	enum isl_dim_type src_type, unsigned src_pos, unsigned n)
   4269 {
   4270 	isl_space *space;
   4271 	struct isl_dim_map *dim_map;
   4272 	struct isl_basic_map *res;
   4273 	enum isl_dim_type t;
   4274 	isl_size total;
   4275 	unsigned off;
   4276 
   4277 	if (!bmap)
   4278 		return NULL;
   4279 	if (n == 0) {
   4280 		bmap = isl_basic_map_reset(bmap, src_type);
   4281 		bmap = isl_basic_map_reset(bmap, dst_type);
   4282 		return bmap;
   4283 	}
   4284 
   4285 	if (isl_basic_map_check_range(bmap, src_type, src_pos, n) < 0)
   4286 		return isl_basic_map_free(bmap);
   4287 
   4288 	if (dst_type == src_type && dst_pos == src_pos)
   4289 		return bmap;
   4290 
   4291 	isl_assert(bmap->ctx, dst_type != src_type, goto error);
   4292 
   4293 	if (pos(bmap->dim, dst_type) + dst_pos ==
   4294 	    pos(bmap->dim, src_type) + src_pos +
   4295 					    ((src_type < dst_type) ? n : 0)) {
   4296 		space = isl_basic_map_take_space(bmap);
   4297 		space = isl_space_move_dims(space, dst_type, dst_pos,
   4298 						src_type, src_pos, n);
   4299 		bmap = isl_basic_map_restore_space(bmap, space);
   4300 		bmap = isl_basic_map_finalize(bmap);
   4301 
   4302 		return bmap;
   4303 	}
   4304 
   4305 	total = isl_basic_map_dim(bmap, isl_dim_all);
   4306 	if (total < 0)
   4307 		return isl_basic_map_free(bmap);
   4308 	dim_map = isl_dim_map_alloc(bmap->ctx, total);
   4309 
   4310 	off = 0;
   4311 	space = isl_basic_map_peek_space(bmap);
   4312 	for (t = isl_dim_param; t <= isl_dim_out; ++t) {
   4313 		isl_size size = isl_space_dim(space, t);
   4314 		if (size < 0)
   4315 			dim_map = isl_dim_map_free(dim_map);
   4316 		if (t == dst_type) {
   4317 			isl_dim_map_dim_range(dim_map, space, t,
   4318 					    0, dst_pos, off);
   4319 			off += dst_pos;
   4320 			isl_dim_map_dim_range(dim_map, space, src_type,
   4321 					    src_pos, n, off);
   4322 			off += n;
   4323 			isl_dim_map_dim_range(dim_map, space, t,
   4324 					    dst_pos, size - dst_pos, off);
   4325 			off += size - dst_pos;
   4326 		} else if (t == src_type) {
   4327 			isl_dim_map_dim_range(dim_map, space, t,
   4328 					    0, src_pos, off);
   4329 			off += src_pos;
   4330 			isl_dim_map_dim_range(dim_map, space, t,
   4331 					src_pos + n, size - src_pos - n, off);
   4332 			off += size - src_pos - n;
   4333 		} else {
   4334 			isl_dim_map_dim(dim_map, space, t, off);
   4335 			off += size;
   4336 		}
   4337 	}
   4338 	isl_dim_map_div(dim_map, bmap, off);
   4339 
   4340 	res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
   4341 			bmap->n_div, bmap->n_eq, bmap->n_ineq);
   4342 	bmap = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
   4343 	space = isl_basic_map_take_space(bmap);
   4344 	space = isl_space_move_dims(space, dst_type, dst_pos,
   4345 					src_type, src_pos, n);
   4346 	bmap = isl_basic_map_restore_space(bmap, space);
   4347 	if (!bmap)
   4348 		goto error;
   4349 
   4350 	ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
   4351 	bmap = isl_basic_map_gauss(bmap, NULL);
   4352 	bmap = isl_basic_map_finalize(bmap);
   4353 
   4354 	return bmap;
   4355 error:
   4356 	isl_basic_map_free(bmap);
   4357 	return NULL;
   4358 }
   4359 
   4360 __isl_give isl_basic_set *isl_basic_set_move_dims(__isl_take isl_basic_set *bset,
   4361 	enum isl_dim_type dst_type, unsigned dst_pos,
   4362 	enum isl_dim_type src_type, unsigned src_pos, unsigned n)
   4363 {
   4364 	isl_basic_map *bmap = bset_to_bmap(bset);
   4365 	bmap = isl_basic_map_move_dims(bmap, dst_type, dst_pos,
   4366 					src_type, src_pos, n);
   4367 	return bset_from_bmap(bmap);
   4368 }
   4369 
   4370 __isl_give isl_set *isl_set_move_dims(__isl_take isl_set *set,
   4371 	enum isl_dim_type dst_type, unsigned dst_pos,
   4372 	enum isl_dim_type src_type, unsigned src_pos, unsigned n)
   4373 {
   4374 	if (!set)
   4375 		return NULL;
   4376 	isl_assert(set->ctx, dst_type != isl_dim_in, goto error);
   4377 	return set_from_map(isl_map_move_dims(set_to_map(set),
   4378 				    dst_type, dst_pos, src_type, src_pos, n));
   4379 error:
   4380 	isl_set_free(set);
   4381 	return NULL;
   4382 }
   4383 
   4384 __isl_give isl_map *isl_map_move_dims(__isl_take isl_map *map,
   4385 	enum isl_dim_type dst_type, unsigned dst_pos,
   4386 	enum isl_dim_type src_type, unsigned src_pos, unsigned n)
   4387 {
   4388 	int i;
   4389 	isl_space *space;
   4390 
   4391 	if (n == 0) {
   4392 		map = isl_map_reset(map, src_type);
   4393 		map = isl_map_reset(map, dst_type);
   4394 		return map;
   4395 	}
   4396 
   4397 	if (isl_map_check_range(map, src_type, src_pos, n))
   4398 		return isl_map_free(map);
   4399 
   4400 	if (dst_type == src_type && dst_pos == src_pos)
   4401 		return map;
   4402 
   4403 	isl_assert(map->ctx, dst_type != src_type, goto error);
   4404 
   4405 	map = isl_map_cow(map);
   4406 	if (!map)
   4407 		return NULL;
   4408 
   4409 	for (i = 0; i < map->n; ++i) {
   4410 		map->p[i] = isl_basic_map_move_dims(map->p[i],
   4411 						dst_type, dst_pos,
   4412 						src_type, src_pos, n);
   4413 		if (!map->p[i])
   4414 			goto error;
   4415 	}
   4416 
   4417 	space = isl_map_take_space(map);
   4418 	space = isl_space_move_dims(space, dst_type, dst_pos,
   4419 					    src_type, src_pos, n);
   4420 	map = isl_map_restore_space(map, space);
   4421 
   4422 	return map;
   4423 error:
   4424 	isl_map_free(map);
   4425 	return NULL;
   4426 }
   4427 
   4428 /* Move the specified dimensions to the last columns right before
   4429  * the divs.  Don't change the dimension specification of bmap.
   4430  * That's the responsibility of the caller.
   4431  */
   4432 static __isl_give isl_basic_map *move_last(__isl_take isl_basic_map *bmap,
   4433 	enum isl_dim_type type, unsigned first, unsigned n)
   4434 {
   4435 	isl_space *space;
   4436 	struct isl_dim_map *dim_map;
   4437 	struct isl_basic_map *res;
   4438 	enum isl_dim_type t;
   4439 	isl_size total;
   4440 	unsigned off;
   4441 
   4442 	if (!bmap)
   4443 		return NULL;
   4444 	if (isl_basic_map_offset(bmap, type) + first + n ==
   4445 				isl_basic_map_offset(bmap, isl_dim_div))
   4446 		return bmap;
   4447 
   4448 	total = isl_basic_map_dim(bmap, isl_dim_all);
   4449 	if (total < 0)
   4450 		return isl_basic_map_free(bmap);
   4451 	dim_map = isl_dim_map_alloc(bmap->ctx, total);
   4452 
   4453 	off = 0;
   4454 	space = isl_basic_map_peek_space(bmap);
   4455 	for (t = isl_dim_param; t <= isl_dim_out; ++t) {
   4456 		isl_size size = isl_space_dim(space, t);
   4457 		if (size < 0)
   4458 			dim_map = isl_dim_map_free(dim_map);
   4459 		if (t == type) {
   4460 			isl_dim_map_dim_range(dim_map, space, t,
   4461 					    0, first, off);
   4462 			off += first;
   4463 			isl_dim_map_dim_range(dim_map, space, t,
   4464 					    first, n, total - bmap->n_div - n);
   4465 			isl_dim_map_dim_range(dim_map, space, t,
   4466 					    first + n, size - (first + n), off);
   4467 			off += size - (first + n);
   4468 		} else {
   4469 			isl_dim_map_dim(dim_map, space, t, off);
   4470 			off += size;
   4471 		}
   4472 	}
   4473 	isl_dim_map_div(dim_map, bmap, off + n);
   4474 
   4475 	res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
   4476 			bmap->n_div, bmap->n_eq, bmap->n_ineq);
   4477 	res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
   4478 	return res;
   4479 }
   4480 
   4481 /* Insert "n" rows in the divs of "bmap".
   4482  *
   4483  * The number of columns is not changed, which means that the last
   4484  * dimensions of "bmap" are being reintepreted as the new divs.
   4485  * The space of "bmap" is not adjusted, however, which means
   4486  * that "bmap" is left in an inconsistent state.  Removing "n" dimensions
   4487  * from the space of "bmap" is the responsibility of the caller.
   4488  */
   4489 static __isl_give isl_basic_map *insert_div_rows(__isl_take isl_basic_map *bmap,
   4490 	int n)
   4491 {
   4492 	int i;
   4493 	size_t row_size;
   4494 	isl_int **new_div;
   4495 	isl_int *old;
   4496 
   4497 	bmap = isl_basic_map_cow(bmap);
   4498 	if (!bmap)
   4499 		return NULL;
   4500 
   4501 	row_size = isl_basic_map_offset(bmap, isl_dim_div) + bmap->extra;
   4502 	old = bmap->block2.data;
   4503 	bmap->block2 = isl_blk_extend(bmap->ctx, bmap->block2,
   4504 					(bmap->extra + n) * (1 + row_size));
   4505 	if (!bmap->block2.data)
   4506 		return isl_basic_map_free(bmap);
   4507 	new_div = isl_alloc_array(bmap->ctx, isl_int *, bmap->extra + n);
   4508 	if (!new_div)
   4509 		return isl_basic_map_free(bmap);
   4510 	for (i = 0; i < n; ++i) {
   4511 		new_div[i] = bmap->block2.data +
   4512 				(bmap->extra + i) * (1 + row_size);
   4513 		isl_seq_clr(new_div[i], 1 + row_size);
   4514 	}
   4515 	for (i = 0; i < bmap->extra; ++i)
   4516 		new_div[n + i] = bmap->block2.data + (bmap->div[i] - old);
   4517 	free(bmap->div);
   4518 	bmap->div = new_div;
   4519 	bmap->n_div += n;
   4520 	bmap->extra += n;
   4521 
   4522 	return bmap;
   4523 }
   4524 
   4525 /* Drop constraints from "bmap" that only involve the variables
   4526  * of "type" in the range [first, first + n] that are not related
   4527  * to any of the variables outside that interval.
   4528  * These constraints cannot influence the values for the variables
   4529  * outside the interval, except in case they cause "bmap" to be empty.
   4530  * Only drop the constraints if "bmap" is known to be non-empty.
   4531  */
   4532 static __isl_give isl_basic_map *drop_irrelevant_constraints(
   4533 	__isl_take isl_basic_map *bmap, enum isl_dim_type type,
   4534 	unsigned first, unsigned n)
   4535 {
   4536 	int i;
   4537 	int *groups;
   4538 	isl_size dim, n_div;
   4539 	isl_bool non_empty;
   4540 
   4541 	non_empty = isl_basic_map_plain_is_non_empty(bmap);
   4542 	if (non_empty < 0)
   4543 		return isl_basic_map_free(bmap);
   4544 	if (!non_empty)
   4545 		return bmap;
   4546 
   4547 	dim = isl_basic_map_dim(bmap, isl_dim_all);
   4548 	n_div = isl_basic_map_dim(bmap, isl_dim_div);
   4549 	if (dim < 0 || n_div < 0)
   4550 		return isl_basic_map_free(bmap);
   4551 	groups = isl_calloc_array(isl_basic_map_get_ctx(bmap), int, dim);
   4552 	if (!groups)
   4553 		return isl_basic_map_free(bmap);
   4554 	first += isl_basic_map_offset(bmap, type) - 1;
   4555 	for (i = 0; i < first; ++i)
   4556 		groups[i] = -1;
   4557 	for (i = first + n; i < dim - n_div; ++i)
   4558 		groups[i] = -1;
   4559 
   4560 	bmap = isl_basic_map_drop_unrelated_constraints(bmap, groups);
   4561 
   4562 	return bmap;
   4563 }
   4564 
   4565 /* Turn the n dimensions of type type, starting at first
   4566  * into existentially quantified variables.
   4567  *
   4568  * If a subset of the projected out variables are unrelated
   4569  * to any of the variables that remain, then the constraints
   4570  * involving this subset are simply dropped first.
   4571  */
   4572 __isl_give isl_basic_map *isl_basic_map_project_out(
   4573 		__isl_take isl_basic_map *bmap,
   4574 		enum isl_dim_type type, unsigned first, unsigned n)
   4575 {
   4576 	isl_bool empty;
   4577 	isl_space *space;
   4578 
   4579 	if (n == 0)
   4580 		return basic_map_space_reset(bmap, type);
   4581 	if (type == isl_dim_div)
   4582 		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
   4583 			"cannot project out existentially quantified variables",
   4584 			return isl_basic_map_free(bmap));
   4585 
   4586 	empty = isl_basic_map_plain_is_empty(bmap);
   4587 	if (empty < 0)
   4588 		return isl_basic_map_free(bmap);
   4589 	if (empty)
   4590 		bmap = isl_basic_map_set_to_empty(bmap);
   4591 
   4592 	bmap = drop_irrelevant_constraints(bmap, type, first, n);
   4593 	if (!bmap)
   4594 		return NULL;
   4595 
   4596 	if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL))
   4597 		return isl_basic_map_remove_dims(bmap, type, first, n);
   4598 
   4599 	if (isl_basic_map_check_range(bmap, type, first, n) < 0)
   4600 		return isl_basic_map_free(bmap);
   4601 
   4602 	bmap = move_last(bmap, type, first, n);
   4603 	bmap = isl_basic_map_cow(bmap);
   4604 	bmap = insert_div_rows(bmap, n);
   4605 
   4606 	space = isl_basic_map_take_space(bmap);
   4607 	space = isl_space_drop_dims(space, type, first, n);
   4608 	bmap = isl_basic_map_restore_space(bmap, space);
   4609 	bmap = isl_basic_map_simplify(bmap);
   4610 	bmap = isl_basic_map_drop_redundant_divs(bmap);
   4611 	return isl_basic_map_finalize(bmap);
   4612 }
   4613 
   4614 /* Turn the n dimensions of type type, starting at first
   4615  * into existentially quantified variables.
   4616  */
   4617 __isl_give isl_basic_set *isl_basic_set_project_out(
   4618 	__isl_take isl_basic_set *bset, enum isl_dim_type type,
   4619 	unsigned first, unsigned n)
   4620 {
   4621 	return bset_from_bmap(isl_basic_map_project_out(bset_to_bmap(bset),
   4622 							type, first, n));
   4623 }
   4624 
   4625 /* Turn the n dimensions of type type, starting at first
   4626  * into existentially quantified variables.
   4627  */
   4628 __isl_give isl_map *isl_map_project_out(__isl_take isl_map *map,
   4629 		enum isl_dim_type type, unsigned first, unsigned n)
   4630 {
   4631 	int i;
   4632 	isl_space *space;
   4633 
   4634 	if (n == 0)
   4635 		return map_space_reset(map, type);
   4636 
   4637 	if (isl_map_check_range(map, type, first, n) < 0)
   4638 		return isl_map_free(map);
   4639 
   4640 	map = isl_map_cow(map);
   4641 	if (!map)
   4642 		return NULL;
   4643 
   4644 	for (i = 0; i < map->n; ++i) {
   4645 		map->p[i] = isl_basic_map_project_out(map->p[i], type, first, n);
   4646 		if (!map->p[i])
   4647 			goto error;
   4648 	}
   4649 
   4650 	if (map->n > 1)
   4651 		ISL_F_CLR(map, ISL_MAP_DISJOINT);
   4652 	map = isl_map_unmark_normalized(map);
   4653 
   4654 	space = isl_map_take_space(map);
   4655 	space = isl_space_drop_dims(space, type, first, n);
   4656 	map = isl_map_restore_space(map, space);
   4657 
   4658 	return map;
   4659 error:
   4660 	isl_map_free(map);
   4661 	return NULL;
   4662 }
   4663 
   4664 #undef TYPE
   4665 #define TYPE	isl_map
   4666 #include "isl_project_out_all_params_templ.c"
   4667 #include "isl_project_out_param_templ.c"
   4668 
   4669 /* Turn all the dimensions of type "type", except the "n" starting at "first"
   4670  * into existentially quantified variables.
   4671  */
   4672 __isl_give isl_map *isl_map_project_onto(__isl_take isl_map *map,
   4673 	enum isl_dim_type type, unsigned first, unsigned n)
   4674 {
   4675 	isl_size dim;
   4676 
   4677 	dim = isl_map_dim(map, type);
   4678 	if (isl_map_check_range(map, type, first, n) < 0 || dim < 0)
   4679 		return isl_map_free(map);
   4680 	map = isl_map_project_out(map, type, first + n, dim - (first + n));
   4681 	map = isl_map_project_out(map, type, 0, first);
   4682 	return map;
   4683 }
   4684 
   4685 /* Turn the n dimensions of type type, starting at first
   4686  * into existentially quantified variables.
   4687  */
   4688 __isl_give isl_set *isl_set_project_out(__isl_take isl_set *set,
   4689 		enum isl_dim_type type, unsigned first, unsigned n)
   4690 {
   4691 	return set_from_map(isl_map_project_out(set_to_map(set),
   4692 						type, first, n));
   4693 }
   4694 
   4695 /* If "set" involves a parameter with identifier "id",
   4696  * then turn it into an existentially quantified variable.
   4697  */
   4698 __isl_give isl_set *isl_set_project_out_param_id(__isl_take isl_set *set,
   4699 	__isl_take isl_id *id)
   4700 {
   4701 	return set_from_map(isl_map_project_out_param_id(set_to_map(set), id));
   4702 }
   4703 
   4704 /* If "set" involves any of the parameters with identifiers in "list",
   4705  * then turn them into existentially quantified variables.
   4706  */
   4707 __isl_give isl_set *isl_set_project_out_param_id_list(__isl_take isl_set *set,
   4708 	__isl_take isl_id_list *list)
   4709 {
   4710 	isl_map *map;
   4711 
   4712 	map = set_to_map(set);
   4713 	map = isl_map_project_out_param_id_list(map, list);
   4714 	return set_from_map(map);
   4715 }
   4716 
   4717 /* Project out all parameters from "set" by existentially quantifying
   4718  * over them.
   4719  */
   4720 __isl_give isl_set *isl_set_project_out_all_params(__isl_take isl_set *set)
   4721 {
   4722 	return set_from_map(isl_map_project_out_all_params(set_to_map(set)));
   4723 }
   4724 
   4725 /* Return a map that projects the elements in "set" onto their
   4726  * "n" set dimensions starting at "first".
   4727  * "type" should be equal to isl_dim_set.
   4728  */
   4729 __isl_give isl_map *isl_set_project_onto_map(__isl_take isl_set *set,
   4730 	enum isl_dim_type type, unsigned first, unsigned n)
   4731 {
   4732 	int i;
   4733 	isl_map *map;
   4734 
   4735 	if (type != isl_dim_set)
   4736 		isl_die(isl_set_get_ctx(set), isl_error_invalid,
   4737 			"only set dimensions can be projected out", goto error);
   4738 	if (isl_set_check_range(set, type, first, n) < 0)
   4739 		return isl_set_free(set);
   4740 
   4741 	map = isl_map_from_domain(set);
   4742 	map = isl_map_add_dims(map, isl_dim_out, n);
   4743 	for (i = 0; i < n; ++i)
   4744 		map = isl_map_equate(map, isl_dim_in, first + i,
   4745 					isl_dim_out, i);
   4746 	return map;
   4747 error:
   4748 	isl_set_free(set);
   4749 	return NULL;
   4750 }
   4751 
   4752 static __isl_give isl_basic_map *add_divs(__isl_take isl_basic_map *bmap,
   4753 	unsigned n)
   4754 {
   4755 	int i, j;
   4756 	isl_size total;
   4757 
   4758 	total = isl_basic_map_dim(bmap, isl_dim_all);
   4759 	if (total < 0)
   4760 		return isl_basic_map_free(bmap);
   4761 	for (i = 0; i < n; ++i) {
   4762 		j = isl_basic_map_alloc_div(bmap);
   4763 		if (j < 0)
   4764 			goto error;
   4765 		isl_seq_clr(bmap->div[j], 1 + 1 + total);
   4766 	}
   4767 	return bmap;
   4768 error:
   4769 	isl_basic_map_free(bmap);
   4770 	return NULL;
   4771 }
   4772 
   4773 /* Does "bmap2" apply to the range of "bmap1" (ignoring parameters)?
   4774  */
   4775 isl_bool isl_basic_map_applies_range(__isl_keep isl_basic_map *bmap1,
   4776 	__isl_keep isl_basic_map *bmap2)
   4777 {
   4778 	isl_space *space1, *space2;
   4779 
   4780 	space1 = isl_basic_map_peek_space(bmap1);
   4781 	space2 = isl_basic_map_peek_space(bmap2);
   4782 	return isl_space_tuple_is_equal(space1, isl_dim_out,
   4783 					space2, isl_dim_in);
   4784 }
   4785 
   4786 /* Check that "bmap2" applies to the range of "bmap1" (ignoring parameters).
   4787  */
   4788 static isl_stat isl_basic_map_check_applies_range(
   4789 	__isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2)
   4790 {
   4791 	isl_bool equal;
   4792 
   4793 	equal = isl_basic_map_applies_range(bmap1, bmap2);
   4794 	if (equal < 0)
   4795 		return isl_stat_error;
   4796 	if (!equal)
   4797 		isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,
   4798 			"spaces don't match", return isl_stat_error);
   4799 	return isl_stat_ok;
   4800 }
   4801 
   4802 __isl_give isl_basic_map *isl_basic_map_apply_range(
   4803 	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
   4804 {
   4805 	isl_space *space_result = NULL;
   4806 	struct isl_basic_map *bmap;
   4807 	isl_size n_in, n_out, n, nparam;
   4808 	unsigned total, pos;
   4809 	struct isl_dim_map *dim_map1, *dim_map2;
   4810 
   4811 	if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
   4812 		goto error;
   4813 	if (isl_basic_map_check_applies_range(bmap1, bmap2) < 0)
   4814 		goto error;
   4815 
   4816 	n_in = isl_basic_map_dim(bmap1, isl_dim_in);
   4817 	n_out = isl_basic_map_dim(bmap2, isl_dim_out);
   4818 	n = isl_basic_map_dim(bmap1, isl_dim_out);
   4819 	nparam = isl_basic_map_dim(bmap1, isl_dim_param);
   4820 	if (n_in < 0 || n_out < 0 || n < 0 || nparam < 0)
   4821 		goto error;
   4822 
   4823 	space_result = isl_space_join(isl_basic_map_get_space(bmap1),
   4824 				  isl_basic_map_get_space(bmap2));
   4825 
   4826 	total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + n;
   4827 	dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
   4828 	dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
   4829 	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
   4830 	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
   4831 	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
   4832 	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_in);
   4833 	isl_dim_map_div(dim_map1, bmap1, pos += n_out);
   4834 	isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
   4835 	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
   4836 	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
   4837 
   4838 	bmap = isl_basic_map_alloc_space(space_result,
   4839 			bmap1->n_div + bmap2->n_div + n,
   4840 			bmap1->n_eq + bmap2->n_eq,
   4841 			bmap1->n_ineq + bmap2->n_ineq);
   4842 	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
   4843 	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
   4844 	bmap = add_divs(bmap, n);
   4845 	bmap = isl_basic_map_simplify(bmap);
   4846 	bmap = isl_basic_map_drop_redundant_divs(bmap);
   4847 	return isl_basic_map_finalize(bmap);
   4848 error:
   4849 	isl_basic_map_free(bmap1);
   4850 	isl_basic_map_free(bmap2);
   4851 	return NULL;
   4852 }
   4853 
   4854 __isl_give isl_basic_set *isl_basic_set_apply(__isl_take isl_basic_set *bset,
   4855 	__isl_take isl_basic_map *bmap)
   4856 {
   4857 	if (isl_basic_map_check_compatible_domain(bmap, bset) < 0)
   4858 		goto error;
   4859 
   4860 	return bset_from_bmap(isl_basic_map_apply_range(bset_to_bmap(bset),
   4861 							bmap));
   4862 error:
   4863 	isl_basic_set_free(bset);
   4864 	isl_basic_map_free(bmap);
   4865 	return NULL;
   4866 }
   4867 
   4868 __isl_give isl_basic_map *isl_basic_map_apply_domain(
   4869 	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
   4870 {
   4871 	if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
   4872 		goto error;
   4873 	if (!isl_space_tuple_is_equal(bmap1->dim, isl_dim_in,
   4874 					bmap2->dim, isl_dim_in))
   4875 		isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,
   4876 			"spaces don't match", goto error);
   4877 
   4878 	bmap1 = isl_basic_map_reverse(bmap1);
   4879 	bmap1 = isl_basic_map_apply_range(bmap1, bmap2);
   4880 	return isl_basic_map_reverse(bmap1);
   4881 error:
   4882 	isl_basic_map_free(bmap1);
   4883 	isl_basic_map_free(bmap2);
   4884 	return NULL;
   4885 }
   4886 
   4887 /* Given two basic maps A -> f(A) and B -> g(B), construct a basic map
   4888  * A \cap B -> f(A) + f(B)
   4889  */
   4890 __isl_give isl_basic_map *isl_basic_map_sum(__isl_take isl_basic_map *bmap1,
   4891 	__isl_take isl_basic_map *bmap2)
   4892 {
   4893 	isl_size n_in, n_out, nparam;
   4894 	unsigned total, pos;
   4895 	struct isl_basic_map *bmap = NULL;
   4896 	struct isl_dim_map *dim_map1, *dim_map2;
   4897 	int i;
   4898 
   4899 	if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
   4900 		goto error;
   4901 
   4902 	nparam = isl_basic_map_dim(bmap1, isl_dim_param);
   4903 	n_in = isl_basic_map_dim(bmap1, isl_dim_in);
   4904 	n_out = isl_basic_map_dim(bmap1, isl_dim_out);
   4905 	if (nparam < 0 || n_in < 0 || n_out < 0)
   4906 		goto error;
   4907 
   4908 	total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + 2 * n_out;
   4909 	dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
   4910 	dim_map2 = isl_dim_map_alloc(bmap2->ctx, total);
   4911 	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
   4912 	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos);
   4913 	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
   4914 	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
   4915 	isl_dim_map_div(dim_map1, bmap1, pos += n_in + n_out);
   4916 	isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
   4917 	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
   4918 	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_out);
   4919 
   4920 	bmap = isl_basic_map_alloc_space(isl_space_copy(bmap1->dim),
   4921 			bmap1->n_div + bmap2->n_div + 2 * n_out,
   4922 			bmap1->n_eq + bmap2->n_eq + n_out,
   4923 			bmap1->n_ineq + bmap2->n_ineq);
   4924 	for (i = 0; i < n_out; ++i) {
   4925 		int j = isl_basic_map_alloc_equality(bmap);
   4926 		if (j < 0)
   4927 			goto error;
   4928 		isl_seq_clr(bmap->eq[j], 1+total);
   4929 		isl_int_set_si(bmap->eq[j][1+nparam+n_in+i], -1);
   4930 		isl_int_set_si(bmap->eq[j][1+pos+i], 1);
   4931 		isl_int_set_si(bmap->eq[j][1+pos-n_out+i], 1);
   4932 	}
   4933 	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
   4934 	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
   4935 	bmap = add_divs(bmap, 2 * n_out);
   4936 
   4937 	bmap = isl_basic_map_simplify(bmap);
   4938 	return isl_basic_map_finalize(bmap);
   4939 error:
   4940 	isl_basic_map_free(bmap);
   4941 	isl_basic_map_free(bmap1);
   4942 	isl_basic_map_free(bmap2);
   4943 	return NULL;
   4944 }
   4945 
   4946 /* Given two maps A -> f(A) and B -> g(B), construct a map
   4947  * A \cap B -> f(A) + f(B)
   4948  */
   4949 __isl_give isl_map *isl_map_sum(__isl_take isl_map *map1,
   4950 	__isl_take isl_map *map2)
   4951 {
   4952 	struct isl_map *result;
   4953 	int i, j;
   4954 
   4955 	if (isl_map_check_equal_space(map1, map2) < 0)
   4956 		goto error;
   4957 
   4958 	result = isl_map_alloc_space(isl_space_copy(map1->dim),
   4959 				map1->n * map2->n, 0);
   4960 	if (!result)
   4961 		goto error;
   4962 	for (i = 0; i < map1->n; ++i)
   4963 		for (j = 0; j < map2->n; ++j) {
   4964 			struct isl_basic_map *part;
   4965 			part = isl_basic_map_sum(
   4966 				    isl_basic_map_copy(map1->p[i]),
   4967 				    isl_basic_map_copy(map2->p[j]));
   4968 			if (isl_basic_map_is_empty(part))
   4969 				isl_basic_map_free(part);
   4970 			else
   4971 				result = isl_map_add_basic_map(result, part);
   4972 			if (!result)
   4973 				goto error;
   4974 		}
   4975 	isl_map_free(map1);
   4976 	isl_map_free(map2);
   4977 	return result;
   4978 error:
   4979 	isl_map_free(map1);
   4980 	isl_map_free(map2);
   4981 	return NULL;
   4982 }
   4983 
   4984 __isl_give isl_set *isl_set_sum(__isl_take isl_set *set1,
   4985 	__isl_take isl_set *set2)
   4986 {
   4987 	return set_from_map(isl_map_sum(set_to_map(set1), set_to_map(set2)));
   4988 }
   4989 
   4990 /* Given a basic map A -> f(A), construct A -> -f(A).
   4991  */
   4992 __isl_give isl_basic_map *isl_basic_map_neg(__isl_take isl_basic_map *bmap)
   4993 {
   4994 	int i, j;
   4995 	unsigned off;
   4996 	isl_size n;
   4997 
   4998 	bmap = isl_basic_map_cow(bmap);
   4999 	n = isl_basic_map_dim(bmap, isl_dim_out);
   5000 	if (n < 0)
   5001 		return isl_basic_map_free(bmap);
   5002 
   5003 	off = isl_basic_map_offset(bmap, isl_dim_out);
   5004 	for (i = 0; i < bmap->n_eq; ++i)
   5005 		for (j = 0; j < n; ++j)
   5006 			isl_int_neg(bmap->eq[i][off+j], bmap->eq[i][off+j]);
   5007 	for (i = 0; i < bmap->n_ineq; ++i)
   5008 		for (j = 0; j < n; ++j)
   5009 			isl_int_neg(bmap->ineq[i][off+j], bmap->ineq[i][off+j]);
   5010 	for (i = 0; i < bmap->n_div; ++i)
   5011 		for (j = 0; j < n; ++j)
   5012 			isl_int_neg(bmap->div[i][1+off+j], bmap->div[i][1+off+j]);
   5013 	bmap = isl_basic_map_gauss(bmap, NULL);
   5014 	return isl_basic_map_finalize(bmap);
   5015 }
   5016 
   5017 __isl_give isl_basic_set *isl_basic_set_neg(__isl_take isl_basic_set *bset)
   5018 {
   5019 	return isl_basic_map_neg(bset);
   5020 }
   5021 
   5022 /* Given a map A -> f(A), construct A -> -f(A).
   5023  */
   5024 __isl_give isl_map *isl_map_neg(__isl_take isl_map *map)
   5025 {
   5026 	int i;
   5027 
   5028 	map = isl_map_cow(map);
   5029 	if (!map)
   5030 		return NULL;
   5031 
   5032 	for (i = 0; i < map->n; ++i) {
   5033 		map->p[i] = isl_basic_map_neg(map->p[i]);
   5034 		if (!map->p[i])
   5035 			goto error;
   5036 	}
   5037 
   5038 	return map;
   5039 error:
   5040 	isl_map_free(map);
   5041 	return NULL;
   5042 }
   5043 
   5044 __isl_give isl_set *isl_set_neg(__isl_take isl_set *set)
   5045 {
   5046 	return set_from_map(isl_map_neg(set_to_map(set)));
   5047 }
   5048 
   5049 /* Given a basic map A -> f(A) and an integer d, construct a basic map
   5050  * A -> floor(f(A)/d).
   5051  */
   5052 __isl_give isl_basic_map *isl_basic_map_floordiv(__isl_take isl_basic_map *bmap,
   5053 		isl_int d)
   5054 {
   5055 	isl_size n_in, n_out, nparam;
   5056 	unsigned total, pos;
   5057 	struct isl_basic_map *result = NULL;
   5058 	struct isl_dim_map *dim_map;
   5059 	int i;
   5060 
   5061 	nparam = isl_basic_map_dim(bmap, isl_dim_param);
   5062 	n_in = isl_basic_map_dim(bmap, isl_dim_in);
   5063 	n_out = isl_basic_map_dim(bmap, isl_dim_out);
   5064 	if (nparam < 0 || n_in < 0 || n_out < 0)
   5065 		return isl_basic_map_free(bmap);
   5066 
   5067 	total = nparam + n_in + n_out + bmap->n_div + n_out;
   5068 	dim_map = isl_dim_map_alloc(bmap->ctx, total);
   5069 	isl_dim_map_dim(dim_map, bmap->dim, isl_dim_param, pos = 0);
   5070 	isl_dim_map_dim(dim_map, bmap->dim, isl_dim_in, pos += nparam);
   5071 	isl_dim_map_div(dim_map, bmap, pos += n_in + n_out);
   5072 	isl_dim_map_dim(dim_map, bmap->dim, isl_dim_out, pos += bmap->n_div);
   5073 
   5074 	result = isl_basic_map_alloc_space(isl_space_copy(bmap->dim),
   5075 			bmap->n_div + n_out,
   5076 			bmap->n_eq, bmap->n_ineq + 2 * n_out);
   5077 	result = isl_basic_map_add_constraints_dim_map(result, bmap, dim_map);
   5078 	result = add_divs(result, n_out);
   5079 	for (i = 0; i < n_out; ++i) {
   5080 		int j;
   5081 		j = isl_basic_map_alloc_inequality(result);
   5082 		if (j < 0)
   5083 			goto error;
   5084 		isl_seq_clr(result->ineq[j], 1+total);
   5085 		isl_int_neg(result->ineq[j][1+nparam+n_in+i], d);
   5086 		isl_int_set_si(result->ineq[j][1+pos+i], 1);
   5087 		j = isl_basic_map_alloc_inequality(result);
   5088 		if (j < 0)
   5089 			goto error;
   5090 		isl_seq_clr(result->ineq[j], 1+total);
   5091 		isl_int_set(result->ineq[j][1+nparam+n_in+i], d);
   5092 		isl_int_set_si(result->ineq[j][1+pos+i], -1);
   5093 		isl_int_sub_ui(result->ineq[j][0], d, 1);
   5094 	}
   5095 
   5096 	result = isl_basic_map_simplify(result);
   5097 	return isl_basic_map_finalize(result);
   5098 error:
   5099 	isl_basic_map_free(result);
   5100 	return NULL;
   5101 }
   5102 
   5103 /* Given a map A -> f(A) and an integer d, construct a map
   5104  * A -> floor(f(A)/d).
   5105  */
   5106 __isl_give isl_map *isl_map_floordiv(__isl_take isl_map *map, isl_int d)
   5107 {
   5108 	int i;
   5109 
   5110 	map = isl_map_cow(map);
   5111 	if (!map)
   5112 		return NULL;
   5113 
   5114 	ISL_F_CLR(map, ISL_MAP_DISJOINT);
   5115 	for (i = 0; i < map->n; ++i) {
   5116 		map->p[i] = isl_basic_map_floordiv(map->p[i], d);
   5117 		if (!map->p[i])
   5118 			goto error;
   5119 	}
   5120 	map = isl_map_unmark_normalized(map);
   5121 
   5122 	return map;
   5123 error:
   5124 	isl_map_free(map);
   5125 	return NULL;
   5126 }
   5127 
   5128 /* Given a map A -> f(A) and an integer d, construct a map
   5129  * A -> floor(f(A)/d).
   5130  */
   5131 __isl_give isl_map *isl_map_floordiv_val(__isl_take isl_map *map,
   5132 	__isl_take isl_val *d)
   5133 {
   5134 	if (!map || !d)
   5135 		goto error;
   5136 	if (!isl_val_is_int(d))
   5137 		isl_die(isl_val_get_ctx(d), isl_error_invalid,
   5138 			"expecting integer denominator", goto error);
   5139 	map = isl_map_floordiv(map, d->n);
   5140 	isl_val_free(d);
   5141 	return map;
   5142 error:
   5143 	isl_map_free(map);
   5144 	isl_val_free(d);
   5145 	return NULL;
   5146 }
   5147 
   5148 static __isl_give isl_basic_map *var_equal(__isl_take isl_basic_map *bmap,
   5149 	unsigned pos)
   5150 {
   5151 	int i;
   5152 	isl_size nparam;
   5153 	isl_size n_in;
   5154 	isl_size total;
   5155 
   5156 	total = isl_basic_map_dim(bmap, isl_dim_all);
   5157 	nparam = isl_basic_map_dim(bmap, isl_dim_param);
   5158 	n_in = isl_basic_map_dim(bmap, isl_dim_in);
   5159 	if (total < 0 || nparam < 0 || n_in < 0)
   5160 		return isl_basic_map_free(bmap);
   5161 	i = isl_basic_map_alloc_equality(bmap);
   5162 	if (i < 0)
   5163 		goto error;
   5164 	isl_seq_clr(bmap->eq[i], 1 + total);
   5165 	isl_int_set_si(bmap->eq[i][1+nparam+pos], -1);
   5166 	isl_int_set_si(bmap->eq[i][1+nparam+n_in+pos], 1);
   5167 	return isl_basic_map_finalize(bmap);
   5168 error:
   5169 	isl_basic_map_free(bmap);
   5170 	return NULL;
   5171 }
   5172 
   5173 /* Add a constraint to "bmap" expressing i_pos < o_pos
   5174  */
   5175 static __isl_give isl_basic_map *var_less(__isl_take isl_basic_map *bmap,
   5176 	unsigned pos)
   5177 {
   5178 	int i;
   5179 	isl_size nparam;
   5180 	isl_size n_in;
   5181 	isl_size total;
   5182 
   5183 	total = isl_basic_map_dim(bmap, isl_dim_all);
   5184 	nparam = isl_basic_map_dim(bmap, isl_dim_param);
   5185 	n_in = isl_basic_map_dim(bmap, isl_dim_in);
   5186 	if (total < 0 || nparam < 0 || n_in < 0)
   5187 		return isl_basic_map_free(bmap);
   5188 	i = isl_basic_map_alloc_inequality(bmap);
   5189 	if (i < 0)
   5190 		goto error;
   5191 	isl_seq_clr(bmap->ineq[i], 1 + total);
   5192 	isl_int_set_si(bmap->ineq[i][0], -1);
   5193 	isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1);
   5194 	isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1);
   5195 	return isl_basic_map_finalize(bmap);
   5196 error:
   5197 	isl_basic_map_free(bmap);
   5198 	return NULL;
   5199 }
   5200 
   5201 /* Add a constraint to "bmap" expressing i_pos <= o_pos
   5202  */
   5203 static __isl_give isl_basic_map *var_less_or_equal(
   5204 	__isl_take isl_basic_map *bmap, unsigned pos)
   5205 {
   5206 	int i;
   5207 	isl_size nparam;
   5208 	isl_size n_in;
   5209 	isl_size total;
   5210 
   5211 	total = isl_basic_map_dim(bmap, isl_dim_all);
   5212 	nparam = isl_basic_map_dim(bmap, isl_dim_param);
   5213 	n_in = isl_basic_map_dim(bmap, isl_dim_in);
   5214 	if (total < 0 || nparam < 0 || n_in < 0)
   5215 		return isl_basic_map_free(bmap);
   5216 	i = isl_basic_map_alloc_inequality(bmap);
   5217 	if (i < 0)
   5218 		goto error;
   5219 	isl_seq_clr(bmap->ineq[i], 1 + total);
   5220 	isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1);
   5221 	isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1);
   5222 	return isl_basic_map_finalize(bmap);
   5223 error:
   5224 	isl_basic_map_free(bmap);
   5225 	return NULL;
   5226 }
   5227 
   5228 /* Add a constraint to "bmap" expressing i_pos > o_pos
   5229  */
   5230 static __isl_give isl_basic_map *var_more(__isl_take isl_basic_map *bmap,
   5231 	unsigned pos)
   5232 {
   5233 	int i;
   5234 	isl_size nparam;
   5235 	isl_size n_in;
   5236 	isl_size total;
   5237 
   5238 	total = isl_basic_map_dim(bmap, isl_dim_all);
   5239 	nparam = isl_basic_map_dim(bmap, isl_dim_param);
   5240 	n_in = isl_basic_map_dim(bmap, isl_dim_in);
   5241 	if (total < 0 || nparam < 0 || n_in < 0)
   5242 		return isl_basic_map_free(bmap);
   5243 	i = isl_basic_map_alloc_inequality(bmap);
   5244 	if (i < 0)
   5245 		goto error;
   5246 	isl_seq_clr(bmap->ineq[i], 1 + total);
   5247 	isl_int_set_si(bmap->ineq[i][0], -1);
   5248 	isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1);
   5249 	isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1);
   5250 	return isl_basic_map_finalize(bmap);
   5251 error:
   5252 	isl_basic_map_free(bmap);
   5253 	return NULL;
   5254 }
   5255 
   5256 /* Add a constraint to "bmap" expressing i_pos >= o_pos
   5257  */
   5258 static __isl_give isl_basic_map *var_more_or_equal(
   5259 	__isl_take isl_basic_map *bmap, unsigned pos)
   5260 {
   5261 	int i;
   5262 	isl_size nparam;
   5263 	isl_size n_in;
   5264 	isl_size total;
   5265 
   5266 	total = isl_basic_map_dim(bmap, isl_dim_all);
   5267 	nparam = isl_basic_map_dim(bmap, isl_dim_param);
   5268 	n_in = isl_basic_map_dim(bmap, isl_dim_in);
   5269 	if (total < 0 || nparam < 0 || n_in < 0)
   5270 		return isl_basic_map_free(bmap);
   5271 	i = isl_basic_map_alloc_inequality(bmap);
   5272 	if (i < 0)
   5273 		goto error;
   5274 	isl_seq_clr(bmap->ineq[i], 1 + total);
   5275 	isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1);
   5276 	isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1);
   5277 	return isl_basic_map_finalize(bmap);
   5278 error:
   5279 	isl_basic_map_free(bmap);
   5280 	return NULL;
   5281 }
   5282 
   5283 __isl_give isl_basic_map *isl_basic_map_equal(
   5284 	__isl_take isl_space *space, unsigned n_equal)
   5285 {
   5286 	int i;
   5287 	struct isl_basic_map *bmap;
   5288 	bmap = isl_basic_map_alloc_space(space, 0, n_equal, 0);
   5289 	if (!bmap)
   5290 		return NULL;
   5291 	for (i = 0; i < n_equal && bmap; ++i)
   5292 		bmap = var_equal(bmap, i);
   5293 	return isl_basic_map_finalize(bmap);
   5294 }
   5295 
   5296 /* Return a relation on of dimension "space" expressing i_[0..pos] << o_[0..pos]
   5297  */
   5298 __isl_give isl_basic_map *isl_basic_map_less_at(__isl_take isl_space *space,
   5299 	unsigned pos)
   5300 {
   5301 	int i;
   5302 	struct isl_basic_map *bmap;
   5303 	bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
   5304 	if (!bmap)
   5305 		return NULL;
   5306 	for (i = 0; i < pos && bmap; ++i)
   5307 		bmap = var_equal(bmap, i);
   5308 	if (bmap)
   5309 		bmap = var_less(bmap, pos);
   5310 	return isl_basic_map_finalize(bmap);
   5311 }
   5312 
   5313 /* Return a relation on "space" expressing i_[0..pos] <<= o_[0..pos]
   5314  */
   5315 __isl_give isl_basic_map *isl_basic_map_less_or_equal_at(
   5316 	__isl_take isl_space *space, unsigned pos)
   5317 {
   5318 	int i;
   5319 	isl_basic_map *bmap;
   5320 
   5321 	bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
   5322 	for (i = 0; i < pos; ++i)
   5323 		bmap = var_equal(bmap, i);
   5324 	bmap = var_less_or_equal(bmap, pos);
   5325 	return isl_basic_map_finalize(bmap);
   5326 }
   5327 
   5328 /* Return a relation on "space" expressing i_pos > o_pos
   5329  */
   5330 __isl_give isl_basic_map *isl_basic_map_more_at(__isl_take isl_space *space,
   5331 	unsigned pos)
   5332 {
   5333 	int i;
   5334 	struct isl_basic_map *bmap;
   5335 	bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
   5336 	if (!bmap)
   5337 		return NULL;
   5338 	for (i = 0; i < pos && bmap; ++i)
   5339 		bmap = var_equal(bmap, i);
   5340 	if (bmap)
   5341 		bmap = var_more(bmap, pos);
   5342 	return isl_basic_map_finalize(bmap);
   5343 }
   5344 
   5345 /* Return a relation on "space" expressing i_[0..pos] >>= o_[0..pos]
   5346  */
   5347 __isl_give isl_basic_map *isl_basic_map_more_or_equal_at(
   5348 	__isl_take isl_space *space, unsigned pos)
   5349 {
   5350 	int i;
   5351 	isl_basic_map *bmap;
   5352 
   5353 	bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
   5354 	for (i = 0; i < pos; ++i)
   5355 		bmap = var_equal(bmap, i);
   5356 	bmap = var_more_or_equal(bmap, pos);
   5357 	return isl_basic_map_finalize(bmap);
   5358 }
   5359 
   5360 static __isl_give isl_map *map_lex_lte_first(__isl_take isl_space *space,
   5361 	unsigned n, int equal)
   5362 {
   5363 	struct isl_map *map;
   5364 	int i;
   5365 
   5366 	if (n == 0 && equal)
   5367 		return isl_map_universe(space);
   5368 
   5369 	map = isl_map_alloc_space(isl_space_copy(space), n, ISL_MAP_DISJOINT);
   5370 
   5371 	for (i = 0; i + 1 < n; ++i)
   5372 		map = isl_map_add_basic_map(map,
   5373 				  isl_basic_map_less_at(isl_space_copy(space), i));
   5374 	if (n > 0) {
   5375 		if (equal)
   5376 			map = isl_map_add_basic_map(map,
   5377 			      isl_basic_map_less_or_equal_at(space, n - 1));
   5378 		else
   5379 			map = isl_map_add_basic_map(map,
   5380 			      isl_basic_map_less_at(space, n - 1));
   5381 	} else
   5382 		isl_space_free(space);
   5383 
   5384 	return map;
   5385 }
   5386 
   5387 static __isl_give isl_map *map_lex_lte(__isl_take isl_space *space, int equal)
   5388 {
   5389 	if (!space)
   5390 		return NULL;
   5391 	return map_lex_lte_first(space, space->n_out, equal);
   5392 }
   5393 
   5394 __isl_give isl_map *isl_map_lex_lt_first(__isl_take isl_space *space,
   5395 	unsigned n)
   5396 {
   5397 	return map_lex_lte_first(space, n, 0);
   5398 }
   5399 
   5400 __isl_give isl_map *isl_map_lex_le_first(__isl_take isl_space *space,
   5401 	unsigned n)
   5402 {
   5403 	return map_lex_lte_first(space, n, 1);
   5404 }
   5405 
   5406 __isl_give isl_map *isl_map_lex_lt(__isl_take isl_space *set_space)
   5407 {
   5408 	return map_lex_lte(isl_space_map_from_set(set_space), 0);
   5409 }
   5410 
   5411 __isl_give isl_map *isl_map_lex_le(__isl_take isl_space *set_space)
   5412 {
   5413 	return map_lex_lte(isl_space_map_from_set(set_space), 1);
   5414 }
   5415 
   5416 static __isl_give isl_map *map_lex_gte_first(__isl_take isl_space *space,
   5417 	unsigned n, int equal)
   5418 {
   5419 	struct isl_map *map;
   5420 	int i;
   5421 
   5422 	if (n == 0 && equal)
   5423 		return isl_map_universe(space);
   5424 
   5425 	map = isl_map_alloc_space(isl_space_copy(space), n, ISL_MAP_DISJOINT);
   5426 
   5427 	for (i = 0; i + 1 < n; ++i)
   5428 		map = isl_map_add_basic_map(map,
   5429 				  isl_basic_map_more_at(isl_space_copy(space), i));
   5430 	if (n > 0) {
   5431 		if (equal)
   5432 			map = isl_map_add_basic_map(map,
   5433 			      isl_basic_map_more_or_equal_at(space, n - 1));
   5434 		else
   5435 			map = isl_map_add_basic_map(map,
   5436 			      isl_basic_map_more_at(space, n - 1));
   5437 	} else
   5438 		isl_space_free(space);
   5439 
   5440 	return map;
   5441 }
   5442 
   5443 static __isl_give isl_map *map_lex_gte(__isl_take isl_space *space, int equal)
   5444 {
   5445 	if (!space)
   5446 		return NULL;
   5447 	return map_lex_gte_first(space, space->n_out, equal);
   5448 }
   5449 
   5450 __isl_give isl_map *isl_map_lex_gt_first(__isl_take isl_space *space,
   5451 	unsigned n)
   5452 {
   5453 	return map_lex_gte_first(space, n, 0);
   5454 }
   5455 
   5456 __isl_give isl_map *isl_map_lex_ge_first(__isl_take isl_space *space,
   5457 	unsigned n)
   5458 {
   5459 	return map_lex_gte_first(space, n, 1);
   5460 }
   5461 
   5462 __isl_give isl_map *isl_map_lex_gt(__isl_take isl_space *set_space)
   5463 {
   5464 	return map_lex_gte(isl_space_map_from_set(set_space), 0);
   5465 }
   5466 
   5467 __isl_give isl_map *isl_map_lex_ge(__isl_take isl_space *set_space)
   5468 {
   5469 	return map_lex_gte(isl_space_map_from_set(set_space), 1);
   5470 }
   5471 
   5472 __isl_give isl_map *isl_set_lex_le_set(__isl_take isl_set *set1,
   5473 	__isl_take isl_set *set2)
   5474 {
   5475 	isl_map *map;
   5476 	map = isl_map_lex_le(isl_set_get_space(set1));
   5477 	map = isl_map_intersect_domain(map, set1);
   5478 	map = isl_map_intersect_range(map, set2);
   5479 	return map;
   5480 }
   5481 
   5482 __isl_give isl_map *isl_set_lex_lt_set(__isl_take isl_set *set1,
   5483 	__isl_take isl_set *set2)
   5484 {
   5485 	isl_map *map;
   5486 	map = isl_map_lex_lt(isl_set_get_space(set1));
   5487 	map = isl_map_intersect_domain(map, set1);
   5488 	map = isl_map_intersect_range(map, set2);
   5489 	return map;
   5490 }
   5491 
   5492 __isl_give isl_map *isl_set_lex_ge_set(__isl_take isl_set *set1,
   5493 	__isl_take isl_set *set2)
   5494 {
   5495 	isl_map *map;
   5496 	map = isl_map_lex_ge(isl_set_get_space(set1));
   5497 	map = isl_map_intersect_domain(map, set1);
   5498 	map = isl_map_intersect_range(map, set2);
   5499 	return map;
   5500 }
   5501 
   5502 __isl_give isl_map *isl_set_lex_gt_set(__isl_take isl_set *set1,
   5503 	__isl_take isl_set *set2)
   5504 {
   5505 	isl_map *map;
   5506 	map = isl_map_lex_gt(isl_set_get_space(set1));
   5507 	map = isl_map_intersect_domain(map, set1);
   5508 	map = isl_map_intersect_range(map, set2);
   5509 	return map;
   5510 }
   5511 
   5512 __isl_give isl_map *isl_map_lex_le_map(__isl_take isl_map *map1,
   5513 	__isl_take isl_map *map2)
   5514 {
   5515 	isl_map *map;
   5516 	map = isl_map_lex_le(isl_space_range(isl_map_get_space(map1)));
   5517 	map = isl_map_apply_domain(map, isl_map_reverse(map1));
   5518 	map = isl_map_apply_range(map, isl_map_reverse(map2));
   5519 	return map;
   5520 }
   5521 
   5522 __isl_give isl_map *isl_map_lex_lt_map(__isl_take isl_map *map1,
   5523 	__isl_take isl_map *map2)
   5524 {
   5525 	isl_map *map;
   5526 	map = isl_map_lex_lt(isl_space_range(isl_map_get_space(map1)));
   5527 	map = isl_map_apply_domain(map, isl_map_reverse(map1));
   5528 	map = isl_map_apply_range(map, isl_map_reverse(map2));
   5529 	return map;
   5530 }
   5531 
   5532 __isl_give isl_map *isl_map_lex_ge_map(__isl_take isl_map *map1,
   5533 	__isl_take isl_map *map2)
   5534 {
   5535 	isl_map *map;
   5536 	map = isl_map_lex_ge(isl_space_range(isl_map_get_space(map1)));
   5537 	map = isl_map_apply_domain(map, isl_map_reverse(map1));
   5538 	map = isl_map_apply_range(map, isl_map_reverse(map2));
   5539 	return map;
   5540 }
   5541 
   5542 __isl_give isl_map *isl_map_lex_gt_map(__isl_take isl_map *map1,
   5543 	__isl_take isl_map *map2)
   5544 {
   5545 	isl_map *map;
   5546 	map = isl_map_lex_gt(isl_space_range(isl_map_get_space(map1)));
   5547 	map = isl_map_apply_domain(map, isl_map_reverse(map1));
   5548 	map = isl_map_apply_range(map, isl_map_reverse(map2));
   5549 	return map;
   5550 }
   5551 
   5552 /* For the div d = floor(f/m) at position "div", add the constraint
   5553  *
   5554  *		f - m d >= 0
   5555  */
   5556 static __isl_give isl_basic_map *add_upper_div_constraint(
   5557 	__isl_take isl_basic_map *bmap, unsigned div)
   5558 {
   5559 	int i;
   5560 	isl_size v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
   5561 	isl_size n_div;
   5562 	unsigned pos;
   5563 
   5564 	n_div = isl_basic_map_dim(bmap, isl_dim_div);
   5565 	if (v_div < 0 || n_div < 0)
   5566 		return isl_basic_map_free(bmap);
   5567 	pos = v_div + div;
   5568 	i = isl_basic_map_alloc_inequality(bmap);
   5569 	if (i < 0)
   5570 		return isl_basic_map_free(bmap);
   5571 	isl_seq_cpy(bmap->ineq[i], bmap->div[div] + 1, 1 + v_div + n_div);
   5572 	isl_int_neg(bmap->ineq[i][1 + pos], bmap->div[div][0]);
   5573 
   5574 	return bmap;
   5575 }
   5576 
   5577 /* For the div d = floor(f/m) at position "div", add the constraint
   5578  *
   5579  *		-(f-(m-1)) + m d >= 0
   5580  */
   5581 static __isl_give isl_basic_map *add_lower_div_constraint(
   5582 	__isl_take isl_basic_map *bmap, unsigned div)
   5583 {
   5584 	int i;
   5585 	isl_size v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
   5586 	isl_size n_div;
   5587 	unsigned pos;
   5588 
   5589 	n_div = isl_basic_map_dim(bmap, isl_dim_div);
   5590 	if (v_div < 0 || n_div < 0)
   5591 		return isl_basic_map_free(bmap);
   5592 	pos = v_div + div;
   5593 	i = isl_basic_map_alloc_inequality(bmap);
   5594 	if (i < 0)
   5595 		return isl_basic_map_free(bmap);
   5596 	isl_seq_neg(bmap->ineq[i], bmap->div[div] + 1, 1 + v_div + n_div);
   5597 	isl_int_set(bmap->ineq[i][1 + pos], bmap->div[div][0]);
   5598 	isl_int_add(bmap->ineq[i][0], bmap->ineq[i][0], bmap->ineq[i][1 + pos]);
   5599 	isl_int_sub_ui(bmap->ineq[i][0], bmap->ineq[i][0], 1);
   5600 
   5601 	return bmap;
   5602 }
   5603 
   5604 /* For the div d = floor(f/m) at position "pos", add the constraints
   5605  *
   5606  *		f - m d >= 0
   5607  *		-(f-(m-1)) + m d >= 0
   5608  *
   5609  * Note that the second constraint is the negation of
   5610  *
   5611  *		f - m d >= m
   5612  */
   5613 __isl_give isl_basic_map *isl_basic_map_add_div_constraints(
   5614 	__isl_take isl_basic_map *bmap, unsigned pos)
   5615 {
   5616 	bmap = add_upper_div_constraint(bmap, pos);
   5617 	bmap = add_lower_div_constraint(bmap, pos);
   5618 	return bmap;
   5619 }
   5620 
   5621 /* For each known div d = floor(f/m), add the constraints
   5622  *
   5623  *		f - m d >= 0
   5624  *		-(f-(m-1)) + m d >= 0
   5625  *
   5626  * Remove duplicate constraints in case of some these div constraints
   5627  * already appear in "bmap".
   5628  */
   5629 __isl_give isl_basic_map *isl_basic_map_add_known_div_constraints(
   5630 	__isl_take isl_basic_map *bmap)
   5631 {
   5632 	isl_size n_div;
   5633 
   5634 	n_div = isl_basic_map_dim(bmap, isl_dim_div);
   5635 	if (n_div < 0)
   5636 		return isl_basic_map_free(bmap);
   5637 	if (n_div == 0)
   5638 		return bmap;
   5639 
   5640 	bmap = add_known_div_constraints(bmap);
   5641 	bmap = isl_basic_map_remove_duplicate_constraints(bmap, NULL, 0);
   5642 	bmap = isl_basic_map_finalize(bmap);
   5643 	return bmap;
   5644 }
   5645 
   5646 /* Add the div constraint of sign "sign" for div "div" of "bmap".
   5647  *
   5648  * In particular, if this div is of the form d = floor(f/m),
   5649  * then add the constraint
   5650  *
   5651  *		f - m d >= 0
   5652  *
   5653  * if sign < 0 or the constraint
   5654  *
   5655  *		-(f-(m-1)) + m d >= 0
   5656  *
   5657  * if sign > 0.
   5658  */
   5659 __isl_give isl_basic_map *isl_basic_map_add_div_constraint(
   5660 	__isl_take isl_basic_map *bmap, unsigned div, int sign)
   5661 {
   5662 	if (sign < 0)
   5663 		return add_upper_div_constraint(bmap, div);
   5664 	else
   5665 		return add_lower_div_constraint(bmap, div);
   5666 }
   5667 
   5668 __isl_give isl_basic_set *isl_basic_map_underlying_set(
   5669 	__isl_take isl_basic_map *bmap)
   5670 {
   5671 	isl_space *space;
   5672 
   5673 	if (!bmap)
   5674 		goto error;
   5675 	if (bmap->dim->nparam == 0 && bmap->dim->n_in == 0 &&
   5676 	    bmap->n_div == 0 &&
   5677 	    !isl_space_is_named_or_nested(bmap->dim, isl_dim_in) &&
   5678 	    !isl_space_is_named_or_nested(bmap->dim, isl_dim_out))
   5679 		return bset_from_bmap(bmap);
   5680 	bmap = isl_basic_map_cow(bmap);
   5681 	if (!bmap)
   5682 		return NULL;
   5683 	space = isl_basic_map_take_space(bmap);
   5684 	space = isl_space_underlying(space, bmap->n_div);
   5685 	bmap = isl_basic_map_restore_space(bmap, space);
   5686 	if (!bmap)
   5687 		return NULL;
   5688 	bmap->extra -= bmap->n_div;
   5689 	bmap->n_div = 0;
   5690 	bmap = isl_basic_map_finalize(bmap);
   5691 	return bset_from_bmap(bmap);
   5692 error:
   5693 	isl_basic_map_free(bmap);
   5694 	return NULL;
   5695 }
   5696 
   5697 __isl_give isl_basic_set *isl_basic_set_underlying_set(
   5698 		__isl_take isl_basic_set *bset)
   5699 {
   5700 	return isl_basic_map_underlying_set(bset_to_bmap(bset));
   5701 }
   5702 
   5703 /* Replace each element in "list" by the result of applying
   5704  * isl_basic_map_underlying_set to the element.
   5705  */
   5706 __isl_give isl_basic_set_list *isl_basic_map_list_underlying_set(
   5707 	__isl_take isl_basic_map_list *list)
   5708 {
   5709 	int i;
   5710 	isl_size n;
   5711 
   5712 	n = isl_basic_map_list_n_basic_map(list);
   5713 	if (n < 0)
   5714 		goto error;
   5715 
   5716 	for (i = 0; i < n; ++i) {
   5717 		isl_basic_map *bmap;
   5718 		isl_basic_set *bset;
   5719 
   5720 		bmap = isl_basic_map_list_get_basic_map(list, i);
   5721 		bset = isl_basic_set_underlying_set(bmap);
   5722 		list = isl_basic_set_list_set_basic_set(list, i, bset);
   5723 	}
   5724 
   5725 	return list;
   5726 error:
   5727 	isl_basic_map_list_free(list);
   5728 	return NULL;
   5729 }
   5730 
   5731 __isl_give isl_basic_map *isl_basic_map_overlying_set(
   5732 	__isl_take isl_basic_set *bset, __isl_take isl_basic_map *like)
   5733 {
   5734 	struct isl_basic_map *bmap;
   5735 	struct isl_ctx *ctx;
   5736 	isl_size dim, bmap_total;
   5737 	unsigned total;
   5738 	int i;
   5739 
   5740 	if (!bset || !like)
   5741 		goto error;
   5742 	ctx = bset->ctx;
   5743 	if (isl_basic_set_check_no_params(bset) < 0 ||
   5744 	    isl_basic_set_check_no_locals(bset) < 0)
   5745 		goto error;
   5746 	dim = isl_basic_set_dim(bset, isl_dim_set);
   5747 	bmap_total = isl_basic_map_dim(like, isl_dim_all);
   5748 	if (dim < 0 || bmap_total < 0)
   5749 		goto error;
   5750 	isl_assert(ctx, dim == bmap_total, goto error);
   5751 	if (like->n_div == 0) {
   5752 		isl_space *space = isl_basic_map_get_space(like);
   5753 		isl_basic_map_free(like);
   5754 		return isl_basic_map_reset_space(bset, space);
   5755 	}
   5756 	bset = isl_basic_set_cow(bset);
   5757 	if (!bset)
   5758 		goto error;
   5759 	total = dim + bset->extra;
   5760 	bmap = bset_to_bmap(bset);
   5761 	isl_space_free(isl_basic_map_take_space(bmap));
   5762 	bmap = isl_basic_map_restore_space(bmap, isl_basic_map_get_space(like));
   5763 	if (!bmap)
   5764 		goto error;
   5765 	bmap->n_div = like->n_div;
   5766 	bmap->extra += like->n_div;
   5767 	if (bmap->extra) {
   5768 		unsigned ltotal;
   5769 		isl_int **div;
   5770 		ltotal = total - bmap->extra + like->extra;
   5771 		if (ltotal > total)
   5772 			ltotal = total;
   5773 		bmap->block2 = isl_blk_extend(ctx, bmap->block2,
   5774 					bmap->extra * (1 + 1 + total));
   5775 		if (isl_blk_is_error(bmap->block2))
   5776 			goto error;
   5777 		div = isl_realloc_array(ctx, bmap->div, isl_int *, bmap->extra);
   5778 		if (!div)
   5779 			goto error;
   5780 		bmap->div = div;
   5781 		for (i = 0; i < bmap->extra; ++i)
   5782 			bmap->div[i] = bmap->block2.data + i * (1 + 1 + total);
   5783 		for (i = 0; i < like->n_div; ++i) {
   5784 			isl_seq_cpy(bmap->div[i], like->div[i], 1 + 1 + ltotal);
   5785 			isl_seq_clr(bmap->div[i]+1+1+ltotal, total - ltotal);
   5786 		}
   5787 		bmap = isl_basic_map_add_known_div_constraints(bmap);
   5788 	}
   5789 	isl_basic_map_free(like);
   5790 	bmap = isl_basic_map_simplify(bmap);
   5791 	bmap = isl_basic_map_finalize(bmap);
   5792 	return bmap;
   5793 error:
   5794 	isl_basic_map_free(like);
   5795 	isl_basic_set_free(bset);
   5796 	return NULL;
   5797 }
   5798 
   5799 __isl_give isl_basic_set *isl_basic_set_from_underlying_set(
   5800 	__isl_take isl_basic_set *bset, __isl_take isl_basic_set *like)
   5801 {
   5802 	return bset_from_bmap(isl_basic_map_overlying_set(bset,
   5803 							bset_to_bmap(like)));
   5804 }
   5805 
   5806 __isl_give isl_set *isl_map_underlying_set(__isl_take isl_map *map)
   5807 {
   5808 	int i;
   5809 
   5810 	map = isl_map_cow(map);
   5811 	if (!map)
   5812 		return NULL;
   5813 	map->dim = isl_space_cow(map->dim);
   5814 	if (!map->dim)
   5815 		goto error;
   5816 
   5817 	for (i = 1; i < map->n; ++i)
   5818 		isl_assert(map->ctx, map->p[0]->n_div == map->p[i]->n_div,
   5819 				goto error);
   5820 	for (i = 0; i < map->n; ++i) {
   5821 		map->p[i] = bset_to_bmap(
   5822 				isl_basic_map_underlying_set(map->p[i]));
   5823 		if (!map->p[i])
   5824 			goto error;
   5825 	}
   5826 	if (map->n == 0)
   5827 		map->dim = isl_space_underlying(map->dim, 0);
   5828 	else {
   5829 		isl_space_free(map->dim);
   5830 		map->dim = isl_space_copy(map->p[0]->dim);
   5831 	}
   5832 	if (!map->dim)
   5833 		goto error;
   5834 	return set_from_map(map);
   5835 error:
   5836 	isl_map_free(map);
   5837 	return NULL;
   5838 }
   5839 
   5840 /* Replace the space of "bmap" by "space".
   5841  *
   5842  * If the space of "bmap" is identical to "space" (including the identifiers
   5843  * of the input and output dimensions), then simply return the original input.
   5844  */
   5845 __isl_give isl_basic_map *isl_basic_map_reset_space(
   5846 	__isl_take isl_basic_map *bmap, __isl_take isl_space *space)
   5847 {
   5848 	isl_bool equal;
   5849 	isl_space *bmap_space;
   5850 
   5851 	bmap_space = isl_basic_map_peek_space(bmap);
   5852 	equal = isl_space_is_equal(bmap_space, space);
   5853 	if (equal >= 0 && equal)
   5854 		equal = isl_space_has_equal_ids(bmap_space, space);
   5855 	if (equal < 0)
   5856 		goto error;
   5857 	if (equal) {
   5858 		isl_space_free(space);
   5859 		return bmap;
   5860 	}
   5861 	isl_space_free(isl_basic_map_take_space(bmap));
   5862 	bmap = isl_basic_map_restore_space(bmap, space);
   5863 
   5864 	bmap = isl_basic_map_finalize(bmap);
   5865 
   5866 	return bmap;
   5867 error:
   5868 	isl_basic_map_free(bmap);
   5869 	isl_space_free(space);
   5870 	return NULL;
   5871 }
   5872 
   5873 __isl_give isl_basic_set *isl_basic_set_reset_space(
   5874 	__isl_take isl_basic_set *bset, __isl_take isl_space *space)
   5875 {
   5876 	return bset_from_bmap(isl_basic_map_reset_space(bset_to_bmap(bset),
   5877 							space));
   5878 }
   5879 
   5880 /* Check that the total dimensions of "map" and "space" are the same.
   5881  */
   5882 static isl_stat check_map_space_equal_total_dim(__isl_keep isl_map *map,
   5883 	__isl_keep isl_space *space)
   5884 {
   5885 	isl_size dim1, dim2;
   5886 
   5887 	dim1 = isl_map_dim(map, isl_dim_all);
   5888 	dim2 = isl_space_dim(space, isl_dim_all);
   5889 	if (dim1 < 0 || dim2 < 0)
   5890 		return isl_stat_error;
   5891 	if (dim1 == dim2)
   5892 		return isl_stat_ok;
   5893 	isl_die(isl_map_get_ctx(map), isl_error_invalid,
   5894 		"total dimensions do not match", return isl_stat_error);
   5895 }
   5896 
   5897 __isl_give isl_map *isl_map_reset_space(__isl_take isl_map *map,
   5898 	__isl_take isl_space *space)
   5899 {
   5900 	int i;
   5901 
   5902 	map = isl_map_cow(map);
   5903 	if (!map || !space)
   5904 		goto error;
   5905 
   5906 	for (i = 0; i < map->n; ++i) {
   5907 		map->p[i] = isl_basic_map_reset_space(map->p[i],
   5908 						    isl_space_copy(space));
   5909 		if (!map->p[i])
   5910 			goto error;
   5911 	}
   5912 	isl_space_free(isl_map_take_space(map));
   5913 	map = isl_map_restore_space(map, space);
   5914 
   5915 	return map;
   5916 error:
   5917 	isl_map_free(map);
   5918 	isl_space_free(space);
   5919 	return NULL;
   5920 }
   5921 
   5922 /* Replace the space of "map" by "space", without modifying
   5923  * the dimension of "map".
   5924  *
   5925  * If the space of "map" is identical to "space" (including the identifiers
   5926  * of the input and output dimensions), then simply return the original input.
   5927  */
   5928 __isl_give isl_map *isl_map_reset_equal_dim_space(__isl_take isl_map *map,
   5929 	__isl_take isl_space *space)
   5930 {
   5931 	isl_bool equal;
   5932 	isl_space *map_space;
   5933 
   5934 	map_space = isl_map_peek_space(map);
   5935 	equal = isl_space_is_equal(map_space, space);
   5936 	if (equal >= 0 && equal)
   5937 		equal = isl_space_has_equal_ids(map_space, space);
   5938 	if (equal < 0)
   5939 		goto error;
   5940 	if (equal) {
   5941 		isl_space_free(space);
   5942 		return map;
   5943 	}
   5944 	if (check_map_space_equal_total_dim(map, space) < 0)
   5945 		goto error;
   5946 	return isl_map_reset_space(map, space);
   5947 error:
   5948 	isl_map_free(map);
   5949 	isl_space_free(space);
   5950 	return NULL;
   5951 }
   5952 
   5953 __isl_give isl_set *isl_set_reset_space(__isl_take isl_set *set,
   5954 	__isl_take isl_space *space)
   5955 {
   5956 	return set_from_map(isl_map_reset_space(set_to_map(set), space));
   5957 }
   5958 
   5959 /* Compute the parameter domain of the given basic set.
   5960  */
   5961 __isl_give isl_basic_set *isl_basic_set_params(__isl_take isl_basic_set *bset)
   5962 {
   5963 	isl_bool is_params;
   5964 	isl_space *space;
   5965 	isl_size n;
   5966 
   5967 	is_params = isl_basic_set_is_params(bset);
   5968 	if (is_params < 0)
   5969 		return isl_basic_set_free(bset);
   5970 	if (is_params)
   5971 		return bset;
   5972 
   5973 	n = isl_basic_set_dim(bset, isl_dim_set);
   5974 	if (n < 0)
   5975 		return isl_basic_set_free(bset);
   5976 	bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n);
   5977 	space = isl_basic_set_get_space(bset);
   5978 	space = isl_space_params(space);
   5979 	bset = isl_basic_set_reset_space(bset, space);
   5980 	return bset;
   5981 }
   5982 
   5983 /* Construct a zero-dimensional basic set with the given parameter domain.
   5984  */
   5985 __isl_give isl_basic_set *isl_basic_set_from_params(
   5986 	__isl_take isl_basic_set *bset)
   5987 {
   5988 	isl_space *space;
   5989 	space = isl_basic_set_get_space(bset);
   5990 	space = isl_space_set_from_params(space);
   5991 	bset = isl_basic_set_reset_space(bset, space);
   5992 	return bset;
   5993 }
   5994 
   5995 /* Compute the parameter domain of the given set.
   5996  */
   5997 __isl_give isl_set *isl_set_params(__isl_take isl_set *set)
   5998 {
   5999 	return isl_map_params(set_to_map(set));
   6000 }
   6001 
   6002 /* Construct a zero-dimensional set with the given parameter domain.
   6003  */
   6004 __isl_give isl_set *isl_set_from_params(__isl_take isl_set *set)
   6005 {
   6006 	isl_space *space;
   6007 	space = isl_set_get_space(set);
   6008 	space = isl_space_set_from_params(space);
   6009 	set = isl_set_reset_space(set, space);
   6010 	return set;
   6011 }
   6012 
   6013 /* Compute the parameter domain of the given map.
   6014  */
   6015 __isl_give isl_set *isl_map_params(__isl_take isl_map *map)
   6016 {
   6017 	isl_space *space;
   6018 	isl_size n_in, n_out;
   6019 
   6020 	n_in = isl_map_dim(map, isl_dim_in);
   6021 	n_out = isl_map_dim(map, isl_dim_out);
   6022 	if (n_in < 0 || n_out < 0)
   6023 		return isl_map_free(map);
   6024 	map = isl_map_project_out(map, isl_dim_in, 0, n_in);
   6025 	map = isl_map_project_out(map, isl_dim_out, 0, n_out);
   6026 	space = isl_map_get_space(map);
   6027 	space = isl_space_params(space);
   6028 	map = isl_map_reset_space(map, space);
   6029 	return map;
   6030 }
   6031 
   6032 __isl_give isl_basic_set *isl_basic_map_domain(__isl_take isl_basic_map *bmap)
   6033 {
   6034 	isl_space *space;
   6035 	isl_size n_out;
   6036 
   6037 	n_out = isl_basic_map_dim(bmap, isl_dim_out);
   6038 	if (n_out < 0)
   6039 		return isl_basic_map_free(bmap);
   6040 	space = isl_space_domain(isl_basic_map_get_space(bmap));
   6041 
   6042 	bmap = isl_basic_map_project_out(bmap, isl_dim_out, 0, n_out);
   6043 
   6044 	return isl_basic_map_reset_space(bmap, space);
   6045 }
   6046 
   6047 isl_bool isl_basic_map_may_be_set(__isl_keep isl_basic_map *bmap)
   6048 {
   6049 	if (!bmap)
   6050 		return isl_bool_error;
   6051 	return isl_space_may_be_set(bmap->dim);
   6052 }
   6053 
   6054 /* Is this basic map actually a set?
   6055  * Users should never call this function.  Outside of isl,
   6056  * the type should indicate whether something is a set or a map.
   6057  */
   6058 isl_bool isl_basic_map_is_set(__isl_keep isl_basic_map *bmap)
   6059 {
   6060 	if (!bmap)
   6061 		return isl_bool_error;
   6062 	return isl_space_is_set(bmap->dim);
   6063 }
   6064 
   6065 __isl_give isl_basic_set *isl_basic_map_range(__isl_take isl_basic_map *bmap)
   6066 {
   6067 	isl_bool is_set;
   6068 
   6069 	is_set = isl_basic_map_is_set(bmap);
   6070 	if (is_set < 0)
   6071 		goto error;
   6072 	if (is_set)
   6073 		return bmap;
   6074 	return isl_basic_map_domain(isl_basic_map_reverse(bmap));
   6075 error:
   6076 	isl_basic_map_free(bmap);
   6077 	return NULL;
   6078 }
   6079 
   6080 __isl_give isl_basic_map *isl_basic_map_domain_map(
   6081 	__isl_take isl_basic_map *bmap)
   6082 {
   6083 	int i;
   6084 	isl_space *space;
   6085 	isl_basic_map *domain;
   6086 	isl_size nparam, n_in, n_out;
   6087 
   6088 	nparam = isl_basic_map_dim(bmap, isl_dim_param);
   6089 	n_in = isl_basic_map_dim(bmap, isl_dim_in);
   6090 	n_out = isl_basic_map_dim(bmap, isl_dim_out);
   6091 	if (nparam < 0 || n_in < 0 || n_out < 0)
   6092 		return isl_basic_map_free(bmap);
   6093 
   6094 	space = isl_basic_map_get_space(bmap);
   6095 	space = isl_space_from_range(isl_space_domain(space));
   6096 	domain = isl_basic_map_universe(space);
   6097 
   6098 	bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
   6099 	bmap = isl_basic_map_apply_range(bmap, domain);
   6100 	bmap = isl_basic_map_extend_constraints(bmap, n_in, 0);
   6101 
   6102 	for (i = 0; i < n_in; ++i)
   6103 		bmap = isl_basic_map_equate(bmap, isl_dim_in, i,
   6104 						    isl_dim_out, i);
   6105 
   6106 	bmap = isl_basic_map_gauss(bmap, NULL);
   6107 	return isl_basic_map_finalize(bmap);
   6108 }
   6109 
   6110 __isl_give isl_basic_map *isl_basic_map_range_map(
   6111 	__isl_take isl_basic_map *bmap)
   6112 {
   6113 	int i;
   6114 	isl_space *space;
   6115 	isl_basic_map *range;
   6116 	isl_size nparam, n_in, n_out;
   6117 
   6118 	nparam = isl_basic_map_dim(bmap, isl_dim_param);
   6119 	n_in = isl_basic_map_dim(bmap, isl_dim_in);
   6120 	n_out = isl_basic_map_dim(bmap, isl_dim_out);
   6121 	if (nparam < 0 || n_in < 0 || n_out < 0)
   6122 		return isl_basic_map_free(bmap);
   6123 
   6124 	space = isl_basic_map_get_space(bmap);
   6125 	space = isl_space_from_range(isl_space_range(space));
   6126 	range = isl_basic_map_universe(space);
   6127 
   6128 	bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
   6129 	bmap = isl_basic_map_apply_range(bmap, range);
   6130 	bmap = isl_basic_map_extend_constraints(bmap, n_out, 0);
   6131 
   6132 	for (i = 0; i < n_out; ++i)
   6133 		bmap = isl_basic_map_equate(bmap, isl_dim_in, n_in + i,
   6134 						    isl_dim_out, i);
   6135 
   6136 	bmap = isl_basic_map_gauss(bmap, NULL);
   6137 	return isl_basic_map_finalize(bmap);
   6138 }
   6139 
   6140 int isl_map_may_be_set(__isl_keep isl_map *map)
   6141 {
   6142 	if (!map)
   6143 		return -1;
   6144 	return isl_space_may_be_set(map->dim);
   6145 }
   6146 
   6147 /* Is this map actually a set?
   6148  * Users should never call this function.  Outside of isl,
   6149  * the type should indicate whether something is a set or a map.
   6150  */
   6151 isl_bool isl_map_is_set(__isl_keep isl_map *map)
   6152 {
   6153 	if (!map)
   6154 		return isl_bool_error;
   6155 	return isl_space_is_set(map->dim);
   6156 }
   6157 
   6158 __isl_give isl_set *isl_map_range(__isl_take isl_map *map)
   6159 {
   6160 	isl_space *space;
   6161 	isl_size n_in;
   6162 
   6163 	n_in = isl_map_dim(map, isl_dim_in);
   6164 	if (n_in < 0)
   6165 		return set_from_map(isl_map_free(map));
   6166 	space = isl_space_range(isl_map_get_space(map));
   6167 
   6168 	map = isl_map_project_out(map, isl_dim_in, 0, n_in);
   6169 
   6170 	return set_from_map(isl_map_reset_space(map, space));
   6171 }
   6172 
   6173 /* Transform "map" by applying "fn_space" to its space and "fn_bmap"
   6174  * to each of its basic maps.
   6175  */
   6176 static __isl_give isl_map *isl_map_transform(__isl_take isl_map *map,
   6177 	__isl_give isl_space *(*fn_space)(__isl_take isl_space *space),
   6178 	__isl_give isl_basic_map *(*fn_bmap)(__isl_take isl_basic_map *bmap))
   6179 {
   6180 	int i;
   6181 	isl_space *space;
   6182 
   6183 	map = isl_map_cow(map);
   6184 	if (!map)
   6185 		return NULL;
   6186 
   6187 	for (i = 0; i < map->n; ++i) {
   6188 		map->p[i] = fn_bmap(map->p[i]);
   6189 		if (!map->p[i])
   6190 			return isl_map_free(map);
   6191 	}
   6192 	map = isl_map_unmark_normalized(map);
   6193 
   6194 	space = isl_map_take_space(map);
   6195 	space = fn_space(space);
   6196 	map = isl_map_restore_space(map, space);
   6197 
   6198 	return map;
   6199 }
   6200 
   6201 __isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map)
   6202 {
   6203 	return isl_map_transform(map, &isl_space_domain_map,
   6204 					&isl_basic_map_domain_map);
   6205 }
   6206 
   6207 __isl_give isl_map *isl_map_range_map(__isl_take isl_map *map)
   6208 {
   6209 	return isl_map_transform(map, &isl_space_range_map,
   6210 					&isl_basic_map_range_map);
   6211 }
   6212 
   6213 /* Given a wrapped map of the form A[B -> C],
   6214  * return the map A[B -> C] -> B.
   6215  */
   6216 __isl_give isl_map *isl_set_wrapped_domain_map(__isl_take isl_set *set)
   6217 {
   6218 	isl_id *id;
   6219 	isl_map *map;
   6220 
   6221 	if (!set)
   6222 		return NULL;
   6223 	if (!isl_set_has_tuple_id(set))
   6224 		return isl_map_domain_map(isl_set_unwrap(set));
   6225 
   6226 	id = isl_set_get_tuple_id(set);
   6227 	map = isl_map_domain_map(isl_set_unwrap(set));
   6228 	map = isl_map_set_tuple_id(map, isl_dim_in, id);
   6229 
   6230 	return map;
   6231 }
   6232 
   6233 __isl_give isl_basic_map *isl_basic_map_from_domain(
   6234 	__isl_take isl_basic_set *bset)
   6235 {
   6236 	return isl_basic_map_reverse(isl_basic_map_from_range(bset));
   6237 }
   6238 
   6239 __isl_give isl_basic_map *isl_basic_map_from_range(
   6240 	__isl_take isl_basic_set *bset)
   6241 {
   6242 	isl_space *space;
   6243 	space = isl_basic_set_get_space(bset);
   6244 	space = isl_space_from_range(space);
   6245 	bset = isl_basic_set_reset_space(bset, space);
   6246 	return bset_to_bmap(bset);
   6247 }
   6248 
   6249 /* Create a relation with the given set as range.
   6250  * The domain of the created relation is a zero-dimensional
   6251  * flat anonymous space.
   6252  */
   6253 __isl_give isl_map *isl_map_from_range(__isl_take isl_set *set)
   6254 {
   6255 	isl_space *space;
   6256 	space = isl_set_get_space(set);
   6257 	space = isl_space_from_range(space);
   6258 	set = isl_set_reset_space(set, space);
   6259 	return set_to_map(set);
   6260 }
   6261 
   6262 /* Create a relation with the given set as domain.
   6263  * The range of the created relation is a zero-dimensional
   6264  * flat anonymous space.
   6265  */
   6266 __isl_give isl_map *isl_map_from_domain(__isl_take isl_set *set)
   6267 {
   6268 	return isl_map_reverse(isl_map_from_range(set));
   6269 }
   6270 
   6271 __isl_give isl_basic_map *isl_basic_map_from_domain_and_range(
   6272 	__isl_take isl_basic_set *domain, __isl_take isl_basic_set *range)
   6273 {
   6274 	return isl_basic_map_apply_range(isl_basic_map_reverse(domain), range);
   6275 }
   6276 
   6277 __isl_give isl_map *isl_map_from_domain_and_range(__isl_take isl_set *domain,
   6278 	__isl_take isl_set *range)
   6279 {
   6280 	return isl_map_apply_range(isl_map_reverse(domain), range);
   6281 }
   6282 
   6283 /* Return a newly allocated isl_map with given space and flags and
   6284  * room for "n" basic maps.
   6285  * Make sure that all cached information is cleared.
   6286  */
   6287 __isl_give isl_map *isl_map_alloc_space(__isl_take isl_space *space, int n,
   6288 	unsigned flags)
   6289 {
   6290 	struct isl_map *map;
   6291 
   6292 	if (!space)
   6293 		return NULL;
   6294 	if (n < 0)
   6295 		isl_die(space->ctx, isl_error_internal,
   6296 			"negative number of basic maps", goto error);
   6297 	map = isl_calloc(space->ctx, struct isl_map,
   6298 			sizeof(struct isl_map) +
   6299 			(n - 1) * sizeof(struct isl_basic_map *));
   6300 	if (!map)
   6301 		goto error;
   6302 
   6303 	map->ctx = space->ctx;
   6304 	isl_ctx_ref(map->ctx);
   6305 	map->ref = 1;
   6306 	map->size = n;
   6307 	map->n = 0;
   6308 	map->dim = space;
   6309 	map->flags = flags;
   6310 	return map;
   6311 error:
   6312 	isl_space_free(space);
   6313 	return NULL;
   6314 }
   6315 
   6316 __isl_give isl_basic_map *isl_basic_map_empty(__isl_take isl_space *space)
   6317 {
   6318 	struct isl_basic_map *bmap;
   6319 	bmap = isl_basic_map_alloc_space(space, 0, 1, 0);
   6320 	bmap = isl_basic_map_set_to_empty(bmap);
   6321 	return bmap;
   6322 }
   6323 
   6324 __isl_give isl_basic_set *isl_basic_set_empty(__isl_take isl_space *space)
   6325 {
   6326 	struct isl_basic_set *bset;
   6327 	bset = isl_basic_set_alloc_space(space, 0, 1, 0);
   6328 	bset = isl_basic_set_set_to_empty(bset);
   6329 	return bset;
   6330 }
   6331 
   6332 __isl_give isl_basic_map *isl_basic_map_universe(__isl_take isl_space *space)
   6333 {
   6334 	struct isl_basic_map *bmap;
   6335 	bmap = isl_basic_map_alloc_space(space, 0, 0, 0);
   6336 	bmap = isl_basic_map_finalize(bmap);
   6337 	return bmap;
   6338 }
   6339 
   6340 __isl_give isl_basic_set *isl_basic_set_universe(__isl_take isl_space *space)
   6341 {
   6342 	struct isl_basic_set *bset;
   6343 	bset = isl_basic_set_alloc_space(space, 0, 0, 0);
   6344 	bset = isl_basic_set_finalize(bset);
   6345 	return bset;
   6346 }
   6347 
   6348 __isl_give isl_basic_map *isl_basic_map_nat_universe(
   6349 	__isl_take isl_space *space)
   6350 {
   6351 	int i;
   6352 	isl_size total = isl_space_dim(space, isl_dim_all);
   6353 	isl_basic_map *bmap;
   6354 
   6355 	if (total < 0)
   6356 		space = isl_space_free(space);
   6357 	bmap = isl_basic_map_alloc_space(space, 0, 0, total);
   6358 	for (i = 0; i < total; ++i) {
   6359 		int k = isl_basic_map_alloc_inequality(bmap);
   6360 		if (k < 0)
   6361 			goto error;
   6362 		isl_seq_clr(bmap->ineq[k], 1 + total);
   6363 		isl_int_set_si(bmap->ineq[k][1 + i], 1);
   6364 	}
   6365 	return bmap;
   6366 error:
   6367 	isl_basic_map_free(bmap);
   6368 	return NULL;
   6369 }
   6370 
   6371 __isl_give isl_basic_set *isl_basic_set_nat_universe(
   6372 	__isl_take isl_space *space)
   6373 {
   6374 	return isl_basic_map_nat_universe(space);
   6375 }
   6376 
   6377 __isl_give isl_map *isl_map_nat_universe(__isl_take isl_space *space)
   6378 {
   6379 	return isl_map_from_basic_map(isl_basic_map_nat_universe(space));
   6380 }
   6381 
   6382 __isl_give isl_set *isl_set_nat_universe(__isl_take isl_space *space)
   6383 {
   6384 	return isl_map_nat_universe(space);
   6385 }
   6386 
   6387 __isl_give isl_map *isl_map_empty(__isl_take isl_space *space)
   6388 {
   6389 	return isl_map_alloc_space(space, 0, ISL_MAP_DISJOINT);
   6390 }
   6391 
   6392 __isl_give isl_set *isl_set_empty(__isl_take isl_space *space)
   6393 {
   6394 	return isl_set_alloc_space(space, 0, ISL_MAP_DISJOINT);
   6395 }
   6396 
   6397 __isl_give isl_map *isl_map_universe(__isl_take isl_space *space)
   6398 {
   6399 	struct isl_map *map;
   6400 	if (!space)
   6401 		return NULL;
   6402 	map = isl_map_alloc_space(isl_space_copy(space), 1, ISL_MAP_DISJOINT);
   6403 	map = isl_map_add_basic_map(map, isl_basic_map_universe(space));
   6404 	return map;
   6405 }
   6406 
   6407 /* This function performs the same operation as isl_map_universe,
   6408  * but is considered as a function on an isl_space when exported.
   6409  */
   6410 __isl_give isl_map *isl_space_universe_map(__isl_take isl_space *space)
   6411 {
   6412 	return isl_map_universe(space);
   6413 }
   6414 
   6415 __isl_give isl_set *isl_set_universe(__isl_take isl_space *space)
   6416 {
   6417 	struct isl_set *set;
   6418 	if (!space)
   6419 		return NULL;
   6420 	set = isl_set_alloc_space(isl_space_copy(space), 1, ISL_MAP_DISJOINT);
   6421 	set = isl_set_add_basic_set(set, isl_basic_set_universe(space));
   6422 	return set;
   6423 }
   6424 
   6425 /* This function performs the same operation as isl_set_universe,
   6426  * but is considered as a function on an isl_space when exported.
   6427  */
   6428 __isl_give isl_set *isl_space_universe_set(__isl_take isl_space *space)
   6429 {
   6430 	return isl_set_universe(space);
   6431 }
   6432 
   6433 __isl_give isl_map *isl_map_dup(__isl_keep isl_map *map)
   6434 {
   6435 	int i;
   6436 	struct isl_map *dup;
   6437 
   6438 	if (!map)
   6439 		return NULL;
   6440 	dup = isl_map_alloc_space(isl_space_copy(map->dim), map->n, map->flags);
   6441 	for (i = 0; i < map->n; ++i)
   6442 		dup = isl_map_add_basic_map(dup, isl_basic_map_copy(map->p[i]));
   6443 	return dup;
   6444 }
   6445 
   6446 __isl_give isl_map *isl_map_add_basic_map(__isl_take isl_map *map,
   6447 						__isl_take isl_basic_map *bmap)
   6448 {
   6449 	if (!bmap || !map)
   6450 		goto error;
   6451 	if (isl_basic_map_plain_is_empty(bmap)) {
   6452 		isl_basic_map_free(bmap);
   6453 		return map;
   6454 	}
   6455 	if (isl_map_basic_map_check_equal_space(map, bmap) < 0)
   6456 		goto error;
   6457 	isl_assert(map->ctx, map->n < map->size, goto error);
   6458 	map->p[map->n] = bmap;
   6459 	map->n++;
   6460 	map = isl_map_unmark_normalized(map);
   6461 	return map;
   6462 error:
   6463 	if (map)
   6464 		isl_map_free(map);
   6465 	if (bmap)
   6466 		isl_basic_map_free(bmap);
   6467 	return NULL;
   6468 }
   6469 
   6470 __isl_null isl_map *isl_map_free(__isl_take isl_map *map)
   6471 {
   6472 	int i;
   6473 
   6474 	if (!map)
   6475 		return NULL;
   6476 
   6477 	if (--map->ref > 0)
   6478 		return NULL;
   6479 
   6480 	clear_caches(map);
   6481 	isl_ctx_deref(map->ctx);
   6482 	for (i = 0; i < map->n; ++i)
   6483 		isl_basic_map_free(map->p[i]);
   6484 	isl_space_free(map->dim);
   6485 	free(map);
   6486 
   6487 	return NULL;
   6488 }
   6489 
   6490 static __isl_give isl_basic_map *isl_basic_map_fix_pos_si(
   6491 	__isl_take isl_basic_map *bmap, unsigned pos, int value)
   6492 {
   6493 	int j;
   6494 	isl_size total;
   6495 
   6496 	total = isl_basic_map_dim(bmap, isl_dim_all);
   6497 	if (total < 0)
   6498 		return isl_basic_map_free(bmap);
   6499 
   6500 	bmap = isl_basic_map_cow(bmap);
   6501 	bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
   6502 	j = isl_basic_map_alloc_equality(bmap);
   6503 	if (j < 0)
   6504 		goto error;
   6505 	isl_seq_clr(bmap->eq[j] + 1, total);
   6506 	isl_int_set_si(bmap->eq[j][pos], -1);
   6507 	isl_int_set_si(bmap->eq[j][0], value);
   6508 	bmap = isl_basic_map_simplify(bmap);
   6509 	return isl_basic_map_finalize(bmap);
   6510 error:
   6511 	isl_basic_map_free(bmap);
   6512 	return NULL;
   6513 }
   6514 
   6515 static __isl_give isl_basic_map *isl_basic_map_fix_pos(
   6516 	__isl_take isl_basic_map *bmap, unsigned pos, isl_int value)
   6517 {
   6518 	int j;
   6519 	isl_size total;
   6520 
   6521 	total = isl_basic_map_dim(bmap, isl_dim_all);
   6522 	if (total < 0)
   6523 		return isl_basic_map_free(bmap);
   6524 
   6525 	bmap = isl_basic_map_cow(bmap);
   6526 	bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
   6527 	j = isl_basic_map_alloc_equality(bmap);
   6528 	if (j < 0)
   6529 		goto error;
   6530 	isl_seq_clr(bmap->eq[j] + 1, total);
   6531 	isl_int_set_si(bmap->eq[j][pos], -1);
   6532 	isl_int_set(bmap->eq[j][0], value);
   6533 	bmap = isl_basic_map_simplify(bmap);
   6534 	return isl_basic_map_finalize(bmap);
   6535 error:
   6536 	isl_basic_map_free(bmap);
   6537 	return NULL;
   6538 }
   6539 
   6540 __isl_give isl_basic_map *isl_basic_map_fix_si(__isl_take isl_basic_map *bmap,
   6541 		enum isl_dim_type type, unsigned pos, int value)
   6542 {
   6543 	if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
   6544 		return isl_basic_map_free(bmap);
   6545 	return isl_basic_map_fix_pos_si(bmap,
   6546 		isl_basic_map_offset(bmap, type) + pos, value);
   6547 }
   6548 
   6549 __isl_give isl_basic_map *isl_basic_map_fix(__isl_take isl_basic_map *bmap,
   6550 		enum isl_dim_type type, unsigned pos, isl_int value)
   6551 {
   6552 	if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
   6553 		return isl_basic_map_free(bmap);
   6554 	return isl_basic_map_fix_pos(bmap,
   6555 		isl_basic_map_offset(bmap, type) + pos, value);
   6556 }
   6557 
   6558 /* Fix the value of the variable at position "pos" of type "type" of "bmap"
   6559  * to be equal to "v".
   6560  */
   6561 __isl_give isl_basic_map *isl_basic_map_fix_val(__isl_take isl_basic_map *bmap,
   6562 	enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
   6563 {
   6564 	if (!bmap || !v)
   6565 		goto error;
   6566 	if (!isl_val_is_int(v))
   6567 		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
   6568 			"expecting integer value", goto error);
   6569 	if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
   6570 		goto error;
   6571 	pos += isl_basic_map_offset(bmap, type);
   6572 	bmap = isl_basic_map_fix_pos(bmap, pos, v->n);
   6573 	isl_val_free(v);
   6574 	return bmap;
   6575 error:
   6576 	isl_basic_map_free(bmap);
   6577 	isl_val_free(v);
   6578 	return NULL;
   6579 }
   6580 
   6581 /* Fix the value of the variable at position "pos" of type "type" of "bset"
   6582  * to be equal to "v".
   6583  */
   6584 __isl_give isl_basic_set *isl_basic_set_fix_val(__isl_take isl_basic_set *bset,
   6585 	enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
   6586 {
   6587 	return isl_basic_map_fix_val(bset, type, pos, v);
   6588 }
   6589 
   6590 __isl_give isl_basic_set *isl_basic_set_fix_si(__isl_take isl_basic_set *bset,
   6591 		enum isl_dim_type type, unsigned pos, int value)
   6592 {
   6593 	return bset_from_bmap(isl_basic_map_fix_si(bset_to_bmap(bset),
   6594 						    type, pos, value));
   6595 }
   6596 
   6597 __isl_give isl_basic_set *isl_basic_set_fix(__isl_take isl_basic_set *bset,
   6598 		enum isl_dim_type type, unsigned pos, isl_int value)
   6599 {
   6600 	return bset_from_bmap(isl_basic_map_fix(bset_to_bmap(bset),
   6601 						    type, pos, value));
   6602 }
   6603 
   6604 /* Remove the basic map at position "i" from "map" if this basic map
   6605  * is (obviously) empty.
   6606  */
   6607 static __isl_give isl_map *remove_if_empty(__isl_take isl_map *map, int i)
   6608 {
   6609 	isl_bool empty;
   6610 
   6611 	if (!map)
   6612 		return NULL;
   6613 
   6614 	empty = isl_basic_map_plain_is_empty(map->p[i]);
   6615 	if (empty < 0)
   6616 		return isl_map_free(map);
   6617 	if (!empty)
   6618 		return map;
   6619 
   6620 	isl_basic_map_free(map->p[i]);
   6621 	map->n--;
   6622 	if (i != map->n) {
   6623 		map->p[i] = map->p[map->n];
   6624 		map = isl_map_unmark_normalized(map);
   6625 
   6626 	}
   6627 
   6628 	return map;
   6629 }
   6630 
   6631 /* Perform "fn" on each basic map of "map", where we may not be holding
   6632  * the only reference to "map".
   6633  * In particular, "fn" should be a semantics preserving operation
   6634  * that we want to apply to all copies of "map".  We therefore need
   6635  * to be careful not to modify "map" in a way that breaks "map"
   6636  * in case anything goes wrong.
   6637  */
   6638 __isl_give isl_map *isl_map_inline_foreach_basic_map(__isl_take isl_map *map,
   6639 	__isl_give isl_basic_map *(*fn)(__isl_take isl_basic_map *bmap))
   6640 {
   6641 	struct isl_basic_map *bmap;
   6642 	int i;
   6643 
   6644 	if (!map)
   6645 		return NULL;
   6646 
   6647 	for (i = map->n - 1; i >= 0; --i) {
   6648 		bmap = isl_basic_map_copy(map->p[i]);
   6649 		bmap = fn(bmap);
   6650 		if (!bmap)
   6651 			goto error;
   6652 		isl_basic_map_free(map->p[i]);
   6653 		map->p[i] = bmap;
   6654 		map = remove_if_empty(map, i);
   6655 		if (!map)
   6656 			return NULL;
   6657 	}
   6658 
   6659 	return map;
   6660 error:
   6661 	isl_map_free(map);
   6662 	return NULL;
   6663 }
   6664 
   6665 __isl_give isl_map *isl_map_fix_si(__isl_take isl_map *map,
   6666 		enum isl_dim_type type, unsigned pos, int value)
   6667 {
   6668 	int i;
   6669 
   6670 	map = isl_map_cow(map);
   6671 	if (isl_map_check_range(map, type, pos, 1) < 0)
   6672 		return isl_map_free(map);
   6673 	for (i = map->n - 1; i >= 0; --i) {
   6674 		map->p[i] = isl_basic_map_fix_si(map->p[i], type, pos, value);
   6675 		map = remove_if_empty(map, i);
   6676 		if (!map)
   6677 			return NULL;
   6678 	}
   6679 	map = isl_map_unmark_normalized(map);
   6680 	return map;
   6681 }
   6682 
   6683 __isl_give isl_set *isl_set_fix_si(__isl_take isl_set *set,
   6684 		enum isl_dim_type type, unsigned pos, int value)
   6685 {
   6686 	return set_from_map(isl_map_fix_si(set_to_map(set), type, pos, value));
   6687 }
   6688 
   6689 __isl_give isl_map *isl_map_fix(__isl_take isl_map *map,
   6690 		enum isl_dim_type type, unsigned pos, isl_int value)
   6691 {
   6692 	int i;
   6693 
   6694 	map = isl_map_cow(map);
   6695 	if (isl_map_check_range(map, type, pos, 1) < 0)
   6696 		return isl_map_free(map);
   6697 	for (i = 0; i < map->n; ++i) {
   6698 		map->p[i] = isl_basic_map_fix(map->p[i], type, pos, value);
   6699 		if (!map->p[i])
   6700 			goto error;
   6701 	}
   6702 	map = isl_map_unmark_normalized(map);
   6703 	return map;
   6704 error:
   6705 	isl_map_free(map);
   6706 	return NULL;
   6707 }
   6708 
   6709 __isl_give isl_set *isl_set_fix(__isl_take isl_set *set,
   6710 		enum isl_dim_type type, unsigned pos, isl_int value)
   6711 {
   6712 	return set_from_map(isl_map_fix(set_to_map(set), type, pos, value));
   6713 }
   6714 
   6715 /* Fix the value of the variable at position "pos" of type "type" of "map"
   6716  * to be equal to "v".
   6717  */
   6718 __isl_give isl_map *isl_map_fix_val(__isl_take isl_map *map,
   6719 	enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
   6720 {
   6721 	int i;
   6722 
   6723 	map = isl_map_cow(map);
   6724 	if (!map || !v)
   6725 		goto error;
   6726 
   6727 	if (!isl_val_is_int(v))
   6728 		isl_die(isl_map_get_ctx(map), isl_error_invalid,
   6729 			"expecting integer value", goto error);
   6730 	if (isl_map_check_range(map, type, pos, 1) < 0)
   6731 		goto error;
   6732 	for (i = map->n - 1; i >= 0; --i) {
   6733 		map->p[i] = isl_basic_map_fix_val(map->p[i], type, pos,
   6734 							isl_val_copy(v));
   6735 		map = remove_if_empty(map, i);
   6736 		if (!map)
   6737 			goto error;
   6738 	}
   6739 	map = isl_map_unmark_normalized(map);
   6740 	isl_val_free(v);
   6741 	return map;
   6742 error:
   6743 	isl_map_free(map);
   6744 	isl_val_free(v);
   6745 	return NULL;
   6746 }
   6747 
   6748 /* Fix the value of the variable at position "pos" of type "type" of "set"
   6749  * to be equal to "v".
   6750  */
   6751 __isl_give isl_set *isl_set_fix_val(__isl_take isl_set *set,
   6752 	enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
   6753 {
   6754 	return isl_map_fix_val(set, type, pos, v);
   6755 }
   6756 
   6757 __isl_give isl_map *isl_map_fix_input_si(__isl_take isl_map *map,
   6758 		unsigned input, int value)
   6759 {
   6760 	return isl_map_fix_si(map, isl_dim_in, input, value);
   6761 }
   6762 
   6763 __isl_give isl_set *isl_set_fix_dim_si(__isl_take isl_set *set, unsigned dim,
   6764 	int value)
   6765 {
   6766 	return set_from_map(isl_map_fix_si(set_to_map(set),
   6767 						isl_dim_set, dim, value));
   6768 }
   6769 
   6770 static __isl_give isl_basic_map *basic_map_bound_si(
   6771 	__isl_take isl_basic_map *bmap,
   6772 	enum isl_dim_type type, unsigned pos, int value, int upper)
   6773 {
   6774 	int j;
   6775 	isl_size total;
   6776 
   6777 	if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
   6778 		return isl_basic_map_free(bmap);
   6779 	total = isl_basic_map_dim(bmap, isl_dim_all);
   6780 	if (total < 0)
   6781 		return isl_basic_map_free(bmap);
   6782 	pos += isl_basic_map_offset(bmap, type);
   6783 	bmap = isl_basic_map_cow(bmap);
   6784 	bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
   6785 	j = isl_basic_map_alloc_inequality(bmap);
   6786 	if (j < 0)
   6787 		goto error;
   6788 	isl_seq_clr(bmap->ineq[j], 1 + total);
   6789 	if (upper) {
   6790 		isl_int_set_si(bmap->ineq[j][pos], -1);
   6791 		isl_int_set_si(bmap->ineq[j][0], value);
   6792 	} else {
   6793 		isl_int_set_si(bmap->ineq[j][pos], 1);
   6794 		isl_int_set_si(bmap->ineq[j][0], -value);
   6795 	}
   6796 	bmap = isl_basic_map_simplify(bmap);
   6797 	return isl_basic_map_finalize(bmap);
   6798 error:
   6799 	isl_basic_map_free(bmap);
   6800 	return NULL;
   6801 }
   6802 
   6803 __isl_give isl_basic_map *isl_basic_map_lower_bound_si(
   6804 	__isl_take isl_basic_map *bmap,
   6805 	enum isl_dim_type type, unsigned pos, int value)
   6806 {
   6807 	return basic_map_bound_si(bmap, type, pos, value, 0);
   6808 }
   6809 
   6810 /* Constrain the values of the given dimension to be no greater than "value".
   6811  */
   6812 __isl_give isl_basic_map *isl_basic_map_upper_bound_si(
   6813 	__isl_take isl_basic_map *bmap,
   6814 	enum isl_dim_type type, unsigned pos, int value)
   6815 {
   6816 	return basic_map_bound_si(bmap, type, pos, value, 1);
   6817 }
   6818 
   6819 static __isl_give isl_map *map_bound_si(__isl_take isl_map *map,
   6820 	enum isl_dim_type type, unsigned pos, int value, int upper)
   6821 {
   6822 	int i;
   6823 
   6824 	map = isl_map_cow(map);
   6825 	if (isl_map_check_range(map, type, pos, 1) < 0)
   6826 		return isl_map_free(map);
   6827 	for (i = 0; i < map->n; ++i) {
   6828 		map->p[i] = basic_map_bound_si(map->p[i],
   6829 						 type, pos, value, upper);
   6830 		if (!map->p[i])
   6831 			goto error;
   6832 	}
   6833 	map = isl_map_unmark_normalized(map);
   6834 	return map;
   6835 error:
   6836 	isl_map_free(map);
   6837 	return NULL;
   6838 }
   6839 
   6840 __isl_give isl_map *isl_map_lower_bound_si(__isl_take isl_map *map,
   6841 	enum isl_dim_type type, unsigned pos, int value)
   6842 {
   6843 	return map_bound_si(map, type, pos, value, 0);
   6844 }
   6845 
   6846 __isl_give isl_map *isl_map_upper_bound_si(__isl_take isl_map *map,
   6847 	enum isl_dim_type type, unsigned pos, int value)
   6848 {
   6849 	return map_bound_si(map, type, pos, value, 1);
   6850 }
   6851 
   6852 __isl_give isl_set *isl_set_lower_bound_si(__isl_take isl_set *set,
   6853 		enum isl_dim_type type, unsigned pos, int value)
   6854 {
   6855 	return set_from_map(isl_map_lower_bound_si(set_to_map(set),
   6856 							type, pos, value));
   6857 }
   6858 
   6859 __isl_give isl_set *isl_set_upper_bound_si(__isl_take isl_set *set,
   6860 	enum isl_dim_type type, unsigned pos, int value)
   6861 {
   6862 	return isl_map_upper_bound_si(set, type, pos, value);
   6863 }
   6864 
   6865 /* Bound the given variable of "bmap" from below (or above is "upper"
   6866  * is set) to "value".
   6867  */
   6868 static __isl_give isl_basic_map *basic_map_bound(
   6869 	__isl_take isl_basic_map *bmap,
   6870 	enum isl_dim_type type, unsigned pos, isl_int value, int upper)
   6871 {
   6872 	int j;
   6873 	isl_size total;
   6874 
   6875 	if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
   6876 		return isl_basic_map_free(bmap);
   6877 	total = isl_basic_map_dim(bmap, isl_dim_all);
   6878 	if (total < 0)
   6879 		return isl_basic_map_free(bmap);
   6880 	pos += isl_basic_map_offset(bmap, type);
   6881 	bmap = isl_basic_map_cow(bmap);
   6882 	bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
   6883 	j = isl_basic_map_alloc_inequality(bmap);
   6884 	if (j < 0)
   6885 		goto error;
   6886 	isl_seq_clr(bmap->ineq[j], 1 + total);
   6887 	if (upper) {
   6888 		isl_int_set_si(bmap->ineq[j][pos], -1);
   6889 		isl_int_set(bmap->ineq[j][0], value);
   6890 	} else {
   6891 		isl_int_set_si(bmap->ineq[j][pos], 1);
   6892 		isl_int_neg(bmap->ineq[j][0], value);
   6893 	}
   6894 	bmap = isl_basic_map_simplify(bmap);
   6895 	return isl_basic_map_finalize(bmap);
   6896 error:
   6897 	isl_basic_map_free(bmap);
   6898 	return NULL;
   6899 }
   6900 
   6901 /* Bound the given variable of "map" from below (or above is "upper"
   6902  * is set) to "value".
   6903  */
   6904 static __isl_give isl_map *map_bound(__isl_take isl_map *map,
   6905 	enum isl_dim_type type, unsigned pos, isl_int value, int upper)
   6906 {
   6907 	int i;
   6908 
   6909 	map = isl_map_cow(map);
   6910 	if (isl_map_check_range(map, type, pos, 1) < 0)
   6911 		return isl_map_free(map);
   6912 	for (i = map->n - 1; i >= 0; --i) {
   6913 		map->p[i] = basic_map_bound(map->p[i], type, pos, value, upper);
   6914 		map = remove_if_empty(map, i);
   6915 		if (!map)
   6916 			return NULL;
   6917 	}
   6918 	map = isl_map_unmark_normalized(map);
   6919 	return map;
   6920 }
   6921 
   6922 __isl_give isl_map *isl_map_lower_bound(__isl_take isl_map *map,
   6923 	enum isl_dim_type type, unsigned pos, isl_int value)
   6924 {
   6925 	return map_bound(map, type, pos, value, 0);
   6926 }
   6927 
   6928 __isl_give isl_map *isl_map_upper_bound(__isl_take isl_map *map,
   6929 	enum isl_dim_type type, unsigned pos, isl_int value)
   6930 {
   6931 	return map_bound(map, type, pos, value, 1);
   6932 }
   6933 
   6934 __isl_give isl_set *isl_set_lower_bound(__isl_take isl_set *set,
   6935 	enum isl_dim_type type, unsigned pos, isl_int value)
   6936 {
   6937 	return isl_map_lower_bound(set, type, pos, value);
   6938 }
   6939 
   6940 __isl_give isl_set *isl_set_upper_bound(__isl_take isl_set *set,
   6941 	enum isl_dim_type type, unsigned pos, isl_int value)
   6942 {
   6943 	return isl_map_upper_bound(set, type, pos, value);
   6944 }
   6945 
   6946 /* Force the values of the variable at position "pos" of type "type" of "map"
   6947  * to be no smaller than "value".
   6948  */
   6949 __isl_give isl_map *isl_map_lower_bound_val(__isl_take isl_map *map,
   6950 	enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
   6951 {
   6952 	if (!value)
   6953 		goto error;
   6954 	if (!isl_val_is_int(value))
   6955 		isl_die(isl_map_get_ctx(map), isl_error_invalid,
   6956 			"expecting integer value", goto error);
   6957 	map = isl_map_lower_bound(map, type, pos, value->n);
   6958 	isl_val_free(value);
   6959 	return map;
   6960 error:
   6961 	isl_val_free(value);
   6962 	isl_map_free(map);
   6963 	return NULL;
   6964 }
   6965 
   6966 /* Force the values of the variable at position "pos" of type "type" of "set"
   6967  * to be no smaller than "value".
   6968  */
   6969 __isl_give isl_set *isl_set_lower_bound_val(__isl_take isl_set *set,
   6970 	enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
   6971 {
   6972 	isl_map *map;
   6973 
   6974 	map = set_to_map(set);
   6975 	return set_from_map(isl_map_lower_bound_val(map, type, pos, value));
   6976 }
   6977 
   6978 /* Force the values of the variable at position "pos" of type "type" of "map"
   6979  * to be no greater than "value".
   6980  */
   6981 __isl_give isl_map *isl_map_upper_bound_val(__isl_take isl_map *map,
   6982 	enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
   6983 {
   6984 	if (!value)
   6985 		goto error;
   6986 	if (!isl_val_is_int(value))
   6987 		isl_die(isl_map_get_ctx(map), isl_error_invalid,
   6988 			"expecting integer value", goto error);
   6989 	map = isl_map_upper_bound(map, type, pos, value->n);
   6990 	isl_val_free(value);
   6991 	return map;
   6992 error:
   6993 	isl_val_free(value);
   6994 	isl_map_free(map);
   6995 	return NULL;
   6996 }
   6997 
   6998 /* Force the values of the variable at position "pos" of type "type" of "set"
   6999  * to be no greater than "value".
   7000  */
   7001 __isl_give isl_set *isl_set_upper_bound_val(__isl_take isl_set *set,
   7002 	enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
   7003 {
   7004 	isl_map *map;
   7005 
   7006 	map = set_to_map(set);
   7007 	return set_from_map(isl_map_upper_bound_val(map, type, pos, value));
   7008 }
   7009 
   7010 /* If "mv" has an explicit domain, then intersect the domain of "map"
   7011  * with this explicit domain.
   7012  *
   7013  * An isl_multi_val object never has an explicit domain,
   7014  * so simply return "map".
   7015  */
   7016 static __isl_give isl_map *isl_map_intersect_multi_val_explicit_domain(
   7017 	__isl_take isl_map *map, __isl_keep isl_multi_val *mv)
   7018 {
   7019 	return map;
   7020 }
   7021 
   7022 #undef BASE
   7023 #define BASE	val
   7024 #include "isl_map_bound_templ.c"
   7025 
   7026 /* Apply "map_bound" to "set" with the corresponding value in "bound"
   7027  * for each set dimension, by treating the set as a map.
   7028  */
   7029 static __isl_give isl_set *set_bound_multi_val(__isl_take isl_set *set,
   7030 	__isl_take isl_multi_val *bound,
   7031 	__isl_give isl_map *map_bound(__isl_take isl_map *map,
   7032 		unsigned pos, __isl_take isl_val *value))
   7033 {
   7034 	isl_map *map;
   7035 
   7036 	map = set_to_map(set);
   7037 	return set_from_map(map_bound_multi_val(map, bound, map_bound));
   7038 }
   7039 
   7040 #undef BASE
   7041 #define BASE	pw_aff
   7042 #include "isl_map_bound_templ.c"
   7043 
   7044 /* Apply "map_bound" to "set" with the corresponding value in "bound"
   7045  * for each set dimension, by converting the set and the bound
   7046  * to objects living in a map space.
   7047  */
   7048 static __isl_give isl_set *set_bound_multi_pw_aff(__isl_take isl_set *set,
   7049 	__isl_take isl_multi_pw_aff *bound,
   7050 	__isl_give isl_map *set_bound(__isl_take isl_map *map,
   7051 		unsigned pos, __isl_take TYPE *value))
   7052 {
   7053 	isl_map *map;
   7054 
   7055 	map = isl_map_from_range(set);
   7056 	bound = isl_multi_pw_aff_from_range(bound);
   7057 	map = map_bound_multi_pw_aff(map, bound, set_bound);
   7058 	return isl_map_range(map);
   7059 }
   7060 
   7061 /* Wrapper around isl_map_lower_bound_val for use in map_bound_multi_val,
   7062  * setting a bound on the given output dimension.
   7063  */
   7064 static __isl_give isl_map *map_lower_bound_val(__isl_take isl_map *map,
   7065 	unsigned pos, __isl_take isl_val *v)
   7066 {
   7067 	return isl_map_lower_bound_val(map, isl_dim_out, pos, v);
   7068 }
   7069 
   7070 /* Force the values of the set dimensions of "set"
   7071  * to be no smaller than the corresponding values in "lower".
   7072  */
   7073 __isl_give isl_set *isl_set_lower_bound_multi_val(__isl_take isl_set *set,
   7074 	__isl_take isl_multi_val *lower)
   7075 {
   7076 	return set_bound_multi_val(set, lower, &map_lower_bound_val);
   7077 }
   7078 
   7079 /* Wrapper around isl_map_upper_bound_val for use in map_bound_multi_val,
   7080  * setting a bound on the given output dimension.
   7081  */
   7082 static __isl_give isl_map *map_upper_bound_val(__isl_take isl_map *map,
   7083 	unsigned pos, __isl_take isl_val *v)
   7084 {
   7085 	return isl_map_upper_bound_val(map, isl_dim_out, pos, v);
   7086 }
   7087 
   7088 /* Force the values of the set dimensions of "set"
   7089  * to be no greater than the corresponding values in "upper".
   7090  */
   7091 __isl_give isl_set *isl_set_upper_bound_multi_val(__isl_take isl_set *set,
   7092 	__isl_take isl_multi_val *upper)
   7093 {
   7094 	return set_bound_multi_val(set, upper, &map_upper_bound_val);
   7095 }
   7096 
   7097 /* Force the symbolic constant expression "bound"
   7098  * to satisfy the relation "order" with respect to
   7099  * the output variable at position "pos" of "map".
   7100  *
   7101  * Create an affine expression representing the output variable
   7102  * in terms of the range and
   7103  * compare it using "order" to "bound" (defined on the domain).
   7104  * The result is a relation between elements in domain and range that
   7105  * can be intersected with "map".
   7106  */
   7107 static __isl_give isl_map *map_bound_pw_aff(__isl_take isl_map *map,
   7108 	unsigned pos, __isl_take isl_pw_aff *bound,
   7109 	__isl_give isl_map *(*order)(__isl_take isl_pw_aff *pa1,
   7110 		__isl_take isl_pw_aff *pa2))
   7111 {
   7112 	isl_space *space;
   7113 	isl_local_space *ls;
   7114 	isl_pw_aff *var;
   7115 
   7116 	space = isl_space_range(isl_map_get_space(map));
   7117 	ls = isl_local_space_from_space(space);
   7118 	var = isl_pw_aff_var_on_domain(ls, isl_dim_set, pos);
   7119 	map = isl_map_intersect(map, order(bound, var));
   7120 	return map;
   7121 }
   7122 
   7123 /* Force the values of the output variable at position "pos" of "map"
   7124  * to be no smaller than the symbolic constant expression "lower".
   7125  */
   7126 static __isl_give isl_map *map_lower_bound_pw_aff(__isl_take isl_map *map,
   7127 	unsigned pos, __isl_take isl_pw_aff *lower)
   7128 {
   7129 	return map_bound_pw_aff(map, pos, lower, &isl_pw_aff_le_map);
   7130 }
   7131 
   7132 /* Force the values of the output variable at position "pos" of "map"
   7133  * to be no greater than the symbolic constant expression "upper".
   7134  */
   7135 static __isl_give isl_map *map_upper_bound_pw_aff(__isl_take isl_map *map,
   7136 	unsigned pos, __isl_take isl_pw_aff *upper)
   7137 {
   7138 	return map_bound_pw_aff(map, pos, upper, &isl_pw_aff_ge_map);
   7139 }
   7140 
   7141 /* Force the values of the set dimensions of "set"
   7142  * to be no smaller than the corresponding constant symbolic expressions
   7143  * in "lower".
   7144  */
   7145 __isl_give isl_set *isl_set_lower_bound_multi_pw_aff(__isl_take isl_set *set,
   7146 	__isl_take isl_multi_pw_aff *lower)
   7147 {
   7148 	return set_bound_multi_pw_aff(set, lower, &map_lower_bound_pw_aff);
   7149 }
   7150 
   7151 /* Force the values of the set dimensions of "set"
   7152  * to be no greater than the corresponding constant symbolic expressions
   7153  * in "upper".
   7154  */
   7155 __isl_give isl_set *isl_set_upper_bound_multi_pw_aff(__isl_take isl_set *set,
   7156 	__isl_take isl_multi_pw_aff *upper)
   7157 {
   7158 	return set_bound_multi_pw_aff(set, upper, &map_upper_bound_pw_aff);
   7159 }
   7160 
   7161 /* Force the values of the output dimensions of "map"
   7162  * to be no smaller than the corresponding constant symbolic expressions
   7163  * in "lower".
   7164  */
   7165 __isl_give isl_map *isl_map_lower_bound_multi_pw_aff(__isl_take isl_map *map,
   7166 	__isl_take isl_multi_pw_aff *lower)
   7167 {
   7168 	return map_bound_multi_pw_aff(map, lower, &map_lower_bound_pw_aff);
   7169 }
   7170 
   7171 /* Force the values of the output dimensions of "map"
   7172  * to be no greater than the corresponding constant symbolic expressions
   7173  * in "upper".
   7174  */
   7175 __isl_give isl_map *isl_map_upper_bound_multi_pw_aff(__isl_take isl_map *map,
   7176 	__isl_take isl_multi_pw_aff *upper)
   7177 {
   7178 	return map_bound_multi_pw_aff(map, upper, &map_upper_bound_pw_aff);
   7179 }
   7180 
   7181 /* Bound the given variable of "bset" from below (or above is "upper"
   7182  * is set) to "value".
   7183  */
   7184 static __isl_give isl_basic_set *isl_basic_set_bound(
   7185 	__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
   7186 	isl_int value, int upper)
   7187 {
   7188 	return bset_from_bmap(basic_map_bound(bset_to_bmap(bset),
   7189 						type, pos, value, upper));
   7190 }
   7191 
   7192 /* Bound the given variable of "bset" from below (or above is "upper"
   7193  * is set) to "value".
   7194  */
   7195 static __isl_give isl_basic_set *isl_basic_set_bound_val(
   7196 	__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
   7197 	__isl_take isl_val *value, int upper)
   7198 {
   7199 	if (!value)
   7200 		goto error;
   7201 	if (!isl_val_is_int(value))
   7202 		isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,
   7203 			"expecting integer value", goto error);
   7204 	bset = isl_basic_set_bound(bset, type, pos, value->n, upper);
   7205 	isl_val_free(value);
   7206 	return bset;
   7207 error:
   7208 	isl_val_free(value);
   7209 	isl_basic_set_free(bset);
   7210 	return NULL;
   7211 }
   7212 
   7213 /* Bound the given variable of "bset" from below to "value".
   7214  */
   7215 __isl_give isl_basic_set *isl_basic_set_lower_bound_val(
   7216 	__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
   7217 	__isl_take isl_val *value)
   7218 {
   7219 	return isl_basic_set_bound_val(bset, type, pos, value, 0);
   7220 }
   7221 
   7222 /* Bound the given variable of "bset" from above to "value".
   7223  */
   7224 __isl_give isl_basic_set *isl_basic_set_upper_bound_val(
   7225 	__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
   7226 	__isl_take isl_val *value)
   7227 {
   7228 	return isl_basic_set_bound_val(bset, type, pos, value, 1);
   7229 }
   7230 
   7231 __isl_give isl_map *isl_map_reverse(__isl_take isl_map *map)
   7232 {
   7233 	return isl_map_transform(map, &isl_space_reverse,
   7234 					&isl_basic_map_reverse);
   7235 }
   7236 
   7237 /* Given a map (A -> B) -> C, return the corresponding map (B -> A) -> C.
   7238  */
   7239 __isl_give isl_map *isl_map_domain_reverse(__isl_take isl_map *map)
   7240 {
   7241 	return isl_map_transform(map, &isl_space_domain_reverse,
   7242 					&isl_basic_map_domain_reverse);
   7243 }
   7244 
   7245 /* Given a map A -> (B -> C), return the corresponding map A -> (C -> B).
   7246  */
   7247 __isl_give isl_map *isl_map_range_reverse(__isl_take isl_map *map)
   7248 {
   7249 	return isl_map_transform(map, &isl_space_range_reverse,
   7250 					&isl_basic_map_range_reverse);
   7251 }
   7252 
   7253 /* Given a set (A -> B), return the corresponding set (B -> A).
   7254  */
   7255 __isl_give isl_set *isl_set_wrapped_reverse(__isl_take isl_set *set)
   7256 {
   7257 	isl_map *map = set_to_map(set);
   7258 
   7259 	map = isl_map_transform(map, &isl_space_wrapped_reverse,
   7260 					&isl_basic_map_set_reverse);
   7261 	return set_from_map(map);
   7262 }
   7263 
   7264 #undef TYPE
   7265 #define TYPE	isl_pw_multi_aff
   7266 #undef SUFFIX
   7267 #define SUFFIX	_pw_multi_aff
   7268 #undef EMPTY
   7269 #define EMPTY	isl_pw_multi_aff_empty
   7270 #undef ADD
   7271 #define ADD	isl_pw_multi_aff_union_add
   7272 #include "isl_map_lexopt_templ.c"
   7273 
   7274 /* Given a map "map", compute the lexicographically minimal
   7275  * (or maximal) image element for each domain element in dom,
   7276  * in the form of an isl_pw_multi_aff.
   7277  * If "empty" is not NULL, then set *empty to those elements in dom that
   7278  * do not have an image element.
   7279  * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
   7280  * should be computed over the domain of "map".  "empty" is also NULL
   7281  * in this case.
   7282  *
   7283  * We first compute the lexicographically minimal or maximal element
   7284  * in the first basic map.  This results in a partial solution "res"
   7285  * and a subset "todo" of dom that still need to be handled.
   7286  * We then consider each of the remaining maps in "map" and successively
   7287  * update both "res" and "todo".
   7288  * If "empty" is NULL, then the todo sets are not needed and therefore
   7289  * also not computed.
   7290  */
   7291 static __isl_give isl_pw_multi_aff *isl_map_partial_lexopt_aligned_pw_multi_aff(
   7292 	__isl_take isl_map *map, __isl_take isl_set *dom,
   7293 	__isl_give isl_set **empty, unsigned flags)
   7294 {
   7295 	int i;
   7296 	int full;
   7297 	isl_pw_multi_aff *res;
   7298 	isl_set *todo;
   7299 
   7300 	full = ISL_FL_ISSET(flags, ISL_OPT_FULL);
   7301 	if (!map || (!full && !dom))
   7302 		goto error;
   7303 
   7304 	if (isl_map_plain_is_empty(map)) {
   7305 		if (empty)
   7306 			*empty = dom;
   7307 		else
   7308 			isl_set_free(dom);
   7309 		return isl_pw_multi_aff_from_map(map);
   7310 	}
   7311 
   7312 	res = basic_map_partial_lexopt_pw_multi_aff(
   7313 					    isl_basic_map_copy(map->p[0]),
   7314 					    isl_set_copy(dom), empty, flags);
   7315 
   7316 	if (empty)
   7317 		todo = *empty;
   7318 	for (i = 1; i < map->n; ++i) {
   7319 		isl_pw_multi_aff *res_i;
   7320 
   7321 		res_i = basic_map_partial_lexopt_pw_multi_aff(
   7322 					    isl_basic_map_copy(map->p[i]),
   7323 					    isl_set_copy(dom), empty, flags);
   7324 
   7325 		if (ISL_FL_ISSET(flags, ISL_OPT_MAX))
   7326 			res = isl_pw_multi_aff_union_lexmax(res, res_i);
   7327 		else
   7328 			res = isl_pw_multi_aff_union_lexmin(res, res_i);
   7329 
   7330 		if (empty)
   7331 			todo = isl_set_intersect(todo, *empty);
   7332 	}
   7333 
   7334 	isl_set_free(dom);
   7335 	isl_map_free(map);
   7336 
   7337 	if (empty)
   7338 		*empty = todo;
   7339 
   7340 	return res;
   7341 error:
   7342 	if (empty)
   7343 		*empty = NULL;
   7344 	isl_set_free(dom);
   7345 	isl_map_free(map);
   7346 	return NULL;
   7347 }
   7348 
   7349 #undef TYPE
   7350 #define TYPE	isl_map
   7351 #undef SUFFIX
   7352 #define SUFFIX
   7353 #undef EMPTY
   7354 #define EMPTY	isl_map_empty
   7355 #undef ADD
   7356 #define ADD	isl_map_union_disjoint
   7357 #include "isl_map_lexopt_templ.c"
   7358 
   7359 /* Given a map "map", compute the lexicographically minimal
   7360  * (or maximal) image element for each domain element in "dom",
   7361  * in the form of an isl_map.
   7362  * If "empty" is not NULL, then set *empty to those elements in "dom" that
   7363  * do not have an image element.
   7364  * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
   7365  * should be computed over the domain of "map".  "empty" is also NULL
   7366  * in this case.
   7367  *
   7368  * If the input consists of more than one disjunct, then first
   7369  * compute the desired result in the form of an isl_pw_multi_aff and
   7370  * then convert that into an isl_map.
   7371  *
   7372  * This function used to have an explicit implementation in terms
   7373  * of isl_maps, but it would continually intersect the domains of
   7374  * partial results with the complement of the domain of the next
   7375  * partial solution, potentially leading to an explosion in the number
   7376  * of disjuncts if there are several disjuncts in the input.
   7377  * An even earlier implementation of this function would look for
   7378  * better results in the domain of the partial result and for extra
   7379  * results in the complement of this domain, which would lead to
   7380  * even more splintering.
   7381  */
   7382 static __isl_give isl_map *isl_map_partial_lexopt_aligned(
   7383 	__isl_take isl_map *map, __isl_take isl_set *dom,
   7384 	__isl_give isl_set **empty, unsigned flags)
   7385 {
   7386 	int full;
   7387 	struct isl_map *res;
   7388 	isl_pw_multi_aff *pma;
   7389 
   7390 	full = ISL_FL_ISSET(flags, ISL_OPT_FULL);
   7391 	if (!map || (!full && !dom))
   7392 		goto error;
   7393 
   7394 	if (isl_map_plain_is_empty(map)) {
   7395 		if (empty)
   7396 			*empty = dom;
   7397 		else
   7398 			isl_set_free(dom);
   7399 		return map;
   7400 	}
   7401 
   7402 	if (map->n == 1) {
   7403 		res = basic_map_partial_lexopt(isl_basic_map_copy(map->p[0]),
   7404 						dom, empty, flags);
   7405 		isl_map_free(map);
   7406 		return res;
   7407 	}
   7408 
   7409 	pma = isl_map_partial_lexopt_aligned_pw_multi_aff(map, dom, empty,
   7410 							flags);
   7411 	return isl_map_from_pw_multi_aff_internal(pma);
   7412 error:
   7413 	if (empty)
   7414 		*empty = NULL;
   7415 	isl_set_free(dom);
   7416 	isl_map_free(map);
   7417 	return NULL;
   7418 }
   7419 
   7420 __isl_give isl_map *isl_map_partial_lexmax(
   7421 		__isl_take isl_map *map, __isl_take isl_set *dom,
   7422 		__isl_give isl_set **empty)
   7423 {
   7424 	return isl_map_partial_lexopt(map, dom, empty, ISL_OPT_MAX);
   7425 }
   7426 
   7427 __isl_give isl_map *isl_map_partial_lexmin(
   7428 		__isl_take isl_map *map, __isl_take isl_set *dom,
   7429 		__isl_give isl_set **empty)
   7430 {
   7431 	return isl_map_partial_lexopt(map, dom, empty, 0);
   7432 }
   7433 
   7434 __isl_give isl_set *isl_set_partial_lexmin(
   7435 		__isl_take isl_set *set, __isl_take isl_set *dom,
   7436 		__isl_give isl_set **empty)
   7437 {
   7438 	return set_from_map(isl_map_partial_lexmin(set_to_map(set),
   7439 						    dom, empty));
   7440 }
   7441 
   7442 __isl_give isl_set *isl_set_partial_lexmax(
   7443 		__isl_take isl_set *set, __isl_take isl_set *dom,
   7444 		__isl_give isl_set **empty)
   7445 {
   7446 	return set_from_map(isl_map_partial_lexmax(set_to_map(set),
   7447 						    dom, empty));
   7448 }
   7449 
   7450 /* Compute the lexicographic minimum (or maximum if "flags" includes
   7451  * ISL_OPT_MAX) of "bset" over its parametric domain.
   7452  */
   7453 __isl_give isl_set *isl_basic_set_lexopt(__isl_take isl_basic_set *bset,
   7454 	unsigned flags)
   7455 {
   7456 	return isl_basic_map_lexopt(bset, flags);
   7457 }
   7458 
   7459 __isl_give isl_map *isl_basic_map_lexmax(__isl_take isl_basic_map *bmap)
   7460 {
   7461 	return isl_basic_map_lexopt(bmap, ISL_OPT_MAX);
   7462 }
   7463 
   7464 __isl_give isl_set *isl_basic_set_lexmin(__isl_take isl_basic_set *bset)
   7465 {
   7466 	return set_from_map(isl_basic_map_lexmin(bset_to_bmap(bset)));
   7467 }
   7468 
   7469 __isl_give isl_set *isl_basic_set_lexmax(__isl_take isl_basic_set *bset)
   7470 {
   7471 	return set_from_map(isl_basic_map_lexmax(bset_to_bmap(bset)));
   7472 }
   7473 
   7474 /* Compute the lexicographic minimum of "bset" over its parametric domain
   7475  * for the purpose of quantifier elimination.
   7476  * That is, find an explicit representation for all the existentially
   7477  * quantified variables in "bset" by computing their lexicographic
   7478  * minimum.
   7479  */
   7480 static __isl_give isl_set *isl_basic_set_lexmin_compute_divs(
   7481 	__isl_take isl_basic_set *bset)
   7482 {
   7483 	return isl_basic_set_lexopt(bset, ISL_OPT_QE);
   7484 }
   7485 
   7486 /* Given a basic map with one output dimension, compute the minimum or
   7487  * maximum of that dimension as an isl_pw_aff.
   7488  *
   7489  * Compute the optimum as a lexicographic optimum over the single
   7490  * output dimension and extract the single isl_pw_aff from the result.
   7491  */
   7492 static __isl_give isl_pw_aff *basic_map_dim_opt(__isl_keep isl_basic_map *bmap,
   7493 	int max)
   7494 {
   7495 	isl_pw_multi_aff *pma;
   7496 	isl_pw_aff *pwaff;
   7497 
   7498 	bmap = isl_basic_map_copy(bmap);
   7499 	pma = isl_basic_map_lexopt_pw_multi_aff(bmap, max ? ISL_OPT_MAX : 0);
   7500 	pwaff = isl_pw_multi_aff_get_pw_aff(pma, 0);
   7501 	isl_pw_multi_aff_free(pma);
   7502 
   7503 	return pwaff;
   7504 }
   7505 
   7506 /* Compute the minimum or maximum of the given output dimension
   7507  * as a function of the parameters and the input dimensions,
   7508  * but independently of the other output dimensions.
   7509  *
   7510  * We first project out the other output dimension and then compute
   7511  * the "lexicographic" maximum in each basic map, combining the results
   7512  * using isl_pw_aff_union_max.
   7513  */
   7514 static __isl_give isl_pw_aff *map_dim_opt(__isl_take isl_map *map, int pos,
   7515 	int max)
   7516 {
   7517 	int i;
   7518 	isl_pw_aff *pwaff;
   7519 	isl_size n_out;
   7520 
   7521 	n_out = isl_map_dim(map, isl_dim_out);
   7522 	if (n_out < 0)
   7523 		map = isl_map_free(map);
   7524 	map = isl_map_project_out(map, isl_dim_out, pos + 1, n_out - (pos + 1));
   7525 	map = isl_map_project_out(map, isl_dim_out, 0, pos);
   7526 	if (!map)
   7527 		return NULL;
   7528 
   7529 	if (map->n == 0) {
   7530 		isl_space *space = isl_map_get_space(map);
   7531 		isl_map_free(map);
   7532 		return isl_pw_aff_empty(space);
   7533 	}
   7534 
   7535 	pwaff = basic_map_dim_opt(map->p[0], max);
   7536 	for (i = 1; i < map->n; ++i) {
   7537 		isl_pw_aff *pwaff_i;
   7538 
   7539 		pwaff_i = basic_map_dim_opt(map->p[i], max);
   7540 		pwaff = isl_pw_aff_union_opt(pwaff, pwaff_i, max);
   7541 	}
   7542 
   7543 	isl_map_free(map);
   7544 
   7545 	return pwaff;
   7546 }
   7547 
   7548 /* Compute the minimum of the given output dimension as a function of the
   7549  * parameters and input dimensions, but independently of
   7550  * the other output dimensions.
   7551  */
   7552 __isl_give isl_pw_aff *isl_map_dim_min(__isl_take isl_map *map, int pos)
   7553 {
   7554 	return map_dim_opt(map, pos, 0);
   7555 }
   7556 
   7557 /* Compute the maximum of the given output dimension as a function of the
   7558  * parameters and input dimensions, but independently of
   7559  * the other output dimensions.
   7560  */
   7561 __isl_give isl_pw_aff *isl_map_dim_max(__isl_take isl_map *map, int pos)
   7562 {
   7563 	return map_dim_opt(map, pos, 1);
   7564 }
   7565 
   7566 /* Compute the minimum or maximum of the given set dimension
   7567  * as a function of the parameters,
   7568  * but independently of the other set dimensions.
   7569  */
   7570 static __isl_give isl_pw_aff *set_dim_opt(__isl_take isl_set *set, int pos,
   7571 	int max)
   7572 {
   7573 	return map_dim_opt(set, pos, max);
   7574 }
   7575 
   7576 /* Compute the maximum of the given set dimension as a function of the
   7577  * parameters, but independently of the other set dimensions.
   7578  */
   7579 __isl_give isl_pw_aff *isl_set_dim_max(__isl_take isl_set *set, int pos)
   7580 {
   7581 	return set_dim_opt(set, pos, 1);
   7582 }
   7583 
   7584 /* Compute the minimum of the given set dimension as a function of the
   7585  * parameters, but independently of the other set dimensions.
   7586  */
   7587 __isl_give isl_pw_aff *isl_set_dim_min(__isl_take isl_set *set, int pos)
   7588 {
   7589 	return set_dim_opt(set, pos, 0);
   7590 }
   7591 
   7592 /* Apply a preimage specified by "mat" on the parameters of "bset".
   7593  * bset is assumed to have only parameters and divs.
   7594  */
   7595 static __isl_give isl_basic_set *basic_set_parameter_preimage(
   7596 	__isl_take isl_basic_set *bset, __isl_take isl_mat *mat)
   7597 {
   7598 	isl_size nparam;
   7599 
   7600 	nparam = isl_basic_set_dim(bset, isl_dim_param);
   7601 	if (nparam < 0 || !mat)
   7602 		goto error;
   7603 
   7604 	bset->dim = isl_space_cow(bset->dim);
   7605 	if (!bset->dim)
   7606 		goto error;
   7607 
   7608 	isl_assert(bset->ctx, mat->n_row == 1 + nparam, goto error);
   7609 
   7610 	bset->dim->nparam = 0;
   7611 	bset->dim->n_out = nparam;
   7612 	bset = isl_basic_set_preimage(bset, mat);
   7613 	if (bset) {
   7614 		bset->dim->nparam = bset->dim->n_out;
   7615 		bset->dim->n_out = 0;
   7616 	}
   7617 	return bset;
   7618 error:
   7619 	isl_mat_free(mat);
   7620 	isl_basic_set_free(bset);
   7621 	return NULL;
   7622 }
   7623 
   7624 /* Apply a preimage specified by "mat" on the parameters of "set".
   7625  * set is assumed to have only parameters and divs.
   7626  */
   7627 static __isl_give isl_set *set_parameter_preimage(__isl_take isl_set *set,
   7628 	__isl_take isl_mat *mat)
   7629 {
   7630 	isl_space *space;
   7631 	isl_size nparam;
   7632 
   7633 	nparam = isl_set_dim(set, isl_dim_param);
   7634 	if (nparam < 0 || !mat)
   7635 		goto error;
   7636 
   7637 	if (mat->n_row != 1 + nparam)
   7638 		isl_die(isl_set_get_ctx(set), isl_error_internal,
   7639 			"unexpected number of rows", goto error);
   7640 
   7641 	space = isl_set_get_space(set);
   7642 	space = isl_space_move_dims(space, isl_dim_set, 0,
   7643 				    isl_dim_param, 0, nparam);
   7644 	set = isl_set_reset_space(set, space);
   7645 	set = isl_set_preimage(set, mat);
   7646 	nparam = isl_set_dim(set, isl_dim_out);
   7647 	if (nparam < 0)
   7648 		set = isl_set_free(set);
   7649 	space = isl_set_get_space(set);
   7650 	space = isl_space_move_dims(space, isl_dim_param, 0,
   7651 				    isl_dim_out, 0, nparam);
   7652 	set = isl_set_reset_space(set, space);
   7653 	return set;
   7654 error:
   7655 	isl_mat_free(mat);
   7656 	isl_set_free(set);
   7657 	return NULL;
   7658 }
   7659 
   7660 /* Intersect the basic set "bset" with the affine space specified by the
   7661  * equalities in "eq".
   7662  */
   7663 static __isl_give isl_basic_set *basic_set_append_equalities(
   7664 	__isl_take isl_basic_set *bset, __isl_take isl_mat *eq)
   7665 {
   7666 	int i, k;
   7667 	unsigned len;
   7668 
   7669 	if (!bset || !eq)
   7670 		goto error;
   7671 
   7672 	bset = isl_basic_set_extend(bset, 0, eq->n_row, 0);
   7673 	if (!bset)
   7674 		goto error;
   7675 
   7676 	len = isl_basic_set_offset(bset, isl_dim_div) + bset->extra;
   7677 	for (i = 0; i < eq->n_row; ++i) {
   7678 		k = isl_basic_set_alloc_equality(bset);
   7679 		if (k < 0)
   7680 			goto error;
   7681 		isl_seq_cpy(bset->eq[k], eq->row[i], eq->n_col);
   7682 		isl_seq_clr(bset->eq[k] + eq->n_col, len - eq->n_col);
   7683 	}
   7684 	isl_mat_free(eq);
   7685 
   7686 	bset = isl_basic_set_gauss(bset, NULL);
   7687 	bset = isl_basic_set_finalize(bset);
   7688 
   7689 	return bset;
   7690 error:
   7691 	isl_mat_free(eq);
   7692 	isl_basic_set_free(bset);
   7693 	return NULL;
   7694 }
   7695 
   7696 /* Intersect the set "set" with the affine space specified by the
   7697  * equalities in "eq".
   7698  */
   7699 static __isl_give isl_set *set_append_equalities(__isl_take isl_set *set,
   7700 	__isl_take isl_mat *eq)
   7701 {
   7702 	int i;
   7703 
   7704 	if (!set || !eq)
   7705 		goto error;
   7706 
   7707 	for (i = 0; i < set->n; ++i) {
   7708 		set->p[i] = basic_set_append_equalities(set->p[i],
   7709 					isl_mat_copy(eq));
   7710 		if (!set->p[i])
   7711 			goto error;
   7712 	}
   7713 	isl_mat_free(eq);
   7714 	return set;
   7715 error:
   7716 	isl_mat_free(eq);
   7717 	isl_set_free(set);
   7718 	return NULL;
   7719 }
   7720 
   7721 /* Given a basic set "bset" that only involves parameters and existentially
   7722  * quantified variables, return the index of the first equality
   7723  * that only involves parameters.  If there is no such equality then
   7724  * return bset->n_eq.
   7725  *
   7726  * This function assumes that isl_basic_set_gauss has been called on "bset".
   7727  */
   7728 static int first_parameter_equality(__isl_keep isl_basic_set *bset)
   7729 {
   7730 	int i, j;
   7731 	isl_size nparam, n_div;
   7732 
   7733 	nparam = isl_basic_set_dim(bset, isl_dim_param);
   7734 	n_div = isl_basic_set_dim(bset, isl_dim_div);
   7735 	if (nparam < 0 || n_div < 0)
   7736 		return -1;
   7737 
   7738 	for (i = 0, j = n_div - 1; i < bset->n_eq && j >= 0; --j) {
   7739 		if (!isl_int_is_zero(bset->eq[i][1 + nparam + j]))
   7740 			++i;
   7741 	}
   7742 
   7743 	return i;
   7744 }
   7745 
   7746 /* Compute an explicit representation for the existentially quantified
   7747  * variables in "bset" by computing the "minimal value" of the set
   7748  * variables.  Since there are no set variables, the computation of
   7749  * the minimal value essentially computes an explicit representation
   7750  * of the non-empty part(s) of "bset".
   7751  *
   7752  * The input only involves parameters and existentially quantified variables.
   7753  * All equalities among parameters have been removed.
   7754  *
   7755  * Since the existentially quantified variables in the result are in general
   7756  * going to be different from those in the input, we first replace
   7757  * them by the minimal number of variables based on their equalities.
   7758  * This should simplify the parametric integer programming.
   7759  */
   7760 static __isl_give isl_set *base_compute_divs(__isl_take isl_basic_set *bset)
   7761 {
   7762 	isl_morph *morph1, *morph2;
   7763 	isl_set *set;
   7764 	isl_size n;
   7765 
   7766 	if (!bset)
   7767 		return NULL;
   7768 	if (bset->n_eq == 0)
   7769 		return isl_basic_set_lexmin_compute_divs(bset);
   7770 
   7771 	morph1 = isl_basic_set_parameter_compression(bset);
   7772 	bset = isl_morph_basic_set(isl_morph_copy(morph1), bset);
   7773 	bset = isl_basic_set_lift(bset);
   7774 	morph2 = isl_basic_set_variable_compression(bset, isl_dim_set);
   7775 	bset = isl_morph_basic_set(morph2, bset);
   7776 	n = isl_basic_set_dim(bset, isl_dim_set);
   7777 	if (n < 0)
   7778 		bset = isl_basic_set_free(bset);
   7779 	bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n);
   7780 
   7781 	set = isl_basic_set_lexmin_compute_divs(bset);
   7782 
   7783 	set = isl_morph_set(isl_morph_inverse(morph1), set);
   7784 
   7785 	return set;
   7786 }
   7787 
   7788 /* Project the given basic set onto its parameter domain, possibly introducing
   7789  * new, explicit, existential variables in the constraints.
   7790  * The input has parameters and (possibly implicit) existential variables.
   7791  * The output has the same parameters, but only
   7792  * explicit existentially quantified variables.
   7793  *
   7794  * The actual projection is performed by pip, but pip doesn't seem
   7795  * to like equalities very much, so we first remove the equalities
   7796  * among the parameters by performing a variable compression on
   7797  * the parameters.  Afterward, an inverse transformation is performed
   7798  * and the equalities among the parameters are inserted back in.
   7799  *
   7800  * The variable compression on the parameters may uncover additional
   7801  * equalities that were only implicit before.  We therefore check
   7802  * if there are any new parameter equalities in the result and
   7803  * if so recurse.  The removal of parameter equalities is required
   7804  * for the parameter compression performed by base_compute_divs.
   7805  */
   7806 static __isl_give isl_set *parameter_compute_divs(
   7807 	__isl_take isl_basic_set *bset)
   7808 {
   7809 	int i;
   7810 	struct isl_mat *eq;
   7811 	struct isl_mat *T, *T2;
   7812 	struct isl_set *set;
   7813 	isl_size nparam;
   7814 
   7815 	bset = isl_basic_set_cow(bset);
   7816 	if (!bset)
   7817 		return NULL;
   7818 
   7819 	if (bset->n_eq == 0)
   7820 		return base_compute_divs(bset);
   7821 
   7822 	bset = isl_basic_set_gauss(bset, NULL);
   7823 	if (!bset)
   7824 		return NULL;
   7825 	if (isl_basic_set_plain_is_empty(bset))
   7826 		return isl_set_from_basic_set(bset);
   7827 
   7828 	i = first_parameter_equality(bset);
   7829 	if (i == bset->n_eq)
   7830 		return base_compute_divs(bset);
   7831 
   7832 	nparam = isl_basic_set_dim(bset, isl_dim_param);
   7833 	if (nparam < 0)
   7834 		return isl_set_from_basic_set(isl_basic_set_free(bset));
   7835 	eq = isl_mat_sub_alloc6(bset->ctx, bset->eq, i, bset->n_eq - i,
   7836 		0, 1 + nparam);
   7837 	eq = isl_mat_cow(eq);
   7838 	T = isl_mat_variable_compression(isl_mat_copy(eq), &T2);
   7839 	if (T && T->n_col == 0) {
   7840 		isl_mat_free(T);
   7841 		isl_mat_free(T2);
   7842 		isl_mat_free(eq);
   7843 		bset = isl_basic_set_set_to_empty(bset);
   7844 		return isl_set_from_basic_set(bset);
   7845 	}
   7846 	bset = basic_set_parameter_preimage(bset, T);
   7847 
   7848 	i = first_parameter_equality(bset);
   7849 	if (!bset)
   7850 		set = NULL;
   7851 	else if (i == bset->n_eq)
   7852 		set = base_compute_divs(bset);
   7853 	else
   7854 		set = parameter_compute_divs(bset);
   7855 	set = set_parameter_preimage(set, T2);
   7856 	set = set_append_equalities(set, eq);
   7857 	return set;
   7858 }
   7859 
   7860 /* Insert the divs from "ls" before those of "bmap".
   7861  *
   7862  * The number of columns is not changed, which means that the last
   7863  * dimensions of "bmap" are being reintepreted as the divs from "ls".
   7864  * The caller is responsible for removing the same number of dimensions
   7865  * from the space of "bmap".
   7866  */
   7867 static __isl_give isl_basic_map *insert_divs_from_local_space(
   7868 	__isl_take isl_basic_map *bmap, __isl_keep isl_local_space *ls)
   7869 {
   7870 	int i;
   7871 	isl_size n_div;
   7872 	int old_n_div;
   7873 
   7874 	n_div = isl_local_space_dim(ls, isl_dim_div);
   7875 	if (n_div < 0)
   7876 		return isl_basic_map_free(bmap);
   7877 	if (n_div == 0)
   7878 		return bmap;
   7879 
   7880 	old_n_div = bmap->n_div;
   7881 	bmap = insert_div_rows(bmap, n_div);
   7882 	if (!bmap)
   7883 		return NULL;
   7884 
   7885 	for (i = 0; i < n_div; ++i) {
   7886 		isl_seq_cpy(bmap->div[i], ls->div->row[i], ls->div->n_col);
   7887 		isl_seq_clr(bmap->div[i] + ls->div->n_col, old_n_div);
   7888 	}
   7889 
   7890 	return bmap;
   7891 }
   7892 
   7893 /* Replace the space of "bmap" by the space and divs of "ls".
   7894  *
   7895  * If "ls" has any divs, then we simplify the result since we may
   7896  * have discovered some additional equalities that could simplify
   7897  * the div expressions.
   7898  */
   7899 static __isl_give isl_basic_map *basic_replace_space_by_local_space(
   7900 	__isl_take isl_basic_map *bmap, __isl_take isl_local_space *ls)
   7901 {
   7902 	isl_size n_div;
   7903 
   7904 	bmap = isl_basic_map_cow(bmap);
   7905 	n_div = isl_local_space_dim(ls, isl_dim_div);
   7906 	if (!bmap || n_div < 0)
   7907 		goto error;
   7908 
   7909 	bmap = insert_divs_from_local_space(bmap, ls);
   7910 	if (!bmap)
   7911 		goto error;
   7912 
   7913 	isl_space_free(bmap->dim);
   7914 	bmap->dim = isl_local_space_get_space(ls);
   7915 	if (!bmap->dim)
   7916 		goto error;
   7917 
   7918 	isl_local_space_free(ls);
   7919 	if (n_div > 0)
   7920 		bmap = isl_basic_map_simplify(bmap);
   7921 	bmap = isl_basic_map_finalize(bmap);
   7922 	return bmap;
   7923 error:
   7924 	isl_basic_map_free(bmap);
   7925 	isl_local_space_free(ls);
   7926 	return NULL;
   7927 }
   7928 
   7929 /* Replace the space of "map" by the space and divs of "ls".
   7930  */
   7931 static __isl_give isl_map *replace_space_by_local_space(__isl_take isl_map *map,
   7932 	__isl_take isl_local_space *ls)
   7933 {
   7934 	int i;
   7935 
   7936 	map = isl_map_cow(map);
   7937 	if (!map || !ls)
   7938 		goto error;
   7939 
   7940 	for (i = 0; i < map->n; ++i) {
   7941 		map->p[i] = basic_replace_space_by_local_space(map->p[i],
   7942 						    isl_local_space_copy(ls));
   7943 		if (!map->p[i])
   7944 			goto error;
   7945 	}
   7946 	isl_space_free(isl_map_take_space(map));
   7947 	map = isl_map_restore_space(map, isl_local_space_get_space(ls));
   7948 
   7949 	isl_local_space_free(ls);
   7950 	return map;
   7951 error:
   7952 	isl_local_space_free(ls);
   7953 	isl_map_free(map);
   7954 	return NULL;
   7955 }
   7956 
   7957 /* Compute an explicit representation for the existentially
   7958  * quantified variables for which do not know any explicit representation yet.
   7959  *
   7960  * We first sort the existentially quantified variables so that the
   7961  * existentially quantified variables for which we already have an explicit
   7962  * representation are placed before those for which we do not.
   7963  * The input dimensions, the output dimensions and the existentially
   7964  * quantified variables for which we already have an explicit
   7965  * representation are then turned into parameters.
   7966  * compute_divs returns a map with the same parameters and
   7967  * no input or output dimensions and the dimension specification
   7968  * is reset to that of the input, including the existentially quantified
   7969  * variables for which we already had an explicit representation.
   7970  */
   7971 static __isl_give isl_map *compute_divs(__isl_take isl_basic_map *bmap)
   7972 {
   7973 	struct isl_basic_set *bset;
   7974 	struct isl_set *set;
   7975 	struct isl_map *map;
   7976 	isl_space *space;
   7977 	isl_local_space *ls;
   7978 	isl_size nparam;
   7979 	isl_size n_in;
   7980 	isl_size n_out;
   7981 	int n_known;
   7982 	int i;
   7983 
   7984 	bmap = isl_basic_map_sort_divs(bmap);
   7985 	bmap = isl_basic_map_cow(bmap);
   7986 	if (!bmap)
   7987 		return NULL;
   7988 
   7989 	n_known = isl_basic_map_first_unknown_div(bmap);
   7990 	nparam = isl_basic_map_dim(bmap, isl_dim_param);
   7991 	n_in = isl_basic_map_dim(bmap, isl_dim_in);
   7992 	n_out = isl_basic_map_dim(bmap, isl_dim_out);
   7993 	if (n_known < 0 || nparam < 0 || n_in < 0 || n_out < 0)
   7994 		return isl_map_from_basic_map(isl_basic_map_free(bmap));
   7995 
   7996 	space = isl_space_set_alloc(bmap->ctx,
   7997 				    nparam + n_in + n_out + n_known, 0);
   7998 	if (!space)
   7999 		goto error;
   8000 
   8001 	ls = isl_basic_map_get_local_space(bmap);
   8002 	ls = isl_local_space_drop_dims(ls, isl_dim_div,
   8003 					n_known, bmap->n_div - n_known);
   8004 	if (n_known > 0) {
   8005 		for (i = n_known; i < bmap->n_div; ++i)
   8006 			swap_div(bmap, i - n_known, i);
   8007 		bmap->n_div -= n_known;
   8008 		bmap->extra -= n_known;
   8009 	}
   8010 	bmap = isl_basic_map_reset_space(bmap, space);
   8011 	bset = bset_from_bmap(bmap);
   8012 
   8013 	set = parameter_compute_divs(bset);
   8014 	map = set_to_map(set);
   8015 	map = replace_space_by_local_space(map, ls);
   8016 
   8017 	return map;
   8018 error:
   8019 	isl_basic_map_free(bmap);
   8020 	return NULL;
   8021 }
   8022 
   8023 /* Remove the explicit representation of local variable "div",
   8024  * if there is any.
   8025  */
   8026 __isl_give isl_basic_map *isl_basic_map_mark_div_unknown(
   8027 	__isl_take isl_basic_map *bmap, int div)
   8028 {
   8029 	isl_bool unknown;
   8030 
   8031 	unknown = isl_basic_map_div_is_marked_unknown(bmap, div);
   8032 	if (unknown < 0)
   8033 		return isl_basic_map_free(bmap);
   8034 	if (unknown)
   8035 		return bmap;
   8036 
   8037 	bmap = isl_basic_map_cow(bmap);
   8038 	if (!bmap)
   8039 		return NULL;
   8040 	isl_int_set_si(bmap->div[div][0], 0);
   8041 	return bmap;
   8042 }
   8043 
   8044 /* Is local variable "div" of "bmap" marked as not having an explicit
   8045  * representation?
   8046  * Note that even if "div" is not marked in this way and therefore
   8047  * has an explicit representation, this representation may still
   8048  * depend (indirectly) on other local variables that do not
   8049  * have an explicit representation.
   8050  */
   8051 isl_bool isl_basic_map_div_is_marked_unknown(__isl_keep isl_basic_map *bmap,
   8052 	int div)
   8053 {
   8054 	if (isl_basic_map_check_range(bmap, isl_dim_div, div, 1) < 0)
   8055 		return isl_bool_error;
   8056 	return isl_int_is_zero(bmap->div[div][0]);
   8057 }
   8058 
   8059 /* Return the position of the first local variable that does not
   8060  * have an explicit representation.
   8061  * Return the total number of local variables if they all have
   8062  * an explicit representation.
   8063  * Return -1 on error.
   8064  */
   8065 int isl_basic_map_first_unknown_div(__isl_keep isl_basic_map *bmap)
   8066 {
   8067 	int i;
   8068 
   8069 	if (!bmap)
   8070 		return -1;
   8071 
   8072 	for (i = 0; i < bmap->n_div; ++i) {
   8073 		if (!isl_basic_map_div_is_known(bmap, i))
   8074 			return i;
   8075 	}
   8076 	return bmap->n_div;
   8077 }
   8078 
   8079 /* Return the position of the first local variable that does not
   8080  * have an explicit representation.
   8081  * Return the total number of local variables if they all have
   8082  * an explicit representation.
   8083  * Return -1 on error.
   8084  */
   8085 int isl_basic_set_first_unknown_div(__isl_keep isl_basic_set *bset)
   8086 {
   8087 	return isl_basic_map_first_unknown_div(bset);
   8088 }
   8089 
   8090 /* Does "bmap" have an explicit representation for all local variables?
   8091  */
   8092 isl_bool isl_basic_map_divs_known(__isl_keep isl_basic_map *bmap)
   8093 {
   8094 	int first;
   8095 	isl_size n;
   8096 
   8097 	n = isl_basic_map_dim(bmap, isl_dim_div);
   8098 	first = isl_basic_map_first_unknown_div(bmap);
   8099 	if (n < 0 || first < 0)
   8100 		return isl_bool_error;
   8101 	return first == n;
   8102 }
   8103 
   8104 /* Do all basic maps in "map" have an explicit representation
   8105  * for all local variables?
   8106  */
   8107 isl_bool isl_map_divs_known(__isl_keep isl_map *map)
   8108 {
   8109 	int i;
   8110 
   8111 	if (!map)
   8112 		return isl_bool_error;
   8113 
   8114 	for (i = 0; i < map->n; ++i) {
   8115 		int known = isl_basic_map_divs_known(map->p[i]);
   8116 		if (known <= 0)
   8117 			return known;
   8118 	}
   8119 
   8120 	return isl_bool_true;
   8121 }
   8122 
   8123 /* If bmap contains any unknown divs, then compute explicit
   8124  * expressions for them.  However, this computation may be
   8125  * quite expensive, so first try to remove divs that aren't
   8126  * strictly needed.
   8127  */
   8128 __isl_give isl_map *isl_basic_map_compute_divs(__isl_take isl_basic_map *bmap)
   8129 {
   8130 	int known;
   8131 	struct isl_map *map;
   8132 
   8133 	known = isl_basic_map_divs_known(bmap);
   8134 	if (known < 0)
   8135 		goto error;
   8136 	if (known)
   8137 		return isl_map_from_basic_map(bmap);
   8138 
   8139 	bmap = isl_basic_map_drop_redundant_divs(bmap);
   8140 
   8141 	known = isl_basic_map_divs_known(bmap);
   8142 	if (known < 0)
   8143 		goto error;
   8144 	if (known)
   8145 		return isl_map_from_basic_map(bmap);
   8146 
   8147 	map = compute_divs(bmap);
   8148 	return map;
   8149 error:
   8150 	isl_basic_map_free(bmap);
   8151 	return NULL;
   8152 }
   8153 
   8154 __isl_give isl_map *isl_map_compute_divs(__isl_take isl_map *map)
   8155 {
   8156 	int i;
   8157 	int known;
   8158 	struct isl_map *res;
   8159 
   8160 	if (!map)
   8161 		return NULL;
   8162 	if (map->n == 0)
   8163 		return map;
   8164 
   8165 	known = isl_map_divs_known(map);
   8166 	if (known < 0) {
   8167 		isl_map_free(map);
   8168 		return NULL;
   8169 	}
   8170 	if (known)
   8171 		return map;
   8172 
   8173 	res = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[0]));
   8174 	for (i = 1 ; i < map->n; ++i) {
   8175 		struct isl_map *r2;
   8176 		r2 = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[i]));
   8177 		if (ISL_F_ISSET(map, ISL_MAP_DISJOINT))
   8178 			res = isl_map_union_disjoint(res, r2);
   8179 		else
   8180 			res = isl_map_union(res, r2);
   8181 	}
   8182 	isl_map_free(map);
   8183 
   8184 	return res;
   8185 }
   8186 
   8187 __isl_give isl_set *isl_basic_set_compute_divs(__isl_take isl_basic_set *bset)
   8188 {
   8189 	return set_from_map(isl_basic_map_compute_divs(bset_to_bmap(bset)));
   8190 }
   8191 
   8192 __isl_give isl_set *isl_set_compute_divs(__isl_take isl_set *set)
   8193 {
   8194 	return set_from_map(isl_map_compute_divs(set_to_map(set)));
   8195 }
   8196 
   8197 __isl_give isl_set *isl_map_domain(__isl_take isl_map *map)
   8198 {
   8199 	isl_space *space;
   8200 	isl_size n_out;
   8201 
   8202 	n_out = isl_map_dim(map, isl_dim_out);
   8203 	if (n_out < 0)
   8204 		return set_from_map(isl_map_free(map));
   8205 	space = isl_space_domain(isl_map_get_space(map));
   8206 
   8207 	map = isl_map_project_out(map, isl_dim_out, 0, n_out);
   8208 
   8209 	return set_from_map(isl_map_reset_space(map, space));
   8210 }
   8211 
   8212 /* Return the union of "map1" and "map2", where we assume for now that
   8213  * "map1" and "map2" are disjoint.  Note that the basic maps inside
   8214  * "map1" or "map2" may not be disjoint from each other.
   8215  * Also note that this function is also called from isl_map_union,
   8216  * which takes care of handling the situation where "map1" and "map2"
   8217  * may not be disjoint.
   8218  *
   8219  * If one of the inputs is empty, we can simply return the other input.
   8220  * Similarly, if one of the inputs is universal, then it is equal to the union.
   8221  */
   8222 static __isl_give isl_map *map_union_disjoint(__isl_take isl_map *map1,
   8223 	__isl_take isl_map *map2)
   8224 {
   8225 	int i;
   8226 	unsigned flags = 0;
   8227 	struct isl_map *map = NULL;
   8228 	int is_universe;
   8229 
   8230 	if (isl_map_check_equal_space(map1, map2) < 0)
   8231 		goto error;
   8232 
   8233 	if (map1->n == 0) {
   8234 		isl_map_free(map1);
   8235 		return map2;
   8236 	}
   8237 	if (map2->n == 0) {
   8238 		isl_map_free(map2);
   8239 		return map1;
   8240 	}
   8241 
   8242 	is_universe = isl_map_plain_is_universe(map1);
   8243 	if (is_universe < 0)
   8244 		goto error;
   8245 	if (is_universe) {
   8246 		isl_map_free(map2);
   8247 		return map1;
   8248 	}
   8249 
   8250 	is_universe = isl_map_plain_is_universe(map2);
   8251 	if (is_universe < 0)
   8252 		goto error;
   8253 	if (is_universe) {
   8254 		isl_map_free(map1);
   8255 		return map2;
   8256 	}
   8257 
   8258 	if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
   8259 	    ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
   8260 		ISL_FL_SET(flags, ISL_MAP_DISJOINT);
   8261 
   8262 	map = isl_map_alloc_space(isl_space_copy(map1->dim),
   8263 				map1->n + map2->n, flags);
   8264 	if (!map)
   8265 		goto error;
   8266 	for (i = 0; i < map1->n; ++i) {
   8267 		map = isl_map_add_basic_map(map,
   8268 				  isl_basic_map_copy(map1->p[i]));
   8269 		if (!map)
   8270 			goto error;
   8271 	}
   8272 	for (i = 0; i < map2->n; ++i) {
   8273 		map = isl_map_add_basic_map(map,
   8274 				  isl_basic_map_copy(map2->p[i]));
   8275 		if (!map)
   8276 			goto error;
   8277 	}
   8278 	isl_map_free(map1);
   8279 	isl_map_free(map2);
   8280 	return map;
   8281 error:
   8282 	isl_map_free(map);
   8283 	isl_map_free(map1);
   8284 	isl_map_free(map2);
   8285 	return NULL;
   8286 }
   8287 
   8288 /* Return the union of "map1" and "map2", where "map1" and "map2" are
   8289  * guaranteed to be disjoint by the caller.
   8290  *
   8291  * Note that this functions is called from within isl_map_make_disjoint,
   8292  * so we have to be careful not to touch the constraints of the inputs
   8293  * in any way.
   8294  */
   8295 __isl_give isl_map *isl_map_union_disjoint(__isl_take isl_map *map1,
   8296 	__isl_take isl_map *map2)
   8297 {
   8298 	isl_map_align_params_bin(&map1, &map2);
   8299 	return map_union_disjoint(map1, map2);
   8300 }
   8301 
   8302 /* Return the union of "map1" and "map2", where "map1" and "map2" may
   8303  * not be disjoint.
   8304  *
   8305  * We currently simply call map_union_disjoint, the internal operation
   8306  * of which does not really depend on the inputs being disjoint.
   8307  * If the result contains more than one basic map, then we clear
   8308  * the disjoint flag since the result may contain basic maps from
   8309  * both inputs and these are not guaranteed to be disjoint.
   8310  *
   8311  * As a special case, if "map1" and "map2" are obviously equal,
   8312  * then we simply return "map1".
   8313  */
   8314 __isl_give isl_map *isl_map_union(__isl_take isl_map *map1,
   8315 	__isl_take isl_map *map2)
   8316 {
   8317 	int equal;
   8318 
   8319 	if (isl_map_align_params_bin(&map1, &map2) < 0)
   8320 		goto error;
   8321 
   8322 	equal = isl_map_plain_is_equal(map1, map2);
   8323 	if (equal < 0)
   8324 		goto error;
   8325 	if (equal) {
   8326 		isl_map_free(map2);
   8327 		return map1;
   8328 	}
   8329 
   8330 	map1 = map_union_disjoint(map1, map2);
   8331 	if (!map1)
   8332 		return NULL;
   8333 	if (map1->n > 1)
   8334 		ISL_F_CLR(map1, ISL_MAP_DISJOINT);
   8335 	return map1;
   8336 error:
   8337 	isl_map_free(map1);
   8338 	isl_map_free(map2);
   8339 	return NULL;
   8340 }
   8341 
   8342 __isl_give isl_set *isl_set_union_disjoint(
   8343 	__isl_take isl_set *set1, __isl_take isl_set *set2)
   8344 {
   8345 	return set_from_map(isl_map_union_disjoint(set_to_map(set1),
   8346 						    set_to_map(set2)));
   8347 }
   8348 
   8349 __isl_give isl_set *isl_set_union(__isl_take isl_set *set1,
   8350 	__isl_take isl_set *set2)
   8351 {
   8352 	return set_from_map(isl_map_union(set_to_map(set1), set_to_map(set2)));
   8353 }
   8354 
   8355 /* Apply "fn" to pairs of elements from "map" and "set" and collect
   8356  * the results in a map living in "space".
   8357  *
   8358  * "map" and "set" are assumed to be compatible and non-NULL.
   8359  */
   8360 static __isl_give isl_map *map_intersect_set(__isl_take isl_map *map,
   8361 	__isl_take isl_space *space, __isl_take isl_set *set,
   8362 	__isl_give isl_basic_map *fn(__isl_take isl_basic_map *bmap,
   8363 		__isl_take isl_basic_set *bset))
   8364 {
   8365 	unsigned flags = 0;
   8366 	struct isl_map *result;
   8367 	int i, j;
   8368 
   8369 	if (isl_set_plain_is_universe(set)) {
   8370 		isl_set_free(set);
   8371 		return isl_map_reset_equal_dim_space(map, space);
   8372 	}
   8373 
   8374 	if (ISL_F_ISSET(map, ISL_MAP_DISJOINT) &&
   8375 	    ISL_F_ISSET(set, ISL_MAP_DISJOINT))
   8376 		ISL_FL_SET(flags, ISL_MAP_DISJOINT);
   8377 
   8378 	result = isl_map_alloc_space(space, map->n * set->n, flags);
   8379 	for (i = 0; result && i < map->n; ++i)
   8380 		for (j = 0; j < set->n; ++j) {
   8381 			result = isl_map_add_basic_map(result,
   8382 					fn(isl_basic_map_copy(map->p[i]),
   8383 					    isl_basic_set_copy(set->p[j])));
   8384 			if (!result)
   8385 				break;
   8386 		}
   8387 
   8388 	isl_map_free(map);
   8389 	isl_set_free(set);
   8390 	return result;
   8391 }
   8392 
   8393 __isl_give isl_map *isl_map_intersect_range(__isl_take isl_map *map,
   8394 	__isl_take isl_set *set)
   8395 {
   8396 	isl_bool ok;
   8397 	isl_space *space;
   8398 
   8399 	isl_map_align_params_set(&map, &set);
   8400 	ok = isl_map_compatible_range(map, set);
   8401 	if (ok < 0)
   8402 		goto error;
   8403 	if (!ok)
   8404 		isl_die(set->ctx, isl_error_invalid,
   8405 			"incompatible spaces", goto error);
   8406 
   8407 	space = isl_map_get_space(map);
   8408 	return map_intersect_set(map, space, set,
   8409 				&isl_basic_map_intersect_range);
   8410 error:
   8411 	isl_map_free(map);
   8412 	isl_set_free(set);
   8413 	return NULL;
   8414 }
   8415 
   8416 /* Intersect the domain of "map" with "set".
   8417  *
   8418  * If the domain dimensions of "map" do not have any identifiers,
   8419  * then copy them over from "set".
   8420  */
   8421 __isl_give isl_map *isl_map_intersect_domain(__isl_take isl_map *map,
   8422 	__isl_take isl_set *set)
   8423 {
   8424 	isl_bool ok;
   8425 	isl_space *space;
   8426 
   8427 	isl_map_align_params_set(&map, &set);
   8428 	ok = isl_map_compatible_domain(map, set);
   8429 	if (ok < 0)
   8430 		goto error;
   8431 	if (!ok)
   8432 		isl_die(set->ctx, isl_error_invalid,
   8433 			"incompatible spaces", goto error);
   8434 
   8435 	space = isl_map_get_space(map);
   8436 	space = isl_space_copy_ids_if_unset(space, isl_dim_in,
   8437 					isl_set_peek_space(set), isl_dim_set);
   8438 	return map_intersect_set(map, space, set,
   8439 				&isl_basic_map_intersect_domain);
   8440 error:
   8441 	isl_map_free(map);
   8442 	isl_set_free(set);
   8443 	return NULL;
   8444 }
   8445 
   8446 #undef BASE
   8447 #define BASE map
   8448 static
   8449 #include "isl_copy_tuple_id_templ.c"
   8450 
   8451 /* Data structure that specifies how isl_map_intersect_factor
   8452  * should operate.
   8453  *
   8454  * "preserve_type" is the tuple where the factor differs from
   8455  * the input map and of which the identifiers needs
   8456  * to be preserved explicitly.
   8457  * "other_factor" is used to extract the space of the other factor
   8458  * from the space of the product ("map").
   8459  * "product" is used to combine the given factor and a universe map
   8460  * in the space returned by "other_factor" to produce a map
   8461  * that lives in the same space as the input map.
   8462  */
   8463 struct isl_intersect_factor_control {
   8464 	enum isl_dim_type preserve_type;
   8465 	__isl_give isl_space *(*other_factor)(__isl_take isl_space *space);
   8466 	__isl_give isl_map *(*product)(__isl_take isl_map *factor,
   8467 		__isl_take isl_map *other);
   8468 };
   8469 
   8470 /* Given a map "map" in some product space and a map "factor"
   8471  * living in some factor space, return the intersection.
   8472  *
   8473  * After aligning the parameters,
   8474  * the map "factor" is first extended to a map living in the same space
   8475  * as "map" and then a regular intersection is computed.
   8476  *
   8477  * Note that the extension is computed as a product, which is anonymous
   8478  * by default.  If "map" has an identifier on the corresponding tuple,
   8479  * then this identifier needs to be set on the product
   8480  * before the intersection is computed.
   8481  */
   8482 static __isl_give isl_map *isl_map_intersect_factor(
   8483 	__isl_take isl_map *map, __isl_take isl_map *factor,
   8484 	struct isl_intersect_factor_control *control)
   8485 {
   8486 	isl_bool equal;
   8487 	isl_space *space;
   8488 	isl_map *other, *product;
   8489 
   8490 	equal = isl_map_has_equal_params(map, factor);
   8491 	if (equal < 0)
   8492 		goto error;
   8493 	if (!equal) {
   8494 		map = isl_map_align_params(map, isl_map_get_space(factor));
   8495 		factor = isl_map_align_params(factor, isl_map_get_space(map));
   8496 	}
   8497 
   8498 	space = isl_map_get_space(map);
   8499 	other = isl_map_universe(control->other_factor(space));
   8500 	product = control->product(factor, other);
   8501 
   8502 	space = isl_map_peek_space(map);
   8503 	product = isl_map_copy_tuple_id(product, control->preserve_type,
   8504 					space, control->preserve_type);
   8505 	return map_intersect(map, product);
   8506 error:
   8507 	isl_map_free(map);
   8508 	isl_map_free(factor);
   8509 	return NULL;
   8510 }
   8511 
   8512 /* Return the domain product of "map2" and "map1".
   8513  */
   8514 static __isl_give isl_map *isl_map_reverse_domain_product(
   8515 	__isl_take isl_map *map1, __isl_take isl_map *map2)
   8516 {
   8517 	return isl_map_domain_product(map2, map1);
   8518 }
   8519 
   8520 /* Return the range product of "map2" and "map1".
   8521  */
   8522 static __isl_give isl_map *isl_map_reverse_range_product(
   8523 	__isl_take isl_map *map1, __isl_take isl_map *map2)
   8524 {
   8525 	return isl_map_range_product(map2, map1);
   8526 }
   8527 
   8528 /* Given a map "map" in a space [A -> B] -> C and a map "factor"
   8529  * in the space A -> C, return the intersection.
   8530  */
   8531 __isl_give isl_map *isl_map_intersect_domain_factor_domain(
   8532 	__isl_take isl_map *map, __isl_take isl_map *factor)
   8533 {
   8534 	struct isl_intersect_factor_control control = {
   8535 		.preserve_type = isl_dim_in,
   8536 		.other_factor = isl_space_domain_factor_range,
   8537 		.product = isl_map_domain_product,
   8538 	};
   8539 
   8540 	return isl_map_intersect_factor(map, factor, &control);
   8541 }
   8542 
   8543 /* Given a map "map" in a space [A -> B] -> C and a map "factor"
   8544  * in the space B -> C, return the intersection.
   8545  */
   8546 __isl_give isl_map *isl_map_intersect_domain_factor_range(
   8547 	__isl_take isl_map *map, __isl_take isl_map *factor)
   8548 {
   8549 	struct isl_intersect_factor_control control = {
   8550 		.preserve_type = isl_dim_in,
   8551 		.other_factor = isl_space_domain_factor_domain,
   8552 		.product = isl_map_reverse_domain_product,
   8553 	};
   8554 
   8555 	return isl_map_intersect_factor(map, factor, &control);
   8556 }
   8557 
   8558 /* Given a map "map" in a space A -> [B -> C] and a map "factor"
   8559  * in the space A -> B, return the intersection.
   8560  */
   8561 __isl_give isl_map *isl_map_intersect_range_factor_domain(
   8562 	__isl_take isl_map *map, __isl_take isl_map *factor)
   8563 {
   8564 	struct isl_intersect_factor_control control = {
   8565 		.preserve_type = isl_dim_out,
   8566 		.other_factor = isl_space_range_factor_range,
   8567 		.product = isl_map_range_product,
   8568 	};
   8569 
   8570 	return isl_map_intersect_factor(map, factor, &control);
   8571 }
   8572 
   8573 /* Given a map "map" in a space A -> [B -> C] and a map "factor"
   8574  * in the space A -> C, return the intersection.
   8575  */
   8576 __isl_give isl_map *isl_map_intersect_range_factor_range(
   8577 	__isl_take isl_map *map, __isl_take isl_map *factor)
   8578 {
   8579 	struct isl_intersect_factor_control control = {
   8580 		.preserve_type = isl_dim_out,
   8581 		.other_factor = isl_space_range_factor_domain,
   8582 		.product = isl_map_reverse_range_product,
   8583 	};
   8584 
   8585 	return isl_map_intersect_factor(map, factor, &control);
   8586 }
   8587 
   8588 /* Given a set "set" in a space [A -> B] and a set "domain"
   8589  * in the space A, return the intersection.
   8590  *
   8591  * The set "domain" is first extended to a set living in the space
   8592  * [A -> B] and then a regular intersection is computed.
   8593  */
   8594 __isl_give isl_set *isl_set_intersect_factor_domain(__isl_take isl_set *set,
   8595 	__isl_take isl_set *domain)
   8596 {
   8597 	struct isl_intersect_factor_control control = {
   8598 		.preserve_type = isl_dim_set,
   8599 		.other_factor = isl_space_factor_range,
   8600 		.product = isl_map_range_product,
   8601 	};
   8602 
   8603 	return set_from_map(isl_map_intersect_factor(set_to_map(set),
   8604 						set_to_map(domain), &control));
   8605 }
   8606 
   8607 /* Given a set "set" in a space [A -> B] and a set "range"
   8608  * in the space B, return the intersection.
   8609  *
   8610  * The set "range" is first extended to a set living in the space
   8611  * [A -> B] and then a regular intersection is computed.
   8612  */
   8613 __isl_give isl_set *isl_set_intersect_factor_range(__isl_take isl_set *set,
   8614 	__isl_take isl_set *range)
   8615 {
   8616 	struct isl_intersect_factor_control control = {
   8617 		.preserve_type = isl_dim_set,
   8618 		.other_factor = isl_space_factor_domain,
   8619 		.product = isl_map_reverse_range_product,
   8620 	};
   8621 
   8622 	return set_from_map(isl_map_intersect_factor(set_to_map(set),
   8623 						set_to_map(range), &control));
   8624 }
   8625 
   8626 #undef BASE
   8627 #define BASE set
   8628 static
   8629 #include "isl_copy_tuple_id_templ.c"
   8630 
   8631 /* Given a map "map" in a space [A -> B] -> C and a set "domain"
   8632  * in the space A, return the intersection.
   8633  *
   8634  * The set "domain" is extended to a set living in the space [A -> B] and
   8635  * the domain of "map" is intersected with this set.
   8636  *
   8637  * If "map" has an identifier on the domain tuple,
   8638  * then this identifier needs to be set on this product
   8639  * before the intersection is computed.
   8640  */
   8641 __isl_give isl_map *isl_map_intersect_domain_wrapped_domain(
   8642 	__isl_take isl_map *map, __isl_take isl_set *domain)
   8643 {
   8644 	isl_space *space;
   8645 	isl_set *factor;
   8646 
   8647 	isl_map_align_params_set(&map, &domain);
   8648 	space = isl_map_get_space(map);
   8649 	space = isl_space_domain_wrapped_range(space);
   8650 	factor = isl_set_universe(space);
   8651 	domain = isl_set_product(domain, factor);
   8652 	space = isl_map_peek_space(map);
   8653 	domain = isl_set_copy_tuple_id(domain, isl_dim_set, space, isl_dim_in);
   8654 	return isl_map_intersect_domain(map, domain);
   8655 }
   8656 
   8657 /* Given a map "map" in a space A -> [B -> C] and a set "domain"
   8658  * in the space B, return the intersection.
   8659  *
   8660  * The set "domain" is extended to a set living in the space [B -> C] and
   8661  * the range of "map" is intersected with this set.
   8662  *
   8663  * If "map" has an identifier on the range tuple,
   8664  * then this identifier needs to be set on this product
   8665  * before the intersection is computed.
   8666  */
   8667 __isl_give isl_map *isl_map_intersect_range_wrapped_domain(
   8668 	__isl_take isl_map *map, __isl_take isl_set *domain)
   8669 {
   8670 	isl_space *space;
   8671 	isl_set *factor;
   8672 
   8673 	isl_map_align_params_set(&map, &domain);
   8674 	space = isl_map_get_space(map);
   8675 	space = isl_space_range_wrapped_range(space);
   8676 	factor = isl_set_universe(space);
   8677 	domain = isl_set_product(domain, factor);
   8678 	space = isl_map_peek_space(map);
   8679 	domain = isl_set_copy_tuple_id(domain, isl_dim_set, space, isl_dim_out);
   8680 	return isl_map_intersect_range(map, domain);
   8681 }
   8682 
   8683 __isl_give isl_map *isl_map_apply_domain(__isl_take isl_map *map1,
   8684 	__isl_take isl_map *map2)
   8685 {
   8686 	if (isl_map_align_params_bin(&map1, &map2) < 0)
   8687 		goto error;
   8688 	map1 = isl_map_reverse(map1);
   8689 	map1 = isl_map_apply_range(map1, map2);
   8690 	return isl_map_reverse(map1);
   8691 error:
   8692 	isl_map_free(map1);
   8693 	isl_map_free(map2);
   8694 	return NULL;
   8695 }
   8696 
   8697 __isl_give isl_map *isl_map_apply_range(__isl_take isl_map *map1,
   8698 	__isl_take isl_map *map2)
   8699 {
   8700 	isl_space *space;
   8701 	struct isl_map *result;
   8702 	int i, j;
   8703 
   8704 	if (isl_map_align_params_bin(&map1, &map2) < 0)
   8705 		goto error;
   8706 
   8707 	space = isl_space_join(isl_space_copy(map1->dim),
   8708 				  isl_space_copy(map2->dim));
   8709 
   8710 	result = isl_map_alloc_space(space, map1->n * map2->n, 0);
   8711 	if (!result)
   8712 		goto error;
   8713 	for (i = 0; i < map1->n; ++i)
   8714 		for (j = 0; j < map2->n; ++j) {
   8715 			result = isl_map_add_basic_map(result,
   8716 			    isl_basic_map_apply_range(
   8717 				isl_basic_map_copy(map1->p[i]),
   8718 				isl_basic_map_copy(map2->p[j])));
   8719 			if (!result)
   8720 				goto error;
   8721 		}
   8722 	isl_map_free(map1);
   8723 	isl_map_free(map2);
   8724 	if (result && result->n <= 1)
   8725 		ISL_F_SET(result, ISL_MAP_DISJOINT);
   8726 	return result;
   8727 error:
   8728 	isl_map_free(map1);
   8729 	isl_map_free(map2);
   8730 	return NULL;
   8731 }
   8732 
   8733 /* Is "bmap" a transformation, i.e.,
   8734  * does it relate elements from the same space.
   8735  */
   8736 isl_bool isl_basic_map_is_transformation(__isl_keep isl_basic_map *bmap)
   8737 {
   8738 	isl_space *space;
   8739 
   8740 	space = isl_basic_map_peek_space(bmap);
   8741 	return isl_space_tuple_is_equal(space, isl_dim_in, space, isl_dim_out);
   8742 }
   8743 
   8744 /* Check that "bmap" is a transformation, i.e.,
   8745  * that it relates elements from the same space.
   8746  */
   8747 static isl_stat isl_basic_map_check_transformation(
   8748 	__isl_keep isl_basic_map *bmap)
   8749 {
   8750 	isl_bool equal;
   8751 
   8752 	equal = isl_basic_map_is_transformation(bmap);
   8753 	if (equal < 0)
   8754 		return isl_stat_error;
   8755 	if (!equal)
   8756 		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
   8757 			"domain and range don't match", return isl_stat_error);
   8758 	return isl_stat_ok;
   8759 }
   8760 
   8761 /*
   8762  * returns range - domain
   8763  */
   8764 __isl_give isl_basic_set *isl_basic_map_deltas(__isl_take isl_basic_map *bmap)
   8765 {
   8766 	isl_space *target_space;
   8767 	struct isl_basic_set *bset;
   8768 	isl_size dim;
   8769 	isl_size nparam;
   8770 	isl_size total;
   8771 	int i;
   8772 
   8773 	if (isl_basic_map_check_transformation(bmap) < 0)
   8774 		return isl_basic_map_free(bmap);
   8775 	dim = isl_basic_map_dim(bmap, isl_dim_in);
   8776 	nparam = isl_basic_map_dim(bmap, isl_dim_param);
   8777 	if (dim < 0 || nparam < 0)
   8778 		goto error;
   8779 	target_space = isl_space_domain(isl_basic_map_get_space(bmap));
   8780 	bmap = isl_basic_map_from_range(isl_basic_map_wrap(bmap));
   8781 	bmap = isl_basic_map_add_dims(bmap, isl_dim_in, dim);
   8782 	total = isl_basic_map_dim(bmap, isl_dim_all);
   8783 	if (total < 0)
   8784 		bmap = isl_basic_map_free(bmap);
   8785 	bmap = isl_basic_map_extend_constraints(bmap, dim, 0);
   8786 	for (i = 0; i < dim; ++i) {
   8787 		int j = isl_basic_map_alloc_equality(bmap);
   8788 		if (j < 0) {
   8789 			bmap = isl_basic_map_free(bmap);
   8790 			break;
   8791 		}
   8792 		isl_seq_clr(bmap->eq[j], 1 + total);
   8793 		isl_int_set_si(bmap->eq[j][1+nparam+i], 1);
   8794 		isl_int_set_si(bmap->eq[j][1+nparam+dim+i], 1);
   8795 		isl_int_set_si(bmap->eq[j][1+nparam+2*dim+i], -1);
   8796 	}
   8797 	bset = isl_basic_map_domain(bmap);
   8798 	bset = isl_basic_set_reset_space(bset, target_space);
   8799 	return bset;
   8800 error:
   8801 	isl_basic_map_free(bmap);
   8802 	return NULL;
   8803 }
   8804 
   8805 /* Is the tuple of type "type1" of "map" the same as
   8806  * the tuple of type "type2" of "space"?
   8807  */
   8808 isl_bool isl_map_space_tuple_is_equal(__isl_keep isl_map *map,
   8809 	enum isl_dim_type type1, __isl_keep isl_space *space,
   8810 	enum isl_dim_type type2)
   8811 {
   8812 	isl_space *map_space;
   8813 
   8814 	map_space = isl_map_peek_space(map);
   8815 	return isl_space_tuple_is_equal(map_space, type1, space, type2);
   8816 }
   8817 
   8818 /* Is the tuple of type "type1" of "map1" the same as
   8819  * the tuple of type "type2" of "map2"?
   8820  */
   8821 isl_bool isl_map_tuple_is_equal(__isl_keep isl_map *map1,
   8822 	enum isl_dim_type type1, __isl_keep isl_map *map2,
   8823 	enum isl_dim_type type2)
   8824 {
   8825 	isl_space *space1, *space2;
   8826 
   8827 	space1 = isl_map_peek_space(map1);
   8828 	space2 = isl_map_peek_space(map2);
   8829 	return isl_space_tuple_is_equal(space1, type1, space2, type2);
   8830 }
   8831 
   8832 /* Is the space of "obj" equal to "space", ignoring parameters?
   8833  */
   8834 isl_bool isl_map_has_space_tuples(__isl_keep isl_map *map,
   8835 	__isl_keep isl_space *space)
   8836 {
   8837 	isl_space *map_space;
   8838 
   8839 	map_space = isl_map_peek_space(map);
   8840 	return isl_space_has_equal_tuples(map_space, space);
   8841 }
   8842 
   8843 /* Check that "map" is a transformation, i.e.,
   8844  * that it relates elements from the same space.
   8845  */
   8846 isl_stat isl_map_check_transformation(__isl_keep isl_map *map)
   8847 {
   8848 	isl_bool equal;
   8849 
   8850 	equal = isl_map_tuple_is_equal(map, isl_dim_in, map, isl_dim_out);
   8851 	if (equal < 0)
   8852 		return isl_stat_error;
   8853 	if (!equal)
   8854 		isl_die(isl_map_get_ctx(map), isl_error_invalid,
   8855 			"domain and range don't match", return isl_stat_error);
   8856 	return isl_stat_ok;
   8857 }
   8858 
   8859 /*
   8860  * returns range - domain
   8861  */
   8862 __isl_give isl_set *isl_map_deltas(__isl_take isl_map *map)
   8863 {
   8864 	int i;
   8865 	isl_space *space;
   8866 	struct isl_set *result;
   8867 
   8868 	if (isl_map_check_transformation(map) < 0)
   8869 		goto error;
   8870 	space = isl_map_get_space(map);
   8871 	space = isl_space_domain(space);
   8872 	result = isl_set_alloc_space(space, map->n, 0);
   8873 	if (!result)
   8874 		goto error;
   8875 	for (i = 0; i < map->n; ++i)
   8876 		result = isl_set_add_basic_set(result,
   8877 			  isl_basic_map_deltas(isl_basic_map_copy(map->p[i])));
   8878 	isl_map_free(map);
   8879 	return result;
   8880 error:
   8881 	isl_map_free(map);
   8882 	return NULL;
   8883 }
   8884 
   8885 /*
   8886  * returns [domain -> range] -> range - domain
   8887  */
   8888 __isl_give isl_basic_map *isl_basic_map_deltas_map(
   8889 	__isl_take isl_basic_map *bmap)
   8890 {
   8891 	int i, k;
   8892 	isl_space *space;
   8893 	isl_basic_map *domain;
   8894 	isl_size nparam, n;
   8895 	isl_size total;
   8896 
   8897 	if (isl_basic_map_check_transformation(bmap) < 0)
   8898 		return isl_basic_map_free(bmap);
   8899 
   8900 	nparam = isl_basic_map_dim(bmap, isl_dim_param);
   8901 	n = isl_basic_map_dim(bmap, isl_dim_in);
   8902 	if (nparam < 0 || n < 0)
   8903 		return isl_basic_map_free(bmap);
   8904 
   8905 	space = isl_basic_map_get_space(bmap);
   8906 	space = isl_space_from_range(isl_space_domain(space));
   8907 	domain = isl_basic_map_universe(space);
   8908 
   8909 	bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
   8910 	bmap = isl_basic_map_apply_range(bmap, domain);
   8911 	bmap = isl_basic_map_extend_constraints(bmap, n, 0);
   8912 
   8913 	total = isl_basic_map_dim(bmap, isl_dim_all);
   8914 	if (total < 0)
   8915 		return isl_basic_map_free(bmap);
   8916 
   8917 	for (i = 0; i < n; ++i) {
   8918 		k = isl_basic_map_alloc_equality(bmap);
   8919 		if (k < 0)
   8920 			goto error;
   8921 		isl_seq_clr(bmap->eq[k], 1 + total);
   8922 		isl_int_set_si(bmap->eq[k][1 + nparam + i], 1);
   8923 		isl_int_set_si(bmap->eq[k][1 + nparam + n + i], -1);
   8924 		isl_int_set_si(bmap->eq[k][1 + nparam + n + n + i], 1);
   8925 	}
   8926 
   8927 	bmap = isl_basic_map_gauss(bmap, NULL);
   8928 	return isl_basic_map_finalize(bmap);
   8929 error:
   8930 	isl_basic_map_free(bmap);
   8931 	return NULL;
   8932 }
   8933 
   8934 /*
   8935  * returns [domain -> range] -> range - domain
   8936  */
   8937 __isl_give isl_map *isl_map_deltas_map(__isl_take isl_map *map)
   8938 {
   8939 	if (isl_map_check_transformation(map) < 0)
   8940 		return isl_map_free(map);
   8941 
   8942 	return isl_map_transform(map, &isl_space_range_map,
   8943 					&isl_basic_map_deltas_map);
   8944 }
   8945 
   8946 /* Return pairs of elements { x -> y } such that y - x is in "deltas".
   8947  */
   8948 __isl_give isl_map *isl_set_translation(__isl_take isl_set *deltas)
   8949 {
   8950 	isl_space *space;
   8951 	isl_map *map;
   8952 
   8953 	space = isl_space_map_from_set(isl_set_get_space(deltas));
   8954 	map = isl_map_deltas_map(isl_map_universe(space));
   8955 	map = isl_map_intersect_range(map, deltas);
   8956 
   8957 	return isl_set_unwrap(isl_map_domain(map));
   8958 }
   8959 
   8960 __isl_give isl_basic_map *isl_basic_map_identity(__isl_take isl_space *space)
   8961 {
   8962 	isl_size n_in, n_out;
   8963 
   8964 	n_in = isl_space_dim(space, isl_dim_in);
   8965 	n_out = isl_space_dim(space, isl_dim_out);
   8966 	if (n_in < 0 || n_out < 0)
   8967 		goto error;
   8968 	if (n_in != n_out)
   8969 		isl_die(space->ctx, isl_error_invalid,
   8970 			"number of input and output dimensions needs to be "
   8971 			"the same", goto error);
   8972 	return isl_basic_map_equal(space, n_in);
   8973 error:
   8974 	isl_space_free(space);
   8975 	return NULL;
   8976 }
   8977 
   8978 __isl_give isl_map *isl_map_identity(__isl_take isl_space *space)
   8979 {
   8980 	return isl_map_from_basic_map(isl_basic_map_identity(space));
   8981 }
   8982 
   8983 __isl_give isl_map *isl_set_identity(__isl_take isl_set *set)
   8984 {
   8985 	isl_space *space = isl_set_get_space(set);
   8986 	isl_map *id;
   8987 	id = isl_map_identity(isl_space_map_from_set(space));
   8988 	return isl_map_intersect_range(id, set);
   8989 }
   8990 
   8991 /* Construct a basic set with all set dimensions having only non-negative
   8992  * values.
   8993  */
   8994 __isl_give isl_basic_set *isl_basic_set_positive_orthant(
   8995 	__isl_take isl_space *space)
   8996 {
   8997 	int i;
   8998 	isl_size nparam;
   8999 	isl_size dim;
   9000 	isl_size total;
   9001 	struct isl_basic_set *bset;
   9002 
   9003 	nparam = isl_space_dim(space, isl_dim_param);
   9004 	dim = isl_space_dim(space, isl_dim_set);
   9005 	total = isl_space_dim(space, isl_dim_all);
   9006 	if (nparam < 0 || dim < 0 || total < 0)
   9007 		space = isl_space_free(space);
   9008 	bset = isl_basic_set_alloc_space(space, 0, 0, dim);
   9009 	if (!bset)
   9010 		return NULL;
   9011 	for (i = 0; i < dim; ++i) {
   9012 		int k = isl_basic_set_alloc_inequality(bset);
   9013 		if (k < 0)
   9014 			goto error;
   9015 		isl_seq_clr(bset->ineq[k], 1 + total);
   9016 		isl_int_set_si(bset->ineq[k][1 + nparam + i], 1);
   9017 	}
   9018 	return bset;
   9019 error:
   9020 	isl_basic_set_free(bset);
   9021 	return NULL;
   9022 }
   9023 
   9024 /* Construct the half-space x_pos >= 0.
   9025  */
   9026 static __isl_give isl_basic_set *nonneg_halfspace(__isl_take isl_space *space,
   9027 	int pos)
   9028 {
   9029 	int k;
   9030 	isl_size total;
   9031 	isl_basic_set *nonneg;
   9032 
   9033 	total = isl_space_dim(space, isl_dim_all);
   9034 	if (total < 0)
   9035 		space = isl_space_free(space);
   9036 	nonneg = isl_basic_set_alloc_space(space, 0, 0, 1);
   9037 	k = isl_basic_set_alloc_inequality(nonneg);
   9038 	if (k < 0)
   9039 		goto error;
   9040 	isl_seq_clr(nonneg->ineq[k], 1 + total);
   9041 	isl_int_set_si(nonneg->ineq[k][pos], 1);
   9042 
   9043 	return isl_basic_set_finalize(nonneg);
   9044 error:
   9045 	isl_basic_set_free(nonneg);
   9046 	return NULL;
   9047 }
   9048 
   9049 /* Construct the half-space x_pos <= -1.
   9050  */
   9051 static __isl_give isl_basic_set *neg_halfspace(__isl_take isl_space *space,
   9052 	int pos)
   9053 {
   9054 	int k;
   9055 	isl_size total;
   9056 	isl_basic_set *neg;
   9057 
   9058 	total = isl_space_dim(space, isl_dim_all);
   9059 	if (total < 0)
   9060 		space = isl_space_free(space);
   9061 	neg = isl_basic_set_alloc_space(space, 0, 0, 1);
   9062 	k = isl_basic_set_alloc_inequality(neg);
   9063 	if (k < 0)
   9064 		goto error;
   9065 	isl_seq_clr(neg->ineq[k], 1 + total);
   9066 	isl_int_set_si(neg->ineq[k][0], -1);
   9067 	isl_int_set_si(neg->ineq[k][pos], -1);
   9068 
   9069 	return isl_basic_set_finalize(neg);
   9070 error:
   9071 	isl_basic_set_free(neg);
   9072 	return NULL;
   9073 }
   9074 
   9075 __isl_give isl_set *isl_set_split_dims(__isl_take isl_set *set,
   9076 	enum isl_dim_type type, unsigned first, unsigned n)
   9077 {
   9078 	int i;
   9079 	unsigned offset;
   9080 	isl_basic_set *nonneg;
   9081 	isl_basic_set *neg;
   9082 
   9083 	if (n == 0)
   9084 		return set;
   9085 
   9086 	if (isl_set_check_range(set, type, first, n) < 0)
   9087 		return isl_set_free(set);
   9088 
   9089 	offset = pos(set->dim, type);
   9090 	for (i = 0; i < n; ++i) {
   9091 		nonneg = nonneg_halfspace(isl_set_get_space(set),
   9092 					  offset + first + i);
   9093 		neg = neg_halfspace(isl_set_get_space(set), offset + first + i);
   9094 
   9095 		set = isl_set_intersect(set, isl_basic_set_union(nonneg, neg));
   9096 	}
   9097 
   9098 	return set;
   9099 }
   9100 
   9101 static isl_stat foreach_orthant(__isl_take isl_set *set, int *signs, int first,
   9102 	int len,
   9103 	isl_stat (*fn)(__isl_take isl_set *orthant, int *signs, void *user),
   9104 	void *user)
   9105 {
   9106 	isl_set *half;
   9107 
   9108 	if (!set)
   9109 		return isl_stat_error;
   9110 	if (isl_set_plain_is_empty(set)) {
   9111 		isl_set_free(set);
   9112 		return isl_stat_ok;
   9113 	}
   9114 	if (first == len)
   9115 		return fn(set, signs, user);
   9116 
   9117 	signs[first] = 1;
   9118 	half = isl_set_from_basic_set(nonneg_halfspace(isl_set_get_space(set),
   9119 							1 + first));
   9120 	half = isl_set_intersect(half, isl_set_copy(set));
   9121 	if (foreach_orthant(half, signs, first + 1, len, fn, user) < 0)
   9122 		goto error;
   9123 
   9124 	signs[first] = -1;
   9125 	half = isl_set_from_basic_set(neg_halfspace(isl_set_get_space(set),
   9126 							1 + first));
   9127 	half = isl_set_intersect(half, set);
   9128 	return foreach_orthant(half, signs, first + 1, len, fn, user);
   9129 error:
   9130 	isl_set_free(set);
   9131 	return isl_stat_error;
   9132 }
   9133 
   9134 /* Call "fn" on the intersections of "set" with each of the orthants
   9135  * (except for obviously empty intersections).  The orthant is identified
   9136  * by the signs array, with each entry having value 1 or -1 according
   9137  * to the sign of the corresponding variable.
   9138  */
   9139 isl_stat isl_set_foreach_orthant(__isl_keep isl_set *set,
   9140 	isl_stat (*fn)(__isl_take isl_set *orthant, int *signs, void *user),
   9141 	void *user)
   9142 {
   9143 	isl_size nparam;
   9144 	isl_size nvar;
   9145 	int *signs;
   9146 	isl_stat r;
   9147 
   9148 	if (!set)
   9149 		return isl_stat_error;
   9150 	if (isl_set_plain_is_empty(set))
   9151 		return isl_stat_ok;
   9152 
   9153 	nparam = isl_set_dim(set, isl_dim_param);
   9154 	nvar = isl_set_dim(set, isl_dim_set);
   9155 	if (nparam < 0 || nvar < 0)
   9156 		return isl_stat_error;
   9157 
   9158 	signs = isl_alloc_array(set->ctx, int, nparam + nvar);
   9159 
   9160 	r = foreach_orthant(isl_set_copy(set), signs, 0, nparam + nvar,
   9161 			    fn, user);
   9162 
   9163 	free(signs);
   9164 
   9165 	return r;
   9166 }
   9167 
   9168 isl_bool isl_set_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
   9169 {
   9170 	return isl_map_is_equal(set_to_map(set1), set_to_map(set2));
   9171 }
   9172 
   9173 isl_bool isl_basic_map_is_subset(__isl_keep isl_basic_map *bmap1,
   9174 	__isl_keep isl_basic_map *bmap2)
   9175 {
   9176 	isl_bool is_subset;
   9177 	struct isl_map *map1;
   9178 	struct isl_map *map2;
   9179 
   9180 	if (!bmap1 || !bmap2)
   9181 		return isl_bool_error;
   9182 
   9183 	map1 = isl_map_from_basic_map(isl_basic_map_copy(bmap1));
   9184 	map2 = isl_map_from_basic_map(isl_basic_map_copy(bmap2));
   9185 
   9186 	is_subset = isl_map_is_subset(map1, map2);
   9187 
   9188 	isl_map_free(map1);
   9189 	isl_map_free(map2);
   9190 
   9191 	return is_subset;
   9192 }
   9193 
   9194 isl_bool isl_basic_set_is_subset(__isl_keep isl_basic_set *bset1,
   9195 	__isl_keep isl_basic_set *bset2)
   9196 {
   9197 	return isl_basic_map_is_subset(bset1, bset2);
   9198 }
   9199 
   9200 isl_bool isl_basic_map_is_equal(__isl_keep isl_basic_map *bmap1,
   9201 	__isl_keep isl_basic_map *bmap2)
   9202 {
   9203 	isl_bool is_subset;
   9204 
   9205 	if (!bmap1 || !bmap2)
   9206 		return isl_bool_error;
   9207 	is_subset = isl_basic_map_is_subset(bmap1, bmap2);
   9208 	if (is_subset != isl_bool_true)
   9209 		return is_subset;
   9210 	is_subset = isl_basic_map_is_subset(bmap2, bmap1);
   9211 	return is_subset;
   9212 }
   9213 
   9214 isl_bool isl_basic_set_is_equal(__isl_keep isl_basic_set *bset1,
   9215 	__isl_keep isl_basic_set *bset2)
   9216 {
   9217 	return isl_basic_map_is_equal(
   9218 		bset_to_bmap(bset1), bset_to_bmap(bset2));
   9219 }
   9220 
   9221 isl_bool isl_map_is_empty(__isl_keep isl_map *map)
   9222 {
   9223 	int i;
   9224 	int is_empty;
   9225 
   9226 	if (!map)
   9227 		return isl_bool_error;
   9228 	for (i = 0; i < map->n; ++i) {
   9229 		is_empty = isl_basic_map_is_empty(map->p[i]);
   9230 		if (is_empty < 0)
   9231 			return isl_bool_error;
   9232 		if (!is_empty)
   9233 			return isl_bool_false;
   9234 	}
   9235 	return isl_bool_true;
   9236 }
   9237 
   9238 isl_bool isl_map_plain_is_empty(__isl_keep isl_map *map)
   9239 {
   9240 	return map ? map->n == 0 : isl_bool_error;
   9241 }
   9242 
   9243 isl_bool isl_set_plain_is_empty(__isl_keep isl_set *set)
   9244 {
   9245 	return set ? set->n == 0 : isl_bool_error;
   9246 }
   9247 
   9248 isl_bool isl_set_is_empty(__isl_keep isl_set *set)
   9249 {
   9250 	return isl_map_is_empty(set_to_map(set));
   9251 }
   9252 
   9253 #undef TYPE
   9254 #define TYPE	isl_basic_map
   9255 
   9256 static
   9257 #include "isl_type_has_equal_space_bin_templ.c"
   9258 #include "isl_type_check_equal_space_templ.c"
   9259 
   9260 /* Check that "bset1" and "bset2" live in the same space,
   9261  * reporting an error if they do not.
   9262  */
   9263 isl_stat isl_basic_set_check_equal_space(__isl_keep isl_basic_set *bset1,
   9264 	__isl_keep isl_basic_set *bset2)
   9265 {
   9266 	return isl_basic_map_check_equal_space(bset_to_bmap(bset1),
   9267 						bset_to_bmap(bset1));
   9268 }
   9269 
   9270 #undef TYPE
   9271 #define TYPE	isl_map
   9272 
   9273 #include "isl_type_has_equal_space_bin_templ.c"
   9274 #include "isl_type_check_equal_space_templ.c"
   9275 #include "isl_type_has_space_templ.c"
   9276 
   9277 isl_bool isl_set_has_equal_space(__isl_keep isl_set *set1,
   9278 	__isl_keep isl_set *set2)
   9279 {
   9280 	return isl_map_has_equal_space(set_to_map(set1), set_to_map(set2));
   9281 }
   9282 
   9283 #undef TYPE1
   9284 #define TYPE1		isl_map
   9285 #undef TYPE2
   9286 #define TYPE2		isl_basic_map
   9287 #undef TYPE_PAIR
   9288 #define TYPE_PAIR	isl_map_basic_map
   9289 
   9290 static
   9291 #include "isl_type_has_equal_space_templ.c"
   9292 #include "isl_type_check_equal_space_templ.c"
   9293 
   9294 /* Check that "set" and "bset" live in the same space,
   9295  * reporting an error if they do not.
   9296  */
   9297 isl_stat isl_set_basic_set_check_equal_space(__isl_keep isl_set *set,
   9298 	__isl_keep isl_basic_set *bset)
   9299 {
   9300 	return isl_map_basic_map_check_equal_space(set_to_map(set),
   9301 						    bset_to_bmap(bset));
   9302 }
   9303 
   9304 static isl_bool map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
   9305 {
   9306 	isl_bool is_subset;
   9307 
   9308 	if (!map1 || !map2)
   9309 		return isl_bool_error;
   9310 	is_subset = isl_map_is_subset(map1, map2);
   9311 	if (is_subset != isl_bool_true)
   9312 		return is_subset;
   9313 	is_subset = isl_map_is_subset(map2, map1);
   9314 	return is_subset;
   9315 }
   9316 
   9317 /* Is "map1" equal to "map2"?
   9318  *
   9319  * First check if they are obviously equal.
   9320  * If not, then perform a more detailed analysis.
   9321  */
   9322 isl_bool isl_map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
   9323 {
   9324 	isl_bool equal;
   9325 
   9326 	equal = isl_map_plain_is_equal(map1, map2);
   9327 	if (equal < 0 || equal)
   9328 		return equal;
   9329 	return isl_map_align_params_map_map_and_test(map1, map2, &map_is_equal);
   9330 }
   9331 
   9332 isl_bool isl_basic_map_is_strict_subset(__isl_keep isl_basic_map *bmap1,
   9333 	__isl_keep isl_basic_map *bmap2)
   9334 {
   9335 	isl_bool is_subset;
   9336 
   9337 	if (!bmap1 || !bmap2)
   9338 		return isl_bool_error;
   9339 	is_subset = isl_basic_map_is_subset(bmap1, bmap2);
   9340 	if (is_subset != isl_bool_true)
   9341 		return is_subset;
   9342 	is_subset = isl_basic_map_is_subset(bmap2, bmap1);
   9343 	return isl_bool_not(is_subset);
   9344 }
   9345 
   9346 isl_bool isl_map_is_strict_subset(__isl_keep isl_map *map1,
   9347 	__isl_keep isl_map *map2)
   9348 {
   9349 	isl_bool is_subset;
   9350 
   9351 	if (!map1 || !map2)
   9352 		return isl_bool_error;
   9353 	is_subset = isl_map_is_subset(map1, map2);
   9354 	if (is_subset != isl_bool_true)
   9355 		return is_subset;
   9356 	is_subset = isl_map_is_subset(map2, map1);
   9357 	return isl_bool_not(is_subset);
   9358 }
   9359 
   9360 isl_bool isl_set_is_strict_subset(__isl_keep isl_set *set1,
   9361 	__isl_keep isl_set *set2)
   9362 {
   9363 	return isl_map_is_strict_subset(set_to_map(set1), set_to_map(set2));
   9364 }
   9365 
   9366 /* Is "bmap" obviously equal to the universe with the same space?
   9367  *
   9368  * That is, does it not have any constraints?
   9369  */
   9370 isl_bool isl_basic_map_plain_is_universe(__isl_keep isl_basic_map *bmap)
   9371 {
   9372 	if (!bmap)
   9373 		return isl_bool_error;
   9374 	return bmap->n_eq == 0 && bmap->n_ineq == 0;
   9375 }
   9376 
   9377 /* Is "bset" obviously equal to the universe with the same space?
   9378  */
   9379 isl_bool isl_basic_set_plain_is_universe(__isl_keep isl_basic_set *bset)
   9380 {
   9381 	return isl_basic_map_plain_is_universe(bset);
   9382 }
   9383 
   9384 /* If "c" does not involve any existentially quantified variables,
   9385  * then set *univ to false and abort
   9386  */
   9387 static isl_stat involves_divs(__isl_take isl_constraint *c, void *user)
   9388 {
   9389 	isl_bool *univ = user;
   9390 	isl_size n;
   9391 
   9392 	n = isl_constraint_dim(c, isl_dim_div);
   9393 	if (n < 0)
   9394 		c = isl_constraint_free(c);
   9395 	*univ = isl_constraint_involves_dims(c, isl_dim_div, 0, n);
   9396 	isl_constraint_free(c);
   9397 	if (*univ < 0 || !*univ)
   9398 		return isl_stat_error;
   9399 	return isl_stat_ok;
   9400 }
   9401 
   9402 /* Is "bmap" equal to the universe with the same space?
   9403  *
   9404  * First check if it is obviously equal to the universe.
   9405  * If not and if there are any constraints not involving
   9406  * existentially quantified variables, then it is certainly
   9407  * not equal to the universe.
   9408  * Otherwise, check if the universe is a subset of "bmap".
   9409  */
   9410 isl_bool isl_basic_map_is_universe(__isl_keep isl_basic_map *bmap)
   9411 {
   9412 	isl_size n_div;
   9413 	isl_bool univ;
   9414 	isl_basic_map *test;
   9415 
   9416 	univ = isl_basic_map_plain_is_universe(bmap);
   9417 	if (univ < 0 || univ)
   9418 		return univ;
   9419 	n_div = isl_basic_map_dim(bmap, isl_dim_div);
   9420 	if (n_div < 0)
   9421 		return isl_bool_error;
   9422 	if (n_div == 0)
   9423 		return isl_bool_false;
   9424 	univ = isl_bool_true;
   9425 	if (isl_basic_map_foreach_constraint(bmap, &involves_divs, &univ) < 0 &&
   9426 	    univ)
   9427 		return isl_bool_error;
   9428 	if (univ < 0 || !univ)
   9429 		return univ;
   9430 	test = isl_basic_map_universe(isl_basic_map_get_space(bmap));
   9431 	univ = isl_basic_map_is_subset(test, bmap);
   9432 	isl_basic_map_free(test);
   9433 	return univ;
   9434 }
   9435 
   9436 /* Is "bset" equal to the universe with the same space?
   9437  */
   9438 isl_bool isl_basic_set_is_universe(__isl_keep isl_basic_set *bset)
   9439 {
   9440 	return isl_basic_map_is_universe(bset);
   9441 }
   9442 
   9443 isl_bool isl_map_plain_is_universe(__isl_keep isl_map *map)
   9444 {
   9445 	int i;
   9446 
   9447 	if (!map)
   9448 		return isl_bool_error;
   9449 
   9450 	for (i = 0; i < map->n; ++i) {
   9451 		isl_bool r = isl_basic_map_plain_is_universe(map->p[i]);
   9452 		if (r < 0 || r)
   9453 			return r;
   9454 	}
   9455 
   9456 	return isl_bool_false;
   9457 }
   9458 
   9459 isl_bool isl_set_plain_is_universe(__isl_keep isl_set *set)
   9460 {
   9461 	return isl_map_plain_is_universe(set_to_map(set));
   9462 }
   9463 
   9464 isl_bool isl_basic_map_is_empty(__isl_keep isl_basic_map *bmap)
   9465 {
   9466 	struct isl_basic_set *bset = NULL;
   9467 	struct isl_vec *sample = NULL;
   9468 	isl_bool empty, non_empty;
   9469 
   9470 	if (!bmap)
   9471 		return isl_bool_error;
   9472 
   9473 	if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
   9474 		return isl_bool_true;
   9475 
   9476 	if (isl_basic_map_plain_is_universe(bmap))
   9477 		return isl_bool_false;
   9478 
   9479 	if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) {
   9480 		struct isl_basic_map *copy = isl_basic_map_copy(bmap);
   9481 		copy = isl_basic_map_remove_redundancies(copy);
   9482 		empty = isl_basic_map_plain_is_empty(copy);
   9483 		isl_basic_map_free(copy);
   9484 		return empty;
   9485 	}
   9486 
   9487 	non_empty = isl_basic_map_plain_is_non_empty(bmap);
   9488 	if (non_empty < 0)
   9489 		return isl_bool_error;
   9490 	if (non_empty)
   9491 		return isl_bool_false;
   9492 	isl_vec_free(bmap->sample);
   9493 	bmap->sample = NULL;
   9494 	bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap));
   9495 	if (!bset)
   9496 		return isl_bool_error;
   9497 	sample = isl_basic_set_sample_vec(bset);
   9498 	if (!sample)
   9499 		return isl_bool_error;
   9500 	empty = sample->size == 0;
   9501 	isl_vec_free(bmap->sample);
   9502 	bmap->sample = sample;
   9503 	if (empty)
   9504 		ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY);
   9505 
   9506 	return empty;
   9507 }
   9508 
   9509 isl_bool isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap)
   9510 {
   9511 	if (!bmap)
   9512 		return isl_bool_error;
   9513 	return ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY);
   9514 }
   9515 
   9516 isl_bool isl_basic_set_plain_is_empty(__isl_keep isl_basic_set *bset)
   9517 {
   9518 	if (!bset)
   9519 		return isl_bool_error;
   9520 	return ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY);
   9521 }
   9522 
   9523 /* Is "bmap" known to be non-empty?
   9524  *
   9525  * That is, is the cached sample still valid?
   9526  */
   9527 isl_bool isl_basic_map_plain_is_non_empty(__isl_keep isl_basic_map *bmap)
   9528 {
   9529 	isl_size total;
   9530 
   9531 	if (!bmap)
   9532 		return isl_bool_error;
   9533 	if (!bmap->sample)
   9534 		return isl_bool_false;
   9535 	total = isl_basic_map_dim(bmap, isl_dim_all);
   9536 	if (total < 0)
   9537 		return isl_bool_error;
   9538 	if (bmap->sample->size != 1 + total)
   9539 		return isl_bool_false;
   9540 	return isl_basic_map_contains(bmap, bmap->sample);
   9541 }
   9542 
   9543 isl_bool isl_basic_set_is_empty(__isl_keep isl_basic_set *bset)
   9544 {
   9545 	return isl_basic_map_is_empty(bset_to_bmap(bset));
   9546 }
   9547 
   9548 __isl_give isl_map *isl_basic_map_union(__isl_take isl_basic_map *bmap1,
   9549 	__isl_take isl_basic_map *bmap2)
   9550 {
   9551 	struct isl_map *map;
   9552 
   9553 	if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
   9554 		goto error;
   9555 
   9556 	map = isl_map_alloc_space(isl_space_copy(bmap1->dim), 2, 0);
   9557 	if (!map)
   9558 		goto error;
   9559 	map = isl_map_add_basic_map(map, bmap1);
   9560 	map = isl_map_add_basic_map(map, bmap2);
   9561 	return map;
   9562 error:
   9563 	isl_basic_map_free(bmap1);
   9564 	isl_basic_map_free(bmap2);
   9565 	return NULL;
   9566 }
   9567 
   9568 __isl_give isl_set *isl_basic_set_union(__isl_take isl_basic_set *bset1,
   9569 	__isl_take isl_basic_set *bset2)
   9570 {
   9571 	return set_from_map(isl_basic_map_union(bset_to_bmap(bset1),
   9572 						bset_to_bmap(bset2)));
   9573 }
   9574 
   9575 /* Order divs such that any div only depends on previous divs */
   9576 __isl_give isl_basic_map *isl_basic_map_order_divs(
   9577 	__isl_take isl_basic_map *bmap)
   9578 {
   9579 	int i;
   9580 	isl_size off;
   9581 
   9582 	off = isl_basic_map_var_offset(bmap, isl_dim_div);
   9583 	if (off < 0)
   9584 		return isl_basic_map_free(bmap);
   9585 
   9586 	for (i = 0; i < bmap->n_div; ++i) {
   9587 		int pos;
   9588 		if (isl_int_is_zero(bmap->div[i][0]))
   9589 			continue;
   9590 		pos = isl_seq_first_non_zero(bmap->div[i]+1+1+off+i,
   9591 							    bmap->n_div-i);
   9592 		if (pos == -1)
   9593 			continue;
   9594 		if (pos == 0)
   9595 			isl_die(isl_basic_map_get_ctx(bmap), isl_error_internal,
   9596 				"integer division depends on itself",
   9597 				return isl_basic_map_free(bmap));
   9598 		bmap = isl_basic_map_swap_div(bmap, i, i + pos);
   9599 		if (!bmap)
   9600 			return NULL;
   9601 		--i;
   9602 	}
   9603 	return bmap;
   9604 }
   9605 
   9606 __isl_give isl_map *isl_map_order_divs(__isl_take isl_map *map)
   9607 {
   9608 	int i;
   9609 
   9610 	if (!map)
   9611 		return 0;
   9612 
   9613 	for (i = 0; i < map->n; ++i) {
   9614 		map->p[i] = isl_basic_map_order_divs(map->p[i]);
   9615 		if (!map->p[i])
   9616 			goto error;
   9617 	}
   9618 
   9619 	return map;
   9620 error:
   9621 	isl_map_free(map);
   9622 	return NULL;
   9623 }
   9624 
   9625 /* Sort the local variables of "bset".
   9626  */
   9627 __isl_give isl_basic_set *isl_basic_set_sort_divs(
   9628 	__isl_take isl_basic_set *bset)
   9629 {
   9630 	return bset_from_bmap(isl_basic_map_sort_divs(bset_to_bmap(bset)));
   9631 }
   9632 
   9633 /* Apply the expansion computed by isl_merge_divs.
   9634  * The expansion itself is given by "exp" while the resulting
   9635  * list of divs is given by "div".
   9636  *
   9637  * Move the integer divisions of "bmap" into the right position
   9638  * according to "exp" and then introduce the additional integer
   9639  * divisions, adding div constraints.
   9640  * The moving should be done first to avoid moving coefficients
   9641  * in the definitions of the extra integer divisions.
   9642  */
   9643 __isl_give isl_basic_map *isl_basic_map_expand_divs(
   9644 	__isl_take isl_basic_map *bmap, __isl_take isl_mat *div, int *exp)
   9645 {
   9646 	int i, j;
   9647 	int n_div;
   9648 
   9649 	bmap = isl_basic_map_cow(bmap);
   9650 	if (!bmap || !div)
   9651 		goto error;
   9652 
   9653 	if (div->n_row < bmap->n_div)
   9654 		isl_die(isl_mat_get_ctx(div), isl_error_invalid,
   9655 			"not an expansion", goto error);
   9656 
   9657 	n_div = bmap->n_div;
   9658 	bmap = isl_basic_map_extend(bmap, div->n_row - n_div, 0,
   9659 					    2 * (div->n_row - n_div));
   9660 
   9661 	for (i = n_div; i < div->n_row; ++i)
   9662 		if (isl_basic_map_alloc_div(bmap) < 0)
   9663 			goto error;
   9664 
   9665 	for (j = n_div - 1; j >= 0; --j) {
   9666 		if (exp[j] == j)
   9667 			break;
   9668 		bmap = isl_basic_map_swap_div(bmap, j, exp[j]);
   9669 		if (!bmap)
   9670 			goto error;
   9671 	}
   9672 	j = 0;
   9673 	for (i = 0; i < div->n_row; ++i) {
   9674 		if (j < n_div && exp[j] == i) {
   9675 			j++;
   9676 		} else {
   9677 			isl_seq_cpy(bmap->div[i], div->row[i], div->n_col);
   9678 			if (isl_basic_map_div_is_marked_unknown(bmap, i))
   9679 				continue;
   9680 			bmap = isl_basic_map_add_div_constraints(bmap, i);
   9681 			if (!bmap)
   9682 				goto error;
   9683 		}
   9684 	}
   9685 
   9686 	isl_mat_free(div);
   9687 	return bmap;
   9688 error:
   9689 	isl_basic_map_free(bmap);
   9690 	isl_mat_free(div);
   9691 	return NULL;
   9692 }
   9693 
   9694 /* Apply the expansion computed by isl_merge_divs.
   9695  * The expansion itself is given by "exp" while the resulting
   9696  * list of divs is given by "div".
   9697  */
   9698 __isl_give isl_basic_set *isl_basic_set_expand_divs(
   9699 	__isl_take isl_basic_set *bset, __isl_take isl_mat *div, int *exp)
   9700 {
   9701 	return isl_basic_map_expand_divs(bset, div, exp);
   9702 }
   9703 
   9704 /* Look for a div in dst that corresponds to the div "div" in src.
   9705  * The divs before "div" in src and dst are assumed to be the same.
   9706  *
   9707  * Return the position of the corresponding div in dst
   9708  * if there is one.  Otherwise, return a position beyond the integer divisions.
   9709  * Return -1 on error.
   9710  */
   9711 static int find_div(__isl_keep isl_basic_map *dst,
   9712 	__isl_keep isl_basic_map *src, unsigned div)
   9713 {
   9714 	int i;
   9715 	isl_size n_div;
   9716 	isl_size v_div;
   9717 
   9718 	v_div = isl_basic_map_var_offset(src, isl_dim_div);
   9719 	n_div = isl_basic_map_dim(dst, isl_dim_div);
   9720 	if (n_div < 0 || v_div < 0)
   9721 		return -1;
   9722 	isl_assert(dst->ctx, div <= n_div, return -1);
   9723 	for (i = div; i < n_div; ++i)
   9724 		if (isl_seq_eq(dst->div[i], src->div[div], 1+1+v_div+div) &&
   9725 		    isl_seq_first_non_zero(dst->div[i] + 1 + 1 + v_div + div,
   9726 						n_div - div) == -1)
   9727 			return i;
   9728 	return n_div;
   9729 }
   9730 
   9731 /* Align the divs of "dst" to those of "src", adding divs from "src"
   9732  * if needed.  That is, make sure that the first src->n_div divs
   9733  * of the result are equal to those of src.
   9734  * The integer division of "src" are assumed to be ordered.
   9735  *
   9736  * The integer divisions are swapped into the right position
   9737  * (possibly after adding them first).  This may result
   9738  * in the remaining integer divisions appearing in the wrong order,
   9739  * i.e., with some integer division appearing before
   9740  * some other integer division on which it depends.
   9741  * The integer divisions therefore need to be ordered.
   9742  * This will not affect the integer divisions aligned to those of "src",
   9743  * since "src" is assumed to have ordered integer divisions.
   9744  *
   9745  * The result is not finalized as by design it will have redundant
   9746  * divs if any divs from "src" were copied.
   9747  */
   9748 __isl_give isl_basic_map *isl_basic_map_align_divs(
   9749 	__isl_take isl_basic_map *dst, __isl_keep isl_basic_map *src)
   9750 {
   9751 	int i;
   9752 	isl_bool known;
   9753 	int extended;
   9754 	isl_size v_div;
   9755 	isl_size dst_n_div;
   9756 
   9757 	if (!dst || !src)
   9758 		return isl_basic_map_free(dst);
   9759 
   9760 	if (src->n_div == 0)
   9761 		return dst;
   9762 
   9763 	known = isl_basic_map_divs_known(src);
   9764 	if (known < 0)
   9765 		return isl_basic_map_free(dst);
   9766 	if (!known)
   9767 		isl_die(isl_basic_map_get_ctx(src), isl_error_invalid,
   9768 			"some src divs are unknown",
   9769 			return isl_basic_map_free(dst));
   9770 
   9771 	v_div = isl_basic_map_var_offset(src, isl_dim_div);
   9772 	if (v_div < 0)
   9773 		return isl_basic_map_free(dst);
   9774 
   9775 	extended = 0;
   9776 	dst_n_div = isl_basic_map_dim(dst, isl_dim_div);
   9777 	if (dst_n_div < 0)
   9778 		dst = isl_basic_map_free(dst);
   9779 	for (i = 0; i < src->n_div; ++i) {
   9780 		int j = find_div(dst, src, i);
   9781 		if (j < 0)
   9782 			dst = isl_basic_map_free(dst);
   9783 		if (j == dst_n_div) {
   9784 			if (!extended) {
   9785 				int extra = src->n_div - i;
   9786 				dst = isl_basic_map_cow(dst);
   9787 				if (!dst)
   9788 					return isl_basic_map_free(dst);
   9789 				dst = isl_basic_map_extend(dst,
   9790 						extra, 0, 2 * extra);
   9791 				extended = 1;
   9792 			}
   9793 			j = isl_basic_map_alloc_div(dst);
   9794 			if (j < 0)
   9795 				return isl_basic_map_free(dst);
   9796 			isl_seq_cpy(dst->div[j], src->div[i], 1+1+v_div+i);
   9797 			isl_seq_clr(dst->div[j]+1+1+v_div+i, dst->n_div - i);
   9798 			dst_n_div++;
   9799 			dst = isl_basic_map_add_div_constraints(dst, j);
   9800 			if (!dst)
   9801 				return isl_basic_map_free(dst);
   9802 		}
   9803 		if (j != i)
   9804 			dst = isl_basic_map_swap_div(dst, i, j);
   9805 		if (!dst)
   9806 			return isl_basic_map_free(dst);
   9807 	}
   9808 	return isl_basic_map_order_divs(dst);
   9809 }
   9810 
   9811 __isl_give isl_map *isl_map_align_divs_internal(__isl_take isl_map *map)
   9812 {
   9813 	int i;
   9814 
   9815 	if (!map)
   9816 		return NULL;
   9817 	if (map->n == 0)
   9818 		return map;
   9819 	map = isl_map_compute_divs(map);
   9820 	map = isl_map_order_divs(map);
   9821 	map = isl_map_cow(map);
   9822 	if (!map)
   9823 		return NULL;
   9824 
   9825 	for (i = 1; i < map->n; ++i)
   9826 		map->p[0] = isl_basic_map_align_divs(map->p[0], map->p[i]);
   9827 	for (i = 1; i < map->n; ++i) {
   9828 		map->p[i] = isl_basic_map_align_divs(map->p[i], map->p[0]);
   9829 		if (!map->p[i])
   9830 			return isl_map_free(map);
   9831 	}
   9832 
   9833 	map = isl_map_unmark_normalized(map);
   9834 	return map;
   9835 }
   9836 
   9837 __isl_give isl_map *isl_map_align_divs(__isl_take isl_map *map)
   9838 {
   9839 	return isl_map_align_divs_internal(map);
   9840 }
   9841 
   9842 __isl_give isl_set *isl_set_align_divs(__isl_take isl_set *set)
   9843 {
   9844 	return set_from_map(isl_map_align_divs_internal(set_to_map(set)));
   9845 }
   9846 
   9847 /* Align the divs of the basic maps in "map" to those
   9848  * of the basic maps in "list", as well as to the other basic maps in "map".
   9849  * The elements in "list" are assumed to have known divs.
   9850  */
   9851 __isl_give isl_map *isl_map_align_divs_to_basic_map_list(
   9852 	__isl_take isl_map *map, __isl_keep isl_basic_map_list *list)
   9853 {
   9854 	int i;
   9855 	isl_size n;
   9856 
   9857 	n = isl_basic_map_list_n_basic_map(list);
   9858 	map = isl_map_compute_divs(map);
   9859 	map = isl_map_cow(map);
   9860 	if (!map || n < 0)
   9861 		return isl_map_free(map);
   9862 	if (map->n == 0)
   9863 		return map;
   9864 
   9865 	for (i = 0; i < n; ++i) {
   9866 		isl_basic_map *bmap;
   9867 
   9868 		bmap = isl_basic_map_list_get_basic_map(list, i);
   9869 		bmap = isl_basic_map_order_divs(bmap);
   9870 		map->p[0] = isl_basic_map_align_divs(map->p[0], bmap);
   9871 		isl_basic_map_free(bmap);
   9872 	}
   9873 	if (!map->p[0])
   9874 		return isl_map_free(map);
   9875 
   9876 	return isl_map_align_divs_internal(map);
   9877 }
   9878 
   9879 /* Align the divs of each element of "list" to those of "bmap".
   9880  * Both "bmap" and the elements of "list" are assumed to have known divs.
   9881  */
   9882 __isl_give isl_basic_map_list *isl_basic_map_list_align_divs_to_basic_map(
   9883 	__isl_take isl_basic_map_list *list, __isl_keep isl_basic_map *bmap)
   9884 {
   9885 	int i;
   9886 	isl_size n;
   9887 
   9888 	n = isl_basic_map_list_n_basic_map(list);
   9889 	if (n < 0 || !bmap)
   9890 		return isl_basic_map_list_free(list);
   9891 
   9892 	for (i = 0; i < n; ++i) {
   9893 		isl_basic_map *bmap_i;
   9894 
   9895 		bmap_i = isl_basic_map_list_get_basic_map(list, i);
   9896 		bmap_i = isl_basic_map_align_divs(bmap_i, bmap);
   9897 		list = isl_basic_map_list_set_basic_map(list, i, bmap_i);
   9898 	}
   9899 
   9900 	return list;
   9901 }
   9902 
   9903 __isl_give isl_set *isl_set_apply( __isl_take isl_set *set,
   9904 	__isl_take isl_map *map)
   9905 {
   9906 	isl_bool ok;
   9907 
   9908 	isl_map_align_params_set(&map, &set);
   9909 	ok = isl_map_compatible_domain(map, set);
   9910 	if (ok < 0)
   9911 		goto error;
   9912 	if (!ok)
   9913 		isl_die(isl_set_get_ctx(set), isl_error_invalid,
   9914 			"incompatible spaces", goto error);
   9915 	map = isl_map_intersect_domain(map, set);
   9916 	set = isl_map_range(map);
   9917 	return set;
   9918 error:
   9919 	isl_set_free(set);
   9920 	isl_map_free(map);
   9921 	return NULL;
   9922 }
   9923 
   9924 /* There is no need to cow as removing empty parts doesn't change
   9925  * the meaning of the set.
   9926  */
   9927 __isl_give isl_map *isl_map_remove_empty_parts(__isl_take isl_map *map)
   9928 {
   9929 	int i;
   9930 
   9931 	if (!map)
   9932 		return NULL;
   9933 
   9934 	for (i = map->n - 1; i >= 0; --i)
   9935 		map = remove_if_empty(map, i);
   9936 
   9937 	return map;
   9938 }
   9939 
   9940 __isl_give isl_set *isl_set_remove_empty_parts(__isl_take isl_set *set)
   9941 {
   9942 	return set_from_map(isl_map_remove_empty_parts(set_to_map(set)));
   9943 }
   9944 
   9945 /* Create a binary relation that maps the shared initial "pos" dimensions
   9946  * of "bset1" and "bset2" to the remaining dimensions of "bset1" and "bset2".
   9947  */
   9948 static __isl_give isl_basic_map *join_initial(__isl_keep isl_basic_set *bset1,
   9949 	__isl_keep isl_basic_set *bset2, int pos)
   9950 {
   9951 	isl_basic_map *bmap1;
   9952 	isl_basic_map *bmap2;
   9953 
   9954 	bmap1 = isl_basic_map_from_range(isl_basic_set_copy(bset1));
   9955 	bmap2 = isl_basic_map_from_range(isl_basic_set_copy(bset2));
   9956 	bmap1 = isl_basic_map_move_dims(bmap1, isl_dim_in, 0,
   9957 					isl_dim_out, 0, pos);
   9958 	bmap2 = isl_basic_map_move_dims(bmap2, isl_dim_in, 0,
   9959 					isl_dim_out, 0, pos);
   9960 	return isl_basic_map_range_product(bmap1, bmap2);
   9961 }
   9962 
   9963 /* Given two basic sets bset1 and bset2, compute the maximal difference
   9964  * between the values of dimension pos in bset1 and those in bset2
   9965  * for any common value of the parameters and dimensions preceding pos.
   9966  */
   9967 static enum isl_lp_result basic_set_maximal_difference_at(
   9968 	__isl_keep isl_basic_set *bset1, __isl_keep isl_basic_set *bset2,
   9969 	int pos, isl_int *opt)
   9970 {
   9971 	isl_basic_map *bmap1;
   9972 	struct isl_ctx *ctx;
   9973 	struct isl_vec *obj;
   9974 	isl_size total;
   9975 	isl_size nparam;
   9976 	isl_size dim1;
   9977 	enum isl_lp_result res;
   9978 
   9979 	nparam = isl_basic_set_dim(bset1, isl_dim_param);
   9980 	dim1 = isl_basic_set_dim(bset1, isl_dim_set);
   9981 	if (nparam < 0 || dim1 < 0 || !bset2)
   9982 		return isl_lp_error;
   9983 
   9984 	bmap1 = join_initial(bset1, bset2, pos);
   9985 	total = isl_basic_map_dim(bmap1, isl_dim_all);
   9986 	if (total < 0)
   9987 		return isl_lp_error;
   9988 
   9989 	ctx = bmap1->ctx;
   9990 	obj = isl_vec_alloc(ctx, 1 + total);
   9991 	if (!obj)
   9992 		goto error;
   9993 	isl_seq_clr(obj->block.data, 1 + total);
   9994 	isl_int_set_si(obj->block.data[1+nparam+pos], 1);
   9995 	isl_int_set_si(obj->block.data[1+nparam+pos+(dim1-pos)], -1);
   9996 	res = isl_basic_map_solve_lp(bmap1, 1, obj->block.data, ctx->one,
   9997 					opt, NULL, NULL);
   9998 	isl_basic_map_free(bmap1);
   9999 	isl_vec_free(obj);
   10000 	return res;
   10001 error:
   10002 	isl_basic_map_free(bmap1);
   10003 	return isl_lp_error;
   10004 }
   10005 
   10006 /* Given two _disjoint_ basic sets bset1 and bset2, check whether
   10007  * for any common value of the parameters and dimensions preceding pos
   10008  * in both basic sets, the values of dimension pos in bset1 are
   10009  * smaller or larger than those in bset2.
   10010  *
   10011  * Returns
   10012  *	 1 if bset1 follows bset2
   10013  *	-1 if bset1 precedes bset2
   10014  *	 0 if bset1 and bset2 are incomparable
   10015  *	-2 if some error occurred.
   10016  */
   10017 int isl_basic_set_compare_at(__isl_keep isl_basic_set *bset1,
   10018 	__isl_keep isl_basic_set *bset2, int pos)
   10019 {
   10020 	isl_int opt;
   10021 	enum isl_lp_result res;
   10022 	int cmp;
   10023 
   10024 	isl_int_init(opt);
   10025 
   10026 	res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt);
   10027 
   10028 	if (res == isl_lp_empty)
   10029 		cmp = 0;
   10030 	else if ((res == isl_lp_ok && isl_int_is_pos(opt)) ||
   10031 		  res == isl_lp_unbounded)
   10032 		cmp = 1;
   10033 	else if (res == isl_lp_ok && isl_int_is_neg(opt))
   10034 		cmp = -1;
   10035 	else
   10036 		cmp = -2;
   10037 
   10038 	isl_int_clear(opt);
   10039 	return cmp;
   10040 }
   10041 
   10042 /* Given two basic sets bset1 and bset2, check whether
   10043  * for any common value of the parameters and dimensions preceding pos
   10044  * there is a value of dimension pos in bset1 that is larger
   10045  * than a value of the same dimension in bset2.
   10046  *
   10047  * Return
   10048  *	 1 if there exists such a pair
   10049  *	 0 if there is no such pair, but there is a pair of equal values
   10050  *	-1 otherwise
   10051  *	-2 if some error occurred.
   10052  */
   10053 int isl_basic_set_follows_at(__isl_keep isl_basic_set *bset1,
   10054 	__isl_keep isl_basic_set *bset2, int pos)
   10055 {
   10056 	isl_bool empty;
   10057 	isl_basic_map *bmap;
   10058 	isl_size dim1;
   10059 
   10060 	dim1 = isl_basic_set_dim(bset1, isl_dim_set);
   10061 	if (dim1 < 0)
   10062 		return -2;
   10063 	bmap = join_initial(bset1, bset2, pos);
   10064 	bmap = isl_basic_map_order_ge(bmap, isl_dim_out, 0,
   10065 					    isl_dim_out, dim1 - pos);
   10066 	empty = isl_basic_map_is_empty(bmap);
   10067 	if (empty < 0)
   10068 		goto error;
   10069 	if (empty) {
   10070 		isl_basic_map_free(bmap);
   10071 		return -1;
   10072 	}
   10073 	bmap = isl_basic_map_order_gt(bmap, isl_dim_out, 0,
   10074 					    isl_dim_out, dim1 - pos);
   10075 	empty = isl_basic_map_is_empty(bmap);
   10076 	if (empty < 0)
   10077 		goto error;
   10078 	isl_basic_map_free(bmap);
   10079 	if (empty)
   10080 		return 0;
   10081 	return 1;
   10082 error:
   10083 	isl_basic_map_free(bmap);
   10084 	return -2;
   10085 }
   10086 
   10087 /* Given two sets set1 and set2, check whether
   10088  * for any common value of the parameters and dimensions preceding pos
   10089  * there is a value of dimension pos in set1 that is larger
   10090  * than a value of the same dimension in set2.
   10091  *
   10092  * Return
   10093  *	 1 if there exists such a pair
   10094  *	 0 if there is no such pair, but there is a pair of equal values
   10095  *	-1 otherwise
   10096  *	-2 if some error occurred.
   10097  */
   10098 int isl_set_follows_at(__isl_keep isl_set *set1,
   10099 	__isl_keep isl_set *set2, int pos)
   10100 {
   10101 	int i, j;
   10102 	int follows = -1;
   10103 
   10104 	if (!set1 || !set2)
   10105 		return -2;
   10106 
   10107 	for (i = 0; i < set1->n; ++i)
   10108 		for (j = 0; j < set2->n; ++j) {
   10109 			int f;
   10110 			f = isl_basic_set_follows_at(set1->p[i], set2->p[j], pos);
   10111 			if (f == 1 || f == -2)
   10112 				return f;
   10113 			if (f > follows)
   10114 				follows = f;
   10115 		}
   10116 
   10117 	return follows;
   10118 }
   10119 
   10120 static isl_bool isl_basic_map_plain_has_fixed_var(
   10121 	__isl_keep isl_basic_map *bmap, unsigned pos, isl_int *val)
   10122 {
   10123 	int i;
   10124 	int d;
   10125 	isl_size total;
   10126 
   10127 	total = isl_basic_map_dim(bmap, isl_dim_all);
   10128 	if (total < 0)
   10129 		return isl_bool_error;
   10130 	for (i = 0, d = total-1; i < bmap->n_eq && d+1 > pos; ++i) {
   10131 		for (; d+1 > pos; --d)
   10132 			if (!isl_int_is_zero(bmap->eq[i][1+d]))
   10133 				break;
   10134 		if (d != pos)
   10135 			continue;
   10136 		if (isl_seq_first_non_zero(bmap->eq[i]+1, d) != -1)
   10137 			return isl_bool_false;
   10138 		if (isl_seq_first_non_zero(bmap->eq[i]+1+d+1, total-d-1) != -1)
   10139 			return isl_bool_false;
   10140 		if (!isl_int_is_one(bmap->eq[i][1+d]))
   10141 			return isl_bool_false;
   10142 		if (val)
   10143 			isl_int_neg(*val, bmap->eq[i][0]);
   10144 		return isl_bool_true;
   10145 	}
   10146 	return isl_bool_false;
   10147 }
   10148 
   10149 static isl_bool isl_map_plain_has_fixed_var(__isl_keep isl_map *map,
   10150 	unsigned pos, isl_int *val)
   10151 {
   10152 	int i;
   10153 	isl_int v;
   10154 	isl_int tmp;
   10155 	isl_bool fixed;
   10156 
   10157 	if (!map)
   10158 		return isl_bool_error;
   10159 	if (map->n == 0)
   10160 		return isl_bool_false;
   10161 	if (map->n == 1)
   10162 		return isl_basic_map_plain_has_fixed_var(map->p[0], pos, val);
   10163 	isl_int_init(v);
   10164 	isl_int_init(tmp);
   10165 	fixed = isl_basic_map_plain_has_fixed_var(map->p[0], pos, &v);
   10166 	for (i = 1; fixed == isl_bool_true && i < map->n; ++i) {
   10167 		fixed = isl_basic_map_plain_has_fixed_var(map->p[i], pos, &tmp);
   10168 		if (fixed == isl_bool_true && isl_int_ne(tmp, v))
   10169 			fixed = isl_bool_false;
   10170 	}
   10171 	if (val)
   10172 		isl_int_set(*val, v);
   10173 	isl_int_clear(tmp);
   10174 	isl_int_clear(v);
   10175 	return fixed;
   10176 }
   10177 
   10178 static isl_bool isl_basic_set_plain_has_fixed_var(
   10179 	__isl_keep isl_basic_set *bset, unsigned pos, isl_int *val)
   10180 {
   10181 	return isl_basic_map_plain_has_fixed_var(bset_to_bmap(bset),
   10182 						pos, val);
   10183 }
   10184 
   10185 isl_bool isl_basic_map_plain_is_fixed(__isl_keep isl_basic_map *bmap,
   10186 	enum isl_dim_type type, unsigned pos, isl_int *val)
   10187 {
   10188 	if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
   10189 		return isl_bool_error;
   10190 	return isl_basic_map_plain_has_fixed_var(bmap,
   10191 		isl_basic_map_offset(bmap, type) - 1 + pos, val);
   10192 }
   10193 
   10194 /* If "bmap" obviously lies on a hyperplane where the given dimension
   10195  * has a fixed value, then return that value.
   10196  * Otherwise return NaN.
   10197  */
   10198 __isl_give isl_val *isl_basic_map_plain_get_val_if_fixed(
   10199 	__isl_keep isl_basic_map *bmap,
   10200 	enum isl_dim_type type, unsigned pos)
   10201 {
   10202 	isl_ctx *ctx;
   10203 	isl_val *v;
   10204 	isl_bool fixed;
   10205 
   10206 	if (!bmap)
   10207 		return NULL;
   10208 	ctx = isl_basic_map_get_ctx(bmap);
   10209 	v = isl_val_alloc(ctx);
   10210 	if (!v)
   10211 		return NULL;
   10212 	fixed = isl_basic_map_plain_is_fixed(bmap, type, pos, &v->n);
   10213 	if (fixed < 0)
   10214 		return isl_val_free(v);
   10215 	if (fixed) {
   10216 		isl_int_set_si(v->d, 1);
   10217 		return v;
   10218 	}
   10219 	isl_val_free(v);
   10220 	return isl_val_nan(ctx);
   10221 }
   10222 
   10223 isl_bool isl_map_plain_is_fixed(__isl_keep isl_map *map,
   10224 	enum isl_dim_type type, unsigned pos, isl_int *val)
   10225 {
   10226 	if (isl_map_check_range(map, type, pos, 1) < 0)
   10227 		return isl_bool_error;
   10228 	return isl_map_plain_has_fixed_var(map,
   10229 		map_offset(map, type) - 1 + pos, val);
   10230 }
   10231 
   10232 /* If "map" obviously lies on a hyperplane where the given dimension
   10233  * has a fixed value, then return that value.
   10234  * Otherwise return NaN.
   10235  */
   10236 __isl_give isl_val *isl_map_plain_get_val_if_fixed(__isl_keep isl_map *map,
   10237 	enum isl_dim_type type, unsigned pos)
   10238 {
   10239 	isl_ctx *ctx;
   10240 	isl_val *v;
   10241 	isl_bool fixed;
   10242 
   10243 	if (!map)
   10244 		return NULL;
   10245 	ctx = isl_map_get_ctx(map);
   10246 	v = isl_val_alloc(ctx);
   10247 	if (!v)
   10248 		return NULL;
   10249 	fixed = isl_map_plain_is_fixed(map, type, pos, &v->n);
   10250 	if (fixed < 0)
   10251 		return isl_val_free(v);
   10252 	if (fixed) {
   10253 		isl_int_set_si(v->d, 1);
   10254 		return v;
   10255 	}
   10256 	isl_val_free(v);
   10257 	return isl_val_nan(ctx);
   10258 }
   10259 
   10260 /* If "set" obviously lies on a hyperplane where the given dimension
   10261  * has a fixed value, then return that value.
   10262  * Otherwise return NaN.
   10263  */
   10264 __isl_give isl_val *isl_set_plain_get_val_if_fixed(__isl_keep isl_set *set,
   10265 	enum isl_dim_type type, unsigned pos)
   10266 {
   10267 	return isl_map_plain_get_val_if_fixed(set, type, pos);
   10268 }
   10269 
   10270 /* Return a sequence of values in the same space as "set"
   10271  * that are equal to the corresponding set dimensions of "set"
   10272  * for those set dimensions that obviously lie on a hyperplane
   10273  * where the dimension has a fixed value.
   10274  * The other elements are set to NaN.
   10275  */
   10276 __isl_give isl_multi_val *isl_set_get_plain_multi_val_if_fixed(
   10277 	__isl_keep isl_set *set)
   10278 {
   10279 	int i;
   10280 	isl_size n;
   10281 	isl_space *space;
   10282 	isl_multi_val *mv;
   10283 
   10284 	space = isl_space_drop_all_params(isl_set_get_space(set));
   10285 	mv = isl_multi_val_alloc(space);
   10286 	n = isl_multi_val_size(mv);
   10287 	if (n < 0)
   10288 		return isl_multi_val_free(mv);
   10289 
   10290 	for (i = 0; i < n; ++i) {
   10291 		isl_val *v;
   10292 
   10293 		v = isl_set_plain_get_val_if_fixed(set, isl_dim_set, i);
   10294 		mv = isl_multi_val_set_val(mv, i, v);
   10295 	}
   10296 
   10297 	return mv;
   10298 }
   10299 
   10300 /* Check if dimension dim has fixed value and if so and if val is not NULL,
   10301  * then return this fixed value in *val.
   10302  */
   10303 isl_bool isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_set *bset,
   10304 	unsigned dim, isl_int *val)
   10305 {
   10306 	isl_size nparam;
   10307 
   10308 	nparam = isl_basic_set_dim(bset, isl_dim_param);
   10309 	if (nparam < 0)
   10310 		return isl_bool_error;
   10311 	return isl_basic_set_plain_has_fixed_var(bset, nparam + dim, val);
   10312 }
   10313 
   10314 /* Return -1 if the constraint "c1" should be sorted before "c2"
   10315  * and 1 if it should be sorted after "c2".
   10316  * Return 0 if the two constraints are the same (up to the constant term).
   10317  *
   10318  * In particular, if a constraint involves later variables than another
   10319  * then it is sorted after this other constraint.
   10320  * uset_gist depends on constraints without existentially quantified
   10321  * variables sorting first.
   10322  *
   10323  * For constraints that have the same latest variable, those
   10324  * with the same coefficient for this latest variable (first in absolute value
   10325  * and then in actual value) are grouped together.
   10326  * This is useful for detecting pairs of constraints that can
   10327  * be chained in their printed representation.
   10328  *
   10329  * Finally, within a group, constraints are sorted according to
   10330  * their coefficients (excluding the constant term).
   10331  */
   10332 static int sort_constraint_cmp(const void *p1, const void *p2, void *arg)
   10333 {
   10334 	isl_int **c1 = (isl_int **) p1;
   10335 	isl_int **c2 = (isl_int **) p2;
   10336 	int l1, l2;
   10337 	unsigned size = *(unsigned *) arg;
   10338 	int cmp;
   10339 
   10340 	l1 = isl_seq_last_non_zero(*c1 + 1, size);
   10341 	l2 = isl_seq_last_non_zero(*c2 + 1, size);
   10342 
   10343 	if (l1 != l2)
   10344 		return l1 - l2;
   10345 
   10346 	cmp = isl_int_abs_cmp((*c1)[1 + l1], (*c2)[1 + l1]);
   10347 	if (cmp != 0)
   10348 		return cmp;
   10349 	cmp = isl_int_cmp((*c1)[1 + l1], (*c2)[1 + l1]);
   10350 	if (cmp != 0)
   10351 		return -cmp;
   10352 
   10353 	return isl_seq_cmp(*c1 + 1, *c2 + 1, size);
   10354 }
   10355 
   10356 /* Return -1 if the constraint "c1" of "bmap" is sorted before "c2"
   10357  * by isl_basic_map_sort_constraints, 1 if it is sorted after "c2"
   10358  * and 0 if the two constraints are the same (up to the constant term).
   10359  */
   10360 int isl_basic_map_constraint_cmp(__isl_keep isl_basic_map *bmap,
   10361 	isl_int *c1, isl_int *c2)
   10362 {
   10363 	isl_size total;
   10364 	unsigned size;
   10365 
   10366 	total = isl_basic_map_dim(bmap, isl_dim_all);
   10367 	if (total < 0)
   10368 		return -2;
   10369 	size = total;
   10370 	return sort_constraint_cmp(&c1, &c2, &size);
   10371 }
   10372 
   10373 __isl_give isl_basic_map *isl_basic_map_sort_constraints(
   10374 	__isl_take isl_basic_map *bmap)
   10375 {
   10376 	isl_size total;
   10377 	unsigned size;
   10378 
   10379 	if (!bmap)
   10380 		return NULL;
   10381 	if (bmap->n_ineq == 0)
   10382 		return bmap;
   10383 	if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_SORTED))
   10384 		return bmap;
   10385 	total = isl_basic_map_dim(bmap, isl_dim_all);
   10386 	if (total < 0)
   10387 		return isl_basic_map_free(bmap);
   10388 	size = total;
   10389 	if (isl_sort(bmap->ineq, bmap->n_ineq, sizeof(isl_int *),
   10390 		    &sort_constraint_cmp, &size) < 0)
   10391 		return isl_basic_map_free(bmap);
   10392 	ISL_F_SET(bmap, ISL_BASIC_MAP_SORTED);
   10393 	return bmap;
   10394 }
   10395 
   10396 __isl_give isl_basic_set *isl_basic_set_sort_constraints(
   10397 	__isl_take isl_basic_set *bset)
   10398 {
   10399 	isl_basic_map *bmap = bset_to_bmap(bset);
   10400 	return bset_from_bmap(isl_basic_map_sort_constraints(bmap));
   10401 }
   10402 
   10403 __isl_give isl_basic_map *isl_basic_map_normalize(
   10404 	__isl_take isl_basic_map *bmap)
   10405 {
   10406 	bmap = isl_basic_map_remove_redundancies(bmap);
   10407 	bmap = isl_basic_map_sort_constraints(bmap);
   10408 	return bmap;
   10409 }
   10410 int isl_basic_map_plain_cmp(__isl_keep isl_basic_map *bmap1,
   10411 	__isl_keep isl_basic_map *bmap2)
   10412 {
   10413 	int i, cmp;
   10414 	isl_size total;
   10415 	isl_space *space1, *space2;
   10416 
   10417 	if (!bmap1 || !bmap2)
   10418 		return -1;
   10419 
   10420 	if (bmap1 == bmap2)
   10421 		return 0;
   10422 	space1 = isl_basic_map_peek_space(bmap1);
   10423 	space2 = isl_basic_map_peek_space(bmap2);
   10424 	cmp = isl_space_cmp(space1, space2);
   10425 	if (cmp)
   10426 		return cmp;
   10427 	if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL) !=
   10428 	    ISL_F_ISSET(bmap2, ISL_BASIC_MAP_RATIONAL))
   10429 		return ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL) ? -1 : 1;
   10430 	if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY) &&
   10431 	    ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
   10432 		return 0;
   10433 	if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY))
   10434 		return 1;
   10435 	if (ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
   10436 		return -1;
   10437 	if (bmap1->n_eq != bmap2->n_eq)
   10438 		return bmap1->n_eq - bmap2->n_eq;
   10439 	if (bmap1->n_ineq != bmap2->n_ineq)
   10440 		return bmap1->n_ineq - bmap2->n_ineq;
   10441 	if (bmap1->n_div != bmap2->n_div)
   10442 		return bmap1->n_div - bmap2->n_div;
   10443 	total = isl_basic_map_dim(bmap1, isl_dim_all);
   10444 	if (total < 0)
   10445 		return -1;
   10446 	for (i = 0; i < bmap1->n_eq; ++i) {
   10447 		cmp = isl_seq_cmp(bmap1->eq[i], bmap2->eq[i], 1+total);
   10448 		if (cmp)
   10449 			return cmp;
   10450 	}
   10451 	for (i = 0; i < bmap1->n_ineq; ++i) {
   10452 		cmp = isl_seq_cmp(bmap1->ineq[i], bmap2->ineq[i], 1+total);
   10453 		if (cmp)
   10454 			return cmp;
   10455 	}
   10456 	for (i = 0; i < bmap1->n_div; ++i) {
   10457 		isl_bool unknown1, unknown2;
   10458 
   10459 		unknown1 = isl_basic_map_div_is_marked_unknown(bmap1, i);
   10460 		unknown2 = isl_basic_map_div_is_marked_unknown(bmap2, i);
   10461 		if (unknown1 < 0 || unknown2 < 0)
   10462 			return -1;
   10463 		if (unknown1 && unknown2)
   10464 			continue;
   10465 		if (unknown1)
   10466 			return 1;
   10467 		if (unknown2)
   10468 			return -1;
   10469 		cmp = isl_seq_cmp(bmap1->div[i], bmap2->div[i], 1+1+total);
   10470 		if (cmp)
   10471 			return cmp;
   10472 	}
   10473 	return 0;
   10474 }
   10475 
   10476 int isl_basic_set_plain_cmp(__isl_keep isl_basic_set *bset1,
   10477 	__isl_keep isl_basic_set *bset2)
   10478 {
   10479 	return isl_basic_map_plain_cmp(bset1, bset2);
   10480 }
   10481 
   10482 int isl_set_plain_cmp(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
   10483 {
   10484 	int i, cmp;
   10485 
   10486 	if (set1 == set2)
   10487 		return 0;
   10488 	if (set1->n != set2->n)
   10489 		return set1->n - set2->n;
   10490 
   10491 	for (i = 0; i < set1->n; ++i) {
   10492 		cmp = isl_basic_set_plain_cmp(set1->p[i], set2->p[i]);
   10493 		if (cmp)
   10494 			return cmp;
   10495 	}
   10496 
   10497 	return 0;
   10498 }
   10499 
   10500 isl_bool isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1,
   10501 	__isl_keep isl_basic_map *bmap2)
   10502 {
   10503 	if (!bmap1 || !bmap2)
   10504 		return isl_bool_error;
   10505 	return isl_basic_map_plain_cmp(bmap1, bmap2) == 0;
   10506 }
   10507 
   10508 isl_bool isl_basic_set_plain_is_equal(__isl_keep isl_basic_set *bset1,
   10509 	__isl_keep isl_basic_set *bset2)
   10510 {
   10511 	return isl_basic_map_plain_is_equal(bset_to_bmap(bset1),
   10512 					    bset_to_bmap(bset2));
   10513 }
   10514 
   10515 static int qsort_bmap_cmp(const void *p1, const void *p2)
   10516 {
   10517 	isl_basic_map *bmap1 = *(isl_basic_map **) p1;
   10518 	isl_basic_map *bmap2 = *(isl_basic_map **) p2;
   10519 
   10520 	return isl_basic_map_plain_cmp(bmap1, bmap2);
   10521 }
   10522 
   10523 /* Sort the basic maps of "map" and remove duplicate basic maps.
   10524  *
   10525  * While removing basic maps, we make sure that the basic maps remain
   10526  * sorted because isl_map_normalize expects the basic maps of the result
   10527  * to be sorted.
   10528  */
   10529 static __isl_give isl_map *sort_and_remove_duplicates(__isl_take isl_map *map)
   10530 {
   10531 	int i, j;
   10532 
   10533 	map = isl_map_remove_empty_parts(map);
   10534 	if (!map)
   10535 		return NULL;
   10536 	qsort(map->p, map->n, sizeof(struct isl_basic_map *), qsort_bmap_cmp);
   10537 	for (i = map->n - 1; i >= 1; --i) {
   10538 		if (!isl_basic_map_plain_is_equal(map->p[i - 1], map->p[i]))
   10539 			continue;
   10540 		isl_basic_map_free(map->p[i-1]);
   10541 		for (j = i; j < map->n; ++j)
   10542 			map->p[j - 1] = map->p[j];
   10543 		map->n--;
   10544 	}
   10545 
   10546 	return map;
   10547 }
   10548 
   10549 /* Remove obvious duplicates among the basic maps of "map".
   10550  *
   10551  * Unlike isl_map_normalize, this function does not remove redundant
   10552  * constraints and only removes duplicates that have exactly the same
   10553  * constraints in the input.  It does sort the constraints and
   10554  * the basic maps to ease the detection of duplicates.
   10555  *
   10556  * If "map" has already been normalized or if the basic maps are
   10557  * disjoint, then there can be no duplicates.
   10558  */
   10559 __isl_give isl_map *isl_map_remove_obvious_duplicates(__isl_take isl_map *map)
   10560 {
   10561 	int i;
   10562 	isl_basic_map *bmap;
   10563 
   10564 	if (!map)
   10565 		return NULL;
   10566 	if (map->n <= 1)
   10567 		return map;
   10568 	if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED | ISL_MAP_DISJOINT))
   10569 		return map;
   10570 	for (i = 0; i < map->n; ++i) {
   10571 		bmap = isl_basic_map_copy(map->p[i]);
   10572 		bmap = isl_basic_map_sort_constraints(bmap);
   10573 		if (!bmap)
   10574 			return isl_map_free(map);
   10575 		isl_basic_map_free(map->p[i]);
   10576 		map->p[i] = bmap;
   10577 	}
   10578 
   10579 	map = sort_and_remove_duplicates(map);
   10580 	return map;
   10581 }
   10582 
   10583 /* We normalize in place, but if anything goes wrong we need
   10584  * to return NULL, so we need to make sure we don't change the
   10585  * meaning of any possible other copies of map.
   10586  */
   10587 __isl_give isl_map *isl_map_normalize(__isl_take isl_map *map)
   10588 {
   10589 	int i;
   10590 	struct isl_basic_map *bmap;
   10591 
   10592 	if (!map)
   10593 		return NULL;
   10594 	if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED))
   10595 		return map;
   10596 	for (i = 0; i < map->n; ++i) {
   10597 		bmap = isl_basic_map_normalize(isl_basic_map_copy(map->p[i]));
   10598 		if (!bmap)
   10599 			goto error;
   10600 		isl_basic_map_free(map->p[i]);
   10601 		map->p[i] = bmap;
   10602 	}
   10603 
   10604 	map = sort_and_remove_duplicates(map);
   10605 	if (map)
   10606 		ISL_F_SET(map, ISL_MAP_NORMALIZED);
   10607 	return map;
   10608 error:
   10609 	isl_map_free(map);
   10610 	return NULL;
   10611 }
   10612 
   10613 __isl_give isl_set *isl_set_normalize(__isl_take isl_set *set)
   10614 {
   10615 	return set_from_map(isl_map_normalize(set_to_map(set)));
   10616 }
   10617 
   10618 isl_bool isl_map_plain_is_equal(__isl_keep isl_map *map1,
   10619 	__isl_keep isl_map *map2)
   10620 {
   10621 	int i;
   10622 	isl_bool equal;
   10623 
   10624 	if (!map1 || !map2)
   10625 		return isl_bool_error;
   10626 
   10627 	if (map1 == map2)
   10628 		return isl_bool_true;
   10629 	equal = isl_map_has_equal_space(map1, map2);
   10630 	if (equal < 0 || !equal)
   10631 		return equal;
   10632 
   10633 	map1 = isl_map_copy(map1);
   10634 	map2 = isl_map_copy(map2);
   10635 	map1 = isl_map_normalize(map1);
   10636 	map2 = isl_map_normalize(map2);
   10637 	if (!map1 || !map2)
   10638 		goto error;
   10639 	equal = map1->n == map2->n;
   10640 	for (i = 0; equal && i < map1->n; ++i) {
   10641 		equal = isl_basic_map_plain_is_equal(map1->p[i], map2->p[i]);
   10642 		if (equal < 0)
   10643 			goto error;
   10644 	}
   10645 	isl_map_free(map1);
   10646 	isl_map_free(map2);
   10647 	return equal;
   10648 error:
   10649 	isl_map_free(map1);
   10650 	isl_map_free(map2);
   10651 	return isl_bool_error;
   10652 }
   10653 
   10654 isl_bool isl_set_plain_is_equal(__isl_keep isl_set *set1,
   10655 	__isl_keep isl_set *set2)
   10656 {
   10657 	return isl_map_plain_is_equal(set_to_map(set1), set_to_map(set2));
   10658 }
   10659 
   10660 /* Return the basic maps in "map" as a list.
   10661  */
   10662 __isl_give isl_basic_map_list *isl_map_get_basic_map_list(
   10663 	__isl_keep isl_map *map)
   10664 {
   10665 	int i;
   10666 	isl_ctx *ctx;
   10667 	isl_basic_map_list *list;
   10668 
   10669 	if (!map)
   10670 		return NULL;
   10671 	ctx = isl_map_get_ctx(map);
   10672 	list = isl_basic_map_list_alloc(ctx, map->n);
   10673 
   10674 	for (i = 0; i < map->n; ++i) {
   10675 		isl_basic_map *bmap;
   10676 
   10677 		bmap = isl_basic_map_copy(map->p[i]);
   10678 		list = isl_basic_map_list_add(list, bmap);
   10679 	}
   10680 
   10681 	return list;
   10682 }
   10683 
   10684 /* Return the intersection of the elements in the non-empty list "list".
   10685  * All elements are assumed to live in the same space.
   10686  */
   10687 __isl_give isl_basic_map *isl_basic_map_list_intersect(
   10688 	__isl_take isl_basic_map_list *list)
   10689 {
   10690 	int i;
   10691 	isl_size n;
   10692 	isl_basic_map *bmap;
   10693 
   10694 	n = isl_basic_map_list_n_basic_map(list);
   10695 	if (n < 0)
   10696 		goto error;
   10697 	if (n < 1)
   10698 		isl_die(isl_basic_map_list_get_ctx(list), isl_error_invalid,
   10699 			"expecting non-empty list", goto error);
   10700 
   10701 	bmap = isl_basic_map_list_get_basic_map(list, 0);
   10702 	for (i = 1; i < n; ++i) {
   10703 		isl_basic_map *bmap_i;
   10704 
   10705 		bmap_i = isl_basic_map_list_get_basic_map(list, i);
   10706 		bmap = isl_basic_map_intersect(bmap, bmap_i);
   10707 	}
   10708 
   10709 	isl_basic_map_list_free(list);
   10710 	return bmap;
   10711 error:
   10712 	isl_basic_map_list_free(list);
   10713 	return NULL;
   10714 }
   10715 
   10716 /* Return the intersection of the elements in the non-empty list "list".
   10717  * All elements are assumed to live in the same space.
   10718  */
   10719 __isl_give isl_basic_set *isl_basic_set_list_intersect(
   10720 	__isl_take isl_basic_set_list *list)
   10721 {
   10722 	return isl_basic_map_list_intersect(list);
   10723 }
   10724 
   10725 /* Return the union of the elements of "list".
   10726  * The list is required to have at least one element.
   10727  */
   10728 __isl_give isl_set *isl_basic_set_list_union(
   10729 	__isl_take isl_basic_set_list *list)
   10730 {
   10731 	int i;
   10732 	isl_size n;
   10733 	isl_space *space;
   10734 	isl_basic_set *bset;
   10735 	isl_set *set;
   10736 
   10737 	n = isl_basic_set_list_n_basic_set(list);
   10738 	if (n < 0)
   10739 		goto error;
   10740 	if (n < 1)
   10741 		isl_die(isl_basic_set_list_get_ctx(list), isl_error_invalid,
   10742 			"expecting non-empty list", goto error);
   10743 
   10744 	bset = isl_basic_set_list_get_basic_set(list, 0);
   10745 	space = isl_basic_set_get_space(bset);
   10746 	isl_basic_set_free(bset);
   10747 
   10748 	set = isl_set_alloc_space(space, n, 0);
   10749 	for (i = 0; i < n; ++i) {
   10750 		bset = isl_basic_set_list_get_basic_set(list, i);
   10751 		set = isl_set_add_basic_set(set, bset);
   10752 	}
   10753 
   10754 	isl_basic_set_list_free(list);
   10755 	return set;
   10756 error:
   10757 	isl_basic_set_list_free(list);
   10758 	return NULL;
   10759 }
   10760 
   10761 /* Return the union of the elements in the non-empty list "list".
   10762  * All elements are assumed to live in the same space.
   10763  */
   10764 __isl_give isl_set *isl_set_list_union(__isl_take isl_set_list *list)
   10765 {
   10766 	int i;
   10767 	isl_size n;
   10768 	isl_set *set;
   10769 
   10770 	n = isl_set_list_n_set(list);
   10771 	if (n < 0)
   10772 		goto error;
   10773 	if (n < 1)
   10774 		isl_die(isl_set_list_get_ctx(list), isl_error_invalid,
   10775 			"expecting non-empty list", goto error);
   10776 
   10777 	set = isl_set_list_get_set(list, 0);
   10778 	for (i = 1; i < n; ++i) {
   10779 		isl_set *set_i;
   10780 
   10781 		set_i = isl_set_list_get_set(list, i);
   10782 		set = isl_set_union(set, set_i);
   10783 	}
   10784 
   10785 	isl_set_list_free(list);
   10786 	return set;
   10787 error:
   10788 	isl_set_list_free(list);
   10789 	return NULL;
   10790 }
   10791 
   10792 __isl_give isl_basic_map *isl_basic_map_product(
   10793 	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
   10794 {
   10795 	isl_space *space_result = NULL;
   10796 	struct isl_basic_map *bmap;
   10797 	unsigned in1, in2, out1, out2, nparam, total, pos;
   10798 	struct isl_dim_map *dim_map1, *dim_map2;
   10799 
   10800 	if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
   10801 		goto error;
   10802 	space_result = isl_space_product(isl_space_copy(bmap1->dim),
   10803 						   isl_space_copy(bmap2->dim));
   10804 
   10805 	in1 = isl_basic_map_dim(bmap1, isl_dim_in);
   10806 	in2 = isl_basic_map_dim(bmap2, isl_dim_in);
   10807 	out1 = isl_basic_map_dim(bmap1, isl_dim_out);
   10808 	out2 = isl_basic_map_dim(bmap2, isl_dim_out);
   10809 	nparam = isl_basic_map_dim(bmap1, isl_dim_param);
   10810 
   10811 	total = nparam + in1 + in2 + out1 + out2 + bmap1->n_div + bmap2->n_div;
   10812 	dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
   10813 	dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
   10814 	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
   10815 	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
   10816 	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
   10817 	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
   10818 	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
   10819 	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
   10820 	isl_dim_map_div(dim_map1, bmap1, pos += out2);
   10821 	isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
   10822 
   10823 	bmap = isl_basic_map_alloc_space(space_result,
   10824 			bmap1->n_div + bmap2->n_div,
   10825 			bmap1->n_eq + bmap2->n_eq,
   10826 			bmap1->n_ineq + bmap2->n_ineq);
   10827 	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
   10828 	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
   10829 	bmap = isl_basic_map_simplify(bmap);
   10830 	return isl_basic_map_finalize(bmap);
   10831 error:
   10832 	isl_basic_map_free(bmap1);
   10833 	isl_basic_map_free(bmap2);
   10834 	return NULL;
   10835 }
   10836 
   10837 __isl_give isl_basic_map *isl_basic_map_flat_product(
   10838 	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
   10839 {
   10840 	isl_basic_map *prod;
   10841 
   10842 	prod = isl_basic_map_product(bmap1, bmap2);
   10843 	prod = isl_basic_map_flatten(prod);
   10844 	return prod;
   10845 }
   10846 
   10847 __isl_give isl_basic_set *isl_basic_set_flat_product(
   10848 	__isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
   10849 {
   10850 	return isl_basic_map_flat_range_product(bset1, bset2);
   10851 }
   10852 
   10853 __isl_give isl_basic_map *isl_basic_map_domain_product(
   10854 	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
   10855 {
   10856 	isl_space *space1, *space2;
   10857 	isl_space *space_result = NULL;
   10858 	isl_basic_map *bmap;
   10859 	isl_size in1, in2, out, nparam;
   10860 	unsigned total, pos;
   10861 	struct isl_dim_map *dim_map1, *dim_map2;
   10862 
   10863 	in1 = isl_basic_map_dim(bmap1, isl_dim_in);
   10864 	in2 = isl_basic_map_dim(bmap2, isl_dim_in);
   10865 	out = isl_basic_map_dim(bmap1, isl_dim_out);
   10866 	nparam = isl_basic_map_dim(bmap1, isl_dim_param);
   10867 	if (in1 < 0 || in2 < 0 || out < 0 || nparam < 0)
   10868 		goto error;
   10869 
   10870 	space1 = isl_basic_map_get_space(bmap1);
   10871 	space2 = isl_basic_map_get_space(bmap2);
   10872 	space_result = isl_space_domain_product(space1, space2);
   10873 
   10874 	total = nparam + in1 + in2 + out + bmap1->n_div + bmap2->n_div;
   10875 	dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
   10876 	dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
   10877 	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
   10878 	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
   10879 	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
   10880 	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
   10881 	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
   10882 	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos);
   10883 	isl_dim_map_div(dim_map1, bmap1, pos += out);
   10884 	isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
   10885 
   10886 	bmap = isl_basic_map_alloc_space(space_result,
   10887 			bmap1->n_div + bmap2->n_div,
   10888 			bmap1->n_eq + bmap2->n_eq,
   10889 			bmap1->n_ineq + bmap2->n_ineq);
   10890 	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
   10891 	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
   10892 	bmap = isl_basic_map_simplify(bmap);
   10893 	return isl_basic_map_finalize(bmap);
   10894 error:
   10895 	isl_basic_map_free(bmap1);
   10896 	isl_basic_map_free(bmap2);
   10897 	return NULL;
   10898 }
   10899 
   10900 __isl_give isl_basic_map *isl_basic_map_range_product(
   10901 	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
   10902 {
   10903 	isl_bool rational;
   10904 	isl_space *space_result = NULL;
   10905 	isl_basic_map *bmap;
   10906 	isl_size in, out1, out2, nparam;
   10907 	unsigned total, pos;
   10908 	struct isl_dim_map *dim_map1, *dim_map2;
   10909 
   10910 	rational = isl_basic_map_is_rational(bmap1);
   10911 	if (rational >= 0 && rational)
   10912 		rational = isl_basic_map_is_rational(bmap2);
   10913 	in = isl_basic_map_dim(bmap1, isl_dim_in);
   10914 	out1 = isl_basic_map_dim(bmap1, isl_dim_out);
   10915 	out2 = isl_basic_map_dim(bmap2, isl_dim_out);
   10916 	nparam = isl_basic_map_dim(bmap1, isl_dim_param);
   10917 	if (in < 0 || out1 < 0 || out2 < 0 || nparam < 0 || rational < 0)
   10918 		goto error;
   10919 
   10920 	if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
   10921 		goto error;
   10922 
   10923 	space_result = isl_space_range_product(isl_space_copy(bmap1->dim),
   10924 					   isl_space_copy(bmap2->dim));
   10925 
   10926 	total = nparam + in + out1 + out2 + bmap1->n_div + bmap2->n_div;
   10927 	dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
   10928 	dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
   10929 	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
   10930 	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
   10931 	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
   10932 	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
   10933 	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in);
   10934 	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
   10935 	isl_dim_map_div(dim_map1, bmap1, pos += out2);
   10936 	isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
   10937 
   10938 	bmap = isl_basic_map_alloc_space(space_result,
   10939 			bmap1->n_div + bmap2->n_div,
   10940 			bmap1->n_eq + bmap2->n_eq,
   10941 			bmap1->n_ineq + bmap2->n_ineq);
   10942 	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
   10943 	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
   10944 	if (rational)
   10945 		bmap = isl_basic_map_set_rational(bmap);
   10946 	bmap = isl_basic_map_simplify(bmap);
   10947 	return isl_basic_map_finalize(bmap);
   10948 error:
   10949 	isl_basic_map_free(bmap1);
   10950 	isl_basic_map_free(bmap2);
   10951 	return NULL;
   10952 }
   10953 
   10954 __isl_give isl_basic_map *isl_basic_map_flat_range_product(
   10955 	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
   10956 {
   10957 	isl_basic_map *prod;
   10958 
   10959 	prod = isl_basic_map_range_product(bmap1, bmap2);
   10960 	prod = isl_basic_map_flatten_range(prod);
   10961 	return prod;
   10962 }
   10963 
   10964 /* Apply "basic_map_product" to each pair of basic maps in "map1" and "map2"
   10965  * and collect the results.
   10966  * The result live in the space obtained by calling "space_product"
   10967  * on the spaces of "map1" and "map2".
   10968  * If "remove_duplicates" is set then the result may contain duplicates
   10969  * (even if the inputs do not) and so we try and remove the obvious
   10970  * duplicates.
   10971  */
   10972 static __isl_give isl_map *map_product(__isl_take isl_map *map1,
   10973 	__isl_take isl_map *map2,
   10974 	__isl_give isl_space *(*space_product)(__isl_take isl_space *left,
   10975 					   __isl_take isl_space *right),
   10976 	__isl_give isl_basic_map *(*basic_map_product)(
   10977 		__isl_take isl_basic_map *left,
   10978 		__isl_take isl_basic_map *right),
   10979 	int remove_duplicates)
   10980 {
   10981 	unsigned flags = 0;
   10982 	struct isl_map *result;
   10983 	int i, j;
   10984 	isl_bool m;
   10985 
   10986 	m = isl_map_has_equal_params(map1, map2);
   10987 	if (m < 0)
   10988 		goto error;
   10989 	if (!m)
   10990 		isl_die(isl_map_get_ctx(map1), isl_error_invalid,
   10991 			"parameters don't match", goto error);
   10992 
   10993 	if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
   10994 	    ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
   10995 		ISL_FL_SET(flags, ISL_MAP_DISJOINT);
   10996 
   10997 	result = isl_map_alloc_space(space_product(isl_space_copy(map1->dim),
   10998 					       isl_space_copy(map2->dim)),
   10999 				map1->n * map2->n, flags);
   11000 	if (!result)
   11001 		goto error;
   11002 	for (i = 0; i < map1->n; ++i)
   11003 		for (j = 0; j < map2->n; ++j) {
   11004 			struct isl_basic_map *part;
   11005 			part = basic_map_product(isl_basic_map_copy(map1->p[i]),
   11006 						 isl_basic_map_copy(map2->p[j]));
   11007 			if (isl_basic_map_is_empty(part))
   11008 				isl_basic_map_free(part);
   11009 			else
   11010 				result = isl_map_add_basic_map(result, part);
   11011 			if (!result)
   11012 				goto error;
   11013 		}
   11014 	if (remove_duplicates)
   11015 		result = isl_map_remove_obvious_duplicates(result);
   11016 	isl_map_free(map1);
   11017 	isl_map_free(map2);
   11018 	return result;
   11019 error:
   11020 	isl_map_free(map1);
   11021 	isl_map_free(map2);
   11022 	return NULL;
   11023 }
   11024 
   11025 /* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
   11026  */
   11027 __isl_give isl_map *isl_map_product(__isl_take isl_map *map1,
   11028 	__isl_take isl_map *map2)
   11029 {
   11030 	isl_map_align_params_bin(&map1, &map2);
   11031 	return map_product(map1, map2, &isl_space_product,
   11032 			&isl_basic_map_product, 0);
   11033 }
   11034 
   11035 /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
   11036  */
   11037 __isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
   11038 	__isl_take isl_map *map2)
   11039 {
   11040 	isl_map *prod;
   11041 
   11042 	prod = isl_map_product(map1, map2);
   11043 	prod = isl_map_flatten(prod);
   11044 	return prod;
   11045 }
   11046 
   11047 /* Given two set A and B, construct its Cartesian product A x B.
   11048  */
   11049 __isl_give isl_set *isl_set_product(__isl_take isl_set *set1,
   11050 	__isl_take isl_set *set2)
   11051 {
   11052 	return isl_map_range_product(set1, set2);
   11053 }
   11054 
   11055 __isl_give isl_set *isl_set_flat_product(__isl_take isl_set *set1,
   11056 	__isl_take isl_set *set2)
   11057 {
   11058 	return isl_map_flat_range_product(set1, set2);
   11059 }
   11060 
   11061 /* Given two maps A -> B and C -> D, construct a map [A -> C] -> (B * D)
   11062  */
   11063 __isl_give isl_map *isl_map_domain_product(__isl_take isl_map *map1,
   11064 	__isl_take isl_map *map2)
   11065 {
   11066 	isl_map_align_params_bin(&map1, &map2);
   11067 	return map_product(map1, map2, &isl_space_domain_product,
   11068 				&isl_basic_map_domain_product, 1);
   11069 }
   11070 
   11071 /* Given two maps A -> B and C -> D, construct a map (A * C) -> [B -> D]
   11072  */
   11073 __isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1,
   11074 	__isl_take isl_map *map2)
   11075 {
   11076 	isl_map_align_params_bin(&map1, &map2);
   11077 	return map_product(map1, map2, &isl_space_range_product,
   11078 				&isl_basic_map_range_product, 1);
   11079 }
   11080 
   11081 /* Given a map of the form [A -> B] -> [C -> D], return the map A -> C.
   11082  */
   11083 __isl_give isl_map *isl_map_factor_domain(__isl_take isl_map *map)
   11084 {
   11085 	isl_space *space;
   11086 	isl_size total1, keep1, total2, keep2;
   11087 
   11088 	total1 = isl_map_dim(map, isl_dim_in);
   11089 	total2 = isl_map_dim(map, isl_dim_out);
   11090 	if (total1 < 0 || total2 < 0)
   11091 		return isl_map_free(map);
   11092 	if (!isl_space_domain_is_wrapping(map->dim) ||
   11093 	    !isl_space_range_is_wrapping(map->dim))
   11094 		isl_die(isl_map_get_ctx(map), isl_error_invalid,
   11095 			"not a product", return isl_map_free(map));
   11096 
   11097 	space = isl_map_get_space(map);
   11098 	space = isl_space_factor_domain(space);
   11099 	keep1 = isl_space_dim(space, isl_dim_in);
   11100 	keep2 = isl_space_dim(space, isl_dim_out);
   11101 	if (keep1 < 0 || keep2 < 0)
   11102 		map = isl_map_free(map);
   11103 	map = isl_map_project_out(map, isl_dim_in, keep1, total1 - keep1);
   11104 	map = isl_map_project_out(map, isl_dim_out, keep2, total2 - keep2);
   11105 	map = isl_map_reset_space(map, space);
   11106 
   11107 	return map;
   11108 }
   11109 
   11110 /* Given a map of the form [A -> B] -> [C -> D], return the map B -> D.
   11111  */
   11112 __isl_give isl_map *isl_map_factor_range(__isl_take isl_map *map)
   11113 {
   11114 	isl_space *space;
   11115 	isl_size total1, keep1, total2, keep2;
   11116 
   11117 	total1 = isl_map_dim(map, isl_dim_in);
   11118 	total2 = isl_map_dim(map, isl_dim_out);
   11119 	if (total1 < 0 || total2 < 0)
   11120 		return isl_map_free(map);
   11121 	if (!isl_space_domain_is_wrapping(map->dim) ||
   11122 	    !isl_space_range_is_wrapping(map->dim))
   11123 		isl_die(isl_map_get_ctx(map), isl_error_invalid,
   11124 			"not a product", return isl_map_free(map));
   11125 
   11126 	space = isl_map_get_space(map);
   11127 	space = isl_space_factor_range(space);
   11128 	keep1 = isl_space_dim(space, isl_dim_in);
   11129 	keep2 = isl_space_dim(space, isl_dim_out);
   11130 	if (keep1 < 0 || keep2 < 0)
   11131 		map = isl_map_free(map);
   11132 	map = isl_map_project_out(map, isl_dim_in, 0, total1 - keep1);
   11133 	map = isl_map_project_out(map, isl_dim_out, 0, total2 - keep2);
   11134 	map = isl_map_reset_space(map, space);
   11135 
   11136 	return map;
   11137 }
   11138 
   11139 /* Given a map of the form [A -> B] -> C, return the map A -> C.
   11140  */
   11141 __isl_give isl_map *isl_map_domain_factor_domain(__isl_take isl_map *map)
   11142 {
   11143 	isl_space *space;
   11144 	isl_size total, keep;
   11145 
   11146 	total = isl_map_dim(map, isl_dim_in);
   11147 	if (total < 0)
   11148 		return isl_map_free(map);
   11149 	if (!isl_space_domain_is_wrapping(map->dim))
   11150 		isl_die(isl_map_get_ctx(map), isl_error_invalid,
   11151 			"domain is not a product", return isl_map_free(map));
   11152 
   11153 	space = isl_map_get_space(map);
   11154 	space = isl_space_domain_factor_domain(space);
   11155 	keep = isl_space_dim(space, isl_dim_in);
   11156 	if (keep < 0)
   11157 		map = isl_map_free(map);
   11158 	map = isl_map_project_out(map, isl_dim_in, keep, total - keep);
   11159 	map = isl_map_reset_space(map, space);
   11160 
   11161 	return map;
   11162 }
   11163 
   11164 /* Given a map of the form [A -> B] -> C, return the map B -> C.
   11165  */
   11166 __isl_give isl_map *isl_map_domain_factor_range(__isl_take isl_map *map)
   11167 {
   11168 	isl_space *space;
   11169 	isl_size total, keep;
   11170 
   11171 	total = isl_map_dim(map, isl_dim_in);
   11172 	if (total < 0)
   11173 		return isl_map_free(map);
   11174 	if (!isl_space_domain_is_wrapping(map->dim))
   11175 		isl_die(isl_map_get_ctx(map), isl_error_invalid,
   11176 			"domain is not a product", return isl_map_free(map));
   11177 
   11178 	space = isl_map_get_space(map);
   11179 	space = isl_space_domain_factor_range(space);
   11180 	keep = isl_space_dim(space, isl_dim_in);
   11181 	if (keep < 0)
   11182 		map = isl_map_free(map);
   11183 	map = isl_map_project_out(map, isl_dim_in, 0, total - keep);
   11184 	map = isl_map_reset_space(map, space);
   11185 
   11186 	return map;
   11187 }
   11188 
   11189 /* Given a map A -> [B -> C], extract the map A -> B.
   11190  */
   11191 __isl_give isl_map *isl_map_range_factor_domain(__isl_take isl_map *map)
   11192 {
   11193 	isl_space *space;
   11194 	isl_size total, keep;
   11195 
   11196 	total = isl_map_dim(map, isl_dim_out);
   11197 	if (total < 0)
   11198 		return isl_map_free(map);
   11199 	if (!isl_space_range_is_wrapping(map->dim))
   11200 		isl_die(isl_map_get_ctx(map), isl_error_invalid,
   11201 			"range is not a product", return isl_map_free(map));
   11202 
   11203 	space = isl_map_get_space(map);
   11204 	space = isl_space_range_factor_domain(space);
   11205 	keep = isl_space_dim(space, isl_dim_out);
   11206 	if (keep < 0)
   11207 		map = isl_map_free(map);
   11208 	map = isl_map_project_out(map, isl_dim_out, keep, total - keep);
   11209 	map = isl_map_reset_space(map, space);
   11210 
   11211 	return map;
   11212 }
   11213 
   11214 /* Given a map A -> [B -> C], extract the map A -> C.
   11215  */
   11216 __isl_give isl_map *isl_map_range_factor_range(__isl_take isl_map *map)
   11217 {
   11218 	isl_space *space;
   11219 	isl_size total, keep;
   11220 
   11221 	total = isl_map_dim(map, isl_dim_out);
   11222 	if (total < 0)
   11223 		return isl_map_free(map);
   11224 	if (!isl_space_range_is_wrapping(map->dim))
   11225 		isl_die(isl_map_get_ctx(map), isl_error_invalid,
   11226 			"range is not a product", return isl_map_free(map));
   11227 
   11228 	space = isl_map_get_space(map);
   11229 	space = isl_space_range_factor_range(space);
   11230 	keep = isl_space_dim(space, isl_dim_out);
   11231 	if (keep < 0)
   11232 		map = isl_map_free(map);
   11233 	map = isl_map_project_out(map, isl_dim_out, 0, total - keep);
   11234 	map = isl_map_reset_space(map, space);
   11235 
   11236 	return map;
   11237 }
   11238 
   11239 /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D)
   11240  */
   11241 __isl_give isl_map *isl_map_flat_domain_product(__isl_take isl_map *map1,
   11242 	__isl_take isl_map *map2)
   11243 {
   11244 	isl_map *prod;
   11245 
   11246 	prod = isl_map_domain_product(map1, map2);
   11247 	prod = isl_map_flatten_domain(prod);
   11248 	return prod;
   11249 }
   11250 
   11251 /* Given two maps A -> B and C -> D, construct a map (A * C) -> (B, D)
   11252  */
   11253 __isl_give isl_map *isl_map_flat_range_product(__isl_take isl_map *map1,
   11254 	__isl_take isl_map *map2)
   11255 {
   11256 	isl_map *prod;
   11257 
   11258 	prod = isl_map_range_product(map1, map2);
   11259 	prod = isl_map_flatten_range(prod);
   11260 	return prod;
   11261 }
   11262 
   11263 uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map *bmap)
   11264 {
   11265 	int i;
   11266 	uint32_t hash = isl_hash_init();
   11267 	isl_size total;
   11268 
   11269 	if (!bmap)
   11270 		return 0;
   11271 	bmap = isl_basic_map_copy(bmap);
   11272 	bmap = isl_basic_map_normalize(bmap);
   11273 	total = isl_basic_map_dim(bmap, isl_dim_all);
   11274 	if (total < 0)
   11275 		return 0;
   11276 	isl_hash_byte(hash, bmap->n_eq & 0xFF);
   11277 	for (i = 0; i < bmap->n_eq; ++i) {
   11278 		uint32_t c_hash;
   11279 		c_hash = isl_seq_get_hash(bmap->eq[i], 1 + total);
   11280 		isl_hash_hash(hash, c_hash);
   11281 	}
   11282 	isl_hash_byte(hash, bmap->n_ineq & 0xFF);
   11283 	for (i = 0; i < bmap->n_ineq; ++i) {
   11284 		uint32_t c_hash;
   11285 		c_hash = isl_seq_get_hash(bmap->ineq[i], 1 + total);
   11286 		isl_hash_hash(hash, c_hash);
   11287 	}
   11288 	isl_hash_byte(hash, bmap->n_div & 0xFF);
   11289 	for (i = 0; i < bmap->n_div; ++i) {
   11290 		uint32_t c_hash;
   11291 		if (isl_int_is_zero(bmap->div[i][0]))
   11292 			continue;
   11293 		isl_hash_byte(hash, i & 0xFF);
   11294 		c_hash = isl_seq_get_hash(bmap->div[i], 1 + 1 + total);
   11295 		isl_hash_hash(hash, c_hash);
   11296 	}
   11297 	isl_basic_map_free(bmap);
   11298 	return hash;
   11299 }
   11300 
   11301 uint32_t isl_basic_set_get_hash(__isl_keep isl_basic_set *bset)
   11302 {
   11303 	return isl_basic_map_get_hash(bset_to_bmap(bset));
   11304 }
   11305 
   11306 uint32_t isl_map_get_hash(__isl_keep isl_map *map)
   11307 {
   11308 	int i;
   11309 	uint32_t hash;
   11310 
   11311 	if (!map)
   11312 		return 0;
   11313 	map = isl_map_copy(map);
   11314 	map = isl_map_normalize(map);
   11315 	if (!map)
   11316 		return 0;
   11317 
   11318 	hash = isl_hash_init();
   11319 	for (i = 0; i < map->n; ++i) {
   11320 		uint32_t bmap_hash;
   11321 		bmap_hash = isl_basic_map_get_hash(map->p[i]);
   11322 		isl_hash_hash(hash, bmap_hash);
   11323 	}
   11324 
   11325 	isl_map_free(map);
   11326 
   11327 	return hash;
   11328 }
   11329 
   11330 uint32_t isl_set_get_hash(__isl_keep isl_set *set)
   11331 {
   11332 	return isl_map_get_hash(set_to_map(set));
   11333 }
   11334 
   11335 /* Return the number of basic maps in the (current) representation of "map".
   11336  */
   11337 isl_size isl_map_n_basic_map(__isl_keep isl_map *map)
   11338 {
   11339 	return map ? map->n : isl_size_error;
   11340 }
   11341 
   11342 isl_size isl_set_n_basic_set(__isl_keep isl_set *set)
   11343 {
   11344 	return set ? set->n : isl_size_error;
   11345 }
   11346 
   11347 isl_stat isl_map_foreach_basic_map(__isl_keep isl_map *map,
   11348 	isl_stat (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user)
   11349 {
   11350 	int i;
   11351 
   11352 	if (!map)
   11353 		return isl_stat_error;
   11354 
   11355 	for (i = 0; i < map->n; ++i)
   11356 		if (fn(isl_basic_map_copy(map->p[i]), user) < 0)
   11357 			return isl_stat_error;
   11358 
   11359 	return isl_stat_ok;
   11360 }
   11361 
   11362 isl_stat isl_set_foreach_basic_set(__isl_keep isl_set *set,
   11363 	isl_stat (*fn)(__isl_take isl_basic_set *bset, void *user), void *user)
   11364 {
   11365 	int i;
   11366 
   11367 	if (!set)
   11368 		return isl_stat_error;
   11369 
   11370 	for (i = 0; i < set->n; ++i)
   11371 		if (fn(isl_basic_set_copy(set->p[i]), user) < 0)
   11372 			return isl_stat_error;
   11373 
   11374 	return isl_stat_ok;
   11375 }
   11376 
   11377 /* Does "test" succeed on every basic set in "set"?
   11378  */
   11379 isl_bool isl_set_every_basic_set(__isl_keep isl_set *set,
   11380 	isl_bool (*test)(__isl_keep isl_basic_set *bset, void *user),
   11381 	void *user)
   11382 {
   11383 	int i;
   11384 
   11385 	if (!set)
   11386 		return isl_bool_error;
   11387 
   11388 	for (i = 0; i < set->n; ++i) {
   11389 		isl_bool r;
   11390 
   11391 		r = test(set->p[i], user);
   11392 		if (r < 0 || !r)
   11393 			return r;
   11394 	}
   11395 
   11396 	return isl_bool_true;
   11397 }
   11398 
   11399 /* Return a list of basic sets, the union of which is equal to "set".
   11400  */
   11401 __isl_give isl_basic_set_list *isl_set_get_basic_set_list(
   11402 	__isl_keep isl_set *set)
   11403 {
   11404 	int i;
   11405 	isl_basic_set_list *list;
   11406 
   11407 	if (!set)
   11408 		return NULL;
   11409 
   11410 	list = isl_basic_set_list_alloc(isl_set_get_ctx(set), set->n);
   11411 	for (i = 0; i < set->n; ++i) {
   11412 		isl_basic_set *bset;
   11413 
   11414 		bset = isl_basic_set_copy(set->p[i]);
   11415 		list = isl_basic_set_list_add(list, bset);
   11416 	}
   11417 
   11418 	return list;
   11419 }
   11420 
   11421 __isl_give isl_basic_set *isl_basic_set_lift(__isl_take isl_basic_set *bset)
   11422 {
   11423 	isl_space *space;
   11424 
   11425 	if (!bset)
   11426 		return NULL;
   11427 
   11428 	bset = isl_basic_set_cow(bset);
   11429 	if (!bset)
   11430 		return NULL;
   11431 
   11432 	space = isl_basic_set_get_space(bset);
   11433 	space = isl_space_lift(space, bset->n_div);
   11434 	if (!space)
   11435 		goto error;
   11436 	isl_space_free(bset->dim);
   11437 	bset->dim = space;
   11438 	bset->extra -= bset->n_div;
   11439 	bset->n_div = 0;
   11440 
   11441 	bset = isl_basic_set_finalize(bset);
   11442 
   11443 	return bset;
   11444 error:
   11445 	isl_basic_set_free(bset);
   11446 	return NULL;
   11447 }
   11448 
   11449 __isl_give isl_set *isl_set_lift(__isl_take isl_set *set)
   11450 {
   11451 	int i;
   11452 	isl_space *space;
   11453 	unsigned n_div;
   11454 
   11455 	set = set_from_map(isl_map_align_divs_internal(set_to_map(set)));
   11456 
   11457 	if (!set)
   11458 		return NULL;
   11459 
   11460 	set = isl_set_cow(set);
   11461 	if (!set)
   11462 		return NULL;
   11463 
   11464 	n_div = set->p[0]->n_div;
   11465 	space = isl_set_get_space(set);
   11466 	space = isl_space_lift(space, n_div);
   11467 	if (!space)
   11468 		goto error;
   11469 	isl_space_free(set->dim);
   11470 	set->dim = space;
   11471 
   11472 	for (i = 0; i < set->n; ++i) {
   11473 		set->p[i] = isl_basic_set_lift(set->p[i]);
   11474 		if (!set->p[i])
   11475 			goto error;
   11476 	}
   11477 
   11478 	return set;
   11479 error:
   11480 	isl_set_free(set);
   11481 	return NULL;
   11482 }
   11483 
   11484 int isl_basic_set_size(__isl_keep isl_basic_set *bset)
   11485 {
   11486 	isl_size dim;
   11487 	int size = 0;
   11488 
   11489 	dim = isl_basic_set_dim(bset, isl_dim_all);
   11490 	if (dim < 0)
   11491 		return -1;
   11492 	size += bset->n_eq * (1 + dim);
   11493 	size += bset->n_ineq * (1 + dim);
   11494 	size += bset->n_div * (2 + dim);
   11495 
   11496 	return size;
   11497 }
   11498 
   11499 int isl_set_size(__isl_keep isl_set *set)
   11500 {
   11501 	int i;
   11502 	int size = 0;
   11503 
   11504 	if (!set)
   11505 		return -1;
   11506 
   11507 	for (i = 0; i < set->n; ++i)
   11508 		size += isl_basic_set_size(set->p[i]);
   11509 
   11510 	return size;
   11511 }
   11512 
   11513 /* Check if there is any lower bound (if lower == 0) and/or upper
   11514  * bound (if upper == 0) on the specified dim.
   11515  */
   11516 static isl_bool basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
   11517 	enum isl_dim_type type, unsigned pos, int lower, int upper)
   11518 {
   11519 	int i;
   11520 
   11521 	if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
   11522 		return isl_bool_error;
   11523 
   11524 	pos += isl_basic_map_offset(bmap, type);
   11525 
   11526 	for (i = 0; i < bmap->n_div; ++i) {
   11527 		if (isl_int_is_zero(bmap->div[i][0]))
   11528 			continue;
   11529 		if (!isl_int_is_zero(bmap->div[i][1 + pos]))
   11530 			return isl_bool_true;
   11531 	}
   11532 
   11533 	for (i = 0; i < bmap->n_eq; ++i)
   11534 		if (!isl_int_is_zero(bmap->eq[i][pos]))
   11535 			return isl_bool_true;
   11536 
   11537 	for (i = 0; i < bmap->n_ineq; ++i) {
   11538 		int sgn = isl_int_sgn(bmap->ineq[i][pos]);
   11539 		if (sgn > 0)
   11540 			lower = 1;
   11541 		if (sgn < 0)
   11542 			upper = 1;
   11543 	}
   11544 
   11545 	return lower && upper;
   11546 }
   11547 
   11548 isl_bool isl_basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
   11549 	enum isl_dim_type type, unsigned pos)
   11550 {
   11551 	return basic_map_dim_is_bounded(bmap, type, pos, 0, 0);
   11552 }
   11553 
   11554 isl_bool isl_basic_map_dim_has_lower_bound(__isl_keep isl_basic_map *bmap,
   11555 	enum isl_dim_type type, unsigned pos)
   11556 {
   11557 	return basic_map_dim_is_bounded(bmap, type, pos, 0, 1);
   11558 }
   11559 
   11560 isl_bool isl_basic_map_dim_has_upper_bound(__isl_keep isl_basic_map *bmap,
   11561 	enum isl_dim_type type, unsigned pos)
   11562 {
   11563 	return basic_map_dim_is_bounded(bmap, type, pos, 1, 0);
   11564 }
   11565 
   11566 isl_bool isl_map_dim_is_bounded(__isl_keep isl_map *map,
   11567 	enum isl_dim_type type, unsigned pos)
   11568 {
   11569 	int i;
   11570 
   11571 	if (!map)
   11572 		return isl_bool_error;
   11573 
   11574 	for (i = 0; i < map->n; ++i) {
   11575 		isl_bool bounded;
   11576 		bounded = isl_basic_map_dim_is_bounded(map->p[i], type, pos);
   11577 		if (bounded < 0 || !bounded)
   11578 			return bounded;
   11579 	}
   11580 
   11581 	return isl_bool_true;
   11582 }
   11583 
   11584 /* Return true if the specified dim is involved in both an upper bound
   11585  * and a lower bound.
   11586  */
   11587 isl_bool isl_set_dim_is_bounded(__isl_keep isl_set *set,
   11588 	enum isl_dim_type type, unsigned pos)
   11589 {
   11590 	return isl_map_dim_is_bounded(set_to_map(set), type, pos);
   11591 }
   11592 
   11593 /* Does "map" have a bound (according to "fn") for any of its basic maps?
   11594  */
   11595 static isl_bool has_any_bound(__isl_keep isl_map *map,
   11596 	enum isl_dim_type type, unsigned pos,
   11597 	isl_bool (*fn)(__isl_keep isl_basic_map *bmap,
   11598 		  enum isl_dim_type type, unsigned pos))
   11599 {
   11600 	int i;
   11601 
   11602 	if (!map)
   11603 		return isl_bool_error;
   11604 
   11605 	for (i = 0; i < map->n; ++i) {
   11606 		isl_bool bounded;
   11607 		bounded = fn(map->p[i], type, pos);
   11608 		if (bounded < 0 || bounded)
   11609 			return bounded;
   11610 	}
   11611 
   11612 	return isl_bool_false;
   11613 }
   11614 
   11615 /* Return 1 if the specified dim is involved in any lower bound.
   11616  */
   11617 isl_bool isl_set_dim_has_any_lower_bound(__isl_keep isl_set *set,
   11618 	enum isl_dim_type type, unsigned pos)
   11619 {
   11620 	return has_any_bound(set, type, pos,
   11621 				&isl_basic_map_dim_has_lower_bound);
   11622 }
   11623 
   11624 /* Return 1 if the specified dim is involved in any upper bound.
   11625  */
   11626 isl_bool isl_set_dim_has_any_upper_bound(__isl_keep isl_set *set,
   11627 	enum isl_dim_type type, unsigned pos)
   11628 {
   11629 	return has_any_bound(set, type, pos,
   11630 				&isl_basic_map_dim_has_upper_bound);
   11631 }
   11632 
   11633 /* Does "map" have a bound (according to "fn") for all of its basic maps?
   11634  */
   11635 static isl_bool has_bound(__isl_keep isl_map *map,
   11636 	enum isl_dim_type type, unsigned pos,
   11637 	isl_bool (*fn)(__isl_keep isl_basic_map *bmap,
   11638 		  enum isl_dim_type type, unsigned pos))
   11639 {
   11640 	int i;
   11641 
   11642 	if (!map)
   11643 		return isl_bool_error;
   11644 
   11645 	for (i = 0; i < map->n; ++i) {
   11646 		isl_bool bounded;
   11647 		bounded = fn(map->p[i], type, pos);
   11648 		if (bounded < 0 || !bounded)
   11649 			return bounded;
   11650 	}
   11651 
   11652 	return isl_bool_true;
   11653 }
   11654 
   11655 /* Return 1 if the specified dim has a lower bound (in each of its basic sets).
   11656  */
   11657 isl_bool isl_set_dim_has_lower_bound(__isl_keep isl_set *set,
   11658 	enum isl_dim_type type, unsigned pos)
   11659 {
   11660 	return has_bound(set, type, pos, &isl_basic_map_dim_has_lower_bound);
   11661 }
   11662 
   11663 /* Return 1 if the specified dim has an upper bound (in each of its basic sets).
   11664  */
   11665 isl_bool isl_set_dim_has_upper_bound(__isl_keep isl_set *set,
   11666 	enum isl_dim_type type, unsigned pos)
   11667 {
   11668 	return has_bound(set, type, pos, &isl_basic_map_dim_has_upper_bound);
   11669 }
   11670 
   11671 /* For each of the "n" variables starting at "first", determine
   11672  * the sign of the variable and put the results in the first "n"
   11673  * elements of the array "signs".
   11674  * Sign
   11675  *	1 means that the variable is non-negative
   11676  *	-1 means that the variable is non-positive
   11677  *	0 means the variable attains both positive and negative values.
   11678  */
   11679 isl_stat isl_basic_set_vars_get_sign(__isl_keep isl_basic_set *bset,
   11680 	unsigned first, unsigned n, int *signs)
   11681 {
   11682 	isl_vec *bound = NULL;
   11683 	struct isl_tab *tab = NULL;
   11684 	struct isl_tab_undo *snap;
   11685 	int i;
   11686 	isl_size total;
   11687 
   11688 	total = isl_basic_set_dim(bset, isl_dim_all);
   11689 	if (total < 0 || !signs)
   11690 		return isl_stat_error;
   11691 
   11692 	bound = isl_vec_alloc(bset->ctx, 1 + total);
   11693 	tab = isl_tab_from_basic_set(bset, 0);
   11694 	if (!bound || !tab)
   11695 		goto error;
   11696 
   11697 	isl_seq_clr(bound->el, bound->size);
   11698 	isl_int_set_si(bound->el[0], -1);
   11699 
   11700 	snap = isl_tab_snap(tab);
   11701 	for (i = 0; i < n; ++i) {
   11702 		int empty;
   11703 
   11704 		isl_int_set_si(bound->el[1 + first + i], -1);
   11705 		if (isl_tab_add_ineq(tab, bound->el) < 0)
   11706 			goto error;
   11707 		empty = tab->empty;
   11708 		isl_int_set_si(bound->el[1 + first + i], 0);
   11709 		if (isl_tab_rollback(tab, snap) < 0)
   11710 			goto error;
   11711 
   11712 		if (empty) {
   11713 			signs[i] = 1;
   11714 			continue;
   11715 		}
   11716 
   11717 		isl_int_set_si(bound->el[1 + first + i], 1);
   11718 		if (isl_tab_add_ineq(tab, bound->el) < 0)
   11719 			goto error;
   11720 		empty = tab->empty;
   11721 		isl_int_set_si(bound->el[1 + first + i], 0);
   11722 		if (isl_tab_rollback(tab, snap) < 0)
   11723 			goto error;
   11724 
   11725 		signs[i] = empty ? -1 : 0;
   11726 	}
   11727 
   11728 	isl_tab_free(tab);
   11729 	isl_vec_free(bound);
   11730 	return isl_stat_ok;
   11731 error:
   11732 	isl_tab_free(tab);
   11733 	isl_vec_free(bound);
   11734 	return isl_stat_error;
   11735 }
   11736 
   11737 isl_stat isl_basic_set_dims_get_sign(__isl_keep isl_basic_set *bset,
   11738 	enum isl_dim_type type, unsigned first, unsigned n, int *signs)
   11739 {
   11740 	if (!bset || !signs)
   11741 		return isl_stat_error;
   11742 	if (isl_basic_set_check_range(bset, type, first, n) < 0)
   11743 		return isl_stat_error;
   11744 
   11745 	first += pos(bset->dim, type) - 1;
   11746 	return isl_basic_set_vars_get_sign(bset, first, n, signs);
   11747 }
   11748 
   11749 /* Is it possible for the integer division "div" to depend (possibly
   11750  * indirectly) on any output dimensions?
   11751  *
   11752  * If the div is undefined, then we conservatively assume that it
   11753  * may depend on them.
   11754  * Otherwise, we check if it actually depends on them or on any integer
   11755  * divisions that may depend on them.
   11756  */
   11757 static isl_bool div_may_involve_output(__isl_keep isl_basic_map *bmap, int div)
   11758 {
   11759 	int i;
   11760 	isl_size n_out, n_div;
   11761 	unsigned o_out, o_div;
   11762 
   11763 	if (isl_int_is_zero(bmap->div[div][0]))
   11764 		return isl_bool_true;
   11765 
   11766 	n_out = isl_basic_map_dim(bmap, isl_dim_out);
   11767 	if (n_out < 0)
   11768 		return isl_bool_error;
   11769 	o_out = isl_basic_map_offset(bmap, isl_dim_out);
   11770 
   11771 	if (isl_seq_first_non_zero(bmap->div[div] + 1 + o_out, n_out) != -1)
   11772 		return isl_bool_true;
   11773 
   11774 	n_div = isl_basic_map_dim(bmap, isl_dim_div);
   11775 	if (n_div < 0)
   11776 		return isl_bool_error;
   11777 	o_div = isl_basic_map_offset(bmap, isl_dim_div);
   11778 
   11779 	for (i = 0; i < n_div; ++i) {
   11780 		isl_bool may_involve;
   11781 
   11782 		if (isl_int_is_zero(bmap->div[div][1 + o_div + i]))
   11783 			continue;
   11784 		may_involve = div_may_involve_output(bmap, i);
   11785 		if (may_involve < 0 || may_involve)
   11786 			return may_involve;
   11787 	}
   11788 
   11789 	return isl_bool_false;
   11790 }
   11791 
   11792 /* Return the first integer division of "bmap" in the range
   11793  * [first, first + n[ that may depend on any output dimensions and
   11794  * that has a non-zero coefficient in "c" (where the first coefficient
   11795  * in "c" corresponds to integer division "first").
   11796  */
   11797 static int first_div_may_involve_output(__isl_keep isl_basic_map *bmap,
   11798 	isl_int *c, int first, int n)
   11799 {
   11800 	int k;
   11801 
   11802 	if (!bmap)
   11803 		return -1;
   11804 
   11805 	for (k = first; k < first + n; ++k) {
   11806 		isl_bool may_involve;
   11807 
   11808 		if (isl_int_is_zero(c[k]))
   11809 			continue;
   11810 		may_involve = div_may_involve_output(bmap, k);
   11811 		if (may_involve < 0)
   11812 			return -1;
   11813 		if (may_involve)
   11814 			return k;
   11815 	}
   11816 
   11817 	return first + n;
   11818 }
   11819 
   11820 /* Look for a pair of inequality constraints in "bmap" of the form
   11821  *
   11822  *	-l + i >= 0		or		i >= l
   11823  * and
   11824  *	n + l - i >= 0		or		i <= l + n
   11825  *
   11826  * with n < "m" and i the output dimension at position "pos".
   11827  * (Note that n >= 0 as otherwise the two constraints would conflict.)
   11828  * Furthermore, "l" is only allowed to involve parameters, input dimensions
   11829  * and earlier output dimensions, as well as integer divisions that do
   11830  * not involve any of the output dimensions.
   11831  *
   11832  * Return the index of the first inequality constraint or bmap->n_ineq
   11833  * if no such pair can be found.
   11834  */
   11835 static int find_modulo_constraint_pair(__isl_keep isl_basic_map *bmap,
   11836 	int pos, isl_int m)
   11837 {
   11838 	int i, j;
   11839 	isl_ctx *ctx;
   11840 	isl_size total;
   11841 	isl_size n_div, n_out;
   11842 	unsigned o_div, o_out;
   11843 	int less;
   11844 
   11845 	total = isl_basic_map_dim(bmap, isl_dim_all);
   11846 	n_out = isl_basic_map_dim(bmap, isl_dim_out);
   11847 	n_div = isl_basic_map_dim(bmap, isl_dim_div);
   11848 	if (total < 0 || n_out < 0 || n_div < 0)
   11849 		return -1;
   11850 
   11851 	ctx = isl_basic_map_get_ctx(bmap);
   11852 	o_out = isl_basic_map_offset(bmap, isl_dim_out);
   11853 	o_div = isl_basic_map_offset(bmap, isl_dim_div);
   11854 	for (i = 0; i < bmap->n_ineq; ++i) {
   11855 		if (!isl_int_abs_eq(bmap->ineq[i][o_out + pos], ctx->one))
   11856 			continue;
   11857 		if (isl_seq_first_non_zero(bmap->ineq[i] + o_out + pos + 1,
   11858 					n_out - (pos + 1)) != -1)
   11859 			continue;
   11860 		if (first_div_may_involve_output(bmap, bmap->ineq[i] + o_div,
   11861 						0, n_div) < n_div)
   11862 			continue;
   11863 		for (j = i + 1; j < bmap->n_ineq; ++j) {
   11864 			if (!isl_int_abs_eq(bmap->ineq[j][o_out + pos],
   11865 					    ctx->one))
   11866 				continue;
   11867 			if (!isl_seq_is_neg(bmap->ineq[i] + 1,
   11868 					    bmap->ineq[j] + 1, total))
   11869 				continue;
   11870 			break;
   11871 		}
   11872 		if (j >= bmap->n_ineq)
   11873 			continue;
   11874 		isl_int_add(bmap->ineq[i][0],
   11875 			    bmap->ineq[i][0], bmap->ineq[j][0]);
   11876 		less = isl_int_abs_lt(bmap->ineq[i][0], m);
   11877 		isl_int_sub(bmap->ineq[i][0],
   11878 			    bmap->ineq[i][0], bmap->ineq[j][0]);
   11879 		if (!less)
   11880 			continue;
   11881 		if (isl_int_is_one(bmap->ineq[i][o_out + pos]))
   11882 			return i;
   11883 		else
   11884 			return j;
   11885 	}
   11886 
   11887 	return bmap->n_ineq;
   11888 }
   11889 
   11890 /* Return the index of the equality of "bmap" that defines
   11891  * the output dimension "pos" in terms of earlier dimensions.
   11892  * The equality may also involve integer divisions, as long
   11893  * as those integer divisions are defined in terms of
   11894  * parameters or input dimensions.
   11895  * In this case, *div is set to the number of integer divisions and
   11896  * *ineq is set to the number of inequality constraints (provided
   11897  * div and ineq are not NULL).
   11898  *
   11899  * The equality may also involve a single integer division involving
   11900  * the output dimensions (typically only output dimension "pos") as
   11901  * long as the coefficient of output dimension "pos" is 1 or -1 and
   11902  * there is a pair of constraints i >= l and i <= l + n, with i referring
   11903  * to output dimension "pos", l an expression involving only earlier
   11904  * dimensions and n smaller than the coefficient of the integer division
   11905  * in the equality.  In this case, the output dimension can be defined
   11906  * in terms of a modulo expression that does not involve the integer division.
   11907  * *div is then set to this single integer division and
   11908  * *ineq is set to the index of constraint i >= l.
   11909  *
   11910  * Return bmap->n_eq if there is no such equality.
   11911  * Return -1 on error.
   11912  */
   11913 int isl_basic_map_output_defining_equality(__isl_keep isl_basic_map *bmap,
   11914 	int pos, int *div, int *ineq)
   11915 {
   11916 	int j, k, l;
   11917 	isl_size n_div, n_out;
   11918 	unsigned o_div, o_out;
   11919 
   11920 	n_out = isl_basic_map_dim(bmap, isl_dim_out);
   11921 	n_div = isl_basic_map_dim(bmap, isl_dim_div);
   11922 	if (n_out < 0 || n_div < 0)
   11923 		return -1;
   11924 
   11925 	o_out = isl_basic_map_offset(bmap, isl_dim_out);
   11926 	o_div = isl_basic_map_offset(bmap, isl_dim_div);
   11927 
   11928 	if (ineq)
   11929 		*ineq = bmap->n_ineq;
   11930 	if (div)
   11931 		*div = n_div;
   11932 	for (j = 0; j < bmap->n_eq; ++j) {
   11933 		if (isl_int_is_zero(bmap->eq[j][o_out + pos]))
   11934 			continue;
   11935 		if (isl_seq_first_non_zero(bmap->eq[j] + o_out + pos + 1,
   11936 					n_out - (pos + 1)) != -1)
   11937 			continue;
   11938 		k = first_div_may_involve_output(bmap, bmap->eq[j] + o_div,
   11939 						0, n_div);
   11940 		if (k >= n_div)
   11941 			return j;
   11942 		if (!isl_int_is_one(bmap->eq[j][o_out + pos]) &&
   11943 		    !isl_int_is_negone(bmap->eq[j][o_out + pos]))
   11944 			continue;
   11945 		if (first_div_may_involve_output(bmap, bmap->eq[j] + o_div,
   11946 						k + 1, n_div - (k+1)) < n_div)
   11947 			continue;
   11948 		l = find_modulo_constraint_pair(bmap, pos,
   11949 						bmap->eq[j][o_div + k]);
   11950 		if (l < 0)
   11951 			return -1;
   11952 		if (l >= bmap->n_ineq)
   11953 			continue;
   11954 		if (div)
   11955 			*div = k;
   11956 		if (ineq)
   11957 			*ineq = l;
   11958 		return j;
   11959 	}
   11960 
   11961 	return bmap->n_eq;
   11962 }
   11963 
   11964 /* Check if the given basic map is obviously single-valued.
   11965  * In particular, for each output dimension, check that there is
   11966  * an equality that defines the output dimension in terms of
   11967  * earlier dimensions.
   11968  */
   11969 isl_bool isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap)
   11970 {
   11971 	int i;
   11972 	isl_size n_out;
   11973 
   11974 	n_out = isl_basic_map_dim(bmap, isl_dim_out);
   11975 	if (n_out < 0)
   11976 		return isl_bool_error;
   11977 
   11978 	for (i = 0; i < n_out; ++i) {
   11979 		int eq;
   11980 
   11981 		eq = isl_basic_map_output_defining_equality(bmap, i,
   11982 							    NULL, NULL);
   11983 		if (eq < 0)
   11984 			return isl_bool_error;
   11985 		if (eq >= bmap->n_eq)
   11986 			return isl_bool_false;
   11987 	}
   11988 
   11989 	return isl_bool_true;
   11990 }
   11991 
   11992 /* Check if the given basic map is single-valued.
   11993  * We simply compute
   11994  *
   11995  *	M \circ M^-1
   11996  *
   11997  * and check if the result is a subset of the identity mapping.
   11998  */
   11999 isl_bool isl_basic_map_is_single_valued(__isl_keep isl_basic_map *bmap)
   12000 {
   12001 	isl_space *space;
   12002 	isl_basic_map *test;
   12003 	isl_basic_map *id;
   12004 	isl_bool sv;
   12005 
   12006 	sv = isl_basic_map_plain_is_single_valued(bmap);
   12007 	if (sv < 0 || sv)
   12008 		return sv;
   12009 
   12010 	test = isl_basic_map_reverse(isl_basic_map_copy(bmap));
   12011 	test = isl_basic_map_apply_range(test, isl_basic_map_copy(bmap));
   12012 
   12013 	space = isl_basic_map_get_space(bmap);
   12014 	space = isl_space_map_from_set(isl_space_range(space));
   12015 	id = isl_basic_map_identity(space);
   12016 
   12017 	sv = isl_basic_map_is_subset(test, id);
   12018 
   12019 	isl_basic_map_free(test);
   12020 	isl_basic_map_free(id);
   12021 
   12022 	return sv;
   12023 }
   12024 
   12025 /* Check if the given map is obviously single-valued.
   12026  */
   12027 isl_bool isl_map_plain_is_single_valued(__isl_keep isl_map *map)
   12028 {
   12029 	if (!map)
   12030 		return isl_bool_error;
   12031 	if (map->n == 0)
   12032 		return isl_bool_true;
   12033 	if (map->n >= 2)
   12034 		return isl_bool_false;
   12035 
   12036 	return isl_basic_map_plain_is_single_valued(map->p[0]);
   12037 }
   12038 
   12039 /* Check if the given map is single-valued.
   12040  * We simply compute
   12041  *
   12042  *	M \circ M^-1
   12043  *
   12044  * and check if the result is a subset of the identity mapping.
   12045  */
   12046 isl_bool isl_map_is_single_valued(__isl_keep isl_map *map)
   12047 {
   12048 	isl_space *space;
   12049 	isl_map *test;
   12050 	isl_map *id;
   12051 	isl_bool sv;
   12052 
   12053 	sv = isl_map_plain_is_single_valued(map);
   12054 	if (sv < 0 || sv)
   12055 		return sv;
   12056 
   12057 	test = isl_map_reverse(isl_map_copy(map));
   12058 	test = isl_map_apply_range(test, isl_map_copy(map));
   12059 
   12060 	space = isl_space_map_from_set(isl_space_range(isl_map_get_space(map)));
   12061 	id = isl_map_identity(space);
   12062 
   12063 	sv = isl_map_is_subset(test, id);
   12064 
   12065 	isl_map_free(test);
   12066 	isl_map_free(id);
   12067 
   12068 	return sv;
   12069 }
   12070 
   12071 isl_bool isl_map_is_injective(__isl_keep isl_map *map)
   12072 {
   12073 	isl_bool in;
   12074 
   12075 	map = isl_map_copy(map);
   12076 	map = isl_map_reverse(map);
   12077 	in = isl_map_is_single_valued(map);
   12078 	isl_map_free(map);
   12079 
   12080 	return in;
   12081 }
   12082 
   12083 /* Check if the given map is obviously injective.
   12084  */
   12085 isl_bool isl_map_plain_is_injective(__isl_keep isl_map *map)
   12086 {
   12087 	isl_bool in;
   12088 
   12089 	map = isl_map_copy(map);
   12090 	map = isl_map_reverse(map);
   12091 	in = isl_map_plain_is_single_valued(map);
   12092 	isl_map_free(map);
   12093 
   12094 	return in;
   12095 }
   12096 
   12097 isl_bool isl_map_is_bijective(__isl_keep isl_map *map)
   12098 {
   12099 	isl_bool sv;
   12100 
   12101 	sv = isl_map_is_single_valued(map);
   12102 	if (sv < 0 || !sv)
   12103 		return sv;
   12104 
   12105 	return isl_map_is_injective(map);
   12106 }
   12107 
   12108 isl_bool isl_set_is_singleton(__isl_keep isl_set *set)
   12109 {
   12110 	return isl_map_is_single_valued(set_to_map(set));
   12111 }
   12112 
   12113 /* Does "map" only map elements to themselves?
   12114  *
   12115  * If the domain and range spaces are different, then "map"
   12116  * is considered not to be an identity relation, even if it is empty.
   12117  * Otherwise, construct the maximal identity relation and
   12118  * check whether "map" is a subset of this relation.
   12119  */
   12120 isl_bool isl_map_is_identity(__isl_keep isl_map *map)
   12121 {
   12122 	isl_map *id;
   12123 	isl_bool equal, is_identity;
   12124 
   12125 	equal = isl_map_tuple_is_equal(map, isl_dim_in, map, isl_dim_out);
   12126 	if (equal < 0 || !equal)
   12127 		return equal;
   12128 
   12129 	id = isl_map_identity(isl_map_get_space(map));
   12130 	is_identity = isl_map_is_subset(map, id);
   12131 	isl_map_free(id);
   12132 
   12133 	return is_identity;
   12134 }
   12135 
   12136 int isl_map_is_translation(__isl_keep isl_map *map)
   12137 {
   12138 	int ok;
   12139 	isl_set *delta;
   12140 
   12141 	delta = isl_map_deltas(isl_map_copy(map));
   12142 	ok = isl_set_is_singleton(delta);
   12143 	isl_set_free(delta);
   12144 
   12145 	return ok;
   12146 }
   12147 
   12148 static int unique(isl_int *p, unsigned pos, unsigned len)
   12149 {
   12150 	if (isl_seq_first_non_zero(p, pos) != -1)
   12151 		return 0;
   12152 	if (isl_seq_first_non_zero(p + pos + 1, len - pos - 1) != -1)
   12153 		return 0;
   12154 	return 1;
   12155 }
   12156 
   12157 isl_bool isl_basic_set_is_box(__isl_keep isl_basic_set *bset)
   12158 {
   12159 	int i, j;
   12160 	isl_size nvar, ovar, n_div;
   12161 
   12162 	n_div = isl_basic_set_dim(bset, isl_dim_div);
   12163 	if (n_div < 0)
   12164 		return isl_bool_error;
   12165 	if (n_div != 0)
   12166 		return isl_bool_false;
   12167 
   12168 	nvar = isl_basic_set_dim(bset, isl_dim_set);
   12169 	ovar = isl_space_offset(bset->dim, isl_dim_set);
   12170 	if (nvar < 0 || ovar < 0)
   12171 		return isl_bool_error;
   12172 	for (j = 0; j < nvar; ++j) {
   12173 		int lower = 0, upper = 0;
   12174 		for (i = 0; i < bset->n_eq; ++i) {
   12175 			if (isl_int_is_zero(bset->eq[i][1 + ovar + j]))
   12176 				continue;
   12177 			if (!unique(bset->eq[i] + 1 + ovar, j, nvar))
   12178 				return isl_bool_false;
   12179 			break;
   12180 		}
   12181 		if (i < bset->n_eq)
   12182 			continue;
   12183 		for (i = 0; i < bset->n_ineq; ++i) {
   12184 			if (isl_int_is_zero(bset->ineq[i][1 + ovar + j]))
   12185 				continue;
   12186 			if (!unique(bset->ineq[i] + 1 + ovar, j, nvar))
   12187 				return isl_bool_false;
   12188 			if (isl_int_is_pos(bset->ineq[i][1 + ovar + j]))
   12189 				lower = 1;
   12190 			else
   12191 				upper = 1;
   12192 		}
   12193 		if (!lower || !upper)
   12194 			return isl_bool_false;
   12195 	}
   12196 
   12197 	return isl_bool_true;
   12198 }
   12199 
   12200 isl_bool isl_set_is_box(__isl_keep isl_set *set)
   12201 {
   12202 	if (!set)
   12203 		return isl_bool_error;
   12204 	if (set->n != 1)
   12205 		return isl_bool_false;
   12206 
   12207 	return isl_basic_set_is_box(set->p[0]);
   12208 }
   12209 
   12210 isl_bool isl_basic_set_is_wrapping(__isl_keep isl_basic_set *bset)
   12211 {
   12212 	if (!bset)
   12213 		return isl_bool_error;
   12214 
   12215 	return isl_space_is_wrapping(bset->dim);
   12216 }
   12217 
   12218 isl_bool isl_set_is_wrapping(__isl_keep isl_set *set)
   12219 {
   12220 	if (!set)
   12221 		return isl_bool_error;
   12222 
   12223 	return isl_space_is_wrapping(set->dim);
   12224 }
   12225 
   12226 /* Modify the space of "map" through a call to "change".
   12227  * If "can_change" is set (not NULL), then first call it to check
   12228  * if the modification is allowed, printing the error message "cannot_change"
   12229  * if it is not.
   12230  */
   12231 static __isl_give isl_map *isl_map_change_space(__isl_take isl_map *map,
   12232 	isl_bool (*can_change)(__isl_keep isl_map *map),
   12233 	const char *cannot_change,
   12234 	__isl_give isl_space *(*change)(__isl_take isl_space *space))
   12235 {
   12236 	isl_bool ok;
   12237 	isl_space *space;
   12238 
   12239 	if (!map)
   12240 		return NULL;
   12241 
   12242 	ok = can_change ? can_change(map) : isl_bool_true;
   12243 	if (ok < 0)
   12244 		return isl_map_free(map);
   12245 	if (!ok)
   12246 		isl_die(isl_map_get_ctx(map), isl_error_invalid, cannot_change,
   12247 			return isl_map_free(map));
   12248 
   12249 	space = change(isl_map_get_space(map));
   12250 	map = isl_map_reset_space(map, space);
   12251 
   12252 	return map;
   12253 }
   12254 
   12255 /* Is the domain of "map" a wrapped relation?
   12256  */
   12257 isl_bool isl_map_domain_is_wrapping(__isl_keep isl_map *map)
   12258 {
   12259 	if (!map)
   12260 		return isl_bool_error;
   12261 
   12262 	return isl_space_domain_is_wrapping(map->dim);
   12263 }
   12264 
   12265 /* Does "map" have a wrapped relation in both domain and range?
   12266  */
   12267 isl_bool isl_map_is_product(__isl_keep isl_map *map)
   12268 {
   12269 	return isl_space_is_product(isl_map_peek_space(map));
   12270 }
   12271 
   12272 /* Is the range of "map" a wrapped relation?
   12273  */
   12274 isl_bool isl_map_range_is_wrapping(__isl_keep isl_map *map)
   12275 {
   12276 	if (!map)
   12277 		return isl_bool_error;
   12278 
   12279 	return isl_space_range_is_wrapping(map->dim);
   12280 }
   12281 
   12282 __isl_give isl_basic_set *isl_basic_map_wrap(__isl_take isl_basic_map *bmap)
   12283 {
   12284 	isl_space *space;
   12285 
   12286 	space = isl_basic_map_take_space(bmap);
   12287 	space = isl_space_wrap(space);
   12288 	bmap = isl_basic_map_restore_space(bmap, space);
   12289 
   12290 	bmap = isl_basic_map_finalize(bmap);
   12291 
   12292 	return bset_from_bmap(bmap);
   12293 }
   12294 
   12295 /* Given a map A -> B, return the set (A -> B).
   12296  */
   12297 __isl_give isl_set *isl_map_wrap(__isl_take isl_map *map)
   12298 {
   12299 	return isl_map_change_space(map, NULL, NULL, &isl_space_wrap);
   12300 }
   12301 
   12302 __isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_set *bset)
   12303 {
   12304 	bset = isl_basic_set_cow(bset);
   12305 	if (!bset)
   12306 		return NULL;
   12307 
   12308 	bset->dim = isl_space_unwrap(bset->dim);
   12309 	if (!bset->dim)
   12310 		goto error;
   12311 
   12312 	bset = isl_basic_set_finalize(bset);
   12313 
   12314 	return bset_to_bmap(bset);
   12315 error:
   12316 	isl_basic_set_free(bset);
   12317 	return NULL;
   12318 }
   12319 
   12320 /* Given a set (A -> B), return the map A -> B.
   12321  * Error out if "set" is not of the form (A -> B).
   12322  */
   12323 __isl_give isl_map *isl_set_unwrap(__isl_take isl_set *set)
   12324 {
   12325 	return isl_map_change_space(set, &isl_set_is_wrapping,
   12326 				    "not a wrapping set", &isl_space_unwrap);
   12327 }
   12328 
   12329 __isl_give isl_basic_map *isl_basic_map_reset(__isl_take isl_basic_map *bmap,
   12330 	enum isl_dim_type type)
   12331 {
   12332 	isl_space *space;
   12333 
   12334 	space = isl_basic_map_take_space(bmap);
   12335 	space = isl_space_reset(space, type);
   12336 	bmap = isl_basic_map_restore_space(bmap, space);
   12337 
   12338 	bmap = isl_basic_map_mark_final(bmap);
   12339 
   12340 	return bmap;
   12341 }
   12342 
   12343 __isl_give isl_map *isl_map_reset(__isl_take isl_map *map,
   12344 	enum isl_dim_type type)
   12345 {
   12346 	int i;
   12347 	isl_space *space;
   12348 
   12349 	if (!map)
   12350 		return NULL;
   12351 
   12352 	if (!isl_space_is_named_or_nested(map->dim, type))
   12353 		return map;
   12354 
   12355 	map = isl_map_cow(map);
   12356 	if (!map)
   12357 		return NULL;
   12358 
   12359 	for (i = 0; i < map->n; ++i) {
   12360 		map->p[i] = isl_basic_map_reset(map->p[i], type);
   12361 		if (!map->p[i])
   12362 			goto error;
   12363 	}
   12364 
   12365 	space = isl_map_take_space(map);
   12366 	space = isl_space_reset(space, type);
   12367 	map = isl_map_restore_space(map, space);
   12368 
   12369 	return map;
   12370 error:
   12371 	isl_map_free(map);
   12372 	return NULL;
   12373 }
   12374 
   12375 __isl_give isl_basic_map *isl_basic_map_flatten(__isl_take isl_basic_map *bmap)
   12376 {
   12377 	isl_space *space;
   12378 
   12379 	space = isl_basic_map_take_space(bmap);
   12380 	space = isl_space_flatten(space);
   12381 	bmap = isl_basic_map_restore_space(bmap, space);
   12382 
   12383 	bmap = isl_basic_map_mark_final(bmap);
   12384 
   12385 	return bmap;
   12386 }
   12387 
   12388 __isl_give isl_basic_set *isl_basic_set_flatten(__isl_take isl_basic_set *bset)
   12389 {
   12390 	return bset_from_bmap(isl_basic_map_flatten(bset_to_bmap(bset)));
   12391 }
   12392 
   12393 __isl_give isl_basic_map *isl_basic_map_flatten_domain(
   12394 	__isl_take isl_basic_map *bmap)
   12395 {
   12396 	isl_space *space;
   12397 
   12398 	space = isl_basic_map_take_space(bmap);
   12399 	space = isl_space_flatten_domain(space);
   12400 	bmap = isl_basic_map_restore_space(bmap, space);
   12401 
   12402 	bmap = isl_basic_map_mark_final(bmap);
   12403 
   12404 	return bmap;
   12405 }
   12406 
   12407 __isl_give isl_basic_map *isl_basic_map_flatten_range(
   12408 	__isl_take isl_basic_map *bmap)
   12409 {
   12410 	isl_space *space;
   12411 
   12412 	space = isl_basic_map_take_space(bmap);
   12413 	space = isl_space_flatten_range(space);
   12414 	bmap = isl_basic_map_restore_space(bmap, space);
   12415 
   12416 	bmap = isl_basic_map_mark_final(bmap);
   12417 
   12418 	return bmap;
   12419 }
   12420 
   12421 /* Remove any internal structure from the spaces of domain and range of "map".
   12422  */
   12423 __isl_give isl_map *isl_map_flatten(__isl_take isl_map *map)
   12424 {
   12425 	if (!map)
   12426 		return NULL;
   12427 
   12428 	if (!map->dim->nested[0] && !map->dim->nested[1])
   12429 		return map;
   12430 
   12431 	return isl_map_change_space(map, NULL, NULL, &isl_space_flatten);
   12432 }
   12433 
   12434 __isl_give isl_set *isl_set_flatten(__isl_take isl_set *set)
   12435 {
   12436 	return set_from_map(isl_map_flatten(set_to_map(set)));
   12437 }
   12438 
   12439 __isl_give isl_map *isl_set_flatten_map(__isl_take isl_set *set)
   12440 {
   12441 	isl_space *space, *flat_space;
   12442 	isl_map *map;
   12443 
   12444 	space = isl_set_get_space(set);
   12445 	flat_space = isl_space_flatten(isl_space_copy(space));
   12446 	map = isl_map_identity(isl_space_join(isl_space_reverse(space),
   12447 						flat_space));
   12448 	map = isl_map_intersect_domain(map, set);
   12449 
   12450 	return map;
   12451 }
   12452 
   12453 /* Remove any internal structure from the space of the domain of "map".
   12454  */
   12455 __isl_give isl_map *isl_map_flatten_domain(__isl_take isl_map *map)
   12456 {
   12457 	if (!map)
   12458 		return NULL;
   12459 
   12460 	if (!map->dim->nested[0])
   12461 		return map;
   12462 
   12463 	return isl_map_change_space(map, NULL, NULL, &isl_space_flatten_domain);
   12464 }
   12465 
   12466 /* Remove any internal structure from the space of the range of "map".
   12467  */
   12468 __isl_give isl_map *isl_map_flatten_range(__isl_take isl_map *map)
   12469 {
   12470 	if (!map)
   12471 		return NULL;
   12472 
   12473 	if (!map->dim->nested[1])
   12474 		return map;
   12475 
   12476 	return isl_map_change_space(map, NULL, NULL, &isl_space_flatten_range);
   12477 }
   12478 
   12479 /* Reorder the dimensions of "bmap" according to the given dim_map
   12480  * and set the dimension specification to "space" and
   12481  * perform Gaussian elimination on the result.
   12482  */
   12483 __isl_give isl_basic_map *isl_basic_map_realign(__isl_take isl_basic_map *bmap,
   12484 	__isl_take isl_space *space, __isl_take struct isl_dim_map *dim_map)
   12485 {
   12486 	isl_basic_map *res;
   12487 	unsigned flags;
   12488 	isl_size n_div;
   12489 
   12490 	n_div = isl_basic_map_dim(bmap, isl_dim_div);
   12491 	if (n_div < 0 || !space || !dim_map)
   12492 		goto error;
   12493 
   12494 	flags = bmap->flags;
   12495 	ISL_FL_CLR(flags, ISL_BASIC_MAP_FINAL);
   12496 	ISL_FL_CLR(flags, ISL_BASIC_MAP_SORTED);
   12497 	ISL_FL_CLR(flags, ISL_BASIC_MAP_NORMALIZED_DIVS);
   12498 	res = isl_basic_map_alloc_space(space, n_div, bmap->n_eq, bmap->n_ineq);
   12499 	res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
   12500 	if (res)
   12501 		res->flags = flags;
   12502 	res = isl_basic_map_gauss(res, NULL);
   12503 	res = isl_basic_map_finalize(res);
   12504 	return res;
   12505 error:
   12506 	isl_dim_map_free(dim_map);
   12507 	isl_basic_map_free(bmap);
   12508 	isl_space_free(space);
   12509 	return NULL;
   12510 }
   12511 
   12512 /* Reorder the dimensions of "map" according to given reordering.
   12513  */
   12514 __isl_give isl_map *isl_map_realign(__isl_take isl_map *map,
   12515 	__isl_take isl_reordering *r)
   12516 {
   12517 	int i;
   12518 	struct isl_dim_map *dim_map;
   12519 
   12520 	map = isl_map_cow(map);
   12521 	dim_map = isl_dim_map_from_reordering(r);
   12522 	if (!map || !r || !dim_map)
   12523 		goto error;
   12524 
   12525 	for (i = 0; i < map->n; ++i) {
   12526 		struct isl_dim_map *dim_map_i;
   12527 		isl_space *space;
   12528 
   12529 		dim_map_i = isl_dim_map_extend(dim_map, map->p[i]);
   12530 
   12531 		space = isl_reordering_get_space(r);
   12532 		map->p[i] = isl_basic_map_realign(map->p[i], space, dim_map_i);
   12533 
   12534 		if (!map->p[i])
   12535 			goto error;
   12536 	}
   12537 
   12538 	map = isl_map_reset_space(map, isl_reordering_get_space(r));
   12539 	map = isl_map_unmark_normalized(map);
   12540 
   12541 	isl_reordering_free(r);
   12542 	isl_dim_map_free(dim_map);
   12543 	return map;
   12544 error:
   12545 	isl_dim_map_free(dim_map);
   12546 	isl_map_free(map);
   12547 	isl_reordering_free(r);
   12548 	return NULL;
   12549 }
   12550 
   12551 __isl_give isl_set *isl_set_realign(__isl_take isl_set *set,
   12552 	__isl_take isl_reordering *r)
   12553 {
   12554 	return set_from_map(isl_map_realign(set_to_map(set), r));
   12555 }
   12556 
   12557 __isl_give isl_map *isl_map_align_params(__isl_take isl_map *map,
   12558 	__isl_take isl_space *model)
   12559 {
   12560 	isl_ctx *ctx;
   12561 	isl_bool aligned;
   12562 
   12563 	if (!map || !model)
   12564 		goto error;
   12565 
   12566 	ctx = isl_space_get_ctx(model);
   12567 	if (!isl_space_has_named_params(model))
   12568 		isl_die(ctx, isl_error_invalid,
   12569 			"model has unnamed parameters", goto error);
   12570 	if (isl_map_check_named_params(map) < 0)
   12571 		goto error;
   12572 	aligned = isl_map_space_has_equal_params(map, model);
   12573 	if (aligned < 0)
   12574 		goto error;
   12575 	if (!aligned) {
   12576 		isl_space *space;
   12577 		isl_reordering *exp;
   12578 
   12579 		space = isl_map_peek_space(map);
   12580 		exp = isl_parameter_alignment_reordering(space, model);
   12581 		map = isl_map_realign(map, exp);
   12582 	}
   12583 
   12584 	isl_space_free(model);
   12585 	return map;
   12586 error:
   12587 	isl_space_free(model);
   12588 	isl_map_free(map);
   12589 	return NULL;
   12590 }
   12591 
   12592 __isl_give isl_set *isl_set_align_params(__isl_take isl_set *set,
   12593 	__isl_take isl_space *model)
   12594 {
   12595 	return isl_map_align_params(set, model);
   12596 }
   12597 
   12598 /* Align the parameters of "bmap" to those of "model", introducing
   12599  * additional parameters if needed.
   12600  */
   12601 __isl_give isl_basic_map *isl_basic_map_align_params(
   12602 	__isl_take isl_basic_map *bmap, __isl_take isl_space *model)
   12603 {
   12604 	isl_ctx *ctx;
   12605 	isl_bool equal_params;
   12606 	isl_space *bmap_space;
   12607 
   12608 	if (!bmap || !model)
   12609 		goto error;
   12610 
   12611 	ctx = isl_space_get_ctx(model);
   12612 	if (!isl_space_has_named_params(model))
   12613 		isl_die(ctx, isl_error_invalid,
   12614 			"model has unnamed parameters", goto error);
   12615 	if (isl_basic_map_check_named_params(bmap) < 0)
   12616 		goto error;
   12617 	bmap_space = isl_basic_map_peek_space(bmap);
   12618 	equal_params = isl_space_has_equal_params(bmap_space, model);
   12619 	if (equal_params < 0)
   12620 		goto error;
   12621 	if (!equal_params) {
   12622 		isl_reordering *exp;
   12623 		struct isl_dim_map *dim_map;
   12624 
   12625 		exp = isl_parameter_alignment_reordering(bmap_space, model);
   12626 		dim_map = isl_dim_map_from_reordering(exp);
   12627 		bmap = isl_basic_map_realign(bmap,
   12628 				    isl_reordering_get_space(exp),
   12629 				    isl_dim_map_extend(dim_map, bmap));
   12630 		isl_reordering_free(exp);
   12631 		isl_dim_map_free(dim_map);
   12632 	}
   12633 
   12634 	isl_space_free(model);
   12635 	return bmap;
   12636 error:
   12637 	isl_space_free(model);
   12638 	isl_basic_map_free(bmap);
   12639 	return NULL;
   12640 }
   12641 
   12642 /* Do "bset" and "space" have the same parameters?
   12643  */
   12644 isl_bool isl_basic_set_space_has_equal_params(__isl_keep isl_basic_set *bset,
   12645 	__isl_keep isl_space *space)
   12646 {
   12647 	isl_space *bset_space;
   12648 
   12649 	bset_space = isl_basic_set_peek_space(bset);
   12650 	return isl_space_has_equal_params(bset_space, space);
   12651 }
   12652 
   12653 /* Do "map" and "space" have the same parameters?
   12654  */
   12655 isl_bool isl_map_space_has_equal_params(__isl_keep isl_map *map,
   12656 	__isl_keep isl_space *space)
   12657 {
   12658 	isl_space *map_space;
   12659 
   12660 	map_space = isl_map_peek_space(map);
   12661 	return isl_space_has_equal_params(map_space, space);
   12662 }
   12663 
   12664 /* Do "set" and "space" have the same parameters?
   12665  */
   12666 isl_bool isl_set_space_has_equal_params(__isl_keep isl_set *set,
   12667 	__isl_keep isl_space *space)
   12668 {
   12669 	return isl_map_space_has_equal_params(set_to_map(set), space);
   12670 }
   12671 
   12672 /* Align the parameters of "bset" to those of "model", introducing
   12673  * additional parameters if needed.
   12674  */
   12675 __isl_give isl_basic_set *isl_basic_set_align_params(
   12676 	__isl_take isl_basic_set *bset, __isl_take isl_space *model)
   12677 {
   12678 	return isl_basic_map_align_params(bset, model);
   12679 }
   12680 
   12681 #undef TYPE
   12682 #define TYPE	isl_map
   12683 #define isl_map_drop_dims	isl_map_drop
   12684 #include "isl_drop_unused_params_templ.c"
   12685 
   12686 /* Drop all parameters not referenced by "set".
   12687  */
   12688 __isl_give isl_set *isl_set_drop_unused_params(
   12689 	__isl_take isl_set *set)
   12690 {
   12691 	return set_from_map(isl_map_drop_unused_params(set_to_map(set)));
   12692 }
   12693 
   12694 #undef TYPE
   12695 #define TYPE	isl_basic_map
   12696 #define isl_basic_map_drop_dims	isl_basic_map_drop
   12697 #include "isl_drop_unused_params_templ.c"
   12698 
   12699 /* Drop all parameters not referenced by "bset".
   12700  */
   12701 __isl_give isl_basic_set *isl_basic_set_drop_unused_params(
   12702 	__isl_take isl_basic_set *bset)
   12703 {
   12704 	return bset_from_bmap(isl_basic_map_drop_unused_params(
   12705 							bset_to_bmap(bset)));
   12706 }
   12707 
   12708 /* Given a tuple of identifiers "tuple" in a space that corresponds
   12709  * to that of "set", if any of those identifiers appear as parameters
   12710  * in "set", then equate those parameters with the corresponding
   12711  * set dimensions and project out the parameters.
   12712  * The result therefore has no such parameters.
   12713  */
   12714 static __isl_give isl_set *equate_params(__isl_take isl_set *set,
   12715 	__isl_keep isl_multi_id *tuple)
   12716 {
   12717 	int i;
   12718 	isl_size n;
   12719 	isl_space *set_space, *tuple_space;
   12720 
   12721 	set_space = isl_set_peek_space(set);
   12722 	tuple_space = isl_multi_id_peek_space(tuple);
   12723 	if (isl_space_check_equal_tuples(tuple_space, set_space) < 0)
   12724 		return isl_set_free(set);
   12725 	n = isl_multi_id_size(tuple);
   12726 	if (n < 0)
   12727 		return isl_set_free(set);
   12728 	for (i = 0; i < n; ++i) {
   12729 		isl_id *id;
   12730 		int pos;
   12731 
   12732 		id = isl_multi_id_get_at(tuple, i);
   12733 		if (!id)
   12734 			return isl_set_free(set);
   12735 		pos = isl_set_find_dim_by_id(set, isl_dim_param, id);
   12736 		isl_id_free(id);
   12737 		if (pos < 0)
   12738 			continue;
   12739 		set = isl_set_equate(set, isl_dim_param, pos, isl_dim_set, i);
   12740 		set = isl_set_project_out(set, isl_dim_param, pos, 1);
   12741 	}
   12742 	return set;
   12743 }
   12744 
   12745 /* Bind the set dimensions of "set" to parameters with identifiers
   12746  * specified by "tuple", living in the same space as "set".
   12747  *
   12748  * If no parameters with these identifiers appear in "set" already,
   12749  * then the set dimensions are simply reinterpreted as parameters.
   12750  * Otherwise, the parameters are first equated to the corresponding
   12751  * set dimensions.
   12752  */
   12753 __isl_give isl_set *isl_set_bind(__isl_take isl_set *set,
   12754 	__isl_take isl_multi_id *tuple)
   12755 {
   12756 	isl_space *space;
   12757 
   12758 	set = equate_params(set, tuple);
   12759 	space = isl_set_get_space(set);
   12760 	space = isl_space_bind_set(space, tuple);
   12761 	isl_multi_id_free(tuple);
   12762 	set = isl_set_reset_space(set, space);
   12763 
   12764 	return set;
   12765 }
   12766 
   12767 /* Given a tuple of identifiers "tuple" in a space that corresponds
   12768  * to the domain of "map", if any of those identifiers appear as parameters
   12769  * in "map", then equate those parameters with the corresponding
   12770  * input dimensions and project out the parameters.
   12771  * The result therefore has no such parameters.
   12772  */
   12773 static __isl_give isl_map *map_equate_params(__isl_take isl_map *map,
   12774 	__isl_keep isl_multi_id *tuple)
   12775 {
   12776 	int i;
   12777 	isl_size n;
   12778 	isl_space *map_space, *tuple_space;
   12779 
   12780 	map_space = isl_map_peek_space(map);
   12781 	tuple_space = isl_multi_id_peek_space(tuple);
   12782 	if (isl_space_check_domain_tuples(tuple_space, map_space) < 0)
   12783 		return isl_map_free(map);
   12784 	n = isl_multi_id_size(tuple);
   12785 	if (n < 0)
   12786 		return isl_map_free(map);
   12787 	for (i = 0; i < n; ++i) {
   12788 		isl_id *id;
   12789 		int pos;
   12790 
   12791 		id = isl_multi_id_get_at(tuple, i);
   12792 		if (!id)
   12793 			return isl_map_free(map);
   12794 		pos = isl_map_find_dim_by_id(map, isl_dim_param, id);
   12795 		isl_id_free(id);
   12796 		if (pos < 0)
   12797 			continue;
   12798 		map = isl_map_equate(map, isl_dim_param, pos, isl_dim_in, i);
   12799 		map = isl_map_project_out(map, isl_dim_param, pos, 1);
   12800 	}
   12801 	return map;
   12802 }
   12803 
   12804 /* Bind the input dimensions of "map" to parameters with identifiers
   12805  * specified by "tuple", living in the domain space of "map".
   12806  *
   12807  * If no parameters with these identifiers appear in "map" already,
   12808  * then the input dimensions are simply reinterpreted as parameters.
   12809  * Otherwise, the parameters are first equated to the corresponding
   12810  * input dimensions.
   12811  */
   12812 __isl_give isl_set *isl_map_bind_domain(__isl_take isl_map *map,
   12813 	__isl_take isl_multi_id *tuple)
   12814 {
   12815 	isl_space *space;
   12816 	isl_set *set;
   12817 
   12818 	map = map_equate_params(map, tuple);
   12819 	space = isl_map_get_space(map);
   12820 	space = isl_space_bind_map_domain(space, tuple);
   12821 	isl_multi_id_free(tuple);
   12822 	set = set_from_map(isl_map_reset_space(map, space));
   12823 
   12824 	return set;
   12825 }
   12826 
   12827 /* Bind the output dimensions of "map" to parameters with identifiers
   12828  * specified by "tuple", living in the range space of "map".
   12829  *
   12830  * Since binding is more easily implemented on the domain,
   12831  * bind the input dimensions of the inverse of "map".
   12832  */
   12833 __isl_give isl_set *isl_map_bind_range(__isl_take isl_map *map,
   12834 	__isl_take isl_multi_id *tuple)
   12835 {
   12836 	return isl_map_bind_domain(isl_map_reverse(map), tuple);
   12837 }
   12838 
   12839 /* Insert a domain corresponding to "tuple"
   12840  * into the nullary or unary relation "set".
   12841  * The result has an extra initial tuple and is therefore
   12842  * either a unary or binary relation.
   12843  * Any parameters with identifiers in "tuple" are reinterpreted
   12844  * as the corresponding domain dimensions.
   12845  */
   12846 static __isl_give isl_map *unbind_params_insert_domain(
   12847 	__isl_take isl_set *set, __isl_take isl_multi_id *tuple)
   12848 {
   12849 	isl_space *space;
   12850 	isl_reordering *r;
   12851 
   12852 	space = isl_set_peek_space(set);
   12853 	r = isl_reordering_unbind_params_insert_domain(space, tuple);
   12854 	isl_multi_id_free(tuple);
   12855 
   12856 	return isl_map_realign(set_to_map(set), r);
   12857 }
   12858 
   12859 /* Construct a set with "tuple" as domain from the parameter domain "set".
   12860  * Any parameters with identifiers in "tuple" are reinterpreted
   12861  * as the corresponding set dimensions.
   12862  */
   12863 __isl_give isl_set *isl_set_unbind_params(__isl_take isl_set *set,
   12864 	__isl_take isl_multi_id *tuple)
   12865 {
   12866 	isl_bool is_params;
   12867 
   12868 	is_params = isl_set_is_params(set);
   12869 	if (is_params < 0)
   12870 		set = isl_set_free(set);
   12871 	else if (!is_params)
   12872 		isl_die(isl_set_get_ctx(set), isl_error_invalid,
   12873 			"expecting parameter domain", set = isl_set_free(set));
   12874 	return set_from_map(unbind_params_insert_domain(set, tuple));
   12875 }
   12876 
   12877 /* Check that "set" is a proper set, i.e., that it is not a parameter domain.
   12878  */
   12879 static isl_stat isl_set_check_is_set(__isl_keep isl_set *set)
   12880 {
   12881 	isl_bool is_params;
   12882 
   12883 	is_params = isl_set_is_params(set);
   12884 	if (is_params < 0)
   12885 		return isl_stat_error;
   12886 	else if (is_params)
   12887 		isl_die(isl_set_get_ctx(set), isl_error_invalid,
   12888 			"expecting proper set", return isl_stat_error);
   12889 
   12890 	return isl_stat_ok;
   12891 }
   12892 
   12893 /* Construct a map with "domain" as domain and "set" as range.
   12894  * Any parameters with identifiers in "domain" are reinterpreted
   12895  * as the corresponding domain dimensions.
   12896  */
   12897 __isl_give isl_map *isl_set_unbind_params_insert_domain(
   12898 	__isl_take isl_set *set, __isl_take isl_multi_id *domain)
   12899 {
   12900 	if (isl_set_check_is_set(set) < 0)
   12901 		set = isl_set_free(set);
   12902 	return unbind_params_insert_domain(set, domain);
   12903 }
   12904 
   12905 /* Construct a map with "domain" as domain and "set" as range.
   12906  */
   12907 __isl_give isl_map *isl_set_insert_domain(__isl_take isl_set *set,
   12908 	__isl_take isl_space *domain)
   12909 {
   12910 	isl_size dim;
   12911 	isl_space *space;
   12912 	isl_map *map;
   12913 
   12914 	if (isl_set_check_is_set(set) < 0 || isl_space_check_is_set(domain) < 0)
   12915 		domain = isl_space_free(domain);
   12916 	dim = isl_space_dim(domain, isl_dim_set);
   12917 	if (dim < 0)
   12918 		domain = isl_space_free(domain);
   12919 	space = isl_set_get_space(set);
   12920 	domain = isl_space_replace_params(domain, space);
   12921 	space = isl_space_map_from_domain_and_range(domain, space);
   12922 
   12923 	map = isl_map_from_range(set);
   12924 	map = isl_map_add_dims(map, isl_dim_in, dim);
   12925 	map = isl_map_reset_space(map, space);
   12926 
   12927 	return map;
   12928 }
   12929 
   12930 __isl_give isl_mat *isl_basic_map_equalities_matrix(
   12931 		__isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
   12932 		enum isl_dim_type c2, enum isl_dim_type c3,
   12933 		enum isl_dim_type c4, enum isl_dim_type c5)
   12934 {
   12935 	enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
   12936 	struct isl_mat *mat;
   12937 	int i, j, k;
   12938 	int pos;
   12939 	isl_size total;
   12940 
   12941 	total = isl_basic_map_dim(bmap, isl_dim_all);
   12942 	if (total < 0)
   12943 		return NULL;
   12944 	mat = isl_mat_alloc(bmap->ctx, bmap->n_eq, total + 1);
   12945 	if (!mat)
   12946 		return NULL;
   12947 	for (i = 0; i < bmap->n_eq; ++i)
   12948 		for (j = 0, pos = 0; j < 5; ++j) {
   12949 			int off = isl_basic_map_offset(bmap, c[j]);
   12950 			isl_size dim = isl_basic_map_dim(bmap, c[j]);
   12951 			if (dim < 0)
   12952 				return isl_mat_free(mat);
   12953 			for (k = 0; k < dim; ++k) {
   12954 				isl_int_set(mat->row[i][pos],
   12955 					    bmap->eq[i][off + k]);
   12956 				++pos;
   12957 			}
   12958 		}
   12959 
   12960 	return mat;
   12961 }
   12962 
   12963 __isl_give isl_mat *isl_basic_map_inequalities_matrix(
   12964 		__isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
   12965 		enum isl_dim_type c2, enum isl_dim_type c3,
   12966 		enum isl_dim_type c4, enum isl_dim_type c5)
   12967 {
   12968 	enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
   12969 	struct isl_mat *mat;
   12970 	int i, j, k;
   12971 	int pos;
   12972 	isl_size total;
   12973 
   12974 	total = isl_basic_map_dim(bmap, isl_dim_all);
   12975 	if (total < 0)
   12976 		return NULL;
   12977 	mat = isl_mat_alloc(bmap->ctx, bmap->n_ineq, total + 1);
   12978 	if (!mat)
   12979 		return NULL;
   12980 	for (i = 0; i < bmap->n_ineq; ++i)
   12981 		for (j = 0, pos = 0; j < 5; ++j) {
   12982 			int off = isl_basic_map_offset(bmap, c[j]);
   12983 			isl_size dim = isl_basic_map_dim(bmap, c[j]);
   12984 			if (dim < 0)
   12985 				return isl_mat_free(mat);
   12986 			for (k = 0; k < dim; ++k) {
   12987 				isl_int_set(mat->row[i][pos],
   12988 					    bmap->ineq[i][off + k]);
   12989 				++pos;
   12990 			}
   12991 		}
   12992 
   12993 	return mat;
   12994 }
   12995 
   12996 __isl_give isl_basic_map *isl_basic_map_from_constraint_matrices(
   12997 	__isl_take isl_space *space,
   12998 	__isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
   12999 	enum isl_dim_type c2, enum isl_dim_type c3,
   13000 	enum isl_dim_type c4, enum isl_dim_type c5)
   13001 {
   13002 	enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
   13003 	isl_basic_map *bmap = NULL;
   13004 	isl_size dim;
   13005 	unsigned total;
   13006 	unsigned extra;
   13007 	int i, j, k, l;
   13008 	int pos;
   13009 
   13010 	dim = isl_space_dim(space, isl_dim_all);
   13011 	if (dim < 0 || !eq || !ineq)
   13012 		goto error;
   13013 
   13014 	if (eq->n_col != ineq->n_col)
   13015 		isl_die(space->ctx, isl_error_invalid,
   13016 			"equalities and inequalities matrices should have "
   13017 			"same number of columns", goto error);
   13018 
   13019 	total = 1 + dim;
   13020 
   13021 	if (eq->n_col < total)
   13022 		isl_die(space->ctx, isl_error_invalid,
   13023 			"number of columns too small", goto error);
   13024 
   13025 	extra = eq->n_col - total;
   13026 
   13027 	bmap = isl_basic_map_alloc_space(isl_space_copy(space), extra,
   13028 				       eq->n_row, ineq->n_row);
   13029 	if (!bmap)
   13030 		goto error;
   13031 	for (i = 0; i < extra; ++i) {
   13032 		k = isl_basic_map_alloc_div(bmap);
   13033 		if (k < 0)
   13034 			goto error;
   13035 		isl_int_set_si(bmap->div[k][0], 0);
   13036 	}
   13037 	for (i = 0; i < eq->n_row; ++i) {
   13038 		l = isl_basic_map_alloc_equality(bmap);
   13039 		if (l < 0)
   13040 			goto error;
   13041 		for (j = 0, pos = 0; j < 5; ++j) {
   13042 			int off = isl_basic_map_offset(bmap, c[j]);
   13043 			isl_size dim = isl_basic_map_dim(bmap, c[j]);
   13044 			if (dim < 0)
   13045 				goto error;
   13046 			for (k = 0; k < dim; ++k) {
   13047 				isl_int_set(bmap->eq[l][off + k],
   13048 					    eq->row[i][pos]);
   13049 				++pos;
   13050 			}
   13051 		}
   13052 	}
   13053 	for (i = 0; i < ineq->n_row; ++i) {
   13054 		l = isl_basic_map_alloc_inequality(bmap);
   13055 		if (l < 0)
   13056 			goto error;
   13057 		for (j = 0, pos = 0; j < 5; ++j) {
   13058 			int off = isl_basic_map_offset(bmap, c[j]);
   13059 			isl_size dim = isl_basic_map_dim(bmap, c[j]);
   13060 			if (dim < 0)
   13061 				goto error;
   13062 			for (k = 0; k < dim; ++k) {
   13063 				isl_int_set(bmap->ineq[l][off + k],
   13064 					    ineq->row[i][pos]);
   13065 				++pos;
   13066 			}
   13067 		}
   13068 	}
   13069 
   13070 	isl_space_free(space);
   13071 	isl_mat_free(eq);
   13072 	isl_mat_free(ineq);
   13073 
   13074 	bmap = isl_basic_map_simplify(bmap);
   13075 	return isl_basic_map_finalize(bmap);
   13076 error:
   13077 	isl_space_free(space);
   13078 	isl_mat_free(eq);
   13079 	isl_mat_free(ineq);
   13080 	isl_basic_map_free(bmap);
   13081 	return NULL;
   13082 }
   13083 
   13084 __isl_give isl_mat *isl_basic_set_equalities_matrix(
   13085 	__isl_keep isl_basic_set *bset, enum isl_dim_type c1,
   13086 	enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
   13087 {
   13088 	return isl_basic_map_equalities_matrix(bset_to_bmap(bset),
   13089 						c1, c2, c3, c4, isl_dim_in);
   13090 }
   13091 
   13092 __isl_give isl_mat *isl_basic_set_inequalities_matrix(
   13093 	__isl_keep isl_basic_set *bset, enum isl_dim_type c1,
   13094 	enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
   13095 {
   13096 	return isl_basic_map_inequalities_matrix(bset_to_bmap(bset),
   13097 						 c1, c2, c3, c4, isl_dim_in);
   13098 }
   13099 
   13100 __isl_give isl_basic_set *isl_basic_set_from_constraint_matrices(
   13101 	__isl_take isl_space *space,
   13102 	__isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
   13103 	enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
   13104 {
   13105 	isl_basic_map *bmap;
   13106 	bmap = isl_basic_map_from_constraint_matrices(space, eq, ineq,
   13107 						   c1, c2, c3, c4, isl_dim_in);
   13108 	return bset_from_bmap(bmap);
   13109 }
   13110 
   13111 isl_bool isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap)
   13112 {
   13113 	if (!bmap)
   13114 		return isl_bool_error;
   13115 
   13116 	return isl_space_can_zip(bmap->dim);
   13117 }
   13118 
   13119 isl_bool isl_map_can_zip(__isl_keep isl_map *map)
   13120 {
   13121 	if (!map)
   13122 		return isl_bool_error;
   13123 
   13124 	return isl_space_can_zip(map->dim);
   13125 }
   13126 
   13127 /* Given a basic map (A -> B) -> (C -> D), return the corresponding basic map
   13128  * (A -> C) -> (B -> D).
   13129  */
   13130 __isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap)
   13131 {
   13132 	unsigned pos;
   13133 	isl_size n_in;
   13134 	isl_size n1;
   13135 	isl_size n2;
   13136 
   13137 	if (!bmap)
   13138 		return NULL;
   13139 
   13140 	if (!isl_basic_map_can_zip(bmap))
   13141 		isl_die(bmap->ctx, isl_error_invalid,
   13142 			"basic map cannot be zipped", goto error);
   13143 	n_in = isl_space_dim(bmap->dim->nested[0], isl_dim_in);
   13144 	n1 = isl_space_dim(bmap->dim->nested[0], isl_dim_out);
   13145 	n2 = isl_space_dim(bmap->dim->nested[1], isl_dim_in);
   13146 	if (n_in < 0 || n1 < 0 || n2 < 0)
   13147 		return isl_basic_map_free(bmap);
   13148 	pos = isl_basic_map_offset(bmap, isl_dim_in) + n_in;
   13149 	bmap = isl_basic_map_cow(bmap);
   13150 	bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
   13151 	if (!bmap)
   13152 		return NULL;
   13153 	bmap->dim = isl_space_zip(bmap->dim);
   13154 	if (!bmap->dim)
   13155 		goto error;
   13156 	bmap = isl_basic_map_mark_final(bmap);
   13157 	return bmap;
   13158 error:
   13159 	isl_basic_map_free(bmap);
   13160 	return NULL;
   13161 }
   13162 
   13163 /* Given a map (A -> B) -> (C -> D), return the corresponding map
   13164  * (A -> C) -> (B -> D).
   13165  */
   13166 __isl_give isl_map *isl_map_zip(__isl_take isl_map *map)
   13167 {
   13168 	if (!map)
   13169 		return NULL;
   13170 
   13171 	if (!isl_map_can_zip(map))
   13172 		isl_die(map->ctx, isl_error_invalid, "map cannot be zipped",
   13173 			goto error);
   13174 
   13175 	return isl_map_transform(map, &isl_space_zip, &isl_basic_map_zip);
   13176 error:
   13177 	isl_map_free(map);
   13178 	return NULL;
   13179 }
   13180 
   13181 /* Can we apply isl_basic_map_curry to "bmap"?
   13182  * That is, does it have a nested relation in its domain?
   13183  */
   13184 isl_bool isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap)
   13185 {
   13186 	if (!bmap)
   13187 		return isl_bool_error;
   13188 
   13189 	return isl_space_can_curry(bmap->dim);
   13190 }
   13191 
   13192 /* Can we apply isl_map_curry to "map"?
   13193  * That is, does it have a nested relation in its domain?
   13194  */
   13195 isl_bool isl_map_can_curry(__isl_keep isl_map *map)
   13196 {
   13197 	if (!map)
   13198 		return isl_bool_error;
   13199 
   13200 	return isl_space_can_curry(map->dim);
   13201 }
   13202 
   13203 /* Given a basic map (A -> B) -> C, return the corresponding basic map
   13204  * A -> (B -> C).
   13205  */
   13206 __isl_give isl_basic_map *isl_basic_map_curry(__isl_take isl_basic_map *bmap)
   13207 {
   13208 
   13209 	if (!bmap)
   13210 		return NULL;
   13211 
   13212 	if (!isl_basic_map_can_curry(bmap))
   13213 		isl_die(bmap->ctx, isl_error_invalid,
   13214 			"basic map cannot be curried", goto error);
   13215 	bmap = isl_basic_map_cow(bmap);
   13216 	if (!bmap)
   13217 		return NULL;
   13218 	bmap->dim = isl_space_curry(bmap->dim);
   13219 	if (!bmap->dim)
   13220 		goto error;
   13221 	bmap = isl_basic_map_mark_final(bmap);
   13222 	return bmap;
   13223 error:
   13224 	isl_basic_map_free(bmap);
   13225 	return NULL;
   13226 }
   13227 
   13228 /* Given a map (A -> B) -> C, return the corresponding map
   13229  * A -> (B -> C).
   13230  */
   13231 __isl_give isl_map *isl_map_curry(__isl_take isl_map *map)
   13232 {
   13233 	return isl_map_change_space(map, &isl_map_can_curry,
   13234 				    "map cannot be curried", &isl_space_curry);
   13235 }
   13236 
   13237 /* Can isl_map_range_curry be applied to "map"?
   13238  * That is, does it have a nested relation in its range,
   13239  * the domain of which is itself a nested relation?
   13240  */
   13241 isl_bool isl_map_can_range_curry(__isl_keep isl_map *map)
   13242 {
   13243 	if (!map)
   13244 		return isl_bool_error;
   13245 
   13246 	return isl_space_can_range_curry(map->dim);
   13247 }
   13248 
   13249 /* Given a map A -> ((B -> C) -> D), return the corresponding map
   13250  * A -> (B -> (C -> D)).
   13251  */
   13252 __isl_give isl_map *isl_map_range_curry(__isl_take isl_map *map)
   13253 {
   13254 	return isl_map_change_space(map, &isl_map_can_range_curry,
   13255 				    "map range cannot be curried",
   13256 				    &isl_space_range_curry);
   13257 }
   13258 
   13259 /* Can we apply isl_basic_map_uncurry to "bmap"?
   13260  * That is, does it have a nested relation in its domain?
   13261  */
   13262 isl_bool isl_basic_map_can_uncurry(__isl_keep isl_basic_map *bmap)
   13263 {
   13264 	if (!bmap)
   13265 		return isl_bool_error;
   13266 
   13267 	return isl_space_can_uncurry(bmap->dim);
   13268 }
   13269 
   13270 /* Can we apply isl_map_uncurry to "map"?
   13271  * That is, does it have a nested relation in its domain?
   13272  */
   13273 isl_bool isl_map_can_uncurry(__isl_keep isl_map *map)
   13274 {
   13275 	if (!map)
   13276 		return isl_bool_error;
   13277 
   13278 	return isl_space_can_uncurry(map->dim);
   13279 }
   13280 
   13281 /* Given a basic map A -> (B -> C), return the corresponding basic map
   13282  * (A -> B) -> C.
   13283  */
   13284 __isl_give isl_basic_map *isl_basic_map_uncurry(__isl_take isl_basic_map *bmap)
   13285 {
   13286 
   13287 	if (!bmap)
   13288 		return NULL;
   13289 
   13290 	if (!isl_basic_map_can_uncurry(bmap))
   13291 		isl_die(bmap->ctx, isl_error_invalid,
   13292 			"basic map cannot be uncurried",
   13293 			return isl_basic_map_free(bmap));
   13294 	bmap = isl_basic_map_cow(bmap);
   13295 	if (!bmap)
   13296 		return NULL;
   13297 	bmap->dim = isl_space_uncurry(bmap->dim);
   13298 	if (!bmap->dim)
   13299 		return isl_basic_map_free(bmap);
   13300 	bmap = isl_basic_map_mark_final(bmap);
   13301 	return bmap;
   13302 }
   13303 
   13304 /* Given a map A -> (B -> C), return the corresponding map
   13305  * (A -> B) -> C.
   13306  */
   13307 __isl_give isl_map *isl_map_uncurry(__isl_take isl_map *map)
   13308 {
   13309 	return isl_map_change_space(map, &isl_map_can_uncurry,
   13310 				"map cannot be uncurried", &isl_space_uncurry);
   13311 }
   13312 
   13313 __isl_give isl_set *isl_set_equate(__isl_take isl_set *set,
   13314 	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
   13315 {
   13316 	return isl_map_equate(set, type1, pos1, type2, pos2);
   13317 }
   13318 
   13319 /* Construct a basic map where the given dimensions are equal to each other.
   13320  */
   13321 static __isl_give isl_basic_map *equator(__isl_take isl_space *space,
   13322 	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
   13323 {
   13324 	isl_basic_map *bmap = NULL;
   13325 	int i;
   13326 	isl_size total;
   13327 
   13328 	total = isl_space_dim(space, isl_dim_all);
   13329 	if (total < 0 ||
   13330 	    isl_space_check_range(space, type1, pos1, 1) < 0 ||
   13331 	    isl_space_check_range(space, type2, pos2, 1) < 0)
   13332 		goto error;
   13333 
   13334 	if (type1 == type2 && pos1 == pos2)
   13335 		return isl_basic_map_universe(space);
   13336 
   13337 	bmap = isl_basic_map_alloc_space(isl_space_copy(space), 0, 1, 0);
   13338 	i = isl_basic_map_alloc_equality(bmap);
   13339 	if (i < 0)
   13340 		goto error;
   13341 	isl_seq_clr(bmap->eq[i], 1 + total);
   13342 	pos1 += isl_basic_map_offset(bmap, type1);
   13343 	pos2 += isl_basic_map_offset(bmap, type2);
   13344 	isl_int_set_si(bmap->eq[i][pos1], -1);
   13345 	isl_int_set_si(bmap->eq[i][pos2], 1);
   13346 	bmap = isl_basic_map_finalize(bmap);
   13347 	isl_space_free(space);
   13348 	return bmap;
   13349 error:
   13350 	isl_space_free(space);
   13351 	isl_basic_map_free(bmap);
   13352 	return NULL;
   13353 }
   13354 
   13355 /* Add a constraint imposing that the given two dimensions are equal.
   13356  */
   13357 __isl_give isl_basic_map *isl_basic_map_equate(__isl_take isl_basic_map *bmap,
   13358 	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
   13359 {
   13360 	isl_basic_map *eq;
   13361 
   13362 	eq = equator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2);
   13363 
   13364 	bmap = isl_basic_map_intersect(bmap, eq);
   13365 
   13366 	return bmap;
   13367 }
   13368 
   13369 /* Add a constraint imposing that the given two dimensions are equal.
   13370  */
   13371 __isl_give isl_map *isl_map_equate(__isl_take isl_map *map,
   13372 	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
   13373 {
   13374 	isl_basic_map *bmap;
   13375 
   13376 	bmap = equator(isl_map_get_space(map), type1, pos1, type2, pos2);
   13377 
   13378 	map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
   13379 
   13380 	return map;
   13381 }
   13382 
   13383 /* Add a constraint imposing that the given two dimensions have opposite values.
   13384  */
   13385 __isl_give isl_map *isl_map_oppose(__isl_take isl_map *map,
   13386 	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
   13387 {
   13388 	isl_basic_map *bmap = NULL;
   13389 	int i;
   13390 	isl_size total;
   13391 
   13392 	if (isl_map_check_range(map, type1, pos1, 1) < 0)
   13393 		return isl_map_free(map);
   13394 	if (isl_map_check_range(map, type2, pos2, 1) < 0)
   13395 		return isl_map_free(map);
   13396 
   13397 	total = isl_map_dim(map, isl_dim_all);
   13398 	if (total < 0)
   13399 		return isl_map_free(map);
   13400 	bmap = isl_basic_map_alloc_space(isl_map_get_space(map), 0, 1, 0);
   13401 	i = isl_basic_map_alloc_equality(bmap);
   13402 	if (i < 0)
   13403 		goto error;
   13404 	isl_seq_clr(bmap->eq[i], 1 + total);
   13405 	pos1 += isl_basic_map_offset(bmap, type1);
   13406 	pos2 += isl_basic_map_offset(bmap, type2);
   13407 	isl_int_set_si(bmap->eq[i][pos1], 1);
   13408 	isl_int_set_si(bmap->eq[i][pos2], 1);
   13409 	bmap = isl_basic_map_finalize(bmap);
   13410 
   13411 	map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
   13412 
   13413 	return map;
   13414 error:
   13415 	isl_basic_map_free(bmap);
   13416 	isl_map_free(map);
   13417 	return NULL;
   13418 }
   13419 
   13420 /* Construct a constraint imposing that the value of the first dimension is
   13421  * greater than or equal to that of the second.
   13422  */
   13423 static __isl_give isl_constraint *constraint_order_ge(
   13424 	__isl_take isl_space *space, enum isl_dim_type type1, int pos1,
   13425 	enum isl_dim_type type2, int pos2)
   13426 {
   13427 	isl_constraint *c;
   13428 
   13429 	if (isl_space_check_range(space, type1, pos1, 1) < 0 ||
   13430 	    isl_space_check_range(space, type2, pos2, 1) < 0)
   13431 		space = isl_space_free(space);
   13432 	if (!space)
   13433 		return NULL;
   13434 
   13435 	c = isl_constraint_alloc_inequality(isl_local_space_from_space(space));
   13436 
   13437 	if (type1 == type2 && pos1 == pos2)
   13438 		return c;
   13439 
   13440 	c = isl_constraint_set_coefficient_si(c, type1, pos1, 1);
   13441 	c = isl_constraint_set_coefficient_si(c, type2, pos2, -1);
   13442 
   13443 	return c;
   13444 }
   13445 
   13446 /* Add a constraint imposing that the value of the first dimension is
   13447  * greater than or equal to that of the second.
   13448  */
   13449 __isl_give isl_basic_map *isl_basic_map_order_ge(__isl_take isl_basic_map *bmap,
   13450 	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
   13451 {
   13452 	isl_constraint *c;
   13453 	isl_space *space;
   13454 
   13455 	if (type1 == type2 && pos1 == pos2)
   13456 		return bmap;
   13457 	space = isl_basic_map_get_space(bmap);
   13458 	c = constraint_order_ge(space, type1, pos1, type2, pos2);
   13459 	bmap = isl_basic_map_add_constraint(bmap, c);
   13460 
   13461 	return bmap;
   13462 }
   13463 
   13464 /* Add a constraint imposing that the value of the first dimension is
   13465  * greater than or equal to that of the second.
   13466  */
   13467 __isl_give isl_map *isl_map_order_ge(__isl_take isl_map *map,
   13468 	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
   13469 {
   13470 	isl_constraint *c;
   13471 	isl_space *space;
   13472 
   13473 	if (type1 == type2 && pos1 == pos2)
   13474 		return map;
   13475 	space = isl_map_get_space(map);
   13476 	c = constraint_order_ge(space, type1, pos1, type2, pos2);
   13477 	map = isl_map_add_constraint(map, c);
   13478 
   13479 	return map;
   13480 }
   13481 
   13482 /* Add a constraint imposing that the value of the first dimension is
   13483  * less than or equal to that of the second.
   13484  */
   13485 __isl_give isl_map *isl_map_order_le(__isl_take isl_map *map,
   13486 	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
   13487 {
   13488 	return isl_map_order_ge(map, type2, pos2, type1, pos1);
   13489 }
   13490 
   13491 /* Construct a basic map where the value of the first dimension is
   13492  * greater than that of the second.
   13493  */
   13494 static __isl_give isl_basic_map *greator(__isl_take isl_space *space,
   13495 	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
   13496 {
   13497 	isl_basic_map *bmap = NULL;
   13498 	int i;
   13499 	isl_size total;
   13500 
   13501 	if (isl_space_check_range(space, type1, pos1, 1) < 0 ||
   13502 	    isl_space_check_range(space, type2, pos2, 1) < 0)
   13503 		goto error;
   13504 
   13505 	if (type1 == type2 && pos1 == pos2)
   13506 		return isl_basic_map_empty(space);
   13507 
   13508 	bmap = isl_basic_map_alloc_space(space, 0, 0, 1);
   13509 	total = isl_basic_map_dim(bmap, isl_dim_all);
   13510 	i = isl_basic_map_alloc_inequality(bmap);
   13511 	if (total < 0 || i < 0)
   13512 		return isl_basic_map_free(bmap);
   13513 	isl_seq_clr(bmap->ineq[i], 1 + total);
   13514 	pos1 += isl_basic_map_offset(bmap, type1);
   13515 	pos2 += isl_basic_map_offset(bmap, type2);
   13516 	isl_int_set_si(bmap->ineq[i][pos1], 1);
   13517 	isl_int_set_si(bmap->ineq[i][pos2], -1);
   13518 	isl_int_set_si(bmap->ineq[i][0], -1);
   13519 	bmap = isl_basic_map_finalize(bmap);
   13520 
   13521 	return bmap;
   13522 error:
   13523 	isl_space_free(space);
   13524 	isl_basic_map_free(bmap);
   13525 	return NULL;
   13526 }
   13527 
   13528 /* Add a constraint imposing that the value of the first dimension is
   13529  * greater than that of the second.
   13530  */
   13531 __isl_give isl_basic_map *isl_basic_map_order_gt(__isl_take isl_basic_map *bmap,
   13532 	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
   13533 {
   13534 	isl_basic_map *gt;
   13535 
   13536 	gt = greator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2);
   13537 
   13538 	bmap = isl_basic_map_intersect(bmap, gt);
   13539 
   13540 	return bmap;
   13541 }
   13542 
   13543 /* Add a constraint imposing that the value of the first dimension is
   13544  * greater than that of the second.
   13545  */
   13546 __isl_give isl_map *isl_map_order_gt(__isl_take isl_map *map,
   13547 	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
   13548 {
   13549 	isl_basic_map *bmap;
   13550 
   13551 	bmap = greator(isl_map_get_space(map), type1, pos1, type2, pos2);
   13552 
   13553 	map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
   13554 
   13555 	return map;
   13556 }
   13557 
   13558 /* Add a constraint imposing that the value of the first dimension is
   13559  * smaller than that of the second.
   13560  */
   13561 __isl_give isl_map *isl_map_order_lt(__isl_take isl_map *map,
   13562 	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
   13563 {
   13564 	return isl_map_order_gt(map, type2, pos2, type1, pos1);
   13565 }
   13566 
   13567 __isl_give isl_aff *isl_basic_map_get_div(__isl_keep isl_basic_map *bmap,
   13568 	int pos)
   13569 {
   13570 	isl_aff *div;
   13571 	isl_local_space *ls;
   13572 
   13573 	if (!bmap)
   13574 		return NULL;
   13575 
   13576 	if (!isl_basic_map_divs_known(bmap))
   13577 		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
   13578 			"some divs are unknown", return NULL);
   13579 
   13580 	ls = isl_basic_map_get_local_space(bmap);
   13581 	div = isl_local_space_get_div(ls, pos);
   13582 	isl_local_space_free(ls);
   13583 
   13584 	return div;
   13585 }
   13586 
   13587 __isl_give isl_aff *isl_basic_set_get_div(__isl_keep isl_basic_set *bset,
   13588 	int pos)
   13589 {
   13590 	return isl_basic_map_get_div(bset, pos);
   13591 }
   13592 
   13593 /* Plug in "subs" for set dimension "pos" of "set".
   13594  */
   13595 __isl_give isl_set *isl_set_substitute(__isl_take isl_set *set,
   13596 	unsigned pos, __isl_keep isl_aff *subs)
   13597 {
   13598 	isl_multi_aff *ma;
   13599 
   13600 	if (set && isl_set_plain_is_empty(set))
   13601 		return set;
   13602 
   13603 	ma = isl_multi_aff_identity_on_domain_space(isl_set_get_space(set));
   13604 	ma = isl_multi_aff_set_aff(ma, pos, isl_aff_copy(subs));
   13605 	return isl_set_preimage_multi_aff(set, ma);
   13606 }
   13607 
   13608 /* Check if the range of "ma" is compatible with the domain or range
   13609  * (depending on "type") of "bmap".
   13610  */
   13611 static isl_stat check_basic_map_compatible_range_multi_aff(
   13612 	__isl_keep isl_basic_map *bmap, enum isl_dim_type type,
   13613 	__isl_keep isl_multi_aff *ma)
   13614 {
   13615 	isl_bool m;
   13616 	isl_space *ma_space;
   13617 
   13618 	ma_space = isl_multi_aff_get_space(ma);
   13619 
   13620 	m = isl_space_has_equal_params(bmap->dim, ma_space);
   13621 	if (m < 0)
   13622 		goto error;
   13623 	if (!m)
   13624 		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
   13625 			"parameters don't match", goto error);
   13626 	m = isl_space_tuple_is_equal(bmap->dim, type, ma_space, isl_dim_out);
   13627 	if (m < 0)
   13628 		goto error;
   13629 	if (!m)
   13630 		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
   13631 			"spaces don't match", goto error);
   13632 
   13633 	isl_space_free(ma_space);
   13634 	return isl_stat_ok;
   13635 error:
   13636 	isl_space_free(ma_space);
   13637 	return isl_stat_error;
   13638 }
   13639 
   13640 /* Copy the divs from "ma" to "bmap", adding zeros for the "n_before"
   13641  * coefficients before the transformed range of dimensions,
   13642  * the "n_after" coefficients after the transformed range of dimensions
   13643  * and the coefficients of the other divs in "bmap".
   13644  */
   13645 static __isl_give isl_basic_map *set_ma_divs(__isl_take isl_basic_map *bmap,
   13646 	__isl_keep isl_multi_aff *ma, int n_before, int n_after, int n_div)
   13647 {
   13648 	int i;
   13649 	isl_size n_param;
   13650 	isl_size n_set;
   13651 	isl_local_space *ls;
   13652 
   13653 	if (n_div == 0)
   13654 		return bmap;
   13655 
   13656 	ls = isl_aff_get_domain_local_space(ma->u.p[0]);
   13657 	n_param = isl_local_space_dim(ls, isl_dim_param);
   13658 	n_set = isl_local_space_dim(ls, isl_dim_set);
   13659 	if (n_param < 0 || n_set < 0)
   13660 		return isl_basic_map_free(bmap);
   13661 
   13662 	for (i = 0; i < n_div; ++i) {
   13663 		int o_bmap = 0, o_ls = 0;
   13664 
   13665 		isl_seq_cpy(bmap->div[i], ls->div->row[i], 1 + 1 + n_param);
   13666 		o_bmap += 1 + 1 + n_param;
   13667 		o_ls += 1 + 1 + n_param;
   13668 		isl_seq_clr(bmap->div[i] + o_bmap, n_before);
   13669 		o_bmap += n_before;
   13670 		isl_seq_cpy(bmap->div[i] + o_bmap,
   13671 			    ls->div->row[i] + o_ls, n_set);
   13672 		o_bmap += n_set;
   13673 		o_ls += n_set;
   13674 		isl_seq_clr(bmap->div[i] + o_bmap, n_after);
   13675 		o_bmap += n_after;
   13676 		isl_seq_cpy(bmap->div[i] + o_bmap,
   13677 			    ls->div->row[i] + o_ls, n_div);
   13678 		o_bmap += n_div;
   13679 		o_ls += n_div;
   13680 		isl_seq_clr(bmap->div[i] + o_bmap, bmap->n_div - n_div);
   13681 		bmap = isl_basic_map_add_div_constraints(bmap, i);
   13682 		if (!bmap)
   13683 			goto error;
   13684 	}
   13685 
   13686 	isl_local_space_free(ls);
   13687 	return bmap;
   13688 error:
   13689 	isl_local_space_free(ls);
   13690 	return isl_basic_map_free(bmap);
   13691 }
   13692 
   13693 /* How many stride constraints does "ma" enforce?
   13694  * That is, how many of the affine expressions have a denominator
   13695  * different from one?
   13696  */
   13697 static int multi_aff_strides(__isl_keep isl_multi_aff *ma)
   13698 {
   13699 	int i;
   13700 	int strides = 0;
   13701 
   13702 	for (i = 0; i < ma->n; ++i)
   13703 		if (!isl_int_is_one(ma->u.p[i]->v->el[0]))
   13704 			strides++;
   13705 
   13706 	return strides;
   13707 }
   13708 
   13709 /* For each affine expression in ma of the form
   13710  *
   13711  *	x_i = (f_i y + h_i)/m_i
   13712  *
   13713  * with m_i different from one, add a constraint to "bmap"
   13714  * of the form
   13715  *
   13716  *	f_i y + h_i = m_i alpha_i
   13717  *
   13718  * with alpha_i an additional existentially quantified variable.
   13719  *
   13720  * The input variables of "ma" correspond to a subset of the variables
   13721  * of "bmap".  There are "n_before" variables in "bmap" before this
   13722  * subset and "n_after" variables after this subset.
   13723  * The integer divisions of the affine expressions in "ma" are assumed
   13724  * to have been aligned.  There are "n_div_ma" of them and
   13725  * they appear first in "bmap", straight after the "n_after" variables.
   13726  */
   13727 static __isl_give isl_basic_map *add_ma_strides(
   13728 	__isl_take isl_basic_map *bmap, __isl_keep isl_multi_aff *ma,
   13729 	int n_before, int n_after, int n_div_ma)
   13730 {
   13731 	int i, k;
   13732 	int div;
   13733 	isl_size total;
   13734 	isl_size n_param;
   13735 	isl_size n_in;
   13736 
   13737 	total = isl_basic_map_dim(bmap, isl_dim_all);
   13738 	n_param = isl_multi_aff_dim(ma, isl_dim_param);
   13739 	n_in = isl_multi_aff_dim(ma, isl_dim_in);
   13740 	if (total < 0 || n_param < 0 || n_in < 0)
   13741 		return isl_basic_map_free(bmap);
   13742 	for (i = 0; i < ma->n; ++i) {
   13743 		int o_bmap = 0, o_ma = 1;
   13744 
   13745 		if (isl_int_is_one(ma->u.p[i]->v->el[0]))
   13746 			continue;
   13747 		div = isl_basic_map_alloc_div(bmap);
   13748 		k = isl_basic_map_alloc_equality(bmap);
   13749 		if (div < 0 || k < 0)
   13750 			goto error;
   13751 		isl_int_set_si(bmap->div[div][0], 0);
   13752 		isl_seq_cpy(bmap->eq[k] + o_bmap,
   13753 			    ma->u.p[i]->v->el + o_ma, 1 + n_param);
   13754 		o_bmap += 1 + n_param;
   13755 		o_ma += 1 + n_param;
   13756 		isl_seq_clr(bmap->eq[k] + o_bmap, n_before);
   13757 		o_bmap += n_before;
   13758 		isl_seq_cpy(bmap->eq[k] + o_bmap,
   13759 			    ma->u.p[i]->v->el + o_ma, n_in);
   13760 		o_bmap += n_in;
   13761 		o_ma += n_in;
   13762 		isl_seq_clr(bmap->eq[k] + o_bmap, n_after);
   13763 		o_bmap += n_after;
   13764 		isl_seq_cpy(bmap->eq[k] + o_bmap,
   13765 			    ma->u.p[i]->v->el + o_ma, n_div_ma);
   13766 		o_bmap += n_div_ma;
   13767 		o_ma += n_div_ma;
   13768 		isl_seq_clr(bmap->eq[k] + o_bmap, 1 + total - o_bmap);
   13769 		isl_int_neg(bmap->eq[k][1 + total], ma->u.p[i]->v->el[0]);
   13770 		total++;
   13771 	}
   13772 
   13773 	return bmap;
   13774 error:
   13775 	isl_basic_map_free(bmap);
   13776 	return NULL;
   13777 }
   13778 
   13779 /* Replace the domain or range space (depending on "type) of "space" by "set".
   13780  */
   13781 static __isl_give isl_space *isl_space_set(__isl_take isl_space *space,
   13782 	enum isl_dim_type type, __isl_take isl_space *set)
   13783 {
   13784 	if (type == isl_dim_in) {
   13785 		space = isl_space_range(space);
   13786 		space = isl_space_map_from_domain_and_range(set, space);
   13787 	} else {
   13788 		space = isl_space_domain(space);
   13789 		space = isl_space_map_from_domain_and_range(space, set);
   13790 	}
   13791 
   13792 	return space;
   13793 }
   13794 
   13795 /* Compute the preimage of the domain or range (depending on "type")
   13796  * of "bmap" under the function represented by "ma".
   13797  * In other words, plug in "ma" in the domain or range of "bmap".
   13798  * The result is a basic map that lives in the same space as "bmap"
   13799  * except that the domain or range has been replaced by
   13800  * the domain space of "ma".
   13801  *
   13802  * If bmap is represented by
   13803  *
   13804  *	A(p) + S u + B x + T v + C(divs) >= 0,
   13805  *
   13806  * where u and x are input and output dimensions if type == isl_dim_out
   13807  * while x and v are input and output dimensions if type == isl_dim_in,
   13808  * and ma is represented by
   13809  *
   13810  *	x = D(p) + F(y) + G(divs')
   13811  *
   13812  * then the result is
   13813  *
   13814  *	A(p) + B D(p) + S u + B F(y) + T v + B G(divs') + C(divs) >= 0
   13815  *
   13816  * The divs in the input set are similarly adjusted.
   13817  * In particular
   13818  *
   13819  *	floor((a_i(p) + s u + b_i x + t v + c_i(divs))/n_i)
   13820  *
   13821  * becomes
   13822  *
   13823  *	floor((a_i(p) + b_i D(p) + s u + b_i F(y) + t v +
   13824  *		B_i G(divs') + c_i(divs))/n_i)
   13825  *
   13826  * If bmap is not a rational map and if F(y) involves any denominators
   13827  *
   13828  *	x_i = (f_i y + h_i)/m_i
   13829  *
   13830  * then additional constraints are added to ensure that we only
   13831  * map back integer points.  That is we enforce
   13832  *
   13833  *	f_i y + h_i = m_i alpha_i
   13834  *
   13835  * with alpha_i an additional existentially quantified variable.
   13836  *
   13837  * We first copy over the divs from "ma".
   13838  * Then we add the modified constraints and divs from "bmap".
   13839  * Finally, we add the stride constraints, if needed.
   13840  */
   13841 __isl_give isl_basic_map *isl_basic_map_preimage_multi_aff(
   13842 	__isl_take isl_basic_map *bmap, enum isl_dim_type type,
   13843 	__isl_take isl_multi_aff *ma)
   13844 {
   13845 	int i, k;
   13846 	isl_space *space;
   13847 	isl_basic_map *res = NULL;
   13848 	isl_size n_before, n_after, n_div_bmap, n_div_ma;
   13849 	isl_int f, c1, c2, g;
   13850 	isl_bool rational;
   13851 	int strides;
   13852 
   13853 	isl_int_init(f);
   13854 	isl_int_init(c1);
   13855 	isl_int_init(c2);
   13856 	isl_int_init(g);
   13857 
   13858 	ma = isl_multi_aff_align_divs(ma);
   13859 	if (!bmap || !ma)
   13860 		goto error;
   13861 	if (check_basic_map_compatible_range_multi_aff(bmap, type, ma) < 0)
   13862 		goto error;
   13863 
   13864 	if (type == isl_dim_in) {
   13865 		n_before = 0;
   13866 		n_after = isl_basic_map_dim(bmap, isl_dim_out);
   13867 	} else {
   13868 		n_before = isl_basic_map_dim(bmap, isl_dim_in);
   13869 		n_after = 0;
   13870 	}
   13871 	n_div_bmap = isl_basic_map_dim(bmap, isl_dim_div);
   13872 	n_div_ma = ma->n ? isl_aff_dim(ma->u.p[0], isl_dim_div) : 0;
   13873 	if (n_before < 0 || n_after < 0 || n_div_bmap < 0 || n_div_ma < 0)
   13874 		goto error;
   13875 
   13876 	space = isl_multi_aff_get_domain_space(ma);
   13877 	space = isl_space_set(isl_basic_map_get_space(bmap), type, space);
   13878 	rational = isl_basic_map_is_rational(bmap);
   13879 	strides = rational ? 0 : multi_aff_strides(ma);
   13880 	res = isl_basic_map_alloc_space(space, n_div_ma + n_div_bmap + strides,
   13881 			    bmap->n_eq + strides, bmap->n_ineq + 2 * n_div_ma);
   13882 	if (rational)
   13883 		res = isl_basic_map_set_rational(res);
   13884 
   13885 	for (i = 0; i < n_div_ma + n_div_bmap; ++i)
   13886 		if (isl_basic_map_alloc_div(res) < 0)
   13887 			goto error;
   13888 
   13889 	res = set_ma_divs(res, ma, n_before, n_after, n_div_ma);
   13890 	if (!res)
   13891 		goto error;
   13892 
   13893 	for (i = 0; i < bmap->n_eq; ++i) {
   13894 		k = isl_basic_map_alloc_equality(res);
   13895 		if (k < 0)
   13896 			goto error;
   13897 		if (isl_seq_preimage(res->eq[k], bmap->eq[i], ma, n_before,
   13898 				    n_after, n_div_ma, n_div_bmap,
   13899 				    f, c1, c2, g, 0) < 0)
   13900 			goto error;
   13901 	}
   13902 
   13903 	for (i = 0; i < bmap->n_ineq; ++i) {
   13904 		k = isl_basic_map_alloc_inequality(res);
   13905 		if (k < 0)
   13906 			goto error;
   13907 		if (isl_seq_preimage(res->ineq[k], bmap->ineq[i], ma, n_before,
   13908 				    n_after, n_div_ma, n_div_bmap,
   13909 				    f, c1, c2, g, 0) < 0)
   13910 			goto error;
   13911 	}
   13912 
   13913 	for (i = 0; i < bmap->n_div; ++i) {
   13914 		if (isl_int_is_zero(bmap->div[i][0])) {
   13915 			isl_int_set_si(res->div[n_div_ma + i][0], 0);
   13916 			continue;
   13917 		}
   13918 		if (isl_seq_preimage(res->div[n_div_ma + i], bmap->div[i], ma,
   13919 				    n_before, n_after, n_div_ma, n_div_bmap,
   13920 				    f, c1, c2, g, 1) < 0)
   13921 			goto error;
   13922 	}
   13923 
   13924 	if (strides)
   13925 		res = add_ma_strides(res, ma, n_before, n_after, n_div_ma);
   13926 
   13927 	isl_int_clear(f);
   13928 	isl_int_clear(c1);
   13929 	isl_int_clear(c2);
   13930 	isl_int_clear(g);
   13931 	isl_basic_map_free(bmap);
   13932 	isl_multi_aff_free(ma);
   13933 	res = isl_basic_map_simplify(res);
   13934 	return isl_basic_map_finalize(res);
   13935 error:
   13936 	isl_int_clear(f);
   13937 	isl_int_clear(c1);
   13938 	isl_int_clear(c2);
   13939 	isl_int_clear(g);
   13940 	isl_basic_map_free(bmap);
   13941 	isl_multi_aff_free(ma);
   13942 	isl_basic_map_free(res);
   13943 	return NULL;
   13944 }
   13945 
   13946 /* Compute the preimage of "bset" under the function represented by "ma".
   13947  * In other words, plug in "ma" in "bset".  The result is a basic set
   13948  * that lives in the domain space of "ma".
   13949  */
   13950 __isl_give isl_basic_set *isl_basic_set_preimage_multi_aff(
   13951 	__isl_take isl_basic_set *bset, __isl_take isl_multi_aff *ma)
   13952 {
   13953 	return isl_basic_map_preimage_multi_aff(bset, isl_dim_set, ma);
   13954 }
   13955 
   13956 /* Compute the preimage of the domain of "bmap" under the function
   13957  * represented by "ma".
   13958  * In other words, plug in "ma" in the domain of "bmap".
   13959  * The result is a basic map that lives in the same space as "bmap"
   13960  * except that the domain has been replaced by the domain space of "ma".
   13961  */
   13962 __isl_give isl_basic_map *isl_basic_map_preimage_domain_multi_aff(
   13963 	__isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma)
   13964 {
   13965 	return isl_basic_map_preimage_multi_aff(bmap, isl_dim_in, ma);
   13966 }
   13967 
   13968 /* Compute the preimage of the range of "bmap" under the function
   13969  * represented by "ma".
   13970  * In other words, plug in "ma" in the range of "bmap".
   13971  * The result is a basic map that lives in the same space as "bmap"
   13972  * except that the range has been replaced by the domain space of "ma".
   13973  */
   13974 __isl_give isl_basic_map *isl_basic_map_preimage_range_multi_aff(
   13975 	__isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma)
   13976 {
   13977 	return isl_basic_map_preimage_multi_aff(bmap, isl_dim_out, ma);
   13978 }
   13979 
   13980 /* Check if the range of "ma" is compatible with the domain or range
   13981  * (depending on "type") of "map".
   13982  * Return isl_stat_error if anything is wrong.
   13983  */
   13984 static isl_stat check_map_compatible_range_multi_aff(
   13985 	__isl_keep isl_map *map, enum isl_dim_type type,
   13986 	__isl_keep isl_multi_aff *ma)
   13987 {
   13988 	isl_bool m;
   13989 	isl_space *ma_space;
   13990 
   13991 	ma_space = isl_multi_aff_get_space(ma);
   13992 	m = isl_map_space_tuple_is_equal(map, type, ma_space, isl_dim_out);
   13993 	isl_space_free(ma_space);
   13994 	if (m < 0)
   13995 		return isl_stat_error;
   13996 	if (!m)
   13997 		isl_die(isl_map_get_ctx(map), isl_error_invalid,
   13998 			"spaces don't match", return isl_stat_error);
   13999 	return isl_stat_ok;
   14000 }
   14001 
   14002 /* Compute the preimage of the domain or range (depending on "type")
   14003  * of "map" under the function represented by "ma".
   14004  * In other words, plug in "ma" in the domain or range of "map".
   14005  * The result is a map that lives in the same space as "map"
   14006  * except that the domain or range has been replaced by
   14007  * the domain space of "ma".
   14008  *
   14009  * The parameters are assumed to have been aligned.
   14010  */
   14011 static __isl_give isl_map *map_preimage_multi_aff(__isl_take isl_map *map,
   14012 	enum isl_dim_type type, __isl_take isl_multi_aff *ma)
   14013 {
   14014 	int i;
   14015 	isl_space *space;
   14016 
   14017 	map = isl_map_cow(map);
   14018 	ma = isl_multi_aff_align_divs(ma);
   14019 	if (!map || !ma)
   14020 		goto error;
   14021 	if (check_map_compatible_range_multi_aff(map, type, ma) < 0)
   14022 		goto error;
   14023 
   14024 	for (i = 0; i < map->n; ++i) {
   14025 		map->p[i] = isl_basic_map_preimage_multi_aff(map->p[i], type,
   14026 							isl_multi_aff_copy(ma));
   14027 		if (!map->p[i])
   14028 			goto error;
   14029 	}
   14030 
   14031 	space = isl_multi_aff_get_domain_space(ma);
   14032 	space = isl_space_set(isl_map_get_space(map), type, space);
   14033 
   14034 	isl_space_free(isl_map_take_space(map));
   14035 	map = isl_map_restore_space(map, space);
   14036 	if (!map)
   14037 		goto error;
   14038 
   14039 	isl_multi_aff_free(ma);
   14040 	if (map->n > 1)
   14041 		ISL_F_CLR(map, ISL_MAP_DISJOINT);
   14042 	ISL_F_CLR(map, ISL_SET_NORMALIZED);
   14043 	return map;
   14044 error:
   14045 	isl_multi_aff_free(ma);
   14046 	isl_map_free(map);
   14047 	return NULL;
   14048 }
   14049 
   14050 /* Compute the preimage of the domain or range (depending on "type")
   14051  * of "map" under the function represented by "ma".
   14052  * In other words, plug in "ma" in the domain or range of "map".
   14053  * The result is a map that lives in the same space as "map"
   14054  * except that the domain or range has been replaced by
   14055  * the domain space of "ma".
   14056  */
   14057 __isl_give isl_map *isl_map_preimage_multi_aff(__isl_take isl_map *map,
   14058 	enum isl_dim_type type, __isl_take isl_multi_aff *ma)
   14059 {
   14060 	isl_bool aligned;
   14061 
   14062 	if (!map || !ma)
   14063 		goto error;
   14064 
   14065 	aligned = isl_map_space_has_equal_params(map, ma->space);
   14066 	if (aligned < 0)
   14067 		goto error;
   14068 	if (aligned)
   14069 		return map_preimage_multi_aff(map, type, ma);
   14070 
   14071 	if (isl_map_check_named_params(map) < 0)
   14072 		goto error;
   14073 	if (!isl_space_has_named_params(ma->space))
   14074 		isl_die(map->ctx, isl_error_invalid,
   14075 			"unaligned unnamed parameters", goto error);
   14076 	map = isl_map_align_params(map, isl_multi_aff_get_space(ma));
   14077 	ma = isl_multi_aff_align_params(ma, isl_map_get_space(map));
   14078 
   14079 	return map_preimage_multi_aff(map, type, ma);
   14080 error:
   14081 	isl_multi_aff_free(ma);
   14082 	return isl_map_free(map);
   14083 }
   14084 
   14085 /* Compute the preimage of "set" under the function represented by "ma".
   14086  * In other words, plug in "ma" in "set".  The result is a set
   14087  * that lives in the domain space of "ma".
   14088  */
   14089 __isl_give isl_set *isl_set_preimage_multi_aff(__isl_take isl_set *set,
   14090 	__isl_take isl_multi_aff *ma)
   14091 {
   14092 	return isl_map_preimage_multi_aff(set, isl_dim_set, ma);
   14093 }
   14094 
   14095 /* Compute the preimage of the domain of "map" under the function
   14096  * represented by "ma".
   14097  * In other words, plug in "ma" in the domain of "map".
   14098  * The result is a map that lives in the same space as "map"
   14099  * except that the domain has been replaced by the domain space of "ma".
   14100  */
   14101 __isl_give isl_map *isl_map_preimage_domain_multi_aff(__isl_take isl_map *map,
   14102 	__isl_take isl_multi_aff *ma)
   14103 {
   14104 	return isl_map_preimage_multi_aff(map, isl_dim_in, ma);
   14105 }
   14106 
   14107 /* Compute the preimage of the range of "map" under the function
   14108  * represented by "ma".
   14109  * In other words, plug in "ma" in the range of "map".
   14110  * The result is a map that lives in the same space as "map"
   14111  * except that the range has been replaced by the domain space of "ma".
   14112  */
   14113 __isl_give isl_map *isl_map_preimage_range_multi_aff(__isl_take isl_map *map,
   14114 	__isl_take isl_multi_aff *ma)
   14115 {
   14116 	return isl_map_preimage_multi_aff(map, isl_dim_out, ma);
   14117 }
   14118 
   14119 /* Compute the preimage of "map" under the function represented by "pma".
   14120  * In other words, plug in "pma" in the domain or range of "map".
   14121  * The result is a map that lives in the same space as "map",
   14122  * except that the space of type "type" has been replaced by
   14123  * the domain space of "pma".
   14124  *
   14125  * The parameters of "map" and "pma" are assumed to have been aligned.
   14126  */
   14127 static __isl_give isl_map *isl_map_preimage_pw_multi_aff_aligned(
   14128 	__isl_take isl_map *map, enum isl_dim_type type,
   14129 	__isl_take isl_pw_multi_aff *pma)
   14130 {
   14131 	int i;
   14132 	isl_map *res;
   14133 
   14134 	if (!pma)
   14135 		goto error;
   14136 
   14137 	if (pma->n == 0) {
   14138 		isl_space *space;
   14139 
   14140 		space = isl_pw_multi_aff_get_domain_space(pma);
   14141 		isl_pw_multi_aff_free(pma);
   14142 		space = isl_space_set(isl_map_get_space(map), type, space);
   14143 		isl_map_free(map);
   14144 		return isl_map_empty(space);
   14145 	}
   14146 
   14147 	res = isl_map_preimage_multi_aff(isl_map_copy(map), type,
   14148 					isl_multi_aff_copy(pma->p[0].maff));
   14149 	if (type == isl_dim_in)
   14150 		res = isl_map_intersect_domain(res,
   14151 						isl_map_copy(pma->p[0].set));
   14152 	else
   14153 		res = isl_map_intersect_range(res,
   14154 						isl_map_copy(pma->p[0].set));
   14155 
   14156 	for (i = 1; i < pma->n; ++i) {
   14157 		isl_map *res_i;
   14158 
   14159 		res_i = isl_map_preimage_multi_aff(isl_map_copy(map), type,
   14160 					isl_multi_aff_copy(pma->p[i].maff));
   14161 		if (type == isl_dim_in)
   14162 			res_i = isl_map_intersect_domain(res_i,
   14163 						isl_map_copy(pma->p[i].set));
   14164 		else
   14165 			res_i = isl_map_intersect_range(res_i,
   14166 						isl_map_copy(pma->p[i].set));
   14167 		res = isl_map_union(res, res_i);
   14168 	}
   14169 
   14170 	isl_pw_multi_aff_free(pma);
   14171 	isl_map_free(map);
   14172 	return res;
   14173 error:
   14174 	isl_pw_multi_aff_free(pma);
   14175 	isl_map_free(map);
   14176 	return NULL;
   14177 }
   14178 
   14179 /* Compute the preimage of "map" under the function represented by "pma".
   14180  * In other words, plug in "pma" in the domain or range of "map".
   14181  * The result is a map that lives in the same space as "map",
   14182  * except that the space of type "type" has been replaced by
   14183  * the domain space of "pma".
   14184  */
   14185 __isl_give isl_map *isl_map_preimage_pw_multi_aff(__isl_take isl_map *map,
   14186 	enum isl_dim_type type, __isl_take isl_pw_multi_aff *pma)
   14187 {
   14188 	isl_bool aligned;
   14189 
   14190 	if (!map || !pma)
   14191 		goto error;
   14192 
   14193 	aligned = isl_map_space_has_equal_params(map, pma->dim);
   14194 	if (aligned < 0)
   14195 		goto error;
   14196 	if (aligned)
   14197 		return isl_map_preimage_pw_multi_aff_aligned(map, type, pma);
   14198 
   14199 	if (isl_map_check_named_params(map) < 0)
   14200 		goto error;
   14201 	if (isl_pw_multi_aff_check_named_params(pma) < 0)
   14202 		goto error;
   14203 	map = isl_map_align_params(map, isl_pw_multi_aff_get_space(pma));
   14204 	pma = isl_pw_multi_aff_align_params(pma, isl_map_get_space(map));
   14205 
   14206 	return isl_map_preimage_pw_multi_aff_aligned(map, type, pma);
   14207 error:
   14208 	isl_pw_multi_aff_free(pma);
   14209 	return isl_map_free(map);
   14210 }
   14211 
   14212 /* Compute the preimage of "set" under the function represented by "pma".
   14213  * In other words, plug in "pma" in "set".  The result is a set
   14214  * that lives in the domain space of "pma".
   14215  */
   14216 __isl_give isl_set *isl_set_preimage_pw_multi_aff(__isl_take isl_set *set,
   14217 	__isl_take isl_pw_multi_aff *pma)
   14218 {
   14219 	return isl_map_preimage_pw_multi_aff(set, isl_dim_set, pma);
   14220 }
   14221 
   14222 /* Compute the preimage of the domain of "map" under the function
   14223  * represented by "pma".
   14224  * In other words, plug in "pma" in the domain of "map".
   14225  * The result is a map that lives in the same space as "map",
   14226  * except that domain space has been replaced by the domain space of "pma".
   14227  */
   14228 __isl_give isl_map *isl_map_preimage_domain_pw_multi_aff(
   14229 	__isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma)
   14230 {
   14231 	return isl_map_preimage_pw_multi_aff(map, isl_dim_in, pma);
   14232 }
   14233 
   14234 /* Compute the preimage of the range of "map" under the function
   14235  * represented by "pma".
   14236  * In other words, plug in "pma" in the range of "map".
   14237  * The result is a map that lives in the same space as "map",
   14238  * except that range space has been replaced by the domain space of "pma".
   14239  */
   14240 __isl_give isl_map *isl_map_preimage_range_pw_multi_aff(
   14241 	__isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma)
   14242 {
   14243 	return isl_map_preimage_pw_multi_aff(map, isl_dim_out, pma);
   14244 }
   14245 
   14246 /* Compute the preimage of "map" under the function represented by "mpa".
   14247  * In other words, plug in "mpa" in the domain or range of "map".
   14248  * The result is a map that lives in the same space as "map",
   14249  * except that the space of type "type" has been replaced by
   14250  * the domain space of "mpa".
   14251  *
   14252  * If the map does not involve any constraints that refer to the
   14253  * dimensions of the substituted space, then the only possible
   14254  * effect of "mpa" on the map is to map the space to a different space.
   14255  * We create a separate isl_multi_aff to effectuate this change
   14256  * in order to avoid spurious splitting of the map along the pieces
   14257  * of "mpa".
   14258  * If "mpa" has a non-trivial explicit domain, however,
   14259  * then the full substitution should be performed.
   14260  */
   14261 __isl_give isl_map *isl_map_preimage_multi_pw_aff(__isl_take isl_map *map,
   14262 	enum isl_dim_type type, __isl_take isl_multi_pw_aff *mpa)
   14263 {
   14264 	isl_size n;
   14265 	isl_bool full;
   14266 	isl_pw_multi_aff *pma;
   14267 
   14268 	n = isl_map_dim(map, type);
   14269 	if (n < 0 || !mpa)
   14270 		goto error;
   14271 
   14272 	full = isl_map_involves_dims(map, type, 0, n);
   14273 	if (full >= 0 && !full)
   14274 		full = isl_multi_pw_aff_has_non_trivial_domain(mpa);
   14275 	if (full < 0)
   14276 		goto error;
   14277 	if (!full) {
   14278 		isl_space *space;
   14279 		isl_multi_aff *ma;
   14280 
   14281 		space = isl_multi_pw_aff_get_space(mpa);
   14282 		isl_multi_pw_aff_free(mpa);
   14283 		ma = isl_multi_aff_zero(space);
   14284 		return isl_map_preimage_multi_aff(map, type, ma);
   14285 	}
   14286 
   14287 	pma = isl_pw_multi_aff_from_multi_pw_aff(mpa);
   14288 	return isl_map_preimage_pw_multi_aff(map, type, pma);
   14289 error:
   14290 	isl_map_free(map);
   14291 	isl_multi_pw_aff_free(mpa);
   14292 	return NULL;
   14293 }
   14294 
   14295 /* Compute the preimage of "map" under the function represented by "mpa".
   14296  * In other words, plug in "mpa" in the domain "map".
   14297  * The result is a map that lives in the same space as "map",
   14298  * except that domain space has been replaced by the domain space of "mpa".
   14299  */
   14300 __isl_give isl_map *isl_map_preimage_domain_multi_pw_aff(
   14301 	__isl_take isl_map *map, __isl_take isl_multi_pw_aff *mpa)
   14302 {
   14303 	return isl_map_preimage_multi_pw_aff(map, isl_dim_in, mpa);
   14304 }
   14305 
   14306 /* Compute the preimage of "set" by the function represented by "mpa".
   14307  * In other words, plug in "mpa" in "set".
   14308  */
   14309 __isl_give isl_set *isl_set_preimage_multi_pw_aff(__isl_take isl_set *set,
   14310 	__isl_take isl_multi_pw_aff *mpa)
   14311 {
   14312 	return isl_map_preimage_multi_pw_aff(set, isl_dim_set, mpa);
   14313 }
   14314 
   14315 /* Given that inequality "ineq" of "bmap" expresses an upper bound
   14316  * on the output dimension "pos" in terms of the parameters,
   14317  * the input dimensions and possibly some integer divisions,
   14318  * but not any other output dimensions, extract this upper bound
   14319  * as a function of all dimensions (with zero coefficients
   14320  * for the output dimensions).
   14321  *
   14322  * That is, the inequality is of the form
   14323  *
   14324  *	e(...) + c - m x >= 0
   14325  *
   14326  * where e does not depend on any other output dimensions.
   14327  * Return (e(...) + c) / m, with the denominator m in the first position.
   14328  */
   14329 __isl_give isl_vec *isl_basic_map_inequality_extract_output_upper_bound(
   14330 	__isl_keep isl_basic_map *bmap, int ineq, int pos)
   14331 {
   14332 	isl_ctx *ctx;
   14333 	isl_vec *v;
   14334 	isl_size v_out, total;
   14335 
   14336 	v_out = isl_basic_map_var_offset(bmap, isl_dim_out);
   14337 	total = isl_basic_map_dim(bmap, isl_dim_all);
   14338 	if (v_out < 0 || total < 0)
   14339 		return NULL;
   14340 	ctx = isl_basic_map_get_ctx(bmap);
   14341 	v = isl_vec_alloc(ctx, 1 + 1 + total);
   14342 	if (!v)
   14343 		return NULL;
   14344 	isl_int_neg(v->el[0], bmap->ineq[ineq][1 + v_out + pos]);
   14345 	isl_seq_cpy(v->el + 1, bmap->ineq[ineq], 1 + total);
   14346 	isl_int_set_si(v->el[1 + 1 + v_out + pos], 0);
   14347 
   14348 	return v;
   14349 }
   14350 
   14351 /* Is constraint "c" of "bmap" of the form
   14352  *
   14353  *	e(...) + c1 - m x >= 0
   14354  *
   14355  * or
   14356  *
   14357  *	-e(...) + c2 + m x >= 0
   14358  *
   14359  * where m > 1 and e does not involve any other output variables?
   14360  *
   14361  * "v_out" is the offset to the output variables.
   14362  * "d" is the position of x among the output variables.
   14363  * "v_div" is the offset to the local variables.
   14364  * "total" is the total number of variables.
   14365  *
   14366  * Since the purpose of this function is to use the constraint
   14367  * to express the output variable as an integer division,
   14368  * do not allow the constraint to involve any local variables
   14369  * that do not have an explicit representation.
   14370  */
   14371 static isl_bool is_potential_div_constraint(__isl_keep isl_basic_map *bmap,
   14372 	isl_int *c, int v_out, int d, int v_div, int total)
   14373 {
   14374 	int i = 0;
   14375 
   14376 	if (isl_int_is_zero(c[1 + v_out + d]))
   14377 		return isl_bool_false;
   14378 	if (isl_int_is_one(c[1 + v_out + d]))
   14379 		return isl_bool_false;
   14380 	if (isl_int_is_negone(c[1 + v_out + d]))
   14381 		return isl_bool_false;
   14382 	if (isl_seq_first_non_zero(c + 1 + v_out, d) != -1)
   14383 		return isl_bool_false;
   14384 	if (isl_seq_first_non_zero(c + 1 + v_out + d + 1,
   14385 				    v_div - (v_out + d + 1)) != -1)
   14386 		return isl_bool_false;
   14387 	for (i = 0; v_div + i < total; ++i) {
   14388 		isl_bool known, involves;
   14389 
   14390 		if (isl_int_is_zero(c[1 + v_div + i]))
   14391 			continue;
   14392 		known = isl_basic_map_div_is_known(bmap, i);
   14393 		if (known < 0 || !known)
   14394 			return known;
   14395 		involves = div_involves_vars(bmap, i, v_out, v_div - v_out);
   14396 		if (involves < 0 || involves)
   14397 			return isl_bool_not(involves);
   14398 	}
   14399 	return isl_bool_true;
   14400 }
   14401 
   14402 /* Look for a pair of constraints
   14403  *
   14404  *	e(...) + c1 - m x >= 0		i.e.,		m x <= e(...) + c1
   14405  *
   14406  * and
   14407  *
   14408  *	-e(...) + c2 + m x >= 0		i.e.,		m x >= e(...) - c2
   14409  *
   14410  * that express that the output dimension x at position "pos"
   14411  * is some integer division of an expression in terms of the parameters,
   14412  * input dimensions and integer divisions.
   14413  * If such a pair can be found, then return the index
   14414  * of the upper bound constraint, m x <= e(...) + c1.
   14415  * Otherwise, return an index beyond the number of constraints.
   14416  *
   14417  * In order for the constraints above to express an integer division,
   14418  * m needs to be greater than 1 and such that
   14419  *
   14420  *	c1 + c2 < m			i.e.,		-c2 >= c1 - (m - 1)
   14421  *
   14422  * In particular, this ensures that
   14423  *
   14424  *	x = floor((e(...) + c1) / m)
   14425  */
   14426 isl_size isl_basic_map_find_output_upper_div_constraint(
   14427 	__isl_keep isl_basic_map *bmap, int pos)
   14428 {
   14429 	int i, j;
   14430 	isl_size n_ineq;
   14431 	isl_size v_out, v_div;
   14432 	isl_size total;
   14433 	isl_int sum;
   14434 
   14435 	total = isl_basic_map_dim(bmap, isl_dim_all);
   14436 	v_out = isl_basic_map_var_offset(bmap, isl_dim_out);
   14437 	v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
   14438 	n_ineq = isl_basic_map_n_inequality(bmap);
   14439 	if (total < 0 || v_out < 0 || v_div < 0 || n_ineq < 0)
   14440 		return isl_size_error;
   14441 
   14442 	isl_int_init(sum);
   14443 	for (i = 0; i < n_ineq; ++i) {
   14444 		isl_bool potential;
   14445 
   14446 		potential = is_potential_div_constraint(bmap, bmap->ineq[i],
   14447 						v_out, pos, v_div, total);
   14448 		if (potential < 0)
   14449 			goto error;
   14450 		if (!potential)
   14451 			continue;
   14452 		for (j = i + 1; j < n_ineq; ++j) {
   14453 			if (!isl_seq_is_neg(bmap->ineq[i] + 1,
   14454 					bmap->ineq[j] + 1, total))
   14455 				continue;
   14456 			isl_int_add(sum, bmap->ineq[i][0], bmap->ineq[j][0]);
   14457 			if (isl_int_abs_lt(sum, bmap->ineq[i][1 + v_out + pos]))
   14458 				break;
   14459 		}
   14460 		if (j < n_ineq)
   14461 			break;
   14462 	}
   14463 	isl_int_clear(sum);
   14464 
   14465 	if (i >= n_ineq)
   14466 		return n_ineq;
   14467 	if (isl_int_is_pos(bmap->ineq[j][1 + v_out + pos]))
   14468 		return i;
   14469 	else
   14470 		return j;
   14471 error:
   14472 	isl_int_clear(sum);
   14473 	return isl_size_error;
   14474 }
   14475 
   14476 /* Return a copy of the equality constraints of "bset" as a matrix.
   14477  */
   14478 __isl_give isl_mat *isl_basic_set_extract_equalities(
   14479 	__isl_keep isl_basic_set *bset)
   14480 {
   14481 	isl_ctx *ctx;
   14482 	isl_size total;
   14483 
   14484 	total = isl_basic_set_dim(bset, isl_dim_all);
   14485 	if (total < 0)
   14486 		return NULL;
   14487 
   14488 	ctx = isl_basic_set_get_ctx(bset);
   14489 	return isl_mat_sub_alloc6(ctx, bset->eq, 0, bset->n_eq, 0, 1 + total);
   14490 }
   14491 
   14492 /* Are the "n" "coefficients" starting at "first" of the integer division
   14493  * expressions at position "pos1" in "bmap1" and "pos2" in "bmap2" equal
   14494  * to each other?
   14495  * The "coefficient" at position 0 is the denominator.
   14496  * The "coefficient" at position 1 is the constant term.
   14497  */
   14498 isl_bool isl_basic_map_equal_div_expr_part(__isl_keep isl_basic_map *bmap1,
   14499 	int pos1, __isl_keep isl_basic_map *bmap2, int pos2,
   14500 	unsigned first, unsigned n)
   14501 {
   14502 	if (isl_basic_map_check_range(bmap1, isl_dim_div, pos1, 1) < 0)
   14503 		return isl_bool_error;
   14504 	if (isl_basic_map_check_range(bmap2, isl_dim_div, pos2, 1) < 0)
   14505 		return isl_bool_error;
   14506 	return isl_seq_eq(bmap1->div[pos1] + first,
   14507 			  bmap2->div[pos2] + first, n);
   14508 }
   14509 
   14510 /* Are the integer division expressions at position "pos1" in "bmap1" and
   14511  * "pos2" in "bmap2" equal to each other, except that the constant terms
   14512  * are different?
   14513  */
   14514 isl_bool isl_basic_map_equal_div_expr_except_constant(
   14515 	__isl_keep isl_basic_map *bmap1, int pos1,
   14516 	__isl_keep isl_basic_map *bmap2, int pos2)
   14517 {
   14518 	isl_bool equal;
   14519 	isl_size total, total2;
   14520 
   14521 	total = isl_basic_map_dim(bmap1, isl_dim_all);
   14522 	total2 = isl_basic_map_dim(bmap2, isl_dim_all);
   14523 	if (total < 0 || total2 < 0)
   14524 		return isl_bool_error;
   14525 	if (total != total2)
   14526 		isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,
   14527 			"incomparable div expressions", return isl_bool_error);
   14528 	equal = isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
   14529 						0, 1);
   14530 	if (equal < 0 || !equal)
   14531 		return equal;
   14532 	equal = isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
   14533 						1, 1);
   14534 	if (equal < 0 || equal)
   14535 		return isl_bool_not(equal);
   14536 	return isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
   14537 						2, total);
   14538 }
   14539 
   14540 /* Replace the numerator of the constant term of the integer division
   14541  * expression at position "div" in "bmap" by "value".
   14542  * The caller guarantees that this does not change the meaning
   14543  * of the input.
   14544  */
   14545 __isl_give isl_basic_map *isl_basic_map_set_div_expr_constant_num_si_inplace(
   14546 	__isl_take isl_basic_map *bmap, int div, int value)
   14547 {
   14548 	if (isl_basic_map_check_range(bmap, isl_dim_div, div, 1) < 0)
   14549 		return isl_basic_map_free(bmap);
   14550 
   14551 	isl_int_set_si(bmap->div[div][1], value);
   14552 
   14553 	return bmap;
   14554 }
   14555 
   14556 /* Is the point "inner" internal to inequality constraint "ineq"
   14557  * of "bset"?
   14558  * The point is considered to be internal to the inequality constraint,
   14559  * if it strictly lies on the positive side of the inequality constraint,
   14560  * or if it lies on the constraint and the constraint is lexico-positive.
   14561  */
   14562 static isl_bool is_internal(__isl_keep isl_vec *inner,
   14563 	__isl_keep isl_basic_set *bset, int ineq)
   14564 {
   14565 	isl_ctx *ctx;
   14566 	int pos;
   14567 	isl_size total;
   14568 
   14569 	if (!inner || !bset)
   14570 		return isl_bool_error;
   14571 
   14572 	ctx = isl_basic_set_get_ctx(bset);
   14573 	isl_seq_inner_product(inner->el, bset->ineq[ineq], inner->size,
   14574 				&ctx->normalize_gcd);
   14575 	if (!isl_int_is_zero(ctx->normalize_gcd))
   14576 		return isl_int_is_nonneg(ctx->normalize_gcd);
   14577 
   14578 	total = isl_basic_set_dim(bset, isl_dim_all);
   14579 	if (total < 0)
   14580 		return isl_bool_error;
   14581 	pos = isl_seq_first_non_zero(bset->ineq[ineq] + 1, total);
   14582 	return isl_int_is_pos(bset->ineq[ineq][1 + pos]);
   14583 }
   14584 
   14585 /* Tighten the inequality constraints of "bset" that are outward with respect
   14586  * to the point "vec".
   14587  * That is, tighten the constraints that are not satisfied by "vec".
   14588  *
   14589  * "vec" is a point internal to some superset S of "bset" that is used
   14590  * to make the subsets of S disjoint, by tightening one half of the constraints
   14591  * that separate two subsets.  In particular, the constraints of S
   14592  * are all satisfied by "vec" and should not be tightened.
   14593  * Of the internal constraints, those that have "vec" on the outside
   14594  * are tightened.  The shared facet is included in the adjacent subset
   14595  * with the opposite constraint.
   14596  * For constraints that saturate "vec", this criterion cannot be used
   14597  * to determine which of the two sides should be tightened.
   14598  * Instead, the sign of the first non-zero coefficient is used
   14599  * to make this choice.  Note that this second criterion is never used
   14600  * on the constraints of S since "vec" is interior to "S".
   14601  */
   14602 __isl_give isl_basic_set *isl_basic_set_tighten_outward(
   14603 	__isl_take isl_basic_set *bset, __isl_keep isl_vec *vec)
   14604 {
   14605 	int j;
   14606 
   14607 	bset = isl_basic_set_cow(bset);
   14608 	if (!bset)
   14609 		return NULL;
   14610 	for (j = 0; j < bset->n_ineq; ++j) {
   14611 		isl_bool internal;
   14612 
   14613 		internal = is_internal(vec, bset, j);
   14614 		if (internal < 0)
   14615 			return isl_basic_set_free(bset);
   14616 		if (internal)
   14617 			continue;
   14618 		isl_int_sub_ui(bset->ineq[j][0], bset->ineq[j][0], 1);
   14619 	}
   14620 
   14621 	return bset;
   14622 }
   14623 
   14624 /* Replace the variables x of type "type" starting at "first" in "bmap"
   14625  * by x' with x = M x' with M the matrix trans.
   14626  * That is, replace the corresponding coefficients c by c M.
   14627  *
   14628  * The transformation matrix should be a square matrix.
   14629  */
   14630 __isl_give isl_basic_map *isl_basic_map_transform_dims(
   14631 	__isl_take isl_basic_map *bmap, enum isl_dim_type type, unsigned first,
   14632 	__isl_take isl_mat *trans)
   14633 {
   14634 	unsigned pos;
   14635 
   14636 	bmap = isl_basic_map_cow(bmap);
   14637 	if (!bmap || !trans)
   14638 		goto error;
   14639 
   14640 	if (trans->n_row != trans->n_col)
   14641 		isl_die(trans->ctx, isl_error_invalid,
   14642 			"expecting square transformation matrix", goto error);
   14643 	if (isl_basic_map_check_range(bmap, type, first, trans->n_row) < 0)
   14644 		goto error;
   14645 
   14646 	pos = isl_basic_map_offset(bmap, type) + first;
   14647 
   14648 	if (isl_mat_sub_transform(bmap->eq, bmap->n_eq, pos,
   14649 			isl_mat_copy(trans)) < 0)
   14650 		goto error;
   14651 	if (isl_mat_sub_transform(bmap->ineq, bmap->n_ineq, pos,
   14652 		      isl_mat_copy(trans)) < 0)
   14653 		goto error;
   14654 	if (isl_mat_sub_transform(bmap->div, bmap->n_div, 1 + pos,
   14655 		      isl_mat_copy(trans)) < 0)
   14656 		goto error;
   14657 
   14658 	ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
   14659 	ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
   14660 
   14661 	isl_mat_free(trans);
   14662 	return bmap;
   14663 error:
   14664 	isl_mat_free(trans);
   14665 	isl_basic_map_free(bmap);
   14666 	return NULL;
   14667 }
   14668 
   14669 /* Replace the variables x of type "type" starting at "first" in "bset"
   14670  * by x' with x = M x' with M the matrix trans.
   14671  * That is, replace the corresponding coefficients c by c M.
   14672  *
   14673  * The transformation matrix should be a square matrix.
   14674  */
   14675 __isl_give isl_basic_set *isl_basic_set_transform_dims(
   14676 	__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned first,
   14677 	__isl_take isl_mat *trans)
   14678 {
   14679 	return isl_basic_map_transform_dims(bset, type, first, trans);
   14680 }
   14681