polylib 5.22.8
alpha.c
Go to the documentation of this file.
1/* polytest.c */
2#include <polylib/polylib.h>
3#include <stdio.h>
4
5/* alpha.c
6 COPYRIGHT
7 Both this software and its documentation are
8
9 Copyright 1993 by IRISA /Universite de Rennes I - France,
10 Copyright 1995,1996 by BYU, Provo, Utah
11 all rights reserved.
12
13*/
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18
19/*---------------------------------------------------------------------*/
20/* int exist_points(pos,P,context) */
21/* pos : index position of current loop index (0..hdim-1) */
22/* P: loop domain */
23/* context : context values for fixed indices */
24/* recursive procedure, recurs for each imbriquation */
25/* returns 1 if there exists any integer points in this polyhedron */
26/* returns 0 if there are none */
27/*---------------------------------------------------------------------*/
28static int exist_points(int pos, Polyhedron *Pol, Value *context) {
29
30 Value LB, UB, k, tmp;
31
32 value_init(LB);
33 value_init(UB);
34 value_init(k);
35 value_init(tmp);
36 value_set_si(LB, 0);
37 value_set_si(UB, 0);
38
39 /* Problem if UB or LB is INFINITY */
40 if (lower_upper_bounds(pos, Pol, context, &LB, &UB) != 0) {
41 errormsg1("exist_points", "infdom", "infinite domain");
42 value_clear(LB);
43 value_clear(UB);
44 value_clear(k);
45 value_clear(tmp);
46 return -1;
47 }
48 value_set_si(context[pos], 0);
49 if (value_lt(UB, LB)) {
50 value_clear(LB);
51 value_clear(UB);
52 value_clear(k);
53 value_clear(tmp);
54 return 0;
55 }
56 if (!Pol->next) {
57 value_subtract(tmp, UB, LB);
58 value_increment(tmp, tmp);
59 value_clear(UB);
60 value_clear(LB);
61 value_clear(k);
62 return (value_pos_p(tmp));
63 }
64
65 for (value_assign(k, LB); value_le(k, UB); value_increment(k, k)) {
66
67 /* insert k in context */
68 value_assign(context[pos], k);
69 if (exist_points(pos + 1, Pol->next, context) > 0) {
70 value_clear(LB);
71 value_clear(UB);
72 value_clear(k);
73 value_clear(tmp);
74 return 1;
75 }
76 }
77 /* Reset context */
78 value_set_si(context[pos], 0);
79 value_clear(UB);
80 value_clear(LB);
81 value_clear(k);
82 value_clear(tmp);
83 return 0;
84}
85
86/*--------------------------------------------------------------*/
87/* Test to see if there are any integral points in a polyhedron */
88/*--------------------------------------------------------------*/
90
91 int res, i;
92 Value *context;
93 Polyhedron *L;
94
99
100 /* Create a context vector size dim+2 and set it to all zeros */
101 context = (Value *)malloc((P->Dimension + 2) * sizeof(Value));
102
103 /* Initialize array 'context' */
104 for (i = 0; i < (P->Dimension + 2); i++)
105 value_init(context[i]);
106
107 Vector_Set(context, 0, (P->Dimension + 2));
108
109 /* Set context[P->Dimension+1] = 1 (the constant) */
110 value_set_si(context[P->Dimension + 1], 1);
111
112 L = Polyhedron_Scan(P, C, MAXRAYS);
113 res = exist_points(1, L, context);
114 Domain_Free(L);
115
116 /* Clear array 'context' */
117 for (i = 0; i < (P->Dimension + 2); i++)
118 value_clear(context[i]);
119 free(context);
120 return res;
121}
122
123/* PolyhedronLTQ ( P1, P2 ) */
124/* P1 and P2 must be simple polyhedra */
125/* result = 0 --> not comparable */
126/* result = -1 --> P1 < P2 */
127/* result = 1 --> P1 > P2 */
128/* INDEX = 1 .... Dimension */
129int PolyhedronLTQ(Polyhedron *Pol1, Polyhedron *Pol2, int INDEX, int PDIM,
130 int NbMaxConstrs) {
131
132 int res, dim, i, j, k;
133 Polyhedron *Q1, *Q2, *Q3, *Q4, *Q;
134 Matrix *Mat;
135
136 if (Pol1->next || Pol2->next) {
137 errormsg1("PolyhedronLTQ", "compoly", "Can only compare polyhedra");
138 return 0;
139 }
140 if (Pol1->Dimension != Pol2->Dimension) {
141 errormsg1("PolyhedronLTQ", "diffdim", "Polyhedra are not same dimension");
142 return 0;
143 }
144 dim = Pol1->Dimension + 2;
145
146 POL_ENSURE_FACETS(Pol1);
148 POL_ENSURE_FACETS(Pol2);
150
151#ifdef DEBUG
152 fprintf(stdout, "P1\n");
153 Polyhedron_Print(stdout, P_VALUE_FMT, Pol1);
154 fprintf(stdout, "P2\n");
155 Polyhedron_Print(stdout, P_VALUE_FMT, Pol2);
156#endif
157
158 /* Create the Line to add */
159 k = Pol1->Dimension - INDEX + 1 - PDIM;
160 Mat = Matrix_Alloc(k, dim);
161 Vector_Set(Mat->p_Init, 0, dim * k);
162 for (j = 0, i = INDEX; j < k; i++, j++)
163 value_set_si(Mat->p[j][i], 1);
164
165 Q1 = AddRays(Mat->p[0], k, Pol1, NbMaxConstrs);
166 Q2 = AddRays(Mat->p[0], k, Pol2, NbMaxConstrs);
167
168#ifdef DEBUG
169 fprintf(stdout, "Q1\n");
170 Polyhedron_Print(stdout, P_VALUE_FMT, Q1);
171 fprintf(stdout, "Q2\n");
172 Polyhedron_Print(stdout, P_VALUE_FMT, Q2);
173#endif
174
175 Matrix_Free(Mat);
176 Q = DomainIntersection(Q1, Q2, NbMaxConstrs);
177
178#ifdef DEBUG
179 fprintf(stdout, "Q\n");
180 Polyhedron_Print(stdout, P_VALUE_FMT, Q);
181#endif
182
183 Domain_Free(Q1);
184 Domain_Free(Q2);
185
186 if (emptyQ(Q))
187 res = 0; /* not comparable */
188 else {
189 Q1 = DomainIntersection(Pol1, Q, NbMaxConstrs);
190 Q2 = DomainIntersection(Pol2, Q, NbMaxConstrs);
191
192#ifdef DEBUG
193 fprintf(stdout, "Q1\n");
194 Polyhedron_Print(stdout, P_VALUE_FMT, Q1);
195 fprintf(stdout, "Q2\n");
196 Polyhedron_Print(stdout, P_VALUE_FMT, Q2);
197#endif
198
199 k = Q1->NbConstraints + Q2->NbConstraints;
200 Mat = Matrix_Alloc(k, dim);
201 Vector_Set(Mat->p_Init, 0, k * dim);
202
203 /* First compute surrounding polyhedron */
204 j = 0;
205 for (i = 0; i < Q1->NbConstraints; i++) {
206 if ((value_one_p(Q1->Constraint[i][0])) &&
207 (value_pos_p(Q1->Constraint[i][INDEX]))) {
208
209 /* keep Q1's lower bounds */
210 for (k = 0; k < dim; k++)
211 value_assign(Mat->p[j][k], Q1->Constraint[i][k]);
212 j++;
213 }
214 }
215 for (i = 0; i < Q2->NbConstraints; i++) {
216 if ((value_one_p(Q2->Constraint[i][0])) &&
217 (value_neg_p(Q2->Constraint[i][INDEX]))) {
218
219 /* and keep Q2's upper bounds */
220 for (k = 0; k < dim; k++)
221 value_assign(Mat->p[j][k], Q2->Constraint[i][k]);
222 j++;
223 }
224 }
225 Q4 = AddConstraints(Mat->p[0], j, Q, NbMaxConstrs);
226 Matrix_Free(Mat);
227
228#ifdef debug
229 fprintf(stderr, "Q4 surrounding polyhedron\n");
230 Polyhderon_Print(stderr, P_VALUE_FMT, Q4);
231#endif
232
233 /* if surrounding polyhedron is empty, D1>D2 */
234 if (emptyQ(Q4)) {
235 res = 1;
236
237#ifdef debug
238 fprintf(stderr, "Surrounding polyhedron is empty\n");
239#endif
240 goto LTQdone2;
241 }
242
243 /* Test if Q1 < Q2 */
244 /* Build a constraint array for >= Q1 and <= Q2 */
245 Mat = Matrix_Alloc(2, dim);
246 Vector_Set(Mat->p_Init, 0, 2 * dim);
247
248 /* Choose a contraint from Q1 */
249 for (i = 0; i < Q1->NbConstraints; i++) {
250 if (value_zero_p(Q1->Constraint[i][0])) {
251
252 /* Equality */
253 if (value_zero_p(Q1->Constraint[i][INDEX])) {
254
255 /* Ignore side constraint (they are in Q) */
256 continue;
257 } else if (value_neg_p(Q1->Constraint[i][INDEX])) {
258
259 /* copy -constraint to Mat */
260 value_set_si(Mat->p[0][0], 1);
261 for (k = 1; k < dim; k++)
262 value_oppose(Mat->p[0][k], Q1->Constraint[i][k]);
263 } else {
264
265 /* Copy constraint to Mat */
266
267 value_set_si(Mat->p[0][0], 1);
268 for (k = 1; k < dim; k++)
269 value_assign(Mat->p[0][k], Q1->Constraint[i][k]);
270 }
271 } else if (value_neg_p(Q1->Constraint[i][INDEX])) {
272
273 /* Upper bound -- make a lower bound from it */
274 value_set_si(Mat->p[0][0], 1);
275 for (k = 1; k < dim; k++)
276 value_oppose(Mat->p[0][k], Q1->Constraint[i][k]);
277 } else {
278
279 /* Lower or side bound -- ignore it */
280 continue;
281 }
282
283 /* Choose a constraint from Q2 */
284 for (j = 0; j < Q2->NbConstraints; j++) {
285 if (value_zero_p(Q2->Constraint[j][0])) { /* equality */
286 if (value_zero_p(Q2->Constraint[j][INDEX])) {
287
288 /* Ignore side constraint (they are in Q) */
289 continue;
290 } else if (value_pos_p(Q2->Constraint[j][INDEX])) {
291
292 /* Copy -constraint to Mat */
293 value_set_si(Mat->p[1][0], 1);
294 for (k = 1; k < dim; k++)
295 value_oppose(Mat->p[1][k], Q2->Constraint[j][k]);
296 } else {
297
298 /* Copy constraint to Mat */
299 value_set_si(Mat->p[1][0], 1);
300 for (k = 1; k < dim; k++)
301 value_assign(Mat->p[1][k], Q2->Constraint[j][k]);
302 };
303 } else if (value_pos_p(Q2->Constraint[j][INDEX])) {
304
305 /* Lower bound -- make an upper bound from it */
306 value_set_si(Mat->p[1][0], 1);
307 for (k = 1; k < dim; k++)
308 value_oppose(Mat->p[1][k], Q2->Constraint[j][k]);
309 } else {
310
311 /* Upper or side bound -- ignore it */
312 continue;
313 };
314
315#ifdef DEBUG
316 fprintf(stdout, "i=%d j=%d M=\n", i + 1, j + 1);
317 Matrix_Print(stdout, P_VALUE_FMT, Mat);
318#endif
319
320 /* Add Mat to Q and see if anything is made */
321 Q3 = AddConstraints(Mat->p[0], 2, Q, NbMaxConstrs);
322
323#ifdef DEBUG
324 fprintf(stdout, "Q3\n");
325 Polyhedron_Print(stdout, P_VALUE_FMT, Q3);
326#endif
327
328 if (!emptyQ(Q3)) {
329 Domain_Free(Q3);
330
331#ifdef DEBUG
332 fprintf(stdout, "not empty\n");
333#endif
334 res = -1;
335 goto LTQdone;
336 }
337#ifdef DEBUG
338 fprintf(stdout, "empty\n");
339#endif
340 Domain_Free(Q3);
341 } /* end for j */
342 } /* end for i */
343 res = 1;
344 LTQdone:
345 Matrix_Free(Mat);
346 LTQdone2:
347 Domain_Free(Q4);
348 Domain_Free(Q1);
349 Domain_Free(Q2);
350 }
351 Domain_Free(Q);
352
353#ifdef DEBUG
354 fprintf(stdout, "res = %d\n", res);
355#endif
356
357 return res;
358} /* PolyhedronLTQ */
359
360/* GaussSimplify --
361 Given Mat1, a matrix of equalities, performs Gaussian elimination.
362 Find a minimum basis, Returns the rank.
363 Mat1 is context, Mat2 is reduced in context of Mat1
364*/
365int GaussSimplify(Matrix *Mat1, Matrix *Mat2) {
366
367 int NbRows = Mat1->NbRows;
368 int NbCols = Mat1->NbColumns;
369 int *column_index;
370 int i, j, k, n, t, pivot, Rank;
371 Value gcd, tmp, *cp;
372
373 column_index = (int *)malloc(NbCols * sizeof(int));
374 if (!column_index) {
375 errormsg1("GaussSimplify", "outofmem", "out of memory space\n");
376 Pol_status = 1;
377 return 0;
378 }
379
380 /* Initialize all the 'Value' variables */
381 value_init(gcd);
382 value_init(tmp);
383
384 Rank = 0;
385 for (j = 0; j < NbCols; j++) { /* for each column starting at */
386 for (i = Rank; i < NbRows; i++) /* diagonal, look down to find */
387 if (value_notzero_p(Mat1->p[i][j])) /* the first non-zero entry */
388 break;
389 if (i != NbRows) { /* was one found ? */
390 if (i != Rank) /* was it found below the diagonal?*/
391 Vector_Exchange(Mat1->p[Rank], Mat1->p[i], NbCols);
392
393 /* Normalize the pivot row */
394 Vector_Gcd(Mat1->p[Rank], NbCols, &gcd);
395
396 /* If (gcd >= 2) */
397 value_set_si(tmp, 2);
398 if (value_ge(gcd, tmp)) {
399 cp = Mat1->p[Rank];
400 for (k = 0; k < NbCols; k++, cp++)
401 value_division(*cp, *cp, gcd);
402 }
403 if (value_neg_p(Mat1->p[Rank][j])) {
404 cp = Mat1->p[Rank];
405 for (k = 0; k < NbCols; k++, cp++)
406 value_oppose(*cp, *cp);
407 }
408 /* End of normalize */
409 pivot = i;
410 for (i = 0; i < NbRows; i++) /* Zero out the rest of the column */
411 if (i != Rank) {
412 if (value_notzero_p(Mat1->p[i][j])) {
413 Value a, a1, a2, a1abs, a2abs;
414 value_init(a);
415 value_init(a1);
416 value_init(a2);
417 value_init(a1abs);
418 value_init(a2abs);
419 value_assign(a1, Mat1->p[i][j]);
420 value_absolute(a1abs, a1);
421 value_assign(a2, Mat1->p[Rank][j]);
422 value_absolute(a2abs, a2);
423 value_gcd(a, a1abs, a2abs);
424 value_divexact(a1, a1, a);
425 value_divexact(a2, a2, a);
426 value_oppose(a1, a1);
427 Vector_Combine(Mat1->p[i], Mat1->p[Rank], Mat1->p[i], a2, a1,
428 NbCols);
429 Vector_Normalize(Mat1->p[i], NbCols);
430 value_clear(a);
431 value_clear(a1);
432 value_clear(a2);
433 value_clear(a1abs);
434 value_clear(a2abs);
435 }
436 }
437 column_index[Rank] = j;
438 Rank++;
439 }
440 } /* end of Gauss elimination */
441
442 if (Mat2) { /* Mat2 is a transformation matrix (i,j->f(i,j))....
443 can't scale it because can't scale both sides of -> */
444 /* normalizes an affine transformation */
445 /* priority of forms */
446 /* 1. i' -> i (identity) */
447 /* 2. i' -> i + constant (uniform) */
448 /* 3. i' -> constant (broadcast) */
449 /* 4. i' -> j (permutation) */
450 /* 5. i' -> j + constant ( ) */
451 /* 6. i' -> i + j + constant (non-uniform) */
452 for (k = 0; k < Rank; k++) {
453 j = column_index[k];
454 for (i = 0; i < (Mat2->NbRows - 1);
455 i++) { /* all but the last row 0...0 1 */
456 if ((i != j) && value_notzero_p(Mat2->p[i][j])) {
457
458 /* Remove dependency of i' on j */
459 Value a, a1, a1abs, a2, a2abs;
460 value_init(a);
461 value_init(a1);
462 value_init(a2);
463 value_init(a1abs);
464 value_init(a2abs);
465 value_assign(a1, Mat2->p[i][j]);
466 value_absolute(a1abs, a1);
467 value_assign(a2, Mat1->p[k][j]);
468 value_absolute(a2abs, a2);
469 value_gcd(a, a1abs, a2abs);
470 value_divexact(a1, a1, a);
471 value_divexact(a2, a2, a);
472 value_oppose(a1, a1);
473 if (value_one_p(a2)) {
474 Vector_Combine(Mat2->p[i], Mat1->p[k], Mat2->p[i], a2, a1, NbCols);
475
476 /* Vector_Normalize(Mat2->p[i],NbCols); -- can't do T */
477 } /* otherwise, can't do it without mult lhs prod (2i,3j->...) */
478 value_clear(a);
479 value_clear(a1);
480 value_clear(a2);
481 value_clear(a1abs);
482 value_clear(a2abs);
483
484 } else if ((i == j) && value_zero_p(Mat2->p[i][j])) {
485
486 /* 'i' does not depend on j */
487 for (n = j + 1; n < (NbCols - 1); n++) {
488 if (value_notzero_p(Mat2->p[i][n])) { /* i' depends on some n */
489 value_set_si(tmp, 1);
490 Vector_Combine(Mat2->p[i], Mat1->p[k], Mat2->p[i], tmp, tmp,
491 NbCols);
492 break;
493 } /* if 'i' depends on just a constant, then leave it alone.*/
494 }
495 }
496 }
497 }
498
499 /* Check last row of transformation Mat2 */
500 for (j = 0; j < (NbCols - 1); j++)
501 if (value_notzero_p(Mat2->p[Mat2->NbRows - 1][j])) {
502 errormsg1("GaussSimplify", "corrtrans", "Corrupted transformation\n");
503 break;
504 }
505
506 if (value_notone_p(Mat2->p[Mat2->NbRows - 1][NbCols - 1])) {
507 errormsg1("GaussSimplify", "corrtrans", "Corrupted transformation\n");
508 }
509 }
510 value_clear(gcd);
511 value_clear(tmp);
512 free(column_index);
513 return Rank;
514} /* GaussSimplify */
515
516/*
517 * Topologically sort 'n' polyhdera and return 0 on failure, otherwise return
518 * 1 on success. Here 'L' is a an array of pointers to polyhedra, 'n' is the
519 * number of polyhedra, 'index' is the level to consider for partial ordering
520 * 'pdim' is the parameter space dimension, 'time' is an array of 'n' integers
521 * to store logical time values, 'pvect', if not NULL, is an array of 'n'
522 * integers that contains a permutation specification after call and MAXRAYS is
523 * the workspace size for polyhedra operations.
524 */
525int PolyhedronTSort(Polyhedron **L, unsigned int n, unsigned int index,
526 unsigned int pdim, int *time, int *pvect,
527 unsigned int MAXRAYS) {
528
529 unsigned int const nbcells =
530 ((n * (n - 1)) >> 1); /* Number of memory cells
531 to allocate, see below */
532 int *dag; /* The upper triangular matrix */
533 int **p; /* Array of matrix row addresses */
534 unsigned int i, j, k;
535 unsigned int t, nb, isroot;
536
537 if (n < 2)
538 return 0;
539
540 /* we need an upper triangular matrix (example with n=4):
541
542 . o o o
543 . . o o . are unuseful cells, o are useful cells
544 . . . o
545 . . . .
546
547 so we need to allocate (n)(n-1)/2 cells
548 - dag will point to this memory.
549 - p[i] will point to row i of the matrix
550 p[0] = dag - 1 (such that p[0][1] == dag[0])
551 p[1] = dag - 1 + (n-1)
552 p[2] = dag - 1 + (n-1) + (n-2)
553 ...
554 p[i] = p[i-1] + (n-1-i)
555 */
556
557 /* malloc n(n-1)/2 for dag and n-1 for p (node n does not have any row) */
558 dag = (int *)malloc(nbcells * sizeof(int));
559 if (!dag)
560 return 0;
561 p = (int **)malloc((n - 1) * sizeof(int *));
562 if (!p) {
563 free(dag);
564 return 0;
565 }
566
567 /* Initialize 'p' and 'dag' */
568 p[0] = dag - 1;
569 for (i = 1; i < n - 1; i++)
570 p[i] = p[i - 1] + (n - 1) - i;
571 for (i = 0; i < nbcells; i++)
572 dag[i] = -2; /* -2 means 'not computed yet' */
573 for (i = 0; i < n; i++)
574 time[i] = -1;
575
576 /* Compute the dag using transitivity to reduce the number of */
577 /* PolyhedronLTQ calls. */
578 for (i = 0; i < n - 1; i++) {
579 POL_ENSURE_FACETS(L[i]);
581 for (j = i + 1; j < n; j++) {
582 if (p[i][j] == -2) /* not computed yes */
583 p[i][j] = PolyhedronLTQ(L[i], L[j], index, pdim, MAXRAYS);
584 if (p[i][j] != 0) {
585
586 /* if p[i][j] is 1 or -1, look for -p[i][j] on the same row:
587 p[i][j] == -p[i][k] ==> p[j][k] = p[i][k] (transitivity)
588 note: p[r][c] == -p[c][r], use this to avoid reading or writing
589 under the matrix diagonal
590 */
591
592 /* first, k<i so look for p[i][j] == p[k][i] (i.e. -p[i][k]) */
593 for (k = 0; k < i; k++)
594 if (p[k][i] == p[i][j])
595 p[k][j] = p[k][i];
596
597 /* then, i<k<j so look for p[i][j] == -p[i][k] */
598 for (k = i + 1; k < j; k++)
599 if (p[i][k] == -p[i][j])
600 p[k][j] = -p[i][k];
601
602 /* last, k>j same search but */
603 for (k = j + 1; k < n; k++)
604 if (p[i][k] == -p[i][j])
605 p[j][k] = p[i][k];
606 }
607 }
608 }
609
610 /* walk thru the dag to compute the partial order (and optionally
611 the permutation)
612 Note: this is not the fastest way to do it but it takes
613 negligible time compared to a single call of PolyhedronLTQ !
614 Each macro-step (while loop) gives the same logical time to all
615 found roots and optionally add these nodes in the permutation vector
616 */
617
618 t = 0; /* current logical time, assigned to current roots and
619 increased by 1 at the end of each step */
620 nb = 0; /* number of processed nodes (have been given a time) */
621 while (nb < n) {
622 for (i = 0; i < n; i++) { /* search for roots */
623 /* for any node, if it's not already been given a logical time
624 then walk thru the node row; if we find a 1 at some column j,
625 it means that node j preceeds the current node, so it is not
626 a root */
627 if (time[i] < 0) {
628 isroot = 1; /* assume that it is until it is definitely not */
629 /* first search on a column */
630 for (j = 0; j < i; j++) {
631 if (p[j][i] == -1) { /* found a node lower than it */
632 isroot = 0;
633 break;
634 }
635 }
636 if /*still*/ (isroot)
637 for (j = i + 1; j < n; j++) {
638 if (p[i][j] == 1) { /* greater than this node */
639 isroot = 0;
640 break;
641 }
642 }
643 if (isroot) { /* then it definitely is */
644 time[i] = t; /* this node gets current logical time */
645 if (pvect)
646 pvect[nb] = i + 1; /* nodes will be numbered from 1 to n */
647 nb++; /* one more node processed */
648 }
649 }
650 }
651 /* now make roots become neutral, i.e. non comparable with all other nodes
652 */
653 for (i = 0; i < n; i++) {
654 if (time[i] == t) {
655 for (j = 0; j < i; j++)
656 p[j][i] = 0;
657 for (j = i + 1; j < n; j++)
658 p[i][j] = 0;
659 }
660 }
661 t++; /* ready for next set of root nodes */
662 }
663
664 free(p); /* let's be clean, collect the garbage */
665 free(dag);
666 return 1;
667} /* PolyhedronTSort */
int PolyhedronLTQ(Polyhedron *Pol1, Polyhedron *Pol2, int INDEX, int PDIM, int NbMaxConstrs)
Definition: alpha.c:129
static int exist_points(int pos, Polyhedron *Pol, Value *context)
Definition: alpha.c:28
int Polyhedron_Not_Empty(Polyhedron *P, Polyhedron *C, int MAXRAYS)
Definition: alpha.c:89
int PolyhedronTSort(Polyhedron **L, unsigned int n, unsigned int index, unsigned int pdim, int *time, int *pvect, unsigned int MAXRAYS)
Definition: alpha.c:525
int GaussSimplify(Matrix *Mat1, Matrix *Mat2)
Definition: alpha.c:365
#define value_pos_p(val)
Definition: arithmetique.h:571
#define value_oppose(ref, val)
Definition: arithmetique.h:552
#define value_le(v1, v2)
Definition: arithmetique.h:507
#define value_notzero_p(val)
Definition: arithmetique.h:576
#define value_divexact(ref, val1, val2)
Definition: arithmetique.h:548
#define value_gcd(ref, val1, val2)
Definition: arithmetique.h:556
#define value_notone_p(val)
Definition: arithmetique.h:578
#define value_one_p(val)
Definition: arithmetique.h:577
#define value_absolute(ref, val)
Definition: arithmetique.h:553
#define value_zero_p(val)
Definition: arithmetique.h:575
#define value_assign(v1, v2)
Definition: arithmetique.h:482
#define value_increment(ref, val)
Definition: arithmetique.h:540
#define value_set_si(val, i)
Definition: arithmetique.h:483
#define value_clear(val)
Definition: arithmetique.h:485
#define value_division(ref, val1, val2)
Definition: arithmetique.h:547
#define value_lt(v1, v2)
Definition: arithmetique.h:506
#define value_subtract(ref, val1, val2)
Definition: arithmetique.h:544
#define value_ge(v1, v2)
Definition: arithmetique.h:505
#define value_neg_p(val)
Definition: arithmetique.h:572
#define value_init(val)
Definition: arithmetique.h:481
void errormsg1(const char *f, const char *msgname, const char *msg)
Definition: errormsg.c:25
int Pol_status
Definition: polyhedron.c:72
Matrix * Matrix_Alloc(unsigned NbRows, unsigned NbColumns)
Definition: matrix.c:24
void Matrix_Print(FILE *Dst, const char *Format, Matrix *Mat)
Definition: matrix.c:115
void Matrix_Free(Matrix *Mat)
Definition: matrix.c:71
Polyhedron * AddRays(Value *AddedRays, unsigned NbAddedRays, Polyhedron *Pol, unsigned NbMaxConstrs)
Add 'NbAddedRays' rays to polyhedron 'Pol'.
Definition: polyhedron.c:2696
Polyhedron * Polyhedron_Scan(Polyhedron *D, Polyhedron *C, unsigned NbMaxRays)
Definition: polyhedron.c:3838
Polyhedron * DomainIntersection(Polyhedron *Pol1, Polyhedron *Pol2, unsigned NbMaxRays)
Return the intersection of two polyhedral domains 'Pol1' and 'Pol2'.
Definition: polyhedron.c:2637
int lower_upper_bounds(int pos, Polyhedron *P, Value *context, Value *LBp, Value *UBp)
Definition: polyhedron.c:3905
Polyhedron * AddConstraints(Value *Con, unsigned NbConstraints, Polyhedron *Pol, unsigned NbMaxRays)
Definition: polyhedron.c:2303
void Polyhedron_Print(FILE *Dst, const char *Format, const Polyhedron *Pol)
Definition: polyhedron.c:1639
void Domain_Free(Polyhedron *Pol)
Definition: polyhedron.c:1626
#define POL_ENSURE_VERTICES(P)
Definition: polyhedron.h:17
#define POL_ENSURE_FACETS(P)
Definition: polyhedron.h:13
static int n
Definition: polyparam.c:276
Definition: types.h:75
unsigned NbRows
Definition: types.h:76
Value ** p
Definition: types.h:77
unsigned NbColumns
Definition: types.h:76
Value * p_Init
Definition: types.h:78
unsigned Dimension
Definition: types.h:94
unsigned NbConstraints
Definition: types.h:94
struct polyhedron * next
Definition: types.h:99
Value ** Constraint
Definition: types.h:95
#define emptyQ(P)
Definition: types.h:118
#define P_VALUE_FMT
Definition: types.h:39
void Vector_Set(Value *p, int n, unsigned length)
Definition: vector.c:227
void Vector_Combine(Value *p1, Value *p2, Value *p3, Value lambda, Value mu, unsigned length)
Definition: vector.c:425
void Vector_Gcd(Value *p, unsigned length, Value *min)
Definition: vector.c:485
void Vector_Exchange(Value *p1, Value *p2, unsigned length)
Definition: vector.c:243
void Vector_Normalize(Value *p, unsigned length)
Definition: vector.c:555
#define MAXRAYS
Definition: verif_ehrhart.c:20