3 #include <bernstein/bernstein.h>
4 #include <barvinok/evalue.h>
5 #include <barvinok/options.h>
6 #include <barvinok/util.h>
7 #include <barvinok/bernstein.h>
10 #include "evalue_convert.h"
11 #include "evalue_read.h"
18 using namespace GiNaC
;
19 using namespace bernstein
;
20 using namespace barvinok
;
22 #define ALLOCN(type,n) (type*)malloc((n) * sizeof(type))
24 #define OPT_VARS (BV_OPT_LAST+1)
25 #define OPT_SPLIT (BV_OPT_LAST+2)
26 #define OPT_LOWER (BV_OPT_LAST+3)
27 #define OPT_METHOD (BV_OPT_LAST+4)
29 struct argp_option argp_options
[] = {
30 { "split", OPT_SPLIT
, "int" },
31 { "variables", OPT_VARS
, "list", 0,
32 "comma separated list of variables over which to compute a bound" },
33 { "lower", OPT_LOWER
, 0, 0, "compute lower bound instead of upper bound"},
34 { "optimization-method", OPT_METHOD
, "bernstein|propagation",
35 0, "optimization method to use" },
40 struct convert_options convert
;
41 struct verify_options verify
;
45 #define METHOD_BERNSTEIN 0
46 #define METHOD_PROPAGATION 1
50 static error_t
parse_opt(int key
, char *arg
, struct argp_state
*state
)
52 struct options
*options
= (struct options
*) state
->input
;
56 state
->child_inputs
[0] = &options
->convert
;
57 state
->child_inputs
[1] = &options
->verify
;
58 state
->child_inputs
[2] = options
->verify
.barvinok
;
59 options
->var_list
= NULL
;
62 options
->method
= METHOD_BERNSTEIN
;
65 options
->var_list
= strdup(arg
);
68 options
->split
= atoi(arg
);
74 if (!strcmp(arg
, "bernstein"))
75 options
->method
= METHOD_BERNSTEIN
;
76 else if (!strcmp(arg
, "propagation"))
77 options
->method
= METHOD_PROPAGATION
;
79 argp_error(state
, "unknown value for --optimization-method option");
82 return ARGP_ERR_UNKNOWN
;
87 static int check_poly_max(const struct check_poly_data
*data
,
89 const struct verify_options
*options
);
91 struct check_poly_max_data
: public check_EP_data
{
94 check_poly_max_data(evalue
*EP
, piecewise_lst
*pl
) : pl(pl
) {
96 this->cp
.check
= check_poly_max
;
100 static int check_poly_max(const struct check_poly_data
*data
,
101 int nparam
, Value
*z
,
102 const struct verify_options
*options
)
106 const check_poly_max_data
*max_data
;
107 max_data
= (const check_poly_max_data
*)data
;
115 if (options
->barvinok
->bernstein_optimize
== BV_BERNSTEIN_MAX
) {
123 max_data
->pl
->evaluate(nparam
, z
, &n
, &d
);
129 if (options
->print_all
) {
130 printf("%s(", minmax
);
131 value_print(stdout
, VALUE_FMT
, z
[0]);
132 for (k
= 1; k
< nparam
; ++k
) {
134 value_print(stdout
, VALUE_FMT
, z
[k
]);
137 value_print(stdout
, VALUE_FMT
, n
);
138 if (value_notone_p(d
)) {
140 value_print(stdout
, VALUE_FMT
, d
);
143 value_print(stdout
, VALUE_FMT
, m
);
147 evalue_optimum(max_data
, &n
, sign
);
154 if (options
->print_all
) {
155 printf(", %s(EP) = ", minmax
);
156 value_print(stdout
, VALUE_FMT
, n
);
163 fprintf(stderr
, "Error !\n");
164 fprintf(stderr
, "%s(", minmax
);
165 value_print(stderr
, VALUE_FMT
, z
[0]);
166 for (k
= 1; k
< nparam
; ++k
) {
167 fprintf(stderr
,", ");
168 value_print(stderr
, VALUE_FMT
, z
[k
]);
170 fprintf(stderr
, ") should be ");
172 fprintf(stderr
, "greater");
174 fprintf(stderr
, "smaller");
175 fprintf(stderr
, " than or equal to ");
176 value_print(stderr
, VALUE_FMT
, n
);
177 fprintf(stderr
, ", while pl eval gives ");
178 value_print(stderr
, VALUE_FMT
, m
);
179 fprintf(stderr
, ".\n");
180 cerr
<< *max_data
->pl
<< endl
;
181 } else if (options
->print_all
)
191 static int verify(piecewise_lst
*pl
, evalue
*EP
, unsigned nvar
, unsigned nparam
,
192 struct verify_options
*options
)
194 check_poly_max_data
data(EP
, pl
);
195 return !check_EP(&data
, nvar
, nparam
, options
);
198 static int optimize(evalue
*EP
, char **all_vars
, unsigned nvar
, unsigned nparam
,
199 struct options
*options
)
202 piecewise_lst
*pl
= NULL
;
203 U
= Universe_Polyhedron(nparam
);
204 int print_solution
= 1;
208 params
= constructParameterVector(all_vars
+nvar
, nparam
);
210 if (options
->verify
.verify
) {
211 verify_options_set_range(&options
->verify
, nvar
+nparam
);
212 if (!options
->verify
.barvinok
->verbose
)
217 options
->verify
.barvinok
->bernstein_optimize
= BV_BERNSTEIN_MIN
;
219 options
->verify
.barvinok
->bernstein_optimize
= BV_BERNSTEIN_MAX
;
220 if (options
->method
== METHOD_BERNSTEIN
) {
221 pl
= evalue_bernstein_coefficients(NULL
, EP
, U
, params
,
222 options
->verify
.barvinok
);
228 pl
= evalue_range_propagation(NULL
, EP
, params
,
229 options
->verify
.barvinok
);
233 if (options
->verify
.verify
) {
234 result
= verify(pl
, EP
, nvar
, nparam
, &options
->verify
);
243 int main(int argc
, char **argv
)
246 char **all_vars
= NULL
;
249 struct options options
;
250 struct barvinok_options
*bv_options
= barvinok_options_new_with_defaults();
251 static struct argp_child argp_children
[] = {
252 { &convert_argp
, 0, "input conversion", 1 },
253 { &verify_argp
, 0, "verification", 2 },
254 { &barvinok_argp
, 0, "barvinok options", 3 },
257 static struct argp argp
= { argp_options
, parse_opt
, 0, 0, argp_children
};
260 options
.verify
.barvinok
= bv_options
;
261 set_program_name(argv
[0]);
262 argp_parse(&argp
, argc
, argv
, 0, 0, &options
);
264 EP
= evalue_read_from_file(stdin
, options
.var_list
, &all_vars
,
265 &nvar
, &nparam
, bv_options
->MaxRays
);
269 evalue_split_periods(EP
, options
.split
, bv_options
->MaxRays
);
271 evalue_convert(EP
, &options
.convert
, bv_options
->verbose
, nparam
, all_vars
);
273 if (EVALUE_IS_ZERO(*EP
))
274 print_evalue(stdout
, EP
, all_vars
);
276 result
= optimize(EP
, all_vars
, nvar
, nparam
, &options
);
280 if (options
.var_list
)
281 free(options
.var_list
);
282 Free_ParamNames(all_vars
, nvar
+nparam
);
283 barvinok_options_free(bv_options
);