Started implementing PDDL type parsing.

This commit is contained in:
2016-05-30 20:43:36 +02:00
parent 1c4c035acc
commit a989f5f86e
8 changed files with 362 additions and 13 deletions

View File

@@ -2,6 +2,7 @@
#include <algorithm>
#include <plasp/pddl/ConsistencyException.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/utils/ParserException.h>
@@ -38,6 +39,8 @@ Domain Domain::fromPDDL(utils::Parser &parser)
domain.computeDerivedRequirements();
domain.checkConsistency();
return domain;
}
@@ -57,6 +60,13 @@ const Requirement::Types &Domain::requirements() const
////////////////////////////////////////////////////////////////////////////////////////////////////
const Domain::TypesHashMap &Domain::types() const
{
return m_types;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parseSection(utils::Parser &parser)
{
parser.expect<std::string>("(:");
@@ -90,7 +100,7 @@ void Domain::parseSection(utils::Parser &parser)
if (sectionIdentifier == "requirements")
parseRequirementsSection(parser);
else if (sectionIdentifier == "types")
skipSection();
parseTypingSection(parser);
else if (sectionIdentifier == "constants")
skipSection();
else if (sectionIdentifier == "predicates")
@@ -128,16 +138,17 @@ void Domain::parseRequirementsSection(utils::Parser &parser)
////////////////////////////////////////////////////////////////////////////////////////////////////
bool Domain::hasRequirement(Requirement::Type requirement) const
{
const auto match = std::find(m_requirements.cbegin(), m_requirements.cend(), requirement);
return match != m_requirements.cend();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::computeDerivedRequirements()
{
const auto hasRequirement =
[&](const auto requirement)
{
const auto match = std::find(m_requirements.cbegin(), m_requirements.cend(), requirement);
return match != m_requirements.cend();
};
const auto addRequirementUnique =
[&](const auto requirement)
{
@@ -180,5 +191,68 @@ void Domain::computeDerivedRequirements()
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parseTypingSection(utils::Parser &parser)
{
// Parses a single type identifier
const auto parseType =
[&]() -> auto &
{
parser.skipWhiteSpace();
const auto typeName = parser.parseIdentifier(isIdentifier);
const auto insertionResult = m_types.emplace(std::make_pair(typeName, Type(typeName)));
auto &type = insertionResult.first->second;
// Flag type for potentially upcoming parent type declaration
type.setDirty();
parser.skipWhiteSpace();
return type;
};
// Parses a type and potentially its parent type
while (parser.currentCharacter() != ')')
{
parseType();
// Check for type inheritance
if (!parser.advanceIf('-'))
continue;
// If existing, parse parent type
auto &parentType = parseType();
parentType.setDirty(false);
// Assign parent type to all types that were previously flagged
std::for_each(m_types.begin(), m_types.end(),
[&](auto &childType)
{
if (!childType.second.isDirty())
return;
childType.second.addParentType(parentType);
childType.second.setDirty(false);
});
}
parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::checkConsistency()
{
if (!m_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);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

58
src/plasp/pddl/Type.cpp Normal file
View File

@@ -0,0 +1,58 @@
#include <plasp/pddl/Type.h>
namespace plasp
{
namespace pddl
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Type
//
////////////////////////////////////////////////////////////////////////////////////////////////////
Type::Type(std::string name)
: m_isDirty{false},
m_name{name}
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Type::setDirty(bool isDirty)
{
m_isDirty = isDirty;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
bool Type::isDirty() const
{
return m_isDirty;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const std::string &Type::name() const
{
return m_name;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Type::addParentType(const Type &parentType)
{
m_parentTypes.emplace_back(&parentType);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const std::vector<const Type *> &Type::parentTypes() const
{
return m_parentTypes;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}