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);
|
static Description fromFile(const boost::filesystem::path &path);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
const Domain &domain() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Description() = default;
|
Description() = default;
|
||||||
|
@ -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;
|
||||||
|
@ -30,6 +30,7 @@ struct Requirement
|
|||||||
ConditionalEffects,
|
ConditionalEffects,
|
||||||
Fluents,
|
Fluents,
|
||||||
NumericFluents,
|
NumericFluents,
|
||||||
|
ObjectFluents,
|
||||||
ADL,
|
ADL,
|
||||||
DurativeActions,
|
DurativeActions,
|
||||||
DurationInequalities,
|
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)
|
void Description::parseContent(utils::Parser &parser)
|
||||||
{
|
{
|
||||||
std::cout << "Parsing file content" << std::endl;
|
std::cout << "Parsing file content" << std::endl;
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
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();
|
FAIL() << e.what();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
::testing::InitGoogleTest(&argc, argv);
|
|
||||||
return RUN_ALL_TESTS();
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user