Crate z3_ref

source ·
Expand description

High level interface to the Z3 SMT solver. Currently, only support for boolean logic is implemented. It is therefore usable only as a SAT solver. We have not yet considered thread safety or reasonable behaviour if multiple contexts are used at once.

Examples

use z3_ref::Stage;
use z3_ref as z3;

// Create Z3 config, context and solver.
let mut ctx = z3::Context::new();

// Create variable, which is of type Ast, which itself represents an
// immutable reference to a Z3 AST object.
let foo = ctx.var_from_int(0);

ctx.assert(foo);

{
    // Push Z3 solver's stack.
    let mut p = ctx.push();

    // A basic example of combining Asts.
    let foo_and_not_foo = p.and(vec![foo.inherit(), p.not(foo)]);
    p.assert(foo_and_not_foo);

    // No way to satisfy foo && !foo.
    assert!(!p.check().is_some())
}
// Pop of the Z3 solver's stack happens here, with the drop of the push
// object p. Asts created between push and pop are no more valid, but this
// library ensures that the borrow checker would refuse any leak.

match ctx.check() {
    Some(result) => assert!(
        result.model() == vec![(0, z3::Evaluation::True)]),
    _ => panic!("the theory should have been satisfiable!"),
}

The following gets refused by the borrow checker because the value not_foo, which is created in the lifetime of p is used after p is dropped.

use z3_ref::Stage;
use z3_ref as z3;

let mut ctx = z3::Context::new();
let foo = ctx.var_from_int(0);
let not_foo;

{
    let mut p = ctx.push();

    not_foo = p.not(foo);
}

ctx.assert(not_foo);

Tricks like this one will also not work (because ctx is mutably borrowed by p).

use z3_ref::Stage;
use z3_ref as z3;

let mut ctx = z3::Context::new();
let foo = ctx.var_from_int(0);
let not_foo;

{
    let mut p = ctx.push();

    not_foo = ctx.not(foo);
}

ctx.assert(not_foo);

Structs

Ast (= abstract syntax tree) is a pointer to a Z3 formula. It can be created by methods of Push or Context object and should not live longer than the object from which it was created.
Base Z3 objects that holds references to Z3 config, context, sort, solver and basic reusable formulae: true and false. Each interaction with Z3 should start with Context::new() and then calling the methods of the object.
An abstract object that gets created after calling Z3 solver push, and on drop it calls Z3 solver pop. It cannot live longer than its parent (which is Context or another Push object), and makes sure that no Ast created between the push and pop can be used after the pop.

Enums

Traits

Context and Push have very similar semantics, both are references to the Z3 context + config + solver, Push has only an extra functionality to pop on drop. This module implements public common functions of Context and Push: operators of the logic, solver’s assert, check, and push functions.