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