Experimental refactoring
This commit is contained in:
parent
742379934f
commit
66b5499005
@ -199,7 +199,7 @@ where
|
||||
pub fn new(declaration: std::rc::Rc<F::FunctionDeclaration>, arguments: Terms<F>) -> Self
|
||||
{
|
||||
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
|
||||
{
|
||||
@ -353,7 +353,7 @@ where
|
||||
pub fn new(declaration: std::rc::Rc<F::PredicateDeclaration>, arguments: Terms<F>) -> Self
|
||||
{
|
||||
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
|
||||
{
|
||||
|
@ -1,7 +1,5 @@
|
||||
pub trait FunctionDeclaration
|
||||
{
|
||||
fn new(name: String, arity: usize) -> Self;
|
||||
|
||||
fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result;
|
||||
fn arity(&self) -> usize;
|
||||
fn matches_signature(&self, other_name: &str, other_arity: usize) -> bool;
|
||||
@ -9,15 +7,6 @@ pub trait 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
|
||||
{
|
||||
write!(formatter, "{}", self.name)
|
||||
@ -36,8 +25,6 @@ impl FunctionDeclaration for crate::FunctionDeclaration
|
||||
|
||||
pub trait PredicateDeclaration
|
||||
{
|
||||
fn new(name: String, arity: usize) -> Self;
|
||||
|
||||
fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result;
|
||||
fn arity(&self) -> usize;
|
||||
fn matches_signature(&self, other_name: &str, other_arity: usize) -> bool;
|
||||
@ -45,15 +32,6 @@ pub trait 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
|
||||
{
|
||||
write!(formatter, "{}", self.name)
|
||||
@ -72,22 +50,12 @@ impl PredicateDeclaration for crate::PredicateDeclaration
|
||||
|
||||
pub trait VariableDeclaration
|
||||
{
|
||||
fn new(name: String) -> Self;
|
||||
|
||||
fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result;
|
||||
fn matches_name(&self, other_name: &str) -> bool;
|
||||
}
|
||||
|
||||
impl VariableDeclaration for crate::VariableDeclaration
|
||||
{
|
||||
fn new(name: String) -> Self
|
||||
{
|
||||
Self
|
||||
{
|
||||
name
|
||||
}
|
||||
}
|
||||
|
||||
fn display_name(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
|
||||
{
|
||||
write!(formatter, "{}", self.name)
|
||||
|
159
src/parse.rs
159
src/parse.rs
@ -4,4 +4,161 @@ pub mod terms;
|
||||
pub mod tokens;
|
||||
|
||||
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
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
use super::terms::*;
|
||||
use super::tokens::*;
|
||||
|
||||
pub fn formula<D, F>(input: &str, declarations: &D)
|
||||
-> Result<crate::OpenFormula<F>, crate::parse::Error>
|
||||
pub fn formula<P>(input: &str, parser: &P)
|
||||
-> Result<crate::OpenFormula<P::Flavor>, crate::parse::Error>
|
||||
where
|
||||
F: crate::flavor::Flavor,
|
||||
D: crate::FindOrCreateFunctionDeclaration<F> + crate::FindOrCreatePredicateDeclaration<F>,
|
||||
P: super::Parser,
|
||||
{
|
||||
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 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
|
||||
F: crate::flavor::Flavor,
|
||||
P: super::Parser,
|
||||
{
|
||||
input: &'i str,
|
||||
declarations: &'d D,
|
||||
variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, F>,
|
||||
parser: &'d P,
|
||||
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
|
||||
F: crate::flavor::Flavor,
|
||||
D: crate::FindOrCreateFunctionDeclaration<F> + crate::FindOrCreatePredicateDeclaration<F>,
|
||||
P: super::Parser,
|
||||
{
|
||||
pub fn new(input: &'i str, declarations: &'d D,
|
||||
variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, F>)
|
||||
pub fn new(input: &'i str, parser: &'d P,
|
||||
variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, P::Flavor>)
|
||||
-> Self
|
||||
{
|
||||
Self
|
||||
{
|
||||
input,
|
||||
declarations,
|
||||
parser,
|
||||
variable_declaration_stack,
|
||||
}
|
||||
}
|
||||
@ -194,7 +192,7 @@ where
|
||||
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 input = trim_start(self.input);
|
||||
@ -221,7 +219,7 @@ where
|
||||
{
|
||||
// TODO: improve error handling if the formulas between the operators are invalid
|
||||
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<_>, _>>()
|
||||
};
|
||||
|
||||
@ -242,12 +240,12 @@ where
|
||||
crate::parse::Error::new_expected_logical_connective_argument(
|
||||
"right-to-left implication".to_string(),
|
||||
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,
|
||||
|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,
|
||||
Box::new(argument), Box::new(accumulator)))
|
||||
@ -266,7 +264,7 @@ where
|
||||
let input = trim_start(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)));
|
||||
},
|
||||
@ -337,10 +335,10 @@ where
|
||||
assert!(comparison_operator_split.next().is_none());
|
||||
|
||||
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)?;
|
||||
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)?;
|
||||
|
||||
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 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)
|
||||
.parse(level + 1))
|
||||
.collect::<Result<_, _>>()?;
|
||||
@ -377,7 +375,7 @@ where
|
||||
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());
|
||||
return Ok(crate::Formula::predicate(declaration, arguments));
|
||||
}
|
||||
@ -391,7 +389,7 @@ where
|
||||
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(
|
||||
@ -400,7 +398,7 @@ where
|
||||
|
||||
// TODO: refactor
|
||||
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
|
||||
T: std::iter::Iterator<Item = Result<&'i str, crate::parse::Error>>
|
||||
{
|
||||
@ -409,7 +407,7 @@ where
|
||||
Some(argument) =>
|
||||
{
|
||||
// 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)?
|
||||
{
|
||||
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)
|
||||
-> Result<crate::Formula<F>, crate::parse::Error>
|
||||
-> Result<crate::Formula<P::Flavor>, crate::parse::Error>
|
||||
where
|
||||
T: std::iter::Iterator<Item = Result<&'i str, crate::parse::Error>>
|
||||
{
|
||||
@ -432,7 +430,7 @@ where
|
||||
Some(argument) =>
|
||||
{
|
||||
// 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)?
|
||||
{
|
||||
Some(next_argument) => Ok(crate::Formula::implies(
|
||||
@ -451,9 +449,9 @@ where
|
||||
|
||||
// TODO: refactor without input argument
|
||||
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,
|
||||
None => return Err(crate::parse::Error::new_expected_variable_declaration(
|
||||
@ -465,7 +463,7 @@ where
|
||||
self.variable_declaration_stack, std::rc::Rc::clone(¶meters));
|
||||
|
||||
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 = match quantifier
|
||||
@ -505,11 +503,10 @@ mod tests
|
||||
#[test]
|
||||
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 formula_str = |input| FormulaStr::new(input, &declarations,
|
||||
&variable_declaration_stack);
|
||||
let formula_str = |input| FormulaStr::new(input, &parser, &variable_declaration_stack);
|
||||
|
||||
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(),
|
||||
|
@ -1,4 +1,3 @@
|
||||
use crate::flavor::VariableDeclaration as _;
|
||||
use super::tokens::*;
|
||||
|
||||
pub(crate) fn function_name(input: &str) -> Option<(&str, &str)>
|
||||
@ -83,23 +82,25 @@ fn is_variable_name(identifier: &str) -> bool
|
||||
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
|
||||
F: crate::flavor::Flavor,
|
||||
P: crate::parse::Parser,
|
||||
{
|
||||
variable_name(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)
|
||||
-> Result<Option<(crate::VariableDeclarations<F>, &str)>, crate::parse::Error>
|
||||
pub(crate) fn variable_declarations<P>(input: &str)
|
||||
-> Result<Option<(crate::VariableDeclarations<P::Flavor>, &str)>, crate::parse::Error>
|
||||
where
|
||||
F: crate::flavor::Flavor,
|
||||
P: crate::parse::Parser,
|
||||
{
|
||||
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,
|
||||
None => return Ok(None),
|
||||
@ -120,7 +121,7 @@ where
|
||||
|
||||
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,
|
||||
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
|
||||
F: crate::flavor::Flavor,
|
||||
P: super::Parser,
|
||||
{
|
||||
input: &'i str,
|
||||
declarations: &'d D,
|
||||
variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, F>,
|
||||
parser: &'d P,
|
||||
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
|
||||
F: crate::flavor::Flavor,
|
||||
D: crate::FindOrCreateFunctionDeclaration<F> + crate::FindOrCreatePredicateDeclaration<F>,
|
||||
P: super::Parser,
|
||||
{
|
||||
pub fn new(input: &'i str, declarations: &'d D,
|
||||
variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, F>)
|
||||
pub fn new(input: &'i str, parser: &'d P,
|
||||
variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, P::Flavor>)
|
||||
-> Self
|
||||
{
|
||||
Self
|
||||
{
|
||||
input,
|
||||
declarations,
|
||||
parser,
|
||||
variable_declaration_stack,
|
||||
}
|
||||
}
|
||||
@ -307,7 +307,7 @@ where
|
||||
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);
|
||||
log::trace!("{}- parsing term: {}", indentation, self.input);
|
||||
@ -347,7 +347,7 @@ where
|
||||
crate::parse::Error::new_expected_term(
|
||||
crate::parse::error::Location::new(0, Some(0))))??;
|
||||
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)?;
|
||||
// TODO: improve error handling if the terms between the operators are invalid
|
||||
|
||||
@ -356,7 +356,7 @@ where
|
||||
|(accumulator, 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)
|
||||
.parse(level + 1)?;
|
||||
let binary_operation =
|
||||
@ -370,7 +370,7 @@ where
|
||||
// The last item hasn’t been consumed yet, so it’s safe to unwrap it
|
||||
let last_argument = argument_iterator.remaining_input().unwrap();
|
||||
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)?;
|
||||
let last_binary_operation =
|
||||
crate::BinaryOperation::new(last_binary_operator, Box::new(accumulator),
|
||||
@ -442,7 +442,8 @@ where
|
||||
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));
|
||||
},
|
||||
_ if is_function_name(identifier) =>
|
||||
@ -459,7 +460,7 @@ where
|
||||
{
|
||||
let functor = |token: &_| *token == Token::Symbol(Symbol::Comma);
|
||||
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)
|
||||
.parse(level + 1))
|
||||
.collect::<Result<_, _>>()?;
|
||||
@ -475,7 +476,7 @@ where
|
||||
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());
|
||||
return Ok(crate::Term::function(declaration, arguments));
|
||||
},
|
||||
@ -494,7 +495,7 @@ where
|
||||
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)
|
||||
.parse(level + 1);
|
||||
}
|
||||
@ -505,7 +506,7 @@ where
|
||||
|
||||
// TODO: refactor
|
||||
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
|
||||
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
|
||||
let argument =
|
||||
TermStr::new(argument?, self.declarations, self.variable_declaration_stack)
|
||||
TermStr::new(argument?, self.parser, self.variable_declaration_stack)
|
||||
.parse(level)?;
|
||||
match self.exponentiate_inner(argument_iterator, level)?
|
||||
{
|
||||
@ -529,7 +530,7 @@ where
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
let argument =
|
||||
TermStr::new(argument?, self.declarations, self.variable_declaration_stack)
|
||||
TermStr::new(argument?, self.parser, self.variable_declaration_stack)
|
||||
.parse(level)?;
|
||||
match self.exponentiate_inner(argument_iterator, level)?
|
||||
{
|
||||
@ -581,7 +582,7 @@ mod tests
|
||||
fn parse_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();
|
||||
assert_eq!((v.0.name.as_str(), v.1), ("X", ""));
|
||||
@ -613,7 +614,7 @@ mod tests
|
||||
fn parse_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();
|
||||
assert_eq!(v.0.len(), 1);
|
||||
|
130
src/utils.rs
130
src/utils.rs
@ -1,28 +1,11 @@
|
||||
use crate::flavor::{FunctionDeclaration as _, PredicateDeclaration as _, 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>;
|
||||
}
|
||||
use crate::flavor::VariableDeclaration as _;
|
||||
|
||||
pub struct BoundVariableDeclarations<'p, F>
|
||||
where
|
||||
F: crate::flavor::Flavor,
|
||||
{
|
||||
parent: &'p VariableDeclarationStackLayer<'p, F>,
|
||||
variable_declarations: std::rc::Rc<crate::VariableDeclarations<F>>,
|
||||
pub parent: &'p VariableDeclarationStackLayer<'p, F>,
|
||||
pub variable_declarations: std::rc::Rc<crate::VariableDeclarations<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
|
||||
where
|
||||
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
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user