Skip to content

Commit b557160

Browse files
committed
BMC: encode properties using timeframe/handle pair
The property encoding interface is changed to return a timeframe/handle pair, instead of just a condition per timeframe. This allows determining the appropriate size of the counterexample trace.
1 parent 87c6f81 commit b557160

File tree

1 file changed

+41
-5
lines changed

1 file changed

+41
-5
lines changed

src/trans-word-level/property.cpp

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ Function: property
7272

7373
void property(
7474
const exprt &property_expr,
75-
exprt::operandst &prop_handles,
75+
std::map<std::size_t, exprt::operandst> &obligations,
7676
message_handlert &message_handler,
7777
decision_proceduret &solver,
7878
std::size_t no_timeframes,
@@ -87,16 +87,14 @@ void property(
8787
property_expr.id() == ID_sva_nexttime ||
8888
property_expr.id() == ID_sva_s_nexttime)
8989
{
90-
prop_handles.resize(no_timeframes, true_exprt());
9190
if(no_timeframes > 0)
9291
{
9392
exprt tmp = instantiate(property_expr, 0, no_timeframes, ns);
94-
prop_handles.push_back(solver.handle(tmp));
93+
obligations[0].push_back(solver.handle(tmp));
9594
}
9695

9796
return;
9897
}
99-
10098
// We want AG p.
10199
auto &p = [](const exprt &expr) -> const exprt & {
102100
if(expr.id() == ID_AG)
@@ -115,7 +113,45 @@ void property(
115113
instantiate(p, c, no_timeframes, ns);
116114

117115
auto handle = solver.handle(tmp);
118-
prop_handles.push_back(std::move(handle));
116+
obligations[c].push_back(std::move(handle));
117+
}
118+
}
119+
120+
/*******************************************************************\
121+
122+
Function: property
123+
124+
Inputs:
125+
126+
Outputs:
127+
128+
Purpose:
129+
130+
\*******************************************************************/
131+
132+
void property(
133+
const exprt &property_expr,
134+
exprt::operandst &prop_handles,
135+
message_handlert &message_handler,
136+
decision_proceduret &solver,
137+
std::size_t no_timeframes,
138+
const namespacet &ns)
139+
{
140+
// The first element of the pair is the length of the
141+
// counterexample, and the second is the condition that
142+
// must be valid for the property to hold.
143+
std::map<std::size_t, exprt::operandst> obligations;
144+
145+
property(
146+
property_expr, obligations, message_handler, solver, no_timeframes, ns);
147+
148+
// Map obligations onto timeframes.
149+
prop_handles.resize(no_timeframes, true_exprt());
150+
for(auto &obligation_it : obligations)
151+
{
152+
auto t = obligation_it.first;
153+
DATA_INVARIANT(t < no_timeframes, "obligation must have valid timeframe");
154+
prop_handles[t] = conjunction(obligation_it.second);
119155
}
120156
}
121157

0 commit comments

Comments
 (0)