-
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 1 commit
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,10 @@ | ||
| //! Not a SAT solver, but a prover. There's a difference. | ||
|
|
||
| use std::{fmt::Display, time::Duration}; | ||
| //use std::{fmt::Display, time::Duration}; | ||
|
|
||
| use std::{collections::VecDeque, fmt::Display, io::Write, path::Path, process::Command, time::Duration}; | ||
|
|
||
| use tempfile::NamedTempFile; | ||
|
|
||
| use z3::{ | ||
| ast::{forall_const, Ast, Bool, Dynamic}, | ||
|
|
@@ -21,6 +25,68 @@ pub enum ProveResult<'ctx> { | |
| Unknown(ReasonUnknown), | ||
| } | ||
|
|
||
| /// Find the swine-z3 file located under the dir directory, and execute swine-z3 on the file located at file_path | ||
| fn execute_swine(dir: &Path, file_path: &Path) { | ||
| let swine = "swine-z3"; | ||
|
|
||
| let find_output = Command::new("find") | ||
| .arg(dir) | ||
| .arg("-name") | ||
| .arg(swine) | ||
| .output().unwrap(); | ||
|
|
||
| if find_output.status.success() { | ||
| let stdout = String::from_utf8_lossy(&find_output.stdout); | ||
|
|
||
| for line in stdout.lines().rev() { | ||
| let path = Path::new(line); | ||
|
|
||
| if path.exists() && path.is_file() { | ||
| let cmd_output = Command::new(path) | ||
| .arg(file_path) | ||
| .output().unwrap(); | ||
|
|
||
| if cmd_output.status.success() { | ||
| println!("{}", String::from_utf8_lossy(&cmd_output.stdout)); | ||
|
||
| break; | ||
| } else { | ||
| eprintln!("Failed to execute swine({}) command with status: {}", line, cmd_output.status); | ||
|
||
| } | ||
| } | ||
| } | ||
| } else { | ||
| eprintln!("Find command execution failed"); | ||
|
||
| } | ||
| } | ||
|
|
||
| fn remove_lines_for_swine(input: &str) -> String { | ||
|
||
| let mut output = String::new(); | ||
| let mut tmp_buffer: VecDeque<char> = VecDeque::new(); | ||
| let mut input_buffer: VecDeque<char> = input.chars().collect(); | ||
| let mut cnt = 0; | ||
|
|
||
| while let Some(c) = input_buffer.pop_front() { | ||
|
||
| tmp_buffer.push_back(c); | ||
| match c { | ||
| '(' => { | ||
| cnt += 1; | ||
| } | ||
| ')' => { | ||
| cnt -= 1; | ||
| if cnt == 0 { | ||
| let tmp: String = tmp_buffer.iter().collect(); | ||
| if !tmp.contains("declare-fun exp") && !tmp.contains("forall") { | ||
| output.push_str(&tmp); | ||
| } | ||
| tmp_buffer.clear(); | ||
| } | ||
| } | ||
| _ => {} | ||
| } | ||
| } | ||
| output | ||
| } | ||
|
|
||
| impl Display for ProveResult<'_> { | ||
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
| match self { | ||
|
|
@@ -94,6 +160,21 @@ impl<'ctx> Prover<'ctx> { | |
| if self.min_level_with_provables.is_none() { | ||
| return ProveResult::Proof; | ||
| } | ||
|
|
||
| let mut smtlib = self.get_smtlib(); | ||
|
||
|
|
||
| smtlib.add_check_sat(); | ||
|
|
||
| let smtlib = smtlib.into_string(); | ||
| let mut smt_file: NamedTempFile = NamedTempFile::new().unwrap(); | ||
|
|
||
| smt_file.write_all(remove_lines_for_swine(&smtlib).as_bytes()).unwrap(); | ||
|
|
||
| let file_path = smt_file.path(); | ||
| let start_dir = Path::new("../"); | ||
|
|
||
| execute_swine(start_dir, file_path); | ||
|
|
||
| let res = if assumptions.is_empty() { | ||
| self.solver.check() | ||
| } else { | ||
|
|
||
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 don't understand why you'd be using
findhere? It should be sufficient to just do the call to swine directly.