Skip to content

Commit f18799b

Browse files
committed
ebmc: factor out BMC
This extracts the functionality to do plain BMC into a separate file.
1 parent 44e0f2e commit f18799b

File tree

6 files changed

+258
-269
lines changed

6 files changed

+258
-269
lines changed

src/ebmc/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
SRC = \
22
bdd_engine.cpp \
3+
bmc.cpp \
34
cegar/abstract.cpp \
45
cegar/bmc_cegar.cpp \
56
cegar/latch_ordering.cpp \

src/ebmc/bmc.cpp

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*******************************************************************\
2+
3+
Module: Bounded Model Checking
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#include "bmc.h"
10+
11+
#include <solvers/prop/literal_expr.h>
12+
#include <trans-word-level/trans_trace_word_level.h>
13+
#include <trans-word-level/unwind.h>
14+
15+
#include "ebmc_error.h"
16+
17+
#include <chrono>
18+
#include <fstream>
19+
20+
void bmc(
21+
std::size_t bound,
22+
bool convert_only,
23+
const transition_systemt &transition_system,
24+
ebmc_propertiest &properties,
25+
const ebmc_solver_factoryt &solver_factory,
26+
message_handlert &message_handler)
27+
{
28+
messaget message(message_handler);
29+
30+
message.status() << "Generating Decision Problem" << messaget::eom;
31+
32+
// convert the transition system
33+
const namespacet ns(transition_system.symbol_table);
34+
35+
auto solver_wrapper = solver_factory(ns, message_handler);
36+
auto &solver = solver_wrapper.stack_decision_procedure();
37+
38+
::unwind(
39+
transition_system.trans_expr, message_handler, solver, bound + 1, ns, true);
40+
41+
// convert the properties
42+
message.status() << "Properties" << messaget::eom;
43+
44+
for(auto &property : properties.properties)
45+
{
46+
if(property.is_disabled())
47+
continue;
48+
49+
::property(
50+
property.expr,
51+
property.timeframe_handles,
52+
message_handler,
53+
solver,
54+
bound + 1,
55+
ns);
56+
}
57+
58+
// lasso constraints, if needed
59+
if(properties.requires_lasso_constraints())
60+
{
61+
message.status() << "Adding lasso constraints" << messaget::eom;
62+
lasso_constraints(
63+
solver, bound + 1, ns, transition_system.main_symbol->name);
64+
}
65+
66+
if(convert_only)
67+
{
68+
for(const auto &property : properties.properties)
69+
{
70+
if(!property.is_disabled())
71+
solver.set_to_false(conjunction(property.timeframe_handles));
72+
}
73+
}
74+
else
75+
{
76+
message.status() << "Solving with " << solver.decision_procedure_text()
77+
<< messaget::eom;
78+
79+
auto sat_start_time = std::chrono::steady_clock::now();
80+
81+
// Use assumptions to check the properties separately
82+
83+
for(auto &property : properties.properties)
84+
{
85+
if(property.is_disabled())
86+
continue;
87+
88+
message.status() << "Checking " << property.name << messaget::eom;
89+
90+
auto constraint = not_exprt(conjunction(property.timeframe_handles));
91+
auto handle = solver.handle(constraint);
92+
if(handle.is_true())
93+
solver.push({literal_exprt(const_literal(true))});
94+
else if(handle.is_false())
95+
solver.push({literal_exprt(const_literal(false))});
96+
else
97+
solver.push({solver.handle(constraint)});
98+
99+
decision_proceduret::resultt dec_result = solver();
100+
101+
solver.pop();
102+
103+
switch(dec_result)
104+
{
105+
case decision_proceduret::resultt::D_SATISFIABLE:
106+
property.refuted();
107+
message.result() << "SAT: counterexample found" << messaget::eom;
108+
109+
property.counterexample = compute_trans_trace(
110+
property.timeframe_handles,
111+
solver,
112+
bound + 1,
113+
ns,
114+
transition_system.main_symbol->name);
115+
break;
116+
117+
case decision_proceduret::resultt::D_UNSATISFIABLE:
118+
message.result() << "UNSAT: No counterexample found within bound"
119+
<< messaget::eom;
120+
property.proved_with_bound(bound);
121+
break;
122+
123+
case decision_proceduret::resultt::D_ERROR:
124+
message.error() << "Error from decision procedure" << messaget::eom;
125+
property.failure();
126+
break;
127+
128+
default:
129+
property.failure();
130+
throw ebmc_errort() << "Unexpected result from decision procedure";
131+
}
132+
}
133+
134+
auto sat_stop_time = std::chrono::steady_clock::now();
135+
136+
message.statistics()
137+
<< "Solver time: "
138+
<< std::chrono::duration<double>(sat_stop_time - sat_start_time).count()
139+
<< messaget::eom;
140+
}
141+
}

src/ebmc/bmc.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*******************************************************************\
2+
3+
Module: Bounded Model Checking
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// Bounded Model Checking
11+
12+
#ifndef EBMC_BMC_H
13+
#define EBMC_BMC_H
14+
15+
#include "ebmc_properties.h"
16+
#include "ebmc_solver_factory.h"
17+
18+
class exprt;
19+
class transition_systemt;
20+
21+
/// This is word-level BMC.
22+
void bmc(
23+
std::size_t bound,
24+
bool convert_only,
25+
const transition_systemt &,
26+
ebmc_propertiest &,
27+
const ebmc_solver_factoryt &,
28+
message_handlert &);
29+
30+
#endif // EBMC_BMC_H

0 commit comments

Comments
 (0)