00001 #include <stdlib.h>
00002 #include <polylib/polylib.h>
00003
00004
00005 typedef struct {
00006 int count;
00007 int *fac;
00008 } factor;
00009
00010 static factor allfactors (int num);
00011
00012
00013
00014
00015 void PrintLatticeUnion(FILE *fp, char *format, LatticeUnion *Head) {
00016
00017 LatticeUnion *temp;
00018
00019 for(temp = Head; temp != NULL; temp = temp->next)
00020 Matrix_Print(fp,format,(Matrix *)temp->M);
00021 return;
00022 }
00023
00024
00025
00026
00027 void LatticeUnion_Free(LatticeUnion *Head) {
00028
00029 LatticeUnion *temp;
00030
00031 while (Head != NULL) {
00032 temp = Head;
00033 Head = temp->next;
00034 Matrix_Free(temp->M);
00035 free(temp);
00036 }
00037 return;
00038 }
00039
00040
00041
00042
00043 LatticeUnion *LatticeUnion_Alloc(void) {
00044
00045 LatticeUnion *temp;
00046
00047 temp = (LatticeUnion *)malloc(sizeof(LatticeUnion));
00048 temp->M=NULL;
00049 temp->next=NULL;
00050 return temp;
00051 }
00052
00053
00054
00055
00056
00057 Bool sameAffinepart (Lattice *A, Lattice *B) {
00058
00059 int i;
00060
00061 #ifdef DOMDEBUG
00062 FILE *fp;
00063 fp = fopen("_debug","a");
00064 fprintf(fp,"\nEntered SAMEAFFINEPART \n");
00065 fclose(fp);
00066 #endif
00067
00068 for (i = 0; i < A->NbRows; i ++)
00069 if (value_ne(A->p[i][A->NbColumns-1],B->p[i][B->NbColumns-1]))
00070 return False;
00071 return True;
00072 }
00073
00074
00075
00076
00077
00078 Lattice *EmptyLattice(int dimension) {
00079
00080 Lattice *result;
00081 int i,j;
00082
00083 #ifdef DOMDEBUG
00084 FILE *fp;
00085 fp = fopen ("_debug", "a");
00086 fprintf (fp, "\nEntered NULLATTICE \n");
00087 fclose (fp);
00088 #endif
00089
00090 result = (Lattice *) Matrix_Alloc(dimension, dimension);
00091 for (i = 0; i < dimension; i ++)
00092 for (j = 0; j < dimension; j ++)
00093 value_set_si(result->p[i][j],0);
00094 value_set_si(result->p[i-1][i-1],1);
00095 return result;
00096 }
00097
00098
00099
00100
00101 Bool isEmptyLattice (Lattice *A) {
00102
00103 int i,j;
00104
00105 #ifdef DOMDEBUG
00106 FILE *fp;
00107 fp = fopen("_debug", "a");
00108 fprintf(fp,"\nEntered ISNULLATTICE \n");
00109 fclose(fp);
00110 #endif
00111
00112 for (i = 0; i < A->NbRows-1; i ++)
00113 for (j = 0; j < A->NbColumns-1; j ++)
00114 if(value_notzero_p(A->p[i][j])) {
00115 return False;
00116 }
00117 if (value_one_p(A->p[i][A->NbColumns-1])) {
00118 return True ;
00119 }
00120 return False ;
00121 }
00122
00123
00124
00125
00126
00127
00128 Bool isLinear(Lattice *A) {
00129
00130 int i;
00131
00132 #ifdef DOMDEBUG
00133 FILE *fp;
00134 fp = fopen ("_debug", "a");
00135 fprintf (fp, "\nEntered ISLINEAR \n");
00136 fclose (fp);
00137 #endif
00138
00139 for (i = 0; i < A->NbRows-1; i ++)
00140 if (value_notzero_p(A->p[i][A->NbColumns-1])) {
00141 return False;
00142 }
00143 return True;
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 void AffineHermite (Lattice *A, Lattice **H, Matrix **U) {
00160
00161 Lattice *temp;
00162 Bool flag = True;
00163
00164 #ifdef DOMDEBUG
00165 FILE *fp;
00166 fp = fopen ("_debug", "a");
00167 fprintf (fp, "\nEntered AFFINEHERMITE \n");
00168 fclose (fp);
00169 #endif
00170
00171 if (isLinear(A) == False)
00172 temp = Homogenise(A,True);
00173 else {
00174 flag = False ;
00175 temp = (Lattice *)Matrix_Copy(A);
00176 }
00177 Hermite((Matrix *)temp,(Matrix **) H, U);
00178 if (flag == True) {
00179 Matrix_Free ((Matrix *) temp);
00180 temp = Homogenise(H[0],False);
00181 Matrix_Free((Matrix *) H[0]);
00182 H[0] = (Lattice *)Matrix_Copy(temp);
00183 Matrix_Free((Matrix *) temp);
00184 temp = Homogenise(U[0],False);
00185 Matrix_Free ((Matrix *) U[0]);
00186 U[0] = (Matrix *)Matrix_Copy(temp);
00187 }
00188 Matrix_Free((Matrix *) temp);
00189 return;
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 void AffineSmith(Lattice *A, Lattice **U, Lattice **V, Lattice **Diag) {
00205
00206 Lattice *temp;
00207 Lattice *Uinv;
00208 int i,j;
00209 Value sum, quo, rem;
00210
00211 #ifdef DOMDEBUG
00212 FILE *fp;
00213 fp = fopen("_debug", "a");
00214 fprintf(fp,"\nEntered AFFINESMITH \n");
00215 fclose(fp);
00216 #endif
00217
00218 value_init(sum);
00219 value_init(quo); value_init(rem);
00220 temp = Homogenise(A,True);
00221 Smith((Matrix *)temp, (Matrix **)U, (Matrix **)V, (Matrix **)Diag);
00222 Matrix_Free((Matrix *)temp);
00223
00224 temp = Homogenise (*U, False);
00225 Matrix_Free ((Matrix *) *U);
00226 *U = (Lattice *)Matrix_Copy ((Matrix *)temp);
00227 Matrix_Free ((Matrix *)temp);
00228
00229 temp = Homogenise (*V, False);
00230 Matrix_Free ((Matrix *)*V);
00231 *V = (Lattice *) Matrix_Copy ((Matrix *)temp);
00232 Matrix_Free ((Matrix *)temp);
00233
00234 temp = Homogenise (*Diag, False);
00235 Matrix_Free ((Matrix *)*Diag);
00236 *Diag = (Lattice *)Matrix_Copy ((Matrix *)temp);
00237 Matrix_Free ((Matrix *)temp);
00238
00239 temp = (Lattice *) Matrix_Copy ((Matrix *) *U);
00240 Uinv = (Lattice *) Matrix_Alloc (U[0]->NbRows, U[0]->NbColumns);
00241 Matrix_Inverse( (Matrix *) temp, (Matrix *) Uinv);
00242 Matrix_Free ((Matrix *) temp);
00243
00244 for (i = 0; i < U[0]->NbRows-1; i ++) {
00245 value_set_si(sum,0);
00246 for(j = 0; j < U[0]->NbColumns-1; j ++) {
00247 value_addmul(sum, Uinv->p[i][j], U[0]->p[j][U[0]->NbColumns-1]);
00248 }
00249 value_assign(Diag[0]->p[i][j],sum);
00250 }
00251 Matrix_Free((Matrix *) Uinv);
00252 for(i = 0; i < U[0]->NbRows-1; i ++)
00253 value_set_si(U[0]->p[i][U[0]->NbColumns-1],0);
00254 for(i = 0; i < Diag[0]->NbRows-1; i ++) {
00255 value_division(quo,Diag[0]->p[i][Diag[0]->NbColumns-1],Diag[0]->p[i][i]);
00256 value_modulus(rem,Diag[0]->p[i][Diag[0]->NbColumns-1],Diag[0]->p[i][i]);
00257
00258 fprintf(stdout," pourcent ");
00259 value_print(stdout,VALUE_FMT,rem);
00260 fprintf(stdout," quotient ");
00261 value_print(stdout,VALUE_FMT,quo);
00262 fprintf(stdout," \n");
00263
00264
00265 if(value_neg_p(rem)) {
00266 value_addto(rem,rem,Diag[0]->p[i][i]);
00267 value_decrement(quo,quo);
00268 };
00269 fprintf(stdout,"apres pourcent ");
00270 value_print(stdout,VALUE_FMT,rem);
00271 fprintf(stdout," quotient ");
00272 value_print(stdout,VALUE_FMT,quo);
00273 fprintf(stdout," \n");
00274 value_assign( Diag[0]->p[i][Diag[0]->NbColumns-1],rem);
00275 value_assign(V[0]->p[i][V[0]->NbColumns-1],quo);
00276 }
00277 value_clear(sum);
00278 value_clear(quo); value_clear(rem);
00279 return;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 Lattice *Homogenise(Lattice *A, Bool Forward) {
00296
00297 Lattice *result;
00298
00299 #ifdef DOMDEBUG
00300 FILE *fp;
00301 fp = fopen("_debug","a");
00302 fprintf(fp,"\nEntered HOMOGENISE \n");
00303 fclose(fp);
00304 #endif
00305
00306 result = (Lattice *)Matrix_Copy(A);
00307 if (Forward == True ) {
00308 PutColumnFirst((Matrix *)result, A->NbColumns-1);
00309 PutRowFirst((Matrix *)result, result->NbRows-1);
00310 }
00311 else {
00312 PutColumnLast((Matrix *)result,0);
00313 PutRowLast((Matrix *)result,0);
00314 }
00315 return result;
00316 }
00317
00318
00319
00320
00321
00322
00323 Bool LatticeIncludes(Lattice *A, Lattice *B) {
00324
00325 Lattice *temp, *UA, *HA;
00326 Bool flag = False;
00327
00328 #ifdef DOMDEBUG
00329 FILE *fp;
00330 fp = fopen("_debug", "a");
00331 fprintf(fp,"\nEntered LATTICE INCLUDES \n");
00332 fclose(fp);
00333 #endif
00334
00335 AffineHermite(A,&HA,&UA);
00336 temp = LatticeIntersection(B,HA);
00337 if (sameLattice(temp, HA) == True)
00338 flag = True;
00339
00340 Matrix_Free((Matrix *)temp);
00341 Matrix_Free((Matrix *)UA);
00342 Matrix_Free((Matrix *)HA);
00343 return flag;
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 Bool sameLattice(Lattice *A, Lattice *B) {
00355
00356 Lattice *HA, *HB, *UA, *UB;
00357 int i,j;
00358 Bool result = True;
00359
00360 #ifdef DOMDEBUG
00361 FILE *fp;
00362 fp = fopen("_debug", "a");
00363 fprintf(fp,"\nEntered SAME LATTICE \n");
00364 fclose(fp);
00365 #endif
00366
00367 AffineHermite(A, &HA, &UA);
00368 AffineHermite(B, &HB, &UB);
00369
00370 for (i = 0 ; i < A->NbRows; i ++)
00371 for (j = 0; j < A->NbColumns; j ++)
00372 if (value_ne(HA->p[i][j],HB->p[i][j])) {
00373 result = False;
00374 break;
00375 }
00376
00377 Matrix_Free ((Matrix *) HA);
00378 Matrix_Free ((Matrix *) HB);
00379 Matrix_Free ((Matrix *) UA);
00380 Matrix_Free ((Matrix *) UB);
00381
00382 return result;
00383 }
00384
00385
00386
00387
00388
00389
00390
00391
00392 Lattice *ChangeLatticeDimension(Lattice *A, int dimension) {
00393
00394 int i, j;
00395 Lattice *Result ;
00396
00397 Result = Matrix_Alloc(dimension, dimension);
00398 if(dimension <= A->NbRows) {
00399 for (i = 0; i < dimension; i ++)
00400 for (j = 0; j < dimension; j ++)
00401 value_assign(Result->p[i][j],A->p[i][j]);
00402 return Result;
00403 }
00404 for (i = 0; i < A->NbRows; i ++)
00405 for (j = 0; j < A->NbRows; j ++)
00406 value_assign(Result->p[i][j],A->p[i][j]);
00407
00408 for (i = A->NbRows; i < dimension; i ++)
00409 for (j = 0; j < dimension; j ++) {
00410 value_set_si(Result->p[i][j],0);
00411 value_set_si(Result->p[j][i],0);
00412 }
00413 for (i = A->NbRows; i < dimension; i ++)
00414 value_set_si(Result->p[i][i],1);
00415 return Result;
00416 }
00417
00418
00419
00420
00421
00422 Lattice *ExtractLinearPart(Lattice *A) {
00423
00424 Lattice *Result;
00425 int i, j;
00426 Result = (Lattice *) Matrix_Alloc(A->NbRows-1, A->NbColumns-1);
00427 for (i = 0; i < A->NbRows-1; i ++)
00428 for (j = 0; j < A->NbColumns-1; j ++)
00429 value_assign(Result->p[i][j],A->p[i][j]);
00430 return Result;
00431 }
00432
00433 static Matrix *MakeDioEqforInter(Matrix *A, Matrix *B);
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 Lattice *LatticeIntersection(Lattice *X, Lattice *Y) {
00459
00460 int i, j, exist;
00461 Lattice *result = NULL, *U = NULL ;
00462 Lattice *A = NULL, *B = NULL, *H = NULL;
00463 Matrix *fordio;
00464 Vector *X1 = NULL;
00465
00466 #ifdef DOMDEBUG
00467 FILE *fp;
00468 fp = fopen("_debug", "a");
00469 fprintf(fp,"\nEntered LATTICEINTERSECTION \n");
00470 fclose(fp);
00471 #endif
00472
00473 if (X->NbRows != X->NbColumns) {
00474 fprintf(stderr, "\nIn LatticeIntersection : The Input Matrix X is a not a well defined Lattice\n");
00475 return EmptyLattice(X->NbRows);
00476 }
00477
00478 if (Y->NbRows != Y->NbColumns) {
00479 fprintf (stderr, "\nIn LatticeIntersection : The Input Matrix Y is a not a well defined Lattice\n");
00480 return EmptyLattice(X->NbRows);
00481 }
00482
00483 if (Y->NbRows != X->NbRows) {
00484 fprintf (stderr, "\nIn LatticeIntersection : the input lattices X and Y are of incompatible dimensions\n");
00485 return EmptyLattice(X->NbRows);
00486 }
00487
00488 if (isinHnf(X))
00489 A = (Lattice *) Matrix_Copy(X);
00490 else {
00491 AffineHermite(X, &H, &U);
00492 A = (Lattice *)Matrix_Copy (H);
00493 Matrix_Free((Matrix *) H);
00494 Matrix_Free((Matrix *) U);
00495 }
00496
00497 if (isinHnf(Y))
00498 B = (Lattice *)Matrix_Copy(Y);
00499 else {
00500 AffineHermite(Y, &H, &U);
00501 B = (Lattice *)Matrix_Copy (H);
00502 Matrix_Free((Matrix *) H);
00503 Matrix_Free((Matrix *) U);
00504 }
00505
00506 if ((isEmptyLattice(A)) || (isEmptyLattice (B))) {
00507 result = EmptyLattice(X->NbRows);
00508 Matrix_Free ((Matrix *) A);
00509 Matrix_Free ((Matrix *) B);
00510 return result;
00511 }
00512 fordio = MakeDioEqforInter (A, B);
00513 Matrix_Free (A);
00514 Matrix_Free (B);
00515 exist = SolveDiophantine(fordio,(Matrix **) &U, &X1);
00516 if (exist < 0) {
00517 result = (EmptyLattice(X->NbRows));
00518 return result;
00519 }
00520
00521 result = (Lattice *)Matrix_Alloc(X->NbRows, X->NbColumns);
00522 for (i = 0; i < result->NbRows-1; i ++)
00523 for (j = 0; j < result->NbColumns-1; j ++)
00524 value_assign(result->p[i][j],U->p[i][j]);
00525
00526 for (i = 0; i < result->NbRows-1; i ++)
00527 value_assign(result->p[i][result->NbColumns-1],X1->p[i]);
00528 for (i = 0; i < result->NbColumns-1; i ++)
00529 value_set_si(result->p[result->NbRows-1][i],0);
00530 value_set_si(result->p[result->NbRows-1][result->NbColumns-1],1);
00531
00532 Matrix_Free((Matrix *) U);
00533 Vector_Free(X1);
00534 Matrix_Free(fordio);
00535
00536 AffineHermite(result,&H,&U);
00537 Matrix_Free((Matrix *)result);
00538 result = (Lattice *)Matrix_Copy(H);
00539
00540 Matrix_Free((Matrix *) H);
00541 Matrix_Free((Matrix *) U);
00542
00543
00544
00545 if (isEmptyLattice (result)) {
00546 Matrix_Free ((Matrix *)result);
00547 return (EmptyLattice (X->NbRows));
00548 }
00549 return result;
00550 }
00551
00552 static Matrix * MakeDioEqforInter (Lattice *A, Lattice *B) {
00553
00554 Matrix *Dio ;
00555 int i,j;
00556
00557 #ifdef DOMDEBUG
00558 FILE *fp;
00559 fp = fopen("_debug", "a");
00560 fprintf(fp,"\nEntered MAKEDIOEQFORINTER \n");
00561 fclose(fp);
00562 #endif
00563
00564 Dio = Matrix_Alloc(2*(A->NbRows-1) + 1, 3 * (A->NbColumns-1)+1);
00565
00566 for (i = 0; i < Dio->NbRows; i ++)
00567 for (j = 0; j < Dio->NbColumns; j ++)
00568 value_set_si(Dio->p[i][j],0);
00569
00570 for (i = 0; i < A->NbRows-1; i++) {
00571 value_set_si(Dio->p[i][i],1);
00572 value_set_si(Dio->p[i+A->NbRows-1][i],1);
00573 }
00574 for (i = 0; i < A->NbRows-1 ; i ++)
00575 for (j = 0; j < A->NbRows-1; j ++) {
00576 value_oppose(Dio->p[i][j+A->NbRows-1],A->p[i][j]);
00577 value_oppose(Dio->p[i+(A->NbRows-1)][j+2*(A->NbRows-1)],B->p[i][j]);
00578 }
00579
00580
00581
00582 for (i = 0; i < A->NbColumns-1; i++) {
00583 value_oppose(Dio->p[i][Dio->NbColumns-1],A->p[i][A->NbColumns-1]);
00584 value_oppose(Dio->p[i+A->NbRows-1][Dio->NbColumns-1],B->p[i][A->NbColumns-1]) ;
00585 }
00586 value_set_si(Dio->p[Dio->NbRows-1][Dio->NbColumns-1],1);
00587 return Dio;
00588 }
00589
00590 static void AddLattice(LatticeUnion *,Matrix *, Matrix *, int , int);
00591 LatticeUnion *SplitLattice(Matrix *, Matrix *, Matrix *);
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 LatticeUnion *Lattice2LatticeUnion(Lattice *X,Lattice *Y)
00658 {
00659 Lattice *B1 = NULL, *B2 = NULL, *newB1 = NULL, *newB2 = NULL, *Intersection=NULL;
00660 Matrix *U = NULL,*M1 = NULL, *M2 = NULL, *M1Inverse = NULL,*MtProduct = NULL;
00661 Matrix *Vinv, *V , *temp, *DiagMatrix ;
00662
00663 LatticeUnion *Head = NULL, *tempHead = NULL;
00664 int i;
00665 Value k;
00666
00667
00668 Intersection = LatticeIntersection(X,Y);
00669 if (isEmptyLattice(Intersection) == True) {
00670 fprintf(stderr,"\nIn Lattice2LatticeUnion : the input lattices X and Y do not have any common part\n");
00671 return NULL;
00672 }
00673
00674 value_init(k);
00675 M1 = (Matrix *)ExtractLinearPart(X);
00676 M2 = (Matrix *)ExtractLinearPart(Intersection);
00677
00678 M1Inverse = Matrix_Alloc(M1->NbRows,M1->NbColumns);
00679 temp = Matrix_Copy(M1);
00680 Matrix_Inverse(temp,M1Inverse);
00681 Matrix_Free(temp);
00682
00683 MtProduct = Matrix_Alloc(M1->NbRows, M1->NbColumns);
00684 Matrix_Product(M1Inverse,M2,MtProduct) ;
00685 Smith(MtProduct, &U, &Vinv, &DiagMatrix);
00686 V = Matrix_Alloc(Vinv->NbRows,Vinv->NbColumns);
00687 Matrix_Inverse(Vinv, V);
00688 Matrix_Free(Vinv);
00689 B1 = Matrix_Alloc(M1->NbRows, U->NbColumns);
00690 B2 = Matrix_Alloc(M2->NbRows, V->NbColumns);
00691 Matrix_Product(M1, U, B1);
00692 Matrix_Product(M2, V, B2);
00693 Matrix_Free(M1);
00694 Matrix_Free(M2);
00695 value_division(k,B2->p[0][0],B1->p[0][0]);
00696 value_division(k,DiagMatrix->p[0][0],k);
00697 for (i = 0; i < DiagMatrix->NbRows; i++)
00698 value_division(DiagMatrix->p[i][i],DiagMatrix->p[i][i],k);
00699 newB1 = ChangeLatticeDimension(B1, B1->NbRows + 1);
00700 Matrix_Free(B1);
00701 newB2 = ChangeLatticeDimension(B2, B2->NbRows +1);
00702 Matrix_Free(B2);
00703 for(i = 0; i < newB1->NbRows - 1;i ++)
00704 value_assign(newB2->p[i][newB1->NbRows-1],Intersection->p[i][X->NbRows-1]);
00705 Head = SplitLattice(newB1,newB2,DiagMatrix);
00706 Matrix_Free(newB1);
00707 Matrix_Free(DiagMatrix);
00708 value_clear(k);
00709 return Head;
00710 }
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797 LatticeUnion *LatticeDifference(Lattice *A,Lattice *B) {
00798
00799 Lattice *Intersection = NULL;
00800 LatticeUnion *Head = NULL, *tempHead = NULL;
00801 Matrix *H , *U1 , *X, *Y ;
00802
00803 #ifdef DOMDEBUG
00804 FILE *fp;
00805 fp = fopen("_debug", "a");
00806 fprintf(fp,"\nEntered LATTICEDIFFERENCE \n");
00807 fclose(fp);
00808 #endif
00809
00810 if (A->NbRows != A->NbColumns) {
00811 fprintf(stderr,"\nIn LatticeDifference : The Input Matrix A is not a proper Lattice \n");
00812 return NULL;
00813 }
00814
00815 if (B->NbRows != B->NbColumns) {
00816 fprintf(stderr,"\nIn LatticeDifference : The Input Matrix B is not a proper Lattice \n");
00817 return NULL;
00818 }
00819
00820 if (A->NbRows != B->NbRows) {
00821 fprintf(stderr,"\nIn Lattice Difference : The Input Lattices A and B have ");
00822 fprintf(stderr,"incompatible dimensions \n");
00823 return NULL;
00824 }
00825
00826 if (isinHnf (A) != True) {
00827 AffineHermite(A,&H,&U1);
00828 X = Matrix_Copy(H);
00829 Matrix_Free(U1);
00830 Matrix_Free(H);
00831 }
00832 else
00833 X = Matrix_Copy(A);
00834
00835 if (isinHnf(B) != True) {
00836 AffineHermite(B,&H,&U1);
00837 Y = Matrix_Copy(H);
00838 Matrix_Free(H);
00839 Matrix_Free(U1);
00840 }
00841 else
00842 Y = Matrix_Copy(B);
00843 if (isEmptyLattice(X)) {
00844 return NULL;
00845 }
00846
00847 Head=Lattice2LatticeUnion(X,Y);
00848
00849
00850
00851 if (Head == NULL) {
00852 Head = (LatticeUnion *)malloc(sizeof(LatticeUnion));
00853 Head->M = Matrix_Copy(X);
00854 Head->next = NULL;
00855 Matrix_Free(X);
00856 Matrix_Free(Y);
00857 return Head;
00858 }
00859
00860 tempHead = Head;
00861 Head = Head->next;
00862 Matrix_Free (tempHead->M);
00863 tempHead->next = NULL;
00864 free(tempHead);
00865
00866 if ((Head != NULL))
00867 Head = LatticeSimplify (Head);
00868 Matrix_Free (X);
00869 Matrix_Free (Y);
00870
00871 return Head;
00872 }
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884 LatticeUnion *SplitLattice(Lattice *B1, Lattice *B2, Matrix *C) {
00885
00886 int i;
00887
00888 LatticeUnion *Head = NULL;
00889 Head = (LatticeUnion *)malloc(sizeof(LatticeUnion));
00890 Head->M = (Lattice *)B2;
00891 Head->next = NULL;
00892 for (i = 0; i < C->NbRows ; i++)
00893 AddLattice(Head,B1,B2,VALUE_TO_INT(C->p[i][i]),i);
00894 return Head;
00895 }
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911 static void AddLattice (LatticeUnion *Head, Matrix *B1, Matrix *B2, int NumofTimes, int Colnumber) {
00912
00913 LatticeUnion *temp, *tail, *marker;
00914 int i,j;
00915 Value tmp;
00916
00917 value_init(tmp);
00918 tail = Head;
00919 while (tail->next != NULL)
00920 tail = tail->next;
00921 marker = tail;
00922
00923 for(temp = Head; temp != NULL; temp=temp->next) {
00924 for (i = 1; i < NumofTimes; i++) {
00925 Lattice *tempMatrix, *H, *U;
00926
00927 tempMatrix = (Lattice *)Matrix_Copy(temp->M);
00928 for (j = 0; j < B2->NbRows; j++) {
00929 value_set_si(tmp,i);
00930 value_addmul(tempMatrix->p[j][B2->NbColumns-1], tmp, B1->p[j][Colnumber]);
00931 }
00932 tail->next = (LatticeUnion *)malloc(sizeof(LatticeUnion));
00933 AffineHermite(tempMatrix,&H,&U);
00934 Matrix_Free((Matrix *)tempMatrix);
00935 Matrix_Free(U);
00936 tail->next->M = H;
00937 tail->next->next=NULL;
00938 tail = tail->next;
00939 }
00940 if (temp == marker)
00941 break;
00942 }
00943 value_clear(tmp);
00944 return;
00945 }
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973 int FindHermiteBasisofDomain(Polyhedron *A, Matrix **B) {
00974
00975 int i, j;
00976 Matrix *temp,*temp1, *tempinv, *Newmat ;
00977 Matrix *vert, *rays, *result;
00978 Polyhedron *Image;
00979 int rank, equcount ;
00980 int noofvertices = 0, noofrays = 0;
00981 int vercount , raycount;
00982 Value lcm, fact;
00983
00984 #ifdef DOMDEBUG
00985 FILE *fp;
00986 fp = fopen("_debug", "a");
00987 fprintf(fp,"\nEntered FINDHERMITEBASISOFDOMAIN \n");
00988 fclose(fp);
00989 #endif
00990
00991 POL_ENSURE_FACETS(A);
00992 POL_ENSURE_VERTICES(A);
00993
00994
00995 if (emptyQ(A)) {
00996 B[0] = Identity(A->Dimension+1);
00997 return(-1);
00998 }
00999
01000 value_init(lcm); value_init(fact);
01001 value_set_si(lcm,1);
01002
01003
01004 for (i = 0; i < A->NbRays; i++)
01005 if ((value_notzero_p(A->Ray[i][0])) && value_notzero_p(A->Ray[i][A->Dimension+1]))
01006 noofvertices++;
01007 else
01008 noofrays ++;
01009
01010 vert = Matrix_Alloc(noofvertices,A->Dimension+1);
01011 rays = Matrix_Alloc(noofrays,A->Dimension);
01012 vercount = 0;
01013 raycount = 0;
01014
01015 for(i = 0; i < A->NbRays; i++) {
01016 if ((value_notzero_p(A->Ray[i][0])) && value_notzero_p(A->Ray[i][A->Dimension+1])) {
01017 for(j = 1; j < A->Dimension+2; j++)
01018 value_assign(vert->p[vercount][j-1],A->Ray[i][j]);
01019 value_lcm(lcm, lcm, A->Ray[i][j-1]);
01020 vercount++;
01021 }
01022 else {
01023 for (j = 1; j < A->Dimension+1; j++)
01024 value_assign(rays->p[raycount][j-1],A->Ray[i][j]);
01025 raycount++;
01026 }
01027 }
01028
01029
01030 for(i = 0; i < vert->NbRows; i ++) {
01031 value_division(fact,lcm,vert->p[i][vert->NbColumns-1]);
01032 for (j = 0; j < vert->NbColumns-1; j++)
01033 value_multiply(vert->p[i][j],vert->p[i][j],fact);
01034 }
01035
01036
01037 temp = RemoveColumn(vert,vert->NbColumns-1);
01038 Matrix_Free(vert);
01039
01040
01041 vert = Matrix_Alloc(temp->NbRows-1, temp->NbColumns);
01042 for (i = 1; i < temp->NbRows; i++)
01043 for (j = 0; j < temp->NbColumns ; j++)
01044 value_subtract(vert->p[i-1][j],temp->p[0][j],temp->p[i][j]);
01045
01046 Matrix_Free(temp);
01047
01048
01049
01050 result = Matrix_Alloc(vert->NbRows+rays->NbRows, vert->NbColumns);
01051 for (i = 0; i < vert->NbRows; i++)
01052 for (j = 0 ;j < result->NbColumns ; j++)
01053 value_assign(result->p[i][j],vert->p[i][j]);
01054
01055 for (; i<result->NbRows; i++)
01056 for (j = 0; j < result->NbColumns; j++)
01057 value_assign(result->p[i][j],rays->p[i-vert->NbRows][j]);
01058
01059 Matrix_Free(vert);
01060 Matrix_Free(rays);
01061
01062 rank = findHermiteBasis(result, &temp);
01063 temp1 = ChangeLatticeDimension(temp,temp->NbRows+1);
01064
01065 Matrix_Free(result);
01066 Matrix_Free(temp);
01067
01068
01069 temp = Matrix_Copy(temp1);
01070 tempinv = Matrix_Alloc(temp->NbRows,temp->NbColumns);
01071 Matrix_Inverse(temp,tempinv);
01072 Matrix_Free(temp);
01073 Image = DomainImage(A,tempinv,MAXNOOFRAYS);
01074 Matrix_Free(tempinv);
01075 Newmat = Matrix_Alloc(temp1->NbRows,temp1->NbColumns);
01076 for(i = 0; i < rank ; i++)
01077 for(j = 0; j < Newmat->NbColumns ; j++)
01078 value_set_si(Newmat->p[i][j],0);
01079 for(i = 0; i < rank; i++)
01080 value_set_si(Newmat->p[i][i],1);
01081 equcount = 0;
01082 for (i = 0; i < Image->NbConstraints; i ++)
01083 if (value_zero_p(Image->Constraint[i][0])) {
01084 for (j = 1; j<Image->Dimension+2; j ++)
01085 value_assign(Newmat->p[rank+equcount][j-1],Image->Constraint[i][j]);
01086 ++equcount ;
01087 }
01088 Domain_Free(Image);
01089 for (i = 0; i < Newmat->NbColumns-1; i++)
01090 value_set_si(Newmat->p[Newmat->NbRows-1][i],0);
01091 value_set_si(Newmat->p[Newmat->NbRows-1][Newmat->NbColumns-1],1);
01092 temp = Matrix_Alloc(Newmat->NbRows, Newmat->NbColumns);
01093 Matrix_Inverse(Newmat,temp);
01094 Matrix_Free(Newmat);
01095 B[0] = Matrix_Alloc(temp1->NbRows,temp->NbColumns);
01096
01097 Matrix_Product(temp1,temp,B[0]);
01098 Matrix_Free(temp1);
01099 Matrix_Free(temp);
01100 value_clear(lcm);
01101 value_clear(fact);
01102 return rank;
01103 }
01104
01105
01106
01107
01108
01109 Lattice *LatticeImage(Lattice *A, Matrix *M) {
01110
01111 Lattice *Img, *temp, *Minv;
01112
01113 #ifdef DOMDEBUG
01114 FILE *fp;
01115 fp = fopen("_debug", "a");
01116 fprintf(fp, "\nEntered LATTICEIMAGE \n");
01117 fclose(fp);
01118 #endif
01119
01120 if ((A->NbRows != M->NbRows) || (M->NbRows != M->NbColumns))
01121 return (EmptyLattice (A->NbRows));
01122
01123 if (value_one_p(M->p[M->NbRows-1][M->NbColumns-1])) {
01124 Img = Matrix_Alloc ( M->NbRows, A->NbColumns );
01125 Matrix_Product (M,A,Img);
01126 return Img;
01127 }
01128 temp = Matrix_Copy(M);
01129 Minv = Matrix_Alloc(temp->NbColumns, temp->NbRows);
01130 Matrix_Inverse(temp, Minv);
01131 Matrix_Free(temp);
01132
01133 Img = LatticePreimage(A, Minv);
01134 Matrix_Free (Minv);
01135 return Img;
01136 }
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148 Lattice *LatticePreimage(Lattice *L, Matrix *G) {
01149
01150 Matrix *Dio, *U ;
01151 Lattice *Result;
01152 Vector *X;
01153 int i,j;
01154 int rank;
01155 Value divisor, tmp;
01156
01157 #ifdef DOMDEBUG
01158 FILE *fp;
01159 fp = fopen("_debug", "a");
01160 fprintf(fp,"\nEntered LATTICEPREIMAGE \n");
01161 fclose(fp);
01162 #endif
01163
01164
01165 if (G->NbRows != L->NbRows) {
01166 fprintf (stderr, "\nIn LatticePreimage: Incompatible types of Lattice and the function\n");
01167 return (EmptyLattice(G->NbColumns));
01168 }
01169
01170 value_init(divisor); value_init(tmp);
01171
01172
01173 value_assign(divisor,G->p[G->NbRows-1][G->NbColumns-1]);
01174 Dio = Matrix_Alloc(G->NbRows, G->NbColumns+L->NbColumns-1);
01175 for (i = 0; i < G->NbRows-1; i++)
01176 for (j = 0; j < G->NbColumns-1; j++)
01177 value_assign(Dio->p[i][j],G->p[i][j]);
01178
01179 for (i = 0;i < G->NbRows-1; i++)
01180 for (j = 0; j < L->NbColumns-1; j++) {
01181 value_multiply(tmp,divisor,L->p[i][j]);
01182 value_oppose(Dio->p[i][j+G->NbColumns-1],tmp);
01183 }
01184
01185 for (i = 0; i < Dio->NbRows-1; i++) {
01186 value_multiply(tmp,divisor,L->p[i][L->NbColumns-1]);
01187 value_subtract(tmp,G->p[i][G->NbColumns-1],tmp);
01188 value_assign(Dio->p[i][Dio->NbColumns-1],tmp);
01189 }
01190 for (i = 0; i < Dio->NbColumns-1; i++)
01191 value_set_si(Dio->p[Dio->NbRows-1][i],0);
01192
01193 value_set_si(Dio->p[Dio->NbRows-1][Dio->NbColumns-1],1);
01194 rank = SolveDiophantine(Dio, &U, &X);
01195
01196 if (rank == -1)
01197 Result = EmptyLattice(G->NbColumns);
01198 else {
01199 Result = Matrix_Alloc (G->NbColumns, G->NbColumns);
01200 for (i = 0; i < Result->NbRows-1; i++)
01201 for (j = 0; j < Result->NbColumns-1; j++)
01202 value_assign(Result->p[i][j],U->p[i][j]);
01203
01204 for (i = 0; i < Result->NbRows-1; i ++)
01205 value_assign(Result->p[i][Result->NbColumns-1],X->p[i]);
01206 Matrix_Free (U);
01207 Vector_Free (X);
01208 for (i = 0; i < Result->NbColumns-1; i ++)
01209 value_set_si(Result->p[Result->NbRows-1][i],0);
01210 value_set_si(Result->p[i][i],1);
01211 }
01212 Matrix_Free(Dio);
01213 value_clear(divisor);
01214 value_clear(tmp);
01215 return Result;
01216 }
01217
01218
01219
01220
01221
01222 Bool IsLattice(Matrix *m) {
01223
01224 int i;
01225
01226 #ifdef DOMDEBUG
01227 FILE *fp;
01228 fp = fopen ("_debug", "a");
01229 fprintf (fp, "\nEntered ISLATTICE \n");
01230 fclose (fp);
01231 #endif
01232
01233
01234
01235
01236 if (m->NbRows != m->NbColumns)
01237 return False;
01238
01239 for (i = 0; i < m->NbColumns-1; i++)
01240 if (value_notzero_p(m->p[m->NbRows-1][i]))
01241 return False ;
01242 if (value_notone_p(m->p[i][i]))
01243 return False;
01244 return True ;
01245 }
01246
01247
01248
01249
01250 Bool isfulldim(Matrix *m) {
01251
01252 Matrix *h, *u ;
01253 int i ;
01254
01255
01256
01257
01258
01259
01260
01261 Hermite(m, &h, &u);
01262 for (i = 0; i < h->NbRows; i ++)
01263 if (value_zero_p(h->p[i][i])) {
01264 Matrix_Free (h);
01265 Matrix_Free (u);
01266 return False;
01267 }
01268 Matrix_Free (h);
01269 Matrix_Free (u);
01270 return True;
01271 }
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289 static Bool Simplify(LatticeUnion **InputList, LatticeUnion **ResultList, int dim) {
01290
01291 int i;
01292 LatticeUnion *prev, *temp;
01293 factor allfac;
01294 Bool retval = False;
01295 int width;
01296 Value cnt, aux, k, fac, num, tmp, foobar;
01297
01298 if ((*InputList == NULL) || (InputList[0]->next == NULL))
01299 return False ;
01300
01301 value_init(aux); value_init(cnt);
01302 value_init(k); value_init(fac);
01303 value_init(num); value_init(tmp);
01304 value_init(foobar);
01305
01306 width = InputList[0]->M->NbRows-1;
01307 allfac = allfactors(VALUE_TO_INT(InputList[0]->M->p[dim][dim]));
01308 value_set_si(cnt,0);
01309 for (temp = InputList[0]; temp != NULL; temp = temp->next)
01310 value_increment(cnt,cnt);
01311 for(i = 0; i < allfac.count; i++) {
01312 value_set_si(foobar,allfac.fac[i]);
01313 value_division(aux,InputList[0]->M->p[dim][dim],foobar);
01314 if(value_ge(cnt,aux))
01315 break;
01316 }
01317 if (i == allfac.count) {
01318 value_clear(cnt); value_clear(aux);
01319 value_clear(k); value_clear(fac);
01320 value_clear(num); value_clear(tmp);
01321 value_clear(foobar);
01322 return False;
01323 }
01324 for (; i < allfac.count; i++) {
01325 Bool Present = False;
01326 value_set_si(k,0);
01327
01328 if (*InputList == NULL) {
01329 value_clear(cnt); value_clear(aux);
01330 value_clear(k); value_clear(fac);
01331 value_clear(num); value_clear(tmp);
01332 value_clear(foobar);
01333 return retval;
01334 }
01335 value_set_si(foobar,allfac.fac[i]);
01336 value_division(num,InputList[0]->M->p[dim][dim],foobar);
01337 while (value_lt(k,foobar)) {
01338 Present = False;
01339 value_assign(fac,k);
01340 for (temp = *InputList; temp != NULL; temp = temp->next) {
01341 if (value_eq(temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1],fac)) {
01342 value_set_si(foobar,allfac.fac[i]);
01343 value_addto(fac,fac,foobar);
01344 if (value_ge(fac,(*InputList)->M->p[dim][dim])) {
01345 Present = True;
01346 break;
01347 }
01348 }
01349 if (value_gt(temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1],fac))
01350 break;
01351 }
01352 if (Present == True) {
01353 retval = True;
01354 if (*ResultList == NULL)
01355 *ResultList = temp = (LatticeUnion *)malloc(sizeof(LatticeUnion));
01356 else {
01357 for (temp = *ResultList; temp->next != NULL; temp = temp->next);
01358 temp->next = (LatticeUnion *) malloc (sizeof (LatticeUnion));
01359 temp = temp->next;
01360 }
01361 temp->M = Matrix_Copy(InputList[0]->M);
01362 temp->next = NULL;
01363 value_set_si(foobar,allfac.fac[i]);
01364 value_assign(temp->M->p[dim][dim],foobar);
01365 value_assign(temp->M->p[dim][width],k);
01366 value_set_si(temp->M->p[width][width],1);
01367
01368
01369 value_assign(tmp,k);
01370 prev = NULL;
01371 temp = InputList[0];
01372 while (temp != NULL) {
01373 if (value_eq(temp->M->p[width][width],tmp)) {
01374 if (temp == InputList[0]) {
01375 prev = temp;
01376 temp = InputList [0] = temp->next;
01377 Matrix_Free(prev->M);
01378 free(prev);
01379 }
01380 else {
01381 prev->next = temp->next;
01382 Matrix_Free(temp->M);
01383 free(temp);
01384 temp = prev->next;
01385 }
01386 value_set_si(foobar,allfac.fac[i]);
01387 value_addto(tmp,tmp,foobar);
01388 }
01389 else {
01390 prev = temp;
01391 temp = temp->next;
01392 }
01393 }
01394 }
01395 value_increment(k,k);
01396 }
01397 }
01398 value_clear(cnt); value_clear(aux);
01399 value_clear(k); value_clear(fac);
01400 value_clear(num); value_clear(tmp);
01401 value_clear(foobar);
01402 return retval;
01403 }
01404
01405
01406
01407
01408
01409
01410
01411
01412 static int LinearPartCompare(const void *A, const void *B) {
01413
01414 Lattice **L1, **L2;
01415 int i, j;
01416
01417 L1 = (Lattice **) A;
01418 L2 = (Lattice **) B;
01419
01420 for (i = 0; i < L1[0]->NbRows-1; i++)
01421 for (j = 0; j <= i ; j++) {
01422 if (value_gt(L1[0]->p[i][j],L2[0]->p[i][j]))
01423 return 1;
01424 if (value_lt(L1[0]->p[i][j],L2[0]->p[i][j]))
01425 return -1;
01426 }
01427 return 0;
01428 }
01429
01430
01431
01432
01433
01434
01435 static void LinearPartSort (LatticeUnion *Head) {
01436
01437 int cnt;
01438 Lattice **Latlist;
01439 LatticeUnion *temp ;
01440
01441 cnt = 0;
01442 for (temp = Head; temp != NULL; temp = temp->next)
01443 cnt ++;
01444
01445 Latlist = (Lattice **) malloc ( sizeof (Lattice *) * cnt);
01446
01447 cnt = 0;
01448 for (temp = Head; temp != NULL; temp = temp->next)
01449 Latlist[cnt++] = temp->M;
01450
01451 qsort(Latlist, cnt, sizeof(Lattice *), LinearPartCompare);
01452
01453 cnt = 0;
01454 for (temp = Head; temp != NULL; temp = temp->next)
01455 temp->M = Latlist[cnt++];
01456
01457 free (Latlist);
01458 return;
01459 }
01460
01461
01462
01463
01464
01465
01466
01467 static int AffinePartCompare(const void *A, const void *B) {
01468
01469 int i;
01470 Lattice **L1, **L2;
01471
01472 L1 = (Lattice **)A;
01473 L2 = (Lattice **)B;
01474
01475 for (i = 0; i < L1[0]->NbRows; i++) {
01476 if (value_gt(L1[0]->p[i][L1[0]->NbColumns-1],L2[0]->p[i][L1[0]->NbColumns-1]))
01477 return 1;
01478
01479 if (value_lt(L1[0]->p[i][L1[0]->NbColumns-1],L2[0]->p[i][L1[0]->NbColumns-1]))
01480 return -1;
01481 }
01482 return 0 ;
01483 }
01484
01485
01486
01487
01488
01489 static void AffinePartSort (LatticeUnion *List) {
01490
01491 int cnt;
01492 Lattice **LatList;
01493 LatticeUnion *tmp;
01494
01495 cnt = 0;
01496 for (tmp = List; tmp != NULL; tmp = tmp->next)
01497 cnt ++;
01498
01499 LatList = (Lattice **) malloc (sizeof(Lattice *) * cnt);
01500
01501 cnt = 0;
01502 for (tmp = List; tmp != NULL; tmp = tmp->next)
01503 LatList[cnt++] = tmp->M;
01504
01505 qsort(LatList,cnt, sizeof (Lattice *), AffinePartCompare);
01506
01507 cnt = 0;
01508 for (tmp = List; tmp != NULL; tmp = tmp->next)
01509 tmp->M = LatList[cnt++];
01510 return;
01511 }
01512
01513 static Bool AlmostSameAffinePart(LatticeUnion *A, LatticeUnion *B) {
01514
01515 int i;
01516
01517 if ((A == NULL) || (B == NULL))
01518 return False;
01519
01520 for (i = 0; i < A->M->NbRows-1; i ++)
01521 if (value_ne(A->M->p[i][A->M->NbColumns-1],B->M->p[i][A->M->NbColumns-1]))
01522 return False;
01523 return True;
01524 }
01525
01526
01527
01528
01529
01530
01531
01532 static Bool AffinePartSimplify(LatticeUnion *curlist, LatticeUnion **newlist) {
01533
01534 int i;
01535 Value aux;
01536 LatticeUnion *temp, *curr, *next;
01537 LatticeUnion *nextlist;
01538 Bool change = False, chng;
01539
01540 if (curlist == NULL)
01541 return False;
01542
01543 if (curlist->next == NULL) {
01544 curlist->next = newlist[0];
01545 newlist[0] = curlist;
01546 return False ;
01547 }
01548
01549 value_init(aux);
01550 for (i = 0; i < curlist->M->NbRows - 1; i ++) {
01551
01552
01553
01554
01555 for (temp = curlist; temp != NULL; temp = temp->next) {
01556 value_assign(aux,temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1]);
01557 value_assign(temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1],temp->M->p[i][temp->M->NbColumns-1]);
01558 value_assign(temp->M->p[i][temp->M->NbColumns-1],aux);
01559 }
01560 AffinePartSort(curlist);
01561 nextlist = NULL;
01562 curr = curlist;
01563 while (curr != NULL) {
01564 next = curr->next;
01565 if (!AlmostSameAffinePart(curr, next)) {
01566 curr->next = NULL;
01567 chng = Simplify(&curlist, newlist, i);
01568 if (nextlist == NULL)
01569 nextlist = curlist;
01570 else {
01571 LatticeUnion *tmp;
01572 for (tmp = nextlist; tmp->next; tmp=tmp->next);
01573 tmp->next = curlist;
01574 }
01575 change = (Bool)(change | chng);
01576 curlist = next;
01577 }
01578 curr = next;
01579 }
01580 curlist = nextlist;
01581
01582
01583
01584
01585 for(temp = curlist; temp != NULL; temp = temp->next) {
01586 value_assign(aux,temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1]);
01587 value_assign(temp->M->p[temp->M->NbRows-1][temp->M->NbColumns-1],temp->M->p[i][temp->M->NbColumns-1]);
01588 value_assign(temp->M->p[i][temp->M->NbColumns-1],aux);
01589 }
01590 if (curlist == NULL)
01591 break;
01592 }
01593 if ( *newlist == NULL)
01594 *newlist = nextlist;
01595 else {
01596 for (curr = *newlist; curr->next != NULL; curr = curr->next);
01597 curr->next = nextlist;
01598 }
01599 value_clear(aux);
01600 return change;
01601 }
01602
01603 static Bool SameLinearPart(LatticeUnion *A, LatticeUnion *B) {
01604
01605 int i, j;
01606 if ((A == NULL) || (B ==NULL))
01607 return False;
01608 for (i = 0; i < A->M->NbRows-1; i++)
01609 for (j = 0; j <= i; j++)
01610 if (value_ne(A->M->p[i][j],B->M->p[i][j]))
01611 return False;
01612
01613 return True;
01614 }
01615
01616
01617
01618
01619 LatticeUnion *LatticeSimplify(LatticeUnion *latlist) {
01620
01621 LatticeUnion *curlist, *nextlist;
01622 LatticeUnion *curr, *next;
01623 Bool change = True, chng;
01624
01625 curlist = latlist;
01626 while (change == True) {
01627 change = False;
01628 LinearPartSort(curlist);
01629 curr = curlist;
01630 nextlist = NULL;
01631 while(curr != NULL) {
01632 next = curr->next;
01633 if (!SameLinearPart(curr, next)) {
01634 curr->next = NULL;
01635 chng = AffinePartSimplify(curlist, &nextlist);
01636 change = (Bool)(change | chng);
01637 curlist = next;
01638 }
01639 curr = next;
01640 }
01641 curlist = nextlist;
01642 }
01643 return curlist;
01644 }
01645
01646 int intcompare (const void *a, const void *b) {
01647
01648 int *i, *j;
01649
01650 i = (int *) a;
01651 j = (int *) b;
01652 if (*i > *j)
01653 return 1;
01654 if (*i < *j)
01655 return -1;
01656 return 0;
01657 }
01658
01659 static int polylib_sqrt(int i);
01660 static factor allfactors (int num) {
01661
01662 int i,j, tmp;
01663 int noofelmts = 1;
01664 int *list, *newlist;
01665 int count;
01666 factor result;
01667
01668 list = (int *)malloc(sizeof (int));
01669 list[0] = 1;
01670
01671 tmp = num;
01672 for (i = 2; i <= polylib_sqrt(tmp); i++) {
01673 if ((tmp % i) == 0) {
01674 if (noofelmts == 0) {
01675 list = (int *) malloc (sizeof (int));
01676 list[0] = i;
01677 noofelmts = 1;
01678 }
01679 else {
01680 newlist = (int *) malloc (sizeof (int) * 2 * noofelmts + 1);
01681 for (j = 0; j < noofelmts; j++)
01682 newlist[j] = list[j] ;
01683 newlist[j] = i;
01684 for (j = 0; j < noofelmts; j++)
01685 newlist[j+noofelmts+1] = i * list[j];
01686 free (list);
01687 list = newlist;
01688 noofelmts= 2*noofelmts+1;
01689 }
01690 tmp = tmp / i;
01691 i = 1;
01692 }
01693 }
01694
01695 if ((tmp != 0) && (tmp != num)) {
01696 newlist = (int *) malloc (sizeof (int) * 2 * noofelmts + 1);
01697 for (j = 0; j < noofelmts; j ++)
01698 newlist[j] = list[j] ;
01699 newlist[j] = tmp;
01700 for (j = 0; j < noofelmts; j ++)
01701 newlist[j+noofelmts+1] = tmp * list[j];
01702 free (list);
01703 list = newlist;
01704 noofelmts= 2*noofelmts+1;
01705 }
01706 qsort (list, noofelmts, sizeof(int), intcompare);
01707 count = 1;
01708 for (i = 1; i < noofelmts; i ++)
01709 if (list[i] != list[i-1])
01710 list[count++] = list[i];
01711 if (list[count-1] == num)
01712 count --;
01713
01714 result.fac = (int *) malloc (sizeof (int) * count);
01715 result.count = count;
01716 for (i = 0; i < count; i ++)
01717 result.fac[i] = list[i];
01718 free (list);
01719 return result;
01720 }
01721
01722 static int polylib_sqrt (int i) {
01723
01724 int j;
01725 j = 0;
01726 i = i > 0 ? i : -i;
01727
01728 while (1) {
01729 if ((j * j) > i)
01730 break;
01731 else
01732 j ++;
01733 }
01734 return (j-1);
01735 }
01736
01737
01738
01739
01740
01741
01742