00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <assert.h>
00030 #ifdef DEBUGPP
00031 #include <time.h>
00032 #endif
00033
00034 #include <polylib/polylib.h>
00035
00036 #ifdef __STDC__
00037 static void traite_m_face(Polyhedron *, int *);
00038 static void scan_m_face(int,int,Polyhedron *,unsigned int *);
00039 #else
00040 static void traite_m_face();
00041 static void scan_m_face();
00042 #endif
00043
00044
00045
00046
00047
00048
00049
00050 Polyhedron *PDomainIntersection(Polyhedron *Pol1,Polyhedron *Pol2,unsigned NbMaxRays) {
00051
00052 Polyhedron *p1, *p2, *p3, *d;
00053
00054 if (!Pol1 || !Pol2) return (Polyhedron*) 0;
00055 if((Pol1->Dimension != Pol2->Dimension) || (Pol1->NbEq != Pol2->NbEq)) {
00056 fprintf(stderr,
00057 "? PDomainIntersection: operation on different dimensions\n");
00058 return (Polyhedron*) 0;
00059 }
00060
00061 d = (Polyhedron *)0;
00062 for (p1=Pol1; p1; p1=p1->next) {
00063 for (p2=Pol2; p2; p2=p2->next) {
00064 p3 = AddConstraints(p2->Constraint[0],
00065 p2->NbConstraints,p1,NbMaxRays);
00066 if (!p3) continue;
00067
00068
00069 if (p3->NbEq!=Pol1->NbEq)
00070 Polyhedron_Free(p3) ;
00071
00072
00073 else
00074 d = AddPolyToDomain(p3,d);
00075 }
00076 }
00077 return d;
00078 }
00079
00080
00081
00082
00083
00084
00085
00086 Polyhedron *PDomainDifference(Polyhedron *Pol1,Polyhedron *Pol2,unsigned NbMaxRays) {
00087
00088 Polyhedron *p1, *p2, *p3, *d;
00089 int i;
00090
00091 if (!Pol1 || !Pol2)
00092 return (Polyhedron*) 0;
00093 if((Pol1->Dimension != Pol2->Dimension) || (Pol1->NbEq != Pol2->NbEq)) {
00094 fprintf(stderr,
00095 "? PDomainDifference: operation on different dimensions\n");
00096 return (Polyhedron*) 0;
00097 }
00098
00099 d = (Polyhedron *)0;
00100 for (p2=Pol2; p2; p2=p2->next) {
00101 for (p1=Pol1; p1; p1=p1->next) {
00102 for (i=0; i<p2->NbConstraints; i++) {
00103
00104
00105 p3 = SubConstraint(p2->Constraint[i],p1,NbMaxRays,2);
00106 if (!p3) continue;
00107
00108
00109
00110 if (emptyQ(p3) || p3->NbEq!=Pol1->NbEq)
00111 Polyhedron_Free(p3);
00112
00113
00114 else
00115 d = AddPolyToDomain(p3,d);
00116 }
00117 }
00118 if (p2 != Pol2)
00119 Domain_Free(Pol1);
00120 Pol1 = d;
00121 d = (Polyhedron *)0;
00122 }
00123 return Pol1;
00124 }
00125
00126
00127
00128
00129 static int TestRank(Matrix *Mat) {
00130
00131 int i,j,k;
00132 Value m1,m2,m3,gcd,tmp;
00133
00134
00135 value_init(m1); value_init(m2);
00136 value_init(m3); value_init(gcd); value_init(tmp);
00137
00138 for(k=0;k<Mat->NbColumns;++k) {
00139
00140
00141
00142 if(value_zero_p(Mat->p[k][k])) {
00143 for(j=k+1;j<Mat->NbRows;++j) {
00144
00145
00146 if(value_notzero_p(Mat->p[j][k])) {
00147
00148
00149 for(i=k;i<Mat->NbColumns;++i) {
00150 value_assign(tmp,Mat->p[j][i]);
00151 value_assign(Mat->p[j][i],Mat->p[k][i]);
00152 value_assign(Mat->p[k][i],tmp);
00153 }
00154 break;
00155 }
00156 }
00157
00158
00159
00160 if(j>=Mat->NbRows) {
00161
00162
00163 value_clear(m1); value_clear(m2);
00164 value_clear(m3); value_clear(gcd); value_clear(tmp);
00165 return 0;
00166 }
00167 }
00168
00169
00170 for(j=k+1;j<Mat->NbRows;++j) {
00171
00172
00173 Gcd(Mat->p[j][k],Mat->p[k][k],&gcd);
00174 for(i=k+1;i<Mat->NbColumns;++i) {
00175
00176
00177 value_multiply(m1,Mat->p[j][i],Mat->p[k][k]);
00178 value_multiply(m2,Mat->p[j][k],Mat->p[k][i]);
00179 value_substract(m3,m1,m2);
00180 value_division(Mat->p[j][i],m3,gcd);
00181 }
00182 }
00183 }
00184
00185
00186 value_clear(m1); value_clear(m2);
00187 value_clear(m3); value_clear(gcd); value_clear(tmp);
00188
00189
00190 return 1;
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200 typedef struct {
00201 unsigned int NbRows;
00202 unsigned int NbColumns;
00203 unsigned int **p;
00204 unsigned int *p_init;
00205 } SatMatrix;
00206
00207 static SatMatrix *SMAlloc(int rows,int cols) {
00208
00209 unsigned int **q, *p;
00210 int i;
00211
00212 SatMatrix *result = (SatMatrix *)malloc(sizeof(SatMatrix));
00213 assert (result != NULL);
00214
00215 result->NbRows = rows;
00216 result->NbColumns = cols;
00217 result->p = q = (unsigned int **)malloc(rows * sizeof(unsigned int *));
00218 assert (result->p != NULL);
00219 result->p_init = p = (unsigned int *)malloc(rows * cols * sizeof(unsigned int));
00220 assert (result->p_init != NULL);
00221
00222 for (i=0;i<rows;i++) {
00223 *q++ = p;
00224 p += cols;
00225 }
00226
00227 return result;
00228 }
00229
00230
00231 static void SMFree (SatMatrix *matrix) {
00232
00233 free ((char *) matrix->p_init);
00234 free ((char *) matrix->p);
00235 free ((char *) matrix);
00236 return;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245 static int m;
00246 static int m_dim;
00247 static int n;
00248 static int ws;
00249 static int nr;
00250
00251 static Polyhedron *CEqualities;
00252 static SatMatrix *Sat;
00253 static int *egalite;
00254 static Matrix *Xi, *Pi;
00255 static Matrix *PiTest;
00256 static Matrix *PiInv;
00257
00258 static Matrix *RaysDi;
00259
00260 static int KD;
00261
00262
00263 static int nbPV;
00264 static Param_Vertices *PV_Result;
00265 static Param_Domain *PDomains;
00266
00267 #ifdef DEBUGPP
00268 static int nbfaces;
00269 #endif
00270
00271
00272
00273
00274
00275
00276 static Polyhedron *Add_CEqualities(Polyhedron *D) {
00277
00278 Polyhedron *d,*r,*tmp;
00279
00280 if(!CEqualities)
00281 return D;
00282 else {
00283 if(!D || emptyQ(D)) {
00284 if(D)
00285 Domain_Free(D);
00286 return(Polyhedron_Copy(CEqualities));
00287 }
00288 r = AddConstraints(D->Constraint[0],D->NbConstraints,
00289 CEqualities,ws);
00290 tmp = r;
00291 for(d=D->next;d;d=d->next) {
00292 tmp->next = AddConstraints(d->Constraint[0],d->NbConstraints,
00293 CEqualities,ws);
00294 tmp = tmp->next;
00295 }
00296 Domain_Free(D);
00297 return(r);
00298 }
00299 }
00300
00301
00302
00303
00304
00305 static void traite_m_face(Polyhedron *D,int *mf) {
00306
00307
00308
00309 Matrix *Si;
00310 Polyhedron *PDi;
00311 Param_Vertices *PV;
00312 int j,k,c,r;
00313 unsigned kx, bx;
00314
00315 #ifdef DEBUGPP
00316 ++nbfaces;
00317 #endif
00318
00319
00320 RaysDi->NbRows = 0;
00321 for(k=0,c=0,kx=0,bx=MSB;k<D->NbRays;++k) {
00322 if(mf[kx]&bx) {
00323 if(c<m+1) {
00324 int i;
00325
00326
00327
00328
00329
00330
00331 for(j=0;j<m+1;++j) {
00332 for(i=0;i<c;++i)
00333
00334
00335 value_assign(PiTest->p[j][i],Pi->p[j][i]);
00336
00337
00338 value_assign(PiTest->p[j][c],D->Ray[k][j+1+n]);
00339 }
00340 PiTest->NbColumns = c+1;
00341 r = TestRank(PiTest);
00342 if(r ) {
00343
00344
00345 for (j=0;j<n;j++)
00346 value_assign(Xi->p[j][c],D->Ray[k][j+1]);
00347 for (j=0;j<m;j++)
00348 value_assign(Pi->p[j][c],D->Ray[k][j+1+n]);
00349 value_assign(Xi->p[n][c],D->Ray[k][n+m+1]);
00350 value_assign(Pi->p[m][c],D->Ray[k][n+m+1]);
00351 c++;
00352 }
00353 }
00354
00355
00356 value_assign(RaysDi->p[RaysDi->NbRows][0],D->Ray[k][0]);
00357 Vector_Copy(&D->Ray[k][n+1],&RaysDi->p[RaysDi->NbRows][1],(m+1));
00358 ++RaysDi->NbRows;
00359 }
00360 NEXT(kx,bx);
00361 }
00362
00363 #ifdef DEBUGPP41
00364 printf("\nRaysDi=\n");
00365 Matrix_Print(stdout,P_VALUE_FMT,RaysDi);
00366 if(c < m+1)
00367 printf("Invalid ");
00368 printf("Pi=\n");
00369 Matrix_Print(stdout,P_VALUE_FMT,Pi);
00370 #endif
00371
00372 #ifdef DEBUGPP4
00373 if(c < m+1)
00374 fprintf(stderr,"Eliminated because of no vertex\n");
00375 #endif
00376
00377 if(c < m+1)
00378 return;
00379
00380
00381
00382
00383
00384
00385
00386
00387 #ifdef DEBUGPP4
00388 fprintf(stderr,"Xi = ");
00389 Matrix_Print(stderr,P_VALUE_FMT,Xi);
00390 fprintf(stderr,"Pi = ");
00391 Matrix_Print(stderr,P_VALUE_FMT,Pi);
00392 #endif
00393
00394
00395
00396 if(!MatInverse(Pi,PiInv)) {
00397
00398 #ifdef DEBUGPP4
00399 fprintf(stderr, "Eliminated because of no inverse Pi\n");
00400 #endif
00401
00402 return;
00403 }
00404
00405 #ifdef DEBUGPP4
00406 fprintf(stderr,"FACE GENERATED!\n");
00407 fprintf(stderr,"PiInv = ");
00408 Matrix_Print(stderr,P_VALUE_FMT,PiInv);
00409 #endif
00410
00411
00412 Si = Matrix_Alloc(Xi->NbRows,PiInv->NbColumns);
00413 rat_prodmat(Si,Xi,PiInv);
00414
00415 #ifdef DEBUGPP4
00416 fprintf(stderr,"Si = ");
00417 Matrix_Print(stderr,P_VALUE_FMT,Si);
00418 #endif
00419
00420 Si->NbRows--;
00421
00422
00423 PV = (Param_Vertices *) malloc(sizeof(Param_Vertices));
00424 PV->next = PV_Result;
00425 PV->Vertex = Si;
00426 PV->Domain = NULL;
00427 PV_Result = PV;
00428 nbPV++;
00429
00430
00431 PDi = Rays2Polyhedron(RaysDi,ws);
00432
00433 #ifdef DEBUGPP3
00434 fprintf(stderr,"RaysDi = ");
00435 Matrix_Print(stderr,P_VALUE_FMT,RaysDi);
00436 fprintf(stderr,"PDi = ");
00437 Polyhedron_Print(stderr,P_VALUE_FMT,PDi);
00438 #endif
00439
00440 if(KD==0) {
00441
00442
00443 PDi = Add_CEqualities(PDi);
00444 PV->Domain = Polyhedron2Constraints(PDi);
00445 Polyhedron_Free(PDi);
00446 }
00447 else {
00448 Param_Domain *PD;
00449 PD = (Param_Domain *) malloc(sizeof(Param_Domain));
00450 PD->Domain = PDi;
00451 PD->F = NULL;
00452 PD->next = PDomains;
00453 PDomains = PD;
00454 }
00455 return;
00456 }
00457
00458
00459
00460
00461
00462
00463 int cntbit[256] = {
00464 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
00465 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00466 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00467 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00468
00469 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00470 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00471 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00472 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00473
00474 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00475 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00476 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00477 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00478
00479 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00480 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00481 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00482 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 };
00483
00484 static int count_sat (unsigned int *mf) {
00485
00486 register unsigned int i, tmp, cnt=0;
00487
00488 for (i=0; i<nr; i++) {
00489 tmp = mf[i];
00490 cnt = cnt
00491 + cntbit[ tmp & 0xff ]
00492 + cntbit[ (tmp>>8) & 0xff ]
00493 + cntbit[ (tmp>>16) & 0xff ]
00494 + cntbit[ (tmp>>24) & 0xff ]
00495 ;
00496 }
00497 return cnt;
00498 }
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 static void scan_m_face(int pos,int nb_un,Polyhedron *D,unsigned int *mf) {
00542
00543
00544
00545
00546
00547 unsigned int *new_mf;
00548
00549 #ifdef DEBUGPP4
00550 fprintf(stderr,"Start scan_m_face(pos=%d, nb_un=%d, n=%d, m=%d\n",
00551 pos,nb_un,n,m);
00552 fprintf(stderr,"mf = ");
00553 {
00554 int i;
00555 for(i=0;i<nr;i++)
00556 fprintf(stderr,"%08X", mf[i]);
00557 fprintf(stderr,"\nequality = [");
00558 for(i=0;i<D->NbConstraints;i++)
00559 fprintf(stderr," %1d",egalite[i]);
00560 fprintf(stderr,"]\n");
00561 }
00562 #endif
00563
00564 if(nb_un == 0) {
00565 int i,j;
00566
00567
00568
00569
00570
00571 for(i=0;i<pos-1;i++)
00572 {
00573 if(egalite[i])
00574 continue;
00575
00576
00577 for (j=0;j<nr;j++)
00578 {
00579
00580 #ifdef DEBUGPP4
00581 fprintf(stderr,"mf=%08X Sat[%d]=%08X &=%08X\n",mf[j],i,Sat->p[i][j],
00582 (mf[j] & Sat->p[i][j]) );
00583 #endif
00584
00585 if (((mf[j]) & (Sat->p[i][j])) != mf[j])
00586 break;
00587 }
00588
00589 #ifdef DEBUGPP4
00590 if (j==nr) fprintf(stderr, "Redundant with constraint %d\n", i);
00591 #endif
00592
00593 if (j==nr) return;
00594 }
00595
00596
00597
00598 traite_m_face(D,mf);
00599 return;
00600 }
00601
00602
00603 if((pos+nb_un)>D->NbConstraints) return;
00604
00605
00606
00607 {
00608 int k;
00609 new_mf = (unsigned int *)malloc(nr*sizeof(unsigned int));
00610 for (k=0; k<nr; k++)
00611 new_mf[k] = mf[k] & Sat->p[pos][k];
00612 }
00613 #ifdef DEBUGPP4
00614 fprintf(stderr,"new_mf = ");
00615 {
00616 int i;
00617 for(i=0;i<nr;i++) {
00618 fprintf(stderr,"%08X", new_mf[i]);
00619 }
00620 fprintf(stderr,"\ncount(new_mf) = %d\n",count_sat(new_mf));
00621 }
00622 #endif
00623
00624 {
00625 int c;
00626 c = count_sat(new_mf);
00627
00628 if (c>m_dim )
00629 {
00630
00631
00632 if( c==count_sat(mf) )
00633 {
00634 egalite[pos]=1;
00635 scan_m_face(pos+1,nb_un,D,new_mf);
00636 }
00637 else
00638 {
00639 egalite[pos]=1;
00640 scan_m_face(pos+1,nb_un-1,D,new_mf);
00641 }
00642 }
00643 }
00644 free(new_mf);
00645 egalite[pos]=0;
00646 if ((pos+nb_un)>=D->NbConstraints) return;
00647 scan_m_face(pos+1,nb_un,D,mf);
00648 return;
00649 }
00650
00651
00652
00653
00654
00655
00656 static SatMatrix *Poly2Sat(Polyhedron *Pol,unsigned int **L) {
00657
00658 SatMatrix *Sat;
00659 int i, j, k, kx;
00660 unsigned int *Temp;
00661 Value *p1, *p2, p3,tmp;
00662 unsigned Dimension, NbRay, NbCon, bx;
00663
00664
00665 value_init(p3); value_init(tmp);
00666
00667 NbRay = Pol->NbRays;
00668 NbCon = Pol->NbConstraints;
00669 Dimension = Pol->Dimension+1;
00670
00671
00672 nr = (NbRay - 1)/(sizeof(int)*8) + 1;
00673 Sat = SMAlloc(NbCon,nr);
00674 Temp = (unsigned int *)malloc(nr*sizeof(unsigned int));
00675 memset(Sat->p_init,0,nr*NbCon*sizeof(int));
00676 memset(Temp,0,nr*sizeof(unsigned int));
00677 kx=0; bx=MSB;
00678 for (k=0; k<NbRay; k++) {
00679 for (i=0; i<NbCon; i++) {
00680 p1 = &Pol->Constraint[i][1];
00681 p2 = &Pol->Ray[k][1];
00682 value_set_si(p3,0);
00683 for (j=0;j<Dimension;j++) {
00684 value_multiply(tmp,*p1,*p2);
00685 value_addto(p3,p3,tmp);
00686 p1++; p2++;
00687 }
00688 if (value_zero_p(p3))
00689 Sat->p[i][kx]|=bx;
00690 }
00691 Temp[kx] |= bx;
00692 NEXT(kx, bx);
00693 }
00694
00695
00696
00697 *L = Temp;
00698
00699
00700 value_clear(p3); value_clear(tmp);
00701
00702 return Sat;
00703 }
00704
00705
00706
00707
00708
00709 Param_Polyhedron *GenParamPolyhedron(Polyhedron *Pol) {
00710
00711 Param_Polyhedron *result;
00712 Matrix *rays;
00713 int nbRows, nbColumns;
00714 int i, size;
00715
00716 rays=Polyhedron2Rays(Pol);
00717 nbRows=rays->NbRows;
00718 nbColumns=rays->NbColumns;
00719
00720
00721 for(i=0;i<nbRows;i++)
00722 if(value_notone_p(rays->p[i][0]) ||
00723 value_zero_p(rays->p[i][nbColumns-1]))
00724 return NULL;
00725
00726
00727 result=(Param_Polyhedron *)malloc(sizeof(Param_Polyhedron));
00728 result->nbV=nbRows;
00729 result->V=NULL;
00730
00731
00732 for(i=0;i<nbRows;i++) {
00733 Matrix *vertex;
00734 Param_Vertices *paramVertex;
00735 int j;
00736
00737 vertex=Matrix_Alloc(nbColumns-2,2);
00738 for(j=1;j<nbColumns-1;j++) {
00739 value_assign(vertex->p[j-1][0],rays->p[i][j]);
00740 value_assign(vertex->p[j-1][1],rays->p[i][nbColumns-1]);
00741 }
00742 paramVertex=(Param_Vertices *)malloc(sizeof(Param_Vertices));
00743 paramVertex->Vertex=vertex;
00744
00745
00746 paramVertex->Domain=Matrix_Alloc(1,2);
00747 value_set_si(paramVertex->Domain->p[0][0],1);
00748 value_set_si(paramVertex->Domain->p[0][1],1);
00749 paramVertex->next=result->V;
00750 result->V=paramVertex;
00751 }
00752
00753
00754 if (nbRows > 1)
00755 size=(nbRows-1)/(8*sizeof(int))+1;
00756 else
00757 size = 1;
00758 result->D=(Param_Domain *)malloc(sizeof(Param_Domain));
00759 result->D->next=NULL;
00760 result->D->Domain=Universe_Polyhedron(0);
00761 result->D->F=(int *)malloc(size*sizeof(int));
00762 memset(&result->D->F[0],0xFF,size*sizeof(int));
00763
00764 return result;
00765 }
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777 Matrix *PreElim_Columns(Polyhedron *E,int *p,int *ref,int m) {
00778
00779 int i,j,l;
00780 Matrix *T;
00781
00782
00783
00784
00785
00786 memset(p,0,sizeof(int)*(E->NbEq));
00787
00788 #ifdef DEBUGPP32
00789 fprintf(stderr,"\n\nPreElim_Columns starting\n");
00790 fprintf(stderr,"E =\n");
00791 Polyhedron_Print(stderr,P_VALUE_FMT,E);
00792 #endif
00793
00794 for(l=0;l<E->NbEq;++l) {
00795 if(value_notzero_p(E->Constraint[l][0])) {
00796 fprintf(stderr,"Internal error: Elim_Columns (polyparam.c), expecting equalities first in E.\n");
00797 free(p);
00798 return(NULL);
00799 }
00800 for(i=1;value_zero_p(E->Constraint[l][i]);++i) {
00801 if(i==E->Dimension+1) {
00802 fprintf(stderr,"Internal error: Elim_Columns (polyparam.c), expecting non-empty constraint in E.\n");
00803 free(p);
00804 return( NULL );
00805 }
00806 }
00807 p[l] = i;
00808
00809 #ifdef DEBUGPP32
00810 fprintf(stderr,"p[%d] = %d,",l,p[l]);
00811 #endif
00812 }
00813
00814
00815 for(i=0;i<E->Dimension+2-E->NbEq;++i) {
00816 ref[i]=i;
00817 for(j=0;j<E->NbEq;++j)
00818 if(p[j]<=ref[i])
00819 ref[i]++;
00820
00821 #ifdef DEBUGPP32
00822 fprintf(stderr,"ref[%d] = %d,",i,ref[i]);
00823 #endif
00824 }
00825
00826
00827 T = Matrix_Alloc(m+1-E->NbEq,m+1);
00828 for(i=0;i<T->NbColumns;i++)
00829 for(j=0;j<T->NbRows;j++)
00830 if(ref[E->Dimension-m+j+1] == E->Dimension-m+i+1)
00831 value_set_si(T->p[j][i],1);
00832 else
00833 value_set_si(T->p[j][i],0);
00834
00835 #ifdef DEBUGPP32
00836 fprintf(stderr,"\nTransMatrix =\n");
00837 Matrix_Print(stderr,P_VALUE_FMT,T);
00838 #endif
00839
00840 return(T);
00841
00842 }
00843
00844
00845
00846
00847
00848
00849
00850 Polyhedron *Elim_Columns(Polyhedron *A,Polyhedron *E,int *p,int *ref) {
00851
00852 int i,l,c;
00853 Matrix *M, *C;
00854 Polyhedron *R;
00855 Value tmp1,tmp2;
00856
00857
00858 value_init(tmp1); value_init(tmp2);
00859
00860 #ifdef DEBUGPP32
00861 fprintf(stderr,"\nElim_Columns starting\n");
00862 fprintf(stderr,"A =\n" );
00863 Polyhedron_Print(stderr,P_VALUE_FMT,A);
00864 #endif
00865
00866
00867 M = Polyhedron2Constraints(A);
00868 for(l=0;l<E->NbEq;++l) {
00869 for(c=0;c<M->NbRows;++c) {
00870 if(value_notzero_p(M->p[c][p[l]])) {
00871
00872
00873 for(i=1;i<M->NbColumns;++i) {
00874 value_multiply(tmp1,M->p[c][i],E->Constraint[l][p[l]]);
00875 value_multiply(tmp2,E->Constraint[l][i],M->p[c][p[l]]);
00876 value_substract(M->p[c][i],tmp1,tmp2);
00877 }
00878 }
00879 }
00880 }
00881
00882 #ifdef DEBUGPP32
00883 fprintf(stderr,"\nElim_Columns after zeroing columns of A.\n");
00884 fprintf(stderr,"M =\n");
00885 Matrix_Print(stderr,P_VALUE_FMT,M);
00886 #endif
00887
00888
00889 C = Matrix_Alloc(M->NbRows,M->NbColumns - E->NbEq);
00890 for(l=0;l<C->NbRows;++l)
00891 for(c=0;c<C->NbColumns;++c) {
00892 value_assign(C->p[l][c],M->p[l][ref[c]]);
00893 }
00894
00895 #ifdef DEBUGPP32
00896 fprintf(stderr,"\nElim_Columns after eliminating columns of A.\n");
00897 fprintf(stderr,"C =\n");
00898 Matrix_Print(stderr,P_VALUE_FMT,C);
00899 #endif
00900
00901 R = Constraints2Polyhedron(C,ws);
00902 Matrix_Free(C);
00903 Matrix_Free(M);
00904 value_clear(tmp1); value_clear(tmp2);
00905 return(R);
00906 }
00907
00908
00909
00910
00911
00912
00913
00914 Param_Polyhedron *Find_m_faces(Polyhedron **Di,Polyhedron *C,int keep_dom,int working_space,Polyhedron **CEq,Matrix **CT) {
00915
00916 unsigned int *mf;
00917 int i, j;
00918 Polyhedron *D=*Di,
00919 *C1,
00920 *D1;
00921 Matrix *M;
00922 Param_Polyhedron *res;
00923 int *p, *ref;
00924
00925 if(CT) {
00926 *CEq = NULL;
00927 *CT = NULL;
00928 }
00929
00930 if(!D || !C)
00931 return (Param_Polyhedron *) 0;
00932
00933 ws = working_space;
00934 m = C->Dimension;
00935 n = D->Dimension - m;
00936 if(n<0) {
00937 fprintf(stderr,
00938 "Find_m_faces: ?%d parameters of a %d-polyhedron !\n",m,n);
00939 return (Param_Polyhedron *) 0;
00940 }
00941 if(m==0) {
00942 Param_Polyhedron *result=GenParamPolyhedron(D);
00943 if(result)
00944 return result;
00945 else {
00946 fprintf(stderr,"Find_m_faces: polyhedron is not bounded!\n");
00947 return (Param_Polyhedron *) 0;
00948 }
00949 }
00950
00951
00952 C1 = align_context(C,D->Dimension,ws);
00953
00954 #ifdef DEBUGPP31
00955 fprintf(stderr,"m = %d\n",m);
00956 fprintf(stderr, "D = ");
00957 Polyhedron_Print(stderr,P_VALUE_FMT,D);
00958 fprintf(stderr,"C1 = ");
00959 Polyhedron_Print(stderr,P_VALUE_FMT,C1);
00960 #endif
00961
00962 D1 = DomainIntersection(D,C1,ws);
00963
00964 #ifdef DEBUGPP31
00965 fprintf(stderr,"D1 = ");
00966 Polyhedron_Print(stderr,P_VALUE_FMT,D1);
00967 #endif
00968
00969 Domain_Free(C1);
00970
00971 if(!D1 || emptyQ(D1))
00972 return(NULL);
00973
00974
00975
00976 M = Matrix_Alloc(n, D1->Dimension+2);
00977 Vector_Set(M->p[0],0,n*(D1->Dimension+2));
00978 for (i=0; i<n; i++)
00979 value_set_si(M->p[i][i+1],1);
00980 C1 = DomainAddRays(D1,M,ws);
00981 Matrix_Free(M);
00982
00983 #ifdef DEBUGPP31
00984 fprintf(stderr,"True context C1 = ");
00985 Polyhedron_Print(stderr,P_VALUE_FMT,C1);
00986 #endif
00987
00988
00989
00990 if(!CT) {
00991 if(C1->NbEq == 0)
00992 CEqualities = NULL;
00993 else {
00994 Polyhedron *CEq1,
00995 *C2,
00996 *D2;
00997
00998
00999
01000
01001 M = Matrix_Alloc(C1->NbEq,m+2);
01002 for(j=0,i=0;i<C1->NbEq;++i,++j) {
01003 while(value_notzero_p(C1->Constraint[j][0]))
01004 ++j;
01005 value_assign(M->p[i][0],C1->Constraint[j][0]);
01006 Vector_Copy(&C1->Constraint[j][D->Dimension-m+1],&M->p[i][1],(m+1));
01007 }
01008 CEqualities = Constraints2Polyhedron(M,ws);
01009 Matrix_Free(M);
01010 CEq1 = align_context(CEqualities,D->Dimension,ws);
01011
01012
01013 D2 = DomainSimplify(D1,CEq1,ws);
01014 C2 = DomainSimplify(C1,CEq1,ws);
01015 Polyhedron_Free(D1);
01016 Polyhedron_Free(C1);
01017 Polyhedron_Free(CEq1);
01018 D1 = D2;
01019 C1 = C2;
01020 }
01021 }
01022 else {
01023 Polyhedron *CEq1,
01024 *C2,
01025 *D2;
01026
01027
01028
01029
01030 CEq1 = C1;
01031 M = Matrix_Alloc(C1->NbConstraints,m+2);
01032 for(i=0;i<C1->NbConstraints;++i) {
01033 value_assign(M->p[i][0],C1->Constraint[i][0]);
01034 Vector_Copy(&C1->Constraint[i][D->Dimension-m+1],&M->p[i][1],(m+1));
01035 }
01036 CEqualities = Constraints2Polyhedron( M, ws );
01037 Matrix_Free(M);
01038
01039 D2 = DomainSimplify(D1,CEq1,ws);
01040 Polyhedron_Free(D1);
01041 D1 = D2;
01042 C1 = Universe_Polyhedron(D2->Dimension);
01043
01044
01045
01046
01047 if( CEq1->NbEq )
01048 {
01049 m -= CEq1->NbEq;
01050 p = (int *)malloc(sizeof(int)*(CEq1->NbEq));
01051 }
01052 else
01053 p = NULL;
01054 ref = (int*) malloc(sizeof(int)*
01055 (CEq1->Dimension+2-CEq1->NbEq));
01056 *CT = PreElim_Columns(CEq1,p,ref,CEqualities->Dimension);
01057 D2 = Elim_Columns(D1,CEq1,p,ref);
01058 C2 = Elim_Columns(C1,CEq1,p,ref);
01059 if (p)
01060 free(p);
01061 free(ref);
01062
01063 #ifdef DEBUGPP3
01064 fprintf(stderr,"D2\t Dim = %3d\tNbEq = %3d\tLines = %3d\n",
01065 D2->Dimension,D2->NbEq,D2->NbBid);
01066 fprintf(stderr,"C2\t Dim = %3d\tNbEq = %3d\tLines = %3d\n",
01067 C2->Dimension,C2->NbEq,C2->NbBid);
01068 #endif
01069
01070 Polyhedron_Free(D1);
01071 Polyhedron_Free(C1);
01072 D1 = D2;
01073 C1 = C2;
01074 *CEq = CEqualities;
01075
01076 #ifdef DEBUGPP3
01077 fprintf(stderr,"Polyhedron CEq = ");
01078 Polyhedron_Print(stderr,P_VALUE_FMT,*CEq);
01079 fprintf(stderr,"Matrix CT = ");
01080 Matrix_Print(stderr,P_VALUE_FMT,*CT);
01081 #endif
01082
01083 Polyhedron_Free(CEq1);
01084 CEqualities = NULL;
01085
01086
01087 if(m==0) {
01088 Param_Polyhedron *result=GenParamPolyhedron(D1);
01089
01090
01091 *Di = D1;
01092 if(result)
01093 return result;
01094 else {
01095 fprintf(stderr,"Find_m_faces: polyhedron is not bounded!\n");
01096 return (Param_Polyhedron *) 0;
01097 }
01098 }
01099 }
01100
01101 #ifdef DEBUGPP3
01102 fprintf(stderr,"Polyhedron D1 (D AND C) = ");
01103 Polyhedron_Print(stderr,P_VALUE_FMT, D1);
01104 fprintf(stderr,"Polyhedron CEqualities = ");
01105 if(CEqualities) Polyhedron_Print(stderr,P_VALUE_FMT, CEqualities);
01106 else fprintf(stderr,"NULL\n");
01107 #endif
01108
01109 KD = keep_dom;
01110 PDomains = NULL;
01111 PV_Result = NULL;
01112 nbPV = 0;
01113
01114 if (D1->NbRays==0) return 0;
01115
01116
01117
01118
01119 Sat = Poly2Sat(D1,&mf);
01120
01121 #ifdef DEBUGPP4
01122
01123
01124
01125 fprintf(stderr,"mf = ");
01126 for (i=0; i<nr; i++)
01127 fprintf(stderr,"%08X", mf[i]);
01128 fprintf(stderr, "\n");
01129 #endif
01130
01131
01132 egalite = (int *)malloc(sizeof(int)*D1->NbConstraints );
01133 memset(egalite,0, sizeof(int)*D1->NbConstraints);
01134
01135 for (i=0; i<D1->NbEq; i++)
01136 egalite[i] = 1;
01137
01138 Xi = Matrix_Alloc(n+1,m+1);
01139 Pi = Matrix_Alloc(m+1,m+1);
01140 PiTest = Matrix_Alloc(m+1,m+1);
01141 PiInv = Matrix_Alloc(m+1,m+2);
01142 RaysDi = Matrix_Alloc(D1->NbRays,m+2);
01143 m_dim = m;
01144
01145 #ifdef DEBUGPP
01146 nbfaces=0;
01147 #endif
01148 #ifdef DEBUGPP3
01149 fprintf(stderr,
01150 "Target: find faces that saturate %d constraints and %d rays/lines\n",
01151 D1->Dimension - m_dim,m_dim+1);
01152 #endif
01153
01154
01155 scan_m_face(D1->NbEq,(D1->Dimension - m_dim - D1->NbEq),D1,mf);
01156
01157
01158
01159 #ifdef DEBUGPP
01160 fprintf( stderr, "Number of m-faces: %d\n", nbfaces );
01161 #endif
01162
01163 Matrix_Free(RaysDi);
01164 Matrix_Free(PiInv);
01165 Matrix_Free(PiTest);
01166 Matrix_Free(Pi);
01167 Matrix_Free(Xi);
01168 free(egalite);
01169 free(mf);
01170 SMFree(Sat);
01171
01172
01173
01174
01175
01176
01177 if(CT)
01178 *Di = D1;
01179 else
01180 Domain_Free(D1);
01181 Domain_Free(C1);
01182
01183 res = (Param_Polyhedron *) malloc (sizeof(Param_Polyhedron));
01184 res->nbV = nbPV;
01185 res->V = PV_Result;
01186 res->D = PDomains;
01187 return(res);
01188 }
01189
01190
01191
01192
01193
01194 void Compute_PDomains(Param_Domain *PD,int nb_domains,int working_space) {
01195
01196 unsigned bx;
01197 int i, ix, nv;
01198 Polyhedron *dx, *d1, *d2;
01199 Param_Domain *p1, *p2, *p2prev, *PDNew;
01200
01201 if (nb_domains==0) {
01202
01203 #ifdef DEBUGPP5
01204 fprintf(stderr,"No domains\n");
01205 #endif
01206
01207 return;
01208 }
01209
01210
01211 nv = (nb_domains - 1)/(8*sizeof(int)) + 1;
01212
01213 #ifdef DEBUGPP5
01214 fprintf(stderr,"nv = %d\n",nv);
01215 #endif
01216
01217 for(p1=PD,i=0,ix=0,bx=MSB;p1;p1=p1->next,i++) {
01218
01219
01220 p1->F = (unsigned *) malloc (nv * sizeof(unsigned));
01221
01222
01223 memset(p1->F,0,nv * sizeof(unsigned));
01224 p1->F[ix] |= bx;
01225 NEXT(ix, bx);
01226 }
01227
01228 #ifdef DEBUGPP5
01229 fprintf(stderr,"nb of vertices=%d\n",i);
01230 #endif
01231
01232
01233 ix = 0; bx=MSB;
01234 for (p1=PD;p1;p1=p1->next) {
01235 for (p2prev=p1,p2=p1->next;p2;p2prev=p2,p2=p2->next) {
01236
01237
01238 dx = PDomainIntersection(p1->Domain,p2->Domain,working_space);
01239
01240 if (!dx || emptyQ(dx)) {
01241
01242 #ifdef DEBUGPP5
01243 fprintf( stderr, "Empty dx (p1 inter p2). Continuing\n");
01244 #endif
01245 if(dx)
01246 Domain_Free(dx);
01247 continue;
01248 }
01249
01250 #ifdef DEBUGPP5
01251 fprintf(stderr,"Begin PDomainDifference\n");
01252 fprintf(stderr, "p1=");
01253 Polyhedron_Print(stderr,P_VALUE_FMT,p1->Domain);
01254 fprintf(stderr,"p2=");
01255 Polyhedron_Print(stderr,P_VALUE_FMT,p2->Domain);
01256 #endif
01257 d1 = PDomainDifference(p1->Domain,p2->Domain,working_space);
01258 d2 = PDomainDifference(p2->Domain,p1->Domain,working_space);
01259
01260 #ifdef DEBUGPP5
01261 fprintf(stderr,"p1\\p2=");
01262 Polyhedron_Print(stderr,P_VALUE_FMT,d1);
01263 fprintf(stderr,"p2\\p1=");
01264 Polyhedron_Print(stderr,P_VALUE_FMT,d2);
01265 fprintf(stderr,"END PDomainDifference\n\n");
01266 #endif
01267 if (!d1 || emptyQ(d1) || d1->NbEq!=0) {
01268
01269 #ifdef DEBUGPP5
01270 fprintf(stderr,"Empty d1\n");
01271 #endif
01272 if (d1)
01273 Domain_Free(d1);
01274 Domain_Free(dx);
01275
01276 if (!d2 || emptyQ(d2) || d2->NbEq!=0) {
01277
01278 #ifdef DEBUGPP5
01279 fprintf( stderr, "Empty d2 (deleting)\n");
01280 #endif
01281
01282 if (d2) Domain_Free(d2);
01283
01284
01285 for (i=0;i<nv;i++)
01286 p1->F[i] |= p2->F[i];
01287
01288
01289 p2prev->next = p2->next;
01290 Domain_Free(p2->Domain);
01291 free(p2->F);
01292 free(p2);
01293 p2 = p2prev;
01294 }
01295 else {
01296
01297 #ifdef DEBUGPP5
01298 fprintf( stderr, "p2 replaced by d2\n");
01299 #endif
01300
01301 for(i=0;i<nv;i++)
01302 p1->F[i] |= p2->F[i];
01303
01304
01305 Domain_Free( p2->Domain );
01306 p2->Domain = d2;
01307 }
01308 }
01309 else {
01310 if (!d2 || emptyQ(d2) || d2->NbEq!=0) {
01311
01312 #ifdef DEBUGPP5
01313 fprintf( stderr, "p1 replaced by d1\n");
01314 #endif
01315 if (d2) Domain_Free(d2);
01316
01317
01318 Domain_Free(dx);
01319
01320
01321 for(i=0;i<nv;i++)
01322 p2->F[i] |= p1->F[i];
01323
01324
01325 Domain_Free(p1->Domain);
01326 p1->Domain = d1;
01327 }
01328 else {
01329
01330 #ifdef DEBUGPP5
01331 fprintf(stderr,"Non-empty d1 and d2\nNew node created\n");
01332 #endif
01333
01334 PDNew = (Param_Domain *) malloc( sizeof(Param_Domain) );
01335 PDNew->F = (int *)malloc( nv*sizeof(int) );
01336 memset(PDNew->F,0,nv*sizeof(int));
01337 PDNew->Domain = dx;
01338
01339 for (i=0;i<nv;i++)
01340 PDNew->F[i] = p1->F[i] | p2->F[i];
01341
01342
01343 Domain_Free( p1->Domain );
01344 p1->Domain = d1;
01345
01346
01347 Domain_Free( p2->Domain );
01348 p2->Domain = d2;
01349
01350
01351 PDNew->next = p1->next;
01352 p1->next = PDNew;
01353 }
01354 }
01355 }
01356 }
01357 }
01358
01359
01360
01361
01362
01363
01364
01365 Param_Polyhedron *Polyhedron2Param_Vertices(Polyhedron *Din,Polyhedron *Cin,int working_space) {
01366
01367 Param_Polyhedron *result;
01368
01369 #ifdef DEBUGPP
01370 fprintf(stderr,"Polyhedron2Param_Vertices algorithm starting at : %.2fs\n",
01371 (float)clock()/CLOCKS_PER_SEC);
01372 #endif
01373
01374
01375 result = Find_m_faces(&Din,Cin,0,working_space,NULL,NULL);
01376
01377 #ifdef DEBUGPP
01378 fprintf(stderr, "nb of points : %d\n",result->nbV);
01379 #endif
01380
01381 #ifdef DEBUGPP
01382 fprintf(stderr, "end main loop : %.2fs\n", (float)clock()/CLOCKS_PER_SEC);
01383 #endif
01384
01385 return(result);
01386 }
01387
01388
01389
01390
01391 void Param_Vertices_Free(Param_Vertices *PV) {
01392
01393 Param_Vertices *next_pv;
01394
01395 while(PV) {
01396 next_pv = PV->next;
01397 if (PV->Vertex) Matrix_Free(PV->Vertex);
01398 if (PV->Domain) Matrix_Free(PV->Domain);
01399 free(PV);
01400 PV = next_pv;
01401 }
01402 }
01403
01404
01405
01406
01407 void Print_Vertex(FILE *DST,Matrix *V,char **param_names){
01408
01409 int l, v;
01410 int first;
01411 Value gcd,tmp;
01412
01413 value_init(gcd); value_init(tmp);
01414
01415 fprintf(DST, "[" );
01416 for(l=0;l<V->NbRows;++l){
01417
01418
01419 first=1;
01420 fprintf(DST, " " );
01421 for(v=0;v < V->NbColumns-2;++v) {
01422 if(value_notzero_p(V->p[l][v])) {
01423 Gcd(V->p[l][v],V->p[l][V->NbColumns-1],&gcd);
01424 value_absolute(gcd,gcd);
01425 value_division(tmp,V->p[l][v],gcd);
01426 if(value_posz_p(tmp)) {
01427 if(!first)
01428 fprintf(DST, "+");
01429 value_division(tmp,V->p[l][v],gcd);
01430 if(value_notone_p(tmp)) {
01431 value_print(DST,VALUE_FMT,tmp);
01432 }
01433 }
01434 else {
01435 value_division(tmp,V->p[l][v],gcd);
01436 if(value_mone_p(tmp))
01437 fprintf(DST, "-" );
01438 else {
01439 value_print(DST,VALUE_FMT,tmp);
01440 }
01441 }
01442 value_division(tmp,V->p[l][V->NbColumns-1],gcd);
01443 if(value_notone_p(tmp)) {
01444 fprintf(DST, "%s/", param_names[v]);
01445 value_print(DST,VALUE_FMT,tmp);
01446 }
01447 else
01448 fprintf(DST, "%s", param_names[v]);
01449 first=0;
01450 }
01451 }
01452
01453
01454 if(value_notzero_p(V->p[l][v]) || first) {
01455 if(value_posz_p(V->p[l][v]) && !first)
01456 fprintf(DST,"+");
01457 Gcd(V->p[l][v],V->p[l][V->NbColumns-1],&gcd);
01458 value_absolute(gcd,gcd);
01459 value_division(tmp,V->p[l][v],gcd);
01460 value_print(DST,VALUE_FMT,tmp);
01461 value_division(tmp,V->p[l][V->NbColumns-1],gcd);
01462 if(value_notone_p(tmp)) {
01463 fprintf(DST,"/");
01464 value_print(DST,VALUE_FMT,tmp);
01465 fprintf(DST," ");
01466 }
01467 }
01468 if (l<V->NbRows-1)
01469 fprintf(DST, ", ");
01470 }
01471 fprintf(DST, " ]");
01472 value_clear(gcd); value_clear(tmp);
01473 return;
01474 }
01475
01476
01477
01478
01479
01480 Matrix *VertexCT(Matrix *V,Matrix *CT) {
01481
01482 Matrix *Vt;
01483 int i,j,k;
01484
01485 if(CT) {
01486
01487
01488 Vt = Matrix_Alloc(V->NbRows,CT->NbColumns+1);
01489 for(i=0;i<V->NbRows;++i) {
01490 value_assign(Vt->p[i][CT->NbColumns],V->p[i][V->NbColumns-1]);
01491 for(j=0;j<CT->NbColumns;j++) {
01492 for(k=0;k<CT->NbRows;k++)
01493 if(value_notzero_p(CT->p[k][j]))
01494 break;
01495 if(k<CT->NbRows)
01496 value_assign(Vt->p[i][j],V->p[i][k]);
01497 else
01498 value_set_si(Vt->p[i][j],0);
01499 }
01500 }
01501 return(Vt);
01502 }
01503 else
01504 return(NULL);
01505 }
01506
01507
01508
01509
01510 void Print_Domain(FILE *DST,Polyhedron *D,char **pname) {
01511
01512 int l, v;
01513 int first;
01514
01515 for(l=0;l<D->NbConstraints;++l) {
01516 fprintf(DST, " ");
01517 first = 1;
01518 for(v=1;v<=D->Dimension;++v) {
01519 if(value_notzero_p(D->Constraint[l][v])) {
01520 if(value_one_p(D->Constraint[l][v])) {
01521 if(first)
01522 fprintf(DST, "%s ", pname[v-1]);
01523 else
01524 fprintf(DST, "+ %s ", pname[v-1] );
01525 }
01526 else if(value_mone_p(D->Constraint[l][v]))
01527 fprintf(DST, "- %s ", pname[v-1] );
01528 else {
01529 if(value_pos_p(D->Constraint[l][v]) && !first )
01530 fprintf(DST, "+ " );
01531 value_print(DST,VALUE_FMT,D->Constraint[l][v]);
01532 fprintf(DST,"%s ",pname[v-1]);
01533 }
01534 first = 0;
01535 }
01536 }
01537 if(value_notzero_p(D->Constraint[l][v])) {
01538 if(value_pos_p(D->Constraint[l][v]) && !first)
01539 fprintf(DST,"+");
01540 fprintf(DST," ");
01541 value_print(DST,VALUE_FMT,D->Constraint[l][v]);
01542 }
01543 fprintf(DST,(value_notzero_p(D->Constraint[l][0])) ?" >= 0":" = 0");
01544 fprintf(DST, "\n" );
01545 }
01546 fprintf(DST, "\n");
01547
01548 if( D->next )
01549 {
01550 fprintf( DST, "UNION\n" );
01551 Print_Domain( DST, D->next, pname );
01552 }
01553 return;
01554 }
01555
01556
01557
01558
01559
01560 void Param_Vertices_Print(FILE *DST,Param_Vertices *PV,char **param_names) {
01561
01562 Polyhedron *poly;
01563
01564 while(PV) {
01565 fprintf(DST, "Vertex :\n" );
01566 Print_Vertex(DST,PV->Vertex,param_names);
01567
01568
01569 fprintf(DST, " If :\n" );
01570 poly = Constraints2Polyhedron(PV->Domain,200);
01571 Print_Domain(DST,poly,param_names);
01572 Domain_Free(poly);
01573 PV = PV->next;
01574 }
01575 return;
01576 }
01577
01578
01579
01580
01581
01582
01583
01584
01585 Param_Polyhedron *Polyhedron2Param_Domain(Polyhedron *Din,Polyhedron *Cin,int working_space) {
01586
01587 Param_Polyhedron *result;
01588 Param_Domain *D;
01589
01590 #ifdef DEBUGPP
01591 fprintf(stderr,"Polyhedron2Param_Polyhedron algorithm starting at : %.2fs\n",
01592 (float)clock()/CLOCKS_PER_SEC);
01593 #endif
01594
01595
01596
01597 result = Find_m_faces(&Din,Cin,1,working_space,NULL,NULL);
01598
01599 #ifdef DEBUGPP
01600 if(result) fprintf(stderr, "Number of vertices : %d\n",result->nbV);
01601 fprintf(stderr,"Vertices found at : %.2fs\n",(float)clock()/CLOCKS_PER_SEC);
01602 #endif
01603
01604
01605 if(result && Cin->Dimension>0)
01606 Compute_PDomains(result->D,result->nbV,working_space);
01607 if(result && CEqualities)
01608 for(D=result->D;D;D=D->next)
01609 D->Domain = Add_CEqualities(D->Domain);
01610
01611 #ifdef DEBUGPP
01612 fprintf(stderr, "domains found at : %.2fs\n", (float)clock()/CLOCKS_PER_SEC);
01613 #endif
01614
01615 return(result);
01616 }
01617
01618
01619
01620
01621 Param_Polyhedron *Polyhedron2Param_SimplifiedDomain(Polyhedron **Din,Polyhedron *Cin,int working_space,Polyhedron **CEq,Matrix **CT) {
01622
01623 Param_Polyhedron *result;
01624
01625 #ifdef DEBUGPP
01626 fprintf(stderr,"Polyhedron2Param_Polyhedron algorithm starting at : %.2fs\n",
01627 (float)clock()/CLOCKS_PER_SEC);
01628 #endif
01629
01630
01631
01632 result = Find_m_faces(Din,Cin,1,working_space,CEq,CT);
01633
01634 #ifdef DEBUGPP
01635 if(result) fprintf(stderr, "Number of vertices : %d\n",result->nbV);
01636 fprintf(stderr,"Vertices found at : %.2fs\n",(float)clock()/CLOCKS_PER_SEC);
01637 #endif
01638
01639
01640 if(result && Cin->Dimension>0)
01641 Compute_PDomains(result->D,result->nbV,working_space);
01642
01643
01644
01645
01646
01647
01648
01649 #ifdef DEBUGPP
01650 fprintf(stderr, "domains found at : %.2fs\n", (float)clock()/CLOCKS_PER_SEC);
01651 #endif
01652
01653 return(result);
01654 }
01655
01656
01657
01658
01659
01660 void Param_Domain_Free(Param_Domain *PD) {
01661
01662 Param_Domain *next_pd;
01663
01664 while(PD) {
01665 free(PD->F);
01666 Domain_Free(PD->Domain);
01667 next_pd = PD->next;
01668 free(PD);
01669 PD = next_pd;
01670 }
01671 return;
01672 }
01673
01674
01675
01676
01677 void Param_Polyhedron_Free(Param_Polyhedron *P) {
01678
01679 if (!P) return;
01680 Param_Vertices_Free(P->V);
01681 Param_Domain_Free(P->D);
01682 free(P);
01683 return;
01684 }
01685
01686
01687
01688