Implemented At expressions.

This commit is contained in:
Patrick Lühne 2016-06-13 19:02:15 +02:00
parent da85e5dd9b
commit 4b500e4bf6
10 changed files with 243 additions and 9 deletions

View File

@ -31,6 +31,9 @@ namespace expressions
class And; class And;
using AndPointer = std::unique_ptr<And>; using AndPointer = std::unique_ptr<And>;
class At;
using AtPointer = std::unique_ptr<At>;
class Constant; class Constant;
using ConstantPointer = std::unique_ptr<Constant>; using ConstantPointer = std::unique_ptr<Constant>;
using Constants = std::vector<ConstantPointer>; using Constants = std::vector<ConstantPointer>;
@ -72,6 +75,7 @@ class Expression
enum class Type enum class Type
{ {
And, And,
At,
Binary, Binary,
Constant, Constant,
Either, Either,
@ -104,6 +108,9 @@ class ExpressionCRTP: public Expression
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer parseLiteral(Context &context, ExpressionContext &expressionContext);
ExpressionPointer parseAtomicFormula(Context &context, ExpressionContext &expressionContext);
ExpressionPointer parsePreconditionExpression(Context &context, ExpressionPointer parsePreconditionExpression(Context &context,
ExpressionContext &expressionContext); ExpressionContext &expressionContext);
ExpressionPointer parseExpression(Context &context, ExpressionContext &expressionContext); ExpressionPointer parseExpression(Context &context, ExpressionContext &expressionContext);

View File

@ -17,7 +17,8 @@ namespace pddl
class InitialState class InitialState
{ {
public: public:
static std::unique_ptr<InitialState> parseDeclaration(Context &context, const Problem &problem); static std::unique_ptr<InitialState> parseDeclaration(Context &context,
ExpressionContext &expressionContext);
public: public:
const Expressions &facts() const; const Expressions &facts() const;

View File

@ -0,0 +1,104 @@
#ifndef __PLASP__PDDL__EXPRESSIONS__AT_H
#define __PLASP__PDDL__EXPRESSIONS__AT_H
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Expression.h>
#include <plasp/pddl/Identifier.h>
namespace plasp
{
namespace pddl
{
namespace expressions
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// At
//
////////////////////////////////////////////////////////////////////////////////////////////////////
class At: public ExpressionCRTP<At>
{
public:
static const Expression::Type ExpressionType = Expression::Type::At;
template<typename ExpressionParser>
static AtPointer parse(Context &context, ExpressionContext &expressionContext,
ExpressionParser parseExpression);
static const size_t TimePointStart = std::numeric_limits<size_t>::max();
static const size_t TimePointEnd = std::numeric_limits<size_t>::max() - 1;
public:
At();
size_t timePoint() const;
const Expression *argument() const;
private:
void setArgument(const Expression *argument);
void setArgument(ExpressionPointer &&argument);
size_t m_timePoint;
const Expression *m_argument;
ExpressionPointer m_argumentStorage;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename ExpressionParser>
AtPointer At::parse(Context &context, ExpressionContext &expressionContext,
ExpressionParser parseExpression)
{
auto &parser = context.parser;
const auto position = parser.position();
if (!parser.probe<std::string>("(")
|| !parser.probeIdentifier("at", isIdentifier))
{
parser.seek(position);
return nullptr;
}
size_t timePoint;
const auto timePointPosition = parser.position();
if (parser.probeIdentifier("start", isIdentifier))
timePoint = TimePointStart;
else if (parser.probeIdentifier("end", isIdentifier))
timePoint = TimePointEnd;
else if (parser.probeNumber())
{
parser.seek(timePointPosition);
timePoint = parser.parse<size_t>();
}
else
{
parser.seek(position);
return nullptr;
}
auto expression = std::make_unique<At>(At());
context.parser.skipWhiteSpace();
// Parse argument
expression->setArgument(parseExpression(context, expressionContext));
parser.expect<std::string>(")");
return expression;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
}
#endif

View File

@ -79,6 +79,8 @@ class Parser
template<class CharacterPredicate> template<class CharacterPredicate>
bool probeIdentifier(const std::string &identifier, CharacterPredicate characterPredicate); bool probeIdentifier(const std::string &identifier, CharacterPredicate characterPredicate);
bool probeNumber();
template<typename Type> template<typename Type>
void expect(const Type &expectedValue); void expect(const Type &expectedValue);

View File

@ -229,5 +229,54 @@ ExpressionPointer parsePredicate(Context &context, ExpressionContext &expression
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer parseLiteral(Context &context, ExpressionContext &expressionContext)
{
ExpressionPointer expression;
if ((expression = parseAtomicFormula(context, expressionContext))
|| (expression = expressions::Not::parse(context, expressionContext, parseAtomicFormula)))
{
return expression;
}
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer parseAtomicFormula(Context &context, ExpressionContext &expressionContext)
{
auto &parser = context.parser;
ExpressionPointer expression;
if ((expression = expressions::Predicate::parse(context, expressionContext)))
return expression;
const auto position = parser.position();
parser.expect<std::string>("(");
const auto expressionIdentifierPosition = parser.position();
if (parser.probeIdentifier("=", isIdentifier))
{
parser.seek(expressionIdentifierPosition);
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
parser.seek(position);
warnUnsupported(context, expressionIdentifier);
parser.seek(expressionIdentifierPosition);
skipSection(parser);
return nullptr;
}
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
} }
} }

View File

@ -1,8 +1,11 @@
#include <plasp/pddl/InitialState.h> #include <plasp/pddl/InitialState.h>
#include <plasp/pddl/Context.h> #include <plasp/pddl/Context.h>
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/Identifier.h> #include <plasp/pddl/Identifier.h>
#include <plasp/pddl/IO.h> #include <plasp/pddl/IO.h>
#include <plasp/pddl/Problem.h>
#include <plasp/pddl/expressions/At.h>
#include <plasp/pddl/expressions/Predicate.h> #include <plasp/pddl/expressions/Predicate.h>
#include <plasp/utils/ParserException.h> #include <plasp/utils/ParserException.h>
@ -24,7 +27,8 @@ inline void warnUnsupported(Context &context, const std::string &expressionIdent
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<InitialState> InitialState::parseDeclaration(Context &context, const Problem &problem) std::unique_ptr<InitialState> InitialState::parseDeclaration(Context &context,
ExpressionContext &expressionContext)
{ {
auto &parser = context.parser; auto &parser = context.parser;
@ -35,8 +39,12 @@ std::unique_ptr<InitialState> InitialState::parseDeclaration(Context &context, c
{ {
ExpressionPointer expression; ExpressionPointer expression;
if ((expression = expressions::Predicate::parse(context, problem))) // TODO: do not allow negative initial state literals
if ((expression = parseLiteral(context, expressionContext))
|| (expression = expressions::At::parse(context, expressionContext, parseLiteral)))
{
return expression; return expression;
}
const auto position = parser.position(); const auto position = parser.position();
@ -44,9 +52,7 @@ std::unique_ptr<InitialState> InitialState::parseDeclaration(Context &context, c
const auto expressionIdentifierPosition = parser.position(); const auto expressionIdentifierPosition = parser.position();
if (parser.probeIdentifier("at", isIdentifier) if (parser.probeIdentifier("=", isIdentifier))
|| parser.probeIdentifier("=", isIdentifier)
|| parser.probeIdentifier("not", isIdentifier))
{ {
parser.seek(expressionIdentifierPosition); parser.seek(expressionIdentifierPosition);
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier); const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);

View File

@ -332,7 +332,11 @@ void Problem::parseInitialStateSection()
parser.expect<std::string>(":"); parser.expect<std::string>(":");
parser.expect<std::string>("init"); parser.expect<std::string>("init");
m_initialState = InitialState::parseDeclaration(m_context, *this); // TODO: remove workaround
expressions::Variables noParameters;
ExpressionContext expressionContext(m_domain, this, noParameters);
m_initialState = InitialState::parseDeclaration(m_context, expressionContext);
parser.expect<std::string>(")"); parser.expect<std::string>(")");
} }
@ -349,7 +353,6 @@ void Problem::parseGoalSection()
// TODO: remove workaround // TODO: remove workaround
expressions::Variables noParameters; expressions::Variables noParameters;
ExpressionContext expressionContext(m_domain, this, noParameters); ExpressionContext expressionContext(m_domain, this, noParameters);
m_goal = parsePreconditionExpression(m_context, expressionContext); m_goal = parsePreconditionExpression(m_context, expressionContext);

View File

@ -84,8 +84,11 @@ void TranslatorASP::checkSupport() const
std::for_each(preconditionArguments.cbegin(), preconditionArguments.cend(), std::for_each(preconditionArguments.cbegin(), preconditionArguments.cend(),
[&](const auto &argument) [&](const auto &argument)
{ {
if (argument->expressionType() != Expression::Type::Predicate) if (argument->expressionType() != Expression::Type::Predicate
&& argument->expressionType() != Expression::Type::Not)
{
throw utils::TranslatorException("Only predicates supported in preconditions currently"); throw utils::TranslatorException("Only predicates supported in preconditions currently");
}
}); });
} }
} }

View File

@ -0,0 +1,48 @@
#include <plasp/pddl/expressions/At.h>
namespace plasp
{
namespace pddl
{
namespace expressions
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// At
//
////////////////////////////////////////////////////////////////////////////////////////////////////
At::At()
: m_argument{nullptr}
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void At::setArgument(const Expression *argument)
{
m_argumentStorage = nullptr;
m_argument = argument;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void At::setArgument(ExpressionPointer &&argument)
{
m_argumentStorage = std::move(argument);
m_argument = m_argumentStorage.get();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const Expression *At::argument() const
{
return m_argument;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
}

View File

@ -528,6 +528,17 @@ void Parser::expect<bool>(const bool &expectedValue)
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
bool Parser::probeNumber()
{
while (!std::iswspace(currentCharacter()))
if (!std::isdigit(currentCharacter()))
return false;
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Parser::removeComments(const std::string &startSequence, const std::string &endSequence, bool removeEnd) void Parser::removeComments(const std::string &startSequence, const std::string &endSequence, bool removeEnd)
{ {
const auto inPosition = m_stream.tellg(); const auto inPosition = m_stream.tellg();