Use custom foliage flavor
With this patch, properties specific to variable, function, and predicate declarations are directly stored within those objects rather than external maps that need to be queried via traits. This greatly simplifies many parts of the logic. This is made possible by implementing a custom foliage flavor, which makes it possible to swap the built-in declaration types for extended versions of those types that fulfill certain requirements.
This commit is contained in:
@@ -1,19 +1,18 @@
|
||||
pub(crate) fn choose_value_in_primitive(term: Box<foliage::Term>,
|
||||
variable_declaration: std::rc::Rc<foliage::VariableDeclaration>)
|
||||
-> foliage::Formula
|
||||
pub(crate) fn choose_value_in_primitive(term: Box<crate::Term>,
|
||||
variable_declaration: std::rc::Rc<crate::VariableDeclaration>)
|
||||
-> crate::Formula
|
||||
{
|
||||
let variable = foliage::Term::variable(variable_declaration);
|
||||
let variable = crate::Term::variable(variable_declaration);
|
||||
|
||||
foliage::Formula::equal(Box::new(variable), term)
|
||||
crate::Formula::equal(Box::new(variable), term)
|
||||
}
|
||||
|
||||
pub(crate) fn choose_value_in_term<C>(term: &clingo::ast::Term,
|
||||
variable_declaration: std::rc::Rc<foliage::VariableDeclaration>, context: &C,
|
||||
variable_declaration_stack: &foliage::VariableDeclarationStackLayer)
|
||||
-> Result<foliage::Formula, crate::Error>
|
||||
variable_declaration: std::rc::Rc<crate::VariableDeclaration>, context: &C,
|
||||
variable_declaration_stack: &crate::VariableDeclarationStackLayer)
|
||||
-> Result<crate::Formula, crate::Error>
|
||||
where
|
||||
C: foliage::FindOrCreateFunctionDeclaration
|
||||
+ crate::traits::AssignVariableDeclarationDomain
|
||||
C: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>,
|
||||
{
|
||||
match term.term_type()
|
||||
{
|
||||
@@ -21,15 +20,15 @@ where
|
||||
.map_err(|error| crate::Error::new_logic("clingo error").with(error))?
|
||||
{
|
||||
clingo::SymbolType::Number => Ok(choose_value_in_primitive(
|
||||
Box::new(foliage::Term::integer(symbol.number()
|
||||
Box::new(crate::Term::integer(symbol.number()
|
||||
.map_err(|error| crate::Error::new_logic("clingo error").with(error))?)),
|
||||
variable_declaration)),
|
||||
clingo::SymbolType::Infimum => Ok(choose_value_in_primitive(
|
||||
Box::new(foliage::Term::infimum()), variable_declaration)),
|
||||
Box::new(crate::Term::infimum()), variable_declaration)),
|
||||
clingo::SymbolType::Supremum => Ok(choose_value_in_primitive(
|
||||
Box::new(foliage::Term::supremum()), variable_declaration)),
|
||||
Box::new(crate::Term::supremum()), variable_declaration)),
|
||||
clingo::SymbolType::String => Ok(choose_value_in_primitive(
|
||||
Box::new(foliage::Term::string(symbol.string()
|
||||
Box::new(crate::Term::string(symbol.string()
|
||||
.map_err(|error| crate::Error::new_logic("clingo error").with(error))?
|
||||
.to_string())),
|
||||
variable_declaration)),
|
||||
@@ -51,7 +50,7 @@ where
|
||||
|
||||
let constant_declaration =
|
||||
context.find_or_create_function_declaration(constant_name, 0);
|
||||
let function = foliage::Term::function(constant_declaration, vec![]);
|
||||
let function = crate::Term::function(constant_declaration, vec![]);
|
||||
|
||||
Ok(choose_value_in_primitive(Box::new(function), variable_declaration))
|
||||
}
|
||||
@@ -60,14 +59,14 @@ where
|
||||
{
|
||||
let other_variable_declaration = match variable_name
|
||||
{
|
||||
// TODO: check
|
||||
// Every occurrence of anonymous variables is treated as if it introduced a fresh
|
||||
// variable declaration
|
||||
"_" => variable_declaration_stack.free_variable_declarations_do_mut(
|
||||
|free_variable_declarations|
|
||||
{
|
||||
// TODO: check domain type
|
||||
let variable_declaration = std::rc::Rc::new(
|
||||
foliage::VariableDeclaration::new("_".to_owned()));
|
||||
crate::VariableDeclaration::new_generated(crate::Domain::Program));
|
||||
|
||||
free_variable_declarations.push(std::rc::Rc::clone(&variable_declaration));
|
||||
|
||||
@@ -75,9 +74,7 @@ where
|
||||
}),
|
||||
_ => variable_declaration_stack.find_or_create(variable_name),
|
||||
};
|
||||
context.assign_variable_declaration_domain(&other_variable_declaration,
|
||||
crate::Domain::Program);
|
||||
let other_variable = foliage::Term::variable(other_variable_declaration);
|
||||
let other_variable = crate::Term::variable(other_variable_declaration);
|
||||
|
||||
Ok(choose_value_in_primitive(Box::new(other_variable), variable_declaration))
|
||||
},
|
||||
@@ -92,26 +89,21 @@ where
|
||||
| foliage::BinaryOperator::Multiply
|
||||
=>
|
||||
{
|
||||
let parameters = (0..2).map(|_|
|
||||
{
|
||||
let variable_declaration = std::rc::Rc::new(
|
||||
foliage::VariableDeclaration::new("<anonymous>".to_string()));
|
||||
context.assign_variable_declaration_domain(&variable_declaration,
|
||||
crate::Domain::Integer);
|
||||
variable_declaration
|
||||
})
|
||||
.collect::<foliage::VariableDeclarations>();
|
||||
let parameters = (0..2).map(
|
||||
|_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
|
||||
crate::Domain::Integer)))
|
||||
.collect::<crate::VariableDeclarations>();
|
||||
let parameters = std::rc::Rc::new(parameters);
|
||||
|
||||
let parameter_1 = ¶meters[0];
|
||||
let parameter_2 = ¶meters[1];
|
||||
|
||||
let translated_binary_operation = foliage::Term::binary_operation(operator,
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(¶meter_1))),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(¶meter_2))));
|
||||
let translated_binary_operation = crate::Term::binary_operation(operator,
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(¶meter_1))),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(¶meter_2))));
|
||||
|
||||
let equals = foliage::Formula::equal(
|
||||
Box::new(foliage::Term::variable(variable_declaration)),
|
||||
let equals = crate::Formula::equal(
|
||||
Box::new(crate::Term::variable(variable_declaration)),
|
||||
Box::new(translated_binary_operation));
|
||||
|
||||
let choose_value_from_left_argument = choose_value_in_term(
|
||||
@@ -122,24 +114,19 @@ where
|
||||
binary_operation.right(), std::rc::Rc::clone(¶meter_2), context,
|
||||
variable_declaration_stack)?;
|
||||
|
||||
let and = foliage::Formula::And(vec![equals, choose_value_from_left_argument,
|
||||
let and = crate::Formula::And(vec![equals, choose_value_from_left_argument,
|
||||
choose_value_from_right_argument]);
|
||||
|
||||
Ok(foliage::Formula::exists(parameters, Box::new(and)))
|
||||
Ok(crate::Formula::exists(parameters, Box::new(and)))
|
||||
},
|
||||
foliage::BinaryOperator::Divide
|
||||
| foliage::BinaryOperator::Modulo
|
||||
=>
|
||||
{
|
||||
let parameters = (0..4).map(|_|
|
||||
{
|
||||
let variable_declaration = std::rc::Rc::new(
|
||||
foliage::VariableDeclaration::new("<anonymous>".to_string()));
|
||||
context.assign_variable_declaration_domain(&variable_declaration,
|
||||
crate::Domain::Integer);
|
||||
variable_declaration
|
||||
})
|
||||
.collect::<foliage::VariableDeclarations>();
|
||||
let parameters = (0..4).map(
|
||||
|_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
|
||||
crate::Domain::Integer)))
|
||||
.collect::<crate::VariableDeclarations>();
|
||||
let parameters = std::rc::Rc::new(parameters);
|
||||
|
||||
let parameter_i = ¶meters[0];
|
||||
@@ -147,15 +134,15 @@ where
|
||||
let parameter_q = ¶meters[2];
|
||||
let parameter_r = ¶meters[3];
|
||||
|
||||
let j_times_q = foliage::Term::multiply(
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_j))),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_q))));
|
||||
let j_times_q = crate::Term::multiply(
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_j))),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_q))));
|
||||
|
||||
let j_times_q_plus_r = foliage::Term::add(Box::new(j_times_q),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_r))));
|
||||
let j_times_q_plus_r = crate::Term::add(Box::new(j_times_q),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_r))));
|
||||
|
||||
let i_equals_j_times_q_plus_r = foliage::Formula::equal(
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_i))),
|
||||
let i_equals_j_times_q_plus_r = crate::Formula::equal(
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_i))),
|
||||
Box::new(j_times_q_plus_r));
|
||||
|
||||
let choose_i_in_t1 = choose_value_in_term(binary_operation.left(),
|
||||
@@ -164,26 +151,26 @@ where
|
||||
let choose_j_in_t2 = choose_value_in_term(binary_operation.right(),
|
||||
std::rc::Rc::clone(parameter_j), context, variable_declaration_stack)?;
|
||||
|
||||
let j_not_equal_to_0 = foliage::Formula::not_equal(
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_j))),
|
||||
Box::new(foliage::Term::integer(0)));
|
||||
let j_not_equal_to_0 = crate::Formula::not_equal(
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_j))),
|
||||
Box::new(crate::Term::integer(0)));
|
||||
|
||||
let r_greater_or_equal_to_0 = foliage::Formula::greater_or_equal(
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_r))),
|
||||
Box::new(foliage::Term::integer(0)));
|
||||
let r_greater_or_equal_to_0 = crate::Formula::greater_or_equal(
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_r))),
|
||||
Box::new(crate::Term::integer(0)));
|
||||
|
||||
let r_less_than_q = foliage::Formula::less(
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_r))),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_q))));
|
||||
let r_less_than_q = crate::Formula::less(
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_r))),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_q))));
|
||||
|
||||
let z_equal_to_q = foliage::Formula::equal(
|
||||
let z_equal_to_q = crate::Formula::equal(
|
||||
Box::new(
|
||||
foliage::Term::variable(std::rc::Rc::clone(&variable_declaration))),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_q))));
|
||||
crate::Term::variable(std::rc::Rc::clone(&variable_declaration))),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_q))));
|
||||
|
||||
let z_equal_to_r = foliage::Formula::equal(
|
||||
Box::new(foliage::Term::variable(variable_declaration)),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_r))));
|
||||
let z_equal_to_r = crate::Formula::equal(
|
||||
Box::new(crate::Term::variable(variable_declaration)),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_r))));
|
||||
|
||||
let last_argument = match operator
|
||||
{
|
||||
@@ -192,11 +179,11 @@ where
|
||||
_ => return Err(crate::Error::new_logic("unreachable code")),
|
||||
};
|
||||
|
||||
let and = foliage::Formula::and(vec![i_equals_j_times_q_plus_r, choose_i_in_t1,
|
||||
let and = crate::Formula::and(vec![i_equals_j_times_q_plus_r, choose_i_in_t1,
|
||||
choose_j_in_t2, j_not_equal_to_0, r_greater_or_equal_to_0, r_less_than_q,
|
||||
last_argument]);
|
||||
|
||||
Ok(foliage::Formula::exists(parameters, Box::new(and)))
|
||||
Ok(crate::Formula::exists(parameters, Box::new(and)))
|
||||
},
|
||||
foliage::BinaryOperator::Exponentiate =>
|
||||
Err(crate::Error::new_unsupported_language_feature("exponentiation")),
|
||||
@@ -210,41 +197,34 @@ where
|
||||
return Err(crate::Error::new_unsupported_language_feature("absolute value")),
|
||||
clingo::ast::UnaryOperator::Minus =>
|
||||
{
|
||||
let parameter_z_prime = std::rc::Rc::new(foliage::VariableDeclaration::new(
|
||||
"<anonymous>".to_string()));
|
||||
context.assign_variable_declaration_domain(¶meter_z_prime,
|
||||
crate::Domain::Integer);
|
||||
let parameter_z_prime = std::rc::Rc::new(
|
||||
crate::VariableDeclaration::new_generated(crate::Domain::Integer));
|
||||
|
||||
let negative_z_prime = foliage::Term::negative(Box::new(
|
||||
foliage::Term::variable(std::rc::Rc::clone(¶meter_z_prime))));
|
||||
let equals = foliage::Formula::equal(
|
||||
Box::new(foliage::Term::variable(variable_declaration)),
|
||||
let negative_z_prime = crate::Term::negative(Box::new(
|
||||
crate::Term::variable(std::rc::Rc::clone(¶meter_z_prime))));
|
||||
let equals = crate::Formula::equal(
|
||||
Box::new(crate::Term::variable(variable_declaration)),
|
||||
Box::new(negative_z_prime));
|
||||
|
||||
let choose_z_prime_in_t_prime = choose_value_in_term(unary_operation.argument(),
|
||||
std::rc::Rc::clone(¶meter_z_prime), context,
|
||||
variable_declaration_stack)?;
|
||||
|
||||
let and = foliage::Formula::and(vec![equals, choose_z_prime_in_t_prime]);
|
||||
let and = crate::Formula::and(vec![equals, choose_z_prime_in_t_prime]);
|
||||
|
||||
let parameters = std::rc::Rc::new(vec![parameter_z_prime]);
|
||||
|
||||
Ok(foliage::Formula::exists(parameters, Box::new(and)))
|
||||
Ok(crate::Formula::exists(parameters, Box::new(and)))
|
||||
},
|
||||
_ => Err(crate::Error::new_not_yet_implemented("todo")),
|
||||
}
|
||||
},
|
||||
clingo::ast::TermType::Interval(interval) =>
|
||||
{
|
||||
let parameters = (0..3).map(|_|
|
||||
{
|
||||
let variable_declaration = std::rc::Rc::new(
|
||||
foliage::VariableDeclaration::new("<anonymous>".to_string()));
|
||||
context.assign_variable_declaration_domain(&variable_declaration,
|
||||
crate::Domain::Integer);
|
||||
variable_declaration
|
||||
})
|
||||
.collect::<foliage::VariableDeclarations>();
|
||||
let parameters = (0..3).map(
|
||||
|_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
|
||||
crate::Domain::Integer)))
|
||||
.collect::<crate::VariableDeclarations>();
|
||||
let parameters = std::rc::Rc::new(parameters);
|
||||
|
||||
let parameter_i = ¶meters[0];
|
||||
@@ -257,22 +237,22 @@ where
|
||||
let choose_j_in_t_2 = choose_value_in_term(interval.right(),
|
||||
std::rc::Rc::clone(parameter_j), context, variable_declaration_stack)?;
|
||||
|
||||
let i_less_than_or_equal_to_k = foliage::Formula::less_or_equal(
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_i))),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_k))));
|
||||
let i_less_than_or_equal_to_k = crate::Formula::less_or_equal(
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_i))),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_k))));
|
||||
|
||||
let k_less_than_or_equal_to_j = foliage::Formula::less_or_equal(
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_k))),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_j))));
|
||||
let k_less_than_or_equal_to_j = crate::Formula::less_or_equal(
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_k))),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_j))));
|
||||
|
||||
let z_equals_k = foliage::Formula::equal(
|
||||
Box::new(foliage::Term::variable(variable_declaration)),
|
||||
Box::new(foliage::Term::variable(std::rc::Rc::clone(parameter_k))));
|
||||
let z_equals_k = crate::Formula::equal(
|
||||
Box::new(crate::Term::variable(variable_declaration)),
|
||||
Box::new(crate::Term::variable(std::rc::Rc::clone(parameter_k))));
|
||||
|
||||
let and = foliage::Formula::and(vec![choose_i_in_t_1, choose_j_in_t_2,
|
||||
let and = crate::Formula::and(vec![choose_i_in_t_1, choose_j_in_t_2,
|
||||
i_less_than_or_equal_to_k, k_less_than_or_equal_to_j, z_equals_k]);
|
||||
|
||||
Ok(foliage::Formula::exists(parameters, Box::new(and)))
|
||||
Ok(crate::Formula::exists(parameters, Box::new(and)))
|
||||
},
|
||||
clingo::ast::TermType::Function(_) =>
|
||||
Err(crate::Error::new_unsupported_language_feature("symbolic functions")),
|
||||
|
@@ -3,16 +3,17 @@ mod translate_body;
|
||||
|
||||
use head_type::*;
|
||||
use translate_body::*;
|
||||
use crate::traits::AssignVariableDeclarationDomain as _;
|
||||
|
||||
use foliage::flavor::{PredicateDeclaration as _};
|
||||
|
||||
struct PredicateDefinitions
|
||||
{
|
||||
pub parameters: std::rc::Rc<foliage::VariableDeclarations>,
|
||||
pub definitions: Vec<foliage::OpenFormula>,
|
||||
pub parameters: std::rc::Rc<crate::VariableDeclarations>,
|
||||
pub definitions: Vec<crate::OpenFormula>,
|
||||
}
|
||||
|
||||
type Definitions =
|
||||
std::collections::BTreeMap::<std::rc::Rc<foliage::PredicateDeclaration>, PredicateDefinitions>;
|
||||
std::collections::BTreeMap::<std::rc::Rc<crate::PredicateDeclaration>, PredicateDefinitions>;
|
||||
|
||||
pub(crate) struct Translator<'p>
|
||||
{
|
||||
@@ -76,8 +77,7 @@ impl<'p> Translator<'p>
|
||||
|
||||
log::info!("read input program “{}”", program_path.as_ref().display());
|
||||
|
||||
let completed_definition = |predicate_declaration, definitions: &mut Definitions,
|
||||
problem: &crate::Problem|
|
||||
let completed_definition = |predicate_declaration, definitions: &mut Definitions|
|
||||
{
|
||||
match definitions.remove(predicate_declaration)
|
||||
{
|
||||
@@ -87,19 +87,19 @@ impl<'p> Translator<'p>
|
||||
let or_arguments = predicate_definitions.definitions.into_iter()
|
||||
.map(|x| crate::existential_closure(x))
|
||||
.collect::<Vec<_>>();
|
||||
let or = foliage::Formula::or(or_arguments);
|
||||
let or = crate::Formula::or(or_arguments);
|
||||
|
||||
let head_arguments = predicate_definitions.parameters.iter()
|
||||
.map(|x| foliage::Term::variable(std::rc::Rc::clone(x)))
|
||||
.map(|x| crate::Term::variable(std::rc::Rc::clone(x)))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let head_predicate = foliage::Formula::predicate(
|
||||
let head_predicate = crate::Formula::predicate(
|
||||
std::rc::Rc::clone(predicate_declaration), head_arguments);
|
||||
|
||||
let completed_definition =
|
||||
foliage::Formula::if_and_only_if(vec![head_predicate, or]);
|
||||
crate::Formula::if_and_only_if(vec![head_predicate, or]);
|
||||
|
||||
let open_formula = foliage::OpenFormula
|
||||
let open_formula = crate::OpenFormula
|
||||
{
|
||||
free_variable_declarations: predicate_definitions.parameters,
|
||||
formula: completed_definition,
|
||||
@@ -110,27 +110,21 @@ impl<'p> Translator<'p>
|
||||
// This predicate has no definitions, so universally falsify it
|
||||
None =>
|
||||
{
|
||||
let parameters = std::rc::Rc::new((0..predicate_declaration.arity)
|
||||
.map(|_|
|
||||
{
|
||||
let variable_declaration = std::rc::Rc::new(
|
||||
foliage::VariableDeclaration::new("<anonymous>".to_string()));
|
||||
problem.assign_variable_declaration_domain(&variable_declaration,
|
||||
crate::Domain::Program);
|
||||
variable_declaration
|
||||
})
|
||||
let parameters = std::rc::Rc::new((0..predicate_declaration.arity()).map(
|
||||
|_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
|
||||
crate::Domain::Program)))
|
||||
.collect::<Vec<_>>());
|
||||
|
||||
let head_arguments = parameters.iter()
|
||||
.map(|x| foliage::Term::variable(std::rc::Rc::clone(x)))
|
||||
.map(|x| crate::Term::variable(std::rc::Rc::clone(x)))
|
||||
.collect();
|
||||
|
||||
let head_predicate = foliage::Formula::predicate(
|
||||
let head_predicate = crate::Formula::predicate(
|
||||
std::rc::Rc::clone(predicate_declaration), head_arguments);
|
||||
|
||||
let not = foliage::Formula::not(Box::new(head_predicate));
|
||||
let not = crate::Formula::not(Box::new(head_predicate));
|
||||
|
||||
let open_formula = foliage::OpenFormula
|
||||
let open_formula = crate::OpenFormula
|
||||
{
|
||||
free_variable_declarations: parameters,
|
||||
formula: not,
|
||||
@@ -144,9 +138,7 @@ impl<'p> Translator<'p>
|
||||
for predicate_declaration in self.problem.predicate_declarations.borrow().iter()
|
||||
{
|
||||
// Don’t perform completion for input predicates and built-in predicates
|
||||
if self.problem.input_predicate_declarations.borrow().contains(predicate_declaration)
|
||||
|| predicate_declaration.name.starts_with("p__")
|
||||
&& predicate_declaration.name.ends_with("__")
|
||||
if *predicate_declaration.is_input.borrow() || predicate_declaration.is_built_in()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -154,12 +146,18 @@ impl<'p> Translator<'p>
|
||||
let statement_kind = crate::problem::StatementKind::CompletedDefinition(
|
||||
std::rc::Rc::clone(&predicate_declaration));
|
||||
|
||||
let completed_definition = completed_definition(predicate_declaration,
|
||||
&mut self.definitions, self.problem);
|
||||
let mut completed_definition = completed_definition(predicate_declaration,
|
||||
&mut self.definitions);
|
||||
|
||||
crate::autoname_variables(&mut completed_definition);
|
||||
|
||||
//crate::simplify(&mut completed_definition);
|
||||
|
||||
let statement_name =
|
||||
format!("completed_definition_{}", predicate_declaration.tptp_statement_name());
|
||||
|
||||
let statement = crate::problem::Statement::new(statement_kind, completed_definition)
|
||||
.with_name(format!("completed_definition_{}_{}", predicate_declaration.name,
|
||||
predicate_declaration.arity));
|
||||
.with_name(statement_name);
|
||||
|
||||
self.problem.add_statement(crate::problem::SectionKind::CompletedDefinitions,
|
||||
statement);
|
||||
@@ -180,15 +178,10 @@ impl<'p> Translator<'p>
|
||||
{
|
||||
if !self.definitions.contains_key(&head_atom.predicate_declaration)
|
||||
{
|
||||
let parameters = std::rc::Rc::new((0..head_atom.predicate_declaration.arity)
|
||||
.map(|_|
|
||||
{
|
||||
let variable_declaration = std::rc::Rc::new(
|
||||
foliage::VariableDeclaration::new("<anonymous>".to_string()));
|
||||
self.problem.assign_variable_declaration_domain(&variable_declaration,
|
||||
crate::Domain::Program);
|
||||
variable_declaration
|
||||
})
|
||||
let parameters = std::rc::Rc::new((0..head_atom.predicate_declaration.arity())
|
||||
.map(
|
||||
|_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
|
||||
crate::Domain::Program)))
|
||||
.collect());
|
||||
|
||||
self.definitions.insert(
|
||||
@@ -207,9 +200,9 @@ impl<'p> Translator<'p>
|
||||
let parameters = std::rc::Rc::clone(&predicate_definitions.parameters);
|
||||
let free_variable_declarations = std::cell::RefCell::new(vec![]);
|
||||
let free_layer =
|
||||
foliage::VariableDeclarationStackLayer::Free(free_variable_declarations);
|
||||
crate::VariableDeclarationStackLayer::Free(free_variable_declarations);
|
||||
let parameters_layer =
|
||||
foliage::VariableDeclarationStackLayer::bound(&free_layer, parameters);
|
||||
crate::VariableDeclarationStackLayer::bound(&free_layer, parameters);
|
||||
|
||||
let mut definition_arguments =
|
||||
translate_body(rule.body(), self.problem, ¶meters_layer)?;
|
||||
@@ -220,10 +213,10 @@ impl<'p> Translator<'p>
|
||||
if let HeadType::ChoiceWithSingleAtom(_) = head_type
|
||||
{
|
||||
let head_arguments = predicate_definitions.parameters.iter()
|
||||
.map(|x| foliage::Term::variable(std::rc::Rc::clone(x)))
|
||||
.map(|x| crate::Term::variable(std::rc::Rc::clone(x)))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let head_predicate = foliage::Formula::predicate(
|
||||
let head_predicate = crate::Formula::predicate(
|
||||
std::rc::Rc::clone(&head_atom.predicate_declaration), head_arguments);
|
||||
|
||||
definition_arguments.push(head_predicate);
|
||||
@@ -245,7 +238,7 @@ impl<'p> Translator<'p>
|
||||
// TODO: refactor
|
||||
let free_variable_declarations = match free_layer
|
||||
{
|
||||
foliage::VariableDeclarationStackLayer::Free(free_variable_declarations)
|
||||
crate::VariableDeclarationStackLayer::Free(free_variable_declarations)
|
||||
=> free_variable_declarations.into_inner(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
@@ -253,11 +246,11 @@ impl<'p> Translator<'p>
|
||||
let definition = match definition_arguments.len()
|
||||
{
|
||||
1 => definition_arguments.pop().unwrap(),
|
||||
0 => foliage::Formula::true_(),
|
||||
_ => foliage::Formula::and(definition_arguments),
|
||||
0 => crate::Formula::true_(),
|
||||
_ => crate::Formula::and(definition_arguments),
|
||||
};
|
||||
|
||||
let definition = foliage::OpenFormula
|
||||
let definition = crate::OpenFormula
|
||||
{
|
||||
free_variable_declarations: std::rc::Rc::new(free_variable_declarations),
|
||||
formula: definition,
|
||||
@@ -269,26 +262,26 @@ impl<'p> Translator<'p>
|
||||
{
|
||||
let free_variable_declarations = std::cell::RefCell::new(vec![]);
|
||||
let free_layer =
|
||||
foliage::VariableDeclarationStackLayer::Free(free_variable_declarations);
|
||||
crate::VariableDeclarationStackLayer::Free(free_variable_declarations);
|
||||
|
||||
let mut arguments = translate_body(rule.body(), self.problem, &free_layer)?;
|
||||
|
||||
// TODO: refactor
|
||||
let free_variable_declarations = match free_layer
|
||||
{
|
||||
foliage::VariableDeclarationStackLayer::Free(free_variable_declarations)
|
||||
crate::VariableDeclarationStackLayer::Free(free_variable_declarations)
|
||||
=> free_variable_declarations.into_inner(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let formula = match arguments.len()
|
||||
{
|
||||
1 => foliage::Formula::not(Box::new(arguments.pop().unwrap())),
|
||||
0 => foliage::Formula::false_(),
|
||||
_ => foliage::Formula::not(Box::new(foliage::Formula::and(arguments))),
|
||||
1 => crate::Formula::not(Box::new(arguments.pop().unwrap())),
|
||||
0 => crate::Formula::false_(),
|
||||
_ => crate::Formula::not(Box::new(crate::Formula::and(arguments))),
|
||||
};
|
||||
|
||||
let open_formula = foliage::OpenFormula
|
||||
let open_formula = crate::OpenFormula
|
||||
{
|
||||
free_variable_declarations: std::rc::Rc::new(free_variable_declarations),
|
||||
formula,
|
||||
@@ -296,6 +289,8 @@ impl<'p> Translator<'p>
|
||||
|
||||
let integrity_constraint = crate::universal_closure(open_formula);
|
||||
|
||||
//crate::simplify(&mut integrity_constraint);
|
||||
|
||||
let statement = crate::problem::Statement::new(
|
||||
crate::problem::StatementKind::IntegrityConstraint, integrity_constraint)
|
||||
.with_name("integrity_constraint".to_string());
|
||||
|
@@ -1,6 +1,6 @@
|
||||
pub(crate) struct HeadAtom<'a>
|
||||
{
|
||||
pub predicate_declaration: std::rc::Rc<foliage::PredicateDeclaration>,
|
||||
pub predicate_declaration: std::rc::Rc<crate::PredicateDeclaration>,
|
||||
pub arguments: &'a [clingo::ast::Term<'a>],
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ pub(crate) enum HeadType<'a>
|
||||
pub(crate) fn determine_head_type<'a, C>(head_literal: &'a clingo::ast::HeadLiteral, context: &C)
|
||||
-> Result<HeadType<'a>, crate::Error>
|
||||
where
|
||||
C: foliage::FindOrCreatePredicateDeclaration
|
||||
C: foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>
|
||||
{
|
||||
let create_head_atom = |function: &'a clingo::ast::Function| -> Result<_, crate::Error>
|
||||
{
|
||||
|
@@ -1,11 +1,10 @@
|
||||
// TODO: rename context
|
||||
pub(crate) fn translate_body_term<C>(body_term: &clingo::ast::Term, sign: clingo::ast::Sign,
|
||||
context: &C, variable_declaration_stack: &foliage::VariableDeclarationStackLayer)
|
||||
-> Result<foliage::Formula, crate::Error>
|
||||
context: &C, variable_declaration_stack: &crate::VariableDeclarationStackLayer)
|
||||
-> Result<crate::Formula, crate::Error>
|
||||
where
|
||||
C: foliage::FindOrCreateFunctionDeclaration
|
||||
+ foliage::FindOrCreatePredicateDeclaration
|
||||
+ crate::traits::AssignVariableDeclarationDomain
|
||||
C: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>
|
||||
+ foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>,
|
||||
{
|
||||
let function = match body_term.term_type()
|
||||
{
|
||||
@@ -18,22 +17,16 @@ where
|
||||
let predicate_declaration = context.find_or_create_predicate_declaration(function_name,
|
||||
function.arguments().len());
|
||||
|
||||
let parameters = function.arguments().iter().map(|_|
|
||||
{
|
||||
let variable_declaration = std::rc::Rc::new(
|
||||
foliage::VariableDeclaration::new("<anonymous>".to_string()));
|
||||
context.assign_variable_declaration_domain(&variable_declaration,
|
||||
crate::Domain::Program);
|
||||
variable_declaration
|
||||
})
|
||||
.collect::<foliage::VariableDeclarations>();
|
||||
let parameters = function.arguments().iter().map(
|
||||
|_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(crate::Domain::Program)))
|
||||
.collect::<crate::VariableDeclarations>();
|
||||
let parameters = std::rc::Rc::new(parameters);
|
||||
|
||||
let predicate_arguments = parameters.iter().map(
|
||||
|parameter| foliage::Term::variable(std::rc::Rc::clone(parameter)))
|
||||
|parameter| crate::Term::variable(std::rc::Rc::clone(parameter)))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let predicate = foliage::Formula::predicate(predicate_declaration, predicate_arguments);
|
||||
let predicate = crate::Formula::predicate(predicate_declaration, predicate_arguments);
|
||||
|
||||
let predicate_literal = match sign
|
||||
{
|
||||
@@ -41,7 +34,7 @@ where
|
||||
| clingo::ast::Sign::DoubleNegation
|
||||
=> predicate,
|
||||
clingo::ast::Sign::Negation
|
||||
=> foliage::Formula::not(Box::new(predicate)),
|
||||
=> crate::Formula::not(Box::new(predicate)),
|
||||
};
|
||||
|
||||
if function.arguments().is_empty()
|
||||
@@ -60,18 +53,17 @@ where
|
||||
|
||||
arguments.push(predicate_literal);
|
||||
|
||||
let and = foliage::Formula::and(arguments);
|
||||
let and = crate::Formula::and(arguments);
|
||||
|
||||
Ok(foliage::Formula::exists(parameters, Box::new(and)))
|
||||
Ok(crate::Formula::exists(parameters, Box::new(and)))
|
||||
}
|
||||
|
||||
pub(crate) fn translate_body_literal<C>(body_literal: &clingo::ast::BodyLiteral,
|
||||
context: &C, variable_declaration_stack: &foliage::VariableDeclarationStackLayer)
|
||||
-> Result<foliage::Formula, crate::Error>
|
||||
context: &C, variable_declaration_stack: &crate::VariableDeclarationStackLayer)
|
||||
-> Result<crate::Formula, crate::Error>
|
||||
where
|
||||
C: foliage::FindOrCreateFunctionDeclaration
|
||||
+ foliage::FindOrCreatePredicateDeclaration
|
||||
+ crate::traits::AssignVariableDeclarationDomain
|
||||
C: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>
|
||||
+ foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>,
|
||||
{
|
||||
match body_literal.sign()
|
||||
{
|
||||
@@ -97,21 +89,16 @@ where
|
||||
_ => return Err(crate::Error::new_logic("unexpected negated Boolean value")),
|
||||
}
|
||||
|
||||
Ok(foliage::Formula::Boolean(value))
|
||||
Ok(crate::Formula::Boolean(value))
|
||||
},
|
||||
clingo::ast::LiteralType::Symbolic(term) => translate_body_term(term, literal.sign(),
|
||||
context, variable_declaration_stack),
|
||||
clingo::ast::LiteralType::Comparison(comparison) =>
|
||||
{
|
||||
let parameters = (0..2).map(|_|
|
||||
{
|
||||
let variable_declaration = std::rc::Rc::new(
|
||||
foliage::VariableDeclaration::new("<anonymous>".to_string()));
|
||||
context.assign_variable_declaration_domain(&variable_declaration,
|
||||
crate::Domain::Program);
|
||||
variable_declaration
|
||||
})
|
||||
.collect::<foliage::VariableDeclarations>();
|
||||
let parameters = (0..2).map(
|
||||
|_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
|
||||
crate::Domain::Program)))
|
||||
.collect::<crate::VariableDeclarations>();
|
||||
let parameters = std::rc::Rc::new(parameters);
|
||||
|
||||
let mut parameters_iterator = parameters.iter();
|
||||
@@ -123,19 +110,19 @@ where
|
||||
let choose_z2_in_t2 = crate::translate::common::choose_value_in_term(comparison.right(),
|
||||
std::rc::Rc::clone(parameter_z2), context, variable_declaration_stack)?;
|
||||
|
||||
let variable_1 = foliage::Term::variable(std::rc::Rc::clone(parameter_z1));
|
||||
let variable_2 = foliage::Term::variable(std::rc::Rc::clone(parameter_z2));
|
||||
let variable_1 = crate::Term::variable(std::rc::Rc::clone(parameter_z1));
|
||||
let variable_2 = crate::Term::variable(std::rc::Rc::clone(parameter_z2));
|
||||
|
||||
let operator = crate::translate::common::translate_comparison_operator(
|
||||
comparison.comparison_type());
|
||||
|
||||
let compare_z1_and_z2 = foliage::Formula::compare(operator, Box::new(variable_1),
|
||||
let compare_z1_and_z2 = crate::Formula::compare(operator, Box::new(variable_1),
|
||||
Box::new(variable_2));
|
||||
|
||||
let and =
|
||||
foliage::Formula::and(vec![choose_z1_in_t1, choose_z2_in_t2, compare_z1_and_z2]);
|
||||
crate::Formula::and(vec![choose_z1_in_t1, choose_z2_in_t2, compare_z1_and_z2]);
|
||||
|
||||
Ok(foliage::Formula::exists(parameters, Box::new(and)))
|
||||
Ok(crate::Formula::exists(parameters, Box::new(and)))
|
||||
},
|
||||
_ => Err(crate::Error::new_unsupported_language_feature(
|
||||
"body literals other than Booleans, terms, or comparisons")),
|
||||
@@ -143,15 +130,14 @@ where
|
||||
}
|
||||
|
||||
pub(crate) fn translate_body<C>(body_literals: &[clingo::ast::BodyLiteral], context: &C,
|
||||
variable_declaration_stack: &foliage::VariableDeclarationStackLayer)
|
||||
-> Result<foliage::Formulas, crate::Error>
|
||||
variable_declaration_stack: &crate::VariableDeclarationStackLayer)
|
||||
-> Result<crate::Formulas, crate::Error>
|
||||
where
|
||||
C: foliage::FindOrCreateFunctionDeclaration
|
||||
+ foliage::FindOrCreatePredicateDeclaration
|
||||
+ crate::traits::AssignVariableDeclarationDomain
|
||||
C: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>
|
||||
+ foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>,
|
||||
{
|
||||
body_literals.iter()
|
||||
.map(|body_literal| translate_body_literal(body_literal, context,
|
||||
variable_declaration_stack))
|
||||
.collect::<Result<foliage::Formulas, crate::Error>>()
|
||||
.collect::<Result<crate::Formulas, crate::Error>>()
|
||||
}
|
||||
|
Reference in New Issue
Block a user