patrick
/
plasp
Archived
1
0
Fork 0
This repository has been archived on 2023-07-19. You can view files and clone it, but cannot push or open issues or pull requests.
plasp/src/plasp/pddl/expressions/Not.cpp

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 << ")";
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
}