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 static int is_translation(Matrix
*M
)
99 if (M
->NbRows
!= M
->NbColumns
)
102 for (i
= 0; i
< M
->NbRows
; ++i
)
103 for (j
= 0; j
< M
->NbColumns
-1; ++j
)
104 if (i
== j
? value_notone_p(M
->p
[i
][j
])
105 : value_notzero_p(M
->p
[i
][j
]))
111 /* Remove all equalities in P and the context C (if not NULL).
112 * Does not destroy P (or C).
113 * Returns transformation on the parameters in the Matrix pointed to by CPP
114 * (unless NULL) and transformation on the variables in the Matrix pointed to
115 * by CVP (unless NULL).
116 * Each of these transformation matrices maps the new parameters/variables
117 * back to the original ones.
118 * If it can be shown that there is no integer point in P, then
119 * an empty polyhedron will be returned.
121 int remove_all_equalities(Polyhedron
**P
, Polyhedron
**C
, Matrix
**CPP
, Matrix
**CVP
,
122 unsigned nparam
, unsigned MaxRays
)
127 Polyhedron
*D
= NULL
;
134 assert(D
->Dimension
== nparam
);
137 if (Q
->NbEq
== 0 && (!D
|| D
->NbEq
== 0))
141 Polyhedron_Matrix_View(D
, &M
, D
->NbEq
);
142 CP
= compress_variables(&M
, 0);
144 *C
= replace_by_empty_polyhedron(D
, D
!= *C
);
147 transform(&Q
, &D
, CP
, Q
!= *P
, MaxRays
);
148 nparam
= CP
->NbColumns
-1;
151 /* compress_parms doesn't like equalities that only involve parameters */
152 remove_parameter_equalities(&Q
, &D
, &CP
, &nparam
, Q
!= *P
, MaxRays
);
154 /* We need to loop until we can't find any more equalities
155 * because the transformation may enable a simplification of the
156 * constraints resulting in new implicit equalities.
158 while (!emptyQ2(Q
) && Q
->NbEq
) {
162 Polyhedron_Matrix_View(Q
, &M
, Q
->NbEq
);
163 T
= compress_parms(&M
, nparam
);
165 Q
= replace_by_empty_polyhedron(Q
, Q
!= *P
);
166 } else if (is_translation(T
)) {
170 transform(&Q
, &D
, T
, Q
!= *P
, MaxRays
);
171 CP
= compose_transformations(CP
, T
);
172 nparam
= CP
->NbColumns
-1;
173 remove_parameter_equalities(&Q
, &D
, &CP
, &nparam
, Q
!= *P
, MaxRays
);
175 } while (!emptyQ(Q
) && Q
->NbEq
&& T
);
177 if (emptyQ(Q
) || !Q
->NbEq
)
180 Polyhedron_Matrix_View(Q
, &M
, Q
->NbEq
);
181 T
= compress_variables(&M
, nparam
);
183 Q
= replace_by_empty_polyhedron(Q
, Q
!= *P
);
184 } else if (isIdentity(T
)) {
187 R
= Polyhedron_Preimage(Q
, T
, MaxRays
);
188 CV
= compose_transformations(CV
, T
);