Skip to content
Open
Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
2e50b5a
Implement execution of swine-z3 on SMT2 files
Feb 11, 2025
57c4725
Add SolverType and CommandError enums, update execute_swine and check…
SeRin-Yang Feb 24, 2025
9b6388a
No functional changes
SeRin-Yang Mar 10, 2025
9120d44
Execute swine directly in the command line
SeRin-Yang Mar 10, 2025
9a0db09
Add SolverType attribute to Prover struct and SMT solver options
SeRin-Yang Mar 19, 2025
6197986
Update check_proof_assuming to return Result for error handling
SeRin-Yang Apr 14, 2025
854e42c
Implement AST evaluation functions for Bool, Int, Real types
SeRin-Yang Apr 30, 2025
793a281
Add swine execution via spawn and parse output into CheckSatResponse …
SeRin-Yang Apr 30, 2025
ae52982
Move code of eval_ast_bool/int/real into SmtEval::eval
SeRin-Yang May 6, 2025
3a41142
Change return type of from_str_to_num_den from (String, String) to (B…
SeRin-Yang May 6, 2025
35b0ef4
Parse counterexample from swine via solver.from_string
SeRin-Yang May 12, 2025
9f44e21
Compare SAT result from swine with 'sat'/'unsat'; return full swine o…
SeRin-Yang May 13, 2025
bc17f1c
Add Cargo.lock file
SeRin-Yang May 13, 2025
ecb9d86
Merge main of moves-rwth/caesar and resolve conflicts
SeRin-Yang May 14, 2025
70f7b1d
Merge remote-tracking branch 'moves-rwth/main'
SeRin-Yang May 16, 2025
4289373
minor changes
SeRin-Yang May 21, 2025
f07c8b7
Remove leftover code
SeRin-Yang May 23, 2025
4af6885
Add check-sat-assuming command for given assumptions
SeRin-Yang May 23, 2025
ecfad75
Add docs for add_check_sat_assuming and add_details_query
SeRin-Yang May 23, 2025
c5464de
Add SolverResult enum
SeRin-Yang May 27, 2025
aaf9c52
Apply the same logic to the SWINE call
SeRin-Yang Jun 4, 2025
b5325b8
Implement check_sat for each SolverType (not working correctly)
SeRin-Yang Jun 5, 2025
fe830be
Fix missing sat check after adding assertions
SeRin-Yang Jun 20, 2025
7709717
Remove print statements used for functon call tracking
SeRin-Yang Jun 20, 2025
6d4259d
Add SMTLIB(String) option to SMTSolverType and SolverType enums
SeRin-Yang Jun 20, 2025
10b522e
no functional change
SeRin-Yang Jul 2, 2025
7f4f5b3
Add CVC5 option to SMTSolverType and SolverType enums
SeRin-Yang Jul 4, 2025
eeac38e
Fix: skip at-most conversion for non-CVC5 solvers
SeRin-Yang Jul 4, 2025
2787eba
Remove SMTLIB option from SMTSolverType and SolverType enums
SeRin-Yang Jul 4, 2025
b33d3b3
Add at_most_k, at_least_k functions
SeRin-Yang Jul 9, 2025
d108056
Clean up unused code
SeRin-Yang Jul 9, 2025
4f7155d
Clean up unused code
SeRin-Yang Jul 9, 2025
2b5c5ad
Restore block_at_least function to original implementation
SeRin-Yang Jul 10, 2025
b42f210
Add SolverType ExternalZ3 and rename SolverType Z3 to InternalZ3
SeRin-Yang Jul 14, 2025
21936b1
Add SolverType Yices
SeRin-Yang Jul 21, 2025
c1cbaf3
Add timeout setting for external SMT solvers
SeRin-Yang Jul 30, 2025
077338d
Change SolverResult::Sat to store a real solver instead of a string
SeRin-Yang Aug 1, 2025
39ffe52
Change solver handling back to match original behavior
SeRin-Yang Aug 18, 2025
98b84e8
Add SolverType parameter to at_most_k
SeRin-Yang Aug 18, 2025
718554a
Rename function to get_solver_type
SeRin-Yang Aug 18, 2025
308846f
Make SolverResult independent from lifetime 'ctx' to fix E0499 error
SeRin-Yang Sep 19, 2025
3a3e33f
Code formatting
SeRin-Yang Sep 19, 2025
50b1814
Add result_solver to Prover for external solver output
SeRin-Yang Sep 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 82 additions & 1 deletion z3rro/src/prover.rs
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},
Expand All @@ -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")
Copy link
Collaborator

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 find here? It should be sufficient to just do the call to swine directly.

.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));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The next step would be to parse the output of SWINE and return a SatResult.

break;
} else {
eprintln!("Failed to execute swine({}) command with status: {}", line, cmd_output.status);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, return a Result and return an error in this case.

}
}
}
} else {
eprintln!("Find command execution failed");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

}
}

fn remove_lines_for_swine(input: &str) -> String {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a doc comment saying which lines this removes.

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() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a comment that you collect the full string for a (possibly multi-line) SMTLIB command by looking for the corresponding closed parenthesis, while counting nested parenthesis.

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 {
Expand Down Expand Up @@ -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();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a next step, add an solver_type attribute of a new enum type SolverType with variants Z3 and SWINE, and then choose here whether to invoke either Z3 or SWINE.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can do this like we did it for SliceVerifyMethod and the SliceOptions::slice_verify_via option in main.rs.


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 {
Expand Down