Implemented variable type requirement checking.
This commit is contained in:
parent
75fbb5fb48
commit
7bd2782fc8
@ -36,16 +36,11 @@ class PrimitiveType: public Expression
|
|||||||
const std::string &name() const;
|
const std::string &name() const;
|
||||||
const std::vector<const PrimitiveType *> &parentTypes() const;
|
const std::vector<const PrimitiveType *> &parentTypes() const;
|
||||||
|
|
||||||
bool isDeclared() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setDirty(bool isDirty = true);
|
void setDirty(bool isDirty = true);
|
||||||
bool isDirty() const;
|
bool isDirty() const;
|
||||||
|
|
||||||
void setDeclared();
|
|
||||||
|
|
||||||
bool m_isDirty;
|
bool m_isDirty;
|
||||||
bool m_isDeclared;
|
|
||||||
|
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
|
|
||||||
|
@ -20,8 +20,10 @@ class Variable: public Expression
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void parseTypedDeclaration(Context &context, ExpressionContext &expressionContext);
|
static void parseTypedDeclaration(Context &context, ExpressionContext &expressionContext);
|
||||||
|
static void parseTypedDeclarations(Context &context, ExpressionContext &expressionContext);
|
||||||
|
|
||||||
static const Variable *parseAndFind(Context &context, const ExpressionContext &expressionContext);
|
static const Variable *parseAndFind(Context &context,
|
||||||
|
const ExpressionContext &expressionContext);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void accept(ExpressionVisitor &expressionVisitor) const override;
|
void accept(ExpressionVisitor &expressionVisitor) const override;
|
||||||
|
@ -40,12 +40,7 @@ void Action::parseDeclaration(Context &context, Domain &domain)
|
|||||||
ExpressionContext expressionContext(domain, action->m_parameters);
|
ExpressionContext expressionContext(domain, action->m_parameters);
|
||||||
|
|
||||||
// Read parameters
|
// Read parameters
|
||||||
while (context.parser.currentCharacter() != ')')
|
expressions::Variable::parseTypedDeclarations(context, expressionContext);
|
||||||
{
|
|
||||||
expressions::Variable::parseTypedDeclaration(context, expressionContext);
|
|
||||||
|
|
||||||
context.parser.skipWhiteSpace();
|
|
||||||
}
|
|
||||||
|
|
||||||
context.parser.expect<std::string>(")");
|
context.parser.expect<std::string>(")");
|
||||||
|
|
||||||
|
@ -111,8 +111,6 @@ void Description::findSections()
|
|||||||
|
|
||||||
if (m_context.parser.probe<std::string>("domain"))
|
if (m_context.parser.probe<std::string>("domain"))
|
||||||
{
|
{
|
||||||
std::cout << "Found domain at " << position << std::endl;
|
|
||||||
|
|
||||||
if (m_domainPosition != -1)
|
if (m_domainPosition != -1)
|
||||||
throw utils::ParserException(m_context.parser, "PDDL description may not contain two domains");
|
throw utils::ParserException(m_context.parser, "PDDL description may not contain two domains");
|
||||||
|
|
||||||
|
@ -315,52 +315,6 @@ void Domain::parseActionSection()
|
|||||||
|
|
||||||
void Domain::checkConsistency()
|
void Domain::checkConsistency()
|
||||||
{
|
{
|
||||||
// TODO: implement requirement declaration checking
|
|
||||||
|
|
||||||
// Verify that typing requirement is correctly declared if used
|
|
||||||
if (!m_primitiveTypes.empty() && !hasRequirement(Requirement::Type::Typing))
|
|
||||||
{
|
|
||||||
m_context.logger.parserWarning(m_context.parser, "Domain contains typing information but does not declare typing requirement");
|
|
||||||
|
|
||||||
m_requirements.push_back(Requirement(Requirement::Type::Typing));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that all variables and constants have types if and only if typing enabled
|
|
||||||
if (hasRequirement(Requirement::Type::Typing))
|
|
||||||
{
|
|
||||||
const auto acceptType =
|
|
||||||
[&](const auto *type)
|
|
||||||
{
|
|
||||||
return ((type == nullptr) != this->hasRequirement(Requirement::Type::Typing));
|
|
||||||
};
|
|
||||||
|
|
||||||
std::for_each(m_constants.cbegin(), m_constants.cend(),
|
|
||||||
[&](const auto &constant)
|
|
||||||
{
|
|
||||||
if (!acceptType(constant->type()))
|
|
||||||
throw ConsistencyException("Constant \"" + constant->name() + "\" has no type");
|
|
||||||
});
|
|
||||||
|
|
||||||
std::for_each(m_predicateDeclarations.cbegin(), m_predicateDeclarations.cend(),
|
|
||||||
[&](const auto &predicateDeclaration)
|
|
||||||
{
|
|
||||||
std::for_each(predicateDeclaration->arguments().cbegin(), predicateDeclaration->arguments().cend(),
|
|
||||||
[&](const auto &argument)
|
|
||||||
{
|
|
||||||
if (!acceptType(argument->type()))
|
|
||||||
throw ConsistencyException("Variable \"" + argument->name() + "\" has no type");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that all used types have been declared
|
|
||||||
std::for_each(m_primitiveTypes.cbegin(), m_primitiveTypes.cend(),
|
|
||||||
[&](const auto &type)
|
|
||||||
{
|
|
||||||
if (!type->isDeclared())
|
|
||||||
throw ConsistencyException("Type \"" + type->name() + "\" used but never declared");
|
|
||||||
});
|
|
||||||
|
|
||||||
// Verify that all used constants have been declared
|
// Verify that all used constants have been declared
|
||||||
std::for_each(m_constants.cbegin(), m_constants.cend(),
|
std::for_each(m_constants.cbegin(), m_constants.cend(),
|
||||||
[&](const auto &constant)
|
[&](const auto &constant)
|
||||||
|
@ -45,12 +45,7 @@ void PredicateDeclaration::parse(Context &context, Domain &domain)
|
|||||||
ExpressionContext expressionContext(domain, predicate->m_parameters);
|
ExpressionContext expressionContext(domain, predicate->m_parameters);
|
||||||
|
|
||||||
// Parse arguments
|
// Parse arguments
|
||||||
while (context.parser.currentCharacter() != ')')
|
expressions::Variable::parseTypedDeclarations(context, expressionContext);
|
||||||
{
|
|
||||||
expressions::Variable::parseTypedDeclaration(context, expressionContext);
|
|
||||||
|
|
||||||
context.parser.skipWhiteSpace();
|
|
||||||
}
|
|
||||||
|
|
||||||
context.parser.expect<std::string>(")");
|
context.parser.expect<std::string>(")");
|
||||||
|
|
||||||
|
@ -23,8 +23,7 @@ namespace expressions
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
PrimitiveType::PrimitiveType()
|
PrimitiveType::PrimitiveType()
|
||||||
: m_isDirty{true},
|
: m_isDirty{true}
|
||||||
m_isDeclared{false}
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,7 +31,6 @@ PrimitiveType::PrimitiveType()
|
|||||||
|
|
||||||
PrimitiveType::PrimitiveType(std::string name)
|
PrimitiveType::PrimitiveType(std::string name)
|
||||||
: m_isDirty{true},
|
: m_isDirty{true},
|
||||||
m_isDeclared{false},
|
|
||||||
m_name{name}
|
m_name{name}
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!m_name.empty());
|
BOOST_ASSERT(!m_name.empty());
|
||||||
@ -61,13 +59,11 @@ void PrimitiveType::parseDeclaration(Context &context, Domain &domain)
|
|||||||
auto *type = match->get();
|
auto *type = match->get();
|
||||||
|
|
||||||
type->setDirty();
|
type->setDirty();
|
||||||
type->setDeclared();
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
types.emplace_back(std::make_unique<PrimitiveType>(typeName));
|
types.emplace_back(std::make_unique<PrimitiveType>(typeName));
|
||||||
types.back()->setDeclared();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -93,9 +89,6 @@ void PrimitiveType::parseTypedDeclaration(Context &context, Domain &domain)
|
|||||||
|
|
||||||
parentType->setDirty(false);
|
parentType->setDirty(false);
|
||||||
|
|
||||||
// Flag parent tpe as correctly declared in the types section
|
|
||||||
parentType->setDeclared();
|
|
||||||
|
|
||||||
// Assign parent type to all types that were previously flagged
|
// Assign parent type to all types that were previously flagged
|
||||||
std::for_each(types.begin(), types.end(),
|
std::for_each(types.begin(), types.end(),
|
||||||
[&](auto &childType)
|
[&](auto &childType)
|
||||||
@ -164,20 +157,6 @@ bool PrimitiveType::isDirty() const
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void PrimitiveType::setDeclared()
|
|
||||||
{
|
|
||||||
m_isDeclared = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool PrimitiveType::isDeclared() const
|
|
||||||
{
|
|
||||||
return m_isDeclared;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
const std::string &PrimitiveType::name() const
|
const std::string &PrimitiveType::name() const
|
||||||
{
|
{
|
||||||
return m_name;
|
return m_name;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
#include <plasp/pddl/Context.h>
|
#include <plasp/pddl/Context.h>
|
||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
#include <plasp/pddl/ExpressionContext.h>
|
#include <plasp/pddl/ExpressionContext.h>
|
||||||
#include <plasp/pddl/ExpressionVisitor.h>
|
#include <plasp/pddl/ExpressionVisitor.h>
|
||||||
#include <plasp/pddl/Identifier.h>
|
#include <plasp/pddl/Identifier.h>
|
||||||
@ -67,8 +68,6 @@ void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expres
|
|||||||
if (!context.parser.probe('-'))
|
if (!context.parser.probe('-'))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO: do not allow nested either expressions
|
|
||||||
|
|
||||||
const auto setType =
|
const auto setType =
|
||||||
[&](const auto *type)
|
[&](const auto *type)
|
||||||
{
|
{
|
||||||
@ -108,6 +107,27 @@ void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expres
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Variable::parseTypedDeclarations(Context &context, ExpressionContext &expressionContext)
|
||||||
|
{
|
||||||
|
while (context.parser.currentCharacter() != ')')
|
||||||
|
parseTypedDeclaration(context, expressionContext);
|
||||||
|
|
||||||
|
if (expressionContext.parameters.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check correct use of typing requirement
|
||||||
|
const auto typingUsed = (expressionContext.parameters.back()->type() != nullptr);
|
||||||
|
const auto typingDeclared = expressionContext.domain.hasRequirement(Requirement::Type::Typing);
|
||||||
|
|
||||||
|
if (!typingUsed && typingDeclared)
|
||||||
|
throw utils::ParserException(context.parser, "Object has undeclared type");
|
||||||
|
|
||||||
|
if (typingUsed && !typingDeclared)
|
||||||
|
throw utils::ParserException(context.parser, "Typing used but not declared as a requirement");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
const Variable *Variable::parseAndFind(Context &context, const ExpressionContext &expressionContext)
|
const Variable *Variable::parseAndFind(Context &context, const ExpressionContext &expressionContext)
|
||||||
{
|
{
|
||||||
context.parser.skipWhiteSpace();
|
context.parser.skipWhiteSpace();
|
||||||
|
@ -255,10 +255,10 @@ bool Parser::probe<std::string>(const std::string &expectedValue)
|
|||||||
{
|
{
|
||||||
BOOST_ASSERT(!std::isspace(expectedValue[0]));
|
BOOST_ASSERT(!std::isspace(expectedValue[0]));
|
||||||
|
|
||||||
skipWhiteSpace();
|
|
||||||
|
|
||||||
const auto previousPosition = position();
|
const auto previousPosition = position();
|
||||||
|
|
||||||
|
skipWhiteSpace();
|
||||||
|
|
||||||
const auto match = std::find_if(expectedValue.cbegin(), expectedValue.cend(),
|
const auto match = std::find_if(expectedValue.cbegin(), expectedValue.cend(),
|
||||||
[&](const auto &expectedCharacter)
|
[&](const auto &expectedCharacter)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user