11
11
#include < verilog/sva_expr.h>
12
12
13
13
#include " ltl.h"
14
+ #include " sva_sequence_match.h"
14
15
#include " temporal_logic.h"
15
16
16
17
static exprt n_Xes (mp_integer n, exprt op)
@@ -22,153 +23,18 @@ static exprt n_Xes(mp_integer n, exprt op)
22
23
return n_Xes (n - 1 , X_exprt{std::move (op)});
23
24
}
24
25
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)
27
28
{
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++)
30
32
{
33
+ auto &c = match.cond_vector [i];
34
+ if (!c.is_true ())
35
+ conjuncts.push_back (n_Xes (i, c));
31
36
}
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);
172
38
}
173
39
174
40
// / takes an SVA property as input, and returns an equivalent LTL property,
@@ -296,7 +162,7 @@ std::optional<exprt> SVA_to_LTL(exprt expr)
296
162
{
297
163
auto delay = match.length () + (overlapped ? 0 : 1 ) - 1 ;
298
164
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});
300
166
}
301
167
}
302
168
@@ -332,7 +198,7 @@ std::optional<exprt> SVA_to_LTL(exprt expr)
332
198
{
333
199
auto delay = match.length () + (overlapped ? 0 : 1 ) - 1 ;
334
200
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});
336
202
}
337
203
}
338
204
@@ -360,7 +226,7 @@ std::optional<exprt> SVA_to_LTL(exprt expr)
360
226
for (auto &match : matches)
361
227
{
362
228
if (!match.empty_match ())
363
- disjuncts.push_back (match. cond_expr ( ));
229
+ disjuncts.push_back (ltl (match ));
364
230
}
365
231
366
232
return disjunction (disjuncts);
0 commit comments