Implemented simplification of directly nested n-ary expressions of the same type.
This commit is contained in:
parent
79d449d0df
commit
263b611a7b
|
@ -112,6 +112,7 @@ class Expression
|
||||||
ExpressionPointer normalized();
|
ExpressionPointer normalized();
|
||||||
virtual ExpressionPointer reduced();
|
virtual ExpressionPointer reduced();
|
||||||
virtual ExpressionPointer negationNormalized();
|
virtual ExpressionPointer negationNormalized();
|
||||||
|
virtual ExpressionPointer simplified();
|
||||||
ExpressionPointer negated();
|
ExpressionPointer negated();
|
||||||
|
|
||||||
virtual void print(std::ostream &ostream) const = 0;
|
virtual void print(std::ostream &ostream) const = 0;
|
||||||
|
|
|
@ -35,6 +35,7 @@ class NAry: public ExpressionCRTP<Derived>
|
||||||
|
|
||||||
ExpressionPointer reduced() override;
|
ExpressionPointer reduced() override;
|
||||||
ExpressionPointer negationNormalized() override;
|
ExpressionPointer negationNormalized() override;
|
||||||
|
ExpressionPointer simplified() override;
|
||||||
|
|
||||||
void print(std::ostream &ostream) const override;
|
void print(std::ostream &ostream) const override;
|
||||||
|
|
||||||
|
@ -145,19 +146,41 @@ inline ExpressionPointer NAry<Derived>::negationNormalized()
|
||||||
m_arguments[i] = m_arguments[i]->negationNormalized();
|
m_arguments[i] = m_arguments[i]->negationNormalized();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*// Unify same-type children
|
return this;
|
||||||
for (size_t i = 0; i < m_arguments.size(); i++)
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived>
|
||||||
|
inline ExpressionPointer NAry<Derived>::simplified()
|
||||||
|
{
|
||||||
|
// Associate same-type children, such as (a && (b && c)) == (a && b && c)
|
||||||
|
for (size_t i = 0; i < m_arguments.size();)
|
||||||
{
|
{
|
||||||
|
m_arguments[i] = m_arguments[i]->simplified();
|
||||||
|
|
||||||
if (m_arguments[i]->expressionType() != Derived::ExpressionType)
|
if (m_arguments[i]->expressionType() != Derived::ExpressionType)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
auto &nAryExpression = dynamic_cast<Derived &>(*m_arguments[i]);
|
auto child = m_arguments[i];
|
||||||
|
auto &nAryExpression = dynamic_cast<Derived &>(*child);
|
||||||
|
|
||||||
m_arguments.reserve(m_arguments.size() + nAryExpression.arguments().size());
|
BOOST_ASSERT(!nAryExpression.arguments().empty());
|
||||||
|
|
||||||
m_arguments.emplace_back(nAryExpression.arguments());
|
// Remove former child by replacing it with the first one of the child
|
||||||
m_arguments.erase(const_iterator __position)
|
m_arguments[i] = nAryExpression.arguments().front();
|
||||||
}*/
|
|
||||||
|
// Reserve space for new arguments
|
||||||
|
m_arguments.reserve(m_arguments.size() + nAryExpression.arguments().size() - 1);
|
||||||
|
|
||||||
|
// Copy all but first element
|
||||||
|
m_arguments.insert(m_arguments.end(), nAryExpression.arguments().begin() + 1, nAryExpression.arguments().end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: recognize tautologies
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace pddl
|
||||||
|
|
||||||
ExpressionPointer Expression::normalized()
|
ExpressionPointer Expression::normalized()
|
||||||
{
|
{
|
||||||
return reduced()->negationNormalized();
|
return reduced()->negationNormalized()->simplified();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -45,6 +45,13 @@ ExpressionPointer Expression::negationNormalized()
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ExpressionPointer Expression::simplified()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ExpressionPointer Expression::negated()
|
ExpressionPointer Expression::negated()
|
||||||
{
|
{
|
||||||
if (expressionType() == Type::Not)
|
if (expressionType() == Type::Not)
|
||||||
|
|
|
@ -10,7 +10,7 @@ using namespace plasp::pddl;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TEST(PDDLNormalizationTests, Reduced)
|
TEST(PDDLNormalizationTests, Reduce)
|
||||||
{
|
{
|
||||||
auto n1 = expressions::NotPointer(new expressions::Not);
|
auto n1 = expressions::NotPointer(new expressions::Not);
|
||||||
auto n2 = expressions::NotPointer(new expressions::Not);
|
auto n2 = expressions::NotPointer(new expressions::Not);
|
||||||
|
@ -38,6 +38,36 @@ TEST(PDDLNormalizationTests, Reduced)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TEST(PDDLNormalizationTests, Simplify)
|
||||||
|
{
|
||||||
|
auto a1 = expressions::AndPointer(new expressions::And);
|
||||||
|
auto a2 = expressions::AndPointer(new expressions::And);
|
||||||
|
auto o1 = expressions::OrPointer(new expressions::Or);
|
||||||
|
auto o2 = expressions::OrPointer(new expressions::Or);
|
||||||
|
|
||||||
|
a1->addArgument(new expressions::Dummy("a"));
|
||||||
|
a1->addArgument(new expressions::Dummy("b"));
|
||||||
|
a1->addArgument(a2);
|
||||||
|
|
||||||
|
a2->addArgument(new expressions::Dummy("c"));
|
||||||
|
a2->addArgument(new expressions::Dummy("d"));
|
||||||
|
a2->addArgument(o1);
|
||||||
|
|
||||||
|
o1->addArgument(new expressions::Dummy("e"));
|
||||||
|
o1->addArgument(new expressions::Dummy("f"));
|
||||||
|
o1->addArgument(o2);
|
||||||
|
|
||||||
|
o2->addArgument(new expressions::Dummy("g"));
|
||||||
|
o2->addArgument(new expressions::Dummy("h"));
|
||||||
|
|
||||||
|
std::stringstream output;
|
||||||
|
a1->simplified()->print(output);
|
||||||
|
|
||||||
|
ASSERT_EQ(output.str(), "(and (a) (b) (c) (d) (or (e) (f) (g) (h)))");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TEST(PDDLNormalizationTests, Implication)
|
TEST(PDDLNormalizationTests, Implication)
|
||||||
{
|
{
|
||||||
auto i = expressions::ImplyPointer(new expressions::Imply);
|
auto i = expressions::ImplyPointer(new expressions::Imply);
|
||||||
|
@ -85,7 +115,6 @@ TEST(PDDLNormalizationTests, DeMorganNegativeConjunction)
|
||||||
ASSERT_EQ(output.str(), "(or (not (a)) (not (b)) (not (c)))");
|
ASSERT_EQ(output.str(), "(or (not (a)) (not (b)) (not (c)))");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TEST(PDDLNormalizationTests, DeMorganNegativeDisjunction)
|
TEST(PDDLNormalizationTests, DeMorganNegativeDisjunction)
|
||||||
|
|
Reference in New Issue