diff --git a/include/plasp/pddl/TranslatorASP.h b/include/plasp/pddl/TranslatorASP.h index 239f4d7..379f6f5 100644 --- a/include/plasp/pddl/TranslatorASP.h +++ b/include/plasp/pddl/TranslatorASP.h @@ -28,6 +28,7 @@ class TranslatorASP void translateDomain() const; void translateTypes() const; void translatePredicates() const; + void translateDerivedPredicates() const; void translateActions() const; void translateProblem() const; diff --git a/include/plasp/pddl/translation/DerivedPredicate.h b/include/plasp/pddl/translation/DerivedPredicate.h new file mode 100644 index 0000000..6d9dc03 --- /dev/null +++ b/include/plasp/pddl/translation/DerivedPredicate.h @@ -0,0 +1,120 @@ +#ifndef __PLASP__PDDL__TRANSLATION__DERIVED_PREDICATE_H +#define __PLASP__PDDL__TRANSLATION__DERIVED_PREDICATE_H + +#include + +#include +#include + +#include +#include + +namespace plasp +{ +namespace pddl +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// DerivedPredicate +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void translateDerivedPredicate(colorlog::ColorStream &outputStream, const ::pddl::normalizedAST::DerivedPredicate &derivedPredicate); +void translateDerivedPredicateDeclaration(colorlog::ColorStream &outputStream, const ::pddl::normalizedAST::DerivedPredicateDeclaration &derivedPredicateDeclaration); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +inline void translateDerivedPredicate(colorlog::ColorStream &outputStream, const ::pddl::normalizedAST::DerivedPredicate &derivedPredicate) +{ + const auto &arguments = derivedPredicate.arguments; + + if (arguments.empty()) + { + outputStream << *derivedPredicate.declaration; + return; + } + + outputStream << "(" << *derivedPredicate.declaration; + + for (const auto &argument : arguments) + { + outputStream << ", "; + + const auto handleConstant = + [&](const ::pddl::normalizedAST::ConstantPointer &constant) + { + outputStream << colorlog::Keyword("constant") << "(" << *constant << ")"; + }; + + const auto handleVariable = + [&](const ::pddl::normalizedAST::VariablePointer &variable) + { + outputStream << *variable; + }; + + argument.match(handleConstant, handleVariable); + } + + outputStream << ")"; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +inline void translateDerivedPredicateDeclaration(colorlog::ColorStream &outputStream, const ::pddl::normalizedAST::DerivedPredicateDeclaration &derivedPredicateDeclaration) +{ + outputStream << colorlog::Keyword("derivedVariable") << "("; + + if (derivedPredicateDeclaration.parameters.empty()) + { + outputStream << derivedPredicateDeclaration << ")"; + return; + } + + outputStream << "(" << derivedPredicateDeclaration; + translateVariablesForRuleHead(outputStream, derivedPredicateDeclaration.parameters); + outputStream << "))"; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +inline void translateDerivedPredicateToVariable(colorlog::ColorStream &outputStream, const ::pddl::normalizedAST::DerivedPredicate &derivedPredicate, bool isPositive = true) +{ + outputStream << colorlog::Keyword("derivedVariable") << "("; + translateDerivedPredicate(outputStream, derivedPredicate); + outputStream << "), " << colorlog::Keyword("value") << "("; + translateDerivedPredicate(outputStream, derivedPredicate); + outputStream << ", "; + + if (isPositive) + outputStream << colorlog::Boolean("true"); + else + outputStream << colorlog::Boolean("false"); + + outputStream << ")"; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +inline void translateDerivedPredicateDeclarationToVariable(colorlog::ColorStream &outputStream, const ::pddl::normalizedAST::DerivedPredicateDeclaration &derivedPredicateDeclaration, bool isPositive = true) +{ + outputStream << colorlog::Keyword("derivedVariable") << "("; + translateDerivedPredicateDeclaration(outputStream, derivedPredicateDeclaration); + outputStream << "), " << colorlog::Keyword("value") << "("; + translateDerivedPredicateDeclaration(outputStream, derivedPredicateDeclaration); + outputStream << ", "; + + if (isPositive) + outputStream << colorlog::Boolean("true"); + else + outputStream << colorlog::Boolean("false"); + + outputStream << ")"; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/pddl/translation/DerivedPredicatePrecondition.h b/include/plasp/pddl/translation/DerivedPredicatePrecondition.h new file mode 100644 index 0000000..abeb4ac --- /dev/null +++ b/include/plasp/pddl/translation/DerivedPredicatePrecondition.h @@ -0,0 +1,104 @@ +#ifndef __PLASP__PDDL__TRANSLATION__DERIVED_PREDICATE_PRECONDITION_H +#define __PLASP__PDDL__TRANSLATION__DERIVED_PREDICATE_PRECONDITION_H + +#include + +#include + +#include + +#include +#include +#include + +namespace plasp +{ +namespace pddl +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// DerivedPredicatePrecondition +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +inline void translateDerivedPredicatePrecondition(colorlog::ColorStream &outputStream, const ::pddl::normalizedAST::DerivedPredicatePrecondition &derivedPredicatePrecondition, const std::string &objectType, PrintObjectName printObjectName) +{ + const auto handlePredicate = + [&](const ::pddl::normalizedAST::PredicatePointer &predicate, bool isPositive = true) + { + outputStream << std::endl << colorlog::Function("precondition") << "("; + printObjectName(); + outputStream << ", "; + translatePredicateToVariable(outputStream, *predicate, isPositive); + outputStream << ") :- " << colorlog::Function(objectType.c_str()) << "("; + printObjectName(); + outputStream << ")."; + }; + + const auto handleNegatedPredicate = + [&](const ::pddl::normalizedAST::PredicatePointer &predicate) + { + handlePredicate(predicate, false); + }; + + const auto handleDerivedPredicate = + [&](const ::pddl::normalizedAST::DerivedPredicatePointer &derivedPredicate, bool isPositive = true) + { + outputStream << std::endl << colorlog::Function("precondition") << "("; + printObjectName(); + outputStream << ", "; + translateDerivedPredicateToVariable(outputStream, *derivedPredicate, isPositive); + outputStream << ") :- " << colorlog::Function(objectType.c_str()) << "("; + printObjectName(); + outputStream << ")."; + }; + + 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); + }; + + const auto handleOr = + [&](const ::pddl::normalizedAST::OrPointer<::pddl::normalizedAST::Literal> &or_) + { + for (const auto &argument : or_->arguments) + handleLiteral(argument); + }; + + derivedPredicatePrecondition.match(handleLiteral, handleAnd, handleOr); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/pddl/translation/Precondition.h b/include/plasp/pddl/translation/Precondition.h index a34ded1..698fecc 100644 --- a/include/plasp/pddl/translation/Precondition.h +++ b/include/plasp/pddl/translation/Precondition.h @@ -7,6 +7,7 @@ #include +#include #include #include @@ -43,16 +44,15 @@ inline void translatePrecondition(colorlog::ColorStream &outputStream, const ::p }; const auto handleDerivedPredicate = - [&](const ::pddl::normalizedAST::DerivedPredicatePointer &, bool = true) + [&](const ::pddl::normalizedAST::DerivedPredicatePointer &derivedPredicate, bool isPositive = true) { outputStream << std::endl << colorlog::Function("precondition") << "("; printObjectName(); outputStream << ", "; - // TODO: implement - /*translatePredicateToVariable(outputStream, *predicate, isPositive); - outputStream << ") :- " << output::Function(objectType.c_str()) << "("; + translateDerivedPredicateToVariable(outputStream, *derivedPredicate, isPositive); + outputStream << ") :- " << colorlog::Function(objectType.c_str()) << "("; printObjectName(); - outputStream << ").";*/ + outputStream << ")."; }; const auto handleNegatedDerivedPredicate = diff --git a/include/plasp/pddl/translation/Variables.h b/include/plasp/pddl/translation/Variables.h index 491a1d4..27f7faf 100644 --- a/include/plasp/pddl/translation/Variables.h +++ b/include/plasp/pddl/translation/Variables.h @@ -29,9 +29,6 @@ void translateVariablesForRuleBody(colorlog::ColorStream &outputStream, const T template inline void translateVariablesForRuleHead(colorlog::ColorStream &outputStream, const T &variables) { - if (variables.empty()) - return; - for (const auto &variable : variables) outputStream << ", " << *variable; } @@ -39,16 +36,11 @@ inline void translateVariablesForRuleHead(colorlog::ColorStream &outputStream, c //////////////////////////////////////////////////////////////////////////////////////////////////// template -inline void translateVariablesForRuleBody(colorlog::ColorStream &outputStream, const T &variables) +void translateVariablesForRuleBody(colorlog::ColorStream &outputStream, const T &variables) { - if (variables.empty()) - return; - - outputStream << " :- "; - for (const auto &variable : variables) { - if (variable.get() != variables.begin()->get()) + if (&variable != &*variables.begin()) outputStream << ", "; if (variable->type) diff --git a/src/plasp/pddl/TranslatorASP.cpp b/src/plasp/pddl/TranslatorASP.cpp index 97ebbd2..34e2fa1 100644 --- a/src/plasp/pddl/TranslatorASP.cpp +++ b/src/plasp/pddl/TranslatorASP.cpp @@ -8,6 +8,8 @@ #include +#include +#include #include #include #include @@ -71,6 +73,12 @@ void TranslatorASP::translateDomain() const translatePredicates(); } + if (!domain->derivedPredicates.empty()) + { + m_outputStream << std::endl; + translateDerivedPredicates(); + } + // Actions if (!domain->actions.empty()) { @@ -148,7 +156,11 @@ void TranslatorASP::translatePredicates() const m_outputStream << ")"; - translateVariablesForRuleBody(m_outputStream, predicate->parameters); + if (!predicate->parameters.empty()) + { + m_outputStream << " :- "; + translateVariablesForRuleBody(m_outputStream, predicate->parameters); + } m_outputStream << "."; } @@ -168,6 +180,115 @@ void TranslatorASP::translatePredicates() const //////////////////////////////////////////////////////////////////////////////////////////////////// +void TranslatorASP::translateDerivedPredicates() const +{ + m_outputStream << colorlog::Heading2("derived predicates"); + + const auto &derivedPredicates = m_description.domain->derivedPredicates; + + for (const auto &derivedPredicate : derivedPredicates) + { + m_outputStream << std::endl << colorlog::Function("derivedVariable") << "("; + + translateDerivedPredicateDeclaration(m_outputStream, *derivedPredicate); + + m_outputStream << ")"; + + if (!derivedPredicate->parameters.empty() || !derivedPredicate->existentialParameters.empty()) + { + m_outputStream << " :- "; + translateVariablesForRuleBody(m_outputStream, derivedPredicate->parameters); + } + + m_outputStream << "."; + } + + m_outputStream + << std::endl << std::endl + << colorlog::Function("boolean") << "(" << colorlog::Boolean("true") << ")." << std::endl + << colorlog::Function("boolean") << "(" << colorlog::Boolean("false") << ")." << std::endl + << std::endl + << colorlog::Function("contains") << "(" + << colorlog::Keyword("derivedVariable") << "(" << colorlog::Variable("X") << "), " + << colorlog::Keyword("value") << "(" << colorlog::Variable("X") << ", " << colorlog::Variable("B") << ")) :- " + << colorlog::Function("derivedVariable") << "(" << colorlog::Keyword("derivedVariable") << "(" << colorlog::Variable("X") << ")), " + << colorlog::Function("boolean") << "(" << colorlog::Variable("B") << ")." + << std::endl << std::endl; + + for (const auto &derivedPredicate : derivedPredicates) + { + const auto printDerivedPredicateName = + [&]() + { + m_outputStream << colorlog::Keyword("derivedPredicate") << "("; + + if (derivedPredicate->parameters.empty()) + { + m_outputStream << *derivedPredicate << ")"; + return; + } + + m_outputStream << "(" << *derivedPredicate; + // TODO: add existentially quantified parameters + translateVariablesForRuleHead(m_outputStream, derivedPredicate->parameters); + + if (!derivedPredicate->existentialParameters.empty()) + translateVariablesForRuleHead(m_outputStream, derivedPredicate->existentialParameters); + + m_outputStream << "))"; + }; + + m_outputStream << std::endl; + + // Name + m_outputStream << colorlog::Function("derivedPredicate") << "("; + printDerivedPredicateName(); + m_outputStream << ", " << colorlog::Keyword("type") << "("; + + if (derivedPredicate->precondition.value().is<::pddl::normalizedAST::OrPointer<::pddl::normalizedAST::Literal>>()) + m_outputStream << colorlog::Reserved("or"); + else + m_outputStream << colorlog::Reserved("and"); + + m_outputStream << "))"; + + if (!derivedPredicate->parameters.empty() || !derivedPredicate->existentialParameters.empty()) + m_outputStream << " :- "; + + if (!derivedPredicate->parameters.empty()) + translateVariablesForRuleBody(m_outputStream, derivedPredicate->parameters); + + if (!derivedPredicate->existentialParameters.empty()) + { + if (!derivedPredicate->parameters.empty()) + m_outputStream << ", "; + + translateVariablesForRuleBody(m_outputStream, derivedPredicate->existentialParameters); + } + + m_outputStream << "."; + + // Precondition + if (derivedPredicate->precondition) + translateDerivedPredicatePrecondition(m_outputStream, derivedPredicate->precondition.value(), "derivedPredicate", printDerivedPredicateName); + + m_outputStream << std::endl << colorlog::Function("postcondition") << "("; + printDerivedPredicateName(); + m_outputStream + << ", " << colorlog::Keyword("effect") << "(" + << colorlog::Reserved("unconditional") << ")" + << ", "; + translateDerivedPredicateDeclarationToVariable(m_outputStream, *derivedPredicate, true); + m_outputStream << ") :- " << colorlog::Function("derivedPredicate") << "("; + printDerivedPredicateName(); + m_outputStream << ")."; + + m_outputStream << std::endl; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void TranslatorASP::translateActions() const { m_outputStream << colorlog::Heading2("actions"); @@ -199,7 +320,11 @@ void TranslatorASP::translateActions() const printActionName(); m_outputStream << ")"; - translateVariablesForRuleBody(m_outputStream, action->parameters); + if (!action->parameters.empty()) + { + m_outputStream << " :- "; + translateVariablesForRuleBody(m_outputStream, action->parameters); + } m_outputStream << ".";