Renamed “pddlparse” library to simply “pddl”.
This commit is contained in:
28
lib/pddl/CMakeLists.txt
Normal file
28
lib/pddl/CMakeLists.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
project(pddl)
|
||||
|
||||
option(PDDL_BUILD_TESTS "Build unit tests" OFF)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wpedantic -Werror ${CMAKE_CXX_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g ${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
|
||||
if (CMAKE_GENERATOR STREQUAL "Ninja" AND
|
||||
((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) OR
|
||||
(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)))
|
||||
# Force colored warnings in Ninja's output, if the compiler has -fdiagnostics-color support.
|
||||
# Rationale in https://github.com/ninja-build/ninja/issues/814
|
||||
set(CMAKE_CXX_FLAGS "-fdiagnostics-color=always ${CMAKE_CXX_FLAGS}")
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
if(PDDL_BUILD_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif(PDDL_BUILD_TESTS)
|
504
lib/pddl/include/pddl/AST.h
Normal file
504
lib/pddl/include/pddl/AST.h
Normal file
@@ -0,0 +1,504 @@
|
||||
#ifndef __PDDL__AST_H
|
||||
#define __PDDL__AST_H
|
||||
|
||||
#include <limits>
|
||||
#include <experimental/optional>
|
||||
#include <set>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace ast
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AST
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Primitives
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Constant
|
||||
{
|
||||
explicit Constant(ConstantDeclaration *declaration)
|
||||
: declaration{declaration}
|
||||
{
|
||||
}
|
||||
|
||||
Constant(const Constant &other) = delete;
|
||||
Constant &operator=(const Constant &&other) = delete;
|
||||
Constant(Constant &&other) = default;
|
||||
Constant &operator=(Constant &&other) = default;
|
||||
|
||||
ConstantDeclaration *declaration;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct ConstantDeclaration
|
||||
{
|
||||
explicit ConstantDeclaration(std::string &&name, std::experimental::optional<Type> &&type = std::experimental::nullopt)
|
||||
: name{std::move(name)},
|
||||
type{std::move(type)}
|
||||
{
|
||||
}
|
||||
|
||||
ConstantDeclaration(const ConstantDeclaration &other) = delete;
|
||||
ConstantDeclaration &operator=(const ConstantDeclaration &&other) = delete;
|
||||
ConstantDeclaration(ConstantDeclaration &&other) = delete;
|
||||
ConstantDeclaration &operator=(ConstantDeclaration &&other) = delete;
|
||||
|
||||
std::string name;
|
||||
// TODO: check whether “either” types should actually be allowed at all
|
||||
std::experimental::optional<Type> type;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct PrimitiveType
|
||||
{
|
||||
explicit PrimitiveType(PrimitiveTypeDeclaration *declaration)
|
||||
: declaration{declaration}
|
||||
{
|
||||
}
|
||||
|
||||
PrimitiveType(const PrimitiveType &other) = delete;
|
||||
PrimitiveType &operator=(const PrimitiveType &&other) = delete;
|
||||
PrimitiveType(PrimitiveType &&other) = default;
|
||||
PrimitiveType &operator=(PrimitiveType &&other) = default;
|
||||
|
||||
PrimitiveTypeDeclaration *declaration;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct PrimitiveTypeDeclaration
|
||||
{
|
||||
explicit PrimitiveTypeDeclaration(std::string &&name)
|
||||
: name{std::move(name)}
|
||||
{
|
||||
}
|
||||
|
||||
PrimitiveTypeDeclaration(const PrimitiveTypeDeclaration &other) = delete;
|
||||
PrimitiveTypeDeclaration &operator=(const PrimitiveTypeDeclaration &&other) = delete;
|
||||
PrimitiveTypeDeclaration(PrimitiveTypeDeclaration &&other) = delete;
|
||||
PrimitiveTypeDeclaration &operator=(PrimitiveTypeDeclaration &&other) = delete;
|
||||
|
||||
std::string name;
|
||||
std::vector<PrimitiveTypePointer> parentTypes;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Variable
|
||||
{
|
||||
explicit Variable(VariableDeclaration *declaration)
|
||||
: declaration{declaration}
|
||||
{
|
||||
}
|
||||
|
||||
Variable(const Variable &other) = delete;
|
||||
Variable &operator=(const Variable &&other) = delete;
|
||||
Variable(Variable &&other) = default;
|
||||
Variable &operator=(Variable &&other) = default;
|
||||
|
||||
VariableDeclaration *declaration;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct VariableDeclaration
|
||||
{
|
||||
explicit VariableDeclaration(std::string &&name, std::experimental::optional<Type> type = std::experimental::nullopt)
|
||||
: name{std::move(name)},
|
||||
type{std::move(type)}
|
||||
{
|
||||
}
|
||||
|
||||
VariableDeclaration(const VariableDeclaration &other) = delete;
|
||||
VariableDeclaration &operator=(const VariableDeclaration &&other) = delete;
|
||||
VariableDeclaration(VariableDeclaration &&other) = delete;
|
||||
VariableDeclaration &operator=(VariableDeclaration &&other) = delete;
|
||||
|
||||
std::string name;
|
||||
std::experimental::optional<Type> type;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compounds
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Predicate
|
||||
{
|
||||
using Arguments = Terms;
|
||||
|
||||
explicit Predicate(Arguments &&arguments, PredicateDeclaration *declaration)
|
||||
: arguments{std::move(arguments)},
|
||||
declaration{declaration}
|
||||
{
|
||||
}
|
||||
|
||||
Predicate(const Predicate &other) = delete;
|
||||
Predicate &operator=(const Predicate &&other) = delete;
|
||||
Predicate(Predicate &&other) = default;
|
||||
Predicate &operator=(Predicate &&other) = default;
|
||||
|
||||
Arguments arguments;
|
||||
PredicateDeclaration *declaration;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct PredicateDeclaration
|
||||
{
|
||||
explicit PredicateDeclaration(std::string &&name, VariableDeclarations &¶meters)
|
||||
: name{std::move(name)},
|
||||
parameters{std::move(parameters)}
|
||||
{
|
||||
}
|
||||
|
||||
PredicateDeclaration(const PredicateDeclaration &other) = delete;
|
||||
PredicateDeclaration &operator=(const PredicateDeclaration &&other) = delete;
|
||||
PredicateDeclaration(PredicateDeclaration &&other) = default;
|
||||
PredicateDeclaration &operator=(PredicateDeclaration &&other) = default;
|
||||
|
||||
std::string name;
|
||||
VariableDeclarations parameters;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Expressions: Base Classes
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived, class ArgumentLeft, class ArgumentRight = ArgumentLeft>
|
||||
struct Binary
|
||||
{
|
||||
explicit Binary(ArgumentLeft &&argumentLeft, ArgumentRight &&argumentRight)
|
||||
: argumentLeft{std::move(argumentLeft)},
|
||||
argumentRight{std::move(argumentRight)}
|
||||
{
|
||||
}
|
||||
|
||||
Binary(const Binary &other) = delete;
|
||||
Binary &operator=(const Binary &&other) = delete;
|
||||
Binary(Binary &&other) = default;
|
||||
Binary &operator=(Binary &&other) = default;
|
||||
|
||||
ArgumentLeft argumentLeft;
|
||||
ArgumentRight argumentRight;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived, class Argument>
|
||||
struct NAry
|
||||
{
|
||||
using Arguments = std::vector<Argument>;
|
||||
|
||||
explicit NAry(Arguments &&arguments) noexcept
|
||||
: arguments{std::move(arguments)}
|
||||
{
|
||||
}
|
||||
|
||||
NAry(const NAry &other) = delete;
|
||||
NAry &operator=(const NAry &&other) = delete;
|
||||
NAry(NAry &&other) = default;
|
||||
NAry &operator=(NAry &&other) = default;
|
||||
|
||||
Arguments arguments;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived, class Argument>
|
||||
struct Quantified
|
||||
{
|
||||
using Parameters = VariableDeclarations;
|
||||
|
||||
explicit Quantified(Parameters &¶meters, Argument &&argument)
|
||||
: parameters{std::move(parameters)},
|
||||
argument{std::move(argument)}
|
||||
{
|
||||
}
|
||||
|
||||
Quantified(const Quantified &other) = delete;
|
||||
Quantified &operator=(const Quantified &&other) = delete;
|
||||
Quantified(Quantified &&other) = default;
|
||||
Quantified &operator=(Quantified &&other) = default;
|
||||
|
||||
Parameters parameters;
|
||||
Argument argument;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Expressions
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
struct And: public NAry<And<Argument>, Argument>
|
||||
{
|
||||
using typename NAry<And<Argument>, Argument>::Arguments;
|
||||
static constexpr const auto Identifier = "and";
|
||||
|
||||
explicit And(Arguments &&arguments) noexcept
|
||||
: NAry<And<Argument>, Argument>(std::move(arguments))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: make binary expression
|
||||
template<class Argument>
|
||||
struct At
|
||||
{
|
||||
static constexpr const auto TimePointStart = std::numeric_limits<std::size_t>::max();
|
||||
static constexpr const auto TimePointEnd = std::numeric_limits<std::size_t>::max() - 1;
|
||||
|
||||
At(std::size_t timePoint, Argument &&argument)
|
||||
: timePoint{timePoint},
|
||||
argument{std::move(argument)}
|
||||
{
|
||||
}
|
||||
|
||||
At(const At &other) = delete;
|
||||
At &operator=(const At &&other) = delete;
|
||||
At(At &&other) = default;
|
||||
At &operator=(At &&other) = default;
|
||||
|
||||
std::size_t timePoint;
|
||||
Argument argument;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
struct Either: public NAry<Either<Argument>, Argument>
|
||||
{
|
||||
using typename NAry<Either<Argument>, Argument>::Arguments;
|
||||
static constexpr const auto Identifier = "either";
|
||||
|
||||
explicit Either(Arguments &&arguments) noexcept
|
||||
: NAry<Either<Argument>, Argument>(std::move(arguments))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
struct Exists: public Quantified<Exists<Argument>, Argument>
|
||||
{
|
||||
static constexpr const auto Identifier = "exists";
|
||||
|
||||
explicit Exists(VariableDeclarations &¶meters, Argument &&argument)
|
||||
: Quantified<Exists<Argument>, Argument>(std::move(parameters), std::move(argument))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
struct ForAll: public Quantified<ForAll<Argument>, Argument>
|
||||
{
|
||||
static constexpr const auto Identifier = "forall";
|
||||
|
||||
explicit ForAll(VariableDeclarations &¶meters, Argument &&argument)
|
||||
: Quantified<ForAll<Argument>, Argument>(std::move(parameters), std::move(argument))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
struct Imply: public Binary<Imply<Argument>, Argument>
|
||||
{
|
||||
static constexpr const auto Identifier = "imply";
|
||||
|
||||
// TODO: make noexcept consistent
|
||||
explicit Imply(Argument &&argumentLeft, Argument &&argumentRight)
|
||||
: Binary<Imply<Argument>, Argument>(std::move(argumentLeft), std::move(argumentRight))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
struct Not
|
||||
{
|
||||
explicit Not(Argument &&argument)
|
||||
: argument{std::move(argument)}
|
||||
{
|
||||
}
|
||||
|
||||
Not(const Not &other) = delete;
|
||||
Not &operator=(const Not &&other) = delete;
|
||||
Not(Not &&other) = default;
|
||||
Not &operator=(Not &&other) = default;
|
||||
|
||||
Argument argument;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
struct Or: public NAry<Or<Argument>, Argument>
|
||||
{
|
||||
using typename NAry<Or<Argument>, Argument>::Arguments;
|
||||
static constexpr const auto Identifier = "or";
|
||||
|
||||
explicit Or(Arguments &&arguments) noexcept
|
||||
: NAry<Or<Argument>, Argument>(std::move(arguments))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class ArgumentLeft, class ArgumentRight>
|
||||
struct When: public Binary<When<ArgumentLeft, ArgumentRight>, ArgumentLeft, ArgumentRight>
|
||||
{
|
||||
static constexpr const auto Identifier = "when";
|
||||
|
||||
explicit When(ArgumentLeft &&argumentLeft, ArgumentRight &&argumentRight)
|
||||
: Binary<When<ArgumentLeft, ArgumentRight>, ArgumentLeft, ArgumentRight>(std::move(argumentLeft), std::move(argumentRight))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PDDL Structure
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Action
|
||||
{
|
||||
Action() = default;
|
||||
|
||||
Action(const Action &other) = delete;
|
||||
Action &operator=(const Action &&other) = delete;
|
||||
Action(Action &&other) = default;
|
||||
Action &operator=(Action &&other) = default;
|
||||
|
||||
std::string name;
|
||||
|
||||
VariableDeclarations parameters;
|
||||
std::experimental::optional<Precondition> precondition;
|
||||
std::experimental::optional<Effect> effect;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Domain
|
||||
{
|
||||
Domain() = default;
|
||||
|
||||
Domain(const Domain &other) = delete;
|
||||
Domain &operator=(const Domain &&other) = delete;
|
||||
Domain(Domain &&other) = delete;
|
||||
Domain &operator=(Domain &&other) = delete;
|
||||
|
||||
std::string name;
|
||||
Requirements requirements;
|
||||
PrimitiveTypeDeclarations types;
|
||||
ConstantDeclarations constants;
|
||||
PredicateDeclarations predicates;
|
||||
Actions actions;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct InitialState
|
||||
{
|
||||
InitialState() = default;
|
||||
|
||||
InitialState(const InitialState &other) = delete;
|
||||
InitialState &operator=(const InitialState &&other) = delete;
|
||||
InitialState(InitialState &&other) = default;
|
||||
InitialState &operator=(InitialState &&other) = default;
|
||||
|
||||
Facts facts;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Problem
|
||||
{
|
||||
Problem() = default;
|
||||
|
||||
Problem(Domain *domain)
|
||||
: domain{domain}
|
||||
{
|
||||
}
|
||||
|
||||
Problem(const Problem &other) = delete;
|
||||
Problem &operator=(const Problem &&other) = delete;
|
||||
Problem(Problem &&other) = default;
|
||||
Problem &operator=(Problem &&other) = default;
|
||||
|
||||
Domain *domain;
|
||||
std::string name;
|
||||
Requirements requirements;
|
||||
ConstantDeclarations objects;
|
||||
InitialState initialState;
|
||||
std::experimental::optional<Goal> goal;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: think about ignoring requirement statements entirely and computing them instead
|
||||
enum class Requirement
|
||||
{
|
||||
STRIPS,
|
||||
Typing,
|
||||
NegativePreconditions,
|
||||
DisjunctivePreconditions,
|
||||
Equality,
|
||||
ExistentialPreconditions,
|
||||
UniversalPreconditions,
|
||||
QuantifiedPreconditions,
|
||||
ConditionalEffects,
|
||||
Fluents,
|
||||
NumericFluents,
|
||||
ObjectFluents,
|
||||
ADL,
|
||||
DurativeActions,
|
||||
DurationInequalities,
|
||||
ContinuousEffects,
|
||||
DerivedPredicates,
|
||||
TimedInitialLiterals,
|
||||
Preferences,
|
||||
Constraints,
|
||||
ActionCosts,
|
||||
GoalUtilities
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Description
|
||||
{
|
||||
Description() = default;
|
||||
|
||||
Description(const Description &other) = delete;
|
||||
Description &operator=(const Description &&other) = delete;
|
||||
Description(Description &&other) = default;
|
||||
Description &operator=(Description &&other) = default;
|
||||
|
||||
DomainPointer domain;
|
||||
std::experimental::optional<ProblemPointer> problem;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
280
lib/pddl/include/pddl/ASTForward.h
Normal file
280
lib/pddl/include/pddl/ASTForward.h
Normal file
@@ -0,0 +1,280 @@
|
||||
#ifndef __PDDL__AST_FORWARD_H
|
||||
#define __PDDL__AST_FORWARD_H
|
||||
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
#include <experimental/optional>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include <pddl/Variant.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AST Forward Declarations
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace ast
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Primitives
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Constant;
|
||||
using ConstantPointer = std::unique_ptr<Constant>;
|
||||
struct ConstantDeclaration;
|
||||
using ConstantDeclarationPointer = std::unique_ptr<ConstantDeclaration>;
|
||||
using ConstantDeclarations = std::vector<ConstantDeclarationPointer>;
|
||||
struct PrimitiveType;
|
||||
using PrimitiveTypePointer = std::unique_ptr<PrimitiveType>;
|
||||
using PrimitiveTypes = std::vector<PrimitiveTypePointer>;
|
||||
struct PrimitiveTypeDeclaration;
|
||||
using PrimitiveTypeDeclarationPointer = std::unique_ptr<PrimitiveTypeDeclaration>;
|
||||
using PrimitiveTypeDeclarations = std::vector<PrimitiveTypeDeclarationPointer>;
|
||||
struct Variable;
|
||||
using VariablePointer = std::unique_ptr<Variable>;
|
||||
using Variables = std::vector<VariablePointer>;
|
||||
struct VariableDeclaration;
|
||||
using VariableDeclarationPointer = std::unique_ptr<VariableDeclaration>;
|
||||
using VariableDeclarations = std::vector<VariableDeclarationPointer>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compounds
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Predicate;
|
||||
using PredicatePointer = std::unique_ptr<Predicate>;
|
||||
using Predicates = std::vector<PredicatePointer>;
|
||||
struct PredicateDeclaration;
|
||||
using PredicateDeclarationPointer = std::unique_ptr<PredicateDeclaration>;
|
||||
using PredicateDeclarations = std::vector<PredicateDeclarationPointer>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Expressions
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
struct And;
|
||||
template<class Argument>
|
||||
using AndPointer = std::unique_ptr<And<Argument>>;
|
||||
template<class Argument>
|
||||
struct At;
|
||||
template<class Argument>
|
||||
using AtPointer = std::unique_ptr<At<Argument>>;
|
||||
template<class Argument>
|
||||
struct Either;
|
||||
template<class Argument>
|
||||
using EitherPointer = std::unique_ptr<Either<Argument>>;
|
||||
template<class Argument>
|
||||
struct Exists;
|
||||
template<class Argument>
|
||||
using ExistsPointer = std::unique_ptr<Exists<Argument>>;
|
||||
template<class Argument>
|
||||
struct ForAll;
|
||||
template<class Argument>
|
||||
using ForAllPointer = std::unique_ptr<ForAll<Argument>>;
|
||||
template<class Argument>
|
||||
struct Imply;
|
||||
template<class Argument>
|
||||
using ImplyPointer = std::unique_ptr<Imply<Argument>>;
|
||||
template<class Argument>
|
||||
struct Not;
|
||||
template<class Argument>
|
||||
using NotPointer = std::unique_ptr<Not<Argument>>;
|
||||
template<class Argument>
|
||||
struct Or;
|
||||
template<class Argument>
|
||||
using OrPointer = std::unique_ptr<Or<Argument>>;
|
||||
template<class ArgumentLeft, class ArgumentRight>
|
||||
struct When;
|
||||
template<class ArgumentLeft, class ArgumentRight>
|
||||
using WhenPointer = std::unique_ptr<When<ArgumentLeft, ArgumentRight>>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PDDL Structure
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Action;
|
||||
using ActionPointer = std::unique_ptr<Action>;
|
||||
using Actions = std::vector<ActionPointer>;
|
||||
struct Description;
|
||||
using DescriptionPointer = std::unique_ptr<Description>;
|
||||
struct Domain;
|
||||
using DomainPointer = std::unique_ptr<Domain>;
|
||||
struct InitialState;
|
||||
struct Problem;
|
||||
using ProblemPointer = std::unique_ptr<Problem>;
|
||||
enum class Requirement;
|
||||
using Requirements = std::vector<Requirement>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Variants
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace detail
|
||||
{
|
||||
using TermT = Variant<
|
||||
ConstantPointer,
|
||||
VariablePointer>;
|
||||
}
|
||||
|
||||
class Term : public detail::TermT
|
||||
{
|
||||
Term() = delete;
|
||||
|
||||
using detail::TermT::TermT;
|
||||
};
|
||||
|
||||
using Terms = std::vector<Term>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// TODO: add missing types
|
||||
using AtomicFormulaT = Variant<
|
||||
PredicatePointer>;
|
||||
}
|
||||
|
||||
class AtomicFormula : public detail::AtomicFormulaT
|
||||
{
|
||||
AtomicFormula() = delete;
|
||||
|
||||
using detail::AtomicFormulaT::AtomicFormulaT;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace detail
|
||||
{
|
||||
using LiteralT = Variant<
|
||||
AtomicFormula,
|
||||
NotPointer<AtomicFormula>>;
|
||||
}
|
||||
|
||||
class Literal : public detail::LiteralT
|
||||
{
|
||||
Literal() = delete;
|
||||
|
||||
using detail::LiteralT::LiteralT;
|
||||
};
|
||||
|
||||
using Literals = std::vector<Literal>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Precondition;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// TODO: add missing types
|
||||
using PreconditionT = Variant<
|
||||
AtomicFormula,
|
||||
AndPointer<Precondition>,
|
||||
ExistsPointer<Precondition>,
|
||||
ForAllPointer<Precondition>,
|
||||
ImplyPointer<Precondition>,
|
||||
NotPointer<Precondition>,
|
||||
OrPointer<Precondition>>;
|
||||
}
|
||||
|
||||
class Precondition : public detail::PreconditionT
|
||||
{
|
||||
Precondition() = delete;
|
||||
|
||||
using detail::PreconditionT::PreconditionT;
|
||||
};
|
||||
|
||||
using Preconditions = std::vector<Precondition>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ConditionalEffect;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// TODO: add missing types
|
||||
using ConditionalEffectT = Variant<
|
||||
Literal,
|
||||
AndPointer<Literal>>;
|
||||
}
|
||||
|
||||
class ConditionalEffect : public detail::ConditionalEffectT
|
||||
{
|
||||
ConditionalEffect() = delete;
|
||||
|
||||
using detail::ConditionalEffectT::ConditionalEffectT;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Effect;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// TODO: add missing types
|
||||
using EffectT = Variant<
|
||||
Literal,
|
||||
AndPointer<Effect>,
|
||||
ForAllPointer<Effect>,
|
||||
WhenPointer<Precondition, ConditionalEffect>>;
|
||||
}
|
||||
|
||||
class Effect : public detail::EffectT
|
||||
{
|
||||
Effect() = delete;
|
||||
|
||||
using detail::EffectT::EffectT;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace detail
|
||||
{
|
||||
using TypeT = Variant<
|
||||
EitherPointer<PrimitiveTypePointer>,
|
||||
PrimitiveTypePointer>;
|
||||
}
|
||||
|
||||
class Type : public detail::TypeT
|
||||
{
|
||||
Type() = delete;
|
||||
|
||||
using detail::TypeT::TypeT;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Fact;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
using FactT = Variant<
|
||||
AtPointer<Literal>,
|
||||
Literal>;
|
||||
}
|
||||
|
||||
class Fact : public detail::FactT
|
||||
{
|
||||
Fact() = delete;
|
||||
|
||||
using detail::FactT::FactT;
|
||||
};
|
||||
|
||||
using Facts = std::vector<Fact>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using Goal = Precondition;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
608
lib/pddl/include/pddl/ASTOutput.h
Normal file
608
lib/pddl/include/pddl/ASTOutput.h
Normal file
@@ -0,0 +1,608 @@
|
||||
#ifndef __PDDL__AST_OUTPUT_H
|
||||
#define __PDDL__AST_OUTPUT_H
|
||||
|
||||
#include <colorlog/ColorStream.h>
|
||||
#include <colorlog/Formatting.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/detail/OutputUtils.h>
|
||||
#include <pddl/detail/parsing/Requirement.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace ast
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Output
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Forward declarations
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Constant &constant, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const ConstantDeclaration &constantDeclaration, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const PrimitiveType &primitiveType, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const PrimitiveTypeDeclaration &primitiveTypeDeclaration, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Variable &variable, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const VariableDeclaration &variableDeclaration, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Predicate &predicate, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const PredicateDeclaration &predicateDeclaration, pddl::detail::PrintContext &printContext);
|
||||
|
||||
template<class Derived, class ArgumentLeft, class ArgumentRight = ArgumentLeft>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Binary<Derived, ArgumentLeft, ArgumentRight> &binary, pddl::detail::PrintContext &printContext);
|
||||
template<class Derived, class Argument>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const NAry<Derived, Argument> &nAry, pddl::detail::PrintContext &printContext);
|
||||
template<class Derived, class Argument>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Quantified<Derived, Argument> &quantified, pddl::detail::PrintContext &printContext);
|
||||
|
||||
template<class Argument>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const At<Argument> &at, pddl::detail::PrintContext &printContext);
|
||||
template<class Argument>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Not<Argument> ¬_, pddl::detail::PrintContext &printContext);
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Action &action, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Domain &domain, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const InitialState &initialState, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Problem &problem, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Requirement &requirement, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Description &description, pddl::detail::PrintContext &printContext);
|
||||
|
||||
template<class ValueType>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const std::unique_ptr<ValueType> &variant, pddl::detail::PrintContext &printContext);
|
||||
template<class ValueType>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const std::vector<ValueType> &variant, pddl::detail::PrintContext &printContext);
|
||||
template<class Variant>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Variant &variant, pddl::detail::PrintContext &printContext);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Primitives
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Constant &constant, pddl::detail::PrintContext &)
|
||||
{
|
||||
return stream << pddl::detail::Constant(constant.declaration->name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const ConstantDeclaration &constantDeclaration, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
stream << pddl::detail::Constant(constantDeclaration.name);
|
||||
|
||||
if (constantDeclaration.type)
|
||||
{
|
||||
stream << " - ";
|
||||
print(stream, constantDeclaration.type.value(), printContext);
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const PrimitiveType &primitiveType, pddl::detail::PrintContext &)
|
||||
{
|
||||
return stream << pddl::detail::Type(primitiveType.declaration->name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const PrimitiveTypeDeclaration &primitiveTypeDeclaration, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
if (primitiveTypeDeclaration.parentTypes.empty())
|
||||
return (stream << pddl::detail::Type(primitiveTypeDeclaration.name));
|
||||
|
||||
if (!primitiveTypeDeclaration.parentTypes.empty())
|
||||
for (const auto &parentType : primitiveTypeDeclaration.parentTypes)
|
||||
{
|
||||
if (&parentType != &primitiveTypeDeclaration.parentTypes.front())
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
|
||||
stream << pddl::detail::Type(primitiveTypeDeclaration.name) << " - " << pddl::detail::Type(parentType->declaration->name);
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Variable &variable, pddl::detail::PrintContext &)
|
||||
{
|
||||
const auto variableName = "?" + variable.declaration->name;
|
||||
|
||||
return (stream << colorlog::Variable(variableName.c_str()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const VariableDeclaration &variableDeclaration, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
const auto variableName = "?" + variableDeclaration.name;
|
||||
|
||||
stream << colorlog::Variable(variableName.c_str());
|
||||
|
||||
if (variableDeclaration.type)
|
||||
{
|
||||
stream << " - ";
|
||||
print(stream, *variableDeclaration.type, printContext);
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compounds
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Predicate &predicate, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
stream << "(" << pddl::detail::Identifier(predicate.declaration->name);
|
||||
|
||||
for (const auto &argument : predicate.arguments)
|
||||
{
|
||||
stream << " ";
|
||||
print(stream, argument, printContext);
|
||||
}
|
||||
|
||||
return (stream << ")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const PredicateDeclaration &predicateDeclaration, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
stream << "(" << pddl::detail::Identifier(predicateDeclaration.name);
|
||||
|
||||
for (const auto ¶meter : predicateDeclaration.parameters)
|
||||
{
|
||||
stream << " ";
|
||||
print(stream, *parameter, printContext);
|
||||
}
|
||||
|
||||
return (stream << ")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Expressions: Base Classes
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived, class ArgumentLeft, class ArgumentRight>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Binary<Derived, ArgumentLeft, ArgumentRight> &binary, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
stream << "(" << colorlog::Keyword(Derived::Identifier);
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, binary.argumentLeft, printContext);
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, binary.argumentRight, printContext);
|
||||
|
||||
printContext.indentationLevel--;
|
||||
|
||||
return (stream << ")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived, class Argument>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const NAry<Derived, Argument> &nAry, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
stream << "(" << colorlog::Keyword(Derived::Identifier);
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
for (const auto &argument : nAry.arguments)
|
||||
{
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, argument, printContext);
|
||||
}
|
||||
|
||||
printContext.indentationLevel--;
|
||||
|
||||
return (stream << ")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived, class Argument>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Quantified<Derived, Argument> &quantified, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
stream << "(" << colorlog::Keyword(Derived::Identifier);
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << "(";
|
||||
print(stream, quantified.parameters, printContext);
|
||||
stream << ")";
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, quantified.argument, printContext);
|
||||
|
||||
printContext.indentationLevel--;
|
||||
|
||||
return (stream << ")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Expressions
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const And<Argument> &and_, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
return print(stream, static_cast<const NAry<And<Argument>, Argument> &>(and_), printContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const At<Argument> &at, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
stream << "(" << colorlog::Keyword("at");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << colorlog::Number<decltype(at.timePoint)>(at.timePoint);
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, at.argument, printContext);
|
||||
|
||||
printContext.indentationLevel--;
|
||||
|
||||
return (stream << ")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Either<Argument> &either, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
return print(stream, static_cast<const NAry<Either<Argument>, Argument> &>(either), printContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Exists<Argument> &exists, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
return print(stream, static_cast<const Quantified<Exists<Argument>, Argument> &>(exists), printContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const ForAll<Argument> &forAll, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
return print(stream, static_cast<const Quantified<ForAll<Argument>, Argument> &>(forAll), printContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Imply<Argument> &imply, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
return print(stream, static_cast<const Binary<Imply<Argument>, Argument> &>(imply), printContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Not<Argument> ¬_, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
stream << "(" << colorlog::Keyword("not") << " ";
|
||||
print(stream, not_.argument, printContext);
|
||||
return (stream << ")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Or<Argument> &or_, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
return print(stream, static_cast<const NAry<Or<Argument>, Argument> &>(or_), printContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class ArgumentLeft, class ArgumentRight>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const When<ArgumentLeft, ArgumentRight> &when, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
return print(stream, static_cast<const Binary<When<ArgumentLeft, ArgumentRight>, ArgumentLeft, ArgumentRight> &>(when), printContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PDDL Structure
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Action &action, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
stream << "(" << colorlog::Keyword(":action") << " " << pddl::detail::Identifier(action.name);
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
if (!action.parameters.empty())
|
||||
{
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << colorlog::Keyword(":parameters");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << "(";
|
||||
print(stream, action.parameters, printContext);
|
||||
stream << ")";
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
if (action.precondition)
|
||||
{
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << colorlog::Keyword(":precondition");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, action.precondition.value(), printContext);
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
if (action.effect)
|
||||
{
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << colorlog::Keyword(":effect");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, action.effect.value(), printContext);
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
printContext.indentationLevel--;
|
||||
|
||||
return (stream << ")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Domain &domain, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
stream << "(" << colorlog::Keyword("define") << " (" << colorlog::Keyword("domain") << " " << pddl::detail::Identifier(domain.name) << ")";
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
if (!domain.requirements.empty())
|
||||
{
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << "(" << colorlog::Keyword(":requirements");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, domain.requirements, printContext);
|
||||
stream << ")";
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
if (!domain.types.empty())
|
||||
{
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << "(" << colorlog::Keyword(":types");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, domain.types, printContext);
|
||||
stream << ")";
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
if (!domain.constants.empty())
|
||||
{
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << "(" << colorlog::Keyword(":constants");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, domain.constants, printContext);
|
||||
stream << ")";
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
if (!domain.predicates.empty())
|
||||
{
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << "(" << colorlog::Keyword(":predicates");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, domain.predicates, printContext);
|
||||
stream << ")";
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
if (!domain.actions.empty())
|
||||
{
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, domain.actions, printContext);
|
||||
}
|
||||
|
||||
printContext.indentationLevel--;
|
||||
|
||||
return (stream << ")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const InitialState &initialState, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
assert(!initialState.facts.empty());
|
||||
|
||||
stream << "(" << colorlog::Keyword(":init");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, initialState.facts, printContext);
|
||||
|
||||
printContext.indentationLevel--;
|
||||
|
||||
return (stream << ")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Problem &problem, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
stream << "(" << colorlog::Keyword("define") << " (" << colorlog::Keyword("problem") << " " << pddl::detail::Identifier(problem.name) << ")";
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << "(" << colorlog::Keyword(":domain") << " " << pddl::detail::Identifier(problem.domain->name) << ")";
|
||||
|
||||
if (!problem.requirements.empty())
|
||||
{
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << "(" << colorlog::Keyword(":requirements");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, problem.requirements, printContext);
|
||||
stream << ")";
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
if (!problem.objects.empty())
|
||||
{
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << "(" << colorlog::Keyword(":objects");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, problem.objects, printContext);
|
||||
stream << ")";
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
if (!problem.initialState.facts.empty())
|
||||
{
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, problem.initialState, printContext);
|
||||
}
|
||||
|
||||
if (problem.goal)
|
||||
{
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << "(" << colorlog::Keyword(":goal");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, problem.goal.value(), printContext);
|
||||
stream << ")";
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
printContext.indentationLevel--;
|
||||
|
||||
return (stream << ")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Requirement &requirement, pddl::detail::PrintContext &)
|
||||
{
|
||||
auto requirementName = std::string(":") + pddl::detail::toString(requirement);
|
||||
|
||||
return (stream << pddl::detail::Identifier(requirementName.c_str()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Description &description, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
print(stream, *description.domain, printContext);
|
||||
stream << std::endl;
|
||||
|
||||
if (description.problem)
|
||||
{
|
||||
stream << std::endl;
|
||||
print(stream, *description.problem.value(), printContext);
|
||||
stream << std::endl;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const Description &description)
|
||||
{
|
||||
pddl::detail::PrintContext printContext;
|
||||
|
||||
return print(stream, description, printContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Variants
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class ValueType>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const std::unique_ptr<ValueType> &uniquePointer, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
assert(uniquePointer);
|
||||
return print(stream, *uniquePointer, printContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class ValueType>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const std::vector<ValueType> &vector, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
for (const auto &element : vector)
|
||||
{
|
||||
if (&element != &vector.front())
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
|
||||
print(stream, element, printContext);
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Variant>
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Variant &variant, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
variant.match([&](const auto &x){return print(stream, x, printContext);});
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
53
lib/pddl/include/pddl/Context.h
Normal file
53
lib/pddl/include/pddl/Context.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef __PDDL__CONTEXT_H
|
||||
#define __PDDL__CONTEXT_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <pddl/Mode.h>
|
||||
#include <pddl/Tokenizer.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Context
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Context
|
||||
{
|
||||
constexpr static const char *auxiliaryPrefix()
|
||||
{
|
||||
return "__plasp_";
|
||||
}
|
||||
|
||||
// TODO: replace std::string with char *
|
||||
using WarningCallback = std::function<void (tokenize::Location &&, const std::string &)>;
|
||||
|
||||
Context() = default;
|
||||
~Context() = default;
|
||||
|
||||
explicit Context(Tokenizer &&tokenizer, WarningCallback warningCallback, Mode mode = Mode::Strict)
|
||||
: tokenizer{std::move(tokenizer)},
|
||||
warningCallback{warningCallback},
|
||||
mode{mode}
|
||||
{
|
||||
}
|
||||
|
||||
Context(const Context &other) = delete;
|
||||
Context &operator=(const Context &other) = delete;
|
||||
Context(Context &&other) = default;
|
||||
Context &operator=(Context &&other) = default;
|
||||
|
||||
Tokenizer tokenizer;
|
||||
WarningCallback warningCallback;
|
||||
|
||||
Mode mode;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
#endif
|
95
lib/pddl/include/pddl/Exception.h
Normal file
95
lib/pddl/include/pddl/Exception.h
Normal file
@@ -0,0 +1,95 @@
|
||||
#ifndef __PDDL__EXCEPTION_H
|
||||
#define __PDDL__EXCEPTION_H
|
||||
|
||||
#include <exception>
|
||||
#include <experimental/optional>
|
||||
#include <string>
|
||||
|
||||
#include <tokenize/Location.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Exception
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Exception: public std::exception
|
||||
{
|
||||
public:
|
||||
Exception()
|
||||
: Exception("unspecified parser error")
|
||||
{
|
||||
}
|
||||
|
||||
Exception(const char *message)
|
||||
: Exception(static_cast<std::string>(message))
|
||||
{
|
||||
}
|
||||
|
||||
Exception(const std::string &message)
|
||||
: m_message{message}
|
||||
{
|
||||
}
|
||||
|
||||
Exception(tokenize::Location &&location)
|
||||
: Exception(std::forward<tokenize::Location>(location), "unspecified parser error")
|
||||
{
|
||||
}
|
||||
|
||||
Exception(tokenize::Location &&location, const char *message)
|
||||
: Exception(std::forward<tokenize::Location>(location), static_cast<std::string>(message))
|
||||
{
|
||||
}
|
||||
|
||||
Exception(tokenize::Location &&location, const std::string &message)
|
||||
: m_location{std::move(location)},
|
||||
m_message{message}
|
||||
{
|
||||
}
|
||||
|
||||
~Exception() noexcept = default;
|
||||
|
||||
const char *what() const noexcept
|
||||
{
|
||||
return m_message.c_str();
|
||||
}
|
||||
|
||||
const std::experimental::optional<tokenize::Location> &location() const
|
||||
{
|
||||
return m_location;
|
||||
}
|
||||
|
||||
const std::string &message() const
|
||||
{
|
||||
return m_message;
|
||||
}
|
||||
|
||||
private:
|
||||
std::experimental::optional<tokenize::Location> m_location;
|
||||
std::string m_message;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ParserException : public Exception
|
||||
{
|
||||
public:
|
||||
using Exception::Exception;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class NormalizationException : public Exception
|
||||
{
|
||||
public:
|
||||
using Exception::Exception;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
#endif
|
27
lib/pddl/include/pddl/Mode.h
Normal file
27
lib/pddl/include/pddl/Mode.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef __PDDL__MODE_H
|
||||
#define __PDDL__MODE_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <pddl/Tokenizer.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Mode
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum class Mode
|
||||
{
|
||||
Strict,
|
||||
Compatibility
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
#endif
|
24
lib/pddl/include/pddl/Normalize.h
Normal file
24
lib/pddl/include/pddl/Normalize.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef __PDDL__NORMALIZE_H
|
||||
#define __PDDL__NORMALIZE_H
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/NormalizedAST.h>
|
||||
#include <pddl/detail/normalization/Description.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Normalize
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using detail::normalize;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
#endif
|
159
lib/pddl/include/pddl/NormalizedAST.h
Normal file
159
lib/pddl/include/pddl/NormalizedAST.h
Normal file
@@ -0,0 +1,159 @@
|
||||
#ifndef __PDDL__NORMALIZED_AST_H
|
||||
#define __PDDL__NORMALIZED_AST_H
|
||||
|
||||
#include <limits>
|
||||
#include <experimental/optional>
|
||||
#include <set>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include <pddl/NormalizedASTForward.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace normalizedAST
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Normalized AST
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PDDL Structure
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Action
|
||||
{
|
||||
Action() = default;
|
||||
|
||||
Action(const Action &other) = delete;
|
||||
Action &operator=(const Action &&other) = delete;
|
||||
Action(Action &&other) = default;
|
||||
Action &operator=(Action &&other) = default;
|
||||
|
||||
std::string name;
|
||||
|
||||
VariableDeclarations parameters;
|
||||
std::experimental::optional<Precondition> precondition;
|
||||
std::experimental::optional<Effect> effect;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Domain
|
||||
{
|
||||
Domain() = default;
|
||||
|
||||
Domain(const Domain &other) = delete;
|
||||
Domain &operator=(const Domain &&other) = delete;
|
||||
Domain(Domain &&other) = delete;
|
||||
Domain &operator=(Domain &&other) = delete;
|
||||
|
||||
std::string name;
|
||||
PrimitiveTypeDeclarations types;
|
||||
ConstantDeclarations constants;
|
||||
PredicateDeclarations predicates;
|
||||
DerivedPredicateDeclarations derivedPredicates;
|
||||
Actions actions;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct DerivedPredicate
|
||||
{
|
||||
using Arguments = Terms;
|
||||
|
||||
explicit DerivedPredicate(Arguments &&arguments, DerivedPredicateDeclaration *declaration)
|
||||
: arguments{std::move(arguments)},
|
||||
declaration{declaration}
|
||||
{
|
||||
}
|
||||
|
||||
DerivedPredicate(const DerivedPredicate &other) = delete;
|
||||
DerivedPredicate &operator=(const DerivedPredicate &&other) = delete;
|
||||
DerivedPredicate(DerivedPredicate &&other) = default;
|
||||
DerivedPredicate &operator=(DerivedPredicate &&other) = default;
|
||||
|
||||
Arguments arguments;
|
||||
DerivedPredicateDeclaration *declaration;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct DerivedPredicateDeclaration
|
||||
{
|
||||
explicit DerivedPredicateDeclaration() = default;
|
||||
|
||||
DerivedPredicateDeclaration(const DerivedPredicateDeclaration &other) = delete;
|
||||
DerivedPredicateDeclaration &operator=(const DerivedPredicateDeclaration &&other) = delete;
|
||||
DerivedPredicateDeclaration(DerivedPredicateDeclaration &&other) = default;
|
||||
DerivedPredicateDeclaration &operator=(DerivedPredicateDeclaration &&other) = default;
|
||||
|
||||
std::string name;
|
||||
|
||||
std::vector<VariableDeclaration *> parameters;
|
||||
VariableDeclarations existentialParameters;
|
||||
std::experimental::optional<DerivedPredicatePrecondition> precondition;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct InitialState
|
||||
{
|
||||
InitialState() = default;
|
||||
|
||||
InitialState(const InitialState &other) = delete;
|
||||
InitialState &operator=(const InitialState &&other) = delete;
|
||||
InitialState(InitialState &&other) = default;
|
||||
InitialState &operator=(InitialState &&other) = default;
|
||||
|
||||
Facts facts;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Problem
|
||||
{
|
||||
Problem() = default;
|
||||
|
||||
Problem(Domain *domain)
|
||||
: domain{domain}
|
||||
{
|
||||
}
|
||||
|
||||
Problem(const Problem &other) = delete;
|
||||
Problem &operator=(const Problem &&other) = delete;
|
||||
Problem(Problem &&other) = default;
|
||||
Problem &operator=(Problem &&other) = default;
|
||||
|
||||
Domain *domain;
|
||||
std::string name;
|
||||
DerivedPredicateDeclarations derivedPredicates;
|
||||
ConstantDeclarations objects;
|
||||
InitialState initialState;
|
||||
std::experimental::optional<Goal> goal;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Description
|
||||
{
|
||||
Description() = default;
|
||||
|
||||
Description(const Description &other) = delete;
|
||||
Description &operator=(const Description &&other) = delete;
|
||||
Description(Description &&other) = default;
|
||||
Description &operator=(Description &&other) = default;
|
||||
|
||||
DomainPointer domain;
|
||||
std::experimental::optional<ProblemPointer> problem;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
230
lib/pddl/include/pddl/NormalizedASTForward.h
Normal file
230
lib/pddl/include/pddl/NormalizedASTForward.h
Normal file
@@ -0,0 +1,230 @@
|
||||
#ifndef __PDDL__NORMALIZED_AST_FORWARD_H
|
||||
#define __PDDL__NORMALIZED_AST_FORWARD_H
|
||||
|
||||
#include <pddl/AST.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Normalized AST Forward Declarations
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace normalizedAST
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Primitives
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using ast::Constant;
|
||||
using ast::ConstantPointer;
|
||||
using ast::ConstantDeclaration;
|
||||
using ast::ConstantDeclarationPointer;
|
||||
using ast::ConstantDeclarations;
|
||||
using ast::PrimitiveTypePointer;
|
||||
using ast::PrimitiveType;
|
||||
using ast::PrimitiveTypePointer;
|
||||
using ast::PrimitiveTypes;
|
||||
using ast::PrimitiveTypeDeclaration;
|
||||
using ast::PrimitiveTypeDeclarationPointer;
|
||||
using ast::PrimitiveTypeDeclarations;
|
||||
using ast::Variable;
|
||||
using ast::VariablePointer;
|
||||
using ast::Variables;
|
||||
using ast::VariableDeclaration;
|
||||
using ast::VariableDeclarationPointer;
|
||||
using ast::VariableDeclarations;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compounds
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct DerivedPredicate;
|
||||
using DerivedPredicatePointer = std::unique_ptr<DerivedPredicate>;
|
||||
using DerivedPredicates = std::vector<DerivedPredicatePointer>;
|
||||
struct DerivedPredicateDeclaration;
|
||||
using DerivedPredicateDeclarationPointer = std::unique_ptr<DerivedPredicateDeclaration>;
|
||||
using DerivedPredicateDeclarations = std::vector<DerivedPredicateDeclarationPointer>;
|
||||
using ast::Predicate;
|
||||
using ast::PredicatePointer;
|
||||
using ast::Predicates;
|
||||
using ast::PredicateDeclaration;
|
||||
using ast::PredicateDeclarationPointer;
|
||||
using ast::PredicateDeclarations;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Expressions
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using ast::And;
|
||||
using ast::AndPointer;
|
||||
using ast::At;
|
||||
using ast::AtPointer;
|
||||
using ast::Either;
|
||||
using ast::EitherPointer;
|
||||
using ast::Exists;
|
||||
using ast::ExistsPointer;
|
||||
using ast::ForAll;
|
||||
using ast::ForAllPointer;
|
||||
using ast::Not;
|
||||
using ast::NotPointer;
|
||||
using ast::Or;
|
||||
using ast::OrPointer;
|
||||
using ast::When;
|
||||
using ast::WhenPointer;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PDDL Structure
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Action;
|
||||
using ActionPointer = std::unique_ptr<Action>;
|
||||
using Actions = std::vector<ActionPointer>;
|
||||
struct Description;
|
||||
using DescriptionPointer = std::unique_ptr<Description>;
|
||||
struct Domain;
|
||||
using DomainPointer = std::unique_ptr<Domain>;
|
||||
struct InitialState;
|
||||
struct Problem;
|
||||
using ProblemPointer = std::unique_ptr<Problem>;
|
||||
enum class Requirement;
|
||||
using Requirements = std::vector<Requirement>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Variants
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using ast::Term;
|
||||
using ast::Terms;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace detail
|
||||
{
|
||||
using AtomicFormulaT = Variant<
|
||||
DerivedPredicatePointer,
|
||||
PredicatePointer>;
|
||||
}
|
||||
|
||||
class AtomicFormula : public detail::AtomicFormulaT
|
||||
{
|
||||
AtomicFormula() = delete;
|
||||
|
||||
using detail::AtomicFormulaT::AtomicFormulaT;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace detail
|
||||
{
|
||||
using LiteralT = Variant<
|
||||
AtomicFormula,
|
||||
NotPointer<AtomicFormula>>;
|
||||
}
|
||||
|
||||
class Literal : public detail::LiteralT
|
||||
{
|
||||
Literal() = delete;
|
||||
|
||||
using detail::LiteralT::LiteralT;
|
||||
};
|
||||
|
||||
using Literals = std::vector<Literal>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Precondition;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
using PreconditionT = Variant<
|
||||
Literal,
|
||||
AndPointer<Literal>>;
|
||||
}
|
||||
|
||||
class Precondition : public detail::PreconditionT
|
||||
{
|
||||
Precondition() = delete;
|
||||
|
||||
using detail::PreconditionT::PreconditionT;
|
||||
};
|
||||
|
||||
using Preconditions = std::vector<Precondition>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class DerivedPredicatePrecondition;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
using DerivedPredicatePreconditionT = Variant<
|
||||
Literal,
|
||||
AndPointer<Literal>,
|
||||
OrPointer<Literal>>;
|
||||
}
|
||||
|
||||
class DerivedPredicatePrecondition : public detail::DerivedPredicatePreconditionT
|
||||
{
|
||||
DerivedPredicatePrecondition() = delete;
|
||||
|
||||
using detail::DerivedPredicatePreconditionT::DerivedPredicatePreconditionT;
|
||||
};
|
||||
|
||||
using DerivedPredicatePreconditions = std::vector<DerivedPredicatePrecondition>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ConditionalEffect;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
using ConditionalEffectT = Variant<
|
||||
Literal,
|
||||
AndPointer<Literal>>;
|
||||
}
|
||||
|
||||
class ConditionalEffect : public detail::ConditionalEffectT
|
||||
{
|
||||
ConditionalEffect() = delete;
|
||||
|
||||
using detail::ConditionalEffectT::ConditionalEffectT;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Effect;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
using EffectT = Variant<
|
||||
Literal,
|
||||
AndPointer<Effect>,
|
||||
ForAllPointer<Effect>,
|
||||
WhenPointer<Precondition, ConditionalEffect>>;
|
||||
}
|
||||
|
||||
class Effect : public detail::EffectT
|
||||
{
|
||||
Effect() = delete;
|
||||
|
||||
using detail::EffectT::EffectT;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using Fact = Literal;
|
||||
using Facts = std::vector<Fact>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using Goal = Precondition;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
358
lib/pddl/include/pddl/NormalizedASTOutput.h
Normal file
358
lib/pddl/include/pddl/NormalizedASTOutput.h
Normal file
@@ -0,0 +1,358 @@
|
||||
#ifndef __PDDL__NORMALIZED_AST_OUTPUT_H
|
||||
#define __PDDL__NORMALIZED_AST_OUTPUT_H
|
||||
|
||||
#include <colorlog/ColorStream.h>
|
||||
#include <colorlog/Formatting.h>
|
||||
|
||||
#include <pddl/ASTOutput.h>
|
||||
#include <pddl/NormalizedAST.h>
|
||||
#include <pddl/detail/OutputUtils.h>
|
||||
#include <pddl/detail/parsing/Requirement.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace normalizedAST
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Output
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using ast::print;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Forward declarations
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const DerivedPredicate &derivedPredicate, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const DerivedPredicateDeclaration &derivedPredicateDeclaration, pddl::detail::PrintContext &printContext);
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Action &action, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Domain &domain, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const InitialState &initialState, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Problem &problem, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Requirement &requirement, pddl::detail::PrintContext &printContext);
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Description &description, pddl::detail::PrintContext &printContext);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compounds
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const DerivedPredicate &derivedPredicate, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
// TODO: implement correctly
|
||||
|
||||
stream << "(" << pddl::detail::Identifier(derivedPredicate.declaration->name);
|
||||
|
||||
for (const auto &argument : derivedPredicate.arguments)
|
||||
{
|
||||
stream << " ";
|
||||
print(stream, argument, printContext);
|
||||
}
|
||||
|
||||
return (stream << ")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const DerivedPredicateDeclaration &derivedPredicateDeclaration, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
stream << "(" << colorlog::Keyword(":derived-predicate") << " " << pddl::detail::Identifier(derivedPredicateDeclaration.name);
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
if (!derivedPredicateDeclaration.parameters.empty())
|
||||
{
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << colorlog::Keyword(":parameters");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << "(";
|
||||
|
||||
for (const auto ¶meter : derivedPredicateDeclaration.parameters)
|
||||
{
|
||||
if (¶meter != &derivedPredicateDeclaration.parameters.front())
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
|
||||
print(stream, *parameter, printContext);
|
||||
}
|
||||
|
||||
stream << ")";
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
if (!derivedPredicateDeclaration.existentialParameters.empty())
|
||||
{
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << colorlog::Keyword(":exists");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << "(";
|
||||
|
||||
for (const auto ¶meter : derivedPredicateDeclaration.existentialParameters)
|
||||
{
|
||||
if (parameter.get() != derivedPredicateDeclaration.existentialParameters.front().get())
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
|
||||
print(stream, *parameter, printContext);
|
||||
}
|
||||
|
||||
stream << ")";
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
if (derivedPredicateDeclaration.precondition)
|
||||
{
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
stream << colorlog::Keyword(":precondition");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
pddl::detail::printIndentedNewline(stream, printContext);
|
||||
print(stream, derivedPredicateDeclaration.precondition.value(), printContext);
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
printContext.indentationLevel--;
|
||||
|
||||
return (stream << ")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PDDL Structure
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Action &action, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
stream << "(" << colorlog::Keyword(":action") << " " << pddl::detail::Identifier(action.name);
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
if (!action.parameters.empty())
|
||||
{
|
||||
printIndentedNewline(stream, printContext);
|
||||
stream << colorlog::Keyword(":parameters");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
printIndentedNewline(stream, printContext);
|
||||
stream << "(";
|
||||
print(stream, action.parameters, printContext);
|
||||
stream << ")";
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
if (action.precondition)
|
||||
{
|
||||
printIndentedNewline(stream, printContext);
|
||||
stream << colorlog::Keyword(":precondition");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
printIndentedNewline(stream, printContext);
|
||||
print(stream, action.precondition.value(), printContext);
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
if (action.effect)
|
||||
{
|
||||
printIndentedNewline(stream, printContext);
|
||||
stream << colorlog::Keyword(":effect");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
printIndentedNewline(stream, printContext);
|
||||
print(stream, action.effect.value(), printContext);
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
printContext.indentationLevel--;
|
||||
|
||||
return (stream << ")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Domain &domain, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
stream << "(" << colorlog::Keyword("define") << " (" << colorlog::Keyword("domain") << " " << pddl::detail::Identifier(domain.name) << ")";
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
if (!domain.types.empty())
|
||||
{
|
||||
printIndentedNewline(stream, printContext);
|
||||
stream << "(" << colorlog::Keyword(":types");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
printIndentedNewline(stream, printContext);
|
||||
print(stream, domain.types, printContext);
|
||||
stream << ")";
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
if (!domain.constants.empty())
|
||||
{
|
||||
printIndentedNewline(stream, printContext);
|
||||
stream << "(" << colorlog::Keyword(":constants");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
printIndentedNewline(stream, printContext);
|
||||
print(stream, domain.constants, printContext);
|
||||
stream << ")";
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
if (!domain.predicates.empty())
|
||||
{
|
||||
printIndentedNewline(stream, printContext);
|
||||
stream << "(" << colorlog::Keyword(":predicates");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
printIndentedNewline(stream, printContext);
|
||||
print(stream, domain.predicates, printContext);
|
||||
stream << ")";
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
if (!domain.derivedPredicates.empty())
|
||||
{
|
||||
printIndentedNewline(stream, printContext);
|
||||
print(stream, domain.derivedPredicates, printContext);
|
||||
}
|
||||
|
||||
if (!domain.actions.empty())
|
||||
{
|
||||
printIndentedNewline(stream, printContext);
|
||||
print(stream, domain.actions, printContext);
|
||||
}
|
||||
|
||||
printContext.indentationLevel--;
|
||||
|
||||
return (stream << ")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const InitialState &initialState, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
assert(!initialState.facts.empty());
|
||||
|
||||
stream << "(" << colorlog::Keyword(":init");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
printIndentedNewline(stream, printContext);
|
||||
print(stream, initialState.facts, printContext);
|
||||
|
||||
printContext.indentationLevel--;
|
||||
|
||||
return (stream << ")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Problem &problem, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
stream << "(" << colorlog::Keyword("define") << " (" << colorlog::Keyword("problem") << " " << pddl::detail::Identifier(problem.name) << ")";
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
printIndentedNewline(stream, printContext);
|
||||
stream << "(" << colorlog::Keyword(":domain") << " " << pddl::detail::Identifier(problem.domain->name) << ")";
|
||||
|
||||
if (!problem.derivedPredicates.empty())
|
||||
{
|
||||
printIndentedNewline(stream, printContext);
|
||||
print(stream, problem.derivedPredicates, printContext);
|
||||
}
|
||||
|
||||
if (!problem.objects.empty())
|
||||
{
|
||||
printIndentedNewline(stream, printContext);
|
||||
stream << "(" << colorlog::Keyword(":objects");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
printIndentedNewline(stream, printContext);
|
||||
print(stream, problem.objects, printContext);
|
||||
stream << ")";
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
if (!problem.initialState.facts.empty())
|
||||
{
|
||||
printIndentedNewline(stream, printContext);
|
||||
print(stream, problem.initialState, printContext);
|
||||
}
|
||||
|
||||
if (problem.goal)
|
||||
{
|
||||
printIndentedNewline(stream, printContext);
|
||||
stream << "(" << colorlog::Keyword(":goal");
|
||||
|
||||
printContext.indentationLevel++;
|
||||
|
||||
printIndentedNewline(stream, printContext);
|
||||
print(stream, problem.goal.value(), printContext);
|
||||
stream << ")";
|
||||
|
||||
printContext.indentationLevel--;
|
||||
}
|
||||
|
||||
printContext.indentationLevel--;
|
||||
|
||||
return (stream << ")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &print(colorlog::ColorStream &stream, const Description &description, pddl::detail::PrintContext &printContext)
|
||||
{
|
||||
print(stream, *description.domain, printContext);
|
||||
stream << std::endl;
|
||||
|
||||
if (description.problem)
|
||||
{
|
||||
stream << std::endl;
|
||||
print(stream, *description.problem.value(), printContext);
|
||||
stream << std::endl;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const Description &description)
|
||||
{
|
||||
pddl::detail::PrintContext printContext;
|
||||
|
||||
return print(stream, description, printContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
24
lib/pddl/include/pddl/Parse.h
Normal file
24
lib/pddl/include/pddl/Parse.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef __PDDL__PARSE_H
|
||||
#define __PDDL__PARSE_H
|
||||
|
||||
#include <experimental/optional>
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Parse
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::Description parseDescription(Context &context);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
#endif
|
52
lib/pddl/include/pddl/Tokenizer.h
Normal file
52
lib/pddl/include/pddl/Tokenizer.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef __PDDL__TOKENIZER_H
|
||||
#define __PDDL__TOKENIZER_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <tokenize/Tokenizer.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Tokenizer
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct PDDLTokenizerPolicy
|
||||
{
|
||||
static char transformCharacter(char c) noexcept
|
||||
{
|
||||
return std::tolower(c);
|
||||
}
|
||||
|
||||
static bool isWhiteSpaceCharacter(char c)
|
||||
{
|
||||
return std::iswspace(c);
|
||||
}
|
||||
|
||||
static bool isBlankCharacter(char c)
|
||||
{
|
||||
return std::isblank(c);
|
||||
}
|
||||
|
||||
static bool isIdentifierCharacter(char c)
|
||||
{
|
||||
return c != '?'
|
||||
&& c != '('
|
||||
&& c != ')'
|
||||
&& c != ';'
|
||||
&& std::isgraph(c);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using Tokenizer = tokenize::Tokenizer<PDDLTokenizerPolicy>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
#endif
|
20
lib/pddl/include/pddl/Variant.h
Normal file
20
lib/pddl/include/pddl/Variant.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef __PDDL__VARIANT_H
|
||||
#define __PDDL__VARIANT_H
|
||||
|
||||
#include <mapbox/variant.hpp>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class... Types>
|
||||
using Variant = mapbox::util::variant<Types...>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif
|
48
lib/pddl/include/pddl/detail/ASTContext.h
Normal file
48
lib/pddl/include/pddl/detail/ASTContext.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef __PDDL__DETAIL__AST_CONTEXT_H
|
||||
#define __PDDL__DETAIL__AST_CONTEXT_H
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/detail/VariableStack.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ASTContext
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct ASTContext
|
||||
{
|
||||
ASTContext(ast::Description &description)
|
||||
: domain{description.domain.get()},
|
||||
problem{description.problem.value() ? std::experimental::optional<ast::Problem *>(description.problem.value().get()) : std::experimental::nullopt}
|
||||
{
|
||||
}
|
||||
|
||||
ASTContext(ast::Domain &domain)
|
||||
: domain{&domain}
|
||||
{
|
||||
}
|
||||
|
||||
ASTContext(ast::Problem &problem)
|
||||
: domain{problem.domain},
|
||||
problem{&problem}
|
||||
{
|
||||
}
|
||||
|
||||
ast::Domain *domain;
|
||||
std::experimental::optional<ast::Problem *> problem;
|
||||
|
||||
VariableStack variables;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
165
lib/pddl/include/pddl/detail/ASTCopy.h
Normal file
165
lib/pddl/include/pddl/detail/ASTCopy.h
Normal file
@@ -0,0 +1,165 @@
|
||||
#ifndef __PDDL__DETAIL__AST_COPY_H
|
||||
#define __PDDL__DETAIL__AST_COPY_H
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Variant.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace ast
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ASTCopy
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Primitives
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline Constant deepCopy(Constant &other);
|
||||
inline PrimitiveType deepCopy(PrimitiveType &other);
|
||||
inline Variable deepCopy(Variable &other);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Expressions: Base Classes
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived, class ArgumentLeft, class ArgumentRight = ArgumentLeft>
|
||||
inline Derived deepCopy(Binary<Derived, ArgumentLeft, ArgumentRight> &other);
|
||||
template<class Derived, class Argument>
|
||||
inline Derived deepCopy(NAry<Derived, Argument> &other);
|
||||
template<class Derived, class Argument>
|
||||
inline Derived deepCopy(Quantified<Derived, Argument> &other);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Expressions
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
inline At<Argument> deepCopy(At<Argument> &other);
|
||||
template<class Argument>
|
||||
inline Not<Argument> deepCopy(Not<Argument> &other);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Variants
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline ast::Type deepCopy(ast::Type &other);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Unique Pointers
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class T>
|
||||
std::unique_ptr<T> deepCopy(std::unique_ptr<T> &other);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Primitives
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Constant deepCopy(Constant &other)
|
||||
{
|
||||
return Constant(other.declaration);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PrimitiveType deepCopy(PrimitiveType &other)
|
||||
{
|
||||
return PrimitiveType(other.declaration);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Variable deepCopy(Variable &other)
|
||||
{
|
||||
return Variable(other.declaration);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Expressions: Base Classes
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived, class ArgumentLeft, class ArgumentRight>
|
||||
Derived deepCopy(Binary<Derived, ArgumentLeft, ArgumentRight> &other)
|
||||
{
|
||||
auto argumentLeft{deepCopy(other.argumentLeft)};
|
||||
auto argumentRight{deepCopy(other.argumentRight)};
|
||||
|
||||
return Binary<Derived, ArgumentLeft, ArgumentRight>(std::move(argumentLeft), std::move(argumentRight));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived, class Argument>
|
||||
Derived deepCopy(NAry<Derived, Argument> &other)
|
||||
{
|
||||
typename Derived::Arguments arguments;
|
||||
arguments.reserve(other.arguments.size());
|
||||
|
||||
for (auto &argument : other.arguments)
|
||||
arguments.emplace_back(deepCopy(argument));
|
||||
|
||||
return Derived(std::move(arguments));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived, class Argument>
|
||||
Derived deepCopy(Quantified<Derived, Argument> &other)
|
||||
{
|
||||
auto argument{deepCopy(other.argument)};
|
||||
|
||||
return Quantified<Derived, Argument>(std::move(argument));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Expressions
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
At<Argument> deepCopy(At<Argument> &other)
|
||||
{
|
||||
auto argument{deepCopy(other.argument)};
|
||||
|
||||
return At<Argument>(other.timePoint, std::move(argument));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
Not<Argument> deepCopy(Not<Argument> &other)
|
||||
{
|
||||
auto argument{deepCopy(other.argument)};
|
||||
|
||||
return Not<Argument>(std::move(argument));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Variants
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::Type deepCopy(ast::Type &other)
|
||||
{
|
||||
return other.match([](auto &x) -> ast::Type {return deepCopy(x);});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Unique Pointers
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class T>
|
||||
std::unique_ptr<T> deepCopy(std::unique_ptr<T> &other)
|
||||
{
|
||||
return std::make_unique<T>(deepCopy(*other));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
117
lib/pddl/include/pddl/detail/OutputUtils.h
Normal file
117
lib/pddl/include/pddl/detail/OutputUtils.h
Normal file
@@ -0,0 +1,117 @@
|
||||
#ifndef __PDDL__DETAIL__OUTPUT_UTILS_H
|
||||
#define __PDDL__DETAIL__OUTPUT_UTILS_H
|
||||
|
||||
#include <colorlog/Formatting.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OutputUtils
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct PrintContext
|
||||
{
|
||||
size_t indentationLevel{0};
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Identifier
|
||||
{
|
||||
Identifier(const char *content)
|
||||
: content{content}
|
||||
{
|
||||
}
|
||||
|
||||
Identifier(const std::string &content)
|
||||
: content{content.c_str()}
|
||||
{
|
||||
}
|
||||
|
||||
const char *content;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const Identifier &identifier)
|
||||
{
|
||||
return (stream
|
||||
<< colorlog::Format({colorlog::Color::Green, colorlog::FontWeight::Normal})
|
||||
<< identifier.content << colorlog::ResetFormat());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Type
|
||||
{
|
||||
Type(const char *name)
|
||||
: name{name}
|
||||
{
|
||||
}
|
||||
|
||||
Type(const std::string &name)
|
||||
: name{name.c_str()}
|
||||
{
|
||||
}
|
||||
|
||||
const char *name;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const Type &type)
|
||||
{
|
||||
return (stream
|
||||
<< colorlog::Format({colorlog::Color::Red, colorlog::FontWeight::Normal})
|
||||
<< type.name << colorlog::ResetFormat());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Constant
|
||||
{
|
||||
Constant(const char *name)
|
||||
: name{name}
|
||||
{
|
||||
}
|
||||
|
||||
Constant(const std::string &name)
|
||||
: name{name.c_str()}
|
||||
{
|
||||
}
|
||||
|
||||
const char *name;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &operator<<(colorlog::ColorStream &stream, const Constant &constant)
|
||||
{
|
||||
return (stream
|
||||
<< colorlog::Format({colorlog::Color::Yellow, colorlog::FontWeight::Normal})
|
||||
<< constant.name << colorlog::ResetFormat());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline colorlog::ColorStream &printIndentedNewline(colorlog::ColorStream &stream, detail::PrintContext &printContext)
|
||||
{
|
||||
stream << std::endl;
|
||||
|
||||
for (size_t i = 0; i < printContext.indentationLevel; i++)
|
||||
stream << "\t";
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
31
lib/pddl/include/pddl/detail/Requirements.h
Normal file
31
lib/pddl/include/pddl/detail/Requirements.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef __PDDL__DETAIL__REQUIREMENTS_H
|
||||
#define __PDDL__DETAIL__REQUIREMENTS_H
|
||||
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/detail/ASTContext.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Requirements
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool hasRequirement(const ast::Domain &domain, ast::Requirement requirement);
|
||||
bool hasRequirement(const ast::Problem &problem, ast::Requirement requirement);
|
||||
bool hasRequirement(const ASTContext &astContext, ast::Requirement requirement);
|
||||
|
||||
void checkRequirement(ast::Domain &domain, ast::Requirement requirement, Context &context);
|
||||
void checkRequirement(ast::Problem &problem, ast::Requirement requirement, Context &context);
|
||||
void checkRequirement(ASTContext &astContext, ast::Requirement requirement, Context &context);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
34
lib/pddl/include/pddl/detail/SignatureMatching.h
Normal file
34
lib/pddl/include/pddl/detail/SignatureMatching.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef __PDDL__DETAIL__SIGNATURE_MATCHING_H
|
||||
#define __PDDL__DETAIL__SIGNATURE_MATCHING_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SignatureMatching
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool matches(const ast::PrimitiveTypeDeclaration &lhs, const ast::PrimitiveTypeDeclaration &rhs);
|
||||
bool matches(const ast::Either<ast::PrimitiveTypePointer> &lhs, const ast::PrimitiveTypeDeclaration &rhs);
|
||||
bool matches(const ast::PrimitiveTypeDeclaration &lhs, const ast::Either<ast::PrimitiveTypePointer> &rhs);
|
||||
bool matches(const ast::Either<ast::PrimitiveTypePointer> &lhs, const ast::Either<ast::PrimitiveTypePointer> &rhs);
|
||||
bool matches(const ast::VariableDeclaration &lhs, const std::experimental::optional<ast::Type> &rhs);
|
||||
bool matches(const ast::ConstantDeclaration &lhs, const std::experimental::optional<ast::Type> &rhs);
|
||||
bool matches(const ast::Term &lhs, const std::experimental::optional<ast::Type> &rhs);
|
||||
|
||||
bool matches(const std::string &predicateName, const ast::Predicate::Arguments &predicateArguments, const ast::PredicateDeclaration &predicateDeclaration);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
38
lib/pddl/include/pddl/detail/VariableStack.h
Normal file
38
lib/pddl/include/pddl/detail/VariableStack.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef __PDDL__DETAIL__VARIABLE_STACK_H
|
||||
#define __PDDL__DETAIL__VARIABLE_STACK_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// VariableStack
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class VariableStack
|
||||
{
|
||||
public:
|
||||
using Layer = ast::VariableDeclarations *;
|
||||
|
||||
public:
|
||||
void push(Layer layer);
|
||||
void pop();
|
||||
|
||||
std::experimental::optional<ast::VariableDeclaration *> findVariableDeclaration(const std::string &variableName) const;
|
||||
bool contains(const ast::VariableDeclaration &variableDeclaration) const;
|
||||
|
||||
private:
|
||||
std::vector<Layer> m_layers;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
26
lib/pddl/include/pddl/detail/normalization/Action.h
Normal file
26
lib/pddl/include/pddl/detail/normalization/Action.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __PDDL__DETAIL__NORMALIZATION__ACTION_H
|
||||
#define __PDDL__DETAIL__NORMALIZATION__ACTION_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/NormalizedASTForward.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Action
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::ActionPointer normalize(ast::ActionPointer &&domain, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
26
lib/pddl/include/pddl/detail/normalization/AtomicFormula.h
Normal file
26
lib/pddl/include/pddl/detail/normalization/AtomicFormula.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __PDDL__DETAIL__NORMALIZATION__ATOMIC_FORMULA_H
|
||||
#define __PDDL__DETAIL__NORMALIZATION__ATOMIC_FORMULA_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/NormalizedASTForward.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AtomicFormula
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::AtomicFormula normalize(ast::AtomicFormula &&atomicFormula);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -0,0 +1,121 @@
|
||||
#ifndef __PDDL__DETAIL__NORMALIZATION__COLLECT_FREE_VARIABLES_H
|
||||
#define __PDDL__DETAIL__NORMALIZATION__COLLECT_FREE_VARIABLES_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/Exception.h>
|
||||
|
||||
#include <pddl/NormalizedASTForward.h>
|
||||
#include <pddl/detail/VariableStack.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Collect Free Variables
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Variant>
|
||||
void collectFreeVariables(const Variant &variant, std::vector<normalizedAST::VariableDeclaration *> &freeVariables, VariableStack &variableStack)
|
||||
{
|
||||
variant.match([&](const auto &x){collectFreeVariables(x, freeVariables, variableStack);});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void collectFreeVariables(const ast::ConstantPointer &, std::vector<normalizedAST::VariableDeclaration *> &, VariableStack &)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void collectFreeVariables(const ast::VariablePointer &variable, std::vector<normalizedAST::VariableDeclaration *> &freeVariables, VariableStack &variableStack)
|
||||
{
|
||||
if (variableStack.contains(*variable->declaration))
|
||||
return;
|
||||
|
||||
const auto matchingFreeVariable = std::find(freeVariables.cbegin(), freeVariables.cend(), variable->declaration);
|
||||
|
||||
if (matchingFreeVariable != freeVariables.cend())
|
||||
return;
|
||||
|
||||
freeVariables.emplace_back(variable->declaration);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void collectFreeVariables(const ast::PredicatePointer &predicate, std::vector<normalizedAST::VariableDeclaration *> &freeVariables, VariableStack &variableStack)
|
||||
{
|
||||
for (const auto &argument : predicate->arguments)
|
||||
collectFreeVariables(argument, freeVariables, variableStack);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
void collectFreeVariables(const ast::AndPointer<Argument> &and_, std::vector<normalizedAST::VariableDeclaration *> &freeVariables, VariableStack &variableStack)
|
||||
{
|
||||
for (const auto &argument : and_->arguments)
|
||||
collectFreeVariables(argument, freeVariables, variableStack);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
void collectFreeVariables(const ast::ExistsPointer<Argument> &exists, std::vector<normalizedAST::VariableDeclaration *> &freeVariables, VariableStack &variableStack)
|
||||
{
|
||||
variableStack.push(&exists->parameters);
|
||||
|
||||
collectFreeVariables(exists->argument, freeVariables, variableStack);
|
||||
|
||||
variableStack.pop();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
void collectFreeVariables(const ast::ForAllPointer<Argument> &forAll, std::vector<normalizedAST::VariableDeclaration *> &freeVariables, VariableStack &variableStack)
|
||||
{
|
||||
variableStack.push(&forAll->parameters);
|
||||
|
||||
collectFreeVariables(forAll->argument, freeVariables, variableStack);
|
||||
|
||||
variableStack.pop();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
void collectFreeVariables(const ast::ImplyPointer<Argument> &imply, std::vector<normalizedAST::VariableDeclaration *> &freeVariables, VariableStack &variableStack)
|
||||
{
|
||||
collectFreeVariables(imply->argumentLeft, freeVariables, variableStack);
|
||||
collectFreeVariables(imply->argumentRight, freeVariables, variableStack);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
void collectFreeVariables(const ast::NotPointer<Argument> ¬_, std::vector<normalizedAST::VariableDeclaration *> &freeVariables, VariableStack &variableStack)
|
||||
{
|
||||
collectFreeVariables(not_->argument, freeVariables, variableStack);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Argument>
|
||||
void collectFreeVariables(const ast::OrPointer<Argument> &or_, std::vector<normalizedAST::VariableDeclaration *> &freeVariables, VariableStack &variableStack)
|
||||
{
|
||||
for (const auto &argument : or_->arguments)
|
||||
collectFreeVariables(argument, freeVariables, variableStack);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -0,0 +1,26 @@
|
||||
#ifndef __PDDL__DETAIL__NORMALIZATION__CONDITIONAL_EFFECT_H
|
||||
#define __PDDL__DETAIL__NORMALIZATION__CONDITIONAL_EFFECT_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/NormalizedASTForward.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ConditionalEffect
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::ConditionalEffect normalize(ast::ConditionalEffect &&conditionalEffect);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
26
lib/pddl/include/pddl/detail/normalization/Description.h
Normal file
26
lib/pddl/include/pddl/detail/normalization/Description.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __PDDL__DETAIL__NORMALIZATION__DESCRIPTION_H
|
||||
#define __PDDL__DETAIL__NORMALIZATION__DESCRIPTION_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/NormalizedASTForward.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Description
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::Description normalize(ast::Description &&description);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
26
lib/pddl/include/pddl/detail/normalization/Domain.h
Normal file
26
lib/pddl/include/pddl/detail/normalization/Domain.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __PDDL__DETAIL__NORMALIZATION__DOMAIN_H
|
||||
#define __PDDL__DETAIL__NORMALIZATION__DOMAIN_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/NormalizedASTForward.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Domain
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::DomainPointer normalize(ast::DomainPointer &&domain);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
26
lib/pddl/include/pddl/detail/normalization/Effect.h
Normal file
26
lib/pddl/include/pddl/detail/normalization/Effect.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __PDDL__DETAIL__NORMALIZATION__EFFECT_H
|
||||
#define __PDDL__DETAIL__NORMALIZATION__EFFECT_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/NormalizedASTForward.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Effect
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::Effect normalize(ast::Effect &&effect, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
26
lib/pddl/include/pddl/detail/normalization/Fact.h
Normal file
26
lib/pddl/include/pddl/detail/normalization/Fact.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __PDDL__DETAIL__NORMALIZATION__FACT_H
|
||||
#define __PDDL__DETAIL__NORMALIZATION__FACT_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/NormalizedASTForward.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Fact
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::Fact normalize(ast::Fact &&fact);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
26
lib/pddl/include/pddl/detail/normalization/InitialState.h
Normal file
26
lib/pddl/include/pddl/detail/normalization/InitialState.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __PDDL__DETAIL__NORMALIZATION__INITIAL_STATE_H
|
||||
#define __PDDL__DETAIL__NORMALIZATION__INITIAL_STATE_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/NormalizedASTForward.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// InitialState
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::InitialState normalize(ast::InitialState &&initialState);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
26
lib/pddl/include/pddl/detail/normalization/Literal.h
Normal file
26
lib/pddl/include/pddl/detail/normalization/Literal.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __PDDL__DETAIL__NORMALIZATION__LITERAL_H
|
||||
#define __PDDL__DETAIL__NORMALIZATION__LITERAL_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/NormalizedASTForward.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Literal
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::Literal normalize(ast::Literal &&literal);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
26
lib/pddl/include/pddl/detail/normalization/Precondition.h
Normal file
26
lib/pddl/include/pddl/detail/normalization/Precondition.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __PDDL__DETAIL__NORMALIZATION__PRECONDITION_H
|
||||
#define __PDDL__DETAIL__NORMALIZATION__PRECONDITION_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/NormalizedASTForward.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Precondition
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::Precondition normalize(ast::Precondition &&precondition, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
26
lib/pddl/include/pddl/detail/normalization/Problem.h
Normal file
26
lib/pddl/include/pddl/detail/normalization/Problem.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __PDDL__DETAIL__NORMALIZATION__PROBLEM_H
|
||||
#define __PDDL__DETAIL__NORMALIZATION__PROBLEM_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/NormalizedASTForward.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Problem
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::ProblemPointer normalize(ast::ProblemPointer &&problem, normalizedAST::Domain *domain);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
26
lib/pddl/include/pddl/detail/normalization/Reduction.h
Normal file
26
lib/pddl/include/pddl/detail/normalization/Reduction.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __PDDL__DETAIL__NORMALIZATION__REDUCTION_H
|
||||
#define __PDDL__DETAIL__NORMALIZATION__REDUCTION_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/NormalizedASTForward.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Reduction
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void reduce(ast::Precondition &precondition);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
50
lib/pddl/include/pddl/detail/parsing/Action.h
Normal file
50
lib/pddl/include/pddl/detail/parsing/Action.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__ACTION_H
|
||||
#define __PDDL__DETAIL__PARSING__ACTION_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Action
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ActionParser
|
||||
{
|
||||
public:
|
||||
ActionParser(Context &context, ast::Domain &domain);
|
||||
ast::ActionPointer parse();
|
||||
|
||||
private:
|
||||
void findSections(ast::Action &action);
|
||||
|
||||
void parseParameterSection(ast::Action &action);
|
||||
void parsePreconditionSection(ast::Action &action);
|
||||
void parseEffectSection(ast::Action &action);
|
||||
|
||||
// For compatibility with old PDDL versions
|
||||
void parseVarsSection(ast::Action &action);
|
||||
|
||||
Context &m_context;
|
||||
ast::Domain &m_domain;
|
||||
|
||||
tokenize::StreamPosition m_parametersPosition;
|
||||
tokenize::StreamPosition m_preconditionPosition;
|
||||
tokenize::StreamPosition m_effectPosition;
|
||||
|
||||
// For compatibility with old PDDL versions
|
||||
tokenize::StreamPosition m_varsPosition;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
27
lib/pddl/include/pddl/detail/parsing/AtomicFormula.h
Normal file
27
lib/pddl/include/pddl/detail/parsing/AtomicFormula.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__ATOMIC_FORMULA_H
|
||||
#define __PDDL__DETAIL__PARSING__ATOMIC_FORMULA_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/detail/ASTContext.h>
|
||||
#include <pddl/detail/VariableStack.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AtomicFormula
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::AtomicFormula> parseAtomicFormula(Context &context, ASTContext &astContext, VariableStack &variableStack);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
27
lib/pddl/include/pddl/detail/parsing/Constant.h
Normal file
27
lib/pddl/include/pddl/detail/parsing/Constant.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__CONSTANT_H
|
||||
#define __PDDL__DETAIL__PARSING__CONSTANT_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/detail/ASTContext.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constant
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::ConstantPointer> testParsingConstant(Context &context, ASTContext &astContext);
|
||||
ast::ConstantPointer parseConstant(Context &context, ASTContext &astContext);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
26
lib/pddl/include/pddl/detail/parsing/ConstantDeclaration.h
Normal file
26
lib/pddl/include/pddl/detail/parsing/ConstantDeclaration.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__CONSTANT_DECLARATION_H
|
||||
#define __PDDL__DETAIL__PARSING__CONSTANT_DECLARATION_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ConstantDeclaration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void parseAndAddConstantDeclarations(Context &context, ast::Domain &domain);
|
||||
void parseAndAddConstantDeclarations(Context &context, ast::Problem &problem);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
37
lib/pddl/include/pddl/detail/parsing/Description.h
Normal file
37
lib/pddl/include/pddl/detail/parsing/Description.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__DESCRIPTION_H
|
||||
#define __PDDL__DETAIL__PARSING__DESCRIPTION_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Description
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class DescriptionParser
|
||||
{
|
||||
public:
|
||||
DescriptionParser(Context &context);
|
||||
ast::Description parse();
|
||||
|
||||
private:
|
||||
void findSections();
|
||||
|
||||
Context &m_context;
|
||||
tokenize::StreamPosition m_domainPosition;
|
||||
tokenize::StreamPosition m_problemPosition;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
48
lib/pddl/include/pddl/detail/parsing/Domain.h
Normal file
48
lib/pddl/include/pddl/detail/parsing/Domain.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__DOMAIN_H
|
||||
#define __PDDL__DETAIL__PARSING__DOMAIN_H
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Context.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Domain
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class DomainParser
|
||||
{
|
||||
public:
|
||||
DomainParser(Context &context);
|
||||
ast::DomainPointer parse();
|
||||
|
||||
private:
|
||||
void findSections(ast::Domain &domain);
|
||||
|
||||
void parseRequirementSection(ast::Domain &domain);
|
||||
void computeDerivedRequirements(ast::Domain &domain);
|
||||
void parseTypeSection(ast::Domain &domain);
|
||||
void parseConstantSection(ast::Domain &domain);
|
||||
void parsePredicateSection(ast::Domain &domain);
|
||||
void parseActionSection(ast::Domain &domain);
|
||||
|
||||
Context &m_context;
|
||||
|
||||
tokenize::StreamPosition m_requirementsPosition;
|
||||
tokenize::StreamPosition m_typesPosition;
|
||||
tokenize::StreamPosition m_constantsPosition;
|
||||
tokenize::StreamPosition m_predicatesPosition;
|
||||
std::vector<tokenize::StreamPosition> m_actionPositions;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
27
lib/pddl/include/pddl/detail/parsing/Effect.h
Normal file
27
lib/pddl/include/pddl/detail/parsing/Effect.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__EFFECT_H
|
||||
#define __PDDL__DETAIL__PARSING__EFFECT_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/detail/ASTContext.h>
|
||||
#include <pddl/detail/VariableStack.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Effect
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::Effect> parseEffect(Context &context, ASTContext &astContext, VariableStack &variableStack);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
252
lib/pddl/include/pddl/detail/parsing/Expressions.h
Normal file
252
lib/pddl/include/pddl/detail/parsing/Expressions.h
Normal file
@@ -0,0 +1,252 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__EXPRESSIONS_H
|
||||
#define __PDDL__DETAIL__PARSING__EXPRESSIONS_H
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/detail/ASTContext.h>
|
||||
#include <pddl/detail/VariableStack.h>
|
||||
#include <pddl/detail/parsing/VariableDeclaration.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Expressions
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename Argument, typename ArgumentParser>
|
||||
std::experimental::optional<ast::AndPointer<Argument>> parseAnd(Context &context, ASTContext &astContext, VariableStack &variableStack, ArgumentParser parseArgument);
|
||||
template<typename Argument, typename ArgumentParser>
|
||||
std::experimental::optional<ast::AtPointer<Argument>> parseAt(Context &context, ASTContext &astContext, VariableStack &variableStack, ArgumentParser parseArgument);
|
||||
template<typename Argument, typename ArgumentParser>
|
||||
std::experimental::optional<ast::EitherPointer<Argument>> parseEither(Context &context, ASTContext &astContext, VariableStack &variableStack, ArgumentParser parseArgument);
|
||||
template<typename Argument, typename ArgumentParser>
|
||||
std::experimental::optional<ast::ExistsPointer<Argument>> parseExists(Context &context, ASTContext &astContext, VariableStack &variableStack, ArgumentParser parseArgument);
|
||||
template<typename Argument, typename ArgumentParser>
|
||||
std::experimental::optional<ast::ForAllPointer<Argument>> parseForAll(Context &context, ASTContext &astContext, VariableStack &variableStack, ArgumentParser parseArgument);
|
||||
template<typename Argument, typename ArgumentParser>
|
||||
std::experimental::optional<ast::ImplyPointer<Argument>> parseImply(Context &context, ASTContext &astContext, VariableStack &variableStack, ArgumentParser parseArgument);
|
||||
template<typename Argument, typename ArgumentParser>
|
||||
std::experimental::optional<ast::NotPointer<Argument>> parseNot(Context &context, ASTContext &astContext, VariableStack &variableStack, ArgumentParser parseArgument);
|
||||
template<typename Argument, typename ArgumentParser>
|
||||
std::experimental::optional<ast::OrPointer<Argument>> parseOr(Context &context, ASTContext &astContext, VariableStack &variableStack, ArgumentParser parseArgument);
|
||||
template<typename ArgumentLeft, typename ArgumentRight, typename ArgumentLeftParser, typename ArgumentRightParser>
|
||||
std::experimental::optional<ast::WhenPointer<ArgumentLeft, ArgumentRight>> parseWhen(Context &context, ASTContext &astContext, VariableStack &variableStack, ArgumentLeftParser parseArgumentLeft, ArgumentRightParser parseArgumentRight);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Expressions: Base Classes
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived, typename ArgumentLeftParser, typename ArgumentRightParser>
|
||||
std::experimental::optional<std::unique_ptr<Derived>> parseBinary(Context &context,
|
||||
ASTContext &astContext, VariableStack &variableStack, ArgumentLeftParser parseArgumentLeft,
|
||||
ArgumentRightParser parseArgumentRight)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
if (!tokenizer.testAndSkip<std::string>("(")
|
||||
|| !tokenizer.testIdentifierAndSkip(Derived::Identifier))
|
||||
{
|
||||
tokenizer.seek(position);
|
||||
return std::experimental::nullopt;
|
||||
}
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Parse arguments of the expression
|
||||
auto argumentLeft = parseArgumentLeft(context, astContext, variableStack);
|
||||
|
||||
if (!argumentLeft)
|
||||
throw ParserException(tokenizer.location(), "could not parse argument of “" + std::string(Derived::Identifier) + "” expression");
|
||||
|
||||
auto argumentRight = parseArgumentRight(context, astContext, variableStack);
|
||||
|
||||
if (!argumentRight)
|
||||
throw ParserException(tokenizer.location(), "could not parse argument of “" + std::string(Derived::Identifier) + "” expression");
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
return std::make_unique<Derived>(std::move(argumentLeft.value()), std::move(argumentRight.value()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived, typename ArgumentParser>
|
||||
std::experimental::optional<std::unique_ptr<Derived>> parseNAry(Context &context,
|
||||
ASTContext &astContext, VariableStack &variableStack, ArgumentParser parseArgument)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
if (!tokenizer.testAndSkip<std::string>("(")
|
||||
|| !tokenizer.testIdentifierAndSkip(Derived::Identifier))
|
||||
{
|
||||
tokenizer.seek(position);
|
||||
return std::experimental::nullopt;
|
||||
}
|
||||
|
||||
typename Derived::Arguments arguments;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Parse arguments of the expression
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
auto argument = parseArgument(context, astContext, variableStack);
|
||||
|
||||
if (!argument)
|
||||
throw ParserException(tokenizer.location(), "could not parse argument of “" + std::string(Derived::Identifier) + "” expression");
|
||||
|
||||
arguments.emplace_back(std::move(argument.value()));
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
if (arguments.empty())
|
||||
context.warningCallback(tokenizer.location(), "“" + std::string(Derived::Identifier) + "” expressions should not be empty");
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
return std::make_unique<Derived>(std::move(arguments));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived, typename ArgumentParser>
|
||||
std::experimental::optional<std::unique_ptr<Derived>> parseQuantified(Context &context,
|
||||
ASTContext &astContext, VariableStack &variableStack, ArgumentParser parseArgument)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
if (!tokenizer.testAndSkip<std::string>("(")
|
||||
|| !tokenizer.testIdentifierAndSkip(Derived::Identifier))
|
||||
{
|
||||
tokenizer.seek(position);
|
||||
return std::experimental::nullopt;
|
||||
}
|
||||
|
||||
// Parse variable list
|
||||
tokenizer.expect<std::string>("(");
|
||||
auto parameters = parseVariableDeclarations(context, *astContext.domain);
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
// Push newly parsed variables to the stack
|
||||
variableStack.push(¶meters);
|
||||
|
||||
// Parse argument of the expression
|
||||
auto argument = parseArgument(context, astContext, variableStack);
|
||||
|
||||
if (!argument)
|
||||
throw ParserException(tokenizer.location(), "could not parse argument of “" + std::string(Derived::Identifier) + "” expression");
|
||||
|
||||
// Clean up variable stack
|
||||
variableStack.pop();
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
return std::make_unique<Derived>(std::move(parameters), std::move(argument.value()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Expressions
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename Argument, typename ArgumentParser>
|
||||
std::experimental::optional<ast::AndPointer<Argument>> parseAnd(Context &context, ASTContext &astContext, VariableStack &variableStack, ArgumentParser parseArgument)
|
||||
{
|
||||
return parseNAry<ast::And<Argument>, ArgumentParser>(context, astContext, variableStack, parseArgument);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename Argument, typename ArgumentParser>
|
||||
std::experimental::optional<ast::EitherPointer<Argument>> parseEither(Context &context, ASTContext &astContext, VariableStack &variableStack, ArgumentParser parseArgument)
|
||||
{
|
||||
return parseNAry<ast::Either<Argument>, ArgumentParser>(context, astContext, variableStack, parseArgument);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename Argument, typename ArgumentParser>
|
||||
std::experimental::optional<ast::ExistsPointer<Argument>> parseExists(Context &context, ASTContext &astContext, VariableStack &variableStack, ArgumentParser parseArgument)
|
||||
{
|
||||
return parseQuantified<ast::Exists<Argument>, ArgumentParser>(context, astContext, variableStack, parseArgument);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename Argument, typename ArgumentParser>
|
||||
std::experimental::optional<ast::ForAllPointer<Argument>> parseForAll(Context &context, ASTContext &astContext, VariableStack &variableStack, ArgumentParser parseArgument)
|
||||
{
|
||||
return parseQuantified<ast::ForAll<Argument>, ArgumentParser>(context, astContext, variableStack, parseArgument);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename Argument, typename ArgumentParser>
|
||||
std::experimental::optional<ast::ImplyPointer<Argument>> parseImply(Context &context, ASTContext &astContext, VariableStack &variableStack, ArgumentParser parseArgument)
|
||||
{
|
||||
return parseBinary<ast::Imply<Argument>, ArgumentParser, ArgumentParser>(context, astContext, variableStack, parseArgument, parseArgument);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename Argument, typename ArgumentParser>
|
||||
std::experimental::optional<ast::NotPointer<Argument>> parseNot(Context &context, ASTContext &astContext, VariableStack &variableStack, ArgumentParser parseArgument)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
if (!tokenizer.testAndSkip<std::string>("(")
|
||||
|| !tokenizer.testIdentifierAndSkip("not"))
|
||||
{
|
||||
tokenizer.seek(position);
|
||||
return std::experimental::nullopt;
|
||||
}
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Parse argument
|
||||
auto argument = parseArgument(context, astContext, variableStack);
|
||||
|
||||
if (!argument)
|
||||
throw ParserException(tokenizer.location(), "could not parse argument of “not” expression");
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
return std::make_unique<ast::Not<Argument>>(std::move(argument.value()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename Argument, typename ArgumentParser>
|
||||
std::experimental::optional<ast::OrPointer<Argument>> parseOr(Context &context, ASTContext &astContext, VariableStack &variableStack, ArgumentParser parseArgument)
|
||||
{
|
||||
return parseNAry<ast::Or<Argument>, ArgumentParser>(context, astContext, variableStack, parseArgument);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename ArgumentLeft, typename ArgumentRight, typename ArgumentLeftParser, typename ArgumentRightParser>
|
||||
std::experimental::optional<ast::WhenPointer<ArgumentLeft, ArgumentRight>> parseWhen(Context &context, ASTContext &astContext, VariableStack &variableStack, ArgumentLeftParser parseArgumentLeft, ArgumentRightParser parseArgumentRight)
|
||||
{
|
||||
return parseBinary<ast::When<ArgumentLeft, ArgumentRight>, ArgumentLeftParser, ArgumentRightParser>(context, astContext, variableStack, parseArgumentLeft, parseArgumentRight);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
27
lib/pddl/include/pddl/detail/parsing/Fact.h
Normal file
27
lib/pddl/include/pddl/detail/parsing/Fact.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__FACT_H
|
||||
#define __PDDL__DETAIL__PARSING__FACT_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/detail/ASTContext.h>
|
||||
#include <pddl/detail/VariableStack.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Fact
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::Fact> parseFact(Context &context, ASTContext &astContext, VariableStack &variableStack);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
25
lib/pddl/include/pddl/detail/parsing/InitialState.h
Normal file
25
lib/pddl/include/pddl/detail/parsing/InitialState.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__INITIAL_STATE_H
|
||||
#define __PDDL__DETAIL__PARSING__INITIAL_STATE_H
|
||||
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/detail/ASTContext.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// InitialState
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::InitialState parseInitialState(Context &context, ASTContext &astContext, VariableStack &variableStack);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
41
lib/pddl/include/pddl/detail/parsing/Parser.h
Normal file
41
lib/pddl/include/pddl/detail/parsing/Parser.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef __PDDL__DETAIL__PARSER_H
|
||||
#define __PDDL__DETAIL__PARSER_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/detail/ASTContext.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Parser
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class T>
|
||||
struct Parser
|
||||
{
|
||||
};
|
||||
|
||||
template<class T, typename... ArgumentParser>
|
||||
std::experimental::optional<T> parse(Context &context, ASTContext &astContext, ArgumentParser... argumentParsers)
|
||||
{
|
||||
return detail::Parser<T>().parse(context, astContext, argumentParsers...);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
std::experimental::optional<T> parse(Context &context, ASTContext &astContext)
|
||||
{
|
||||
return detail::Parser<T>().parse(context, astContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
28
lib/pddl/include/pddl/detail/parsing/Precondition.h
Normal file
28
lib/pddl/include/pddl/detail/parsing/Precondition.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__PRECONDITION_H
|
||||
#define __PDDL__DETAIL__PARSING__PRECONDITION_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/detail/ASTContext.h>
|
||||
#include <pddl/detail/VariableStack.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Precondition
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::Precondition> parsePrecondition(Context &context, ASTContext &astContext, VariableStack &variableStack);
|
||||
std::experimental::optional<ast::Precondition> parsePreconditionBody(Context &context, ASTContext &astContext, VariableStack &variableStack);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
28
lib/pddl/include/pddl/detail/parsing/Predicate.h
Normal file
28
lib/pddl/include/pddl/detail/parsing/Predicate.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__PREDICATE_H
|
||||
#define __PDDL__DETAIL__PARSING__PREDICATE_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/detail/ASTContext.h>
|
||||
#include <pddl/detail/VariableStack.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Predicate
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: rename consistently
|
||||
std::experimental::optional<ast::PredicatePointer> parsePredicate(Context &context, ASTContext &astContext, VariableStack &variableStack);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
25
lib/pddl/include/pddl/detail/parsing/PredicateDeclaration.h
Normal file
25
lib/pddl/include/pddl/detail/parsing/PredicateDeclaration.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__PREDICATE_DECLARATION_H
|
||||
#define __PDDL__DETAIL__PARSING__PREDICATE_DECLARATION_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PredicateDeclaration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void parseAndAddPredicateDeclarations(Context &context, ast::Domain &domain);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
25
lib/pddl/include/pddl/detail/parsing/PrimitiveType.h
Normal file
25
lib/pddl/include/pddl/detail/parsing/PrimitiveType.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__PRIMITIVE_TYPE_H
|
||||
#define __PDDL__DETAIL__PARSING__PRIMITIVE_TYPE_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PrimitiveType
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::PrimitiveTypePointer parsePrimitiveType(Context &context, ast::Domain &domain);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -0,0 +1,25 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__PRIMITIVE_TYPE_DECLARATION_H
|
||||
#define __PDDL__DETAIL__PARSING__PRIMITIVE_TYPE_DECLARATION_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PrimitiveTypeDeclaration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void parseAndAddPrimitiveTypeDeclarations(Context &context, ast::Domain &domain);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
49
lib/pddl/include/pddl/detail/parsing/Problem.h
Normal file
49
lib/pddl/include/pddl/detail/parsing/Problem.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__PROBLEM_H
|
||||
#define __PDDL__DETAIL__PARSING__PROBLEM_H
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Context.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Problem
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ProblemParser
|
||||
{
|
||||
public:
|
||||
ProblemParser(Context &context, ast::Domain &domain);
|
||||
ast::ProblemPointer parse();
|
||||
|
||||
private:
|
||||
void findSections(ast::Problem &problem);
|
||||
|
||||
void parseDomainSection(ast::Problem &problem);
|
||||
void parseRequirementSection(ast::Problem &problem);
|
||||
void computeDerivedRequirements(ast::Problem &problem);
|
||||
void parseObjectSection(ast::Problem &problem);
|
||||
void parseInitialStateSection(ast::Problem &problem);
|
||||
void parseGoalSection(ast::Problem &problem);
|
||||
|
||||
Context &m_context;
|
||||
ast::Domain &m_domain;
|
||||
|
||||
tokenize::StreamPosition m_domainPosition;
|
||||
tokenize::StreamPosition m_requirementsPosition;
|
||||
tokenize::StreamPosition m_objectsPosition;
|
||||
tokenize::StreamPosition m_initialStatePosition;
|
||||
tokenize::StreamPosition m_goalPosition;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
26
lib/pddl/include/pddl/detail/parsing/Requirement.h
Normal file
26
lib/pddl/include/pddl/detail/parsing/Requirement.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__REQUIREMENT_H
|
||||
#define __PDDL__DETAIL__PARSING__REQUIREMENT_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Requirement
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::Requirement> parseRequirement(Context &context);
|
||||
const char *toString(const ast::Requirement &requirement);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
25
lib/pddl/include/pddl/detail/parsing/Type.h
Normal file
25
lib/pddl/include/pddl/detail/parsing/Type.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__TYPE_H
|
||||
#define __PDDL__DETAIL__PARSING__TYPE_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Type
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::Type parseType(Context &context, ast::Domain &domain);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
26
lib/pddl/include/pddl/detail/parsing/Unsupported.h
Normal file
26
lib/pddl/include/pddl/detail/parsing/Unsupported.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__UNSUPPORTED_H
|
||||
#define __PDDL__DETAIL__PARSING__UNSUPPORTED_H
|
||||
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/Exception.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Unsupported
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ParserException exceptUnsupportedExpression(tokenize::StreamPosition position, Context &context);
|
||||
ParserException exceptUnsupportedSection(tokenize::StreamPosition position, Context &context);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
44
lib/pddl/include/pddl/detail/parsing/Utils.h
Normal file
44
lib/pddl/include/pddl/detail/parsing/Utils.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef __PDDL__DETAIL__PARSE_UTILS_H
|
||||
#define __PDDL__DETAIL__PARSE_UTILS_H
|
||||
|
||||
#include <pddl/Tokenizer.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ParseUtils
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: refactor
|
||||
inline void skipSection(Tokenizer &tokenizer)
|
||||
{
|
||||
size_t openParentheses = 1;
|
||||
|
||||
while (true)
|
||||
{
|
||||
const auto character = tokenizer.currentCharacter();
|
||||
tokenizer.advance();
|
||||
|
||||
if (character == '(')
|
||||
openParentheses++;
|
||||
else if (character == ')')
|
||||
{
|
||||
openParentheses--;
|
||||
|
||||
if (openParentheses == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
28
lib/pddl/include/pddl/detail/parsing/Variable.h
Normal file
28
lib/pddl/include/pddl/detail/parsing/Variable.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__VARIABLE_H
|
||||
#define __PDDL__DETAIL__PARSING__VARIABLE_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
#include <pddl/detail/VariableStack.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Variable
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: find consistent naming scheme
|
||||
std::experimental::optional<ast::VariablePointer> testParsingVariable(Context &context, VariableStack &variableStack);
|
||||
ast::VariablePointer parseVariable(Context &context, VariableStack &variableStack);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
26
lib/pddl/include/pddl/detail/parsing/VariableDeclaration.h
Normal file
26
lib/pddl/include/pddl/detail/parsing/VariableDeclaration.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __PDDL__DETAIL__PARSING__VARIABLE_DECLARATION_H
|
||||
#define __PDDL__DETAIL__PARSING__VARIABLE_DECLARATION_H
|
||||
|
||||
#include <pddl/ASTForward.h>
|
||||
#include <pddl/Context.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// VariableDeclaration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void parseAndAddVariableDeclarations(Context &context, ast::Domain &domain, ast::VariableDeclarations &variableDeclarations);
|
||||
ast::VariableDeclarations parseVariableDeclarations(Context &context, ast::Domain &domain);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
41
lib/pddl/src/CMakeLists.txt
Normal file
41
lib/pddl/src/CMakeLists.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
set(target pddl)
|
||||
|
||||
file(GLOB core_sources "pddl/*.cpp")
|
||||
file(GLOB core_headers "../include/pddl/*.h")
|
||||
|
||||
file(GLOB detail_sources "pddl/detail/*.cpp")
|
||||
file(GLOB detail_headers "../include/pddl/detail/*.h")
|
||||
|
||||
file(GLOB detail_parsing_sources "pddl/detail/parsing/*.cpp")
|
||||
file(GLOB detail_parsing_headers "../include/pddl/detail/parsing/*.h")
|
||||
|
||||
file(GLOB detail_normalization_sources "pddl/detail/normalization/*.cpp")
|
||||
file(GLOB detail_normalization_headers "../include/pddl/detail/normalization/*.h")
|
||||
|
||||
set(includes
|
||||
${PROJECT_SOURCE_DIR}/include
|
||||
${PROJECT_SOURCE_DIR}/../../lib/colorlog/include
|
||||
${PROJECT_SOURCE_DIR}/../../lib/tokenize/include
|
||||
${PROJECT_SOURCE_DIR}/../../lib/variant/include
|
||||
)
|
||||
|
||||
set(sources
|
||||
${core_sources}
|
||||
${core_headers}
|
||||
|
||||
${detail_sources}
|
||||
${detail_headers}
|
||||
|
||||
${detail_parsing_sources}
|
||||
${detail_parsing_headers}
|
||||
|
||||
${detail_normalization_sources}
|
||||
${detail_normalization_headers}
|
||||
)
|
||||
|
||||
set(libraries
|
||||
)
|
||||
|
||||
add_library(${target} ${sources})
|
||||
target_include_directories(${target} PRIVATE ${includes})
|
||||
target_link_libraries(${target} ${libraries})
|
22
lib/pddl/src/pddl/Parse.cpp
Normal file
22
lib/pddl/src/pddl/Parse.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#include <pddl/Parse.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/detail/parsing/Description.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Parse
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::Description parseDescription(Context &context)
|
||||
{
|
||||
return detail::DescriptionParser(context).parse();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
99
lib/pddl/src/pddl/detail/Requirements.cpp
Normal file
99
lib/pddl/src/pddl/detail/Requirements.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
#include <pddl/detail/Requirements.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/detail/parsing/Requirement.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Requirements
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool hasRequirement(const ast::Domain &domain, ast::Requirement requirement)
|
||||
{
|
||||
const auto match = std::find_if(domain.requirements.cbegin(), domain.requirements.cend(),
|
||||
[&](const auto &declaredRequirement)
|
||||
{
|
||||
return declaredRequirement == requirement;
|
||||
});
|
||||
|
||||
return match != domain.requirements.cend();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool hasRequirement(const ast::Problem &problem, ast::Requirement requirement)
|
||||
{
|
||||
const auto match = std::find_if(problem.requirements.cbegin(), problem.requirements.cend(),
|
||||
[&](const auto &declaredRequirement)
|
||||
{
|
||||
return declaredRequirement == requirement;
|
||||
});
|
||||
|
||||
if (match != problem.requirements.cend())
|
||||
return true;
|
||||
|
||||
return hasRequirement(problem.domain, requirement);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool hasRequirement(const ASTContext &astContext, ast::Requirement requirement)
|
||||
{
|
||||
if (astContext.problem)
|
||||
return hasRequirement(*astContext.problem.value(), requirement);
|
||||
|
||||
return hasRequirement(*astContext.domain, requirement);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void checkRequirement(ast::Domain &domain, ast::Requirement requirement, Context &context)
|
||||
{
|
||||
if (hasRequirement(domain, requirement))
|
||||
return;
|
||||
|
||||
if (context.mode == Mode::Compatibility)
|
||||
context.warningCallback(context.tokenizer.location(), "requirement “" + std::string(toString(requirement)) + "” used but never declared, silently adding requirement");
|
||||
else
|
||||
throw ParserException(context.tokenizer.location(), "requirement “" + std::string(toString(requirement)) + "” used but never declared");
|
||||
|
||||
domain.requirements.push_back(requirement);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void checkRequirement(ast::Problem &problem, ast::Requirement requirement, Context &context)
|
||||
{
|
||||
if (hasRequirement(problem, requirement))
|
||||
return;
|
||||
|
||||
if (context.mode == Mode::Compatibility)
|
||||
context.warningCallback(context.tokenizer.location(), "requirement “" + std::string(toString(requirement)) + "” used but never declared, silently adding requirement");
|
||||
else
|
||||
throw ParserException(context.tokenizer.location(), "requirement “" + std::string(toString(requirement)) + "” used but never declared");
|
||||
|
||||
problem.requirements.push_back(requirement);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void checkRequirement(ASTContext &astContext, ast::Requirement requirement, Context &context)
|
||||
{
|
||||
if (astContext.problem)
|
||||
checkRequirement(*astContext.problem.value(), requirement, context);
|
||||
else
|
||||
checkRequirement(*astContext.domain, requirement, context);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
140
lib/pddl/src/pddl/detail/SignatureMatching.cpp
Normal file
140
lib/pddl/src/pddl/detail/SignatureMatching.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
#include <pddl/detail/SignatureMatching.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SignatureMatching
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool matches(const ast::PrimitiveTypeDeclaration &lhs, const ast::PrimitiveTypeDeclaration &rhs)
|
||||
{
|
||||
// TODO: check if this assumption is correct
|
||||
// With typing enabled, all objects inherit from “object”
|
||||
if (rhs.name == "object")
|
||||
return true;
|
||||
|
||||
// Two types match if rhs is lhs or one of its ancestors
|
||||
if (&lhs == &rhs)
|
||||
return true;
|
||||
|
||||
for (const auto &lhsParentType : lhs.parentTypes)
|
||||
if (matches(*lhsParentType->declaration, rhs))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool matches(const ast::PrimitiveTypeDeclaration &lhs, const ast::Either<ast::PrimitiveTypePointer> &rhs)
|
||||
{
|
||||
for (const auto &rhsType : rhs.arguments)
|
||||
if (matches(lhs, *rhsType->declaration))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool matches(const ast::Either<ast::PrimitiveTypePointer> &lhs, const ast::PrimitiveTypeDeclaration &rhs)
|
||||
{
|
||||
if (lhs.arguments.size() != 1)
|
||||
return false;
|
||||
|
||||
// Strictly speaking, a 1-ary either is identical to its argument
|
||||
return matches(*lhs.arguments[0]->declaration, rhs);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool matches(const ast::Either<ast::PrimitiveTypePointer> &lhs, const ast::Either<ast::PrimitiveTypePointer> &rhs)
|
||||
{
|
||||
// All of the types in lhs must have a match in rhs
|
||||
for (const auto &lhsType : lhs.arguments)
|
||||
if (!matches(*lhsType->declaration, rhs))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class T>
|
||||
bool matches(const T &lhs, const ast::Type &rhs)
|
||||
{
|
||||
return rhs.match(
|
||||
[&](const ast::PrimitiveTypePointer &x){return matches(lhs, *x->declaration);},
|
||||
[&](const ast::EitherPointer<ast::PrimitiveTypePointer> &x){return matches(lhs, *x);});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool matches(const ast::Type &lhs, const ast::Type &rhs)
|
||||
{
|
||||
return lhs.match(
|
||||
[&](const ast::PrimitiveTypePointer &x){return matches(*x->declaration, rhs);},
|
||||
[&](const ast::EitherPointer<ast::PrimitiveTypePointer> &x){return matches(*x, rhs);});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool matches(const ast::VariableDeclaration &lhs, const std::experimental::optional<ast::Type> &rhs)
|
||||
{
|
||||
if (!lhs.type && !rhs)
|
||||
return true;
|
||||
|
||||
// If typing is enabled, all objects have to be typed
|
||||
assert(lhs.type);
|
||||
assert(rhs);
|
||||
|
||||
return matches(lhs.type.value(), rhs.value());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool matches(const ast::ConstantDeclaration &lhs, const std::experimental::optional<ast::Type> &rhs)
|
||||
{
|
||||
if (!lhs.type && !rhs)
|
||||
return true;
|
||||
|
||||
// If typing is enabled, all objects have to be typed
|
||||
assert(lhs.type);
|
||||
assert(rhs);
|
||||
|
||||
return matches(lhs.type.value(), rhs.value());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool matches(const ast::Term &lhs, const std::experimental::optional<ast::Type> &rhs)
|
||||
{
|
||||
return lhs.match([&](const auto &x){return matches(*x->declaration, rhs);});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool matches(const std::string &predicateName, const ast::Predicate::Arguments &predicateArguments, const ast::PredicateDeclaration &predicateDeclaration)
|
||||
{
|
||||
if (predicateName != predicateDeclaration.name)
|
||||
return false;
|
||||
|
||||
if (predicateArguments.size() != predicateDeclaration.parameters.size())
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < predicateArguments.size(); i++)
|
||||
if (!matches(predicateArguments[i], predicateDeclaration.parameters[i]->type))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
77
lib/pddl/src/pddl/detail/VariableStack.cpp
Normal file
77
lib/pddl/src/pddl/detail/VariableStack.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#include <pddl/detail/VariableStack.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// VariableStack
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void VariableStack::push(ast::VariableDeclarations *layer)
|
||||
{
|
||||
m_layers.push_back(layer);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void VariableStack::pop()
|
||||
{
|
||||
m_layers.pop_back();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::VariableDeclaration *> VariableStack::findVariableDeclaration(const std::string &variableName) const
|
||||
{
|
||||
const auto variableDeclarationMatches =
|
||||
[&variableName](const auto &variableDeclaration)
|
||||
{
|
||||
return variableDeclaration->name == variableName;
|
||||
};
|
||||
|
||||
for (auto i = m_layers.rbegin(); i != m_layers.rend(); i++)
|
||||
{
|
||||
auto &layer = **i;
|
||||
const auto matchingVariableDeclaration = std::find_if(layer.begin(), layer.end(), variableDeclarationMatches);
|
||||
|
||||
if (matchingVariableDeclaration != layer.end())
|
||||
return matchingVariableDeclaration->get();
|
||||
}
|
||||
|
||||
return std::experimental::nullopt;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool VariableStack::contains(const ast::VariableDeclaration &variableDeclaration) const
|
||||
{
|
||||
const auto variableDeclarationMatches =
|
||||
[&](const auto &other)
|
||||
{
|
||||
return &variableDeclaration == other.get();
|
||||
};
|
||||
|
||||
for (auto i = m_layers.rbegin(); i != m_layers.rend(); i++)
|
||||
{
|
||||
auto &layer = **i;
|
||||
const auto matchingVariableDeclaration = std::find_if(layer.begin(), layer.end(), variableDeclarationMatches);
|
||||
|
||||
if (matchingVariableDeclaration != layer.end())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
38
lib/pddl/src/pddl/detail/normalization/Action.cpp
Normal file
38
lib/pddl/src/pddl/detail/normalization/Action.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include <pddl/detail/normalization/Action.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/NormalizedAST.h>
|
||||
#include <pddl/detail/normalization/Effect.h>
|
||||
#include <pddl/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);
|
||||
|
||||
if (action->effect)
|
||||
normalizedAction->effect = normalize(std::move(action->effect.value()), derivedPredicates);
|
||||
|
||||
return normalizedAction;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
32
lib/pddl/src/pddl/detail/normalization/AtomicFormula.cpp
Normal file
32
lib/pddl/src/pddl/detail/normalization/AtomicFormula.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include <pddl/detail/normalization/AtomicFormula.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/NormalizedAST.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AtomicFormula
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::AtomicFormula normalize(ast::AtomicFormula &&atomicFormula)
|
||||
{
|
||||
const auto handlePredicate =
|
||||
[&](ast::PredicatePointer &predicate) -> normalizedAST::AtomicFormula
|
||||
{
|
||||
return std::move(predicate);
|
||||
};
|
||||
|
||||
return atomicFormula.match(handlePredicate);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
45
lib/pddl/src/pddl/detail/normalization/ConditionalEffect.cpp
Normal file
45
lib/pddl/src/pddl/detail/normalization/ConditionalEffect.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include <pddl/detail/normalization/Effect.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/NormalizedAST.h>
|
||||
#include <pddl/detail/normalization/Literal.h>
|
||||
#include <pddl/detail/normalization/Precondition.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Effect
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::ConditionalEffect normalize(ast::ConditionalEffect &&conditionalEffect)
|
||||
{
|
||||
const auto handleLiteral =
|
||||
[](ast::Literal &literal) -> normalizedAST::ConditionalEffect
|
||||
{
|
||||
return normalize(std::move(literal));
|
||||
};
|
||||
|
||||
const auto handleAnd =
|
||||
[&](ast::AndPointer<ast::Literal> &and_) -> normalizedAST::ConditionalEffect
|
||||
{
|
||||
normalizedAST::And<normalizedAST::Literal>::Arguments arguments;
|
||||
|
||||
for (auto &argument : and_->arguments)
|
||||
arguments.emplace_back(normalize(std::move(argument)));
|
||||
|
||||
return std::make_unique<normalizedAST::And<normalizedAST::Literal>>(std::move(arguments));
|
||||
};
|
||||
|
||||
return conditionalEffect.match(handleLiteral, handleAnd);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
34
lib/pddl/src/pddl/detail/normalization/Description.cpp
Normal file
34
lib/pddl/src/pddl/detail/normalization/Description.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include <pddl/detail/normalization/Description.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/NormalizedAST.h>
|
||||
#include <pddl/detail/normalization/Domain.h>
|
||||
#include <pddl/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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
38
lib/pddl/src/pddl/detail/normalization/Domain.cpp
Normal file
38
lib/pddl/src/pddl/detail/normalization/Domain.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include <pddl/detail/normalization/Domain.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/NormalizedAST.h>
|
||||
#include <pddl/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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
62
lib/pddl/src/pddl/detail/normalization/Effect.cpp
Normal file
62
lib/pddl/src/pddl/detail/normalization/Effect.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include <pddl/detail/normalization/Effect.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/NormalizedAST.h>
|
||||
#include <pddl/detail/normalization/ConditionalEffect.h>
|
||||
#include <pddl/detail/normalization/Literal.h>
|
||||
#include <pddl/detail/normalization/Precondition.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Effect
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::Effect normalize(ast::Effect &&effect, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
|
||||
{
|
||||
const auto handleLiteral =
|
||||
[](ast::Literal &literal) -> normalizedAST::Effect
|
||||
{
|
||||
return normalize(std::move(literal));
|
||||
};
|
||||
|
||||
const auto handleAnd =
|
||||
[&](ast::AndPointer<ast::Effect> &and_) -> normalizedAST::Effect
|
||||
{
|
||||
normalizedAST::And<normalizedAST::Effect>::Arguments arguments;
|
||||
|
||||
for (auto &argument : and_->arguments)
|
||||
arguments.emplace_back(normalize(std::move(argument), derivedPredicates));
|
||||
|
||||
return std::make_unique<normalizedAST::And<normalizedAST::Effect>>(std::move(arguments));
|
||||
};
|
||||
|
||||
const auto handleForAll =
|
||||
[&](ast::ForAllPointer<ast::Effect> &forAll) -> normalizedAST::Effect
|
||||
{
|
||||
auto normalizedArgument = normalize(std::move(forAll->argument), derivedPredicates);
|
||||
return std::make_unique<normalizedAST::ForAll<normalizedAST::Effect>>(std::move(forAll->parameters), std::move(normalizedArgument));
|
||||
};
|
||||
|
||||
const auto handleWhen =
|
||||
[&](ast::WhenPointer<ast::Precondition, ast::ConditionalEffect> &when) -> normalizedAST::Effect
|
||||
{
|
||||
auto normalizedCondition = normalize(std::move(when->argumentLeft), derivedPredicates);
|
||||
auto normalizedConditionalEffect = normalize(std::move(when->argumentRight));
|
||||
|
||||
return std::make_unique<normalizedAST::When<normalizedAST::Precondition, normalizedAST::ConditionalEffect>>(std::move(normalizedCondition), std::move(normalizedConditionalEffect));
|
||||
};
|
||||
|
||||
return effect.match(handleLiteral, handleAnd, handleForAll, handleWhen);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
39
lib/pddl/src/pddl/detail/normalization/Fact.cpp
Normal file
39
lib/pddl/src/pddl/detail/normalization/Fact.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <pddl/detail/normalization/Fact.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/NormalizedAST.h>
|
||||
#include <pddl/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 can’t be normalized currently");
|
||||
};
|
||||
|
||||
return fact.match(handleLiteral, handleAt);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
33
lib/pddl/src/pddl/detail/normalization/InitialState.cpp
Normal file
33
lib/pddl/src/pddl/detail/normalization/InitialState.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <pddl/detail/normalization/InitialState.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/NormalizedAST.h>
|
||||
#include <pddl/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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
39
lib/pddl/src/pddl/detail/normalization/Literal.cpp
Normal file
39
lib/pddl/src/pddl/detail/normalization/Literal.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <pddl/detail/normalization/Literal.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/NormalizedAST.h>
|
||||
#include <pddl/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> ¬_) -> normalizedAST::Literal
|
||||
{
|
||||
return std::make_unique<normalizedAST::Not<normalizedAST::AtomicFormula>>(normalize(std::move(not_->argument)));
|
||||
};
|
||||
|
||||
return literal.match(handleAtomicFormula, handleNot);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
360
lib/pddl/src/pddl/detail/normalization/Precondition.cpp
Normal file
360
lib/pddl/src/pddl/detail/normalization/Precondition.cpp
Normal file
@@ -0,0 +1,360 @@
|
||||
#include <pddl/detail/normalization/Precondition.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/NormalizedAST.h>
|
||||
#include <pddl/detail/normalization/AtomicFormula.h>
|
||||
#include <pddl/detail/normalization/CollectFreeVariables.h>
|
||||
#include <pddl/detail/normalization/Reduction.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Precondition
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Forward Declarations
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::Literal normalizeNested(ast::AndPointer<ast::Precondition> &and_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
|
||||
normalizedAST::Literal normalizeNested(ast::AtomicFormula &, normalizedAST::DerivedPredicateDeclarations &);
|
||||
normalizedAST::Literal normalizeNested(ast::ExistsPointer<ast::Precondition> &exists, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
|
||||
normalizedAST::Literal normalizeNested(ast::ForAllPointer<ast::Precondition> &forAll, normalizedAST::DerivedPredicateDeclarations &);
|
||||
normalizedAST::Literal normalizeNested(ast::ImplyPointer<ast::Precondition> &, normalizedAST::DerivedPredicateDeclarations &);
|
||||
normalizedAST::Literal normalizeNested(ast::NotPointer<ast::Precondition> ¬_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
|
||||
normalizedAST::Literal normalizeNested(ast::OrPointer<ast::Precondition> &or_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
|
||||
normalizedAST::AndPointer<normalizedAST::Literal> normalizeTopLevel(ast::AndPointer<ast::Precondition> &and_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
|
||||
normalizedAST::AtomicFormula normalizeTopLevel(ast::AtomicFormula &, normalizedAST::DerivedPredicateDeclarations &);
|
||||
normalizedAST::Literal normalizeTopLevel(ast::ExistsPointer<ast::Precondition> &exists, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
|
||||
normalizedAST::Literal normalizeTopLevel(ast::ForAllPointer<ast::Precondition> &forAll, normalizedAST::DerivedPredicateDeclarations &);
|
||||
normalizedAST::Literal normalizeTopLevel(ast::ImplyPointer<ast::Precondition> &, normalizedAST::DerivedPredicateDeclarations &);
|
||||
normalizedAST::NotPointer<normalizedAST::AtomicFormula> normalizeTopLevel(ast::NotPointer<ast::Precondition> ¬_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
|
||||
normalizedAST::OrPointer<normalizedAST::Literal> normalizeTopLevel(ast::OrPointer<ast::Precondition> &or_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::DerivedPredicatePointer addDerivedPredicate(const std::vector<normalizedAST::VariableDeclaration *> ¶meters, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
|
||||
{
|
||||
auto name = "derived-predicate-" + std::to_string(derivedPredicates.size() + 1);
|
||||
|
||||
normalizedAST::DerivedPredicate::Arguments arguments;
|
||||
arguments.reserve(parameters.size());
|
||||
|
||||
for (const auto ¶meter : 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::AtomicFormula &atomicFormula, normalizedAST::DerivedPredicateDeclarations &)
|
||||
{
|
||||
return normalize(std::move(atomicFormula));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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) -> normalizedAST::DerivedPredicatePrecondition
|
||||
{
|
||||
return normalizeTopLevel(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> ¬_, normalizedAST::DerivedPredicateDeclarations &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>();
|
||||
|
||||
return std::make_unique<normalizedAST::Not<normalizedAST::AtomicFormula>>(std::move(normalizedArgument));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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::AtomicFormula normalizeTopLevel(ast::AtomicFormula &atomicFormula, normalizedAST::DerivedPredicateDeclarations &)
|
||||
{
|
||||
return normalize(std::move(atomicFormula));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Normalize top-level conjunctions
|
||||
normalizedAST::AndPointer<normalizedAST::Literal> normalizeTopLevel(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> ¬_) -> normalizedAST::Literal
|
||||
{
|
||||
return normalizeTopLevel(not_, derivedPredicates);
|
||||
};
|
||||
|
||||
const auto handleNested =
|
||||
[&](auto &nested) -> normalizedAST::Literal
|
||||
{
|
||||
return normalizeNested(nested, derivedPredicates);
|
||||
};
|
||||
|
||||
for (auto &argument : and_->arguments)
|
||||
{
|
||||
auto normalizedArgument = argument.match(handleAtomicFormula, handleNot, handleNested);
|
||||
|
||||
arguments.emplace_back(std::move(normalizedArgument));
|
||||
}
|
||||
|
||||
return std::make_unique<normalizedAST::And<normalizedAST::Literal>>(std::move(arguments));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::Literal normalizeTopLevel(ast::ExistsPointer<ast::Precondition> &exists, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
|
||||
{
|
||||
return normalizeNested(exists, derivedPredicates);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::Literal normalizeTopLevel(ast::ForAllPointer<ast::Precondition> &, normalizedAST::DerivedPredicateDeclarations &)
|
||||
{
|
||||
throw std::logic_error("precondition not in normal form (forall), please report to the bug tracker");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::Literal normalizeTopLevel(ast::ImplyPointer<ast::Precondition> &, normalizedAST::DerivedPredicateDeclarations &)
|
||||
{
|
||||
throw std::logic_error("precondition not in normal form (imply), please report to the bug tracker");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Normalize top-level negations
|
||||
normalizedAST::NotPointer<normalizedAST::AtomicFormula> normalizeTopLevel(ast::NotPointer<ast::Precondition> ¬_, 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));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: refactor to avoid code duplication
|
||||
normalizedAST::OrPointer<normalizedAST::Literal> normalizeTopLevel(ast::OrPointer<ast::Precondition> &or_, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
|
||||
{
|
||||
normalizedAST::Or<normalizedAST::Literal>::Arguments arguments;
|
||||
|
||||
arguments.reserve(or_->arguments.size());
|
||||
|
||||
const auto handleAtomicFormula =
|
||||
[&](ast::AtomicFormula &atomicFormula) -> normalizedAST::Literal
|
||||
{
|
||||
return normalize(std::move(atomicFormula));
|
||||
};
|
||||
|
||||
const auto handleNot =
|
||||
[&](ast::NotPointer<ast::Precondition> ¬_) -> normalizedAST::Literal
|
||||
{
|
||||
return normalizeTopLevel(not_, derivedPredicates);
|
||||
};
|
||||
|
||||
const auto handleNested =
|
||||
[&](auto &nested) -> normalizedAST::Literal
|
||||
{
|
||||
return normalizeNested(nested, derivedPredicates);
|
||||
};
|
||||
|
||||
for (auto &argument : or_->arguments)
|
||||
{
|
||||
auto normalizedArgument = argument.match(handleAtomicFormula, handleNot, handleNested);
|
||||
|
||||
arguments.emplace_back(std::move(normalizedArgument));
|
||||
}
|
||||
|
||||
return std::make_unique<normalizedAST::Or<normalizedAST::Literal>>(std::move(arguments));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
normalizedAST::Precondition normalize(ast::Precondition &&precondition, normalizedAST::DerivedPredicateDeclarations &derivedPredicates)
|
||||
{
|
||||
// Bring precondition to normal form
|
||||
reduce(precondition);
|
||||
|
||||
const auto handleAtomicFormula =
|
||||
[&](ast::AtomicFormula &atomicFormula) -> normalizedAST::Precondition
|
||||
{
|
||||
return normalizeTopLevel(atomicFormula, derivedPredicates);
|
||||
};
|
||||
|
||||
const auto handleAnd =
|
||||
[&](ast::AndPointer<ast::Precondition> &and_) -> normalizedAST::Precondition
|
||||
{
|
||||
return normalizeTopLevel(and_, derivedPredicates);
|
||||
};
|
||||
|
||||
const auto handleExists =
|
||||
[&](ast::ExistsPointer<ast::Precondition> &exists) -> normalizedAST::Precondition
|
||||
{
|
||||
return normalizeTopLevel(exists, derivedPredicates);
|
||||
};
|
||||
|
||||
const auto handleForAll =
|
||||
[&](ast::ForAllPointer<ast::Precondition> &forAll) -> normalizedAST::Precondition
|
||||
{
|
||||
return normalizeTopLevel(forAll, derivedPredicates);
|
||||
};
|
||||
|
||||
const auto handleImply =
|
||||
[&](ast::ImplyPointer<ast::Precondition> &imply) -> normalizedAST::Precondition
|
||||
{
|
||||
return normalizeTopLevel(imply, derivedPredicates);
|
||||
};
|
||||
|
||||
const auto handleNot =
|
||||
[&](ast::NotPointer<ast::Precondition> ¬_) -> normalizedAST::Precondition
|
||||
{
|
||||
return normalizeTopLevel(not_, derivedPredicates);
|
||||
};
|
||||
|
||||
const auto handleOr =
|
||||
[&](ast::OrPointer<ast::Precondition> &or_) -> normalizedAST::Precondition
|
||||
{
|
||||
return normalizeNested(or_, derivedPredicates);
|
||||
};
|
||||
|
||||
return precondition.match(handleAtomicFormula, handleAnd, handleExists, handleForAll, handleImply, handleNot, handleOr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
36
lib/pddl/src/pddl/detail/normalization/Problem.cpp
Normal file
36
lib/pddl/src/pddl/detail/normalization/Problem.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <pddl/detail/normalization/Problem.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/NormalizedAST.h>
|
||||
#include <pddl/detail/normalization/InitialState.h>
|
||||
#include <pddl/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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
287
lib/pddl/src/pddl/detail/normalization/Reduction.cpp
Normal file
287
lib/pddl/src/pddl/detail/normalization/Reduction.cpp
Normal file
@@ -0,0 +1,287 @@
|
||||
#include <pddl/detail/normalization/Reduction.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/NormalizedAST.h>
|
||||
#include <pddl/detail/normalization/AtomicFormula.h>
|
||||
#include <pddl/detail/normalization/CollectFreeVariables.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Reduction
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Forward declarations
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void eliminateImply(ast::Precondition &precondition);
|
||||
void negationNormalize(ast::Precondition &precondition);
|
||||
void eliminateForAll(ast::Precondition &precondition);
|
||||
void eliminateDoubleNegations(ast::Precondition &precondition);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void eliminateImply(ast::Precondition &precondition)
|
||||
{
|
||||
const auto handleAtomicFormula =
|
||||
[](ast::AtomicFormula &)
|
||||
{
|
||||
};
|
||||
|
||||
const auto handleAnd =
|
||||
[](ast::AndPointer<ast::Precondition> &and_)
|
||||
{
|
||||
for (auto &argument : and_->arguments)
|
||||
eliminateImply(argument);
|
||||
};
|
||||
|
||||
const auto handleExists =
|
||||
[](ast::ExistsPointer<ast::Precondition> &exists)
|
||||
{
|
||||
eliminateImply(exists->argument);
|
||||
};
|
||||
|
||||
const auto handleForAll =
|
||||
[](ast::ForAllPointer<ast::Precondition> &forAll)
|
||||
{
|
||||
eliminateImply(forAll->argument);
|
||||
};
|
||||
|
||||
const auto handleImply =
|
||||
[&](ast::ImplyPointer<ast::Precondition> &imply)
|
||||
{
|
||||
eliminateImply(imply->argumentLeft);
|
||||
eliminateImply(imply->argumentRight);
|
||||
|
||||
ast::Or<ast::Precondition>::Arguments arguments;
|
||||
arguments.reserve(2);
|
||||
arguments.emplace_back(std::make_unique<ast::Not<ast::Precondition>>(std::move(imply->argumentLeft)));
|
||||
arguments.emplace_back(std::move(imply->argumentRight));
|
||||
|
||||
precondition = std::make_unique<ast::Or<ast::Precondition>>(std::move(arguments));
|
||||
};
|
||||
|
||||
const auto handleNot =
|
||||
[](ast::NotPointer<ast::Precondition> ¬_)
|
||||
{
|
||||
eliminateImply(not_->argument);
|
||||
};
|
||||
|
||||
const auto handleOr =
|
||||
[](ast::OrPointer<ast::Precondition> &or_)
|
||||
{
|
||||
for (auto &argument : or_->arguments)
|
||||
eliminateImply(argument);
|
||||
};
|
||||
|
||||
precondition.match(handleAtomicFormula, handleAnd, handleExists, handleForAll, handleImply, handleNot, handleOr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void eliminateForAll(ast::Precondition &precondition)
|
||||
{
|
||||
const auto handleAtomicFormula =
|
||||
[](ast::AtomicFormula &)
|
||||
{
|
||||
};
|
||||
|
||||
const auto handleAnd =
|
||||
[](ast::AndPointer<ast::Precondition> &and_)
|
||||
{
|
||||
for (auto &argument : and_->arguments)
|
||||
eliminateForAll(argument);
|
||||
};
|
||||
|
||||
const auto handleExists =
|
||||
[](ast::ExistsPointer<ast::Precondition> &exists)
|
||||
{
|
||||
eliminateForAll(exists->argument);
|
||||
};
|
||||
|
||||
const auto handleForAll =
|
||||
[&](ast::ForAllPointer<ast::Precondition> &forAll)
|
||||
{
|
||||
eliminateForAll(forAll->argument);
|
||||
|
||||
auto negatedArgument = std::make_unique<ast::Not<ast::Precondition>>(std::move(forAll->argument));
|
||||
auto exists = std::make_unique<ast::Exists<ast::Precondition>>(std::move(forAll->parameters), std::move(negatedArgument));
|
||||
precondition = std::make_unique<ast::Not<ast::Precondition>>(std::move(exists));
|
||||
};
|
||||
|
||||
const auto handleImply =
|
||||
[&](ast::ImplyPointer<ast::Precondition> &imply)
|
||||
{
|
||||
eliminateForAll(imply->argumentLeft);
|
||||
eliminateForAll(imply->argumentRight);
|
||||
};
|
||||
|
||||
const auto handleNot =
|
||||
[](ast::NotPointer<ast::Precondition> ¬_)
|
||||
{
|
||||
eliminateForAll(not_->argument);
|
||||
};
|
||||
|
||||
const auto handleOr =
|
||||
[](ast::OrPointer<ast::Precondition> &or_)
|
||||
{
|
||||
for (auto &argument : or_->arguments)
|
||||
eliminateForAll(argument);
|
||||
};
|
||||
|
||||
precondition.match(handleAtomicFormula, handleAnd, handleExists, handleForAll, handleImply, handleNot, handleOr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void reduce(ast::Precondition &precondition)
|
||||
{
|
||||
// Replace “imply” statements with disjunctions
|
||||
eliminateImply(precondition);
|
||||
|
||||
// Eliminate “forall” statements
|
||||
eliminateForAll(precondition);
|
||||
|
||||
// Negation-normalize the precondition
|
||||
negationNormalize(precondition);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
194
lib/pddl/src/pddl/detail/parsing/Action.cpp
Normal file
194
lib/pddl/src/pddl/detail/parsing/Action.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
#include <pddl/detail/parsing/Action.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/detail/ASTContext.h>
|
||||
#include <pddl/detail/VariableStack.h>
|
||||
#include <pddl/detail/parsing/Effect.h>
|
||||
#include <pddl/detail/parsing/Precondition.h>
|
||||
#include <pddl/detail/parsing/Utils.h>
|
||||
#include <pddl/detail/parsing/VariableDeclaration.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Action
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ActionParser::ActionParser(Context &context, ast::Domain &domain)
|
||||
: m_context{context},
|
||||
m_domain{domain},
|
||||
m_parametersPosition{tokenize::InvalidStreamPosition},
|
||||
m_preconditionPosition{tokenize::InvalidStreamPosition},
|
||||
m_effectPosition{tokenize::InvalidStreamPosition},
|
||||
m_varsPosition{tokenize::InvalidStreamPosition}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::ActionPointer ActionParser::parse()
|
||||
{
|
||||
auto action = std::make_unique<ast::Action>();
|
||||
|
||||
findSections(*action);
|
||||
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
if (m_parametersPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_parametersPosition);
|
||||
parseParameterSection(*action);
|
||||
}
|
||||
|
||||
// For compatibility with old PDDL versions, vars sections are parsed in addition to parameters
|
||||
if (m_varsPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_varsPosition);
|
||||
parseVarsSection(*action);
|
||||
}
|
||||
|
||||
if (m_preconditionPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_preconditionPosition);
|
||||
parsePreconditionSection(*action);
|
||||
}
|
||||
|
||||
if (m_effectPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_effectPosition);
|
||||
parseEffectSection(*action);
|
||||
}
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ActionParser::findSections(ast::Action &action)
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("action");
|
||||
|
||||
action.name = tokenizer.getIdentifier();
|
||||
|
||||
// TODO: rename parameters appropriately
|
||||
const auto setSectionPosition =
|
||||
[&](const std::string §ionName, auto §ionPosition, const auto value, bool unique = false)
|
||||
{
|
||||
if (unique && sectionPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(value);
|
||||
throw ParserException(tokenizer.location(), "only one “:" + sectionName + "” section allowed");
|
||||
}
|
||||
|
||||
sectionPosition = value;
|
||||
};
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
tokenizer.expect<std::string>(":");
|
||||
|
||||
if (tokenizer.testIdentifierAndSkip("parameters"))
|
||||
setSectionPosition("parameters", m_parametersPosition, position, true);
|
||||
else if (tokenizer.testIdentifierAndSkip("precondition"))
|
||||
setSectionPosition("precondition", m_preconditionPosition, position, true);
|
||||
else if (tokenizer.testIdentifierAndSkip("effect"))
|
||||
setSectionPosition("effect", m_effectPosition, position, true);
|
||||
else if (m_context.mode == Mode::Compatibility && tokenizer.testIdentifierAndSkip("vars"))
|
||||
setSectionPosition("vars", m_varsPosition, position, true);
|
||||
else
|
||||
{
|
||||
const auto sectionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.seek(position);
|
||||
throw ParserException(tokenizer.location(), "unknown action section “" + sectionIdentifier + "”");
|
||||
}
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
|
||||
// Skip section for now and parse it later
|
||||
skipSection(tokenizer);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ActionParser::parseParameterSection(ast::Action &action)
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>(":parameters");
|
||||
tokenizer.expect<std::string>("(");
|
||||
|
||||
parseAndAddVariableDeclarations(m_context, m_domain, action.parameters);
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ActionParser::parsePreconditionSection(ast::Action &action)
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>(":precondition");
|
||||
|
||||
ASTContext astContext(m_domain);
|
||||
VariableStack variableStack;
|
||||
variableStack.push(&action.parameters);
|
||||
|
||||
action.precondition = parsePrecondition(m_context, astContext, variableStack);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ActionParser::parseEffectSection(ast::Action &action)
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>(":effect");
|
||||
|
||||
ASTContext astContext(m_domain);
|
||||
VariableStack variableStack;
|
||||
variableStack.push(&action.parameters);
|
||||
|
||||
action.effect = parseEffect(m_context, astContext, variableStack);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ActionParser::parseVarsSection(ast::Action &action)
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>(":vars");
|
||||
tokenizer.expect<std::string>("(");
|
||||
|
||||
m_context.warningCallback(tokenizer.location(), "“vars” section is not part of the PDDL 3.1 specification, treating it like additional “parameters” section");
|
||||
|
||||
parseAndAddVariableDeclarations(m_context, m_domain, action.parameters);
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
40
lib/pddl/src/pddl/detail/parsing/AtomicFormula.cpp
Normal file
40
lib/pddl/src/pddl/detail/parsing/AtomicFormula.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#include <pddl/detail/parsing/AtomicFormula.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/detail/parsing/Predicate.h>
|
||||
#include <pddl/detail/parsing/Unsupported.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AtomicFormula
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::AtomicFormula> parseAtomicFormula(Context &context, ASTContext &astContext, VariableStack &variableStack)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
// Test unsupported expressions first
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
if (tokenizer.testIdentifierAndReturn("="))
|
||||
throw exceptUnsupportedExpression(position, context);
|
||||
|
||||
tokenizer.seek(position);
|
||||
|
||||
// Now, test supported expressions
|
||||
return parsePredicate(context, astContext, variableStack);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
84
lib/pddl/src/pddl/detail/parsing/Constant.cpp
Normal file
84
lib/pddl/src/pddl/detail/parsing/Constant.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#include <pddl/detail/parsing/Constant.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Exception.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constant
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::ConstantPointer> findConstant(const std::string &constantName, ast::ConstantDeclarations &constantDeclarations)
|
||||
{
|
||||
const auto matchingConstant = std::find_if(constantDeclarations.begin(), constantDeclarations.end(),
|
||||
[&](const auto &constantDeclaration)
|
||||
{
|
||||
return constantDeclaration->name == constantName;
|
||||
});
|
||||
|
||||
if (matchingConstant == constantDeclarations.end())
|
||||
return std::experimental::nullopt;
|
||||
|
||||
return std::make_unique<ast::Constant>(matchingConstant->get());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::ConstantPointer> findConstant(const std::string &constantName, ASTContext &astContext)
|
||||
{
|
||||
auto constant = findConstant(constantName, astContext.domain->constants);
|
||||
|
||||
if (constant)
|
||||
return std::move(constant.value());
|
||||
|
||||
if (astContext.problem)
|
||||
{
|
||||
constant = findConstant(constantName, astContext.problem.value()->objects);
|
||||
|
||||
if (constant)
|
||||
return std::move(constant.value());
|
||||
}
|
||||
|
||||
return std::experimental::nullopt;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::ConstantPointer> testParsingConstant(Context &context, ASTContext &astContext)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
const auto constantName = tokenizer.getIdentifier();
|
||||
auto constant = findConstant(constantName, astContext);
|
||||
|
||||
if (!constant)
|
||||
return std::experimental::nullopt;
|
||||
|
||||
return std::move(constant.value());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::ConstantPointer parseConstant(Context &context, ASTContext &astContext)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
const auto constantName = tokenizer.getIdentifier();
|
||||
auto constant = findConstant(constantName, astContext);
|
||||
|
||||
if (!constant)
|
||||
throw ParserException(tokenizer.location(), "undeclared constant “" + constantName + "”");
|
||||
|
||||
return std::move(constant.value());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
83
lib/pddl/src/pddl/detail/parsing/ConstantDeclaration.cpp
Normal file
83
lib/pddl/src/pddl/detail/parsing/ConstantDeclaration.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#include <pddl/detail/parsing/ConstantDeclaration.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/detail/ASTCopy.h>
|
||||
#include <pddl/detail/parsing/PrimitiveType.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ConstantDeclaration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void parseAndAddUntypedConstantDeclaration(Context &context, ast::ConstantDeclarations &constantDeclarations)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
auto constantName = tokenizer.getIdentifier();
|
||||
assert(constantName != "-");
|
||||
|
||||
constantDeclarations.emplace_back(std::make_unique<ast::ConstantDeclaration>(std::move(constantName)));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void parseAndAddConstantDeclarations(Context &context, ast::Domain &domain, ast::ConstantDeclarations &constantDeclarations)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Index on the first element of the current inheritance list
|
||||
size_t inheritanceIndex = constantDeclarations.size();
|
||||
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
parseAndAddUntypedConstantDeclaration(context, constantDeclarations);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
if (!tokenizer.testAndSkip<char>('-'))
|
||||
continue;
|
||||
|
||||
// If existing, parse and store parent type
|
||||
auto parentType = parsePrimitiveType(context, domain);
|
||||
|
||||
for (size_t i = inheritanceIndex; i < constantDeclarations.size(); i++)
|
||||
constantDeclarations[i]->type = ast::deepCopy(parentType);
|
||||
|
||||
// All types up to now are labeled with their parent types
|
||||
inheritanceIndex = constantDeclarations.size();
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
const bool isTypingUsed = !domain.types.empty();
|
||||
|
||||
if (isTypingUsed && !constantDeclarations.empty() && !constantDeclarations.back()->type)
|
||||
throw ParserException(tokenizer.location(), "missing type declaration for constant “" + constantDeclarations.back()->name + "”");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void parseAndAddConstantDeclarations(Context &context, ast::Domain &domain)
|
||||
{
|
||||
parseAndAddConstantDeclarations(context, domain, domain.constants);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void parseAndAddConstantDeclarations(Context &context, ast::Problem &problem)
|
||||
{
|
||||
parseAndAddConstantDeclarations(context, *problem.domain, problem.objects);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
118
lib/pddl/src/pddl/detail/parsing/Description.cpp
Normal file
118
lib/pddl/src/pddl/detail/parsing/Description.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
#include <pddl/detail/parsing/Description.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/detail/parsing/Domain.h>
|
||||
#include <pddl/detail/parsing/Problem.h>
|
||||
#include <pddl/detail/parsing/Utils.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Description
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DescriptionParser::DescriptionParser(Context &context)
|
||||
: m_context{context},
|
||||
m_domainPosition{tokenize::InvalidStreamPosition},
|
||||
m_problemPosition{tokenize::InvalidStreamPosition}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::Description DescriptionParser::parse()
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
tokenizer.removeComments(";", "\n", false);
|
||||
|
||||
findSections();
|
||||
|
||||
if (m_domainPosition == tokenize::InvalidStreamPosition)
|
||||
throw ParserException("no PDDL domain specified");
|
||||
|
||||
tokenizer.seek(m_domainPosition);
|
||||
|
||||
auto domain = DomainParser(m_context).parse();
|
||||
|
||||
// If no problem is given, return just the domain
|
||||
if (m_problemPosition == tokenize::InvalidStreamPosition)
|
||||
return {std::move(domain), std::experimental::nullopt};
|
||||
|
||||
tokenizer.seek(m_problemPosition);
|
||||
|
||||
auto problem = ProblemParser(m_context, *domain).parse();
|
||||
|
||||
// TODO: check consistency
|
||||
// * check typing requirement
|
||||
// * check that typing is used consistently
|
||||
// * check that constants/objects, variables, and predicates aren't declared twice
|
||||
// * check section order
|
||||
// * check that preconditions and effects are well-formed
|
||||
return {std::move(domain), std::move(problem)};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DescriptionParser::findSections()
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
while (!tokenizer.atEnd())
|
||||
{
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
|
||||
if (m_context.mode == Mode::Compatibility && tokenizer.testAndReturn<std::string>("in-package"))
|
||||
{
|
||||
m_context.warningCallback(tokenizer.location(), "“in-package” section is not part of the PDDL 3.1 specification, ignoring section");
|
||||
|
||||
skipSection(tokenizer);
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
tokenizer.expect<std::string>("define");
|
||||
tokenizer.expect<std::string>("(");
|
||||
|
||||
if (tokenizer.testAndSkip<std::string>("domain"))
|
||||
{
|
||||
if (m_domainPosition != tokenize::InvalidStreamPosition)
|
||||
throw ParserException(tokenizer.location(), "PDDL description may not contain two domains");
|
||||
|
||||
m_domainPosition = position;
|
||||
skipSection(tokenizer);
|
||||
skipSection(tokenizer);
|
||||
}
|
||||
else if (m_context.tokenizer.testAndSkip<std::string>("problem"))
|
||||
{
|
||||
if (m_problemPosition != tokenize::InvalidStreamPosition)
|
||||
throw ParserException("PDDL description may not contain two problems currently");
|
||||
|
||||
m_problemPosition = position;
|
||||
skipSection(tokenizer);
|
||||
skipSection(tokenizer);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto sectionIdentifier = tokenizer.get<std::string>();
|
||||
throw ParserException(tokenizer.location(), "unknown PDDL section “" + sectionIdentifier + "”");
|
||||
}
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
296
lib/pddl/src/pddl/detail/parsing/Domain.cpp
Normal file
296
lib/pddl/src/pddl/detail/parsing/Domain.cpp
Normal file
@@ -0,0 +1,296 @@
|
||||
#include <pddl/detail/parsing/Domain.h>
|
||||
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/detail/Requirements.h>
|
||||
#include <pddl/detail/parsing/Action.h>
|
||||
#include <pddl/detail/parsing/ConstantDeclaration.h>
|
||||
#include <pddl/detail/parsing/PredicateDeclaration.h>
|
||||
#include <pddl/detail/parsing/PrimitiveTypeDeclaration.h>
|
||||
#include <pddl/detail/parsing/Requirement.h>
|
||||
#include <pddl/detail/parsing/Unsupported.h>
|
||||
#include <pddl/detail/parsing/Utils.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Domain
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DomainParser::DomainParser(Context &context)
|
||||
: m_context{context},
|
||||
m_requirementsPosition{tokenize::InvalidStreamPosition},
|
||||
m_typesPosition{tokenize::InvalidStreamPosition},
|
||||
m_constantsPosition{tokenize::InvalidStreamPosition},
|
||||
m_predicatesPosition{tokenize::InvalidStreamPosition}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::DomainPointer DomainParser::parse()
|
||||
{
|
||||
auto domain = std::make_unique<ast::Domain>();
|
||||
|
||||
findSections(*domain);
|
||||
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
if (m_requirementsPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_requirementsPosition);
|
||||
parseRequirementSection(*domain);
|
||||
}
|
||||
|
||||
if (m_typesPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_typesPosition);
|
||||
parseTypeSection(*domain);
|
||||
}
|
||||
|
||||
if (m_constantsPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_constantsPosition);
|
||||
parseConstantSection(*domain);
|
||||
}
|
||||
|
||||
if (m_predicatesPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_predicatesPosition);
|
||||
parsePredicateSection(*domain);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_actionPositions.size(); i++)
|
||||
if (m_actionPositions[i] != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_actionPositions[i]);
|
||||
parseActionSection(*domain);
|
||||
}
|
||||
|
||||
computeDerivedRequirements(*domain);
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DomainParser::findSections(ast::Domain &domain)
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>("define");
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>("domain");
|
||||
|
||||
domain.name = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
const auto setSectionPosition =
|
||||
[&](const std::string §ionName, auto §ionPosition, const auto value, bool unique = false)
|
||||
{
|
||||
if (unique && sectionPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(value);
|
||||
throw ParserException(tokenizer.location(), "only one “:" + sectionName + "” section allowed");
|
||||
}
|
||||
|
||||
sectionPosition = value;
|
||||
};
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Find sections
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
|
||||
// Save the parser position of the individual sections for later parsing
|
||||
if (tokenizer.testIdentifierAndSkip("requirements"))
|
||||
setSectionPosition("requirements", m_requirementsPosition, position, true);
|
||||
else if (tokenizer.testIdentifierAndSkip("types"))
|
||||
setSectionPosition("types", m_typesPosition, position, true);
|
||||
else if (tokenizer.testIdentifierAndSkip("constants"))
|
||||
setSectionPosition("constants", m_constantsPosition, position, true);
|
||||
else if (tokenizer.testIdentifierAndSkip("predicates"))
|
||||
setSectionPosition("predicates", m_predicatesPosition, position, true);
|
||||
else if (tokenizer.testIdentifierAndSkip("action"))
|
||||
{
|
||||
m_actionPositions.emplace_back(tokenize::InvalidStreamPosition);
|
||||
setSectionPosition("action", m_actionPositions.back(), position);
|
||||
}
|
||||
else if (tokenizer.testIdentifierAndSkip("functions")
|
||||
|| tokenizer.testIdentifierAndSkip("constraints")
|
||||
|| tokenizer.testIdentifierAndSkip("durative-action")
|
||||
|| tokenizer.testIdentifierAndSkip("derived"))
|
||||
{
|
||||
throw exceptUnsupportedSection(position, m_context);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto sectionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.seek(position);
|
||||
throw ParserException(tokenizer.location(), "unknown domain section “" + sectionIdentifier + "”");
|
||||
}
|
||||
|
||||
// Skip section for now and parse it later
|
||||
skipSection(tokenizer);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DomainParser::parseRequirementSection(ast::Domain &domain)
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("requirements");
|
||||
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
tokenizer.expect<std::string>(":");
|
||||
|
||||
const auto requirement = parseRequirement(m_context);
|
||||
|
||||
if (requirement)
|
||||
domain.requirements.emplace_back(requirement.value());
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
// TODO: do this check only once the problem is parsed
|
||||
// If no requirements are specified, assume STRIPS
|
||||
if (domain.requirements.empty())
|
||||
domain.requirements.emplace_back(ast::Requirement::STRIPS);
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DomainParser::computeDerivedRequirements(ast::Domain &domain)
|
||||
{
|
||||
const auto addRequirementUnique =
|
||||
[&](auto requirement)
|
||||
{
|
||||
if (hasRequirement(domain, requirement))
|
||||
return;
|
||||
|
||||
domain.requirements.push_back(requirement);
|
||||
};
|
||||
|
||||
if (hasRequirement(domain, ast::Requirement::ADL))
|
||||
{
|
||||
addRequirementUnique(ast::Requirement::STRIPS);
|
||||
addRequirementUnique(ast::Requirement::Typing);
|
||||
addRequirementUnique(ast::Requirement::NegativePreconditions);
|
||||
addRequirementUnique(ast::Requirement::DisjunctivePreconditions);
|
||||
addRequirementUnique(ast::Requirement::Equality);
|
||||
addRequirementUnique(ast::Requirement::QuantifiedPreconditions);
|
||||
addRequirementUnique(ast::Requirement::ConditionalEffects);
|
||||
}
|
||||
|
||||
if (hasRequirement(domain, ast::Requirement::QuantifiedPreconditions))
|
||||
{
|
||||
addRequirementUnique(ast::Requirement::ExistentialPreconditions);
|
||||
addRequirementUnique(ast::Requirement::UniversalPreconditions);
|
||||
}
|
||||
|
||||
if (hasRequirement(domain, ast::Requirement::Fluents))
|
||||
{
|
||||
addRequirementUnique(ast::Requirement::NumericFluents);
|
||||
addRequirementUnique(ast::Requirement::ObjectFluents);
|
||||
}
|
||||
|
||||
if (hasRequirement(domain, ast::Requirement::TimedInitialLiterals))
|
||||
addRequirementUnique(ast::Requirement::DurativeActions);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DomainParser::parseTypeSection(ast::Domain &domain)
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("types");
|
||||
|
||||
checkRequirement(domain, ast::Requirement::Typing, m_context);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Store types and their parent types
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
if (tokenizer.currentCharacter() == '(')
|
||||
throw ParserException(tokenizer.location(), "only primitive types are allowed in type section");
|
||||
|
||||
parseAndAddPrimitiveTypeDeclarations(m_context, domain);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DomainParser::parseConstantSection(ast::Domain &domain)
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("constants");
|
||||
|
||||
// Store constants
|
||||
parseAndAddConstantDeclarations(m_context, domain);
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DomainParser::parsePredicateSection(ast::Domain &domain)
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("predicates");
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Store predicates
|
||||
parseAndAddPredicateDeclarations(m_context, domain);
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DomainParser::parseActionSection(ast::Domain &domain)
|
||||
{
|
||||
domain.actions.emplace_back(ActionParser(m_context, domain).parse());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
151
lib/pddl/src/pddl/detail/parsing/Effect.cpp
Normal file
151
lib/pddl/src/pddl/detail/parsing/Effect.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
#include <pddl/detail/parsing/Effect.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/detail/parsing/AtomicFormula.h>
|
||||
#include <pddl/detail/parsing/Expressions.h>
|
||||
#include <pddl/detail/parsing/Precondition.h>
|
||||
#include <pddl/detail/parsing/Unsupported.h>
|
||||
#include <pddl/detail/parsing/Utils.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Effect
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::Effect> parseEffectBody(Context &context, ASTContext &astContext, VariableStack &variableStack);
|
||||
std::experimental::optional<ast::ConditionalEffect> parseConditionalEffect(Context &context, ASTContext &astContext, VariableStack &variableStack);
|
||||
std::experimental::optional<ast::Literal> parseConditionalEffectBody(Context &context, ASTContext &astContext, VariableStack &variableStack);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::Effect> parseEffect(Context &context, ASTContext &astContext, VariableStack &variableStack)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
std::experimental::optional<ast::Effect> effect;
|
||||
|
||||
if ((effect = parseAnd<ast::Effect>(context, astContext, variableStack, parseEffect))
|
||||
|| (effect = parseForAll<ast::Effect>(context, astContext, variableStack, parseEffect))
|
||||
|| (effect = parseWhen<ast::Precondition, ast::ConditionalEffect>(context, astContext, variableStack, parsePreconditionBody, parseConditionalEffect)))
|
||||
{
|
||||
return std::move(effect.value());
|
||||
}
|
||||
|
||||
return parseEffectBody(context, astContext, variableStack);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::Effect> parseEffectBody(Context &context, ASTContext &astContext, VariableStack &variableStack)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Test unsupported expressions first
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
const auto expressionIdentifierPosition = tokenizer.position();
|
||||
|
||||
if (tokenizer.testIdentifierAndReturn("assign")
|
||||
|| tokenizer.testIdentifierAndReturn("scale-up")
|
||||
|| tokenizer.testIdentifierAndReturn("scale-down")
|
||||
|| tokenizer.testIdentifierAndReturn("increase")
|
||||
|| tokenizer.testIdentifierAndReturn("decrease"))
|
||||
{
|
||||
throw exceptUnsupportedExpression(position, context);
|
||||
}
|
||||
|
||||
tokenizer.seek(position);
|
||||
|
||||
// Now, test supported expressions
|
||||
std::experimental::optional<ast::Effect> effect;
|
||||
|
||||
if ((effect = parseNot<ast::AtomicFormula>(context, astContext, variableStack, parseAtomicFormula))
|
||||
|| (effect = parseAtomicFormula(context, astContext, variableStack)))
|
||||
{
|
||||
return std::move(effect.value());
|
||||
}
|
||||
|
||||
tokenizer.seek(expressionIdentifierPosition);
|
||||
const auto expressionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.seek(position);
|
||||
throw ParserException(tokenizer.location(), "expression type “" + expressionIdentifier + "” unknown or not allowed in effect body");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::ConditionalEffect> parseConditionalEffect(Context &context, ASTContext &astContext, VariableStack &variableStack)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
std::experimental::optional<ast::ConditionalEffect> conditionalEffect;
|
||||
|
||||
if ((conditionalEffect = parseAnd<ast::Literal>(context, astContext, variableStack, parseConditionalEffectBody)))
|
||||
return std::move(conditionalEffect.value());
|
||||
|
||||
return parseConditionalEffectBody(context, astContext, variableStack);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::Literal> parseConditionalEffectBody(Context &context, ASTContext &astContext, VariableStack &variableStack)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Test unsupported expressions first
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
const auto expressionIdentifierPosition = tokenizer.position();
|
||||
|
||||
if (tokenizer.testIdentifierAndReturn("=")
|
||||
|| tokenizer.testIdentifierAndReturn("assign")
|
||||
|| tokenizer.testIdentifierAndReturn("scale-up")
|
||||
|| tokenizer.testIdentifierAndReturn("scale-down")
|
||||
|| tokenizer.testIdentifierAndReturn("increase")
|
||||
|| tokenizer.testIdentifierAndReturn("decrease"))
|
||||
{
|
||||
throw exceptUnsupportedExpression(position, context);
|
||||
}
|
||||
|
||||
tokenizer.seek(position);
|
||||
|
||||
// Now, test supported expressions
|
||||
std::experimental::optional<ast::Literal> literal;
|
||||
|
||||
if ((literal = parseNot<ast::AtomicFormula>(context, astContext, variableStack, parseAtomicFormula))
|
||||
|| (literal = parseAtomicFormula(context, astContext, variableStack)))
|
||||
{
|
||||
return std::move(literal.value());
|
||||
}
|
||||
|
||||
tokenizer.seek(expressionIdentifierPosition);
|
||||
const auto expressionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.seek(position);
|
||||
throw ParserException(tokenizer.location(), "expression type “" + expressionIdentifier + "” unknown or not allowed in conditional effect body");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
54
lib/pddl/src/pddl/detail/parsing/Fact.cpp
Normal file
54
lib/pddl/src/pddl/detail/parsing/Fact.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include <pddl/detail/parsing/Fact.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/detail/parsing/AtomicFormula.h>
|
||||
#include <pddl/detail/parsing/Expressions.h>
|
||||
#include <pddl/detail/parsing/Unsupported.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Fact
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::Fact> parseFact(Context &context, ASTContext &astContext, VariableStack &variableStack)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
// Test unsupported expressions first
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
if (tokenizer.testIdentifierAndReturn("="))
|
||||
throw exceptUnsupportedExpression(position, context);
|
||||
|
||||
tokenizer.seek(position);
|
||||
|
||||
// Now, test supported expressions
|
||||
std::experimental::optional<ast::Fact> fact;
|
||||
|
||||
if ((fact = parseNot<ast::AtomicFormula>(context, astContext, variableStack, parseAtomicFormula))
|
||||
|| (fact = parseAtomicFormula(context, astContext, variableStack)))
|
||||
{
|
||||
return std::move(fact.value());
|
||||
}
|
||||
|
||||
// Test for “at” expressions only now to allow “at” as a predicate name
|
||||
// TODO: allow this in compatibility mode only?
|
||||
if (tokenizer.testIdentifierAndReturn("at"))
|
||||
throw exceptUnsupportedExpression(position, context);
|
||||
|
||||
return std::experimental::nullopt;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
44
lib/pddl/src/pddl/detail/parsing/InitialState.cpp
Normal file
44
lib/pddl/src/pddl/detail/parsing/InitialState.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <pddl/detail/parsing/InitialState.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/detail/parsing/Fact.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// InitialState
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::InitialState parseInitialState(Context &context, ASTContext &astContext, VariableStack &variableStack)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
ast::InitialState initialState;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
auto fact = parseFact(context, astContext, variableStack);
|
||||
|
||||
if (!fact)
|
||||
throw ParserException(tokenizer.location(), "invalid initial state fact");
|
||||
|
||||
initialState.facts.emplace_back(std::move(fact.value()));
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
return initialState;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
104
lib/pddl/src/pddl/detail/parsing/Precondition.cpp
Normal file
104
lib/pddl/src/pddl/detail/parsing/Precondition.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
#include <pddl/detail/parsing/Precondition.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/detail/parsing/AtomicFormula.h>
|
||||
#include <pddl/detail/parsing/Expressions.h>
|
||||
#include <pddl/detail/parsing/Unsupported.h>
|
||||
#include <pddl/detail/parsing/Utils.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Precondition
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::Precondition> parsePrecondition(Context &context, ASTContext &astContext, VariableStack &variableStack)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Test unsupported expressions first
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
|
||||
if (tokenizer.testIdentifierAndReturn("preference"))
|
||||
throw exceptUnsupportedExpression(position, context);
|
||||
|
||||
tokenizer.seek(position);
|
||||
|
||||
// Now, test supported expressions
|
||||
std::experimental::optional<ast::Precondition> precondition;
|
||||
|
||||
if ((precondition = parseAnd<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|
||||
|| (precondition = parseForAll<ast::Precondition>(context, astContext, variableStack, parsePrecondition)))
|
||||
{
|
||||
return std::move(precondition.value());
|
||||
}
|
||||
|
||||
tokenizer.seek(position);
|
||||
return parsePreconditionBody(context, astContext, variableStack);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::Precondition> parsePreconditionBody(Context &context, ASTContext &astContext, VariableStack &variableStack)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Test unsupported expressions first
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
const auto expressionIdentifierPosition = tokenizer.position();
|
||||
|
||||
if (tokenizer.testIdentifierAndReturn("-")
|
||||
|| tokenizer.testIdentifierAndReturn("*")
|
||||
|| tokenizer.testIdentifierAndReturn("+")
|
||||
|| tokenizer.testIdentifierAndReturn("-")
|
||||
|| tokenizer.testIdentifierAndReturn("/")
|
||||
|| tokenizer.testIdentifierAndReturn(">")
|
||||
|| tokenizer.testIdentifierAndReturn("<")
|
||||
|| tokenizer.testIdentifierAndReturn(">=")
|
||||
|| tokenizer.testIdentifierAndReturn("<="))
|
||||
{
|
||||
throw exceptUnsupportedExpression(position, context);
|
||||
}
|
||||
|
||||
tokenizer.seek(position);
|
||||
|
||||
// Now, test supported expressions
|
||||
std::experimental::optional<ast::Precondition> precondition;
|
||||
|
||||
if ((precondition = parseAnd<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|
||||
|| (precondition = parseOr<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|
||||
|| (precondition = parseExists<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|
||||
|| (precondition = parseForAll<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|
||||
|| (precondition = parseNot<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|
||||
|| (precondition = parseImply<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|
||||
|| (precondition = parseAtomicFormula(context, astContext, variableStack)))
|
||||
{
|
||||
return std::move(precondition.value());
|
||||
}
|
||||
|
||||
tokenizer.seek(expressionIdentifierPosition);
|
||||
const auto expressionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.seek(position);
|
||||
throw ParserException(tokenizer.location(), "expression type “" + expressionIdentifier + "” unknown or not allowed in precondition body");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
94
lib/pddl/src/pddl/detail/parsing/Predicate.cpp
Normal file
94
lib/pddl/src/pddl/detail/parsing/Predicate.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#include <pddl/detail/parsing/Predicate.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/detail/SignatureMatching.h>
|
||||
#include <pddl/detail/parsing/Constant.h>
|
||||
#include <pddl/detail/parsing/Variable.h>
|
||||
#include <pddl/detail/parsing/VariableDeclaration.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Predicate
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::PredicatePointer> parsePredicate(Context &context, ASTContext &astContext, VariableStack &variableStack)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
const auto previousPosition = tokenizer.position();
|
||||
|
||||
if (!tokenizer.testAndSkip<std::string>("("))
|
||||
{
|
||||
tokenizer.seek(previousPosition);
|
||||
return std::experimental::nullopt;
|
||||
}
|
||||
|
||||
const auto name = tokenizer.getIdentifier();
|
||||
ast::Predicate::Arguments arguments;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Parse arguments
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
// Parse argument if it is a variable
|
||||
auto variable = testParsingVariable(context, variableStack);
|
||||
|
||||
if (variable)
|
||||
{
|
||||
arguments.emplace_back(std::move(variable.value()));
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Parse argument if it is a constant
|
||||
auto constant = testParsingConstant(context, astContext);
|
||||
|
||||
if (constant)
|
||||
{
|
||||
arguments.emplace_back(std::move(constant.value()));
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
continue;
|
||||
}
|
||||
|
||||
// If argument is neither variable nor constant, this is not a valid predicate
|
||||
tokenizer.seek(previousPosition);
|
||||
return std::experimental::nullopt;
|
||||
}
|
||||
|
||||
const auto &predicates = astContext.domain->predicates;
|
||||
|
||||
const auto matchingPredicateDeclaration = std::find_if(predicates.cbegin(), predicates.cend(),
|
||||
[&](const auto &predicateDeclaration)
|
||||
{
|
||||
return matches(name, arguments, *predicateDeclaration);
|
||||
});
|
||||
|
||||
if (matchingPredicateDeclaration == predicates.cend())
|
||||
{
|
||||
// TODO: enumerate candidates and why they are incompatible
|
||||
tokenizer.seek(previousPosition);
|
||||
throw ParserException(tokenizer.location(), "no matching declaration found for predicate “" + name + "”");
|
||||
}
|
||||
|
||||
auto *declaration = matchingPredicateDeclaration->get();
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
return std::make_unique<ast::Predicate>(std::move(arguments), declaration);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
53
lib/pddl/src/pddl/detail/parsing/PredicateDeclaration.cpp
Normal file
53
lib/pddl/src/pddl/detail/parsing/PredicateDeclaration.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#include <pddl/detail/parsing/PredicateDeclaration.h>
|
||||
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/detail/ASTContext.h>
|
||||
#include <pddl/detail/parsing/VariableDeclaration.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PredicateDeclaration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void parseAndAddPredicateDeclaration(Context &context, ast::Domain &domain)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
tokenizer.expect<std::string>("(");
|
||||
|
||||
auto name = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Parse parameters
|
||||
auto parameters = parseVariableDeclarations(context, domain);
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
domain.predicates.emplace_back(std::make_unique<ast::PredicateDeclaration>(std::move(name), std::move(parameters)));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void parseAndAddPredicateDeclarations(Context &context, ast::Domain &domain)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
parseAndAddPredicateDeclaration(context, domain);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
56
lib/pddl/src/pddl/detail/parsing/PrimitiveType.cpp
Normal file
56
lib/pddl/src/pddl/detail/parsing/PrimitiveType.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include <pddl/detail/parsing/PrimitiveType.h>
|
||||
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/detail/Requirements.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PrimitiveType
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::PrimitiveTypePointer parsePrimitiveType(Context &context, ast::Domain &domain)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
auto &types = domain.types;
|
||||
|
||||
auto typeName = tokenizer.getIdentifier();
|
||||
|
||||
if (typeName.empty())
|
||||
throw ParserException(tokenizer.location(), "could not parse primitive type, expected identifier");
|
||||
|
||||
auto matchingType = std::find_if(types.begin(), types.end(),
|
||||
[&](auto &primitiveTypeDeclaration)
|
||||
{
|
||||
return primitiveTypeDeclaration->name == typeName;
|
||||
});
|
||||
|
||||
// If the type has not been declared yet, add it but issue a warning
|
||||
if (matchingType == types.end())
|
||||
{
|
||||
// “object” type is always allowed without warning
|
||||
if (typeName != "object")
|
||||
{
|
||||
if (context.mode != Mode::Compatibility)
|
||||
throw ParserException(tokenizer.location(), "primitive type “" + typeName + "” used without or before declaration");
|
||||
|
||||
context.warningCallback(tokenizer.location(), "primitive type “" + typeName + "” used without or before declaration, silently adding declaration");
|
||||
}
|
||||
|
||||
types.emplace_back(std::make_unique<ast::PrimitiveTypeDeclaration>(std::move(typeName)));
|
||||
|
||||
return std::make_unique<ast::PrimitiveType>(types.back().get());
|
||||
}
|
||||
|
||||
return std::make_unique<ast::PrimitiveType>(matchingType->get());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,93 @@
|
||||
#include <pddl/detail/parsing/PrimitiveTypeDeclaration.h>
|
||||
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/detail/ASTCopy.h>
|
||||
#include <pddl/detail/parsing/PrimitiveType.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PrimitiveTypeDeclaration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::PrimitiveTypeDeclarationPointer *> findPrimitiveTypeDeclaration(ast::Domain &domain, const std::string &typeName)
|
||||
{
|
||||
auto &types = domain.types;
|
||||
|
||||
const auto matchingPrimitiveType = std::find_if(types.begin(), types.end(),
|
||||
[&](const auto &primitiveType)
|
||||
{
|
||||
return primitiveType->name == typeName;
|
||||
});
|
||||
|
||||
if (matchingPrimitiveType != types.end())
|
||||
return &*matchingPrimitiveType;
|
||||
|
||||
return std::experimental::nullopt;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::PrimitiveTypeDeclarationPointer &parseAndAddUntypedPrimitiveTypeDeclaration(Context &context, ast::Domain &domain, std::vector<bool> &flaggedTypes)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
auto typeName = tokenizer.getIdentifier();
|
||||
|
||||
auto &types = domain.types;
|
||||
|
||||
auto matchingPrimitiveTypeDeclaration = findPrimitiveTypeDeclaration(domain, typeName);
|
||||
|
||||
if (matchingPrimitiveTypeDeclaration)
|
||||
return *matchingPrimitiveTypeDeclaration.value();
|
||||
|
||||
types.emplace_back(std::make_unique<ast::PrimitiveTypeDeclaration>(std::move(typeName)));
|
||||
flaggedTypes.emplace_back(false);
|
||||
|
||||
return types.back();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void parseAndAddPrimitiveTypeDeclarations(Context &context, ast::Domain &domain)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
auto &types = domain.types;
|
||||
assert(types.empty());
|
||||
|
||||
std::vector<bool> flaggedTypes;
|
||||
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
auto &childType = parseAndAddUntypedPrimitiveTypeDeclaration(context, domain, flaggedTypes);
|
||||
flaggedTypes[&childType - &types.front()] = true;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
if (!tokenizer.testAndSkip<char>('-'))
|
||||
continue;
|
||||
|
||||
// Skip parent type information for now
|
||||
auto &parentType = parseAndAddUntypedPrimitiveTypeDeclaration(context, domain, flaggedTypes);
|
||||
|
||||
for (size_t i = 0; i < flaggedTypes.size(); i++)
|
||||
if (flaggedTypes[i])
|
||||
{
|
||||
flaggedTypes[i] = false;
|
||||
types[i]->parentTypes.emplace_back(std::make_unique<ast::PrimitiveType>(parentType.get()));
|
||||
}
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
293
lib/pddl/src/pddl/detail/parsing/Problem.cpp
Normal file
293
lib/pddl/src/pddl/detail/parsing/Problem.cpp
Normal file
@@ -0,0 +1,293 @@
|
||||
#include <pddl/detail/parsing/Problem.h>
|
||||
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/detail/Requirements.h>
|
||||
#include <pddl/detail/parsing/ConstantDeclaration.h>
|
||||
#include <pddl/detail/parsing/InitialState.h>
|
||||
#include <pddl/detail/parsing/Precondition.h>
|
||||
#include <pddl/detail/parsing/Requirement.h>
|
||||
#include <pddl/detail/parsing/Unsupported.h>
|
||||
#include <pddl/detail/parsing/Utils.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Problem
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ProblemParser::ProblemParser(Context &context, ast::Domain &domain)
|
||||
: m_context{context},
|
||||
m_domain{domain},
|
||||
m_domainPosition{tokenize::InvalidStreamPosition},
|
||||
m_requirementsPosition{tokenize::InvalidStreamPosition},
|
||||
m_objectsPosition{tokenize::InvalidStreamPosition},
|
||||
m_initialStatePosition{tokenize::InvalidStreamPosition},
|
||||
m_goalPosition{tokenize::InvalidStreamPosition}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::ProblemPointer ProblemParser::parse()
|
||||
{
|
||||
auto problem = std::make_unique<ast::Problem>(&m_domain);
|
||||
|
||||
findSections(*problem);
|
||||
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
if (m_domainPosition == tokenize::InvalidStreamPosition)
|
||||
throw ParserException(tokenizer.location(), "problem description does not specify a corresponding domain");
|
||||
|
||||
tokenizer.seek(m_domainPosition);
|
||||
parseDomainSection(*problem);
|
||||
|
||||
if (m_requirementsPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_requirementsPosition);
|
||||
parseRequirementSection(*problem);
|
||||
}
|
||||
|
||||
if (m_objectsPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_objectsPosition);
|
||||
parseObjectSection(*problem);
|
||||
}
|
||||
|
||||
if (m_initialStatePosition == tokenize::InvalidStreamPosition)
|
||||
throw ParserException(tokenizer.location(), "problem description does not specify an initial state");
|
||||
|
||||
tokenizer.seek(m_initialStatePosition);
|
||||
parseInitialStateSection(*problem);
|
||||
|
||||
if (m_goalPosition == tokenize::InvalidStreamPosition)
|
||||
throw ParserException(tokenizer.location(), "problem description does not specify a goal");
|
||||
|
||||
tokenizer.seek(m_goalPosition);
|
||||
parseGoalSection(*problem);
|
||||
|
||||
return problem;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ProblemParser::findSections(ast::Problem &problem)
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>("define");
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>("problem");
|
||||
|
||||
problem.name = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
const auto setSectionPosition =
|
||||
[&](const std::string §ionName, auto §ionPosition, const auto value, bool unique = false)
|
||||
{
|
||||
if (unique && sectionPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(value);
|
||||
throw ParserException(tokenizer.location(), "only one “:" + sectionName + "” section allowed");
|
||||
}
|
||||
|
||||
sectionPosition = value;
|
||||
};
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
|
||||
if (tokenizer.testIdentifierAndSkip("domain"))
|
||||
setSectionPosition("domain", m_domainPosition, position, true);
|
||||
else if (tokenizer.testIdentifierAndSkip("requirements"))
|
||||
setSectionPosition("requirements", m_requirementsPosition, position, true);
|
||||
else if (tokenizer.testIdentifierAndSkip("objects"))
|
||||
setSectionPosition("objects", m_objectsPosition, position, true);
|
||||
else if (tokenizer.testIdentifierAndSkip("init"))
|
||||
setSectionPosition("init", m_initialStatePosition, position, true);
|
||||
else if (tokenizer.testIdentifierAndSkip("goal"))
|
||||
setSectionPosition("goal", m_goalPosition, position, true);
|
||||
else if (tokenizer.testIdentifierAndSkip("constraints")
|
||||
|| tokenizer.testIdentifierAndSkip("metric")
|
||||
|| tokenizer.testIdentifierAndSkip("length"))
|
||||
{
|
||||
throw exceptUnsupportedSection(position, m_context);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto sectionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.seek(position);
|
||||
throw ParserException(tokenizer.location(), "unknown problem section “" + sectionIdentifier + "”");
|
||||
}
|
||||
|
||||
// Skip section for now and parse it later
|
||||
skipSection(tokenizer);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ProblemParser::parseDomainSection(ast::Problem &problem)
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("domain");
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
const auto domainName = tokenizer.getIdentifier();
|
||||
|
||||
if (problem.domain->name != domainName)
|
||||
throw ParserException(tokenizer.location(), "domains do not match (“" + problem.domain->name + "” and “" + domainName + "”)");
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ProblemParser::parseRequirementSection(ast::Problem &problem)
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("requirements");
|
||||
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
tokenizer.expect<std::string>(":");
|
||||
|
||||
const auto requirement = parseRequirement(m_context);
|
||||
|
||||
if (requirement)
|
||||
problem.requirements.emplace_back(requirement.value());
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
// TODO: do this check only once the problem is parsed
|
||||
// If no requirements are specified, assume STRIPS
|
||||
if (problem.requirements.empty())
|
||||
problem.requirements.emplace_back(ast::Requirement::STRIPS);
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: refactor, exists identically in DomainParser
|
||||
void ProblemParser::computeDerivedRequirements(ast::Problem &problem)
|
||||
{
|
||||
const auto addRequirementUnique =
|
||||
[&](const auto requirement)
|
||||
{
|
||||
if (hasRequirement(problem, requirement))
|
||||
return;
|
||||
|
||||
problem.requirements.push_back(ast::Requirement(requirement));
|
||||
};
|
||||
|
||||
if (hasRequirement(problem, ast::Requirement::ADL))
|
||||
{
|
||||
addRequirementUnique(ast::Requirement::STRIPS);
|
||||
addRequirementUnique(ast::Requirement::Typing);
|
||||
addRequirementUnique(ast::Requirement::NegativePreconditions);
|
||||
addRequirementUnique(ast::Requirement::DisjunctivePreconditions);
|
||||
addRequirementUnique(ast::Requirement::Equality);
|
||||
addRequirementUnique(ast::Requirement::QuantifiedPreconditions);
|
||||
addRequirementUnique(ast::Requirement::ConditionalEffects);
|
||||
}
|
||||
|
||||
if (hasRequirement(problem, ast::Requirement::QuantifiedPreconditions))
|
||||
{
|
||||
addRequirementUnique(ast::Requirement::ExistentialPreconditions);
|
||||
addRequirementUnique(ast::Requirement::UniversalPreconditions);
|
||||
}
|
||||
|
||||
if (hasRequirement(problem, ast::Requirement::Fluents))
|
||||
{
|
||||
addRequirementUnique(ast::Requirement::NumericFluents);
|
||||
addRequirementUnique(ast::Requirement::ObjectFluents);
|
||||
}
|
||||
|
||||
if (hasRequirement(problem, ast::Requirement::TimedInitialLiterals))
|
||||
addRequirementUnique(ast::Requirement::DurativeActions);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ProblemParser::parseObjectSection(ast::Problem &problem)
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("objects");
|
||||
|
||||
// Store constants
|
||||
parseAndAddConstantDeclarations(m_context, problem);
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ProblemParser::parseInitialStateSection(ast::Problem &problem)
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("init");
|
||||
|
||||
ASTContext astContext(problem);
|
||||
VariableStack variableStack;
|
||||
|
||||
problem.initialState = parseInitialState(m_context, astContext, variableStack);
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
skipSection(tokenizer);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ProblemParser::parseGoalSection(ast::Problem &problem)
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("goal");
|
||||
|
||||
ASTContext astContext(problem);
|
||||
VariableStack variableStack;
|
||||
|
||||
problem.goal = parsePrecondition(m_context, astContext, variableStack);
|
||||
|
||||
skipSection(tokenizer);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
93
lib/pddl/src/pddl/detail/parsing/Requirement.cpp
Normal file
93
lib/pddl/src/pddl/detail/parsing/Requirement.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
#include <pddl/detail/parsing/Requirement.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Exception.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Requirement
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct CompareStrings
|
||||
{
|
||||
bool operator()(const char *lhs, const char *rhs) const
|
||||
{
|
||||
return std::strcmp(lhs, rhs) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using RequirementNameMap = std::map<const char *, ast::Requirement, CompareStrings>;
|
||||
static const RequirementNameMap requirementNameMap =
|
||||
{
|
||||
{"strips", ast::Requirement::STRIPS},
|
||||
{"typing", ast::Requirement::Typing},
|
||||
{"negative-preconditions", ast::Requirement::NegativePreconditions},
|
||||
{"disjunctive-preconditions", ast::Requirement::DisjunctivePreconditions},
|
||||
{"equality", ast::Requirement::Equality},
|
||||
{"existential-preconditions", ast::Requirement::ExistentialPreconditions},
|
||||
{"universal-preconditions", ast::Requirement::UniversalPreconditions},
|
||||
{"quantified-preconditions", ast::Requirement::QuantifiedPreconditions},
|
||||
{"conditional-effects", ast::Requirement::ConditionalEffects},
|
||||
{"fluents", ast::Requirement::Fluents},
|
||||
{"numeric-fluents", ast::Requirement::NumericFluents},
|
||||
{"object-fluents", ast::Requirement::ObjectFluents},
|
||||
{"adl", ast::Requirement::ADL},
|
||||
{"durative-actions", ast::Requirement::DurativeActions},
|
||||
{"duration-inequalities", ast::Requirement::DurationInequalities},
|
||||
{"continuous-effects", ast::Requirement::ContinuousEffects},
|
||||
{"derived-predicates", ast::Requirement::DerivedPredicates},
|
||||
{"timed-initial-literals", ast::Requirement::TimedInitialLiterals},
|
||||
{"preferences", ast::Requirement::Preferences},
|
||||
{"constraints", ast::Requirement::Constraints},
|
||||
{"action-costs", ast::Requirement::ActionCosts},
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::Requirement> parseRequirement(Context &context)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
const auto requirementName = tokenizer.getIdentifier();
|
||||
|
||||
const auto matchingRequirement = requirementNameMap.find(requirementName.c_str());
|
||||
|
||||
if (matchingRequirement != requirementNameMap.cend())
|
||||
return matchingRequirement->second;
|
||||
|
||||
if (context.mode == Mode::Compatibility && (requirementName == "goal-utilities" || requirementName == "domain-axioms"))
|
||||
context.warningCallback(tokenizer.location(), "“" + requirementName + "” requirement is not part of the PDDL 3.1 specification, ignoring requirement");
|
||||
|
||||
return std::experimental::nullopt;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const char *toString(const ast::Requirement &requirement)
|
||||
{
|
||||
const auto matchingRequirement = std::find_if(requirementNameMap.cbegin(), requirementNameMap.cend(),
|
||||
[&](const auto &requirementNamePair)
|
||||
{
|
||||
return requirementNamePair.second == requirement;
|
||||
});
|
||||
|
||||
assert(matchingRequirement != requirementNameMap.cend());
|
||||
|
||||
return matchingRequirement->first;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
52
lib/pddl/src/pddl/detail/parsing/Type.cpp
Normal file
52
lib/pddl/src/pddl/detail/parsing/Type.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <pddl/detail/parsing/Type.h>
|
||||
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/detail/parsing/Expressions.h>
|
||||
#include <pddl/detail/parsing/PrimitiveType.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Type
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::Type parseType(Context &context, ast::Domain &domain)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
if (tokenizer.testAndReturn<char>('('))
|
||||
{
|
||||
// TODO: refactor
|
||||
auto parsePrimitiveTypeWrapper =
|
||||
[](auto &context, auto &astContext, auto &) -> std::experimental::optional<ast::PrimitiveTypePointer>
|
||||
{
|
||||
return parsePrimitiveType(context, *astContext.domain);
|
||||
};
|
||||
|
||||
// TODO: refactor
|
||||
ASTContext astContext(domain);
|
||||
VariableStack variableStack;
|
||||
|
||||
auto eitherType = parseEither<ast::PrimitiveTypePointer>(context, astContext, variableStack, parsePrimitiveTypeWrapper);
|
||||
|
||||
if (!eitherType)
|
||||
throw ParserException(tokenizer.location(), "expected primitive type or “either” expression");
|
||||
|
||||
return std::move(eitherType.value());
|
||||
}
|
||||
|
||||
// If existing, parse and store parent type
|
||||
return parsePrimitiveType(context, domain);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
45
lib/pddl/src/pddl/detail/parsing/Unsupported.cpp
Normal file
45
lib/pddl/src/pddl/detail/parsing/Unsupported.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include <pddl/detail/parsing/Unsupported.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/detail/parsing/Utils.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Unsupported
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ParserException exceptUnsupportedExpression(tokenize::StreamPosition position, Context &context)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.seek(position);
|
||||
tokenizer.expect<std::string>("(");
|
||||
auto expressionType = tokenizer.getIdentifier();
|
||||
|
||||
return ParserException(tokenizer.location(position), "“" + expressionType + "” expressions currently unsupported");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ParserException exceptUnsupportedSection(tokenize::StreamPosition position, Context &context)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.seek(position);
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
auto sectionType = tokenizer.getIdentifier();
|
||||
|
||||
return ParserException(tokenizer.location(position), "“:" + sectionType + "” sections currently unsupported");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
75
lib/pddl/src/pddl/detail/parsing/Variable.cpp
Normal file
75
lib/pddl/src/pddl/detail/parsing/Variable.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include <pddl/detail/parsing/Variable.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Exception.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Predicate
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<std::string> testParsingVariableName(Context &context)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
if (!tokenizer.testAndReturn<std::string>("?"))
|
||||
return std::experimental::nullopt;
|
||||
|
||||
tokenizer.expect<std::string>("?");
|
||||
|
||||
return tokenizer.getIdentifier();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string parseVariableName(Context &context)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("?");
|
||||
|
||||
return tokenizer.getIdentifier();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::experimental::optional<ast::VariablePointer> testParsingVariable(Context &context, VariableStack &variableStack)
|
||||
{
|
||||
auto variableName = testParsingVariableName(context);
|
||||
|
||||
if (!variableName)
|
||||
return std::experimental::nullopt;
|
||||
|
||||
auto variableDeclaration = variableStack.findVariableDeclaration(variableName.value());
|
||||
|
||||
if (!variableDeclaration)
|
||||
return std::experimental::nullopt;
|
||||
|
||||
return std::make_unique<ast::Variable>(variableDeclaration.value());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::VariablePointer parseVariable(Context &context, VariableStack &variableStack)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
auto variableName = parseVariableName(context);
|
||||
auto variableDeclaration = variableStack.findVariableDeclaration(variableName);
|
||||
|
||||
if (!variableDeclaration)
|
||||
throw ParserException(tokenizer.location(), "undeclared variable “" + variableName + "”");
|
||||
|
||||
return std::make_unique<ast::Variable>(variableDeclaration.value());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
87
lib/pddl/src/pddl/detail/parsing/VariableDeclaration.cpp
Normal file
87
lib/pddl/src/pddl/detail/parsing/VariableDeclaration.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include <pddl/detail/parsing/VariableDeclaration.h>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Exception.h>
|
||||
#include <pddl/detail/ASTCopy.h>
|
||||
#include <pddl/detail/parsing/Type.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// VariableDeclaration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void parseAndAddUntypedVariableDeclaration(Context &context, ast::VariableDeclarations &variableDeclarations)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("?");
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
auto variableName = tokenizer.getIdentifier();
|
||||
|
||||
if (variableName == "" || variableName == "-")
|
||||
{
|
||||
tokenizer.seek(position);
|
||||
throw ParserException(tokenizer.location(), "could not parse variable name");
|
||||
}
|
||||
|
||||
variableDeclarations.emplace_back(std::make_unique<ast::VariableDeclaration>(std::move(variableName)));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void parseAndAddVariableDeclarations(Context &context, ast::Domain &domain, ast::VariableDeclarations &variableDeclarations)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Index on the first element of the current inheritance list
|
||||
size_t inheritanceIndex = variableDeclarations.size();
|
||||
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
parseAndAddUntypedVariableDeclaration(context, variableDeclarations);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
if (!tokenizer.testAndSkip<char>('-'))
|
||||
continue;
|
||||
|
||||
auto parentType = parseType(context, domain);
|
||||
|
||||
for (size_t i = inheritanceIndex; i < variableDeclarations.size(); i++)
|
||||
variableDeclarations[i]->type = ast::deepCopy(parentType);
|
||||
|
||||
// All types up to now are labeled with their parent types
|
||||
inheritanceIndex = variableDeclarations.size();
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
const bool isTypingUsed = !domain.types.empty();
|
||||
|
||||
if (isTypingUsed && !variableDeclarations.empty() && !variableDeclarations.back()->type)
|
||||
throw ParserException(tokenizer.location(), "missing type declaration for variable “?" + variableDeclarations.back()->name + "”");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ast::VariableDeclarations parseVariableDeclarations(Context &context, ast::Domain &domain)
|
||||
{
|
||||
ast::VariableDeclarations result;
|
||||
|
||||
parseAndAddVariableDeclarations(context, domain, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
24
lib/pddl/tests/CMakeLists.txt
Normal file
24
lib/pddl/tests/CMakeLists.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
set(target pddl-tests)
|
||||
|
||||
file(GLOB core_sources "*.cpp")
|
||||
|
||||
set(includes
|
||||
${PROJECT_SOURCE_DIR}/include
|
||||
${PROJECT_SOURCE_DIR}/../../lib/catch/single_include
|
||||
${PROJECT_SOURCE_DIR}/../../lib/tokenize/include
|
||||
${PROJECT_SOURCE_DIR}/../../lib/variant/include
|
||||
)
|
||||
|
||||
set(libraries
|
||||
stdc++fs
|
||||
pddl
|
||||
)
|
||||
|
||||
add_executable(${target} ${core_sources})
|
||||
target_include_directories(${target} PRIVATE ${includes})
|
||||
target_link_libraries(${target} ${libraries})
|
||||
|
||||
add_custom_target(run-pddl-tests
|
||||
COMMAND ${CMAKE_BINARY_DIR}/bin/pddl-tests --use-colour=yes
|
||||
DEPENDS ${target}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/../../tests)
|
183
lib/pddl/tests/TestAcceptanceOfOfficialPDDLInstances.cpp
Normal file
183
lib/pddl/tests/TestAcceptanceOfOfficialPDDLInstances.cpp
Normal file
@@ -0,0 +1,183 @@
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <experimental/filesystem>
|
||||
#include <set>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Parse.h>
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
const pddl::Context::WarningCallback ignoreWarnings = [](const auto &, const auto &){};
|
||||
const auto pddlInstanceBasePath = fs::path("data") / "pddl-instances";
|
||||
|
||||
const std::set<std::experimental::filesystem::path> unsupportedDomains =
|
||||
{
|
||||
// “=” expressions unsupported
|
||||
pddlInstanceBasePath / "ipc-1998" / "domains" / "assembly-round-1-adl" / "domain.pddl",
|
||||
// “=” expressions unsupported
|
||||
pddlInstanceBasePath / "ipc-1998" / "domains" / "mystery-prime-round-1-strips" / "domain.pddl",
|
||||
// “=” expressions unsupported
|
||||
pddlInstanceBasePath / "ipc-1998" / "domains" / "mystery-prime-round-2-strips" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "depots-numeric-automatic" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "depots-numeric-hand-coded" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "depots-time-automatic" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "depots-time-hand-coded" / "domain.pddl",
|
||||
// “:durative-action” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "depots-time-simple-automatic" / "domain.pddl",
|
||||
// “:durative-action” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "depots-time-simple-hand-coded" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "driverlog-numeric-automatic" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "driverlog-numeric-hand-coded" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "driverlog-numeric-hard-automatic" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "driverlog-numeric-hard-hand-coded" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "driverlog-time-automatic" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "driverlog-time-hand-coded" / "domain.pddl",
|
||||
// “:durative-action” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "driverlog-time-simple-automatic" / "domain.pddl",
|
||||
// “:durative-action” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "driverlog-time-simple-hand-coded" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "rovers-numeric-automatic" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "rovers-numeric-hand-coded" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "rovers-time-automatic" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "rovers-time-hand-coded" / "domain.pddl",
|
||||
// “:durative-action” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "rovers-time-simple-automatic" / "domain.pddl",
|
||||
// “:durative-action” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "rovers-time-simple-hand-coded" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "satellite-complex-automatic" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "satellite-complex-hand-coded" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "satellite-numeric-automatic" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "satellite-numeric-hand-coded" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "satellite-numeric-hard-automatic" / "domain.pddl",
|
||||
// “=” expressions unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "satellite-strips-automatic" / "domain.pddl",
|
||||
// “=” expressions unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "satellite-strips-hand-coded" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "satellite-time-automatic" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "satellite-time-hand-coded" / "domain.pddl",
|
||||
// “:durative-action” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "satellite-time-simple-automatic" / "domain.pddl",
|
||||
// “:durative-action” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "satellite-time-simple-hand-coded" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "settlers-numeric-automatic" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "umtranslog-2-numeric-hand-coded" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "zenotravel-numeric-automatic" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "zenotravel-numeric-hand-coded" / "domain.pddl",
|
||||
// “either” expressions unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "zenotravel-strips-automatic" / "domain.pddl",
|
||||
// “either” expressions unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "zenotravel-strips-hand-coded" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "zenotravel-time-automatic" / "domain.pddl",
|
||||
// “:functions” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "zenotravel-time-hand-coded" / "domain.pddl",
|
||||
// “:durative-action” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "zenotravel-time-simple-automatic" / "domain.pddl",
|
||||
// “:durative-action” sections unsupported
|
||||
pddlInstanceBasePath / "ipc-2002" / "domains" / "zenotravel-time-simple-hand-coded" / "domain.pddl",
|
||||
|
||||
};
|
||||
|
||||
const std::set<std::experimental::filesystem::path> unsupportedInstances =
|
||||
{
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("[PDDL acceptance] All official PDDL domains are parsed without errors", "[PDDL acceptance]")
|
||||
{
|
||||
for (const auto &competitionDirectory : fs::directory_iterator(pddlInstanceBasePath))
|
||||
{
|
||||
if (!fs::is_directory(competitionDirectory))
|
||||
continue;
|
||||
|
||||
for (const auto &domainDirectory : fs::directory_iterator(competitionDirectory.path() / "domains"))
|
||||
{
|
||||
if (!fs::is_directory(domainDirectory))
|
||||
continue;
|
||||
|
||||
const auto domainFile = domainDirectory / "domain.pddl";
|
||||
|
||||
if (unsupportedDomains.find(domainFile) != unsupportedDomains.cend())
|
||||
continue;
|
||||
|
||||
const auto testSectionName = competitionDirectory.path().stem().string() + ", "
|
||||
+ domainDirectory.path().stem().string();
|
||||
|
||||
SECTION("domain [" + testSectionName + "]")
|
||||
{
|
||||
pddl::Tokenizer tokenizer;
|
||||
tokenizer.read(domainFile);
|
||||
pddl::Context context(std::move(tokenizer), ignoreWarnings, pddl::Mode::Compatibility);
|
||||
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("[PDDL acceptance] The first instance for all official PDDL domains is parsed without errors", "[PDDL acceptance]")
|
||||
{
|
||||
for (const auto &competitionDirectory : fs::directory_iterator(pddlInstanceBasePath))
|
||||
{
|
||||
if (!fs::is_directory(competitionDirectory))
|
||||
continue;
|
||||
|
||||
for (const auto &domainDirectory : fs::directory_iterator(competitionDirectory.path() / "domains"))
|
||||
{
|
||||
if (!fs::is_directory(domainDirectory))
|
||||
continue;
|
||||
|
||||
const auto domainFile = domainDirectory / "domain.pddl";
|
||||
const auto instanceFile = domainDirectory / "instances" / "instance-1.pddl";
|
||||
|
||||
if (unsupportedDomains.find(domainFile) != unsupportedDomains.cend()
|
||||
|| unsupportedInstances.find(instanceFile) != unsupportedInstances.cend())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto testSectionName = competitionDirectory.path().stem().string() + ", "
|
||||
+ domainDirectory.path().stem().string() + ", "
|
||||
+ instanceFile.stem().string();
|
||||
|
||||
SECTION("instance [" + testSectionName + "]")
|
||||
{
|
||||
pddl::Tokenizer tokenizer;
|
||||
tokenizer.read(domainFile);
|
||||
tokenizer.read(instanceFile);
|
||||
pddl::Context context(std::move(tokenizer), ignoreWarnings, pddl::Mode::Compatibility);
|
||||
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
87
lib/pddl/tests/TestIssues.cpp
Normal file
87
lib/pddl/tests/TestIssues.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <experimental/filesystem>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Parse.h>
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
const pddl::Context::WarningCallback ignoreWarnings = [](const auto &, const auto &){};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("[PDDL parser issues] Check past issues", "[PDDL parser issues]")
|
||||
{
|
||||
pddl::Tokenizer tokenizer;
|
||||
pddl::Context context(std::move(tokenizer), ignoreWarnings);
|
||||
|
||||
SECTION("white space issues with constants and parsing unsupported sections")
|
||||
{
|
||||
const auto domainFile = fs::path("data") / "issues" / "issue-1.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("white space issues with empty n-ary predicates")
|
||||
{
|
||||
const auto domainFile = fs::path("data") / "issues" / "issue-2.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("comments are correctly ignored")
|
||||
{
|
||||
const auto domainFile = fs::path("data") / "issues" / "issue-3.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
// Check that no infinite loop occurs
|
||||
SECTION("“either” in typing section")
|
||||
{
|
||||
const auto domainFile = fs::path("data") / "issues" / "issue-7.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
CHECK_THROWS(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
// Check that whitespace is correctly ignored in type section
|
||||
SECTION("whitespace in typing section")
|
||||
{
|
||||
const auto domainFile = fs::path("data") / "issues" / "issue-8.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
// Check that accidentally unnamed variables lead to an exception and not a segfault
|
||||
SECTION("whitespace in typing section")
|
||||
{
|
||||
const auto domainFile = fs::path("data") / "issues" / "issue-9.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
CHECK_THROWS(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
// Check that “at” is allowed as a predicate name and not exclusively for “at” expressions
|
||||
SECTION("“at” as predicate name")
|
||||
{
|
||||
const auto domainFile = fs::path("data") / "issues" / "issue-10.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
|
||||
const auto description = pddl::parseDescription(context);
|
||||
|
||||
REQUIRE(description.problem);
|
||||
|
||||
const auto &problem = description.problem.value();
|
||||
const auto &facts = problem->initialState.facts;
|
||||
|
||||
const auto invalidFact = std::find_if(facts.cbegin(), facts.cend(),
|
||||
[](const auto &fact)
|
||||
{
|
||||
return fact.template is<pddl::ast::AtPointer<pddl::ast::Literal>>();
|
||||
});
|
||||
|
||||
const auto containsInvalidFact = (invalidFact != facts.cend());
|
||||
|
||||
CHECK(!containsInvalidFact);
|
||||
}
|
||||
}
|
383
lib/pddl/tests/TestOfficialPDDLInstances.cpp
Normal file
383
lib/pddl/tests/TestOfficialPDDLInstances.cpp
Normal file
@@ -0,0 +1,383 @@
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <experimental/filesystem>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Parse.h>
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
const pddl::Context::WarningCallback ignoreWarnings = [](const auto &, const auto &){};
|
||||
const auto pddlInstanceBasePath = fs::path("data") / "pddl-instances";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("[PDDL instances] The official PDDL instances are parsed correctly", "[PDDL instances]")
|
||||
{
|
||||
pddl::Tokenizer tokenizer;
|
||||
pddl::Context context(std::move(tokenizer), ignoreWarnings);
|
||||
|
||||
SECTION("types, predicates, and actions in blocksworld domain")
|
||||
{
|
||||
const auto domainFile = pddlInstanceBasePath / "ipc-2000" / "domains" / "blocks-strips-typed" / "domain.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
auto description = pddl::parseDescription(context);
|
||||
|
||||
CHECK(description.domain->name == "blocks");
|
||||
CHECK(description.domain->constants.empty());
|
||||
|
||||
const auto &types = description.domain->types;
|
||||
|
||||
REQUIRE(types.size() == 1);
|
||||
const auto &typeBlock = types[0];
|
||||
CHECK(typeBlock->name == "block");
|
||||
|
||||
const auto &predicates = description.domain->predicates;
|
||||
|
||||
REQUIRE(predicates.size() == 5);
|
||||
|
||||
CHECK(predicates[0]->name == "on");
|
||||
REQUIRE(predicates[0]->parameters.size() == 2);
|
||||
CHECK(predicates[0]->parameters[0]->name == "x");
|
||||
CHECK(predicates[0]->parameters[0]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
CHECK(predicates[0]->parameters[1]->name == "y");
|
||||
CHECK(predicates[0]->parameters[1]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
CHECK(predicates[1]->name == "ontable");
|
||||
REQUIRE(predicates[1]->parameters.size() == 1);
|
||||
CHECK(predicates[1]->parameters[0]->name == "x");
|
||||
CHECK(predicates[1]->parameters[0]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
CHECK(predicates[2]->name == "clear");
|
||||
REQUIRE(predicates[2]->parameters.size() == 1);
|
||||
CHECK(predicates[2]->parameters[0]->name == "x");
|
||||
CHECK(predicates[2]->parameters[0]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
CHECK(predicates[3]->name == "handempty");
|
||||
CHECK(predicates[3]->parameters.empty());
|
||||
CHECK(predicates[4]->name == "holding");
|
||||
REQUIRE(predicates[4]->parameters.size() == 1);
|
||||
CHECK(predicates[4]->parameters[0]->name == "x");
|
||||
CHECK(predicates[4]->parameters[0]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
|
||||
const auto &actions = description.domain->actions;
|
||||
|
||||
REQUIRE(actions.size() == 4);
|
||||
|
||||
CHECK(actions[3]->name == "unstack");
|
||||
|
||||
REQUIRE(actions[3]->parameters.size() == 2);
|
||||
CHECK(actions[3]->parameters[0]->name == "x");
|
||||
CHECK(actions[3]->parameters[0]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
CHECK(actions[3]->parameters[1]->name == "y");
|
||||
CHECK(actions[3]->parameters[1]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
|
||||
const auto &preconditionAnd = actions[3]->precondition.value().get<pddl::ast::AndPointer<pddl::ast::Precondition>>();
|
||||
const auto &precondition0 = preconditionAnd->arguments[0].get<pddl::ast::AtomicFormula>().get<pddl::ast::PredicatePointer>();
|
||||
// TODO: check declaration once implemented
|
||||
REQUIRE(precondition0->arguments.size() == 2);
|
||||
CHECK(precondition0->arguments[0].get<pddl::ast::VariablePointer>()->declaration->name == "x");
|
||||
CHECK(precondition0->arguments[0].get<pddl::ast::VariablePointer>()->declaration->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
CHECK(precondition0->arguments[1].get<pddl::ast::VariablePointer>()->declaration->name == "y");
|
||||
CHECK(precondition0->arguments[1].get<pddl::ast::VariablePointer>()->declaration->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
const auto &precondition1 = preconditionAnd->arguments[1].get<pddl::ast::AtomicFormula>().get<pddl::ast::PredicatePointer>();
|
||||
// TODO: check declaration once implemented
|
||||
REQUIRE(precondition1->arguments.size() == 1);
|
||||
CHECK(precondition1->arguments[0].get<pddl::ast::VariablePointer>()->declaration->name == "x");
|
||||
CHECK(precondition1->arguments[0].get<pddl::ast::VariablePointer>()->declaration->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
const auto &precondition2 = preconditionAnd->arguments[2].get<pddl::ast::AtomicFormula>().get<pddl::ast::PredicatePointer>();
|
||||
// TODO: check declaration once implemented
|
||||
REQUIRE(precondition2->arguments.empty());
|
||||
|
||||
const auto &effectAnd = actions[3]->effect.value().get<pddl::ast::AndPointer<pddl::ast::Effect>>();
|
||||
const auto &effect0 = effectAnd->arguments[0].get<pddl::ast::Literal>().get<pddl::ast::AtomicFormula>().get<pddl::ast::PredicatePointer>();
|
||||
// TODO: check declaration once implemented
|
||||
REQUIRE(effect0->arguments.size() == 1);
|
||||
CHECK(effect0->arguments[0].get<pddl::ast::VariablePointer>()->declaration->name == "x");
|
||||
CHECK(effect0->arguments[0].get<pddl::ast::VariablePointer>()->declaration->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
const auto &effect1 = effectAnd->arguments[1].get<pddl::ast::Literal>().get<pddl::ast::AtomicFormula>().get<pddl::ast::PredicatePointer>();
|
||||
// TODO: check declaration once implemented
|
||||
REQUIRE(effect1->arguments.size() == 1);
|
||||
CHECK(effect1->arguments[0].get<pddl::ast::VariablePointer>()->declaration->name == "y");
|
||||
CHECK(effect1->arguments[0].get<pddl::ast::VariablePointer>()->declaration->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
const auto &effectNot2 = effectAnd->arguments[2].get<pddl::ast::Literal>().get<pddl::ast::NotPointer<pddl::ast::AtomicFormula>>()->argument.get<pddl::ast::PredicatePointer>();
|
||||
// TODO: check declaration once implemented
|
||||
REQUIRE(effectNot2->arguments.size() == 1);
|
||||
CHECK(effectNot2->arguments[0].get<pddl::ast::VariablePointer>()->declaration->name == "x");
|
||||
CHECK(effectNot2->arguments[0].get<pddl::ast::VariablePointer>()->declaration->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
const auto &effectNot3 = effectAnd->arguments[3].get<pddl::ast::Literal>().get<pddl::ast::NotPointer<pddl::ast::AtomicFormula>>()->argument.get<pddl::ast::PredicatePointer>();
|
||||
// TODO: check declaration once implemented
|
||||
REQUIRE(effectNot3->arguments.empty());
|
||||
const auto &effectNot4 = effectAnd->arguments[4].get<pddl::ast::Literal>().get<pddl::ast::NotPointer<pddl::ast::AtomicFormula>>()->argument.get<pddl::ast::PredicatePointer>();
|
||||
// TODO: check declaration once implemented
|
||||
REQUIRE(effectNot4->arguments.size() == 2);
|
||||
CHECK(effectNot4->arguments[0].get<pddl::ast::VariablePointer>()->declaration->name == "x");
|
||||
CHECK(effectNot4->arguments[0].get<pddl::ast::VariablePointer>()->declaration->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
CHECK(effectNot4->arguments[1].get<pddl::ast::VariablePointer>()->declaration->name == "y");
|
||||
CHECK(effectNot4->arguments[1].get<pddl::ast::VariablePointer>()->declaration->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
}
|
||||
|
||||
SECTION("types, predicates, and actions in blocksworld instance")
|
||||
{
|
||||
const auto domainFile = pddlInstanceBasePath / "ipc-2000" / "domains" / "blocks-strips-typed" / "domain.pddl";
|
||||
const auto instanceFile = pddlInstanceBasePath / "ipc-2000" / "domains" / "blocks-strips-typed" / "instances" / "instance-1.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
context.tokenizer.read(instanceFile);
|
||||
auto description = pddl::parseDescription(context);
|
||||
|
||||
const auto &types = description.domain->types;
|
||||
const auto &typeBlock = types[0];
|
||||
|
||||
REQUIRE(description.problem);
|
||||
|
||||
const auto &problem = description.problem.value();
|
||||
|
||||
CHECK(problem->name == "blocks-4-0");
|
||||
CHECK(problem->domain->name == "blocks");
|
||||
|
||||
const auto &objects = problem->objects;
|
||||
|
||||
REQUIRE(objects.size() == 4);
|
||||
CHECK(objects[0]->name == "d");
|
||||
CHECK(objects[1]->name == "b");
|
||||
CHECK(objects[2]->name == "a");
|
||||
CHECK(objects[3]->name == "c");
|
||||
|
||||
const auto &facts = problem->initialState.facts;
|
||||
|
||||
REQUIRE(facts.size() == 9);
|
||||
const auto &fact0 = facts[0].get<pddl::ast::Literal>().get<pddl::ast::AtomicFormula>().get<pddl::ast::PredicatePointer>();
|
||||
// TODO: check declaration once implemented
|
||||
REQUIRE(fact0->arguments.size() == 1);
|
||||
CHECK(fact0->arguments[0].get<pddl::ast::ConstantPointer>()->declaration->name == "c");
|
||||
CHECK(fact0->arguments[0].get<pddl::ast::ConstantPointer>()->declaration->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
const auto &fact5 = facts[5].get<pddl::ast::Literal>().get<pddl::ast::AtomicFormula>().get<pddl::ast::PredicatePointer>();
|
||||
// TODO: check declaration once implemented
|
||||
REQUIRE(fact5->arguments.size() == 1);
|
||||
CHECK(fact5->arguments[0].get<pddl::ast::ConstantPointer>()->declaration->name == "a");
|
||||
CHECK(fact5->arguments[0].get<pddl::ast::ConstantPointer>()->declaration->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
const auto &fact8 = facts[8].get<pddl::ast::Literal>().get<pddl::ast::AtomicFormula>().get<pddl::ast::PredicatePointer>();
|
||||
// TODO: check declaration once implemented
|
||||
REQUIRE(fact8->arguments.empty());
|
||||
|
||||
REQUIRE(problem->goal);
|
||||
|
||||
const auto &goal = problem->goal.value();
|
||||
const auto &goalAnd = goal.get<pddl::ast::AndPointer<pddl::ast::Precondition>>();
|
||||
|
||||
REQUIRE(goalAnd->arguments.size() == 3);
|
||||
const auto &goal0 = goalAnd->arguments[0].get<pddl::ast::AtomicFormula>().get<pddl::ast::PredicatePointer>();
|
||||
// TODO: check declaration once implemented
|
||||
REQUIRE(goal0->arguments.size() == 2);
|
||||
CHECK(goal0->arguments[0].get<pddl::ast::ConstantPointer>()->declaration->name == "d");
|
||||
CHECK(goal0->arguments[0].get<pddl::ast::ConstantPointer>()->declaration->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
CHECK(goal0->arguments[1].get<pddl::ast::ConstantPointer>()->declaration->name == "c");
|
||||
CHECK(goal0->arguments[1].get<pddl::ast::ConstantPointer>()->declaration->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
const auto &goal1 = goalAnd->arguments[1].get<pddl::ast::AtomicFormula>().get<pddl::ast::PredicatePointer>();
|
||||
// TODO: check declaration once implemented
|
||||
REQUIRE(goal0->arguments.size() == 2);
|
||||
CHECK(goal1->arguments[0].get<pddl::ast::ConstantPointer>()->declaration->name == "c");
|
||||
CHECK(goal1->arguments[0].get<pddl::ast::ConstantPointer>()->declaration->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
CHECK(goal1->arguments[1].get<pddl::ast::ConstantPointer>()->declaration->name == "b");
|
||||
CHECK(goal1->arguments[1].get<pddl::ast::ConstantPointer>()->declaration->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
const auto &goal2 = goalAnd->arguments[2].get<pddl::ast::AtomicFormula>().get<pddl::ast::PredicatePointer>();
|
||||
// TODO: check declaration once implemented
|
||||
REQUIRE(goal0->arguments.size() == 2);
|
||||
CHECK(goal2->arguments[0].get<pddl::ast::ConstantPointer>()->declaration->name == "b");
|
||||
CHECK(goal2->arguments[0].get<pddl::ast::ConstantPointer>()->declaration->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
CHECK(goal2->arguments[1].get<pddl::ast::ConstantPointer>()->declaration->name == "a");
|
||||
CHECK(goal2->arguments[1].get<pddl::ast::ConstantPointer>()->declaration->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration == typeBlock.get());
|
||||
}
|
||||
|
||||
SECTION("“either” type in zenotravel domain")
|
||||
{
|
||||
context.mode = pddl::Mode::Compatibility;
|
||||
|
||||
const auto domainFile = pddlInstanceBasePath / "ipc-2002" / "domains" / "zenotravel-strips-hand-coded" / "domain.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
auto description = pddl::parseDescription(context);
|
||||
|
||||
const auto &predicates = description.domain->predicates;
|
||||
|
||||
REQUIRE(predicates.size() == 4);
|
||||
REQUIRE(predicates[0]->name == "at");
|
||||
REQUIRE(predicates[0]->parameters.size() == 2);
|
||||
REQUIRE(predicates[0]->parameters[0]->name == "x");
|
||||
REQUIRE(predicates[0]->parameters[0]->type);
|
||||
CHECK(predicates[0]->parameters[0]->type.value().get<pddl::ast::EitherPointer<pddl::ast::PrimitiveTypePointer>>()->arguments[0]->declaration->name == "person");
|
||||
CHECK(predicates[0]->parameters[0]->type.value().get<pddl::ast::EitherPointer<pddl::ast::PrimitiveTypePointer>>()->arguments[1]->declaration->name == "aircraft");
|
||||
REQUIRE(predicates[0]->parameters[1]->name == "c");
|
||||
REQUIRE(predicates[0]->parameters[1]->type);
|
||||
CHECK(predicates[0]->parameters[1]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "city");
|
||||
}
|
||||
|
||||
SECTION("typed constants in schedule domain")
|
||||
{
|
||||
context.mode = pddl::Mode::Compatibility;
|
||||
|
||||
const auto domainFile = pddlInstanceBasePath / "ipc-2000" / "domains" / "schedule-adl-typed" / "domain.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
auto description = pddl::parseDescription(context);
|
||||
|
||||
const auto &constants = description.domain->constants;
|
||||
|
||||
REQUIRE(constants.size() == 14);
|
||||
CHECK(constants[0]->name == "cold");
|
||||
CHECK(constants[0]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "temperature");
|
||||
CHECK(constants[1]->name == "hot");
|
||||
CHECK(constants[1]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "temperature");
|
||||
CHECK(constants[2]->name == "cylindrical");
|
||||
CHECK(constants[2]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "ashape");
|
||||
CHECK(constants[3]->name == "polisher");
|
||||
CHECK(constants[3]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "machine");
|
||||
CHECK(constants[4]->name == "roller");
|
||||
CHECK(constants[4]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "machine");
|
||||
CHECK(constants[10]->name == "immersion-painter");
|
||||
CHECK(constants[10]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "machine");
|
||||
CHECK(constants[11]->name == "polished");
|
||||
CHECK(constants[11]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "surface");
|
||||
CHECK(constants[13]->name == "smooth");
|
||||
CHECK(constants[13]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "surface");
|
||||
}
|
||||
|
||||
SECTION("type inheritance in logistics domain")
|
||||
{
|
||||
context.mode = pddl::Mode::Compatibility;
|
||||
|
||||
const auto domainFile = pddlInstanceBasePath / "ipc-2000" / "domains" / "logistics-strips-typed" / "domain.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
auto description = pddl::parseDescription(context);
|
||||
|
||||
const auto &types = description.domain->types;
|
||||
|
||||
REQUIRE(types.size() == 10);
|
||||
CHECK(types[0]->name == "truck");
|
||||
REQUIRE(types[0]->parentTypes.size() == 1);
|
||||
CHECK(types[0]->parentTypes[0]->declaration->name == "vehicle");
|
||||
CHECK(types[1]->name == "airplane");
|
||||
REQUIRE(types[1]->parentTypes.size() == 1);
|
||||
CHECK(types[1]->parentTypes[0]->declaration->name == "vehicle");
|
||||
CHECK(types[2]->name == "vehicle");
|
||||
REQUIRE(types[2]->parentTypes.size() == 1);
|
||||
CHECK(types[2]->parentTypes[0]->declaration->name == "physobj");
|
||||
CHECK(types[3]->name == "package");
|
||||
REQUIRE(types[3]->parentTypes.size() == 1);
|
||||
CHECK(types[3]->parentTypes[0]->declaration->name == "physobj");
|
||||
CHECK(types[4]->name == "physobj");
|
||||
REQUIRE(types[4]->parentTypes.size() == 1);
|
||||
CHECK(types[4]->parentTypes[0]->declaration->name == "object");
|
||||
CHECK(types[5]->name == "airport");
|
||||
REQUIRE(types[5]->parentTypes.size() == 1);
|
||||
CHECK(types[5]->parentTypes[0]->declaration->name == "place");
|
||||
CHECK(types[6]->name == "location");
|
||||
REQUIRE(types[6]->parentTypes.size() == 1);
|
||||
CHECK(types[6]->parentTypes[0]->declaration->name == "place");
|
||||
CHECK(types[7]->name == "place");
|
||||
REQUIRE(types[7]->parentTypes.size() == 1);
|
||||
CHECK(types[7]->parentTypes[0]->declaration->name == "object");
|
||||
CHECK(types[8]->name == "city");
|
||||
REQUIRE(types[8]->parentTypes.size() == 1);
|
||||
CHECK(types[8]->parentTypes[0]->declaration->name == "object");
|
||||
CHECK(types[9]->name == "object");
|
||||
REQUIRE(types[9]->parentTypes.empty());
|
||||
}
|
||||
|
||||
SECTION("typing in mystery domain")
|
||||
{
|
||||
context.mode = pddl::Mode::Compatibility;
|
||||
|
||||
const auto domainFile = pddlInstanceBasePath / "ipc-1998" / "domains" / "mystery-round-1-adl" / "domain.pddl";
|
||||
const auto instanceFile = pddlInstanceBasePath / "ipc-1998" / "domains" / "mystery-round-1-adl" / "instances" / "instance-1.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
context.tokenizer.read(instanceFile);
|
||||
auto description = pddl::parseDescription(context);
|
||||
|
||||
const auto &actions = description.domain->actions;
|
||||
|
||||
REQUIRE(actions.size() == 3);
|
||||
// TODO: adjust if there are changes to handling :vars section
|
||||
REQUIRE(actions[0]->parameters.size() == 5);
|
||||
CHECK(actions[0]->parameters[0]->name == "c");
|
||||
CHECK(actions[0]->parameters[0]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "pain");
|
||||
CHECK(actions[0]->parameters[1]->name == "v");
|
||||
CHECK(actions[0]->parameters[1]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "pleasure");
|
||||
CHECK(actions[0]->parameters[2]->name == "n");
|
||||
CHECK(actions[0]->parameters[2]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "food");
|
||||
CHECK(actions[0]->parameters[3]->name == "s1");
|
||||
CHECK(actions[0]->parameters[3]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "planet");
|
||||
CHECK(actions[0]->parameters[4]->name == "s2");
|
||||
CHECK(actions[0]->parameters[4]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "planet");
|
||||
|
||||
REQUIRE(description.problem);
|
||||
|
||||
const auto &problem = description.problem.value();
|
||||
const auto &objects = problem->objects;
|
||||
|
||||
REQUIRE(objects.size() == 21);
|
||||
CHECK(objects[0]->name == "rice");
|
||||
CHECK(objects[0]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "food");
|
||||
CHECK(objects[1]->name == "pear");
|
||||
CHECK(objects[1]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "food");
|
||||
CHECK(objects[2]->name == "flounder");
|
||||
CHECK(objects[2]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "food");
|
||||
CHECK(objects[5]->name == "lamb");
|
||||
CHECK(objects[5]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "food");
|
||||
CHECK(objects[6]->name == "rest");
|
||||
CHECK(objects[6]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "pleasure");
|
||||
CHECK(objects[7]->name == "hangover");
|
||||
CHECK(objects[7]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "pain");
|
||||
CHECK(objects[8]->name == "depression");
|
||||
CHECK(objects[8]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "pain");
|
||||
CHECK(objects[9]->name == "abrasion");
|
||||
CHECK(objects[9]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "pain");
|
||||
CHECK(objects[10]->name == "kentucky");
|
||||
CHECK(objects[10]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "province");
|
||||
CHECK(objects[16]->name == "guanabara");
|
||||
CHECK(objects[16]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "province");
|
||||
CHECK(objects[17]->name == "mars");
|
||||
CHECK(objects[17]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "planet");
|
||||
CHECK(objects[20]->name == "venus");
|
||||
CHECK(objects[20]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "planet");
|
||||
}
|
||||
|
||||
SECTION("complicated nested effect expressions in schedule domain")
|
||||
{
|
||||
context.mode = pddl::Mode::Compatibility;
|
||||
|
||||
const auto domainFile = pddlInstanceBasePath / "ipc-2000" / "domains" / "schedule-adl-typed" / "domain.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
auto description = pddl::parseDescription(context);
|
||||
|
||||
const auto &actions = description.domain->actions;
|
||||
|
||||
REQUIRE(actions.size() == 9);
|
||||
CHECK(actions[1]->name == "do-roll");
|
||||
const auto &effectAnd = actions[1]->effect.value().get<pddl::ast::AndPointer<pddl::ast::Effect>>();
|
||||
REQUIRE(effectAnd->arguments.size() == 10);
|
||||
CHECK(effectAnd->arguments[0].get<pddl::ast::Literal>().get<pddl::ast::AtomicFormula>().get<pddl::ast::PredicatePointer>()->arguments[0].get<pddl::ast::ConstantPointer>()->declaration->name == "roller");
|
||||
CHECK(effectAnd->arguments[1].get<pddl::ast::Literal>().get<pddl::ast::AtomicFormula>().is<pddl::ast::PredicatePointer>());
|
||||
CHECK(effectAnd->arguments[2].get<pddl::ast::Literal>().get<pddl::ast::AtomicFormula>().is<pddl::ast::PredicatePointer>());
|
||||
CHECK(effectAnd->arguments[3].get<pddl::ast::Literal>().get<pddl::ast::AtomicFormula>().is<pddl::ast::PredicatePointer>());
|
||||
const auto &effectWhen4 = effectAnd->arguments[4].get<pddl::ast::WhenPointer<pddl::ast::Precondition, pddl::ast::ConditionalEffect>>();
|
||||
// TODO: check name of declaration
|
||||
CHECK(effectWhen4->argumentLeft.get<pddl::ast::NotPointer<pddl::ast::Precondition>>()->argument.get<pddl::ast::AtomicFormula>().is<pddl::ast::PredicatePointer>());
|
||||
CHECK(effectWhen4->argumentRight.get<pddl::ast::Literal>().get<pddl::ast::AtomicFormula>().is<pddl::ast::PredicatePointer>());
|
||||
const auto &effectForAll5 = effectAnd->arguments[5].get<pddl::ast::ForAllPointer<pddl::ast::Effect>>();
|
||||
REQUIRE(effectForAll5->parameters.size() == 1);
|
||||
CHECK(effectForAll5->parameters[0]->name == "oldsurface");
|
||||
CHECK(effectForAll5->parameters[0]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "surface");
|
||||
const auto &effectForAll5When = effectForAll5->argument.get<pddl::ast::WhenPointer<pddl::ast::Precondition, pddl::ast::ConditionalEffect>>();
|
||||
// TODO: check name of declaration
|
||||
CHECK(effectForAll5When->argumentLeft.get<pddl::ast::AtomicFormula>().is<pddl::ast::PredicatePointer>());
|
||||
CHECK(effectForAll5When->argumentRight.get<pddl::ast::Literal>().get<pddl::ast::NotPointer<pddl::ast::AtomicFormula>>()->argument.is<pddl::ast::PredicatePointer>());
|
||||
const auto &effectForAll6 = effectAnd->arguments[6].get<pddl::ast::ForAllPointer<pddl::ast::Effect>>();
|
||||
REQUIRE(effectForAll6->parameters.size() == 1);
|
||||
CHECK(effectForAll6->parameters[0]->name == "oldpaint");
|
||||
CHECK(effectForAll6->parameters[0]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "colour");
|
||||
const auto &effectForAll9 = effectAnd->arguments[9].get<pddl::ast::ForAllPointer<pddl::ast::Effect>>();
|
||||
REQUIRE(effectForAll9->parameters.size() == 1);
|
||||
CHECK(effectForAll9->parameters[0]->name == "oldtemp");
|
||||
CHECK(effectForAll9->parameters[0]->type.value().get<pddl::ast::PrimitiveTypePointer>()->declaration->name == "temperature");
|
||||
const auto &effectForAll9When = effectForAll9->argument.get<pddl::ast::WhenPointer<pddl::ast::Precondition, pddl::ast::ConditionalEffect>>();
|
||||
// TODO: check name of declaration
|
||||
CHECK(effectForAll9When->argumentLeft.get<pddl::ast::AtomicFormula>().is<pddl::ast::PredicatePointer>());
|
||||
CHECK(effectForAll9When->argumentRight.get<pddl::ast::Literal>().get<pddl::ast::NotPointer<pddl::ast::AtomicFormula>>()->argument.is<pddl::ast::PredicatePointer>());
|
||||
}
|
||||
}
|
125
lib/pddl/tests/TestParser.cpp
Normal file
125
lib/pddl/tests/TestParser.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <experimental/filesystem>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Parse.h>
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
const pddl::Context::WarningCallback ignoreWarnings = [](const auto &, const auto &){};
|
||||
const auto pddlInstanceBasePath = fs::path("data") / "pddl-instances";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("[PDDL parser] The PDDL parser behaves correctly", "[PDDL parser]")
|
||||
{
|
||||
pddl::Tokenizer tokenizer;
|
||||
pddl::Context context(std::move(tokenizer), ignoreWarnings);
|
||||
|
||||
// Check that no infinite loop occurs
|
||||
SECTION("“either” in typing section")
|
||||
{
|
||||
const auto domainFile = fs::path("data") / "test-cases" / "typing-1.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
const auto description = pddl::parseDescription(context);
|
||||
|
||||
const auto &types = description.domain->types;
|
||||
|
||||
REQUIRE(types.size() == 5);
|
||||
CHECK(types[0]->name == "object");
|
||||
REQUIRE(types[0]->parentTypes.size() == 1);
|
||||
CHECK(types[0]->parentTypes[0]->declaration == types[0].get());
|
||||
CHECK(types[1]->name == "a1");
|
||||
REQUIRE(types[1]->parentTypes.size() == 1);
|
||||
CHECK(types[1]->parentTypes[0]->declaration == types[0].get());
|
||||
CHECK(types[2]->name == "a2");
|
||||
REQUIRE(types[2]->parentTypes.size() == 1);
|
||||
CHECK(types[2]->parentTypes[0]->declaration == types[0].get());
|
||||
CHECK(types[3]->name == "a3");
|
||||
REQUIRE(types[3]->parentTypes.size() == 1);
|
||||
CHECK(types[3]->parentTypes[0]->declaration == types[0].get());
|
||||
CHECK(types[4]->name == "bx");
|
||||
REQUIRE(types[4]->parentTypes.size() == 3);
|
||||
CHECK(types[4]->parentTypes[0]->declaration == types[1].get());
|
||||
CHECK(types[4]->parentTypes[1]->declaration == types[2].get());
|
||||
CHECK(types[4]->parentTypes[2]->declaration == types[3].get());
|
||||
}
|
||||
|
||||
SECTION("missing domains are detected")
|
||||
{
|
||||
const auto instanceFile = fs::path("data") / "pddl-instances" / "ipc-2000" / "domains" / "blocks-strips-typed" / "instances" / "instance-1.pddl";
|
||||
context.tokenizer.read(instanceFile);
|
||||
CHECK_THROWS(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("mismatched domains are detected")
|
||||
{
|
||||
const auto domainFile = fs::path("data") / "pddl-instances" / "ipc-2000" / "domains" / "blocks-strips-typed" / "domain.pddl";
|
||||
const auto instanceFile = fs::path("data") / "pddl-instances" / "ipc-2000" / "domains" / "freecell-strips-typed" / "instances" / "instance-1.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
context.tokenizer.read(instanceFile);
|
||||
CHECK_THROWS(pddl::parseDescription(context));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("[PDDL parser] Syntax errors are correctly recognized", "[PDDL parser]")
|
||||
{
|
||||
pddl::Tokenizer tokenizer;
|
||||
pddl::Context context(std::move(tokenizer), ignoreWarnings);
|
||||
|
||||
SECTION("valid domain")
|
||||
{
|
||||
const auto domainFile = fs::path("data") / "pddl-syntax" / "domain-valid.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
for (size_t i = 1; i <= 3; i++)
|
||||
SECTION("syntax errors in expressions (" + std::to_string(i) + ")")
|
||||
{
|
||||
const auto domainFile = fs::path("data") / "pddl-syntax" / ("domain-expressions-" + std::to_string(i) + ".pddl");
|
||||
context.tokenizer.read(domainFile);
|
||||
CHECK_THROWS(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
for (size_t i = 1; i <= 3; i++)
|
||||
SECTION("syntax errors in expression names (" + std::to_string(i) + ")")
|
||||
{
|
||||
const auto domainFile = fs::path("data") / "pddl-syntax" / ("domain-expression-name-" + std::to_string(i) + ".pddl");
|
||||
context.tokenizer.read(domainFile);
|
||||
CHECK_THROWS(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
for (size_t i = 1; i <= 8; i++)
|
||||
SECTION("syntax errors with parentheses (" + std::to_string(i) + ")")
|
||||
{
|
||||
const auto domainFile = fs::path("data") / "pddl-syntax" / ("domain-parentheses-" + std::to_string(i) + ".pddl");
|
||||
context.tokenizer.read(domainFile);
|
||||
CHECK_THROWS(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
for (size_t i = 1; i <= 7; i++)
|
||||
SECTION("syntax errors in section names (" + std::to_string(i) + ")")
|
||||
{
|
||||
const auto domainFile = fs::path("data") / "pddl-syntax" / ("domain-section-name-" + std::to_string(i) + ".pddl");
|
||||
context.tokenizer.read(domainFile);
|
||||
CHECK_THROWS(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
for (size_t i = 1; i <= 4; i++)
|
||||
SECTION("syntax errors in types (" + std::to_string(i) + ")")
|
||||
{
|
||||
const auto domainFile = fs::path("data") / "pddl-syntax" / ("domain-types-" + std::to_string(i) + ".pddl");
|
||||
context.tokenizer.read(domainFile);
|
||||
CHECK_THROWS(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
for (size_t i = 1; i <= 3; i++)
|
||||
SECTION("syntax errors in variables (" + std::to_string(i) + ")")
|
||||
{
|
||||
const auto domainFile = fs::path("data") / "pddl-syntax" / ("domain-variables-" + std::to_string(i) + ".pddl");
|
||||
context.tokenizer.read(domainFile);
|
||||
CHECK_THROWS(pddl::parseDescription(context));
|
||||
}
|
||||
}
|
149
lib/pddl/tests/TestSignatureMatching.cpp
Normal file
149
lib/pddl/tests/TestSignatureMatching.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <experimental/filesystem>
|
||||
|
||||
#include <pddl/AST.h>
|
||||
#include <pddl/Parse.h>
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
const pddl::Context::WarningCallback ignoreWarnings = [](const auto &, const auto &){};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("[PDDL signature matching] Predicate signatures are matched correctly", "[PDDL signature matching]")
|
||||
{
|
||||
std::stringstream input;
|
||||
pddl::Tokenizer tokenizer;
|
||||
pddl::Context context(std::move(tokenizer), ignoreWarnings);
|
||||
const auto domainFile = fs::path("data") / "test-cases" / "skeleton.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
|
||||
SECTION("directly matching primitive types")
|
||||
{
|
||||
input
|
||||
<< "(:action test :parameters (?x - a1 ?y - a2 ?z - a3) :precondition (p1 ?x ?y ?z)))";
|
||||
context.tokenizer.read("input", input);
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("derived primitive types (direct children)")
|
||||
{
|
||||
input
|
||||
<< "(:action test :parameters (?x - b1 ?y - b2 ?z - b3) :precondition (p1 ?x ?y ?z)))";
|
||||
context.tokenizer.read("input", input);
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("derived primitive types (indirect children)")
|
||||
{
|
||||
input
|
||||
<< "(:action test :parameters (?x - c1 ?y - c2 ?z - c3) :precondition (p1 ?x ?y ?z)))";
|
||||
context.tokenizer.read("input", input);
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("incompatible primitive types")
|
||||
{
|
||||
input
|
||||
<< "(:action test :parameters (?x - a3 ?y - a2 ?z - a3) :precondition (p1 ?x ?y ?z)))";
|
||||
context.tokenizer.read("input", input);
|
||||
CHECK_THROWS(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("unrelated primitive types")
|
||||
{
|
||||
input
|
||||
<< "(:action test :parameters (?x - b1 ?y - b2 ?z - b1) :precondition (p1 ?x ?y ?z)))";
|
||||
context.tokenizer.read("input", input);
|
||||
CHECK_THROWS(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("incompatible parent types (1)")
|
||||
{
|
||||
input
|
||||
<< "(:action test :parameters (?x - object ?y - b2 ?z - c3) :precondition (p1 ?x ?y ?z)))";
|
||||
context.tokenizer.read("input", input);
|
||||
CHECK_THROWS(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("incompatible parent types (2)")
|
||||
{
|
||||
input
|
||||
<< "(:action test :parameters (?x - a1 ?y - a2 ?z - a3) :precondition (p2 ?x ?y ?z)))";
|
||||
context.tokenizer.read("input", input);
|
||||
CHECK_THROWS(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("matching types with multiple inheritance (1)")
|
||||
{
|
||||
input
|
||||
<< "(:action test :parameters (?x - b1 ?y - b2 ?z - cx) :precondition (p1 ?x ?y ?z)))";
|
||||
context.tokenizer.read("input", input);
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("matching types with multiple inheritance (2)")
|
||||
{
|
||||
input
|
||||
<< "(:action test :parameters (?x - bx ?y - b2 ?z - c3) :precondition (p1 ?x ?y ?z)))";
|
||||
context.tokenizer.read("input", input);
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("“either” type not matching primitive type")
|
||||
{
|
||||
input
|
||||
<< "(:action test :parameters (?x - either (a1 a2) ?y - b2 ?z - c3) :precondition (p1 ?x ?y ?z)))";
|
||||
context.tokenizer.read("input", input);
|
||||
CHECK_THROWS(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("1-ary “either” type matching primitive type")
|
||||
{
|
||||
input
|
||||
<< "(:action test :parameters (?x - (either a1) ?y - a2 ?z - a3) :precondition (p1 ?x ?y ?z)))";
|
||||
context.tokenizer.read("input", input);
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("“either” type directly matching another “either” type")
|
||||
{
|
||||
input
|
||||
<< "(:action test :parameters (?x - (either a1 a2) ?y ?z - (either b1 b3)) :precondition (p3 ?x ?y ?z)))";
|
||||
context.tokenizer.read("input", input);
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("“either” type matching another “either” type via inheritance")
|
||||
{
|
||||
input
|
||||
<< "(:action test :parameters (?x - (either b1 a2) ?y ?z - (either c1 b3)) :precondition (p3 ?x ?y ?z)))";
|
||||
context.tokenizer.read("input", input);
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("“either” type incompatible with another “either” type")
|
||||
{
|
||||
input
|
||||
<< "(:action test :parameters (?x - (either b1 a2) ?y ?z - (either c2 b3)) :precondition (p3 ?x ?y ?z)))";
|
||||
context.tokenizer.read("input", input);
|
||||
CHECK_THROWS(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("“either” type compatible with another “either” type via multiple inheritance")
|
||||
{
|
||||
input
|
||||
<< "(:action test :parameters (?x - (either cx c2) ?y ?z - (either cx c3)) :precondition (p3 ?x ?y ?z)))";
|
||||
context.tokenizer.read("input", input);
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
|
||||
SECTION("constants compatible with “either” type via multiple inheritance")
|
||||
{
|
||||
input
|
||||
<< "(:action test :precondition (p3 cbx cb1 cb3)))";
|
||||
context.tokenizer.read("input", input);
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
}
|
2
lib/pddl/tests/main.cpp
Normal file
2
lib/pddl/tests/main.cpp
Normal file
@@ -0,0 +1,2 @@
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include <catch.hpp>
|
Reference in New Issue
Block a user