00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdlib.h>
00019 #include <polylib/polylib.h>
00020 #define WS 200
00021
00022
00023
00024
00025 typedef struct _Polyhedron_union {
00026 Enumeration *pt;
00027 struct _Polyhedron_union *next;} Polyhedron_union;
00028
00029 static int ppcm1 (int a, int b);
00030 Matrix *CalcBase( Matrix *R);
00031
00032
00033
00034
00035 static void Soustraire_ligne(Matrix *R, int l1, int l2, int piv );
00036 static int existepivot( Matrix *R, int l );
00037 static void swap_line(Matrix *R, int l1, int l2);
00038
00039
00040
00041
00042
00043
00044
00045 Matrix *CalcBase( Matrix *R )
00046 {
00047 Matrix *B;
00048 int i, j;
00049 Value p;
00050 int l;
00051 int lnn;
00052 int dimbase;
00053 int u;
00054 Value som;
00055 int c;
00056
00057
00058 for( l=0 ; l<R->NbRows ; ++l )
00059 {
00060
00061 if( (lnn=existepivot(R,l)) != -1 )
00062 {
00063 swap_line( R, l, lnn );
00064
00065
00066 for( j=l+1 ; j<R->NbRows ; ++j )
00067 if(value_notzero_p( R->p[j][l]) )
00068 Soustraire_ligne( R, l, j, l );
00069
00070
00071 for( j=0 ; j<l ; ++j )
00072 if( value_notzero_p(R->p[j][l]) )
00073 Soustraire_ligne( R, l, j, l );
00074
00075 }
00076
00077
00078 }
00079
00080 dimbase = 0;
00081 for( l=0 ; l<R->NbRows ; ++l )
00082 if( value_zero_p(R->p[l][l]) )
00083 ++dimbase;
00084
00085 B = Matrix_Alloc( dimbase, R->NbRows );
00086
00087 l=0;
00088 for( u=0 ; u<dimbase ; ++u )
00089 {
00090 while(value_notzero_p( R->p[l][l]) )
00091 ++l;
00092
00093
00094 for( i=R->NbRows-1 ; i>l ; --i )
00095 value_set_si(B->p[u][i], 0);
00096 value_set_si(B->p[u][l], 1);
00097 for( i=l-1 ; i>=0 ; --i )
00098 {
00099 if(value_zero_p( R->p[i][i]) )
00100
00101
00102 value_set_si(B->p[u][i],0);
00103 else
00104 {
00105
00106 value_set_si(som,0);
00107 for( c=l ; c>i ; --c )
00108 {
00109 value_addmul(som, R->p[i][c], B->p[u][c]);
00110 value_multiply(B->p[u][c] ,B->p[u][c] , R->p[i][i]);
00111 }
00112 value_oppose(B->p[u][i] , som );
00113 }
00114 }
00115
00116 value_set_si(p,0);
00117 for( i=0 ; i<R->NbRows ; ++i )
00118 value_gcd(p, p, B->p[u][i]);
00119 if( value_zero_p(p))
00120 value_set_si(p,1);
00121 for( i=0 ; i<R->NbRows && value_zero_p(B->p[u][i]); ++i )
00122 ;
00123 if( i<R->NbRows )
00124 if( value_neg_p(B->p[u][i]) )
00125 value_oppose( p,p );
00126
00127 for( i=0 ; i<R->NbRows ; ++i )
00128 value_divexact(B->p[u][i], B->p[u][i], p);
00129
00130
00131 ++l;
00132 }
00133 return B;
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 static int existepivot( Matrix *R, int l )
00219 {
00220 int j, c;
00221
00222 for( j=l ; j<R->NbRows ; ++j )
00223 if(value_notzero_p( R->p[j][l]) )
00224 return( j );
00225
00226
00227
00228 for( j=0 ; j<l ; ++j )
00229 {
00230 for( c=0 ; c<l && value_zero_p(R->p[j][c]) ; c++ )
00231 ;
00232 if( c==l && value_notzero_p(R->p[j][l]) )
00233 return( j );
00234 }
00235
00236 return( -1 );
00237 }
00238
00239
00240
00241 static void swap_line(Matrix *R, int l1, int l2)
00242 {
00243 int i;
00244 Value tmp;
00245
00246 if( l1 != l2 )
00247 for(i = 0;i < R->NbColumns;i ++)
00248 {
00249 value_assign(tmp , R->p[l1][i]);
00250 value_assign(R->p[l1][i] , R->p[l2][i]);
00251 value_assign(R->p[l2][i] , tmp);
00252 }
00253 }
00254
00255
00256
00257 int pgcd1( int a, int b)
00258 {
00259 int r;
00260 if( a== 0 )
00261 return( abs(b) );
00262 if(b==0 )
00263 return(abs(a) );
00264 do
00265 {
00266 r= a % b;
00267 a= b;
00268 b = r;
00269 }
00270 while ( r!=0 );
00271 return(abs(a));
00272 }
00273
00274
00275
00276
00277
00278
00279 static void Soustraire_ligne(Matrix *R, int l1, int l2, int piv )
00280 {
00281 int i;
00282 Value a, b, p, t;
00283
00284
00285 if (value_zero_p(R->p[l2][piv] ))
00286 return;
00287
00288 value_init(a);
00289 value_init(b);
00290 value_init(p);
00291 value_init(t);
00292
00293 value_gcd(p, R->p[l1][piv], R->p[l2][piv]);
00294 value_divexact(a, R->p[l1][piv], p);
00295 value_divexact(b, R->p[l2][piv], p);
00296
00297 value_set_si(R->p[l2][piv] , 0);
00298 value_set_si(p,0);
00299 for(i = piv + 1;i < R->NbColumns;i ++)
00300 {
00301 value_multiply(t,b,R->p[l1][i]);
00302 value_multiply(R->p[l2][i],a,R->p[l2][i]);
00303 value_subtract(R->p[l2][i],R->p[l2][i],t);
00304 value_gcd(p, p, R->p[l2][i]);
00305 }
00306
00307 for( i=piv+1 ; i<R->NbColumns && p!=0 ; i++ )
00308 value_divexact(R->p[l2][i], R->p[l2][i], p);
00309
00310 value_clear(a);
00311 value_clear(b);
00312 value_clear(p);
00313 value_clear(t);
00314 }
00315
00316
00317
00318
00319
00320 void new_eadd(evalue *e1,evalue *res) {
00321 int i, p, x, y;
00322
00323 evalue *ne;
00324 Value g,m1,m2;
00325
00326 value_init(g);
00327 value_init(m1);
00328 value_init(m2);
00329 if (value_notzero_p(e1->d) && value_notzero_p(res->d)) {
00330
00331 value_multiply(m1,e1->x.n,res->d);
00332 value_multiply(m2,res->x.n,e1->d);
00333 value_addto(res->x.n,m1,m2);
00334 value_multiply(res->d,e1->d,res->d);
00335 value_gcd(g, res->x.n,res->d);
00336 if (value_notone_p(g)) {
00337 value_divexact(res->d, res->d, g);
00338 value_divexact(res->x.n, res->x.n, g);
00339 }
00340 value_clear(g); value_clear(m1); value_clear(m2);
00341 return ;
00342 }
00343 else if (value_notzero_p(e1->d) && value_zero_p(res->d)) {
00344 if (res->x.p->type==polynomial) {
00345
00346 new_eadd(e1, &res->x.p->arr[0]);
00347 value_clear(g); value_clear(m1); value_clear(m2);
00348 return ;
00349 }
00350 else if (res->x.p->type==periodic) {
00351
00352 for (i=0; i<res->x.p->size; i++) {
00353 new_eadd(e1, &res->x.p->arr[i]);
00354 }
00355 value_clear(g); value_clear(m1); value_clear(m2);
00356
00357 return ;
00358 }
00359 else {
00360 fprintf(stderr, "eadd: cannot add const with vector\n");
00361 value_clear(g); value_clear(m1); value_clear(m2);
00362
00363 return;
00364 }
00365 }
00366
00367
00368
00369 else if (value_zero_p(e1->d) && value_notzero_p(res->d)) {
00370 enode *tmp;
00371 evalue x;
00372 x=*res;
00373 tmp= ecopy(e1->x.p);
00374 value_init(res->d);
00375 value_set_si( res->d, 0 );
00376 res->x.p=tmp;
00377
00378 new_eadd(&x,res);
00379 value_clear(g); value_clear(m1); value_clear(m2);
00380 return ;
00381 }
00382 else {
00383 if ((e1->x.p->type != res->x.p->type) ) {
00384
00385
00386
00387
00388 if ((res->x.p->type == periodic)&&(e1->x.p->type == polynomial)) {
00389
00390 evalue eval;
00391 value_set_si( eval.d, 0 );
00392 eval.x.p=ecopy(res->x.p);
00393 res->x.p= ecopy(e1->x.p);
00394 new_eadd(&eval,&res->x.p->arr[0]);
00395
00396 }
00397 else if ((res->x.p->type == polynomial)&&(e1->x.p->type == periodic)) {
00398
00399
00400
00401 new_eadd(e1,&res->x.p->arr[0]);
00402 }
00403
00404 value_clear(g); value_clear(m1); value_clear(m2);
00405 return;
00406 }
00407 else if (e1->x.p->pos != res->x.p->pos ) {
00408
00409
00410
00411 if (res->x.p->type == polynomial) {
00412
00413
00414 new_eadd(e1,&res->x.p->arr[0]);
00415 value_clear(g); value_clear(m1); value_clear(m2);
00416 return;
00417 }
00418 else {
00419
00420
00421 for (i=0;i<res->x.p->size;i++) {
00422 new_eadd(e1,&res->x.p->arr[i]);
00423 }
00424 value_clear(g); value_clear(m1); value_clear(m2);
00425 return;
00426 }
00427
00428
00429 }
00430
00431
00432
00433 if (e1->x.p->size == res->x.p->size) {
00434
00435 for (i=0; i<res->x.p->size; i++) {
00436 new_eadd(&e1->x.p->arr[i], &res->x.p->arr[i]);
00437 }
00438 value_clear(g); value_clear(m1); value_clear(m2);
00439 return ;
00440 }
00441
00442
00443 if (res->x.p->type==polynomial) {
00444
00445
00446
00447
00448 if(e1->x.p->size > res->x.p->size) {
00449 enode *tmp;
00450 tmp = ecopy(e1->x.p);
00451 for(i=0;i<res->x.p->size;++i) {
00452 new_eadd(&res->x.p->arr[i], &tmp->arr[i]);
00453
00454 }
00455 res->x.p = tmp;
00456
00457 }
00458 else {
00459
00460 for (i=0; i<e1->x.p->size ; i++) {
00461 new_eadd(&e1->x.p->arr[i], &res->x.p->arr[i]);
00462 }
00463 value_clear(g); value_clear(m1); value_clear(m2);
00464
00465 return ;
00466 }
00467 }
00468
00469
00470 else if (res->x.p->type==periodic) {
00471
00472
00473
00474
00475
00476 x=e1->x.p->size;
00477 y= res->x.p->size;
00478 p=ppcm1(x,y);
00479 ne= (evalue *) malloc (sizeof(evalue));
00480 value_init(ne->d);
00481 value_set_si( ne->d,0);
00482
00483 ne->x.p=new_enode(res->x.p->type,p, res->x.p->pos);
00484 for(i=0;i<p;i++) {
00485 value_assign(ne->x.p->arr[i].d, res->x.p->arr[i%y].d);
00486 if (value_notzero_p(ne->x.p->arr[i].d)) {
00487 value_init(ne->x.p->arr[i].x.n);
00488 value_assign(ne->x.p->arr[i].x.n, res->x.p->arr[i%y].x.n);
00489 }
00490 else {
00491 ne->x.p->arr[i].x.p =ecopy(res->x.p->arr[i%y].x.p);
00492 }
00493 }
00494 for(i=0;i<p;i++) {
00495 new_eadd(&e1->x.p->arr[i%x], &ne->x.p->arr[i]);
00496 }
00497
00498 res=ne;
00499
00500 value_clear(g); value_clear(m1); value_clear(m2);
00501 return ;
00502 }
00503 else {
00504 fprintf(stderr, "eadd: ?cannot add vectors of different length\n");
00505 value_clear(g); value_clear(m1); value_clear(m2);
00506 return ;
00507 }
00508 }
00509 value_clear(g); value_clear(m1); value_clear(m2);
00510 return ;
00511 }
00512
00513
00514 Matrix *Reduce_Matrix (Matrix *Mat) {
00515 int i;
00516 Value *p;
00517 p=*(Mat->p+(Mat->NbRows-1));
00518 for (i=0;i<Mat->NbColumns; i++) {
00519 value_clear(*p++);
00520 }
00521 for (i=0; i<Mat->NbRows-1; i++) {
00522 p=*(Mat->p+i);
00523 value_clear(*(p+(Mat->NbColumns-1)));
00524 }
00525 Mat->NbRows--;
00526 Mat->NbColumns--;
00527 return Mat;
00528 }
00529
00530
00531
00532
00533 void Scalar_product(Value *p1,Value *p2,unsigned length, Value *r) {
00534 Value *cp1, *cp2;
00535
00536 int i;
00537 cp1=p1;
00538 cp2=p2;
00539 value_set_si(*r,0);
00540 for (i=0;i<length;i++) {
00541 value_addmul(*r, *cp1, *cp2);
00542 cp1++; cp2++;
00543 }
00544 }
00545
00546
00547
00548 int ppcm1 (int a, int b) {
00549 int t;
00550 t = (a*b)/ pgcd1(a,b);
00551 return t;
00552 }
00553
00554
00555 Matrix *Orthogonal_Base(Matrix *Mat) {
00556 Matrix *OrthMat;
00557 Value a,b,c,d;
00558 Vector *q,*p,*f;
00559 unsigned length;
00560 int i,j,k;
00561 value_init(a);
00562 value_init(b);
00563 value_init(c);
00564 value_init(d);
00565 OrthMat= Matrix_Alloc(Mat->NbRows,Mat->NbColumns);
00566 length=Mat->NbColumns;
00567 for(k=0; k<length; k++) {
00568 value_assign(OrthMat->p[0][k],Mat->p[0][k]);
00569 }
00570 f=Vector_Alloc(length);
00571 p=Vector_Alloc(length);
00572 q=Vector_Alloc(length);
00573 for(i=1; i<Mat->NbRows; i++) {
00574 for(k=0;k<length;k++) {
00575 value_assign(f->p[k],Mat->p[i][k]);
00576 value_assign(q->p[k],Mat->p[i][k]);
00577 }
00578 value_set_si(d,1);
00579 for(j=0; j<i; j++) {
00580 for(k=0;k<length;k++) {
00581 value_assign(p->p[k],OrthMat->p[j][k]);
00582 }
00583
00584 Scalar_product(p->p,f->p,length,&a);
00585 Scalar_product(p->p,p->p,length,&b);
00586 value_gcd(c, a, b);
00587 value_divexact(a, a, c);
00588 value_divexact(b, b, c);
00589 for(k=0;k<length;k++) {
00590 value_multiply(p->p[k],p->p[k],a);
00591 }
00592
00593 if(value_notone_p(d)|value_notone_p(b)) {
00594 value_lcm(c, d, b);
00595 value_divexact(a, c, b);
00596 value_divexact(b, c, d);
00597 value_assign(d,c);
00598 for(k=0;k<length;k++) {
00599 value_multiply(p->p[k],p->p[k],a);
00600 value_multiply(q->p[k],q->p[k],b);
00601 }
00602
00603 }
00604
00605 for(k=0;k<length;k++) {
00606 value_subtract(q->p[k],q->p[k],p->p[k]);
00607 }
00608
00609 }
00610 Vector_Gcd(q->p,length,&c);
00611 Vector_AntiScale(q->p, OrthMat->p[i], c, length);
00612 }
00613 value_clear(a);
00614 value_clear(b);
00615 value_clear(c);
00616 value_clear(d);
00617 return OrthMat;
00618 }
00619
00620
00621
00622 void Remove_Element(Enumeration *en,Enumeration **re, Enumeration *prev) {
00623 if (en== *re) {
00624 *re= (*re)->next;
00625 }
00626 else {
00627 prev->next=en->next;
00628 }
00629 }
00630
00631
00632
00633
00634 void Remove_RedundantDomains (Enumeration **Ures) {
00635 Enumeration *ren1, *ren2, *previous=NULL;
00636 int red;
00637 for (ren1=*Ures; ren1; ren1=ren1->next) {
00638 red=0;
00639 for (ren2=*Ures; ren2; ren2=ren2->next) {
00640 if (ren1!=ren2) {
00641
00642 if (PolyhedronIncludes(ren2->ValidityDomain, ren1->ValidityDomain)) {
00643 red= 1;
00644 break;
00645
00646 }
00647
00648 }
00649 }
00650 if (red) {
00651 Remove_Element(ren1,Ures,previous);
00652 }
00653 previous=ren1;
00654 }
00655 }
00656
00657
00658 int IncludeInRes (Polyhedron *p, Enumeration *e, unsigned MR) {
00659 Enumeration *en;
00660 for (en=e; en; en=en->next) {
00661
00662 if (PolyhedronIncludes(e->ValidityDomain,p))
00663 return 1;
00664 }
00665 return 0;
00666 }
00667
00668 Polyhedron *DMUnion(Enumeration *en, unsigned MR) {
00669 Enumeration *e1;
00670 Polyhedron *d;
00671 e1=en;
00672 d=e1->ValidityDomain;
00673 for (e1=en->next; e1; e1=e1->next) {
00674 d= DomainUnion( d, e1->ValidityDomain, MR);
00675 }
00676 return d;
00677 }
00678
00679
00680 void AffConstraints(Polyhedron *Poldisj)
00681 {
00682 Polyhedron *p;
00683
00684 for(p=Poldisj;p;p=p->next)
00685 {
00686 Polyhedron_PrintConstraints( stdout, P_VALUE_FMT, p);
00687 printf("\n");
00688 }
00689 }
00690 int Degenerate (Enumeration *en) {
00691 if(value_notzero_p(en->EP.d)) {
00692
00693 if(value_mone_p(en->EP.x.n )) {
00694 return 1;
00695 }
00696 }
00697 return 0;
00698 }
00699
00700
00701
00702 Enumeration *Domain_Enumerate(Polyhedron *D, Polyhedron *C, unsigned MAXRAYS,
00703 const char **pn)
00704 { Polyhedron_union *Polun,*pu;
00705 Polyhedron *lp, *lp1, *lp1next;
00706 Polyhedron *d1,*d2,*d;
00707 Enumeration *e,*pr,*en,*en1, *en2,*tmp, *res, *sen;
00708 Polun=NULL;
00709
00710 for (d = D; d; d = d->next) {
00711 POL_ENSURE_FACETS(d);
00712 POL_ENSURE_VERTICES(d);
00713 }
00714 POL_ENSURE_FACETS(C);
00715 POL_ENSURE_VERTICES(C);
00716
00717 lp = Disjoint_Domain( D, 0, MAXRAYS );
00718
00719 #ifdef UE_DEBUG
00720 printf("##############################################################\n");
00721 printf("\n###### DISJOINT UNION ######\n\n");
00722 AffConstraints(lp);
00723 printf("##############################################################\n");
00724 #endif
00725
00726 for (lp1=lp ; lp1; lp1=lp1->next)
00727 {
00728 Enumeration *enext;
00729 lp1next = lp1->next;
00730 lp1->next = NULL;
00731 en= Polyhedron_Enumerate(lp1, C, MAXRAYS,NULL);
00732 lp1->next = lp1next;
00733 sen= NULL;
00734 for (e=en;e;e=enext) {
00735 enext = e->next;
00736 if (!Degenerate(e)) {
00737 e->next = sen;
00738 sen=e;
00739 } else {
00740 free_evalue_refs(&e->EP);
00741 Domain_Free(e->ValidityDomain);
00742 free(e);
00743 }
00744 }
00745
00746 if(sen!= NULL)
00747 {
00748 pu = (Polyhedron_union *)malloc(sizeof(Polyhedron_union));
00749 pu->pt=sen;
00750 pu->next = Polun;
00751 Polun = pu;
00752 }
00753 }
00754 if(!Polun)
00755 {
00756 #ifdef UE_DEBUG
00757 fprintf(stdout,"Empty Polun\n");
00758 #endif
00759 return ((Enumeration *) 0);
00760 }
00761
00762 while(Polun->next != NULL) {
00763 Enumeration *enext;
00764 res=NULL;
00765 en1=Polun->pt;
00766 en2=(Polun->next)->pt;
00767
00768 d1=DMUnion(en1, MAXRAYS);
00769 d2=DMUnion(en2, MAXRAYS);
00770
00771 for (en1=Polun->pt;en1;en1=enext) {
00772 enext = en1->next;
00773 for(en2=(Polun->next)->pt;en2;en2=en2->next)
00774 {
00775 d = DomainIntersection(en1->ValidityDomain,en2->ValidityDomain,MAXRAYS);
00776 if( d && !emptyQ(d)&&!IncludeInRes(d,res,MAXRAYS)) {
00777 tmp = (Enumeration *)malloc(sizeof(Enumeration));
00778 value_init(tmp->EP.d);
00779 value_assign( tmp->EP.d, en2->EP.d );
00780 if(value_zero_p(tmp->EP.d))
00781 tmp->EP.x.p=ecopy(en2->EP.x.p);
00782 else
00783 {
00784 value_init(tmp->EP.x.n);
00785 value_assign( tmp->EP.x.n, en2->EP.x.n );
00786 }
00787
00788 new_eadd(&en1->EP,&tmp->EP);
00789 tmp->ValidityDomain =d;
00790 tmp->next= res;
00791 res=tmp;
00792 }
00793 }
00794 d=DomainDifference(en1->ValidityDomain,d2 ,MAXRAYS);
00795 if (d && !emptyQ(d) && !IncludeInRes(d,res,MAXRAYS)) {
00796 en1->ValidityDomain = d;
00797 en1->next= res;
00798 res=en1;
00799 } else {
00800 free_evalue_refs(&en1->EP);
00801 free(en1);
00802 }
00803 }
00804 for (en2=(Polun->next)->pt; en2; en2 = enext) {
00805 enext = en2->next;
00806 d= DomainDifference(en2->ValidityDomain,d1,MAXRAYS);
00807 if (d && !emptyQ(d)&&!IncludeInRes(d,res,MAXRAYS)) {
00808 en2->ValidityDomain = d;
00809 en2->next = res;
00810 res = en2;
00811 } else {
00812 free_evalue_refs(&en2->EP);
00813 free(en2);
00814 }
00815 }
00816 Domain_Free(d1);
00817 Domain_Free(d2);
00818
00819 Polun->pt=res;
00820
00821 Polun->next= (Polun->next)->next;
00822 }
00823 res=Polun->pt;
00824
00825 Remove_RedundantDomains(&res);
00826 return(res);
00827 }
00828
00829
00830
00831
00832
00833
00834
00835 Enumeration *Polyhedron_Image_Enumerate(Polyhedron *D, Polyhedron *C, Matrix *T, unsigned MAXRAYS, const char **par_name)
00836 { Polyhedron *polun,*pol;
00837 Enumeration *ee;
00838 Matrix *TCopy,*Tred, *d1,*d;
00839 Vector *v1,*v2;
00840 Value h;
00841 int i,j,k;
00842
00843 POL_ENSURE_FACETS(D);
00844 POL_ENSURE_VERTICES(D);
00845 POL_ENSURE_FACETS(C);
00846 POL_ENSURE_VERTICES(C);
00847
00848 value_init(h);
00849 if(!D) {
00850 fprintf(stdout," Error: in reading input domain \n");
00851 value_clear(h);
00852 return ((Enumeration *) 0);
00853 }
00854 else {
00855 printf("\n ################ INPUT POLYHEDRON #######################\n\n");
00856 AffConstraints(D);
00857 }
00858
00859 #ifdef DOMAIN_IMAGE
00860 fpol=DomainImage(D,T,MAXRAYS);
00861 printf("\n $$$$$$$$$$$$$ THE DOMAIN IMAGE $$$$$$$$$$$$$\n\n");
00862 AffConstraints(fpol);
00863 if(emptyQ(fpol)) {
00864 value_clear(h);
00865 return ((Enumeration *) 0);
00866 }
00867 ee = Domain_Enumerate(fpol,C,MAXRAYS,par_name);
00868 value_clear(h);
00869 return (ee);
00870 #endif
00871
00872 TCopy= Matrix_Copy(T);
00873 Tred= Reduce_Matrix(TCopy);
00874 printf("\n ################## INPUT REDUCED TRANSFORMATION MATRIX ##################\n" );
00875 Matrix_Print(stdout,P_VALUE_FMT,Tred);
00876
00877 if (Tred->NbRows <Tred->NbColumns) {
00878 d1=(Matrix *) Matrix_Alloc(Tred->NbColumns,Tred->NbColumns);
00879 for (i=0;i<Tred->NbRows;i++) {
00880 for (j=0; j<Tred->NbColumns;j++) {
00881 value_assign( d1->p[i][j], Tred->p[i][j] );
00882 }
00883 }
00884 for(i=Tred->NbRows;i<Tred->NbColumns;i++) {
00885 for (j=0;j<Tred->NbColumns;j++) {
00886 value_set_si( d1->p[i][j], 0 );
00887 }
00888 }
00889 d= (Matrix *) CalcBase(d1);
00890 Matrix_Free(Tred);
00891 Matrix_Free(d1);
00892
00893 }
00894 else {
00895 d=(Matrix *) CalcBase(Tred);
00896 Matrix_Free(Tred);
00897 }
00898 if(d->NbRows==0) {
00899 if(emptyQ(D)) {
00900 value_clear(h);
00901 return ((Enumeration *) 0);
00902 }
00903 else {
00904 printf( " Ker(A)=0 implys directly Enumeration on input polyhedron\n\n");
00905 ee=Domain_Enumerate(D,C,MAXRAYS,par_name);
00906 value_clear(h);
00907 return ee;
00908 }
00909 }
00910
00911 d1=Transpose(d);
00912 Matrix_Free(d);
00913
00914 if(d1->NbRows!=D->Dimension) {
00915 fprintf(stdout," \n Error: incompatible dimension \n");
00916 value_clear(h);
00917 return ((Enumeration *) 0);
00918 }
00919 if(d1->NbColumns > 1) {
00920 fprintf(stdout," \n Error: Can not compute int�gral points : More then vector in ker(A)! \n");
00921 value_clear(h);
00922 return ((Enumeration *) 0);
00923
00924 }
00925 printf( " \n Ker(A)=1 implys adding constraints befor Enumeration\n");
00926 v1=Vector_Alloc(d1->NbRows);
00927 v2=Vector_Alloc(d1->NbRows);
00928
00929 polun=(Polyhedron *) NULL;
00930 for (k=0;k<d1->NbRows;k++) {
00931 value_assign(v1->p[k],d1->p[k][0]) ;
00932 }
00933
00934
00935
00936 for (j=0;j<D->NbConstraints;j++) {
00937 for (k=0;k<=D->Dimension-1;k++) {
00938 value_assign(v2->p[k],D->Constraint[j][k+1]) ;
00939 }
00940 Scalar_product(v1->p,v2->p,D->Dimension,&h);
00941
00942 if(value_pos_p(h)&&!value_zero_p(D->Constraint[j][0])) {
00943 Vector *NCont;
00944 Value val;
00945 value_init( val );
00946
00947
00948 NCont=Vector_Alloc(d1->NbRows+2);
00949 value_set_si( NCont->p[0],1);
00950
00951 for (k=1;k<=D->Dimension;k++) {
00952 value_oppose( NCont->p[k], D->Constraint[j][k]);
00953 }
00954 value_decrement(val,h);
00955 value_subtract(val,val,D->Constraint[j][D->Dimension+1]);
00956 value_assign (NCont->p[D->Dimension+1],val);
00957 value_clear(val);
00958
00959 pol=AddConstraints(NCont->p,1,D,MAXRAYS);
00960 POL_ENSURE_VERTICES(pol);
00961 polun=AddPolyToDomain(Polyhedron_Copy(pol),polun);
00962 Polyhedron_Free(pol);
00963 Vector_Free(NCont);
00964 value_clear( val );
00965 }
00966 }
00967 if(polun==NULL) {
00968 if(emptyQ(D)) {
00969 value_clear(h);
00970 return ((Enumeration *) 0);
00971 }
00972 else {
00973 ee= Domain_Enumerate(D,C,MAXRAYS,par_name);
00974 }
00975 }
00976 else {
00977 if(emptyQ(polun)){
00978 value_clear(h);
00979 return ((Enumeration *) 0);
00980 }
00981 else {
00982 printf("\n ##################################################################");
00983 printf("\n ****** THE RESULT OF ADDING CONSTRAINTS TO THE INPUT POLYHEDRON ****** \n");
00984 AffConstraints(polun);
00985 ee= Domain_Enumerate(polun,C,MAXRAYS,par_name);
00986 value_clear(h);
00987 return (ee );
00988 }
00989 }
00990
00991
00992 return( NULL );
00993 }
00994
00995