2020-05-05 19:40:57 +02:00
|
|
|
// TODO: rename context
|
2020-02-03 02:57:45 +01:00
|
|
|
pub(crate) fn translate_body_term<C>(body_term: &clingo::ast::Term, sign: clingo::ast::Sign,
|
2020-05-22 02:25:00 +02:00
|
|
|
context: &C, variable_declaration_stack: &crate::VariableDeclarationStackLayer)
|
|
|
|
-> Result<crate::Formula, crate::Error>
|
2020-02-03 02:57:45 +01:00
|
|
|
where
|
2020-05-22 02:25:00 +02:00
|
|
|
C: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>
|
|
|
|
+ foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>,
|
2020-01-31 17:24:13 +01:00
|
|
|
{
|
|
|
|
let function = match body_term.term_type()
|
|
|
|
{
|
|
|
|
clingo::ast::TermType::Function(value) => value,
|
|
|
|
_ => return Err(crate::Error::new_unsupported_language_feature("only functions supported as body terms")),
|
|
|
|
};
|
|
|
|
|
|
|
|
let function_name = function.name().map_err(|error| crate::Error::new_decode_identifier(error))?;
|
|
|
|
|
2020-04-17 04:10:23 +02:00
|
|
|
let predicate_declaration = context.find_or_create_predicate_declaration(function_name,
|
2020-01-31 17:24:13 +01:00
|
|
|
function.arguments().len());
|
|
|
|
|
2020-05-22 02:25:00 +02:00
|
|
|
let parameters = function.arguments().iter().map(
|
|
|
|
|_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(crate::Domain::Program)))
|
|
|
|
.collect::<crate::VariableDeclarations>();
|
2020-02-02 17:57:27 +01:00
|
|
|
let parameters = std::rc::Rc::new(parameters);
|
2020-01-31 17:24:13 +01:00
|
|
|
|
|
|
|
let predicate_arguments = parameters.iter().map(
|
2020-05-22 02:25:00 +02:00
|
|
|
|parameter| crate::Term::variable(std::rc::Rc::clone(parameter)))
|
2020-01-31 17:24:13 +01:00
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
2020-05-22 02:25:00 +02:00
|
|
|
let predicate = crate::Formula::predicate(predicate_declaration, predicate_arguments);
|
2020-01-31 17:24:13 +01:00
|
|
|
|
|
|
|
let predicate_literal = match sign
|
|
|
|
{
|
|
|
|
clingo::ast::Sign::None
|
|
|
|
| clingo::ast::Sign::DoubleNegation
|
2020-02-02 02:32:32 +01:00
|
|
|
=> predicate,
|
2020-01-31 17:24:13 +01:00
|
|
|
clingo::ast::Sign::Negation
|
2020-05-22 02:25:00 +02:00
|
|
|
=> crate::Formula::not(Box::new(predicate)),
|
2020-01-31 17:24:13 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
if function.arguments().is_empty()
|
|
|
|
{
|
|
|
|
return Ok(predicate_literal);
|
|
|
|
}
|
|
|
|
|
2020-02-02 02:32:32 +01:00
|
|
|
assert_eq!(function.arguments().len(), parameters.len());
|
2020-01-31 17:24:13 +01:00
|
|
|
|
2020-02-02 02:32:32 +01:00
|
|
|
let mut parameters_iterator = parameters.iter();
|
|
|
|
let mut arguments = function.arguments().iter().map(
|
2020-04-17 00:09:44 +02:00
|
|
|
|x| crate::translate::common::choose_value_in_term(x,
|
2020-04-17 03:28:18 +02:00
|
|
|
std::rc::Rc::clone(¶meters_iterator.next().unwrap()), context,
|
|
|
|
variable_declaration_stack))
|
2020-01-31 17:24:13 +01:00
|
|
|
.collect::<Result<Vec<_>, _>>()?;
|
|
|
|
|
2020-04-17 00:09:44 +02:00
|
|
|
arguments.push(predicate_literal);
|
2020-01-31 17:24:13 +01:00
|
|
|
|
2020-05-22 02:25:00 +02:00
|
|
|
let and = crate::Formula::and(arguments);
|
2020-01-31 17:24:13 +01:00
|
|
|
|
2020-05-22 02:25:00 +02:00
|
|
|
Ok(crate::Formula::exists(parameters, Box::new(and)))
|
2020-01-31 17:24:13 +01:00
|
|
|
}
|
|
|
|
|
2020-02-03 02:57:45 +01:00
|
|
|
pub(crate) fn translate_body_literal<C>(body_literal: &clingo::ast::BodyLiteral,
|
2020-05-22 02:25:00 +02:00
|
|
|
context: &C, variable_declaration_stack: &crate::VariableDeclarationStackLayer)
|
|
|
|
-> Result<crate::Formula, crate::Error>
|
2020-02-03 02:57:45 +01:00
|
|
|
where
|
2020-05-22 02:25:00 +02:00
|
|
|
C: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>
|
|
|
|
+ foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>,
|
2020-01-31 17:24:13 +01:00
|
|
|
{
|
|
|
|
match body_literal.sign()
|
|
|
|
{
|
|
|
|
clingo::ast::Sign::None => (),
|
|
|
|
_ => return Err(crate::Error::new_unsupported_language_feature(
|
|
|
|
"signed body literals")),
|
|
|
|
}
|
|
|
|
|
|
|
|
let literal = match body_literal.body_literal_type()
|
|
|
|
{
|
|
|
|
clingo::ast::BodyLiteralType::Literal(literal) => literal,
|
|
|
|
_ => return Err(crate::Error::new_unsupported_language_feature(
|
|
|
|
"only plain body literals supported")),
|
|
|
|
};
|
|
|
|
|
|
|
|
match literal.literal_type()
|
|
|
|
{
|
|
|
|
clingo::ast::LiteralType::Boolean(value) =>
|
|
|
|
{
|
|
|
|
match literal.sign()
|
|
|
|
{
|
|
|
|
clingo::ast::Sign::None => (),
|
|
|
|
_ => return Err(crate::Error::new_logic("unexpected negated Boolean value")),
|
|
|
|
}
|
|
|
|
|
2020-05-22 02:25:00 +02:00
|
|
|
Ok(crate::Formula::Boolean(value))
|
2020-01-31 17:24:13 +01:00
|
|
|
},
|
2020-02-01 19:20:46 +01:00
|
|
|
clingo::ast::LiteralType::Symbolic(term) => translate_body_term(term, literal.sign(),
|
2020-04-17 03:28:18 +02:00
|
|
|
context, variable_declaration_stack),
|
2020-01-31 17:24:13 +01:00
|
|
|
clingo::ast::LiteralType::Comparison(comparison) =>
|
|
|
|
{
|
2020-05-22 02:25:00 +02:00
|
|
|
let parameters = (0..2).map(
|
|
|
|
|_| std::rc::Rc::new(crate::VariableDeclaration::new_generated(
|
|
|
|
crate::Domain::Program)))
|
|
|
|
.collect::<crate::VariableDeclarations>();
|
2020-02-02 17:57:27 +01:00
|
|
|
let parameters = std::rc::Rc::new(parameters);
|
2020-01-31 17:24:13 +01:00
|
|
|
|
2020-02-02 02:32:32 +01:00
|
|
|
let mut parameters_iterator = parameters.iter();
|
|
|
|
let parameter_z1 = ¶meters_iterator.next().unwrap();
|
|
|
|
let parameter_z2 = ¶meters_iterator.next().unwrap();
|
2020-01-31 17:24:13 +01:00
|
|
|
|
2020-02-02 02:32:32 +01:00
|
|
|
let choose_z1_in_t1 = crate::translate::common::choose_value_in_term(comparison.left(),
|
2020-04-17 03:28:18 +02:00
|
|
|
std::rc::Rc::clone(parameter_z1), context, variable_declaration_stack)?;
|
2020-02-02 02:32:32 +01:00
|
|
|
let choose_z2_in_t2 = crate::translate::common::choose_value_in_term(comparison.right(),
|
2020-04-17 03:28:18 +02:00
|
|
|
std::rc::Rc::clone(parameter_z2), context, variable_declaration_stack)?;
|
2020-01-31 17:24:13 +01:00
|
|
|
|
2020-05-22 02:25:00 +02:00
|
|
|
let variable_1 = crate::Term::variable(std::rc::Rc::clone(parameter_z1));
|
|
|
|
let variable_2 = crate::Term::variable(std::rc::Rc::clone(parameter_z2));
|
2020-01-31 17:24:13 +01:00
|
|
|
|
2020-02-02 02:32:32 +01:00
|
|
|
let operator = crate::translate::common::translate_comparison_operator(
|
|
|
|
comparison.comparison_type());
|
2020-01-31 17:24:13 +01:00
|
|
|
|
2020-05-22 02:25:00 +02:00
|
|
|
let compare_z1_and_z2 = crate::Formula::compare(operator, Box::new(variable_1),
|
2020-02-02 02:32:32 +01:00
|
|
|
Box::new(variable_2));
|
2020-01-31 17:24:13 +01:00
|
|
|
|
2020-04-17 00:09:44 +02:00
|
|
|
let and =
|
2020-05-22 02:25:00 +02:00
|
|
|
crate::Formula::and(vec![choose_z1_in_t1, choose_z2_in_t2, compare_z1_and_z2]);
|
2020-01-31 17:24:13 +01:00
|
|
|
|
2020-05-22 02:25:00 +02:00
|
|
|
Ok(crate::Formula::exists(parameters, Box::new(and)))
|
2020-01-31 17:24:13 +01:00
|
|
|
},
|
|
|
|
_ => Err(crate::Error::new_unsupported_language_feature(
|
|
|
|
"body literals other than Booleans, terms, or comparisons")),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-17 03:28:18 +02:00
|
|
|
pub(crate) fn translate_body<C>(body_literals: &[clingo::ast::BodyLiteral], context: &C,
|
2020-05-22 02:25:00 +02:00
|
|
|
variable_declaration_stack: &crate::VariableDeclarationStackLayer)
|
|
|
|
-> Result<crate::Formulas, crate::Error>
|
2020-02-03 02:57:45 +01:00
|
|
|
where
|
2020-05-22 02:25:00 +02:00
|
|
|
C: foliage::FindOrCreateFunctionDeclaration<crate::FoliageFlavor>
|
|
|
|
+ foliage::FindOrCreatePredicateDeclaration<crate::FoliageFlavor>,
|
2020-01-31 17:24:13 +01:00
|
|
|
{
|
|
|
|
body_literals.iter()
|
2020-04-17 03:28:18 +02:00
|
|
|
.map(|body_literal| translate_body_literal(body_literal, context,
|
|
|
|
variable_declaration_stack))
|
2020-05-22 02:25:00 +02:00
|
|
|
.collect::<Result<crate::Formulas, crate::Error>>()
|
2020-01-31 17:24:13 +01:00
|
|
|
}
|