diff --git a/include/plasp/pddl/Type.h b/include/plasp/pddl/Type.h index 9720c91..001f702 100644 --- a/include/plasp/pddl/Type.h +++ b/include/plasp/pddl/Type.h @@ -35,15 +35,20 @@ class Type const std::string &name() const; const std::vector &parentTypes() const; + bool isDeclared() const; + private: Type(std::string name); void setDirty(bool isDirty = true); bool isDirty() const; + void setDeclared(); + void addParentType(const Type &parentType); bool m_isDirty; + bool m_isDeclared; std::string m_name; diff --git a/src/plasp/pddl/Domain.cpp b/src/plasp/pddl/Domain.cpp index 0a0a031..a025490 100644 --- a/src/plasp/pddl/Domain.cpp +++ b/src/plasp/pddl/Domain.cpp @@ -215,12 +215,21 @@ void Domain::parseTypingSection(utils::Parser &parser) void Domain::checkConsistency() { + // Verify that typing requirement is correctly declared if used if (!m_context.types.empty() && !hasRequirement(Requirement::Type::Typing)) { throw ConsistencyException("Domain contains typing information but does not declare typing requirement"); m_requirements.push_back(Requirement::Type::Typing); } + + // Verify that all used types have been declared + std::for_each(m_context.types.cbegin(), m_context.types.cend(), + [&](const auto &type) + { + if (!type.second.isDeclared()) + throw ConsistencyException("Type \"" + type.second.name() + "\" used but never declared"); + }); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/Type.cpp b/src/plasp/pddl/Type.cpp index 9b4f173..9c22942 100644 --- a/src/plasp/pddl/Type.cpp +++ b/src/plasp/pddl/Type.cpp @@ -18,6 +18,7 @@ namespace pddl Type::Type(std::string name) : m_isDirty{false}, + m_isDeclared{false}, m_name(name) { } @@ -51,6 +52,9 @@ void Type::parsePDDL(utils::Parser &parser, Context &context) // Flag type for potentially upcoming parent type declaration type.setDirty(); + // Flag type as correctly declared in the types section + type.setDeclared(); + return type; }; @@ -95,6 +99,20 @@ bool Type::isDirty() const //////////////////////////////////////////////////////////////////////////////////////////////////// +void Type::setDeclared() +{ + m_isDeclared = true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool Type::isDeclared() const +{ + return m_isDeclared; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + const std::string &Type::name() const { return m_name;