Refactoring to make parsing expressions consistent across PDDL domains and problems.
This commit is contained in:
parent
d5fa00a4a4
commit
b612122180
@ -21,7 +21,7 @@ namespace pddl
|
||||
class Action
|
||||
{
|
||||
public:
|
||||
static Action &parseDeclaration(Context &context);
|
||||
static void parseDeclaration(Context &context, Domain &domain);
|
||||
|
||||
public:
|
||||
const std::string &name() const;
|
||||
|
@ -5,11 +5,6 @@
|
||||
#include <unordered_map>
|
||||
#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>
|
||||
|
||||
namespace plasp
|
||||
@ -33,17 +28,6 @@ class Context
|
||||
|
||||
utils::Parser &parser;
|
||||
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;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -33,6 +33,8 @@ class Description
|
||||
void parseContent();
|
||||
void parseSection();
|
||||
|
||||
void checkConsistency();
|
||||
|
||||
utils::Parser m_parser;
|
||||
Context m_context;
|
||||
|
||||
|
@ -1,8 +1,12 @@
|
||||
#ifndef __PLASP__PDDL__DOMAIN_H
|
||||
#define __PLASP__PDDL__DOMAIN_H
|
||||
|
||||
#include <plasp/pddl/Action.h>
|
||||
#include <plasp/pddl/Context.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>
|
||||
|
||||
namespace plasp
|
||||
@ -19,19 +23,32 @@ namespace pddl
|
||||
class Domain
|
||||
{
|
||||
public:
|
||||
static Domain fromPDDL(Context &context);
|
||||
|
||||
public:
|
||||
const std::string &name() const;
|
||||
const Requirements &requirements() const;
|
||||
const expressions::PrimitiveTypes &types() const;
|
||||
const expressions::Constants &constants() const;
|
||||
const expressions::PredicateDeclarations &predicates() const;
|
||||
const std::vector<std::unique_ptr<Action>> &actions() const;
|
||||
|
||||
private:
|
||||
Domain(Context &context);
|
||||
|
||||
public:
|
||||
void readPDDL();
|
||||
|
||||
bool isDeclared() const;
|
||||
|
||||
const std::string &name() const;
|
||||
|
||||
const Requirements &requirements() const;
|
||||
|
||||
expressions::PrimitiveTypes &types();
|
||||
const expressions::PrimitiveTypes &types() const;
|
||||
|
||||
expressions::Constants &constants();
|
||||
const expressions::Constants &constants() const;
|
||||
|
||||
expressions::PredicateDeclarations &predicates();
|
||||
const expressions::PredicateDeclarations &predicates() const;
|
||||
|
||||
std::vector<std::unique_ptr<Action>> &actions();
|
||||
const std::vector<std::unique_ptr<Action>> &actions() const;
|
||||
|
||||
void checkConsistency();
|
||||
|
||||
private:
|
||||
void parseSection();
|
||||
|
||||
void parseRequirementSection();
|
||||
@ -46,12 +63,15 @@ class Domain
|
||||
|
||||
void parseActionSection();
|
||||
|
||||
void checkConsistency();
|
||||
|
||||
Context &m_context;
|
||||
bool m_isDeclared;
|
||||
|
||||
std::string m_name;
|
||||
Requirements m_requirements;
|
||||
expressions::PrimitiveTypes m_primitiveTypes;
|
||||
expressions::Constants m_constants;
|
||||
expressions::PredicateDeclarations m_predicateDeclarations;
|
||||
std::vector<std::unique_ptr<Action>> m_actions;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -17,7 +17,10 @@ namespace pddl
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Context;
|
||||
class Domain;
|
||||
class ExpressionContext;
|
||||
class ExpressionVisitor;
|
||||
class Problem;
|
||||
|
||||
class Expression;
|
||||
using ExpressionPointer = std::unique_ptr<Expression>;
|
||||
@ -77,10 +80,11 @@ class Expression
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parsePreconditionExpression(Context &context,
|
||||
const expressions::Variables ¶meters);
|
||||
ExpressionPointer parseExpression(Context &context, const expressions::Variables ¶meters);
|
||||
ExpressionContext &expressionContext);
|
||||
ExpressionPointer parseExpression(Context &context, ExpressionContext &expressionContext);
|
||||
|
||||
ExpressionPointer parseEffectExpression(Context &context, const expressions::Variables ¶meters);
|
||||
ExpressionPointer parseEffectExpression(Context &context,
|
||||
ExpressionContext &expressionContext);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
46
include/plasp/pddl/ExpressionContext.h
Normal file
46
include/plasp/pddl/ExpressionContext.h
Normal 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 ¶meters)
|
||||
: domain(domain),
|
||||
problem(nullptr),
|
||||
parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
ExpressionContext(Domain &domain, Problem *problem, expressions::Variables ¶meters)
|
||||
: domain(domain),
|
||||
problem{problem},
|
||||
parameters(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
Domain &domain;
|
||||
Problem *problem;
|
||||
|
||||
expressions::Variables ¶meters;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -19,15 +19,25 @@ namespace pddl
|
||||
class Problem
|
||||
{
|
||||
public:
|
||||
static Problem fromPDDL(Context &context);
|
||||
Problem(Context &context, Domain &domain);
|
||||
|
||||
void readPDDL();
|
||||
|
||||
bool isDeclared() const;
|
||||
|
||||
Domain &domain();
|
||||
const Domain &domain() const;
|
||||
|
||||
public:
|
||||
const std::string &name() const;
|
||||
|
||||
const Requirements &requirements() const;
|
||||
|
||||
private:
|
||||
Problem(Context &context);
|
||||
expressions::Constants &objects();
|
||||
const expressions::Constants &objects() const;
|
||||
|
||||
void checkConsistency();
|
||||
|
||||
private:
|
||||
void parseSection();
|
||||
|
||||
void parseRequirementSection();
|
||||
@ -36,9 +46,9 @@ class Problem
|
||||
|
||||
void parseObjectSection();
|
||||
|
||||
void checkConsistency();
|
||||
|
||||
Context &m_context;
|
||||
Domain &m_domain;
|
||||
bool m_isDeclared;
|
||||
|
||||
std::string m_name;
|
||||
Requirements m_requirements;
|
||||
|
@ -20,7 +20,7 @@ class And: public NAry
|
||||
{
|
||||
public:
|
||||
template<typename ExpressionParser>
|
||||
static AndPointer parse(Context &context, const Variables ¶meters,
|
||||
static AndPointer parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression);
|
||||
|
||||
public:
|
||||
@ -33,12 +33,12 @@ class And: public NAry
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename ExpressionParser>
|
||||
AndPointer And::parse(Context &context, const Variables ¶meters,
|
||||
AndPointer And::parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression)
|
||||
{
|
||||
auto expression = std::make_unique<And>(And());
|
||||
|
||||
expression->NAry::parse(context, parameters, parseExpression);
|
||||
expression->NAry::parse(context, expressionContext, parseExpression);
|
||||
|
||||
if (expression->arguments().empty())
|
||||
throw ConsistencyException("\"and\" expressions should not be empty");
|
||||
|
@ -27,7 +27,8 @@ class Binary: public Expression
|
||||
|
||||
protected:
|
||||
template<typename ExpressionParser>
|
||||
void parse(Context &context, const Variables ¶meters, ExpressionParser parseExpression);
|
||||
void parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression);
|
||||
|
||||
private:
|
||||
ExpressionPointer m_leftArgument;
|
||||
@ -37,12 +38,13 @@ class Binary: public Expression
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename ExpressionParser>
|
||||
void Binary::parse(Context &context, const Variables ¶meters, ExpressionParser parseExpression)
|
||||
void Binary::parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression)
|
||||
{
|
||||
// Assume that expression identifier (imply, exists, etc.) is already parsed
|
||||
// Parse arguments of the expression
|
||||
m_leftArgument = parseExpression(context, parameters);
|
||||
m_rightArgument = parseExpression(context, parameters);
|
||||
m_leftArgument = parseExpression(context, expressionContext);
|
||||
m_rightArgument = parseExpression(context, expressionContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -22,10 +22,10 @@ namespace expressions
|
||||
class Constant: public Expression
|
||||
{
|
||||
public:
|
||||
static ConstantPointer parseDeclaration(Context &context);
|
||||
static void parseTypedDeclaration(Context &context, Constants &constants);
|
||||
static void parseTypedDeclaration(Context &context, Domain &domain);
|
||||
static void parseTypedDeclaration(Context &context, Problem &problem);
|
||||
|
||||
static Constant *parseExisting(Context &context);
|
||||
static Constant *parseAndFind(Context &context, const ExpressionContext &expressionContext);
|
||||
|
||||
// TODO: method for lazy creation if not existing
|
||||
|
||||
@ -38,6 +38,11 @@ class Constant: public Expression
|
||||
bool isDeclared() const;
|
||||
|
||||
private:
|
||||
static ConstantPointer parseDeclaration(Context &context);
|
||||
static void parseTypedDeclaration(Context &context, Domain &domain, Constants &constants);
|
||||
|
||||
static Constant *parseAndFind(const std::string &constantName, const Constants &constants);
|
||||
|
||||
Constant();
|
||||
|
||||
void setDirty(bool isDirty = true);
|
||||
|
@ -20,7 +20,7 @@ class Either: public NAry
|
||||
{
|
||||
public:
|
||||
template<typename ExpressionParser>
|
||||
static EitherPointer parse(Context &context, const Variables ¶meters,
|
||||
static EitherPointer parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression);
|
||||
|
||||
public:
|
||||
@ -33,12 +33,12 @@ class Either: public NAry
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename ExpressionParser>
|
||||
EitherPointer Either::parse(Context &context, const Variables ¶meters,
|
||||
EitherPointer Either::parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression)
|
||||
{
|
||||
auto expression = std::make_unique<Either>(Either());
|
||||
|
||||
expression->NAry::parse(context, parameters, parseExpression);
|
||||
expression->NAry::parse(context, expressionContext, parseExpression);
|
||||
|
||||
if (expression->arguments().empty())
|
||||
throw ConsistencyException("\"and\" expressions should not be empty");
|
||||
|
@ -20,7 +20,7 @@ class Imply: public Binary
|
||||
{
|
||||
public:
|
||||
template<typename ExpressionParser>
|
||||
static ImplyPointer parse(Context &context, const Variables ¶meters,
|
||||
static ImplyPointer parse(Context &context, ExpressionContext ¶meters,
|
||||
ExpressionParser parseExpression);
|
||||
|
||||
public:
|
||||
@ -33,7 +33,7 @@ class Imply: public Binary
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename ExpressionParser>
|
||||
ImplyPointer Imply::parse(Context &context, const Variables ¶meters,
|
||||
ImplyPointer Imply::parse(Context &context, ExpressionContext ¶meters,
|
||||
ExpressionParser parseExpression)
|
||||
{
|
||||
auto expression = std::make_unique<Imply>(Imply());
|
||||
|
@ -26,7 +26,7 @@ class NAry: public Expression
|
||||
|
||||
protected:
|
||||
template<typename ExpressionParser>
|
||||
void parse(Context &context, const Variables ¶meters, ExpressionParser parseExpression);
|
||||
void parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression);
|
||||
|
||||
private:
|
||||
Expressions m_arguments;
|
||||
@ -35,7 +35,7 @@ class NAry: public Expression
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename ExpressionParser>
|
||||
void NAry::parse(Context &context, const Variables ¶meters, ExpressionParser parseExpression)
|
||||
void NAry::parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression)
|
||||
{
|
||||
context.parser.skipWhiteSpace();
|
||||
|
||||
@ -43,7 +43,7 @@ void NAry::parse(Context &context, const Variables ¶meters, ExpressionParser
|
||||
// Parse arguments of the expression
|
||||
while (context.parser.currentCharacter() != ')')
|
||||
{
|
||||
m_arguments.emplace_back(parseExpression(context, parameters));
|
||||
m_arguments.emplace_back(parseExpression(context, expressionContext));
|
||||
|
||||
context.parser.skipWhiteSpace();
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class Not: public Expression
|
||||
{
|
||||
public:
|
||||
template<typename ExpressionParser>
|
||||
static NotPointer parse(Context &context, const Variables ¶meters,
|
||||
static NotPointer parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression);
|
||||
|
||||
public:
|
||||
@ -38,7 +38,7 @@ class Not: public Expression
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename ExpressionParser>
|
||||
NotPointer Not::parse(Context &context, const Variables ¶meters,
|
||||
NotPointer Not::parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression)
|
||||
{
|
||||
auto expression = std::make_unique<Not>(Not());
|
||||
@ -46,7 +46,7 @@ NotPointer Not::parse(Context &context, const Variables ¶meters,
|
||||
context.parser.skipWhiteSpace();
|
||||
|
||||
// Parse argument
|
||||
expression->m_argument = parseExpression(context, parameters);
|
||||
expression->m_argument = parseExpression(context, expressionContext);
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ class Or: public NAry
|
||||
{
|
||||
public:
|
||||
template<typename ExpressionParser>
|
||||
static OrPointer parse(Context &context, const Variables ¶meters,
|
||||
static OrPointer parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression);
|
||||
|
||||
public:
|
||||
@ -33,11 +33,12 @@ class Or: public NAry
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename ExpressionParser>
|
||||
OrPointer Or::parse(Context &context, const Variables ¶meters, ExpressionParser parseExpression)
|
||||
OrPointer Or::parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression)
|
||||
{
|
||||
auto expression = std::make_unique<Or>(Or());
|
||||
|
||||
expression->NAry::parse(context, parameters, parseExpression);
|
||||
expression->NAry::parse(context, expressionContext, parseExpression);
|
||||
|
||||
if (expression->arguments().empty())
|
||||
throw ConsistencyException("\"or\" expressions should not be empty");
|
||||
|
@ -20,7 +20,7 @@ class Predicate: public Expression
|
||||
{
|
||||
public:
|
||||
static PredicatePointer parse(std::string name, Context &context,
|
||||
const Variables ¶meters);
|
||||
ExpressionContext &expressionContext);
|
||||
|
||||
public:
|
||||
void accept(ExpressionVisitor &expressionVisitor) const override;
|
||||
|
@ -19,7 +19,7 @@ namespace expressions
|
||||
class PredicateDeclaration: public Expression
|
||||
{
|
||||
public:
|
||||
static void parse(Context &context);
|
||||
static void parse(Context &context, Domain &domain);
|
||||
|
||||
public:
|
||||
void accept(ExpressionVisitor &expressionVisitor) const override;
|
||||
@ -37,7 +37,7 @@ class PredicateDeclaration: public Expression
|
||||
bool m_isDeclared;
|
||||
|
||||
std::string m_name;
|
||||
Variables m_arguments;
|
||||
Variables m_parameters;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -22,12 +22,15 @@ namespace expressions
|
||||
class PrimitiveType: public Expression
|
||||
{
|
||||
public:
|
||||
static PrimitiveType *parseDeclaration(Context &context);
|
||||
static void parseTypedDeclaration(Context &context);
|
||||
static void parseDeclaration(Context &context, Domain &domain);
|
||||
static void parseTypedDeclaration(Context &context, Domain &domain);
|
||||
|
||||
static PrimitiveType *parseExisting(Context &context);
|
||||
static PrimitiveType *parseAndFindOrCreate(Context &context, Domain &domain);
|
||||
|
||||
public:
|
||||
PrimitiveType();
|
||||
PrimitiveType(std::string name);
|
||||
|
||||
void accept(ExpressionVisitor &expressionVisitor) const override;
|
||||
|
||||
const std::string &name() const;
|
||||
@ -36,11 +39,6 @@ class PrimitiveType: public Expression
|
||||
bool isDeclared() const;
|
||||
|
||||
private:
|
||||
static PrimitiveType *create(std::string name, Context &context);
|
||||
|
||||
private:
|
||||
PrimitiveType();
|
||||
|
||||
void setDirty(bool isDirty = true);
|
||||
bool isDirty() const;
|
||||
|
||||
|
@ -16,7 +16,8 @@ namespace expressions
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseExistingPrimitiveType(Context &context, const Variables ¶meters);
|
||||
ExpressionPointer parseExistingPrimitiveType(Context &context,
|
||||
ExpressionContext &expressionContext);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -19,11 +19,9 @@ namespace expressions
|
||||
class Variable: public Expression
|
||||
{
|
||||
public:
|
||||
static VariablePointer parseDeclaration(Context &context);
|
||||
static void parseTypedDeclaration(Context &context, ExpressionContext &expressionContext);
|
||||
|
||||
static void parseTypedDeclaration(Context &context, Variables ¶meters);
|
||||
|
||||
static const Variable *parseExisting(Context &context, const Variables &variables);
|
||||
static const Variable *parseAndFind(Context &context, const ExpressionContext &expressionContext);
|
||||
|
||||
public:
|
||||
void accept(ExpressionVisitor &expressionVisitor) const override;
|
||||
@ -36,6 +34,9 @@ class Variable: public Expression
|
||||
|
||||
void setType(const Expression *type);
|
||||
|
||||
private:
|
||||
static void parseDeclaration(Context &context, Variables ¶meters);
|
||||
|
||||
private:
|
||||
Variable();
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/Identifier.h>
|
||||
#include <plasp/pddl/expressions/Type.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);
|
||||
|
||||
auto action = std::make_unique<Action>(Action(actionName));
|
||||
|
||||
context.parser.expect<std::string>(":parameters");
|
||||
|
||||
context.parser.expect<std::string>("(");
|
||||
|
||||
ExpressionContext expressionContext(domain, action->m_parameters);
|
||||
|
||||
// Read parameters
|
||||
while (context.parser.currentCharacter() != ')')
|
||||
{
|
||||
expressions::Variable::parseTypedDeclaration(context, action->m_parameters);
|
||||
expressions::Variable::parseTypedDeclaration(context, expressionContext);
|
||||
|
||||
context.parser.skipWhiteSpace();
|
||||
}
|
||||
@ -54,17 +57,15 @@ Action &Action::parseDeclaration(Context &context)
|
||||
const auto sectionIdentifier = context.parser.parseIdentifier(isIdentifier);
|
||||
|
||||
if (sectionIdentifier == "precondition")
|
||||
action->m_precondition = parsePreconditionExpression(context, action->m_parameters);
|
||||
action->m_precondition = parsePreconditionExpression(context, expressionContext);
|
||||
else if (sectionIdentifier == "effect")
|
||||
action->m_effect = parseEffectExpression(context, action->m_parameters);
|
||||
action->m_effect = parseEffectExpression(context, expressionContext);
|
||||
|
||||
context.parser.skipWhiteSpace();
|
||||
}
|
||||
|
||||
// Store new action
|
||||
context.actions.emplace_back(std::move(action));
|
||||
|
||||
return *context.actions.back();
|
||||
expressionContext.domain.actions().emplace_back(std::move(action));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -31,6 +31,9 @@ Description Description::fromStream(std::istream &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)
|
||||
{
|
||||
description.m_context.parser.skipWhiteSpace();
|
||||
@ -41,6 +44,8 @@ Description Description::fromStream(std::istream &istream)
|
||||
description.parseContent();
|
||||
}
|
||||
|
||||
description.checkConsistency();
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
@ -89,14 +94,36 @@ void Description::parseSection()
|
||||
std::cout << "Parsing section " << sectionIdentifier << std::endl;
|
||||
|
||||
if (sectionIdentifier == "domain")
|
||||
m_domain = std::make_unique<Domain>(Domain::fromPDDL(m_context));
|
||||
{
|
||||
BOOST_ASSERT(m_domain);
|
||||
|
||||
if (m_domain->isDeclared())
|
||||
throw utils::ParserException(m_context.parser, "PDDL description may not contain two domains");
|
||||
|
||||
m_domain->readPDDL();
|
||||
}
|
||||
else if (sectionIdentifier == "problem")
|
||||
m_problem = std::make_unique<Problem>(Problem::fromPDDL(m_context));
|
||||
{
|
||||
BOOST_ASSERT(m_problem);
|
||||
|
||||
if (m_problem->isDeclared())
|
||||
throw utils::ParserException(m_context.parser, "PDDL description may currently not contain two problems");
|
||||
|
||||
m_problem->readPDDL();
|
||||
}
|
||||
else
|
||||
throw utils::ParserException(m_context.parser, "Unknown PDDL section \"" + sectionIdentifier + "\"");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Description::checkConsistency()
|
||||
{
|
||||
m_domain->checkConsistency();
|
||||
m_problem->checkConsistency();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -23,37 +23,41 @@ namespace pddl
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Domain::Domain(Context &context)
|
||||
: m_context(context)
|
||||
: m_context(context),
|
||||
m_isDeclared{false}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Domain Domain::fromPDDL(Context &context)
|
||||
void Domain::readPDDL()
|
||||
{
|
||||
Domain domain(context);
|
||||
m_name = m_context.parser.parseIdentifier(isIdentifier);
|
||||
|
||||
domain.m_name = context.parser.parseIdentifier(isIdentifier);
|
||||
std::cout << "Parsing domain " << m_name << std::endl;
|
||||
|
||||
std::cout << "Parsing domain " << domain.m_name << std::endl;
|
||||
|
||||
context.parser.expect<std::string>(")");
|
||||
m_context.parser.expect<std::string>(")");
|
||||
|
||||
while (true)
|
||||
{
|
||||
context.parser.skipWhiteSpace();
|
||||
m_context.parser.skipWhiteSpace();
|
||||
|
||||
if (context.parser.currentCharacter() == ')')
|
||||
if (m_context.parser.currentCharacter() == ')')
|
||||
break;
|
||||
|
||||
domain.parseSection();
|
||||
parseSection();
|
||||
}
|
||||
|
||||
domain.computeDerivedRequirements();
|
||||
computeDerivedRequirements();
|
||||
|
||||
domain.checkConsistency();
|
||||
m_isDeclared = true;
|
||||
}
|
||||
|
||||
return domain;
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Domain::isDeclared() const
|
||||
{
|
||||
return m_isDeclared;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -72,30 +76,58 @@ const Requirements &Domain::requirements() const
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
expressions::PrimitiveTypes &Domain::types()
|
||||
{
|
||||
return m_primitiveTypes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const expressions::PrimitiveTypes &Domain::types() const
|
||||
{
|
||||
return m_context.primitiveTypes;
|
||||
return m_primitiveTypes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
expressions::Constants &Domain::constants()
|
||||
{
|
||||
return m_constants;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const expressions::Constants &Domain::constants() const
|
||||
{
|
||||
return m_context.constants;
|
||||
return m_constants;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
expressions::PredicateDeclarations &Domain::predicates()
|
||||
{
|
||||
return m_predicateDeclarations;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const expressions::PredicateDeclarations &Domain::predicates() const
|
||||
{
|
||||
return m_context.predicateDeclarations;
|
||||
return m_predicateDeclarations;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<std::unique_ptr<Action>> &Domain::actions()
|
||||
{
|
||||
return m_actions;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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() == '(')
|
||||
throw utils::ParserException(m_context.parser, "Only primitive types are allowed in type section");
|
||||
|
||||
expressions::PrimitiveType::parseTypedDeclaration(m_context);
|
||||
expressions::PrimitiveType::parseTypedDeclaration(m_context, *this);
|
||||
|
||||
m_context.parser.skipWhiteSpace();
|
||||
}
|
||||
@ -259,7 +291,7 @@ void Domain::parseConstantSection()
|
||||
// Store constants
|
||||
while (m_context.parser.currentCharacter() != ')')
|
||||
{
|
||||
expressions::Constant::parseTypedDeclaration(m_context, m_context.constants);
|
||||
expressions::Constant::parseTypedDeclaration(m_context, *this);
|
||||
|
||||
m_context.parser.skipWhiteSpace();
|
||||
}
|
||||
@ -276,7 +308,7 @@ void Domain::parsePredicateSection()
|
||||
// Store predicates and their arguments
|
||||
while (m_context.parser.currentCharacter() != ')')
|
||||
{
|
||||
expressions::PredicateDeclaration::parse(m_context);
|
||||
expressions::PredicateDeclaration::parse(m_context, *this);
|
||||
|
||||
m_context.parser.skipWhiteSpace();
|
||||
}
|
||||
@ -290,7 +322,7 @@ void Domain::parseActionSection()
|
||||
{
|
||||
m_context.parser.skipWhiteSpace();
|
||||
|
||||
Action::parseDeclaration(m_context);
|
||||
Action::parseDeclaration(m_context, *this);
|
||||
|
||||
m_context.parser.expect<std::string>(")");
|
||||
}
|
||||
@ -300,7 +332,7 @@ void Domain::parseActionSection()
|
||||
void Domain::checkConsistency()
|
||||
{
|
||||
// Verify that typing requirement is correctly declared if used
|
||||
if (!m_context.primitiveTypes.empty() && !hasRequirement(Requirement::Type::Typing))
|
||||
if (!m_primitiveTypes.empty() && !hasRequirement(Requirement::Type::Typing))
|
||||
{
|
||||
throw ConsistencyException("Domain contains typing information but does not declare typing requirement");
|
||||
|
||||
@ -308,7 +340,7 @@ void Domain::checkConsistency()
|
||||
}
|
||||
|
||||
// Verify that all used types have been declared
|
||||
std::for_each(m_context.primitiveTypes.cbegin(), m_context.primitiveTypes.cend(),
|
||||
std::for_each(m_primitiveTypes.cbegin(), m_primitiveTypes.cend(),
|
||||
[&](const auto &type)
|
||||
{
|
||||
if (!type->isDeclared())
|
||||
@ -316,7 +348,7 @@ void Domain::checkConsistency()
|
||||
});
|
||||
|
||||
// Verify that all used constants have been declared
|
||||
std::for_each(m_context.constants.cbegin(), m_context.constants.cend(),
|
||||
std::for_each(m_constants.cbegin(), m_constants.cend(),
|
||||
[&](const auto &constant)
|
||||
{
|
||||
if (!constant->isDeclared())
|
||||
@ -327,7 +359,7 @@ void Domain::checkConsistency()
|
||||
});
|
||||
|
||||
// Verify that all used predicates have been declared
|
||||
std::for_each(m_context.predicateDeclarations.cbegin(), m_context.predicateDeclarations.cend(),
|
||||
std::for_each(m_predicateDeclarations.cbegin(), m_predicateDeclarations.cend(),
|
||||
[&](const auto &predicate)
|
||||
{
|
||||
if (!predicate->isDeclared())
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include <plasp/pddl/Expression.h>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/Identifier.h>
|
||||
#include <plasp/pddl/expressions/And.h>
|
||||
#include <plasp/pddl/expressions/Imply.h>
|
||||
@ -23,15 +25,16 @@ namespace pddl
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier,
|
||||
Context &context, const expressions::Variables ¶meters);
|
||||
ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier, Context &context,
|
||||
ExpressionContext &expressionContext);
|
||||
ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier,
|
||||
Context &context, const expressions::Variables ¶meters);
|
||||
ExpressionPointer parsePredicate(Context &context, const expressions::Variables ¶meters);
|
||||
Context &context, ExpressionContext &expressionContext);
|
||||
ExpressionPointer parsePredicate(Context &context, ExpressionContext &expressionContext);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void throwUnsupported(const utils::Parser &parser, const std::string &expressionIdentifier)
|
||||
[[noreturn]] void throwUnsupported(const utils::Parser &parser,
|
||||
const std::string &expressionIdentifier)
|
||||
{
|
||||
throw utils::ParserException(parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported in this context");
|
||||
}
|
||||
@ -39,7 +42,7 @@ void throwUnsupported(const utils::Parser &parser, const std::string &expression
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parsePreconditionExpression(Context &context,
|
||||
const expressions::Variables ¶meters)
|
||||
ExpressionContext &expressionContext)
|
||||
{
|
||||
context.parser.expect<std::string>("(");
|
||||
|
||||
@ -49,7 +52,7 @@ ExpressionPointer parsePreconditionExpression(Context &context,
|
||||
|
||||
if (expressionIdentifier == "and")
|
||||
{
|
||||
expression = expressions::And::parse(context, parameters,
|
||||
expression = expressions::And::parse(context, expressionContext,
|
||||
parsePreconditionExpression);
|
||||
}
|
||||
else if (expressionIdentifier == "forall"
|
||||
@ -58,7 +61,7 @@ ExpressionPointer parsePreconditionExpression(Context &context,
|
||||
throwUnsupported(context.parser, expressionIdentifier);
|
||||
}
|
||||
else
|
||||
expression = parseExpressionContent(expressionIdentifier, context, parameters);
|
||||
expression = parseExpressionContent(expressionIdentifier, context, expressionContext);
|
||||
|
||||
context.parser.expect<std::string>(")");
|
||||
|
||||
@ -67,13 +70,13 @@ ExpressionPointer parsePreconditionExpression(Context &context,
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseExpression(Context &context, const expressions::Variables ¶meters)
|
||||
ExpressionPointer parseExpression(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
context.parser.expect<std::string>("(");
|
||||
|
||||
const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier);
|
||||
|
||||
auto expression = parseExpressionContent(expressionIdentifier, context, parameters);
|
||||
auto expression = parseExpressionContent(expressionIdentifier, context, expressionContext);
|
||||
|
||||
context.parser.expect<std::string>(")");
|
||||
|
||||
@ -82,22 +85,22 @@ ExpressionPointer parseExpression(Context &context, const expressions::Variables
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier,
|
||||
Context &context, const expressions::Variables ¶meters)
|
||||
ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier, Context &context,
|
||||
ExpressionContext &expressionContext)
|
||||
{
|
||||
context.parser.skipWhiteSpace();
|
||||
|
||||
if (expressionIdentifier == "and")
|
||||
return expressions::And::parse(context, parameters, parseExpression);
|
||||
return expressions::And::parse(context, expressionContext, parseExpression);
|
||||
|
||||
if (expressionIdentifier == "or")
|
||||
return expressions::Or::parse(context, parameters, parseExpression);
|
||||
return expressions::Or::parse(context, expressionContext, parseExpression);
|
||||
|
||||
if (expressionIdentifier == "not")
|
||||
return expressions::Not::parse(context, parameters, parseExpression);
|
||||
return expressions::Not::parse(context, expressionContext, parseExpression);
|
||||
|
||||
if (expressionIdentifier == "imply")
|
||||
return expressions::Imply::parse(context, parameters, parseExpression);
|
||||
return expressions::Imply::parse(context, expressionContext, parseExpression);
|
||||
|
||||
if (expressionIdentifier == "exists"
|
||||
|| expressionIdentifier == "forall"
|
||||
@ -116,23 +119,25 @@ ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier
|
||||
throwUnsupported(context.parser, expressionIdentifier);
|
||||
}
|
||||
|
||||
auto &predicateDeclarations = expressionContext.domain.predicates();
|
||||
|
||||
// Check if predicate with that name exists
|
||||
const auto match = std::find_if(context.predicateDeclarations.cbegin(), context.predicateDeclarations.cend(),
|
||||
const auto match = std::find_if(predicateDeclarations.cbegin(), predicateDeclarations.cend(),
|
||||
[&](const auto &predicate)
|
||||
{
|
||||
return predicate->name() == expressionIdentifier;
|
||||
});
|
||||
|
||||
// If predicate exists, parse it
|
||||
if (match != context.predicateDeclarations.cend())
|
||||
return expressions::Predicate::parse(expressionIdentifier, context, parameters);
|
||||
if (match != predicateDeclarations.cend())
|
||||
return expressions::Predicate::parse(expressionIdentifier, context, expressionContext);
|
||||
|
||||
throw utils::ParserException(context.parser, "Expression \"" + expressionIdentifier + "\" not allowed in this context");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseEffectExpression(Context &context, const expressions::Variables ¶meters)
|
||||
ExpressionPointer parseEffectExpression(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
context.parser.expect<std::string>("(");
|
||||
|
||||
@ -141,14 +146,14 @@ ExpressionPointer parseEffectExpression(Context &context, const expressions::Var
|
||||
ExpressionPointer expression;
|
||||
|
||||
if (expressionIdentifier == "and")
|
||||
expression = expressions::And::parse(context, parameters, parseEffectExpression);
|
||||
expression = expressions::And::parse(context, expressionContext, parseEffectExpression);
|
||||
else if (expressionIdentifier == "forall"
|
||||
|| expressionIdentifier == "when")
|
||||
{
|
||||
throwUnsupported(context.parser, expressionIdentifier);
|
||||
}
|
||||
else
|
||||
expression = parseEffectBodyExpressionContent(expressionIdentifier, context, parameters);
|
||||
expression = parseEffectBodyExpressionContent(expressionIdentifier, context, expressionContext);
|
||||
|
||||
context.parser.expect<std::string>(")");
|
||||
|
||||
@ -158,12 +163,12 @@ ExpressionPointer parseEffectExpression(Context &context, const expressions::Var
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier,
|
||||
Context &context, const expressions::Variables ¶meters)
|
||||
Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
ExpressionPointer expression;
|
||||
|
||||
if (expressionIdentifier == "not")
|
||||
return expressions::Not::parse(context, parameters, parsePredicate);
|
||||
return expressions::Not::parse(context, expressionContext, parsePredicate);
|
||||
|
||||
if (expressionIdentifier == "="
|
||||
|| expressionIdentifier == "assign"
|
||||
@ -175,23 +180,25 @@ ExpressionPointer parseEffectBodyExpressionContent(const std::string &expression
|
||||
throwUnsupported(context.parser, expressionIdentifier);
|
||||
}
|
||||
|
||||
const auto &predicateDeclarations = expressionContext.domain.predicates();
|
||||
|
||||
// Check if predicate with that name exists
|
||||
const auto match = std::find_if(context.predicateDeclarations.cbegin(), context.predicateDeclarations.cend(),
|
||||
const auto match = std::find_if(predicateDeclarations.cbegin(), predicateDeclarations.cend(),
|
||||
[&](const auto &predicate)
|
||||
{
|
||||
return predicate->name() == expressionIdentifier;
|
||||
});
|
||||
|
||||
// If predicate exists, parse it
|
||||
if (match != context.predicateDeclarations.cend())
|
||||
return expressions::Predicate::parse(expressionIdentifier, context, parameters);
|
||||
if (match != predicateDeclarations.cend())
|
||||
return expressions::Predicate::parse(expressionIdentifier, context, expressionContext);
|
||||
|
||||
throw utils::ParserException(context.parser, "Expression \"" + expressionIdentifier + "\" not allowed in this context");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parsePredicate(Context &context, const expressions::Variables ¶meters)
|
||||
ExpressionPointer parsePredicate(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
context.parser.expect<std::string>("(");
|
||||
|
||||
@ -199,18 +206,20 @@ ExpressionPointer parsePredicate(Context &context, const expressions::Variables
|
||||
|
||||
ExpressionPointer expression;
|
||||
|
||||
const auto &predicateDeclarations = expressionContext.domain.predicates();
|
||||
|
||||
// Check if predicate with that name exists
|
||||
const auto match = std::find_if(context.predicateDeclarations.cbegin(), context.predicateDeclarations.cend(),
|
||||
const auto match = std::find_if(predicateDeclarations.cbegin(), predicateDeclarations.cend(),
|
||||
[&](const auto &predicate)
|
||||
{
|
||||
return predicate->name() == predicateName;
|
||||
});
|
||||
|
||||
// If predicate exists, parse it
|
||||
if (match == context.predicateDeclarations.cend())
|
||||
if (match == predicateDeclarations.cend())
|
||||
throw utils::ParserException(context.parser, "Unknown predicate \"" + predicateName + "\"");
|
||||
|
||||
expression = expressions::Predicate::parse(predicateName, context, parameters);
|
||||
expression = expressions::Predicate::parse(predicateName, context, expressionContext);
|
||||
|
||||
context.parser.expect<std::string>(")");
|
||||
|
||||
|
@ -3,7 +3,9 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include <plasp/pddl/Identifier.h>
|
||||
#include <plasp/pddl/expressions/Constant.h>
|
||||
#include <plasp/utils/IO.h>
|
||||
#include <plasp/utils/ParserException.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
@ -16,38 +18,57 @@ namespace pddl
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Problem::Problem(Context &context)
|
||||
: m_context(context)
|
||||
Problem::Problem(Context &context, Domain &domain)
|
||||
: m_context(context),
|
||||
m_domain(domain),
|
||||
m_isDeclared{false}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Problem Problem::fromPDDL(Context &context)
|
||||
void Problem::readPDDL()
|
||||
{
|
||||
Problem problem(context);
|
||||
m_name = m_context.parser.parseIdentifier(isIdentifier);
|
||||
|
||||
problem.m_name = context.parser.parseIdentifier(isIdentifier);
|
||||
std::cout << "Parsing problem " << m_name << std::endl;
|
||||
|
||||
std::cout << "Parsing problem " << problem.m_name << std::endl;
|
||||
|
||||
context.parser.expect<std::string>(")");
|
||||
m_context.parser.expect<std::string>(")");
|
||||
|
||||
while (true)
|
||||
{
|
||||
context.parser.skipWhiteSpace();
|
||||
m_context.parser.skipWhiteSpace();
|
||||
|
||||
if (context.parser.currentCharacter() == ')')
|
||||
if (m_context.parser.currentCharacter() == ')')
|
||||
break;
|
||||
|
||||
problem.parseSection();
|
||||
parseSection();
|
||||
}
|
||||
|
||||
problem.computeDerivedRequirements();
|
||||
computeDerivedRequirements();
|
||||
|
||||
problem.checkConsistency();
|
||||
m_isDeclared = true;
|
||||
}
|
||||
|
||||
return problem;
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Problem::isDeclared() const
|
||||
{
|
||||
return m_isDeclared;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Domain &Problem::domain()
|
||||
{
|
||||
return m_domain;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const Domain &Problem::domain() const
|
||||
{
|
||||
return m_domain;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -66,6 +87,20 @@ const Requirements &Problem::requirements() const
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
expressions::Constants &Problem::objects()
|
||||
{
|
||||
return m_objects;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const expressions::Constants &Problem::objects() const
|
||||
{
|
||||
return m_objects;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Problem::parseSection()
|
||||
{
|
||||
m_context.parser.expect<std::string>("(");
|
||||
@ -203,7 +238,7 @@ void Problem::parseObjectSection()
|
||||
// Store constants
|
||||
while (m_context.parser.currentCharacter() != ')')
|
||||
{
|
||||
expressions::Constant::parseTypedDeclaration(m_context);
|
||||
//expressions::Constant::parseTypedDeclaration(m_context);
|
||||
|
||||
m_context.parser.skipWhiteSpace();
|
||||
}
|
||||
|
@ -5,7 +5,10 @@
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/ExpressionVisitor.h>
|
||||
#include <plasp/pddl/Problem.h>
|
||||
#include <plasp/pddl/expressions/PrimitiveType.h>
|
||||
|
||||
namespace plasp
|
||||
@ -50,7 +53,21 @@ ConstantPointer Constant::parseDeclaration(Context &context)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Constant::parseTypedDeclaration(Context &context, Constants &constants)
|
||||
void Constant::parseTypedDeclaration(Context &context, Domain &domain)
|
||||
{
|
||||
parseTypedDeclaration(context, domain, domain.constants());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Constant::parseTypedDeclaration(Context &context, Problem &problem)
|
||||
{
|
||||
parseTypedDeclaration(context, problem.domain(), problem.objects());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Constant::parseTypedDeclaration(Context &context, Domain &domain, Constants &constants)
|
||||
{
|
||||
// Parse and store constant
|
||||
constants.emplace_back(parseDeclaration(context));
|
||||
@ -67,7 +84,7 @@ void Constant::parseTypedDeclaration(Context &context, Constants &constants)
|
||||
return;
|
||||
|
||||
// If existing, parse and store parent type
|
||||
auto *type = PrimitiveType::parseExisting(context);
|
||||
auto *type = PrimitiveType::parseAndFindOrCreate(context, domain);
|
||||
|
||||
// Assign parent type to all types that were previously flagged
|
||||
std::for_each(constants.begin(), constants.end(),
|
||||
@ -83,21 +100,42 @@ void Constant::parseTypedDeclaration(Context &context, Constants &constants)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Constant *Constant::parseExisting(Context &context)
|
||||
Constant *Constant::parseAndFind(Context &context, const ExpressionContext &expressionContext)
|
||||
{
|
||||
context.parser.skipWhiteSpace();
|
||||
|
||||
const auto constantName = context.parser.parseIdentifier(isIdentifier);
|
||||
|
||||
auto *constant = parseAndFind(constantName, expressionContext.domain.constants());
|
||||
|
||||
if (constant)
|
||||
return constant;
|
||||
|
||||
if (expressionContext.problem)
|
||||
{
|
||||
constant = parseAndFind(constantName, expressionContext.problem->objects());
|
||||
|
||||
if (constant)
|
||||
return constant;
|
||||
}
|
||||
|
||||
throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Constant *Constant::parseAndFind(const std::string &constantName, const Constants &constants)
|
||||
{
|
||||
// TODO: use hash map
|
||||
const auto match = std::find_if(context.constants.cbegin(), context.constants.cend(),
|
||||
const auto match = std::find_if(constants.cbegin(), constants.cend(),
|
||||
[&](const auto &constant)
|
||||
{
|
||||
return constant->name() == constantName;
|
||||
});
|
||||
const auto constantExists = (match != context.constants.cend());
|
||||
const auto constantExists = (match != constants.cend());
|
||||
|
||||
if (!constantExists)
|
||||
throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared");
|
||||
return nullptr;
|
||||
|
||||
return match->get();
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
#include <plasp/pddl/expressions/Type.h>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Identifier.h>
|
||||
#include <plasp/pddl/expressions/Predicate.h>
|
||||
#include <plasp/utils/IO.h>
|
||||
#include <plasp/utils/ParserException.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include <plasp/pddl/expressions/Predicate.h>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/ExpressionVisitor.h>
|
||||
#include <plasp/pddl/Identifier.h>
|
||||
#include <plasp/pddl/expressions/Constant.h>
|
||||
@ -27,7 +29,8 @@ Predicate::Predicate()
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PredicatePointer Predicate::parse(std::string name, Context &context, const Variables ¶meters)
|
||||
PredicatePointer Predicate::parse(std::string name, Context &context,
|
||||
ExpressionContext &expressionContext)
|
||||
{
|
||||
auto predicate = std::make_unique<Predicate>(Predicate());
|
||||
|
||||
@ -41,14 +44,14 @@ PredicatePointer Predicate::parse(std::string name, Context &context, const Vari
|
||||
// Parse variables
|
||||
if (context.parser.currentCharacter() == '?')
|
||||
{
|
||||
const auto *variable = Variable::parseExisting(context, parameters);
|
||||
const auto *variable = Variable::parseAndFind(context, expressionContext);
|
||||
auto variableReference = std::make_unique<Reference<Variable>>(variable);
|
||||
predicate->m_arguments.emplace_back(std::move(variableReference));
|
||||
}
|
||||
// Parse constants
|
||||
else
|
||||
{
|
||||
const auto *constant = Constant::parseExisting(context);
|
||||
const auto *constant = Constant::parseAndFind(context, expressionContext);
|
||||
auto constantReference = std::make_unique<Reference<Constant>>(constant);
|
||||
predicate->m_arguments.emplace_back(std::move(constantReference));
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include <plasp/pddl/expressions/PredicateDeclaration.h>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/ExpressionVisitor.h>
|
||||
#include <plasp/pddl/Identifier.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>("(");
|
||||
|
||||
@ -40,18 +42,19 @@ void PredicateDeclaration::parse(Context &context)
|
||||
|
||||
context.parser.skipWhiteSpace();
|
||||
|
||||
ExpressionContext expressionContext(domain, predicate->m_parameters);
|
||||
|
||||
// Parse arguments
|
||||
while (context.parser.currentCharacter() != ')')
|
||||
{
|
||||
expressions::Variable::parseTypedDeclaration(context, predicate->m_arguments);
|
||||
expressions::Variable::parseTypedDeclaration(context, expressionContext);
|
||||
|
||||
context.parser.skipWhiteSpace();
|
||||
}
|
||||
|
||||
context.parser.expect<std::string>(")");
|
||||
|
||||
// Store new predicate
|
||||
context.predicateDeclarations.emplace_back(std::move(predicate));
|
||||
domain.predicates().emplace_back(std::move(predicate));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -86,7 +89,7 @@ const std::string &PredicateDeclaration::name() const
|
||||
|
||||
const Variables &PredicateDeclaration::arguments() const
|
||||
{
|
||||
return m_arguments;
|
||||
return m_parameters;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/ExpressionVisitor.h>
|
||||
|
||||
namespace plasp
|
||||
@ -21,65 +23,61 @@ namespace expressions
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PrimitiveType::PrimitiveType()
|
||||
: m_isDirty{false},
|
||||
: m_isDirty{true},
|
||||
m_isDeclared{false}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PrimitiveType *PrimitiveType::create(std::string name, Context &context)
|
||||
PrimitiveType::PrimitiveType(std::string name)
|
||||
: m_isDirty{true},
|
||||
m_isDeclared{false},
|
||||
m_name{name}
|
||||
{
|
||||
// Create new primitive type if not already existing
|
||||
auto type = std::make_unique<PrimitiveType>(PrimitiveType());
|
||||
|
||||
type->m_name = name;
|
||||
|
||||
BOOST_ASSERT(!type->m_name.empty());
|
||||
|
||||
// Flag type for potentially upcoming parent type declaration
|
||||
type->setDirty();
|
||||
|
||||
// TODO: Store constant in hash map
|
||||
context.primitiveTypes.emplace_back(std::move(type));
|
||||
|
||||
return context.primitiveTypes.back().get();
|
||||
BOOST_ASSERT(!m_name.empty());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PrimitiveType *PrimitiveType::parseDeclaration(Context &context)
|
||||
void PrimitiveType::parseDeclaration(Context &context, Domain &domain)
|
||||
{
|
||||
auto &types = domain.types();
|
||||
|
||||
context.parser.skipWhiteSpace();
|
||||
|
||||
const auto typeName = context.parser.parseIdentifier(isIdentifier);
|
||||
|
||||
// TODO: use hash map
|
||||
const auto match = std::find_if(context.primitiveTypes.cbegin(), context.primitiveTypes.cend(),
|
||||
const auto match = std::find_if(types.cbegin(), types.cend(),
|
||||
[&](const auto &primitiveType)
|
||||
{
|
||||
return primitiveType->name() == typeName;
|
||||
});
|
||||
|
||||
// Return existing primitive type
|
||||
if (match != context.primitiveTypes.cend())
|
||||
if (match != types.cend())
|
||||
{
|
||||
auto *type = match->get();
|
||||
|
||||
type->setDirty();
|
||||
|
||||
return type;
|
||||
return;
|
||||
}
|
||||
|
||||
return create(typeName, context);
|
||||
types.emplace_back(std::make_unique<PrimitiveType>(typeName));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PrimitiveType::parseTypedDeclaration(Context &context)
|
||||
void PrimitiveType::parseTypedDeclaration(Context &context, Domain &domain)
|
||||
{
|
||||
auto &types = domain.types();
|
||||
|
||||
// Parse and store type
|
||||
auto *type = parseDeclaration(context);
|
||||
parseDeclaration(context, domain);
|
||||
|
||||
auto *type = types.back().get();
|
||||
|
||||
// Flag type as correctly declared in the types section
|
||||
type->setDeclared();
|
||||
@ -91,7 +89,7 @@ void PrimitiveType::parseTypedDeclaration(Context &context)
|
||||
return;
|
||||
|
||||
// If existing, parse and store parent type
|
||||
auto *parentType = parseExisting(context);
|
||||
auto *parentType = parseAndFindOrCreate(context, domain);
|
||||
|
||||
parentType->setDirty(false);
|
||||
|
||||
@ -99,7 +97,7 @@ void PrimitiveType::parseTypedDeclaration(Context &context)
|
||||
parentType->setDeclared();
|
||||
|
||||
// Assign parent type to all types that were previously flagged
|
||||
std::for_each(context.primitiveTypes.begin(), context.primitiveTypes.end(),
|
||||
std::for_each(types.begin(), types.end(),
|
||||
[&](auto &childType)
|
||||
{
|
||||
if (!childType->isDirty())
|
||||
@ -112,8 +110,10 @@ void PrimitiveType::parseTypedDeclaration(Context &context)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PrimitiveType *PrimitiveType::parseExisting(Context &context)
|
||||
PrimitiveType *PrimitiveType::parseAndFindOrCreate(Context &context, Domain &domain)
|
||||
{
|
||||
auto &types = domain.types();
|
||||
|
||||
context.parser.skipWhiteSpace();
|
||||
|
||||
const auto typeName = context.parser.parseIdentifier(isIdentifier);
|
||||
@ -121,19 +121,22 @@ PrimitiveType *PrimitiveType::parseExisting(Context &context)
|
||||
BOOST_ASSERT(!typeName.empty());
|
||||
|
||||
// TODO: use hash map
|
||||
const auto match = std::find_if(context.primitiveTypes.cbegin(), context.primitiveTypes.cend(),
|
||||
const auto match = std::find_if(types.cbegin(), types.cend(),
|
||||
[&](const auto &primitiveType)
|
||||
{
|
||||
return primitiveType->name() == typeName;
|
||||
});
|
||||
|
||||
if (match == context.primitiveTypes.cend())
|
||||
if (match == types.cend())
|
||||
{
|
||||
// Primitive type "object" is implicitly declared
|
||||
if (typeName != "object")
|
||||
context.logger.parserWarning(context.parser, "Primitive type \"" + typeName + "\" used but never declared");
|
||||
|
||||
return create(typeName, context);
|
||||
types.emplace_back(std::make_unique<expressions::PrimitiveType>(typeName));
|
||||
types.back()->setDeclared();
|
||||
|
||||
return types.back().get();
|
||||
}
|
||||
|
||||
auto *type = match->get();
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include <plasp/pddl/expressions/Type.h>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/expressions/PrimitiveType.h>
|
||||
#include <plasp/pddl/expressions/Reference.h>
|
||||
|
||||
namespace plasp
|
||||
@ -16,9 +18,9 @@ namespace expressions
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseExistingPrimitiveType(Context &context, const Variables ¶meters)
|
||||
ExpressionPointer parseExistingPrimitiveType(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
auto primitiveType = PrimitiveType::parseExisting(context);
|
||||
auto *primitiveType = PrimitiveType::parseAndFindOrCreate(context, expressionContext.domain);
|
||||
|
||||
return std::make_unique<Reference<PrimitiveType>>(primitiveType);
|
||||
}
|
||||
|
@ -2,10 +2,14 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/ExpressionVisitor.h>
|
||||
#include <plasp/pddl/Identifier.h>
|
||||
#include <plasp/pddl/expressions/Either.h>
|
||||
#include <plasp/pddl/expressions/PrimitiveType.h>
|
||||
#include <plasp/pddl/expressions/Type.h>
|
||||
#include <plasp/utils/ParserException.h>
|
||||
|
||||
@ -29,7 +33,7 @@ Variable::Variable()
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
VariablePointer Variable::parseDeclaration(Context &context)
|
||||
void Variable::parseDeclaration(Context &context, Variables ¶meters)
|
||||
{
|
||||
context.parser.skipWhiteSpace();
|
||||
|
||||
@ -42,17 +46,19 @@ VariablePointer Variable::parseDeclaration(Context &context)
|
||||
// Flag variable for potentially upcoming type declaration
|
||||
variable->setDirty();
|
||||
|
||||
return variable;
|
||||
parameters.emplace_back(std::move(variable));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Variable::parseTypedDeclaration(Context &context, Variables ¶meters)
|
||||
void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
// Parse and store variable itself
|
||||
parameters.emplace_back(parseDeclaration(context));
|
||||
auto &variables = expressionContext.parameters;
|
||||
|
||||
auto ¶meter = parameters.back();
|
||||
// Parse and store variable itself
|
||||
parseDeclaration(context, variables);
|
||||
|
||||
auto &variable = variables.back();
|
||||
|
||||
context.parser.skipWhiteSpace();
|
||||
|
||||
@ -66,14 +72,14 @@ void Variable::parseTypedDeclaration(Context &context, Variables ¶meters)
|
||||
[&](const auto *type)
|
||||
{
|
||||
// Set the argument type for all previously flagged arguments
|
||||
std::for_each(parameters.begin(), parameters.end(),
|
||||
[&](auto ¶meter)
|
||||
std::for_each(variables.begin(), variables.end(),
|
||||
[&](auto &variable)
|
||||
{
|
||||
if (!parameter->isDirty())
|
||||
if (!variable->isDirty())
|
||||
return;
|
||||
|
||||
parameter->setType(type);
|
||||
parameter->setDirty(false);
|
||||
variable->setType(type);
|
||||
variable->setDirty(false);
|
||||
});
|
||||
};
|
||||
|
||||
@ -85,23 +91,23 @@ void Variable::parseTypedDeclaration(Context &context, Variables ¶meters)
|
||||
context.parser.expect<std::string>("(");
|
||||
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>(")");
|
||||
|
||||
setType(parameter->m_eitherExpression.get());
|
||||
setType(variable->m_eitherExpression.get());
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse primitive type
|
||||
const auto *type = PrimitiveType::parseExisting(context);
|
||||
const auto *type = PrimitiveType::parseAndFindOrCreate(context, expressionContext.domain);
|
||||
|
||||
setType(type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const Variable *Variable::parseExisting(Context &context, const Variables &variables)
|
||||
const Variable *Variable::parseAndFind(Context &context, const ExpressionContext &expressionContext)
|
||||
{
|
||||
context.parser.skipWhiteSpace();
|
||||
|
||||
@ -109,6 +115,8 @@ const Variable *Variable::parseExisting(Context &context, const Variables &varia
|
||||
|
||||
const auto variableName = context.parser.parseIdentifier(isIdentifier);
|
||||
|
||||
const auto &variables = expressionContext.parameters;
|
||||
|
||||
const auto match = std::find_if(variables.cbegin(), variables.cend(),
|
||||
[&](const auto &variable)
|
||||
{
|
||||
@ -116,7 +124,7 @@ const Variable *Variable::parseExisting(Context &context, const Variables &varia
|
||||
});
|
||||
|
||||
if (match == variables.cend())
|
||||
throw utils::ParserException(context.parser, "Variable \"" + variableName + "\" used but never declared");
|
||||
throw utils::ParserException(context.parser, "Parameter \"" + variableName + "\" used but never declared");
|
||||
|
||||
return match->get();
|
||||
}
|
||||
|
Reference in New Issue
Block a user