@@ -25,27 +25,78 @@ static exprt n_Xes(mp_integer n, exprt op)
2525// Returns a set of match conditions (given as LTL formula)
2626struct ltl_sequence_matcht
2727{
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 ( )
3030 {
31- PRECONDITION (length >= 0 );
3231 }
3332
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+ }
3649
37- bool empty () const
50+ // c0 ∧ X c1 ∧ XX c2 ....
51+ exprt cond_expr () const
3852 {
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;
4071 }
4172};
4273
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+
4394std::vector<ltl_sequence_matcht> LTL_sequence_matches (const exprt &sequence)
4495{
4596 if (sequence.id () == ID_sva_boolean)
4697 {
4798 // atomic proposition
48- return {{to_sva_boolean_expr (sequence).op (), 1 }};
99+ return {ltl_sequence_matcht {to_sva_boolean_expr (sequence).op ()}};
49100 }
50101 else if (sequence.id () == ID_sva_sequence_concatenation)
51102 {
@@ -57,17 +108,16 @@ std::vector<ltl_sequence_matcht> LTL_sequence_matches(const exprt &sequence)
57108 return {};
58109
59110 std::vector<ltl_sequence_matcht> result;
111+
60112 // cross product
61113 for (auto &match_lhs : matches_lhs)
62114 for (auto &match_rhs : matches_rhs)
63115 {
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));
71121 }
72122 return result;
73123 }
@@ -82,12 +132,12 @@ std::vector<ltl_sequence_matcht> LTL_sequence_matches(const exprt &sequence)
82132
83133 if (delay.to ().is_nil ())
84134 {
135+ // delay as instructed
136+ auto delay_sequence = ltl_sequence_matcht::true_match (from_int);
137+
85138 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+
91141 return matches;
92142 }
93143 else if (delay.to ().id () == ID_infinity)
@@ -101,13 +151,12 @@ std::vector<ltl_sequence_matcht> LTL_sequence_matches(const exprt &sequence)
101151
102152 for (mp_integer i = from_int; i <= to_int; ++i)
103153 {
154+ // delay as instructed
155+ auto delay_sequence = ltl_sequence_matcht::true_match (i);
156+
104157 for (const auto &match : matches)
105158 {
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));
111160 }
112161 }
113162
@@ -239,15 +288,15 @@ std::optional<exprt> SVA_to_LTL(exprt expr)
239288 for (auto &match : matches)
240289 {
241290 const auto overlapped = expr.id () == ID_sva_overlapped_implication;
242- if (match.empty () && overlapped)
291+ if (match.empty_match () && overlapped)
243292 {
244293 // ignore the empty match
245294 }
246295 else
247296 {
248- auto delay = match.length + (overlapped ? 0 : 1 ) - 1 ;
297+ auto delay = match.length () + (overlapped ? 0 : 1 ) - 1 ;
249298 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});
251300 }
252301 }
253302
@@ -275,15 +324,15 @@ std::optional<exprt> SVA_to_LTL(exprt expr)
275324 for (auto &match : matches)
276325 {
277326 const auto overlapped = expr.id () == ID_sva_overlapped_followed_by;
278- if (match.empty () && overlapped)
327+ if (match.empty_match () && overlapped)
279328 {
280329 // ignore the empty match
281330 }
282331 else
283332 {
284- auto delay = match.length + (overlapped ? 0 : 1 ) - 1 ;
333+ auto delay = match.length () + (overlapped ? 0 : 1 ) - 1 ;
285334 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});
287336 }
288337 }
289338
@@ -310,8 +359,8 @@ std::optional<exprt> SVA_to_LTL(exprt expr)
310359
311360 for (auto &match : matches)
312361 {
313- if (!match.empty ())
314- disjuncts.push_back (match.cond );
362+ if (!match.empty_match ())
363+ disjuncts.push_back (match.cond_expr () );
315364 }
316365
317366 return disjunction (disjuncts);
0 commit comments