Skip to content

Commit 2a5cea2

Browse files
author
Daniel Kroening
committed
This introduces nondet_symbol_exprt, which is generated by symbolic execution in response to side_effect_expr_nondett
1 parent 61b0d6d commit 2a5cea2

File tree

6 files changed

+83
-17
lines changed

6 files changed

+83
-17
lines changed

src/ansi-c/expr2c.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -1644,11 +1644,11 @@ std::string expr2ct::convert_symbol(
16441644
}
16451645

16461646
std::string expr2ct::convert_nondet_symbol(
1647-
const exprt &src,
1647+
const nondet_symbol_exprt &src,
16481648
unsigned &precedence)
16491649
{
1650-
const std::string &id=src.get_string(ID_identifier);
1651-
return "nondet_symbol("+id+")";
1650+
const irep_idt id=src.get_identifier();
1651+
return "nondet_symbol("+id2string(id)+")";
16521652
}
16531653

16541654
std::string expr2ct::convert_predicate_symbol(
@@ -3790,7 +3790,7 @@ std::string expr2ct::convert_with_precedence(
37903790
return convert_symbol(src, precedence);
37913791

37923792
else if(src.id()==ID_nondet_symbol)
3793-
return convert_nondet_symbol(src, precedence);
3793+
return convert_nondet_symbol(to_nondet_symbol_expr(src), precedence);
37943794

37953795
else if(src.id()==ID_predicate_symbol)
37963796
return convert_predicate_symbol(src, precedence);

src/ansi-c/expr2c_class.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,8 @@ class expr2ct
227227
std::string convert_predicate_next_symbol(const exprt &src, unsigned &precedence);
228228
// NOLINTNEXTLINE(whitespace/line_length)
229229
std::string convert_predicate_passive_symbol(const exprt &src, unsigned &precedence);
230-
std::string convert_nondet_symbol(const exprt &src, unsigned &precedence);
230+
// NOLINTNEXTLINE(whitespace/line_length)
231+
std::string convert_nondet_symbol(const nondet_symbol_exprt &, unsigned &precedence);
231232
std::string convert_quantified_symbol(const exprt &src, unsigned &precedence);
232233
std::string convert_nondet_bool(const exprt &src, unsigned &precedence);
233234
std::string convert_object_descriptor(const exprt &src, unsigned &precedence);

src/goto-symex/goto_symex.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ void goto_symext::replace_nondet(exprt &expr)
2727
if(expr.id()==ID_side_effect &&
2828
expr.get(ID_statement)==ID_nondet)
2929
{
30-
exprt new_expr(ID_nondet_symbol, expr.type());
31-
new_expr.set(ID_identifier, "symex::nondet"+std::to_string(nondet_count++));
30+
irep_idt identifier="symex::nondet"+std::to_string(nondet_count++);
31+
nondet_symbol_exprt new_expr(identifier, expr.type());
3232
new_expr.add_source_location()=expr.source_location();
3333
expr.swap(new_expr);
3434
}

src/solvers/smt1/smt1_conv.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ void smt1_convt::convert_expr(const exprt &expr, bool bool_as_bv)
540540
const typet &type=expr.type();
541541

542542
irep_idt id=to_symbol_expr(expr).get_identifier();
543-
assert(id!="");
543+
DATA_INVARIANT(!id.empty(), "symbol must have identifier");
544544

545545
// boolean symbols may have to be converted
546546
from_bool_begin(type, bool_as_bv);
@@ -553,8 +553,8 @@ void smt1_convt::convert_expr(const exprt &expr, bool bool_as_bv)
553553
{
554554
const typet &type=expr.type();
555555

556-
irep_idt id=expr.get(ID_identifier);
557-
assert(id!="");
556+
irep_idt id=to_nondet_symbol_expr(expr).get_identifier();
557+
DATA_INVARIANT(!id.empty(), "symbol must have identifier");
558558

559559
// boolean symbols may have to be converted
560560
from_bool_begin(type, bool_as_bv);
@@ -2822,7 +2822,8 @@ void smt1_convt::find_symbols(const exprt &expr)
28222822
if(expr.id()==ID_symbol)
28232823
identifier=to_symbol_expr(expr).get_identifier();
28242824
else
2825-
identifier="nondet_"+expr.get_string(ID_identifier);
2825+
identifier="nondet_"+
2826+
id2string(to_nondet_symbol_expr(expr).get_identifier());
28262827

28272828
if(quantified_symbols.find(identifier)!=quantified_symbols.end())
28282829
return; // Symbol is quantified, i.e., it doesn't require declaration.

src/solvers/smt2/smt2_conv.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -853,20 +853,19 @@ void smt2_convt::convert_expr(const exprt &expr)
853853
if(expr.id()==ID_symbol)
854854
{
855855
irep_idt id=to_symbol_expr(expr).get_identifier();
856-
assert(id!=irep_idt());
857-
856+
DATA_INVARIANT(!id.empty(), "symbol must have identifier");
858857
out << '|' << convert_identifier(id) << '|';
859858
}
860859
else if(expr.id()==ID_nondet_symbol)
861860
{
862-
irep_idt id=expr.get(ID_identifier);
863-
assert(id!="");
861+
irep_idt id=to_nondet_symbol_expr(expr).get_identifier();
862+
DATA_INVARIANT(!id.empty(), "symbol must have identifier");
864863
out << '|' << convert_identifier("nondet_"+id2string(id)) << '|';
865864
}
866865
else if(expr.id()==ID_smt2_symbol)
867866
{
868867
irep_idt id=expr.get(ID_identifier);
869-
assert(id!=irep_idt());
868+
DATA_INVARIANT(!id.empty(), "smt2_symbol must have identifier");
870869
out << id;
871870
}
872871
else if(expr.id()==ID_typecast)
@@ -4071,7 +4070,8 @@ void smt2_convt::find_symbols(const exprt &expr)
40714070
if(expr.id()==ID_symbol)
40724071
identifier=to_symbol_expr(expr).get_identifier();
40734072
else
4074-
identifier="nondet_"+id2string(expr.get(ID_identifier));
4073+
identifier="nondet_"+
4074+
id2string(to_nondet_symbol_expr(expr).get_identifier());
40754075

40764076
identifiert &id=identifier_map[identifier];
40774077

src/util/std_expr.h

+64
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,70 @@ inline void validate_expr(const symbol_exprt &value)
238238
}
239239

240240

241+
/*! \brief Expression to hold a nondeterministic choice
242+
*/
243+
class nondet_symbol_exprt:public exprt
244+
{
245+
public:
246+
/*! \brief Constructor
247+
* \param identifier Name of symbol
248+
* \param type Type of symbol
249+
*/
250+
nondet_symbol_exprt(
251+
const irep_idt &identifier,
252+
const typet &type):exprt(ID_nondet_symbol, type)
253+
{
254+
set_identifier(identifier);
255+
}
256+
257+
void set_identifier(const irep_idt &identifier)
258+
{
259+
set(ID_identifier, identifier);
260+
}
261+
262+
const irep_idt &get_identifier() const
263+
{
264+
return get(ID_identifier);
265+
}
266+
};
267+
268+
/*! \brief Cast a generic exprt to a \ref nondet_symbol_exprt
269+
*
270+
* This is an unchecked conversion. \a expr must be known to be \ref
271+
* nondet_symbol_exprt.
272+
*
273+
* \param expr Source expression
274+
* \return Object of type \ref nondet_symbol_exprt
275+
*
276+
* \ingroup gr_std_expr
277+
*/
278+
inline const nondet_symbol_exprt &to_nondet_symbol_expr(const exprt &expr)
279+
{
280+
PRECONDITION(expr.id()==ID_nondet_symbol);
281+
DATA_INVARIANT(!expr.has_operands(), "Symbols must not have operands");
282+
return static_cast<const nondet_symbol_exprt &>(expr);
283+
}
284+
285+
/*! \copydoc to_nondet_symbol_expr(const exprt &)
286+
* \ingroup gr_std_expr
287+
*/
288+
inline nondet_symbol_exprt &to_nondet_symbol_expr(exprt &expr)
289+
{
290+
PRECONDITION(expr.id()==ID_symbol);
291+
DATA_INVARIANT(!expr.has_operands(), "Symbols must not have operands");
292+
return static_cast<nondet_symbol_exprt &>(expr);
293+
}
294+
295+
template<> inline bool can_cast_expr<nondet_symbol_exprt>(const exprt &base)
296+
{
297+
return base.id()==ID_nondet_symbol;
298+
}
299+
inline void validate_expr(const nondet_symbol_exprt &value)
300+
{
301+
validate_operands(value, 0, "Symbols must not have operands");
302+
}
303+
304+
241305
/*! \brief Generic base class for unary expressions
242306
*/
243307
class unary_exprt:public exprt

0 commit comments

Comments
 (0)