Skip to content

Commit 3f0410b

Browse files
authored
Merge pull request #1112 from diffblue/sva-to-ltl-refactoring
SVA-to-LTL: refactoring to use vector
2 parents c6dfec8 + 2edd9ab commit 3f0410b

File tree

1 file changed

+82
-33
lines changed

1 file changed

+82
-33
lines changed

src/temporal-logic/sva_to_ltl.cpp

Lines changed: 82 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,78 @@ static exprt n_Xes(mp_integer n, exprt op)
2525
// Returns a set of match conditions (given as LTL formula)
2626
struct 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+
4394
std::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

Comments
 (0)