2
2
#define CONSTR_PREPRO_H
3
3
4
4
/* *
5
- * Preprocess flat constraints before adding
5
+ * Preprocess flat constraints before adding.
6
+ *
7
+ * Possible tasks:
8
+ * 1. Simplify constraints
9
+ * 2. Replace a functional constraint by a different one,
10
+ * via returning its result variable from another
11
+ * (see conditional inequalities).
6
12
*/
7
13
8
14
#include < cmath>
@@ -126,6 +132,8 @@ class ConstraintPreprocessors {
126
132
CondLinConEQ& c, PreprocessInfo& prepro) {
127
133
prepro.narrow_result_bounds (0.0 , 1.0 );
128
134
prepro.set_result_type ( var::INTEGER );
135
+ if (!IsNormalized (c))
136
+ c.GetConstraint ().negate (); // for equality
129
137
if (0 !=MPD ( IfPreproEqResBounds () ))
130
138
if (FixEqualityResult (c, prepro))
131
139
return ;
@@ -135,6 +143,16 @@ class ConstraintPreprocessors {
135
143
return ;
136
144
}
137
145
146
+ // / See if the argument of a conditional
147
+ // / algebraic constraint is normalized
148
+ template <class Body , int kind>
149
+ bool IsNormalized (
150
+ ConditionalConstraint<
151
+ AlgebraicConstraint< Body, AlgConRhs<kind> > >& cc) {
152
+ auto & arg = cc.GetConstraint ();
153
+ return arg.is_normalized ();
154
+ }
155
+
138
156
// / Preprocess CondQuadConEQ
139
157
template <class PreprocessInfo >
140
158
void PreprocessConstraint (
@@ -218,9 +236,21 @@ class ConstraintPreprocessors {
218
236
PreprocessInfo& prepro) {
219
237
prepro.narrow_result_bounds (0.0 , 1.0 );
220
238
prepro.set_result_type ( var::INTEGER );
221
- // See if we need to round the constant term
222
239
assert (kind);
223
240
auto & algc = cc.GetArguments ();
241
+ if (!IsNormalized (cc)) {
242
+ auto arg1 = algc;
243
+ arg1.negate (); // Negate the terms and sense
244
+ prepro.set_result_var (
245
+ MPD ( AssignResultVar2Args (
246
+ ConditionalConstraint<
247
+ AlgebraicConstraint< Body, AlgConRhs<
248
+ -kind> > > { {
249
+ std::move (arg1.GetBody ()), arg1.rhs ()
250
+ } } ) ));
251
+ return ;
252
+ }
253
+ // See if we need to round the constant term
224
254
auto rhs = algc.rhs ();
225
255
auto bnt_body = MPD (
226
256
ComputeBoundsAndType (algc.GetBody ()) );
0 commit comments