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