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, const 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, const 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 value_gcd(g, res->x.n, res->d);
00369 if (value_notone_p(g)) {
00370 value_divexact(res->d, res->d, g);
00371 value_divexact(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 value_gcd(g, res->x.n, res->d);
00410 if (value_notone_p(g)) {
00411 value_divexact(res->d, res->d, g);
00412 value_divexact(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 d = D->Dimension;
00735 if (MAXRAYS < 2*D->NbConstraints)
00736 MAXRAYS = 2*D->NbConstraints;
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,
00758 "an equality was found where I did expect an inequality.\n");
00759 fprintf(stderr,"Trying to continue...\n");
00760 continue;
00761 }
00762 Vector_Copy(D->Constraint[i],M->p[M->NbRows],(d+2));
00763 for(j=1;j<=d;j++)
00764 if(value_neg_p(D->Constraint[i][j])) {
00765 value_addmul(M->p[M->NbRows][d+1], D->Constraint[i][j], size[j-1]);
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 return(NULL);
00784 }
00785
00786
00787 min = (Value *) malloc(sizeof(Value) * (d+2));
00788 for(i=0;i<=d;i++) {
00789 value_init(min[i]);
00790 value_set_si(min[i],0);
00791 }
00792 value_init(min[i]);
00793 value_set_si(min[i],1);
00794 C = Universe_Polyhedron(0);
00795 S = Polyhedron_Scan(T,C,MAXRAYS);
00796 Polyhedron_Free(C);
00797 Polyhedron_Free(T);
00798
00799 #ifdef EDEBUG6
00800 for(i=0;i<=(d+1);i++) {
00801 value_print(stderr,P_VALUE_FMT,min[i]);
00802 fprintf(stderr," ,");
00803 }
00804 fprintf(stderr,"\n");
00805 Polyhedron_Print(stderr,P_VALUE_FMT,S);
00806 fprintf(stderr,"\n");
00807 #endif
00808
00809 if (!cherche_min(min,S,1))
00810 {
00811 for(i=0;i<=(d+1);i++)
00812 value_clear(min[i]);
00813 return(NULL);
00814 }
00815 Domain_Free(S);
00816
00817 #ifdef EDEBUG6
00818 fprintf(stderr,"min = ( ");
00819 value_print(stderr,P_VALUE_FMT,min[1]);
00820 for(i=2;i<=d;i++) {
00821 fprintf(stderr,", ");
00822 value_print(stderr,P_VALUE_FMT,min[i]);
00823 }
00824 fprintf(stderr,")\n");
00825 #endif
00826
00827
00828 M = Matrix_Alloc(d*2,d+2);
00829 for(i=0;i<d;i++) {
00830
00831
00832 value_set_si(M->p[2*i][0],1);
00833 for(j=1;j<=d;j++)
00834 value_set_si(M->p[2*i][j],0);
00835 value_set_si(M->p[2*i][i+1],1);
00836 value_oppose(M->p[2*i][d+1],min[i+1]);
00837
00838
00839 value_set_si(M->p[2*i+1][0],1);
00840 for(j=1;j<=d;j++)
00841 value_set_si(M->p[2*i+1][j],0);
00842 value_set_si(M->p[2*i+1][i+1],-1);
00843 value_addto(M->p[2*i+1][d+1],min[i+1],size[i]);
00844 value_sub_int(M->p[2*i+1][d+1],M->p[2*i+1][d+1],1);
00845 }
00846
00847 #ifdef EDEBUG6
00848 fprintf(stderr,"PolyhedronPreprocess: constraints H = ");
00849 Matrix_Print(stderr,P_VALUE_FMT,M);
00850 #endif
00851
00852 H = Constraints2Polyhedron(M,MAXRAYS);
00853
00854 #ifdef EDEBUG6
00855 Polyhedron_Print(stderr,P_VALUE_FMT,H);
00856 fprintf(stderr,"\n");
00857 #endif
00858
00859 Matrix_Free(M);
00860 for(i=0;i<=(d+1);i++)
00861 value_clear(min[i]);
00862 free(min);
00863 assert(!emptyQ(H));
00864 return(H);
00865 }
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882 Polyhedron *Polyhedron_Preprocess2(Polyhedron *D,Value *size,
00883 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
00974 value_set_si(tmp1,20);
00975 value_addto(tmp2,size[i],size[i]);
00976 if(value_le(s,tmp1)
00977 || value_le(s,tmp2)) {
00978
00979 if( value_zero_p(lcm[i]) )
00980 value_set_si(lcm[i],1);
00981
00982 value_division(tmp1,size[i],lcm[i]);
00983
00984
00985 value_addto(tmp2,s,tmp1);
00986 value_add_int(tmp2,tmp2,1);
00987 value_division(lcm[i],tmp2,tmp1);
00988
00989
00990 value_multiply(size[i],lcm[i],tmp1);
00991
00992 #ifdef EDEBUG62
00993 fprintf(stderr,"new size = ");
00994 for( np=0 ; np<D->Dimension; np++ )
00995 value_print(stderr,VALUE_FMT,size[np]);
00996 fprintf(stderr,", new lcm = ");
00997 for( np=0 ; np<D->Dimension; np++ )
00998 value_print(stderr,VALUE_FMT,lcm[np]);
00999 fprintf(stderr,"\n");
01000 #endif
01001
01002 }
01003 else {
01004
01005 #ifdef EDEBUG62
01006 fprintf(stderr,"Failed on dimension %d.\n",i);
01007 #endif
01008 break;
01009 }
01010 }
01011 }
01012 if(i!=D->Dimension) {
01013 Matrix_Free(c);
01014 value_clear(n); value_clear(s);
01015 value_clear(tmp1); value_clear(tmp2);
01016 return(NULL);
01017 }
01018 for(i=0;i<D->Dimension;i++) {
01019 value_subtract(c->p[2*i+1][D->Dimension+1],size[i],
01020 c->p[2*i][D->Dimension+1]);
01021 }
01022
01023 #ifdef EDEBUG62
01024 fprintf(stderr,"PreProcess2 : c =");
01025 Matrix_Print(stderr,P_VALUE_FMT,c);
01026 #endif
01027
01028 H = Constraints2Polyhedron(c,MAXRAYS);
01029 Matrix_Free(c);
01030 value_clear(n); value_clear(s);
01031 value_clear(tmp1); value_clear(tmp2);
01032 return(H);
01033 }
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046 Polyhedron *old_Polyhedron_Preprocess(Polyhedron *D,Value size,
01047 unsigned MAXRAYS) {
01048
01049 int p, p1, ub, lb;
01050 Value a, a1, b, b1, g, aa;
01051 Value abs_a, abs_b, size_copy;
01052 int dim, con, newi, needed;
01053 Value **C;
01054 Matrix *M;
01055 Polyhedron *D1;
01056
01057 value_init(a); value_init(a1); value_init(b);
01058 value_init(b1); value_init(g); value_init(aa);
01059 value_init(abs_a); value_init(abs_b); value_init(size_copy);
01060
01061 dim = D->Dimension;
01062 con = D->NbConstraints;
01063 M = Matrix_Alloc(MAXRAYS,dim+2);
01064 newi = 0;
01065 value_assign(size_copy,size);
01066 C = D->Constraint;
01067 for (p=1; p<=dim; p++) {
01068 for (ub=0; ub<con; ub++) {
01069 value_assign(a,C[ub][p]);
01070 if (value_posz_p(a))
01071 continue;
01072 for (lb=0;lb<con;lb++) {
01073 value_assign(b,C[lb][p]);
01074 if (value_negz_p(b))
01075 continue;
01076
01077
01078
01079
01080 needed=0;
01081 for (p1=1; p1<p; p1++) {
01082 if (value_notzero_p(C[ub][p1]) ||
01083 value_notzero_p(C[lb][p1])) {
01084 needed=1;
01085 break;
01086 }
01087 }
01088 if (!needed) continue;
01089 value_absolute(abs_a,a);
01090 value_absolute(abs_b,b);
01091
01092
01093 value_gcd(g, abs_a, abs_b);
01094 value_divexact(a1, a, g);
01095 value_divexact(b1, b, g);
01096 value_set_si(M->p[newi][0],1);
01097 value_oppose(abs_a,a1);
01098 Vector_Combine(&(C[ub][1]),&(C[lb][1]),&(M->p[newi][1]),
01099 b1,abs_a,dim+1);
01100 value_multiply(aa,a1,b1);
01101 value_addmul(M->p[newi][dim+1], aa, size_copy);
01102 Vector_Normalize(&(M->p[newi][1]),(dim+1));
01103 newi++;
01104 }
01105 }
01106 }
01107 D1 = AddConstraints(M->p_Init,newi,D,MAXRAYS);
01108 Matrix_Free(M);
01109
01110 value_clear(a); value_clear(a1); value_clear(b);
01111 value_clear(b1); value_clear(g); value_clear(aa);
01112 value_clear(abs_a); value_clear(abs_b); value_clear(size_copy);
01113 return D1;
01114 }
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128 void count_points (int pos,Polyhedron *P,Value *context, Value *res) {
01129
01130 Value LB, UB, k, c;
01131
01132 POL_ENSURE_FACETS(P);
01133 POL_ENSURE_VERTICES(P);
01134
01135 if (emptyQ(P)) {
01136 value_set_si(*res, 0);
01137 return;
01138 }
01139
01140 value_init(LB); value_init(UB); value_init(k);
01141 value_set_si(LB,0);
01142 value_set_si(UB,0);
01143
01144 if (lower_upper_bounds(pos,P,context,&LB,&UB) !=0) {
01145
01146
01147 fprintf(stderr, "count_points: ? infinite domain\n");
01148 value_clear(LB); value_clear(UB); value_clear(k);
01149 value_set_si(*res, -1);
01150 return;
01151 }
01152
01153 #ifdef EDEBUG1
01154 if (!P->next) {
01155 int i;
01156 for (value_assign(k,LB); value_le(k,UB); value_increment(k,k)) {
01157 fprintf(stderr, "(");
01158 for (i=1; i<pos; i++) {
01159 value_print(stderr,P_VALUE_FMT,context[i]);
01160 fprintf(stderr,",");
01161 }
01162 value_print(stderr,P_VALUE_FMT,k);
01163 fprintf(stderr,")\n");
01164 }
01165 }
01166 #endif
01167
01168 value_set_si(context[pos],0);
01169 if (value_lt(UB,LB)) {
01170 value_clear(LB); value_clear(UB); value_clear(k);
01171 value_set_si(*res, 0);
01172 return;
01173 }
01174 if (!P->next) {
01175 value_subtract(k,UB,LB);
01176 value_add_int(k,k,1);
01177 value_assign(*res, k);
01178 value_clear(LB); value_clear(UB); value_clear(k);
01179 return;
01180 }
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191 value_init(c);
01192 value_set_si(*res, 0);
01193 for (value_assign(k,LB);value_le(k,UB);value_increment(k,k)) {
01194
01195 value_assign(context[pos],k);
01196 count_points(pos+1,P->next,context,&c);
01197 if(value_notmone_p(c))
01198 value_addto(*res, *res, c);
01199 else {
01200 value_set_si(*res, -1);
01201 break;
01202 }
01203 }
01204 value_clear(c);
01205
01206 #ifdef EDEBUG11
01207 fprintf(stderr,"%d\n",CNT);
01208 #endif
01209
01210
01211 value_set_si(context[pos],0);
01212 value_clear(LB); value_clear(UB); value_clear(k);
01213 return;
01214 }
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229 static enode *P_Enum(Polyhedron *L,Polyhedron *LQ,Value *context,int pos,
01230 int nb_param,int dim,Value *lcm, const char **param_name)
01231 {
01232 enode *res,*B,*C;
01233 int hdim,i,j,rank,flag;
01234 Value n,g,nLB,nUB,nlcm,noff,nexp,k1,nm,hdv,k,lcm_copy;
01235 Value tmp;
01236 Matrix *A;
01237
01238 #ifdef EDEBUG
01239 fprintf(stderr,"-------------------- begin P_Enum -------------------\n");
01240 fprintf(stderr,"Calling P_Enum with pos = %d\n",pos);
01241 #endif
01242
01243
01244 value_init(n); value_init(g); value_init(nLB);
01245 value_init(nUB); value_init(nlcm); value_init(noff);
01246 value_init(nexp); value_init(k1); value_init(nm);
01247 value_init(hdv); value_init(k); value_init(tmp);
01248 value_init(lcm_copy);
01249
01250 if( value_zero_p(lcm[pos-1]) )
01251 {
01252 hdim = 1;
01253 value_set_si( lcm_copy, 1 );
01254 }
01255 else
01256 {
01257
01258 hdim = dim-nb_param+1;
01259 value_assign( lcm_copy, lcm[pos-1] );
01260 }
01261
01262
01263
01264 flag = lower_upper_bounds(pos,LQ,&context[dim-nb_param],&nLB,&nUB);
01265 if (flag & LB_INFINITY) {
01266 if (!(flag & UB_INFINITY)) {
01267
01268
01269
01270 value_sub_int(nLB,nUB,1);
01271 value_set_si(hdv,hdim);
01272 value_multiply(tmp,hdv,lcm_copy);
01273 value_subtract(nLB,nLB,tmp);
01274 if(value_pos_p(nLB))
01275 value_set_si(nLB,0);
01276 }
01277 else {
01278 value_set_si(nLB,0);
01279
01280
01281 value_set_si(hdv,hdim);
01282 value_multiply(nUB,hdv,lcm_copy);
01283 value_add_int(nUB,nUB,1);
01284 }
01285 }
01286
01287
01288
01289
01290
01291
01292
01293 #ifdef REDUCE_DEGREE
01294 if (pos==1 && (flag & UB_INFINITY)==0) {
01295
01296
01297
01298
01299 #ifdef EDEBUG
01300 fprintf(stderr,"*************** n **********\n");
01301 value_print(stderr,VALUE_FMT,n);
01302 fprintf(stderr,"\n");
01303 #endif
01304
01305 value_subtract(n,nUB,nLB);
01306 value_increment(n,n);
01307
01308 #ifdef EDEBUG
01309 value_print(stderr,VALUE_FMT,n);
01310 fprintf(stderr,"\n*************** n ************\n");
01311 #endif
01312
01313
01314 if(value_neg_p(n))
01315 i=0;
01316 else {
01317 value_modulus(tmp,n,lcm_copy);
01318 if(value_notzero_p(tmp)) {
01319 value_division(tmp,n,lcm_copy);
01320 value_increment(tmp,tmp);
01321 i = VALUE_TO_INT(tmp);
01322 }
01323 else {
01324 value_division(tmp,n,lcm_copy);
01325 i = VALUE_TO_INT(tmp);
01326 }
01327 }
01328
01329 #ifdef EDEBUG
01330 value_print(stderr,VALUE_FMT,n);
01331 fprintf(stderr,"\n*************** n ************\n");
01332 #endif
01333
01334
01335 if (i < hdim){
01336 hdim=i;
01337
01338 #ifdef EDEBUG4
01339 fprintf(stdout,"Parameter #%d: LB=",pos);
01340 value_print(stdout,VALUE_FMT,nLB);
01341 fprintf(stdout," UB=");
01342 value_print(stdout,VALUE_FMT,nUB);
01343 fprintf(stdout," lcm=");
01344 value_print(stdout,VALUE_FMT,lcm_copy);
01345 fprintf(stdout," degree reduced to %d\n",hdim-1);
01346 #endif
01347
01348 }
01349 }
01350 #endif
01351
01352
01353
01354 res = new_enode(polynomial,hdim,pos);
01355 for (i=0;i<hdim;i++) {
01356 int l;
01357 l = VALUE_TO_INT(lcm_copy);
01358 res->arr[i].x.p = new_enode(periodic,l,pos);
01359 }
01360
01361
01362 A = Matrix_Alloc(hdim, 2*hdim+1);
01363 B = new_enode(evector, hdim, 0);
01364 C = new_enode(evector, hdim, 0);
01365
01366
01367 for (j = 0; j < hdim; ++j)
01368 free_evalue_refs(&C->arr[j]);
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379 if(value_neg_p(nLB)) {
01380 value_modulus(nlcm,nLB,lcm_copy);
01381 value_addto(nlcm,nlcm,lcm_copy);
01382 }
01383 else {
01384 value_modulus(nlcm,nLB,lcm_copy);
01385 }
01386
01387
01388 value_subtract(noff,nLB,nlcm);
01389 value_addto(tmp,lcm_copy,nlcm);
01390 for (value_assign(k,nlcm);value_lt(k,tmp);) {
01391
01392 #ifdef EDEBUG
01393 fprintf(stderr,"Finding ");
01394 value_print(stderr,VALUE_FMT,k);
01395 fprintf(stderr,"-th elements of periodic coefficients\n");
01396 #endif
01397
01398 value_set_si(hdv,hdim);
01399 value_multiply(nm,hdv,lcm_copy);
01400 value_addto(nm,nm,nLB);
01401 i=0;
01402 for (value_addto(n,k,noff); value_lt(n,nm);
01403 value_addto(n,n,lcm_copy),i++) {
01404
01405
01406
01407
01408
01409 #ifdef ALL_OVERFLOW_WARNINGS
01410 if (((flag & UB_INFINITY)==0) && value_gt(n,nUB)) {
01411 fprintf(stdout,"Domain Overflow: Parameter #%d:",pos);
01412 fprintf(stdout,"nLB=");
01413 value_print(stdout,VALUE_FMT,nLB);
01414 fprintf(stdout," n=");
01415 value_print(stdout,VALUE_FMT,n);
01416 fprintf(stdout," nUB=");
01417 value_print(stdout,VALUE_FMT,nUB);
01418 fprintf(stdout,"\n");
01419 }
01420 #else
01421 if (overflow_warning_flag && ((flag & UB_INFINITY)==0) &&
01422 value_gt(n,nUB)) {
01423 fprintf(stdout,"\nWARNING: Parameter Domain Overflow.");
01424 fprintf(stdout," Result may be incorrect on this domain.\n");
01425 overflow_warning_flag = 0;
01426 }
01427 #endif
01428
01429
01430 value_assign(context[dim-nb_param+pos],n);
01431
01432 #ifdef EDEBUG1
01433 if( param_name )
01434 {
01435 fprintf(stderr,"%s = ",param_name[pos-1]);
01436 value_print(stderr,VALUE_FMT,n);
01437 fprintf(stderr," (hdim=%d, lcm[%d]=",hdim,pos-1);
01438 value_print(stderr,VALUE_FMT,lcm_copy);
01439 fprintf(stderr,")\n");
01440 }
01441 else
01442 {
01443 fprintf(stderr,"P%d = ",pos);
01444 value_print(stderr,VALUE_FMT,n);
01445 fprintf(stderr," (hdim=%d, lcm[%d]=",hdim,pos-1);
01446 value_print(stderr,VALUE_FMT,lcm_copy);
01447 fprintf(stderr,")\n");
01448 }
01449 #endif
01450
01451
01452 if (pos==nb_param) {
01453
01454 #ifdef EDEBUG
01455 fprintf(stderr,"Yes\n");
01456 #endif
01457
01458
01459
01460 value_set_si(B->arr[i].d,1);
01461 value_init(B->arr[i].x.n);
01462 count_points(1,L,context,&B->arr[i].x.n);
01463
01464 #ifdef EDEBUG3
01465 for (j=1; j<pos; j++) fputs(" ",stdout);
01466 fprintf(stdout, "E(");
01467 for (j=1; j<nb_param; j++) {
01468 value_print(stdout,VALUE_FMT,context[dim-nb_param+j]);
01469 fprintf(stdout,",");
01470 }
01471 value_print(stdout,VALUE_FMT,n);
01472 fprintf(stdout,") = ");
01473 value_print(stdout,VALUE_FMT,B->arr[i].x.n);
01474 fprintf(stdout," =");
01475 #endif
01476
01477 }
01478 else {
01479
01480 value_set_si(B->arr[i].d,0);
01481 B->arr[i].x.p = P_Enum(L,LQ->next,context,pos+1,
01482 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 value_gcd(g, A->p[i][i+1], A->p[i][j+1+hdim]);
01568 value_init(C->arr[j].d);
01569 value_divexact(C->arr[j].d, A->p[i][i+1], g);
01570 value_init(C->arr[j].x.n);
01571 value_divexact(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)]),
01590 param_name);
01591 fprintf(stderr,"\n");
01592 }
01593 #endif
01594
01595 for (j = 0; j < rank; ++j)
01596 free_evalue_refs(&C->arr[j]);
01597 }
01598 value_addto(tmp,lcm_copy,nlcm);
01599
01600 value_increment(k,k);
01601 for (i = 0; i < hdim; ++i) {
01602 free_evalue_refs(&B->arr[i]);
01603 if (value_lt(k,tmp))
01604 value_init(B->arr[i].d);
01605 }
01606 }
01607
01608 #ifdef EDEBUG
01609 if( param_name )
01610 {
01611 fprintf(stderr,"res (enode) =\n");
01612 print_enode(stderr,res,param_name);
01613 }
01614 fprintf(stderr, "-------------------- end P_Enum -----------------------\n");
01615 #endif
01616
01617
01618 value_set_si(context[dim-nb_param+pos],0);
01619
01620
01621 Matrix_Free(A);
01622 free(B);
01623 free(C);
01624
01625
01626 value_clear(n); value_clear(g); value_clear(nLB);
01627 value_clear(nUB); value_clear(nlcm); value_clear(noff);
01628 value_clear(nexp); value_clear(k1); value_clear(nm);
01629 value_clear(hdv); value_clear(k); value_clear(tmp);
01630 value_clear(lcm_copy);
01631 return res;
01632 }
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643 static void Scan_Vertices(Param_Polyhedron *PP,Param_Domain *Q,Matrix *CT,
01644 Value *lcm, int nbp, const char **param_name)
01645 {
01646 Param_Vertices *V;
01647 int i, j, ix, l, np;
01648 unsigned bx;
01649 Value k,m1;
01650
01651
01652
01653
01654
01655 value_init(k); value_init(m1);
01656 for( np=0 ; np<nbp ; np++ )
01657 value_set_si( lcm[np], 0 );
01658
01659 if( param_name )
01660 fprintf(stdout,"Vertices:\n");
01661
01662 for(i=0,ix=0,bx=MSB,V=PP->V; V && i<PP->nbV; i++,V=V->next) {
01663 if (Q->F[ix] & bx) {
01664 if( param_name )
01665 {
01666 if(CT) {
01667 Matrix *v;
01668 v = VertexCT(V->Vertex,CT);
01669 Print_Vertex(stdout,v,param_name);
01670 Matrix_Free(v);
01671 }
01672 else
01673 Print_Vertex(stdout,V->Vertex,param_name);
01674 fprintf(stdout,"\n");
01675 }
01676
01677 for(j=0;j<V->Vertex->NbRows;j++) {
01678
01679 for( l=0 ; l<V->Vertex->NbColumns-1 ; l++ )
01680 {
01681 if( value_notzero_p(V->Vertex->p[j][l]) )
01682 {
01683 value_gcd(m1, V->Vertex->p[j][V->Vertex->NbColumns-1],
01684 V->Vertex->p[j][l]);
01685 value_divexact(k, V->Vertex->p[j][V->Vertex->NbColumns-1], m1);
01686 if( value_notzero_p(lcm[l]) )
01687 {
01688
01689 if (value_notzero_p(k) && value_notone_p(k))
01690 {
01691 value_gcd(m1, lcm[l], k);
01692 value_divexact(k, k, m1);
01693 value_multiply(lcm[l],lcm[l],k);
01694 }
01695 }
01696 else
01697 {
01698 value_assign(lcm[l],k);
01699 }
01700 }
01701 }
01702 }
01703 }
01704 NEXT(ix,bx);
01705 }
01706 value_clear(k); value_clear(m1);
01707 }
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721 Enumeration *Enumerate_NoParameters(Polyhedron *P,Polyhedron *C,
01722 Matrix *CT,Polyhedron *CEq,
01723 unsigned MAXRAYS, const char **param_name)
01724 {
01725 Polyhedron *L;
01726 Enumeration *res;
01727 Value *context;
01728 int j;
01729 int hdim = P->Dimension + 1;
01730 int r,i;
01731
01732
01733 context = (Value *) malloc((hdim+1)*sizeof(Value));
01734 for (j=0;j<= hdim;j++)
01735 value_init(context[j]);
01736
01737 res = (Enumeration *)malloc(sizeof(Enumeration));
01738 res->next = NULL;
01739 res->ValidityDomain = Universe_Polyhedron(0);
01740 value_init(res->EP.d);
01741 value_set_si(res->EP.d,0);
01742 L = Polyhedron_Scan(P,res->ValidityDomain,MAXRAYS);
01743
01744 #ifdef EDEBUG2
01745 fprintf(stderr, "L = \n");
01746 Polyhedron_Print(stderr, P_VALUE_FMT, L);
01747 #endif
01748
01749 if(CT) {
01750 Polyhedron *Dt;
01751
01752
01753 Dt = Polyhedron_Preimage(res->ValidityDomain,CT,MAXRAYS);
01754 Polyhedron_Free(res->ValidityDomain);
01755 res->ValidityDomain = DomainIntersection(Dt,CEq,MAXRAYS);
01756 Polyhedron_Free(Dt);
01757 }
01758
01759 if( param_name )
01760 {
01761 fprintf(stdout,"---------------------------------------\n");
01762 fprintf(stdout,"Domain:\n");
01763 Print_Domain(stdout,res->ValidityDomain, param_name);
01764
01765
01766 printf("Vertices:\n");
01767 for(r=0;r<P->NbRays;++r) {
01768 if(value_zero_p(P->Ray[r][0]))
01769 printf("(line) ");
01770 printf("[");
01771 if (P->Dimension > 0)
01772 value_print(stdout,P_VALUE_FMT,P->Ray[r][1]);
01773 for(i=1;i<P->Dimension;i++) {
01774 printf(", ");
01775 value_print(stdout,P_VALUE_FMT,P->Ray[r][i+1]);
01776 }
01777 printf("]");
01778 if(value_notone_p(P->Ray[r][P->Dimension+1])) {
01779 printf("/");
01780 value_print(stdout,P_VALUE_FMT, P->Ray[r][P->Dimension+1]);
01781 }
01782 printf("\n");
01783 }
01784 }
01785
01786 res->EP.x.p = new_enode(polynomial,1,0);;
01787 value_set_si(res->EP.x.p->arr[0].d, 1);
01788 value_init(res->EP.x.p->arr[0].x.n);
01789
01790 if (emptyQ(P)) {
01791 value_set_si(res->EP.x.p->arr[0].x.n, 0);
01792 } else if (!L) {
01793
01794 value_set_si(res->EP.x.p->arr[0].x.n, 1);
01795 } else {
01796 CATCH(overflow_error) {
01797 fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
01798 fprintf(stderr,"You should rebuild PolyLib using GNU-MP"
01799 " or increasing the size of integers.\n");
01800 overflow_warning_flag = 0;
01801 assert(overflow_warning_flag);
01802 }
01803 TRY {
01804
01805 Vector_Set(context,0,(hdim+1));
01806
01807
01808 value_set_si(context[hdim],1);
01809 count_points(1, L, context, &res->EP.x.p->arr[0].x.n);
01810 UNCATCH(overflow_error);
01811 }
01812 }
01813
01814 Domain_Free(L);
01815
01816
01817
01818
01819
01820
01821 if( param_name )
01822 {
01823 fprintf(stdout,"\nEhrhart Polynomial:\n");
01824 print_evalue(stdout,&res->EP,param_name);
01825 fprintf(stdout, "\n");
01826 }
01827
01828 for (j=0;j<= hdim;j++)
01829 value_clear(context[j]);
01830 free(context);
01831 return(res);
01832 }
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843 Enumeration *Polyhedron_Enumerate(Polyhedron *Pi,Polyhedron *C,
01844 unsigned MAXRAYS, const char **param_name)
01845 {
01846 Polyhedron *L, *CQ, *CQ2, *LQ, *U, *CEq, *rVD, *P, *Ph = NULL;
01847 Matrix *CT;
01848 Param_Polyhedron *PP;
01849 Param_Domain *Q;
01850 int i,hdim, dim, nb_param, np;
01851 Value *lcm, *m1, hdv;
01852 Value *context;
01853 Enumeration *en, *res;
01854
01855 if (POL_ISSET(MAXRAYS, POL_NO_DUAL))
01856 MAXRAYS = 0;
01857
01858 POL_ENSURE_FACETS(Pi);
01859 POL_ENSURE_VERTICES(Pi);
01860 POL_ENSURE_FACETS(C);
01861 POL_ENSURE_VERTICES(C);
01862
01863 res = NULL;
01864 P = Pi;
01865
01866 #ifdef EDEBUG2
01867 fprintf(stderr,"C = \n");
01868 Polyhedron_Print(stderr,P_VALUE_FMT,C);
01869 fprintf(stderr,"P = \n");
01870 Polyhedron_Print(stderr,P_VALUE_FMT,P);
01871 #endif
01872
01873 hdim = P->Dimension + 1;
01874 dim = P->Dimension;
01875 nb_param = C->Dimension;
01876
01877
01878 if(nb_param == 0) {
01879
01880 return(Enumerate_NoParameters(P,C,NULL,NULL,MAXRAYS,param_name));
01881 }
01882 if(nb_param == dim) {
01883 res = (Enumeration *)malloc(sizeof(Enumeration));
01884 res->next = 0;
01885 res->ValidityDomain = DomainIntersection(P,C,MAXRAYS);
01886 value_init(res->EP.d);
01887 value_init(res->EP.x.n);
01888 value_set_si(res->EP.d,1);
01889 value_set_si(res->EP.x.n,1);
01890 if( param_name ) {
01891 fprintf(stdout,"---------------------------------------\n");
01892 fprintf(stdout,"Domain:\n");
01893 Print_Domain(stdout,res->ValidityDomain, param_name);
01894 fprintf(stdout,"\nEhrhart Polynomial:\n");
01895 print_evalue(stdout,&res->EP,param_name);
01896 fprintf(stdout, "\n");
01897 }
01898 return res;
01899 }
01900 PP = Polyhedron2Param_SimplifiedDomain(&P,C,MAXRAYS,&CEq,&CT);
01901 if(!PP) {
01902 if( param_name )
01903 fprintf(stdout, "\nEhrhart Polynomial:\nNULL\n");
01904
01905 return(NULL);
01906 }
01907
01908
01909 if(CT) {
01910 nb_param -= CT->NbColumns-CT->NbRows;
01911 dim -= CT->NbColumns-CT->NbRows;
01912 hdim -= CT->NbColumns-CT->NbRows;
01913
01914
01915 if(nb_param == 0) {
01916 res = Enumerate_NoParameters(P,C,CT,CEq,MAXRAYS,param_name);
01917 Param_Polyhedron_Free(PP);
01918 goto out;
01919 }
01920 }
01921
01922
01923 lcm = (Value *)malloc((nb_param+1) * sizeof(Value));
01924 m1 = (Value *)malloc((nb_param+1) * sizeof(Value));
01925
01926 for( np=0 ; np < nb_param+1; np++ )
01927 {
01928 value_init(lcm[np]); value_init(m1[np]);
01929 }
01930 value_init(hdv);
01931
01932 for(Q=PP->D;Q;Q=Q->next) {
01933 int hom = 0;
01934 if(CT) {
01935 Polyhedron *Dt;
01936 CQ = Q->Domain;
01937 Dt = Polyhedron_Preimage(Q->Domain,CT,MAXRAYS);
01938 rVD = DomainIntersection(Dt,CEq,MAXRAYS);
01939
01940
01941 if(!rVD || emptyQ(rVD) ||
01942 (rVD->Dimension-rVD->NbEq < Dt->Dimension-Dt->NbEq-CEq->NbEq)) {
01943 if(rVD)
01944 Polyhedron_Free(rVD);
01945 Polyhedron_Free(Dt);
01946 Polyhedron_Free(CQ);
01947 continue;
01948 }
01949 Polyhedron_Free(Dt);
01950 }
01951 else
01952 rVD = CQ = Q->Domain;
01953 en = (Enumeration *)malloc(sizeof(Enumeration));
01954 en->next = res;
01955 res = en;
01956 res->ValidityDomain = rVD;
01957
01958 if( param_name ) {
01959 fprintf(stdout,"---------------------------------------\n");
01960 fprintf(stdout,"Domain:\n");
01961
01962 #ifdef EPRINT_ALL_VALIDITY_CONSTRAINTS
01963 Print_Domain(stdout,res->ValidityDomain,param_name);
01964 #else
01965 {
01966 Polyhedron *VD;
01967 VD = DomainSimplify(res->ValidityDomain,C,MAXRAYS);
01968 Print_Domain(stdout,VD,param_name);
01969 Domain_Free(VD);
01970 }
01971 #endif
01972 }
01973
01974 overflow_warning_flag = 1;
01975
01976
01977 Scan_Vertices(PP,Q,CT,lcm,nb_param,param_name);
01978
01979 #ifdef EDEBUG2
01980 fprintf(stderr,"Denominator = ");
01981 for( np=0;np<nb_param;np++)
01982 value_print(stderr,P_VALUE_FMT,lcm[np]);
01983 fprintf(stderr," and hdim == %d \n",hdim);
01984 #endif
01985
01986 #ifdef EDEBUG2
01987 fprintf(stderr,"CQ = \n");
01988 Polyhedron_Print(stderr,P_VALUE_FMT,CQ);
01989 #endif
01990
01991
01992
01993 value_set_si(hdv,hdim-nb_param);
01994
01995 for( np=0;np<nb_param+1;np++) {
01996 if( value_notzero_p(lcm[np]) )
01997 value_multiply(m1[np],hdv,lcm[np]);
01998 else
01999 value_set_si(m1[np],1);
02000 }
02001
02002 #ifdef EDEBUG2
02003 fprintf(stderr,"m1 == ");
02004 for( np=0;np<nb_param;np++)
02005 value_print(stderr,P_VALUE_FMT,m1[np]);
02006 fprintf(stderr,"\n");
02007 #endif
02008
02009 CATCH(overflow_error) {
02010 fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
02011 CQ2 = NULL;
02012 }
02013 TRY {
02014 CQ2 = Polyhedron_Preprocess(CQ,m1,MAXRAYS);
02015
02016 #ifdef EDEBUG2
02017 fprintf(stderr,"After preprocess, CQ2 = ");
02018 Polyhedron_Print(stderr,P_VALUE_FMT,CQ2);
02019 #endif
02020
02021 UNCATCH(overflow_error);
02022 }
02023
02024
02025
02026 if ((!CQ2 || emptyQ(CQ2)) && CQ->NbBid==0) {
02027 int r;
02028
02029 #ifdef EDEBUG2
02030 fprintf(stderr,"Trying to call Polyhedron_Preprocess2 : CQ = \n");
02031 Polyhedron_Print(stderr,P_VALUE_FMT,CQ);
02032 #endif
02033
02034
02035 for(r=0;r<CQ->NbRays;r++) {
02036 if(value_zero_p(CQ->Ray[r][0]) ||
02037 value_zero_p(CQ->Ray[r][CQ->Dimension+1]))
02038 break;
02039 }
02040 if(r==CQ->NbRays) {
02041
02042
02043
02044 CQ2 = Polyhedron_Preprocess2(CQ,m1,lcm,MAXRAYS);
02045 }
02046 }
02047
02048 if (!CQ2) {
02049 Polyhedron *tmp;
02050 #ifdef EDEBUG2
02051 fprintf(stderr,"Homogenize.\n");
02052 #endif
02053 hom = 1;
02054 tmp = homogenize(CQ, MAXRAYS);
02055 CQ2 = Polyhedron_Preprocess(tmp,m1,MAXRAYS);
02056 Polyhedron_Free(tmp);
02057 if (!Ph)
02058 Ph = homogenize(P, MAXRAYS);
02059 for (np=0; np < nb_param+1; np++)
02060 if (value_notzero_p(lcm[np]))
02061 value_addto(m1[np],m1[np],lcm[np]);
02062 }
02063
02064 if (!CQ2 || emptyQ(CQ2)) {
02065 #ifdef EDEBUG2
02066 fprintf(stderr,"Degenerate.\n");
02067 #endif
02068 fprintf(stdout,"Degenerate Domain. Can not continue.\n");
02069 value_init(res->EP.d);
02070 value_init(res->EP.x.n);
02071 value_set_si(res->EP.d,1);
02072 value_set_si(res->EP.x.n,-1);
02073 }
02074 else {
02075
02076 #ifdef EDEBUG2
02077 fprintf(stderr,"CQ2 = \n");
02078 Polyhedron_Print(stderr,P_VALUE_FMT,CQ2);
02079 if( ! PolyhedronIncludes(CQ, CQ2) )
02080 fprintf( stderr,"CQ does not include CQ2 !\n");
02081 else
02082 fprintf( stderr,"CQ includes CQ2.\n");
02083 if( ! PolyhedronIncludes(res->ValidityDomain, CQ2) )
02084 fprintf( stderr,"CQ2 is *not* included in validity domain !\n");
02085 else
02086 fprintf( stderr,"CQ2 is included in validity domain.\n");
02087 #endif
02088
02089
02090 L = Polyhedron_Scan(hom ? Ph : P,CQ2,MAXRAYS);
02091 U = Universe_Polyhedron(0);
02092
02093
02094 LQ = Polyhedron_Scan(CQ2,U,MAXRAYS);
02095 Domain_Free(U);
02096 if(CT)
02097 Domain_Free(CQ);
02098
02099
02100 Domain_Free(CQ2);
02101
02102 #ifdef EDEBUG2
02103 fprintf(stderr,"L = \n");
02104 Polyhedron_Print(stderr,P_VALUE_FMT,L);
02105 fprintf(stderr,"LQ = \n");
02106 Polyhedron_Print(stderr,P_VALUE_FMT,LQ);
02107 #endif
02108 #ifdef EDEBUG3
02109 fprintf(stdout,"\nSystem of Equations:\n");
02110 #endif
02111
02112 value_init(res->EP.d);
02113 value_set_si(res->EP.d,0);
02114
02115
02116 context = (Value *) malloc ((hdim+1+hom)*sizeof(Value));
02117 for(i=0;i<=(hdim+hom);i++)
02118 value_init(context[i]);
02119 Vector_Set(context,0,(hdim+1+hom));
02120
02121
02122 value_set_si(context[hdim+hom],1);
02123
02124 CATCH(overflow_error) {
02125 fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
02126 fprintf(stderr,"You should rebuild PolyLib using GNU-MP "
02127 "or increasing the size of integers.\n");
02128 overflow_warning_flag = 0;
02129 assert(overflow_warning_flag);
02130
02131 }
02132 TRY {
02133 res->EP.x.p = P_Enum(L,LQ,context,1,nb_param+hom,
02134 dim+hom,lcm,param_name);
02135 UNCATCH(overflow_error);
02136 }
02137 if (hom)
02138 dehomogenize_evalue(&res->EP, nb_param+1);
02139
02140 for(i=0;i<=(hdim+hom);i++)
02141 value_clear(context[i]);
02142 free(context);
02143 Domain_Free(L);
02144 Domain_Free(LQ);
02145
02146 #ifdef EDEBUG5
02147 if( param_name )
02148 {
02149 fprintf(stdout,"\nEhrhart Polynomial (before simplification):\n");
02150 print_evalue(stdout,&res->EP,param_name);
02151 }
02152 #endif
02153
02154
02155 reduce_evalue(&res->EP);
02156
02157
02158
02159 if(CT)
02160 addeliminatedparams_evalue(&res->EP,CT);
02161
02162 if (param_name) {
02163 fprintf(stdout,"\nEhrhart Polynomial:\n");
02164 print_evalue(stdout,&res->EP, param_name);
02165 fprintf(stdout,"\n");
02166
02167 }
02168
02169 }
02170 }
02171
02172 if (Ph)
02173 Polyhedron_Free(Ph);
02174
02175 for (np=0; np < nb_param+1; np++)
02176 {
02177 value_clear(lcm[np]); value_clear(m1[np]);
02178 }
02179 value_clear(hdv);
02180 free(lcm);
02181 free(m1);
02182
02183 Param_Vertices_Free(PP->V);
02184 while (PP->D) {
02185 Q = PP->D;
02186 PP->D = PP->D->next;
02187 free(Q->F);
02188 free(Q);
02189 }
02190 free(PP);
02191
02192 out:
02193 if (CEq)
02194 Polyhedron_Free(CEq);
02195 if (CT)
02196 Matrix_Free(CT);
02197 if( P != Pi )
02198 Polyhedron_Free( P );
02199
02200 return res;
02201 }
02202
02203 void Enumeration_Free(Enumeration *en)
02204 {
02205 Enumeration *ee;
02206
02207 while( en )
02208 {
02209 free_evalue_refs( &(en->EP) );
02210 Domain_Free( en->ValidityDomain );
02211 ee = en ->next;
02212 free( en );
02213 en = ee;
02214 }
02215 }
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227 void evalue_div(evalue * e, Value n) {
02228 int i;
02229 Value gc;
02230 value_init(gc);
02231 if (value_zero_p(e->d)) {
02232 for (i=0; i< e->x.p->size; i++) {
02233 evalue_div(&(e->x.p->arr[i]), n);
02234 }
02235 }
02236 else {
02237 value_multiply(e->d, e->d, n);
02238
02239 value_gcd(gc, e->x.n, e->d);
02240 if (value_notone_p(gc)) {
02241 value_divexact(e->d, e->d, gc);
02242 value_divexact(e->x.n, e->x.n, gc);
02243 }
02244 }
02245 value_clear(gc);
02246 }
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264 Enumeration *Ehrhart_Quick_Apx_Full_Dim(Polyhedron *Pi,Polyhedron *C,
02265 unsigned MAXRAYS, const char **param_name)
02266 {
02267 Polyhedron *L, *CQ, *CQ2, *LQ, *U, *CEq, *rVD, *P;
02268 Matrix *CT;
02269 Param_Polyhedron *PP;
02270 Param_Domain *Q;
02271 int i,j,hdim, dim, nb_param, np;
02272 Value *lcm, *m1, hdv;
02273 Value *context;
02274 Enumeration *en, *res;
02275 Value expansion_det;
02276 Polyhedron * Expanded;
02277
02278
02279 Param_Vertices * V_tmp;
02280
02281 res = NULL;
02282 P = Pi;
02283
02284 value_init(expansion_det);
02285
02286 #ifdef EDEBUG2
02287 fprintf(stderr,"C = \n");
02288 Polyhedron_Print(stderr,P_VALUE_FMT,C);
02289 fprintf(stderr,"P = \n");
02290 Polyhedron_Print(stderr,P_VALUE_FMT,P);
02291 #endif
02292
02293 hdim = P->Dimension + 1;
02294 dim = P->Dimension;
02295 nb_param = C->Dimension;
02296
02297
02298 if(nb_param == 0) {
02299
02300 return(Enumerate_NoParameters(P,C,NULL,NULL,MAXRAYS, param_name));
02301 }
02302
02303 #if EDEBUG2
02304 printf("Enumerating polyhedron : \n");
02305 Polyhedron_Print(stdout, P_VALUE_FMT, P);
02306 #endif
02307
02308 PP = Polyhedron2Param_SimplifiedDomain(&P,C,MAXRAYS,&CEq,&CT);
02309 if(!PP) {
02310 if( param_name )
02311 fprintf(stdout, "\nEhrhart Polynomial:\nNULL\n");
02312
02313 return(NULL);
02314 }
02315
02316
02317 if(CT) {
02318 nb_param -= CT->NbColumns-CT->NbRows;
02319 dim -= CT->NbColumns-CT->NbRows;
02320 hdim -= CT->NbColumns-CT->NbRows;
02321
02322
02323 if(nb_param == 0)
02324 {
02325 res = Enumerate_NoParameters(P,C,CT,CEq,MAXRAYS,param_name);
02326 if( P != Pi )
02327 Polyhedron_Free( P );
02328 return( res );
02329 }
02330 }
02331
02332 if (!PP->nbV)
02333
02334 return NULL;
02335
02336
02337 lcm = (Value *)malloc( nb_param * sizeof(Value));
02338 m1 = (Value *)malloc( nb_param * sizeof(Value));
02339
02340 for( np=0 ; np<nb_param ; np++ )
02341 {
02342 value_init(lcm[np]); value_init(m1[np]);
02343 }
02344 value_init(hdv);
02345
02346 #if EDEBUG2
02347 Polyhedron_Print(stderr, P_VALUE_FMT, P);
02348 #endif
02349
02350 Expanded = P;
02351 Param_Polyhedron_Scale_Integer(PP, &Expanded, &expansion_det, MAXRAYS);
02352
02353 #if EDEBUG2
02354 Polyhedron_Print(stderr, P_VALUE_FMT, Expanded);
02355 #endif
02356
02357 if (P != Expanded)
02358 Polyhedron_Free(P);
02359 P = Expanded;
02360
02361
02362
02363
02364
02365
02366
02367 for (i=0; i< nb_param; i++) value_set_si(lcm[i], 1);
02368
02369 for(Q=PP->D;Q;Q=Q->next) {
02370 if(CT) {
02371 Polyhedron *Dt;
02372 CQ = Q->Domain;
02373 Dt = Polyhedron_Preimage(Q->Domain,CT,MAXRAYS);
02374 rVD = DomainIntersection(Dt,CEq,MAXRAYS);
02375
02376
02377 if(!rVD || emptyQ(rVD) ||
02378 (rVD->Dimension-rVD->NbEq < Dt->Dimension-Dt->NbEq-CEq->NbEq)) {
02379 if(rVD)
02380 Polyhedron_Free(rVD);
02381 Polyhedron_Free(Dt);
02382 continue;
02383 }
02384 Polyhedron_Free(Dt);
02385 }
02386 else
02387 rVD = CQ = Q->Domain;
02388 en = (Enumeration *)malloc(sizeof(Enumeration));
02389 en->next = res;
02390 res = en;
02391 res->ValidityDomain = rVD;
02392
02393 if( param_name )
02394 {
02395 fprintf(stdout,"---------------------------------------\n");
02396 fprintf(stdout,"Domain:\n");
02397
02398 #ifdef EPRINT_ALL_VALIDITY_CONSTRAINTS
02399 Print_Domain(stdout,res->ValidityDomain,param_name);
02400 #else
02401 {
02402 Polyhedron *VD;
02403 VD = DomainSimplify(res->ValidityDomain,C,MAXRAYS);
02404 Print_Domain(stdout,VD,param_name);
02405 Domain_Free(VD);
02406 }
02407 #endif
02408 }
02409
02410 overflow_warning_flag = 1;
02411
02412 #ifdef EDEBUG2
02413 fprintf(stderr,"Denominator = ");
02414 for( np=0;np<nb_param;np++)
02415 value_print(stderr,P_VALUE_FMT,lcm[np]);
02416 fprintf(stderr," and hdim == %d \n",hdim);
02417 #endif
02418
02419 #ifdef EDEBUG2
02420 fprintf(stderr,"CQ = \n");
02421 Polyhedron_Print(stderr,P_VALUE_FMT,CQ);
02422 #endif
02423
02424
02425
02426 value_set_si(hdv,hdim-nb_param);
02427
02428 for( np=0;np<nb_param;np++)
02429 {
02430 if( value_notzero_p(lcm[np]) )
02431 value_multiply(m1[np],hdv,lcm[np]);
02432 else
02433 value_set_si(m1[np],1);
02434 }
02435
02436 #ifdef EDEBUG2
02437 fprintf(stderr,"m1 == ");
02438 for( np=0;np<nb_param;np++)
02439 value_print(stderr,P_VALUE_FMT,m1[np]);
02440 fprintf(stderr,"\n");
02441 #endif
02442
02443 CATCH(overflow_error) {
02444 fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
02445 CQ2 = NULL;
02446 }
02447 TRY {
02448 CQ2 = Polyhedron_Preprocess(CQ,m1,MAXRAYS);
02449
02450 #ifdef EDEBUG2
02451 fprintf(stderr,"After preprocess, CQ2 = ");
02452 Polyhedron_Print(stderr,P_VALUE_FMT,CQ2);
02453 #endif
02454
02455 UNCATCH(overflow_error);
02456 }
02457
02458
02459
02460 if ((!CQ2 || emptyQ(CQ2)) && CQ->NbBid==0) {
02461 int r;
02462
02463 #ifdef EDEBUG2
02464 fprintf(stderr,"Trying to call Polyhedron_Preprocess2 : CQ = \n");
02465 Polyhedron_Print(stderr,P_VALUE_FMT,CQ);
02466 #endif
02467
02468
02469 for(r=0;r<CQ->NbRays;r++) {
02470 if(value_zero_p(CQ->Ray[r][0]) ||
02471 value_zero_p(CQ->Ray[r][CQ->Dimension+1]))
02472 break;
02473 }
02474 if(r==CQ->NbRays) {
02475
02476
02477
02478 CQ2 = Polyhedron_Preprocess2(CQ,m1,lcm,MAXRAYS);
02479 }
02480 }
02481 if (!CQ2 || emptyQ(CQ2)) {
02482 #ifdef EDEBUG2
02483 fprintf(stderr,"Degenerate.\n");
02484 #endif
02485 fprintf(stdout,"Degenerate Domain. Can not continue.\n");
02486 value_init(res->EP.d);
02487 value_init(res->EP.x.n);
02488 value_set_si(res->EP.d,1);
02489 value_set_si(res->EP.x.n,-1);
02490 }
02491 else {
02492
02493 #ifdef EDEBUG2
02494 fprintf(stderr,"CQ2 = \n");
02495 Polyhedron_Print(stderr,P_VALUE_FMT,CQ2);
02496 if( ! PolyhedronIncludes(CQ, CQ2) )
02497 fprintf( stderr,"CQ does not include CQ2 !\n");
02498 else
02499 fprintf( stderr,"CQ includes CQ2.\n");
02500 if( ! PolyhedronIncludes(res->ValidityDomain, CQ2) )
02501 fprintf( stderr,"CQ2 is *not* included in validity domain !\n");
02502 else
02503 fprintf( stderr,"CQ2 is included in validity domain.\n");
02504 #endif
02505
02506
02507 L = Polyhedron_Scan(P,CQ,MAXRAYS);
02508 U = Universe_Polyhedron(0);
02509
02510
02511 LQ = Polyhedron_Scan(CQ2,U,MAXRAYS);
02512 Domain_Free(U);
02513 if(CT)
02514 Domain_Free(CQ);
02515
02516
02517 Domain_Free(CQ2);
02518
02519 #ifdef EDEBUG2
02520 fprintf(stderr,"L = \n");
02521 Polyhedron_Print(stderr,P_VALUE_FMT,L);
02522 fprintf(stderr,"LQ = \n");
02523 Polyhedron_Print(stderr,P_VALUE_FMT,LQ);
02524 #endif
02525 #ifdef EDEBUG3
02526 fprintf(stdout,"\nSystem of Equations:\n");
02527 #endif
02528
02529 value_init(res->EP.d);
02530 value_set_si(res->EP.d,0);
02531
02532
02533 context = (Value *) malloc ((hdim+1)*sizeof(Value));
02534 for(i=0;i<=(hdim);i++)
02535 value_init(context[i]);
02536 Vector_Set(context,0,(hdim+1));
02537
02538
02539 value_set_si(context[hdim],1);
02540
02541 CATCH(overflow_error) {
02542 fprintf(stderr,"Enumerate: arithmetic overflow error.\n");
02543 fprintf(stderr,"You should rebuild PolyLib using GNU-MP "
02544 "or increasing the size of integers.\n");
02545 overflow_warning_flag = 0;
02546 assert(overflow_warning_flag);
02547
02548 }
02549 TRY {
02550 res->EP.x.p = P_Enum(L,LQ,context,1,nb_param,dim,lcm, param_name);
02551 UNCATCH(overflow_error);
02552 }
02553
02554 for(i=0;i<=(hdim);i++)
02555 value_clear(context[i]);
02556 free(context);
02557 Domain_Free(L);
02558 Domain_Free(LQ);
02559
02560 #ifdef EDEBUG5
02561 if( param_name )
02562 {
02563 fprintf(stdout,"\nEhrhart Polynomial (before simplification):\n");
02564 print_evalue(stdout,&res->EP,param_name);
02565 }
02566
02567
02568 fprintf(stdout,"\nEhrhart Polynomial (before division):\n");
02569 print_evalue(stdout,&(res->EP),param_name);
02570 #endif
02571
02572 evalue_div(&(res->EP), expansion_det);
02573
02574
02575
02576 reduce_evalue(&res->EP);
02577
02578
02579
02580 if(CT)
02581 addeliminatedparams_evalue(&res->EP,CT);
02582
02583 if( param_name )
02584 {
02585 fprintf(stdout,"\nEhrhart Polynomial:\n");
02586 print_evalue(stdout,&res->EP, param_name);
02587 fprintf(stdout,"\n");
02588
02589
02590 }
02591
02592 }
02593 }
02594 value_clear(expansion_det);
02595
02596 if( P != Pi )
02597 Polyhedron_Free( P );
02598
02599 for( np=0; np<nb_param ; np++ )
02600 {
02601 value_clear(lcm[np]); value_clear(m1[np]);
02602 }
02603 value_clear(hdv);
02604
02605 return res;
02606 }
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618 Enumeration *Ehrhart_Quick_Apx(Matrix * M, Matrix * C,
02619 Matrix **Validity_Lattice, unsigned maxRays) {
02620
02621
02622
02623
02624 Matrix * M_full;
02625 Polyhedron * P, * PC;
02626 Enumeration *en;
02627
02628 M_full = full_dimensionize(M, C->NbColumns-2, Validity_Lattice);
02629
02630
02631 mpolyhedron_compress_last_vars(C, *Validity_Lattice);
02632 show_matrix(M_full);
02633 P = Constraints2Polyhedron(M_full, maxRays);
02634 PC = Constraints2Polyhedron(C, maxRays);
02635 Matrix_Free(M_full);
02636
02637 en = Ehrhart_Quick_Apx_Full_Dim(P, PC, maxRays, NULL);
02638
02639
02640 Polyhedron_Free(P);
02641 Polyhedron_Free(PC);
02642 return en;
02643 }
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660 Enumeration *Constraints_EhrhartQuickApx(Matrix const * M, Matrix const * C,
02661 Matrix ** validityLattice,
02662 Matrix ** parmEqualities,
02663 unsigned int ** elimParms,
02664 unsigned maxRays) {
02665 Enumeration *EP;
02666 Matrix * Mp = Matrix_Copy(M);
02667 Matrix * Cp = Matrix_Copy(C);
02668
02669
02670 (*parmEqualities) = Constraints_Remove_parm_eqs(&Mp, &Cp, 0, elimParms);
02671 if (Mp->NbRows>=0) {
02672 EP = Ehrhart_Quick_Apx(Mp, Cp, validityLattice, maxRays);
02673 return EP;
02674 }
02675 else {
02676
02677 return NULL;
02678 }
02679
02680 }
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692 const char **parmsWithoutElim(char const **parmNames,
02693 unsigned int const *elimParms,
02694 unsigned int nbParms)
02695 {
02696 int i=0, j=0,k;
02697 int newParmNb = nbParms - elimParms[0];
02698 const char **newParmNames = (const char **)malloc(newParmNb * sizeof(char *));
02699 for (k=1; k<= elimParms[0]; k++) {
02700 while (i!=elimParms[k]) {
02701 newParmNames[i-k+1] = parmNames[i];
02702 i++;
02703 }
02704 }
02705 return newParmNames;
02706 }
02707
02708
02709
02710
02711
02712
02713
02714
02715 Enumeration * Enumeration_zero(unsigned int nbParms, unsigned int maxRays) {
02716 Matrix * Mz = Matrix_Alloc(1, nbParms+3);
02717 Polyhedron * emptyP;
02718 Polyhedron * universe;
02719 Enumeration * zero;
02720
02721
02722 value_set_si(Mz->p[0][1], 2);
02723 value_set_si(Mz->p[0][nbParms+2], 1);
02724 emptyP = Constraints2Polyhedron(Mz, maxRays);
02725 Matrix_Free(Mz);
02726 universe = Universe_Polyhedron(nbParms);
02727 zero = Polyhedron_Enumerate(emptyP, universe, maxRays, NULL);
02728 Polyhedron_Free(emptyP);
02729 Polyhedron_Free(universe);
02730 return zero;
02731 }
02732