Home | History | Annotate | Line # | Download | only in dist
      1 /*
      2  * Copyright 2010      INRIA Saclay
      3  *
      4  * Use of this software is governed by the MIT license
      5  *
      6  * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
      7  * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
      8  * 91893 Orsay, France
      9  */
     10 
     11 #include <isl_map_private.h>
     12 #include <isl/set.h>
     13 #include <isl_space_private.h>
     14 #include <isl_seq.h>
     15 #include <isl_aff_private.h>
     16 #include <isl_mat_private.h>
     17 #include <isl_factorization.h>
     18 
     19 /*
     20  * Let C be a cone and define
     21  *
     22  *	C' := { y | forall x in C : y x >= 0 }
     23  *
     24  * C' contains the coefficients of all linear constraints
     25  * that are valid for C.
     26  * Furthermore, C'' = C.
     27  *
     28  * If C is defined as { x | A x >= 0 }
     29  * then any element in C' must be a non-negative combination
     30  * of the rows of A, i.e., y = t A with t >= 0.  That is,
     31  *
     32  *	C' = { y | exists t >= 0 : y = t A }
     33  *
     34  * If any of the rows in A actually represents an equality, then
     35  * also negative combinations of this row are allowed and so the
     36  * non-negativity constraint on the corresponding element of t
     37  * can be dropped.
     38  *
     39  * A polyhedron P = { x | b + A x >= 0 } can be represented
     40  * in homogeneous coordinates by the cone
     41  * C = { [z,x] | b z + A x >= and z >= 0 }
     42  * The valid linear constraints on C correspond to the valid affine
     43  * constraints on P.
     44  * This is essentially Farkas' lemma.
     45  *
     46  * Since
     47  *				  [ 1 0 ]
     48  *		[ w y ] = [t_0 t] [ b A ]
     49  *
     50  * we have
     51  *
     52  *	C' = { w, y | exists t_0, t >= 0 : y = t A and w = t_0 + t b }
     53  * or
     54  *
     55  *	C' = { w, y | exists t >= 0 : y = t A and w - t b >= 0 }
     56  *
     57  * In practice, we introduce an extra variable (w), shifting all
     58  * other variables to the right, and an extra inequality
     59  * (w - t b >= 0) corresponding to the positivity constraint on
     60  * the homogeneous coordinate.
     61  *
     62  * When going back from coefficients to solutions, we immediately
     63  * plug in 1 for z, which corresponds to shifting all variables
     64  * to the left, with the leftmost ending up in the constant position.
     65  */
     66 
     67 /* Add the given prefix to all named isl_dim_set dimensions in "space".
     68  */
     69 static __isl_give isl_space *isl_space_prefix(__isl_take isl_space *space,
     70 	const char *prefix)
     71 {
     72 	int i;
     73 	isl_ctx *ctx;
     74 	isl_size nvar;
     75 	size_t prefix_len = strlen(prefix);
     76 
     77 	if (!space)
     78 		return NULL;
     79 
     80 	ctx = isl_space_get_ctx(space);
     81 	nvar = isl_space_dim(space, isl_dim_set);
     82 	if (nvar < 0)
     83 		return isl_space_free(space);
     84 
     85 	for (i = 0; i < nvar; ++i) {
     86 		const char *name;
     87 		char *prefix_name;
     88 
     89 		name = isl_space_get_dim_name(space, isl_dim_set, i);
     90 		if (!name)
     91 			continue;
     92 
     93 		prefix_name = isl_alloc_array(ctx, char,
     94 					      prefix_len + strlen(name) + 1);
     95 		if (!prefix_name)
     96 			goto error;
     97 		memcpy(prefix_name, prefix, prefix_len);
     98 		strcpy(prefix_name + prefix_len, name);
     99 
    100 		space = isl_space_set_dim_name(space,
    101 						isl_dim_set, i, prefix_name);
    102 		free(prefix_name);
    103 	}
    104 
    105 	return space;
    106 error:
    107 	isl_space_free(space);
    108 	return NULL;
    109 }
    110 
    111 /* Given a dimension specification of the solutions space, construct
    112  * a dimension specification for the space of coefficients.
    113  *
    114  * In particular transform
    115  *
    116  *	[params] -> { S }
    117  *
    118  * to
    119  *
    120  *	{ coefficients[[cst, params] -> S] }
    121  *
    122  * and prefix each dimension name with "c_".
    123  */
    124 static __isl_give isl_space *isl_space_coefficients(__isl_take isl_space *space)
    125 {
    126 	isl_space *space_param;
    127 	isl_size nvar;
    128 	isl_size nparam;
    129 
    130 	nvar = isl_space_dim(space, isl_dim_set);
    131 	nparam = isl_space_dim(space, isl_dim_param);
    132 	if (nvar < 0 || nparam < 0)
    133 		return isl_space_free(space);
    134 	space_param = isl_space_copy(space);
    135 	space_param = isl_space_drop_dims(space_param, isl_dim_set, 0, nvar);
    136 	space_param = isl_space_move_dims(space_param, isl_dim_set, 0,
    137 				 isl_dim_param, 0, nparam);
    138 	space_param = isl_space_prefix(space_param, "c_");
    139 	space_param = isl_space_insert_dims(space_param, isl_dim_set, 0, 1);
    140 	space_param = isl_space_set_dim_name(space_param,
    141 				isl_dim_set, 0, "c_cst");
    142 	space = isl_space_drop_dims(space, isl_dim_param, 0, nparam);
    143 	space = isl_space_prefix(space, "c_");
    144 	space = isl_space_join(isl_space_from_domain(space_param),
    145 			   isl_space_from_range(space));
    146 	space = isl_space_wrap(space);
    147 	space = isl_space_set_tuple_name(space, isl_dim_set, "coefficients");
    148 
    149 	return space;
    150 }
    151 
    152 /* Drop the given prefix from all named dimensions of type "type" in "space".
    153  */
    154 static __isl_give isl_space *isl_space_unprefix(__isl_take isl_space *space,
    155 	enum isl_dim_type type, const char *prefix)
    156 {
    157 	int i;
    158 	isl_size n;
    159 	size_t prefix_len = strlen(prefix);
    160 
    161 	n = isl_space_dim(space, type);
    162 	if (n < 0)
    163 		return isl_space_free(space);
    164 
    165 	for (i = 0; i < n; ++i) {
    166 		const char *name;
    167 
    168 		name = isl_space_get_dim_name(space, type, i);
    169 		if (!name)
    170 			continue;
    171 		if (strncmp(name, prefix, prefix_len))
    172 			continue;
    173 
    174 		space = isl_space_set_dim_name(space,
    175 						type, i, name + prefix_len);
    176 	}
    177 
    178 	return space;
    179 }
    180 
    181 /* Given a dimension specification of the space of coefficients, construct
    182  * a dimension specification for the space of solutions.
    183  *
    184  * In particular transform
    185  *
    186  *	{ coefficients[[cst, params] -> S] }
    187  *
    188  * to
    189  *
    190  *	[params] -> { S }
    191  *
    192  * and drop the "c_" prefix from the dimension names.
    193  */
    194 static __isl_give isl_space *isl_space_solutions(__isl_take isl_space *space)
    195 {
    196 	isl_size nparam;
    197 
    198 	space = isl_space_unwrap(space);
    199 	space = isl_space_drop_dims(space, isl_dim_in, 0, 1);
    200 	space = isl_space_unprefix(space, isl_dim_in, "c_");
    201 	space = isl_space_unprefix(space, isl_dim_out, "c_");
    202 	nparam = isl_space_dim(space, isl_dim_in);
    203 	if (nparam < 0)
    204 		return isl_space_free(space);
    205 	space = isl_space_move_dims(space,
    206 				    isl_dim_param, 0, isl_dim_in, 0, nparam);
    207 	space = isl_space_range(space);
    208 
    209 	return space;
    210 }
    211 
    212 /* Return the rational universe basic set in the given space.
    213  */
    214 static __isl_give isl_basic_set *rational_universe(__isl_take isl_space *space)
    215 {
    216 	isl_basic_set *bset;
    217 
    218 	bset = isl_basic_set_universe(space);
    219 	bset = isl_basic_set_set_rational(bset);
    220 
    221 	return bset;
    222 }
    223 
    224 /* Compute the dual of "bset" by applying Farkas' lemma.
    225  * As explained above, we add an extra dimension to represent
    226  * the coefficient of the constant term when going from solutions
    227  * to coefficients (shift == 1) and we drop the extra dimension when going
    228  * in the opposite direction (shift == -1).
    229  * The dual can be created in an arbitrary space.
    230  * The caller is responsible for putting the result in the appropriate space.
    231  *
    232  * If "bset" is (obviously) empty, then the way this emptiness
    233  * is represented by the constraints does not allow for the application
    234  * of the standard farkas algorithm.  We therefore handle this case
    235  * specifically and return the universe basic set.
    236  */
    237 static __isl_give isl_basic_set *farkas(__isl_take isl_basic_set *bset,
    238 	int shift)
    239 {
    240 	int i, j, k;
    241 	isl_ctx *ctx;
    242 	isl_space *space;
    243 	isl_basic_set *dual = NULL;
    244 	isl_size total;
    245 
    246 	total = isl_basic_set_dim(bset, isl_dim_all);
    247 	if (total < 0)
    248 		return isl_basic_set_free(bset);
    249 
    250 	ctx = isl_basic_set_get_ctx(bset);
    251 	space = isl_space_set_alloc(ctx, 0, total + shift);
    252 	if (isl_basic_set_plain_is_empty(bset)) {
    253 		isl_basic_set_free(bset);
    254 		return rational_universe(space);
    255 	}
    256 
    257 	dual = isl_basic_set_alloc_space(space, bset->n_eq + bset->n_ineq,
    258 					total, bset->n_ineq + (shift > 0));
    259 	dual = isl_basic_set_set_rational(dual);
    260 
    261 	for (i = 0; i < bset->n_eq + bset->n_ineq; ++i) {
    262 		k = isl_basic_set_alloc_div(dual);
    263 		if (k < 0)
    264 			goto error;
    265 		isl_int_set_si(dual->div[k][0], 0);
    266 	}
    267 
    268 	for (i = 0; i < total; ++i) {
    269 		k = isl_basic_set_alloc_equality(dual);
    270 		if (k < 0)
    271 			goto error;
    272 		isl_seq_clr(dual->eq[k], 1 + shift + total);
    273 		isl_int_set_si(dual->eq[k][1 + shift + i], -1);
    274 		for (j = 0; j < bset->n_eq; ++j)
    275 			isl_int_set(dual->eq[k][1 + shift + total + j],
    276 				    bset->eq[j][1 + i]);
    277 		for (j = 0; j < bset->n_ineq; ++j)
    278 			isl_int_set(dual->eq[k][1 + shift + total + bset->n_eq + j],
    279 				    bset->ineq[j][1 + i]);
    280 	}
    281 
    282 	for (i = 0; i < bset->n_ineq; ++i) {
    283 		k = isl_basic_set_alloc_inequality(dual);
    284 		if (k < 0)
    285 			goto error;
    286 		isl_seq_clr(dual->ineq[k],
    287 			    1 + shift + total + bset->n_eq + bset->n_ineq);
    288 		isl_int_set_si(dual->ineq[k][1 + shift + total + bset->n_eq + i], 1);
    289 	}
    290 
    291 	if (shift > 0) {
    292 		k = isl_basic_set_alloc_inequality(dual);
    293 		if (k < 0)
    294 			goto error;
    295 		isl_seq_clr(dual->ineq[k], 2 + total);
    296 		isl_int_set_si(dual->ineq[k][1], 1);
    297 		for (j = 0; j < bset->n_eq; ++j)
    298 			isl_int_neg(dual->ineq[k][2 + total + j],
    299 				    bset->eq[j][0]);
    300 		for (j = 0; j < bset->n_ineq; ++j)
    301 			isl_int_neg(dual->ineq[k][2 + total + bset->n_eq + j],
    302 				    bset->ineq[j][0]);
    303 	}
    304 
    305 	dual = isl_basic_set_remove_divs(dual);
    306 	dual = isl_basic_set_simplify(dual);
    307 	dual = isl_basic_set_finalize(dual);
    308 
    309 	isl_basic_set_free(bset);
    310 	return dual;
    311 error:
    312 	isl_basic_set_free(bset);
    313 	isl_basic_set_free(dual);
    314 	return NULL;
    315 }
    316 
    317 /* Construct a basic set containing the tuples of coefficients of all
    318  * valid affine constraints on the given basic set, ignoring
    319  * the space of input and output and without any further decomposition.
    320  */
    321 static __isl_give isl_basic_set *isl_basic_set_coefficients_base(
    322 	__isl_take isl_basic_set *bset)
    323 {
    324 	return farkas(bset, 1);
    325 }
    326 
    327 /* Return the inverse mapping of "morph".
    328  */
    329 static __isl_give isl_mat *peek_inv(__isl_keep isl_morph *morph)
    330 {
    331 	return morph ? morph->inv : NULL;
    332 }
    333 
    334 /* Return a copy of the inverse mapping of "morph".
    335  */
    336 static __isl_give isl_mat *get_inv(__isl_keep isl_morph *morph)
    337 {
    338 	return isl_mat_copy(peek_inv(morph));
    339 }
    340 
    341 /* Information about a single factor within isl_basic_set_coefficients_product.
    342  *
    343  * "start" is the position of the first coefficient (beyond
    344  * the one corresponding to the constant term) in this factor.
    345  * "dim" is the number of coefficients (other than
    346  * the one corresponding to the constant term) in this factor.
    347  * "n_line" is the number of lines in "coeff".
    348  * "n_ray" is the number of rays (other than lines) in "coeff".
    349  * "n_vertex" is the number of vertices in "coeff".
    350  *
    351  * While iterating over the vertices,
    352  * "pos" represents the inequality constraint corresponding
    353  * to the current vertex.
    354  */
    355 struct isl_coefficients_factor_data {
    356 	isl_basic_set *coeff;
    357 	int start;
    358 	int dim;
    359 	int n_line;
    360 	int n_ray;
    361 	int n_vertex;
    362 	int pos;
    363 };
    364 
    365 /* Internal data structure for isl_basic_set_coefficients_product.
    366  * "n" is the number of factors in the factorization.
    367  * "pos" is the next factor that will be considered.
    368  * "start_next" is the position of the first coefficient (beyond
    369  * the one corresponding to the constant term) in the next factor.
    370  * "factors" contains information about the individual "n" factors.
    371  */
    372 struct isl_coefficients_product_data {
    373 	int n;
    374 	int pos;
    375 	int start_next;
    376 	struct isl_coefficients_factor_data *factors;
    377 };
    378 
    379 /* Initialize the internal data structure for
    380  * isl_basic_set_coefficients_product.
    381  */
    382 static isl_stat isl_coefficients_product_data_init(isl_ctx *ctx,
    383 	struct isl_coefficients_product_data *data, int n)
    384 {
    385 	data->n = n;
    386 	data->pos = 0;
    387 	data->start_next = 0;
    388 	data->factors = isl_calloc_array(ctx,
    389 					struct isl_coefficients_factor_data, n);
    390 	if (!data->factors)
    391 		return isl_stat_error;
    392 	return isl_stat_ok;
    393 }
    394 
    395 /* Free all memory allocated in "data".
    396  */
    397 static void isl_coefficients_product_data_clear(
    398 	struct isl_coefficients_product_data *data)
    399 {
    400 	int i;
    401 
    402 	if (data->factors) {
    403 		for (i = 0; i < data->n; ++i) {
    404 			isl_basic_set_free(data->factors[i].coeff);
    405 		}
    406 	}
    407 	free(data->factors);
    408 }
    409 
    410 /* Does inequality "ineq" in the (dual) basic set "bset" represent a ray?
    411  * In particular, does it have a zero denominator
    412  * (i.e., a zero coefficient for the constant term)?
    413  */
    414 static int is_ray(__isl_keep isl_basic_set *bset, int ineq)
    415 {
    416 	return isl_int_is_zero(bset->ineq[ineq][1]);
    417 }
    418 
    419 /* isl_factorizer_every_factor_basic_set callback that
    420  * constructs a basic set containing the tuples of coefficients of all
    421  * valid affine constraints on the factor "bset" and
    422  * extracts further information that will be used
    423  * when combining the results over the different factors.
    424  */
    425 static isl_bool isl_basic_set_coefficients_factor(
    426 	__isl_keep isl_basic_set *bset, void *user)
    427 {
    428 	struct isl_coefficients_product_data *data = user;
    429 	isl_basic_set *coeff;
    430 	isl_size n_eq, n_ineq, dim;
    431 	int i, n_ray, n_vertex;
    432 
    433 	coeff = isl_basic_set_coefficients_base(isl_basic_set_copy(bset));
    434 	data->factors[data->pos].coeff = coeff;
    435 	if (!coeff)
    436 		return isl_bool_error;
    437 
    438 	dim = isl_basic_set_dim(bset, isl_dim_set);
    439 	n_eq = isl_basic_set_n_equality(coeff);
    440 	n_ineq = isl_basic_set_n_inequality(coeff);
    441 	if (dim < 0 || n_eq < 0 || n_ineq < 0)
    442 		return isl_bool_error;
    443 	n_ray = n_vertex = 0;
    444 	for (i = 0; i < n_ineq; ++i) {
    445 		if (is_ray(coeff, i))
    446 			n_ray++;
    447 		else
    448 			n_vertex++;
    449 	}
    450 	data->factors[data->pos].start = data->start_next;
    451 	data->factors[data->pos].dim = dim;
    452 	data->factors[data->pos].n_line = n_eq;
    453 	data->factors[data->pos].n_ray = n_ray;
    454 	data->factors[data->pos].n_vertex = n_vertex;
    455 	data->pos++;
    456 	data->start_next += dim;
    457 
    458 	return isl_bool_true;
    459 }
    460 
    461 /* Clear an entry in the product, given that there is a "total" number
    462  * of coefficients (other than that of the constant term).
    463  */
    464 static void clear_entry(isl_int *entry, int total)
    465 {
    466 	isl_seq_clr(entry, 1 + 1 + total);
    467 }
    468 
    469 /* Set the part of the entry corresponding to factor "data",
    470  * from the factor coefficients in "src".
    471  */
    472 static void set_factor(isl_int *entry, isl_int *src,
    473 	struct isl_coefficients_factor_data *data)
    474 {
    475 	isl_seq_cpy(entry + 1 + 1 + data->start, src + 1 + 1, data->dim);
    476 }
    477 
    478 /* Set the part of the entry corresponding to factor "data",
    479  * from the factor coefficients in "src" multiplied by "f".
    480  */
    481 static void scale_factor(isl_int *entry, isl_int *src, isl_int f,
    482 	struct isl_coefficients_factor_data *data)
    483 {
    484 	isl_seq_scale(entry + 1 + 1 + data->start, src + 1 + 1, f, data->dim);
    485 }
    486 
    487 /* Add all lines from the given factor to "bset",
    488  * given that there is a "total" number of coefficients
    489  * (other than that of the constant term).
    490  */
    491 static __isl_give isl_basic_set *add_lines(__isl_take isl_basic_set *bset,
    492 	struct isl_coefficients_factor_data *factor, int total)
    493 {
    494 	int i;
    495 
    496 	for (i = 0; i < factor->n_line; ++i) {
    497 		int k;
    498 
    499 		k = isl_basic_set_alloc_equality(bset);
    500 		if (k < 0)
    501 			return isl_basic_set_free(bset);
    502 		clear_entry(bset->eq[k], total);
    503 		set_factor(bset->eq[k], factor->coeff->eq[i], factor);
    504 	}
    505 
    506 	return bset;
    507 }
    508 
    509 /* Add all rays (other than lines) from the given factor to "bset",
    510  * given that there is a "total" number of coefficients
    511  * (other than that of the constant term).
    512  */
    513 static __isl_give isl_basic_set *add_rays(__isl_take isl_basic_set *bset,
    514 	struct isl_coefficients_factor_data *data, int total)
    515 {
    516 	int i;
    517 	int n_ineq = data->n_ray + data->n_vertex;
    518 
    519 	for (i = 0; i < n_ineq; ++i) {
    520 		int k;
    521 
    522 		if (!is_ray(data->coeff, i))
    523 			continue;
    524 
    525 		k = isl_basic_set_alloc_inequality(bset);
    526 		if (k < 0)
    527 			return isl_basic_set_free(bset);
    528 		clear_entry(bset->ineq[k], total);
    529 		set_factor(bset->ineq[k], data->coeff->ineq[i], data);
    530 	}
    531 
    532 	return bset;
    533 }
    534 
    535 /* Move to the first vertex of the given factor starting
    536  * at inequality constraint "start", setting factor->pos and
    537  * returning 1 if a vertex is found.
    538  */
    539 static int factor_first_vertex(struct isl_coefficients_factor_data *factor,
    540 	int start)
    541 {
    542 	int j;
    543 	int n = factor->n_ray + factor->n_vertex;
    544 
    545 	for (j = start; j < n; ++j) {
    546 		if (is_ray(factor->coeff, j))
    547 			continue;
    548 		factor->pos = j;
    549 		return 1;
    550 	}
    551 
    552 	return 0;
    553 }
    554 
    555 /* Move to the first constraint in each factor starting at "first"
    556  * that represents a vertex.
    557  * In particular, skip the initial constraints that correspond to rays.
    558  */
    559 static void first_vertex(struct isl_coefficients_product_data *data, int first)
    560 {
    561 	int i;
    562 
    563 	for (i = first; i < data->n; ++i)
    564 		factor_first_vertex(&data->factors[i], 0);
    565 }
    566 
    567 /* Move to the next vertex in the product.
    568  * In particular, move to the next vertex of the last factor.
    569  * If all vertices of this last factor have already been considered,
    570  * then move to the next vertex of the previous factor(s)
    571  * until a factor is found that still has a next vertex.
    572  * Once such a next vertex has been found, the subsequent
    573  * factors are reset to the first vertex.
    574  * Return 1 if any next vertex was found.
    575  */
    576 static int next_vertex(struct isl_coefficients_product_data *data)
    577 {
    578 	int i;
    579 
    580 	for (i = data->n - 1; i >= 0; --i) {
    581 		struct isl_coefficients_factor_data *factor = &data->factors[i];
    582 
    583 		if (!factor_first_vertex(factor, factor->pos + 1))
    584 			continue;
    585 		first_vertex(data, i + 1);
    586 		return 1;
    587 	}
    588 
    589 	return 0;
    590 }
    591 
    592 /* Add a vertex to the product "bset" combining the currently selected
    593  * vertices of the factors.
    594  *
    595  * In the dual representation, the constant term is always zero.
    596  * The vertex itself is the sum of the contributions of the factors
    597  * with a shared denominator in position 1.
    598  *
    599  * First compute the shared denominator (lcm) and
    600  * then scale the numerators to this shared denominator.
    601  */
    602 static __isl_give isl_basic_set *add_vertex(__isl_take isl_basic_set *bset,
    603 	struct isl_coefficients_product_data *data)
    604 {
    605 	int i;
    606 	int k;
    607 	isl_int lcm, f;
    608 
    609 	k = isl_basic_set_alloc_inequality(bset);
    610 	if (k < 0)
    611 		return isl_basic_set_free(bset);
    612 
    613 	isl_int_init(lcm);
    614 	isl_int_init(f);
    615 	isl_int_set_si(lcm, 1);
    616 	for (i = 0; i < data->n; ++i) {
    617 		struct isl_coefficients_factor_data *factor = &data->factors[i];
    618 		isl_basic_set *coeff = factor->coeff;
    619 		int pos = factor->pos;
    620 		isl_int_lcm(lcm, lcm, coeff->ineq[pos][1]);
    621 	}
    622 	isl_int_set_si(bset->ineq[k][0], 0);
    623 	isl_int_set(bset->ineq[k][1], lcm);
    624 
    625 	for (i = 0; i < data->n; ++i) {
    626 		struct isl_coefficients_factor_data *factor = &data->factors[i];
    627 		isl_basic_set *coeff = factor->coeff;
    628 		int pos = factor->pos;
    629 		isl_int_divexact(f, lcm, coeff->ineq[pos][1]);
    630 		scale_factor(bset->ineq[k], coeff->ineq[pos], f, factor);
    631 	}
    632 
    633 	isl_int_clear(f);
    634 	isl_int_clear(lcm);
    635 
    636 	return bset;
    637 }
    638 
    639 /* Combine the duals of the factors in the factorization of a basic set
    640  * to form the dual of the entire basic set.
    641  * The dual share the coefficient of the constant term.
    642  * All other coefficients are specific to a factor.
    643  * Any constraint not involving the coefficient of the constant term
    644  * can therefor simply be copied into the appropriate position.
    645  * This includes all equality constraints since the coefficient
    646  * of the constant term can always be increased and therefore
    647  * never appears in an equality constraint.
    648  * The inequality constraints involving the coefficient of
    649  * the constant term need to be combined across factors.
    650  * In particular, if this coefficient needs to be greater than or equal
    651  * to some linear combination of the other coefficients in each factor,
    652  * then it needs to be greater than or equal to the sum of
    653  * these linear combinations across the factors.
    654  *
    655  * Alternatively, the constraints of the dual can be seen
    656  * as the vertices, rays and lines of the original basic set.
    657  * Clearly, rays and lines can simply be copied,
    658  * while vertices needs to be combined across factors.
    659  * This means that the number of rays and lines in the product
    660  * is equal to the sum of the numbers in the factors,
    661  * while the number of vertices is the product
    662  * of the number of vertices in the factors.  Note that each
    663  * factor has at least one vertex.
    664  * The only exception is when the factor is the dual of an obviously empty set,
    665  * in which case a universe dual is created.
    666  * In this case, return a universe dual for the product as well.
    667  *
    668  * While constructing the vertices, look for the first combination
    669  * of inequality constraints that represent a vertex,
    670  * construct the corresponding vertex and then move on
    671  * to the next combination of inequality constraints until
    672  * all combinations have been considered.
    673  */
    674 static __isl_give isl_basic_set *construct_product(isl_ctx *ctx,
    675 	struct isl_coefficients_product_data *data)
    676 {
    677 	int i;
    678 	int n_line, n_ray, n_vertex;
    679 	int total;
    680 	isl_space *space;
    681 	isl_basic_set *product;
    682 
    683 	if (!data->factors)
    684 		return NULL;
    685 
    686 	total = data->start_next;
    687 
    688 	n_line = 0;
    689 	n_ray = 0;
    690 	n_vertex = 1;
    691 	for (i = 0; i < data->n; ++i) {
    692 		n_line += data->factors[i].n_line;
    693 		n_ray += data->factors[i].n_ray;
    694 		n_vertex *= data->factors[i].n_vertex;
    695 	}
    696 
    697 	space = isl_space_set_alloc(ctx, 0, 1 + total);
    698 	if (n_vertex == 0)
    699 		return rational_universe(space);
    700 	product = isl_basic_set_alloc_space(space, 0, n_line, n_ray + n_vertex);
    701 	product = isl_basic_set_set_rational(product);
    702 
    703 	for (i = 0; i < data->n; ++i)
    704 		product = add_lines(product, &data->factors[i], total);
    705 	for (i = 0; i < data->n; ++i)
    706 		product = add_rays(product, &data->factors[i], total);
    707 
    708 	first_vertex(data, 0);
    709 	do {
    710 		product = add_vertex(product, data);
    711 	} while (next_vertex(data));
    712 
    713 	return product;
    714 }
    715 
    716 /* Given a factorization "f" of a basic set,
    717  * construct a basic set containing the tuples of coefficients of all
    718  * valid affine constraints on the product of the factors, ignoring
    719  * the space of input and output.
    720  * Note that this product may not be equal to the original basic set,
    721  * if a non-trivial transformation is involved.
    722  * This is handled by the caller.
    723  *
    724  * Compute the tuples of coefficients for each factor separately and
    725  * then combine the results.
    726  */
    727 static __isl_give isl_basic_set *isl_basic_set_coefficients_product(
    728 	__isl_take isl_factorizer *f)
    729 {
    730 	struct isl_coefficients_product_data data;
    731 	isl_ctx *ctx;
    732 	isl_basic_set *coeff;
    733 	isl_bool every;
    734 
    735 	ctx = isl_factorizer_get_ctx(f);
    736 	if (isl_coefficients_product_data_init(ctx, &data, f->n_group) < 0)
    737 		f = isl_factorizer_free(f);
    738 	every = isl_factorizer_every_factor_basic_set(f,
    739 			&isl_basic_set_coefficients_factor, &data);
    740 	isl_factorizer_free(f);
    741 	if (every >= 0)
    742 		coeff = construct_product(ctx, &data);
    743 	else
    744 		coeff = NULL;
    745 	isl_coefficients_product_data_clear(&data);
    746 
    747 	return coeff;
    748 }
    749 
    750 /* Given a factorization "f" of a basic set,
    751  * construct a basic set containing the tuples of coefficients of all
    752  * valid affine constraints on the basic set, ignoring
    753  * the space of input and output.
    754  *
    755  * The factorization may involve a linear transformation of the basic set.
    756  * In particular, the transformed basic set is formulated
    757  * in terms of x' = U x, i.e., x = V x', with V = U^{-1}.
    758  * The dual is then computed in terms of y' with y'^t [z; x'] >= 0.
    759  * Plugging in y' = [1 0; 0 V^t] y yields
    760  * y^t [1 0; 0 V] [z; x'] >= 0, i.e., y^t [z; x] >= 0, which is
    761  * the desired set of coefficients y.
    762  * Note that this transformation to y' only needs to be applied
    763  * if U is not the identity matrix.
    764  */
    765 static __isl_give isl_basic_set *isl_basic_set_coefficients_morphed_product(
    766 	__isl_take isl_factorizer *f)
    767 {
    768 	isl_bool is_identity;
    769 	isl_space *space;
    770 	isl_mat *inv;
    771 	isl_multi_aff *ma;
    772 	isl_basic_set *coeff;
    773 
    774 	if (!f)
    775 		goto error;
    776 	is_identity = isl_mat_is_scaled_identity(peek_inv(f->morph));
    777 	if (is_identity < 0)
    778 		goto error;
    779 	if (is_identity)
    780 		return isl_basic_set_coefficients_product(f);
    781 
    782 	inv = get_inv(f->morph);
    783 	inv = isl_mat_transpose(inv);
    784 	inv = isl_mat_lin_to_aff(inv);
    785 
    786 	coeff = isl_basic_set_coefficients_product(f);
    787 	space = isl_space_map_from_set(isl_basic_set_get_space(coeff));
    788 	ma = isl_multi_aff_from_aff_mat(space, inv);
    789 	coeff = isl_basic_set_preimage_multi_aff(coeff, ma);
    790 
    791 	return coeff;
    792 error:
    793 	isl_factorizer_free(f);
    794 	return NULL;
    795 }
    796 
    797 /* Construct a basic set containing the tuples of coefficients of all
    798  * valid affine constraints on the given basic set, ignoring
    799  * the space of input and output.
    800  *
    801  * The caller has already checked that "bset" does not involve
    802  * any local variables.  It may have parameters, though.
    803  * Treat them as regular variables internally.
    804  * This is especially important for the factorization,
    805  * since the (original) parameters should be taken into account
    806  * explicitly in this factorization.
    807  *
    808  * Check if the basic set can be factorized.
    809  * If so, compute constraints on the coefficients of the factors
    810  * separately and combine the results.
    811  * Otherwise, compute the results for the input basic set as a whole.
    812  */
    813 static __isl_give isl_basic_set *basic_set_coefficients(
    814 	__isl_take isl_basic_set *bset)
    815 {
    816 	isl_factorizer *f;
    817 	isl_size nparam;
    818 
    819 	nparam = isl_basic_set_dim(bset, isl_dim_param);
    820 	if (nparam < 0)
    821 		return isl_basic_set_free(bset);
    822 	bset = isl_basic_set_move_dims(bset, isl_dim_set, 0,
    823 					    isl_dim_param, 0, nparam);
    824 
    825 	f = isl_basic_set_factorizer(bset);
    826 	if (!f)
    827 		return isl_basic_set_free(bset);
    828 	if (f->n_group > 0) {
    829 		isl_basic_set_free(bset);
    830 		return isl_basic_set_coefficients_morphed_product(f);
    831 	}
    832 	isl_factorizer_free(f);
    833 	return isl_basic_set_coefficients_base(bset);
    834 }
    835 
    836 /* Construct a basic set containing the tuples of coefficients of all
    837  * valid affine constraints on the given basic set.
    838  */
    839 __isl_give isl_basic_set *isl_basic_set_coefficients(
    840 	__isl_take isl_basic_set *bset)
    841 {
    842 	isl_space *space;
    843 
    844 	if (!bset)
    845 		return NULL;
    846 	if (bset->n_div)
    847 		isl_die(bset->ctx, isl_error_invalid,
    848 			"input set not allowed to have local variables",
    849 			goto error);
    850 
    851 	space = isl_basic_set_get_space(bset);
    852 	space = isl_space_coefficients(space);
    853 
    854 	bset = basic_set_coefficients(bset);
    855 	bset = isl_basic_set_reset_space(bset, space);
    856 	return bset;
    857 error:
    858 	isl_basic_set_free(bset);
    859 	return NULL;
    860 }
    861 
    862 /* Construct a basic set containing the elements that satisfy all
    863  * affine constraints whose coefficient tuples are
    864  * contained in the given basic set.
    865  */
    866 __isl_give isl_basic_set *isl_basic_set_solutions(
    867 	__isl_take isl_basic_set *bset)
    868 {
    869 	isl_space *space;
    870 
    871 	if (!bset)
    872 		return NULL;
    873 	if (bset->n_div)
    874 		isl_die(bset->ctx, isl_error_invalid,
    875 			"input set not allowed to have local variables",
    876 			goto error);
    877 
    878 	space = isl_basic_set_get_space(bset);
    879 	space = isl_space_solutions(space);
    880 
    881 	bset = farkas(bset, -1);
    882 	bset = isl_basic_set_reset_space(bset, space);
    883 	return bset;
    884 error:
    885 	isl_basic_set_free(bset);
    886 	return NULL;
    887 }
    888 
    889 /* Construct a basic set containing the tuples of coefficients of all
    890  * valid affine constraints on the given set.
    891  */
    892 __isl_give isl_basic_set *isl_set_coefficients(__isl_take isl_set *set)
    893 {
    894 	int i;
    895 	isl_basic_set *coeff;
    896 
    897 	if (!set)
    898 		return NULL;
    899 	if (set->n == 0) {
    900 		isl_space *space = isl_set_get_space(set);
    901 		space = isl_space_coefficients(space);
    902 		isl_set_free(set);
    903 		return rational_universe(space);
    904 	}
    905 
    906 	coeff = isl_basic_set_coefficients(isl_basic_set_copy(set->p[0]));
    907 
    908 	for (i = 1; i < set->n; ++i) {
    909 		isl_basic_set *bset, *coeff_i;
    910 		bset = isl_basic_set_copy(set->p[i]);
    911 		coeff_i = isl_basic_set_coefficients(bset);
    912 		coeff = isl_basic_set_intersect(coeff, coeff_i);
    913 	}
    914 
    915 	isl_set_free(set);
    916 	return coeff;
    917 }
    918 
    919 /* Wrapper around isl_basic_set_coefficients for use
    920  * as a isl_basic_set_list_map callback.
    921  */
    922 static __isl_give isl_basic_set *coefficients_wrap(
    923 	__isl_take isl_basic_set *bset, void *user)
    924 {
    925 	return isl_basic_set_coefficients(bset);
    926 }
    927 
    928 /* Replace the elements of "list" by the result of applying
    929  * isl_basic_set_coefficients to them.
    930  */
    931 __isl_give isl_basic_set_list *isl_basic_set_list_coefficients(
    932 	__isl_take isl_basic_set_list *list)
    933 {
    934 	return isl_basic_set_list_map(list, &coefficients_wrap, NULL);
    935 }
    936 
    937 /* Construct a basic set containing the elements that satisfy all
    938  * affine constraints whose coefficient tuples are
    939  * contained in the given set.
    940  */
    941 __isl_give isl_basic_set *isl_set_solutions(__isl_take isl_set *set)
    942 {
    943 	int i;
    944 	isl_basic_set *sol;
    945 
    946 	if (!set)
    947 		return NULL;
    948 	if (set->n == 0) {
    949 		isl_space *space = isl_set_get_space(set);
    950 		space = isl_space_solutions(space);
    951 		isl_set_free(set);
    952 		return rational_universe(space);
    953 	}
    954 
    955 	sol = isl_basic_set_solutions(isl_basic_set_copy(set->p[0]));
    956 
    957 	for (i = 1; i < set->n; ++i) {
    958 		isl_basic_set *bset, *sol_i;
    959 		bset = isl_basic_set_copy(set->p[i]);
    960 		sol_i = isl_basic_set_solutions(bset);
    961 		sol = isl_basic_set_intersect(sol, sol_i);
    962 	}
    963 
    964 	isl_set_free(set);
    965 	return sol;
    966 }
    967