use std::collections::HashMap;
use std::fmt::Debug;
use std::fmt;
use backends::smtlib2::SMTProc;
#[derive(Clone, Debug)]
pub enum SMTError {
Undefined,
Unsat,
AssertionError(String),
}
#[derive(Clone, Debug)]
pub enum SMTRes {
Sat(String, Option<String>),
Unsat(String, Option<String>),
Error(String, Option<String>),
}
pub type SMTResult<T> = Result<T, SMTError>;
pub trait SMTBackend {
type Idx: Debug + Clone;
type Logic: Logic;
fn set_logic<S: SMTProc>(&mut self, &mut S);
fn new_var<T, P>(&mut self, Option<T>, P) -> Self::Idx
where T: AsRef<str>,
P: Into<<<Self as SMTBackend>::Logic as Logic>::Sorts>;
fn assert<T: Into<<<Self as SMTBackend>::Logic as Logic>::Fns>>(&mut self, T, &[Self::Idx]) -> Self::Idx;
fn check_sat<S: SMTProc>(&mut self, &mut S, bool) -> SMTRes;
fn solve<S: SMTProc>(&mut self, &mut S, bool) -> (SMTResult<HashMap<Self::Idx, u64>>, SMTRes);
}
pub trait Logic: fmt::Display + Clone + Copy {
type Fns: SMTNode + fmt::Display + Debug + Clone;
type Sorts: fmt::Display + Debug + Clone;
fn free_var<T: AsRef<str>>(T, Self::Sorts) -> Self::Fns;
}
pub trait SMTNode: fmt::Display {
fn is_var(&self) -> bool;
fn is_const(&self) -> bool;
fn is_fn(&self) -> bool {
!self.is_var() && !self.is_const()
}
}