From b61212218093fa60c5ce5062b6f86bd1ede0b797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Tue, 7 Jun 2016 13:26:19 +0200 Subject: [PATCH] Refactoring to make parsing expressions consistent across PDDL domains and problems. --- include/plasp/pddl/Action.h | 2 +- include/plasp/pddl/Context.h | 16 ---- include/plasp/pddl/Description.h | 2 + include/plasp/pddl/Domain.h | 46 ++++++++--- include/plasp/pddl/Expression.h | 10 ++- include/plasp/pddl/ExpressionContext.h | 46 +++++++++++ include/plasp/pddl/Problem.h | 22 +++-- include/plasp/pddl/expressions/And.h | 6 +- include/plasp/pddl/expressions/Binary.h | 10 ++- include/plasp/pddl/expressions/Constant.h | 11 ++- include/plasp/pddl/expressions/Either.h | 6 +- include/plasp/pddl/expressions/Imply.h | 4 +- include/plasp/pddl/expressions/NAry.h | 6 +- include/plasp/pddl/expressions/Not.h | 6 +- include/plasp/pddl/expressions/Or.h | 7 +- include/plasp/pddl/expressions/Predicate.h | 2 +- .../pddl/expressions/PredicateDeclaration.h | 4 +- .../plasp/pddl/expressions/PrimitiveType.h | 14 ++-- include/plasp/pddl/expressions/Type.h | 3 +- include/plasp/pddl/expressions/Variable.h | 9 +- src/plasp/pddl/Action.cpp | 17 ++-- src/plasp/pddl/Description.cpp | 31 ++++++- src/plasp/pddl/Domain.cpp | 82 +++++++++++++------ src/plasp/pddl/Expression.cpp | 71 +++++++++------- src/plasp/pddl/Problem.cpp | 65 +++++++++++---- src/plasp/pddl/expressions/Constant.cpp | 50 +++++++++-- src/plasp/pddl/expressions/InitialState.cpp | 2 + src/plasp/pddl/expressions/Predicate.cpp | 9 +- .../pddl/expressions/PredicateDeclaration.cpp | 13 +-- src/plasp/pddl/expressions/PrimitiveType.cpp | 61 +++++++------- src/plasp/pddl/expressions/Type.cpp | 6 +- src/plasp/pddl/expressions/Variable.cpp | 40 +++++---- 32 files changed, 458 insertions(+), 221 deletions(-) create mode 100644 include/plasp/pddl/ExpressionContext.h diff --git a/include/plasp/pddl/Action.h b/include/plasp/pddl/Action.h index 2cb1225..ee3461a 100644 --- a/include/plasp/pddl/Action.h +++ b/include/plasp/pddl/Action.h @@ -21,7 +21,7 @@ namespace pddl class Action { public: - static Action &parseDeclaration(Context &context); + static void parseDeclaration(Context &context, Domain &domain); public: const std::string &name() const; diff --git a/include/plasp/pddl/Context.h b/include/plasp/pddl/Context.h index 7d01495..f71426d 100644 --- a/include/plasp/pddl/Context.h +++ b/include/plasp/pddl/Context.h @@ -5,11 +5,6 @@ #include #include -#include -#include -#include -#include -#include #include namespace plasp @@ -33,17 +28,6 @@ class Context utils::Parser &parser; utils::Logger logger; - - expressions::PrimitiveTypes primitiveTypes; - //std::unordered_map primitiveTypesHashMap; - - expressions::Constants constants; - //std::unordered_map constantsHashMap; - - expressions::PredicateDeclarations predicateDeclarations; - //std::unordered_map predicatesHashMap; - - std::vector> actions; }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/Description.h b/include/plasp/pddl/Description.h index 3bf6344..d261661 100644 --- a/include/plasp/pddl/Description.h +++ b/include/plasp/pddl/Description.h @@ -33,6 +33,8 @@ class Description void parseContent(); void parseSection(); + void checkConsistency(); + utils::Parser m_parser; Context m_context; diff --git a/include/plasp/pddl/Domain.h b/include/plasp/pddl/Domain.h index 2dedf70..22c4fce 100644 --- a/include/plasp/pddl/Domain.h +++ b/include/plasp/pddl/Domain.h @@ -1,8 +1,12 @@ #ifndef __PLASP__PDDL__DOMAIN_H #define __PLASP__PDDL__DOMAIN_H +#include #include #include +#include +#include +#include #include namespace plasp @@ -19,19 +23,32 @@ namespace pddl class Domain { public: - static Domain fromPDDL(Context &context); - - public: - const std::string &name() const; - const Requirements &requirements() const; - const expressions::PrimitiveTypes &types() const; - const expressions::Constants &constants() const; - const expressions::PredicateDeclarations &predicates() const; - const std::vector> &actions() const; - - private: Domain(Context &context); + public: + void readPDDL(); + + bool isDeclared() const; + + const std::string &name() const; + + const Requirements &requirements() const; + + expressions::PrimitiveTypes &types(); + const expressions::PrimitiveTypes &types() const; + + expressions::Constants &constants(); + const expressions::Constants &constants() const; + + expressions::PredicateDeclarations &predicates(); + const expressions::PredicateDeclarations &predicates() const; + + std::vector> &actions(); + const std::vector> &actions() const; + + void checkConsistency(); + + private: void parseSection(); void parseRequirementSection(); @@ -46,12 +63,15 @@ class Domain void parseActionSection(); - void checkConsistency(); - Context &m_context; + bool m_isDeclared; std::string m_name; Requirements m_requirements; + expressions::PrimitiveTypes m_primitiveTypes; + expressions::Constants m_constants; + expressions::PredicateDeclarations m_predicateDeclarations; + std::vector> m_actions; }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/Expression.h b/include/plasp/pddl/Expression.h index f430280..29b1215 100644 --- a/include/plasp/pddl/Expression.h +++ b/include/plasp/pddl/Expression.h @@ -17,7 +17,10 @@ namespace pddl //////////////////////////////////////////////////////////////////////////////////////////////////// class Context; +class Domain; +class ExpressionContext; class ExpressionVisitor; +class Problem; class Expression; using ExpressionPointer = std::unique_ptr; @@ -77,10 +80,11 @@ class Expression //////////////////////////////////////////////////////////////////////////////////////////////////// ExpressionPointer parsePreconditionExpression(Context &context, - const expressions::Variables ¶meters); -ExpressionPointer parseExpression(Context &context, const expressions::Variables ¶meters); + ExpressionContext &expressionContext); +ExpressionPointer parseExpression(Context &context, ExpressionContext &expressionContext); -ExpressionPointer parseEffectExpression(Context &context, const expressions::Variables ¶meters); +ExpressionPointer parseEffectExpression(Context &context, + ExpressionContext &expressionContext); //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/ExpressionContext.h b/include/plasp/pddl/ExpressionContext.h new file mode 100644 index 0000000..4c60e01 --- /dev/null +++ b/include/plasp/pddl/ExpressionContext.h @@ -0,0 +1,46 @@ +#ifndef __PLASP__PDDL__EXPRESSION_CONTEXT_H +#define __PLASP__PDDL__EXPRESSION_CONTEXT_H + +#include +#include + +namespace plasp +{ +namespace pddl +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// ExpressionContext +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class ExpressionContext +{ + public: + ExpressionContext(Domain &domain, expressions::Variables ¶meters) + : domain(domain), + problem(nullptr), + parameters(parameters) + { + } + + ExpressionContext(Domain &domain, Problem *problem, expressions::Variables ¶meters) + : domain(domain), + problem{problem}, + parameters(parameters) + { + } + + Domain &domain; + Problem *problem; + + expressions::Variables ¶meters; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/pddl/Problem.h b/include/plasp/pddl/Problem.h index 565c220..2154290 100644 --- a/include/plasp/pddl/Problem.h +++ b/include/plasp/pddl/Problem.h @@ -19,15 +19,25 @@ namespace pddl class Problem { public: - static Problem fromPDDL(Context &context); + Problem(Context &context, Domain &domain); + + void readPDDL(); + + bool isDeclared() const; + + Domain &domain(); + const Domain &domain() const; - public: const std::string &name() const; + const Requirements &requirements() const; - private: - Problem(Context &context); + expressions::Constants &objects(); + const expressions::Constants &objects() const; + void checkConsistency(); + + private: void parseSection(); void parseRequirementSection(); @@ -36,9 +46,9 @@ class Problem void parseObjectSection(); - void checkConsistency(); - Context &m_context; + Domain &m_domain; + bool m_isDeclared; std::string m_name; Requirements m_requirements; diff --git a/include/plasp/pddl/expressions/And.h b/include/plasp/pddl/expressions/And.h index 266ac48..aa9a1f5 100644 --- a/include/plasp/pddl/expressions/And.h +++ b/include/plasp/pddl/expressions/And.h @@ -20,7 +20,7 @@ class And: public NAry { public: template - static AndPointer parse(Context &context, const Variables ¶meters, + static AndPointer parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression); public: @@ -33,12 +33,12 @@ class And: public NAry //////////////////////////////////////////////////////////////////////////////////////////////////// template -AndPointer And::parse(Context &context, const Variables ¶meters, +AndPointer And::parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression) { auto expression = std::make_unique(And()); - expression->NAry::parse(context, parameters, parseExpression); + expression->NAry::parse(context, expressionContext, parseExpression); if (expression->arguments().empty()) throw ConsistencyException("\"and\" expressions should not be empty"); diff --git a/include/plasp/pddl/expressions/Binary.h b/include/plasp/pddl/expressions/Binary.h index 135ce06..b041367 100644 --- a/include/plasp/pddl/expressions/Binary.h +++ b/include/plasp/pddl/expressions/Binary.h @@ -27,7 +27,8 @@ class Binary: public Expression protected: template - void parse(Context &context, const Variables ¶meters, ExpressionParser parseExpression); + void parse(Context &context, ExpressionContext &expressionContext, + ExpressionParser parseExpression); private: ExpressionPointer m_leftArgument; @@ -37,12 +38,13 @@ class Binary: public Expression //////////////////////////////////////////////////////////////////////////////////////////////////// template -void Binary::parse(Context &context, const Variables ¶meters, ExpressionParser parseExpression) +void Binary::parse(Context &context, ExpressionContext &expressionContext, + ExpressionParser parseExpression) { // Assume that expression identifier (imply, exists, etc.) is already parsed // Parse arguments of the expression - m_leftArgument = parseExpression(context, parameters); - m_rightArgument = parseExpression(context, parameters); + m_leftArgument = parseExpression(context, expressionContext); + m_rightArgument = parseExpression(context, expressionContext); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/expressions/Constant.h b/include/plasp/pddl/expressions/Constant.h index eeebb2a..b14b6a0 100644 --- a/include/plasp/pddl/expressions/Constant.h +++ b/include/plasp/pddl/expressions/Constant.h @@ -22,10 +22,10 @@ namespace expressions class Constant: public Expression { public: - static ConstantPointer parseDeclaration(Context &context); - static void parseTypedDeclaration(Context &context, Constants &constants); + static void parseTypedDeclaration(Context &context, Domain &domain); + static void parseTypedDeclaration(Context &context, Problem &problem); - static Constant *parseExisting(Context &context); + static Constant *parseAndFind(Context &context, const ExpressionContext &expressionContext); // TODO: method for lazy creation if not existing @@ -38,6 +38,11 @@ class Constant: public Expression bool isDeclared() const; private: + static ConstantPointer parseDeclaration(Context &context); + static void parseTypedDeclaration(Context &context, Domain &domain, Constants &constants); + + static Constant *parseAndFind(const std::string &constantName, const Constants &constants); + Constant(); void setDirty(bool isDirty = true); diff --git a/include/plasp/pddl/expressions/Either.h b/include/plasp/pddl/expressions/Either.h index 36e846c..b436894 100644 --- a/include/plasp/pddl/expressions/Either.h +++ b/include/plasp/pddl/expressions/Either.h @@ -20,7 +20,7 @@ class Either: public NAry { public: template - static EitherPointer parse(Context &context, const Variables ¶meters, + static EitherPointer parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression); public: @@ -33,12 +33,12 @@ class Either: public NAry //////////////////////////////////////////////////////////////////////////////////////////////////// template -EitherPointer Either::parse(Context &context, const Variables ¶meters, +EitherPointer Either::parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression) { auto expression = std::make_unique(Either()); - expression->NAry::parse(context, parameters, parseExpression); + expression->NAry::parse(context, expressionContext, parseExpression); if (expression->arguments().empty()) throw ConsistencyException("\"and\" expressions should not be empty"); diff --git a/include/plasp/pddl/expressions/Imply.h b/include/plasp/pddl/expressions/Imply.h index 029bfee..f3c476a 100644 --- a/include/plasp/pddl/expressions/Imply.h +++ b/include/plasp/pddl/expressions/Imply.h @@ -20,7 +20,7 @@ class Imply: public Binary { public: template - static ImplyPointer parse(Context &context, const Variables ¶meters, + static ImplyPointer parse(Context &context, ExpressionContext ¶meters, ExpressionParser parseExpression); public: @@ -33,7 +33,7 @@ class Imply: public Binary //////////////////////////////////////////////////////////////////////////////////////////////////// template -ImplyPointer Imply::parse(Context &context, const Variables ¶meters, +ImplyPointer Imply::parse(Context &context, ExpressionContext ¶meters, ExpressionParser parseExpression) { auto expression = std::make_unique(Imply()); diff --git a/include/plasp/pddl/expressions/NAry.h b/include/plasp/pddl/expressions/NAry.h index 0399390..c635654 100644 --- a/include/plasp/pddl/expressions/NAry.h +++ b/include/plasp/pddl/expressions/NAry.h @@ -26,7 +26,7 @@ class NAry: public Expression protected: template - void parse(Context &context, const Variables ¶meters, ExpressionParser parseExpression); + void parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression); private: Expressions m_arguments; @@ -35,7 +35,7 @@ class NAry: public Expression //////////////////////////////////////////////////////////////////////////////////////////////////// template -void NAry::parse(Context &context, const Variables ¶meters, ExpressionParser parseExpression) +void NAry::parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression) { context.parser.skipWhiteSpace(); @@ -43,7 +43,7 @@ void NAry::parse(Context &context, const Variables ¶meters, ExpressionParser // Parse arguments of the expression while (context.parser.currentCharacter() != ')') { - m_arguments.emplace_back(parseExpression(context, parameters)); + m_arguments.emplace_back(parseExpression(context, expressionContext)); context.parser.skipWhiteSpace(); } diff --git a/include/plasp/pddl/expressions/Not.h b/include/plasp/pddl/expressions/Not.h index c91a825..03fea0b 100644 --- a/include/plasp/pddl/expressions/Not.h +++ b/include/plasp/pddl/expressions/Not.h @@ -21,7 +21,7 @@ class Not: public Expression { public: template - static NotPointer parse(Context &context, const Variables ¶meters, + static NotPointer parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression); public: @@ -38,7 +38,7 @@ class Not: public Expression //////////////////////////////////////////////////////////////////////////////////////////////////// template -NotPointer Not::parse(Context &context, const Variables ¶meters, +NotPointer Not::parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression) { auto expression = std::make_unique(Not()); @@ -46,7 +46,7 @@ NotPointer Not::parse(Context &context, const Variables ¶meters, context.parser.skipWhiteSpace(); // Parse argument - expression->m_argument = parseExpression(context, parameters); + expression->m_argument = parseExpression(context, expressionContext); return expression; } diff --git a/include/plasp/pddl/expressions/Or.h b/include/plasp/pddl/expressions/Or.h index a33c4d6..dfc5b19 100644 --- a/include/plasp/pddl/expressions/Or.h +++ b/include/plasp/pddl/expressions/Or.h @@ -20,7 +20,7 @@ class Or: public NAry { public: template - static OrPointer parse(Context &context, const Variables ¶meters, + static OrPointer parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression); public: @@ -33,11 +33,12 @@ class Or: public NAry //////////////////////////////////////////////////////////////////////////////////////////////////// template -OrPointer Or::parse(Context &context, const Variables ¶meters, ExpressionParser parseExpression) +OrPointer Or::parse(Context &context, ExpressionContext &expressionContext, + ExpressionParser parseExpression) { auto expression = std::make_unique(Or()); - expression->NAry::parse(context, parameters, parseExpression); + expression->NAry::parse(context, expressionContext, parseExpression); if (expression->arguments().empty()) throw ConsistencyException("\"or\" expressions should not be empty"); diff --git a/include/plasp/pddl/expressions/Predicate.h b/include/plasp/pddl/expressions/Predicate.h index dde8f73..c71e1d7 100644 --- a/include/plasp/pddl/expressions/Predicate.h +++ b/include/plasp/pddl/expressions/Predicate.h @@ -20,7 +20,7 @@ class Predicate: public Expression { public: static PredicatePointer parse(std::string name, Context &context, - const Variables ¶meters); + ExpressionContext &expressionContext); public: void accept(ExpressionVisitor &expressionVisitor) const override; diff --git a/include/plasp/pddl/expressions/PredicateDeclaration.h b/include/plasp/pddl/expressions/PredicateDeclaration.h index b9eebc4..684057f 100644 --- a/include/plasp/pddl/expressions/PredicateDeclaration.h +++ b/include/plasp/pddl/expressions/PredicateDeclaration.h @@ -19,7 +19,7 @@ namespace expressions class PredicateDeclaration: public Expression { public: - static void parse(Context &context); + static void parse(Context &context, Domain &domain); public: void accept(ExpressionVisitor &expressionVisitor) const override; @@ -37,7 +37,7 @@ class PredicateDeclaration: public Expression bool m_isDeclared; std::string m_name; - Variables m_arguments; + Variables m_parameters; }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/expressions/PrimitiveType.h b/include/plasp/pddl/expressions/PrimitiveType.h index 12a7987..e42e913 100644 --- a/include/plasp/pddl/expressions/PrimitiveType.h +++ b/include/plasp/pddl/expressions/PrimitiveType.h @@ -22,12 +22,15 @@ namespace expressions class PrimitiveType: public Expression { public: - static PrimitiveType *parseDeclaration(Context &context); - static void parseTypedDeclaration(Context &context); + static void parseDeclaration(Context &context, Domain &domain); + static void parseTypedDeclaration(Context &context, Domain &domain); - static PrimitiveType *parseExisting(Context &context); + static PrimitiveType *parseAndFindOrCreate(Context &context, Domain &domain); public: + PrimitiveType(); + PrimitiveType(std::string name); + void accept(ExpressionVisitor &expressionVisitor) const override; const std::string &name() const; @@ -36,11 +39,6 @@ class PrimitiveType: public Expression bool isDeclared() const; private: - static PrimitiveType *create(std::string name, Context &context); - - private: - PrimitiveType(); - void setDirty(bool isDirty = true); bool isDirty() const; diff --git a/include/plasp/pddl/expressions/Type.h b/include/plasp/pddl/expressions/Type.h index d7118a5..54c09cd 100644 --- a/include/plasp/pddl/expressions/Type.h +++ b/include/plasp/pddl/expressions/Type.h @@ -16,7 +16,8 @@ namespace expressions // //////////////////////////////////////////////////////////////////////////////////////////////////// -ExpressionPointer parseExistingPrimitiveType(Context &context, const Variables ¶meters); +ExpressionPointer parseExistingPrimitiveType(Context &context, + ExpressionContext &expressionContext); //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/expressions/Variable.h b/include/plasp/pddl/expressions/Variable.h index 01e8297..79f1163 100644 --- a/include/plasp/pddl/expressions/Variable.h +++ b/include/plasp/pddl/expressions/Variable.h @@ -19,11 +19,9 @@ namespace expressions class Variable: public Expression { public: - static VariablePointer parseDeclaration(Context &context); + static void parseTypedDeclaration(Context &context, ExpressionContext &expressionContext); - static void parseTypedDeclaration(Context &context, Variables ¶meters); - - static const Variable *parseExisting(Context &context, const Variables &variables); + static const Variable *parseAndFind(Context &context, const ExpressionContext &expressionContext); public: void accept(ExpressionVisitor &expressionVisitor) const override; @@ -36,6 +34,9 @@ class Variable: public Expression void setType(const Expression *type); + private: + static void parseDeclaration(Context &context, Variables ¶meters); + private: Variable(); diff --git a/src/plasp/pddl/Action.cpp b/src/plasp/pddl/Action.cpp index 1124901..14f0bd3 100644 --- a/src/plasp/pddl/Action.cpp +++ b/src/plasp/pddl/Action.cpp @@ -3,6 +3,8 @@ #include #include +#include +#include #include #include #include @@ -26,20 +28,21 @@ Action::Action(std::string name) //////////////////////////////////////////////////////////////////////////////////////////////////// -Action &Action::parseDeclaration(Context &context) +void Action::parseDeclaration(Context &context, Domain &domain) { const auto actionName = context.parser.parseIdentifier(isIdentifier); auto action = std::make_unique(Action(actionName)); context.parser.expect(":parameters"); - context.parser.expect("("); + ExpressionContext expressionContext(domain, action->m_parameters); + // Read parameters while (context.parser.currentCharacter() != ')') { - expressions::Variable::parseTypedDeclaration(context, action->m_parameters); + expressions::Variable::parseTypedDeclaration(context, expressionContext); context.parser.skipWhiteSpace(); } @@ -54,17 +57,15 @@ Action &Action::parseDeclaration(Context &context) const auto sectionIdentifier = context.parser.parseIdentifier(isIdentifier); if (sectionIdentifier == "precondition") - action->m_precondition = parsePreconditionExpression(context, action->m_parameters); + action->m_precondition = parsePreconditionExpression(context, expressionContext); else if (sectionIdentifier == "effect") - action->m_effect = parseEffectExpression(context, action->m_parameters); + action->m_effect = parseEffectExpression(context, expressionContext); context.parser.skipWhiteSpace(); } // Store new action - context.actions.emplace_back(std::move(action)); - - return *context.actions.back(); + expressionContext.domain.actions().emplace_back(std::move(action)); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/Description.cpp b/src/plasp/pddl/Description.cpp index e7b34a4..72d3e62 100644 --- a/src/plasp/pddl/Description.cpp +++ b/src/plasp/pddl/Description.cpp @@ -31,6 +31,9 @@ Description Description::fromStream(std::istream &istream) { Description description(istream); + description.m_domain = std::make_unique(Domain(description.m_context)); + description.m_problem = std::make_unique(Problem(description.m_context, *description.m_domain)); + while (true) { description.m_context.parser.skipWhiteSpace(); @@ -41,6 +44,8 @@ Description Description::fromStream(std::istream &istream) description.parseContent(); } + description.checkConsistency(); + return description; } @@ -89,14 +94,36 @@ void Description::parseSection() std::cout << "Parsing section " << sectionIdentifier << std::endl; if (sectionIdentifier == "domain") - m_domain = std::make_unique(Domain::fromPDDL(m_context)); + { + BOOST_ASSERT(m_domain); + + if (m_domain->isDeclared()) + throw utils::ParserException(m_context.parser, "PDDL description may not contain two domains"); + + m_domain->readPDDL(); + } else if (sectionIdentifier == "problem") - m_problem = std::make_unique(Problem::fromPDDL(m_context)); + { + BOOST_ASSERT(m_problem); + + if (m_problem->isDeclared()) + throw utils::ParserException(m_context.parser, "PDDL description may currently not contain two problems"); + + m_problem->readPDDL(); + } else throw utils::ParserException(m_context.parser, "Unknown PDDL section \"" + sectionIdentifier + "\""); } //////////////////////////////////////////////////////////////////////////////////////////////////// +void Description::checkConsistency() +{ + m_domain->checkConsistency(); + m_problem->checkConsistency(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } diff --git a/src/plasp/pddl/Domain.cpp b/src/plasp/pddl/Domain.cpp index 493689c..2d2d76b 100644 --- a/src/plasp/pddl/Domain.cpp +++ b/src/plasp/pddl/Domain.cpp @@ -23,37 +23,41 @@ namespace pddl //////////////////////////////////////////////////////////////////////////////////////////////////// Domain::Domain(Context &context) -: m_context(context) +: m_context(context), + m_isDeclared{false} { } //////////////////////////////////////////////////////////////////////////////////////////////////// -Domain Domain::fromPDDL(Context &context) +void Domain::readPDDL() { - Domain domain(context); + m_name = m_context.parser.parseIdentifier(isIdentifier); - domain.m_name = context.parser.parseIdentifier(isIdentifier); + std::cout << "Parsing domain " << m_name << std::endl; - std::cout << "Parsing domain " << domain.m_name << std::endl; - - context.parser.expect(")"); + m_context.parser.expect(")"); while (true) { - context.parser.skipWhiteSpace(); + m_context.parser.skipWhiteSpace(); - if (context.parser.currentCharacter() == ')') + if (m_context.parser.currentCharacter() == ')') break; - domain.parseSection(); + parseSection(); } - domain.computeDerivedRequirements(); + computeDerivedRequirements(); - domain.checkConsistency(); + m_isDeclared = true; +} - return domain; +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool Domain::isDeclared() const +{ + return m_isDeclared; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -72,30 +76,58 @@ const Requirements &Domain::requirements() const //////////////////////////////////////////////////////////////////////////////////////////////////// +expressions::PrimitiveTypes &Domain::types() +{ + return m_primitiveTypes; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + const expressions::PrimitiveTypes &Domain::types() const { - return m_context.primitiveTypes; + return m_primitiveTypes; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +expressions::Constants &Domain::constants() +{ + return m_constants; } //////////////////////////////////////////////////////////////////////////////////////////////////// const expressions::Constants &Domain::constants() const { - return m_context.constants; + return m_constants; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +expressions::PredicateDeclarations &Domain::predicates() +{ + return m_predicateDeclarations; } //////////////////////////////////////////////////////////////////////////////////////////////////// const expressions::PredicateDeclarations &Domain::predicates() const { - return m_context.predicateDeclarations; + return m_predicateDeclarations; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::vector> &Domain::actions() +{ + return m_actions; } //////////////////////////////////////////////////////////////////////////////////////////////////// const std::vector> &Domain::actions() const { - return m_context.actions; + return m_actions; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -242,7 +274,7 @@ void Domain::parseTypeSection() if (m_context.parser.currentCharacter() == '(') throw utils::ParserException(m_context.parser, "Only primitive types are allowed in type section"); - expressions::PrimitiveType::parseTypedDeclaration(m_context); + expressions::PrimitiveType::parseTypedDeclaration(m_context, *this); m_context.parser.skipWhiteSpace(); } @@ -259,7 +291,7 @@ void Domain::parseConstantSection() // Store constants while (m_context.parser.currentCharacter() != ')') { - expressions::Constant::parseTypedDeclaration(m_context, m_context.constants); + expressions::Constant::parseTypedDeclaration(m_context, *this); m_context.parser.skipWhiteSpace(); } @@ -276,7 +308,7 @@ void Domain::parsePredicateSection() // Store predicates and their arguments while (m_context.parser.currentCharacter() != ')') { - expressions::PredicateDeclaration::parse(m_context); + expressions::PredicateDeclaration::parse(m_context, *this); m_context.parser.skipWhiteSpace(); } @@ -290,7 +322,7 @@ void Domain::parseActionSection() { m_context.parser.skipWhiteSpace(); - Action::parseDeclaration(m_context); + Action::parseDeclaration(m_context, *this); m_context.parser.expect(")"); } @@ -300,7 +332,7 @@ void Domain::parseActionSection() void Domain::checkConsistency() { // Verify that typing requirement is correctly declared if used - if (!m_context.primitiveTypes.empty() && !hasRequirement(Requirement::Type::Typing)) + if (!m_primitiveTypes.empty() && !hasRequirement(Requirement::Type::Typing)) { throw ConsistencyException("Domain contains typing information but does not declare typing requirement"); @@ -308,7 +340,7 @@ void Domain::checkConsistency() } // Verify that all used types have been declared - std::for_each(m_context.primitiveTypes.cbegin(), m_context.primitiveTypes.cend(), + std::for_each(m_primitiveTypes.cbegin(), m_primitiveTypes.cend(), [&](const auto &type) { if (!type->isDeclared()) @@ -316,7 +348,7 @@ void Domain::checkConsistency() }); // Verify that all used constants have been declared - std::for_each(m_context.constants.cbegin(), m_context.constants.cend(), + std::for_each(m_constants.cbegin(), m_constants.cend(), [&](const auto &constant) { if (!constant->isDeclared()) @@ -327,7 +359,7 @@ void Domain::checkConsistency() }); // Verify that all used predicates have been declared - std::for_each(m_context.predicateDeclarations.cbegin(), m_context.predicateDeclarations.cend(), + std::for_each(m_predicateDeclarations.cbegin(), m_predicateDeclarations.cend(), [&](const auto &predicate) { if (!predicate->isDeclared()) diff --git a/src/plasp/pddl/Expression.cpp b/src/plasp/pddl/Expression.cpp index 04baf11..e5e88da 100644 --- a/src/plasp/pddl/Expression.cpp +++ b/src/plasp/pddl/Expression.cpp @@ -1,6 +1,8 @@ #include #include +#include +#include #include #include #include @@ -23,15 +25,16 @@ namespace pddl // //////////////////////////////////////////////////////////////////////////////////////////////////// -ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier, - Context &context, const expressions::Variables ¶meters); +ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier, Context &context, + ExpressionContext &expressionContext); ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier, - Context &context, const expressions::Variables ¶meters); -ExpressionPointer parsePredicate(Context &context, const expressions::Variables ¶meters); + Context &context, ExpressionContext &expressionContext); +ExpressionPointer parsePredicate(Context &context, ExpressionContext &expressionContext); //////////////////////////////////////////////////////////////////////////////////////////////////// -void throwUnsupported(const utils::Parser &parser, const std::string &expressionIdentifier) +[[noreturn]] void throwUnsupported(const utils::Parser &parser, + const std::string &expressionIdentifier) { throw utils::ParserException(parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported in this context"); } @@ -39,7 +42,7 @@ void throwUnsupported(const utils::Parser &parser, const std::string &expression //////////////////////////////////////////////////////////////////////////////////////////////////// ExpressionPointer parsePreconditionExpression(Context &context, - const expressions::Variables ¶meters) + ExpressionContext &expressionContext) { context.parser.expect("("); @@ -49,7 +52,7 @@ ExpressionPointer parsePreconditionExpression(Context &context, if (expressionIdentifier == "and") { - expression = expressions::And::parse(context, parameters, + expression = expressions::And::parse(context, expressionContext, parsePreconditionExpression); } else if (expressionIdentifier == "forall" @@ -58,7 +61,7 @@ ExpressionPointer parsePreconditionExpression(Context &context, throwUnsupported(context.parser, expressionIdentifier); } else - expression = parseExpressionContent(expressionIdentifier, context, parameters); + expression = parseExpressionContent(expressionIdentifier, context, expressionContext); context.parser.expect(")"); @@ -67,13 +70,13 @@ ExpressionPointer parsePreconditionExpression(Context &context, //////////////////////////////////////////////////////////////////////////////////////////////////// -ExpressionPointer parseExpression(Context &context, const expressions::Variables ¶meters) +ExpressionPointer parseExpression(Context &context, ExpressionContext &expressionContext) { context.parser.expect("("); const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier); - auto expression = parseExpressionContent(expressionIdentifier, context, parameters); + auto expression = parseExpressionContent(expressionIdentifier, context, expressionContext); context.parser.expect(")"); @@ -82,22 +85,22 @@ ExpressionPointer parseExpression(Context &context, const expressions::Variables //////////////////////////////////////////////////////////////////////////////////////////////////// -ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier, - Context &context, const expressions::Variables ¶meters) +ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier, Context &context, + ExpressionContext &expressionContext) { context.parser.skipWhiteSpace(); if (expressionIdentifier == "and") - return expressions::And::parse(context, parameters, parseExpression); + return expressions::And::parse(context, expressionContext, parseExpression); if (expressionIdentifier == "or") - return expressions::Or::parse(context, parameters, parseExpression); + return expressions::Or::parse(context, expressionContext, parseExpression); if (expressionIdentifier == "not") - return expressions::Not::parse(context, parameters, parseExpression); + return expressions::Not::parse(context, expressionContext, parseExpression); if (expressionIdentifier == "imply") - return expressions::Imply::parse(context, parameters, parseExpression); + return expressions::Imply::parse(context, expressionContext, parseExpression); if (expressionIdentifier == "exists" || expressionIdentifier == "forall" @@ -116,23 +119,25 @@ ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier throwUnsupported(context.parser, expressionIdentifier); } + auto &predicateDeclarations = expressionContext.domain.predicates(); + // Check if predicate with that name exists - const auto match = std::find_if(context.predicateDeclarations.cbegin(), context.predicateDeclarations.cend(), + const auto match = std::find_if(predicateDeclarations.cbegin(), predicateDeclarations.cend(), [&](const auto &predicate) { return predicate->name() == expressionIdentifier; }); // If predicate exists, parse it - if (match != context.predicateDeclarations.cend()) - return expressions::Predicate::parse(expressionIdentifier, context, parameters); + if (match != predicateDeclarations.cend()) + return expressions::Predicate::parse(expressionIdentifier, context, expressionContext); throw utils::ParserException(context.parser, "Expression \"" + expressionIdentifier + "\" not allowed in this context"); } //////////////////////////////////////////////////////////////////////////////////////////////////// -ExpressionPointer parseEffectExpression(Context &context, const expressions::Variables ¶meters) +ExpressionPointer parseEffectExpression(Context &context, ExpressionContext &expressionContext) { context.parser.expect("("); @@ -141,14 +146,14 @@ ExpressionPointer parseEffectExpression(Context &context, const expressions::Var ExpressionPointer expression; if (expressionIdentifier == "and") - expression = expressions::And::parse(context, parameters, parseEffectExpression); + expression = expressions::And::parse(context, expressionContext, parseEffectExpression); else if (expressionIdentifier == "forall" || expressionIdentifier == "when") { throwUnsupported(context.parser, expressionIdentifier); } else - expression = parseEffectBodyExpressionContent(expressionIdentifier, context, parameters); + expression = parseEffectBodyExpressionContent(expressionIdentifier, context, expressionContext); context.parser.expect(")"); @@ -158,12 +163,12 @@ ExpressionPointer parseEffectExpression(Context &context, const expressions::Var //////////////////////////////////////////////////////////////////////////////////////////////////// ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier, - Context &context, const expressions::Variables ¶meters) + Context &context, ExpressionContext &expressionContext) { ExpressionPointer expression; if (expressionIdentifier == "not") - return expressions::Not::parse(context, parameters, parsePredicate); + return expressions::Not::parse(context, expressionContext, parsePredicate); if (expressionIdentifier == "=" || expressionIdentifier == "assign" @@ -175,23 +180,25 @@ ExpressionPointer parseEffectBodyExpressionContent(const std::string &expression throwUnsupported(context.parser, expressionIdentifier); } + const auto &predicateDeclarations = expressionContext.domain.predicates(); + // Check if predicate with that name exists - const auto match = std::find_if(context.predicateDeclarations.cbegin(), context.predicateDeclarations.cend(), + const auto match = std::find_if(predicateDeclarations.cbegin(), predicateDeclarations.cend(), [&](const auto &predicate) { return predicate->name() == expressionIdentifier; }); // If predicate exists, parse it - if (match != context.predicateDeclarations.cend()) - return expressions::Predicate::parse(expressionIdentifier, context, parameters); + if (match != predicateDeclarations.cend()) + return expressions::Predicate::parse(expressionIdentifier, context, expressionContext); throw utils::ParserException(context.parser, "Expression \"" + expressionIdentifier + "\" not allowed in this context"); } //////////////////////////////////////////////////////////////////////////////////////////////////// -ExpressionPointer parsePredicate(Context &context, const expressions::Variables ¶meters) +ExpressionPointer parsePredicate(Context &context, ExpressionContext &expressionContext) { context.parser.expect("("); @@ -199,18 +206,20 @@ ExpressionPointer parsePredicate(Context &context, const expressions::Variables ExpressionPointer expression; + const auto &predicateDeclarations = expressionContext.domain.predicates(); + // Check if predicate with that name exists - const auto match = std::find_if(context.predicateDeclarations.cbegin(), context.predicateDeclarations.cend(), + const auto match = std::find_if(predicateDeclarations.cbegin(), predicateDeclarations.cend(), [&](const auto &predicate) { return predicate->name() == predicateName; }); // If predicate exists, parse it - if (match == context.predicateDeclarations.cend()) + if (match == predicateDeclarations.cend()) throw utils::ParserException(context.parser, "Unknown predicate \"" + predicateName + "\""); - expression = expressions::Predicate::parse(predicateName, context, parameters); + expression = expressions::Predicate::parse(predicateName, context, expressionContext); context.parser.expect(")"); diff --git a/src/plasp/pddl/Problem.cpp b/src/plasp/pddl/Problem.cpp index 75611ba..3f3738b 100644 --- a/src/plasp/pddl/Problem.cpp +++ b/src/plasp/pddl/Problem.cpp @@ -3,7 +3,9 @@ #include #include +#include #include +#include namespace plasp { @@ -16,38 +18,57 @@ namespace pddl // //////////////////////////////////////////////////////////////////////////////////////////////////// -Problem::Problem(Context &context) -: m_context(context) +Problem::Problem(Context &context, Domain &domain) +: m_context(context), + m_domain(domain), + m_isDeclared{false} { } //////////////////////////////////////////////////////////////////////////////////////////////////// -Problem Problem::fromPDDL(Context &context) +void Problem::readPDDL() { - Problem problem(context); + m_name = m_context.parser.parseIdentifier(isIdentifier); - problem.m_name = context.parser.parseIdentifier(isIdentifier); + std::cout << "Parsing problem " << m_name << std::endl; - std::cout << "Parsing problem " << problem.m_name << std::endl; - - context.parser.expect(")"); + m_context.parser.expect(")"); while (true) { - context.parser.skipWhiteSpace(); + m_context.parser.skipWhiteSpace(); - if (context.parser.currentCharacter() == ')') + if (m_context.parser.currentCharacter() == ')') break; - problem.parseSection(); + parseSection(); } - problem.computeDerivedRequirements(); + computeDerivedRequirements(); - problem.checkConsistency(); + m_isDeclared = true; +} - return problem; +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool Problem::isDeclared() const +{ + return m_isDeclared; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Domain &Problem::domain() +{ + return m_domain; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +const Domain &Problem::domain() const +{ + return m_domain; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -66,6 +87,20 @@ const Requirements &Problem::requirements() const //////////////////////////////////////////////////////////////////////////////////////////////////// +expressions::Constants &Problem::objects() +{ + return m_objects; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +const expressions::Constants &Problem::objects() const +{ + return m_objects; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void Problem::parseSection() { m_context.parser.expect("("); @@ -203,7 +238,7 @@ void Problem::parseObjectSection() // Store constants while (m_context.parser.currentCharacter() != ')') { - expressions::Constant::parseTypedDeclaration(m_context); + //expressions::Constant::parseTypedDeclaration(m_context); m_context.parser.skipWhiteSpace(); } diff --git a/src/plasp/pddl/expressions/Constant.cpp b/src/plasp/pddl/expressions/Constant.cpp index 18af058..5e26d3b 100644 --- a/src/plasp/pddl/expressions/Constant.cpp +++ b/src/plasp/pddl/expressions/Constant.cpp @@ -5,7 +5,10 @@ #include #include +#include +#include #include +#include #include namespace plasp @@ -50,7 +53,21 @@ ConstantPointer Constant::parseDeclaration(Context &context) //////////////////////////////////////////////////////////////////////////////////////////////////// -void Constant::parseTypedDeclaration(Context &context, Constants &constants) +void Constant::parseTypedDeclaration(Context &context, Domain &domain) +{ + parseTypedDeclaration(context, domain, domain.constants()); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Constant::parseTypedDeclaration(Context &context, Problem &problem) +{ + parseTypedDeclaration(context, problem.domain(), problem.objects()); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Constant::parseTypedDeclaration(Context &context, Domain &domain, Constants &constants) { // Parse and store constant constants.emplace_back(parseDeclaration(context)); @@ -67,7 +84,7 @@ void Constant::parseTypedDeclaration(Context &context, Constants &constants) return; // If existing, parse and store parent type - auto *type = PrimitiveType::parseExisting(context); + auto *type = PrimitiveType::parseAndFindOrCreate(context, domain); // Assign parent type to all types that were previously flagged std::for_each(constants.begin(), constants.end(), @@ -83,21 +100,42 @@ void Constant::parseTypedDeclaration(Context &context, Constants &constants) //////////////////////////////////////////////////////////////////////////////////////////////////// -Constant *Constant::parseExisting(Context &context) +Constant *Constant::parseAndFind(Context &context, const ExpressionContext &expressionContext) { context.parser.skipWhiteSpace(); const auto constantName = context.parser.parseIdentifier(isIdentifier); + + auto *constant = parseAndFind(constantName, expressionContext.domain.constants()); + + if (constant) + return constant; + + if (expressionContext.problem) + { + constant = parseAndFind(constantName, expressionContext.problem->objects()); + + if (constant) + return constant; + } + + throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Constant *Constant::parseAndFind(const std::string &constantName, const Constants &constants) +{ // TODO: use hash map - const auto match = std::find_if(context.constants.cbegin(), context.constants.cend(), + const auto match = std::find_if(constants.cbegin(), constants.cend(), [&](const auto &constant) { return constant->name() == constantName; }); - const auto constantExists = (match != context.constants.cend()); + const auto constantExists = (match != constants.cend()); if (!constantExists) - throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared"); + return nullptr; return match->get(); } diff --git a/src/plasp/pddl/expressions/InitialState.cpp b/src/plasp/pddl/expressions/InitialState.cpp index 4b4f449..3d85d3f 100644 --- a/src/plasp/pddl/expressions/InitialState.cpp +++ b/src/plasp/pddl/expressions/InitialState.cpp @@ -1,8 +1,10 @@ #include #include +#include #include #include +#include namespace plasp { diff --git a/src/plasp/pddl/expressions/Predicate.cpp b/src/plasp/pddl/expressions/Predicate.cpp index 15c8526..73f9bdf 100644 --- a/src/plasp/pddl/expressions/Predicate.cpp +++ b/src/plasp/pddl/expressions/Predicate.cpp @@ -1,6 +1,8 @@ #include #include +#include +#include #include #include #include @@ -27,7 +29,8 @@ Predicate::Predicate() //////////////////////////////////////////////////////////////////////////////////////////////////// -PredicatePointer Predicate::parse(std::string name, Context &context, const Variables ¶meters) +PredicatePointer Predicate::parse(std::string name, Context &context, + ExpressionContext &expressionContext) { auto predicate = std::make_unique(Predicate()); @@ -41,14 +44,14 @@ PredicatePointer Predicate::parse(std::string name, Context &context, const Vari // Parse variables if (context.parser.currentCharacter() == '?') { - const auto *variable = Variable::parseExisting(context, parameters); + const auto *variable = Variable::parseAndFind(context, expressionContext); auto variableReference = std::make_unique>(variable); predicate->m_arguments.emplace_back(std::move(variableReference)); } // Parse constants else { - const auto *constant = Constant::parseExisting(context); + const auto *constant = Constant::parseAndFind(context, expressionContext); auto constantReference = std::make_unique>(constant); predicate->m_arguments.emplace_back(std::move(constantReference)); } diff --git a/src/plasp/pddl/expressions/PredicateDeclaration.cpp b/src/plasp/pddl/expressions/PredicateDeclaration.cpp index a7ed7cd..2330d23 100644 --- a/src/plasp/pddl/expressions/PredicateDeclaration.cpp +++ b/src/plasp/pddl/expressions/PredicateDeclaration.cpp @@ -1,6 +1,8 @@ #include #include +#include +#include #include #include #include @@ -27,7 +29,7 @@ PredicateDeclaration::PredicateDeclaration() //////////////////////////////////////////////////////////////////////////////////////////////////// -void PredicateDeclaration::parse(Context &context) +void PredicateDeclaration::parse(Context &context, Domain &domain) { context.parser.expect("("); @@ -40,18 +42,19 @@ void PredicateDeclaration::parse(Context &context) context.parser.skipWhiteSpace(); + ExpressionContext expressionContext(domain, predicate->m_parameters); + // Parse arguments while (context.parser.currentCharacter() != ')') { - expressions::Variable::parseTypedDeclaration(context, predicate->m_arguments); + expressions::Variable::parseTypedDeclaration(context, expressionContext); context.parser.skipWhiteSpace(); } context.parser.expect(")"); - // Store new predicate - context.predicateDeclarations.emplace_back(std::move(predicate)); + domain.predicates().emplace_back(std::move(predicate)); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -86,7 +89,7 @@ const std::string &PredicateDeclaration::name() const const Variables &PredicateDeclaration::arguments() const { - return m_arguments; + return m_parameters; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/expressions/PrimitiveType.cpp b/src/plasp/pddl/expressions/PrimitiveType.cpp index 6cb6b12..cb708c8 100644 --- a/src/plasp/pddl/expressions/PrimitiveType.cpp +++ b/src/plasp/pddl/expressions/PrimitiveType.cpp @@ -5,6 +5,8 @@ #include #include +#include +#include #include namespace plasp @@ -21,65 +23,61 @@ namespace expressions //////////////////////////////////////////////////////////////////////////////////////////////////// PrimitiveType::PrimitiveType() -: m_isDirty{false}, +: m_isDirty{true}, m_isDeclared{false} { } //////////////////////////////////////////////////////////////////////////////////////////////////// -PrimitiveType *PrimitiveType::create(std::string name, Context &context) +PrimitiveType::PrimitiveType(std::string name) +: m_isDirty{true}, + m_isDeclared{false}, + m_name{name} { - // Create new primitive type if not already existing - auto type = std::make_unique(PrimitiveType()); - - type->m_name = name; - - BOOST_ASSERT(!type->m_name.empty()); - - // Flag type for potentially upcoming parent type declaration - type->setDirty(); - - // TODO: Store constant in hash map - context.primitiveTypes.emplace_back(std::move(type)); - - return context.primitiveTypes.back().get(); + BOOST_ASSERT(!m_name.empty()); } //////////////////////////////////////////////////////////////////////////////////////////////////// -PrimitiveType *PrimitiveType::parseDeclaration(Context &context) +void PrimitiveType::parseDeclaration(Context &context, Domain &domain) { + auto &types = domain.types(); + context.parser.skipWhiteSpace(); const auto typeName = context.parser.parseIdentifier(isIdentifier); // TODO: use hash map - const auto match = std::find_if(context.primitiveTypes.cbegin(), context.primitiveTypes.cend(), + const auto match = std::find_if(types.cbegin(), types.cend(), [&](const auto &primitiveType) { return primitiveType->name() == typeName; }); // Return existing primitive type - if (match != context.primitiveTypes.cend()) + if (match != types.cend()) { auto *type = match->get(); type->setDirty(); - return type; + return; } - return create(typeName, context); + types.emplace_back(std::make_unique(typeName)); } //////////////////////////////////////////////////////////////////////////////////////////////////// -void PrimitiveType::parseTypedDeclaration(Context &context) +void PrimitiveType::parseTypedDeclaration(Context &context, Domain &domain) { + auto &types = domain.types(); + // Parse and store type - auto *type = parseDeclaration(context); + parseDeclaration(context, domain); + + auto *type = types.back().get(); // Flag type as correctly declared in the types section type->setDeclared(); @@ -91,7 +89,7 @@ void PrimitiveType::parseTypedDeclaration(Context &context) return; // If existing, parse and store parent type - auto *parentType = parseExisting(context); + auto *parentType = parseAndFindOrCreate(context, domain); parentType->setDirty(false); @@ -99,7 +97,7 @@ void PrimitiveType::parseTypedDeclaration(Context &context) parentType->setDeclared(); // Assign parent type to all types that were previously flagged - std::for_each(context.primitiveTypes.begin(), context.primitiveTypes.end(), + std::for_each(types.begin(), types.end(), [&](auto &childType) { if (!childType->isDirty()) @@ -112,8 +110,10 @@ void PrimitiveType::parseTypedDeclaration(Context &context) //////////////////////////////////////////////////////////////////////////////////////////////////// -PrimitiveType *PrimitiveType::parseExisting(Context &context) +PrimitiveType *PrimitiveType::parseAndFindOrCreate(Context &context, Domain &domain) { + auto &types = domain.types(); + context.parser.skipWhiteSpace(); const auto typeName = context.parser.parseIdentifier(isIdentifier); @@ -121,19 +121,22 @@ PrimitiveType *PrimitiveType::parseExisting(Context &context) BOOST_ASSERT(!typeName.empty()); // TODO: use hash map - const auto match = std::find_if(context.primitiveTypes.cbegin(), context.primitiveTypes.cend(), + const auto match = std::find_if(types.cbegin(), types.cend(), [&](const auto &primitiveType) { return primitiveType->name() == typeName; }); - if (match == context.primitiveTypes.cend()) + if (match == types.cend()) { // Primitive type "object" is implicitly declared if (typeName != "object") context.logger.parserWarning(context.parser, "Primitive type \"" + typeName + "\" used but never declared"); - return create(typeName, context); + types.emplace_back(std::make_unique(typeName)); + types.back()->setDeclared(); + + return types.back().get(); } auto *type = match->get(); diff --git a/src/plasp/pddl/expressions/Type.cpp b/src/plasp/pddl/expressions/Type.cpp index a8c16b9..b65c6ca 100644 --- a/src/plasp/pddl/expressions/Type.cpp +++ b/src/plasp/pddl/expressions/Type.cpp @@ -1,6 +1,8 @@ #include #include +#include +#include #include namespace plasp @@ -16,9 +18,9 @@ namespace expressions // //////////////////////////////////////////////////////////////////////////////////////////////////// -ExpressionPointer parseExistingPrimitiveType(Context &context, const Variables ¶meters) +ExpressionPointer parseExistingPrimitiveType(Context &context, ExpressionContext &expressionContext) { - auto primitiveType = PrimitiveType::parseExisting(context); + auto *primitiveType = PrimitiveType::parseAndFindOrCreate(context, expressionContext.domain); return std::make_unique>(primitiveType); } diff --git a/src/plasp/pddl/expressions/Variable.cpp b/src/plasp/pddl/expressions/Variable.cpp index b758744..4317a28 100644 --- a/src/plasp/pddl/expressions/Variable.cpp +++ b/src/plasp/pddl/expressions/Variable.cpp @@ -2,10 +2,14 @@ #include +#include + #include +#include #include #include #include +#include #include #include @@ -29,7 +33,7 @@ Variable::Variable() //////////////////////////////////////////////////////////////////////////////////////////////////// -VariablePointer Variable::parseDeclaration(Context &context) +void Variable::parseDeclaration(Context &context, Variables ¶meters) { context.parser.skipWhiteSpace(); @@ -42,17 +46,19 @@ VariablePointer Variable::parseDeclaration(Context &context) // Flag variable for potentially upcoming type declaration variable->setDirty(); - return variable; + parameters.emplace_back(std::move(variable)); } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Variable::parseTypedDeclaration(Context &context, Variables ¶meters) +void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expressionContext) { - // Parse and store variable itself - parameters.emplace_back(parseDeclaration(context)); + auto &variables = expressionContext.parameters; - auto ¶meter = parameters.back(); + // Parse and store variable itself + parseDeclaration(context, variables); + + auto &variable = variables.back(); context.parser.skipWhiteSpace(); @@ -66,14 +72,14 @@ void Variable::parseTypedDeclaration(Context &context, Variables ¶meters) [&](const auto *type) { // Set the argument type for all previously flagged arguments - std::for_each(parameters.begin(), parameters.end(), - [&](auto ¶meter) + std::for_each(variables.begin(), variables.end(), + [&](auto &variable) { - if (!parameter->isDirty()) + if (!variable->isDirty()) return; - parameter->setType(type); - parameter->setDirty(false); + variable->setType(type); + variable->setDirty(false); }); }; @@ -85,23 +91,23 @@ void Variable::parseTypedDeclaration(Context &context, Variables ¶meters) context.parser.expect("("); context.parser.expect("either"); - parameter->m_eitherExpression = Either::parse(context, parameters, parseExistingPrimitiveType); + variable->m_eitherExpression = Either::parse(context, expressionContext, parseExistingPrimitiveType); context.parser.expect(")"); - setType(parameter->m_eitherExpression.get()); + setType(variable->m_eitherExpression.get()); return; } // Parse primitive type - const auto *type = PrimitiveType::parseExisting(context); + const auto *type = PrimitiveType::parseAndFindOrCreate(context, expressionContext.domain); setType(type); } //////////////////////////////////////////////////////////////////////////////////////////////////// -const Variable *Variable::parseExisting(Context &context, const Variables &variables) +const Variable *Variable::parseAndFind(Context &context, const ExpressionContext &expressionContext) { context.parser.skipWhiteSpace(); @@ -109,6 +115,8 @@ const Variable *Variable::parseExisting(Context &context, const Variables &varia const auto variableName = context.parser.parseIdentifier(isIdentifier); + const auto &variables = expressionContext.parameters; + const auto match = std::find_if(variables.cbegin(), variables.cend(), [&](const auto &variable) { @@ -116,7 +124,7 @@ const Variable *Variable::parseExisting(Context &context, const Variables &varia }); if (match == variables.cend()) - throw utils::ParserException(context.parser, "Variable \"" + variableName + "\" used but never declared"); + throw utils::ParserException(context.parser, "Parameter \"" + variableName + "\" used but never declared"); return match->get(); }