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