2 #include <barvinok/util.h>
3 #include "remove_equalities.h"
5 static void transform(Polyhedron
**P
, Polyhedron
**C
, Matrix
*CP
, int free
,
12 T
= align_matrix(CP
, Q
->Dimension
+1);
13 *P
= Polyhedron_Preimage(Q
, T
, MaxRays
);
19 *C
= Polyhedron_Preimage(D
, CP
, MaxRays
);
24 static Matrix
*compose_transformations(Matrix
*first
, Matrix
*second
)
31 combined
= Matrix_Alloc(first
->NbRows
, second
->NbColumns
);
32 Matrix_Product(first
, second
, combined
);
38 static Polyhedron
*replace_by_empty_polyhedron(Polyhedron
*Q
, int free
)
40 unsigned dim
= Q
->Dimension
;
43 return Empty_Polyhedron(dim
);
46 static int first_parameter_equality(Polyhedron
*Q
, unsigned nparam
)
53 for (i
= 0; i
< Q
->NbEq
; ++i
)
54 if (First_Non_Zero(Q
->Constraint
[i
]+1, Q
->Dimension
-nparam
) == -1)
60 static void remove_parameter_equalities(Polyhedron
**Q
, Polyhedron
**D
,
61 Matrix
**CP
, unsigned *nparam
,
62 int free
, unsigned MaxRays
)
66 /* We need to loop until we can't find any more equalities
67 * because the transformation may enable a simplification of the
68 * constraints resulting in new implicit equalities.
70 while ((i
= first_parameter_equality(*Q
, *nparam
)) < (*Q
)->NbEq
) {
71 Matrix
*M
= Matrix_Alloc((*Q
)->NbEq
, 1+*nparam
+1);
75 for (; i
< (*Q
)->NbEq
; ++i
) {
76 if (First_Non_Zero((*Q
)->Constraint
[i
]+1, (*Q
)->Dimension
-*nparam
) == -1)
77 Vector_Copy((*Q
)->Constraint
[i
]+1+(*Q
)->Dimension
-*nparam
,
78 M
->p
[n
++]+1, *nparam
+1);
81 T
= compress_variables(M
, 0);
84 *Q
= replace_by_empty_polyhedron(*Q
, free
);
87 transform(Q
, D
, T
, free
, MaxRays
);
88 *nparam
= T
->NbColumns
-1;
89 *CP
= compose_transformations(*CP
, T
);
95 /* Remove all equalities in P and the context C (if not NULL).
96 * Does not destroy P (or C).
97 * Returns transformation on the parameters in the Matrix pointed to by CPP
98 * (unless NULL) and transformation on the variables in the Matrix pointed to
99 * by CVP (unless NULL).
100 * Each of these transformation matrices maps the new parameters/variables
101 * back to the original ones.
102 * If it can be shown that there is no integer point in P, then
103 * an empty polyhedron will be returned.
105 int remove_all_equalities(Polyhedron
**P
, Polyhedron
**C
, Matrix
**CPP
, Matrix
**CVP
,
106 unsigned nparam
, unsigned MaxRays
)
111 Polyhedron
*D
= NULL
;
118 assert(D
->Dimension
== nparam
);
121 if (Q
->NbEq
== 0 && (!D
|| D
->NbEq
== 0))
125 Polyhedron_Matrix_View(D
, &M
, D
->NbEq
);
126 CP
= compress_variables(&M
, 0);
127 transform(&Q
, &D
, CP
, Q
!= *P
, MaxRays
);
128 nparam
= CP
->NbColumns
-1;
131 /* compress_parms doesn't like equalities that only involve parameters */
132 remove_parameter_equalities(&Q
, &D
, &CP
, &nparam
, Q
!= *P
, MaxRays
);
134 if (!emptyQ2(Q
) && Q
->NbEq
) {
136 Polyhedron_Matrix_View(Q
, &M
, Q
->NbEq
);
137 T
= compress_parms(&M
, nparam
);
139 Q
= replace_by_empty_polyhedron(Q
, Q
!= *P
);
140 } else if (isIdentity(T
)) {
143 transform(&Q
, &D
, T
, Q
!= *P
, MaxRays
);
144 CP
= compose_transformations(CP
, T
);
145 nparam
= CP
->NbColumns
-1;
146 remove_parameter_equalities(&Q
, &D
, &CP
, &nparam
, Q
!= *P
, MaxRays
);
150 /* We need to loop until we can't find any more equalities
151 * because the transformation may enable a simplification of the
152 * constraints resulting in new implicit equalities.
154 while (!emptyQ2(Q
) && Q
->NbEq
) {
156 Polyhedron_Matrix_View(Q
, &M
, Q
->NbEq
);
157 T
= compress_variables(&M
, nparam
);
159 Q
= replace_by_empty_polyhedron(Q
, Q
!= *P
);
160 } else if (isIdentity(T
)) {
163 R
= Polyhedron_Preimage(Q
, T
, MaxRays
);
164 CV
= compose_transformations(CV
, T
);