00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <ctype.h>
00014 #include <string.h>
00015 #include <unistd.h>
00016 #include <assert.h>
00017
00018 #include <polylib/polylib.h>
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #define EPRINT_ALL_VALIDITY_CONSTRAINTS
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #define REDUCE_DEGREE
00071
00072
00073
00074
00075
00076 #define ALL_OVERFLOW_WARNINGS
00077
00078
00079
00080 int overflow_warning_flag = 1;
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 enode *new_enode(enode_type type,int size,int pos) {
00097
00098 enode *res;
00099 int i;
00100
00101 if(size == 0) {
00102 fprintf(stderr, "Allocating enode of size 0 !\n" );
00103 return NULL;
00104 }
00105 res = (enode *) malloc(sizeof(enode) + (size-1)*sizeof(evalue));
00106 res->type = type;
00107 res->size = size;
00108 res->pos = pos;
00109 for(i=0; i<size; i++) {
00110 value_init(res->arr[i].d);
00111 value_set_si(res->arr[i].d,0);
00112 res->arr[i].x.p = 0;
00113 }
00114 return res;
00115 }
00116
00117
00118
00119
00120
00121 void free_evalue_refs(evalue *e) {
00122
00123 enode *p;
00124 int i;
00125
00126 if (value_notzero_p(e->d)) {
00127
00128
00129 value_clear(e->d);
00130 value_clear(e->x.n);
00131 return;
00132 }
00133 value_clear(e->d);
00134 p = e->x.p;
00135 if (!p) return;
00136 for (i=0; i<p->size; i++) {
00137 free_evalue_refs(&(p->arr[i]));
00138 }
00139 free(p);
00140 return;
00141 }
00142
00143
00144
00145
00146
00147
00148
00149 enode *ecopy(enode *e) {
00150
00151 enode *res;
00152 int i;
00153
00154 res = new_enode(e->type,e->size,e->pos);
00155 for(i=0;i<e->size;++i) {
00156 value_assign(res->arr[i].d,e->arr[i].d);
00157 if(value_zero_p(res->arr[i].d))
00158 res->arr[i].x.p = ecopy(e->arr[i].x.p);
00159 else {
00160 value_init(res->arr[i].x.n);
00161 value_assign(res->arr[i].x.n,e->arr[i].x.n);
00162 }
00163 }
00164 return(res);
00165 }
00166
00167
00168
00169
00170
00171
00172
00173 void print_evalue(FILE *DST,evalue *e,char **pname) {
00174
00175 if(value_notzero_p(e->d)) {
00176 if(value_notone_p(e->d)) {
00177 value_print(DST,VALUE_FMT,e->x.n);
00178 fprintf(DST,"/");
00179 value_print(DST,VALUE_FMT,e->d);
00180 }
00181 else {
00182 value_print(DST,VALUE_FMT,e->x.n);
00183 }
00184 }
00185 else
00186 print_enode(DST,e->x.p,pname);
00187 return;
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197 void print_enode(FILE *DST,enode *p,char **pname) {
00198
00199 int i;
00200
00201 if (!p) {
00202 fprintf(DST, "NULL");
00203 return;
00204 }
00205 if (p->type == evector) {
00206 fprintf(DST, "{ ");
00207 for (i=0; i<p->size; i++) {
00208 print_evalue(DST, &p->arr[i], pname);
00209 if (i!=(p->size-1))
00210 fprintf(DST, ", ");
00211 }
00212 fprintf(DST, " }\n");
00213 }
00214 else if (p->type == polynomial) {
00215 fprintf(DST, "( ");
00216 for (i=p->size-1; i>=0; i--) {
00217 print_evalue(DST, &p->arr[i], pname);
00218 if (i==1) fprintf(DST, " * %s + ", pname[p->pos-1]);
00219 else if (i>1)
00220 fprintf(DST, " * %s^%d + ", pname[p->pos-1], i);
00221 }
00222 fprintf(DST, " )\n");
00223 }
00224 else if (p->type == periodic) {
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)) fprintf(DST, ", ");
00229 }
00230 fprintf(DST," ]_%s", pname[p->pos-1]);
00231 }
00232 return;
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242 static int eequal(evalue *e1,evalue *e2) {
00243
00244 int i;
00245 enode *p1, *p2;
00246
00247 if (value_ne(e1->d,e2->d))
00248 return 0;
00249
00250
00251 if (value_notzero_p(e1->d)) {
00252 if (value_ne(e1->x.n,e2->x.n))
00253 return 0;
00254
00255
00256 return 1;
00257 }
00258
00259
00260 p1 = e1->x.p;
00261 p2 = e2->x.p;
00262 if (p1->type != p2->type) return 0;
00263 if (p1->size != p2->size) return 0;
00264 if (p1->pos != p2->pos) return 0;
00265 for (i=0; i<p1->size; i++)
00266 if (!eequal(&p1->arr[i], &p2->arr[i]) )
00267 return 0;
00268 return 1;
00269 }
00270
00271
00272
00273
00274
00275
00276 void reduce_evalue (evalue *e) {
00277
00278 enode *p;
00279 int i, j, k;
00280
00281 if (value_notzero_p(e->d))
00282 return;
00283 if(!(p = e->x.p))
00284 return;
00285
00286
00287 for (i=0; i<p->size; i++)
00288 reduce_evalue(&p->arr[i]);
00289
00290 if (p->type==periodic) {
00291
00292
00293 for (i=1; i<=(p->size)/2; i++) {
00294 if ((p->size % i)==0) {
00295
00296
00297 for (j=0; j<i; j++)
00298 for (k=j+i; k<e->x.p->size; k+=i)
00299 if (!eequal(&p->arr[j], &p->arr[k])) goto you_lose;
00300
00301
00302 for (j=i; j<p->size; j++) free_evalue_refs(&p->arr[j]);
00303 p->size = i;
00304 break;
00305
00306 you_lose:
00307 continue;
00308 }
00309 }
00310
00311
00312 if (p->size == 1) {
00313 value_clear(e->d);
00314 memcpy(e,&p->arr[0],sizeof(evalue));
00315 free(p);
00316 }
00317 }
00318 else if (p->type==polynomial) {
00319
00320
00321 for (i=p->size-1;i>=0;i--) {
00322 if (value_one_p(p->arr[i].d) && value_zero_p(p->arr[i].x.n))
00323
00324
00325 continue;
00326 else
00327 break;
00328 }
00329 if (i==-1) p->size = 1;
00330 else if (i+1<p->size) p->size = i+1;
00331
00332
00333 if (p->size == 1) {
00334 value_clear(e->d);
00335 memcpy(e,&p->arr[0],sizeof(evalue));
00336 free(p);
00337 }
00338 }
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 static void emul (evalue *e1,evalue *e2,evalue *res) {
00352
00353 enode *p;
00354 int i;
00355 Value g;
00356
00357 if (value_zero_p(e2->d)) {
00358 fprintf(stderr, "emul: ?expecting constant value\n");
00359 return;
00360 }
00361 value_init(g);
00362 if (value_notzero_p(e1->d)) {
00363
00364 value_init(res->x.n);
00365
00366 value_multiply(res->d,e1->d,e2->d);
00367 value_multiply(res->x.n,e1->x.n,e2->x.n );
00368 Gcd(res->x.n, res->d,&g);
00369 if (value_notone_p(g)) {
00370 value_division(res->d,res->d,g);
00371 value_division(res->x.n,res->x.n,g);
00372 }
00373 }
00374 else {
00375 value_set_si(res->d,0);
00376 p = e1->x.p;
00377 res->x.p = new_enode(p->type, p->size, p->pos);
00378 for (i=0; i<p->size; i++) {
00379 emul(&p->arr[i], e2, &(res->x.p->arr[i]) );
00380 }
00381 }
00382 value_clear(g);
00383 return;
00384 }
00385
00386
00387
00388
00389
00390
00391
00392
00393 void eadd(evalue *e1,evalue *res) {
00394
00395 int i;
00396 Value g,m1,m2;
00397
00398 value_init(g);
00399 value_init(m1);
00400 value_init(m2);
00401
00402 if (value_notzero_p(e1->d) && value_notzero_p(res->d)) {
00403
00404
00405 value_multiply(m1,e1->x.n,res->d);
00406 value_multiply(m2,res->x.n,e1->d);
00407 value_addto(res->x.n,m1,m2);
00408 value_multiply(res->d,e1->d,res->d);
00409 Gcd(res->x.n,res->d,&g);
00410 if (value_notone_p(g)) {
00411 value_division(res->d,res->d,g);
00412 value_division(res->x.n,res->x.n,g);
00413 }
00414 value_clear(g); value_clear(m1); value_clear(m2);
00415 return;
00416 }
00417 else if (value_notzero_p(e1->d) && value_zero_p(res->d)) {
00418 if (res->x.p->type==polynomial) {
00419
00420
00421 eadd(e1, &res->x.p->arr[0]);
00422 value_clear(g); value_clear(m1); value_clear(m2);
00423 return;
00424 }
00425 else if (res->x.p->type==periodic) {
00426
00427
00428 for (i=0; i<res->x.p->size; i++) {
00429 eadd(e1, &res->x.p->arr[i]);
00430 }
00431 value_clear(g); value_clear(m1); value_clear(m2);
00432 return;
00433 }
00434 else {
00435 fprintf(stderr, "eadd: cannot add const with vector\n");
00436 value_clear(g); value_clear(m1); value_clear(m2);
00437 return;
00438 }
00439 }
00440 else if (value_zero_p(e1->d) && value_notzero_p(res->d)) {
00441 fprintf(stderr,"eadd: cannot add evalue to const\n");
00442 value_clear(g); value_clear(m1); value_clear(m2);
00443 return;
00444 }
00445 else {
00446 if ((e1->x.p->type != res->x.p->type) ||
00447 (e1->x.p->pos != res->x.p->pos )) {
00448 fprintf(stderr, "eadd: ?cannot add, incompatible types\n");
00449 value_clear(g); value_clear(m1); value_clear(m2);
00450 return;
00451 }
00452 if (e1->x.p->size == res->x.p->size) {
00453 for (i=0; i<res->x.p->size; i++) {
00454 eadd(&e1->x.p->arr[i], &res->x.p->arr[i]);
00455 }
00456 value_clear(g); value_clear(m1); value_clear(m2);
00457 return;
00458 }
00459
00460
00461 if (res->x.p->type==polynomial) {
00462
00463
00464
00465
00466
00467 if(e1->x.p->size > res->x.p->size) {
00468 enode *tmp;
00469 tmp = ecopy(e1->x.p);
00470 for(i=0;i<res->x.p->size;++i) {
00471 eadd(&res->x.p->arr[i], &tmp->arr[i]);
00472 free_evalue_refs(&res->x.p->arr[i]);
00473 }
00474 res->x.p = tmp;
00475 }
00476 else {
00477 for (i=0; i<e1->x.p->size ; i++) {
00478 eadd(&e1->x.p->arr[i], &res->x.p->arr[i]);
00479 }
00480 value_clear(g); value_clear(m1); value_clear(m2);
00481 return;
00482 }
00483 }
00484 else if (res->x.p->type==periodic) {
00485 fprintf(stderr, "eadd: ?addition of different sized periodic nos\n");
00486 value_clear(g); value_clear(m1); value_clear(m2);
00487 return;
00488 }
00489 else {
00490 fprintf(stderr, "eadd: ?cannot add vectors of different length\n");
00491 value_clear(g); value_clear(m1); value_clear(m2);
00492 return;
00493 }
00494 }
00495 value_clear(g); value_clear(m1); value_clear(m2);
00496 return;
00497 }
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 void edot(enode *v1,enode *v2,evalue *res) {
00510
00511 int i;
00512 evalue tmp;
00513
00514 if ((v1->type != evector) || (v2->type != evector)) {
00515 fprintf(stderr, "edot: ?expecting vectors\n");
00516 return;
00517 }
00518 if (v1->size != v2->size) {
00519 fprintf(stderr, "edot: ? vector lengths do not agree\n");
00520 return;
00521 }
00522 if (v1->size<=0) {
00523 value_set_si(res->d,1);
00524 value_init(res->x.n);
00525 value_set_si(res->x.n,0);
00526 return;
00527 }
00528
00529
00530
00531 emul(&v1->arr[0],&v2->arr[0],res);
00532 for (i=1; i<v1->size; i++) {
00533 value_init(tmp.d);
00534 value_init(tmp.x.n);
00535
00536
00537 emul(&v1->arr[i],&v2->arr[i],&tmp);
00538 eadd(&tmp,res);
00539 free_evalue_refs(&tmp);
00540 }
00541 return;
00542 }
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 static void aep_evalue(evalue *e, int *ref) {
00554
00555 enode *p;
00556 int i;
00557
00558 if (value_notzero_p(e->d))
00559 return;
00560 if(!(p = e->x.p))
00561 return;
00562
00563
00564 for (i=0;i<p->size;i++)
00565 aep_evalue(&p->arr[i],ref);
00566
00567
00568 p->pos = ref[p->pos-1]+1;
00569 return;
00570 }
00571
00572
00573 static void addeliminatedparams_evalue(evalue *e,Matrix *CT) {
00574
00575 enode *p;
00576 int i, j;
00577 int *ref;
00578
00579 if (value_notzero_p(e->d))
00580 return;
00581 if(!(p = e->x.p))
00582 return;
00583
00584
00585 ref = (int *)malloc(sizeof(int)*(CT->NbRows-1));
00586 for(i=0;i<CT->NbRows-1;i++)
00587 for(j=0;j<CT->NbColumns;j++)
00588 if(value_notzero_p(CT->p[i][j])) {
00589 ref[i] = j;
00590 break;
00591 }
00592
00593
00594 aep_evalue(e,ref);
00595 free( ref );
00596 return;
00597 }
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619 #define MAXITER 100
00620 int cherche_min(Value *min,Polyhedron *D,int pos) {
00621
00622 Value binf, bsup;
00623 Value i;
00624 int flag, maxiter;
00625
00626 if(!D)
00627 return(1);
00628 if(pos > D->Dimension)
00629 return(1);
00630
00631 value_init(binf); value_init(bsup);
00632 value_init(i);
00633
00634 #ifdef EDEBUG61
00635 fprintf(stderr,"Entering Cherche min --> \n");
00636 fprintf(stderr,"LowerUpperBounds :\n");
00637 fprintf(stderr,"pos = %d\n",pos);
00638 fprintf(stderr,"current min = (");
00639 value_print(stderr,P_VALUE_FMT,min[0]);
00640 {int j;
00641 for(j=1;j<=D->Dimension ; j++) {
00642 fprintf(stderr,", ");
00643 value_print(stderr,P_VALUE_FMT,min[j]);
00644 }
00645 }
00646 fprintf(stderr,")\n");
00647 #endif
00648
00649 flag = lower_upper_bounds(pos,D,min,&binf,&bsup);
00650
00651 #ifdef EDEBUG61
00652 fprintf(stderr, "flag = %d\n", flag);
00653 fprintf(stderr,"binf = ");
00654 value_print(stderr,P_VALUE_FMT,binf);
00655 fprintf(stderr,"\n");
00656 fprintf(stderr,"bsup = ");
00657 value_print(stderr,P_VALUE_FMT,bsup);
00658 fprintf(stderr,"\n");
00659 #endif
00660
00661 if(flag&LB_INFINITY)
00662 value_set_si(binf,0);
00663
00664
00665 for(maxiter=0,(((flag&LB_INFINITY) || value_neg_p(binf)) ?
00666 value_set_si(i,0) : value_assign(i,binf));
00667 ((flag&UB_INFINITY) || value_le(i,bsup)) && maxiter<MAXITER ;
00668 value_increment(i,i),maxiter++) {
00669
00670 value_assign(min[pos],i);
00671 if(cherche_min(min,D->next,pos+1)) {
00672 value_clear(binf); value_clear(bsup);
00673 value_clear(i);
00674 return(1);
00675 }
00676 }
00677
00678
00679 if((flag&LB_INFINITY) || value_neg_p(binf))
00680 for(maxiter=0,(((flag&UB_INFINITY) || value_pos_p(bsup))?
00681 value_set_si(i,-1)
00682 :value_assign(i,bsup));
00683 ((flag&LB_INFINITY) || value_ge(i,binf)) && maxiter<MAXITER ;
00684 value_decrement(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 value_clear(binf); value_clear(bsup);
00694 value_clear(i);
00695
00696 value_set_si(min[pos],0);
00697 return(0);
00698 }
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 Polyhedron *Polyhedron_Preprocess(Polyhedron *D,Value *size,unsigned MAXRAYS)
00729 {
00730 Matrix *M;
00731 int i, j, d;
00732 Polyhedron *T, *S, *H, *C;
00733 Value *min,tmp;
00734
00735 value_init(tmp);
00736 d = D->Dimension;
00737 M = Matrix_Alloc(MAXRAYS, D->Dimension+2);
00738 M->NbRows = D->NbConstraints;
00739
00740
00741 for(i=0;i<D->NbConstraints;i++)
00742 Vector_Copy(D->Constraint[i],M->p[i],(d+2));
00743
00744 #ifdef EDEBUG6
00745 fprintf(stderr,"M for PreProcess : ");
00746 Matrix_Print(stderr,P_VALUE_FMT,M);
00747 fprintf(stderr,"\nsize == ");
00748 for( i=0 ; i<d ; i++ )
00749 value_print(stderr,P_VALUE_FMT,size[i]);
00750 fprintf(stderr,"\n");
00751 #endif
00752
00753
00754 for(i=0;i<D->NbConstraints;i++) {
00755 if(value_zero_p(D->Constraint[i][0])) {
00756 fprintf(stderr,"Polyhedron_Preprocess: ");
00757 fprintf(stderr,"an equality was found where I did expect an inequality.\n");
00758 fprintf(stderr,"Trying to continue...\n");
00759 continue;
00760 }
00761 Vector_Copy(D->Constraint[i],M->p[M->NbRows],(d+2));
00762 for(j=1;j<=d;j++)
00763 if(value_neg_p(D->Constraint[i][j])) {
00764 value_multiply(tmp,D->Constraint[i][j],size[j-1]);
00765 value_addto(M->p[M->NbRows][d+1],M->p[M->NbRows][d+1],tmp);
00766 }
00767
00768
00769 if(value_ne(M->p[M->NbRows][d+1],D->Constraint[i][d+1]))
00770 M->NbRows ++ ;
00771 }
00772
00773 #ifdef EDEBUG6
00774 fprintf(stderr,"M used to find min : ");
00775 Matrix_Print(stderr,P_VALUE_FMT,M);
00776 #endif
00777
00778 T = Constraints2Polyhedron(M,MAXRAYS);
00779 Matrix_Free(M);
00780 if (!T || emptyQ(T)) {
00781 if(T)
00782 Polyhedron_Free(T);
00783 value_clear(tmp);
00784 return(NULL);
00785 }
00786
00787
00788 min = (Value *) malloc(sizeof(Value) * (d+2));
00789 for(i=0;i<=d;i++) {
00790 value_init(min[i]);
00791 value_set_si(min[i],0);
00792 }
00793 value_init(min[i]);
00794 value_set_si(min[i],1);
00795 C = Universe_Polyhedron(0);
00796 S = Polyhedron_Scan(T,C,MAXRAYS);
00797 Polyhedron_Free(C);
00798 Polyhedron_Free(T);
00799
00800 #ifdef EDEBUG6
00801 for(i=0;i<=(d+1);i++) {
00802 value_print(stderr,P_VALUE_FMT,min[i]);
00803 fprintf(stderr," ,");
00804 }
00805 fprintf(stderr,"\n");
00806 Polyhedron_Print(stderr,P_VALUE_FMT,S);
00807 fprintf(stderr,"\n");
00808 #endif
00809
00810 if (!cherche_min(min,S,1))
00811 {
00812 for(i=0;i<=(d+1);i++)
00813 value_clear(min[i]);
00814 value_clear(tmp);
00815 return(NULL);
00816 }
00817 Domain_Free(S);
00818
00819 #ifdef EDEBUG6
00820 fprintf(stderr,"min = ( ");
00821 value_print(stderr,P_VALUE_FMT,min[1]);
00822 for(i=2;i<=d;i++) {
00823 fprintf(stderr,", ");
00824 value_print(stderr,P_VALUE_FMT,min[i]);
00825 }
00826 fprintf(stderr,")\n");
00827 #endif
00828
00829
00830 M = Matrix_Alloc(d*2,d+2);
00831 for(i=0;i<d;i++) {
00832
00833
00834 value_set_si(M->p[2*i][0],1);
00835 for(j=1;j<=d;j++)
00836 value_set_si(M->p[2*i][j],0);
00837 value_set_si(M->p[2*i][i+1],1);
00838 value_oppose(M->p[2*i][d+1],min[i+1]);
00839
00840
00841 value_set_si(M->p[2*i+1][0],1);
00842 for(j=1;j<=d;j++)
00843 value_set_si(M->p[2*i+1][j],0);
00844 value_set_si(M->p[2*i+1][i+1],-1);
00845 value_addto(M->p[2*i+1][d+1],min[i+1],size[i]);
00846 value_sub_int(M->p[2*i+1][d+1],M->p[2*i+1][d+1],1);
00847 }
00848
00849 #ifdef EDEBUG6
00850 fprintf(stderr,"PolyhedronPreprocess: constraints H = ");
00851 Matrix_Print(stderr,P_VALUE_FMT,M);
00852 #endif
00853
00854 H = Constraints2Polyhedron(M,MAXRAYS);
00855
00856 #ifdef EDEBUG6
00857 Polyhedron_Print(stderr,P_VALUE_FMT,H);
00858 fprintf(stderr,"\n");
00859 #endif
00860
00861 Matrix_Free(M);
00862 for(i=0;i<=(d+1);i++)
00863 value_clear(min[i]);
00864 free(min);
00865 value_clear(tmp);
00866 return(H);
00867 }
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883 Polyhedron *Polyhedron_Preprocess2(Polyhedron *D,Value *size,Value *lcm,unsigned MAXRAYS) {
00884
00885 Matrix *c;
00886 Polyhedron *H;
00887 int i,j,r;
00888 Value n;
00889 Value s;
00890 Value tmp1,tmp2;
00891
00892 #ifdef EDEBUG62
00893 int np;
00894 #endif
00895
00896 value_init(n); value_init(s);
00897 value_init(tmp1); value_init(tmp2);
00898 c = Matrix_Alloc(D->Dimension*2,D->Dimension+2);
00899
00900 #ifdef EDEBUG62
00901 fprintf(stderr,"\nPreProcess2 : starting\n");
00902 fprintf(stderr,"lcm = ");
00903 for( np=0 ; np<D->Dimension; np++ )
00904 value_print(stderr,VALUE_FMT,lcm[np]);
00905 fprintf(stderr,", size = ");
00906 for( np=0 ; np<D->Dimension; np++ )
00907 value_print(stderr,VALUE_FMT,size[np]);
00908 fprintf(stderr,"\n");
00909 #endif
00910
00911 for(i=0;i<D->Dimension;i++) {
00912
00913
00914 value_set_si(c->p[2*i][0],1);
00915 for(j=0;j<D->Dimension;j++)
00916 value_set_si(c->p[2*i][1+j],0);
00917 value_division(n,D->Ray[0][i+1],D->Ray[0][D->Dimension+1]);
00918 for(r=1;r<D->NbRays;r++) {
00919 value_division(tmp1,D->Ray[r][i+1],D->Ray[r][D->Dimension+1]);
00920 if(value_gt(n,tmp1)) {
00921
00922
00923 value_division(n,D->Ray[r][i+1],D->Ray[r][D->Dimension+1]);
00924 }
00925 }
00926 value_set_si(c->p[2*i][i+1],1);
00927 value_oppose(c->p[2*i][D->Dimension+1],n);
00928
00929
00930 value_set_si(c->p[2*i+1][0],1);
00931 for(j=0;j<D->Dimension;j++)
00932 value_set_si(c->p[2*i+1][1+j],0);
00933
00934
00935 value_addto(tmp1,D->Ray[0][i+1],D->Ray[0][D->Dimension+1]);
00936 value_sub_int(tmp1,tmp1,1);
00937 value_division(n,tmp1,D->Ray[0][D->Dimension+1]);
00938 for(r=1;r<D->NbRays;r++) {
00939 value_addto(tmp1,D->Ray[r][i+1],D->Ray[r][D->Dimension+1]);
00940 value_sub_int(tmp1,tmp1,1);
00941 value_division(tmp1,tmp1,D->Ray[r][D->Dimension+1]);
00942 if (value_lt(n,tmp1)) {
00943
00944
00945 value_addto(tmp1,D->Ray[r][i+1],D->Ray[r][D->Dimension+1]);
00946 value_sub_int(tmp1,tmp1,1);
00947 value_division(n,tmp1,D->Ray[r][D->Dimension+1]);
00948 }
00949 }
00950 value_set_si(c->p[2*i+1][i+1],-1);
00951 value_assign(c->p[2*i+1][D->Dimension+1],n);
00952 value_addto(s,c->p[2*i+1][D->Dimension+1],c->p[2*i][D->Dimension+1]);
00953
00954
00955 if(value_gt(s,size[i])) {
00956
00957 #ifdef EDEBUG62
00958 fprintf(stderr,"size on dimension %d\n",i);
00959 fprintf(stderr,"lcm = ");
00960 for( np=0 ; np<D->Dimension; np++ )
00961 value_print(stderr,VALUE_FMT,lcm[np]);
00962 fprintf(stderr,", size = ");
00963 for( np=0 ; np<D->Dimension; np++ )
00964 value_print(stderr,VALUE_FMT,size[np]);
00965 fprintf(stderr,"\n");
00966 fprintf(stderr,"required size (s) = ");
00967 value_print(stderr,VALUE_FMT,s);
00968 fprintf(stderr,"\n");
00969 #endif
00970
00971
00972
00973 value_set_si(tmp1,20);
00974 value_addto(tmp2,size[i],size[i]);
00975 if(value_le(s,tmp1)
00976 || value_le(s,tmp2)) {
00977
00978 if( value_zero_p(lcm[i]) )
00979 value_set_si(lcm[i],1);
00980
00981 value_division(tmp1,size[i],lcm[i]);
00982
00983
00984 value_addto(tmp2,s,tmp1);
00985 value_add_int(tmp2,tmp2,1);
00986 value_division(lcm[i],tmp2,tmp1);
00987
00988
00989 value_multiply(size[i],lcm[i],tmp1);
00990
00991 #ifdef EDEBUG62
00992 fprintf(stderr,"new size = ");
00993 for( np=0 ; np<D->Dimension; np++ )
00994 value_print(stderr,VALUE_FMT,size[np]);
00995 fprintf(stderr,", new lcm = ");
00996 for( np=0 ; np<D->Dimension; np++ )
00997 value_print(stderr,VALUE_FMT,lcm[np]);
00998 fprintf(stderr,"\n");
00999 #endif
01000
01001 }
01002 else {
01003
01004 #ifdef EDEBUG62
01005 fprintf(stderr,"Failed on dimension %d.\n",i);
01006 #endif
01007 break;
01008 }
01009 }
01010 }
01011 if(i!=D->Dimension) {
01012 Matrix_Free(c);
01013 value_clear(n); value_clear(s);
01014 value_clear(tmp1); value_clear(tmp2);
01015 return(NULL);
01016 }
01017 for(i=0;i<D->Dimension;i++) {
01018 value_substract(c->p[2*i+1][D->Dimension+1],size[i],
01019 c->p[2*i][D->Dimension+1]);
01020 }
01021
01022 #ifdef EDEBUG62
01023 fprintf(stderr,"PreProcess2 : c =");
01024 Matrix_Print(stderr,P_VALUE_FMT,c);
01025 #endif
01026
01027 H = Constraints2Polyhedron(c,MAXRAYS);
01028 Matrix_Free(c);
01029 value_clear(n); value_clear(s);
01030 value_clear(tmp1); value_clear(tmp2);
01031 return(H);
01032 }
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045 Polyhedron *old_Polyhedron_Preprocess(Polyhedron *D,Value size,unsigned MAXRAYS) {
01046
01047 int p, p1, ub, lb;
01048 Value a, a1, b, b1, g, aa;
01049 Value abs_a, abs_b, size_copy;
01050 int dim, con, new, needed;
01051 Value **C;
01052 Matrix *M;
01053 Polyhedron *D1;
01054
01055 value_init(a); value_init(a1); value_init(b);
01056 value_init(b1); value_init(g); value_init(aa);
01057 value_init(abs_a); value_init(abs_b); value_init(size_copy);
01058
01059 dim = D->Dimension;
01060 con = D->NbConstraints;
01061 M = Matrix_Alloc(MAXRAYS,dim+2);
01062 new = 0;
01063 value_assign(size_copy,size);
01064 C = D->Constraint;
01065 for (p=1; p<=dim; p++) {
01066 for (ub=0; ub<con; ub++) {
01067 value_assign(a,C[ub][p]);
01068 if (value_posz_p(a))
01069 continue;
01070 for (lb=0;lb<con;lb++) {
01071 value_assign(b,C[lb][p]);
01072 if (value_negz_p(b))
01073 continue;
01074
01075
01076
01077
01078 needed=0;
01079 for (p1=1; p1<p; p1++) {
01080 if (value_notzero_p(C[ub][p1]) || value_notzero_p(C[lb][p1])) {
01081 needed=1;
01082 break;
01083 }
01084 }
01085 if (!needed) continue;
01086 value_absolute(abs_a,a);
01087 value_absolute(abs_b,b);
01088
01089
01090 Gcd(abs_a,abs_b,&g);
01091 value_division(a1,a,g);
01092 value_division(b1,b,g);
01093 value_set_si(M->p[new][0],1);
01094 value_oppose(abs_a,a1);
01095 Vector_Combine(&(C[ub][1]),&(C[lb][1]),&(M->p[new][1]),
01096 b1,abs_a,dim+1);
01097 value_multiply(aa,a1,b1);
01098 value_multiply(abs_a,aa,size_copy);
01099 value_addto(M->p[new][dim+1],M->p[new][dim+1],abs_a);
01100 Vector_Normalize(&(M->p[new][1]),(dim+1));
01101 new++;
01102 }
01103 }
01104 }
01105 D1 = AddConstraints(M->p_Init,new,D,MAXRAYS);
01106 Matrix_Free(M);
01107
01108 value_clear(a); value_clear(a1); value_clear(b);
01109 value_clear(b1); value_clear(g); value_clear(aa);
01110 value_clear(abs_a); value_clear(abs_b); value_clear(size_copy);
01111 return D1;
01112 }
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126 void count_points (int pos,Polyhedron *P,Value *context, Value *res) {
01127
01128 Value LB, UB, k, c;
01129
01130 if (emptyQ(P)) {
01131 value_set_si(*res, 0);
01132 return;
01133 }
01134
01135 value_init(LB); value_init(UB); value_init(k);
01136 value_set_si(LB,0);
01137 value_set_si(UB,0);
01138
01139 if (lower_upper_bounds(pos,P,context,&LB,&UB) !=0) {
01140
01141
01142 fprintf(stderr, "count_points: ? infinite domain\n");
01143 value_clear(LB); value_clear(UB); value_clear(k);
01144 value_set_si(*res, -1);
01145 return;
01146 }
01147
01148 #ifdef EDEBUG1
01149 if (!P->next) {
01150 int i;
01151 for (value_assign(k,LB); value_le(k,UB); value_increment(k,k)) {
01152 fprintf(stderr, "(");
01153 for (i=1; i<pos; i++) {
01154 value_print(stderr,P_VALUE_FMT,context[i]);
01155 fprintf(stderr,",");
01156 }
01157 value_print(stderr,P_VALUE_FMT,k);
01158 fprintf(stderr,")\n");
01159 }
01160 }
01161 #endif
01162
01163 value_set_si(context[pos],0);
01164 if (value_lt(UB,LB)) {
01165 value_clear(LB); value_clear(UB); value_clear(k);
01166 value_set_si(*res, 0);
01167 return;
01168 }
01169 if (!P->next) {
01170 value_substract(k,UB,LB);
01171 value_add_int(k,k,1);
01172 value_assign(*res, k);
01173 value_clear(LB); value_clear(UB); value_clear(k);
01174 return;
01175 }
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186 value_init(c);
01187 value_set_si(*res, 0);
01188 for (value_assign(k,LB);value_le(k,UB);value_increment(k,k)) {
01189
01190 value_assign(context[pos],k);
01191 count_points(pos+1,P->next,context,&c);
01192 if(value_notmone_p(c))
01193 value_addto(*res, *res, c);
01194 else {
01195 value_set_si(*res, 0);
01196 break;
01197 }
01198 }
01199 value_clear(c);
01200
01201 #ifdef EDEBUG11
01202 fprintf(stderr,"%d\n",CNT);
01203 #endif
01204
01205
01206 value_set_si(context[pos],0);
01207 value_clear(LB); value_clear(UB); value_clear(k);
01208 return;
01209 }
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224 static enode *P_Enum(Polyhedron *L,Polyhedron *LQ,Value *context,int pos,int nb_param,int dim,Value *lcm,char **param_name) {
01225
01226 enode *res,*B,*C;
01227 int hdim,i,j,rank,flag;
01228 Value n,g,nLB,nUB,nlcm,noff,nexp,k1,nm,hdv,k,lcm_copy;
01229 Value tmp;
01230 Matrix *A;
01231
01232 #ifdef EDEBUG
01233 fprintf(stderr,"-------------------- begin P_Enum -------------------\n");
01234 fprintf(stderr,"Calling P_Enum with pos = %d\n",pos);
01235 #endif
01236
01237
01238 if(nb_param==0) {
01239 res=new_enode(polynomial,1,0);
01240 value_set_si(res->arr[0].d,1);
01241 value_init(res->arr[0].x.n);
01242 count_points(1,L,context,&res->arr[0].x.n);
01243 return res;
01244 }
01245
01246
01247 value_init(n); value_init(g); value_init(nLB);
01248 value_init(nUB); value_init(nlcm); value_init(noff);
01249 value_init(nexp); value_init(k1); value_init(nm);
01250 value_init(hdv); value_init(k); value_init(tmp);
01251 value_init(lcm_copy);
01252
01253 if( value_zero_p(lcm[pos-1]) )
01254 {
01255 hdim = 1;
01256 value_set_si( lcm_copy, 1 );
01257 }
01258 else
01259 {
01260
01261 hdim = dim-nb_param+1;
01262 value_assign( lcm_copy, lcm[pos-1] );
01263 }
01264
01265
01266
01267 flag = lower_upper_bounds(pos,LQ,&context[dim-nb_param],&nLB,&nUB);
01268 if (flag & LB_INFINITY) {
01269 if (!(flag & UB_INFINITY)) {
01270
01271
01272
01273 value_sub_int(nLB,nUB,1);
01274 value_set_si(hdv,hdim);
01275 value_multiply(tmp,hdv,lcm_copy);
01276 value_substract(nLB,nLB,tmp);
01277 if(value_pos_p(nLB))
01278 value_set_si(nLB,0);
01279 }
01280 else {
01281 value_set_si(nLB,0);
01282
01283
01284 value_set_si(hdv,hdim);
01285 value_multiply(nUB,hdv,lcm_copy);
01286 value_add_int(nUB,nUB,1);
01287 }
01288 }
01289
01290
01291
01292
01293
01294
01295
01296 #ifdef REDUCE_DEGREE
01297 if (pos==1 && (flag & UB_INFINITY)==0) {
01298
01299
01300
01301
01302 #ifdef EDEBUG
01303 fprintf(stderr,"*************** n **********\n");
01304 value_print(stderr,VALUE_FMT,n);
01305 fprintf(stderr,"\n");
01306 #endif
01307
01308 value_substract(n,nUB,nLB);
01309 value_increment(n,n);
01310
01311 #ifdef EDEBUG
01312 value_print(stderr,VALUE_FMT,n);
01313 fprintf(stderr,"\n*************** n ************\n");
01314 #endif
01315
01316
01317 if(value_neg_p(n))
01318 i=0;
01319 else {
01320 value_modulus(tmp,n,lcm_copy);
01321 if(value_notzero_p(tmp)) {
01322 value_division(tmp,n,lcm_copy);
01323 value_increment(tmp,tmp);
01324 i = VALUE_TO_INT(tmp);
01325 }
01326 else {
01327 value_division(tmp,n,lcm_copy);
01328 i = VALUE_TO_INT(tmp);
01329 }
01330 }
01331
01332 #ifdef EDEBUG
01333 value_print(stderr,VALUE_FMT,n);
01334 fprintf(stderr,"\n*************** n ************\n");
01335 #endif
01336
01337
01338 if (i < hdim){
01339 hdim=i;
01340
01341 #ifdef EDEBUG4
01342 fprintf(stdout,"Parameter #%d: LB=",pos);
01343 value_print(stdout,VALUE_FMT,nLB);
01344 fprintf(stdout," UB=");
01345 value_print(stdout,VALUE_FMT,nUB);
01346 fprintf(stdout," lcm=");
01347 value_print(stdout,VALUE_FMT,lcm_copy);
01348 fprintf(stdout," degree reduced to %d\n",hdim-1);
01349 #endif
01350
01351 }
01352 }
01353 #endif
01354
01355
01356
01357 res = new_enode(polynomial,hdim,pos);
01358 for (i=0;i<hdim;i++) {
01359 int l;
01360 l = VALUE_TO_INT(lcm_copy);
01361 res->arr[i].x.p = new_enode(periodic,l,pos);
01362 }
01363
01364
01365 A = Matrix_Alloc(hdim, 2*hdim+1);
01366 B = new_enode(evector, hdim, 0);
01367 C = new_enode(evector, hdim, 0);
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378 if(value_neg_p(nLB)) {
01379 value_modulus(nlcm,nLB,lcm_copy);
01380 value_addto(nlcm,nlcm,lcm_copy);
01381 }
01382 else {
01383 value_modulus(nlcm,nLB,lcm_copy);
01384 }
01385
01386
01387 value_substract(noff,nLB,nlcm);
01388 value_addto(tmp,lcm_copy,nlcm);
01389 for (value_assign(k,nlcm);value_lt(k,tmp);value_increment(k,k)) {
01390
01391 #ifdef EDEBUG
01392 fprintf(stderr,"Finding ");
01393 value_print(stderr,VALUE_FMT,k);
01394 fprintf(stderr,"-th elements of periodic coefficients\n");
01395 #endif
01396
01397 value_set_si(hdv,hdim);
01398 value_multiply(nm,hdv,lcm_copy);
01399 value_addto(nm,nm,nLB);
01400 i=0;
01401 for (value_addto(n,k,noff); value_lt(n,nm); value_addto(n,n,lcm_copy),i++) {
01402
01403
01404
01405
01406
01407 #ifdef ALL_OVERFLOW_WARNINGS
01408 if (((flag & UB_INFINITY)==0) && value_gt(n,nUB)) {
01409 fprintf(stdout,"Domain Overflow: Parameter #%d:",pos);
01410 fprintf(stdout,"nLB=");
01411 value_print(stdout,VALUE_FMT,nLB);
01412 fprintf(stdout," n=");
01413 value_print(stdout,VALUE_FMT,n);
01414 fprintf(stdout," nUB=");
01415 value_print(stdout,VALUE_FMT,nUB);
01416 fprintf(stdout,"\n");
01417 }
01418 #else
01419 if (overflow_warning_flag && ((flag & UB_INFINITY)==0) &&
01420 value_gt(n,nUB)) {
01421 fprintf(stdout,"\nWARNING: Parameter Domain Overflow.");
01422 fprintf(stdout," Result may be incorrect on this domain.\n");
01423 overflow_warning_flag = 0;
01424 }
01425 #endif
01426
01427
01428 value_assign(context[dim-nb_param+pos],n);
01429
01430 #ifdef EDEBUG1
01431 if( param_name )
01432 {
01433 fprintf(stderr,"%s = ",param_name[pos-1]);
01434 value_print(stderr,VALUE_FMT,n);
01435 fprintf(stderr," (hdim=%d, lcm[%d]=",hdim,pos-1);
01436 value_print(stderr,VALUE_FMT,lcm_copy);
01437 fprintf(stderr,")\n");
01438 }
01439 else
01440 {
01441 fprintf(stderr,"P%d = ",pos);
01442 value_print(stderr,VALUE_FMT,n);
01443 fprintf(stderr," (hdim=%d, lcm[%d]=",hdim,pos-1);
01444 value_print(stderr,VALUE_FMT,lcm_copy);
01445 fprintf(stderr,")\n");
01446 }
01447 #endif
01448
01449
01450 if (pos==nb_param) {
01451
01452 #ifdef EDEBUG
01453 fprintf(stderr,"Yes\n");
01454 #endif
01455
01456
01457
01458 value_set_si(B->arr[i].d,1);
01459 value_init(B->arr[i].x.n);
01460 count_points(1,L,context,&B->arr[i].x.n);
01461
01462 #ifdef EDEBUG3
01463 for (j=1; j<pos; j++) fputs(" ",stdout);
01464 fprintf(stdout, "E(");
01465 for (j=1; j<nb_param; j++) {
01466 value_print(stdout,VALUE_FMT,context[dim-nb_param+j]);
01467 fprintf(stdout,",");
01468 }
01469 value_print(stdout,VALUE_FMT,n);
01470 fprintf(stdout,") = ");
01471 value_print(stdout,VALUE_FMT,B->arr[i].x.n);
01472 fprintf(stdout," =");
01473 #endif
01474
01475 }
01476 else {
01477
01478 value_set_si(B->arr[i].d,0);
01479 B->arr[i].x.p = P_Enum(L,LQ->next,context,pos+1,nb_param,dim,lcm,param_name);
01480
01481 #ifdef EDEBUG3
01482 if( param_name )
01483 {
01484 for (j=1; j<pos; j++)
01485 fputs(" ", stdout);
01486 fprintf(stdout, "E(");
01487 for (j=1; j<=pos; j++) {
01488 value_print(stdout,VALUE_FMT,context[dim-nb_param+j]);
01489 fprintf(stdout,",");
01490 }
01491 for (j=pos+1; j<nb_param; j++)
01492 fprintf(stdout,"%s,",param_name[j]);
01493 fprintf(stdout,"%s) = ",param_name[j]);
01494 print_enode(stdout,B->arr[i].x.p,param_name);
01495 fprintf(stdout," =");
01496 }
01497 #endif
01498
01499 }
01500
01501
01502
01503
01504 value_set_si(A->p[i][0],0);
01505 value_set_si(nexp,1);
01506 for (j=1;j<=hdim;j++) {
01507 value_assign(A->p[i][j],nexp);
01508 value_set_si(A->p[i][j+hdim],0);
01509
01510 #ifdef EDEBUG3
01511 fprintf(stdout," + ");
01512 value_print(stdout,VALUE_FMT,nexp);
01513 fprintf(stdout," c%d",j);
01514 #endif
01515 value_multiply(nexp,nexp,n);
01516 }
01517
01518 #ifdef EDEBUG3
01519 fprintf(stdout, "\n");
01520 #endif
01521
01522 value_set_si(A->p[i][i+1+hdim],1);
01523 }
01524
01525
01526 if (i!=hdim)
01527 fprintf(stderr, "P_Enum: ?expecting i==hdim\n");
01528
01529 #ifdef EDEBUG
01530 if( param_name )
01531 {
01532 fprintf(stderr,"B (enode) =\n");
01533 print_enode(stderr,B,param_name);
01534 }
01535 fprintf(stderr,"A (Before Gauss) =\n");
01536 Matrix_Print(stderr,P_VALUE_FMT,A);
01537 #endif
01538
01539
01540 rank = Gauss(A,hdim,2*hdim);
01541
01542 #ifdef EDEBUG
01543 fprintf(stderr,"A (After Gauss) =\n");
01544 Matrix_Print(stderr,P_VALUE_FMT,A);
01545 #endif
01546
01547
01548 if (rank!=hdim) {
01549 fprintf(stderr, "P_Enum: ?expecting rank==hdim\n");
01550 }
01551
01552
01553
01554
01555 if(value_lt(k,lcm_copy))
01556 value_assign(k1,k);
01557 else
01558 value_substract(k1,k,lcm_copy);
01559
01560 for (i=0; i<rank; i++) {
01561
01562
01563 for (j=0; j<rank; j++) {
01564 Gcd(A->p[i][i+1],A->p[i][j+1+hdim],&g);
01565 value_division(C->arr[j].d,A->p[i][i+1],g);
01566 value_init(C->arr[j].x.n);
01567 value_division(C->arr[j].x.n,A->p[i][j+1+hdim],g);
01568 }
01569
01570 #ifdef EDEBUG
01571 if( param_name )
01572 {
01573 fprintf(stderr, "C (enode) =\n");
01574 print_enode(stderr, C, param_name);
01575 }
01576 #endif
01577
01578
01579 edot(B,C,&(res->arr[i].x.p->arr[VALUE_TO_INT(k1)]));
01580
01581 #ifdef EDEBUG
01582 if( param_name )
01583 {
01584 fprintf(stderr, "B.C (evalue)=\n");
01585 print_evalue(stderr,&(res->arr[i].x.p->arr[VALUE_TO_INT(k1)]),param_name );
01586 fprintf(stderr,"\n");
01587 }
01588 #endif
01589
01590 }
01591 value_addto(tmp,lcm_copy,nlcm);
01592 }
01593
01594 #ifdef EDEBUG
01595 if( param_name )
01596 {
01597 fprintf(stderr,"res (enode) =\n");
01598 print_enode(stderr,res,param_name);
01599 }
01600 fprintf(stderr, "-------------------- end P_Enum -----------------------\n");
01601 #endif
01602
01603
01604 value_set_si(context[dim-nb_param+pos],0);
01605
01606
01607 Matrix_Free(A);
01608 free(B);
01609 free(C);
01610
01611
01612 value_clear(n); value_clear(g); value_clear(nLB);
01613 value_clear(nUB); value_clear(nlcm); value_clear(noff);
01614 value_clear(nexp); value_clear(k1); value_clear(nm);
01615 value_clear(hdv); value_clear(k); value_clear(tmp);
01616 value_clear(lcm_copy);
01617 return res;
01618 }
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629 static void Scan_Vertices(Param_Polyhedron *PP,Param_Domain *Q,Matrix *CT,
01630 Value *lcm, int nbp, char **param_name )
01631 {
01632 Param_Vertices *V;
01633 int i, j, ix, l, np;
01634 unsigned bx;
01635 Value k,m1;
01636
01637
01638
01639
01640
01641 value_init(k); value_init(m1);
01642 for( np=0 ; np<nbp ; np++ )
01643 value_set_si( lcm[np], 0 );
01644
01645 if( param_name )
01646 fprintf(stdout,"Vertices:\n");
01647
01648 for(i=0,ix=0,bx=MSB,V=PP->V; V && i<PP->nbV; i++,V=V->next) {
01649 if (Q->F[ix] & bx) {
01650 if( param_name )
01651 {
01652 if(CT) {
01653 Matrix *v;
01654 v = VertexCT(V->Vertex,CT);
01655 Print_Vertex(stdout,v,param_name);
01656 Matrix_Free(v);
01657 }
01658 else
01659 Print_Vertex(stdout,V->Vertex,param_name);
01660 fprintf(stdout,"\n");
01661 }
01662
01663 for(j=0;j<V->Vertex->NbRows;j++) {
01664
01665 for( l=0 ; l<V->Vertex->NbColumns-2 ; l++ )
01666 {
01667 if( value_notzero_p(V->Vertex->p[j][l]) )
01668 {
01669 Gcd(V->Vertex->p[j][V->Vertex->NbColumns-1],V->Vertex->p[j][l], &m1);
01670 value_division(k,V->Vertex->p[j][V->Vertex->NbColumns-1],m1);
01671 if( value_notzero_p(lcm[l]) )
01672 {
01673
01674 if (value_notzero_p(k) && value_notone_p(k))
01675 {
01676 Gcd(lcm[l],k,&m1);
01677 value_division(k,k,m1);
01678 value_multiply(lcm[l],lcm[l],k);
01679 }
01680 }
01681 else
01682 {
01683 value_assign(lcm[l],k);
01684 }
01685 }
01686 }
01687 }
01688 }
01689 NEXT(ix,bx);
01690 }
01691 value_clear(k); value_clear(m1);
01692 }
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706 Enumeration *Enumerate_NoParameters(Polyhedron *P,Polyhedron *C,Matrix *CT,Polyhedron *CEq,unsigned MAXRAYS,char **param_name) {
01707
01708 Polyhedron *L;
01709 Enumeration *res;
01710 Value *context,tmp;
01711 int j;
01712 int hdim = P->Dimension + 1;
01713 int r,i;
01714
01715
01716 context = (Value *) malloc((hdim+1)*sizeof(Value));
01717 for (j=0;j<= hdim;j++)
01718 value_init(context[j]);
01719 value_init(tmp);
01720
01721 res = (Enumeration *)malloc(sizeof(Enumeration));
01722 res->next = NULL;
01723 res->ValidityDomain = Universe_Polyhedron(0);
01724 value_init(res->EP.d);
01725 value_set_si(res->EP.d,0);
01726 L = Polyhedron_Scan(P,res->ValidityDomain,MAXRAYS);
01727
01728 #ifdef EDEBUG2
01729 fprintf(stderr, "L = \n");
01730 Polyhedron_Print(stderr, P_VALUE_FMT, L);
01731 #endif
01732
01733 if(CT) {
01734 Polyhedron *Dt;
01735
01736
01737 Dt = Polyhedron_Preimage(res->ValidityDomain,CT,MAXRAYS);
01738 Polyhedron_Free(res->ValidityDomain);
01739 res->ValidityDomain = DomainIntersection(Dt,CEq,MAXRAYS);
01740 Polyhedron_Free(Dt);
01741 }
01742
01743 if( param_name )
01744 {
01745 fprintf(stdout,"---------------------------------------\n");
01746 fprintf(stdout,"Domain:\n");
01747 Print_Domain(stdout,res->ValidityDomain, param_name);
01748
01749
01750 printf("Vertices:\n");
01751 for(r=0;r<P->NbRays;++r) {
01752 if(value_zero_p(P->Ray[r][0]))
01753 printf("(line) ");
01754 printf("[");
01755 if (P->Dimension > 0)
01756 value_print(stdout,P_VALUE_FMT,P->Ray[r][1]);
01757 for(i=1;i<P->Dimension;i++) {
01758 printf(", ");
01759 value_print(stdout,P_VALUE_FMT,P->Ray[r][i+1]);
01760 }
01761 printf("]");
01762 if(value_notone_p(P->Ray[r][P->Dimension+1])) {
01763 printf("/");
01764 value_print(stdout,P_VALUE_FMT, P->Ray[r][P->Dimension+1]);
01765 }
01766 printf("\n");
01767 }
01768 }
01769 if (emptyQ(P)) {
01770 res->EP.x.p = new_enode(polynomial,1,0);;
01771 value_set_si(res->EP.x.p->arr[0].d, 1);
01772 value_init(res->EP.x.p->arr[0].x.n);
01773 value_set_si(res->EP.x.p->arr[0].x.n, 0);
01774 } else if (!L) {
01775
01776 res->EP.x.p = new_enode(polynomial,1,0);;
01777 value_set_si(res->EP.x.p->arr[0].d, 1);
01778 value_init(res->EP.x.p->arr[0].x.n);
01779 value_set_si(res->EP.x.p->arr[0].x.n, 1);
01780 } else {
01781 CATCH(overflow_error) {
01782 fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
01783 fprintf(stderr,"You should rebuild PolyLib using GNU-MP or increasing the size of integers.\n");
01784 overflow_warning_flag = 0;
01785 assert(overflow_warning_flag);
01786 }
01787 TRY {
01788
01789 Vector_Set(context,0,(hdim+1));
01790
01791
01792 value_set_si(context[hdim],1);
01793 value_set_si(tmp,1);
01794 res->EP.x.p = P_Enum(L,NULL,context,1,0,hdim-1,&tmp,param_name);
01795 UNCATCH(overflow_error);
01796 }
01797 }
01798
01799 Domain_Free(L);
01800
01801
01802
01803
01804
01805
01806 if( param_name )
01807 {
01808 fprintf(stdout,"\nEhrhart Polynomial:\n");
01809 print_evalue(stdout,&res->EP,param_name);
01810 fprintf(stdout, "\n");
01811 }
01812
01813 value_clear(tmp);
01814 for (j=0;j<= hdim;j++)
01815 value_clear(context[j]);
01816 free(context);
01817 return(res);
01818 }
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829 Enumeration *Polyhedron_Enumerate(Polyhedron *Pi,Polyhedron *C,unsigned MAXRAYS,char **param_name)
01830 {
01831 Polyhedron *L, *CQ, *CQ2, *LQ, *U, *CEq, *rVD, *P;
01832 Matrix *CT;
01833 Param_Polyhedron *PP;
01834 Param_Domain *Q;
01835 int i,hdim, dim, nb_param, np;
01836 Value *lcm, *m1, hdv;
01837 Value *context;
01838 Enumeration *en, *res;
01839
01840 res = NULL;
01841 P = Pi;
01842
01843 #ifdef EDEBUG2
01844 fprintf(stderr,"C = \n");
01845 Polyhedron_Print(stderr,P_VALUE_FMT,C);
01846 fprintf(stderr,"P = \n");
01847 Polyhedron_Print(stderr,P_VALUE_FMT,P);
01848 #endif
01849
01850 hdim = P->Dimension + 1;
01851 dim = P->Dimension;
01852 nb_param = C->Dimension;
01853
01854
01855 if(nb_param == 0) {
01856
01857 return(Enumerate_NoParameters(P,C,NULL,NULL,MAXRAYS,param_name));
01858 }
01859 PP = Polyhedron2Param_SimplifiedDomain(&P,C,MAXRAYS,&CEq,&CT);
01860 if(!PP) {
01861 if( param_name )
01862 fprintf(stdout, "\nEhrhart Polynomial:\nNULL\n");
01863
01864 return(NULL);
01865 }
01866
01867
01868 if(CT) {
01869 nb_param -= CT->NbColumns-CT->NbRows;
01870 dim -= CT->NbColumns-CT->NbRows;
01871 hdim -= CT->NbColumns-CT->NbRows;
01872
01873
01874 if(nb_param == 0)
01875 {
01876 res = Enumerate_NoParameters(P,C,CT,CEq,MAXRAYS,param_name);
01877 if( P != Pi )
01878 Polyhedron_Free( P );
01879 return( res );
01880 }
01881 }
01882
01883
01884 lcm = (Value *)malloc( nb_param * sizeof(Value));
01885 m1 = (Value *)malloc( nb_param * sizeof(Value));
01886
01887 for( np=0 ; np<nb_param ; np++ )
01888 {
01889 value_init(lcm[np]); value_init(m1[np]);
01890 }
01891 value_init(hdv);
01892
01893 for(Q=PP->D;Q;Q=Q->next) {
01894 if(CT) {
01895 Polyhedron *Dt;
01896 CQ = Q->Domain;
01897 Dt = Polyhedron_Preimage(Q->Domain,CT,MAXRAYS);
01898 rVD = DomainIntersection(Dt,CEq,MAXRAYS);
01899
01900
01901 if(!rVD || emptyQ(rVD) ||
01902 (rVD->Dimension-rVD->NbEq < Dt->Dimension-Dt->NbEq-CEq->NbEq)) {
01903 if(rVD)
01904 Polyhedron_Free(rVD);
01905 Polyhedron_Free(Dt);
01906 continue;
01907 }
01908 Polyhedron_Free(Dt);
01909 }
01910 else
01911 rVD = CQ = Q->Domain;
01912 en = (Enumeration *)malloc(sizeof(Enumeration));
01913 en->next = res;
01914 res = en;
01915 res->ValidityDomain = rVD;
01916
01917 if( param_name )
01918 {
01919 fprintf(stdout,"---------------------------------------\n");
01920 fprintf(stdout,"Domain:\n");
01921
01922 #ifdef EPRINT_ALL_VALIDITY_CONSTRAINTS
01923 Print_Domain(stdout,res->ValidityDomain,param_name);
01924 #else
01925 {
01926 Polyhedron *VD;
01927 VD = DomainSimplify(res->ValidityDomain,C,MAXRAYS);
01928 Print_Domain(stdout,VD,param_name);
01929 Domain_Free(VD);
01930 }
01931 #endif
01932 }
01933
01934 overflow_warning_flag = 1;
01935
01936
01937 Scan_Vertices(PP,Q,CT,lcm,nb_param,param_name);
01938
01939 #ifdef EDEBUG2
01940 fprintf(stderr,"Denominator = ");
01941 for( np=0;np<nb_param;np++)
01942 value_print(stderr,P_VALUE_FMT,lcm[np]);
01943 fprintf(stderr," and hdim == %d \n",hdim);
01944 #endif
01945
01946 #ifdef EDEBUG2
01947 fprintf(stderr,"CQ = \n");
01948 Polyhedron_Print(stderr,P_VALUE_FMT,CQ);
01949 #endif
01950
01951
01952
01953 value_set_si(hdv,hdim-nb_param);
01954
01955 for( np=0;np<nb_param;np++)
01956 {
01957 if( value_notzero_p(lcm[np]) )
01958 value_multiply(m1[np],hdv,lcm[np]);
01959 else
01960 value_set_si(m1[np],1);
01961 }
01962
01963 #ifdef EDEBUG2
01964 fprintf(stderr,"m1 == ");
01965 for( np=0;np<nb_param;np++)
01966 value_print(stderr,P_VALUE_FMT,m1[np]);
01967 fprintf(stderr,"\n");
01968 #endif
01969
01970 CATCH(overflow_error) {
01971 fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
01972 CQ2 = NULL;
01973 }
01974 TRY {
01975 CQ2 = Polyhedron_Preprocess(CQ,m1,MAXRAYS);
01976
01977 #ifdef EDEBUG2
01978 fprintf(stderr,"After preprocess, CQ2 = ");
01979 Polyhedron_Print(stderr,P_VALUE_FMT,CQ2);
01980 #endif
01981
01982 UNCATCH(overflow_error);
01983 }
01984
01985
01986
01987 if ((!CQ2 || emptyQ(CQ2)) && CQ->NbBid==0) {
01988 int r;
01989
01990 #ifdef EDEBUG2
01991 fprintf(stderr,"Trying to call Polyhedron_Preprocess2 : CQ = \n");
01992 Polyhedron_Print(stderr,P_VALUE_FMT,CQ);
01993 #endif
01994
01995
01996 for(r=0;r<CQ->NbRays;r++) {
01997 if(value_zero_p(CQ->Ray[r][0]) ||
01998 value_zero_p(CQ->Ray[r][CQ->Dimension+1]))
01999 break;
02000 }
02001 if(r==CQ->NbRays) {
02002
02003
02004
02005 CQ2 = Polyhedron_Preprocess2(CQ,m1,lcm,MAXRAYS);
02006 }
02007 }
02008 if (!CQ2 || emptyQ(CQ2)) {
02009 #ifdef EDEBUG2
02010 fprintf(stderr,"Degenerate.\n");
02011 #endif
02012 fprintf(stdout,"Degenerate Domain. Can not continue.\n");
02013 value_init(res->EP.d);
02014 value_init(res->EP.x.n);
02015 value_set_si(res->EP.d,1);
02016 value_set_si(res->EP.x.n,-1);
02017 }
02018 else {
02019
02020 #ifdef EDEBUG2
02021 fprintf(stderr,"CQ2 = \n");
02022 Polyhedron_Print(stderr,P_VALUE_FMT,CQ2);
02023 if( ! PolyhedronIncludes(CQ, CQ2) )
02024 fprintf( stderr,"CQ does not include CQ2 !\n");
02025 else
02026 fprintf( stderr,"CQ includes CQ2.\n");
02027 if( ! PolyhedronIncludes(res->ValidityDomain, CQ2) )
02028 fprintf( stderr,"CQ2 is *not* included in validity domain !\n");
02029 else
02030 fprintf( stderr,"CQ2 is included in validity domain.\n");
02031 #endif
02032
02033
02034 L = Polyhedron_Scan(P,CQ,MAXRAYS);
02035 U = Universe_Polyhedron(0);
02036
02037
02038 LQ = Polyhedron_Scan(CQ2,U,MAXRAYS);
02039 Domain_Free(U);
02040 if(CT)
02041 Domain_Free(CQ);
02042
02043
02044 Domain_Free(CQ2);
02045
02046 #ifdef EDEBUG2
02047 fprintf(stderr,"L = \n");
02048 Polyhedron_Print(stderr,P_VALUE_FMT,L);
02049 fprintf(stderr,"LQ = \n");
02050 Polyhedron_Print(stderr,P_VALUE_FMT,LQ);
02051 #endif
02052 #ifdef EDEBUG3
02053 fprintf(stdout,"\nSystem of Equations:\n");
02054 #endif
02055
02056 value_init(res->EP.d);
02057 value_set_si(res->EP.d,0);
02058
02059
02060 context = (Value *) malloc ((hdim+1)*sizeof(Value));
02061 for(i=0;i<=(hdim);i++)
02062 value_init(context[i]);
02063 Vector_Set(context,0,(hdim+1));
02064
02065
02066 value_set_si(context[hdim],1);
02067
02068 CATCH(overflow_error) {
02069 fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
02070 fprintf(stderr,"You should rebuild PolyLib using GNU-MP or increasing the size of integers.\n");
02071 overflow_warning_flag = 0;
02072 assert(overflow_warning_flag);
02073
02074 }
02075 TRY {
02076 res->EP.x.p = P_Enum(L,LQ,context,1,nb_param,dim,lcm,param_name);
02077 UNCATCH(overflow_error);
02078 }
02079
02080 for(i=0;i<=(hdim);i++)
02081 value_clear(context[i]);
02082 free(context);
02083 Domain_Free(L);
02084 Domain_Free(LQ);
02085
02086 #ifdef EDEBUG5
02087 if( param_name )
02088 {
02089 fprintf(stdout,"\nEhrhart Polynomial (before simplification):\n");
02090 print_evalue(stdout,&res->EP,param_name);
02091 }
02092 #endif
02093
02094
02095 reduce_evalue(&res->EP);
02096
02097
02098
02099 if(CT)
02100 addeliminatedparams_evalue(&res->EP,CT);
02101
02102 if( param_name )
02103 {
02104 fprintf(stdout,"\nEhrhart Polynomial:\n");
02105 print_evalue(stdout,&res->EP, param_name);
02106 fprintf(stdout,"\n");
02107
02108 }
02109
02110 }
02111 }
02112
02113 if( P != Pi )
02114 Polyhedron_Free( P );
02115
02116 for( np=0; np<nb_param ; np++ )
02117 {
02118 value_clear(lcm[np]); value_clear(m1[np]);
02119 }
02120 value_clear(hdv);
02121
02122 return res;
02123 }
02124
02125 void Enumeration_Free(Enumeration *en)
02126 {
02127 Enumeration *ee;
02128
02129 while( en )
02130 {
02131 free_evalue_refs( &(en->EP) );
02132 Polyhedron_Free( en->ValidityDomain );
02133 ee = en ->next;
02134 free( en );
02135 en = ee;
02136 }
02137 }
02138
02139
02140