From 17685b68fb17dad08f1a59fa3bd02bb27b57e630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Sat, 21 May 2016 02:43:07 +0200 Subject: [PATCH] Started implementing SAS to ASP translator. --- apps/plasp-app/main.cpp | 4 +- include/plasp/sas/TranslatorASP.h | 37 ++++++ include/plasp/sas/TranslatorException.h | 56 +++++++++ src/plasp/sas/TranslatorASP.cpp | 156 ++++++++++++++++++++++++ 4 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 include/plasp/sas/TranslatorASP.h create mode 100644 include/plasp/sas/TranslatorException.h create mode 100644 src/plasp/sas/TranslatorASP.cpp diff --git a/apps/plasp-app/main.cpp b/apps/plasp-app/main.cpp index f92e226..5143f63 100644 --- a/apps/plasp-app/main.cpp +++ b/apps/plasp-app/main.cpp @@ -3,6 +3,7 @@ #include #include +#include int main(int argc, char **argv) { @@ -40,7 +41,8 @@ int main(int argc, char **argv) try { const auto sasDescription = plasp::sas::Description::fromFile(variablesMap["input"].as()); - sasDescription.print(std::cout); + const auto sasTranslator = plasp::sas::TranslatorASP(sasDescription); + sasTranslator.translate(std::cout); } catch (const std::exception &e) { diff --git a/include/plasp/sas/TranslatorASP.h b/include/plasp/sas/TranslatorASP.h new file mode 100644 index 0000000..891ce79 --- /dev/null +++ b/include/plasp/sas/TranslatorASP.h @@ -0,0 +1,37 @@ +#ifndef __SAS__TRANSLATOR_ASP_H +#define __SAS__TRANSLATOR_ASP_H + +#include + +#include + +namespace plasp +{ +namespace sas +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TranslatorASP +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class TranslatorASP +{ + public: + explicit TranslatorASP(const Description &description); + + void translate(std::ostream &ostream) const; + + private: + void checkSupport() const; + + const Description &m_description; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/sas/TranslatorException.h b/include/plasp/sas/TranslatorException.h new file mode 100644 index 0000000..84df69f --- /dev/null +++ b/include/plasp/sas/TranslatorException.h @@ -0,0 +1,56 @@ +#ifndef __SAS__TRANSLATOR_EXCEPTION_H +#define __SAS__TRANSLATOR_EXCEPTION_H + +#include +#include + +namespace plasp +{ +namespace sas +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TranslatorException +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class TranslatorException: public std::exception +{ + public: + explicit TranslatorException() + { + } + + explicit TranslatorException(const char *message) + : m_message(message) + { + } + + explicit TranslatorException(const std::string &message) + : m_message(message) + { + } + + ~TranslatorException() throw() + { + } + + const char *what() const throw() + { + if (m_message.empty()) + return "Unspecified error while translating SAS description"; + + return m_message.c_str(); + } + + private: + std::string m_message; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/src/plasp/sas/TranslatorASP.cpp b/src/plasp/sas/TranslatorASP.cpp new file mode 100644 index 0000000..e2a95d1 --- /dev/null +++ b/src/plasp/sas/TranslatorASP.cpp @@ -0,0 +1,156 @@ +#include + +#include + +namespace plasp +{ +namespace sas +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// TranslatorASP +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +TranslatorASP::TranslatorASP(const Description &description) +: m_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(), + [&](const auto &operator_) + { + std::for_each(operator_.effects.cbegin(), operator_.effects.cend(), + [&](const auto &effect) + { + if (!effect.conditions.empty()) + throw TranslatorException("Conditional effects are currently unsupported"); + }); + }); + + if (!m_description.axiomRules().empty()) + throw TranslatorException("Axiom rules are currently unsupported"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void TranslatorASP::translate(std::ostream &ostream) const +{ + checkSupport(); + + std::vector fluents; + + const auto &variables = m_description.variables(); + + std::for_each(variables.cbegin(), variables.cend(), + [&](const auto &variable) + { + std::for_each(variable.values.cbegin(), variable.values.cend(), + [&](const auto &value) + { + fluents.push_back(&value); + }); + }); + + ostream << "% fluents" << std::endl; + + std::for_each(fluents.cbegin(), fluents.cend(), + [&](const auto *fluent) + { + if (fluent->sign == Value::Sign::Negative) + return; + + ostream << "fluent(" << *fluent << ")." << std::endl; + }); + + ostream << std::endl; + ostream << "% initial state" << std::endl; + + const auto &initialStateFacts = m_description.initialStateFacts(); + + std::for_each(initialStateFacts.cbegin(), initialStateFacts.cend(), + [&](const auto &initialStateFact) + { + ostream << "init(" << initialStateFact.value << ")." << std::endl; + }); + + ostream << std::endl; + ostream << "% goal" << std::endl; + + const auto &goalFacts = m_description.goalFacts(); + + std::for_each(goalFacts.cbegin(), goalFacts.cend(), + [&](const auto &goalFact) + { + ostream << "goal(" << goalFact.value << ")." << std::endl; + }); + + ostream << std::endl; + ostream << "% actions" << std::endl; + + const auto &operators = m_description.operators(); + + std::for_each(operators.cbegin(), operators.cend(), + [&](const auto &operator_) + { + ostream << "action(" << operator_.predicate << ")." << std::endl; + + std::for_each(operator_.preconditions.cbegin(), operator_.preconditions.cend(), + [&](const auto &precondition) + { + ostream << "precondition(" << operator_.predicate + << ", " << precondition.value.name + << ", " << (precondition.value.sign == Value::Sign::Positive ? "true" : "false") + << ")." << std::endl; + }); + + std::for_each(operator_.effects.cbegin(), operator_.effects.cend(), + [&](const auto &effect) + { + ostream << "postcondition(" << operator_.predicate + << ", " << effect.postcondition.value.name + << ", " << (effect.postcondition.value.sign == Value::Sign::Positive ? "true" : "false") + << ")." << std::endl; + }); + }); + + ostream << std::endl; + ostream << "% mutex groups" << std::endl; + + const auto &mutexGroups = m_description.mutexGroups(); + + std::for_each(mutexGroups.cbegin(), mutexGroups.cend(), + [&](const auto &mutexGroup) + { + ostream << ":- time(T)"; + + std::for_each(mutexGroup.facts.cbegin(), mutexGroup.facts.cend(), + [&](const auto &fact) + { + ostream << ", holds(" << fact.value << ", T)"; + }); + + ostream << "." << std::endl; + }); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +}