Skip to content

Commit d9b6f15

Browse files
committed
boolbv backend honors forall/exists scopes
The boolbv backend now introduces new names for the bound symbols. This matches the new behavior for let expressions.
1 parent 523622a commit d9b6f15

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

src/solvers/flattening/boolbv.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,29 @@ bool boolbvt::is_unbounded_array(const typet &type) const
552552
return false;
553553
}
554554

555+
binding_exprt::variablest boolbvt::fresh_binding(const binding_exprt &binding)
556+
{
557+
// to ensure freshness of the new identifiers
558+
scope_counter++;
559+
560+
binding_exprt::variablest result;
561+
result.reserve(binding.variables().size());
562+
563+
for(const auto &binding : binding.variables())
564+
{
565+
const auto &old_identifier = binding.get_identifier();
566+
567+
// produce a new identifier
568+
const irep_idt new_identifier =
569+
"boolbvt::scope::" + std::to_string(scope_counter) +
570+
"::" + id2string(old_identifier);
571+
572+
result.emplace_back(new_identifier, binding.type());
573+
}
574+
575+
return result;
576+
}
577+
555578
void boolbvt::print_assignment(std::ostream &out) const
556579
{
557580
arrayst::print_assignment(out);

src/solvers/flattening/boolbv.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,9 @@ class boolbvt:public arrayst
274274

275275
// scopes
276276
std::size_t scope_counter = 0;
277+
278+
/// create new, unique variables for the given binding
279+
binding_exprt::variablest fresh_binding(const binding_exprt &);
277280
};
278281

279282
#endif // CPROVER_SOLVERS_FLATTENING_BOOLBV_H

src/solvers/flattening/boolbv_quantifier.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ Author: Daniel Kroening, kroening@kroening.com
1212
#include <util/expr_util.h>
1313
#include <util/invariant.h>
1414
#include <util/optional.h>
15+
#include <util/range.h>
1516
#include <util/replace_expr.h>
17+
#include <util/replace_symbol.h>
1618
#include <util/simplify_expr.h>
1719

1820
/// A method to detect equivalence between experts that can contain typecast
@@ -206,6 +208,22 @@ literalt boolbvt::convert_quantifier(const quantifier_exprt &src)
206208
{
207209
PRECONDITION(src.id() == ID_forall || src.id() == ID_exists);
208210

211+
// We first worry about the scoping of the symbols bound by the quantifier.
212+
auto fresh_symbols = fresh_binding(src);
213+
214+
// replace in where()
215+
replace_symbolt replace_symbol;
216+
217+
for(const auto &pair : make_range(src.variables()).zip(fresh_symbols))
218+
replace_symbol.insert(pair.first, pair.second);
219+
220+
exprt renamed_where = src.where();
221+
replace_symbol(renamed_where);
222+
223+
// produce new quantifier expression
224+
auto new_src =
225+
quantifier_exprt(src.id(), std::move(fresh_symbols), renamed_where);
226+
209227
const auto res = instantiate_quantifier(src, ns);
210228

211229
if(res)

0 commit comments

Comments
 (0)