101 lines
2.4 KiB
C++
101 lines
2.4 KiB
C++
#include <plasp/pddl/expressions/Not.h>
|
|
|
|
#include <plasp/pddl/expressions/And.h>
|
|
#include <plasp/pddl/expressions/Or.h>
|
|
|
|
namespace plasp
|
|
{
|
|
namespace pddl
|
|
{
|
|
namespace expressions
|
|
{
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Not
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Not::Not()
|
|
: m_argument{nullptr}
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void Not::setArgument(ExpressionPointer argument)
|
|
{
|
|
m_argument = argument;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
ExpressionPointer Not::argument() const
|
|
{
|
|
return m_argument;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
ExpressionPointer Not::normalized()
|
|
{
|
|
BOOST_ASSERT(m_argument);
|
|
|
|
// Remove double negations immediately
|
|
if (m_argument->expressionType() == Expression::Type::Not)
|
|
{
|
|
auto &argument = dynamic_cast<Not &>(*m_argument);
|
|
|
|
return argument.m_argument->normalized();
|
|
}
|
|
|
|
m_argument = m_argument->normalized();
|
|
|
|
// De Morgan for negative conjunctions
|
|
if (m_argument->expressionType() == Expression::Type::And)
|
|
{
|
|
auto &andExpression = dynamic_cast<And &>(*m_argument);
|
|
auto orExpression = OrPointer(new Or);
|
|
|
|
orExpression->arguments().reserve(andExpression.arguments().size());
|
|
|
|
for (size_t i = 0; i < andExpression.arguments().size(); i++)
|
|
orExpression->addArgument(andExpression.arguments()[i]->negated());
|
|
|
|
return orExpression->normalized();
|
|
}
|
|
|
|
// De Morgan for negative disjunctions
|
|
if (m_argument->expressionType() == Expression::Type::Or)
|
|
{
|
|
auto &orExpression = dynamic_cast<Or &>(*m_argument);
|
|
auto andExpression = AndPointer(new And);
|
|
|
|
andExpression->arguments().reserve(orExpression.arguments().size());
|
|
|
|
for (size_t i = 0; i < orExpression.arguments().size(); i++)
|
|
andExpression->addArgument(orExpression.arguments()[i]->negated());
|
|
|
|
return andExpression->normalized();
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void Not::print(std::ostream &ostream) const
|
|
{
|
|
ostream << "(not ";
|
|
|
|
m_argument->print(ostream);
|
|
|
|
ostream << ")";
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}
|
|
}
|
|
}
|