diff --git a/include/plasp/sas/Predicate.h b/include/plasp/sas/Predicate.h index 91b4281..b938c0d 100644 --- a/include/plasp/sas/Predicate.h +++ b/include/plasp/sas/Predicate.h @@ -16,18 +16,27 @@ namespace sas // //////////////////////////////////////////////////////////////////////////////////////////////////// -struct Predicate +class Predicate { - std::string name; - std::vector arguments; + public: + static Predicate fromSAS(std::istream &istream); + + using Arguments = std::vector; + + public: + void printAsSAS(std::ostream &ostream) const; + void printAsASP(std::ostream &ostream) const; + + const std::string &name() const; + const Arguments &arguments() const; + + private: + std::string m_name; + std::vector m_arguments; }; //////////////////////////////////////////////////////////////////////////////////////////////////// -std::ostream &operator <<(std::ostream &ostream, const Predicate &predicate); - -//////////////////////////////////////////////////////////////////////////////////////////////////// - } } diff --git a/src/plasp/sas/Debugging.cpp b/src/plasp/sas/Debugging.cpp index 0350da7..f84e8c1 100644 --- a/src/plasp/sas/Debugging.cpp +++ b/src/plasp/sas/Debugging.cpp @@ -95,7 +95,9 @@ std::ostream &operator >>(std::ostream &ostream, const Description &description) std::for_each(operators.cbegin(), operators.cend(), [&](const auto &operator_) { - ostream << "\t" << operator_.predicate() << ":" << std::endl; + ostream << "\t"; + operator_.predicate().printAsSAS(ostream); + ostream << ":" << std::endl; const auto &preconditions = operator_.preconditions(); diff --git a/src/plasp/sas/Operator.cpp b/src/plasp/sas/Operator.cpp index 4aa9b4a..9d1c2d8 100644 --- a/src/plasp/sas/Operator.cpp +++ b/src/plasp/sas/Operator.cpp @@ -23,28 +23,7 @@ Operator Operator::fromSAS(std::istream &istream, const Variables &variables) utils::parseExpected(istream, "begin_operator"); - try - { - istream.ignore(std::numeric_limits::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(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"); - } + operator_.m_predicate = Predicate::fromSAS(istream); const auto numberOfPrevailConditions = utils::parse(istream); operator_.m_preconditions.reserve(numberOfPrevailConditions); diff --git a/src/plasp/sas/Predicate.cpp b/src/plasp/sas/Predicate.cpp index d9042b8..d506276 100644 --- a/src/plasp/sas/Predicate.cpp +++ b/src/plasp/sas/Predicate.cpp @@ -1,6 +1,10 @@ #include #include +#include +#include + +#include namespace plasp { @@ -13,22 +17,89 @@ namespace sas // //////////////////////////////////////////////////////////////////////////////////////////////////// -std::ostream &operator <<(std::ostream &ostream, const Predicate &predicate) +Predicate Predicate::fromSAS(std::istream &istream) { - if (predicate.arguments.empty()) - return (ostream << predicate.name); + Predicate predicate; - ostream << predicate.name << "("; + try + { + istream.ignore(std::numeric_limits::max(), '\n'); - for (size_t i = 0; i < predicate.arguments.size(); i++) + // TODO: Inefficient, reimplement in one pass + std::string line; + std::getline(istream, line); + + std::stringstream lineStream(line); + + predicate.m_name = utils::parse(lineStream); + + while (lineStream.peek() == ' ') + lineStream.ignore(1); + + for (std::string argument; std::getline(lineStream, argument, ' ');) + predicate.m_arguments.push_back(std::move(argument)); + } + catch (const std::exception &e) + { + throw utils::ParserException("Could not parse operator predicate"); + } + + return predicate; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +const std::string &Predicate::name() const +{ + return m_name; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +const Predicate::Arguments &Predicate::arguments() const +{ + return m_arguments; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Predicate::printAsSAS(std::ostream &ostream) const +{ + if (m_arguments.empty()) + { + ostream << m_name; + return; + } + + for (size_t i = 0; i < m_arguments.size(); i++) + { + if (i > 0) + ostream << " "; + + ostream << m_arguments[i]; + } +} +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Predicate::printAsASP(std::ostream &ostream) const +{ + if (m_arguments.empty()) + { + ostream << m_name; + return; + } + + ostream << m_name << "("; + + for (size_t i = 0; i < m_arguments.size(); i++) { if (i > 0) ostream << ", "; - ostream << predicate.arguments[i]; + ostream << m_arguments[i]; } - return (ostream << ")"); + ostream << ")"; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/sas/TranslatorASP.cpp b/src/plasp/sas/TranslatorASP.cpp index 38c7533..a2f7272 100644 --- a/src/plasp/sas/TranslatorASP.cpp +++ b/src/plasp/sas/TranslatorASP.cpp @@ -125,15 +125,18 @@ void TranslatorASP::translate(std::ostream &ostream) const std::for_each(operators.cbegin(), operators.cend(), [&](const auto &operator_) { - ostream << "action(" << operator_.predicate() << ")." << std::endl; + ostream << "action("; + operator_.predicate().printAsASP(ostream); + ostream << ")." << std::endl; const auto &preconditions = operator_.preconditions(); std::for_each(preconditions.cbegin(), preconditions.cend(), [&](const auto &precondition) { - ostream << "precondition(" << operator_.predicate() - << ", " << precondition.value().name() + ostream << "precondition("; + operator_.predicate().printAsASP(ostream); + ostream << ", " << precondition.value().name() << ", " << (precondition.value().sign() == Value::Sign::Positive ? "true" : "false") << ")." << std::endl; }); @@ -143,8 +146,9 @@ void TranslatorASP::translate(std::ostream &ostream) const std::for_each(effects.cbegin(), effects.cend(), [&](const auto &effect) { - ostream << "postcondition(" << operator_.predicate() - << ", " << effect.postcondition().value().name() + ostream << "postcondition("; + operator_.predicate().printAsASP(ostream); + ostream << ", " << effect.postcondition().value().name() << ", " << (effect.postcondition().value().sign() == Value::Sign::Positive ? "true" : "false") << ")." << std::endl; }); diff --git a/tests/TestSASParser.cpp b/tests/TestSASParser.cpp index d3bc83f..a54feb5 100644 --- a/tests/TestSASParser.cpp +++ b/tests/TestSASParser.cpp @@ -67,10 +67,10 @@ TEST_F(SASParserTests, ParseValidSASFile) ASSERT_EQ(&description.goal().facts()[1].value(), &description.variables()[7].values()[0]); ASSERT_EQ(description.operators().size(), 34); - 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[0], "philosopher-0"); - ASSERT_EQ(description.operators()[0].predicate().arguments[4], "state-3"); + 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()[0], "philosopher-0"); + ASSERT_EQ(description.operators()[0].predicate().arguments()[4], "state-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()[1].value(), &description.variables()[16].values()[1]); @@ -78,10 +78,10 @@ TEST_F(SASParserTests, ParseValidSASFile) 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].postcondition().value(), &description.variables()[0].values()[0]); - 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[0], "philosopher-1"); - ASSERT_EQ(description.operators()[33].predicate().arguments[3], "fork"); + 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()[0], "philosopher-1"); + ASSERT_EQ(description.operators()[33].predicate().arguments()[3], "fork"); 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()[1].value(), &description.variables()[2].values()[2]);