@@ -1427,4 +1427,81 @@ inline overflow_result_exprt &to_overflow_result_expr(exprt &expr)
14271427 return ret;
14281428}
14291429
1430+ // / \brief Returns one plus the index of the least-significant one bit, or zero
1431+ // / if the operand is zero.
1432+ class find_first_set_exprt : public unary_exprt
1433+ {
1434+ public:
1435+ find_first_set_exprt (exprt _op, typet _type)
1436+ : unary_exprt(ID_find_first_set, std::move(_op), std::move(_type))
1437+ {
1438+ }
1439+
1440+ explicit find_first_set_exprt (const exprt &_op)
1441+ : find_first_set_exprt(_op, _op.type())
1442+ {
1443+ }
1444+
1445+ static void check (
1446+ const exprt &expr,
1447+ const validation_modet vm = validation_modet::INVARIANT)
1448+ {
1449+ DATA_CHECK (
1450+ vm,
1451+ expr.operands ().size () == 1 ,
1452+ " unary expression must have a single operand" );
1453+ DATA_CHECK (
1454+ vm,
1455+ can_cast_type<bitvector_typet>(to_unary_expr (expr).op ().type ()),
1456+ " operand must be of bitvector type" );
1457+ }
1458+
1459+ static void validate (
1460+ const exprt &expr,
1461+ const namespacet &,
1462+ const validation_modet vm = validation_modet::INVARIANT)
1463+ {
1464+ check (expr, vm);
1465+ }
1466+
1467+ // / Lower a find_first_set_exprt to arithmetic and logic expressions.
1468+ // / \return Semantically equivalent expression
1469+ exprt lower () const ;
1470+ };
1471+
1472+ template <>
1473+ inline bool can_cast_expr<find_first_set_exprt>(const exprt &base)
1474+ {
1475+ return base.id () == ID_find_first_set;
1476+ }
1477+
1478+ inline void validate_expr (const find_first_set_exprt &value)
1479+ {
1480+ validate_operands (value, 1 , " find_first_set must have one operand" );
1481+ }
1482+
1483+ // / \brief Cast an exprt to a \ref find_first_set_exprt
1484+ // /
1485+ // / \a expr must be known to be \ref find_first_set_exprt.
1486+ // /
1487+ // / \param expr: Source expression
1488+ // / \return Object of type \ref find_first_set_exprt
1489+ inline const find_first_set_exprt &to_find_first_set_expr (const exprt &expr)
1490+ {
1491+ PRECONDITION (expr.id () == ID_find_first_set);
1492+ const find_first_set_exprt &ret =
1493+ static_cast <const find_first_set_exprt &>(expr);
1494+ validate_expr (ret);
1495+ return ret;
1496+ }
1497+
1498+ // / \copydoc to_find_first_set_expr(const exprt &)
1499+ inline find_first_set_exprt &to_find_first_set_expr (exprt &expr)
1500+ {
1501+ PRECONDITION (expr.id () == ID_find_first_set);
1502+ find_first_set_exprt &ret = static_cast <find_first_set_exprt &>(expr);
1503+ validate_expr (ret);
1504+ return ret;
1505+ }
1506+
14301507#endif // CPROVER_UTIL_BITVECTOR_EXPR_H
0 commit comments