Parsing domains in two passes and continued working on parsing the initial state.

This commit is contained in:
Patrick Lühne 2016-06-09 01:25:18 +02:00
parent ff7a6b8c8f
commit 8428c20bd4
13 changed files with 380 additions and 175 deletions

View File

@ -26,7 +26,8 @@ class Domain
Domain(Context &context);
public:
void readPDDL();
void findSections();
void parse();
void setName(std::string name);
const std::string &name() const;
@ -66,10 +67,20 @@ class Domain
Context &m_context;
std::string m_name;
utils::Parser::Position m_requirementsPosition;
Requirements m_requirements;
expressions::PrimitiveTypes m_primitiveTypes;
utils::Parser::Position m_typesPosition;
expressions::PrimitiveTypes m_types;
utils::Parser::Position m_constantsPosition;
expressions::Constants m_constants;
expressions::PredicateDeclarations m_predicateDeclarations;
utils::Parser::Position m_predicatesPosition;
expressions::PredicateDeclarations m_predicates;
std::vector<utils::Parser::Position> m_actionPositions;
std::vector<std::unique_ptr<Action>> m_actions;
};

View File

@ -7,20 +7,27 @@ namespace plasp
{
namespace pddl
{
namespace expressions
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// InitialState
//
////////////////////////////////////////////////////////////////////////////////////////////////////
class InitialState
{
public:
static std::unique_ptr<InitialState> parseDeclaration(Context &context, const Problem &problem);
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Type
//
////////////////////////////////////////////////////////////////////////////////////////////////////
public:
const Expressions &facts() const;
ExpressionPointer parseInitialState(Context &context);
private:
Expressions m_facts;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
}

View File

@ -3,6 +3,7 @@
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Expression.h>
#include <plasp/pddl/InitialState.h>
#include <plasp/pddl/Requirement.h>
namespace plasp
@ -21,7 +22,7 @@ class Problem
public:
Problem(Context &context, Domain &domain);
void readPDDL();
void parse();
bool isDeclared() const;
@ -37,6 +38,9 @@ class Problem
expressions::Constants &objects();
const expressions::Constants &objects() const;
InitialState &initialState();
const InitialState &initialState() const;
void checkConsistency();
private:
@ -49,6 +53,8 @@ class Problem
void parseObjectSection();
void parseInitialStateSection();
Context &m_context;
Domain &m_domain;
bool m_isDeclared;
@ -57,6 +63,8 @@ class Problem
Requirements m_requirements;
expressions::Constants m_objects;
std::unique_ptr<InitialState> m_initialState;
};
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -27,7 +27,8 @@ class Constant: public Expression
static void parseTypedDeclaration(Context &context, Problem &problem);
static void parseTypedDeclarations(Context &context, Problem &problem);
static Constant *parseAndFind(Context &context, const ExpressionContext &expressionContext);
static Constant *parseAndFind(Context &context, const Domain &domain);
static Constant *parseAndFind(Context &context, const Problem &problem);
public:
void accept(ExpressionVisitor &expressionVisitor) const override;

View File

@ -21,6 +21,7 @@ class Predicate: public Expression
public:
static PredicatePointer parse(std::string name, Context &context,
ExpressionContext &expressionContext);
static PredicatePointer parse(std::string name, Context &context, const Problem &problem);
public:
void accept(ExpressionVisitor &expressionVisitor) const override;

View File

@ -106,12 +106,12 @@ void Description::parseContent()
throw ConsistencyException("No PDDL domain specified");
m_context.parser.seek(m_domainPosition);
m_domain->readPDDL();
m_domain->parse();
if (m_problemPosition != -1)
{
m_context.parser.seek(m_problemPosition);
m_problem->readPDDL();
m_problem->parse();
}
}
@ -119,41 +119,45 @@ void Description::parseContent()
void Description::findSections()
{
while (true)
auto &parser = m_context.parser;
parser.skipWhiteSpace();
while (!parser.atEndOfStream())
{
m_context.parser.skipWhiteSpace();
const auto position = parser.position();
if (m_context.parser.atEndOfStream())
return;
parser.expect<std::string>("(");
parser.expect<std::string>("define");
parser.expect<std::string>("(");
const auto position = m_context.parser.position();
m_context.parser.expect<std::string>("(");
m_context.parser.expect<std::string>("define");
m_context.parser.expect<std::string>("(");
if (m_context.parser.probe<std::string>("domain"))
if (parser.probe<std::string>("domain"))
{
if (m_domainPosition != -1)
throw utils::ParserException(m_context.parser, "PDDL description may not contain two domains");
throw utils::ParserException(parser, "PDDL description may not contain two domains");
m_domainPosition = position;
parser.seek(position);
m_domain->findSections();
}
else if (m_context.parser.probe<std::string>("problem"))
{
if (m_problemPosition != -1)
throw utils::ParserException(m_context.parser, "PDDL description may currently not contain two problems");
throw utils::ParserException(parser, "PDDL description may currently not contain two problems");
m_problemPosition = position;
skipSection(parser);
skipSection(parser);
}
else
{
const auto sectionIdentifier = m_context.parser.parse<std::string>();
throw utils::ParserException(m_context.parser, "Unknown PDDL section \"" + sectionIdentifier + "\"");
const auto sectionIdentifier = parser.parse<std::string>();
throw utils::ParserException(parser, "Unknown PDDL section \"" + sectionIdentifier + "\"");
}
skipSection(m_context.parser);
skipSection(m_context.parser);
m_context.parser.skipWhiteSpace();
}
}

View File

@ -11,6 +11,7 @@
#include <plasp/pddl/expressions/Variable.h>
#include <plasp/utils/IO.h>
#include <plasp/utils/ParserException.h>
#include <plasp/utils/ParserWarning.h>
namespace plasp
{
@ -24,33 +25,127 @@ namespace pddl
////////////////////////////////////////////////////////////////////////////////////////////////////
Domain::Domain(Context &context)
: m_context(context)
: m_context(context),
m_requirementsPosition{-1},
m_typesPosition{-1},
m_constantsPosition{-1},
m_predicatesPosition{-1}
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::readPDDL()
void Domain::findSections()
{
m_context.parser.expect<std::string>("(");
m_context.parser.expect<std::string>("define");
m_context.parser.expect<std::string>("(");
m_context.parser.expect<std::string>("domain");
auto &parser = m_context.parser;
parser.expect<std::string>("(");
parser.expect<std::string>("define");
parser.expect<std::string>("(");
parser.expect<std::string>("domain");
m_name = m_context.parser.parseIdentifier(isIdentifier);
std::cout << "Found domain " << m_name << std::endl;
parser.expect<std::string>(")");
const auto setSectionPosition =
[&](const std::string &sectionName, auto &sectionPosition, const auto value, bool unique = false)
{
if (unique && sectionPosition != -1)
throw utils::ParserException(parser, "Only one \":" + sectionName + "\" section allowed");
sectionPosition = value;
};
parser.skipWhiteSpace();
// Find sections
while (parser.currentCharacter() != ')')
{
const auto position = parser.position();
parser.expect<std::string>("(");
parser.expect<std::string>(":");
// Save the parser position of the individual sections for later parsing
if (parser.probe<std::string>("requirements"))
setSectionPosition("requirements", m_requirementsPosition, position, true);
else if (parser.probe<std::string>("types"))
setSectionPosition("types", m_typesPosition, position, true);
else if (parser.probe<std::string>("constants"))
setSectionPosition("constants", m_constantsPosition, position, true);
else if (parser.probe<std::string>("predicates"))
setSectionPosition("predicates", m_predicatesPosition, position, true);
else if (parser.probe<std::string>("action"))
{
m_actionPositions.emplace_back(-1);
setSectionPosition("action", m_actionPositions.back(), position);
}
else if (parser.probe<std::string>("functions")
|| parser.probe<std::string>("constraints")
|| parser.probe<std::string>("durative-action")
|| parser.probe<std::string>("derived"))
{
parser.seek(position);
m_context.logger.parserWarning(parser, "Section type currently unsupported");
parser.advance();
}
else
{
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
parser.seek(position);
throw utils::ParserException(m_context.parser, "Unknown domain section \"" + sectionIdentifier + "\"");
}
// Skip section for now and parse it later
skipSection(parser);
parser.skipWhiteSpace();
}
parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parse()
{
auto &parser = m_context.parser;
std::cout << "Parsing domain " << m_name << std::endl;
m_context.parser.expect<std::string>(")");
while (true)
if (m_requirementsPosition != -1)
{
m_context.parser.skipWhiteSpace();
parser.seek(m_requirementsPosition);
parseRequirementSection();
}
if (m_context.parser.probe(')'))
break;
if (m_typesPosition != -1)
{
parser.seek(m_typesPosition);
parseTypeSection();
}
parseSection();
if (m_constantsPosition != -1)
{
parser.seek(m_constantsPosition);
parseConstantSection();
}
if (m_predicatesPosition != -1)
{
parser.seek(m_predicatesPosition);
parsePredicateSection();
}
for (size_t i = 0; i < m_actionPositions.size(); i++)
if (m_actionPositions[i] != -1)
{
parser.seek(m_actionPositions[i]);
parseActionSection();
}
computeDerivedRequirements();
@ -81,14 +176,14 @@ const Requirements &Domain::requirements() const
expressions::PrimitiveTypes &Domain::types()
{
return m_primitiveTypes;
return m_types;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const expressions::PrimitiveTypes &Domain::types() const
{
return m_primitiveTypes;
return m_types;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -109,14 +204,14 @@ const expressions::Constants &Domain::constants() const
expressions::PredicateDeclarations &Domain::predicates()
{
return m_predicateDeclarations;
return m_predicates;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const expressions::PredicateDeclarations &Domain::predicates() const
{
return m_predicateDeclarations;
return m_predicates;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -135,52 +230,21 @@ const std::vector<std::unique_ptr<Action>> &Domain::actions() const
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parseSection()
void Domain::parseRequirementSection()
{
auto &parser = m_context.parser;
parser.expect<std::string>("(");
parser.expect<std::string>(":");
parser.expect<std::string>("requirements");
// TODO: check order of the sections
if (parser.probe<std::string>("requirements"))
parseRequirementSection();
else if (parser.probe<std::string>("types"))
parseTypeSection();
else if (parser.probe<std::string>("constants"))
parseConstantSection();
else if (parser.probe<std::string>("predicates"))
parsePredicateSection();
else if (parser.probe<std::string>("action"))
parseActionSection();
else if (parser.probe<std::string>("functions")
|| parser.probe<std::string>("constraints")
|| parser.probe<std::string>("durative-action")
|| parser.probe<std::string>("derived"))
while (parser.currentCharacter() != ')')
{
std::cout << "Skipping section" << std::endl;
skipSection(m_context.parser);
}
else
{
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
throw utils::ParserException(m_context.parser, "Unknown domain section \"" + sectionIdentifier + "\"");
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parseRequirementSection()
{
m_context.parser.skipWhiteSpace();
while (m_context.parser.currentCharacter() != ')')
{
m_context.parser.expect<std::string>(":");
parser.expect<std::string>(":");
m_requirements.emplace_back(Requirement::parse(m_context));
m_context.parser.skipWhiteSpace();
parser.skipWhiteSpace();
}
// TODO: do this check only once the problem is parsed
@ -188,7 +252,7 @@ void Domain::parseRequirementSection()
if (m_requirements.empty())
m_requirements.emplace_back(Requirement::Type::STRIPS);
m_context.parser.expect<std::string>(")");
parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -258,60 +322,82 @@ void Domain::computeDerivedRequirements()
void Domain::parseTypeSection()
{
auto &parser = m_context.parser;
parser.expect<std::string>("(");
parser.expect<std::string>(":");
parser.expect<std::string>("types");
checkRequirement(Requirement::Type::Typing);
m_context.parser.skipWhiteSpace();
parser.skipWhiteSpace();
// Store types and their parent types
while (!m_context.parser.probe(')'))
while (parser.currentCharacter() != ')')
{
if (m_context.parser.currentCharacter() == '(')
throw utils::ParserException(m_context.parser, "Only primitive types are allowed in type section");
if (parser.currentCharacter() == '(')
throw utils::ParserException(parser, "Only primitive types are allowed in type section");
expressions::PrimitiveType::parseTypedDeclaration(m_context, *this);
m_context.parser.skipWhiteSpace();
parser.skipWhiteSpace();
}
parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parseConstantSection()
{
m_context.parser.skipWhiteSpace();
auto &parser = m_context.parser;
parser.expect<std::string>("(");
parser.expect<std::string>(":");
parser.expect<std::string>("constants");
// Store constants
expressions::Constant::parseTypedDeclarations(m_context, *this);
m_context.parser.expect<std::string>(")");
parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parsePredicateSection()
{
m_context.parser.skipWhiteSpace();
auto &parser = m_context.parser;
parser.expect<std::string>("(");
parser.expect<std::string>(":");
parser.expect<std::string>("predicates");
parser.skipWhiteSpace();
// Store predicates and their arguments
while (m_context.parser.currentCharacter() != ')')
while (parser.currentCharacter() != ')')
{
expressions::PredicateDeclaration::parse(m_context, *this);
m_context.parser.skipWhiteSpace();
parser.skipWhiteSpace();
}
m_context.parser.expect<std::string>(")");
parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parseActionSection()
{
m_context.parser.skipWhiteSpace();
auto &parser = m_context.parser;
parser.expect<std::string>("(");
parser.expect<std::string>(":");
parser.expect<std::string>("action");
Action::parseDeclaration(m_context, *this);
m_context.parser.expect<std::string>(")");
parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -4,6 +4,7 @@
#include <plasp/pddl/Domain.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/IO.h>
#include <plasp/pddl/expressions/And.h>
#include <plasp/pddl/expressions/Imply.h>
#include <plasp/pddl/expressions/Not.h>
@ -33,10 +34,10 @@ ExpressionPointer parsePredicate(Context &context, ExpressionContext &expression
////////////////////////////////////////////////////////////////////////////////////////////////////
[[noreturn]] void throwUnsupported(const utils::Parser &parser,
const std::string &expressionIdentifier)
inline void warnUnsupported(Context &context, const std::string &expressionIdentifier)
{
throw utils::ParserException(parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported in this context");
context.logger.parserWarning(context.parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported in this context");
skipSection(context.parser);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -58,7 +59,9 @@ ExpressionPointer parsePreconditionExpression(Context &context,
else if (expressionIdentifier == "forall"
|| expressionIdentifier == "preference")
{
throwUnsupported(context.parser, expressionIdentifier);
warnUnsupported(context, expressionIdentifier);
return nullptr;
}
else
expression = parseExpressionContent(expressionIdentifier, context, expressionContext);
@ -116,7 +119,9 @@ ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier
|| expressionIdentifier == ">="
|| expressionIdentifier == "<=")
{
throwUnsupported(context.parser, expressionIdentifier);
warnUnsupported(context, expressionIdentifier);
return nullptr;
}
auto &predicateDeclarations = expressionContext.domain.predicates();
@ -132,7 +137,7 @@ ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier
if (match != predicateDeclarations.cend())
return expressions::Predicate::parse(expressionIdentifier, context, expressionContext);
throw utils::ParserException(context.parser, "Expression \"" + expressionIdentifier + "\" not allowed in this context");
throw utils::ParserException(context.parser, "Unknown expression \"" + expressionIdentifier + "\"");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -150,7 +155,9 @@ ExpressionPointer parseEffectExpression(Context &context, ExpressionContext &exp
else if (expressionIdentifier == "forall"
|| expressionIdentifier == "when")
{
throwUnsupported(context.parser, expressionIdentifier);
warnUnsupported(context, expressionIdentifier);
return nullptr;
}
else
expression = parseEffectBodyExpressionContent(expressionIdentifier, context, expressionContext);
@ -177,7 +184,9 @@ ExpressionPointer parseEffectBodyExpressionContent(const std::string &expression
|| expressionIdentifier == "increase"
|| expressionIdentifier == "decrease")
{
throwUnsupported(context.parser, expressionIdentifier);
warnUnsupported(context, expressionIdentifier);
return nullptr;
}
const auto &predicateDeclarations = expressionContext.domain.predicates();

View File

@ -0,0 +1,63 @@
#include <plasp/pddl/InitialState.h>
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/IO.h>
#include <plasp/pddl/expressions/Predicate.h>
#include <plasp/utils/ParserException.h>
namespace plasp
{
namespace pddl
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// InitialState
//
////////////////////////////////////////////////////////////////////////////////////////////////////
inline void warnUnsupported(Context &context, const std::string &expressionIdentifier)
{
context.logger.parserWarning(context.parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported in this context");
skipSection(context.parser);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<InitialState> InitialState::parseDeclaration(Context &context, const Problem &problem)
{
auto initialState = std::make_unique<InitialState>(InitialState());
while (context.parser.currentCharacter() != ')')
{
context.parser.expect<std::string>("(");
ExpressionPointer expression;
const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier);
if (expressionIdentifier == "at"
|| expressionIdentifier == "="
|| expressionIdentifier == "not")
{
warnUnsupported(context, expressionIdentifier);
continue;
}
// If none of the above types apply, the content is a predicate over constants and objects
initialState->m_facts.emplace_back(expressions::Predicate::parse(expressionIdentifier, context, problem));
context.parser.expect<std::string>(")");
context.parser.skipWhiteSpace();
}
return initialState;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@ -29,7 +29,7 @@ Problem::Problem(Context &context, Domain &domain)
////////////////////////////////////////////////////////////////////////////////////////////////////
void Problem::readPDDL()
void Problem::parse()
{
m_context.parser.expect<std::string>("(");
m_context.parser.expect<std::string>("define");
@ -122,8 +122,9 @@ void Problem::parseSection()
parseRequirementSection();
else if (parser.probe<std::string>("objects"))
parseObjectSection();
else if (parser.probe<std::string>("init")
|| parser.probe<std::string>("goal")
else if (parser.probe<std::string>("init"))
parseInitialStateSection();
else if (parser.probe<std::string>("goal")
|| parser.probe<std::string>("constraints")
|| parser.probe<std::string>("metric")
|| parser.probe<std::string>("length"))
@ -255,6 +256,33 @@ void Problem::parseObjectSection()
////////////////////////////////////////////////////////////////////////////////////////////////////
void Problem::parseInitialStateSection()
{
m_initialState = InitialState::parseDeclaration(m_context, *this);
m_context.parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
InitialState &Problem::initialState()
{
BOOST_ASSERT(m_initialState);
return *m_initialState;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const InitialState &Problem::initialState() const
{
BOOST_ASSERT(m_initialState);
return *m_initialState;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Problem::checkConsistency()
{
}

View File

@ -134,24 +134,37 @@ void Constant::parseTypedDeclarations(Context &context, Problem &problem)
////////////////////////////////////////////////////////////////////////////////////////////////////
Constant *Constant::parseAndFind(Context &context, const ExpressionContext &expressionContext)
Constant *Constant::parseAndFind(Context &context, const Domain &domain)
{
context.parser.skipWhiteSpace();
const auto constantName = context.parser.parseIdentifier(isIdentifier);
auto *constant = parseAndFind(constantName, expressionContext.domain.constants());
auto *constant = parseAndFind(constantName, domain.constants());
if (constant != nullptr)
return constant;
throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Constant *Constant::parseAndFind(Context &context, const Problem &problem)
{
context.parser.skipWhiteSpace();
const auto constantName = context.parser.parseIdentifier(isIdentifier);
auto *constant = parseAndFind(constantName, problem.domain().constants());
if (constant)
return constant;
if (expressionContext.problem)
{
constant = parseAndFind(constantName, expressionContext.problem->objects());
constant = parseAndFind(constantName, problem.objects());
if (constant)
return constant;
}
throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared");
}

View File

@ -1,54 +0,0 @@
#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
{
namespace pddl
{
namespace expressions
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// InitialState
//
////////////////////////////////////////////////////////////////////////////////////////////////////
void throwUnsupported(const utils::Parser &parser, const std::string &expressionIdentifier)
{
throw utils::ParserException(parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported in this context");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer parseInitialState(Context &context)
{
context.parser.expect<std::string>("(");
const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier);
ExpressionPointer expression;
if (expressionIdentifier == "at"
|| expressionIdentifier == "=")
{
throwUnsupported(context.parser, expressionIdentifier);
}
// TODO: implement predicate parsing
context.parser.expect<std::string>(")");
return expression;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
}

View File

@ -51,7 +51,9 @@ PredicatePointer Predicate::parse(std::string name, Context &context,
// Parse constants
else
{
const auto *constant = Constant::parseAndFind(context, expressionContext);
const auto *constant = (expressionContext.problem == nullptr)
? Constant::parseAndFind(context, expressionContext.domain)
: Constant::parseAndFind(context, *expressionContext.problem);
auto constantReference = std::make_unique<Reference<Constant>>(constant);
predicate->m_arguments.emplace_back(std::move(constantReference));
}
@ -66,6 +68,32 @@ PredicatePointer Predicate::parse(std::string name, Context &context,
////////////////////////////////////////////////////////////////////////////////////////////////////
PredicatePointer Predicate::parse(std::string name, Context &context, const Problem &problem)
{
auto predicate = std::make_unique<Predicate>(Predicate());
predicate->m_name = name;
context.parser.skipWhiteSpace();
while (context.parser.currentCharacter() != ')')
{
if (context.parser.currentCharacter() == '?')
throw utils::ParserException(context.parser, "Variables not allowed in this context");
// Parse objects and constants
const auto *constant = Constant::parseAndFind(context, problem);
auto constantReference = std::make_unique<Reference<Constant>>(constant);
predicate->m_arguments.emplace_back(std::move(constantReference));
}
// TODO: check that signature matches one of the declared ones
return predicate;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Predicate::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const
{
expressionVisitor.visit(*this);