From 9d1a8f4c0f1839d5eda1c3cf26c93b482b4e0669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Fri, 23 Jun 2017 04:18:07 +0200 Subject: [PATCH] Started implementing PDDL normalization. --- app/main.cpp | 5 +- include/plasp/pddl/TranslatorASP.h | 6 +- include/plasp/pddl/translation/Effect.h | 16 +- include/plasp/pddl/translation/Goal.h | 71 +++--- include/plasp/pddl/translation/Precondition.h | 74 +++--- include/plasp/pddl/translation/Predicate.h | 16 +- include/plasp/pddl/translation/Primitives.h | 36 ++- include/plasp/pddl/translation/Variables.h | 6 +- lib/pddlparse/include/pddlparse/Exception.h | 8 + lib/pddlparse/include/pddlparse/Normalize.h | 24 ++ .../include/pddlparse/NormalizedAST.h | 1 + .../include/pddlparse/NormalizedASTForward.h | 5 +- .../pddlparse/detail/normalization/Action.h | 26 +++ .../detail/normalization/AtomicFormula.h | 26 +++ .../detail/normalization/Description.h | 26 +++ .../pddlparse/detail/normalization/Domain.h | 26 +++ .../pddlparse/detail/normalization/Effect.h | 26 +++ .../pddlparse/detail/normalization/Fact.h | 26 +++ .../detail/normalization/InitialState.h | 26 +++ .../pddlparse/detail/normalization/Literal.h | 26 +++ .../detail/normalization/Precondition.h | 26 +++ .../pddlparse/detail/normalization/Problem.h | 26 +++ lib/pddlparse/src/CMakeLists.txt | 6 + .../pddlparse/detail/normalization/Action.cpp | 41 ++++ .../detail/normalization/AtomicFormula.cpp | 38 +++ .../detail/normalization/Description.cpp | 34 +++ .../pddlparse/detail/normalization/Domain.cpp | 38 +++ .../pddlparse/detail/normalization/Effect.cpp | 28 +++ .../pddlparse/detail/normalization/Fact.cpp | 39 ++++ .../detail/normalization/InitialState.cpp | 33 +++ .../detail/normalization/Literal.cpp | 39 ++++ .../detail/normalization/Precondition.cpp | 218 ++++++++++++++++++ .../detail/normalization/Problem.cpp | 36 +++ src/plasp/pddl/TranslatorASP.cpp | 62 ++--- tests/TestPDDLTranslation.cpp | 5 +- 35 files changed, 1028 insertions(+), 117 deletions(-) create mode 100644 lib/pddlparse/include/pddlparse/Normalize.h create mode 100644 lib/pddlparse/include/pddlparse/detail/normalization/Action.h create mode 100644 lib/pddlparse/include/pddlparse/detail/normalization/AtomicFormula.h create mode 100644 lib/pddlparse/include/pddlparse/detail/normalization/Description.h create mode 100644 lib/pddlparse/include/pddlparse/detail/normalization/Domain.h create mode 100644 lib/pddlparse/include/pddlparse/detail/normalization/Effect.h create mode 100644 lib/pddlparse/include/pddlparse/detail/normalization/Fact.h create mode 100644 lib/pddlparse/include/pddlparse/detail/normalization/InitialState.h create mode 100644 lib/pddlparse/include/pddlparse/detail/normalization/Literal.h create mode 100644 lib/pddlparse/include/pddlparse/detail/normalization/Precondition.h create mode 100644 lib/pddlparse/include/pddlparse/detail/normalization/Problem.h create mode 100644 lib/pddlparse/src/pddlparse/detail/normalization/Action.cpp create mode 100644 lib/pddlparse/src/pddlparse/detail/normalization/AtomicFormula.cpp create mode 100644 lib/pddlparse/src/pddlparse/detail/normalization/Description.cpp create mode 100644 lib/pddlparse/src/pddlparse/detail/normalization/Domain.cpp create mode 100644 lib/pddlparse/src/pddlparse/detail/normalization/Effect.cpp create mode 100644 lib/pddlparse/src/pddlparse/detail/normalization/Fact.cpp create mode 100644 lib/pddlparse/src/pddlparse/detail/normalization/InitialState.cpp create mode 100644 lib/pddlparse/src/pddlparse/detail/normalization/Literal.cpp create mode 100644 lib/pddlparse/src/pddlparse/detail/normalization/Precondition.cpp create mode 100644 lib/pddlparse/src/pddlparse/detail/normalization/Problem.cpp diff --git a/app/main.cpp b/app/main.cpp index 8bd0111..514e149 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include @@ -187,7 +189,8 @@ int main(int argc, char **argv) auto context = pddl::Context(std::move(tokenizer), logWarning); context.mode = parsingMode; auto description = pddl::parseDescription(context); - const auto translator = plasp::pddl::TranslatorASP(std::move(description), logger.outputStream()); + auto normalizedDescription = pddl::normalize(std::move(description)); + const auto translator = plasp::pddl::TranslatorASP(std::move(normalizedDescription), logger.outputStream()); translator.translate(); } else if (language == plasp::Language::Type::SAS) diff --git a/include/plasp/pddl/TranslatorASP.h b/include/plasp/pddl/TranslatorASP.h index 4107a64..239f4d7 100644 --- a/include/plasp/pddl/TranslatorASP.h +++ b/include/plasp/pddl/TranslatorASP.h @@ -3,7 +3,7 @@ #include -#include +#include #include namespace plasp @@ -20,7 +20,7 @@ namespace pddl class TranslatorASP { public: - explicit TranslatorASP(const ::pddl::ast::Description &description, colorlog::ColorStream &outputStream); + explicit TranslatorASP(const ::pddl::normalizedAST::Description &description, colorlog::ColorStream &outputStream); void translate() const; @@ -35,7 +35,7 @@ class TranslatorASP void translateGoal() const; void translateConstants(const std::string &heading, const ::pddl::ast::ConstantDeclarations &constants) const; - const ::pddl::ast::Description &m_description; + const ::pddl::normalizedAST::Description &m_description; colorlog::ColorStream &m_outputStream; }; diff --git a/include/plasp/pddl/translation/Effect.h b/include/plasp/pddl/translation/Effect.h index d35ff35..1c9df1c 100644 --- a/include/plasp/pddl/translation/Effect.h +++ b/include/plasp/pddl/translation/Effect.h @@ -3,7 +3,7 @@ #include -#include +#include #include @@ -22,7 +22,7 @@ namespace pddl //////////////////////////////////////////////////////////////////////////////////////////////////// template -inline void translateEffect(colorlog::ColorStream &outputStream, const ::pddl::ast::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) { const auto handleUnsupported = [](const auto &) @@ -31,7 +31,7 @@ inline void translateEffect(colorlog::ColorStream &outputStream, const ::pddl::a }; const auto handlePredicate = - [&](const ::pddl::ast::PredicatePointer &predicate, bool isPositive = true) + [&](const ::pddl::normalizedAST::PredicatePointer &predicate, bool isPositive = true) { outputStream << std::endl << colorlog::Function("postcondition") << "("; printObjectName(); @@ -46,24 +46,24 @@ inline void translateEffect(colorlog::ColorStream &outputStream, const ::pddl::a }; const auto handleAtomicFormula = - [&](const ::pddl::ast::AtomicFormula &atomicFormula) + [&](const ::pddl::normalizedAST::AtomicFormula &atomicFormula) { atomicFormula.match(handlePredicate, handleUnsupported); }; const auto handleNot = - [&](const ::pddl::ast::NotPointer<::pddl::ast::Effect> ¬_) + [&](const ::pddl::normalizedAST::NotPointer<::pddl::normalizedAST::Effect> ¬_) { - if (!not_->argument.is<::pddl::ast::AtomicFormula>() || !not_->argument.get<::pddl::ast::AtomicFormula>().is<::pddl::ast::PredicatePointer>()) + if (!not_->argument.is<::pddl::normalizedAST::AtomicFormula>() || !not_->argument.get<::pddl::normalizedAST::AtomicFormula>().is<::pddl::normalizedAST::PredicatePointer>()) handleUnsupported(not_); - const auto &predicate = not_->argument.get<::pddl::ast::AtomicFormula>().get<::pddl::ast::PredicatePointer>(); + const auto &predicate = not_->argument.get<::pddl::normalizedAST::AtomicFormula>().get<::pddl::normalizedAST::PredicatePointer>(); handlePredicate(predicate, false); }; const auto handleAnd = - [&](const ::pddl::ast::AndPointer<::pddl::ast::Effect> &and_) + [&](const ::pddl::normalizedAST::AndPointer<::pddl::normalizedAST::Effect> &and_) { for (const auto &argument : and_->arguments) translateEffect(outputStream, argument, objectType, printObjectName); diff --git a/include/plasp/pddl/translation/Goal.h b/include/plasp/pddl/translation/Goal.h index c48dd52..ea4c66b 100644 --- a/include/plasp/pddl/translation/Goal.h +++ b/include/plasp/pddl/translation/Goal.h @@ -3,7 +3,7 @@ #include -#include +#include #include @@ -21,16 +21,10 @@ namespace pddl // //////////////////////////////////////////////////////////////////////////////////////////////////// -inline void translateGoal(colorlog::ColorStream &outputStream, const ::pddl::ast::Goal &goal) +inline void translateGoal(colorlog::ColorStream &outputStream, const ::pddl::normalizedAST::Goal &goal) { - const auto handleUnsupported = - [](const auto &) - { - throw TranslatorException("only “and” expressions and (negated) predicates supported as goals currently"); - }; - const auto handlePredicate = - [&](const ::pddl::ast::PredicatePointer &predicate, bool isPositive = true) + [&](const ::pddl::normalizedAST::PredicatePointer &predicate, bool isPositive = true) { outputStream << std::endl << colorlog::Function("goal") << "("; // TODO: assert that goal is variable-free @@ -38,31 +32,54 @@ inline void translateGoal(colorlog::ColorStream &outputStream, const ::pddl::ast outputStream << ")."; }; - const auto handleAtomicFormula = - [&](const ::pddl::ast::AtomicFormula &atomicFormula) + const auto handleNegatedPredicate = + [&](const ::pddl::normalizedAST::PredicatePointer &predicate) { - atomicFormula.match(handlePredicate, handleUnsupported); - }; - - const auto handleNot = - [&](const ::pddl::ast::NotPointer<::pddl::ast::Goal> ¬_) - { - if (!not_->argument.is<::pddl::ast::AtomicFormula>() || !not_->argument.get<::pddl::ast::AtomicFormula>().is<::pddl::ast::PredicatePointer>()) - handleUnsupported(not_); - - const auto &predicate = not_->argument.get<::pddl::ast::AtomicFormula>().get<::pddl::ast::PredicatePointer>(); - handlePredicate(predicate, false); }; - const auto handleAnd = - [&](const ::pddl::ast::AndPointer<::pddl::ast::Goal> &and_) + const auto handleDerivedPredicate = + [&](const ::pddl::normalizedAST::DerivedPredicatePointer &, bool = true) { - for (const auto &argument : and_->arguments) - translateGoal(outputStream, argument); + outputStream << std::endl << colorlog::Function("goal") << "("; + // TODO: assert that goal is variable-free + // TODO: implement + //translatePredicateToVariable(outputStream, *predicate, isPositive); + outputStream << ")."; }; - goal.match(handleAtomicFormula, handleNot, handleAnd, handleUnsupported); + 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); + }; + + goal.match(handleLiteral, handleAnd); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/translation/Precondition.h b/include/plasp/pddl/translation/Precondition.h index 4b8ed31..a34ded1 100644 --- a/include/plasp/pddl/translation/Precondition.h +++ b/include/plasp/pddl/translation/Precondition.h @@ -3,7 +3,7 @@ #include -#include +#include #include @@ -22,16 +22,10 @@ namespace pddl //////////////////////////////////////////////////////////////////////////////////////////////////// template -inline void translatePrecondition(colorlog::ColorStream &outputStream, const ::pddl::ast::Precondition &precondition, const std::string &objectType, PrintObjectName printObjectName) +inline void translatePrecondition(colorlog::ColorStream &outputStream, const ::pddl::normalizedAST::Precondition &precondition, const std::string &objectType, PrintObjectName printObjectName) { - const auto handleUnsupported = - [](const auto &) - { - throw TranslatorException("only “and” expressions and (negated) predicates supported as action preconditions currently"); - }; - const auto handlePredicate = - [&](const ::pddl::ast::PredicatePointer &predicate, bool isPositive = true) + [&](const ::pddl::normalizedAST::PredicatePointer &predicate, bool isPositive = true) { outputStream << std::endl << colorlog::Function("precondition") << "("; printObjectName(); @@ -42,31 +36,57 @@ inline void translatePrecondition(colorlog::ColorStream &outputStream, const ::p outputStream << ")."; }; - const auto handleAtomicFormula = - [&](const ::pddl::ast::AtomicFormula &atomicFormula) + const auto handleNegatedPredicate = + [&](const ::pddl::normalizedAST::PredicatePointer &predicate) { - atomicFormula.match(handlePredicate, handleUnsupported); - }; - - const auto handleNot = - [&](const ::pddl::ast::NotPointer<::pddl::ast::Precondition> ¬_) - { - if (!not_->argument.is<::pddl::ast::AtomicFormula>() || !not_->argument.get<::pddl::ast::AtomicFormula>().is<::pddl::ast::PredicatePointer>()) - handleUnsupported(not_); - - const auto &predicate = not_->argument.get<::pddl::ast::AtomicFormula>().get<::pddl::ast::PredicatePointer>(); - handlePredicate(predicate, false); }; - const auto handleAnd = - [&](const ::pddl::ast::AndPointer<::pddl::ast::Precondition> &and_) + const auto handleDerivedPredicate = + [&](const ::pddl::normalizedAST::DerivedPredicatePointer &, bool = true) { - for (const auto &argument : and_->arguments) - translatePrecondition(outputStream, argument, objectType, printObjectName); + outputStream << std::endl << colorlog::Function("precondition") << "("; + printObjectName(); + outputStream << ", "; + // TODO: implement + /*translatePredicateToVariable(outputStream, *predicate, isPositive); + outputStream << ") :- " << output::Function(objectType.c_str()) << "("; + printObjectName(); + outputStream << ").";*/ }; - precondition.match(handleAtomicFormula, handleNot, handleAnd, handleUnsupported); + 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); + }; + + precondition.match(handleLiteral, handleAnd); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/translation/Predicate.h b/include/plasp/pddl/translation/Predicate.h index ea5e243..448a29f 100644 --- a/include/plasp/pddl/translation/Predicate.h +++ b/include/plasp/pddl/translation/Predicate.h @@ -3,7 +3,7 @@ #include -#include +#include #include #include @@ -20,12 +20,12 @@ namespace pddl // //////////////////////////////////////////////////////////////////////////////////////////////////// -void translatePredicate(colorlog::ColorStream &outputStream, const ::pddl::ast::Predicate &predicate); -void translatePredicateDeclaration(colorlog::ColorStream &outputStream, const ::pddl::ast::PredicateDeclaration &predicateDeclaration); +void translatePredicate(colorlog::ColorStream &outputStream, const ::pddl::normalizedAST::Predicate &predicate); +void translatePredicateDeclaration(colorlog::ColorStream &outputStream, const ::pddl::normalizedAST::PredicateDeclaration &predicateDeclaration); //////////////////////////////////////////////////////////////////////////////////////////////////// -inline void translatePredicate(colorlog::ColorStream &outputStream, const ::pddl::ast::Predicate &predicate) +inline void translatePredicate(colorlog::ColorStream &outputStream, const ::pddl::normalizedAST::Predicate &predicate) { const auto &arguments = predicate.arguments; @@ -42,13 +42,13 @@ inline void translatePredicate(colorlog::ColorStream &outputStream, const ::pddl outputStream << ", "; const auto handleConstant = - [&](const ::pddl::ast::ConstantPointer &constant) + [&](const ::pddl::normalizedAST::ConstantPointer &constant) { outputStream << colorlog::Keyword("constant") << "(" << *constant << ")"; }; const auto handleVariable = - [&](const ::pddl::ast::VariablePointer &variable) + [&](const ::pddl::normalizedAST::VariablePointer &variable) { outputStream << *variable; }; @@ -67,7 +67,7 @@ inline void translatePredicate(colorlog::ColorStream &outputStream, const ::pddl //////////////////////////////////////////////////////////////////////////////////////////////////// -inline void translatePredicateDeclaration(colorlog::ColorStream &outputStream, const ::pddl::ast::PredicateDeclaration &predicateDeclaration) +inline void translatePredicateDeclaration(colorlog::ColorStream &outputStream, const ::pddl::normalizedAST::PredicateDeclaration &predicateDeclaration) { outputStream << colorlog::Keyword("variable") << "("; @@ -84,7 +84,7 @@ inline void translatePredicateDeclaration(colorlog::ColorStream &outputStream, c //////////////////////////////////////////////////////////////////////////////////////////////////// -void translatePredicateToVariable(colorlog::ColorStream &outputStream, const ::pddl::ast::Predicate &predicate, bool isPositive = true) +void translatePredicateToVariable(colorlog::ColorStream &outputStream, const ::pddl::normalizedAST::Predicate &predicate, bool isPositive = true) { outputStream << colorlog::Keyword("variable") << "("; translatePredicate(outputStream, predicate); diff --git a/include/plasp/pddl/translation/Primitives.h b/include/plasp/pddl/translation/Primitives.h index d70d2b0..27d0894 100644 --- a/include/plasp/pddl/translation/Primitives.h +++ b/include/plasp/pddl/translation/Primitives.h @@ -3,7 +3,7 @@ #include -#include +#include #include @@ -18,7 +18,7 @@ namespace pddl // //////////////////////////////////////////////////////////////////////////////////////////////////// -inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const ::pddl::ast::ConstantDeclaration &constantDeclaration) +inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const ::pddl::normalizedAST::ConstantDeclaration &constantDeclaration) { assert(!constantDeclaration.name.empty()); @@ -27,7 +27,7 @@ inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const :: //////////////////////////////////////////////////////////////////////////////////////////////////// -inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const ::pddl::ast::Constant &constant) +inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const ::pddl::normalizedAST::Constant &constant) { assert(constant.declaration != nullptr); @@ -36,7 +36,7 @@ inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const :: //////////////////////////////////////////////////////////////////////////////////////////////////// -inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const ::pddl::ast::PrimitiveTypeDeclaration &primitiveTypeDeclaration) +inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const ::pddl::normalizedAST::PrimitiveTypeDeclaration &primitiveTypeDeclaration) { assert(!primitiveTypeDeclaration.name.empty()); @@ -45,7 +45,7 @@ inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const :: //////////////////////////////////////////////////////////////////////////////////////////////////// -inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const ::pddl::ast::PrimitiveType &primitiveType) +inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const ::pddl::normalizedAST::PrimitiveType &primitiveType) { assert(primitiveType.declaration != nullptr); @@ -54,7 +54,7 @@ inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const :: //////////////////////////////////////////////////////////////////////////////////////////////////// -inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, ::pddl::ast::VariableDeclaration &variableDeclaration) +inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, ::pddl::normalizedAST::VariableDeclaration &variableDeclaration) { assert(!variableDeclaration.name.empty()); assert(std::isalpha(variableDeclaration.name[0])); @@ -70,7 +70,7 @@ inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, ::pddl:: //////////////////////////////////////////////////////////////////////////////////////////////////// -inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, ::pddl::ast::Variable &variable) +inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, ::pddl::normalizedAST::Variable &variable) { assert(variable.declaration != nullptr); @@ -80,7 +80,7 @@ inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, ::pddl:: //////////////////////////////////////////////////////////////////////////////////////////////////// // TODO: move to appropriate header -inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const ::pddl::ast::Action &action) +inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const ::pddl::normalizedAST::Action &action) { return (stream << colorlog::String(action.name.c_str())); } @@ -88,7 +88,7 @@ inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const :: //////////////////////////////////////////////////////////////////////////////////////////////////// // TODO: move to appropriate header -inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const ::pddl::ast::PredicateDeclaration &predicateDeclaration) +inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const ::pddl::normalizedAST::PredicateDeclaration &predicateDeclaration) { return (stream << colorlog::String(predicateDeclaration.name.c_str())); } @@ -96,13 +96,29 @@ inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const :: //////////////////////////////////////////////////////////////////////////////////////////////////// // TODO: move to appropriate header -inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const ::pddl::ast::Predicate &predicate) +inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const ::pddl::normalizedAST::Predicate &predicate) { return (stream << *predicate.declaration); } //////////////////////////////////////////////////////////////////////////////////////////////////// +// TODO: move to appropriate header +inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const ::pddl::normalizedAST::DerivedPredicateDeclaration &derivedPredicateDeclaration) +{ + return (stream << colorlog::String(derivedPredicateDeclaration.name.c_str())); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// TODO: move to appropriate header +inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const ::pddl::normalizedAST::DerivedPredicate &derivedPredicate) +{ + return (stream << *derivedPredicate.declaration); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } diff --git a/include/plasp/pddl/translation/Variables.h b/include/plasp/pddl/translation/Variables.h index ffa767a..491a1d4 100644 --- a/include/plasp/pddl/translation/Variables.h +++ b/include/plasp/pddl/translation/Variables.h @@ -3,7 +3,7 @@ #include -#include +#include #include #include @@ -53,10 +53,10 @@ inline void translateVariablesForRuleBody(colorlog::ColorStream &outputStream, c if (variable->type) { - if (!variable->type.value().template is<::pddl::ast::PrimitiveTypePointer>()) + if (!variable->type.value().template is<::pddl::normalizedAST::PrimitiveTypePointer>()) throw TranslatorException("only primitive types supported currently"); - const auto &type = variable->type.value().template get<::pddl::ast::PrimitiveTypePointer>(); + const auto &type = variable->type.value().template get<::pddl::normalizedAST::PrimitiveTypePointer>(); outputStream << colorlog::Function("has") << "(" << *variable << ", " << colorlog::Keyword("type") << "(" << *type << "))"; diff --git a/lib/pddlparse/include/pddlparse/Exception.h b/lib/pddlparse/include/pddlparse/Exception.h index 07555cd..b877ffb 100644 --- a/lib/pddlparse/include/pddlparse/Exception.h +++ b/lib/pddlparse/include/pddlparse/Exception.h @@ -82,6 +82,14 @@ class ParserException : public Exception //////////////////////////////////////////////////////////////////////////////////////////////////// +class NormalizationException : public Exception +{ + public: + using Exception::Exception; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } #endif diff --git a/lib/pddlparse/include/pddlparse/Normalize.h b/lib/pddlparse/include/pddlparse/Normalize.h new file mode 100644 index 0000000..865c3b9 --- /dev/null +++ b/lib/pddlparse/include/pddlparse/Normalize.h @@ -0,0 +1,24 @@ +#ifndef __PDDL_PARSE__NORMALIZE_H +#define __PDDL_PARSE__NORMALIZE_H + +#include +#include +#include +#include + +namespace pddl +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Normalize +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +using detail::normalize; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/NormalizedAST.h b/lib/pddlparse/include/pddlparse/NormalizedAST.h index f25949a..0e68ac8 100644 --- a/lib/pddlparse/include/pddlparse/NormalizedAST.h +++ b/lib/pddlparse/include/pddlparse/NormalizedAST.h @@ -133,6 +133,7 @@ struct Problem Domain *domain; std::string name; + DerivedPredicateDeclarations derivedPredicates; ConstantDeclarations objects; InitialState initialState; std::experimental::optional goal; diff --git a/lib/pddlparse/include/pddlparse/NormalizedASTForward.h b/lib/pddlparse/include/pddlparse/NormalizedASTForward.h index 6d7a8e5..54d50f0 100644 --- a/lib/pddlparse/include/pddlparse/NormalizedASTForward.h +++ b/lib/pddlparse/include/pddlparse/NormalizedASTForward.h @@ -66,6 +66,9 @@ using ast::AtPointer; using ast::Either; using ast::EitherPointer; using ast::Exists; +using ast::ExistsPointer; +using ast::ForAll; +using ast::ForAllPointer; using ast::Not; using ast::NotPointer; using ast::When; @@ -170,7 +173,7 @@ namespace detail using EffectT = Variant< AtomicFormula, AndPointer, - ast::ForAllPointer, + ForAllPointer, NotPointer, WhenPointer>; } diff --git a/lib/pddlparse/include/pddlparse/detail/normalization/Action.h b/lib/pddlparse/include/pddlparse/detail/normalization/Action.h new file mode 100644 index 0000000..0e9e635 --- /dev/null +++ b/lib/pddlparse/include/pddlparse/detail/normalization/Action.h @@ -0,0 +1,26 @@ +#ifndef __PDDL_PARSE__DETAIL__NORMALIZATION__ACTION_H +#define __PDDL_PARSE__DETAIL__NORMALIZATION__ACTION_H + +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Action +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::ActionPointer normalize(ast::ActionPointer &&domain, normalizedAST::DerivedPredicateDeclarations &derivedPredicates); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/detail/normalization/AtomicFormula.h b/lib/pddlparse/include/pddlparse/detail/normalization/AtomicFormula.h new file mode 100644 index 0000000..279fe04 --- /dev/null +++ b/lib/pddlparse/include/pddlparse/detail/normalization/AtomicFormula.h @@ -0,0 +1,26 @@ +#ifndef __PDDL_PARSE__DETAIL__NORMALIZATION__ATOMIC_FORMULA_H +#define __PDDL_PARSE__DETAIL__NORMALIZATION__ATOMIC_FORMULA_H + +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// AtomicFormula +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::AtomicFormula normalize(ast::AtomicFormula &&atomicFormula); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/detail/normalization/Description.h b/lib/pddlparse/include/pddlparse/detail/normalization/Description.h new file mode 100644 index 0000000..d6731e0 --- /dev/null +++ b/lib/pddlparse/include/pddlparse/detail/normalization/Description.h @@ -0,0 +1,26 @@ +#ifndef __PDDL_PARSE__DETAIL__NORMALIZATION__DESCRIPTION_H +#define __PDDL_PARSE__DETAIL__NORMALIZATION__DESCRIPTION_H + +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Description +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::Description normalize(ast::Description &&description); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/detail/normalization/Domain.h b/lib/pddlparse/include/pddlparse/detail/normalization/Domain.h new file mode 100644 index 0000000..0927e00 --- /dev/null +++ b/lib/pddlparse/include/pddlparse/detail/normalization/Domain.h @@ -0,0 +1,26 @@ +#ifndef __PDDL_PARSE__DETAIL__NORMALIZATION__DOMAIN_H +#define __PDDL_PARSE__DETAIL__NORMALIZATION__DOMAIN_H + +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Domain +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::DomainPointer normalize(ast::DomainPointer &&domain); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/detail/normalization/Effect.h b/lib/pddlparse/include/pddlparse/detail/normalization/Effect.h new file mode 100644 index 0000000..e7181da --- /dev/null +++ b/lib/pddlparse/include/pddlparse/detail/normalization/Effect.h @@ -0,0 +1,26 @@ +#ifndef __PDDL_PARSE__DETAIL__NORMALIZATION__EFFECT_H +#define __PDDL_PARSE__DETAIL__NORMALIZATION__EFFECT_H + +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Effect +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::Effect normalize(ast::Effect &&effect); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/detail/normalization/Fact.h b/lib/pddlparse/include/pddlparse/detail/normalization/Fact.h new file mode 100644 index 0000000..3dec70c --- /dev/null +++ b/lib/pddlparse/include/pddlparse/detail/normalization/Fact.h @@ -0,0 +1,26 @@ +#ifndef __PDDL_PARSE__DETAIL__NORMALIZATION__FACT_H +#define __PDDL_PARSE__DETAIL__NORMALIZATION__FACT_H + +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Fact +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::Fact normalize(ast::Fact &&fact); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/detail/normalization/InitialState.h b/lib/pddlparse/include/pddlparse/detail/normalization/InitialState.h new file mode 100644 index 0000000..e6edaba --- /dev/null +++ b/lib/pddlparse/include/pddlparse/detail/normalization/InitialState.h @@ -0,0 +1,26 @@ +#ifndef __PDDL_PARSE__DETAIL__NORMALIZATION__INITIAL_STATE_H +#define __PDDL_PARSE__DETAIL__NORMALIZATION__INITIAL_STATE_H + +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// InitialState +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::InitialState normalize(ast::InitialState &&initialState); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/detail/normalization/Literal.h b/lib/pddlparse/include/pddlparse/detail/normalization/Literal.h new file mode 100644 index 0000000..f667011 --- /dev/null +++ b/lib/pddlparse/include/pddlparse/detail/normalization/Literal.h @@ -0,0 +1,26 @@ +#ifndef __PDDL_PARSE__DETAIL__NORMALIZATION__LITERAL_H +#define __PDDL_PARSE__DETAIL__NORMALIZATION__LITERAL_H + +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Literal +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::Literal normalize(ast::Literal &&literal); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/detail/normalization/Precondition.h b/lib/pddlparse/include/pddlparse/detail/normalization/Precondition.h new file mode 100644 index 0000000..aaf2dd9 --- /dev/null +++ b/lib/pddlparse/include/pddlparse/detail/normalization/Precondition.h @@ -0,0 +1,26 @@ +#ifndef __PDDL_PARSE__DETAIL__NORMALIZATION__PRECONDITION_H +#define __PDDL_PARSE__DETAIL__NORMALIZATION__PRECONDITION_H + +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Precondition +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::Precondition normalize(ast::Precondition &&precondition, normalizedAST::DerivedPredicateDeclarations &derivedPredicates); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/detail/normalization/Problem.h b/lib/pddlparse/include/pddlparse/detail/normalization/Problem.h new file mode 100644 index 0000000..d052ef1 --- /dev/null +++ b/lib/pddlparse/include/pddlparse/detail/normalization/Problem.h @@ -0,0 +1,26 @@ +#ifndef __PDDL_PARSE__DETAIL__NORMALIZATION__PROBLEM_H +#define __PDDL_PARSE__DETAIL__NORMALIZATION__PROBLEM_H + +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Problem +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::ProblemPointer normalize(ast::ProblemPointer &&problem, normalizedAST::Domain *domain); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/src/CMakeLists.txt b/lib/pddlparse/src/CMakeLists.txt index 0eb1160..a8f65e6 100644 --- a/lib/pddlparse/src/CMakeLists.txt +++ b/lib/pddlparse/src/CMakeLists.txt @@ -9,6 +9,9 @@ file(GLOB detail_headers "../include/pddlparse/detail/*.h") file(GLOB detail_parsing_sources "pddlparse/detail/parsing/*.cpp") file(GLOB detail_parsing_headers "../include/pddlparse/detail/parsing/*.h") +file(GLOB detail_normalization_sources "pddlparse/detail/normalization/*.cpp") +file(GLOB detail_normalization_headers "../include/pddlparse/detail/normalization/*.h") + set(includes ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/../../lib/colorlog/include @@ -25,6 +28,9 @@ set(sources ${detail_parsing_sources} ${detail_parsing_headers} + + ${detail_normalization_sources} + ${detail_normalization_headers} ) set(libraries diff --git a/lib/pddlparse/src/pddlparse/detail/normalization/Action.cpp b/lib/pddlparse/src/pddlparse/detail/normalization/Action.cpp new file mode 100644 index 0000000..9fd3796 --- /dev/null +++ b/lib/pddlparse/src/pddlparse/detail/normalization/Action.cpp @@ -0,0 +1,41 @@ +#include + +#include +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Action +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::ActionPointer normalize(ast::ActionPointer &&action, normalizedAST::DerivedPredicateDeclarations &derivedPredicates) +{ + auto normalizedAction = std::make_unique(); + + normalizedAction->name = std::move(action->name); + normalizedAction->parameters = std::move(action->parameters); + + if (action->precondition) + normalizedAction->precondition = normalize(std::move(action->precondition.value()), derivedPredicates); + + // TODO: implement + /* + if (action->effect) + normalizedAction->effect = normalize(std::move(action->effect.value())); + */ + + return normalizedAction; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/lib/pddlparse/src/pddlparse/detail/normalization/AtomicFormula.cpp b/lib/pddlparse/src/pddlparse/detail/normalization/AtomicFormula.cpp new file mode 100644 index 0000000..3fed719 --- /dev/null +++ b/lib/pddlparse/src/pddlparse/detail/normalization/AtomicFormula.cpp @@ -0,0 +1,38 @@ +#include + +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// AtomicFormula +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::AtomicFormula normalize(ast::AtomicFormula &&atomicFormula) +{ + const auto handleUnsupported = + [&](ast::UnsupportedPointer &unsupported) -> normalizedAST::AtomicFormula + { + throw NormalizationException("“" + unsupported->type + "” expressions as literals can’t be normalized currently"); + }; + + const auto handlePredicate = + [&](ast::PredicatePointer &predicate) -> normalizedAST::AtomicFormula + { + return std::move(predicate); + }; + + return atomicFormula.match(handlePredicate, handleUnsupported); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/lib/pddlparse/src/pddlparse/detail/normalization/Description.cpp b/lib/pddlparse/src/pddlparse/detail/normalization/Description.cpp new file mode 100644 index 0000000..ccba08c --- /dev/null +++ b/lib/pddlparse/src/pddlparse/detail/normalization/Description.cpp @@ -0,0 +1,34 @@ +#include + +#include +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Description +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::Description normalize(ast::Description &&description) +{ + normalizedAST::Description normalizedDescription; + + normalizedDescription.domain = normalize(std::move(description.domain)); + + if (description.problem) + normalizedDescription.problem = normalize(std::move(description.problem.value()), normalizedDescription.domain.get()); + + return normalizedDescription; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/lib/pddlparse/src/pddlparse/detail/normalization/Domain.cpp b/lib/pddlparse/src/pddlparse/detail/normalization/Domain.cpp new file mode 100644 index 0000000..19fc523 --- /dev/null +++ b/lib/pddlparse/src/pddlparse/detail/normalization/Domain.cpp @@ -0,0 +1,38 @@ +#include + +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Description +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::DomainPointer normalize(ast::DomainPointer &&domain) +{ + auto normalizedDomain = std::make_unique(); + + normalizedDomain->types = std::move(domain->types); + normalizedDomain->name = std::move(domain->name); + normalizedDomain->constants = std::move(domain->constants); + normalizedDomain->predicates = std::move(domain->predicates); + + normalizedDomain->actions.reserve(domain->actions.size()); + + for (auto &&action : domain->actions) + normalizedDomain->actions.emplace_back(normalize(std::move(action), normalizedDomain->derivedPredicates)); + + return normalizedDomain; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/lib/pddlparse/src/pddlparse/detail/normalization/Effect.cpp b/lib/pddlparse/src/pddlparse/detail/normalization/Effect.cpp new file mode 100644 index 0000000..a50d4a7 --- /dev/null +++ b/lib/pddlparse/src/pddlparse/detail/normalization/Effect.cpp @@ -0,0 +1,28 @@ +#include + +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Effect +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// TODO: implement +/* +normalizedAST::Effect normalize(ast::Effect &&) +{ +} +*/ + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/lib/pddlparse/src/pddlparse/detail/normalization/Fact.cpp b/lib/pddlparse/src/pddlparse/detail/normalization/Fact.cpp new file mode 100644 index 0000000..3199feb --- /dev/null +++ b/lib/pddlparse/src/pddlparse/detail/normalization/Fact.cpp @@ -0,0 +1,39 @@ +#include + +#include +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Fact +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::Fact normalize(ast::Fact &&fact) +{ + const auto handleLiteral = + [&](ast::Literal &literal) -> normalizedAST::Literal + { + return normalize(std::move(literal)); + }; + + const auto handleAt = + [&](ast::AtPointer &) -> normalizedAST::Literal + { + throw NormalizationException("“at” expressions in preconditions can’t be normalized currently"); + }; + + return fact.match(handleLiteral, handleAt); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/lib/pddlparse/src/pddlparse/detail/normalization/InitialState.cpp b/lib/pddlparse/src/pddlparse/detail/normalization/InitialState.cpp new file mode 100644 index 0000000..c2d50c1 --- /dev/null +++ b/lib/pddlparse/src/pddlparse/detail/normalization/InitialState.cpp @@ -0,0 +1,33 @@ +#include + +#include +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// InitialState +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::InitialState normalize(ast::InitialState &&initialState) +{ + normalizedAST::InitialState normalizedInitialState; + normalizedInitialState.facts.reserve(initialState.facts.size()); + + for (auto &fact : initialState.facts) + normalizedInitialState.facts.emplace_back(normalize(std::move(fact))); + + return normalizedInitialState; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/lib/pddlparse/src/pddlparse/detail/normalization/Literal.cpp b/lib/pddlparse/src/pddlparse/detail/normalization/Literal.cpp new file mode 100644 index 0000000..a381533 --- /dev/null +++ b/lib/pddlparse/src/pddlparse/detail/normalization/Literal.cpp @@ -0,0 +1,39 @@ +#include + +#include +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Literal +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::Literal normalize(ast::Literal &&literal) +{ + const auto handleAtomicFormula = + [&](ast::AtomicFormula &atomicFormula) -> normalizedAST::Literal + { + return normalize(std::move(atomicFormula)); + }; + + const auto handleNot = + [&](ast::NotPointer ¬_) -> normalizedAST::Literal + { + return std::make_unique>(normalize(std::move(not_->argument))); + }; + + return literal.match(handleAtomicFormula, handleNot); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/lib/pddlparse/src/pddlparse/detail/normalization/Precondition.cpp b/lib/pddlparse/src/pddlparse/detail/normalization/Precondition.cpp new file mode 100644 index 0000000..e5f82bc --- /dev/null +++ b/lib/pddlparse/src/pddlparse/detail/normalization/Precondition.cpp @@ -0,0 +1,218 @@ +#include + +#include +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Precondition +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::DerivedPredicatePointer addDerivedPredicate(normalizedAST::DerivedPredicateDeclarations &derivedPredicates, const std::string &type) +{ + auto name = "derived-" + type + "-" + std::to_string(derivedPredicates.size() + 1); + + derivedPredicates.emplace_back(std::make_unique(std::move(name), normalizedAST::VariableDeclarations())); + + return std::make_unique(normalizedAST::DerivedPredicate::Arguments(), derivedPredicates.back().get()); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::DerivedPredicatePointer normalizeNested(ast::AndPointer &, normalizedAST::DerivedPredicateDeclarations &derivedPredicates) +{ + // TODO: handle arguments recursively + return addDerivedPredicate(derivedPredicates, "and"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::DerivedPredicatePointer normalizeNested(ast::AtomicFormula &, normalizedAST::DerivedPredicateDeclarations &) +{ + // TODO: add explanation + throw std::logic_error("atomic formulas should have been handled earlier"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::DerivedPredicatePointer normalizeNested(ast::ExistsPointer &, normalizedAST::DerivedPredicateDeclarations &derivedPredicates) +{ + // TODO: handle arguments recursively + return addDerivedPredicate(derivedPredicates, "exists"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::DerivedPredicatePointer normalizeNested(ast::ForAllPointer &, normalizedAST::DerivedPredicateDeclarations &derivedPredicates) +{ + // TODO: handle arguments recursively + return addDerivedPredicate(derivedPredicates, "forall"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::DerivedPredicatePointer normalizeNested(ast::ImplyPointer &, normalizedAST::DerivedPredicateDeclarations &derivedPredicates) +{ + // TODO: handle arguments recursively + return addDerivedPredicate(derivedPredicates, "imply"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::DerivedPredicatePointer normalizeNested(ast::NotPointer &, normalizedAST::DerivedPredicateDeclarations &derivedPredicates) +{ + // TODO: handle arguments recursively + return addDerivedPredicate(derivedPredicates, "not"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::DerivedPredicatePointer normalizeNested(ast::OrPointer &, normalizedAST::DerivedPredicateDeclarations &derivedPredicates) +{ + // TODO: handle arguments recursively + return addDerivedPredicate(derivedPredicates, "or"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::PredicatePointer normalize(ast::UnsupportedPointer &&unsupported, normalizedAST::DerivedPredicateDeclarations &) +{ + throw NormalizationException("“" + unsupported->type + "” expressions in preconditions can’t be normalized currently"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// Normalize top-level negations +normalizedAST::NotPointer normalize(ast::NotPointer &¬_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates) +{ + // “not” expressions may be nested one time to form simple literals + if (not_->argument.is()) + return std::make_unique>(normalize(std::move(not_->argument.get()))); + + const auto handleNested = + [&](auto &nested) -> normalizedAST::AtomicFormula + { + return normalizeNested(nested, derivedPredicates); + }; + + const auto handleUnsupported = + [&](ast::UnsupportedPointer &unsupported) -> normalizedAST::AtomicFormula + { + throw NormalizationException("“" + unsupported->type + "” expressions in preconditions can’t be normalized currently"); + }; + + auto normalizedArgument = not_->argument.match(handleNested, handleUnsupported); + + return std::make_unique>(std::move(normalizedArgument)); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// Normalize top-level conjunctions +normalizedAST::AndPointer normalize(ast::AndPointer &&and_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates) +{ + normalizedAST::And::Arguments arguments; + + arguments.reserve(and_->arguments.size()); + + const auto handleAtomicFormula = + [&](ast::AtomicFormula &atomicFormula) -> normalizedAST::Literal + { + return normalize(std::move(atomicFormula)); + }; + + const auto handleNot = + [&](ast::NotPointer ¬_) -> normalizedAST::Literal + { + return normalize(std::move(not_), derivedPredicates); + }; + + const auto handleNested = + [&](auto &nested) -> normalizedAST::Literal + { + return normalizeNested(nested, derivedPredicates); + }; + + const auto handleUnsupported = + [&](ast::UnsupportedPointer &unsupported) -> normalizedAST::Literal + { + throw NormalizationException("“" + unsupported->type + "” expressions in preconditions can’t be normalized currently"); + }; + + for (auto &&argument : and_->arguments) + { + auto normalizedArgument = argument.match(handleAtomicFormula, handleNot, handleNested, handleUnsupported); + + arguments.emplace_back(std::move(normalizedArgument)); + } + + return std::make_unique>(std::move(arguments)); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::Precondition normalize(ast::Precondition &&precondition, normalizedAST::DerivedPredicateDeclarations &derivedPredicates) +{ + /* + reduce + + AtomicFormula, + AndPointer, + NotPointer, + UnsupportedPointer>; + + ExistsPointer, + ForAllPointer, + ImplyPointer, + OrPointer, + + to + + Literal, + AndPointer>; + */ + const auto handleAtomicFormula = + [&](ast::AtomicFormula &atomicFormula) -> normalizedAST::Precondition + { + return normalize(std::move(atomicFormula)); + }; + + const auto handleNot = + [&](ast::NotPointer ¬_) -> normalizedAST::Precondition + { + return normalize(std::move(not_), derivedPredicates); + }; + + const auto handleAnd = + [&](ast::AndPointer &and_) -> normalizedAST::Precondition + { + return normalize(std::move(and_), derivedPredicates); + }; + + const auto handleNested = + [&](auto &nested) -> normalizedAST::Precondition + { + return normalizeNested(nested, derivedPredicates); + }; + + const auto handleUnsupported = + [&](ast::UnsupportedPointer &unsupported) -> normalizedAST::Precondition + { + throw NormalizationException("“" + unsupported->type + "” expressions in preconditions can’t be normalized currently"); + }; + + return precondition.match(handleAtomicFormula, handleNot, handleAnd, handleUnsupported, handleNested); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/lib/pddlparse/src/pddlparse/detail/normalization/Problem.cpp b/lib/pddlparse/src/pddlparse/detail/normalization/Problem.cpp new file mode 100644 index 0000000..26c6781 --- /dev/null +++ b/lib/pddlparse/src/pddlparse/detail/normalization/Problem.cpp @@ -0,0 +1,36 @@ +#include + +#include +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Problem +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +normalizedAST::ProblemPointer normalize(ast::ProblemPointer &&problem, normalizedAST::Domain *domain) +{ + auto normalizedProblem = std::make_unique(domain); + + normalizedProblem->name = std::move(problem->name); + normalizedProblem->objects = std::move(problem->objects); + normalizedProblem->initialState = normalize(std::move(problem->initialState)); + + if (problem->goal) + normalizedProblem->goal = normalize(std::move(problem->goal.value()), normalizedProblem->derivedPredicates); + + return normalizedProblem; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/src/plasp/pddl/TranslatorASP.cpp b/src/plasp/pddl/TranslatorASP.cpp index df3ba78..97ebbd2 100644 --- a/src/plasp/pddl/TranslatorASP.cpp +++ b/src/plasp/pddl/TranslatorASP.cpp @@ -4,7 +4,7 @@ #include -#include +#include #include @@ -26,7 +26,7 @@ namespace pddl // //////////////////////////////////////////////////////////////////////////////////////////////////// -TranslatorASP::TranslatorASP(const ::pddl::ast::Description &description, colorlog::ColorStream &outputStream) +TranslatorASP::TranslatorASP(const ::pddl::normalizedAST::Description &description, colorlog::ColorStream &outputStream) : m_description{description}, m_outputStream(outputStream) { @@ -216,7 +216,7 @@ void TranslatorASP::translateActions() const //////////////////////////////////////////////////////////////////////////////////////////////////// -void TranslatorASP::translateConstants(const std::string &heading, const ::pddl::ast::ConstantDeclarations &constants) const +void TranslatorASP::translateConstants(const std::string &heading, const ::pddl::normalizedAST::ConstantDeclarations &constants) const { m_outputStream << colorlog::Heading2(heading.c_str()); @@ -232,10 +232,10 @@ void TranslatorASP::translateConstants(const std::string &heading, const ::pddl: if (type) { - if (!type.value().is<::pddl::ast::PrimitiveTypePointer>()) + if (!type.value().is<::pddl::normalizedAST::PrimitiveTypePointer>()) throw TranslatorException("only primitive types supported currently"); - const auto &primitveType = type.value().get<::pddl::ast::PrimitiveTypePointer>(); + const auto &primitveType = type.value().get<::pddl::normalizedAST::PrimitiveTypePointer>(); m_outputStream << colorlog::Function("has") << "(" << colorlog::Keyword("constant") << "(" << *constant << "), " @@ -294,36 +294,44 @@ void TranslatorASP::translateInitialState() const { m_outputStream << std::endl << colorlog::Function("initialState") << "("; - const auto handleUnsupported = - [&](const auto &) + const auto handlePredicate = + [&](const ::pddl::normalizedAST::PredicatePointer &predicate, bool isPositive = true) { - throw TranslatorException("only predicates and their negations supported in initial state currently"); - }; - - const auto handleAtomicFormula = - [&](const ::pddl::ast::AtomicFormula &atomicFormula, bool isPositive = true) - { - if (!atomicFormula.is<::pddl::ast::PredicatePointer>()) - handleUnsupported(atomicFormula); - - const auto &predicate = atomicFormula.get<::pddl::ast::PredicatePointer>(); - translatePredicateToVariable(m_outputStream, *predicate, isPositive); }; + const auto handleNegatedPredicate = + [&](const ::pddl::normalizedAST::PredicatePointer &predicate) + { + return handlePredicate(predicate, false); + }; + + const auto handleDerivedPredicate = + [&](const ::pddl::normalizedAST::DerivedPredicatePointer &, bool = true) + { + // TODO: implement + //translatePredicateToVariable(m_outputStream, *predicate, true); + }; + + const auto handleNegatedDerivedPredicate = + [&](const ::pddl::normalizedAST::DerivedPredicatePointer &derivedPredicate) + { + return handleDerivedPredicate(derivedPredicate, false); + }; + + const auto handleAtomicFormula = + [&](const ::pddl::normalizedAST::AtomicFormula &atomicFormula) + { + atomicFormula.match(handlePredicate, handleDerivedPredicate); + }; + const auto handleNot = - [&](const ::pddl::ast::NotPointer<::pddl::ast::AtomicFormula> ¬_) + [&](const ::pddl::normalizedAST::NotPointer<::pddl::normalizedAST::AtomicFormula> ¬_) { - handleAtomicFormula(not_->argument, false); + not_->argument.match(handleNegatedPredicate, handleNegatedDerivedPredicate); }; - const auto handleLiteral = - [&](const ::pddl::ast::Literal &literal) - { - literal.match(handleAtomicFormula, handleNot); - }; - - fact.match(handleLiteral, handleUnsupported); + fact.match(handleAtomicFormula, handleNot); m_outputStream << ")."; } diff --git a/tests/TestPDDLTranslation.cpp b/tests/TestPDDLTranslation.cpp index de2fce6..a7f9760 100644 --- a/tests/TestPDDLTranslation.cpp +++ b/tests/TestPDDLTranslation.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -25,7 +26,7 @@ TEST_CASE("[PDDL translation] Former issues are fixed", "[PDDL translation]") SECTION("translating domains without typing information works") { context.tokenizer.read("data/issues/issue-4.pddl"); - auto description = pddl::parseDescription(context); + auto description = pddl::normalize(pddl::parseDescription(context)); const auto translator = plasp::pddl::TranslatorASP(std::move(description), logger.outputStream()); CHECK_NOTHROW(translator.translate()); } @@ -33,7 +34,7 @@ TEST_CASE("[PDDL translation] Former issues are fixed", "[PDDL translation]") SECTION("translating the simple blocks world domain works") { context.tokenizer.read("data/issues/issue-5.pddl"); - auto description = pddl::parseDescription(context); + auto description = pddl::normalize(pddl::parseDescription(context)); const auto translator = plasp::pddl::TranslatorASP(std::move(description), logger.outputStream()); CHECK_NOTHROW(translator.translate()); }