polysign_isl.c: extract_inequalities: use isl_val
[barvinok.git] / polysign_isl.c
blobb9c6667d2f9aee2274a2eb88389ee286a2a83aa5
1 #include <assert.h>
2 #include <isl/val_gmp.h>
3 #include <isl/lp.h>
4 #include <isl_set_polylib.h>
5 #include "polysign.h"
7 static void values2isl(Value *src, isl_int *dst, int len)
9 int i;
11 for (i = 0; i < len; ++i)
12 isl_int_set_gmp(dst[i], src[i]);
15 static __isl_give isl_mat *extract_equalities(isl_ctx *ctx, Matrix *M)
17 int i, j;
18 int n;
19 isl_val *v;
20 isl_mat *eq;
22 n = 0;
23 for (i = 0; i < M->NbRows; ++i)
24 if (value_zero_p(M->p[i][0]))
25 ++n;
27 eq = isl_mat_alloc(ctx, n, M->NbColumns - 1);
28 for (i = 0; i < M->NbRows; ++i) {
29 if (!value_zero_p(M->p[i][0]))
30 continue;
31 for (j = 0; j < M->NbColumns - 1; ++j) {
32 v = isl_val_int_from_gmp(ctx, M->p[i][1 + j]);
33 eq = isl_mat_set_element_val(eq, i, j, v);
37 return eq;
40 static __isl_give isl_mat *extract_inequalities(isl_ctx *ctx, Matrix *M)
42 int i, j;
43 int n;
44 isl_val *v;
45 isl_mat *ineq;
47 n = 0;
48 for (i = 0; i < M->NbRows; ++i)
49 if (!value_zero_p(M->p[i][0]))
50 ++n;
52 ineq = isl_mat_alloc(ctx, n, M->NbColumns - 1);
53 for (i = 0; i < M->NbRows; ++i) {
54 if (value_zero_p(M->p[i][0]))
55 continue;
56 for (j = 0; j < M->NbColumns - 1; ++j) {
57 v = isl_val_int_from_gmp(ctx, M->p[i][1 + j]);
58 ineq = isl_mat_set_element_val(ineq, i, j, v);
62 return ineq;
65 enum order_sign isl_polyhedron_affine_sign(Polyhedron *D, Matrix *T,
66 struct barvinok_options *options)
68 isl_ctx *ctx = isl_ctx_alloc();
69 isl_space *dim;
70 isl_vec *aff;
71 isl_basic_set *bset;
72 isl_int denom;
73 isl_int min, max;
74 enum isl_lp_result lp_min, lp_max;
75 enum order_sign sign = order_undefined;
77 isl_int_init(denom);
78 isl_int_init(min);
79 isl_int_init(max);
81 assert(D->Dimension == T->NbColumns - 1);
83 aff = isl_vec_alloc(ctx, T->NbColumns);
84 assert(aff);
85 values2isl(T->p[0], aff->el + 1, T->NbColumns - 1);
86 values2isl(T->p[0] + T->NbColumns - 1, aff->el, 1);
87 values2isl(T->p[1] + T->NbColumns - 1, &denom, 1);
89 dim = isl_space_set_alloc(ctx, 0, D->Dimension);
90 bset = isl_basic_set_new_from_polylib(D, dim);
92 lp_min = isl_basic_set_solve_lp(bset, 0, aff->el, denom, &min,
93 NULL, NULL);
94 assert(lp_min != isl_lp_error);
96 if (lp_min == isl_lp_empty)
97 sign = order_undefined;
98 else if (lp_min == isl_lp_ok && isl_int_is_pos(min))
99 sign = order_gt;
100 else {
101 lp_max = isl_basic_set_solve_lp(bset, 1, aff->el, denom, &max,
102 NULL, NULL);
103 assert(lp_max != isl_lp_error);
105 if (lp_max == isl_lp_ok && isl_int_is_neg(max))
106 sign = order_lt;
107 else if (lp_min == isl_lp_ok && lp_max == isl_lp_ok &&
108 isl_int_is_zero(min) && isl_int_is_zero(max))
109 sign = order_eq;
110 else if (lp_min == isl_lp_ok && isl_int_is_zero(min))
111 sign = order_ge;
112 else if (lp_max == isl_lp_ok && isl_int_is_zero(max))
113 sign = order_le;
114 else
115 sign = order_unknown;
118 isl_basic_set_free(bset);
119 isl_vec_free(aff);
120 isl_int_clear(min);
121 isl_int_clear(max);
122 isl_int_clear(denom);
123 isl_ctx_free(ctx);
125 return sign;
128 static enum lp_result isl_lp_result2lp_result(enum isl_lp_result res)
130 switch (res) {
131 case isl_lp_ok:
132 return lp_ok;
133 case isl_lp_unbounded:
134 return lp_unbounded;
135 case isl_lp_empty:
136 return lp_empty;
137 default:
138 assert(0);
142 enum lp_result isl_constraints_opt(Matrix *C, Value *obj, Value denom,
143 enum lp_dir dir, Value *opt)
145 isl_ctx *ctx = isl_ctx_alloc();
146 isl_space *dim;
147 isl_mat *eq, *ineq;
148 isl_basic_set *bset;
149 isl_int isl_denom, isl_opt;
150 isl_vec *aff;
151 enum isl_lp_result res;
152 int max = dir == lp_max;
154 isl_int_init(isl_denom);
155 isl_int_init(isl_opt);
157 eq = extract_equalities(ctx, C);
158 ineq = extract_inequalities(ctx, C);
159 dim = isl_space_set_alloc(ctx, 0, C->NbColumns - 2);
160 bset = isl_basic_set_from_constraint_matrices(dim, eq, ineq,
161 isl_dim_set, isl_dim_div, isl_dim_param, isl_dim_cst);
162 aff = isl_vec_alloc(ctx, C->NbColumns - 1);
163 assert(aff);
164 values2isl(obj, aff->el + 1, aff->size - 1);
165 values2isl(obj + aff->size - 1, aff->el, 1);
166 isl_int_set_gmp(isl_denom, denom);
168 res = isl_basic_set_solve_lp(bset, max, aff->el, isl_denom, &isl_opt,
169 NULL, NULL);
170 isl_int_get_gmp(isl_opt, *opt);
172 isl_vec_free(aff);
173 isl_int_clear(isl_denom);
174 isl_int_clear(isl_opt);
175 isl_basic_set_free(bset);
176 isl_ctx_free(ctx);
178 return isl_lp_result2lp_result(res);