Implemented disjunctive normal form.

This commit is contained in:
2016-09-08 03:42:32 +02:00
parent 34496a7158
commit 4fc9b35c13
12 changed files with 273 additions and 1 deletions

View File

@@ -26,9 +26,16 @@ namespace pddl
//
////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer Expression::copy()
{
return this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer Expression::normalized()
{
return reduced()->negationNormalized()->prenex()->simplified();
return reduced()->negationNormalized()->prenex()->simplified()->disjunctionNormalized()->simplified();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -97,6 +104,13 @@ ExpressionPointer Expression::simplified()
////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer Expression::disjunctionNormalized()
{
return this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer Expression::negated()
{
if (expressionType() == Type::Not)

View File

@@ -3,6 +3,8 @@
#include <algorithm>
#include <iostream>
#include <plasp/pddl/expressions/Or.h>
namespace plasp
{
namespace pddl
@@ -20,6 +22,51 @@ const std::string And::Identifier = "and";
////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer And::disjunctionNormalized()
{
for (size_t i = 0; i < m_arguments.size(); i++)
{
BOOST_ASSERT(m_arguments[i]);
m_arguments[i] = m_arguments[i]->disjunctionNormalized();
}
const auto match = std::find_if(m_arguments.begin(), m_arguments.end(),
[](const auto &argument)
{
return argument->expressionType() == Expression::Type::Or;
});
if (match == m_arguments.end())
return this;
auto orExpression = OrPointer(dynamic_cast<expressions::Or *>(match->get()));
const size_t orExpressionIndex = match - m_arguments.begin();
// Apply the distributive law
// Copy this and expression for each argument of the or expression
for (size_t i = 0; i < orExpression->arguments().size(); i++)
{
auto newAndExpression = new expressions::And;
newAndExpression->arguments().resize(m_arguments.size());
for (size_t j = 0; j < m_arguments.size(); j++)
{
if (j == orExpressionIndex)
newAndExpression->arguments()[j] = orExpression->arguments()[i]->copy();
else
newAndExpression->arguments()[j] = m_arguments[j]->copy();
}
// Replace the respective argument with the new, recursively normalized and expression
orExpression->arguments()[i] = newAndExpression->disjunctionNormalized();
}
return orExpression;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
}

View File

@@ -22,6 +22,17 @@ At::At()
////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer At::copy()
{
auto result = new At;
result->m_argument = m_argument->copy();
return result;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void At::setArgument(ExpressionPointer argument)
{
m_argument = argument;
@@ -76,6 +87,17 @@ ExpressionPointer At::simplified()
////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer At::disjunctionNormalized()
{
BOOST_ASSERT(m_argument);
m_argument = m_argument->disjunctionNormalized();
return this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void At::print(std::ostream &ostream) const
{
ostream << "(at " << m_timePoint << " ";

View File

@@ -25,6 +25,17 @@ Not::Not()
////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer Not::copy()
{
auto result = new Not;
result->m_argument = m_argument->copy();
return result;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Not::setArgument(ExpressionPointer argument)
{
m_argument = argument;
@@ -150,6 +161,17 @@ ExpressionPointer Not::simplified()
////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer Not::disjunctionNormalized()
{
BOOST_ASSERT(m_argument);
m_argument = m_argument->disjunctionNormalized();
return this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Not::print(std::ostream &ostream) const
{
ostream << "(not ";