From 05058c149ec4999614a1578cd059ef1ff8b3271f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Mon, 23 May 2016 17:13:11 +0200 Subject: [PATCH] Added axiom rule support for SAS translator output. --- encodings/meta-sequential-incremental.lp | 1 + include/plasp/sas/Description.h | 2 + include/plasp/utils/Parsing.h | 2 + src/plasp/sas/Description.cpp | 17 ++++++++ src/plasp/sas/TranslatorASP.cpp | 55 ++++++++++++++++++------ tests/TestUtils.cpp | 3 +- 6 files changed, 66 insertions(+), 14 deletions(-) diff --git a/encodings/meta-sequential-incremental.lp b/encodings/meta-sequential-incremental.lp index 915af63..998c2ec 100644 --- a/encodings/meta-sequential-incremental.lp +++ b/encodings/meta-sequential-incremental.lp @@ -2,6 +2,7 @@ % Check feature requirements :- requiresFeature(actionCosts, true). +:- requiresFeature(axiomRules, true). #program base. diff --git a/include/plasp/sas/Description.h b/include/plasp/sas/Description.h index 5baa938..ca16f29 100644 --- a/include/plasp/sas/Description.h +++ b/include/plasp/sas/Description.h @@ -40,6 +40,8 @@ class Description const Operators &operators() const; const AxiomRules &axiomRules() const; + bool usesAxiomRules() const; + private: Description(); diff --git a/include/plasp/utils/Parsing.h b/include/plasp/utils/Parsing.h index 2641541..16a005d 100644 --- a/include/plasp/utils/Parsing.h +++ b/include/plasp/utils/Parsing.h @@ -65,6 +65,7 @@ inline std::string escapeASP(const std::string &string) boost::replace_all(escaped, "_", "__"); boost::replace_all(escaped, "-", "_h"); + boost::replace_all(escaped, "@", "_a"); return escaped; } @@ -75,6 +76,7 @@ inline std::string unescapeASP(const std::string &string) { auto unescaped = string; + boost::replace_all(unescaped, "_a", "@"); boost::replace_all(unescaped, "_h", "-"); boost::replace_all(unescaped, "__", "_"); diff --git a/src/plasp/sas/Description.cpp b/src/plasp/sas/Description.cpp index 0cc637c..d1b0a02 100644 --- a/src/plasp/sas/Description.cpp +++ b/src/plasp/sas/Description.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -111,6 +112,22 @@ const AxiomRules &Description::axiomRules() const //////////////////////////////////////////////////////////////////////////////////////////////////// +bool Description::usesAxiomRules() const +{ + if (!m_axiomRules.empty()) + return true; + + const auto match = std::find_if(m_variables.cbegin(), m_variables.cend(), + [&](const auto &variable) + { + return variable.axiomLayer() != -1; + }); + + return match != m_variables.cend(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void Description::parseVersionSection(std::istream &istream) const { utils::parseExpected(istream, "begin_version"); diff --git a/src/plasp/sas/TranslatorASP.cpp b/src/plasp/sas/TranslatorASP.cpp index 9066ef9..ef05764 100644 --- a/src/plasp/sas/TranslatorASP.cpp +++ b/src/plasp/sas/TranslatorASP.cpp @@ -23,15 +23,6 @@ TranslatorASP::TranslatorASP(const Description &description) void TranslatorASP::checkSupport() const { - const auto &variables = m_description.variables(); - - std::for_each(variables.cbegin(), variables.cend(), - [&](const auto &variable) - { - if (variable.axiomLayer() != -1) - throw TranslatorException("Axiom layers are currently unsupported"); - }); - const auto &operators = m_description.operators(); std::for_each(operators.cbegin(), operators.cend(), @@ -46,9 +37,6 @@ void TranslatorASP::checkSupport() const throw TranslatorException("Conditional effects are currently unsupported"); }); }); - - if (!m_description.axiomRules().empty()) - throw TranslatorException("Axiom rules are currently unsupported"); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -57,11 +45,17 @@ void TranslatorASP::translate(std::ostream &ostream) const { checkSupport(); + const auto usesActionCosts = m_description.usesActionCosts(); + const auto usesAxiomRules = m_description.usesAxiomRules(); + ostream << "% feature requirements" << std::endl; - if (m_description.usesActionCosts()) + if (usesActionCosts) ostream << "requiresFeature(actionCosts)." << std::endl; + if (usesAxiomRules) + ostream << "requiresFeature(axiomRules)." << std::endl; + ostream << std::endl; ostream << "% initial state" << std::endl; @@ -204,6 +198,41 @@ void TranslatorASP::translate(std::ostream &ostream) const ostream << ")." << std::endl; }); } + + if (usesAxiomRules) + { + ostream << std::endl; + ostream << "% axiom rules"; + + const auto &axiomRules = m_description.axiomRules(); + + for (size_t i = 0; i < axiomRules.size(); i++) + { + const auto &axiomRule = axiomRules[i]; + + ostream << std::endl << "axiomRule(axiomRule" << i << ")." << std::endl; + + const auto &conditions = axiomRule.conditions(); + + std::for_each(conditions.cbegin(), conditions.cend(), + [&](const auto &condition) + { + ostream << "condition(axiomRule(axiomRule" << i << "), "; + condition.variable().printNameAsASPPredicate(ostream); + ostream << ", "; + condition.value().printAsASPPredicate(ostream); + ostream << ")." << std::endl; + }); + + const auto &postcondition = axiomRule.postcondition(); + + ostream << "postcondition(axiomRule(axiomRule" << i << "), "; + postcondition.variable().printNameAsASPPredicate(ostream); + ostream << ", "; + postcondition.value().printAsASPPredicate(ostream); + ostream << ")." << std::endl; + } + } } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/tests/TestUtils.cpp b/tests/TestUtils.cpp index d96b84a..e4775fb 100644 --- a/tests/TestUtils.cpp +++ b/tests/TestUtils.cpp @@ -6,11 +6,12 @@ TEST(UtilsTests, EscapeASP) { - const std::string predicate = "action(stack_on(block-1, block-2))"; + const std::string predicate = "action(stack_on(block-1, block-2, value@3, value@4))"; const auto escaped = plasp::utils::escapeASP(predicate); const auto unescaped = plasp::utils::unescapeASP(escaped); ASSERT_EQ(escaped.find("-"), std::string::npos); + ASSERT_EQ(escaped.find("@"), std::string::npos); ASSERT_EQ(predicate, unescaped); }