Skip to content

Commit 1d29235

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 7947c89 commit 1d29235

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

src/temporal-logic/temporal_logic.cpp

+76
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,79 @@ std::optional<exprt> LTL_to_CTL(exprt expr)
210210
else
211211
return {};
212212
}
213+
214+
std::optional<exprt> SVA_to_LTL(exprt expr)
215+
{
216+
// Some SVA is directly mappable to LTL
217+
if(expr.id() == ID_sva_always)
218+
{
219+
auto rec = SVA_to_LTL(to_sva_always_expr(expr).op());
220+
if(rec.has_value())
221+
return G_exprt{rec.value()};
222+
else
223+
return {};
224+
}
225+
else if(expr.id() == ID_sva_s_eventually)
226+
{
227+
auto rec = SVA_to_LTL(to_sva_s_eventually_expr(expr).op());
228+
if(rec.has_value())
229+
return F_exprt{rec.value()};
230+
else
231+
return {};
232+
}
233+
else if(expr.id() == ID_sva_s_nexttime)
234+
{
235+
auto rec = SVA_to_LTL(to_sva_s_nexttime_expr(expr).op());
236+
if(rec.has_value())
237+
return X_exprt{rec.value()};
238+
else
239+
return {};
240+
}
241+
else if(expr.id() == ID_sva_nexttime)
242+
{
243+
auto rec = SVA_to_LTL(to_sva_nexttime_expr(expr).op());
244+
if(rec.has_value())
245+
return X_exprt{rec.value()};
246+
else
247+
return {};
248+
}
249+
else if(expr.id() == ID_sva_overlapped_implication)
250+
{
251+
auto &implication = to_sva_overlapped_implication_expr(expr);
252+
auto rec_lhs = SVA_to_LTL(implication.lhs());
253+
auto rec_rhs = SVA_to_LTL(implication.rhs());
254+
if(rec_lhs.has_value() && rec_rhs.has_value())
255+
return implies_exprt{rec_lhs.value(), rec_rhs.value()};
256+
else
257+
return {};
258+
}
259+
else if(expr.id() == ID_sva_non_overlapped_implication)
260+
{
261+
auto &implication = to_sva_non_overlapped_implication_expr(expr);
262+
auto rec_lhs = SVA_to_LTL(implication.lhs());
263+
auto rec_rhs = SVA_to_LTL(implication.rhs());
264+
if(rec_lhs.has_value() && rec_rhs.has_value())
265+
return implies_exprt{rec_lhs.value(), X_exprt{rec_rhs.value()}};
266+
else
267+
return {};
268+
}
269+
else if(!has_temporal_operator(expr))
270+
{
271+
return expr;
272+
}
273+
else if(
274+
expr.id() == ID_and || expr.id() == ID_implies || expr.id() == ID_or ||
275+
expr.id() == ID_not)
276+
{
277+
for(auto &op : expr.operands())
278+
{
279+
auto rec = SVA_to_LTL(op);
280+
if(!rec.has_value())
281+
return {};
282+
op = rec.value();
283+
}
284+
return expr;
285+
}
286+
else
287+
return {};
288+
}

src/temporal-logic/temporal_logic.h

+4
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,8 @@ bool is_SVA_always_s_eventually_p(const exprt &);
8181
/// returns {} if not possible
8282
std::optional<exprt> LTL_to_CTL(exprt);
8383

84+
/// If possible, this maps an SVA expression to an equivalent LTL
85+
/// expression, or otherwise returns {}.
86+
std::optional<exprt> SVA_to_LTL(exprt);
87+
8488
#endif

0 commit comments

Comments
 (0)