use crate::prelude::*;
use std::io::{BufRead, BufReader, Read};
use std::process::ChildStdout;
#[allow(unused_imports)]
use crate::Solver;
pub type RSmtParser = SmtParser<BufReader<ChildStdout>>;
macro_rules! try_apply {
($e:expr => |$res:pat| $do:expr, $msg:expr) => {
match $e {
Ok($res) => $do,
Err(e) => bail!("{}: {}", $msg, e),
}
};
}
pub struct SmtParser<R> {
input: R,
buff: String,
buff_2: String,
cursor: usize,
}
impl<R: Read> Read for SmtParser<R> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
self.input.read(buf)
}
}
impl<'a> SmtParser<BufReader<&'a [u8]>> {
pub fn of_str(s: &'a str) -> Self {
SmtParser::new(BufReader::new(s.as_bytes()))
}
}
impl<R: BufRead> SmtParser<R> {
pub fn new(input: R) -> Self {
SmtParser {
input,
buff: String::with_capacity(5_000),
buff_2: String::with_capacity(5_000),
cursor: 0,
}
}
pub fn swap(&mut self, nu_input: &mut R) {
::std::mem::swap(&mut self.input, nu_input)
}
pub fn buff(&self) -> &str {
&self.buff
}
pub fn buff_rest(&self) -> &str {
&self.buff[self.cursor..]
}
pub fn cursor(&self) -> usize {
self.cursor
}
fn read_line(&mut self) -> SmtRes<bool> {
let read = self.input.read_line(&mut self.buff)?;
Ok(read != 0)
}
pub fn get_sexpr(&mut self) -> SmtRes<&str> {
let sexpr_end = self.load_sexpr()?;
let sexpr_start = self.cursor;
self.cursor = sexpr_end;
Ok(&self.buff[sexpr_start..sexpr_end])
}
fn try_load_sexpr(&mut self) -> SmtRes<Option<usize>> {
self.spc_cmt();
let (mut op_paren, mut cl_paren) = (0, 0);
let mut quoted_ident = false;
let mut sexpr_start = self.cursor;
let mut sexpr_end = sexpr_start;
let mut nempty = false;
'load: loop {
if sexpr_start == self.buff.len() {
let eoi = !self.read_line()?;
if eoi {
if nempty && !quoted_ident && op_paren == cl_paren {
break 'load;
} else {
return Ok(None);
}
}
}
debug_assert!(op_paren >= cl_paren);
let mut chars = self.buff[sexpr_start..].chars();
'chars: while let Some(c) = chars.next() {
debug_assert!(op_paren >= cl_paren);
sexpr_end += 1;
if quoted_ident {
quoted_ident = c != '|';
if !quoted_ident && op_paren == 0 {
break 'load;
} else {
continue 'chars;
}
}
match c {
';' => {
if nempty && op_paren == cl_paren {
sexpr_end -= 1;
break 'load;
}
nempty = true;
if !quoted_ident {
while let Some(c) = chars.next() {
sexpr_end += 1;
if c == '\n' {
continue 'chars;
}
}
}
}
'|' => {
if !quoted_ident && nempty && op_paren == cl_paren {
sexpr_end -= 1;
break 'load;
}
nempty = true;
quoted_ident = !quoted_ident;
if !quoted_ident && op_paren == 0 {
break 'load;
}
}
'(' => {
if nempty && op_paren == cl_paren {
sexpr_end -= 1;
break 'load;
}
nempty = true;
op_paren += 1
}
')' => {
if op_paren == cl_paren && nempty {
sexpr_end -= 1;
break 'load;
} else {
cl_paren += 1;
if op_paren == cl_paren {
break 'load;
}
}
}
_ => {
if c.is_whitespace() && op_paren == 0 && nempty == true {
sexpr_end -= 1;
break 'load;
} else if !c.is_whitespace() {
nempty = true
}
}
}
}
if sexpr_start == self.buff.len() {
break 'load;
}
sexpr_start = self.buff.len()
}
self.spc_cmt();
Ok(Some(sexpr_end))
}
fn load_sexpr(&mut self) -> SmtRes<usize> {
if let Some(end) = self.try_load_sexpr()? {
Ok(end)
} else {
bail!("reached eoi")
}
}
pub fn clear(&mut self) {
self.spc_cmt();
if !self.cursor >= self.buff.len() {
debug_assert!(self.buff_2.is_empty());
self.buff_2.push_str(&self.buff[self.cursor..]);
self.buff.clear();
::std::mem::swap(&mut self.buff, &mut self.buff_2);
self.cursor = 0
} else {
self.buff.clear();
self.cursor = 0
}
}
pub fn print(&self, pref: &str) {
let mut count = 0;
let mut printed_cursor = false;
for line in self.buff.lines() {
println!("{}|`{}`", pref, line);
if !printed_cursor {
let nu_count = count + line.len() + 1;
if self.cursor <= nu_count {
printed_cursor = true;
println!("{0}| {1: >2$}^", pref, "", self.cursor - count)
}
count = nu_count;
}
}
}
pub fn spc_cmt(&mut self) {
if self.cursor >= self.buff.len() {
return ();
}
let mut chars = self.buff[self.cursor..].chars();
'spc_cmt: while let Some(c) = chars.next() {
if !c.is_whitespace() {
if c == ';' {
self.cursor += 1;
'skip_line: while let Some(c) = chars.next() {
self.cursor += 1;
if c == '\n' || c == '\r' {
break 'skip_line;
}
}
} else {
break 'spc_cmt;
}
} else {
self.cursor += 1;
}
}
}
pub fn try_tag(&mut self, tag: &str) -> SmtRes<bool> {
loop {
self.spc_cmt();
if self.cursor + tag.len() >= self.buff.len() + 1 {
if self.cursor < self.buff.len() {
if self.buff[self.cursor..self.buff.len()]
!= tag[0..self.buff.len() - self.cursor]
{
return Ok(false);
} else {
()
}
}
let eoi = !self.read_line()?;
self.spc_cmt();
if eoi {
return Ok(false);
}
} else if &self.buff[self.cursor..self.cursor + tag.len()] == tag {
self.cursor += tag.len();
return Ok(true);
} else {
self.spc_cmt();
return Ok(false);
}
}
}
pub fn tag(&mut self, tag: &str) -> SmtRes<()> {
if self.try_tag(tag)? {
Ok(())
} else {
self.fail_with(format!("expected `{}`", tag))
}
}
pub fn tag_info(&mut self, tag: &str, err_msg: &str) -> SmtRes<()> {
if self.try_tag(tag)? {
Ok(())
} else {
self.fail_with(format!("expected `{}` {}", tag, err_msg))
}
}
fn pos(&self) -> usize {
self.cursor
}
fn backtrack_to(&mut self, pos: usize) {
self.cursor = pos
}
pub fn try_word(&mut self, word: &str) -> SmtRes<bool> {
let start_pos = self.pos();
if self.try_tag(word)? {
if let Some(c) = self.buff[self.cursor..].chars().next() {
if c.is_whitespace() || c == ')' || c == '(' || c == ';' {
return Ok(true);
}
}
}
self.backtrack_to(start_pos);
self.spc_cmt();
Ok(false)
}
pub fn try_tags<'a, Tags, S>(&mut self, tags: &'a Tags) -> SmtRes<bool>
where
&'a Tags: IntoIterator<Item = S>,
S: AsRef<str>,
{
let start_pos = self.pos();
for tag in tags {
if !self.try_tag(tag.as_ref())? {
self.backtrack_to(start_pos);
self.spc_cmt();
return Ok(false);
}
}
Ok(true)
}
pub fn tags<'a, Tags, S>(&mut self, tags: &'a Tags) -> SmtRes<()>
where
&'a Tags: IntoIterator<Item = S>,
S: AsRef<str>,
{
for tag in tags {
self.tag(tag.as_ref())?
}
Ok(())
}
pub fn fail_with<T, Str: Into<String>>(&mut self, msg: Str) -> SmtRes<T> {
self.try_error()?;
let sexpr = self.get_sexpr().map(str::to_string).ok();
let sexpr = if let Some(e) = sexpr {
e
} else if self.cursor < self.buff.len() {
let mut stuff = self.buff[self.cursor..].trim().split_whitespace();
if let Some(stuff) = stuff.next() {
stuff.to_string()
} else {
" ".to_string()
}
} else {
"eoi".to_string()
};
if sexpr == "unsupported" {
bail!(ErrorKind::Unsupported)
} else {
bail!(ErrorKind::ParseError(msg.into(), sexpr))
}
}
pub fn try_bool(&mut self) -> SmtRes<Option<bool>> {
if self.try_word("true")? {
Ok(Some(true))
} else if self.try_word("false")? {
Ok(Some(false))
} else {
Ok(None)
}
}
pub fn bool(&mut self) -> SmtRes<bool> {
if let Some(b) = self.try_bool()? {
Ok(b)
} else {
self.fail_with("expected boolean")
}
}
#[inline]
fn try_uint_indices(&self) -> SmtRes<Option<(usize, usize)>> {
let mut end = self.cursor;
let (mut zero_first, mut first) = (false, true);
for c in self.buff[self.cursor..].chars() {
if c.is_numeric() {
if first {
first = false;
if c == '0' {
zero_first = true
}
} else if zero_first {
return Ok(None);
}
end += 1
} else {
break;
}
}
if end > self.cursor {
Ok(Some((self.cursor, end)))
} else {
Ok(None)
}
}
#[inline]
fn try_uint(&mut self) -> SmtRes<Option<&str>> {
self.spc_cmt();
if let Some((res_start, res_end)) = self.try_uint_indices()? {
self.cursor = res_end;
Ok(Some(&self.buff[res_start..res_end]))
} else {
Ok(None)
}
}
#[inline]
fn uint<F, T>(&mut self, f: F) -> SmtRes<T>
where
F: Fn(&str) -> T,
{
if let Some(res) = self.try_uint()?.map(f) {
Ok(res)
} else {
self.fail_with("expected unsigned integer")
}
}
pub fn try_int<F, T, Err>(&mut self, f: F) -> SmtRes<Option<T>>
where
F: FnOnce(&str, bool) -> Result<T, Err>,
Err: ::std::fmt::Display,
{
let start_pos = self.pos();
self.load_sexpr()?;
let mut res = None;
if let Some((int_start, int_end)) = self.try_uint_indices()? {
self.cursor = int_end;
if self.try_tag(".")? {
self.backtrack_to(start_pos);
res = None
} else {
self.cursor = int_end;
let uint = &self.buff[int_start..int_end];
try_apply!(
f(uint, true) => |int| res = Some(int),
format!("error parsing integer `{}`", uint)
)
}
} else if self.try_tag("(")? {
let pos = if self.try_tag("-")? {
false
} else if self.try_tag("+")? {
true
} else {
self.backtrack_to(start_pos);
return Ok(None);
};
if let Some(uint) = self.try_uint()? {
match f(uint, pos) {
Ok(int) => res = Some(int),
Err(e) => {
let uint = if !pos {
format!("(- {})", uint)
} else {
uint.into()
};
bail!("error parsing integer `{}`: {}", uint, e)
}
}
}
if !(res.is_some() && self.try_tag(")")?) {
self.backtrack_to(start_pos);
return Ok(None);
}
}
if res.is_none() {
self.backtrack_to(start_pos)
}
Ok(res)
}
pub fn try_rat<F, T, Err>(&mut self, f: F) -> SmtRes<Option<T>>
where
F: Fn(&str, &str, bool) -> Result<T, Err>,
Err: ::std::fmt::Display,
{
let err = "error parsing rational";
let start_pos = self.pos();
self.load_sexpr()?;
let mut res = None;
let positive = if self.try_tags(&["(", "-"])? {
self.spc_cmt();
false
} else {
true
};
if let Some((fst_start, fst_end)) = self.try_uint_indices()? {
if fst_end + 1 < self.buff.len() && &self.buff[fst_end..(fst_end + 2)] == ".0" {
try_apply!(
f(
& self.buff[ fst_start .. fst_end ], "1", positive
) => |okay| res = Some(okay), err
);
self.cursor = fst_end + 2
} else if fst_end < self.buff.len() && &self.buff[fst_end..(fst_end + 1)] == "." {
self.cursor = fst_end + 1;
if let Some((snd_start, snd_end)) = self.try_uint_indices()? {
let num = format!(
"{}{}",
&self.buff[fst_start..fst_end],
&self.buff[snd_start..snd_end],
);
let mut den = String::with_capacity(snd_end - snd_start);
den.push('1');
for _ in snd_start..snd_end {
den.push('0')
}
try_apply!(
f(
& num, & den, positive
) => |okay| res = Some(okay), err
);
self.cursor = snd_end
} else {
bail!("ill-formed rational")
}
} else {
self.backtrack_to(start_pos);
return Ok(None);
}
}
if res.is_none() {
if !self.try_tag("(")? {
self.backtrack_to(start_pos);
return Ok(None);
}
if !self.try_tag("/")? {
self.backtrack_to(start_pos);
return Ok(None);
}
self.spc_cmt();
res = if let Some((num_start, num_end)) = self.try_uint_indices()? {
if num_end + 1 < self.buff.len() && &self.buff[num_end..(num_end + 2)] == ".0" {
self.cursor = num_end + 2
} else {
self.cursor = num_end
}
self.spc_cmt();
if let Some((den_start, den_end)) = self.try_uint_indices()? {
let not_eoi = den_end + 1 < self.buff.len();
let point_zero = &self.buff[den_end..(den_end + 2)] == ".0";
if not_eoi && point_zero {
self.cursor = den_end + 2
} else {
self.cursor = den_end
}
match f(
&self.buff[num_start..num_end],
&self.buff[den_start..den_end],
positive,
) {
Ok(res) => Some(res),
Err(e) => bail!("error parsing rational: {}", e),
}
} else {
None
}
} else {
None
};
if res.is_some() {
self.tag(")")?
}
}
if res.is_some() {
if !positive {
self.tag(")")?
}
Ok(res)
} else {
Ok(None)
}
}
pub fn try_sym<'me, F, T, Err>(&'me mut self, f: F) -> SmtRes<Option<T>>
where
F: FnOnce(&'me str) -> Result<T, Err>,
Err: ::std::fmt::Display,
{
self.spc_cmt();
let err_end = self.load_sexpr()?;
let is_sym = if let Some(c) = self.buff[self.cursor..].chars().next() {
match c {
_ if c.is_alphabetic() => true,
'|' | '~' | '!' | '@' | '$' | '%' | '^' | '&' | '*' | '_' | '-' | '+' | '='
| '<' | '>' | '.' | '?' => true,
_ => false,
}
} else {
false
};
if is_sym {
let ident = &self.buff[self.cursor..err_end];
self.cursor = err_end;
match f(ident) {
Ok(res) => Ok(Some(res)),
Err(e) => bail!(
"error parsing symbol `{}`: {}",
&self.buff[self.cursor..err_end],
e
),
}
} else {
Ok(None)
}
}
pub fn success(&mut self) -> SmtRes<()> {
self.tag("success")
}
pub fn try_error(&mut self) -> SmtRes<()> {
let start_pos = self.pos();
if self.try_load_sexpr()?.is_none() {
return Ok(());
}
if self.try_tag("(")? {
self.spc_cmt();
if self.try_tag("error")? {
self.spc_cmt();
if self.try_tag("\"")? {
let err_start = self.pos();
let mut err_end = err_start;
while err_end < self.buff.len() {
if err_end + 1 < self.buff.len() {
if &self.buff[err_end..err_end + 2] == "\\\"" {
err_end += 2;
continue;
}
}
if &self.buff[err_end..err_end + 1] == "\"" {
break;
} else {
err_end += 1;
continue;
}
}
self.cursor = err_end + 1;
self.spc_cmt();
self.tag(")").chain_err(|| "closing error message")?;
bail!(ErrorKind::SolverError(self.buff[err_start..err_end].into()))
}
}
self.backtrack_to(start_pos)
}
Ok(())
}
pub fn check_sat(&mut self) -> SmtRes<Option<bool>> {
self.spc_cmt();
if self.try_tag("sat")? {
Ok(Some(true))
} else if self.try_tag("unsat")? {
Ok(Some(false))
} else if self.try_tag("unknown")? {
Ok(None)
} else if self.try_tag("timeout")? {
bail!(ErrorKind::Timeout)
} else {
self.try_error()?;
self.fail_with("expected `sat` or `unsat`")
}
}
pub fn try_actlit_id(&mut self) -> SmtRes<bool> {
if self.try_tag(crate::actlit::ACTLIT_PREF)? {
self.uint(|_| ())
.chain_err(|| "while parsing internal actlit identifier")?;
self.tag(crate::actlit::ACTLIT_SUFF)?;
Ok(true)
} else {
Ok(false)
}
}
pub fn get_unsat_core<Sym, Parser>(&mut self, parser: Parser) -> SmtRes<Vec<Sym>>
where
Parser: for<'a> SymParser<Sym, &'a mut Self>,
{
self.spc_cmt();
self.try_error()?;
let mut core = Vec::new();
self.tag("(")?;
self.spc_cmt();
while !self.try_tag(")")? {
core.push(parser.parse_sym(self)?);
self.spc_cmt();
}
self.clear();
Ok(core)
}
pub fn get_model_const<Ident, Value, Type, Parser>(
&mut self,
prune_actlits: bool,
parser: Parser,
) -> SmtRes<Vec<(Ident, Type, Value)>>
where
Parser: for<'a> IdentParser<Ident, Type, &'a mut Self>
+ for<'a> ModelParser<Ident, Type, Value, &'a mut Self>,
{
self.spc_cmt();
self.try_error()?;
let mut model = Vec::new();
self.tag("(")?;
self.try_tag("model")?;
while !self.try_tag(")")? {
self.tag_info("(", "opening define-fun or `)` closing model")?;
self.tag("define-fun")?;
if prune_actlits && self.try_actlit_id()? {
self.tags(&["(", ")"])?;
self.tag("Bool")?;
self.bool()?;
} else {
let id = parser.parse_ident(self)?;
self.tags(&["(", ")"])?;
let typ = parser.parse_type(self)?;
let value = parser.parse_value(self, &id, &[], &typ)?;
model.push((id, typ, value));
}
self.tag(")")?;
}
self.clear();
Ok(model)
}
pub fn get_model<Ident, Value, Type, Parser>(
&mut self,
prune_actlits: bool,
parser: Parser,
) -> SmtRes<Model<Ident, Type, Value>>
where
Parser: for<'a> IdentParser<Ident, Type, &'a mut Self>
+ for<'a> ModelParser<Ident, Type, Value, &'a mut Self>,
{
self.spc_cmt();
self.try_error()?;
let mut model = Vec::new();
self.tag("(")?;
self.try_tag("model")?;
while !self.try_tag(")")? {
self.tag_info("(", "opening define-fun or `)` closing model")?;
self.tag("define-fun")?;
if prune_actlits && self.try_actlit_id()? {
self.tags(&["(", ")"])?;
self.tag("Bool")?;
self.bool()?;
} else {
let id = parser.parse_ident(self)?;
self.tag("(")?;
let mut args = Vec::new();
while self.try_tag("(")? {
self.spc_cmt();
let id = parser.parse_ident(self)?;
self.spc_cmt();
let typ = parser.parse_type(self)?;
self.spc_cmt();
self.tag(")")?;
args.push((id, typ))
}
self.tag(")")?;
self.spc_cmt();
let typ = parser.parse_type(self)?;
self.spc_cmt();
let value = parser.parse_value(self, &id, &args, &typ)?;
model.push((id, args, typ, value));
}
self.tag(")")?;
}
self.clear();
Ok(model)
}
pub fn get_values<Val, Info: Clone, Expr, Parser>(
&mut self,
parser: Parser,
info: Info,
) -> SmtRes<Vec<(Expr, Val)>>
where
Parser:
for<'a> ValueParser<Val, &'a mut Self> + for<'a> ExprParser<Expr, Info, &'a mut Self>,
{
self.spc_cmt();
self.try_error()?;
let mut values = Vec::new();
self.tag("(")?;
while !self.try_tag(")")? {
self.tag_info("(", "opening expr/value pair or `)` closing value list")?;
let expr = parser.parse_expr(self, info.clone())?;
let value = parser.parse_value(self)?;
values.push((expr, value));
self.tag(")")?;
}
self.clear();
Ok(values)
}
pub fn get_interpolant<Expr, Info, Parser>(
&mut self,
parser: Parser,
info: Info,
) -> SmtRes<Expr>
where
Parser: for<'a> ExprParser<Expr, Info, &'a mut Self>,
{
self.spc_cmt();
self.try_error()?;
let expr = parser.parse_expr(self, info)?;
self.clear();
Ok(expr)
}
}
pub trait SymParser<Sym, Input>: Copy {
fn parse_sym(self, i: Input) -> SmtRes<Sym>;
}
impl<'a, Sym, T> SymParser<Sym, &'a str> for T
where
T: SymParser<Sym, &'a [u8]>,
{
fn parse_sym(self, input: &'a str) -> SmtRes<Sym> {
self.parse_sym(input.as_bytes())
}
}
impl<'a, Sym, T, Br> SymParser<Sym, &'a mut SmtParser<Br>> for T
where
T: SymParser<Sym, &'a str>,
Br: BufRead,
{
fn parse_sym(self, input: &'a mut SmtParser<Br>) -> SmtRes<Sym> {
self.parse_sym(input.get_sexpr()?)
}
}
impl<'a, Br> SymParser<&'a str, &'a mut SmtParser<Br>> for ()
where
Br: BufRead,
{
fn parse_sym(self, input: &'a mut SmtParser<Br>) -> SmtRes<&'a str> {
input
.try_sym(|s| SmtRes::Ok(s))
.and_then(|sym_opt| sym_opt.ok_or_else(|| "expected symbol".into()))
}
}
impl<'a, Br> SymParser<String, &'a mut SmtParser<Br>> for ()
where
Br: BufRead,
{
fn parse_sym(self, input: &'a mut SmtParser<Br>) -> SmtRes<String> {
input
.try_sym(|s| SmtRes::Ok(s.into()))
.and_then(|sym_opt| sym_opt.ok_or_else(|| "expected symbol".into()))
}
}
pub trait IdentParser<Ident, Type, Input>: Copy {
fn parse_ident(self, i: Input) -> SmtRes<Ident>;
fn parse_type(self, i: Input) -> SmtRes<Type>;
}
impl<'a, Ident, Type, T> IdentParser<Ident, Type, &'a str> for T
where
T: IdentParser<Ident, Type, &'a [u8]>,
{
fn parse_ident(self, input: &'a str) -> SmtRes<Ident> {
self.parse_ident(input.as_bytes())
}
fn parse_type(self, input: &'a str) -> SmtRes<Type> {
self.parse_type(input.as_bytes())
}
}
impl<'a, Ident, Type, T, Br> IdentParser<Ident, Type, &'a mut SmtParser<Br>> for T
where
T: IdentParser<Ident, Type, &'a str>,
Br: BufRead,
{
fn parse_ident(self, input: &'a mut SmtParser<Br>) -> SmtRes<Ident> {
self.parse_ident(input.get_sexpr()?)
}
fn parse_type(self, input: &'a mut SmtParser<Br>) -> SmtRes<Type> {
self.parse_type(input.get_sexpr()?)
}
}
impl<'a, Br> IdentParser<&'a str, &'a str, &'a mut SmtParser<Br>> for ()
where
Br: BufRead,
{
fn parse_ident(self, input: &'a mut SmtParser<Br>) -> SmtRes<&'a str> {
input.get_sexpr()
}
fn parse_type(self, input: &'a mut SmtParser<Br>) -> SmtRes<&'a str> {
input.get_sexpr()
}
}
impl<'a, Br> IdentParser<String, String, &'a mut SmtParser<Br>> for ()
where
Br: BufRead,
{
fn parse_ident(self, input: &'a mut SmtParser<Br>) -> SmtRes<String> {
input.get_sexpr().map(String::from)
}
fn parse_type(self, input: &'a mut SmtParser<Br>) -> SmtRes<String> {
input.get_sexpr().map(String::from)
}
}
pub trait ModelParser<Ident, Type, Value, Input>: Copy {
fn parse_value(self, i: Input, id: &Ident, args: &[(Ident, Type)], out: &Type)
-> SmtRes<Value>;
}
impl<'a, Ident, Type, Value, T> ModelParser<Ident, Type, Value, &'a str> for T
where
T: ModelParser<Ident, Type, Value, &'a [u8]>,
{
fn parse_value(
self,
input: &'a str,
name: &Ident,
inputs: &[(Ident, Type)],
output: &Type,
) -> SmtRes<Value> {
self.parse_value(input.as_bytes(), name, inputs, output)
}
}
impl<'a, Ident, Type, Value, T, Br> ModelParser<Ident, Type, Value, &'a mut SmtParser<Br>> for T
where
T: ModelParser<Ident, Type, Value, &'a str>,
Br: BufRead,
{
fn parse_value(
self,
input: &'a mut SmtParser<Br>,
name: &Ident,
inputs: &[(Ident, Type)],
output: &Type,
) -> SmtRes<Value> {
self.parse_value(input.get_sexpr()?, name, inputs, output)
}
}
impl<'a, Br> ModelParser<&'a str, &'a str, &'a str, &'a mut SmtParser<Br>> for ()
where
Br: BufRead,
{
fn parse_value(
self,
input: &'a mut SmtParser<Br>,
_name: &&'a str,
_inputs: &[(&'a str, &'a str)],
_output: &&'a str,
) -> SmtRes<&'a str> {
input.get_sexpr()
}
}
impl<'a, Br> ModelParser<String, String, String, &'a mut SmtParser<Br>> for ()
where
Br: BufRead,
{
fn parse_value(
self,
input: &'a mut SmtParser<Br>,
_name: &String,
_inputs: &[(String, String)],
_output: &String,
) -> SmtRes<String> {
input.get_sexpr().map(String::from)
}
}
pub trait ValueParser<Value, Input>: Copy {
fn parse_value(self, i: Input) -> SmtRes<Value>;
}
impl<'a, Value, T> ValueParser<Value, &'a str> for T
where
T: ValueParser<Value, &'a [u8]>,
{
fn parse_value(self, input: &'a str) -> SmtRes<Value> {
self.parse_value(input.as_bytes())
}
}
impl<'a, Value, T, Br> ValueParser<Value, &'a mut SmtParser<Br>> for T
where
T: ValueParser<Value, &'a str>,
Br: BufRead,
{
fn parse_value(self, input: &'a mut SmtParser<Br>) -> SmtRes<Value> {
self.parse_value(input.get_sexpr()?)
}
}
impl<'a, Br> ValueParser<&'a str, &'a mut SmtParser<Br>> for ()
where
Br: BufRead,
{
fn parse_value(self, input: &'a mut SmtParser<Br>) -> SmtRes<&'a str> {
input.get_sexpr()
}
}
impl<'a, Br> ValueParser<String, &'a mut SmtParser<Br>> for ()
where
Br: BufRead,
{
fn parse_value(self, input: &'a mut SmtParser<Br>) -> SmtRes<String> {
input.get_sexpr().map(String::from)
}
}
pub trait ExprParser<Expr, Info, Input>: Copy {
fn parse_expr(self, i: Input, info: Info) -> SmtRes<Expr>;
}
impl<'a, Expr, Info, T> ExprParser<Expr, Info, &'a str> for T
where
T: ExprParser<Expr, Info, &'a [u8]>,
{
fn parse_expr(self, input: &'a str, info: Info) -> SmtRes<Expr> {
self.parse_expr(input.as_bytes(), info)
}
}
impl<'a, Expr, Info, T, Br> ExprParser<Expr, Info, &'a mut SmtParser<Br>> for T
where
T: ExprParser<Expr, Info, &'a str>,
Br: BufRead,
{
fn parse_expr(self, input: &'a mut SmtParser<Br>, info: Info) -> SmtRes<Expr> {
self.parse_expr(input.get_sexpr()?, info)
}
}
impl<'a, Br> ExprParser<&'a str, (), &'a mut SmtParser<Br>> for ()
where
Br: BufRead,
{
fn parse_expr(self, input: &'a mut SmtParser<Br>, _info: ()) -> SmtRes<&'a str> {
input.get_sexpr()
}
}
impl<'a, Br> ExprParser<String, (), &'a mut SmtParser<Br>> for ()
where
Br: BufRead,
{
fn parse_expr(self, input: &'a mut SmtParser<Br>, _info: ()) -> SmtRes<String> {
input.get_sexpr().map(String::from)
}
}
pub trait ProofParser<Proof, Input>: Copy {
fn parse_proof(self, i: Input) -> SmtRes<Proof>;
}
impl<'a, Proof, T> ProofParser<Proof, &'a str> for T
where
T: ProofParser<Proof, &'a [u8]>,
{
fn parse_proof(self, input: &'a str) -> SmtRes<Proof> {
self.parse_proof(input.as_bytes())
}
}
impl<'a, Proof, T, Br> ProofParser<Proof, &'a mut SmtParser<Br>> for T
where
T: ProofParser<Proof, &'a str>,
Br: BufRead,
{
fn parse_proof(self, input: &'a mut SmtParser<Br>) -> SmtRes<Proof> {
self.parse_proof(input.get_sexpr()?)
}
}