Implemented computation of derived requirements.
This commit is contained in:
parent
5c37026ec7
commit
d26ff2df77
@ -24,6 +24,7 @@ class Description
|
||||
static Description fromFile(const boost::filesystem::path &path);
|
||||
|
||||
public:
|
||||
const Domain &domain() const;
|
||||
|
||||
private:
|
||||
Description() = default;
|
||||
|
@ -30,6 +30,7 @@ class Domain
|
||||
void parseSection(utils::Parser &parser);
|
||||
|
||||
void parseRequirementsSection(utils::Parser &parser);
|
||||
void computeDerivedRequirements();
|
||||
|
||||
std::string m_name;
|
||||
Requirement::Types m_requirements;
|
||||
|
@ -30,6 +30,7 @@ struct Requirement
|
||||
ConditionalEffects,
|
||||
Fluents,
|
||||
NumericFluents,
|
||||
ObjectFluents,
|
||||
ADL,
|
||||
DurativeActions,
|
||||
DurationInequalities,
|
||||
|
@ -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)
|
||||
{
|
||||
std::cout << "Parsing file content" << std::endl;
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include <plasp/pddl/Domain.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <plasp/pddl/Identifier.h>
|
||||
#include <plasp/utils/ParserException.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
@ -33,6 +36,8 @@ Domain Domain::fromPDDL(utils::Parser &parser)
|
||||
domain.parseSection(parser);
|
||||
}
|
||||
|
||||
domain.computeDerivedRequirements();
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
@ -115,10 +120,65 @@ void Domain::parseRequirementsSection(utils::Parser &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>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ const RequirementTypeNames requirementTypesToPDDL = boost::assign::list_of<Requi
|
||||
(Requirement::Type::ConditionalEffects, "conditional-effects")
|
||||
(Requirement::Type::Fluents, "fluents")
|
||||
(Requirement::Type::NumericFluents, "numeric-fluents")
|
||||
(Requirement::Type::ObjectFluents, "object-fluents")
|
||||
(Requirement::Type::ADL, "adl")
|
||||
(Requirement::Type::DurativeActions, "durative-actions")
|
||||
(Requirement::Type::DurationInequalities, "duration-inequalities")
|
||||
@ -58,6 +59,7 @@ const RequirementTypeNames requirementTypesToASP = boost::assign::list_of<Requir
|
||||
(Requirement::Type::ConditionalEffects, "conditionalEffects")
|
||||
(Requirement::Type::Fluents, "fluents")
|
||||
(Requirement::Type::NumericFluents, "numericFluents")
|
||||
(Requirement::Type::ObjectFluents, "objectFluents")
|
||||
(Requirement::Type::ADL, "adl")
|
||||
(Requirement::Type::DurativeActions, "durativeActions")
|
||||
(Requirement::Type::DurationInequalities, "durationInequalities")
|
||||
|
57
tests/TestPDDLParser.cpp
Normal file
57
tests/TestPDDLParser.cpp
Normal 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();
|
||||
}
|
||||
}
|
@ -175,11 +175,3 @@ TEST_F(SASParserTests, ParseRequirements)
|
||||
FAIL() << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
Reference in New Issue
Block a user