Skip to content

Commit 662afe0

Browse files
authored
Merge pull request #765 from diffblue/property_nnf
extract NNF from `normalize_property_rec`
2 parents d559b64 + d1237ca commit 662afe0

File tree

3 files changed

+42
-61
lines changed

3 files changed

+42
-61
lines changed

src/temporal-logic/nnf.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,35 @@ std::optional<exprt> negate_property_node(const exprt &expr)
139139
else
140140
return {};
141141
}
142+
143+
exprt property_nnf(exprt expr)
144+
{
145+
// Do the node
146+
if(expr.id() == ID_not)
147+
{
148+
auto node_opt = negate_property_node(to_not_expr(expr).op());
149+
if(!node_opt.has_value())
150+
return expr; // give up
151+
152+
expr = node_opt.value();
153+
}
154+
else if(expr.id() == ID_implies)
155+
{
156+
auto &implies = to_implies_expr(expr);
157+
expr = or_exprt{not_exprt{implies.lhs()}, implies.rhs()};
158+
}
159+
else if(
160+
expr.id() == ID_equal && to_equal_expr(expr).lhs().type().id() == ID_bool)
161+
{
162+
auto &equal = to_equal_expr(expr);
163+
expr = and_exprt{
164+
implies_exprt{equal.lhs(), equal.rhs()},
165+
implies_exprt{equal.rhs(), equal.lhs()}};
166+
}
167+
168+
// Do the operands, recursively
169+
for(auto &op : expr.operands())
170+
op = property_nnf(op);
171+
172+
return expr;
173+
}

src/temporal-logic/nnf.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@ Author: Daniel Kroening, [email protected]
1515
/// Returns {} if no negation is known.
1616
std::optional<exprt> negate_property_node(const exprt &);
1717

18+
/// Turn a full property into NNF
19+
exprt property_nnf(exprt);
20+
1821
#endif

src/temporal-logic/normalize_property.cpp

Lines changed: 7 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -14,66 +14,11 @@ Author: Daniel Kroening, [email protected]
1414

1515
#include <verilog/sva_expr.h>
1616

17+
#include "nnf.h"
1718
#include "temporal_expr.h"
1819
#include "temporal_logic.h"
1920
#include "trivial_sva.h"
2021

21-
exprt normalize_pre_not(not_exprt expr)
22-
{
23-
const auto &op = expr.op();
24-
25-
if(op.id() == ID_and)
26-
{
27-
auto operands = op.operands();
28-
for(auto &op : operands)
29-
op = not_exprt{op};
30-
return or_exprt{std::move(operands)};
31-
}
32-
else if(op.id() == ID_or)
33-
{
34-
auto operands = op.operands();
35-
for(auto &op : operands)
36-
op = not_exprt{op};
37-
return and_exprt{std::move(operands)};
38-
}
39-
else if(op.id() == ID_not)
40-
{
41-
return to_not_expr(op).op();
42-
}
43-
else if(op.id() == ID_G)
44-
{
45-
// ¬Gφ --> F¬φ
46-
return F_exprt{not_exprt{to_G_expr(op).op()}};
47-
}
48-
else if(op.id() == ID_F)
49-
{
50-
// ¬Fφ --> G¬φ
51-
return G_exprt{not_exprt{to_F_expr(op).op()}};
52-
}
53-
else if(op.id() == ID_X)
54-
{
55-
// ¬Xφ --> X¬φ
56-
return X_exprt{not_exprt{to_X_expr(op).op()}};
57-
}
58-
else if(op.id() == ID_sva_always)
59-
{
60-
// ¬ sva_always φ --> sva_s_eventually ¬φ
61-
return sva_s_eventually_exprt{not_exprt{to_sva_always_expr(op).op()}};
62-
}
63-
else if(op.id() == ID_sva_s_eventually)
64-
{
65-
// ¬ sva_s_eventually φ --> sva_always ¬φ
66-
return sva_always_exprt{not_exprt{to_sva_s_eventually_expr(op).op()}};
67-
}
68-
69-
return std::move(expr);
70-
}
71-
72-
exprt normalize_pre_implies(implies_exprt expr)
73-
{
74-
return or_exprt{not_exprt{expr.lhs()}, expr.rhs()};
75-
}
76-
7722
exprt normalize_pre_sva_non_overlapped_implication(
7823
sva_non_overlapped_implication_exprt expr)
7924
{
@@ -113,13 +58,11 @@ exprt normalize_pre_sva_cycle_delay(sva_cycle_delay_exprt expr)
11358
exprt normalize_property_rec(exprt expr)
11459
{
11560
// pre-traversal
116-
if(expr.id() == ID_not)
117-
expr = normalize_pre_not(to_not_expr(expr));
118-
else if(expr.id() == ID_implies)
119-
expr = normalize_pre_implies(to_implies_expr(expr));
120-
else if(expr.id() == ID_sva_non_overlapped_implication)
61+
if(expr.id() == ID_sva_non_overlapped_implication)
62+
{
12163
expr = normalize_pre_sva_non_overlapped_implication(
12264
to_sva_non_overlapped_implication_expr(expr));
65+
}
12366
else if(expr.id() == ID_sva_nexttime)
12467
{
12568
auto one = natural_typet{}.one_expr();
@@ -184,5 +127,8 @@ exprt normalize_property(exprt expr)
184127
// now do recursion
185128
expr = normalize_property_rec(expr);
186129

130+
// NNF
131+
expr = property_nnf(expr);
132+
187133
return expr;
188134
}

0 commit comments

Comments
 (0)