Started implementing PDDL normalization.

This commit is contained in:
2017-06-23 04:18:07 +02:00
parent e4f4b5e066
commit 9d1a8f4c0f
35 changed files with 1028 additions and 117 deletions

View File

@@ -9,6 +9,9 @@ file(GLOB detail_headers "../include/pddlparse/detail/*.h")
file(GLOB detail_parsing_sources "pddlparse/detail/parsing/*.cpp")
file(GLOB detail_parsing_headers "../include/pddlparse/detail/parsing/*.h")
file(GLOB detail_normalization_sources "pddlparse/detail/normalization/*.cpp")
file(GLOB detail_normalization_headers "../include/pddlparse/detail/normalization/*.h")
set(includes
${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/../../lib/colorlog/include
@@ -25,6 +28,9 @@ set(sources
${detail_parsing_sources}
${detail_parsing_headers}
${detail_normalization_sources}
${detail_normalization_headers}
)
set(libraries

View File

@@ -0,0 +1,41 @@
#include <pddlparse/detail/normalization/Action.h>
#include <pddlparse/AST.h>
#include <pddlparse/NormalizedAST.h>
#include <pddlparse/detail/normalization/Effect.h>
#include <pddlparse/detail/normalization/Precondition.h>
namespace pddl
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Action
//
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::ActionPointer normalize(ast::ActionPointer &&action, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
{
auto normalizedAction = std::make_unique<normalizedAST::Action>();
normalizedAction->name = std::move(action->name);
normalizedAction->parameters = std::move(action->parameters);
if (action->precondition)
normalizedAction->precondition = normalize(std::move(action->precondition.value()), derivedPredicates);
// TODO: implement
/*
if (action->effect)
normalizedAction->effect = normalize(std::move(action->effect.value()));
*/
return normalizedAction;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@@ -0,0 +1,38 @@
#include <pddlparse/detail/normalization/AtomicFormula.h>
#include <pddlparse/AST.h>
#include <pddlparse/Exception.h>
#include <pddlparse/NormalizedAST.h>
namespace pddl
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// AtomicFormula
//
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::AtomicFormula normalize(ast::AtomicFormula &&atomicFormula)
{
const auto handleUnsupported =
[&](ast::UnsupportedPointer &unsupported) -> normalizedAST::AtomicFormula
{
throw NormalizationException("" + unsupported->type + "” expressions as literals cant be normalized currently");
};
const auto handlePredicate =
[&](ast::PredicatePointer &predicate) -> normalizedAST::AtomicFormula
{
return std::move(predicate);
};
return atomicFormula.match(handlePredicate, handleUnsupported);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@@ -0,0 +1,34 @@
#include <pddlparse/detail/normalization/Description.h>
#include <pddlparse/AST.h>
#include <pddlparse/NormalizedAST.h>
#include <pddlparse/detail/normalization/Domain.h>
#include <pddlparse/detail/normalization/Problem.h>
namespace pddl
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Description
//
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::Description normalize(ast::Description &&description)
{
normalizedAST::Description normalizedDescription;
normalizedDescription.domain = normalize(std::move(description.domain));
if (description.problem)
normalizedDescription.problem = normalize(std::move(description.problem.value()), normalizedDescription.domain.get());
return normalizedDescription;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@@ -0,0 +1,38 @@
#include <pddlparse/detail/normalization/Domain.h>
#include <pddlparse/AST.h>
#include <pddlparse/NormalizedAST.h>
#include <pddlparse/detail/normalization/Action.h>
namespace pddl
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Description
//
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::DomainPointer normalize(ast::DomainPointer &&domain)
{
auto normalizedDomain = std::make_unique<normalizedAST::Domain>();
normalizedDomain->types = std::move(domain->types);
normalizedDomain->name = std::move(domain->name);
normalizedDomain->constants = std::move(domain->constants);
normalizedDomain->predicates = std::move(domain->predicates);
normalizedDomain->actions.reserve(domain->actions.size());
for (auto &&action : domain->actions)
normalizedDomain->actions.emplace_back(normalize(std::move(action), normalizedDomain->derivedPredicates));
return normalizedDomain;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@@ -0,0 +1,28 @@
#include <pddlparse/detail/normalization/Effect.h>
#include <pddlparse/AST.h>
#include <pddlparse/Exception.h>
#include <pddlparse/NormalizedAST.h>
namespace pddl
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Effect
//
////////////////////////////////////////////////////////////////////////////////////////////////////
// TODO: implement
/*
normalizedAST::Effect normalize(ast::Effect &&)
{
}
*/
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@@ -0,0 +1,39 @@
#include <pddlparse/detail/normalization/Fact.h>
#include <pddlparse/AST.h>
#include <pddlparse/Exception.h>
#include <pddlparse/NormalizedAST.h>
#include <pddlparse/detail/normalization/Literal.h>
namespace pddl
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Fact
//
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::Fact normalize(ast::Fact &&fact)
{
const auto handleLiteral =
[&](ast::Literal &literal) -> normalizedAST::Literal
{
return normalize(std::move(literal));
};
const auto handleAt =
[&](ast::AtPointer<ast::Literal> &) -> normalizedAST::Literal
{
throw NormalizationException("“at” expressions in preconditions cant be normalized currently");
};
return fact.match(handleLiteral, handleAt);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@@ -0,0 +1,33 @@
#include <pddlparse/detail/normalization/InitialState.h>
#include <pddlparse/AST.h>
#include <pddlparse/Exception.h>
#include <pddlparse/NormalizedAST.h>
#include <pddlparse/detail/normalization/Fact.h>
namespace pddl
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// InitialState
//
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::InitialState normalize(ast::InitialState &&initialState)
{
normalizedAST::InitialState normalizedInitialState;
normalizedInitialState.facts.reserve(initialState.facts.size());
for (auto &fact : initialState.facts)
normalizedInitialState.facts.emplace_back(normalize(std::move(fact)));
return normalizedInitialState;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@@ -0,0 +1,39 @@
#include <pddlparse/detail/normalization/Literal.h>
#include <pddlparse/AST.h>
#include <pddlparse/Exception.h>
#include <pddlparse/NormalizedAST.h>
#include <pddlparse/detail/normalization/AtomicFormula.h>
namespace pddl
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Literal
//
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::Literal normalize(ast::Literal &&literal)
{
const auto handleAtomicFormula =
[&](ast::AtomicFormula &atomicFormula) -> normalizedAST::Literal
{
return normalize(std::move(atomicFormula));
};
const auto handleNot =
[&](ast::NotPointer<ast::AtomicFormula> &not_) -> normalizedAST::Literal
{
return std::make_unique<normalizedAST::Not<normalizedAST::AtomicFormula>>(normalize(std::move(not_->argument)));
};
return literal.match(handleAtomicFormula, handleNot);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@@ -0,0 +1,218 @@
#include <pddlparse/detail/normalization/Precondition.h>
#include <pddlparse/AST.h>
#include <pddlparse/Exception.h>
#include <pddlparse/NormalizedAST.h>
#include <pddlparse/detail/normalization/AtomicFormula.h>
namespace pddl
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Precondition
//
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::DerivedPredicatePointer addDerivedPredicate(normalizedAST::DerivedPredicateDeclarations &derivedPredicates, const std::string &type)
{
auto name = "derived-" + type + "-" + std::to_string(derivedPredicates.size() + 1);
derivedPredicates.emplace_back(std::make_unique<normalizedAST::DerivedPredicateDeclaration>(std::move(name), normalizedAST::VariableDeclarations()));
return std::make_unique<normalizedAST::DerivedPredicate>(normalizedAST::DerivedPredicate::Arguments(), derivedPredicates.back().get());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::DerivedPredicatePointer normalizeNested(ast::AndPointer<ast::Precondition> &, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
{
// TODO: handle arguments recursively
return addDerivedPredicate(derivedPredicates, "and");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::DerivedPredicatePointer normalizeNested(ast::AtomicFormula &, normalizedAST::DerivedPredicateDeclarations &)
{
// TODO: add explanation
throw std::logic_error("atomic formulas should have been handled earlier");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::DerivedPredicatePointer normalizeNested(ast::ExistsPointer<ast::Precondition> &, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
{
// TODO: handle arguments recursively
return addDerivedPredicate(derivedPredicates, "exists");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::DerivedPredicatePointer normalizeNested(ast::ForAllPointer<ast::Precondition> &, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
{
// TODO: handle arguments recursively
return addDerivedPredicate(derivedPredicates, "forall");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::DerivedPredicatePointer normalizeNested(ast::ImplyPointer<ast::Precondition> &, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
{
// TODO: handle arguments recursively
return addDerivedPredicate(derivedPredicates, "imply");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::DerivedPredicatePointer normalizeNested(ast::NotPointer<ast::Precondition> &, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
{
// TODO: handle arguments recursively
return addDerivedPredicate(derivedPredicates, "not");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::DerivedPredicatePointer normalizeNested(ast::OrPointer<ast::Precondition> &, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
{
// TODO: handle arguments recursively
return addDerivedPredicate(derivedPredicates, "or");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::PredicatePointer normalize(ast::UnsupportedPointer &&unsupported, normalizedAST::DerivedPredicateDeclarations &)
{
throw NormalizationException("" + unsupported->type + "” expressions in preconditions cant be normalized currently");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// 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>())));
const auto handleNested =
[&](auto &nested) -> normalizedAST::AtomicFormula
{
return normalizeNested(nested, derivedPredicates);
};
const auto handleUnsupported =
[&](ast::UnsupportedPointer &unsupported) -> normalizedAST::AtomicFormula
{
throw NormalizationException("" + unsupported->type + "” expressions in preconditions cant be normalized currently");
};
auto normalizedArgument = not_->argument.match(handleNested, handleUnsupported);
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)
{
/*
reduce
AtomicFormula,
AndPointer<Precondition>,
NotPointer<Precondition>,
UnsupportedPointer>;
ExistsPointer<Precondition>,
ForAllPointer<Precondition>,
ImplyPointer<Precondition>,
OrPointer<Precondition>,
to
Literal,
AndPointer<Literal>>;
*/
const auto handleAtomicFormula =
[&](ast::AtomicFormula &atomicFormula) -> normalizedAST::Precondition
{
return normalize(std::move(atomicFormula));
};
const auto handleNot =
[&](ast::NotPointer<ast::Precondition> &not_) -> normalizedAST::Precondition
{
return normalize(std::move(not_), derivedPredicates);
};
const auto handleAnd =
[&](ast::AndPointer<ast::Precondition> &and_) -> normalizedAST::Precondition
{
return normalize(std::move(and_), derivedPredicates);
};
const auto handleNested =
[&](auto &nested) -> normalizedAST::Precondition
{
return normalizeNested(nested, derivedPredicates);
};
const auto handleUnsupported =
[&](ast::UnsupportedPointer &unsupported) -> normalizedAST::Precondition
{
throw NormalizationException("" + unsupported->type + "” expressions in preconditions cant be normalized currently");
};
return precondition.match(handleAtomicFormula, handleNot, handleAnd, handleUnsupported, handleNested);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@@ -0,0 +1,36 @@
#include <pddlparse/detail/normalization/Problem.h>
#include <pddlparse/AST.h>
#include <pddlparse/NormalizedAST.h>
#include <pddlparse/detail/normalization/InitialState.h>
#include <pddlparse/detail/normalization/Precondition.h>
namespace pddl
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Problem
//
////////////////////////////////////////////////////////////////////////////////////////////////////
normalizedAST::ProblemPointer normalize(ast::ProblemPointer &&problem, normalizedAST::Domain *domain)
{
auto normalizedProblem = std::make_unique<normalizedAST::Problem>(domain);
normalizedProblem->name = std::move(problem->name);
normalizedProblem->objects = std::move(problem->objects);
normalizedProblem->initialState = normalize(std::move(problem->initialState));
if (problem->goal)
normalizedProblem->goal = normalize(std::move(problem->goal.value()), normalizedProblem->derivedPredicates);
return normalizedProblem;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}