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
|
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
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
|
159
src/parse.rs
159
src/parse.rs
@ -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
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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(¶meters));
|
self.variable_declaration_stack, std::rc::Rc::clone(¶meters));
|
||||||
|
|
||||||
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(),
|
||||||
|
@ -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 hasn’t been consumed yet, so it’s safe to unwrap it
|
// 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 = 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);
|
||||||
|
130
src/utils.rs
130
src/utils.rs
@ -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
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user