Made Operator a proper class.
This commit is contained in:
parent
c13e3539f2
commit
21237ecac7
@ -20,20 +20,30 @@ namespace sas
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct Operator;
|
class Operator;
|
||||||
using Operators = std::vector<Operator>;
|
using Operators = std::vector<Operator>;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct Operator
|
class Operator
|
||||||
{
|
{
|
||||||
using Condition = AssignedVariable;
|
public:
|
||||||
using Conditions = AssignedVariables;
|
static Operator fromSAS(std::istream &istream, const Variables &variables);
|
||||||
|
|
||||||
Predicate predicate;
|
using Condition = AssignedVariable;
|
||||||
Conditions preconditions;
|
using Conditions = AssignedVariables;
|
||||||
Effects effects;
|
|
||||||
size_t costs;
|
public:
|
||||||
|
const Predicate &predicate() const;
|
||||||
|
const Conditions &preconditions() const;
|
||||||
|
const Effects &effects() const;
|
||||||
|
size_t costs() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Predicate m_predicate;
|
||||||
|
Conditions m_preconditions;
|
||||||
|
Effects m_effects;
|
||||||
|
size_t m_costs;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -183,10 +183,13 @@ void Description::print(std::ostream &ostream) const
|
|||||||
std::for_each(m_operators.cbegin(), m_operators.cend(),
|
std::for_each(m_operators.cbegin(), m_operators.cend(),
|
||||||
[&](const auto &operator_)
|
[&](const auto &operator_)
|
||||||
{
|
{
|
||||||
ostream << "\t" << operator_.predicate << ":" << std::endl;
|
ostream << "\t" << operator_.predicate() << ":" << std::endl;
|
||||||
ostream << "\t\tpreconditions: " << operator_.preconditions.size() << std::endl;
|
|
||||||
|
|
||||||
std::for_each(operator_.preconditions.cbegin(), operator_.preconditions.cend(),
|
const auto &preconditions = operator_.preconditions();
|
||||||
|
|
||||||
|
ostream << "\t\tpreconditions: " << preconditions.size() << std::endl;
|
||||||
|
|
||||||
|
std::for_each(preconditions.cbegin(), preconditions.cend(),
|
||||||
[&](const auto &precondition)
|
[&](const auto &precondition)
|
||||||
{
|
{
|
||||||
std::cout << "\t\t\t" << precondition.variable().name() << " = ";
|
std::cout << "\t\t\t" << precondition.variable().name() << " = ";
|
||||||
@ -194,9 +197,11 @@ void Description::print(std::ostream &ostream) const
|
|||||||
ostream << std::endl;
|
ostream << std::endl;
|
||||||
});
|
});
|
||||||
|
|
||||||
ostream << "\t\teffects: " << operator_.effects.size() << std::endl;
|
const auto &effects = operator_.effects();
|
||||||
|
|
||||||
std::for_each(operator_.effects.cbegin(), operator_.effects.cend(),
|
ostream << "\t\teffects: " << effects.size() << std::endl;
|
||||||
|
|
||||||
|
std::for_each(effects.cbegin(), effects.cend(),
|
||||||
[&](const auto &effect)
|
[&](const auto &effect)
|
||||||
{
|
{
|
||||||
ostream << "\t\t\teffect:" << std::endl;
|
ostream << "\t\t\teffect:" << std::endl;
|
||||||
@ -216,7 +221,7 @@ void Description::print(std::ostream &ostream) const
|
|||||||
ostream << std::endl;
|
ostream << std::endl;
|
||||||
});
|
});
|
||||||
|
|
||||||
ostream << "\t\tcosts: " << operator_.costs << std::endl;
|
ostream << "\t\tcosts: " << operator_.costs() << std::endl;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Axiom section
|
// Axiom section
|
||||||
@ -310,70 +315,10 @@ void Description::parseGoalSection(std::istream &istream)
|
|||||||
void Description::parseOperatorSection(std::istream &istream)
|
void Description::parseOperatorSection(std::istream &istream)
|
||||||
{
|
{
|
||||||
const auto numberOfOperators = utils::parse<size_t>(istream);
|
const auto numberOfOperators = utils::parse<size_t>(istream);
|
||||||
m_operators.resize(numberOfOperators);
|
m_operators.reserve(numberOfOperators);
|
||||||
|
|
||||||
for (size_t i = 0; i < numberOfOperators; i++)
|
for (size_t i = 0; i < numberOfOperators; i++)
|
||||||
{
|
m_operators.emplace_back(Operator::fromSAS(istream, m_variables));
|
||||||
utils::parseExpected<std::string>(istream, "begin_operator");
|
|
||||||
|
|
||||||
auto &operator_ = m_operators[i];
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
istream.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
|
||||||
|
|
||||||
// TODO: Inefficient, reimplement in one pass
|
|
||||||
std::string line;
|
|
||||||
std::getline(istream, line);
|
|
||||||
|
|
||||||
std::stringstream lineStream(line);
|
|
||||||
|
|
||||||
operator_.predicate.name = utils::parse<std::string>(lineStream);
|
|
||||||
|
|
||||||
while (lineStream.peek() == ' ')
|
|
||||||
lineStream.ignore(1);
|
|
||||||
|
|
||||||
for (std::string argument; std::getline(lineStream, argument, ' ');)
|
|
||||||
operator_.predicate.arguments.push_back(std::move(argument));
|
|
||||||
}
|
|
||||||
catch (const std::exception &e)
|
|
||||||
{
|
|
||||||
throw utils::ParserException("Could not parse operator predicate");
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto numberOfPrevailConditions = utils::parse<size_t>(istream);
|
|
||||||
operator_.preconditions.reserve(numberOfPrevailConditions);
|
|
||||||
|
|
||||||
for (size_t j = 0; j < numberOfPrevailConditions; j++)
|
|
||||||
operator_.preconditions.emplace_back(AssignedVariable::fromSAS(istream, m_variables));
|
|
||||||
|
|
||||||
const auto numberOfEffects = utils::parse<size_t>(istream);
|
|
||||||
operator_.effects.reserve(numberOfEffects);
|
|
||||||
|
|
||||||
for (size_t j = 0; j < numberOfEffects; j++)
|
|
||||||
{
|
|
||||||
Effect::Conditions conditions;
|
|
||||||
|
|
||||||
const auto numberOfEffectConditions = utils::parse<size_t>(istream);
|
|
||||||
conditions.reserve(numberOfEffectConditions);
|
|
||||||
|
|
||||||
for (size_t k = 0; k < numberOfEffectConditions; k++)
|
|
||||||
conditions.emplace_back(AssignedVariable::fromSAS(istream, m_variables));
|
|
||||||
|
|
||||||
const auto variableTransition = VariableTransition::fromSAS(istream, m_variables);
|
|
||||||
|
|
||||||
if (&variableTransition.valueBefore() != &Value::Any)
|
|
||||||
operator_.preconditions.emplace_back(AssignedVariable(variableTransition.variable(), variableTransition.valueBefore()));
|
|
||||||
|
|
||||||
const Effect::Condition postcondition = {variableTransition.variable(), variableTransition.valueAfter()};
|
|
||||||
const Effect effect = {std::move(conditions), std::move(postcondition)};
|
|
||||||
operator_.effects.push_back(std::move(effect));
|
|
||||||
}
|
|
||||||
|
|
||||||
operator_.costs = utils::parse<size_t>(istream);
|
|
||||||
|
|
||||||
utils::parseExpected<std::string>(istream, "end_operator");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
116
src/plasp/sas/Operator.cpp
Normal file
116
src/plasp/sas/Operator.cpp
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
#include <plasp/sas/Operator.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include <plasp/sas/VariableTransition.h>
|
||||||
|
#include <plasp/utils/Parsing.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace sas
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Operator
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Operator Operator::fromSAS(std::istream &istream, const Variables &variables)
|
||||||
|
{
|
||||||
|
Operator operator_;
|
||||||
|
|
||||||
|
utils::parseExpected<std::string>(istream, "begin_operator");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
istream.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||||
|
|
||||||
|
// TODO: Inefficient, reimplement in one pass
|
||||||
|
std::string line;
|
||||||
|
std::getline(istream, line);
|
||||||
|
|
||||||
|
std::stringstream lineStream(line);
|
||||||
|
|
||||||
|
operator_.m_predicate.name = utils::parse<std::string>(lineStream);
|
||||||
|
|
||||||
|
while (lineStream.peek() == ' ')
|
||||||
|
lineStream.ignore(1);
|
||||||
|
|
||||||
|
for (std::string argument; std::getline(lineStream, argument, ' ');)
|
||||||
|
operator_.m_predicate.arguments.push_back(std::move(argument));
|
||||||
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
throw utils::ParserException("Could not parse operator predicate");
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto numberOfPrevailConditions = utils::parse<size_t>(istream);
|
||||||
|
operator_.m_preconditions.reserve(numberOfPrevailConditions);
|
||||||
|
|
||||||
|
for (size_t j = 0; j < numberOfPrevailConditions; j++)
|
||||||
|
operator_.m_preconditions.emplace_back(AssignedVariable::fromSAS(istream, variables));
|
||||||
|
|
||||||
|
const auto numberOfEffects = utils::parse<size_t>(istream);
|
||||||
|
operator_.m_effects.reserve(numberOfEffects);
|
||||||
|
|
||||||
|
for (size_t j = 0; j < numberOfEffects; j++)
|
||||||
|
{
|
||||||
|
Effect::Conditions conditions;
|
||||||
|
|
||||||
|
const auto numberOfEffectConditions = utils::parse<size_t>(istream);
|
||||||
|
conditions.reserve(numberOfEffectConditions);
|
||||||
|
|
||||||
|
for (size_t k = 0; k < numberOfEffectConditions; k++)
|
||||||
|
conditions.emplace_back(AssignedVariable::fromSAS(istream, variables));
|
||||||
|
|
||||||
|
const auto variableTransition = VariableTransition::fromSAS(istream, variables);
|
||||||
|
|
||||||
|
if (&variableTransition.valueBefore() != &Value::Any)
|
||||||
|
operator_.m_preconditions.emplace_back(AssignedVariable(variableTransition.variable(), variableTransition.valueBefore()));
|
||||||
|
|
||||||
|
const Effect::Condition postcondition = {variableTransition.variable(), variableTransition.valueAfter()};
|
||||||
|
const Effect effect = {std::move(conditions), std::move(postcondition)};
|
||||||
|
operator_.m_effects.push_back(std::move(effect));
|
||||||
|
}
|
||||||
|
|
||||||
|
operator_.m_costs = utils::parse<size_t>(istream);
|
||||||
|
|
||||||
|
utils::parseExpected<std::string>(istream, "end_operator");
|
||||||
|
|
||||||
|
return operator_;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Predicate &Operator::predicate() const
|
||||||
|
{
|
||||||
|
return m_predicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Operator::Conditions &Operator::preconditions() const
|
||||||
|
{
|
||||||
|
return m_preconditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const Effects &Operator::effects() const
|
||||||
|
{
|
||||||
|
return m_effects;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
size_t Operator::costs() const
|
||||||
|
{
|
||||||
|
return m_costs;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -36,7 +36,7 @@ void TranslatorASP::checkSupport() const
|
|||||||
std::for_each(operators.cbegin(), operators.cend(),
|
std::for_each(operators.cbegin(), operators.cend(),
|
||||||
[&](const auto &operator_)
|
[&](const auto &operator_)
|
||||||
{
|
{
|
||||||
std::for_each(operator_.effects.cbegin(), operator_.effects.cend(),
|
std::for_each(operator_.effects().cbegin(), operator_.effects().cend(),
|
||||||
[&](const auto &effect)
|
[&](const auto &effect)
|
||||||
{
|
{
|
||||||
if (!effect.conditions.empty())
|
if (!effect.conditions.empty())
|
||||||
@ -123,21 +123,25 @@ void TranslatorASP::translate(std::ostream &ostream) const
|
|||||||
std::for_each(operators.cbegin(), operators.cend(),
|
std::for_each(operators.cbegin(), operators.cend(),
|
||||||
[&](const auto &operator_)
|
[&](const auto &operator_)
|
||||||
{
|
{
|
||||||
ostream << "action(" << operator_.predicate << ")." << std::endl;
|
ostream << "action(" << operator_.predicate() << ")." << std::endl;
|
||||||
|
|
||||||
std::for_each(operator_.preconditions.cbegin(), operator_.preconditions.cend(),
|
const auto &preconditions = operator_.preconditions();
|
||||||
|
|
||||||
|
std::for_each(preconditions.cbegin(), preconditions.cend(),
|
||||||
[&](const auto &precondition)
|
[&](const auto &precondition)
|
||||||
{
|
{
|
||||||
ostream << "precondition(" << operator_.predicate
|
ostream << "precondition(" << operator_.predicate()
|
||||||
<< ", " << precondition.value().name()
|
<< ", " << precondition.value().name()
|
||||||
<< ", " << (precondition.value().sign() == Value::Sign::Positive ? "true" : "false")
|
<< ", " << (precondition.value().sign() == Value::Sign::Positive ? "true" : "false")
|
||||||
<< ")." << std::endl;
|
<< ")." << std::endl;
|
||||||
});
|
});
|
||||||
|
|
||||||
std::for_each(operator_.effects.cbegin(), operator_.effects.cend(),
|
const auto &effects = operator_.effects();
|
||||||
|
|
||||||
|
std::for_each(effects.cbegin(), effects.cend(),
|
||||||
[&](const auto &effect)
|
[&](const auto &effect)
|
||||||
{
|
{
|
||||||
ostream << "postcondition(" << operator_.predicate
|
ostream << "postcondition(" << operator_.predicate()
|
||||||
<< ", " << effect.postcondition.value().name()
|
<< ", " << effect.postcondition.value().name()
|
||||||
<< ", " << (effect.postcondition.value().sign() == Value::Sign::Positive ? "true" : "false")
|
<< ", " << (effect.postcondition.value().sign() == Value::Sign::Positive ? "true" : "false")
|
||||||
<< ")." << std::endl;
|
<< ")." << std::endl;
|
||||||
|
@ -67,28 +67,28 @@ TEST_F(SASParserTests, ParseValidSASFile)
|
|||||||
ASSERT_EQ(&description.goal().facts()[1].value(), &description.variables()[7].values()[0]);
|
ASSERT_EQ(&description.goal().facts()[1].value(), &description.variables()[7].values()[0]);
|
||||||
|
|
||||||
ASSERT_EQ(description.operators().size(), 34);
|
ASSERT_EQ(description.operators().size(), 34);
|
||||||
ASSERT_EQ(description.operators()[0].predicate.name, "activate-trans");
|
ASSERT_EQ(description.operators()[0].predicate().name, "activate-trans");
|
||||||
ASSERT_EQ(description.operators()[0].predicate.arguments.size(), 5);
|
ASSERT_EQ(description.operators()[0].predicate().arguments.size(), 5);
|
||||||
ASSERT_EQ(description.operators()[0].predicate.arguments[0], "philosopher-0");
|
ASSERT_EQ(description.operators()[0].predicate().arguments[0], "philosopher-0");
|
||||||
ASSERT_EQ(description.operators()[0].predicate.arguments[4], "state-3");
|
ASSERT_EQ(description.operators()[0].predicate().arguments[4], "state-3");
|
||||||
ASSERT_EQ(description.operators()[0].preconditions.size(), 3);
|
ASSERT_EQ(description.operators()[0].preconditions().size(), 3);
|
||||||
ASSERT_EQ(&description.operators()[0].preconditions[0].value(), &description.variables()[4].values()[4]);
|
ASSERT_EQ(&description.operators()[0].preconditions()[0].value(), &description.variables()[4].values()[4]);
|
||||||
ASSERT_EQ(&description.operators()[0].preconditions[1].value(), &description.variables()[16].values()[1]);
|
ASSERT_EQ(&description.operators()[0].preconditions()[1].value(), &description.variables()[16].values()[1]);
|
||||||
ASSERT_EQ(&description.operators()[0].preconditions[2].value(), &description.variables()[0].values()[8]);
|
ASSERT_EQ(&description.operators()[0].preconditions()[2].value(), &description.variables()[0].values()[8]);
|
||||||
ASSERT_EQ(description.operators()[0].effects.size(), 1);
|
ASSERT_EQ(description.operators()[0].effects().size(), 1);
|
||||||
ASSERT_EQ(description.operators()[0].effects[0].conditions.size(), 0);
|
ASSERT_EQ(description.operators()[0].effects()[0].conditions.size(), 0);
|
||||||
ASSERT_EQ(&description.operators()[0].effects[0].postcondition.value(), &description.variables()[0].values()[0]);
|
ASSERT_EQ(&description.operators()[0].effects()[0].postcondition.value(), &description.variables()[0].values()[0]);
|
||||||
ASSERT_EQ(description.operators()[33].predicate.name, "queue-write");
|
ASSERT_EQ(description.operators()[33].predicate().name, "queue-write");
|
||||||
ASSERT_EQ(description.operators()[33].predicate.arguments.size(), 4);
|
ASSERT_EQ(description.operators()[33].predicate().arguments.size(), 4);
|
||||||
ASSERT_EQ(description.operators()[33].predicate.arguments[0], "philosopher-1");
|
ASSERT_EQ(description.operators()[33].predicate().arguments[0], "philosopher-1");
|
||||||
ASSERT_EQ(description.operators()[33].predicate.arguments[3], "fork");
|
ASSERT_EQ(description.operators()[33].predicate().arguments[3], "fork");
|
||||||
ASSERT_EQ(description.operators()[33].preconditions.size(), 2);
|
ASSERT_EQ(description.operators()[33].preconditions().size(), 2);
|
||||||
ASSERT_EQ(&description.operators()[33].preconditions[0].value(), &description.variables()[1].values()[3]);
|
ASSERT_EQ(&description.operators()[33].preconditions()[0].value(), &description.variables()[1].values()[3]);
|
||||||
ASSERT_EQ(&description.operators()[33].preconditions[1].value(), &description.variables()[2].values()[2]);
|
ASSERT_EQ(&description.operators()[33].preconditions()[1].value(), &description.variables()[2].values()[2]);
|
||||||
ASSERT_EQ(description.operators()[33].effects.size(), 3);
|
ASSERT_EQ(description.operators()[33].effects().size(), 3);
|
||||||
ASSERT_EQ(description.operators()[33].effects[0].conditions.size(), 0);
|
ASSERT_EQ(description.operators()[33].effects()[0].conditions.size(), 0);
|
||||||
ASSERT_EQ(&description.operators()[33].effects[0].postcondition.value(), &description.variables()[1].values()[7]);
|
ASSERT_EQ(&description.operators()[33].effects()[0].postcondition.value(), &description.variables()[1].values()[7]);
|
||||||
ASSERT_EQ(&description.operators()[33].effects[2].postcondition.value(), &description.variables()[35].values()[0]);
|
ASSERT_EQ(&description.operators()[33].effects()[2].postcondition.value(), &description.variables()[35].values()[0]);
|
||||||
|
|
||||||
ASSERT_EQ(description.axiomRules().size(), 33);
|
ASSERT_EQ(description.axiomRules().size(), 33);
|
||||||
ASSERT_EQ(description.axiomRules()[0].conditions.size(), 4);
|
ASSERT_EQ(description.axiomRules()[0].conditions.size(), 4);
|
||||||
|
Reference in New Issue
Block a user