@@ -136,48 +136,24 @@ exprt linear_functiont::to_expr(bool negated) const
136
136
return sum.is_nil () ? from_integer (0 , type) : sum;
137
137
}
138
138
139
- // / \param qvar: a symbol representing a universally quantified variable
140
- // / \param val: an expression
141
- // / \param f: an expression containing `+` and `-`
142
- // / operations in which `qvar` should appear exactly once.
143
- // / \return an expression corresponding of $f^{-1}(val)$ where $f$ is seen as
144
- // / a function of $qvar$, i.e. the value that is necessary for `qvar` for `f`
145
- // / to be equal to `val`. For instance, if `f` corresponds to the expression
146
- // / $q + x$, `compute_inverse_function(q,v,f)` returns an expression
147
- // / for $v - x$.
148
- static exprt
149
- compute_inverse_function (const exprt &qvar, const exprt &val, const exprt &f)
139
+ exprt linear_functiont::solve (
140
+ linear_functiont f,
141
+ const exprt &var,
142
+ const exprt &val)
150
143
{
151
- exprt positive, negative;
152
- // number of times the element should be added (can be negative)
153
- // qvar has to be equal to val - f(0) if it appears positively in f
154
- // (i.e. if f(qvar)=f(0) + qvar) and f(0) - val if it appears negatively
155
- // in f. So we start by computing val - f(0).
156
- linear_functiont linear_function{minus_exprt (val, f)};
157
-
158
- // true if qvar appears negatively in f (positively in linear_function):
159
- bool neg = false ;
160
-
161
- auto it = linear_function.coefficients .find (qvar);
162
- INVARIANT (
163
- it != linear_function.coefficients .end (),
164
- string_refinement_invariantt (" a function must have an occurrence of qvar" ));
165
- if (it->second == 1 || it->second == -1 )
166
- {
167
- neg = (it->second == 1 );
168
- }
169
- else
170
- {
171
- INVARIANT (
172
- it->second == 0 ,
173
- string_refinement_invariantt (
174
- " a proper function must have exactly one "
175
- " occurrence after reduction, or it cancelled out, and it does not"
176
- " have one" ));
177
- }
178
-
179
- linear_function.coefficients .erase (it);
180
- return linear_function.to_expr (neg);
144
+ auto it = f.coefficients .find (var);
145
+ PRECONDITION (it != f.coefficients .end ());
146
+ PRECONDITION (it->second == 1 || it->second == -1 );
147
+ const bool positive = it->second == 1 ;
148
+
149
+ // Transform `f` into `f(var <- 0)`
150
+ f.coefficients .erase (it);
151
+ // Transform `f(var <- 0)` into `f(var <- 0) - val`
152
+ f.add (linear_functiont{unary_minus_exprt{val}});
153
+
154
+ // If the coefficient of var is 1 then solution `val - f(var <- 0),
155
+ // otherwise `f(var <- 0) - val`
156
+ return f.to_expr (positive);
181
157
}
182
158
183
159
// / Instantiates a string constraint by substituting the quantifiers.
@@ -204,7 +180,7 @@ exprt instantiate(
204
180
for (const auto &index : find_indexes (axiom.body , str, axiom.univ_var ))
205
181
{
206
182
const exprt univ_var_value =
207
- compute_inverse_function ( axiom.univ_var , val, index );
183
+ linear_functiont::solve (linear_functiont{index}, axiom.univ_var , val);
208
184
implies_exprt instance (
209
185
and_exprt (
210
186
binary_relation_exprt (axiom.univ_var , ID_ge, axiom.lower_bound ),
0 commit comments