1 #include <isl_set_polylib.h>
2 #include <isl_constraint.h>
3 #include <barvinok/evalue.h>
5 static __isl_give isl_qpolynomial
*extract_base(__isl_take isl_dim
*dim
,
11 isl_qpolynomial
*base
, *c
;
17 if (e
->x
.p
->type
== polynomial
)
18 return isl_qpolynomial_var(dim
, isl_dim_param
, e
->x
.p
->pos
- 1);
20 nparam
= isl_dim_size(dim
, isl_dim_param
);
21 v
= isl_vec_alloc(dim
->ctx
, 2 + nparam
);
25 isl_seq_clr(v
->el
+ 2, nparam
);
26 evalue_extract_affine(&e
->x
.p
->arr
[0], v
->el
+ 2, &v
->el
[1], &v
->el
[0]);
28 div
= isl_div_alloc(isl_dim_copy(dim
));
29 isl_div_set_constant(div
, v
->el
[1]);
30 isl_div_set_denominator(div
, v
->el
[0]);
32 for (i
= 0; i
< nparam
; ++i
)
33 isl_div_set_coefficient(div
, isl_dim_param
, i
, v
->el
[2 + i
]);
35 base
= isl_qpolynomial_div(div
);
37 if (e
->x
.p
->type
== fractional
) {
38 base
= isl_qpolynomial_neg(base
);
40 c
= isl_qpolynomial_rat_cst(isl_dim_copy(dim
), v
->el
[1], v
->el
[0]);
41 base
= isl_qpolynomial_add(base
, c
);
43 for (i
= 0; i
< nparam
; ++i
) {
45 c
= isl_qpolynomial_rat_cst(isl_dim_copy(dim
),
46 v
->el
[2 + i
], v
->el
[0]);
47 t
= isl_qpolynomial_var(isl_dim_copy(dim
),
49 t
= isl_qpolynomial_mul(c
, t
);
50 base
= isl_qpolynomial_add(base
, t
);
63 static int type_offset(enode
*p
)
65 return p
->type
== fractional
? 1 :
66 p
->type
== flooring
? 1 : 0;
69 static __isl_give isl_qpolynomial
*evalue2qp(__isl_take isl_dim
*dim
,
74 isl_qpolynomial
*base
;
77 if (EVALUE_IS_NAN(*e
))
78 return isl_qpolynomial_infty(dim
);
79 if (value_notzero_p(e
->d
))
80 return isl_qpolynomial_rat_cst(dim
, e
->x
.n
, e
->d
);
82 offset
= type_offset(e
->x
.p
);
84 assert(e
->x
.p
->type
== polynomial
||
85 e
->x
.p
->type
== flooring
||
86 e
->x
.p
->type
== fractional
);
87 assert(e
->x
.p
->size
>= 1 + offset
);
89 base
= extract_base(isl_dim_copy(dim
), e
);
90 qp
= evalue2qp(isl_dim_copy(dim
), &e
->x
.p
->arr
[e
->x
.p
->size
- 1]);
92 for (i
= e
->x
.p
->size
- 2; i
>= offset
; --i
) {
93 qp
= isl_qpolynomial_mul(qp
, isl_qpolynomial_copy(base
));
94 qp
= isl_qpolynomial_add(qp
,
95 evalue2qp(isl_dim_copy(dim
), &e
->x
.p
->arr
[i
]));
98 isl_qpolynomial_free(base
);
104 static __isl_give isl_pw_qpolynomial
*guarded_evalue2pwqp(__isl_take isl_set
*set
,
107 static __isl_give isl_pw_qpolynomial
*relation2pwqp(__isl_take isl_set
*set
,
114 isl_pw_qpolynomial
*pwqp
;
115 struct isl_constraint
*c
;
116 struct isl_basic_set
*bset
;
117 struct isl_set
*guard
;
123 if (e
->x
.p
->size
== 1) {
124 dim
= isl_set_get_dim(set
);
126 return isl_pw_qpolynomial_zero(dim
);
129 isl_assert(set
->ctx
, e
->x
.p
->size
> 0, goto error
);
130 isl_assert(set
->ctx
, e
->x
.p
->size
<= 3, goto error
);
131 isl_assert(set
->ctx
, value_zero_p(e
->x
.p
->arr
[0].d
), goto error
);
132 isl_assert(set
->ctx
, e
->x
.p
->arr
[0].x
.p
->type
== fractional
, goto error
);
133 fract
= &e
->x
.p
->arr
[0];
135 nparam
= isl_set_dim(set
, isl_dim_param
);
136 vec
= isl_vec_alloc(set
->ctx
, 2 + nparam
+ 1);
140 isl_seq_clr(vec
->el
+ 2, nparam
);
141 evalue_extract_affine(&fract
->x
.p
->arr
[0],
142 vec
->el
+ 2, &vec
->el
[1], &vec
->el
[0]);
144 dim
= isl_set_get_dim(set
);
145 dim
= isl_dim_add(dim
, isl_dim_set
, 1);
147 bset
= isl_basic_set_universe(dim
);
148 c
= isl_equality_alloc(isl_dim_copy(dim
));
149 isl_int_neg(vec
->el
[0], vec
->el
[0]);
150 isl_constraint_set_coefficient(c
, isl_dim_set
, 0, vec
->el
[0]);
151 isl_constraint_set_constant(c
, vec
->el
[1]);
152 for (i
= 0; i
< nparam
; ++i
)
153 isl_constraint_set_coefficient(c
, isl_dim_param
, i
, vec
->el
[2+i
]);
154 bset
= isl_basic_set_add_constraint(bset
, c
);
155 bset
= isl_basic_set_project_out(bset
, isl_dim_set
, 0, 1);
156 guard
= isl_set_from_basic_set(bset
);
159 pwqp
= guarded_evalue2pwqp(isl_set_intersect(isl_set_copy(set
),
160 isl_set_copy(guard
)),
163 if (e
->x
.p
->size
== 3) {
164 isl_pw_qpolynomial
*pwqpc
;
165 guard
= isl_set_complement(guard
);
166 pwqpc
= guarded_evalue2pwqp(isl_set_intersect(isl_set_copy(set
),
167 isl_set_copy(guard
)),
169 pwqp
= isl_pw_qpolynomial_add_disjoint(pwqp
, pwqpc
);
181 static __isl_give isl_pw_qpolynomial
*guarded_evalue2pwqp(__isl_take isl_set
*set
,
186 if (value_zero_p(e
->d
) && e
->x
.p
->type
== relation
)
187 return relation2pwqp(set
, e
);
189 qp
= evalue2qp(isl_set_get_dim(set
), e
);
191 return isl_pw_qpolynomial_alloc(set
, qp
);
194 __isl_give isl_pw_qpolynomial
*evalue2isl(__isl_take isl_dim
*dim
, const evalue
*e
)
197 isl_pw_qpolynomial
*pwqp
;
201 if (EVALUE_IS_ZERO(*e
))
202 return isl_pw_qpolynomial_zero(dim
);
204 if (value_notzero_p(e
->d
)) {
205 isl_set
*set
= isl_set_universe(isl_dim_copy(dim
));
206 isl_qpolynomial
*qp
= isl_qpolynomial_rat_cst(dim
, e
->x
.n
, e
->d
);
207 return isl_pw_qpolynomial_alloc(set
, qp
);
210 assert(!EVALUE_IS_NAN(*e
));
212 assert(e
->x
.p
->type
== partition
);
214 pwqp
= isl_pw_qpolynomial_zero(isl_dim_copy(dim
));
216 for (i
= 0; i
< e
->x
.p
->size
/2; ++i
) {
217 Polyhedron
*D
= EVALUE_DOMAIN(e
->x
.p
->arr
[2 * i
]);
218 isl_set
*set
= isl_set_new_from_polylib(D
, isl_dim_copy(dim
));
219 isl_pw_qpolynomial
*pwqp_i
;
221 pwqp_i
= guarded_evalue2pwqp(set
, &e
->x
.p
->arr
[2 * i
+ 1]);
223 pwqp
= isl_pw_qpolynomial_add_disjoint(pwqp
, pwqp_i
);