00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <ctype.h>
00031 #include <string.h>
00032 #include <unistd.h>
00033 #include <assert.h>
00034
00035 #include <polylib/polylib.h>
00036 #include <polylib/homogenization.h>
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #define EPRINT_ALL_VALIDITY_CONSTRAINTS
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 #define REDUCE_DEGREE
00089
00090
00091
00092
00093
00094 #define ALL_OVERFLOW_WARNINGS
00095
00096
00097
00098 int overflow_warning_flag = 1;
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 enode *new_enode(enode_type type,int size,int pos) {
00115
00116 enode *res;
00117 int i;
00118
00119 if(size == 0) {
00120 fprintf(stderr, "Allocating enode of size 0 !\n" );
00121 return NULL;
00122 }
00123 res = (enode *) malloc(sizeof(enode) + (size-1)*sizeof(evalue));
00124 res->type = type;
00125 res->size = size;
00126 res->pos = pos;
00127 for(i=0; i<size; i++) {
00128 value_init(res->arr[i].d);
00129 value_set_si(res->arr[i].d,0);
00130 res->arr[i].x.p = 0;
00131 }
00132 return res;
00133 }
00134
00135
00136
00137
00138
00139 void free_evalue_refs(evalue *e) {
00140
00141 enode *p;
00142 int i;
00143
00144 if (value_notzero_p(e->d)) {
00145
00146
00147 value_clear(e->d);
00148 value_clear(e->x.n);
00149 return;
00150 }
00151 value_clear(e->d);
00152 p = e->x.p;
00153 if (!p) return;
00154 for (i=0; i<p->size; i++) {
00155 free_evalue_refs(&(p->arr[i]));
00156 }
00157 free(p);
00158 return;
00159 }
00160
00161
00162
00163
00164
00165
00166
00167 enode *ecopy(enode *e) {
00168
00169 enode *res;
00170 int i;
00171
00172 res = new_enode(e->type,e->size,e->pos);
00173 for(i=0;i<e->size;++i) {
00174 value_assign(res->arr[i].d,e->arr[i].d);
00175 if(value_zero_p(res->arr[i].d))
00176 res->arr[i].x.p = ecopy(e->arr[i].x.p);
00177 else {
00178 value_init(res->arr[i].x.n);
00179 value_assign(res->arr[i].x.n,e->arr[i].x.n);
00180 }
00181 }
00182 return(res);
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192 void print_evalue(FILE *DST, evalue *e, const char **pname)
00193 {
00194 if(value_notzero_p(e->d)) {
00195 if(value_notone_p(e->d)) {
00196 value_print(DST,VALUE_FMT,e->x.n);
00197 fprintf(DST,"/");
00198 value_print(DST,VALUE_FMT,e->d);
00199 }
00200 else {
00201 value_print(DST,VALUE_FMT,e->x.n);
00202 }
00203 }
00204 else
00205 print_enode(DST,e->x.p,pname);
00206 return;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216 void print_enode(FILE *DST, enode *p, const char **pname)
00217 {
00218 int i;
00219
00220 if (!p) {
00221 fprintf(DST, "NULL");
00222 return;
00223 }
00224 if (p->type == evector) {
00225 fprintf(DST, "{ ");
00226 for (i=0; i<p->size; i++) {
00227 print_evalue(DST, &p->arr[i], pname);
00228 if (i!=(p->size-1))
00229 fprintf(DST, ", ");
00230 }
00231 fprintf(DST, " }\n");
00232 }
00233 else if (p->type == polynomial) {
00234 fprintf(DST, "( ");
00235 for (i=p->size-1; i>=0; i--) {
00236 print_evalue(DST, &p->arr[i], pname);
00237 if (i==1) fprintf(DST, " * %s + ", pname[p->pos-1]);
00238 else if (i>1)
00239 fprintf(DST, " * %s^%d + ", pname[p->pos-1], i);
00240 }
00241 fprintf(DST, " )\n");
00242 }
00243 else if (p->type == periodic) {
00244 fprintf(DST, "[ ");
00245 for (i=0; i<p->size; i++) {
00246 print_evalue(DST, &p->arr[i], pname);
00247 if (i!=(p->size-1)) fprintf(DST, ", ");
00248 }
00249 fprintf(DST," ]_%s", pname[p->pos-1]);
00250 }
00251 return;
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261 static int eequal(evalue *e1,evalue *e2) {
00262
00263 int i;
00264 enode *p1, *p2;
00265
00266 if (value_ne(e1->d,e2->d))
00267 return 0;
00268
00269
00270 if (value_notzero_p(e1->d)) {
00271 if (value_ne(e1->x.n,e2->x.n))
00272 return 0;
00273
00274
00275 return 1;
00276 }
00277
00278
00279 p1 = e1->x.p;
00280 p2 = e2->x.p;
00281 if (p1->type != p2->type) return 0;
00282 if (p1->size != p2->size) return 0;
00283 if (p1->pos != p2->pos) return 0;
00284 for (i=0; i<p1->size; i++)
00285 if (!eequal(&p1->arr[i], &p2->arr[i]) )
00286 return 0;
00287 return 1;
00288 }
00289
00290
00291
00292
00293
00294
00295 void reduce_evalue (evalue *e) {
00296
00297 enode *p;
00298 int i, j, k;
00299
00300 if (value_notzero_p(e->d))
00301 return;
00302 if(!(p = e->x.p))
00303 return;
00304
00305
00306 for (i=0; i<p->size; i++)
00307 reduce_evalue(&p->arr[i]);
00308
00309 if (p->type==periodic) {
00310
00311
00312 for (i=1; i<=(p->size)/2; i++) {
00313 if ((p->size % i)==0) {
00314
00315
00316 for (j=0; j<i; j++)
00317 for (k=j+i; k<e->x.p->size; k+=i)
00318 if (!eequal(&p->arr[j], &p->arr[k])) goto you_lose;
00319
00320
00321 for (j=i; j<p->size; j++) free_evalue_refs(&p->arr[j]);
00322 p->size = i;
00323 break;
00324
00325 you_lose:
00326 continue;
00327 }
00328 }
00329
00330
00331 if (p->size == 1) {
00332 value_clear(e->d);
00333 memcpy(e,&p->arr[0],sizeof(evalue));
00334 free(p);
00335 }
00336 }
00337 else if (p->type==polynomial) {
00338
00339
00340 for (i=p->size-1;i>=1;i--) {
00341 if (!(value_one_p(p->arr[i].d) && value_zero_p(p->arr[i].x.n)))
00342 break;
00343
00344 free_evalue_refs(&p->arr[i]);
00345 }
00346 if (i+1<p->size)
00347 p->size = i+1;
00348
00349
00350 if (p->size == 1) {
00351 value_clear(e->d);
00352 memcpy(e,&p->arr[0],sizeof(evalue));
00353 free(p);
00354 }
00355 }
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 static void emul (evalue *e1,evalue *e2,evalue *res) {
00369
00370 enode *p;
00371 int i;
00372 Value g;
00373
00374 if (value_zero_p(e2->d)) {
00375 fprintf(stderr, "emul: ?expecting constant value\n");
00376 return;
00377 }
00378 value_init(g);
00379 if (value_notzero_p(e1->d)) {
00380
00381 value_init(res->x.n);
00382
00383 value_multiply(res->d,e1->d,e2->d);
00384 value_multiply(res->x.n,e1->x.n,e2->x.n );
00385 value_gcd(g, res->x.n, res->d);
00386 if (value_notone_p(g)) {
00387 value_divexact(res->d, res->d, g);
00388 value_divexact(res->x.n, res->x.n, g);
00389 }
00390 }
00391 else {
00392 value_set_si(res->d,0);
00393 p = e1->x.p;
00394 res->x.p = new_enode(p->type, p->size, p->pos);
00395 for (i=0; i<p->size; i++) {
00396 emul(&p->arr[i], e2, &(res->x.p->arr[i]) );
00397 }
00398 }
00399 value_clear(g);
00400 return;
00401 }
00402
00403
00404
00405
00406
00407
00408
00409
00410 void eadd(evalue *e1,evalue *res) {
00411
00412 int i;
00413 Value g,m1,m2;
00414
00415 value_init(g);
00416 value_init(m1);
00417 value_init(m2);
00418
00419 if (value_notzero_p(e1->d) && value_notzero_p(res->d)) {
00420
00421
00422 value_multiply(m1,e1->x.n,res->d);
00423 value_multiply(m2,res->x.n,e1->d);
00424 value_addto(res->x.n,m1,m2);
00425 value_multiply(res->d,e1->d,res->d);
00426 value_gcd(g, res->x.n, res->d);
00427 if (value_notone_p(g)) {
00428 value_divexact(res->d, res->d, g);
00429 value_divexact(res->x.n, res->x.n, g);
00430 }
00431 value_clear(g); value_clear(m1); value_clear(m2);
00432 return;
00433 }
00434 else if (value_notzero_p(e1->d) && value_zero_p(res->d)) {
00435 if (res->x.p->type==polynomial) {
00436
00437
00438 eadd(e1, &res->x.p->arr[0]);
00439 value_clear(g); value_clear(m1); value_clear(m2);
00440 return;
00441 }
00442 else if (res->x.p->type==periodic) {
00443
00444
00445 for (i=0; i<res->x.p->size; i++) {
00446 eadd(e1, &res->x.p->arr[i]);
00447 }
00448 value_clear(g); value_clear(m1); value_clear(m2);
00449 return;
00450 }
00451 else {
00452 fprintf(stderr, "eadd: cannot add const with vector\n");
00453 value_clear(g); value_clear(m1); value_clear(m2);
00454 return;
00455 }
00456 }
00457 else if (value_zero_p(e1->d) && value_notzero_p(res->d)) {
00458 fprintf(stderr,"eadd: cannot add evalue to const\n");
00459 value_clear(g); value_clear(m1); value_clear(m2);
00460 return;
00461 }
00462 else {
00463 if ((e1->x.p->type != res->x.p->type) ||
00464 (e1->x.p->pos != res->x.p->pos )) {
00465 fprintf(stderr, "eadd: ?cannot add, incompatible types\n");
00466 value_clear(g); value_clear(m1); value_clear(m2);
00467 return;
00468 }
00469 if (e1->x.p->size == res->x.p->size) {
00470 for (i=0; i<res->x.p->size; i++) {
00471 eadd(&e1->x.p->arr[i], &res->x.p->arr[i]);
00472 }
00473 value_clear(g); value_clear(m1); value_clear(m2);
00474 return;
00475 }
00476
00477
00478 if (res->x.p->type==polynomial) {
00479
00480
00481
00482
00483
00484 if(e1->x.p->size > res->x.p->size) {
00485 enode *tmp;
00486 tmp = ecopy(e1->x.p);
00487 for(i=0;i<res->x.p->size;++i) {
00488 eadd(&res->x.p->arr[i], &tmp->arr[i]);
00489 free_evalue_refs(&res->x.p->arr[i]);
00490 }
00491 res->x.p = tmp;
00492 }
00493 else {
00494 for (i=0; i<e1->x.p->size ; i++) {
00495 eadd(&e1->x.p->arr[i], &res->x.p->arr[i]);
00496 }
00497 value_clear(g); value_clear(m1); value_clear(m2);
00498 return;
00499 }
00500 }
00501 else if (res->x.p->type==periodic) {
00502 fprintf(stderr, "eadd: ?addition of different sized periodic nos\n");
00503 value_clear(g); value_clear(m1); value_clear(m2);
00504 return;
00505 }
00506 else {
00507 fprintf(stderr, "eadd: ?cannot add vectors of different length\n");
00508 value_clear(g); value_clear(m1); value_clear(m2);
00509 return;
00510 }
00511 }
00512 value_clear(g); value_clear(m1); value_clear(m2);
00513 return;
00514 }
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 void edot(enode *v1,enode *v2,evalue *res) {
00527
00528 int i;
00529 evalue tmp;
00530
00531 if ((v1->type != evector) || (v2->type != evector)) {
00532 fprintf(stderr, "edot: ?expecting vectors\n");
00533 return;
00534 }
00535 if (v1->size != v2->size) {
00536 fprintf(stderr, "edot: ? vector lengths do not agree\n");
00537 return;
00538 }
00539 if (v1->size<=0) {
00540 value_set_si(res->d,1);
00541 value_init(res->x.n);
00542 value_set_si(res->x.n,0);
00543 return;
00544 }
00545
00546
00547
00548 emul(&v1->arr[0],&v2->arr[0],res);
00549 for (i=1; i<v1->size; i++) {
00550 value_init(tmp.d);
00551
00552
00553 emul(&v1->arr[i],&v2->arr[i],&tmp);
00554 eadd(&tmp,res);
00555 free_evalue_refs(&tmp);
00556 }
00557 return;
00558 }
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569 static void aep_evalue(evalue *e, int *ref) {
00570
00571 enode *p;
00572 int i;
00573
00574 if (value_notzero_p(e->d))
00575 return;
00576 if(!(p = e->x.p))
00577 return;
00578
00579
00580 for (i=0;i<p->size;i++)
00581 aep_evalue(&p->arr[i],ref);
00582
00583
00584 p->pos = ref[p->pos-1]+1;
00585 return;
00586 }
00587
00588
00589 static void addeliminatedparams_evalue(evalue *e,Matrix *CT) {
00590
00591 enode *p;
00592 int i, j;
00593 int *ref;
00594
00595 if (value_notzero_p(e->d))
00596 return;
00597 if(!(p = e->x.p))
00598 return;
00599
00600
00601 ref = (int *)malloc(sizeof(int)*(CT->NbRows-1));
00602 for(i=0;i<CT->NbRows-1;i++)
00603 for(j=0;j<CT->NbColumns;j++)
00604 if(value_notzero_p(CT->p[i][j])) {
00605 ref[i] = j;
00606 break;
00607 }
00608
00609
00610 aep_evalue(e,ref);
00611 free( ref );
00612 return;
00613 }
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 #define MAXITER 100
00636 int cherche_min(Value *min,Polyhedron *D,int pos) {
00637
00638 Value binf, bsup;
00639 Value i;
00640 int flag, maxiter;
00641
00642 if(!D)
00643 return(1);
00644 if(pos > D->Dimension)
00645 return(1);
00646
00647 value_init(binf); value_init(bsup);
00648 value_init(i);
00649
00650 #ifdef EDEBUG61
00651 fprintf(stderr,"Entering Cherche min --> \n");
00652 fprintf(stderr,"LowerUpperBounds :\n");
00653 fprintf(stderr,"pos = %d\n",pos);
00654 fprintf(stderr,"current min = (");
00655 value_print(stderr,P_VALUE_FMT,min[1]);
00656 {int j;
00657 for(j=2;j<=D->Dimension ; j++) {
00658 fprintf(stderr,", ");
00659 value_print(stderr,P_VALUE_FMT,min[j]);
00660 }
00661 }
00662 fprintf(stderr,")\n");
00663 #endif
00664
00665 flag = lower_upper_bounds(pos,D,min,&binf,&bsup);
00666
00667 #ifdef EDEBUG61
00668 fprintf(stderr, "flag = %d\n", flag);
00669 fprintf(stderr,"binf = ");
00670 value_print(stderr,P_VALUE_FMT,binf);
00671 fprintf(stderr,"\n");
00672 fprintf(stderr,"bsup = ");
00673 value_print(stderr,P_VALUE_FMT,bsup);
00674 fprintf(stderr,"\n");
00675 #endif
00676
00677 if(flag&LB_INFINITY)
00678 value_set_si(binf,0);
00679
00680
00681 for(maxiter=0,(((flag&LB_INFINITY) || value_neg_p(binf)) ?
00682 value_set_si(i,0) : value_assign(i,binf));
00683 ((flag&UB_INFINITY) || value_le(i,bsup)) && maxiter<MAXITER ;
00684 value_increment(i,i),maxiter++) {
00685
00686 value_assign(min[pos],i);
00687 if(cherche_min(min,D->next,pos+1)) {
00688 value_clear(binf); value_clear(bsup);
00689 value_clear(i);
00690 return(1);
00691 }
00692 }
00693
00694
00695 if((flag&LB_INFINITY) || value_neg_p(binf))
00696 for(maxiter=0,(((flag&UB_INFINITY) || value_pos_p(bsup))?
00697 value_set_si(i,-1)
00698 :value_assign(i,bsup));
00699 ((flag&LB_INFINITY) || value_ge(i,binf)) && maxiter<MAXITER ;
00700 value_decrement(i,i),maxiter++) {
00701
00702 value_assign(min[pos],i);
00703 if(cherche_min(min,D->next,pos+1)) {
00704 value_clear(binf); value_clear(bsup);
00705 value_clear(i);
00706 return(1);
00707 }
00708 }
00709 value_clear(binf); value_clear(bsup);
00710 value_clear(i);
00711
00712 value_set_si(min[pos],0);
00713 return(0);
00714 }
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744 Polyhedron *Polyhedron_Preprocess(Polyhedron *D,Value *size,unsigned MAXRAYS)
00745 {
00746 Matrix *M;
00747 int i, j, d;
00748 Polyhedron *T, *S, *H, *C;
00749 Value *min;
00750
00751 d = D->Dimension;
00752 if (MAXRAYS < 2*D->NbConstraints)
00753 MAXRAYS = 2*D->NbConstraints;
00754 M = Matrix_Alloc(MAXRAYS, D->Dimension+2);
00755 M->NbRows = D->NbConstraints;
00756
00757
00758 for(i=0;i<D->NbConstraints;i++)
00759 Vector_Copy(D->Constraint[i],M->p[i],(d+2));
00760
00761 #ifdef EDEBUG6
00762 fprintf(stderr,"M for PreProcess : ");
00763 Matrix_Print(stderr,P_VALUE_FMT,M);
00764 fprintf(stderr,"\nsize == ");
00765 for( i=0 ; i<d ; i++ )
00766 value_print(stderr,P_VALUE_FMT,size[i]);
00767 fprintf(stderr,"\n");
00768 #endif
00769
00770
00771 for(i=0;i<D->NbConstraints;i++) {
00772 if(value_zero_p(D->Constraint[i][0])) {
00773 fprintf(stderr,"Polyhedron_Preprocess: ");
00774 fprintf(stderr,
00775 "an equality was found where I did expect an inequality.\n");
00776 fprintf(stderr,"Trying to continue...\n");
00777 continue;
00778 }
00779 Vector_Copy(D->Constraint[i],M->p[M->NbRows],(d+2));
00780 for(j=1;j<=d;j++)
00781 if(value_neg_p(D->Constraint[i][j])) {
00782 value_addmul(M->p[M->NbRows][d+1], D->Constraint[i][j], size[j-1]);
00783 }
00784
00785
00786 if(value_ne(M->p[M->NbRows][d+1],D->Constraint[i][d+1]))
00787 M->NbRows ++ ;
00788 }
00789
00790 #ifdef EDEBUG6
00791 fprintf(stderr,"M used to find min : ");
00792 Matrix_Print(stderr,P_VALUE_FMT,M);
00793 #endif
00794
00795 T = Constraints2Polyhedron(M,MAXRAYS);
00796 Matrix_Free(M);
00797 if (!T || emptyQ(T)) {
00798 if(T)
00799 Polyhedron_Free(T);
00800 return(NULL);
00801 }
00802
00803
00804 min = (Value *) malloc(sizeof(Value) * (d+2));
00805 for(i=0;i<=d;i++) {
00806 value_init(min[i]);
00807 value_set_si(min[i],0);
00808 }
00809 value_init(min[i]);
00810 value_set_si(min[i],1);
00811 C = Universe_Polyhedron(0);
00812 S = Polyhedron_Scan(T,C,MAXRAYS);
00813 Polyhedron_Free(C);
00814 Polyhedron_Free(T);
00815
00816 #ifdef EDEBUG6
00817 for(i=0;i<=(d+1);i++) {
00818 value_print(stderr,P_VALUE_FMT,min[i]);
00819 fprintf(stderr," ,");
00820 }
00821 fprintf(stderr,"\n");
00822 Polyhedron_Print(stderr,P_VALUE_FMT,S);
00823 fprintf(stderr,"\n");
00824 #endif
00825
00826 if (!cherche_min(min,S,1))
00827 {
00828 for(i=0;i<=(d+1);i++)
00829 value_clear(min[i]);
00830 return(NULL);
00831 }
00832 Domain_Free(S);
00833
00834 #ifdef EDEBUG6
00835 fprintf(stderr,"min = ( ");
00836 value_print(stderr,P_VALUE_FMT,min[1]);
00837 for(i=2;i<=d;i++) {
00838 fprintf(stderr,", ");
00839 value_print(stderr,P_VALUE_FMT,min[i]);
00840 }
00841 fprintf(stderr,")\n");
00842 #endif
00843
00844
00845 M = Matrix_Alloc(d*2,d+2);
00846 for(i=0;i<d;i++) {
00847
00848
00849 value_set_si(M->p[2*i][0],1);
00850 for(j=1;j<=d;j++)
00851 value_set_si(M->p[2*i][j],0);
00852 value_set_si(M->p[2*i][i+1],1);
00853 value_oppose(M->p[2*i][d+1],min[i+1]);
00854
00855
00856 value_set_si(M->p[2*i+1][0],1);
00857 for(j=1;j<=d;j++)
00858 value_set_si(M->p[2*i+1][j],0);
00859 value_set_si(M->p[2*i+1][i+1],-1);
00860 value_addto(M->p[2*i+1][d+1],min[i+1],size[i]);
00861 value_sub_int(M->p[2*i+1][d+1],M->p[2*i+1][d+1],1);
00862 }
00863
00864 #ifdef EDEBUG6
00865 fprintf(stderr,"PolyhedronPreprocess: constraints H = ");
00866 Matrix_Print(stderr,P_VALUE_FMT,M);
00867 #endif
00868
00869 H = Constraints2Polyhedron(M,MAXRAYS);
00870
00871 #ifdef EDEBUG6
00872 Polyhedron_Print(stderr,P_VALUE_FMT,H);
00873 fprintf(stderr,"\n");
00874 #endif
00875
00876 Matrix_Free(M);
00877 for(i=0;i<=(d+1);i++)
00878 value_clear(min[i]);
00879 free(min);
00880 assert(!emptyQ(H));
00881 return(H);
00882 }
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899 Polyhedron *Polyhedron_Preprocess2(Polyhedron *D,Value *size,
00900 Value *lcm,unsigned MAXRAYS) {
00901
00902 Matrix *c;
00903 Polyhedron *H;
00904 int i,j,r;
00905 Value n;
00906 Value s;
00907 Value tmp1,tmp2;
00908
00909 #ifdef EDEBUG62
00910 int np;
00911 #endif
00912
00913 value_init(n); value_init(s);
00914 value_init(tmp1); value_init(tmp2);
00915 c = Matrix_Alloc(D->Dimension*2,D->Dimension+2);
00916
00917 #ifdef EDEBUG62
00918 fprintf(stderr,"\nPreProcess2 : starting\n");
00919 fprintf(stderr,"lcm = ");
00920 for( np=0 ; np<D->Dimension; np++ )
00921 value_print(stderr,VALUE_FMT,lcm[np]);
00922 fprintf(stderr,", size = ");
00923 for( np=0 ; np<D->Dimension; np++ )
00924 value_print(stderr,VALUE_FMT,size[np]);
00925 fprintf(stderr,"\n");
00926 #endif
00927
00928 for(i=0;i<D->Dimension;i++) {
00929
00930
00931 value_set_si(c->p[2*i][0],1);
00932 for(j=0;j<D->Dimension;j++)
00933 value_set_si(c->p[2*i][1+j],0);
00934 value_division(n,D->Ray[0][i+1],D->Ray[0][D->Dimension+1]);
00935 for(r=1;r<D->NbRays;r++) {
00936 value_division(tmp1,D->Ray[r][i+1],D->Ray[r][D->Dimension+1]);
00937 if(value_gt(n,tmp1)) {
00938
00939
00940 value_division(n,D->Ray[r][i+1],D->Ray[r][D->Dimension+1]);
00941 }
00942 }
00943 value_set_si(c->p[2*i][i+1],1);
00944 value_oppose(c->p[2*i][D->Dimension+1],n);
00945
00946
00947 value_set_si(c->p[2*i+1][0],1);
00948 for(j=0;j<D->Dimension;j++)
00949 value_set_si(c->p[2*i+1][1+j],0);
00950
00951
00952 value_addto(tmp1,D->Ray[0][i+1],D->Ray[0][D->Dimension+1]);
00953 value_sub_int(tmp1,tmp1,1);
00954 value_division(n,tmp1,D->Ray[0][D->Dimension+1]);
00955 for(r=1;r<D->NbRays;r++) {
00956 value_addto(tmp1,D->Ray[r][i+1],D->Ray[r][D->Dimension+1]);
00957 value_sub_int(tmp1,tmp1,1);
00958 value_division(tmp1,tmp1,D->Ray[r][D->Dimension+1]);
00959 if (value_lt(n,tmp1)) {
00960
00961
00962 value_addto(tmp1,D->Ray[r][i+1],D->Ray[r][D->Dimension+1]);
00963 value_sub_int(tmp1,tmp1,1);
00964 value_division(n,tmp1,D->Ray[r][D->Dimension+1]);
00965 }
00966 }
00967 value_set_si(c->p[2*i+1][i+1],-1);
00968 value_assign(c->p[2*i+1][D->Dimension+1],n);
00969 value_addto(s,c->p[2*i+1][D->Dimension+1],c->p[2*i][D->Dimension+1]);
00970
00971
00972 if(value_gt(s,size[i])) {
00973
00974 #ifdef EDEBUG62
00975 fprintf(stderr,"size on dimension %d\n",i);
00976 fprintf(stderr,"lcm = ");
00977 for( np=0 ; np<D->Dimension; np++ )
00978 value_print(stderr,VALUE_FMT,lcm[np]);
00979 fprintf(stderr,", size = ");
00980 for( np=0 ; np<D->Dimension; np++ )
00981 value_print(stderr,VALUE_FMT,size[np]);
00982 fprintf(stderr,"\n");
00983 fprintf(stderr,"required size (s) = ");
00984 value_print(stderr,VALUE_FMT,s);
00985 fprintf(stderr,"\n");
00986 #endif
00987
00988
00989
00990
00991 value_set_si(tmp1,20);
00992 value_addto(tmp2,size[i],size[i]);
00993 if(value_le(s,tmp1)
00994 || value_le(s,tmp2)) {
00995
00996 if( value_zero_p(lcm[i]) )
00997 value_set_si(lcm[i],1);
00998
00999 value_division(tmp1,size[i],lcm[i]);
01000
01001
01002 value_addto(tmp2,s,tmp1);
01003 value_add_int(tmp2,tmp2,1);
01004 value_division(lcm[i],tmp2,tmp1);
01005
01006
01007 value_multiply(size[i],lcm[i],tmp1);
01008
01009 #ifdef EDEBUG62
01010 fprintf(stderr,"new size = ");
01011 for( np=0 ; np<D->Dimension; np++ )
01012 value_print(stderr,VALUE_FMT,size[np]);
01013 fprintf(stderr,", new lcm = ");
01014 for( np=0 ; np<D->Dimension; np++ )
01015 value_print(stderr,VALUE_FMT,lcm[np]);
01016 fprintf(stderr,"\n");
01017 #endif
01018
01019 }
01020 else {
01021
01022 #ifdef EDEBUG62
01023 fprintf(stderr,"Failed on dimension %d.\n",i);
01024 #endif
01025 break;
01026 }
01027 }
01028 }
01029 if(i!=D->Dimension) {
01030 Matrix_Free(c);
01031 value_clear(n); value_clear(s);
01032 value_clear(tmp1); value_clear(tmp2);
01033 return(NULL);
01034 }
01035 for(i=0;i<D->Dimension;i++) {
01036 value_subtract(c->p[2*i+1][D->Dimension+1],size[i],
01037 c->p[2*i][D->Dimension+1]);
01038 }
01039
01040 #ifdef EDEBUG62
01041 fprintf(stderr,"PreProcess2 : c =");
01042 Matrix_Print(stderr,P_VALUE_FMT,c);
01043 #endif
01044
01045 H = Constraints2Polyhedron(c,MAXRAYS);
01046 Matrix_Free(c);
01047 value_clear(n); value_clear(s);
01048 value_clear(tmp1); value_clear(tmp2);
01049 return(H);
01050 }
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063 Polyhedron *old_Polyhedron_Preprocess(Polyhedron *D,Value size,
01064 unsigned MAXRAYS) {
01065
01066 int p, p1, ub, lb;
01067 Value a, a1, b, b1, g, aa;
01068 Value abs_a, abs_b, size_copy;
01069 int dim, con, newi, needed;
01070 Value **C;
01071 Matrix *M;
01072 Polyhedron *D1;
01073
01074 value_init(a); value_init(a1); value_init(b);
01075 value_init(b1); value_init(g); value_init(aa);
01076 value_init(abs_a); value_init(abs_b); value_init(size_copy);
01077
01078 dim = D->Dimension;
01079 con = D->NbConstraints;
01080 M = Matrix_Alloc(MAXRAYS,dim+2);
01081 newi = 0;
01082 value_assign(size_copy,size);
01083 C = D->Constraint;
01084 for (p=1; p<=dim; p++) {
01085 for (ub=0; ub<con; ub++) {
01086 value_assign(a,C[ub][p]);
01087 if (value_posz_p(a))
01088 continue;
01089 for (lb=0;lb<con;lb++) {
01090 value_assign(b,C[lb][p]);
01091 if (value_negz_p(b))
01092 continue;
01093
01094
01095
01096
01097 needed=0;
01098 for (p1=1; p1<p; p1++) {
01099 if (value_notzero_p(C[ub][p1]) ||
01100 value_notzero_p(C[lb][p1])) {
01101 needed=1;
01102 break;
01103 }
01104 }
01105 if (!needed) continue;
01106 value_absolute(abs_a,a);
01107 value_absolute(abs_b,b);
01108
01109
01110 value_gcd(g, abs_a, abs_b);
01111 value_divexact(a1, a, g);
01112 value_divexact(b1, b, g);
01113 value_set_si(M->p[newi][0],1);
01114 value_oppose(abs_a,a1);
01115 Vector_Combine(&(C[ub][1]),&(C[lb][1]),&(M->p[newi][1]),
01116 b1,abs_a,dim+1);
01117 value_multiply(aa,a1,b1);
01118 value_addmul(M->p[newi][dim+1], aa, size_copy);
01119 Vector_Normalize(&(M->p[newi][1]),(dim+1));
01120 newi++;
01121 }
01122 }
01123 }
01124 D1 = AddConstraints(M->p_Init,newi,D,MAXRAYS);
01125 Matrix_Free(M);
01126
01127 value_clear(a); value_clear(a1); value_clear(b);
01128 value_clear(b1); value_clear(g); value_clear(aa);
01129 value_clear(abs_a); value_clear(abs_b); value_clear(size_copy);
01130 return D1;
01131 }
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145 void count_points (int pos,Polyhedron *P,Value *context, Value *res) {
01146
01147 Value LB, UB, k, c;
01148
01149 POL_ENSURE_FACETS(P);
01150 POL_ENSURE_VERTICES(P);
01151
01152 if (emptyQ(P)) {
01153 value_set_si(*res, 0);
01154 return;
01155 }
01156
01157 value_init(LB); value_init(UB); value_init(k);
01158 value_set_si(LB,0);
01159 value_set_si(UB,0);
01160
01161 if (lower_upper_bounds(pos,P,context,&LB,&UB) !=0) {
01162
01163
01164 fprintf(stderr, "count_points: ? infinite domain\n");
01165 value_clear(LB); value_clear(UB); value_clear(k);
01166 value_set_si(*res, -1);
01167 return;
01168 }
01169
01170 #ifdef EDEBUG1
01171 if (!P->next) {
01172 int i;
01173 for (value_assign(k,LB); value_le(k,UB); value_increment(k,k)) {
01174 fprintf(stderr, "(");
01175 for (i=1; i<pos; i++) {
01176 value_print(stderr,P_VALUE_FMT,context[i]);
01177 fprintf(stderr,",");
01178 }
01179 value_print(stderr,P_VALUE_FMT,k);
01180 fprintf(stderr,")\n");
01181 }
01182 }
01183 #endif
01184
01185 value_set_si(context[pos],0);
01186 if (value_lt(UB,LB)) {
01187 value_clear(LB); value_clear(UB); value_clear(k);
01188 value_set_si(*res, 0);
01189 return;
01190 }
01191 if (!P->next) {
01192 value_subtract(k,UB,LB);
01193 value_add_int(k,k,1);
01194 value_assign(*res, k);
01195 value_clear(LB); value_clear(UB); value_clear(k);
01196 return;
01197 }
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 value_init(c);
01209 value_set_si(*res, 0);
01210 for (value_assign(k,LB);value_le(k,UB);value_increment(k,k)) {
01211
01212 value_assign(context[pos],k);
01213 count_points(pos+1,P->next,context,&c);
01214 if(value_notmone_p(c))
01215 value_addto(*res, *res, c);
01216 else {
01217 value_set_si(*res, -1);
01218 break;
01219 }
01220 }
01221 value_clear(c);
01222
01223 #ifdef EDEBUG11
01224 fprintf(stderr,"%d\n",CNT);
01225 #endif
01226
01227
01228 value_set_si(context[pos],0);
01229 value_clear(LB); value_clear(UB); value_clear(k);
01230 return;
01231 }
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246 static enode *P_Enum(Polyhedron *L,Polyhedron *LQ,Value *context,int pos,
01247 int nb_param,int dim,Value *lcm, const char **param_name)
01248 {
01249 enode *res,*B,*C;
01250 int hdim,i,j,rank,flag;
01251 Value n,g,nLB,nUB,nlcm,noff,nexp,k1,nm,hdv,k,lcm_copy;
01252 Value tmp;
01253 Matrix *A;
01254
01255 #ifdef EDEBUG
01256 fprintf(stderr,"-------------------- begin P_Enum -------------------\n");
01257 fprintf(stderr,"Calling P_Enum with pos = %d\n",pos);
01258 #endif
01259
01260
01261 value_init(n); value_init(g); value_init(nLB);
01262 value_init(nUB); value_init(nlcm); value_init(noff);
01263 value_init(nexp); value_init(k1); value_init(nm);
01264 value_init(hdv); value_init(k); value_init(tmp);
01265 value_init(lcm_copy);
01266
01267 if( value_zero_p(lcm[pos-1]) )
01268 {
01269 hdim = 1;
01270 value_set_si( lcm_copy, 1 );
01271 }
01272 else
01273 {
01274
01275 hdim = dim-nb_param+1;
01276 value_assign( lcm_copy, lcm[pos-1] );
01277 }
01278
01279
01280
01281 flag = lower_upper_bounds(pos,LQ,&context[dim-nb_param],&nLB,&nUB);
01282 if (flag & LB_INFINITY) {
01283 if (!(flag & UB_INFINITY)) {
01284
01285
01286
01287 value_sub_int(nLB,nUB,1);
01288 value_set_si(hdv,hdim);
01289 value_multiply(tmp,hdv,lcm_copy);
01290 value_subtract(nLB,nLB,tmp);
01291 if(value_pos_p(nLB))
01292 value_set_si(nLB,0);
01293 }
01294 else {
01295 value_set_si(nLB,0);
01296
01297
01298 value_set_si(hdv,hdim);
01299 value_multiply(nUB,hdv,lcm_copy);
01300 value_add_int(nUB,nUB,1);
01301 }
01302 }
01303
01304
01305
01306
01307
01308
01309
01310 #ifdef REDUCE_DEGREE
01311 if (pos==1 && (flag & UB_INFINITY)==0) {
01312
01313
01314
01315
01316 #ifdef EDEBUG
01317 fprintf(stderr,"*************** n **********\n");
01318 value_print(stderr,VALUE_FMT,n);
01319 fprintf(stderr,"\n");
01320 #endif
01321
01322 value_subtract(n,nUB,nLB);
01323 value_increment(n,n);
01324
01325 #ifdef EDEBUG
01326 value_print(stderr,VALUE_FMT,n);
01327 fprintf(stderr,"\n*************** n ************\n");
01328 #endif
01329
01330
01331 if(value_neg_p(n))
01332 i=0;
01333 else {
01334 value_modulus(tmp,n,lcm_copy);
01335 if(value_notzero_p(tmp)) {
01336 value_division(tmp,n,lcm_copy);
01337 value_increment(tmp,tmp);
01338 i = VALUE_TO_INT(tmp);
01339 }
01340 else {
01341 value_division(tmp,n,lcm_copy);
01342 i = VALUE_TO_INT(tmp);
01343 }
01344 }
01345
01346 #ifdef EDEBUG
01347 value_print(stderr,VALUE_FMT,n);
01348 fprintf(stderr,"\n*************** n ************\n");
01349 #endif
01350
01351
01352 if (i < hdim){
01353 hdim=i;
01354
01355 #ifdef EDEBUG4
01356 fprintf(stdout,"Parameter #%d: LB=",pos);
01357 value_print(stdout,VALUE_FMT,nLB);
01358 fprintf(stdout," UB=");
01359 value_print(stdout,VALUE_FMT,nUB);
01360 fprintf(stdout," lcm=");
01361 value_print(stdout,VALUE_FMT,lcm_copy);
01362 fprintf(stdout," degree reduced to %d\n",hdim-1);
01363 #endif
01364
01365 }
01366 }
01367 #endif
01368
01369
01370
01371 res = new_enode(polynomial,hdim,pos);
01372 for (i=0;i<hdim;i++) {
01373 int l;
01374 l = VALUE_TO_INT(lcm_copy);
01375 res->arr[i].x.p = new_enode(periodic,l,pos);
01376 }
01377
01378
01379 A = Matrix_Alloc(hdim, 2*hdim+1);
01380 B = new_enode(evector, hdim, 0);
01381 C = new_enode(evector, hdim, 0);
01382
01383
01384 for (j = 0; j < hdim; ++j)
01385 free_evalue_refs(&C->arr[j]);
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396 if(value_neg_p(nLB)) {
01397 value_modulus(nlcm,nLB,lcm_copy);
01398 value_addto(nlcm,nlcm,lcm_copy);
01399 }
01400 else {
01401 value_modulus(nlcm,nLB,lcm_copy);
01402 }
01403
01404
01405 value_subtract(noff,nLB,nlcm);
01406 value_addto(tmp,lcm_copy,nlcm);
01407 for (value_assign(k,nlcm);value_lt(k,tmp);) {
01408
01409 #ifdef EDEBUG
01410 fprintf(stderr,"Finding ");
01411 value_print(stderr,VALUE_FMT,k);
01412 fprintf(stderr,"-th elements of periodic coefficients\n");
01413 #endif
01414
01415 value_set_si(hdv,hdim);
01416 value_multiply(nm,hdv,lcm_copy);
01417 value_addto(nm,nm,nLB);
01418 i=0;
01419 for (value_addto(n,k,noff); value_lt(n,nm);
01420 value_addto(n,n,lcm_copy),i++) {
01421
01422
01423
01424
01425
01426 #ifdef ALL_OVERFLOW_WARNINGS
01427 if (((flag & UB_INFINITY)==0) && value_gt(n,nUB)) {
01428 fprintf(stdout,"Domain Overflow: Parameter #%d:",pos);
01429 fprintf(stdout,"nLB=");
01430 value_print(stdout,VALUE_FMT,nLB);
01431 fprintf(stdout," n=");
01432 value_print(stdout,VALUE_FMT,n);
01433 fprintf(stdout," nUB=");
01434 value_print(stdout,VALUE_FMT,nUB);
01435 fprintf(stdout,"\n");
01436 }
01437 #else
01438 if (overflow_warning_flag && ((flag & UB_INFINITY)==0) &&
01439 value_gt(n,nUB)) {
01440 fprintf(stdout,"\nWARNING: Parameter Domain Overflow.");
01441 fprintf(stdout," Result may be incorrect on this domain.\n");
01442 overflow_warning_flag = 0;
01443 }
01444 #endif
01445
01446
01447 value_assign(context[dim-nb_param+pos],n);
01448
01449 #ifdef EDEBUG1
01450 if( param_name )
01451 {
01452 fprintf(stderr,"%s = ",param_name[pos-1]);
01453 value_print(stderr,VALUE_FMT,n);
01454 fprintf(stderr," (hdim=%d, lcm[%d]=",hdim,pos-1);
01455 value_print(stderr,VALUE_FMT,lcm_copy);
01456 fprintf(stderr,")\n");
01457 }
01458 else
01459 {
01460 fprintf(stderr,"P%d = ",pos);
01461 value_print(stderr,VALUE_FMT,n);
01462 fprintf(stderr," (hdim=%d, lcm[%d]=",hdim,pos-1);
01463 value_print(stderr,VALUE_FMT,lcm_copy);
01464 fprintf(stderr,")\n");
01465 }
01466 #endif
01467
01468
01469 if (pos==nb_param) {
01470
01471 #ifdef EDEBUG
01472 fprintf(stderr,"Yes\n");
01473 #endif
01474
01475
01476
01477 value_set_si(B->arr[i].d,1);
01478 value_init(B->arr[i].x.n);
01479 count_points(1,L,context,&B->arr[i].x.n);
01480
01481 #ifdef EDEBUG3
01482 for (j=1; j<pos; j++) fputs(" ",stdout);
01483 fprintf(stdout, "E(");
01484 for (j=1; j<nb_param; j++) {
01485 value_print(stdout,VALUE_FMT,context[dim-nb_param+j]);
01486 fprintf(stdout,",");
01487 }
01488 value_print(stdout,VALUE_FMT,n);
01489 fprintf(stdout,") = ");
01490 value_print(stdout,VALUE_FMT,B->arr[i].x.n);
01491 fprintf(stdout," =");
01492 #endif
01493
01494 }
01495 else {
01496
01497 value_set_si(B->arr[i].d,0);
01498 B->arr[i].x.p = P_Enum(L,LQ->next,context,pos+1,
01499 nb_param,dim,lcm,param_name);
01500
01501 #ifdef EDEBUG3
01502 if( param_name )
01503 {
01504 for (j=1; j<pos; j++)
01505 fputs(" ", stdout);
01506 fprintf(stdout, "E(");
01507 for (j=1; j<=pos; j++) {
01508 value_print(stdout,VALUE_FMT,context[dim-nb_param+j]);
01509 fprintf(stdout,",");
01510 }
01511 for (j=pos+1; j<nb_param; j++)
01512 fprintf(stdout,"%s,",param_name[j]);
01513 fprintf(stdout,"%s) = ",param_name[j]);
01514 print_enode(stdout,B->arr[i].x.p,param_name);
01515 fprintf(stdout," =");
01516 }
01517 #endif
01518
01519 }
01520
01521
01522
01523
01524 value_set_si(A->p[i][0],0);
01525 value_set_si(nexp,1);
01526 for (j=1;j<=hdim;j++) {
01527 value_assign(A->p[i][j],nexp);
01528 value_set_si(A->p[i][j+hdim],0);
01529
01530 #ifdef EDEBUG3
01531 fprintf(stdout," + ");
01532 value_print(stdout,VALUE_FMT,nexp);
01533 fprintf(stdout," c%d",j);
01534 #endif
01535 value_multiply(nexp,nexp,n);
01536 }
01537
01538 #ifdef EDEBUG3
01539 fprintf(stdout, "\n");
01540 #endif
01541
01542 value_set_si(A->p[i][i+1+hdim],1);
01543 }
01544
01545
01546 if (i!=hdim)
01547 fprintf(stderr, "P_Enum: ?expecting i==hdim\n");
01548
01549 #ifdef EDEBUG
01550 if( param_name )
01551 {
01552 fprintf(stderr,"B (enode) =\n");
01553 print_enode(stderr,B,param_name);
01554 }
01555 fprintf(stderr,"A (Before Gauss) =\n");
01556 Matrix_Print(stderr,P_VALUE_FMT,A);
01557 #endif
01558
01559
01560 rank = Gauss(A,hdim,2*hdim);
01561
01562 #ifdef EDEBUG
01563 fprintf(stderr,"A (After Gauss) =\n");
01564 Matrix_Print(stderr,P_VALUE_FMT,A);
01565 #endif
01566
01567
01568 if (rank!=hdim) {
01569 fprintf(stderr, "P_Enum: ?expecting rank==hdim\n");
01570 }
01571
01572
01573
01574
01575 if(value_lt(k,lcm_copy))
01576 value_assign(k1,k);
01577 else
01578 value_subtract(k1,k,lcm_copy);
01579
01580 for (i=0; i<rank; i++) {
01581
01582
01583 for (j=0; j<rank; j++) {
01584 value_gcd(g, A->p[i][i+1], A->p[i][j+1+hdim]);
01585 value_init(C->arr[j].d);
01586 value_divexact(C->arr[j].d, A->p[i][i+1], g);
01587 value_init(C->arr[j].x.n);
01588 value_divexact(C->arr[j].x.n, A->p[i][j+1+hdim], g);
01589 }
01590
01591 #ifdef EDEBUG
01592 if( param_name )
01593 {
01594 fprintf(stderr, "C (enode) =\n");
01595 print_enode(stderr, C, param_name);
01596 }
01597 #endif
01598
01599
01600 edot(B,C,&(res->arr[i].x.p->arr[VALUE_TO_INT(k1)]));
01601
01602 #ifdef EDEBUG
01603 if( param_name )
01604 {
01605 fprintf(stderr, "B.C (evalue)=\n");
01606 print_evalue(stderr,&(res->arr[i].x.p->arr[VALUE_TO_INT(k1)]),
01607 param_name);
01608 fprintf(stderr,"\n");
01609 }
01610 #endif
01611
01612 for (j = 0; j < rank; ++j)
01613 free_evalue_refs(&C->arr[j]);
01614 }
01615 value_addto(tmp,lcm_copy,nlcm);
01616
01617 value_increment(k,k);
01618 for (i = 0; i < hdim; ++i) {
01619 free_evalue_refs(&B->arr[i]);
01620 if (value_lt(k,tmp))
01621 value_init(B->arr[i].d);
01622 }
01623 }
01624
01625 #ifdef EDEBUG
01626 if( param_name )
01627 {
01628 fprintf(stderr,"res (enode) =\n");
01629 print_enode(stderr,res,param_name);
01630 }
01631 fprintf(stderr, "-------------------- end P_Enum -----------------------\n");
01632 #endif
01633
01634
01635 value_set_si(context[dim-nb_param+pos],0);
01636
01637
01638 Matrix_Free(A);
01639 free(B);
01640 free(C);
01641
01642
01643 value_clear(n); value_clear(g); value_clear(nLB);
01644 value_clear(nUB); value_clear(nlcm); value_clear(noff);
01645 value_clear(nexp); value_clear(k1); value_clear(nm);
01646 value_clear(hdv); value_clear(k); value_clear(tmp);
01647 value_clear(lcm_copy);
01648 return res;
01649 }
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660 static void Scan_Vertices(Param_Polyhedron *PP,Param_Domain *Q,Matrix *CT,
01661 Value *lcm, int nbp, const char **param_name)
01662 {
01663 Param_Vertices *V;
01664 int i, j, ix, l, np;
01665 unsigned bx;
01666 Value k,m1;
01667
01668
01669
01670
01671
01672 value_init(k); value_init(m1);
01673 for( np=0 ; np<nbp ; np++ )
01674 value_set_si( lcm[np], 0 );
01675
01676 if( param_name )
01677 fprintf(stdout,"Vertices:\n");
01678
01679 for(i=0,ix=0,bx=MSB,V=PP->V; V && i<PP->nbV; i++,V=V->next) {
01680 if (Q->F[ix] & bx) {
01681 if( param_name )
01682 {
01683 if(CT) {
01684 Matrix *v;
01685 v = VertexCT(V->Vertex,CT);
01686 Print_Vertex(stdout,v,param_name);
01687 Matrix_Free(v);
01688 }
01689 else
01690 Print_Vertex(stdout,V->Vertex,param_name);
01691 fprintf(stdout,"\n");
01692 }
01693
01694 for(j=0;j<V->Vertex->NbRows;j++) {
01695
01696 for( l=0 ; l<V->Vertex->NbColumns-1 ; l++ )
01697 {
01698 if( value_notzero_p(V->Vertex->p[j][l]) )
01699 {
01700 value_gcd(m1, V->Vertex->p[j][V->Vertex->NbColumns-1],
01701 V->Vertex->p[j][l]);
01702 value_divexact(k, V->Vertex->p[j][V->Vertex->NbColumns-1], m1);
01703 if( value_notzero_p(lcm[l]) )
01704 {
01705
01706 if (value_notzero_p(k) && value_notone_p(k))
01707 {
01708 value_gcd(m1, lcm[l], k);
01709 value_divexact(k, k, m1);
01710 value_multiply(lcm[l],lcm[l],k);
01711 }
01712 }
01713 else
01714 {
01715 value_assign(lcm[l],k);
01716 }
01717 }
01718 }
01719 }
01720 }
01721 NEXT(ix,bx);
01722 }
01723 value_clear(k); value_clear(m1);
01724 }
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738 Enumeration *Enumerate_NoParameters(Polyhedron *P,Polyhedron *C,
01739 Matrix *CT,Polyhedron *CEq,
01740 unsigned MAXRAYS, const char **param_name)
01741 {
01742 Polyhedron *L;
01743 Enumeration *res;
01744 Value *context;
01745 int j;
01746 int hdim = P->Dimension + 1;
01747 int r,i;
01748
01749
01750 context = (Value *) malloc((hdim+1)*sizeof(Value));
01751 for (j=0;j<= hdim;j++)
01752 value_init(context[j]);
01753
01754 res = (Enumeration *)malloc(sizeof(Enumeration));
01755 res->next = NULL;
01756 res->ValidityDomain = Universe_Polyhedron(0);
01757 value_init(res->EP.d);
01758 value_set_si(res->EP.d,0);
01759 L = Polyhedron_Scan(P,res->ValidityDomain,MAXRAYS);
01760
01761 #ifdef EDEBUG2
01762 fprintf(stderr, "L = \n");
01763 Polyhedron_Print(stderr, P_VALUE_FMT, L);
01764 #endif
01765
01766 if(CT) {
01767 Polyhedron *Dt;
01768
01769
01770 Dt = Polyhedron_Preimage(res->ValidityDomain,CT,MAXRAYS);
01771 Polyhedron_Free(res->ValidityDomain);
01772 res->ValidityDomain = DomainIntersection(Dt,CEq,MAXRAYS);
01773 Polyhedron_Free(Dt);
01774 }
01775
01776 if( param_name )
01777 {
01778 fprintf(stdout,"---------------------------------------\n");
01779 fprintf(stdout,"Domain:\n");
01780 Print_Domain(stdout,res->ValidityDomain, param_name);
01781
01782
01783 printf("Vertices:\n");
01784 for(r=0;r<P->NbRays;++r) {
01785 if(value_zero_p(P->Ray[r][0]))
01786 printf("(line) ");
01787 printf("[");
01788 if (P->Dimension > 0)
01789 value_print(stdout,P_VALUE_FMT,P->Ray[r][1]);
01790 for(i=1;i<P->Dimension;i++) {
01791 printf(", ");
01792 value_print(stdout,P_VALUE_FMT,P->Ray[r][i+1]);
01793 }
01794 printf("]");
01795 if(value_notone_p(P->Ray[r][P->Dimension+1])) {
01796 printf("/");
01797 value_print(stdout,P_VALUE_FMT, P->Ray[r][P->Dimension+1]);
01798 }
01799 printf("\n");
01800 }
01801 }
01802
01803 res->EP.x.p = new_enode(polynomial,1,0);;
01804 value_set_si(res->EP.x.p->arr[0].d, 1);
01805 value_init(res->EP.x.p->arr[0].x.n);
01806
01807 if (emptyQ(P)) {
01808 value_set_si(res->EP.x.p->arr[0].x.n, 0);
01809 } else if (!L) {
01810
01811 value_set_si(res->EP.x.p->arr[0].x.n, 1);
01812 } else {
01813 CATCH(overflow_error) {
01814 fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
01815 fprintf(stderr,"You should rebuild PolyLib using GNU-MP"
01816 " or increasing the size of integers.\n");
01817 overflow_warning_flag = 0;
01818 assert(overflow_warning_flag);
01819 }
01820 TRY {
01821
01822 Vector_Set(context,0,(hdim+1));
01823
01824
01825 value_set_si(context[hdim],1);
01826 count_points(1, L, context, &res->EP.x.p->arr[0].x.n);
01827 UNCATCH(overflow_error);
01828 }
01829 }
01830
01831 Domain_Free(L);
01832
01833
01834
01835
01836
01837
01838 if( param_name )
01839 {
01840 fprintf(stdout,"\nEhrhart Polynomial:\n");
01841 print_evalue(stdout,&res->EP,param_name);
01842 fprintf(stdout, "\n");
01843 }
01844
01845 for (j=0;j<= hdim;j++)
01846 value_clear(context[j]);
01847 free(context);
01848 return(res);
01849 }
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860 Enumeration *Polyhedron_Enumerate(Polyhedron *Pi,Polyhedron *C,
01861 unsigned MAXRAYS, const char **param_name)
01862 {
01863 Polyhedron *L, *CQ, *CQ2, *LQ, *U, *CEq, *rVD, *P, *Ph = NULL;
01864 Matrix *CT;
01865 Param_Polyhedron *PP;
01866 Param_Domain *Q;
01867 int i,hdim, dim, nb_param, np;
01868 Value *lcm, *m1, hdv;
01869 Value *context;
01870 Enumeration *en, *res;
01871
01872 if (POL_ISSET(MAXRAYS, POL_NO_DUAL))
01873 MAXRAYS = 0;
01874
01875 POL_ENSURE_FACETS(Pi);
01876 POL_ENSURE_VERTICES(Pi);
01877 POL_ENSURE_FACETS(C);
01878 POL_ENSURE_VERTICES(C);
01879
01880 res = NULL;
01881 P = Pi;
01882
01883 #ifdef EDEBUG2
01884 fprintf(stderr,"C = \n");
01885 Polyhedron_Print(stderr,P_VALUE_FMT,C);
01886 fprintf(stderr,"P = \n");
01887 Polyhedron_Print(stderr,P_VALUE_FMT,P);
01888 #endif
01889
01890 hdim = P->Dimension + 1;
01891 dim = P->Dimension;
01892 nb_param = C->Dimension;
01893
01894
01895 if(nb_param == 0) {
01896
01897 return(Enumerate_NoParameters(P,C,NULL,NULL,MAXRAYS,param_name));
01898 }
01899 if(nb_param == dim) {
01900 res = (Enumeration *)malloc(sizeof(Enumeration));
01901 res->next = 0;
01902 res->ValidityDomain = DomainIntersection(P,C,MAXRAYS);
01903 value_init(res->EP.d);
01904 value_init(res->EP.x.n);
01905 value_set_si(res->EP.d,1);
01906 value_set_si(res->EP.x.n,1);
01907 if( param_name ) {
01908 fprintf(stdout,"---------------------------------------\n");
01909 fprintf(stdout,"Domain:\n");
01910 Print_Domain(stdout,res->ValidityDomain, param_name);
01911 fprintf(stdout,"\nEhrhart Polynomial:\n");
01912 print_evalue(stdout,&res->EP,param_name);
01913 fprintf(stdout, "\n");
01914 }
01915 return res;
01916 }
01917 PP = Polyhedron2Param_SimplifiedDomain(&P,C,MAXRAYS,&CEq,&CT);
01918 if(!PP) {
01919 if( param_name )
01920 fprintf(stdout, "\nEhrhart Polynomial:\nNULL\n");
01921
01922 return(NULL);
01923 }
01924
01925
01926 if(CT) {
01927 nb_param -= CT->NbColumns-CT->NbRows;
01928 dim -= CT->NbColumns-CT->NbRows;
01929 hdim -= CT->NbColumns-CT->NbRows;
01930
01931
01932 if(nb_param == 0) {
01933 res = Enumerate_NoParameters(P,C,CT,CEq,MAXRAYS,param_name);
01934 Param_Polyhedron_Free(PP);
01935 goto out;
01936 }
01937 }
01938
01939
01940 lcm = (Value *)malloc((nb_param+1) * sizeof(Value));
01941 m1 = (Value *)malloc((nb_param+1) * sizeof(Value));
01942
01943 for( np=0 ; np < nb_param+1; np++ )
01944 {
01945 value_init(lcm[np]); value_init(m1[np]);
01946 }
01947 value_init(hdv);
01948
01949 for(Q=PP->D;Q;Q=Q->next) {
01950 int hom = 0;
01951 if(CT) {
01952 Polyhedron *Dt;
01953 CQ = Q->Domain;
01954 Dt = Polyhedron_Preimage(Q->Domain,CT,MAXRAYS);
01955 rVD = DomainIntersection(Dt,CEq,MAXRAYS);
01956
01957
01958 if(!rVD || emptyQ(rVD) ||
01959 (rVD->Dimension-rVD->NbEq < Dt->Dimension-Dt->NbEq-CEq->NbEq)) {
01960 if(rVD)
01961 Polyhedron_Free(rVD);
01962 Polyhedron_Free(Dt);
01963 Polyhedron_Free(CQ);
01964 continue;
01965 }
01966 Polyhedron_Free(Dt);
01967 }
01968 else
01969 rVD = CQ = Q->Domain;
01970 en = (Enumeration *)malloc(sizeof(Enumeration));
01971 en->next = res;
01972 res = en;
01973 res->ValidityDomain = rVD;
01974
01975 if( param_name ) {
01976 fprintf(stdout,"---------------------------------------\n");
01977 fprintf(stdout,"Domain:\n");
01978
01979 #ifdef EPRINT_ALL_VALIDITY_CONSTRAINTS
01980 Print_Domain(stdout,res->ValidityDomain,param_name);
01981 #else
01982 {
01983 Polyhedron *VD;
01984 VD = DomainSimplify(res->ValidityDomain,C,MAXRAYS);
01985 Print_Domain(stdout,VD,param_name);
01986 Domain_Free(VD);
01987 }
01988 #endif
01989 }
01990
01991 overflow_warning_flag = 1;
01992
01993
01994 Scan_Vertices(PP,Q,CT,lcm,nb_param,param_name);
01995
01996 #ifdef EDEBUG2
01997 fprintf(stderr,"Denominator = ");
01998 for( np=0;np<nb_param;np++)
01999 value_print(stderr,P_VALUE_FMT,lcm[np]);
02000 fprintf(stderr," and hdim == %d \n",hdim);
02001 #endif
02002
02003 #ifdef EDEBUG2
02004 fprintf(stderr,"CQ = \n");
02005 Polyhedron_Print(stderr,P_VALUE_FMT,CQ);
02006 #endif
02007
02008
02009
02010 value_set_si(hdv,hdim-nb_param);
02011
02012 for( np=0;np<nb_param+1;np++) {
02013 if( value_notzero_p(lcm[np]) )
02014 value_multiply(m1[np],hdv,lcm[np]);
02015 else
02016 value_set_si(m1[np],1);
02017 }
02018
02019 #ifdef EDEBUG2
02020 fprintf(stderr,"m1 == ");
02021 for( np=0;np<nb_param;np++)
02022 value_print(stderr,P_VALUE_FMT,m1[np]);
02023 fprintf(stderr,"\n");
02024 #endif
02025
02026 CATCH(overflow_error) {
02027 fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
02028 CQ2 = NULL;
02029 }
02030 TRY {
02031 CQ2 = Polyhedron_Preprocess(CQ,m1,MAXRAYS);
02032
02033 #ifdef EDEBUG2
02034 fprintf(stderr,"After preprocess, CQ2 = ");
02035 Polyhedron_Print(stderr,P_VALUE_FMT,CQ2);
02036 #endif
02037
02038 UNCATCH(overflow_error);
02039 }
02040
02041
02042
02043 if ((!CQ2 || emptyQ(CQ2)) && CQ->NbBid==0) {
02044 int r;
02045
02046 #ifdef EDEBUG2
02047 fprintf(stderr,"Trying to call Polyhedron_Preprocess2 : CQ = \n");
02048 Polyhedron_Print(stderr,P_VALUE_FMT,CQ);
02049 #endif
02050
02051
02052 for(r=0;r<CQ->NbRays;r++) {
02053 if(value_zero_p(CQ->Ray[r][0]) ||
02054 value_zero_p(CQ->Ray[r][CQ->Dimension+1]))
02055 break;
02056 }
02057 if(r==CQ->NbRays) {
02058
02059
02060
02061 CQ2 = Polyhedron_Preprocess2(CQ,m1,lcm,MAXRAYS);
02062 }
02063 }
02064
02065 if (!CQ2) {
02066 Polyhedron *tmp;
02067 #ifdef EDEBUG2
02068 fprintf(stderr,"Homogenize.\n");
02069 #endif
02070 hom = 1;
02071 tmp = homogenize(CQ, MAXRAYS);
02072 CQ2 = Polyhedron_Preprocess(tmp,m1,MAXRAYS);
02073 Polyhedron_Free(tmp);
02074 if (!Ph)
02075 Ph = homogenize(P, MAXRAYS);
02076 for (np=0; np < nb_param+1; np++)
02077 if (value_notzero_p(lcm[np]))
02078 value_addto(m1[np],m1[np],lcm[np]);
02079 }
02080
02081 if (!CQ2 || emptyQ(CQ2)) {
02082 #ifdef EDEBUG2
02083 fprintf(stderr,"Degenerate.\n");
02084 #endif
02085 fprintf(stdout,"Degenerate Domain. Can not continue.\n");
02086 value_init(res->EP.d);
02087 value_init(res->EP.x.n);
02088 value_set_si(res->EP.d,1);
02089 value_set_si(res->EP.x.n,-1);
02090 }
02091 else {
02092
02093 #ifdef EDEBUG2
02094 fprintf(stderr,"CQ2 = \n");
02095 Polyhedron_Print(stderr,P_VALUE_FMT,CQ2);
02096 if( ! PolyhedronIncludes(CQ, CQ2) )
02097 fprintf( stderr,"CQ does not include CQ2 !\n");
02098 else
02099 fprintf( stderr,"CQ includes CQ2.\n");
02100 if( ! PolyhedronIncludes(res->ValidityDomain, CQ2) )
02101 fprintf( stderr,"CQ2 is *not* included in validity domain !\n");
02102 else
02103 fprintf( stderr,"CQ2 is included in validity domain.\n");
02104 #endif
02105
02106
02107 L = Polyhedron_Scan(hom ? Ph : P,CQ2,MAXRAYS);
02108 U = Universe_Polyhedron(0);
02109
02110
02111 LQ = Polyhedron_Scan(CQ2,U,MAXRAYS);
02112 Domain_Free(U);
02113 if(CT)
02114 Domain_Free(CQ);
02115
02116
02117 Domain_Free(CQ2);
02118
02119 #ifdef EDEBUG2
02120 fprintf(stderr,"L = \n");
02121 Polyhedron_Print(stderr,P_VALUE_FMT,L);
02122 fprintf(stderr,"LQ = \n");
02123 Polyhedron_Print(stderr,P_VALUE_FMT,LQ);
02124 #endif
02125 #ifdef EDEBUG3
02126 fprintf(stdout,"\nSystem of Equations:\n");
02127 #endif
02128
02129 value_init(res->EP.d);
02130 value_set_si(res->EP.d,0);
02131
02132
02133 context = (Value *) malloc ((hdim+1+hom)*sizeof(Value));
02134 for(i=0;i<=(hdim+hom);i++)
02135 value_init(context[i]);
02136 Vector_Set(context,0,(hdim+1+hom));
02137
02138
02139 value_set_si(context[hdim+hom],1);
02140
02141 CATCH(overflow_error) {
02142 fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
02143 fprintf(stderr,"You should rebuild PolyLib using GNU-MP "
02144 "or increasing the size of integers.\n");
02145 overflow_warning_flag = 0;
02146 assert(overflow_warning_flag);
02147
02148 }
02149 TRY {
02150 res->EP.x.p = P_Enum(L,LQ,context,1,nb_param+hom,
02151 dim+hom,lcm,param_name);
02152 UNCATCH(overflow_error);
02153 }
02154 if (hom)
02155 dehomogenize_evalue(&res->EP, nb_param+1);
02156
02157 for(i=0;i<=(hdim+hom);i++)
02158 value_clear(context[i]);
02159 free(context);
02160 Domain_Free(L);
02161 Domain_Free(LQ);
02162
02163 #ifdef EDEBUG5
02164 if( param_name )
02165 {
02166 fprintf(stdout,"\nEhrhart Polynomial (before simplification):\n");
02167 print_evalue(stdout,&res->EP,param_name);
02168 }
02169 #endif
02170
02171
02172 reduce_evalue(&res->EP);
02173
02174
02175
02176 if(CT)
02177 addeliminatedparams_evalue(&res->EP,CT);
02178
02179 if (param_name) {
02180 fprintf(stdout,"\nEhrhart Polynomial:\n");
02181 print_evalue(stdout,&res->EP, param_name);
02182 fprintf(stdout,"\n");
02183
02184 }
02185
02186 }
02187 }
02188
02189 if (Ph)
02190 Polyhedron_Free(Ph);
02191
02192 for (np=0; np < nb_param+1; np++)
02193 {
02194 value_clear(lcm[np]); value_clear(m1[np]);
02195 }
02196 value_clear(hdv);
02197 free(lcm);
02198 free(m1);
02199
02200 Param_Vertices_Free(PP->V);
02201 while (PP->D) {
02202 Q = PP->D;
02203 PP->D = PP->D->next;
02204 free(Q->F);
02205 free(Q);
02206 }
02207 free(PP);
02208
02209 out:
02210 if (CEq)
02211 Polyhedron_Free(CEq);
02212 if (CT)
02213 Matrix_Free(CT);
02214 if( P != Pi )
02215 Polyhedron_Free( P );
02216
02217 return res;
02218 }
02219
02220 void Enumeration_Free(Enumeration *en)
02221 {
02222 Enumeration *ee;
02223
02224 while( en )
02225 {
02226 free_evalue_refs( &(en->EP) );
02227 Domain_Free( en->ValidityDomain );
02228 ee = en ->next;
02229 free( en );
02230 en = ee;
02231 }
02232 }
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244 void evalue_div(evalue * e, Value n) {
02245 int i;
02246 Value gc;
02247 value_init(gc);
02248 if (value_zero_p(e->d)) {
02249 for (i=0; i< e->x.p->size; i++) {
02250 evalue_div(&(e->x.p->arr[i]), n);
02251 }
02252 }
02253 else {
02254 value_multiply(e->d, e->d, n);
02255
02256 value_gcd(gc, e->x.n, e->d);
02257 if (value_notone_p(gc)) {
02258 value_divexact(e->d, e->d, gc);
02259 value_divexact(e->x.n, e->x.n, gc);
02260 }
02261 }
02262 value_clear(gc);
02263 }
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281 Enumeration *Ehrhart_Quick_Apx_Full_Dim(Polyhedron *Pi,Polyhedron *C,
02282 unsigned MAXRAYS, const char **param_name)
02283 {
02284 Polyhedron *L, *CQ, *CQ2, *LQ, *U, *CEq, *rVD, *P;
02285 Matrix *CT;
02286 Param_Polyhedron *PP;
02287 Param_Domain *Q;
02288 int i,j,hdim, dim, nb_param, np;
02289 Value *lcm, *m1, hdv;
02290 Value *context;
02291 Enumeration *en, *res;
02292 Value expansion_det;
02293 Polyhedron * Expanded;
02294
02295
02296 Param_Vertices * V_tmp;
02297
02298 res = NULL;
02299 P = Pi;
02300
02301 value_init(expansion_det);
02302
02303 #ifdef EDEBUG2
02304 fprintf(stderr,"C = \n");
02305 Polyhedron_Print(stderr,P_VALUE_FMT,C);
02306 fprintf(stderr,"P = \n");
02307 Polyhedron_Print(stderr,P_VALUE_FMT,P);
02308 #endif
02309
02310 hdim = P->Dimension + 1;
02311 dim = P->Dimension;
02312 nb_param = C->Dimension;
02313
02314
02315 if(nb_param == 0) {
02316
02317 return(Enumerate_NoParameters(P,C,NULL,NULL,MAXRAYS, param_name));
02318 }
02319
02320 #if EDEBUG2
02321 printf("Enumerating polyhedron : \n");
02322 Polyhedron_Print(stdout, P_VALUE_FMT, P);
02323 #endif
02324
02325 PP = Polyhedron2Param_SimplifiedDomain(&P,C,MAXRAYS,&CEq,&CT);
02326 if(!PP) {
02327 if( param_name )
02328 fprintf(stdout, "\nEhrhart Polynomial:\nNULL\n");
02329
02330 return(NULL);
02331 }
02332
02333
02334 if(CT) {
02335 nb_param -= CT->NbColumns-CT->NbRows;
02336 dim -= CT->NbColumns-CT->NbRows;
02337 hdim -= CT->NbColumns-CT->NbRows;
02338
02339
02340 if(nb_param == 0)
02341 {
02342 res = Enumerate_NoParameters(P,C,CT,CEq,MAXRAYS,param_name);
02343 if( P != Pi )
02344 Polyhedron_Free( P );
02345 return( res );
02346 }
02347 }
02348
02349 if (!PP->nbV)
02350
02351 return NULL;
02352
02353
02354 lcm = (Value *)malloc( nb_param * sizeof(Value));
02355 m1 = (Value *)malloc( nb_param * sizeof(Value));
02356
02357 for( np=0 ; np<nb_param ; np++ )
02358 {
02359 value_init(lcm[np]); value_init(m1[np]);
02360 }
02361 value_init(hdv);
02362
02363 #if EDEBUG2
02364 Polyhedron_Print(stderr, P_VALUE_FMT, P);
02365 #endif
02366
02367 Expanded = P;
02368 Param_Polyhedron_Scale_Integer(PP, &Expanded, &expansion_det, MAXRAYS);
02369
02370 #if EDEBUG2
02371 Polyhedron_Print(stderr, P_VALUE_FMT, Expanded);
02372 #endif
02373
02374 if (P != Expanded)
02375 Polyhedron_Free(P);
02376 P = Expanded;
02377
02378
02379
02380
02381
02382
02383
02384 for (i=0; i< nb_param; i++) value_set_si(lcm[i], 1);
02385
02386 for(Q=PP->D;Q;Q=Q->next) {
02387 if(CT) {
02388 Polyhedron *Dt;
02389 CQ = Q->Domain;
02390 Dt = Polyhedron_Preimage(Q->Domain,CT,MAXRAYS);
02391 rVD = DomainIntersection(Dt,CEq,MAXRAYS);
02392
02393
02394 if(!rVD || emptyQ(rVD) ||
02395 (rVD->Dimension-rVD->NbEq < Dt->Dimension-Dt->NbEq-CEq->NbEq)) {
02396 if(rVD)
02397 Polyhedron_Free(rVD);
02398 Polyhedron_Free(Dt);
02399 continue;
02400 }
02401 Polyhedron_Free(Dt);
02402 }
02403 else
02404 rVD = CQ = Q->Domain;
02405 en = (Enumeration *)malloc(sizeof(Enumeration));
02406 en->next = res;
02407 res = en;
02408 res->ValidityDomain = rVD;
02409
02410 if( param_name )
02411 {
02412 fprintf(stdout,"---------------------------------------\n");
02413 fprintf(stdout,"Domain:\n");
02414
02415 #ifdef EPRINT_ALL_VALIDITY_CONSTRAINTS
02416 Print_Domain(stdout,res->ValidityDomain,param_name);
02417 #else
02418 {
02419 Polyhedron *VD;
02420 VD = DomainSimplify(res->ValidityDomain,C,MAXRAYS);
02421 Print_Domain(stdout,VD,param_name);
02422 Domain_Free(VD);
02423 }
02424 #endif
02425 }
02426
02427 overflow_warning_flag = 1;
02428
02429 #ifdef EDEBUG2
02430 fprintf(stderr,"Denominator = ");
02431 for( np=0;np<nb_param;np++)
02432 value_print(stderr,P_VALUE_FMT,lcm[np]);
02433 fprintf(stderr," and hdim == %d \n",hdim);
02434 #endif
02435
02436 #ifdef EDEBUG2
02437 fprintf(stderr,"CQ = \n");
02438 Polyhedron_Print(stderr,P_VALUE_FMT,CQ);
02439 #endif
02440
02441
02442
02443 value_set_si(hdv,hdim-nb_param);
02444
02445 for( np=0;np<nb_param;np++)
02446 {
02447 if( value_notzero_p(lcm[np]) )
02448 value_multiply(m1[np],hdv,lcm[np]);
02449 else
02450 value_set_si(m1[np],1);
02451 }
02452
02453 #ifdef EDEBUG2
02454 fprintf(stderr,"m1 == ");
02455 for( np=0;np<nb_param;np++)
02456 value_print(stderr,P_VALUE_FMT,m1[np]);
02457 fprintf(stderr,"\n");
02458 #endif
02459
02460 CATCH(overflow_error) {
02461 fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
02462 CQ2 = NULL;
02463 }
02464 TRY {
02465 CQ2 = Polyhedron_Preprocess(CQ,m1,MAXRAYS);
02466
02467 #ifdef EDEBUG2
02468 fprintf(stderr,"After preprocess, CQ2 = ");
02469 Polyhedron_Print(stderr,P_VALUE_FMT,CQ2);
02470 #endif
02471
02472 UNCATCH(overflow_error);
02473 }
02474
02475
02476
02477 if ((!CQ2 || emptyQ(CQ2)) && CQ->NbBid==0) {
02478 int r;
02479
02480 #ifdef EDEBUG2
02481 fprintf(stderr,"Trying to call Polyhedron_Preprocess2 : CQ = \n");
02482 Polyhedron_Print(stderr,P_VALUE_FMT,CQ);
02483 #endif
02484
02485
02486 for(r=0;r<CQ->NbRays;r++) {
02487 if(value_zero_p(CQ->Ray[r][0]) ||
02488 value_zero_p(CQ->Ray[r][CQ->Dimension+1]))
02489 break;
02490 }
02491 if(r==CQ->NbRays) {
02492
02493
02494
02495 CQ2 = Polyhedron_Preprocess2(CQ,m1,lcm,MAXRAYS);
02496 }
02497 }
02498 if (!CQ2 || emptyQ(CQ2)) {
02499 #ifdef EDEBUG2
02500 fprintf(stderr,"Degenerate.\n");
02501 #endif
02502 fprintf(stdout,"Degenerate Domain. Can not continue.\n");
02503 value_init(res->EP.d);
02504 value_init(res->EP.x.n);
02505 value_set_si(res->EP.d,1);
02506 value_set_si(res->EP.x.n,-1);
02507 }
02508 else {
02509
02510 #ifdef EDEBUG2
02511 fprintf(stderr,"CQ2 = \n");
02512 Polyhedron_Print(stderr,P_VALUE_FMT,CQ2);
02513 if( ! PolyhedronIncludes(CQ, CQ2) )
02514 fprintf( stderr,"CQ does not include CQ2 !\n");
02515 else
02516 fprintf( stderr,"CQ includes CQ2.\n");
02517 if( ! PolyhedronIncludes(res->ValidityDomain, CQ2) )
02518 fprintf( stderr,"CQ2 is *not* included in validity domain !\n");
02519 else
02520 fprintf( stderr,"CQ2 is included in validity domain.\n");
02521 #endif
02522
02523
02524 L = Polyhedron_Scan(P,CQ,MAXRAYS);
02525 U = Universe_Polyhedron(0);
02526
02527
02528 LQ = Polyhedron_Scan(CQ2,U,MAXRAYS);
02529 Domain_Free(U);
02530 if(CT)
02531 Domain_Free(CQ);
02532
02533
02534 Domain_Free(CQ2);
02535
02536 #ifdef EDEBUG2
02537 fprintf(stderr,"L = \n");
02538 Polyhedron_Print(stderr,P_VALUE_FMT,L);
02539 fprintf(stderr,"LQ = \n");
02540 Polyhedron_Print(stderr,P_VALUE_FMT,LQ);
02541 #endif
02542 #ifdef EDEBUG3
02543 fprintf(stdout,"\nSystem of Equations:\n");
02544 #endif
02545
02546 value_init(res->EP.d);
02547 value_set_si(res->EP.d,0);
02548
02549
02550 context = (Value *) malloc ((hdim+1)*sizeof(Value));
02551 for(i=0;i<=(hdim);i++)
02552 value_init(context[i]);
02553 Vector_Set(context,0,(hdim+1));
02554
02555
02556 value_set_si(context[hdim],1);
02557
02558 CATCH(overflow_error) {
02559 fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
02560 fprintf(stderr,"You should rebuild PolyLib using GNU-MP "
02561 "or increasing the size of integers.\n");
02562 overflow_warning_flag = 0;
02563 assert(overflow_warning_flag);
02564
02565 }
02566 TRY {
02567 res->EP.x.p = P_Enum(L,LQ,context,1,nb_param,dim,lcm, param_name);
02568 UNCATCH(overflow_error);
02569 }
02570
02571 for(i=0;i<=(hdim);i++)
02572 value_clear(context[i]);
02573 free(context);
02574 Domain_Free(L);
02575 Domain_Free(LQ);
02576
02577 #ifdef EDEBUG5
02578 if( param_name )
02579 {
02580 fprintf(stdout,"\nEhrhart Polynomial (before simplification):\n");
02581 print_evalue(stdout,&res->EP,param_name);
02582 }
02583
02584
02585 fprintf(stdout,"\nEhrhart Polynomial (before division):\n");
02586 print_evalue(stdout,&(res->EP),param_name);
02587 #endif
02588
02589 evalue_div(&(res->EP), expansion_det);
02590
02591
02592
02593 reduce_evalue(&res->EP);
02594
02595
02596
02597 if(CT)
02598 addeliminatedparams_evalue(&res->EP,CT);
02599
02600 if( param_name )
02601 {
02602 fprintf(stdout,"\nEhrhart Polynomial:\n");
02603 print_evalue(stdout,&res->EP, param_name);
02604 fprintf(stdout,"\n");
02605
02606
02607 }
02608
02609 }
02610 }
02611 value_clear(expansion_det);
02612
02613 if( P != Pi )
02614 Polyhedron_Free( P );
02615
02616 for( np=0; np<nb_param ; np++ )
02617 {
02618 value_clear(lcm[np]); value_clear(m1[np]);
02619 }
02620 value_clear(hdv);
02621
02622 return res;
02623 }
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635 Enumeration *Ehrhart_Quick_Apx(Matrix * M, Matrix * C,
02636 Matrix **Validity_Lattice, unsigned maxRays) {
02637
02638
02639
02640
02641 Matrix * M_full;
02642 Polyhedron * P, * PC;
02643 Enumeration *en;
02644
02645 M_full = full_dimensionize(M, C->NbColumns-2, Validity_Lattice);
02646
02647
02648 mpolyhedron_compress_last_vars(C, *Validity_Lattice);
02649 show_matrix(M_full);
02650 P = Constraints2Polyhedron(M_full, maxRays);
02651 PC = Constraints2Polyhedron(C, maxRays);
02652 Matrix_Free(M_full);
02653
02654 en = Ehrhart_Quick_Apx_Full_Dim(P, PC, maxRays, NULL);
02655
02656
02657 Polyhedron_Free(P);
02658 Polyhedron_Free(PC);
02659 return en;
02660 }
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677 Enumeration *Constraints_EhrhartQuickApx(Matrix const * M, Matrix const * C,
02678 Matrix ** validityLattice,
02679 Matrix ** parmEqualities,
02680 unsigned int ** elimParms,
02681 unsigned maxRays) {
02682 Enumeration *EP;
02683 Matrix * Mp = Matrix_Copy(M);
02684 Matrix * Cp = Matrix_Copy(C);
02685
02686
02687 (*parmEqualities) = Constraints_Remove_parm_eqs(&Mp, &Cp, 0, elimParms);
02688 if (Mp->NbRows>=0) {
02689 EP = Ehrhart_Quick_Apx(Mp, Cp, validityLattice, maxRays);
02690 return EP;
02691 }
02692 else {
02693
02694 return NULL;
02695 }
02696
02697 }
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709 const char **parmsWithoutElim(char const **parmNames,
02710 unsigned int const *elimParms,
02711 unsigned int nbParms)
02712 {
02713 int i=0, j=0,k;
02714 int newParmNb = nbParms - elimParms[0];
02715 const char **newParmNames = (const char **)malloc(newParmNb * sizeof(char *));
02716 for (k=1; k<= elimParms[0]; k++) {
02717 while (i!=elimParms[k]) {
02718 newParmNames[i-k+1] = parmNames[i];
02719 i++;
02720 }
02721 }
02722 return newParmNames;
02723 }
02724
02725
02726
02727
02728
02729
02730
02731
02732 Enumeration * Enumeration_zero(unsigned int nbParms, unsigned int maxRays) {
02733 Matrix * Mz = Matrix_Alloc(1, nbParms+3);
02734 Polyhedron * emptyP;
02735 Polyhedron * universe;
02736 Enumeration * zero;
02737
02738
02739 value_set_si(Mz->p[0][1], 2);
02740 value_set_si(Mz->p[0][nbParms+2], 1);
02741 emptyP = Constraints2Polyhedron(Mz, maxRays);
02742 Matrix_Free(Mz);
02743 universe = Universe_Polyhedron(nbParms);
02744 zero = Polyhedron_Enumerate(emptyP, universe, maxRays, NULL);
02745 Polyhedron_Free(emptyP);
02746 Polyhedron_Free(universe);
02747 return zero;
02748 }
02749