/* Check whether the polynomial "poly" has sign "sign" over "bset", * i.e., if sign == 1, check that the lower bound on the polynomial * is non-negative and if sign == -1, check that the upper bound on * the polynomial is non-positive. */ static int has_sign(__isl_keep isl_basic_set *bset, __isl_keep isl_qpolynomial *poly, int sign, int *signs) { struct range_data data_m; unsigned nparam; isl_space *dim; isl_val *opt; int r; enum isl_fold type; nparam = isl_basic_set_dim(bset, isl_dim_param); bset = isl_basic_set_copy(bset); poly = isl_qpolynomial_copy(poly); bset = isl_basic_set_move_dims(bset, isl_dim_set, 0, isl_dim_param, 0, nparam); poly = isl_qpolynomial_move_dims(poly, isl_dim_in, 0, isl_dim_param, 0, nparam); dim = isl_qpolynomial_get_space(poly); dim = isl_space_params(dim); dim = isl_space_from_domain(dim); dim = isl_space_add_dims(dim, isl_dim_out, 1); data_m.test_monotonicity = 0; data_m.signs = signs; data_m.sign = -sign; type = data_m.sign < 0 ? isl_fold_min : isl_fold_max; data_m.pwf = isl_pw_qpolynomial_fold_zero(dim, type); data_m.tight = 0; data_m.pwf_tight = NULL; if (propagate_on_domain(bset, poly, &data_m) < 0) goto error; if (sign > 0) opt = isl_pw_qpolynomial_fold_min(data_m.pwf); else opt = isl_pw_qpolynomial_fold_max(data_m.pwf); if (!opt) r = -1; else if (isl_val_is_nan(opt) || isl_val_is_infty(opt) || isl_val_is_neginfty(opt)) r = 0; else r = sign * isl_val_sgn(opt) >= 0; isl_val_free(opt); return r; error: isl_pw_qpolynomial_fold_free(data_m.pwf); return -1; }
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); }
enum order_sign isl_polyhedron_affine_sign(Polyhedron *D, Matrix *T, struct barvinok_options *options) { int i; isl_ctx *ctx = isl_ctx_alloc(); isl_space *dim; isl_local_space *ls; isl_aff *aff; isl_basic_set *bset; isl_val *min, *max = NULL; isl_val *v; enum order_sign sign = order_undefined; assert(D->Dimension == T->NbColumns - 1); dim = isl_space_set_alloc(ctx, 0, D->Dimension); ls = isl_local_space_from_space(isl_space_copy(dim)); bset = isl_basic_set_new_from_polylib(D, dim); aff = isl_aff_zero_on_domain(ls); for (i = 0; i < D->Dimension; ++i) { v = isl_val_int_from_gmp(ctx, T->p[0][i]); aff = isl_aff_set_coefficient_val(aff, isl_dim_in, i, v); } v = isl_val_int_from_gmp(ctx, T->p[0][D->Dimension]); aff = isl_aff_set_constant_val(aff, v); v = isl_val_int_from_gmp(ctx, T->p[1][D->Dimension]); aff = isl_aff_scale_down_val(aff, v); min = isl_basic_set_min_lp_val(bset, aff); min = isl_val_ceil(min); assert(min); if (isl_val_is_nan(min)) sign = order_undefined; else if (isl_val_is_pos(min)) sign = order_gt; else { max = isl_basic_set_max_lp_val(bset, aff); max = isl_val_floor(max); assert(max); if (isl_val_is_neg(max)) sign = order_lt; else if (isl_val_is_zero(min) && isl_val_is_zero(max)) sign = order_eq; else if (isl_val_is_zero(min)) sign = order_ge; else if (isl_val_is_zero(max)) sign = order_le; else sign = order_unknown; } isl_basic_set_free(bset); isl_aff_free(aff); isl_val_free(min); isl_val_free(max); isl_ctx_free(ctx); return sign; }