From d82ae8544b36f9434df57bf0c44e67c135f765c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Wed, 28 Jun 2017 00:28:36 +0200 Subject: [PATCH] Implemented translation of conditional PDDL effects. --- .../pddl/translation/ConditionalEffect.h | 110 ++++++++++++++++++ include/plasp/pddl/translation/Effect.h | 55 +++++++-- include/plasp/pddl/translation/Precondition.h | 18 +-- src/plasp/pddl/TranslatorASP.cpp | 16 ++- 4 files changed, 181 insertions(+), 18 deletions(-) create mode 100644 include/plasp/pddl/translation/ConditionalEffect.h diff --git a/include/plasp/pddl/translation/ConditionalEffect.h b/include/plasp/pddl/translation/ConditionalEffect.h new file mode 100644 index 0000000..0e8a38b --- /dev/null +++ b/include/plasp/pddl/translation/ConditionalEffect.h @@ -0,0 +1,110 @@ +#ifndef __PLASP__PDDL__TRANSLATION__CONDITIONAL_EFFECT_H +#define __PLASP__PDDL__TRANSLATION__CONDITIONAL_EFFECT_H + +#include + +#include + +#include + +#include +#include +#include +#include + +namespace plasp +{ +namespace pddl +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// ConditionalEffect +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +inline void translateConditionalEffect(colorlog::ColorStream &outputStream, + const ::pddl::normalizedAST::ConditionalEffect &conditionalEffect, + PrintObjectName printObjectName, VariableStack &variableStack, + size_t &numberOfConditionalEffects) +{ + const auto handlePredicate = + [&](const ::pddl::normalizedAST::PredicatePointer &predicate, bool isPositive = true) + { + outputStream << std::endl << colorlog::Function("postcondition") << "("; + printObjectName(); + outputStream + << ", " << colorlog::Keyword("effect") << "(" + << colorlog::Number(numberOfConditionalEffects) << ")" + << ", "; + translatePredicateToVariable(outputStream, *predicate, isPositive); + outputStream << ") :- " << colorlog::Function("action") << "("; + printObjectName(); + outputStream << ")"; + + if (!variableStack.layers.empty()) + for (const auto &layer : variableStack.layers) + { + if (!layer->empty()) + outputStream << ", "; + + translateVariablesForRuleBody(outputStream, *layer); + } + + outputStream << "."; + }; + + const auto handleNegatedPredicate = + [&](const ::pddl::normalizedAST::PredicatePointer &predicate) + { + handlePredicate(predicate, false); + }; + + const auto handleDerivedPredicate = + [&](const ::pddl::normalizedAST::DerivedPredicatePointer &, bool = true) + { + // TODO: refactor as to exclude derived predicates from the Effect variant + throw TranslatorException("derived predicates should not appear in effects, please report to the bug tracker"); + }; + + const auto handleNegatedDerivedPredicate = + [&](const ::pddl::normalizedAST::DerivedPredicatePointer &derivedPredicate) + { + handleDerivedPredicate(derivedPredicate, false); + }; + + const auto handleAtomicFormula = + [&](const ::pddl::normalizedAST::AtomicFormula &atomicFormula) + { + atomicFormula.match(handlePredicate, handleDerivedPredicate); + }; + + const auto handleNot = + [&](const ::pddl::normalizedAST::NotPointer<::pddl::normalizedAST::AtomicFormula> ¬_) + { + not_->argument.match(handleNegatedPredicate, handleNegatedDerivedPredicate); + }; + + const auto handleLiteral = + [&](const ::pddl::normalizedAST::Literal &literal) + { + literal.match(handleAtomicFormula, handleNot); + }; + + const auto handleAnd = + [&](const ::pddl::normalizedAST::AndPointer<::pddl::normalizedAST::Literal> &and_) + { + for (const auto &argument : and_->arguments) + handleLiteral(argument); + }; + + conditionalEffect.match(handleAnd, handleLiteral); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/pddl/translation/Effect.h b/include/plasp/pddl/translation/Effect.h index 2ceddc3..5479d2e 100644 --- a/include/plasp/pddl/translation/Effect.h +++ b/include/plasp/pddl/translation/Effect.h @@ -7,6 +7,8 @@ #include +#include +#include #include #include #include @@ -24,7 +26,9 @@ namespace pddl //////////////////////////////////////////////////////////////////////////////////////////////////// template -inline void translateEffect(colorlog::ColorStream &outputStream, const ::pddl::normalizedAST::Effect &effect, const std::string &objectType, PrintObjectName printObjectName, VariableStack &variableStack) +inline void translateEffect(colorlog::ColorStream &outputStream, + const ::pddl::normalizedAST::Effect &effect, PrintObjectName printObjectName, + VariableStack &variableStack, size_t &numberOfConditionalEffects) { const auto handlePredicate = [&](const ::pddl::normalizedAST::PredicatePointer &predicate, bool isPositive = true) @@ -36,7 +40,7 @@ inline void translateEffect(colorlog::ColorStream &outputStream, const ::pddl::n << colorlog::Reserved("unconditional") << ")" << ", "; translatePredicateToVariable(outputStream, *predicate, isPositive); - outputStream << ") :- " << colorlog::Function(objectType.c_str()) << "("; + outputStream << ") :- " << colorlog::Function("action") << "("; printObjectName(); outputStream << ")"; @@ -93,7 +97,8 @@ inline void translateEffect(colorlog::ColorStream &outputStream, const ::pddl::n [&](const ::pddl::normalizedAST::AndPointer<::pddl::normalizedAST::Effect> &and_) { for (const auto &argument : and_->arguments) - translateEffect(outputStream, argument, objectType, printObjectName, variableStack); + translateEffect(outputStream, argument, printObjectName, variableStack, + numberOfConditionalEffects); }; const auto handleForAll = @@ -101,15 +106,46 @@ inline void translateEffect(colorlog::ColorStream &outputStream, const ::pddl::n { variableStack.push(&forAll->parameters); - translateEffect(outputStream, forAll->argument, objectType, printObjectName, variableStack); + translateEffect(outputStream, forAll->argument, printObjectName, + variableStack, numberOfConditionalEffects); variableStack.pop(); }; const auto handleWhen = - [&](const ::pddl::normalizedAST::WhenPointer<::pddl::normalizedAST::Precondition, ::pddl::normalizedAST::ConditionalEffect> &) + [&](const ::pddl::normalizedAST::WhenPointer<::pddl::normalizedAST::Precondition, + ::pddl::normalizedAST::ConditionalEffect> &when) { - throw TranslatorException("“when” expressions not yet supported by translator"); + numberOfConditionalEffects++; + + const auto printConditionalEffectIdentifier = + [&]() + { + outputStream << colorlog::Keyword("effect") << "(" + << colorlog::Number(numberOfConditionalEffects) << ")"; + }; + + const auto printPreconditionRuleBody = + [&]() + { + outputStream << " :- " << colorlog::Function("action") << "("; + printObjectName(); + outputStream << ")"; + + for (const auto &layer : variableStack.layers) + { + if (!layer->empty()) + outputStream << ", "; + + translateVariablesForRuleBody(outputStream, *layer); + } + }; + + translatePrecondition(outputStream, when->argumentLeft, + printConditionalEffectIdentifier, printPreconditionRuleBody); + + translateConditionalEffect(outputStream, when->argumentRight, printObjectName, + variableStack, numberOfConditionalEffects); }; effect.match(handleAnd, handleForAll, handleLiteral, handleWhen); @@ -118,11 +154,14 @@ inline void translateEffect(colorlog::ColorStream &outputStream, const ::pddl::n //////////////////////////////////////////////////////////////////////////////////////////////////// template -inline void translateEffect(colorlog::ColorStream &outputStream, const ::pddl::normalizedAST::Effect &effect, const std::string &objectType, PrintObjectName printObjectName) +inline void translateEffect(colorlog::ColorStream &outputStream, + const ::pddl::normalizedAST::Effect &effect, PrintObjectName printObjectName, + size_t &numberOfConditionalEffects) { VariableStack variableStack; - translateEffect(outputStream, effect, objectType, printObjectName, variableStack); + translateEffect(outputStream, effect, printObjectName, variableStack, + numberOfConditionalEffects); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/translation/Precondition.h b/include/plasp/pddl/translation/Precondition.h index 698fecc..e9fa89e 100644 --- a/include/plasp/pddl/translation/Precondition.h +++ b/include/plasp/pddl/translation/Precondition.h @@ -22,8 +22,10 @@ namespace pddl // //////////////////////////////////////////////////////////////////////////////////////////////////// -template -inline void translatePrecondition(colorlog::ColorStream &outputStream, const ::pddl::normalizedAST::Precondition &precondition, const std::string &objectType, PrintObjectName printObjectName) +template +inline void translatePrecondition(colorlog::ColorStream &outputStream, + const ::pddl::normalizedAST::Precondition &precondition, PrintObjectName printObjectName, + PrintRuleBody printRuleBody) { const auto handlePredicate = [&](const ::pddl::normalizedAST::PredicatePointer &predicate, bool isPositive = true) @@ -32,9 +34,9 @@ inline void translatePrecondition(colorlog::ColorStream &outputStream, const ::p printObjectName(); outputStream << ", "; translatePredicateToVariable(outputStream, *predicate, isPositive); - outputStream << ") :- " << colorlog::Function(objectType.c_str()) << "("; - printObjectName(); - outputStream << ")."; + outputStream << ")"; + printRuleBody(); + outputStream << "."; }; const auto handleNegatedPredicate = @@ -50,9 +52,9 @@ inline void translatePrecondition(colorlog::ColorStream &outputStream, const ::p printObjectName(); outputStream << ", "; translateDerivedPredicateToVariable(outputStream, *derivedPredicate, isPositive); - outputStream << ") :- " << colorlog::Function(objectType.c_str()) << "("; - printObjectName(); - outputStream << ")."; + outputStream << ")"; + printRuleBody(); + outputStream << "."; }; const auto handleNegatedDerivedPredicate = diff --git a/src/plasp/pddl/TranslatorASP.cpp b/src/plasp/pddl/TranslatorASP.cpp index 0722984..264f09a 100644 --- a/src/plasp/pddl/TranslatorASP.cpp +++ b/src/plasp/pddl/TranslatorASP.cpp @@ -300,6 +300,8 @@ void TranslatorASP::translateActions() const const auto &actions = m_description.domain->actions; + size_t numberOfConditionalEffects{0}; + for (const auto &action : actions) { const auto printActionName = @@ -318,6 +320,14 @@ void TranslatorASP::translateActions() const m_outputStream << "))"; }; + const auto printPreconditionRuleBody = + [&]() + { + m_outputStream << " :- " << colorlog::Function("action") << "("; + printActionName(); + m_outputStream << ")"; + }; + m_outputStream << std::endl; // Name @@ -335,11 +345,13 @@ void TranslatorASP::translateActions() const // Precondition if (action->precondition) - translatePrecondition(m_outputStream, action->precondition.value(), "action", printActionName); + translatePrecondition(m_outputStream, action->precondition.value(), printActionName, + printPreconditionRuleBody); // Effect if (action->effect) - translateEffect(m_outputStream, action->effect.value(), "action", printActionName); + translateEffect(m_outputStream, action->effect.value(), printActionName, + numberOfConditionalEffects); m_outputStream << std::endl; }