Started implementing predicate parsing.

This commit is contained in:
2016-05-31 16:43:25 +02:00
parent 5f763e90fc
commit 2654a6ff23
10 changed files with 404 additions and 19 deletions

View File

@@ -74,6 +74,13 @@ const TypeHashMap &Domain::types() const
////////////////////////////////////////////////////////////////////////////////////////////////////
const PredicateHashMap &Domain::predicates() const
{
return m_context.predicates;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parseSection(utils::Parser &parser)
{
parser.expect<std::string>("(:");
@@ -111,7 +118,7 @@ void Domain::parseSection(utils::Parser &parser)
else if (sectionIdentifier == "constants")
skipSection();
else if (sectionIdentifier == "predicates")
skipSection();
parsePredicateSection(parser);
else if (sectionIdentifier == "functions")
skipSection();
else if (sectionIdentifier == "constraints")
@@ -124,17 +131,16 @@ void Domain::parseSection(utils::Parser &parser)
void Domain::parseRequirementsSection(utils::Parser &parser)
{
while (true)
parser.skipWhiteSpace();
while (parser.currentCharacter() != ')')
{
parser.skipWhiteSpace();
if (parser.currentCharacter() == ')')
break;
if (parser.currentCharacter() == ':')
parser.advance();
m_requirements.emplace_back(Requirement::parse(parser));
parser.skipWhiteSpace();
}
if (m_requirements.empty())
@@ -204,10 +210,29 @@ void Domain::computeDerivedRequirements()
void Domain::parseTypingSection(utils::Parser &parser)
{
parser.skipWhiteSpace();
// Store types and their parent types
while (parser.currentCharacter() != ')')
{
Type::parseWithInheritance(parser, m_context);
Type::parseDeclaration(parser, m_context);
parser.skipWhiteSpace();
}
parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parsePredicateSection(utils::Parser &parser)
{
parser.skipWhiteSpace();
// Store predicates and their arguments
while (parser.currentCharacter() != ')')
{
Predicate::parseDeclaration(parser, m_context);
parser.skipWhiteSpace();
}
@@ -234,6 +259,16 @@ void Domain::checkConsistency()
if (!type.second.isDeclared())
throw ConsistencyException("Type \"" + type.second.name() + "\" used but never declared");
});
// Verify that all used predicates have been declared
std::for_each(m_context.predicates.cbegin(), m_context.predicates.cend(),
[&](const auto &predicate)
{
if (!predicate.second.isDeclared())
throw ConsistencyException("Predicate \"" + predicate.second.name() + "\" used but never declared");
});
// Verify that all variables have types
}
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,111 @@
#include <plasp/pddl/Predicate.h>
#include <algorithm>
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Identifier.h>
namespace plasp
{
namespace pddl
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Predicate
//
////////////////////////////////////////////////////////////////////////////////////////////////////
Predicate::Predicate(std::string name)
: m_isDeclared{false},
m_name{name}
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Predicate &Predicate::parseDeclaration(utils::Parser &parser, Context &context)
{
parser.expect<std::string>("(");
const auto predicateName = parser.parseIdentifier(isIdentifier);
Predicate predicate(predicateName);
// Flag predicate as correctly declared in the types section
predicate.setDeclared();
parser.skipWhiteSpace();
// Parse arguments
while (parser.currentCharacter() != ')')
{
predicate.m_arguments.emplace_back(Variable::parse(parser, context));
parser.skipWhiteSpace();
// Check if the variable has a type declaration
if (!parser.advanceIf('-'))
continue;
// Parse argument type
const auto &type = Type::parse(parser, context);
// Set the argument type for all previously flagged arguments
std::for_each(predicate.m_arguments.begin(), predicate.m_arguments.end(),
[&](auto &argument)
{
if (!argument.isDirty())
return;
argument.setType(type);
argument.setDirty(false);
});
parser.skipWhiteSpace();
}
parser.expect<std::string>(")");
const auto predicateArity = predicate.m_arguments.size();
const PredicateHashMapKey key = {predicateName, predicateArity};
const auto insertionResult = context.predicates.emplace(std::make_pair(key, std::move(predicate)));
std::cout << "Emplaced " << insertionResult.first->second.name() << std::endl;
return insertionResult.first->second;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Predicate::setDeclared()
{
m_isDeclared = true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
bool Predicate::isDeclared() const
{
return m_isDeclared;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const std::string &Predicate::name() const
{
return m_name;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const Variables &Predicate::arguments() const
{
return m_arguments;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@@ -48,19 +48,19 @@ Type &Type::parse(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;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Type &Type::parseWithInheritance(utils::Parser &parser, Context &context)
Type &Type::parseDeclaration(utils::Parser &parser, Context &context)
{
// Parse and store type
auto &type = parse(parser, context);
// Flag type as correctly declared in the types section
type.setDeclared();
parser.skipWhiteSpace();
// Check for type inheritance
@@ -72,6 +72,10 @@ Type &Type::parseWithInheritance(utils::Parser &parser, Context &context)
parentType.setDirty(false);
// Type object is an implicit primitive type
if (parentType.name() == "object")
parentType.setDeclared();
// Assign parent type to all types that were previously flagged
std::for_each(context.types.begin(), context.types.end(),
[&](auto &childType)

View File

@@ -0,0 +1,81 @@
#include <plasp/pddl/Variable.h>
#include <boost/assert.hpp>
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Identifier.h>
namespace plasp
{
namespace pddl
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Variable
//
////////////////////////////////////////////////////////////////////////////////////////////////////
Variable::Variable(std::string name)
: m_isDirty{false},
m_name(name)
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Variable Variable::parse(utils::Parser &parser, Context &context)
{
parser.skipWhiteSpace();
parser.expect<std::string>("?");
const auto variableName = parser.parseIdentifier(isIdentifier);
Variable variable(variableName);
variable.setDirty();
return variable;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Variable::setDirty(bool isDirty)
{
m_isDirty = isDirty;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
bool Variable::isDirty() const
{
return m_isDirty;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const std::string &Variable::name() const
{
return m_name;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Variable::setType(const Type &type)
{
m_type = &type;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const Type &Variable::type() const
{
BOOST_ASSERT(m_type != nullptr);
return *m_type;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}