Skip to content

Commit 438a803

Browse files
committed
extract sva_sequence_matcht
This extracts the class that represents potential SVA sequence matches, and the function that generates these from SVA sequence expressions into a separate file.
1 parent 2d61d66 commit 438a803

File tree

2 files changed

+14
-147
lines changed

2 files changed

+14
-147
lines changed

src/temporal-logic/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ SRC = ctl.cpp \
22
ltl.cpp \
33
nnf.cpp \
44
normalize_property.cpp \
5+
sva_sequence_match.cpp \
56
sva_to_ltl.cpp \
67
temporal_logic.cpp \
78
trivial_sva.cpp \

src/temporal-logic/sva_to_ltl.cpp

Lines changed: 13 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Author: Daniel Kroening, [email protected]
1111
#include <verilog/sva_expr.h>
1212

1313
#include "ltl.h"
14+
#include "sva_sequence_match.h"
1415
#include "temporal_logic.h"
1516

1617
static exprt n_Xes(mp_integer n, exprt op)
@@ -22,153 +23,18 @@ static exprt n_Xes(mp_integer n, exprt op)
2223
return n_Xes(n - 1, X_exprt{std::move(op)});
2324
}
2425

25-
// Returns a set of match conditions (given as LTL formula)
26-
struct ltl_sequence_matcht
26+
// c0 ∧ X c1 ∧ XX c2 ....
27+
static exprt ltl(const sva_sequence_matcht &match)
2728
{
28-
// the empty match
29-
ltl_sequence_matcht()
29+
exprt::operandst conjuncts;
30+
conjuncts.reserve(match.cond_vector.size());
31+
for(std::size_t i = 0; i < match.cond_vector.size(); i++)
3032
{
33+
auto &c = match.cond_vector[i];
34+
if(!c.is_true())
35+
conjuncts.push_back(n_Xes(i, c));
3136
}
32-
33-
// a match of length 1
34-
explicit ltl_sequence_matcht(exprt __cond) : cond_vector{1, std::move(__cond)}
35-
{
36-
}
37-
38-
std::vector<exprt> cond_vector;
39-
40-
std::size_t length()
41-
{
42-
return cond_vector.size();
43-
}
44-
45-
bool empty_match() const
46-
{
47-
return cond_vector.empty();
48-
}
49-
50-
// c0 ∧ X c1 ∧ XX c2 ....
51-
exprt cond_expr() const
52-
{
53-
exprt::operandst conjuncts;
54-
conjuncts.reserve(cond_vector.size());
55-
for(std::size_t i = 0; i < cond_vector.size(); i++)
56-
{
57-
auto &c = cond_vector[i];
58-
if(!c.is_true())
59-
conjuncts.push_back(n_Xes(i, c));
60-
}
61-
return conjunction(conjuncts);
62-
}
63-
64-
// generate true ##1 ... ##1 true with length n
65-
static ltl_sequence_matcht true_match(const mp_integer &n)
66-
{
67-
ltl_sequence_matcht result;
68-
for(mp_integer i; i < n; ++i)
69-
result.cond_vector.push_back(true_exprt{});
70-
return result;
71-
}
72-
};
73-
74-
// nonoverlapping concatenation
75-
ltl_sequence_matcht concat(ltl_sequence_matcht a, const ltl_sequence_matcht &b)
76-
{
77-
a.cond_vector.insert(
78-
a.cond_vector.end(), b.cond_vector.begin(), b.cond_vector.end());
79-
return a;
80-
}
81-
82-
// overlapping concatenation
83-
ltl_sequence_matcht
84-
overlapping_concat(ltl_sequence_matcht a, ltl_sequence_matcht b)
85-
{
86-
PRECONDITION(!a.empty_match());
87-
PRECONDITION(!b.empty_match());
88-
auto a_last = a.cond_vector.back();
89-
a.cond_vector.pop_back();
90-
b.cond_vector.front() = conjunction({a_last, b.cond_vector.front()});
91-
return concat(std::move(a), b);
92-
}
93-
94-
std::vector<ltl_sequence_matcht> LTL_sequence_matches(const exprt &sequence)
95-
{
96-
if(sequence.id() == ID_sva_boolean)
97-
{
98-
// atomic proposition
99-
return {ltl_sequence_matcht{to_sva_boolean_expr(sequence).op()}};
100-
}
101-
else if(sequence.id() == ID_sva_sequence_concatenation)
102-
{
103-
auto &concatenation = to_sva_sequence_concatenation_expr(sequence);
104-
auto matches_lhs = LTL_sequence_matches(concatenation.lhs());
105-
auto matches_rhs = LTL_sequence_matches(concatenation.rhs());
106-
107-
if(matches_lhs.empty() || matches_rhs.empty())
108-
return {};
109-
110-
std::vector<ltl_sequence_matcht> result;
111-
112-
// cross product
113-
for(auto &match_lhs : matches_lhs)
114-
for(auto &match_rhs : matches_rhs)
115-
{
116-
// Sequence concatenation is overlapping
117-
auto new_match = overlapping_concat(match_lhs, match_rhs);
118-
CHECK_RETURN(
119-
new_match.length() == match_lhs.length() + match_rhs.length() - 1);
120-
result.push_back(std::move(new_match));
121-
}
122-
return result;
123-
}
124-
else if(sequence.id() == ID_sva_cycle_delay)
125-
{
126-
auto &delay = to_sva_cycle_delay_expr(sequence);
127-
auto matches = LTL_sequence_matches(delay.op());
128-
auto from_int = numeric_cast_v<mp_integer>(delay.from());
129-
130-
if(matches.empty())
131-
return {};
132-
133-
if(delay.to().is_nil())
134-
{
135-
// delay as instructed
136-
auto delay_sequence = ltl_sequence_matcht::true_match(from_int);
137-
138-
for(auto &match : matches)
139-
match = concat(delay_sequence, match);
140-
141-
return matches;
142-
}
143-
else if(delay.to().id() == ID_infinity)
144-
{
145-
return {}; // can't encode
146-
}
147-
else if(delay.to().is_constant())
148-
{
149-
auto to_int = numeric_cast_v<mp_integer>(to_constant_expr(delay.to()));
150-
std::vector<ltl_sequence_matcht> new_matches;
151-
152-
for(mp_integer i = from_int; i <= to_int; ++i)
153-
{
154-
// delay as instructed
155-
auto delay_sequence = ltl_sequence_matcht::true_match(i);
156-
157-
for(const auto &match : matches)
158-
{
159-
new_matches.push_back(concat(delay_sequence, match));
160-
}
161-
}
162-
163-
return new_matches;
164-
}
165-
else
166-
return {};
167-
}
168-
else
169-
{
170-
return {}; // unsupported
171-
}
37+
return conjunction(conjuncts);
17238
}
17339

17440
/// takes an SVA property as input, and returns an equivalent LTL property,
@@ -296,7 +162,7 @@ std::optional<exprt> SVA_to_LTL(exprt expr)
296162
{
297163
auto delay = match.length() + (overlapped ? 0 : 1) - 1;
298164
auto delayed_property = n_Xes(delay, property_rec.value());
299-
conjuncts.push_back(implies_exprt{match.cond_expr(), delayed_property});
165+
conjuncts.push_back(implies_exprt{ltl(match), delayed_property});
300166
}
301167
}
302168

@@ -332,7 +198,7 @@ std::optional<exprt> SVA_to_LTL(exprt expr)
332198
{
333199
auto delay = match.length() + (overlapped ? 0 : 1) - 1;
334200
auto delayed_property = n_Xes(delay, property_rec.value());
335-
disjuncts.push_back(and_exprt{match.cond_expr(), delayed_property});
201+
disjuncts.push_back(and_exprt{ltl(match), delayed_property});
336202
}
337203
}
338204

@@ -360,7 +226,7 @@ std::optional<exprt> SVA_to_LTL(exprt expr)
360226
for(auto &match : matches)
361227
{
362228
if(!match.empty_match())
363-
disjuncts.push_back(match.cond_expr());
229+
disjuncts.push_back(ltl(match));
364230
}
365231

366232
return disjunction(disjuncts);

0 commit comments

Comments
 (0)