Skip to content

Commit 60853b9

Browse files
authored
Merge pull request #6922 from diffblue/named_term
introduce named_term expressions
2 parents 74c7764 + d6ddea3 commit 60853b9

File tree

5 files changed

+96
-0
lines changed

5 files changed

+96
-0
lines changed

src/solvers/flattening/boolbv.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ bvt boolbvt::convert_bitvector(const exprt &expr)
185185
else if(expr.id()==ID_string_constant)
186186
return convert_bitvector(
187187
to_string_constant(expr).to_array_expr());
188+
else if(expr.id() == ID_named_term)
189+
{
190+
const auto &named_term_expr = to_named_term_expr(expr);
191+
set_to_true(equal_exprt(named_term_expr.symbol(), named_term_expr.value()));
192+
return convert_symbol(named_term_expr.symbol());
193+
}
188194
else if(expr.id()==ID_array)
189195
return convert_array(expr);
190196
else if(expr.id()==ID_vector)

src/solvers/prop/prop_conv_solver.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,14 @@ literalt prop_conv_solvert::convert_bool(const exprt &expr)
300300
return equal ? prop.lequal(tmp1, tmp2) : prop.lxor(tmp1, tmp2);
301301
}
302302
}
303+
else if(expr.id() == ID_named_term)
304+
{
305+
const auto &named_term_expr = to_named_term_expr(expr);
306+
literalt value_converted = convert(named_term_expr.value());
307+
set_to_true(
308+
equal_exprt(named_term_expr.symbol(), literal_exprt(value_converted)));
309+
return value_converted;
310+
}
303311

304312
return convert_rest(expr);
305313
}

src/solvers/smt2/smt2_conv.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,6 +1607,14 @@ void smt2_convt::convert_expr(const exprt &expr)
16071607
"unsupported type for " + shift_expr.id_string() + ": " +
16081608
type.id_string());
16091609
}
1610+
else if(expr.id() == ID_named_term)
1611+
{
1612+
const auto &named_term_expr = to_named_term_expr(expr);
1613+
out << "(! ";
1614+
convert(named_term_expr.value());
1615+
out << " :named "
1616+
<< convert_identifier(named_term_expr.symbol().get_identifier()) << ')';
1617+
}
16101618
else if(expr.id()==ID_with)
16111619
{
16121620
convert_with(to_with_expr(expr));

src/util/irep_ids.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ IREP_ID_ONE(ieee_float_equal)
227227
IREP_ID_ONE(ieee_float_notequal)
228228
IREP_ID_ONE(isnan)
229229
IREP_ID_ONE(lambda)
230+
IREP_ID_ONE(named_term)
230231
IREP_ID_ONE(array_comprehension)
231232
IREP_ID_ONE(array_of)
232233
IREP_ID_ONE(array_equal)

src/util/std_expr.h

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3543,4 +3543,77 @@ inline bool can_cast_expr<class_method_descriptor_exprt>(const exprt &base)
35433543
return base.id() == ID_virtual_function;
35443544
}
35453545

3546+
/// \brief Expression that introduces a new symbol that is equal to the operand.
3547+
/// This expression corresponds to the SMT-LIB2 feature 'named term'.
3548+
/// The symbol is not bound, i.e., visible outside of this expression.
3549+
/// The expression roughly corresponds to Python's "walrus operator", but
3550+
/// is not a side effect.
3551+
class named_term_exprt : public binary_exprt
3552+
{
3553+
public:
3554+
explicit named_term_exprt(symbol_exprt symbol, exprt value)
3555+
: binary_exprt(
3556+
std::move(symbol),
3557+
ID_named_term,
3558+
value, // not moved, for type
3559+
value.type())
3560+
{
3561+
PRECONDITION(symbol.type() == type());
3562+
}
3563+
3564+
const symbol_exprt &symbol() const
3565+
{
3566+
return static_cast<const symbol_exprt &>(op0());
3567+
}
3568+
3569+
symbol_exprt &symbol()
3570+
{
3571+
return static_cast<symbol_exprt &>(op0());
3572+
}
3573+
3574+
const exprt &value() const
3575+
{
3576+
return op1();
3577+
}
3578+
3579+
exprt &value()
3580+
{
3581+
return op1();
3582+
}
3583+
};
3584+
3585+
template <>
3586+
inline bool can_cast_expr<named_term_exprt>(const exprt &base)
3587+
{
3588+
return base.id() == ID_named_term;
3589+
}
3590+
3591+
inline void validate_expr(const named_term_exprt &value)
3592+
{
3593+
validate_operands(value, 2, "'named term' must have two operands");
3594+
}
3595+
3596+
/// \brief Cast an exprt to a \ref named_term_exprt
3597+
///
3598+
/// \a expr must be known to be \ref named_term_exprt.
3599+
///
3600+
/// \param expr: Source expression
3601+
/// \return Object of type \ref named_term_exprt
3602+
inline const named_term_exprt &to_named_term_expr(const exprt &expr)
3603+
{
3604+
PRECONDITION(expr.id() == ID_named_term);
3605+
const named_term_exprt &ret = static_cast<const named_term_exprt &>(expr);
3606+
validate_expr(ret);
3607+
return ret;
3608+
}
3609+
3610+
/// \copydoc to_array_comprehension_expr(const exprt &)
3611+
inline named_term_exprt &to_named_term_expr(exprt &expr)
3612+
{
3613+
PRECONDITION(expr.id() == ID_named_term);
3614+
named_term_exprt &ret = static_cast<named_term_exprt &>(expr);
3615+
validate_expr(ret);
3616+
return ret;
3617+
}
3618+
35463619
#endif // CPROVER_UTIL_STD_EXPR_H

0 commit comments

Comments
 (0)