patrick
/
plasp
Archived
1
0
Fork 0

Refactoring to make parsing expressions consistent across PDDL domains and problems.

This commit is contained in:
Patrick Lühne 2016-06-07 13:26:19 +02:00
parent d5fa00a4a4
commit b612122180
32 changed files with 458 additions and 221 deletions

View File

@ -21,7 +21,7 @@ namespace pddl
class Action class Action
{ {
public: public:
static Action &parseDeclaration(Context &context); static void parseDeclaration(Context &context, Domain &domain);
public: public:
const std::string &name() const; const std::string &name() const;

View File

@ -5,11 +5,6 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include <plasp/pddl/Action.h>
#include <plasp/pddl/Expression.h>
#include <plasp/pddl/expressions/Constant.h>
#include <plasp/pddl/expressions/PredicateDeclaration.h>
#include <plasp/pddl/expressions/PrimitiveType.h>
#include <plasp/utils/Logger.h> #include <plasp/utils/Logger.h>
namespace plasp namespace plasp
@ -33,17 +28,6 @@ class Context
utils::Parser &parser; utils::Parser &parser;
utils::Logger logger; utils::Logger logger;
expressions::PrimitiveTypes primitiveTypes;
//std::unordered_map<std::string, expressions::PrimitiveType *> primitiveTypesHashMap;
expressions::Constants constants;
//std::unordered_map<std::string, expressions::Constant *> constantsHashMap;
expressions::PredicateDeclarations predicateDeclarations;
//std::unordered_map<expressions::PredicateHashMapKey, expressions::Predicate *> predicatesHashMap;
std::vector<std::unique_ptr<Action>> actions;
}; };
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -33,6 +33,8 @@ class Description
void parseContent(); void parseContent();
void parseSection(); void parseSection();
void checkConsistency();
utils::Parser m_parser; utils::Parser m_parser;
Context m_context; Context m_context;

View File

@ -1,8 +1,12 @@
#ifndef __PLASP__PDDL__DOMAIN_H #ifndef __PLASP__PDDL__DOMAIN_H
#define __PLASP__PDDL__DOMAIN_H #define __PLASP__PDDL__DOMAIN_H
#include <plasp/pddl/Action.h>
#include <plasp/pddl/Context.h> #include <plasp/pddl/Context.h>
#include <plasp/pddl/Expression.h> #include <plasp/pddl/Expression.h>
#include <plasp/pddl/expressions/Constant.h>
#include <plasp/pddl/expressions/PredicateDeclaration.h>
#include <plasp/pddl/expressions/PrimitiveType.h>
#include <plasp/pddl/Requirement.h> #include <plasp/pddl/Requirement.h>
namespace plasp namespace plasp
@ -19,19 +23,32 @@ namespace pddl
class Domain class Domain
{ {
public: 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<std::unique_ptr<Action>> &actions() const;
private:
Domain(Context &context); 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<std::unique_ptr<Action>> &actions();
const std::vector<std::unique_ptr<Action>> &actions() const;
void checkConsistency();
private:
void parseSection(); void parseSection();
void parseRequirementSection(); void parseRequirementSection();
@ -46,12 +63,15 @@ class Domain
void parseActionSection(); void parseActionSection();
void checkConsistency();
Context &m_context; Context &m_context;
bool m_isDeclared;
std::string m_name; std::string m_name;
Requirements m_requirements; Requirements m_requirements;
expressions::PrimitiveTypes m_primitiveTypes;
expressions::Constants m_constants;
expressions::PredicateDeclarations m_predicateDeclarations;
std::vector<std::unique_ptr<Action>> m_actions;
}; };
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -17,7 +17,10 @@ namespace pddl
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
class Context; class Context;
class Domain;
class ExpressionContext;
class ExpressionVisitor; class ExpressionVisitor;
class Problem;
class Expression; class Expression;
using ExpressionPointer = std::unique_ptr<Expression>; using ExpressionPointer = std::unique_ptr<Expression>;
@ -77,10 +80,11 @@ class Expression
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer parsePreconditionExpression(Context &context, ExpressionPointer parsePreconditionExpression(Context &context,
const expressions::Variables &parameters); ExpressionContext &expressionContext);
ExpressionPointer parseExpression(Context &context, const expressions::Variables &parameters); ExpressionPointer parseExpression(Context &context, ExpressionContext &expressionContext);
ExpressionPointer parseEffectExpression(Context &context, const expressions::Variables &parameters); ExpressionPointer parseEffectExpression(Context &context,
ExpressionContext &expressionContext);
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,46 @@
#ifndef __PLASP__PDDL__EXPRESSION_CONTEXT_H
#define __PLASP__PDDL__EXPRESSION_CONTEXT_H
#include <plasp/pddl/Expression.h>
#include <plasp/pddl/Requirement.h>
namespace plasp
{
namespace pddl
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// ExpressionContext
//
////////////////////////////////////////////////////////////////////////////////////////////////////
class ExpressionContext
{
public:
ExpressionContext(Domain &domain, expressions::Variables &parameters)
: domain(domain),
problem(nullptr),
parameters(parameters)
{
}
ExpressionContext(Domain &domain, Problem *problem, expressions::Variables &parameters)
: domain(domain),
problem{problem},
parameters(parameters)
{
}
Domain &domain;
Problem *problem;
expressions::Variables &parameters;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@ -19,15 +19,25 @@ namespace pddl
class Problem class Problem
{ {
public: 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 std::string &name() const;
const Requirements &requirements() const; const Requirements &requirements() const;
private: expressions::Constants &objects();
Problem(Context &context); const expressions::Constants &objects() const;
void checkConsistency();
private:
void parseSection(); void parseSection();
void parseRequirementSection(); void parseRequirementSection();
@ -36,9 +46,9 @@ class Problem
void parseObjectSection(); void parseObjectSection();
void checkConsistency();
Context &m_context; Context &m_context;
Domain &m_domain;
bool m_isDeclared;
std::string m_name; std::string m_name;
Requirements m_requirements; Requirements m_requirements;

View File

@ -20,7 +20,7 @@ class And: public NAry
{ {
public: public:
template<typename ExpressionParser> template<typename ExpressionParser>
static AndPointer parse(Context &context, const Variables &parameters, static AndPointer parse(Context &context, ExpressionContext &expressionContext,
ExpressionParser parseExpression); ExpressionParser parseExpression);
public: public:
@ -33,12 +33,12 @@ class And: public NAry
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename ExpressionParser> template<typename ExpressionParser>
AndPointer And::parse(Context &context, const Variables &parameters, AndPointer And::parse(Context &context, ExpressionContext &expressionContext,
ExpressionParser parseExpression) ExpressionParser parseExpression)
{ {
auto expression = std::make_unique<And>(And()); auto expression = std::make_unique<And>(And());
expression->NAry::parse(context, parameters, parseExpression); expression->NAry::parse(context, expressionContext, parseExpression);
if (expression->arguments().empty()) if (expression->arguments().empty())
throw ConsistencyException("\"and\" expressions should not be empty"); throw ConsistencyException("\"and\" expressions should not be empty");

View File

@ -27,7 +27,8 @@ class Binary: public Expression
protected: protected:
template<typename ExpressionParser> template<typename ExpressionParser>
void parse(Context &context, const Variables &parameters, ExpressionParser parseExpression); void parse(Context &context, ExpressionContext &expressionContext,
ExpressionParser parseExpression);
private: private:
ExpressionPointer m_leftArgument; ExpressionPointer m_leftArgument;
@ -37,12 +38,13 @@ class Binary: public Expression
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename ExpressionParser> template<typename ExpressionParser>
void Binary::parse(Context &context, const Variables &parameters, ExpressionParser parseExpression) void Binary::parse(Context &context, ExpressionContext &expressionContext,
ExpressionParser parseExpression)
{ {
// Assume that expression identifier (imply, exists, etc.) is already parsed // Assume that expression identifier (imply, exists, etc.) is already parsed
// Parse arguments of the expression // Parse arguments of the expression
m_leftArgument = parseExpression(context, parameters); m_leftArgument = parseExpression(context, expressionContext);
m_rightArgument = parseExpression(context, parameters); m_rightArgument = parseExpression(context, expressionContext);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -22,10 +22,10 @@ namespace expressions
class Constant: public Expression class Constant: public Expression
{ {
public: public:
static ConstantPointer parseDeclaration(Context &context); static void parseTypedDeclaration(Context &context, Domain &domain);
static void parseTypedDeclaration(Context &context, Constants &constants); 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 // TODO: method for lazy creation if not existing
@ -38,6 +38,11 @@ class Constant: public Expression
bool isDeclared() const; bool isDeclared() const;
private: 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(); Constant();
void setDirty(bool isDirty = true); void setDirty(bool isDirty = true);

View File

@ -20,7 +20,7 @@ class Either: public NAry
{ {
public: public:
template<typename ExpressionParser> template<typename ExpressionParser>
static EitherPointer parse(Context &context, const Variables &parameters, static EitherPointer parse(Context &context, ExpressionContext &expressionContext,
ExpressionParser parseExpression); ExpressionParser parseExpression);
public: public:
@ -33,12 +33,12 @@ class Either: public NAry
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename ExpressionParser> template<typename ExpressionParser>
EitherPointer Either::parse(Context &context, const Variables &parameters, EitherPointer Either::parse(Context &context, ExpressionContext &expressionContext,
ExpressionParser parseExpression) ExpressionParser parseExpression)
{ {
auto expression = std::make_unique<Either>(Either()); auto expression = std::make_unique<Either>(Either());
expression->NAry::parse(context, parameters, parseExpression); expression->NAry::parse(context, expressionContext, parseExpression);
if (expression->arguments().empty()) if (expression->arguments().empty())
throw ConsistencyException("\"and\" expressions should not be empty"); throw ConsistencyException("\"and\" expressions should not be empty");

View File

@ -20,7 +20,7 @@ class Imply: public Binary
{ {
public: public:
template<typename ExpressionParser> template<typename ExpressionParser>
static ImplyPointer parse(Context &context, const Variables &parameters, static ImplyPointer parse(Context &context, ExpressionContext &parameters,
ExpressionParser parseExpression); ExpressionParser parseExpression);
public: public:
@ -33,7 +33,7 @@ class Imply: public Binary
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename ExpressionParser> template<typename ExpressionParser>
ImplyPointer Imply::parse(Context &context, const Variables &parameters, ImplyPointer Imply::parse(Context &context, ExpressionContext &parameters,
ExpressionParser parseExpression) ExpressionParser parseExpression)
{ {
auto expression = std::make_unique<Imply>(Imply()); auto expression = std::make_unique<Imply>(Imply());

View File

@ -26,7 +26,7 @@ class NAry: public Expression
protected: protected:
template<typename ExpressionParser> template<typename ExpressionParser>
void parse(Context &context, const Variables &parameters, ExpressionParser parseExpression); void parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression);
private: private:
Expressions m_arguments; Expressions m_arguments;
@ -35,7 +35,7 @@ class NAry: public Expression
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename ExpressionParser> template<typename ExpressionParser>
void NAry::parse(Context &context, const Variables &parameters, ExpressionParser parseExpression) void NAry::parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression)
{ {
context.parser.skipWhiteSpace(); context.parser.skipWhiteSpace();
@ -43,7 +43,7 @@ void NAry::parse(Context &context, const Variables &parameters, ExpressionParser
// Parse arguments of the expression // Parse arguments of the expression
while (context.parser.currentCharacter() != ')') while (context.parser.currentCharacter() != ')')
{ {
m_arguments.emplace_back(parseExpression(context, parameters)); m_arguments.emplace_back(parseExpression(context, expressionContext));
context.parser.skipWhiteSpace(); context.parser.skipWhiteSpace();
} }

View File

@ -21,7 +21,7 @@ class Not: public Expression
{ {
public: public:
template<typename ExpressionParser> template<typename ExpressionParser>
static NotPointer parse(Context &context, const Variables &parameters, static NotPointer parse(Context &context, ExpressionContext &expressionContext,
ExpressionParser parseExpression); ExpressionParser parseExpression);
public: public:
@ -38,7 +38,7 @@ class Not: public Expression
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename ExpressionParser> template<typename ExpressionParser>
NotPointer Not::parse(Context &context, const Variables &parameters, NotPointer Not::parse(Context &context, ExpressionContext &expressionContext,
ExpressionParser parseExpression) ExpressionParser parseExpression)
{ {
auto expression = std::make_unique<Not>(Not()); auto expression = std::make_unique<Not>(Not());
@ -46,7 +46,7 @@ NotPointer Not::parse(Context &context, const Variables &parameters,
context.parser.skipWhiteSpace(); context.parser.skipWhiteSpace();
// Parse argument // Parse argument
expression->m_argument = parseExpression(context, parameters); expression->m_argument = parseExpression(context, expressionContext);
return expression; return expression;
} }

View File

@ -20,7 +20,7 @@ class Or: public NAry
{ {
public: public:
template<typename ExpressionParser> template<typename ExpressionParser>
static OrPointer parse(Context &context, const Variables &parameters, static OrPointer parse(Context &context, ExpressionContext &expressionContext,
ExpressionParser parseExpression); ExpressionParser parseExpression);
public: public:
@ -33,11 +33,12 @@ class Or: public NAry
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename ExpressionParser> template<typename ExpressionParser>
OrPointer Or::parse(Context &context, const Variables &parameters, ExpressionParser parseExpression) OrPointer Or::parse(Context &context, ExpressionContext &expressionContext,
ExpressionParser parseExpression)
{ {
auto expression = std::make_unique<Or>(Or()); auto expression = std::make_unique<Or>(Or());
expression->NAry::parse(context, parameters, parseExpression); expression->NAry::parse(context, expressionContext, parseExpression);
if (expression->arguments().empty()) if (expression->arguments().empty())
throw ConsistencyException("\"or\" expressions should not be empty"); throw ConsistencyException("\"or\" expressions should not be empty");

View File

@ -20,7 +20,7 @@ class Predicate: public Expression
{ {
public: public:
static PredicatePointer parse(std::string name, Context &context, static PredicatePointer parse(std::string name, Context &context,
const Variables &parameters); ExpressionContext &expressionContext);
public: public:
void accept(ExpressionVisitor &expressionVisitor) const override; void accept(ExpressionVisitor &expressionVisitor) const override;

View File

@ -19,7 +19,7 @@ namespace expressions
class PredicateDeclaration: public Expression class PredicateDeclaration: public Expression
{ {
public: public:
static void parse(Context &context); static void parse(Context &context, Domain &domain);
public: public:
void accept(ExpressionVisitor &expressionVisitor) const override; void accept(ExpressionVisitor &expressionVisitor) const override;
@ -37,7 +37,7 @@ class PredicateDeclaration: public Expression
bool m_isDeclared; bool m_isDeclared;
std::string m_name; std::string m_name;
Variables m_arguments; Variables m_parameters;
}; };
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -22,12 +22,15 @@ namespace expressions
class PrimitiveType: public Expression class PrimitiveType: public Expression
{ {
public: public:
static PrimitiveType *parseDeclaration(Context &context); static void parseDeclaration(Context &context, Domain &domain);
static void parseTypedDeclaration(Context &context); static void parseTypedDeclaration(Context &context, Domain &domain);
static PrimitiveType *parseExisting(Context &context); static PrimitiveType *parseAndFindOrCreate(Context &context, Domain &domain);
public: public:
PrimitiveType();
PrimitiveType(std::string name);
void accept(ExpressionVisitor &expressionVisitor) const override; void accept(ExpressionVisitor &expressionVisitor) const override;
const std::string &name() const; const std::string &name() const;
@ -36,11 +39,6 @@ class PrimitiveType: public Expression
bool isDeclared() const; bool isDeclared() const;
private: private:
static PrimitiveType *create(std::string name, Context &context);
private:
PrimitiveType();
void setDirty(bool isDirty = true); void setDirty(bool isDirty = true);
bool isDirty() const; bool isDirty() const;

View File

@ -16,7 +16,8 @@ namespace expressions
// //
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer parseExistingPrimitiveType(Context &context, const Variables &parameters); ExpressionPointer parseExistingPrimitiveType(Context &context,
ExpressionContext &expressionContext);
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -19,11 +19,9 @@ namespace expressions
class Variable: public Expression class Variable: public Expression
{ {
public: public:
static VariablePointer parseDeclaration(Context &context); static void parseTypedDeclaration(Context &context, ExpressionContext &expressionContext);
static void parseTypedDeclaration(Context &context, Variables &parameters); static const Variable *parseAndFind(Context &context, const ExpressionContext &expressionContext);
static const Variable *parseExisting(Context &context, const Variables &variables);
public: public:
void accept(ExpressionVisitor &expressionVisitor) const override; void accept(ExpressionVisitor &expressionVisitor) const override;
@ -36,6 +34,9 @@ class Variable: public Expression
void setType(const Expression *type); void setType(const Expression *type);
private:
static void parseDeclaration(Context &context, Variables &parameters);
private: private:
Variable(); Variable();

View File

@ -3,6 +3,8 @@
#include <algorithm> #include <algorithm>
#include <plasp/pddl/Context.h> #include <plasp/pddl/Context.h>
#include <plasp/pddl/Domain.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/Identifier.h> #include <plasp/pddl/Identifier.h>
#include <plasp/pddl/expressions/Type.h> #include <plasp/pddl/expressions/Type.h>
#include <plasp/utils/IO.h> #include <plasp/utils/IO.h>
@ -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); const auto actionName = context.parser.parseIdentifier(isIdentifier);
auto action = std::make_unique<Action>(Action(actionName)); auto action = std::make_unique<Action>(Action(actionName));
context.parser.expect<std::string>(":parameters"); context.parser.expect<std::string>(":parameters");
context.parser.expect<std::string>("("); context.parser.expect<std::string>("(");
ExpressionContext expressionContext(domain, action->m_parameters);
// Read parameters // Read parameters
while (context.parser.currentCharacter() != ')') while (context.parser.currentCharacter() != ')')
{ {
expressions::Variable::parseTypedDeclaration(context, action->m_parameters); expressions::Variable::parseTypedDeclaration(context, expressionContext);
context.parser.skipWhiteSpace(); context.parser.skipWhiteSpace();
} }
@ -54,17 +57,15 @@ Action &Action::parseDeclaration(Context &context)
const auto sectionIdentifier = context.parser.parseIdentifier(isIdentifier); const auto sectionIdentifier = context.parser.parseIdentifier(isIdentifier);
if (sectionIdentifier == "precondition") if (sectionIdentifier == "precondition")
action->m_precondition = parsePreconditionExpression(context, action->m_parameters); action->m_precondition = parsePreconditionExpression(context, expressionContext);
else if (sectionIdentifier == "effect") else if (sectionIdentifier == "effect")
action->m_effect = parseEffectExpression(context, action->m_parameters); action->m_effect = parseEffectExpression(context, expressionContext);
context.parser.skipWhiteSpace(); context.parser.skipWhiteSpace();
} }
// Store new action // Store new action
context.actions.emplace_back(std::move(action)); expressionContext.domain.actions().emplace_back(std::move(action));
return *context.actions.back();
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -31,6 +31,9 @@ Description Description::fromStream(std::istream &istream)
{ {
Description description(istream); Description description(istream);
description.m_domain = std::make_unique<Domain>(Domain(description.m_context));
description.m_problem = std::make_unique<Problem>(Problem(description.m_context, *description.m_domain));
while (true) while (true)
{ {
description.m_context.parser.skipWhiteSpace(); description.m_context.parser.skipWhiteSpace();
@ -41,6 +44,8 @@ Description Description::fromStream(std::istream &istream)
description.parseContent(); description.parseContent();
} }
description.checkConsistency();
return description; return description;
} }
@ -89,14 +94,36 @@ void Description::parseSection()
std::cout << "Parsing section " << sectionIdentifier << std::endl; std::cout << "Parsing section " << sectionIdentifier << std::endl;
if (sectionIdentifier == "domain") if (sectionIdentifier == "domain")
m_domain = std::make_unique<Domain>(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") else if (sectionIdentifier == "problem")
m_problem = std::make_unique<Problem>(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 else
throw utils::ParserException(m_context.parser, "Unknown PDDL section \"" + sectionIdentifier + "\""); throw utils::ParserException(m_context.parser, "Unknown PDDL section \"" + sectionIdentifier + "\"");
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
void Description::checkConsistency()
{
m_domain->checkConsistency();
m_problem->checkConsistency();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
} }
} }

View File

@ -23,37 +23,41 @@ namespace pddl
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Domain::Domain(Context &context) 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; m_context.parser.expect<std::string>(")");
context.parser.expect<std::string>(")");
while (true) while (true)
{ {
context.parser.skipWhiteSpace(); m_context.parser.skipWhiteSpace();
if (context.parser.currentCharacter() == ')') if (m_context.parser.currentCharacter() == ')')
break; 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 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 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 const expressions::PredicateDeclarations &Domain::predicates() const
{ {
return m_context.predicateDeclarations; return m_predicateDeclarations;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
std::vector<std::unique_ptr<Action>> &Domain::actions()
{
return m_actions;
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
const std::vector<std::unique_ptr<Action>> &Domain::actions() const const std::vector<std::unique_ptr<Action>> &Domain::actions() const
{ {
return m_context.actions; return m_actions;
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
@ -242,7 +274,7 @@ void Domain::parseTypeSection()
if (m_context.parser.currentCharacter() == '(') if (m_context.parser.currentCharacter() == '(')
throw utils::ParserException(m_context.parser, "Only primitive types are allowed in type section"); 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(); m_context.parser.skipWhiteSpace();
} }
@ -259,7 +291,7 @@ void Domain::parseConstantSection()
// Store constants // Store constants
while (m_context.parser.currentCharacter() != ')') while (m_context.parser.currentCharacter() != ')')
{ {
expressions::Constant::parseTypedDeclaration(m_context, m_context.constants); expressions::Constant::parseTypedDeclaration(m_context, *this);
m_context.parser.skipWhiteSpace(); m_context.parser.skipWhiteSpace();
} }
@ -276,7 +308,7 @@ void Domain::parsePredicateSection()
// Store predicates and their arguments // Store predicates and their arguments
while (m_context.parser.currentCharacter() != ')') while (m_context.parser.currentCharacter() != ')')
{ {
expressions::PredicateDeclaration::parse(m_context); expressions::PredicateDeclaration::parse(m_context, *this);
m_context.parser.skipWhiteSpace(); m_context.parser.skipWhiteSpace();
} }
@ -290,7 +322,7 @@ void Domain::parseActionSection()
{ {
m_context.parser.skipWhiteSpace(); m_context.parser.skipWhiteSpace();
Action::parseDeclaration(m_context); Action::parseDeclaration(m_context, *this);
m_context.parser.expect<std::string>(")"); m_context.parser.expect<std::string>(")");
} }
@ -300,7 +332,7 @@ void Domain::parseActionSection()
void Domain::checkConsistency() void Domain::checkConsistency()
{ {
// Verify that typing requirement is correctly declared if used // 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"); 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 // 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) [&](const auto &type)
{ {
if (!type->isDeclared()) if (!type->isDeclared())
@ -316,7 +348,7 @@ void Domain::checkConsistency()
}); });
// Verify that all used constants have been declared // 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) [&](const auto &constant)
{ {
if (!constant->isDeclared()) if (!constant->isDeclared())
@ -327,7 +359,7 @@ void Domain::checkConsistency()
}); });
// Verify that all used predicates have been declared // 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) [&](const auto &predicate)
{ {
if (!predicate->isDeclared()) if (!predicate->isDeclared())

View File

@ -1,6 +1,8 @@
#include <plasp/pddl/Expression.h> #include <plasp/pddl/Expression.h>
#include <plasp/pddl/Context.h> #include <plasp/pddl/Context.h>
#include <plasp/pddl/Domain.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/Identifier.h> #include <plasp/pddl/Identifier.h>
#include <plasp/pddl/expressions/And.h> #include <plasp/pddl/expressions/And.h>
#include <plasp/pddl/expressions/Imply.h> #include <plasp/pddl/expressions/Imply.h>
@ -23,15 +25,16 @@ namespace pddl
// //
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier, ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier, Context &context,
Context &context, const expressions::Variables &parameters); ExpressionContext &expressionContext);
ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier, ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier,
Context &context, const expressions::Variables &parameters); Context &context, ExpressionContext &expressionContext);
ExpressionPointer parsePredicate(Context &context, const expressions::Variables &parameters); 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"); 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, ExpressionPointer parsePreconditionExpression(Context &context,
const expressions::Variables &parameters) ExpressionContext &expressionContext)
{ {
context.parser.expect<std::string>("("); context.parser.expect<std::string>("(");
@ -49,7 +52,7 @@ ExpressionPointer parsePreconditionExpression(Context &context,
if (expressionIdentifier == "and") if (expressionIdentifier == "and")
{ {
expression = expressions::And::parse(context, parameters, expression = expressions::And::parse(context, expressionContext,
parsePreconditionExpression); parsePreconditionExpression);
} }
else if (expressionIdentifier == "forall" else if (expressionIdentifier == "forall"
@ -58,7 +61,7 @@ ExpressionPointer parsePreconditionExpression(Context &context,
throwUnsupported(context.parser, expressionIdentifier); throwUnsupported(context.parser, expressionIdentifier);
} }
else else
expression = parseExpressionContent(expressionIdentifier, context, parameters); expression = parseExpressionContent(expressionIdentifier, context, expressionContext);
context.parser.expect<std::string>(")"); context.parser.expect<std::string>(")");
@ -67,13 +70,13 @@ ExpressionPointer parsePreconditionExpression(Context &context,
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer parseExpression(Context &context, const expressions::Variables &parameters) ExpressionPointer parseExpression(Context &context, ExpressionContext &expressionContext)
{ {
context.parser.expect<std::string>("("); context.parser.expect<std::string>("(");
const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier); const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier);
auto expression = parseExpressionContent(expressionIdentifier, context, parameters); auto expression = parseExpressionContent(expressionIdentifier, context, expressionContext);
context.parser.expect<std::string>(")"); context.parser.expect<std::string>(")");
@ -82,22 +85,22 @@ ExpressionPointer parseExpression(Context &context, const expressions::Variables
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier, ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier, Context &context,
Context &context, const expressions::Variables &parameters) ExpressionContext &expressionContext)
{ {
context.parser.skipWhiteSpace(); context.parser.skipWhiteSpace();
if (expressionIdentifier == "and") if (expressionIdentifier == "and")
return expressions::And::parse(context, parameters, parseExpression); return expressions::And::parse(context, expressionContext, parseExpression);
if (expressionIdentifier == "or") if (expressionIdentifier == "or")
return expressions::Or::parse(context, parameters, parseExpression); return expressions::Or::parse(context, expressionContext, parseExpression);
if (expressionIdentifier == "not") if (expressionIdentifier == "not")
return expressions::Not::parse(context, parameters, parseExpression); return expressions::Not::parse(context, expressionContext, parseExpression);
if (expressionIdentifier == "imply") if (expressionIdentifier == "imply")
return expressions::Imply::parse(context, parameters, parseExpression); return expressions::Imply::parse(context, expressionContext, parseExpression);
if (expressionIdentifier == "exists" if (expressionIdentifier == "exists"
|| expressionIdentifier == "forall" || expressionIdentifier == "forall"
@ -116,23 +119,25 @@ ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier
throwUnsupported(context.parser, expressionIdentifier); throwUnsupported(context.parser, expressionIdentifier);
} }
auto &predicateDeclarations = expressionContext.domain.predicates();
// Check if predicate with that name exists // 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) [&](const auto &predicate)
{ {
return predicate->name() == expressionIdentifier; return predicate->name() == expressionIdentifier;
}); });
// If predicate exists, parse it // If predicate exists, parse it
if (match != context.predicateDeclarations.cend()) if (match != predicateDeclarations.cend())
return expressions::Predicate::parse(expressionIdentifier, context, parameters); return expressions::Predicate::parse(expressionIdentifier, context, expressionContext);
throw utils::ParserException(context.parser, "Expression \"" + expressionIdentifier + "\" not allowed in this context"); throw utils::ParserException(context.parser, "Expression \"" + expressionIdentifier + "\" not allowed in this context");
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer parseEffectExpression(Context &context, const expressions::Variables &parameters) ExpressionPointer parseEffectExpression(Context &context, ExpressionContext &expressionContext)
{ {
context.parser.expect<std::string>("("); context.parser.expect<std::string>("(");
@ -141,14 +146,14 @@ ExpressionPointer parseEffectExpression(Context &context, const expressions::Var
ExpressionPointer expression; ExpressionPointer expression;
if (expressionIdentifier == "and") if (expressionIdentifier == "and")
expression = expressions::And::parse(context, parameters, parseEffectExpression); expression = expressions::And::parse(context, expressionContext, parseEffectExpression);
else if (expressionIdentifier == "forall" else if (expressionIdentifier == "forall"
|| expressionIdentifier == "when") || expressionIdentifier == "when")
{ {
throwUnsupported(context.parser, expressionIdentifier); throwUnsupported(context.parser, expressionIdentifier);
} }
else else
expression = parseEffectBodyExpressionContent(expressionIdentifier, context, parameters); expression = parseEffectBodyExpressionContent(expressionIdentifier, context, expressionContext);
context.parser.expect<std::string>(")"); context.parser.expect<std::string>(")");
@ -158,12 +163,12 @@ ExpressionPointer parseEffectExpression(Context &context, const expressions::Var
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier, ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier,
Context &context, const expressions::Variables &parameters) Context &context, ExpressionContext &expressionContext)
{ {
ExpressionPointer expression; ExpressionPointer expression;
if (expressionIdentifier == "not") if (expressionIdentifier == "not")
return expressions::Not::parse(context, parameters, parsePredicate); return expressions::Not::parse(context, expressionContext, parsePredicate);
if (expressionIdentifier == "=" if (expressionIdentifier == "="
|| expressionIdentifier == "assign" || expressionIdentifier == "assign"
@ -175,23 +180,25 @@ ExpressionPointer parseEffectBodyExpressionContent(const std::string &expression
throwUnsupported(context.parser, expressionIdentifier); throwUnsupported(context.parser, expressionIdentifier);
} }
const auto &predicateDeclarations = expressionContext.domain.predicates();
// Check if predicate with that name exists // 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) [&](const auto &predicate)
{ {
return predicate->name() == expressionIdentifier; return predicate->name() == expressionIdentifier;
}); });
// If predicate exists, parse it // If predicate exists, parse it
if (match != context.predicateDeclarations.cend()) if (match != predicateDeclarations.cend())
return expressions::Predicate::parse(expressionIdentifier, context, parameters); return expressions::Predicate::parse(expressionIdentifier, context, expressionContext);
throw utils::ParserException(context.parser, "Expression \"" + expressionIdentifier + "\" not allowed in this context"); throw utils::ParserException(context.parser, "Expression \"" + expressionIdentifier + "\" not allowed in this context");
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer parsePredicate(Context &context, const expressions::Variables &parameters) ExpressionPointer parsePredicate(Context &context, ExpressionContext &expressionContext)
{ {
context.parser.expect<std::string>("("); context.parser.expect<std::string>("(");
@ -199,18 +206,20 @@ ExpressionPointer parsePredicate(Context &context, const expressions::Variables
ExpressionPointer expression; ExpressionPointer expression;
const auto &predicateDeclarations = expressionContext.domain.predicates();
// Check if predicate with that name exists // 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) [&](const auto &predicate)
{ {
return predicate->name() == predicateName; return predicate->name() == predicateName;
}); });
// If predicate exists, parse it // If predicate exists, parse it
if (match == context.predicateDeclarations.cend()) if (match == predicateDeclarations.cend())
throw utils::ParserException(context.parser, "Unknown predicate \"" + predicateName + "\""); 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<std::string>(")"); context.parser.expect<std::string>(")");

View File

@ -3,7 +3,9 @@
#include <algorithm> #include <algorithm>
#include <plasp/pddl/Identifier.h> #include <plasp/pddl/Identifier.h>
#include <plasp/pddl/expressions/Constant.h>
#include <plasp/utils/IO.h> #include <plasp/utils/IO.h>
#include <plasp/utils/ParserException.h>
namespace plasp namespace plasp
{ {
@ -16,38 +18,57 @@ namespace pddl
// //
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Problem::Problem(Context &context) Problem::Problem(Context &context, Domain &domain)
: m_context(context) : 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; m_context.parser.expect<std::string>(")");
context.parser.expect<std::string>(")");
while (true) while (true)
{ {
context.parser.skipWhiteSpace(); m_context.parser.skipWhiteSpace();
if (context.parser.currentCharacter() == ')') if (m_context.parser.currentCharacter() == ')')
break; 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() void Problem::parseSection()
{ {
m_context.parser.expect<std::string>("("); m_context.parser.expect<std::string>("(");
@ -203,7 +238,7 @@ void Problem::parseObjectSection()
// Store constants // Store constants
while (m_context.parser.currentCharacter() != ')') while (m_context.parser.currentCharacter() != ')')
{ {
expressions::Constant::parseTypedDeclaration(m_context); //expressions::Constant::parseTypedDeclaration(m_context);
m_context.parser.skipWhiteSpace(); m_context.parser.skipWhiteSpace();
} }

View File

@ -5,7 +5,10 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <plasp/pddl/Context.h> #include <plasp/pddl/Context.h>
#include <plasp/pddl/Domain.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/ExpressionVisitor.h> #include <plasp/pddl/ExpressionVisitor.h>
#include <plasp/pddl/Problem.h>
#include <plasp/pddl/expressions/PrimitiveType.h> #include <plasp/pddl/expressions/PrimitiveType.h>
namespace plasp 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 // Parse and store constant
constants.emplace_back(parseDeclaration(context)); constants.emplace_back(parseDeclaration(context));
@ -67,7 +84,7 @@ void Constant::parseTypedDeclaration(Context &context, Constants &constants)
return; return;
// If existing, parse and store parent type // 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 // Assign parent type to all types that were previously flagged
std::for_each(constants.begin(), constants.end(), 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(); context.parser.skipWhiteSpace();
const auto constantName = context.parser.parseIdentifier(isIdentifier); 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 // 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) [&](const auto &constant)
{ {
return constant->name() == constantName; return constant->name() == constantName;
}); });
const auto constantExists = (match != context.constants.cend()); const auto constantExists = (match != constants.cend());
if (!constantExists) if (!constantExists)
throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared"); return nullptr;
return match->get(); return match->get();
} }

View File

@ -1,8 +1,10 @@
#include <plasp/pddl/expressions/Type.h> #include <plasp/pddl/expressions/Type.h>
#include <plasp/pddl/Context.h> #include <plasp/pddl/Context.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/expressions/Predicate.h> #include <plasp/pddl/expressions/Predicate.h>
#include <plasp/utils/IO.h> #include <plasp/utils/IO.h>
#include <plasp/utils/ParserException.h>
namespace plasp namespace plasp
{ {

View File

@ -1,6 +1,8 @@
#include <plasp/pddl/expressions/Predicate.h> #include <plasp/pddl/expressions/Predicate.h>
#include <plasp/pddl/Context.h> #include <plasp/pddl/Context.h>
#include <plasp/pddl/Domain.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/ExpressionVisitor.h> #include <plasp/pddl/ExpressionVisitor.h>
#include <plasp/pddl/Identifier.h> #include <plasp/pddl/Identifier.h>
#include <plasp/pddl/expressions/Constant.h> #include <plasp/pddl/expressions/Constant.h>
@ -27,7 +29,8 @@ Predicate::Predicate()
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
PredicatePointer Predicate::parse(std::string name, Context &context, const Variables &parameters) PredicatePointer Predicate::parse(std::string name, Context &context,
ExpressionContext &expressionContext)
{ {
auto predicate = std::make_unique<Predicate>(Predicate()); auto predicate = std::make_unique<Predicate>(Predicate());
@ -41,14 +44,14 @@ PredicatePointer Predicate::parse(std::string name, Context &context, const Vari
// Parse variables // Parse variables
if (context.parser.currentCharacter() == '?') if (context.parser.currentCharacter() == '?')
{ {
const auto *variable = Variable::parseExisting(context, parameters); const auto *variable = Variable::parseAndFind(context, expressionContext);
auto variableReference = std::make_unique<Reference<Variable>>(variable); auto variableReference = std::make_unique<Reference<Variable>>(variable);
predicate->m_arguments.emplace_back(std::move(variableReference)); predicate->m_arguments.emplace_back(std::move(variableReference));
} }
// Parse constants // Parse constants
else else
{ {
const auto *constant = Constant::parseExisting(context); const auto *constant = Constant::parseAndFind(context, expressionContext);
auto constantReference = std::make_unique<Reference<Constant>>(constant); auto constantReference = std::make_unique<Reference<Constant>>(constant);
predicate->m_arguments.emplace_back(std::move(constantReference)); predicate->m_arguments.emplace_back(std::move(constantReference));
} }

View File

@ -1,6 +1,8 @@
#include <plasp/pddl/expressions/PredicateDeclaration.h> #include <plasp/pddl/expressions/PredicateDeclaration.h>
#include <plasp/pddl/Context.h> #include <plasp/pddl/Context.h>
#include <plasp/pddl/Domain.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/ExpressionVisitor.h> #include <plasp/pddl/ExpressionVisitor.h>
#include <plasp/pddl/Identifier.h> #include <plasp/pddl/Identifier.h>
#include <plasp/pddl/expressions/Constant.h> #include <plasp/pddl/expressions/Constant.h>
@ -27,7 +29,7 @@ PredicateDeclaration::PredicateDeclaration()
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
void PredicateDeclaration::parse(Context &context) void PredicateDeclaration::parse(Context &context, Domain &domain)
{ {
context.parser.expect<std::string>("("); context.parser.expect<std::string>("(");
@ -40,18 +42,19 @@ void PredicateDeclaration::parse(Context &context)
context.parser.skipWhiteSpace(); context.parser.skipWhiteSpace();
ExpressionContext expressionContext(domain, predicate->m_parameters);
// Parse arguments // Parse arguments
while (context.parser.currentCharacter() != ')') while (context.parser.currentCharacter() != ')')
{ {
expressions::Variable::parseTypedDeclaration(context, predicate->m_arguments); expressions::Variable::parseTypedDeclaration(context, expressionContext);
context.parser.skipWhiteSpace(); context.parser.skipWhiteSpace();
} }
context.parser.expect<std::string>(")"); context.parser.expect<std::string>(")");
// Store new predicate domain.predicates().emplace_back(std::move(predicate));
context.predicateDeclarations.emplace_back(std::move(predicate));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
@ -86,7 +89,7 @@ const std::string &PredicateDeclaration::name() const
const Variables &PredicateDeclaration::arguments() const const Variables &PredicateDeclaration::arguments() const
{ {
return m_arguments; return m_parameters;
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -5,6 +5,8 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <plasp/pddl/Context.h> #include <plasp/pddl/Context.h>
#include <plasp/pddl/Domain.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/ExpressionVisitor.h> #include <plasp/pddl/ExpressionVisitor.h>
namespace plasp namespace plasp
@ -21,65 +23,61 @@ namespace expressions
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
PrimitiveType::PrimitiveType() PrimitiveType::PrimitiveType()
: m_isDirty{false}, : m_isDirty{true},
m_isDeclared{false} 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 BOOST_ASSERT(!m_name.empty());
auto type = std::make_unique<PrimitiveType>(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();
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
PrimitiveType *PrimitiveType::parseDeclaration(Context &context) void PrimitiveType::parseDeclaration(Context &context, Domain &domain)
{ {
auto &types = domain.types();
context.parser.skipWhiteSpace(); context.parser.skipWhiteSpace();
const auto typeName = context.parser.parseIdentifier(isIdentifier); const auto typeName = context.parser.parseIdentifier(isIdentifier);
// TODO: use hash map // 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) [&](const auto &primitiveType)
{ {
return primitiveType->name() == typeName; return primitiveType->name() == typeName;
}); });
// Return existing primitive type // Return existing primitive type
if (match != context.primitiveTypes.cend()) if (match != types.cend())
{ {
auto *type = match->get(); auto *type = match->get();
type->setDirty(); type->setDirty();
return type; return;
} }
return create(typeName, context); types.emplace_back(std::make_unique<PrimitiveType>(typeName));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
void PrimitiveType::parseTypedDeclaration(Context &context) void PrimitiveType::parseTypedDeclaration(Context &context, Domain &domain)
{ {
auto &types = domain.types();
// Parse and store type // 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 // Flag type as correctly declared in the types section
type->setDeclared(); type->setDeclared();
@ -91,7 +89,7 @@ void PrimitiveType::parseTypedDeclaration(Context &context)
return; return;
// If existing, parse and store parent type // If existing, parse and store parent type
auto *parentType = parseExisting(context); auto *parentType = parseAndFindOrCreate(context, domain);
parentType->setDirty(false); parentType->setDirty(false);
@ -99,7 +97,7 @@ void PrimitiveType::parseTypedDeclaration(Context &context)
parentType->setDeclared(); parentType->setDeclared();
// Assign parent type to all types that were previously flagged // 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) [&](auto &childType)
{ {
if (!childType->isDirty()) 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(); context.parser.skipWhiteSpace();
const auto typeName = context.parser.parseIdentifier(isIdentifier); const auto typeName = context.parser.parseIdentifier(isIdentifier);
@ -121,19 +121,22 @@ PrimitiveType *PrimitiveType::parseExisting(Context &context)
BOOST_ASSERT(!typeName.empty()); BOOST_ASSERT(!typeName.empty());
// TODO: use hash map // 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) [&](const auto &primitiveType)
{ {
return primitiveType->name() == typeName; return primitiveType->name() == typeName;
}); });
if (match == context.primitiveTypes.cend()) if (match == types.cend())
{ {
// Primitive type "object" is implicitly declared // Primitive type "object" is implicitly declared
if (typeName != "object") if (typeName != "object")
context.logger.parserWarning(context.parser, "Primitive type \"" + typeName + "\" used but never declared"); context.logger.parserWarning(context.parser, "Primitive type \"" + typeName + "\" used but never declared");
return create(typeName, context); types.emplace_back(std::make_unique<expressions::PrimitiveType>(typeName));
types.back()->setDeclared();
return types.back().get();
} }
auto *type = match->get(); auto *type = match->get();

View File

@ -1,6 +1,8 @@
#include <plasp/pddl/expressions/Type.h> #include <plasp/pddl/expressions/Type.h>
#include <plasp/pddl/Context.h> #include <plasp/pddl/Context.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/expressions/PrimitiveType.h>
#include <plasp/pddl/expressions/Reference.h> #include <plasp/pddl/expressions/Reference.h>
namespace plasp namespace plasp
@ -16,9 +18,9 @@ namespace expressions
// //
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer parseExistingPrimitiveType(Context &context, const Variables &parameters) ExpressionPointer parseExistingPrimitiveType(Context &context, ExpressionContext &expressionContext)
{ {
auto primitiveType = PrimitiveType::parseExisting(context); auto *primitiveType = PrimitiveType::parseAndFindOrCreate(context, expressionContext.domain);
return std::make_unique<Reference<PrimitiveType>>(primitiveType); return std::make_unique<Reference<PrimitiveType>>(primitiveType);
} }

View File

@ -2,10 +2,14 @@
#include <algorithm> #include <algorithm>
#include <boost/assert.hpp>
#include <plasp/pddl/Context.h> #include <plasp/pddl/Context.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/ExpressionVisitor.h> #include <plasp/pddl/ExpressionVisitor.h>
#include <plasp/pddl/Identifier.h> #include <plasp/pddl/Identifier.h>
#include <plasp/pddl/expressions/Either.h> #include <plasp/pddl/expressions/Either.h>
#include <plasp/pddl/expressions/PrimitiveType.h>
#include <plasp/pddl/expressions/Type.h> #include <plasp/pddl/expressions/Type.h>
#include <plasp/utils/ParserException.h> #include <plasp/utils/ParserException.h>
@ -29,7 +33,7 @@ Variable::Variable()
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
VariablePointer Variable::parseDeclaration(Context &context) void Variable::parseDeclaration(Context &context, Variables &parameters)
{ {
context.parser.skipWhiteSpace(); context.parser.skipWhiteSpace();
@ -42,17 +46,19 @@ VariablePointer Variable::parseDeclaration(Context &context)
// Flag variable for potentially upcoming type declaration // Flag variable for potentially upcoming type declaration
variable->setDirty(); variable->setDirty();
return variable; parameters.emplace_back(std::move(variable));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
void Variable::parseTypedDeclaration(Context &context, Variables &parameters) void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expressionContext)
{ {
// Parse and store variable itself auto &variables = expressionContext.parameters;
parameters.emplace_back(parseDeclaration(context));
auto &parameter = parameters.back(); // Parse and store variable itself
parseDeclaration(context, variables);
auto &variable = variables.back();
context.parser.skipWhiteSpace(); context.parser.skipWhiteSpace();
@ -66,14 +72,14 @@ void Variable::parseTypedDeclaration(Context &context, Variables &parameters)
[&](const auto *type) [&](const auto *type)
{ {
// Set the argument type for all previously flagged arguments // Set the argument type for all previously flagged arguments
std::for_each(parameters.begin(), parameters.end(), std::for_each(variables.begin(), variables.end(),
[&](auto &parameter) [&](auto &variable)
{ {
if (!parameter->isDirty()) if (!variable->isDirty())
return; return;
parameter->setType(type); variable->setType(type);
parameter->setDirty(false); variable->setDirty(false);
}); });
}; };
@ -85,23 +91,23 @@ void Variable::parseTypedDeclaration(Context &context, Variables &parameters)
context.parser.expect<std::string>("("); context.parser.expect<std::string>("(");
context.parser.expect<std::string>("either"); context.parser.expect<std::string>("either");
parameter->m_eitherExpression = Either::parse(context, parameters, parseExistingPrimitiveType); variable->m_eitherExpression = Either::parse(context, expressionContext, parseExistingPrimitiveType);
context.parser.expect<std::string>(")"); context.parser.expect<std::string>(")");
setType(parameter->m_eitherExpression.get()); setType(variable->m_eitherExpression.get());
return; return;
} }
// Parse primitive type // Parse primitive type
const auto *type = PrimitiveType::parseExisting(context); const auto *type = PrimitiveType::parseAndFindOrCreate(context, expressionContext.domain);
setType(type); setType(type);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
const Variable *Variable::parseExisting(Context &context, const Variables &variables) const Variable *Variable::parseAndFind(Context &context, const ExpressionContext &expressionContext)
{ {
context.parser.skipWhiteSpace(); 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 variableName = context.parser.parseIdentifier(isIdentifier);
const auto &variables = expressionContext.parameters;
const auto match = std::find_if(variables.cbegin(), variables.cend(), const auto match = std::find_if(variables.cbegin(), variables.cend(),
[&](const auto &variable) [&](const auto &variable)
{ {
@ -116,7 +124,7 @@ const Variable *Variable::parseExisting(Context &context, const Variables &varia
}); });
if (match == variables.cend()) 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(); return match->get();
} }