diff --git a/include/plasp/pddl/translation/Effect.h b/include/plasp/pddl/translation/Effect.h index a8f7c8e..9b212fb 100644 --- a/include/plasp/pddl/translation/Effect.h +++ b/include/plasp/pddl/translation/Effect.h @@ -9,6 +9,8 @@ #include #include +#include +#include namespace plasp { @@ -22,7 +24,7 @@ namespace pddl //////////////////////////////////////////////////////////////////////////////////////////////////// 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, const std::string &objectType, PrintObjectName printObjectName, VariableStack &variableStack) { const auto handlePredicate = [&](const ::pddl::normalizedAST::PredicatePointer &predicate, bool isPositive = true) @@ -36,13 +38,37 @@ inline void translateEffect(colorlog::ColorStream &outputStream, const ::pddl::n translatePredicateToVariable(outputStream, *predicate, isPositive); outputStream << ") :- " << colorlog::Function(objectType.c_str()) << "("; printObjectName(); - outputStream << ")."; + 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) { - throw TranslatorException("derived predicates not yet supported by translator"); + // TODO: refactor as to exclude derived predicates from the Effect variant + throw TranslatorException("derived predicates should not appear in effects"); + }; + + const auto handleNegatedDerivedPredicate = + [&](const ::pddl::normalizedAST::DerivedPredicatePointer &derivedPredicate) + { + handleDerivedPredicate(derivedPredicate, false); }; const auto handleAtomicFormula = @@ -54,12 +80,7 @@ inline void translateEffect(colorlog::ColorStream &outputStream, const ::pddl::n const auto handleNot = [&](const ::pddl::normalizedAST::NotPointer<::pddl::normalizedAST::AtomicFormula> ¬_) { - if (!not_->argument.is<::pddl::normalizedAST::PredicatePointer>()) - throw TranslatorException("only “and” expressions and (negated) predicates supported as action effects currently"); - - const auto &predicate = not_->argument.get<::pddl::normalizedAST::PredicatePointer>(); - - handlePredicate(predicate, false); + not_->argument.match(handleNegatedPredicate, handleNegatedDerivedPredicate); }; const auto handleLiteral = @@ -72,13 +93,17 @@ 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); + translateEffect(outputStream, argument, objectType, printObjectName, variableStack); }; const auto handleForAll = - [&](const ::pddl::normalizedAST::ForAllPointer<::pddl::normalizedAST::Effect> &) + [&](const ::pddl::normalizedAST::ForAllPointer<::pddl::normalizedAST::Effect> &forAll) { - throw TranslatorException("“when” expressions not yet supported by translator"); + variableStack.push(&forAll->parameters); + + translateEffect(outputStream, forAll->argument, objectType, printObjectName, variableStack); + + variableStack.pop(); }; const auto handleWhen = @@ -92,6 +117,16 @@ 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) +{ + VariableStack variableStack; + + translateEffect(outputStream, effect, objectType, printObjectName, variableStack); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } diff --git a/include/plasp/pddl/translation/VariableStack.h b/include/plasp/pddl/translation/VariableStack.h new file mode 100644 index 0000000..e3b8e0d --- /dev/null +++ b/include/plasp/pddl/translation/VariableStack.h @@ -0,0 +1,39 @@ +#ifndef __PLASP__PDDL__TRANSLATION__VARIABLE_STACK_H +#define __PLASP__PDDL__TRANSLATION__VARIABLE_STACK_H + +#include + +namespace plasp +{ +namespace pddl +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// VariableStack +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct VariableStack +{ + using Layer = ::pddl::normalizedAST::VariableDeclarations *; + + void push(Layer layer) + { + layers.push_back(layer); + } + + void pop() + { + layers.pop_back(); + } + + std::vector layers; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/src/plasp/pddl/TranslatorASP.cpp b/src/plasp/pddl/TranslatorASP.cpp index 270f415..0722984 100644 --- a/src/plasp/pddl/TranslatorASP.cpp +++ b/src/plasp/pddl/TranslatorASP.cpp @@ -337,6 +337,7 @@ void TranslatorASP::translateActions() const if (action->precondition) translatePrecondition(m_outputStream, action->precondition.value(), "action", printActionName); + // Effect if (action->effect) translateEffect(m_outputStream, action->effect.value(), "action", printActionName);