Experimental refactoring

This commit is contained in:
Patrick Lühne 2020-07-07 08:15:52 +02:00
parent 742379934f
commit 66b5499005
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
6 changed files with 229 additions and 230 deletions

View File

@ -199,7 +199,7 @@ where
pub fn new(declaration: std::rc::Rc<F::FunctionDeclaration>, arguments: Terms<F>) -> Self pub fn new(declaration: std::rc::Rc<F::FunctionDeclaration>, arguments: Terms<F>) -> Self
{ {
assert_eq!(declaration.arity(), arguments.len(), assert_eq!(declaration.arity(), arguments.len(),
"function has a different number of arguments then declared"); "function has a different number of arguments than declared");
Self Self
{ {
@ -353,7 +353,7 @@ where
pub fn new(declaration: std::rc::Rc<F::PredicateDeclaration>, arguments: Terms<F>) -> Self pub fn new(declaration: std::rc::Rc<F::PredicateDeclaration>, arguments: Terms<F>) -> Self
{ {
assert_eq!(declaration.arity(), arguments.len(), assert_eq!(declaration.arity(), arguments.len(),
"predicate has a different number of arguments then declared"); "predicate has a different number of arguments than declared");
Self Self
{ {

View File

@ -1,7 +1,5 @@
pub trait FunctionDeclaration pub trait FunctionDeclaration
{ {
fn new(name: String, arity: usize) -> Self;
fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result; fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result;
fn arity(&self) -> usize; fn arity(&self) -> usize;
fn matches_signature(&self, other_name: &str, other_arity: usize) -> bool; fn matches_signature(&self, other_name: &str, other_arity: usize) -> bool;
@ -9,15 +7,6 @@ pub trait FunctionDeclaration
impl FunctionDeclaration for crate::FunctionDeclaration impl FunctionDeclaration for crate::FunctionDeclaration
{ {
fn new(name: String, arity: usize) -> Self
{
Self
{
name,
arity,
}
}
fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
{ {
write!(formatter, "{}", self.name) write!(formatter, "{}", self.name)
@ -36,8 +25,6 @@ impl FunctionDeclaration for crate::FunctionDeclaration
pub trait PredicateDeclaration pub trait PredicateDeclaration
{ {
fn new(name: String, arity: usize) -> Self;
fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result; fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result;
fn arity(&self) -> usize; fn arity(&self) -> usize;
fn matches_signature(&self, other_name: &str, other_arity: usize) -> bool; fn matches_signature(&self, other_name: &str, other_arity: usize) -> bool;
@ -45,15 +32,6 @@ pub trait PredicateDeclaration
impl PredicateDeclaration for crate::PredicateDeclaration impl PredicateDeclaration for crate::PredicateDeclaration
{ {
fn new(name: String, arity: usize) -> Self
{
Self
{
name,
arity,
}
}
fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
{ {
write!(formatter, "{}", self.name) write!(formatter, "{}", self.name)
@ -72,22 +50,12 @@ impl PredicateDeclaration for crate::PredicateDeclaration
pub trait VariableDeclaration pub trait VariableDeclaration
{ {
fn new(name: String) -> Self;
fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result; fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result;
fn matches_name(&self, other_name: &str) -> bool; fn matches_name(&self, other_name: &str) -> bool;
} }
impl VariableDeclaration for crate::VariableDeclaration impl VariableDeclaration for crate::VariableDeclaration
{ {
fn new(name: String) -> Self
{
Self
{
name
}
}
fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
{ {
write!(formatter, "{}", self.name) write!(formatter, "{}", self.name)

View File

@ -4,4 +4,161 @@ pub mod terms;
pub mod tokens; pub mod tokens;
pub use error::Error; pub use error::Error;
pub use formulas::formula;
use crate::flavor::{FunctionDeclaration as _, PredicateDeclaration as _, VariableDeclaration as _};
pub trait Parser: Sized
{
type Flavor: crate::flavor::Flavor;
fn new_function_declaration(name: String, arity: usize)
-> <Self::Flavor as crate::flavor::Flavor>::FunctionDeclaration;
fn new_predicate_declaration(name: String, arity: usize)
-> <Self::Flavor as crate::flavor::Flavor>::PredicateDeclaration;
fn new_variable_declaration(name: String)
-> <Self::Flavor as crate::flavor::Flavor>::VariableDeclaration;
fn find_or_create_function_declaration(&self, name: &str, arity: usize)
-> std::rc::Rc<<Self::Flavor as crate::flavor::Flavor>::FunctionDeclaration>;
fn find_or_create_predicate_declaration(&self, name: &str, arity: usize)
-> std::rc::Rc<<Self::Flavor as crate::flavor::Flavor>::PredicateDeclaration>;
fn find_or_create_variable_declaration(
variable_declaration_stack_layer: &crate::VariableDeclarationStackLayer<Self::Flavor>,
variable_name: &str)
-> std::rc::Rc<<Self::Flavor as crate::flavor::Flavor>::VariableDeclaration>
{
match variable_declaration_stack_layer
{
crate::VariableDeclarationStackLayer::Free(free_variable_declarations) =>
{
if let Some(variable_declaration) = free_variable_declarations.borrow().iter()
.find(|x| x.matches_name(variable_name))
{
return std::rc::Rc::clone(&variable_declaration);
}
let variable_declaration = Self::new_variable_declaration(variable_name.to_owned());
let variable_declaration = std::rc::Rc::new(variable_declaration);
free_variable_declarations.borrow_mut()
.push(std::rc::Rc::clone(&variable_declaration));
variable_declaration
},
crate::VariableDeclarationStackLayer::Bound(bound_variable_declarations) =>
{
if let Some(variable_declaration) = bound_variable_declarations
.variable_declarations.iter()
.find(|x| x.matches_name(variable_name))
{
return std::rc::Rc::clone(&variable_declaration);
}
Self::find_or_create_variable_declaration(bound_variable_declarations.parent,
variable_name)
},
}
}
fn parse_formula(&self, input: &str)
-> Result<crate::OpenFormula<Self::Flavor>, crate::parse::Error>
{
formulas::formula(input, self)
}
}
pub struct DefaultParser
{
function_declarations:
std::cell::RefCell<crate::FunctionDeclarations<<Self as Parser>::Flavor>>,
predicate_declarations:
std::cell::RefCell<crate::PredicateDeclarations<<Self as Parser>::Flavor>>,
}
impl DefaultParser
{
pub fn new() -> Self
{
Self
{
function_declarations: std::cell::RefCell::new(
crate::FunctionDeclarations::<<Self as Parser>::Flavor>::new()),
predicate_declarations: std::cell::RefCell::new(
crate::PredicateDeclarations::<<Self as Parser>::Flavor>::new()),
}
}
}
impl Parser for DefaultParser
{
type Flavor = crate::flavor::DefaultFlavor;
fn new_function_declaration(name: String, arity: usize)
-> <Self::Flavor as crate::flavor::Flavor>::FunctionDeclaration
{
crate::FunctionDeclaration
{
name,
arity,
}
}
fn new_predicate_declaration(name: String, arity: usize)
-> <Self::Flavor as crate::flavor::Flavor>::PredicateDeclaration
{
crate::PredicateDeclaration
{
name,
arity,
}
}
fn new_variable_declaration(name: String)
-> <Self::Flavor as crate::flavor::Flavor>::VariableDeclaration
{
crate::VariableDeclaration
{
name,
}
}
fn find_or_create_function_declaration(&self, name: &str, arity: usize)
-> std::rc::Rc<<Self::Flavor as crate::flavor::Flavor>::FunctionDeclaration>
{
let mut function_declarations = self.function_declarations.borrow_mut();
match function_declarations.iter().find(|x| x.matches_signature(name, arity))
{
Some(declaration) => std::rc::Rc::clone(&declaration),
None =>
{
let declaration = Self::new_function_declaration(name.to_string(), arity);
let declaration = std::rc::Rc::new(declaration);
function_declarations.insert(std::rc::Rc::clone(&declaration));
declaration
},
}
}
fn find_or_create_predicate_declaration(&self, name: &str, arity: usize)
-> std::rc::Rc<<Self::Flavor as crate::flavor::Flavor>::PredicateDeclaration>
{
let mut predicate_declarations = self.predicate_declarations.borrow_mut();
match predicate_declarations.iter().find(|x| x.matches_signature(name, arity))
{
Some(declaration) => std::rc::Rc::clone(&declaration),
None =>
{
let declaration = Self::new_predicate_declaration(name.to_string(), arity);
let declaration = std::rc::Rc::new(declaration);
predicate_declarations.insert(std::rc::Rc::clone(&declaration));
declaration
},
}
}
}

View File

@ -1,15 +1,14 @@
use super::terms::*; use super::terms::*;
use super::tokens::*; use super::tokens::*;
pub fn formula<D, F>(input: &str, declarations: &D) pub fn formula<P>(input: &str, parser: &P)
-> Result<crate::OpenFormula<F>, crate::parse::Error> -> Result<crate::OpenFormula<P::Flavor>, crate::parse::Error>
where where
F: crate::flavor::Flavor, P: super::Parser,
D: crate::FindOrCreateFunctionDeclaration<F> + crate::FindOrCreatePredicateDeclaration<F>,
{ {
let variable_declaration_stack = crate::VariableDeclarationStackLayer::free(); let variable_declaration_stack = crate::VariableDeclarationStackLayer::free();
let formula_str = FormulaStr::new(input, declarations, &variable_declaration_stack); let formula_str = FormulaStr::new(input, parser, &variable_declaration_stack);
let formula = formula_str.parse(0)?; let formula = formula_str.parse(0)?;
let free_variable_declarations = match variable_declaration_stack let free_variable_declarations = match variable_declaration_stack
@ -71,28 +70,27 @@ impl std::fmt::Debug for LogicalConnective
} }
} }
struct FormulaStr<'i, 'd, 'p, 'v, F, D> struct FormulaStr<'i, 'd, 'p, 'v, P>
where where
F: crate::flavor::Flavor, P: super::Parser,
{ {
input: &'i str, input: &'i str,
declarations: &'d D, parser: &'d P,
variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, F>, variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, P::Flavor>,
} }
impl<'i, 'd, 'p, 'v, F, D> FormulaStr<'i, 'd, 'p, 'v, F, D> impl<'i, 'd, 'p, 'v, P> FormulaStr<'i, 'd, 'p, 'v, P>
where where
F: crate::flavor::Flavor, P: super::Parser,
D: crate::FindOrCreateFunctionDeclaration<F> + crate::FindOrCreatePredicateDeclaration<F>,
{ {
pub fn new(input: &'i str, declarations: &'d D, pub fn new(input: &'i str, parser: &'d P,
variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, F>) variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, P::Flavor>)
-> Self -> Self
{ {
Self Self
{ {
input, input,
declarations, parser,
variable_declaration_stack, variable_declaration_stack,
} }
} }
@ -194,7 +192,7 @@ where
Tokens::new_filter_map(self.input, functor) Tokens::new_filter_map(self.input, functor)
} }
pub fn parse(&self, level: usize) -> Result<crate::Formula<F>, crate::parse::Error> pub fn parse(&self, level: usize) -> Result<crate::Formula<P::Flavor>, crate::parse::Error>
{ {
let indentation = " ".repeat(level); let indentation = " ".repeat(level);
let input = trim_start(self.input); let input = trim_start(self.input);
@ -221,7 +219,7 @@ where
{ {
// TODO: improve error handling if the formulas between the operators are invalid // TODO: improve error handling if the formulas between the operators are invalid
self.split_at_logical_connective(top_level_logical_connective) self.split_at_logical_connective(top_level_logical_connective)
.map(|argument| FormulaStr::new(argument?, self.declarations, self.variable_declaration_stack).parse(level + 1)) .map(|argument| FormulaStr::new(argument?, self.parser, self.variable_declaration_stack).parse(level + 1))
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()
}; };
@ -242,12 +240,12 @@ where
crate::parse::Error::new_expected_logical_connective_argument( crate::parse::Error::new_expected_logical_connective_argument(
"right-to-left implication".to_string(), "right-to-left implication".to_string(),
crate::parse::error::Location::new(0, Some(0))))?; crate::parse::error::Location::new(0, Some(0))))?;
let first_argument = FormulaStr::new(first_argument?, self.declarations, self.variable_declaration_stack).parse(level + 1)?; let first_argument = FormulaStr::new(first_argument?, self.parser, self.variable_declaration_stack).parse(level + 1)?;
return argument_iterator.try_fold(first_argument, return argument_iterator.try_fold(first_argument,
|accumulator, argument| |accumulator, argument|
{ {
let argument = FormulaStr::new(argument?, self.declarations, self.variable_declaration_stack).parse(level + 1)?; let argument = FormulaStr::new(argument?, self.parser, self.variable_declaration_stack).parse(level + 1)?;
Ok(crate::Formula::implies(crate::ImplicationDirection::RightToLeft, Ok(crate::Formula::implies(crate::ImplicationDirection::RightToLeft,
Box::new(argument), Box::new(accumulator))) Box::new(argument), Box::new(accumulator)))
@ -266,7 +264,7 @@ where
let input = trim_start(input); let input = trim_start(input);
log::trace!("{} parsing “not” formula body: {}", indentation, input); log::trace!("{} parsing “not” formula body: {}", indentation, input);
let argument = FormulaStr::new(input, self.declarations, self.variable_declaration_stack).parse(level + 1)?; let argument = FormulaStr::new(input, self.parser, self.variable_declaration_stack).parse(level + 1)?;
return Ok(crate::Formula::not(Box::new(argument))); return Ok(crate::Formula::not(Box::new(argument)));
}, },
@ -337,10 +335,10 @@ where
assert!(comparison_operator_split.next().is_none()); assert!(comparison_operator_split.next().is_none());
let argument_left = let argument_left =
TermStr::new(input_left, self.declarations, self.variable_declaration_stack) TermStr::new(input_left, self.parser, self.variable_declaration_stack)
.parse(level + 1)?; .parse(level + 1)?;
let argument_right = let argument_right =
TermStr::new(input_right, self.declarations, self.variable_declaration_stack) TermStr::new(input_right, self.parser, self.variable_declaration_stack)
.parse(level + 1)?; .parse(level + 1)?;
return Ok(crate::Formula::compare(comparison_operator, Box::new(argument_left), return Ok(crate::Formula::compare(comparison_operator, Box::new(argument_left),
@ -361,7 +359,7 @@ where
{ {
let functor = |token: &_| *token == Token::Symbol(Symbol::Comma); let functor = |token: &_| *token == Token::Symbol(Symbol::Comma);
let arguments = Tokens::new_filter(parenthesized_expression, functor).split() let arguments = Tokens::new_filter(parenthesized_expression, functor).split()
.map(|argument| TermStr::new(argument?, self.declarations, .map(|argument| TermStr::new(argument?, self.parser,
self.variable_declaration_stack) self.variable_declaration_stack)
.parse(level + 1)) .parse(level + 1))
.collect::<Result<_, _>>()?; .collect::<Result<_, _>>()?;
@ -377,7 +375,7 @@ where
crate::parse::error::Location::new(0, Some(0)))) crate::parse::error::Location::new(0, Some(0))))
} }
let declaration = self.declarations.find_or_create_predicate_declaration(predicate_name, let declaration = self.parser.find_or_create_predicate_declaration(predicate_name,
arguments.len()); arguments.len());
return Ok(crate::Formula::predicate(declaration, arguments)); return Ok(crate::Formula::predicate(declaration, arguments));
} }
@ -391,7 +389,7 @@ where
crate::parse::error::Location::new(0, Some(0)))); crate::parse::error::Location::new(0, Some(0))));
} }
return FormulaStr::new(parenthesized_expression, self.declarations, self.variable_declaration_stack).parse(level + 1); return FormulaStr::new(parenthesized_expression, self.parser, self.variable_declaration_stack).parse(level + 1);
} }
Err(crate::parse::Error::new_unexpected_token( Err(crate::parse::Error::new_unexpected_token(
@ -400,7 +398,7 @@ where
// TODO: refactor // TODO: refactor
fn implication_left_to_right_inner<T>(&self, mut argument_iterator: T, level: usize) fn implication_left_to_right_inner<T>(&self, mut argument_iterator: T, level: usize)
-> Result<Option<crate::Formula<F>>, crate::parse::Error> -> Result<Option<crate::Formula<P::Flavor>>, crate::parse::Error>
where where
T: std::iter::Iterator<Item = Result<&'i str, crate::parse::Error>> T: std::iter::Iterator<Item = Result<&'i str, crate::parse::Error>>
{ {
@ -409,7 +407,7 @@ where
Some(argument) => Some(argument) =>
{ {
// TODO: improve error handling if antecedent cannot be parsed // TODO: improve error handling if antecedent cannot be parsed
let argument = FormulaStr::new(argument?, self.declarations, self.variable_declaration_stack).parse(level)?; let argument = FormulaStr::new(argument?, self.parser, self.variable_declaration_stack).parse(level)?;
match self.implication_left_to_right_inner(argument_iterator, level)? match self.implication_left_to_right_inner(argument_iterator, level)?
{ {
Some(next_argument) => Ok(Some(crate::Formula::implies( Some(next_argument) => Ok(Some(crate::Formula::implies(
@ -423,7 +421,7 @@ where
} }
fn implication_left_to_right<T>(&self, mut argument_iterator: T, level: usize) fn implication_left_to_right<T>(&self, mut argument_iterator: T, level: usize)
-> Result<crate::Formula<F>, crate::parse::Error> -> Result<crate::Formula<P::Flavor>, crate::parse::Error>
where where
T: std::iter::Iterator<Item = Result<&'i str, crate::parse::Error>> T: std::iter::Iterator<Item = Result<&'i str, crate::parse::Error>>
{ {
@ -432,7 +430,7 @@ where
Some(argument) => Some(argument) =>
{ {
// TODO: improve error handling if antecedent cannot be parsed // TODO: improve error handling if antecedent cannot be parsed
let argument = FormulaStr::new(argument?, self.declarations, self.variable_declaration_stack).parse(level)?; let argument = FormulaStr::new(argument?, self.parser, self.variable_declaration_stack).parse(level)?;
match self.implication_left_to_right_inner(argument_iterator, level)? match self.implication_left_to_right_inner(argument_iterator, level)?
{ {
Some(next_argument) => Ok(crate::Formula::implies( Some(next_argument) => Ok(crate::Formula::implies(
@ -451,9 +449,9 @@ where
// TODO: refactor without input argument // TODO: refactor without input argument
fn quantified_formula(&self, input: &str, quantifier: Quantifier, level: usize) fn quantified_formula(&self, input: &str, quantifier: Quantifier, level: usize)
-> Result<crate::Formula<F>, crate::parse::Error> -> Result<crate::Formula<P::Flavor>, crate::parse::Error>
{ {
let (parameters, input) = match variable_declarations::<F>(input)? let (parameters, input) = match variable_declarations::<P>(input)?
{ {
Some(variable_declarations) => variable_declarations, Some(variable_declarations) => variable_declarations,
None => return Err(crate::parse::Error::new_expected_variable_declaration( None => return Err(crate::parse::Error::new_expected_variable_declaration(
@ -465,7 +463,7 @@ where
self.variable_declaration_stack, std::rc::Rc::clone(&parameters)); self.variable_declaration_stack, std::rc::Rc::clone(&parameters));
let formula_str = let formula_str =
FormulaStr::new(input.trim(), self.declarations, &variable_declaration_stack); FormulaStr::new(input.trim(), self.parser, &variable_declaration_stack);
let formula = Box::new(formula_str.parse(level)?); let formula = Box::new(formula_str.parse(level)?);
let formula = match quantifier let formula = match quantifier
@ -505,11 +503,10 @@ mod tests
#[test] #[test]
fn tokenize_formula_logical_connectives() fn tokenize_formula_logical_connectives()
{ {
let declarations = crate::Declarations::<crate::flavor::DefaultFlavor>::new(); let parser = crate::parse::DefaultParser::new();
let variable_declaration_stack = crate::VariableDeclarationStackLayer::free(); let variable_declaration_stack = crate::VariableDeclarationStackLayer::free();
let formula_str = |input| FormulaStr::new(input, &declarations, let formula_str = |input| FormulaStr::new(input, &parser, &variable_declaration_stack);
&variable_declaration_stack);
let f = formula_str("((forall X exists Y (p(X) -> q(Y)) and false) or p) -> false"); let f = formula_str("((forall X exists Y (p(X) -> q(Y)) and false) or p) -> false");
assert_eq!(f.top_level_logical_connective().unwrap(), assert_eq!(f.top_level_logical_connective().unwrap(),

View File

@ -1,4 +1,3 @@
use crate::flavor::VariableDeclaration as _;
use super::tokens::*; use super::tokens::*;
pub(crate) fn function_name(input: &str) -> Option<(&str, &str)> pub(crate) fn function_name(input: &str) -> Option<(&str, &str)>
@ -83,23 +82,25 @@ fn is_variable_name(identifier: &str) -> bool
false false
} }
pub(crate) fn variable_declaration<F>(input: &str) -> Option<(F::VariableDeclaration, &str)> pub(crate) fn variable_declaration<P>(input: &str)
-> Option<(<P::Flavor as crate::flavor::Flavor>::VariableDeclaration, &str)>
where where
F: crate::flavor::Flavor, P: crate::parse::Parser,
{ {
variable_name(input) variable_name(input)
.map(|(variable_name, remaining_input)| .map(|(variable_name, remaining_input)|
(F::VariableDeclaration::new(variable_name.to_string()), remaining_input)) (<P as crate::parse::Parser>::new_variable_declaration(variable_name.to_string()),
remaining_input))
} }
pub(crate) fn variable_declarations<F>(input: &str) pub(crate) fn variable_declarations<P>(input: &str)
-> Result<Option<(crate::VariableDeclarations<F>, &str)>, crate::parse::Error> -> Result<Option<(crate::VariableDeclarations<P::Flavor>, &str)>, crate::parse::Error>
where where
F: crate::flavor::Flavor, P: crate::parse::Parser,
{ {
let mut variable_declarations = vec![]; let mut variable_declarations = vec![];
let (first_variable_declaration, mut input) = match variable_declaration::<F>(input) let (first_variable_declaration, mut input) = match variable_declaration::<P>(input)
{ {
Some(first_variable_declaration) => first_variable_declaration, Some(first_variable_declaration) => first_variable_declaration,
None => return Ok(None), None => return Ok(None),
@ -120,7 +121,7 @@ where
input = trim_start(input); input = trim_start(input);
let (variable_declaration, remaining_input) = match variable_declaration::<F>(input) let (variable_declaration, remaining_input) = match variable_declaration::<P>(input)
{ {
Some(variable_declaration) => variable_declaration, Some(variable_declaration) => variable_declaration,
None => return Err(crate::parse::Error::new_expected_variable_declaration( None => return Err(crate::parse::Error::new_expected_variable_declaration(
@ -167,28 +168,27 @@ impl std::fmt::Debug for ArithmeticOperatorClass
} }
} }
pub(crate) struct TermStr<'i, 'd, 'v, 'p, F, D> pub(crate) struct TermStr<'i, 'd, 'v, 'p, P>
where where
F: crate::flavor::Flavor, P: super::Parser,
{ {
input: &'i str, input: &'i str,
declarations: &'d D, parser: &'d P,
variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, F>, variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, P::Flavor>,
} }
impl<'i, 'd, 'v, 'p, F, D> TermStr<'i, 'd, 'v, 'p, F, D> impl<'i, 'd, 'v, 'p, P> TermStr<'i, 'd, 'v, 'p, P>
where where
F: crate::flavor::Flavor, P: super::Parser,
D: crate::FindOrCreateFunctionDeclaration<F> + crate::FindOrCreatePredicateDeclaration<F>,
{ {
pub fn new(input: &'i str, declarations: &'d D, pub fn new(input: &'i str, parser: &'d P,
variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, F>) variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, P::Flavor>)
-> Self -> Self
{ {
Self Self
{ {
input, input,
declarations, parser,
variable_declaration_stack, variable_declaration_stack,
} }
} }
@ -307,7 +307,7 @@ where
Ok(top_level_arithmetic_operator_class) Ok(top_level_arithmetic_operator_class)
} }
pub fn parse(&self, level: usize) -> Result<crate::Term<F>, crate::parse::Error> pub fn parse(&self, level: usize) -> Result<crate::Term<P::Flavor>, crate::parse::Error>
{ {
let indentation = " ".repeat(level); let indentation = " ".repeat(level);
log::trace!("{}- parsing term: {}", indentation, self.input); log::trace!("{}- parsing term: {}", indentation, self.input);
@ -347,7 +347,7 @@ where
crate::parse::Error::new_expected_term( crate::parse::Error::new_expected_term(
crate::parse::error::Location::new(0, Some(0))))??; crate::parse::error::Location::new(0, Some(0))))??;
let first_argument = let first_argument =
TermStr::new(first_argument, self.declarations, self.variable_declaration_stack) TermStr::new(first_argument, self.parser, self.variable_declaration_stack)
.parse(level + 1)?; .parse(level + 1)?;
// TODO: improve error handling if the terms between the operators are invalid // TODO: improve error handling if the terms between the operators are invalid
@ -356,7 +356,7 @@ where
|(accumulator, binary_operator), argument| |(accumulator, binary_operator), argument|
{ {
let (argument, next_binary_operator) = argument?; let (argument, next_binary_operator) = argument?;
let argument = TermStr::new(argument, self.declarations, let argument = TermStr::new(argument, self.parser,
self.variable_declaration_stack) self.variable_declaration_stack)
.parse(level + 1)?; .parse(level + 1)?;
let binary_operation = let binary_operation =
@ -370,7 +370,7 @@ where
// The last item hasnt been consumed yet, so its safe to unwrap it // The last item hasnt been consumed yet, so its safe to unwrap it
let last_argument = argument_iterator.remaining_input().unwrap(); let last_argument = argument_iterator.remaining_input().unwrap();
let last_argument = let last_argument =
TermStr::new(last_argument, self.declarations, self.variable_declaration_stack) TermStr::new(last_argument, self.parser, self.variable_declaration_stack)
.parse(level + 1)?; .parse(level + 1)?;
let last_binary_operation = let last_binary_operation =
crate::BinaryOperation::new(last_binary_operator, Box::new(accumulator), crate::BinaryOperation::new(last_binary_operator, Box::new(accumulator),
@ -442,7 +442,8 @@ where
crate::parse::error::Location::new(0, Some(0)))) crate::parse::error::Location::new(0, Some(0))))
} }
let declaration = self.variable_declaration_stack.find_or_create(identifier); let declaration = P::find_or_create_variable_declaration(
self.variable_declaration_stack, identifier);
return Ok(crate::Term::variable(declaration)); return Ok(crate::Term::variable(declaration));
}, },
_ if is_function_name(identifier) => _ if is_function_name(identifier) =>
@ -459,7 +460,7 @@ where
{ {
let functor = |token: &_| *token == Token::Symbol(Symbol::Comma); let functor = |token: &_| *token == Token::Symbol(Symbol::Comma);
let arguments = Tokens::new_filter(parenthesized_expression, functor).split() let arguments = Tokens::new_filter(parenthesized_expression, functor).split()
.map(|argument| TermStr::new(argument?, self.declarations, .map(|argument| TermStr::new(argument?, self.parser,
self.variable_declaration_stack) self.variable_declaration_stack)
.parse(level + 1)) .parse(level + 1))
.collect::<Result<_, _>>()?; .collect::<Result<_, _>>()?;
@ -475,7 +476,7 @@ where
crate::parse::error::Location::new(0, Some(0)))) crate::parse::error::Location::new(0, Some(0))))
} }
let declaration = self.declarations.find_or_create_function_declaration( let declaration = self.parser.find_or_create_function_declaration(
function_name, arguments.len()); function_name, arguments.len());
return Ok(crate::Term::function(declaration, arguments)); return Ok(crate::Term::function(declaration, arguments));
}, },
@ -494,7 +495,7 @@ where
crate::parse::error::Location::new(0, Some(0)))); crate::parse::error::Location::new(0, Some(0))));
} }
return TermStr::new(parenthesized_expression, self.declarations, return TermStr::new(parenthesized_expression, self.parser,
self.variable_declaration_stack) self.variable_declaration_stack)
.parse(level + 1); .parse(level + 1);
} }
@ -505,7 +506,7 @@ where
// TODO: refactor // TODO: refactor
fn exponentiate_inner<T>(&self, mut argument_iterator: T, level: usize) fn exponentiate_inner<T>(&self, mut argument_iterator: T, level: usize)
-> Result<Option<crate::Term<F>>, crate::parse::Error> -> Result<Option<crate::Term<P::Flavor>>, crate::parse::Error>
where where
T: std::iter::Iterator<Item = Result<&'i str, crate::parse::Error>> T: std::iter::Iterator<Item = Result<&'i str, crate::parse::Error>>
{ {
@ -515,7 +516,7 @@ where
{ {
// TODO: improve error handling if antecedent cannot be parsed // TODO: improve error handling if antecedent cannot be parsed
let argument = let argument =
TermStr::new(argument?, self.declarations, self.variable_declaration_stack) TermStr::new(argument?, self.parser, self.variable_declaration_stack)
.parse(level)?; .parse(level)?;
match self.exponentiate_inner(argument_iterator, level)? match self.exponentiate_inner(argument_iterator, level)?
{ {
@ -529,7 +530,7 @@ where
} }
fn exponentiate<T>(&self, mut argument_iterator: T, level: usize) fn exponentiate<T>(&self, mut argument_iterator: T, level: usize)
-> Result<crate::Term<F>, crate::parse::Error> -> Result<crate::Term<P::Flavor>, crate::parse::Error>
where where
T: std::iter::Iterator<Item = Result<&'i str, crate::parse::Error>> T: std::iter::Iterator<Item = Result<&'i str, crate::parse::Error>>
{ {
@ -539,7 +540,7 @@ where
{ {
// TODO: improve error handling if antecedent cannot be parsed // TODO: improve error handling if antecedent cannot be parsed
let argument = let argument =
TermStr::new(argument?, self.declarations, self.variable_declaration_stack) TermStr::new(argument?, self.parser, self.variable_declaration_stack)
.parse(level)?; .parse(level)?;
match self.exponentiate_inner(argument_iterator, level)? match self.exponentiate_inner(argument_iterator, level)?
{ {
@ -581,7 +582,7 @@ mod tests
fn parse_variable_declaration() fn parse_variable_declaration()
{ {
let variable_declaration = let variable_declaration =
|x| super::variable_declaration::<crate::flavor::DefaultFlavor>(x); |x| super::variable_declaration::<crate::parse::DefaultParser>(x);
let v = variable_declaration("X").unwrap(); let v = variable_declaration("X").unwrap();
assert_eq!((v.0.name.as_str(), v.1), ("X", "")); assert_eq!((v.0.name.as_str(), v.1), ("X", ""));
@ -613,7 +614,7 @@ mod tests
fn parse_variable_declarations() fn parse_variable_declarations()
{ {
let variable_declarations = let variable_declarations =
|x| super::variable_declarations::<crate::flavor::DefaultFlavor>(x); |x| super::variable_declarations::<crate::parse::DefaultParser>(x);
let v = variable_declarations("X.").unwrap().unwrap(); let v = variable_declarations("X.").unwrap().unwrap();
assert_eq!(v.0.len(), 1); assert_eq!(v.0.len(), 1);

View File

@ -1,28 +1,11 @@
use crate::flavor::{FunctionDeclaration as _, PredicateDeclaration as _, VariableDeclaration as _}; use crate::flavor::VariableDeclaration as _;
// Group with implementations
pub trait FindOrCreateFunctionDeclaration<F>
where
F: crate::flavor::Flavor,
{
fn find_or_create_function_declaration(&self, name: &str, arity: usize)
-> std::rc::Rc<F::FunctionDeclaration>;
}
pub trait FindOrCreatePredicateDeclaration<F>
where
F: crate::flavor::Flavor,
{
fn find_or_create_predicate_declaration(&self, name: &str, arity: usize)
-> std::rc::Rc<F::PredicateDeclaration>;
}
pub struct BoundVariableDeclarations<'p, F> pub struct BoundVariableDeclarations<'p, F>
where where
F: crate::flavor::Flavor, F: crate::flavor::Flavor,
{ {
parent: &'p VariableDeclarationStackLayer<'p, F>, pub parent: &'p VariableDeclarationStackLayer<'p, F>,
variable_declarations: std::rc::Rc<crate::VariableDeclarations<F>>, pub variable_declarations: std::rc::Rc<crate::VariableDeclarations<F>>,
} }
impl<'p, F> BoundVariableDeclarations<'p, F> impl<'p, F> BoundVariableDeclarations<'p, F>
@ -91,40 +74,6 @@ where
} }
} }
pub fn find_or_create(&self, variable_name: &str) -> std::rc::Rc<F::VariableDeclaration>
{
match self
{
VariableDeclarationStackLayer::Free(free_variable_declarations) =>
{
if let Some(variable_declaration) = free_variable_declarations.borrow().iter()
.find(|x| x.matches_name(variable_name))
{
return std::rc::Rc::clone(&variable_declaration);
}
let variable_declaration = F::VariableDeclaration::new(variable_name.to_owned());
let variable_declaration = std::rc::Rc::new(variable_declaration);
free_variable_declarations.borrow_mut()
.push(std::rc::Rc::clone(&variable_declaration));
variable_declaration
},
VariableDeclarationStackLayer::Bound(bound_variable_declarations) =>
{
if let Some(variable_declaration) = bound_variable_declarations
.variable_declarations.iter()
.find(|x| x.matches_name(variable_name))
{
return std::rc::Rc::clone(&variable_declaration);
}
bound_variable_declarations.parent.find_or_create(variable_name)
},
}
}
pub fn free_variable_declarations_do_mut<F1, F2>(&self, f: F1) -> F2 pub fn free_variable_declarations_do_mut<F1, F2>(&self, f: F1) -> F2
where where
F1: Fn(&mut crate::VariableDeclarations<F>) -> F2, F1: Fn(&mut crate::VariableDeclarations<F>) -> F2,
@ -151,76 +100,3 @@ where
} }
} }
} }
pub struct Declarations<F>
where
F: crate::flavor::Flavor,
{
function_declarations: std::cell::RefCell<crate::FunctionDeclarations<F>>,
predicate_declarations: std::cell::RefCell<crate::PredicateDeclarations<F>>,
}
impl<F> Declarations<F>
where
F: crate::flavor::Flavor,
{
pub fn new() -> Self
{
Self
{
function_declarations: std::cell::RefCell::new(crate::FunctionDeclarations::<F>::new()),
predicate_declarations:
std::cell::RefCell::new(crate::PredicateDeclarations::<F>::new()),
}
}
}
impl<F> FindOrCreateFunctionDeclaration<F> for Declarations<F>
where
F: crate::flavor::Flavor,
{
fn find_or_create_function_declaration(&self, name: &str, arity: usize)
-> std::rc::Rc<F::FunctionDeclaration>
{
let mut function_declarations = self.function_declarations.borrow_mut();
match function_declarations.iter().find(|x| x.matches_signature(name, arity))
{
Some(declaration) => std::rc::Rc::clone(&declaration),
None =>
{
let declaration = F::FunctionDeclaration::new(name.to_string(), arity);
let declaration = std::rc::Rc::new(declaration);
function_declarations.insert(std::rc::Rc::clone(&declaration));
declaration
},
}
}
}
impl<F> FindOrCreatePredicateDeclaration<F> for Declarations<F>
where
F: crate::flavor::Flavor,
{
fn find_or_create_predicate_declaration(&self, name: &str, arity: usize)
-> std::rc::Rc<F::PredicateDeclaration>
{
let mut predicate_declarations = self.predicate_declarations.borrow_mut();
match predicate_declarations.iter().find(|x| x.matches_signature(name, arity))
{
Some(declaration) => std::rc::Rc::clone(&declaration),
None =>
{
let declaration = F::PredicateDeclaration::new(name.to_string(), arity);
let declaration = std::rc::Rc::new(declaration);
predicate_declarations.insert(std::rc::Rc::clone(&declaration));
declaration
},
}
}
}