Reimplemented plasp with PDDL parsing library.
This commit is contained in:
parent
9c7532bd9d
commit
e345fd60fd
@ -7,6 +7,8 @@ set(includes
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${PROJECT_SOURCE_DIR}/include
|
||||
${PROJECT_SOURCE_DIR}/lib/tokenize/include
|
||||
${PROJECT_SOURCE_DIR}/lib/variant/include
|
||||
${PROJECT_SOURCE_DIR}/lib/pddlparse/include
|
||||
)
|
||||
|
||||
set(sources
|
||||
|
18
app/main.cpp
18
app/main.cpp
@ -4,10 +4,14 @@
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
#include <pddlparse/AST.h>
|
||||
#include <pddlparse/Parse.h>
|
||||
|
||||
#include <plasp/LanguageDetection.h>
|
||||
#include <plasp/output/ColorStream.h>
|
||||
#include <plasp/output/Logger.h>
|
||||
#include <plasp/output/Priority.h>
|
||||
#include <plasp/output/TranslatorException.h>
|
||||
#include <plasp/pddl/Description.h>
|
||||
#include <plasp/pddl/TranslatorASP.h>
|
||||
#include <plasp/sas/Description.h>
|
||||
#include <plasp/sas/TranslatorASP.h>
|
||||
@ -148,9 +152,15 @@ int main(int argc, char **argv)
|
||||
|
||||
if (language == plasp::Language::Type::PDDL)
|
||||
{
|
||||
auto context = plasp::pddl::Context(std::move(tokenizer), logger);
|
||||
auto description = plasp::pddl::Description::fromContext(context);
|
||||
const auto translator = plasp::pddl::TranslatorASP(description, logger.outputStream());
|
||||
const auto logWarning =
|
||||
[&](const auto &location, const auto &warning)
|
||||
{
|
||||
logger.log(plasp::output::Priority::Warning, location, warning);
|
||||
};
|
||||
|
||||
auto context = pddl::Context(std::move(tokenizer), logWarning);
|
||||
auto description = pddl::parseDescription(context);
|
||||
const auto translator = plasp::pddl::TranslatorASP(std::move(description), logger.outputStream());
|
||||
translator.translate();
|
||||
}
|
||||
else if (language == plasp::Language::Type::SAS)
|
||||
|
@ -1,51 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__ACTION_H
|
||||
#define __PLASP__PDDL__ACTION_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <plasp/pddl/Expression.h>
|
||||
#include <plasp/pddl/expressions/Variable.h>
|
||||
|
||||
#include <tokenize/Tokenizer.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Action
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Action
|
||||
{
|
||||
public:
|
||||
static void parseDeclaration(Context &context, Domain &domain);
|
||||
|
||||
public:
|
||||
const std::string &name() const;
|
||||
|
||||
const expressions::Variables ¶meters() const;
|
||||
const Expression *precondition() const;
|
||||
const Expression *effect() const;
|
||||
|
||||
void normalize(expressions::DerivedPredicates &derivedPredicates);
|
||||
|
||||
private:
|
||||
Action() = default;
|
||||
|
||||
std::string m_name;
|
||||
|
||||
expressions::Variables m_parameters;
|
||||
ExpressionPointer m_precondition;
|
||||
ExpressionPointer m_effect;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,57 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__CONSISTENCY_EXCEPTION_H
|
||||
#define __PLASP__PDDL__CONSISTENCY_EXCEPTION_H
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ConsistencyException
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ConsistencyException: public std::exception
|
||||
{
|
||||
public:
|
||||
explicit ConsistencyException()
|
||||
: ConsistencyException("unspecified consistency error")
|
||||
{
|
||||
}
|
||||
|
||||
explicit ConsistencyException(const char *message)
|
||||
: ConsistencyException(static_cast<std::string>(message))
|
||||
{
|
||||
}
|
||||
|
||||
explicit ConsistencyException(const std::string &message)
|
||||
: m_message{message}
|
||||
{
|
||||
}
|
||||
|
||||
~ConsistencyException() throw()
|
||||
{
|
||||
}
|
||||
|
||||
const char *what() const throw()
|
||||
{
|
||||
if (m_message.empty())
|
||||
return "unspecified consistency error";
|
||||
|
||||
return m_message.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_message;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,59 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__CONTEXT_H
|
||||
#define __PLASP__PDDL__CONTEXT_H
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <plasp/output/Logger.h>
|
||||
#include <plasp/pddl/Tokenizer.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Context
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Context
|
||||
{
|
||||
public:
|
||||
Context() = default;
|
||||
~Context() = default;
|
||||
|
||||
explicit Context(Tokenizer &&otherTokenizer, output::Logger &otherLogger)
|
||||
: tokenizer{std::move(otherTokenizer)},
|
||||
logger(otherLogger)
|
||||
{
|
||||
}
|
||||
|
||||
Context(const Context &other) = delete;
|
||||
Context &operator=(const Context &other) = delete;
|
||||
|
||||
Context(Context &&other)
|
||||
: tokenizer(std::move(other.tokenizer)),
|
||||
logger(other.logger)
|
||||
{
|
||||
}
|
||||
|
||||
Context &operator=(Context &&other) = delete;
|
||||
|
||||
constexpr static const char *auxiliaryPrefix()
|
||||
{
|
||||
return "__plasp_";
|
||||
}
|
||||
|
||||
Tokenizer tokenizer;
|
||||
output::Logger &logger;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,60 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__DESCRIPTION_H
|
||||
#define __PLASP__PDDL__DESCRIPTION_H
|
||||
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/pddl/Problem.h>
|
||||
|
||||
#include <tokenize/Tokenizer.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Description
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Description
|
||||
{
|
||||
public:
|
||||
static Description fromContext(Context &context);
|
||||
static Description fromStream(std::istream &istream, Context &context);
|
||||
static Description fromFile(const std::string &path, Context &context);
|
||||
static Description fromFiles(const std::vector<std::string> &paths, Context &context);
|
||||
|
||||
public:
|
||||
Context &context();
|
||||
const Context &context() const;
|
||||
|
||||
const Domain &domain() const;
|
||||
|
||||
bool containsProblem() const;
|
||||
const Problem &problem() const;
|
||||
|
||||
void normalize();
|
||||
|
||||
private:
|
||||
Description(Context &context);
|
||||
|
||||
void parse();
|
||||
void findSections();
|
||||
|
||||
void checkConsistency();
|
||||
|
||||
Context &m_context;
|
||||
|
||||
tokenize::StreamPosition m_domainPosition;
|
||||
std::unique_ptr<Domain> m_domain;
|
||||
tokenize::StreamPosition m_problemPosition;
|
||||
std::unique_ptr<Problem> m_problem;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,101 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__DOMAIN_H
|
||||
#define __PLASP__PDDL__DOMAIN_H
|
||||
|
||||
#include <plasp/pddl/Action.h>
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Expression.h>
|
||||
#include <plasp/pddl/Requirement.h>
|
||||
#include <plasp/pddl/Tokenizer.h>
|
||||
#include <plasp/pddl/expressions/Constant.h>
|
||||
#include <plasp/pddl/expressions/DerivedPredicate.h>
|
||||
#include <plasp/pddl/expressions/PredicateDeclaration.h>
|
||||
#include <plasp/pddl/expressions/PrimitiveType.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Domain
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Domain
|
||||
{
|
||||
public:
|
||||
Domain(Context &context);
|
||||
|
||||
public:
|
||||
void findSections();
|
||||
void parse();
|
||||
|
||||
void setName(std::string name);
|
||||
const std::string &name() const;
|
||||
|
||||
const Requirements &requirements() const;
|
||||
bool hasRequirement(Requirement::Type requirementType) const;
|
||||
void checkRequirement(Requirement::Type requirementType);
|
||||
|
||||
expressions::PrimitiveTypes &types();
|
||||
const expressions::PrimitiveTypes &types() const;
|
||||
|
||||
expressions::Constants &constants();
|
||||
const expressions::Constants &constants() const;
|
||||
|
||||
expressions::PredicateDeclarations &predicates();
|
||||
const expressions::PredicateDeclarations &predicates() const;
|
||||
|
||||
std::vector<std::unique_ptr<Action>> &actions();
|
||||
const std::vector<std::unique_ptr<Action>> &actions() const;
|
||||
|
||||
expressions::DerivedPredicates &derivedPredicates();
|
||||
const expressions::DerivedPredicates &derivedPredicates() const;
|
||||
|
||||
void checkConsistency();
|
||||
|
||||
void normalize();
|
||||
|
||||
private:
|
||||
void parseSection();
|
||||
|
||||
void parseRequirementSection();
|
||||
void computeDerivedRequirements();
|
||||
|
||||
void parseTypeSection();
|
||||
|
||||
void parseConstantSection();
|
||||
|
||||
void parsePredicateSection();
|
||||
|
||||
void parseActionSection();
|
||||
|
||||
Context &m_context;
|
||||
|
||||
std::string m_name;
|
||||
|
||||
tokenize::StreamPosition m_requirementsPosition;
|
||||
Requirements m_requirements;
|
||||
|
||||
tokenize::StreamPosition m_typesPosition;
|
||||
expressions::PrimitiveTypes m_types;
|
||||
|
||||
tokenize::StreamPosition m_constantsPosition;
|
||||
expressions::Constants m_constants;
|
||||
|
||||
tokenize::StreamPosition m_predicatesPosition;
|
||||
expressions::PredicateDeclarations m_predicates;
|
||||
|
||||
std::vector<tokenize::StreamPosition> m_actionPositions;
|
||||
std::vector<std::unique_ptr<Action>> m_actions;
|
||||
|
||||
expressions::DerivedPredicates m_derivedPredicates;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,237 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSION_H
|
||||
#define __PLASP__PDDL__EXPRESSION_H
|
||||
|
||||
#include <iosfwd>
|
||||
#include <set>
|
||||
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
|
||||
#include <tokenize/Tokenizer.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Expression
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Context;
|
||||
class Domain;
|
||||
class ExpressionContext;
|
||||
class ExpressionVisitor;
|
||||
class Problem;
|
||||
|
||||
class Expression;
|
||||
using ExpressionPointer = boost::intrusive_ptr<Expression>;
|
||||
using Expressions = std::vector<ExpressionPointer>;
|
||||
|
||||
namespace expressions
|
||||
{
|
||||
class And;
|
||||
using AndPointer = boost::intrusive_ptr<And>;
|
||||
|
||||
class At;
|
||||
using AtPointer = boost::intrusive_ptr<At>;
|
||||
|
||||
class Constant;
|
||||
using ConstantPointer = boost::intrusive_ptr<Constant>;
|
||||
using Constants = std::vector<ConstantPointer>;
|
||||
|
||||
class DerivedPredicate;
|
||||
using DerivedPredicatePointer = boost::intrusive_ptr<DerivedPredicate>;
|
||||
using DerivedPredicates = std::vector<DerivedPredicatePointer>;
|
||||
|
||||
class Dummy;
|
||||
using DummyPointer = boost::intrusive_ptr<Dummy>;
|
||||
|
||||
class Either;
|
||||
using EitherPointer = boost::intrusive_ptr<Either>;
|
||||
|
||||
class Exists;
|
||||
using ExistsPointer = boost::intrusive_ptr<Exists>;
|
||||
|
||||
class ForAll;
|
||||
using ForAllPointer = boost::intrusive_ptr<ForAll>;
|
||||
|
||||
class Imply;
|
||||
using ImplyPointer = boost::intrusive_ptr<Imply>;
|
||||
|
||||
class Not;
|
||||
using NotPointer = boost::intrusive_ptr<Not>;
|
||||
|
||||
class Or;
|
||||
using OrPointer = boost::intrusive_ptr<Or>;
|
||||
|
||||
class Predicate;
|
||||
using PredicatePointer = boost::intrusive_ptr<Predicate>;
|
||||
using Predicates = std::vector<PredicatePointer>;
|
||||
|
||||
class PredicateDeclaration;
|
||||
using PredicateDeclarationPointer = boost::intrusive_ptr<PredicateDeclaration>;
|
||||
using PredicateDeclarations = std::vector<PredicateDeclarationPointer>;
|
||||
|
||||
class PrimitiveType;
|
||||
using PrimitiveTypePointer = boost::intrusive_ptr<PrimitiveType>;
|
||||
using PrimitiveTypes = std::vector<PrimitiveTypePointer>;
|
||||
|
||||
class Quantified;
|
||||
using QuantifiedPointer = boost::intrusive_ptr<Quantified>;
|
||||
|
||||
template<class Type>
|
||||
class Reference;
|
||||
template<class Type>
|
||||
using ReferencePointer = boost::intrusive_ptr<Reference<Type>>;
|
||||
|
||||
class Unsupported;
|
||||
using UnsupportedPointer = boost::intrusive_ptr<Unsupported>;
|
||||
|
||||
class Variable;
|
||||
using VariablePointer = boost::intrusive_ptr<Variable>;
|
||||
using Variables = std::vector<VariablePointer>;
|
||||
|
||||
class When;
|
||||
using WhenPointer = boost::intrusive_ptr<When>;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Expression
|
||||
{
|
||||
public:
|
||||
enum class Type
|
||||
{
|
||||
And,
|
||||
At,
|
||||
Binary,
|
||||
Constant,
|
||||
DerivedPredicate,
|
||||
Dummy,
|
||||
Either,
|
||||
Exists,
|
||||
ForAll,
|
||||
Imply,
|
||||
Not,
|
||||
Or,
|
||||
PredicateDeclaration,
|
||||
Predicate,
|
||||
PrimitiveType,
|
||||
Reference,
|
||||
Unsupported,
|
||||
Variable,
|
||||
When,
|
||||
};
|
||||
|
||||
public:
|
||||
virtual ~Expression() = default;
|
||||
|
||||
virtual Type expressionType() const = 0;
|
||||
|
||||
template<class T>
|
||||
bool is() const;
|
||||
template<class T>
|
||||
T &as();
|
||||
template<class T>
|
||||
const T &as() const;
|
||||
|
||||
virtual ExpressionPointer copy();
|
||||
|
||||
// Transform into a normal form as used for the translation to ASP
|
||||
ExpressionPointer normalized();
|
||||
// Reduce the set of used expressions (eliminates implications, for instance)
|
||||
virtual ExpressionPointer reduced();
|
||||
// Transform such that only existential (and no universal) quantifiers are used
|
||||
virtual ExpressionPointer existentiallyQuantified();
|
||||
// Simplify the expression equivalently
|
||||
virtual ExpressionPointer simplified();
|
||||
// Decompose expression into derived predicates (eliminate recursively nested expressions)
|
||||
virtual ExpressionPointer decomposed(expressions::DerivedPredicates &derivedPredicates);
|
||||
// Negate the expression
|
||||
ExpressionPointer negated();
|
||||
|
||||
virtual void collectParameters(std::set<expressions::VariablePointer> ¶meters);
|
||||
|
||||
virtual void print(std::ostream &ostream) const = 0;
|
||||
|
||||
private:
|
||||
friend void intrusive_ptr_add_ref(Expression *expression);
|
||||
friend void intrusive_ptr_release(Expression *expression);
|
||||
|
||||
size_t m_referenceCount = 0;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class T>
|
||||
bool Expression::is() const
|
||||
{
|
||||
return expressionType() == T::ExpressionType;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class T>
|
||||
T &Expression::as()
|
||||
{
|
||||
return dynamic_cast<T &>(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class T>
|
||||
const T &Expression::as() const
|
||||
{
|
||||
return dynamic_cast<const T &>(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void intrusive_ptr_add_ref(Expression *expression)
|
||||
{
|
||||
expression->m_referenceCount++;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void intrusive_ptr_release(Expression *expression)
|
||||
{
|
||||
if (--expression->m_referenceCount == 0)
|
||||
delete expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
class ExpressionCRTP: public Expression
|
||||
{
|
||||
public:
|
||||
Type expressionType() const override final
|
||||
{
|
||||
return Derived::ExpressionType;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseLiteral(Context &context, ExpressionContext &expressionContext);
|
||||
ExpressionPointer parseAtomicFormula(Context &context, ExpressionContext &expressionContext);
|
||||
|
||||
ExpressionPointer parsePreconditionExpression(Context &context,
|
||||
ExpressionContext &expressionContext);
|
||||
ExpressionPointer parseExpression(Context &context, ExpressionContext &expressionContext);
|
||||
|
||||
ExpressionPointer parseEffectExpression(Context &context,
|
||||
ExpressionContext &expressionContext);
|
||||
|
||||
ExpressionPointer parseConditionalEffectExpression(Context &context,
|
||||
ExpressionContext &expressionContext);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,39 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSION_CONTEXT_H
|
||||
#define __PLASP__PDDL__EXPRESSION_CONTEXT_H
|
||||
|
||||
#include <plasp/pddl/Expression.h>
|
||||
#include <plasp/pddl/Requirement.h>
|
||||
#include <plasp/pddl/VariableStack.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ExpressionContext
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ExpressionContext
|
||||
{
|
||||
public:
|
||||
ExpressionContext(Domain &domain);
|
||||
ExpressionContext(Domain &domain, Problem *problem);
|
||||
|
||||
bool hasRequirement(Requirement::Type requirementType) const;
|
||||
void checkRequirement(Requirement::Type requirementType) const;
|
||||
|
||||
Domain &domain;
|
||||
Problem *problem;
|
||||
|
||||
VariableStack variables;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,45 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__IO_H
|
||||
#define __PLASP__PDDL__IO_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <plasp/pddl/Tokenizer.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IO
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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
|
@ -1,35 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__INITIAL_STATE_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__INITIAL_STATE_H
|
||||
|
||||
#include <plasp/pddl/Expression.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// InitialState
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class InitialState
|
||||
{
|
||||
public:
|
||||
static std::unique_ptr<InitialState> parseDeclaration(Context &context,
|
||||
ExpressionContext &expressionContext);
|
||||
|
||||
public:
|
||||
const Expressions &facts() const;
|
||||
|
||||
private:
|
||||
Expressions m_facts;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,87 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__PROBLEM_H
|
||||
#define __PLASP__PDDL__PROBLEM_H
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Expression.h>
|
||||
#include <plasp/pddl/InitialState.h>
|
||||
#include <plasp/pddl/Requirement.h>
|
||||
#include <plasp/pddl/Tokenizer.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Problem
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Problem
|
||||
{
|
||||
public:
|
||||
Problem(Context &context, Domain &domain);
|
||||
|
||||
void findSections();
|
||||
void parse();
|
||||
|
||||
Domain &domain();
|
||||
const Domain &domain() const;
|
||||
|
||||
const std::string &name() const;
|
||||
|
||||
const Requirements &requirements() const;
|
||||
bool hasRequirement(Requirement::Type requirementType) const;
|
||||
void checkRequirement(Requirement::Type requirementType);
|
||||
|
||||
expressions::Constants &objects();
|
||||
const expressions::Constants &objects() const;
|
||||
|
||||
InitialState &initialState();
|
||||
const InitialState &initialState() const;
|
||||
|
||||
const Expression &goal() const;
|
||||
|
||||
void checkConsistency();
|
||||
|
||||
void normalize();
|
||||
|
||||
private:
|
||||
void parseRequirementSection();
|
||||
void computeDerivedRequirements();
|
||||
|
||||
void parseDomainSection();
|
||||
|
||||
void parseObjectSection();
|
||||
|
||||
void parseInitialStateSection();
|
||||
|
||||
void parseGoalSection();
|
||||
|
||||
Context &m_context;
|
||||
Domain &m_domain;
|
||||
|
||||
std::string m_name;
|
||||
|
||||
tokenize::StreamPosition m_domainPosition;
|
||||
|
||||
tokenize::StreamPosition m_requirementsPosition;
|
||||
Requirements m_requirements;
|
||||
|
||||
tokenize::StreamPosition m_objectsPosition;
|
||||
expressions::Constants m_objects;
|
||||
|
||||
tokenize::StreamPosition m_initialStatePosition;
|
||||
std::unique_ptr<InitialState> m_initialState;
|
||||
|
||||
tokenize::StreamPosition m_goalPosition;
|
||||
ExpressionPointer m_goal;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,72 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__REQUIREMENT_H
|
||||
#define __PLASP__PDDL__REQUIREMENT_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Requirement
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Requirement;
|
||||
using Requirements = std::vector<Requirement>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Requirement
|
||||
{
|
||||
public:
|
||||
enum class Type
|
||||
{
|
||||
STRIPS,
|
||||
Typing,
|
||||
NegativePreconditions,
|
||||
DisjunctivePreconditions,
|
||||
Equality,
|
||||
ExistentialPreconditions,
|
||||
UniversalPreconditions,
|
||||
QuantifiedPreconditions,
|
||||
ConditionalEffects,
|
||||
Fluents,
|
||||
NumericFluents,
|
||||
ObjectFluents,
|
||||
ADL,
|
||||
DurativeActions,
|
||||
DurationInequalities,
|
||||
ContinuousEffects,
|
||||
DerivedPredicates,
|
||||
TimedInitialLiterals,
|
||||
Preferences,
|
||||
Constraints,
|
||||
ActionCosts,
|
||||
GoalUtilities
|
||||
};
|
||||
|
||||
static Requirement parse(Context &context);
|
||||
|
||||
public:
|
||||
Requirement(Type type);
|
||||
|
||||
Type type() const;
|
||||
|
||||
std::string toPDDL() const;
|
||||
std::string toASP() const;
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,54 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__TOKENIZER_H
|
||||
#define __PLASP__PDDL__TOKENIZER_H
|
||||
|
||||
#include <tokenize/Tokenizer.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Tokenizer
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class PDDLTokenizerPolicy
|
||||
{
|
||||
public:
|
||||
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
|
@ -1,9 +1,10 @@
|
||||
#ifndef __PLASP__PDDL__TRANSLATOR_ASP_H
|
||||
#define __PLASP__PDDL__TRANSLATOR_ASP_H
|
||||
|
||||
#include <plasp/pddl/Description.h>
|
||||
#include <plasp/output/ColorStream.h>
|
||||
|
||||
#include <iosfwd>
|
||||
#include <pddlparse/ASTForward.h>
|
||||
#include <pddlparse/Parse.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
@ -19,7 +20,7 @@ namespace pddl
|
||||
class TranslatorASP
|
||||
{
|
||||
public:
|
||||
explicit TranslatorASP(Description &description, output::ColorStream &outputStream);
|
||||
explicit TranslatorASP(const ::pddl::ast::Description &description, output::ColorStream &outputStream);
|
||||
|
||||
void translate() const;
|
||||
|
||||
@ -27,15 +28,14 @@ class TranslatorASP
|
||||
void translateDomain() const;
|
||||
void translateTypes() const;
|
||||
void translatePredicates() const;
|
||||
void translateDerivedPredicates() const;
|
||||
void translateActions() const;
|
||||
|
||||
void translateProblem() const;
|
||||
void translateInitialState() const;
|
||||
void translateGoal() const;
|
||||
void translateConstants(const std::string &heading, const expressions::Constants &constants) const;
|
||||
void translateConstants(const std::string &heading, const ::pddl::ast::ConstantDeclarations &constants) const;
|
||||
|
||||
Description &m_description;
|
||||
const ::pddl::ast::Description &m_description;
|
||||
output::ColorStream &m_outputStream;
|
||||
};
|
||||
|
||||
|
@ -1,34 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__VARIABLE_STACK_H
|
||||
#define __PLASP__PDDL__VARIABLE_STACK_H
|
||||
|
||||
#include <plasp/pddl/expressions/Variable.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// VariableStack
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class VariableStack
|
||||
{
|
||||
public:
|
||||
void push(expressions::Variables *variables);
|
||||
void pop();
|
||||
|
||||
expressions::VariablePointer parseAndFind(Context &context);
|
||||
|
||||
private:
|
||||
std::vector<expressions::Variables *> m_variableStack;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,36 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__AND_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__AND_H
|
||||
|
||||
#include <plasp/pddl/expressions/NAry.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// And
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class And: public NAry<And>
|
||||
{
|
||||
public:
|
||||
static const Expression::Type ExpressionType = Expression::Type::And;
|
||||
|
||||
static const std::string Identifier;
|
||||
|
||||
public:
|
||||
ExpressionPointer decomposed(DerivedPredicates &derivedPredicates) override;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,112 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__AT_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__AT_H
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Expression.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// At
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class At: public ExpressionCRTP<At>
|
||||
{
|
||||
public:
|
||||
static const Expression::Type ExpressionType = Expression::Type::At;
|
||||
|
||||
template<typename ExpressionParser>
|
||||
static AtPointer parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression);
|
||||
|
||||
static const size_t TimePointStart = std::numeric_limits<size_t>::max();
|
||||
static const size_t TimePointEnd = std::numeric_limits<size_t>::max() - 1;
|
||||
|
||||
public:
|
||||
At();
|
||||
|
||||
ExpressionPointer copy() override;
|
||||
|
||||
size_t timePoint() const;
|
||||
|
||||
void setArgument(ExpressionPointer argument);
|
||||
ExpressionPointer argument() const;
|
||||
|
||||
ExpressionPointer reduced() override;
|
||||
ExpressionPointer existentiallyQuantified() override;
|
||||
ExpressionPointer simplified() override;
|
||||
|
||||
void collectParameters(std::set<VariablePointer> ¶meters) override;
|
||||
|
||||
void print(std::ostream &ostream) const override;
|
||||
|
||||
protected:
|
||||
size_t m_timePoint;
|
||||
|
||||
ExpressionPointer m_argument;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename ExpressionParser>
|
||||
AtPointer At::parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
if (!tokenizer.testAndSkip<std::string>("(")
|
||||
|| !tokenizer.testIdentifierAndSkip("at"))
|
||||
{
|
||||
tokenizer.seek(position);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t timePoint;
|
||||
|
||||
const auto timePointPosition = tokenizer.position();
|
||||
|
||||
if (tokenizer.testIdentifierAndSkip("start"))
|
||||
timePoint = TimePointStart;
|
||||
else if (tokenizer.testIdentifierAndSkip("end"))
|
||||
timePoint = TimePointEnd;
|
||||
else if (tokenizer.probeNumber())
|
||||
{
|
||||
tokenizer.seek(timePointPosition);
|
||||
timePoint = tokenizer.get<size_t>();
|
||||
}
|
||||
else
|
||||
{
|
||||
tokenizer.seek(position);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto expression = AtPointer(new At);
|
||||
|
||||
expression->m_timePoint = timePoint;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Parse argument
|
||||
expression->setArgument(parseExpression(context, expressionContext));
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,195 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__BINARY_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__BINARY_H
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Expression.h>
|
||||
|
||||
#include <plasp/pddl/expressions/Exists.h>
|
||||
#include <plasp/pddl/expressions/ForAll.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Binary
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
class Binary: public ExpressionCRTP<Derived>
|
||||
{
|
||||
public:
|
||||
template<typename ExpressionParser>
|
||||
static boost::intrusive_ptr<Derived> parse(Context &context,
|
||||
ExpressionContext &expressionContext, ExpressionParser parseExpression);
|
||||
|
||||
public:
|
||||
ExpressionPointer copy() override;
|
||||
|
||||
void setArgument(size_t i, ExpressionPointer argument);
|
||||
std::array<ExpressionPointer, 2> &arguments();
|
||||
const std::array<ExpressionPointer, 2> &arguments() const;
|
||||
|
||||
ExpressionPointer reduced() override;
|
||||
ExpressionPointer existentiallyQuantified() override;
|
||||
ExpressionPointer simplified() override;
|
||||
|
||||
void collectParameters(std::set<VariablePointer> ¶meters) override;
|
||||
|
||||
void print(std::ostream &ostream) const override;
|
||||
|
||||
protected:
|
||||
std::array<ExpressionPointer, 2> m_arguments;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
template<typename ExpressionParser>
|
||||
boost::intrusive_ptr<Derived> Binary<Derived>::parse(Context &context,
|
||||
ExpressionContext &expressionContext, ExpressionParser parseExpression)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
if (!tokenizer.testAndSkip<std::string>("(")
|
||||
|| !tokenizer.testIdentifierAndSkip(Derived::Identifier))
|
||||
{
|
||||
tokenizer.seek(position);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto expression = boost::intrusive_ptr<Derived>(new Derived);
|
||||
|
||||
// Parse arguments of the expression
|
||||
expression->Binary<Derived>::setArgument(0, parseExpression(context, expressionContext));
|
||||
expression->Binary<Derived>::setArgument(1, parseExpression(context, expressionContext));
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
ExpressionPointer Binary<Derived>::copy()
|
||||
{
|
||||
auto result = new Derived;
|
||||
|
||||
for (size_t i = 0; i < m_arguments.size(); i++)
|
||||
result->m_arguments[i] = m_arguments[i]->copy();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
void Binary<Derived>::setArgument(size_t i, ExpressionPointer expression)
|
||||
{
|
||||
BOOST_ASSERT_MSG(i <= m_arguments.size(), "Index out of range");
|
||||
|
||||
m_arguments[i] = expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
std::array<ExpressionPointer, 2> &Binary<Derived>::arguments()
|
||||
{
|
||||
return m_arguments;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
const std::array<ExpressionPointer, 2> &Binary<Derived>::arguments() const
|
||||
{
|
||||
return m_arguments;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
inline ExpressionPointer Binary<Derived>::reduced()
|
||||
{
|
||||
for (auto &argument : m_arguments)
|
||||
{
|
||||
BOOST_ASSERT(argument);
|
||||
|
||||
argument = argument->reduced();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
inline ExpressionPointer Binary<Derived>::existentiallyQuantified()
|
||||
{
|
||||
for (auto &argument : m_arguments)
|
||||
{
|
||||
BOOST_ASSERT(argument);
|
||||
|
||||
argument = argument->existentiallyQuantified();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
inline ExpressionPointer Binary<Derived>::simplified()
|
||||
{
|
||||
for (auto &argument : m_arguments)
|
||||
{
|
||||
BOOST_ASSERT(argument);
|
||||
|
||||
argument = argument->simplified();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
inline void Binary<Derived>::collectParameters(std::set<VariablePointer> ¶meters)
|
||||
{
|
||||
for (const auto &argument : m_arguments)
|
||||
argument->collectParameters(parameters);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
inline void Binary<Derived>::print(std::ostream &ostream) const
|
||||
{
|
||||
ostream << "(" << Derived::Identifier;
|
||||
|
||||
std::for_each(m_arguments.begin(), m_arguments.end(),
|
||||
[&](auto &argument)
|
||||
{
|
||||
ostream << " ";
|
||||
argument->print(ostream);
|
||||
});
|
||||
|
||||
ostream << ")";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,64 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__CONSTANT_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__CONSTANT_H
|
||||
|
||||
#include <plasp/pddl/Expression.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constant
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Constant: public ExpressionCRTP<Constant>
|
||||
{
|
||||
public:
|
||||
static const Expression::Type ExpressionType = Expression::Type::Constant;
|
||||
|
||||
static void parseTypedDeclaration(Context &context, Domain &domain);
|
||||
static void parseTypedDeclarations(Context &context, Domain &domain);
|
||||
static void parseTypedDeclaration(Context &context, Problem &problem);
|
||||
static void parseTypedDeclarations(Context &context, Problem &problem);
|
||||
|
||||
static ConstantPointer parseAndFind(Context &context, const Domain &domain);
|
||||
static ConstantPointer parseAndFind(Context &context, const Problem &problem);
|
||||
|
||||
public:
|
||||
const std::string &name() const;
|
||||
PrimitiveTypePointer type() const;
|
||||
|
||||
void print(std::ostream &ostream) const override;
|
||||
|
||||
private:
|
||||
static ConstantPointer parseDeclaration(Context &context);
|
||||
static void parseTypedDeclaration(Context &context, Domain &domain, Constants &constants);
|
||||
|
||||
static ConstantPointer parseAndFind(const std::string &constantName, const Constants &constants);
|
||||
|
||||
Constant();
|
||||
|
||||
void setDirty(bool isDirty = true);
|
||||
bool isDirty() const;
|
||||
|
||||
void setType(PrimitiveTypePointer parentType);
|
||||
|
||||
bool m_isDirty;
|
||||
|
||||
std::string m_name;
|
||||
|
||||
PrimitiveTypePointer m_type;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,59 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__DERIVED_PREDICATE_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__DERIVED_PREDICATE_H
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <plasp/pddl/Expression.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DerivedPredicate
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class DerivedPredicate: public ExpressionCRTP<DerivedPredicate>
|
||||
{
|
||||
public:
|
||||
static const Expression::Type ExpressionType = Expression::Type::DerivedPredicate;
|
||||
|
||||
// TODO: consider implementing parsing functions for compatibility with older PDDL versions
|
||||
|
||||
public:
|
||||
explicit DerivedPredicate(size_t id);
|
||||
|
||||
size_t id() const;
|
||||
|
||||
void setPreconditions(std::vector<Expressions> &&preconditions);
|
||||
const std::vector<Expressions> &preconditions() const;
|
||||
|
||||
const std::set<VariablePointer> ¶meters() const;
|
||||
|
||||
void collectParameters(std::set<VariablePointer> ¶meters) override;
|
||||
|
||||
void print(std::ostream &ostream) const override;
|
||||
|
||||
private:
|
||||
void collectParameters();
|
||||
|
||||
size_t m_id;
|
||||
|
||||
// The arguments are interpreted as a disjunction of conjunctions
|
||||
std::vector<Expressions> m_preconditions;
|
||||
|
||||
std::set<VariablePointer> m_parameters;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,39 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__DUMMY_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__DUMMY_H
|
||||
|
||||
#include <plasp/pddl/Expression.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dummy
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Dummy: public ExpressionCRTP<Dummy>
|
||||
{
|
||||
public:
|
||||
static const Expression::Type ExpressionType = Expression::Type::Dummy;
|
||||
|
||||
public:
|
||||
Dummy(std::string name);
|
||||
|
||||
void print(std::ostream &ostream) const override;
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,33 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__EITHER_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__EITHER_H
|
||||
|
||||
#include <plasp/pddl/expressions/NAry.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Either
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Either: public NAry<Either>
|
||||
{
|
||||
public:
|
||||
static const Expression::Type ExpressionType = Expression::Type::Either;
|
||||
|
||||
static const std::string Identifier;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,33 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__EXISTS_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__EXISTS_H
|
||||
|
||||
#include <plasp/pddl/expressions/Quantified.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Exists
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Exists: public QuantifiedCRTP<Exists>
|
||||
{
|
||||
public:
|
||||
static const Expression::Type ExpressionType = Expression::Type::Exists;
|
||||
|
||||
static const std::string Identifier;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,36 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__FOR_ALL_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__FOR_ALL_H
|
||||
|
||||
#include <plasp/pddl/expressions/Quantified.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ForAll
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ForAll: public QuantifiedCRTP<ForAll>
|
||||
{
|
||||
public:
|
||||
static const Expression::Type ExpressionType = Expression::Type::ForAll;
|
||||
|
||||
static const std::string Identifier;
|
||||
|
||||
public:
|
||||
ExpressionPointer existentiallyQuantified() override;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,36 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__IMPLY_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__IMPLY_H
|
||||
|
||||
#include <plasp/pddl/expressions/Binary.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Imply
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Imply: public Binary<Imply>
|
||||
{
|
||||
public:
|
||||
static const Expression::Type ExpressionType = Expression::Type::Imply;
|
||||
|
||||
static const std::string Identifier;
|
||||
|
||||
public:
|
||||
ExpressionPointer reduced() override;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,239 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__N_ARY_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__N_ARY_H
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Expression.h>
|
||||
|
||||
#include <plasp/pddl/expressions/Exists.h>
|
||||
#include <plasp/pddl/expressions/ForAll.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// NAry
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
class NAry: public ExpressionCRTP<Derived>
|
||||
{
|
||||
public:
|
||||
template<typename ExpressionParser>
|
||||
static boost::intrusive_ptr<Derived> parse(Context &context,
|
||||
ExpressionContext &expressionContext, ExpressionParser parseExpression);
|
||||
|
||||
public:
|
||||
ExpressionPointer copy() override;
|
||||
|
||||
void setArgument(size_t i, ExpressionPointer argument);
|
||||
void addArgument(ExpressionPointer argument);
|
||||
Expressions &arguments();
|
||||
const Expressions &arguments() const;
|
||||
|
||||
ExpressionPointer reduced() override;
|
||||
ExpressionPointer existentiallyQuantified() override;
|
||||
ExpressionPointer simplified() override;
|
||||
|
||||
void collectParameters(std::set<VariablePointer> ¶meters) override;
|
||||
|
||||
void print(std::ostream &ostream) const override;
|
||||
|
||||
protected:
|
||||
Expressions m_arguments;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
template<typename ExpressionParser>
|
||||
boost::intrusive_ptr<Derived> NAry<Derived>::parse(Context &context,
|
||||
ExpressionContext &expressionContext, ExpressionParser parseExpression)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
if (!tokenizer.testAndSkip<std::string>("(")
|
||||
|| !tokenizer.testIdentifierAndSkip(Derived::Identifier))
|
||||
{
|
||||
tokenizer.seek(position);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto expression = boost::intrusive_ptr<Derived>(new Derived);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Parse arguments of the expression
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
expression->addArgument(parseExpression(context, expressionContext));
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
if (expression->m_arguments.empty())
|
||||
context.logger.log(output::Priority::Warning, tokenizer, "“" + Derived::Identifier + "” expressions should not be empty");
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
ExpressionPointer NAry<Derived>::copy()
|
||||
{
|
||||
auto result = new Derived;
|
||||
|
||||
result->m_arguments.resize(m_arguments.size());
|
||||
|
||||
for (size_t i = 0; i < m_arguments.size(); i++)
|
||||
result->m_arguments[i] = m_arguments[i]->copy();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
void NAry<Derived>::setArgument(size_t i, ExpressionPointer expression)
|
||||
{
|
||||
BOOST_ASSERT_MSG(i <= m_arguments.size(), "Index out of range");
|
||||
|
||||
m_arguments[i] = expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
void NAry<Derived>::addArgument(ExpressionPointer argument)
|
||||
{
|
||||
if (!argument)
|
||||
return;
|
||||
|
||||
m_arguments.emplace_back(argument);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
const Expressions &NAry<Derived>::arguments() const
|
||||
{
|
||||
return m_arguments;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
Expressions &NAry<Derived>::arguments()
|
||||
{
|
||||
return m_arguments;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
inline ExpressionPointer NAry<Derived>::reduced()
|
||||
{
|
||||
for (auto &argument : m_arguments)
|
||||
{
|
||||
BOOST_ASSERT(argument);
|
||||
|
||||
argument = argument->reduced();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
inline ExpressionPointer NAry<Derived>::existentiallyQuantified()
|
||||
{
|
||||
for (auto &argument : m_arguments)
|
||||
{
|
||||
BOOST_ASSERT(argument);
|
||||
|
||||
argument = argument->existentiallyQuantified();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
inline ExpressionPointer NAry<Derived>::simplified()
|
||||
{
|
||||
// Associate same-type children, such as (a && (b && c)) == (a && b && c)
|
||||
for (size_t i = 0; i < m_arguments.size();)
|
||||
{
|
||||
auto &argument = m_arguments[i];
|
||||
argument = argument->simplified();
|
||||
|
||||
if (argument->expressionType() != Derived::ExpressionType)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto &nAryExpression = argument->template as<Derived>();
|
||||
|
||||
BOOST_ASSERT(!nAryExpression.arguments().empty());
|
||||
|
||||
// Remove former child by replacing it with the first one of the child
|
||||
m_arguments[i] = nAryExpression.arguments().front();
|
||||
|
||||
// Reserve space for new arguments
|
||||
m_arguments.reserve(m_arguments.size() + nAryExpression.arguments().size() - 1);
|
||||
|
||||
// Copy all but first element
|
||||
m_arguments.insert(m_arguments.end(), nAryExpression.arguments().begin() + 1, nAryExpression.arguments().end());
|
||||
}
|
||||
|
||||
// TODO: recognize tautologies
|
||||
// TODO: introduce/handle boolean values
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
inline void NAry<Derived>::collectParameters(std::set<VariablePointer> ¶meters)
|
||||
{
|
||||
for (const auto &argument : m_arguments)
|
||||
argument->collectParameters(parameters);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
inline void NAry<Derived>::print(std::ostream &ostream) const
|
||||
{
|
||||
ostream << "(" << Derived::Identifier;
|
||||
|
||||
for (const auto &argument : m_arguments)
|
||||
{
|
||||
ostream << " ";
|
||||
argument->print(ostream);
|
||||
}
|
||||
|
||||
ostream << ")";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,85 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__NOT_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__NOT_H
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Expression.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Not
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Not: public ExpressionCRTP<Not>
|
||||
{
|
||||
public:
|
||||
static const Expression::Type ExpressionType = Expression::Type::Not;
|
||||
|
||||
template<typename ExpressionParser>
|
||||
static NotPointer parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression);
|
||||
|
||||
public:
|
||||
Not();
|
||||
|
||||
ExpressionPointer copy() override;
|
||||
|
||||
void setArgument(ExpressionPointer argument);
|
||||
ExpressionPointer argument() const;
|
||||
|
||||
ExpressionPointer reduced() override;
|
||||
ExpressionPointer existentiallyQuantified() override;
|
||||
ExpressionPointer simplified() override;
|
||||
ExpressionPointer decomposed(DerivedPredicates &derivedPredicates) override;
|
||||
|
||||
void collectParameters(std::set<VariablePointer> ¶meters) override;
|
||||
|
||||
void print(std::ostream &ostream) const override;
|
||||
|
||||
protected:
|
||||
ExpressionPointer m_argument;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename ExpressionParser>
|
||||
NotPointer Not::parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
if (!tokenizer.testAndSkip<std::string>("(")
|
||||
|| !tokenizer.testIdentifierAndSkip("not"))
|
||||
{
|
||||
tokenizer.seek(position);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto expression = NotPointer(new Not);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Parse argument
|
||||
expression->setArgument(parseExpression(context, expressionContext));
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,36 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__OR_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__OR_H
|
||||
|
||||
#include <plasp/pddl/expressions/NAry.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Or
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Or: public NAry<Or>
|
||||
{
|
||||
public:
|
||||
static const Expression::Type ExpressionType = Expression::Type::Or;
|
||||
|
||||
static const std::string Identifier;
|
||||
|
||||
public:
|
||||
ExpressionPointer decomposed(DerivedPredicates &derivedPredicates) override;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,56 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__PREDICATE_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__PREDICATE_H
|
||||
|
||||
#include <plasp/pddl/Expression.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Predicate
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Predicate: public ExpressionCRTP<Predicate>
|
||||
{
|
||||
public:
|
||||
static const Expression::Type ExpressionType = Expression::Type::Predicate;
|
||||
|
||||
static PredicatePointer parse(Context &context, ExpressionContext &expressionContext);
|
||||
static PredicatePointer parse(Context &context, const Problem &problem);
|
||||
|
||||
public:
|
||||
const std::string &name() const;
|
||||
const Expressions &arguments() const;
|
||||
|
||||
bool isDeclared() const;
|
||||
|
||||
ExpressionPointer decomposed(DerivedPredicates &derivedPredicates) override;
|
||||
|
||||
void collectParameters(std::set<VariablePointer> ¶meters) override;
|
||||
|
||||
void print(std::ostream &ostream) const override;
|
||||
|
||||
private:
|
||||
Predicate();
|
||||
|
||||
void setDeclared();
|
||||
|
||||
bool m_isDeclared;
|
||||
|
||||
std::string m_name;
|
||||
Expressions m_arguments;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,53 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__PREDICATE_DECLARATION_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__PREDICATE_DECLARATION_H
|
||||
|
||||
#include <plasp/pddl/Expression.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PredicateDeclaration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class PredicateDeclaration: public ExpressionCRTP<PredicateDeclaration>
|
||||
{
|
||||
public:
|
||||
static const Expression::Type ExpressionType = Expression::Type::PredicateDeclaration;
|
||||
|
||||
static void parse(Context &context, Domain &domain);
|
||||
|
||||
public:
|
||||
const std::string &name() const;
|
||||
const Variables ¶meters() const;
|
||||
|
||||
bool isDeclared() const;
|
||||
|
||||
void normalizeParameterNames();
|
||||
|
||||
void print(std::ostream &ostream) const override;
|
||||
|
||||
private:
|
||||
PredicateDeclaration();
|
||||
|
||||
void setDeclared();
|
||||
|
||||
bool m_isDeclared;
|
||||
|
||||
std::string m_name;
|
||||
Variables m_parameters;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,55 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__PRIMITIVE_TYPE_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__PRIMITIVE_TYPE_H
|
||||
|
||||
#include <plasp/pddl/Expression.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PrimitiveType
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class PrimitiveType: public ExpressionCRTP<PrimitiveType>
|
||||
{
|
||||
public:
|
||||
static const Expression::Type ExpressionType = Expression::Type::PrimitiveType;
|
||||
|
||||
static void parseDeclaration(Context &context, Domain &domain);
|
||||
static void parseTypedDeclaration(Context &context, Domain &domain);
|
||||
|
||||
static PrimitiveTypePointer parseAndFind(Context &context, Domain &domain);
|
||||
|
||||
public:
|
||||
PrimitiveType();
|
||||
PrimitiveType(std::string name);
|
||||
|
||||
const std::string &name() const;
|
||||
const PrimitiveTypes &parentTypes() const;
|
||||
|
||||
void print(std::ostream &ostream) const override;
|
||||
|
||||
private:
|
||||
void setDirty(bool isDirty = true);
|
||||
bool isDirty() const;
|
||||
|
||||
bool m_isDirty;
|
||||
|
||||
std::string m_name;
|
||||
|
||||
PrimitiveTypes m_parentTypes;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,250 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__QUANTIFIED_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__QUANTIFIED_H
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Expression.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/expressions/DerivedPredicate.h>
|
||||
#include <plasp/pddl/expressions/Variable.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Quantified
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Quantified: public Expression
|
||||
{
|
||||
public:
|
||||
void setArgument(ExpressionPointer argument);
|
||||
ExpressionPointer argument() const;
|
||||
|
||||
Variables &variables();
|
||||
const Variables &variables() const;
|
||||
|
||||
protected:
|
||||
Variables m_variables;
|
||||
ExpressionPointer m_argument;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
class QuantifiedCRTP: public Quantified
|
||||
{
|
||||
public:
|
||||
template<typename ExpressionParser>
|
||||
static boost::intrusive_ptr<Derived> parse(Context &context,
|
||||
ExpressionContext &expressionContext, ExpressionParser parseExpression);
|
||||
|
||||
public:
|
||||
Type expressionType() const override final
|
||||
{
|
||||
return Derived::ExpressionType;
|
||||
}
|
||||
|
||||
ExpressionPointer copy() override;
|
||||
|
||||
ExpressionPointer reduced() override;
|
||||
ExpressionPointer existentiallyQuantified() override;
|
||||
ExpressionPointer simplified() override;
|
||||
ExpressionPointer decomposed(DerivedPredicates &derivedPredicates) override;
|
||||
|
||||
void collectParameters(std::set<VariablePointer> ¶meters) override;
|
||||
|
||||
void print(std::ostream &ostream) const override;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
template<typename ExpressionParser>
|
||||
boost::intrusive_ptr<Derived> QuantifiedCRTP<Derived>::parse(Context &context,
|
||||
ExpressionContext &expressionContext, ExpressionParser parseExpression)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
if (!tokenizer.testAndSkip<std::string>("(")
|
||||
|| !tokenizer.testIdentifierAndSkip(Derived::Identifier))
|
||||
{
|
||||
tokenizer.seek(position);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto expression = boost::intrusive_ptr<Derived>(new Derived);
|
||||
|
||||
// Parse variable list
|
||||
tokenizer.expect<std::string>("(");
|
||||
Variable::parseTypedDeclarations(context, expressionContext, expression->m_variables);
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
// Push newly parsed variables to the stack
|
||||
expressionContext.variables.push(&expression->m_variables);
|
||||
|
||||
// Parse argument of the expression
|
||||
expression->Quantified::setArgument(parseExpression(context, expressionContext));
|
||||
|
||||
// Clean up variable stack
|
||||
expressionContext.variables.pop();
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
ExpressionPointer QuantifiedCRTP<Derived>::copy()
|
||||
{
|
||||
auto result = new Derived;
|
||||
|
||||
result->m_argument = m_argument->copy();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void Quantified::setArgument(ExpressionPointer expression)
|
||||
{
|
||||
m_argument = expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline ExpressionPointer Quantified::argument() const
|
||||
{
|
||||
return m_argument;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline Variables &Quantified::variables()
|
||||
{
|
||||
return m_variables;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline const Variables &Quantified::variables() const
|
||||
{
|
||||
return m_variables;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
inline ExpressionPointer QuantifiedCRTP<Derived>::reduced()
|
||||
{
|
||||
BOOST_ASSERT(m_argument);
|
||||
|
||||
m_argument = m_argument->reduced();
|
||||
|
||||
// Child quantifiers may not move before this quantifier, the order matters
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
inline ExpressionPointer QuantifiedCRTP<Derived>::existentiallyQuantified()
|
||||
{
|
||||
BOOST_ASSERT(m_argument);
|
||||
|
||||
m_argument = m_argument->existentiallyQuantified();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
inline ExpressionPointer QuantifiedCRTP<Derived>::simplified()
|
||||
{
|
||||
BOOST_ASSERT(m_argument);
|
||||
|
||||
m_argument = m_argument->simplified();
|
||||
|
||||
// Associate same-type children, such as (forall (?x) (forall (?y) (...)))
|
||||
if (m_argument->expressionType() != Derived::ExpressionType)
|
||||
return this;
|
||||
|
||||
auto &quantifiedExpression = m_argument->template as<Derived>();
|
||||
|
||||
// Unify variables
|
||||
m_variables.insert(m_variables.end(), quantifiedExpression.variables().begin(), quantifiedExpression.variables().end());
|
||||
|
||||
// Move child expression up
|
||||
m_argument = quantifiedExpression.argument();
|
||||
|
||||
// TODO: introduce/handle boolean values
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
inline ExpressionPointer QuantifiedCRTP<Derived>::decomposed(DerivedPredicates &derivedPredicates)
|
||||
{
|
||||
derivedPredicates.emplace_back(new DerivedPredicate(derivedPredicates.size()));
|
||||
auto derivedPredicate = derivedPredicates.back();
|
||||
|
||||
m_argument = m_argument->decomposed(derivedPredicates);
|
||||
|
||||
derivedPredicate->setPreconditions({{this}});
|
||||
|
||||
return derivedPredicate;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
inline void QuantifiedCRTP<Derived>::collectParameters(std::set<VariablePointer> ¶meters)
|
||||
{
|
||||
m_argument->collectParameters(parameters);
|
||||
|
||||
// Remove bound variables
|
||||
for (const auto &variable : m_variables)
|
||||
parameters.erase(variable);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
inline void QuantifiedCRTP<Derived>::print(std::ostream &ostream) const
|
||||
{
|
||||
ostream << "(" << Derived::Identifier << " (";
|
||||
|
||||
for (size_t i = 0; i < m_variables.size(); i++)
|
||||
{
|
||||
if (i > 0)
|
||||
ostream << " ";
|
||||
|
||||
m_variables[i]->print(ostream);
|
||||
}
|
||||
|
||||
ostream << ") ";
|
||||
|
||||
m_argument->print(ostream);
|
||||
|
||||
ostream << ")";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,28 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__TYPE_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__TYPE_H
|
||||
|
||||
#include <plasp/pddl/Expression.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Type
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PrimitiveTypePointer parseExistingPrimitiveType(Context &context,
|
||||
ExpressionContext &expressionContext);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,42 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__UNSUPPORTED_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__UNSUPPORTED_H
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Expression.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Unsupported
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Unsupported: public ExpressionCRTP<Unsupported>
|
||||
{
|
||||
public:
|
||||
static const Expression::Type ExpressionType = Expression::Type::Unsupported;
|
||||
|
||||
static UnsupportedPointer parse(Context &context);
|
||||
|
||||
public:
|
||||
const std::string &type() const;
|
||||
|
||||
void print(std::ostream &ostream) const override;
|
||||
|
||||
private:
|
||||
std::string m_type;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,63 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__VARIABLE_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__VARIABLE_H
|
||||
|
||||
#include <plasp/pddl/Expression.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Variable
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Variable: public ExpressionCRTP<Variable>
|
||||
{
|
||||
public:
|
||||
static const Expression::Type ExpressionType = Expression::Type::Variable;
|
||||
|
||||
static void parseTypedDeclaration(Context &context, ExpressionContext &expressionContext,
|
||||
Variables &variables);
|
||||
static void parseTypedDeclarations(Context &context, ExpressionContext &expressionContext,
|
||||
Variables &variables);
|
||||
|
||||
public:
|
||||
Variable();
|
||||
Variable(std::string name);
|
||||
|
||||
void setName(std::string name);
|
||||
const std::string &name() const;
|
||||
|
||||
void setType(ExpressionPointer type);
|
||||
ExpressionPointer type() const;
|
||||
|
||||
void setDirty(bool isDirty = true);
|
||||
bool isDirty() const;
|
||||
|
||||
void collectParameters(std::set<VariablePointer> ¶meters) override;
|
||||
|
||||
void print(std::ostream &ostream) const override;
|
||||
|
||||
private:
|
||||
static void parseDeclaration(Context &context, Variables ¶meters);
|
||||
|
||||
private:
|
||||
bool m_isDirty;
|
||||
|
||||
std::string m_name;
|
||||
|
||||
ExpressionPointer m_type;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,67 +0,0 @@
|
||||
#ifndef __PLASP__PDDL__EXPRESSIONS__WHEN_H
|
||||
#define __PLASP__PDDL__EXPRESSIONS__WHEN_H
|
||||
|
||||
#include <plasp/pddl/expressions/Binary.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// When
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class When: public Binary<When>
|
||||
{
|
||||
public:
|
||||
static const Expression::Type ExpressionType = Expression::Type::When;
|
||||
|
||||
static const std::string Identifier;
|
||||
|
||||
template<typename ConditionExpressionParser, typename ImplicationExpressionParser>
|
||||
static WhenPointer parse(Context &context, ExpressionContext &expressionContext,
|
||||
ConditionExpressionParser parseConditionExpression,
|
||||
ImplicationExpressionParser parseImplicationExpression);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename ConditionExpressionParser, typename ImplicationExpressionParser>
|
||||
WhenPointer When::parse(Context &context, ExpressionContext &expressionContext,
|
||||
ConditionExpressionParser parseConditionExpression,
|
||||
ImplicationExpressionParser parseImplicationExpression)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
if (!tokenizer.testAndSkip<std::string>("(")
|
||||
|| !tokenizer.testIdentifierAndSkip(Identifier))
|
||||
{
|
||||
tokenizer.seek(position);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto expression = WhenPointer(new When);
|
||||
|
||||
// Parse arguments of the expression
|
||||
expression->setArgument(0, parseConditionExpression(context, expressionContext));
|
||||
expression->setArgument(1, parseImplicationExpression(context, expressionContext));
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
79
include/plasp/pddl/translation/Effect.h
Normal file
79
include/plasp/pddl/translation/Effect.h
Normal file
@ -0,0 +1,79 @@
|
||||
#ifndef __PLASP__PDDL__TRANSLATION__EFFECT_H
|
||||
#define __PLASP__PDDL__TRANSLATION__EFFECT_H
|
||||
|
||||
#include <pddlparse/AST.h>
|
||||
|
||||
#include <plasp/output/Formatting.h>
|
||||
#include <plasp/output/TranslatorException.h>
|
||||
|
||||
#include <plasp/pddl/translation/Predicate.h>
|
||||
#include <plasp/pddl/translation/Primitives.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Effect
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename PrintObjectName>
|
||||
inline void translateEffect(output::ColorStream &outputStream, const ::pddl::ast::Effect &effect, const std::string &objectType, PrintObjectName printObjectName)
|
||||
{
|
||||
const auto handleUnsupported =
|
||||
[](const auto &)
|
||||
{
|
||||
throw output::TranslatorException("only “and” expressions and (negated) predicates supported as action effects currently");
|
||||
};
|
||||
|
||||
const auto handlePredicate =
|
||||
[&](const ::pddl::ast::PredicatePointer &predicate, bool isPositive = true)
|
||||
{
|
||||
outputStream << std::endl << output::Function("postcondition") << "(";
|
||||
printObjectName();
|
||||
outputStream
|
||||
<< ", " << output::Keyword("effect") << "("
|
||||
<< output::Reserved("unconditional") << ")"
|
||||
<< ", ";
|
||||
translatePredicateToVariable(outputStream, *predicate, isPositive);
|
||||
outputStream << ") :- " << output::Function(objectType.c_str()) << "(";
|
||||
printObjectName();
|
||||
outputStream << ").";
|
||||
};
|
||||
|
||||
const auto handleAtomicFormula =
|
||||
[&](const ::pddl::ast::AtomicFormula &atomicFormula)
|
||||
{
|
||||
atomicFormula.match(handlePredicate, handleUnsupported);
|
||||
};
|
||||
|
||||
const auto handleNot =
|
||||
[&](const ::pddl::ast::NotPointer<::pddl::ast::Effect> ¬_)
|
||||
{
|
||||
if (!not_->argument.is<::pddl::ast::AtomicFormula>() || !not_->argument.get<::pddl::ast::AtomicFormula>().is<::pddl::ast::PredicatePointer>())
|
||||
handleUnsupported(not_);
|
||||
|
||||
const auto &predicate = not_->argument.get<::pddl::ast::AtomicFormula>().get<::pddl::ast::PredicatePointer>();
|
||||
|
||||
handlePredicate(predicate, false);
|
||||
};
|
||||
|
||||
const auto handleAnd =
|
||||
[&](const ::pddl::ast::AndPointer<::pddl::ast::Effect> &and_)
|
||||
{
|
||||
for (const auto &argument : and_->arguments)
|
||||
translateEffect(outputStream, argument, objectType, printObjectName);
|
||||
};
|
||||
|
||||
effect.match(handleAtomicFormula, handleNot, handleAnd, handleUnsupported);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
72
include/plasp/pddl/translation/Goal.h
Normal file
72
include/plasp/pddl/translation/Goal.h
Normal file
@ -0,0 +1,72 @@
|
||||
#ifndef __PLASP__PDDL__TRANSLATION__GOAL_H
|
||||
#define __PLASP__PDDL__TRANSLATION__GOAL_H
|
||||
|
||||
#include <pddlparse/AST.h>
|
||||
|
||||
#include <plasp/output/Formatting.h>
|
||||
#include <plasp/output/TranslatorException.h>
|
||||
|
||||
#include <plasp/pddl/translation/Predicate.h>
|
||||
#include <plasp/pddl/translation/Primitives.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Goal
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void translateGoal(output::ColorStream &outputStream, const ::pddl::ast::Goal &goal)
|
||||
{
|
||||
const auto handleUnsupported =
|
||||
[](const auto &)
|
||||
{
|
||||
throw output::TranslatorException("only “and” expressions and (negated) predicates supported as goals currently");
|
||||
};
|
||||
|
||||
const auto handlePredicate =
|
||||
[&](const ::pddl::ast::PredicatePointer &predicate, bool isPositive = true)
|
||||
{
|
||||
outputStream << std::endl << output::Function("goal") << "(";
|
||||
// TODO: assert that goal is variable-free
|
||||
translatePredicateToVariable(outputStream, *predicate, isPositive);
|
||||
outputStream << ").";
|
||||
};
|
||||
|
||||
const auto handleAtomicFormula =
|
||||
[&](const ::pddl::ast::AtomicFormula &atomicFormula)
|
||||
{
|
||||
atomicFormula.match(handlePredicate, handleUnsupported);
|
||||
};
|
||||
|
||||
const auto handleNot =
|
||||
[&](const ::pddl::ast::NotPointer<::pddl::ast::Goal> ¬_)
|
||||
{
|
||||
if (!not_->argument.is<::pddl::ast::AtomicFormula>() || !not_->argument.get<::pddl::ast::AtomicFormula>().is<::pddl::ast::PredicatePointer>())
|
||||
handleUnsupported(not_);
|
||||
|
||||
const auto &predicate = not_->argument.get<::pddl::ast::AtomicFormula>().get<::pddl::ast::PredicatePointer>();
|
||||
|
||||
handlePredicate(predicate, false);
|
||||
};
|
||||
|
||||
const auto handleAnd =
|
||||
[&](const ::pddl::ast::AndPointer<::pddl::ast::Goal> &and_)
|
||||
{
|
||||
for (const auto &argument : and_->arguments)
|
||||
translateGoal(outputStream, argument);
|
||||
};
|
||||
|
||||
goal.match(handleAtomicFormula, handleNot, handleAnd, handleUnsupported);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,16 +1,18 @@
|
||||
#ifndef __PLASP__PDDL__TRANSLATION__PRECONDITION_H
|
||||
#define __PLASP__PDDL__TRANSLATION__PRECONDITION_H
|
||||
|
||||
#include <pddlparse/AST.h>
|
||||
|
||||
#include <plasp/output/Formatting.h>
|
||||
#include <plasp/pddl/Description.h>
|
||||
#include <plasp/output/TranslatorException.h>
|
||||
|
||||
#include <plasp/pddl/translation/Predicate.h>
|
||||
#include <plasp/pddl/translation/Primitives.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace translation
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@ -18,57 +20,56 @@ namespace translation
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class PrintObjectName>
|
||||
void translatePreconditionDisjunction(output::ColorStream &outputStream, const std::string &objectType, PrintObjectName printObjectName, const std::vector<Expressions> &preconditionDisjunction);
|
||||
template<class PrintObjectName>
|
||||
void translatePreconditionConjunction(output::ColorStream &outputStream, const std::string &objectType, PrintObjectName printObjectName, size_t disjunctionID, const Expressions &preconditionConjunction);
|
||||
template<class PrintObjectName>
|
||||
void translatePrecondition(output::ColorStream &outputStream, const std::string &objectType, PrintObjectName printObjectName, size_t disjunctionID, const Expression &precondition);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class PrintObjectName>
|
||||
inline void translatePreconditionDisjunction(output::ColorStream &outputStream, const std::string &objectType, PrintObjectName printObjectName, const std::vector<Expressions> &preconditionDisjunction)
|
||||
template<typename PrintObjectName>
|
||||
inline void translatePrecondition(output::ColorStream &outputStream, const ::pddl::ast::Precondition &precondition, const std::string &objectType, PrintObjectName printObjectName)
|
||||
{
|
||||
for (size_t i = 0; i < preconditionDisjunction.size(); i++)
|
||||
translatePreconditionConjunction(outputStream, objectType, printObjectName, i, preconditionDisjunction[i]);
|
||||
const auto handleUnsupported =
|
||||
[](const auto &)
|
||||
{
|
||||
throw output::TranslatorException("only “and” expressions and (negated) predicates supported as action preconditions currently");
|
||||
};
|
||||
|
||||
const auto handlePredicate =
|
||||
[&](const ::pddl::ast::PredicatePointer &predicate, bool isPositive = true)
|
||||
{
|
||||
outputStream << std::endl << output::Function("precondition") << "(";
|
||||
printObjectName();
|
||||
outputStream << ", ";
|
||||
translatePredicateToVariable(outputStream, *predicate, isPositive);
|
||||
outputStream << ") :- " << output::Function(objectType.c_str()) << "(";
|
||||
printObjectName();
|
||||
outputStream << ").";
|
||||
};
|
||||
|
||||
const auto handleAtomicFormula =
|
||||
[&](const ::pddl::ast::AtomicFormula &atomicFormula)
|
||||
{
|
||||
atomicFormula.match(handlePredicate, handleUnsupported);
|
||||
};
|
||||
|
||||
const auto handleNot =
|
||||
[&](const ::pddl::ast::NotPointer<::pddl::ast::Precondition> ¬_)
|
||||
{
|
||||
if (!not_->argument.is<::pddl::ast::AtomicFormula>() || !not_->argument.get<::pddl::ast::AtomicFormula>().is<::pddl::ast::PredicatePointer>())
|
||||
handleUnsupported(not_);
|
||||
|
||||
const auto &predicate = not_->argument.get<::pddl::ast::AtomicFormula>().get<::pddl::ast::PredicatePointer>();
|
||||
|
||||
handlePredicate(predicate, false);
|
||||
};
|
||||
|
||||
const auto handleAnd =
|
||||
[&](const ::pddl::ast::AndPointer<::pddl::ast::Precondition> &and_)
|
||||
{
|
||||
for (const auto &argument : and_->arguments)
|
||||
translatePrecondition(outputStream, argument, objectType, printObjectName);
|
||||
};
|
||||
|
||||
precondition.match(handleAtomicFormula, handleNot, handleAnd, handleUnsupported);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class PrintObjectName>
|
||||
inline void translatePreconditionConjunction(output::ColorStream &outputStream, const std::string &objectType, PrintObjectName printObjectName, size_t disjunctionID, const Expressions &preconditionConjunction)
|
||||
{
|
||||
for (size_t i = 0; i < preconditionConjunction.size(); i++)
|
||||
translatePrecondition(outputStream, objectType, printObjectName, disjunctionID, *preconditionConjunction[i]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class PrintObjectName>
|
||||
inline void translatePrecondition(output::ColorStream &outputStream, const std::string &objectType, PrintObjectName printObjectName, size_t disjunctionID, const Expression &precondition)
|
||||
{
|
||||
outputStream << std::endl << output::Function("precondition") << "(";
|
||||
|
||||
printObjectName(outputStream);
|
||||
|
||||
outputStream
|
||||
<< ", " << output::Keyword("disjunct")
|
||||
<< "(" << output::Number<decltype(disjunctionID)>(disjunctionID)
|
||||
<< "), ";
|
||||
|
||||
translateLiteral(outputStream, precondition);
|
||||
|
||||
outputStream << ") :- " << output::Function(objectType.c_str()) << "(";
|
||||
|
||||
printObjectName(outputStream);
|
||||
|
||||
outputStream << ").";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,18 @@
|
||||
#ifndef __PLASP__PDDL__TRANSLATION__PREDICATE_H
|
||||
#define __PLASP__PDDL__TRANSLATION__PREDICATE_H
|
||||
|
||||
#include <pddlparse/AST.h>
|
||||
#include <pddlparse/Parse.h>
|
||||
|
||||
#include <plasp/output/Formatting.h>
|
||||
#include <plasp/pddl/expressions/Constant.h>
|
||||
#include <plasp/pddl/expressions/DerivedPredicate.h>
|
||||
#include <plasp/pddl/expressions/Predicate.h>
|
||||
#include <plasp/pddl/expressions/PredicateDeclaration.h>
|
||||
#include <plasp/pddl/expressions/Variable.h>
|
||||
|
||||
#include <plasp/pddl/translation/Primitives.h>
|
||||
#include <plasp/pddl/translation/Variables.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace translation
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@ -22,44 +20,46 @@ namespace translation
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void translatePredicate(output::ColorStream &outputStream, const expressions::Predicate &predicate);
|
||||
void translateDerivedPredicate(output::ColorStream &outputStream, const expressions::DerivedPredicate &derivedPredicate);
|
||||
void printPredicateName(output::ColorStream &outputStream, const expressions::PredicateDeclaration &predicateDeclaration);
|
||||
void printDerivedPredicateName(output::ColorStream &outputStream, const expressions::DerivedPredicate &derivedPredicate);
|
||||
void translatePredicate(output::ColorStream &outputStream, const ::pddl::ast::Predicate &predicate);
|
||||
void translatePredicateDeclaration(output::ColorStream &outputStream, const ::pddl::ast::PredicateDeclaration &predicateDeclaration);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void translatePredicate(output::ColorStream &outputStream, const expressions::Predicate &predicate)
|
||||
inline void translatePredicate(output::ColorStream &outputStream, const ::pddl::ast::Predicate &predicate)
|
||||
{
|
||||
const auto &arguments = predicate.arguments();
|
||||
const auto &arguments = predicate.arguments;
|
||||
|
||||
if (arguments.empty())
|
||||
{
|
||||
outputStream << output::String(predicate.name().c_str());
|
||||
|
||||
outputStream << *predicate.declaration;
|
||||
return;
|
||||
}
|
||||
|
||||
outputStream << "(" << output::String(predicate.name().c_str());
|
||||
outputStream << "(" << *predicate.declaration;
|
||||
|
||||
for (const auto &argument : arguments)
|
||||
{
|
||||
outputStream << ", ";
|
||||
|
||||
if (argument->is<expressions::Constant>())
|
||||
{
|
||||
const auto &constant = argument->as<expressions::Constant>();
|
||||
const auto handleConstant =
|
||||
[&](const ::pddl::ast::ConstantPointer &constant)
|
||||
{
|
||||
outputStream << output::Keyword("constant") << "(" << *constant << ")";
|
||||
};
|
||||
|
||||
outputStream << output::Keyword("constant") << "(" << output::String(constant.name().c_str()) << ")";
|
||||
}
|
||||
else if (argument->is<expressions::Variable>())
|
||||
{
|
||||
const auto &variable = argument->as<expressions::Variable>();
|
||||
const auto handleVariable =
|
||||
[&](const ::pddl::ast::VariablePointer &variable)
|
||||
{
|
||||
outputStream << *variable;
|
||||
};
|
||||
|
||||
outputStream << output::Variable(variable.name().c_str());
|
||||
}
|
||||
else
|
||||
throw output::TranslatorException("only variables and constants supported in predicates currently");
|
||||
const auto handleUnsupported =
|
||||
[&](const auto &)
|
||||
{
|
||||
throw output::TranslatorException("only variables and constants supported in predicates currently");
|
||||
};
|
||||
|
||||
argument.match(handleConstant, handleVariable, handleUnsupported);
|
||||
}
|
||||
|
||||
outputStream << ")";
|
||||
@ -67,64 +67,41 @@ inline void translatePredicate(output::ColorStream &outputStream, const expressi
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void translateDerivedPredicate(output::ColorStream &outputStream, const expressions::DerivedPredicate &derivedPredicate)
|
||||
{
|
||||
const auto ¶meters = derivedPredicate.parameters();
|
||||
const auto id = derivedPredicate.id();
|
||||
|
||||
if (parameters.empty())
|
||||
{
|
||||
outputStream << output::Number<decltype(id)>(id);
|
||||
return;
|
||||
}
|
||||
|
||||
outputStream << "(" << output::Number<decltype(id)>(id);
|
||||
|
||||
for (const auto ¶meter : parameters)
|
||||
outputStream << ", " << output::Variable(parameter->name().c_str());
|
||||
|
||||
outputStream << ")";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void printPredicateName(output::ColorStream &outputStream, const expressions::PredicateDeclaration &predicateDeclaration)
|
||||
inline void translatePredicateDeclaration(output::ColorStream &outputStream, const ::pddl::ast::PredicateDeclaration &predicateDeclaration)
|
||||
{
|
||||
outputStream << output::Keyword("variable") << "(";
|
||||
|
||||
if (predicateDeclaration.parameters().empty())
|
||||
if (predicateDeclaration.parameters.empty())
|
||||
{
|
||||
outputStream << output::String(predicateDeclaration.name().c_str()) << ")";
|
||||
outputStream << predicateDeclaration << ")";
|
||||
return;
|
||||
}
|
||||
|
||||
outputStream << "(" << output::String(predicateDeclaration.name().c_str());
|
||||
translation::translateVariablesForRuleHead(outputStream, predicateDeclaration.parameters());
|
||||
outputStream << "(" << predicateDeclaration;
|
||||
translateVariablesForRuleHead(outputStream, predicateDeclaration.parameters);
|
||||
outputStream << "))";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void printDerivedPredicateName(output::ColorStream &outputStream, const expressions::DerivedPredicate &derivedPredicate)
|
||||
void translatePredicateToVariable(output::ColorStream &outputStream, const ::pddl::ast::Predicate &predicate, bool isPositive = true)
|
||||
{
|
||||
outputStream << output::Keyword("derivedVariable") << "(";
|
||||
outputStream << output::Keyword("variable") << "(";
|
||||
translatePredicate(outputStream, predicate);
|
||||
outputStream << "), " << output::Keyword("value") << "(";
|
||||
translatePredicate(outputStream, predicate);
|
||||
outputStream << ", ";
|
||||
|
||||
const auto id = derivedPredicate.id();
|
||||
if (isPositive)
|
||||
outputStream << output::Boolean("true");
|
||||
else
|
||||
outputStream << output::Boolean("false");
|
||||
|
||||
if (derivedPredicate.parameters().empty())
|
||||
{
|
||||
outputStream << output::Number<decltype(id)>(id) << ")";
|
||||
return;
|
||||
}
|
||||
|
||||
outputStream << "(" << output::Number<decltype(id)>(id);
|
||||
translation::translateVariablesForRuleHead(outputStream, derivedPredicate.parameters());
|
||||
outputStream << "))";
|
||||
outputStream << ")";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,15 @@
|
||||
#ifndef __PLASP__PDDL__TRANSLATION__PRIMITIVES_H
|
||||
#define __PLASP__PDDL__TRANSLATION__PRIMITIVES_H
|
||||
|
||||
#include <pddlparse/AST.h>
|
||||
|
||||
#include <plasp/output/Formatting.h>
|
||||
#include <plasp/output/TranslatorException.h>
|
||||
#include <plasp/pddl/Description.h>
|
||||
#include <plasp/pddl/expressions/Not.h>
|
||||
#include <plasp/pddl/expressions/Predicate.h>
|
||||
#include <plasp/pddl/translation/Predicate.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace translation
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@ -21,56 +17,91 @@ namespace translation
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void translateLiteral(output::ColorStream &outputStream, const Expression &literal);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void translateLiteral(output::ColorStream &outputStream, const Expression &literal)
|
||||
inline output::ColorStream &operator<<(output::ColorStream &stream, const ::pddl::ast::ConstantDeclaration &constantDeclaration)
|
||||
{
|
||||
// Translate single predicate
|
||||
if (literal.is<expressions::Predicate>())
|
||||
{
|
||||
const auto &predicate = literal.as<expressions::Predicate>();
|
||||
assert(!constantDeclaration.name.empty());
|
||||
|
||||
outputStream << output::Keyword("variable") << "(";
|
||||
translation::translatePredicate(outputStream, predicate);
|
||||
outputStream << "), " << output::Keyword("value") << "(";
|
||||
translation::translatePredicate(outputStream, predicate);
|
||||
outputStream << ", " << output::Boolean("true") << ")";
|
||||
}
|
||||
// Assuming that "not" expression may only contain a predicate
|
||||
else if (literal.is<expressions::Not>())
|
||||
{
|
||||
const auto ¬Expression = literal.as<expressions::Not>();
|
||||
|
||||
if (notExpression.argument()->expressionType() != Expression::Type::Predicate)
|
||||
throw output::TranslatorException("only negations of primitive predicates supported as literals currently");
|
||||
|
||||
const auto &predicate = notExpression.argument()->as<expressions::Predicate>();
|
||||
|
||||
outputStream << output::Keyword("variable") << "(";
|
||||
translation::translatePredicate(outputStream, predicate);
|
||||
outputStream << "), " << output::Keyword("value") << "(";
|
||||
translation::translatePredicate(outputStream, predicate);
|
||||
outputStream << ", " << output::Boolean("false") << ")";
|
||||
}
|
||||
else if (literal.is<expressions::DerivedPredicate>())
|
||||
{
|
||||
const auto &derivedPredicate = literal.as<expressions::DerivedPredicate>();
|
||||
|
||||
outputStream << output::Keyword("derivedVariable") << "(";
|
||||
translation::translateDerivedPredicate(outputStream, derivedPredicate);
|
||||
outputStream << "), " << output::Keyword("value") << "(";
|
||||
translation::translateDerivedPredicate(outputStream, derivedPredicate);
|
||||
outputStream << ", " << output::Boolean("true") << ")";
|
||||
}
|
||||
else
|
||||
throw output::TranslatorException("only primitive predicates and their negations supported as literals currently");
|
||||
return (stream << output::String(constantDeclaration.name.c_str()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline output::ColorStream &operator<<(output::ColorStream &stream, const ::pddl::ast::Constant &constant)
|
||||
{
|
||||
assert(constant.declaration != nullptr);
|
||||
|
||||
return (stream << *constant.declaration);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline output::ColorStream &operator<<(output::ColorStream &stream, const ::pddl::ast::PrimitiveTypeDeclaration &primitiveTypeDeclaration)
|
||||
{
|
||||
assert(!primitiveTypeDeclaration.name.empty());
|
||||
|
||||
return (stream << output::String(primitiveTypeDeclaration.name.c_str()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline output::ColorStream &operator<<(output::ColorStream &stream, const ::pddl::ast::PrimitiveType &primitiveType)
|
||||
{
|
||||
assert(primitiveType.declaration != nullptr);
|
||||
|
||||
return (stream << *primitiveType.declaration);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline output::ColorStream &operator<<(output::ColorStream &stream, ::pddl::ast::VariableDeclaration &variableDeclaration)
|
||||
{
|
||||
assert(!variableDeclaration.name.empty());
|
||||
assert(std::isalpha(variableDeclaration.name[0]));
|
||||
|
||||
if (!std::isupper(variableDeclaration.name[0]))
|
||||
variableDeclaration.name[0] = std::toupper(variableDeclaration.name[0]);
|
||||
|
||||
return (stream
|
||||
<< output::Format({output::Color::Green, output::FontWeight::Bold})
|
||||
<< variableDeclaration.name
|
||||
<< output::ResetFormat());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline output::ColorStream &operator<<(output::ColorStream &stream, ::pddl::ast::Variable &variable)
|
||||
{
|
||||
assert(variable.declaration != nullptr);
|
||||
|
||||
return (stream << *variable.declaration);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: move to appropriate header
|
||||
inline output::ColorStream &operator<<(output::ColorStream &stream, const ::pddl::ast::Action &action)
|
||||
{
|
||||
return (stream << output::String(action.name.c_str()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: move to appropriate header
|
||||
inline output::ColorStream &operator<<(output::ColorStream &stream, const ::pddl::ast::PredicateDeclaration &predicateDeclaration)
|
||||
{
|
||||
return (stream << output::String(predicateDeclaration.name.c_str()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: move to appropriate header
|
||||
inline output::ColorStream &operator<<(output::ColorStream &stream, const ::pddl::ast::Predicate &predicate)
|
||||
{
|
||||
return (stream << *predicate.declaration);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
#ifndef __PLASP__PDDL__TRANSLATION__VARIABLES_H
|
||||
#define __PLASP__PDDL__TRANSLATION__VARIABLES_H
|
||||
|
||||
#include <pddlparse/AST.h>
|
||||
#include <pddlparse/Parse.h>
|
||||
|
||||
#include <plasp/output/Formatting.h>
|
||||
#include <plasp/output/TranslatorException.h>
|
||||
|
||||
@ -8,8 +11,6 @@ namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace translation
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@ -30,12 +31,8 @@ inline void translateVariablesForRuleHead(output::ColorStream &outputStream, con
|
||||
if (variables.empty())
|
||||
return;
|
||||
|
||||
for (auto i = variables.cbegin(); i != variables.cend(); i++)
|
||||
{
|
||||
const auto &variable = **i;
|
||||
|
||||
outputStream << ", " << output::Variable(variable.name().c_str());
|
||||
}
|
||||
for (const auto &variable : variables)
|
||||
outputStream << ", " << *variable;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -48,28 +45,25 @@ inline void translateVariablesForRuleBody(output::ColorStream &outputStream, con
|
||||
|
||||
outputStream << " :- ";
|
||||
|
||||
for (auto i = variables.cbegin(); i != variables.cend(); i++)
|
||||
for (const auto &variable : variables)
|
||||
{
|
||||
const auto &variable = **i;
|
||||
|
||||
if (i != variables.cbegin())
|
||||
if (variable.get() != variables.begin()->get())
|
||||
outputStream << ", ";
|
||||
|
||||
if (variable.type() != nullptr)
|
||||
if (variable->type)
|
||||
{
|
||||
if (variable.type()->expressionType() != Expression::Type::PrimitiveType)
|
||||
if (!variable->type.value().template is<::pddl::ast::PrimitiveTypePointer>())
|
||||
throw output::TranslatorException("only primitive types supported currently");
|
||||
|
||||
const auto &type = variable.type()->template as<expressions::PrimitiveType>();
|
||||
const auto &type = variable->type.value().template get<::pddl::ast::PrimitiveTypePointer>();
|
||||
|
||||
outputStream << output::Function("has") << "("
|
||||
<< output::Variable(variable.name().c_str()) << ", "
|
||||
<< output::Keyword("type") << "(" << output::String(type.name().c_str()) << "))";
|
||||
<< *variable << ", " << output::Keyword("type") << "(" << *type << "))";
|
||||
}
|
||||
else
|
||||
{
|
||||
outputStream << output::Function("has") << "("
|
||||
<< output::Variable(variable.name().c_str()) << ", "
|
||||
<< *variable << ", "
|
||||
<< output::Keyword("type") << "(" << output::String("object") << "))";
|
||||
}
|
||||
}
|
||||
@ -77,7 +71,6 @@ inline void translateVariablesForRuleBody(output::ColorStream &outputStream, con
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,8 @@ set(includes
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${PROJECT_SOURCE_DIR}/include
|
||||
${PROJECT_SOURCE_DIR}/lib/tokenize/include
|
||||
${PROJECT_SOURCE_DIR}/lib/variant/include
|
||||
${PROJECT_SOURCE_DIR}/lib/pddlparse/include
|
||||
)
|
||||
|
||||
set(sources
|
||||
@ -59,6 +61,7 @@ set(sources
|
||||
set(libraries
|
||||
${Boost_LIBRARIES}
|
||||
tokenize
|
||||
pddlparse
|
||||
pthread
|
||||
)
|
||||
|
||||
|
@ -1,118 +0,0 @@
|
||||
#include <plasp/pddl/Action.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/expressions/Type.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Action
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Action::parseDeclaration(Context &context, Domain &domain)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
auto action = std::make_unique<Action>(Action());
|
||||
|
||||
action->m_name = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.expect<std::string>(":parameters");
|
||||
tokenizer.expect<std::string>("(");
|
||||
|
||||
ExpressionContext expressionContext(domain);
|
||||
expressionContext.variables.push(&action->m_parameters);
|
||||
|
||||
// Read parameters
|
||||
expressions::Variable::parseTypedDeclarations(context, expressionContext, action->m_parameters);
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
// Parse preconditions and effects
|
||||
while (!tokenizer.testAndReturn(')'))
|
||||
{
|
||||
tokenizer.expect<std::string>(":");
|
||||
|
||||
if (tokenizer.testIdentifierAndSkip("precondition"))
|
||||
action->m_precondition = parsePreconditionExpression(context, expressionContext);
|
||||
else if (tokenizer.testIdentifierAndSkip("effect"))
|
||||
action->m_effect = parseEffectExpression(context, expressionContext);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
// Store new action
|
||||
expressionContext.domain.actions().emplace_back(std::move(action));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string &Action::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const expressions::Variables &Action::parameters() const
|
||||
{
|
||||
return m_parameters;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const Expression *Action::precondition() const
|
||||
{
|
||||
BOOST_ASSERT(m_precondition);
|
||||
|
||||
return m_precondition.get();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const Expression *Action::effect() const
|
||||
{
|
||||
BOOST_ASSERT(m_effect);
|
||||
|
||||
return m_effect.get();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Action::normalize(expressions::DerivedPredicates &derivedPredicates)
|
||||
{
|
||||
// Normalize preconditions and effects
|
||||
m_precondition = m_precondition->normalized()->decomposed(derivedPredicates);
|
||||
{
|
||||
m_precondition->print(std::cout);
|
||||
|
||||
// TODO: refactor
|
||||
std::set<expressions::VariablePointer> parameters;
|
||||
m_precondition->collectParameters(parameters);
|
||||
}
|
||||
|
||||
m_effect = m_effect->normalized();
|
||||
{
|
||||
// TODO: refactor
|
||||
std::set<expressions::VariablePointer> parameters;
|
||||
m_effect->collectParameters(parameters);
|
||||
}
|
||||
|
||||
// Normalize parameter names
|
||||
for (size_t i = 0; i < m_parameters.size(); i++)
|
||||
m_parameters[i]->setName("X" + std::to_string(i));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
@ -1,220 +0,0 @@
|
||||
#include <plasp/pddl/Description.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include <plasp/pddl/ConsistencyException.h>
|
||||
#include <plasp/pddl/IO.h>
|
||||
|
||||
#include <tokenize/TokenizerException.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Description
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Description::Description(Context &context)
|
||||
: m_context(context),
|
||||
m_domainPosition{tokenize::InvalidStreamPosition},
|
||||
m_domain{std::make_unique<Domain>(Domain(m_context))},
|
||||
m_problemPosition{tokenize::InvalidStreamPosition}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Description Description::fromContext(Context &context)
|
||||
{
|
||||
Description description(context);
|
||||
|
||||
description.parse();
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Description Description::fromStream(std::istream &istream, Context &context)
|
||||
{
|
||||
Description description(context);
|
||||
|
||||
description.m_context.tokenizer.read("std::cin", istream);
|
||||
description.parse();
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Description Description::fromFile(const std::string &path, Context &context)
|
||||
{
|
||||
Description description(context);
|
||||
|
||||
description.m_context.tokenizer.read(path);
|
||||
description.parse();
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Description Description::fromFiles(const std::vector<std::string> &paths, Context &context)
|
||||
{
|
||||
BOOST_ASSERT(!paths.empty());
|
||||
|
||||
// TODO: handle dirty context objects (for instance, reused context objects in unit tests)
|
||||
|
||||
Description description(context);
|
||||
|
||||
std::for_each(paths.cbegin(), paths.cend(),
|
||||
[&](const auto &path)
|
||||
{
|
||||
description.m_context.tokenizer.read(path);
|
||||
});
|
||||
|
||||
description.parse();
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Context &Description::context()
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const Context &Description::context() const
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const Domain &Description::domain() const
|
||||
{
|
||||
BOOST_ASSERT(m_domain);
|
||||
|
||||
return *m_domain;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Description::containsProblem() const
|
||||
{
|
||||
return m_problem.get() != nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const Problem &Description::problem() const
|
||||
{
|
||||
BOOST_ASSERT(m_problem);
|
||||
|
||||
return *m_problem;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Description::parse()
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.removeComments(";", "\n", false);
|
||||
|
||||
// First, determine the locations of domain and problem
|
||||
findSections();
|
||||
|
||||
if (m_domainPosition == tokenize::InvalidStreamPosition)
|
||||
throw ConsistencyException("no PDDL domain specified");
|
||||
|
||||
tokenizer.seek(m_domainPosition);
|
||||
m_domain->parse();
|
||||
|
||||
if (m_problemPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_problemPosition);
|
||||
m_problem->parse();
|
||||
}
|
||||
|
||||
checkConsistency();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Description::findSections()
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
while (!tokenizer.atEnd())
|
||||
{
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>("define");
|
||||
tokenizer.expect<std::string>("(");
|
||||
|
||||
if (tokenizer.testAndSkip<std::string>("domain"))
|
||||
{
|
||||
if (m_domainPosition != tokenize::InvalidStreamPosition)
|
||||
throw tokenize::TokenizerException(tokenizer, "PDDL description may not contain two domains");
|
||||
|
||||
m_domainPosition = position;
|
||||
|
||||
tokenizer.seek(position);
|
||||
m_domain->findSections();
|
||||
}
|
||||
else if (tokenizer.testAndSkip<std::string>("problem"))
|
||||
{
|
||||
if (m_problemPosition != tokenize::InvalidStreamPosition)
|
||||
throw tokenize::TokenizerException(tokenizer, "PDDL description may currently not contain two problems");
|
||||
|
||||
m_problem = std::make_unique<Problem>(Problem(m_context, *m_domain));
|
||||
|
||||
m_problemPosition = position;
|
||||
|
||||
tokenizer.seek(position);
|
||||
m_problem->findSections();
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto sectionIdentifier = tokenizer.get<std::string>();
|
||||
throw tokenize::TokenizerException(tokenizer, "unknown PDDL section “" + sectionIdentifier + "”");
|
||||
}
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Description::checkConsistency()
|
||||
{
|
||||
m_domain->checkConsistency();
|
||||
m_problem->checkConsistency();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Description::normalize()
|
||||
{
|
||||
m_domain->normalize();
|
||||
|
||||
if (m_problem)
|
||||
m_problem->normalize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
@ -1,451 +0,0 @@
|
||||
#include <plasp/pddl/Domain.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <plasp/pddl/ConsistencyException.h>
|
||||
#include <plasp/pddl/IO.h>
|
||||
#include <plasp/pddl/expressions/Constant.h>
|
||||
#include <plasp/pddl/expressions/PredicateDeclaration.h>
|
||||
#include <plasp/pddl/expressions/PrimitiveType.h>
|
||||
#include <plasp/pddl/expressions/Variable.h>
|
||||
|
||||
#include <tokenize/TokenizerException.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Domain
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Domain::Domain(Context &context)
|
||||
: m_context(context),
|
||||
m_requirementsPosition{tokenize::InvalidStreamPosition},
|
||||
m_typesPosition{tokenize::InvalidStreamPosition},
|
||||
m_constantsPosition{tokenize::InvalidStreamPosition},
|
||||
m_predicatesPosition{tokenize::InvalidStreamPosition}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Domain::findSections()
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>("define");
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>("domain");
|
||||
|
||||
m_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 tokenize::TokenizerException(tokenizer, "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>(":");
|
||||
|
||||
const auto sectionIdentifierPosition = tokenizer.position();
|
||||
|
||||
// Save the tokenizer 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(-1);
|
||||
setSectionPosition("action", m_actionPositions.back(), position);
|
||||
}
|
||||
else if (tokenizer.testIdentifierAndSkip("functions")
|
||||
|| tokenizer.testIdentifierAndSkip("constraints")
|
||||
|| tokenizer.testIdentifierAndSkip("durative-action")
|
||||
|| tokenizer.testIdentifierAndSkip("derived"))
|
||||
{
|
||||
tokenizer.seek(sectionIdentifierPosition);
|
||||
|
||||
const auto sectionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
m_context.logger.log(output::Priority::Warning, tokenizer, "section type “" + sectionIdentifier + "” currently unsupported");
|
||||
|
||||
tokenizer.seek(sectionIdentifierPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto sectionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.seek(position);
|
||||
throw tokenize::TokenizerException(tokenizer, "unknown domain section “" + sectionIdentifier + "”");
|
||||
}
|
||||
|
||||
// Skip section for now and parse it later
|
||||
skipSection(tokenizer);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Domain::parse()
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
if (m_requirementsPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_requirementsPosition);
|
||||
parseRequirementSection();
|
||||
}
|
||||
|
||||
if (m_typesPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_typesPosition);
|
||||
parseTypeSection();
|
||||
}
|
||||
|
||||
if (m_constantsPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_constantsPosition);
|
||||
parseConstantSection();
|
||||
}
|
||||
|
||||
if (m_predicatesPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_predicatesPosition);
|
||||
parsePredicateSection();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_actionPositions.size(); i++)
|
||||
if (m_actionPositions[i] != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_actionPositions[i]);
|
||||
parseActionSection();
|
||||
}
|
||||
|
||||
computeDerivedRequirements();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Domain::setName(std::string name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string &Domain::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const Requirements &Domain::requirements() const
|
||||
{
|
||||
return m_requirements;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
expressions::PrimitiveTypes &Domain::types()
|
||||
{
|
||||
return m_types;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const expressions::PrimitiveTypes &Domain::types() const
|
||||
{
|
||||
return m_types;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
expressions::Constants &Domain::constants()
|
||||
{
|
||||
return m_constants;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const expressions::Constants &Domain::constants() const
|
||||
{
|
||||
return m_constants;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
expressions::PredicateDeclarations &Domain::predicates()
|
||||
{
|
||||
return m_predicates;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const expressions::PredicateDeclarations &Domain::predicates() const
|
||||
{
|
||||
return m_predicates;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<std::unique_ptr<Action>> &Domain::actions()
|
||||
{
|
||||
return m_actions;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::vector<std::unique_ptr<Action>> &Domain::actions() const
|
||||
{
|
||||
return m_actions;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
expressions::DerivedPredicates &Domain::derivedPredicates()
|
||||
{
|
||||
return m_derivedPredicates;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const expressions::DerivedPredicates &Domain::derivedPredicates() const
|
||||
{
|
||||
return m_derivedPredicates;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Domain::parseRequirementSection()
|
||||
{
|
||||
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>(":");
|
||||
|
||||
m_requirements.emplace_back(Requirement::parse(m_context));
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
// TODO: do this check only once the problem is parsed
|
||||
// If no requirements are specified, assume STRIPS
|
||||
if (m_requirements.empty())
|
||||
m_requirements.emplace_back(Requirement::Type::STRIPS);
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Domain::hasRequirement(Requirement::Type requirementType) const
|
||||
{
|
||||
const auto match = std::find_if(m_requirements.cbegin(), m_requirements.cend(),
|
||||
[&](const auto &requirement)
|
||||
{
|
||||
return requirement.type() == requirementType;
|
||||
});
|
||||
|
||||
return match != m_requirements.cend();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Domain::checkRequirement(Requirement::Type requirementType)
|
||||
{
|
||||
if (hasRequirement(requirementType))
|
||||
return;
|
||||
|
||||
m_context.logger.log(output::Priority::Warning, m_context.tokenizer, "requirement “" + Requirement(requirementType).toPDDL() + "” used but never declared");
|
||||
|
||||
m_requirements.push_back(requirementType);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Domain::computeDerivedRequirements()
|
||||
{
|
||||
const auto addRequirementUnique =
|
||||
[&](const auto requirement)
|
||||
{
|
||||
if (hasRequirement(requirement))
|
||||
return;
|
||||
|
||||
m_requirements.push_back(Requirement(requirement));
|
||||
};
|
||||
|
||||
if (hasRequirement(Requirement::Type::ADL))
|
||||
{
|
||||
addRequirementUnique(Requirement::Type::STRIPS);
|
||||
addRequirementUnique(Requirement::Type::Typing);
|
||||
addRequirementUnique(Requirement::Type::NegativePreconditions);
|
||||
addRequirementUnique(Requirement::Type::DisjunctivePreconditions);
|
||||
addRequirementUnique(Requirement::Type::Equality);
|
||||
addRequirementUnique(Requirement::Type::QuantifiedPreconditions);
|
||||
addRequirementUnique(Requirement::Type::ConditionalEffects);
|
||||
}
|
||||
|
||||
if (hasRequirement(Requirement::Type::QuantifiedPreconditions))
|
||||
{
|
||||
addRequirementUnique(Requirement::Type::ExistentialPreconditions);
|
||||
addRequirementUnique(Requirement::Type::UniversalPreconditions);
|
||||
}
|
||||
|
||||
if (hasRequirement(Requirement::Type::Fluents))
|
||||
{
|
||||
addRequirementUnique(Requirement::Type::NumericFluents);
|
||||
addRequirementUnique(Requirement::Type::ObjectFluents);
|
||||
}
|
||||
|
||||
if (hasRequirement(Requirement::Type::TimedInitialLiterals))
|
||||
addRequirementUnique(Requirement::Type::DurativeActions);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Domain::parseTypeSection()
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("types");
|
||||
|
||||
checkRequirement(Requirement::Type::Typing);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Store types and their parent types
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
if (tokenizer.currentCharacter() == '(')
|
||||
throw tokenize::TokenizerException(tokenizer, "only primitive types are allowed in type section");
|
||||
|
||||
expressions::PrimitiveType::parseTypedDeclaration(m_context, *this);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Domain::parseConstantSection()
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("constants");
|
||||
|
||||
// Store constants
|
||||
expressions::Constant::parseTypedDeclarations(m_context, *this);
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Domain::parsePredicateSection()
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("predicates");
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Store predicates and their arguments
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
expressions::PredicateDeclaration::parse(m_context, *this);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Domain::parseActionSection()
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("action");
|
||||
|
||||
Action::parseDeclaration(m_context, *this);
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Domain::checkConsistency()
|
||||
{
|
||||
// Verify that constants are unique
|
||||
// Verify that all primitive types are unique
|
||||
// Check for case-sensitivity issues
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Domain::normalize()
|
||||
{
|
||||
std::for_each(m_predicates.begin(), m_predicates.end(),
|
||||
[](auto &predicate)
|
||||
{
|
||||
predicate->normalizeParameterNames();
|
||||
});
|
||||
|
||||
std::for_each(m_actions.begin(), m_actions.end(),
|
||||
[&](auto &action)
|
||||
{
|
||||
action->normalize(m_derivedPredicates);
|
||||
});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
@ -1,336 +0,0 @@
|
||||
#include <plasp/pddl/Expression.h>
|
||||
|
||||
#include <plasp/output/TranslatorException.h>
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/IO.h>
|
||||
#include <plasp/pddl/expressions/And.h>
|
||||
#include <plasp/pddl/expressions/Exists.h>
|
||||
#include <plasp/pddl/expressions/ForAll.h>
|
||||
#include <plasp/pddl/expressions/Imply.h>
|
||||
#include <plasp/pddl/expressions/Not.h>
|
||||
#include <plasp/pddl/expressions/Or.h>
|
||||
#include <plasp/pddl/expressions/Predicate.h>
|
||||
#include <plasp/pddl/expressions/PredicateDeclaration.h>
|
||||
#include <plasp/pddl/expressions/Unsupported.h>
|
||||
#include <plasp/pddl/expressions/When.h>
|
||||
|
||||
#include <tokenize/TokenizerException.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Expression
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer Expression::copy()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer Expression::normalized()
|
||||
{
|
||||
return reduced()->simplified()->existentiallyQuantified()->simplified();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer Expression::reduced()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer Expression::existentiallyQuantified()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer Expression::simplified()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer Expression::decomposed(expressions::DerivedPredicates &)
|
||||
{
|
||||
throw output::TranslatorException("expression cannot be decomposed (not normalized)");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer Expression::negated()
|
||||
{
|
||||
if (is<expressions::Not>())
|
||||
return as<expressions::Not>().argument();
|
||||
|
||||
auto notExpression = expressions::NotPointer(new expressions::Not);
|
||||
notExpression->setArgument(this);
|
||||
|
||||
return notExpression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: implement better (visitor pattern?)
|
||||
void Expression::collectParameters(std::set<expressions::VariablePointer> &)
|
||||
{
|
||||
throw output::TranslatorException("expression parameters could not be collected (expression not normalized)");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseEffectBodyExpression(Context &context, ExpressionContext &expressionContext);
|
||||
ExpressionPointer parsePredicate(Context &context, ExpressionContext &expressionContext);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parsePreconditionExpression(Context &context,
|
||||
ExpressionContext &expressionContext)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
ExpressionPointer expression;
|
||||
|
||||
if ((expression = expressions::And::parse(context, expressionContext, parsePreconditionExpression))
|
||||
|| (expression = expressions::ForAll::parse(context, expressionContext, parsePreconditionExpression)))
|
||||
{
|
||||
return expression;
|
||||
}
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
|
||||
const auto expressionIdentifierPosition = tokenizer.position();
|
||||
|
||||
if (tokenizer.testIdentifierAndSkip("preference"))
|
||||
{
|
||||
// TODO: refactor
|
||||
tokenizer.seek(expressionIdentifierPosition);
|
||||
const auto expressionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.seek(position);
|
||||
return expressions::Unsupported::parse(context);
|
||||
}
|
||||
|
||||
tokenizer.seek(position);
|
||||
return parseExpression(context, expressionContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseExpression(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
ExpressionPointer expression;
|
||||
|
||||
if ((expression = expressions::And::parse(context, expressionContext, parseExpression))
|
||||
|| (expression = expressions::Or::parse(context, expressionContext, parseExpression))
|
||||
|| (expression = expressions::Exists::parse(context, expressionContext, parseExpression))
|
||||
|| (expression = expressions::ForAll::parse(context, expressionContext, parseExpression))
|
||||
|| (expression = expressions::Not::parse(context, expressionContext, parseExpression))
|
||||
|| (expression = expressions::Imply::parse(context, expressionContext, parseExpression))
|
||||
|| (expression = expressions::Predicate::parse(context, expressionContext)))
|
||||
{
|
||||
return expression;
|
||||
}
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
|
||||
const auto expressionIdentifierPosition = tokenizer.position();
|
||||
|
||||
if (tokenizer.testIdentifierAndSkip("-")
|
||||
|| tokenizer.testIdentifierAndSkip("=")
|
||||
|| tokenizer.testIdentifierAndSkip("*")
|
||||
|| tokenizer.testIdentifierAndSkip("+")
|
||||
|| tokenizer.testIdentifierAndSkip("-")
|
||||
|| tokenizer.testIdentifierAndSkip("/")
|
||||
|| tokenizer.testIdentifierAndSkip(">")
|
||||
|| tokenizer.testIdentifierAndSkip("<")
|
||||
|| tokenizer.testIdentifierAndSkip("=")
|
||||
|| tokenizer.testIdentifierAndSkip(">=")
|
||||
|| tokenizer.testIdentifierAndSkip("<="))
|
||||
{
|
||||
tokenizer.seek(expressionIdentifierPosition);
|
||||
const auto expressionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.seek(position);
|
||||
return expressions::Unsupported::parse(context);
|
||||
}
|
||||
|
||||
tokenizer.seek(expressionIdentifierPosition);
|
||||
const auto expressionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.seek(position);
|
||||
throw tokenize::TokenizerException(tokenizer, "expression type “" + expressionIdentifier + "” unknown or not allowed in this context");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseEffectExpression(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
ExpressionPointer expression;
|
||||
|
||||
if ((expression = expressions::And::parse(context, expressionContext, parseEffectExpression))
|
||||
|| (expression = expressions::ForAll::parse(context, expressionContext, parseEffectExpression))
|
||||
|| (expression = expressions::When::parse(context, expressionContext, parseExpression, parseConditionalEffectExpression)))
|
||||
{
|
||||
return expression;
|
||||
}
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
|
||||
const auto expressionIdentifierPosition = tokenizer.position();
|
||||
|
||||
if (tokenizer.testIdentifierAndSkip("when"))
|
||||
{
|
||||
tokenizer.seek(expressionIdentifierPosition);
|
||||
const auto expressionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.seek(position);
|
||||
return expressions::Unsupported::parse(context);
|
||||
}
|
||||
|
||||
tokenizer.seek(position);
|
||||
return parseEffectBodyExpression(context, expressionContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseEffectBodyExpression(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
ExpressionPointer expression;
|
||||
|
||||
if ((expression = expressions::Not::parse(context, expressionContext, parsePredicate))
|
||||
|| (expression = expressions::Predicate::parse(context, expressionContext)))
|
||||
{
|
||||
return expression;
|
||||
}
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
|
||||
const auto expressionIdentifierPosition = tokenizer.position();
|
||||
|
||||
if (tokenizer.testIdentifierAndSkip("=")
|
||||
|| tokenizer.testIdentifierAndSkip("assign")
|
||||
|| tokenizer.testIdentifierAndSkip("scale-up")
|
||||
|| tokenizer.testIdentifierAndSkip("scale-down")
|
||||
|| tokenizer.testIdentifierAndSkip("increase")
|
||||
|| tokenizer.testIdentifierAndSkip("decrease"))
|
||||
{
|
||||
tokenizer.seek(expressionIdentifierPosition);
|
||||
const auto expressionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.seek(position);
|
||||
return expressions::Unsupported::parse(context);
|
||||
}
|
||||
|
||||
tokenizer.seek(expressionIdentifierPosition);
|
||||
const auto expressionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.seek(position);
|
||||
throw tokenize::TokenizerException(tokenizer, "expression type “" + expressionIdentifier + "” unknown or not allowed in this context");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseConditionalEffectExpression(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
ExpressionPointer expression;
|
||||
|
||||
if ((expression = expressions::And::parse(context, expressionContext, parseEffectBodyExpression)))
|
||||
return expression;
|
||||
|
||||
return parseEffectBodyExpression(context, expressionContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parsePredicate(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
ExpressionPointer expression;
|
||||
|
||||
if ((expression = expressions::Predicate::parse(context, expressionContext)))
|
||||
return expression;
|
||||
|
||||
throw tokenize::TokenizerException(context.tokenizer, "expected predicate");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseLiteral(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
ExpressionPointer expression;
|
||||
|
||||
if ((expression = parseAtomicFormula(context, expressionContext))
|
||||
|| (expression = expressions::Not::parse(context, expressionContext, parseAtomicFormula)))
|
||||
{
|
||||
return expression;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseAtomicFormula(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
ExpressionPointer expression;
|
||||
|
||||
if ((expression = expressions::Predicate::parse(context, expressionContext)))
|
||||
return expression;
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
if (!tokenizer.testAndSkip<std::string>("("))
|
||||
return nullptr;
|
||||
|
||||
const auto expressionIdentifierPosition = tokenizer.position();
|
||||
|
||||
if (tokenizer.testIdentifierAndSkip("="))
|
||||
{
|
||||
tokenizer.seek(expressionIdentifierPosition);
|
||||
const auto expressionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.seek(position);
|
||||
return expressions::Unsupported::parse(context);
|
||||
}
|
||||
|
||||
tokenizer.seek(position);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/pddl/Problem.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ExpressionContext
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionContext::ExpressionContext(Domain &domain)
|
||||
: domain(domain),
|
||||
problem(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionContext::ExpressionContext(Domain &domain, Problem *problem)
|
||||
: domain(domain),
|
||||
problem{problem}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool ExpressionContext::hasRequirement(Requirement::Type requirementType) const
|
||||
{
|
||||
if (problem != nullptr)
|
||||
return problem->hasRequirement(requirementType);
|
||||
|
||||
return domain.hasRequirement(requirementType);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ExpressionContext::checkRequirement(Requirement::Type requirementType) const
|
||||
{
|
||||
if (problem != nullptr)
|
||||
problem->checkRequirement(requirementType);
|
||||
else
|
||||
domain.checkRequirement(requirementType);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
#include <plasp/pddl/InitialState.h>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/IO.h>
|
||||
#include <plasp/pddl/Problem.h>
|
||||
#include <plasp/pddl/expressions/At.h>
|
||||
#include <plasp/pddl/expressions/Predicate.h>
|
||||
#include <plasp/pddl/expressions/Unsupported.h>
|
||||
|
||||
#include <tokenize/TokenizerException.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// InitialState
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::unique_ptr<InitialState> InitialState::parseDeclaration(Context &context,
|
||||
ExpressionContext &expressionContext)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
auto initialState = std::make_unique<InitialState>(InitialState());
|
||||
|
||||
const auto parseInitialStateElement =
|
||||
[&]() -> ExpressionPointer
|
||||
{
|
||||
ExpressionPointer expression;
|
||||
|
||||
// TODO: do not allow negative initial state literals
|
||||
if ((expression = parseLiteral(context, expressionContext))
|
||||
|| (expression = expressions::At::parse(context, expressionContext, parseLiteral)))
|
||||
{
|
||||
return expression;
|
||||
}
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
|
||||
const auto expressionIdentifierPosition = tokenizer.position();
|
||||
|
||||
if (tokenizer.testIdentifierAndSkip("="))
|
||||
{
|
||||
tokenizer.seek(expressionIdentifierPosition);
|
||||
const auto expressionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.seek(position);
|
||||
return expressions::Unsupported::parse(context);
|
||||
}
|
||||
|
||||
tokenizer.seek(expressionIdentifierPosition);
|
||||
const auto expressionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.seek(position);
|
||||
throw tokenize::TokenizerException(tokenizer, "expression type “" + expressionIdentifier + "” unknown or not allowed in this context");
|
||||
};
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
ExpressionPointer expression;
|
||||
|
||||
if ((expression = parseInitialStateElement()))
|
||||
initialState->m_facts.emplace_back(std::move(expression));
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
return initialState;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const Expressions &InitialState::facts() const
|
||||
{
|
||||
return m_facts;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
@ -1,408 +0,0 @@
|
||||
#include <plasp/pddl/Problem.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <plasp/pddl/ConsistencyException.h>
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/IO.h>
|
||||
#include <plasp/pddl/expressions/Constant.h>
|
||||
|
||||
#include <tokenize/TokenizerException.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Problem
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Problem::Problem(Context &context, 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}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Problem::findSections()
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>("define");
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>("problem");
|
||||
|
||||
m_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 tokenize::TokenizerException(tokenizer, "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>(":");
|
||||
|
||||
const auto sectionIdentifierPosition = tokenizer.position();
|
||||
|
||||
// TODO: check order of the sections
|
||||
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"))
|
||||
{
|
||||
tokenizer.seek(sectionIdentifierPosition);
|
||||
|
||||
const auto sectionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
m_context.logger.log(output::Priority::Warning, tokenizer, "section type “" + sectionIdentifier + "” currently unsupported");
|
||||
|
||||
tokenizer.seek(sectionIdentifierPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto sectionIdentifier = tokenizer.getIdentifier();
|
||||
|
||||
tokenizer.seek(position);
|
||||
throw tokenize::TokenizerException(tokenizer, "unknown problem section “" + sectionIdentifier + "”");
|
||||
}
|
||||
|
||||
// Skip section for now and parse it later
|
||||
skipSection(tokenizer);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Problem::parse()
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
if (m_domainPosition == tokenize::InvalidStreamPosition)
|
||||
throw ConsistencyException("problem description does not specify the corresponding domain");
|
||||
|
||||
tokenizer.seek(m_domainPosition);
|
||||
parseDomainSection();
|
||||
|
||||
if (m_requirementsPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_requirementsPosition);
|
||||
parseRequirementSection();
|
||||
}
|
||||
|
||||
if (m_objectsPosition != tokenize::InvalidStreamPosition)
|
||||
{
|
||||
tokenizer.seek(m_objectsPosition);
|
||||
parseObjectSection();
|
||||
}
|
||||
|
||||
if (m_initialStatePosition == tokenize::InvalidStreamPosition)
|
||||
throw ConsistencyException("problem description does not specify an initial state");
|
||||
|
||||
tokenizer.seek(m_initialStatePosition);
|
||||
parseInitialStateSection();
|
||||
|
||||
if (m_goalPosition == tokenize::InvalidStreamPosition)
|
||||
throw ConsistencyException("problem description does not specify a goal");
|
||||
|
||||
tokenizer.seek(m_goalPosition);
|
||||
parseGoalSection();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Domain &Problem::domain()
|
||||
{
|
||||
return m_domain;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const Domain &Problem::domain() const
|
||||
{
|
||||
return m_domain;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string &Problem::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const Requirements &Problem::requirements() const
|
||||
{
|
||||
return m_requirements;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
expressions::Constants &Problem::objects()
|
||||
{
|
||||
return m_objects;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const expressions::Constants &Problem::objects() const
|
||||
{
|
||||
return m_objects;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Problem::parseDomainSection()
|
||||
{
|
||||
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 (m_domain.name() != domainName)
|
||||
throw tokenize::TokenizerException(tokenizer, "domains do not match (“" + m_domain.name() + "” and “" + domainName + "”)");
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Problem::parseRequirementSection()
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("requirements");
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
tokenizer.expect<std::string>(":");
|
||||
|
||||
m_requirements.emplace_back(Requirement::parse(m_context));
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
// TODO: do this check only once the domain is parsed
|
||||
// If no requirements are specified, assume STRIPS
|
||||
if (m_requirements.empty())
|
||||
m_requirements.emplace_back(Requirement::Type::STRIPS);
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Problem::hasRequirement(Requirement::Type requirementType) const
|
||||
{
|
||||
const auto match = std::find_if(m_requirements.cbegin(), m_requirements.cend(),
|
||||
[&](const auto &requirement)
|
||||
{
|
||||
return requirement.type() == requirementType;
|
||||
});
|
||||
|
||||
if (match != m_requirements.cend())
|
||||
return true;
|
||||
|
||||
return m_domain.hasRequirement(requirementType);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Problem::checkRequirement(Requirement::Type requirementType)
|
||||
{
|
||||
if (hasRequirement(requirementType))
|
||||
return;
|
||||
|
||||
m_context.logger.log(output::Priority::Warning, m_context.tokenizer, "requirement “" + Requirement(requirementType).toPDDL() + "” used but never declared");
|
||||
|
||||
m_requirements.push_back(requirementType);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Problem::computeDerivedRequirements()
|
||||
{
|
||||
const auto addRequirementUnique =
|
||||
[&](const auto requirement)
|
||||
{
|
||||
if (hasRequirement(requirement))
|
||||
return;
|
||||
|
||||
m_requirements.push_back(Requirement(requirement));
|
||||
};
|
||||
|
||||
if (hasRequirement(Requirement::Type::ADL))
|
||||
{
|
||||
addRequirementUnique(Requirement::Type::STRIPS);
|
||||
addRequirementUnique(Requirement::Type::Typing);
|
||||
addRequirementUnique(Requirement::Type::NegativePreconditions);
|
||||
addRequirementUnique(Requirement::Type::DisjunctivePreconditions);
|
||||
addRequirementUnique(Requirement::Type::Equality);
|
||||
addRequirementUnique(Requirement::Type::QuantifiedPreconditions);
|
||||
addRequirementUnique(Requirement::Type::ConditionalEffects);
|
||||
}
|
||||
|
||||
if (hasRequirement(Requirement::Type::QuantifiedPreconditions))
|
||||
{
|
||||
addRequirementUnique(Requirement::Type::ExistentialPreconditions);
|
||||
addRequirementUnique(Requirement::Type::UniversalPreconditions);
|
||||
}
|
||||
|
||||
if (hasRequirement(Requirement::Type::Fluents))
|
||||
{
|
||||
addRequirementUnique(Requirement::Type::NumericFluents);
|
||||
addRequirementUnique(Requirement::Type::ObjectFluents);
|
||||
}
|
||||
|
||||
if (hasRequirement(Requirement::Type::TimedInitialLiterals))
|
||||
addRequirementUnique(Requirement::Type::DurativeActions);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Problem::parseObjectSection()
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("objects");
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Store constants
|
||||
expressions::Constant::parseTypedDeclarations(m_context, *this);
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Problem::parseInitialStateSection()
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("init");
|
||||
|
||||
ExpressionContext expressionContext(m_domain, this);
|
||||
|
||||
m_initialState = InitialState::parseDeclaration(m_context, expressionContext);
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Problem::parseGoalSection()
|
||||
{
|
||||
auto &tokenizer = m_context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
tokenizer.expect<std::string>(":");
|
||||
tokenizer.expect<std::string>("goal");
|
||||
|
||||
ExpressionContext expressionContext(m_domain, this);
|
||||
|
||||
m_goal = parsePreconditionExpression(m_context, expressionContext);
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
InitialState &Problem::initialState()
|
||||
{
|
||||
BOOST_ASSERT(m_initialState);
|
||||
|
||||
return *m_initialState;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const InitialState &Problem::initialState() const
|
||||
{
|
||||
BOOST_ASSERT(m_initialState);
|
||||
|
||||
return *m_initialState;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const Expression &Problem::goal() const
|
||||
{
|
||||
BOOST_ASSERT(m_goal);
|
||||
|
||||
return *m_goal;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Problem::checkConsistency()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Problem::normalize()
|
||||
{
|
||||
BOOST_ASSERT(m_goal);
|
||||
|
||||
// TODO: normalize objects and initial state
|
||||
|
||||
m_goal = m_goal->normalized();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
@ -1,134 +0,0 @@
|
||||
#include <plasp/pddl/Requirement.h>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/assign.hpp>
|
||||
#include <boost/bimap.hpp>
|
||||
|
||||
#include <tokenize/TokenizerException.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Requirement
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using RequirementTypeNames = boost::bimap<Requirement::Type, std::string>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const RequirementTypeNames requirementTypesToPDDL = boost::assign::list_of<RequirementTypeNames::relation>
|
||||
(Requirement::Type::STRIPS, "strips")
|
||||
(Requirement::Type::Typing, "typing")
|
||||
(Requirement::Type::NegativePreconditions, "negative-preconditions")
|
||||
(Requirement::Type::DisjunctivePreconditions, "disjunctive-preconditions")
|
||||
(Requirement::Type::Equality, "equality")
|
||||
(Requirement::Type::ExistentialPreconditions, "existential-preconditions")
|
||||
(Requirement::Type::UniversalPreconditions, "universal-preconditions")
|
||||
(Requirement::Type::QuantifiedPreconditions, "quantified-preconditions")
|
||||
(Requirement::Type::ConditionalEffects, "conditional-effects")
|
||||
(Requirement::Type::Fluents, "fluents")
|
||||
(Requirement::Type::NumericFluents, "numeric-fluents")
|
||||
(Requirement::Type::ObjectFluents, "object-fluents")
|
||||
(Requirement::Type::ADL, "adl")
|
||||
(Requirement::Type::DurativeActions, "durative-actions")
|
||||
(Requirement::Type::DurationInequalities, "duration-inequalities")
|
||||
(Requirement::Type::ContinuousEffects, "continuous-effects")
|
||||
(Requirement::Type::DerivedPredicates, "derived-predicates")
|
||||
(Requirement::Type::TimedInitialLiterals, "timed-initial-literals")
|
||||
(Requirement::Type::Preferences, "preferences")
|
||||
(Requirement::Type::Constraints, "constraints")
|
||||
(Requirement::Type::ActionCosts, "action-costs")
|
||||
(Requirement::Type::GoalUtilities, "goal-utilities");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const RequirementTypeNames requirementTypesToASP = boost::assign::list_of<RequirementTypeNames::relation>
|
||||
(Requirement::Type::STRIPS, "strips")
|
||||
(Requirement::Type::Typing, "typing")
|
||||
(Requirement::Type::NegativePreconditions, "negativePreconditions")
|
||||
(Requirement::Type::DisjunctivePreconditions, "disjunctivePreconditions")
|
||||
(Requirement::Type::Equality, "equality")
|
||||
(Requirement::Type::ExistentialPreconditions, "existentialPreconditions")
|
||||
(Requirement::Type::UniversalPreconditions, "universalPreconditions")
|
||||
(Requirement::Type::QuantifiedPreconditions, "quantifiedPreconditions")
|
||||
(Requirement::Type::ConditionalEffects, "conditionalEffects")
|
||||
(Requirement::Type::Fluents, "fluents")
|
||||
(Requirement::Type::NumericFluents, "numericFluents")
|
||||
(Requirement::Type::ObjectFluents, "objectFluents")
|
||||
(Requirement::Type::ADL, "adl")
|
||||
(Requirement::Type::DurativeActions, "durativeActions")
|
||||
(Requirement::Type::DurationInequalities, "durationInequalities")
|
||||
(Requirement::Type::ContinuousEffects, "continuousEffects")
|
||||
(Requirement::Type::DerivedPredicates, "derivedPredicates")
|
||||
(Requirement::Type::TimedInitialLiterals, "timedInitialLiterals")
|
||||
(Requirement::Type::Preferences, "preferences")
|
||||
(Requirement::Type::Constraints, "constraints")
|
||||
(Requirement::Type::ActionCosts, "actionCosts")
|
||||
(Requirement::Type::GoalUtilities, "goalUtilities");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Requirement::Requirement(Requirement::Type type)
|
||||
: m_type{type}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Requirement Requirement::parse(Context &context)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
const auto requirementName = tokenizer.getIdentifier();
|
||||
|
||||
const auto match = requirementTypesToPDDL.right.find(requirementName);
|
||||
|
||||
if (match == requirementTypesToPDDL.right.end())
|
||||
throw tokenize::TokenizerException(tokenizer, "unknown PDDL requirement “" + requirementName + "”");
|
||||
|
||||
const auto requirementType = match->second;
|
||||
|
||||
if (requirementType == Requirement::Type::GoalUtilities)
|
||||
context.logger.log(output::Priority::Warning, tokenizer, "requirement “goal-utilities” is not part of the PDDL 3.1 specification");
|
||||
|
||||
return Requirement(match->second);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Requirement::Type Requirement::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string Requirement::toPDDL() const
|
||||
{
|
||||
const auto match = requirementTypesToPDDL.left.find(m_type);
|
||||
|
||||
BOOST_ASSERT(match != requirementTypesToPDDL.left.end());
|
||||
|
||||
return match->second;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string Requirement::toASP() const
|
||||
{
|
||||
const auto match = requirementTypesToASP.left.find(m_type);
|
||||
|
||||
BOOST_ASSERT(match != requirementTypesToASP.left.end());
|
||||
|
||||
return match->second;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
@ -2,11 +2,13 @@
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <pddlparse/AST.h>
|
||||
|
||||
#include <plasp/output/Formatting.h>
|
||||
#include <plasp/output/TranslatorException.h>
|
||||
#include <plasp/pddl/expressions/And.h>
|
||||
#include <plasp/pddl/expressions/Not.h>
|
||||
#include <plasp/pddl/expressions/Predicate.h>
|
||||
|
||||
#include <plasp/pddl/translation/Effect.h>
|
||||
#include <plasp/pddl/translation/Goal.h>
|
||||
#include <plasp/pddl/translation/Precondition.h>
|
||||
#include <plasp/pddl/translation/Predicate.h>
|
||||
#include <plasp/pddl/translation/Primitives.h>
|
||||
@ -23,11 +25,10 @@ namespace pddl
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TranslatorASP::TranslatorASP(Description &description, output::ColorStream &outputStream)
|
||||
: m_description(description),
|
||||
TranslatorASP::TranslatorASP(const ::pddl::ast::Description &description, output::ColorStream &outputStream)
|
||||
: m_description{description},
|
||||
m_outputStream(outputStream)
|
||||
{
|
||||
m_description.normalize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -36,7 +37,7 @@ void TranslatorASP::translate() const
|
||||
{
|
||||
translateDomain();
|
||||
|
||||
if (m_description.containsProblem())
|
||||
if (m_description.problem)
|
||||
{
|
||||
m_outputStream << std::endl;
|
||||
translateProblem();
|
||||
@ -49,35 +50,28 @@ void TranslatorASP::translateDomain() const
|
||||
{
|
||||
m_outputStream << output::Heading1("domain");
|
||||
|
||||
const auto &domain = m_description.domain();
|
||||
const auto &domain = m_description.domain;
|
||||
|
||||
// Types
|
||||
m_outputStream << std::endl;
|
||||
translateTypes();
|
||||
|
||||
// Constants
|
||||
if (!domain.constants().empty())
|
||||
if (!domain->constants.empty())
|
||||
{
|
||||
m_outputStream << std::endl;
|
||||
translateConstants("constants", domain.constants());
|
||||
translateConstants("constants", domain->constants);
|
||||
}
|
||||
|
||||
// Predicates
|
||||
if (!domain.predicates().empty())
|
||||
if (!domain->predicates.empty())
|
||||
{
|
||||
m_outputStream << std::endl;
|
||||
translatePredicates();
|
||||
}
|
||||
|
||||
// Derived predicates
|
||||
if (!domain.derivedPredicates().empty())
|
||||
{
|
||||
m_outputStream << std::endl;
|
||||
translateDerivedPredicates();
|
||||
}
|
||||
|
||||
// Actions
|
||||
if (!domain.actions().empty())
|
||||
if (!domain->actions.empty())
|
||||
{
|
||||
m_outputStream << std::endl;
|
||||
translateActions();
|
||||
@ -92,7 +86,7 @@ void TranslatorASP::translateTypes() const
|
||||
|
||||
m_outputStream << std::endl;
|
||||
|
||||
const auto &types = m_description.domain().types();
|
||||
const auto &types = m_description.domain->types;
|
||||
|
||||
if (types.empty())
|
||||
{
|
||||
@ -108,18 +102,18 @@ void TranslatorASP::translateTypes() const
|
||||
m_outputStream
|
||||
<< output::Function("type") << "("
|
||||
<< output::Keyword("type") << "("
|
||||
<< output::String(type->name().c_str())
|
||||
<< *type
|
||||
<< "))." << std::endl;
|
||||
|
||||
const auto &parentTypes = type->parentTypes();
|
||||
const auto &parentTypes = type->parentTypes;
|
||||
|
||||
std::for_each(parentTypes.cbegin(), parentTypes.cend(),
|
||||
[&](const auto &parentType)
|
||||
{
|
||||
m_outputStream
|
||||
<< output::Function("inherits") << "(" << output::Keyword("type")
|
||||
<< "(" << output::String(type->name().c_str()) << "), " << output::Keyword("type")
|
||||
<< "(" << output::String(parentType->name().c_str()) << "))." << std::endl;
|
||||
<< "(" << *type << "), " << output::Keyword("type")
|
||||
<< "(" << *parentType << "))." << std::endl;
|
||||
});
|
||||
}
|
||||
|
||||
@ -143,17 +137,17 @@ void TranslatorASP::translatePredicates() const
|
||||
{
|
||||
m_outputStream << output::Heading2("variables");
|
||||
|
||||
const auto &predicates = m_description.domain().predicates();
|
||||
const auto &predicates = m_description.domain->predicates;
|
||||
|
||||
for (const auto &predicate : predicates)
|
||||
{
|
||||
m_outputStream << std::endl << output::Function("variable") << "(";
|
||||
|
||||
translation::printPredicateName(m_outputStream, *predicate);
|
||||
translatePredicateDeclaration(m_outputStream, *predicate);
|
||||
|
||||
m_outputStream << ")";
|
||||
|
||||
translation::translateVariablesForRuleBody(m_outputStream, predicate->parameters());
|
||||
translateVariablesForRuleBody(m_outputStream, predicate->parameters);
|
||||
|
||||
m_outputStream << ".";
|
||||
}
|
||||
@ -173,160 +167,47 @@ void TranslatorASP::translatePredicates() const
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TranslatorASP::translateDerivedPredicates() const
|
||||
{
|
||||
m_outputStream << output::Heading2("derived predicates");
|
||||
|
||||
const auto &derivedPredicates = m_description.domain().derivedPredicates();
|
||||
|
||||
for (const auto &derivedPredicate : derivedPredicates)
|
||||
{
|
||||
const auto printObjectName =
|
||||
[&](auto &outputStream)
|
||||
{
|
||||
translation::printDerivedPredicateName(outputStream, *derivedPredicate);
|
||||
};
|
||||
|
||||
m_outputStream << std::endl << output::Function("derivedVariable") << "(";
|
||||
|
||||
printObjectName(m_outputStream);
|
||||
|
||||
m_outputStream << ")";
|
||||
|
||||
translation::translateVariablesForRuleBody(m_outputStream, derivedPredicate->parameters());
|
||||
|
||||
m_outputStream << ".";
|
||||
|
||||
translation::translatePreconditionDisjunction(m_outputStream, "derivedVariable", printObjectName, derivedPredicate->preconditions());
|
||||
|
||||
m_outputStream << std::endl;
|
||||
}
|
||||
|
||||
m_outputStream
|
||||
<< std::endl
|
||||
<< output::Function("contains") << "("
|
||||
<< output::Keyword("derivedVariable") << "(" << output::Variable("X") << "), "
|
||||
<< output::Keyword("value") << "(" << output::Variable("X") << ", " << output::Variable("B") << ")) :- "
|
||||
<< output::Function("derivedVariable") << "(" << output::Keyword("derivedVariable") << "(" << output::Variable("X") << ")), "
|
||||
<< output::Function("boolean") << "(" << output::Variable("B") << ")."
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TranslatorASP::translateActions() const
|
||||
{
|
||||
m_outputStream << output::Heading2("actions");
|
||||
|
||||
const auto &actions = m_description.domain().actions();
|
||||
|
||||
const auto printActionName =
|
||||
[&](const auto &action)
|
||||
{
|
||||
m_outputStream << output::Keyword("action") << "(";
|
||||
|
||||
if (action.parameters().empty())
|
||||
{
|
||||
m_outputStream << output::String(action.name().c_str()) << ")";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_outputStream << "(" << output::String(action.name().c_str());
|
||||
translation::translateVariablesForRuleHead(m_outputStream, action.parameters());
|
||||
m_outputStream << "))";
|
||||
};
|
||||
const auto &actions = m_description.domain->actions;
|
||||
|
||||
for (const auto &action : actions)
|
||||
{
|
||||
const auto translateExpression =
|
||||
[&](const auto &ruleHead, const auto &literal, bool enumerateEffects = false)
|
||||
const auto printActionName =
|
||||
[&]()
|
||||
{
|
||||
m_outputStream << std::endl << output::Function(ruleHead) << "(";
|
||||
m_outputStream << output::Keyword("action") << "(";
|
||||
|
||||
printActionName(*action);
|
||||
if (action->parameters.empty())
|
||||
{
|
||||
m_outputStream << *action << ")";
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: implement conditional effects
|
||||
if (enumerateEffects)
|
||||
m_outputStream << ", " << output::Keyword("effect") << "(" << output::Reserved("unconditional") << ")";
|
||||
|
||||
m_outputStream << ", ";
|
||||
|
||||
translation::translateLiteral(m_outputStream, literal);
|
||||
|
||||
m_outputStream << ") :- " << output::Function("action") << "(";
|
||||
|
||||
printActionName(*action);
|
||||
|
||||
m_outputStream << ").";
|
||||
m_outputStream << "(" << *action;
|
||||
translateVariablesForRuleHead(m_outputStream, action->parameters);
|
||||
m_outputStream << "))";
|
||||
};
|
||||
|
||||
m_outputStream << std::endl;
|
||||
|
||||
// Name
|
||||
m_outputStream << output::Function("action") << "(";
|
||||
printActionName(*action);
|
||||
printActionName();
|
||||
m_outputStream << ")";
|
||||
|
||||
translation::translateVariablesForRuleBody(m_outputStream, action->parameters());
|
||||
translateVariablesForRuleBody(m_outputStream, action->parameters);
|
||||
|
||||
m_outputStream << ".";
|
||||
|
||||
// Precondition
|
||||
if (action->precondition())
|
||||
{
|
||||
const auto &precondition = *action->precondition();
|
||||
if (action->precondition)
|
||||
translatePrecondition(m_outputStream, action->precondition.value(), "action", printActionName);
|
||||
|
||||
switch (precondition.expressionType())
|
||||
{
|
||||
case Expression::Type::And:
|
||||
{
|
||||
const auto &andExpression = precondition.as<expressions::And>();
|
||||
|
||||
std::for_each(andExpression.arguments().cbegin(), andExpression.arguments().cend(),
|
||||
[&](const auto argument)
|
||||
{
|
||||
translateExpression("precondition", *argument);
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
case Expression::Type::Predicate:
|
||||
case Expression::Type::Not:
|
||||
case Expression::Type::DerivedPredicate:
|
||||
{
|
||||
translateExpression("precondition", precondition);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw output::TranslatorException("only “and” expressions and (negated) predicates supported as action preconditions currently (" + std::to_string((int)precondition.expressionType()) + ")");
|
||||
}
|
||||
}
|
||||
|
||||
// Effect
|
||||
if (action->effect())
|
||||
{
|
||||
const auto &effect = *action->effect();
|
||||
|
||||
if (effect.is<expressions::Predicate>() || effect.is<expressions::Not>())
|
||||
{
|
||||
translateExpression("postcondition", effect, true);
|
||||
}
|
||||
// Assuming a conjunction
|
||||
else
|
||||
{
|
||||
if (effect.expressionType() != Expression::Type::And)
|
||||
throw output::TranslatorException("only “and” expressions and (negated) predicates supported as action effects currently");
|
||||
|
||||
const auto &andExpression = effect.as<expressions::And>();
|
||||
|
||||
std::for_each(andExpression.arguments().cbegin(), andExpression.arguments().cend(),
|
||||
[&](const auto argument)
|
||||
{
|
||||
translateExpression("postcondition", *argument, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (action->effect)
|
||||
translateEffect(m_outputStream, action->effect.value(), "action", printActionName);
|
||||
|
||||
m_outputStream << std::endl;
|
||||
}
|
||||
@ -334,7 +215,7 @@ void TranslatorASP::translateActions() const
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TranslatorASP::translateConstants(const std::string &heading, const expressions::Constants &constants) const
|
||||
void TranslatorASP::translateConstants(const std::string &heading, const ::pddl::ast::ConstantDeclarations &constants) const
|
||||
{
|
||||
m_outputStream << output::Heading2(heading.c_str());
|
||||
|
||||
@ -343,21 +224,26 @@ void TranslatorASP::translateConstants(const std::string &heading, const express
|
||||
m_outputStream << std::endl
|
||||
<< output::Function("constant") << "("
|
||||
<< output::Keyword("constant") << "("
|
||||
<< output::String(constant->name().c_str())
|
||||
<< *constant
|
||||
<< "))." << std::endl;
|
||||
|
||||
const auto type = constant->type();
|
||||
const auto &type = constant->type;
|
||||
|
||||
if (type != nullptr)
|
||||
if (type)
|
||||
{
|
||||
if (!type.value().is<::pddl::ast::PrimitiveTypePointer>())
|
||||
throw output::TranslatorException("only primitive types supported currently");
|
||||
|
||||
const auto &primitveType = type.value().get<::pddl::ast::PrimitiveTypePointer>();
|
||||
|
||||
m_outputStream << output::Function("has") << "("
|
||||
<< output::Keyword("constant") << "(" << output::String(constant->name().c_str()) << "), "
|
||||
<< output::Keyword("type") << "(" << output::String(type->name().c_str()) << "))." << std::endl;
|
||||
<< output::Keyword("constant") << "(" << *constant << "), "
|
||||
<< output::Keyword("type") << "(" << *primitveType << "))." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_outputStream << output::Function("has") << "("
|
||||
<< output::Keyword("constant") << "(" << output::String(constant->name().c_str()) << "), "
|
||||
<< output::Keyword("constant") << "(" << *constant << "), "
|
||||
<< output::Keyword("type") << "(" << output::String("object") << "))." << std::endl;
|
||||
}
|
||||
}
|
||||
@ -367,17 +253,17 @@ void TranslatorASP::translateConstants(const std::string &heading, const express
|
||||
|
||||
void TranslatorASP::translateProblem() const
|
||||
{
|
||||
BOOST_ASSERT(m_description.containsProblem());
|
||||
assert(m_description.problem);
|
||||
|
||||
m_outputStream << output::Heading1("problem");
|
||||
|
||||
const auto &problem = m_description.problem();
|
||||
const auto &problem = m_description.problem.value();
|
||||
|
||||
// Objects
|
||||
if (!problem.objects().empty())
|
||||
if (!problem->objects.empty())
|
||||
{
|
||||
m_outputStream << std::endl;
|
||||
translateConstants("objects", problem.objects());
|
||||
translateConstants("objects", problem->objects);
|
||||
}
|
||||
|
||||
// Initial State
|
||||
@ -385,42 +271,45 @@ void TranslatorASP::translateProblem() const
|
||||
translateInitialState();
|
||||
|
||||
// Goal
|
||||
m_outputStream << std::endl;
|
||||
translateGoal();
|
||||
if (problem->goal)
|
||||
{
|
||||
m_outputStream << std::endl;
|
||||
translateGoal();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TranslatorASP::translateInitialState() const
|
||||
{
|
||||
BOOST_ASSERT(m_description.containsProblem());
|
||||
assert(m_description.problem);
|
||||
|
||||
m_outputStream << output::Heading2("initial state");
|
||||
|
||||
const auto &initialStateFacts = m_description.problem().initialState().facts();
|
||||
const auto &facts = m_description.problem.value()->initialState.facts;
|
||||
|
||||
for (const auto &fact : initialStateFacts)
|
||||
for (const auto &fact : facts)
|
||||
{
|
||||
m_outputStream << std::endl << output::Function("initialState") << "(";
|
||||
|
||||
// Translate single predicate
|
||||
if (fact->is<expressions::Predicate>())
|
||||
if (fact.is<::pddl::ast::AtomicFormula>() && fact.get<::pddl::ast::AtomicFormula>().is<::pddl::ast::PredicatePointer>())
|
||||
{
|
||||
const auto &predicate = fact->as<expressions::Predicate>();
|
||||
const auto &predicate = fact.get<::pddl::ast::AtomicFormula>().get<::pddl::ast::PredicatePointer>();
|
||||
|
||||
m_outputStream << output::Keyword("variable") << "(";
|
||||
translation::translatePredicate(m_outputStream, predicate);
|
||||
m_outputStream << "), " << output::Keyword("value") << "(";
|
||||
translation::translatePredicate(m_outputStream, predicate);
|
||||
m_outputStream << ", " << output::Boolean("true") << ")";
|
||||
translatePredicateToVariable(m_outputStream, *predicate, true);
|
||||
}
|
||||
// Assuming that "not" expression may only contain a predicate
|
||||
else if (fact->is<expressions::Not>())
|
||||
else if (fact.is<::pddl::ast::NotPointer<::pddl::ast::Fact>>())
|
||||
{
|
||||
const auto ¬Expression = fact->as<expressions::Not>();
|
||||
const auto ¬Expression = fact.get<::pddl::ast::NotPointer<::pddl::ast::Fact>>();
|
||||
|
||||
if (notExpression.argument()->expressionType() != Expression::Type::Predicate)
|
||||
if (!notExpression->argument.is<::pddl::ast::AtomicFormula>() || !notExpression->argument.get<::pddl::ast::AtomicFormula>().is<::pddl::ast::PredicatePointer>())
|
||||
throw output::TranslatorException("only negations of simple predicates supported in initial state currently");
|
||||
|
||||
const auto &predicate = notExpression->argument.get<::pddl::ast::AtomicFormula>().get<::pddl::ast::PredicatePointer>();
|
||||
|
||||
translatePredicateToVariable(m_outputStream, *predicate, false);
|
||||
}
|
||||
else
|
||||
throw output::TranslatorException("only predicates and their negations supported in initial state currently");
|
||||
@ -445,36 +334,14 @@ void TranslatorASP::translateInitialState() const
|
||||
|
||||
void TranslatorASP::translateGoal() const
|
||||
{
|
||||
BOOST_ASSERT(m_description.containsProblem());
|
||||
assert(m_description.problem);
|
||||
assert(m_description.problem.value()->goal);
|
||||
|
||||
m_outputStream << output::Heading2("goal");
|
||||
|
||||
const auto &goal = m_description.problem().goal();
|
||||
|
||||
if (goal.is<expressions::Predicate>() || goal.is<expressions::Not>())
|
||||
{
|
||||
m_outputStream << std::endl << output::Function("goal") << "(";
|
||||
|
||||
translation::translateLiteral(m_outputStream, goal);
|
||||
|
||||
m_outputStream << ").";
|
||||
}
|
||||
else if (goal.is<expressions::And>())
|
||||
{
|
||||
const auto &andExpression = goal.as<expressions::And>();
|
||||
|
||||
std::for_each(andExpression.arguments().cbegin(), andExpression.arguments().cend(),
|
||||
[&](const auto argument)
|
||||
{
|
||||
m_outputStream << std::endl << output::Function("goal") << "(";
|
||||
|
||||
translation::translateLiteral(m_outputStream, *argument);
|
||||
|
||||
m_outputStream << ").";
|
||||
});
|
||||
}
|
||||
else
|
||||
throw output::TranslatorException("only single predicates, their negations, and conjunctions are currently supported in the goal");
|
||||
const auto &goal = m_description.problem.value()->goal.value();
|
||||
// TODO: refactor
|
||||
::plasp::pddl::translateGoal(m_outputStream, goal);
|
||||
|
||||
m_outputStream << std::endl;
|
||||
}
|
||||
|
@ -1,62 +0,0 @@
|
||||
#include <plasp/pddl/VariableStack.h>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// VariableStack
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void VariableStack::push(expressions::Variables *variables)
|
||||
{
|
||||
m_variableStack.push_back(variables);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void VariableStack::pop()
|
||||
{
|
||||
m_variableStack.pop_back();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
expressions::VariablePointer VariableStack::parseAndFind(plasp::pddl::Context &context)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
tokenizer.expect<std::string>("?");
|
||||
|
||||
const auto variableName = tokenizer.getIdentifier();
|
||||
|
||||
for (auto i = m_variableStack.crbegin(); i != m_variableStack.crend(); i++)
|
||||
{
|
||||
const auto *variables = *i;
|
||||
|
||||
BOOST_ASSERT(variables);
|
||||
|
||||
const auto match = std::find_if(variables->crbegin(), variables->crend(),
|
||||
[&](const auto &variable)
|
||||
{
|
||||
return variable->name() == variableName;
|
||||
});
|
||||
|
||||
if (match != variables->crend())
|
||||
return match->get();
|
||||
}
|
||||
|
||||
throw tokenize::TokenizerException(tokenizer, "variable “" + variableName + "” used but never declared");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
#include <plasp/pddl/expressions/And.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#include <plasp/output/TranslatorException.h>
|
||||
#include <plasp/pddl/expressions/Or.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// And
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string And::Identifier = "and";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer And::decomposed(DerivedPredicates &derivedPredicates)
|
||||
{
|
||||
BOOST_ASSERT(!m_arguments.empty());
|
||||
|
||||
derivedPredicates.emplace_back(new DerivedPredicate(derivedPredicates.size()));
|
||||
auto derivedPredicate = derivedPredicates.back();
|
||||
|
||||
for (auto &argument : m_arguments)
|
||||
argument = argument->decomposed(derivedPredicates);
|
||||
|
||||
std::vector<Expressions> preconditions;
|
||||
preconditions.emplace_back(std::move(m_arguments));
|
||||
|
||||
// Move this expression’s arguments to the derived predicate
|
||||
derivedPredicate->setPreconditions(std::move(preconditions));
|
||||
|
||||
return derivedPredicate;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
#include <plasp/pddl/expressions/At.h>
|
||||
|
||||
#include <plasp/output/TranslatorException.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// At
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
At::At()
|
||||
: m_argument{nullptr}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer At::copy()
|
||||
{
|
||||
auto result = new At;
|
||||
|
||||
result->m_argument = m_argument->copy();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void At::setArgument(ExpressionPointer argument)
|
||||
{
|
||||
m_argument = argument;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer At::argument() const
|
||||
{
|
||||
return m_argument;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer At::reduced()
|
||||
{
|
||||
throw output::TranslatorException("reducing “at” predicates currently not supported");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer At::existentiallyQuantified()
|
||||
{
|
||||
BOOST_ASSERT(m_argument);
|
||||
|
||||
m_argument = m_argument->existentiallyQuantified();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer At::simplified()
|
||||
{
|
||||
BOOST_ASSERT(m_argument);
|
||||
|
||||
m_argument = m_argument->simplified();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void At::collectParameters(std::set<VariablePointer> ¶meters)
|
||||
{
|
||||
m_argument->collectParameters(parameters);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void At::print(std::ostream &ostream) const
|
||||
{
|
||||
ostream << "(at " << m_timePoint << " ";
|
||||
|
||||
m_argument->print(ostream);
|
||||
|
||||
ostream << ")";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,253 +0,0 @@
|
||||
#include <plasp/pddl/expressions/Constant.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/Problem.h>
|
||||
#include <plasp/pddl/expressions/PrimitiveType.h>
|
||||
|
||||
#include <tokenize/TokenizerException.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constant
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Constant::Constant()
|
||||
: m_isDirty{false},
|
||||
m_type{nullptr}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ConstantPointer Constant::parseDeclaration(Context &context)
|
||||
{
|
||||
context.tokenizer.skipWhiteSpace();
|
||||
|
||||
auto constant = ConstantPointer(new Constant);
|
||||
|
||||
constant->m_name = context.tokenizer.getIdentifier();
|
||||
|
||||
BOOST_ASSERT(constant->m_name != "-");
|
||||
|
||||
// Flag constant for potentially upcoming type declaration
|
||||
constant->setDirty();
|
||||
|
||||
return constant;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Constant::parseTypedDeclaration(Context &context, Domain &domain)
|
||||
{
|
||||
parseTypedDeclaration(context, domain, domain.constants());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Constant::parseTypedDeclaration(Context &context, Problem &problem)
|
||||
{
|
||||
parseTypedDeclaration(context, problem.domain(), problem.objects());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Constant::parseTypedDeclaration(Context &context, Domain &domain, Constants &constants)
|
||||
{
|
||||
// Parse and store constant
|
||||
constants.emplace_back(parseDeclaration(context));
|
||||
|
||||
context.tokenizer.skipWhiteSpace();
|
||||
|
||||
// Check for typing information
|
||||
if (!context.tokenizer.testAndSkip<char>('-'))
|
||||
return;
|
||||
|
||||
// If existing, parse and store parent type
|
||||
auto type = PrimitiveType::parseAndFind(context, domain);
|
||||
|
||||
// Assign parent type to all types that were previously flagged
|
||||
std::for_each(constants.begin(), constants.end(),
|
||||
[&](auto &constant)
|
||||
{
|
||||
if (!constant->isDirty())
|
||||
return;
|
||||
|
||||
constant->setType(type);
|
||||
constant->setDirty(false);
|
||||
});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Constant::parseTypedDeclarations(Context &context, Domain &domain)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
parseTypedDeclaration(context, domain);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
if (domain.constants().empty())
|
||||
return;
|
||||
|
||||
// Check correct use of typing requirement
|
||||
const auto typingUsed = (domain.constants().back()->type() != nullptr);
|
||||
|
||||
// If types are given, check that typing is a requirement
|
||||
if (typingUsed)
|
||||
domain.checkRequirement(Requirement::Type::Typing);
|
||||
// If no types are given, check that typing is not a requirement
|
||||
else if (domain.hasRequirement(Requirement::Type::Typing))
|
||||
throw tokenize::TokenizerException(tokenizer, "constant has undeclared type");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Constant::parseTypedDeclarations(Context &context, Problem &problem)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
parseTypedDeclaration(context, problem);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
if (problem.objects().empty())
|
||||
return;
|
||||
|
||||
// Check correct use of typing requirement
|
||||
const auto typingUsed = (problem.objects().back()->type() != nullptr);
|
||||
|
||||
// If types are given, check that typing is a requirement
|
||||
if (typingUsed)
|
||||
problem.checkRequirement(Requirement::Type::Typing);
|
||||
// If no types are given, check that typing is not a requirement
|
||||
else if (problem.hasRequirement(Requirement::Type::Typing))
|
||||
throw tokenize::TokenizerException(tokenizer, "constant has undeclared type");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ConstantPointer Constant::parseAndFind(Context &context, const Domain &domain)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
const auto constantName = tokenizer.getIdentifier();
|
||||
|
||||
auto constant = parseAndFind(constantName, domain.constants());
|
||||
|
||||
if (constant != nullptr)
|
||||
return constant;
|
||||
|
||||
throw tokenize::TokenizerException(tokenizer, "constant “" + constantName + "” used but never declared");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ConstantPointer Constant::parseAndFind(Context &context, const Problem &problem)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
const auto constantName = tokenizer.getIdentifier();
|
||||
|
||||
auto constant = parseAndFind(constantName, problem.domain().constants());
|
||||
|
||||
if (constant)
|
||||
return constant;
|
||||
|
||||
constant = parseAndFind(constantName, problem.objects());
|
||||
|
||||
if (constant)
|
||||
return constant;
|
||||
|
||||
throw tokenize::TokenizerException(tokenizer, "constant “" + constantName + "” used but never declared");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ConstantPointer Constant::parseAndFind(const std::string &constantName, const Constants &constants)
|
||||
{
|
||||
const auto match = std::find_if(constants.cbegin(), constants.cend(),
|
||||
[&](const auto &constant)
|
||||
{
|
||||
return constant->name() == constantName;
|
||||
});
|
||||
|
||||
const auto constantExists = (match != constants.cend());
|
||||
|
||||
if (!constantExists)
|
||||
return nullptr;
|
||||
|
||||
return match->get();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Constant::setDirty(bool isDirty)
|
||||
{
|
||||
m_isDirty = isDirty;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Constant::isDirty() const
|
||||
{
|
||||
return m_isDirty;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string &Constant::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Constant::setType(PrimitiveTypePointer type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PrimitiveTypePointer Constant::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Constant::print(std::ostream &ostream) const
|
||||
{
|
||||
ostream << "(" << m_name << ")";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
#include <plasp/pddl/expressions/DerivedPredicate.h>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DerivedPredicate
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DerivedPredicate::DerivedPredicate(size_t id)
|
||||
: m_id{id}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
size_t DerivedPredicate::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DerivedPredicate::setPreconditions(std::vector<Expressions> &&preconditions)
|
||||
{
|
||||
m_preconditions = std::move(preconditions);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::vector<Expressions> &DerivedPredicate::preconditions() const
|
||||
{
|
||||
return m_preconditions;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DerivedPredicate::collectParameters()
|
||||
{
|
||||
for (const auto &conjunction : m_preconditions)
|
||||
for (const auto &precondition : conjunction)
|
||||
precondition->collectParameters(m_parameters);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::set<VariablePointer> &DerivedPredicate::parameters() const
|
||||
{
|
||||
return m_parameters;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DerivedPredicate::collectParameters(std::set<VariablePointer> ¶meters)
|
||||
{
|
||||
for (auto &conjunction : m_preconditions)
|
||||
for (auto &precondition : conjunction)
|
||||
{
|
||||
BOOST_ASSERT(precondition.get() != this);
|
||||
precondition->collectParameters(m_parameters);
|
||||
}
|
||||
|
||||
// Copy in order not to interfere with potentially bound variables in parent expressions
|
||||
parameters = m_parameters;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DerivedPredicate::print(std::ostream &ostream) const
|
||||
{
|
||||
ostream << "(:derived " << m_id << " ";
|
||||
|
||||
BOOST_ASSERT(m_preconditions.size() > 0);
|
||||
|
||||
const auto printConjunction =
|
||||
[&ostream](const auto &conjunction)
|
||||
{
|
||||
if (conjunction.size() == 0)
|
||||
{
|
||||
conjunction.front()->print(ostream);
|
||||
return;
|
||||
}
|
||||
|
||||
ostream << "(and";
|
||||
|
||||
for (const auto &precondition : conjunction)
|
||||
{
|
||||
ostream << " ";
|
||||
precondition->print(ostream);
|
||||
}
|
||||
|
||||
ostream << ")";
|
||||
};
|
||||
|
||||
if (m_preconditions.size() == 1)
|
||||
{
|
||||
const auto &conjunction = m_preconditions.front();
|
||||
|
||||
BOOST_ASSERT(conjunction.size() > 0);
|
||||
|
||||
printConjunction(conjunction);
|
||||
|
||||
ostream << ")";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ostream << " (or";
|
||||
|
||||
for (const auto conjunction : m_preconditions)
|
||||
{
|
||||
ostream << " ";
|
||||
|
||||
printConjunction(conjunction);
|
||||
}
|
||||
|
||||
ostream << "))";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
#include <plasp/pddl/expressions/Dummy.h>
|
||||
|
||||
#include <plasp/pddl/IO.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dummy
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Dummy::Dummy(std::string name)
|
||||
: m_name{name}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Dummy::print(std::ostream &ostream) const
|
||||
{
|
||||
ostream << "(" << m_name << ")";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
#include <plasp/pddl/expressions/Either.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Either
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string Either::Identifier = "either";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#include <plasp/pddl/expressions/Exists.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Exists
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string Exists::Identifier = "exists";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
#include <plasp/pddl/expressions/ForAll.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#include <plasp/pddl/expressions/Exists.h>
|
||||
#include <plasp/pddl/expressions/Not.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ForAll
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string ForAll::Identifier = "forall";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer ForAll::existentiallyQuantified()
|
||||
{
|
||||
auto existsExpression = ExistsPointer(new Exists());
|
||||
auto notExpression = NotPointer(new Not());
|
||||
|
||||
notExpression->setArgument(m_argument->existentiallyQuantified());
|
||||
existsExpression->setArgument(notExpression);
|
||||
existsExpression->variables() = std::move(m_variables);
|
||||
|
||||
return existsExpression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
#include <plasp/pddl/expressions/Imply.h>
|
||||
|
||||
#include <plasp/pddl/expressions/Not.h>
|
||||
#include <plasp/pddl/expressions/Or.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Imply
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: make static character string literal
|
||||
const std::string Imply::Identifier = "imply";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer Imply::reduced()
|
||||
{
|
||||
BOOST_ASSERT(m_arguments[0]);
|
||||
BOOST_ASSERT(m_arguments[1]);
|
||||
|
||||
m_arguments[0] = m_arguments[0]->reduced();
|
||||
m_arguments[1] = m_arguments[1]->reduced();
|
||||
|
||||
auto notArgument0 = NotPointer(new Not);
|
||||
notArgument0->setArgument(m_arguments[0]);
|
||||
|
||||
auto orExpression = OrPointer(new Or);
|
||||
orExpression->addArgument(notArgument0);
|
||||
orExpression->addArgument(m_arguments[1]);
|
||||
|
||||
return orExpression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,134 +0,0 @@
|
||||
#include <plasp/pddl/expressions/Not.h>
|
||||
|
||||
#include <plasp/output/TranslatorException.h>
|
||||
#include <plasp/pddl/expressions/And.h>
|
||||
#include <plasp/pddl/expressions/DerivedPredicate.h>
|
||||
#include <plasp/pddl/expressions/Exists.h>
|
||||
#include <plasp/pddl/expressions/ForAll.h>
|
||||
#include <plasp/pddl/expressions/Or.h>
|
||||
#include <plasp/pddl/expressions/Predicate.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Not
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Not::Not()
|
||||
: m_argument{nullptr}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer Not::copy()
|
||||
{
|
||||
auto result = new Not;
|
||||
|
||||
result->m_argument = m_argument->copy();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Not::setArgument(ExpressionPointer argument)
|
||||
{
|
||||
m_argument = argument;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer Not::argument() const
|
||||
{
|
||||
return m_argument;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer Not::reduced()
|
||||
{
|
||||
BOOST_ASSERT(m_argument);
|
||||
|
||||
m_argument = m_argument->reduced();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer Not::existentiallyQuantified()
|
||||
{
|
||||
BOOST_ASSERT(m_argument);
|
||||
|
||||
m_argument = m_argument->existentiallyQuantified();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer Not::simplified()
|
||||
{
|
||||
BOOST_ASSERT(m_argument);
|
||||
|
||||
m_argument = m_argument->simplified();
|
||||
|
||||
if (!m_argument->is<Not>())
|
||||
return this;
|
||||
|
||||
// Remove double negations
|
||||
const auto ¬Expression = m_argument->as<Not>();
|
||||
|
||||
return notExpression.argument();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Not::collectParameters(std::set<VariablePointer> ¶meters)
|
||||
{
|
||||
m_argument->collectParameters(parameters);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer Not::decomposed(DerivedPredicates &derivedPredicates)
|
||||
{
|
||||
m_argument = m_argument->decomposed(derivedPredicates);
|
||||
|
||||
// Predicates and derived predicates can be directly negated
|
||||
if (m_argument->is<Predicate>() || m_argument->is<DerivedPredicate>())
|
||||
return this;
|
||||
|
||||
derivedPredicates.emplace_back(new DerivedPredicate(derivedPredicates.size()));
|
||||
auto derivedPredicate = derivedPredicates.back();
|
||||
|
||||
// Move this expression’s arguments to the derived predicate
|
||||
derivedPredicate->setPreconditions({{this}});
|
||||
|
||||
return derivedPredicate;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Not::print(std::ostream &ostream) const
|
||||
{
|
||||
ostream << "(not ";
|
||||
|
||||
m_argument->print(ostream);
|
||||
|
||||
ostream << ")";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
#include <plasp/pddl/expressions/Or.h>
|
||||
|
||||
#include <plasp/output/TranslatorException.h>
|
||||
#include <plasp/pddl/expressions/And.h>
|
||||
#include <plasp/pddl/expressions/DerivedPredicate.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Or
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string Or::Identifier = "or";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer Or::decomposed(DerivedPredicates &derivedPredicates)
|
||||
{
|
||||
BOOST_ASSERT(!m_arguments.empty());
|
||||
|
||||
derivedPredicates.emplace_back(new DerivedPredicate(derivedPredicates.size()));
|
||||
auto derivedPredicate = derivedPredicates.back();
|
||||
|
||||
std::vector<Expressions> preconditions;
|
||||
|
||||
for (auto &argument : m_arguments)
|
||||
{
|
||||
Expressions conjunction;
|
||||
|
||||
// “and” expressions can directly be inlined into the derived predicate
|
||||
if (argument->is<And>())
|
||||
{
|
||||
conjunction = std::move(argument->as<And>().arguments());
|
||||
|
||||
for (auto &argument : conjunction)
|
||||
argument = argument->decomposed(derivedPredicates);
|
||||
}
|
||||
else
|
||||
conjunction.emplace_back(argument->decomposed(derivedPredicates));
|
||||
|
||||
// Move this expression’s arguments to the derived predicate
|
||||
preconditions.emplace_back(std::move(conjunction));
|
||||
}
|
||||
|
||||
derivedPredicate->setPreconditions(std::move(preconditions));
|
||||
|
||||
return derivedPredicate;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,199 +0,0 @@
|
||||
#include <plasp/pddl/expressions/Predicate.h>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/Problem.h>
|
||||
#include <plasp/pddl/expressions/Constant.h>
|
||||
#include <plasp/pddl/expressions/Variable.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Predicate
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Predicate::Predicate()
|
||||
: m_isDeclared{false}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PredicatePointer Predicate::parse(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
if (!tokenizer.testAndSkip<std::string>("("))
|
||||
{
|
||||
tokenizer.seek(position);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto predicateName = tokenizer.getIdentifier();
|
||||
const auto &predicates = expressionContext.domain.predicates();
|
||||
|
||||
const auto matchingPredicate = std::find_if(predicates.cbegin(), predicates.cend(),
|
||||
[&](const auto &predicate)
|
||||
{
|
||||
return predicate->name() == predicateName;
|
||||
});
|
||||
|
||||
if (matchingPredicate == predicates.cend())
|
||||
{
|
||||
tokenizer.seek(position);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto predicate = PredicatePointer(new Predicate);
|
||||
|
||||
predicate->m_name = predicateName;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Parse arguments
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
// Parse variables
|
||||
if (tokenizer.currentCharacter() == '?')
|
||||
{
|
||||
const auto variable = expressionContext.variables.parseAndFind(context);
|
||||
predicate->m_arguments.emplace_back(variable);
|
||||
}
|
||||
// Parse constants
|
||||
else
|
||||
{
|
||||
const auto constant = (expressionContext.problem == nullptr)
|
||||
? Constant::parseAndFind(context, expressionContext.domain)
|
||||
: Constant::parseAndFind(context, *expressionContext.problem);
|
||||
predicate->m_arguments.emplace_back(constant);
|
||||
}
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
// TODO: check that signature matches one of the declared ones
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
return predicate;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PredicatePointer Predicate::parse(Context &context, const Problem &problem)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
const auto position = tokenizer.position();
|
||||
|
||||
if (!tokenizer.testAndSkip<std::string>("("))
|
||||
{
|
||||
tokenizer.seek(position);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto predicateName = tokenizer.getIdentifier();
|
||||
const auto &predicates = problem.domain().predicates();
|
||||
|
||||
const auto matchingPredicate = std::find_if(predicates.cbegin(), predicates.cend(),
|
||||
[&](const auto &predicate)
|
||||
{
|
||||
return predicate->name() == predicateName;
|
||||
});
|
||||
|
||||
if (matchingPredicate == predicates.cend())
|
||||
{
|
||||
tokenizer.seek(position);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto predicate = PredicatePointer(new Predicate);
|
||||
|
||||
predicate->m_name = predicateName;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
if (tokenizer.currentCharacter() == '?')
|
||||
throw tokenize::TokenizerException(tokenizer, "variables not allowed in this context");
|
||||
|
||||
// Parse objects and constants
|
||||
const auto constant = Constant::parseAndFind(context, problem);
|
||||
predicate->m_arguments.emplace_back(constant);
|
||||
}
|
||||
|
||||
// TODO: check that signature matches one of the declared ones
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
return predicate;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Predicate::setDeclared()
|
||||
{
|
||||
m_isDeclared = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Predicate::isDeclared() const
|
||||
{
|
||||
return m_isDeclared;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer Predicate::decomposed(DerivedPredicates &)
|
||||
{
|
||||
// Predicates cannot be further decomposed
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Predicate::collectParameters(std::set<VariablePointer> ¶meters)
|
||||
{
|
||||
for (const auto &argument : m_arguments)
|
||||
argument->collectParameters(parameters);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string &Predicate::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const Expressions &Predicate::arguments() const
|
||||
{
|
||||
return m_arguments;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Predicate::print(std::ostream &ostream) const
|
||||
{
|
||||
// TODO: implement correctly
|
||||
ostream << "(<predicate>)";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
#include <plasp/pddl/expressions/PredicateDeclaration.h>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/expressions/Constant.h>
|
||||
#include <plasp/pddl/expressions/Variable.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PredicateDeclaration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PredicateDeclaration::PredicateDeclaration()
|
||||
: m_isDeclared{false}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PredicateDeclaration::parse(Context &context, Domain &domain)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
|
||||
auto predicate = PredicateDeclarationPointer(new PredicateDeclaration);
|
||||
|
||||
predicate->m_name = tokenizer.getIdentifier();
|
||||
|
||||
// Flag predicate as correctly declared in the types section
|
||||
predicate->setDeclared();
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
ExpressionContext expressionContext(domain);
|
||||
expressionContext.variables.push(&predicate->m_parameters);
|
||||
|
||||
// Parse parameters
|
||||
Variable::parseTypedDeclarations(context, expressionContext, predicate->m_parameters);
|
||||
|
||||
tokenizer.expect<std::string>(")");
|
||||
|
||||
domain.predicates().emplace_back(std::move(predicate));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PredicateDeclaration::setDeclared()
|
||||
{
|
||||
m_isDeclared = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool PredicateDeclaration::isDeclared() const
|
||||
{
|
||||
return m_isDeclared;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string &PredicateDeclaration::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const Variables &PredicateDeclaration::parameters() const
|
||||
{
|
||||
return m_parameters;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PredicateDeclaration::normalizeParameterNames()
|
||||
{
|
||||
for (size_t i = 0; i < m_parameters.size(); i++)
|
||||
m_parameters[i]->setName("X" + std::to_string(i));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PredicateDeclaration::print(std::ostream &ostream) const
|
||||
{
|
||||
// TODO: implement correctly
|
||||
ostream << "(<predicate declaration>)";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,184 +0,0 @@
|
||||
#include <plasp/pddl/expressions/PrimitiveType.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
|
||||
#include <tokenize/TokenizerException.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PrimitiveType
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PrimitiveType::PrimitiveType()
|
||||
: m_isDirty{true}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PrimitiveType::PrimitiveType(std::string name)
|
||||
: m_isDirty{true},
|
||||
m_name{name}
|
||||
{
|
||||
BOOST_ASSERT(!m_name.empty());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PrimitiveType::parseDeclaration(Context &context, Domain &domain)
|
||||
{
|
||||
auto &types = domain.types();
|
||||
|
||||
context.tokenizer.skipWhiteSpace();
|
||||
|
||||
const auto typeName = context.tokenizer.getIdentifier();
|
||||
|
||||
const auto match = std::find_if(types.cbegin(), types.cend(),
|
||||
[&](const auto &primitiveType)
|
||||
{
|
||||
return primitiveType->name() == typeName;
|
||||
});
|
||||
|
||||
// Return existing primitive type
|
||||
if (match != types.cend())
|
||||
{
|
||||
auto *type = match->get();
|
||||
|
||||
type->setDirty();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
types.emplace_back(PrimitiveTypePointer(new PrimitiveType(typeName)));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PrimitiveType::parseTypedDeclaration(Context &context, Domain &domain)
|
||||
{
|
||||
auto &types = domain.types();
|
||||
|
||||
// Parse and store type
|
||||
parseDeclaration(context, domain);
|
||||
|
||||
context.tokenizer.skipWhiteSpace();
|
||||
|
||||
// Check for type inheritance
|
||||
if (!context.tokenizer.testAndSkip<char>('-'))
|
||||
return;
|
||||
|
||||
domain.checkRequirement(Requirement::Type::Typing);
|
||||
|
||||
// If existing, parse and store parent type
|
||||
auto parentType = parseAndFind(context, domain);
|
||||
|
||||
parentType->setDirty(false);
|
||||
|
||||
// Assign parent type to all types that were previously flagged
|
||||
std::for_each(types.begin(), types.end(),
|
||||
[&](auto &childType)
|
||||
{
|
||||
if (!childType->isDirty())
|
||||
return;
|
||||
|
||||
childType->m_parentTypes.push_back(parentType);
|
||||
childType->setDirty(false);
|
||||
});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PrimitiveTypePointer PrimitiveType::parseAndFind(Context &context, Domain &domain)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
auto &types = domain.types();
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
const auto typeName = tokenizer.getIdentifier();
|
||||
|
||||
if (typeName.empty())
|
||||
throw tokenize::TokenizerException(tokenizer, "no type supplied");
|
||||
|
||||
const auto match = std::find_if(types.cbegin(), types.cend(),
|
||||
[&](const auto &primitiveType)
|
||||
{
|
||||
return primitiveType->name() == typeName;
|
||||
});
|
||||
|
||||
if (match == types.cend())
|
||||
{
|
||||
// Only "object" is allowed as an implicit type
|
||||
if (typeName == "object" || typeName == "objects")
|
||||
{
|
||||
context.logger.log(output::Priority::Warning, tokenizer, "primitive type “" + typeName + "” should be declared");
|
||||
types.emplace_back(PrimitiveTypePointer(new PrimitiveType(typeName)));
|
||||
}
|
||||
else
|
||||
throw tokenize::TokenizerException(tokenizer, "type “" + typeName + "” used but never declared");
|
||||
|
||||
return types.back().get();
|
||||
}
|
||||
|
||||
auto *type = match->get();
|
||||
type->setDirty();
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PrimitiveType::setDirty(bool isDirty)
|
||||
{
|
||||
m_isDirty = isDirty;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool PrimitiveType::isDirty() const
|
||||
{
|
||||
return m_isDirty;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string &PrimitiveType::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const PrimitiveTypes &PrimitiveType::parentTypes() const
|
||||
{
|
||||
return m_parentTypes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PrimitiveType::print(std::ostream &ostream) const
|
||||
{
|
||||
// TODO: implement correctly
|
||||
ostream << "(<primitive type" << m_name << ">)";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
#include <plasp/pddl/expressions/Type.h>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/expressions/PrimitiveType.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Type
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PrimitiveTypePointer parseExistingPrimitiveType(Context &context,
|
||||
ExpressionContext &expressionContext)
|
||||
{
|
||||
return PrimitiveType::parseAndFind(context, expressionContext.domain);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
#include <plasp/pddl/expressions/Unsupported.h>
|
||||
|
||||
#include <plasp/pddl/IO.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Unsupported
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
UnsupportedPointer Unsupported::parse(Context &context)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
auto expression = UnsupportedPointer(new Unsupported);
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
|
||||
expression->m_type = tokenizer.getIdentifier();
|
||||
|
||||
context.logger.log(output::Priority::Warning, tokenizer, "expression type “" + expression->m_type + "” currently unsupported in this context");
|
||||
|
||||
skipSection(tokenizer);
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string &Unsupported::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Unsupported::print(std::ostream &ostream) const
|
||||
{
|
||||
// TODO: implement correctly
|
||||
ostream << "(<unsupported expression “" << m_type << "”>)";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,210 +0,0 @@
|
||||
#include <plasp/pddl/expressions/Variable.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/expressions/Either.h>
|
||||
#include <plasp/pddl/expressions/PrimitiveType.h>
|
||||
#include <plasp/pddl/expressions/Type.h>
|
||||
|
||||
#include <tokenize/TokenizerException.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Variable
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Variable::Variable()
|
||||
: m_isDirty{false}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Variable::Variable(std::string name)
|
||||
: m_isDirty{false},
|
||||
m_name{name}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Variable::parseDeclaration(Context &context, Variables ¶meters)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
tokenizer.expect<std::string>("?");
|
||||
|
||||
auto variable = VariablePointer(new Variable);
|
||||
|
||||
variable->m_name = tokenizer.getIdentifier();
|
||||
|
||||
// Check if variable of that name already exists in the current scope
|
||||
const auto match = std::find_if(parameters.cbegin(), parameters.cend(),
|
||||
[&](const auto ¶meter)
|
||||
{
|
||||
return parameter->name() == variable->m_name;
|
||||
});
|
||||
|
||||
if (match != parameters.cend())
|
||||
throw tokenize::TokenizerException(tokenizer, "variable “" + variable->m_name + "” already declared in this scope");
|
||||
|
||||
// Flag variable for potentially upcoming type declaration
|
||||
variable->setDirty();
|
||||
|
||||
parameters.emplace_back(variable);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expressionContext,
|
||||
Variables &variables)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
// Parse and store variable itself
|
||||
parseDeclaration(context, variables);
|
||||
|
||||
auto variable = variables.back();
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Check if the variable has a type declaration
|
||||
if (!tokenizer.testAndSkip<char>('-'))
|
||||
return;
|
||||
|
||||
const auto setType =
|
||||
[&](ExpressionPointer type)
|
||||
{
|
||||
// Set the argument type for all previously flagged arguments
|
||||
for (auto &variable : variables)
|
||||
{
|
||||
if (!variable->isDirty())
|
||||
return;
|
||||
|
||||
variable->setType(type);
|
||||
variable->setDirty(false);
|
||||
}
|
||||
};
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
|
||||
// Parse argument if it has "either" type (always begins with opening parenthesis)
|
||||
variable->m_type = Either::parse(context, expressionContext, parseExistingPrimitiveType);
|
||||
|
||||
// Else, try parsing it as a primitive type
|
||||
if (!variable->m_type)
|
||||
variable->m_type = PrimitiveType::parseAndFind(context, expressionContext.domain);
|
||||
|
||||
setType(variable->m_type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Variable::parseTypedDeclarations(Context &context, ExpressionContext &expressionContext,
|
||||
Variables &variables)
|
||||
{
|
||||
auto &tokenizer = context.tokenizer;
|
||||
|
||||
while (tokenizer.currentCharacter() != ')')
|
||||
{
|
||||
parseTypedDeclaration(context, expressionContext, variables);
|
||||
|
||||
tokenizer.skipWhiteSpace();
|
||||
}
|
||||
|
||||
if (variables.empty())
|
||||
return;
|
||||
|
||||
// Check correct use of typing requirement
|
||||
const auto typingUsed = (variables.back()->type() != nullptr);
|
||||
|
||||
// If types are given, check that typing is a requirement
|
||||
if (typingUsed)
|
||||
expressionContext.checkRequirement(Requirement::Type::Typing);
|
||||
// If no types are given, check that typing is not a requirement
|
||||
else if (expressionContext.hasRequirement(Requirement::Type::Typing))
|
||||
throw tokenize::TokenizerException(tokenizer, "variable has undeclared type");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Variable::setName(std::string name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string &Variable::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Variable::setType(ExpressionPointer type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer Variable::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Variable::setDirty(bool isDirty)
|
||||
{
|
||||
m_isDirty = isDirty;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Variable::isDirty() const
|
||||
{
|
||||
return m_isDirty;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Variable::collectParameters(std::set<VariablePointer> ¶meters)
|
||||
{
|
||||
parameters.emplace(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Variable::print(std::ostream &ostream) const
|
||||
{
|
||||
ostream << "?" << m_name;
|
||||
|
||||
if (m_type)
|
||||
{
|
||||
ostream << " - ";
|
||||
m_type->print(ostream);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
#include <plasp/pddl/expressions/When.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// When
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string When::Identifier = "when";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -7,6 +7,8 @@ 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
|
||||
${PROJECT_SOURCE_DIR}/lib/pddlparse/include
|
||||
)
|
||||
|
||||
set(libraries
|
||||
|
@ -1,19 +1,8 @@
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <plasp/pddl/expressions/And.h>
|
||||
#include <plasp/pddl/expressions/Dummy.h>
|
||||
#include <plasp/pddl/expressions/Exists.h>
|
||||
#include <plasp/pddl/expressions/ForAll.h>
|
||||
#include <plasp/pddl/expressions/Imply.h>
|
||||
#include <plasp/pddl/expressions/Not.h>
|
||||
#include <plasp/pddl/expressions/Or.h>
|
||||
#include <plasp/pddl/expressions/Variable.h>
|
||||
|
||||
using namespace plasp::pddl;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("[PDDL normalization] PDDL expressions are correctly reduced", "[PDDL normalization]")
|
||||
/*TEST_CASE("[PDDL normalization] PDDL expressions are correctly reduced", "[PDDL normalization]")
|
||||
{
|
||||
auto n1 = expressions::NotPointer(new expressions::Not);
|
||||
auto n2 = expressions::NotPointer(new expressions::Not);
|
||||
@ -205,4 +194,4 @@ TEST_CASE("[PDDL normalization] “for all” expressions are correctly replaced
|
||||
f1->normalized()->print(output);
|
||||
|
||||
CHECK(output.str() == "(exists (?x ?y) (not (exists (?z ?u ?v ?w) (not (a)))))");
|
||||
}
|
||||
}*/
|
||||
|
@ -1,532 +0,0 @@
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <plasp/pddl/ConsistencyException.h>
|
||||
#include <plasp/pddl/Description.h>
|
||||
#include <plasp/pddl/expressions/And.h>
|
||||
#include <plasp/pddl/expressions/Either.h>
|
||||
#include <plasp/pddl/expressions/Not.h>
|
||||
#include <plasp/pddl/expressions/Predicate.h>
|
||||
#include <plasp/pddl/expressions/PrimitiveType.h>
|
||||
|
||||
using namespace plasp::pddl;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("[PDDL parser] The Blocks World domain is parsed correctly", "[PDDL parser]")
|
||||
{
|
||||
plasp::output::Logger logger;
|
||||
Context context(Tokenizer(), logger);
|
||||
|
||||
const auto description = Description::fromFile("data/blocksworld-domain.pddl", context);
|
||||
|
||||
REQUIRE_NOTHROW(description.domain());
|
||||
|
||||
const auto &domain = description.domain();
|
||||
|
||||
// Name
|
||||
CHECK(domain.name() == "blocks");
|
||||
|
||||
// Requirements
|
||||
REQUIRE(domain.requirements().size() == 2u);
|
||||
CHECK(domain.requirements()[0].type() == Requirement::Type::STRIPS);
|
||||
CHECK(domain.requirements()[1].type() == Requirement::Type::Typing);
|
||||
|
||||
// Types
|
||||
REQUIRE(domain.types().size() == 1u);
|
||||
|
||||
const auto &block = *domain.types()[0];
|
||||
|
||||
CHECK(block.name() == "block");
|
||||
REQUIRE(block.parentTypes().size() == 0u);
|
||||
|
||||
// Predicates
|
||||
REQUIRE(domain.predicates().size() == 5u);
|
||||
|
||||
const auto &on = *domain.predicates()[0];
|
||||
|
||||
CHECK(on.name() == "on");
|
||||
REQUIRE(on.parameters().size() == 2u);
|
||||
CHECK(on.parameters()[0]->name() == "x");
|
||||
const auto &onArgument0Type = on.parameters()[0]->type()->as<expressions::PrimitiveType>();
|
||||
CHECK(&onArgument0Type == &block);
|
||||
CHECK(on.parameters()[1]->name() == "y");
|
||||
const auto &onArgument1Type = on.parameters()[1]->type()->as<expressions::PrimitiveType>();
|
||||
CHECK(&onArgument1Type == &block);
|
||||
|
||||
const auto &handempty = *domain.predicates()[3];
|
||||
|
||||
CHECK(handempty.name() == "handempty");
|
||||
CHECK(handempty.parameters().empty());
|
||||
|
||||
// Actions
|
||||
REQUIRE(domain.actions().size() == 4u);
|
||||
|
||||
const auto &pickUp = *domain.actions()[0];
|
||||
|
||||
CHECK(pickUp.name() == "pick-up");
|
||||
REQUIRE(pickUp.parameters().size() == 1u);
|
||||
CHECK(pickUp.parameters()[0]->name() == "x");
|
||||
CHECK(pickUp.parameters()[0]->type() == &block);
|
||||
|
||||
const auto &pickUpPre = pickUp.precondition()->as<expressions::And>();
|
||||
REQUIRE(pickUpPre.arguments().size() == 3u);
|
||||
const auto &pickUpPre0 = pickUpPre.arguments()[0]->as<expressions::Predicate>();
|
||||
CHECK(pickUpPre0.name() == "clear");
|
||||
REQUIRE(pickUpPre0.arguments().size() == 1u);
|
||||
const auto &pickUpPre00 = pickUpPre0.arguments()[0]->as<expressions::Variable>();
|
||||
CHECK(pickUpPre00.name() == "x");
|
||||
CHECK(pickUpPre00.type() == &block);
|
||||
CHECK(&pickUpPre00 == pickUp.parameters()[0].get());
|
||||
const auto &pickUpPre2 = pickUpPre.arguments()[2]->as<expressions::Predicate>();
|
||||
CHECK(pickUpPre2.name() == "handempty");
|
||||
CHECK(pickUpPre2.arguments().empty());
|
||||
|
||||
const auto &pickUpEff = pickUp.effect()->as<expressions::And>();
|
||||
REQUIRE(pickUpEff.arguments().size() == 4u);
|
||||
const auto &pickUpEff0 = pickUpEff.arguments()[0]->as<expressions::Not>();
|
||||
const auto &pickUpEff00 = pickUpEff0.argument()->as<expressions::Predicate>();
|
||||
CHECK(pickUpEff00.name() == "ontable");
|
||||
REQUIRE(pickUpEff00.arguments().size() == 1u);
|
||||
const auto &pickUpEff000 = pickUpEff00.arguments()[0]->as<expressions::Variable>();
|
||||
CHECK(pickUpEff000.name() == "x");
|
||||
CHECK(pickUpEff000.type() == &block);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("[PDDL parser] A Blocks World problem is parsed correctly", "[PDDL parser]")
|
||||
{
|
||||
plasp::output::Logger logger;
|
||||
Context context(Tokenizer(), logger);
|
||||
|
||||
const auto description = Description::fromFiles({"data/blocksworld-domain.pddl", "data/blocksworld-problem.pddl"}, context);
|
||||
|
||||
REQUIRE_NOTHROW(description.problem());
|
||||
|
||||
const auto &problem = description.problem();
|
||||
|
||||
// Name
|
||||
CHECK(problem.name() == "blocks-4-0");
|
||||
CHECK(problem.domain().name() == "blocks");
|
||||
|
||||
// Requirements
|
||||
// TODO: compute domain vs. problem requirements correctly and check them
|
||||
|
||||
// Objects
|
||||
REQUIRE(problem.objects().size() == 4u);
|
||||
|
||||
CHECK(problem.objects()[0]->name() == "d");
|
||||
REQUIRE(problem.objects()[0]->type() != nullptr);
|
||||
CHECK(problem.objects()[0]->type()->name() == "block");
|
||||
CHECK(problem.objects()[3]->name() == "c");
|
||||
REQUIRE(problem.objects()[3]->type() != nullptr);
|
||||
CHECK(problem.objects()[3]->type()->name() == "block");
|
||||
|
||||
// Initial State
|
||||
const auto &facts = problem.initialState().facts();
|
||||
|
||||
REQUIRE(facts.size() == 9u);
|
||||
const auto &fact0 = facts[0].get()->as<expressions::Predicate>();
|
||||
CHECK(fact0.name() == "clear");
|
||||
REQUIRE(fact0.arguments().size() == 1u);
|
||||
const auto &fact00 = fact0.arguments()[0]->as<expressions::Constant>();
|
||||
CHECK(fact00.name() == "c");
|
||||
REQUIRE(fact00.type() != nullptr);
|
||||
CHECK(fact00.type()->name() == "block");
|
||||
const auto &fact8 = facts[8].get()->as<expressions::Predicate>();
|
||||
CHECK(fact8.name() == "handempty");
|
||||
REQUIRE(fact8.arguments().size() == 0u);
|
||||
|
||||
// Goal
|
||||
const auto &goal = problem.goal().as<expressions::And>();
|
||||
|
||||
REQUIRE(goal.arguments().size() == 3u);
|
||||
const auto &goal0 = goal.arguments()[0]->as<expressions::Predicate>();
|
||||
CHECK(goal0.name() == "on");
|
||||
REQUIRE(goal0.arguments().size() == 2u);
|
||||
const auto &goal00 = goal0.arguments()[0]->as<expressions::Constant>();
|
||||
CHECK(goal00.name() == "d");
|
||||
const auto &goal01 = goal0.arguments()[1]->as<expressions::Constant>();
|
||||
CHECK(goal01.name() == "c");
|
||||
const auto &goal2 = goal.arguments()[2]->as<expressions::Predicate>();
|
||||
CHECK(goal2.name() == "on");
|
||||
REQUIRE(goal2.arguments().size() == 2u);
|
||||
const auto &goal20 = goal2.arguments()[0]->as<expressions::Constant>();
|
||||
CHECK(goal20.name() == "b");
|
||||
const auto &goal21 = goal2.arguments()[1]->as<expressions::Constant>();
|
||||
CHECK(goal21.name() == "a");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("[PDDL parser] The Storage domain is parsed correctly", "[PDDL parser]")
|
||||
{
|
||||
plasp::output::Logger logger;
|
||||
Context context(Tokenizer(), logger);
|
||||
|
||||
const auto description = plasp::pddl::Description::fromFile("data/storage-domain.pddl", context);
|
||||
|
||||
REQUIRE_NOTHROW(description.domain());
|
||||
|
||||
const auto &domain = description.domain();
|
||||
|
||||
// Name
|
||||
CHECK(domain.name() == "storage-propositional");
|
||||
|
||||
// Requirements
|
||||
REQUIRE(domain.requirements().size() == 1u);
|
||||
CHECK(domain.requirements()[0].type() == Requirement::Type::Typing);
|
||||
|
||||
// Types
|
||||
REQUIRE(domain.types().size() == 10u);
|
||||
|
||||
const auto &hoist = *domain.types()[0];
|
||||
const auto &surface = *domain.types()[1];
|
||||
const auto &area = *domain.types()[3];
|
||||
const auto &object = *domain.types()[4];
|
||||
const auto &storearea = *domain.types()[7];
|
||||
const auto &crate = *domain.types()[9];
|
||||
|
||||
const auto &hoistParents = hoist.parentTypes();
|
||||
REQUIRE(hoistParents.size() == 1u);
|
||||
CHECK(std::find(hoistParents.cbegin(), hoistParents.cend(), &object) != hoistParents.cend());
|
||||
|
||||
const auto &areaParents = area.parentTypes();
|
||||
REQUIRE(areaParents.size() == 2u);
|
||||
CHECK(std::find(areaParents.cbegin(), areaParents.cend(), &object) != areaParents.cend());
|
||||
CHECK(std::find(areaParents.cbegin(), areaParents.cend(), &surface) != areaParents.cend());
|
||||
|
||||
// Predicates
|
||||
REQUIRE(domain.predicates().size() == 8u);
|
||||
|
||||
const auto &on = *domain.predicates()[5];
|
||||
|
||||
CHECK(on.name() == "on");
|
||||
REQUIRE(on.parameters().size() == 2u);
|
||||
CHECK(on.parameters()[0]->name() == "c");
|
||||
const auto &onArgument0Type = on.parameters()[0]->type()->as<expressions::PrimitiveType>();
|
||||
CHECK(&onArgument0Type == &crate);
|
||||
CHECK(on.parameters()[1]->name() == "s");
|
||||
const auto &onArgument1Type = on.parameters()[1]->type()->as<expressions::PrimitiveType>();
|
||||
CHECK(&onArgument1Type == &storearea);
|
||||
|
||||
const auto &in = *domain.predicates()[1];
|
||||
CHECK(in.name() == "in");
|
||||
REQUIRE(in.parameters().size() == 2u);
|
||||
CHECK(in.parameters()[0]->name() == "x");
|
||||
const auto &inArgument0Type = in.parameters()[0]->type()->as<expressions::Either>();
|
||||
REQUIRE(inArgument0Type.arguments().size() == 2u);
|
||||
const auto &inArgument0Type0 = inArgument0Type.arguments()[0]->as<expressions::PrimitiveType>();
|
||||
CHECK(&inArgument0Type0 == &storearea);
|
||||
const auto &inArgument0Type1 = inArgument0Type.arguments()[1]->as<expressions::PrimitiveType>();
|
||||
CHECK(&inArgument0Type1 == &crate);
|
||||
|
||||
// Actions
|
||||
REQUIRE(domain.actions().size() == 5u);
|
||||
|
||||
const auto &drop = *domain.actions()[1];
|
||||
|
||||
CHECK(drop.name() == "drop");
|
||||
REQUIRE(drop.parameters().size() == 5u);
|
||||
CHECK(drop.parameters()[3]->name() == "a2");
|
||||
CHECK(drop.parameters()[3]->type() == &area);
|
||||
|
||||
const auto &dropPre = drop.precondition()->as<expressions::And>();
|
||||
REQUIRE(dropPre.arguments().size() == 5u);
|
||||
const auto &dropPre2 = dropPre.arguments()[2]->as<expressions::Predicate>();
|
||||
CHECK(dropPre2.name() == "lifting");
|
||||
REQUIRE(dropPre2.arguments().size() == 2u);
|
||||
const auto &dropPre21 = dropPre2.arguments()[1]->as<expressions::Variable>();
|
||||
CHECK(dropPre21.name() == "c");
|
||||
CHECK(dropPre21.type() == &crate);
|
||||
|
||||
const auto &dropEff = drop.effect()->as<expressions::And>();
|
||||
REQUIRE(dropEff.arguments().size() == 5u);
|
||||
const auto &dropEff2 = dropEff.arguments()[2]->as<expressions::Not>();
|
||||
const auto &dropEff20 = dropEff2.argument()->as<expressions::Predicate>();
|
||||
CHECK(dropEff20.name() == "clear");
|
||||
REQUIRE(dropEff20.arguments().size() == 1u);
|
||||
const auto &dropEff200 = dropEff20.arguments()[0]->as<expressions::Variable>();
|
||||
CHECK(dropEff200.name() == "a1");
|
||||
CHECK(dropEff200.type() == &storearea);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("[PDDL parser] A Storage problem is parsed correctly", "[PDDL parser]")
|
||||
{
|
||||
plasp::output::Logger logger;
|
||||
Context context(Tokenizer(), logger);
|
||||
|
||||
const auto description = Description::fromFiles({"data/storage-domain.pddl", "data/storage-problem.pddl"}, context);
|
||||
|
||||
REQUIRE_NOTHROW(description.problem());
|
||||
|
||||
const auto &problem = description.problem();
|
||||
|
||||
// Name
|
||||
CHECK(problem.name() == "storage-1");
|
||||
CHECK(problem.domain().name() == "storage-propositional");
|
||||
|
||||
// Requirements
|
||||
// TODO: compute domain vs. problem requirements correctly and check them
|
||||
|
||||
// Objects
|
||||
REQUIRE(problem.objects().size() == 7u);
|
||||
|
||||
CHECK(problem.objects()[0]->name() == "depot0-1-1");
|
||||
REQUIRE(problem.objects()[0]->type() != nullptr);
|
||||
CHECK(problem.objects()[0]->type()->name() == "storearea");
|
||||
CHECK(problem.objects()[6]->name() == "loadarea");
|
||||
REQUIRE(problem.objects()[6]->type() != nullptr);
|
||||
CHECK(problem.objects()[6]->type()->name() == "transitarea");
|
||||
|
||||
// Initial State
|
||||
const auto &facts = problem.initialState().facts();
|
||||
|
||||
REQUIRE(facts.size() == 10u);
|
||||
const auto &fact0 = facts[0].get()->as<expressions::Predicate>();
|
||||
CHECK(fact0.name() == "in");
|
||||
REQUIRE(fact0.arguments().size() == 2u);
|
||||
const auto &fact01 = fact0.arguments()[1]->as<expressions::Constant>();
|
||||
CHECK(fact01.name() == "depot0");
|
||||
REQUIRE(fact01.type() != nullptr);
|
||||
CHECK(fact01.type()->name() == "depot");
|
||||
const auto &fact9 = facts[9].get()->as<expressions::Predicate>();
|
||||
CHECK(fact9.name() == "available");
|
||||
REQUIRE(fact9.arguments().size() == 1u);
|
||||
const auto &fact90 = fact9.arguments()[0]->as<expressions::Constant>();
|
||||
CHECK(fact90.name() == "hoist0");
|
||||
REQUIRE(fact90.type() != nullptr);
|
||||
CHECK(fact90.type()->name() == "hoist");
|
||||
|
||||
// Goal
|
||||
const auto &goal = problem.goal().as<expressions::And>();
|
||||
|
||||
REQUIRE(goal.arguments().size() == 1u);
|
||||
const auto &goal0 = goal.arguments()[0]->as<expressions::Predicate>();
|
||||
CHECK(goal0.name() == "in");
|
||||
REQUIRE(goal0.arguments().size() == 2u);
|
||||
const auto &goal00 = goal0.arguments()[0]->as<expressions::Constant>();
|
||||
CHECK(goal00.name() == "crate0");
|
||||
const auto &goal01 = goal0.arguments()[1]->as<expressions::Constant>();
|
||||
CHECK(goal01.name() == "depot0");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("[PDDL parser] Constants are parsed correctly", "[PDDL parser]")
|
||||
{
|
||||
plasp::output::Logger logger;
|
||||
Context context(Tokenizer(), logger);
|
||||
|
||||
const auto description = Description::fromFile("data/woodworking-domain.pddl", context);
|
||||
|
||||
REQUIRE_NOTHROW(description.domain());
|
||||
|
||||
const auto &domain = description.domain();
|
||||
|
||||
// Name
|
||||
CHECK(domain.name() == "woodworking");
|
||||
|
||||
// Types
|
||||
const auto &acolour = *domain.types()[0];
|
||||
const auto &surface = *domain.types()[4];
|
||||
const auto &treatmentstatus = *domain.types()[5];
|
||||
|
||||
// Constants
|
||||
REQUIRE(domain.constants().size() == 8u);
|
||||
CHECK(domain.constants()[0]->type() == &surface);
|
||||
CHECK(domain.constants()[2]->type() == &surface);
|
||||
CHECK(domain.constants()[3]->type() == &treatmentstatus);
|
||||
CHECK(domain.constants()[6]->type() == &treatmentstatus);
|
||||
CHECK(domain.constants()[7]->type() == &acolour);
|
||||
|
||||
// TODO: add test with constants in predicates
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("[PDDL parser] White spaces are ignored", "[PDDL parser]")
|
||||
{
|
||||
plasp::output::Logger logger;
|
||||
Context context(Tokenizer(), logger);
|
||||
|
||||
CHECK_NOTHROW(Description::fromFile("data/test-cases/white-space.pddl", context));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("[PDDL parser] Missing or unmatching domain descriptions are detected", "[PDDL parser]")
|
||||
{
|
||||
plasp::output::Logger logger;
|
||||
Context context(Tokenizer(), logger);
|
||||
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS_AS(Description::fromFile("data/blocksworld-problem.pddl", context), ConsistencyException);
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS_AS(Description::fromFiles({"data/blocksworld-problem.pddl", "data/storage-domain.pddl"}, context), tokenize::TokenizerException);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("[PDDL parser] Common PDDL syntax errors are detected", "[PDDL parser]")
|
||||
{
|
||||
plasp::output::Logger logger;
|
||||
Context context(Tokenizer(), logger);
|
||||
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_NOTHROW(Description::fromFile("data/pddl-syntax/domain-valid.pddl", context));
|
||||
}
|
||||
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-expressions-1.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-expressions-2.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-expressions-3.pddl", context));
|
||||
}
|
||||
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-expression-name-1.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-expression-name-2.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-expression-name-3.pddl", context));
|
||||
}
|
||||
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-parentheses-1.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-parentheses-2.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-parentheses-3.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-parentheses-4.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-parentheses-5.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-parentheses-6.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-parentheses-7.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-parentheses-8.pddl", context));
|
||||
}
|
||||
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-section-name-1.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-section-name-2.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-section-name-3.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-section-name-4.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-section-name-5.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-section-name-6.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-section-name-7.pddl", context));
|
||||
}
|
||||
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-types-1.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-types-2.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-types-3.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-types-4.pddl", context));
|
||||
}
|
||||
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-variables-1.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-variables-2.pddl", context));
|
||||
}
|
||||
SECTION("")
|
||||
{
|
||||
CHECK_THROWS(Description::fromFile("data/pddl-syntax/domain-variables-3.pddl", context));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("[PDDL parser] Former issues are fixed", "[PDDL parser]")
|
||||
{
|
||||
plasp::output::Logger logger;
|
||||
Context context(Tokenizer(), logger);
|
||||
|
||||
SECTION("white space issues with constants and parsing unsupported sections")
|
||||
{
|
||||
CHECK_NOTHROW(Description::fromFile("data/issues/issue-1.pddl", context));
|
||||
}
|
||||
|
||||
SECTION("white space issues with empty n-ary predicates")
|
||||
{
|
||||
CHECK_NOTHROW(Description::fromFile("data/issues/issue-2.pddl", context));
|
||||
}
|
||||
|
||||
SECTION("comments are correctly ignored")
|
||||
{
|
||||
CHECK_NOTHROW(Description::fromFile("data/issues/issue-3.pddl", context));
|
||||
}
|
||||
}
|
@ -3,31 +3,37 @@
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#include <boost/iostreams/device/null.hpp>
|
||||
|
||||
#include <plasp/pddl/Description.h>
|
||||
#include <pddlparse/AST.h>
|
||||
#include <pddlparse/Parse.h>
|
||||
|
||||
#include <plasp/output/Logger.h>
|
||||
#include <plasp/pddl/TranslatorASP.h>
|
||||
|
||||
using namespace plasp::pddl;
|
||||
|
||||
boost::iostreams::stream<boost::iostreams::null_sink> nullStream((boost::iostreams::null_sink()));
|
||||
const pddl::Context::WarningCallback ignoreWarnings = [](const auto &, const auto &){};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_CASE("[PDDL translation] Former issues are fixed", "[PDDL translation]")
|
||||
{
|
||||
plasp::output::Logger logger;
|
||||
Context context(Tokenizer(), logger);
|
||||
// TODO: refactor
|
||||
plasp::output::Logger logger(nullStream, nullStream);
|
||||
pddl::Tokenizer tokenizer;
|
||||
pddl::Context context(std::move(tokenizer), ignoreWarnings);
|
||||
|
||||
SECTION("translating domains without typing information works")
|
||||
{
|
||||
auto description = Description::fromFile("data/issues/issue-4.pddl", context);
|
||||
const auto translator = TranslatorASP(description, description.context().logger.outputStream());
|
||||
context.tokenizer.read("data/issues/issue-4.pddl");
|
||||
auto description = pddl::parseDescription(context);
|
||||
const auto translator = plasp::pddl::TranslatorASP(std::move(description), logger.outputStream());
|
||||
CHECK_NOTHROW(translator.translate());
|
||||
}
|
||||
|
||||
SECTION("translating the simple blocks world domain works")
|
||||
{
|
||||
auto description = Description::fromFile("data/issues/issue-5.pddl", context);
|
||||
const auto translator = TranslatorASP(description, description.context().logger.outputStream());
|
||||
context.tokenizer.read("data/issues/issue-5.pddl");
|
||||
auto description = pddl::parseDescription(context);
|
||||
const auto translator = plasp::pddl::TranslatorASP(std::move(description), logger.outputStream());
|
||||
CHECK_NOTHROW(translator.translate());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user