/* Look for all equalities satisfied by the integer points in bset,
 * which is assumed not to have any explicit equalities.
 *
 * The equalities are obtained by successively looking for
 * a point that is affinely independent of the points found so far.
 * In particular, for each equality satisfied by the points so far,
 * we check if there is any point on a hyperplane parallel to the
 * corresponding hyperplane shifted by at least one (in either direction).
 *
 * Before looking for any outside points, we first compute the recession
 * cone.  The directions of this recession cone will always be part
 * of the affine hull, so there is no need for looking for any points
 * in these directions.
 * In particular, if the recession cone is full-dimensional, then
 * the affine hull is simply the whole universe.
 */
static struct isl_basic_set *uset_affine_hull(struct isl_basic_set *bset)
{
	struct isl_basic_set *cone;

	if (isl_basic_set_plain_is_empty(bset))
		return bset;

	cone = isl_basic_set_recession_cone(isl_basic_set_copy(bset));
	if (!cone)
		goto error;
	if (cone->n_eq == 0) {
		struct isl_basic_set *hull;
		isl_basic_set_free(cone);
		hull = isl_basic_set_universe_like(bset);
		isl_basic_set_free(bset);
		return hull;
	}

	if (cone->n_eq < isl_basic_set_total_dim(cone))
		return affine_hull_with_cone(bset, cone);

	isl_basic_set_free(cone);
	return uset_affine_hull_bounded(bset);
error:
	isl_basic_set_free(bset);
	return NULL;
}
/* Compute the affine hull of "bset", where "cone" is the recession cone
 * of "bset".
 *
 * We first compute a unimodular transformation that puts the unbounded
 * directions in the last dimensions.  In particular, we take a transformation
 * that maps all equalities to equalities (in HNF) on the first dimensions.
 * Let x be the original dimensions and y the transformed, with y_1 bounded
 * and y_2 unbounded.
 *
 *	       [ y_1 ]			[ y_1 ]   [ Q_1 ]
 *	x = U  [ y_2 ]			[ y_2 ] = [ Q_2 ] x
 *
 * Let's call the input basic set S.  We compute S' = preimage(S, U)
 * and drop the final dimensions including any constraints involving them.
 * This results in set S''.
 * Then we compute the affine hull A'' of S''.
 * Let F y_1 >= g be the constraint system of A''.  In the transformed
 * space the y_2 are unbounded, so we can add them back without any constraints,
 * resulting in
 *
 *		        [ y_1 ]
 *		[ F 0 ] [ y_2 ] >= g
 * or
 *		        [ Q_1 ]
 *		[ F 0 ] [ Q_2 ] x >= g
 * or
 *		F Q_1 x >= g
 *
 * The affine hull in the original space is then obtained as
 * A = preimage(A'', Q_1).
 */
static struct isl_basic_set *affine_hull_with_cone(struct isl_basic_set *bset,
	struct isl_basic_set *cone)
{
	unsigned total;
	unsigned cone_dim;
	struct isl_basic_set *hull;
	struct isl_mat *M, *U, *Q;

	if (!bset || !cone)
		goto error;

	total = isl_basic_set_total_dim(cone);
	cone_dim = total - cone->n_eq;

	M = isl_mat_sub_alloc6(bset->ctx, cone->eq, 0, cone->n_eq, 1, total);
	M = isl_mat_left_hermite(M, 0, &U, &Q);
	if (!M)
		goto error;
	isl_mat_free(M);

	U = isl_mat_lin_to_aff(U);
	bset = isl_basic_set_preimage(bset, isl_mat_copy(U));

	bset = isl_basic_set_drop_constraints_involving(bset, total - cone_dim,
							cone_dim);
	bset = isl_basic_set_drop_dims(bset, total - cone_dim, cone_dim);

	Q = isl_mat_lin_to_aff(Q);
	Q = isl_mat_drop_rows(Q, 1 + total - cone_dim, cone_dim);

	if (bset && bset->sample && bset->sample->size == 1 + total)
		bset->sample = isl_mat_vec_product(isl_mat_copy(Q), bset->sample);

	hull = uset_affine_hull_bounded(bset);

	if (!hull)
		isl_mat_free(U);
	else {
		struct isl_vec *sample = isl_vec_copy(hull->sample);
		U = isl_mat_drop_cols(U, 1 + total - cone_dim, cone_dim);
		if (sample && sample->size > 0)
			sample = isl_mat_vec_product(U, sample);
		else
			isl_mat_free(U);
		hull = isl_basic_set_preimage(hull, Q);
		if (hull) {
			isl_vec_free(hull->sample);
			hull->sample = sample;
		} else
			isl_vec_free(sample);
	}

	isl_basic_set_free(cone);

	return hull;
error:
	isl_basic_set_free(bset);
	isl_basic_set_free(cone);
	return NULL;
}
__isl_give isl_morph *isl_morph_alloc(
	__isl_take isl_basic_set *dom, __isl_take isl_basic_set *ran,
	__isl_take isl_mat *map, __isl_take isl_mat *inv)
{
	isl_morph *morph;

	if (!dom || !ran || !map || !inv)
		goto error;

	morph = isl_alloc_type(dom->ctx, struct isl_morph);
	if (!morph)
		goto error;

	morph->ref = 1;
	morph->dom = dom;
	morph->ran = ran;
	morph->map = map;
	morph->inv = inv;

	return morph;
error:
	isl_basic_set_free(dom);
	isl_basic_set_free(ran);
	isl_mat_free(map);
	isl_mat_free(inv);
	return NULL;
}
Exemple #4
0
/* Check if the constraints in "set" imply any stride on set dimension "pos" and
 * store the results in data->stride and data->offset.
 *
 * In particular, compute the affine hull and then check if
 * any of the constraints in the hull impose any stride on the dimension.
 * If no such constraint can be found, then the offset is taken
 * to be the zero expression and the stride is taken to be one.
 */
static void set_detect_stride(__isl_keep isl_set *set, int pos,
	struct isl_detect_stride_data *data)
{
	isl_basic_set *hull;

	hull = isl_set_affine_hull(isl_set_copy(set));

	data->pos = pos;
	data->found = 0;
	data->stride = NULL;
	data->offset = NULL;
	if (isl_basic_set_foreach_constraint(hull, &detect_stride, data) < 0)
		goto error;

	if (!data->found) {
		data->stride = isl_val_one(isl_set_get_ctx(set));
		if (data->want_offset) {
			isl_space *space;
			isl_local_space *ls;

			space = isl_set_get_space(set);
			ls = isl_local_space_from_space(space);
			data->offset = isl_aff_zero_on_domain(ls);
		}
	}
	isl_basic_set_free(hull);
	return;
error:
	isl_basic_set_free(hull);
	data->stride = isl_val_free(data->stride);
	data->offset = isl_aff_free(data->offset);
}
void isl_morph_free(__isl_take isl_morph *morph)
{
	if (!morph)
		return;

	if (--morph->ref > 0)
		return;

	isl_basic_set_free(morph->dom);
	isl_basic_set_free(morph->ran);
	isl_mat_free(morph->map);
	isl_mat_free(morph->inv);
	free(morph);
}
Exemple #6
0
/* Replace graft->enforced by "enforced".
 */
__isl_give isl_ast_graft *isl_ast_graft_set_enforced(
	__isl_take isl_ast_graft *graft, __isl_take isl_basic_set *enforced)
{
	if (!graft || !enforced)
		goto error;

	isl_basic_set_free(graft->enforced);
	graft->enforced = enforced;

	return graft;
error:
	isl_basic_set_free(enforced);
	return isl_ast_graft_free(graft);
}
Exemple #7
0
static __isl_give isl_mat *isl_basic_set_scan_samples(
	__isl_take isl_basic_set *bset)
{
	isl_ctx *ctx;
	isl_size dim;
	struct scan_samples ss;

	ctx = isl_basic_set_get_ctx(bset);
	dim = isl_basic_set_dim(bset, isl_dim_all);
	if (dim < 0)
		goto error;
	ss.callback.add = scan_samples_add_sample;
	ss.samples = isl_mat_alloc(ctx, 0, 1 + dim);
	if (!ss.samples)
		goto error;

	if (isl_basic_set_scan(bset, &ss.callback) < 0) {
		isl_mat_free(ss.samples);
		return NULL;
	}

	return ss.samples;
error:
	isl_basic_set_free(bset);
	return NULL;
}
static isl_stat add_vertex(__isl_take isl_vertex *vertex, void *user)
{
	Param_Vertices ***next_V = (Param_Vertices ***) user;
	Param_Vertices *V;
	Polyhedron *D;
	isl_basic_set *dom;
	isl_multi_aff *expr;
	isl_ctx *ctx;

	ctx = isl_vertex_get_ctx(vertex);

	dom = isl_vertex_get_domain(vertex);
	D = isl_basic_set_to_polylib(dom);
	isl_basic_set_free(dom);

	expr = isl_vertex_get_expr(vertex);

	V = isl_alloc_type(ctx, Param_Vertices);
	V->Vertex = isl_multi_aff_to_polylib(expr);
	V->Domain = Polyhedron2Constraints(D);
	V->Facets = NULL;
	V->next = NULL;

	Polyhedron_Free(D);
	isl_multi_aff_free(expr);

	**next_V = V;
	*next_V = &V->next;

	isl_vertex_free(vertex);

	return isl_stat_ok;
}
Exemple #9
0
static struct isl_vec *interval_sample(struct isl_basic_set *bset)
{
	int i;
	isl_int t;
	struct isl_vec *sample;

	bset = isl_basic_set_simplify(bset);
	if (!bset)
		return NULL;
	if (isl_basic_set_plain_is_empty(bset))
		return empty_sample(bset);
	if (bset->n_eq == 0 && bset->n_ineq == 0)
		return zero_sample(bset);

	sample = isl_vec_alloc(bset->ctx, 2);
	if (!sample)
		goto error;
	if (!bset)
		return NULL;
	isl_int_set_si(sample->block.data[0], 1);

	if (bset->n_eq > 0) {
		isl_assert(bset->ctx, bset->n_eq == 1, goto error);
		isl_assert(bset->ctx, bset->n_ineq == 0, goto error);
		if (isl_int_is_one(bset->eq[0][1]))
			isl_int_neg(sample->el[1], bset->eq[0][0]);
		else {
			isl_assert(bset->ctx, isl_int_is_negone(bset->eq[0][1]),
				   goto error);
			isl_int_set(sample->el[1], bset->eq[0][0]);
		}
		isl_basic_set_free(bset);
		return sample;
	}
static isl_stat add_chamber(__isl_take isl_cell *cell, void *user)
{
	struct bv_add_chamber_data *data = (struct bv_add_chamber_data *)user;
	isl_ctx *ctx;
	isl_basic_set *domain;

	ctx = isl_cell_get_ctx(cell);

	domain = isl_cell_get_domain(cell);

	data->dom = isl_alloc_type(ctx, Param_Domain);
	data->dom->Domain = isl_basic_set_to_polylib(domain);
	data->dom->F = isl_calloc_array(ctx, unsigned, data->vertex_len);
	data->dom->next = NULL;

	isl_basic_set_free(domain);

	*data->next_D = data->dom;
	data->next_D = &data->dom->next;

	isl_cell_foreach_vertex(cell, &add_chamber_vertex, data);

	isl_cell_free(cell);

	return isl_stat_ok;
}
Exemple #11
0
/* Construct a basic set described by the "n" equalities of "bset" starting
 * at "first".
 */
static __isl_give isl_basic_set *copy_equalities(__isl_keep isl_basic_set *bset,
	unsigned first, unsigned n)
{
	int i, k;
	isl_basic_set *eq;
	unsigned total;

	isl_assert(bset->ctx, bset->n_div == 0, return NULL);

	total = isl_basic_set_total_dim(bset);
	eq = isl_basic_set_alloc_space(isl_space_copy(bset->dim), 0, n, 0);
	if (!eq)
		return NULL;
	for (i = 0; i < n; ++i) {
		k = isl_basic_set_alloc_equality(eq);
		if (k < 0)
			goto error;
		isl_seq_cpy(eq->eq[k], bset->eq[first + k], 1 + total);
	}

	return eq;
error:
	isl_basic_set_free(eq);
	return NULL;
}
Exemple #12
0
static isl_stat basic_guarded_poly_bound(__isl_take isl_basic_set *bset,
	void *user)
{
	struct range_data *data = (struct range_data *)user;
	isl_ctx *ctx;
	unsigned nparam = isl_basic_set_dim(bset, isl_dim_param);
	unsigned dim = isl_basic_set_dim(bset, isl_dim_set);
	isl_stat r;

	data->signs = NULL;

	ctx = isl_basic_set_get_ctx(bset);
	data->signs = isl_alloc_array(ctx, int,
					isl_basic_set_dim(bset, isl_dim_all));

	if (isl_basic_set_dims_get_sign(bset, isl_dim_set, 0, dim,
					data->signs + nparam) < 0)
		goto error;
	if (isl_basic_set_dims_get_sign(bset, isl_dim_param, 0, nparam,
					data->signs) < 0)
		goto error;

	r = propagate_on_domain(bset, isl_qpolynomial_copy(data->poly), data);

	free(data->signs);

	return r;
error:
	free(data->signs);
	isl_basic_set_free(bset);
	return isl_stat_error;
}
Exemple #13
0
/* Recursively perform range propagation on the polynomial "poly"
 * defined over the basic set "bset" and collect the results in "data".
 */
static isl_stat propagate_on_domain(__isl_take isl_basic_set *bset,
	__isl_take isl_qpolynomial *poly, struct range_data *data)
{
	isl_ctx *ctx;
	isl_qpolynomial *save_poly = data->poly;
	int save_monotonicity = data->monotonicity;
	unsigned d;

	if (!bset || !poly)
		goto error;

	ctx = isl_basic_set_get_ctx(bset);
	d = isl_basic_set_dim(bset, isl_dim_set);
	isl_assert(ctx, d >= 1, goto error);

	if (isl_qpolynomial_is_cst(poly, NULL, NULL)) {
		bset = isl_basic_set_project_out(bset, isl_dim_set, 0, d);
		poly = isl_qpolynomial_drop_dims(poly, isl_dim_in, 0, d);
		return add_guarded_poly(bset, poly, data);
	}

	if (data->test_monotonicity)
		data->monotonicity = monotonicity(bset, poly, data);
	else
		data->monotonicity = 0;
	if (data->monotonicity < -1)
		goto error;

	data->poly = poly;
	if (isl_basic_set_foreach_bound_pair(bset, isl_dim_set, d - 1,
					    &propagate_on_bound_pair, data) < 0)
		goto error;

	isl_basic_set_free(bset);
	isl_qpolynomial_free(poly);
	data->monotonicity = save_monotonicity;
	data->poly = save_poly;

	return isl_stat_ok;
error:
	isl_basic_set_free(bset);
	isl_qpolynomial_free(poly);
	data->monotonicity = save_monotonicity;
	data->poly = save_poly;
	return isl_stat_error;
}
Exemple #14
0
/// Add an isl basic set to a ScopLib matrix_list
///
/// @param bset The basic set to add
/// @param user The matrix list we should add the basic set to
///
/// XXX: At the moment this function expects just a matrix, as support
/// for matrix lists is currently not available in ScopLib. So union of
/// polyhedron are not yet supported
int ScopLib::domainToMatrix_basic_set(isl_basic_set *bset, void *user) {
  scoplib_matrix_p m = (scoplib_matrix_p) user;
  assert(!m->NbRows && "Union of polyhedron not yet supported");

  isl_basic_set_foreach_constraint(bset, &domainToMatrix_constraint, user);
  isl_basic_set_free(bset);
  return 0;
}
Exemple #15
0
static struct isl_vec *empty_sample(struct isl_basic_set *bset)
{
	struct isl_vec *vec;

	vec = isl_vec_alloc(bset->ctx, 0);
	isl_basic_set_free(bset);
	return vec;
}
struct isl_map *isl_pip_basic_map_lexopt(
		struct isl_basic_map *bmap, struct isl_basic_set *dom,
		struct isl_set **empty, int max)
{
	isl_basic_map_free(bmap);
	isl_basic_set_free(dom);
	return NULL;
}
/* Look for all equalities satisfied by the integer points in bmap
 * that are independent of the equalities already explicitly available
 * in bmap.
 *
 * We first remove all equalities already explicitly available,
 * then look for additional equalities in the reduced space
 * and then transform the result to the original space.
 * The original equalities are _not_ added to this set.  This is
 * the responsibility of the calling function.
 * The resulting basic set has all meaning about the dimensions removed.
 * In particular, dimensions that correspond to existential variables
 * in bmap and that are found to be fixed are not removed.
 */
static struct isl_basic_set *equalities_in_underlying_set(
						struct isl_basic_map *bmap)
{
	struct isl_mat *T1 = NULL;
	struct isl_mat *T2 = NULL;
	struct isl_basic_set *bset = NULL;
	struct isl_basic_set *hull = NULL;

	bset = isl_basic_map_underlying_set(bmap);
	if (!bset)
		return NULL;
	if (bset->n_eq)
		bset = isl_basic_set_remove_equalities(bset, &T1, &T2);
	if (!bset)
		goto error;

	hull = uset_affine_hull(bset);
	if (!T2)
		return hull;

	if (!hull) {
		isl_mat_free(T1);
		isl_mat_free(T2);
	} else {
		struct isl_vec *sample = isl_vec_copy(hull->sample);
		if (sample && sample->size > 0)
			sample = isl_mat_vec_product(T1, sample);
		else
			isl_mat_free(T1);
		hull = isl_basic_set_preimage(hull, T2);
		if (hull) {
			isl_vec_free(hull->sample);
			hull->sample = sample;
		} else
			isl_vec_free(sample);
	}

	return hull;
error:
	isl_mat_free(T2);
	isl_basic_set_free(bset);
	isl_basic_set_free(hull);
	return NULL;
}
/* Detect and make explicit all equalities satisfied by the (integer)
 * points in bmap.
 */
struct isl_basic_map *isl_basic_map_detect_equalities(
						struct isl_basic_map *bmap)
{
	int i, j;
	struct isl_basic_set *hull = NULL;

	if (!bmap)
		return NULL;
	if (bmap->n_ineq == 0)
		return bmap;
	if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
		return bmap;
	if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_ALL_EQUALITIES))
		return bmap;
	if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL))
		return isl_basic_map_implicit_equalities(bmap);

	hull = equalities_in_underlying_set(isl_basic_map_copy(bmap));
	if (!hull)
		goto error;
	if (ISL_F_ISSET(hull, ISL_BASIC_SET_EMPTY)) {
		isl_basic_set_free(hull);
		return isl_basic_map_set_to_empty(bmap);
	}
	bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim), 0,
					hull->n_eq, 0);
	for (i = 0; i < hull->n_eq; ++i) {
		j = isl_basic_map_alloc_equality(bmap);
		if (j < 0)
			goto error;
		isl_seq_cpy(bmap->eq[j], hull->eq[i],
				1 + isl_basic_set_total_dim(hull));
	}
	isl_vec_free(bmap->sample);
	bmap->sample = isl_vec_copy(hull->sample);
	isl_basic_set_free(hull);
	ISL_F_SET(bmap, ISL_BASIC_MAP_NO_IMPLICIT | ISL_BASIC_MAP_ALL_EQUALITIES);
	bmap = isl_basic_map_simplify(bmap);
	return isl_basic_map_finalize(bmap);
error:
	isl_basic_set_free(hull);
	isl_basic_map_free(bmap);
	return NULL;
}
enum lp_result isl_constraints_opt(Matrix *C, Value *obj, Value denom,
				    enum lp_dir dir, Value *opt)
{
	int i;
	isl_ctx *ctx = isl_ctx_alloc();
	isl_space *dim;
	isl_local_space *ls;
	isl_mat *eq, *ineq;
	isl_basic_set *bset;
	isl_aff *aff;
	isl_val *v;
	enum isl_lp_result res;
	int max = dir == lp_max;

	eq = extract_equalities(ctx, C);
	ineq = extract_inequalities(ctx, C);
	dim = isl_space_set_alloc(ctx, 0, C->NbColumns - 2);
	ls = isl_local_space_from_space(isl_space_copy(dim));
	bset = isl_basic_set_from_constraint_matrices(dim, eq, ineq,
			isl_dim_set, isl_dim_div, isl_dim_param, isl_dim_cst);
	aff = isl_aff_zero_on_domain(ls);
	for (i = 0; i < C->NbColumns - 2; ++i) {
		v = isl_val_int_from_gmp(ctx, obj[i]);
		aff = isl_aff_set_coefficient_val(aff, isl_dim_in, i, v);
	}
	v = isl_val_int_from_gmp(ctx, obj[C->NbColumns - 2]);
	aff = isl_aff_set_constant_val(aff, v);
	v = isl_val_int_from_gmp(ctx, denom);
	aff = isl_aff_scale_down_val(aff, v);

	if (max)
		v = isl_val_floor(isl_basic_set_max_lp_val(bset, aff));
	else
		v = isl_val_ceil(isl_basic_set_min_lp_val(bset, aff));
	if (!v)
		res = isl_lp_error;
	else if (isl_val_is_nan(v))
		res = isl_lp_empty;
	else if (!isl_val_is_rat(v))
		res = isl_lp_unbounded;
	else {
		res = isl_lp_ok;
		isl_val_get_num_gmp(v, *opt);
	}

	isl_val_free(v);
	isl_aff_free(aff);
	isl_basic_set_free(bset);
	isl_ctx_free(ctx);

	return isl_lp_result2lp_result(res);
}
/* The implementation is based on Section 5.2 of Michael Karr,
 * "Affine Relationships Among Variables of a Program",
 * except that the echelon form we use starts from the last column
 * and that we are dealing with integer coefficients.
 */
static struct isl_basic_set *affine_hull(
	struct isl_basic_set *bset1, struct isl_basic_set *bset2)
{
	unsigned total;
	int col;
	int row;

	if (!bset1 || !bset2)
		goto error;

	total = 1 + isl_basic_set_n_dim(bset1);

	row = 0;
	for (col = total-1; col >= 0; --col) {
		int is_zero1 = row >= bset1->n_eq ||
			isl_int_is_zero(bset1->eq[row][col]);
		int is_zero2 = row >= bset2->n_eq ||
			isl_int_is_zero(bset2->eq[row][col]);
		if (!is_zero1 && !is_zero2) {
			set_common_multiple(bset1, bset2, row, col);
			++row;
		} else if (!is_zero1 && is_zero2) {
			construct_column(bset1, bset2, row, col);
		} else if (is_zero1 && !is_zero2) {
			construct_column(bset2, bset1, row, col);
		} else {
			if (transform_column(bset1, bset2, row, col))
				--row;
		}
	}
	isl_assert(bset1->ctx, row == bset1->n_eq, goto error);
	isl_basic_set_free(bset2);
	bset1 = isl_basic_set_normalize_constraints(bset1);
	return bset1;
error:
	isl_basic_set_free(bset1);
	isl_basic_set_free(bset2);
	return NULL;
}
/**
 * Check whether there is any need for the constraint "upper" on
 * "level" to get reduced.
 * In case of the isl backend, there should be no need to do so
 * if the level corresponds to an existentially quantified variable.
 * Moreover, the way reduction is performed does not work for such
 * variables since its position might chance during the construction
 * of a set for reduction.
 */
int cloog_constraint_needs_reduction(CloogConstraint *upper, int level)
{
	isl_basic_set *bset;
	isl_constraint *c;
	struct cloog_isl_dim dim;

	c = cloog_constraint_to_isl(upper);
	bset = isl_basic_set_from_constraint(isl_constraint_copy(c));
	dim = basic_set_cloog_dim_to_isl_dim(bset, level - 1);
	isl_basic_set_free(bset);

	return dim.type == isl_dim_set;
}
int main(int argc, char **argv)
{
	struct isl_ctx *ctx = isl_ctx_alloc();
	struct isl_basic_set *bset;

	bset = isl_basic_set_read_from_file(ctx, stdin);
	bset = isl_basic_set_detect_equalities(bset);
	isl_basic_set_print(bset, stdout, 0, "", "", ISL_FORMAT_POLYLIB);
	isl_basic_set_free(bset);
	isl_ctx_free(ctx);

	return 0;
}
void isl_bset_list_free(isl_bset_list *list)
{
	isl_bset_list *node = list;
	isl_bset_list *next_node;

	while (node != NULL)
	{
		isl_basic_set_free(node->bset);
		next_node = node->next;
		free(node);
		node = next_node;
	}
}
/* Extend an initial (under-)approximation of the affine hull of basic
 * set represented by the tableau "tab"
 * by looking for points that do not satisfy one of the equalities
 * in the current approximation and adding them to that approximation
 * until no such points can be found any more.
 *
 * The caller of this function ensures that "tab" is bounded or
 * that tab->basis and tab->n_unbounded have been set appropriately.
 */
static struct isl_basic_set *extend_affine_hull(struct isl_tab *tab,
	struct isl_basic_set *hull)
{
	int i, j;
	unsigned dim;

	if (!tab || !hull)
		goto error;

	dim = tab->n_var;

	if (isl_tab_extend_cons(tab, 2 * dim + 1) < 0)
		goto error;

	for (i = 0; i < dim; ++i) {
		struct isl_vec *sample;
		struct isl_basic_set *point;
		for (j = 0; j < hull->n_eq; ++j) {
			sample = outside_point(tab, hull->eq[j], 1);
			if (!sample)
				goto error;
			if (sample->size > 0)
				break;
			isl_vec_free(sample);
			sample = outside_point(tab, hull->eq[j], 0);
			if (!sample)
				goto error;
			if (sample->size > 0)
				break;
			isl_vec_free(sample);

			if (isl_tab_add_eq(tab, hull->eq[j]) < 0)
				goto error;
		}
		if (j == hull->n_eq)
			break;
		if (tab->samples)
			tab = isl_tab_add_sample(tab, isl_vec_copy(sample));
		if (!tab)
			goto error;
		point = isl_basic_set_from_vec(sample);
		hull = affine_hull(hull, point);
		if (!hull)
			return NULL;
	}

	return hull;
error:
	isl_basic_set_free(hull);
	return NULL;
}
Exemple #25
0
/* Construct a zero sample of the same dimension as bset.
 * As a special case, if bset is zero-dimensional, this
 * function creates a zero-dimensional sample point.
 */
static struct isl_vec *zero_sample(struct isl_basic_set *bset)
{
	unsigned dim;
	struct isl_vec *sample;

	dim = isl_basic_set_total_dim(bset);
	sample = isl_vec_alloc(bset->ctx, 1 + dim);
	if (sample) {
		isl_int_set_si(sample->el[0], 1);
		isl_seq_clr(sample->el + 1, dim);
	}
	isl_basic_set_free(bset);
	return sample;
}
int main(int argc, char **argv)
{
	struct isl_ctx *ctx = isl_ctx_alloc();
	struct isl_basic_set *bset;
	struct isl_vec *obj;
	struct isl_vec *sol;
	isl_int opt;
	unsigned dim;
	enum isl_lp_result res;
	isl_printer *p;

	isl_int_init(opt);
	bset = isl_basic_set_read_from_file(ctx, stdin);
	assert(bset);
	obj = isl_vec_read_from_file(ctx, stdin);
	assert(obj);
	dim = isl_basic_set_total_dim(bset);
	assert(obj->size >= dim && obj->size <= dim + 1);
	if (obj->size != dim + 1)
		obj = isl_vec_lin_to_aff(obj);
	else
		obj = vec_ror(obj);
	res = isl_basic_set_solve_ilp(bset, 0, obj->el, &opt, &sol);
	switch (res) {
	case isl_lp_error:
		fprintf(stderr, "error\n");
		return -1;
	case isl_lp_empty:
		fprintf(stdout, "empty\n");
		break;
	case isl_lp_unbounded:
		fprintf(stdout, "unbounded\n");
		break;
	case isl_lp_ok:
		p = isl_printer_to_file(ctx, stdout);
		p = isl_printer_print_vec(p, sol);
		p = isl_printer_end_line(p);
		p = isl_printer_print_isl_int(p, opt);
		p = isl_printer_end_line(p);
		isl_printer_free(p);
	}
	isl_basic_set_free(bset);
	isl_vec_free(obj);
	isl_vec_free(sol);
	isl_ctx_free(ctx);
	isl_int_clear(opt);

	return 0;
}
static int scan_0D(struct isl_basic_set *bset,
	struct isl_scan_callback *callback)
{
	struct isl_vec *sample;

	sample = isl_vec_alloc(bset->ctx, 1);
	isl_basic_set_free(bset);

	if (!sample)
		return -1;

	isl_int_set_si(sample->el[0], 1);

	return callback->add(callback, sample);
}
Exemple #28
0
struct isl_basic_set *isl_basic_set_remove_equalities(
	struct isl_basic_set *bset, struct isl_mat **T, struct isl_mat **T2)
{
	if (T)
		*T = NULL;
	if (T2)
		*T2 = NULL;
	if (!bset)
		return NULL;
	isl_assert(bset->ctx, isl_basic_set_n_param(bset) == 0, goto error);
	bset = isl_basic_set_gauss(bset, NULL);
	if (ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY))
		return bset;
	bset = compress_variables(bset, T, T2);
	return bset;
error:
	isl_basic_set_free(bset);
	*T = NULL;
	return NULL;
}
Param_Polyhedron *ISL_P2PP(Polyhedron *P, Polyhedron *C,
			  struct barvinok_options *options)
{
	int i, j;
	isl_ctx *ctx = isl_ctx_alloc();
	isl_space *dim;
	isl_basic_set *bset, *context;
	isl_vertices *vertices;
	unsigned nparam = C->Dimension;
	unsigned nvar = P->Dimension - nparam;
	Param_Polyhedron *PP = isl_calloc_type(ctx, Param_Polyhedron);
	Param_Vertices **next_V;
	struct bv_add_chamber_data data;

	dim = isl_space_set_alloc(ctx, nparam, nvar);
	bset = isl_basic_set_new_from_polylib(P, dim);
	dim = isl_space_set_alloc(ctx, nparam, 0);
	context = isl_basic_set_new_from_polylib(C, dim);

	bset = isl_basic_set_intersect(bset, context);

	vertices = isl_basic_set_compute_vertices(bset);
	isl_basic_set_free(bset);

	PP->Rays = NULL;
	PP->nbV = isl_vertices_get_n_vertices(vertices);
	PP->Constraints = Polyhedron2Constraints(P);

	next_V = &PP->V;
	isl_vertices_foreach_vertex(vertices, &add_vertex, &next_V);

	data.next_D = &PP->D;
	data.vertex_len = (PP->nbV + INT_BITS - 1)/INT_BITS;
	isl_vertices_foreach_cell(vertices, &add_chamber, &data);

	isl_vertices_free(vertices);

	isl_ctx_free(ctx);

	return PP;
}
struct isl_basic_set *isl_basic_set_recession_cone(struct isl_basic_set *bset)
{
	int i;

	bset = isl_basic_set_cow(bset);
	if (!bset)
		return NULL;
	isl_assert(bset->ctx, bset->n_div == 0, goto error);

	for (i = 0; i < bset->n_eq; ++i)
		isl_int_set_si(bset->eq[i][0], 0);

	for (i = 0; i < bset->n_ineq; ++i)
		isl_int_set_si(bset->ineq[i][0], 0);

	ISL_F_CLR(bset, ISL_BASIC_SET_NO_IMPLICIT);
	return isl_basic_set_implicit_equalities(bset);
error:
	isl_basic_set_free(bset);
	return NULL;
}