/* Add a specific constraint of bmap (or its opposite) to tab.
 * The position of the constraint is specified by "c", where
 * the equalities of bmap are counted twice, once for the inequality
 * that is equal to the equality, and once for its negation.
 *
 * Each of these constraints has been added to "tab" before by
 * tab_add_constraints (and later removed again), so there should
 * already be a row available for the constraint.
 */
static int tab_add_constraint(struct isl_tab *tab,
	__isl_keep isl_basic_map *bmap, int *div_map, int c, int oppose)
{
	unsigned dim;
	unsigned tab_total;
	unsigned bmap_total;
	isl_vec *v;
	int r;

	if (!tab || !bmap)
		return -1;

	tab_total = isl_basic_map_total_dim(tab->bmap);
	bmap_total = isl_basic_map_total_dim(bmap);
	dim = isl_space_dim(tab->bmap->dim, isl_dim_all);

	v = isl_vec_alloc(bmap->ctx, 1 + tab_total);
	if (!v)
		return -1;

	if (c < 2 * bmap->n_eq) {
		if ((c % 2) != oppose)
			isl_seq_neg(bmap->eq[c/2], bmap->eq[c/2],
					1 + bmap_total);
		if (oppose)
			isl_int_sub_ui(bmap->eq[c/2][0], bmap->eq[c/2][0], 1);
		expand_constraint(v, dim, bmap->eq[c/2], div_map, bmap->n_div);
		r = isl_tab_add_ineq(tab, v->el);
		if (oppose)
			isl_int_add_ui(bmap->eq[c/2][0], bmap->eq[c/2][0], 1);
		if ((c % 2) != oppose)
			isl_seq_neg(bmap->eq[c/2], bmap->eq[c/2],
					1 + bmap_total);
	} else {
		c -= 2 * bmap->n_eq;
		if (oppose) {
			isl_seq_neg(bmap->ineq[c], bmap->ineq[c],
					1 + bmap_total);
			isl_int_sub_ui(bmap->ineq[c][0], bmap->ineq[c][0], 1);
		}
		expand_constraint(v, dim, bmap->ineq[c], div_map, bmap->n_div);
		r = isl_tab_add_ineq(tab, v->el);
		if (oppose) {
			isl_int_add_ui(bmap->ineq[c][0], bmap->ineq[c][0], 1);
			isl_seq_neg(bmap->ineq[c], bmap->ineq[c],
					1 + bmap_total);
		}
	}

	isl_vec_free(v);
	return r;
}
Example #2
0
/* Find an integer point in the set represented by "tab"
 * that lies outside of the equality "eq" e(x) = 0.
 * If "up" is true, look for a point satisfying e(x) - 1 >= 0.
 * Otherwise, look for a point satisfying -e(x) - 1 >= 0 (i.e., e(x) <= -1).
 * The point, if found, is returned.
 * If no point can be found, a zero-length vector is returned.
 *
 * Before solving an ILP problem, we first check if simply
 * adding the normal of the constraint to one of the known
 * integer points in the basic set represented by "tab"
 * yields another point inside the basic set.
 *
 * The caller of this function ensures that the tableau is bounded or
 * that tab->basis and tab->n_unbounded have been set appropriately.
 */
static struct isl_vec *outside_point(struct isl_tab *tab, isl_int *eq, int up)
{
	struct isl_ctx *ctx;
	struct isl_vec *sample = NULL;
	struct isl_tab_undo *snap;
	unsigned dim;

	if (!tab)
		return NULL;
	ctx = tab->mat->ctx;

	dim = tab->n_var;
	sample = isl_vec_alloc(ctx, 1 + dim);
	if (!sample)
		return NULL;
	isl_int_set_si(sample->el[0], 1);
	isl_seq_combine(sample->el + 1,
		ctx->one, tab->bmap->sample->el + 1,
		up ? ctx->one : ctx->negone, eq + 1, dim);
	if (isl_basic_map_contains(tab->bmap, sample))
		return sample;
	isl_vec_free(sample);
	sample = NULL;

	snap = isl_tab_snap(tab);

	if (!up)
		isl_seq_neg(eq, eq, 1 + dim);
	isl_int_sub_ui(eq[0], eq[0], 1);

	if (isl_tab_extend_cons(tab, 1) < 0)
		goto error;
	if (isl_tab_add_ineq(tab, eq) < 0)
		goto error;

	sample = isl_tab_sample(tab);

	isl_int_add_ui(eq[0], eq[0], 1);
	if (!up)
		isl_seq_neg(eq, eq, 1 + dim);

	if (sample && isl_tab_rollback(tab, snap) < 0)
		goto error;

	return sample;
error:
	isl_vec_free(sample);
	return NULL;
}
Example #3
0
__isl_give isl_point *isl_point_sub_ui(__isl_take isl_point *pnt,
	enum isl_dim_type type, int pos, unsigned val)
{
	if (!pnt || isl_point_is_void(pnt))
		return pnt;

	pnt = isl_point_cow(pnt);
	if (!pnt)
		return NULL;
	pnt->vec = isl_vec_cow(pnt->vec);
	if (!pnt->vec)
		goto error;

	if (type == isl_dim_set)
		pos += isl_dim_size(pnt->dim, isl_dim_param);

	isl_int_sub_ui(pnt->vec->el[1 + pos], pnt->vec->el[1 + pos], val);

	return pnt;
error:
	isl_point_free(pnt);
	return NULL;
}