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