Skip to content

Commit ded98de

Browse files
authored
Merge pull request #6585 from diffblue/quantifier-multi-binding
Quantifiers with multiple bindings
2 parents ed7a0d3 + b165bf9 commit ded98de

File tree

4 files changed

+51
-19
lines changed

4 files changed

+51
-19
lines changed

src/solvers/smt2/smt2_conv.cpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1972,13 +1972,16 @@ void smt2_convt::convert_expr(const exprt &expr)
19721972
else if(quantifier_expr.id() == ID_exists)
19731973
out << "(exists ";
19741974

1975-
exprt bound = quantifier_expr.symbol();
1976-
1977-
out << "((";
1978-
convert_expr(bound);
1979-
out << " ";
1980-
convert_type(bound.type());
1981-
out << ")) ";
1975+
out << "( ";
1976+
for(const auto &bound : quantifier_expr.variables())
1977+
{
1978+
out << "(";
1979+
convert_expr(bound);
1980+
out << " ";
1981+
convert_type(bound.type());
1982+
out << ") ";
1983+
}
1984+
out << ") ";
19821985

19831986
convert_expr(quantifier_expr.where());
19841987

@@ -4566,10 +4569,13 @@ void smt2_convt::find_symbols(const exprt &expr)
45664569
// do not declare the quantified symbol, but record
45674570
// as 'bound symbol'
45684571
const auto &q_expr = to_quantifier_expr(expr);
4569-
const auto identifier = q_expr.symbol().get_identifier();
4570-
identifiert &id = identifier_map[identifier];
4571-
id.type = q_expr.symbol().type();
4572-
id.is_bound = true;
4572+
for(const auto &symbol : q_expr.variables())
4573+
{
4574+
const auto identifier = symbol.get_identifier();
4575+
identifiert &id = identifier_map[identifier];
4576+
id.type = symbol.type();
4577+
id.is_bound = true;
4578+
}
45734579
find_symbols(q_expr.where());
45744580
return;
45754581
}

src/util/format_expr.cpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -356,16 +356,32 @@ void format_expr_configt::setup()
356356

357357
expr_map[ID_forall] =
358358
[](std::ostream &os, const exprt &expr) -> std::ostream & {
359-
return os << u8"\u2200 " << format(to_quantifier_expr(expr).symbol())
360-
<< " : " << format(to_quantifier_expr(expr).symbol().type())
361-
<< " . " << format(to_quantifier_expr(expr).where());
359+
os << u8"\u2200 ";
360+
bool first = true;
361+
for(const auto &symbol : to_quantifier_expr(expr).variables())
362+
{
363+
if(first)
364+
first = false;
365+
else
366+
os << ", ";
367+
os << format(symbol) << " : " << format(symbol.type());
368+
}
369+
return os << " . " << format(to_quantifier_expr(expr).where());
362370
};
363371

364372
expr_map[ID_exists] =
365373
[](std::ostream &os, const exprt &expr) -> std::ostream & {
366-
return os << u8"\u2203 " << format(to_quantifier_expr(expr).symbol())
367-
<< " : " << format(to_quantifier_expr(expr).symbol().type())
368-
<< " . " << format(to_quantifier_expr(expr).where());
374+
os << u8"\u2203 ";
375+
bool first = true;
376+
for(const auto &symbol : to_quantifier_expr(expr).variables())
377+
{
378+
if(first)
379+
first = false;
380+
else
381+
os << ", ";
382+
os << format(symbol) << " : " << format(symbol.type());
383+
}
384+
return os << " . " << format(to_quantifier_expr(expr).where());
369385
};
370386

371387
expr_map[ID_let] = [](std::ostream &os, const exprt &expr) -> std::ostream & {

src/util/mathematical_expr.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,11 @@ class forall_exprt : public quantifier_exprt
336336
: quantifier_exprt(ID_forall, _symbol, _where)
337337
{
338338
}
339+
340+
forall_exprt(const binding_exprt::variablest &_variables, const exprt &_where)
341+
: quantifier_exprt(ID_forall, _variables, _where)
342+
{
343+
}
339344
};
340345

341346
template <>
@@ -373,6 +378,11 @@ class exists_exprt : public quantifier_exprt
373378
: quantifier_exprt(ID_exists, _symbol, _where)
374379
{
375380
}
381+
382+
exists_exprt(const binding_exprt::variablest &_variables, const exprt &_where)
383+
: quantifier_exprt(ID_exists, _variables, _where)
384+
{
385+
}
376386
};
377387

378388
template <>

src/util/simplify_expr_boolean.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,13 +204,13 @@ simplify_exprt::resultt<> simplify_exprt::simplify_not(const not_exprt &expr)
204204
else if(op.id()==ID_exists) // !(exists: a) <-> forall: not a
205205
{
206206
auto const &op_as_exists = to_exists_expr(op);
207-
return forall_exprt{op_as_exists.symbol(),
207+
return forall_exprt{op_as_exists.variables(),
208208
simplify_not(not_exprt(op_as_exists.where()))};
209209
}
210210
else if(op.id() == ID_forall) // !(forall: a) <-> exists: not a
211211
{
212212
auto const &op_as_forall = to_forall_expr(op);
213-
return exists_exprt{op_as_forall.symbol(),
213+
return exists_exprt{op_as_forall.variables(),
214214
simplify_not(not_exprt(op_as_forall.where()))};
215215
}
216216

0 commit comments

Comments
 (0)