Skip to content

Commit ca88d02

Browse files
committed
SMV: union operator
The SMV union operator computes the union of two set expressions.
1 parent a152b63 commit ca88d02

File tree

4 files changed

+74
-21
lines changed

4 files changed

+74
-21
lines changed
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
KNOWNBUG broken-smt-backend
1+
CORE broken-smt-backend
22
smv_union2.smv
33

4-
^\[spec1\] x != 3: PROVED \(CT=1\)$
4+
^\[spec1\] x != 3: PROVED \(CT=0\)$
55
^\[spec2\] x != 2: REFUTED$
66
^EXIT=10$
77
^SIGNAL=0$
88
--
99
^warning: ignoring
1010
--
11-
The type checker rejects this.

regression/smv/range-type/range_type3.smv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ INIT x=0
66

77
DEFINE n:=0 union 1;
88

9+
-- assignment RHS is a set
910
ASSIGN next(x):=n;
1011

1112
SPEC AG x=0

src/smvlang/smv_typecheck.cpp

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,37 @@ void smv_typecheckt::typecheck_expr_rec(exprt &expr, modet mode)
950950
// only get added by type checker
951951
PRECONDITION(false);
952952
}
953+
else if(expr.id() == ID_smv_union)
954+
{
955+
auto &lhs = to_binary_expr(expr).lhs();
956+
auto &rhs = to_binary_expr(expr).rhs();
957+
958+
typecheck_expr_rec(lhs, mode);
959+
typecheck_expr_rec(rhs, mode);
960+
961+
// create smv_set expression
962+
exprt::operandst elements;
963+
964+
if(lhs.id() == ID_smv_set)
965+
{
966+
elements.insert(
967+
elements.end(), lhs.operands().begin(), lhs.operands().end());
968+
}
969+
else
970+
elements.push_back(lhs);
971+
972+
if(rhs.id() == ID_smv_set)
973+
{
974+
elements.insert(
975+
elements.end(), rhs.operands().begin(), rhs.operands().end());
976+
}
977+
else
978+
elements.push_back(rhs);
979+
980+
expr.id(ID_smv_set);
981+
expr.operands() = std::move(elements);
982+
expr.type() = smv_set_typet{smv_enumeration_typet{}};
983+
}
953984
else if(expr.id() == ID_smv_setin)
954985
{
955986
auto &lhs = to_binary_expr(expr).lhs();
@@ -1319,7 +1350,7 @@ void smv_typecheckt::typecheck_expr_rec(exprt &expr, modet mode)
13191350
else if(expr.id() == ID_smv_set)
13201351
{
13211352
// a set literal
1322-
expr.type() = typet{ID_smv_set};
1353+
expr.type() = smv_set_typet{smv_enumeration_typet{}};
13231354

13241355
for(auto &op : expr.operands())
13251356
typecheck_expr_rec(op, mode);
@@ -1719,23 +1750,6 @@ void smv_typecheckt::convert(exprt &expr, expr_modet expr_mode)
17191750
expr.id(ID_next_symbol);
17201751
}
17211752
}
1722-
else if(expr.id()=="smv_nondet_choice" ||
1723-
expr.id()=="smv_union")
1724-
{
1725-
if(expr.operands().size()==0)
1726-
{
1727-
throw errort().with_location(expr.find_source_location())
1728-
<< "expected operand here";
1729-
}
1730-
1731-
std::string identifier=
1732-
module+"::var::"+std::to_string(nondet_count++);
1733-
1734-
expr.set(ID_identifier, identifier);
1735-
expr.set("#smv_nondet_choice", true);
1736-
1737-
expr.id(ID_constraint_select_one);
1738-
}
17391753
else if(expr.id()=="smv_cases") // cases
17401754
{
17411755
if(expr.operands().size()<1)

src/smvlang/smv_types.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,43 @@ inline smv_enumeration_typet &to_smv_enumeration_type(typet &type)
7171
return static_cast<smv_enumeration_typet &>(type);
7272
}
7373

74+
/// The SMV set type -- NuSMV distinguishes the boolean set, the integer set,
75+
/// the symbolic set, and the integers-and-symbolic set.
76+
class smv_set_typet : public type_with_subtypet
77+
{
78+
public:
79+
explicit smv_set_typet(typet subtype)
80+
: type_with_subtypet(ID_smv_set, std::move(subtype))
81+
{
82+
}
83+
};
84+
85+
/// compute the union of the given set types
86+
smv_set_typet type_union(const smv_set_typet &, const smv_set_typet &);
87+
88+
/*! \brief Cast a generic typet to a \ref smv_set_typet
89+
*
90+
* This is an unchecked conversion. \a type must be known to be \ref
91+
* smv_set_typet.
92+
*
93+
* \param type Source type
94+
* \return Object of type \ref smv_set_typet
95+
*
96+
* \ingroup gr_std_types
97+
*/
98+
inline const smv_set_typet &to_smv_set_type(const typet &type)
99+
{
100+
PRECONDITION(type.id() == ID_smv_set);
101+
return static_cast<const smv_set_typet &>(type);
102+
}
103+
104+
/*! \copydoc to_smv_set_type(const typet &)
105+
* \ingroup gr_std_types
106+
*/
107+
inline smv_set_typet &to_smv_set_type(typet &type)
108+
{
109+
PRECONDITION(type.id() == ID_smv_set);
110+
return static_cast<smv_set_typet &>(type);
111+
}
112+
74113
#endif // CPROVER_SMV_TYPES_H

0 commit comments

Comments
 (0)