Skip to content

Commit 793a281

Browse files
committed
Add swine execution via spawn and parse output into CheckSatResponse and GetModelResponse
1 parent 854e42c commit 793a281

File tree

1 file changed

+62
-11
lines changed

1 file changed

+62
-11
lines changed

z3rro/src/prover.rs

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ use std::{
55
collections::VecDeque,
66
env,
77
fmt::Display,
8-
io::{self, Write},
8+
io::{self, BufRead, BufReader, Read, Write},
99
path::Path,
10-
process::Command,
10+
process::{Command, Stdio},
1111
time::Duration,
1212
};
1313

@@ -19,17 +19,24 @@ use z3::{
1919
};
2020

2121
use crate::{
22-
model::InstrumentedModel,
22+
model::{InstrumentedModel, ModelSource},
2323
smtlib::Smtlib,
2424
util::{set_solver_timeout, ReasonUnknown},
2525
};
2626

27+
use smtlib_lowlevel::{
28+
ast::{CheckSatResponse, GetModelResponse},
29+
Storage,
30+
};
31+
2732
#[derive(Debug, Error)]
2833
pub enum ProverCommandError {
2934
#[error("Environment variable error: {0}")]
3035
EnvVarError(#[from] env::VarError),
3136
#[error("Process execution failed: {0}")]
3237
ProcessError(#[from] io::Error),
38+
#[error("Parse error")]
39+
ParseError,
3340
}
3441

3542
#[derive(Debug)]
@@ -128,12 +135,12 @@ pub struct Prover<'ctx> {
128135
level: usize,
129136
/// The minimum level where an assertion was added to the solver.
130137
min_level_with_provables: Option<usize>,
131-
smt_solver: SolverType
138+
smt_solver: SolverType,
132139
}
133140

134141
impl<'ctx> Prover<'ctx> {
135142
/// Create a new prover with the given [`Context`].
136-
pub fn new(ctx: &'ctx Context, solver_type:SolverType) -> Self {
143+
pub fn new(ctx: &'ctx Context, solver_type: SolverType) -> Self {
137144
Prover {
138145
solver: Solver::new(ctx),
139146
level: 0,
@@ -186,18 +193,60 @@ impl<'ctx> Prover<'ctx> {
186193
.unwrap();
187194
let file_path = smt_file.path();
188195

196+
let child = Command::new("swine")
197+
.arg(file_path)
198+
.stdout(Stdio::piped())
199+
.stderr(Stdio::piped())
200+
.spawn();
201+
match child {
202+
Ok(mut child) => {
203+
if let Some(stdout) = child.stdout.take() {
204+
let storage = Storage::new();
205+
let mut buffer = BufReader::new(stdout);
206+
let mut line = String::new();
207+
buffer.read_line(&mut line)?;
208+
209+
let sat_res = match CheckSatResponse::parse(&storage, &line) {
210+
Ok(res) => res,
211+
Err(e) => {
212+
eprintln!("ParseError: {}", e);
213+
panic!();
214+
}
215+
};
216+
217+
let mut cex = String::new();
218+
buffer.read_to_string(&mut cex)?;
219+
220+
if sat_res == CheckSatResponse::Sat {
221+
match GetModelResponse::parse(&storage, &cex) {
222+
Ok(model_res) => {
223+
let model = InstrumentedModel::new(
224+
ModelSource::SwineModel(model_res),
225+
);
226+
println!("{:?}", model_res);
227+
}
228+
Err(e) => eprintln!("ParseError: {}", e),
229+
}
230+
}
231+
}
232+
}
233+
Err(e) => eprintln!("Failed to spawn: {}", e),
234+
}
235+
189236
let res = execute_swine(file_path);
190237
match res {
191238
Ok(SatResult::Unsat) => Ok(ProveResult::Proof),
192239
Ok(SatResult::Unknown) => {
193240
// TODO: Determine the correct reason for Unknown
194-
Ok(ProveResult::Unknown(ReasonUnknown::Other("unknown".to_string())))
195-
},
241+
Ok(ProveResult::Unknown(ReasonUnknown::Other(
242+
"unknown".to_string(),
243+
)))
244+
}
196245
Ok(SatResult::Sat) => {
197246
// TODO: Get the model from the output of SWINE
198247
panic!("no counterexample for swine")
199-
},
200-
Err(err) => Err(err)
248+
}
249+
Err(err) => Err(err),
201250
}
202251
}
203252
SolverType::Z3 => {
@@ -208,10 +257,12 @@ impl<'ctx> Prover<'ctx> {
208257
};
209258
match res {
210259
SatResult::Unsat => Ok(ProveResult::Proof),
211-
SatResult::Unknown => Ok(ProveResult::Unknown(self.get_reason_unknown().unwrap())),
260+
SatResult::Unknown => {
261+
Ok(ProveResult::Unknown(self.get_reason_unknown().unwrap()))
262+
}
212263
SatResult::Sat => {
213264
let model = self.get_model().unwrap();
214-
let model = InstrumentedModel::new(model);
265+
let model = InstrumentedModel::new(ModelSource::Z3Model(model));
215266
Ok(ProveResult::Counterexample(model))
216267
}
217268
}

0 commit comments

Comments
 (0)