2 #include <NTL/mat_ZZ.h>
3 #include <barvinok/evalue.h>
4 #include <barvinok/util.h>
5 #include <barvinok/barvinok.h>
7 #include "verif_ehrhart.h"
9 #ifdef HAVE_GROWING_CHERNIKOVA
17 #define getopt_long(a,b,c,d,e) getopt(a,b,c)
20 struct option options
[] = {
21 { "explicit", no_argument
, 0, 'e' },
22 { "series", no_argument
, 0, 's' },
23 { "print-all", no_argument
, 0, 'A' },
24 { "verbose", no_argument
, 0, 'v' },
25 { "version", no_argument
, 0, 'V' },
30 /* RANGE : normal range for evalutations (-RANGE -> RANGE) */
33 /* SRANGE : small range for evalutations */
36 /* if dimension >= BIDDIM, use SRANGE */
39 /* VSRANGE : very small range for evalutations */
42 /* if dimension >= VBIDDIM, use VSRANGE */
45 int check_series(Polyhedron
*S
, Polyhedron
*CS
, gen_fun
*gf
,
46 int nparam
, int pos
, Value
*z
, int print_all
)
58 /* Computes the coefficient */
59 gf
->coefficient(&z
[S
->Dimension
-nparam
+1], &c
);
61 /* if c=0 we may be out of context. */
62 /* scanning is useless in this case*/
66 value_print(stdout
,VALUE_FMT
,z
[S
->Dimension
-nparam
+1]);
67 for(k
=S
->Dimension
-nparam
+2;k
<=S
->Dimension
;++k
) {
69 value_print(stdout
,VALUE_FMT
,z
[k
]);
72 value_print(stdout
,VALUE_FMT
,c
);
75 /* Manually count the number of points */
76 count_points(1,S
,z
,&tmp
);
79 value_print(stdout
, P_VALUE_FMT
, tmp
);
86 fprintf(stderr
,"Error !\n");
87 fprintf(stderr
,"EP( ");
88 value_print(stderr
,VALUE_FMT
,z
[S
->Dimension
-nparam
+1]);
89 for(k
=S
->Dimension
-nparam
+2;k
<=S
->Dimension
;++k
) {
91 value_print(stderr
,VALUE_FMT
,z
[k
]);
93 fprintf(stderr
," ) should be ");
94 value_print(stderr
,VALUE_FMT
,tmp
);
95 fprintf(stderr
,", while EP eval gives ");
96 value_print(stderr
,VALUE_FMT
,c
);
97 fprintf(stderr
,".\n");
98 #ifndef DONT_BREAK_ON_ERROR
99 value_clear(c
); value_clear(tmp
);
102 } else if (print_all
)
106 !(lower_upper_bounds(1+pos
, CS
, &z
[S
->Dimension
-nparam
], &LB
, &UB
));
108 for(value_assign(tmp
,LB
); value_le(tmp
,UB
); value_increment(tmp
,tmp
)) {
110 k
= VALUE_TO_INT(tmp
);
111 if(!pos
&& !(k
%st
)) {
116 value_assign(z
[pos
+S
->Dimension
-nparam
+1],tmp
);
117 if (!check_series(S
, CS
->next
, gf
, nparam
, pos
+1, z
, print_all
)) {
118 value_clear(c
); value_clear(tmp
);
124 value_set_si(z
[pos
+S
->Dimension
-nparam
+1],0);
134 int main(int argc
,char *argv
[]) {
136 Matrix
*C1
, *P1
, *MM
;
137 Polyhedron
*C
, *P
, *S
, *CS
, *U
;
139 Enumeration
*en
= NULL
;
143 int m
= INT_MAX
, M
= INT_MIN
, r
;
151 while ((c
= getopt_long(argc
, argv
, "m:M:r:sveVA", options
, &ind
)) != -1) {
176 printf(barvinok_version());
182 /******* Read the input *********/
186 if(C1
->NbColumns
< 2) {
187 fprintf(stderr
,"Not enough parameters !\n");
191 P
= Constraints2Polyhedron(P1
,MAXRAYS
);
192 C
= Constraints2Polyhedron(C1
,MAXRAYS
);
193 params
= Read_ParamNames(stdin
, C
->Dimension
);
197 /******* Read the options: initialize Min and Max ********/
198 if(P
->Dimension
>= VBIGDIM
)
200 else if(P
->Dimension
>= BIGDIM
)
211 fprintf(stderr
,"Nothing to do: Min > Max !\n");
220 /******* Compute true context *******/
221 CC
= align_context(C
,P
->Dimension
,MAXRAYS
);
222 PP
= DomainIntersection(P
,CC
,MAXRAYS
);
224 C1
= Matrix_Alloc(C
->Dimension
+1,P
->Dimension
+1);
226 for(i
=0;i
<C1
->NbRows
;i
++)
227 for(j
=0;j
<C1
->NbColumns
;j
++)
228 if(i
==j
-P
->Dimension
+C
->Dimension
)
229 value_set_si(C1
->p
[i
][j
],1);
231 value_set_si(C1
->p
[i
][j
],0);
232 CC
= Polyhedron_Image(PP
,C1
,MAXRAYS
);
238 /* Intersect context with range */
239 if(C
->Dimension
> 0) {
240 MM
= Matrix_Alloc(2*C
->Dimension
, C
->Dimension
+2);
241 for (i
= 0; i
< C
->Dimension
; ++i
) {
242 value_set_si(MM
->p
[2*i
][0], 1);
243 value_set_si(MM
->p
[2*i
][1+i
], 1);
244 value_set_si(MM
->p
[2*i
][1+C
->Dimension
], -m
);
245 value_set_si(MM
->p
[2*i
+1][0], 1);
246 value_set_si(MM
->p
[2*i
+1][1+i
], -1);
247 value_set_si(MM
->p
[2*i
+1][1+C
->Dimension
], M
);
249 CC
= AddConstraints(MM
->p
[0], 2*C
->Dimension
, C
, MAXRAYS
);
250 U
= Universe_Polyhedron(0);
251 CS
= Polyhedron_Scan(CC
, U
, MAXRAYS
);
260 /******* Compute EP *********/
262 en
= barvinok_enumerate(P
,C
,MAXRAYS
);
264 Enumeration_Print(stdout
, en
, params
);
267 gf
= barvinok_series(P
, C
, MAXRAYS
);
269 gf
->print(std::cout
, C
->Dimension
, params
);
274 en
= partition2enumeration(EP
);
276 Enumeration_Print(stdout
, en
, params
);
280 /******* Initializations for check *********/
281 p
= (Value
*)malloc(sizeof(Value
) * (P
->Dimension
+2));
282 for(i
=0;i
<=P
->Dimension
;i
++) {
284 value_set_si(p
[i
],0);
287 value_set_si(p
[i
],1);
289 /* S = scanning list of polyhedra */
290 S
= Polyhedron_Scan(P
,C
,MAXRAYS
);
293 if (C
->Dimension
> 0) {
294 value_subtract(tmp
,Max
,Min
);
295 if (VALUE_TO_INT(tmp
) > 80)
296 st
= 1+(VALUE_TO_INT(tmp
))/80;
299 for(i
=VALUE_TO_INT(Min
);i
<=VALUE_TO_INT(Max
);i
+=st
)
305 /******* CHECK NOW *********/
307 if (!series
|| function
) {
308 if (!check_poly(S
, CS
,en
,C
->Dimension
,0,p
, print_all
))
311 if (!check_series(S
, CS
,gf
,C
->Dimension
,0,p
, print_all
))
318 fprintf(stderr
,"Check failed !\n");
324 Enumeration_Free(en
);
328 for(i
=0;i
<=(P
->Dimension
+1);i
++)
334 Free_ParamNames(params
, C
->Dimension
);