34
34
#include < libsolutil/Algorithms.h>
35
35
#include < libsolutil/StringUtils.h>
36
36
37
- #include < boost/algorithm/string.hpp>
38
-
39
37
#include < range/v3/algorithm/for_each.hpp>
38
+ #include < range/v3/algorithm/none_of.hpp>
40
39
#include < range/v3/view.hpp>
41
40
#include < range/v3/view/enumerate.hpp>
42
41
#include < range/v3/view/reverse.hpp>
@@ -1895,7 +1894,7 @@ CHCSolverInterface::QueryResult CHC::query(smtutil::Expression const& _query, la
1895
1894
2339_error,
1896
1895
" CHC: Requested query:\n " + smtLibCode
1897
1896
);
1898
- return {.answer = CheckResult::UNKNOWN, .invariant = smtutil::Expression ( true ) , .cex = {}};
1897
+ return {.answer = CheckResult::UNKNOWN, .invariants = {} , .cex = {}};
1899
1898
}
1900
1899
auto result = m_interface->query (_query);
1901
1900
switch (result.answer )
@@ -2137,7 +2136,7 @@ void CHC::checkVerificationTargets()
2137
2136
namespace
2138
2137
{
2139
2138
std::map<Predicate const *, std::set<std::string>> collectInvariants (
2140
- smtutil::Expression const & _proof ,
2139
+ CHCSmtLib2Interface::Invariants const & _invariants ,
2141
2140
std::set<Predicate const *> const & _predicates,
2142
2141
ModelCheckerInvariants const & _invariantsSetting
2143
2142
)
@@ -2148,38 +2147,23 @@ std::map<Predicate const*, std::set<std::string>> collectInvariants(
2148
2147
if (_invariantsSetting.has (InvariantType::Reentrancy))
2149
2148
targets.insert (" nondet_interface_" );
2150
2149
2151
- std::map<std::string, std::pair<smtutil::Expression, smtutil::Expression>> equalities;
2152
- // Collect equalities where one of the sides is a predicate we're interested in.
2153
- util::BreadthFirstSearch<smtutil::Expression const *>{{&_proof}}.run ([&](auto && _expr, auto && _addChild) {
2154
- if (_expr->name == " =" )
2155
- for (auto const & t: targets)
2156
- {
2157
- auto arg0 = _expr->arguments .at (0 );
2158
- auto arg1 = _expr->arguments .at (1 );
2159
- if (boost::algorithm::starts_with (arg0.name , t))
2160
- equalities.insert ({arg0.name , {arg0, std::move (arg1)}});
2161
- else if (boost::algorithm::starts_with (arg1.name , t))
2162
- equalities.insert ({arg1.name , {arg1, std::move (arg0)}});
2163
- }
2164
- for (auto const & arg: _expr->arguments )
2165
- _addChild (&arg);
2166
- });
2167
-
2168
2150
std::map<Predicate const *, std::set<std::string>> invariants;
2169
- for (auto pred: _predicates)
2151
+ for (auto const * pred: _predicates)
2170
2152
{
2171
- auto predName = pred->functor ().name ;
2172
- if (!equalities.count (predName))
2153
+ smtAssert (pred);
2154
+ auto const & predName = pred->functor ().name ;
2155
+ if (!_invariants.contains (predName))
2156
+ continue ;
2157
+ if (ranges::none_of (targets, [&](auto const & _target) { return predName.starts_with (_target); }))
2173
2158
continue ;
2174
2159
2175
- solAssert (pred->contextContract (), " " );
2160
+ smtAssert (pred->contextContract ());
2176
2161
2177
- auto const & [predExpr, invExpr ] = equalities .at (predName);
2162
+ auto const & [definition, formalArguments ] = _invariants .at (predName);
2178
2163
2179
- static std::set<std::string> const ignore{" true" , " false" };
2180
- auto r = substitute (invExpr, pred->expressionSubstitution (predExpr));
2164
+ auto r = substitute (definition, pred->expressionSubstitution (formalArguments));
2181
2165
// No point in reporting true/false as invariants.
2182
- if (!ignore. count ( r.name ) )
2166
+ if (r. name != " true " && r.name != " false " )
2183
2167
invariants[pred].insert (toSolidityStr (r));
2184
2168
}
2185
2169
return invariants;
@@ -2205,7 +2189,7 @@ void CHC::checkAndReportTarget(
2205
2189
placeholder.constraints && placeholder.errorExpression == _target.errorId
2206
2190
);
2207
2191
auto const & location = _target.errorNode ->location ();
2208
- auto [result, invariant , model] = query (error (), location);
2192
+ auto [result, invariants , model] = query (error (), location);
2209
2193
if (result == CheckResult::UNSATISFIABLE)
2210
2194
{
2211
2195
m_safeTargets[_target.errorNode ].insert (_target);
@@ -2214,9 +2198,9 @@ void CHC::checkAndReportTarget(
2214
2198
predicates.insert (pred);
2215
2199
for (auto const * pred: m_nondetInterfaces | ranges::views::values)
2216
2200
predicates.insert (pred);
2217
- std::map<Predicate const *, std::set<std::string>> invariants = collectInvariants (invariant , predicates, m_settings.invariants );
2218
- for (auto pred: invariants | ranges::views::keys)
2219
- m_invariants[pred] += std::move (invariants .at (pred));
2201
+ std::map<Predicate const *, std::set<std::string>> invariantStrings = collectInvariants (invariants , predicates, m_settings.invariants );
2202
+ for (auto pred: invariantStrings | ranges::views::keys)
2203
+ m_invariants[pred] += std::move (invariantStrings .at (pred));
2220
2204
}
2221
2205
else if (result == CheckResult::SATISFIABLE)
2222
2206
{
0 commit comments