Make inner types customizable

This commit is contained in:
Patrick Lühne 2020-05-19 15:39:20 +02:00
parent 170cde6a82
commit c7d79e7b07
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
9 changed files with 434 additions and 287 deletions

View File

@ -1,3 +1,5 @@
use crate::flavor::{FunctionDeclaration as _, PredicateDeclaration as _};
// Operators // Operators
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
@ -59,7 +61,8 @@ impl FunctionDeclaration
} }
} }
pub type FunctionDeclarations = std::collections::BTreeSet<std::rc::Rc<FunctionDeclaration>>; pub type FunctionDeclarations<F> =
std::collections::BTreeSet<std::rc::Rc<<F as crate::flavor::Flavor>::FunctionDeclaration>>;
#[derive(Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct PredicateDeclaration pub struct PredicateDeclaration
@ -80,7 +83,8 @@ impl PredicateDeclaration
} }
} }
pub type PredicateDeclarations = std::collections::BTreeSet<std::rc::Rc<PredicateDeclaration>>; pub type PredicateDeclarations<F> =
std::collections::BTreeSet<std::rc::Rc<<F as crate::flavor::Flavor>::PredicateDeclaration>>;
pub struct VariableDeclaration pub struct VariableDeclaration
{ {
@ -149,21 +153,26 @@ impl VariableDeclaration
} }
} }
pub type VariableDeclarations = Vec<std::rc::Rc<VariableDeclaration>>; pub type VariableDeclarations<F> =
Vec<std::rc::Rc<<F as crate::flavor::Flavor>::VariableDeclaration>>;
// Terms // Terms
#[derive(Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct BinaryOperation pub struct BinaryOperation<F>
where
F: crate::flavor::Flavor,
{ {
pub operator: BinaryOperator, pub operator: BinaryOperator,
pub left: Box<Term>, pub left: Box<Term<F>>,
pub right: Box<Term>, pub right: Box<Term<F>>,
} }
impl BinaryOperation impl<F> BinaryOperation<F>
where
F: crate::flavor::Flavor,
{ {
pub fn new(operator: BinaryOperator, left: Box<Term>, right: Box<Term>) -> Self pub fn new(operator: BinaryOperator, left: Box<Term<F>>, right: Box<Term<F>>) -> Self
{ {
Self Self
{ {
@ -175,17 +184,21 @@ impl BinaryOperation
} }
#[derive(Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Function pub struct Function<F>
where
F: crate::flavor::Flavor,
{ {
pub declaration: std::rc::Rc<FunctionDeclaration>, pub declaration: std::rc::Rc<F::FunctionDeclaration>,
pub arguments: Terms, pub arguments: Terms<F>,
} }
impl Function impl<F> Function<F>
where
F: crate::flavor::Flavor,
{ {
pub fn new(declaration: std::rc::Rc<FunctionDeclaration>, arguments: Terms) -> 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 then declared");
Self Self
@ -204,15 +217,19 @@ pub enum SpecialInteger
} }
#[derive(Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct UnaryOperation pub struct UnaryOperation<F>
where
F: crate::flavor::Flavor,
{ {
pub operator: UnaryOperator, pub operator: UnaryOperator,
pub argument: Box<Term>, pub argument: Box<Term<F>>,
} }
impl UnaryOperation impl<F> UnaryOperation<F>
where
F: crate::flavor::Flavor,
{ {
pub fn new(operator: UnaryOperator, argument: Box<Term>) -> Self pub fn new(operator: UnaryOperator, argument: Box<Term<F>>) -> Self
{ {
Self Self
{ {
@ -223,14 +240,18 @@ impl UnaryOperation
} }
#[derive(Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Variable pub struct Variable<F>
where
F: crate::flavor::Flavor,
{ {
pub declaration: std::rc::Rc<VariableDeclaration>, pub declaration: std::rc::Rc<F::VariableDeclaration>,
} }
impl Variable impl<F> Variable<F>
where
F: crate::flavor::Flavor,
{ {
pub fn new(declaration: std::rc::Rc<VariableDeclaration>) -> Self pub fn new(declaration: std::rc::Rc<F::VariableDeclaration>) -> Self
{ {
Self Self
{ {
@ -242,16 +263,20 @@ impl Variable
// Formulas // Formulas
#[derive(Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Compare pub struct Compare<F>
where
F: crate::flavor::Flavor,
{ {
pub operator: ComparisonOperator, pub operator: ComparisonOperator,
pub left: Box<Term>, pub left: Box<Term<F>>,
pub right: Box<Term>, pub right: Box<Term<F>>,
} }
impl Compare impl<F> Compare<F>
where
F: crate::flavor::Flavor,
{ {
pub fn new(operator: ComparisonOperator, left: Box<Term>, right: Box<Term>) -> Self pub fn new(operator: ComparisonOperator, left: Box<Term<F>>, right: Box<Term<F>>) -> Self
{ {
Self Self
{ {
@ -263,15 +288,19 @@ impl Compare
} }
#[derive(Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct QuantifiedFormula pub struct QuantifiedFormula<F>
where
F: crate::flavor::Flavor,
{ {
pub parameters: std::rc::Rc<VariableDeclarations>, pub parameters: std::rc::Rc<VariableDeclarations<F>>,
pub argument: Box<Formula>, pub argument: Box<Formula<F>>,
} }
impl QuantifiedFormula impl<F> QuantifiedFormula<F>
where
F: crate::flavor::Flavor,
{ {
pub fn new(parameters: std::rc::Rc<VariableDeclarations>, argument: Box<Formula>) -> Self pub fn new(parameters: std::rc::Rc<VariableDeclarations<F>>, argument: Box<Formula<F>>) -> Self
{ {
Self Self
{ {
@ -282,16 +311,21 @@ impl QuantifiedFormula
} }
#[derive(Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Implies pub struct Implies<F>
where
F: crate::flavor::Flavor,
{ {
pub direction: ImplicationDirection, pub direction: ImplicationDirection,
pub antecedent: Box<Formula>, pub antecedent: Box<Formula<F>>,
pub implication: Box<Formula>, pub implication: Box<Formula<F>>,
} }
impl Implies impl<F> Implies<F>
where
F: crate::flavor::Flavor,
{ {
pub fn new(direction: ImplicationDirection, antecedent: Box<Formula>, implication: Box<Formula>) pub fn new(direction: ImplicationDirection, antecedent: Box<Formula<F>>,
implication: Box<Formula<F>>)
-> Self -> Self
{ {
Self Self
@ -304,17 +338,21 @@ impl Implies
} }
#[derive(Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Predicate pub struct Predicate<F>
where
F: crate::flavor::Flavor,
{ {
pub declaration: std::rc::Rc<PredicateDeclaration>, pub declaration: std::rc::Rc<F::PredicateDeclaration>,
pub arguments: Terms, pub arguments: Terms<F>,
} }
impl Predicate impl<F> Predicate<F>
where
F: crate::flavor::Flavor,
{ {
pub fn new(declaration: std::rc::Rc<PredicateDeclaration>, arguments: Terms) -> 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 then declared");
Self Self
@ -328,33 +366,37 @@ impl Predicate
// Variants // Variants
#[derive(Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Term pub enum Term<F>
where
F: crate::flavor::Flavor,
{ {
BinaryOperation(BinaryOperation), BinaryOperation(BinaryOperation<F>),
Boolean(bool), Boolean(bool),
Function(Function), Function(Function<F>),
Integer(i32), Integer(i32),
SpecialInteger(SpecialInteger), SpecialInteger(SpecialInteger),
String(String), String(String),
UnaryOperation(UnaryOperation), UnaryOperation(UnaryOperation<F>),
Variable(Variable), Variable(Variable<F>),
} }
pub type Terms = Vec<Term>; pub type Terms<F> = Vec<Term<F>>;
impl Term impl<F> Term<F>
where
F: crate::flavor::Flavor,
{ {
pub fn absolute_value(argument: Box<Term>) -> Self pub fn absolute_value(argument: Box<Term<F>>) -> Self
{ {
Self::unary_operation(UnaryOperator::AbsoluteValue, argument) Self::unary_operation(UnaryOperator::AbsoluteValue, argument)
} }
pub fn add(left: Box<Term>, right: Box<Term>) -> Self pub fn add(left: Box<Term<F>>, right: Box<Term<F>>) -> Self
{ {
Self::binary_operation(BinaryOperator::Add, left, right) Self::binary_operation(BinaryOperator::Add, left, right)
} }
pub fn binary_operation(operator: BinaryOperator, left: Box<Term>, right: Box<Term>) -> Self pub fn binary_operation(operator: BinaryOperator, left: Box<Term<F>>, right: Box<Term<F>>) -> Self
{ {
Self::BinaryOperation(BinaryOperation::new(operator, left, right)) Self::BinaryOperation(BinaryOperation::new(operator, left, right))
} }
@ -364,12 +406,12 @@ impl Term
Self::Boolean(value) Self::Boolean(value)
} }
pub fn divide(left: Box<Term>, right: Box<Term>) -> Self pub fn divide(left: Box<Term<F>>, right: Box<Term<F>>) -> Self
{ {
Self::binary_operation(BinaryOperator::Divide, left, right) Self::binary_operation(BinaryOperator::Divide, left, right)
} }
pub fn exponentiate(left: Box<Term>, right: Box<Term>) -> Self pub fn exponentiate(left: Box<Term<F>>, right: Box<Term<F>>) -> Self
{ {
Self::binary_operation(BinaryOperator::Exponentiate, left, right) Self::binary_operation(BinaryOperator::Exponentiate, left, right)
} }
@ -379,7 +421,7 @@ impl Term
Self::boolean(false) Self::boolean(false)
} }
pub fn function(declaration: std::rc::Rc<FunctionDeclaration>, arguments: Terms) -> Self pub fn function(declaration: std::rc::Rc<F::FunctionDeclaration>, arguments: Terms<F>) -> Self
{ {
Self::Function(Function::new(declaration, arguments)) Self::Function(Function::new(declaration, arguments))
} }
@ -394,17 +436,17 @@ impl Term
Self::Integer(value) Self::Integer(value)
} }
pub fn modulo(left: Box<Term>, right: Box<Term>) -> Self pub fn modulo(left: Box<Term<F>>, right: Box<Term<F>>) -> Self
{ {
Self::binary_operation(BinaryOperator::Modulo, left, right) Self::binary_operation(BinaryOperator::Modulo, left, right)
} }
pub fn multiply(left: Box<Term>, right: Box<Term>) -> Self pub fn multiply(left: Box<Term<F>>, right: Box<Term<F>>) -> Self
{ {
Self::binary_operation(BinaryOperator::Multiply, left, right) Self::binary_operation(BinaryOperator::Multiply, left, right)
} }
pub fn negative(argument: Box<Term>) -> Self pub fn negative(argument: Box<Term<F>>) -> Self
{ {
Self::unary_operation(UnaryOperator::Negative, argument) Self::unary_operation(UnaryOperator::Negative, argument)
} }
@ -419,7 +461,7 @@ impl Term
Self::String(value) Self::String(value)
} }
pub fn subtract(left: Box<Term>, right: Box<Term>) -> Self pub fn subtract(left: Box<Term<F>>, right: Box<Term<F>>) -> Self
{ {
Self::binary_operation(BinaryOperator::Subtract, left, right) Self::binary_operation(BinaryOperator::Subtract, left, right)
} }
@ -434,37 +476,41 @@ impl Term
Self::boolean(true) Self::boolean(true)
} }
pub fn unary_operation(operator: UnaryOperator, argument: Box<Term>) -> Self pub fn unary_operation(operator: UnaryOperator, argument: Box<Term<F>>) -> Self
{ {
Self::UnaryOperation(UnaryOperation::new(operator, argument)) Self::UnaryOperation(UnaryOperation::new(operator, argument))
} }
pub fn variable(declaration: std::rc::Rc<VariableDeclaration>) -> Self pub fn variable(declaration: std::rc::Rc<F::VariableDeclaration>) -> Self
{ {
Self::Variable(Variable::new(declaration)) Self::Variable(Variable::new(declaration))
} }
} }
#[derive(Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Formula pub enum Formula<F>
where
F: crate::flavor::Flavor,
{ {
And(Formulas), And(Formulas<F>),
Boolean(bool), Boolean(bool),
Compare(Compare), Compare(Compare<F>),
Exists(QuantifiedFormula), Exists(QuantifiedFormula<F>),
ForAll(QuantifiedFormula), ForAll(QuantifiedFormula<F>),
IfAndOnlyIf(Formulas), IfAndOnlyIf(Formulas<F>),
Implies(Implies), Implies(Implies<F>),
Not(Box<Formula>), Not(Box<Formula<F>>),
Or(Formulas), Or(Formulas<F>),
Predicate(Predicate), Predicate(Predicate<F>),
} }
pub type Formulas = Vec<Formula>; pub type Formulas<F> = Vec<Formula<F>>;
impl Formula impl<F> Formula<F>
where
F: crate::flavor::Flavor,
{ {
pub fn and(arguments: Formulas) -> Self pub fn and(arguments: Formulas<F>) -> Self
{ {
Self::And(arguments) Self::And(arguments)
} }
@ -474,17 +520,17 @@ impl Formula
Self::Boolean(value) Self::Boolean(value)
} }
pub fn compare(operator: ComparisonOperator, left: Box<Term>, right: Box<Term>) -> Self pub fn compare(operator: ComparisonOperator, left: Box<Term<F>>, right: Box<Term<F>>) -> Self
{ {
Self::Compare(Compare::new(operator, left, right)) Self::Compare(Compare::new(operator, left, right))
} }
pub fn exists(parameters: std::rc::Rc<VariableDeclarations>, argument: Box<Formula>) -> Self pub fn exists(parameters: std::rc::Rc<VariableDeclarations<F>>, argument: Box<Formula<F>>) -> Self
{ {
Self::Exists(QuantifiedFormula::new(parameters, argument)) Self::Exists(QuantifiedFormula::new(parameters, argument))
} }
pub fn equal(left: Box<Term>, right: Box<Term>) -> Self pub fn equal(left: Box<Term<F>>, right: Box<Term<F>>) -> Self
{ {
Self::compare(ComparisonOperator::Equal, left, right) Self::compare(ComparisonOperator::Equal, left, right)
} }
@ -494,58 +540,58 @@ impl Formula
Self::boolean(false) Self::boolean(false)
} }
pub fn for_all(parameters: std::rc::Rc<VariableDeclarations>, argument: Box<Formula>) -> Self pub fn for_all(parameters: std::rc::Rc<VariableDeclarations<F>>, argument: Box<Formula<F>>) -> Self
{ {
Self::ForAll(QuantifiedFormula::new(parameters, argument)) Self::ForAll(QuantifiedFormula::new(parameters, argument))
} }
pub fn greater(left: Box<Term>, right: Box<Term>) -> Self pub fn greater(left: Box<Term<F>>, right: Box<Term<F>>) -> Self
{ {
Self::compare(ComparisonOperator::Greater, left, right) Self::compare(ComparisonOperator::Greater, left, right)
} }
pub fn greater_or_equal(left: Box<Term>, right: Box<Term>) -> Self pub fn greater_or_equal(left: Box<Term<F>>, right: Box<Term<F>>) -> Self
{ {
Self::compare(ComparisonOperator::GreaterOrEqual, left, right) Self::compare(ComparisonOperator::GreaterOrEqual, left, right)
} }
pub fn if_and_only_if(arguments: Formulas) -> Self pub fn if_and_only_if(arguments: Formulas<F>) -> Self
{ {
Self::IfAndOnlyIf(arguments) Self::IfAndOnlyIf(arguments)
} }
pub fn implies(direction: ImplicationDirection, antecedent: Box<Formula>, pub fn implies(direction: ImplicationDirection, antecedent: Box<Formula<F>>,
consequent: Box<Formula>) -> Self consequent: Box<Formula<F>>) -> Self
{ {
Self::Implies(Implies::new(direction, antecedent, consequent)) Self::Implies(Implies::new(direction, antecedent, consequent))
} }
pub fn less(left: Box<Term>, right: Box<Term>) -> Self pub fn less(left: Box<Term<F>>, right: Box<Term<F>>) -> Self
{ {
Self::compare(ComparisonOperator::Less, left, right) Self::compare(ComparisonOperator::Less, left, right)
} }
pub fn less_or_equal(left: Box<Term>, right: Box<Term>) -> Self pub fn less_or_equal(left: Box<Term<F>>, right: Box<Term<F>>) -> Self
{ {
Self::compare(ComparisonOperator::LessOrEqual, left, right) Self::compare(ComparisonOperator::LessOrEqual, left, right)
} }
pub fn not(argument: Box<Formula>) -> Self pub fn not(argument: Box<Formula<F>>) -> Self
{ {
Self::Not(argument) Self::Not(argument)
} }
pub fn not_equal(left: Box<Term>, right: Box<Term>) -> Self pub fn not_equal(left: Box<Term<F>>, right: Box<Term<F>>) -> Self
{ {
Self::compare(ComparisonOperator::NotEqual, left, right) Self::compare(ComparisonOperator::NotEqual, left, right)
} }
pub fn or(arguments: Formulas) -> Self pub fn or(arguments: Formulas<F>) -> Self
{ {
Self::Or(arguments) Self::Or(arguments)
} }
pub fn predicate(declaration: std::rc::Rc<PredicateDeclaration>, arguments: Terms) -> Self pub fn predicate(declaration: std::rc::Rc<F::PredicateDeclaration>, arguments: Terms<F>) -> Self
{ {
Self::Predicate(Predicate::new(declaration, arguments)) Self::Predicate(Predicate::new(declaration, arguments))
} }
@ -556,8 +602,10 @@ impl Formula
} }
} }
pub struct OpenFormula pub struct OpenFormula<F>
where
F: crate::flavor::Flavor,
{ {
pub free_variable_declarations: std::rc::Rc<VariableDeclarations>, pub free_variable_declarations: std::rc::Rc<VariableDeclarations<F>>,
pub formula: Formula, pub formula: Formula<F>,
} }

100
src/flavor.rs Normal file
View File

@ -0,0 +1,100 @@
pub trait FunctionDeclaration
{
fn new(name: String, arity: usize) -> Self;
fn name(&self) -> &str;
fn arity(&self) -> usize;
}
impl FunctionDeclaration for crate::FunctionDeclaration
{
fn new(name: String, arity: usize) -> Self
{
Self
{
name,
arity,
}
}
fn name(&self) -> &str
{
&self.name
}
fn arity(&self) -> usize
{
self.arity
}
}
pub trait PredicateDeclaration
{
fn new(name: String, arity: usize) -> Self;
fn name(&self) -> &str;
fn arity(&self) -> usize;
}
impl PredicateDeclaration for crate::PredicateDeclaration
{
fn new(name: String, arity: usize) -> Self
{
Self
{
name,
arity,
}
}
fn name(&self) -> &str
{
&self.name
}
fn arity(&self) -> usize
{
self.arity
}
}
pub trait VariableDeclaration
{
fn new(name: String) -> Self;
fn name(&self) -> &str;
}
impl VariableDeclaration for crate::VariableDeclaration
{
fn new(name: String) -> Self
{
Self
{
name
}
}
fn name(&self) -> &str
{
&self.name
}
}
pub trait Flavor
{
type FunctionDeclaration: FunctionDeclaration + std::cmp::Eq + std::cmp::Ord + std::hash::Hash;
type PredicateDeclaration:
PredicateDeclaration + std::cmp::Eq + std::cmp::Ord + std::hash::Hash;
type VariableDeclaration: VariableDeclaration + std::cmp::Eq + std::cmp::Ord + std::hash::Hash
+ std::fmt::Display;
}
pub struct DefaultFlavor;
impl Flavor for DefaultFlavor
{
type FunctionDeclaration = crate::FunctionDeclaration;
type PredicateDeclaration = crate::PredicateDeclaration;
type VariableDeclaration = crate::VariableDeclaration;
}

View File

@ -1,37 +1,2 @@
pub mod formulas; pub mod formulas;
pub mod terms; pub mod terms;
pub trait Format
{
fn display_variable_declaration(&self, formatter: &mut std::fmt::Formatter,
variable_declaration: &std::rc::Rc<crate::VariableDeclaration>)
-> std::fmt::Result;
}
pub struct DefaultFormat;
impl Format for DefaultFormat
{
fn display_variable_declaration(&self, formatter: &mut std::fmt::Formatter,
variable_declaration: &std::rc::Rc<crate::VariableDeclaration>)
-> std::fmt::Result
{
write!(formatter, "{:?}", variable_declaration)
}
}
pub fn display_term<'term, 'format, F>(term: &'term crate::Term, format: &'format F)
-> terms::TermDisplay<'term, 'format, F>
where
F: Format,
{
terms::display_term(term, None, terms::TermPosition::Any, format)
}
pub fn display_formula<'formula, 'format, F>(formula: &'formula crate::Formula, format: &'format F)
-> formulas::FormulaDisplay<'formula, 'format, F>
where
F: Format,
{
formulas::display_formula(formula, None, formulas::FormulaPosition::Any, format)
}

View File

@ -1,3 +1,4 @@
use crate::flavor::PredicateDeclaration as _;
use super::terms::*; use super::terms::*;
impl std::fmt::Debug for crate::ComparisonOperator impl std::fmt::Debug for crate::ComparisonOperator
@ -53,19 +54,19 @@ pub(crate) enum FormulaPosition
ImpliesAntecedent, ImpliesAntecedent,
} }
pub struct FormulaDisplay<'formula, 'format, F> pub struct FormulaDisplay<'formula, F>
where where
F: super::Format, F: crate::flavor::Flavor,
{ {
formula: &'formula crate::Formula, formula: &'formula crate::Formula<F>,
parent_formula: Option<&'formula crate::Formula>, parent_formula: Option<&'formula crate::Formula<F>>,
position: FormulaPosition, position: FormulaPosition,
format: &'format F, //declarations: &'d D,
} }
impl<'formula, 'format, F> FormulaDisplay<'formula, 'format, F> impl<'formula, F> FormulaDisplay<'formula, F>
where where
F: super::Format, F: crate::flavor::Flavor,
{ {
fn requires_parentheses(&self) -> bool fn requires_parentheses(&self) -> bool
{ {
@ -135,24 +136,23 @@ where
} }
} }
pub(crate) fn display_formula<'formula, 'format, F>(formula: &'formula crate::Formula, pub(crate) fn display_formula<'formula, F>(formula: &'formula crate::Formula<F>,
parent_formula: Option<&'formula crate::Formula>, position: FormulaPosition, format: &'format F) parent_formula: Option<&'formula crate::Formula<F>>, position: FormulaPosition)
-> FormulaDisplay<'formula, 'format, F> -> FormulaDisplay<'formula, F>
where where
F: super::Format, F: crate::flavor::Flavor,
{ {
FormulaDisplay FormulaDisplay
{ {
formula, formula,
parent_formula, parent_formula,
position, position,
format,
} }
} }
impl<'formula, 'format, F> std::fmt::Debug for FormulaDisplay<'formula, 'format, F> impl<'formula, F> std::fmt::Debug for FormulaDisplay<'formula, F>
where where
F: super::Format, F: crate::flavor::Flavor,
{ {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
{ {
@ -169,8 +169,8 @@ where
{ {
if exists.parameters.is_empty() if exists.parameters.is_empty()
{ {
write!(formatter, "{:?}", display_formula(&exists.argument, self.parent_formula, write!(formatter, "{:?}", display_formula::<F>(&exists.argument,
self.position, self.format))?; self.parent_formula, self.position))?;
} }
else else
{ {
@ -180,14 +180,13 @@ where
for parameter in exists.parameters.iter() for parameter in exists.parameters.iter()
{ {
write!(formatter, "{}", separator)?; write!(formatter, "{}{}", separator, parameter)?;
self.format.display_variable_declaration(formatter, &parameter)?;
separator = ", " separator = ", "
} }
write!(formatter, " {:?}", display_formula(&exists.argument, Some(self.formula), write!(formatter, " {:?}", display_formula(&exists.argument, Some(self.formula),
FormulaPosition::Any, self.format))?; FormulaPosition::Any))?;
} }
}, },
crate::Formula::ForAll(for_all) => crate::Formula::ForAll(for_all) =>
@ -195,7 +194,7 @@ where
if for_all.parameters.is_empty() if for_all.parameters.is_empty()
{ {
write!(formatter, "{:?}", display_formula(&for_all.argument, write!(formatter, "{:?}", display_formula(&for_all.argument,
self.parent_formula, self.position, self.format))?; self.parent_formula, self.position))?;
} }
else else
{ {
@ -205,18 +204,17 @@ where
for parameter in for_all.parameters.iter() for parameter in for_all.parameters.iter()
{ {
write!(formatter, "{}", separator)?; write!(formatter, "{}{}", separator, parameter)?;
self.format.display_variable_declaration(formatter, &parameter)?;
separator = ", " separator = ", "
} }
write!(formatter, " {:?}", display_formula(&for_all.argument, write!(formatter, " {:?}", display_formula(&for_all.argument,
Some(self.formula), FormulaPosition::Any, self.format))?; Some(self.formula), FormulaPosition::Any))?;
} }
}, },
crate::Formula::Not(argument) => write!(formatter, "not {:?}", crate::Formula::Not(argument) => write!(formatter, "not {:?}",
display_formula(argument, Some(self.formula), FormulaPosition::Any, self.format))?, display_formula(argument, Some(self.formula), FormulaPosition::Any))?,
crate::Formula::And(arguments) => crate::Formula::And(arguments) =>
{ {
if arguments.is_empty() if arguments.is_empty()
@ -236,7 +234,7 @@ where
for argument in arguments for argument in arguments
{ {
write!(formatter, "{}{:?}", separator, write!(formatter, "{}{:?}", separator,
display_formula(argument, parent_formula, position, self.format))?; display_formula(argument, parent_formula, position))?;
separator = " and " separator = " and "
} }
@ -261,7 +259,7 @@ where
for argument in arguments for argument in arguments
{ {
write!(formatter, "{}{:?}", separator, write!(formatter, "{}{:?}", separator,
display_formula(argument, parent_formula, position, self.format))?; display_formula(argument, parent_formula, position))?;
separator = " or " separator = " or "
} }
@ -273,14 +271,13 @@ where
{ {
write!(formatter, "{:?}", write!(formatter, "{:?}",
display_formula(antecedent, Some(self.formula), display_formula(antecedent, Some(self.formula),
FormulaPosition::ImpliesAntecedent, self.format)) FormulaPosition::ImpliesAntecedent))
}; };
let format_implication = |formatter: &mut std::fmt::Formatter| -> Result<_, _> let format_implication = |formatter: &mut std::fmt::Formatter| -> Result<_, _>
{ {
write!(formatter, "{:?}", write!(formatter, "{:?}",
display_formula(implication, Some(self.formula), FormulaPosition::Any, display_formula(implication, Some(self.formula), FormulaPosition::Any))
self.format))
}; };
match direction match direction
@ -318,7 +315,7 @@ where
for argument in arguments for argument in arguments
{ {
write!(formatter, "{}{:?}", separator, write!(formatter, "{}{:?}", separator,
display_formula(argument, parent_formula, position, self.format))?; display_formula(argument, parent_formula, position))?;
separator = " <-> " separator = " <-> "
} }
@ -337,15 +334,14 @@ where
}; };
write!(formatter, "{:?} {} {:?}", write!(formatter, "{:?} {} {:?}",
display_term(&compare.left, None, TermPosition::Any, self.format), display_term(&compare.left, None, TermPosition::Any), operator_string,
operator_string, display_term(&compare.right, None, TermPosition::Any))?;
display_term(&compare.right, None, TermPosition::Any, self.format))?;
}, },
crate::Formula::Boolean(true) => write!(formatter, "true")?, crate::Formula::Boolean(true) => write!(formatter, "true")?,
crate::Formula::Boolean(false) => write!(formatter, "false")?, crate::Formula::Boolean(false) => write!(formatter, "false")?,
crate::Formula::Predicate(predicate) => crate::Formula::Predicate(predicate) =>
{ {
write!(formatter, "{}", predicate.declaration.name)?; write!(formatter, "{}", predicate.declaration.name())?;
if !predicate.arguments.is_empty() if !predicate.arguments.is_empty()
{ {
@ -356,7 +352,7 @@ where
for argument in &predicate.arguments for argument in &predicate.arguments
{ {
write!(formatter, "{}{:?}", separator, display_term(argument, None, write!(formatter, "{}{:?}", separator, display_term(argument, None,
TermPosition::Any, self.format))?; TermPosition::Any))?;
separator = ", " separator = ", "
} }
@ -375,9 +371,9 @@ where
} }
} }
impl<'formula, 'format, F> std::fmt::Display for FormulaDisplay<'formula, 'format, F> impl<'formula, F> std::fmt::Display for FormulaDisplay<'formula, F>
where where
F: super::Format, F: crate::flavor::Flavor,
{ {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
{ {
@ -385,21 +381,23 @@ where
} }
} }
impl std::fmt::Debug for crate::Formula impl<F> std::fmt::Debug for crate::Formula<F>
where
F: crate::flavor::Flavor,
{ {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
{ {
write!(formatter, "{:?}", display_formula(&self, None, FormulaPosition::Any, write!(formatter, "{:?}", display_formula(&self, None, FormulaPosition::Any))
&super::DefaultFormat))
} }
} }
impl std::fmt::Display for crate::Formula impl<F> std::fmt::Display for crate::Formula<F>
where
F: crate::flavor::Flavor,
{ {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
{ {
write!(formatter, "{}", display_formula(&self, None, FormulaPosition::Any, write!(formatter, "{}", display_formula(&self, None, FormulaPosition::Any))
&super::DefaultFormat))
} }
} }
@ -407,7 +405,10 @@ impl std::fmt::Display for crate::Formula
mod tests mod tests
{ {
use crate::*; use crate::*;
use crate::format::terms::tests::*; use format::terms::tests::*;
type Formula = crate::Formula<flavor::DefaultFlavor>;
type Term = crate::Term<flavor::DefaultFlavor>;
type VariableDeclarations = crate::VariableDeclarations<flavor::DefaultFlavor>;
macro_rules! assert macro_rules! assert
{ {
@ -442,7 +443,7 @@ mod tests
}; };
} }
fn format(formula: Box<ast::Formula>) -> String fn format(formula: Box<Formula>) -> String
{ {
format!("{}", formula) format!("{}", formula)
} }

View File

@ -1,3 +1,5 @@
use crate::flavor::FunctionDeclaration as _;
impl std::fmt::Debug for crate::SpecialInteger impl std::fmt::Debug for crate::SpecialInteger
{ {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
@ -58,19 +60,18 @@ pub(crate) enum TermPosition
Right, Right,
} }
pub struct TermDisplay<'term, 'format, F> pub struct TermDisplay<'term, F>
where where
F: super::Format, F: crate::flavor::Flavor,
{ {
term: &'term crate::Term, term: &'term crate::Term<F>,
parent_term: Option<&'term crate::Term>, parent_term: Option<&'term crate::Term<F>>,
position: TermPosition, position: TermPosition,
format: &'format F,
} }
impl<'term, 'format, F> TermDisplay<'term, 'format, F> impl<'term, F> TermDisplay<'term, F>
where where
F: super::Format, F: crate::flavor::Flavor,
{ {
fn requires_parentheses(&self) -> bool fn requires_parentheses(&self) -> bool
{ {
@ -154,24 +155,23 @@ where
} }
} }
pub(crate) fn display_term<'term, 'format, F>(term: &'term crate::Term, pub(crate) fn display_term<'term, F>(term: &'term crate::Term<F>,
parent_term: Option<&'term crate::Term>, position: TermPosition, format: &'format F) parent_term: Option<&'term crate::Term<F>>, position: TermPosition)
-> TermDisplay<'term, 'format, F> -> TermDisplay<'term, F>
where where
F: super::Format, F: crate::flavor::Flavor,
{ {
TermDisplay TermDisplay
{ {
term, term,
parent_term, parent_term,
position, position,
format,
} }
} }
impl<'term, 'format, F> std::fmt::Debug for TermDisplay<'term, 'format, F> impl<'term, F> std::fmt::Debug for TermDisplay<'term, F>
where where
F: super::Format, F: crate::flavor::Flavor,
{ {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
{ {
@ -190,15 +190,14 @@ where
crate::Term::Integer(value) => write!(formatter, "{}", value)?, crate::Term::Integer(value) => write!(formatter, "{}", value)?,
crate::Term::String(value) => write!(formatter, "\"{}\"", crate::Term::String(value) => write!(formatter, "\"{}\"",
value.replace("\\", "\\\\").replace("\n", "\\n").replace("\t", "\\t"))?, value.replace("\\", "\\\\").replace("\n", "\\n").replace("\t", "\\t"))?,
crate::Term::Variable(variable) => crate::Term::Variable(variable) => write!(formatter, "{}", variable.declaration)?,
self.format.display_variable_declaration(formatter, &variable.declaration)?,
crate::Term::Function(function) => crate::Term::Function(function) =>
{ {
write!(formatter, "{}", function.declaration.name)?; write!(formatter, "{}", function.declaration.name())?;
assert!(function.declaration.arity == function.arguments.len(), assert!(function.declaration.arity() == function.arguments.len(),
"number of function arguments differs from declaration (expected {}, got {})", "number of function arguments differs from declaration (expected {}, got {})",
function.declaration.arity, function.arguments.len()); function.declaration.arity(), function.arguments.len());
if !function.arguments.is_empty() if !function.arguments.is_empty()
{ {
@ -209,8 +208,7 @@ where
for argument in &function.arguments for argument in &function.arguments
{ {
write!(formatter, "{}{:?}", separator, write!(formatter, "{}{:?}", separator,
display_term(&argument, Some(self.term), TermPosition::Any, display_term(&argument, Some(self.term), TermPosition::Any))?;
self.format))?;
separator = ", "; separator = ", ";
} }
@ -231,20 +229,18 @@ where
}; };
write!(formatter, "{:?} {} {:?}", write!(formatter, "{:?} {} {:?}",
display_term(&binary_operation.left, Some(self.term), TermPosition::Left, display_term(&binary_operation.left, Some(self.term), TermPosition::Left),
self.format),
operator_string, operator_string,
display_term(&binary_operation.right, Some(self.term), TermPosition::Right, display_term(&binary_operation.right, Some(self.term), TermPosition::Right))?;
self.format))?;
}, },
crate::Term::UnaryOperation( crate::Term::UnaryOperation(
crate::UnaryOperation{operator: crate::UnaryOperator::Negative, argument}) crate::UnaryOperation{operator: crate::UnaryOperator::Negative, argument})
=> write!(formatter, "-{:?}", => write!(formatter, "-{:?}",
display_term(argument, Some(self.term), TermPosition::Any, self.format))?, display_term(argument, Some(self.term), TermPosition::Any))?,
crate::Term::UnaryOperation( crate::Term::UnaryOperation(
crate::UnaryOperation{operator: crate::UnaryOperator::AbsoluteValue, argument}) crate::UnaryOperation{operator: crate::UnaryOperator::AbsoluteValue, argument})
=> write!(formatter, "|{:?}|", => write!(formatter, "|{:?}|",
display_term(argument, Some(self.term), TermPosition::Any, self.format))?, display_term(argument, Some(self.term), TermPosition::Any))?,
} }
if requires_parentheses if requires_parentheses
@ -256,9 +252,9 @@ where
} }
} }
impl<'term, 'format, F> std::fmt::Display for TermDisplay<'term, 'format, F> impl<'term, F> std::fmt::Display for TermDisplay<'term, F>
where where
F: super::Format, F: crate::flavor::Flavor,
{ {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
{ {
@ -266,20 +262,23 @@ where
} }
} }
impl std::fmt::Debug for crate::Term impl<F> std::fmt::Debug for crate::Term<F>
where
F: crate::flavor::Flavor,
{ {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
{ {
write!(formatter, "{:?}", display_term(&self, None, TermPosition::Any, write!(formatter, "{:?}", display_term(&self, None, TermPosition::Any))
&super::DefaultFormat))
} }
} }
impl std::fmt::Display for crate::Term impl<F> std::fmt::Display for crate::Term<F>
where
F: crate::flavor::Flavor,
{ {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
{ {
write!(formatter, "{}", display_term(&self, None, TermPosition::Any, &super::DefaultFormat)) write!(formatter, "{}", display_term(&self, None, TermPosition::Any))
} }
} }
@ -287,6 +286,7 @@ impl std::fmt::Display for crate::Term
pub(crate) mod tests pub(crate) mod tests
{ {
use crate::*; use crate::*;
type Term = crate::Term<flavor::DefaultFlavor>;
macro_rules! assert macro_rules! assert
{ {
@ -296,7 +296,7 @@ pub(crate) mod tests
}; };
} }
fn format(term: Box<ast::Term>) -> String fn format(term: Box<Term>) -> String
{ {
format!("{}", term) format!("{}", term)
} }

View File

@ -1,4 +1,5 @@
mod ast; mod ast;
pub mod flavor;
pub mod format; pub mod format;
pub mod parse; pub mod parse;
mod utils; mod utils;

View File

@ -1,9 +1,11 @@
use super::terms::*; use super::terms::*;
use super::tokens::*; use super::tokens::*;
pub fn formula<D>(input: &str, declarations: &D) -> Result<crate::OpenFormula, crate::parse::Error> pub fn formula<D, F>(input: &str, declarations: &D)
-> Result<crate::OpenFormula<F>, crate::parse::Error>
where where
D: crate::FindOrCreateFunctionDeclaration + crate::FindOrCreatePredicateDeclaration, F: crate::flavor::Flavor,
D: crate::FindOrCreateFunctionDeclaration<F> + crate::FindOrCreatePredicateDeclaration<F>,
{ {
let variable_declaration_stack = crate::VariableDeclarationStackLayer::free(); let variable_declaration_stack = crate::VariableDeclarationStackLayer::free();
@ -69,19 +71,22 @@ impl std::fmt::Debug for LogicalConnective
} }
} }
struct FormulaStr<'i, 'd, 'p, 'v, D> struct FormulaStr<'i, 'd, 'p, 'v, F, D>
where
F: crate::flavor::Flavor,
{ {
input: &'i str, input: &'i str,
declarations: &'d D, declarations: &'d D,
variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p>, variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, F>,
} }
impl<'i, 'd, 'p, 'v, D> FormulaStr<'i, 'd, 'p, 'v, D> impl<'i, 'd, 'p, 'v, F, D> FormulaStr<'i, 'd, 'p, 'v, F, D>
where where
D: crate::FindOrCreateFunctionDeclaration + crate::FindOrCreatePredicateDeclaration, F: crate::flavor::Flavor,
D: crate::FindOrCreateFunctionDeclaration<F> + crate::FindOrCreatePredicateDeclaration<F>,
{ {
pub fn new(input: &'i str, declarations: &'d D, pub fn new(input: &'i str, declarations: &'d D,
variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p>) variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, F>)
-> Self -> Self
{ {
Self Self
@ -189,7 +194,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, crate::parse::Error> pub fn parse(&self, level: usize) -> Result<crate::Formula<F>, crate::parse::Error>
{ {
let indentation = " ".repeat(level); let indentation = " ".repeat(level);
let input = trim_start(self.input); let input = trim_start(self.input);
@ -395,7 +400,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>, crate::parse::Error> -> Result<Option<crate::Formula<F>>, 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>>
{ {
@ -418,7 +423,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, crate::parse::Error> -> Result<crate::Formula<F>, 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>>
{ {
@ -446,9 +451,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, crate::parse::Error> -> Result<crate::Formula<F>, crate::parse::Error>
{ {
let (parameters, input) = match variable_declarations(input)? let (parameters, input) = match variable_declarations::<F>(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(
@ -500,7 +505,7 @@ mod tests
#[test] #[test]
fn tokenize_formula_logical_connectives() fn tokenize_formula_logical_connectives()
{ {
let declarations = crate::Declarations::new(); let declarations = crate::Declarations::<crate::flavor::DefaultFlavor>::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, &declarations,

View File

@ -1,3 +1,4 @@
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)>
@ -82,19 +83,23 @@ fn is_variable_name(identifier: &str) -> bool
false false
} }
pub(crate) fn variable_declaration(input: &str) -> Option<(crate::VariableDeclaration, &str)> pub(crate) fn variable_declaration<F>(input: &str) -> Option<(F::VariableDeclaration, &str)>
where
F: crate::flavor::Flavor,
{ {
variable_name(input) variable_name(input)
.map(|(variable_name, remaining_input)| .map(|(variable_name, remaining_input)|
(crate::VariableDeclaration::new(variable_name.to_string()), remaining_input)) (F::VariableDeclaration::new(variable_name.to_string()), remaining_input))
} }
pub(crate) fn variable_declarations(input: &str) pub(crate) fn variable_declarations<F>(input: &str)
-> Result<Option<(crate::VariableDeclarations, &str)>, crate::parse::Error> -> Result<Option<(crate::VariableDeclarations<F>, &str)>, crate::parse::Error>
where
F: crate::flavor::Flavor,
{ {
let mut variable_declarations = vec![]; let mut variable_declarations = vec![];
let (first_variable_declaration, mut input) = match variable_declaration(input) let (first_variable_declaration, mut input) = match variable_declaration::<F>(input)
{ {
Some(first_variable_declaration) => first_variable_declaration, Some(first_variable_declaration) => first_variable_declaration,
None => return Ok(None), None => return Ok(None),
@ -115,7 +120,7 @@ pub(crate) fn variable_declarations(input: &str)
input = trim_start(input); input = trim_start(input);
let (variable_declaration, remaining_input) = match variable_declaration(input) let (variable_declaration, remaining_input) = match variable_declaration::<F>(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(
@ -162,19 +167,22 @@ impl std::fmt::Debug for ArithmeticOperatorClass
} }
} }
pub(crate) struct TermStr<'i, 'd, 'v, 'p, D> pub(crate) struct TermStr<'i, 'd, 'v, 'p, F, D>
where
F: crate::flavor::Flavor,
{ {
input: &'i str, input: &'i str,
declarations: &'d D, declarations: &'d D,
variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p>, variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, F>,
} }
impl<'i, 'd, 'v, 'p, D> TermStr<'i, 'd, 'v, 'p, D> impl<'i, 'd, 'v, 'p, F, D> TermStr<'i, 'd, 'v, 'p, F, D>
where where
D: crate::FindOrCreateFunctionDeclaration + crate::FindOrCreatePredicateDeclaration, F: crate::flavor::Flavor,
D: crate::FindOrCreateFunctionDeclaration<F> + crate::FindOrCreatePredicateDeclaration<F>,
{ {
pub fn new(input: &'i str, declarations: &'d D, pub fn new(input: &'i str, declarations: &'d D,
variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p>) variable_declaration_stack: &'v crate::VariableDeclarationStackLayer<'p, F>)
-> Self -> Self
{ {
Self Self
@ -299,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, crate::parse::Error> pub fn parse(&self, level: usize) -> Result<crate::Term<F>, 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);
@ -497,7 +505,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>, crate::parse::Error> -> Result<Option<crate::Term<F>>, 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>>
{ {
@ -521,7 +529,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, crate::parse::Error> -> Result<crate::Term<F>, 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>>
{ {
@ -572,6 +580,9 @@ mod tests
#[test] #[test]
fn parse_variable_declaration() fn parse_variable_declaration()
{ {
let variable_declaration =
|x| super::variable_declaration::<crate::flavor::DefaultFlavor>(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", ""));
let v = variable_declaration("_X").unwrap(); let v = variable_declaration("_X").unwrap();
@ -601,6 +612,9 @@ mod tests
#[test] #[test]
fn parse_variable_declarations() fn parse_variable_declarations()
{ {
let variable_declarations =
|x| super::variable_declarations::<crate::flavor::DefaultFlavor>(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);
assert_eq!(v.0[0].name.as_str(), "X"); assert_eq!(v.0[0].name.as_str(), "X");

View File

@ -1,25 +1,36 @@
pub trait FindOrCreateFunctionDeclaration 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) fn find_or_create_function_declaration(&self, name: &str, arity: usize)
-> std::rc::Rc<crate::FunctionDeclaration>; -> std::rc::Rc<F::FunctionDeclaration>;
} }
pub trait FindOrCreatePredicateDeclaration pub trait FindOrCreatePredicateDeclaration<F>
where
F: crate::flavor::Flavor,
{ {
fn find_or_create_predicate_declaration(&self, name: &str, arity: usize) fn find_or_create_predicate_declaration(&self, name: &str, arity: usize)
-> std::rc::Rc<crate::PredicateDeclaration>; -> std::rc::Rc<F::PredicateDeclaration>;
} }
pub struct BoundVariableDeclarations<'p> pub struct BoundVariableDeclarations<'p, F>
where
F: crate::flavor::Flavor,
{ {
parent: &'p VariableDeclarationStackLayer<'p>, parent: &'p VariableDeclarationStackLayer<'p, F>,
variable_declarations: std::rc::Rc<crate::VariableDeclarations>, variable_declarations: std::rc::Rc<crate::VariableDeclarations<F>>,
} }
impl<'p> BoundVariableDeclarations<'p> impl<'p, F> BoundVariableDeclarations<'p, F>
where
F: crate::flavor::Flavor,
{ {
pub fn new(parent: &'p VariableDeclarationStackLayer<'p>, pub fn new(parent: &'p VariableDeclarationStackLayer<'p, F>,
variable_declarations: std::rc::Rc<crate::VariableDeclarations>) -> Self variable_declarations: std::rc::Rc<crate::VariableDeclarations<F>>) -> Self
{ {
Self Self
{ {
@ -29,33 +40,37 @@ impl<'p> BoundVariableDeclarations<'p>
} }
} }
pub enum VariableDeclarationStackLayer<'p> pub enum VariableDeclarationStackLayer<'p, F>
where
F: crate::flavor::Flavor,
{ {
Free(std::cell::RefCell<crate::VariableDeclarations>), Free(std::cell::RefCell<crate::VariableDeclarations<F>>),
Bound(BoundVariableDeclarations<'p>), Bound(BoundVariableDeclarations<'p, F>),
} }
impl<'p> VariableDeclarationStackLayer<'p> impl<'p, F> VariableDeclarationStackLayer<'p, F>
where
F: crate::flavor::Flavor,
{ {
pub fn free() -> Self pub fn free() -> Self
{ {
Self::Free(std::cell::RefCell::new(vec![])) Self::Free(std::cell::RefCell::new(vec![]))
} }
pub fn bound(parent: &'p VariableDeclarationStackLayer<'p>, pub fn bound(parent: &'p VariableDeclarationStackLayer<'p, F>,
variable_declarations: std::rc::Rc<crate::VariableDeclarations>) -> Self variable_declarations: std::rc::Rc<crate::VariableDeclarations<F>>) -> Self
{ {
Self::Bound(BoundVariableDeclarations::new(parent, variable_declarations)) Self::Bound(BoundVariableDeclarations::new(parent, variable_declarations))
} }
pub fn find(&self, variable_name: &str) -> Option<std::rc::Rc<crate::VariableDeclaration>> pub fn find(&self, variable_name: &str) -> Option<std::rc::Rc<F::VariableDeclaration>>
{ {
match self match self
{ {
VariableDeclarationStackLayer::Free(free_variable_declarations) => VariableDeclarationStackLayer::Free(free_variable_declarations) =>
{ {
if let Some(variable_declaration) = free_variable_declarations.borrow().iter() if let Some(variable_declaration) = free_variable_declarations.borrow().iter()
.find(|x| x.name == variable_name) .find(|x| x.name() == variable_name)
{ {
return Some(std::rc::Rc::clone(&variable_declaration)); return Some(std::rc::Rc::clone(&variable_declaration));
} }
@ -66,7 +81,7 @@ impl<'p> VariableDeclarationStackLayer<'p>
{ {
if let Some(variable_declaration) = bound_variable_declarations if let Some(variable_declaration) = bound_variable_declarations
.variable_declarations.iter() .variable_declarations.iter()
.find(|x| x.name == variable_name) .find(|x| x.name() == variable_name)
{ {
return Some(std::rc::Rc::clone(&variable_declaration)); return Some(std::rc::Rc::clone(&variable_declaration));
} }
@ -76,22 +91,19 @@ impl<'p> VariableDeclarationStackLayer<'p>
} }
} }
pub fn find_or_create(&self, variable_name: &str) -> std::rc::Rc<crate::VariableDeclaration> pub fn find_or_create(&self, variable_name: &str) -> std::rc::Rc<F::VariableDeclaration>
{ {
match self match self
{ {
VariableDeclarationStackLayer::Free(free_variable_declarations) => VariableDeclarationStackLayer::Free(free_variable_declarations) =>
{ {
if let Some(variable_declaration) = free_variable_declarations.borrow().iter() if let Some(variable_declaration) = free_variable_declarations.borrow().iter()
.find(|x| x.name == variable_name) .find(|x| x.name() == variable_name)
{ {
return std::rc::Rc::clone(&variable_declaration); return std::rc::Rc::clone(&variable_declaration);
} }
let variable_declaration = crate::VariableDeclaration let variable_declaration = F::VariableDeclaration::new(variable_name.to_owned());
{
name: variable_name.to_owned(),
};
let variable_declaration = std::rc::Rc::new(variable_declaration); let variable_declaration = std::rc::Rc::new(variable_declaration);
free_variable_declarations.borrow_mut() free_variable_declarations.borrow_mut()
@ -103,7 +115,7 @@ impl<'p> VariableDeclarationStackLayer<'p>
{ {
if let Some(variable_declaration) = bound_variable_declarations if let Some(variable_declaration) = bound_variable_declarations
.variable_declarations.iter() .variable_declarations.iter()
.find(|x| x.name == variable_name) .find(|x| x.name() == variable_name)
{ {
return std::rc::Rc::clone(&variable_declaration); return std::rc::Rc::clone(&variable_declaration);
} }
@ -113,9 +125,9 @@ impl<'p> VariableDeclarationStackLayer<'p>
} }
} }
pub fn free_variable_declarations_do_mut<F, G>(&self, f: F) -> G pub fn free_variable_declarations_do_mut<F1, F2>(&self, f: F1) -> F2
where where
F: Fn(&mut crate::VariableDeclarations) -> G F1: Fn(&mut crate::VariableDeclarations<F>) -> F2,
{ {
match self match self
{ {
@ -126,9 +138,9 @@ impl<'p> VariableDeclarationStackLayer<'p>
} }
} }
pub fn free_variable_declarations_do<F, G>(&self, f: F) -> G pub fn free_variable_declarations_do<F1, F2>(&self, f: F1) -> F2
where where
F: Fn(&crate::VariableDeclarations) -> G F1: Fn(&crate::VariableDeclarations<F>) -> F2,
{ {
match self match self
{ {
@ -140,41 +152,44 @@ impl<'p> VariableDeclarationStackLayer<'p>
} }
} }
pub struct Declarations pub struct Declarations<F>
where
F: crate::flavor::Flavor,
{ {
function_declarations: std::cell::RefCell<crate::FunctionDeclarations>, function_declarations: std::cell::RefCell<crate::FunctionDeclarations<F>>,
predicate_declarations: std::cell::RefCell<crate::PredicateDeclarations>, predicate_declarations: std::cell::RefCell<crate::PredicateDeclarations<F>>,
} }
impl Declarations impl<F> Declarations<F>
where
F: crate::flavor::Flavor,
{ {
pub fn new() -> Self pub fn new() -> Self
{ {
Self Self
{ {
function_declarations: std::cell::RefCell::new(crate::FunctionDeclarations::new()), function_declarations: std::cell::RefCell::new(crate::FunctionDeclarations::<F>::new()),
predicate_declarations: std::cell::RefCell::new(crate::PredicateDeclarations::new()), predicate_declarations:
std::cell::RefCell::new(crate::PredicateDeclarations::<F>::new()),
} }
} }
} }
impl FindOrCreateFunctionDeclaration for Declarations impl<F> FindOrCreateFunctionDeclaration<F> for Declarations<F>
where
F: crate::flavor::Flavor,
{ {
fn find_or_create_function_declaration(&self, name: &str, arity: usize) fn find_or_create_function_declaration(&self, name: &str, arity: usize)
-> std::rc::Rc<crate::FunctionDeclaration> -> std::rc::Rc<F::FunctionDeclaration>
{ {
let mut function_declarations = self.function_declarations.borrow_mut(); let mut function_declarations = self.function_declarations.borrow_mut();
match function_declarations.iter().find(|x| x.name == name && x.arity == arity) match function_declarations.iter().find(|x| x.name() == name && x.arity() == arity)
{ {
Some(declaration) => std::rc::Rc::clone(&declaration), Some(declaration) => std::rc::Rc::clone(&declaration),
None => None =>
{ {
let declaration = crate::FunctionDeclaration let declaration = F::FunctionDeclaration::new(name.to_string(), arity);
{
name: name.to_string(),
arity,
};
let declaration = std::rc::Rc::new(declaration); let declaration = std::rc::Rc::new(declaration);
function_declarations.insert(std::rc::Rc::clone(&declaration)); function_declarations.insert(std::rc::Rc::clone(&declaration));
@ -185,23 +200,21 @@ impl FindOrCreateFunctionDeclaration for Declarations
} }
} }
impl FindOrCreatePredicateDeclaration for Declarations impl<F> FindOrCreatePredicateDeclaration<F> for Declarations<F>
where
F: crate::flavor::Flavor,
{ {
fn find_or_create_predicate_declaration(&self, name: &str, arity: usize) fn find_or_create_predicate_declaration(&self, name: &str, arity: usize)
-> std::rc::Rc<crate::PredicateDeclaration> -> std::rc::Rc<F::PredicateDeclaration>
{ {
let mut predicate_declarations = self.predicate_declarations.borrow_mut(); let mut predicate_declarations = self.predicate_declarations.borrow_mut();
match predicate_declarations.iter().find(|x| x.name == name && x.arity == arity) match predicate_declarations.iter().find(|x| x.name() == name && x.arity() == arity)
{ {
Some(declaration) => std::rc::Rc::clone(&declaration), Some(declaration) => std::rc::Rc::clone(&declaration),
None => None =>
{ {
let declaration = crate::PredicateDeclaration let declaration = F::PredicateDeclaration::new(name.to_string(), arity);
{
name: name.to_string(),
arity,
};
let declaration = std::rc::Rc::new(declaration); let declaration = std::rc::Rc::new(declaration);
predicate_declarations.insert(std::rc::Rc::clone(&declaration)); predicate_declarations.insert(std::rc::Rc::clone(&declaration));