diff --git a/lib/pddlparse/include/pddlparse/detail/normalization/Reduction.h b/lib/pddlparse/include/pddlparse/detail/normalization/Reduction.h new file mode 100644 index 0000000..2ee5cc0 --- /dev/null +++ b/lib/pddlparse/include/pddlparse/detail/normalization/Reduction.h @@ -0,0 +1,26 @@ +#ifndef __PDDL_PARSE__DETAIL__NORMALIZATION__REDUCTION_H +#define __PDDL_PARSE__DETAIL__NORMALIZATION__REDUCTION_H + +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Reduction +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void reduce(ast::Precondition &precondition); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/src/pddlparse/detail/normalization/Precondition.cpp b/lib/pddlparse/src/pddlparse/detail/normalization/Precondition.cpp index 45977b4..db68191 100644 --- a/lib/pddlparse/src/pddlparse/detail/normalization/Precondition.cpp +++ b/lib/pddlparse/src/pddlparse/detail/normalization/Precondition.cpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace pddl { @@ -275,6 +276,9 @@ normalizedAST::AndPointer normalize(ast::AndPointer normalizedAST::Precondition { diff --git a/lib/pddlparse/src/pddlparse/detail/normalization/Reduction.cpp b/lib/pddlparse/src/pddlparse/detail/normalization/Reduction.cpp new file mode 100644 index 0000000..9d29cef --- /dev/null +++ b/lib/pddlparse/src/pddlparse/detail/normalization/Reduction.cpp @@ -0,0 +1,95 @@ +#include + +#include +#include +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Reduction +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +const auto handleUnsupported = + [](ast::UnsupportedPointer &unsupported) + { + throw NormalizationException("“" + unsupported->type + "” expressions in preconditions can’t be normalized currently"); + }; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void eliminateImply(ast::Precondition &precondition) +{ + const auto handleAtomicFormula = + [](ast::AtomicFormula &) + { + }; + + const auto handleAnd = + [](ast::AndPointer &and_) + { + for (auto &argument : and_->arguments) + eliminateImply(argument); + }; + + const auto handleExists = + [](ast::ExistsPointer &exists) + { + eliminateImply(exists->argument); + }; + + const auto handleForAll = + [](ast::ForAllPointer &forAll) + { + eliminateImply(forAll->argument); + }; + + const auto handleImply = + [&](ast::ImplyPointer &imply) + { + eliminateImply(imply->argumentLeft); + eliminateImply(imply->argumentRight); + + ast::Or::Arguments arguments; + arguments.reserve(2); + arguments.emplace_back(std::make_unique>(std::move(imply->argumentLeft))); + arguments.emplace_back(std::move(imply->argumentRight)); + + precondition = std::make_unique>(std::move(arguments)); + }; + + const auto handleNot = + [](ast::NotPointer ¬_) + { + eliminateImply(not_->argument); + }; + + const auto handleOr = + [](ast::OrPointer &or_) + { + for (auto &argument : or_->arguments) + eliminateImply(argument); + }; + + precondition.match(handleAtomicFormula, handleAnd, handleExists, handleForAll, handleImply, handleNot, handleOr, handleUnsupported); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void reduce(ast::Precondition &precondition) +{ + // Replace “imply” statements with disjunctions + eliminateImply(precondition); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +}