Refactoring to support TPTP output

This commit is contained in:
Patrick Lühne 2020-02-03 02:57:45 +01:00
parent 0714bed2cc
commit 072fa34e69
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
6 changed files with 467 additions and 218 deletions

View File

@ -1,53 +1,31 @@
pub(crate) struct VariableDeclarationDisplay<'a> pub(crate) struct DomainDisplay
{ {
variable_declaration: &'a foliage::VariableDeclaration, domain: crate::translate::common::Domain,
} }
pub(crate) struct TermDisplay<'a> pub(crate) fn display_domain(domain: crate::translate::common::Domain) -> DomainDisplay
{ {
term: &'a foliage::Term, DomainDisplay
}
pub(crate) struct FormulaDisplay<'a>
{
formula: &'a foliage::Formula,
}
pub(crate) fn display_variable_declaration<'a>(variable_declaration: &'a foliage::VariableDeclaration)
-> VariableDeclarationDisplay<'a>
{
VariableDeclarationDisplay
{ {
variable_declaration, domain,
} }
} }
pub(crate) fn display_term<'a>(term: &'a foliage::Term) -> TermDisplay<'a> impl std::fmt::Debug for DomainDisplay
{
TermDisplay
{
term,
}
}
pub(crate) fn display_formula<'a>(formula: &'a foliage::Formula)
-> FormulaDisplay<'a>
{
FormulaDisplay
{
formula,
}
}
impl<'a> std::fmt::Debug for VariableDeclarationDisplay<'a>
{ {
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
{ {
write!(format, "{}", &self.variable_declaration.name) let domain_name = match self.domain
{
crate::translate::common::Domain::Integer => "$int",
crate::translate::common::Domain::Program => "object",
};
write!(format, "{}", domain_name)
} }
} }
impl<'a> std::fmt::Display for VariableDeclarationDisplay<'a> impl std::fmt::Display for DomainDisplay
{ {
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
{ {
@ -55,10 +33,107 @@ impl<'a> std::fmt::Display for VariableDeclarationDisplay<'a>
} }
} }
impl<'a> std::fmt::Debug for TermDisplay<'a> pub(crate) struct VariableDeclarationDisplay<'a, 'b, C>
where
C: crate::translate::common::VariableDeclarationDomain
+ crate::translate::common::VariableDeclarationID
{
variable_declaration: &'a std::rc::Rc<foliage::VariableDeclaration>,
context: &'b C,
}
pub(crate) fn display_variable_declaration<'a, 'b, C>(
variable_declaration: &'a std::rc::Rc<foliage::VariableDeclaration>, context: &'b C)
-> VariableDeclarationDisplay<'a, 'b, C>
where
C: crate::translate::common::VariableDeclarationDomain
+ crate::translate::common::VariableDeclarationID
{
VariableDeclarationDisplay
{
variable_declaration,
context,
}
}
pub(crate) struct TermDisplay<'a, 'b, C>
{
term: &'a foliage::Term,
context: &'b C,
}
pub(crate) fn display_term<'a, 'b, C>(term: &'a foliage::Term, context: &'b C)
-> TermDisplay<'a, 'b, C>
where
C: crate::translate::common::VariableDeclarationDomain
+ crate::translate::common::VariableDeclarationID
{
TermDisplay
{
term,
context,
}
}
pub(crate) struct FormulaDisplay<'a, 'b, C>
{
formula: &'a foliage::Formula,
context: &'b C,
}
pub(crate) fn display_formula<'a, 'b, C>(formula: &'a foliage::Formula, context: &'b C)
-> FormulaDisplay<'a, 'b, C>
{
FormulaDisplay
{
formula,
context,
}
}
impl<'a, 'b, C> std::fmt::Debug for VariableDeclarationDisplay<'a, 'b, C>
where
C: crate::translate::common::VariableDeclarationDomain
+ crate::translate::common::VariableDeclarationID
{ {
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
{ {
let id = self.context.variable_declaration_id(self.variable_declaration);
let domain = self.context.variable_declaration_domain(self.variable_declaration)
.expect("unspecified variable domain");
let prefix = match domain
{
crate::translate::common::Domain::Integer => "N",
crate::translate::common::Domain::Program => "X",
};
write!(format, "{}{}", prefix, id + 1)
}
}
impl<'a, 'b, C> std::fmt::Display for VariableDeclarationDisplay<'a, 'b, C>
where
C: crate::translate::common::VariableDeclarationDomain
+ crate::translate::common::VariableDeclarationID
{
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
{
write!(format, "{:?}", &self)
}
}
impl<'a, 'b, C> std::fmt::Debug for TermDisplay<'a, 'b, C>
where
C: crate::translate::common::VariableDeclarationDomain
+ crate::translate::common::VariableDeclarationID
{
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
{
let display_variable_declaration = |variable_declaration|
display_variable_declaration(variable_declaration, self.context);
let display_term = |term| display_term(term, self.context);
match &self.term match &self.term
{ {
foliage::Term::Boolean(true) => write!(format, "$true"), foliage::Term::Boolean(true) => write!(format, "$true"),
@ -119,7 +194,10 @@ impl<'a> std::fmt::Debug for TermDisplay<'a>
} }
} }
impl<'term> std::fmt::Display for TermDisplay<'term> impl<'a, 'b, C> std::fmt::Display for TermDisplay<'a, 'b, C>
where
C: crate::translate::common::VariableDeclarationDomain
+ crate::translate::common::VariableDeclarationID
{ {
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
{ {
@ -127,10 +205,18 @@ impl<'term> std::fmt::Display for TermDisplay<'term>
} }
} }
impl<'formula> std::fmt::Debug for FormulaDisplay<'formula> impl<'a, 'b, C> std::fmt::Debug for FormulaDisplay<'a, 'b, C>
where
C: crate::translate::common::VariableDeclarationDomain
+ crate::translate::common::VariableDeclarationID
{ {
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
{ {
let display_variable_declaration = |variable_declaration|
display_variable_declaration(variable_declaration, self.context);
let display_term = |term| display_term(term, self.context);
let display_formula = |formula| display_formula(formula, self.context);
match &self.formula match &self.formula
{ {
foliage::Formula::Exists(exists) => foliage::Formula::Exists(exists) =>
@ -141,7 +227,11 @@ impl<'formula> std::fmt::Debug for FormulaDisplay<'formula>
for parameter in exists.parameters.iter() for parameter in exists.parameters.iter()
{ {
write!(format, "{}{:?}", separator, display_variable_declaration(parameter))?; let parameter_domain = self.context.variable_declaration_domain(parameter)
.expect("unspecified variable domain");
write!(format, "{}{:?}: {}", separator, display_variable_declaration(parameter),
display_domain(parameter_domain))?;
separator = ", " separator = ", "
} }
@ -156,7 +246,11 @@ impl<'formula> std::fmt::Debug for FormulaDisplay<'formula>
for parameter in for_all.parameters.iter() for parameter in for_all.parameters.iter()
{ {
write!(format, "{}{:?}", separator, display_variable_declaration(parameter))?; let parameter_domain = self.context.variable_declaration_domain(parameter)
.expect("unspecified variable domain");
write!(format, "{}{:?}: {}", separator, display_variable_declaration(parameter),
display_domain(parameter_domain))?;
separator = ", " separator = ", "
} }
@ -199,7 +293,8 @@ impl<'formula> std::fmt::Debug for FormulaDisplay<'formula>
write!(format, ")")?; write!(format, ")")?;
}, },
foliage::Formula::Implies(foliage::Implies{antecedent, implication}) foliage::Formula::Implies(foliage::Implies{antecedent, implication})
=> write!(format, "({:?} => {:?})", display_formula(antecedent), display_formula(implication))?, => write!(format, "({:?} => {:?})", display_formula(antecedent),
display_formula(implication))?,
foliage::Formula::IfAndOnlyIf(foliage::IfAndOnlyIf{left, right}) foliage::Formula::IfAndOnlyIf(foliage::IfAndOnlyIf{left, right})
=> write!(format, "({:?} <=> {:?})", display_formula(left), display_formula(right))?, => write!(format, "({:?} <=> {:?})", display_formula(left), display_formula(right))?,
foliage::Formula::Compare(foliage::Compare{operator: foliage::ComparisonOperator::Less, left, right}) foliage::Formula::Compare(foliage::Compare{operator: foliage::ComparisonOperator::Less, left, right})
@ -242,7 +337,10 @@ impl<'formula> std::fmt::Debug for FormulaDisplay<'formula>
} }
} }
impl<'formula> std::fmt::Display for FormulaDisplay<'formula> impl<'a, 'b, C> std::fmt::Display for FormulaDisplay<'a, 'b, C>
where
C: crate::translate::common::VariableDeclarationDomain
+ crate::translate::common::VariableDeclarationID
{ {
fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result fn fmt(&self, format: &mut std::fmt::Formatter) -> std::fmt::Result
{ {

View File

@ -1,2 +1,2 @@
mod common; pub(crate) mod common;
pub mod verify_properties; pub mod verify_properties;

View File

@ -1,89 +1,46 @@
pub(crate) trait FindOrCreateFunctionDeclaration #[derive(Clone, Copy, Debug, PartialEq)]
pub(crate) enum Domain
{ {
fn find_or_create(&mut self, name: &str, arity: usize) Program,
Integer,
}
pub(crate) trait AssignVariableDeclarationDomain
{
fn assign_variable_declaration_domain(&self,
variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>, domain: Domain);
}
pub(crate) trait VariableDeclarationDomain
{
fn variable_declaration_domain(&self,
variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>) -> Option<Domain>;
}
pub(crate) trait VariableDeclarationID
{
fn variable_declaration_id(&self,
variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>) -> usize;
}
pub(crate) trait GetOrCreateFunctionDeclaration
{
fn get_or_create_function_declaration(&self, name: &str, arity: usize)
-> std::rc::Rc<foliage::FunctionDeclaration>; -> std::rc::Rc<foliage::FunctionDeclaration>;
} }
pub(crate) trait FindOrCreatePredicateDeclaration pub(crate) trait GetOrCreatePredicateDeclaration
{ {
fn find_or_create(&mut self, name: &str, arity: usize) fn get_or_create_predicate_declaration(&self, name: &str, arity: usize)
-> std::rc::Rc<foliage::PredicateDeclaration>; -> std::rc::Rc<foliage::PredicateDeclaration>;
} }
pub(crate) trait FindOrCreateVariableDeclaration pub(crate) trait GetOrCreateVariableDeclaration
{ {
fn find_or_create(&mut self, name: &str) fn get_or_create_variable_declaration(&self, name: &str)
-> std::rc::Rc<foliage::VariableDeclaration>; -> 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>
{
match self.iter()
.find(|x| x.name == name && x.arity == arity)
{
Some(value) => std::rc::Rc::clone(value),
None =>
{
let declaration = std::rc::Rc::new(foliage::FunctionDeclaration::new(
name.to_string(), arity));
self.insert(std::rc::Rc::clone(&declaration));
log::debug!("new function declaration: {}/{}", name, arity);
declaration
},
}
}
}
impl FindOrCreatePredicateDeclaration for foliage::PredicateDeclarations
{
fn find_or_create(&mut self, name: &str, arity: usize)
-> std::rc::Rc<foliage::PredicateDeclaration>
{
match self.iter()
.find(|x| x.name == name && x.arity == arity)
{
Some(value) => std::rc::Rc::clone(value),
None =>
{
let declaration = std::rc::Rc::new(foliage::PredicateDeclaration::new(
name.to_string(), arity));
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 = std::rc::Rc::new(foliage::VariableDeclaration::new(
"_".to_owned()));
self.free_variable_declarations.push(std::rc::Rc::clone(&variable_declaration));
return variable_declaration;
}
self.find_or_create(name)
}
}
pub(crate) fn translate_binary_operator(binary_operator: clingo::ast::BinaryOperator) pub(crate) fn translate_binary_operator(binary_operator: clingo::ast::BinaryOperator)
-> Result<foliage::BinaryOperator, crate::Error> -> Result<foliage::BinaryOperator, crate::Error>
{ {
@ -137,11 +94,13 @@ pub(crate) fn choose_value_in_primitive(term: Box<foliage::Term>,
foliage::Formula::equal(Box::new(variable), term) foliage::Formula::equal(Box::new(variable), term)
} }
pub(crate) fn choose_value_in_term(term: &clingo::ast::Term, pub(crate) fn choose_value_in_term<C>(term: &clingo::ast::Term,
variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>, variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>, context: &C)
mut function_declarations: &mut foliage::FunctionDeclarations,
mut variable_declaration_stack: &mut foliage::VariableDeclarationStack)
-> Result<foliage::Formula, crate::Error> -> Result<foliage::Formula, crate::Error>
where
C: crate::translate::common::GetOrCreateFunctionDeclaration
+ crate::translate::common::GetOrCreateVariableDeclaration
+ crate::translate::common::AssignVariableDeclarationDomain
{ {
match term.term_type() match term.term_type()
{ {
@ -176,7 +135,7 @@ pub(crate) fn choose_value_in_term(term: &clingo::ast::Term,
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 = function_declarations.find_or_create(constant_name, 0); let constant_declaration = context.get_or_create_function_declaration(constant_name, 0);
let function = foliage::Term::function(&constant_declaration, vec![]); let function = foliage::Term::function(&constant_declaration, vec![]);
Ok(choose_value_in_primitive(Box::new(function), variable_declaration)) Ok(choose_value_in_primitive(Box::new(function), variable_declaration))
@ -184,7 +143,10 @@ pub(crate) fn choose_value_in_term(term: &clingo::ast::Term,
}, },
clingo::ast::TermType::Variable(variable_name) => clingo::ast::TermType::Variable(variable_name) =>
{ {
let other_variable_declaration = variable_declaration_stack.find_or_create(variable_name); let other_variable_declaration = context.get_or_create_variable_declaration(
variable_name);
context.assign_variable_declaration_domain(&other_variable_declaration,
Domain::Program);
let other_variable = foliage::Term::variable(&other_variable_declaration); let other_variable = foliage::Term::variable(&other_variable_declaration);
Ok(choose_value_in_primitive(Box::new(other_variable), variable_declaration)) Ok(choose_value_in_primitive(Box::new(other_variable), variable_declaration))
@ -201,8 +163,14 @@ pub(crate) fn choose_value_in_term(term: &clingo::ast::Term,
| foliage::BinaryOperator::Multiply | foliage::BinaryOperator::Multiply
=> =>
{ {
let parameters = (0..2).map(|_| std::rc::Rc::new( let parameters = (0..2).map(|_|
foliage::VariableDeclaration::new("<anonymous>".to_string()))) {
let variable_declaration = std::rc::Rc::new(
foliage::VariableDeclaration::new("<anonymous>".to_string()));
context.assign_variable_declaration_domain(&variable_declaration,
Domain::Integer);
variable_declaration
})
.collect::<foliage::VariableDeclarations>(); .collect::<foliage::VariableDeclarations>();
let parameters = std::rc::Rc::new(parameters); let parameters = std::rc::Rc::new(parameters);
@ -218,12 +186,10 @@ pub(crate) fn choose_value_in_term(term: &clingo::ast::Term,
Box::new(translated_binary_operation)); Box::new(translated_binary_operation));
let choose_value_from_left_argument = choose_value_in_term( let choose_value_from_left_argument = choose_value_in_term(
binary_operation.left(), &parameter_1, &mut function_declarations, binary_operation.left(), &parameter_1, context)?;
&mut variable_declaration_stack)?;
let choose_value_from_right_argument = choose_value_in_term( let choose_value_from_right_argument = choose_value_in_term(
binary_operation.right(), &parameter_2, &mut function_declarations, binary_operation.right(), &parameter_2, context)?;
&mut variable_declaration_stack)?;
let and = foliage::Formula::And(vec![Box::new(equals), let and = foliage::Formula::And(vec![Box::new(equals),
Box::new(choose_value_from_left_argument), Box::new(choose_value_from_left_argument),
@ -235,8 +201,14 @@ pub(crate) fn choose_value_in_term(term: &clingo::ast::Term,
| foliage::BinaryOperator::Modulo | foliage::BinaryOperator::Modulo
=> =>
{ {
let parameters = (0..4).map(|_| std::rc::Rc::new( let parameters = (0..4).map(|_|
foliage::VariableDeclaration::new("<anonymous>".to_string()))) {
let variable_declaration = std::rc::Rc::new(
foliage::VariableDeclaration::new("<anonymous>".to_string()));
context.assign_variable_declaration_domain(&variable_declaration,
Domain::Integer);
variable_declaration
})
.collect::<foliage::VariableDeclarations>(); .collect::<foliage::VariableDeclarations>();
let parameters = std::rc::Rc::new(parameters); let parameters = std::rc::Rc::new(parameters);
@ -256,10 +228,10 @@ pub(crate) fn choose_value_in_term(term: &clingo::ast::Term,
Box::new(foliage::Term::variable(parameter_j)), Box::new(j_times_q_plus_r)); Box::new(foliage::Term::variable(parameter_j)), Box::new(j_times_q_plus_r));
let choose_i_in_t1 = choose_value_in_term(binary_operation.left(), parameter_i, let choose_i_in_t1 = choose_value_in_term(binary_operation.left(), parameter_i,
&mut function_declarations, &mut variable_declaration_stack)?; context)?;
let choose_i_in_t2 = choose_value_in_term(binary_operation.left(), parameter_j, let choose_i_in_t2 = choose_value_in_term(binary_operation.left(), parameter_j,
&mut function_declarations, &mut variable_declaration_stack)?; context)?;
let j_not_equal_to_0 = foliage::Formula::not_equal( let j_not_equal_to_0 = foliage::Formula::not_equal(
Box::new(foliage::Term::variable(parameter_j)), Box::new(foliage::Term::variable(parameter_j)),
@ -295,7 +267,8 @@ pub(crate) fn choose_value_in_term(term: &clingo::ast::Term,
Ok(foliage::Formula::exists(parameters, Box::new(and))) Ok(foliage::Formula::exists(parameters, Box::new(and)))
}, },
_ => Err(crate::Error::new_not_yet_implemented("todo")), foliage::BinaryOperator::Exponentiate =>
Err(crate::Error::new_unsupported_language_feature("exponentiation")),
} }
}, },
clingo::ast::TermType::UnaryOperation(unary_operation) => clingo::ast::TermType::UnaryOperation(unary_operation) =>
@ -308,6 +281,7 @@ pub(crate) fn choose_value_in_term(term: &clingo::ast::Term,
{ {
let parameter_z_prime = std::rc::Rc::new(foliage::VariableDeclaration::new( let parameter_z_prime = std::rc::Rc::new(foliage::VariableDeclaration::new(
"<anonymous>".to_string())); "<anonymous>".to_string()));
context.assign_variable_declaration_domain(&parameter_z_prime, Domain::Integer);
let negative_z_prime = foliage::Term::negative(Box::new( let negative_z_prime = foliage::Term::negative(Box::new(
foliage::Term::variable(&parameter_z_prime))); foliage::Term::variable(&parameter_z_prime)));
@ -316,8 +290,7 @@ pub(crate) fn choose_value_in_term(term: &clingo::ast::Term,
Box::new(negative_z_prime)); Box::new(negative_z_prime));
let choose_z_prime_in_t_prime = choose_value_in_term(unary_operation.argument(), let choose_z_prime_in_t_prime = choose_value_in_term(unary_operation.argument(),
&parameter_z_prime, &mut function_declarations, &parameter_z_prime, context)?;
&mut variable_declaration_stack)?;
let and = foliage::Formula::and(vec![Box::new(equals), let and = foliage::Formula::and(vec![Box::new(equals),
Box::new(choose_z_prime_in_t_prime)]); Box::new(choose_z_prime_in_t_prime)]);
@ -331,8 +304,14 @@ pub(crate) fn choose_value_in_term(term: &clingo::ast::Term,
}, },
clingo::ast::TermType::Interval(interval) => clingo::ast::TermType::Interval(interval) =>
{ {
let parameters = (0..3).map(|_| std::rc::Rc::new( let parameters = (0..3).map(|_|
foliage::VariableDeclaration::new("<anonymous>".to_string()))) {
let variable_declaration = std::rc::Rc::new(
foliage::VariableDeclaration::new("<anonymous>".to_string()));
context.assign_variable_declaration_domain(&variable_declaration,
Domain::Integer);
variable_declaration
})
.collect::<foliage::VariableDeclarations>(); .collect::<foliage::VariableDeclarations>();
let parameters = std::rc::Rc::new(parameters); let parameters = std::rc::Rc::new(parameters);
@ -340,11 +319,9 @@ pub(crate) fn choose_value_in_term(term: &clingo::ast::Term,
let parameter_j = &parameters[1]; let parameter_j = &parameters[1];
let parameter_k = &parameters[2]; let parameter_k = &parameters[2];
let choose_i_in_t_1 = choose_value_in_term(interval.left(), parameter_i, let choose_i_in_t_1 = choose_value_in_term(interval.left(), parameter_i, context)?;
&mut function_declarations, &mut variable_declaration_stack)?;
let choose_j_in_t_2 = choose_value_in_term(interval.right(), parameter_j, let choose_j_in_t_2 = choose_value_in_term(interval.right(), parameter_j, context)?;
&mut function_declarations, &mut variable_declaration_stack)?;
let i_less_than_or_equal_to_k = foliage::Formula::less_or_equal( let i_less_than_or_equal_to_k = foliage::Formula::less_or_equal(
Box::new(foliage::Term::variable(parameter_i)), Box::new(foliage::Term::variable(parameter_i)),

View File

@ -3,6 +3,7 @@ mod translate_body;
use head_type::*; use head_type::*;
use translate_body::*; use translate_body::*;
use crate::translate::common::AssignVariableDeclarationDomain as _;
struct ScopedFormula struct ScopedFormula
{ {
@ -16,14 +17,24 @@ struct Definitions
definitions: Vec<ScopedFormula>, definitions: Vec<ScopedFormula>,
} }
type VariableDeclarationDomains
= std::collections::BTreeMap<std::rc::Rc<foliage::VariableDeclaration>,
crate::translate::common::Domain>;
type VariableDeclarationIDs
= std::collections::BTreeMap::<std::rc::Rc<foliage::VariableDeclaration>, usize>;
struct Context struct Context
{ {
pub definitions: std::collections::BTreeMap::<std::rc::Rc<foliage::PredicateDeclaration>, Definitions>, pub definitions: std::cell::RefCell<std::collections::BTreeMap::<std::rc::Rc<foliage::PredicateDeclaration>,
pub integrity_constraints: foliage::Formulas, Definitions>>,
pub integrity_constraints: std::cell::RefCell<foliage::Formulas>,
pub function_declarations: foliage::FunctionDeclarations, pub function_declarations: std::cell::RefCell<foliage::FunctionDeclarations>,
pub predicate_declarations: foliage::PredicateDeclarations, pub predicate_declarations: std::cell::RefCell<foliage::PredicateDeclarations>,
pub variable_declaration_stack: foliage::VariableDeclarationStack, pub variable_declaration_stack: std::cell::RefCell<foliage::VariableDeclarationStack>,
pub variable_declaration_domains: std::cell::RefCell<VariableDeclarationDomains>,
pub variable_declaration_ids: std::cell::RefCell<VariableDeclarationIDs>,
} }
impl Context impl Context
@ -32,11 +43,149 @@ impl Context
{ {
Self Self
{ {
definitions: std::collections::BTreeMap::<_, _>::new(), definitions: std::cell::RefCell::new(std::collections::BTreeMap::<_, _>::new()),
integrity_constraints: vec![], integrity_constraints: std::cell::RefCell::new(vec![]),
function_declarations: foliage::FunctionDeclarations::new(),
predicate_declarations: foliage::PredicateDeclarations::new(), function_declarations: std::cell::RefCell::new(foliage::FunctionDeclarations::new()),
variable_declaration_stack: foliage::VariableDeclarationStack::new(), predicate_declarations: std::cell::RefCell::new(foliage::PredicateDeclarations::new()),
variable_declaration_stack: std::cell::RefCell::new(foliage::VariableDeclarationStack::new()),
variable_declaration_domains: std::cell::RefCell::new(VariableDeclarationDomains::new()),
variable_declaration_ids: std::cell::RefCell::new(VariableDeclarationIDs::new()),
}
}
}
impl crate::translate::common::GetOrCreateFunctionDeclaration for Context
{
fn get_or_create_function_declaration(&self, name: &str, arity: usize)
-> std::rc::Rc<foliage::FunctionDeclaration>
{
let mut function_declarations = self.function_declarations.borrow_mut();
match function_declarations.iter()
.find(|x| x.name == name && x.arity == arity)
{
Some(value) => std::rc::Rc::clone(value),
None =>
{
let declaration = std::rc::Rc::new(foliage::FunctionDeclaration::new(
name.to_string(), arity));
function_declarations.insert(std::rc::Rc::clone(&declaration));
log::debug!("new function declaration: {}/{}", name, arity);
declaration
},
}
}
}
impl crate::translate::common::GetOrCreatePredicateDeclaration for Context
{
fn get_or_create_predicate_declaration(&self, name: &str, arity: usize)
-> std::rc::Rc<foliage::PredicateDeclaration>
{
let mut predicate_declarations = self.predicate_declarations.borrow_mut();
match predicate_declarations.iter()
.find(|x| x.name == name && x.arity == arity)
{
Some(value) => std::rc::Rc::clone(value),
None =>
{
let declaration = std::rc::Rc::new(foliage::PredicateDeclaration::new(
name.to_string(), arity));
predicate_declarations.insert(std::rc::Rc::clone(&declaration));
log::debug!("new predicate declaration: {}/{}", name, arity);
declaration
},
}
}
}
impl crate::translate::common::GetOrCreateVariableDeclaration for Context
{
fn get_or_create_variable_declaration(&self, name: &str)
-> std::rc::Rc<foliage::VariableDeclaration>
{
let mut variable_declaration_stack = self.variable_declaration_stack.borrow_mut();
// TODO: check correctness
if name == "_"
{
let variable_declaration = std::rc::Rc::new(foliage::VariableDeclaration::new(
"_".to_owned()));
variable_declaration_stack.free_variable_declarations.push(
std::rc::Rc::clone(&variable_declaration));
return variable_declaration;
}
variable_declaration_stack.find_or_create(name)
}
}
impl crate::translate::common::AssignVariableDeclarationDomain for Context
{
fn assign_variable_declaration_domain(&self,
variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>,
domain: crate::translate::common::Domain)
{
let mut variable_declaration_domains = self.variable_declaration_domains.borrow_mut();
match variable_declaration_domains.get(variable_declaration)
{
Some(current_domain) => assert_eq!(*current_domain, domain,
"inconsistent variable declaration domain"),
None =>
{
variable_declaration_domains
.insert(std::rc::Rc::clone(variable_declaration).into(), domain);
},
}
}
}
impl crate::translate::common::VariableDeclarationDomain for Context
{
fn variable_declaration_domain(&self,
variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>)
-> Option<crate::translate::common::Domain>
{
let variable_declaration_domains = self.variable_declaration_domains.borrow();
variable_declaration_domains.get(variable_declaration)
.map(|x| *x)
}
}
impl crate::translate::common::VariableDeclarationID for Context
{
fn variable_declaration_id(&self,
variable_declaration: &std::rc::Rc<foliage::VariableDeclaration>)
-> usize
{
let mut variable_declaration_ids = self.variable_declaration_ids.borrow_mut();
match variable_declaration_ids.get(variable_declaration)
{
Some(id) =>
{
//log::trace!("{:p} → {} (already known)", *variable_declaration, id);
*id
}
None =>
{
let id = variable_declaration_ids.len();
variable_declaration_ids.insert(std::rc::Rc::clone(variable_declaration).into(), id);
//log::trace!("{:p} → {} (new)", *variable_declaration, id);
id
},
} }
} }
} }
@ -104,11 +253,8 @@ where
} }
let context = statement_handler.context; let context = statement_handler.context;
let mut definitions = context.definitions;
let integrity_constraints = context.integrity_constraints;
let predicate_declarations = context.predicate_declarations;
for (predicate_declaration, definitions) in definitions.iter() for (predicate_declaration, definitions) in context.definitions.borrow().iter()
{ {
for definition in definitions.definitions.iter() for definition in definitions.definitions.iter()
{ {
@ -117,9 +263,9 @@ where
} }
} }
let mut completed_definition = |predicate_declaration| let completed_definition = |predicate_declaration|
{ {
match definitions.remove(predicate_declaration) match context.definitions.borrow_mut().remove(predicate_declaration)
{ {
// This predicate symbol has at least one definition, so build the disjunction of those // This predicate symbol has at least one definition, so build the disjunction of those
Some(definitions) => Some(definitions) =>
@ -151,7 +297,14 @@ where
None => None =>
{ {
let head_atom_parameters = std::rc::Rc::new((0..predicate_declaration.arity) let head_atom_parameters = std::rc::Rc::new((0..predicate_declaration.arity)
.map(|_| std::rc::Rc::new(foliage::VariableDeclaration::new("<anonymous>".to_string()))) .map(|_|
{
let variable_declaration = std::rc::Rc::new(
foliage::VariableDeclaration::new("<anonymous>".to_string()));
context.assign_variable_declaration_domain(&variable_declaration,
crate::translate::common::Domain::Program);
variable_declaration
})
.collect::<Vec<_>>()); .collect::<Vec<_>>());
let head_arguments = head_atom_parameters.iter() let head_arguments = head_atom_parameters.iter()
@ -174,6 +327,7 @@ where
} }
}; };
let predicate_declarations = context.predicate_declarations.borrow();
let completed_definitions = predicate_declarations.iter() let completed_definitions = predicate_declarations.iter()
.map(|x| (std::rc::Rc::clone(x), completed_definition(x))); .map(|x| (std::rc::Rc::clone(x), completed_definition(x)));
@ -181,37 +335,43 @@ where
{ {
println!("tff(completion_{}_{}, axiom, {}).", predicate_declaration.name, println!("tff(completion_{}_{}, axiom, {}).", predicate_declaration.name,
predicate_declaration.arity, predicate_declaration.arity,
crate::output::tptp::display_formula(&completed_definition)); crate::output::tptp::display_formula(&completed_definition, &context));
} }
for integrity_constraint in integrity_constraints for integrity_constraint in context.integrity_constraints.borrow().iter()
{ {
println!("tff(integrity_constraint, axiom, {}).", println!("tff(integrity_constraint, axiom, {}).",
crate::output::tptp::display_formula(&integrity_constraint)); crate::output::tptp::display_formula(&integrity_constraint, &context));
} }
Ok(()) Ok(())
} }
fn read_rule(rule: &clingo::ast::Rule, context: &mut Context) -> Result<(), crate::Error> fn read_rule(rule: &clingo::ast::Rule, context: &Context)
-> Result<(), crate::Error>
{ {
use super::common::FindOrCreatePredicateDeclaration; let head_type = determine_head_type(rule.head(), context)?;
let head_type = determine_head_type(rule.head(),
|name, arity| context.predicate_declarations.find_or_create(name, arity))?;
match &head_type match &head_type
{ {
HeadType::SingleAtom(head_atom) HeadType::SingleAtom(head_atom)
| HeadType::ChoiceWithSingleAtom(head_atom) => | HeadType::ChoiceWithSingleAtom(head_atom) =>
{ {
if !context.definitions.contains_key(&head_atom.predicate_declaration) if !context.definitions.borrow().contains_key(&head_atom.predicate_declaration)
{ {
let head_atom_parameters = std::rc::Rc::new((0..head_atom.predicate_declaration.arity) let head_atom_parameters = std::rc::Rc::new((0..head_atom.predicate_declaration.arity)
.map(|_| std::rc::Rc::new(foliage::VariableDeclaration::new("<anonymous>".to_string()))) .map(|_|
{
let variable_declaration = std::rc::Rc::new(
foliage::VariableDeclaration::new("<anonymous>".to_string()));
context.assign_variable_declaration_domain(&variable_declaration,
crate::translate::common::Domain::Program);
variable_declaration
})
.collect()); .collect());
context.definitions.insert(std::rc::Rc::clone(&head_atom.predicate_declaration), context.definitions.borrow_mut().insert(
std::rc::Rc::clone(&head_atom.predicate_declaration),
Definitions Definitions
{ {
head_atom_parameters, head_atom_parameters,
@ -219,14 +379,13 @@ fn read_rule(rule: &clingo::ast::Rule, context: &mut Context) -> Result<(), crat
}); });
} }
let definitions = context.definitions.get_mut(&head_atom.predicate_declaration).unwrap(); let mut definitions = context.definitions.borrow_mut();
let definitions = definitions.get_mut(&head_atom.predicate_declaration).unwrap();
context.variable_declaration_stack.push(std::rc::Rc::clone( let head_atom_parameters = std::rc::Rc::clone(&definitions.head_atom_parameters);
&definitions.head_atom_parameters)); context.variable_declaration_stack.borrow_mut().push(head_atom_parameters);
let mut definition_arguments = translate_body(rule.body(), let mut definition_arguments = translate_body(rule.body(), context)?;
&mut context.function_declarations, &mut context.predicate_declarations,
&mut context.variable_declaration_stack)?;
assert_eq!(definitions.head_atom_parameters.len(), head_atom.arguments.len()); assert_eq!(definitions.head_atom_parameters.len(), head_atom.arguments.len());
@ -249,17 +408,17 @@ fn read_rule(rule: &clingo::ast::Rule, context: &mut Context) -> Result<(), crat
let head_atom_argument = head_atom_arguments_iterator.next().unwrap(); let head_atom_argument = head_atom_arguments_iterator.next().unwrap();
let translated_head_term = crate::translate::common::choose_value_in_term( let translated_head_term = crate::translate::common::choose_value_in_term(
head_atom_argument, head_atom_parameter, &mut context.function_declarations, head_atom_argument, head_atom_parameter, context)?;
&mut context.variable_declaration_stack)?;
definition_arguments.push(Box::new(translated_head_term)); definition_arguments.push(Box::new(translated_head_term));
} }
context.variable_declaration_stack.pop(); context.variable_declaration_stack.borrow_mut().pop();
let mut free_variable_declarations = vec![]; let mut free_variable_declarations = vec![];
std::mem::swap(&mut context.variable_declaration_stack.free_variable_declarations, std::mem::swap(
&mut context.variable_declaration_stack.borrow_mut().free_variable_declarations,
&mut free_variable_declarations); &mut free_variable_declarations);
let definition = match definition_arguments.len() let definition = match definition_arguments.len()
@ -281,13 +440,12 @@ fn read_rule(rule: &clingo::ast::Rule, context: &mut Context) -> Result<(), crat
}, },
HeadType::IntegrityConstraint => HeadType::IntegrityConstraint =>
{ {
let mut arguments = translate_body(rule.body(), let mut arguments = translate_body(rule.body(), context)?;
&mut context.function_declarations, &mut context.predicate_declarations,
&mut context.variable_declaration_stack)?;
let mut free_variable_declarations = vec![]; let mut free_variable_declarations = vec![];
std::mem::swap(&mut context.variable_declaration_stack.free_variable_declarations, std::mem::swap(
&mut context.variable_declaration_stack.borrow_mut().free_variable_declarations,
&mut free_variable_declarations); &mut free_variable_declarations);
let formula = match arguments.len() let formula = match arguments.len()
@ -307,7 +465,7 @@ fn read_rule(rule: &clingo::ast::Rule, context: &mut Context) -> Result<(), crat
log::debug!("translated integrity constraint: {:?}", integrity_constraint); log::debug!("translated integrity constraint: {:?}", integrity_constraint);
context.integrity_constraints.push(integrity_constraint); context.integrity_constraints.borrow_mut().push(integrity_constraint);
}, },
HeadType::Trivial => log::info!("skipping trivial rule"), HeadType::Trivial => log::info!("skipping trivial rule"),
} }

View File

@ -12,19 +12,18 @@ pub(crate) enum HeadType<'a>
Trivial, Trivial,
} }
pub(crate) fn determine_head_type<'a, F>(head_literal: &'a clingo::ast::HeadLiteral, pub(crate) fn determine_head_type<'a, C>(head_literal: &'a clingo::ast::HeadLiteral, context: &C)
mut find_or_create_predicate_declaration: F)
-> Result<HeadType<'a>, crate::Error> -> Result<HeadType<'a>, crate::Error>
where where
F: FnMut(&str, usize) -> std::rc::Rc<foliage::PredicateDeclaration> C: crate::translate::common::GetOrCreatePredicateDeclaration
{ {
let mut create_head_atom = |function: &'a clingo::ast::Function| -> Result<_, crate::Error> let create_head_atom = |function: &'a clingo::ast::Function| -> Result<_, crate::Error>
{ {
let function_name = function.name() let function_name = function.name()
.map_err(|error| crate::Error::new_decode_identifier(error))?; .map_err(|error| crate::Error::new_decode_identifier(error))?;
let predicate_declaration let predicate_declaration = context.get_or_create_predicate_declaration(function_name,
= find_or_create_predicate_declaration(function_name, function.arguments().len()); function.arguments().len());
Ok(HeadAtom Ok(HeadAtom
{ {

View File

@ -1,11 +1,12 @@
pub(crate) fn translate_body_term(body_term: &clingo::ast::Term, sign: clingo::ast::Sign, pub(crate) fn translate_body_term<C>(body_term: &clingo::ast::Term, sign: clingo::ast::Sign,
mut function_declarations: &mut foliage::FunctionDeclarations, context: &C)
predicate_declarations: &mut foliage::PredicateDeclarations,
mut variable_declaration_stack: &mut foliage::VariableDeclarationStack)
-> Result<foliage::Formula, crate::Error> -> Result<foliage::Formula, crate::Error>
where
C: crate::translate::common::GetOrCreateVariableDeclaration
+ crate::translate::common::GetOrCreateFunctionDeclaration
+ crate::translate::common::GetOrCreatePredicateDeclaration
+ crate::translate::common::AssignVariableDeclarationDomain
{ {
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,
@ -14,11 +15,17 @@ pub(crate) fn translate_body_term(body_term: &clingo::ast::Term, sign: clingo::a
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 = predicate_declarations.find_or_create(function_name, let predicate_declaration = context.get_or_create_predicate_declaration(function_name,
function.arguments().len()); function.arguments().len());
let parameters = function.arguments().iter().map(|_| std::rc::Rc::new( let parameters = function.arguments().iter().map(|_|
foliage::VariableDeclaration::new("<anonymous>".to_string()))) {
let variable_declaration = std::rc::Rc::new(
foliage::VariableDeclaration::new("<anonymous>".to_string()));
context.assign_variable_declaration_domain(&variable_declaration,
crate::translate::common::Domain::Program);
variable_declaration
})
.collect::<foliage::VariableDeclarations>(); .collect::<foliage::VariableDeclarations>();
let parameters = std::rc::Rc::new(parameters); let parameters = std::rc::Rc::new(parameters);
@ -47,7 +54,7 @@ pub(crate) fn translate_body_term(body_term: &clingo::ast::Term, sign: clingo::a
let mut parameters_iterator = parameters.iter(); let mut parameters_iterator = parameters.iter();
let mut arguments = function.arguments().iter().map( let mut arguments = function.arguments().iter().map(
|x| crate::translate::common::choose_value_in_term(x, &parameters_iterator.next().unwrap(), |x| crate::translate::common::choose_value_in_term(x, &parameters_iterator.next().unwrap(),
&mut function_declarations, &mut variable_declaration_stack) context)
.map(|x| Box::new(x))) .map(|x| Box::new(x)))
.collect::<Result<Vec<_>, _>>()?; .collect::<Result<Vec<_>, _>>()?;
@ -58,11 +65,14 @@ pub(crate) fn translate_body_term(body_term: &clingo::ast::Term, sign: clingo::a
Ok(foliage::Formula::exists(parameters, Box::new(and))) Ok(foliage::Formula::exists(parameters, Box::new(and)))
} }
pub(crate) fn translate_body_literal(body_literal: &clingo::ast::BodyLiteral, pub(crate) fn translate_body_literal<C>(body_literal: &clingo::ast::BodyLiteral,
mut function_declarations: &mut foliage::FunctionDeclarations, context: &C)
mut predicate_declarations: &mut foliage::PredicateDeclarations,
mut variable_declaration_stack: &mut foliage::VariableDeclarationStack)
-> Result<foliage::Formula, crate::Error> -> Result<foliage::Formula, crate::Error>
where
C: crate::translate::common::GetOrCreateVariableDeclaration
+ crate::translate::common::GetOrCreateFunctionDeclaration
+ crate::translate::common::GetOrCreatePredicateDeclaration
+ crate::translate::common::AssignVariableDeclarationDomain
{ {
match body_literal.sign() match body_literal.sign()
{ {
@ -91,12 +101,17 @@ pub(crate) fn translate_body_literal(body_literal: &clingo::ast::BodyLiteral,
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 function_declarations, &mut predicate_declarations, context),
&mut variable_declaration_stack),
clingo::ast::LiteralType::Comparison(comparison) => clingo::ast::LiteralType::Comparison(comparison) =>
{ {
let parameters = (0..2).map(|_| std::rc::Rc::new(foliage::VariableDeclaration::new( let parameters = (0..2).map(|_|
"<anonymous>".to_string()))) {
let variable_declaration = std::rc::Rc::new(
foliage::VariableDeclaration::new("<anonymous>".to_string()));
context.assign_variable_declaration_domain(&variable_declaration,
crate::translate::common::Domain::Program);
variable_declaration
})
.collect::<foliage::VariableDeclarations>(); .collect::<foliage::VariableDeclarations>();
let parameters = std::rc::Rc::new(parameters); let parameters = std::rc::Rc::new(parameters);
@ -105,9 +120,9 @@ pub(crate) fn translate_body_literal(body_literal: &clingo::ast::BodyLiteral,
let parameter_z2 = &parameters_iterator.next().unwrap(); let parameter_z2 = &parameters_iterator.next().unwrap();
let choose_z1_in_t1 = crate::translate::common::choose_value_in_term(comparison.left(), let choose_z1_in_t1 = crate::translate::common::choose_value_in_term(comparison.left(),
parameter_z1, &mut function_declarations, &mut variable_declaration_stack)?; parameter_z1, context)?;
let choose_z2_in_t2 = crate::translate::common::choose_value_in_term(comparison.right(), let choose_z2_in_t2 = crate::translate::common::choose_value_in_term(comparison.right(),
parameter_z2, &mut function_declarations, &mut variable_declaration_stack)?; parameter_z2, context)?;
let variable_1 = foliage::Term::variable(parameter_z1); let variable_1 = foliage::Term::variable(parameter_z1);
let variable_2 = foliage::Term::variable(parameter_z2); let variable_2 = foliage::Term::variable(parameter_z2);
@ -128,15 +143,17 @@ pub(crate) fn translate_body_literal(body_literal: &clingo::ast::BodyLiteral,
} }
} }
pub(crate) fn translate_body(body_literals: &[clingo::ast::BodyLiteral], pub(crate) fn translate_body<C>(body_literals: &[clingo::ast::BodyLiteral],
mut function_declaration: &mut foliage::FunctionDeclarations, context: &C)
mut predicate_declaration: &mut foliage::PredicateDeclarations,
mut variable_declaration_stack: &mut foliage::VariableDeclarationStack)
-> Result<foliage::Formulas, crate::Error> -> Result<foliage::Formulas, crate::Error>
where
C: crate::translate::common::GetOrCreateVariableDeclaration
+ crate::translate::common::GetOrCreateFunctionDeclaration
+ crate::translate::common::GetOrCreatePredicateDeclaration
+ crate::translate::common::AssignVariableDeclarationDomain
{ {
body_literals.iter() body_literals.iter()
.map(|body_literal| translate_body_literal(body_literal, &mut function_declaration, .map(|body_literal| translate_body_literal(body_literal, context)
&mut predicate_declaration, &mut variable_declaration_stack)
.map(|value| Box::new(value))) .map(|value| Box::new(value)))
.collect::<Result<foliage::Formulas, crate::Error>>() .collect::<Result<foliage::Formulas, crate::Error>>()
} }