From 7bd2782fc8eb5c9a8f62b6b4953f407b1f1dc923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Wed, 8 Jun 2016 01:05:36 +0200 Subject: [PATCH] Implemented variable type requirement checking. --- .../plasp/pddl/expressions/PrimitiveType.h | 5 -- include/plasp/pddl/expressions/Variable.h | 4 +- src/plasp/pddl/Action.cpp | 7 +-- src/plasp/pddl/Description.cpp | 2 - src/plasp/pddl/Domain.cpp | 46 ------------------- .../pddl/expressions/PredicateDeclaration.cpp | 7 +-- src/plasp/pddl/expressions/PrimitiveType.cpp | 23 +--------- src/plasp/pddl/expressions/Variable.cpp | 24 +++++++++- src/plasp/utils/Parser.cpp | 4 +- 9 files changed, 30 insertions(+), 92 deletions(-) diff --git a/include/plasp/pddl/expressions/PrimitiveType.h b/include/plasp/pddl/expressions/PrimitiveType.h index e42e913..8fb7c4a 100644 --- a/include/plasp/pddl/expressions/PrimitiveType.h +++ b/include/plasp/pddl/expressions/PrimitiveType.h @@ -36,16 +36,11 @@ class PrimitiveType: public Expression const std::string &name() const; const std::vector &parentTypes() const; - bool isDeclared() const; - private: void setDirty(bool isDirty = true); bool isDirty() const; - void setDeclared(); - bool m_isDirty; - bool m_isDeclared; std::string m_name; diff --git a/include/plasp/pddl/expressions/Variable.h b/include/plasp/pddl/expressions/Variable.h index 79f1163..15439af 100644 --- a/include/plasp/pddl/expressions/Variable.h +++ b/include/plasp/pddl/expressions/Variable.h @@ -20,8 +20,10 @@ class Variable: public Expression { public: 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: void accept(ExpressionVisitor &expressionVisitor) const override; diff --git a/src/plasp/pddl/Action.cpp b/src/plasp/pddl/Action.cpp index 14f0bd3..b46f943 100644 --- a/src/plasp/pddl/Action.cpp +++ b/src/plasp/pddl/Action.cpp @@ -40,12 +40,7 @@ void Action::parseDeclaration(Context &context, Domain &domain) ExpressionContext expressionContext(domain, action->m_parameters); // Read parameters - while (context.parser.currentCharacter() != ')') - { - expressions::Variable::parseTypedDeclaration(context, expressionContext); - - context.parser.skipWhiteSpace(); - } + expressions::Variable::parseTypedDeclarations(context, expressionContext); context.parser.expect(")"); diff --git a/src/plasp/pddl/Description.cpp b/src/plasp/pddl/Description.cpp index 02a8ae7..4c893ef 100644 --- a/src/plasp/pddl/Description.cpp +++ b/src/plasp/pddl/Description.cpp @@ -111,8 +111,6 @@ void Description::findSections() if (m_context.parser.probe("domain")) { - std::cout << "Found domain at " << position << std::endl; - if (m_domainPosition != -1) throw utils::ParserException(m_context.parser, "PDDL description may not contain two domains"); diff --git a/src/plasp/pddl/Domain.cpp b/src/plasp/pddl/Domain.cpp index fb45689..88a50c1 100644 --- a/src/plasp/pddl/Domain.cpp +++ b/src/plasp/pddl/Domain.cpp @@ -315,52 +315,6 @@ void Domain::parseActionSection() 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 std::for_each(m_constants.cbegin(), m_constants.cend(), [&](const auto &constant) diff --git a/src/plasp/pddl/expressions/PredicateDeclaration.cpp b/src/plasp/pddl/expressions/PredicateDeclaration.cpp index 2330d23..e941577 100644 --- a/src/plasp/pddl/expressions/PredicateDeclaration.cpp +++ b/src/plasp/pddl/expressions/PredicateDeclaration.cpp @@ -45,12 +45,7 @@ void PredicateDeclaration::parse(Context &context, Domain &domain) ExpressionContext expressionContext(domain, predicate->m_parameters); // Parse arguments - while (context.parser.currentCharacter() != ')') - { - expressions::Variable::parseTypedDeclaration(context, expressionContext); - - context.parser.skipWhiteSpace(); - } + expressions::Variable::parseTypedDeclarations(context, expressionContext); context.parser.expect(")"); diff --git a/src/plasp/pddl/expressions/PrimitiveType.cpp b/src/plasp/pddl/expressions/PrimitiveType.cpp index 8834b56..11a7bd7 100644 --- a/src/plasp/pddl/expressions/PrimitiveType.cpp +++ b/src/plasp/pddl/expressions/PrimitiveType.cpp @@ -23,8 +23,7 @@ namespace expressions //////////////////////////////////////////////////////////////////////////////////////////////////// PrimitiveType::PrimitiveType() -: m_isDirty{true}, - m_isDeclared{false} +: m_isDirty{true} { } @@ -32,7 +31,6 @@ PrimitiveType::PrimitiveType() PrimitiveType::PrimitiveType(std::string name) : m_isDirty{true}, - m_isDeclared{false}, m_name{name} { BOOST_ASSERT(!m_name.empty()); @@ -61,13 +59,11 @@ void PrimitiveType::parseDeclaration(Context &context, Domain &domain) auto *type = match->get(); type->setDirty(); - type->setDeclared(); return; } types.emplace_back(std::make_unique(typeName)); - types.back()->setDeclared(); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -93,9 +89,6 @@ void PrimitiveType::parseTypedDeclaration(Context &context, Domain &domain) 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 std::for_each(types.begin(), types.end(), [&](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 { return m_name; diff --git a/src/plasp/pddl/expressions/Variable.cpp b/src/plasp/pddl/expressions/Variable.cpp index e2eaaa9..e5da42e 100644 --- a/src/plasp/pddl/expressions/Variable.cpp +++ b/src/plasp/pddl/expressions/Variable.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -67,8 +68,6 @@ void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expres if (!context.parser.probe('-')) return; - // TODO: do not allow nested either expressions - const auto setType = [&](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) { context.parser.skipWhiteSpace(); diff --git a/src/plasp/utils/Parser.cpp b/src/plasp/utils/Parser.cpp index 455f61d..360a505 100644 --- a/src/plasp/utils/Parser.cpp +++ b/src/plasp/utils/Parser.cpp @@ -255,10 +255,10 @@ bool Parser::probe(const std::string &expectedValue) { BOOST_ASSERT(!std::isspace(expectedValue[0])); - skipWhiteSpace(); - const auto previousPosition = position(); + skipWhiteSpace(); + const auto match = std::find_if(expectedValue.cbegin(), expectedValue.cend(), [&](const auto &expectedCharacter) {