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
{
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
{

View File

@ -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)

View File

@ -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
},
}
}
}

View File

@ -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(&parameters));
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(),

View File

@ -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 hasnt been consumed yet, so its 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);

View File

@ -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
},
}
}
}