Started refactoring Variables as expressions.

This commit is contained in:
Patrick Lühne 2016-06-03 13:20:52 +02:00
parent 36e28994ee
commit d334b4150b
12 changed files with 295 additions and 38 deletions

View File

@ -4,7 +4,7 @@
#include <vector> #include <vector>
#include <plasp/pddl/Expression.h> #include <plasp/pddl/Expression.h>
#include <plasp/pddl/Variable.h> #include <plasp/pddl/expressions/VariableExpression.h>
#include <plasp/utils/Parser.h> #include <plasp/utils/Parser.h>
namespace plasp namespace plasp
@ -26,7 +26,7 @@ class Action
public: public:
const std::string &name() const; const std::string &name() const;
const Variables &parameters() const; const expressions::VariableExpressions &parameters() const;
const Expression &precondition() const; const Expression &precondition() const;
const Expression &effect() const; const Expression &effect() const;
@ -35,7 +35,7 @@ class Action
std::string m_name; std::string m_name;
Variables m_parameters; expressions::VariableExpressions m_parameters;
std::unique_ptr<Expression> m_precondition; std::unique_ptr<Expression> m_precondition;
std::unique_ptr<Expression> m_effect; std::unique_ptr<Expression> m_effect;
}; };

View File

@ -22,6 +22,29 @@ namespace pddl
class Context; class Context;
class ExpressionVisitor; class ExpressionVisitor;
class Expression;
using ExpressionPointer = std::unique_ptr<Expression>;
using Expressions = std::vector<ExpressionPointer>;
namespace expressions
{
class AndExpression;
using AndExpressionPointer = std::unique_ptr<AndExpression>;
class NotExpression;
using NotExpressionPointer = std::unique_ptr<NotExpression>;
class OrExpression;
using OrExpressionPointer = std::unique_ptr<OrExpression>;
class PredicateExpression;
using PredicateExpressionPointer = std::unique_ptr<PredicateExpression>;
class VariableExpression;
using VariableExpressionPointer = std::unique_ptr<VariableExpression>;
using VariableExpressions = std::vector<VariableExpressionPointer>;
}
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
class Expression class Expression
@ -32,10 +55,13 @@ class Expression
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<Expression> parsePreconditionExpression(utils::Parser &parser, Context &context, const Variables &parameters); ExpressionPointer parsePreconditionExpression(utils::Parser &parser, Context &context,
std::unique_ptr<Expression> parseExpression(utils::Parser &parser, Context &context, const Variables &parameters); const expressions::VariableExpressions &parameters);
ExpressionPointer parseExpression(utils::Parser &parser, Context &context,
const expressions::VariableExpressions &parameters);
std::unique_ptr<Expression> parseEffectExpression(utils::Parser &parser, Context &context, const Variables &parameters); ExpressionPointer parseEffectExpression(utils::Parser &parser, Context &context,
const expressions::VariableExpressions &parameters);
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -20,7 +20,8 @@ class AndExpression: public NAryExpression
{ {
public: public:
template<typename ExpressionParser> template<typename ExpressionParser>
static std::unique_ptr<AndExpression> parse(utils::Parser &parser, Context &context, const Variables &parameters, ExpressionParser parseExpression); static AndExpressionPointer parse(utils::Parser &parser, Context &context,
const VariableExpressions &parameters, ExpressionParser parseExpression);
public: public:
void accept(ExpressionVisitor &expressionVisitor) const override; void accept(ExpressionVisitor &expressionVisitor) const override;
@ -32,7 +33,8 @@ class AndExpression: public NAryExpression
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename ExpressionParser> template<typename ExpressionParser>
std::unique_ptr<AndExpression> AndExpression::parse(utils::Parser &parser, Context &context, const Variables &parameters, ExpressionParser parseExpression) AndExpressionPointer AndExpression::parse(utils::Parser &parser, Context &context,
const VariableExpressions &parameters, ExpressionParser parseExpression)
{ {
auto expression = std::make_unique<AndExpression>(AndExpression()); auto expression = std::make_unique<AndExpression>(AndExpression());

View File

@ -7,6 +7,7 @@
#include <plasp/pddl/ConsistencyException.h> #include <plasp/pddl/ConsistencyException.h>
#include <plasp/pddl/Expression.h> #include <plasp/pddl/Expression.h>
#include <plasp/pddl/expressions/VariableExpression.h>
#include <plasp/utils/Parser.h> #include <plasp/utils/Parser.h>
namespace plasp namespace plasp
@ -25,20 +26,22 @@ namespace expressions
class NAryExpression: public Expression class NAryExpression: public Expression
{ {
public: public:
const std::vector<std::unique_ptr<Expression>> &arguments() const; const Expressions &arguments() const;
protected: protected:
template<typename ExpressionParser> template<typename ExpressionParser>
void parse(utils::Parser &parser, Context &context, const Variables &parameters, ExpressionParser parseExpression); void parse(utils::Parser &parser, Context &context, const VariableExpressions &parameters,
ExpressionParser parseExpression);
private: private:
std::vector<std::unique_ptr<Expression>> m_arguments; Expressions m_arguments;
}; };
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename ExpressionParser> template<typename ExpressionParser>
void NAryExpression::parse(utils::Parser &parser, Context &context, const Variables &parameters, ExpressionParser parseExpression) void NAryExpression::parse(utils::Parser &parser, Context &context,
const VariableExpressions &parameters, ExpressionParser parseExpression)
{ {
parser.skipWhiteSpace(); parser.skipWhiteSpace();

View File

@ -21,7 +21,8 @@ class NotExpression: public Expression
{ {
public: public:
template<typename ExpressionParser> template<typename ExpressionParser>
static std::unique_ptr<NotExpression> parse(utils::Parser &parser, Context &context, const Variables &parameters, ExpressionParser parseExpression); static NotExpressionPointer parse(utils::Parser &parser, Context &context,
const VariableExpressions &parameters, ExpressionParser parseExpression);
public: public:
void accept(ExpressionVisitor &expressionVisitor) const override; void accept(ExpressionVisitor &expressionVisitor) const override;
@ -31,13 +32,14 @@ class NotExpression: public Expression
private: private:
NotExpression() = default; NotExpression() = default;
std::unique_ptr<Expression> m_argument; ExpressionPointer m_argument;
}; };
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename ExpressionParser> template<typename ExpressionParser>
std::unique_ptr<NotExpression> NotExpression::parse(utils::Parser &parser, Context &context, const Variables &parameters, ExpressionParser parseExpression) NotExpressionPointer NotExpression::parse(utils::Parser &parser, Context &context,
const VariableExpressions &parameters, ExpressionParser parseExpression)
{ {
auto expression = std::make_unique<NotExpression>(NotExpression()); auto expression = std::make_unique<NotExpression>(NotExpression());

View File

@ -20,7 +20,8 @@ class OrExpression: public NAryExpression
{ {
public: public:
template<typename ExpressionParser> template<typename ExpressionParser>
static std::unique_ptr<OrExpression> parse(utils::Parser &parser, Context &context, const Variables &parameters, ExpressionParser parseExpression); static OrExpressionPointer parse(utils::Parser &parser, Context &context,
const VariableExpressions &parameters, ExpressionParser parseExpression);
public: public:
void accept(ExpressionVisitor &expressionVisitor) const override; void accept(ExpressionVisitor &expressionVisitor) const override;
@ -32,7 +33,8 @@ class OrExpression: public NAryExpression
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename ExpressionParser> template<typename ExpressionParser>
std::unique_ptr<OrExpression> OrExpression::parse(utils::Parser &parser, Context &context, const Variables &parameters, ExpressionParser parseExpression) OrExpressionPointer OrExpression::parse(utils::Parser &parser, Context &context,
const VariableExpressions &parameters, ExpressionParser parseExpression)
{ {
auto expression = std::make_unique<OrExpression>(OrExpression()); auto expression = std::make_unique<OrExpression>(OrExpression());

View File

@ -3,6 +3,7 @@
#include <plasp/pddl/Expression.h> #include <plasp/pddl/Expression.h>
#include <plasp/pddl/Predicate.h> #include <plasp/pddl/Predicate.h>
#include <plasp/pddl/expressions/VariableExpression.h>
namespace plasp namespace plasp
{ {
@ -20,16 +21,19 @@ namespace expressions
class PredicateExpression: public Expression class PredicateExpression: public Expression
{ {
public: public:
static std::unique_ptr<PredicateExpression> parse(std::string name, utils::Parser &parser, Context &context, const Variables &parameters); static PredicateExpressionPointer parse(std::string name, utils::Parser &parser,
Context &context, const VariableExpressions &parameters);
public: public:
void accept(ExpressionVisitor &expressionVisitor) const override; void accept(ExpressionVisitor &expressionVisitor) const override;
const std::vector<const VariableExpression *> &arguments() const;
private: private:
PredicateExpression() = default; PredicateExpression() = default;
std::string m_name; std::string m_name;
Variables m_arguments; std::vector<const VariableExpression *> m_arguments;
}; };
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,56 @@
#ifndef __PLASP__PDDL__EXPRESSION__VARIABLE_EXPRESSION_H
#define __PLASP__PDDL__EXPRESSION__VARIABLE_EXPRESSION_H
#include <plasp/pddl/Expression.h>
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

View File

@ -37,7 +37,7 @@ Action &Action::parseDeclaration(utils::Parser &parser, Context &context)
// Read parameters // Read parameters
while (parser.currentCharacter() != ')') while (parser.currentCharacter() != ')')
{ {
Variable::parseTyped(parser, context, action->m_parameters); expressions::VariableExpression::parseTypedDeclaration(parser, context, action->m_parameters);
parser.skipWhiteSpace(); 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; return m_parameters;
} }

View File

@ -19,9 +19,12 @@ namespace pddl
// //
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<Expression> parseExpressionContent(const std::string &expressionIdentifier, utils::Parser &parser, Context &context, const Variables &parameters); ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier,
std::unique_ptr<Expression> parseEffectBodyExpressionContent(const std::string &expressionIdentifier, utils::Parser &parser, Context &context, const Variables &parameters); utils::Parser &parser, Context &context, const expressions::VariableExpressions &parameters);
std::unique_ptr<Expression> parsePredicateExpression(utils::Parser &parser, Context &context, const Variables &parameters); ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier,
utils::Parser &parser, Context &context, const expressions::VariableExpressions &parameters);
ExpressionPointer parsePredicateExpression(utils::Parser &parser, Context &context,
const expressions::VariableExpressions &parameters);
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
@ -32,16 +35,20 @@ void throwUnsupported(const utils::Parser &parser, const std::string &expression
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<Expression> parsePreconditionExpression(utils::Parser &parser, Context &context, const Variables &parameters) ExpressionPointer parsePreconditionExpression(utils::Parser &parser, Context &context,
const expressions::VariableExpressions &parameters)
{ {
parser.expect<std::string>("("); parser.expect<std::string>("(");
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier); const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
std::unique_ptr<Expression> expression; ExpressionPointer expression;
if (expressionIdentifier == "and") if (expressionIdentifier == "and")
expression = expressions::AndExpression::parse(parser, context, parameters, parsePreconditionExpression); {
expression = expressions::AndExpression::parse(parser, context, parameters,
parsePreconditionExpression);
}
else if (expressionIdentifier == "forall" else if (expressionIdentifier == "forall"
|| expressionIdentifier == "preference") || expressionIdentifier == "preference")
{ {
@ -57,7 +64,8 @@ std::unique_ptr<Expression> parsePreconditionExpression(utils::Parser &parser, C
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<Expression> parseExpression(utils::Parser &parser, Context &context, const Variables &parameters) ExpressionPointer parseExpression(utils::Parser &parser, Context &context,
const expressions::VariableExpressions &parameters)
{ {
parser.expect<std::string>("("); parser.expect<std::string>("(");
@ -72,11 +80,12 @@ std::unique_ptr<Expression> parseExpression(utils::Parser &parser, Context &cont
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<Expression> parseExpressionContent(const std::string &expressionIdentifier, utils::Parser &parser, Context &context, const Variables &parameters) ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier,
utils::Parser &parser, Context &context, const expressions::VariableExpressions &parameters)
{ {
parser.skipWhiteSpace(); parser.skipWhiteSpace();
std::unique_ptr<Expression> expression; ExpressionPointer expression;
if (expressionIdentifier == "and") if (expressionIdentifier == "and")
expression = expressions::AndExpression::parse(parser, context, parameters, parseExpression); expression = expressions::AndExpression::parse(parser, context, parameters, parseExpression);
@ -122,13 +131,14 @@ std::unique_ptr<Expression> parseExpressionContent(const std::string &expression
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<Expression> parseEffectExpression(utils::Parser &parser, Context &context, const Variables &parameters) ExpressionPointer parseEffectExpression(utils::Parser &parser, Context &context,
const expressions::VariableExpressions &parameters)
{ {
parser.expect<std::string>("("); parser.expect<std::string>("(");
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier); const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
std::unique_ptr<Expression> expression; ExpressionPointer expression;
if (expressionIdentifier == "and") if (expressionIdentifier == "and")
expression = expressions::AndExpression::parse(parser, context, parameters, parseEffectExpression); expression = expressions::AndExpression::parse(parser, context, parameters, parseEffectExpression);
@ -147,9 +157,10 @@ std::unique_ptr<Expression> parseEffectExpression(utils::Parser &parser, Context
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<Expression> parseEffectBodyExpressionContent(const std::string &expressionIdentifier, utils::Parser &parser, Context &context, const Variables &parameters) ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier,
utils::Parser &parser, Context &context, const expressions::VariableExpressions &parameters)
{ {
std::unique_ptr<Expression> expression; ExpressionPointer expression;
if (expressionIdentifier == "not") if (expressionIdentifier == "not")
expression = expressions::NotExpression::parse(parser, context, parameters, parsePredicateExpression); expression = expressions::NotExpression::parse(parser, context, parameters, parsePredicateExpression);
@ -183,13 +194,14 @@ std::unique_ptr<Expression> parseEffectBodyExpressionContent(const std::string &
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<Expression> parsePredicateExpression(utils::Parser &parser, Context &context, const Variables &parameters) ExpressionPointer parsePredicateExpression(utils::Parser &parser, Context &context,
const expressions::VariableExpressions &parameters)
{ {
parser.expect<std::string>("("); parser.expect<std::string>("(");
const auto predicateName = parser.parseIdentifier(isIdentifier); const auto predicateName = parser.parseIdentifier(isIdentifier);
std::unique_ptr<Expression> expression; ExpressionPointer expression;
// Check if predicate with that name exists // Check if predicate with that name exists
const auto match = std::find_if(context.predicates.cbegin(), context.predicates.cend(), const auto match = std::find_if(context.predicates.cbegin(), context.predicates.cend(),

View File

@ -15,7 +15,8 @@ namespace expressions
// //
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<PredicateExpression> PredicateExpression::parse(std::string name, utils::Parser &parser, Context &context, const Variables &parameters) PredicateExpressionPointer PredicateExpression::parse(std::string name, utils::Parser &parser,
Context &context, const VariableExpressions &parameters)
{ {
auto expression = std::make_unique<PredicateExpression>(PredicateExpression()); auto expression = std::make_unique<PredicateExpression>(PredicateExpression());
@ -25,7 +26,7 @@ std::unique_ptr<PredicateExpression> PredicateExpression::parse(std::string name
// Parse arguments // Parse arguments
while (parser.currentCharacter() != ')') 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 // TODO: check that signature matches one of the declared ones
@ -41,6 +42,13 @@ void PredicateExpression::accept(plasp::pddl::ExpressionVisitor &expressionVisit
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
const std::vector<const VariableExpression *> &PredicateExpression::arguments() const
{
return m_arguments;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
} }
} }
} }

View File

@ -0,0 +1,142 @@
#include <plasp/pddl/expressions/VariableExpression.h>
#include <algorithm>
#include <plasp/pddl/Context.h>
#include <plasp/pddl/ExpressionVisitor.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/utils/ParserException.h>
namespace plasp
{
namespace pddl
{
namespace expressions
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// VariableExpression
//
////////////////////////////////////////////////////////////////////////////////////////////////////
VariableExpression::VariableExpression()
: m_isDirty{false}
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
VariableExpressionPointer VariableExpression::parseDeclaration(utils::Parser &parser)
{
parser.skipWhiteSpace();
parser.expect<std::string>("?");
auto variable = std::make_unique<VariableExpression>(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<std::string>("?");
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;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
}