diff --git a/include/plasp/sas/Value.h b/include/plasp/sas/Value.h index 2c0d95a..62bcff9 100644 --- a/include/plasp/sas/Value.h +++ b/include/plasp/sas/Value.h @@ -18,16 +18,32 @@ namespace sas struct Value { - enum class Sign - { - Positive, - Negative - }; + public: + enum class Sign + { + Positive, + Negative + }; - static const Value Any; + static const Value Any; - Sign sign; - std::string name; + static Value fromSAS(std::istream &istream); + + 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; //////////////////////////////////////////////////////////////////////////////////////////////////// -std::ostream &operator <<(std::ostream &ostream, const Value &value); - -//////////////////////////////////////////////////////////////////////////////////////////////////// - } } diff --git a/src/plasp/sas/Description.cpp b/src/plasp/sas/Description.cpp index ddbfedd..78c9d87 100644 --- a/src/plasp/sas/Description.cpp +++ b/src/plasp/sas/Description.cpp @@ -129,7 +129,9 @@ void Description::print(std::ostream &ostream) const std::for_each(values.cbegin(), values.cend(), [&](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; @@ -146,7 +148,9 @@ void Description::print(std::ostream &ostream) const std::for_each(mutexGroup.facts.cbegin(), mutexGroup.facts.cend(), [&](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(), [&](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 @@ -165,7 +171,9 @@ void Description::print(std::ostream &ostream) const std::for_each(m_goalFacts.cbegin(), m_goalFacts.cend(), [&](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 @@ -180,7 +188,9 @@ void Description::print(std::ostream &ostream) const std::for_each(operator_.preconditions.cbegin(), operator_.preconditions.cend(), [&](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; @@ -194,11 +204,15 @@ void Description::print(std::ostream &ostream) const std::for_each(effect.conditions.cbegin(), effect.conditions.cend(), [&](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\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; @@ -216,11 +230,15 @@ void Description::print(std::ostream &ostream) const std::for_each(axiomRule.conditions.cbegin(), axiomRule.conditions.cend(), [&](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\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; }); } diff --git a/src/plasp/sas/TranslatorASP.cpp b/src/plasp/sas/TranslatorASP.cpp index 58574d0..4aab003 100644 --- a/src/plasp/sas/TranslatorASP.cpp +++ b/src/plasp/sas/TranslatorASP.cpp @@ -69,14 +69,14 @@ void TranslatorASP::translate(std::ostream &ostream) const const auto match = std::find_if(fluents.cbegin(), fluents.cend(), [&](const auto &fluent) { - return value.name == *fluent; + return value.name() == *fluent; }); // Don’t add fluents if their negated form has already been added if (match != fluents.cend()) 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(), [&](const auto &initialStateFact) { - ostream << "init(" << initialStateFact.value << ")." << std::endl; + ostream << "init("; + initialStateFact.value.printAsASP(ostream); + ostream << ")." << std::endl; }); ostream << std::endl; @@ -108,7 +110,9 @@ void TranslatorASP::translate(std::ostream &ostream) const std::for_each(goalFacts.cbegin(), goalFacts.cend(), [&](const auto &goalFact) { - ostream << "goal(" << goalFact.value << ")." << std::endl; + ostream << "goal("; + goalFact.value.printAsASP(ostream); + ostream << ")." << std::endl; }); ostream << std::endl; @@ -125,8 +129,8 @@ void TranslatorASP::translate(std::ostream &ostream) const [&](const auto &precondition) { ostream << "precondition(" << operator_.predicate - << ", " << precondition.value.name - << ", " << (precondition.value.sign == Value::Sign::Positive ? "true" : "false") + << ", " << precondition.value.name() + << ", " << (precondition.value.sign() == Value::Sign::Positive ? "true" : "false") << ")." << std::endl; }); @@ -134,8 +138,8 @@ void TranslatorASP::translate(std::ostream &ostream) const [&](const auto &effect) { ostream << "postcondition(" << operator_.predicate - << ", " << effect.postcondition.value.name - << ", " << (effect.postcondition.value.sign == Value::Sign::Positive ? "true" : "false") + << ", " << effect.postcondition.value.name() + << ", " << (effect.postcondition.value.sign() == Value::Sign::Positive ? "true" : "false") << ")." << std::endl; }); }); @@ -153,7 +157,9 @@ void TranslatorASP::translate(std::ostream &ostream) const std::for_each(mutexGroup.facts.cbegin(), mutexGroup.facts.cend(), [&](const auto &fact) { - ostream << ", holds(" << fact.value << ", T)"; + ostream << ", holds("; + fact.value.printAsASP(ostream); + ostream << ", T)"; }); ostream << "." << std::endl; diff --git a/src/plasp/sas/Value.cpp b/src/plasp/sas/Value.cpp index 4d42110..9b8f930 100644 --- a/src/plasp/sas/Value.cpp +++ b/src/plasp/sas/Value.cpp @@ -2,6 +2,8 @@ #include +#include + namespace plasp { 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(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 "; - 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; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/sas/Variable.cpp b/src/plasp/sas/Variable.cpp index afb6d5e..4d44c08 100644 --- a/src/plasp/sas/Variable.cpp +++ b/src/plasp/sas/Variable.cpp @@ -32,32 +32,10 @@ Variable Variable::fromSAS(std::istream &istream) variable.m_axiomLayer = utils::parse(istream); const auto numberOfValues = utils::parse(istream); - variable.m_values.resize(numberOfValues); + variable.m_values.reserve(numberOfValues); - try - { - for (size_t j = 0; j < numberOfValues; j++) - { - auto &value = variable.m_values[j]; - - const auto sasSign = utils::parse(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() + ")"); - } + for (size_t j = 0; j < numberOfValues; j++) + variable.m_values.emplace_back(Value::fromSAS(istream)); utils::parseExpected(istream, "end_variable"); diff --git a/tests/TestSASParser.cpp b/tests/TestSASParser.cpp index 4a5b457..5e774a2 100644 --- a/tests/TestSASParser.cpp +++ b/tests/TestSASParser.cpp @@ -46,11 +46,11 @@ TEST_F(SASParserTests, ParseValidSASFile) ASSERT_EQ(description.variables().size(), 37); 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].name, "activate(philosopher-0, forks--pid-rfork)"); + 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()[36].axiomLayer(), -1); - 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].sign(), plasp::sas::Value::Sign::Negative); + ASSERT_EQ(description.variables()[36].values()[1].name(), "queue-tail-msg(forks-1-, fork)"); ASSERT_EQ(description.mutexGroups().size(), 8); ASSERT_EQ(description.mutexGroups()[0].facts.size(), 9);