diff --git a/include/plasp/pddl/Expression.h b/include/plasp/pddl/Expression.h index 06441c2..62d6a67 100644 --- a/include/plasp/pddl/Expression.h +++ b/include/plasp/pddl/Expression.h @@ -1,6 +1,8 @@ #ifndef __PLASP__PDDL__EXPRESSION_H #define __PLASP__PDDL__EXPRESSION_H +#include + #include #include @@ -110,6 +112,8 @@ class Expression virtual ExpressionPointer normalized(); ExpressionPointer negated(); + virtual void print(std::ostream &ostream) const = 0; + private: friend void intrusive_ptr_add_ref(Expression *expression); friend void intrusive_ptr_release(Expression *expression); diff --git a/include/plasp/pddl/expressions/At.h b/include/plasp/pddl/expressions/At.h index 41b9524..fdef30e 100644 --- a/include/plasp/pddl/expressions/At.h +++ b/include/plasp/pddl/expressions/At.h @@ -39,6 +39,8 @@ class At: public ExpressionCRTP ExpressionPointer normalized() override; + void print(std::ostream &ostream) const override; + protected: size_t m_timePoint; diff --git a/include/plasp/pddl/expressions/Binary.h b/include/plasp/pddl/expressions/Binary.h index a369737..f300905 100644 --- a/include/plasp/pddl/expressions/Binary.h +++ b/include/plasp/pddl/expressions/Binary.h @@ -33,6 +33,8 @@ class Binary: public ExpressionCRTP ExpressionPointer normalized() override; + void print(std::ostream &ostream) const override; + protected: std::array m_arguments; }; @@ -102,6 +104,23 @@ inline ExpressionPointer Binary::normalized() //////////////////////////////////////////////////////////////////////////////////////////////////// +template +inline void Binary::print(std::ostream &ostream) const +{ + ostream << "(" << Derived::Identifier; + + std::for_each(m_arguments.begin(), m_arguments.end(), + [&](auto &argument) + { + ostream << " "; + argument->print(ostream); + }); + + ostream << ")"; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } } diff --git a/include/plasp/pddl/expressions/Constant.h b/include/plasp/pddl/expressions/Constant.h index 26da80f..26b3461 100644 --- a/include/plasp/pddl/expressions/Constant.h +++ b/include/plasp/pddl/expressions/Constant.h @@ -35,6 +35,8 @@ class Constant: public ExpressionCRTP const std::string &name() const; PrimitiveTypePointer type() const; + void print(std::ostream &ostream) const override; + private: static ConstantPointer parseDeclaration(Context &context); static void parseTypedDeclaration(Context &context, Domain &domain, Constants &constants); diff --git a/include/plasp/pddl/expressions/Dummy.h b/include/plasp/pddl/expressions/Dummy.h index e2eed5a..2905f49 100644 --- a/include/plasp/pddl/expressions/Dummy.h +++ b/include/plasp/pddl/expressions/Dummy.h @@ -21,12 +21,13 @@ class Dummy: public ExpressionCRTP public: static const Expression::Type ExpressionType = Expression::Type::Dummy; - bool isNormalized() const; + public: + Dummy(std::string name); - ExpressionPointer normalized() override; + void print(std::ostream &ostream) const override; private: - bool m_isNormalized = false; + std::string m_name; }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/expressions/NAry.h b/include/plasp/pddl/expressions/NAry.h index a296199..62b1d6f 100644 --- a/include/plasp/pddl/expressions/NAry.h +++ b/include/plasp/pddl/expressions/NAry.h @@ -35,6 +35,8 @@ class NAry: public ExpressionCRTP ExpressionPointer normalized() override; + void print(std::ostream &ostream) const override; + protected: Expressions m_arguments; }; @@ -132,6 +134,23 @@ inline ExpressionPointer NAry::normalized() //////////////////////////////////////////////////////////////////////////////////////////////////// +template +inline void NAry::print(std::ostream &ostream) const +{ + ostream << "(" << Derived::Identifier; + + std::for_each(m_arguments.begin(), m_arguments.end(), + [&](auto &argument) + { + ostream << " "; + argument->print(ostream); + }); + + ostream << ")"; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } } diff --git a/include/plasp/pddl/expressions/Not.h b/include/plasp/pddl/expressions/Not.h index 1e3abd5..52ad743 100644 --- a/include/plasp/pddl/expressions/Not.h +++ b/include/plasp/pddl/expressions/Not.h @@ -34,6 +34,8 @@ class Not: public ExpressionCRTP ExpressionPointer normalized() override; + void print(std::ostream &ostream) const override; + protected: ExpressionPointer m_argument; }; diff --git a/include/plasp/pddl/expressions/Predicate.h b/include/plasp/pddl/expressions/Predicate.h index fca134f..3dd81c3 100644 --- a/include/plasp/pddl/expressions/Predicate.h +++ b/include/plasp/pddl/expressions/Predicate.h @@ -30,6 +30,8 @@ class Predicate: public ExpressionCRTP bool isDeclared() const; + void print(std::ostream &ostream) const override; + private: Predicate(); diff --git a/include/plasp/pddl/expressions/PredicateDeclaration.h b/include/plasp/pddl/expressions/PredicateDeclaration.h index b14622a..f977d28 100644 --- a/include/plasp/pddl/expressions/PredicateDeclaration.h +++ b/include/plasp/pddl/expressions/PredicateDeclaration.h @@ -31,6 +31,8 @@ class PredicateDeclaration: public ExpressionCRTP void normalizeParameterNames(); + void print(std::ostream &ostream) const override; + private: PredicateDeclaration(); diff --git a/include/plasp/pddl/expressions/PrimitiveType.h b/include/plasp/pddl/expressions/PrimitiveType.h index 11e6f58..a471d00 100644 --- a/include/plasp/pddl/expressions/PrimitiveType.h +++ b/include/plasp/pddl/expressions/PrimitiveType.h @@ -35,6 +35,8 @@ class PrimitiveType: public ExpressionCRTP const std::string &name() const; const PrimitiveTypes &parentTypes() const; + void print(std::ostream &ostream) const override; + private: void setDirty(bool isDirty = true); bool isDirty() const; diff --git a/include/plasp/pddl/expressions/Unsupported.h b/include/plasp/pddl/expressions/Unsupported.h index 6be1be4..48e0ef7 100644 --- a/include/plasp/pddl/expressions/Unsupported.h +++ b/include/plasp/pddl/expressions/Unsupported.h @@ -27,6 +27,8 @@ class Unsupported: public ExpressionCRTP public: const std::string &type() const; + void print(std::ostream &ostream) const override; + private: std::string m_type; }; diff --git a/include/plasp/pddl/expressions/Variable.h b/include/plasp/pddl/expressions/Variable.h index 1d8e333..9a5522a 100644 --- a/include/plasp/pddl/expressions/Variable.h +++ b/include/plasp/pddl/expressions/Variable.h @@ -37,6 +37,8 @@ class Variable: public ExpressionCRTP void setDirty(bool isDirty = true); bool isDirty() const; + void print(std::ostream &ostream) const override; + private: static void parseDeclaration(Context &context, Variables ¶meters); diff --git a/src/plasp/pddl/expressions/And.cpp b/src/plasp/pddl/expressions/And.cpp index a017773..912b966 100644 --- a/src/plasp/pddl/expressions/And.cpp +++ b/src/plasp/pddl/expressions/And.cpp @@ -1,5 +1,8 @@ #include +#include +#include + namespace plasp { namespace pddl diff --git a/src/plasp/pddl/expressions/At.cpp b/src/plasp/pddl/expressions/At.cpp index ec8f248..2d0c245 100644 --- a/src/plasp/pddl/expressions/At.cpp +++ b/src/plasp/pddl/expressions/At.cpp @@ -45,6 +45,17 @@ ExpressionPointer At::normalized() //////////////////////////////////////////////////////////////////////////////////////////////////// +void At::print(std::ostream &ostream) const +{ + ostream << "(at " << m_timePoint << " "; + + m_argument->print(ostream); + + ostream << ")"; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } } diff --git a/src/plasp/pddl/expressions/Constant.cpp b/src/plasp/pddl/expressions/Constant.cpp index 7f13f0c..b5477e6 100644 --- a/src/plasp/pddl/expressions/Constant.cpp +++ b/src/plasp/pddl/expressions/Constant.cpp @@ -239,6 +239,13 @@ PrimitiveTypePointer Constant::type() const //////////////////////////////////////////////////////////////////////////////////////////////////// +void Constant::print(std::ostream &ostream) const +{ + ostream << "(" << m_name << ")"; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } } diff --git a/src/plasp/pddl/expressions/Dummy.cpp b/src/plasp/pddl/expressions/Dummy.cpp index d1fac3d..fec67d5 100644 --- a/src/plasp/pddl/expressions/Dummy.cpp +++ b/src/plasp/pddl/expressions/Dummy.cpp @@ -15,18 +15,16 @@ namespace expressions // //////////////////////////////////////////////////////////////////////////////////////////////////// -bool Dummy::isNormalized() const +Dummy::Dummy(std::string name) +: m_name{name} { - return m_isNormalized; } //////////////////////////////////////////////////////////////////////////////////////////////////// -ExpressionPointer Dummy::normalized() +void Dummy::print(std::ostream &ostream) const { - m_isNormalized = true; - - return this; + ostream << "(" << m_name << ")"; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/expressions/Not.cpp b/src/plasp/pddl/expressions/Not.cpp index a6ff9b1..c65bcd0 100644 --- a/src/plasp/pddl/expressions/Not.cpp +++ b/src/plasp/pddl/expressions/Not.cpp @@ -84,6 +84,17 @@ ExpressionPointer Not::normalized() //////////////////////////////////////////////////////////////////////////////////////////////////// +void Not::print(std::ostream &ostream) const +{ + ostream << "(not "; + + m_argument->print(ostream); + + ostream << ")"; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } } diff --git a/src/plasp/pddl/expressions/Predicate.cpp b/src/plasp/pddl/expressions/Predicate.cpp index dbf6b8e..0e40cbc 100644 --- a/src/plasp/pddl/expressions/Predicate.cpp +++ b/src/plasp/pddl/expressions/Predicate.cpp @@ -170,6 +170,14 @@ const Expressions &Predicate::arguments() const //////////////////////////////////////////////////////////////////////////////////////////////////// +void Predicate::print(std::ostream &ostream) const +{ + // TODO: implement correctly + ostream << "()"; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } } diff --git a/src/plasp/pddl/expressions/PredicateDeclaration.cpp b/src/plasp/pddl/expressions/PredicateDeclaration.cpp index 377f9cb..1b20c2d 100644 --- a/src/plasp/pddl/expressions/PredicateDeclaration.cpp +++ b/src/plasp/pddl/expressions/PredicateDeclaration.cpp @@ -87,6 +87,14 @@ void PredicateDeclaration::normalizeParameterNames() //////////////////////////////////////////////////////////////////////////////////////////////////// +void PredicateDeclaration::print(std::ostream &ostream) const +{ + // TODO: implement correctly + ostream << "()"; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } } diff --git a/src/plasp/pddl/expressions/PrimitiveType.cpp b/src/plasp/pddl/expressions/PrimitiveType.cpp index 198f76e..bd1dc10 100644 --- a/src/plasp/pddl/expressions/PrimitiveType.cpp +++ b/src/plasp/pddl/expressions/PrimitiveType.cpp @@ -169,6 +169,14 @@ const PrimitiveTypes &PrimitiveType::parentTypes() const //////////////////////////////////////////////////////////////////////////////////////////////////// +void PrimitiveType::print(std::ostream &ostream) const +{ + // TODO: implement correctly + ostream << "()"; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } } diff --git a/src/plasp/pddl/expressions/Unsupported.cpp b/src/plasp/pddl/expressions/Unsupported.cpp index 7202f50..2fd6531 100644 --- a/src/plasp/pddl/expressions/Unsupported.cpp +++ b/src/plasp/pddl/expressions/Unsupported.cpp @@ -41,6 +41,14 @@ const std::string &Unsupported::type() const //////////////////////////////////////////////////////////////////////////////////////////////////// +void Unsupported::print(std::ostream &ostream) const +{ + // TODO: implement correctly + ostream << "()"; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } } diff --git a/src/plasp/pddl/expressions/Variable.cpp b/src/plasp/pddl/expressions/Variable.cpp index 0a3286d..1de1c5f 100644 --- a/src/plasp/pddl/expressions/Variable.cpp +++ b/src/plasp/pddl/expressions/Variable.cpp @@ -203,6 +203,14 @@ bool Variable::isDirty() const //////////////////////////////////////////////////////////////////////////////////////////////////// +void Variable::print(std::ostream &ostream) const +{ + // TODO: implement correctly + ostream << "()"; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } } diff --git a/tests/TestPDDLNormalization.cpp b/tests/TestPDDLNormalization.cpp index 1954171..e65d831 100644 --- a/tests/TestPDDLNormalization.cpp +++ b/tests/TestPDDLNormalization.cpp @@ -13,28 +13,14 @@ using namespace plasp::pddl; TEST(PDDLNormalizationTests, Implication) { auto i = expressions::ImplyPointer(new expressions::Imply); - auto d1 = expressions::DummyPointer(new expressions::Dummy); - const auto d1p = d1.get(); - auto d2 = expressions::DummyPointer(new expressions::Dummy); - const auto d2p = d2.get(); - i->setArgument(0, d1); - i->setArgument(1, d2); + i->setArgument(0, new expressions::Dummy("a")); + i->setArgument(1, new expressions::Dummy("b")); - auto normalized = i->normalized(); + std::stringstream output; + i->normalized()->print(output); - ASSERT_EQ(normalized->expressionType(), Expression::Type::Or); - - const auto &o = dynamic_cast(*normalized); - - ASSERT_EQ(o.arguments()[0]->expressionType(), Expression::Type::Not); - - const auto &n = dynamic_cast(*o.arguments()[0]); - - ASSERT_EQ(n.argument(), d1p); - ASSERT_EQ(o.arguments()[1], d2p); - ASSERT_TRUE(d1p->isNormalized()); - ASSERT_TRUE(d2p->isNormalized()); + ASSERT_EQ(output.str(), "(or (not (a)) (b))"); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -43,57 +29,32 @@ TEST(PDDLNormalizationTests, DoubleNegation) { auto n1 = expressions::NotPointer(new expressions::Not); auto n2 = expressions::NotPointer(new expressions::Not); - auto d = expressions::DummyPointer(new expressions::Dummy); - const auto dp = d.get(); - n2->setArgument(std::move(d)); - n1->setArgument(std::move(n2)); + n2->setArgument(new expressions::Dummy("a")); + n1->setArgument(n2); - auto normalized = n1->normalized(); + std::stringstream output; + n1->normalized()->print(output); - ASSERT_EQ(normalized.get(), dp); - ASSERT_TRUE(dp->isNormalized()); + ASSERT_EQ(output.str(), "(a)"); } //////////////////////////////////////////////////////////////////////////////////////////////////// TEST(PDDLNormalizationTests, DeMorganNegativeConjunction) { - auto d1 = expressions::DummyPointer(new expressions::Dummy); - const auto d1p = d1.get(); - auto d2 = expressions::DummyPointer(new expressions::Dummy); - const auto d2p = d2.get(); - auto d3 = expressions::DummyPointer(new expressions::Dummy); - const auto d3p = d3.get(); - auto a = expressions::AndPointer(new expressions::And); - a->addArgument(d1); - a->addArgument(d2); - a->addArgument(d3); + a->addArgument(new expressions::Dummy("a")); + a->addArgument(new expressions::Dummy("b")); + a->addArgument(new expressions::Dummy("c")); auto n = expressions::NotPointer(new expressions::Not); n->setArgument(a); - auto normalized = n->normalized(); + std::stringstream output; + n->normalized()->print(output); - ASSERT_EQ(normalized->expressionType(), Expression::Type::Or); - - const auto &o = dynamic_cast(*normalized); - - ASSERT_EQ(o.arguments()[0]->expressionType(), Expression::Type::Not); - ASSERT_EQ(o.arguments()[1]->expressionType(), Expression::Type::Not); - ASSERT_EQ(o.arguments()[2]->expressionType(), Expression::Type::Not); - - const auto &n1 = dynamic_cast(*o.arguments()[0]); - const auto &n2 = dynamic_cast(*o.arguments()[1]); - const auto &n3 = dynamic_cast(*o.arguments()[2]); - - ASSERT_EQ(n1.argument().get(), d1p); - ASSERT_EQ(n2.argument().get(), d2p); - ASSERT_EQ(n3.argument().get(), d3p); - ASSERT_TRUE(d1p->isNormalized()); - ASSERT_TRUE(d2p->isNormalized()); - ASSERT_TRUE(d3p->isNormalized()); + ASSERT_EQ(output.str(), "(or (not (a)) (not (b)) (not (c)))"); } @@ -101,39 +62,39 @@ TEST(PDDLNormalizationTests, DeMorganNegativeConjunction) TEST(PDDLNormalizationTests, DeMorganNegativeDisjunction) { - auto d1 = expressions::DummyPointer(new expressions::Dummy); - const auto d1p = d1.get(); - auto d2 = expressions::DummyPointer(new expressions::Dummy); - const auto d2p = d2.get(); - auto d3 = expressions::DummyPointer(new expressions::Dummy); - const auto d3p = d3.get(); - - auto o = expressions::OrPointer(new expressions::Or); - o->addArgument(d1); - o->addArgument(d2); - o->addArgument(d3); + auto a = expressions::OrPointer(new expressions::Or); + a->addArgument(new expressions::Dummy("a")); + a->addArgument(new expressions::Dummy("b")); + a->addArgument(new expressions::Dummy("c")); auto n = expressions::NotPointer(new expressions::Not); - n->setArgument(o); + n->setArgument(a); - auto normalized = n->normalized(); + std::stringstream output; + n->normalized()->print(output); - ASSERT_EQ(normalized->expressionType(), Expression::Type::And); - - const auto &a = dynamic_cast(*normalized); - - ASSERT_EQ(a.arguments()[0]->expressionType(), Expression::Type::Not); - ASSERT_EQ(a.arguments()[1]->expressionType(), Expression::Type::Not); - ASSERT_EQ(a.arguments()[2]->expressionType(), Expression::Type::Not); - - const auto &n1 = dynamic_cast(*a.arguments()[0]); - const auto &n2 = dynamic_cast(*a.arguments()[1]); - const auto &n3 = dynamic_cast(*a.arguments()[2]); - - ASSERT_EQ(n1.argument().get(), d1p); - ASSERT_EQ(n2.argument().get(), d2p); - ASSERT_EQ(n3.argument().get(), d3p); - ASSERT_TRUE(d1p->isNormalized()); - ASSERT_TRUE(d2p->isNormalized()); - ASSERT_TRUE(d3p->isNormalized()); + ASSERT_EQ(output.str(), "(and (not (a)) (not (b)) (not (c)))"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +TEST(PDDLNormalizationTests, DoubleNegationInner) +{ + auto n1 = expressions::NotPointer(new expressions::Not); + auto n2 = expressions::NotPointer(new expressions::Not); + auto n3 = expressions::NotPointer(new expressions::Not); + auto a = expressions::AndPointer(new expressions::And); + + a->addArgument(new expressions::Dummy("a")); + a->addArgument(new expressions::Dummy("b")); + a->addArgument(new expressions::Dummy("c")); + + n3->setArgument(a); + n2->setArgument(n3); + n1->setArgument(n2); + + std::stringstream output; + n1->normalized()->print(output); + + ASSERT_EQ(output.str(), "(or (not (a)) (not (b)) (not (c)))"); }