Skip to content

Commit 35bb73e

Browse files
committed
SMV netlist output now includes temporal logic properties
The conversion to netlist now includes the properties, which are then reproduced in the SMV output.
1 parent 3c31174 commit 35bb73e

File tree

5 files changed

+121
-14
lines changed

5 files changed

+121
-14
lines changed

regression/ebmc/BDD/BDD_SVA1.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ BDD_SVA1.sv
66
^\[top\.property\.p0\] always top\.my_bit: PROVED$
77
^\[top\.property\.p1\] always top\.my_bit: PROVED$
88
^\[top\.property\.p2\] always \(top\.counter == 3 \|-> \(nexttime top\.counter == 4\)\): FAILURE: property not supported by BDD engine$
9-
^\[top\.property\.p3\] always \(top\.counter == 3 \|=> top\.counter == 4\): PROVED$
9+
^\[top\.property\.p3\] always \(top\.counter == 3 \|=> top\.counter == 4\): FAILURE: property not supported by BDD engine$
1010
^\[top\.property\.p4\] always \(top\.counter == 3 \|=> \(nexttime top\.counter == 5\)\): FAILURE: property not supported by BDD engine$
1111
^\[top\.property\.p5\] always s_eventually top\.counter == 8: PROVED$
1212
^\[top\.property\.p6\] always \(top\.counter == 0 \|-> \(s_eventually top\.counter == 8\)\): FAILURE: property not supported by BDD engine$

src/temporal-logic/temporal_logic.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ bool is_temporal_operator(const exprt &expr)
1919
expr.id() == ID_X || expr.id() == ID_sva_always ||
2020
expr.id() == ID_sva_always || expr.id() == ID_sva_ranged_always ||
2121
expr.id() == ID_sva_nexttime || expr.id() == ID_sva_s_nexttime ||
22+
expr.id() == ID_sva_non_overlapped_implication ||
2223
expr.id() == ID_sva_until || expr.id() == ID_sva_s_until ||
2324
expr.id() == ID_sva_until_with || expr.id() == ID_sva_s_until_with ||
2425
expr.id() == ID_sva_eventually || expr.id() == ID_sva_s_eventually ||

src/trans-netlist/netlist.cpp

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -313,22 +313,50 @@ void netlistt::output_smv(std::ostream &out) const
313313
out << "-- Initial state" << '\n';
314314
out << '\n';
315315

316-
for(unsigned i=0; i<initial.size(); i++)
316+
for(auto &initial_l : initial)
317317
{
318-
out << "INIT ";
319-
print_smv(out, initial[i]);
320-
out << '\n';
318+
if(!initial_l.is_true())
319+
{
320+
out << "INIT ";
321+
print_smv(out, initial_l);
322+
out << '\n';
323+
}
321324
}
322325

323326
out << '\n';
324327
out << "-- TRANS" << '\n';
325328
out << '\n';
326329

327-
for(unsigned i=0; i<transition.size(); i++)
330+
for(auto &trans_l : transition)
328331
{
329-
out << "TRANS ";
330-
print_smv(out, transition[i]);
331-
out << '\n';
332+
if(!trans_l.is_true())
333+
{
334+
out << "TRANS ";
335+
print_smv(out, trans_l);
336+
out << '\n';
337+
}
338+
}
339+
340+
out << '\n';
341+
out << "-- Properties" << '\n';
342+
out << '\n';
343+
344+
for(auto &[id, property] : properties)
345+
{
346+
if(std::holds_alternative<Gpt>(property))
347+
{
348+
out << "-- " << id << '\n';
349+
out << "LTLSPEC G ";
350+
print_smv(out, std::get<Gpt>(property).p);
351+
out << '\n';
352+
}
353+
else if(std::holds_alternative<GFpt>(property))
354+
{
355+
out << "-- " << id << '\n';
356+
out << "LTLSPEC G F ";
357+
print_smv(out, std::get<GFpt>(property).p);
358+
out << '\n';
359+
}
332360
}
333361
}
334362

src/trans-netlist/netlist.h

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ Author: Daniel Kroening, [email protected]
99
#ifndef CPROVER_TRANS_NETLIST_H
1010
#define CPROVER_TRANS_NETLIST_H
1111

12-
#include <iosfwd>
13-
1412
#include "aig.h"
1513
#include "var_map.h"
1614

15+
#include <iosfwd>
16+
#include <variant>
17+
1718
class netlistt:public aig_plus_constraintst
1819
{
1920
public:
@@ -51,7 +52,23 @@ class netlistt:public aig_plus_constraintst
5152
// these are implicit conjunctions
5253
bvt initial;
5354
bvt transition;
54-
55+
56+
struct Gpt
57+
{
58+
literalt p;
59+
};
60+
61+
struct GFpt
62+
{
63+
literalt p;
64+
};
65+
66+
using propertyt = std::variant<Gpt, GFpt>;
67+
68+
// map from property ID to property netlist nodes
69+
using propertiest = std::map<irep_idt, propertyt>;
70+
propertiest properties;
71+
5572
protected:
5673
static std::string id2smv(const irep_idt &id);
5774
void print_smv(std::ostream &out, literalt l) const;

src/trans-netlist/trans_to_netlist.cpp

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,23 @@ Author: Daniel Kroening, [email protected]
66
77
\*******************************************************************/
88

9+
#include "trans_to_netlist.h"
10+
911
#include <util/arith_tools.h>
1012
#include <util/bitvector_expr.h>
1113
#include <util/ebmc_util.h>
1214
#include <util/namespace.h>
1315
#include <util/std_expr.h>
1416

1517
#include <solvers/flattening/boolbv_width.h>
18+
#include <temporal-logic/normalize_property.h>
19+
#include <temporal-logic/temporal_expr.h>
20+
#include <temporal-logic/temporal_logic.h>
21+
#include <verilog/sva_expr.h>
1622

1723
#include "aig_prop.h"
18-
#include "netlist.h"
19-
#include "trans_to_netlist.h"
2024
#include "instantiate_netlist.h"
25+
#include "netlist.h"
2126

2227
/*******************************************************************\
2328
@@ -303,6 +308,62 @@ void convert_trans_to_netlistt::operator()(const irep_idt &module)
303308
dest.initial.push_back(instantiate_convert(
304309
aig_prop, dest.var_map, trans.init(), ns, get_message_handler()));
305310

311+
// properties
312+
for(const auto &[id, symbol] : symbol_table)
313+
{
314+
if(symbol.module == module && symbol.is_property)
315+
{
316+
auto expr = normalize_property(symbol.value);
317+
318+
auto convert = [&aig_prop, this](const exprt &expr) -> literalt {
319+
return instantiate_convert(
320+
aig_prop, dest.var_map, expr, ns, get_message_handler());
321+
};
322+
323+
if(expr.id() == ID_AG || expr.id() == ID_G || expr.id() == ID_sva_always)
324+
{
325+
auto get_phi = [](const exprt &expr) {
326+
if(expr.id() == ID_AG)
327+
return to_AG_expr(expr).op();
328+
else if(expr.id() == ID_G)
329+
return to_G_expr(expr).op();
330+
else if(expr.id() == ID_sva_always)
331+
return to_sva_always_expr(expr).op();
332+
else
333+
PRECONDITION(false);
334+
};
335+
336+
auto phi = get_phi(expr);
337+
338+
if(!has_temporal_operator(phi))
339+
{
340+
dest.properties.emplace(id, netlistt::Gpt{convert(phi)});
341+
}
342+
else if(
343+
phi.id() == ID_AF || phi.id() == ID_F ||
344+
phi.id() == ID_sva_s_eventually)
345+
{
346+
auto get_psi = [](const exprt &expr) {
347+
if(expr.id() == ID_AF)
348+
return to_AF_expr(expr).op();
349+
else if(expr.id() == ID_F)
350+
return to_F_expr(expr).op();
351+
else if(expr.id() == ID_sva_s_eventually)
352+
return to_sva_s_eventually_expr(expr).op();
353+
else
354+
PRECONDITION(false);
355+
};
356+
357+
dest.properties.emplace(id, netlistt::GFpt{convert(get_psi(phi))});
358+
}
359+
else
360+
{
361+
// unsupported
362+
}
363+
}
364+
}
365+
}
366+
306367
// find the nondet nodes
307368
for(std::size_t n=0; n<dest.nodes.size(); n++)
308369
{

0 commit comments

Comments
 (0)