@@ -25,27 +25,79 @@ 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)
35
+ {
36
+ cond_vector.push_back (std::move (__cond));
37
+ }
38
+
39
+ std::vector<exprt> cond_vector;
40
+
41
+ std::size_t length ()
42
+ {
43
+ return cond_vector.size ();
44
+ }
45
+
46
+ bool empty_match () const
47
+ {
48
+ return cond_vector.empty ();
49
+ }
36
50
37
- bool empty () const
51
+ // c0 ∧ X c1 ∧ XX c2 ....
52
+ exprt cond_expr () const
38
53
{
39
- return length == 0 ;
54
+ exprt::operandst conjuncts;
55
+ conjuncts.reserve (cond_vector.size ());
56
+ for (std::size_t i = 0 ; i < cond_vector.size (); i++)
57
+ {
58
+ auto &c = cond_vector[i];
59
+ if (!c.is_true ())
60
+ conjuncts.push_back (n_Xes (i, cond_vector[i]));
61
+ }
62
+ return conjunction (conjuncts);
63
+ }
64
+
65
+ // generate true ##1 ... ##1 true with length n
66
+ static ltl_sequence_matcht true_match (const mp_integer &n)
67
+ {
68
+ ltl_sequence_matcht result;
69
+ for (mp_integer i; i < n; ++i)
70
+ result.cond_vector .push_back (true_exprt{});
71
+ return result;
40
72
}
41
73
};
42
74
75
+ // nonoverlapping concatenation
76
+ ltl_sequence_matcht concat (ltl_sequence_matcht a, const ltl_sequence_matcht &b)
77
+ {
78
+ a.cond_vector .insert (
79
+ a.cond_vector .end (), b.cond_vector .begin (), b.cond_vector .end ());
80
+ return a;
81
+ }
82
+
83
+ // overlapping concatenation
84
+ ltl_sequence_matcht
85
+ overlapping_concat (ltl_sequence_matcht a, ltl_sequence_matcht b)
86
+ {
87
+ PRECONDITION (!a.empty_match ());
88
+ PRECONDITION (!b.empty_match ());
89
+ auto a_last = a.cond_vector .back ();
90
+ a.cond_vector .pop_back ();
91
+ b.cond_vector .front () = conjunction ({a_last, b.cond_vector .front ()});
92
+ return concat (std::move (a), b);
93
+ }
94
+
43
95
std::vector<ltl_sequence_matcht> LTL_sequence_matches (const exprt &sequence)
44
96
{
45
97
if (sequence.id () == ID_sva_boolean)
46
98
{
47
99
// atomic proposition
48
- return {{to_sva_boolean_expr (sequence).op (), 1 }};
100
+ return {ltl_sequence_matcht {to_sva_boolean_expr (sequence).op ()}};
49
101
}
50
102
else if (sequence.id () == ID_sva_sequence_concatenation)
51
103
{
@@ -57,17 +109,16 @@ std::vector<ltl_sequence_matcht> LTL_sequence_matches(const exprt &sequence)
57
109
return {};
58
110
59
111
std::vector<ltl_sequence_matcht> result;
112
+
60
113
// cross product
61
114
for (auto &match_lhs : matches_lhs)
62
115
for (auto &match_rhs : matches_rhs)
63
116
{
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 );
117
+ // Sequence concatenation is overlapping
118
+ auto new_match = overlapping_concat (match_lhs, match_rhs);
119
+ CHECK_RETURN (
120
+ new_match.length () == match_lhs.length () + match_rhs.length () - 1 );
121
+ result.push_back (std::move (new_match));
71
122
}
72
123
return result;
73
124
}
@@ -82,12 +133,12 @@ std::vector<ltl_sequence_matcht> LTL_sequence_matches(const exprt &sequence)
82
133
83
134
if (delay.to ().is_nil ())
84
135
{
136
+ // delay as instructed
137
+ auto delay_sequence = ltl_sequence_matcht::true_match (from_int);
138
+
85
139
for (auto &match : matches)
86
- {
87
- // delay as instructed
88
- match.length += from_int;
89
- match.cond = n_Xes (from_int, match.cond );
90
- }
140
+ match = concat (delay_sequence, match);
141
+
91
142
return matches;
92
143
}
93
144
else if (delay.to ().id () == ID_infinity)
@@ -101,13 +152,12 @@ std::vector<ltl_sequence_matcht> LTL_sequence_matches(const exprt &sequence)
101
152
102
153
for (mp_integer i = from_int; i <= to_int; ++i)
103
154
{
155
+ // delay as instructed
156
+ auto delay_sequence = ltl_sequence_matcht::true_match (i);
157
+
104
158
for (const auto &match : matches)
105
159
{
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));
160
+ new_matches.push_back (concat (delay_sequence, match));
111
161
}
112
162
}
113
163
@@ -239,15 +289,15 @@ std::optional<exprt> SVA_to_LTL(exprt expr)
239
289
for (auto &match : matches)
240
290
{
241
291
const auto overlapped = expr.id () == ID_sva_overlapped_implication;
242
- if (match.empty () && overlapped)
292
+ if (match.empty_match () && overlapped)
243
293
{
244
294
// ignore the empty match
245
295
}
246
296
else
247
297
{
248
- auto delay = match.length + (overlapped ? 0 : 1 ) - 1 ;
298
+ auto delay = match.length () + (overlapped ? 0 : 1 ) - 1 ;
249
299
auto delayed_property = n_Xes (delay, property_rec.value ());
250
- conjuncts.push_back (implies_exprt{match.cond , delayed_property});
300
+ conjuncts.push_back (implies_exprt{match.cond_expr () , delayed_property});
251
301
}
252
302
}
253
303
@@ -275,15 +325,15 @@ std::optional<exprt> SVA_to_LTL(exprt expr)
275
325
for (auto &match : matches)
276
326
{
277
327
const auto overlapped = expr.id () == ID_sva_overlapped_followed_by;
278
- if (match.empty () && overlapped)
328
+ if (match.empty_match () && overlapped)
279
329
{
280
330
// ignore the empty match
281
331
}
282
332
else
283
333
{
284
- auto delay = match.length + (overlapped ? 0 : 1 ) - 1 ;
334
+ auto delay = match.length () + (overlapped ? 0 : 1 ) - 1 ;
285
335
auto delayed_property = n_Xes (delay, property_rec.value ());
286
- disjuncts.push_back (and_exprt{match.cond , delayed_property});
336
+ disjuncts.push_back (and_exprt{match.cond_expr () , delayed_property});
287
337
}
288
338
}
289
339
@@ -310,8 +360,8 @@ std::optional<exprt> SVA_to_LTL(exprt expr)
310
360
311
361
for (auto &match : matches)
312
362
{
313
- if (!match.empty ())
314
- disjuncts.push_back (match.cond );
363
+ if (!match.empty_match ())
364
+ disjuncts.push_back (match.cond_expr () );
315
365
}
316
366
317
367
return disjunction (disjuncts);
0 commit comments