diff --git a/include/plasp/pddl/Action.h b/include/plasp/pddl/Action.h index 4b618d9..d0b1b94 100644 --- a/include/plasp/pddl/Action.h +++ b/include/plasp/pddl/Action.h @@ -4,7 +4,7 @@ #include #include -#include +#include #include namespace plasp @@ -26,7 +26,7 @@ class Action public: const std::string &name() const; - const Variables ¶meters() const; + const expressions::VariableExpressions ¶meters() const; const Expression &precondition() const; const Expression &effect() const; @@ -35,7 +35,7 @@ class Action std::string m_name; - Variables m_parameters; + expressions::VariableExpressions m_parameters; std::unique_ptr m_precondition; std::unique_ptr m_effect; }; diff --git a/include/plasp/pddl/Expression.h b/include/plasp/pddl/Expression.h index 0627c9d..1d054a7 100644 --- a/include/plasp/pddl/Expression.h +++ b/include/plasp/pddl/Expression.h @@ -22,6 +22,29 @@ namespace pddl class Context; class ExpressionVisitor; +class Expression; +using ExpressionPointer = std::unique_ptr; +using Expressions = std::vector; + +namespace expressions +{ +class AndExpression; +using AndExpressionPointer = std::unique_ptr; + +class NotExpression; +using NotExpressionPointer = std::unique_ptr; + +class OrExpression; +using OrExpressionPointer = std::unique_ptr; + +class PredicateExpression; +using PredicateExpressionPointer = std::unique_ptr; + +class VariableExpression; +using VariableExpressionPointer = std::unique_ptr; +using VariableExpressions = std::vector; +} + //////////////////////////////////////////////////////////////////////////////////////////////////// class Expression @@ -32,10 +55,13 @@ class Expression //////////////////////////////////////////////////////////////////////////////////////////////////// -std::unique_ptr parsePreconditionExpression(utils::Parser &parser, Context &context, const Variables ¶meters); -std::unique_ptr parseExpression(utils::Parser &parser, Context &context, const Variables ¶meters); +ExpressionPointer parsePreconditionExpression(utils::Parser &parser, Context &context, + const expressions::VariableExpressions ¶meters); +ExpressionPointer parseExpression(utils::Parser &parser, Context &context, + const expressions::VariableExpressions ¶meters); -std::unique_ptr parseEffectExpression(utils::Parser &parser, Context &context, const Variables ¶meters); +ExpressionPointer parseEffectExpression(utils::Parser &parser, Context &context, + const expressions::VariableExpressions ¶meters); //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/expressions/AndExpression.h b/include/plasp/pddl/expressions/AndExpression.h index c09f25e..2ce7ce6 100644 --- a/include/plasp/pddl/expressions/AndExpression.h +++ b/include/plasp/pddl/expressions/AndExpression.h @@ -20,7 +20,8 @@ class AndExpression: public NAryExpression { public: template - static std::unique_ptr parse(utils::Parser &parser, Context &context, const Variables ¶meters, ExpressionParser parseExpression); + static AndExpressionPointer parse(utils::Parser &parser, Context &context, + const VariableExpressions ¶meters, ExpressionParser parseExpression); public: void accept(ExpressionVisitor &expressionVisitor) const override; @@ -32,7 +33,8 @@ class AndExpression: public NAryExpression //////////////////////////////////////////////////////////////////////////////////////////////////// template -std::unique_ptr AndExpression::parse(utils::Parser &parser, Context &context, const Variables ¶meters, ExpressionParser parseExpression) +AndExpressionPointer AndExpression::parse(utils::Parser &parser, Context &context, + const VariableExpressions ¶meters, ExpressionParser parseExpression) { auto expression = std::make_unique(AndExpression()); diff --git a/include/plasp/pddl/expressions/NAryExpression.h b/include/plasp/pddl/expressions/NAryExpression.h index 5574745..4008ba4 100644 --- a/include/plasp/pddl/expressions/NAryExpression.h +++ b/include/plasp/pddl/expressions/NAryExpression.h @@ -7,6 +7,7 @@ #include #include +#include #include namespace plasp @@ -25,20 +26,22 @@ namespace expressions class NAryExpression: public Expression { public: - const std::vector> &arguments() const; + const Expressions &arguments() const; protected: template - void parse(utils::Parser &parser, Context &context, const Variables ¶meters, ExpressionParser parseExpression); + void parse(utils::Parser &parser, Context &context, const VariableExpressions ¶meters, + ExpressionParser parseExpression); private: - std::vector> m_arguments; + Expressions m_arguments; }; //////////////////////////////////////////////////////////////////////////////////////////////////// template -void NAryExpression::parse(utils::Parser &parser, Context &context, const Variables ¶meters, ExpressionParser parseExpression) +void NAryExpression::parse(utils::Parser &parser, Context &context, + const VariableExpressions ¶meters, ExpressionParser parseExpression) { parser.skipWhiteSpace(); diff --git a/include/plasp/pddl/expressions/NotExpression.h b/include/plasp/pddl/expressions/NotExpression.h index b2a8f84..982b1d8 100644 --- a/include/plasp/pddl/expressions/NotExpression.h +++ b/include/plasp/pddl/expressions/NotExpression.h @@ -21,7 +21,8 @@ class NotExpression: public Expression { public: template - static std::unique_ptr parse(utils::Parser &parser, Context &context, const Variables ¶meters, ExpressionParser parseExpression); + static NotExpressionPointer parse(utils::Parser &parser, Context &context, + const VariableExpressions ¶meters, ExpressionParser parseExpression); public: void accept(ExpressionVisitor &expressionVisitor) const override; @@ -31,13 +32,14 @@ class NotExpression: public Expression private: NotExpression() = default; - std::unique_ptr m_argument; + ExpressionPointer m_argument; }; //////////////////////////////////////////////////////////////////////////////////////////////////// template -std::unique_ptr NotExpression::parse(utils::Parser &parser, Context &context, const Variables ¶meters, ExpressionParser parseExpression) +NotExpressionPointer NotExpression::parse(utils::Parser &parser, Context &context, + const VariableExpressions ¶meters, ExpressionParser parseExpression) { auto expression = std::make_unique(NotExpression()); diff --git a/include/plasp/pddl/expressions/OrExpression.h b/include/plasp/pddl/expressions/OrExpression.h index d234099..50f34ed 100644 --- a/include/plasp/pddl/expressions/OrExpression.h +++ b/include/plasp/pddl/expressions/OrExpression.h @@ -20,7 +20,8 @@ class OrExpression: public NAryExpression { public: template - static std::unique_ptr parse(utils::Parser &parser, Context &context, const Variables ¶meters, ExpressionParser parseExpression); + static OrExpressionPointer parse(utils::Parser &parser, Context &context, + const VariableExpressions ¶meters, ExpressionParser parseExpression); public: void accept(ExpressionVisitor &expressionVisitor) const override; @@ -32,7 +33,8 @@ class OrExpression: public NAryExpression //////////////////////////////////////////////////////////////////////////////////////////////////// template -std::unique_ptr OrExpression::parse(utils::Parser &parser, Context &context, const Variables ¶meters, ExpressionParser parseExpression) +OrExpressionPointer OrExpression::parse(utils::Parser &parser, Context &context, + const VariableExpressions ¶meters, ExpressionParser parseExpression) { auto expression = std::make_unique(OrExpression()); diff --git a/include/plasp/pddl/expressions/PredicateExpression.h b/include/plasp/pddl/expressions/PredicateExpression.h index 219c6b5..2a30e1a 100644 --- a/include/plasp/pddl/expressions/PredicateExpression.h +++ b/include/plasp/pddl/expressions/PredicateExpression.h @@ -3,6 +3,7 @@ #include #include +#include namespace plasp { @@ -20,16 +21,19 @@ namespace expressions class PredicateExpression: public Expression { public: - static std::unique_ptr parse(std::string name, utils::Parser &parser, Context &context, const Variables ¶meters); + static PredicateExpressionPointer parse(std::string name, utils::Parser &parser, + Context &context, const VariableExpressions ¶meters); public: void accept(ExpressionVisitor &expressionVisitor) const override; + const std::vector &arguments() const; + private: PredicateExpression() = default; std::string m_name; - Variables m_arguments; + std::vector m_arguments; }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/expressions/VariableExpression.h b/include/plasp/pddl/expressions/VariableExpression.h new file mode 100644 index 0000000..a023036 --- /dev/null +++ b/include/plasp/pddl/expressions/VariableExpression.h @@ -0,0 +1,56 @@ +#ifndef __PLASP__PDDL__EXPRESSION__VARIABLE_EXPRESSION_H +#define __PLASP__PDDL__EXPRESSION__VARIABLE_EXPRESSION_H + +#include + +namespace plasp +{ +namespace pddl +{ +namespace expressions +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// VariableExpression +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class VariableExpression: public Expression +{ + public: + static VariableExpressionPointer parseDeclaration(utils::Parser &parser); + static void parseTypedDeclaration(utils::Parser &parser, Context &context, + VariableExpressions &variableExpressions); + + static const VariableExpression *parse(utils::Parser &parser, + const VariableExpressions &variableExpressions); + + public: + void accept(ExpressionVisitor &expressionVisitor) const override; + + const std::string &name() const; + TypePtr type() const; + + void setDirty(bool isDirty = true); + bool isDirty() const; + + void setType(TypePtr type); + + private: + VariableExpression(); + + bool m_isDirty; + + std::string m_name; + + TypePtr m_type; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} +} + +#endif diff --git a/src/plasp/pddl/Action.cpp b/src/plasp/pddl/Action.cpp index f58c163..a7e6e87 100644 --- a/src/plasp/pddl/Action.cpp +++ b/src/plasp/pddl/Action.cpp @@ -37,7 +37,7 @@ Action &Action::parseDeclaration(utils::Parser &parser, Context &context) // Read parameters while (parser.currentCharacter() != ')') { - Variable::parseTyped(parser, context, action->m_parameters); + expressions::VariableExpression::parseTypedDeclaration(parser, context, action->m_parameters); parser.skipWhiteSpace(); } @@ -74,7 +74,7 @@ const std::string &Action::name() const //////////////////////////////////////////////////////////////////////////////////////////////////// -const Variables &Action::parameters() const +const expressions::VariableExpressions &Action::parameters() const { return m_parameters; } diff --git a/src/plasp/pddl/Expression.cpp b/src/plasp/pddl/Expression.cpp index 44de3b5..85dd902 100644 --- a/src/plasp/pddl/Expression.cpp +++ b/src/plasp/pddl/Expression.cpp @@ -19,9 +19,12 @@ namespace pddl // //////////////////////////////////////////////////////////////////////////////////////////////////// -std::unique_ptr parseExpressionContent(const std::string &expressionIdentifier, utils::Parser &parser, Context &context, const Variables ¶meters); -std::unique_ptr parseEffectBodyExpressionContent(const std::string &expressionIdentifier, utils::Parser &parser, Context &context, const Variables ¶meters); -std::unique_ptr parsePredicateExpression(utils::Parser &parser, Context &context, const Variables ¶meters); +ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier, + utils::Parser &parser, Context &context, const expressions::VariableExpressions ¶meters); +ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier, + utils::Parser &parser, Context &context, const expressions::VariableExpressions ¶meters); +ExpressionPointer parsePredicateExpression(utils::Parser &parser, Context &context, + const expressions::VariableExpressions ¶meters); //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -32,16 +35,20 @@ void throwUnsupported(const utils::Parser &parser, const std::string &expression //////////////////////////////////////////////////////////////////////////////////////////////////// -std::unique_ptr parsePreconditionExpression(utils::Parser &parser, Context &context, const Variables ¶meters) +ExpressionPointer parsePreconditionExpression(utils::Parser &parser, Context &context, + const expressions::VariableExpressions ¶meters) { parser.expect("("); const auto expressionIdentifier = parser.parseIdentifier(isIdentifier); - std::unique_ptr expression; + ExpressionPointer expression; if (expressionIdentifier == "and") - expression = expressions::AndExpression::parse(parser, context, parameters, parsePreconditionExpression); + { + expression = expressions::AndExpression::parse(parser, context, parameters, + parsePreconditionExpression); + } else if (expressionIdentifier == "forall" || expressionIdentifier == "preference") { @@ -57,7 +64,8 @@ std::unique_ptr parsePreconditionExpression(utils::Parser &parser, C //////////////////////////////////////////////////////////////////////////////////////////////////// -std::unique_ptr parseExpression(utils::Parser &parser, Context &context, const Variables ¶meters) +ExpressionPointer parseExpression(utils::Parser &parser, Context &context, + const expressions::VariableExpressions ¶meters) { parser.expect("("); @@ -72,11 +80,12 @@ std::unique_ptr parseExpression(utils::Parser &parser, Context &cont //////////////////////////////////////////////////////////////////////////////////////////////////// -std::unique_ptr parseExpressionContent(const std::string &expressionIdentifier, utils::Parser &parser, Context &context, const Variables ¶meters) +ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier, + utils::Parser &parser, Context &context, const expressions::VariableExpressions ¶meters) { parser.skipWhiteSpace(); - std::unique_ptr expression; + ExpressionPointer expression; if (expressionIdentifier == "and") expression = expressions::AndExpression::parse(parser, context, parameters, parseExpression); @@ -122,13 +131,14 @@ std::unique_ptr parseExpressionContent(const std::string &expression //////////////////////////////////////////////////////////////////////////////////////////////////// -std::unique_ptr parseEffectExpression(utils::Parser &parser, Context &context, const Variables ¶meters) +ExpressionPointer parseEffectExpression(utils::Parser &parser, Context &context, + const expressions::VariableExpressions ¶meters) { parser.expect("("); const auto expressionIdentifier = parser.parseIdentifier(isIdentifier); - std::unique_ptr expression; + ExpressionPointer expression; if (expressionIdentifier == "and") expression = expressions::AndExpression::parse(parser, context, parameters, parseEffectExpression); @@ -147,9 +157,10 @@ std::unique_ptr parseEffectExpression(utils::Parser &parser, Context //////////////////////////////////////////////////////////////////////////////////////////////////// -std::unique_ptr parseEffectBodyExpressionContent(const std::string &expressionIdentifier, utils::Parser &parser, Context &context, const Variables ¶meters) +ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier, + utils::Parser &parser, Context &context, const expressions::VariableExpressions ¶meters) { - std::unique_ptr expression; + ExpressionPointer expression; if (expressionIdentifier == "not") expression = expressions::NotExpression::parse(parser, context, parameters, parsePredicateExpression); @@ -183,13 +194,14 @@ std::unique_ptr parseEffectBodyExpressionContent(const std::string & //////////////////////////////////////////////////////////////////////////////////////////////////// -std::unique_ptr parsePredicateExpression(utils::Parser &parser, Context &context, const Variables ¶meters) +ExpressionPointer parsePredicateExpression(utils::Parser &parser, Context &context, + const expressions::VariableExpressions ¶meters) { parser.expect("("); const auto predicateName = parser.parseIdentifier(isIdentifier); - std::unique_ptr expression; + ExpressionPointer expression; // Check if predicate with that name exists const auto match = std::find_if(context.predicates.cbegin(), context.predicates.cend(), diff --git a/src/plasp/pddl/expressions/PredicateExpression.cpp b/src/plasp/pddl/expressions/PredicateExpression.cpp index 88d3450..8a17e38 100644 --- a/src/plasp/pddl/expressions/PredicateExpression.cpp +++ b/src/plasp/pddl/expressions/PredicateExpression.cpp @@ -15,7 +15,8 @@ namespace expressions // //////////////////////////////////////////////////////////////////////////////////////////////////// -std::unique_ptr PredicateExpression::parse(std::string name, utils::Parser &parser, Context &context, const Variables ¶meters) +PredicateExpressionPointer PredicateExpression::parse(std::string name, utils::Parser &parser, + Context &context, const VariableExpressions ¶meters) { auto expression = std::make_unique(PredicateExpression()); @@ -25,7 +26,7 @@ std::unique_ptr PredicateExpression::parse(std::string name // Parse arguments while (parser.currentCharacter() != ')') - Variable::parseTyped(parser, context, expression->m_arguments); + expression->m_arguments.emplace_back(VariableExpression::parse(parser, parameters)); // TODO: check that signature matches one of the declared ones @@ -41,6 +42,13 @@ void PredicateExpression::accept(plasp::pddl::ExpressionVisitor &expressionVisit //////////////////////////////////////////////////////////////////////////////////////////////////// +const std::vector &PredicateExpression::arguments() const +{ + return m_arguments; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } } diff --git a/src/plasp/pddl/expressions/VariableExpression.cpp b/src/plasp/pddl/expressions/VariableExpression.cpp new file mode 100644 index 0000000..c578113 --- /dev/null +++ b/src/plasp/pddl/expressions/VariableExpression.cpp @@ -0,0 +1,142 @@ +#include + +#include + +#include +#include +#include +#include + +namespace plasp +{ +namespace pddl +{ +namespace expressions +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// VariableExpression +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +VariableExpression::VariableExpression() +: m_isDirty{false} +{ +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +VariableExpressionPointer VariableExpression::parseDeclaration(utils::Parser &parser) +{ + parser.skipWhiteSpace(); + + parser.expect("?"); + + auto variable = std::make_unique(VariableExpression()); + + variable->m_name = parser.parseIdentifier(isIdentifier); + variable->setDirty(); + + return variable; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void VariableExpression::parseTypedDeclaration(utils::Parser &parser, Context &context, + VariableExpressions &variableExpressions) +{ + // Parse and store variable itself + variableExpressions.emplace_back(parseDeclaration(parser)); + + parser.skipWhiteSpace(); + + // Check if the variable has a type declaration + if (!parser.advanceIf('-')) + return; + + // Parse argument type + const auto type = parseType(parser, context); + + // Set the argument type for all previously flagged arguments + std::for_each(variableExpressions.begin(), variableExpressions.end(), + [&](auto &variable) + { + if (!variable->isDirty()) + return; + + variable->setType(type); + variable->setDirty(false); + }); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +const VariableExpression *VariableExpression::parse(utils::Parser &parser, + const VariableExpressions &variableExpressions) +{ + parser.skipWhiteSpace(); + + parser.expect("?"); + + const auto variableName = parser.parseIdentifier(isIdentifier); + + const auto match = std::find_if(variableExpressions.cbegin(), variableExpressions.cend(), + [&](const auto &variableExpression) + { + return variableExpression->name() == variableName; + }); + + if (match == variableExpressions.cend()) + throw utils::ParserException(parser.row(), parser.column(), "Variable \"" + variableName + "\" used but never declared"); + + return match->get(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void VariableExpression::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const +{ + expressionVisitor.visit(*this); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +const std::string &VariableExpression::name() const +{ + return m_name; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +TypePtr VariableExpression::type() const +{ + return m_type; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void VariableExpression::setDirty(bool isDirty) +{ + m_isDirty = isDirty; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool VariableExpression::isDirty() const +{ + return m_isDirty; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void VariableExpression::setType(TypePtr type) +{ + m_type = type; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} +}