Skip to content

Commit 0f16fe8

Browse files
pleichelliottt
andauthored
Defaults for well known SMT solvers (#52)
This commit adds the methods `.with_z3_defaults()` and `.with_cvc5_defaults()` to the `ContextBuilder`. These methods will add the default arguments to start the respective SMT solver in REPL mode. --------- Co-authored-by: Trevor Elliott <[email protected]>
1 parent e4b2063 commit 0f16fe8

File tree

7 files changed

+66
-30
lines changed

7 files changed

+66
-30
lines changed

.github/workflows/ci.yml

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,26 @@ name: CI
22

33
on:
44
push:
5-
branches: [ "main" ]
5+
branches: ["main"]
66
pull_request:
7-
branches: [ "main" ]
7+
branches: ["main"]
88

99
env:
1010
CARGO_TERM_COLOR: always
1111

1212
jobs:
1313
build:
14-
1514
runs-on: ubuntu-latest
1615

1716
steps:
18-
- uses: actions/checkout@v3
19-
- name: Install Z3
20-
run: sudo apt install -y z3
21-
- name: Build
22-
run: cargo build --verbose
23-
- name: Run tests
24-
run: cargo test --verbose
25-
- name: Run Sudoku Example
26-
run: |
27-
cargo run --example sudoku
28-
cargo run --example quantifiers
17+
- uses: actions/checkout@v3
18+
- name: Install Solvers
19+
run: sudo apt install -y z3 cvc5
20+
- name: Build
21+
run: cargo build --verbose
22+
- name: Run tests
23+
run: cargo test --verbose
24+
- name: Run Sudoku Example
25+
run: |
26+
cargo run --example sudoku
27+
cargo run --example quantifiers

README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ use easy_smt::{ContextBuilder, Response};
3333
fn main() -> std::io::Result<()> {
3434
// Create a new context, backed by a Z3 subprocess.
3535
let mut ctx = ContextBuilder::new()
36-
.solver("z3")
37-
.solver_args(["-smt2", "-in"])
36+
.with_z3_defaults()
3837
.build()?;
3938

4039
// Declare `x` and `y` variables that are bitvectors of width 32.
@@ -148,8 +147,7 @@ fn main() -> std::io::Result<()> {
148147
// Everything needed to replay the solver session will be written
149148
// to `replay.smt2`.
150149
.replay_file(Some(std::fs::File::create("replay.smt2")?))
151-
.solver("z3")
152-
.solver_args(["-smt2", "-in"])
150+
.with_z3_defaults()
153151
.build()?;
154152

155153
// ...

examples/quantifiers.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33

44
fn main() -> std::io::Result<()> {
55
env_logger::init();
6-
let mut ctx = easy_smt::ContextBuilder::new()
7-
.solver("z3")
8-
.solver_args(["-smt2", "-in"])
9-
.build()?;
6+
let mut ctx = easy_smt::ContextBuilder::new().with_z3_defaults().build()?;
107

118
// Declare an uninterpreted representation for sets.
129
ctx.declare_sort("MySet", 0)?;

examples/sudoku.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ use easy_smt::SExpr;
55
fn main() -> std::io::Result<()> {
66
env_logger::init();
77

8-
let mut ctx = easy_smt::ContextBuilder::new()
9-
.solver("z3")
10-
.solver_args(["-smt2", "-in"])
11-
.build()?;
8+
let mut ctx = easy_smt::ContextBuilder::new().with_z3_defaults().build()?;
129

1310
// for helping diagnose unsolvable problems
1411
ctx.set_option(":produce-unsat-cores", ctx.true_())?;

src/context.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,16 @@ impl ContextBuilder {
8181
Self::default()
8282
}
8383

84+
/// Initialize the builder with Z3 defaults.
85+
pub fn with_z3_defaults(&mut self) -> &mut Self {
86+
self.solver("z3").solver_args(["-smt2", "-in", "-v:0"])
87+
}
88+
89+
/// Initialize the builder with CVC5 defaults.
90+
pub fn with_cvc5_defaults(&mut self) -> &mut Self {
91+
self.solver("cvc5").solver_args(["--quiet", "--lang=smt2", "--incremental"])
92+
}
93+
8494
/// Configure the solver that will be used.
8595
///
8696
/// You can pass arguments to the underlying solver via the

tests/error.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
// This test ensures that we can handle `(error "...")` responses from z3.
22
#[test]
33
fn handles_errors_gracefully() -> std::io::Result<()> {
4-
let mut context = easy_smt::ContextBuilder::new()
5-
.solver("z3")
6-
.solver_args(["-smt2", "-in"])
7-
.build()?;
4+
let mut context = easy_smt::ContextBuilder::new().with_z3_defaults().build()?;
85

96
let width = context.numeral(1);
107
let sort = context.bit_vec_sort(width);

tests/solvers.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use easy_smt::{Context, Response};
2+
3+
fn test_solver_interaction(solver: &mut Context) {
4+
let int_sort = solver.int_sort();
5+
let x = solver.declare_const("x", int_sort).unwrap();
6+
7+
// x <= 2 && x > 1
8+
let constr = solver.and(
9+
solver.lte(x, solver.numeral(2)),
10+
solver.gt(x, solver.numeral(1)),
11+
);
12+
solver.assert(constr).unwrap();
13+
14+
assert_eq!(solver.check().unwrap(), Response::Sat);
15+
16+
let solution = solver.get_value(vec![x]).unwrap();
17+
assert_eq!(solution.len(), 1);
18+
assert_eq!(solution[0].0, x);
19+
assert_eq!(solver.get_u64(solution[0].1).unwrap(), 2);
20+
}
21+
22+
#[test]
23+
fn test_z3_solver() {
24+
let mut context = easy_smt::ContextBuilder::new()
25+
.with_z3_defaults()
26+
.build()
27+
.unwrap();
28+
test_solver_interaction(&mut context);
29+
}
30+
31+
#[test]
32+
fn test_cvc5_solver() {
33+
let mut context = easy_smt::ContextBuilder::new()
34+
.with_cvc5_defaults()
35+
.build()
36+
.unwrap();
37+
test_solver_interaction(&mut context);
38+
}

0 commit comments

Comments
 (0)