ESBMC
Efficient SMT-based Context-Bounded Model Checker
Loading...
Searching...
No Matches
bmc.h
Go to the documentation of this file.
1#ifndef CPROVER_CBMC_BMC_H
2#define CPROVER_CBMC_BMC_H
3
13#include <langapi/language_ui.h>
14#include <list>
15#include <map>
16#include <set>
18#include <solvers/solve.h>
19#include <util/config/options.h>
21#include <util/config/cmdline.h>
22#include <atomic>
23
24class bmct
25{
26public:
27 bmct(goto_functionst &funcs, optionst &opts, contextt &_context);
28
30
31 // Dead-store advisories (CWE-563) computed during goto preprocessing. Set by
32 // the driver before verification; surfaced in SARIF as note-level results
33 // on both the success and failure paths.
34 std::vector<dead_store_advisoryt> dead_store_advisories;
35 // True once a SARIF document carrying the advisories has been written — from
36 // a trace path, or from the --dead-code-check advisory that folds them into
37 // its own document — so start_bmc() does not write a second one. There is a
38 // single SARIF output path, so a second write would truncate the first.
48
49 /* ltl_run_thread returns an ltl_res, or one of these sentinels. A formula
50 * with no prefix assertion, or whose monitor preconditions are violated,
51 * carries no usable prefix verdict: neither ⊤ nor any lower outcome may be
52 * claimed from it (#6547). */
53 static constexpr int ltl_res_uninstrumented = -3;
54
55 // Set when an LTL run produced no four-valued verdict; consulted by
56 // report_result to report UNKNOWN rather than the ⊤ that an absent or
57 // truncated monitor used to produce.
58 std::atomic<bool> ltl_uninstrumented{false};
59
62
64 bool cs_bound_pruned = false;
65
66 virtual smt_resultt start_bmc();
67 virtual smt_resultt run(std::shared_ptr<symex_target_equationt> &eq);
68 virtual ~bmct();
69
73
74protected:
78
79 std::unique_ptr<smt_convt> runtime_solver;
80 std::unique_ptr<reachability_treet> symex;
81 pytest_generator pytest_gen; // For Python pytest test case generation
82 ctest_generator ctest_gen; // For C/C++ CTest test case generation
83 mutable std::atomic<bool> keep_alive_running;
84 mutable std::atomic<int> keep_alive_interval;
85
86 virtual smt_resultt
88
89 // Re-encode `local_eq` in vacuity mode against a fresh solver and check
90 // whether the path to each kept claim is reachable. UNSAT means the
91 // discharge was vacuous: the path assumptions alone are unsatisfiable.
93
96
98 bool invariant_refutes(const symex_target_equationt &eq, size_t claim_index);
99
100 // Set by the vacuity probe when at least one kept claim discharged
101 // vacuously; consulted by report_result to map the final verdict from
102 // SUCCESSFUL to UNKNOWN. Atomic because multi_property_check writes from
103 // parallel job threads.
104 std::atomic<bool> vacuity_detected{false};
105
106 // Set when a violated claim was only violated downstream of a
107 // --loop-invariant-check havoc; consulted by report_result to map a verdict
108 // with no concrete violation from FAILED to UNKNOWN (issue #7480). Atomic
109 // because multi_property_check writes from parallel job threads.
110 std::atomic<bool> weak_invariant_detected{false};
111
112 virtual void show_program(const symex_target_equationt &eq);
113 virtual void report_success();
114 virtual void report_failure();
117 void report_violation();
118
122 bool verdict_is_unknown = false;
123 virtual void report_unknown();
124 virtual void keep_alive_function() const;
125
126 virtual void
127 error_trace(smt_convt &smt_conv, const symex_target_equationt &eq);
128
129 virtual void successful_trace(const symex_target_equationt &eq);
130
131 virtual void show_vcc(const symex_target_equationt &eq);
132
133 virtual void show_vcc(std::ostream &out, const symex_target_equationt &eq);
134
135 virtual void report_trace(smt_resultt &res, const symex_target_equationt &eq);
136
137 virtual void report_result(smt_resultt &res);
138
139 virtual void
141
142 smt_resultt run_thread(std::shared_ptr<symex_target_equationt> &eq);
143
144 /* Not const: the solver that satisfied a prefix assertion is kept in
145 * runtime_solver so the verdict can be backed by a counterexample. */
147
152 const symex_target_equationt &eq,
153 size_t remaining_claims,
155 unsigned int truncated_loops);
156
157 std::vector<std::unique_ptr<ssa_step_algorithm>> algorithms;
158
160 smt_convt &smt_conv,
161 symex_target_equationt &eq) const;
162
163 // for multi-property
165 symex_target_equationt &local_eq,
166 const claim_slicer &claim,
167 const bool &is_goto_cov);
169 const claim_slicer &claim,
170 const bool &is_goto_cov);
171
174 {
175 Unsat, // re-solve returned UNSAT — witness set is exhaustive
176 CapHit, // --max-witnesses limit reached
177 NoInputs, // first witness had no nondet inputs to block
178 Error, // re-solve returned an error / unknown
179 Disabled, // --all-witnesses not set; single witness reported
180 };
181
184 {
185 size_t ce_index; // global ce_counter slot
186 std::vector<collected_nondet_value> nondet_inputs; // input tuple
187 goto_tracet trace; // goto-level trace
188 };
189
196 virtual void report_multi_property_trace(
197 const smt_resultt &res,
198 const std::vector<witness_recordt> &witnesses,
199 enumeration_stop_reasont stop_reason,
200 const std::string &msg,
201 bool reachability_trace = false);
202
204 const claim_slicer &claim,
205 const std::string &claim_sig,
206 const bool &is_assert_cov,
207 const bool &is_cond_cov,
208 const bool &is_branch_cov,
209 const bool &is_branch_func_cov,
210 const bool &is_k_path_cov,
211 const std::unordered_set<std::string> &reached_claims,
212 const std::unordered_multiset<std::string> &reached_mul_claims);
213
214private:
219 void report_property_verdicts(smt_resultt res) const;
220
222 void report_coverage_goal_verdicts(
223 const std::map<std::string, property_resultt> &verdicts) const;
224
228 void seed_property_verdicts(const symex_target_equationt &eq) const;
230 void seed_unreached_claims(const symex_target_equationt &eq) const;
231
235 void record_satisfiable_claim(
236 const claim_slicer &claim,
237 const property_locationt &loc,
238 bool inductive_step,
239 symex_target_equationt &local_eq);
240
248 void record_violated_properties(
249 smt_convt &smt_conv,
250 const symex_target_equationt &eq);
251
255 std::set<std::string> library_files;
256
261 bool reports_final_verdict(smt_resultt res) const;
262
267 bool saw_bounded_loop_truncation = false;
268
272 bool proves_the_program() const;
273
277 bool all_properties_proved(smt_resultt res) const;
278
279 static constexpr size_t default_barren_interleaving_budget = 100;
280
284 size_t barren_interleaving_budget() const;
285
288 struct SolverStats
289 {
290 std::atomic<double> total_time_ms = 0.0;
291 std::string name;
292 std::once_flag name_flag;
293 };
294
295 SolverStats solver_stats;
296
300 std::atomic<size_t> ce_counter{0};
301
307 std::atomic<bool> report_incomplete{false};
308};
309
316 const optionst &options,
317 const goto_functionst &goto_functions,
318 const namespacet &ns);
319
320void report_coverage(
321 const optionst &options,
322 std::unordered_set<std::string> &reached_claims,
323 const std::unordered_multiset<std::string> &reached_mul_claims,
324 pytest_generator &pytest_gen,
325 ctest_generator &ctest_gen);
326
329void note_cov_incomplete(const std::string &reason);
330
335
336#endif
void note_cov_incomplete(const std::string &reason)
Record why a coverage measurement is not exhaustive; the reason is listed under the closing COVERAGE ...
Definition bmc.cpp:96
void report_coverage_completeness()
Closing line of a coverage run: whether every goal was actually decided, and if not,...
Definition bmc.cpp:1786
void report_coverage(const optionst &options, std::unordered_set< std::string > &reached_claims, const std::unordered_multiset< std::string > &reached_mul_claims, pytest_generator &pytest_gen, ctest_generator &ctest_gen)
Definition bmc.cpp:1370
void report_k_step_property_table(const optionst &options, const goto_functionst &goto_functions, const namespacet &ns)
Print the property table a k-step strategy accumulated across its phases, once, where the strategy co...
Definition bmc.cpp:3947
Definition bigint.hh:58
BigInt interleaving_number
Definition bmc.h:60
optionst & options
Definition bmc.h:29
ltl_res
Definition bmc.h:41
@ ltl_res_failing
Definition bmc.h:44
@ ltl_res_bad
Definition bmc.h:45
@ ltl_res_good
Definition bmc.h:42
@ ltl_res_succeeding
Definition bmc.h:43
virtual void error_trace(smt_convt &smt_conv, const symex_target_equationt &eq)
Definition bmc.cpp:409
ctest_generator ctest_gen
Definition bmc.h:82
std::atomic< bool > vacuity_detected
Definition bmc.h:104
enumeration_stop_reasont
Reason why witness enumeration stopped, used in the report footer.
Definition bmc.h:174
@ CapHit
Definition bmc.h:176
@ Error
Definition bmc.h:178
@ Unsat
Definition bmc.h:175
@ Disabled
Definition bmc.h:179
@ NoInputs
Definition bmc.h:177
std::atomic< bool > weak_invariant_detected
Definition bmc.h:110
static constexpr int ltl_res_uninstrumented
Definition bmc.h:53
void clear_verified_claims_in_ssa(symex_target_equationt &local_eq, const claim_slicer &claim, const bool &is_goto_cov)
Definition bmc.cpp:804
BigInt interleaving_failed
Definition bmc.h:61
virtual void report_unknown()
Definition bmc.cpp:603
virtual smt_resultt run_decision_procedure(smt_convt &smt_conv, symex_target_equationt &eq) const
Definition bmc.cpp:517
smt_resultt multi_property_check(const symex_target_equationt &eq, size_t remaining_claims, smt_convt &runtime_solver, unsigned int truncated_loops)
Definition bmc.cpp:2929
bool violates_only_the_abstraction() const
Whether every violation found refutes only the –loop-invariant-check abstraction, so the run neither ...
Definition bmc.cpp:608
virtual void report_trace(smt_resultt &res, const symex_target_equationt &eq)
Definition bmc.cpp:758
pytest_generator pytest_gen
Definition bmc.h:81
virtual void report_multi_property_trace(const smt_resultt &res, const std::vector< witness_recordt > &witnesses, enumeration_stop_reasont stop_reason, const std::string &msg, bool reachability_trace=false)
Multi-witness textual reporter.
Definition bmc.cpp:960
virtual smt_resultt run(std::shared_ptr< symex_target_equationt > &eq)
Definition bmc.cpp:2176
void report_coverage_verbose(const claim_slicer &claim, const std::string &claim_sig, const bool &is_assert_cov, const bool &is_cond_cov, const bool &is_branch_cov, const bool &is_branch_func_cov, const bool &is_k_path_cov, const std::unordered_set< std::string > &reached_claims, const std::unordered_multiset< std::string > &reached_mul_claims)
Definition bmc.cpp:1833
const goto_functionst & program
Definition bmc.h:77
smt_resultt run_thread(std::shared_ptr< symex_target_equationt > &eq)
Definition bmc.cpp:2453
void report_violation()
Emit the verdict for a satisfiable run: FAILED, or UNKNOWN when every violated claim was abstraction-...
Definition bmc.cpp:614
virtual void successful_trace(const symex_target_equationt &eq)
Definition bmc.cpp:260
bool cs_bound_pruned
Mirrors reachability_treet::cs_bound_pruned; valid after start_bmc().
Definition bmc.h:64
virtual void show_program(const symex_target_equationt &eq)
Definition bmc.cpp:698
std::unique_ptr< smt_convt > runtime_solver
Definition bmc.h:79
virtual void report_success()
Definition bmc.cpp:584
std::atomic< bool > keep_alive_running
Definition bmc.h:83
std::vector< dead_store_advisoryt > dead_store_advisories
Definition bmc.h:34
smt_resultt check_claim_unsatisfiable(symex_target_equationt &local_eq) const
Whether the kept claim can hold at all on a feasible path.
Definition bmc.cpp:648
virtual void report_failure()
Definition bmc.cpp:598
bmct(goto_functionst &funcs, optionst &opts, contextt &_context)
Definition bmc.cpp:193
virtual ~bmct()
void generate_smt_from_equation(smt_convt &smt_conv, symex_target_equationt &eq) const
Definition bmc.cpp:476
std::atomic< bool > ltl_uninstrumented
Definition bmc.h:58
std::vector< std::unique_ptr< ssa_step_algorithm > > algorithms
Definition bmc.h:157
bool verdict_is_unknown
Set when the run printed UNKNOWN over a satisfiable result, so start_bmc can return the exit code the...
Definition bmc.h:122
bool invariant_refutes(const symex_target_equationt &eq, size_t claim_index)
Whether the invariant leaves one claim no way to hold (issue #7585).
Definition bmc.cpp:659
virtual void report_result(smt_resultt &res)
Definition bmc.cpp:1956
bool dead_store_sarif_written
Definition bmc.h:39
std::atomic< int > keep_alive_interval
Definition bmc.h:84
virtual smt_resultt start_bmc()
Definition bmc.cpp:2066
const contextt & context
Definition bmc.h:75
virtual void bidirectional_search(smt_convt &smt_conv, const symex_target_equationt &eq)
Definition bmc.cpp:2321
void clear_verified_claims_in_goto(const claim_slicer &claim, const bool &is_goto_cov)
Definition bmc.cpp:833
virtual void show_vcc(const symex_target_equationt &eq)
Definition show_vcc.cpp:54
size_t ltl_results_seen[4]
Definition bmc.h:47
std::unique_ptr< reachability_treet > symex
Definition bmc.h:80
virtual void keep_alive_function() const
Definition bmc.cpp:500
int ltl_run_thread(symex_target_equationt &equation)
Definition bmc.cpp:2645
namespacet ns
Definition bmc.h:76
smt_resultt check_vacuity(symex_target_equationt &local_eq) const
Definition bmc.cpp:669
Claim slicer: remove every other claim of the formula with the exception of the one to keep.
Definition slice.h:45
Definition context.h:57
This generates CTest test-cases for C programs.
Definition ctest.h:14
Definition goto_functions.h:56
Definition goto_trace.h:93
Definition namespace.h:10
Definition options.h:11
Generates pytest test-cases for Python programs.
Definition pytest.h:15
Slim, frontend-facing SMT interface.
Definition smt_conv.h:30
Definition symex_target_equation.h:21
smt_resultt
Result of a call to dec_solve.
Definition smt_result.h:7
One enumerated witness for a failing property.
Definition bmc.h:184
std::vector< collected_nondet_value > nondet_inputs
Definition bmc.h:186
goto_tracet trace
Definition bmc.h:187
size_t ce_index
Definition bmc.h:185
Where a property lives, kept apart from the table key so the report can sort by source position and p...
Definition property_verdict.h:35