3 #include <barvinok/util.h>
4 #include <barvinok/barvinok.h>
8 #include "omega/convert.h"
11 /* The input of this example program is a polytope in combined
12 * data and parameter space followed by two lines indicating
13 * the number of existential variables and parameters respectively.
14 * The first lines starts with "E ", followed by a number.
15 * The second lines starts with "P ", followed by a number.
16 * These two lines are (optionally) followed by the names of the parameters.
17 * The polytope is in PolyLib notation.
20 #ifdef HAVE_GROWING_CHERNIKOVA
21 #define MAXRAYS POL_NO_DUAL
27 #define getopt_long(a,b,c,d,e) getopt(a,b,c)
30 struct option options
[] = {
32 { "omega", no_argument
, 0, 'o' },
35 { "pip", no_argument
, 0, 'p' },
37 { "series", no_argument
, 0, 's' },
38 { "scarf", no_argument
, 0, 'S' },
39 { "convert", no_argument
, 0, 'c' },
40 { "floor", no_argument
, 0, 'f' },
41 { "range-reduction", no_argument
, 0, 'R' },
42 { "verify", no_argument
, 0, 'T' },
43 { "print-all", no_argument
, 0, 'A' },
44 { "min", required_argument
, 0, 'm' },
45 { "max", required_argument
, 0, 'M' },
46 { "range", required_argument
, 0, 'r' },
47 { "version", no_argument
, 0, 'V' },
53 #define PIPLIB_OPT "p"
61 Polyhedron
*Omega_simplify(Polyhedron
*P
,
62 unsigned exist
, unsigned nparam
, char **parms
)
66 Relation r
= Polyhedron2relation(P
, exist
, nparam
, parms
);
68 return relation2Domain(r
, varv
, paramv
);
72 Polyhedron
*Omega_simplify(Polyhedron
*P
,
73 unsigned exist
, unsigned nparam
, char **parms
)
79 /* define this to continue the test after first error found */
80 /* #define DONT_BREAK_ON_ERROR */
82 /* RANGE : normal range for evalutations (-RANGE -> RANGE) */
85 /* SRANGE : small range for evalutations */
88 /* if dimension >= BIDDIM, use SRANGE */
91 /* VSRANGE : very small range for evalutations */
94 /* if dimension >= VBIDDIM, use VSRANGE */
97 static Value min_val
, max_val
;
103 static int check_poly(Polyhedron
*S
, Polyhedron
*C
, evalue
*EP
,
104 int exist
, int nparam
, int pos
, Value
*z
, int print_all
);
105 static void verify_results(Polyhedron
*P
, evalue
*EP
, int exist
, int nparam
,
106 int m
, int M
, int print_all
);
108 int main(int argc
, char **argv
)
113 int exist
, nparam
, nvar
;
126 int m
= INT_MAX
, M
= INT_MIN
, r
;
127 int print_solution
= 1;
129 while ((c
= getopt_long(argc
, argv
,
130 OMEGA_OPT PIPLIB_OPT
"sSfcRTAm:M:r:V", options
, &ind
)) != -1) {
173 printf(barvinok_version());
179 if (series
&& !scarf
) {
181 "--series currently only available if --scarf is specified\n");
186 A
= Constraints2Polyhedron(MA
, MAXRAYS
);
189 fgets(s
, 128, stdin
);
190 while ((*s
=='#') || (sscanf(s
, "E %d", &exist
)<1))
191 fgets(s
, 128, stdin
);
193 fgets(s
, 128, stdin
);
194 while ((*s
=='#') || (sscanf(s
, "P %d", &nparam
)<1))
195 fgets(s
, 128, stdin
);
197 /******* Read the options: initialize Min and Max ********/
198 if (A
->Dimension
>= VBIGDIM
)
200 else if (A
->Dimension
>= BIGDIM
)
209 if (verify
&& m
> M
) {
210 fprintf(stderr
,"Nothing to do: min > max !\n");
216 if (print_solution
) {
217 Polyhedron_Print(stdout
, P_VALUE_FMT
, A
);
218 printf("exist: %d, nparam: %d\n", exist
, nparam
);
220 param_name
= Read_ParamNames(stdin
, nparam
);
221 nvar
= A
->Dimension
- exist
- nparam
;
223 A
= Omega_simplify(A
, exist
, nparam
, param_name
);
225 exist
= A
->Dimension
- nvar
- nparam
;
229 barvinok_options
*options
= barvinok_options_new_with_defaults();
231 gf
= barvinok_enumerate_scarf_series(A
, exist
, nparam
, options
);
232 if (print_solution
) {
233 gf
->print(std::cout
, nparam
, param_name
);
240 barvinok_options
*options
= barvinok_options_new_with_defaults();
241 EP
= barvinok_enumerate_scarf(A
, exist
, nparam
, options
);
243 } else if (pip
&& exist
> 0)
244 EP
= barvinok_enumerate_pip(A
, exist
, nparam
, MAXRAYS
);
246 EP
= barvinok_enumerate_e(A
, exist
, nparam
, MAXRAYS
);
250 evalue_range_reduction(EP
);
252 print_evalue(stdout
, EP
, param_name
);
254 fprintf(stderr
, "WARNING: floor conversion not supported\n");
255 evalue_frac2floor(EP
);
257 print_evalue(stdout
, EP
, param_name
);
258 } else if (convert
) {
259 evalue_mod2table(EP
, nparam
);
261 print_evalue(stdout
, EP
, param_name
);
264 verify_results(A
, EP
, exist
, nparam
, m
, M
, print_all
);
265 free_evalue_refs(EP
);
268 Free_ParamNames(param_name
, nparam
);
273 void verify_results(Polyhedron
*P
, evalue
*EP
, int exist
, int nparam
, int m
, int M
,
280 Polyhedron
*C
= Polyhedron_Project(P
, nparam
);
283 value_set_si(min_val
,m
);
284 value_set_si(max_val
,M
);
287 p
= (Value
*)malloc(sizeof(Value
) * (P
->Dimension
+2));
288 for(i
=0;i
<=P
->Dimension
;i
++) {
290 value_set_si(p
[i
],0);
293 value_set_si(p
[i
],1);
295 /* S = scanning list of polyhedra */
296 S
= Polyhedron_Scan(P
, C
, MAXRAYS
& POL_NO_DUAL
? 0 : MAXRAYS
);
299 if (C
->Dimension
> 0) {
300 value_subtract(tmp
,max_val
,min_val
);
301 if (VALUE_TO_INT(tmp
) > 80)
302 st
= 1+(VALUE_TO_INT(tmp
))/80;
305 for(i
=VALUE_TO_INT(min_val
);i
<=VALUE_TO_INT(max_val
);i
+=st
)
312 /******* CHECK NOW *********/
314 if(S
&& !check_poly(S
, C
, EP
, exist
, nparam
, 0, p
, print_all
)) {
315 fprintf(stderr
,"Check failed !\n");
322 for(i
=0;i
<=(P
->Dimension
+1);i
++)
330 /****************************************************/
331 /* function check_poly : */
332 /* scans the parameter space from min to max (all */
333 /* directions). Computes the number of points in */
334 /* the polytope using both methods, and compare them*/
335 /* returns 1 on success */
336 /****************************************************/
338 int check_poly(Polyhedron
*S
, Polyhedron
*C
, evalue
*EP
,
339 int exist
, int nparam
, int pos
, Value
*z
, int print_all
)
344 value_init(c
); value_init(tmp
);
348 /* Computes the ehrhart polynomial */
349 value_set_double(c
, compute_evalue(EP
,&z
[S
->Dimension
-nparam
+1])+.25);
350 /* if c=0 we may be out of context. */
351 /* scanning is useless in this case*/
352 if(!in_domain(C
,&z
[S
->Dimension
-nparam
+1])) {
360 value_print(stdout
,VALUE_FMT
,z
[S
->Dimension
-nparam
+1]);
361 for(k
=S
->Dimension
-nparam
+2;k
<=S
->Dimension
;++k
) {
363 value_print(stdout
,VALUE_FMT
,z
[k
]);
366 value_print(stdout
,VALUE_FMT
,c
);
370 /* Manually count the number of points */
371 count_points_e(1, S
, exist
, nparam
, z
, &tmp
);
373 printf(", count = ");
374 value_print(stdout
, P_VALUE_FMT
, tmp
);
378 if(value_ne(tmp
,c
)) {
381 fprintf(stderr
,"Error !\n");
382 fprintf(stderr
,"EP( ");
383 value_print(stderr
,VALUE_FMT
,z
[S
->Dimension
-nparam
+1]);
384 for(k
=S
->Dimension
-nparam
+2;k
<=S
->Dimension
;++k
) {
385 fprintf(stderr
,", ");
386 value_print(stderr
,VALUE_FMT
,z
[k
]);
388 fprintf(stderr
," ) should be ");
389 value_print(stderr
,VALUE_FMT
,tmp
);
390 fprintf(stderr
,", while EP eval gives ");
391 value_print(stderr
,VALUE_FMT
,c
);
392 fprintf(stderr
,".\n");
393 print_evalue(stderr
, EP
, params
);
394 #ifndef DONT_BREAK_ON_ERROR
395 value_clear(c
); value_clear(tmp
);
404 for(value_assign(tmp
,min_val
); value_le(tmp
,max_val
); value_increment(tmp
,tmp
)) {
406 k
= VALUE_TO_INT(tmp
);
407 if(!pos
&& !(k
%st
)) {
413 value_assign(z
[pos
+S
->Dimension
-nparam
+1],tmp
);
414 if(!check_poly(S
, C
, EP
, exist
, nparam
, pos
+1, z
, print_all
)) {
415 value_clear(c
); value_clear(tmp
);
419 value_clear(c
); value_clear(tmp
);