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