Implemented negation normalization (NFF).
This commit is contained in:
parent
939c2c735c
commit
994801525a
@ -14,6 +14,7 @@
|
||||
#include <pddlparse/Normalize.h>
|
||||
#include <pddlparse/NormalizedASTOutput.h>
|
||||
#include <pddlparse/Parse.h>
|
||||
#include <pddlparse/detail/normalization/Reduction.h>
|
||||
|
||||
#include <plasp/LanguageDetection.h>
|
||||
#include <plasp/TranslatorException.h>
|
||||
|
@ -17,6 +17,15 @@ namespace detail
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Forward declarations
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void eliminateImply(ast::Precondition &precondition);
|
||||
void negationNormalize(ast::Precondition &precondition);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const auto handleUnsupported =
|
||||
[](ast::UnsupportedPointer &unsupported)
|
||||
{
|
||||
@ -83,10 +92,141 @@ void eliminateImply(ast::Precondition &precondition)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Negation-normalize an expression whose parent is a “not” expression
|
||||
void negationNormalizeNegated(ast::Precondition &precondition, ast::Precondition &parent)
|
||||
{
|
||||
const auto handleAtomicFormula =
|
||||
[](ast::AtomicFormula &)
|
||||
{
|
||||
};
|
||||
|
||||
const auto handleAnd =
|
||||
[&](ast::AndPointer<ast::Precondition> &and_)
|
||||
{
|
||||
ast::Or<ast::Precondition>::Arguments arguments;
|
||||
arguments.reserve(and_->arguments.size());
|
||||
|
||||
// Apply De Morgan
|
||||
for (auto &argument : and_->arguments)
|
||||
arguments.emplace_back(std::make_unique<ast::Not<ast::Precondition>>(std::move(argument)));
|
||||
|
||||
// Finally, negation-normalize each argument
|
||||
for (auto &argument : arguments)
|
||||
negationNormalize(argument);
|
||||
|
||||
// Replace the parent “not” containing this “and” with an “or” over the negated arguments
|
||||
parent = std::make_unique<ast::Or<ast::Precondition>>(std::move(arguments));
|
||||
};
|
||||
|
||||
const auto handleExists =
|
||||
[](ast::ExistsPointer<ast::Precondition> &exists)
|
||||
{
|
||||
negationNormalize(exists->argument);
|
||||
};
|
||||
|
||||
const auto handleForAll =
|
||||
[](ast::ForAllPointer<ast::Precondition> &forAll)
|
||||
{
|
||||
negationNormalize(forAll->argument);
|
||||
};
|
||||
|
||||
const auto handleImply =
|
||||
[](ast::ImplyPointer<ast::Precondition> &)
|
||||
{
|
||||
throw std::logic_error("precondition not ready for negation normalization (imply), please report to the bug tracker");
|
||||
};
|
||||
|
||||
const auto handleNot =
|
||||
[&](ast::NotPointer<ast::Precondition> ¬_)
|
||||
{
|
||||
negationNormalize(not_->argument);
|
||||
|
||||
// As the parent contains the argument, the argument needs to be saved before overwriting the parent
|
||||
// TODO: check whether this workaround can be avoided
|
||||
auto argument = std::move(not_->argument);
|
||||
parent = std::move(argument);
|
||||
};
|
||||
|
||||
const auto handleOr =
|
||||
[&](ast::OrPointer<ast::Precondition> &or_)
|
||||
{
|
||||
ast::And<ast::Precondition>::Arguments arguments;
|
||||
arguments.reserve(or_->arguments.size());
|
||||
|
||||
// Apply De Morgan
|
||||
for (auto &argument : or_->arguments)
|
||||
arguments.emplace_back(std::make_unique<ast::Not<ast::Precondition>>(std::move(argument)));
|
||||
|
||||
// Finally, negation-normalize each argument
|
||||
for (auto &argument : arguments)
|
||||
negationNormalize(argument);
|
||||
|
||||
// Replace the parent “not” containing this “or” with an “and” over the negated arguments
|
||||
parent = std::make_unique<ast::And<ast::Precondition>>(std::move(arguments));
|
||||
};
|
||||
|
||||
precondition.match(handleAtomicFormula, handleAnd, handleExists, handleForAll, handleImply, handleNot, handleOr, handleUnsupported);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void negationNormalize(ast::Precondition &precondition)
|
||||
{
|
||||
const auto handleAtomicFormula =
|
||||
[](ast::AtomicFormula &)
|
||||
{
|
||||
};
|
||||
|
||||
const auto handleAnd =
|
||||
[](ast::AndPointer<ast::Precondition> &and_)
|
||||
{
|
||||
for (auto &argument : and_->arguments)
|
||||
negationNormalize(argument);
|
||||
};
|
||||
|
||||
const auto handleExists =
|
||||
[](ast::ExistsPointer<ast::Precondition> &exists)
|
||||
{
|
||||
negationNormalize(exists->argument);
|
||||
};
|
||||
|
||||
const auto handleForAll =
|
||||
[](ast::ForAllPointer<ast::Precondition> &forAll)
|
||||
{
|
||||
negationNormalize(forAll->argument);
|
||||
};
|
||||
|
||||
const auto handleImply =
|
||||
[](ast::ImplyPointer<ast::Precondition> &)
|
||||
{
|
||||
throw std::logic_error("precondition not ready for negation normalization (imply), please report to the bug tracker");
|
||||
};
|
||||
|
||||
const auto handleNot =
|
||||
[&](ast::NotPointer<ast::Precondition> ¬_)
|
||||
{
|
||||
negationNormalizeNegated(not_->argument, precondition);
|
||||
};
|
||||
|
||||
const auto handleOr =
|
||||
[](ast::OrPointer<ast::Precondition> &or_)
|
||||
{
|
||||
for (auto &argument : or_->arguments)
|
||||
negationNormalize(argument);
|
||||
};
|
||||
|
||||
precondition.match(handleAtomicFormula, handleAnd, handleExists, handleForAll, handleImply, handleNot, handleOr, handleUnsupported);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void reduce(ast::Precondition &precondition)
|
||||
{
|
||||
// Replace “imply” statements with disjunctions
|
||||
eliminateImply(precondition);
|
||||
|
||||
// Negation-normalize the precondition
|
||||
negationNormalize(precondition);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
Reference in New Issue
Block a user