@@ -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+
18401863Function: 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