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/lib/pddlparse/src/pddlparse/detail/normalization/Precondition.cpp

285 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <pddlparse/detail/normalization/Precondition.h>
#include <pddlparse/AST.h>
#include <pddlparse/Exception.h>
#include <pddlparse/NormalizedAST.h>
#include <pddlparse/detail/normalization/AtomicFormula.h>
#include <pddlparse/detail/normalization/CollectFreeVariables.h>
namespace pddl
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Precondition
//
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
// Forward Declarations
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::Literal normalizeNested(ast::AndPointer<ast::Precondition> &and_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
normalizedAST::Literal normalizeNested(ast::ExistsPointer<ast::Precondition> &exists, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
normalizedAST::Literal normalizeNested(ast::ForAllPointer<ast::Precondition> &forAll, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
normalizedAST::Literal normalizeNested(ast::ImplyPointer<ast::Precondition> &, normalizedAST::DerivedPredicateDeclarations &);
normalizedAST::Literal normalizeNested(ast::NotPointer<ast::Precondition> &not_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
normalizedAST::Literal normalizeNested(ast::OrPointer<ast::Precondition> &or_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
normalizedAST::Literal normalizeNested(ast::UnsupportedPointer &unsupported, normalizedAST::DerivedPredicateDeclarations &);
normalizedAST::Literal normalizeNested(ast::AtomicFormula &, normalizedAST::DerivedPredicateDeclarations &);
normalizedAST::PredicatePointer normalize(ast::UnsupportedPointer &&unsupported, normalizedAST::DerivedPredicateDeclarations &);
normalizedAST::AtomicFormula normalize(ast::AtomicFormula &atomicFormula, normalizedAST::DerivedPredicateDeclarations &);
normalizedAST::NotPointer<normalizedAST::AtomicFormula> normalize(ast::NotPointer<ast::Precondition> &&not_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
normalizedAST::AndPointer<normalizedAST::Literal> normalize(ast::AndPointer<ast::Precondition> &&and_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::DerivedPredicatePointer addDerivedPredicate(const std::vector<normalizedAST::VariableDeclaration *> &parameters, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
{
auto name = "derived-predicate-" + std::to_string(derivedPredicates.size() + 1);
normalizedAST::DerivedPredicate::Arguments arguments;
arguments.reserve(parameters.size());
for (const auto &parameter : parameters)
arguments.emplace_back(std::make_unique<normalizedAST::Variable>(parameter));
derivedPredicates.emplace_back(std::make_unique<normalizedAST::DerivedPredicateDeclaration>());
auto *derivedPredicate = derivedPredicates.back().get();
derivedPredicate->name = std::move(name);
derivedPredicate->parameters = std::move(parameters);
return std::make_unique<normalizedAST::DerivedPredicate>(std::move(arguments), derivedPredicate);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::Literal normalizeNested(ast::AndPointer<ast::Precondition> &and_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
{
std::vector<normalizedAST::VariableDeclaration *> parameters;
VariableStack variableStack;
collectFreeVariables(and_, parameters, variableStack);
auto derivedPredicate = addDerivedPredicate(parameters, derivedPredicates);
normalizedAST::And<normalizedAST::Literal>::Arguments normalizedArguments;
normalizedArguments.reserve(and_->arguments.size());
for (auto &argument : and_->arguments)
normalizedArguments.emplace_back(argument.match(
[&](auto &x) -> normalizedAST::Literal
{
return normalizeNested(x, derivedPredicates);
}));
derivedPredicate->declaration->precondition = std::make_unique<normalizedAST::And<normalizedAST::Literal>>(std::move(normalizedArguments));
// TODO: investigate, could be a compiler bug
return std::move(derivedPredicate);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::Literal normalizeNested(ast::ExistsPointer<ast::Precondition> &exists, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
{
std::vector<normalizedAST::VariableDeclaration *> parameters;
VariableStack variableStack;
collectFreeVariables(exists, parameters, variableStack);
auto derivedPredicate = addDerivedPredicate(parameters, derivedPredicates);
derivedPredicate->declaration->existentialParameters = std::move(exists->parameters);
derivedPredicate->declaration->precondition = exists->argument.match([&](auto &x){return normalizeNested(x, derivedPredicates);});
// TODO: investigate, could be a compiler bug
return std::move(derivedPredicate);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::Literal normalizeNested(ast::ForAllPointer<ast::Precondition> &, normalizedAST::DerivedPredicateDeclarations &)
{
// “forall” expressions should be reduced to negated “exists” statements at this point
throw std::logic_error("precondition not in normal form (forall), please report to the bug tracker");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::Literal normalizeNested(ast::ImplyPointer<ast::Precondition> &, normalizedAST::DerivedPredicateDeclarations &)
{
// “imply” expressions should be reduced to disjunctions at this point
throw std::logic_error("precondition not in normal form (imply), please report to the bug tracker");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::Literal normalizeNested(ast::NotPointer<ast::Precondition> &not_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
{
std::vector<normalizedAST::VariableDeclaration *> parameters;
VariableStack variableStack;
collectFreeVariables(not_, parameters, variableStack);
auto derivedPredicate = addDerivedPredicate(parameters, derivedPredicates);
auto normalizedArgumentLiteral = not_->argument.match(
[&](auto &x) -> normalizedAST::Literal
{
return normalizeNested(x, derivedPredicates);
});
// Multiple negations should be eliminated at this point
if (normalizedArgumentLiteral.is<normalizedAST::NotPointer<normalizedAST::AtomicFormula>>())
throw std::logic_error("precondition not in normal form (multiple negation), please report to the bug tracker");
auto &normalizedArgument = normalizedArgumentLiteral.get<normalizedAST::AtomicFormula>();
derivedPredicate->declaration->precondition = std::make_unique<normalizedAST::Not<normalizedAST::AtomicFormula>>(std::move(normalizedArgument));
// TODO: investigate, could be a compiler bug
return std::move(derivedPredicate);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::Literal normalizeNested(ast::OrPointer<ast::Precondition> &or_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
{
std::vector<normalizedAST::VariableDeclaration *> parameters;
VariableStack variableStack;
collectFreeVariables(or_, parameters, variableStack);
auto derivedPredicate = addDerivedPredicate(parameters, derivedPredicates);
normalizedAST::Or<normalizedAST::Literal>::Arguments normalizedArguments;
normalizedArguments.reserve(or_->arguments.size());
for (auto &argument : or_->arguments)
normalizedArguments.emplace_back(argument.match(
[&](auto &x) -> normalizedAST::Literal
{
return normalizeNested(x, derivedPredicates);
}));
derivedPredicate->declaration->precondition = std::make_unique<normalizedAST::Or<normalizedAST::Literal>>(std::move(normalizedArguments));
// TODO: investigate, could be a compiler bug
return std::move(derivedPredicate);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::Literal normalizeNested(ast::UnsupportedPointer &unsupported, normalizedAST::DerivedPredicateDeclarations &)
{
throw NormalizationException("" + unsupported->type + "” expressions in preconditions cant be normalized currently");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::Literal normalizeNested(ast::AtomicFormula &atomicFormula, normalizedAST::DerivedPredicateDeclarations &)
{
return normalize(std::move(atomicFormula));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::PredicatePointer normalize(ast::UnsupportedPointer &&unsupported, normalizedAST::DerivedPredicateDeclarations &)
{
throw NormalizationException("" + unsupported->type + "” expressions in preconditions cant be normalized currently");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::AtomicFormula normalize(ast::AtomicFormula &&atomicFormula, normalizedAST::DerivedPredicateDeclarations &)
{
return normalize(std::move(atomicFormula));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Normalize top-level negations
normalizedAST::NotPointer<normalizedAST::AtomicFormula> normalize(ast::NotPointer<ast::Precondition> &&not_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
{
// “not” expressions may be nested one time to form simple literals
if (not_->argument.is<ast::AtomicFormula>())
return std::make_unique<normalizedAST::Not<normalizedAST::AtomicFormula>>(normalize(std::move(not_->argument.get<ast::AtomicFormula>())));
auto normalizedArgument = not_->argument.match(
[&](auto &nested) -> normalizedAST::AtomicFormula
{
auto normalizedLiteral = normalizeNested(nested, derivedPredicates);
// Multiple negations should be eliminated at this point
if (normalizedLiteral.template is<normalizedAST::NotPointer<normalizedAST::AtomicFormula>>())
throw std::logic_error("precondition not in normal form (multiple negation), please report to the bug tracker");
return std::move(normalizedLiteral.template get<normalizedAST::AtomicFormula>());
});
return std::make_unique<normalizedAST::Not<normalizedAST::AtomicFormula>>(std::move(normalizedArgument));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Normalize top-level conjunctions
normalizedAST::AndPointer<normalizedAST::Literal> normalize(ast::AndPointer<ast::Precondition> &&and_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
{
normalizedAST::And<normalizedAST::Literal>::Arguments arguments;
arguments.reserve(and_->arguments.size());
const auto handleAtomicFormula =
[&](ast::AtomicFormula &atomicFormula) -> normalizedAST::Literal
{
return normalize(std::move(atomicFormula));
};
const auto handleNot =
[&](ast::NotPointer<ast::Precondition> &not_) -> normalizedAST::Literal
{
return normalize(std::move(not_), derivedPredicates);
};
const auto handleNested =
[&](auto &nested) -> normalizedAST::Literal
{
return normalizeNested(nested, derivedPredicates);
};
const auto handleUnsupported =
[&](ast::UnsupportedPointer &unsupported) -> normalizedAST::Literal
{
throw NormalizationException("" + unsupported->type + "” expressions in preconditions cant be normalized currently");
};
for (auto &&argument : and_->arguments)
{
auto normalizedArgument = argument.match(handleAtomicFormula, handleNot, handleNested, handleUnsupported);
arguments.emplace_back(std::move(normalizedArgument));
}
return std::make_unique<normalizedAST::And<normalizedAST::Literal>>(std::move(arguments));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::Precondition normalize(ast::Precondition &&precondition, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
{
return precondition.match(
[&](auto &x) -> normalizedAST::Precondition
{
return normalize(std::move(x), derivedPredicates);
});
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}