Home | History | Annotate | Line # | Download | only in dist
      1 /*
      2  * Copyright 2011      INRIA Saclay
      3  * Copyright 2011      Sven Verdoolaege
      4  * Copyright 2012-2014 Ecole Normale Superieure
      5  * Copyright 2014      INRIA Rocquencourt
      6  * Copyright 2016      Sven Verdoolaege
      7  * Copyright 2018,2020 Cerebras Systems
      8  * Copyright 2021      Sven Verdoolaege
      9  * Copyright 2022      Cerebras Systems
     10  *
     11  * Use of this software is governed by the MIT license
     12  *
     13  * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
     14  * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
     15  * 91893 Orsay, France
     16  * and Ecole Normale Superieure, 45 rue dUlm, 75230 Paris, France
     17  * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
     18  * B.P. 105 - 78153 Le Chesnay, France
     19  * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA
     20  * and Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA
     21  */
     22 
     23 #include <isl_ctx_private.h>
     24 #include <isl_map_private.h>
     25 #include <isl_union_map_private.h>
     26 #include <isl_aff_private.h>
     27 #include <isl_space_private.h>
     28 #include <isl_local_space_private.h>
     29 #include <isl_vec_private.h>
     30 #include <isl_mat_private.h>
     31 #include <isl_id_private.h>
     32 #include <isl/constraint.h>
     33 #include <isl_seq.h>
     34 #include <isl/set.h>
     35 #include <isl_val_private.h>
     36 #include <isl_point_private.h>
     37 #include <isl_config.h>
     38 
     39 #undef EL_BASE
     40 #define EL_BASE aff
     41 
     42 #include <isl_list_templ.c>
     43 #include <isl_list_read_templ.c>
     44 
     45 #undef EL_BASE
     46 #define EL_BASE pw_aff
     47 
     48 #include <isl_list_templ.c>
     49 #include <isl_list_read_templ.c>
     50 
     51 #undef EL_BASE
     52 #define EL_BASE pw_multi_aff
     53 
     54 #include <isl_list_templ.c>
     55 #include <isl_list_read_templ.c>
     56 
     57 #undef EL_BASE
     58 #define EL_BASE union_pw_aff
     59 
     60 #include <isl_list_templ.c>
     61 #include <isl_list_read_templ.c>
     62 
     63 #undef EL_BASE
     64 #define EL_BASE union_pw_multi_aff
     65 
     66 #include <isl_list_templ.c>
     67 
     68 /* Construct an isl_aff from the given domain local space "ls" and
     69  * coefficients "v", where the local space is known to be valid
     70  * for an affine expression.
     71  */
     72 static __isl_give isl_aff *isl_aff_alloc_vec_validated(
     73 	__isl_take isl_local_space *ls, __isl_take isl_vec *v)
     74 {
     75 	isl_aff *aff;
     76 
     77 	if (!ls || !v)
     78 		goto error;
     79 
     80 	aff = isl_calloc_type(v->ctx, struct isl_aff);
     81 	if (!aff)
     82 		goto error;
     83 
     84 	aff->ref = 1;
     85 	aff->ls = ls;
     86 	aff->v = v;
     87 
     88 	return aff;
     89 error:
     90 	isl_local_space_free(ls);
     91 	isl_vec_free(v);
     92 	return NULL;
     93 }
     94 
     95 /* Construct an isl_aff from the given domain local space "ls" and
     96  * coefficients "v".
     97  *
     98  * First check that "ls" is a valid domain local space
     99  * for an affine expression.
    100  */
    101 __isl_give isl_aff *isl_aff_alloc_vec(__isl_take isl_local_space *ls,
    102 	__isl_take isl_vec *v)
    103 {
    104 	isl_ctx *ctx;
    105 
    106 	if (!ls)
    107 		return NULL;
    108 
    109 	ctx = isl_local_space_get_ctx(ls);
    110 	if (!isl_local_space_divs_known(ls))
    111 		isl_die(ctx, isl_error_invalid, "local space has unknown divs",
    112 			goto error);
    113 	if (!isl_local_space_is_set(ls))
    114 		isl_die(ctx, isl_error_invalid,
    115 			"domain of affine expression should be a set",
    116 			goto error);
    117 	return isl_aff_alloc_vec_validated(ls, v);
    118 error:
    119 	isl_local_space_free(ls);
    120 	isl_vec_free(v);
    121 	return NULL;
    122 }
    123 
    124 __isl_give isl_aff *isl_aff_alloc(__isl_take isl_local_space *ls)
    125 {
    126 	isl_ctx *ctx;
    127 	isl_vec *v;
    128 	isl_size total;
    129 
    130 	if (!ls)
    131 		return NULL;
    132 
    133 	ctx = isl_local_space_get_ctx(ls);
    134 
    135 	total = isl_local_space_dim(ls, isl_dim_all);
    136 	if (total < 0)
    137 		goto error;
    138 	v = isl_vec_alloc(ctx, 1 + 1 + total);
    139 	return isl_aff_alloc_vec(ls, v);
    140 error:
    141 	isl_local_space_free(ls);
    142 	return NULL;
    143 }
    144 
    145 __isl_give isl_aff *isl_aff_copy(__isl_keep isl_aff *aff)
    146 {
    147 	if (!aff)
    148 		return NULL;
    149 
    150 	aff->ref++;
    151 	return aff;
    152 }
    153 
    154 __isl_give isl_aff *isl_aff_dup(__isl_keep isl_aff *aff)
    155 {
    156 	if (!aff)
    157 		return NULL;
    158 
    159 	return isl_aff_alloc_vec_validated(isl_local_space_copy(aff->ls),
    160 					    isl_vec_copy(aff->v));
    161 }
    162 
    163 __isl_give isl_aff *isl_aff_cow(__isl_take isl_aff *aff)
    164 {
    165 	if (!aff)
    166 		return NULL;
    167 
    168 	if (aff->ref == 1)
    169 		return aff;
    170 	aff->ref--;
    171 	return isl_aff_dup(aff);
    172 }
    173 
    174 /* Return a copy of the rational affine expression of "aff".
    175  */
    176 static __isl_give isl_vec *isl_aff_get_rat_aff(__isl_keep isl_aff *aff)
    177 {
    178 	if (!aff)
    179 		return NULL;
    180 	return isl_vec_copy(aff->v);
    181 }
    182 
    183 /* Return the rational affine expression of "aff".
    184  * This may be either a copy or the expression itself
    185  * if there is only one reference to "aff".
    186  * This allows the expression to be modified inplace
    187  * if both the "aff" and its expression have only a single reference.
    188  * The caller is not allowed to modify "aff" between this call and
    189  * a subsequent call to isl_aff_restore_rat_aff.
    190  * The only exception is that isl_aff_free can be called instead.
    191  */
    192 static __isl_give isl_vec *isl_aff_take_rat_aff(__isl_keep isl_aff *aff)
    193 {
    194 	isl_vec *v;
    195 
    196 	if (!aff)
    197 		return NULL;
    198 	if (aff->ref != 1)
    199 		return isl_aff_get_rat_aff(aff);
    200 	v = aff->v;
    201 	aff->v = NULL;
    202 	return v;
    203 }
    204 
    205 /* Set the rational affine expression of "aff" to "v",
    206  * where the rational affine expression of "aff" may be missing
    207  * due to a preceding call to isl_aff_take_rat_aff.
    208  * However, in this case, "aff" only has a single reference and
    209  * then the call to isl_aff_cow has no effect.
    210  */
    211 static __isl_give isl_aff *isl_aff_restore_rat_aff(__isl_keep isl_aff *aff,
    212 	__isl_take isl_vec *v)
    213 {
    214 	if (!aff || !v)
    215 		goto error;
    216 
    217 	if (aff->v == v) {
    218 		isl_vec_free(v);
    219 		return aff;
    220 	}
    221 
    222 	aff = isl_aff_cow(aff);
    223 	if (!aff)
    224 		goto error;
    225 	isl_vec_free(aff->v);
    226 	aff->v = v;
    227 
    228 	return aff;
    229 error:
    230 	isl_aff_free(aff);
    231 	isl_vec_free(v);
    232 	return NULL;
    233 }
    234 
    235 __isl_give isl_aff *isl_aff_zero_on_domain(__isl_take isl_local_space *ls)
    236 {
    237 	isl_aff *aff;
    238 
    239 	aff = isl_aff_alloc(ls);
    240 	if (!aff)
    241 		return NULL;
    242 
    243 	isl_int_set_si(aff->v->el[0], 1);
    244 	isl_seq_clr(aff->v->el + 1, aff->v->size - 1);
    245 
    246 	return aff;
    247 }
    248 
    249 /* Return an affine expression that is equal to zero on domain space "space".
    250  */
    251 __isl_give isl_aff *isl_aff_zero_on_domain_space(__isl_take isl_space *space)
    252 {
    253 	return isl_aff_zero_on_domain(isl_local_space_from_space(space));
    254 }
    255 
    256 /* This function performs the same operation as isl_aff_zero_on_domain_space,
    257  * but is considered as a function on an isl_space when exported.
    258  */
    259 __isl_give isl_aff *isl_space_zero_aff_on_domain(__isl_take isl_space *space)
    260 {
    261 	return isl_aff_zero_on_domain_space(space);
    262 }
    263 
    264 /* Return a piecewise affine expression defined on the specified domain
    265  * that is equal to zero.
    266  */
    267 __isl_give isl_pw_aff *isl_pw_aff_zero_on_domain(__isl_take isl_local_space *ls)
    268 {
    269 	return isl_pw_aff_from_aff(isl_aff_zero_on_domain(ls));
    270 }
    271 
    272 /* Change "aff" into a NaN.
    273  *
    274  * Note that this function gets called from isl_aff_nan_on_domain,
    275  * so "aff" may not have been initialized yet.
    276  */
    277 static __isl_give isl_aff *isl_aff_set_nan(__isl_take isl_aff *aff)
    278 {
    279 	isl_vec *v;
    280 
    281 	v = isl_aff_take_rat_aff(aff);
    282 	v = isl_vec_clr(v);
    283 	aff = isl_aff_restore_rat_aff(aff, v);
    284 
    285 	return aff;
    286 }
    287 
    288 /* Return an affine expression defined on the specified domain
    289  * that represents NaN.
    290  */
    291 __isl_give isl_aff *isl_aff_nan_on_domain(__isl_take isl_local_space *ls)
    292 {
    293 	isl_aff *aff;
    294 
    295 	aff = isl_aff_alloc(ls);
    296 	return isl_aff_set_nan(aff);
    297 }
    298 
    299 /* Return an affine expression defined on the specified domain space
    300  * that represents NaN.
    301  */
    302 __isl_give isl_aff *isl_aff_nan_on_domain_space(__isl_take isl_space *space)
    303 {
    304 	return isl_aff_nan_on_domain(isl_local_space_from_space(space));
    305 }
    306 
    307 /* Return a piecewise affine expression defined on the specified domain space
    308  * that represents NaN.
    309  */
    310 __isl_give isl_pw_aff *isl_pw_aff_nan_on_domain_space(
    311 	__isl_take isl_space *space)
    312 {
    313 	return isl_pw_aff_from_aff(isl_aff_nan_on_domain_space(space));
    314 }
    315 
    316 /* Return a piecewise affine expression defined on the specified domain
    317  * that represents NaN.
    318  */
    319 __isl_give isl_pw_aff *isl_pw_aff_nan_on_domain(__isl_take isl_local_space *ls)
    320 {
    321 	return isl_pw_aff_from_aff(isl_aff_nan_on_domain(ls));
    322 }
    323 
    324 /* Return an affine expression that is equal to "val" on
    325  * domain local space "ls".
    326  *
    327  * Note that the encoding for the special value NaN
    328  * is the same in isl_val and isl_aff, so this does not need
    329  * to be treated in any special way.
    330  */
    331 __isl_give isl_aff *isl_aff_val_on_domain(__isl_take isl_local_space *ls,
    332 	__isl_take isl_val *val)
    333 {
    334 	isl_aff *aff;
    335 
    336 	if (!ls || !val)
    337 		goto error;
    338 	if (!isl_val_is_rat(val) && !isl_val_is_nan(val))
    339 		isl_die(isl_val_get_ctx(val), isl_error_invalid,
    340 			"expecting rational value or NaN", goto error);
    341 
    342 	aff = isl_aff_alloc(isl_local_space_copy(ls));
    343 	if (!aff)
    344 		goto error;
    345 
    346 	isl_seq_clr(aff->v->el + 2, aff->v->size - 2);
    347 	isl_int_set(aff->v->el[1], val->n);
    348 	isl_int_set(aff->v->el[0], val->d);
    349 
    350 	isl_local_space_free(ls);
    351 	isl_val_free(val);
    352 	return aff;
    353 error:
    354 	isl_local_space_free(ls);
    355 	isl_val_free(val);
    356 	return NULL;
    357 }
    358 
    359 /* Return an affine expression that is equal to "val" on domain space "space".
    360  */
    361 __isl_give isl_aff *isl_aff_val_on_domain_space(__isl_take isl_space *space,
    362 	__isl_take isl_val *val)
    363 {
    364 	return isl_aff_val_on_domain(isl_local_space_from_space(space), val);
    365 }
    366 
    367 /* Return an affine expression that is equal to the specified dimension
    368  * in "ls".
    369  */
    370 __isl_give isl_aff *isl_aff_var_on_domain(__isl_take isl_local_space *ls,
    371 	enum isl_dim_type type, unsigned pos)
    372 {
    373 	isl_space *space;
    374 	isl_aff *aff;
    375 
    376 	if (!ls)
    377 		return NULL;
    378 
    379 	space = isl_local_space_get_space(ls);
    380 	if (!space)
    381 		goto error;
    382 	if (isl_space_is_map(space))
    383 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
    384 			"expecting (parameter) set space", goto error);
    385 	if (isl_local_space_check_range(ls, type, pos, 1) < 0)
    386 		goto error;
    387 
    388 	isl_space_free(space);
    389 	aff = isl_aff_alloc(ls);
    390 	if (!aff)
    391 		return NULL;
    392 
    393 	pos += isl_local_space_offset(aff->ls, type);
    394 
    395 	isl_int_set_si(aff->v->el[0], 1);
    396 	isl_seq_clr(aff->v->el + 1, aff->v->size - 1);
    397 	isl_int_set_si(aff->v->el[1 + pos], 1);
    398 
    399 	return aff;
    400 error:
    401 	isl_local_space_free(ls);
    402 	isl_space_free(space);
    403 	return NULL;
    404 }
    405 
    406 /* Return a piecewise affine expression that is equal to
    407  * the specified dimension in "ls".
    408  */
    409 __isl_give isl_pw_aff *isl_pw_aff_var_on_domain(__isl_take isl_local_space *ls,
    410 	enum isl_dim_type type, unsigned pos)
    411 {
    412 	return isl_pw_aff_from_aff(isl_aff_var_on_domain(ls, type, pos));
    413 }
    414 
    415 /* Return an affine expression that is equal to the parameter
    416  * in the domain space "space" with identifier "id".
    417  */
    418 __isl_give isl_aff *isl_aff_param_on_domain_space_id(
    419 	__isl_take isl_space *space, __isl_take isl_id *id)
    420 {
    421 	int pos;
    422 	isl_local_space *ls;
    423 
    424 	if (!space || !id)
    425 		goto error;
    426 	pos = isl_space_find_dim_by_id(space, isl_dim_param, id);
    427 	if (pos < 0)
    428 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
    429 			"parameter not found in space", goto error);
    430 	isl_id_free(id);
    431 	ls = isl_local_space_from_space(space);
    432 	return isl_aff_var_on_domain(ls, isl_dim_param, pos);
    433 error:
    434 	isl_space_free(space);
    435 	isl_id_free(id);
    436 	return NULL;
    437 }
    438 
    439 /* This function performs the same operation as
    440  * isl_aff_param_on_domain_space_id,
    441  * but is considered as a function on an isl_space when exported.
    442  */
    443 __isl_give isl_aff *isl_space_param_aff_on_domain_id(
    444 	__isl_take isl_space *space, __isl_take isl_id *id)
    445 {
    446 	return isl_aff_param_on_domain_space_id(space, id);
    447 }
    448 
    449 __isl_null isl_aff *isl_aff_free(__isl_take isl_aff *aff)
    450 {
    451 	if (!aff)
    452 		return NULL;
    453 
    454 	if (--aff->ref > 0)
    455 		return NULL;
    456 
    457 	isl_local_space_free(aff->ls);
    458 	isl_vec_free(aff->v);
    459 
    460 	free(aff);
    461 
    462 	return NULL;
    463 }
    464 
    465 isl_ctx *isl_aff_get_ctx(__isl_keep isl_aff *aff)
    466 {
    467 	return aff ? isl_local_space_get_ctx(aff->ls) : NULL;
    468 }
    469 
    470 /* Return a hash value that digests "aff".
    471  */
    472 uint32_t isl_aff_get_hash(__isl_keep isl_aff *aff)
    473 {
    474 	uint32_t hash, ls_hash, v_hash;
    475 
    476 	if (!aff)
    477 		return 0;
    478 
    479 	hash = isl_hash_init();
    480 	ls_hash = isl_local_space_get_hash(aff->ls);
    481 	isl_hash_hash(hash, ls_hash);
    482 	v_hash = isl_vec_get_hash(aff->v);
    483 	isl_hash_hash(hash, v_hash);
    484 
    485 	return hash;
    486 }
    487 
    488 /* Return the domain local space of "aff".
    489  */
    490 static __isl_keep isl_local_space *isl_aff_peek_domain_local_space(
    491 	__isl_keep isl_aff *aff)
    492 {
    493 	return aff ? aff->ls : NULL;
    494 }
    495 
    496 /* Return the number of variables of the given type in the domain of "aff".
    497  */
    498 isl_size isl_aff_domain_dim(__isl_keep isl_aff *aff, enum isl_dim_type type)
    499 {
    500 	isl_local_space *ls;
    501 
    502 	ls = isl_aff_peek_domain_local_space(aff);
    503 	return isl_local_space_dim(ls, type);
    504 }
    505 
    506 /* Externally, an isl_aff has a map space, but internally, the
    507  * ls field corresponds to the domain of that space.
    508  */
    509 isl_size isl_aff_dim(__isl_keep isl_aff *aff, enum isl_dim_type type)
    510 {
    511 	if (!aff)
    512 		return isl_size_error;
    513 	if (type == isl_dim_out)
    514 		return 1;
    515 	if (type == isl_dim_in)
    516 		type = isl_dim_set;
    517 	return isl_aff_domain_dim(aff, type);
    518 }
    519 
    520 /* Return the offset of the first coefficient of type "type" in
    521  * the domain of "aff".
    522  */
    523 isl_size isl_aff_domain_offset(__isl_keep isl_aff *aff, enum isl_dim_type type)
    524 {
    525 	isl_local_space *ls;
    526 
    527 	ls = isl_aff_peek_domain_local_space(aff);
    528 	return isl_local_space_offset(ls, type);
    529 }
    530 
    531 /* Return the position of the dimension of the given type and name
    532  * in "aff".
    533  * Return -1 if no such dimension can be found.
    534  */
    535 int isl_aff_find_dim_by_name(__isl_keep isl_aff *aff, enum isl_dim_type type,
    536 	const char *name)
    537 {
    538 	if (!aff)
    539 		return -1;
    540 	if (type == isl_dim_out)
    541 		return -1;
    542 	if (type == isl_dim_in)
    543 		type = isl_dim_set;
    544 	return isl_local_space_find_dim_by_name(aff->ls, type, name);
    545 }
    546 
    547 /* Return the domain space of "aff".
    548  */
    549 static __isl_keep isl_space *isl_aff_peek_domain_space(__isl_keep isl_aff *aff)
    550 {
    551 	return aff ? isl_local_space_peek_space(aff->ls) : NULL;
    552 }
    553 
    554 __isl_give isl_space *isl_aff_get_domain_space(__isl_keep isl_aff *aff)
    555 {
    556 	return isl_space_copy(isl_aff_peek_domain_space(aff));
    557 }
    558 
    559 __isl_give isl_space *isl_aff_get_space(__isl_keep isl_aff *aff)
    560 {
    561 	isl_space *space;
    562 	if (!aff)
    563 		return NULL;
    564 	space = isl_local_space_get_space(aff->ls);
    565 	space = isl_space_from_domain(space);
    566 	space = isl_space_add_dims(space, isl_dim_out, 1);
    567 	return space;
    568 }
    569 
    570 /* Return a copy of the domain space of "aff".
    571  */
    572 __isl_give isl_local_space *isl_aff_get_domain_local_space(
    573 	__isl_keep isl_aff *aff)
    574 {
    575 	return isl_local_space_copy(isl_aff_peek_domain_local_space(aff));
    576 }
    577 
    578 __isl_give isl_local_space *isl_aff_get_local_space(__isl_keep isl_aff *aff)
    579 {
    580 	isl_local_space *ls;
    581 	if (!aff)
    582 		return NULL;
    583 	ls = isl_local_space_copy(aff->ls);
    584 	ls = isl_local_space_from_domain(ls);
    585 	ls = isl_local_space_add_dims(ls, isl_dim_out, 1);
    586 	return ls;
    587 }
    588 
    589 /* Return the local space of the domain of "aff".
    590  * This may be either a copy or the local space itself
    591  * if there is only one reference to "aff".
    592  * This allows the local space to be modified inplace
    593  * if both the expression and its local space have only a single reference.
    594  * The caller is not allowed to modify "aff" between this call and
    595  * a subsequent call to isl_aff_restore_domain_local_space.
    596  * The only exception is that isl_aff_free can be called instead.
    597  */
    598 __isl_give isl_local_space *isl_aff_take_domain_local_space(
    599 	__isl_keep isl_aff *aff)
    600 {
    601 	isl_local_space *ls;
    602 
    603 	if (!aff)
    604 		return NULL;
    605 	if (aff->ref != 1)
    606 		return isl_aff_get_domain_local_space(aff);
    607 	ls = aff->ls;
    608 	aff->ls = NULL;
    609 	return ls;
    610 }
    611 
    612 /* Set the local space of the domain of "aff" to "ls",
    613  * where the local space of "aff" may be missing
    614  * due to a preceding call to isl_aff_take_domain_local_space.
    615  * However, in this case, "aff" only has a single reference and
    616  * then the call to isl_aff_cow has no effect.
    617  */
    618 __isl_give isl_aff *isl_aff_restore_domain_local_space(
    619 	__isl_keep isl_aff *aff, __isl_take isl_local_space *ls)
    620 {
    621 	if (!aff || !ls)
    622 		goto error;
    623 
    624 	if (aff->ls == ls) {
    625 		isl_local_space_free(ls);
    626 		return aff;
    627 	}
    628 
    629 	aff = isl_aff_cow(aff);
    630 	if (!aff)
    631 		goto error;
    632 	isl_local_space_free(aff->ls);
    633 	aff->ls = ls;
    634 
    635 	return aff;
    636 error:
    637 	isl_aff_free(aff);
    638 	isl_local_space_free(ls);
    639 	return NULL;
    640 }
    641 
    642 /* Externally, an isl_aff has a map space, but internally, the
    643  * ls field corresponds to the domain of that space.
    644  */
    645 const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff,
    646 	enum isl_dim_type type, unsigned pos)
    647 {
    648 	if (!aff)
    649 		return NULL;
    650 	if (type == isl_dim_out)
    651 		return NULL;
    652 	if (type == isl_dim_in)
    653 		type = isl_dim_set;
    654 	return isl_local_space_get_dim_name(aff->ls, type, pos);
    655 }
    656 
    657 __isl_give isl_aff *isl_aff_reset_domain_space(__isl_take isl_aff *aff,
    658 	__isl_take isl_space *space)
    659 {
    660 	aff = isl_aff_cow(aff);
    661 	if (!aff || !space)
    662 		goto error;
    663 
    664 	aff->ls = isl_local_space_reset_space(aff->ls, space);
    665 	if (!aff->ls)
    666 		return isl_aff_free(aff);
    667 
    668 	return aff;
    669 error:
    670 	isl_aff_free(aff);
    671 	isl_space_free(space);
    672 	return NULL;
    673 }
    674 
    675 /* Reset the space of "aff".  This function is called from isl_pw_templ.c
    676  * and doesn't know if the space of an element object is represented
    677  * directly or through its domain.  It therefore passes along both.
    678  */
    679 __isl_give isl_aff *isl_aff_reset_space_and_domain(__isl_take isl_aff *aff,
    680 	__isl_take isl_space *space, __isl_take isl_space *domain)
    681 {
    682 	isl_space_free(space);
    683 	return isl_aff_reset_domain_space(aff, domain);
    684 }
    685 
    686 /* Reorder the dimensions of the domain of "aff" according
    687  * to the given reordering.
    688  */
    689 __isl_give isl_aff *isl_aff_realign_domain(__isl_take isl_aff *aff,
    690 	__isl_take isl_reordering *r)
    691 {
    692 	aff = isl_aff_cow(aff);
    693 	if (!aff)
    694 		goto error;
    695 
    696 	r = isl_reordering_extend(r, aff->ls->div->n_row);
    697 	aff->v = isl_vec_reorder(aff->v, 2, isl_reordering_copy(r));
    698 	aff->ls = isl_local_space_realign(aff->ls, r);
    699 
    700 	if (!aff->v || !aff->ls)
    701 		return isl_aff_free(aff);
    702 
    703 	return aff;
    704 error:
    705 	isl_aff_free(aff);
    706 	isl_reordering_free(r);
    707 	return NULL;
    708 }
    709 
    710 __isl_give isl_aff *isl_aff_align_params(__isl_take isl_aff *aff,
    711 	__isl_take isl_space *model)
    712 {
    713 	isl_space *domain_space;
    714 	isl_bool equal_params;
    715 
    716 	domain_space = isl_aff_peek_domain_space(aff);
    717 	equal_params = isl_space_has_equal_params(domain_space, model);
    718 	if (equal_params < 0)
    719 		goto error;
    720 	if (!equal_params) {
    721 		isl_reordering *exp;
    722 
    723 		exp = isl_parameter_alignment_reordering(domain_space, model);
    724 		aff = isl_aff_realign_domain(aff, exp);
    725 	}
    726 
    727 	isl_space_free(model);
    728 	return aff;
    729 error:
    730 	isl_space_free(model);
    731 	isl_aff_free(aff);
    732 	return NULL;
    733 }
    734 
    735 #undef TYPE
    736 #define TYPE isl_aff
    737 #include "isl_unbind_params_templ.c"
    738 
    739 /* Is "aff" obviously equal to zero?
    740  *
    741  * If the denominator is zero, then "aff" is not equal to zero.
    742  */
    743 isl_bool isl_aff_plain_is_zero(__isl_keep isl_aff *aff)
    744 {
    745 	int pos;
    746 
    747 	if (!aff)
    748 		return isl_bool_error;
    749 
    750 	if (isl_int_is_zero(aff->v->el[0]))
    751 		return isl_bool_false;
    752 	pos = isl_seq_first_non_zero(aff->v->el + 1, aff->v->size - 1);
    753 	return isl_bool_ok(pos < 0);
    754 }
    755 
    756 /* Does "aff" represent NaN?
    757  */
    758 isl_bool isl_aff_is_nan(__isl_keep isl_aff *aff)
    759 {
    760 	if (!aff)
    761 		return isl_bool_error;
    762 
    763 	return isl_bool_ok(isl_seq_first_non_zero(aff->v->el, 2) < 0);
    764 }
    765 
    766 /* Are "aff1" and "aff2" obviously equal?
    767  *
    768  * NaN is not equal to anything, not even to another NaN.
    769  */
    770 isl_bool isl_aff_plain_is_equal(__isl_keep isl_aff *aff1,
    771 	__isl_keep isl_aff *aff2)
    772 {
    773 	isl_bool equal;
    774 
    775 	if (!aff1 || !aff2)
    776 		return isl_bool_error;
    777 
    778 	if (isl_aff_is_nan(aff1) || isl_aff_is_nan(aff2))
    779 		return isl_bool_false;
    780 
    781 	equal = isl_local_space_is_equal(aff1->ls, aff2->ls);
    782 	if (equal < 0 || !equal)
    783 		return equal;
    784 
    785 	return isl_vec_is_equal(aff1->v, aff2->v);
    786 }
    787 
    788 /* Return the common denominator of "aff" in "v".
    789  *
    790  * We cannot return anything meaningful in case of a NaN.
    791  */
    792 isl_stat isl_aff_get_denominator(__isl_keep isl_aff *aff, isl_int *v)
    793 {
    794 	if (!aff)
    795 		return isl_stat_error;
    796 	if (isl_aff_is_nan(aff))
    797 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
    798 			"cannot get denominator of NaN", return isl_stat_error);
    799 	isl_int_set(*v, aff->v->el[0]);
    800 	return isl_stat_ok;
    801 }
    802 
    803 /* Return the common denominator of "aff".
    804  */
    805 __isl_give isl_val *isl_aff_get_denominator_val(__isl_keep isl_aff *aff)
    806 {
    807 	isl_ctx *ctx;
    808 
    809 	if (!aff)
    810 		return NULL;
    811 
    812 	ctx = isl_aff_get_ctx(aff);
    813 	if (isl_aff_is_nan(aff))
    814 		return isl_val_nan(ctx);
    815 	return isl_val_int_from_isl_int(ctx, aff->v->el[0]);
    816 }
    817 
    818 /* Return the constant term of "aff".
    819  */
    820 __isl_give isl_val *isl_aff_get_constant_val(__isl_keep isl_aff *aff)
    821 {
    822 	isl_ctx *ctx;
    823 	isl_val *v;
    824 
    825 	if (!aff)
    826 		return NULL;
    827 
    828 	ctx = isl_aff_get_ctx(aff);
    829 	if (isl_aff_is_nan(aff))
    830 		return isl_val_nan(ctx);
    831 	v = isl_val_rat_from_isl_int(ctx, aff->v->el[1], aff->v->el[0]);
    832 	return isl_val_normalize(v);
    833 }
    834 
    835 /* Return the coefficient of the variable of type "type" at position "pos"
    836  * of "aff".
    837  */
    838 __isl_give isl_val *isl_aff_get_coefficient_val(__isl_keep isl_aff *aff,
    839 	enum isl_dim_type type, int pos)
    840 {
    841 	isl_ctx *ctx;
    842 	isl_val *v;
    843 
    844 	if (!aff)
    845 		return NULL;
    846 
    847 	ctx = isl_aff_get_ctx(aff);
    848 	if (type == isl_dim_out)
    849 		isl_die(ctx, isl_error_invalid,
    850 			"output/set dimension does not have a coefficient",
    851 			return NULL);
    852 	if (type == isl_dim_in)
    853 		type = isl_dim_set;
    854 
    855 	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
    856 		return NULL;
    857 
    858 	if (isl_aff_is_nan(aff))
    859 		return isl_val_nan(ctx);
    860 	pos += isl_local_space_offset(aff->ls, type);
    861 	v = isl_val_rat_from_isl_int(ctx, aff->v->el[1 + pos], aff->v->el[0]);
    862 	return isl_val_normalize(v);
    863 }
    864 
    865 /* Return the sign of the coefficient of the variable of type "type"
    866  * at position "pos" of "aff".
    867  */
    868 int isl_aff_coefficient_sgn(__isl_keep isl_aff *aff, enum isl_dim_type type,
    869 	int pos)
    870 {
    871 	isl_ctx *ctx;
    872 
    873 	if (!aff)
    874 		return 0;
    875 
    876 	ctx = isl_aff_get_ctx(aff);
    877 	if (type == isl_dim_out)
    878 		isl_die(ctx, isl_error_invalid,
    879 			"output/set dimension does not have a coefficient",
    880 			return 0);
    881 	if (type == isl_dim_in)
    882 		type = isl_dim_set;
    883 
    884 	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
    885 		return 0;
    886 
    887 	pos += isl_local_space_offset(aff->ls, type);
    888 	return isl_int_sgn(aff->v->el[1 + pos]);
    889 }
    890 
    891 /* Replace the numerator of the constant term of "aff" by "v".
    892  *
    893  * A NaN is unaffected by this operation.
    894  */
    895 __isl_give isl_aff *isl_aff_set_constant(__isl_take isl_aff *aff, isl_int v)
    896 {
    897 	if (!aff)
    898 		return NULL;
    899 	if (isl_aff_is_nan(aff))
    900 		return aff;
    901 	aff = isl_aff_cow(aff);
    902 	if (!aff)
    903 		return NULL;
    904 
    905 	aff->v = isl_vec_cow(aff->v);
    906 	if (!aff->v)
    907 		return isl_aff_free(aff);
    908 
    909 	isl_int_set(aff->v->el[1], v);
    910 
    911 	return aff;
    912 }
    913 
    914 /* Replace the constant term of "aff" by "v".
    915  *
    916  * A NaN is unaffected by this operation.
    917  */
    918 __isl_give isl_aff *isl_aff_set_constant_val(__isl_take isl_aff *aff,
    919 	__isl_take isl_val *v)
    920 {
    921 	if (!aff || !v)
    922 		goto error;
    923 
    924 	if (isl_aff_is_nan(aff)) {
    925 		isl_val_free(v);
    926 		return aff;
    927 	}
    928 
    929 	if (!isl_val_is_rat(v))
    930 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
    931 			"expecting rational value", goto error);
    932 
    933 	if (isl_int_eq(aff->v->el[1], v->n) &&
    934 	    isl_int_eq(aff->v->el[0], v->d)) {
    935 		isl_val_free(v);
    936 		return aff;
    937 	}
    938 
    939 	aff = isl_aff_cow(aff);
    940 	if (!aff)
    941 		goto error;
    942 	aff->v = isl_vec_cow(aff->v);
    943 	if (!aff->v)
    944 		goto error;
    945 
    946 	if (isl_int_eq(aff->v->el[0], v->d)) {
    947 		isl_int_set(aff->v->el[1], v->n);
    948 	} else if (isl_int_is_one(v->d)) {
    949 		isl_int_mul(aff->v->el[1], aff->v->el[0], v->n);
    950 	} else {
    951 		isl_seq_scale(aff->v->el + 1,
    952 				aff->v->el + 1, v->d, aff->v->size - 1);
    953 		isl_int_mul(aff->v->el[1], aff->v->el[0], v->n);
    954 		isl_int_mul(aff->v->el[0], aff->v->el[0], v->d);
    955 		aff->v = isl_vec_normalize(aff->v);
    956 		if (!aff->v)
    957 			goto error;
    958 	}
    959 
    960 	isl_val_free(v);
    961 	return aff;
    962 error:
    963 	isl_aff_free(aff);
    964 	isl_val_free(v);
    965 	return NULL;
    966 }
    967 
    968 /* Add "v" to the constant term of "aff".
    969  *
    970  * A NaN is unaffected by this operation.
    971  */
    972 __isl_give isl_aff *isl_aff_add_constant(__isl_take isl_aff *aff, isl_int v)
    973 {
    974 	if (isl_int_is_zero(v))
    975 		return aff;
    976 
    977 	if (!aff)
    978 		return NULL;
    979 	if (isl_aff_is_nan(aff))
    980 		return aff;
    981 	aff = isl_aff_cow(aff);
    982 	if (!aff)
    983 		return NULL;
    984 
    985 	aff->v = isl_vec_cow(aff->v);
    986 	if (!aff->v)
    987 		return isl_aff_free(aff);
    988 
    989 	isl_int_addmul(aff->v->el[1], aff->v->el[0], v);
    990 
    991 	return aff;
    992 }
    993 
    994 /* Add "v" to the constant term of "aff",
    995  * in case "aff" is a rational expression.
    996  */
    997 static __isl_give isl_aff *isl_aff_add_rat_constant_val(__isl_take isl_aff *aff,
    998 	__isl_take isl_val *v)
    999 {
   1000 	aff = isl_aff_cow(aff);
   1001 	if (!aff)
   1002 		goto error;
   1003 
   1004 	aff->v = isl_vec_cow(aff->v);
   1005 	if (!aff->v)
   1006 		goto error;
   1007 
   1008 	if (isl_int_is_one(v->d)) {
   1009 		isl_int_addmul(aff->v->el[1], aff->v->el[0], v->n);
   1010 	} else if (isl_int_eq(aff->v->el[0], v->d)) {
   1011 		isl_int_add(aff->v->el[1], aff->v->el[1], v->n);
   1012 		aff->v = isl_vec_normalize(aff->v);
   1013 		if (!aff->v)
   1014 			goto error;
   1015 	} else {
   1016 		isl_seq_scale(aff->v->el + 1,
   1017 				aff->v->el + 1, v->d, aff->v->size - 1);
   1018 		isl_int_addmul(aff->v->el[1], aff->v->el[0], v->n);
   1019 		isl_int_mul(aff->v->el[0], aff->v->el[0], v->d);
   1020 		aff->v = isl_vec_normalize(aff->v);
   1021 		if (!aff->v)
   1022 			goto error;
   1023 	}
   1024 
   1025 	isl_val_free(v);
   1026 	return aff;
   1027 error:
   1028 	isl_aff_free(aff);
   1029 	isl_val_free(v);
   1030 	return NULL;
   1031 }
   1032 
   1033 /* Return the first argument and free the second.
   1034  */
   1035 static __isl_give isl_aff *pick_free(__isl_take isl_aff *aff,
   1036 	__isl_take isl_val *v)
   1037 {
   1038 	isl_val_free(v);
   1039 	return aff;
   1040 }
   1041 
   1042 /* Replace the first argument by NaN and free the second argument.
   1043  */
   1044 static __isl_give isl_aff *set_nan_free_val(__isl_take isl_aff *aff,
   1045 	__isl_take isl_val *v)
   1046 {
   1047 	isl_val_free(v);
   1048 	return isl_aff_set_nan(aff);
   1049 }
   1050 
   1051 /* Add "v" to the constant term of "aff".
   1052  *
   1053  * A NaN is unaffected by this operation.
   1054  * Conversely, adding a NaN turns "aff" into a NaN.
   1055  */
   1056 __isl_give isl_aff *isl_aff_add_constant_val(__isl_take isl_aff *aff,
   1057 	__isl_take isl_val *v)
   1058 {
   1059 	isl_bool is_nan, is_zero, is_rat;
   1060 
   1061 	is_nan = isl_aff_is_nan(aff);
   1062 	is_zero = isl_val_is_zero(v);
   1063 	if (is_nan < 0 || is_zero < 0)
   1064 		goto error;
   1065 	if (is_nan || is_zero)
   1066 		return pick_free(aff, v);
   1067 
   1068 	is_nan = isl_val_is_nan(v);
   1069 	is_rat = isl_val_is_rat(v);
   1070 	if (is_nan < 0 || is_rat < 0)
   1071 		goto error;
   1072 	if (is_nan)
   1073 		return set_nan_free_val(aff, v);
   1074 	if (!is_rat)
   1075 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   1076 			"expecting rational value or NaN", goto error);
   1077 
   1078 	return isl_aff_add_rat_constant_val(aff, v);
   1079 error:
   1080 	isl_aff_free(aff);
   1081 	isl_val_free(v);
   1082 	return NULL;
   1083 }
   1084 
   1085 __isl_give isl_aff *isl_aff_add_constant_si(__isl_take isl_aff *aff, int v)
   1086 {
   1087 	isl_int t;
   1088 
   1089 	isl_int_init(t);
   1090 	isl_int_set_si(t, v);
   1091 	aff = isl_aff_add_constant(aff, t);
   1092 	isl_int_clear(t);
   1093 
   1094 	return aff;
   1095 }
   1096 
   1097 /* Add "v" to the numerator of the constant term of "aff".
   1098  *
   1099  * A NaN is unaffected by this operation.
   1100  */
   1101 __isl_give isl_aff *isl_aff_add_constant_num(__isl_take isl_aff *aff, isl_int v)
   1102 {
   1103 	if (isl_int_is_zero(v))
   1104 		return aff;
   1105 
   1106 	if (!aff)
   1107 		return NULL;
   1108 	if (isl_aff_is_nan(aff))
   1109 		return aff;
   1110 	aff = isl_aff_cow(aff);
   1111 	if (!aff)
   1112 		return NULL;
   1113 
   1114 	aff->v = isl_vec_cow(aff->v);
   1115 	if (!aff->v)
   1116 		return isl_aff_free(aff);
   1117 
   1118 	isl_int_add(aff->v->el[1], aff->v->el[1], v);
   1119 
   1120 	return aff;
   1121 }
   1122 
   1123 /* Add "v" to the numerator of the constant term of "aff".
   1124  *
   1125  * A NaN is unaffected by this operation.
   1126  */
   1127 __isl_give isl_aff *isl_aff_add_constant_num_si(__isl_take isl_aff *aff, int v)
   1128 {
   1129 	isl_int t;
   1130 
   1131 	if (v == 0)
   1132 		return aff;
   1133 
   1134 	isl_int_init(t);
   1135 	isl_int_set_si(t, v);
   1136 	aff = isl_aff_add_constant_num(aff, t);
   1137 	isl_int_clear(t);
   1138 
   1139 	return aff;
   1140 }
   1141 
   1142 /* Replace the numerator of the constant term of "aff" by "v".
   1143  *
   1144  * A NaN is unaffected by this operation.
   1145  */
   1146 __isl_give isl_aff *isl_aff_set_constant_si(__isl_take isl_aff *aff, int v)
   1147 {
   1148 	if (!aff)
   1149 		return NULL;
   1150 	if (isl_aff_is_nan(aff))
   1151 		return aff;
   1152 	aff = isl_aff_cow(aff);
   1153 	if (!aff)
   1154 		return NULL;
   1155 
   1156 	aff->v = isl_vec_cow(aff->v);
   1157 	if (!aff->v)
   1158 		return isl_aff_free(aff);
   1159 
   1160 	isl_int_set_si(aff->v->el[1], v);
   1161 
   1162 	return aff;
   1163 }
   1164 
   1165 /* Replace the numerator of the coefficient of the variable of type "type"
   1166  * at position "pos" of "aff" by "v".
   1167  *
   1168  * A NaN is unaffected by this operation.
   1169  */
   1170 __isl_give isl_aff *isl_aff_set_coefficient(__isl_take isl_aff *aff,
   1171 	enum isl_dim_type type, int pos, isl_int v)
   1172 {
   1173 	if (!aff)
   1174 		return NULL;
   1175 
   1176 	if (type == isl_dim_out)
   1177 		isl_die(aff->v->ctx, isl_error_invalid,
   1178 			"output/set dimension does not have a coefficient",
   1179 			return isl_aff_free(aff));
   1180 	if (type == isl_dim_in)
   1181 		type = isl_dim_set;
   1182 
   1183 	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
   1184 		return isl_aff_free(aff);
   1185 
   1186 	if (isl_aff_is_nan(aff))
   1187 		return aff;
   1188 	aff = isl_aff_cow(aff);
   1189 	if (!aff)
   1190 		return NULL;
   1191 
   1192 	aff->v = isl_vec_cow(aff->v);
   1193 	if (!aff->v)
   1194 		return isl_aff_free(aff);
   1195 
   1196 	pos += isl_local_space_offset(aff->ls, type);
   1197 	isl_int_set(aff->v->el[1 + pos], v);
   1198 
   1199 	return aff;
   1200 }
   1201 
   1202 /* Replace the numerator of the coefficient of the variable of type "type"
   1203  * at position "pos" of "aff" by "v".
   1204  *
   1205  * A NaN is unaffected by this operation.
   1206  */
   1207 __isl_give isl_aff *isl_aff_set_coefficient_si(__isl_take isl_aff *aff,
   1208 	enum isl_dim_type type, int pos, int v)
   1209 {
   1210 	if (!aff)
   1211 		return NULL;
   1212 
   1213 	if (type == isl_dim_out)
   1214 		isl_die(aff->v->ctx, isl_error_invalid,
   1215 			"output/set dimension does not have a coefficient",
   1216 			return isl_aff_free(aff));
   1217 	if (type == isl_dim_in)
   1218 		type = isl_dim_set;
   1219 
   1220 	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
   1221 		return isl_aff_free(aff);
   1222 
   1223 	if (isl_aff_is_nan(aff))
   1224 		return aff;
   1225 	pos += isl_local_space_offset(aff->ls, type);
   1226 	if (isl_int_cmp_si(aff->v->el[1 + pos], v) == 0)
   1227 		return aff;
   1228 
   1229 	aff = isl_aff_cow(aff);
   1230 	if (!aff)
   1231 		return NULL;
   1232 
   1233 	aff->v = isl_vec_cow(aff->v);
   1234 	if (!aff->v)
   1235 		return isl_aff_free(aff);
   1236 
   1237 	isl_int_set_si(aff->v->el[1 + pos], v);
   1238 
   1239 	return aff;
   1240 }
   1241 
   1242 /* Replace the coefficient of the variable of type "type" at position "pos"
   1243  * of "aff" by "v".
   1244  *
   1245  * A NaN is unaffected by this operation.
   1246  */
   1247 __isl_give isl_aff *isl_aff_set_coefficient_val(__isl_take isl_aff *aff,
   1248 	enum isl_dim_type type, int pos, __isl_take isl_val *v)
   1249 {
   1250 	if (!aff || !v)
   1251 		goto error;
   1252 
   1253 	if (type == isl_dim_out)
   1254 		isl_die(aff->v->ctx, isl_error_invalid,
   1255 			"output/set dimension does not have a coefficient",
   1256 			goto error);
   1257 	if (type == isl_dim_in)
   1258 		type = isl_dim_set;
   1259 
   1260 	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
   1261 		return isl_aff_free(aff);
   1262 
   1263 	if (isl_aff_is_nan(aff)) {
   1264 		isl_val_free(v);
   1265 		return aff;
   1266 	}
   1267 	if (!isl_val_is_rat(v))
   1268 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   1269 			"expecting rational value", goto error);
   1270 
   1271 	pos += isl_local_space_offset(aff->ls, type);
   1272 	if (isl_int_eq(aff->v->el[1 + pos], v->n) &&
   1273 	    isl_int_eq(aff->v->el[0], v->d)) {
   1274 		isl_val_free(v);
   1275 		return aff;
   1276 	}
   1277 
   1278 	aff = isl_aff_cow(aff);
   1279 	if (!aff)
   1280 		goto error;
   1281 	aff->v = isl_vec_cow(aff->v);
   1282 	if (!aff->v)
   1283 		goto error;
   1284 
   1285 	if (isl_int_eq(aff->v->el[0], v->d)) {
   1286 		isl_int_set(aff->v->el[1 + pos], v->n);
   1287 	} else if (isl_int_is_one(v->d)) {
   1288 		isl_int_mul(aff->v->el[1 + pos], aff->v->el[0], v->n);
   1289 	} else {
   1290 		isl_seq_scale(aff->v->el + 1,
   1291 				aff->v->el + 1, v->d, aff->v->size - 1);
   1292 		isl_int_mul(aff->v->el[1 + pos], aff->v->el[0], v->n);
   1293 		isl_int_mul(aff->v->el[0], aff->v->el[0], v->d);
   1294 		aff->v = isl_vec_normalize(aff->v);
   1295 		if (!aff->v)
   1296 			goto error;
   1297 	}
   1298 
   1299 	isl_val_free(v);
   1300 	return aff;
   1301 error:
   1302 	isl_aff_free(aff);
   1303 	isl_val_free(v);
   1304 	return NULL;
   1305 }
   1306 
   1307 /* Add "v" to the coefficient of the variable of type "type"
   1308  * at position "pos" of "aff".
   1309  *
   1310  * A NaN is unaffected by this operation.
   1311  */
   1312 __isl_give isl_aff *isl_aff_add_coefficient(__isl_take isl_aff *aff,
   1313 	enum isl_dim_type type, int pos, isl_int v)
   1314 {
   1315 	if (!aff)
   1316 		return NULL;
   1317 
   1318 	if (type == isl_dim_out)
   1319 		isl_die(aff->v->ctx, isl_error_invalid,
   1320 			"output/set dimension does not have a coefficient",
   1321 			return isl_aff_free(aff));
   1322 	if (type == isl_dim_in)
   1323 		type = isl_dim_set;
   1324 
   1325 	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
   1326 		return isl_aff_free(aff);
   1327 
   1328 	if (isl_aff_is_nan(aff))
   1329 		return aff;
   1330 	aff = isl_aff_cow(aff);
   1331 	if (!aff)
   1332 		return NULL;
   1333 
   1334 	aff->v = isl_vec_cow(aff->v);
   1335 	if (!aff->v)
   1336 		return isl_aff_free(aff);
   1337 
   1338 	pos += isl_local_space_offset(aff->ls, type);
   1339 	isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v);
   1340 
   1341 	return aff;
   1342 }
   1343 
   1344 /* Add "v" to the coefficient of the variable of type "type"
   1345  * at position "pos" of "aff".
   1346  *
   1347  * A NaN is unaffected by this operation.
   1348  */
   1349 __isl_give isl_aff *isl_aff_add_coefficient_val(__isl_take isl_aff *aff,
   1350 	enum isl_dim_type type, int pos, __isl_take isl_val *v)
   1351 {
   1352 	if (!aff || !v)
   1353 		goto error;
   1354 
   1355 	if (isl_val_is_zero(v)) {
   1356 		isl_val_free(v);
   1357 		return aff;
   1358 	}
   1359 
   1360 	if (type == isl_dim_out)
   1361 		isl_die(aff->v->ctx, isl_error_invalid,
   1362 			"output/set dimension does not have a coefficient",
   1363 			goto error);
   1364 	if (type == isl_dim_in)
   1365 		type = isl_dim_set;
   1366 
   1367 	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
   1368 		goto error;
   1369 
   1370 	if (isl_aff_is_nan(aff)) {
   1371 		isl_val_free(v);
   1372 		return aff;
   1373 	}
   1374 	if (!isl_val_is_rat(v))
   1375 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   1376 			"expecting rational value", goto error);
   1377 
   1378 	aff = isl_aff_cow(aff);
   1379 	if (!aff)
   1380 		goto error;
   1381 
   1382 	aff->v = isl_vec_cow(aff->v);
   1383 	if (!aff->v)
   1384 		goto error;
   1385 
   1386 	pos += isl_local_space_offset(aff->ls, type);
   1387 	if (isl_int_is_one(v->d)) {
   1388 		isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v->n);
   1389 	} else if (isl_int_eq(aff->v->el[0], v->d)) {
   1390 		isl_int_add(aff->v->el[1 + pos], aff->v->el[1 + pos], v->n);
   1391 		aff->v = isl_vec_normalize(aff->v);
   1392 		if (!aff->v)
   1393 			goto error;
   1394 	} else {
   1395 		isl_seq_scale(aff->v->el + 1,
   1396 				aff->v->el + 1, v->d, aff->v->size - 1);
   1397 		isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v->n);
   1398 		isl_int_mul(aff->v->el[0], aff->v->el[0], v->d);
   1399 		aff->v = isl_vec_normalize(aff->v);
   1400 		if (!aff->v)
   1401 			goto error;
   1402 	}
   1403 
   1404 	isl_val_free(v);
   1405 	return aff;
   1406 error:
   1407 	isl_aff_free(aff);
   1408 	isl_val_free(v);
   1409 	return NULL;
   1410 }
   1411 
   1412 __isl_give isl_aff *isl_aff_add_coefficient_si(__isl_take isl_aff *aff,
   1413 	enum isl_dim_type type, int pos, int v)
   1414 {
   1415 	isl_int t;
   1416 
   1417 	isl_int_init(t);
   1418 	isl_int_set_si(t, v);
   1419 	aff = isl_aff_add_coefficient(aff, type, pos, t);
   1420 	isl_int_clear(t);
   1421 
   1422 	return aff;
   1423 }
   1424 
   1425 __isl_give isl_aff *isl_aff_get_div(__isl_keep isl_aff *aff, int pos)
   1426 {
   1427 	if (!aff)
   1428 		return NULL;
   1429 
   1430 	return isl_local_space_get_div(aff->ls, pos);
   1431 }
   1432 
   1433 /* Return the negation of "aff".
   1434  *
   1435  * As a special case, -NaN = NaN.
   1436  */
   1437 __isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff)
   1438 {
   1439 	if (!aff)
   1440 		return NULL;
   1441 	if (isl_aff_is_nan(aff))
   1442 		return aff;
   1443 	aff = isl_aff_cow(aff);
   1444 	if (!aff)
   1445 		return NULL;
   1446 	aff->v = isl_vec_cow(aff->v);
   1447 	if (!aff->v)
   1448 		return isl_aff_free(aff);
   1449 
   1450 	isl_seq_neg(aff->v->el + 1, aff->v->el + 1, aff->v->size - 1);
   1451 
   1452 	return aff;
   1453 }
   1454 
   1455 /* Remove divs from the local space that do not appear in the affine
   1456  * expression.
   1457  * We currently only remove divs at the end.
   1458  * Some intermediate divs may also not appear directly in the affine
   1459  * expression, but we would also need to check that no other divs are
   1460  * defined in terms of them.
   1461  */
   1462 __isl_give isl_aff *isl_aff_remove_unused_divs(__isl_take isl_aff *aff)
   1463 {
   1464 	int pos;
   1465 	isl_size off;
   1466 	isl_size n;
   1467 
   1468 	n = isl_aff_domain_dim(aff, isl_dim_div);
   1469 	off = isl_aff_domain_offset(aff, isl_dim_div);
   1470 	if (n < 0 || off < 0)
   1471 		return isl_aff_free(aff);
   1472 
   1473 	pos = isl_seq_last_non_zero(aff->v->el + 1 + off, n) + 1;
   1474 	if (pos == n)
   1475 		return aff;
   1476 
   1477 	aff = isl_aff_cow(aff);
   1478 	if (!aff)
   1479 		return NULL;
   1480 
   1481 	aff->ls = isl_local_space_drop_dims(aff->ls, isl_dim_div, pos, n - pos);
   1482 	aff->v = isl_vec_drop_els(aff->v, 1 + off + pos, n - pos);
   1483 	if (!aff->ls || !aff->v)
   1484 		return isl_aff_free(aff);
   1485 
   1486 	return aff;
   1487 }
   1488 
   1489 /* Look for any divs in the aff->ls with a denominator equal to one
   1490  * and plug them into the affine expression and any subsequent divs
   1491  * that may reference the div.
   1492  */
   1493 static __isl_give isl_aff *plug_in_integral_divs(__isl_take isl_aff *aff)
   1494 {
   1495 	int i;
   1496 	isl_size n;
   1497 	int len;
   1498 	isl_int v;
   1499 	isl_vec *vec;
   1500 	isl_local_space *ls;
   1501 	isl_size off;
   1502 
   1503 	n = isl_aff_domain_dim(aff, isl_dim_div);
   1504 	off = isl_aff_domain_offset(aff, isl_dim_div);
   1505 	if (n < 0 || off < 0)
   1506 		return isl_aff_free(aff);
   1507 	len = aff->v->size;
   1508 	for (i = 0; i < n; ++i) {
   1509 		if (!isl_int_is_one(aff->ls->div->row[i][0]))
   1510 			continue;
   1511 		ls = isl_local_space_copy(aff->ls);
   1512 		ls = isl_local_space_substitute_seq(ls, isl_dim_div, i,
   1513 				aff->ls->div->row[i], len, i + 1, n - (i + 1));
   1514 		vec = isl_vec_copy(aff->v);
   1515 		vec = isl_vec_cow(vec);
   1516 		if (!ls || !vec)
   1517 			goto error;
   1518 
   1519 		isl_int_init(v);
   1520 
   1521 		isl_seq_substitute(vec->el, off + i, aff->ls->div->row[i],
   1522 					len, len, v);
   1523 
   1524 		isl_int_clear(v);
   1525 
   1526 		isl_vec_free(aff->v);
   1527 		aff->v = vec;
   1528 		isl_local_space_free(aff->ls);
   1529 		aff->ls = ls;
   1530 	}
   1531 
   1532 	return aff;
   1533 error:
   1534 	isl_vec_free(vec);
   1535 	isl_local_space_free(ls);
   1536 	return isl_aff_free(aff);
   1537 }
   1538 
   1539 /* Look for any divs j that appear with a unit coefficient inside
   1540  * the definitions of other divs i and plug them into the definitions
   1541  * of the divs i.
   1542  *
   1543  * In particular, an expression of the form
   1544  *
   1545  *	floor((f(..) + floor(g(..)/n))/m)
   1546  *
   1547  * is simplified to
   1548  *
   1549  *	floor((n * f(..) + g(..))/(n * m))
   1550  *
   1551  * This simplification is correct because we can move the expression
   1552  * f(..) into the inner floor in the original expression to obtain
   1553  *
   1554  *	floor(floor((n * f(..) + g(..))/n)/m)
   1555  *
   1556  * from which we can derive the simplified expression.
   1557  */
   1558 static __isl_give isl_aff *plug_in_unit_divs(__isl_take isl_aff *aff)
   1559 {
   1560 	int i, j;
   1561 	isl_size n;
   1562 	isl_size off;
   1563 
   1564 	n = isl_aff_domain_dim(aff, isl_dim_div);
   1565 	off = isl_aff_domain_offset(aff, isl_dim_div);
   1566 	if (n < 0 || off < 0)
   1567 		return isl_aff_free(aff);
   1568 	for (i = 1; i < n; ++i) {
   1569 		for (j = 0; j < i; ++j) {
   1570 			if (!isl_int_is_one(aff->ls->div->row[i][1 + off + j]))
   1571 				continue;
   1572 			aff->ls = isl_local_space_substitute_seq(aff->ls,
   1573 				isl_dim_div, j, aff->ls->div->row[j],
   1574 				aff->v->size, i, 1);
   1575 			if (!aff->ls)
   1576 				return isl_aff_free(aff);
   1577 		}
   1578 	}
   1579 
   1580 	return aff;
   1581 }
   1582 
   1583 /* Swap divs "a" and "b" in "aff", which is assumed to be non-NULL.
   1584  *
   1585  * Even though this function is only called on isl_affs with a single
   1586  * reference, we are careful to only change aff->v and aff->ls together.
   1587  */
   1588 static __isl_give isl_aff *swap_div(__isl_take isl_aff *aff, int a, int b)
   1589 {
   1590 	isl_size off = isl_aff_domain_offset(aff, isl_dim_div);
   1591 	isl_local_space *ls;
   1592 	isl_vec *v;
   1593 
   1594 	if (off < 0)
   1595 		return isl_aff_free(aff);
   1596 
   1597 	ls = isl_local_space_copy(aff->ls);
   1598 	ls = isl_local_space_swap_div(ls, a, b);
   1599 	v = isl_vec_copy(aff->v);
   1600 	v = isl_vec_cow(v);
   1601 	if (!ls || !v)
   1602 		goto error;
   1603 
   1604 	isl_int_swap(v->el[1 + off + a], v->el[1 + off + b]);
   1605 	isl_vec_free(aff->v);
   1606 	aff->v = v;
   1607 	isl_local_space_free(aff->ls);
   1608 	aff->ls = ls;
   1609 
   1610 	return aff;
   1611 error:
   1612 	isl_vec_free(v);
   1613 	isl_local_space_free(ls);
   1614 	return isl_aff_free(aff);
   1615 }
   1616 
   1617 /* Merge divs "a" and "b" in "aff", which is assumed to be non-NULL.
   1618  *
   1619  * We currently do not actually remove div "b", but simply add its
   1620  * coefficient to that of "a" and then zero it out.
   1621  */
   1622 static __isl_give isl_aff *merge_divs(__isl_take isl_aff *aff, int a, int b)
   1623 {
   1624 	isl_size off = isl_aff_domain_offset(aff, isl_dim_div);
   1625 
   1626 	if (off < 0)
   1627 		return isl_aff_free(aff);
   1628 
   1629 	if (isl_int_is_zero(aff->v->el[1 + off + b]))
   1630 		return aff;
   1631 
   1632 	aff->v = isl_vec_cow(aff->v);
   1633 	if (!aff->v)
   1634 		return isl_aff_free(aff);
   1635 
   1636 	isl_int_add(aff->v->el[1 + off + a],
   1637 		    aff->v->el[1 + off + a], aff->v->el[1 + off + b]);
   1638 	isl_int_set_si(aff->v->el[1 + off + b], 0);
   1639 
   1640 	return aff;
   1641 }
   1642 
   1643 /* Sort the divs in the local space of "aff" according to
   1644  * the comparison function "cmp_row" in isl_local_space.c,
   1645  * combining the coefficients of identical divs.
   1646  *
   1647  * Reordering divs does not change the semantics of "aff",
   1648  * so there is no need to call isl_aff_cow.
   1649  * Moreover, this function is currently only called on isl_affs
   1650  * with a single reference.
   1651  */
   1652 static __isl_give isl_aff *sort_divs(__isl_take isl_aff *aff)
   1653 {
   1654 	isl_size n;
   1655 	int i, j;
   1656 
   1657 	n = isl_aff_dim(aff, isl_dim_div);
   1658 	if (n < 0)
   1659 		return isl_aff_free(aff);
   1660 	for (i = 1; i < n; ++i) {
   1661 		for (j = i - 1; j >= 0; --j) {
   1662 			int cmp = isl_mat_cmp_div(aff->ls->div, j, j + 1);
   1663 			if (cmp < 0)
   1664 				break;
   1665 			if (cmp == 0)
   1666 				aff = merge_divs(aff, j, j + 1);
   1667 			else
   1668 				aff = swap_div(aff, j, j + 1);
   1669 			if (!aff)
   1670 				return NULL;
   1671 		}
   1672 	}
   1673 
   1674 	return aff;
   1675 }
   1676 
   1677 /* Normalize the representation of "aff".
   1678  *
   1679  * This function should only be called on "new" isl_affs, i.e.,
   1680  * with only a single reference.  We therefore do not need to
   1681  * worry about affecting other instances.
   1682  */
   1683 __isl_give isl_aff *isl_aff_normalize(__isl_take isl_aff *aff)
   1684 {
   1685 	if (!aff)
   1686 		return NULL;
   1687 	aff->v = isl_vec_normalize(aff->v);
   1688 	if (!aff->v)
   1689 		return isl_aff_free(aff);
   1690 	aff = plug_in_integral_divs(aff);
   1691 	aff = plug_in_unit_divs(aff);
   1692 	aff = sort_divs(aff);
   1693 	aff = isl_aff_remove_unused_divs(aff);
   1694 	return aff;
   1695 }
   1696 
   1697 /* Given f, return floor(f).
   1698  * If f is an integer expression, then just return f.
   1699  * If f is a constant, then return the constant floor(f).
   1700  * Otherwise, if f = g/m, write g = q m + r,
   1701  * create a new div d = [r/m] and return the expression q + d.
   1702  * The coefficients in r are taken to lie between -m/2 and m/2.
   1703  *
   1704  * reduce_div_coefficients performs the same normalization.
   1705  *
   1706  * As a special case, floor(NaN) = NaN.
   1707  */
   1708 __isl_give isl_aff *isl_aff_floor(__isl_take isl_aff *aff)
   1709 {
   1710 	int i;
   1711 	int size;
   1712 	isl_ctx *ctx;
   1713 	isl_vec *div;
   1714 
   1715 	if (!aff)
   1716 		return NULL;
   1717 
   1718 	if (isl_aff_is_nan(aff))
   1719 		return aff;
   1720 	if (isl_int_is_one(aff->v->el[0]))
   1721 		return aff;
   1722 
   1723 	aff = isl_aff_cow(aff);
   1724 	if (!aff)
   1725 		return NULL;
   1726 
   1727 	aff->v = isl_vec_cow(aff->v);
   1728 	if (!aff->v)
   1729 		return isl_aff_free(aff);
   1730 
   1731 	if (isl_aff_is_cst(aff)) {
   1732 		isl_int_fdiv_q(aff->v->el[1], aff->v->el[1], aff->v->el[0]);
   1733 		isl_int_set_si(aff->v->el[0], 1);
   1734 		return aff;
   1735 	}
   1736 
   1737 	div = isl_vec_copy(aff->v);
   1738 	div = isl_vec_cow(div);
   1739 	if (!div)
   1740 		return isl_aff_free(aff);
   1741 
   1742 	ctx = isl_aff_get_ctx(aff);
   1743 	isl_int_fdiv_q(aff->v->el[0], aff->v->el[0], ctx->two);
   1744 	for (i = 1; i < aff->v->size; ++i) {
   1745 		isl_int_fdiv_r(div->el[i], div->el[i], div->el[0]);
   1746 		isl_int_fdiv_q(aff->v->el[i], aff->v->el[i], div->el[0]);
   1747 		if (isl_int_gt(div->el[i], aff->v->el[0])) {
   1748 			isl_int_sub(div->el[i], div->el[i], div->el[0]);
   1749 			isl_int_add_ui(aff->v->el[i], aff->v->el[i], 1);
   1750 		}
   1751 	}
   1752 
   1753 	aff->ls = isl_local_space_add_div(aff->ls, div);
   1754 	if (!aff->ls)
   1755 		return isl_aff_free(aff);
   1756 
   1757 	size = aff->v->size;
   1758 	aff->v = isl_vec_extend(aff->v, size + 1);
   1759 	if (!aff->v)
   1760 		return isl_aff_free(aff);
   1761 	isl_int_set_si(aff->v->el[0], 1);
   1762 	isl_int_set_si(aff->v->el[size], 1);
   1763 
   1764 	aff = isl_aff_normalize(aff);
   1765 
   1766 	return aff;
   1767 }
   1768 
   1769 /* Compute
   1770  *
   1771  *	aff mod m = aff - m * floor(aff/m)
   1772  *
   1773  * with m an integer value.
   1774  */
   1775 __isl_give isl_aff *isl_aff_mod_val(__isl_take isl_aff *aff,
   1776 	__isl_take isl_val *m)
   1777 {
   1778 	isl_aff *res;
   1779 
   1780 	if (!aff || !m)
   1781 		goto error;
   1782 
   1783 	if (!isl_val_is_int(m))
   1784 		isl_die(isl_val_get_ctx(m), isl_error_invalid,
   1785 			"expecting integer modulo", goto error);
   1786 
   1787 	res = isl_aff_copy(aff);
   1788 	aff = isl_aff_scale_down_val(aff, isl_val_copy(m));
   1789 	aff = isl_aff_floor(aff);
   1790 	aff = isl_aff_scale_val(aff, m);
   1791 	res = isl_aff_sub(res, aff);
   1792 
   1793 	return res;
   1794 error:
   1795 	isl_aff_free(aff);
   1796 	isl_val_free(m);
   1797 	return NULL;
   1798 }
   1799 
   1800 /* Compute
   1801  *
   1802  *	pwaff mod m = pwaff - m * floor(pwaff/m)
   1803  */
   1804 __isl_give isl_pw_aff *isl_pw_aff_mod(__isl_take isl_pw_aff *pwaff, isl_int m)
   1805 {
   1806 	isl_pw_aff *res;
   1807 
   1808 	res = isl_pw_aff_copy(pwaff);
   1809 	pwaff = isl_pw_aff_scale_down(pwaff, m);
   1810 	pwaff = isl_pw_aff_floor(pwaff);
   1811 	pwaff = isl_pw_aff_scale(pwaff, m);
   1812 	res = isl_pw_aff_sub(res, pwaff);
   1813 
   1814 	return res;
   1815 }
   1816 
   1817 /* Compute
   1818  *
   1819  *	pa mod m = pa - m * floor(pa/m)
   1820  *
   1821  * with m an integer value.
   1822  */
   1823 __isl_give isl_pw_aff *isl_pw_aff_mod_val(__isl_take isl_pw_aff *pa,
   1824 	__isl_take isl_val *m)
   1825 {
   1826 	if (!pa || !m)
   1827 		goto error;
   1828 	if (!isl_val_is_int(m))
   1829 		isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
   1830 			"expecting integer modulo", goto error);
   1831 	pa = isl_pw_aff_mod(pa, m->n);
   1832 	isl_val_free(m);
   1833 	return pa;
   1834 error:
   1835 	isl_pw_aff_free(pa);
   1836 	isl_val_free(m);
   1837 	return NULL;
   1838 }
   1839 
   1840 /* Given f, return ceil(f).
   1841  * If f is an integer expression, then just return f.
   1842  * Otherwise, let f be the expression
   1843  *
   1844  *	e/m
   1845  *
   1846  * then return
   1847  *
   1848  *	floor((e + m - 1)/m)
   1849  *
   1850  * As a special case, ceil(NaN) = NaN.
   1851  */
   1852 __isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff)
   1853 {
   1854 	if (!aff)
   1855 		return NULL;
   1856 
   1857 	if (isl_aff_is_nan(aff))
   1858 		return aff;
   1859 	if (isl_int_is_one(aff->v->el[0]))
   1860 		return aff;
   1861 
   1862 	aff = isl_aff_cow(aff);
   1863 	if (!aff)
   1864 		return NULL;
   1865 	aff->v = isl_vec_cow(aff->v);
   1866 	if (!aff->v)
   1867 		return isl_aff_free(aff);
   1868 
   1869 	isl_int_add(aff->v->el[1], aff->v->el[1], aff->v->el[0]);
   1870 	isl_int_sub_ui(aff->v->el[1], aff->v->el[1], 1);
   1871 	aff = isl_aff_floor(aff);
   1872 
   1873 	return aff;
   1874 }
   1875 
   1876 /* Apply the expansion computed by isl_merge_divs.
   1877  * The expansion itself is given by "exp" while the resulting
   1878  * list of divs is given by "div".
   1879  */
   1880 __isl_give isl_aff *isl_aff_expand_divs(__isl_take isl_aff *aff,
   1881 	__isl_take isl_mat *div, int *exp)
   1882 {
   1883 	isl_size old_n_div;
   1884 	isl_size new_n_div;
   1885 	isl_size offset;
   1886 
   1887 	aff = isl_aff_cow(aff);
   1888 
   1889 	offset = isl_aff_domain_offset(aff, isl_dim_div);
   1890 	old_n_div = isl_aff_domain_dim(aff, isl_dim_div);
   1891 	new_n_div = isl_mat_rows(div);
   1892 	if (offset < 0 || old_n_div < 0 || new_n_div < 0)
   1893 		goto error;
   1894 
   1895 	aff->v = isl_vec_expand(aff->v, 1 + offset, old_n_div, exp, new_n_div);
   1896 	aff->ls = isl_local_space_replace_divs(aff->ls, div);
   1897 	if (!aff->v || !aff->ls)
   1898 		return isl_aff_free(aff);
   1899 	return aff;
   1900 error:
   1901 	isl_aff_free(aff);
   1902 	isl_mat_free(div);
   1903 	return NULL;
   1904 }
   1905 
   1906 /* Add two affine expressions that live in the same local space.
   1907  */
   1908 static __isl_give isl_aff *add_expanded(__isl_take isl_aff *aff1,
   1909 	__isl_take isl_aff *aff2)
   1910 {
   1911 	isl_int gcd, f;
   1912 
   1913 	aff1 = isl_aff_cow(aff1);
   1914 	if (!aff1 || !aff2)
   1915 		goto error;
   1916 
   1917 	aff1->v = isl_vec_cow(aff1->v);
   1918 	if (!aff1->v)
   1919 		goto error;
   1920 
   1921 	isl_int_init(gcd);
   1922 	isl_int_init(f);
   1923 	isl_int_gcd(gcd, aff1->v->el[0], aff2->v->el[0]);
   1924 	isl_int_divexact(f, aff2->v->el[0], gcd);
   1925 	isl_seq_scale(aff1->v->el + 1, aff1->v->el + 1, f, aff1->v->size - 1);
   1926 	isl_int_divexact(f, aff1->v->el[0], gcd);
   1927 	isl_seq_addmul(aff1->v->el + 1, f, aff2->v->el + 1, aff1->v->size - 1);
   1928 	isl_int_divexact(f, aff2->v->el[0], gcd);
   1929 	isl_int_mul(aff1->v->el[0], aff1->v->el[0], f);
   1930 	isl_int_clear(f);
   1931 	isl_int_clear(gcd);
   1932 
   1933 	isl_aff_free(aff2);
   1934 	aff1 = isl_aff_normalize(aff1);
   1935 	return aff1;
   1936 error:
   1937 	isl_aff_free(aff1);
   1938 	isl_aff_free(aff2);
   1939 	return NULL;
   1940 }
   1941 
   1942 /* Replace one of the arguments by a NaN and free the other one.
   1943  */
   1944 static __isl_give isl_aff *set_nan_free(__isl_take isl_aff *aff1,
   1945 	__isl_take isl_aff *aff2)
   1946 {
   1947 	isl_aff_free(aff2);
   1948 	return isl_aff_set_nan(aff1);
   1949 }
   1950 
   1951 /* Return the sum of "aff1" and "aff2".
   1952  *
   1953  * If either of the two is NaN, then the result is NaN.
   1954  */
   1955 __isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1,
   1956 	__isl_take isl_aff *aff2)
   1957 {
   1958 	isl_ctx *ctx;
   1959 	int *exp1 = NULL;
   1960 	int *exp2 = NULL;
   1961 	isl_mat *div;
   1962 	isl_size n_div1, n_div2;
   1963 
   1964 	if (!aff1 || !aff2)
   1965 		goto error;
   1966 
   1967 	ctx = isl_aff_get_ctx(aff1);
   1968 	if (!isl_space_is_equal(aff1->ls->dim, aff2->ls->dim))
   1969 		isl_die(ctx, isl_error_invalid,
   1970 			"spaces don't match", goto error);
   1971 
   1972 	if (isl_aff_is_nan(aff1)) {
   1973 		isl_aff_free(aff2);
   1974 		return aff1;
   1975 	}
   1976 	if (isl_aff_is_nan(aff2)) {
   1977 		isl_aff_free(aff1);
   1978 		return aff2;
   1979 	}
   1980 
   1981 	n_div1 = isl_aff_dim(aff1, isl_dim_div);
   1982 	n_div2 = isl_aff_dim(aff2, isl_dim_div);
   1983 	if (n_div1 < 0 || n_div2 < 0)
   1984 		goto error;
   1985 	if (n_div1 == 0 && n_div2 == 0)
   1986 		return add_expanded(aff1, aff2);
   1987 
   1988 	exp1 = isl_alloc_array(ctx, int, n_div1);
   1989 	exp2 = isl_alloc_array(ctx, int, n_div2);
   1990 	if ((n_div1 && !exp1) || (n_div2 && !exp2))
   1991 		goto error;
   1992 
   1993 	div = isl_merge_divs(aff1->ls->div, aff2->ls->div, exp1, exp2);
   1994 	aff1 = isl_aff_expand_divs(aff1, isl_mat_copy(div), exp1);
   1995 	aff2 = isl_aff_expand_divs(aff2, div, exp2);
   1996 	free(exp1);
   1997 	free(exp2);
   1998 
   1999 	return add_expanded(aff1, aff2);
   2000 error:
   2001 	free(exp1);
   2002 	free(exp2);
   2003 	isl_aff_free(aff1);
   2004 	isl_aff_free(aff2);
   2005 	return NULL;
   2006 }
   2007 
   2008 __isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1,
   2009 	__isl_take isl_aff *aff2)
   2010 {
   2011 	return isl_aff_add(aff1, isl_aff_neg(aff2));
   2012 }
   2013 
   2014 /* Return the result of scaling "aff" by a factor of "f".
   2015  *
   2016  * As a special case, f * NaN = NaN.
   2017  */
   2018 __isl_give isl_aff *isl_aff_scale(__isl_take isl_aff *aff, isl_int f)
   2019 {
   2020 	isl_int gcd;
   2021 
   2022 	if (!aff)
   2023 		return NULL;
   2024 	if (isl_aff_is_nan(aff))
   2025 		return aff;
   2026 
   2027 	if (isl_int_is_one(f))
   2028 		return aff;
   2029 
   2030 	aff = isl_aff_cow(aff);
   2031 	if (!aff)
   2032 		return NULL;
   2033 	aff->v = isl_vec_cow(aff->v);
   2034 	if (!aff->v)
   2035 		return isl_aff_free(aff);
   2036 
   2037 	if (isl_int_is_pos(f) && isl_int_is_divisible_by(aff->v->el[0], f)) {
   2038 		isl_int_divexact(aff->v->el[0], aff->v->el[0], f);
   2039 		return aff;
   2040 	}
   2041 
   2042 	isl_int_init(gcd);
   2043 	isl_int_gcd(gcd, aff->v->el[0], f);
   2044 	isl_int_divexact(aff->v->el[0], aff->v->el[0], gcd);
   2045 	isl_int_divexact(gcd, f, gcd);
   2046 	isl_seq_scale(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
   2047 	isl_int_clear(gcd);
   2048 
   2049 	return aff;
   2050 }
   2051 
   2052 /* Multiple "aff" by "v".
   2053  */
   2054 __isl_give isl_aff *isl_aff_scale_val(__isl_take isl_aff *aff,
   2055 	__isl_take isl_val *v)
   2056 {
   2057 	if (!aff || !v)
   2058 		goto error;
   2059 
   2060 	if (isl_val_is_one(v)) {
   2061 		isl_val_free(v);
   2062 		return aff;
   2063 	}
   2064 
   2065 	if (!isl_val_is_rat(v))
   2066 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   2067 			"expecting rational factor", goto error);
   2068 
   2069 	aff = isl_aff_scale(aff, v->n);
   2070 	aff = isl_aff_scale_down(aff, v->d);
   2071 
   2072 	isl_val_free(v);
   2073 	return aff;
   2074 error:
   2075 	isl_aff_free(aff);
   2076 	isl_val_free(v);
   2077 	return NULL;
   2078 }
   2079 
   2080 /* Return the result of scaling "aff" down by a factor of "f".
   2081  *
   2082  * As a special case, NaN/f = NaN.
   2083  */
   2084 __isl_give isl_aff *isl_aff_scale_down(__isl_take isl_aff *aff, isl_int f)
   2085 {
   2086 	isl_int gcd;
   2087 
   2088 	if (!aff)
   2089 		return NULL;
   2090 	if (isl_aff_is_nan(aff))
   2091 		return aff;
   2092 
   2093 	if (isl_int_is_one(f))
   2094 		return aff;
   2095 
   2096 	aff = isl_aff_cow(aff);
   2097 	if (!aff)
   2098 		return NULL;
   2099 
   2100 	if (isl_int_is_zero(f))
   2101 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   2102 			"cannot scale down by zero", return isl_aff_free(aff));
   2103 
   2104 	aff->v = isl_vec_cow(aff->v);
   2105 	if (!aff->v)
   2106 		return isl_aff_free(aff);
   2107 
   2108 	isl_int_init(gcd);
   2109 	isl_seq_gcd(aff->v->el + 1, aff->v->size - 1, &gcd);
   2110 	isl_int_gcd(gcd, gcd, f);
   2111 	isl_seq_scale_down(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
   2112 	isl_int_divexact(gcd, f, gcd);
   2113 	isl_int_mul(aff->v->el[0], aff->v->el[0], gcd);
   2114 	isl_int_clear(gcd);
   2115 
   2116 	return aff;
   2117 }
   2118 
   2119 /* Divide "aff" by "v".
   2120  */
   2121 __isl_give isl_aff *isl_aff_scale_down_val(__isl_take isl_aff *aff,
   2122 	__isl_take isl_val *v)
   2123 {
   2124 	if (!aff || !v)
   2125 		goto error;
   2126 
   2127 	if (isl_val_is_one(v)) {
   2128 		isl_val_free(v);
   2129 		return aff;
   2130 	}
   2131 
   2132 	if (!isl_val_is_rat(v))
   2133 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   2134 			"expecting rational factor", goto error);
   2135 	if (!isl_val_is_pos(v))
   2136 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   2137 			"factor needs to be positive", goto error);
   2138 
   2139 	aff = isl_aff_scale(aff, v->d);
   2140 	aff = isl_aff_scale_down(aff, v->n);
   2141 
   2142 	isl_val_free(v);
   2143 	return aff;
   2144 error:
   2145 	isl_aff_free(aff);
   2146 	isl_val_free(v);
   2147 	return NULL;
   2148 }
   2149 
   2150 __isl_give isl_aff *isl_aff_scale_down_ui(__isl_take isl_aff *aff, unsigned f)
   2151 {
   2152 	isl_int v;
   2153 
   2154 	if (f == 1)
   2155 		return aff;
   2156 
   2157 	isl_int_init(v);
   2158 	isl_int_set_ui(v, f);
   2159 	aff = isl_aff_scale_down(aff, v);
   2160 	isl_int_clear(v);
   2161 
   2162 	return aff;
   2163 }
   2164 
   2165 __isl_give isl_aff *isl_aff_set_dim_name(__isl_take isl_aff *aff,
   2166 	enum isl_dim_type type, unsigned pos, const char *s)
   2167 {
   2168 	aff = isl_aff_cow(aff);
   2169 	if (!aff)
   2170 		return NULL;
   2171 	if (type == isl_dim_out)
   2172 		isl_die(aff->v->ctx, isl_error_invalid,
   2173 			"cannot set name of output/set dimension",
   2174 			return isl_aff_free(aff));
   2175 	if (type == isl_dim_in)
   2176 		type = isl_dim_set;
   2177 	aff->ls = isl_local_space_set_dim_name(aff->ls, type, pos, s);
   2178 	if (!aff->ls)
   2179 		return isl_aff_free(aff);
   2180 
   2181 	return aff;
   2182 }
   2183 
   2184 __isl_give isl_aff *isl_aff_set_dim_id(__isl_take isl_aff *aff,
   2185 	enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
   2186 {
   2187 	aff = isl_aff_cow(aff);
   2188 	if (!aff)
   2189 		goto error;
   2190 	if (type == isl_dim_out)
   2191 		isl_die(aff->v->ctx, isl_error_invalid,
   2192 			"cannot set name of output/set dimension",
   2193 			goto error);
   2194 	if (type == isl_dim_in)
   2195 		type = isl_dim_set;
   2196 	aff->ls = isl_local_space_set_dim_id(aff->ls, type, pos, id);
   2197 	if (!aff->ls)
   2198 		return isl_aff_free(aff);
   2199 
   2200 	return aff;
   2201 error:
   2202 	isl_id_free(id);
   2203 	isl_aff_free(aff);
   2204 	return NULL;
   2205 }
   2206 
   2207 /* Replace the identifier of the input tuple of "aff" by "id".
   2208  * type is currently required to be equal to isl_dim_in
   2209  */
   2210 __isl_give isl_aff *isl_aff_set_tuple_id(__isl_take isl_aff *aff,
   2211 	enum isl_dim_type type, __isl_take isl_id *id)
   2212 {
   2213 	aff = isl_aff_cow(aff);
   2214 	if (!aff)
   2215 		goto error;
   2216 	if (type != isl_dim_in)
   2217 		isl_die(aff->v->ctx, isl_error_invalid,
   2218 			"cannot only set id of input tuple", goto error);
   2219 	aff->ls = isl_local_space_set_tuple_id(aff->ls, isl_dim_set, id);
   2220 	if (!aff->ls)
   2221 		return isl_aff_free(aff);
   2222 
   2223 	return aff;
   2224 error:
   2225 	isl_id_free(id);
   2226 	isl_aff_free(aff);
   2227 	return NULL;
   2228 }
   2229 
   2230 /* Exploit the equalities in "eq" to simplify the affine expression
   2231  * and the expressions of the integer divisions in the local space.
   2232  * The integer divisions in this local space are assumed to appear
   2233  * as regular dimensions in "eq".
   2234  */
   2235 static __isl_give isl_aff *isl_aff_substitute_equalities_lifted(
   2236 	__isl_take isl_aff *aff, __isl_take isl_basic_set *eq)
   2237 {
   2238 	int i, j;
   2239 	unsigned o_div;
   2240 	unsigned n_div;
   2241 
   2242 	if (!eq)
   2243 		goto error;
   2244 	if (eq->n_eq == 0) {
   2245 		isl_basic_set_free(eq);
   2246 		return aff;
   2247 	}
   2248 
   2249 	aff = isl_aff_cow(aff);
   2250 	if (!aff)
   2251 		goto error;
   2252 
   2253 	aff->ls = isl_local_space_substitute_equalities(aff->ls,
   2254 							isl_basic_set_copy(eq));
   2255 	aff->v = isl_vec_cow(aff->v);
   2256 	if (!aff->ls || !aff->v)
   2257 		goto error;
   2258 
   2259 	o_div = isl_basic_set_offset(eq, isl_dim_div);
   2260 	n_div = eq->n_div;
   2261 	for (i = 0; i < eq->n_eq; ++i) {
   2262 		j = isl_seq_last_non_zero(eq->eq[i], o_div + n_div);
   2263 		if (j < 0 || j == 0 || j >= o_div)
   2264 			continue;
   2265 
   2266 		isl_seq_elim(aff->v->el + 1, eq->eq[i], j, o_div,
   2267 				&aff->v->el[0]);
   2268 	}
   2269 
   2270 	isl_basic_set_free(eq);
   2271 	aff = isl_aff_normalize(aff);
   2272 	return aff;
   2273 error:
   2274 	isl_basic_set_free(eq);
   2275 	isl_aff_free(aff);
   2276 	return NULL;
   2277 }
   2278 
   2279 /* Exploit the equalities in "eq" to simplify the affine expression
   2280  * and the expressions of the integer divisions in the local space.
   2281  */
   2282 __isl_give isl_aff *isl_aff_substitute_equalities(__isl_take isl_aff *aff,
   2283 	__isl_take isl_basic_set *eq)
   2284 {
   2285 	isl_size n_div;
   2286 
   2287 	n_div = isl_aff_domain_dim(aff, isl_dim_div);
   2288 	if (n_div < 0)
   2289 		goto error;
   2290 	if (n_div > 0)
   2291 		eq = isl_basic_set_add_dims(eq, isl_dim_set, n_div);
   2292 	return isl_aff_substitute_equalities_lifted(aff, eq);
   2293 error:
   2294 	isl_basic_set_free(eq);
   2295 	isl_aff_free(aff);
   2296 	return NULL;
   2297 }
   2298 
   2299 /* Look for equalities among the variables shared by context and aff
   2300  * and the integer divisions of aff, if any.
   2301  * The equalities are then used to eliminate coefficients and/or integer
   2302  * divisions from aff.
   2303  */
   2304 __isl_give isl_aff *isl_aff_gist(__isl_take isl_aff *aff,
   2305 	__isl_take isl_set *context)
   2306 {
   2307 	isl_local_space *ls;
   2308 	isl_basic_set *hull;
   2309 
   2310 	ls = isl_aff_get_domain_local_space(aff);
   2311 	context = isl_local_space_lift_set(ls, context);
   2312 
   2313 	hull = isl_set_affine_hull(context);
   2314 	return isl_aff_substitute_equalities_lifted(aff, hull);
   2315 }
   2316 
   2317 __isl_give isl_aff *isl_aff_gist_params(__isl_take isl_aff *aff,
   2318 	__isl_take isl_set *context)
   2319 {
   2320 	isl_set *dom_context = isl_set_universe(isl_aff_get_domain_space(aff));
   2321 	dom_context = isl_set_intersect_params(dom_context, context);
   2322 	return isl_aff_gist(aff, dom_context);
   2323 }
   2324 
   2325 /* Return a basic set containing those elements in the space
   2326  * of aff where it is positive.  "rational" should not be set.
   2327  *
   2328  * If "aff" is NaN, then it is not positive.
   2329  */
   2330 static __isl_give isl_basic_set *aff_pos_basic_set(__isl_take isl_aff *aff,
   2331 	int rational, void *user)
   2332 {
   2333 	isl_constraint *ineq;
   2334 	isl_basic_set *bset;
   2335 	isl_val *c;
   2336 
   2337 	if (!aff)
   2338 		return NULL;
   2339 	if (isl_aff_is_nan(aff)) {
   2340 		isl_space *space = isl_aff_get_domain_space(aff);
   2341 		isl_aff_free(aff);
   2342 		return isl_basic_set_empty(space);
   2343 	}
   2344 	if (rational)
   2345 		isl_die(isl_aff_get_ctx(aff), isl_error_unsupported,
   2346 			"rational sets not supported", goto error);
   2347 
   2348 	ineq = isl_inequality_from_aff(aff);
   2349 	c = isl_constraint_get_constant_val(ineq);
   2350 	c = isl_val_sub_ui(c, 1);
   2351 	ineq = isl_constraint_set_constant_val(ineq, c);
   2352 
   2353 	bset = isl_basic_set_from_constraint(ineq);
   2354 	bset = isl_basic_set_simplify(bset);
   2355 	return bset;
   2356 error:
   2357 	isl_aff_free(aff);
   2358 	return NULL;
   2359 }
   2360 
   2361 /* Return a basic set containing those elements in the space
   2362  * of aff where it is non-negative.
   2363  * If "rational" is set, then return a rational basic set.
   2364  *
   2365  * If "aff" is NaN, then it is not non-negative (it's not negative either).
   2366  */
   2367 static __isl_give isl_basic_set *aff_nonneg_basic_set(
   2368 	__isl_take isl_aff *aff, int rational, void *user)
   2369 {
   2370 	isl_constraint *ineq;
   2371 	isl_basic_set *bset;
   2372 
   2373 	if (!aff)
   2374 		return NULL;
   2375 	if (isl_aff_is_nan(aff)) {
   2376 		isl_space *space = isl_aff_get_domain_space(aff);
   2377 		isl_aff_free(aff);
   2378 		return isl_basic_set_empty(space);
   2379 	}
   2380 
   2381 	ineq = isl_inequality_from_aff(aff);
   2382 
   2383 	bset = isl_basic_set_from_constraint(ineq);
   2384 	if (rational)
   2385 		bset = isl_basic_set_set_rational(bset);
   2386 	bset = isl_basic_set_simplify(bset);
   2387 	return bset;
   2388 }
   2389 
   2390 /* Return a basic set containing those elements in the space
   2391  * of aff where it is non-negative.
   2392  */
   2393 __isl_give isl_basic_set *isl_aff_nonneg_basic_set(__isl_take isl_aff *aff)
   2394 {
   2395 	return aff_nonneg_basic_set(aff, 0, NULL);
   2396 }
   2397 
   2398 /* Return a basic set containing those elements in the domain space
   2399  * of "aff" where it is positive.
   2400  */
   2401 __isl_give isl_basic_set *isl_aff_pos_basic_set(__isl_take isl_aff *aff)
   2402 {
   2403 	aff = isl_aff_add_constant_num_si(aff, -1);
   2404 	return isl_aff_nonneg_basic_set(aff);
   2405 }
   2406 
   2407 /* Return a basic set containing those elements in the domain space
   2408  * of aff where it is negative.
   2409  */
   2410 __isl_give isl_basic_set *isl_aff_neg_basic_set(__isl_take isl_aff *aff)
   2411 {
   2412 	aff = isl_aff_neg(aff);
   2413 	return isl_aff_pos_basic_set(aff);
   2414 }
   2415 
   2416 /* Return a basic set containing those elements in the space
   2417  * of aff where it is zero.
   2418  * If "rational" is set, then return a rational basic set.
   2419  *
   2420  * If "aff" is NaN, then it is not zero.
   2421  */
   2422 static __isl_give isl_basic_set *aff_zero_basic_set(__isl_take isl_aff *aff,
   2423 	int rational, void *user)
   2424 {
   2425 	isl_constraint *ineq;
   2426 	isl_basic_set *bset;
   2427 
   2428 	if (!aff)
   2429 		return NULL;
   2430 	if (isl_aff_is_nan(aff)) {
   2431 		isl_space *space = isl_aff_get_domain_space(aff);
   2432 		isl_aff_free(aff);
   2433 		return isl_basic_set_empty(space);
   2434 	}
   2435 
   2436 	ineq = isl_equality_from_aff(aff);
   2437 
   2438 	bset = isl_basic_set_from_constraint(ineq);
   2439 	if (rational)
   2440 		bset = isl_basic_set_set_rational(bset);
   2441 	bset = isl_basic_set_simplify(bset);
   2442 	return bset;
   2443 }
   2444 
   2445 /* Return a basic set containing those elements in the space
   2446  * of aff where it is zero.
   2447  */
   2448 __isl_give isl_basic_set *isl_aff_zero_basic_set(__isl_take isl_aff *aff)
   2449 {
   2450 	return aff_zero_basic_set(aff, 0, NULL);
   2451 }
   2452 
   2453 /* Return a basic set containing those elements in the shared space
   2454  * of aff1 and aff2 where aff1 is greater than or equal to aff2.
   2455  */
   2456 __isl_give isl_basic_set *isl_aff_ge_basic_set(__isl_take isl_aff *aff1,
   2457 	__isl_take isl_aff *aff2)
   2458 {
   2459 	aff1 = isl_aff_sub(aff1, aff2);
   2460 
   2461 	return isl_aff_nonneg_basic_set(aff1);
   2462 }
   2463 
   2464 /* Return a basic set containing those elements in the shared domain space
   2465  * of "aff1" and "aff2" where "aff1" is greater than "aff2".
   2466  */
   2467 __isl_give isl_basic_set *isl_aff_gt_basic_set(__isl_take isl_aff *aff1,
   2468 	__isl_take isl_aff *aff2)
   2469 {
   2470 	aff1 = isl_aff_sub(aff1, aff2);
   2471 
   2472 	return isl_aff_pos_basic_set(aff1);
   2473 }
   2474 
   2475 /* Return a set containing those elements in the shared space
   2476  * of aff1 and aff2 where aff1 is greater than or equal to aff2.
   2477  */
   2478 __isl_give isl_set *isl_aff_ge_set(__isl_take isl_aff *aff1,
   2479 	__isl_take isl_aff *aff2)
   2480 {
   2481 	return isl_set_from_basic_set(isl_aff_ge_basic_set(aff1, aff2));
   2482 }
   2483 
   2484 /* Return a set containing those elements in the shared domain space
   2485  * of aff1 and aff2 where aff1 is greater than aff2.
   2486  *
   2487  * If either of the two inputs is NaN, then the result is empty,
   2488  * as comparisons with NaN always return false.
   2489  */
   2490 __isl_give isl_set *isl_aff_gt_set(__isl_take isl_aff *aff1,
   2491 	__isl_take isl_aff *aff2)
   2492 {
   2493 	return isl_set_from_basic_set(isl_aff_gt_basic_set(aff1, aff2));
   2494 }
   2495 
   2496 /* Return a basic set containing those elements in the shared space
   2497  * of aff1 and aff2 where aff1 is smaller than or equal to aff2.
   2498  */
   2499 __isl_give isl_basic_set *isl_aff_le_basic_set(__isl_take isl_aff *aff1,
   2500 	__isl_take isl_aff *aff2)
   2501 {
   2502 	return isl_aff_ge_basic_set(aff2, aff1);
   2503 }
   2504 
   2505 /* Return a basic set containing those elements in the shared domain space
   2506  * of "aff1" and "aff2" where "aff1" is smaller than "aff2".
   2507  */
   2508 __isl_give isl_basic_set *isl_aff_lt_basic_set(__isl_take isl_aff *aff1,
   2509 	__isl_take isl_aff *aff2)
   2510 {
   2511 	return isl_aff_gt_basic_set(aff2, aff1);
   2512 }
   2513 
   2514 /* Return a set containing those elements in the shared space
   2515  * of aff1 and aff2 where aff1 is smaller than or equal to aff2.
   2516  */
   2517 __isl_give isl_set *isl_aff_le_set(__isl_take isl_aff *aff1,
   2518 	__isl_take isl_aff *aff2)
   2519 {
   2520 	return isl_aff_ge_set(aff2, aff1);
   2521 }
   2522 
   2523 /* Return a set containing those elements in the shared domain space
   2524  * of "aff1" and "aff2" where "aff1" is smaller than "aff2".
   2525  */
   2526 __isl_give isl_set *isl_aff_lt_set(__isl_take isl_aff *aff1,
   2527 	__isl_take isl_aff *aff2)
   2528 {
   2529 	return isl_set_from_basic_set(isl_aff_lt_basic_set(aff1, aff2));
   2530 }
   2531 
   2532 /* Return a basic set containing those elements in the shared space
   2533  * of aff1 and aff2 where aff1 and aff2 are equal.
   2534  */
   2535 __isl_give isl_basic_set *isl_aff_eq_basic_set(__isl_take isl_aff *aff1,
   2536 	__isl_take isl_aff *aff2)
   2537 {
   2538 	aff1 = isl_aff_sub(aff1, aff2);
   2539 
   2540 	return isl_aff_zero_basic_set(aff1);
   2541 }
   2542 
   2543 /* Return a set containing those elements in the shared space
   2544  * of aff1 and aff2 where aff1 and aff2 are equal.
   2545  */
   2546 __isl_give isl_set *isl_aff_eq_set(__isl_take isl_aff *aff1,
   2547 	__isl_take isl_aff *aff2)
   2548 {
   2549 	return isl_set_from_basic_set(isl_aff_eq_basic_set(aff1, aff2));
   2550 }
   2551 
   2552 /* Return a set containing those elements in the shared domain space
   2553  * of aff1 and aff2 where aff1 and aff2 are not equal.
   2554  *
   2555  * If either of the two inputs is NaN, then the result is empty,
   2556  * as comparisons with NaN always return false.
   2557  */
   2558 __isl_give isl_set *isl_aff_ne_set(__isl_take isl_aff *aff1,
   2559 	__isl_take isl_aff *aff2)
   2560 {
   2561 	isl_set *set_lt, *set_gt;
   2562 
   2563 	set_lt = isl_aff_lt_set(isl_aff_copy(aff1),
   2564 				isl_aff_copy(aff2));
   2565 	set_gt = isl_aff_gt_set(aff1, aff2);
   2566 	return isl_set_union_disjoint(set_lt, set_gt);
   2567 }
   2568 
   2569 __isl_give isl_aff *isl_aff_add_on_domain(__isl_keep isl_set *dom,
   2570 	__isl_take isl_aff *aff1, __isl_take isl_aff *aff2)
   2571 {
   2572 	aff1 = isl_aff_add(aff1, aff2);
   2573 	aff1 = isl_aff_gist(aff1, isl_set_copy(dom));
   2574 	return aff1;
   2575 }
   2576 
   2577 isl_bool isl_aff_is_empty(__isl_keep isl_aff *aff)
   2578 {
   2579 	if (!aff)
   2580 		return isl_bool_error;
   2581 
   2582 	return isl_bool_false;
   2583 }
   2584 
   2585 #undef TYPE
   2586 #define TYPE	isl_aff
   2587 static
   2588 #include "check_type_range_templ.c"
   2589 
   2590 /* Check whether the given affine expression has non-zero coefficient
   2591  * for any dimension in the given range or if any of these dimensions
   2592  * appear with non-zero coefficients in any of the integer divisions
   2593  * involved in the affine expression.
   2594  */
   2595 isl_bool isl_aff_involves_dims(__isl_keep isl_aff *aff,
   2596 	enum isl_dim_type type, unsigned first, unsigned n)
   2597 {
   2598 	int i;
   2599 	int *active = NULL;
   2600 	isl_bool involves = isl_bool_false;
   2601 
   2602 	if (!aff)
   2603 		return isl_bool_error;
   2604 	if (n == 0)
   2605 		return isl_bool_false;
   2606 	if (isl_aff_check_range(aff, type, first, n) < 0)
   2607 		return isl_bool_error;
   2608 
   2609 	active = isl_local_space_get_active(aff->ls, aff->v->el + 2);
   2610 	if (!active)
   2611 		goto error;
   2612 
   2613 	first += isl_local_space_offset(aff->ls, type) - 1;
   2614 	for (i = 0; i < n; ++i)
   2615 		if (active[first + i]) {
   2616 			involves = isl_bool_true;
   2617 			break;
   2618 		}
   2619 
   2620 	free(active);
   2621 
   2622 	return involves;
   2623 error:
   2624 	free(active);
   2625 	return isl_bool_error;
   2626 }
   2627 
   2628 /* Does "aff" involve any local variables, i.e., integer divisions?
   2629  */
   2630 isl_bool isl_aff_involves_locals(__isl_keep isl_aff *aff)
   2631 {
   2632 	isl_size n;
   2633 
   2634 	n = isl_aff_dim(aff, isl_dim_div);
   2635 	if (n < 0)
   2636 		return isl_bool_error;
   2637 	return isl_bool_ok(n > 0);
   2638 }
   2639 
   2640 __isl_give isl_aff *isl_aff_drop_dims(__isl_take isl_aff *aff,
   2641 	enum isl_dim_type type, unsigned first, unsigned n)
   2642 {
   2643 	if (!aff)
   2644 		return NULL;
   2645 	if (type == isl_dim_out)
   2646 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   2647 			"cannot drop output/set dimension",
   2648 			return isl_aff_free(aff));
   2649 	if (type == isl_dim_in)
   2650 		type = isl_dim_set;
   2651 	if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
   2652 		return aff;
   2653 
   2654 	if (isl_local_space_check_range(aff->ls, type, first, n) < 0)
   2655 		return isl_aff_free(aff);
   2656 
   2657 	aff = isl_aff_cow(aff);
   2658 	if (!aff)
   2659 		return NULL;
   2660 
   2661 	aff->ls = isl_local_space_drop_dims(aff->ls, type, first, n);
   2662 	if (!aff->ls)
   2663 		return isl_aff_free(aff);
   2664 
   2665 	first += 1 + isl_local_space_offset(aff->ls, type);
   2666 	aff->v = isl_vec_drop_els(aff->v, first, n);
   2667 	if (!aff->v)
   2668 		return isl_aff_free(aff);
   2669 
   2670 	return aff;
   2671 }
   2672 
   2673 /* Is the domain of "aff" a product?
   2674  */
   2675 static isl_bool isl_aff_domain_is_product(__isl_keep isl_aff *aff)
   2676 {
   2677 	return isl_space_is_product(isl_aff_peek_domain_space(aff));
   2678 }
   2679 
   2680 #undef TYPE
   2681 #define TYPE	isl_aff
   2682 #include <isl_domain_factor_templ.c>
   2683 
   2684 /* Project the domain of the affine expression onto its parameter space.
   2685  * The affine expression may not involve any of the domain dimensions.
   2686  */
   2687 __isl_give isl_aff *isl_aff_project_domain_on_params(__isl_take isl_aff *aff)
   2688 {
   2689 	isl_space *space;
   2690 	isl_size n;
   2691 
   2692 	n = isl_aff_dim(aff, isl_dim_in);
   2693 	if (n < 0)
   2694 		return isl_aff_free(aff);
   2695 	aff = isl_aff_drop_domain(aff, 0, n);
   2696 	space = isl_aff_get_domain_space(aff);
   2697 	space = isl_space_params(space);
   2698 	aff = isl_aff_reset_domain_space(aff, space);
   2699 	return aff;
   2700 }
   2701 
   2702 /* Convert an affine expression defined over a parameter domain
   2703  * into one that is defined over a zero-dimensional set.
   2704  */
   2705 __isl_give isl_aff *isl_aff_from_range(__isl_take isl_aff *aff)
   2706 {
   2707 	isl_local_space *ls;
   2708 
   2709 	ls = isl_aff_take_domain_local_space(aff);
   2710 	ls = isl_local_space_set_from_params(ls);
   2711 	aff = isl_aff_restore_domain_local_space(aff, ls);
   2712 
   2713 	return aff;
   2714 }
   2715 
   2716 __isl_give isl_aff *isl_aff_insert_dims(__isl_take isl_aff *aff,
   2717 	enum isl_dim_type type, unsigned first, unsigned n)
   2718 {
   2719 	if (!aff)
   2720 		return NULL;
   2721 	if (type == isl_dim_out)
   2722 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   2723 			"cannot insert output/set dimensions",
   2724 			return isl_aff_free(aff));
   2725 	if (type == isl_dim_in)
   2726 		type = isl_dim_set;
   2727 	if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
   2728 		return aff;
   2729 
   2730 	if (isl_local_space_check_range(aff->ls, type, first, 0) < 0)
   2731 		return isl_aff_free(aff);
   2732 
   2733 	aff = isl_aff_cow(aff);
   2734 	if (!aff)
   2735 		return NULL;
   2736 
   2737 	aff->ls = isl_local_space_insert_dims(aff->ls, type, first, n);
   2738 	if (!aff->ls)
   2739 		return isl_aff_free(aff);
   2740 
   2741 	first += 1 + isl_local_space_offset(aff->ls, type);
   2742 	aff->v = isl_vec_insert_zero_els(aff->v, first, n);
   2743 	if (!aff->v)
   2744 		return isl_aff_free(aff);
   2745 
   2746 	return aff;
   2747 }
   2748 
   2749 __isl_give isl_aff *isl_aff_add_dims(__isl_take isl_aff *aff,
   2750 	enum isl_dim_type type, unsigned n)
   2751 {
   2752 	isl_size pos;
   2753 
   2754 	pos = isl_aff_dim(aff, type);
   2755 	if (pos < 0)
   2756 		return isl_aff_free(aff);
   2757 
   2758 	return isl_aff_insert_dims(aff, type, pos, n);
   2759 }
   2760 
   2761 /* Move the "n" dimensions of "src_type" starting at "src_pos" of "aff"
   2762  * to dimensions of "dst_type" at "dst_pos".
   2763  *
   2764  * We only support moving input dimensions to parameters and vice versa.
   2765  */
   2766 __isl_give isl_aff *isl_aff_move_dims(__isl_take isl_aff *aff,
   2767 	enum isl_dim_type dst_type, unsigned dst_pos,
   2768 	enum isl_dim_type src_type, unsigned src_pos, unsigned n)
   2769 {
   2770 	unsigned g_dst_pos;
   2771 	unsigned g_src_pos;
   2772 	isl_size src_off, dst_off;
   2773 
   2774 	if (!aff)
   2775 		return NULL;
   2776 	if (n == 0 &&
   2777 	    !isl_local_space_is_named_or_nested(aff->ls, src_type) &&
   2778 	    !isl_local_space_is_named_or_nested(aff->ls, dst_type))
   2779 		return aff;
   2780 
   2781 	if (dst_type == isl_dim_out || src_type == isl_dim_out)
   2782 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   2783 			"cannot move output/set dimension",
   2784 			return isl_aff_free(aff));
   2785 	if (dst_type == isl_dim_div || src_type == isl_dim_div)
   2786 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   2787 			"cannot move divs", return isl_aff_free(aff));
   2788 	if (dst_type == isl_dim_in)
   2789 		dst_type = isl_dim_set;
   2790 	if (src_type == isl_dim_in)
   2791 		src_type = isl_dim_set;
   2792 
   2793 	if (isl_local_space_check_range(aff->ls, src_type, src_pos, n) < 0)
   2794 		return isl_aff_free(aff);
   2795 	if (dst_type == src_type)
   2796 		isl_die(isl_aff_get_ctx(aff), isl_error_unsupported,
   2797 			"moving dims within the same type not supported",
   2798 			return isl_aff_free(aff));
   2799 
   2800 	aff = isl_aff_cow(aff);
   2801 	src_off = isl_aff_domain_offset(aff, src_type);
   2802 	dst_off = isl_aff_domain_offset(aff, dst_type);
   2803 	if (src_off < 0 || dst_off < 0)
   2804 		return isl_aff_free(aff);
   2805 
   2806 	g_src_pos = 1 + src_off + src_pos;
   2807 	g_dst_pos = 1 + dst_off + dst_pos;
   2808 	if (dst_type > src_type)
   2809 		g_dst_pos -= n;
   2810 
   2811 	aff->v = isl_vec_move_els(aff->v, g_dst_pos, g_src_pos, n);
   2812 	aff->ls = isl_local_space_move_dims(aff->ls, dst_type, dst_pos,
   2813 						src_type, src_pos, n);
   2814 	if (!aff->v || !aff->ls)
   2815 		return isl_aff_free(aff);
   2816 
   2817 	aff = sort_divs(aff);
   2818 
   2819 	return aff;
   2820 }
   2821 
   2822 /* Given an affine function on a domain (A -> B),
   2823  * interchange A and B in the wrapped domain
   2824  * to obtain a function on the domain (B -> A).
   2825  *
   2826  * Since this may change the position of some variables,
   2827  * it may also change the normalized order of the local variables.
   2828  * Restore this order.  Since sort_divs assumes the input
   2829  * has a single reference, an explicit isl_aff_cow is required.
   2830  */
   2831 __isl_give isl_aff *isl_aff_domain_reverse(__isl_take isl_aff *aff)
   2832 {
   2833 	isl_space *space;
   2834 	isl_local_space *ls;
   2835 	isl_vec *v;
   2836 	isl_size n_in, n_out;
   2837 	unsigned offset;
   2838 
   2839 	space = isl_aff_peek_domain_space(aff);
   2840 	offset = isl_space_offset(space, isl_dim_set);
   2841 	n_in = isl_space_wrapped_dim(space, isl_dim_set, isl_dim_in);
   2842 	n_out = isl_space_wrapped_dim(space, isl_dim_set, isl_dim_out);
   2843 	if (offset < 0 || n_in < 0 || n_out < 0)
   2844 		return isl_aff_free(aff);
   2845 
   2846 	v = isl_aff_take_rat_aff(aff);
   2847 	v = isl_vec_move_els(v, 1 + 1 + offset, 1 + 1 + offset + n_in, n_out);
   2848 	aff = isl_aff_restore_rat_aff(aff, v);
   2849 
   2850 	ls = isl_aff_take_domain_local_space(aff);
   2851 	ls = isl_local_space_wrapped_reverse(ls);
   2852 	aff = isl_aff_restore_domain_local_space(aff, ls);
   2853 
   2854 	aff = isl_aff_cow(aff);
   2855 	aff = sort_divs(aff);
   2856 
   2857 	return aff;
   2858 }
   2859 
   2860 /* Return a zero isl_aff in the given space.
   2861  *
   2862  * This is a helper function for isl_pw_*_as_* that ensures a uniform
   2863  * interface over all piecewise types.
   2864  */
   2865 static __isl_give isl_aff *isl_aff_zero_in_space(__isl_take isl_space *space)
   2866 {
   2867 	isl_local_space *ls;
   2868 
   2869 	ls = isl_local_space_from_space(isl_space_domain(space));
   2870 	return isl_aff_zero_on_domain(ls);
   2871 }
   2872 
   2873 #define isl_aff_involves_nan isl_aff_is_nan
   2874 
   2875 #undef PW
   2876 #define PW isl_pw_aff
   2877 #undef BASE
   2878 #define BASE aff
   2879 #undef EL_IS_ZERO
   2880 #define EL_IS_ZERO is_empty
   2881 #undef ZERO
   2882 #define ZERO empty
   2883 #undef IS_ZERO
   2884 #define IS_ZERO is_empty
   2885 #undef FIELD
   2886 #define FIELD aff
   2887 #undef DEFAULT_IS_ZERO
   2888 #define DEFAULT_IS_ZERO 0
   2889 
   2890 #include <isl_pw_templ.c>
   2891 #include <isl_pw_un_op_templ.c>
   2892 #include <isl_pw_add_constant_val_templ.c>
   2893 #include <isl_pw_add_disjoint_templ.c>
   2894 #include <isl_pw_bind_domain_templ.c>
   2895 #include <isl_pw_domain_reverse_templ.c>
   2896 #include <isl_pw_eval.c>
   2897 #include <isl_pw_hash.c>
   2898 #include <isl_pw_fix_templ.c>
   2899 #include <isl_pw_from_range_templ.c>
   2900 #include <isl_pw_insert_dims_templ.c>
   2901 #include <isl_pw_insert_domain_templ.c>
   2902 #include <isl_pw_move_dims_templ.c>
   2903 #include <isl_pw_neg_templ.c>
   2904 #include <isl_pw_pullback_templ.c>
   2905 #include <isl_pw_scale_templ.c>
   2906 #include <isl_pw_sub_templ.c>
   2907 #include <isl_pw_union_opt.c>
   2908 
   2909 #undef BASE
   2910 #define BASE pw_aff
   2911 
   2912 #include <isl_union_single.c>
   2913 #include <isl_union_neg.c>
   2914 #include <isl_union_sub_templ.c>
   2915 
   2916 #undef BASE
   2917 #define BASE aff
   2918 
   2919 #include <isl_union_pw_templ.c>
   2920 
   2921 /* Compute a piecewise quasi-affine expression with a domain that
   2922  * is the union of those of pwaff1 and pwaff2 and such that on each
   2923  * cell, the quasi-affine expression is the maximum of those of pwaff1
   2924  * and pwaff2.  If only one of pwaff1 or pwaff2 is defined on a given
   2925  * cell, then the associated expression is the defined one.
   2926  */
   2927 __isl_give isl_pw_aff *isl_pw_aff_union_max(__isl_take isl_pw_aff *pwaff1,
   2928 	__isl_take isl_pw_aff *pwaff2)
   2929 {
   2930 	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
   2931 	return isl_pw_aff_union_opt_cmp(pwaff1, pwaff2, &isl_aff_ge_set);
   2932 }
   2933 
   2934 /* Compute a piecewise quasi-affine expression with a domain that
   2935  * is the union of those of pwaff1 and pwaff2 and such that on each
   2936  * cell, the quasi-affine expression is the minimum of those of pwaff1
   2937  * and pwaff2.  If only one of pwaff1 or pwaff2 is defined on a given
   2938  * cell, then the associated expression is the defined one.
   2939  */
   2940 __isl_give isl_pw_aff *isl_pw_aff_union_min(__isl_take isl_pw_aff *pwaff1,
   2941 	__isl_take isl_pw_aff *pwaff2)
   2942 {
   2943 	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
   2944 	return isl_pw_aff_union_opt_cmp(pwaff1, pwaff2, &isl_aff_le_set);
   2945 }
   2946 
   2947 __isl_give isl_pw_aff *isl_pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1,
   2948 	__isl_take isl_pw_aff *pwaff2, int max)
   2949 {
   2950 	if (max)
   2951 		return isl_pw_aff_union_max(pwaff1, pwaff2);
   2952 	else
   2953 		return isl_pw_aff_union_min(pwaff1, pwaff2);
   2954 }
   2955 
   2956 /* Is the domain of "pa" a product?
   2957  */
   2958 static isl_bool isl_pw_aff_domain_is_product(__isl_keep isl_pw_aff *pa)
   2959 {
   2960 	return isl_space_domain_is_wrapping(isl_pw_aff_peek_space(pa));
   2961 }
   2962 
   2963 #undef TYPE
   2964 #define TYPE	isl_pw_aff
   2965 #include <isl_domain_factor_templ.c>
   2966 
   2967 /* Return a set containing those elements in the domain
   2968  * of "pwaff" where it satisfies "fn" (if complement is 0) or
   2969  * does not satisfy "fn" (if complement is 1).
   2970  *
   2971  * The pieces with a NaN never belong to the result since
   2972  * NaN does not satisfy any property.
   2973  */
   2974 static __isl_give isl_set *pw_aff_locus(__isl_take isl_pw_aff *pwaff,
   2975 	__isl_give isl_basic_set *(*fn)(__isl_take isl_aff *aff, int rational,
   2976 		void *user),
   2977 	int complement, void *user)
   2978 {
   2979 	int i;
   2980 	isl_set *set;
   2981 
   2982 	if (!pwaff)
   2983 		return NULL;
   2984 
   2985 	set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff));
   2986 
   2987 	for (i = 0; i < pwaff->n; ++i) {
   2988 		isl_basic_set *bset;
   2989 		isl_set *set_i, *locus;
   2990 		isl_bool rational;
   2991 
   2992 		if (isl_aff_is_nan(pwaff->p[i].aff))
   2993 			continue;
   2994 
   2995 		rational = isl_set_has_rational(pwaff->p[i].set);
   2996 		bset = fn(isl_aff_copy(pwaff->p[i].aff), rational, user);
   2997 		locus = isl_set_from_basic_set(bset);
   2998 		set_i = isl_set_copy(pwaff->p[i].set);
   2999 		if (complement)
   3000 			set_i = isl_set_subtract(set_i, locus);
   3001 		else
   3002 			set_i = isl_set_intersect(set_i, locus);
   3003 		set = isl_set_union_disjoint(set, set_i);
   3004 	}
   3005 
   3006 	isl_pw_aff_free(pwaff);
   3007 
   3008 	return set;
   3009 }
   3010 
   3011 /* Return a set containing those elements in the domain
   3012  * of "pa" where it is positive.
   3013  */
   3014 __isl_give isl_set *isl_pw_aff_pos_set(__isl_take isl_pw_aff *pa)
   3015 {
   3016 	return pw_aff_locus(pa, &aff_pos_basic_set, 0, NULL);
   3017 }
   3018 
   3019 /* Return a set containing those elements in the domain
   3020  * of pwaff where it is non-negative.
   3021  */
   3022 __isl_give isl_set *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff)
   3023 {
   3024 	return pw_aff_locus(pwaff, &aff_nonneg_basic_set, 0, NULL);
   3025 }
   3026 
   3027 /* Return a set containing those elements in the domain
   3028  * of pwaff where it is zero.
   3029  */
   3030 __isl_give isl_set *isl_pw_aff_zero_set(__isl_take isl_pw_aff *pwaff)
   3031 {
   3032 	return pw_aff_locus(pwaff, &aff_zero_basic_set, 0, NULL);
   3033 }
   3034 
   3035 /* Return a set containing those elements in the domain
   3036  * of pwaff where it is not zero.
   3037  */
   3038 __isl_give isl_set *isl_pw_aff_non_zero_set(__isl_take isl_pw_aff *pwaff)
   3039 {
   3040 	return pw_aff_locus(pwaff, &aff_zero_basic_set, 1, NULL);
   3041 }
   3042 
   3043 /* Bind the affine function "aff" to the parameter "id",
   3044  * returning the elements in the domain where the affine expression
   3045  * is equal to the parameter.
   3046  */
   3047 __isl_give isl_basic_set *isl_aff_bind_id(__isl_take isl_aff *aff,
   3048 	__isl_take isl_id *id)
   3049 {
   3050 	isl_space *space;
   3051 	isl_aff *aff_id;
   3052 
   3053 	space = isl_aff_get_domain_space(aff);
   3054 	space = isl_space_add_param_id(space, isl_id_copy(id));
   3055 
   3056 	aff = isl_aff_align_params(aff, isl_space_copy(space));
   3057 	aff_id = isl_aff_param_on_domain_space_id(space, id);
   3058 
   3059 	return isl_aff_eq_basic_set(aff, aff_id);
   3060 }
   3061 
   3062 /* Wrapper around isl_aff_bind_id for use as pw_aff_locus callback.
   3063  * "rational" should not be set.
   3064  */
   3065 static __isl_give isl_basic_set *aff_bind_id(__isl_take isl_aff *aff,
   3066 	int rational, void *user)
   3067 {
   3068 	isl_id *id = user;
   3069 
   3070 	if (!aff)
   3071 		return NULL;
   3072 	if (rational)
   3073 		isl_die(isl_aff_get_ctx(aff), isl_error_unsupported,
   3074 			"rational binding not supported", goto error);
   3075 	return isl_aff_bind_id(aff, isl_id_copy(id));
   3076 error:
   3077 	isl_aff_free(aff);
   3078 	return NULL;
   3079 }
   3080 
   3081 /* Bind the piecewise affine function "pa" to the parameter "id",
   3082  * returning the elements in the domain where the expression
   3083  * is equal to the parameter.
   3084  */
   3085 __isl_give isl_set *isl_pw_aff_bind_id(__isl_take isl_pw_aff *pa,
   3086 	__isl_take isl_id *id)
   3087 {
   3088 	isl_set *bound;
   3089 
   3090 	bound = pw_aff_locus(pa, &aff_bind_id, 0, id);
   3091 	isl_id_free(id);
   3092 
   3093 	return bound;
   3094 }
   3095 
   3096 /* Return a set containing those elements in the shared domain
   3097  * of pwaff1 and pwaff2 where pwaff1 is greater than (or equal) to pwaff2.
   3098  *
   3099  * We compute the difference on the shared domain and then construct
   3100  * the set of values where this difference is non-negative.
   3101  * If strict is set, we first subtract 1 from the difference.
   3102  * If equal is set, we only return the elements where pwaff1 and pwaff2
   3103  * are equal.
   3104  */
   3105 static __isl_give isl_set *pw_aff_gte_set(__isl_take isl_pw_aff *pwaff1,
   3106 	__isl_take isl_pw_aff *pwaff2, int strict, int equal)
   3107 {
   3108 	isl_set *set1, *set2;
   3109 
   3110 	set1 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff1));
   3111 	set2 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff2));
   3112 	set1 = isl_set_intersect(set1, set2);
   3113 	pwaff1 = isl_pw_aff_intersect_domain(pwaff1, isl_set_copy(set1));
   3114 	pwaff2 = isl_pw_aff_intersect_domain(pwaff2, isl_set_copy(set1));
   3115 	pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_neg(pwaff2));
   3116 
   3117 	if (strict) {
   3118 		isl_space *space = isl_set_get_space(set1);
   3119 		isl_aff *aff;
   3120 		aff = isl_aff_zero_on_domain(isl_local_space_from_space(space));
   3121 		aff = isl_aff_add_constant_si(aff, -1);
   3122 		pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_alloc(set1, aff));
   3123 	} else
   3124 		isl_set_free(set1);
   3125 
   3126 	if (equal)
   3127 		return isl_pw_aff_zero_set(pwaff1);
   3128 	return isl_pw_aff_nonneg_set(pwaff1);
   3129 }
   3130 
   3131 /* Return a set containing those elements in the shared domain
   3132  * of pwaff1 and pwaff2 where pwaff1 is equal to pwaff2.
   3133  */
   3134 __isl_give isl_set *isl_pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1,
   3135 	__isl_take isl_pw_aff *pwaff2)
   3136 {
   3137 	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
   3138 	return pw_aff_gte_set(pwaff1, pwaff2, 0, 1);
   3139 }
   3140 
   3141 /* Return a set containing those elements in the shared domain
   3142  * of pwaff1 and pwaff2 where pwaff1 is greater than or equal to pwaff2.
   3143  */
   3144 __isl_give isl_set *isl_pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
   3145 	__isl_take isl_pw_aff *pwaff2)
   3146 {
   3147 	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
   3148 	return pw_aff_gte_set(pwaff1, pwaff2, 0, 0);
   3149 }
   3150 
   3151 /* Return a set containing those elements in the shared domain
   3152  * of pwaff1 and pwaff2 where pwaff1 is strictly greater than pwaff2.
   3153  */
   3154 __isl_give isl_set *isl_pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
   3155 	__isl_take isl_pw_aff *pwaff2)
   3156 {
   3157 	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
   3158 	return pw_aff_gte_set(pwaff1, pwaff2, 1, 0);
   3159 }
   3160 
   3161 __isl_give isl_set *isl_pw_aff_le_set(__isl_take isl_pw_aff *pwaff1,
   3162 	__isl_take isl_pw_aff *pwaff2)
   3163 {
   3164 	return isl_pw_aff_ge_set(pwaff2, pwaff1);
   3165 }
   3166 
   3167 __isl_give isl_set *isl_pw_aff_lt_set(__isl_take isl_pw_aff *pwaff1,
   3168 	__isl_take isl_pw_aff *pwaff2)
   3169 {
   3170 	return isl_pw_aff_gt_set(pwaff2, pwaff1);
   3171 }
   3172 
   3173 /* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
   3174  * where the function values are ordered in the same way as "order",
   3175  * which returns a set in the shared domain of its two arguments.
   3176  *
   3177  * Let "pa1" and "pa2" be defined on domains A and B respectively.
   3178  * We first pull back the two functions such that they are defined on
   3179  * the domain [A -> B].  Then we apply "order", resulting in a set
   3180  * in the space [A -> B].  Finally, we unwrap this set to obtain
   3181  * a map in the space A -> B.
   3182  */
   3183 static __isl_give isl_map *isl_pw_aff_order_map(
   3184 	__isl_take isl_pw_aff *pa1, __isl_take isl_pw_aff *pa2,
   3185 	__isl_give isl_set *(*order)(__isl_take isl_pw_aff *pa1,
   3186 		__isl_take isl_pw_aff *pa2))
   3187 {
   3188 	isl_space *space1, *space2;
   3189 	isl_multi_aff *ma;
   3190 	isl_set *set;
   3191 
   3192 	isl_pw_aff_align_params_bin(&pa1, &pa2);
   3193 	space1 = isl_space_domain(isl_pw_aff_get_space(pa1));
   3194 	space2 = isl_space_domain(isl_pw_aff_get_space(pa2));
   3195 	space1 = isl_space_map_from_domain_and_range(space1, space2);
   3196 	ma = isl_multi_aff_domain_map(isl_space_copy(space1));
   3197 	pa1 = isl_pw_aff_pullback_multi_aff(pa1, ma);
   3198 	ma = isl_multi_aff_range_map(space1);
   3199 	pa2 = isl_pw_aff_pullback_multi_aff(pa2, ma);
   3200 	set = order(pa1, pa2);
   3201 
   3202 	return isl_set_unwrap(set);
   3203 }
   3204 
   3205 /* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
   3206  * where the function values are equal.
   3207  */
   3208 __isl_give isl_map *isl_pw_aff_eq_map(__isl_take isl_pw_aff *pa1,
   3209 	__isl_take isl_pw_aff *pa2)
   3210 {
   3211 	return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_eq_set);
   3212 }
   3213 
   3214 /* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
   3215  * where the function value of "pa1" is less than or equal to
   3216  * the function value of "pa2".
   3217  */
   3218 __isl_give isl_map *isl_pw_aff_le_map(__isl_take isl_pw_aff *pa1,
   3219 	__isl_take isl_pw_aff *pa2)
   3220 {
   3221 	return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_le_set);
   3222 }
   3223 
   3224 /* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
   3225  * where the function value of "pa1" is less than the function value of "pa2".
   3226  */
   3227 __isl_give isl_map *isl_pw_aff_lt_map(__isl_take isl_pw_aff *pa1,
   3228 	__isl_take isl_pw_aff *pa2)
   3229 {
   3230 	return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_lt_set);
   3231 }
   3232 
   3233 /* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
   3234  * where the function value of "pa1" is greater than or equal to
   3235  * the function value of "pa2".
   3236  */
   3237 __isl_give isl_map *isl_pw_aff_ge_map(__isl_take isl_pw_aff *pa1,
   3238 	__isl_take isl_pw_aff *pa2)
   3239 {
   3240 	return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_ge_set);
   3241 }
   3242 
   3243 /* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
   3244  * where the function value of "pa1" is greater than the function value
   3245  * of "pa2".
   3246  */
   3247 __isl_give isl_map *isl_pw_aff_gt_map(__isl_take isl_pw_aff *pa1,
   3248 	__isl_take isl_pw_aff *pa2)
   3249 {
   3250 	return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_gt_set);
   3251 }
   3252 
   3253 /* Return a set containing those elements in the shared domain
   3254  * of the elements of list1 and list2 where each element in list1
   3255  * has the relation specified by "fn" with each element in list2.
   3256  */
   3257 static __isl_give isl_set *pw_aff_list_set(__isl_take isl_pw_aff_list *list1,
   3258 	__isl_take isl_pw_aff_list *list2,
   3259 	__isl_give isl_set *(*fn)(__isl_take isl_pw_aff *pwaff1,
   3260 				    __isl_take isl_pw_aff *pwaff2))
   3261 {
   3262 	int i, j;
   3263 	isl_ctx *ctx;
   3264 	isl_set *set;
   3265 
   3266 	if (!list1 || !list2)
   3267 		goto error;
   3268 
   3269 	ctx = isl_pw_aff_list_get_ctx(list1);
   3270 	if (list1->n < 1 || list2->n < 1)
   3271 		isl_die(ctx, isl_error_invalid,
   3272 			"list should contain at least one element", goto error);
   3273 
   3274 	set = isl_set_universe(isl_pw_aff_get_domain_space(list1->p[0]));
   3275 	for (i = 0; i < list1->n; ++i)
   3276 		for (j = 0; j < list2->n; ++j) {
   3277 			isl_set *set_ij;
   3278 
   3279 			set_ij = fn(isl_pw_aff_copy(list1->p[i]),
   3280 				    isl_pw_aff_copy(list2->p[j]));
   3281 			set = isl_set_intersect(set, set_ij);
   3282 		}
   3283 
   3284 	isl_pw_aff_list_free(list1);
   3285 	isl_pw_aff_list_free(list2);
   3286 	return set;
   3287 error:
   3288 	isl_pw_aff_list_free(list1);
   3289 	isl_pw_aff_list_free(list2);
   3290 	return NULL;
   3291 }
   3292 
   3293 /* Return a set containing those elements in the shared domain
   3294  * of the elements of list1 and list2 where each element in list1
   3295  * is equal to each element in list2.
   3296  */
   3297 __isl_give isl_set *isl_pw_aff_list_eq_set(__isl_take isl_pw_aff_list *list1,
   3298 	__isl_take isl_pw_aff_list *list2)
   3299 {
   3300 	return pw_aff_list_set(list1, list2, &isl_pw_aff_eq_set);
   3301 }
   3302 
   3303 __isl_give isl_set *isl_pw_aff_list_ne_set(__isl_take isl_pw_aff_list *list1,
   3304 	__isl_take isl_pw_aff_list *list2)
   3305 {
   3306 	return pw_aff_list_set(list1, list2, &isl_pw_aff_ne_set);
   3307 }
   3308 
   3309 /* Return a set containing those elements in the shared domain
   3310  * of the elements of list1 and list2 where each element in list1
   3311  * is less than or equal to each element in list2.
   3312  */
   3313 __isl_give isl_set *isl_pw_aff_list_le_set(__isl_take isl_pw_aff_list *list1,
   3314 	__isl_take isl_pw_aff_list *list2)
   3315 {
   3316 	return pw_aff_list_set(list1, list2, &isl_pw_aff_le_set);
   3317 }
   3318 
   3319 __isl_give isl_set *isl_pw_aff_list_lt_set(__isl_take isl_pw_aff_list *list1,
   3320 	__isl_take isl_pw_aff_list *list2)
   3321 {
   3322 	return pw_aff_list_set(list1, list2, &isl_pw_aff_lt_set);
   3323 }
   3324 
   3325 __isl_give isl_set *isl_pw_aff_list_ge_set(__isl_take isl_pw_aff_list *list1,
   3326 	__isl_take isl_pw_aff_list *list2)
   3327 {
   3328 	return pw_aff_list_set(list1, list2, &isl_pw_aff_ge_set);
   3329 }
   3330 
   3331 __isl_give isl_set *isl_pw_aff_list_gt_set(__isl_take isl_pw_aff_list *list1,
   3332 	__isl_take isl_pw_aff_list *list2)
   3333 {
   3334 	return pw_aff_list_set(list1, list2, &isl_pw_aff_gt_set);
   3335 }
   3336 
   3337 
   3338 /* Return a set containing those elements in the shared domain
   3339  * of pwaff1 and pwaff2 where pwaff1 is not equal to pwaff2.
   3340  */
   3341 __isl_give isl_set *isl_pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1,
   3342 	__isl_take isl_pw_aff *pwaff2)
   3343 {
   3344 	isl_set *set_lt, *set_gt;
   3345 
   3346 	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
   3347 	set_lt = isl_pw_aff_lt_set(isl_pw_aff_copy(pwaff1),
   3348 				   isl_pw_aff_copy(pwaff2));
   3349 	set_gt = isl_pw_aff_gt_set(pwaff1, pwaff2);
   3350 	return isl_set_union_disjoint(set_lt, set_gt);
   3351 }
   3352 
   3353 __isl_give isl_pw_aff *isl_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff,
   3354 	isl_int v)
   3355 {
   3356 	int i;
   3357 
   3358 	if (isl_int_is_one(v))
   3359 		return pwaff;
   3360 	if (!isl_int_is_pos(v))
   3361 		isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
   3362 			"factor needs to be positive",
   3363 			return isl_pw_aff_free(pwaff));
   3364 	pwaff = isl_pw_aff_cow(pwaff);
   3365 	if (!pwaff)
   3366 		return NULL;
   3367 	if (pwaff->n == 0)
   3368 		return pwaff;
   3369 
   3370 	for (i = 0; i < pwaff->n; ++i) {
   3371 		pwaff->p[i].aff = isl_aff_scale_down(pwaff->p[i].aff, v);
   3372 		if (!pwaff->p[i].aff)
   3373 			return isl_pw_aff_free(pwaff);
   3374 	}
   3375 
   3376 	return pwaff;
   3377 }
   3378 
   3379 __isl_give isl_pw_aff *isl_pw_aff_floor(__isl_take isl_pw_aff *pwaff)
   3380 {
   3381 	struct isl_pw_aff_un_op_control control = { .fn_base = &isl_aff_floor };
   3382 	return isl_pw_aff_un_op(pwaff, &control);
   3383 }
   3384 
   3385 __isl_give isl_pw_aff *isl_pw_aff_ceil(__isl_take isl_pw_aff *pwaff)
   3386 {
   3387 	struct isl_pw_aff_un_op_control control = { .fn_base = &isl_aff_ceil };
   3388 	return isl_pw_aff_un_op(pwaff, &control);
   3389 }
   3390 
   3391 /* Assuming that "cond1" and "cond2" are disjoint,
   3392  * return an affine expression that is equal to pwaff1 on cond1
   3393  * and to pwaff2 on cond2.
   3394  */
   3395 static __isl_give isl_pw_aff *isl_pw_aff_select(
   3396 	__isl_take isl_set *cond1, __isl_take isl_pw_aff *pwaff1,
   3397 	__isl_take isl_set *cond2, __isl_take isl_pw_aff *pwaff2)
   3398 {
   3399 	pwaff1 = isl_pw_aff_intersect_domain(pwaff1, cond1);
   3400 	pwaff2 = isl_pw_aff_intersect_domain(pwaff2, cond2);
   3401 
   3402 	return isl_pw_aff_add_disjoint(pwaff1, pwaff2);
   3403 }
   3404 
   3405 /* Return an affine expression that is equal to pwaff_true for elements
   3406  * where "cond" is non-zero and to pwaff_false for elements where "cond"
   3407  * is zero.
   3408  * That is, return cond ? pwaff_true : pwaff_false;
   3409  *
   3410  * If "cond" involves and NaN, then we conservatively return a NaN
   3411  * on its entire domain.  In principle, we could consider the pieces
   3412  * where it is NaN separately from those where it is not.
   3413  *
   3414  * If "pwaff_true" and "pwaff_false" are obviously equal to each other,
   3415  * then only use the domain of "cond" to restrict the domain.
   3416  */
   3417 __isl_give isl_pw_aff *isl_pw_aff_cond(__isl_take isl_pw_aff *cond,
   3418 	__isl_take isl_pw_aff *pwaff_true, __isl_take isl_pw_aff *pwaff_false)
   3419 {
   3420 	isl_set *cond_true, *cond_false;
   3421 	isl_bool equal;
   3422 
   3423 	if (!cond)
   3424 		goto error;
   3425 	if (isl_pw_aff_involves_nan(cond)) {
   3426 		isl_space *space = isl_pw_aff_get_domain_space(cond);
   3427 		isl_local_space *ls = isl_local_space_from_space(space);
   3428 		isl_pw_aff_free(cond);
   3429 		isl_pw_aff_free(pwaff_true);
   3430 		isl_pw_aff_free(pwaff_false);
   3431 		return isl_pw_aff_nan_on_domain(ls);
   3432 	}
   3433 
   3434 	pwaff_true = isl_pw_aff_align_params(pwaff_true,
   3435 					    isl_pw_aff_get_space(pwaff_false));
   3436 	pwaff_false = isl_pw_aff_align_params(pwaff_false,
   3437 					    isl_pw_aff_get_space(pwaff_true));
   3438 	equal = isl_pw_aff_plain_is_equal(pwaff_true, pwaff_false);
   3439 	if (equal < 0)
   3440 		goto error;
   3441 	if (equal) {
   3442 		isl_set *dom;
   3443 
   3444 		dom = isl_set_coalesce(isl_pw_aff_domain(cond));
   3445 		isl_pw_aff_free(pwaff_false);
   3446 		return isl_pw_aff_intersect_domain(pwaff_true, dom);
   3447 	}
   3448 
   3449 	cond_true = isl_pw_aff_non_zero_set(isl_pw_aff_copy(cond));
   3450 	cond_false = isl_pw_aff_zero_set(cond);
   3451 	return isl_pw_aff_select(cond_true, pwaff_true,
   3452 				 cond_false, pwaff_false);
   3453 error:
   3454 	isl_pw_aff_free(cond);
   3455 	isl_pw_aff_free(pwaff_true);
   3456 	isl_pw_aff_free(pwaff_false);
   3457 	return NULL;
   3458 }
   3459 
   3460 isl_bool isl_aff_is_cst(__isl_keep isl_aff *aff)
   3461 {
   3462 	int pos;
   3463 
   3464 	if (!aff)
   3465 		return isl_bool_error;
   3466 
   3467 	pos = isl_seq_first_non_zero(aff->v->el + 2, aff->v->size - 2);
   3468 	return isl_bool_ok(pos == -1);
   3469 }
   3470 
   3471 /* Check whether pwaff is a piecewise constant.
   3472  */
   3473 isl_bool isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff)
   3474 {
   3475 	int i;
   3476 
   3477 	if (!pwaff)
   3478 		return isl_bool_error;
   3479 
   3480 	for (i = 0; i < pwaff->n; ++i) {
   3481 		isl_bool is_cst = isl_aff_is_cst(pwaff->p[i].aff);
   3482 		if (is_cst < 0 || !is_cst)
   3483 			return is_cst;
   3484 	}
   3485 
   3486 	return isl_bool_true;
   3487 }
   3488 
   3489 /* Return the product of "aff1" and "aff2".
   3490  *
   3491  * If either of the two is NaN, then the result is NaN.
   3492  *
   3493  * Otherwise, at least one of "aff1" or "aff2" needs to be a constant.
   3494  */
   3495 __isl_give isl_aff *isl_aff_mul(__isl_take isl_aff *aff1,
   3496 	__isl_take isl_aff *aff2)
   3497 {
   3498 	if (!aff1 || !aff2)
   3499 		goto error;
   3500 
   3501 	if (isl_aff_is_nan(aff1)) {
   3502 		isl_aff_free(aff2);
   3503 		return aff1;
   3504 	}
   3505 	if (isl_aff_is_nan(aff2)) {
   3506 		isl_aff_free(aff1);
   3507 		return aff2;
   3508 	}
   3509 
   3510 	if (!isl_aff_is_cst(aff2) && isl_aff_is_cst(aff1))
   3511 		return isl_aff_mul(aff2, aff1);
   3512 
   3513 	if (!isl_aff_is_cst(aff2))
   3514 		isl_die(isl_aff_get_ctx(aff1), isl_error_invalid,
   3515 			"at least one affine expression should be constant",
   3516 			goto error);
   3517 
   3518 	aff1 = isl_aff_cow(aff1);
   3519 	if (!aff1 || !aff2)
   3520 		goto error;
   3521 
   3522 	aff1 = isl_aff_scale(aff1, aff2->v->el[1]);
   3523 	aff1 = isl_aff_scale_down(aff1, aff2->v->el[0]);
   3524 
   3525 	isl_aff_free(aff2);
   3526 	return aff1;
   3527 error:
   3528 	isl_aff_free(aff1);
   3529 	isl_aff_free(aff2);
   3530 	return NULL;
   3531 }
   3532 
   3533 /* Divide "aff1" by "aff2", assuming "aff2" is a constant.
   3534  *
   3535  * If either of the two is NaN, then the result is NaN.
   3536  * A division by zero also results in NaN.
   3537  */
   3538 __isl_give isl_aff *isl_aff_div(__isl_take isl_aff *aff1,
   3539 	__isl_take isl_aff *aff2)
   3540 {
   3541 	isl_bool is_cst, is_zero;
   3542 	int neg;
   3543 
   3544 	if (!aff1 || !aff2)
   3545 		goto error;
   3546 
   3547 	if (isl_aff_is_nan(aff1)) {
   3548 		isl_aff_free(aff2);
   3549 		return aff1;
   3550 	}
   3551 	if (isl_aff_is_nan(aff2)) {
   3552 		isl_aff_free(aff1);
   3553 		return aff2;
   3554 	}
   3555 
   3556 	is_cst = isl_aff_is_cst(aff2);
   3557 	if (is_cst < 0)
   3558 		goto error;
   3559 	if (!is_cst)
   3560 		isl_die(isl_aff_get_ctx(aff2), isl_error_invalid,
   3561 			"second argument should be a constant", goto error);
   3562 	is_zero = isl_aff_plain_is_zero(aff2);
   3563 	if (is_zero < 0)
   3564 		goto error;
   3565 	if (is_zero)
   3566 		return set_nan_free(aff1, aff2);
   3567 
   3568 	neg = isl_int_is_neg(aff2->v->el[1]);
   3569 	if (neg) {
   3570 		isl_int_neg(aff2->v->el[0], aff2->v->el[0]);
   3571 		isl_int_neg(aff2->v->el[1], aff2->v->el[1]);
   3572 	}
   3573 
   3574 	aff1 = isl_aff_scale(aff1, aff2->v->el[0]);
   3575 	aff1 = isl_aff_scale_down(aff1, aff2->v->el[1]);
   3576 
   3577 	if (neg) {
   3578 		isl_int_neg(aff2->v->el[0], aff2->v->el[0]);
   3579 		isl_int_neg(aff2->v->el[1], aff2->v->el[1]);
   3580 	}
   3581 
   3582 	isl_aff_free(aff2);
   3583 	return aff1;
   3584 error:
   3585 	isl_aff_free(aff1);
   3586 	isl_aff_free(aff2);
   3587 	return NULL;
   3588 }
   3589 
   3590 __isl_give isl_pw_aff *isl_pw_aff_add(__isl_take isl_pw_aff *pwaff1,
   3591 	__isl_take isl_pw_aff *pwaff2)
   3592 {
   3593 	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
   3594 	return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_add);
   3595 }
   3596 
   3597 __isl_give isl_pw_aff *isl_pw_aff_mul(__isl_take isl_pw_aff *pwaff1,
   3598 	__isl_take isl_pw_aff *pwaff2)
   3599 {
   3600 	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
   3601 	return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_mul);
   3602 }
   3603 
   3604 /* Divide "pa1" by "pa2", assuming "pa2" is a piecewise constant.
   3605  */
   3606 __isl_give isl_pw_aff *isl_pw_aff_div(__isl_take isl_pw_aff *pa1,
   3607 	__isl_take isl_pw_aff *pa2)
   3608 {
   3609 	int is_cst;
   3610 
   3611 	is_cst = isl_pw_aff_is_cst(pa2);
   3612 	if (is_cst < 0)
   3613 		goto error;
   3614 	if (!is_cst)
   3615 		isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,
   3616 			"second argument should be a piecewise constant",
   3617 			goto error);
   3618 	isl_pw_aff_align_params_bin(&pa1, &pa2);
   3619 	return isl_pw_aff_on_shared_domain(pa1, pa2, &isl_aff_div);
   3620 error:
   3621 	isl_pw_aff_free(pa1);
   3622 	isl_pw_aff_free(pa2);
   3623 	return NULL;
   3624 }
   3625 
   3626 /* Compute the quotient of the integer division of "pa1" by "pa2"
   3627  * with rounding towards zero.
   3628  * "pa2" is assumed to be a piecewise constant.
   3629  *
   3630  * In particular, return
   3631  *
   3632  *	pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2)
   3633  *
   3634  */
   3635 __isl_give isl_pw_aff *isl_pw_aff_tdiv_q(__isl_take isl_pw_aff *pa1,
   3636 	__isl_take isl_pw_aff *pa2)
   3637 {
   3638 	int is_cst;
   3639 	isl_set *cond;
   3640 	isl_pw_aff *f, *c;
   3641 
   3642 	is_cst = isl_pw_aff_is_cst(pa2);
   3643 	if (is_cst < 0)
   3644 		goto error;
   3645 	if (!is_cst)
   3646 		isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,
   3647 			"second argument should be a piecewise constant",
   3648 			goto error);
   3649 
   3650 	pa1 = isl_pw_aff_div(pa1, pa2);
   3651 
   3652 	cond = isl_pw_aff_nonneg_set(isl_pw_aff_copy(pa1));
   3653 	f = isl_pw_aff_floor(isl_pw_aff_copy(pa1));
   3654 	c = isl_pw_aff_ceil(pa1);
   3655 	return isl_pw_aff_cond(isl_set_indicator_function(cond), f, c);
   3656 error:
   3657 	isl_pw_aff_free(pa1);
   3658 	isl_pw_aff_free(pa2);
   3659 	return NULL;
   3660 }
   3661 
   3662 /* Compute the remainder of the integer division of "pa1" by "pa2"
   3663  * with rounding towards zero.
   3664  * "pa2" is assumed to be a piecewise constant.
   3665  *
   3666  * In particular, return
   3667  *
   3668  *	pa1 - pa2 * (pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2))
   3669  *
   3670  */
   3671 __isl_give isl_pw_aff *isl_pw_aff_tdiv_r(__isl_take isl_pw_aff *pa1,
   3672 	__isl_take isl_pw_aff *pa2)
   3673 {
   3674 	int is_cst;
   3675 	isl_pw_aff *res;
   3676 
   3677 	is_cst = isl_pw_aff_is_cst(pa2);
   3678 	if (is_cst < 0)
   3679 		goto error;
   3680 	if (!is_cst)
   3681 		isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,
   3682 			"second argument should be a piecewise constant",
   3683 			goto error);
   3684 	res = isl_pw_aff_tdiv_q(isl_pw_aff_copy(pa1), isl_pw_aff_copy(pa2));
   3685 	res = isl_pw_aff_mul(pa2, res);
   3686 	res = isl_pw_aff_sub(pa1, res);
   3687 	return res;
   3688 error:
   3689 	isl_pw_aff_free(pa1);
   3690 	isl_pw_aff_free(pa2);
   3691 	return NULL;
   3692 }
   3693 
   3694 /* Does either of "pa1" or "pa2" involve any NaN?
   3695  */
   3696 static isl_bool either_involves_nan(__isl_keep isl_pw_aff *pa1,
   3697 	__isl_keep isl_pw_aff *pa2)
   3698 {
   3699 	isl_bool has_nan;
   3700 
   3701 	has_nan = isl_pw_aff_involves_nan(pa1);
   3702 	if (has_nan < 0 || has_nan)
   3703 		return has_nan;
   3704 	return isl_pw_aff_involves_nan(pa2);
   3705 }
   3706 
   3707 /* Return a piecewise affine expression defined on the specified domain
   3708  * that represents NaN.
   3709  */
   3710 static __isl_give isl_pw_aff *nan_on_domain_set(__isl_take isl_set *dom)
   3711 {
   3712 	isl_local_space *ls;
   3713 	isl_pw_aff *pa;
   3714 
   3715 	ls = isl_local_space_from_space(isl_set_get_space(dom));
   3716 	pa = isl_pw_aff_nan_on_domain(ls);
   3717 	pa = isl_pw_aff_intersect_domain(pa, dom);
   3718 
   3719 	return pa;
   3720 }
   3721 
   3722 /* Replace "pa1" and "pa2" (at least one of which involves a NaN)
   3723  * by a NaN on their shared domain.
   3724  *
   3725  * In principle, the result could be refined to only being NaN
   3726  * on the parts of this domain where at least one of "pa1" or "pa2" is NaN.
   3727  */
   3728 static __isl_give isl_pw_aff *replace_by_nan(__isl_take isl_pw_aff *pa1,
   3729 	__isl_take isl_pw_aff *pa2)
   3730 {
   3731 	isl_set *dom;
   3732 
   3733 	dom = isl_set_intersect(isl_pw_aff_domain(pa1), isl_pw_aff_domain(pa2));
   3734 	return nan_on_domain_set(dom);
   3735 }
   3736 
   3737 static __isl_give isl_pw_aff *pw_aff_min(__isl_take isl_pw_aff *pwaff1,
   3738 	__isl_take isl_pw_aff *pwaff2)
   3739 {
   3740 	isl_set *le;
   3741 	isl_set *dom;
   3742 
   3743 	dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)),
   3744 				isl_pw_aff_domain(isl_pw_aff_copy(pwaff2)));
   3745 	le = isl_pw_aff_le_set(isl_pw_aff_copy(pwaff1),
   3746 				isl_pw_aff_copy(pwaff2));
   3747 	dom = isl_set_subtract(dom, isl_set_copy(le));
   3748 	return isl_pw_aff_select(le, pwaff1, dom, pwaff2);
   3749 }
   3750 
   3751 static __isl_give isl_pw_aff *pw_aff_max(__isl_take isl_pw_aff *pwaff1,
   3752 	__isl_take isl_pw_aff *pwaff2)
   3753 {
   3754 	isl_set *ge;
   3755 	isl_set *dom;
   3756 
   3757 	dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)),
   3758 				isl_pw_aff_domain(isl_pw_aff_copy(pwaff2)));
   3759 	ge = isl_pw_aff_ge_set(isl_pw_aff_copy(pwaff1),
   3760 				isl_pw_aff_copy(pwaff2));
   3761 	dom = isl_set_subtract(dom, isl_set_copy(ge));
   3762 	return isl_pw_aff_select(ge, pwaff1, dom, pwaff2);
   3763 }
   3764 
   3765 /* Return an expression for the minimum (if "max" is not set) or
   3766  * the maximum (if "max" is set) of "pa1" and "pa2".
   3767  * If either expression involves any NaN, then return a NaN
   3768  * on the shared domain as result.
   3769  */
   3770 static __isl_give isl_pw_aff *pw_aff_min_max(__isl_take isl_pw_aff *pa1,
   3771 	__isl_take isl_pw_aff *pa2, int max)
   3772 {
   3773 	isl_bool has_nan;
   3774 
   3775 	has_nan = either_involves_nan(pa1, pa2);
   3776 	if (has_nan < 0)
   3777 		pa1 = isl_pw_aff_free(pa1);
   3778 	else if (has_nan)
   3779 		return replace_by_nan(pa1, pa2);
   3780 
   3781 	isl_pw_aff_align_params_bin(&pa1, &pa2);
   3782 	if (max)
   3783 		return pw_aff_max(pa1, pa2);
   3784 	else
   3785 		return pw_aff_min(pa1, pa2);
   3786 }
   3787 
   3788 /* Return an expression for the minimum of "pwaff1" and "pwaff2".
   3789  */
   3790 __isl_give isl_pw_aff *isl_pw_aff_min(__isl_take isl_pw_aff *pwaff1,
   3791 	__isl_take isl_pw_aff *pwaff2)
   3792 {
   3793 	return pw_aff_min_max(pwaff1, pwaff2, 0);
   3794 }
   3795 
   3796 /* Return an expression for the maximum of "pwaff1" and "pwaff2".
   3797  */
   3798 __isl_give isl_pw_aff *isl_pw_aff_max(__isl_take isl_pw_aff *pwaff1,
   3799 	__isl_take isl_pw_aff *pwaff2)
   3800 {
   3801 	return pw_aff_min_max(pwaff1, pwaff2, 1);
   3802 }
   3803 
   3804 /* Does "pa" not involve any NaN?
   3805  */
   3806 static isl_bool pw_aff_no_nan(__isl_keep isl_pw_aff *pa, void *user)
   3807 {
   3808 	return isl_bool_not(isl_pw_aff_involves_nan(pa));
   3809 }
   3810 
   3811 /* Does any element of "list" involve any NaN?
   3812  *
   3813  * That is, is it not the case that every element does not involve any NaN?
   3814  */
   3815 static isl_bool isl_pw_aff_list_involves_nan(__isl_keep isl_pw_aff_list *list)
   3816 {
   3817 	return isl_bool_not(isl_pw_aff_list_every(list, &pw_aff_no_nan, NULL));
   3818 }
   3819 
   3820 /* Replace "list" (consisting of "n" elements, of which
   3821  * at least one element involves a NaN)
   3822  * by a NaN on the shared domain of the elements.
   3823  *
   3824  * In principle, the result could be refined to only being NaN
   3825  * on the parts of this domain where at least one of the elements is NaN.
   3826  */
   3827 static __isl_give isl_pw_aff *replace_list_by_nan(
   3828 	__isl_take isl_pw_aff_list *list, int n)
   3829 {
   3830 	int i;
   3831 	isl_set *dom;
   3832 
   3833 	dom = isl_pw_aff_domain(isl_pw_aff_list_get_at(list, 0));
   3834 	for (i = 1; i < n; ++i) {
   3835 		isl_set *dom_i;
   3836 
   3837 		dom_i = isl_pw_aff_domain(isl_pw_aff_list_get_at(list, i));
   3838 		dom = isl_set_intersect(dom, dom_i);
   3839 	}
   3840 
   3841 	isl_pw_aff_list_free(list);
   3842 	return nan_on_domain_set(dom);
   3843 }
   3844 
   3845 /* Return the set where the element at "pos1" of "list" is less than or
   3846  * equal to the element at "pos2".
   3847  * Equality is only allowed if "pos1" is smaller than "pos2".
   3848  */
   3849 static __isl_give isl_set *less(__isl_keep isl_pw_aff_list *list,
   3850 	int pos1, int pos2)
   3851 {
   3852 	isl_pw_aff *pa1, *pa2;
   3853 
   3854 	pa1 = isl_pw_aff_list_get_at(list, pos1);
   3855 	pa2 = isl_pw_aff_list_get_at(list, pos2);
   3856 
   3857 	if (pos1 < pos2)
   3858 		return isl_pw_aff_le_set(pa1, pa2);
   3859 	else
   3860 		return isl_pw_aff_lt_set(pa1, pa2);
   3861 }
   3862 
   3863 /* Return an isl_pw_aff that maps each element in the intersection of the
   3864  * domains of the piecewise affine expressions in "list"
   3865  * to the maximal (if "max" is set) or minimal (if "max" is not set)
   3866  * expression in "list" at that element.
   3867  * If any expression involves any NaN, then return a NaN
   3868  * on the shared domain as result.
   3869  *
   3870  * If "list" has n elements, then the result consists of n pieces,
   3871  * where, in the case of a minimum, each piece has as value expression
   3872  * the value expression of one of the elements and as domain
   3873  * the set of elements where that value expression
   3874  * is less than (or equal) to the other value expressions.
   3875  * In the case of a maximum, the condition is
   3876  * that all the other value expressions are less than (or equal)
   3877  * to the given value expression.
   3878  *
   3879  * In order to produce disjoint pieces, a pair of elements
   3880  * in the original domain is only allowed to be equal to each other
   3881  * on exactly one of the two pieces corresponding to the two elements.
   3882  * The position in the list is used to break ties.
   3883  * In particular, in the case of a minimum,
   3884  * in the piece corresponding to a given element,
   3885  * this element is allowed to be equal to any later element in the list,
   3886  * but not to any earlier element in the list.
   3887  */
   3888 static __isl_give isl_pw_aff *isl_pw_aff_list_opt(
   3889 	__isl_take isl_pw_aff_list *list, int max)
   3890 {
   3891 	int i, j;
   3892 	isl_bool has_nan;
   3893 	isl_size n;
   3894 	isl_space *space;
   3895 	isl_pw_aff *pa, *res;
   3896 
   3897 	n = isl_pw_aff_list_size(list);
   3898 	if (n < 0)
   3899 		goto error;
   3900 	if (n < 1)
   3901 		isl_die(isl_pw_aff_list_get_ctx(list), isl_error_invalid,
   3902 			"list should contain at least one element", goto error);
   3903 
   3904 	has_nan = isl_pw_aff_list_involves_nan(list);
   3905 	if (has_nan < 0)
   3906 		goto error;
   3907 	if (has_nan)
   3908 		return replace_list_by_nan(list, n);
   3909 
   3910 	pa = isl_pw_aff_list_get_at(list, 0);
   3911 	space = isl_pw_aff_get_space(pa);
   3912 	isl_pw_aff_free(pa);
   3913 	res = isl_pw_aff_empty(space);
   3914 
   3915 	for (i = 0; i < n; ++i) {
   3916 		pa = isl_pw_aff_list_get_at(list, i);
   3917 		for (j = 0; j < n; ++j) {
   3918 			isl_set *dom;
   3919 
   3920 			if (j == i)
   3921 				continue;
   3922 			if (max)
   3923 				dom = less(list, j, i);
   3924 			else
   3925 				dom = less(list, i, j);
   3926 
   3927 			pa = isl_pw_aff_intersect_domain(pa, dom);
   3928 		}
   3929 		res =  isl_pw_aff_add_disjoint(res, pa);
   3930 	}
   3931 
   3932 	isl_pw_aff_list_free(list);
   3933 	return res;
   3934 error:
   3935 	isl_pw_aff_list_free(list);
   3936 	return NULL;
   3937 }
   3938 
   3939 /* Return an isl_pw_aff that maps each element in the intersection of the
   3940  * domains of the elements of list to the minimal corresponding affine
   3941  * expression.
   3942  */
   3943 __isl_give isl_pw_aff *isl_pw_aff_list_min(__isl_take isl_pw_aff_list *list)
   3944 {
   3945 	return isl_pw_aff_list_opt(list, 0);
   3946 }
   3947 
   3948 /* Return an isl_pw_aff that maps each element in the intersection of the
   3949  * domains of the elements of list to the maximal corresponding affine
   3950  * expression.
   3951  */
   3952 __isl_give isl_pw_aff *isl_pw_aff_list_max(__isl_take isl_pw_aff_list *list)
   3953 {
   3954 	return isl_pw_aff_list_opt(list, 1);
   3955 }
   3956 
   3957 /* Mark the domains of "pwaff" as rational.
   3958  */
   3959 __isl_give isl_pw_aff *isl_pw_aff_set_rational(__isl_take isl_pw_aff *pwaff)
   3960 {
   3961 	int i;
   3962 
   3963 	pwaff = isl_pw_aff_cow(pwaff);
   3964 	if (!pwaff)
   3965 		return NULL;
   3966 	if (pwaff->n == 0)
   3967 		return pwaff;
   3968 
   3969 	for (i = 0; i < pwaff->n; ++i) {
   3970 		pwaff->p[i].set = isl_set_set_rational(pwaff->p[i].set);
   3971 		if (!pwaff->p[i].set)
   3972 			return isl_pw_aff_free(pwaff);
   3973 	}
   3974 
   3975 	return pwaff;
   3976 }
   3977 
   3978 /* Mark the domains of the elements of "list" as rational.
   3979  */
   3980 __isl_give isl_pw_aff_list *isl_pw_aff_list_set_rational(
   3981 	__isl_take isl_pw_aff_list *list)
   3982 {
   3983 	int i, n;
   3984 
   3985 	if (!list)
   3986 		return NULL;
   3987 	if (list->n == 0)
   3988 		return list;
   3989 
   3990 	n = list->n;
   3991 	for (i = 0; i < n; ++i) {
   3992 		isl_pw_aff *pa;
   3993 
   3994 		pa = isl_pw_aff_list_get_pw_aff(list, i);
   3995 		pa = isl_pw_aff_set_rational(pa);
   3996 		list = isl_pw_aff_list_set_pw_aff(list, i, pa);
   3997 	}
   3998 
   3999 	return list;
   4000 }
   4001 
   4002 /* Do the parameters of "aff" match those of "space"?
   4003  */
   4004 isl_bool isl_aff_matching_params(__isl_keep isl_aff *aff,
   4005 	__isl_keep isl_space *space)
   4006 {
   4007 	isl_space *aff_space;
   4008 	isl_bool match;
   4009 
   4010 	if (!aff || !space)
   4011 		return isl_bool_error;
   4012 
   4013 	aff_space = isl_aff_get_domain_space(aff);
   4014 
   4015 	match = isl_space_has_equal_params(space, aff_space);
   4016 
   4017 	isl_space_free(aff_space);
   4018 	return match;
   4019 }
   4020 
   4021 /* Check that the domain space of "aff" matches "space".
   4022  */
   4023 isl_stat isl_aff_check_match_domain_space(__isl_keep isl_aff *aff,
   4024 	__isl_keep isl_space *space)
   4025 {
   4026 	isl_space *aff_space;
   4027 	isl_bool match;
   4028 
   4029 	if (!aff || !space)
   4030 		return isl_stat_error;
   4031 
   4032 	aff_space = isl_aff_get_domain_space(aff);
   4033 
   4034 	match = isl_space_has_equal_params(space, aff_space);
   4035 	if (match < 0)
   4036 		goto error;
   4037 	if (!match)
   4038 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   4039 			"parameters don't match", goto error);
   4040 	match = isl_space_tuple_is_equal(space, isl_dim_in,
   4041 					aff_space, isl_dim_set);
   4042 	if (match < 0)
   4043 		goto error;
   4044 	if (!match)
   4045 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   4046 			"domains don't match", goto error);
   4047 	isl_space_free(aff_space);
   4048 	return isl_stat_ok;
   4049 error:
   4050 	isl_space_free(aff_space);
   4051 	return isl_stat_error;
   4052 }
   4053 
   4054 /* Return the shared (universe) domain of the elements of "ma".
   4055  *
   4056  * Since an isl_multi_aff (and an isl_aff) is always total,
   4057  * the domain is always the universe set in its domain space.
   4058  * This is a helper function for use in the generic isl_multi_*_bind.
   4059  */
   4060 static __isl_give isl_basic_set *isl_multi_aff_domain(
   4061 	__isl_take isl_multi_aff *ma)
   4062 {
   4063 	isl_space *space;
   4064 
   4065 	space = isl_multi_aff_get_space(ma);
   4066 	isl_multi_aff_free(ma);
   4067 
   4068 	return isl_basic_set_universe(isl_space_domain(space));
   4069 }
   4070 
   4071 #undef BASE
   4072 #define BASE aff
   4073 
   4074 #include <isl_multi_no_explicit_domain.c>
   4075 #include <isl_multi_templ.c>
   4076 #include <isl_multi_un_op_templ.c>
   4077 #include <isl_multi_bin_val_templ.c>
   4078 #include <isl_multi_add_constant_templ.c>
   4079 #include <isl_multi_align_set.c>
   4080 #include <isl_multi_arith_templ.c>
   4081 #include <isl_multi_bind_domain_templ.c>
   4082 #include <isl_multi_cmp.c>
   4083 #include <isl_multi_dim_id_templ.c>
   4084 #include <isl_multi_dims.c>
   4085 #include <isl_multi_domain_reverse_templ.c>
   4086 #include <isl_multi_floor.c>
   4087 #include <isl_multi_from_base_templ.c>
   4088 #include <isl_multi_identity_templ.c>
   4089 #include <isl_multi_insert_domain_templ.c>
   4090 #include <isl_multi_locals_templ.c>
   4091 #include <isl_multi_move_dims_templ.c>
   4092 #include <isl_multi_nan_templ.c>
   4093 #include <isl_multi_product_templ.c>
   4094 #include <isl_multi_splice_templ.c>
   4095 #include <isl_multi_tuple_id_templ.c>
   4096 #include <isl_multi_unbind_params_templ.c>
   4097 #include <isl_multi_zero_templ.c>
   4098 
   4099 #undef DOMBASE
   4100 #define DOMBASE set
   4101 #include <isl_multi_check_domain_templ.c>
   4102 #include <isl_multi_apply_set_no_explicit_domain_templ.c>
   4103 #include <isl_multi_gist.c>
   4104 
   4105 #undef DOMBASE
   4106 #define DOMBASE basic_set
   4107 #include <isl_multi_bind_templ.c>
   4108 
   4109 /* Construct an isl_multi_aff living in "space" that corresponds
   4110  * to the affine transformation matrix "mat".
   4111  */
   4112 __isl_give isl_multi_aff *isl_multi_aff_from_aff_mat(
   4113 	__isl_take isl_space *space, __isl_take isl_mat *mat)
   4114 {
   4115 	isl_ctx *ctx;
   4116 	isl_local_space *ls = NULL;
   4117 	isl_multi_aff *ma = NULL;
   4118 	isl_size n_row, n_col, n_out, total;
   4119 	int i;
   4120 
   4121 	if (!space || !mat)
   4122 		goto error;
   4123 
   4124 	ctx = isl_mat_get_ctx(mat);
   4125 
   4126 	n_row = isl_mat_rows(mat);
   4127 	n_col = isl_mat_cols(mat);
   4128 	n_out = isl_space_dim(space, isl_dim_out);
   4129 	total = isl_space_dim(space, isl_dim_all);
   4130 	if (n_row < 0 || n_col < 0 || n_out < 0 || total < 0)
   4131 		goto error;
   4132 	if (n_row < 1)
   4133 		isl_die(ctx, isl_error_invalid,
   4134 			"insufficient number of rows", goto error);
   4135 	if (n_col < 1)
   4136 		isl_die(ctx, isl_error_invalid,
   4137 			"insufficient number of columns", goto error);
   4138 	if (1 + n_out != n_row || 2 + total != n_row + n_col)
   4139 		isl_die(ctx, isl_error_invalid,
   4140 			"dimension mismatch", goto error);
   4141 
   4142 	ma = isl_multi_aff_zero(isl_space_copy(space));
   4143 	space = isl_space_domain(space);
   4144 	ls = isl_local_space_from_space(isl_space_copy(space));
   4145 
   4146 	for (i = 0; i < n_row - 1; ++i) {
   4147 		isl_vec *v;
   4148 		isl_aff *aff;
   4149 
   4150 		v = isl_vec_alloc(ctx, 1 + n_col);
   4151 		if (!v)
   4152 			goto error;
   4153 		isl_int_set(v->el[0], mat->row[0][0]);
   4154 		isl_seq_cpy(v->el + 1, mat->row[1 + i], n_col);
   4155 		v = isl_vec_normalize(v);
   4156 		aff = isl_aff_alloc_vec_validated(isl_local_space_copy(ls), v);
   4157 		ma = isl_multi_aff_set_aff(ma, i, aff);
   4158 	}
   4159 
   4160 	isl_space_free(space);
   4161 	isl_local_space_free(ls);
   4162 	isl_mat_free(mat);
   4163 	return ma;
   4164 error:
   4165 	isl_space_free(space);
   4166 	isl_local_space_free(ls);
   4167 	isl_mat_free(mat);
   4168 	isl_multi_aff_free(ma);
   4169 	return NULL;
   4170 }
   4171 
   4172 /* Return the constant terms of the affine expressions of "ma".
   4173  */
   4174 __isl_give isl_multi_val *isl_multi_aff_get_constant_multi_val(
   4175 	__isl_keep isl_multi_aff *ma)
   4176 {
   4177 	int i;
   4178 	isl_size n;
   4179 	isl_space *space;
   4180 	isl_multi_val *mv;
   4181 
   4182 	n = isl_multi_aff_size(ma);
   4183 	if (n < 0)
   4184 		return NULL;
   4185 	space = isl_space_range(isl_multi_aff_get_space(ma));
   4186 	space = isl_space_drop_all_params(space);
   4187 	mv = isl_multi_val_zero(space);
   4188 
   4189 	for (i = 0; i < n; ++i) {
   4190 		isl_aff *aff;
   4191 		isl_val *val;
   4192 
   4193 		aff = isl_multi_aff_get_at(ma, i);
   4194 		val = isl_aff_get_constant_val(aff);
   4195 		isl_aff_free(aff);
   4196 		mv = isl_multi_val_set_at(mv, i, val);
   4197 	}
   4198 
   4199 	return mv;
   4200 }
   4201 
   4202 /* Remove any internal structure of the domain of "ma".
   4203  * If there is any such internal structure in the input,
   4204  * then the name of the corresponding space is also removed.
   4205  */
   4206 __isl_give isl_multi_aff *isl_multi_aff_flatten_domain(
   4207 	__isl_take isl_multi_aff *ma)
   4208 {
   4209 	isl_space *space;
   4210 
   4211 	if (!ma)
   4212 		return NULL;
   4213 
   4214 	if (!ma->space->nested[0])
   4215 		return ma;
   4216 
   4217 	space = isl_multi_aff_get_space(ma);
   4218 	space = isl_space_flatten_domain(space);
   4219 	ma = isl_multi_aff_reset_space(ma, space);
   4220 
   4221 	return ma;
   4222 }
   4223 
   4224 /* Given a map space, return an isl_multi_aff that maps a wrapped copy
   4225  * of the space to its domain.
   4226  */
   4227 __isl_give isl_multi_aff *isl_multi_aff_domain_map(__isl_take isl_space *space)
   4228 {
   4229 	int i;
   4230 	isl_size n_in;
   4231 	isl_local_space *ls;
   4232 	isl_multi_aff *ma;
   4233 
   4234 	if (!space)
   4235 		return NULL;
   4236 	if (!isl_space_is_map(space))
   4237 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
   4238 			"not a map space", goto error);
   4239 
   4240 	n_in = isl_space_dim(space, isl_dim_in);
   4241 	if (n_in < 0)
   4242 		goto error;
   4243 	space = isl_space_domain_map(space);
   4244 
   4245 	ma = isl_multi_aff_alloc(isl_space_copy(space));
   4246 	if (n_in == 0) {
   4247 		isl_space_free(space);
   4248 		return ma;
   4249 	}
   4250 
   4251 	space = isl_space_domain(space);
   4252 	ls = isl_local_space_from_space(space);
   4253 	for (i = 0; i < n_in; ++i) {
   4254 		isl_aff *aff;
   4255 
   4256 		aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
   4257 						isl_dim_set, i);
   4258 		ma = isl_multi_aff_set_aff(ma, i, aff);
   4259 	}
   4260 	isl_local_space_free(ls);
   4261 	return ma;
   4262 error:
   4263 	isl_space_free(space);
   4264 	return NULL;
   4265 }
   4266 
   4267 /* This function performs the same operation as isl_multi_aff_domain_map,
   4268  * but is considered as a function on an isl_space when exported.
   4269  */
   4270 __isl_give isl_multi_aff *isl_space_domain_map_multi_aff(
   4271 	__isl_take isl_space *space)
   4272 {
   4273 	return isl_multi_aff_domain_map(space);
   4274 }
   4275 
   4276 /* Given a map space, return an isl_multi_aff that maps a wrapped copy
   4277  * of the space to its range.
   4278  */
   4279 __isl_give isl_multi_aff *isl_multi_aff_range_map(__isl_take isl_space *space)
   4280 {
   4281 	int i;
   4282 	isl_size n_in, n_out;
   4283 	isl_local_space *ls;
   4284 	isl_multi_aff *ma;
   4285 
   4286 	if (!space)
   4287 		return NULL;
   4288 	if (!isl_space_is_map(space))
   4289 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
   4290 			"not a map space", goto error);
   4291 
   4292 	n_in = isl_space_dim(space, isl_dim_in);
   4293 	n_out = isl_space_dim(space, isl_dim_out);
   4294 	if (n_in < 0 || n_out < 0)
   4295 		goto error;
   4296 	space = isl_space_range_map(space);
   4297 
   4298 	ma = isl_multi_aff_alloc(isl_space_copy(space));
   4299 	if (n_out == 0) {
   4300 		isl_space_free(space);
   4301 		return ma;
   4302 	}
   4303 
   4304 	space = isl_space_domain(space);
   4305 	ls = isl_local_space_from_space(space);
   4306 	for (i = 0; i < n_out; ++i) {
   4307 		isl_aff *aff;
   4308 
   4309 		aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
   4310 						isl_dim_set, n_in + i);
   4311 		ma = isl_multi_aff_set_aff(ma, i, aff);
   4312 	}
   4313 	isl_local_space_free(ls);
   4314 	return ma;
   4315 error:
   4316 	isl_space_free(space);
   4317 	return NULL;
   4318 }
   4319 
   4320 /* This function performs the same operation as isl_multi_aff_range_map,
   4321  * but is considered as a function on an isl_space when exported.
   4322  */
   4323 __isl_give isl_multi_aff *isl_space_range_map_multi_aff(
   4324 	__isl_take isl_space *space)
   4325 {
   4326 	return isl_multi_aff_range_map(space);
   4327 }
   4328 
   4329 /* Given a map space, return an isl_pw_multi_aff that maps a wrapped copy
   4330  * of the space to its domain.
   4331  */
   4332 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_domain_map(
   4333 	__isl_take isl_space *space)
   4334 {
   4335 	return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_domain_map(space));
   4336 }
   4337 
   4338 /* This function performs the same operation as isl_pw_multi_aff_domain_map,
   4339  * but is considered as a function on an isl_space when exported.
   4340  */
   4341 __isl_give isl_pw_multi_aff *isl_space_domain_map_pw_multi_aff(
   4342 	__isl_take isl_space *space)
   4343 {
   4344 	return isl_pw_multi_aff_domain_map(space);
   4345 }
   4346 
   4347 /* Given a map space, return an isl_pw_multi_aff that maps a wrapped copy
   4348  * of the space to its range.
   4349  */
   4350 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map(
   4351 	__isl_take isl_space *space)
   4352 {
   4353 	return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_range_map(space));
   4354 }
   4355 
   4356 /* This function performs the same operation as isl_pw_multi_aff_range_map,
   4357  * but is considered as a function on an isl_space when exported.
   4358  */
   4359 __isl_give isl_pw_multi_aff *isl_space_range_map_pw_multi_aff(
   4360 	__isl_take isl_space *space)
   4361 {
   4362 	return isl_pw_multi_aff_range_map(space);
   4363 }
   4364 
   4365 /* Given the space of a set and a range of set dimensions,
   4366  * construct an isl_multi_aff that projects out those dimensions.
   4367  */
   4368 __isl_give isl_multi_aff *isl_multi_aff_project_out_map(
   4369 	__isl_take isl_space *space, enum isl_dim_type type,
   4370 	unsigned first, unsigned n)
   4371 {
   4372 	int i;
   4373 	isl_size dim;
   4374 	isl_local_space *ls;
   4375 	isl_multi_aff *ma;
   4376 
   4377 	if (!space)
   4378 		return NULL;
   4379 	if (!isl_space_is_set(space))
   4380 		isl_die(isl_space_get_ctx(space), isl_error_unsupported,
   4381 			"expecting set space", goto error);
   4382 	if (type != isl_dim_set)
   4383 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
   4384 			"only set dimensions can be projected out", goto error);
   4385 	if (isl_space_check_range(space, type, first, n) < 0)
   4386 		goto error;
   4387 
   4388 	dim = isl_space_dim(space, isl_dim_set);
   4389 	if (dim < 0)
   4390 		goto error;
   4391 
   4392 	space = isl_space_from_domain(space);
   4393 	space = isl_space_add_dims(space, isl_dim_out, dim - n);
   4394 
   4395 	if (dim == n)
   4396 		return isl_multi_aff_alloc(space);
   4397 
   4398 	ma = isl_multi_aff_alloc(isl_space_copy(space));
   4399 	space = isl_space_domain(space);
   4400 	ls = isl_local_space_from_space(space);
   4401 
   4402 	for (i = 0; i < first; ++i) {
   4403 		isl_aff *aff;
   4404 
   4405 		aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
   4406 						isl_dim_set, i);
   4407 		ma = isl_multi_aff_set_aff(ma, i, aff);
   4408 	}
   4409 
   4410 	for (i = 0; i < dim - (first + n); ++i) {
   4411 		isl_aff *aff;
   4412 
   4413 		aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
   4414 						isl_dim_set, first + n + i);
   4415 		ma = isl_multi_aff_set_aff(ma, first + i, aff);
   4416 	}
   4417 
   4418 	isl_local_space_free(ls);
   4419 	return ma;
   4420 error:
   4421 	isl_space_free(space);
   4422 	return NULL;
   4423 }
   4424 
   4425 /* Given the space of a set and a range of set dimensions,
   4426  * construct an isl_pw_multi_aff that projects out those dimensions.
   4427  */
   4428 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_out_map(
   4429 	__isl_take isl_space *space, enum isl_dim_type type,
   4430 	unsigned first, unsigned n)
   4431 {
   4432 	isl_multi_aff *ma;
   4433 
   4434 	ma = isl_multi_aff_project_out_map(space, type, first, n);
   4435 	return isl_pw_multi_aff_from_multi_aff(ma);
   4436 }
   4437 
   4438 /* This function performs the same operation as isl_pw_multi_aff_from_multi_aff,
   4439  * but is considered as a function on an isl_multi_aff when exported.
   4440  */
   4441 __isl_give isl_pw_multi_aff *isl_multi_aff_to_pw_multi_aff(
   4442 	__isl_take isl_multi_aff *ma)
   4443 {
   4444 	return isl_pw_multi_aff_from_multi_aff(ma);
   4445 }
   4446 
   4447 /* Create a piecewise multi-affine expression in the given space that maps each
   4448  * input dimension to the corresponding output dimension.
   4449  */
   4450 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity(
   4451 	__isl_take isl_space *space)
   4452 {
   4453 	return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_identity(space));
   4454 }
   4455 
   4456 /* Create a piecewise multi expression that maps elements in the given space
   4457  * to themselves.
   4458  */
   4459 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity_on_domain_space(
   4460 	__isl_take isl_space *space)
   4461 {
   4462 	isl_multi_aff *ma;
   4463 
   4464 	ma = isl_multi_aff_identity_on_domain_space(space);
   4465 	return isl_pw_multi_aff_from_multi_aff(ma);
   4466 }
   4467 
   4468 /* This function performs the same operation as
   4469  * isl_pw_multi_aff_identity_on_domain_space,
   4470  * but is considered as a function on an isl_space when exported.
   4471  */
   4472 __isl_give isl_pw_multi_aff *isl_space_identity_pw_multi_aff_on_domain(
   4473 	__isl_take isl_space *space)
   4474 {
   4475 	return isl_pw_multi_aff_identity_on_domain_space(space);
   4476 }
   4477 
   4478 /* Exploit the equalities in "eq" to simplify the affine expressions.
   4479  */
   4480 static __isl_give isl_multi_aff *isl_multi_aff_substitute_equalities(
   4481 	__isl_take isl_multi_aff *maff, __isl_take isl_basic_set *eq)
   4482 {
   4483 	isl_size n;
   4484 	int i;
   4485 
   4486 	n = isl_multi_aff_size(maff);
   4487 	if (n < 0 || !eq)
   4488 		goto error;
   4489 
   4490 	for (i = 0; i < n; ++i) {
   4491 		isl_aff *aff;
   4492 
   4493 		aff = isl_multi_aff_take_at(maff, i);
   4494 		aff = isl_aff_substitute_equalities(aff,
   4495 						    isl_basic_set_copy(eq));
   4496 		maff = isl_multi_aff_restore_at(maff, i, aff);
   4497 	}
   4498 
   4499 	isl_basic_set_free(eq);
   4500 	return maff;
   4501 error:
   4502 	isl_basic_set_free(eq);
   4503 	isl_multi_aff_free(maff);
   4504 	return NULL;
   4505 }
   4506 
   4507 __isl_give isl_multi_aff *isl_multi_aff_scale(__isl_take isl_multi_aff *maff,
   4508 	isl_int f)
   4509 {
   4510 	isl_size n;
   4511 	int i;
   4512 
   4513 	n = isl_multi_aff_size(maff);
   4514 	if (n < 0)
   4515 		return isl_multi_aff_free(maff);
   4516 
   4517 	for (i = 0; i < n; ++i) {
   4518 		isl_aff *aff;
   4519 
   4520 		aff = isl_multi_aff_take_at(maff, i);
   4521 		aff = isl_aff_scale(aff, f);
   4522 		maff = isl_multi_aff_restore_at(maff, i, aff);
   4523 	}
   4524 
   4525 	return maff;
   4526 }
   4527 
   4528 __isl_give isl_multi_aff *isl_multi_aff_add_on_domain(__isl_keep isl_set *dom,
   4529 	__isl_take isl_multi_aff *maff1, __isl_take isl_multi_aff *maff2)
   4530 {
   4531 	maff1 = isl_multi_aff_add(maff1, maff2);
   4532 	maff1 = isl_multi_aff_gist(maff1, isl_set_copy(dom));
   4533 	return maff1;
   4534 }
   4535 
   4536 isl_bool isl_multi_aff_is_empty(__isl_keep isl_multi_aff *maff)
   4537 {
   4538 	if (!maff)
   4539 		return isl_bool_error;
   4540 
   4541 	return isl_bool_false;
   4542 }
   4543 
   4544 /* Return the set of domain elements where "ma1" is lexicographically
   4545  * smaller than or equal to "ma2".
   4546  */
   4547 __isl_give isl_set *isl_multi_aff_lex_le_set(__isl_take isl_multi_aff *ma1,
   4548 	__isl_take isl_multi_aff *ma2)
   4549 {
   4550 	return isl_multi_aff_lex_ge_set(ma2, ma1);
   4551 }
   4552 
   4553 /* Return the set of domain elements where "ma1" is lexicographically
   4554  * smaller than "ma2".
   4555  */
   4556 __isl_give isl_set *isl_multi_aff_lex_lt_set(__isl_take isl_multi_aff *ma1,
   4557 	__isl_take isl_multi_aff *ma2)
   4558 {
   4559 	return isl_multi_aff_lex_gt_set(ma2, ma1);
   4560 }
   4561 
   4562 /* Return the set of domain elements where "ma1" is lexicographically
   4563  * greater than to "ma2".  If "equal" is set, then include the domain
   4564  * elements where they are equal.
   4565  * Do this for the case where there are no entries.
   4566  * In this case, "ma1" cannot be greater than "ma2",
   4567  * but it is (greater than or) equal to "ma2".
   4568  */
   4569 static __isl_give isl_set *isl_multi_aff_lex_gte_set_0d(
   4570 	__isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2, int equal)
   4571 {
   4572 	isl_space *space;
   4573 
   4574 	space = isl_multi_aff_get_domain_space(ma1);
   4575 
   4576 	isl_multi_aff_free(ma1);
   4577 	isl_multi_aff_free(ma2);
   4578 
   4579 	if (equal)
   4580 		return isl_set_universe(space);
   4581 	else
   4582 		return isl_set_empty(space);
   4583 }
   4584 
   4585 /* Return the set where entry "i" of "ma1" and "ma2"
   4586  * satisfy the relation prescribed by "cmp".
   4587  */
   4588 static __isl_give isl_set *isl_multi_aff_order_at(__isl_keep isl_multi_aff *ma1,
   4589 	__isl_keep isl_multi_aff *ma2, int i,
   4590 	__isl_give isl_set *(*cmp)(__isl_take isl_aff *aff1,
   4591 		__isl_take isl_aff *aff2))
   4592 {
   4593 	isl_aff *aff1, *aff2;
   4594 
   4595 	aff1 = isl_multi_aff_get_at(ma1, i);
   4596 	aff2 = isl_multi_aff_get_at(ma2, i);
   4597 	return cmp(aff1, aff2);
   4598 }
   4599 
   4600 /* Return the set of domain elements where "ma1" is lexicographically
   4601  * greater than to "ma2".  If "equal" is set, then include the domain
   4602  * elements where they are equal.
   4603  *
   4604  * In particular, for all but the final entry,
   4605  * include the set of elements where this entry is strictly greater in "ma1"
   4606  * and all previous entries are equal.
   4607  * The final entry is also allowed to be equal in the two functions
   4608  * if "equal" is set.
   4609  *
   4610  * The case where there are no entries is handled separately.
   4611  */
   4612 static __isl_give isl_set *isl_multi_aff_lex_gte_set(
   4613 	__isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2, int equal)
   4614 {
   4615 	int i;
   4616 	isl_size n;
   4617 	isl_space *space;
   4618 	isl_set *res;
   4619 	isl_set *equal_set;
   4620 	isl_set *gte;
   4621 
   4622 	if (isl_multi_aff_check_equal_space(ma1, ma2) < 0)
   4623 		goto error;
   4624 	n = isl_multi_aff_size(ma1);
   4625 	if (n < 0)
   4626 		goto error;
   4627 	if (n == 0)
   4628 		return isl_multi_aff_lex_gte_set_0d(ma1, ma2, equal);
   4629 
   4630 	space = isl_multi_aff_get_domain_space(ma1);
   4631 	res = isl_set_empty(isl_space_copy(space));
   4632 	equal_set = isl_set_universe(space);
   4633 
   4634 	for (i = 0; i + 1 < n; ++i) {
   4635 		isl_bool empty;
   4636 		isl_set *gt, *eq;
   4637 
   4638 		gt = isl_multi_aff_order_at(ma1, ma2, i, &isl_aff_gt_set);
   4639 		gt = isl_set_intersect(gt, isl_set_copy(equal_set));
   4640 		res = isl_set_union(res, gt);
   4641 		eq = isl_multi_aff_order_at(ma1, ma2, i, &isl_aff_eq_set);
   4642 		equal_set = isl_set_intersect(equal_set, eq);
   4643 
   4644 		empty = isl_set_is_empty(equal_set);
   4645 		if (empty >= 0 && empty)
   4646 			break;
   4647 	}
   4648 
   4649 	if (equal)
   4650 		gte = isl_multi_aff_order_at(ma1, ma2, n - 1, &isl_aff_ge_set);
   4651 	else
   4652 		gte = isl_multi_aff_order_at(ma1, ma2, n - 1, &isl_aff_gt_set);
   4653 	isl_multi_aff_free(ma1);
   4654 	isl_multi_aff_free(ma2);
   4655 
   4656 	gte = isl_set_intersect(gte, equal_set);
   4657 	return isl_set_union(res, gte);
   4658 error:
   4659 	isl_multi_aff_free(ma1);
   4660 	isl_multi_aff_free(ma2);
   4661 	return NULL;
   4662 }
   4663 
   4664 /* Return the set of domain elements where "ma1" is lexicographically
   4665  * greater than or equal to "ma2".
   4666  */
   4667 __isl_give isl_set *isl_multi_aff_lex_ge_set(__isl_take isl_multi_aff *ma1,
   4668 	__isl_take isl_multi_aff *ma2)
   4669 {
   4670 	return isl_multi_aff_lex_gte_set(ma1, ma2, 1);
   4671 }
   4672 
   4673 /* Return the set of domain elements where "ma1" is lexicographically
   4674  * greater than "ma2".
   4675  */
   4676 __isl_give isl_set *isl_multi_aff_lex_gt_set(__isl_take isl_multi_aff *ma1,
   4677 	__isl_take isl_multi_aff *ma2)
   4678 {
   4679 	return isl_multi_aff_lex_gte_set(ma1, ma2, 0);
   4680 }
   4681 
   4682 #define isl_multi_aff_zero_in_space	isl_multi_aff_zero
   4683 
   4684 #undef PW
   4685 #define PW isl_pw_multi_aff
   4686 #undef BASE
   4687 #define BASE multi_aff
   4688 #undef EL_IS_ZERO
   4689 #define EL_IS_ZERO is_empty
   4690 #undef ZERO
   4691 #define ZERO empty
   4692 #undef IS_ZERO
   4693 #define IS_ZERO is_empty
   4694 #undef FIELD
   4695 #define FIELD maff
   4696 #undef DEFAULT_IS_ZERO
   4697 #define DEFAULT_IS_ZERO 0
   4698 
   4699 #include <isl_pw_templ.c>
   4700 #include <isl_pw_un_op_templ.c>
   4701 #include <isl_pw_add_constant_multi_val_templ.c>
   4702 #include <isl_pw_add_constant_val_templ.c>
   4703 #include <isl_pw_add_disjoint_templ.c>
   4704 #include <isl_pw_bind_domain_templ.c>
   4705 #include <isl_pw_domain_reverse_templ.c>
   4706 #include <isl_pw_fix_templ.c>
   4707 #include <isl_pw_from_range_templ.c>
   4708 #include <isl_pw_insert_dims_templ.c>
   4709 #include <isl_pw_insert_domain_templ.c>
   4710 #include <isl_pw_locals_templ.c>
   4711 #include <isl_pw_move_dims_templ.c>
   4712 #include <isl_pw_neg_templ.c>
   4713 #include <isl_pw_pullback_templ.c>
   4714 #include <isl_pw_range_tuple_id_templ.c>
   4715 #include <isl_pw_union_opt.c>
   4716 
   4717 #undef BASE
   4718 #define BASE pw_multi_aff
   4719 
   4720 #include <isl_union_multi.c>
   4721 #include "isl_union_locals_templ.c"
   4722 #include <isl_union_neg.c>
   4723 #include <isl_union_sub_templ.c>
   4724 
   4725 #undef BASE
   4726 #define BASE multi_aff
   4727 
   4728 #include <isl_union_pw_templ.c>
   4729 
   4730 /* Generic function for extracting a factor from a product "pma".
   4731  * "check_space" checks that the space is that of the right kind of product.
   4732  * "space_factor" extracts the factor from the space.
   4733  * "multi_aff_factor" extracts the factor from the constituent functions.
   4734  */
   4735 static __isl_give isl_pw_multi_aff *pw_multi_aff_factor(
   4736 	__isl_take isl_pw_multi_aff *pma,
   4737 	isl_stat (*check_space)(__isl_keep isl_pw_multi_aff *pma),
   4738 	__isl_give isl_space *(*space_factor)(__isl_take isl_space *space),
   4739 	__isl_give isl_multi_aff *(*multi_aff_factor)(
   4740 		__isl_take isl_multi_aff *ma))
   4741 {
   4742 	int i;
   4743 	isl_space *space;
   4744 
   4745 	if (check_space(pma) < 0)
   4746 		return isl_pw_multi_aff_free(pma);
   4747 
   4748 	space = isl_pw_multi_aff_take_space(pma);
   4749 	space = space_factor(space);
   4750 
   4751 	for (i = 0; pma && i < pma->n; ++i) {
   4752 		isl_multi_aff *ma;
   4753 
   4754 		ma = isl_pw_multi_aff_take_base_at(pma, i);
   4755 		ma = multi_aff_factor(ma);
   4756 		pma = isl_pw_multi_aff_restore_base_at(pma, i, ma);
   4757 	}
   4758 
   4759 	pma = isl_pw_multi_aff_restore_space(pma, space);
   4760 
   4761 	return pma;
   4762 }
   4763 
   4764 /* Is the range of "pma" a wrapped relation?
   4765  */
   4766 static isl_bool isl_pw_multi_aff_range_is_wrapping(
   4767 	__isl_keep isl_pw_multi_aff *pma)
   4768 {
   4769 	return isl_space_range_is_wrapping(isl_pw_multi_aff_peek_space(pma));
   4770 }
   4771 
   4772 /* Check that the range of "pma" is a product.
   4773  */
   4774 static isl_stat pw_multi_aff_check_range_product(
   4775 	__isl_keep isl_pw_multi_aff *pma)
   4776 {
   4777 	isl_bool wraps;
   4778 
   4779 	wraps = isl_pw_multi_aff_range_is_wrapping(pma);
   4780 	if (wraps < 0)
   4781 		return isl_stat_error;
   4782 	if (!wraps)
   4783 		isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
   4784 			"range is not a product", return isl_stat_error);
   4785 	return isl_stat_ok;
   4786 }
   4787 
   4788 /* Given a function A -> [B -> C], extract the function A -> B.
   4789  */
   4790 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_factor_domain(
   4791 	__isl_take isl_pw_multi_aff *pma)
   4792 {
   4793 	return pw_multi_aff_factor(pma, &pw_multi_aff_check_range_product,
   4794 				&isl_space_range_factor_domain,
   4795 				&isl_multi_aff_range_factor_domain);
   4796 }
   4797 
   4798 /* Given a function A -> [B -> C], extract the function A -> C.
   4799  */
   4800 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_factor_range(
   4801 	__isl_take isl_pw_multi_aff *pma)
   4802 {
   4803 	return pw_multi_aff_factor(pma, &pw_multi_aff_check_range_product,
   4804 				&isl_space_range_factor_range,
   4805 				&isl_multi_aff_range_factor_range);
   4806 }
   4807 
   4808 /* Given two piecewise multi affine expressions, return a piecewise
   4809  * multi-affine expression defined on the union of the definition domains
   4810  * of the inputs that is equal to the lexicographic maximum of the two
   4811  * inputs on each cell.  If only one of the two inputs is defined on
   4812  * a given cell, then it is considered to be the maximum.
   4813  */
   4814 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmax(
   4815 	__isl_take isl_pw_multi_aff *pma1,
   4816 	__isl_take isl_pw_multi_aff *pma2)
   4817 {
   4818 	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
   4819 	return isl_pw_multi_aff_union_opt_cmp(pma1, pma2,
   4820 					    &isl_multi_aff_lex_ge_set);
   4821 }
   4822 
   4823 /* Given two piecewise multi affine expressions, return a piecewise
   4824  * multi-affine expression defined on the union of the definition domains
   4825  * of the inputs that is equal to the lexicographic minimum of the two
   4826  * inputs on each cell.  If only one of the two inputs is defined on
   4827  * a given cell, then it is considered to be the minimum.
   4828  */
   4829 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmin(
   4830 	__isl_take isl_pw_multi_aff *pma1,
   4831 	__isl_take isl_pw_multi_aff *pma2)
   4832 {
   4833 	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
   4834 	return isl_pw_multi_aff_union_opt_cmp(pma1, pma2,
   4835 					    &isl_multi_aff_lex_le_set);
   4836 }
   4837 
   4838 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_add(
   4839 	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
   4840 {
   4841 	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
   4842 	return isl_pw_multi_aff_on_shared_domain(pma1, pma2,
   4843 						&isl_multi_aff_add);
   4844 }
   4845 
   4846 /* Subtract "pma2" from "pma1" and return the result.
   4847  */
   4848 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_sub(
   4849 	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
   4850 {
   4851 	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
   4852 	return isl_pw_multi_aff_on_shared_domain(pma1, pma2,
   4853 						&isl_multi_aff_sub);
   4854 }
   4855 
   4856 /* Given two piecewise multi-affine expressions A -> B and C -> D,
   4857  * construct a piecewise multi-affine expression [A -> C] -> [B -> D].
   4858  */
   4859 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_product(
   4860 	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
   4861 {
   4862 	int i, j, n;
   4863 	isl_space *space;
   4864 	isl_pw_multi_aff *res;
   4865 
   4866 	if (isl_pw_multi_aff_align_params_bin(&pma1, &pma2) < 0)
   4867 		goto error;
   4868 
   4869 	n = pma1->n * pma2->n;
   4870 	space = isl_space_product(isl_space_copy(pma1->dim),
   4871 				  isl_space_copy(pma2->dim));
   4872 	res = isl_pw_multi_aff_alloc_size(space, n);
   4873 
   4874 	for (i = 0; i < pma1->n; ++i) {
   4875 		for (j = 0; j < pma2->n; ++j) {
   4876 			isl_set *domain;
   4877 			isl_multi_aff *ma;
   4878 
   4879 			domain = isl_set_product(isl_set_copy(pma1->p[i].set),
   4880 						 isl_set_copy(pma2->p[j].set));
   4881 			ma = isl_multi_aff_product(
   4882 					isl_multi_aff_copy(pma1->p[i].maff),
   4883 					isl_multi_aff_copy(pma2->p[j].maff));
   4884 			res = isl_pw_multi_aff_add_piece(res, domain, ma);
   4885 		}
   4886 	}
   4887 
   4888 	isl_pw_multi_aff_free(pma1);
   4889 	isl_pw_multi_aff_free(pma2);
   4890 	return res;
   4891 error:
   4892 	isl_pw_multi_aff_free(pma1);
   4893 	isl_pw_multi_aff_free(pma2);
   4894 	return NULL;
   4895 }
   4896 
   4897 /* Subtract the initial "n" elements in "ma" with coefficients in "c" and
   4898  * denominator "denom".
   4899  * "denom" is allowed to be negative, in which case the actual denominator
   4900  * is -denom and the expressions are added instead.
   4901  */
   4902 static __isl_give isl_aff *subtract_initial(__isl_take isl_aff *aff,
   4903 	__isl_keep isl_multi_aff *ma, int n, isl_int *c, isl_int denom)
   4904 {
   4905 	int i, first;
   4906 	int sign;
   4907 	isl_int d;
   4908 
   4909 	first = isl_seq_first_non_zero(c, n);
   4910 	if (first == -1)
   4911 		return aff;
   4912 
   4913 	sign = isl_int_sgn(denom);
   4914 	isl_int_init(d);
   4915 	isl_int_abs(d, denom);
   4916 	for (i = first; i < n; ++i) {
   4917 		isl_aff *aff_i;
   4918 
   4919 		if (isl_int_is_zero(c[i]))
   4920 			continue;
   4921 		aff_i = isl_multi_aff_get_aff(ma, i);
   4922 		aff_i = isl_aff_scale(aff_i, c[i]);
   4923 		aff_i = isl_aff_scale_down(aff_i, d);
   4924 		if (sign >= 0)
   4925 			aff = isl_aff_sub(aff, aff_i);
   4926 		else
   4927 			aff = isl_aff_add(aff, aff_i);
   4928 	}
   4929 	isl_int_clear(d);
   4930 
   4931 	return aff;
   4932 }
   4933 
   4934 /* Extract an affine expression that expresses the output dimension "pos"
   4935  * of "bmap" in terms of the parameters and input dimensions from
   4936  * equality "eq".
   4937  * Note that this expression may involve integer divisions defined
   4938  * in terms of parameters and input dimensions.
   4939  * The equality may also involve references to earlier (but not later)
   4940  * output dimensions.  These are replaced by the corresponding elements
   4941  * in "ma".
   4942  *
   4943  * If the equality is of the form
   4944  *
   4945  *	f(i) + h(j) + a x + g(i) = 0,
   4946  *
   4947  * with f(i) a linear combinations of the parameters and input dimensions,
   4948  * g(i) a linear combination of integer divisions defined in terms of the same
   4949  * and h(j) a linear combinations of earlier output dimensions,
   4950  * then the affine expression is
   4951  *
   4952  *	(-f(i) - g(i))/a - h(j)/a
   4953  *
   4954  * If the equality is of the form
   4955  *
   4956  *	f(i) + h(j) - a x + g(i) = 0,
   4957  *
   4958  * then the affine expression is
   4959  *
   4960  *	(f(i) + g(i))/a - h(j)/(-a)
   4961  *
   4962  *
   4963  * If "div" refers to an integer division (i.e., it is smaller than
   4964  * the number of integer divisions), then the equality constraint
   4965  * does involve an integer division (the one at position "div") that
   4966  * is defined in terms of output dimensions.  However, this integer
   4967  * division can be eliminated by exploiting a pair of constraints
   4968  * x >= l and x <= l + n, with n smaller than the coefficient of "div"
   4969  * in the equality constraint.  "ineq" refers to inequality x >= l, i.e.,
   4970  * -l + x >= 0.
   4971  * In particular, let
   4972  *
   4973  *	x = e(i) + m floor(...)
   4974  *
   4975  * with e(i) the expression derived above and floor(...) the integer
   4976  * division involving output dimensions.
   4977  * From
   4978  *
   4979  *	l <= x <= l + n,
   4980  *
   4981  * we have
   4982  *
   4983  *	0 <= x - l <= n
   4984  *
   4985  * This means
   4986  *
   4987  *	e(i) + m floor(...) - l = (e(i) + m floor(...) - l) mod m
   4988  *	                        = (e(i) - l) mod m
   4989  *
   4990  * Therefore,
   4991  *
   4992  *	x - l = (e(i) - l) mod m
   4993  *
   4994  * or
   4995  *
   4996  *	x = ((e(i) - l) mod m) + l
   4997  *
   4998  * The variable "shift" below contains the expression -l, which may
   4999  * also involve a linear combination of earlier output dimensions.
   5000  */
   5001 static __isl_give isl_aff *extract_aff_from_equality(
   5002 	__isl_keep isl_basic_map *bmap, int pos, int eq, int div, int ineq,
   5003 	__isl_keep isl_multi_aff *ma)
   5004 {
   5005 	unsigned o_out;
   5006 	isl_size n_div, n_out;
   5007 	isl_ctx *ctx;
   5008 	isl_local_space *ls;
   5009 	isl_aff *aff, *shift;
   5010 	isl_val *mod;
   5011 
   5012 	ctx = isl_basic_map_get_ctx(bmap);
   5013 	ls = isl_basic_map_get_local_space(bmap);
   5014 	ls = isl_local_space_domain(ls);
   5015 	aff = isl_aff_alloc(isl_local_space_copy(ls));
   5016 	if (!aff)
   5017 		goto error;
   5018 	o_out = isl_basic_map_offset(bmap, isl_dim_out);
   5019 	n_out = isl_basic_map_dim(bmap, isl_dim_out);
   5020 	n_div = isl_basic_map_dim(bmap, isl_dim_div);
   5021 	if (n_out < 0 || n_div < 0)
   5022 		goto error;
   5023 	if (isl_int_is_neg(bmap->eq[eq][o_out + pos])) {
   5024 		isl_seq_cpy(aff->v->el + 1, bmap->eq[eq], o_out);
   5025 		isl_seq_cpy(aff->v->el + 1 + o_out,
   5026 			    bmap->eq[eq] + o_out + n_out, n_div);
   5027 	} else {
   5028 		isl_seq_neg(aff->v->el + 1, bmap->eq[eq], o_out);
   5029 		isl_seq_neg(aff->v->el + 1 + o_out,
   5030 			    bmap->eq[eq] + o_out + n_out, n_div);
   5031 	}
   5032 	if (div < n_div)
   5033 		isl_int_set_si(aff->v->el[1 + o_out + div], 0);
   5034 	isl_int_abs(aff->v->el[0], bmap->eq[eq][o_out + pos]);
   5035 	aff = subtract_initial(aff, ma, pos, bmap->eq[eq] + o_out,
   5036 			    bmap->eq[eq][o_out + pos]);
   5037 	if (div < n_div) {
   5038 		shift = isl_aff_alloc(isl_local_space_copy(ls));
   5039 		if (!shift)
   5040 			goto error;
   5041 		isl_seq_cpy(shift->v->el + 1, bmap->ineq[ineq], o_out);
   5042 		isl_seq_cpy(shift->v->el + 1 + o_out,
   5043 			    bmap->ineq[ineq] + o_out + n_out, n_div);
   5044 		isl_int_set_si(shift->v->el[0], 1);
   5045 		shift = subtract_initial(shift, ma, pos,
   5046 					bmap->ineq[ineq] + o_out, ctx->negone);
   5047 		aff = isl_aff_add(aff, isl_aff_copy(shift));
   5048 		mod = isl_val_int_from_isl_int(ctx,
   5049 					    bmap->eq[eq][o_out + n_out + div]);
   5050 		mod = isl_val_abs(mod);
   5051 		aff = isl_aff_mod_val(aff, mod);
   5052 		aff = isl_aff_sub(aff, shift);
   5053 	}
   5054 
   5055 	isl_local_space_free(ls);
   5056 	return aff;
   5057 error:
   5058 	isl_local_space_free(ls);
   5059 	isl_aff_free(aff);
   5060 	return NULL;
   5061 }
   5062 
   5063 /* Given a basic map with output dimensions defined
   5064  * in terms of the parameters input dimensions and earlier
   5065  * output dimensions using an equality (and possibly a pair on inequalities),
   5066  * extract an isl_aff that expresses output dimension "pos" in terms
   5067  * of the parameters and input dimensions.
   5068  * Note that this expression may involve integer divisions defined
   5069  * in terms of parameters and input dimensions.
   5070  * "ma" contains the expressions corresponding to earlier output dimensions.
   5071  *
   5072  * This function shares some similarities with
   5073  * isl_basic_map_has_defining_equality and isl_constraint_get_bound.
   5074  */
   5075 static __isl_give isl_aff *extract_isl_aff_from_basic_map(
   5076 	__isl_keep isl_basic_map *bmap, int pos, __isl_keep isl_multi_aff *ma)
   5077 {
   5078 	int eq, div, ineq;
   5079 	isl_aff *aff;
   5080 
   5081 	if (!bmap)
   5082 		return NULL;
   5083 	eq = isl_basic_map_output_defining_equality(bmap, pos, &div, &ineq);
   5084 	if (eq >= bmap->n_eq)
   5085 		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
   5086 			"unable to find suitable equality", return NULL);
   5087 	aff = extract_aff_from_equality(bmap, pos, eq, div, ineq, ma);
   5088 
   5089 	aff = isl_aff_remove_unused_divs(aff);
   5090 	return aff;
   5091 }
   5092 
   5093 /* Given a basic map where each output dimension is defined
   5094  * in terms of the parameters and input dimensions using an equality,
   5095  * extract an isl_multi_aff that expresses the output dimensions in terms
   5096  * of the parameters and input dimensions.
   5097  */
   5098 static __isl_give isl_multi_aff *extract_isl_multi_aff_from_basic_map(
   5099 	__isl_take isl_basic_map *bmap)
   5100 {
   5101 	int i;
   5102 	isl_size n_out;
   5103 	isl_multi_aff *ma;
   5104 
   5105 	if (!bmap)
   5106 		return NULL;
   5107 
   5108 	ma = isl_multi_aff_alloc(isl_basic_map_get_space(bmap));
   5109 	n_out = isl_basic_map_dim(bmap, isl_dim_out);
   5110 	if (n_out < 0)
   5111 		ma = isl_multi_aff_free(ma);
   5112 
   5113 	for (i = 0; i < n_out; ++i) {
   5114 		isl_aff *aff;
   5115 
   5116 		aff = extract_isl_aff_from_basic_map(bmap, i, ma);
   5117 		ma = isl_multi_aff_set_aff(ma, i, aff);
   5118 	}
   5119 
   5120 	isl_basic_map_free(bmap);
   5121 
   5122 	return ma;
   5123 }
   5124 
   5125 /* Given a basic set where each set dimension is defined
   5126  * in terms of the parameters using an equality,
   5127  * extract an isl_multi_aff that expresses the set dimensions in terms
   5128  * of the parameters.
   5129  */
   5130 __isl_give isl_multi_aff *isl_multi_aff_from_basic_set_equalities(
   5131 	__isl_take isl_basic_set *bset)
   5132 {
   5133 	return extract_isl_multi_aff_from_basic_map(bset);
   5134 }
   5135 
   5136 /* Create an isl_pw_multi_aff that is equivalent to
   5137  * isl_map_intersect_domain(isl_map_from_basic_map(bmap), domain).
   5138  * The given basic map is such that each output dimension is defined
   5139  * in terms of the parameters and input dimensions using an equality.
   5140  *
   5141  * Since some applications expect the result of isl_pw_multi_aff_from_map
   5142  * to only contain integer affine expressions, we compute the floor
   5143  * of the expression before returning.
   5144  *
   5145  * Remove all constraints involving local variables without
   5146  * an explicit representation (resulting in the removal of those
   5147  * local variables) prior to the actual extraction to ensure
   5148  * that the local spaces in which the resulting affine expressions
   5149  * are created do not contain any unknown local variables.
   5150  * Removing such constraints is safe because constraints involving
   5151  * unknown local variables are not used to determine whether
   5152  * a basic map is obviously single-valued.
   5153  */
   5154 static __isl_give isl_pw_multi_aff *plain_pw_multi_aff_from_map(
   5155 	__isl_take isl_set *domain, __isl_take isl_basic_map *bmap)
   5156 {
   5157 	isl_multi_aff *ma;
   5158 
   5159 	bmap = isl_basic_map_drop_constraints_involving_unknown_divs(bmap);
   5160 	ma = extract_isl_multi_aff_from_basic_map(bmap);
   5161 	ma = isl_multi_aff_floor(ma);
   5162 	return isl_pw_multi_aff_alloc(domain, ma);
   5163 }
   5164 
   5165 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
   5166  * This obviously only works if the input "map" is single-valued.
   5167  * If so, we compute the lexicographic minimum of the image in the form
   5168  * of an isl_pw_multi_aff.  Since the image is unique, it is equal
   5169  * to its lexicographic minimum.
   5170  * If the input is not single-valued, we produce an error.
   5171  */
   5172 static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_base(
   5173 	__isl_take isl_map *map)
   5174 {
   5175 	int i;
   5176 	int sv;
   5177 	isl_pw_multi_aff *pma;
   5178 
   5179 	sv = isl_map_is_single_valued(map);
   5180 	if (sv < 0)
   5181 		goto error;
   5182 	if (!sv)
   5183 		isl_die(isl_map_get_ctx(map), isl_error_invalid,
   5184 			"map is not single-valued", goto error);
   5185 	map = isl_map_make_disjoint(map);
   5186 	if (!map)
   5187 		return NULL;
   5188 
   5189 	pma = isl_pw_multi_aff_empty(isl_map_get_space(map));
   5190 
   5191 	for (i = 0; i < map->n; ++i) {
   5192 		isl_pw_multi_aff *pma_i;
   5193 		isl_basic_map *bmap;
   5194 		bmap = isl_basic_map_copy(map->p[i]);
   5195 		pma_i = isl_basic_map_lexmin_pw_multi_aff(bmap);
   5196 		pma = isl_pw_multi_aff_add_disjoint(pma, pma_i);
   5197 	}
   5198 
   5199 	isl_map_free(map);
   5200 	return pma;
   5201 error:
   5202 	isl_map_free(map);
   5203 	return NULL;
   5204 }
   5205 
   5206 /* Construct an isl_aff from the given domain local space "ls" and
   5207  * coefficients "v", where the local space may involve
   5208  * local variables without a known expression, as long as these
   5209  * do not have a non-zero coefficient in "v".
   5210  * These need to be pruned away first since an isl_aff cannot
   5211  * reference any local variables without a known expression.
   5212  * For simplicity, remove all local variables that have a zero coefficient and
   5213  * that are not used in other local variables with a non-zero coefficient.
   5214  */
   5215 static __isl_give isl_aff *isl_aff_alloc_vec_prune(
   5216 	__isl_take isl_local_space *ls, __isl_take isl_vec *v)
   5217 {
   5218 	int i;
   5219 	isl_size n_div, v_div;
   5220 
   5221 	n_div = isl_local_space_dim(ls, isl_dim_div);
   5222 	v_div = isl_local_space_var_offset(ls, isl_dim_div);
   5223 	if (n_div < 0 || v_div < 0 || !v)
   5224 		goto error;
   5225 	for (i = n_div - 1; i >= 0; --i) {
   5226 		isl_bool involves;
   5227 
   5228 		if (!isl_int_is_zero(v->el[1 + 1 + v_div + i]))
   5229 			continue;
   5230 		involves = isl_local_space_involves_dims(ls, isl_dim_div, i, 1);
   5231 		if (involves < 0)
   5232 			goto error;
   5233 		if (involves)
   5234 			continue;
   5235 		ls = isl_local_space_drop_dims(ls, isl_dim_div, i, 1);
   5236 		v = isl_vec_drop_els(v, 1 + 1 + v_div + i, 1);
   5237 		if (!v)
   5238 			goto error;
   5239 	}
   5240 
   5241 	return isl_aff_alloc_vec(ls, v);
   5242 error:
   5243 	isl_local_space_free(ls);
   5244 	isl_vec_free(v);
   5245 	return NULL;
   5246 }
   5247 
   5248 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map,
   5249  * taking into account that the output dimension at position "d"
   5250  * can be represented as
   5251  *
   5252  *	x = floor((e(...) + c1) / m)
   5253  *
   5254  * given that constraint "i" is of the form
   5255  *
   5256  *	e(...) + c1 - m x >= 0
   5257  *
   5258  * with e(...) an expression that does not involve any other output dimensions.
   5259  *
   5260  *
   5261  * Let "map" be of the form
   5262  *
   5263  *	A -> B
   5264  *
   5265  * We construct a mapping
   5266  *
   5267  *	A -> [A -> x = floor(...)]
   5268  *
   5269  * apply that to the map, obtaining
   5270  *
   5271  *	[A -> x = floor(...)] -> B
   5272  *
   5273  * and equate dimension "d" to x.
   5274  * We then compute a isl_pw_multi_aff representation of the resulting map
   5275  * and plug in the mapping above.
   5276  *
   5277  * The constraint "i" is guaranteed by the caller not to involve
   5278  * any local variables without a known expression, but such local variables
   5279  * may appear in other constraints.  They therefore need to be removed
   5280  * during the construction of the affine expression.
   5281  */
   5282 static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_div(
   5283 	__isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i)
   5284 {
   5285 	isl_space *space = NULL;
   5286 	isl_local_space *ls;
   5287 	isl_multi_aff *ma;
   5288 	isl_aff *aff;
   5289 	isl_vec *v;
   5290 	isl_map *insert;
   5291 	isl_size n_in;
   5292 	isl_pw_multi_aff *pma;
   5293 	isl_bool is_set;
   5294 
   5295 	is_set = isl_map_is_set(map);
   5296 	if (is_set < 0)
   5297 		goto error;
   5298 
   5299 	space = isl_space_domain(isl_map_get_space(map));
   5300 	n_in = isl_space_dim(space, isl_dim_set);
   5301 	if (n_in < 0)
   5302 		goto error;
   5303 
   5304 	ls = isl_basic_map_get_local_space(hull);
   5305 	if (!is_set)
   5306 		ls = isl_local_space_wrap(ls);
   5307 	v = isl_basic_map_inequality_extract_output_upper_bound(hull, i, d);
   5308 	isl_basic_map_free(hull);
   5309 
   5310 	aff = isl_aff_alloc_vec_prune(ls, v);
   5311 	aff = isl_aff_floor(aff);
   5312 	if (is_set) {
   5313 		aff = isl_aff_project_domain_on_params(aff);
   5314 		isl_space_free(space);
   5315 		ma = isl_multi_aff_from_aff(aff);
   5316 	} else {
   5317 		aff = isl_aff_domain_factor_domain(aff);
   5318 		ma = isl_multi_aff_identity(isl_space_map_from_set(space));
   5319 		ma = isl_multi_aff_range_product(ma,
   5320 						isl_multi_aff_from_aff(aff));
   5321 	}
   5322 
   5323 	insert = isl_map_from_multi_aff_internal(isl_multi_aff_copy(ma));
   5324 	map = isl_map_apply_domain(map, insert);
   5325 	map = isl_map_equate(map, isl_dim_in, n_in, isl_dim_out, d);
   5326 	pma = isl_pw_multi_aff_from_map(map);
   5327 	pma = isl_pw_multi_aff_pullback_multi_aff(pma, ma);
   5328 
   5329 	return pma;
   5330 error:
   5331 	isl_space_free(space);
   5332 	isl_map_free(map);
   5333 	isl_basic_map_free(hull);
   5334 	return NULL;
   5335 }
   5336 
   5337 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
   5338  *
   5339  * As a special case, we first check if there is any pair of constraints,
   5340  * shared by all the basic maps in "map" that force a given dimension
   5341  * to be equal to the floor of some affine combination of the input dimensions.
   5342  *
   5343  * In particular, if we can find two constraints
   5344  *
   5345  *	e(...) + c1 - m x >= 0		i.e.,		m x <= e(...) + c1
   5346  *
   5347  * and
   5348  *
   5349  *	-e(...) + c2 + m x >= 0		i.e.,		m x >= e(...) - c2
   5350  *
   5351  * where m > 1 and e only depends on parameters and input dimensions,
   5352  * and such that
   5353  *
   5354  *	c1 + c2 < m			i.e.,		-c2 >= c1 - (m - 1)
   5355  *
   5356  * then we know that we can take
   5357  *
   5358  *	x = floor((e(...) + c1) / m)
   5359  *
   5360  * without having to perform any computation.
   5361  *
   5362  * Note that we know that
   5363  *
   5364  *	c1 + c2 >= 1
   5365  *
   5366  * If c1 + c2 were 0, then we would have detected an equality during
   5367  * simplification.  If c1 + c2 were negative, then we would have detected
   5368  * a contradiction.
   5369  */
   5370 static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_check_div(
   5371 	__isl_take isl_map *map)
   5372 {
   5373 	int d;
   5374 	isl_size dim;
   5375 	isl_size i;
   5376 	isl_size n_ineq;
   5377 	isl_basic_map *hull;
   5378 
   5379 	hull = isl_map_unshifted_simple_hull(isl_map_copy(map));
   5380 	dim = isl_map_dim(map, isl_dim_out);
   5381 	n_ineq = isl_basic_map_n_inequality(hull);
   5382 	if (dim < 0 || n_ineq < 0)
   5383 		goto error;
   5384 
   5385 	dim = isl_map_dim(map, isl_dim_out);
   5386 	for (d = 0; d < dim; ++d) {
   5387 		i = isl_basic_map_find_output_upper_div_constraint(hull, d);
   5388 		if (i < 0)
   5389 			goto error;
   5390 		if (i >= n_ineq)
   5391 			continue;
   5392 		return pw_multi_aff_from_map_div(map, hull, d, i);
   5393 	}
   5394 	isl_basic_map_free(hull);
   5395 	return pw_multi_aff_from_map_base(map);
   5396 error:
   5397 	isl_map_free(map);
   5398 	isl_basic_map_free(hull);
   5399 	return NULL;
   5400 }
   5401 
   5402 /* Given an affine expression
   5403  *
   5404  *	[A -> B] -> f(A,B)
   5405  *
   5406  * construct an isl_multi_aff
   5407  *
   5408  *	[A -> B] -> B'
   5409  *
   5410  * such that dimension "d" in B' is set to "aff" and the remaining
   5411  * dimensions are set equal to the corresponding dimensions in B.
   5412  * "n_in" is the dimension of the space A.
   5413  * "n_out" is the dimension of the space B.
   5414  *
   5415  * If "is_set" is set, then the affine expression is of the form
   5416  *
   5417  *	[B] -> f(B)
   5418  *
   5419  * and we construct an isl_multi_aff
   5420  *
   5421  *	B -> B'
   5422  */
   5423 static __isl_give isl_multi_aff *range_map(__isl_take isl_aff *aff, int d,
   5424 	unsigned n_in, unsigned n_out, int is_set)
   5425 {
   5426 	int i;
   5427 	isl_multi_aff *ma;
   5428 	isl_space *space, *space2;
   5429 	isl_local_space *ls;
   5430 
   5431 	space = isl_aff_get_domain_space(aff);
   5432 	ls = isl_local_space_from_space(isl_space_copy(space));
   5433 	space2 = isl_space_copy(space);
   5434 	if (!is_set)
   5435 		space2 = isl_space_range(isl_space_unwrap(space2));
   5436 	space = isl_space_map_from_domain_and_range(space, space2);
   5437 	ma = isl_multi_aff_alloc(space);
   5438 	ma = isl_multi_aff_set_aff(ma, d, aff);
   5439 
   5440 	for (i = 0; i < n_out; ++i) {
   5441 		if (i == d)
   5442 			continue;
   5443 		aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
   5444 						isl_dim_set, n_in + i);
   5445 		ma = isl_multi_aff_set_aff(ma, i, aff);
   5446 	}
   5447 
   5448 	isl_local_space_free(ls);
   5449 
   5450 	return ma;
   5451 }
   5452 
   5453 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map,
   5454  * taking into account that the dimension at position "d" can be written as
   5455  *
   5456  *	x = m a + f(..)						(1)
   5457  *
   5458  * where m is equal to "gcd".
   5459  * "i" is the index of the equality in "hull" that defines f(..).
   5460  * In particular, the equality is of the form
   5461  *
   5462  *	f(..) - x + m g(existentials) = 0
   5463  *
   5464  * or
   5465  *
   5466  *	-f(..) + x + m g(existentials) = 0
   5467  *
   5468  * We basically plug (1) into "map", resulting in a map with "a"
   5469  * in the range instead of "x".  The corresponding isl_pw_multi_aff
   5470  * defining "a" is then plugged back into (1) to obtain a definition for "x".
   5471  *
   5472  * Specifically, given the input map
   5473  *
   5474  *	A -> B
   5475  *
   5476  * We first wrap it into a set
   5477  *
   5478  *	[A -> B]
   5479  *
   5480  * and define (1) on top of the corresponding space, resulting in "aff".
   5481  * We use this to create an isl_multi_aff that maps the output position "d"
   5482  * from "a" to "x", leaving all other (intput and output) dimensions unchanged.
   5483  * We plug this into the wrapped map, unwrap the result and compute the
   5484  * corresponding isl_pw_multi_aff.
   5485  * The result is an expression
   5486  *
   5487  *	A -> T(A)
   5488  *
   5489  * We adjust that to
   5490  *
   5491  *	A -> [A -> T(A)]
   5492  *
   5493  * so that we can plug that into "aff", after extending the latter to
   5494  * a mapping
   5495  *
   5496  *	[A -> B] -> B'
   5497  *
   5498  *
   5499  * If "map" is actually a set, then there is no "A" space, meaning
   5500  * that we do not need to perform any wrapping, and that the result
   5501  * of the recursive call is of the form
   5502  *
   5503  *	[T]
   5504  *
   5505  * which is plugged into a mapping of the form
   5506  *
   5507  *	B -> B'
   5508  */
   5509 static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_stride(
   5510 	__isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i,
   5511 	isl_int gcd)
   5512 {
   5513 	isl_set *set;
   5514 	isl_space *space;
   5515 	isl_local_space *ls;
   5516 	isl_aff *aff;
   5517 	isl_multi_aff *ma;
   5518 	isl_pw_multi_aff *pma, *id;
   5519 	isl_size n_in;
   5520 	unsigned o_out;
   5521 	isl_size n_out;
   5522 	isl_bool is_set;
   5523 
   5524 	is_set = isl_map_is_set(map);
   5525 	if (is_set < 0)
   5526 		goto error;
   5527 
   5528 	n_in = isl_basic_map_dim(hull, isl_dim_in);
   5529 	n_out = isl_basic_map_dim(hull, isl_dim_out);
   5530 	if (n_in < 0 || n_out < 0)
   5531 		goto error;
   5532 	o_out = isl_basic_map_offset(hull, isl_dim_out);
   5533 
   5534 	if (is_set)
   5535 		set = map;
   5536 	else
   5537 		set = isl_map_wrap(map);
   5538 	space = isl_space_map_from_set(isl_set_get_space(set));
   5539 	ma = isl_multi_aff_identity(space);
   5540 	ls = isl_local_space_from_space(isl_set_get_space(set));
   5541 	aff = isl_aff_alloc(ls);
   5542 	if (aff) {
   5543 		isl_int_set_si(aff->v->el[0], 1);
   5544 		if (isl_int_is_one(hull->eq[i][o_out + d]))
   5545 			isl_seq_neg(aff->v->el + 1, hull->eq[i],
   5546 				    aff->v->size - 1);
   5547 		else
   5548 			isl_seq_cpy(aff->v->el + 1, hull->eq[i],
   5549 				    aff->v->size - 1);
   5550 		isl_int_set(aff->v->el[1 + o_out + d], gcd);
   5551 	}
   5552 	ma = isl_multi_aff_set_aff(ma, n_in + d, isl_aff_copy(aff));
   5553 	set = isl_set_preimage_multi_aff(set, ma);
   5554 
   5555 	ma = range_map(aff, d, n_in, n_out, is_set);
   5556 
   5557 	if (is_set)
   5558 		map = set;
   5559 	else
   5560 		map = isl_set_unwrap(set);
   5561 	pma = isl_pw_multi_aff_from_map(map);
   5562 
   5563 	if (!is_set) {
   5564 		space = isl_pw_multi_aff_get_domain_space(pma);
   5565 		space = isl_space_map_from_set(space);
   5566 		id = isl_pw_multi_aff_identity(space);
   5567 		pma = isl_pw_multi_aff_range_product(id, pma);
   5568 	}
   5569 	id = isl_pw_multi_aff_from_multi_aff(ma);
   5570 	pma = isl_pw_multi_aff_pullback_pw_multi_aff(id, pma);
   5571 
   5572 	isl_basic_map_free(hull);
   5573 	return pma;
   5574 error:
   5575 	isl_map_free(map);
   5576 	isl_basic_map_free(hull);
   5577 	return NULL;
   5578 }
   5579 
   5580 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
   5581  * "hull" contains the equalities valid for "map".
   5582  *
   5583  * Check if any of the output dimensions is "strided".
   5584  * That is, we check if it can be written as
   5585  *
   5586  *	x = m a + f(..)
   5587  *
   5588  * with m greater than 1, a some combination of existentially quantified
   5589  * variables and f an expression in the parameters and input dimensions.
   5590  * If so, we remove the stride in pw_multi_aff_from_map_stride.
   5591  *
   5592  * Otherwise, we continue with pw_multi_aff_from_map_check_div for a further
   5593  * special case.
   5594  */
   5595 static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_check_strides(
   5596 	__isl_take isl_map *map, __isl_take isl_basic_map *hull)
   5597 {
   5598 	int i, j;
   5599 	isl_size n_out;
   5600 	unsigned o_out;
   5601 	isl_size n_div;
   5602 	unsigned o_div;
   5603 	isl_int gcd;
   5604 
   5605 	n_div = isl_basic_map_dim(hull, isl_dim_div);
   5606 	n_out = isl_basic_map_dim(hull, isl_dim_out);
   5607 	if (n_div < 0 || n_out < 0)
   5608 		goto error;
   5609 
   5610 	if (n_div == 0) {
   5611 		isl_basic_map_free(hull);
   5612 		return pw_multi_aff_from_map_check_div(map);
   5613 	}
   5614 
   5615 	isl_int_init(gcd);
   5616 
   5617 	o_div = isl_basic_map_offset(hull, isl_dim_div);
   5618 	o_out = isl_basic_map_offset(hull, isl_dim_out);
   5619 
   5620 	for (i = 0; i < n_out; ++i) {
   5621 		for (j = 0; j < hull->n_eq; ++j) {
   5622 			isl_int *eq = hull->eq[j];
   5623 			isl_pw_multi_aff *res;
   5624 
   5625 			if (!isl_int_is_one(eq[o_out + i]) &&
   5626 			    !isl_int_is_negone(eq[o_out + i]))
   5627 				continue;
   5628 			if (isl_seq_first_non_zero(eq + o_out, i) != -1)
   5629 				continue;
   5630 			if (isl_seq_first_non_zero(eq + o_out + i + 1,
   5631 						    n_out - (i + 1)) != -1)
   5632 				continue;
   5633 			isl_seq_gcd(eq + o_div, n_div, &gcd);
   5634 			if (isl_int_is_zero(gcd))
   5635 				continue;
   5636 			if (isl_int_is_one(gcd))
   5637 				continue;
   5638 
   5639 			res = pw_multi_aff_from_map_stride(map, hull,
   5640 								i, j, gcd);
   5641 			isl_int_clear(gcd);
   5642 			return res;
   5643 		}
   5644 	}
   5645 
   5646 	isl_int_clear(gcd);
   5647 	isl_basic_map_free(hull);
   5648 	return pw_multi_aff_from_map_check_div(map);
   5649 error:
   5650 	isl_map_free(map);
   5651 	isl_basic_map_free(hull);
   5652 	return NULL;
   5653 }
   5654 
   5655 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
   5656  *
   5657  * As a special case, we first check if all output dimensions are uniquely
   5658  * defined in terms of the parameters and input dimensions over the entire
   5659  * domain.  If so, we extract the desired isl_pw_multi_aff directly
   5660  * from the affine hull of "map" and its domain.
   5661  *
   5662  * Otherwise, continue with pw_multi_aff_from_map_check_strides for more
   5663  * special cases.
   5664  */
   5665 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map)
   5666 {
   5667 	isl_bool sv;
   5668 	isl_size n;
   5669 	isl_basic_map *hull;
   5670 
   5671 	n = isl_map_n_basic_map(map);
   5672 	if (n < 0)
   5673 		goto error;
   5674 
   5675 	if (n == 1) {
   5676 		hull = isl_map_unshifted_simple_hull(isl_map_copy(map));
   5677 		hull = isl_basic_map_plain_affine_hull(hull);
   5678 		sv = isl_basic_map_plain_is_single_valued(hull);
   5679 		if (sv >= 0 && sv)
   5680 			return plain_pw_multi_aff_from_map(isl_map_domain(map),
   5681 							    hull);
   5682 		isl_basic_map_free(hull);
   5683 	}
   5684 	map = isl_map_detect_equalities(map);
   5685 	hull = isl_map_unshifted_simple_hull(isl_map_copy(map));
   5686 	sv = isl_basic_map_plain_is_single_valued(hull);
   5687 	if (sv >= 0 && sv)
   5688 		return plain_pw_multi_aff_from_map(isl_map_domain(map), hull);
   5689 	if (sv >= 0)
   5690 		return pw_multi_aff_from_map_check_strides(map, hull);
   5691 	isl_basic_map_free(hull);
   5692 error:
   5693 	isl_map_free(map);
   5694 	return NULL;
   5695 }
   5696 
   5697 /* This function performs the same operation as isl_pw_multi_aff_from_map,
   5698  * but is considered as a function on an isl_map when exported.
   5699  */
   5700 __isl_give isl_pw_multi_aff *isl_map_as_pw_multi_aff(__isl_take isl_map *map)
   5701 {
   5702 	return isl_pw_multi_aff_from_map(map);
   5703 }
   5704 
   5705 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(__isl_take isl_set *set)
   5706 {
   5707 	return isl_pw_multi_aff_from_map(set);
   5708 }
   5709 
   5710 /* This function performs the same operation as isl_pw_multi_aff_from_set,
   5711  * but is considered as a function on an isl_set when exported.
   5712  */
   5713 __isl_give isl_pw_multi_aff *isl_set_as_pw_multi_aff(__isl_take isl_set *set)
   5714 {
   5715 	return isl_pw_multi_aff_from_set(set);
   5716 }
   5717 
   5718 /* Convert "map" into an isl_pw_multi_aff (if possible) and
   5719  * add it to *user.
   5720  */
   5721 static isl_stat pw_multi_aff_from_map(__isl_take isl_map *map, void *user)
   5722 {
   5723 	isl_union_pw_multi_aff **upma = user;
   5724 	isl_pw_multi_aff *pma;
   5725 
   5726 	pma = isl_pw_multi_aff_from_map(map);
   5727 	*upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
   5728 
   5729 	return *upma ? isl_stat_ok : isl_stat_error;
   5730 }
   5731 
   5732 /* Create an isl_union_pw_multi_aff with the given isl_aff on a universe
   5733  * domain.
   5734  */
   5735 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_aff(
   5736 	__isl_take isl_aff *aff)
   5737 {
   5738 	isl_multi_aff *ma;
   5739 	isl_pw_multi_aff *pma;
   5740 
   5741 	ma = isl_multi_aff_from_aff(aff);
   5742 	pma = isl_pw_multi_aff_from_multi_aff(ma);
   5743 	return isl_union_pw_multi_aff_from_pw_multi_aff(pma);
   5744 }
   5745 
   5746 /* Try and create an isl_union_pw_multi_aff that is equivalent
   5747  * to the given isl_union_map.
   5748  * The isl_union_map is required to be single-valued in each space.
   5749  * Otherwise, an error is produced.
   5750  */
   5751 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_map(
   5752 	__isl_take isl_union_map *umap)
   5753 {
   5754 	isl_space *space;
   5755 	isl_union_pw_multi_aff *upma;
   5756 
   5757 	space = isl_union_map_get_space(umap);
   5758 	upma = isl_union_pw_multi_aff_empty(space);
   5759 	if (isl_union_map_foreach_map(umap, &pw_multi_aff_from_map, &upma) < 0)
   5760 		upma = isl_union_pw_multi_aff_free(upma);
   5761 	isl_union_map_free(umap);
   5762 
   5763 	return upma;
   5764 }
   5765 
   5766 /* This function performs the same operation as
   5767  * isl_union_pw_multi_aff_from_union_map,
   5768  * but is considered as a function on an isl_union_map when exported.
   5769  */
   5770 __isl_give isl_union_pw_multi_aff *isl_union_map_as_union_pw_multi_aff(
   5771 	__isl_take isl_union_map *umap)
   5772 {
   5773 	return isl_union_pw_multi_aff_from_union_map(umap);
   5774 }
   5775 
   5776 /* Try and create an isl_union_pw_multi_aff that is equivalent
   5777  * to the given isl_union_set.
   5778  * The isl_union_set is required to be a singleton in each space.
   5779  * Otherwise, an error is produced.
   5780  */
   5781 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_set(
   5782 	__isl_take isl_union_set *uset)
   5783 {
   5784 	return isl_union_pw_multi_aff_from_union_map(uset);
   5785 }
   5786 
   5787 /* Return the piecewise affine expression "set ? 1 : 0".
   5788  */
   5789 __isl_give isl_pw_aff *isl_set_indicator_function(__isl_take isl_set *set)
   5790 {
   5791 	isl_pw_aff *pa;
   5792 	isl_space *space = isl_set_get_space(set);
   5793 	isl_local_space *ls = isl_local_space_from_space(space);
   5794 	isl_aff *zero = isl_aff_zero_on_domain(isl_local_space_copy(ls));
   5795 	isl_aff *one = isl_aff_zero_on_domain(ls);
   5796 
   5797 	one = isl_aff_add_constant_si(one, 1);
   5798 	pa = isl_pw_aff_alloc(isl_set_copy(set), one);
   5799 	set = isl_set_complement(set);
   5800 	pa = isl_pw_aff_add_disjoint(pa, isl_pw_aff_alloc(set, zero));
   5801 
   5802 	return pa;
   5803 }
   5804 
   5805 /* Plug in "subs" for dimension "type", "pos" of "aff".
   5806  *
   5807  * Let i be the dimension to replace and let "subs" be of the form
   5808  *
   5809  *	f/d
   5810  *
   5811  * and "aff" of the form
   5812  *
   5813  *	(a i + g)/m
   5814  *
   5815  * The result is
   5816  *
   5817  *	(a f + d g')/(m d)
   5818  *
   5819  * where g' is the result of plugging in "subs" in each of the integer
   5820  * divisions in g.
   5821  */
   5822 __isl_give isl_aff *isl_aff_substitute(__isl_take isl_aff *aff,
   5823 	enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
   5824 {
   5825 	isl_ctx *ctx;
   5826 	isl_int v;
   5827 	isl_size n_div;
   5828 
   5829 	aff = isl_aff_cow(aff);
   5830 	if (!aff || !subs)
   5831 		return isl_aff_free(aff);
   5832 
   5833 	ctx = isl_aff_get_ctx(aff);
   5834 	if (!isl_space_is_equal(aff->ls->dim, subs->ls->dim))
   5835 		isl_die(ctx, isl_error_invalid,
   5836 			"spaces don't match", return isl_aff_free(aff));
   5837 	n_div = isl_aff_domain_dim(subs, isl_dim_div);
   5838 	if (n_div < 0)
   5839 		return isl_aff_free(aff);
   5840 	if (n_div != 0)
   5841 		isl_die(ctx, isl_error_unsupported,
   5842 			"cannot handle divs yet", return isl_aff_free(aff));
   5843 
   5844 	aff->ls = isl_local_space_substitute(aff->ls, type, pos, subs);
   5845 	if (!aff->ls)
   5846 		return isl_aff_free(aff);
   5847 
   5848 	aff->v = isl_vec_cow(aff->v);
   5849 	if (!aff->v)
   5850 		return isl_aff_free(aff);
   5851 
   5852 	pos += isl_local_space_offset(aff->ls, type);
   5853 
   5854 	isl_int_init(v);
   5855 	isl_seq_substitute(aff->v->el, pos, subs->v->el,
   5856 			    aff->v->size, subs->v->size, v);
   5857 	isl_int_clear(v);
   5858 
   5859 	return aff;
   5860 }
   5861 
   5862 /* Plug in "subs" for dimension "type", "pos" in each of the affine
   5863  * expressions in "maff".
   5864  */
   5865 __isl_give isl_multi_aff *isl_multi_aff_substitute(
   5866 	__isl_take isl_multi_aff *maff, enum isl_dim_type type, unsigned pos,
   5867 	__isl_keep isl_aff *subs)
   5868 {
   5869 	isl_size n;
   5870 	int i;
   5871 
   5872 	n = isl_multi_aff_size(maff);
   5873 	if (n < 0 || !subs)
   5874 		return isl_multi_aff_free(maff);
   5875 
   5876 	if (type == isl_dim_in)
   5877 		type = isl_dim_set;
   5878 
   5879 	for (i = 0; i < n; ++i) {
   5880 		isl_aff *aff;
   5881 
   5882 		aff = isl_multi_aff_take_at(maff, i);
   5883 		aff = isl_aff_substitute(aff, type, pos, subs);
   5884 		maff = isl_multi_aff_restore_at(maff, i, aff);
   5885 	}
   5886 
   5887 	return maff;
   5888 }
   5889 
   5890 /* Plug in "subs" for input dimension "pos" of "pma".
   5891  *
   5892  * pma is of the form
   5893  *
   5894  *	A_i(v) -> M_i(v)
   5895  *
   5896  * while subs is of the form
   5897  *
   5898  *	v' = B_j(v) -> S_j
   5899  *
   5900  * Each pair i,j such that C_ij = A_i \cap B_i is non-empty
   5901  * has a contribution in the result, in particular
   5902  *
   5903  *	C_ij(S_j) -> M_i(S_j)
   5904  *
   5905  * Note that plugging in S_j in C_ij may also result in an empty set
   5906  * and this contribution should simply be discarded.
   5907  */
   5908 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute(
   5909 	__isl_take isl_pw_multi_aff *pma, unsigned pos,
   5910 	__isl_keep isl_pw_aff *subs)
   5911 {
   5912 	int i, j, n;
   5913 	isl_pw_multi_aff *res;
   5914 
   5915 	if (!pma || !subs)
   5916 		return isl_pw_multi_aff_free(pma);
   5917 
   5918 	n = pma->n * subs->n;
   5919 	res = isl_pw_multi_aff_alloc_size(isl_space_copy(pma->dim), n);
   5920 
   5921 	for (i = 0; i < pma->n; ++i) {
   5922 		for (j = 0; j < subs->n; ++j) {
   5923 			isl_set *common;
   5924 			isl_multi_aff *res_ij;
   5925 			int empty;
   5926 
   5927 			common = isl_set_intersect(
   5928 					isl_set_copy(pma->p[i].set),
   5929 					isl_set_copy(subs->p[j].set));
   5930 			common = isl_set_substitute(common,
   5931 					pos, subs->p[j].aff);
   5932 			empty = isl_set_plain_is_empty(common);
   5933 			if (empty < 0 || empty) {
   5934 				isl_set_free(common);
   5935 				if (empty < 0)
   5936 					goto error;
   5937 				continue;
   5938 			}
   5939 
   5940 			res_ij = isl_multi_aff_substitute(
   5941 					isl_multi_aff_copy(pma->p[i].maff),
   5942 					isl_dim_in, pos, subs->p[j].aff);
   5943 
   5944 			res = isl_pw_multi_aff_add_piece(res, common, res_ij);
   5945 		}
   5946 	}
   5947 
   5948 	isl_pw_multi_aff_free(pma);
   5949 	return res;
   5950 error:
   5951 	isl_pw_multi_aff_free(pma);
   5952 	isl_pw_multi_aff_free(res);
   5953 	return NULL;
   5954 }
   5955 
   5956 /* Compute the preimage of a range of dimensions in the affine expression "src"
   5957  * under "ma" and put the result in "dst".  The number of dimensions in "src"
   5958  * that precede the range is given by "n_before".  The number of dimensions
   5959  * in the range is given by the number of output dimensions of "ma".
   5960  * The number of dimensions that follow the range is given by "n_after".
   5961  * If "has_denom" is set (to one),
   5962  * then "src" and "dst" have an extra initial denominator.
   5963  * "n_div_ma" is the number of existentials in "ma"
   5964  * "n_div_bset" is the number of existentials in "src"
   5965  * The resulting "dst" (which is assumed to have been allocated by
   5966  * the caller) contains coefficients for both sets of existentials,
   5967  * first those in "ma" and then those in "src".
   5968  * f, c1, c2 and g are temporary objects that have been initialized
   5969  * by the caller.
   5970  *
   5971  * Let src represent the expression
   5972  *
   5973  *	(a(p) + f_u u + b v + f_w w + c(divs))/d
   5974  *
   5975  * and let ma represent the expressions
   5976  *
   5977  *	v_i = (r_i(p) + s_i(y) + t_i(divs'))/m_i
   5978  *
   5979  * We start out with the following expression for dst:
   5980  *
   5981  *	(a(p) + f_u u + 0 y + f_w w + 0 divs' + c(divs) + f \sum_i b_i v_i)/d
   5982  *
   5983  * with the multiplication factor f initially equal to 1
   5984  * and f \sum_i b_i v_i kept separately.
   5985  * For each x_i that we substitute, we multiply the numerator
   5986  * (and denominator) of dst by c_1 = m_i and add the numerator
   5987  * of the x_i expression multiplied by c_2 = f b_i,
   5988  * after removing the common factors of c_1 and c_2.
   5989  * The multiplication factor f also needs to be multiplied by c_1
   5990  * for the next x_j, j > i.
   5991  */
   5992 isl_stat isl_seq_preimage(isl_int *dst, isl_int *src,
   5993 	__isl_keep isl_multi_aff *ma, int n_before, int n_after,
   5994 	int n_div_ma, int n_div_bmap,
   5995 	isl_int f, isl_int c1, isl_int c2, isl_int g, int has_denom)
   5996 {
   5997 	int i;
   5998 	isl_size n_param, n_in, n_out;
   5999 	int o_dst, o_src;
   6000 
   6001 	n_param = isl_multi_aff_dim(ma, isl_dim_param);
   6002 	n_in = isl_multi_aff_dim(ma, isl_dim_in);
   6003 	n_out = isl_multi_aff_dim(ma, isl_dim_out);
   6004 	if (n_param < 0 || n_in < 0 || n_out < 0)
   6005 		return isl_stat_error;
   6006 
   6007 	isl_seq_cpy(dst, src, has_denom + 1 + n_param + n_before);
   6008 	o_dst = o_src = has_denom + 1 + n_param + n_before;
   6009 	isl_seq_clr(dst + o_dst, n_in);
   6010 	o_dst += n_in;
   6011 	o_src += n_out;
   6012 	isl_seq_cpy(dst + o_dst, src + o_src, n_after);
   6013 	o_dst += n_after;
   6014 	o_src += n_after;
   6015 	isl_seq_clr(dst + o_dst, n_div_ma);
   6016 	o_dst += n_div_ma;
   6017 	isl_seq_cpy(dst + o_dst, src + o_src, n_div_bmap);
   6018 
   6019 	isl_int_set_si(f, 1);
   6020 
   6021 	for (i = 0; i < n_out; ++i) {
   6022 		int offset = has_denom + 1 + n_param + n_before + i;
   6023 
   6024 		if (isl_int_is_zero(src[offset]))
   6025 			continue;
   6026 		isl_int_set(c1, ma->u.p[i]->v->el[0]);
   6027 		isl_int_mul(c2, f, src[offset]);
   6028 		isl_int_gcd(g, c1, c2);
   6029 		isl_int_divexact(c1, c1, g);
   6030 		isl_int_divexact(c2, c2, g);
   6031 
   6032 		isl_int_mul(f, f, c1);
   6033 		o_dst = has_denom;
   6034 		o_src = 1;
   6035 		isl_seq_combine(dst + o_dst, c1, dst + o_dst,
   6036 				c2, ma->u.p[i]->v->el + o_src, 1 + n_param);
   6037 		o_dst += 1 + n_param;
   6038 		o_src += 1 + n_param;
   6039 		isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_before);
   6040 		o_dst += n_before;
   6041 		isl_seq_combine(dst + o_dst, c1, dst + o_dst,
   6042 				c2, ma->u.p[i]->v->el + o_src, n_in);
   6043 		o_dst += n_in;
   6044 		o_src += n_in;
   6045 		isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_after);
   6046 		o_dst += n_after;
   6047 		isl_seq_combine(dst + o_dst, c1, dst + o_dst,
   6048 				c2, ma->u.p[i]->v->el + o_src, n_div_ma);
   6049 		o_dst += n_div_ma;
   6050 		o_src += n_div_ma;
   6051 		isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_div_bmap);
   6052 		if (has_denom)
   6053 			isl_int_mul(dst[0], dst[0], c1);
   6054 	}
   6055 
   6056 	return isl_stat_ok;
   6057 }
   6058 
   6059 /* Compute the pullback of "aff" by the function represented by "ma".
   6060  * In other words, plug in "ma" in "aff".  The result is an affine expression
   6061  * defined over the domain space of "ma".
   6062  *
   6063  * If "aff" is represented by
   6064  *
   6065  *	(a(p) + b x + c(divs))/d
   6066  *
   6067  * and ma is represented by
   6068  *
   6069  *	x = D(p) + F(y) + G(divs')
   6070  *
   6071  * then the result is
   6072  *
   6073  *	(a(p) + b D(p) + b F(y) + b G(divs') + c(divs))/d
   6074  *
   6075  * The divs in the local space of the input are similarly adjusted
   6076  * through a call to isl_local_space_preimage_multi_aff.
   6077  */
   6078 __isl_give isl_aff *isl_aff_pullback_multi_aff(__isl_take isl_aff *aff,
   6079 	__isl_take isl_multi_aff *ma)
   6080 {
   6081 	isl_aff *res = NULL;
   6082 	isl_local_space *ls;
   6083 	isl_size n_div_aff, n_div_ma;
   6084 	isl_int f, c1, c2, g;
   6085 
   6086 	ma = isl_multi_aff_align_divs(ma);
   6087 	if (!aff || !ma)
   6088 		goto error;
   6089 
   6090 	n_div_aff = isl_aff_dim(aff, isl_dim_div);
   6091 	n_div_ma = ma->n ? isl_aff_dim(ma->u.p[0], isl_dim_div) : 0;
   6092 	if (n_div_aff < 0 || n_div_ma < 0)
   6093 		goto error;
   6094 
   6095 	ls = isl_aff_get_domain_local_space(aff);
   6096 	ls = isl_local_space_preimage_multi_aff(ls, isl_multi_aff_copy(ma));
   6097 	res = isl_aff_alloc(ls);
   6098 	if (!res)
   6099 		goto error;
   6100 
   6101 	isl_int_init(f);
   6102 	isl_int_init(c1);
   6103 	isl_int_init(c2);
   6104 	isl_int_init(g);
   6105 
   6106 	if (isl_seq_preimage(res->v->el, aff->v->el, ma, 0, 0,
   6107 			    n_div_ma, n_div_aff, f, c1, c2, g, 1) < 0)
   6108 		res = isl_aff_free(res);
   6109 
   6110 	isl_int_clear(f);
   6111 	isl_int_clear(c1);
   6112 	isl_int_clear(c2);
   6113 	isl_int_clear(g);
   6114 
   6115 	isl_aff_free(aff);
   6116 	isl_multi_aff_free(ma);
   6117 	res = isl_aff_normalize(res);
   6118 	return res;
   6119 error:
   6120 	isl_aff_free(aff);
   6121 	isl_multi_aff_free(ma);
   6122 	isl_aff_free(res);
   6123 	return NULL;
   6124 }
   6125 
   6126 /* Compute the pullback of "aff1" by the function represented by "aff2".
   6127  * In other words, plug in "aff2" in "aff1".  The result is an affine expression
   6128  * defined over the domain space of "aff1".
   6129  *
   6130  * The domain of "aff1" should match the range of "aff2", which means
   6131  * that it should be single-dimensional.
   6132  */
   6133 __isl_give isl_aff *isl_aff_pullback_aff(__isl_take isl_aff *aff1,
   6134 	__isl_take isl_aff *aff2)
   6135 {
   6136 	isl_multi_aff *ma;
   6137 
   6138 	ma = isl_multi_aff_from_aff(aff2);
   6139 	return isl_aff_pullback_multi_aff(aff1, ma);
   6140 }
   6141 
   6142 /* Compute the pullback of "ma1" by the function represented by "ma2".
   6143  * In other words, plug in "ma2" in "ma1".
   6144  */
   6145 __isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff(
   6146 	__isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2)
   6147 {
   6148 	int i;
   6149 	isl_size n;
   6150 	isl_space *space = NULL;
   6151 
   6152 	isl_multi_aff_align_params_bin(&ma1, &ma2);
   6153 	ma2 = isl_multi_aff_align_divs(ma2);
   6154 	n = isl_multi_aff_size(ma1);
   6155 	if (n < 0 || !ma2)
   6156 		goto error;
   6157 
   6158 	space = isl_space_join(isl_multi_aff_get_space(ma2),
   6159 				isl_multi_aff_get_space(ma1));
   6160 
   6161 	for (i = 0; i < n; ++i) {
   6162 		isl_aff *aff;
   6163 
   6164 		aff = isl_multi_aff_take_at(ma1, i);
   6165 		aff = isl_aff_pullback_multi_aff(aff, isl_multi_aff_copy(ma2));
   6166 		ma1 = isl_multi_aff_restore_at(ma1, i, aff);
   6167 	}
   6168 
   6169 	ma1 = isl_multi_aff_reset_space(ma1, space);
   6170 	isl_multi_aff_free(ma2);
   6171 	return ma1;
   6172 error:
   6173 	isl_space_free(space);
   6174 	isl_multi_aff_free(ma2);
   6175 	isl_multi_aff_free(ma1);
   6176 	return NULL;
   6177 }
   6178 
   6179 /* Extend the local space of "dst" to include the divs
   6180  * in the local space of "src".
   6181  *
   6182  * If "src" does not have any divs or if the local spaces of "dst" and
   6183  * "src" are the same, then no extension is required.
   6184  */
   6185 __isl_give isl_aff *isl_aff_align_divs(__isl_take isl_aff *dst,
   6186 	__isl_keep isl_aff *src)
   6187 {
   6188 	isl_ctx *ctx;
   6189 	isl_size src_n_div, dst_n_div;
   6190 	int *exp1 = NULL;
   6191 	int *exp2 = NULL;
   6192 	isl_bool equal;
   6193 	isl_mat *div;
   6194 
   6195 	if (!src || !dst)
   6196 		return isl_aff_free(dst);
   6197 
   6198 	ctx = isl_aff_get_ctx(src);
   6199 	equal = isl_local_space_has_equal_space(src->ls, dst->ls);
   6200 	if (equal < 0)
   6201 		return isl_aff_free(dst);
   6202 	if (!equal)
   6203 		isl_die(ctx, isl_error_invalid,
   6204 			"spaces don't match", goto error);
   6205 
   6206 	src_n_div = isl_aff_domain_dim(src, isl_dim_div);
   6207 	dst_n_div = isl_aff_domain_dim(dst, isl_dim_div);
   6208 	if (src_n_div == 0)
   6209 		return dst;
   6210 	equal = isl_local_space_is_equal(src->ls, dst->ls);
   6211 	if (equal < 0 || src_n_div < 0 || dst_n_div < 0)
   6212 		return isl_aff_free(dst);
   6213 	if (equal)
   6214 		return dst;
   6215 
   6216 	exp1 = isl_alloc_array(ctx, int, src_n_div);
   6217 	exp2 = isl_alloc_array(ctx, int, dst_n_div);
   6218 	if (!exp1 || (dst_n_div && !exp2))
   6219 		goto error;
   6220 
   6221 	div = isl_merge_divs(src->ls->div, dst->ls->div, exp1, exp2);
   6222 	dst = isl_aff_expand_divs(dst, div, exp2);
   6223 	free(exp1);
   6224 	free(exp2);
   6225 
   6226 	return dst;
   6227 error:
   6228 	free(exp1);
   6229 	free(exp2);
   6230 	return isl_aff_free(dst);
   6231 }
   6232 
   6233 /* Adjust the local spaces of the affine expressions in "maff"
   6234  * such that they all have the save divs.
   6235  */
   6236 __isl_give isl_multi_aff *isl_multi_aff_align_divs(
   6237 	__isl_take isl_multi_aff *maff)
   6238 {
   6239 	isl_aff *aff_0;
   6240 	isl_size n;
   6241 	int i;
   6242 
   6243 	n = isl_multi_aff_size(maff);
   6244 	if (n < 0)
   6245 		return isl_multi_aff_free(maff);
   6246 	if (n <= 1)
   6247 		return maff;
   6248 
   6249 	aff_0 = isl_multi_aff_take_at(maff, 0);
   6250 	for (i = 1; i < n; ++i) {
   6251 		isl_aff *aff_i;
   6252 
   6253 		aff_i = isl_multi_aff_peek_at(maff, i);
   6254 		aff_0 = isl_aff_align_divs(aff_0, aff_i);
   6255 	}
   6256 	maff = isl_multi_aff_restore_at(maff, 0, aff_0);
   6257 
   6258 	aff_0 = isl_multi_aff_peek_at(maff, 0);
   6259 	for (i = 1; i < n; ++i) {
   6260 		isl_aff *aff_i;
   6261 
   6262 		aff_i = isl_multi_aff_take_at(maff, i);
   6263 		aff_i = isl_aff_align_divs(aff_i, aff_0);
   6264 		maff = isl_multi_aff_restore_at(maff, i, aff_i);
   6265 	}
   6266 
   6267 	return maff;
   6268 }
   6269 
   6270 __isl_give isl_aff *isl_aff_lift(__isl_take isl_aff *aff)
   6271 {
   6272 	aff = isl_aff_cow(aff);
   6273 	if (!aff)
   6274 		return NULL;
   6275 
   6276 	aff->ls = isl_local_space_lift(aff->ls);
   6277 	if (!aff->ls)
   6278 		return isl_aff_free(aff);
   6279 
   6280 	return aff;
   6281 }
   6282 
   6283 /* Lift "maff" to a space with extra dimensions such that the result
   6284  * has no more existentially quantified variables.
   6285  * If "ls" is not NULL, then *ls is assigned the local space that lies
   6286  * at the basis of the lifting applied to "maff".
   6287  */
   6288 __isl_give isl_multi_aff *isl_multi_aff_lift(__isl_take isl_multi_aff *maff,
   6289 	__isl_give isl_local_space **ls)
   6290 {
   6291 	int i;
   6292 	isl_space *space;
   6293 	isl_aff *aff;
   6294 	isl_size n, n_div;
   6295 
   6296 	if (ls)
   6297 		*ls = NULL;
   6298 
   6299 	n = isl_multi_aff_size(maff);
   6300 	if (n < 0)
   6301 		return isl_multi_aff_free(maff);
   6302 
   6303 	if (n == 0) {
   6304 		if (ls) {
   6305 			isl_space *space = isl_multi_aff_get_domain_space(maff);
   6306 			*ls = isl_local_space_from_space(space);
   6307 			if (!*ls)
   6308 				return isl_multi_aff_free(maff);
   6309 		}
   6310 		return maff;
   6311 	}
   6312 
   6313 	maff = isl_multi_aff_align_divs(maff);
   6314 
   6315 	aff = isl_multi_aff_peek_at(maff, 0);
   6316 	n_div = isl_aff_dim(aff, isl_dim_div);
   6317 	if (n_div < 0)
   6318 		return isl_multi_aff_free(maff);
   6319 	space = isl_multi_aff_get_space(maff);
   6320 	space = isl_space_lift(isl_space_domain(space), n_div);
   6321 	space = isl_space_extend_domain_with_range(space,
   6322 						isl_multi_aff_get_space(maff));
   6323 	maff = isl_multi_aff_restore_space(maff, space);
   6324 
   6325 	if (ls) {
   6326 		aff = isl_multi_aff_peek_at(maff, 0);
   6327 		*ls = isl_aff_get_domain_local_space(aff);
   6328 		if (!*ls)
   6329 			return isl_multi_aff_free(maff);
   6330 	}
   6331 
   6332 	for (i = 0; i < n; ++i) {
   6333 		aff = isl_multi_aff_take_at(maff, i);
   6334 		aff = isl_aff_lift(aff);
   6335 		maff = isl_multi_aff_restore_at(maff, i, aff);
   6336 	}
   6337 
   6338 	return maff;
   6339 }
   6340 
   6341 #undef TYPE
   6342 #define TYPE	isl_pw_multi_aff
   6343 static
   6344 #include "check_type_range_templ.c"
   6345 
   6346 /* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma".
   6347  */
   6348 __isl_give isl_pw_aff *isl_pw_multi_aff_get_at(
   6349 	__isl_keep isl_pw_multi_aff *pma, int pos)
   6350 {
   6351 	int i;
   6352 	isl_size n_out;
   6353 	isl_space *space;
   6354 	isl_pw_aff *pa;
   6355 
   6356 	if (isl_pw_multi_aff_check_range(pma, isl_dim_out, pos, 1) < 0)
   6357 		return NULL;
   6358 
   6359 	n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
   6360 	if (n_out < 0)
   6361 		return NULL;
   6362 
   6363 	space = isl_pw_multi_aff_get_space(pma);
   6364 	space = isl_space_drop_dims(space, isl_dim_out,
   6365 				    pos + 1, n_out - pos - 1);
   6366 	space = isl_space_drop_dims(space, isl_dim_out, 0, pos);
   6367 
   6368 	pa = isl_pw_aff_alloc_size(space, pma->n);
   6369 	for (i = 0; i < pma->n; ++i) {
   6370 		isl_aff *aff;
   6371 		aff = isl_multi_aff_get_aff(pma->p[i].maff, pos);
   6372 		pa = isl_pw_aff_add_piece(pa, isl_set_copy(pma->p[i].set), aff);
   6373 	}
   6374 
   6375 	return pa;
   6376 }
   6377 
   6378 /* This is an alternative name for the function above.
   6379  */
   6380 __isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff(
   6381 	__isl_keep isl_pw_multi_aff *pma, int pos)
   6382 {
   6383 	return isl_pw_multi_aff_get_at(pma, pos);
   6384 }
   6385 
   6386 /* Return an isl_pw_multi_aff with the given "set" as domain and
   6387  * an unnamed zero-dimensional range.
   6388  */
   6389 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain(
   6390 	__isl_take isl_set *set)
   6391 {
   6392 	isl_multi_aff *ma;
   6393 	isl_space *space;
   6394 
   6395 	space = isl_set_get_space(set);
   6396 	space = isl_space_from_domain(space);
   6397 	ma = isl_multi_aff_zero(space);
   6398 	return isl_pw_multi_aff_alloc(set, ma);
   6399 }
   6400 
   6401 /* Add an isl_pw_multi_aff with the given "set" as domain and
   6402  * an unnamed zero-dimensional range to *user.
   6403  */
   6404 static isl_stat add_pw_multi_aff_from_domain(__isl_take isl_set *set,
   6405 	void *user)
   6406 {
   6407 	isl_union_pw_multi_aff **upma = user;
   6408 	isl_pw_multi_aff *pma;
   6409 
   6410 	pma = isl_pw_multi_aff_from_domain(set);
   6411 	*upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
   6412 
   6413 	return isl_stat_ok;
   6414 }
   6415 
   6416 /* Return an isl_union_pw_multi_aff with the given "uset" as domain and
   6417  * an unnamed zero-dimensional range.
   6418  */
   6419 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_domain(
   6420 	__isl_take isl_union_set *uset)
   6421 {
   6422 	isl_space *space;
   6423 	isl_union_pw_multi_aff *upma;
   6424 
   6425 	if (!uset)
   6426 		return NULL;
   6427 
   6428 	space = isl_union_set_get_space(uset);
   6429 	upma = isl_union_pw_multi_aff_empty(space);
   6430 
   6431 	if (isl_union_set_foreach_set(uset,
   6432 				    &add_pw_multi_aff_from_domain, &upma) < 0)
   6433 		goto error;
   6434 
   6435 	isl_union_set_free(uset);
   6436 	return upma;
   6437 error:
   6438 	isl_union_set_free(uset);
   6439 	isl_union_pw_multi_aff_free(upma);
   6440 	return NULL;
   6441 }
   6442 
   6443 /* Local data for bin_entry and the callback "fn".
   6444  */
   6445 struct isl_union_pw_multi_aff_bin_data {
   6446 	isl_union_pw_multi_aff *upma2;
   6447 	isl_union_pw_multi_aff *res;
   6448 	isl_pw_multi_aff *pma;
   6449 	isl_stat (*fn)(__isl_take isl_pw_multi_aff *pma, void *user);
   6450 };
   6451 
   6452 /* Given an isl_pw_multi_aff from upma1, store it in data->pma
   6453  * and call data->fn for each isl_pw_multi_aff in data->upma2.
   6454  */
   6455 static isl_stat bin_entry(__isl_take isl_pw_multi_aff *pma, void *user)
   6456 {
   6457 	struct isl_union_pw_multi_aff_bin_data *data = user;
   6458 	isl_stat r;
   6459 
   6460 	data->pma = pma;
   6461 	r = isl_union_pw_multi_aff_foreach_pw_multi_aff(data->upma2,
   6462 				   data->fn, data);
   6463 	isl_pw_multi_aff_free(pma);
   6464 
   6465 	return r;
   6466 }
   6467 
   6468 /* Call "fn" on each pair of isl_pw_multi_affs in "upma1" and "upma2".
   6469  * The isl_pw_multi_aff from upma1 is stored in data->pma (where data is
   6470  * passed as user field) and the isl_pw_multi_aff from upma2 is available
   6471  * as *entry.  The callback should adjust data->res if desired.
   6472  */
   6473 static __isl_give isl_union_pw_multi_aff *bin_op(
   6474 	__isl_take isl_union_pw_multi_aff *upma1,
   6475 	__isl_take isl_union_pw_multi_aff *upma2,
   6476 	isl_stat (*fn)(__isl_take isl_pw_multi_aff *pma, void *user))
   6477 {
   6478 	isl_space *space;
   6479 	struct isl_union_pw_multi_aff_bin_data data = { NULL, NULL, NULL, fn };
   6480 
   6481 	space = isl_union_pw_multi_aff_get_space(upma2);
   6482 	upma1 = isl_union_pw_multi_aff_align_params(upma1, space);
   6483 	space = isl_union_pw_multi_aff_get_space(upma1);
   6484 	upma2 = isl_union_pw_multi_aff_align_params(upma2, space);
   6485 
   6486 	if (!upma1 || !upma2)
   6487 		goto error;
   6488 
   6489 	data.upma2 = upma2;
   6490 	data.res = isl_union_pw_multi_aff_alloc_same_size(upma1);
   6491 	if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma1,
   6492 				   &bin_entry, &data) < 0)
   6493 		goto error;
   6494 
   6495 	isl_union_pw_multi_aff_free(upma1);
   6496 	isl_union_pw_multi_aff_free(upma2);
   6497 	return data.res;
   6498 error:
   6499 	isl_union_pw_multi_aff_free(upma1);
   6500 	isl_union_pw_multi_aff_free(upma2);
   6501 	isl_union_pw_multi_aff_free(data.res);
   6502 	return NULL;
   6503 }
   6504 
   6505 /* Given two isl_pw_multi_affs A -> B and C -> D,
   6506  * construct an isl_pw_multi_aff (A * C) -> [B -> D].
   6507  */
   6508 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_product(
   6509 	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
   6510 {
   6511 	isl_space *space;
   6512 
   6513 	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
   6514 	space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1),
   6515 					isl_pw_multi_aff_get_space(pma2));
   6516 	return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space,
   6517 					    &isl_multi_aff_range_product);
   6518 }
   6519 
   6520 /* Given two isl_pw_multi_affs A -> B and C -> D,
   6521  * construct an isl_pw_multi_aff (A * C) -> (B, D).
   6522  */
   6523 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_flat_range_product(
   6524 	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
   6525 {
   6526 	isl_space *space;
   6527 
   6528 	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
   6529 	space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1),
   6530 					isl_pw_multi_aff_get_space(pma2));
   6531 	space = isl_space_flatten_range(space);
   6532 	return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space,
   6533 					    &isl_multi_aff_flat_range_product);
   6534 }
   6535 
   6536 /* If data->pma and "pma2" have the same domain space, then use "range_product"
   6537  * to compute some form of range product and add the result to data->res.
   6538  */
   6539 static isl_stat gen_range_product_entry(__isl_take isl_pw_multi_aff *pma2,
   6540 	__isl_give isl_pw_multi_aff *(*range_product)(
   6541 		__isl_take isl_pw_multi_aff *pma1,
   6542 		__isl_take isl_pw_multi_aff *pma2),
   6543 	void *user)
   6544 {
   6545 	struct isl_union_pw_multi_aff_bin_data *data = user;
   6546 	isl_bool match;
   6547 	isl_space *space1, *space2;
   6548 
   6549 	space1 = isl_pw_multi_aff_peek_space(data->pma);
   6550 	space2 = isl_pw_multi_aff_peek_space(pma2);
   6551 	match = isl_space_tuple_is_equal(space1, isl_dim_in,
   6552 					space2, isl_dim_in);
   6553 	if (match < 0 || !match) {
   6554 		isl_pw_multi_aff_free(pma2);
   6555 		return match < 0 ? isl_stat_error : isl_stat_ok;
   6556 	}
   6557 
   6558 	pma2 = range_product(isl_pw_multi_aff_copy(data->pma), pma2);
   6559 
   6560 	data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2);
   6561 
   6562 	return isl_stat_ok;
   6563 }
   6564 
   6565 /* If data->pma and "pma2" have the same domain space, then compute
   6566  * their flat range product and add the result to data->res.
   6567  */
   6568 static isl_stat flat_range_product_entry(__isl_take isl_pw_multi_aff *pma2,
   6569 	void *user)
   6570 {
   6571 	return gen_range_product_entry(pma2,
   6572 				&isl_pw_multi_aff_flat_range_product, user);
   6573 }
   6574 
   6575 /* Given two isl_union_pw_multi_affs A -> B and C -> D,
   6576  * construct an isl_union_pw_multi_aff (A * C) -> (B, D).
   6577  */
   6578 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_flat_range_product(
   6579 	__isl_take isl_union_pw_multi_aff *upma1,
   6580 	__isl_take isl_union_pw_multi_aff *upma2)
   6581 {
   6582 	return bin_op(upma1, upma2, &flat_range_product_entry);
   6583 }
   6584 
   6585 /* If data->pma and "pma2" have the same domain space, then compute
   6586  * their range product and add the result to data->res.
   6587  */
   6588 static isl_stat range_product_entry(__isl_take isl_pw_multi_aff *pma2,
   6589 	void *user)
   6590 {
   6591 	return gen_range_product_entry(pma2,
   6592 				&isl_pw_multi_aff_range_product, user);
   6593 }
   6594 
   6595 /* Given two isl_union_pw_multi_affs A -> B and C -> D,
   6596  * construct an isl_union_pw_multi_aff (A * C) -> [B -> D].
   6597  */
   6598 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_range_product(
   6599 	__isl_take isl_union_pw_multi_aff *upma1,
   6600 	__isl_take isl_union_pw_multi_aff *upma2)
   6601 {
   6602 	return bin_op(upma1, upma2, &range_product_entry);
   6603 }
   6604 
   6605 /* Replace the affine expressions at position "pos" in "pma" by "pa".
   6606  * The parameters are assumed to have been aligned.
   6607  *
   6608  * The implementation essentially performs an isl_pw_*_on_shared_domain,
   6609  * except that it works on two different isl_pw_* types.
   6610  */
   6611 static __isl_give isl_pw_multi_aff *pw_multi_aff_set_pw_aff(
   6612 	__isl_take isl_pw_multi_aff *pma, unsigned pos,
   6613 	__isl_take isl_pw_aff *pa)
   6614 {
   6615 	int i, j, n;
   6616 	isl_pw_multi_aff *res = NULL;
   6617 
   6618 	if (!pma || !pa)
   6619 		goto error;
   6620 
   6621 	if (!isl_space_tuple_is_equal(pma->dim, isl_dim_in,
   6622 					pa->dim, isl_dim_in))
   6623 		isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
   6624 			"domains don't match", goto error);
   6625 	if (isl_pw_multi_aff_check_range(pma, isl_dim_out, pos, 1) < 0)
   6626 		goto error;
   6627 
   6628 	n = pma->n * pa->n;
   6629 	res = isl_pw_multi_aff_alloc_size(isl_pw_multi_aff_get_space(pma), n);
   6630 
   6631 	for (i = 0; i < pma->n; ++i) {
   6632 		for (j = 0; j < pa->n; ++j) {
   6633 			isl_set *common;
   6634 			isl_multi_aff *res_ij;
   6635 			int empty;
   6636 
   6637 			common = isl_set_intersect(isl_set_copy(pma->p[i].set),
   6638 						   isl_set_copy(pa->p[j].set));
   6639 			empty = isl_set_plain_is_empty(common);
   6640 			if (empty < 0 || empty) {
   6641 				isl_set_free(common);
   6642 				if (empty < 0)
   6643 					goto error;
   6644 				continue;
   6645 			}
   6646 
   6647 			res_ij = isl_multi_aff_set_aff(
   6648 					isl_multi_aff_copy(pma->p[i].maff), pos,
   6649 					isl_aff_copy(pa->p[j].aff));
   6650 			res_ij = isl_multi_aff_gist(res_ij,
   6651 					isl_set_copy(common));
   6652 
   6653 			res = isl_pw_multi_aff_add_piece(res, common, res_ij);
   6654 		}
   6655 	}
   6656 
   6657 	isl_pw_multi_aff_free(pma);
   6658 	isl_pw_aff_free(pa);
   6659 	return res;
   6660 error:
   6661 	isl_pw_multi_aff_free(pma);
   6662 	isl_pw_aff_free(pa);
   6663 	return isl_pw_multi_aff_free(res);
   6664 }
   6665 
   6666 /* Replace the affine expressions at position "pos" in "pma" by "pa".
   6667  */
   6668 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_pw_aff(
   6669 	__isl_take isl_pw_multi_aff *pma, unsigned pos,
   6670 	__isl_take isl_pw_aff *pa)
   6671 {
   6672 	isl_bool equal_params;
   6673 
   6674 	if (!pma || !pa)
   6675 		goto error;
   6676 	equal_params = isl_space_has_equal_params(pma->dim, pa->dim);
   6677 	if (equal_params < 0)
   6678 		goto error;
   6679 	if (equal_params)
   6680 		return pw_multi_aff_set_pw_aff(pma, pos, pa);
   6681 	if (isl_pw_multi_aff_check_named_params(pma) < 0 ||
   6682 	    isl_pw_aff_check_named_params(pa) < 0)
   6683 		goto error;
   6684 	pma = isl_pw_multi_aff_align_params(pma, isl_pw_aff_get_space(pa));
   6685 	pa = isl_pw_aff_align_params(pa, isl_pw_multi_aff_get_space(pma));
   6686 	return pw_multi_aff_set_pw_aff(pma, pos, pa);
   6687 error:
   6688 	isl_pw_multi_aff_free(pma);
   6689 	isl_pw_aff_free(pa);
   6690 	return NULL;
   6691 }
   6692 
   6693 /* Do the parameters of "pa" match those of "space"?
   6694  */
   6695 isl_bool isl_pw_aff_matching_params(__isl_keep isl_pw_aff *pa,
   6696 	__isl_keep isl_space *space)
   6697 {
   6698 	isl_space *pa_space;
   6699 	isl_bool match;
   6700 
   6701 	if (!pa || !space)
   6702 		return isl_bool_error;
   6703 
   6704 	pa_space = isl_pw_aff_get_space(pa);
   6705 
   6706 	match = isl_space_has_equal_params(space, pa_space);
   6707 
   6708 	isl_space_free(pa_space);
   6709 	return match;
   6710 }
   6711 
   6712 /* Check that the domain space of "pa" matches "space".
   6713  */
   6714 isl_stat isl_pw_aff_check_match_domain_space(__isl_keep isl_pw_aff *pa,
   6715 	__isl_keep isl_space *space)
   6716 {
   6717 	isl_space *pa_space;
   6718 	isl_bool match;
   6719 
   6720 	if (!pa || !space)
   6721 		return isl_stat_error;
   6722 
   6723 	pa_space = isl_pw_aff_get_space(pa);
   6724 
   6725 	match = isl_space_has_equal_params(space, pa_space);
   6726 	if (match < 0)
   6727 		goto error;
   6728 	if (!match)
   6729 		isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
   6730 			"parameters don't match", goto error);
   6731 	match = isl_space_tuple_is_equal(space, isl_dim_in,
   6732 					pa_space, isl_dim_in);
   6733 	if (match < 0)
   6734 		goto error;
   6735 	if (!match)
   6736 		isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
   6737 			"domains don't match", goto error);
   6738 	isl_space_free(pa_space);
   6739 	return isl_stat_ok;
   6740 error:
   6741 	isl_space_free(pa_space);
   6742 	return isl_stat_error;
   6743 }
   6744 
   6745 #undef BASE
   6746 #define BASE pw_aff
   6747 #undef DOMBASE
   6748 #define DOMBASE set
   6749 
   6750 #include <isl_multi_explicit_domain.c>
   6751 #include <isl_multi_pw_aff_explicit_domain.c>
   6752 #include <isl_multi_templ.c>
   6753 #include <isl_multi_un_op_templ.c>
   6754 #include <isl_multi_bin_val_templ.c>
   6755 #include <isl_multi_add_constant_templ.c>
   6756 #include <isl_multi_align_set.c>
   6757 #include <isl_multi_apply_set_explicit_domain_templ.c>
   6758 #include <isl_multi_arith_templ.c>
   6759 #include <isl_multi_bind_templ.c>
   6760 #include <isl_multi_bind_domain_templ.c>
   6761 #include <isl_multi_coalesce.c>
   6762 #include <isl_multi_domain_templ.c>
   6763 #include <isl_multi_domain_reverse_templ.c>
   6764 #include <isl_multi_dim_id_templ.c>
   6765 #include <isl_multi_dims.c>
   6766 #include <isl_multi_from_base_templ.c>
   6767 #include <isl_multi_check_domain_templ.c>
   6768 #include <isl_multi_gist.c>
   6769 #include <isl_multi_hash.c>
   6770 #include <isl_multi_identity_templ.c>
   6771 #include <isl_multi_insert_domain_templ.c>
   6772 #include <isl_multi_intersect.c>
   6773 #include <isl_multi_min_max_templ.c>
   6774 #include <isl_multi_move_dims_templ.c>
   6775 #include <isl_multi_nan_templ.c>
   6776 #include <isl_multi_param_templ.c>
   6777 #include <isl_multi_product_templ.c>
   6778 #include <isl_multi_splice_templ.c>
   6779 #include <isl_multi_tuple_id_templ.c>
   6780 #include <isl_multi_union_add_templ.c>
   6781 #include <isl_multi_zero_templ.c>
   6782 #include <isl_multi_unbind_params_templ.c>
   6783 
   6784 /* Is every element of "mpa" defined over a single universe domain?
   6785  */
   6786 isl_bool isl_multi_pw_aff_isa_multi_aff(__isl_keep isl_multi_pw_aff *mpa)
   6787 {
   6788 	return isl_multi_pw_aff_every(mpa, &isl_pw_aff_isa_aff);
   6789 }
   6790 
   6791 /* Given that every element of "mpa" is defined over a single universe domain,
   6792  * return the corresponding base expressions.
   6793  */
   6794 __isl_give isl_multi_aff *isl_multi_pw_aff_as_multi_aff(
   6795 	__isl_take isl_multi_pw_aff *mpa)
   6796 {
   6797 	int i;
   6798 	isl_size n;
   6799 	isl_multi_aff *ma;
   6800 
   6801 	n = isl_multi_pw_aff_size(mpa);
   6802 	if (n < 0)
   6803 		mpa = isl_multi_pw_aff_free(mpa);
   6804 	ma = isl_multi_aff_alloc(isl_multi_pw_aff_get_space(mpa));
   6805 	for (i = 0; i < n; ++i) {
   6806 		isl_aff *aff;
   6807 
   6808 		aff = isl_pw_aff_as_aff(isl_multi_pw_aff_get_at(mpa, i));
   6809 		ma = isl_multi_aff_set_aff(ma, i, aff);
   6810 	}
   6811 	isl_multi_pw_aff_free(mpa);
   6812 	return ma;
   6813 }
   6814 
   6815 /* If "mpa" has an explicit domain, then intersect the domain of "map"
   6816  * with this explicit domain.
   6817  */
   6818 __isl_give isl_map *isl_map_intersect_multi_pw_aff_explicit_domain(
   6819 	__isl_take isl_map *map, __isl_keep isl_multi_pw_aff *mpa)
   6820 {
   6821 	isl_set *dom;
   6822 
   6823 	if (!isl_multi_pw_aff_has_explicit_domain(mpa))
   6824 		return map;
   6825 
   6826 	dom = isl_multi_pw_aff_domain(isl_multi_pw_aff_copy(mpa));
   6827 	map = isl_map_intersect_domain(map, dom);
   6828 
   6829 	return map;
   6830 }
   6831 
   6832 /* Are all elements of "mpa" piecewise constants?
   6833  */
   6834 isl_bool isl_multi_pw_aff_is_cst(__isl_keep isl_multi_pw_aff *mpa)
   6835 {
   6836 	return isl_multi_pw_aff_every(mpa, &isl_pw_aff_is_cst);
   6837 }
   6838 
   6839 /* Does "mpa" have a non-trivial explicit domain?
   6840  *
   6841  * The explicit domain, if present, is trivial if it represents
   6842  * an (obviously) universe set.
   6843  */
   6844 isl_bool isl_multi_pw_aff_has_non_trivial_domain(
   6845 	__isl_keep isl_multi_pw_aff *mpa)
   6846 {
   6847 	if (!mpa)
   6848 		return isl_bool_error;
   6849 	if (!isl_multi_pw_aff_has_explicit_domain(mpa))
   6850 		return isl_bool_false;
   6851 	return isl_bool_not(isl_set_plain_is_universe(mpa->u.dom));
   6852 }
   6853 
   6854 #undef BASE
   6855 #define BASE	set
   6856 
   6857 #include "isl_opt_mpa_templ.c"
   6858 
   6859 /* Compute the minima of the set dimensions as a function of the
   6860  * parameters, but independently of the other set dimensions.
   6861  */
   6862 __isl_give isl_multi_pw_aff *isl_set_min_multi_pw_aff(__isl_take isl_set *set)
   6863 {
   6864 	return set_opt_mpa(set, &isl_set_dim_min);
   6865 }
   6866 
   6867 /* Compute the maxima of the set dimensions as a function of the
   6868  * parameters, but independently of the other set dimensions.
   6869  */
   6870 __isl_give isl_multi_pw_aff *isl_set_max_multi_pw_aff(__isl_take isl_set *set)
   6871 {
   6872 	return set_opt_mpa(set, &isl_set_dim_max);
   6873 }
   6874 
   6875 #undef BASE
   6876 #define BASE	map
   6877 
   6878 #include "isl_opt_mpa_templ.c"
   6879 
   6880 /* Compute the minima of the output dimensions as a function of the
   6881  * parameters and input dimensions, but independently of
   6882  * the other output dimensions.
   6883  */
   6884 __isl_give isl_multi_pw_aff *isl_map_min_multi_pw_aff(__isl_take isl_map *map)
   6885 {
   6886 	return map_opt_mpa(map, &isl_map_dim_min);
   6887 }
   6888 
   6889 /* Compute the maxima of the output dimensions as a function of the
   6890  * parameters and input dimensions, but independently of
   6891  * the other output dimensions.
   6892  */
   6893 __isl_give isl_multi_pw_aff *isl_map_max_multi_pw_aff(__isl_take isl_map *map)
   6894 {
   6895 	return map_opt_mpa(map, &isl_map_dim_max);
   6896 }
   6897 
   6898 #undef TYPE
   6899 #define TYPE	isl_pw_multi_aff
   6900 #include "isl_type_check_match_range_multi_val.c"
   6901 
   6902 /* Apply "fn" to the base expressions of "pma" and "mv".
   6903  */
   6904 static __isl_give isl_pw_multi_aff *isl_pw_multi_aff_op_multi_val(
   6905 	__isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv,
   6906 	__isl_give isl_multi_aff *(*fn)(__isl_take isl_multi_aff *ma,
   6907 		__isl_take isl_multi_val *mv))
   6908 {
   6909 	int i;
   6910 	isl_size n;
   6911 
   6912 	if (isl_pw_multi_aff_check_match_range_multi_val(pma, mv) < 0)
   6913 		goto error;
   6914 
   6915 	n = isl_pw_multi_aff_n_piece(pma);
   6916 	if (n < 0)
   6917 		goto error;
   6918 
   6919 	for (i = 0; i < n; ++i) {
   6920 		isl_multi_aff *ma;
   6921 
   6922 		ma = isl_pw_multi_aff_take_base_at(pma, i);
   6923 		ma = fn(ma, isl_multi_val_copy(mv));
   6924 		pma = isl_pw_multi_aff_restore_base_at(pma, i, ma);
   6925 	}
   6926 
   6927 	isl_multi_val_free(mv);
   6928 	return pma;
   6929 error:
   6930 	isl_multi_val_free(mv);
   6931 	isl_pw_multi_aff_free(pma);
   6932 	return NULL;
   6933 }
   6934 
   6935 /* Scale the elements of "pma" by the corresponding elements of "mv".
   6936  */
   6937 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_multi_val(
   6938 	__isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv)
   6939 {
   6940 	return isl_pw_multi_aff_op_multi_val(pma, mv,
   6941 					&isl_multi_aff_scale_multi_val);
   6942 }
   6943 
   6944 /* Scale the elements of "pma" down by the corresponding elements of "mv".
   6945  */
   6946 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_down_multi_val(
   6947 	__isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv)
   6948 {
   6949 	return isl_pw_multi_aff_op_multi_val(pma, mv,
   6950 					&isl_multi_aff_scale_down_multi_val);
   6951 }
   6952 
   6953 /* This function is called for each entry of an isl_union_pw_multi_aff.
   6954  * If the space of the entry matches that of data->mv,
   6955  * then apply isl_pw_multi_aff_scale_multi_val and return the result.
   6956  * Otherwise, return an empty isl_pw_multi_aff.
   6957  */
   6958 static __isl_give isl_pw_multi_aff *union_pw_multi_aff_scale_multi_val_entry(
   6959 	__isl_take isl_pw_multi_aff *pma, void *user)
   6960 {
   6961 	isl_bool equal;
   6962 	isl_multi_val *mv = user;
   6963 
   6964 	equal = isl_pw_multi_aff_match_range_multi_val(pma, mv);
   6965 	if (equal < 0)
   6966 		return isl_pw_multi_aff_free(pma);
   6967 	if (!equal) {
   6968 		isl_space *space = isl_pw_multi_aff_get_space(pma);
   6969 		isl_pw_multi_aff_free(pma);
   6970 		return isl_pw_multi_aff_empty(space);
   6971 	}
   6972 
   6973 	return isl_pw_multi_aff_scale_multi_val(pma, isl_multi_val_copy(mv));
   6974 }
   6975 
   6976 /* Scale the elements of "upma" by the corresponding elements of "mv",
   6977  * for those entries that match the space of "mv".
   6978  */
   6979 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_multi_val(
   6980 	__isl_take isl_union_pw_multi_aff *upma, __isl_take isl_multi_val *mv)
   6981 {
   6982 	struct isl_union_pw_multi_aff_transform_control control = {
   6983 		.fn = &union_pw_multi_aff_scale_multi_val_entry,
   6984 		.fn_user = mv,
   6985 	};
   6986 
   6987 	upma = isl_union_pw_multi_aff_align_params(upma,
   6988 						isl_multi_val_get_space(mv));
   6989 	mv = isl_multi_val_align_params(mv,
   6990 					isl_union_pw_multi_aff_get_space(upma));
   6991 	if (!upma || !mv)
   6992 		goto error;
   6993 
   6994 	return isl_union_pw_multi_aff_transform(upma, &control);
   6995 
   6996 	isl_multi_val_free(mv);
   6997 	return upma;
   6998 error:
   6999 	isl_multi_val_free(mv);
   7000 	isl_union_pw_multi_aff_free(upma);
   7001 	return NULL;
   7002 }
   7003 
   7004 /* Construct and return a piecewise multi affine expression
   7005  * in the given space with value zero in each of the output dimensions and
   7006  * a universe domain.
   7007  */
   7008 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero(__isl_take isl_space *space)
   7009 {
   7010 	return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_zero(space));
   7011 }
   7012 
   7013 /* Construct and return a piecewise multi affine expression
   7014  * that is equal to the given piecewise affine expression.
   7015  */
   7016 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_pw_aff(
   7017 	__isl_take isl_pw_aff *pa)
   7018 {
   7019 	int i;
   7020 	isl_space *space;
   7021 	isl_pw_multi_aff *pma;
   7022 
   7023 	if (!pa)
   7024 		return NULL;
   7025 
   7026 	space = isl_pw_aff_get_space(pa);
   7027 	pma = isl_pw_multi_aff_alloc_size(space, pa->n);
   7028 
   7029 	for (i = 0; i < pa->n; ++i) {
   7030 		isl_set *set;
   7031 		isl_multi_aff *ma;
   7032 
   7033 		set = isl_set_copy(pa->p[i].set);
   7034 		ma = isl_multi_aff_from_aff(isl_aff_copy(pa->p[i].aff));
   7035 		pma = isl_pw_multi_aff_add_piece(pma, set, ma);
   7036 	}
   7037 
   7038 	isl_pw_aff_free(pa);
   7039 	return pma;
   7040 }
   7041 
   7042 /* Construct and return a piecewise multi affine expression
   7043  * that is equal to the given multi piecewise affine expression
   7044  * on the shared domain of the piecewise affine expressions,
   7045  * in the special case of a 0D multi piecewise affine expression.
   7046  *
   7047  * Create a piecewise multi affine expression with the explicit domain of
   7048  * the 0D multi piecewise affine expression as domain.
   7049  */
   7050 static __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff_0D(
   7051 	__isl_take isl_multi_pw_aff *mpa)
   7052 {
   7053 	isl_space *space;
   7054 	isl_set *dom;
   7055 	isl_multi_aff *ma;
   7056 
   7057 	space = isl_multi_pw_aff_get_space(mpa);
   7058 	dom = isl_multi_pw_aff_get_explicit_domain(mpa);
   7059 	isl_multi_pw_aff_free(mpa);
   7060 
   7061 	ma = isl_multi_aff_zero(space);
   7062 	return isl_pw_multi_aff_alloc(dom, ma);
   7063 }
   7064 
   7065 /* Construct and return a piecewise multi affine expression
   7066  * that is equal to the given multi piecewise affine expression
   7067  * on the shared domain of the piecewise affine expressions.
   7068  */
   7069 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff(
   7070 	__isl_take isl_multi_pw_aff *mpa)
   7071 {
   7072 	int i;
   7073 	isl_space *space;
   7074 	isl_pw_aff *pa;
   7075 	isl_pw_multi_aff *pma;
   7076 
   7077 	if (!mpa)
   7078 		return NULL;
   7079 
   7080 	if (mpa->n == 0)
   7081 		return isl_pw_multi_aff_from_multi_pw_aff_0D(mpa);
   7082 
   7083 	space = isl_multi_pw_aff_get_space(mpa);
   7084 	pa = isl_multi_pw_aff_get_pw_aff(mpa, 0);
   7085 	pma = isl_pw_multi_aff_from_pw_aff(pa);
   7086 
   7087 	for (i = 1; i < mpa->n; ++i) {
   7088 		isl_pw_multi_aff *pma_i;
   7089 
   7090 		pa = isl_multi_pw_aff_get_pw_aff(mpa, i);
   7091 		pma_i = isl_pw_multi_aff_from_pw_aff(pa);
   7092 		pma = isl_pw_multi_aff_range_product(pma, pma_i);
   7093 	}
   7094 
   7095 	pma = isl_pw_multi_aff_reset_space(pma, space);
   7096 
   7097 	isl_multi_pw_aff_free(mpa);
   7098 	return pma;
   7099 }
   7100 
   7101 /* Convenience function that constructs an isl_multi_pw_aff
   7102  * directly from an isl_aff.
   7103  */
   7104 __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_aff(__isl_take isl_aff *aff)
   7105 {
   7106 	return isl_multi_pw_aff_from_pw_aff(isl_pw_aff_from_aff(aff));
   7107 }
   7108 
   7109 /* Construct and return a multi piecewise affine expression
   7110  * that is equal to the given multi affine expression.
   7111  */
   7112 __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_multi_aff(
   7113 	__isl_take isl_multi_aff *ma)
   7114 {
   7115 	int i;
   7116 	isl_size n;
   7117 	isl_multi_pw_aff *mpa;
   7118 
   7119 	n = isl_multi_aff_dim(ma, isl_dim_out);
   7120 	if (n < 0)
   7121 		ma = isl_multi_aff_free(ma);
   7122 	if (!ma)
   7123 		return NULL;
   7124 
   7125 	mpa = isl_multi_pw_aff_alloc(isl_multi_aff_get_space(ma));
   7126 
   7127 	for (i = 0; i < n; ++i) {
   7128 		isl_pw_aff *pa;
   7129 
   7130 		pa = isl_pw_aff_from_aff(isl_multi_aff_get_aff(ma, i));
   7131 		mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa);
   7132 	}
   7133 
   7134 	isl_multi_aff_free(ma);
   7135 	return mpa;
   7136 }
   7137 
   7138 /* This function performs the same operation as isl_multi_pw_aff_from_multi_aff,
   7139  * but is considered as a function on an isl_multi_aff when exported.
   7140  */
   7141 __isl_give isl_multi_pw_aff *isl_multi_aff_to_multi_pw_aff(
   7142 	__isl_take isl_multi_aff *ma)
   7143 {
   7144 	return isl_multi_pw_aff_from_multi_aff(ma);
   7145 }
   7146 
   7147 /* Construct and return a multi piecewise affine expression
   7148  * that is equal to the given piecewise multi affine expression.
   7149  *
   7150  * If the resulting multi piecewise affine expression has
   7151  * an explicit domain, then assign it the domain of the input.
   7152  * In other cases, the domain is stored in the individual elements.
   7153  */
   7154 __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_multi_aff(
   7155 	__isl_take isl_pw_multi_aff *pma)
   7156 {
   7157 	int i;
   7158 	isl_size n;
   7159 	isl_space *space;
   7160 	isl_multi_pw_aff *mpa;
   7161 
   7162 	n = isl_pw_multi_aff_dim(pma, isl_dim_out);
   7163 	if (n < 0)
   7164 		pma = isl_pw_multi_aff_free(pma);
   7165 	space = isl_pw_multi_aff_get_space(pma);
   7166 	mpa = isl_multi_pw_aff_alloc(space);
   7167 
   7168 	for (i = 0; i < n; ++i) {
   7169 		isl_pw_aff *pa;
   7170 
   7171 		pa = isl_pw_multi_aff_get_pw_aff(pma, i);
   7172 		mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa);
   7173 	}
   7174 	if (isl_multi_pw_aff_has_explicit_domain(mpa)) {
   7175 		isl_set *dom;
   7176 
   7177 		dom = isl_pw_multi_aff_domain(isl_pw_multi_aff_copy(pma));
   7178 		mpa = isl_multi_pw_aff_intersect_domain(mpa, dom);
   7179 	}
   7180 
   7181 	isl_pw_multi_aff_free(pma);
   7182 	return mpa;
   7183 }
   7184 
   7185 /* This function performs the same operation as
   7186  * isl_multi_pw_aff_from_pw_multi_aff,
   7187  * but is considered as a function on an isl_pw_multi_aff when exported.
   7188  */
   7189 __isl_give isl_multi_pw_aff *isl_pw_multi_aff_to_multi_pw_aff(
   7190 	__isl_take isl_pw_multi_aff *pma)
   7191 {
   7192 	return isl_multi_pw_aff_from_pw_multi_aff(pma);
   7193 }
   7194 
   7195 /* Do "pa1" and "pa2" represent the same function?
   7196  *
   7197  * We first check if they are obviously equal.
   7198  * If not, we convert them to maps and check if those are equal.
   7199  *
   7200  * If "pa1" or "pa2" contain any NaNs, then they are considered
   7201  * not to be the same.  A NaN is not equal to anything, not even
   7202  * to another NaN.
   7203  */
   7204 isl_bool isl_pw_aff_is_equal(__isl_keep isl_pw_aff *pa1,
   7205 	__isl_keep isl_pw_aff *pa2)
   7206 {
   7207 	isl_bool equal;
   7208 	isl_bool has_nan;
   7209 	isl_map *map1, *map2;
   7210 
   7211 	if (!pa1 || !pa2)
   7212 		return isl_bool_error;
   7213 
   7214 	equal = isl_pw_aff_plain_is_equal(pa1, pa2);
   7215 	if (equal < 0 || equal)
   7216 		return equal;
   7217 	has_nan = either_involves_nan(pa1, pa2);
   7218 	if (has_nan < 0)
   7219 		return isl_bool_error;
   7220 	if (has_nan)
   7221 		return isl_bool_false;
   7222 
   7223 	map1 = isl_map_from_pw_aff_internal(isl_pw_aff_copy(pa1));
   7224 	map2 = isl_map_from_pw_aff_internal(isl_pw_aff_copy(pa2));
   7225 	equal = isl_map_is_equal(map1, map2);
   7226 	isl_map_free(map1);
   7227 	isl_map_free(map2);
   7228 
   7229 	return equal;
   7230 }
   7231 
   7232 /* Do "mpa1" and "mpa2" represent the same function?
   7233  *
   7234  * Note that we cannot convert the entire isl_multi_pw_aff
   7235  * to a map because the domains of the piecewise affine expressions
   7236  * may not be the same.
   7237  */
   7238 isl_bool isl_multi_pw_aff_is_equal(__isl_keep isl_multi_pw_aff *mpa1,
   7239 	__isl_keep isl_multi_pw_aff *mpa2)
   7240 {
   7241 	int i;
   7242 	isl_bool equal, equal_params;
   7243 
   7244 	if (!mpa1 || !mpa2)
   7245 		return isl_bool_error;
   7246 
   7247 	equal_params = isl_space_has_equal_params(mpa1->space, mpa2->space);
   7248 	if (equal_params < 0)
   7249 		return isl_bool_error;
   7250 	if (!equal_params) {
   7251 		if (!isl_space_has_named_params(mpa1->space))
   7252 			return isl_bool_false;
   7253 		if (!isl_space_has_named_params(mpa2->space))
   7254 			return isl_bool_false;
   7255 		mpa1 = isl_multi_pw_aff_copy(mpa1);
   7256 		mpa2 = isl_multi_pw_aff_copy(mpa2);
   7257 		mpa1 = isl_multi_pw_aff_align_params(mpa1,
   7258 					    isl_multi_pw_aff_get_space(mpa2));
   7259 		mpa2 = isl_multi_pw_aff_align_params(mpa2,
   7260 					    isl_multi_pw_aff_get_space(mpa1));
   7261 		equal = isl_multi_pw_aff_is_equal(mpa1, mpa2);
   7262 		isl_multi_pw_aff_free(mpa1);
   7263 		isl_multi_pw_aff_free(mpa2);
   7264 		return equal;
   7265 	}
   7266 
   7267 	equal = isl_space_is_equal(mpa1->space, mpa2->space);
   7268 	if (equal < 0 || !equal)
   7269 		return equal;
   7270 
   7271 	for (i = 0; i < mpa1->n; ++i) {
   7272 		equal = isl_pw_aff_is_equal(mpa1->u.p[i], mpa2->u.p[i]);
   7273 		if (equal < 0 || !equal)
   7274 			return equal;
   7275 	}
   7276 
   7277 	return isl_bool_true;
   7278 }
   7279 
   7280 /* Do "pma1" and "pma2" represent the same function?
   7281  *
   7282  * First check if they are obviously equal.
   7283  * If not, then convert them to maps and check if those are equal.
   7284  *
   7285  * If "pa1" or "pa2" contain any NaNs, then they are considered
   7286  * not to be the same.  A NaN is not equal to anything, not even
   7287  * to another NaN.
   7288  */
   7289 isl_bool isl_pw_multi_aff_is_equal(__isl_keep isl_pw_multi_aff *pma1,
   7290 	__isl_keep isl_pw_multi_aff *pma2)
   7291 {
   7292 	isl_bool equal;
   7293 	isl_bool has_nan;
   7294 	isl_map *map1, *map2;
   7295 
   7296 	if (!pma1 || !pma2)
   7297 		return isl_bool_error;
   7298 
   7299 	equal = isl_pw_multi_aff_plain_is_equal(pma1, pma2);
   7300 	if (equal < 0 || equal)
   7301 		return equal;
   7302 	has_nan = isl_pw_multi_aff_involves_nan(pma1);
   7303 	if (has_nan >= 0 && !has_nan)
   7304 		has_nan = isl_pw_multi_aff_involves_nan(pma2);
   7305 	if (has_nan < 0 || has_nan)
   7306 		return isl_bool_not(has_nan);
   7307 
   7308 	map1 = isl_map_from_pw_multi_aff_internal(isl_pw_multi_aff_copy(pma1));
   7309 	map2 = isl_map_from_pw_multi_aff_internal(isl_pw_multi_aff_copy(pma2));
   7310 	equal = isl_map_is_equal(map1, map2);
   7311 	isl_map_free(map1);
   7312 	isl_map_free(map2);
   7313 
   7314 	return equal;
   7315 }
   7316 
   7317 #undef BASE
   7318 #define BASE	multi_aff
   7319 
   7320 #include "isl_multi_pw_aff_pullback_templ.c"
   7321 
   7322 #undef BASE
   7323 #define BASE	pw_multi_aff
   7324 
   7325 #include "isl_multi_pw_aff_pullback_templ.c"
   7326 
   7327 /* Apply "aff" to "mpa".  The range of "mpa" needs to be compatible
   7328  * with the domain of "aff".  The domain of the result is the same
   7329  * as that of "mpa".
   7330  * "mpa" and "aff" are assumed to have been aligned.
   7331  *
   7332  * We first extract the parametric constant from "aff", defined
   7333  * over the correct domain.
   7334  * Then we add the appropriate combinations of the members of "mpa".
   7335  * Finally, we add the integer divisions through recursive calls.
   7336  */
   7337 static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff_aligned(
   7338 	__isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff)
   7339 {
   7340 	int i;
   7341 	isl_size n_in, n_div, n_mpa_in;
   7342 	isl_space *space;
   7343 	isl_val *v;
   7344 	isl_pw_aff *pa;
   7345 	isl_aff *tmp;
   7346 
   7347 	n_in = isl_aff_dim(aff, isl_dim_in);
   7348 	n_div = isl_aff_dim(aff, isl_dim_div);
   7349 	n_mpa_in = isl_multi_pw_aff_dim(mpa, isl_dim_in);
   7350 	if (n_in < 0 || n_div < 0 || n_mpa_in < 0)
   7351 		goto error;
   7352 
   7353 	space = isl_space_domain(isl_multi_pw_aff_get_space(mpa));
   7354 	tmp = isl_aff_copy(aff);
   7355 	tmp = isl_aff_drop_dims(tmp, isl_dim_div, 0, n_div);
   7356 	tmp = isl_aff_drop_dims(tmp, isl_dim_in, 0, n_in);
   7357 	tmp = isl_aff_add_dims(tmp, isl_dim_in, n_mpa_in);
   7358 	tmp = isl_aff_reset_domain_space(tmp, space);
   7359 	pa = isl_pw_aff_from_aff(tmp);
   7360 
   7361 	for (i = 0; i < n_in; ++i) {
   7362 		isl_pw_aff *pa_i;
   7363 
   7364 		if (!isl_aff_involves_dims(aff, isl_dim_in, i, 1))
   7365 			continue;
   7366 		v = isl_aff_get_coefficient_val(aff, isl_dim_in, i);
   7367 		pa_i = isl_multi_pw_aff_get_pw_aff(mpa, i);
   7368 		pa_i = isl_pw_aff_scale_val(pa_i, v);
   7369 		pa = isl_pw_aff_add(pa, pa_i);
   7370 	}
   7371 
   7372 	for (i = 0; i < n_div; ++i) {
   7373 		isl_aff *div;
   7374 		isl_pw_aff *pa_i;
   7375 
   7376 		if (!isl_aff_involves_dims(aff, isl_dim_div, i, 1))
   7377 			continue;
   7378 		div = isl_aff_get_div(aff, i);
   7379 		pa_i = isl_multi_pw_aff_apply_aff_aligned(
   7380 					    isl_multi_pw_aff_copy(mpa), div);
   7381 		pa_i = isl_pw_aff_floor(pa_i);
   7382 		v = isl_aff_get_coefficient_val(aff, isl_dim_div, i);
   7383 		pa_i = isl_pw_aff_scale_val(pa_i, v);
   7384 		pa = isl_pw_aff_add(pa, pa_i);
   7385 	}
   7386 
   7387 	isl_multi_pw_aff_free(mpa);
   7388 	isl_aff_free(aff);
   7389 
   7390 	return pa;
   7391 error:
   7392 	isl_multi_pw_aff_free(mpa);
   7393 	isl_aff_free(aff);
   7394 	return NULL;
   7395 }
   7396 
   7397 /* Apply "aff" to "mpa".  The range of "mpa" needs to be compatible
   7398  * with the domain of "aff".  The domain of the result is the same
   7399  * as that of "mpa".
   7400  */
   7401 __isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff(
   7402 	__isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff)
   7403 {
   7404 	isl_bool equal_params;
   7405 
   7406 	if (!aff || !mpa)
   7407 		goto error;
   7408 	equal_params = isl_space_has_equal_params(aff->ls->dim, mpa->space);
   7409 	if (equal_params < 0)
   7410 		goto error;
   7411 	if (equal_params)
   7412 		return isl_multi_pw_aff_apply_aff_aligned(mpa, aff);
   7413 
   7414 	aff = isl_aff_align_params(aff, isl_multi_pw_aff_get_space(mpa));
   7415 	mpa = isl_multi_pw_aff_align_params(mpa, isl_aff_get_space(aff));
   7416 
   7417 	return isl_multi_pw_aff_apply_aff_aligned(mpa, aff);
   7418 error:
   7419 	isl_aff_free(aff);
   7420 	isl_multi_pw_aff_free(mpa);
   7421 	return NULL;
   7422 }
   7423 
   7424 /* Apply "pa" to "mpa".  The range of "mpa" needs to be compatible
   7425  * with the domain of "pa".  The domain of the result is the same
   7426  * as that of "mpa".
   7427  * "mpa" and "pa" are assumed to have been aligned.
   7428  *
   7429  * We consider each piece in turn.  Note that the domains of the
   7430  * pieces are assumed to be disjoint and they remain disjoint
   7431  * after taking the preimage (over the same function).
   7432  */
   7433 static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff_aligned(
   7434 	__isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa)
   7435 {
   7436 	isl_space *space;
   7437 	isl_pw_aff *res;
   7438 	int i;
   7439 
   7440 	if (!mpa || !pa)
   7441 		goto error;
   7442 
   7443 	space = isl_space_join(isl_multi_pw_aff_get_space(mpa),
   7444 				isl_pw_aff_get_space(pa));
   7445 	res = isl_pw_aff_empty(space);
   7446 
   7447 	for (i = 0; i < pa->n; ++i) {
   7448 		isl_pw_aff *pa_i;
   7449 		isl_set *domain;
   7450 
   7451 		pa_i = isl_multi_pw_aff_apply_aff_aligned(
   7452 					isl_multi_pw_aff_copy(mpa),
   7453 					isl_aff_copy(pa->p[i].aff));
   7454 		domain = isl_set_copy(pa->p[i].set);
   7455 		domain = isl_set_preimage_multi_pw_aff(domain,
   7456 					isl_multi_pw_aff_copy(mpa));
   7457 		pa_i = isl_pw_aff_intersect_domain(pa_i, domain);
   7458 		res = isl_pw_aff_add_disjoint(res, pa_i);
   7459 	}
   7460 
   7461 	isl_pw_aff_free(pa);
   7462 	isl_multi_pw_aff_free(mpa);
   7463 	return res;
   7464 error:
   7465 	isl_pw_aff_free(pa);
   7466 	isl_multi_pw_aff_free(mpa);
   7467 	return NULL;
   7468 }
   7469 
   7470 /* Apply "pa" to "mpa".  The range of "mpa" needs to be compatible
   7471  * with the domain of "pa".  The domain of the result is the same
   7472  * as that of "mpa".
   7473  */
   7474 __isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff(
   7475 	__isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa)
   7476 {
   7477 	isl_bool equal_params;
   7478 
   7479 	if (!pa || !mpa)
   7480 		goto error;
   7481 	equal_params = isl_space_has_equal_params(pa->dim, mpa->space);
   7482 	if (equal_params < 0)
   7483 		goto error;
   7484 	if (equal_params)
   7485 		return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa);
   7486 
   7487 	pa = isl_pw_aff_align_params(pa, isl_multi_pw_aff_get_space(mpa));
   7488 	mpa = isl_multi_pw_aff_align_params(mpa, isl_pw_aff_get_space(pa));
   7489 
   7490 	return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa);
   7491 error:
   7492 	isl_pw_aff_free(pa);
   7493 	isl_multi_pw_aff_free(mpa);
   7494 	return NULL;
   7495 }
   7496 
   7497 /* Compute the pullback of "pa" by the function represented by "mpa".
   7498  * In other words, plug in "mpa" in "pa".
   7499  *
   7500  * The pullback is computed by applying "pa" to "mpa".
   7501  */
   7502 __isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff(
   7503 	__isl_take isl_pw_aff *pa, __isl_take isl_multi_pw_aff *mpa)
   7504 {
   7505 	return isl_multi_pw_aff_apply_pw_aff(mpa, pa);
   7506 }
   7507 
   7508 #undef BASE
   7509 #define BASE	multi_pw_aff
   7510 
   7511 #include "isl_multi_pw_aff_pullback_templ.c"
   7512 
   7513 /* Align the parameters of "mpa1" and "mpa2", check that the ranges
   7514  * of "mpa1" and "mpa2" live in the same space, construct map space
   7515  * between the domain spaces of "mpa1" and "mpa2" and call "order"
   7516  * with this map space as extract argument.
   7517  */
   7518 static __isl_give isl_map *isl_multi_pw_aff_order_map(
   7519 	__isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2,
   7520 	__isl_give isl_map *(*order)(__isl_keep isl_multi_pw_aff *mpa1,
   7521 		__isl_keep isl_multi_pw_aff *mpa2, __isl_take isl_space *space))
   7522 {
   7523 	int match;
   7524 	isl_space *space1, *space2;
   7525 	isl_map *res;
   7526 
   7527 	mpa1 = isl_multi_pw_aff_align_params(mpa1,
   7528 					    isl_multi_pw_aff_get_space(mpa2));
   7529 	mpa2 = isl_multi_pw_aff_align_params(mpa2,
   7530 					    isl_multi_pw_aff_get_space(mpa1));
   7531 	if (!mpa1 || !mpa2)
   7532 		goto error;
   7533 	match = isl_space_tuple_is_equal(mpa1->space, isl_dim_out,
   7534 					mpa2->space, isl_dim_out);
   7535 	if (match < 0)
   7536 		goto error;
   7537 	if (!match)
   7538 		isl_die(isl_multi_pw_aff_get_ctx(mpa1), isl_error_invalid,
   7539 			"range spaces don't match", goto error);
   7540 	space1 = isl_space_domain(isl_multi_pw_aff_get_space(mpa1));
   7541 	space2 = isl_space_domain(isl_multi_pw_aff_get_space(mpa2));
   7542 	space1 = isl_space_map_from_domain_and_range(space1, space2);
   7543 
   7544 	res = order(mpa1, mpa2, space1);
   7545 	isl_multi_pw_aff_free(mpa1);
   7546 	isl_multi_pw_aff_free(mpa2);
   7547 	return res;
   7548 error:
   7549 	isl_multi_pw_aff_free(mpa1);
   7550 	isl_multi_pw_aff_free(mpa2);
   7551 	return NULL;
   7552 }
   7553 
   7554 /* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
   7555  * where the function values are equal.  "space" is the space of the result.
   7556  * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
   7557  *
   7558  * "mpa1" and "mpa2" are equal when each of the pairs of elements
   7559  * in the sequences are equal.
   7560  */
   7561 static __isl_give isl_map *isl_multi_pw_aff_eq_map_on_space(
   7562 	__isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2,
   7563 	__isl_take isl_space *space)
   7564 {
   7565 	int i;
   7566 	isl_size n;
   7567 	isl_map *res;
   7568 
   7569 	n = isl_multi_pw_aff_dim(mpa1, isl_dim_out);
   7570 	if (n < 0)
   7571 		space = isl_space_free(space);
   7572 	res = isl_map_universe(space);
   7573 
   7574 	for (i = 0; i < n; ++i) {
   7575 		isl_pw_aff *pa1, *pa2;
   7576 		isl_map *map;
   7577 
   7578 		pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i);
   7579 		pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i);
   7580 		map = isl_pw_aff_eq_map(pa1, pa2);
   7581 		res = isl_map_intersect(res, map);
   7582 	}
   7583 
   7584 	return res;
   7585 }
   7586 
   7587 /* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
   7588  * where the function values are equal.
   7589  */
   7590 __isl_give isl_map *isl_multi_pw_aff_eq_map(__isl_take isl_multi_pw_aff *mpa1,
   7591 	__isl_take isl_multi_pw_aff *mpa2)
   7592 {
   7593 	return isl_multi_pw_aff_order_map(mpa1, mpa2,
   7594 					    &isl_multi_pw_aff_eq_map_on_space);
   7595 }
   7596 
   7597 /* Intersect "map" with the result of applying "order"
   7598  * on two copies of "mpa".
   7599  */
   7600 static __isl_give isl_map *isl_map_order_at_multi_pw_aff(
   7601 	__isl_take isl_map *map, __isl_take isl_multi_pw_aff *mpa,
   7602 	__isl_give isl_map *(*order)(__isl_take isl_multi_pw_aff *mpa1,
   7603 		__isl_take isl_multi_pw_aff *mpa2))
   7604 {
   7605 	return isl_map_intersect(map, order(mpa, isl_multi_pw_aff_copy(mpa)));
   7606 }
   7607 
   7608 /* Return the subset of "map" where the domain and the range
   7609  * have equal "mpa" values.
   7610  */
   7611 __isl_give isl_map *isl_map_eq_at_multi_pw_aff(__isl_take isl_map *map,
   7612 	__isl_take isl_multi_pw_aff *mpa)
   7613 {
   7614 	return isl_map_order_at_multi_pw_aff(map, mpa,
   7615 						&isl_multi_pw_aff_eq_map);
   7616 }
   7617 
   7618 /* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
   7619  * where the function values of "mpa1" lexicographically satisfies
   7620  * "strict_base"/"base" compared to that of "mpa2".
   7621  * "space" is the space of the result.
   7622  * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
   7623  *
   7624  * "mpa1" lexicographically satisfies "strict_base"/"base" compared to "mpa2"
   7625  * if, for some i, the i-th element of "mpa1" satisfies "strict_base"/"base"
   7626  * when compared to the i-th element of "mpa2" while all previous elements are
   7627  * pairwise equal.
   7628  * In particular, if i corresponds to the final elements
   7629  * then they need to satisfy "base", while "strict_base" needs to be satisfied
   7630  * for other values of i.
   7631  * If "base" is a strict order, then "base" and "strict_base" are the same.
   7632  */
   7633 static __isl_give isl_map *isl_multi_pw_aff_lex_map_on_space(
   7634 	__isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2,
   7635 	__isl_give isl_map *(*strict_base)(__isl_take isl_pw_aff *pa1,
   7636 		__isl_take isl_pw_aff *pa2),
   7637 	__isl_give isl_map *(*base)(__isl_take isl_pw_aff *pa1,
   7638 		__isl_take isl_pw_aff *pa2),
   7639 	__isl_take isl_space *space)
   7640 {
   7641 	int i;
   7642 	isl_size n;
   7643 	isl_map *res, *rest;
   7644 
   7645 	n = isl_multi_pw_aff_dim(mpa1, isl_dim_out);
   7646 	if (n < 0)
   7647 		space = isl_space_free(space);
   7648 	res = isl_map_empty(isl_space_copy(space));
   7649 	rest = isl_map_universe(space);
   7650 
   7651 	for (i = 0; i < n; ++i) {
   7652 		int last;
   7653 		isl_pw_aff *pa1, *pa2;
   7654 		isl_map *map;
   7655 
   7656 		last = i == n - 1;
   7657 
   7658 		pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i);
   7659 		pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i);
   7660 		map = last ? base(pa1, pa2) : strict_base(pa1, pa2);
   7661 		map = isl_map_intersect(map, isl_map_copy(rest));
   7662 		res = isl_map_union(res, map);
   7663 
   7664 		if (last)
   7665 			continue;
   7666 
   7667 		pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i);
   7668 		pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i);
   7669 		map = isl_pw_aff_eq_map(pa1, pa2);
   7670 		rest = isl_map_intersect(rest, map);
   7671 	}
   7672 
   7673 	isl_map_free(rest);
   7674 	return res;
   7675 }
   7676 
   7677 #undef ORDER
   7678 #define ORDER		le
   7679 #undef STRICT_ORDER
   7680 #define STRICT_ORDER	lt
   7681 #include "isl_aff_lex_templ.c"
   7682 
   7683 #undef ORDER
   7684 #define ORDER		lt
   7685 #undef STRICT_ORDER
   7686 #define STRICT_ORDER	lt
   7687 #include "isl_aff_lex_templ.c"
   7688 
   7689 #undef ORDER
   7690 #define ORDER		ge
   7691 #undef STRICT_ORDER
   7692 #define STRICT_ORDER	gt
   7693 #include "isl_aff_lex_templ.c"
   7694 
   7695 #undef ORDER
   7696 #define ORDER		gt
   7697 #undef STRICT_ORDER
   7698 #define STRICT_ORDER	gt
   7699 #include "isl_aff_lex_templ.c"
   7700 
   7701 /* Compare two isl_affs.
   7702  *
   7703  * Return -1 if "aff1" is "smaller" than "aff2", 1 if "aff1" is "greater"
   7704  * than "aff2" and 0 if they are equal.
   7705  *
   7706  * The order is fairly arbitrary.  We do consider expressions that only involve
   7707  * earlier dimensions as "smaller".
   7708  */
   7709 int isl_aff_plain_cmp(__isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2)
   7710 {
   7711 	int cmp;
   7712 	int last1, last2;
   7713 
   7714 	if (aff1 == aff2)
   7715 		return 0;
   7716 
   7717 	if (!aff1)
   7718 		return -1;
   7719 	if (!aff2)
   7720 		return 1;
   7721 
   7722 	cmp = isl_local_space_cmp(aff1->ls, aff2->ls);
   7723 	if (cmp != 0)
   7724 		return cmp;
   7725 
   7726 	last1 = isl_seq_last_non_zero(aff1->v->el + 1, aff1->v->size - 1);
   7727 	last2 = isl_seq_last_non_zero(aff2->v->el + 1, aff1->v->size - 1);
   7728 	if (last1 != last2)
   7729 		return last1 - last2;
   7730 
   7731 	return isl_seq_cmp(aff1->v->el, aff2->v->el, aff1->v->size);
   7732 }
   7733 
   7734 /* Compare two isl_pw_affs.
   7735  *
   7736  * Return -1 if "pa1" is "smaller" than "pa2", 1 if "pa1" is "greater"
   7737  * than "pa2" and 0 if they are equal.
   7738  *
   7739  * The order is fairly arbitrary.  We do consider expressions that only involve
   7740  * earlier dimensions as "smaller".
   7741  */
   7742 int isl_pw_aff_plain_cmp(__isl_keep isl_pw_aff *pa1,
   7743 	__isl_keep isl_pw_aff *pa2)
   7744 {
   7745 	int i;
   7746 	int cmp;
   7747 
   7748 	if (pa1 == pa2)
   7749 		return 0;
   7750 
   7751 	if (!pa1)
   7752 		return -1;
   7753 	if (!pa2)
   7754 		return 1;
   7755 
   7756 	cmp = isl_space_cmp(pa1->dim, pa2->dim);
   7757 	if (cmp != 0)
   7758 		return cmp;
   7759 
   7760 	if (pa1->n != pa2->n)
   7761 		return pa1->n - pa2->n;
   7762 
   7763 	for (i = 0; i < pa1->n; ++i) {
   7764 		cmp = isl_set_plain_cmp(pa1->p[i].set, pa2->p[i].set);
   7765 		if (cmp != 0)
   7766 			return cmp;
   7767 		cmp = isl_aff_plain_cmp(pa1->p[i].aff, pa2->p[i].aff);
   7768 		if (cmp != 0)
   7769 			return cmp;
   7770 	}
   7771 
   7772 	return 0;
   7773 }
   7774 
   7775 /* Return a piecewise affine expression that is equal to "v" on "domain".
   7776  */
   7777 __isl_give isl_pw_aff *isl_pw_aff_val_on_domain(__isl_take isl_set *domain,
   7778 	__isl_take isl_val *v)
   7779 {
   7780 	isl_space *space;
   7781 	isl_local_space *ls;
   7782 	isl_aff *aff;
   7783 
   7784 	space = isl_set_get_space(domain);
   7785 	ls = isl_local_space_from_space(space);
   7786 	aff = isl_aff_val_on_domain(ls, v);
   7787 
   7788 	return isl_pw_aff_alloc(domain, aff);
   7789 }
   7790 
   7791 /* This function performs the same operation as isl_pw_aff_val_on_domain,
   7792  * but is considered as a function on an isl_set when exported.
   7793  */
   7794 __isl_give isl_pw_aff *isl_set_pw_aff_on_domain_val(__isl_take isl_set *domain,
   7795 	__isl_take isl_val *v)
   7796 {
   7797 	return isl_pw_aff_val_on_domain(domain, v);
   7798 }
   7799 
   7800 /* Return a piecewise affine expression that is equal to the parameter
   7801  * with identifier "id" on "domain".
   7802  */
   7803 __isl_give isl_pw_aff *isl_pw_aff_param_on_domain_id(
   7804 	__isl_take isl_set *domain, __isl_take isl_id *id)
   7805 {
   7806 	isl_space *space;
   7807 	isl_aff *aff;
   7808 
   7809 	space = isl_set_get_space(domain);
   7810 	space = isl_space_add_param_id(space, isl_id_copy(id));
   7811 	domain = isl_set_align_params(domain, isl_space_copy(space));
   7812 	aff = isl_aff_param_on_domain_space_id(space, id);
   7813 
   7814 	return isl_pw_aff_alloc(domain, aff);
   7815 }
   7816 
   7817 /* This function performs the same operation as
   7818  * isl_pw_aff_param_on_domain_id,
   7819  * but is considered as a function on an isl_set when exported.
   7820  */
   7821 __isl_give isl_pw_aff *isl_set_param_pw_aff_on_domain_id(
   7822 	__isl_take isl_set *domain, __isl_take isl_id *id)
   7823 {
   7824 	return isl_pw_aff_param_on_domain_id(domain, id);
   7825 }
   7826 
   7827 /* Return a multi affine expression that is equal to "mv" on domain
   7828  * space "space".
   7829  */
   7830 __isl_give isl_multi_aff *isl_multi_aff_multi_val_on_domain_space(
   7831 	__isl_take isl_space *space, __isl_take isl_multi_val *mv)
   7832 {
   7833 	int i;
   7834 	isl_size n;
   7835 	isl_space *space2;
   7836 	isl_local_space *ls;
   7837 	isl_multi_aff *ma;
   7838 
   7839 	n = isl_multi_val_dim(mv, isl_dim_set);
   7840 	if (!space || n < 0)
   7841 		goto error;
   7842 
   7843 	space2 = isl_multi_val_get_space(mv);
   7844 	space2 = isl_space_align_params(space2, isl_space_copy(space));
   7845 	space = isl_space_align_params(space, isl_space_copy(space2));
   7846 	space = isl_space_map_from_domain_and_range(space, space2);
   7847 	ma = isl_multi_aff_alloc(isl_space_copy(space));
   7848 	ls = isl_local_space_from_space(isl_space_domain(space));
   7849 	for (i = 0; i < n; ++i) {
   7850 		isl_val *v;
   7851 		isl_aff *aff;
   7852 
   7853 		v = isl_multi_val_get_val(mv, i);
   7854 		aff = isl_aff_val_on_domain(isl_local_space_copy(ls), v);
   7855 		ma = isl_multi_aff_set_aff(ma, i, aff);
   7856 	}
   7857 	isl_local_space_free(ls);
   7858 
   7859 	isl_multi_val_free(mv);
   7860 	return ma;
   7861 error:
   7862 	isl_space_free(space);
   7863 	isl_multi_val_free(mv);
   7864 	return NULL;
   7865 }
   7866 
   7867 /* This is an alternative name for the function above.
   7868  */
   7869 __isl_give isl_multi_aff *isl_multi_aff_multi_val_on_space(
   7870 	__isl_take isl_space *space, __isl_take isl_multi_val *mv)
   7871 {
   7872 	return isl_multi_aff_multi_val_on_domain_space(space, mv);
   7873 }
   7874 
   7875 /* This function performs the same operation as
   7876  * isl_multi_aff_multi_val_on_domain_space,
   7877  * but is considered as a function on an isl_space when exported.
   7878  */
   7879 __isl_give isl_multi_aff *isl_space_multi_aff_on_domain_multi_val(
   7880 	__isl_take isl_space *space, __isl_take isl_multi_val *mv)
   7881 {
   7882 	return isl_multi_aff_multi_val_on_domain_space(space, mv);
   7883 }
   7884 
   7885 /* Return a piecewise multi-affine expression
   7886  * that is equal to "mv" on "domain".
   7887  */
   7888 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_multi_val_on_domain(
   7889 	__isl_take isl_set *domain, __isl_take isl_multi_val *mv)
   7890 {
   7891 	isl_space *space;
   7892 	isl_multi_aff *ma;
   7893 
   7894 	space = isl_set_get_space(domain);
   7895 	ma = isl_multi_aff_multi_val_on_space(space, mv);
   7896 
   7897 	return isl_pw_multi_aff_alloc(domain, ma);
   7898 }
   7899 
   7900 /* This function performs the same operation as
   7901  * isl_pw_multi_aff_multi_val_on_domain,
   7902  * but is considered as a function on an isl_set when exported.
   7903  */
   7904 __isl_give isl_pw_multi_aff *isl_set_pw_multi_aff_on_domain_multi_val(
   7905 	__isl_take isl_set *domain, __isl_take isl_multi_val *mv)
   7906 {
   7907 	return isl_pw_multi_aff_multi_val_on_domain(domain, mv);
   7908 }
   7909 
   7910 /* Internal data structure for isl_union_pw_multi_aff_multi_val_on_domain.
   7911  * mv is the value that should be attained on each domain set
   7912  * res collects the results
   7913  */
   7914 struct isl_union_pw_multi_aff_multi_val_on_domain_data {
   7915 	isl_multi_val *mv;
   7916 	isl_union_pw_multi_aff *res;
   7917 };
   7918 
   7919 /* Create an isl_pw_multi_aff equal to data->mv on "domain"
   7920  * and add it to data->res.
   7921  */
   7922 static isl_stat pw_multi_aff_multi_val_on_domain(__isl_take isl_set *domain,
   7923 	void *user)
   7924 {
   7925 	struct isl_union_pw_multi_aff_multi_val_on_domain_data *data = user;
   7926 	isl_pw_multi_aff *pma;
   7927 	isl_multi_val *mv;
   7928 
   7929 	mv = isl_multi_val_copy(data->mv);
   7930 	pma = isl_pw_multi_aff_multi_val_on_domain(domain, mv);
   7931 	data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma);
   7932 
   7933 	return data->res ? isl_stat_ok : isl_stat_error;
   7934 }
   7935 
   7936 /* Return a union piecewise multi-affine expression
   7937  * that is equal to "mv" on "domain".
   7938  */
   7939 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_multi_val_on_domain(
   7940 	__isl_take isl_union_set *domain, __isl_take isl_multi_val *mv)
   7941 {
   7942 	struct isl_union_pw_multi_aff_multi_val_on_domain_data data;
   7943 	isl_space *space;
   7944 
   7945 	space = isl_union_set_get_space(domain);
   7946 	data.res = isl_union_pw_multi_aff_empty(space);
   7947 	data.mv = mv;
   7948 	if (isl_union_set_foreach_set(domain,
   7949 			&pw_multi_aff_multi_val_on_domain, &data) < 0)
   7950 		data.res = isl_union_pw_multi_aff_free(data.res);
   7951 	isl_union_set_free(domain);
   7952 	isl_multi_val_free(mv);
   7953 	return data.res;
   7954 }
   7955 
   7956 /* Compute the pullback of data->pma by the function represented by "pma2",
   7957  * provided the spaces match, and add the results to data->res.
   7958  */
   7959 static isl_stat pullback_entry(__isl_take isl_pw_multi_aff *pma2, void *user)
   7960 {
   7961 	struct isl_union_pw_multi_aff_bin_data *data = user;
   7962 
   7963 	if (!isl_space_tuple_is_equal(data->pma->dim, isl_dim_in,
   7964 				 pma2->dim, isl_dim_out)) {
   7965 		isl_pw_multi_aff_free(pma2);
   7966 		return isl_stat_ok;
   7967 	}
   7968 
   7969 	pma2 = isl_pw_multi_aff_pullback_pw_multi_aff(
   7970 					isl_pw_multi_aff_copy(data->pma), pma2);
   7971 
   7972 	data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2);
   7973 	if (!data->res)
   7974 		return isl_stat_error;
   7975 
   7976 	return isl_stat_ok;
   7977 }
   7978 
   7979 /* Compute the pullback of "upma1" by the function represented by "upma2".
   7980  */
   7981 __isl_give isl_union_pw_multi_aff *
   7982 isl_union_pw_multi_aff_pullback_union_pw_multi_aff(
   7983 	__isl_take isl_union_pw_multi_aff *upma1,
   7984 	__isl_take isl_union_pw_multi_aff *upma2)
   7985 {
   7986 	return bin_op(upma1, upma2, &pullback_entry);
   7987 }
   7988 
   7989 /* Apply "upma2" to "upma1".
   7990  *
   7991  * That is, compute the pullback of "upma2" by "upma1".
   7992  */
   7993 __isl_give isl_union_pw_multi_aff *
   7994 isl_union_pw_multi_aff_apply_union_pw_multi_aff(
   7995 	__isl_take isl_union_pw_multi_aff *upma1,
   7996 	__isl_take isl_union_pw_multi_aff *upma2)
   7997 {
   7998 	return isl_union_pw_multi_aff_pullback_union_pw_multi_aff(upma2, upma1);
   7999 }
   8000 
   8001 #undef BASE
   8002 #define BASE pw_multi_aff
   8003 static
   8004 #include "isl_copy_tuple_id_templ.c"
   8005 
   8006 /* Given a function "pma1" of the form A[B -> C] -> D and
   8007  * a function "pma2" of the form E -> B,
   8008  * replace the domain of the wrapped relation inside the domain of "pma1"
   8009  * by the preimage with respect to "pma2".
   8010  * In other words, plug in "pma2" in this nested domain.
   8011  * The result is of the form A[E -> C] -> D.
   8012  *
   8013  * In particular, extend E -> B to A[E -> C] -> A[B -> C] and
   8014  * plug that into "pma1".
   8015  */
   8016 __isl_give isl_pw_multi_aff *
   8017 isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(
   8018 	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
   8019 {
   8020 	isl_space *pma1_space, *pma2_space;
   8021 	isl_space *space;
   8022 	isl_pw_multi_aff *id;
   8023 
   8024 	pma1_space = isl_pw_multi_aff_peek_space(pma1);
   8025 	pma2_space = isl_pw_multi_aff_peek_space(pma2);
   8026 
   8027 	if (isl_space_check_domain_is_wrapping(pma1_space) < 0)
   8028 		goto error;
   8029 	if (isl_space_check_wrapped_tuple_is_equal(pma1_space,
   8030 			isl_dim_in, isl_dim_in, pma2_space, isl_dim_out) < 0)
   8031 		goto error;
   8032 
   8033 	space = isl_space_domain(isl_space_copy(pma1_space));
   8034 	space = isl_space_range(isl_space_unwrap(space));
   8035 	id = isl_pw_multi_aff_identity_on_domain_space(space);
   8036 	pma2 = isl_pw_multi_aff_product(pma2, id);
   8037 
   8038 	pma2 = isl_pw_multi_aff_copy_tuple_id(pma2, isl_dim_in,
   8039 						pma1_space, isl_dim_in);
   8040 	pma2 = isl_pw_multi_aff_copy_tuple_id(pma2, isl_dim_out,
   8041 						pma1_space, isl_dim_in);
   8042 
   8043 	return isl_pw_multi_aff_pullback_pw_multi_aff(pma1, pma2);
   8044 error:
   8045 	isl_pw_multi_aff_free(pma1);
   8046 	isl_pw_multi_aff_free(pma2);
   8047 	return NULL;
   8048 }
   8049 
   8050 /* If data->pma and "pma2" are such that
   8051  * data->pma is of the form A[B -> C] -> D and
   8052  * "pma2" is of the form E -> B,
   8053  * then replace the domain of the wrapped relation
   8054  * inside the domain of data->pma by the preimage with respect to "pma2" and
   8055  * add the result to data->res.
   8056  */
   8057 static isl_stat preimage_domain_wrapped_domain_entry(
   8058 	__isl_take isl_pw_multi_aff *pma2, void *user)
   8059 {
   8060 	struct isl_union_pw_multi_aff_bin_data *data = user;
   8061 	isl_space *pma1_space, *pma2_space;
   8062 	isl_bool match;
   8063 
   8064 	pma1_space = isl_pw_multi_aff_peek_space(data->pma);
   8065 	pma2_space = isl_pw_multi_aff_peek_space(pma2);
   8066 
   8067 	match = isl_space_domain_is_wrapping(pma1_space);
   8068 	if (match >= 0 && match)
   8069 		match = isl_space_wrapped_tuple_is_equal(pma1_space, isl_dim_in,
   8070 					isl_dim_in, pma2_space, isl_dim_out);
   8071 	if (match < 0 || !match) {
   8072 		isl_pw_multi_aff_free(pma2);
   8073 		return match < 0 ? isl_stat_error : isl_stat_ok;
   8074 	}
   8075 
   8076 	pma2 = isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(
   8077 		isl_pw_multi_aff_copy(data->pma), pma2);
   8078 
   8079 	data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2);
   8080 
   8081 	return isl_stat_non_null(data->res);
   8082 }
   8083 
   8084 /* For each pair of functions A[B -> C] -> D in "upma1" and
   8085  * E -> B in "upma2",
   8086  * replace the domain of the wrapped relation inside the domain of the first
   8087  * by the preimage with respect to the second and collect the results.
   8088  * In other words, plug in the second function in this nested domain.
   8089  * The results are of the form A[E -> C] -> D.
   8090  */
   8091 __isl_give isl_union_pw_multi_aff *
   8092 isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff(
   8093 	__isl_take isl_union_pw_multi_aff *upma1,
   8094 	__isl_take isl_union_pw_multi_aff *upma2)
   8095 {
   8096 	return bin_op(upma1, upma2, &preimage_domain_wrapped_domain_entry);
   8097 }
   8098 
   8099 /* Check that the domain space of "upa" matches "space".
   8100  *
   8101  * This function is called from isl_multi_union_pw_aff_set_union_pw_aff and
   8102  * can in principle never fail since the space "space" is that
   8103  * of the isl_multi_union_pw_aff and is a set space such that
   8104  * there is no domain space to match.
   8105  *
   8106  * We check the parameters and double-check that "space" is
   8107  * indeed that of a set.
   8108  */
   8109 static isl_stat isl_union_pw_aff_check_match_domain_space(
   8110 	__isl_keep isl_union_pw_aff *upa, __isl_keep isl_space *space)
   8111 {
   8112 	isl_space *upa_space;
   8113 	isl_bool match;
   8114 
   8115 	if (!upa || !space)
   8116 		return isl_stat_error;
   8117 
   8118 	match = isl_space_is_set(space);
   8119 	if (match < 0)
   8120 		return isl_stat_error;
   8121 	if (!match)
   8122 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
   8123 			"expecting set space", return isl_stat_error);
   8124 
   8125 	upa_space = isl_union_pw_aff_get_space(upa);
   8126 	match = isl_space_has_equal_params(space, upa_space);
   8127 	if (match < 0)
   8128 		goto error;
   8129 	if (!match)
   8130 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
   8131 			"parameters don't match", goto error);
   8132 
   8133 	isl_space_free(upa_space);
   8134 	return isl_stat_ok;
   8135 error:
   8136 	isl_space_free(upa_space);
   8137 	return isl_stat_error;
   8138 }
   8139 
   8140 /* Do the parameters of "upa" match those of "space"?
   8141  */
   8142 static isl_bool isl_union_pw_aff_matching_params(
   8143 	__isl_keep isl_union_pw_aff *upa, __isl_keep isl_space *space)
   8144 {
   8145 	isl_space *upa_space;
   8146 	isl_bool match;
   8147 
   8148 	if (!upa || !space)
   8149 		return isl_bool_error;
   8150 
   8151 	upa_space = isl_union_pw_aff_get_space(upa);
   8152 
   8153 	match = isl_space_has_equal_params(space, upa_space);
   8154 
   8155 	isl_space_free(upa_space);
   8156 	return match;
   8157 }
   8158 
   8159 /* Internal data structure for isl_union_pw_aff_reset_domain_space.
   8160  * space represents the new parameters.
   8161  * res collects the results.
   8162  */
   8163 struct isl_union_pw_aff_reset_params_data {
   8164 	isl_space *space;
   8165 	isl_union_pw_aff *res;
   8166 };
   8167 
   8168 /* Replace the parameters of "pa" by data->space and
   8169  * add the result to data->res.
   8170  */
   8171 static isl_stat reset_params(__isl_take isl_pw_aff *pa, void *user)
   8172 {
   8173 	struct isl_union_pw_aff_reset_params_data *data = user;
   8174 	isl_space *space;
   8175 
   8176 	space = isl_pw_aff_get_space(pa);
   8177 	space = isl_space_replace_params(space, data->space);
   8178 	pa = isl_pw_aff_reset_space(pa, space);
   8179 	data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
   8180 
   8181 	return data->res ? isl_stat_ok : isl_stat_error;
   8182 }
   8183 
   8184 /* Replace the domain space of "upa" by "space".
   8185  * Since a union expression does not have a (single) domain space,
   8186  * "space" is necessarily a parameter space.
   8187  *
   8188  * Since the order and the names of the parameters determine
   8189  * the hash value, we need to create a new hash table.
   8190  */
   8191 static __isl_give isl_union_pw_aff *isl_union_pw_aff_reset_domain_space(
   8192 	__isl_take isl_union_pw_aff *upa, __isl_take isl_space *space)
   8193 {
   8194 	struct isl_union_pw_aff_reset_params_data data = { space };
   8195 	isl_bool match;
   8196 
   8197 	match = isl_union_pw_aff_matching_params(upa, space);
   8198 	if (match < 0)
   8199 		upa = isl_union_pw_aff_free(upa);
   8200 	else if (match) {
   8201 		isl_space_free(space);
   8202 		return upa;
   8203 	}
   8204 
   8205 	data.res = isl_union_pw_aff_empty(isl_space_copy(space));
   8206 	if (isl_union_pw_aff_foreach_pw_aff(upa, &reset_params, &data) < 0)
   8207 		data.res = isl_union_pw_aff_free(data.res);
   8208 
   8209 	isl_union_pw_aff_free(upa);
   8210 	isl_space_free(space);
   8211 	return data.res;
   8212 }
   8213 
   8214 /* Return the floor of "pa".
   8215  */
   8216 static __isl_give isl_pw_aff *floor_entry(__isl_take isl_pw_aff *pa, void *user)
   8217 {
   8218 	return isl_pw_aff_floor(pa);
   8219 }
   8220 
   8221 /* Given f, return floor(f).
   8222  */
   8223 __isl_give isl_union_pw_aff *isl_union_pw_aff_floor(
   8224 	__isl_take isl_union_pw_aff *upa)
   8225 {
   8226 	return isl_union_pw_aff_transform_inplace(upa, &floor_entry, NULL);
   8227 }
   8228 
   8229 /* Compute
   8230  *
   8231  *	upa mod m = upa - m * floor(upa/m)
   8232  *
   8233  * with m an integer value.
   8234  */
   8235 __isl_give isl_union_pw_aff *isl_union_pw_aff_mod_val(
   8236 	__isl_take isl_union_pw_aff *upa, __isl_take isl_val *m)
   8237 {
   8238 	isl_union_pw_aff *res;
   8239 
   8240 	if (!upa || !m)
   8241 		goto error;
   8242 
   8243 	if (!isl_val_is_int(m))
   8244 		isl_die(isl_val_get_ctx(m), isl_error_invalid,
   8245 			"expecting integer modulo", goto error);
   8246 	if (!isl_val_is_pos(m))
   8247 		isl_die(isl_val_get_ctx(m), isl_error_invalid,
   8248 			"expecting positive modulo", goto error);
   8249 
   8250 	res = isl_union_pw_aff_copy(upa);
   8251 	upa = isl_union_pw_aff_scale_down_val(upa, isl_val_copy(m));
   8252 	upa = isl_union_pw_aff_floor(upa);
   8253 	upa = isl_union_pw_aff_scale_val(upa, m);
   8254 	res = isl_union_pw_aff_sub(res, upa);
   8255 
   8256 	return res;
   8257 error:
   8258 	isl_val_free(m);
   8259 	isl_union_pw_aff_free(upa);
   8260 	return NULL;
   8261 }
   8262 
   8263 /* Internal data structure for isl_union_pw_multi_aff_get_union_pw_aff.
   8264  * pos is the output position that needs to be extracted.
   8265  * res collects the results.
   8266  */
   8267 struct isl_union_pw_multi_aff_get_union_pw_aff_data {
   8268 	int pos;
   8269 	isl_union_pw_aff *res;
   8270 };
   8271 
   8272 /* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma"
   8273  * (assuming it has such a dimension) and add it to data->res.
   8274  */
   8275 static isl_stat get_union_pw_aff(__isl_take isl_pw_multi_aff *pma, void *user)
   8276 {
   8277 	struct isl_union_pw_multi_aff_get_union_pw_aff_data *data = user;
   8278 	isl_size n_out;
   8279 	isl_pw_aff *pa;
   8280 
   8281 	n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
   8282 	if (n_out < 0)
   8283 		return isl_stat_error;
   8284 	if (data->pos >= n_out) {
   8285 		isl_pw_multi_aff_free(pma);
   8286 		return isl_stat_ok;
   8287 	}
   8288 
   8289 	pa = isl_pw_multi_aff_get_pw_aff(pma, data->pos);
   8290 	isl_pw_multi_aff_free(pma);
   8291 
   8292 	data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
   8293 
   8294 	return data->res ? isl_stat_ok : isl_stat_error;
   8295 }
   8296 
   8297 /* Extract an isl_union_pw_aff corresponding to
   8298  * output dimension "pos" of "upma".
   8299  */
   8300 __isl_give isl_union_pw_aff *isl_union_pw_multi_aff_get_union_pw_aff(
   8301 	__isl_keep isl_union_pw_multi_aff *upma, int pos)
   8302 {
   8303 	struct isl_union_pw_multi_aff_get_union_pw_aff_data data;
   8304 	isl_space *space;
   8305 
   8306 	if (!upma)
   8307 		return NULL;
   8308 
   8309 	if (pos < 0)
   8310 		isl_die(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid,
   8311 			"cannot extract at negative position", return NULL);
   8312 
   8313 	space = isl_union_pw_multi_aff_get_space(upma);
   8314 	data.res = isl_union_pw_aff_empty(space);
   8315 	data.pos = pos;
   8316 	if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
   8317 						&get_union_pw_aff, &data) < 0)
   8318 		data.res = isl_union_pw_aff_free(data.res);
   8319 
   8320 	return data.res;
   8321 }
   8322 
   8323 /* Return a union piecewise affine expression
   8324  * that is equal to "aff" on "domain".
   8325  */
   8326 __isl_give isl_union_pw_aff *isl_union_pw_aff_aff_on_domain(
   8327 	__isl_take isl_union_set *domain, __isl_take isl_aff *aff)
   8328 {
   8329 	isl_pw_aff *pa;
   8330 
   8331 	pa = isl_pw_aff_from_aff(aff);
   8332 	return isl_union_pw_aff_pw_aff_on_domain(domain, pa);
   8333 }
   8334 
   8335 /* Return a union piecewise affine expression
   8336  * that is equal to the parameter identified by "id" on "domain".
   8337  *
   8338  * Make sure the parameter appears in the space passed to
   8339  * isl_aff_param_on_domain_space_id.
   8340  */
   8341 __isl_give isl_union_pw_aff *isl_union_pw_aff_param_on_domain_id(
   8342 	__isl_take isl_union_set *domain, __isl_take isl_id *id)
   8343 {
   8344 	isl_space *space;
   8345 	isl_aff *aff;
   8346 
   8347 	space = isl_union_set_get_space(domain);
   8348 	space = isl_space_add_param_id(space, isl_id_copy(id));
   8349 	aff = isl_aff_param_on_domain_space_id(space, id);
   8350 	return isl_union_pw_aff_aff_on_domain(domain, aff);
   8351 }
   8352 
   8353 /* Internal data structure for isl_union_pw_aff_pw_aff_on_domain.
   8354  * "pa" is the piecewise symbolic value that the resulting isl_union_pw_aff
   8355  * needs to attain.
   8356  * "res" collects the results.
   8357  */
   8358 struct isl_union_pw_aff_pw_aff_on_domain_data {
   8359 	isl_pw_aff *pa;
   8360 	isl_union_pw_aff *res;
   8361 };
   8362 
   8363 /* Construct a piecewise affine expression that is equal to data->pa
   8364  * on "domain" and add the result to data->res.
   8365  */
   8366 static isl_stat pw_aff_on_domain(__isl_take isl_set *domain, void *user)
   8367 {
   8368 	struct isl_union_pw_aff_pw_aff_on_domain_data *data = user;
   8369 	isl_pw_aff *pa;
   8370 	isl_size dim;
   8371 
   8372 	pa = isl_pw_aff_copy(data->pa);
   8373 	dim = isl_set_dim(domain, isl_dim_set);
   8374 	if (dim < 0)
   8375 		pa = isl_pw_aff_free(pa);
   8376 	pa = isl_pw_aff_from_range(pa);
   8377 	pa = isl_pw_aff_add_dims(pa, isl_dim_in, dim);
   8378 	pa = isl_pw_aff_reset_domain_space(pa, isl_set_get_space(domain));
   8379 	pa = isl_pw_aff_intersect_domain(pa, domain);
   8380 	data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
   8381 
   8382 	return data->res ? isl_stat_ok : isl_stat_error;
   8383 }
   8384 
   8385 /* Return a union piecewise affine expression
   8386  * that is equal to "pa" on "domain", assuming "domain" and "pa"
   8387  * have been aligned.
   8388  *
   8389  * Construct an isl_pw_aff on each of the sets in "domain" and
   8390  * collect the results.
   8391  */
   8392 static __isl_give isl_union_pw_aff *isl_union_pw_aff_pw_aff_on_domain_aligned(
   8393 	__isl_take isl_union_set *domain, __isl_take isl_pw_aff *pa)
   8394 {
   8395 	struct isl_union_pw_aff_pw_aff_on_domain_data data;
   8396 	isl_space *space;
   8397 
   8398 	space = isl_union_set_get_space(domain);
   8399 	data.res = isl_union_pw_aff_empty(space);
   8400 	data.pa = pa;
   8401 	if (isl_union_set_foreach_set(domain, &pw_aff_on_domain, &data) < 0)
   8402 		data.res = isl_union_pw_aff_free(data.res);
   8403 	isl_union_set_free(domain);
   8404 	isl_pw_aff_free(pa);
   8405 	return data.res;
   8406 }
   8407 
   8408 /* Return a union piecewise affine expression
   8409  * that is equal to "pa" on "domain".
   8410  *
   8411  * Check that "pa" is a parametric expression,
   8412  * align the parameters if needed and call
   8413  * isl_union_pw_aff_pw_aff_on_domain_aligned.
   8414  */
   8415 __isl_give isl_union_pw_aff *isl_union_pw_aff_pw_aff_on_domain(
   8416 	__isl_take isl_union_set *domain, __isl_take isl_pw_aff *pa)
   8417 {
   8418 	isl_bool is_set;
   8419 	isl_bool equal_params;
   8420 	isl_space *domain_space, *pa_space;
   8421 
   8422 	pa_space = isl_pw_aff_peek_space(pa);
   8423 	is_set = isl_space_is_set(pa_space);
   8424 	if (is_set < 0)
   8425 		goto error;
   8426 	if (!is_set)
   8427 		isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
   8428 			"expecting parametric expression", goto error);
   8429 
   8430 	domain_space = isl_union_set_get_space(domain);
   8431 	pa_space = isl_pw_aff_get_space(pa);
   8432 	equal_params = isl_space_has_equal_params(domain_space, pa_space);
   8433 	if (equal_params >= 0 && !equal_params) {
   8434 		isl_space *space;
   8435 
   8436 		space = isl_space_align_params(domain_space, pa_space);
   8437 		pa = isl_pw_aff_align_params(pa, isl_space_copy(space));
   8438 		domain = isl_union_set_align_params(domain, space);
   8439 	} else {
   8440 		isl_space_free(domain_space);
   8441 		isl_space_free(pa_space);
   8442 	}
   8443 
   8444 	if (equal_params < 0)
   8445 		goto error;
   8446 	return isl_union_pw_aff_pw_aff_on_domain_aligned(domain, pa);
   8447 error:
   8448 	isl_union_set_free(domain);
   8449 	isl_pw_aff_free(pa);
   8450 	return NULL;
   8451 }
   8452 
   8453 /* Internal data structure for isl_union_pw_aff_val_on_domain.
   8454  * "v" is the value that the resulting isl_union_pw_aff needs to attain.
   8455  * "res" collects the results.
   8456  */
   8457 struct isl_union_pw_aff_val_on_domain_data {
   8458 	isl_val *v;
   8459 	isl_union_pw_aff *res;
   8460 };
   8461 
   8462 /* Construct a piecewise affine expression that is equal to data->v
   8463  * on "domain" and add the result to data->res.
   8464  */
   8465 static isl_stat pw_aff_val_on_domain(__isl_take isl_set *domain, void *user)
   8466 {
   8467 	struct isl_union_pw_aff_val_on_domain_data *data = user;
   8468 	isl_pw_aff *pa;
   8469 	isl_val *v;
   8470 
   8471 	v = isl_val_copy(data->v);
   8472 	pa = isl_pw_aff_val_on_domain(domain, v);
   8473 	data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
   8474 
   8475 	return data->res ? isl_stat_ok : isl_stat_error;
   8476 }
   8477 
   8478 /* Return a union piecewise affine expression
   8479  * that is equal to "v" on "domain".
   8480  *
   8481  * Construct an isl_pw_aff on each of the sets in "domain" and
   8482  * collect the results.
   8483  */
   8484 __isl_give isl_union_pw_aff *isl_union_pw_aff_val_on_domain(
   8485 	__isl_take isl_union_set *domain, __isl_take isl_val *v)
   8486 {
   8487 	struct isl_union_pw_aff_val_on_domain_data data;
   8488 	isl_space *space;
   8489 
   8490 	space = isl_union_set_get_space(domain);
   8491 	data.res = isl_union_pw_aff_empty(space);
   8492 	data.v = v;
   8493 	if (isl_union_set_foreach_set(domain, &pw_aff_val_on_domain, &data) < 0)
   8494 		data.res = isl_union_pw_aff_free(data.res);
   8495 	isl_union_set_free(domain);
   8496 	isl_val_free(v);
   8497 	return data.res;
   8498 }
   8499 
   8500 /* Construct a piecewise multi affine expression
   8501  * that is equal to "pa" and add it to upma.
   8502  */
   8503 static isl_stat pw_multi_aff_from_pw_aff_entry(__isl_take isl_pw_aff *pa,
   8504 	void *user)
   8505 {
   8506 	isl_union_pw_multi_aff **upma = user;
   8507 	isl_pw_multi_aff *pma;
   8508 
   8509 	pma = isl_pw_multi_aff_from_pw_aff(pa);
   8510 	*upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
   8511 
   8512 	return *upma ? isl_stat_ok : isl_stat_error;
   8513 }
   8514 
   8515 /* Construct and return a union piecewise multi affine expression
   8516  * that is equal to the given union piecewise affine expression.
   8517  */
   8518 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_pw_aff(
   8519 	__isl_take isl_union_pw_aff *upa)
   8520 {
   8521 	isl_space *space;
   8522 	isl_union_pw_multi_aff *upma;
   8523 
   8524 	if (!upa)
   8525 		return NULL;
   8526 
   8527 	space = isl_union_pw_aff_get_space(upa);
   8528 	upma = isl_union_pw_multi_aff_empty(space);
   8529 
   8530 	if (isl_union_pw_aff_foreach_pw_aff(upa,
   8531 				&pw_multi_aff_from_pw_aff_entry, &upma) < 0)
   8532 		upma = isl_union_pw_multi_aff_free(upma);
   8533 
   8534 	isl_union_pw_aff_free(upa);
   8535 	return upma;
   8536 }
   8537 
   8538 /* Compute the set of elements in the domain of "pa" where it is zero and
   8539  * add this set to "uset".
   8540  */
   8541 static isl_stat zero_union_set(__isl_take isl_pw_aff *pa, void *user)
   8542 {
   8543 	isl_union_set **uset = (isl_union_set **)user;
   8544 
   8545 	*uset = isl_union_set_add_set(*uset, isl_pw_aff_zero_set(pa));
   8546 
   8547 	return *uset ? isl_stat_ok : isl_stat_error;
   8548 }
   8549 
   8550 /* Return a union set containing those elements in the domain
   8551  * of "upa" where it is zero.
   8552  */
   8553 __isl_give isl_union_set *isl_union_pw_aff_zero_union_set(
   8554 	__isl_take isl_union_pw_aff *upa)
   8555 {
   8556 	isl_union_set *zero;
   8557 
   8558 	zero = isl_union_set_empty(isl_union_pw_aff_get_space(upa));
   8559 	if (isl_union_pw_aff_foreach_pw_aff(upa, &zero_union_set, &zero) < 0)
   8560 		zero = isl_union_set_free(zero);
   8561 
   8562 	isl_union_pw_aff_free(upa);
   8563 	return zero;
   8564 }
   8565 
   8566 /* Internal data structure for isl_union_pw_aff_bind_id,
   8567  * storing the parameter that needs to be bound and
   8568  * the accumulated results.
   8569  */
   8570 struct isl_bind_id_data {
   8571 	isl_id *id;
   8572 	isl_union_set *bound;
   8573 };
   8574 
   8575 /* Bind the piecewise affine function "pa" to the parameter data->id,
   8576  * adding the resulting elements in the domain where the expression
   8577  * is equal to the parameter to data->bound.
   8578  */
   8579 static isl_stat bind_id(__isl_take isl_pw_aff *pa, void *user)
   8580 {
   8581 	struct isl_bind_id_data *data = user;
   8582 	isl_set *bound;
   8583 
   8584 	bound = isl_pw_aff_bind_id(pa, isl_id_copy(data->id));
   8585 	data->bound = isl_union_set_add_set(data->bound, bound);
   8586 
   8587 	return data->bound ? isl_stat_ok : isl_stat_error;
   8588 }
   8589 
   8590 /* Bind the union piecewise affine function "upa" to the parameter "id",
   8591  * returning the elements in the domain where the expression
   8592  * is equal to the parameter.
   8593  */
   8594 __isl_give isl_union_set *isl_union_pw_aff_bind_id(
   8595 	__isl_take isl_union_pw_aff *upa, __isl_take isl_id *id)
   8596 {
   8597 	struct isl_bind_id_data data = { id };
   8598 
   8599 	data.bound = isl_union_set_empty(isl_union_pw_aff_get_space(upa));
   8600 	if (isl_union_pw_aff_foreach_pw_aff(upa, &bind_id, &data) < 0)
   8601 		data.bound = isl_union_set_free(data.bound);
   8602 
   8603 	isl_union_pw_aff_free(upa);
   8604 	isl_id_free(id);
   8605 	return data.bound;
   8606 }
   8607 
   8608 /* Internal data structure for isl_union_pw_aff_pullback_union_pw_multi_aff.
   8609  * upma is the function that is plugged in.
   8610  * pa is the current part of the function in which upma is plugged in.
   8611  * res collects the results.
   8612  */
   8613 struct isl_union_pw_aff_pullback_upma_data {
   8614 	isl_union_pw_multi_aff *upma;
   8615 	isl_pw_aff *pa;
   8616 	isl_union_pw_aff *res;
   8617 };
   8618 
   8619 /* Check if "pma" can be plugged into data->pa.
   8620  * If so, perform the pullback and add the result to data->res.
   8621  */
   8622 static isl_stat pa_pb_pma(__isl_take isl_pw_multi_aff *pma, void *user)
   8623 {
   8624 	struct isl_union_pw_aff_pullback_upma_data *data = user;
   8625 	isl_pw_aff *pa;
   8626 
   8627 	if (!isl_space_tuple_is_equal(data->pa->dim, isl_dim_in,
   8628 				 pma->dim, isl_dim_out)) {
   8629 		isl_pw_multi_aff_free(pma);
   8630 		return isl_stat_ok;
   8631 	}
   8632 
   8633 	pa = isl_pw_aff_copy(data->pa);
   8634 	pa = isl_pw_aff_pullback_pw_multi_aff(pa, pma);
   8635 
   8636 	data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
   8637 
   8638 	return data->res ? isl_stat_ok : isl_stat_error;
   8639 }
   8640 
   8641 /* Check if any of the elements of data->upma can be plugged into pa,
   8642  * add if so add the result to data->res.
   8643  */
   8644 static isl_stat upa_pb_upma(__isl_take isl_pw_aff *pa, void *user)
   8645 {
   8646 	struct isl_union_pw_aff_pullback_upma_data *data = user;
   8647 	isl_stat r;
   8648 
   8649 	data->pa = pa;
   8650 	r = isl_union_pw_multi_aff_foreach_pw_multi_aff(data->upma,
   8651 				   &pa_pb_pma, data);
   8652 	isl_pw_aff_free(pa);
   8653 
   8654 	return r;
   8655 }
   8656 
   8657 /* Compute the pullback of "upa" by the function represented by "upma".
   8658  * In other words, plug in "upma" in "upa".  The result contains
   8659  * expressions defined over the domain space of "upma".
   8660  *
   8661  * Run over all pairs of elements in "upa" and "upma", perform
   8662  * the pullback when appropriate and collect the results.
   8663  * If the hash value were based on the domain space rather than
   8664  * the function space, then we could run through all elements
   8665  * of "upma" and directly pick out the corresponding element of "upa".
   8666  */
   8667 __isl_give isl_union_pw_aff *isl_union_pw_aff_pullback_union_pw_multi_aff(
   8668 	__isl_take isl_union_pw_aff *upa,
   8669 	__isl_take isl_union_pw_multi_aff *upma)
   8670 {
   8671 	struct isl_union_pw_aff_pullback_upma_data data = { NULL, NULL };
   8672 	isl_space *space;
   8673 
   8674 	space = isl_union_pw_multi_aff_get_space(upma);
   8675 	upa = isl_union_pw_aff_align_params(upa, space);
   8676 	space = isl_union_pw_aff_get_space(upa);
   8677 	upma = isl_union_pw_multi_aff_align_params(upma, space);
   8678 
   8679 	if (!upa || !upma)
   8680 		goto error;
   8681 
   8682 	data.upma = upma;
   8683 	data.res = isl_union_pw_aff_alloc_same_size(upa);
   8684 	if (isl_union_pw_aff_foreach_pw_aff(upa, &upa_pb_upma, &data) < 0)
   8685 		data.res = isl_union_pw_aff_free(data.res);
   8686 
   8687 	isl_union_pw_aff_free(upa);
   8688 	isl_union_pw_multi_aff_free(upma);
   8689 	return data.res;
   8690 error:
   8691 	isl_union_pw_aff_free(upa);
   8692 	isl_union_pw_multi_aff_free(upma);
   8693 	return NULL;
   8694 }
   8695 
   8696 #undef BASE
   8697 #define BASE union_pw_aff
   8698 #undef DOMBASE
   8699 #define DOMBASE union_set
   8700 
   8701 #include <isl_multi_explicit_domain.c>
   8702 #include <isl_multi_union_pw_aff_explicit_domain.c>
   8703 #include <isl_multi_templ.c>
   8704 #include <isl_multi_un_op_templ.c>
   8705 #include <isl_multi_bin_val_templ.c>
   8706 #include <isl_multi_align_set.c>
   8707 #include <isl_multi_align_union_set.c>
   8708 #include <isl_multi_apply_set_explicit_domain_templ.c>
   8709 #include <isl_multi_apply_union_set_explicit_domain_templ.c>
   8710 #include <isl_multi_arith_templ.c>
   8711 #include <isl_multi_bind_templ.c>
   8712 #include <isl_multi_coalesce.c>
   8713 #include <isl_multi_dim_id_templ.c>
   8714 #include <isl_multi_floor.c>
   8715 #include <isl_multi_from_base_templ.c>
   8716 #include <isl_multi_check_domain_templ.c>
   8717 #include <isl_multi_gist.c>
   8718 #include <isl_multi_intersect.c>
   8719 #include <isl_multi_nan_templ.c>
   8720 #include <isl_multi_tuple_id_templ.c>
   8721 #include <isl_multi_union_add_templ.c>
   8722 #include <isl_multi_zero_space_templ.c>
   8723 
   8724 /* Does "mupa" have a non-trivial explicit domain?
   8725  *
   8726  * The explicit domain, if present, is trivial if it represents
   8727  * an (obviously) universe parameter set.
   8728  */
   8729 isl_bool isl_multi_union_pw_aff_has_non_trivial_domain(
   8730 	__isl_keep isl_multi_union_pw_aff *mupa)
   8731 {
   8732 	isl_bool is_params, trivial;
   8733 	isl_set *set;
   8734 
   8735 	if (!mupa)
   8736 		return isl_bool_error;
   8737 	if (!isl_multi_union_pw_aff_has_explicit_domain(mupa))
   8738 		return isl_bool_false;
   8739 	is_params = isl_union_set_is_params(mupa->u.dom);
   8740 	if (is_params < 0 || !is_params)
   8741 		return isl_bool_not(is_params);
   8742 	set = isl_set_from_union_set(isl_union_set_copy(mupa->u.dom));
   8743 	trivial = isl_set_plain_is_universe(set);
   8744 	isl_set_free(set);
   8745 	return isl_bool_not(trivial);
   8746 }
   8747 
   8748 /* Construct a multiple union piecewise affine expression
   8749  * in the given space with value zero in each of the output dimensions.
   8750  *
   8751  * Since there is no canonical zero value for
   8752  * a union piecewise affine expression, we can only construct
   8753  * a zero-dimensional "zero" value.
   8754  */
   8755 __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_zero(
   8756 	__isl_take isl_space *space)
   8757 {
   8758 	isl_bool params;
   8759 	isl_size dim;
   8760 
   8761 	if (!space)
   8762 		return NULL;
   8763 
   8764 	params = isl_space_is_params(space);
   8765 	if (params < 0)
   8766 		goto error;
   8767 	if (params)
   8768 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
   8769 			"expecting proper set space", goto error);
   8770 	if (!isl_space_is_set(space))
   8771 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
   8772 			"expecting set space", goto error);
   8773 	dim = isl_space_dim(space, isl_dim_out);
   8774 	if (dim < 0)
   8775 		goto error;
   8776 	if (dim != 0)
   8777 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
   8778 			"expecting 0D space", goto error);
   8779 
   8780 	return isl_multi_union_pw_aff_alloc(space);
   8781 error:
   8782 	isl_space_free(space);
   8783 	return NULL;
   8784 }
   8785 
   8786 /* Construct and return a multi union piecewise affine expression
   8787  * that is equal to the given multi affine expression.
   8788  */
   8789 __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_aff(
   8790 	__isl_take isl_multi_aff *ma)
   8791 {
   8792 	isl_multi_pw_aff *mpa;
   8793 
   8794 	mpa = isl_multi_pw_aff_from_multi_aff(ma);
   8795 	return isl_multi_union_pw_aff_from_multi_pw_aff(mpa);
   8796 }
   8797 
   8798 /* This function performs the same operation as
   8799  * isl_multi_union_pw_aff_from_multi_aff, but is considered as a function on an
   8800  * isl_multi_aff when exported.
   8801  */
   8802 __isl_give isl_multi_union_pw_aff *isl_multi_aff_to_multi_union_pw_aff(
   8803         __isl_take isl_multi_aff *ma)
   8804 {
   8805         return isl_multi_union_pw_aff_from_multi_aff(ma);
   8806 }
   8807 
   8808 /* Construct and return a multi union piecewise affine expression
   8809  * that is equal to the given multi piecewise affine expression.
   8810  *
   8811  * If the resulting multi union piecewise affine expression has
   8812  * an explicit domain, then assign it the domain of the input.
   8813  * In other cases, the domain is stored in the individual elements.
   8814  */
   8815 __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_pw_aff(
   8816 	__isl_take isl_multi_pw_aff *mpa)
   8817 {
   8818 	int i;
   8819 	isl_size n;
   8820 	isl_space *space;
   8821 	isl_multi_union_pw_aff *mupa;
   8822 
   8823 	n = isl_multi_pw_aff_dim(mpa, isl_dim_out);
   8824 	if (n < 0)
   8825 		mpa = isl_multi_pw_aff_free(mpa);
   8826 	if (!mpa)
   8827 		return NULL;
   8828 
   8829 	space = isl_multi_pw_aff_get_space(mpa);
   8830 	space = isl_space_range(space);
   8831 	mupa = isl_multi_union_pw_aff_alloc(space);
   8832 
   8833 	for (i = 0; i < n; ++i) {
   8834 		isl_pw_aff *pa;
   8835 		isl_union_pw_aff *upa;
   8836 
   8837 		pa = isl_multi_pw_aff_get_pw_aff(mpa, i);
   8838 		upa = isl_union_pw_aff_from_pw_aff(pa);
   8839 		mupa = isl_multi_union_pw_aff_restore_check_space(mupa, i, upa);
   8840 	}
   8841 	if (isl_multi_union_pw_aff_has_explicit_domain(mupa)) {
   8842 		isl_union_set *dom;
   8843 		isl_multi_pw_aff *copy;
   8844 
   8845 		copy = isl_multi_pw_aff_copy(mpa);
   8846 		dom = isl_union_set_from_set(isl_multi_pw_aff_domain(copy));
   8847 		mupa = isl_multi_union_pw_aff_intersect_domain(mupa, dom);
   8848 	}
   8849 
   8850 	isl_multi_pw_aff_free(mpa);
   8851 
   8852 	return mupa;
   8853 }
   8854 
   8855 /* Extract the range space of "pma" and assign it to *space.
   8856  * If *space has already been set (through a previous call to this function),
   8857  * then check that the range space is the same.
   8858  */
   8859 static isl_stat extract_space(__isl_take isl_pw_multi_aff *pma, void *user)
   8860 {
   8861 	isl_space **space = user;
   8862 	isl_space *pma_space;
   8863 	isl_bool equal;
   8864 
   8865 	pma_space = isl_space_range(isl_pw_multi_aff_get_space(pma));
   8866 	isl_pw_multi_aff_free(pma);
   8867 
   8868 	if (!pma_space)
   8869 		return isl_stat_error;
   8870 	if (!*space) {
   8871 		*space = pma_space;
   8872 		return isl_stat_ok;
   8873 	}
   8874 
   8875 	equal = isl_space_is_equal(pma_space, *space);
   8876 	isl_space_free(pma_space);
   8877 
   8878 	if (equal < 0)
   8879 		return isl_stat_error;
   8880 	if (!equal)
   8881 		isl_die(isl_space_get_ctx(*space), isl_error_invalid,
   8882 			"range spaces not the same", return isl_stat_error);
   8883 	return isl_stat_ok;
   8884 }
   8885 
   8886 /* Construct and return a multi union piecewise affine expression
   8887  * that is equal to the given union piecewise multi affine expression.
   8888  *
   8889  * In order to be able to perform the conversion, the input
   8890  * needs to be non-empty and may only involve a single range space.
   8891  *
   8892  * If the resulting multi union piecewise affine expression has
   8893  * an explicit domain, then assign it the domain of the input.
   8894  * In other cases, the domain is stored in the individual elements.
   8895  */
   8896 __isl_give isl_multi_union_pw_aff *
   8897 isl_multi_union_pw_aff_from_union_pw_multi_aff(
   8898 	__isl_take isl_union_pw_multi_aff *upma)
   8899 {
   8900 	isl_space *space = NULL;
   8901 	isl_multi_union_pw_aff *mupa;
   8902 	int i;
   8903 	isl_size n;
   8904 
   8905 	n = isl_union_pw_multi_aff_n_pw_multi_aff(upma);
   8906 	if (n < 0)
   8907 		goto error;
   8908 	if (n == 0)
   8909 		isl_die(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid,
   8910 			"cannot extract range space from empty input",
   8911 			goto error);
   8912 	if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, &extract_space,
   8913 							&space) < 0)
   8914 		goto error;
   8915 
   8916 	if (!space)
   8917 		goto error;
   8918 
   8919 	n = isl_space_dim(space, isl_dim_set);
   8920 	if (n < 0)
   8921 		space = isl_space_free(space);
   8922 	mupa = isl_multi_union_pw_aff_alloc(space);
   8923 
   8924 	for (i = 0; i < n; ++i) {
   8925 		isl_union_pw_aff *upa;
   8926 
   8927 		upa = isl_union_pw_multi_aff_get_union_pw_aff(upma, i);
   8928 		mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
   8929 	}
   8930 	if (isl_multi_union_pw_aff_has_explicit_domain(mupa)) {
   8931 		isl_union_set *dom;
   8932 		isl_union_pw_multi_aff *copy;
   8933 
   8934 		copy = isl_union_pw_multi_aff_copy(upma);
   8935 		dom = isl_union_pw_multi_aff_domain(copy);
   8936 		mupa = isl_multi_union_pw_aff_intersect_domain(mupa, dom);
   8937 	}
   8938 
   8939 	isl_union_pw_multi_aff_free(upma);
   8940 	return mupa;
   8941 error:
   8942 	isl_space_free(space);
   8943 	isl_union_pw_multi_aff_free(upma);
   8944 	return NULL;
   8945 }
   8946 
   8947 /* This function performs the same operation as
   8948  * isl_multi_union_pw_aff_from_union_pw_multi_aff,
   8949  * but is considered as a function on an isl_union_pw_multi_aff when exported.
   8950  */
   8951 __isl_give isl_multi_union_pw_aff *
   8952 isl_union_pw_multi_aff_as_multi_union_pw_aff(
   8953 	__isl_take isl_union_pw_multi_aff *upma)
   8954 {
   8955 	return isl_multi_union_pw_aff_from_union_pw_multi_aff(upma);
   8956 }
   8957 
   8958 /* Try and create an isl_multi_union_pw_aff that is equivalent
   8959  * to the given isl_union_map.
   8960  * The isl_union_map is required to be single-valued in each space.
   8961  * Moreover, it cannot be empty and all range spaces need to be the same.
   8962  * Otherwise, an error is produced.
   8963  */
   8964 __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_map(
   8965 	__isl_take isl_union_map *umap)
   8966 {
   8967 	isl_union_pw_multi_aff *upma;
   8968 
   8969 	upma = isl_union_pw_multi_aff_from_union_map(umap);
   8970 	return isl_multi_union_pw_aff_from_union_pw_multi_aff(upma);
   8971 }
   8972 
   8973 /* This function performs the same operation as
   8974  * isl_multi_union_pw_aff_from_union_map,
   8975  * but is considered as a function on an isl_union_map when exported.
   8976  */
   8977 __isl_give isl_multi_union_pw_aff *isl_union_map_as_multi_union_pw_aff(
   8978 	__isl_take isl_union_map *umap)
   8979 {
   8980 	return isl_multi_union_pw_aff_from_union_map(umap);
   8981 }
   8982 
   8983 /* Return a multiple union piecewise affine expression
   8984  * that is equal to "mv" on "domain", assuming "domain" and "mv"
   8985  * have been aligned.
   8986  *
   8987  * If the resulting multi union piecewise affine expression has
   8988  * an explicit domain, then assign it the input domain.
   8989  * In other cases, the domain is stored in the individual elements.
   8990  */
   8991 static __isl_give isl_multi_union_pw_aff *
   8992 isl_multi_union_pw_aff_multi_val_on_domain_aligned(
   8993 	__isl_take isl_union_set *domain, __isl_take isl_multi_val *mv)
   8994 {
   8995 	int i;
   8996 	isl_size n;
   8997 	isl_space *space;
   8998 	isl_multi_union_pw_aff *mupa;
   8999 
   9000 	n = isl_multi_val_dim(mv, isl_dim_set);
   9001 	if (!domain || n < 0)
   9002 		goto error;
   9003 
   9004 	space = isl_multi_val_get_space(mv);
   9005 	mupa = isl_multi_union_pw_aff_alloc(space);
   9006 	for (i = 0; i < n; ++i) {
   9007 		isl_val *v;
   9008 		isl_union_pw_aff *upa;
   9009 
   9010 		v = isl_multi_val_get_val(mv, i);
   9011 		upa = isl_union_pw_aff_val_on_domain(isl_union_set_copy(domain),
   9012 							v);
   9013 		mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
   9014 	}
   9015 	if (isl_multi_union_pw_aff_has_explicit_domain(mupa))
   9016 		mupa = isl_multi_union_pw_aff_intersect_domain(mupa,
   9017 						    isl_union_set_copy(domain));
   9018 
   9019 	isl_union_set_free(domain);
   9020 	isl_multi_val_free(mv);
   9021 	return mupa;
   9022 error:
   9023 	isl_union_set_free(domain);
   9024 	isl_multi_val_free(mv);
   9025 	return NULL;
   9026 }
   9027 
   9028 /* Return a multiple union piecewise affine expression
   9029  * that is equal to "mv" on "domain".
   9030  */
   9031 __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_val_on_domain(
   9032 	__isl_take isl_union_set *domain, __isl_take isl_multi_val *mv)
   9033 {
   9034 	isl_bool equal_params;
   9035 
   9036 	if (!domain || !mv)
   9037 		goto error;
   9038 	equal_params = isl_space_has_equal_params(domain->dim, mv->space);
   9039 	if (equal_params < 0)
   9040 		goto error;
   9041 	if (equal_params)
   9042 		return isl_multi_union_pw_aff_multi_val_on_domain_aligned(
   9043 								    domain, mv);
   9044 	domain = isl_union_set_align_params(domain,
   9045 						isl_multi_val_get_space(mv));
   9046 	mv = isl_multi_val_align_params(mv, isl_union_set_get_space(domain));
   9047 	return isl_multi_union_pw_aff_multi_val_on_domain_aligned(domain, mv);
   9048 error:
   9049 	isl_union_set_free(domain);
   9050 	isl_multi_val_free(mv);
   9051 	return NULL;
   9052 }
   9053 
   9054 /* Return a multiple union piecewise affine expression
   9055  * that is equal to "ma" on "domain".
   9056  */
   9057 __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_aff_on_domain(
   9058 	__isl_take isl_union_set *domain, __isl_take isl_multi_aff *ma)
   9059 {
   9060 	isl_pw_multi_aff *pma;
   9061 
   9062 	pma = isl_pw_multi_aff_from_multi_aff(ma);
   9063 	return isl_multi_union_pw_aff_pw_multi_aff_on_domain(domain, pma);
   9064 }
   9065 
   9066 /* Return a multiple union piecewise affine expression
   9067  * that is equal to "pma" on "domain", assuming "domain" and "pma"
   9068  * have been aligned.
   9069  *
   9070  * If the resulting multi union piecewise affine expression has
   9071  * an explicit domain, then assign it the input domain.
   9072  * In other cases, the domain is stored in the individual elements.
   9073  */
   9074 static __isl_give isl_multi_union_pw_aff *
   9075 isl_multi_union_pw_aff_pw_multi_aff_on_domain_aligned(
   9076 	__isl_take isl_union_set *domain, __isl_take isl_pw_multi_aff *pma)
   9077 {
   9078 	int i;
   9079 	isl_size n;
   9080 	isl_space *space;
   9081 	isl_multi_union_pw_aff *mupa;
   9082 
   9083 	n = isl_pw_multi_aff_dim(pma, isl_dim_set);
   9084 	if (!domain || n < 0)
   9085 		goto error;
   9086 	space = isl_pw_multi_aff_get_space(pma);
   9087 	mupa = isl_multi_union_pw_aff_alloc(space);
   9088 	for (i = 0; i < n; ++i) {
   9089 		isl_pw_aff *pa;
   9090 		isl_union_pw_aff *upa;
   9091 
   9092 		pa = isl_pw_multi_aff_get_pw_aff(pma, i);
   9093 		upa = isl_union_pw_aff_pw_aff_on_domain(
   9094 					    isl_union_set_copy(domain), pa);
   9095 		mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
   9096 	}
   9097 	if (isl_multi_union_pw_aff_has_explicit_domain(mupa))
   9098 		mupa = isl_multi_union_pw_aff_intersect_domain(mupa,
   9099 						    isl_union_set_copy(domain));
   9100 
   9101 	isl_union_set_free(domain);
   9102 	isl_pw_multi_aff_free(pma);
   9103 	return mupa;
   9104 error:
   9105 	isl_union_set_free(domain);
   9106 	isl_pw_multi_aff_free(pma);
   9107 	return NULL;
   9108 }
   9109 
   9110 /* Return a multiple union piecewise affine expression
   9111  * that is equal to "pma" on "domain".
   9112  */
   9113 __isl_give isl_multi_union_pw_aff *
   9114 isl_multi_union_pw_aff_pw_multi_aff_on_domain(__isl_take isl_union_set *domain,
   9115 	__isl_take isl_pw_multi_aff *pma)
   9116 {
   9117 	isl_bool equal_params;
   9118 	isl_space *space;
   9119 
   9120 	space = isl_pw_multi_aff_peek_space(pma);
   9121 	equal_params = isl_union_set_space_has_equal_params(domain, space);
   9122 	if (equal_params < 0)
   9123 		goto error;
   9124 	if (equal_params)
   9125 		return isl_multi_union_pw_aff_pw_multi_aff_on_domain_aligned(
   9126 								domain, pma);
   9127 	domain = isl_union_set_align_params(domain,
   9128 					    isl_pw_multi_aff_get_space(pma));
   9129 	pma = isl_pw_multi_aff_align_params(pma,
   9130 					    isl_union_set_get_space(domain));
   9131 	return isl_multi_union_pw_aff_pw_multi_aff_on_domain_aligned(domain,
   9132 									pma);
   9133 error:
   9134 	isl_union_set_free(domain);
   9135 	isl_pw_multi_aff_free(pma);
   9136 	return NULL;
   9137 }
   9138 
   9139 /* Return a union set containing those elements in the domains
   9140  * of the elements of "mupa" where they are all zero.
   9141  *
   9142  * If there are no elements, then simply return the entire domain.
   9143  */
   9144 __isl_give isl_union_set *isl_multi_union_pw_aff_zero_union_set(
   9145 	__isl_take isl_multi_union_pw_aff *mupa)
   9146 {
   9147 	int i;
   9148 	isl_size n;
   9149 	isl_union_pw_aff *upa;
   9150 	isl_union_set *zero;
   9151 
   9152 	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
   9153 	if (n < 0)
   9154 		mupa = isl_multi_union_pw_aff_free(mupa);
   9155 	if (!mupa)
   9156 		return NULL;
   9157 
   9158 	if (n == 0)
   9159 		return isl_multi_union_pw_aff_domain(mupa);
   9160 
   9161 	upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
   9162 	zero = isl_union_pw_aff_zero_union_set(upa);
   9163 
   9164 	for (i = 1; i < n; ++i) {
   9165 		isl_union_set *zero_i;
   9166 
   9167 		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
   9168 		zero_i = isl_union_pw_aff_zero_union_set(upa);
   9169 
   9170 		zero = isl_union_set_intersect(zero, zero_i);
   9171 	}
   9172 
   9173 	isl_multi_union_pw_aff_free(mupa);
   9174 	return zero;
   9175 }
   9176 
   9177 /* Construct a union map mapping the shared domain
   9178  * of the union piecewise affine expressions to the range of "mupa"
   9179  * in the special case of a 0D multi union piecewise affine expression.
   9180  *
   9181  * Construct a map between the explicit domain of "mupa" and
   9182  * the range space.
   9183  * Note that this assumes that the domain consists of explicit elements.
   9184  */
   9185 static __isl_give isl_union_map *isl_union_map_from_multi_union_pw_aff_0D(
   9186 	__isl_take isl_multi_union_pw_aff *mupa)
   9187 {
   9188 	isl_bool is_params;
   9189 	isl_space *space;
   9190 	isl_union_set *dom, *ran;
   9191 
   9192 	space = isl_multi_union_pw_aff_get_space(mupa);
   9193 	dom = isl_multi_union_pw_aff_domain(mupa);
   9194 	ran = isl_union_set_from_set(isl_set_universe(space));
   9195 
   9196 	is_params = isl_union_set_is_params(dom);
   9197 	if (is_params < 0)
   9198 		dom = isl_union_set_free(dom);
   9199 	else if (is_params)
   9200 		isl_die(isl_union_set_get_ctx(dom), isl_error_invalid,
   9201 			"cannot create union map from expression without "
   9202 			"explicit domain elements",
   9203 			dom = isl_union_set_free(dom));
   9204 
   9205 	return isl_union_map_from_domain_and_range(dom, ran);
   9206 }
   9207 
   9208 /* Construct a union map mapping the shared domain
   9209  * of the union piecewise affine expressions to the range of "mupa"
   9210  * with each dimension in the range equated to the
   9211  * corresponding union piecewise affine expression.
   9212  *
   9213  * If the input is zero-dimensional, then construct a mapping
   9214  * from its explicit domain.
   9215  */
   9216 __isl_give isl_union_map *isl_union_map_from_multi_union_pw_aff(
   9217 	__isl_take isl_multi_union_pw_aff *mupa)
   9218 {
   9219 	int i;
   9220 	isl_size n;
   9221 	isl_space *space;
   9222 	isl_union_map *umap;
   9223 	isl_union_pw_aff *upa;
   9224 
   9225 	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
   9226 	if (n < 0)
   9227 		mupa = isl_multi_union_pw_aff_free(mupa);
   9228 	if (!mupa)
   9229 		return NULL;
   9230 
   9231 	if (n == 0)
   9232 		return isl_union_map_from_multi_union_pw_aff_0D(mupa);
   9233 
   9234 	upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
   9235 	umap = isl_union_map_from_union_pw_aff(upa);
   9236 
   9237 	for (i = 1; i < n; ++i) {
   9238 		isl_union_map *umap_i;
   9239 
   9240 		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
   9241 		umap_i = isl_union_map_from_union_pw_aff(upa);
   9242 		umap = isl_union_map_flat_range_product(umap, umap_i);
   9243 	}
   9244 
   9245 	space = isl_multi_union_pw_aff_get_space(mupa);
   9246 	umap = isl_union_map_reset_range_space(umap, space);
   9247 
   9248 	isl_multi_union_pw_aff_free(mupa);
   9249 	return umap;
   9250 }
   9251 
   9252 /* Internal data structure for isl_union_pw_multi_aff_reset_range_space.
   9253  * "range" is the space from which to set the range space.
   9254  * "res" collects the results.
   9255  */
   9256 struct isl_union_pw_multi_aff_reset_range_space_data {
   9257 	isl_space *range;
   9258 	isl_union_pw_multi_aff *res;
   9259 };
   9260 
   9261 /* Replace the range space of "pma" by the range space of data->range and
   9262  * add the result to data->res.
   9263  */
   9264 static isl_stat reset_range_space(__isl_take isl_pw_multi_aff *pma, void *user)
   9265 {
   9266 	struct isl_union_pw_multi_aff_reset_range_space_data *data = user;
   9267 	isl_space *space;
   9268 
   9269 	space = isl_pw_multi_aff_get_space(pma);
   9270 	space = isl_space_domain(space);
   9271 	space = isl_space_extend_domain_with_range(space,
   9272 						isl_space_copy(data->range));
   9273 	pma = isl_pw_multi_aff_reset_space(pma, space);
   9274 	data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma);
   9275 
   9276 	return data->res ? isl_stat_ok : isl_stat_error;
   9277 }
   9278 
   9279 /* Replace the range space of all the piecewise affine expressions in "upma" by
   9280  * the range space of "space".
   9281  *
   9282  * This assumes that all these expressions have the same output dimension.
   9283  *
   9284  * Since the spaces of the expressions change, so do their hash values.
   9285  * We therefore need to create a new isl_union_pw_multi_aff.
   9286  * Note that the hash value is currently computed based on the entire
   9287  * space even though there can only be a single expression with a given
   9288  * domain space.
   9289  */
   9290 static __isl_give isl_union_pw_multi_aff *
   9291 isl_union_pw_multi_aff_reset_range_space(
   9292 	__isl_take isl_union_pw_multi_aff *upma, __isl_take isl_space *space)
   9293 {
   9294 	struct isl_union_pw_multi_aff_reset_range_space_data data = { space };
   9295 	isl_space *space_upma;
   9296 
   9297 	space_upma = isl_union_pw_multi_aff_get_space(upma);
   9298 	data.res = isl_union_pw_multi_aff_empty(space_upma);
   9299 	if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
   9300 					&reset_range_space, &data) < 0)
   9301 		data.res = isl_union_pw_multi_aff_free(data.res);
   9302 
   9303 	isl_space_free(space);
   9304 	isl_union_pw_multi_aff_free(upma);
   9305 	return data.res;
   9306 }
   9307 
   9308 /* Construct and return a union piecewise multi affine expression
   9309  * that is equal to the given multi union piecewise affine expression,
   9310  * in the special case of a 0D multi union piecewise affine expression.
   9311  *
   9312  * Construct a union piecewise multi affine expression
   9313  * on top of the explicit domain of the input.
   9314  */
   9315 __isl_give isl_union_pw_multi_aff *
   9316 isl_union_pw_multi_aff_from_multi_union_pw_aff_0D(
   9317 	__isl_take isl_multi_union_pw_aff *mupa)
   9318 {
   9319 	isl_space *space;
   9320 	isl_multi_val *mv;
   9321 	isl_union_set *domain;
   9322 
   9323 	space = isl_multi_union_pw_aff_get_space(mupa);
   9324 	mv = isl_multi_val_zero(space);
   9325 	domain = isl_multi_union_pw_aff_domain(mupa);
   9326 	return isl_union_pw_multi_aff_multi_val_on_domain(domain, mv);
   9327 }
   9328 
   9329 /* Construct and return a union piecewise multi affine expression
   9330  * that is equal to the given multi union piecewise affine expression.
   9331  *
   9332  * If the input is zero-dimensional, then
   9333  * construct a union piecewise multi affine expression
   9334  * on top of the explicit domain of the input.
   9335  */
   9336 __isl_give isl_union_pw_multi_aff *
   9337 isl_union_pw_multi_aff_from_multi_union_pw_aff(
   9338 	__isl_take isl_multi_union_pw_aff *mupa)
   9339 {
   9340 	int i;
   9341 	isl_size n;
   9342 	isl_space *space;
   9343 	isl_union_pw_multi_aff *upma;
   9344 	isl_union_pw_aff *upa;
   9345 
   9346 	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
   9347 	if (n < 0)
   9348 		mupa = isl_multi_union_pw_aff_free(mupa);
   9349 	if (!mupa)
   9350 		return NULL;
   9351 
   9352 	if (n == 0)
   9353 		return isl_union_pw_multi_aff_from_multi_union_pw_aff_0D(mupa);
   9354 
   9355 	space = isl_multi_union_pw_aff_get_space(mupa);
   9356 	upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
   9357 	upma = isl_union_pw_multi_aff_from_union_pw_aff(upa);
   9358 
   9359 	for (i = 1; i < n; ++i) {
   9360 		isl_union_pw_multi_aff *upma_i;
   9361 
   9362 		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
   9363 		upma_i = isl_union_pw_multi_aff_from_union_pw_aff(upa);
   9364 		upma = isl_union_pw_multi_aff_flat_range_product(upma, upma_i);
   9365 	}
   9366 
   9367 	upma = isl_union_pw_multi_aff_reset_range_space(upma, space);
   9368 
   9369 	isl_multi_union_pw_aff_free(mupa);
   9370 	return upma;
   9371 }
   9372 
   9373 /* Intersect the range of "mupa" with "range",
   9374  * in the special case where "mupa" is 0D.
   9375  *
   9376  * Intersect the domain of "mupa" with the constraints on the parameters
   9377  * of "range".
   9378  */
   9379 static __isl_give isl_multi_union_pw_aff *mupa_intersect_range_0D(
   9380 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_set *range)
   9381 {
   9382 	range = isl_set_params(range);
   9383 	mupa = isl_multi_union_pw_aff_intersect_params(mupa, range);
   9384 	return mupa;
   9385 }
   9386 
   9387 /* Intersect the range of "mupa" with "range".
   9388  * That is, keep only those domain elements that have a function value
   9389  * in "range".
   9390  */
   9391 __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_intersect_range(
   9392 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_set *range)
   9393 {
   9394 	isl_union_pw_multi_aff *upma;
   9395 	isl_union_set *domain;
   9396 	isl_space *space;
   9397 	isl_size n;
   9398 	int match;
   9399 
   9400 	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
   9401 	if (n < 0 || !range)
   9402 		goto error;
   9403 
   9404 	space = isl_set_get_space(range);
   9405 	match = isl_space_tuple_is_equal(mupa->space, isl_dim_set,
   9406 					space, isl_dim_set);
   9407 	isl_space_free(space);
   9408 	if (match < 0)
   9409 		goto error;
   9410 	if (!match)
   9411 		isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid,
   9412 			"space don't match", goto error);
   9413 	if (n == 0)
   9414 		return mupa_intersect_range_0D(mupa, range);
   9415 
   9416 	upma = isl_union_pw_multi_aff_from_multi_union_pw_aff(
   9417 					isl_multi_union_pw_aff_copy(mupa));
   9418 	domain = isl_union_set_from_set(range);
   9419 	domain = isl_union_set_preimage_union_pw_multi_aff(domain, upma);
   9420 	mupa = isl_multi_union_pw_aff_intersect_domain(mupa, domain);
   9421 
   9422 	return mupa;
   9423 error:
   9424 	isl_multi_union_pw_aff_free(mupa);
   9425 	isl_set_free(range);
   9426 	return NULL;
   9427 }
   9428 
   9429 /* Return the shared domain of the elements of "mupa",
   9430  * in the special case where "mupa" is zero-dimensional.
   9431  *
   9432  * Return the explicit domain of "mupa".
   9433  * Note that this domain may be a parameter set, either
   9434  * because "mupa" is meant to live in a set space or
   9435  * because no explicit domain has been set.
   9436  */
   9437 __isl_give isl_union_set *isl_multi_union_pw_aff_domain_0D(
   9438 	__isl_take isl_multi_union_pw_aff *mupa)
   9439 {
   9440 	isl_union_set *dom;
   9441 
   9442 	dom = isl_multi_union_pw_aff_get_explicit_domain(mupa);
   9443 	isl_multi_union_pw_aff_free(mupa);
   9444 
   9445 	return dom;
   9446 }
   9447 
   9448 /* Return the shared domain of the elements of "mupa".
   9449  *
   9450  * If "mupa" is zero-dimensional, then return its explicit domain.
   9451  */
   9452 __isl_give isl_union_set *isl_multi_union_pw_aff_domain(
   9453 	__isl_take isl_multi_union_pw_aff *mupa)
   9454 {
   9455 	int i;
   9456 	isl_size n;
   9457 	isl_union_pw_aff *upa;
   9458 	isl_union_set *dom;
   9459 
   9460 	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
   9461 	if (n < 0)
   9462 		mupa = isl_multi_union_pw_aff_free(mupa);
   9463 	if (!mupa)
   9464 		return NULL;
   9465 
   9466 	if (n == 0)
   9467 		return isl_multi_union_pw_aff_domain_0D(mupa);
   9468 
   9469 	upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
   9470 	dom = isl_union_pw_aff_domain(upa);
   9471 	for (i = 1; i < n; ++i) {
   9472 		isl_union_set *dom_i;
   9473 
   9474 		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
   9475 		dom_i = isl_union_pw_aff_domain(upa);
   9476 		dom = isl_union_set_intersect(dom, dom_i);
   9477 	}
   9478 
   9479 	isl_multi_union_pw_aff_free(mupa);
   9480 	return dom;
   9481 }
   9482 
   9483 /* Apply "aff" to "mupa".  The space of "mupa" is equal to the domain of "aff".
   9484  * In particular, the spaces have been aligned.
   9485  * The result is defined over the shared domain of the elements of "mupa"
   9486  *
   9487  * We first extract the parametric constant part of "aff" and
   9488  * define that over the shared domain.
   9489  * Then we iterate over all input dimensions of "aff" and add the corresponding
   9490  * multiples of the elements of "mupa".
   9491  * Finally, we consider the integer divisions, calling the function
   9492  * recursively to obtain an isl_union_pw_aff corresponding to the
   9493  * integer division argument.
   9494  */
   9495 static __isl_give isl_union_pw_aff *multi_union_pw_aff_apply_aff(
   9496 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff)
   9497 {
   9498 	int i;
   9499 	isl_size n_in, n_div;
   9500 	isl_union_pw_aff *upa;
   9501 	isl_union_set *uset;
   9502 	isl_val *v;
   9503 	isl_aff *cst;
   9504 
   9505 	n_in = isl_aff_dim(aff, isl_dim_in);
   9506 	n_div = isl_aff_dim(aff, isl_dim_div);
   9507 	if (n_in < 0 || n_div < 0)
   9508 		goto error;
   9509 
   9510 	uset = isl_multi_union_pw_aff_domain(isl_multi_union_pw_aff_copy(mupa));
   9511 	cst = isl_aff_copy(aff);
   9512 	cst = isl_aff_drop_dims(cst, isl_dim_div, 0, n_div);
   9513 	cst = isl_aff_drop_dims(cst, isl_dim_in, 0, n_in);
   9514 	cst = isl_aff_project_domain_on_params(cst);
   9515 	upa = isl_union_pw_aff_aff_on_domain(uset, cst);
   9516 
   9517 	for (i = 0; i < n_in; ++i) {
   9518 		isl_union_pw_aff *upa_i;
   9519 
   9520 		if (!isl_aff_involves_dims(aff, isl_dim_in, i, 1))
   9521 			continue;
   9522 		v = isl_aff_get_coefficient_val(aff, isl_dim_in, i);
   9523 		upa_i = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
   9524 		upa_i = isl_union_pw_aff_scale_val(upa_i, v);
   9525 		upa = isl_union_pw_aff_add(upa, upa_i);
   9526 	}
   9527 
   9528 	for (i = 0; i < n_div; ++i) {
   9529 		isl_aff *div;
   9530 		isl_union_pw_aff *upa_i;
   9531 
   9532 		if (!isl_aff_involves_dims(aff, isl_dim_div, i, 1))
   9533 			continue;
   9534 		div = isl_aff_get_div(aff, i);
   9535 		upa_i = multi_union_pw_aff_apply_aff(
   9536 					isl_multi_union_pw_aff_copy(mupa), div);
   9537 		upa_i = isl_union_pw_aff_floor(upa_i);
   9538 		v = isl_aff_get_coefficient_val(aff, isl_dim_div, i);
   9539 		upa_i = isl_union_pw_aff_scale_val(upa_i, v);
   9540 		upa = isl_union_pw_aff_add(upa, upa_i);
   9541 	}
   9542 
   9543 	isl_multi_union_pw_aff_free(mupa);
   9544 	isl_aff_free(aff);
   9545 
   9546 	return upa;
   9547 error:
   9548 	isl_multi_union_pw_aff_free(mupa);
   9549 	isl_aff_free(aff);
   9550 	return NULL;
   9551 }
   9552 
   9553 /* Apply "aff" to "mupa".  The space of "mupa" needs to be compatible
   9554  * with the domain of "aff".
   9555  * Furthermore, the dimension of this space needs to be greater than zero.
   9556  * The result is defined over the shared domain of the elements of "mupa"
   9557  *
   9558  * We perform these checks and then hand over control to
   9559  * multi_union_pw_aff_apply_aff.
   9560  */
   9561 __isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_aff(
   9562 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff)
   9563 {
   9564 	isl_size dim;
   9565 	isl_space *space1, *space2;
   9566 	isl_bool equal;
   9567 
   9568 	mupa = isl_multi_union_pw_aff_align_params(mupa,
   9569 						isl_aff_get_space(aff));
   9570 	aff = isl_aff_align_params(aff, isl_multi_union_pw_aff_get_space(mupa));
   9571 	if (!mupa || !aff)
   9572 		goto error;
   9573 
   9574 	space1 = isl_multi_union_pw_aff_get_space(mupa);
   9575 	space2 = isl_aff_get_domain_space(aff);
   9576 	equal = isl_space_is_equal(space1, space2);
   9577 	isl_space_free(space1);
   9578 	isl_space_free(space2);
   9579 	if (equal < 0)
   9580 		goto error;
   9581 	if (!equal)
   9582 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   9583 			"spaces don't match", goto error);
   9584 	dim = isl_aff_dim(aff, isl_dim_in);
   9585 	if (dim < 0)
   9586 		goto error;
   9587 	if (dim == 0)
   9588 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   9589 			"cannot determine domains", goto error);
   9590 
   9591 	return multi_union_pw_aff_apply_aff(mupa, aff);
   9592 error:
   9593 	isl_multi_union_pw_aff_free(mupa);
   9594 	isl_aff_free(aff);
   9595 	return NULL;
   9596 }
   9597 
   9598 /* Apply "ma" to "mupa", in the special case where "mupa" is 0D.
   9599  * The space of "mupa" is known to be compatible with the domain of "ma".
   9600  *
   9601  * Construct an isl_multi_union_pw_aff that is equal to "ma"
   9602  * on the domain of "mupa".
   9603  */
   9604 static __isl_give isl_multi_union_pw_aff *mupa_apply_multi_aff_0D(
   9605 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma)
   9606 {
   9607 	isl_union_set *dom;
   9608 
   9609 	dom = isl_multi_union_pw_aff_domain(mupa);
   9610 	ma = isl_multi_aff_project_domain_on_params(ma);
   9611 
   9612 	return isl_multi_union_pw_aff_multi_aff_on_domain(dom, ma);
   9613 }
   9614 
   9615 /* Apply "ma" to "mupa".  The space of "mupa" needs to be compatible
   9616  * with the domain of "ma".
   9617  * The result is defined over the shared domain of the elements of "mupa"
   9618  */
   9619 __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_multi_aff(
   9620 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma)
   9621 {
   9622 	isl_space *space1, *space2;
   9623 	isl_multi_union_pw_aff *res;
   9624 	isl_bool equal;
   9625 	int i;
   9626 	isl_size n_in, n_out;
   9627 
   9628 	mupa = isl_multi_union_pw_aff_align_params(mupa,
   9629 						isl_multi_aff_get_space(ma));
   9630 	ma = isl_multi_aff_align_params(ma,
   9631 					isl_multi_union_pw_aff_get_space(mupa));
   9632 	n_in = isl_multi_aff_dim(ma, isl_dim_in);
   9633 	n_out = isl_multi_aff_dim(ma, isl_dim_out);
   9634 	if (!mupa || n_in < 0 || n_out < 0)
   9635 		goto error;
   9636 
   9637 	space1 = isl_multi_union_pw_aff_get_space(mupa);
   9638 	space2 = isl_multi_aff_get_domain_space(ma);
   9639 	equal = isl_space_is_equal(space1, space2);
   9640 	isl_space_free(space1);
   9641 	isl_space_free(space2);
   9642 	if (equal < 0)
   9643 		goto error;
   9644 	if (!equal)
   9645 		isl_die(isl_multi_aff_get_ctx(ma), isl_error_invalid,
   9646 			"spaces don't match", goto error);
   9647 	if (n_in == 0)
   9648 		return mupa_apply_multi_aff_0D(mupa, ma);
   9649 
   9650 	space1 = isl_space_range(isl_multi_aff_get_space(ma));
   9651 	res = isl_multi_union_pw_aff_alloc(space1);
   9652 
   9653 	for (i = 0; i < n_out; ++i) {
   9654 		isl_aff *aff;
   9655 		isl_union_pw_aff *upa;
   9656 
   9657 		aff = isl_multi_aff_get_aff(ma, i);
   9658 		upa = multi_union_pw_aff_apply_aff(
   9659 					isl_multi_union_pw_aff_copy(mupa), aff);
   9660 		res = isl_multi_union_pw_aff_set_union_pw_aff(res, i, upa);
   9661 	}
   9662 
   9663 	isl_multi_aff_free(ma);
   9664 	isl_multi_union_pw_aff_free(mupa);
   9665 	return res;
   9666 error:
   9667 	isl_multi_union_pw_aff_free(mupa);
   9668 	isl_multi_aff_free(ma);
   9669 	return NULL;
   9670 }
   9671 
   9672 /* Apply "pa" to "mupa", in the special case where "mupa" is 0D.
   9673  * The space of "mupa" is known to be compatible with the domain of "pa".
   9674  *
   9675  * Construct an isl_multi_union_pw_aff that is equal to "pa"
   9676  * on the domain of "mupa".
   9677  */
   9678 static __isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_pw_aff_0D(
   9679 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_pw_aff *pa)
   9680 {
   9681 	isl_union_set *dom;
   9682 
   9683 	dom = isl_multi_union_pw_aff_domain(mupa);
   9684 	pa = isl_pw_aff_project_domain_on_params(pa);
   9685 
   9686 	return isl_union_pw_aff_pw_aff_on_domain(dom, pa);
   9687 }
   9688 
   9689 /* Apply "pa" to "mupa".  The space of "mupa" needs to be compatible
   9690  * with the domain of "pa".
   9691  * Furthermore, the dimension of this space needs to be greater than zero.
   9692  * The result is defined over the shared domain of the elements of "mupa"
   9693  */
   9694 __isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_pw_aff(
   9695 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_pw_aff *pa)
   9696 {
   9697 	int i;
   9698 	isl_bool equal;
   9699 	isl_size n_in;
   9700 	isl_space *space, *space2;
   9701 	isl_union_pw_aff *upa;
   9702 
   9703 	mupa = isl_multi_union_pw_aff_align_params(mupa,
   9704 						isl_pw_aff_get_space(pa));
   9705 	pa = isl_pw_aff_align_params(pa,
   9706 				    isl_multi_union_pw_aff_get_space(mupa));
   9707 	if (!mupa || !pa)
   9708 		goto error;
   9709 
   9710 	space = isl_multi_union_pw_aff_get_space(mupa);
   9711 	space2 = isl_pw_aff_get_domain_space(pa);
   9712 	equal = isl_space_is_equal(space, space2);
   9713 	isl_space_free(space);
   9714 	isl_space_free(space2);
   9715 	if (equal < 0)
   9716 		goto error;
   9717 	if (!equal)
   9718 		isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
   9719 			"spaces don't match", goto error);
   9720 	n_in = isl_pw_aff_dim(pa, isl_dim_in);
   9721 	if (n_in < 0)
   9722 		goto error;
   9723 	if (n_in == 0)
   9724 		return isl_multi_union_pw_aff_apply_pw_aff_0D(mupa, pa);
   9725 
   9726 	space = isl_space_params(isl_multi_union_pw_aff_get_space(mupa));
   9727 	upa = isl_union_pw_aff_empty(space);
   9728 
   9729 	for (i = 0; i < pa->n; ++i) {
   9730 		isl_aff *aff;
   9731 		isl_set *domain;
   9732 		isl_multi_union_pw_aff *mupa_i;
   9733 		isl_union_pw_aff *upa_i;
   9734 
   9735 		mupa_i = isl_multi_union_pw_aff_copy(mupa);
   9736 		domain = isl_set_copy(pa->p[i].set);
   9737 		mupa_i = isl_multi_union_pw_aff_intersect_range(mupa_i, domain);
   9738 		aff = isl_aff_copy(pa->p[i].aff);
   9739 		upa_i = multi_union_pw_aff_apply_aff(mupa_i, aff);
   9740 		upa = isl_union_pw_aff_union_add(upa, upa_i);
   9741 	}
   9742 
   9743 	isl_multi_union_pw_aff_free(mupa);
   9744 	isl_pw_aff_free(pa);
   9745 	return upa;
   9746 error:
   9747 	isl_multi_union_pw_aff_free(mupa);
   9748 	isl_pw_aff_free(pa);
   9749 	return NULL;
   9750 }
   9751 
   9752 /* Apply "pma" to "mupa", in the special case where "mupa" is 0D.
   9753  * The space of "mupa" is known to be compatible with the domain of "pma".
   9754  *
   9755  * Construct an isl_multi_union_pw_aff that is equal to "pma"
   9756  * on the domain of "mupa".
   9757  */
   9758 static __isl_give isl_multi_union_pw_aff *mupa_apply_pw_multi_aff_0D(
   9759 	__isl_take isl_multi_union_pw_aff *mupa,
   9760 	__isl_take isl_pw_multi_aff *pma)
   9761 {
   9762 	isl_union_set *dom;
   9763 
   9764 	dom = isl_multi_union_pw_aff_domain(mupa);
   9765 	pma = isl_pw_multi_aff_project_domain_on_params(pma);
   9766 
   9767 	return isl_multi_union_pw_aff_pw_multi_aff_on_domain(dom, pma);
   9768 }
   9769 
   9770 /* Apply "pma" to "mupa".  The space of "mupa" needs to be compatible
   9771  * with the domain of "pma".
   9772  * The result is defined over the shared domain of the elements of "mupa"
   9773  */
   9774 __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_pw_multi_aff(
   9775 	__isl_take isl_multi_union_pw_aff *mupa,
   9776 	__isl_take isl_pw_multi_aff *pma)
   9777 {
   9778 	isl_space *space1, *space2;
   9779 	isl_multi_union_pw_aff *res;
   9780 	isl_bool equal;
   9781 	int i;
   9782 	isl_size n_in, n_out;
   9783 
   9784 	mupa = isl_multi_union_pw_aff_align_params(mupa,
   9785 					isl_pw_multi_aff_get_space(pma));
   9786 	pma = isl_pw_multi_aff_align_params(pma,
   9787 					isl_multi_union_pw_aff_get_space(mupa));
   9788 	if (!mupa || !pma)
   9789 		goto error;
   9790 
   9791 	space1 = isl_multi_union_pw_aff_get_space(mupa);
   9792 	space2 = isl_pw_multi_aff_get_domain_space(pma);
   9793 	equal = isl_space_is_equal(space1, space2);
   9794 	isl_space_free(space1);
   9795 	isl_space_free(space2);
   9796 	if (equal < 0)
   9797 		goto error;
   9798 	if (!equal)
   9799 		isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
   9800 			"spaces don't match", goto error);
   9801 	n_in = isl_pw_multi_aff_dim(pma, isl_dim_in);
   9802 	n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
   9803 	if (n_in < 0 || n_out < 0)
   9804 		goto error;
   9805 	if (n_in == 0)
   9806 		return mupa_apply_pw_multi_aff_0D(mupa, pma);
   9807 
   9808 	space1 = isl_space_range(isl_pw_multi_aff_get_space(pma));
   9809 	res = isl_multi_union_pw_aff_alloc(space1);
   9810 
   9811 	for (i = 0; i < n_out; ++i) {
   9812 		isl_pw_aff *pa;
   9813 		isl_union_pw_aff *upa;
   9814 
   9815 		pa = isl_pw_multi_aff_get_pw_aff(pma, i);
   9816 		upa = isl_multi_union_pw_aff_apply_pw_aff(
   9817 					isl_multi_union_pw_aff_copy(mupa), pa);
   9818 		res = isl_multi_union_pw_aff_set_union_pw_aff(res, i, upa);
   9819 	}
   9820 
   9821 	isl_pw_multi_aff_free(pma);
   9822 	isl_multi_union_pw_aff_free(mupa);
   9823 	return res;
   9824 error:
   9825 	isl_multi_union_pw_aff_free(mupa);
   9826 	isl_pw_multi_aff_free(pma);
   9827 	return NULL;
   9828 }
   9829 
   9830 /* Replace the explicit domain of "mupa" by its preimage under "upma".
   9831  * If the explicit domain only keeps track of constraints on the parameters,
   9832  * then only update those constraints.
   9833  */
   9834 static __isl_give isl_multi_union_pw_aff *preimage_explicit_domain(
   9835 	__isl_take isl_multi_union_pw_aff *mupa,
   9836 	__isl_keep isl_union_pw_multi_aff *upma)
   9837 {
   9838 	isl_bool is_params;
   9839 
   9840 	if (isl_multi_union_pw_aff_check_has_explicit_domain(mupa) < 0)
   9841 		return isl_multi_union_pw_aff_free(mupa);
   9842 
   9843 	mupa = isl_multi_union_pw_aff_cow(mupa);
   9844 	if (!mupa)
   9845 		return NULL;
   9846 
   9847 	is_params = isl_union_set_is_params(mupa->u.dom);
   9848 	if (is_params < 0)
   9849 		return isl_multi_union_pw_aff_free(mupa);
   9850 
   9851 	upma = isl_union_pw_multi_aff_copy(upma);
   9852 	if (is_params)
   9853 		mupa->u.dom = isl_union_set_intersect_params(mupa->u.dom,
   9854 		    isl_union_set_params(isl_union_pw_multi_aff_domain(upma)));
   9855 	else
   9856 		mupa->u.dom = isl_union_set_preimage_union_pw_multi_aff(
   9857 							    mupa->u.dom, upma);
   9858 	if (!mupa->u.dom)
   9859 		return isl_multi_union_pw_aff_free(mupa);
   9860 	return mupa;
   9861 }
   9862 
   9863 /* Compute the pullback of "mupa" by the function represented by "upma".
   9864  * In other words, plug in "upma" in "mupa".  The result contains
   9865  * expressions defined over the domain space of "upma".
   9866  *
   9867  * Run over all elements of "mupa" and plug in "upma" in each of them.
   9868  *
   9869  * If "mupa" has an explicit domain, then it is this domain
   9870  * that needs to undergo a pullback instead, i.e., a preimage.
   9871  */
   9872 __isl_give isl_multi_union_pw_aff *
   9873 isl_multi_union_pw_aff_pullback_union_pw_multi_aff(
   9874 	__isl_take isl_multi_union_pw_aff *mupa,
   9875 	__isl_take isl_union_pw_multi_aff *upma)
   9876 {
   9877 	int i;
   9878 	isl_size n;
   9879 
   9880 	mupa = isl_multi_union_pw_aff_align_params(mupa,
   9881 				    isl_union_pw_multi_aff_get_space(upma));
   9882 	upma = isl_union_pw_multi_aff_align_params(upma,
   9883 				    isl_multi_union_pw_aff_get_space(mupa));
   9884 	mupa = isl_multi_union_pw_aff_cow(mupa);
   9885 	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
   9886 	if (n < 0 || !upma)
   9887 		goto error;
   9888 
   9889 	for (i = 0; i < n; ++i) {
   9890 		isl_union_pw_aff *upa;
   9891 
   9892 		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
   9893 		upa = isl_union_pw_aff_pullback_union_pw_multi_aff(upa,
   9894 					    isl_union_pw_multi_aff_copy(upma));
   9895 		mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
   9896 	}
   9897 
   9898 	if (isl_multi_union_pw_aff_has_explicit_domain(mupa))
   9899 		mupa = preimage_explicit_domain(mupa, upma);
   9900 
   9901 	isl_union_pw_multi_aff_free(upma);
   9902 	return mupa;
   9903 error:
   9904 	isl_multi_union_pw_aff_free(mupa);
   9905 	isl_union_pw_multi_aff_free(upma);
   9906 	return NULL;
   9907 }
   9908 
   9909 /* Extract the sequence of elements in "mupa" with domain space "space"
   9910  * (ignoring parameters).
   9911  *
   9912  * For the elements of "mupa" that are not defined on the specified space,
   9913  * the corresponding element in the result is empty.
   9914  */
   9915 __isl_give isl_multi_pw_aff *isl_multi_union_pw_aff_extract_multi_pw_aff(
   9916 	__isl_keep isl_multi_union_pw_aff *mupa, __isl_take isl_space *space)
   9917 {
   9918 	int i;
   9919 	isl_size n;
   9920 	isl_space *space_mpa;
   9921 	isl_multi_pw_aff *mpa;
   9922 
   9923 	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
   9924 	if (n < 0 || !space)
   9925 		goto error;
   9926 
   9927 	space_mpa = isl_multi_union_pw_aff_get_space(mupa);
   9928 	space = isl_space_replace_params(space, space_mpa);
   9929 	space_mpa = isl_space_map_from_domain_and_range(isl_space_copy(space),
   9930 							space_mpa);
   9931 	mpa = isl_multi_pw_aff_alloc(space_mpa);
   9932 
   9933 	space = isl_space_from_domain(space);
   9934 	space = isl_space_add_dims(space, isl_dim_out, 1);
   9935 	for (i = 0; i < n; ++i) {
   9936 		isl_union_pw_aff *upa;
   9937 		isl_pw_aff *pa;
   9938 
   9939 		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
   9940 		pa = isl_union_pw_aff_extract_pw_aff(upa,
   9941 							isl_space_copy(space));
   9942 		mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa);
   9943 		isl_union_pw_aff_free(upa);
   9944 	}
   9945 
   9946 	isl_space_free(space);
   9947 	return mpa;
   9948 error:
   9949 	isl_space_free(space);
   9950 	return NULL;
   9951 }
   9952 
   9953 /* Data structure that specifies how isl_union_pw_multi_aff_un_op
   9954  * should modify the base expressions in the input.
   9955  *
   9956  * If "filter" is not NULL, then only the base expressions that satisfy "filter"
   9957  * are taken into account.
   9958  * "fn" is applied to each entry in the input.
   9959  */
   9960 struct isl_union_pw_multi_aff_un_op_control {
   9961 	isl_bool (*filter)(__isl_keep isl_pw_multi_aff *part);
   9962 	__isl_give isl_pw_multi_aff *(*fn)(__isl_take isl_pw_multi_aff *pma);
   9963 };
   9964 
   9965 /* Wrapper for isl_union_pw_multi_aff_un_op filter functions (which do not take
   9966  * a second argument) for use as an isl_union_pw_multi_aff_transform
   9967  * filter function (which does take a second argument).
   9968  * Simply call control->filter without the second argument.
   9969  */
   9970 static isl_bool isl_union_pw_multi_aff_un_op_filter_drop_user(
   9971 	__isl_take isl_pw_multi_aff *pma, void *user)
   9972 {
   9973 	struct isl_union_pw_multi_aff_un_op_control *control = user;
   9974 
   9975 	return control->filter(pma);
   9976 }
   9977 
   9978 /* Wrapper for isl_union_pw_multi_aff_un_op base functions (which do not take
   9979  * a second argument) for use as an isl_union_pw_multi_aff_transform
   9980  * base function (which does take a second argument).
   9981  * Simply call control->fn without the second argument.
   9982  */
   9983 static __isl_give isl_pw_multi_aff *isl_union_pw_multi_aff_un_op_drop_user(
   9984 	__isl_take isl_pw_multi_aff *pma, void *user)
   9985 {
   9986 	struct isl_union_pw_multi_aff_un_op_control *control = user;
   9987 
   9988 	return control->fn(pma);
   9989 }
   9990 
   9991 /* Construct an isl_union_pw_multi_aff that is obtained by
   9992  * modifying "upma" according to "control".
   9993  *
   9994  * isl_union_pw_multi_aff_transform performs essentially
   9995  * the same operation, but takes a filter and a callback function
   9996  * of a different form (with an extra argument).
   9997  * Call isl_union_pw_multi_aff_transform with wrappers
   9998  * that remove this extra argument.
   9999  */
   10000 static __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_un_op(
   10001 	__isl_take isl_union_pw_multi_aff *upma,
   10002 	struct isl_union_pw_multi_aff_un_op_control *control)
   10003 {
   10004 	struct isl_union_pw_multi_aff_transform_control t_control = {
   10005 		.filter = &isl_union_pw_multi_aff_un_op_filter_drop_user,
   10006 		.filter_user = control,
   10007 		.fn = &isl_union_pw_multi_aff_un_op_drop_user,
   10008 		.fn_user = control,
   10009 	};
   10010 
   10011 	return isl_union_pw_multi_aff_transform(upma, &t_control);
   10012 }
   10013 
   10014 /* For each function in "upma" of the form A -> [B -> C],
   10015  * extract the function A -> B and collect the results.
   10016  */
   10017 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_range_factor_domain(
   10018 	__isl_take isl_union_pw_multi_aff *upma)
   10019 {
   10020 	struct isl_union_pw_multi_aff_un_op_control control = {
   10021 		.filter = &isl_pw_multi_aff_range_is_wrapping,
   10022 		.fn = &isl_pw_multi_aff_range_factor_domain,
   10023 	};
   10024 	return isl_union_pw_multi_aff_un_op(upma, &control);
   10025 }
   10026 
   10027 /* For each function in "upma" of the form A -> [B -> C],
   10028  * extract the function A -> C and collect the results.
   10029  */
   10030 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_range_factor_range(
   10031 	__isl_take isl_union_pw_multi_aff *upma)
   10032 {
   10033 	struct isl_union_pw_multi_aff_un_op_control control = {
   10034 		.filter = &isl_pw_multi_aff_range_is_wrapping,
   10035 		.fn = &isl_pw_multi_aff_range_factor_range,
   10036 	};
   10037 	return isl_union_pw_multi_aff_un_op(upma, &control);
   10038 }
   10039 
   10040 /* Evaluate the affine function "aff" in the void point "pnt".
   10041  * In particular, return the value NaN.
   10042  */
   10043 static __isl_give isl_val *eval_void(__isl_take isl_aff *aff,
   10044 	__isl_take isl_point *pnt)
   10045 {
   10046 	isl_ctx *ctx;
   10047 
   10048 	ctx = isl_point_get_ctx(pnt);
   10049 	isl_aff_free(aff);
   10050 	isl_point_free(pnt);
   10051 	return isl_val_nan(ctx);
   10052 }
   10053 
   10054 /* Evaluate the affine expression "aff"
   10055  * in the coordinates (with denominator) "pnt".
   10056  */
   10057 static __isl_give isl_val *eval(__isl_keep isl_vec *aff,
   10058 	__isl_keep isl_vec *pnt)
   10059 {
   10060 	isl_int n, d;
   10061 	isl_ctx *ctx;
   10062 	isl_val *v;
   10063 
   10064 	if (!aff || !pnt)
   10065 		return NULL;
   10066 
   10067 	ctx = isl_vec_get_ctx(aff);
   10068 	isl_int_init(n);
   10069 	isl_int_init(d);
   10070 	isl_seq_inner_product(aff->el + 1, pnt->el, pnt->size, &n);
   10071 	isl_int_mul(d, aff->el[0], pnt->el[0]);
   10072 	v = isl_val_rat_from_isl_int(ctx, n, d);
   10073 	v = isl_val_normalize(v);
   10074 	isl_int_clear(n);
   10075 	isl_int_clear(d);
   10076 
   10077 	return v;
   10078 }
   10079 
   10080 /* Check that the domain space of "aff" is equal to "space".
   10081  */
   10082 static isl_stat isl_aff_check_has_domain_space(__isl_keep isl_aff *aff,
   10083 	__isl_keep isl_space *space)
   10084 {
   10085 	isl_bool ok;
   10086 
   10087 	ok = isl_space_is_equal(isl_aff_peek_domain_space(aff), space);
   10088 	if (ok < 0)
   10089 		return isl_stat_error;
   10090 	if (!ok)
   10091 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   10092 			"incompatible spaces", return isl_stat_error);
   10093 	return isl_stat_ok;
   10094 }
   10095 
   10096 /* Evaluate the affine function "aff" in "pnt".
   10097  */
   10098 __isl_give isl_val *isl_aff_eval(__isl_take isl_aff *aff,
   10099 	__isl_take isl_point *pnt)
   10100 {
   10101 	isl_bool is_void;
   10102 	isl_val *v;
   10103 	isl_local_space *ls;
   10104 
   10105 	if (isl_aff_check_has_domain_space(aff, isl_point_peek_space(pnt)) < 0)
   10106 		goto error;
   10107 	is_void = isl_point_is_void(pnt);
   10108 	if (is_void < 0)
   10109 		goto error;
   10110 	if (is_void)
   10111 		return eval_void(aff, pnt);
   10112 
   10113 	ls = isl_aff_get_domain_local_space(aff);
   10114 	pnt = isl_local_space_lift_point(ls, pnt);
   10115 
   10116 	v = eval(aff->v, isl_point_peek_vec(pnt));
   10117 
   10118 	isl_aff_free(aff);
   10119 	isl_point_free(pnt);
   10120 
   10121 	return v;
   10122 error:
   10123 	isl_aff_free(aff);
   10124 	isl_point_free(pnt);
   10125 	return NULL;
   10126 }
   10127