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