Struct rsmt2::Solver [−][src]
pub struct Solver<Parser> { /* fields omitted */ }
Expand description
Solver providing most of the SMT-LIB 2.5 commands.
Note the Self::tee
function, which takes a file writer to which it will write
everything sent to the solver.
Implementations
Creates a solver kid with the default z3 configuration.
Mostly used in tests, same as Self::new( SmtConf::z3(), parser )
.
Creates a solver kid with the default cvc4 configuration.
Mostly used in tests, same as Self::new( SmtConf::z3(), parser )
.
Creates a solver kid with the default yices 2 configuration.
Mostly used in tests, same as Self::new( SmtConf::yices_2(), parser )
.
Creates a solver kid with the default z3 configuration and command.
Mostly used in tests, same as Self::new( SmtConf::default_z3(), parser )
.
Warning
The command used to run a particular solver is up to the end-user. As such, it does not
make sense to use default commands for anything else than local testing. You should
explicitely pass the command to use with Self::z3
instead.
Creates a solver kid with the default cvc4 configuration and command.
Mostly used in tests, same as Self::new( SmtConf::default_z3(), parser )
.
Warning
The command used to run a particular solver is up to the end-user. As such, it does not
make sense to use default commands for anything else than local testing. You should
explicitely pass the command to use with Self::cvc4
instead.
Creates a solver kid with the default yices 2 configuration and command.
Mostly used in tests, same as Self::new( SmtConf::default_yices_2(), parser )
.
Warning
The command used to run a particular solver is up to the end-user. As such, it does not
make sense to use default commands for anything else than local testing. You should
explicitely pass the command to use with Self::yices_2
instead.
Forces the solver to write all communications to a file.
- fails if the solver is already tee-ed;
- see also
Self::path_tee
.
Forces the solver to write all communications to a file.
- opens
file
withcreate
andwrite
; - fails if the solver is already tee-ed;
- see also
Self::tee
.
Kills the solver kid.
The windows version just prints (exit)
on the kid’s stdin
. Anything else seems to cause
problems.
This function is automatically called when the solver is dropped.
Prints a comment in the tee-ed file, if any.
Asserts an expression.
Examples
let mut solver = Solver::default_z3(()).unwrap();
solver.assert("(= 0 1)").unwrap();
Check-sat command, turns unknown
results into errors.
See also
If you want a more natural way to handle unknown results, see parse_check_sat_or_unk
.
Examples
let mut conf = SmtConf::default_z3();
conf.option("-t:10");
let mut solver = Solver::new(conf, ()).unwrap();
solver.declare_const("x", "Int").unwrap();
solver.declare_const("y", "Int").unwrap();
solver.push(1).unwrap();
solver.assert("(= (+ x y) 0)").unwrap();
let maybe_sat = solver.check_sat().unwrap();
assert_eq! { maybe_sat, true }
solver.pop(1).unwrap();
solver.assert("(= (+ (* x x y) (* y y x)) 7654321)").unwrap();
let sat_res = & solver.check_sat();
match * sat_res {
Err(ref e) => match * e.kind() {
::rsmt2::errors::ErrorKind::Unknown => (),
_ => panic!("expected unknown"),
},
Ok(res) => panic!("expected error: {:?}", res),
}
Check-sat command, turns unknown
results in None
.
See also
Examples
let mut conf = SmtConf::default_z3();
conf.option("-t:10");
solver.path_tee("./log.smt2").unwrap();
solver.declare_const("x", "Int").unwrap();
solver.declare_const("y", "Int").unwrap();
solver.push(1).unwrap();
solver.assert("(= (+ x y) 0)").unwrap();
let maybe_sat = solver.check_sat_or_unk().unwrap();
assert_eq! { maybe_sat, Some(true) }
solver.pop(1).unwrap();
solver.assert("(= (+ (* x x y) (* y y x)) 7654321)").unwrap();
let maybe_sat = solver.check_sat_or_unk().unwrap();
// Unknown ~~~~~~~~~~~~~vvvv
assert_eq! { maybe_sat, None }
Resets the underlying solver. Restarts the kid process if no reset command is supported.
Examples
let mut solver = Solver::default_z3(()).unwrap();
solver.assert("(= 0 1)").unwrap();
assert!(! solver.check_sat().unwrap());
solver.reset().unwrap();
assert!(solver.check_sat().unwrap());
Declares a new constant.
Examples
let mut solver = Solver::default_z3(()).unwrap();
solver.declare_const("x", "Int").unwrap()
pub fn declare_fun<FunSym, Args, OutSort>(
&mut self,
symbol: FunSym,
args: Args,
out: OutSort
) -> SmtRes<()> where
FunSym: Sym2Smt<()>,
OutSort: Sort2Smt,
Args: IntoIterator,
Args::Item: Sort2Smt,
pub fn declare_fun<FunSym, Args, OutSort>(
&mut self,
symbol: FunSym,
args: Args,
out: OutSort
) -> SmtRes<()> where
FunSym: Sym2Smt<()>,
OutSort: Sort2Smt,
Args: IntoIterator,
Args::Item: Sort2Smt,
Declares a new function symbol.
let mut solver = Solver::default_z3(()).unwrap();
solver.declare_fun(
"my_symbol", & [ "Int", "Real", "Bool" ], "Bool"
).unwrap()
Defines a new constant function symbol.
Examples
let mut solver = Solver::default_z3(()).unwrap();
solver.define_const(
"seven", "Int", "7"
).unwrap()
pub fn define_fun<Args>(
&mut self,
symbol: impl Sym2Smt,
args: Args,
out: impl Sort2Smt,
body: impl Expr2Smt
) -> SmtRes<()> where
Args: IntoIterator,
Args::Item: SymAndSort,
pub fn define_fun<Args>(
&mut self,
symbol: impl Sym2Smt,
args: Args,
out: impl Sort2Smt,
body: impl Expr2Smt
) -> SmtRes<()> where
Args: IntoIterator,
Args::Item: SymAndSort,
Defines a new function symbol.
Examples
let mut solver = Solver::default_z3(()).unwrap();
solver.define_fun(
"abs", & [ ("n", "Int") ], "Int", "(ite (< x 0) (- x) x)"
).unwrap()
Pushes n
layers on the assertion stack.
- see also
Self::pop
.
Note that using actlits is more efficient than push/pop, and is useable for most push/pop use-cases.
Examples
let mut solver = Solver::default_z3(()).unwrap();
solver.declare_const("x", "Int").unwrap();
solver.declare_const("y", "Int").unwrap();
solver.assert("(= x y)").unwrap();
let sat = solver.check_sat().unwrap();
assert!(sat);
solver.push(1).unwrap();
solver.assert("(= x (+ x 1))").unwrap();
let sat = solver.check_sat().unwrap();
assert!(! sat);
solver.pop(1).unwrap();
let sat = solver.check_sat().unwrap();
assert!(sat);
Pops n
layers off the assertion stack.
- see also
Self::push
.
Note that using actlits is more efficient than push/pop, and is useable for most push/pop use-cases.
pub fn check_sat_assuming<Idents>(&mut self, idents: Idents) -> SmtRes<bool> where
Idents: IntoIterator,
Idents::Item: Sym2Smt,
pub fn check_sat_assuming<Idents>(&mut self, idents: Idents) -> SmtRes<bool> where
Idents: IntoIterator,
Idents::Item: Sym2Smt,
Check-sat assuming command, turns unknown
results into errors.
- see also actlits.
pub fn check_sat_assuming_or_unk<Ident, Idents>(
&mut self,
idents: Idents
) -> SmtRes<Option<bool>> where
Idents: IntoIterator,
Idents::Item: Sym2Smt,
pub fn check_sat_assuming_or_unk<Ident, Idents>(
&mut self,
idents: Idents
) -> SmtRes<Option<bool>> where
Idents: IntoIterator,
Idents::Item: Sym2Smt,
Check-sat assuming command, turns unknown
results into None
.
- see also actlits.
Sets the logic.
Examples
let mut solver = Solver::default_z3(()).unwrap();
solver.set_logic( ::rsmt2::Logic::QF_UF ).unwrap();
Sets a custom logic.
Examples
let mut solver = Solver::default_z3(()).unwrap();
solver.set_custom_logic("QF_UFBV").unwrap();
pub fn define_fun_rec<Args>(
&mut self,
symbol: impl Sym2Smt,
args: Args,
out: impl Sort2Smt,
body: impl Expr2Smt
) -> SmtRes<()> where
Args: IntoIterator,
Args::Item: SymAndSort,
pub fn define_fun_rec<Args>(
&mut self,
symbol: impl Sym2Smt,
args: Args,
out: impl Sort2Smt,
body: impl Expr2Smt
) -> SmtRes<()> where
Args: IntoIterator,
Args::Item: SymAndSort,
Defines a recursive function.
Examples
let mut solver = Solver::default_z3(()).unwrap();
solver.define_fun_rec(
"abs", & [ ("n", "Int") ], "Int", "(ite (< x 0) (abs (- x)) x)"
).unwrap()
pub fn define_funs_rec<Defs>(&mut self, funs: Defs) -> SmtRes<()> where
Defs: IntoIterator + Clone,
Defs::Item: FunDef,
pub fn define_funs_rec<Defs>(&mut self, funs: Defs) -> SmtRes<()> where
Defs: IntoIterator + Clone,
Defs::Item: FunDef,
Defines some (possibily mutually) recursive functions.
Examples
let mut solver = Solver::default_z3(()).unwrap();
solver.define_funs_rec( & [
("abs_1", [ ("n", "Int") ], "Int", "(ite (< x 0) (abs_2 (- x)) x)"),
("abs_2", [ ("n", "Int") ], "Int", "(ite (< x 0) (abs_3 (- x)) x)"),
("abs_3", [ ("n", "Int") ], "Int", "(ite (< x 0) (abs_1 (- x)) x)"),
] ).unwrap()
pub fn declare_datatypes<Defs>(&mut self, defs: Defs) -> SmtRes<()> where
Defs: IntoIterator + Clone,
Defs::Item: AdtDecl,
pub fn declare_datatypes<Defs>(&mut self, defs: Defs) -> SmtRes<()> where
Defs: IntoIterator + Clone,
Defs::Item: AdtDecl,
Declares mutually recursive datatypes.
A relatively recent version of z3 is recommended. Sort definition is a relatively expert action, this function is a bit complex. The example below goes over how it works.
Examples
use rsmt2::print::{AdtDecl, AdtVariantField, AdtVariant};
// Alright, so we're going to declare two mutually recursive sorts. It is easier to pack the
// sort-declaration data in custom types. If you want to declare a sort, you most likely
// already have a representation for it, so working on custom types is reasonable.
// Notice that the `AdtDecl`, `AdtVariantField` and `AdtVariant` traits from `rsmt2::print::_`
// are in scope. This is what our custom types will need to generate to declare the sort.
// We'll use static string slices for simplicity as `&str` implements all printing traits.
type Sym = &'static str;
type Sort = &'static str;
// Let's start with the top-level sort type.
struct MySort {
// Name of the sort, for instance `List`.
sym: Sym,
// Symbol(s) for the type parameter(s), for instance `T` for `List<T>`. Must be a collection
// of known length, because rsmt2 needs to access the arity (number of type parameters).
args: Vec<Sym>,
// Body of the sort: its variants. For instance the `nil` and `cons` variants for `List<T>`.
variants: Vec<Variant>,
}
impl MySort {
// This thing build the actual definition expected by rsmt2. Its output is something that
// implements `AdtDecl` and can only live as long as the input ref to `self`.
fn as_decl<'me>(&'me self) -> impl AdtDecl + 'me {
// Check out rsmt2's documentation and you'll see that `AdtDecl` is already implemented for
// certain triplets.
(
// Symbol.
&self.sym,
// Sized collection of type-parameter symbols.
&self.args,
// Variant, collection of iterator over `impl AdtVariant` (see below).
self.variants.iter().map(Variant::as_decl),
)
}
fn tree() -> Self {
Self {
sym: "Tree",
args: vec!["T"],
variants: vec![Variant::tree_leaf(), Variant::tree_node()],
}
}
}
// Next up, variants. A variant is a symbol (*e.g.* `nil` or `cons` for `List<T>`) and some
// fields which describe the data stored in the variant.
struct Variant {
sym: Sym,
fields: Vec<Field>,
}
impl Variant {
// Variant declaration; again, `AdtVariant` is implemented for certain types of pairs.
fn as_decl<'me>(&'me self) -> impl AdtVariant + 'me {
(
// Symbol.
self.sym,
// Iterator over field declarations.
self.fields.iter().map(Field::as_decl),
)
}
fn tree_leaf() -> Self {
Self {
sym: "leaf",
fields: vec![],
}
}
fn tree_node() -> Self {
Self {
sym: "node",
fields: vec![Field::tree_node_value(), Field::tree_node_children()],
}
}
}
// A symbol and a sort: describes a piece of data in a variant with a symbol to retrieve it,
// *i.e.* the name of the field.
struct Field {
sym: Sym,
sort: Sort,
}
impl Field {
// As usual, `AdtVariantField` is implemented for certain pairs.
fn as_decl(&self) -> impl AdtVariantField {
(self.sym, self.sort)
}
fn tree_node_value() -> Self {
Self {
sym: "value",
sort: "T",
}
}
fn tree_node_children() -> Self {
Self {
sym: "children",
sort: "(TreeList T)",
}
}
}
let tree = MySort::tree();
// Now this `tree` uses an non-existing `(TreeList T)` sort to store its children, let's declare
// it now.
let nil = Variant {
sym: "nil",
fields: vec![],
};
let cons = Variant {
sym: "cons",
fields: vec![
Field {
sym: "car",
sort: "(Tree T)",
},
Field {
sym: "cdr",
sort: "(TreeList T)",
},
],
};
let tree_list = MySort {
sym: "TreeList",
args: vec!["T"],
variants: vec![nil, cons],
};
let mut solver = rsmt2::Solver::default_z3(()).unwrap();
solver
// These sort are mutually recursive, `Solver::declare_datatypes` needs to declare them at the
// same time.
.declare_datatypes(&[tree.as_decl(), tree_list.as_decl()])
.unwrap();
// That's it! Solver now knows these sorts and we can use them.
solver.declare_const("t1", "(Tree Int)").unwrap();
solver.declare_const("t2", "(Tree Bool)").unwrap();
solver.assert("(> (value t1) 20)").unwrap();
solver.assert("(not (is-leaf t2))").unwrap();
solver.assert("(not (value t2))").unwrap();
let sat = solver.check_sat().unwrap();
assert!(sat);
pub fn get_model<Ident, Type, Value>(
&mut self
) -> SmtRes<Vec<(Ident, Vec<(Ident, Type)>, Type, Value)>> where
Parser: for<'p> IdentParser<Ident, Type, &'p mut RSmtParser> + for<'p> ModelParser<Ident, Type, Value, &'p mut RSmtParser>,
pub fn get_model<Ident, Type, Value>(
&mut self
) -> SmtRes<Vec<(Ident, Vec<(Ident, Type)>, Type, Value)>> where
Parser: for<'p> IdentParser<Ident, Type, &'p mut RSmtParser> + for<'p> ModelParser<Ident, Type, Value, &'p mut RSmtParser>,
Get-model command.
pub fn get_model_const<Ident, Type, Value>(
&mut self
) -> SmtRes<Vec<(Ident, Type, Value)>> where
Parser: for<'p> IdentParser<Ident, Type, &'p mut RSmtParser> + for<'p> ModelParser<Ident, Type, Value, &'p mut RSmtParser>,
pub fn get_model_const<Ident, Type, Value>(
&mut self
) -> SmtRes<Vec<(Ident, Type, Value)>> where
Parser: for<'p> IdentParser<Ident, Type, &'p mut RSmtParser> + for<'p> ModelParser<Ident, Type, Value, &'p mut RSmtParser>,
Get-model command when all the symbols are nullary.
pub fn get_values<Exprs, PExpr, PValue>(
&mut self,
exprs: Exprs
) -> SmtRes<Vec<(PExpr, PValue)>> where
Parser: for<'p> ExprParser<PExpr, (), &'p mut RSmtParser> + for<'p> ValueParser<PValue, &'p mut RSmtParser>,
Exprs: IntoIterator,
Exprs::Item: Expr2Smt,
pub fn get_values<Exprs, PExpr, PValue>(
&mut self,
exprs: Exprs
) -> SmtRes<Vec<(PExpr, PValue)>> where
Parser: for<'p> ExprParser<PExpr, (), &'p mut RSmtParser> + for<'p> ValueParser<PValue, &'p mut RSmtParser>,
Exprs: IntoIterator,
Exprs::Item: Expr2Smt,
Get-values command.
Notice that the input expression type and the output one have no reason to be the same.
pub fn get_unsat_core<Sym>(&mut self) -> SmtRes<Vec<Sym>> where
Parser: for<'p> SymParser<Sym, &'p mut RSmtParser>,
pub fn get_unsat_core<Sym>(&mut self) -> SmtRes<Vec<Sym>> where
Parser: for<'p> SymParser<Sym, &'p mut RSmtParser>,
Get-unsat-core command.
Examples
use rsmt2::Solver;
let mut solver = Solver::default_z3(()).unwrap();
solver.declare_const("x", "Int").unwrap();
solver.declare_const("y", "Int").unwrap();
solver.assert("(= (+ x y) 0)").unwrap();
let future = solver.print_check_sat().unwrap();
// Do stuff while the solver works.
let sat = solver.parse_check_sat(future).unwrap();
assert!(sat);
pub fn get_interpolant<Expr>(
&mut self,
sym_1: impl Sym2Smt,
sym_2: impl Sym2Smt
) -> SmtRes<Expr> where
Parser: for<'p> ExprParser<Expr, (), &'p mut RSmtParser>,
pub fn get_interpolant<Expr>(
&mut self,
sym_1: impl Sym2Smt,
sym_2: impl Sym2Smt
) -> SmtRes<Expr> where
Parser: for<'p> ExprParser<Expr, (), &'p mut RSmtParser>,
Get-interpolant command.
pub fn get_interpolant_with<Info, Expr>(
&mut self,
sym_1: impl Sym2Smt,
sym_2: impl Sym2Smt,
info: Info
) -> SmtRes<Expr> where
Parser: for<'p> ExprParser<Expr, Info, &'p mut RSmtParser>,
pub fn get_interpolant_with<Info, Expr>(
&mut self,
sym_1: impl Sym2Smt,
sym_2: impl Sym2Smt,
info: Info
) -> SmtRes<Expr> where
Parser: for<'p> ExprParser<Expr, Info, &'p mut RSmtParser>,
Get-interpolant command.
Actlit-Related Functions.
See the actlit
module for more details.
Introduces a new actlit.
See the actlit
module for more details.
Deactivates an activation literal, alias for solver.set_actlit(actlit, false)
.
See the actlit
module for more details.
Forces the value of an actlit and consumes it.
See the actlit
module for more details.
Asserts an expression without print information, guarded by an activation literal.
See the actlit
module for more details.
pub fn check_sat_act<Actlits>(&mut self, actlits: Actlits) -> SmtRes<bool> where
Actlits: IntoIterator,
Actlits::Item: Sym2Smt,
pub fn check_sat_act<Actlits>(&mut self, actlits: Actlits) -> SmtRes<bool> where
Actlits: IntoIterator,
Actlits::Item: Sym2Smt,
Check-sat command with activation literals, turns unknown
results into
errors.
pub fn check_sat_act_or_unk<Actlits>(
&mut self,
actlits: Actlits
) -> SmtRes<Option<bool>> where
Actlits: IntoIterator,
Actlits::Item: Sym2Smt,
pub fn check_sat_act_or_unk<Actlits>(
&mut self,
actlits: Actlits
) -> SmtRes<Option<bool>> where
Actlits: IntoIterator,
Actlits::Item: Sym2Smt,
Check-sat command with activation literals, turns unknown
results in
None
.
Prints a check-sat command.
Allows to print the check-sat
and get the result later, e.g. with
Self::parse_check_sat
.
See also
NamedExpr
: a convenient wrapper around any expression that gives it a name.
Examples
use rsmt2::prelude::*;
let mut conf = SmtConf::default_z3();
conf.unsat_cores();
let mut solver = Solver::new(conf, ()).unwrap();
solver.declare_const("n", "Int").unwrap();
solver.declare_const("m", "Int").unwrap();
solver.assert("true").unwrap();
let e_1 = "(> n 7)";
let label_e_1 = "e_1";
let named = NamedExpr::new(label_e_1, e_1);
solver.assert(&named).unwrap();
let e_2 = "(> m 0)";
let label_e_2 = "e_2";
let named = NamedExpr::new(label_e_2, e_2);
solver.assert(&named).unwrap();
let e_3 = "(< n 3)";
let label_e_3 = "e_3";
let named = NamedExpr::new(label_e_3, e_3);
solver.assert(&named).unwrap();
assert!(!solver.check_sat().unwrap());
let core: Vec<String> = solver.get_unsat_core().unwrap();
assert_eq!(core, vec![label_e_1, label_e_3]);
pub fn print_check_sat_act<Actlits>(
&mut self,
actlits: Actlits
) -> SmtRes<FutureCheckSat> where
Actlits: IntoIterator,
Actlits::Item: Sym2Smt,
pub fn print_check_sat_act<Actlits>(
&mut self,
actlits: Actlits
) -> SmtRes<FutureCheckSat> where
Actlits: IntoIterator,
Actlits::Item: Sym2Smt,
Check-sat command, with actlits.
See the actlit
module for more details.
Parse the result of a check-sat, turns unknown
results into errors.
Parse the result of a check-sat, turns unknown
results into None
.
Get-interpolant command.
At the time of writing, only Z3 supports this command.
pub fn print_check_sat_assuming<Idents>(
&mut self,
bool_vars: Idents
) -> SmtRes<FutureCheckSat> where
Idents: IntoIterator,
Idents::Item: Sym2Smt,
pub fn print_check_sat_assuming<Idents>(
&mut self,
bool_vars: Idents
) -> SmtRes<FutureCheckSat> where
Idents: IntoIterator,
Idents::Item: Sym2Smt,
Check-sat with assumptions command with unit info.
pub fn print_check_sat_assuming_with<Idents, Info>(
&mut self,
bool_vars: Idents,
info: Info
) -> SmtRes<FutureCheckSat> where
Info: Copy,
Idents: IntoIterator,
Idents::Item: Sym2Smt<Info>,
pub fn print_check_sat_assuming_with<Idents, Info>(
&mut self,
bool_vars: Idents,
info: Info
) -> SmtRes<FutureCheckSat> where
Info: Copy,
Idents: IntoIterator,
Idents::Item: Sym2Smt<Info>,
Check-sat with assumptions command.
Asynchronous check-sat, see the asynch
module for details.
This function is not unsafe
in the sense that it cannot create undefined behavior.
However, it is unsafe because the asynchronous check might end up running forever in the
background, burning 100% CPU.
Declares a new sort.
Examples
let mut solver = Solver::default_z3(()).unwrap();
solver.declare_sort("A", 0).unwrap();
solver.declare_const("x", "A").unwrap();
solver.declare_const("y", "A").unwrap();
solver.declare_fun("f", & [ "A" ], "A").unwrap();
solver.assert("(= (f (f x)) x)").unwrap();
solver.assert("(= (f x) y)").unwrap();
solver.assert("(not (= x y))").unwrap();
let sat = solver.check_sat().unwrap();
pub fn define_sort<Args>(
&mut self,
sort_sym: impl Sym2Smt,
args: Args,
body: impl Sort2Smt
) -> SmtRes<()> where
Args: IntoIterator,
Args::Item: Sort2Smt,
pub fn define_sort<Args>(
&mut self,
sort_sym: impl Sym2Smt,
args: Args,
body: impl Sort2Smt
) -> SmtRes<()> where
Args: IntoIterator,
Args::Item: Sort2Smt,
Defines a new sort.
Examples
Note the use of Self::define_null_sort
to avoid problems with empty arguments.
let mut solver = Solver::default_z3(()).unwrap();
solver.define_sort("MySet", & ["T"], "(Array T Bool)").unwrap();
solver.define_null_sort("IList", "(List Int)").unwrap();
solver.define_sort(
"List-Set", & ["T"], "(Array (List T) Bool)"
).unwrap();
solver.define_null_sort("I", "Int").unwrap();
solver.declare_const("s1", "(MySet I)").unwrap();
solver.declare_const("s2", "(List-Set Int)").unwrap();
solver.declare_const("a", "I").unwrap();
solver.declare_const("l", "IList").unwrap();
solver.assert("(= (select s1 a) true)").unwrap();
solver.assert("(= (select s2 l) false)").unwrap();
let sat = solver.check_sat().unwrap();
Defines a new nullary sort.
When using Self::define_sort
with empty args
, rust complains because it does not know
what the Arg
type parameter is. This function addresses this problem by not having
arguments.
Declares a new constant.
pub fn declare_fun_with<Args, Info>(
&mut self,
symbol: impl Sym2Smt<Info>,
args: Args,
out: impl Sort2Smt,
info: Info
) -> SmtRes<()> where
Info: Copy,
Args: IntoIterator,
Args::Item: Sort2Smt,
pub fn declare_fun_with<Args, Info>(
&mut self,
symbol: impl Sym2Smt<Info>,
args: Args,
out: impl Sort2Smt,
info: Info
) -> SmtRes<()> where
Info: Copy,
Args: IntoIterator,
Args::Item: Sort2Smt,
Declares a new function symbol.
Defines a new constant.
pub fn define_fun_with<Args, Info>(
&mut self,
symbol: impl Sym2Smt<Info>,
args: Args,
out: impl Sort2Smt,
body: impl Expr2Smt<Info>,
info: Info
) -> SmtRes<()> where
Info: Copy,
Args: IntoIterator,
Args::Item: SymAndSort<Info>,
pub fn define_fun_with<Args, Info>(
&mut self,
symbol: impl Sym2Smt<Info>,
args: Args,
out: impl Sort2Smt,
body: impl Expr2Smt<Info>,
info: Info
) -> SmtRes<()> where
Info: Copy,
Args: IntoIterator,
Args::Item: SymAndSort<Info>,
Defines a new function symbol.
pub fn define_funs_rec_with<Defs, Info>(
&mut self,
funs: Defs,
info: Info
) -> SmtRes<()> where
Info: Copy,
Defs: IntoIterator + Clone,
Defs::Item: FunDef<Info>,
pub fn define_funs_rec_with<Defs, Info>(
&mut self,
funs: Defs,
info: Info
) -> SmtRes<()> where
Info: Copy,
Defs: IntoIterator + Clone,
Defs::Item: FunDef<Info>,
Defines some new (possibily mutually) recursive functions.
pub fn define_fun_rec_with<Args, Info>(
&mut self,
symbol: impl Sym2Smt<Info>,
args: Args,
out: impl Sort2Smt,
body: impl Expr2Smt<Info>,
info: Info
) -> SmtRes<()> where
Info: Copy,
Args: IntoIterator,
Args::Item: SymAndSort<Info>,
pub fn define_fun_rec_with<Args, Info>(
&mut self,
symbol: impl Sym2Smt<Info>,
args: Args,
out: impl Sort2Smt,
body: impl Expr2Smt<Info>,
info: Info
) -> SmtRes<()> where
Info: Copy,
Args: IntoIterator,
Args::Item: SymAndSort<Info>,
Defines a new recursive function.
Asserts an expression with info, optional actlit and optional name.
Asserts an expression with an activation literal, a name and some print info.
Asserts an expression with some print information, guarded by an activation literal.
See the actlit
module for more details.
Asserts an expression with some print information.
Asserts a named expression.
Asserts an expression with a name and some print info.
pub fn check_sat_assuming_with<Info, Syms>(
&mut self,
idents: Syms,
info: Info
) -> SmtRes<bool> where
Info: Copy,
Syms: IntoIterator,
Syms::Item: Sym2Smt<Info>,
pub fn check_sat_assuming_with<Info, Syms>(
&mut self,
idents: Syms,
info: Info
) -> SmtRes<bool> where
Info: Copy,
Syms: IntoIterator,
Syms::Item: Sym2Smt<Info>,
Check-sat assuming command, turns unknown
results into errors.
pub fn check_sat_assuming_or_unk_with<Idents, Info>(
&mut self,
idents: Idents,
info: Info
) -> SmtRes<Option<bool>> where
Info: Copy,
Idents: IntoIterator,
Idents::Item: Sym2Smt<Info>,
pub fn check_sat_assuming_or_unk_with<Idents, Info>(
&mut self,
idents: Idents,
info: Info
) -> SmtRes<Option<bool>> where
Info: Copy,
Idents: IntoIterator,
Idents::Item: Sym2Smt<Info>,
Check-sat assuming command, turns unknown
results into None
.
Set option command.
Activates unsat core production.
Activates model production.
Resets the assertions in the solver.
Get option command.
Trait Implementations
Pull some bytes from this source into the specified buffer, returning how many bytes were read. Read more
Like read
, except that it reads into a slice of buffers. Read more
can_vector
)Determines if this Read
er has an efficient read_vectored
implementation. Read more
read_initializer
)Determines if this Read
er can work with buffers of uninitialized
memory. Read more
Read all bytes until EOF in this source, placing them into buf
. Read more
Read all bytes until EOF in this source, appending them to buf
. Read more
Read the exact number of bytes required to fill buf
. Read more
Creates a “by reference” adapter for this instance of Read
. Read more
Creates an adapter which will chain this stream with another. Read more
Write a buffer into this writer, returning how many bytes were written. Read more
Flush this output stream, ensuring that all intermediately buffered contents reach their destination. Read more
can_vector
)Determines if this Write
r has an efficient write_vectored
implementation. Read more
Attempts to write an entire buffer into this writer. Read more
write_all_vectored
)Attempts to write multiple buffers into this writer. Read more
Writes a formatted string into this writer, returning any error encountered. Read more