Home | History | Annotate | Line # | Download | only in dist
      1 /*
      2  * Copyright 2008-2009 Katholieke Universiteit Leuven
      3  * Copyright 2014      INRIA Rocquencourt
      4  *
      5  * Use of this software is governed by the MIT license
      6  *
      7  * Written by Sven Verdoolaege, K.U.Leuven, Departement
      8  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
      9  * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
     10  * B.P. 105 - 78153 Le Chesnay, France
     11  */
     12 
     13 #include <isl_ctx_private.h>
     14 #include <isl_map_private.h>
     15 #include <isl_lp_private.h>
     16 #include <isl/map.h>
     17 #include <isl_mat_private.h>
     18 #include <isl_vec_private.h>
     19 #include <isl/set.h>
     20 #include <isl_seq.h>
     21 #include <isl_options_private.h>
     22 #include "isl_equalities.h"
     23 #include "isl_tab.h"
     24 #include <isl_sort.h>
     25 
     26 #include <bset_to_bmap.c>
     27 #include <bset_from_bmap.c>
     28 #include <set_to_map.c>
     29 
     30 static __isl_give isl_basic_set *uset_convex_hull_wrap_bounded(
     31 	__isl_take isl_set *set);
     32 
     33 /* Remove redundant
     34  * constraints.  If the minimal value along the normal of a constraint
     35  * is the same if the constraint is removed, then the constraint is redundant.
     36  *
     37  * Since some constraints may be mutually redundant, sort the constraints
     38  * first such that constraints that involve existentially quantified
     39  * variables are considered for removal before those that do not.
     40  * The sorting is also needed for the use in map_simple_hull.
     41  *
     42  * Note that isl_tab_detect_implicit_equalities may also end up
     43  * marking some constraints as redundant.  Make sure the constraints
     44  * are preserved and undo those marking such that isl_tab_detect_redundant
     45  * can consider the constraints in the sorted order.
     46  *
     47  * Alternatively, we could have intersected the basic map with the
     48  * corresponding equality and then checked if the dimension was that
     49  * of a facet.
     50  */
     51 __isl_give isl_basic_map *isl_basic_map_remove_redundancies(
     52 	__isl_take isl_basic_map *bmap)
     53 {
     54 	struct isl_tab *tab;
     55 
     56 	if (!bmap)
     57 		return NULL;
     58 
     59 	bmap = isl_basic_map_gauss(bmap, NULL);
     60 	if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
     61 		return bmap;
     62 	if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_NO_REDUNDANT))
     63 		return bmap;
     64 	if (bmap->n_ineq <= 1)
     65 		return bmap;
     66 
     67 	bmap = isl_basic_map_sort_constraints(bmap);
     68 	tab = isl_tab_from_basic_map(bmap, 0);
     69 	if (!tab)
     70 		goto error;
     71 	tab->preserve = 1;
     72 	if (isl_tab_detect_implicit_equalities(tab) < 0)
     73 		goto error;
     74 	if (isl_tab_restore_redundant(tab) < 0)
     75 		goto error;
     76 	tab->preserve = 0;
     77 	if (isl_tab_detect_redundant(tab) < 0)
     78 		goto error;
     79 	bmap = isl_basic_map_update_from_tab(bmap, tab);
     80 	isl_tab_free(tab);
     81 	if (!bmap)
     82 		return NULL;
     83 	ISL_F_SET(bmap, ISL_BASIC_MAP_NO_IMPLICIT);
     84 	ISL_F_SET(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
     85 	return bmap;
     86 error:
     87 	isl_tab_free(tab);
     88 	isl_basic_map_free(bmap);
     89 	return NULL;
     90 }
     91 
     92 __isl_give isl_basic_set *isl_basic_set_remove_redundancies(
     93 	__isl_take isl_basic_set *bset)
     94 {
     95 	return bset_from_bmap(
     96 		isl_basic_map_remove_redundancies(bset_to_bmap(bset)));
     97 }
     98 
     99 /* Remove redundant constraints in each of the basic maps.
    100  */
    101 __isl_give isl_map *isl_map_remove_redundancies(__isl_take isl_map *map)
    102 {
    103 	return isl_map_inline_foreach_basic_map(map,
    104 					    &isl_basic_map_remove_redundancies);
    105 }
    106 
    107 __isl_give isl_set *isl_set_remove_redundancies(__isl_take isl_set *set)
    108 {
    109 	return isl_map_remove_redundancies(set);
    110 }
    111 
    112 /* Check if the set set is bound in the direction of the affine
    113  * constraint c and if so, set the constant term such that the
    114  * resulting constraint is a bounding constraint for the set.
    115  */
    116 static isl_bool uset_is_bound(__isl_keep isl_set *set, isl_int *c, unsigned len)
    117 {
    118 	int first;
    119 	int j;
    120 	isl_int opt;
    121 	isl_int opt_denom;
    122 
    123 	isl_int_init(opt);
    124 	isl_int_init(opt_denom);
    125 	first = 1;
    126 	for (j = 0; j < set->n; ++j) {
    127 		enum isl_lp_result res;
    128 
    129 		if (ISL_F_ISSET(set->p[j], ISL_BASIC_SET_EMPTY))
    130 			continue;
    131 
    132 		res = isl_basic_set_solve_lp(set->p[j],
    133 				0, c, set->ctx->one, &opt, &opt_denom, NULL);
    134 		if (res == isl_lp_unbounded)
    135 			break;
    136 		if (res == isl_lp_error)
    137 			goto error;
    138 		if (res == isl_lp_empty) {
    139 			set->p[j] = isl_basic_set_set_to_empty(set->p[j]);
    140 			if (!set->p[j])
    141 				goto error;
    142 			continue;
    143 		}
    144 		if (first || isl_int_is_neg(opt)) {
    145 			if (!isl_int_is_one(opt_denom))
    146 				isl_seq_scale(c, c, opt_denom, len);
    147 			isl_int_sub(c[0], c[0], opt);
    148 		}
    149 		first = 0;
    150 	}
    151 	isl_int_clear(opt);
    152 	isl_int_clear(opt_denom);
    153 	return isl_bool_ok(j >= set->n);
    154 error:
    155 	isl_int_clear(opt);
    156 	isl_int_clear(opt_denom);
    157 	return isl_bool_error;
    158 }
    159 
    160 static __isl_give isl_set *isl_set_add_basic_set_equality(
    161 	__isl_take isl_set *set, isl_int *c)
    162 {
    163 	int i;
    164 
    165 	set = isl_set_cow(set);
    166 	if (!set)
    167 		return NULL;
    168 	for (i = 0; i < set->n; ++i) {
    169 		set->p[i] = isl_basic_set_add_eq(set->p[i], c);
    170 		if (!set->p[i])
    171 			goto error;
    172 	}
    173 	return set;
    174 error:
    175 	isl_set_free(set);
    176 	return NULL;
    177 }
    178 
    179 /* Given a union of basic sets, construct the constraints for wrapping
    180  * a facet around one of its ridges.
    181  * In particular, if each of n the d-dimensional basic sets i in "set"
    182  * contains the origin, satisfies the constraints x_1 >= 0 and x_2 >= 0
    183  * and is defined by the constraints
    184  *				    [ 1 ]
    185  *				A_i [ x ]  >= 0
    186  *
    187  * then the resulting set is of dimension n*(1+d) and has as constraints
    188  *
    189  *				    [ a_i ]
    190  *				A_i [ x_i ] >= 0
    191  *
    192  *				      a_i   >= 0
    193  *
    194  *			\sum_i x_{i,1} = 1
    195  */
    196 static __isl_give isl_basic_set *wrap_constraints(__isl_keep isl_set *set)
    197 {
    198 	struct isl_basic_set *lp;
    199 	unsigned n_eq;
    200 	unsigned n_ineq;
    201 	int i, j, k;
    202 	isl_size dim, lp_dim;
    203 
    204 	dim = isl_set_dim(set, isl_dim_set);
    205 	if (dim < 0)
    206 		return NULL;
    207 
    208 	dim += 1;
    209 	n_eq = 1;
    210 	n_ineq = set->n;
    211 	for (i = 0; i < set->n; ++i) {
    212 		n_eq += set->p[i]->n_eq;
    213 		n_ineq += set->p[i]->n_ineq;
    214 	}
    215 	lp = isl_basic_set_alloc(set->ctx, 0, dim * set->n, 0, n_eq, n_ineq);
    216 	lp = isl_basic_set_set_rational(lp);
    217 	if (!lp)
    218 		return NULL;
    219 	lp_dim = isl_basic_set_dim(lp, isl_dim_set);
    220 	if (lp_dim < 0)
    221 		return isl_basic_set_free(lp);
    222 	k = isl_basic_set_alloc_equality(lp);
    223 	isl_int_set_si(lp->eq[k][0], -1);
    224 	for (i = 0; i < set->n; ++i) {
    225 		isl_int_set_si(lp->eq[k][1+dim*i], 0);
    226 		isl_int_set_si(lp->eq[k][1+dim*i+1], 1);
    227 		isl_seq_clr(lp->eq[k]+1+dim*i+2, dim-2);
    228 	}
    229 	for (i = 0; i < set->n; ++i) {
    230 		k = isl_basic_set_alloc_inequality(lp);
    231 		isl_seq_clr(lp->ineq[k], 1+lp_dim);
    232 		isl_int_set_si(lp->ineq[k][1+dim*i], 1);
    233 
    234 		for (j = 0; j < set->p[i]->n_eq; ++j) {
    235 			k = isl_basic_set_alloc_equality(lp);
    236 			isl_seq_clr(lp->eq[k], 1+dim*i);
    237 			isl_seq_cpy(lp->eq[k]+1+dim*i, set->p[i]->eq[j], dim);
    238 			isl_seq_clr(lp->eq[k]+1+dim*(i+1), dim*(set->n-i-1));
    239 		}
    240 
    241 		for (j = 0; j < set->p[i]->n_ineq; ++j) {
    242 			k = isl_basic_set_alloc_inequality(lp);
    243 			isl_seq_clr(lp->ineq[k], 1+dim*i);
    244 			isl_seq_cpy(lp->ineq[k]+1+dim*i, set->p[i]->ineq[j], dim);
    245 			isl_seq_clr(lp->ineq[k]+1+dim*(i+1), dim*(set->n-i-1));
    246 		}
    247 	}
    248 	return lp;
    249 }
    250 
    251 /* Given a facet "facet" of the convex hull of "set" and a facet "ridge"
    252  * of that facet, compute the other facet of the convex hull that contains
    253  * the ridge.
    254  *
    255  * We first transform the set such that the facet constraint becomes
    256  *
    257  *			x_1 >= 0
    258  *
    259  * I.e., the facet lies in
    260  *
    261  *			x_1 = 0
    262  *
    263  * and on that facet, the constraint that defines the ridge is
    264  *
    265  *			x_2 >= 0
    266  *
    267  * (This transformation is not strictly needed, all that is needed is
    268  * that the ridge contains the origin.)
    269  *
    270  * Since the ridge contains the origin, the cone of the convex hull
    271  * will be of the form
    272  *
    273  *			x_1 >= 0
    274  *			x_2 >= a x_1
    275  *
    276  * with this second constraint defining the new facet.
    277  * The constant a is obtained by settting x_1 in the cone of the
    278  * convex hull to 1 and minimizing x_2.
    279  * Now, each element in the cone of the convex hull is the sum
    280  * of elements in the cones of the basic sets.
    281  * If a_i is the dilation factor of basic set i, then the problem
    282  * we need to solve is
    283  *
    284  *			min \sum_i x_{i,2}
    285  *			st
    286  *				\sum_i x_{i,1} = 1
    287  *				    a_i   >= 0
    288  *				  [ a_i ]
    289  *				A [ x_i ] >= 0
    290  *
    291  * with
    292  *				    [  1  ]
    293  *				A_i [ x_i ] >= 0
    294  *
    295  * the constraints of each (transformed) basic set.
    296  * If a = n/d, then the constraint defining the new facet (in the transformed
    297  * space) is
    298  *
    299  *			-n x_1 + d x_2 >= 0
    300  *
    301  * In the original space, we need to take the same combination of the
    302  * corresponding constraints "facet" and "ridge".
    303  *
    304  * If a = -infty = "-1/0", then we just return the original facet constraint.
    305  * This means that the facet is unbounded, but has a bounded intersection
    306  * with the union of sets.
    307  */
    308 isl_int *isl_set_wrap_facet(__isl_keep isl_set *set,
    309 	isl_int *facet, isl_int *ridge)
    310 {
    311 	int i;
    312 	isl_ctx *ctx;
    313 	struct isl_mat *T = NULL;
    314 	struct isl_basic_set *lp = NULL;
    315 	struct isl_vec *obj;
    316 	enum isl_lp_result res;
    317 	isl_int num, den;
    318 	isl_size dim;
    319 
    320 	dim = isl_set_dim(set, isl_dim_set);
    321 	if (dim < 0)
    322 		return NULL;
    323 	ctx = set->ctx;
    324 	set = isl_set_copy(set);
    325 	set = isl_set_set_rational(set);
    326 
    327 	dim += 1;
    328 	T = isl_mat_alloc(ctx, 3, dim);
    329 	if (!T)
    330 		goto error;
    331 	isl_int_set_si(T->row[0][0], 1);
    332 	isl_seq_clr(T->row[0]+1, dim - 1);
    333 	isl_seq_cpy(T->row[1], facet, dim);
    334 	isl_seq_cpy(T->row[2], ridge, dim);
    335 	T = isl_mat_right_inverse(T);
    336 	set = isl_set_preimage(set, T);
    337 	T = NULL;
    338 	if (!set)
    339 		goto error;
    340 	lp = wrap_constraints(set);
    341 	obj = isl_vec_alloc(ctx, 1 + dim*set->n);
    342 	if (!obj)
    343 		goto error;
    344 	isl_int_set_si(obj->block.data[0], 0);
    345 	for (i = 0; i < set->n; ++i) {
    346 		isl_seq_clr(obj->block.data + 1 + dim*i, 2);
    347 		isl_int_set_si(obj->block.data[1 + dim*i+2], 1);
    348 		isl_seq_clr(obj->block.data + 1 + dim*i+3, dim-3);
    349 	}
    350 	isl_int_init(num);
    351 	isl_int_init(den);
    352 	res = isl_basic_set_solve_lp(lp, 0,
    353 			    obj->block.data, ctx->one, &num, &den, NULL);
    354 	if (res == isl_lp_ok) {
    355 		isl_int_neg(num, num);
    356 		isl_seq_combine(facet, num, facet, den, ridge, dim);
    357 		isl_seq_normalize(ctx, facet, dim);
    358 	}
    359 	isl_int_clear(num);
    360 	isl_int_clear(den);
    361 	isl_vec_free(obj);
    362 	isl_basic_set_free(lp);
    363 	isl_set_free(set);
    364 	if (res == isl_lp_error)
    365 		return NULL;
    366 	isl_assert(ctx, res == isl_lp_ok || res == isl_lp_unbounded,
    367 		   return NULL);
    368 	return facet;
    369 error:
    370 	isl_basic_set_free(lp);
    371 	isl_mat_free(T);
    372 	isl_set_free(set);
    373 	return NULL;
    374 }
    375 
    376 /* Compute the constraint of a facet of "set".
    377  *
    378  * We first compute the intersection with a bounding constraint
    379  * that is orthogonal to one of the coordinate axes.
    380  * If the affine hull of this intersection has only one equality,
    381  * we have found a facet.
    382  * Otherwise, we wrap the current bounding constraint around
    383  * one of the equalities of the face (one that is not equal to
    384  * the current bounding constraint).
    385  * This process continues until we have found a facet.
    386  * The dimension of the intersection increases by at least
    387  * one on each iteration, so termination is guaranteed.
    388  */
    389 static __isl_give isl_mat *initial_facet_constraint(__isl_keep isl_set *set)
    390 {
    391 	struct isl_set *slice = NULL;
    392 	struct isl_basic_set *face = NULL;
    393 	int i;
    394 	isl_size dim = isl_set_dim(set, isl_dim_set);
    395 	isl_bool is_bound;
    396 	isl_mat *bounds = NULL;
    397 
    398 	if (dim < 0)
    399 		return NULL;
    400 	isl_assert(set->ctx, set->n > 0, goto error);
    401 	bounds = isl_mat_alloc(set->ctx, 1, 1 + dim);
    402 	if (!bounds)
    403 		return NULL;
    404 
    405 	isl_seq_clr(bounds->row[0], dim);
    406 	isl_int_set_si(bounds->row[0][1 + dim - 1], 1);
    407 	is_bound = uset_is_bound(set, bounds->row[0], 1 + dim);
    408 	if (is_bound < 0)
    409 		goto error;
    410 	isl_assert(set->ctx, is_bound, goto error);
    411 	isl_seq_normalize(set->ctx, bounds->row[0], 1 + dim);
    412 	bounds->n_row = 1;
    413 
    414 	for (;;) {
    415 		slice = isl_set_copy(set);
    416 		slice = isl_set_add_basic_set_equality(slice, bounds->row[0]);
    417 		face = isl_set_affine_hull(slice);
    418 		if (!face)
    419 			goto error;
    420 		if (face->n_eq == 1) {
    421 			isl_basic_set_free(face);
    422 			break;
    423 		}
    424 		for (i = 0; i < face->n_eq; ++i)
    425 			if (!isl_seq_eq(bounds->row[0], face->eq[i], 1 + dim) &&
    426 			    !isl_seq_is_neg(bounds->row[0],
    427 						face->eq[i], 1 + dim))
    428 				break;
    429 		isl_assert(set->ctx, i < face->n_eq, goto error);
    430 		if (!isl_set_wrap_facet(set, bounds->row[0], face->eq[i]))
    431 			goto error;
    432 		isl_seq_normalize(set->ctx, bounds->row[0], bounds->n_col);
    433 		isl_basic_set_free(face);
    434 	}
    435 
    436 	return bounds;
    437 error:
    438 	isl_basic_set_free(face);
    439 	isl_mat_free(bounds);
    440 	return NULL;
    441 }
    442 
    443 /* Given the bounding constraint "c" of a facet of the convex hull of "set",
    444  * compute a hyperplane description of the facet, i.e., compute the facets
    445  * of the facet.
    446  *
    447  * We compute an affine transformation that transforms the constraint
    448  *
    449  *			  [ 1 ]
    450  *			c [ x ] = 0
    451  *
    452  * to the constraint
    453  *
    454  *			   z_1  = 0
    455  *
    456  * by computing the right inverse U of a matrix that starts with the rows
    457  *
    458  *			[ 1 0 ]
    459  *			[  c  ]
    460  *
    461  * Then
    462  *			[ 1 ]     [ 1 ]
    463  *			[ x ] = U [ z ]
    464  * and
    465  *			[ 1 ]     [ 1 ]
    466  *			[ z ] = Q [ x ]
    467  *
    468  * with Q = U^{-1}
    469  * Since z_1 is zero, we can drop this variable as well as the corresponding
    470  * column of U to obtain
    471  *
    472  *			[ 1 ]      [ 1  ]
    473  *			[ x ] = U' [ z' ]
    474  * and
    475  *			[ 1  ]      [ 1 ]
    476  *			[ z' ] = Q' [ x ]
    477  *
    478  * with Q' equal to Q, but without the corresponding row.
    479  * After computing the facets of the facet in the z' space,
    480  * we convert them back to the x space through Q.
    481  */
    482 static __isl_give isl_basic_set *compute_facet(__isl_keep isl_set *set,
    483 	isl_int *c)
    484 {
    485 	struct isl_mat *m, *U, *Q;
    486 	struct isl_basic_set *facet = NULL;
    487 	struct isl_ctx *ctx;
    488 	isl_size dim;
    489 
    490 	dim = isl_set_dim(set, isl_dim_set);
    491 	if (dim < 0)
    492 		return NULL;
    493 	ctx = set->ctx;
    494 	set = isl_set_copy(set);
    495 	m = isl_mat_alloc(set->ctx, 2, 1 + dim);
    496 	if (!m)
    497 		goto error;
    498 	isl_int_set_si(m->row[0][0], 1);
    499 	isl_seq_clr(m->row[0]+1, dim);
    500 	isl_seq_cpy(m->row[1], c, 1+dim);
    501 	U = isl_mat_right_inverse(m);
    502 	Q = isl_mat_right_inverse(isl_mat_copy(U));
    503 	U = isl_mat_drop_cols(U, 1, 1);
    504 	Q = isl_mat_drop_rows(Q, 1, 1);
    505 	set = isl_set_preimage(set, U);
    506 	facet = uset_convex_hull_wrap_bounded(set);
    507 	facet = isl_basic_set_preimage(facet, Q);
    508 	if (facet && facet->n_eq != 0)
    509 		isl_die(ctx, isl_error_internal, "unexpected equality",
    510 			return isl_basic_set_free(facet));
    511 	return facet;
    512 error:
    513 	isl_basic_set_free(facet);
    514 	isl_set_free(set);
    515 	return NULL;
    516 }
    517 
    518 /* Given an initial facet constraint, compute the remaining facets.
    519  * We do this by running through all facets found so far and computing
    520  * the adjacent facets through wrapping, adding those facets that we
    521  * hadn't already found before.
    522  *
    523  * For each facet we have found so far, we first compute its facets
    524  * in the resulting convex hull.  That is, we compute the ridges
    525  * of the resulting convex hull contained in the facet.
    526  * We also compute the corresponding facet in the current approximation
    527  * of the convex hull.  There is no need to wrap around the ridges
    528  * in this facet since that would result in a facet that is already
    529  * present in the current approximation.
    530  *
    531  * This function can still be significantly optimized by checking which of
    532  * the facets of the basic sets are also facets of the convex hull and
    533  * using all the facets so far to help in constructing the facets of the
    534  * facets
    535  * and/or
    536  * using the technique in section "3.1 Ridge Generation" of
    537  * "Extended Convex Hull" by Fukuda et al.
    538  */
    539 static __isl_give isl_basic_set *extend(__isl_take isl_basic_set *hull,
    540 	__isl_keep isl_set *set)
    541 {
    542 	int i, j, f;
    543 	int k;
    544 	struct isl_basic_set *facet = NULL;
    545 	struct isl_basic_set *hull_facet = NULL;
    546 	isl_size dim;
    547 
    548 	dim = isl_set_dim(set, isl_dim_set);
    549 	if (dim < 0 || !hull)
    550 		return isl_basic_set_free(hull);
    551 
    552 	isl_assert(set->ctx, set->n > 0, goto error);
    553 
    554 	for (i = 0; i < hull->n_ineq; ++i) {
    555 		facet = compute_facet(set, hull->ineq[i]);
    556 		facet = isl_basic_set_add_eq(facet, hull->ineq[i]);
    557 		facet = isl_basic_set_gauss(facet, NULL);
    558 		facet = isl_basic_set_normalize_constraints(facet);
    559 		hull_facet = isl_basic_set_copy(hull);
    560 		hull_facet = isl_basic_set_add_eq(hull_facet, hull->ineq[i]);
    561 		hull_facet = isl_basic_set_gauss(hull_facet, NULL);
    562 		hull_facet = isl_basic_set_normalize_constraints(hull_facet);
    563 		if (!facet || !hull_facet)
    564 			goto error;
    565 		hull = isl_basic_set_cow(hull);
    566 		hull = isl_basic_set_extend(hull, 0, 0, facet->n_ineq);
    567 		if (!hull)
    568 			goto error;
    569 		for (j = 0; j < facet->n_ineq; ++j) {
    570 			for (f = 0; f < hull_facet->n_ineq; ++f)
    571 				if (isl_seq_eq(facet->ineq[j],
    572 						hull_facet->ineq[f], 1 + dim))
    573 					break;
    574 			if (f < hull_facet->n_ineq)
    575 				continue;
    576 			k = isl_basic_set_alloc_inequality(hull);
    577 			if (k < 0)
    578 				goto error;
    579 			isl_seq_cpy(hull->ineq[k], hull->ineq[i], 1+dim);
    580 			if (!isl_set_wrap_facet(set, hull->ineq[k], facet->ineq[j]))
    581 				goto error;
    582 		}
    583 		isl_basic_set_free(hull_facet);
    584 		isl_basic_set_free(facet);
    585 	}
    586 	hull = isl_basic_set_simplify(hull);
    587 	hull = isl_basic_set_finalize(hull);
    588 	return hull;
    589 error:
    590 	isl_basic_set_free(hull_facet);
    591 	isl_basic_set_free(facet);
    592 	isl_basic_set_free(hull);
    593 	return NULL;
    594 }
    595 
    596 /* Special case for computing the convex hull of a one dimensional set.
    597  * We simply collect the lower and upper bounds of each basic set
    598  * and the biggest of those.
    599  */
    600 static __isl_give isl_basic_set *convex_hull_1d(__isl_take isl_set *set)
    601 {
    602 	struct isl_mat *c = NULL;
    603 	isl_int *lower = NULL;
    604 	isl_int *upper = NULL;
    605 	int i, j, k;
    606 	isl_int a, b;
    607 	struct isl_basic_set *hull;
    608 
    609 	for (i = 0; i < set->n; ++i) {
    610 		set->p[i] = isl_basic_set_simplify(set->p[i]);
    611 		if (!set->p[i])
    612 			goto error;
    613 	}
    614 	set = isl_set_remove_empty_parts(set);
    615 	if (!set)
    616 		goto error;
    617 	isl_assert(set->ctx, set->n > 0, goto error);
    618 	c = isl_mat_alloc(set->ctx, 2, 2);
    619 	if (!c)
    620 		goto error;
    621 
    622 	if (set->p[0]->n_eq > 0) {
    623 		isl_assert(set->ctx, set->p[0]->n_eq == 1, goto error);
    624 		lower = c->row[0];
    625 		upper = c->row[1];
    626 		if (isl_int_is_pos(set->p[0]->eq[0][1])) {
    627 			isl_seq_cpy(lower, set->p[0]->eq[0], 2);
    628 			isl_seq_neg(upper, set->p[0]->eq[0], 2);
    629 		} else {
    630 			isl_seq_neg(lower, set->p[0]->eq[0], 2);
    631 			isl_seq_cpy(upper, set->p[0]->eq[0], 2);
    632 		}
    633 	} else {
    634 		for (j = 0; j < set->p[0]->n_ineq; ++j) {
    635 			if (isl_int_is_pos(set->p[0]->ineq[j][1])) {
    636 				lower = c->row[0];
    637 				isl_seq_cpy(lower, set->p[0]->ineq[j], 2);
    638 			} else {
    639 				upper = c->row[1];
    640 				isl_seq_cpy(upper, set->p[0]->ineq[j], 2);
    641 			}
    642 		}
    643 	}
    644 
    645 	isl_int_init(a);
    646 	isl_int_init(b);
    647 	for (i = 0; i < set->n; ++i) {
    648 		struct isl_basic_set *bset = set->p[i];
    649 		int has_lower = 0;
    650 		int has_upper = 0;
    651 
    652 		for (j = 0; j < bset->n_eq; ++j) {
    653 			has_lower = 1;
    654 			has_upper = 1;
    655 			if (lower) {
    656 				isl_int_mul(a, lower[0], bset->eq[j][1]);
    657 				isl_int_mul(b, lower[1], bset->eq[j][0]);
    658 				if (isl_int_lt(a, b) && isl_int_is_pos(bset->eq[j][1]))
    659 					isl_seq_cpy(lower, bset->eq[j], 2);
    660 				if (isl_int_gt(a, b) && isl_int_is_neg(bset->eq[j][1]))
    661 					isl_seq_neg(lower, bset->eq[j], 2);
    662 			}
    663 			if (upper) {
    664 				isl_int_mul(a, upper[0], bset->eq[j][1]);
    665 				isl_int_mul(b, upper[1], bset->eq[j][0]);
    666 				if (isl_int_lt(a, b) && isl_int_is_pos(bset->eq[j][1]))
    667 					isl_seq_neg(upper, bset->eq[j], 2);
    668 				if (isl_int_gt(a, b) && isl_int_is_neg(bset->eq[j][1]))
    669 					isl_seq_cpy(upper, bset->eq[j], 2);
    670 			}
    671 		}
    672 		for (j = 0; j < bset->n_ineq; ++j) {
    673 			if (isl_int_is_pos(bset->ineq[j][1]))
    674 				has_lower = 1;
    675 			if (isl_int_is_neg(bset->ineq[j][1]))
    676 				has_upper = 1;
    677 			if (lower && isl_int_is_pos(bset->ineq[j][1])) {
    678 				isl_int_mul(a, lower[0], bset->ineq[j][1]);
    679 				isl_int_mul(b, lower[1], bset->ineq[j][0]);
    680 				if (isl_int_lt(a, b))
    681 					isl_seq_cpy(lower, bset->ineq[j], 2);
    682 			}
    683 			if (upper && isl_int_is_neg(bset->ineq[j][1])) {
    684 				isl_int_mul(a, upper[0], bset->ineq[j][1]);
    685 				isl_int_mul(b, upper[1], bset->ineq[j][0]);
    686 				if (isl_int_gt(a, b))
    687 					isl_seq_cpy(upper, bset->ineq[j], 2);
    688 			}
    689 		}
    690 		if (!has_lower)
    691 			lower = NULL;
    692 		if (!has_upper)
    693 			upper = NULL;
    694 	}
    695 	isl_int_clear(a);
    696 	isl_int_clear(b);
    697 
    698 	hull = isl_basic_set_alloc(set->ctx, 0, 1, 0, 0, 2);
    699 	hull = isl_basic_set_set_rational(hull);
    700 	if (!hull)
    701 		goto error;
    702 	if (lower) {
    703 		k = isl_basic_set_alloc_inequality(hull);
    704 		isl_seq_cpy(hull->ineq[k], lower, 2);
    705 	}
    706 	if (upper) {
    707 		k = isl_basic_set_alloc_inequality(hull);
    708 		isl_seq_cpy(hull->ineq[k], upper, 2);
    709 	}
    710 	hull = isl_basic_set_finalize(hull);
    711 	isl_set_free(set);
    712 	isl_mat_free(c);
    713 	return hull;
    714 error:
    715 	isl_set_free(set);
    716 	isl_mat_free(c);
    717 	return NULL;
    718 }
    719 
    720 static __isl_give isl_basic_set *convex_hull_0d(__isl_take isl_set *set)
    721 {
    722 	struct isl_basic_set *convex_hull;
    723 
    724 	if (!set)
    725 		return NULL;
    726 
    727 	if (isl_set_is_empty(set))
    728 		convex_hull = isl_basic_set_empty(isl_space_copy(set->dim));
    729 	else
    730 		convex_hull = isl_basic_set_universe(isl_space_copy(set->dim));
    731 	isl_set_free(set);
    732 	return convex_hull;
    733 }
    734 
    735 /* Compute the convex hull of a pair of basic sets without any parameters or
    736  * integer divisions using Fourier-Motzkin elimination.
    737  * The convex hull is the set of all points that can be written as
    738  * the sum of points from both basic sets (in homogeneous coordinates).
    739  * We set up the constraints in a space with dimensions for each of
    740  * the three sets and then project out the dimensions corresponding
    741  * to the two original basic sets, retaining only those corresponding
    742  * to the convex hull.
    743  */
    744 static __isl_give isl_basic_set *convex_hull_pair_elim(
    745 	__isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
    746 {
    747 	int i, j, k;
    748 	struct isl_basic_set *bset[2];
    749 	struct isl_basic_set *hull = NULL;
    750 	isl_size dim;
    751 
    752 	dim = isl_basic_set_dim(bset1, isl_dim_set);
    753 	if (dim < 0 || !bset2)
    754 		goto error;
    755 
    756 	hull = isl_basic_set_alloc(bset1->ctx, 0, 2 + 3 * dim, 0,
    757 				1 + dim + bset1->n_eq + bset2->n_eq,
    758 				2 + bset1->n_ineq + bset2->n_ineq);
    759 	bset[0] = bset1;
    760 	bset[1] = bset2;
    761 	for (i = 0; i < 2; ++i) {
    762 		for (j = 0; j < bset[i]->n_eq; ++j) {
    763 			k = isl_basic_set_alloc_equality(hull);
    764 			if (k < 0)
    765 				goto error;
    766 			isl_seq_clr(hull->eq[k], (i+1) * (1+dim));
    767 			isl_seq_clr(hull->eq[k]+(i+2)*(1+dim), (1-i)*(1+dim));
    768 			isl_seq_cpy(hull->eq[k]+(i+1)*(1+dim), bset[i]->eq[j],
    769 					1+dim);
    770 		}
    771 		for (j = 0; j < bset[i]->n_ineq; ++j) {
    772 			k = isl_basic_set_alloc_inequality(hull);
    773 			if (k < 0)
    774 				goto error;
    775 			isl_seq_clr(hull->ineq[k], (i+1) * (1+dim));
    776 			isl_seq_clr(hull->ineq[k]+(i+2)*(1+dim), (1-i)*(1+dim));
    777 			isl_seq_cpy(hull->ineq[k]+(i+1)*(1+dim),
    778 					bset[i]->ineq[j], 1+dim);
    779 		}
    780 		k = isl_basic_set_alloc_inequality(hull);
    781 		if (k < 0)
    782 			goto error;
    783 		isl_seq_clr(hull->ineq[k], 1+2+3*dim);
    784 		isl_int_set_si(hull->ineq[k][(i+1)*(1+dim)], 1);
    785 	}
    786 	for (j = 0; j < 1+dim; ++j) {
    787 		k = isl_basic_set_alloc_equality(hull);
    788 		if (k < 0)
    789 			goto error;
    790 		isl_seq_clr(hull->eq[k], 1+2+3*dim);
    791 		isl_int_set_si(hull->eq[k][j], -1);
    792 		isl_int_set_si(hull->eq[k][1+dim+j], 1);
    793 		isl_int_set_si(hull->eq[k][2*(1+dim)+j], 1);
    794 	}
    795 	hull = isl_basic_set_set_rational(hull);
    796 	hull = isl_basic_set_remove_dims(hull, isl_dim_set, dim, 2*(1+dim));
    797 	hull = isl_basic_set_remove_redundancies(hull);
    798 	isl_basic_set_free(bset1);
    799 	isl_basic_set_free(bset2);
    800 	return hull;
    801 error:
    802 	isl_basic_set_free(bset1);
    803 	isl_basic_set_free(bset2);
    804 	isl_basic_set_free(hull);
    805 	return NULL;
    806 }
    807 
    808 /* Is the set bounded for each value of the parameters?
    809  */
    810 isl_bool isl_basic_set_is_bounded(__isl_keep isl_basic_set *bset)
    811 {
    812 	struct isl_tab *tab;
    813 	isl_bool bounded;
    814 
    815 	if (!bset)
    816 		return isl_bool_error;
    817 	if (isl_basic_set_plain_is_empty(bset))
    818 		return isl_bool_true;
    819 
    820 	tab = isl_tab_from_recession_cone(bset, 1);
    821 	bounded = isl_tab_cone_is_bounded(tab);
    822 	isl_tab_free(tab);
    823 	return bounded;
    824 }
    825 
    826 /* Is the image bounded for each value of the parameters and
    827  * the domain variables?
    828  */
    829 isl_bool isl_basic_map_image_is_bounded(__isl_keep isl_basic_map *bmap)
    830 {
    831 	isl_size nparam = isl_basic_map_dim(bmap, isl_dim_param);
    832 	isl_size n_in = isl_basic_map_dim(bmap, isl_dim_in);
    833 	isl_bool bounded;
    834 
    835 	if (nparam < 0 || n_in < 0)
    836 		return isl_bool_error;
    837 
    838 	bmap = isl_basic_map_copy(bmap);
    839 	bmap = isl_basic_map_cow(bmap);
    840 	bmap = isl_basic_map_move_dims(bmap, isl_dim_param, nparam,
    841 					isl_dim_in, 0, n_in);
    842 	bounded = isl_basic_set_is_bounded(bset_from_bmap(bmap));
    843 	isl_basic_map_free(bmap);
    844 
    845 	return bounded;
    846 }
    847 
    848 /* Is the set bounded for each value of the parameters?
    849  */
    850 isl_bool isl_set_is_bounded(__isl_keep isl_set *set)
    851 {
    852 	int i;
    853 
    854 	if (!set)
    855 		return isl_bool_error;
    856 
    857 	for (i = 0; i < set->n; ++i) {
    858 		isl_bool bounded = isl_basic_set_is_bounded(set->p[i]);
    859 		if (!bounded || bounded < 0)
    860 			return bounded;
    861 	}
    862 	return isl_bool_true;
    863 }
    864 
    865 /* Compute the lineality space of the convex hull of bset1 and bset2.
    866  *
    867  * We first compute the intersection of the recession cone of bset1
    868  * with the negative of the recession cone of bset2 and then compute
    869  * the linear hull of the resulting cone.
    870  */
    871 static __isl_give isl_basic_set *induced_lineality_space(
    872 	__isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
    873 {
    874 	int i, k;
    875 	struct isl_basic_set *lin = NULL;
    876 	isl_size dim;
    877 
    878 	dim = isl_basic_set_dim(bset1, isl_dim_all);
    879 	if (dim < 0 || !bset2)
    880 		goto error;
    881 
    882 	lin = isl_basic_set_alloc_space(isl_basic_set_get_space(bset1), 0,
    883 					bset1->n_eq + bset2->n_eq,
    884 					bset1->n_ineq + bset2->n_ineq);
    885 	lin = isl_basic_set_set_rational(lin);
    886 	if (!lin)
    887 		goto error;
    888 	for (i = 0; i < bset1->n_eq; ++i) {
    889 		k = isl_basic_set_alloc_equality(lin);
    890 		if (k < 0)
    891 			goto error;
    892 		isl_int_set_si(lin->eq[k][0], 0);
    893 		isl_seq_cpy(lin->eq[k] + 1, bset1->eq[i] + 1, dim);
    894 	}
    895 	for (i = 0; i < bset1->n_ineq; ++i) {
    896 		k = isl_basic_set_alloc_inequality(lin);
    897 		if (k < 0)
    898 			goto error;
    899 		isl_int_set_si(lin->ineq[k][0], 0);
    900 		isl_seq_cpy(lin->ineq[k] + 1, bset1->ineq[i] + 1, dim);
    901 	}
    902 	for (i = 0; i < bset2->n_eq; ++i) {
    903 		k = isl_basic_set_alloc_equality(lin);
    904 		if (k < 0)
    905 			goto error;
    906 		isl_int_set_si(lin->eq[k][0], 0);
    907 		isl_seq_neg(lin->eq[k] + 1, bset2->eq[i] + 1, dim);
    908 	}
    909 	for (i = 0; i < bset2->n_ineq; ++i) {
    910 		k = isl_basic_set_alloc_inequality(lin);
    911 		if (k < 0)
    912 			goto error;
    913 		isl_int_set_si(lin->ineq[k][0], 0);
    914 		isl_seq_neg(lin->ineq[k] + 1, bset2->ineq[i] + 1, dim);
    915 	}
    916 
    917 	isl_basic_set_free(bset1);
    918 	isl_basic_set_free(bset2);
    919 	return isl_basic_set_affine_hull(lin);
    920 error:
    921 	isl_basic_set_free(lin);
    922 	isl_basic_set_free(bset1);
    923 	isl_basic_set_free(bset2);
    924 	return NULL;
    925 }
    926 
    927 static __isl_give isl_basic_set *uset_convex_hull(__isl_take isl_set *set);
    928 
    929 /* Given a set and a linear space "lin" of dimension n > 0,
    930  * project the linear space from the set, compute the convex hull
    931  * and then map the set back to the original space.
    932  *
    933  * Let
    934  *
    935  *	M x = 0
    936  *
    937  * describe the linear space.  We first compute the Hermite normal
    938  * form H = M U of M = H Q, to obtain
    939  *
    940  *	H Q x = 0
    941  *
    942  * The last n rows of H will be zero, so the last n variables of x' = Q x
    943  * are the one we want to project out.  We do this by transforming each
    944  * basic set A x >= b to A U x' >= b and then removing the last n dimensions.
    945  * After computing the convex hull in x'_1, i.e., A' x'_1 >= b',
    946  * we transform the hull back to the original space as A' Q_1 x >= b',
    947  * with Q_1 all but the last n rows of Q.
    948  */
    949 static __isl_give isl_basic_set *modulo_lineality(__isl_take isl_set *set,
    950 	__isl_take isl_basic_set *lin)
    951 {
    952 	isl_size total = isl_basic_set_dim(lin, isl_dim_all);
    953 	unsigned lin_dim;
    954 	struct isl_basic_set *hull;
    955 	struct isl_mat *M, *U, *Q;
    956 
    957 	if (!set || total < 0)
    958 		goto error;
    959 	lin_dim = total - lin->n_eq;
    960 	M = isl_mat_sub_alloc6(set->ctx, lin->eq, 0, lin->n_eq, 1, total);
    961 	M = isl_mat_left_hermite(M, 0, &U, &Q);
    962 	if (!M)
    963 		goto error;
    964 	isl_mat_free(M);
    965 	isl_basic_set_free(lin);
    966 
    967 	Q = isl_mat_drop_rows(Q, Q->n_row - lin_dim, lin_dim);
    968 
    969 	U = isl_mat_lin_to_aff(U);
    970 	Q = isl_mat_lin_to_aff(Q);
    971 
    972 	set = isl_set_preimage(set, U);
    973 	set = isl_set_remove_dims(set, isl_dim_set, total - lin_dim, lin_dim);
    974 	hull = uset_convex_hull(set);
    975 	hull = isl_basic_set_preimage(hull, Q);
    976 
    977 	return hull;
    978 error:
    979 	isl_basic_set_free(lin);
    980 	isl_set_free(set);
    981 	return NULL;
    982 }
    983 
    984 /* Given two polyhedra with as constraints h_{ij} x >= 0 in homegeneous space,
    985  * set up an LP for solving
    986  *
    987  *	\sum_j \alpha_{1j} h_{1j} = \sum_j \alpha_{2j} h_{2j}
    988  *
    989  * \alpha{i0} corresponds to the (implicit) positivity constraint 1 >= 0
    990  * The next \alpha{ij} correspond to the equalities and come in pairs.
    991  * The final \alpha{ij} correspond to the inequalities.
    992  */
    993 static __isl_give isl_basic_set *valid_direction_lp(
    994 	__isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
    995 {
    996 	isl_space *space;
    997 	struct isl_basic_set *lp;
    998 	unsigned d;
    999 	int n;
   1000 	int i, j, k;
   1001 	isl_size total;
   1002 
   1003 	total = isl_basic_set_dim(bset1, isl_dim_all);
   1004 	if (total < 0 || !bset2)
   1005 		goto error;
   1006 	d = 1 + total;
   1007 	n = 2 +
   1008 	    2 * bset1->n_eq + bset1->n_ineq + 2 * bset2->n_eq + bset2->n_ineq;
   1009 	space = isl_space_set_alloc(bset1->ctx, 0, n);
   1010 	lp = isl_basic_set_alloc_space(space, 0, d, n);
   1011 	if (!lp)
   1012 		goto error;
   1013 	for (i = 0; i < n; ++i) {
   1014 		k = isl_basic_set_alloc_inequality(lp);
   1015 		if (k < 0)
   1016 			goto error;
   1017 		isl_seq_clr(lp->ineq[k] + 1, n);
   1018 		isl_int_set_si(lp->ineq[k][0], -1);
   1019 		isl_int_set_si(lp->ineq[k][1 + i], 1);
   1020 	}
   1021 	for (i = 0; i < d; ++i) {
   1022 		k = isl_basic_set_alloc_equality(lp);
   1023 		if (k < 0)
   1024 			goto error;
   1025 		n = 0;
   1026 		isl_int_set_si(lp->eq[k][n], 0); n++;
   1027 		/* positivity constraint 1 >= 0 */
   1028 		isl_int_set_si(lp->eq[k][n], i == 0); n++;
   1029 		for (j = 0; j < bset1->n_eq; ++j) {
   1030 			isl_int_set(lp->eq[k][n], bset1->eq[j][i]); n++;
   1031 			isl_int_neg(lp->eq[k][n], bset1->eq[j][i]); n++;
   1032 		}
   1033 		for (j = 0; j < bset1->n_ineq; ++j) {
   1034 			isl_int_set(lp->eq[k][n], bset1->ineq[j][i]); n++;
   1035 		}
   1036 		/* positivity constraint 1 >= 0 */
   1037 		isl_int_set_si(lp->eq[k][n], -(i == 0)); n++;
   1038 		for (j = 0; j < bset2->n_eq; ++j) {
   1039 			isl_int_neg(lp->eq[k][n], bset2->eq[j][i]); n++;
   1040 			isl_int_set(lp->eq[k][n], bset2->eq[j][i]); n++;
   1041 		}
   1042 		for (j = 0; j < bset2->n_ineq; ++j) {
   1043 			isl_int_neg(lp->eq[k][n], bset2->ineq[j][i]); n++;
   1044 		}
   1045 	}
   1046 	lp = isl_basic_set_gauss(lp, NULL);
   1047 	isl_basic_set_free(bset1);
   1048 	isl_basic_set_free(bset2);
   1049 	return lp;
   1050 error:
   1051 	isl_basic_set_free(bset1);
   1052 	isl_basic_set_free(bset2);
   1053 	return NULL;
   1054 }
   1055 
   1056 /* Compute a vector s in the homogeneous space such that <s, r> > 0
   1057  * for all rays in the homogeneous space of the two cones that correspond
   1058  * to the input polyhedra bset1 and bset2.
   1059  *
   1060  * We compute s as a vector that satisfies
   1061  *
   1062  *	s = \sum_j \alpha_{ij} h_{ij}	for i = 1,2			(*)
   1063  *
   1064  * with h_{ij} the normals of the facets of polyhedron i
   1065  * (including the "positivity constraint" 1 >= 0) and \alpha_{ij}
   1066  * strictly positive numbers.  For simplicity we impose \alpha_{ij} >= 1.
   1067  * We first set up an LP with as variables the \alpha{ij}.
   1068  * In this formulation, for each polyhedron i,
   1069  * the first constraint is the positivity constraint, followed by pairs
   1070  * of variables for the equalities, followed by variables for the inequalities.
   1071  * We then simply pick a feasible solution and compute s using (*).
   1072  *
   1073  * Note that we simply pick any valid direction and make no attempt
   1074  * to pick a "good" or even the "best" valid direction.
   1075  */
   1076 static __isl_give isl_vec *valid_direction(
   1077 	__isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
   1078 {
   1079 	struct isl_basic_set *lp;
   1080 	struct isl_tab *tab;
   1081 	struct isl_vec *sample = NULL;
   1082 	struct isl_vec *dir;
   1083 	isl_size d;
   1084 	int i;
   1085 	int n;
   1086 
   1087 	if (!bset1 || !bset2)
   1088 		goto error;
   1089 	lp = valid_direction_lp(isl_basic_set_copy(bset1),
   1090 				isl_basic_set_copy(bset2));
   1091 	tab = isl_tab_from_basic_set(lp, 0);
   1092 	sample = isl_tab_get_sample_value(tab);
   1093 	isl_tab_free(tab);
   1094 	isl_basic_set_free(lp);
   1095 	if (!sample)
   1096 		goto error;
   1097 	d = isl_basic_set_dim(bset1, isl_dim_all);
   1098 	if (d < 0)
   1099 		goto error;
   1100 	dir = isl_vec_alloc(bset1->ctx, 1 + d);
   1101 	if (!dir)
   1102 		goto error;
   1103 	isl_seq_clr(dir->block.data + 1, dir->size - 1);
   1104 	n = 1;
   1105 	/* positivity constraint 1 >= 0 */
   1106 	isl_int_set(dir->block.data[0], sample->block.data[n]); n++;
   1107 	for (i = 0; i < bset1->n_eq; ++i) {
   1108 		isl_int_sub(sample->block.data[n],
   1109 			    sample->block.data[n], sample->block.data[n+1]);
   1110 		isl_seq_combine(dir->block.data,
   1111 				bset1->ctx->one, dir->block.data,
   1112 				sample->block.data[n], bset1->eq[i], 1 + d);
   1113 
   1114 		n += 2;
   1115 	}
   1116 	for (i = 0; i < bset1->n_ineq; ++i)
   1117 		isl_seq_combine(dir->block.data,
   1118 				bset1->ctx->one, dir->block.data,
   1119 				sample->block.data[n++], bset1->ineq[i], 1 + d);
   1120 	isl_vec_free(sample);
   1121 	isl_seq_normalize(bset1->ctx, dir->el, dir->size);
   1122 	isl_basic_set_free(bset1);
   1123 	isl_basic_set_free(bset2);
   1124 	return dir;
   1125 error:
   1126 	isl_vec_free(sample);
   1127 	isl_basic_set_free(bset1);
   1128 	isl_basic_set_free(bset2);
   1129 	return NULL;
   1130 }
   1131 
   1132 /* Given a polyhedron b_i + A_i x >= 0 and a map T = S^{-1},
   1133  * compute b_i' + A_i' x' >= 0, with
   1134  *
   1135  *	[ b_i A_i ]        [ y' ]		              [ y' ]
   1136  *	[  1   0  ] S^{-1} [ x' ] >= 0	or	[ b_i' A_i' ] [ x' ] >= 0
   1137  *
   1138  * In particular, add the "positivity constraint" and then perform
   1139  * the mapping.
   1140  */
   1141 static __isl_give isl_basic_set *homogeneous_map(__isl_take isl_basic_set *bset,
   1142 	__isl_take isl_mat *T)
   1143 {
   1144 	int k;
   1145 	isl_size total;
   1146 
   1147 	total = isl_basic_set_dim(bset, isl_dim_all);
   1148 	if (total < 0)
   1149 		goto error;
   1150 	bset = isl_basic_set_extend_constraints(bset, 0, 1);
   1151 	k = isl_basic_set_alloc_inequality(bset);
   1152 	if (k < 0)
   1153 		goto error;
   1154 	isl_seq_clr(bset->ineq[k] + 1, total);
   1155 	isl_int_set_si(bset->ineq[k][0], 1);
   1156 	bset = isl_basic_set_preimage(bset, T);
   1157 	return bset;
   1158 error:
   1159 	isl_mat_free(T);
   1160 	isl_basic_set_free(bset);
   1161 	return NULL;
   1162 }
   1163 
   1164 /* Compute the convex hull of a pair of basic sets without any parameters or
   1165  * integer divisions, where the convex hull is known to be pointed,
   1166  * but the basic sets may be unbounded.
   1167  *
   1168  * We turn this problem into the computation of a convex hull of a pair
   1169  * _bounded_ polyhedra by "changing the direction of the homogeneous
   1170  * dimension".  This idea is due to Matthias Koeppe.
   1171  *
   1172  * Consider the cones in homogeneous space that correspond to the
   1173  * input polyhedra.  The rays of these cones are also rays of the
   1174  * polyhedra if the coordinate that corresponds to the homogeneous
   1175  * dimension is zero.  That is, if the inner product of the rays
   1176  * with the homogeneous direction is zero.
   1177  * The cones in the homogeneous space can also be considered to
   1178  * correspond to other pairs of polyhedra by chosing a different
   1179  * homogeneous direction.  To ensure that both of these polyhedra
   1180  * are bounded, we need to make sure that all rays of the cones
   1181  * correspond to vertices and not to rays.
   1182  * Let s be a direction such that <s, r> > 0 for all rays r of both cones.
   1183  * Then using s as a homogeneous direction, we obtain a pair of polytopes.
   1184  * The vector s is computed in valid_direction.
   1185  *
   1186  * Note that we need to consider _all_ rays of the cones and not just
   1187  * the rays that correspond to rays in the polyhedra.  If we were to
   1188  * only consider those rays and turn them into vertices, then we
   1189  * may inadvertently turn some vertices into rays.
   1190  *
   1191  * The standard homogeneous direction is the unit vector in the 0th coordinate.
   1192  * We therefore transform the two polyhedra such that the selected
   1193  * direction is mapped onto this standard direction and then proceed
   1194  * with the normal computation.
   1195  * Let S be a non-singular square matrix with s as its first row,
   1196  * then we want to map the polyhedra to the space
   1197  *
   1198  *	[ y' ]     [ y ]		[ y ]          [ y' ]
   1199  *	[ x' ] = S [ x ]	i.e.,	[ x ] = S^{-1} [ x' ]
   1200  *
   1201  * We take S to be the unimodular completion of s to limit the growth
   1202  * of the coefficients in the following computations.
   1203  *
   1204  * Let b_i + A_i x >= 0 be the constraints of polyhedron i.
   1205  * We first move to the homogeneous dimension
   1206  *
   1207  *	b_i y + A_i x >= 0		[ b_i A_i ] [ y ]    [ 0 ]
   1208  *	    y         >= 0	or	[  1   0  ] [ x ] >= [ 0 ]
   1209  *
   1210  * Then we change directoin
   1211  *
   1212  *	[ b_i A_i ]        [ y' ]		              [ y' ]
   1213  *	[  1   0  ] S^{-1} [ x' ] >= 0	or	[ b_i' A_i' ] [ x' ] >= 0
   1214  *
   1215  * Then we compute the convex hull of the polytopes b_i' + A_i' x' >= 0
   1216  * resulting in b' + A' x' >= 0, which we then convert back
   1217  *
   1218  *	            [ y ]		        [ y ]
   1219  *	[ b' A' ] S [ x ] >= 0	or	[ b A ] [ x ] >= 0
   1220  *
   1221  * The polyhedron b + A x >= 0 is then the convex hull of the input polyhedra.
   1222  */
   1223 static __isl_give isl_basic_set *convex_hull_pair_pointed(
   1224 	__isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
   1225 {
   1226 	struct isl_ctx *ctx = NULL;
   1227 	struct isl_vec *dir = NULL;
   1228 	struct isl_mat *T = NULL;
   1229 	struct isl_mat *T2 = NULL;
   1230 	struct isl_basic_set *hull;
   1231 	struct isl_set *set;
   1232 
   1233 	if (!bset1 || !bset2)
   1234 		goto error;
   1235 	ctx = isl_basic_set_get_ctx(bset1);
   1236 	dir = valid_direction(isl_basic_set_copy(bset1),
   1237 				isl_basic_set_copy(bset2));
   1238 	if (!dir)
   1239 		goto error;
   1240 	T = isl_mat_alloc(ctx, dir->size, dir->size);
   1241 	if (!T)
   1242 		goto error;
   1243 	isl_seq_cpy(T->row[0], dir->block.data, dir->size);
   1244 	T = isl_mat_unimodular_complete(T, 1);
   1245 	T2 = isl_mat_right_inverse(isl_mat_copy(T));
   1246 
   1247 	bset1 = homogeneous_map(bset1, isl_mat_copy(T2));
   1248 	bset2 = homogeneous_map(bset2, T2);
   1249 	set = isl_set_alloc_space(isl_basic_set_get_space(bset1), 2, 0);
   1250 	set = isl_set_add_basic_set(set, bset1);
   1251 	set = isl_set_add_basic_set(set, bset2);
   1252 	hull = uset_convex_hull(set);
   1253 	hull = isl_basic_set_preimage(hull, T);
   1254 
   1255 	isl_vec_free(dir);
   1256 
   1257 	return hull;
   1258 error:
   1259 	isl_vec_free(dir);
   1260 	isl_basic_set_free(bset1);
   1261 	isl_basic_set_free(bset2);
   1262 	return NULL;
   1263 }
   1264 
   1265 static __isl_give isl_basic_set *uset_convex_hull_wrap(__isl_take isl_set *set);
   1266 static __isl_give isl_basic_set *modulo_affine_hull(
   1267 	__isl_take isl_set *set, __isl_take isl_basic_set *affine_hull);
   1268 
   1269 /* Compute the convex hull of a pair of basic sets without any parameters or
   1270  * integer divisions.
   1271  *
   1272  * This function is called from uset_convex_hull_unbounded, which
   1273  * means that the complete convex hull is unbounded.  Some pairs
   1274  * of basic sets may still be bounded, though.
   1275  * They may even lie inside a lower dimensional space, in which
   1276  * case they need to be handled inside their affine hull since
   1277  * the main algorithm assumes that the result is full-dimensional.
   1278  *
   1279  * If the convex hull of the two basic sets would have a non-trivial
   1280  * lineality space, we first project out this lineality space.
   1281  */
   1282 static __isl_give isl_basic_set *convex_hull_pair(
   1283 	__isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
   1284 {
   1285 	isl_basic_set *lin, *aff;
   1286 	isl_bool bounded1, bounded2;
   1287 	isl_size total;
   1288 
   1289 	if (bset1->ctx->opt->convex == ISL_CONVEX_HULL_FM)
   1290 		return convex_hull_pair_elim(bset1, bset2);
   1291 
   1292 	aff = isl_set_affine_hull(isl_basic_set_union(isl_basic_set_copy(bset1),
   1293 						    isl_basic_set_copy(bset2)));
   1294 	if (!aff)
   1295 		goto error;
   1296 	if (aff->n_eq != 0)
   1297 		return modulo_affine_hull(isl_basic_set_union(bset1, bset2), aff);
   1298 	isl_basic_set_free(aff);
   1299 
   1300 	bounded1 = isl_basic_set_is_bounded(bset1);
   1301 	bounded2 = isl_basic_set_is_bounded(bset2);
   1302 
   1303 	if (bounded1 < 0 || bounded2 < 0)
   1304 		goto error;
   1305 
   1306 	if (bounded1 && bounded2)
   1307 		return uset_convex_hull_wrap(isl_basic_set_union(bset1, bset2));
   1308 
   1309 	if (bounded1 || bounded2)
   1310 		return convex_hull_pair_pointed(bset1, bset2);
   1311 
   1312 	lin = induced_lineality_space(isl_basic_set_copy(bset1),
   1313 				      isl_basic_set_copy(bset2));
   1314 	if (!lin)
   1315 		goto error;
   1316 	if (isl_basic_set_plain_is_universe(lin)) {
   1317 		isl_basic_set_free(bset1);
   1318 		isl_basic_set_free(bset2);
   1319 		return lin;
   1320 	}
   1321 	total = isl_basic_set_dim(lin, isl_dim_all);
   1322 	if (lin->n_eq < total) {
   1323 		struct isl_set *set;
   1324 		set = isl_set_alloc_space(isl_basic_set_get_space(bset1), 2, 0);
   1325 		set = isl_set_add_basic_set(set, bset1);
   1326 		set = isl_set_add_basic_set(set, bset2);
   1327 		return modulo_lineality(set, lin);
   1328 	}
   1329 	isl_basic_set_free(lin);
   1330 	if (total < 0)
   1331 		goto error;
   1332 
   1333 	return convex_hull_pair_pointed(bset1, bset2);
   1334 error:
   1335 	isl_basic_set_free(bset1);
   1336 	isl_basic_set_free(bset2);
   1337 	return NULL;
   1338 }
   1339 
   1340 /* Compute the lineality space of a basic set.
   1341  * We basically just drop the constants and turn every inequality
   1342  * into an equality.
   1343  * Any explicit representations of local variables are removed
   1344  * because they may no longer be valid representations
   1345  * in the lineality space.
   1346  */
   1347 __isl_give isl_basic_set *isl_basic_set_lineality_space(
   1348 	__isl_take isl_basic_set *bset)
   1349 {
   1350 	int i, k;
   1351 	struct isl_basic_set *lin = NULL;
   1352 	isl_size n_div, dim;
   1353 
   1354 	n_div = isl_basic_set_dim(bset, isl_dim_div);
   1355 	dim = isl_basic_set_dim(bset, isl_dim_all);
   1356 	if (n_div < 0 || dim < 0)
   1357 		return isl_basic_set_free(bset);
   1358 
   1359 	lin = isl_basic_set_alloc_space(isl_basic_set_get_space(bset),
   1360 					n_div, dim, 0);
   1361 	for (i = 0; i < n_div; ++i)
   1362 		if (isl_basic_set_alloc_div(lin) < 0)
   1363 			goto error;
   1364 	if (!lin)
   1365 		goto error;
   1366 	for (i = 0; i < bset->n_eq; ++i) {
   1367 		k = isl_basic_set_alloc_equality(lin);
   1368 		if (k < 0)
   1369 			goto error;
   1370 		isl_int_set_si(lin->eq[k][0], 0);
   1371 		isl_seq_cpy(lin->eq[k] + 1, bset->eq[i] + 1, dim);
   1372 	}
   1373 	lin = isl_basic_set_gauss(lin, NULL);
   1374 	if (!lin)
   1375 		goto error;
   1376 	for (i = 0; i < bset->n_ineq && lin->n_eq < dim; ++i) {
   1377 		k = isl_basic_set_alloc_equality(lin);
   1378 		if (k < 0)
   1379 			goto error;
   1380 		isl_int_set_si(lin->eq[k][0], 0);
   1381 		isl_seq_cpy(lin->eq[k] + 1, bset->ineq[i] + 1, dim);
   1382 		lin = isl_basic_set_gauss(lin, NULL);
   1383 		if (!lin)
   1384 			goto error;
   1385 	}
   1386 	isl_basic_set_free(bset);
   1387 	return lin;
   1388 error:
   1389 	isl_basic_set_free(lin);
   1390 	isl_basic_set_free(bset);
   1391 	return NULL;
   1392 }
   1393 
   1394 /* Compute the (linear) hull of the lineality spaces of the basic sets in the
   1395  * set "set".
   1396  */
   1397 __isl_give isl_basic_set *isl_set_combined_lineality_space(
   1398 	__isl_take isl_set *set)
   1399 {
   1400 	int i;
   1401 	struct isl_set *lin = NULL;
   1402 
   1403 	if (!set)
   1404 		return NULL;
   1405 	if (set->n == 0) {
   1406 		isl_space *space = isl_set_get_space(set);
   1407 		isl_set_free(set);
   1408 		return isl_basic_set_empty(space);
   1409 	}
   1410 
   1411 	lin = isl_set_alloc_space(isl_set_get_space(set), set->n, 0);
   1412 	for (i = 0; i < set->n; ++i)
   1413 		lin = isl_set_add_basic_set(lin,
   1414 		    isl_basic_set_lineality_space(isl_basic_set_copy(set->p[i])));
   1415 	isl_set_free(set);
   1416 	return isl_set_affine_hull(lin);
   1417 }
   1418 
   1419 /* Compute the convex hull of a set without any parameters or
   1420  * integer divisions.
   1421  * In each step, we combined two basic sets until only one
   1422  * basic set is left.
   1423  * The input basic sets are assumed not to have a non-trivial
   1424  * lineality space.  If any of the intermediate results has
   1425  * a non-trivial lineality space, it is projected out.
   1426  */
   1427 static __isl_give isl_basic_set *uset_convex_hull_unbounded(
   1428 	__isl_take isl_set *set)
   1429 {
   1430 	isl_basic_set_list *list;
   1431 
   1432 	list = isl_set_get_basic_set_list(set);
   1433 	isl_set_free(set);
   1434 
   1435 	while (list) {
   1436 		isl_size n, total;
   1437 		struct isl_basic_set *t;
   1438 		isl_basic_set *bset1, *bset2;
   1439 
   1440 		n = isl_basic_set_list_n_basic_set(list);
   1441 		if (n < 0)
   1442 			goto error;
   1443 		if (n < 2)
   1444 			isl_die(isl_basic_set_list_get_ctx(list),
   1445 				isl_error_internal,
   1446 				"expecting at least two elements", goto error);
   1447 		bset1 = isl_basic_set_list_get_basic_set(list, n - 1);
   1448 		bset2 = isl_basic_set_list_get_basic_set(list, n - 2);
   1449 		bset1 = convex_hull_pair(bset1, bset2);
   1450 		if (n == 2) {
   1451 			isl_basic_set_list_free(list);
   1452 			return bset1;
   1453 		}
   1454 		bset1 = isl_basic_set_underlying_set(bset1);
   1455 		list = isl_basic_set_list_drop(list, n - 2, 2);
   1456 		list = isl_basic_set_list_add(list, bset1);
   1457 
   1458 		t = isl_basic_set_list_get_basic_set(list, n - 2);
   1459 		t = isl_basic_set_lineality_space(t);
   1460 		if (!t)
   1461 			goto error;
   1462 		if (isl_basic_set_plain_is_universe(t)) {
   1463 			isl_basic_set_list_free(list);
   1464 			return t;
   1465 		}
   1466 		total = isl_basic_set_dim(t, isl_dim_all);
   1467 		if (t->n_eq < total) {
   1468 			set = isl_basic_set_list_union(list);
   1469 			return modulo_lineality(set, t);
   1470 		}
   1471 		isl_basic_set_free(t);
   1472 		if (total < 0)
   1473 			goto error;
   1474 	}
   1475 
   1476 	return NULL;
   1477 error:
   1478 	isl_basic_set_list_free(list);
   1479 	return NULL;
   1480 }
   1481 
   1482 /* Compute an initial hull for wrapping containing a single initial
   1483  * facet.
   1484  * This function assumes that the given set is bounded.
   1485  */
   1486 static __isl_give isl_basic_set *initial_hull(__isl_take isl_basic_set *hull,
   1487 	__isl_keep isl_set *set)
   1488 {
   1489 	struct isl_mat *bounds = NULL;
   1490 	isl_size dim;
   1491 	int k;
   1492 
   1493 	if (!hull)
   1494 		goto error;
   1495 	bounds = initial_facet_constraint(set);
   1496 	if (!bounds)
   1497 		goto error;
   1498 	k = isl_basic_set_alloc_inequality(hull);
   1499 	if (k < 0)
   1500 		goto error;
   1501 	dim = isl_set_dim(set, isl_dim_set);
   1502 	if (dim < 0)
   1503 		goto error;
   1504 	isl_assert(set->ctx, 1 + dim == bounds->n_col, goto error);
   1505 	isl_seq_cpy(hull->ineq[k], bounds->row[0], bounds->n_col);
   1506 	isl_mat_free(bounds);
   1507 
   1508 	return hull;
   1509 error:
   1510 	isl_basic_set_free(hull);
   1511 	isl_mat_free(bounds);
   1512 	return NULL;
   1513 }
   1514 
   1515 struct max_constraint {
   1516 	struct isl_mat *c;
   1517 	int	 	count;
   1518 	int		ineq;
   1519 };
   1520 
   1521 static isl_bool max_constraint_equal(const void *entry, const void *val)
   1522 {
   1523 	struct max_constraint *a = (struct max_constraint *)entry;
   1524 	isl_int *b = (isl_int *)val;
   1525 
   1526 	return isl_bool_ok(isl_seq_eq(a->c->row[0] + 1, b, a->c->n_col - 1));
   1527 }
   1528 
   1529 static isl_stat update_constraint(struct isl_ctx *ctx,
   1530 	struct isl_hash_table *table,
   1531 	isl_int *con, unsigned len, int n, int ineq)
   1532 {
   1533 	struct isl_hash_table_entry *entry;
   1534 	struct max_constraint *c;
   1535 	uint32_t c_hash;
   1536 
   1537 	c_hash = isl_seq_get_hash(con + 1, len);
   1538 	entry = isl_hash_table_find(ctx, table, c_hash, max_constraint_equal,
   1539 			con + 1, 0);
   1540 	if (!entry)
   1541 		return isl_stat_error;
   1542 	if (entry == isl_hash_table_entry_none)
   1543 		return isl_stat_ok;
   1544 	c = entry->data;
   1545 	if (c->count < n) {
   1546 		isl_hash_table_remove(ctx, table, entry);
   1547 		return isl_stat_ok;
   1548 	}
   1549 	c->count++;
   1550 	if (isl_int_gt(c->c->row[0][0], con[0]))
   1551 		return isl_stat_ok;
   1552 	if (isl_int_eq(c->c->row[0][0], con[0])) {
   1553 		if (ineq)
   1554 			c->ineq = ineq;
   1555 		return isl_stat_ok;
   1556 	}
   1557 	c->c = isl_mat_cow(c->c);
   1558 	isl_int_set(c->c->row[0][0], con[0]);
   1559 	c->ineq = ineq;
   1560 
   1561 	return isl_stat_ok;
   1562 }
   1563 
   1564 /* Check whether the constraint hash table "table" contains the constraint
   1565  * "con".
   1566  */
   1567 static isl_bool has_constraint(struct isl_ctx *ctx,
   1568 	struct isl_hash_table *table, isl_int *con, unsigned len, int n)
   1569 {
   1570 	struct isl_hash_table_entry *entry;
   1571 	struct max_constraint *c;
   1572 	uint32_t c_hash;
   1573 
   1574 	c_hash = isl_seq_get_hash(con + 1, len);
   1575 	entry = isl_hash_table_find(ctx, table, c_hash, max_constraint_equal,
   1576 			con + 1, 0);
   1577 	if (!entry)
   1578 		return isl_bool_error;
   1579 	if (entry == isl_hash_table_entry_none)
   1580 		return isl_bool_false;
   1581 	c = entry->data;
   1582 	if (c->count < n)
   1583 		return isl_bool_false;
   1584 	return isl_bool_ok(isl_int_eq(c->c->row[0][0], con[0]));
   1585 }
   1586 
   1587 /* Are the constraints of "bset" known to be facets?
   1588  * If there are any equality constraints, then they are not.
   1589  * If there may be redundant constraints, then those
   1590  * redundant constraints are not facets.
   1591  */
   1592 static isl_bool has_facets(__isl_keep isl_basic_set *bset)
   1593 {
   1594 	isl_size n_eq;
   1595 
   1596 	n_eq = isl_basic_set_n_equality(bset);
   1597 	if (n_eq < 0)
   1598 		return isl_bool_error;
   1599 	if (n_eq != 0)
   1600 		return isl_bool_false;
   1601 	return ISL_F_ISSET(bset, ISL_BASIC_SET_NO_REDUNDANT);
   1602 }
   1603 
   1604 /* Check for inequality constraints of a basic set without equalities
   1605  * or redundant constraints
   1606  * such that the same or more stringent copies of the constraint appear
   1607  * in all of the basic sets.  Such constraints are necessarily facet
   1608  * constraints of the convex hull.
   1609  *
   1610  * If the resulting basic set is by chance identical to one of
   1611  * the basic sets in "set", then we know that this basic set contains
   1612  * all other basic sets and is therefore the convex hull of set.
   1613  * In this case we set *is_hull to 1.
   1614  */
   1615 static __isl_give isl_basic_set *common_constraints(
   1616 	__isl_take isl_basic_set *hull, __isl_keep isl_set *set, int *is_hull)
   1617 {
   1618 	int i, j, s, n;
   1619 	int min_constraints;
   1620 	int best;
   1621 	struct max_constraint *constraints = NULL;
   1622 	struct isl_hash_table *table = NULL;
   1623 	isl_size total;
   1624 
   1625 	*is_hull = 0;
   1626 
   1627 	for (i = 0; i < set->n; ++i) {
   1628 		isl_bool facets = has_facets(set->p[i]);
   1629 		if (facets < 0)
   1630 			return isl_basic_set_free(hull);
   1631 		if (facets)
   1632 			break;
   1633 	}
   1634 	if (i >= set->n)
   1635 		return hull;
   1636 	min_constraints = set->p[i]->n_ineq;
   1637 	best = i;
   1638 	for (i = best + 1; i < set->n; ++i) {
   1639 		isl_bool facets = has_facets(set->p[i]);
   1640 		if (facets < 0)
   1641 			return isl_basic_set_free(hull);
   1642 		if (!facets)
   1643 			continue;
   1644 		if (set->p[i]->n_ineq >= min_constraints)
   1645 			continue;
   1646 		min_constraints = set->p[i]->n_ineq;
   1647 		best = i;
   1648 	}
   1649 	constraints = isl_calloc_array(hull->ctx, struct max_constraint,
   1650 					min_constraints);
   1651 	if (!constraints)
   1652 		return hull;
   1653 	table = isl_alloc_type(hull->ctx, struct isl_hash_table);
   1654 	if (isl_hash_table_init(hull->ctx, table, min_constraints))
   1655 		goto error;
   1656 
   1657 	total = isl_set_dim(set, isl_dim_all);
   1658 	if (total < 0)
   1659 		goto error;
   1660 	for (i = 0; i < set->p[best]->n_ineq; ++i) {
   1661 		constraints[i].c = isl_mat_sub_alloc6(hull->ctx,
   1662 			set->p[best]->ineq + i, 0, 1, 0, 1 + total);
   1663 		if (!constraints[i].c)
   1664 			goto error;
   1665 		constraints[i].ineq = 1;
   1666 	}
   1667 	for (i = 0; i < min_constraints; ++i) {
   1668 		struct isl_hash_table_entry *entry;
   1669 		uint32_t c_hash;
   1670 		c_hash = isl_seq_get_hash(constraints[i].c->row[0] + 1, total);
   1671 		entry = isl_hash_table_find(hull->ctx, table, c_hash,
   1672 			max_constraint_equal, constraints[i].c->row[0] + 1, 1);
   1673 		if (!entry)
   1674 			goto error;
   1675 		isl_assert(hull->ctx, !entry->data, goto error);
   1676 		entry->data = &constraints[i];
   1677 	}
   1678 
   1679 	n = 0;
   1680 	for (s = 0; s < set->n; ++s) {
   1681 		if (s == best)
   1682 			continue;
   1683 
   1684 		for (i = 0; i < set->p[s]->n_eq; ++i) {
   1685 			isl_int *eq = set->p[s]->eq[i];
   1686 			for (j = 0; j < 2; ++j) {
   1687 				isl_seq_neg(eq, eq, 1 + total);
   1688 				if (update_constraint(hull->ctx, table,
   1689 						    eq, total, n, 0) < 0)
   1690 					goto error;
   1691 			}
   1692 		}
   1693 		for (i = 0; i < set->p[s]->n_ineq; ++i) {
   1694 			isl_int *ineq = set->p[s]->ineq[i];
   1695 			if (update_constraint(hull->ctx, table, ineq, total, n,
   1696 					set->p[s]->n_eq == 0) < 0)
   1697 				goto error;
   1698 		}
   1699 		++n;
   1700 	}
   1701 
   1702 	for (i = 0; i < min_constraints; ++i) {
   1703 		if (constraints[i].count < n)
   1704 			continue;
   1705 		if (!constraints[i].ineq)
   1706 			continue;
   1707 		j = isl_basic_set_alloc_inequality(hull);
   1708 		if (j < 0)
   1709 			goto error;
   1710 		isl_seq_cpy(hull->ineq[j], constraints[i].c->row[0], 1 + total);
   1711 	}
   1712 
   1713 	for (s = 0; s < set->n; ++s) {
   1714 		if (set->p[s]->n_eq)
   1715 			continue;
   1716 		if (set->p[s]->n_ineq != hull->n_ineq)
   1717 			continue;
   1718 		for (i = 0; i < set->p[s]->n_ineq; ++i) {
   1719 			isl_bool has;
   1720 			isl_int *ineq = set->p[s]->ineq[i];
   1721 			has = has_constraint(hull->ctx, table, ineq, total, n);
   1722 			if (has < 0)
   1723 				goto error;
   1724 			if (!has)
   1725 				break;
   1726 		}
   1727 		if (i == set->p[s]->n_ineq)
   1728 			*is_hull = 1;
   1729 	}
   1730 
   1731 	isl_hash_table_clear(table);
   1732 	for (i = 0; i < min_constraints; ++i)
   1733 		isl_mat_free(constraints[i].c);
   1734 	free(constraints);
   1735 	free(table);
   1736 	return hull;
   1737 error:
   1738 	isl_hash_table_clear(table);
   1739 	free(table);
   1740 	if (constraints)
   1741 		for (i = 0; i < min_constraints; ++i)
   1742 			isl_mat_free(constraints[i].c);
   1743 	free(constraints);
   1744 	return hull;
   1745 }
   1746 
   1747 /* Create a template for the convex hull of "set" and fill it up
   1748  * obvious facet constraints, if any.  If the result happens to
   1749  * be the convex hull of "set" then *is_hull is set to 1.
   1750  */
   1751 static __isl_give isl_basic_set *proto_hull(__isl_keep isl_set *set,
   1752 	int *is_hull)
   1753 {
   1754 	struct isl_basic_set *hull;
   1755 	unsigned n_ineq;
   1756 	int i;
   1757 
   1758 	n_ineq = 1;
   1759 	for (i = 0; i < set->n; ++i) {
   1760 		n_ineq += set->p[i]->n_eq;
   1761 		n_ineq += set->p[i]->n_ineq;
   1762 	}
   1763 	hull = isl_basic_set_alloc_space(isl_space_copy(set->dim), 0, 0, n_ineq);
   1764 	hull = isl_basic_set_set_rational(hull);
   1765 	if (!hull)
   1766 		return NULL;
   1767 	return common_constraints(hull, set, is_hull);
   1768 }
   1769 
   1770 static __isl_give isl_basic_set *uset_convex_hull_wrap(__isl_take isl_set *set)
   1771 {
   1772 	struct isl_basic_set *hull;
   1773 	int is_hull;
   1774 
   1775 	hull = proto_hull(set, &is_hull);
   1776 	if (hull && !is_hull) {
   1777 		if (hull->n_ineq == 0)
   1778 			hull = initial_hull(hull, set);
   1779 		hull = extend(hull, set);
   1780 	}
   1781 	isl_set_free(set);
   1782 
   1783 	return hull;
   1784 }
   1785 
   1786 /* Compute the convex hull of a set without any parameters or
   1787  * integer divisions.  Depending on whether the set is bounded,
   1788  * we pass control to the wrapping based convex hull or
   1789  * the Fourier-Motzkin elimination based convex hull.
   1790  * We also handle a few special cases before checking the boundedness.
   1791  */
   1792 static __isl_give isl_basic_set *uset_convex_hull(__isl_take isl_set *set)
   1793 {
   1794 	isl_bool bounded;
   1795 	isl_size dim;
   1796 	struct isl_basic_set *convex_hull = NULL;
   1797 	struct isl_basic_set *lin;
   1798 
   1799 	dim = isl_set_dim(set, isl_dim_all);
   1800 	if (dim < 0)
   1801 		goto error;
   1802 	if (dim == 0)
   1803 		return convex_hull_0d(set);
   1804 
   1805 	set = isl_set_coalesce(set);
   1806 	set = isl_set_set_rational(set);
   1807 
   1808 	if (!set)
   1809 		return NULL;
   1810 	if (set->n == 1) {
   1811 		convex_hull = isl_basic_set_copy(set->p[0]);
   1812 		isl_set_free(set);
   1813 		return convex_hull;
   1814 	}
   1815 	if (dim == 1)
   1816 		return convex_hull_1d(set);
   1817 
   1818 	bounded = isl_set_is_bounded(set);
   1819 	if (bounded < 0)
   1820 		goto error;
   1821 	if (bounded && set->ctx->opt->convex == ISL_CONVEX_HULL_WRAP)
   1822 		return uset_convex_hull_wrap(set);
   1823 
   1824 	lin = isl_set_combined_lineality_space(isl_set_copy(set));
   1825 	if (!lin)
   1826 		goto error;
   1827 	if (isl_basic_set_plain_is_universe(lin)) {
   1828 		isl_set_free(set);
   1829 		return lin;
   1830 	}
   1831 	if (lin->n_eq < dim)
   1832 		return modulo_lineality(set, lin);
   1833 	isl_basic_set_free(lin);
   1834 
   1835 	return uset_convex_hull_unbounded(set);
   1836 error:
   1837 	isl_set_free(set);
   1838 	isl_basic_set_free(convex_hull);
   1839 	return NULL;
   1840 }
   1841 
   1842 /* This is the core procedure, where "set" is a "pure" set, i.e.,
   1843  * without parameters or divs and where the convex hull of set is
   1844  * known to be full-dimensional.
   1845  */
   1846 static __isl_give isl_basic_set *uset_convex_hull_wrap_bounded(
   1847 	__isl_take isl_set *set)
   1848 {
   1849 	struct isl_basic_set *convex_hull = NULL;
   1850 	isl_size dim;
   1851 
   1852 	dim = isl_set_dim(set, isl_dim_all);
   1853 	if (dim < 0)
   1854 		goto error;
   1855 
   1856 	if (dim == 0) {
   1857 		convex_hull = isl_basic_set_universe(isl_space_copy(set->dim));
   1858 		isl_set_free(set);
   1859 		convex_hull = isl_basic_set_set_rational(convex_hull);
   1860 		return convex_hull;
   1861 	}
   1862 
   1863 	set = isl_set_set_rational(set);
   1864 	set = isl_set_coalesce(set);
   1865 	if (!set)
   1866 		goto error;
   1867 	if (set->n == 1) {
   1868 		convex_hull = isl_basic_set_copy(set->p[0]);
   1869 		isl_set_free(set);
   1870 		convex_hull = isl_basic_map_remove_redundancies(convex_hull);
   1871 		return convex_hull;
   1872 	}
   1873 	if (dim == 1)
   1874 		return convex_hull_1d(set);
   1875 
   1876 	return uset_convex_hull_wrap(set);
   1877 error:
   1878 	isl_set_free(set);
   1879 	return NULL;
   1880 }
   1881 
   1882 /* Compute the convex hull of set "set" with affine hull "affine_hull",
   1883  * We first remove the equalities (transforming the set), compute the
   1884  * convex hull of the transformed set and then add the equalities back
   1885  * (after performing the inverse transformation.
   1886  */
   1887 static __isl_give isl_basic_set *modulo_affine_hull(
   1888 	__isl_take isl_set *set, __isl_take isl_basic_set *affine_hull)
   1889 {
   1890 	struct isl_mat *T;
   1891 	struct isl_mat *T2;
   1892 	struct isl_basic_set *dummy;
   1893 	struct isl_basic_set *convex_hull;
   1894 
   1895 	dummy = isl_basic_set_remove_equalities(
   1896 			isl_basic_set_copy(affine_hull), &T, &T2);
   1897 	if (!dummy)
   1898 		goto error;
   1899 	isl_basic_set_free(dummy);
   1900 	set = isl_set_preimage(set, T);
   1901 	convex_hull = uset_convex_hull(set);
   1902 	convex_hull = isl_basic_set_preimage(convex_hull, T2);
   1903 	convex_hull = isl_basic_set_intersect(convex_hull, affine_hull);
   1904 	return convex_hull;
   1905 error:
   1906 	isl_mat_free(T);
   1907 	isl_mat_free(T2);
   1908 	isl_basic_set_free(affine_hull);
   1909 	isl_set_free(set);
   1910 	return NULL;
   1911 }
   1912 
   1913 /* Return an empty basic map living in the same space as "map".
   1914  */
   1915 static __isl_give isl_basic_map *replace_map_by_empty_basic_map(
   1916 	__isl_take isl_map *map)
   1917 {
   1918 	isl_space *space;
   1919 
   1920 	space = isl_map_get_space(map);
   1921 	isl_map_free(map);
   1922 	return isl_basic_map_empty(space);
   1923 }
   1924 
   1925 /* Compute the convex hull of a map.
   1926  *
   1927  * The implementation was inspired by "Extended Convex Hull" by Fukuda et al.,
   1928  * specifically, the wrapping of facets to obtain new facets.
   1929  */
   1930 __isl_give isl_basic_map *isl_map_convex_hull(__isl_take isl_map *map)
   1931 {
   1932 	struct isl_basic_set *bset;
   1933 	struct isl_basic_map *model = NULL;
   1934 	struct isl_basic_set *affine_hull = NULL;
   1935 	struct isl_basic_map *convex_hull = NULL;
   1936 	struct isl_set *set = NULL;
   1937 
   1938 	map = isl_map_detect_equalities(map);
   1939 	map = isl_map_align_divs_internal(map);
   1940 	if (!map)
   1941 		goto error;
   1942 
   1943 	if (map->n == 0)
   1944 		return replace_map_by_empty_basic_map(map);
   1945 
   1946 	model = isl_basic_map_copy(map->p[0]);
   1947 	set = isl_map_underlying_set(map);
   1948 	if (!set)
   1949 		goto error;
   1950 
   1951 	affine_hull = isl_set_affine_hull(isl_set_copy(set));
   1952 	if (!affine_hull)
   1953 		goto error;
   1954 	if (affine_hull->n_eq != 0)
   1955 		bset = modulo_affine_hull(set, affine_hull);
   1956 	else {
   1957 		isl_basic_set_free(affine_hull);
   1958 		bset = uset_convex_hull(set);
   1959 	}
   1960 
   1961 	convex_hull = isl_basic_map_overlying_set(bset, model);
   1962 	if (!convex_hull)
   1963 		return NULL;
   1964 
   1965 	ISL_F_SET(convex_hull, ISL_BASIC_MAP_NO_IMPLICIT);
   1966 	ISL_F_SET(convex_hull, ISL_BASIC_MAP_ALL_EQUALITIES);
   1967 	ISL_F_CLR(convex_hull, ISL_BASIC_MAP_RATIONAL);
   1968 	return convex_hull;
   1969 error:
   1970 	isl_set_free(set);
   1971 	isl_basic_map_free(model);
   1972 	return NULL;
   1973 }
   1974 
   1975 __isl_give isl_basic_set *isl_set_convex_hull(__isl_take isl_set *set)
   1976 {
   1977 	return bset_from_bmap(isl_map_convex_hull(set_to_map(set)));
   1978 }
   1979 
   1980 __isl_give isl_basic_map *isl_map_polyhedral_hull(__isl_take isl_map *map)
   1981 {
   1982 	isl_basic_map *hull;
   1983 
   1984 	hull = isl_map_convex_hull(map);
   1985 	return isl_basic_map_remove_divs(hull);
   1986 }
   1987 
   1988 __isl_give isl_basic_set *isl_set_polyhedral_hull(__isl_take isl_set *set)
   1989 {
   1990 	return bset_from_bmap(isl_map_polyhedral_hull(set_to_map(set)));
   1991 }
   1992 
   1993 struct sh_data_entry {
   1994 	struct isl_hash_table	*table;
   1995 	struct isl_tab		*tab;
   1996 };
   1997 
   1998 /* Holds the data needed during the simple hull computation.
   1999  * In particular,
   2000  *	n		the number of basic sets in the original set
   2001  *	hull_table	a hash table of already computed constraints
   2002  *			in the simple hull
   2003  *	p		for each basic set,
   2004  *		table		a hash table of the constraints
   2005  *		tab		the tableau corresponding to the basic set
   2006  */
   2007 struct sh_data {
   2008 	struct isl_ctx		*ctx;
   2009 	unsigned		n;
   2010 	struct isl_hash_table	*hull_table;
   2011 	struct sh_data_entry	p[1];
   2012 };
   2013 
   2014 static void sh_data_free(struct sh_data *data)
   2015 {
   2016 	int i;
   2017 
   2018 	if (!data)
   2019 		return;
   2020 	isl_hash_table_free(data->ctx, data->hull_table);
   2021 	for (i = 0; i < data->n; ++i) {
   2022 		isl_hash_table_free(data->ctx, data->p[i].table);
   2023 		isl_tab_free(data->p[i].tab);
   2024 	}
   2025 	free(data);
   2026 }
   2027 
   2028 struct ineq_cmp_data {
   2029 	unsigned	len;
   2030 	isl_int		*p;
   2031 };
   2032 
   2033 static isl_bool has_ineq(const void *entry, const void *val)
   2034 {
   2035 	isl_int *row = (isl_int *)entry;
   2036 	struct ineq_cmp_data *v = (struct ineq_cmp_data *)val;
   2037 
   2038 	return isl_bool_ok(isl_seq_eq(row + 1, v->p + 1, v->len) ||
   2039 			   isl_seq_is_neg(row + 1, v->p + 1, v->len));
   2040 }
   2041 
   2042 static int hash_ineq(struct isl_ctx *ctx, struct isl_hash_table *table,
   2043 			isl_int *ineq, unsigned len)
   2044 {
   2045 	uint32_t c_hash;
   2046 	struct ineq_cmp_data v;
   2047 	struct isl_hash_table_entry *entry;
   2048 
   2049 	v.len = len;
   2050 	v.p = ineq;
   2051 	c_hash = isl_seq_get_hash(ineq + 1, len);
   2052 	entry = isl_hash_table_find(ctx, table, c_hash, has_ineq, &v, 1);
   2053 	if (!entry)
   2054 		return - 1;
   2055 	entry->data = ineq;
   2056 	return 0;
   2057 }
   2058 
   2059 /* Fill hash table "table" with the constraints of "bset".
   2060  * Equalities are added as two inequalities.
   2061  * The value in the hash table is a pointer to the (in)equality of "bset".
   2062  */
   2063 static isl_stat hash_basic_set(struct isl_hash_table *table,
   2064 	__isl_keep isl_basic_set *bset)
   2065 {
   2066 	int i, j;
   2067 	isl_size dim = isl_basic_set_dim(bset, isl_dim_all);
   2068 
   2069 	if (dim < 0)
   2070 		return isl_stat_error;
   2071 	for (i = 0; i < bset->n_eq; ++i) {
   2072 		for (j = 0; j < 2; ++j) {
   2073 			isl_seq_neg(bset->eq[i], bset->eq[i], 1 + dim);
   2074 			if (hash_ineq(bset->ctx, table, bset->eq[i], dim) < 0)
   2075 				return isl_stat_error;
   2076 		}
   2077 	}
   2078 	for (i = 0; i < bset->n_ineq; ++i) {
   2079 		if (hash_ineq(bset->ctx, table, bset->ineq[i], dim) < 0)
   2080 			return isl_stat_error;
   2081 	}
   2082 	return isl_stat_ok;
   2083 }
   2084 
   2085 static struct sh_data *sh_data_alloc(__isl_keep isl_set *set, unsigned n_ineq)
   2086 {
   2087 	struct sh_data *data;
   2088 	int i;
   2089 
   2090 	data = isl_calloc(set->ctx, struct sh_data,
   2091 		sizeof(struct sh_data) +
   2092 		(set->n - 1) * sizeof(struct sh_data_entry));
   2093 	if (!data)
   2094 		return NULL;
   2095 	data->ctx = set->ctx;
   2096 	data->n = set->n;
   2097 	data->hull_table = isl_hash_table_alloc(set->ctx, n_ineq);
   2098 	if (!data->hull_table)
   2099 		goto error;
   2100 	for (i = 0; i < set->n; ++i) {
   2101 		data->p[i].table = isl_hash_table_alloc(set->ctx,
   2102 				    2 * set->p[i]->n_eq + set->p[i]->n_ineq);
   2103 		if (!data->p[i].table)
   2104 			goto error;
   2105 		if (hash_basic_set(data->p[i].table, set->p[i]) < 0)
   2106 			goto error;
   2107 	}
   2108 	return data;
   2109 error:
   2110 	sh_data_free(data);
   2111 	return NULL;
   2112 }
   2113 
   2114 /* Check if inequality "ineq" is a bound for basic set "j" or if
   2115  * it can be relaxed (by increasing the constant term) to become
   2116  * a bound for that basic set.  In the latter case, the constant
   2117  * term is updated.
   2118  * Relaxation of the constant term is only allowed if "shift" is set.
   2119  *
   2120  * Return 1 if "ineq" is a bound
   2121  *	  0 if "ineq" may attain arbitrarily small values on basic set "j"
   2122  *	 -1 if some error occurred
   2123  */
   2124 static int is_bound(struct sh_data *data, __isl_keep isl_set *set, int j,
   2125 	isl_int *ineq, int shift)
   2126 {
   2127 	enum isl_lp_result res;
   2128 	isl_int opt;
   2129 
   2130 	if (!data->p[j].tab) {
   2131 		data->p[j].tab = isl_tab_from_basic_set(set->p[j], 0);
   2132 		if (!data->p[j].tab)
   2133 			return -1;
   2134 	}
   2135 
   2136 	isl_int_init(opt);
   2137 
   2138 	res = isl_tab_min(data->p[j].tab, ineq, data->ctx->one,
   2139 				&opt, NULL, 0);
   2140 	if (res == isl_lp_ok && isl_int_is_neg(opt)) {
   2141 		if (shift)
   2142 			isl_int_sub(ineq[0], ineq[0], opt);
   2143 		else
   2144 			res = isl_lp_unbounded;
   2145 	}
   2146 
   2147 	isl_int_clear(opt);
   2148 
   2149 	return (res == isl_lp_ok || res == isl_lp_empty) ? 1 :
   2150 	       res == isl_lp_unbounded ? 0 : -1;
   2151 }
   2152 
   2153 /* Set the constant term of "ineq" to the maximum of those of the constraints
   2154  * in the basic sets of "set" following "i" that are parallel to "ineq".
   2155  * That is, if any of the basic sets of "set" following "i" have a more
   2156  * relaxed copy of "ineq", then replace "ineq" by the most relaxed copy.
   2157  * "c_hash" is the hash value of the linear part of "ineq".
   2158  * "v" has been set up for use by has_ineq.
   2159  *
   2160  * Note that the two inequality constraints corresponding to an equality are
   2161  * represented by the same inequality constraint in data->p[j].table
   2162  * (but with different hash values).  This means the constraint (or at
   2163  * least its constant term) may need to be temporarily negated to get
   2164  * the actually hashed constraint.
   2165  */
   2166 static isl_stat set_max_constant_term(struct sh_data *data,
   2167 	__isl_keep isl_set *set,
   2168 	int i, isl_int *ineq, uint32_t c_hash, struct ineq_cmp_data *v)
   2169 {
   2170 	int j;
   2171 	isl_ctx *ctx;
   2172 	struct isl_hash_table_entry *entry;
   2173 
   2174 	ctx = isl_set_get_ctx(set);
   2175 	for (j = i + 1; j < set->n; ++j) {
   2176 		int neg;
   2177 		isl_int *ineq_j;
   2178 
   2179 		entry = isl_hash_table_find(ctx, data->p[j].table,
   2180 						c_hash, &has_ineq, v, 0);
   2181 		if (!entry)
   2182 			return isl_stat_error;
   2183 		if (entry == isl_hash_table_entry_none)
   2184 			continue;
   2185 
   2186 		ineq_j = entry->data;
   2187 		neg = isl_seq_is_neg(ineq_j + 1, ineq + 1, v->len);
   2188 		if (neg)
   2189 			isl_int_neg(ineq_j[0], ineq_j[0]);
   2190 		if (isl_int_gt(ineq_j[0], ineq[0]))
   2191 			isl_int_set(ineq[0], ineq_j[0]);
   2192 		if (neg)
   2193 			isl_int_neg(ineq_j[0], ineq_j[0]);
   2194 	}
   2195 
   2196 	return isl_stat_ok;
   2197 }
   2198 
   2199 /* Check if inequality "ineq" from basic set "i" is or can be relaxed to
   2200  * become a bound on the whole set.  If so, add the (relaxed) inequality
   2201  * to "hull".  Relaxation is only allowed if "shift" is set.
   2202  *
   2203  * We first check if "hull" already contains a translate of the inequality.
   2204  * If so, we are done.
   2205  * Then, we check if any of the previous basic sets contains a translate
   2206  * of the inequality.  If so, then we have already considered this
   2207  * inequality and we are done.
   2208  * Otherwise, for each basic set other than "i", we check if the inequality
   2209  * is a bound on the basic set, but first replace the constant term
   2210  * by the maximal value of any translate of the inequality in any
   2211  * of the following basic sets.
   2212  * For previous basic sets, we know that they do not contain a translate
   2213  * of the inequality, so we directly call is_bound.
   2214  * For following basic sets, we first check if a translate of the
   2215  * inequality appears in its description.  If so, the constant term
   2216  * of the inequality has already been updated with respect to this
   2217  * translate and the inequality is therefore known to be a bound
   2218  * of this basic set.
   2219  */
   2220 static __isl_give isl_basic_set *add_bound(__isl_take isl_basic_set *hull,
   2221 	struct sh_data *data, __isl_keep isl_set *set, int i, isl_int *ineq,
   2222 	int shift)
   2223 {
   2224 	uint32_t c_hash;
   2225 	struct ineq_cmp_data v;
   2226 	struct isl_hash_table_entry *entry;
   2227 	int j, k;
   2228 	isl_size total;
   2229 
   2230 	total = isl_basic_set_dim(hull, isl_dim_all);
   2231 	if (total < 0)
   2232 		return isl_basic_set_free(hull);
   2233 
   2234 	v.len = total;
   2235 	v.p = ineq;
   2236 	c_hash = isl_seq_get_hash(ineq + 1, v.len);
   2237 
   2238 	entry = isl_hash_table_find(hull->ctx, data->hull_table, c_hash,
   2239 					has_ineq, &v, 0);
   2240 	if (!entry)
   2241 		return isl_basic_set_free(hull);
   2242 	if (entry != isl_hash_table_entry_none)
   2243 		return hull;
   2244 
   2245 	for (j = 0; j < i; ++j) {
   2246 		entry = isl_hash_table_find(hull->ctx, data->p[j].table,
   2247 						c_hash, has_ineq, &v, 0);
   2248 		if (!entry)
   2249 			return isl_basic_set_free(hull);
   2250 		if (entry != isl_hash_table_entry_none)
   2251 			break;
   2252 	}
   2253 	if (j < i)
   2254 		return hull;
   2255 
   2256 	k = isl_basic_set_alloc_inequality(hull);
   2257 	if (k < 0)
   2258 		goto error;
   2259 	isl_seq_cpy(hull->ineq[k], ineq, 1 + v.len);
   2260 
   2261 	if (set_max_constant_term(data, set, i, hull->ineq[k], c_hash, &v) < 0)
   2262 		goto error;
   2263 	for (j = 0; j < i; ++j) {
   2264 		int bound;
   2265 		bound = is_bound(data, set, j, hull->ineq[k], shift);
   2266 		if (bound < 0)
   2267 			goto error;
   2268 		if (!bound)
   2269 			break;
   2270 	}
   2271 	if (j < i)
   2272 		return isl_basic_set_free_inequality(hull, 1);
   2273 
   2274 	for (j = i + 1; j < set->n; ++j) {
   2275 		int bound;
   2276 		entry = isl_hash_table_find(hull->ctx, data->p[j].table,
   2277 						c_hash, has_ineq, &v, 0);
   2278 		if (!entry)
   2279 			return isl_basic_set_free(hull);
   2280 		if (entry != isl_hash_table_entry_none)
   2281 			continue;
   2282 		bound = is_bound(data, set, j, hull->ineq[k], shift);
   2283 		if (bound < 0)
   2284 			goto error;
   2285 		if (!bound)
   2286 			break;
   2287 	}
   2288 	if (j < set->n)
   2289 		return isl_basic_set_free_inequality(hull, 1);
   2290 
   2291 	entry = isl_hash_table_find(hull->ctx, data->hull_table, c_hash,
   2292 					has_ineq, &v, 1);
   2293 	if (!entry)
   2294 		goto error;
   2295 	entry->data = hull->ineq[k];
   2296 
   2297 	return hull;
   2298 error:
   2299 	isl_basic_set_free(hull);
   2300 	return NULL;
   2301 }
   2302 
   2303 /* Check if any inequality from basic set "i" is or can be relaxed to
   2304  * become a bound on the whole set.  If so, add the (relaxed) inequality
   2305  * to "hull".  Relaxation is only allowed if "shift" is set.
   2306  */
   2307 static __isl_give isl_basic_set *add_bounds(__isl_take isl_basic_set *bset,
   2308 	struct sh_data *data, __isl_keep isl_set *set, int i, int shift)
   2309 {
   2310 	int j, k;
   2311 	isl_size dim = isl_basic_set_dim(bset, isl_dim_all);
   2312 
   2313 	if (dim < 0)
   2314 		return isl_basic_set_free(bset);
   2315 
   2316 	for (j = 0; j < set->p[i]->n_eq; ++j) {
   2317 		for (k = 0; k < 2; ++k) {
   2318 			isl_seq_neg(set->p[i]->eq[j], set->p[i]->eq[j], 1+dim);
   2319 			bset = add_bound(bset, data, set, i, set->p[i]->eq[j],
   2320 					    shift);
   2321 		}
   2322 	}
   2323 	for (j = 0; j < set->p[i]->n_ineq; ++j)
   2324 		bset = add_bound(bset, data, set, i, set->p[i]->ineq[j], shift);
   2325 	return bset;
   2326 }
   2327 
   2328 /* Compute a superset of the convex hull of set that is described
   2329  * by only (translates of) the constraints in the constituents of set.
   2330  * Translation is only allowed if "shift" is set.
   2331  */
   2332 static __isl_give isl_basic_set *uset_simple_hull(__isl_take isl_set *set,
   2333 	int shift)
   2334 {
   2335 	struct sh_data *data = NULL;
   2336 	struct isl_basic_set *hull = NULL;
   2337 	unsigned n_ineq;
   2338 	int i;
   2339 
   2340 	if (!set)
   2341 		return NULL;
   2342 
   2343 	n_ineq = 0;
   2344 	for (i = 0; i < set->n; ++i) {
   2345 		if (!set->p[i])
   2346 			goto error;
   2347 		n_ineq += 2 * set->p[i]->n_eq + set->p[i]->n_ineq;
   2348 	}
   2349 
   2350 	hull = isl_basic_set_alloc_space(isl_space_copy(set->dim), 0, 0, n_ineq);
   2351 	if (!hull)
   2352 		goto error;
   2353 
   2354 	data = sh_data_alloc(set, n_ineq);
   2355 	if (!data)
   2356 		goto error;
   2357 
   2358 	for (i = 0; i < set->n; ++i)
   2359 		hull = add_bounds(hull, data, set, i, shift);
   2360 
   2361 	sh_data_free(data);
   2362 	isl_set_free(set);
   2363 
   2364 	return hull;
   2365 error:
   2366 	sh_data_free(data);
   2367 	isl_basic_set_free(hull);
   2368 	isl_set_free(set);
   2369 	return NULL;
   2370 }
   2371 
   2372 /* Compute a superset of the convex hull of map that is described
   2373  * by only (translates of) the constraints in the constituents of map.
   2374  * Handle trivial cases where map is NULL or contains at most one disjunct.
   2375  */
   2376 static __isl_give isl_basic_map *map_simple_hull_trivial(
   2377 	__isl_take isl_map *map)
   2378 {
   2379 	isl_basic_map *hull;
   2380 
   2381 	if (!map)
   2382 		return NULL;
   2383 	if (map->n == 0)
   2384 		return replace_map_by_empty_basic_map(map);
   2385 
   2386 	hull = isl_basic_map_copy(map->p[0]);
   2387 	isl_map_free(map);
   2388 	return hull;
   2389 }
   2390 
   2391 /* Return a copy of the simple hull cached inside "map".
   2392  * "shift" determines whether to return the cached unshifted or shifted
   2393  * simple hull.
   2394  */
   2395 static __isl_give isl_basic_map *cached_simple_hull(__isl_take isl_map *map,
   2396 	int shift)
   2397 {
   2398 	isl_basic_map *hull;
   2399 
   2400 	hull = isl_basic_map_copy(map->cached_simple_hull[shift]);
   2401 	isl_map_free(map);
   2402 
   2403 	return hull;
   2404 }
   2405 
   2406 /* Compute a superset of the convex hull of map that is described
   2407  * by only (translates of) the constraints in the constituents of map.
   2408  * Translation is only allowed if "shift" is set.
   2409  *
   2410  * The constraints are sorted while removing redundant constraints
   2411  * in order to indicate a preference of which constraints should
   2412  * be preserved.  In particular, pairs of constraints that are
   2413  * sorted together are preferred to either both be preserved
   2414  * or both be removed.  The sorting is performed inside
   2415  * isl_basic_map_remove_redundancies.
   2416  *
   2417  * The result of the computation is stored in map->cached_simple_hull[shift]
   2418  * such that it can be reused in subsequent calls.  The cache is cleared
   2419  * whenever the map is modified (in isl_map_cow).
   2420  * Note that the results need to be stored in the input map for there
   2421  * to be any chance that they may get reused.  In particular, they
   2422  * are stored in a copy of the input map that is saved before
   2423  * the integer division alignment.
   2424  */
   2425 static __isl_give isl_basic_map *map_simple_hull(__isl_take isl_map *map,
   2426 	int shift)
   2427 {
   2428 	struct isl_set *set = NULL;
   2429 	struct isl_basic_map *model = NULL;
   2430 	struct isl_basic_map *hull;
   2431 	struct isl_basic_map *affine_hull;
   2432 	struct isl_basic_set *bset = NULL;
   2433 	isl_map *input;
   2434 
   2435 	if (!map || map->n <= 1)
   2436 		return map_simple_hull_trivial(map);
   2437 
   2438 	if (map->cached_simple_hull[shift])
   2439 		return cached_simple_hull(map, shift);
   2440 
   2441 	map = isl_map_detect_equalities(map);
   2442 	if (!map || map->n <= 1)
   2443 		return map_simple_hull_trivial(map);
   2444 	affine_hull = isl_map_affine_hull(isl_map_copy(map));
   2445 	input = isl_map_copy(map);
   2446 	map = isl_map_align_divs_internal(map);
   2447 	model = map ? isl_basic_map_copy(map->p[0]) : NULL;
   2448 
   2449 	set = isl_map_underlying_set(map);
   2450 
   2451 	bset = uset_simple_hull(set, shift);
   2452 
   2453 	hull = isl_basic_map_overlying_set(bset, model);
   2454 
   2455 	hull = isl_basic_map_intersect(hull, affine_hull);
   2456 	hull = isl_basic_map_remove_redundancies(hull);
   2457 
   2458 	if (hull) {
   2459 		ISL_F_SET(hull, ISL_BASIC_MAP_NO_IMPLICIT);
   2460 		ISL_F_SET(hull, ISL_BASIC_MAP_ALL_EQUALITIES);
   2461 	}
   2462 
   2463 	hull = isl_basic_map_finalize(hull);
   2464 	if (input)
   2465 		input->cached_simple_hull[shift] = isl_basic_map_copy(hull);
   2466 	isl_map_free(input);
   2467 
   2468 	return hull;
   2469 }
   2470 
   2471 /* Compute a superset of the convex hull of map that is described
   2472  * by only translates of the constraints in the constituents of map.
   2473  */
   2474 __isl_give isl_basic_map *isl_map_simple_hull(__isl_take isl_map *map)
   2475 {
   2476 	return map_simple_hull(map, 1);
   2477 }
   2478 
   2479 __isl_give isl_basic_set *isl_set_simple_hull(__isl_take isl_set *set)
   2480 {
   2481 	return bset_from_bmap(isl_map_simple_hull(set_to_map(set)));
   2482 }
   2483 
   2484 /* Compute a superset of the convex hull of map that is described
   2485  * by only the constraints in the constituents of map.
   2486  */
   2487 __isl_give isl_basic_map *isl_map_unshifted_simple_hull(
   2488 	__isl_take isl_map *map)
   2489 {
   2490 	return map_simple_hull(map, 0);
   2491 }
   2492 
   2493 __isl_give isl_basic_set *isl_set_unshifted_simple_hull(
   2494 	__isl_take isl_set *set)
   2495 {
   2496 	return isl_map_unshifted_simple_hull(set);
   2497 }
   2498 
   2499 /* Drop all inequalities from "bmap1" that do not also appear in "bmap2".
   2500  * A constraint that appears with different constant terms
   2501  * in "bmap1" and "bmap2" is also kept, with the least restrictive
   2502  * (i.e., greatest) constant term.
   2503  * "bmap1" and "bmap2" are assumed to have the same (known)
   2504  * integer divisions.
   2505  * The constraints of both "bmap1" and "bmap2" are assumed
   2506  * to have been sorted using isl_basic_map_sort_constraints.
   2507  *
   2508  * Run through the inequality constraints of "bmap1" and "bmap2"
   2509  * in sorted order.
   2510  * Each constraint of "bmap1" without a matching constraint in "bmap2"
   2511  * is removed.
   2512  * If a match is found, the constraint is kept.  If needed, the constant
   2513  * term of the constraint is adjusted.
   2514  */
   2515 static __isl_give isl_basic_map *select_shared_inequalities(
   2516 	__isl_take isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2)
   2517 {
   2518 	int i1, i2;
   2519 
   2520 	bmap1 = isl_basic_map_cow(bmap1);
   2521 	if (!bmap1 || !bmap2)
   2522 		return isl_basic_map_free(bmap1);
   2523 
   2524 	i1 = bmap1->n_ineq - 1;
   2525 	i2 = bmap2->n_ineq - 1;
   2526 	while (bmap1 && i1 >= 0 && i2 >= 0) {
   2527 		int cmp;
   2528 
   2529 		cmp = isl_basic_map_constraint_cmp(bmap1, bmap1->ineq[i1],
   2530 							bmap2->ineq[i2]);
   2531 		if (cmp < 0) {
   2532 			--i2;
   2533 			continue;
   2534 		}
   2535 		if (cmp > 0) {
   2536 			if (isl_basic_map_drop_inequality(bmap1, i1) < 0)
   2537 				bmap1 = isl_basic_map_free(bmap1);
   2538 			--i1;
   2539 			continue;
   2540 		}
   2541 		if (isl_int_lt(bmap1->ineq[i1][0], bmap2->ineq[i2][0]))
   2542 			isl_int_set(bmap1->ineq[i1][0], bmap2->ineq[i2][0]);
   2543 		--i1;
   2544 		--i2;
   2545 	}
   2546 	for (; i1 >= 0; --i1)
   2547 		if (isl_basic_map_drop_inequality(bmap1, i1) < 0)
   2548 			bmap1 = isl_basic_map_free(bmap1);
   2549 
   2550 	return bmap1;
   2551 }
   2552 
   2553 /* Drop all equalities from "bmap1" that do not also appear in "bmap2".
   2554  * "bmap1" and "bmap2" are assumed to have the same (known)
   2555  * integer divisions.
   2556  *
   2557  * Run through the equality constraints of "bmap1" and "bmap2".
   2558  * Each constraint of "bmap1" without a matching constraint in "bmap2"
   2559  * is removed.
   2560  */
   2561 static __isl_give isl_basic_map *select_shared_equalities(
   2562 	__isl_take isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2)
   2563 {
   2564 	int i1, i2;
   2565 	isl_size total;
   2566 
   2567 	bmap1 = isl_basic_map_cow(bmap1);
   2568 	total = isl_basic_map_dim(bmap1, isl_dim_all);
   2569 	if (total < 0 || !bmap2)
   2570 		return isl_basic_map_free(bmap1);
   2571 
   2572 	i1 = bmap1->n_eq - 1;
   2573 	i2 = bmap2->n_eq - 1;
   2574 	while (bmap1 && i1 >= 0 && i2 >= 0) {
   2575 		int last1, last2;
   2576 
   2577 		last1 = isl_seq_last_non_zero(bmap1->eq[i1] + 1, total);
   2578 		last2 = isl_seq_last_non_zero(bmap2->eq[i2] + 1, total);
   2579 		if (last1 > last2) {
   2580 			--i2;
   2581 			continue;
   2582 		}
   2583 		if (last1 < last2) {
   2584 			if (isl_basic_map_drop_equality(bmap1, i1) < 0)
   2585 				bmap1 = isl_basic_map_free(bmap1);
   2586 			--i1;
   2587 			continue;
   2588 		}
   2589 		if (!isl_seq_eq(bmap1->eq[i1], bmap2->eq[i2], 1 + total)) {
   2590 			if (isl_basic_map_drop_equality(bmap1, i1) < 0)
   2591 				bmap1 = isl_basic_map_free(bmap1);
   2592 		}
   2593 		--i1;
   2594 		--i2;
   2595 	}
   2596 	for (; i1 >= 0; --i1)
   2597 		if (isl_basic_map_drop_equality(bmap1, i1) < 0)
   2598 			bmap1 = isl_basic_map_free(bmap1);
   2599 
   2600 	return bmap1;
   2601 }
   2602 
   2603 /* Compute a superset of "bmap1" and "bmap2" that is described
   2604  * by only the constraints that appear in both "bmap1" and "bmap2".
   2605  *
   2606  * First drop constraints that involve unknown integer divisions
   2607  * since it is not trivial to check whether two such integer divisions
   2608  * in different basic maps are the same.
   2609  * Then align the remaining (known) divs and sort the constraints.
   2610  * Finally drop all inequalities and equalities from "bmap1" that
   2611  * do not also appear in "bmap2".
   2612  */
   2613 __isl_give isl_basic_map *isl_basic_map_plain_unshifted_simple_hull(
   2614 	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
   2615 {
   2616 	if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
   2617 		goto error;
   2618 
   2619 	bmap1 = isl_basic_map_drop_constraints_involving_unknown_divs(bmap1);
   2620 	bmap2 = isl_basic_map_drop_constraints_involving_unknown_divs(bmap2);
   2621 	bmap1 = isl_basic_map_order_divs(bmap1);
   2622 	bmap2 = isl_basic_map_align_divs(bmap2, bmap1);
   2623 	bmap1 = isl_basic_map_align_divs(bmap1, bmap2);
   2624 	bmap1 = isl_basic_map_sort_constraints(bmap1);
   2625 	bmap2 = isl_basic_map_sort_constraints(bmap2);
   2626 
   2627 	bmap1 = select_shared_inequalities(bmap1, bmap2);
   2628 	bmap1 = select_shared_equalities(bmap1, bmap2);
   2629 
   2630 	isl_basic_map_free(bmap2);
   2631 	bmap1 = isl_basic_map_finalize(bmap1);
   2632 	return bmap1;
   2633 error:
   2634 	isl_basic_map_free(bmap1);
   2635 	isl_basic_map_free(bmap2);
   2636 	return NULL;
   2637 }
   2638 
   2639 /* Compute a superset of the convex hull of "map" that is described
   2640  * by only the constraints in the constituents of "map".
   2641  * In particular, the result is composed of constraints that appear
   2642  * in each of the basic maps of "map"
   2643  *
   2644  * Constraints that involve unknown integer divisions are dropped
   2645  * since it is not trivial to check whether two such integer divisions
   2646  * in different basic maps are the same.
   2647  *
   2648  * The hull is initialized from the first basic map and then
   2649  * updated with respect to the other basic maps in turn.
   2650  */
   2651 __isl_give isl_basic_map *isl_map_plain_unshifted_simple_hull(
   2652 	__isl_take isl_map *map)
   2653 {
   2654 	int i;
   2655 	isl_basic_map *hull;
   2656 
   2657 	if (!map)
   2658 		return NULL;
   2659 	if (map->n <= 1)
   2660 		return map_simple_hull_trivial(map);
   2661 	map = isl_map_drop_constraints_involving_unknown_divs(map);
   2662 	hull = isl_basic_map_copy(map->p[0]);
   2663 	for (i = 1; i < map->n; ++i) {
   2664 		isl_basic_map *bmap_i;
   2665 
   2666 		bmap_i = isl_basic_map_copy(map->p[i]);
   2667 		hull = isl_basic_map_plain_unshifted_simple_hull(hull, bmap_i);
   2668 	}
   2669 
   2670 	isl_map_free(map);
   2671 	return hull;
   2672 }
   2673 
   2674 /* Compute a superset of the convex hull of "set" that is described
   2675  * by only the constraints in the constituents of "set".
   2676  * In particular, the result is composed of constraints that appear
   2677  * in each of the basic sets of "set"
   2678  */
   2679 __isl_give isl_basic_set *isl_set_plain_unshifted_simple_hull(
   2680 	__isl_take isl_set *set)
   2681 {
   2682 	return isl_map_plain_unshifted_simple_hull(set);
   2683 }
   2684 
   2685 /* Check if "ineq" is a bound on "set" and, if so, add it to "hull".
   2686  *
   2687  * For each basic set in "set", we first check if the basic set
   2688  * contains a translate of "ineq".  If this translate is more relaxed,
   2689  * then we assume that "ineq" is not a bound on this basic set.
   2690  * Otherwise, we know that it is a bound.
   2691  * If the basic set does not contain a translate of "ineq", then
   2692  * we call is_bound to perform the test.
   2693  */
   2694 static __isl_give isl_basic_set *add_bound_from_constraint(
   2695 	__isl_take isl_basic_set *hull, struct sh_data *data,
   2696 	__isl_keep isl_set *set, isl_int *ineq)
   2697 {
   2698 	int i, k;
   2699 	isl_ctx *ctx;
   2700 	uint32_t c_hash;
   2701 	struct ineq_cmp_data v;
   2702 	isl_size total;
   2703 
   2704 	total = isl_basic_set_dim(hull, isl_dim_all);
   2705 	if (total < 0 || !set)
   2706 		return isl_basic_set_free(hull);
   2707 
   2708 	v.len = total;
   2709 	v.p = ineq;
   2710 	c_hash = isl_seq_get_hash(ineq + 1, v.len);
   2711 
   2712 	ctx = isl_basic_set_get_ctx(hull);
   2713 	for (i = 0; i < set->n; ++i) {
   2714 		int bound;
   2715 		struct isl_hash_table_entry *entry;
   2716 
   2717 		entry = isl_hash_table_find(ctx, data->p[i].table,
   2718 						c_hash, &has_ineq, &v, 0);
   2719 		if (!entry)
   2720 			return isl_basic_set_free(hull);
   2721 		if (entry != isl_hash_table_entry_none) {
   2722 			isl_int *ineq_i = entry->data;
   2723 			int neg, more_relaxed;
   2724 
   2725 			neg = isl_seq_is_neg(ineq_i + 1, ineq + 1, v.len);
   2726 			if (neg)
   2727 				isl_int_neg(ineq_i[0], ineq_i[0]);
   2728 			more_relaxed = isl_int_gt(ineq_i[0], ineq[0]);
   2729 			if (neg)
   2730 				isl_int_neg(ineq_i[0], ineq_i[0]);
   2731 			if (more_relaxed)
   2732 				break;
   2733 			else
   2734 				continue;
   2735 		}
   2736 		bound = is_bound(data, set, i, ineq, 0);
   2737 		if (bound < 0)
   2738 			return isl_basic_set_free(hull);
   2739 		if (!bound)
   2740 			break;
   2741 	}
   2742 	if (i < set->n)
   2743 		return hull;
   2744 
   2745 	k = isl_basic_set_alloc_inequality(hull);
   2746 	if (k < 0)
   2747 		return isl_basic_set_free(hull);
   2748 	isl_seq_cpy(hull->ineq[k], ineq, 1 + v.len);
   2749 
   2750 	return hull;
   2751 }
   2752 
   2753 /* Compute a superset of the convex hull of "set" that is described
   2754  * by only some of the "n_ineq" constraints in the list "ineq", where "set"
   2755  * has no parameters or integer divisions.
   2756  *
   2757  * The inequalities in "ineq" are assumed to have been sorted such
   2758  * that constraints with the same linear part appear together and
   2759  * that among constraints with the same linear part, those with
   2760  * smaller constant term appear first.
   2761  *
   2762  * We reuse the same data structure that is used by uset_simple_hull,
   2763  * but we do not need the hull table since we will not consider the
   2764  * same constraint more than once.  We therefore allocate it with zero size.
   2765  *
   2766  * We run through the constraints and try to add them one by one,
   2767  * skipping identical constraints.  If we have added a constraint and
   2768  * the next constraint is a more relaxed translate, then we skip this
   2769  * next constraint as well.
   2770  */
   2771 static __isl_give isl_basic_set *uset_unshifted_simple_hull_from_constraints(
   2772 	__isl_take isl_set *set, int n_ineq, isl_int **ineq)
   2773 {
   2774 	int i;
   2775 	int last_added = 0;
   2776 	struct sh_data *data = NULL;
   2777 	isl_basic_set *hull = NULL;
   2778 	isl_size dim;
   2779 
   2780 	hull = isl_basic_set_alloc_space(isl_set_get_space(set), 0, 0, n_ineq);
   2781 	if (!hull)
   2782 		goto error;
   2783 
   2784 	data = sh_data_alloc(set, 0);
   2785 	if (!data)
   2786 		goto error;
   2787 
   2788 	dim = isl_set_dim(set, isl_dim_set);
   2789 	if (dim < 0)
   2790 		goto error;
   2791 	for (i = 0; i < n_ineq; ++i) {
   2792 		int hull_n_ineq = hull->n_ineq;
   2793 		int parallel;
   2794 
   2795 		parallel = i > 0 && isl_seq_eq(ineq[i - 1] + 1, ineq[i] + 1,
   2796 						dim);
   2797 		if (parallel &&
   2798 		    (last_added || isl_int_eq(ineq[i - 1][0], ineq[i][0])))
   2799 			continue;
   2800 		hull = add_bound_from_constraint(hull, data, set, ineq[i]);
   2801 		if (!hull)
   2802 			goto error;
   2803 		last_added = hull->n_ineq > hull_n_ineq;
   2804 	}
   2805 
   2806 	sh_data_free(data);
   2807 	isl_set_free(set);
   2808 	return hull;
   2809 error:
   2810 	sh_data_free(data);
   2811 	isl_set_free(set);
   2812 	isl_basic_set_free(hull);
   2813 	return NULL;
   2814 }
   2815 
   2816 /* Collect pointers to all the inequalities in the elements of "list"
   2817  * in "ineq".  For equalities, store both a pointer to the equality and
   2818  * a pointer to its opposite, which is first copied to "mat".
   2819  * "ineq" and "mat" are assumed to have been preallocated to the right size
   2820  * (the number of inequalities + 2 times the number of equalites and
   2821  * the number of equalities, respectively).
   2822  */
   2823 static __isl_give isl_mat *collect_inequalities(__isl_take isl_mat *mat,
   2824 	__isl_keep isl_basic_set_list *list, isl_int **ineq)
   2825 {
   2826 	int i, j, n_eq, n_ineq;
   2827 	isl_size n;
   2828 
   2829 	n = isl_basic_set_list_n_basic_set(list);
   2830 	if (!mat || n < 0)
   2831 		return isl_mat_free(mat);
   2832 
   2833 	n_eq = 0;
   2834 	n_ineq = 0;
   2835 	for (i = 0; i < n; ++i) {
   2836 		isl_basic_set *bset;
   2837 		bset = isl_basic_set_list_get_basic_set(list, i);
   2838 		if (!bset)
   2839 			return isl_mat_free(mat);
   2840 		for (j = 0; j < bset->n_eq; ++j) {
   2841 			ineq[n_ineq++] = mat->row[n_eq];
   2842 			ineq[n_ineq++] = bset->eq[j];
   2843 			isl_seq_neg(mat->row[n_eq++], bset->eq[j], mat->n_col);
   2844 		}
   2845 		for (j = 0; j < bset->n_ineq; ++j)
   2846 			ineq[n_ineq++] = bset->ineq[j];
   2847 		isl_basic_set_free(bset);
   2848 	}
   2849 
   2850 	return mat;
   2851 }
   2852 
   2853 /* Comparison routine for use as an isl_sort callback.
   2854  *
   2855  * Constraints with the same linear part are sorted together and
   2856  * among constraints with the same linear part, those with smaller
   2857  * constant term are sorted first.
   2858  */
   2859 static int cmp_ineq(const void *a, const void *b, void *arg)
   2860 {
   2861 	unsigned dim = *(unsigned *) arg;
   2862 	isl_int * const *ineq1 = a;
   2863 	isl_int * const *ineq2 = b;
   2864 	int cmp;
   2865 
   2866 	cmp = isl_seq_cmp((*ineq1) + 1, (*ineq2) + 1, dim);
   2867 	if (cmp != 0)
   2868 		return cmp;
   2869 	return isl_int_cmp((*ineq1)[0], (*ineq2)[0]);
   2870 }
   2871 
   2872 /* Compute a superset of the convex hull of "set" that is described
   2873  * by only constraints in the elements of "list", where "set" has
   2874  * no parameters or integer divisions.
   2875  *
   2876  * We collect all the constraints in those elements and then
   2877  * sort the constraints such that constraints with the same linear part
   2878  * are sorted together and that those with smaller constant term are
   2879  * sorted first.
   2880  */
   2881 static __isl_give isl_basic_set *uset_unshifted_simple_hull_from_basic_set_list(
   2882 	__isl_take isl_set *set, __isl_take isl_basic_set_list *list)
   2883 {
   2884 	int i, n_eq, n_ineq;
   2885 	isl_size n;
   2886 	isl_size dim;
   2887 	isl_ctx *ctx;
   2888 	isl_mat *mat = NULL;
   2889 	isl_int **ineq = NULL;
   2890 	isl_basic_set *hull;
   2891 
   2892 	n = isl_basic_set_list_n_basic_set(list);
   2893 	if (!set || n < 0)
   2894 		goto error;
   2895 	ctx = isl_set_get_ctx(set);
   2896 
   2897 	n_eq = 0;
   2898 	n_ineq = 0;
   2899 	for (i = 0; i < n; ++i) {
   2900 		isl_basic_set *bset;
   2901 		bset = isl_basic_set_list_get_basic_set(list, i);
   2902 		if (!bset)
   2903 			goto error;
   2904 		n_eq += bset->n_eq;
   2905 		n_ineq += 2 * bset->n_eq + bset->n_ineq;
   2906 		isl_basic_set_free(bset);
   2907 	}
   2908 
   2909 	ineq = isl_alloc_array(ctx, isl_int *, n_ineq);
   2910 	if (n_ineq > 0 && !ineq)
   2911 		goto error;
   2912 
   2913 	dim = isl_set_dim(set, isl_dim_set);
   2914 	if (dim < 0)
   2915 		goto error;
   2916 	mat = isl_mat_alloc(ctx, n_eq, 1 + dim);
   2917 	mat = collect_inequalities(mat, list, ineq);
   2918 	if (!mat)
   2919 		goto error;
   2920 
   2921 	if (isl_sort(ineq, n_ineq, sizeof(ineq[0]), &cmp_ineq, &dim) < 0)
   2922 		goto error;
   2923 
   2924 	hull = uset_unshifted_simple_hull_from_constraints(set, n_ineq, ineq);
   2925 
   2926 	isl_mat_free(mat);
   2927 	free(ineq);
   2928 	isl_basic_set_list_free(list);
   2929 	return hull;
   2930 error:
   2931 	isl_mat_free(mat);
   2932 	free(ineq);
   2933 	isl_set_free(set);
   2934 	isl_basic_set_list_free(list);
   2935 	return NULL;
   2936 }
   2937 
   2938 /* Compute a superset of the convex hull of "map" that is described
   2939  * by only constraints in the elements of "list".
   2940  *
   2941  * If the list is empty, then we can only describe the universe set.
   2942  * If the input map is empty, then all constraints are valid, so
   2943  * we return the intersection of the elements in "list".
   2944  *
   2945  * Otherwise, we align all divs and temporarily treat them
   2946  * as regular variables, computing the unshifted simple hull in
   2947  * uset_unshifted_simple_hull_from_basic_set_list.
   2948  */
   2949 static __isl_give isl_basic_map *map_unshifted_simple_hull_from_basic_map_list(
   2950 	__isl_take isl_map *map, __isl_take isl_basic_map_list *list)
   2951 {
   2952 	isl_size n;
   2953 	isl_basic_map *model;
   2954 	isl_basic_map *hull;
   2955 	isl_set *set;
   2956 	isl_basic_set_list *bset_list;
   2957 
   2958 	n = isl_basic_map_list_n_basic_map(list);
   2959 	if (!map || n < 0)
   2960 		goto error;
   2961 
   2962 	if (n == 0) {
   2963 		isl_space *space;
   2964 
   2965 		space = isl_map_get_space(map);
   2966 		isl_map_free(map);
   2967 		isl_basic_map_list_free(list);
   2968 		return isl_basic_map_universe(space);
   2969 	}
   2970 	if (isl_map_plain_is_empty(map)) {
   2971 		isl_map_free(map);
   2972 		return isl_basic_map_list_intersect(list);
   2973 	}
   2974 
   2975 	map = isl_map_align_divs_to_basic_map_list(map, list);
   2976 	if (!map)
   2977 		goto error;
   2978 	list = isl_basic_map_list_align_divs_to_basic_map(list, map->p[0]);
   2979 
   2980 	model = isl_basic_map_list_get_basic_map(list, 0);
   2981 
   2982 	set = isl_map_underlying_set(map);
   2983 	bset_list = isl_basic_map_list_underlying_set(list);
   2984 
   2985 	hull = uset_unshifted_simple_hull_from_basic_set_list(set, bset_list);
   2986 	hull = isl_basic_map_overlying_set(hull, model);
   2987 
   2988 	return hull;
   2989 error:
   2990 	isl_map_free(map);
   2991 	isl_basic_map_list_free(list);
   2992 	return NULL;
   2993 }
   2994 
   2995 /* Return a sequence of the basic maps that make up the maps in "list".
   2996  */
   2997 static __isl_give isl_basic_map_list *collect_basic_maps(
   2998 	__isl_take isl_map_list *list)
   2999 {
   3000 	int i;
   3001 	isl_size n;
   3002 	isl_ctx *ctx;
   3003 	isl_basic_map_list *bmap_list;
   3004 
   3005 	if (!list)
   3006 		return NULL;
   3007 	n = isl_map_list_n_map(list);
   3008 	ctx = isl_map_list_get_ctx(list);
   3009 	bmap_list = isl_basic_map_list_alloc(ctx, 0);
   3010 	if (n < 0)
   3011 		bmap_list = isl_basic_map_list_free(bmap_list);
   3012 
   3013 	for (i = 0; i < n; ++i) {
   3014 		isl_map *map;
   3015 		isl_basic_map_list *list_i;
   3016 
   3017 		map = isl_map_list_get_map(list, i);
   3018 		map = isl_map_compute_divs(map);
   3019 		list_i = isl_map_get_basic_map_list(map);
   3020 		isl_map_free(map);
   3021 		bmap_list = isl_basic_map_list_concat(bmap_list, list_i);
   3022 	}
   3023 
   3024 	isl_map_list_free(list);
   3025 	return bmap_list;
   3026 }
   3027 
   3028 /* Compute a superset of the convex hull of "map" that is described
   3029  * by only constraints in the elements of "list".
   3030  *
   3031  * If "map" is the universe, then the convex hull (and therefore
   3032  * any superset of the convexhull) is the universe as well.
   3033  *
   3034  * Otherwise, we collect all the basic maps in the map list and
   3035  * continue with map_unshifted_simple_hull_from_basic_map_list.
   3036  */
   3037 __isl_give isl_basic_map *isl_map_unshifted_simple_hull_from_map_list(
   3038 	__isl_take isl_map *map, __isl_take isl_map_list *list)
   3039 {
   3040 	isl_basic_map_list *bmap_list;
   3041 	int is_universe;
   3042 
   3043 	is_universe = isl_map_plain_is_universe(map);
   3044 	if (is_universe < 0)
   3045 		map = isl_map_free(map);
   3046 	if (is_universe < 0 || is_universe) {
   3047 		isl_map_list_free(list);
   3048 		return isl_map_unshifted_simple_hull(map);
   3049 	}
   3050 
   3051 	bmap_list = collect_basic_maps(list);
   3052 	return map_unshifted_simple_hull_from_basic_map_list(map, bmap_list);
   3053 }
   3054 
   3055 /* Compute a superset of the convex hull of "set" that is described
   3056  * by only constraints in the elements of "list".
   3057  */
   3058 __isl_give isl_basic_set *isl_set_unshifted_simple_hull_from_set_list(
   3059 	__isl_take isl_set *set, __isl_take isl_set_list *list)
   3060 {
   3061 	return isl_map_unshifted_simple_hull_from_map_list(set, list);
   3062 }
   3063 
   3064 /* Given a set "set", return parametric bounds on the dimension "dim".
   3065  */
   3066 static __isl_give isl_basic_set *set_bounds(__isl_keep isl_set *set, int dim)
   3067 {
   3068 	isl_size set_dim = isl_set_dim(set, isl_dim_set);
   3069 	if (set_dim < 0)
   3070 		return NULL;
   3071 	set = isl_set_copy(set);
   3072 	set = isl_set_eliminate_dims(set, dim + 1, set_dim - (dim + 1));
   3073 	set = isl_set_eliminate_dims(set, 0, dim);
   3074 	return isl_set_convex_hull(set);
   3075 }
   3076 
   3077 /* Computes a "simple hull" and then check if each dimension in the
   3078  * resulting hull is bounded by a symbolic constant.  If not, the
   3079  * hull is intersected with the corresponding bounds on the whole set.
   3080  */
   3081 __isl_give isl_basic_set *isl_set_bounded_simple_hull(__isl_take isl_set *set)
   3082 {
   3083 	int i, j;
   3084 	struct isl_basic_set *hull;
   3085 	isl_size nparam, dim, total;
   3086 	unsigned left;
   3087 	int removed_divs = 0;
   3088 
   3089 	hull = isl_set_simple_hull(isl_set_copy(set));
   3090 	nparam = isl_basic_set_dim(hull, isl_dim_param);
   3091 	dim = isl_basic_set_dim(hull, isl_dim_set);
   3092 	total = isl_basic_set_dim(hull, isl_dim_all);
   3093 	if (nparam < 0 || dim < 0 || total < 0)
   3094 		goto error;
   3095 
   3096 	for (i = 0; i < dim; ++i) {
   3097 		int lower = 0, upper = 0;
   3098 		struct isl_basic_set *bounds;
   3099 
   3100 		left = total - nparam - i - 1;
   3101 		for (j = 0; j < hull->n_eq; ++j) {
   3102 			if (isl_int_is_zero(hull->eq[j][1 + nparam + i]))
   3103 				continue;
   3104 			if (isl_seq_first_non_zero(hull->eq[j]+1+nparam+i+1,
   3105 						    left) == -1)
   3106 				break;
   3107 		}
   3108 		if (j < hull->n_eq)
   3109 			continue;
   3110 
   3111 		for (j = 0; j < hull->n_ineq; ++j) {
   3112 			if (isl_int_is_zero(hull->ineq[j][1 + nparam + i]))
   3113 				continue;
   3114 			if (isl_seq_first_non_zero(hull->ineq[j]+1+nparam+i+1,
   3115 						    left) != -1 ||
   3116 			    isl_seq_first_non_zero(hull->ineq[j]+1+nparam,
   3117 						    i) != -1)
   3118 				continue;
   3119 			if (isl_int_is_pos(hull->ineq[j][1 + nparam + i]))
   3120 				lower = 1;
   3121 			else
   3122 				upper = 1;
   3123 			if (lower && upper)
   3124 				break;
   3125 		}
   3126 
   3127 		if (lower && upper)
   3128 			continue;
   3129 
   3130 		if (!removed_divs) {
   3131 			set = isl_set_remove_divs(set);
   3132 			if (!set)
   3133 				goto error;
   3134 			removed_divs = 1;
   3135 		}
   3136 		bounds = set_bounds(set, i);
   3137 		hull = isl_basic_set_intersect(hull, bounds);
   3138 		if (!hull)
   3139 			goto error;
   3140 	}
   3141 
   3142 	isl_set_free(set);
   3143 	return hull;
   3144 error:
   3145 	isl_set_free(set);
   3146 	isl_basic_set_free(hull);
   3147 	return NULL;
   3148 }
   3149