diff --git a/include/plasp/pddl/ExpressionContext.h b/include/plasp/pddl/ExpressionContext.h index 4c60e01..20bb013 100644 --- a/include/plasp/pddl/ExpressionContext.h +++ b/include/plasp/pddl/ExpressionContext.h @@ -18,19 +18,11 @@ namespace pddl class ExpressionContext { public: - ExpressionContext(Domain &domain, expressions::Variables ¶meters) - : domain(domain), - problem(nullptr), - parameters(parameters) - { - } + ExpressionContext(Domain &domain, expressions::Variables ¶meters); + ExpressionContext(Domain &domain, Problem *problem, expressions::Variables ¶meters); - ExpressionContext(Domain &domain, Problem *problem, expressions::Variables ¶meters) - : domain(domain), - problem{problem}, - parameters(parameters) - { - } + bool hasRequirement(Requirement::Type requirementType) const; + void checkRequirement(Requirement::Type requirementType) const; Domain &domain; Problem *problem; diff --git a/src/plasp/pddl/Domain.cpp b/src/plasp/pddl/Domain.cpp index d351e39..9e0a50b 100644 --- a/src/plasp/pddl/Domain.cpp +++ b/src/plasp/pddl/Domain.cpp @@ -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(); diff --git a/src/plasp/pddl/ExpressionContext.cpp b/src/plasp/pddl/ExpressionContext.cpp new file mode 100644 index 0000000..ed3fb97 --- /dev/null +++ b/src/plasp/pddl/ExpressionContext.cpp @@ -0,0 +1,56 @@ +#include + +#include +#include + +namespace plasp +{ +namespace pddl +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// ExpressionContext +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ExpressionContext::ExpressionContext(Domain &domain, expressions::Variables ¶meters) +: domain(domain), + problem(nullptr), + parameters(parameters) +{ +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ExpressionContext::ExpressionContext(Domain &domain, Problem *problem, expressions::Variables ¶meters) +: 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); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/src/plasp/pddl/Problem.cpp b/src/plasp/pddl/Problem.cpp index 632c099..a7835f8 100644 --- a/src/plasp/pddl/Problem.cpp +++ b/src/plasp/pddl/Problem.cpp @@ -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"); - }); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/expressions/Constant.cpp b/src/plasp/pddl/expressions/Constant.cpp index 055b6a5..a011713 100644 --- a/src/plasp/pddl/expressions/Constant.cpp +++ b/src/plasp/pddl/expressions/Constant.cpp @@ -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"); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/expressions/PrimitiveType.cpp b/src/plasp/pddl/expressions/PrimitiveType.cpp index fb61e86..a7e24d4 100644 --- a/src/plasp/pddl/expressions/PrimitiveType.cpp +++ b/src/plasp/pddl/expressions/PrimitiveType.cpp @@ -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); diff --git a/src/plasp/pddl/expressions/Variable.cpp b/src/plasp/pddl/expressions/Variable.cpp index 85b5afb..421047d 100644 --- a/src/plasp/pddl/expressions/Variable.cpp +++ b/src/plasp/pddl/expressions/Variable.cpp @@ -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"); } ////////////////////////////////////////////////////////////////////////////////////////////////////