2 #include <barvinok/evalue.h>
3 #include <barvinok/options.h>
4 #include <barvinok/util.h>
7 #include "evalue_convert.h"
8 #include "evalue_read.h"
15 #define ALLOCN(type,n) (type*)malloc((n) * sizeof(type))
17 #define OPT_VARS (BV_OPT_LAST+1)
19 struct argp_option argp_options
[] = {
20 { "variables", OPT_VARS
, "list", 0,
21 "comma separated list of variables over which to maximize" },
22 { "verbose", 'v', 0, 0, },
27 struct convert_options convert
;
28 struct verify_options verify
;
33 static error_t
parse_opt(int key
, char *arg
, struct argp_state
*state
)
35 struct options
*options
= (struct options
*) state
->input
;
39 state
->child_inputs
[0] = &options
->convert
;
40 state
->child_inputs
[1] = &options
->verify
;
41 state
->child_inputs
[2] = options
->verify
.barvinok
;
42 options
->var_list
= NULL
;
49 options
->var_list
= strdup(arg
);
52 return ARGP_ERR_UNKNOWN
;
57 static int check_poly_sum(const struct check_poly_data
*data
,
59 const struct verify_options
*options
);
61 struct check_poly_sum_data
: public check_poly_data
{
66 check_poly_sum_data(Value
*z
, evalue
*EP
, evalue
*sum
) :
69 this->check
= check_poly_sum
;
73 static void sum(Polyhedron
*S
, int pos
, const check_poly_sum_data
*data
,
74 evalue
*s
, const struct verify_options
*options
)
77 evalue
*e
= evalue_eval(data
->EP
, data
->z
+1);
86 ok
= !(lower_upper_bounds(1+pos
, S
, data
->z
, &LB
, &UB
));
88 for (; value_le(LB
, UB
); value_increment(LB
, LB
)) {
89 value_assign(data
->z
[1+pos
], LB
);
90 sum(S
->next
, pos
+1, data
, s
, options
);
92 value_set_si(data
->z
[1+pos
], 0);
98 static evalue
*sum(const check_poly_sum_data
*data
,
99 const struct verify_options
*options
)
101 evalue
*s
= evalue_zero();
102 for (int i
= 0; i
< data
->EP
->x
.p
->size
/2; ++i
)
103 if (!emptyQ2(data
->S
[i
]))
104 sum(data
->S
[i
], 0, data
, s
, options
);
108 static int check_poly_sum(const struct check_poly_data
*data
,
109 int nparam
, Value
*z
,
110 const struct verify_options
*options
)
112 const check_poly_sum_data
*sum_data
;
113 sum_data
= static_cast<const check_poly_sum_data
*>(data
);
118 e
= evalue_eval(sum_data
->sum
, z
);
119 if (options
->print_all
) {
121 value_print(stdout
, VALUE_FMT
, z
[0]);
122 for (k
= 1; k
< nparam
; ++k
) {
124 value_print(stdout
, VALUE_FMT
, z
[k
]);
127 value_print(stdout
, VALUE_FMT
, e
->x
.n
);
128 if (value_notone_p(e
->d
)) {
130 value_print(stdout
, VALUE_FMT
, e
->d
);
134 s
= sum(sum_data
, options
);
136 if (options
->print_all
) {
137 printf(", sum(EP) = ");
138 value_print(stdout
, VALUE_FMT
, s
->x
.n
);
139 if (value_notone_p(s
->d
)) {
141 value_print(stdout
, VALUE_FMT
, s
->d
);
151 fprintf(stderr
,"Error !\n");
152 fprintf(stderr
,"sum( ");
153 value_print(stderr
, VALUE_FMT
, z
[0]);
154 for (k
= 1; k
< nparam
; ++k
) {
155 fprintf(stderr
, ", ");
156 value_print(stderr
, VALUE_FMT
, z
[k
]);
158 fprintf(stderr
," ) should be ");
159 value_print(stderr
, VALUE_FMT
, s
->x
.n
);
160 if (value_notone_p(s
->d
)) {
161 fprintf(stderr
, "/");
162 value_print(stderr
, VALUE_FMT
, s
->d
);
164 fprintf(stderr
,", while summation gives ");
165 value_print(stderr
, VALUE_FMT
, e
->x
.n
);
166 if (value_notone_p(e
->d
)) {
167 fprintf(stderr
, "/");
168 value_print(stderr
, VALUE_FMT
, e
->d
);
170 fprintf(stderr
, ".\n");
171 } else if (options
->print_all
)
182 static int verify(Polyhedron
*P
, evalue
*sum
, evalue
*EP
,
183 unsigned nvar
, unsigned nparam
, Vector
*p
,
184 struct verify_options
*options
)
187 unsigned MaxRays
= options
->barvinok
->MaxRays
;
190 CS
= check_poly_context_scan(NULL
, &P
, P
->Dimension
, options
);
192 check_poly_init(P
, options
);
194 if (!(CS
&& emptyQ2(CS
))) {
195 check_poly_sum_data
data(p
->p
, EP
, sum
);
196 data
.S
= ALLOCN(Polyhedron
*, EP
->x
.p
->size
/2);
197 for (int i
= 0; i
< EP
->x
.p
->size
/2; ++i
) {
198 Polyhedron
*A
= EVALUE_DOMAIN(EP
->x
.p
->arr
[2*i
]);
199 data
.S
[i
] = Polyhedron_Scan(A
, P
, MaxRays
& POL_NO_DUAL
? 0 : MaxRays
);
201 error
= !check_poly(CS
, &data
, nparam
, 0, p
->p
+1+nvar
, options
);
202 for (int i
= 0; i
< EP
->x
.p
->size
/2; ++i
)
203 Domain_Free(data
.S
[i
]);
207 if (!options
->print_all
)
218 static int verify(evalue
*EP
, evalue
*sum
, unsigned nvar
, unsigned nparam
,
219 struct verify_options
*options
)
223 p
= Vector_Alloc(nvar
+nparam
+2);
224 value_set_si(p
->p
[nvar
+nparam
+1], 1);
226 assert(value_zero_p(sum
->d
));
227 assert(sum
->x
.p
->type
== partition
);
230 for (int i
= 0; i
< sum
->x
.p
->size
/2; ++i
) {
231 Polyhedron
*D
= EVALUE_DOMAIN(sum
->x
.p
->arr
[2*i
]);
232 for (Polyhedron
*P
= D
; P
; P
= P
->next
) {
233 error
= verify(P
, sum
, EP
, nvar
, nparam
, p
, options
);
234 if (error
&& !options
->continue_on_error
)
237 if (error
&& !options
->continue_on_error
)
246 int main(int argc
, char **argv
)
249 char **all_vars
= NULL
;
252 struct options options
;
253 struct barvinok_options
*bv_options
= barvinok_options_new_with_defaults();
254 static struct argp_child argp_children
[] = {
255 { &convert_argp
, 0, "input conversion", 1 },
256 { &verify_argp
, 0, "verification", 2 },
257 { &barvinok_argp
, 0, "barvinok options", 3 },
260 static struct argp argp
= { argp_options
, parse_opt
, 0, 0, argp_children
};
263 options
.verify
.barvinok
= bv_options
;
264 set_program_name(argv
[0]);
265 argp_parse(&argp
, argc
, argv
, 0, 0, &options
);
267 EP
= evalue_read_from_file(stdin
, options
.var_list
, &all_vars
,
268 &nvar
, &nparam
, bv_options
->MaxRays
);
271 if (options
.verify
.verify
)
272 verify_options_set_range(&options
.verify
, nvar
+nparam
);
274 evalue_convert(EP
, &options
.convert
, options
.verbose
, nparam
, all_vars
);
276 if (EVALUE_IS_ZERO(*EP
))
277 print_evalue(stdout
, EP
, all_vars
);
279 evalue
*sum
= evalue_sum(EP
, nvar
, bv_options
->MaxRays
);
280 if (options
.verify
.verify
)
281 result
= verify(EP
, sum
, nvar
, nparam
, &options
.verify
);
283 print_evalue(stdout
, sum
, all_vars
+nvar
);
284 free_evalue_refs(sum
);
288 free_evalue_refs(EP
);
291 if (options
.var_list
)
292 free(options
.var_list
);
293 Free_ParamNames(all_vars
, nvar
+nparam
);
294 barvinok_options_free(bv_options
);