Skip to content

Commit 492a8b8

Browse files
authored
Merge pull request #1521 from diffblue/smvlang-assign-set
SMV: turn nondeterministic choice into disjunction
2 parents b709df1 + 1df0bb7 commit 492a8b8

File tree

1 file changed

+46
-26
lines changed

1 file changed

+46
-26
lines changed

src/smvlang/smv_typecheck.cpp

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ class smv_typecheckt:public typecheckt
9595
void typecheck(smv_parse_treet::modulet::elementt &);
9696
void typecheck_expr_rec(exprt &, modet, bool next);
9797
void convert_expr_to(exprt &, const typet &dest);
98+
void typecheck_assignment(exprt &);
9899
exprt convert_word_constant(const constant_exprt &);
99100

100101
smv_parse_treet::modulet *modulep;
@@ -1697,26 +1698,6 @@ void smv_typecheckt::convert_expr_to(exprt &expr, const typet &dest_type)
16971698

16981699
if(src_type != dest_type)
16991700
{
1700-
if(src_type.id() == ID_smv_set && expr.id() == ID_smv_set)
1701-
{
1702-
// sets can be assigned to scalars, which yields a nondeterministic
1703-
// choice
1704-
std::string identifier =
1705-
module_identifier + "::var::" + std::to_string(nondet_count++);
1706-
1707-
expr.set(ID_identifier, identifier);
1708-
expr.set("#smv_nondet_choice", true);
1709-
1710-
expr.id(ID_constraint_select_one);
1711-
expr.type() = dest_type;
1712-
1713-
// apply recursively
1714-
for(auto &op : expr.operands())
1715-
convert_expr_to(op, dest_type);
1716-
1717-
return;
1718-
}
1719-
17201701
if(dest_type.id() == ID_signedbv || dest_type.id() == ID_unsignedbv)
17211702
{
17221703
// no implicit conversion
@@ -1837,6 +1818,48 @@ void smv_typecheckt::convert_expr_to(exprt &expr, const typet &dest_type)
18371818

18381819
/*******************************************************************\
18391820
1821+
Function: smv_typecheckt::typecheck_assignment
1822+
1823+
Inputs:
1824+
1825+
Outputs:
1826+
1827+
Purpose:
1828+
1829+
\*******************************************************************/
1830+
1831+
void smv_typecheckt::typecheck_assignment(exprt &expr)
1832+
{
1833+
PRECONDITION(expr.id() == ID_equal);
1834+
expr.type() = bool_typet{};
1835+
1836+
auto &equal_expr = to_equal_expr(expr);
1837+
auto &lhs = equal_expr.lhs();
1838+
auto &rhs = equal_expr.rhs();
1839+
1840+
if(rhs.type().id() == ID_smv_set && rhs.id() == ID_smv_set)
1841+
{
1842+
// Sets can be assigned to scalars, which yields a nondeterministic
1843+
// choice. First check the set elements.
1844+
for(auto &op : rhs.operands())
1845+
convert_expr_to(op, lhs.type());
1846+
1847+
// Now turn the nondeterministic choice into a top-level
1848+
// disjunctive constraint.
1849+
exprt::operandst disjuncts;
1850+
1851+
for(auto &op : rhs.operands())
1852+
disjuncts.push_back(equal_exprt{lhs, op});
1853+
1854+
expr = disjunction(disjuncts);
1855+
return;
1856+
}
1857+
1858+
convert_expr_to(rhs, lhs.type());
1859+
}
1860+
1861+
/*******************************************************************\
1862+
18401863
Function: smv_typecheckt::convert
18411864
18421865
Inputs:
@@ -2047,23 +2070,20 @@ void smv_typecheckt::typecheck(smv_parse_treet::modulet::elementt &element)
20472070
case smv_parse_treet::modulet::elementt::ASSIGN_CURRENT:
20482071
typecheck(element.lhs(), OTHER);
20492072
typecheck(element.rhs(), OTHER);
2050-
convert_expr_to(element.rhs(), element.lhs().type());
2051-
element.expr.type() = bool_typet{};
2073+
typecheck_assignment(element.expr);
20522074
return;
20532075

20542076
case smv_parse_treet::modulet::elementt::ASSIGN_INIT:
20552077
typecheck(element.lhs(), INIT);
20562078
typecheck(element.rhs(), INIT);
2057-
convert_expr_to(element.rhs(), element.lhs().type());
20582079
no_next_allowed(element.rhs());
2059-
element.expr.type() = bool_typet{};
2080+
typecheck_assignment(element.expr);
20602081
return;
20612082

20622083
case smv_parse_treet::modulet::elementt::ASSIGN_NEXT:
20632084
typecheck(element.lhs(), TRANS);
20642085
typecheck(element.rhs(), TRANS);
2065-
convert_expr_to(element.rhs(), element.lhs().type());
2066-
element.expr.type() = bool_typet{};
2086+
typecheck_assignment(element.expr);
20672087
return;
20682088

20692089
case smv_parse_treet::modulet::elementt::DEFINE:

0 commit comments

Comments
 (0)