Implemented computation of derived requirements.

This commit is contained in:
Patrick Lühne 2016-05-30 15:44:13 +02:00
parent 5c37026ec7
commit d26ff2df77
8 changed files with 131 additions and 8 deletions

View File

@ -24,6 +24,7 @@ class Description
static Description fromFile(const boost::filesystem::path &path); static Description fromFile(const boost::filesystem::path &path);
public: public:
const Domain &domain() const;
private: private:
Description() = default; Description() = default;

View File

@ -30,6 +30,7 @@ class Domain
void parseSection(utils::Parser &parser); void parseSection(utils::Parser &parser);
void parseRequirementsSection(utils::Parser &parser); void parseRequirementsSection(utils::Parser &parser);
void computeDerivedRequirements();
std::string m_name; std::string m_name;
Requirement::Types m_requirements; Requirement::Types m_requirements;

View File

@ -30,6 +30,7 @@ struct Requirement
ConditionalEffects, ConditionalEffects,
Fluents, Fluents,
NumericFluents, NumericFluents,
ObjectFluents,
ADL, ADL,
DurativeActions, DurativeActions,
DurationInequalities, DurationInequalities,

View File

@ -51,6 +51,15 @@ Description Description::fromFile(const boost::filesystem::path &path)
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
const Domain &Description::domain() const
{
BOOST_ASSERT(m_domain);
return *m_domain;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Description::parseContent(utils::Parser &parser) void Description::parseContent(utils::Parser &parser)
{ {
std::cout << "Parsing file content" << std::endl; std::cout << "Parsing file content" << std::endl;

View File

@ -1,6 +1,9 @@
#include <plasp/pddl/Domain.h> #include <plasp/pddl/Domain.h>
#include <algorithm>
#include <plasp/pddl/Identifier.h> #include <plasp/pddl/Identifier.h>
#include <plasp/utils/ParserException.h>
namespace plasp namespace plasp
{ {
@ -33,6 +36,8 @@ Domain Domain::fromPDDL(utils::Parser &parser)
domain.parseSection(parser); domain.parseSection(parser);
} }
domain.computeDerivedRequirements();
return domain; return domain;
} }
@ -115,10 +120,65 @@ void Domain::parseRequirementsSection(utils::Parser &parser)
m_requirements.emplace_back(Requirement::fromPDDL(parser)); m_requirements.emplace_back(Requirement::fromPDDL(parser));
} }
if (m_requirements.empty())
throw utils::ParserException(parser.row(), parser.column(), "Requirements section does not contain any requirements");
parser.expect<std::string>(")"); parser.expect<std::string>(")");
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
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)
{
if (hasRequirement(requirement))
return;
m_requirements.push_back(requirement);
};
// If no requirements are specified, assume STRIPS
if (m_requirements.empty())
addRequirementUnique(Requirement::Type::STRIPS);
if (hasRequirement(Requirement::Type::ADL))
{
addRequirementUnique(Requirement::Type::STRIPS);
addRequirementUnique(Requirement::Type::Typing);
addRequirementUnique(Requirement::Type::NegativePreconditions);
addRequirementUnique(Requirement::Type::DisjunctivePreconditions);
addRequirementUnique(Requirement::Type::Equality);
addRequirementUnique(Requirement::Type::QuantifiedPreconditions);
addRequirementUnique(Requirement::Type::ConditionalEffects);
}
if (hasRequirement(Requirement::Type::QuantifiedPreconditions))
{
addRequirementUnique(Requirement::Type::ExistentialPreconditions);
addRequirementUnique(Requirement::Type::UniversalPreconditions);
}
if (hasRequirement(Requirement::Type::Fluents))
{
addRequirementUnique(Requirement::Type::NumericFluents);
addRequirementUnique(Requirement::Type::ObjectFluents);
}
if (hasRequirement(Requirement::Type::TimedInitialLiterals))
addRequirementUnique(Requirement::Type::DurativeActions);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
} }
} }

View File

@ -34,6 +34,7 @@ const RequirementTypeNames requirementTypesToPDDL = boost::assign::list_of<Requi
(Requirement::Type::ConditionalEffects, "conditional-effects") (Requirement::Type::ConditionalEffects, "conditional-effects")
(Requirement::Type::Fluents, "fluents") (Requirement::Type::Fluents, "fluents")
(Requirement::Type::NumericFluents, "numeric-fluents") (Requirement::Type::NumericFluents, "numeric-fluents")
(Requirement::Type::ObjectFluents, "object-fluents")
(Requirement::Type::ADL, "adl") (Requirement::Type::ADL, "adl")
(Requirement::Type::DurativeActions, "durative-actions") (Requirement::Type::DurativeActions, "durative-actions")
(Requirement::Type::DurationInequalities, "duration-inequalities") (Requirement::Type::DurationInequalities, "duration-inequalities")
@ -58,6 +59,7 @@ const RequirementTypeNames requirementTypesToASP = boost::assign::list_of<Requir
(Requirement::Type::ConditionalEffects, "conditionalEffects") (Requirement::Type::ConditionalEffects, "conditionalEffects")
(Requirement::Type::Fluents, "fluents") (Requirement::Type::Fluents, "fluents")
(Requirement::Type::NumericFluents, "numericFluents") (Requirement::Type::NumericFluents, "numericFluents")
(Requirement::Type::ObjectFluents, "objectFluents")
(Requirement::Type::ADL, "adl") (Requirement::Type::ADL, "adl")
(Requirement::Type::DurativeActions, "durativeActions") (Requirement::Type::DurativeActions, "durativeActions")
(Requirement::Type::DurationInequalities, "durationInequalities") (Requirement::Type::DurationInequalities, "durationInequalities")

57
tests/TestPDDLParser.cpp Normal file
View File

@ -0,0 +1,57 @@
#include <gtest/gtest.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <plasp/pddl/Description.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
class PDDLParserTests : public ::testing::Test
{
protected:
PDDLParserTests()
: m_blocksworldDomainFile(readFile("data/blocksworld-domain.pddl"))
{
}
static std::stringstream readFile(const std::string &path)
{
std::ifstream fileStream(path, std::ios::in);
std::stringstream outputStream;
if (!fileStream.is_open())
throw std::runtime_error("Could not open file \"" + path + "\"");
outputStream << fileStream.rdbuf();
return outputStream;
}
std::stringstream m_blocksworldDomainFile;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
TEST_F(PDDLParserTests, ParseValidPDDLFile)
{
try
{
const auto description = plasp::pddl::Description::fromStream(m_blocksworldDomainFile);
ASSERT_NO_THROW(description.domain());
const auto &domain = description.domain();
ASSERT_EQ(domain.requirements().size(), 2u);
ASSERT_EQ(domain.requirements()[0], plasp::pddl::Requirement::Type::STRIPS);
ASSERT_EQ(domain.requirements()[1], plasp::pddl::Requirement::Type::Typing);
}
catch (const std::exception &e)
{
FAIL() << e.what();
}
}

View File

@ -175,11 +175,3 @@ TEST_F(SASParserTests, ParseRequirements)
FAIL() << e.what(); FAIL() << e.what();
} }
} }
////////////////////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}