-
Notifications
You must be signed in to change notification settings - Fork 11
Implement execution of swine-z3 on SMT2 files #65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 35 commits
2e50b5a
57c4725
9b6388a
9120d44
9a0db09
6197986
854e42c
793a281
ae52982
3a41142
35b0ef4
9f44e21
bc17f1c
ecb9d86
70f7b1d
4289373
f07c8b7
4af6885
ecfad75
c5464de
aaf9c52
b5325b8
fe830be
7709717
6d4259d
10b522e
7f4f5b3
eeac38e
2787eba
b33d3b3
d108056
4f7155d
2b5c5ad
b42f210
21936b1
c1cbaf3
077338d
39ffe52
98b84e8
718554a
308846f
3a3e33f
50b1814
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,16 +9,16 @@ use z3::{ | |
| }; | ||
| use z3rro::{ | ||
| model::{InstrumentedModel, ModelConsistency}, | ||
| prover::{ProveResult, Prover}, | ||
| prover::{ProveResult, Prover, ProverCommandError, SolverType}, | ||
| util::ReasonUnknown, | ||
| }; | ||
|
|
||
| use crate::{ | ||
| ast::{ExprBuilder, Span}, | ||
| resource_limits::{LimitError, LimitsRef}, | ||
| resource_limits::LimitsRef, | ||
| slicing::{ | ||
| model::{SliceMode, SliceModel}, | ||
| util::{PartialMinimizeResult, SubsetExploration}, | ||
| util::{at_most_k, PartialMinimizeResult, SubsetExploration}, | ||
| }, | ||
| smt::translate_exprs::TranslateExprs, | ||
| VerifyError, | ||
|
|
@@ -218,7 +218,10 @@ impl<'ctx> SliceSolver<'ctx> { | |
| options, | ||
| limits_ref, | ||
| )?; | ||
| if exists_forall_solver.check_sat() == SatResult::Sat { | ||
| let sat_res = exists_forall_solver | ||
| .check_sat() | ||
| .map_err(|err| VerifyError::ProverError(err))?; | ||
| if sat_res == SatResult::Sat { | ||
| let model = exists_forall_solver.get_model().unwrap(); | ||
| let slice_model = | ||
| SliceModel::from_model(SliceMode::Verify, &self.slice_stmts, selection, &model); | ||
|
|
@@ -251,7 +254,7 @@ impl<'ctx> SliceSolver<'ctx> { | |
| let res = self.prover.check_proof_assuming(&active_toggle_values); | ||
|
|
||
| let mut slice_searcher = SliceModelSearch::new(active_toggle_values.clone()); | ||
| if let ProveResult::Proof = res { | ||
| if let Ok(ProveResult::Proof) = res { | ||
| slice_searcher.found_active(self.prover.get_unsat_core()); | ||
| } | ||
|
|
||
|
|
@@ -351,7 +354,10 @@ impl<'ctx> SliceSolver<'ctx> { | |
| self.prover.push(); | ||
|
|
||
| slice_sat_binary_search(&mut self.prover, &active_toggle_values, options, limits_ref)?; | ||
| let res = self.prover.check_proof(); | ||
| let res = self | ||
| .prover | ||
| .check_proof() | ||
| .map_err(|err| VerifyError::ProverError(err))?; | ||
| let model = if let Some(model) = self.prover.get_model() { | ||
| assert!(matches!( | ||
| res, | ||
|
|
@@ -469,8 +475,13 @@ fn slice_sat_binary_search<'ctx>( | |
| prover.push(); | ||
|
|
||
| let ctx = prover.get_context(); | ||
| let at_most_n_true = Bool::pb_le(ctx, &slice_vars, at_most_n as i32); | ||
| prover.add_assumption(&at_most_n_true); | ||
| if !slice_vars.is_empty() { | ||
| let at_most_n_true = match prover.get_smt_solver() { | ||
| SolverType::CVC5 | SolverType::YICES => at_most_k(ctx, at_most_n as i64, active_slice_vars), | ||
| _ => Bool::pb_le(ctx, &slice_vars, at_most_n as i32), | ||
| }; | ||
| prover.add_assumption(&at_most_n_true); | ||
| } | ||
| }; | ||
|
|
||
| // TODO: we could have min_least_bound set to 1 if we could conclude for | ||
|
|
@@ -506,7 +517,10 @@ fn slice_sat_binary_search<'ctx>( | |
| if let Some(timeout) = limits_ref.time_left() { | ||
| prover.set_timeout(timeout); | ||
| } | ||
| let res = prover.check_sat(); | ||
|
|
||
| let res = prover | ||
| .check_sat() | ||
| .map_err(|err| VerifyError::ProverError(err))?; | ||
|
|
||
| entered.record("res", tracing::field::debug(res)); | ||
|
|
||
|
|
@@ -571,7 +585,9 @@ fn slice_sat_binary_search<'ctx>( | |
| if let Some(timeout) = limits_ref.time_left() { | ||
| prover.set_timeout(timeout); | ||
| } | ||
| let res = prover.check_sat(); | ||
| let res = prover | ||
| .check_sat() | ||
| .map_err(|err| VerifyError::ProverError(err))?; | ||
| if minimize.min_accept().is_some() { | ||
| assert!(res == SatResult::Sat || res == SatResult::Unknown); | ||
| } else if minimize.max_reject().is_some() { | ||
|
|
@@ -593,7 +609,7 @@ pub fn slice_unsat_search<'ctx>( | |
| prover: &mut Prover<'ctx>, | ||
| options: &SliceSolveOptions, | ||
| limits_ref: &LimitsRef, | ||
| ) -> Result<Option<Vec<Bool<'ctx>>>, LimitError> { | ||
| ) -> Result<Option<Vec<Bool<'ctx>>>, VerifyError> { | ||
| let mut slice_searcher = | ||
| SliceModelSearch::new(exploration.variables().iter().cloned().collect_vec()); | ||
| let all_variables = exploration.variables().clone(); | ||
|
|
@@ -602,14 +618,15 @@ pub fn slice_unsat_search<'ctx>( | |
| limits_ref.check_limits()?; | ||
|
|
||
| match check_proof_seed(&all_variables, prover, limits_ref, &seed) { | ||
| ProveResult::Proof => { | ||
| Ok(ProveResult::Proof) => { | ||
| // now start the shrinking, then block up | ||
| let res = exploration.shrink_block_unsat(seed, |seed| { | ||
| match check_proof_seed(&all_variables, prover, limits_ref, seed) { | ||
| ProveResult::Proof => Some(unsat_core_to_seed(prover, &all_variables)), | ||
| ProveResult::Counterexample | ProveResult::Unknown(_) => None, | ||
| } | ||
| }); | ||
| let res_seed = match check_proof_seed(&all_variables, prover, limits_ref, &seed) { | ||
|
||
| Ok(ProveResult::Proof) => Some(unsat_core_to_seed(prover, &all_variables)), | ||
| Ok(ProveResult::Counterexample) | Ok(ProveResult::Unknown(_)) => None, | ||
| Err(err) => return Err(VerifyError::ProverError(err)), | ||
| }; | ||
|
|
||
| let res = exploration.shrink_block_unsat(seed, |_| res_seed.clone()); | ||
|
|
||
| let res_vec: Vec<_> = res.iter().cloned().collect(); | ||
| slice_searcher.found_active(res_vec); | ||
|
|
@@ -620,16 +637,17 @@ pub fn slice_unsat_search<'ctx>( | |
| SliceMinimality::Size => exploration.block_at_least(res.len()), | ||
| } | ||
| } | ||
| ProveResult::Counterexample => { | ||
| Ok(ProveResult::Counterexample) => { | ||
| // grow the counterexample and then block down | ||
| exploration.grow_block_sat(seed, |seed| { | ||
| match check_proof_seed(&all_variables, prover, limits_ref, seed) { | ||
| ProveResult::Counterexample => true, | ||
| ProveResult::Proof | ProveResult::Unknown(_) => false, | ||
| } | ||
| }); | ||
| let res_seed = match check_proof_seed(&all_variables, prover, limits_ref, &seed) { | ||
|
||
| Ok(ProveResult::Counterexample) => true, | ||
| Ok(ProveResult::Proof) | Ok(ProveResult::Unknown(_)) => false, | ||
| Err(err) => return Err(VerifyError::ProverError(err)), | ||
| }; | ||
|
|
||
| exploration.grow_block_sat(seed, |_| res_seed); | ||
| } | ||
| ProveResult::Unknown(_) => { | ||
| Ok(ProveResult::Unknown(_)) => { | ||
| exploration.block_this(&seed); | ||
|
|
||
| match options.unknown { | ||
|
|
@@ -643,6 +661,7 @@ pub fn slice_unsat_search<'ctx>( | |
| } | ||
| } | ||
| } | ||
| Err(err) => return Err(VerifyError::ProverError(err)), | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -655,7 +674,7 @@ fn check_proof_seed<'ctx>( | |
| prover: &mut Prover<'ctx>, | ||
| limits_ref: &LimitsRef, | ||
| seed: &IndexSet<Bool<'ctx>>, | ||
| ) -> ProveResult { | ||
| ) -> Result<ProveResult, ProverCommandError> { | ||
| let mut timeout = Duration::from_millis(100); | ||
| if let Some(time_left) = limits_ref.time_left() { | ||
| timeout = timeout.min(time_left); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd have the function
at_most_ktake aSolverTypeparameter, and have it do the decision of whether to callBool::pb_leor your ownat_most_kimplementation.