@@ -25,27 +25,78 @@ static exprt n_Xes(mp_integer n, exprt op)
25
25
// Returns a set of match conditions (given as LTL formula)
26
26
struct ltl_sequence_matcht
27
27
{
28
- ltl_sequence_matcht (exprt __cond, mp_integer __length)
29
- : cond(std::move(__cond)), length(std::move(__length) )
28
+ // the empty match
29
+ ltl_sequence_matcht ( )
30
30
{
31
- PRECONDITION (length >= 0 );
32
31
}
33
32
34
- exprt cond; // LTL
35
- mp_integer length; // match_end - match_start + 1
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
+ }
36
49
37
- bool empty () const
50
+ // c0 ∧ X c1 ∧ XX c2 ....
51
+ exprt cond_expr () const
38
52
{
39
- return length == 0 ;
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;
40
71
}
41
72
};
42
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
+
43
94
std::vector<ltl_sequence_matcht> LTL_sequence_matches (const exprt &sequence)
44
95
{
45
96
if (sequence.id () == ID_sva_boolean)
46
97
{
47
98
// atomic proposition
48
- return {{to_sva_boolean_expr (sequence).op (), 1 }};
99
+ return {ltl_sequence_matcht {to_sva_boolean_expr (sequence).op ()}};
49
100
}
50
101
else if (sequence.id () == ID_sva_sequence_concatenation)
51
102
{
@@ -57,17 +108,16 @@ std::vector<ltl_sequence_matcht> LTL_sequence_matches(const exprt &sequence)
57
108
return {};
58
109
59
110
std::vector<ltl_sequence_matcht> result;
111
+
60
112
// cross product
61
113
for (auto &match_lhs : matches_lhs)
62
114
for (auto &match_rhs : matches_rhs)
63
115
{
64
- // Concatenation is overlapping, hence deduct one from
65
- // the length.
66
- auto delay = match_lhs.length - 1 ;
67
- auto rhs_delayed = n_Xes (delay, match_rhs.cond );
68
- result.emplace_back (
69
- and_exprt{match_lhs.cond , rhs_delayed},
70
- match_lhs.length + match_rhs.length - 1 );
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));
71
121
}
72
122
return result;
73
123
}
@@ -82,12 +132,12 @@ std::vector<ltl_sequence_matcht> LTL_sequence_matches(const exprt &sequence)
82
132
83
133
if (delay.to ().is_nil ())
84
134
{
135
+ // delay as instructed
136
+ auto delay_sequence = ltl_sequence_matcht::true_match (from_int);
137
+
85
138
for (auto &match : matches)
86
- {
87
- // delay as instructed
88
- match.length += from_int;
89
- match.cond = n_Xes (from_int, match.cond );
90
- }
139
+ match = concat (delay_sequence, match);
140
+
91
141
return matches;
92
142
}
93
143
else if (delay.to ().id () == ID_infinity)
@@ -101,13 +151,12 @@ std::vector<ltl_sequence_matcht> LTL_sequence_matches(const exprt &sequence)
101
151
102
152
for (mp_integer i = from_int; i <= to_int; ++i)
103
153
{
154
+ // delay as instructed
155
+ auto delay_sequence = ltl_sequence_matcht::true_match (i);
156
+
104
157
for (const auto &match : matches)
105
158
{
106
- // delay as instructed
107
- auto new_match = match;
108
- new_match.length += from_int;
109
- new_match.cond = n_Xes (i, match.cond );
110
- new_matches.push_back (std::move (new_match));
159
+ new_matches.push_back (concat (delay_sequence, match));
111
160
}
112
161
}
113
162
@@ -239,15 +288,15 @@ std::optional<exprt> SVA_to_LTL(exprt expr)
239
288
for (auto &match : matches)
240
289
{
241
290
const auto overlapped = expr.id () == ID_sva_overlapped_implication;
242
- if (match.empty () && overlapped)
291
+ if (match.empty_match () && overlapped)
243
292
{
244
293
// ignore the empty match
245
294
}
246
295
else
247
296
{
248
- auto delay = match.length + (overlapped ? 0 : 1 ) - 1 ;
297
+ auto delay = match.length () + (overlapped ? 0 : 1 ) - 1 ;
249
298
auto delayed_property = n_Xes (delay, property_rec.value ());
250
- conjuncts.push_back (implies_exprt{match.cond , delayed_property});
299
+ conjuncts.push_back (implies_exprt{match.cond_expr () , delayed_property});
251
300
}
252
301
}
253
302
@@ -275,15 +324,15 @@ std::optional<exprt> SVA_to_LTL(exprt expr)
275
324
for (auto &match : matches)
276
325
{
277
326
const auto overlapped = expr.id () == ID_sva_overlapped_followed_by;
278
- if (match.empty () && overlapped)
327
+ if (match.empty_match () && overlapped)
279
328
{
280
329
// ignore the empty match
281
330
}
282
331
else
283
332
{
284
- auto delay = match.length + (overlapped ? 0 : 1 ) - 1 ;
333
+ auto delay = match.length () + (overlapped ? 0 : 1 ) - 1 ;
285
334
auto delayed_property = n_Xes (delay, property_rec.value ());
286
- disjuncts.push_back (and_exprt{match.cond , delayed_property});
335
+ disjuncts.push_back (and_exprt{match.cond_expr () , delayed_property});
287
336
}
288
337
}
289
338
@@ -310,8 +359,8 @@ std::optional<exprt> SVA_to_LTL(exprt expr)
310
359
311
360
for (auto &match : matches)
312
361
{
313
- if (!match.empty ())
314
- disjuncts.push_back (match.cond );
362
+ if (!match.empty_match ())
363
+ disjuncts.push_back (match.cond_expr () );
315
364
}
316
365
317
366
return disjunction (disjuncts);
0 commit comments