polysign_isl.c: extract_equalities: use isl_val
[barvinok.git] / polysign_isl.c
blobe57690d83c4e016fae3dfc6a2242156e02baf088
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_int 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 isl_int_init(v);
53 ineq = isl_mat_alloc(ctx, n, M->NbColumns - 1);
54 for (i = 0; i < M->NbRows; ++i) {
55 if (value_zero_p(M->p[i][0]))
56 continue;
57 for (j = 0; j < M->NbColumns - 1; ++j) {
58 isl_int_set_gmp(v, M->p[i][1 + j]);
59 ineq = isl_mat_set_element(ineq, i, j, v);
62 isl_int_clear(v);
64 return ineq;
67 enum order_sign isl_polyhedron_affine_sign(Polyhedron *D, Matrix *T,
68 struct barvinok_options *options)
70 isl_ctx *ctx = isl_ctx_alloc();
71 isl_space *dim;
72 isl_vec *aff;
73 isl_basic_set *bset;
74 isl_int denom;
75 isl_int min, max;
76 enum isl_lp_result lp_min, lp_max;
77 enum order_sign sign = order_undefined;
79 isl_int_init(denom);
80 isl_int_init(min);
81 isl_int_init(max);
83 assert(D->Dimension == T->NbColumns - 1);
85 aff = isl_vec_alloc(ctx, T->NbColumns);
86 assert(aff);
87 values2isl(T->p[0], aff->el + 1, T->NbColumns - 1);
88 values2isl(T->p[0] + T->NbColumns - 1, aff->el, 1);
89 values2isl(T->p[1] + T->NbColumns - 1, &denom, 1);
91 dim = isl_space_set_alloc(ctx, 0, D->Dimension);
92 bset = isl_basic_set_new_from_polylib(D, dim);
94 lp_min = isl_basic_set_solve_lp(bset, 0, aff->el, denom, &min,
95 NULL, NULL);
96 assert(lp_min != isl_lp_error);
98 if (lp_min == isl_lp_empty)
99 sign = order_undefined;
100 else if (lp_min == isl_lp_ok && isl_int_is_pos(min))
101 sign = order_gt;
102 else {
103 lp_max = isl_basic_set_solve_lp(bset, 1, aff->el, denom, &max,
104 NULL, NULL);
105 assert(lp_max != isl_lp_error);
107 if (lp_max == isl_lp_ok && isl_int_is_neg(max))
108 sign = order_lt;
109 else if (lp_min == isl_lp_ok && lp_max == isl_lp_ok &&
110 isl_int_is_zero(min) && isl_int_is_zero(max))
111 sign = order_eq;
112 else if (lp_min == isl_lp_ok && isl_int_is_zero(min))
113 sign = order_ge;
114 else if (lp_max == isl_lp_ok && isl_int_is_zero(max))
115 sign = order_le;
116 else
117 sign = order_unknown;
120 isl_basic_set_free(bset);
121 isl_vec_free(aff);
122 isl_int_clear(min);
123 isl_int_clear(max);
124 isl_int_clear(denom);
125 isl_ctx_free(ctx);
127 return sign;
130 static enum lp_result isl_lp_result2lp_result(enum isl_lp_result res)
132 switch (res) {
133 case isl_lp_ok:
134 return lp_ok;
135 case isl_lp_unbounded:
136 return lp_unbounded;
137 case isl_lp_empty:
138 return lp_empty;
139 default:
140 assert(0);
144 enum lp_result isl_constraints_opt(Matrix *C, Value *obj, Value denom,
145 enum lp_dir dir, Value *opt)
147 isl_ctx *ctx = isl_ctx_alloc();
148 isl_space *dim;
149 isl_mat *eq, *ineq;
150 isl_basic_set *bset;
151 isl_int isl_denom, isl_opt;
152 isl_vec *aff;
153 enum isl_lp_result res;
154 int max = dir == lp_max;
156 isl_int_init(isl_denom);
157 isl_int_init(isl_opt);
159 eq = extract_equalities(ctx, C);
160 ineq = extract_inequalities(ctx, C);
161 dim = isl_space_set_alloc(ctx, 0, C->NbColumns - 2);
162 bset = isl_basic_set_from_constraint_matrices(dim, eq, ineq,
163 isl_dim_set, isl_dim_div, isl_dim_param, isl_dim_cst);
164 aff = isl_vec_alloc(ctx, C->NbColumns - 1);
165 assert(aff);
166 values2isl(obj, aff->el + 1, aff->size - 1);
167 values2isl(obj + aff->size - 1, aff->el, 1);
168 isl_int_set_gmp(isl_denom, denom);
170 res = isl_basic_set_solve_lp(bset, max, aff->el, isl_denom, &isl_opt,
171 NULL, NULL);
172 isl_int_get_gmp(isl_opt, *opt);
174 isl_vec_free(aff);
175 isl_int_clear(isl_denom);
176 isl_int_clear(isl_opt);
177 isl_basic_set_free(bset);
178 isl_ctx_free(ctx);
180 return isl_lp_result2lp_result(res);