From 692d3fe83ab2bd5496a94214c51063214139ed4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Wed, 7 Dec 2016 02:11:54 +0100 Subject: [PATCH] Refactoring to avoid checking expression types via type enum. --- include/plasp/pddl/Expression.h | 11 ++ src/plasp/pddl/Expression.cpp | 6 +- src/plasp/pddl/TranslatorASP.cpp | 232 ++++++++++++++--------------- src/plasp/pddl/expressions/Not.cpp | 19 +-- src/plasp/pddl/expressions/Or.cpp | 2 +- 5 files changed, 137 insertions(+), 133 deletions(-) diff --git a/include/plasp/pddl/Expression.h b/include/plasp/pddl/Expression.h index 79b0c4f..ac29322 100644 --- a/include/plasp/pddl/Expression.h +++ b/include/plasp/pddl/Expression.h @@ -130,6 +130,9 @@ class Expression virtual Type expressionType() const = 0; + template + bool is() const; + virtual ExpressionPointer copy(); // Transform into a normal form as used for the translation to ASP @@ -161,6 +164,14 @@ class Expression //////////////////////////////////////////////////////////////////////////////////////////////////// +template +bool Expression::is() const +{ + return expressionType() == T::ExpressionType; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + inline void intrusive_ptr_add_ref(Expression *expression) { expression->m_referenceCount++; diff --git a/src/plasp/pddl/Expression.cpp b/src/plasp/pddl/Expression.cpp index 50073f5..5c07a5d 100644 --- a/src/plasp/pddl/Expression.cpp +++ b/src/plasp/pddl/Expression.cpp @@ -61,7 +61,7 @@ ExpressionPointer Expression::moveUpQuantifiers(ExpressionPointer parent, Expres { BOOST_ASSERT(child); - if (child->expressionType() == Expression::Type::Exists) + if (child->is()) { auto quantifiedExpression = expressions::ExistsPointer(dynamic_cast(child.get())); @@ -74,7 +74,7 @@ ExpressionPointer Expression::moveUpQuantifiers(ExpressionPointer parent, Expres // Make parent point to the quantifier that has been moved up return quantifiedExpression; } - else if (child->expressionType() == Expression::Type::ForAll) + else if (child->is()) { auto quantifiedExpression = expressions::ForAllPointer(dynamic_cast(child.get())); @@ -109,7 +109,7 @@ ExpressionPointer Expression::simplified() ExpressionPointer Expression::negated() { - if (expressionType() == Type::Not) + if (is()) { auto ¬Expression = dynamic_cast(*this); diff --git a/src/plasp/pddl/TranslatorASP.cpp b/src/plasp/pddl/TranslatorASP.cpp index dc49af0..fe3a70b 100644 --- a/src/plasp/pddl/TranslatorASP.cpp +++ b/src/plasp/pddl/TranslatorASP.cpp @@ -279,101 +279,99 @@ void TranslatorASP::translateActions() const m_outputStream << "))"; }; - std::for_each(actions.cbegin(), actions.cend(), - [&](const auto &action) + for (const auto &action : actions) + { + const auto translateExpression = + [&](const auto &ruleHead, const auto &literal, bool enumerateEffects = false) + { + m_outputStream << std::endl << output::Function(ruleHead) << "("; + + printActionName(*action); + + // TODO: implement conditional effects + if (enumerateEffects) + m_outputStream << ", " << output::Keyword("effect") << "(" << output::Reserved("unconditional") << ")"; + + m_outputStream << ", "; + + translateLiteral(m_outputStream, literal); + + m_outputStream << ") :- " << output::Function("action") << "("; + + printActionName(*action); + + m_outputStream << ")."; + }; + + m_outputStream << std::endl; + + // Name + m_outputStream << output::Function("action") << "("; + printActionName(*action); + m_outputStream << ")"; + + translateVariablesBody(m_outputStream, action->parameters()); + + m_outputStream << "."; + + // Precondition + if (action->precondition()) { - const auto translateExpression = - [&](const auto &ruleHead, const auto &literal, bool enumerateEffects = false) - { - m_outputStream << std::endl << output::Function(ruleHead) << "("; + const auto &precondition = *action->precondition(); - printActionName(*action); - - // TODO: implement conditional effects - if (enumerateEffects) - m_outputStream << ", " << output::Keyword("effect") << "(" << output::Reserved("unconditional") << ")"; - - m_outputStream << ", "; - - translateLiteral(m_outputStream, literal); - - m_outputStream << ") :- " << output::Function("action") << "("; - - printActionName(*action); - - m_outputStream << ")."; - }; - - m_outputStream << std::endl; - - // Name - m_outputStream << output::Function("action") << "("; - printActionName(*action); - m_outputStream << ")"; - - translateVariablesBody(m_outputStream, action->parameters()); - - m_outputStream << "."; - - // Precondition - if (action->precondition()) + switch (precondition.expressionType()) { - const auto &precondition = *action->precondition(); - - switch (precondition.expressionType()) + case Expression::Type::And: { - case Expression::Type::And: - { - const auto &andExpression = dynamic_cast(precondition); - - std::for_each(andExpression.arguments().cbegin(), andExpression.arguments().cend(), - [&](const auto argument) - { - translateExpression("precondition", *argument); - }); - - break; - } - case Expression::Type::Predicate: - case Expression::Type::Not: - case Expression::Type::DerivedPredicate: - { - translateExpression("precondition", precondition); - break; - } - default: - throw output::TranslatorException("only “and” expressions and (negated) predicates supported as action preconditions currently (" + std::to_string((int)precondition.expressionType()) + ")"); - } - } - - // Effect - if (action->effect()) - { - const auto &effect = *action->effect(); - - if (effect.expressionType() == Expression::Type::Predicate - || effect.expressionType() == Expression::Type::Not) - { - translateExpression("postcondition", effect, true); - } - // Assuming a conjunction - else - { - if (effect.expressionType() != Expression::Type::And) - throw output::TranslatorException("only “and” expressions and (negated) predicates supported as action effects currently"); - - const auto &andExpression = dynamic_cast(effect); + const auto &andExpression = dynamic_cast(precondition); std::for_each(andExpression.arguments().cbegin(), andExpression.arguments().cend(), [&](const auto argument) { - translateExpression("postcondition", *argument, true); + translateExpression("precondition", *argument); }); - } - } - m_outputStream << std::endl; - }); + break; + } + case Expression::Type::Predicate: + case Expression::Type::Not: + case Expression::Type::DerivedPredicate: + { + translateExpression("precondition", precondition); + break; + } + default: + throw output::TranslatorException("only “and” expressions and (negated) predicates supported as action preconditions currently (" + std::to_string((int)precondition.expressionType()) + ")"); + } + } + + // Effect + if (action->effect()) + { + const auto &effect = *action->effect(); + + if (effect.is() || effect.is()) + { + translateExpression("postcondition", effect, true); + } + // Assuming a conjunction + else + { + if (effect.expressionType() != Expression::Type::And) + throw output::TranslatorException("only “and” expressions and (negated) predicates supported as action effects currently"); + + const auto &andExpression = dynamic_cast(effect); + + std::for_each(andExpression.arguments().cbegin(), andExpression.arguments().cend(), + [&](const auto argument) + { + translateExpression("postcondition", *argument, true); + }); + } + } + + m_outputStream << std::endl; + } } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -466,7 +464,7 @@ void translateVariablesBody(output::ColorStream &outputStream, const T &variable void translateLiteral(output::ColorStream &outputStream, const Expression &literal) { // Translate single predicate - if (literal.expressionType() == Expression::Type::Predicate) + if (literal.is()) { const auto &predicate = dynamic_cast(literal); @@ -477,7 +475,7 @@ void translateLiteral(output::ColorStream &outputStream, const Expression &liter outputStream << ", " << output::Boolean("true") << ")"; } // Assuming that "not" expression may only contain a predicate - else if (literal.expressionType() == Expression::Type::Not) + else if (literal.is()) { const auto ¬Expression = dynamic_cast(literal); @@ -492,7 +490,7 @@ void translateLiteral(output::ColorStream &outputStream, const Expression &liter translatePredicate(outputStream, predicate); outputStream << ", " << output::Boolean("false") << ")"; } - else if (literal.expressionType() == Expression::Type::DerivedPredicate) + else if (literal.is()) { const auto &derivedPredicate = dynamic_cast(literal); @@ -527,13 +525,13 @@ void translatePredicate(output::ColorStream &outputStream, const expressions::Pr { outputStream << ", "; - if ((*i)->expressionType() == Expression::Type::Constant) + if ((*i)->is()) { const auto &constant = dynamic_cast(**i); outputStream << output::Keyword("constant") << "(" << output::String(constant.name().c_str()) << ")"; } - else if ((*i)->expressionType() == Expression::Type::Variable) + else if ((*i)->is()) { const auto &variable = dynamic_cast(**i); @@ -582,35 +580,34 @@ void TranslatorASP::translateInitialState() const const auto &initialStateFacts = m_description.problem().initialState().facts(); - std::for_each(initialStateFacts.cbegin(), initialStateFacts.cend(), - [&](const auto &fact) + for (const auto &fact : initialStateFacts) + { + m_outputStream << std::endl << output::Function("initialState") << "("; + + // Translate single predicate + if (fact->is()) { - m_outputStream << std::endl << output::Function("initialState") << "("; + const auto &predicate = dynamic_cast(*fact); - // Translate single predicate - if (fact->expressionType() == Expression::Type::Predicate) - { - const auto &predicate = dynamic_cast(*fact); + m_outputStream << output::Keyword("variable") << "("; + translatePredicate(m_outputStream, predicate); + m_outputStream << "), " << output::Keyword("value") << "("; + translatePredicate(m_outputStream, predicate); + m_outputStream << ", " << output::Boolean("true") << ")"; + } + // Assuming that "not" expression may only contain a predicate + else if (fact->is()) + { + const auto ¬Expression = dynamic_cast(*fact); - m_outputStream << output::Keyword("variable") << "("; - translatePredicate(m_outputStream, predicate); - m_outputStream << "), " << output::Keyword("value") << "("; - translatePredicate(m_outputStream, predicate); - m_outputStream << ", " << output::Boolean("true") << ")"; - } - // Assuming that "not" expression may only contain a predicate - else if (fact->expressionType() == Expression::Type::Not) - { - const auto ¬Expression = dynamic_cast(*fact); + if (notExpression.argument()->expressionType() != Expression::Type::Predicate) + throw output::TranslatorException("only negations of simple predicates supported in initial state currently"); + } + else + throw output::TranslatorException("only predicates and their negations supported in initial state currently"); - if (notExpression.argument()->expressionType() != Expression::Type::Predicate) - throw output::TranslatorException("only negations of simple predicates supported in initial state currently"); - } - else - throw output::TranslatorException("only predicates and their negations supported in initial state currently"); - - m_outputStream << ")."; - }); + m_outputStream << ")."; + } m_outputStream << std::endl << std::endl @@ -635,8 +632,7 @@ void TranslatorASP::translateGoal() const const auto &goal = m_description.problem().goal(); - if (goal.expressionType() == Expression::Type::Predicate - || goal.expressionType() == Expression::Type::Not) + if (goal.is() || goal.is()) { m_outputStream << std::endl << output::Function("goal") << "("; @@ -644,7 +640,7 @@ void TranslatorASP::translateGoal() const m_outputStream << ")."; } - else if (goal.expressionType() == Expression::Type::And) + else if (goal.is()) { const auto &andExpression = dynamic_cast(goal); diff --git a/src/plasp/pddl/expressions/Not.cpp b/src/plasp/pddl/expressions/Not.cpp index 01e8a98..297c904 100644 --- a/src/plasp/pddl/expressions/Not.cpp +++ b/src/plasp/pddl/expressions/Not.cpp @@ -2,9 +2,11 @@ #include #include +#include #include #include #include +#include namespace plasp { @@ -79,15 +81,13 @@ ExpressionPointer Not::simplified() m_argument = m_argument->simplified(); + if (!m_argument->is()) + return this; + // Remove double negations - if (m_argument->expressionType() == Expression::Type::Not) - { - const auto ¬Expression = dynamic_cast(*m_argument); + const auto ¬Expression = dynamic_cast(*m_argument); - return notExpression.argument(); - } - - return this; + return notExpression.argument(); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -104,11 +104,8 @@ ExpressionPointer Not::decomposed(DerivedPredicates &derivedPredicates) m_argument = m_argument->decomposed(derivedPredicates); // Predicates and derived predicates can be directly negated - if (m_argument->expressionType() == Expression::Type::Predicate - || m_argument->expressionType() == Expression::Type::DerivedPredicate) - { + if (m_argument->is() || m_argument->is()) return this; - } derivedPredicates.emplace_back(new DerivedPredicate()); auto &derivedPredicate = derivedPredicates.back(); diff --git a/src/plasp/pddl/expressions/Or.cpp b/src/plasp/pddl/expressions/Or.cpp index 25d8713..fe43f4c 100644 --- a/src/plasp/pddl/expressions/Or.cpp +++ b/src/plasp/pddl/expressions/Or.cpp @@ -33,7 +33,7 @@ ExpressionPointer Or::decomposed(DerivedPredicates &derivedPredicates) Expressions conjunction; // “and” expressions can directly be inlined into the derived predicate - if (argument->expressionType() == Expression::Type::And) + if (argument->is()) { const auto &andExpression = dynamic_cast(*argument);