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
{
public:
ExpressionContext(Domain &domain, expressions::Variables &parameters)
: domain(domain),
problem(nullptr),
parameters(parameters)
{
}
ExpressionContext(Domain &domain, expressions::Variables &parameters);
ExpressionContext(Domain &domain, Problem *problem, expressions::Variables &parameters);
ExpressionContext(Domain &domain, Problem *problem, expressions::Variables &parameters)
: domain(domain),
problem{problem},
parameters(parameters)
{
}
bool hasRequirement(Requirement::Type requirementType) const;
void checkRequirement(Requirement::Type requirementType) const;
Domain &domain;
Problem *problem;

View File

@ -258,8 +258,7 @@ void Domain::computeDerivedRequirements()
void Domain::parseTypeSection()
{
if (!hasRequirement(Requirement::Type::Typing))
throw utils::ParserException(m_context.parser, "Typing used but not declared as a requirement");
checkRequirement(Requirement::Type::Typing);
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 match != m_requirements.cend();
if (match != m_requirements.cend())
return true;
return m_domain.hasRequirement(requirementType);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Problem::checkRequirement(Requirement::Type requirementType) const
{
m_domain.checkRequirement(requirementType);
if (hasRequirement(requirementType))
return;
@ -256,14 +257,6 @@ void Problem::parseObjectSection()
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
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");
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
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");
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('-'))
return;
if (!domain.hasRequirement(Requirement::Type::Typing))
throw utils::ParserException(context.parser, "Typing used but not declared as a requirement");
domain.checkRequirement(Requirement::Type::Typing);
// If existing, parse and store parent type
auto *parentType = parseAndFind(context, domain);

View File

@ -117,13 +117,13 @@ void Variable::parseTypedDeclarations(Context &context, ExpressionContext &expre
// 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, "Variable has undeclared type");
if (typingUsed && !typingDeclared)
throw utils::ParserException(context.parser, "Typing used but not declared as a requirement");
// If types are given, check that typing is a requirement
if (typingUsed)
expressionContext.checkRequirement(Requirement::Type::Typing);
// If no types are given, check that typing is not a requirement
else if (expressionContext.hasRequirement(Requirement::Type::Typing))
throw utils::ParserException(context.parser, "Constant has undeclared type");
}
////////////////////////////////////////////////////////////////////////////////////////////////////