Refactoring

This commit is contained in:
Patrick Lühne 2020-02-01 21:59:36 +01:00
parent 24980d5a8d
commit 86c8391278
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
3 changed files with 153 additions and 84 deletions

View File

@ -1,61 +1,122 @@
pub(crate) trait FindOrCreateFunctionDeclaration = FnMut(&str, usize) pub(crate) trait FindOrCreateFunctionDeclaration
-> std::rc::Rc<foliage::FunctionDeclaration>;
pub(crate) trait FindOrCreatePredicateDeclaration = FnMut(&str, usize)
-> std::rc::Rc<foliage::PredicateDeclaration>;
pub(crate) trait FindOrCreateVariableDeclaration = FnMut(&str)
-> std::rc::Rc<foliage::VariableDeclaration>;
pub(crate) fn find_or_create_predicate_declaration(predicate_declarations: &mut foliage::PredicateDeclarations,
name: &str, arity: usize)
-> std::rc::Rc<foliage::PredicateDeclaration>
{ {
match predicate_declarations.iter() fn find_or_create(&mut self, name: &str, arity: usize)
.find(|x| x.name == name && x.arity == arity) -> std::rc::Rc<foliage::FunctionDeclaration>;
}
pub(crate) trait FindOrCreatePredicateDeclaration
{
fn find_or_create(&mut self, name: &str, arity: usize)
-> std::rc::Rc<foliage::PredicateDeclaration>;
}
pub(crate) trait FindOrCreateVariableDeclaration
{
fn find_or_create(&mut self, name: &str)
-> std::rc::Rc<foliage::VariableDeclaration>;
}
impl FindOrCreateFunctionDeclaration for foliage::FunctionDeclarations
{
fn find_or_create(&mut self, name: &str, arity: usize)
-> std::rc::Rc<foliage::FunctionDeclaration>
{ {
Some(value) => std::rc::Rc::clone(value), match self.iter()
None => .find(|x| x.name == name && x.arity == arity)
{ {
let declaration = foliage::PredicateDeclaration Some(value) => std::rc::Rc::clone(value),
None =>
{ {
name: name.to_owned(), let declaration = foliage::FunctionDeclaration
arity, {
}; name: name.to_owned(),
let declaration = std::rc::Rc::new(declaration); arity,
};
let declaration = std::rc::Rc::new(declaration);
predicate_declarations.insert(std::rc::Rc::clone(&declaration)); self.insert(std::rc::Rc::clone(&declaration));
log::debug!("new predicate declaration: {}/{}", name, arity); log::debug!("new function declaration: {}/{}", name, arity);
declaration declaration
}, },
}
} }
} }
pub(crate) fn find_or_create_function_declaration(function_declarations: &mut foliage::FunctionDeclarations, impl FindOrCreatePredicateDeclaration for foliage::PredicateDeclarations
name: &str, arity: usize)
-> std::rc::Rc<foliage::FunctionDeclaration>
{ {
match function_declarations.iter() fn find_or_create(&mut self, name: &str, arity: usize)
.find(|x| x.name == name && x.arity == arity) -> std::rc::Rc<foliage::PredicateDeclaration>
{ {
Some(value) => std::rc::Rc::clone(value), match self.iter()
None => .find(|x| x.name == name && x.arity == arity)
{ {
let declaration = foliage::FunctionDeclaration Some(value) => std::rc::Rc::clone(value),
None =>
{ {
name: name.to_owned(), let declaration = foliage::PredicateDeclaration
arity, {
name: name.to_owned(),
arity,
};
let declaration = std::rc::Rc::new(declaration);
self.insert(std::rc::Rc::clone(&declaration));
log::debug!("new predicate declaration: {}/{}", name, arity);
declaration
},
}
}
}
impl FindOrCreateVariableDeclaration for foliage::VariableDeclarationStack
{
fn find_or_create(&mut self, name: &str)
-> std::rc::Rc<foliage::VariableDeclaration>
{
// TODO: check correctness
if name == "_"
{
let variable_declaration = foliage::VariableDeclaration
{
name: "_".to_owned(),
}; };
let declaration = std::rc::Rc::new(declaration); let variable_declaration = std::rc::Rc::new(variable_declaration);
function_declarations.insert(std::rc::Rc::clone(&declaration)); self.free_variable_declarations.insert(
std::rc::Rc::clone(&variable_declaration));
log::debug!("new function declaration: {}/{}", name, arity); return variable_declaration;
}
declaration self.find_or_create(name)
}, }
}
pub(crate) fn translate_binary_operator(binary_operator: clingo::ast::BinaryOperator)
-> Result<foliage::BinaryOperator, crate::Error>
{
match binary_operator
{
clingo::ast::BinaryOperator::And
| clingo::ast::BinaryOperator::Or
| clingo::ast::BinaryOperator::Xor
=> return Err(crate::Error::new_unsupported_language_feature("binary logical operators")),
clingo::ast::BinaryOperator::Plus
=> Ok(foliage::BinaryOperator::Addition),
clingo::ast::BinaryOperator::Minus
=> Ok(foliage::BinaryOperator::Subtraction),
clingo::ast::BinaryOperator::Multiplication
=> Ok(foliage::BinaryOperator::Multiplication),
clingo::ast::BinaryOperator::Division
=> Ok(foliage::BinaryOperator::Division),
clingo::ast::BinaryOperator::Modulo
=> Ok(foliage::BinaryOperator::Modulo),
clingo::ast::BinaryOperator::Power
=> Ok(foliage::BinaryOperator::Exponentiation),
} }
} }
@ -96,13 +157,11 @@ pub(crate) fn choose_value_in_primitive(term: Box<foliage::Term>,
} }
} }
pub(crate) fn choose_value_in_term<F1, F2>(term: &clingo::ast::Term, pub(crate) fn choose_value_in_term(term: &clingo::ast::Term,
variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>, variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>,
mut find_or_create_function_declaration: F1, mut find_or_create_variable_declaration: F2) function_declarations: &mut foliage::FunctionDeclarations,
variable_declaration_stack: &mut foliage::VariableDeclarationStack)
-> Result<foliage::Formula, crate::Error> -> Result<foliage::Formula, crate::Error>
where
F1: FindOrCreateFunctionDeclaration,
F2: FindOrCreateVariableDeclaration,
{ {
match term.term_type() match term.term_type()
{ {
@ -139,7 +198,7 @@ where
let constant_name = symbol.name() let constant_name = symbol.name()
.map_err(|error| crate::Error::new_logic("clingo error").with(error))?; .map_err(|error| crate::Error::new_logic("clingo error").with(error))?;
let constant_declaration = find_or_create_function_declaration(constant_name, 0); let constant_declaration = function_declarations.find_or_create(constant_name, 0);
let function = foliage::Term::Function(foliage::Function let function = foliage::Term::Function(foliage::Function
{ {
@ -150,8 +209,18 @@ where
Ok(foliage::Formula::Comparison(choose_value_in_primitive(Box::new(function), variable_declaration))) Ok(foliage::Formula::Comparison(choose_value_in_primitive(Box::new(function), variable_declaration)))
} }
}, },
clingo::ast::TermType::Variable(variable) => clingo::ast::TermType::Variable(variable_name) =>
Err(crate::Error::new_not_yet_implemented("todo")), {
let other_variable_declaration = variable_declaration_stack.find_or_create(variable_name);
let other_variable = foliage::Term::Variable(foliage::Variable
{
declaration: other_variable_declaration,
});
Ok(foliage::Formula::Comparison(choose_value_in_primitive(Box::new(other_variable),
variable_declaration)))
},
_ => Err(crate::Error::new_not_yet_implemented("todo")), _ => Err(crate::Error::new_not_yet_implemented("todo")),
} }
} }

View File

@ -12,31 +12,32 @@ pub struct ScopedFormula
pub struct Definitions pub struct Definitions
{ {
head_atom_parameters: foliage::VariableDeclarations, head_atom_parameters: std::rc::Rc<foliage::VariableDeclarations>,
definitions: Vec<ScopedFormula>, definitions: Vec<ScopedFormula>,
} }
pub fn read(rule: &clingo::ast::Rule) -> Result<(), crate::Error> pub fn read(rule: &clingo::ast::Rule) -> Result<(), crate::Error>
{ {
use super::common::FindOrCreatePredicateDeclaration;
let mut function_declarations = foliage::FunctionDeclarations::new(); let mut function_declarations = foliage::FunctionDeclarations::new();
let mut predicate_declarations = foliage::PredicateDeclarations::new(); let mut predicate_declarations = foliage::PredicateDeclarations::new();
let mut variable_declaration_stack = foliage::VariableDeclarationStack::new(); let mut variable_declaration_stack = foliage::VariableDeclarationStack::new();
let head_type = determine_head_type(rule.head(), let head_type = determine_head_type(rule.head(),
|name, arity| super::common::find_or_create_predicate_declaration( |name, arity| predicate_declarations.find_or_create(name, arity))?;
&mut predicate_declarations, name, arity))?;
let mut definitions let mut definitions
= std::collections::BTreeMap::<std::rc::Rc<foliage::PredicateDeclaration>, Definitions>::new(); = std::collections::BTreeMap::<std::rc::Rc<foliage::PredicateDeclaration>, Definitions>::new();
let declare_predicate_parameters = |predicate_declaration: &foliage::PredicateDeclaration| let declare_predicate_parameters = |predicate_declaration: &foliage::PredicateDeclaration|
{ {
(0..predicate_declaration.arity) std::rc::Rc::new((0..predicate_declaration.arity)
.map(|_| std::rc::Rc::new(foliage::VariableDeclaration .map(|_| std::rc::Rc::new(foliage::VariableDeclaration
{ {
name: "<anonymous>".to_string(), name: "<anonymous>".to_string(),
})) }))
.collect() .collect())
}; };
match head_type match head_type
@ -54,8 +55,15 @@ pub fn read(rule: &clingo::ast::Rule) -> Result<(), crate::Error>
} }
let definitions = definitions.get(&head_atom.predicate_declaration).unwrap(); let definitions = definitions.get(&head_atom.predicate_declaration).unwrap();
variable_declaration_stack.push(std::rc::Rc::clone(&definitions.head_atom_parameters));
let translated_body = translate_body(rule.body(), &mut function_declarations,
&mut predicate_declarations, &mut variable_declaration_stack);
variable_declaration_stack.pop();
}, },
HeadType::ChoiceWithSingleAtom(test) => HeadType::ChoiceWithSingleAtom(_) =>
log::debug!("translating choice rule with single atom"), log::debug!("translating choice rule with single atom"),
HeadType::IntegrityConstraint => HeadType::IntegrityConstraint =>
log::debug!("translating integrity constraint"), log::debug!("translating integrity constraint"),

View File

@ -1,12 +1,11 @@
pub(crate) fn translate_body_term<F1, F2, F3>(body_term: &clingo::ast::Term, sign: clingo::ast::Sign, pub(crate) fn translate_body_term(body_term: &clingo::ast::Term, sign: clingo::ast::Sign,
mut find_or_create_function_declaration: F1, mut find_or_create_predicate_declaration: F2, mut function_declarations: &mut foliage::FunctionDeclarations,
mut find_or_create_variable_declaration: F3) predicate_declarations: &mut foliage::PredicateDeclarations,
mut variable_declaration_stack: &mut foliage::VariableDeclarationStack)
-> Result<foliage::Formula, crate::Error> -> Result<foliage::Formula, crate::Error>
where
F1: crate::translate::common::FindOrCreateFunctionDeclaration,
F2: crate::translate::common::FindOrCreatePredicateDeclaration,
F3: crate::translate::common::FindOrCreateVariableDeclaration,
{ {
use crate::translate::common::FindOrCreatePredicateDeclaration;
let function = match body_term.term_type() let function = match body_term.term_type()
{ {
clingo::ast::TermType::Function(value) => value, clingo::ast::TermType::Function(value) => value,
@ -15,7 +14,7 @@ where
let function_name = function.name().map_err(|error| crate::Error::new_decode_identifier(error))?; let function_name = function.name().map_err(|error| crate::Error::new_decode_identifier(error))?;
let predicate_declaration = find_or_create_predicate_declaration(function_name, let predicate_declaration = predicate_declarations.find_or_create(function_name,
function.arguments().len()); function.arguments().len());
let parameters = function.arguments().iter().map(|_| std::rc::Rc::new( let parameters = function.arguments().iter().map(|_| std::rc::Rc::new(
@ -54,7 +53,7 @@ where
let mut arguments = function.arguments().iter().map(|x| let mut arguments = function.arguments().iter().map(|x|
{ {
let result = crate::translate::common::choose_value_in_term(x, &parameters[i], let result = crate::translate::common::choose_value_in_term(x, &parameters[i],
&mut find_or_create_function_declaration, &mut find_or_create_variable_declaration) &mut function_declarations, &mut variable_declaration_stack)
.map(|x| Box::new(x)); .map(|x| Box::new(x));
i += 1; i += 1;
result result
@ -72,14 +71,11 @@ where
})) }))
} }
pub(crate) fn translate_body_literal<F1, F2, F3>(body_literal: &clingo::ast::BodyLiteral, pub(crate) fn translate_body_literal(body_literal: &clingo::ast::BodyLiteral,
mut find_or_create_function_declaration: F1, mut find_or_create_predicate_declaration: F2, mut function_declarations: &mut foliage::FunctionDeclarations,
mut find_or_create_variable_declaration: F3) mut predicate_declarations: &mut foliage::PredicateDeclarations,
mut variable_declaration_stack: &mut foliage::VariableDeclarationStack)
-> Result<foliage::Formula, crate::Error> -> Result<foliage::Formula, crate::Error>
where
F1: crate::translate::common::FindOrCreateFunctionDeclaration,
F2: crate::translate::common::FindOrCreatePredicateDeclaration,
F3: crate::translate::common::FindOrCreateVariableDeclaration,
{ {
match body_literal.sign() match body_literal.sign()
{ {
@ -108,8 +104,8 @@ where
Ok(foliage::Formula::Boolean(value)) Ok(foliage::Formula::Boolean(value))
}, },
clingo::ast::LiteralType::Symbolic(term) => translate_body_term(term, literal.sign(), clingo::ast::LiteralType::Symbolic(term) => translate_body_term(term, literal.sign(),
&mut find_or_create_function_declaration, &mut find_or_create_predicate_declaration, &mut function_declarations, &mut predicate_declarations,
&mut find_or_create_variable_declaration), &mut variable_declaration_stack),
clingo::ast::LiteralType::Comparison(comparison) => clingo::ast::LiteralType::Comparison(comparison) =>
{ {
let new_variable_declaration = || std::rc::Rc::new(foliage::VariableDeclaration let new_variable_declaration = || std::rc::Rc::new(foliage::VariableDeclaration
@ -123,9 +119,9 @@ where
let parameter_z2 = &parameters[1]; let parameter_z2 = &parameters[1];
let choose_z1_in_t1 = crate::translate::common::choose_value_in_term(comparison.left(), &parameter_z1, let choose_z1_in_t1 = crate::translate::common::choose_value_in_term(comparison.left(), &parameter_z1,
&mut find_or_create_function_declaration, &mut find_or_create_variable_declaration)?; &mut function_declarations, &mut variable_declaration_stack)?;
let choose_z2_in_t2 = crate::translate::common::choose_value_in_term(comparison.right(), &parameter_z2, let choose_z2_in_t2 = crate::translate::common::choose_value_in_term(comparison.right(), &parameter_z2,
&mut find_or_create_function_declaration, &mut find_or_create_variable_declaration)?; &mut function_declarations, &mut variable_declaration_stack)?;
let variable_1 = foliage::Variable let variable_1 = foliage::Variable
{ {
@ -161,19 +157,15 @@ where
} }
} }
pub(crate) fn translate_body<F1, F2, F3>(body_literals: &[clingo::ast::BodyLiteral], pub(crate) fn translate_body(body_literals: &[clingo::ast::BodyLiteral],
mut find_or_create_function_declaration: F1, mut find_or_create_predicate_declaration: F2, mut function_declaration: &mut foliage::FunctionDeclarations,
mut find_or_create_variable_declaration: F3) mut predicate_declaration: &mut foliage::PredicateDeclarations,
mut variable_declaration_stack: &mut foliage::VariableDeclarationStack)
-> Result<foliage::Formulas, crate::Error> -> Result<foliage::Formulas, crate::Error>
where
F1: crate::translate::common::FindOrCreateFunctionDeclaration,
F2: crate::translate::common::FindOrCreatePredicateDeclaration,
F3: crate::translate::common::FindOrCreateVariableDeclaration,
{ {
body_literals.iter() body_literals.iter()
.map(|body_literal| translate_body_literal(body_literal, .map(|body_literal| translate_body_literal(body_literal, &mut function_declaration,
&mut find_or_create_function_declaration, &mut find_or_create_predicate_declaration, &mut predicate_declaration, &mut variable_declaration_stack)
&mut find_or_create_variable_declaration)
.map(|value| Box::new(value))) .map(|value| Box::new(value)))
.collect::<Result<foliage::Formulas, crate::Error>>() .collect::<Result<foliage::Formulas, crate::Error>>()
} }