Skip to content

Commit f5aa4d8

Browse files
committed
Perform simplification of not_exprt as preorder step
Each of the possible simplifications has an impact on its operands, which in turn mostly needs to be simplified. Instead of doing this again (as the operand has already been simplified), do most of the work as a preorder step so that only the modified operand is subject to simplification.
1 parent b836b4f commit f5aa4d8

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

src/util/simplify_expr.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2795,6 +2795,10 @@ simplify_exprt::simplify_node_preorder(const exprt &expr)
27952795
{
27962796
result = simplify_unary_pointer_predicate_preorder(to_unary_expr(expr));
27972797
}
2798+
else if(expr.id() == ID_not)
2799+
{
2800+
result = simplify_not_preorder(to_not_expr(expr));
2801+
}
27982802
else if(expr.has_operands())
27992803
{
28002804
optionalt<exprt::operandst> new_operands;

src/util/simplify_expr_boolean.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,3 +377,66 @@ simplify_exprt::resultt<> simplify_exprt::simplify_not(const not_exprt &expr)
377377

378378
return unchanged(expr);
379379
}
380+
381+
simplify_exprt::resultt<>
382+
simplify_exprt::simplify_not_preorder(const not_exprt &expr)
383+
{
384+
const exprt &op = expr.op();
385+
386+
if(!expr.is_boolean() || !op.is_boolean())
387+
{
388+
return unchanged(expr);
389+
}
390+
391+
if(op.id() == ID_not) // (not not a) == a
392+
{
393+
return changed(simplify_rec(to_not_expr(op).op()));
394+
}
395+
else if(op.is_false())
396+
{
397+
return true_exprt{};
398+
}
399+
else if(op.is_true())
400+
{
401+
return false_exprt{};
402+
}
403+
else if(op.id() == ID_and || op.id() == ID_or)
404+
{
405+
exprt tmp = op;
406+
407+
Forall_operands(it, tmp)
408+
{
409+
*it = boolean_negate(*it);
410+
}
411+
412+
tmp.id(tmp.id() == ID_and ? ID_or : ID_and);
413+
414+
return changed(simplify_rec(tmp));
415+
}
416+
else if(op.id() == ID_notequal) // !(a!=b) <-> a==b
417+
{
418+
exprt tmp = op;
419+
tmp.id(ID_equal);
420+
return changed(simplify_rec(tmp));
421+
}
422+
else if(op.id() == ID_exists) // !(exists: a) <-> forall: not a
423+
{
424+
auto const &op_as_exists = to_exists_expr(op);
425+
return changed(simplify_rec(
426+
forall_exprt{op_as_exists.symbol(), not_exprt{op_as_exists.where()}}));
427+
}
428+
else if(op.id() == ID_forall) // !(forall: a) <-> exists: not a
429+
{
430+
auto const &op_as_forall = to_forall_expr(op);
431+
return changed(simplify_rec(
432+
exists_exprt{op_as_forall.symbol(), not_exprt{op_as_forall.where()}}));
433+
}
434+
435+
auto op_result = simplify_rec(op);
436+
if(!op_result.has_changed())
437+
return op_result;
438+
439+
not_exprt tmp = expr;
440+
tmp.op() = std::move(op_result.expr);
441+
return std::move(tmp);
442+
}

src/util/simplify_expr_class.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ class simplify_exprt
167167
NODISCARD resultt<> simplify_if(const if_exprt &);
168168
NODISCARD resultt<> simplify_bitnot(const bitnot_exprt &);
169169
NODISCARD resultt<> simplify_not(const not_exprt &);
170+
NODISCARD resultt<> simplify_not_preorder(const not_exprt &expr);
170171
NODISCARD resultt<> simplify_boolean(const exprt &);
171172
NODISCARD resultt<> simplify_inequality(const binary_relation_exprt &);
172173
NODISCARD resultt<>

0 commit comments

Comments
 (0)