mod facade;
pub use facade::ManagerFacade;
pub use facade::SolverFacade;
use crate::formally;
use formally::smt::{
self,
backends::{Backend, Error},
logics::{Logic, LogicEx},
};
use std::{hash::Hash, rc::Rc};
type Result<T, E = Error> = std::result::Result<T, E>;
pub trait Manager: Default + Sized {
type ALL: LogicEx;
type Backend: Backend;
type Solver;
type FuncDecl: Clone + Hash + PartialEq + Eq;
type Sort: Clone + Hash + PartialEq + Eq;
type Term: Clone;
const FUNC_DEF_SUPPORTED: bool = false;
fn backend(&self) -> &Self::Backend;
fn uninterpreted_sort(&self, name: &str) -> Result<Self::Sort>;
fn func_decl(
&self,
solver: &Self::Solver,
name: &str,
sorts: &[Self::Sort],
range: Self::Sort,
) -> Result<Self::FuncDecl>;
#[allow(unused)]
fn func_def(
&self,
solver: &Self::Solver,
name: &str,
sorts: &[Self::Sort],
range: Self::Sort,
variables: &[Self::Term],
body: Self::Term,
) -> Result<Self::FuncDecl> {
unreachable!()
}
fn variable(&self, name: &str, sort: Self::Sort) -> Result<Self::Term>;
fn application(&self, func: &Self::FuncDecl, arguments: &[Self::Term]) -> Result<Self::Term>;
fn constant(&self, cnst: &smt::Constant) -> Result<Self::Term>;
fn quantified(
&self,
quantifier: smt::Quantifier,
variables: &[Self::Term],
body: Self::Term,
) -> Result<Self::Term>;
fn sort(
&self,
sort: <Self::ALL as LogicEx>::Sort<'_>,
to_sort: impl Fn(&smt::SortArgument) -> Result<Self::Sort>,
to_value: impl Fn(&smt::SortArgument) -> Result<&smt::Integer>,
) -> Result<Self::Sort>;
fn atom(
&self,
atom: <Self::ALL as LogicEx>::Atom<'_>,
to_term: impl Fn(&smt::Term) -> Result<Self::Term>,
to_terms: impl Fn(&[smt::Term]) -> Result<Vec<Self::Term>>,
) -> Result<Self::Term>;
#[allow(unused)]
fn export(
&self,
term: Self::Term,
pool: &dyn smt::TermPool,
to_func: impl Clone + Fn(Self::FuncDecl) -> Option<smt::UserFunction>,
to_sort: impl Clone + Fn(Self::Sort) -> Option<smt::Sort>,
) -> Option<smt::Term> {
None
}
}
pub trait Solver: Sized {
type Manager: 'static + Manager;
type Result: Into<Option<bool>>;
type Model<'s>: Model<Term = <Self::Manager as Manager>::Term>
where
Self: 's;
fn new(
config: &smt::Config,
logic: Result<Option<&'static dyn Logic>>,
manager: Rc<Self::Manager>,
) -> Result<Self>;
fn logic(&self) -> &dyn Logic;
fn solver(&self) -> &<Self::Manager as Manager>::Solver;
fn config(&self, config: &smt::Config) -> Result<()>;
fn push(&mut self) -> Result<()>;
fn pop(&mut self, n: usize) -> Result<()>;
fn require(&mut self, term: <Self::Manager as Manager>::Term) -> Result<()>;
fn check(&self) -> Result<Self::Result>;
fn model(&self) -> Result<Self::Model<'_>>;
}
pub trait Model: Sized {
type Term;
fn value(&self, term: Self::Term) -> Option<Self::Term>;
}