1/*******************************************************************\
5Author: Daniel Kroening, kroening@kroening.com
7\*******************************************************************/
18#include <unordered_set>
37 // turn a => b into !a || b
51 for(exprt::operandst::const_iterator it =
new_operands.begin();
92 return std::move(
tmp);
97 std::unordered_set<exprt, irep_hash> expr_set;
107 for(exprt::operandst::const_iterator it =
new_operands.begin();
110 if(!it->is_boolean())
127 !expr_set.insert(*it).second;
142 // NOLINTNEXTLINE(whitespace/line_length)
143 // This block reduces singleton intervals like (value >= 255 && value <= 255)
144 // to just (value == 255). We also need to be careful with the operands
145 // as some of them are erased in the previous step. We proceed only if
146 // no operands have been erased (i.e. the expression structure has been
147 // preserved by previous simplification rounds.)
158 // Before we do anything else, we need to "pattern match" against the
159 // expression and make sure that it has the structure we're looking for.
160 // The structure we're looking for is going to be
161 // (value >= 255 && !(value >= 256)) -- 255, 256 values indicative.
162 // (this is because previous simplification runs will have transformed
163 // the less_than_or_equal expression to a not(greater_than_or_equal)
166 // matching (value >= 255)
172 // The construction of these expressions ensures that the RHS
173 // is constant, therefore if we don't have a constant, it's a
174 // different expression, so we bail.
175 if(!
ge_expr->rhs().is_constant())
190 // matching !(value >= 256)
200 // If the rhs() is not constant, it has a different structure
202 if(!
ge_expr->rhs().is_constant())
220 // We need to match both operands, at the particular sequence we expect.
226 // If we are here, we have matched the structure we expected, so we can
227 // make some reasonable assumptions about where certain info we need is
239 std::set<mp_integer> values;
243 if(
eq.lhs().is_constant())
244 std::swap(
eq.lhs(),
eq.rhs());
270 if(
symbol_opt.has_value() && values.size() >= 3)
274 if(upper - lower + 1 ==
mp_integer{values.size()})
295 // search for a and !a
298 op.id() ==
ID_not && op.is_boolean() &&
299 expr_set.find(
to_not_expr(op).op()) != expr_set.end())
317 return std::move(
tmp);
333 if(op.
id()==
ID_not)
// (not not a) == a
357 return std::move(
tmp);
363 return std::move(
tmp);
365 else if(op.
id()==
ID_exists)
// !(exists: a) <-> forall: not a
371 else if(op.
id() ==
ID_forall)
// !(forall: a) <-> exists: not a
391 // the following simplification only holds when the domain is non-empty
393 (where ==
false || where ==
true) &&
399 return v.type().id() == ID_integer || v.type().id() == ID_rational ||
400 v.type().id() == ID_real || v.type().id() == ID_bool ||
401 (can_cast_type<bitvector_typet>(v.type()) &&
402 to_bitvector_type(v.type()).get_width() > 0);
const c_enum_tag_typet & to_c_enum_tag_type(const typet &type)
Cast a typet to a c_enum_tag_typet.
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Boolean AND All operands must be boolean, and the result is always boolean.
A base class for binary expressions.
A constant literal expression.
Base class for all expressions.
std::vector< exprt > operandst
bool has_operands() const
Return true if there is at least one operand.
bool is_boolean() const
Return whether the expression represents a Boolean.
The Boolean constant false.
const irep_idt & id() const
Binary less than or equal operator expression.
A base class for quantifier expressions.
resultt simplify_quantifier_expr(const quantifier_exprt &)
Try to simplify exists/forall to a constant expression.
static resultt changed(resultt<> result)
resultt simplify_boolean(const exprt &)
resultt simplify_not(const not_exprt &)
static resultt unchanged(exprt expr)
Expression to hold a symbol (variable)
The Boolean constant true.
static exprt conditional_cast(const exprt &expr, const typet &type)
The type of an expression, extends irept.
#define Forall_operands(it, expr)
constant_exprt make_boolean_expr(bool value)
returns true_exprt if given true and false_exprt otherwise
Deprecated expression utility functions.
bool is_false(const literalt &l)
bool is_true(const literalt &l)
API to expression classes for 'mathematical' expressions.
const exists_exprt & to_exists_expr(const exprt &expr)
const forall_exprt & to_forall_expr(const exprt &expr)
#define PRECONDITION(CONDITION)
API to expression classes.
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
const not_exprt & to_not_expr(const exprt &expr)
Cast an exprt to an not_exprt.
const implies_exprt & to_implies_expr(const exprt &expr)
Cast an exprt to a implies_exprt.
const equal_exprt & to_equal_expr(const exprt &expr)
Cast an exprt to an equal_exprt.