Made Value a proper class.

This commit is contained in:
Patrick Lühne 2016-05-21 16:22:40 +02:00
parent 5e016d2d79
commit 273e310c60
6 changed files with 151 additions and 63 deletions

View File

@ -18,16 +18,32 @@ namespace sas
struct Value struct Value
{ {
enum class Sign public:
{ enum class Sign
Positive, {
Negative Positive,
}; Negative
};
static const Value Any; static const Value Any;
Sign sign; static Value fromSAS(std::istream &istream);
std::string name;
public:
void printAsSAS(std::ostream &ostream) const;
void printAsASP(std::ostream &ostream) const;
Sign sign() const;
const std::string &name() const;
private:
static const Value any();
private:
Value();
Sign m_sign;
std::string m_name;
}; };
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
@ -36,10 +52,6 @@ using Values = std::vector<Value>;
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
std::ostream &operator <<(std::ostream &ostream, const Value &value);
////////////////////////////////////////////////////////////////////////////////////////////////////
} }
} }

View File

@ -129,7 +129,9 @@ void Description::print(std::ostream &ostream) const
std::for_each(values.cbegin(), values.cend(), std::for_each(values.cbegin(), values.cend(),
[&](const auto &value) [&](const auto &value)
{ {
ostream << "\t\t\t" << value << std::endl; ostream << "\t\t\t";
value.printAsSAS(ostream);
ostream << std::endl;
}); });
ostream << "\t\taxiom layer: " << variable.axiomLayer() << std::endl; ostream << "\t\taxiom layer: " << variable.axiomLayer() << std::endl;
@ -146,7 +148,9 @@ void Description::print(std::ostream &ostream) const
std::for_each(mutexGroup.facts.cbegin(), mutexGroup.facts.cend(), std::for_each(mutexGroup.facts.cbegin(), mutexGroup.facts.cend(),
[&](const auto &fact) [&](const auto &fact)
{ {
ostream << "\t\t" << fact.variable.name() << " = " << fact.value << std::endl; ostream << "\t\t" << fact.variable.name() << " = ";
fact.value.printAsSAS(ostream);
ostream << std::endl;
}); });
}); });
@ -156,7 +160,9 @@ void Description::print(std::ostream &ostream) const
std::for_each(m_initialStateFacts.cbegin(), m_initialStateFacts.cend(), std::for_each(m_initialStateFacts.cbegin(), m_initialStateFacts.cend(),
[&](const auto &initialStateFact) [&](const auto &initialStateFact)
{ {
ostream << "\t" << initialStateFact.variable.name() << " = " << initialStateFact.value << std::endl; ostream << "\t" << initialStateFact.variable.name() << " = ";
initialStateFact.value.printAsSAS(ostream);
ostream << std::endl;
}); });
// Goal section // Goal section
@ -165,7 +171,9 @@ void Description::print(std::ostream &ostream) const
std::for_each(m_goalFacts.cbegin(), m_goalFacts.cend(), std::for_each(m_goalFacts.cbegin(), m_goalFacts.cend(),
[&](const auto &goalFact) [&](const auto &goalFact)
{ {
ostream << "\t" << goalFact.variable.name() << " = " << goalFact.value << std::endl; ostream << "\t" << goalFact.variable.name() << " = ";
goalFact.value.printAsSAS(ostream);
ostream << std::endl;
}); });
// Operator section // Operator section
@ -180,7 +188,9 @@ void Description::print(std::ostream &ostream) const
std::for_each(operator_.preconditions.cbegin(), operator_.preconditions.cend(), std::for_each(operator_.preconditions.cbegin(), operator_.preconditions.cend(),
[&](const auto &precondition) [&](const auto &precondition)
{ {
std::cout << "\t\t\t" << precondition.variable.name() << " = " << precondition.value << std::endl; std::cout << "\t\t\t" << precondition.variable.name() << " = ";
precondition.value.printAsSAS(ostream);
ostream << std::endl;
}); });
ostream << "\t\teffects: " << operator_.effects.size() << std::endl; ostream << "\t\teffects: " << operator_.effects.size() << std::endl;
@ -194,11 +204,15 @@ void Description::print(std::ostream &ostream) const
std::for_each(effect.conditions.cbegin(), effect.conditions.cend(), std::for_each(effect.conditions.cbegin(), effect.conditions.cend(),
[&](const auto &condition) [&](const auto &condition)
{ {
ostream << "\t\t\t\t\t" << condition.variable.name() << " = " << condition.value << std::endl; ostream << "\t\t\t\t\t" << condition.variable.name() << " = ";
condition.value.printAsSAS(ostream);
ostream << std::endl;
}); });
ostream << "\t\t\t\tpostcondition:" << std::endl; ostream << "\t\t\t\tpostcondition:" << std::endl;
ostream << "\t\t\t\t\t" << effect.postcondition.variable.name() << " = " << effect.postcondition.value << std::endl; ostream << "\t\t\t\t\t" << effect.postcondition.variable.name() << " = ";
effect.postcondition.value.printAsSAS(ostream);
ostream << std::endl;
}); });
ostream << "\t\tcosts: " << operator_.costs << std::endl; ostream << "\t\tcosts: " << operator_.costs << std::endl;
@ -216,11 +230,15 @@ void Description::print(std::ostream &ostream) const
std::for_each(axiomRule.conditions.cbegin(), axiomRule.conditions.cend(), std::for_each(axiomRule.conditions.cbegin(), axiomRule.conditions.cend(),
[&](const auto &condition) [&](const auto &condition)
{ {
ostream << "\t\t\t" << condition.variable.name() << " = " << condition.value << std::endl; ostream << "\t\t\t" << condition.variable.name() << " = ";
condition.value.printAsSAS(ostream);
ostream << std::endl;
}); });
ostream << "\t\tpostcondition:" << std::endl; ostream << "\t\tpostcondition:" << std::endl;
ostream << "\t\t\t" << axiomRule.postcondition.variable.name() << " = " << axiomRule.postcondition.value << std::endl; ostream << "\t\t\t" << axiomRule.postcondition.variable.name() << " = ";
axiomRule.postcondition.value.printAsSAS(ostream);
ostream << std::endl;
}); });
} }

View File

@ -69,14 +69,14 @@ void TranslatorASP::translate(std::ostream &ostream) const
const auto match = std::find_if(fluents.cbegin(), fluents.cend(), const auto match = std::find_if(fluents.cbegin(), fluents.cend(),
[&](const auto &fluent) [&](const auto &fluent)
{ {
return value.name == *fluent; return value.name() == *fluent;
}); });
// Dont add fluents if their negated form has already been added // Dont add fluents if their negated form has already been added
if (match != fluents.cend()) if (match != fluents.cend())
return; return;
fluents.push_back(&value.name); fluents.push_back(&value.name());
}); });
}); });
@ -97,7 +97,9 @@ void TranslatorASP::translate(std::ostream &ostream) const
std::for_each(initialStateFacts.cbegin(), initialStateFacts.cend(), std::for_each(initialStateFacts.cbegin(), initialStateFacts.cend(),
[&](const auto &initialStateFact) [&](const auto &initialStateFact)
{ {
ostream << "init(" << initialStateFact.value << ")." << std::endl; ostream << "init(";
initialStateFact.value.printAsASP(ostream);
ostream << ")." << std::endl;
}); });
ostream << std::endl; ostream << std::endl;
@ -108,7 +110,9 @@ void TranslatorASP::translate(std::ostream &ostream) const
std::for_each(goalFacts.cbegin(), goalFacts.cend(), std::for_each(goalFacts.cbegin(), goalFacts.cend(),
[&](const auto &goalFact) [&](const auto &goalFact)
{ {
ostream << "goal(" << goalFact.value << ")." << std::endl; ostream << "goal(";
goalFact.value.printAsASP(ostream);
ostream << ")." << std::endl;
}); });
ostream << std::endl; ostream << std::endl;
@ -125,8 +129,8 @@ void TranslatorASP::translate(std::ostream &ostream) const
[&](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;
}); });
@ -134,8 +138,8 @@ void TranslatorASP::translate(std::ostream &ostream) const
[&](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;
}); });
}); });
@ -153,7 +157,9 @@ void TranslatorASP::translate(std::ostream &ostream) const
std::for_each(mutexGroup.facts.cbegin(), mutexGroup.facts.cend(), std::for_each(mutexGroup.facts.cbegin(), mutexGroup.facts.cend(),
[&](const auto &fact) [&](const auto &fact)
{ {
ostream << ", holds(" << fact.value << ", T)"; ostream << ", holds(";
fact.value.printAsASP(ostream);
ostream << ", T)";
}); });
ostream << "." << std::endl; ostream << "." << std::endl;

View File

@ -2,6 +2,8 @@
#include <iostream> #include <iostream>
#include <plasp/utils/Parsing.h>
namespace plasp namespace plasp
{ {
namespace sas namespace sas
@ -13,16 +15,88 @@ namespace sas
// //
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
const Value Value::Any = {Value::Sign::Positive, "(any)"}; const Value Value::any()
{
Value any;
any.m_name = "(any)";
return any;
}
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
std::ostream &operator <<(std::ostream &ostream, const Value &value) const Value Value::Any = Value::any();
////////////////////////////////////////////////////////////////////////////////////////////////////
Value::Value()
: m_sign(Sign::Positive)
{ {
if (value.sign == Value::Sign::Negative) }
////////////////////////////////////////////////////////////////////////////////////////////////////
Value Value::fromSAS(std::istream &istream)
{
Value value;
const auto sasSign = utils::parse<std::string>(istream);
if (sasSign == "Atom")
value.m_sign = Value::Sign::Positive;
else if (sasSign == "NegatedAtom")
value.m_sign = Value::Sign::Negative;
else
throw utils::ParserException("Invalid value sign \"" + sasSign + "\"");
try
{
istream.ignore(1);
std::getline(istream, value.m_name);
}
catch (const std::exception &e)
{
throw utils::ParserException(std::string("Could not parse variable value (") + e.what() + ")");
}
return value;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Value::Sign Value::sign() const
{
return m_sign;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const std::string &Value::name() const
{
return m_name;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Value::printAsASP(std::ostream &ostream) const
{
if (m_sign == Value::Sign::Negative)
ostream << "not "; ostream << "not ";
return (ostream << value.name); ostream << m_name;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Value::printAsSAS(std::ostream &ostream) const
{
if (m_sign == Value::Sign::Positive)
ostream << "Atom ";
else
ostream << "NegatedAtom ";
ostream << m_name;
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -32,32 +32,10 @@ Variable Variable::fromSAS(std::istream &istream)
variable.m_axiomLayer = utils::parse<int>(istream); variable.m_axiomLayer = utils::parse<int>(istream);
const auto numberOfValues = utils::parse<size_t>(istream); const auto numberOfValues = utils::parse<size_t>(istream);
variable.m_values.resize(numberOfValues); variable.m_values.reserve(numberOfValues);
try for (size_t j = 0; j < numberOfValues; j++)
{ variable.m_values.emplace_back(Value::fromSAS(istream));
for (size_t j = 0; j < numberOfValues; j++)
{
auto &value = variable.m_values[j];
const auto sasSign = utils::parse<std::string>(istream);
if (sasSign == "Atom")
value.sign = Value::Sign::Positive;
else if (sasSign == "NegatedAtom")
value.sign = Value::Sign::Negative;
else
throw utils::ParserException("Invalid value sign \"" + sasSign + "\"");
istream.ignore(1);
std::getline(istream, value.name);
}
}
catch (const std::exception &e)
{
throw utils::ParserException("Could not parse variable " + variable.m_name + " (" + e.what() + ")");
}
utils::parseExpected<std::string>(istream, "end_variable"); utils::parseExpected<std::string>(istream, "end_variable");

View File

@ -46,11 +46,11 @@ TEST_F(SASParserTests, ParseValidSASFile)
ASSERT_EQ(description.variables().size(), 37); ASSERT_EQ(description.variables().size(), 37);
ASSERT_EQ(description.variables()[0].axiomLayer(), -1); ASSERT_EQ(description.variables()[0].axiomLayer(), -1);
ASSERT_EQ(description.variables()[0].values()[0].sign, plasp::sas::Value::Sign::Positive); ASSERT_EQ(description.variables()[0].values()[0].sign(), plasp::sas::Value::Sign::Positive);
ASSERT_EQ(description.variables()[0].values()[0].name, "activate(philosopher-0, forks--pid-rfork)"); ASSERT_EQ(description.variables()[0].values()[0].name(), "activate(philosopher-0, forks--pid-rfork)");
ASSERT_EQ(description.variables()[36].axiomLayer(), -1); ASSERT_EQ(description.variables()[36].axiomLayer(), -1);
ASSERT_EQ(description.variables()[36].values()[1].sign, plasp::sas::Value::Sign::Negative); ASSERT_EQ(description.variables()[36].values()[1].sign(), plasp::sas::Value::Sign::Negative);
ASSERT_EQ(description.variables()[36].values()[1].name, "queue-tail-msg(forks-1-, fork)"); ASSERT_EQ(description.variables()[36].values()[1].name(), "queue-tail-msg(forks-1-, fork)");
ASSERT_EQ(description.mutexGroups().size(), 8); ASSERT_EQ(description.mutexGroups().size(), 8);
ASSERT_EQ(description.mutexGroups()[0].facts.size(), 9); ASSERT_EQ(description.mutexGroups()[0].facts.size(), 9);