Implemented variable stack for parsing nested variable lists (as within quantified expressions).

This commit is contained in:
Patrick Lühne 2016-09-06 17:34:07 +02:00
parent f4f0e07bc1
commit eb28ed3938
10 changed files with 111 additions and 47 deletions

View File

@ -3,6 +3,7 @@
#include <plasp/pddl/Expression.h> #include <plasp/pddl/Expression.h>
#include <plasp/pddl/Requirement.h> #include <plasp/pddl/Requirement.h>
#include <plasp/pddl/VariableStack.h>
namespace plasp namespace plasp
{ {
@ -18,8 +19,8 @@ namespace pddl
class ExpressionContext class ExpressionContext
{ {
public: public:
ExpressionContext(Domain &domain, expressions::Variables &parameters); ExpressionContext(Domain &domain);
ExpressionContext(Domain &domain, Problem *problem, expressions::Variables &parameters); ExpressionContext(Domain &domain, Problem *problem);
bool hasRequirement(Requirement::Type requirementType) const; bool hasRequirement(Requirement::Type requirementType) const;
void checkRequirement(Requirement::Type requirementType) const; void checkRequirement(Requirement::Type requirementType) const;
@ -27,7 +28,7 @@ class ExpressionContext
Domain &domain; Domain &domain;
Problem *problem; Problem *problem;
expressions::Variables &parameters; VariableStack variables;
}; };
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,34 @@
#ifndef __PLASP__PDDL__VARIABLE_STACK_H
#define __PLASP__PDDL__VARIABLE_STACK_H
#include <plasp/pddl/expressions/Variable.h>
namespace plasp
{
namespace pddl
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// VariableStack
//
////////////////////////////////////////////////////////////////////////////////////////////////////
class VariableStack
{
public:
void push(expressions::Variables *variables);
void pop();
expressions::VariablePointer parseAndFind(Context &context);
private:
std::vector<expressions::Variables *> m_variableStack;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@ -26,9 +26,6 @@ class Variable: public ExpressionCRTP<Variable>
static void parseTypedDeclarations(Context &context, ExpressionContext &expressionContext, static void parseTypedDeclarations(Context &context, ExpressionContext &expressionContext,
Variables &variables); Variables &variables);
static VariablePointer parseAndFind(Context &context,
const ExpressionContext &expressionContext);
public: public:
void setName(std::string name); void setName(std::string name);
const std::string &name() const; const std::string &name() const;

View File

@ -29,7 +29,8 @@ void Action::parseDeclaration(Context &context, Domain &domain)
parser.expect<std::string>(":parameters"); parser.expect<std::string>(":parameters");
parser.expect<std::string>("("); parser.expect<std::string>("(");
ExpressionContext expressionContext(domain, action->m_parameters); ExpressionContext expressionContext(domain);
expressionContext.variables.push(&action->m_parameters);
// Read parameters // Read parameters
expressions::Variable::parseTypedDeclarations(context, expressionContext, action->m_parameters); expressions::Variable::parseTypedDeclarations(context, expressionContext, action->m_parameters);

View File

@ -14,19 +14,17 @@ namespace pddl
// //
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionContext::ExpressionContext(Domain &domain, expressions::Variables &parameters) ExpressionContext::ExpressionContext(Domain &domain)
: domain(domain), : domain(domain),
problem(nullptr), problem(nullptr)
parameters(parameters)
{ {
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionContext::ExpressionContext(Domain &domain, Problem *problem, expressions::Variables &parameters) ExpressionContext::ExpressionContext(Domain &domain, Problem *problem)
: domain(domain), : domain(domain),
problem{problem}, problem{problem}
parameters(parameters)
{ {
} }

View File

@ -333,9 +333,7 @@ void Problem::parseInitialStateSection()
parser.expect<std::string>(":"); parser.expect<std::string>(":");
parser.expect<std::string>("init"); parser.expect<std::string>("init");
// TODO: remove workaround ExpressionContext expressionContext(m_domain, this);
expressions::Variables noParameters;
ExpressionContext expressionContext(m_domain, this, noParameters);
m_initialState = InitialState::parseDeclaration(m_context, expressionContext); m_initialState = InitialState::parseDeclaration(m_context, expressionContext);
@ -352,9 +350,7 @@ void Problem::parseGoalSection()
parser.expect<std::string>(":"); parser.expect<std::string>(":");
parser.expect<std::string>("goal"); parser.expect<std::string>("goal");
// TODO: remove workaround ExpressionContext expressionContext(m_domain, this);
expressions::Variables noParameters;
ExpressionContext expressionContext(m_domain, this, noParameters);
m_goal = parsePreconditionExpression(m_context, expressionContext); m_goal = parsePreconditionExpression(m_context, expressionContext);

View File

@ -0,0 +1,62 @@
#include <plasp/pddl/VariableStack.h>
#include <plasp/pddl/Context.h>
namespace plasp
{
namespace pddl
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// VariableStack
//
////////////////////////////////////////////////////////////////////////////////////////////////////
void VariableStack::push(expressions::Variables *variables)
{
m_variableStack.push_back(variables);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void VariableStack::pop()
{
m_variableStack.pop_back();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
expressions::VariablePointer VariableStack::parseAndFind(plasp::pddl::Context &context)
{
auto &parser = context.parser;
parser.skipWhiteSpace();
parser.expect<std::string>("?");
const auto variableName = parser.parseIdentifier();
for (auto i = m_variableStack.crbegin(); i != m_variableStack.crend(); i++)
{
const auto *variables = *i;
BOOST_ASSERT(variables);
const auto match = std::find_if(variables->crbegin(), variables->crend(),
[&](const auto &variable)
{
return variable->name() == variableName;
});
if (match != variables->crend())
return match->get();
}
throw utils::ParserException(parser.coordinate(), "variable “" + variableName + "” used but never declared");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@ -66,7 +66,7 @@ PredicatePointer Predicate::parse(Context &context, ExpressionContext &expressio
// Parse variables // Parse variables
if (context.parser.currentCharacter() == '?') if (context.parser.currentCharacter() == '?')
{ {
const auto variable = Variable::parseAndFind(context, expressionContext); const auto variable = expressionContext.variables.parseAndFind(context);
predicate->m_arguments.emplace_back(variable); predicate->m_arguments.emplace_back(variable);
} }
// Parse constants // Parse constants

View File

@ -39,7 +39,8 @@ void PredicateDeclaration::parse(Context &context, Domain &domain)
context.parser.skipWhiteSpace(); context.parser.skipWhiteSpace();
ExpressionContext expressionContext(domain, predicate->m_parameters); ExpressionContext expressionContext(domain);
expressionContext.variables.push(&predicate->m_parameters);
// Parse arguments // Parse arguments
expressions::Variable::parseTypedDeclarations(context, expressionContext, predicate->m_parameters); expressions::Variable::parseTypedDeclarations(context, expressionContext, predicate->m_parameters);

View File

@ -136,32 +136,6 @@ void Variable::parseTypedDeclarations(Context &context, ExpressionContext &expre
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
VariablePointer Variable::parseAndFind(Context &context, const ExpressionContext &expressionContext)
{
auto &parser = context.parser;
parser.skipWhiteSpace();
parser.expect<std::string>("?");
const auto variableName = parser.parseIdentifier();
const auto &variables = expressionContext.parameters;
const auto match = std::find_if(variables.cbegin(), variables.cend(),
[&](const auto &variable)
{
return variable->name() == variableName;
});
if (match == variables.cend())
throw utils::ParserException(parser.coordinate(), "parameter “" + variableName + "” used but never declared");
return match->get();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Variable::setName(std::string name) void Variable::setName(std::string name)
{ {
m_name = name; m_name = name;