Implemented early checking for typing requirement in Variables and Constants.

This commit is contained in:
Patrick Lühne 2016-06-08 12:51:39 +02:00
parent e60af33f75
commit 75e51c856e
7 changed files with 82 additions and 44 deletions

View File

@ -18,19 +18,11 @@ namespace pddl
class ExpressionContext class ExpressionContext
{ {
public: public:
ExpressionContext(Domain &domain, expressions::Variables &parameters) ExpressionContext(Domain &domain, expressions::Variables &parameters);
: domain(domain), ExpressionContext(Domain &domain, Problem *problem, expressions::Variables &parameters);
problem(nullptr),
parameters(parameters)
{
}
ExpressionContext(Domain &domain, Problem *problem, expressions::Variables &parameters) bool hasRequirement(Requirement::Type requirementType) const;
: domain(domain), void checkRequirement(Requirement::Type requirementType) const;
problem{problem},
parameters(parameters)
{
}
Domain &domain; Domain &domain;
Problem *problem; Problem *problem;

View File

@ -258,8 +258,7 @@ void Domain::computeDerivedRequirements()
void Domain::parseTypeSection() void Domain::parseTypeSection()
{ {
if (!hasRequirement(Requirement::Type::Typing)) checkRequirement(Requirement::Type::Typing);
throw utils::ParserException(m_context.parser, "Typing used but not declared as a requirement");
m_context.parser.skipWhiteSpace(); m_context.parser.skipWhiteSpace();

View File

@ -0,0 +1,56 @@
#include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/Domain.h>
#include <plasp/pddl/Problem.h>
namespace plasp
{
namespace pddl
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// ExpressionContext
//
////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionContext::ExpressionContext(Domain &domain, expressions::Variables &parameters)
: domain(domain),
problem(nullptr),
parameters(parameters)
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionContext::ExpressionContext(Domain &domain, Problem *problem, expressions::Variables &parameters)
: domain(domain),
problem{problem},
parameters(parameters)
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
bool ExpressionContext::hasRequirement(Requirement::Type requirementType) const
{
if (problem != nullptr)
return problem->hasRequirement(requirementType);
return domain.hasRequirement(requirementType);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void ExpressionContext::checkRequirement(Requirement::Type requirementType) const
{
if (problem != nullptr)
problem->checkRequirement(requirementType);
else
domain.checkRequirement(requirementType);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@ -185,15 +185,16 @@ bool Problem::hasRequirement(Requirement::Type requirementType) const
return requirement.type() == requirementType; return requirement.type() == requirementType;
}); });
return match != m_requirements.cend(); if (match != m_requirements.cend())
return true;
return m_domain.hasRequirement(requirementType);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
void Problem::checkRequirement(Requirement::Type requirementType) const void Problem::checkRequirement(Requirement::Type requirementType) const
{ {
m_domain.checkRequirement(requirementType);
if (hasRequirement(requirementType)) if (hasRequirement(requirementType))
return; return;
@ -256,14 +257,6 @@ void Problem::parseObjectSection()
void Problem::checkConsistency() void Problem::checkConsistency()
{ {
// Verify that all objects have types
if (hasRequirement(Requirement::Type::Typing) || m_domain.hasRequirement(Requirement::Type::Typing))
std::for_each(m_objects.cbegin(), m_objects.cend(),
[&](const auto &constant)
{
if (constant->type() == nullptr)
throw ConsistencyException("Object \"" + constant->name() + "\" has no type");
});
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -102,13 +102,13 @@ void Constant::parseTypedDeclarations(Context &context, Domain &domain)
// Check correct use of typing requirement // Check correct use of typing requirement
const auto typingUsed = (domain.constants().back()->type() != nullptr); const auto typingUsed = (domain.constants().back()->type() != nullptr);
const auto typingDeclared = domain.hasRequirement(Requirement::Type::Typing);
if (!typingUsed && typingDeclared) // If types are given, check that typing is a requirement
if (typingUsed)
domain.checkRequirement(Requirement::Type::Typing);
// If no types are given, check that typing is not a requirement
else if (domain.hasRequirement(Requirement::Type::Typing))
throw utils::ParserException(context.parser, "Constant has undeclared type"); throw utils::ParserException(context.parser, "Constant has undeclared type");
if (typingUsed && !typingDeclared)
throw utils::ParserException(context.parser, "Typing used but not declared as a requirement");
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
@ -123,14 +123,13 @@ void Constant::parseTypedDeclarations(Context &context, Problem &problem)
// Check correct use of typing requirement // Check correct use of typing requirement
const auto typingUsed = (problem.objects().back()->type() != nullptr); const auto typingUsed = (problem.objects().back()->type() != nullptr);
const auto typingDeclared = problem.domain().hasRequirement(Requirement::Type::Typing)
|| problem.hasRequirement(Requirement::Type::Typing);
if (!typingUsed && typingDeclared) // If types are given, check that typing is a requirement
if (typingUsed)
problem.checkRequirement(Requirement::Type::Typing);
// If no types are given, check that typing is not a requirement
else if (problem.hasRequirement(Requirement::Type::Typing))
throw utils::ParserException(context.parser, "Constant has undeclared type"); throw utils::ParserException(context.parser, "Constant has undeclared type");
if (typingUsed && !typingDeclared)
throw utils::ParserException(context.parser, "Typing used but not declared as a requirement");
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -80,8 +80,7 @@ void PrimitiveType::parseTypedDeclaration(Context &context, Domain &domain)
if (!context.parser.probe('-')) if (!context.parser.probe('-'))
return; return;
if (!domain.hasRequirement(Requirement::Type::Typing)) domain.checkRequirement(Requirement::Type::Typing);
throw utils::ParserException(context.parser, "Typing used but not declared as a requirement");
// If existing, parse and store parent type // If existing, parse and store parent type
auto *parentType = parseAndFind(context, domain); auto *parentType = parseAndFind(context, domain);

View File

@ -117,13 +117,13 @@ void Variable::parseTypedDeclarations(Context &context, ExpressionContext &expre
// Check correct use of typing requirement // Check correct use of typing requirement
const auto typingUsed = (expressionContext.parameters.back()->type() != nullptr); const auto typingUsed = (expressionContext.parameters.back()->type() != nullptr);
const auto typingDeclared = expressionContext.domain.hasRequirement(Requirement::Type::Typing);
if (!typingUsed && typingDeclared) // If types are given, check that typing is a requirement
throw utils::ParserException(context.parser, "Variable has undeclared type"); if (typingUsed)
expressionContext.checkRequirement(Requirement::Type::Typing);
if (typingUsed && !typingDeclared) // If no types are given, check that typing is not a requirement
throw utils::ParserException(context.parser, "Typing used but not declared as a requirement"); else if (expressionContext.hasRequirement(Requirement::Type::Typing))
throw utils::ParserException(context.parser, "Constant has undeclared type");
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////