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; }
/* Apply the morphism to the basic set. * We basically just compute the preimage of "bset" under the inverse mapping * in morph, add in stride constraints and intersect with the range * of the morphism. */ __isl_give isl_basic_set *isl_morph_basic_set(__isl_take isl_morph *morph, __isl_take isl_basic_set *bset) { isl_basic_set *res = NULL; isl_mat *mat = NULL; int i, k; int max_stride; if (!morph || !bset) goto error; isl_assert(bset->ctx, isl_space_is_equal(bset->dim, morph->dom->dim), goto error); max_stride = morph->inv->n_row - 1; if (isl_int_is_one(morph->inv->row[0][0])) max_stride = 0; res = isl_basic_set_alloc_space(isl_space_copy(morph->ran->dim), bset->n_div + max_stride, bset->n_eq + max_stride, bset->n_ineq); for (i = 0; i < bset->n_div; ++i) if (isl_basic_set_alloc_div(res) < 0) goto error; mat = isl_mat_sub_alloc6(bset->ctx, bset->eq, 0, bset->n_eq, 0, morph->inv->n_row); mat = isl_mat_product(mat, isl_mat_copy(morph->inv)); if (!mat) goto error; for (i = 0; i < bset->n_eq; ++i) { k = isl_basic_set_alloc_equality(res); if (k < 0) goto error; isl_seq_cpy(res->eq[k], mat->row[i], mat->n_col); isl_seq_scale(res->eq[k] + mat->n_col, bset->eq[i] + mat->n_col, morph->inv->row[0][0], bset->n_div); } isl_mat_free(mat); mat = isl_mat_sub_alloc6(bset->ctx, bset->ineq, 0, bset->n_ineq, 0, morph->inv->n_row); mat = isl_mat_product(mat, isl_mat_copy(morph->inv)); if (!mat) goto error; for (i = 0; i < bset->n_ineq; ++i) { k = isl_basic_set_alloc_inequality(res); if (k < 0) goto error; isl_seq_cpy(res->ineq[k], mat->row[i], mat->n_col); isl_seq_scale(res->ineq[k] + mat->n_col, bset->ineq[i] + mat->n_col, morph->inv->row[0][0], bset->n_div); } isl_mat_free(mat); mat = isl_mat_sub_alloc6(bset->ctx, bset->div, 0, bset->n_div, 1, morph->inv->n_row); mat = isl_mat_product(mat, isl_mat_copy(morph->inv)); if (!mat) goto error; for (i = 0; i < bset->n_div; ++i) { isl_int_mul(res->div[i][0], morph->inv->row[0][0], bset->div[i][0]); isl_seq_cpy(res->div[i] + 1, mat->row[i], mat->n_col); isl_seq_scale(res->div[i] + 1 + mat->n_col, bset->div[i] + 1 + mat->n_col, morph->inv->row[0][0], bset->n_div); } isl_mat_free(mat); res = add_strides(res, morph); if (isl_basic_set_is_rational(bset)) res = isl_basic_set_set_rational(res); res = isl_basic_set_simplify(res); res = isl_basic_set_finalize(res); res = isl_basic_set_intersect(res, isl_basic_set_copy(morph->ran)); isl_morph_free(morph); isl_basic_set_free(bset); return res; error: isl_mat_free(mat); isl_morph_free(morph); isl_basic_set_free(bset); isl_basic_set_free(res); return NULL; }