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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #undef POLY_DEBUG
00038 #undef POLY_RR_DEBUG
00039 #undef POLY_CH_DEBUG
00040
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043 #include <string.h>
00044 #include <assert.h>
00045 #include <polylib/polylib.h>
00046
00047 #ifdef MAC_OS
00048 #define abs __abs
00049 #endif
00050
00051
00052 #define WSIZE (8*sizeof(int))
00053
00054 #define bexchange(a, b, l)\
00055 {\
00056 char *t = (char *)malloc(l*sizeof(char));\
00057 memcpy((t), (char *)(a), (int)(l));\
00058 memcpy((char *)(a), (char *)(b), (int)(l));\
00059 memcpy((char *)(b), (t), (int)(l));\
00060 free(t); \
00061 }
00062
00063 #define exchange(a, b, t)\
00064 { (t)=(a); (a)=(b); (b)=(t); }
00065
00066
00067
00068
00069
00070 void errormsg1(char *f , char *msgname, char *msg);
00071
00072 int Pol_status;
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 typedef struct {
00083 unsigned int NbRows;
00084 unsigned int NbColumns;
00085 int **p;
00086 int *p_init;
00087 } SatMatrix;
00088
00089
00090
00091
00092 static SatMatrix *SMAlloc(int rows,int cols) {
00093
00094 int **q, *p, i;
00095 SatMatrix *result;
00096
00097 result = (SatMatrix *) malloc (sizeof(SatMatrix));
00098 if(!result) {
00099 errormsg1("SMAlloc", "outofmem", "out of memory space");
00100 return 0;
00101 }
00102 result->NbRows = rows;
00103 result->NbColumns = cols;
00104 if(rows == 0 || cols == 0) {
00105 result->p = NULL;
00106 return result;
00107 }
00108 result->p = q = (int **)malloc(rows * sizeof(int *));
00109 if(!result->p) {
00110 errormsg1("SMAlloc", "outofmem", "out of memory space");
00111 return 0;
00112 }
00113 result->p_init = p = (int *)malloc (rows * cols * sizeof (int));
00114 if(!result->p_init) {
00115 errormsg1("SMAlloc", "outofmem", "out of memory space");
00116 return 0;
00117 }
00118 for (i=0; i<rows; i++) {
00119 *q++ = p;
00120 p += cols;
00121 }
00122 return result;
00123 }
00124
00125
00126
00127
00128 static void SMFree (SatMatrix **matrix) {
00129 SatMatrix *SM = *matrix;
00130
00131 if (SM) {
00132 if (SM->p) {
00133 free ((char *) SM->p_init);
00134 free ((char *) SM->p);
00135 }
00136 free ((char *) SM);
00137 *matrix = NULL;
00138 }
00139 }
00140
00141
00142
00143
00144
00145 static void SMPrint (SatMatrix *matrix) {
00146
00147 int *p;
00148 int i, j;
00149 unsigned NbRows, NbColumns;
00150
00151 fprintf(stderr,"%d %d\n",NbRows=matrix->NbRows, NbColumns=matrix->NbColumns);
00152 for (i=0;i<NbRows;i++) {
00153 p = *(matrix->p+i);
00154 for (j=0;j<NbColumns;j++)
00155 fprintf(stderr, " %10X ", *p++);
00156 fprintf(stderr, "\n");
00157 }
00158 }
00159
00160
00161
00162
00163 static void SatVector_OR(int *p1,int *p2,int *p3,unsigned length) {
00164
00165 int *cp1, *cp2, *cp3;
00166 int i;
00167
00168 cp1=p1;
00169 cp2=p2;
00170 cp3=p3;
00171 for (i=0;i<length;i++) {
00172 *cp3 = *cp1 | *cp2;
00173 cp3++;
00174 cp1++;
00175 cp2++;
00176 }
00177 }
00178
00179
00180
00181
00182 #define SMVector_Copy(p1, p2, length) \
00183 memcpy((char *)(p2), (char *)(p1), (int)((length)*sizeof(int)))
00184
00185
00186
00187
00188 #define SMVector_Init(p1, length) \
00189 memset((char *)(p1), 0, (int)((length)*sizeof(int)))
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 static void Combine(Value *p1, Value *p2, Value *p3, int pos, unsigned length) {
00202
00203 Value a1, a2, gcd;
00204 Value abs_a1,abs_a2,neg_a1;
00205
00206
00207 value_init(a1); value_init(a2); value_init(gcd);
00208 value_init(abs_a1); value_init(abs_a2); value_init(neg_a1);
00209
00210
00211 value_assign(a1,p1[pos]);
00212
00213
00214 value_assign(a2,p2[pos]);
00215
00216
00217 value_absolute(abs_a1,a1);
00218
00219
00220 value_absolute(abs_a2,a2);
00221
00222
00223 Gcd(abs_a1,abs_a2,&gcd);
00224
00225
00226 value_division (a1,a1,gcd);
00227
00228
00229 value_division (a2,a2,gcd);
00230
00231
00232 value_oppose(neg_a1,a1);
00233
00234 Vector_Combine(p1+1,p2+1,p3+1,a2,neg_a1,length);
00235 Vector_Normalize(p3+1,length);
00236
00237
00238 value_clear(a1); value_clear(a2); value_clear(gcd);
00239 value_clear(abs_a1); value_clear(abs_a2); value_clear(neg_a1);
00240
00241 return;
00242 }
00243
00244
00245
00246
00247
00248
00249 static SatMatrix *TransformSat(Matrix *Mat, Matrix *Ray, SatMatrix *Sat) {
00250
00251 int i, j, sat_nbcolumns;
00252 unsigned jx1, jx2, bx1, bx2;
00253 SatMatrix *result;
00254
00255 if (Mat->NbRows != 0)
00256 sat_nbcolumns = (Mat->NbRows-1) /(sizeof(int)*8) + 1;
00257 else
00258 sat_nbcolumns = 0;
00259
00260 result = SMAlloc(Ray->NbRows, sat_nbcolumns);
00261 SMVector_Init(result->p_init, Ray->NbRows * sat_nbcolumns);
00262
00263 for(i=0,jx1=0,bx1=MSB; i<Ray->NbRows; i++) {
00264 for(j=0,jx2=0,bx2=MSB; j<Mat->NbRows; j++) {
00265 if (Sat->p[j][jx1] & bx1)
00266 result->p[i][jx2] |= bx2;
00267 NEXT(jx2,bx2);
00268 }
00269 NEXT(jx1, bx1);
00270 }
00271 return result;
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 static void RaySort(Matrix *Ray,SatMatrix *Sat,int NbBid,int NbRay,int *equal_bound,int *sup_bound,unsigned RowSize1, unsigned RowSize2, unsigned bx, unsigned jx) {
00289
00290 int inf_bound;
00291 Value **uni_eq, **uni_sup, **uni_inf;
00292 int **inc_eq, **inc_sup, **inc_inf;
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 *sup_bound = *equal_bound = NbBid;
00304 uni_sup = uni_eq = Ray->p+NbBid;
00305 inc_sup = inc_eq = Sat->p+NbBid;
00306 inf_bound = NbRay;
00307 uni_inf = Ray->p+NbRay;
00308 inc_inf = Sat->p+NbRay;
00309
00310 while (inf_bound>*sup_bound) {
00311 if (value_zero_p(**uni_sup)) {
00312 if (inc_eq != inc_sup) {
00313 Vector_Exchange(*uni_eq,*uni_sup,RowSize1);
00314 bexchange(*inc_eq,*inc_sup,RowSize2);
00315 }
00316 (*equal_bound)++; uni_eq++; inc_eq++;
00317 (*sup_bound)++; uni_sup++; inc_sup++;
00318 }
00319 else {
00320 *((*inc_sup)+jx)|=bx;
00321
00322
00323 if (value_neg_p(**uni_sup)) {
00324 inf_bound--; uni_inf--; inc_inf--;
00325 if (inc_inf != inc_sup) {
00326 Vector_Exchange(*uni_inf,*uni_sup,RowSize1);
00327 bexchange(*inc_inf,*inc_sup,RowSize2);
00328 }
00329 }
00330 else {
00331 (*sup_bound)++; uni_sup++; inc_sup++;
00332 }
00333 }
00334 }
00335 }
00336
00337 static void SatMatrix_Extend(SatMatrix *Sat, Matrix* Mat, unsigned rows)
00338 {
00339 int i;
00340 unsigned cols;
00341 cols = (Mat->NbRows - 1)/(sizeof(int)*8) + 1;
00342
00343 Sat->p = (int **)realloc(Sat->p, rows * sizeof(int *));
00344 if(!Sat->p) {
00345 errormsg1("SatMatrix_Extend", "outofmem", "out of memory space");
00346 return;
00347 }
00348 Sat->p_init = (int *)realloc(Sat->p_init, rows * cols * sizeof (int));
00349 if(!Sat->p_init) {
00350 errormsg1("SatMatrix_Extend", "outofmem", "out of memory space");
00351 return;
00352 }
00353 for (i = 0; i < rows; ++i)
00354 Sat->p[i] = Sat->p_init + (i * cols);
00355 Sat->NbRows = rows;
00356 }
00357
00358 static void Matrix_Extend(Matrix *Mat, unsigned NbRows)
00359 {
00360 Value *p, **q;
00361 int i,j;
00362
00363 q = (Value **)realloc(Mat->p, NbRows * sizeof(*q));
00364 if(!q) {
00365 errormsg1("Matrix_Extend", "outofmem", "out of memory space");
00366 return;
00367 }
00368 Mat->p = q;
00369 if (Mat->p_Init_size < NbRows * Mat->NbColumns) {
00370 p = (Value *)realloc(Mat->p_Init, NbRows * Mat->NbColumns * sizeof(Value));
00371 if(!p) {
00372 errormsg1("Matrix_Extend", "outofmem", "out of memory space");
00373 return;
00374 }
00375 Mat->p_Init = p;
00376 Vector_Set(Mat->p_Init + Mat->NbRows*Mat->NbColumns, 0,
00377 Mat->p_Init_size - Mat->NbRows*Mat->NbColumns);
00378 for (i = Mat->p_Init_size; i < Mat->NbColumns*NbRows; ++i)
00379 value_init(Mat->p_Init[i]);
00380 Mat->p_Init_size = Mat->NbColumns*NbRows;
00381 } else
00382 Vector_Set(Mat->p_Init + Mat->NbRows*Mat->NbColumns, 0,
00383 (NbRows - Mat->NbRows) * Mat->NbColumns);
00384 for (i=0;i<NbRows;i++) {
00385 Mat->p[i] = Mat->p_Init + (i * Mat->NbColumns);
00386 }
00387 Mat->NbRows = NbRows;
00388 }
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 static int Chernikova (Matrix *Mat,Matrix *Ray,SatMatrix *Sat, unsigned NbBid, unsigned NbMaxRays, unsigned FirstConstraint,unsigned dual) {
00402
00403 unsigned NbRay, Dimension, NbConstraints, RowSize1, RowSize2, sat_nbcolumns;
00404 int sup_bound, equal_bound, index_non_zero, bound;
00405 int i, j, k, l, redundant, rayonly, nbcommonconstraints;
00406 int *Temp, aux;
00407 int *ip1, *ip2;
00408 unsigned bx, m, jx;
00409 Value *p1, *p2, *p3;
00410
00411 #ifdef POLY_CH_DEBUG
00412 fprintf(stderr, "[Chernikova: Input]\nRay = ");
00413 Matrix_Print(stderr,0,Ray);
00414 fprintf(stderr, "\nConstraints = ");
00415 Matrix_Print(stderr,0,Mat);
00416 fprintf(stderr, "\nSat = ");
00417 SMPrint(Sat);
00418 #endif
00419
00420 NbConstraints=Mat->NbRows;
00421 NbRay = Ray->NbRows;
00422 Dimension = Mat->NbColumns-1;
00423 sat_nbcolumns=Sat->NbColumns;
00424
00425 RowSize1=(Dimension+1);
00426 RowSize2=sat_nbcolumns * sizeof(int);
00427
00428 Temp=(int *)malloc(RowSize2);
00429 if(!Temp) {
00430 errormsg1("Chernikova", "outofmem", "out of memory space");
00431 return 0;
00432 }
00433 CATCH(any_exception_error) {
00434
00435
00436
00437
00438
00439 free(Temp);
00440 RETHROW();
00441 }
00442 TRY {
00443 jx = FirstConstraint/WSIZE;
00444 bx = MSB; bx >>= FirstConstraint%WSIZE;
00445 for (k=FirstConstraint; k<NbConstraints; k++) {
00446
00447
00448
00449
00450
00451
00452 index_non_zero = NbRay;
00453 for (i=0; i<NbRay; i++) {
00454 p1 = Ray->p[i]+1;
00455 p2 = Mat->p[k]+1;
00456 p3 = Ray->p[i];
00457
00458
00459 value_multiply(*p3,*p1,*p2);
00460 p1++; p2++;
00461 for (j=1; j<Dimension; j++) {
00462
00463
00464 value_addmul(*p3, *p1, *p2);
00465 p1++; p2++;
00466 }
00467 if (value_notzero_p(*p3) && (i<index_non_zero))
00468 index_non_zero=i;
00469 }
00470
00471 #ifdef POLY_CH_DEBUG
00472 fprintf(stderr, "[Chernikova: A]\nRay = ");
00473 Matrix_Print(stderr,0,Ray);
00474 fprintf(stderr, "\nConstraints = ");
00475 Matrix_Print(stderr,0,Mat);
00476 fprintf(stderr, "\nSat = ");
00477 SMPrint (Sat);
00478 #endif
00479
00480
00481 if (index_non_zero<NbBid) {
00482
00483
00484 NbBid--;
00485 if (NbBid!=index_non_zero)
00486 Vector_Exchange(Ray->p[index_non_zero],Ray->p[NbBid],RowSize1);
00487
00488 #ifdef POLY_CH_DEBUG
00489 fprintf(stderr,"************\n");
00490 for(i=0;i<RowSize1;i++) {
00491 value_print(stderr,P_VALUE_FMT,Ray->p[index_non_zero][i]);
00492 }
00493 fprintf(stderr,"\n******\n");
00494 for(i=0;i<RowSize1;i++) {
00495 value_print(stderr,P_VALUE_FMT,Ray->p[NbBid][i]);
00496 }
00497 fprintf(stderr,"\n*******\n");
00498 #endif
00499
00500
00501 for (i=0; i<NbBid; i++)
00502 if (value_notzero_p(Ray->p[i][0]))
00503 Combine(Ray->p[i],Ray->p[NbBid],Ray->p[i],0,Dimension);
00504
00505
00506
00507
00508 if (value_neg_p(Ray->p[NbBid][0])) {
00509 p1=Ray->p[NbBid];
00510 for (j=0;j<Dimension+1; j++) {
00511
00512
00513 value_oppose(*p1,*p1);
00514 p1++;
00515 }
00516 }
00517
00518 #ifdef POLY_CH_DEBUG
00519 fprintf(stderr, "[Chernikova: B]\nRay = ");
00520 Ray->NbRows=NbRay;
00521 Matrix_Print(stderr,0,Ray);
00522 fprintf(stderr, "\nConstraints = ");
00523 Matrix_Print(stderr,0,Mat);
00524 fprintf(stderr, "\nSat = ");
00525 SMPrint(Sat);
00526 #endif
00527
00528
00529 for (i=NbBid+1; i<NbRay; i++)
00530 if (value_notzero_p(Ray->p[i][0]))
00531 Combine(Ray->p[i],Ray->p[NbBid],Ray->p[i],0,Dimension);
00532
00533
00534 if (value_notzero_p(Mat->p[k][0])) {
00535 for (j=0;j<sat_nbcolumns;j++) {
00536 Sat->p[NbBid][j] = 0;
00537 }
00538
00539 Sat->p[NbBid][jx] |= bx;
00540 }
00541 else {
00542 if (--NbRay != NbBid) {
00543 Vector_Copy(Ray->p[NbRay],Ray->p[NbBid],Dimension+1);
00544 SMVector_Copy(Sat->p[NbRay],Sat->p[NbBid],sat_nbcolumns);
00545 }
00546 }
00547
00548 #ifdef POLY_CH_DEBUG
00549 fprintf(stderr, "[Chernikova: C]\nRay = ");
00550 Ray->NbRows=NbRay;
00551 Matrix_Print(stderr,0,Ray);
00552 fprintf(stderr, "\nConstraints = ");
00553 Matrix_Print(stderr,0,Mat);
00554 fprintf(stderr, "\nSat = ");
00555 SMPrint (Sat);
00556 #endif
00557
00558 }
00559 else {
00560 RaySort(Ray, Sat, NbBid, NbRay, &equal_bound, &sup_bound,
00561 RowSize1, RowSize2,bx,jx);
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 #ifdef POLY_CH_DEBUG
00575 fprintf(stderr, "[Chernikova: D]\nRay = ");
00576 Ray->NbRows=NbRay;
00577 Matrix_Print(stderr,0,Ray);
00578 fprintf(stderr, "\nConstraints = ");
00579 Matrix_Print(stderr,0,Mat);
00580 fprintf(stderr, "\nSat = ");
00581 SMPrint (Sat);
00582 #endif
00583
00584
00585 bound=NbRay;
00586 for (i=equal_bound; i<sup_bound; i++)
00587 for(j=sup_bound; j<bound; j++) {
00588
00589
00590
00591
00592
00593
00594 nbcommonconstraints = 0;
00595 for (l=0; l<jx; l++) {
00596 aux = Temp[l] = Sat->p[i][l] | Sat->p[j][l];
00597 for (m=MSB; m!=0; m>>=1)
00598 if (!(aux&m))
00599 nbcommonconstraints++;
00600 }
00601 aux = Temp[jx] = Sat->p[i][jx] | Sat->p[j][jx];
00602 for (m=MSB; m!=bx; m>>=1)
00603 if (!(aux&m))
00604 nbcommonconstraints++;
00605 rayonly = (value_zero_p(Ray->p[i][Dimension]) &&
00606 value_zero_p(Ray->p[j][Dimension]) &&
00607 (dual == 0));
00608 if(rayonly)
00609 nbcommonconstraints++;
00610
00611
00612
00613
00614
00615 if (nbcommonconstraints+NbBid>=Dimension-2) {
00616
00617 redundant=0;
00618 for (m=NbBid; m<bound; m++)
00619 if ((m!=i)&&(m!=j)) {
00620
00621
00622
00623
00624
00625 if (rayonly && value_notzero_p(Ray->p[m][Dimension]))
00626 continue;
00627
00628
00629
00630
00631 ip1 = Temp;
00632 ip2 = Sat->p[m];
00633 for (l=0; l<=jx; l++,ip2++,ip1++)
00634 if (*ip2 & ~*ip1)
00635 break;
00636 if (l>jx) {
00637 redundant=1;
00638 break;
00639 }
00640 }
00641
00642 #ifdef POLY_CH_DEBUG
00643 fprintf(stderr, "[Chernikova: E]\nRay = ");
00644 Ray->NbRows=NbRay;
00645 Matrix_Print(stderr,0,Ray);
00646 fprintf(stderr, "\nConstraints = ");
00647 Matrix_Print(stderr,0,Mat);
00648 fprintf(stderr, "\nSat = ");
00649 SMPrint (Sat);
00650 #endif
00651
00652
00653
00654
00655
00656 if (!redundant) {
00657 if (NbRay==NbMaxRays) {
00658 NbMaxRays *= 2;
00659 Ray->NbRows = NbRay;
00660 Matrix_Extend(Ray, NbMaxRays);
00661 SatMatrix_Extend(Sat, Mat, NbMaxRays);
00662 }
00663
00664
00665 Combine(Ray->p[j],Ray->p[i],Ray->p[NbRay],0,Dimension);
00666 SatVector_OR(Sat->p[j],Sat->p[i],Sat->p[NbRay],sat_nbcolumns);
00667 Sat->p[NbRay][jx] &= ~bx;
00668 NbRay++;
00669 }
00670 }
00671 }
00672
00673 #ifdef POLY_CH_DEBUG
00674 fprintf(stderr,
00675 "[Chernikova: F]\n"
00676 "sup_bound=%d\n"
00677 "equal_bound=%d\n"
00678 "bound=%d\n"
00679 "NbRay=%d\n"
00680 "Dimension = %d\n"
00681 "Ray = ",sup_bound,equal_bound,bound,NbRay,Dimension);
00682 #endif
00683 #ifdef POLY_CH_DEBUG
00684 Ray->NbRows=NbRay;
00685 fprintf(stderr, "[Chernikova: F]:\nRay = ");
00686 Matrix_Print(stderr,0,Ray);
00687 #endif
00688
00689
00690
00691
00692 j = (value_notzero_p(Mat->p[k][0])) ?
00693 sup_bound : equal_bound;
00694
00695 i = NbRay;
00696 #ifdef POLY_CH_DEBUG
00697 fprintf(stderr, "i = %d\nj = %d \n", i, j);
00698 #endif
00699 while ((j<bound)&&(i>bound)) {
00700 i--;
00701 Vector_Copy(Ray->p[i],Ray->p[j],Dimension+1);
00702 SMVector_Copy(Sat->p[i],Sat->p[j],sat_nbcolumns);
00703 j++;
00704 }
00705
00706 #ifdef POLY_CH_DEBUG
00707 fprintf(stderr, "i = %d\nj = %d \n", i, j);
00708 fprintf(stderr,
00709 "[Chernikova: F]\n"
00710 "sup_bound=%d\n"
00711 "equal_bound=%d\n"
00712 "bound=%d\n"
00713 "NbRay=%d\n"
00714 "Dimension = %d\n"
00715 "Ray = ",sup_bound,equal_bound,bound,NbRay, Dimension);
00716 #endif
00717 #ifdef POLY_CH_DEBUG
00718 Ray->NbRows=NbRay;
00719 fprintf(stderr, "[Chernikova: G]\nRay = ");
00720 Matrix_Print(stderr,0,Ray);
00721 #endif
00722 if (j==bound)
00723 NbRay=i;
00724 else
00725 NbRay=j;
00726 }
00727 NEXT(jx,bx);
00728 }
00729 Ray->NbRows=NbRay;
00730 Sat->NbRows=NbRay;
00731
00732 }
00733
00734 UNCATCH(any_exception_error);
00735 free(Temp);
00736
00737 #ifdef POLY_CH_DEBUG
00738 fprintf(stderr, "[Chernikova: Output]\nRay = ");
00739 Matrix_Print(stderr,0,Ray);
00740 fprintf(stderr, "\nConstraints = ");
00741 Matrix_Print(stderr,0,Mat);
00742 fprintf(stderr, "\nSat = ");
00743 SMPrint (Sat);
00744 #endif
00745
00746 return 0;
00747 }
00748
00749 static int Gauss4(Value **p, int NbEq, int NbRows, int Dimension)
00750 {
00751 int i, j, k, pivot, Rank;
00752 int *column_index = NULL;
00753 Value gcd, *cp;
00754
00755 value_init(gcd);
00756 column_index=(int *)malloc(Dimension * sizeof(int));
00757 if(!column_index) {
00758 errormsg1("Gauss","outofmem","out of memory space");
00759 value_clear(gcd);
00760 return 0;
00761 }
00762 Rank=0;
00763
00764 CATCH(any_exception_error) {
00765 if (column_index)
00766 free(column_index);
00767 value_clear(gcd);
00768 RETHROW();
00769 }
00770 TRY {
00771
00772 for (j=1; j<=Dimension; j++) {
00773 for (i=Rank; i<NbEq; i++)
00774
00775
00776 if (value_notzero_p(p[i][j]))
00777 break;
00778 if (i!=NbEq) {
00779 if (i!=Rank)
00780 Vector_Exchange(p[Rank]+1,p[i]+1,Dimension);
00781
00782
00783
00784 Vector_Gcd(p[Rank]+1,Dimension,&gcd);
00785
00786
00787 if (value_cmp_si(gcd, 2) >= 0) {
00788 cp = &p[Rank][1];
00789 for (k=0; k<Dimension; k++) {
00790 value_division (*cp,*cp,gcd);
00791 cp++;
00792 }
00793 }
00794
00795
00796 if (value_neg_p(p[Rank][j])) {
00797 cp = p[Rank]+1;
00798 for (k=0; k<Dimension; k++) {
00799 value_oppose(*cp, *cp);
00800 cp++;
00801 }
00802 }
00803
00804
00805 pivot=i;
00806 for (i=pivot+1; i<NbEq; i++) {
00807
00808
00809 if (value_notzero_p(p[i][j]))
00810 Combine(p[i],p[Rank],p[i],j,Dimension);
00811 }
00812
00813
00814
00815
00816
00817 column_index[Rank]=j;
00818 Rank++;
00819 }
00820 }
00821
00822
00823 for (k=Rank-1; k>=0; k--) {
00824 j = column_index[k];
00825
00826
00827 for (i=0; i<k; i++) {
00828
00829
00830 if (value_notzero_p(p[i][j]))
00831 Combine(p[i],p[k],p[i],j,Dimension);
00832 }
00833
00834
00835 for (i=NbEq;i<NbRows;i++) {
00836
00837
00838 if (value_notzero_p(p[i][j]))
00839 Combine(p[i],p[k],p[i],j,Dimension);
00840 }
00841 }
00842 }
00843
00844 UNCATCH(any_exception_error);
00845 free(column_index), column_index = NULL;
00846
00847 value_clear(gcd);
00848 return Rank;
00849 }
00850
00851
00852
00853
00854
00855
00856
00857 int Gauss(Matrix *Mat, int NbEq, int Dimension)
00858 {
00859 int Rank;
00860
00861 #ifdef POLY_DEBUG
00862 fprintf(stderr, "[Gauss : Input]\nRay =");
00863 Matrix_Print(stderr,0,Mat);
00864 #endif
00865
00866 Rank = Gauss4(Mat->p, NbEq, Mat->NbRows, Dimension);
00867
00868 #ifdef POLY_DEBUG
00869 fprintf(stderr, "[Gauss : Output]\nRay =");
00870 Matrix_Print(stderr,0,Mat);
00871 #endif
00872
00873 return Rank;
00874 }
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887 static Polyhedron *Remove_Redundants(Matrix *Mat,Matrix *Ray,SatMatrix *Sat,unsigned *Filter) {
00888
00889 int i, j, k;
00890 unsigned Dimension, sat_nbcolumns, NbRay, NbConstraints, RowSize1, RowSize2,
00891 *Trace = NULL, *bx = NULL, *jx = NULL, Dim_RaySpace, b;
00892 unsigned NbBid, NbUni, NbEq, NbIneq;
00893 unsigned NbBid2, NbUni2, NbEq2, NbIneq2;
00894 int Redundant;
00895 int aux, *temp2 = NULL;
00896 Polyhedron *Pol = NULL;
00897 Value *temp1 = NULL;
00898 Value *p, *q;
00899 Value Status,tmp1,tmp2,tmp3;
00900
00901 Dimension = Mat->NbColumns-1;
00902 NbRay = Ray->NbRows;
00903 sat_nbcolumns = Sat->NbColumns;
00904 NbConstraints = Mat->NbRows;
00905 RowSize1=(Dimension+1);
00906 RowSize2=sat_nbcolumns * sizeof(int);
00907
00908 temp1=(Value *)malloc(RowSize1*sizeof(Value));
00909 if(!temp1) {
00910 errormsg1("Remove_Redundants", "outofmem", "out of memory space");
00911 return 0;
00912 }
00913
00914
00915 value_init(Status); value_init(tmp1);
00916 value_init(tmp2); value_init(tmp3);
00917
00918 for(i=0;i<RowSize1;i++)
00919 value_init(temp1[i]);
00920
00921 temp2=(int *)malloc(RowSize2);
00922 if(!temp2) {
00923 errormsg1("Remove_Redundants", "outofmem", "out of memory space");
00924
00925
00926 value_clear(Status); value_clear(tmp1);
00927 value_clear(tmp2); value_clear(tmp3);
00928 for(i=0;i<RowSize1;i++)
00929 value_clear(temp1[i]);
00930 free(temp1);
00931 return 0;
00932 }
00933
00934
00935
00936 bx = (unsigned *)malloc(NbConstraints * sizeof(unsigned));
00937 if(!bx) {
00938 errormsg1("Remove_Redundants", "outofmem", "out of memory space");
00939
00940
00941 value_clear(Status); value_clear(tmp1);
00942 value_clear(tmp2); value_clear(tmp3);
00943 for(i=0;i<RowSize1;i++)
00944 value_clear(temp1[i]);
00945 free(temp1); free(temp2);
00946 return 0;
00947 }
00948 jx = (unsigned *)malloc(NbConstraints * sizeof(unsigned));
00949 if(!jx) {
00950 errormsg1("Remove_Redundants", "outofmem", "out of memory space");
00951
00952
00953 value_clear(Status); value_clear(tmp1);
00954 value_clear(tmp2); value_clear(tmp3);
00955 for(i=0;i<RowSize1;i++)
00956 value_clear(temp1[i]);
00957 free(temp1); free(temp2); free(bx);
00958 return 0;
00959 }
00960 CATCH(any_exception_error) {
00961
00962 if (temp1) {
00963 for(i=0;i<RowSize1;i++)
00964 value_clear(temp1[i]);
00965 free(temp1);
00966 }
00967 if (temp2) free(temp2);
00968 if (bx) free(bx);
00969 if (jx) free(jx);
00970 if (Trace) free(Trace);
00971 if (Pol) Polyhedron_Free(Pol);
00972
00973
00974 value_clear(Status); value_clear(tmp1);
00975 value_clear(tmp2); value_clear(tmp3);
00976
00977 RETHROW();
00978 }
00979 TRY {
00980
00981
00982
00983
00984
00985
00986 i = 0;
00987 b = MSB;
00988 for (j=0; j<NbConstraints; j++) {
00989 jx[j] = i;
00990 bx[j] = b;
00991 NEXT(i,b);
00992 }
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002 aux = 0;
01003 for (i=0; i<NbRay; i++) {
01004
01005
01006 value_set_si(Ray->p[i][0],0);
01007
01008
01009 if (value_notzero_p(Ray->p[i][Dimension]))
01010 aux++;
01011 }
01012
01013
01014 if (!aux) {
01015
01016
01017 value_clear(Status); value_clear(tmp1);
01018 value_clear(tmp2); value_clear(tmp3);
01019 for(i=0;i<RowSize1;i++)
01020 value_clear(temp1[i]);
01021
01022
01023 free(temp1); free(temp2); free(jx); free(bx);
01024 UNCATCH(any_exception_error);
01025 return Empty_Polyhedron(Dimension-1);
01026 }
01027
01028 #ifdef POLY_RR_DEBUG
01029 fprintf(stderr, "[Remove_redundants : Init]\nConstraints =");
01030 Matrix_Print(stderr,0,Mat);
01031 fprintf(stderr, "\nRays =");
01032 Matrix_Print(stderr,0,Ray);
01033 #endif
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044 NbEq=0;
01045 #ifdef JUNK
01046
01047
01048 memset((char *)temp2, 0, RowSize2);
01049 #endif
01050
01051 #ifdef POLY_RR_DEBUG
01052 fprintf (stderr, " j = ");
01053 #endif
01054
01055 for (j=0; j<NbConstraints; j++) {
01056
01057 #ifdef POLY_RR_DEBUG
01058 fprintf (stderr, " %i ", j);
01059 fflush (stderr);
01060 #endif
01061
01062 #ifdef JUNK
01063
01064 if (Filter && value_zero_p(Mat->p[j][0]))
01065 temp2[jx[j]] |= bx[j];
01066 #endif
01067
01068 value_set_si(Mat->p[j][0],0);
01069
01070
01071 for (i=1, p = &Mat->p[j][1]; i<Dimension; i++) {
01072
01073
01074 if (value_notzero_p(*p)) {
01075 p++;
01076 break;
01077 }
01078 else
01079 p++;
01080 }
01081
01082 #ifdef POLY_RR_DEBUG
01083 fprintf(stderr, "[Remove_redundants : IntoStep1]\nConstraints =");
01084 Matrix_Print(stderr,0,Mat);
01085 fprintf (stderr, " j = %i \n", j);
01086 #endif
01087
01088
01089
01090
01091
01092 if (i==Dimension) {
01093 for (i=0; i<NbRay; i++)
01094 if (!(Sat->p[i][jx[j]]&bx[j])) {
01095
01096
01097 value_increment(Mat->p[j][0],Mat->p[j][0]);
01098 }
01099
01100
01101
01102 value_set_si(tmp1,NbRay);
01103 if ((value_eq(Mat->p[j][0],tmp1)) &&
01104 (value_notzero_p(Mat->p[j][Dimension]))) {
01105
01106
01107 value_clear(Status); value_clear(tmp1);
01108 value_clear(tmp2); value_clear(tmp3);
01109 for(i=0;i<RowSize1;i++)
01110 value_clear(temp1[i]);
01111
01112
01113 free(temp1); free(temp2); free(jx); free(bx);
01114 UNCATCH(any_exception_error);
01115 return Empty_Polyhedron(Dimension-1);
01116 }
01117
01118
01119 NbConstraints--;
01120 if (j==NbConstraints) continue;
01121 Vector_Exchange(Mat->p[j], Mat->p[NbConstraints],RowSize1);
01122 exchange(jx[j], jx[NbConstraints], aux);
01123 exchange(bx[j], bx[NbConstraints], aux);
01124 j--; continue;
01125 }
01126
01127
01128
01129 for (i=0; i<NbRay; i++)
01130 if (!(Sat->p[i][jx[j]]&bx[j])) {
01131
01132
01133 value_increment(Mat->p[j][0],Mat->p[j][0]);
01134
01135
01136 value_increment (Ray->p[i][0],Ray->p[i][0]);
01137 }
01138
01139
01140 value_set_si(tmp1,NbRay);
01141 if (value_eq(Mat->p[j][0],tmp1))
01142 NbEq++;
01143 }
01144 Mat->NbRows = NbConstraints;
01145
01146 NbBid=0;
01147 for (i=0; i<NbRay; i++) {
01148
01149
01150 if (value_zero_p(Ray->p[i][Dimension]))
01151
01152
01153 value_increment(Ray->p[i][0],Ray->p[i][0]);
01154
01155
01156
01157
01158
01159
01160 value_set_si(tmp1,(NbConstraints+1));
01161 if (value_eq(Ray->p[i][0],tmp1))
01162 NbBid++;
01163 }
01164
01165 #ifdef POLY_RR_DEBUG
01166 fprintf(stderr, "[Remove_redundants : Step1]\nConstraints =");
01167 Matrix_Print(stderr,0,Mat);
01168 fprintf(stderr, "\nRay =");
01169 Matrix_Print(stderr,0,Ray);
01170 #endif
01171
01172
01173
01174
01175
01176
01177
01178
01179 for (i=0; i<NbEq; i++) {
01180
01181
01182 value_set_si(tmp1,NbRay);
01183 if (value_ne(Mat->p[i][0],tmp1)) {
01184
01185 value_set_si(tmp1,NbRay);
01186
01187 for (k=i+1;value_ne(Mat->p[k][0],tmp1) && k<NbConstraints;k++);
01188 if (k==NbConstraints) break;
01189
01190
01191
01192 Vector_Copy(Mat->p[k], temp1,RowSize1);
01193 aux = jx[k];
01194 j = bx[k];
01195 for (;k>i;k--) {
01196 Vector_Copy(Mat->p[k-1],Mat->p[k],RowSize1);
01197 jx[k] = jx[k-1];
01198 bx[k] = bx[k-1];
01199 }
01200 Vector_Copy(temp1,Mat->p[i],RowSize1);
01201 jx[i] = aux;
01202 bx[i] = j;
01203 }
01204 }
01205
01206 #ifdef JUNK
01207 if (Filter)
01208 for (i=0; i<NbEq; i++) {
01209
01210
01211 Redundant = 0;
01212 for (j=i+1; j<NbEq; j++) {
01213 for (k=0, p=&Mat->p[i][1], q=&Mat->p[j][1]; k<Dimension; k++,p++,q++) {
01214
01215 if (value_ne(*p, *q))
01216 break;
01217 }
01218
01219
01220
01221 if (k==Dimension && (temp2[jx[j]] & bx[j])) {
01222 Redundant=1;
01223 break;
01224 }
01225 }
01226
01227
01228 if (!Redundant) Filter[jx[i]] |= bx[i];
01229 }
01230
01231 #endif
01232 #ifdef POLY_RR_DEBUG
01233 fprintf(stderr, "[Remove_redundants : Step2]\nConstraints =");
01234 Matrix_Print(stderr,0,Mat);
01235 fprintf(stderr, "\nRay =");
01236 Matrix_Print(stderr,0,Ray);
01237 #endif
01238
01239
01240
01241
01242
01243
01244
01245
01246 NbEq2 = Gauss(Mat,NbEq,Dimension);
01247
01248
01249
01250
01251 if (NbEq2>=Dimension) {
01252
01253
01254 value_clear(Status); value_clear(tmp1);
01255 value_clear(tmp2); value_clear(tmp3);
01256 for(i=0;i<RowSize1;i++)
01257 value_clear(temp1[i]);
01258
01259 free(temp1); free(temp2); free(jx); free(bx);
01260 UNCATCH(any_exception_error);
01261 return Empty_Polyhedron(Dimension-1);
01262 }
01263
01264 #ifdef POLY_RR_DEBUG
01265 fprintf(stderr, "[Remove_redundants : Step3]\nConstraints =");
01266 Matrix_Print(stderr,0,Mat);
01267 fprintf(stderr, "\nRay =");
01268 Matrix_Print(stderr,0,Ray);
01269 #endif
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279 for (i=0, k=NbRay; i<NbBid && k>i; i++) {
01280 value_set_si(tmp1,(NbConstraints+1));
01281
01282
01283 if (value_ne(Ray->p[i][0],tmp1)) {
01284
01285 value_set_si(tmp1,(NbConstraints+1));
01286
01287 while (--k >i && value_ne(Ray->p[k][0],tmp1)) ;
01288
01289
01290
01291 Vector_Exchange(Ray->p[i], Ray->p[k], RowSize1);
01292 bexchange(Sat->p[i], Sat->p[k], RowSize2);
01293 }
01294 }
01295
01296 #ifdef POLY_RR_DEBUG
01297 fprintf(stderr, "[Remove_redundants : Step4]\nConstraints =");
01298 Matrix_Print(stderr,0,Mat);
01299 fprintf(stderr, "\nRay =");
01300 Matrix_Print(stderr,0,Ray);
01301 #endif
01302
01303
01304
01305
01306
01307
01308
01309
01310 NbBid2 = Gauss(Ray, NbBid, Dimension);
01311
01312 #ifdef POLY_RR_DEBUG
01313 fprintf(stderr, "[Remove_redundants : After Gauss]\nRay =");
01314 Matrix_Print(stderr,0,Ray);
01315 #endif
01316
01317
01318
01319 if (NbBid2>=Dimension) {
01320 errormsg1("RemoveRedundants", "rmrdt", "dimension error");
01321
01322
01323 value_clear(Status); value_clear(tmp1);
01324 value_clear(tmp2); value_clear(tmp3);
01325 for(i=0;i<RowSize1;i++)
01326 value_clear(temp1[i]);
01327
01328 free(temp1); free(temp2); free(jx); free(bx);
01329 UNCATCH(any_exception_error);
01330 return Empty_Polyhedron(Dimension-1);
01331 }
01332
01333
01334 Dim_RaySpace = Dimension-1-NbEq2-NbBid2;
01335
01336 #ifdef POLY_RR_DEBUG
01337 fprintf(stderr, "[Remove_redundants : Step5]\nConstraints =");
01338 Matrix_Print(stderr,0,Mat);
01339 fprintf(stderr, "\nRay =");
01340 Matrix_Print(stderr,0,Ray);
01341 #endif
01342
01343
01344
01345
01346
01347
01348
01349
01350 value_set_si(tmp2,Dim_RaySpace);
01351 value_set_si(tmp3,NbRay);
01352 NbIneq=0;
01353 for (j=0; j<NbConstraints; j++) {
01354
01355
01356 for (i=1, p = &Mat->p[j][1]; i<Dimension; i++)
01357 if (value_notzero_p (*p)) {
01358 p++;
01359 break;
01360 }
01361 else
01362 p++;
01363
01364
01365
01366 if (i==Dimension) {
01367
01368 value_set_si(tmp1,NbRay);
01369
01370
01371
01372 if ((value_eq (Mat->p[j][0],tmp1)) &&
01373 (value_notzero_p(Mat->p[j][Dimension]))) {
01374
01375
01376 value_clear(Status); value_clear(tmp1);
01377 value_clear(tmp2); value_clear(tmp3);
01378 for(i=0;i<RowSize1;i++)
01379 value_clear(temp1[i]);
01380
01381
01382 free(temp1); free(temp2); free(jx); free(bx);
01383 UNCATCH(any_exception_error);
01384 return Empty_Polyhedron(Dimension-1);
01385 }
01386
01387
01388
01389 value_set_si(Mat->p[j][0],2);
01390 continue;
01391 }
01392
01393
01394 value_assign(Status, Mat->p[j][0]);
01395
01396
01397 if (value_zero_p(Status))
01398
01399
01400 value_set_si(Mat->p[j][0],2);
01401
01402
01403 else if (value_lt(Status,tmp2))
01404
01405
01406 value_set_si(Mat->p[j][0],2);
01407
01408
01409 else if (value_eq(Status,tmp3))
01410
01411
01412 value_set_si(Mat->p[j][0],0);
01413
01414
01415 else {
01416 NbIneq++;
01417
01418
01419 value_set_si(Mat->p[j][0],1);
01420 }
01421 }
01422
01423 #ifdef POLY_RR_DEBUG
01424 fprintf(stderr, "[Remove_redundants : Step6]\nConstraints =");
01425 Matrix_Print(stderr,0,Mat);
01426 fprintf(stderr, "\nRay =");
01427 Matrix_Print(stderr,0,Ray);
01428 #endif
01429
01430
01431
01432
01433
01434
01435 value_set_si(tmp2,Dim_RaySpace);
01436 value_set_si(tmp3,(NbConstraints+1));
01437 NbUni=0;
01438 for (j=0; j<NbRay; j++) {
01439
01440
01441 value_assign(Status, Ray->p[j][0]);
01442
01443
01444 if (value_lt(Status,tmp2))
01445
01446
01447 value_set_si(Ray->p[j][0],2);
01448
01449
01450 else if (value_eq(Status,tmp3))
01451
01452
01453 value_set_si(Ray->p[j][0],0);
01454
01455
01456 else {
01457 NbUni++;
01458
01459
01460 value_set_si(Ray->p[j][0],1);
01461 }
01462 }
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472 Pol = Polyhedron_Alloc(Dimension-1, NbIneq+NbEq2+1, NbUni+NbBid2);
01473 if (!Pol) {
01474 errormsg1("Remove_redundants", "outofmem", "out of memory space");
01475
01476
01477 value_clear(Status); value_clear(tmp1);
01478 value_clear(tmp2); value_clear(tmp3);
01479 for(i=0;i<RowSize1;i++)
01480 value_clear(temp1[i]);
01481
01482 free(temp1); free(temp2); free(jx); free(bx);
01483 UNCATCH(any_exception_error);
01484 return 0;
01485 }
01486 Pol->NbBid = NbBid2;
01487 Pol->NbEq = NbEq2;
01488
01489
01490 if (NbBid2) Vector_Copy(Ray->p[0], Pol->Ray[0], (Dimension+1)*NbBid2);
01491 if (NbEq2) Vector_Copy(Mat->p[0], Pol->Constraint[0], (Dimension+1)*NbEq2);
01492
01493 #ifdef POLY_RR_DEBUG
01494 fprintf(stderr, "[Remove_redundants : Step7]\nConstraints =");
01495 Matrix_Print(stderr,0,Mat);
01496 fprintf(stderr, "\nRay =");
01497 Matrix_Print(stderr,0,Ray);
01498 #endif
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513 Trace=(unsigned *)malloc(sat_nbcolumns * sizeof(unsigned));
01514 if(!Trace) {
01515 errormsg1("Remove_Redundants", "outofmem", "out of memory space");
01516
01517
01518 value_clear(Status); value_clear(tmp1);
01519 value_clear(tmp2); value_clear(tmp3);
01520 for(i=0;i<RowSize1;i++)
01521 value_clear(temp1[i]);
01522
01523 free(temp1); free(temp2); free(jx); free(bx);
01524 UNCATCH(any_exception_error);
01525 return 0;
01526 }
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549 NbIneq2 = 0;
01550 for (j=NbEq; j<NbConstraints; j++) {
01551
01552
01553 if (value_one_p (Mat->p[j][0])) {
01554 for (k=0; k<sat_nbcolumns; k++) Trace[k]=0;
01555
01556
01557
01558 for (i=NbBid; i<NbRay; i++)
01559
01560
01561 if (value_one_p(Ray->p[i][0])) {
01562 if (!(Sat->p[i][jx[j]]&bx[j]))
01563 for (k=0; k<sat_nbcolumns; k++) Trace[k] |= Sat->p[i][k];
01564 }
01565
01566
01567
01568
01569 Redundant=0;
01570 for (i=NbEq; i<NbConstraints; i++) {
01571
01572
01573 if (value_one_p(Mat->p[i][0]) && (i!=j) && !(Trace[jx[i]] & bx[i])) {
01574 Redundant=1;
01575 break;
01576 }
01577 }
01578 if (Redundant) {
01579 value_set_si(Mat->p[j][0],2);
01580 }
01581 else {
01582 Vector_Copy(Mat->p[j], Pol->Constraint[NbEq2+NbIneq2], Dimension+1);
01583 if (Filter) Filter[jx[j]] |= bx[j];
01584 NbIneq2++;
01585 }
01586 }
01587 }
01588 free(Trace), Trace = NULL;
01589
01590 #ifdef POLY_RR_DEBUG
01591 fprintf(stderr, "[Remove_redundants : Step8]\nConstraints =");
01592 Matrix_Print(stderr,0,Mat);
01593 fprintf(stderr, "\nRay =");
01594 Matrix_Print(stderr,0,Ray);
01595 #endif
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606 Trace=(unsigned *)malloc(NbRay * sizeof(unsigned));
01607 if(!Trace) {
01608 errormsg1("Remove_Redundants", "outofmem", "out of memory space");
01609
01610
01611 value_clear(Status); value_clear(tmp1);
01612 value_clear(tmp2); value_clear(tmp3);
01613 for(i=0;i<RowSize1;i++)
01614 value_clear(temp1[i]);
01615
01616 free(bx); free(jx); free(temp2); free(temp1);
01617 UNCATCH(any_exception_error);
01618 return 0;
01619 }
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638 NbUni2 = 0;
01639
01640
01641 aux = 0;
01642 for (i=NbBid; i<NbRay; i++) {
01643
01644
01645 if (value_one_p (Ray->p[i][0])) {
01646
01647
01648 if (value_notzero_p (Ray->p[i][Dimension]))
01649 for (k=NbBid; k<NbRay; k++) Trace[k]=0;
01650 else
01651
01652
01653
01654
01655 for (k=NbBid; k<NbRay; k++)
01656
01657
01658 Trace[k] = (value_notzero_p (Ray->p[k][Dimension]));
01659
01660
01661
01662 for (j=NbEq; j<NbConstraints; j++)
01663
01664
01665 if (value_one_p (Mat->p[j][0])) {
01666 if (!(Sat->p[i][jx[j]]&bx[j]))
01667 for (k=NbBid; k<NbRay; k++) Trace[k] |= Sat->p[k][jx[j]]&bx[j];
01668 }
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678 Redundant = 0;
01679 for (j=NbBid; j<NbRay; j++) {
01680
01681
01682 if (value_one_p (Ray->p[j][0]) && (i!=j) && !Trace[j]) {
01683 Redundant=1;
01684 break;
01685 }
01686 }
01687 if (Redundant)
01688 value_set_si(Ray->p[i][0],2);
01689 else {
01690 Vector_Copy(Ray->p[i], Pol->Ray[NbBid2+NbUni2], Dimension+1);
01691 NbUni2++;
01692
01693
01694 if (value_zero_p (Ray->p[i][Dimension]))
01695 aux++;
01696 }
01697 }
01698 }
01699
01700
01701 if (aux>=Dim_RaySpace) {
01702 Vector_Set(Pol->Constraint[NbEq2+NbIneq2],0,Dimension+1);
01703 value_set_si(Pol->Constraint[NbEq2+NbIneq2][0],1);
01704 value_set_si(Pol->Constraint[NbEq2+NbIneq2][Dimension],1);
01705 NbIneq2++;
01706 }
01707 }
01708
01709 UNCATCH(any_exception_error);
01710
01711 #ifdef POLY_RR_DEBUG
01712 fprintf(stderr, "[Remove_redundants : Step9]\nConstraints =");
01713 Matrix_Print(stderr,0,Mat);
01714 fprintf(stderr, "\nRay =");
01715 Matrix_Print(stderr,0,Ray);
01716 #endif
01717
01718 free(Trace);
01719 free(bx);
01720 free(jx);
01721 free(temp2);
01722
01723 Pol->NbConstraints = NbEq2 + NbIneq2;
01724 Pol->NbRays = NbBid2 + NbUni2;
01725
01726
01727 value_clear(Status); value_clear(tmp1);
01728 value_clear(tmp2); value_clear(tmp3);
01729 for(i=0;i<RowSize1;i++)
01730 value_clear(temp1[i]);
01731 free(temp1);
01732 F_SET(Pol,
01733 POL_VALID | POL_INEQUALITIES | POL_FACETS | POL_POINTS | POL_VERTICES);
01734 return Pol;
01735 }
01736
01737
01738
01739
01740 Polyhedron* Polyhedron_Alloc(unsigned Dimension,unsigned NbConstraints,unsigned NbRays) {
01741
01742 Polyhedron *Pol;
01743 unsigned NbRows,NbColumns;
01744 int i,j;
01745 Value *p, **q;
01746
01747 Pol=(Polyhedron *)malloc(sizeof(Polyhedron));
01748 if(!Pol) {
01749 errormsg1("Polyhedron_Alloc", "outofmem", "out of memory space");
01750 return 0;
01751 }
01752
01753 Pol->next = (Polyhedron *)0;
01754 Pol->Dimension = Dimension;
01755 Pol->NbConstraints = NbConstraints;
01756 Pol->NbRays = NbRays;
01757 Pol->NbEq = 0;
01758 Pol->NbBid = 0;
01759 Pol->flags = 0;
01760 NbRows = NbConstraints + NbRays;
01761 NbColumns = Dimension + 2;
01762
01763 q = (Value **)malloc(NbRows * sizeof(Value *));
01764 if(!q) {
01765 errormsg1("Polyhedron_Alloc", "outofmem", "out of memory space");
01766 return 0;
01767 }
01768 p = value_alloc(NbRows*NbColumns, &Pol->p_Init_size);
01769 if(!p) {
01770 free(q);
01771 errormsg1("Polyhedron_Alloc", "outofmem", "out of memory space");
01772 return 0;
01773 }
01774 Pol->Constraint = q;
01775 Pol->Ray = q + NbConstraints;
01776 Pol->p_Init = p;
01777 for (i=0;i<NbRows;i++) {
01778 *q++ = p;
01779 p += NbColumns;
01780 }
01781 return Pol;
01782 }
01783
01784
01785
01786
01787 void Polyhedron_Free(Polyhedron *Pol)
01788 {
01789 if(!Pol)
01790 return;
01791 value_free(Pol->p_Init, Pol->p_Init_size);
01792 free(Pol->Constraint);
01793 free(Pol);
01794 return;
01795 }
01796
01797
01798
01799
01800 void Domain_Free(Polyhedron *Pol)
01801 {
01802 Polyhedron *Next;
01803
01804 for (; Pol; Pol = Next) {
01805 Next = Pol->next;
01806 Polyhedron_Free(Pol);
01807 }
01808 return;
01809 }
01810
01811
01812
01813
01814 void Polyhedron_Print(FILE *Dst,char *Format,Polyhedron *Pol) {
01815
01816 unsigned Dimension, NbConstraints, NbRays;
01817 int i, j;
01818 Value *p;
01819
01820 if (!Pol) {
01821 fprintf(Dst, "<null polyhedron>\n");
01822 return;
01823 }
01824
01825 Dimension = Pol->Dimension + 2;
01826 NbConstraints = Pol->NbConstraints;
01827 NbRays = Pol->NbRays;
01828 fprintf(Dst, "POLYHEDRON Dimension:%d\n", Pol->Dimension);
01829 fprintf(Dst," Constraints:%d Equations:%d Rays:%d Lines:%d\n",
01830 Pol->NbConstraints, Pol->NbEq, Pol->NbRays, Pol->NbBid);
01831 fprintf(Dst,"Constraints %d %d\n", NbConstraints, Dimension);
01832
01833 for (i=0;i<NbConstraints;i++) {
01834 p=Pol->Constraint[i];
01835
01836
01837 if (value_notzero_p (*p))
01838 fprintf(Dst,"Inequality: [");
01839 else
01840 fprintf(Dst,"Equality: [");
01841 p++;
01842 for (j=1;j<Dimension;j++) {
01843 value_print(Dst,Format,*p++);
01844 }
01845 (void)fprintf(Dst," ]\n");
01846 }
01847
01848 (void)fprintf(Dst, "Rays %d %d\n", NbRays, Dimension);
01849 for (i=0;i<NbRays;i++) {
01850 p=Pol->Ray[i];
01851
01852
01853 if (value_notzero_p (*p)) {
01854 p++;
01855
01856
01857 if (value_notzero_p (p[Dimension-2]))
01858 fprintf(Dst, "Vertex: [");
01859 else
01860 fprintf(Dst, "Ray: [");
01861 }
01862 else {
01863 p++;
01864 fprintf(Dst, "Line: [");
01865 }
01866 for (j=1; j < Dimension-1; j++) {
01867 value_print(Dst,Format,*p++);
01868 }
01869
01870
01871 if (value_notzero_p (*p)) {
01872 fprintf( Dst, " ]/" );
01873 value_print(Dst,VALUE_FMT,*p);
01874 fprintf( Dst, "\n" );
01875 }
01876 else
01877 fprintf(Dst, " ]\n");
01878 }
01879 if (Pol->next) {
01880 fprintf(Dst, "UNION ");
01881 Polyhedron_Print(Dst,Format,Pol->next);
01882 }
01883 }
01884
01885
01886
01887
01888 void PolyPrint (Polyhedron *Pol) {
01889 Polyhedron_Print(stderr,"%4d",Pol);
01890 }
01891
01892
01893
01894
01895
01896
01897
01898
01899 Polyhedron *Empty_Polyhedron(unsigned Dimension) {
01900
01901 Polyhedron *Pol;
01902 int i;
01903
01904 Pol = Polyhedron_Alloc(Dimension, Dimension+1, 0);
01905 if (!Pol) {
01906 errormsg1("Empty_Polyhedron", "outofmem", "out of memory space");
01907 return 0;
01908 }
01909 Vector_Set(Pol->Constraint[0],0,(Dimension+1)*(Dimension+2));
01910 for (i=0; i<=Dimension; i++) {
01911
01912
01913 value_set_si(Pol->Constraint[i][i+1],1);
01914 }
01915 Pol->NbEq = Dimension+1;
01916 Pol->NbBid = 0;
01917 F_SET(Pol,
01918 POL_VALID | POL_INEQUALITIES | POL_FACETS | POL_POINTS | POL_VERTICES);
01919 return Pol;
01920 }
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932 Polyhedron *Universe_Polyhedron(unsigned Dimension) {
01933
01934 Polyhedron *Pol;
01935 int i;
01936
01937 Pol = Polyhedron_Alloc(Dimension,1,Dimension+1);
01938 if (!Pol) {
01939 errormsg1("Universe_Polyhedron", "outofmem", "out of memory space");
01940 return 0;
01941 }
01942 Vector_Set(Pol->Constraint[0],0,(Dimension+2));
01943
01944
01945 value_set_si(Pol->Constraint[0][0],1);
01946
01947
01948 value_set_si(Pol->Constraint[0][Dimension+1],1);
01949 Vector_Set(Pol->Ray[0],0,(Dimension+1)*(Dimension+2));
01950 for (i=0;i<=Dimension;i++) {
01951
01952
01953 value_set_si(Pol->Ray[i][i+1],1);
01954 }
01955
01956
01957 value_set_si(Pol->Ray[Dimension][0],1);
01958 Pol->NbEq = 0;
01959 Pol->NbBid = Dimension;
01960 F_SET(Pol,
01961 POL_VALID | POL_INEQUALITIES | POL_FACETS | POL_POINTS | POL_VERTICES);
01962 return Pol;
01963 }
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976 Polyhedron *Constraints2Polyhedron(Matrix *Constraints,unsigned NbMaxRays) {
01977
01978 Polyhedron *Pol = NULL;
01979 Matrix *Ray = NULL;
01980 SatMatrix *Sat = NULL;
01981 unsigned Dimension, nbcolumns;
01982 int i;
01983
01984 Dimension = Constraints->NbColumns - 1;
01985 if (Dimension < 1) {
01986 errormsg1("Constraints2Polyhedron","invalidpoly","invalid polyhedron dimension");
01987 return 0;
01988 }
01989
01990
01991
01992 if (Constraints->NbRows==0) {
01993 Pol = Universe_Polyhedron(Dimension-1);
01994 return Pol;
01995 }
01996
01997 if (NbMaxRays == POL_NO_DUAL) {
01998 unsigned NbEq = 0;
01999 unsigned Rank;
02000
02001 for (i = 0; i < Constraints->NbRows; ++i)
02002 if (value_zero_p(Constraints->p[i][0])) {
02003 if (i != NbEq)
02004 ExchangeRows(Constraints, i, NbEq);
02005 ++NbEq;
02006 }
02007 Rank = Gauss(Constraints, NbEq, Dimension);
02008 Pol = Polyhedron_Alloc(Dimension-1, Constraints->NbRows - (NbEq-Rank), 0);
02009
02010 Vector_Copy(Constraints->p[0], Pol->Constraint[0],
02011 Rank * Constraints->NbColumns);
02012 Vector_Copy(Constraints->p[NbEq], Pol->Constraint[Rank],
02013 (Constraints->NbRows - NbEq) * Constraints->NbColumns);
02014 Pol->NbEq = Rank;
02015 Pol->Ray = 0;
02016 F_SET(Pol, POL_VALID | POL_INEQUALITIES);
02017 return Pol;
02018 }
02019
02020 if (Dimension > NbMaxRays)
02021 NbMaxRays = Dimension;
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033 Ray = Matrix_Alloc(NbMaxRays, Dimension+1);
02034 if(!Ray) {
02035 errormsg1("Constraints2Polyhedron","outofmem","out of memory space");
02036 return 0;
02037 }
02038 Vector_Set(Ray->p_Init,0, NbMaxRays * (Dimension+1));
02039 for (i=0; i<Dimension; i++) {
02040
02041
02042 value_set_si(Ray->p[i][i+1],1);
02043 }
02044
02045
02046 value_set_si(Ray->p[Dimension-1][0],1);
02047 Ray->NbRows = Dimension;
02048
02049
02050 nbcolumns = (Constraints->NbRows - 1)/(sizeof(int)*8) + 1;
02051 Sat = SMAlloc(NbMaxRays, nbcolumns);
02052 SMVector_Init(Sat->p_init,Dimension*nbcolumns);
02053 Sat->NbRows = Dimension;
02054
02055 CATCH(any_exception_error) {
02056
02057
02058 if (Sat) SMFree(&Sat);
02059 if (Ray) Matrix_Free(Ray);
02060 if (Pol) Polyhedron_Free(Pol);
02061 RETHROW();
02062 }
02063 TRY {
02064
02065
02066 Chernikova(Constraints,Ray,Sat,Dimension-1,NbMaxRays,0,0);
02067
02068 #ifdef POLY_DEBUG
02069 fprintf(stderr, "[constraints2polyhedron]\nConstraints = ");
02070 Matrix_Print(stderr,0,Constraints);
02071 fprintf(stderr, "\nRay = ");
02072 Matrix_Print(stderr,0,Ray);
02073 fprintf(stderr, "\nSat = ");
02074 SMPrint(Sat);
02075 #endif
02076
02077
02078 Pol = Remove_Redundants(Constraints,Ray,Sat,0);
02079 }
02080
02081 UNCATCH(any_exception_error);
02082
02083 #ifdef POLY_DEBUG
02084 fprintf(stderr, "\nPol = ");
02085 Polyhedron_Print(stderr,"%4d",Pol);
02086 #endif
02087
02088 SMFree(&Sat), Sat = NULL;
02089 Matrix_Free(Ray), Ray = NULL;
02090 return Pol;
02091 }
02092
02093 #undef POLY_DEBUG
02094
02095
02096
02097
02098 Matrix *Polyhedron2Constraints(Polyhedron *Pol) {
02099
02100 Matrix *Mat;
02101 unsigned NbConstraints,Dimension;
02102
02103 POL_ENSURE_INEQUALITIES(Pol);
02104
02105 NbConstraints = Pol->NbConstraints;
02106 Dimension = Pol->Dimension+2;
02107 Mat = Matrix_Alloc(NbConstraints,Dimension);
02108 if(!Mat) {
02109 errormsg1("Polyhedron2Constraints", "outofmem", "out of memory space");
02110 return 0;
02111 }
02112 Vector_Copy(Pol->Constraint[0],Mat->p_Init,NbConstraints * Dimension);
02113 return Mat;
02114 }
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125 Polyhedron *Rays2Polyhedron(Matrix *Ray,unsigned NbMaxConstrs) {
02126
02127 Polyhedron *Pol = NULL;
02128 Matrix *Mat = NULL;
02129 SatMatrix *Sat = NULL, *SatTranspose = NULL;
02130 unsigned Dimension, nbcolumns;
02131 int i;
02132
02133 Dimension = Ray->NbColumns-1;
02134 Sat = NULL;
02135 SatTranspose = NULL;
02136 Mat = NULL;
02137
02138 if (Ray->NbRows==0) {
02139
02140
02141 Pol = Empty_Polyhedron(Dimension-1);
02142 return(Pol);
02143 }
02144
02145
02146 if (NbMaxConstrs == POL_NO_DUAL)
02147 NbMaxConstrs = 0;
02148
02149 if (Dimension > NbMaxConstrs)
02150 NbMaxConstrs = Dimension;
02151
02152
02153 Mat = Matrix_Alloc(NbMaxConstrs,Dimension+1);
02154 if(!Mat) {
02155 errormsg1("Rays2Polyhedron","outofmem","out of memory space");
02156 return 0;
02157 }
02158
02159
02160 Vector_Set(Mat->p_Init,0,NbMaxConstrs * (Dimension+1));
02161 for (i=0; i<Dimension; i++) {
02162
02163
02164 value_set_si(Mat->p[i][i+1],1);
02165 }
02166
02167
02168
02169 Mat->NbRows = Dimension;
02170 nbcolumns = (Ray->NbRows -1)/(sizeof(int)*8) + 1;
02171 SatTranspose = SMAlloc(NbMaxConstrs,nbcolumns);
02172 SMVector_Init(SatTranspose->p[0],Dimension * nbcolumns);
02173 SatTranspose->NbRows = Dimension;
02174
02175 #ifdef POLY_DEBUG
02176 fprintf(stderr, "[ray2polyhedron: Before]\nRay = ");
02177 Matrix_Print(stderr,0,Ray);
02178 fprintf(stderr, "\nConstraints = ");
02179 Matrix_Print(stderr,0,Mat);
02180 fprintf(stderr, "\nSatTranspose = ");
02181 SMPrint (SatTranspose);
02182 #endif
02183
02184 CATCH(any_exception_error) {
02185
02186
02187
02188
02189 if (SatTranspose) SMFree(&SatTranspose);
02190 if (Sat) SMFree(&Sat);
02191 if (Mat) Matrix_Free(Mat);
02192 if (Pol) Polyhedron_Free(Pol);
02193 RETHROW();
02194 }
02195 TRY {
02196
02197
02198 Chernikova(Ray,Mat,SatTranspose,Dimension,NbMaxConstrs,0,1);
02199
02200 #ifdef POLY_DEBUG
02201 fprintf(stderr, "[ray2polyhedron: After]\nRay = ");
02202 Matrix_Print(stderr,0,Ray);
02203 fprintf(stderr, "\nConstraints = ");
02204 Matrix_Print(stderr,0,Mat);
02205 fprintf(stderr, "\nSatTranspose = ");
02206 SMPrint (SatTranspose);
02207 #endif
02208
02209
02210
02211 Sat = TransformSat(Mat,Ray,SatTranspose);
02212
02213 #ifdef POLY_DEBUG
02214 fprintf(stderr, "\nSat =");
02215 SMPrint(Sat);
02216 #endif
02217
02218 SMFree(&SatTranspose), SatTranspose = NULL;
02219
02220
02221 Pol = Remove_Redundants(Mat,Ray,Sat,0);
02222 }
02223
02224 UNCATCH(any_exception_error);
02225
02226 #ifdef POLY_DEBUG
02227 fprintf(stderr, "\nPol = ");
02228 Polyhedron_Print(stderr,"%4d",Pol);
02229 #endif
02230
02231 SMFree(&Sat);
02232 Matrix_Free(Mat);
02233 return Pol;
02234 }
02235
02236
02237
02238
02239
02240 void Polyhedron_Compute_Dual(Polyhedron *P)
02241 {
02242 if (!F_ISSET(P, POL_VALID))
02243 return;
02244
02245 if (F_ISSET(P, POL_FACETS | POL_VERTICES))
02246 return;
02247
02248 if (F_ISSET(P, POL_INEQUALITIES)) {
02249 Matrix M;
02250 Polyhedron tmp, *Q;
02251
02252 M.NbRows = P->NbConstraints;
02253 M.NbColumns = P->Dimension+2;
02254 M.p_Init = P->p_Init;
02255 M.p = P->Constraint;
02256 Q = Constraints2Polyhedron(&M, 0);
02257
02258
02259 tmp = *Q;
02260 *Q = *P;
02261 *P = tmp;
02262
02263 P->next = Q->next;
02264 Polyhedron_Free(Q);
02265 return;
02266 }
02267
02268
02269 assert(0);
02270 }
02271
02272
02273
02274
02275
02276
02277
02278
02279 static SatMatrix *BuildSat(Matrix *Mat,Matrix *Ray,unsigned NbConstraints,unsigned NbMaxRays) {
02280
02281 SatMatrix *Sat = NULL;
02282 int i, j, k, jx;
02283 Value *p1, *p2, *p3;
02284 unsigned Dimension, NbRay, bx, nbcolumns;
02285
02286 CATCH(any_exception_error) {
02287 if (Sat)
02288 SMFree(&Sat);
02289 RETHROW();
02290 }
02291 TRY {
02292 NbRay = Ray->NbRows;
02293 Dimension = Mat->NbColumns-1;
02294
02295
02296 nbcolumns = (Mat->NbRows - 1)/(sizeof(int)*8) + 1;
02297 Sat = SMAlloc(NbMaxRays,nbcolumns);
02298 Sat->NbRows = NbRay;
02299 SMVector_Init(Sat->p_init, nbcolumns * NbRay);
02300 jx=0; bx=MSB;
02301 for (k=0; k<NbConstraints; k++) {
02302 for (i=0; i<NbRay; i++) {
02303
02304
02305
02306 p1 = Ray->p[i]+1;
02307 p2 = Mat->p[k]+1;
02308 p3 = Ray->p[i];
02309 value_set_si(*p3,0);
02310 for (j=0; j<Dimension; j++) {
02311 value_addmul(*p3, *p1, *p2);
02312 p1++; p2++;
02313 }
02314 }
02315 for (j=0; j<NbRay; j++) {
02316
02317
02318
02319 if (value_notzero_p(Ray->p[j][0]))
02320 Sat->p[j][jx]|=bx;
02321 }
02322 NEXT(jx, bx);
02323 }
02324 }
02325
02326 UNCATCH(any_exception_error);
02327 return Sat;
02328 }
02329
02330
02331
02332
02333
02334
02335 Polyhedron *AddConstraints(Value *Con,unsigned NbConstraints,Polyhedron *Pol,unsigned NbMaxRays) {
02336
02337 Polyhedron *NewPol = NULL;
02338 Matrix *Mat = NULL, *Ray = NULL;
02339 SatMatrix *Sat = NULL;
02340 unsigned NbRay, NbCon, Dimension;
02341
02342 if (NbConstraints == 0)
02343 return Polyhedron_Copy(Pol);
02344
02345 POL_ENSURE_FACETS(Pol);
02346 POL_ENSURE_VERTICES(Pol);
02347
02348 CATCH(any_exception_error) {
02349 if (NewPol) Polyhedron_Free(NewPol);
02350 if (Mat) Matrix_Free(Mat);
02351 if (Ray) Matrix_Free(Ray);
02352 if (Sat) SMFree(&Sat);
02353 RETHROW();
02354 }
02355 TRY {
02356 NbRay = Pol->NbRays;
02357 NbCon = Pol->NbConstraints + NbConstraints;
02358 Dimension = Pol->Dimension + 2;
02359
02360
02361 if (NbMaxRays == POL_NO_DUAL)
02362 NbMaxRays = 0;
02363
02364 if (NbRay > NbMaxRays)
02365 NbMaxRays = NbRay;
02366
02367 Mat = Matrix_Alloc(NbCon, Dimension);
02368 if(!Mat) {
02369 errormsg1("AddConstraints", "outofmem", "out of memory space");
02370 UNCATCH(any_exception_error);
02371 return 0;
02372 }
02373
02374
02375 Vector_Copy(Pol->Constraint[0], Mat->p[0], Pol->NbConstraints * Dimension);
02376
02377
02378 Vector_Copy(Con, Mat->p[Pol->NbConstraints], NbConstraints * Dimension);
02379
02380
02381 Ray = Matrix_Alloc(NbMaxRays, Dimension);
02382 if(!Ray) {
02383 errormsg1("AddConstraints", "outofmem", "out of memory space");
02384 UNCATCH(any_exception_error);
02385 return 0;
02386 }
02387 Ray->NbRows = NbRay;
02388
02389
02390 if (NbRay)
02391 Vector_Copy(Pol->Ray[0], Ray->p[0], NbRay * Dimension);
02392
02393
02394
02395 Sat = BuildSat(Mat, Ray, Pol->NbConstraints, NbMaxRays);
02396
02397
02398 Pol_status = Chernikova(Mat, Ray, Sat, Pol->NbBid, NbMaxRays, Pol->NbConstraints,0);
02399
02400
02401 NewPol = Remove_Redundants(Mat, Ray, Sat, 0);
02402
02403 }
02404
02405 UNCATCH(any_exception_error);
02406 SMFree(&Sat);
02407 Matrix_Free(Ray);
02408 Matrix_Free(Mat);
02409 return NewPol;
02410 }
02411
02412
02413
02414
02415
02416
02417
02418 int PolyhedronIncludes(Polyhedron *Pol1,Polyhedron *Pol2) {
02419
02420 int Dimension = Pol1->Dimension + 1;
02421 int i, j, k;
02422 Value *p1, *p2, p3;
02423
02424 POL_ENSURE_FACETS(Pol1);
02425 POL_ENSURE_VERTICES(Pol1);
02426 POL_ENSURE_FACETS(Pol2);
02427 POL_ENSURE_VERTICES(Pol2);
02428
02429 value_init(p3);
02430 for (k=0; k<Pol1->NbConstraints; k++) {
02431 for (i=0;i<Pol2->NbRays;i++) {
02432
02433
02434 p1 = Pol2->Ray[i]+1;
02435 p2 = Pol1->Constraint[k]+1;
02436 value_set_si(p3,0);
02437 for(j=0;j<Dimension;j++) {
02438 value_addmul(p3, *p1,*p2);
02439 p1++; p2++;
02440 }
02441
02442
02443
02444 if(value_neg_p(p3) ||
02445 (value_notzero_p(p3)
02446 && (value_zero_p(Pol1->Constraint[k][0]) || (value_zero_p(Pol2->Ray[i][0])) ) )) {
02447 value_clear(p3);
02448 return 0;
02449 }
02450 }
02451 }
02452 value_clear(p3);
02453 return 1;
02454 }
02455
02456
02457
02458
02459
02460
02461
02462 Polyhedron *AddPolyToDomain(Polyhedron *Pol,Polyhedron *PolDomain) {
02463
02464 Polyhedron *p, *pnext, *p_domain_end = (Polyhedron *) 0;
02465 int Redundant;
02466
02467 if (!Pol)
02468 return PolDomain;
02469 if (!PolDomain)
02470 return Pol;
02471
02472 POL_ENSURE_FACETS(Pol);
02473 POL_ENSURE_VERTICES(Pol);
02474
02475
02476 if (emptyQ(Pol)) {
02477 Polyhedron_Free(Pol);
02478 return PolDomain;
02479 }
02480
02481 POL_ENSURE_FACETS(PolDomain);
02482 POL_ENSURE_VERTICES(PolDomain);
02483
02484
02485 if (emptyQ(PolDomain)) {
02486 Polyhedron_Free(PolDomain);
02487 return Pol;
02488 }
02489
02490
02491 Redundant = 0;
02492 for (p=PolDomain,PolDomain=(Polyhedron *)0; p; p=pnext) {
02493
02494
02495 if (PolyhedronIncludes(Pol, p))
02496 {
02497
02498 pnext = p->next;
02499 Polyhedron_Free( p );
02500 continue;
02501 }
02502
02503
02504 if (!PolDomain) PolDomain = p; else p_domain_end->next = p;
02505 p_domain_end = p;
02506
02507
02508 if (PolyhedronIncludes(p,Pol)) {
02509 Redundant = 1;
02510 break;
02511 }
02512 pnext = p->next;
02513 }
02514 if (!Redundant) {
02515
02516
02517
02518 if (!PolDomain) PolDomain = Pol; else p_domain_end->next = Pol;
02519 }
02520 else {
02521
02522
02523 Polyhedron_Free(Pol);
02524 }
02525 return PolDomain;
02526 }
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538 Polyhedron *SubConstraint(Value *Con,Polyhedron *Pol,unsigned NbMaxRays,int Pass) {
02539
02540 Polyhedron *NewPol = NULL;
02541 Matrix *Mat = NULL, *Ray = NULL;
02542 SatMatrix *Sat = NULL;
02543 unsigned NbRay, NbCon, NbEle1, Dimension;
02544 int i;
02545
02546 POL_ENSURE_FACETS(Pol);
02547 POL_ENSURE_VERTICES(Pol);
02548
02549 CATCH(any_exception_error) {
02550 if (NewPol) Polyhedron_Free(NewPol);
02551 if (Mat) Matrix_Free(Mat);
02552 if (Ray) Matrix_Free(Ray);
02553 if (Sat) SMFree(&Sat);
02554 RETHROW();
02555 }
02556 TRY {
02557
02558
02559 Dimension = Pol->Dimension+1;
02560 for (i=1; i<Dimension; i++)
02561 if (value_notzero_p(Con[i])) break;
02562 if (i==Dimension) {
02563 UNCATCH(any_exception_error);
02564 return (Polyhedron *) 0;
02565 }
02566
02567 NbRay = Pol->NbRays;
02568 NbCon = Pol->NbConstraints;
02569 Dimension = Pol->Dimension+2;
02570 NbEle1 = NbCon * Dimension;
02571
02572
02573 if (NbMaxRays == POL_NO_DUAL)
02574 NbMaxRays = 0;
02575
02576 if (NbRay > NbMaxRays)
02577 NbMaxRays = NbRay;
02578
02579 Mat = Matrix_Alloc(NbCon + 1, Dimension);
02580 if(!Mat) {
02581 errormsg1("SubConstraint", "outofmem", "out of memory space");
02582 UNCATCH(any_exception_error);
02583 return 0;
02584 }
02585
02586
02587 Vector_Copy(Pol->Constraint[0], Mat->p[0], NbEle1);
02588
02589
02590 value_set_si(Mat->p[NbCon][0],1);
02591 if (!(Pass&1))
02592 for(i=1; i<Dimension; i++)
02593 value_oppose(Mat->p[NbCon][i],Con[i]);
02594 else
02595 for(i=1; i<Dimension; i++)
02596 value_assign(Mat->p[NbCon][i],Con[i]);
02597 if (!(Pass&2))
02598 value_decrement(Mat->p[NbCon][Dimension-1],Mat->p[NbCon][Dimension-1]);
02599
02600
02601 Ray = Matrix_Alloc(NbMaxRays, Dimension);
02602 if(!Ray) {
02603 errormsg1("SubConstraint", "outofmem", "out of memory space");
02604 UNCATCH(any_exception_error);
02605 return 0;
02606 }
02607
02608
02609 Ray->NbRows = NbRay;
02610 if (NbRay)
02611 Vector_Copy(Pol->Ray[0], Ray->p[0], NbRay * Dimension);
02612
02613
02614
02615 Sat = BuildSat(Mat, Ray, NbCon, NbMaxRays);
02616
02617
02618 Pol_status = Chernikova(Mat, Ray, Sat, Pol->NbBid, NbMaxRays, NbCon,0);
02619
02620
02621 NewPol = Remove_Redundants(Mat, Ray, Sat, 0);
02622
02623 }
02624
02625 UNCATCH(any_exception_error);
02626
02627 SMFree(&Sat);
02628 Matrix_Free(Ray);
02629 Matrix_Free(Mat);
02630 return NewPol;
02631 }
02632
02633
02634
02635
02636
02637 Polyhedron *DomainIntersection(Polyhedron *Pol1,Polyhedron *Pol2,unsigned NbMaxRays) {
02638
02639 Polyhedron *p1, *p2, *p3, *d;
02640
02641 if (!Pol1 || !Pol2) return (Polyhedron*) 0;
02642 if (Pol1->Dimension != Pol2->Dimension) {
02643 errormsg1( "DomainIntersection", "diffdim",
02644 "operation on different dimensions");
02645 return (Polyhedron*) 0;
02646 }
02647
02648
02649
02650
02651 d = (Polyhedron *)0;
02652 for (p1=Pol1; p1; p1=p1->next) {
02653 for (p2=Pol2; p2; p2=p2->next) {
02654 p3 = AddConstraints(p2->Constraint[0],
02655 p2->NbConstraints, p1, NbMaxRays);
02656 d = AddPolyToDomain(p3,d);
02657 }
02658 }
02659 if (!d)
02660 return Empty_Polyhedron(Pol1->Dimension);
02661 else
02662 return d;
02663
02664 }
02665
02666
02667
02668
02669 Matrix *Polyhedron2Rays(Polyhedron *Pol) {
02670
02671 Matrix *Ray;
02672 unsigned NbRays, Dimension;
02673
02674 POL_ENSURE_POINTS(Pol);
02675
02676 NbRays = Pol->NbRays;
02677 Dimension = Pol->Dimension+2;
02678 Ray = Matrix_Alloc(NbRays, Dimension);
02679 if(!Ray) {
02680 errormsg1("Polyhedron2Rays", "outofmem", "out of memory space");
02681 return 0;
02682 }
02683 Vector_Copy(Pol->Ray[0], Ray->p_Init, NbRays*Dimension);
02684 return Ray;
02685 }
02686
02687
02688
02689
02690
02691 Polyhedron *AddRays(Value *AddedRays,unsigned NbAddedRays,Polyhedron *Pol,unsigned NbMaxConstrs) {
02692
02693 Polyhedron *NewPol = NULL;
02694 Matrix *Mat = NULL, *Ray = NULL;
02695 SatMatrix *Sat = NULL, *SatTranspose = NULL;
02696 unsigned NbCon, NbRay,NbEle1, Dimension;
02697
02698 POL_ENSURE_FACETS(Pol);
02699 POL_ENSURE_VERTICES(Pol);
02700
02701 CATCH(any_exception_error) {
02702 if (NewPol) Polyhedron_Free(NewPol);
02703 if (Mat) Matrix_Free(Mat);
02704 if (Ray) Matrix_Free(Ray);
02705 if (Sat) SMFree(&Sat);
02706 if (SatTranspose) SMFree(&SatTranspose);
02707 RETHROW();
02708 }
02709 TRY {
02710
02711 NbCon = Pol->NbConstraints;
02712 NbRay = Pol->NbRays;
02713 Dimension = Pol->Dimension + 2;
02714 NbEle1 = NbRay * Dimension;
02715
02716 Ray = Matrix_Alloc(NbAddedRays + NbRay, Dimension);
02717 if(!Ray) {
02718 errormsg1("AddRays", "outofmem", "out of memory space");
02719 UNCATCH(any_exception_error);
02720 return 0;
02721 }
02722
02723
02724 if (NbRay)
02725 Vector_Copy(Pol->Ray[0], Ray->p_Init, NbEle1);
02726
02727
02728 Vector_Copy(AddedRays, Ray->p_Init+NbEle1, NbAddedRays * Dimension);
02729
02730
02731 if (NbMaxConstrs == POL_NO_DUAL)
02732 NbMaxConstrs = 0;
02733
02734
02735 if (NbMaxConstrs < NbCon)
02736 NbMaxConstrs = NbCon;
02737
02738
02739 Mat = Matrix_Alloc(NbMaxConstrs, Dimension);
02740 if(!Mat) {
02741 errormsg1("AddRays", "outofmem", "out of memory space");
02742 UNCATCH(any_exception_error);
02743 return 0;
02744 }
02745 Mat->NbRows = NbCon;
02746
02747
02748 Vector_Copy(Pol->Constraint[0], Mat->p_Init, NbCon*Dimension);
02749
02750
02751
02752
02753 SatTranspose = BuildSat(Ray, Mat, NbRay, NbMaxConstrs);
02754
02755
02756 Pol_status = Chernikova(Ray, Mat, SatTranspose, Pol->NbEq, NbMaxConstrs, NbRay,1);
02757
02758
02759
02760 Sat = TransformSat(Mat, Ray, SatTranspose);
02761 SMFree(&SatTranspose), SatTranspose = NULL;
02762
02763
02764 NewPol = Remove_Redundants(Mat, Ray, Sat, 0);
02765
02766 SMFree(&Sat), Sat = NULL;
02767 Matrix_Free(Mat), Mat = NULL;
02768 Matrix_Free(Ray), Ray = NULL;
02769 }
02770
02771 UNCATCH(any_exception_error);
02772 return NewPol;
02773 }
02774
02775
02776
02777
02778
02779
02780 Polyhedron *DomainAddRays(Polyhedron *Pol,Matrix *Ray,unsigned NbMaxConstrs) {
02781
02782 Polyhedron *PolA, *PolEndA, *p1, *p2, *p3;
02783 int Redundant;
02784
02785 if (!Pol) return (Polyhedron*) 0;
02786 if (!Ray ) return Pol;
02787 if (Pol->Dimension != Ray->NbColumns-2) {
02788 errormsg1(
02789 "DomainAddRays", "diffdim", "operation on different dimensions");
02790 return (Polyhedron*) 0;
02791 }
02792
02793
02794 PolA = PolEndA = (Polyhedron *)0;
02795 for (p1=Pol; p1; p1=p1->next) {
02796 p3 = AddRays(Ray->p[0], Ray->NbRows, p1, NbMaxConstrs);
02797
02798
02799 Redundant = 0;
02800 for (p2=PolA; p2; p2=p2->next) {
02801 if (PolyhedronIncludes(p2, p3)) {
02802 Redundant = 1;
02803 break;
02804 }
02805 }
02806
02807
02808 if (!Redundant) {
02809 if (!PolEndA)
02810 PolEndA = PolA = p3;
02811 else {
02812 PolEndA->next = p3;
02813 PolEndA = PolEndA->next;
02814 }
02815 }
02816 }
02817 return PolA;
02818 }
02819
02820
02821
02822
02823 Polyhedron *Polyhedron_Copy(Polyhedron *Pol) {
02824
02825 Polyhedron *Pol1;
02826
02827 if (!Pol) return (Polyhedron *)0;
02828
02829
02830 Pol1 = Polyhedron_Alloc(Pol->Dimension, Pol->NbConstraints, Pol->NbRays);
02831 if (!Pol1) {
02832 errormsg1("Polyhedron_Copy", "outofmem", "out of memory space");
02833 return 0;
02834 }
02835 if( Pol->NbConstraints )
02836 Vector_Copy(Pol->Constraint[0], Pol1->Constraint[0],
02837 Pol->NbConstraints*(Pol->Dimension+2));
02838 if( Pol->NbRays )
02839 Vector_Copy(Pol->Ray[0], Pol1->Ray[0],
02840 Pol->NbRays*(Pol->Dimension+2));
02841 Pol1->NbBid = Pol->NbBid;
02842 Pol1->NbEq = Pol->NbEq;
02843 Pol1->flags = Pol->flags;
02844 return Pol1;
02845 }
02846
02847
02848
02849
02850 Polyhedron *Domain_Copy(Polyhedron *Pol) {
02851
02852 Polyhedron *Pol1;
02853
02854 if (!Pol) return (Polyhedron *) 0;
02855 Pol1 = Polyhedron_Copy(Pol);
02856 if (Pol->next) Pol1->next = Domain_Copy(Pol->next);
02857 return Pol1;
02858 }
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888 static void addToFilter(int k, unsigned *Filter, SatMatrix *Sat,Value *tmpR,Value *tmpC,int NbRays,int NbConstraints) {
02889
02890 int kj, i,j, jx;
02891 unsigned kb, bx;
02892
02893
02894 kj = k/WSIZE; kb = MSB; kb >>= k%WSIZE;
02895 Filter[kj]|=kb;
02896 value_set_si(tmpC[k],-1);
02897
02898
02899 for(i=0; i<NbRays; i++)
02900 if (value_posz_p(tmpR[i])) {
02901 if (Sat->p[i][kj]&kb)
02902 value_decrement(tmpR[i],tmpR[i]);
02903 else {
02904
02905
02906 value_set_si(tmpR[i],-1);
02907
02908
02909 jx=0; bx=MSB;
02910 for(j=0; j<NbConstraints; j++) {
02911 if (value_posz_p(tmpC[j]) && (Sat->p[i][jx]&bx) )
02912 value_decrement(tmpC[j],tmpC[j]);
02913 NEXT(jx,bx);
02914 }
02915 }
02916 }
02917 }
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929 static void FindSimple(Polyhedron *P1,Polyhedron *P2,unsigned *Filter,unsigned NbMaxRays) {
02930
02931 Matrix *Mat = NULL;
02932 SatMatrix *Sat = NULL;
02933 int i, j, k, jx, found;
02934 Value *p1, *p2, p3;
02935 unsigned Dimension, NbRays, NbConstraints, bx, nc;
02936 Value NbConstraintsLeft, tmp;
02937 Value *tmpC = NULL, *tmpR = NULL;
02938 Polyhedron *Pol = NULL, *Pol2 = NULL;
02939
02940
02941 value_init(p3); value_init(NbConstraintsLeft);
02942 value_init(tmp);
02943
02944 CATCH(any_exception_error) {
02945 if (tmpC) free(tmpC);
02946 if (tmpR) free(tmpR);
02947 if (Mat) Matrix_Free(Mat);
02948 if (Sat) SMFree(&Sat);
02949 if (Pol2 && Pol2!=P2) Polyhedron_Free(Pol2);
02950 if (Pol && Pol!=Pol2 && Pol!=P2) Polyhedron_Free(Pol);
02951
02952
02953 value_clear(p3); value_clear(NbConstraintsLeft);
02954 value_clear(tmp);
02955 RETHROW();
02956 }
02957 TRY {
02958
02959 Dimension = P1->Dimension+2;
02960 Mat = Matrix_Alloc(P1->NbConstraints, Dimension);
02961 if(!Mat) {
02962 errormsg1("FindSimple", "outofmem", "out of memory space");
02963 UNCATCH(any_exception_error);
02964
02965
02966 value_clear(p3); value_clear(NbConstraintsLeft); value_clear(tmp);
02967 return;
02968 }
02969
02970
02971 jx = 0; bx = MSB; Mat->NbRows=0;
02972 value_set_si(NbConstraintsLeft,0);
02973 for (k=0; k<P1->NbConstraints; k++) {
02974 if (Filter[jx]&bx) {
02975 Vector_Copy(P1->Constraint[k], Mat->p[Mat->NbRows], Dimension);
02976 Mat->NbRows++;
02977 }
02978 else
02979 value_increment(NbConstraintsLeft,NbConstraintsLeft);
02980 NEXT(jx,bx);
02981 }
02982 Pol2 = P2;
02983
02984 for (;;) {
02985 if (Mat->NbRows==0)
02986 Pol = Polyhedron_Copy(Pol2);
02987 else {
02988 Pol = AddConstraints(Mat->p_Init, Mat->NbRows, Pol2, NbMaxRays);
02989 if (Pol2 != P2) Polyhedron_Free(Pol2), Pol2 = NULL;
02990 }
02991 if (emptyQ(Pol)) {
02992 Matrix_Free(Mat), Mat = NULL;
02993 Polyhedron_Free(Pol), Pol = NULL;
02994 UNCATCH(any_exception_error);
02995
02996
02997 value_clear(p3); value_clear(NbConstraintsLeft); value_clear(tmp);
02998 return;
02999 }
03000 Mat->NbRows = 0;
03001 Pol2 = Pol;
03002
03003
03004 Dimension = Pol->Dimension+1;
03005 NbRays = Pol->NbRays;
03006 NbConstraints = P1->NbConstraints;
03007 tmpR = (Value *)malloc(NbRays*sizeof(Value));
03008 if(!tmpR) {
03009 errormsg1("FindSimple", "outofmem", "out of memory space");
03010 UNCATCH(any_exception_error);
03011
03012
03013 value_clear(p3); value_clear(NbConstraintsLeft); value_clear(tmp);
03014 return;
03015 }
03016 for(i=0;i<NbRays;i++)
03017 value_init(tmpR[i]);
03018 tmpC = (Value *)malloc(NbConstraints*sizeof(Value));
03019 if(!tmpC) {
03020 errormsg1("FindSimple", "outofmem", "out of memory space");
03021 UNCATCH(any_exception_error);
03022
03023
03024 value_clear(p3); value_clear(NbConstraintsLeft);
03025 for(i=0;i<NbRays;i++)
03026 value_clear(tmpR[i]);
03027 free(tmpR);
03028 return;
03029 }
03030 for(i=0;i<NbConstraints;i++)
03031 value_init(tmpC[i]);
03032 Vector_Set(tmpR,0,NbRays);
03033 Vector_Set(tmpC,0,NbConstraints);
03034
03035
03036 nc = (NbConstraints - 1) / (sizeof(int)*8) + 1;
03037 Sat = SMAlloc(NbRays, nc);
03038 Sat->NbRows = NbRays;
03039 SMVector_Init(Sat->p_init, nc*NbRays);
03040
03041 jx=0; bx=MSB;
03042 for (k=0; k<NbConstraints; k++) {
03043 if (Filter[jx]&bx)
03044 value_set_si(tmpC[k],-1);
03045 else
03046 for (i=0; i<NbRays; i++) {
03047 p1 = Pol->Ray[i]+1;
03048 p2 = P1->Constraint[k]+1;
03049 value_set_si(p3,0);
03050 for (j=0; j<Dimension; j++) {
03051 value_addmul(p3, *p1, *p2);
03052 p1++; p2++;
03053 }
03054 if(value_zero_p(p3) ||
03055 (value_pos_p(p3) && value_notzero_p(P1->Constraint[k][0]))) {
03056 Sat->p[i][jx]|=bx;
03057 value_increment(tmpR[i],tmpR[i]);
03058 value_increment(tmpC[k],tmpC[k]);
03059 }
03060 }
03061 NEXT(jx, bx);
03062 }
03063
03064 do {
03065 found = 0;
03066 for(i=0; i<NbRays; i++)
03067 if(value_posz_p(tmpR[i])) {
03068 value_add_int(tmp,tmpR[i],1);
03069 if(value_eq(tmp,NbConstraintsLeft)) {
03070
03071
03072 jx = 0; bx = MSB;
03073 for(k=0; k<NbConstraints; k++) {
03074 if(value_posz_p(tmpC[k]) && ((Sat->p[i][jx]&bx)==0)) {
03075 addToFilter(k, Filter, Sat, tmpR, tmpC,
03076 NbRays, NbConstraints);
03077 Vector_Copy(P1->Constraint[k],
03078 Mat->p[Mat->NbRows],Dimension+1);
03079 Mat->NbRows++;
03080 value_decrement(NbConstraintsLeft,NbConstraintsLeft);
03081 found=1;
03082 break;
03083 }
03084 NEXT(jx,bx);
03085 }
03086 break;
03087 }
03088 }
03089 }
03090 while (found);
03091
03092 if (!Mat->NbRows) {
03093
03094 Value cmax;
03095 value_init(cmax);
03096
03097 #ifndef LINEAR_VALUE_IS_CHARS
03098 value_set_si(cmax,(NbRays * NbConstraints+1));
03099 #else
03100 value_set_si(cmax,1);
03101 #endif
03102
03103 j = -1;
03104 for(k=0; k<NbConstraints; k++)
03105 if (value_posz_p(tmpC[k])) {
03106 if (value_gt(cmax,tmpC[k])) {
03107 value_assign(cmax,tmpC[k]);
03108 j = k;
03109 }
03110 }
03111 value_clear(cmax);
03112 if (j<0) {
03113 errormsg1("DomSimplify","logerror","logic error");
03114 }
03115 else {
03116 addToFilter(j, Filter, Sat, tmpR, tmpC, NbRays, NbConstraints);
03117 Vector_Copy(P1->Constraint[j],Mat->p[Mat->NbRows],Dimension+1);
03118 Mat->NbRows++;
03119 value_decrement(NbConstraintsLeft,NbConstraintsLeft);
03120 }
03121 }
03122 SMFree(&Sat), Sat = NULL;
03123 free(tmpC), tmpC = NULL;
03124 free(tmpR), tmpR = NULL;
03125 }
03126 }
03127
03128
03129 value_clear(p3); value_clear(NbConstraintsLeft);
03130 value_clear(tmp);
03131 for(i=0;i<NbRays;i++)
03132 value_clear(tmpR[i]);
03133 for(i=0;i<NbRays;i++)
03134 value_clear(tmpC[i]);
03135
03136 UNCATCH(any_exception_error);
03137 }
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147 static int SimplifyConstraints(Polyhedron *Pol1,Polyhedron *Pol2,unsigned *Filter,unsigned NbMaxRays) {
03148
03149 Polyhedron *Pol = NULL;
03150 Matrix *Mat = NULL, *Ray = NULL;
03151 SatMatrix *Sat = NULL;
03152 unsigned NbRay, NbCon, NbCon1, NbCon2, NbEle1, Dimension, notempty;
03153
03154 CATCH(any_exception_error) {
03155 if (Pol) Polyhedron_Free(Pol);
03156 if (Mat) Matrix_Free(Mat);
03157 if (Ray) Matrix_Free(Ray);
03158 if (Sat) SMFree(&Sat);
03159 RETHROW();
03160 }
03161 TRY {
03162
03163 NbRay = Pol1->NbRays;
03164 NbCon1 = Pol1->NbConstraints;
03165 NbCon2 = Pol2->NbConstraints;
03166 NbCon = NbCon1 + NbCon2;
03167 Dimension = Pol1->Dimension+2;
03168 NbEle1 = NbCon1*Dimension;
03169
03170
03171 if (NbMaxRays == POL_NO_DUAL)
03172 NbMaxRays = 0;
03173
03174 if (NbRay > NbMaxRays)
03175 NbMaxRays = NbRay;
03176
03177
03178 Mat = Matrix_Alloc(NbCon, Dimension);
03179 if(!Mat) {
03180 errormsg1("SimplifyConstraints", "outofmem", "out of memory space");
03181 UNCATCH(any_exception_error);
03182 return 0;
03183 }
03184
03185
03186 Vector_Copy(Pol1->Constraint[0], Mat->p_Init, NbEle1);
03187
03188
03189 Vector_Copy(Pol2->Constraint[0], Mat->p_Init+NbEle1, NbCon2*Dimension);
03190
03191
03192 Ray = Matrix_Alloc(NbMaxRays, Dimension);
03193 if(!Ray) {
03194 errormsg1("SimplifyConstraints", "outofmem", "out of memory space");
03195 UNCATCH(any_exception_error);
03196 return 0;
03197 }
03198 Ray->NbRows = NbRay;
03199
03200
03201 Vector_Copy(Pol1->Ray[0], Ray->p_Init, NbRay*Dimension);
03202
03203
03204
03205 Sat = BuildSat(Mat, Ray, NbCon1, NbMaxRays);
03206
03207
03208 Pol_status = Chernikova(Mat, Ray, Sat, Pol1->NbBid, NbMaxRays, NbCon1,0);
03209
03210
03211 Pol = Remove_Redundants(Mat, Ray, Sat, Filter);
03212 notempty = 1;
03213 if (Filter && emptyQ(Pol)) {
03214 notempty = 0;
03215 FindSimple(Pol1, Pol2, Filter, NbMaxRays);
03216 }
03217
03218
03219 Polyhedron_Free(Pol), Pol = NULL;
03220 SMFree(&Sat), Sat = NULL;
03221 Matrix_Free(Ray), Ray = NULL;
03222 Matrix_Free(Mat), Mat = NULL;
03223
03224 }
03225
03226 UNCATCH(any_exception_error);
03227 return notempty;
03228 }
03229
03230
03231
03232
03233
03234 static void SimplifyEqualities(Polyhedron *Pol1, Polyhedron *Pol2, unsigned *Filter) {
03235
03236 int i,j;
03237 unsigned ix, bx, NbEqn, NbEqn1, NbEqn2, NbEle2, Dimension;
03238 Matrix *Mat;
03239
03240 NbEqn1 = Pol1->NbEq;
03241 NbEqn2 = Pol2->NbEq;
03242 NbEqn = NbEqn1 + NbEqn2;
03243 Dimension = Pol1->Dimension+2;
03244 NbEle2 = NbEqn2*Dimension;
03245
03246 Mat = Matrix_Alloc(NbEqn, Dimension);
03247 if (!Mat) {
03248 errormsg1("SimplifyEqualities", "outofmem", "out of memory space");
03249 Pol_status = 1;
03250 return;
03251 }
03252
03253
03254 Vector_Copy(Pol2->Constraint[0], Mat->p_Init, NbEle2);
03255
03256
03257 Vector_Copy(Pol1->Constraint[0], Mat->p_Init+NbEle2, NbEqn1*Dimension);
03258
03259 Gauss(Mat, NbEqn2, Dimension-1);
03260
03261 ix = 0;
03262 bx = MSB;
03263 for (i=NbEqn2; i<NbEqn; i++) {
03264 for (j=1; j<Dimension; j++) {
03265 if (value_notzero_p(Mat->p[i][j])) {
03266
03267
03268
03269 Filter[ix] |= bx;
03270 break;
03271 }
03272 }
03273 NEXT(ix,bx);
03274 }
03275 Matrix_Free(Mat);
03276 return;
03277 }
03278
03279
03280
03281
03282
03283
03284
03285
03286
03287 Polyhedron *DomainSimplify(Polyhedron *Pol1, Polyhedron *Pol2, unsigned NbMaxRays) {
03288
03289 Polyhedron *p1, *p2, *p3, *d;
03290 unsigned k, jx, bx, nbentries, NbConstraints, Dimension, NbCon, empty;
03291 unsigned *Filter;
03292 Matrix *Constraints;
03293
03294
03295 if (!Pol1 || !Pol2) return Pol1;
03296 if (Pol1->Dimension != Pol2->Dimension) {
03297 errormsg1("DomSimplify","diffdim","operation on different dimensions");
03298 Pol_status = 1;
03299 return 0;
03300 }
03301 POL_ENSURE_VERTICES(Pol1);
03302 POL_ENSURE_VERTICES(Pol2);
03303 if (emptyQ(Pol1)||emptyQ(Pol2))
03304 return Empty_Polyhedron(Pol1->Dimension);
03305
03306
03307
03308 NbCon = 0;
03309 for (p2=Pol2; p2; p2=p2->next)
03310 if (p2->NbConstraints > NbCon)
03311 NbCon = p2->NbConstraints;
03312
03313 Dimension = Pol1->Dimension+2;
03314 d = (Polyhedron *)0;
03315 for (p1=Pol1; p1; p1=p1->next) {
03316
03317
03318
03319
03320
03321
03322 NbConstraints = p1->NbConstraints;
03323 nbentries = (NbConstraints + NbCon - 1) / (sizeof(int)*8) + 1;
03324
03325
03326 Filter = (unsigned *)malloc(nbentries * sizeof(int));
03327 if (!Filter) {
03328 errormsg1("DomSimplify", "outofmem", "out of memory space\n");
03329 Pol_status = 1;
03330 return 0;
03331 }
03332
03333
03334 SMVector_Init(Filter, nbentries);
03335
03336
03337 empty = 1;
03338 for (p2=Pol2; p2; p2=p2->next) {
03339
03340
03341
03342
03343
03344
03345 SimplifyEqualities(p1, p2, Filter);
03346 if (SimplifyConstraints(p1, p2, Filter, NbMaxRays))
03347 empty=0;
03348
03349
03350 }
03351
03352 if (!empty) {
03353
03354
03355 Constraints = Matrix_Alloc(NbConstraints, Dimension);
03356 if (!Constraints) {
03357 errormsg1("DomSimplify", "outofmem", "out of memory space\n");
03358 Pol_status = 1;
03359 return 0;
03360 }
03361 Constraints->NbRows = 0;
03362 for (k=0, jx=0, bx=MSB; k<NbConstraints; k++) {
03363
03364
03365
03366 if (Filter[jx]&bx) {
03367 Vector_Copy(p1->Constraint[k],
03368 Constraints->p[Constraints->NbRows],
03369 Dimension);
03370 Constraints->NbRows++;
03371 }
03372 NEXT(jx,bx);
03373 }
03374
03375
03376
03377 p3 = Constraints2Polyhedron(Constraints,NbMaxRays);
03378 Matrix_Free(Constraints);
03379
03380
03381 d = AddPolyToDomain (p3, d);
03382 p3 = NULL;
03383 }
03384 free(Filter);
03385 }
03386 if (!d)
03387 return Empty_Polyhedron(Pol1->Dimension);
03388 else return d;
03389
03390 }
03391
03392
03393
03394
03395 Polyhedron *Stras_DomainSimplify(Polyhedron *Pol1,Polyhedron *Pol2,unsigned NbMaxRays) {
03396
03397 Polyhedron *p1, *p2, *p3 = NULL, *d = NULL;
03398 unsigned k, jx, bx, nbentries, NbConstraints, Dimension, NbCon, empty;
03399 unsigned *Filter = NULL;
03400 Matrix *Constraints = NULL;
03401
03402 CATCH(any_exception_error) {
03403 if (Constraints) Matrix_Free(Constraints);
03404 if (Filter) free(Filter);
03405 if (d) Polyhedron_Free(d);
03406 if (p2) Polyhedron_Free(p3);
03407 RETHROW();
03408 }
03409 TRY {
03410 if (!Pol1 || !Pol2) {
03411 UNCATCH(any_exception_error);
03412 return Pol1;
03413 }
03414 if (Pol1->Dimension != Pol2->Dimension) {
03415 errormsg1("DomainSimplify","diffdim","operation on different dimensions");
03416 UNCATCH(any_exception_error);
03417 return 0;
03418 }
03419 POL_ENSURE_VERTICES(Pol1);
03420 POL_ENSURE_VERTICES(Pol2);
03421 if (emptyQ(Pol1)||emptyQ(Pol2)) {
03422 UNCATCH(any_exception_error);
03423 return Empty_Polyhedron(Pol1->Dimension);
03424 }
03425
03426
03427
03428 NbCon = 0;
03429 for (p2=Pol2; p2; p2=p2->next)
03430 if (p2->NbConstraints > NbCon)
03431 NbCon = p2->NbConstraints;
03432
03433 Dimension = Pol1->Dimension+2;
03434 d = (Polyhedron *)0;
03435 for (p1=Pol1; p1; p1=p1->next) {
03436
03437
03438
03439
03440
03441
03442 NbConstraints = p1->NbConstraints;
03443 nbentries = (NbConstraints + NbCon - 1)/(sizeof(int)*8) + 1;
03444
03445
03446 Filter = (unsigned *)malloc(nbentries * sizeof(int));
03447 if(!Filter) {
03448 errormsg1("DomainSimplify", "outofmem", "out of memory space");
03449 UNCATCH(any_exception_error);
03450 return 0;
03451 }
03452
03453
03454 SMVector_Init(Filter, nbentries);
03455
03456
03457 empty = 1;
03458 for (p2=Pol2; p2; p2=p2->next) {
03459
03460
03461
03462
03463
03464
03465 if (SimplifyConstraints(p1, p2, Filter, NbMaxRays))
03466 empty=0;
03467 }
03468
03469 if (!empty) {
03470
03471
03472 Constraints = Matrix_Alloc(NbConstraints,Dimension);
03473 if(!Constraints) {
03474 errormsg1("DomainSimplify", "outofmem", "out of memory space");
03475 UNCATCH(any_exception_error);
03476 return 0;
03477 }
03478 Constraints->NbRows = 0;
03479 for (k=0, jx=0, bx=MSB; k<NbConstraints; k++) {
03480
03481
03482
03483 if (Filter[jx]&bx) {
03484 Vector_Copy(p1->Constraint[k],
03485 Constraints->p[Constraints->NbRows],
03486 Dimension);
03487 Constraints->NbRows++;
03488 }
03489 NEXT(jx,bx);
03490 }
03491
03492
03493
03494 p3 = Constraints2Polyhedron(Constraints,NbMaxRays);
03495 Matrix_Free(Constraints), Constraints = NULL;
03496
03497
03498 d = AddPolyToDomain (p3, d);
03499 p3 = NULL;
03500 }
03501 free(Filter), Filter = NULL;
03502 }
03503 }
03504
03505 UNCATCH(any_exception_error);
03506 if (!d)
03507 return Empty_Polyhedron(Pol1->Dimension);
03508 else
03509 return d;
03510 }
03511
03512
03513
03514
03515
03516 Polyhedron *DomainUnion(Polyhedron *Pol1,Polyhedron *Pol2,unsigned NbMaxRays) {
03517
03518 Polyhedron *PolA, *PolEndA, *PolB, *PolEndB, *p1, *p2;
03519 int Redundant;
03520
03521 if (!Pol1 || !Pol2) return (Polyhedron *) 0;
03522 if (Pol1->Dimension != Pol2->Dimension) {
03523 errormsg1("DomainUnion","diffdim","operation on different dimensions");
03524 return (Polyhedron*) 0;
03525 }
03526
03527
03528
03529
03530
03531
03532
03533 PolA = PolEndA = (Polyhedron *)0;
03534 for (p1=Pol1; p1; p1=p1->next) {
03535
03536
03537 Redundant = 0;
03538 for (p2=Pol2; p2; p2=p2->next) {
03539 if (PolyhedronIncludes(p2, p1) ) {
03540 Redundant = 1;
03541
03542
03543 break;
03544
03545 }
03546 }
03547 if (!Redundant) {
03548
03549
03550 if (!PolEndA)
03551 PolEndA = PolA = Polyhedron_Copy(p1);
03552 else {
03553 PolEndA->next = Polyhedron_Copy(p1);
03554 PolEndA = PolEndA->next;
03555 }
03556
03557 }
03558 }
03559
03560
03561 PolB = PolEndB = (Polyhedron *)0;
03562 for (p2=Pol2; p2; p2=p2->next) {
03563
03564
03565 Redundant = 0;
03566 for (p1=PolA; p1; p1=p1->next) {
03567 if (PolyhedronIncludes(p1, p2)) {
03568 Redundant = 1;
03569 break;
03570 }
03571 }
03572 if (!Redundant) {
03573
03574
03575 if (!PolEndB)
03576 PolEndB = PolB = Polyhedron_Copy(p2);
03577 else {
03578 PolEndB->next = Polyhedron_Copy(p2);
03579 PolEndB = PolEndB->next;
03580 }
03581
03582
03583 }
03584 }
03585
03586 if (!PolA) return PolB;
03587 PolEndA->next = PolB;
03588 return PolA;
03589 }
03590
03591
03592
03593
03594
03595
03596
03597 Polyhedron *DomainConvex(Polyhedron *Pol,unsigned NbMaxConstrs) {
03598
03599 Polyhedron *p, *q, *NewPol = NULL;
03600
03601 CATCH(any_exception_error) {
03602 if (NewPol) Polyhedron_Free(NewPol);
03603 RETHROW();
03604 }
03605 TRY {
03606
03607 if (!Pol) {
03608 UNCATCH(any_exception_error);
03609 return (Polyhedron*) 0;
03610 }
03611
03612 NewPol = Polyhedron_Copy(Pol);
03613 for (p=Pol->next; p; p=p->next) {
03614 q = AddRays(p->Ray[0], p->NbRays, NewPol, NbMaxConstrs);
03615 Polyhedron_Free(NewPol);
03616 NewPol = q;
03617 }
03618 }
03619
03620 UNCATCH(any_exception_error);
03621
03622 return NewPol;
03623 }
03624
03625
03626
03627
03628
03629 Polyhedron *DomainDifference(Polyhedron *Pol1,Polyhedron *Pol2,unsigned NbMaxRays) {
03630
03631 Polyhedron *p1, *p2, *p3, *d;
03632 int i;
03633
03634 if (!Pol1 || !Pol2) return (Polyhedron*) 0;
03635 if (Pol1->Dimension != Pol2->Dimension) {
03636 errormsg1("DomainDifference",
03637 "diffdim", "operation on different dimensions");
03638 return (Polyhedron*) 0;
03639 }
03640 POL_ENSURE_FACETS(Pol1);
03641 POL_ENSURE_VERTICES(Pol1);
03642 POL_ENSURE_FACETS(Pol2);
03643 POL_ENSURE_VERTICES(Pol2);
03644 if (emptyQ(Pol1) || emptyQ(Pol2))
03645 return (Domain_Copy(Pol1));
03646 d = (Polyhedron *)0;
03647 for (p2=Pol2; p2; p2=p2->next) {
03648 for (p1=Pol1; p1; p1=p1->next) {
03649 for (i=0; i<p2->NbConstraints; i++) {
03650
03651
03652
03653 p3 = SubConstraint(p2->Constraint[i], p1, NbMaxRays,0);
03654
03655
03656 d = AddPolyToDomain (p3, d);
03657
03658
03659
03660
03661
03662 if( value_notzero_p(p2->Constraint[i][0]) )
03663 continue;
03664 p3 = SubConstraint(p2->Constraint[i], p1, NbMaxRays,1);
03665
03666
03667 d = AddPolyToDomain (p3, d);
03668 }
03669 }
03670 if (p2 != Pol2)
03671 Domain_Free(Pol1);
03672 Pol1 = d;
03673 d = (Polyhedron *)0;
03674 }
03675 if (!Pol1)
03676 return Empty_Polyhedron(Pol2->Dimension);
03677 else
03678 return Pol1;
03679 }
03680
03681
03682
03683
03684
03685
03686 Polyhedron *align_context(Polyhedron *Pol,int align_dimension,int NbMaxRays) {
03687
03688 int i, j, k;
03689 Polyhedron *p = NULL, **next, *result = NULL;
03690
03691 CATCH(any_exception_error) {
03692 if (result) Polyhedron_Free(result);
03693 RETHROW();
03694 }
03695 TRY {
03696
03697 if (!Pol) return Pol;
03698 if (align_dimension < Pol->Dimension) {
03699 errormsg1("align_context", "diffdim", "context dimension exceeds data");
03700 UNCATCH(any_exception_error);
03701 return Pol;
03702 }
03703 if (align_dimension == Pol->Dimension) {
03704 UNCATCH(any_exception_error);
03705 return Polyhedron_Copy(Pol);
03706 }
03707
03708
03709 k = align_dimension - Pol->Dimension;
03710 next = &result;
03711
03712
03713 for (; Pol; Pol=Pol->next) {
03714 int have_cons = !F_ISSET(Pol, POL_VALID) || F_ISSET(Pol, POL_INEQUALITIES);
03715 int have_rays = !F_ISSET(Pol, POL_VALID) || F_ISSET(Pol, POL_POINTS);
03716 unsigned NbCons = have_cons ? Pol->NbConstraints : 0;
03717 unsigned NbRays = have_rays ? Pol->NbRays + k : 0;
03718
03719 p = Polyhedron_Alloc(align_dimension, NbCons, NbRays);
03720 if (have_cons) {
03721 for (i = 0; i < NbCons; ++i) {
03722 value_assign(p->Constraint[i][0], Pol->Constraint[i][0]);
03723 Vector_Copy(Pol->Constraint[i]+1, p->Constraint[i]+k+1, Pol->Dimension+1);
03724 }
03725 p->NbEq = Pol->NbEq;
03726 }
03727
03728 if (have_rays) {
03729 for (i = 0; i < k; ++i)
03730 value_set_si(p->Ray[i][1+i], 1);
03731 for (i = 0; i < Pol->NbRays; ++i) {
03732 value_assign(p->Ray[k+i][0], Pol->Ray[i][0]);
03733 Vector_Copy(Pol->Ray[i]+1, p->Ray[i+k]+k+1, Pol->Dimension+1);
03734 }
03735 p->NbBid = Pol->NbBid + k;
03736 }
03737 p->flags = Pol->flags;
03738
03739 *next = p;
03740 next = &p->next;
03741 }
03742 }
03743
03744 UNCATCH(any_exception_error);
03745 return result;
03746 }
03747
03748
03749
03750
03751
03752
03753
03754
03755 Polyhedron *Polyhedron_Scan(Polyhedron *D, Polyhedron *C,unsigned NbMaxRays) {
03756
03757 int i, j, dim ;
03758 Matrix *Mat;
03759 Polyhedron *C1, *C2, *D1, *D2;
03760 Polyhedron *res, *last, *tmp;
03761
03762 dim = D->Dimension - C->Dimension;
03763 res = last = (Polyhedron *) 0;
03764 if (dim==0) return (Polyhedron *)0;
03765
03766 POL_ENSURE_FACETS(D);
03767 POL_ENSURE_VERTICES(D);
03768 POL_ENSURE_FACETS(C);
03769 POL_ENSURE_VERTICES(C);
03770
03771
03772 Mat = Matrix_Alloc(D->Dimension, D->Dimension+2);
03773 if(!Mat) {
03774 errormsg1("Polyhedron_Scan", "outofmem", "out of memory space");
03775 return 0;
03776 }
03777 C1 = align_context(C,D->Dimension,NbMaxRays);
03778 if(!C1) {
03779 return 0;
03780 }
03781
03782 D2 = DomainIntersection( C1, D, NbMaxRays);
03783
03784 for (i=0; i<dim; i++)
03785 {
03786 Vector_Set(Mat->p_Init,0,D2->Dimension*(D2->Dimension + 2));
03787 for (j=i+1; j<dim; j++) {
03788 value_set_si(Mat->p[j-i-1][j+1],1);
03789 }
03790 Mat->NbRows = dim-i-1;
03791 D1 = Mat->NbRows ? DomainAddRays(D2, Mat, NbMaxRays) : D2;
03792 tmp = DomainSimplify(D1, C1, NbMaxRays);
03793 if (!last) res = last = tmp;
03794 else { last->next = tmp; last = tmp; }
03795 C2 = DomainIntersection(C1, D1, NbMaxRays);
03796 Domain_Free(C1);
03797 C1 = C2;
03798 if (Mat->NbRows) Domain_Free(D1);
03799 }
03800 Domain_Free(D2);
03801 Domain_Free(C1);
03802 Matrix_Free(Mat);
03803 return res;
03804 }
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815 int lower_upper_bounds(int pos,Polyhedron *P,Value *context,Value *LBp,Value *UBp) {
03816
03817 Value LB, UB;
03818 int flag, i;
03819 Value n, n1, d, tmp;
03820
03821 POL_ENSURE_FACETS(P);
03822 POL_ENSURE_VERTICES(P);
03823
03824
03825 value_init(LB); value_init(UB); value_init(tmp);
03826 value_init(n); value_init(n1); value_init(d);
03827
03828 value_set_si(LB,0);
03829 value_set_si(UB,0);
03830
03831
03832 flag = LB_INFINITY | UB_INFINITY;
03833 for (i=0; i<P->NbConstraints; i++) {
03834 value_assign(d,P->Constraint[i][pos]);
03835 if (value_zero_p(d)) continue;
03836 Inner_Product(&context[1],&(P->Constraint[i][1]),P->Dimension+1,&n);
03837 value_oppose(n,n);
03838
03839
03840
03841
03842
03843
03844
03845
03846
03847
03848
03849
03850
03851 if(value_zero_p(P->Constraint[i][0])) {
03852 value_modulus(tmp,n,d);
03853
03854
03855 if(value_notzero_p(tmp)) {
03856 value_set_si(*LBp,1);
03857 value_set_si(*UBp,0);
03858
03859
03860 value_clear(LB); value_clear(UB); value_clear(tmp);
03861 value_clear(n); value_clear(n1); value_clear(d);
03862 return 0;
03863 }
03864 value_division(n1,n,d);
03865
03866
03867 if((flag&LB_INFINITY) || value_gt(n1,LB))
03868 value_assign(LB,n1);
03869 if((flag&UB_INFINITY) || value_lt(n1,UB))
03870 value_assign(UB,n1);
03871 flag = 0;
03872 }
03873
03874 if (value_pos_p(d)) {
03875 value_modulus(tmp,n,d);
03876
03877
03878 if (value_pos_p(n) && value_notzero_p(tmp)) {
03879 value_division(n1,n,d);
03880 value_add_int(n1,n1,1);
03881 }
03882 else
03883 value_division(n1,n,d);
03884 if (flag&LB_INFINITY) {
03885 value_assign(LB,n1);
03886 flag^=LB_INFINITY;
03887 }
03888 else if(value_gt(n1,LB))
03889 value_assign(LB,n1);
03890 }
03891
03892 if (value_neg_p(d)) {
03893 value_modulus(tmp,n,d);
03894
03895
03896 if (value_pos_p(n) && value_notzero_p(tmp)) {
03897 value_division(n1,n,d);
03898 value_sub_int(n1,n1,1);
03899 }
03900 else
03901 value_division(n1,n,d);
03902
03903 if (flag&UB_INFINITY) {
03904 value_assign(UB,n1);
03905 flag^=UB_INFINITY;
03906 }
03907 else if (value_lt(n1,UB))
03908 value_assign(UB, n1);
03909 }
03910 }
03911 if ((flag & LB_INFINITY)==0) value_assign(*LBp,LB);
03912 if ((flag & UB_INFINITY)==0) value_assign(*UBp,UB);
03913
03914
03915 value_clear(LB); value_clear(UB); value_clear(tmp);
03916 value_clear(n); value_clear(n1); value_clear(d);
03917 return flag;
03918 }
03919
03920
03921
03922
03923 static void Rays_Mult(Value **A, Matrix *B, Value **C, unsigned NbRays)
03924 {
03925 int i, j, k;
03926 unsigned Dimension1, Dimension2;
03927 Value Sum, tmp;
03928
03929 value_init(Sum); value_init(tmp);
03930
03931 CATCH(any_exception_error) {
03932 value_clear(Sum); value_clear(tmp);
03933 RETHROW();
03934 }
03935 TRY {
03936 Dimension1 = B->NbRows;
03937 Dimension2 = B->NbColumns;
03938
03939 for (i=0; i<NbRays; i++) {
03940 value_assign(C[i][0],A[i][0]);
03941 for (j=0; j<Dimension2; j++) {
03942 value_set_si(Sum,0);
03943 for (k=0; k<Dimension1; k++) {
03944
03945
03946 value_addmul(Sum, A[i][k+1], B->p[k][j]);
03947 }
03948 value_assign(C[i][j+1],Sum);
03949 }
03950 Vector_Gcd(C[i]+1, Dimension2, &tmp);
03951 if (value_notone_p(tmp))
03952 Vector_AntiScale(C[i]+1, C[i]+1, tmp, Dimension2);
03953 }
03954 }
03955 UNCATCH(any_exception_error);
03956 value_clear(Sum); value_clear(tmp);
03957 }
03958
03959
03960
03961
03962 static void Rays_Mult_Transpose(Value **A, Matrix *B, Value **C,
03963 unsigned NbRays)
03964 {
03965 int i, j, k;
03966 unsigned Dimension1, Dimension2;
03967 Value Sum, tmp;
03968
03969 value_init(Sum); value_init(tmp);
03970
03971 CATCH(any_exception_error) {
03972 value_clear(Sum); value_clear(tmp);
03973 RETHROW();
03974 }
03975 TRY {
03976 Dimension1 = B->NbColumns;
03977 Dimension2 = B->NbRows;
03978
03979 for (i=0; i<NbRays; i++) {
03980 value_assign(C[i][0],A[i][0]);
03981 for (j=0; j<Dimension2; j++) {
03982 value_set_si(Sum,0);
03983 for (k=0; k<Dimension1; k++) {
03984
03985
03986 value_addmul(Sum, A[i][k+1], B->p[j][k]);
03987 }
03988 value_assign(C[i][j+1],Sum);
03989 }
03990 Vector_Gcd(C[i]+1, Dimension2, &tmp);
03991 if (value_notone_p(tmp))
03992 Vector_AntiScale(C[i]+1, C[i]+1, tmp, Dimension2);
03993 }
03994 }
03995 UNCATCH(any_exception_error);
03996 value_clear(Sum); value_clear(tmp);
03997 }
03998
03999
04000
04001
04002
04003
04004
04005 Polyhedron *Polyhedron_Preimage(Polyhedron *Pol,Matrix *Func,unsigned NbMaxRays) {
04006
04007 Matrix *Constraints = NULL;
04008 Polyhedron *NewPol = NULL;
04009 unsigned NbConstraints, Dimension1, Dimension2;
04010
04011 POL_ENSURE_FACETS(Pol);
04012 POL_ENSURE_VERTICES(Pol);
04013
04014 CATCH(any_exception_error) {
04015 if (Constraints) Matrix_Free(Constraints);
04016 if (NewPol) Polyhedron_Free(NewPol);
04017 RETHROW();
04018 }
04019 TRY {
04020
04021 NbConstraints = Pol->NbConstraints;
04022 Dimension1 = Pol->Dimension+1;
04023 Dimension2 = Func->NbColumns;
04024 if (Dimension1!=(Func->NbRows)) {
04025 errormsg1("Polyhedron_Preimage", "dimincomp", "incompatable dimensions");
04026 UNCATCH(any_exception_error);
04027 return Empty_Polyhedron(Dimension2-1);
04028 }
04029
04030
04031
04032
04033
04034
04035
04036
04037
04038 Constraints = Matrix_Alloc(NbConstraints, Dimension2+1);
04039 if (!Constraints) {
04040 errormsg1("Polyhedron_Preimage", "outofmem", "out of memory space\n");
04041 Pol_status = 1;
04042 UNCATCH(any_exception_error);
04043 return 0;
04044 }
04045
04046
04047
04048 Rays_Mult(Pol->Constraint, Func, Constraints->p, NbConstraints);
04049 NewPol = Constraints2Polyhedron(Constraints, NbMaxRays);
04050 Matrix_Free(Constraints), Constraints = NULL;
04051
04052 }
04053
04054 UNCATCH(any_exception_error);
04055
04056 return NewPol;
04057 }
04058
04059
04060
04061
04062
04063
04064
04065 Polyhedron *DomainPreimage(Polyhedron *Pol,Matrix *Func,unsigned NbMaxRays) {
04066
04067 Polyhedron *p, *q, *d = NULL;
04068
04069 CATCH(any_exception_error) {
04070 if (d) Polyhedron_Free(d);
04071 RETHROW();
04072 }
04073 TRY {
04074 if (!Pol || !Func) {
04075 UNCATCH(any_exception_error);
04076 return (Polyhedron *) 0;
04077 }
04078 d = (Polyhedron *) 0;
04079 for (p=Pol; p; p=p->next) {
04080 q = Polyhedron_Preimage(p, Func, NbMaxRays);
04081 d = AddPolyToDomain (q, d);
04082 }
04083 }
04084 UNCATCH(any_exception_error);
04085 return d;
04086 }
04087
04088
04089
04090
04091
04092
04093 Polyhedron *Polyhedron_Image(Polyhedron *Pol, Matrix *Func,unsigned NbMaxConstrs) {
04094
04095 Matrix *Rays = NULL;
04096 Polyhedron *NewPol = NULL;
04097 unsigned NbRays, Dimension1, Dimension2;
04098
04099 POL_ENSURE_FACETS(Pol);
04100 POL_ENSURE_VERTICES(Pol);
04101
04102 CATCH(any_exception_error) {
04103 if (Rays) Matrix_Free(Rays);
04104 if (NewPol) Polyhedron_Free(NewPol);
04105 RETHROW();
04106 }
04107 TRY {
04108
04109 NbRays = Pol->NbRays;
04110 Dimension1 = Pol->Dimension+1;
04111 Dimension2 = Func->NbRows;
04112 if (Dimension1!=Func->NbColumns) {
04113 errormsg1("Polyhedron_Image", "dimincomp", "incompatible dimensions");
04114 UNCATCH(any_exception_error);
04115 return Empty_Polyhedron(Dimension2-1);
04116 }
04117
04118
04119
04120
04121
04122
04123
04124
04125
04126
04127 if (Dimension1 == Dimension2) {
04128 Matrix *M, *M2;
04129 int ok;
04130 M = Matrix_Copy(Func);
04131 M2 = Matrix_Alloc(Dimension2, Dimension1);
04132 if (!M2) {
04133 errormsg1("Polyhedron_Image", "outofmem", "out of memory space\n");
04134 UNCATCH(any_exception_error);
04135 return 0;
04136 }
04137
04138 ok = Matrix_Inverse(M, M2);
04139 Matrix_Free(M);
04140 if (ok) {
04141 NewPol = Polyhedron_Alloc(Pol->Dimension, Pol->NbConstraints,
04142 Pol->NbRays);
04143 if (!NewPol) {
04144 errormsg1("Polyhedron_Image", "outofmem",
04145 "out of memory space\n");
04146 UNCATCH(any_exception_error);
04147 return 0;
04148 }
04149 Rays_Mult_Transpose(Pol->Ray, Func, NewPol->Ray, NbRays);
04150 Rays_Mult(Pol->Constraint, M2, NewPol->Constraint,
04151 Pol->NbConstraints);
04152 NewPol->NbEq = Pol->NbEq;
04153 NewPol->NbBid = Pol->NbBid;
04154 if (NewPol->NbEq)
04155 Gauss4(NewPol->Constraint, NewPol->NbEq, NewPol->NbConstraints,
04156 NewPol->Dimension+1);
04157 if (NewPol->NbBid)
04158 Gauss4(NewPol->Ray, NewPol->NbBid, NewPol->NbRays,
04159 NewPol->Dimension+1);
04160 }
04161 Matrix_Free(M2);
04162 }
04163
04164 if (!NewPol) {
04165
04166 Rays = Matrix_Alloc(NbRays, Dimension2+1);
04167 if (!Rays) {
04168 errormsg1("Polyhedron_Image", "outofmem", "out of memory space\n");
04169 UNCATCH(any_exception_error);
04170 return 0;
04171 }
04172
04173
04174
04175 Rays_Mult_Transpose(Pol->Ray, Func, Rays->p, NbRays);
04176 NewPol = Rays2Polyhedron(Rays, NbMaxConstrs);
04177 Matrix_Free(Rays), Rays = NULL;
04178 }
04179
04180 }
04181
04182 UNCATCH(any_exception_error);
04183 return NewPol;
04184 }
04185
04186
04187
04188
04189
04190
04191 Polyhedron *DomainImage(Polyhedron *Pol,Matrix *Func,unsigned NbMaxConstrs) {
04192
04193 Polyhedron *p, *q, *d = NULL;
04194
04195 CATCH(any_exception_error) {
04196 if (d) Polyhedron_Free(d);
04197 RETHROW();
04198 }
04199 TRY {
04200
04201 if (!Pol || !Func) {
04202 UNCATCH(any_exception_error);
04203 return (Polyhedron *) 0;
04204 }
04205 d = (Polyhedron *) 0;
04206 for (p=Pol; p; p=p->next) {
04207 q = Polyhedron_Image(p, Func, NbMaxConstrs);
04208 d = AddPolyToDomain (q, d);
04209 }
04210 }
04211
04212 UNCATCH(any_exception_error);
04213
04214 return d;
04215 }
04216
04217
04218
04219
04220
04221
04222
04223
04224
04225
04226
04227 Interval *DomainCost(Polyhedron *Pol,Value *Cost) {
04228
04229 int i, j, NbRay, Dim;
04230 Value *p1, *p2, p3, d, status;
04231 Value tmp1, tmp2, tmp3;
04232 Value **Ray;
04233 Interval *I = NULL;
04234
04235 value_init(p3); value_init(d); value_init(status);
04236 value_init(tmp1); value_init(tmp2); value_init(tmp3);
04237
04238 POL_ENSURE_FACETS(Pol);
04239 POL_ENSURE_VERTICES(Pol);
04240
04241 CATCH(any_exception_error) {
04242 if (I) free(I);
04243 RETHROW();
04244 value_clear(p3); value_clear(d); value_clear(status);
04245 value_clear(tmp1); value_clear(tmp2); value_clear(tmp3);
04246 }
04247 TRY {
04248
04249 Ray = Pol->Ray;
04250 NbRay = Pol->NbRays;
04251 Dim = Pol->Dimension+1;
04252 I = (Interval *) malloc (sizeof(Interval));
04253 if (!I) {
04254 errormsg1("DomainCost", "outofmem", "out of memory space\n");
04255 UNCATCH(any_exception_error);
04256 value_clear(p3); value_clear(d); value_clear(status);
04257 value_clear(tmp1); value_clear(tmp2); value_clear(tmp3);
04258 return 0;
04259 }
04260
04261
04262
04263
04264
04265
04266
04267
04268 value_set_si(I->MaxN,-1);
04269 value_set_si(I->MaxD,0);
04270 I->MaxI = -1;
04271 value_set_si(I->MinN,1);
04272 value_set_si(I->MinD,0);
04273 I->MinI = -1;
04274
04275
04276 for (i=0; i<NbRay; i++) {
04277 p1 = Ray[i];
04278 value_assign(status, *p1);
04279 p1++;
04280 p2 = Cost;
04281
04282
04283 value_multiply(p3,*p1,*p2);
04284 p1++; p2++;
04285 for (j=1; j<Dim; j++) {
04286 value_multiply(tmp1,*p1,*p2);
04287
04288
04289 value_addto(p3,p3,tmp1);
04290 p1++; p2++;
04291 }
04292
04293
04294 p1--;
04295 value_assign(d,*p1);
04296 value_multiply(tmp1,p3,I->MaxD);
04297 value_multiply(tmp2,I->MaxN,d);
04298 value_set_si(tmp3,1);
04299
04300
04301 if (I->MaxI==-1 ||
04302 value_gt(tmp1,tmp2) ||
04303 (value_eq(tmp1,tmp2) &&
04304 value_eq(d,tmp3) && value_ne(I->MaxD,tmp3))) {
04305 value_assign(I->MaxN,p3);
04306 value_assign(I->MaxD,d);
04307 I->MaxI = i;
04308 }
04309 value_multiply(tmp1,p3,I->MinD);
04310 value_multiply(tmp2,I->MinN,d);
04311 value_set_si(tmp3,1);
04312
04313
04314 if (I->MinI==-1 ||
04315 value_lt(tmp1,tmp2) ||
04316 (value_eq(tmp1,tmp2) &&
04317 value_eq(d,tmp3) && value_ne(I->MinD,tmp3))) {
04318 value_assign(I->MinN, p3);
04319 value_assign(I->MinD, d);
04320 I->MinI = i;
04321 }
04322 value_multiply(tmp1,p3,I->MaxD);
04323 value_set_si(tmp2,0);
04324
04325
04326 if (value_zero_p(status)) {
04327 if (value_lt(tmp1,tmp2)) {
04328 value_oppose(I->MaxN,p3);
04329 value_set_si(I->MaxD,0);
04330 I->MaxI = i;
04331 }
04332 value_multiply(tmp1,p3,I->MinD);
04333 value_set_si(tmp2,0);
04334
04335 if (value_gt(tmp1,tmp2)) {
04336 value_oppose(I->MinN,p3);
04337 value_set_si(I->MinD,0);
04338 I->MinI = i;
04339 }
04340 }
04341 }
04342 }
04343
04344 UNCATCH(any_exception_error);
04345 value_clear(p3); value_clear(d); value_clear(status);
04346 value_clear(tmp1); value_clear(tmp2); value_clear(tmp3);
04347 return I;
04348 }
04349
04350
04351
04352
04353
04354
04355 Polyhedron *DomainAddConstraints(Polyhedron *Pol,Matrix *Mat,unsigned NbMaxRays) {
04356
04357 Polyhedron *PolA, *PolEndA, *p1, *p2, *p3;
04358 int Redundant;
04359
04360 if (!Pol) return (Polyhedron*) 0;
04361 if (!Mat) return Pol;
04362 if (Pol->Dimension != Mat->NbColumns-2) {
04363 errormsg1("DomainAddConstraints",
04364 "diffdim", "operation on different dimensions");
04365 return (Polyhedron*) 0;
04366 }
04367
04368
04369 PolA = PolEndA = (Polyhedron *)0;
04370 for (p1=Pol; p1; p1=p1->next) {
04371 p3 = AddConstraints(Mat->p_Init, Mat->NbRows, p1, NbMaxRays);
04372
04373
04374 Redundant = 0;
04375 for (p2=PolA; p2; p2=p2->next) {
04376 if (PolyhedronIncludes(p2, p3)) {
04377 Redundant = 1;
04378 break;
04379 }
04380 }
04381
04382
04383 if (!Redundant) {
04384
04385
04386 if (!PolEndA)
04387 PolEndA = PolA = p3;
04388 else {
04389 PolEndA->next = p3;
04390 PolEndA = PolEndA->next;
04391 }
04392 }
04393 }
04394 return PolA;
04395 }
04396
04397
04398
04399
04400
04401
04402
04403
04404
04405
04406
04407
04408 Polyhedron *Disjoint_Domain( Polyhedron *P, int flag, unsigned NbMaxRays )
04409 {
04410 Polyhedron *lP, *tmp, *Result, *lR, *prec, *reste;
04411 Polyhedron *p1, *p2, *p3, *Pol1, *dx, *d1, *d2, *pi, *newpi;
04412 int i;
04413
04414 if( flag!=0 && flag!=1 )
04415 {
04416 errormsg1("Disjoint_Domain",
04417 "invalidarg", "flag should be equal to 0 or 1");
04418 return (Polyhedron*) 0;
04419 }
04420 if(!P) return (Polyhedron*) 0;
04421 if(!P->next) return Polyhedron_Copy(P);
04422
04423 Result = (Polyhedron *)0;
04424
04425 for(lP=P;lP;lP=lP->next)
04426 {
04427 reste = Polyhedron_Copy(lP);
04428 prec = (Polyhedron *)0;
04429
04430 lR=Result;
04431 while( lR && reste )
04432 {
04433
04434 dx = (Polyhedron *)0;
04435 for( p1=reste; p1; p1=p1->next )
04436 {
04437 p3 = AddConstraints(lR->Constraint[0], lR->NbConstraints, p1,
04438 NbMaxRays);
04439 dx = AddPolyToDomain(p3,dx);
04440 }
04441
04442
04443 if(!dx)
04444 { prec = lR;
04445 lR=lR->next;
04446 continue;
04447 }
04448 if (emptyQ(dx)) {
04449 Domain_Free(dx);
04450 prec = lR;
04451 lR=lR->next;
04452 continue;
04453 }
04454
04455
04456
04457
04458
04459
04460
04461
04462 d1 = (Polyhedron *)0;
04463 for (p1=reste; p1; p1=p1->next)
04464 {
04465 pi = p1;
04466 for (i=0; i<P->NbConstraints && pi ; i++)
04467 {
04468
04469
04470
04471 p3 = SubConstraint(P->Constraint[i], pi, NbMaxRays,2*flag);
04472
04473 d1 = AddPolyToDomain (p3, d1);
04474
04475
04476
04477
04478 if( value_zero_p(P->Constraint[i][0]) )
04479 {
04480 p3 = SubConstraint(P->Constraint[i], pi, NbMaxRays,1+2*flag);
04481
04482 d1 = AddPolyToDomain (p3, d1);
04483
04484
04485 newpi = AddConstraints( P->Constraint[i], 1, pi, NbMaxRays);
04486 }
04487 else
04488 {
04489
04490 newpi = SubConstraint(P->Constraint[i], pi, NbMaxRays,3);
04491 }
04492 if( newpi && emptyQ( newpi ) )
04493 {
04494 Domain_Free( newpi );
04495 newpi = (Polyhedron *)0;
04496 }
04497 if( pi != p1 )
04498 Domain_Free( pi );
04499 pi = newpi;
04500 }
04501 if( pi != p1 )
04502 Domain_Free( pi );
04503 }
04504
04505
04506 Pol1 = Polyhedron_Copy( lR );
04507 for (p2=reste; p2; p2=p2->next)
04508 {
04509 d2 = (Polyhedron *)0;
04510 for (p1=Pol1; p1; p1=p1->next)
04511 {
04512 pi = p1;
04513 for (i=0; i<p2->NbConstraints && pi ; i++)
04514 {
04515
04516
04517
04518 p3 = SubConstraint(p2->Constraint[i], pi, NbMaxRays,2*flag);
04519
04520 d2 = AddPolyToDomain (p3, d2);
04521
04522
04523
04524
04525 if( value_zero_p(p2->Constraint[i][0]) )
04526 {
04527 p3 = SubConstraint(p2->Constraint[i], pi, NbMaxRays,1+2*flag);
04528
04529 d2 = AddPolyToDomain (p3, d2);
04530
04531
04532 newpi = AddConstraints( p2->Constraint[i], 1, pi, NbMaxRays);
04533 }
04534 else
04535 {
04536
04537 newpi = SubConstraint(p2->Constraint[i], pi, NbMaxRays,3);
04538 }
04539 if( newpi && emptyQ( newpi ) )
04540 {
04541 Domain_Free( newpi );
04542 newpi = (Polyhedron *)0;
04543 }
04544 if( pi != p1 )
04545 Domain_Free( pi );
04546 pi = newpi;
04547 }
04548 if( pi && pi!=p1 )
04549 Domain_Free( pi );
04550 }
04551 if( Pol1 )
04552 Domain_Free( Pol1 );
04553 Pol1 = d2;
04554 }
04555
04556
04557
04558 if( d1 && emptyQ(d1) )
04559 {
04560 Domain_Free( d1 );
04561 d1 = NULL;
04562 }
04563 if( d2 && emptyQ(d2) )
04564 {
04565 Domain_Free( d2 );
04566 d2 = NULL;
04567 }
04568
04569
04570 Domain_Free( reste );
04571 reste = d1;
04572
04573
04574 if( d2 )
04575 {
04576 for( tmp=d2 ; tmp->next ; tmp=tmp->next )
04577 ;
04578 tmp->next = Result;
04579 Result = d2;
04580 if( !prec )
04581 prec = tmp;
04582 }
04583
04584
04585 for( tmp=dx ; tmp->next ; tmp=tmp->next )
04586 ;
04587 tmp->next = Result;
04588 Result = dx;
04589 if( !prec )
04590 prec = tmp;
04591
04592
04593 if( !prec )
04594 errormsg1( "Disjoint_Domain","internalerror","internal error");
04595 prec->next = lR->next;
04596 Polyhedron_Free( lR );
04597 lR = prec->next;
04598 }
04599
04600
04601 if(reste)
04602 {
04603 if(emptyQ(reste))
04604 {
04605 Domain_Free( reste );
04606 reste = NULL;
04607 }
04608 else
04609 {
04610 Polyhedron *tnext;
04611 for( tmp=reste ; tmp ; tmp=tnext )
04612 {
04613 tnext = tmp->next;
04614 tmp->next = NULL;
04615 Result = AddPolyToDomain(tmp, Result);
04616 }
04617 }
04618 }
04619 }
04620
04621 return( Result );
04622 }
04623
04624
04625
04626
04627 void Polyhedron_PrintConstraints(FILE *Dst,char *Format,Polyhedron *Pol)
04628 {
04629 int i,j;
04630
04631 fprintf( Dst, "%d %d\n", Pol->NbConstraints, Pol->Dimension+2 );
04632 for( i=0 ; i<Pol->NbConstraints ; i++ )
04633 {
04634 for( j=0 ; j<Pol->Dimension+2 ; j++ )
04635 value_print( stdout, Format, Pol->Constraint[i][j] );
04636 fprintf( Dst, "\n" );
04637 }
04638
04639 }
04640
04641
04642 void Domain_PrintConstraints(FILE *Dst,char *Format,Polyhedron *Pol)
04643 {
04644 Polyhedron *Q;
04645 for (Q = Pol; Q; Q = Q->next)
04646 Polyhedron_PrintConstraints(Dst, Format, Q);
04647 }
04648
04649 static Polyhedron *p_simplify_constraints(Polyhedron *P, Vector *row,
04650 Value *g, unsigned MaxRays)
04651 {
04652 Polyhedron *T, *R = P;
04653 int len = P->Dimension+2;
04654 int r;
04655
04656
04657
04658
04659
04660
04661 for (r = 0; r < R->NbConstraints; ++r) {
04662 if (ConstraintSimplify(R->Constraint[r], row->p, len, g)) {
04663 T = R;
04664 R = AddConstraints(row->p, 1, R, MaxRays);
04665 if (T != P)
04666 Polyhedron_Free(T);
04667 r = -1;
04668 }
04669 }
04670 if (R != P)
04671 Polyhedron_Free(P);
04672 return R;
04673 }
04674
04675
04676
04677
04678
04679
04680
04681 Polyhedron *DomainConstraintSimplify(Polyhedron *P, unsigned MaxRays)
04682 {
04683 Polyhedron **prev;
04684 int len = P->Dimension+2;
04685 Vector *row = Vector_Alloc(len);
04686 Value g;
04687 Polyhedron *R = P, *N;
04688 value_set_si(row->p[0], 1);
04689 value_init(g);
04690
04691 for (prev = &R; P; P = N) {
04692 Polyhedron *T;
04693 N = P->next;
04694 T = p_simplify_constraints(P, row, &g, MaxRays);
04695
04696 if (emptyQ(T) && prev != &R) {
04697 Polyhedron_Free(T);
04698 *prev = NULL;
04699 continue;
04700 }
04701
04702 if (T != P)
04703 T->next = N;
04704 *prev = T;
04705 prev = &T->next;
04706 }
04707
04708 if (R->next && emptyQ(R)) {
04709 N = R->next;
04710 Polyhedron_Free(R);
04711 R = N;
04712 }
04713
04714 value_clear(g);
04715 Vector_Free(row);
04716 return R;
04717 }