Skip to content

Commit aadac0c

Browse files
committed
SMV netlist: translate some SVA to LTL
Parts of SVA map directly to LTL. This allows extending the set of formulas converted to LTL when outputting an SMV model.
1 parent ed453c4 commit aadac0c

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

src/temporal-logic/temporal_logic.cpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ Author: Daniel Kroening, [email protected]
1010

1111
#include <util/expr_util.h>
1212

13+
#include <verilog/sva_expr.h>
14+
15+
#include "ltl.h"
16+
1317
bool is_temporal_operator(const exprt &expr)
1418
{
1519
return is_CTL_operator(expr) || is_LTL_operator(expr) ||
@@ -136,3 +140,78 @@ bool is_SVA(const exprt &expr)
136140

137141
return !has_subexpr(expr, non_SVA_operator);
138142
}
143+
144+
std::optional<exprt> SVA_to_LTL(const exprt &expr)
145+
{
146+
// Some SVA is directly mappable to LTL
147+
if(expr.id() == ID_sva_always)
148+
{
149+
auto rec = SVA_to_LTL(to_sva_always_expr(expr).op());
150+
if(rec.has_value())
151+
return G_exprt{rec.value()};
152+
else
153+
return {};
154+
}
155+
else if(expr.id() == ID_sva_s_eventually)
156+
{
157+
auto rec = SVA_to_LTL(to_sva_s_eventually_expr(expr).op());
158+
if(rec.has_value())
159+
return F_exprt{rec.value()};
160+
else
161+
return {};
162+
}
163+
else if(expr.id() == ID_sva_s_nexttime)
164+
{
165+
auto rec = SVA_to_LTL(to_sva_s_nexttime_expr(expr).op());
166+
if(rec.has_value())
167+
return X_exprt{rec.value()};
168+
else
169+
return {};
170+
}
171+
else if(expr.id() == ID_sva_nexttime)
172+
{
173+
auto rec = SVA_to_LTL(to_sva_nexttime_expr(expr).op());
174+
if(rec.has_value())
175+
return X_exprt{rec.value()};
176+
else
177+
return {};
178+
}
179+
else if(expr.id() == ID_sva_overlapped_implication)
180+
{
181+
auto &implication = to_sva_overlapped_implication_expr(expr);
182+
auto rec_lhs = SVA_to_LTL(implication.lhs());
183+
auto rec_rhs = SVA_to_LTL(implication.rhs());
184+
if(rec_lhs.has_value() && rec_rhs.has_value())
185+
return implies_exprt{rec_lhs.value(), rec_rhs.value()};
186+
else
187+
return {};
188+
}
189+
else if(expr.id() == ID_sva_non_overlapped_implication)
190+
{
191+
auto &implication = to_sva_non_overlapped_implication_expr(expr);
192+
auto rec_lhs = SVA_to_LTL(implication.lhs());
193+
auto rec_rhs = SVA_to_LTL(implication.rhs());
194+
if(rec_lhs.has_value() && rec_rhs.has_value())
195+
return implies_exprt{rec_lhs.value(), X_exprt{rec_rhs.value()}};
196+
else
197+
return {};
198+
}
199+
else if(
200+
expr.id() == ID_and || expr.id() == ID_implies || expr.id() == ID_or ||
201+
expr.id() == ID_not)
202+
{
203+
exprt copy = expr;
204+
for(auto &op : copy.operands())
205+
{
206+
auto rec = SVA_to_LTL(op);
207+
if(!rec.has_value())
208+
return {};
209+
op = rec.value();
210+
}
211+
return copy;
212+
}
213+
else if(!has_temporal_operator(expr))
214+
return expr;
215+
else
216+
return {};
217+
}

src/temporal-logic/temporal_logic.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,8 @@ bool is_SVA_operator(const exprt &);
7171
/// Returns true iff the given expression is an SVA expression
7272
bool is_SVA(const exprt &);
7373

74+
/// If possible, this maps an SVA expression to an equivalent LTL
75+
/// expression, or otherwise returns {}.
76+
std::optional<exprt> SVA_to_LTL(const exprt &);
77+
7478
#endif

0 commit comments

Comments
 (0)