/* 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; }
/* Add all constraints of bmap to tab. The equalities of bmap * are added as a pair of inequalities. */ static int tab_add_constraints(struct isl_tab *tab, __isl_keep isl_basic_map *bmap, int *div_map) { int i; unsigned dim; unsigned tab_total; unsigned bmap_total; isl_vec *v; 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); if (isl_tab_extend_cons(tab, 2 * bmap->n_eq + bmap->n_ineq) < 0) return -1; v = isl_vec_alloc(bmap->ctx, 1 + tab_total); if (!v) return -1; for (i = 0; i < bmap->n_eq; ++i) { expand_constraint(v, dim, bmap->eq[i], div_map, bmap->n_div); if (isl_tab_add_ineq(tab, v->el) < 0) goto error; isl_seq_neg(bmap->eq[i], bmap->eq[i], 1 + bmap_total); expand_constraint(v, dim, bmap->eq[i], div_map, bmap->n_div); if (isl_tab_add_ineq(tab, v->el) < 0) goto error; isl_seq_neg(bmap->eq[i], bmap->eq[i], 1 + bmap_total); if (tab->empty) break; } for (i = 0; i < bmap->n_ineq; ++i) { expand_constraint(v, dim, bmap->ineq[i], div_map, bmap->n_div); if (isl_tab_add_ineq(tab, v->el) < 0) goto error; if (tab->empty) break; } isl_vec_free(v); return 0; error: isl_vec_free(v); return -1; }
/* Return 1 if "bmap" contains the point "point". * "bmap" is assumed to have known divs. * The point is first extended with the divs and then passed * to basic_map_contains. */ int isl_basic_map_contains_point(__isl_keep isl_basic_map *bmap, __isl_keep isl_point *point) { int i; struct isl_vec *vec; unsigned dim; int contains; if (!bmap || !point) return -1; isl_assert(bmap->ctx, isl_dim_equal(bmap->dim, point->dim), return -1); if (bmap->n_div == 0) return isl_basic_map_contains(bmap, point->vec); dim = isl_basic_map_total_dim(bmap) - bmap->n_div; vec = isl_vec_alloc(bmap->ctx, 1 + dim + bmap->n_div); if (!vec) return -1; isl_seq_cpy(vec->el, point->vec->el, point->vec->size); for (i = 0; i < bmap->n_div; ++i) { isl_seq_inner_product(bmap->div[i] + 1, vec->el, 1 + dim + i, &vec->el[1+dim+i]); isl_int_fdiv_q(vec->el[1+dim+i], vec->el[1+dim+i], bmap->div[i][0]); } contains = isl_basic_map_contains(bmap, vec); isl_vec_free(vec); return contains; }
static int tab_add_divs(struct isl_tab *tab, __isl_keep isl_basic_map *bmap, int **div_map) { int i, j; struct isl_vec *vec; unsigned total; unsigned dim; if (!bmap) return -1; if (!bmap->n_div) return 0; if (!*div_map) *div_map = isl_alloc_array(bmap->ctx, int, bmap->n_div); if (!*div_map) return -1; total = isl_basic_map_total_dim(tab->bmap); dim = total - tab->bmap->n_div; vec = isl_vec_alloc(bmap->ctx, 2 + total + bmap->n_div); if (!vec) return -1; for (i = 0; i < bmap->n_div; ++i) { isl_seq_cpy(vec->el, bmap->div[i], 2 + dim); isl_seq_clr(vec->el + 2 + dim, tab->bmap->n_div); for (j = 0; j < i; ++j) isl_int_set(vec->el[2 + dim + (*div_map)[j]], bmap->div[i][2 + dim + j]); for (j = 0; j < tab->bmap->n_div; ++j) if (isl_seq_eq(tab->bmap->div[j], vec->el, 2 + dim + tab->bmap->n_div)) break; (*div_map)[i] = j; if (j == tab->bmap->n_div) { vec->size = 2 + dim + tab->bmap->n_div; if (isl_tab_add_div(tab, vec) < 0) goto error; } } isl_vec_free(vec); return 0; error: isl_vec_free(vec); return -1; }
enum isl_lp_result isl_pip_solve_lp(struct isl_basic_map *bmap, int maximize, isl_int *f, isl_int denom, isl_int *opt, isl_int *opt_denom, struct isl_vec **vec) { enum isl_lp_result res = isl_lp_ok; PipMatrix *domain = NULL; PipOptions *options; PipQuast *sol; unsigned total; total = isl_basic_map_total_dim(bmap); domain = isl_basic_map_to_pip(bmap, 0, 1, 0); if (!domain) goto error; entier_set_si(domain->p[0][1], -1); isl_int_set(domain->p[0][domain->NbColumns - 1], f[0]); isl_seq_cpy_to_pip(domain->p[0]+2, f+1, total); options = pip_options_init(); if (!options) goto error; options->Urs_unknowns = -1; options->Maximize = maximize; options->Nq = 0; sol = pip_solve(domain, NULL, -1, options); pip_options_free(options); if (!sol) goto error; if (vec) { isl_ctx *ctx = isl_basic_map_get_ctx(bmap); *vec = isl_vec_alloc(ctx, 1 + total); } if (vec && !*vec) res = isl_lp_error; else if (!sol->list) res = isl_lp_empty; else if (entier_zero_p(sol->list->vector->the_deno[0])) res = isl_lp_unbounded; else copy_solution(*vec, maximize, opt, opt_denom, sol); pip_matrix_free(domain); pip_quast_free(sol); return res; error: if (domain) pip_matrix_free(domain); return isl_lp_error; }