@@ -50,20 +50,24 @@ find_indexes(const exprt &expr, const exprt &str, const symbol_exprt &qvar)
50
50
return result;
51
51
}
52
52
53
- std::map<exprt, int > map_representation_of_sum (const exprt &f)
53
+ linear_functiont::linear_functiont (const exprt &f)
54
54
{
55
- // number of times the leaf should be added (can be negative)
56
- std::map<exprt, int > elems;
57
-
55
+ type = f. type ();
56
+ // list of expressions to process with a boolean flag telling whether they
57
+ // appear positively or negatively (true is for positive)
58
58
std::list<std::pair<exprt, bool >> to_process;
59
59
to_process.emplace_back (f, true );
60
60
61
61
while (!to_process.empty ())
62
62
{
63
- exprt cur = to_process.back ().first ;
63
+ const exprt cur = to_process.back ().first ;
64
64
bool positive = to_process.back ().second ;
65
65
to_process.pop_back ();
66
- if (cur.id () == ID_plus)
66
+ if (auto integer = numeric_cast<mp_integer>(cur))
67
+ {
68
+ constant_coefficient += positive ? integer.value () : -integer.value ();
69
+ }
70
+ else if (cur.id () == ID_plus)
67
71
{
68
72
for (const auto &op : cur.operands ())
69
73
to_process.emplace_back (op, positive);
@@ -80,68 +84,48 @@ std::map<exprt, int> map_representation_of_sum(const exprt &f)
80
84
else
81
85
{
82
86
if (positive)
83
- ++elems [cur];
87
+ ++coefficients [cur];
84
88
else
85
- --elems [cur];
89
+ --coefficients [cur];
86
90
}
87
91
}
88
- return elems;
89
92
}
90
93
91
- exprt sum_over_map (std::map<exprt, int > &m, const typet &type, bool negated)
94
+ exprt linear_functiont::to_expr ( bool negated) const
92
95
{
93
- if (m.empty ())
94
- return from_integer (0 , type);
95
-
96
- exprt sum = nil_exprt ();
97
- mp_integer constants = 0 ;
98
- typet index_type = m.begin ()->first .type ();
96
+ exprt sum = nil_exprt{};
97
+ const exprt constant_expr = from_integer (constant_coefficient, type);
98
+ if (constant_coefficient != 0 )
99
+ sum = negated ? (exprt)unary_minus_exprt{constant_expr} : constant_expr;
99
100
100
- for (const auto &term : m )
101
+ for (const auto &term : coefficients )
101
102
{
102
103
const exprt &t = term.first ;
103
- int factor = negated ? (-term.second ) : term.second ;
104
- if (t. id () == ID_constant )
104
+ const mp_integer factor = negated ? (-term.second ) : term.second ;
105
+ if (factor == - 1 )
105
106
{
106
- // Constants are accumulated in the variable \c constants
107
- const auto int_value = numeric_cast_v<mp_integer>(to_constant_expr (t));
108
- constants += int_value * factor;
107
+ if (sum.is_nil ())
108
+ sum = unary_minus_exprt (t);
109
+ else
110
+ sum = minus_exprt (sum, t);
109
111
}
110
- else
112
+ else if (factor == 1 )
111
113
{
112
- switch (factor)
113
- {
114
- case -1 :
115
- if (sum.is_nil ())
116
- sum = unary_minus_exprt (t);
117
- else
118
- sum = minus_exprt (sum, t);
119
- break ;
120
-
121
- case 1 :
122
- if (sum.is_nil ())
123
- sum = t;
124
- else
125
- sum = plus_exprt (sum, t);
126
- break ;
127
-
128
- default :
129
- {
130
- const mult_exprt to_add{t, from_integer (factor, t.type ())};
131
- if (sum.is_nil ())
132
- sum = to_add;
133
- else
134
- sum = plus_exprt (sum, to_add);
135
- }
136
- }
114
+ if (sum.is_nil ())
115
+ sum = t;
116
+ else
117
+ sum = plus_exprt (sum, t);
118
+ }
119
+ else if (factor != 0 )
120
+ {
121
+ const mult_exprt to_add{t, from_integer (factor, t.type ())};
122
+ if (sum.is_nil ())
123
+ sum = to_add;
124
+ else
125
+ sum = plus_exprt (sum, to_add);
137
126
}
138
127
}
139
-
140
- const exprt index_const = from_integer (constants, index_type);
141
- if (sum.is_not_nil ())
142
- return plus_exprt (sum, index_const);
143
- else
144
- return index_const;
128
+ return sum.is_nil () ? from_integer (0 , type) : sum;
145
129
}
146
130
147
131
// / \param qvar: a symbol representing a universally quantified variable
@@ -161,14 +145,14 @@ compute_inverse_function(const exprt &qvar, const exprt &val, const exprt &f)
161
145
// qvar has to be equal to val - f(0) if it appears positively in f
162
146
// (i.e. if f(qvar)=f(0) + qvar) and f(0) - val if it appears negatively
163
147
// in f. So we start by computing val - f(0).
164
- std::map<exprt, int > elems = map_representation_of_sum ( minus_exprt (val, f)) ;
148
+ linear_functiont linear_function{ minus_exprt (val, f)} ;
165
149
166
- // true if qvar appears negatively in f (positively in elems ):
150
+ // true if qvar appears negatively in f (positively in linear_function ):
167
151
bool neg = false ;
168
152
169
- auto it = elems .find (qvar);
153
+ auto it = linear_function. coefficients .find (qvar);
170
154
INVARIANT (
171
- it != elems .end (),
155
+ it != linear_function. coefficients .end (),
172
156
string_refinement_invariantt (" a function must have an occurrence of qvar" ));
173
157
if (it->second == 1 || it->second == -1 )
174
158
{
@@ -184,8 +168,8 @@ compute_inverse_function(const exprt &qvar, const exprt &val, const exprt &f)
184
168
" have one" ));
185
169
}
186
170
187
- elems .erase (it);
188
- return sum_over_map (elems, f. type (), neg);
171
+ linear_function. coefficients .erase (it);
172
+ return linear_function. to_expr ( neg);
189
173
}
190
174
191
175
// / Instantiates a string constraint by substituting the quantifiers.
0 commit comments