Implemented parsing of PDDL constants.
This commit is contained in:
146
src/plasp/pddl/Constant.cpp
Normal file
146
src/plasp/pddl/Constant.cpp
Normal file
@@ -0,0 +1,146 @@
|
||||
#include <plasp/pddl/Constant.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Identifier.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constant
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Constant::Constant(std::string name)
|
||||
: m_isDirty{false},
|
||||
m_isDeclared{false},
|
||||
m_name(name),
|
||||
m_type{nullptr}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Constant &Constant::parse(utils::Parser &parser, Context &context)
|
||||
{
|
||||
parser.skipWhiteSpace();
|
||||
|
||||
const auto constantName = parser.parseIdentifier(isIdentifier);
|
||||
const auto match = context.constantsHashMap.find(constantName);
|
||||
const auto constantExists = (match != context.constantsHashMap.cend());
|
||||
|
||||
// Return existing primitive types
|
||||
if (constantExists)
|
||||
{
|
||||
auto &constant = *match->second;
|
||||
|
||||
constant.setDirty();
|
||||
|
||||
return constant;
|
||||
}
|
||||
|
||||
// Store new primitive type
|
||||
context.constants.emplace_back(std::make_unique<Constant>(Constant(constantName)));
|
||||
|
||||
auto &constant = *context.constants.back();
|
||||
|
||||
// Add a pointer to the primitive type to the hash map
|
||||
context.constantsHashMap.emplace(std::make_pair(constantName, &constant));
|
||||
|
||||
// Flag type for potentially upcoming parent type declaration
|
||||
constant.setDirty();
|
||||
|
||||
return constant;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Constant &Constant::parseDeclaration(utils::Parser &parser, Context &context)
|
||||
{
|
||||
// Parse and store constant
|
||||
auto &constant = parse(parser, context);
|
||||
|
||||
// Flag constant as correctly declared in the types section
|
||||
constant.setDeclared();
|
||||
|
||||
parser.skipWhiteSpace();
|
||||
|
||||
// Check for typing information
|
||||
if (!parser.advanceIf('-'))
|
||||
return constant;
|
||||
|
||||
// If existing, parse and store parent type
|
||||
auto &type = PrimitiveType::parse(parser, context);
|
||||
|
||||
// Assign parent type to all types that were previously flagged
|
||||
std::for_each(context.constants.begin(), context.constants.end(),
|
||||
[&](auto &constant)
|
||||
{
|
||||
if (!constant->isDirty())
|
||||
return;
|
||||
|
||||
constant->setType(&type);
|
||||
constant->setDirty(false);
|
||||
});
|
||||
|
||||
return constant;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Constant::setDirty(bool isDirty)
|
||||
{
|
||||
m_isDirty = isDirty;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Constant::isDirty() const
|
||||
{
|
||||
return m_isDirty;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Constant::setDeclared()
|
||||
{
|
||||
m_isDeclared = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Constant::isDeclared() const
|
||||
{
|
||||
return m_isDeclared;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string &Constant::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Constant::setType(const PrimitiveType *type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const PrimitiveType *Constant::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
@@ -74,6 +74,13 @@ const std::vector<std::unique_ptr<PrimitiveType>> &Domain::types() const
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::vector<std::unique_ptr<Constant>> &Domain::constants() const
|
||||
{
|
||||
return m_context.constants;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::vector<std::unique_ptr<Predicate>> &Domain::predicates() const
|
||||
{
|
||||
return m_context.predicates;
|
||||
@@ -116,7 +123,7 @@ void Domain::parseSection(utils::Parser &parser)
|
||||
else if (sectionIdentifier == "types")
|
||||
parseTypeSection(parser);
|
||||
else if (sectionIdentifier == "constants")
|
||||
skipSection();
|
||||
parseConstantSection(parser);
|
||||
else if (sectionIdentifier == "predicates")
|
||||
parsePredicateSection(parser);
|
||||
else if (sectionIdentifier == "functions")
|
||||
@@ -125,6 +132,10 @@ void Domain::parseSection(utils::Parser &parser)
|
||||
skipSection();
|
||||
else if (sectionIdentifier == "action")
|
||||
skipSection();
|
||||
else if (sectionIdentifier == "durative-action")
|
||||
skipSection();
|
||||
else if (sectionIdentifier == "derived")
|
||||
skipSection();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -228,6 +239,23 @@ void Domain::parseTypeSection(utils::Parser &parser)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Domain::parseConstantSection(utils::Parser &parser)
|
||||
{
|
||||
parser.skipWhiteSpace();
|
||||
|
||||
// Store constants
|
||||
while (parser.currentCharacter() != ')')
|
||||
{
|
||||
Constant::parseDeclaration(parser, m_context);
|
||||
|
||||
parser.skipWhiteSpace();
|
||||
}
|
||||
|
||||
parser.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Domain::parsePredicateSection(utils::Parser &parser)
|
||||
{
|
||||
parser.skipWhiteSpace();
|
||||
@@ -263,6 +291,17 @@ void Domain::checkConsistency()
|
||||
throw ConsistencyException("Type \"" + type->name() + "\" used but never declared");
|
||||
});
|
||||
|
||||
// Verify that all used constants have been declared
|
||||
std::for_each(m_context.constants.cbegin(), m_context.constants.cend(),
|
||||
[&](const auto &constant)
|
||||
{
|
||||
if (!constant->isDeclared())
|
||||
throw ConsistencyException("Constant \"" + constant->name() + "\" used but never declared");
|
||||
|
||||
if (constant->type() == nullptr)
|
||||
throw ConsistencyException("Constant \"" + constant->name() + "\" has an undeclared type");
|
||||
});
|
||||
|
||||
// Verify that all used predicates have been declared
|
||||
std::for_each(m_context.predicates.cbegin(), m_context.predicates.cend(),
|
||||
[&](const auto &predicate)
|
||||
|
@@ -89,7 +89,7 @@ PrimitiveType &PrimitiveType::parseDeclaration(utils::Parser &parser, Context &c
|
||||
if (!childType->isDirty())
|
||||
return;
|
||||
|
||||
childType->addParentType(parentType);
|
||||
childType->addParentType(&parentType);
|
||||
childType->setDirty(false);
|
||||
});
|
||||
|
||||
@@ -133,9 +133,9 @@ const std::string &PrimitiveType::name() const
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PrimitiveType::addParentType(const PrimitiveType &parentType)
|
||||
void PrimitiveType::addParentType(const PrimitiveType *parentType)
|
||||
{
|
||||
m_parentTypes.emplace_back(&parentType);
|
||||
m_parentTypes.push_back(parentType);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
Reference in New Issue
Block a user