diff --git a/lib/pddlparse/src/pddlparse/detail/normalization/Reduction.cpp b/lib/pddlparse/src/pddlparse/detail/normalization/Reduction.cpp index 11e6b40..ba55898 100644 --- a/lib/pddlparse/src/pddlparse/detail/normalization/Reduction.cpp +++ b/lib/pddlparse/src/pddlparse/detail/normalization/Reduction.cpp @@ -220,6 +220,60 @@ void negationNormalize(ast::Precondition &precondition) //////////////////////////////////////////////////////////////////////////////////////////////////// +void eliminateForAll(ast::Precondition &precondition) +{ + const auto handleAtomicFormula = + [](ast::AtomicFormula &) + { + }; + + const auto handleAnd = + [](ast::AndPointer &and_) + { + for (auto &argument : and_->arguments) + eliminateForAll(argument); + }; + + const auto handleExists = + [](ast::ExistsPointer &exists) + { + eliminateForAll(exists->argument); + }; + + const auto handleForAll = + [&](ast::ForAllPointer &forAll) + { + auto negatedArgument = std::make_unique>(std::move(forAll->argument)); + auto exists = std::make_unique>(std::move(forAll->parameters), std::move(negatedArgument)); + + precondition = std::make_unique>(std::move(exists)); + }; + + const auto handleImply = + [&](ast::ImplyPointer &imply) + { + eliminateForAll(imply->argumentLeft); + eliminateForAll(imply->argumentRight); + }; + + const auto handleNot = + [](ast::NotPointer ¬_) + { + eliminateForAll(not_->argument); + }; + + const auto handleOr = + [](ast::OrPointer &or_) + { + for (auto &argument : or_->arguments) + eliminateForAll(argument); + }; + + precondition.match(handleAtomicFormula, handleAnd, handleExists, handleForAll, handleImply, handleNot, handleOr, handleUnsupported); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void reduce(ast::Precondition &precondition) { // Replace “imply” statements with disjunctions @@ -227,6 +281,9 @@ void reduce(ast::Precondition &precondition) // Negation-normalize the precondition negationNormalize(precondition); + + // Eliminate “forall” statements + eliminateForAll(precondition); } ////////////////////////////////////////////////////////////////////////////////////////////////////