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
)
50 for (i
= 0; i
< Q
->NbEq
; ++i
)
51 if (First_Non_Zero(Q
->Constraint
[i
]+1, Q
->Dimension
-nparam
) == -1)
57 static void remove_parameter_equalities(Polyhedron
**Q
, Polyhedron
**D
,
58 Matrix
**CP
, unsigned *nparam
,
59 int free
, unsigned MaxRays
)
63 /* We need to loop until we can't find any more equalities
64 * because the transformation may enable a simplification of the
65 * constraints resulting in new implicit equalities.
67 while ((i
= first_parameter_equality(*Q
, *nparam
)) < (*Q
)->NbEq
) {
68 Matrix
*M
= Matrix_Alloc((*Q
)->NbEq
, 1+*nparam
+1);
72 for (; i
< (*Q
)->NbEq
; ++i
) {
73 if (First_Non_Zero((*Q
)->Constraint
[i
]+1, (*Q
)->Dimension
-*nparam
) == -1)
74 Vector_Copy((*Q
)->Constraint
[i
]+1+(*Q
)->Dimension
-*nparam
,
75 M
->p
[n
++]+1, *nparam
+1);
78 T
= compress_variables(M
, 0);
81 *Q
= replace_by_empty_polyhedron(*Q
, free
);
84 transform(Q
, D
, T
, free
, MaxRays
);
85 *nparam
= T
->NbColumns
-1;
86 *CP
= compose_transformations(*CP
, T
);
92 /* Remove all equalities in P and the context C (if not NULL).
93 * Does not destroy P (or C).
94 * Returns transformation on the parameters in the Matrix pointed to by CPP
95 * (unless NULL) and transformation on the variables in the Matrix pointed to
96 * by CVP (unless NULL).
97 * Each of these transformation matrices maps the new parameters/variables
98 * back to the original ones.
99 * If it can be shown that there is no integer point in P, then
100 * an empty polyhedron will be returned.
102 int remove_all_equalities(Polyhedron
**P
, Polyhedron
**C
, Matrix
**CPP
, Matrix
**CVP
,
103 unsigned nparam
, unsigned MaxRays
)
108 Polyhedron
*D
= NULL
;
115 assert(D
->Dimension
== nparam
);
118 if (Q
->NbEq
== 0 && (!D
|| D
->NbEq
== 0))
122 Polyhedron_Matrix_View(D
, &M
, D
->NbEq
);
123 CP
= compress_variables(&M
, 0);
124 transform(&Q
, &D
, CP
, Q
!= *P
, MaxRays
);
125 nparam
= CP
->NbColumns
-1;
128 /* compress_parms doesn't like equalities that only involve parameters */
129 remove_parameter_equalities(&Q
, &D
, &CP
, &nparam
, Q
!= *P
, MaxRays
);
131 if (!emptyQ2(Q
) && Q
->NbEq
) {
133 Polyhedron_Matrix_View(Q
, &M
, Q
->NbEq
);
134 T
= compress_parms(&M
, nparam
);
136 Q
= replace_by_empty_polyhedron(Q
, Q
!= *P
);
137 } else if (isIdentity(T
)) {
140 transform(&Q
, &D
, T
, Q
!= *P
, MaxRays
);
141 CP
= compose_transformations(CP
, T
);
142 nparam
= CP
->NbColumns
-1;
143 remove_parameter_equalities(&Q
, &D
, &CP
, &nparam
, Q
!= *P
, MaxRays
);
147 /* We need to loop until we can't find any more equalities
148 * because the transformation may enable a simplification of the
149 * constraints resulting in new implicit equalities.
151 while (!emptyQ2(Q
) && Q
->NbEq
) {
153 Polyhedron_Matrix_View(Q
, &M
, Q
->NbEq
);
154 T
= compress_variables(&M
, nparam
);
156 Q
= replace_by_empty_polyhedron(Q
, Q
!= *P
);
157 } else if (isIdentity(T
)) {
160 R
= Polyhedron_Preimage(Q
, T
, MaxRays
);
161 CV
= compose_transformations(CV
, T
);