Refactoring to make parsing expressions consistent across PDDL domains and problems.
This commit is contained in:
		@@ -21,7 +21,7 @@ namespace pddl
 | 
			
		||||
class Action
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		static Action &parseDeclaration(Context &context);
 | 
			
		||||
		static void parseDeclaration(Context &context, Domain &domain);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		const std::string &name() const;
 | 
			
		||||
 
 | 
			
		||||
@@ -5,11 +5,6 @@
 | 
			
		||||
#include <unordered_map>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include <plasp/pddl/Action.h>
 | 
			
		||||
#include <plasp/pddl/Expression.h>
 | 
			
		||||
#include <plasp/pddl/expressions/Constant.h>
 | 
			
		||||
#include <plasp/pddl/expressions/PredicateDeclaration.h>
 | 
			
		||||
#include <plasp/pddl/expressions/PrimitiveType.h>
 | 
			
		||||
#include <plasp/utils/Logger.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
@@ -33,17 +28,6 @@ class Context
 | 
			
		||||
 | 
			
		||||
		utils::Parser &parser;
 | 
			
		||||
		utils::Logger logger;
 | 
			
		||||
 | 
			
		||||
		expressions::PrimitiveTypes primitiveTypes;
 | 
			
		||||
		//std::unordered_map<std::string, expressions::PrimitiveType *> primitiveTypesHashMap;
 | 
			
		||||
 | 
			
		||||
		expressions::Constants constants;
 | 
			
		||||
		//std::unordered_map<std::string, expressions::Constant *> constantsHashMap;
 | 
			
		||||
 | 
			
		||||
		expressions::PredicateDeclarations predicateDeclarations;
 | 
			
		||||
		//std::unordered_map<expressions::PredicateHashMapKey, expressions::Predicate *> predicatesHashMap;
 | 
			
		||||
 | 
			
		||||
		std::vector<std::unique_ptr<Action>> actions;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,8 @@ class Description
 | 
			
		||||
		void parseContent();
 | 
			
		||||
		void parseSection();
 | 
			
		||||
 | 
			
		||||
		void checkConsistency();
 | 
			
		||||
 | 
			
		||||
		utils::Parser m_parser;
 | 
			
		||||
		Context m_context;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,12 @@
 | 
			
		||||
#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/expressions/Constant.h>
 | 
			
		||||
#include <plasp/pddl/expressions/PredicateDeclaration.h>
 | 
			
		||||
#include <plasp/pddl/expressions/PrimitiveType.h>
 | 
			
		||||
#include <plasp/pddl/Requirement.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
@@ -19,19 +23,32 @@ namespace pddl
 | 
			
		||||
class Domain
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		static Domain fromPDDL(Context &context);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		const std::string &name() const;
 | 
			
		||||
		const Requirements &requirements() const;
 | 
			
		||||
		const expressions::PrimitiveTypes &types() const;
 | 
			
		||||
		const expressions::Constants &constants() const;
 | 
			
		||||
		const expressions::PredicateDeclarations &predicates() const;
 | 
			
		||||
		const std::vector<std::unique_ptr<Action>> &actions() const;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		Domain(Context &context);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		void readPDDL();
 | 
			
		||||
 | 
			
		||||
		bool isDeclared() const;
 | 
			
		||||
 | 
			
		||||
		const std::string &name() const;
 | 
			
		||||
 | 
			
		||||
		const Requirements &requirements() const;
 | 
			
		||||
 | 
			
		||||
		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;
 | 
			
		||||
 | 
			
		||||
		void checkConsistency();
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		void parseSection();
 | 
			
		||||
 | 
			
		||||
		void parseRequirementSection();
 | 
			
		||||
@@ -46,12 +63,15 @@ class Domain
 | 
			
		||||
 | 
			
		||||
		void parseActionSection();
 | 
			
		||||
 | 
			
		||||
		void checkConsistency();
 | 
			
		||||
 | 
			
		||||
		Context &m_context;
 | 
			
		||||
		bool m_isDeclared;
 | 
			
		||||
 | 
			
		||||
		std::string m_name;
 | 
			
		||||
		Requirements m_requirements;
 | 
			
		||||
		expressions::PrimitiveTypes m_primitiveTypes;
 | 
			
		||||
		expressions::Constants m_constants;
 | 
			
		||||
		expressions::PredicateDeclarations m_predicateDeclarations;
 | 
			
		||||
		std::vector<std::unique_ptr<Action>> m_actions;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,10 @@ namespace pddl
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
class Context;
 | 
			
		||||
class Domain;
 | 
			
		||||
class ExpressionContext;
 | 
			
		||||
class ExpressionVisitor;
 | 
			
		||||
class Problem;
 | 
			
		||||
 | 
			
		||||
class Expression;
 | 
			
		||||
using ExpressionPointer = std::unique_ptr<Expression>;
 | 
			
		||||
@@ -77,10 +80,11 @@ class Expression
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
ExpressionPointer parsePreconditionExpression(Context &context,
 | 
			
		||||
	const expressions::Variables ¶meters);
 | 
			
		||||
ExpressionPointer parseExpression(Context &context, const expressions::Variables ¶meters);
 | 
			
		||||
	ExpressionContext &expressionContext);
 | 
			
		||||
ExpressionPointer parseExpression(Context &context, ExpressionContext &expressionContext);
 | 
			
		||||
 | 
			
		||||
ExpressionPointer parseEffectExpression(Context &context, const expressions::Variables ¶meters);
 | 
			
		||||
ExpressionPointer parseEffectExpression(Context &context,
 | 
			
		||||
	ExpressionContext &expressionContext);
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										46
									
								
								include/plasp/pddl/ExpressionContext.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								include/plasp/pddl/ExpressionContext.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
#ifndef __PLASP__PDDL__EXPRESSION_CONTEXT_H
 | 
			
		||||
#define __PLASP__PDDL__EXPRESSION_CONTEXT_H
 | 
			
		||||
 | 
			
		||||
#include <plasp/pddl/Expression.h>
 | 
			
		||||
#include <plasp/pddl/Requirement.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
namespace pddl
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//
 | 
			
		||||
// ExpressionContext
 | 
			
		||||
//
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
class ExpressionContext
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		ExpressionContext(Domain &domain, expressions::Variables ¶meters)
 | 
			
		||||
		:	domain(domain),
 | 
			
		||||
			problem(nullptr),
 | 
			
		||||
			parameters(parameters)
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ExpressionContext(Domain &domain, Problem *problem, expressions::Variables ¶meters)
 | 
			
		||||
		:	domain(domain),
 | 
			
		||||
			problem{problem},
 | 
			
		||||
			parameters(parameters)
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Domain &domain;
 | 
			
		||||
		Problem *problem;
 | 
			
		||||
 | 
			
		||||
		expressions::Variables ¶meters;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -19,15 +19,25 @@ namespace pddl
 | 
			
		||||
class Problem
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		static Problem fromPDDL(Context &context);
 | 
			
		||||
		Problem(Context &context, Domain &domain);
 | 
			
		||||
 | 
			
		||||
		void readPDDL();
 | 
			
		||||
 | 
			
		||||
		bool isDeclared() const;
 | 
			
		||||
 | 
			
		||||
		Domain &domain();
 | 
			
		||||
		const Domain &domain() const;
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		const std::string &name() const;
 | 
			
		||||
 | 
			
		||||
		const Requirements &requirements() const;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		Problem(Context &context);
 | 
			
		||||
		expressions::Constants &objects();
 | 
			
		||||
		const expressions::Constants &objects() const;
 | 
			
		||||
 | 
			
		||||
		void checkConsistency();
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		void parseSection();
 | 
			
		||||
 | 
			
		||||
		void parseRequirementSection();
 | 
			
		||||
@@ -36,9 +46,9 @@ class Problem
 | 
			
		||||
 | 
			
		||||
		void parseObjectSection();
 | 
			
		||||
 | 
			
		||||
		void checkConsistency();
 | 
			
		||||
 | 
			
		||||
		Context &m_context;
 | 
			
		||||
		Domain &m_domain;
 | 
			
		||||
		bool m_isDeclared;
 | 
			
		||||
 | 
			
		||||
		std::string m_name;
 | 
			
		||||
		Requirements m_requirements;
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ class And: public NAry
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		template<typename ExpressionParser>
 | 
			
		||||
		static AndPointer parse(Context &context, const Variables ¶meters,
 | 
			
		||||
		static AndPointer parse(Context &context, ExpressionContext &expressionContext,
 | 
			
		||||
			ExpressionParser parseExpression);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
@@ -33,12 +33,12 @@ class And: public NAry
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<typename ExpressionParser>
 | 
			
		||||
AndPointer And::parse(Context &context, const Variables ¶meters,
 | 
			
		||||
AndPointer And::parse(Context &context, ExpressionContext &expressionContext,
 | 
			
		||||
	ExpressionParser parseExpression)
 | 
			
		||||
{
 | 
			
		||||
	auto expression = std::make_unique<And>(And());
 | 
			
		||||
 | 
			
		||||
	expression->NAry::parse(context, parameters, parseExpression);
 | 
			
		||||
	expression->NAry::parse(context, expressionContext, parseExpression);
 | 
			
		||||
 | 
			
		||||
	if (expression->arguments().empty())
 | 
			
		||||
		throw ConsistencyException("\"and\" expressions should not be empty");
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,8 @@ class Binary: public Expression
 | 
			
		||||
 | 
			
		||||
	protected:
 | 
			
		||||
		template<typename ExpressionParser>
 | 
			
		||||
		void parse(Context &context, const Variables ¶meters, ExpressionParser parseExpression);
 | 
			
		||||
		void parse(Context &context, ExpressionContext &expressionContext,
 | 
			
		||||
			ExpressionParser parseExpression);
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		ExpressionPointer m_leftArgument;
 | 
			
		||||
@@ -37,12 +38,13 @@ class Binary: public Expression
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<typename ExpressionParser>
 | 
			
		||||
void Binary::parse(Context &context, const Variables ¶meters, ExpressionParser parseExpression)
 | 
			
		||||
void Binary::parse(Context &context, ExpressionContext &expressionContext,
 | 
			
		||||
	ExpressionParser parseExpression)
 | 
			
		||||
{
 | 
			
		||||
	// Assume that expression identifier (imply, exists, etc.) is already parsed
 | 
			
		||||
	// Parse arguments of the expression
 | 
			
		||||
	m_leftArgument = parseExpression(context, parameters);
 | 
			
		||||
	m_rightArgument = parseExpression(context, parameters);
 | 
			
		||||
	m_leftArgument = parseExpression(context, expressionContext);
 | 
			
		||||
	m_rightArgument = parseExpression(context, expressionContext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -22,10 +22,10 @@ namespace expressions
 | 
			
		||||
class Constant: public Expression
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		static ConstantPointer parseDeclaration(Context &context);
 | 
			
		||||
		static void parseTypedDeclaration(Context &context, Constants &constants);
 | 
			
		||||
		static void parseTypedDeclaration(Context &context, Domain &domain);
 | 
			
		||||
		static void parseTypedDeclaration(Context &context, Problem &problem);
 | 
			
		||||
 | 
			
		||||
		static Constant *parseExisting(Context &context);
 | 
			
		||||
		static Constant *parseAndFind(Context &context, const ExpressionContext &expressionContext);
 | 
			
		||||
 | 
			
		||||
		// TODO: method for lazy creation if not existing
 | 
			
		||||
 | 
			
		||||
@@ -38,6 +38,11 @@ class Constant: public Expression
 | 
			
		||||
		bool isDeclared() const;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		static ConstantPointer parseDeclaration(Context &context);
 | 
			
		||||
		static void parseTypedDeclaration(Context &context, Domain &domain, Constants &constants);
 | 
			
		||||
 | 
			
		||||
		static Constant *parseAndFind(const std::string &constantName, const Constants &constants);
 | 
			
		||||
 | 
			
		||||
		Constant();
 | 
			
		||||
 | 
			
		||||
		void setDirty(bool isDirty = true);
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ class Either: public NAry
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		template<typename ExpressionParser>
 | 
			
		||||
		static EitherPointer parse(Context &context, const Variables ¶meters,
 | 
			
		||||
		static EitherPointer parse(Context &context, ExpressionContext &expressionContext,
 | 
			
		||||
			ExpressionParser parseExpression);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
@@ -33,12 +33,12 @@ class Either: public NAry
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<typename ExpressionParser>
 | 
			
		||||
EitherPointer Either::parse(Context &context, const Variables ¶meters,
 | 
			
		||||
EitherPointer Either::parse(Context &context, ExpressionContext &expressionContext,
 | 
			
		||||
	ExpressionParser parseExpression)
 | 
			
		||||
{
 | 
			
		||||
	auto expression = std::make_unique<Either>(Either());
 | 
			
		||||
 | 
			
		||||
	expression->NAry::parse(context, parameters, parseExpression);
 | 
			
		||||
	expression->NAry::parse(context, expressionContext, parseExpression);
 | 
			
		||||
 | 
			
		||||
	if (expression->arguments().empty())
 | 
			
		||||
		throw ConsistencyException("\"and\" expressions should not be empty");
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ class Imply: public Binary
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		template<typename ExpressionParser>
 | 
			
		||||
		static ImplyPointer parse(Context &context, const Variables ¶meters,
 | 
			
		||||
		static ImplyPointer parse(Context &context, ExpressionContext ¶meters,
 | 
			
		||||
			ExpressionParser parseExpression);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
@@ -33,7 +33,7 @@ class Imply: public Binary
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<typename ExpressionParser>
 | 
			
		||||
ImplyPointer Imply::parse(Context &context, const Variables ¶meters,
 | 
			
		||||
ImplyPointer Imply::parse(Context &context, ExpressionContext ¶meters,
 | 
			
		||||
	ExpressionParser parseExpression)
 | 
			
		||||
{
 | 
			
		||||
	auto expression = std::make_unique<Imply>(Imply());
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ class NAry: public Expression
 | 
			
		||||
 | 
			
		||||
	protected:
 | 
			
		||||
		template<typename ExpressionParser>
 | 
			
		||||
		void parse(Context &context, const Variables ¶meters, ExpressionParser parseExpression);
 | 
			
		||||
		void parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression);
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		Expressions m_arguments;
 | 
			
		||||
@@ -35,7 +35,7 @@ class NAry: public Expression
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<typename ExpressionParser>
 | 
			
		||||
void NAry::parse(Context &context, const Variables ¶meters, ExpressionParser parseExpression)
 | 
			
		||||
void NAry::parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression)
 | 
			
		||||
{
 | 
			
		||||
	context.parser.skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
@@ -43,7 +43,7 @@ void NAry::parse(Context &context, const Variables ¶meters, ExpressionParser
 | 
			
		||||
	// Parse arguments of the expression
 | 
			
		||||
	while (context.parser.currentCharacter() != ')')
 | 
			
		||||
	{
 | 
			
		||||
		m_arguments.emplace_back(parseExpression(context, parameters));
 | 
			
		||||
		m_arguments.emplace_back(parseExpression(context, expressionContext));
 | 
			
		||||
 | 
			
		||||
		context.parser.skipWhiteSpace();
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ class Not: public Expression
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		template<typename ExpressionParser>
 | 
			
		||||
		static NotPointer parse(Context &context, const Variables ¶meters,
 | 
			
		||||
		static NotPointer parse(Context &context, ExpressionContext &expressionContext,
 | 
			
		||||
			ExpressionParser parseExpression);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
@@ -38,7 +38,7 @@ class Not: public Expression
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<typename ExpressionParser>
 | 
			
		||||
NotPointer Not::parse(Context &context, const Variables ¶meters,
 | 
			
		||||
NotPointer Not::parse(Context &context, ExpressionContext &expressionContext,
 | 
			
		||||
	ExpressionParser parseExpression)
 | 
			
		||||
{
 | 
			
		||||
	auto expression = std::make_unique<Not>(Not());
 | 
			
		||||
@@ -46,7 +46,7 @@ NotPointer Not::parse(Context &context, const Variables ¶meters,
 | 
			
		||||
	context.parser.skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
	// Parse argument
 | 
			
		||||
	expression->m_argument = parseExpression(context, parameters);
 | 
			
		||||
	expression->m_argument = parseExpression(context, expressionContext);
 | 
			
		||||
 | 
			
		||||
	return expression;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ class Or: public NAry
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		template<typename ExpressionParser>
 | 
			
		||||
		static OrPointer parse(Context &context, const Variables ¶meters,
 | 
			
		||||
		static OrPointer parse(Context &context, ExpressionContext &expressionContext,
 | 
			
		||||
			ExpressionParser parseExpression);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
@@ -33,11 +33,12 @@ class Or: public NAry
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<typename ExpressionParser>
 | 
			
		||||
OrPointer Or::parse(Context &context, const Variables ¶meters, ExpressionParser parseExpression)
 | 
			
		||||
OrPointer Or::parse(Context &context, ExpressionContext &expressionContext,
 | 
			
		||||
	ExpressionParser parseExpression)
 | 
			
		||||
{
 | 
			
		||||
	auto expression = std::make_unique<Or>(Or());
 | 
			
		||||
 | 
			
		||||
	expression->NAry::parse(context, parameters, parseExpression);
 | 
			
		||||
	expression->NAry::parse(context, expressionContext, parseExpression);
 | 
			
		||||
 | 
			
		||||
	if (expression->arguments().empty())
 | 
			
		||||
		throw ConsistencyException("\"or\" expressions should not be empty");
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ class Predicate: public Expression
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		static PredicatePointer parse(std::string name, Context &context,
 | 
			
		||||
			const Variables ¶meters);
 | 
			
		||||
			ExpressionContext &expressionContext);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		void accept(ExpressionVisitor &expressionVisitor) const override;
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ namespace expressions
 | 
			
		||||
class PredicateDeclaration: public Expression
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		static void parse(Context &context);
 | 
			
		||||
		static void parse(Context &context, Domain &domain);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		void accept(ExpressionVisitor &expressionVisitor) const override;
 | 
			
		||||
@@ -37,7 +37,7 @@ class PredicateDeclaration: public Expression
 | 
			
		||||
		bool m_isDeclared;
 | 
			
		||||
 | 
			
		||||
		std::string m_name;
 | 
			
		||||
		Variables m_arguments;
 | 
			
		||||
		Variables m_parameters;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -22,12 +22,15 @@ namespace expressions
 | 
			
		||||
class PrimitiveType: public Expression
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		static PrimitiveType *parseDeclaration(Context &context);
 | 
			
		||||
		static void parseTypedDeclaration(Context &context);
 | 
			
		||||
		static void parseDeclaration(Context &context, Domain &domain);
 | 
			
		||||
		static void parseTypedDeclaration(Context &context, Domain &domain);
 | 
			
		||||
 | 
			
		||||
		static PrimitiveType *parseExisting(Context &context);
 | 
			
		||||
		static PrimitiveType *parseAndFindOrCreate(Context &context, Domain &domain);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		PrimitiveType();
 | 
			
		||||
		PrimitiveType(std::string name);
 | 
			
		||||
 | 
			
		||||
		void accept(ExpressionVisitor &expressionVisitor) const override;
 | 
			
		||||
 | 
			
		||||
		const std::string &name() const;
 | 
			
		||||
@@ -36,11 +39,6 @@ class PrimitiveType: public Expression
 | 
			
		||||
		bool isDeclared() const;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		static PrimitiveType *create(std::string name, Context &context);
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		PrimitiveType();
 | 
			
		||||
 | 
			
		||||
		void setDirty(bool isDirty = true);
 | 
			
		||||
		bool isDirty() const;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,8 @@ namespace expressions
 | 
			
		||||
//
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
ExpressionPointer parseExistingPrimitiveType(Context &context, const Variables ¶meters);
 | 
			
		||||
ExpressionPointer parseExistingPrimitiveType(Context &context,
 | 
			
		||||
	ExpressionContext &expressionContext);
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,11 +19,9 @@ namespace expressions
 | 
			
		||||
class Variable: public Expression
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		static VariablePointer parseDeclaration(Context &context);
 | 
			
		||||
		static void parseTypedDeclaration(Context &context, ExpressionContext &expressionContext);
 | 
			
		||||
 | 
			
		||||
		static void parseTypedDeclaration(Context &context, Variables ¶meters);
 | 
			
		||||
 | 
			
		||||
		static const Variable *parseExisting(Context &context, const Variables &variables);
 | 
			
		||||
		static const Variable *parseAndFind(Context &context, const ExpressionContext &expressionContext);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		void accept(ExpressionVisitor &expressionVisitor) const override;
 | 
			
		||||
@@ -36,6 +34,9 @@ class Variable: public Expression
 | 
			
		||||
 | 
			
		||||
		void setType(const Expression *type);
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		static void parseDeclaration(Context &context, Variables ¶meters);
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		Variable();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,8 @@
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
#include <plasp/pddl/Context.h>
 | 
			
		||||
#include <plasp/pddl/Domain.h>
 | 
			
		||||
#include <plasp/pddl/ExpressionContext.h>
 | 
			
		||||
#include <plasp/pddl/Identifier.h>
 | 
			
		||||
#include <plasp/pddl/expressions/Type.h>
 | 
			
		||||
#include <plasp/utils/IO.h>
 | 
			
		||||
@@ -26,20 +28,21 @@ Action::Action(std::string name)
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
Action &Action::parseDeclaration(Context &context)
 | 
			
		||||
void Action::parseDeclaration(Context &context, Domain &domain)
 | 
			
		||||
{
 | 
			
		||||
	const auto actionName = context.parser.parseIdentifier(isIdentifier);
 | 
			
		||||
 | 
			
		||||
	auto action = std::make_unique<Action>(Action(actionName));
 | 
			
		||||
 | 
			
		||||
	context.parser.expect<std::string>(":parameters");
 | 
			
		||||
 | 
			
		||||
	context.parser.expect<std::string>("(");
 | 
			
		||||
 | 
			
		||||
	ExpressionContext expressionContext(domain, action->m_parameters);
 | 
			
		||||
 | 
			
		||||
	// Read parameters
 | 
			
		||||
	while (context.parser.currentCharacter() != ')')
 | 
			
		||||
	{
 | 
			
		||||
		expressions::Variable::parseTypedDeclaration(context, action->m_parameters);
 | 
			
		||||
		expressions::Variable::parseTypedDeclaration(context, expressionContext);
 | 
			
		||||
 | 
			
		||||
		context.parser.skipWhiteSpace();
 | 
			
		||||
	}
 | 
			
		||||
@@ -54,17 +57,15 @@ Action &Action::parseDeclaration(Context &context)
 | 
			
		||||
		const auto sectionIdentifier = context.parser.parseIdentifier(isIdentifier);
 | 
			
		||||
 | 
			
		||||
		if (sectionIdentifier == "precondition")
 | 
			
		||||
			action->m_precondition = parsePreconditionExpression(context, action->m_parameters);
 | 
			
		||||
			action->m_precondition = parsePreconditionExpression(context, expressionContext);
 | 
			
		||||
		else if (sectionIdentifier == "effect")
 | 
			
		||||
			action->m_effect = parseEffectExpression(context, action->m_parameters);
 | 
			
		||||
			action->m_effect = parseEffectExpression(context, expressionContext);
 | 
			
		||||
 | 
			
		||||
		context.parser.skipWhiteSpace();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Store new action
 | 
			
		||||
	context.actions.emplace_back(std::move(action));
 | 
			
		||||
 | 
			
		||||
	return *context.actions.back();
 | 
			
		||||
	expressionContext.domain.actions().emplace_back(std::move(action));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,9 @@ Description Description::fromStream(std::istream &istream)
 | 
			
		||||
{
 | 
			
		||||
	Description description(istream);
 | 
			
		||||
 | 
			
		||||
	description.m_domain = std::make_unique<Domain>(Domain(description.m_context));
 | 
			
		||||
	description.m_problem = std::make_unique<Problem>(Problem(description.m_context, *description.m_domain));
 | 
			
		||||
 | 
			
		||||
	while (true)
 | 
			
		||||
	{
 | 
			
		||||
		description.m_context.parser.skipWhiteSpace();
 | 
			
		||||
@@ -41,6 +44,8 @@ Description Description::fromStream(std::istream &istream)
 | 
			
		||||
		description.parseContent();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	description.checkConsistency();
 | 
			
		||||
 | 
			
		||||
	return description;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -89,14 +94,36 @@ void Description::parseSection()
 | 
			
		||||
	std::cout << "Parsing section " << sectionIdentifier << std::endl;
 | 
			
		||||
 | 
			
		||||
	if (sectionIdentifier == "domain")
 | 
			
		||||
		m_domain = std::make_unique<Domain>(Domain::fromPDDL(m_context));
 | 
			
		||||
	{
 | 
			
		||||
		BOOST_ASSERT(m_domain);
 | 
			
		||||
 | 
			
		||||
		if (m_domain->isDeclared())
 | 
			
		||||
			throw utils::ParserException(m_context.parser, "PDDL description may not contain two domains");
 | 
			
		||||
 | 
			
		||||
		m_domain->readPDDL();
 | 
			
		||||
	}
 | 
			
		||||
	else if (sectionIdentifier == "problem")
 | 
			
		||||
		m_problem = std::make_unique<Problem>(Problem::fromPDDL(m_context));
 | 
			
		||||
	{
 | 
			
		||||
		BOOST_ASSERT(m_problem);
 | 
			
		||||
 | 
			
		||||
		if (m_problem->isDeclared())
 | 
			
		||||
			throw utils::ParserException(m_context.parser, "PDDL description may currently not contain two problems");
 | 
			
		||||
 | 
			
		||||
		m_problem->readPDDL();
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		throw utils::ParserException(m_context.parser, "Unknown PDDL section \"" + sectionIdentifier + "\"");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Description::checkConsistency()
 | 
			
		||||
{
 | 
			
		||||
	m_domain->checkConsistency();
 | 
			
		||||
	m_problem->checkConsistency();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -23,37 +23,41 @@ namespace pddl
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
Domain::Domain(Context &context)
 | 
			
		||||
:	m_context(context)
 | 
			
		||||
:	m_context(context),
 | 
			
		||||
	m_isDeclared{false}
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
Domain Domain::fromPDDL(Context &context)
 | 
			
		||||
void Domain::readPDDL()
 | 
			
		||||
{
 | 
			
		||||
	Domain domain(context);
 | 
			
		||||
	m_name = m_context.parser.parseIdentifier(isIdentifier);
 | 
			
		||||
 | 
			
		||||
	domain.m_name = context.parser.parseIdentifier(isIdentifier);
 | 
			
		||||
	std::cout << "Parsing domain " << m_name << std::endl;
 | 
			
		||||
 | 
			
		||||
	std::cout << "Parsing domain " << domain.m_name << std::endl;
 | 
			
		||||
 | 
			
		||||
	context.parser.expect<std::string>(")");
 | 
			
		||||
	m_context.parser.expect<std::string>(")");
 | 
			
		||||
 | 
			
		||||
	while (true)
 | 
			
		||||
	{
 | 
			
		||||
		context.parser.skipWhiteSpace();
 | 
			
		||||
		m_context.parser.skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
		if (context.parser.currentCharacter() == ')')
 | 
			
		||||
		if (m_context.parser.currentCharacter() == ')')
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		domain.parseSection();
 | 
			
		||||
		parseSection();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	domain.computeDerivedRequirements();
 | 
			
		||||
	computeDerivedRequirements();
 | 
			
		||||
 | 
			
		||||
	domain.checkConsistency();
 | 
			
		||||
	m_isDeclared = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	return domain;
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
bool Domain::isDeclared() const
 | 
			
		||||
{
 | 
			
		||||
	return m_isDeclared;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -72,30 +76,58 @@ const Requirements &Domain::requirements() const
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
expressions::PrimitiveTypes &Domain::types()
 | 
			
		||||
{
 | 
			
		||||
	return m_primitiveTypes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
const expressions::PrimitiveTypes &Domain::types() const
 | 
			
		||||
{
 | 
			
		||||
	return m_context.primitiveTypes;
 | 
			
		||||
	return m_primitiveTypes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
expressions::Constants &Domain::constants()
 | 
			
		||||
{
 | 
			
		||||
	return m_constants;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
const expressions::Constants &Domain::constants() const
 | 
			
		||||
{
 | 
			
		||||
	return m_context.constants;
 | 
			
		||||
	return m_constants;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
expressions::PredicateDeclarations &Domain::predicates()
 | 
			
		||||
{
 | 
			
		||||
	return m_predicateDeclarations;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
const expressions::PredicateDeclarations &Domain::predicates() const
 | 
			
		||||
{
 | 
			
		||||
	return m_context.predicateDeclarations;
 | 
			
		||||
	return m_predicateDeclarations;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
std::vector<std::unique_ptr<Action>> &Domain::actions()
 | 
			
		||||
{
 | 
			
		||||
	return m_actions;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
const std::vector<std::unique_ptr<Action>> &Domain::actions() const
 | 
			
		||||
{
 | 
			
		||||
	return m_context.actions;
 | 
			
		||||
	return m_actions;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -242,7 +274,7 @@ void Domain::parseTypeSection()
 | 
			
		||||
		if (m_context.parser.currentCharacter() == '(')
 | 
			
		||||
			throw utils::ParserException(m_context.parser, "Only primitive types are allowed in type section");
 | 
			
		||||
 | 
			
		||||
		expressions::PrimitiveType::parseTypedDeclaration(m_context);
 | 
			
		||||
		expressions::PrimitiveType::parseTypedDeclaration(m_context, *this);
 | 
			
		||||
 | 
			
		||||
		m_context.parser.skipWhiteSpace();
 | 
			
		||||
	}
 | 
			
		||||
@@ -259,7 +291,7 @@ void Domain::parseConstantSection()
 | 
			
		||||
	// Store constants
 | 
			
		||||
	while (m_context.parser.currentCharacter() != ')')
 | 
			
		||||
	{
 | 
			
		||||
		expressions::Constant::parseTypedDeclaration(m_context, m_context.constants);
 | 
			
		||||
		expressions::Constant::parseTypedDeclaration(m_context, *this);
 | 
			
		||||
 | 
			
		||||
		m_context.parser.skipWhiteSpace();
 | 
			
		||||
	}
 | 
			
		||||
@@ -276,7 +308,7 @@ void Domain::parsePredicateSection()
 | 
			
		||||
	// Store predicates and their arguments
 | 
			
		||||
	while (m_context.parser.currentCharacter() != ')')
 | 
			
		||||
	{
 | 
			
		||||
		expressions::PredicateDeclaration::parse(m_context);
 | 
			
		||||
		expressions::PredicateDeclaration::parse(m_context, *this);
 | 
			
		||||
 | 
			
		||||
		m_context.parser.skipWhiteSpace();
 | 
			
		||||
	}
 | 
			
		||||
@@ -290,7 +322,7 @@ void Domain::parseActionSection()
 | 
			
		||||
{
 | 
			
		||||
	m_context.parser.skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
	Action::parseDeclaration(m_context);
 | 
			
		||||
	Action::parseDeclaration(m_context, *this);
 | 
			
		||||
 | 
			
		||||
	m_context.parser.expect<std::string>(")");
 | 
			
		||||
}
 | 
			
		||||
@@ -300,7 +332,7 @@ void Domain::parseActionSection()
 | 
			
		||||
void Domain::checkConsistency()
 | 
			
		||||
{
 | 
			
		||||
	// Verify that typing requirement is correctly declared if used
 | 
			
		||||
	if (!m_context.primitiveTypes.empty() && !hasRequirement(Requirement::Type::Typing))
 | 
			
		||||
	if (!m_primitiveTypes.empty() && !hasRequirement(Requirement::Type::Typing))
 | 
			
		||||
	{
 | 
			
		||||
		throw ConsistencyException("Domain contains typing information but does not declare typing requirement");
 | 
			
		||||
 | 
			
		||||
@@ -308,7 +340,7 @@ void Domain::checkConsistency()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Verify that all used types have been declared
 | 
			
		||||
	std::for_each(m_context.primitiveTypes.cbegin(), m_context.primitiveTypes.cend(),
 | 
			
		||||
	std::for_each(m_primitiveTypes.cbegin(), m_primitiveTypes.cend(),
 | 
			
		||||
		[&](const auto &type)
 | 
			
		||||
		{
 | 
			
		||||
			if (!type->isDeclared())
 | 
			
		||||
@@ -316,7 +348,7 @@ void Domain::checkConsistency()
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
	// Verify that all used constants have been declared
 | 
			
		||||
	std::for_each(m_context.constants.cbegin(), m_context.constants.cend(),
 | 
			
		||||
	std::for_each(m_constants.cbegin(), m_constants.cend(),
 | 
			
		||||
		[&](const auto &constant)
 | 
			
		||||
		{
 | 
			
		||||
			if (!constant->isDeclared())
 | 
			
		||||
@@ -327,7 +359,7 @@ void Domain::checkConsistency()
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
	// Verify that all used predicates have been declared
 | 
			
		||||
	std::for_each(m_context.predicateDeclarations.cbegin(), m_context.predicateDeclarations.cend(),
 | 
			
		||||
	std::for_each(m_predicateDeclarations.cbegin(), m_predicateDeclarations.cend(),
 | 
			
		||||
		[&](const auto &predicate)
 | 
			
		||||
		{
 | 
			
		||||
			if (!predicate->isDeclared())
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
#include <plasp/pddl/Expression.h>
 | 
			
		||||
 | 
			
		||||
#include <plasp/pddl/Context.h>
 | 
			
		||||
#include <plasp/pddl/Domain.h>
 | 
			
		||||
#include <plasp/pddl/ExpressionContext.h>
 | 
			
		||||
#include <plasp/pddl/Identifier.h>
 | 
			
		||||
#include <plasp/pddl/expressions/And.h>
 | 
			
		||||
#include <plasp/pddl/expressions/Imply.h>
 | 
			
		||||
@@ -23,15 +25,16 @@ namespace pddl
 | 
			
		||||
//
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier,
 | 
			
		||||
	Context &context, const expressions::Variables ¶meters);
 | 
			
		||||
ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier, Context &context,
 | 
			
		||||
	ExpressionContext &expressionContext);
 | 
			
		||||
ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier,
 | 
			
		||||
	Context &context, const expressions::Variables ¶meters);
 | 
			
		||||
ExpressionPointer parsePredicate(Context &context, const expressions::Variables ¶meters);
 | 
			
		||||
	Context &context, ExpressionContext &expressionContext);
 | 
			
		||||
ExpressionPointer parsePredicate(Context &context, ExpressionContext &expressionContext);
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void throwUnsupported(const utils::Parser &parser, const std::string &expressionIdentifier)
 | 
			
		||||
[[noreturn]] void throwUnsupported(const utils::Parser &parser,
 | 
			
		||||
	const std::string &expressionIdentifier)
 | 
			
		||||
{
 | 
			
		||||
	throw utils::ParserException(parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported in this context");
 | 
			
		||||
}
 | 
			
		||||
@@ -39,7 +42,7 @@ void throwUnsupported(const utils::Parser &parser, const std::string &expression
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
ExpressionPointer parsePreconditionExpression(Context &context,
 | 
			
		||||
	const expressions::Variables ¶meters)
 | 
			
		||||
	ExpressionContext &expressionContext)
 | 
			
		||||
{
 | 
			
		||||
	context.parser.expect<std::string>("(");
 | 
			
		||||
 | 
			
		||||
@@ -49,7 +52,7 @@ ExpressionPointer parsePreconditionExpression(Context &context,
 | 
			
		||||
 | 
			
		||||
	if (expressionIdentifier == "and")
 | 
			
		||||
	{
 | 
			
		||||
		expression = expressions::And::parse(context, parameters,
 | 
			
		||||
		expression = expressions::And::parse(context, expressionContext,
 | 
			
		||||
			parsePreconditionExpression);
 | 
			
		||||
	}
 | 
			
		||||
	else if (expressionIdentifier == "forall"
 | 
			
		||||
@@ -58,7 +61,7 @@ ExpressionPointer parsePreconditionExpression(Context &context,
 | 
			
		||||
		throwUnsupported(context.parser, expressionIdentifier);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		expression = parseExpressionContent(expressionIdentifier, context, parameters);
 | 
			
		||||
		expression = parseExpressionContent(expressionIdentifier, context, expressionContext);
 | 
			
		||||
 | 
			
		||||
	context.parser.expect<std::string>(")");
 | 
			
		||||
 | 
			
		||||
@@ -67,13 +70,13 @@ ExpressionPointer parsePreconditionExpression(Context &context,
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
ExpressionPointer parseExpression(Context &context, const expressions::Variables ¶meters)
 | 
			
		||||
ExpressionPointer parseExpression(Context &context, ExpressionContext &expressionContext)
 | 
			
		||||
{
 | 
			
		||||
	context.parser.expect<std::string>("(");
 | 
			
		||||
 | 
			
		||||
	const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier);
 | 
			
		||||
 | 
			
		||||
	auto expression = parseExpressionContent(expressionIdentifier, context, parameters);
 | 
			
		||||
	auto expression = parseExpressionContent(expressionIdentifier, context, expressionContext);
 | 
			
		||||
 | 
			
		||||
	context.parser.expect<std::string>(")");
 | 
			
		||||
 | 
			
		||||
@@ -82,22 +85,22 @@ ExpressionPointer parseExpression(Context &context, const expressions::Variables
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier,
 | 
			
		||||
	Context &context, const expressions::Variables ¶meters)
 | 
			
		||||
ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier, Context &context,
 | 
			
		||||
	ExpressionContext &expressionContext)
 | 
			
		||||
{
 | 
			
		||||
	context.parser.skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
	if (expressionIdentifier == "and")
 | 
			
		||||
		return expressions::And::parse(context, parameters, parseExpression);
 | 
			
		||||
		return expressions::And::parse(context, expressionContext, parseExpression);
 | 
			
		||||
 | 
			
		||||
	if (expressionIdentifier == "or")
 | 
			
		||||
		return expressions::Or::parse(context, parameters, parseExpression);
 | 
			
		||||
		return expressions::Or::parse(context, expressionContext, parseExpression);
 | 
			
		||||
 | 
			
		||||
	if (expressionIdentifier == "not")
 | 
			
		||||
		return expressions::Not::parse(context, parameters, parseExpression);
 | 
			
		||||
		return expressions::Not::parse(context, expressionContext, parseExpression);
 | 
			
		||||
 | 
			
		||||
	if (expressionIdentifier == "imply")
 | 
			
		||||
		return expressions::Imply::parse(context, parameters, parseExpression);
 | 
			
		||||
		return expressions::Imply::parse(context, expressionContext, parseExpression);
 | 
			
		||||
 | 
			
		||||
	if (expressionIdentifier == "exists"
 | 
			
		||||
		|| expressionIdentifier == "forall"
 | 
			
		||||
@@ -116,23 +119,25 @@ ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier
 | 
			
		||||
		throwUnsupported(context.parser, expressionIdentifier);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	auto &predicateDeclarations = expressionContext.domain.predicates();
 | 
			
		||||
 | 
			
		||||
	// Check if predicate with that name exists
 | 
			
		||||
	const auto match = std::find_if(context.predicateDeclarations.cbegin(), context.predicateDeclarations.cend(),
 | 
			
		||||
	const auto match = std::find_if(predicateDeclarations.cbegin(), predicateDeclarations.cend(),
 | 
			
		||||
		[&](const auto &predicate)
 | 
			
		||||
		{
 | 
			
		||||
			return predicate->name() == expressionIdentifier;
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
	// If predicate exists, parse it
 | 
			
		||||
	if (match != context.predicateDeclarations.cend())
 | 
			
		||||
		return expressions::Predicate::parse(expressionIdentifier, context, parameters);
 | 
			
		||||
	if (match != predicateDeclarations.cend())
 | 
			
		||||
		return expressions::Predicate::parse(expressionIdentifier, context, expressionContext);
 | 
			
		||||
 | 
			
		||||
	throw utils::ParserException(context.parser, "Expression \"" + expressionIdentifier + "\" not allowed in this context");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
ExpressionPointer parseEffectExpression(Context &context, const expressions::Variables ¶meters)
 | 
			
		||||
ExpressionPointer parseEffectExpression(Context &context, ExpressionContext &expressionContext)
 | 
			
		||||
{
 | 
			
		||||
	context.parser.expect<std::string>("(");
 | 
			
		||||
 | 
			
		||||
@@ -141,14 +146,14 @@ ExpressionPointer parseEffectExpression(Context &context, const expressions::Var
 | 
			
		||||
	ExpressionPointer expression;
 | 
			
		||||
 | 
			
		||||
	if (expressionIdentifier == "and")
 | 
			
		||||
		expression = expressions::And::parse(context, parameters, parseEffectExpression);
 | 
			
		||||
		expression = expressions::And::parse(context, expressionContext, parseEffectExpression);
 | 
			
		||||
	else if (expressionIdentifier == "forall"
 | 
			
		||||
		|| expressionIdentifier == "when")
 | 
			
		||||
	{
 | 
			
		||||
		throwUnsupported(context.parser, expressionIdentifier);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		expression = parseEffectBodyExpressionContent(expressionIdentifier, context, parameters);
 | 
			
		||||
		expression = parseEffectBodyExpressionContent(expressionIdentifier, context, expressionContext);
 | 
			
		||||
 | 
			
		||||
	context.parser.expect<std::string>(")");
 | 
			
		||||
 | 
			
		||||
@@ -158,12 +163,12 @@ ExpressionPointer parseEffectExpression(Context &context, const expressions::Var
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier,
 | 
			
		||||
	Context &context, const expressions::Variables ¶meters)
 | 
			
		||||
	Context &context, ExpressionContext &expressionContext)
 | 
			
		||||
{
 | 
			
		||||
	ExpressionPointer expression;
 | 
			
		||||
 | 
			
		||||
	if (expressionIdentifier == "not")
 | 
			
		||||
		return expressions::Not::parse(context, parameters, parsePredicate);
 | 
			
		||||
		return expressions::Not::parse(context, expressionContext, parsePredicate);
 | 
			
		||||
 | 
			
		||||
	if (expressionIdentifier == "="
 | 
			
		||||
		|| expressionIdentifier == "assign"
 | 
			
		||||
@@ -175,23 +180,25 @@ ExpressionPointer parseEffectBodyExpressionContent(const std::string &expression
 | 
			
		||||
		throwUnsupported(context.parser, expressionIdentifier);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const auto &predicateDeclarations = expressionContext.domain.predicates();
 | 
			
		||||
 | 
			
		||||
	// Check if predicate with that name exists
 | 
			
		||||
	const auto match = std::find_if(context.predicateDeclarations.cbegin(), context.predicateDeclarations.cend(),
 | 
			
		||||
	const auto match = std::find_if(predicateDeclarations.cbegin(), predicateDeclarations.cend(),
 | 
			
		||||
		[&](const auto &predicate)
 | 
			
		||||
		{
 | 
			
		||||
			return predicate->name() == expressionIdentifier;
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
	// If predicate exists, parse it
 | 
			
		||||
	if (match != context.predicateDeclarations.cend())
 | 
			
		||||
		return expressions::Predicate::parse(expressionIdentifier, context, parameters);
 | 
			
		||||
	if (match != predicateDeclarations.cend())
 | 
			
		||||
		return expressions::Predicate::parse(expressionIdentifier, context, expressionContext);
 | 
			
		||||
 | 
			
		||||
	throw utils::ParserException(context.parser, "Expression \"" + expressionIdentifier + "\" not allowed in this context");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
ExpressionPointer parsePredicate(Context &context, const expressions::Variables ¶meters)
 | 
			
		||||
ExpressionPointer parsePredicate(Context &context, ExpressionContext &expressionContext)
 | 
			
		||||
{
 | 
			
		||||
	context.parser.expect<std::string>("(");
 | 
			
		||||
 | 
			
		||||
@@ -199,18 +206,20 @@ ExpressionPointer parsePredicate(Context &context, const expressions::Variables
 | 
			
		||||
 | 
			
		||||
	ExpressionPointer expression;
 | 
			
		||||
 | 
			
		||||
	const auto &predicateDeclarations = expressionContext.domain.predicates();
 | 
			
		||||
 | 
			
		||||
	// Check if predicate with that name exists
 | 
			
		||||
	const auto match = std::find_if(context.predicateDeclarations.cbegin(), context.predicateDeclarations.cend(),
 | 
			
		||||
	const auto match = std::find_if(predicateDeclarations.cbegin(), predicateDeclarations.cend(),
 | 
			
		||||
		[&](const auto &predicate)
 | 
			
		||||
		{
 | 
			
		||||
			return predicate->name() == predicateName;
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
	// If predicate exists, parse it
 | 
			
		||||
	if (match == context.predicateDeclarations.cend())
 | 
			
		||||
	if (match == predicateDeclarations.cend())
 | 
			
		||||
		throw utils::ParserException(context.parser, "Unknown predicate \"" + predicateName + "\"");
 | 
			
		||||
 | 
			
		||||
	expression = expressions::Predicate::parse(predicateName, context, parameters);
 | 
			
		||||
	expression = expressions::Predicate::parse(predicateName, context, expressionContext);
 | 
			
		||||
 | 
			
		||||
	context.parser.expect<std::string>(")");
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,9 @@
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
#include <plasp/pddl/Identifier.h>
 | 
			
		||||
#include <plasp/pddl/expressions/Constant.h>
 | 
			
		||||
#include <plasp/utils/IO.h>
 | 
			
		||||
#include <plasp/utils/ParserException.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -16,38 +18,57 @@ namespace pddl
 | 
			
		||||
//
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
Problem::Problem(Context &context)
 | 
			
		||||
:	m_context(context)
 | 
			
		||||
Problem::Problem(Context &context, Domain &domain)
 | 
			
		||||
:	m_context(context),
 | 
			
		||||
	m_domain(domain),
 | 
			
		||||
	m_isDeclared{false}
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
Problem Problem::fromPDDL(Context &context)
 | 
			
		||||
void Problem::readPDDL()
 | 
			
		||||
{
 | 
			
		||||
	Problem problem(context);
 | 
			
		||||
	m_name = m_context.parser.parseIdentifier(isIdentifier);
 | 
			
		||||
 | 
			
		||||
	problem.m_name = context.parser.parseIdentifier(isIdentifier);
 | 
			
		||||
	std::cout << "Parsing problem " << m_name << std::endl;
 | 
			
		||||
 | 
			
		||||
	std::cout << "Parsing problem " << problem.m_name << std::endl;
 | 
			
		||||
 | 
			
		||||
	context.parser.expect<std::string>(")");
 | 
			
		||||
	m_context.parser.expect<std::string>(")");
 | 
			
		||||
 | 
			
		||||
	while (true)
 | 
			
		||||
	{
 | 
			
		||||
		context.parser.skipWhiteSpace();
 | 
			
		||||
		m_context.parser.skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
		if (context.parser.currentCharacter() == ')')
 | 
			
		||||
		if (m_context.parser.currentCharacter() == ')')
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		problem.parseSection();
 | 
			
		||||
		parseSection();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	problem.computeDerivedRequirements();
 | 
			
		||||
	computeDerivedRequirements();
 | 
			
		||||
 | 
			
		||||
	problem.checkConsistency();
 | 
			
		||||
	m_isDeclared = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	return problem;
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
bool Problem::isDeclared() const
 | 
			
		||||
{
 | 
			
		||||
	return m_isDeclared;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
Domain &Problem::domain()
 | 
			
		||||
{
 | 
			
		||||
	return m_domain;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
const Domain &Problem::domain() const
 | 
			
		||||
{
 | 
			
		||||
	return m_domain;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -66,6 +87,20 @@ const Requirements &Problem::requirements() const
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
expressions::Constants &Problem::objects()
 | 
			
		||||
{
 | 
			
		||||
	return m_objects;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
const expressions::Constants &Problem::objects() const
 | 
			
		||||
{
 | 
			
		||||
	return m_objects;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Problem::parseSection()
 | 
			
		||||
{
 | 
			
		||||
	m_context.parser.expect<std::string>("(");
 | 
			
		||||
@@ -203,7 +238,7 @@ void Problem::parseObjectSection()
 | 
			
		||||
	// Store constants
 | 
			
		||||
	while (m_context.parser.currentCharacter() != ')')
 | 
			
		||||
	{
 | 
			
		||||
		expressions::Constant::parseTypedDeclaration(m_context);
 | 
			
		||||
		//expressions::Constant::parseTypedDeclaration(m_context);
 | 
			
		||||
 | 
			
		||||
		m_context.parser.skipWhiteSpace();
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,10 @@
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
 | 
			
		||||
#include <plasp/pddl/Context.h>
 | 
			
		||||
#include <plasp/pddl/Domain.h>
 | 
			
		||||
#include <plasp/pddl/ExpressionContext.h>
 | 
			
		||||
#include <plasp/pddl/ExpressionVisitor.h>
 | 
			
		||||
#include <plasp/pddl/Problem.h>
 | 
			
		||||
#include <plasp/pddl/expressions/PrimitiveType.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
@@ -50,7 +53,21 @@ ConstantPointer Constant::parseDeclaration(Context &context)
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Constant::parseTypedDeclaration(Context &context, Constants &constants)
 | 
			
		||||
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));
 | 
			
		||||
@@ -67,7 +84,7 @@ void Constant::parseTypedDeclaration(Context &context, Constants &constants)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	// If existing, parse and store parent type
 | 
			
		||||
	auto *type = PrimitiveType::parseExisting(context);
 | 
			
		||||
	auto *type = PrimitiveType::parseAndFindOrCreate(context, domain);
 | 
			
		||||
 | 
			
		||||
	// Assign parent type to all types that were previously flagged
 | 
			
		||||
	std::for_each(constants.begin(), constants.end(),
 | 
			
		||||
@@ -83,21 +100,42 @@ void Constant::parseTypedDeclaration(Context &context, Constants &constants)
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
Constant *Constant::parseExisting(Context &context)
 | 
			
		||||
Constant *Constant::parseAndFind(Context &context, const ExpressionContext &expressionContext)
 | 
			
		||||
{
 | 
			
		||||
	context.parser.skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
	const auto constantName = context.parser.parseIdentifier(isIdentifier);
 | 
			
		||||
 | 
			
		||||
	auto *constant = parseAndFind(constantName, expressionContext.domain.constants());
 | 
			
		||||
 | 
			
		||||
	if (constant)
 | 
			
		||||
		return constant;
 | 
			
		||||
 | 
			
		||||
	if (expressionContext.problem)
 | 
			
		||||
	{
 | 
			
		||||
		constant = parseAndFind(constantName, expressionContext.problem->objects());
 | 
			
		||||
 | 
			
		||||
		if (constant)
 | 
			
		||||
			return constant;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
Constant *Constant::parseAndFind(const std::string &constantName, const Constants &constants)
 | 
			
		||||
{
 | 
			
		||||
	// TODO: use hash map
 | 
			
		||||
	const auto match = std::find_if(context.constants.cbegin(), context.constants.cend(),
 | 
			
		||||
	const auto match = std::find_if(constants.cbegin(), constants.cend(),
 | 
			
		||||
		[&](const auto &constant)
 | 
			
		||||
		{
 | 
			
		||||
			return constant->name() == constantName;
 | 
			
		||||
		});
 | 
			
		||||
	const auto constantExists = (match != context.constants.cend());
 | 
			
		||||
	const auto constantExists = (match != constants.cend());
 | 
			
		||||
 | 
			
		||||
	if (!constantExists)
 | 
			
		||||
		throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared");
 | 
			
		||||
		return nullptr;
 | 
			
		||||
 | 
			
		||||
	return match->get();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,10 @@
 | 
			
		||||
#include <plasp/pddl/expressions/Type.h>
 | 
			
		||||
 | 
			
		||||
#include <plasp/pddl/Context.h>
 | 
			
		||||
#include <plasp/pddl/Identifier.h>
 | 
			
		||||
#include <plasp/pddl/expressions/Predicate.h>
 | 
			
		||||
#include <plasp/utils/IO.h>
 | 
			
		||||
#include <plasp/utils/ParserException.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
#include <plasp/pddl/expressions/Predicate.h>
 | 
			
		||||
 | 
			
		||||
#include <plasp/pddl/Context.h>
 | 
			
		||||
#include <plasp/pddl/Domain.h>
 | 
			
		||||
#include <plasp/pddl/ExpressionContext.h>
 | 
			
		||||
#include <plasp/pddl/ExpressionVisitor.h>
 | 
			
		||||
#include <plasp/pddl/Identifier.h>
 | 
			
		||||
#include <plasp/pddl/expressions/Constant.h>
 | 
			
		||||
@@ -27,7 +29,8 @@ Predicate::Predicate()
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
PredicatePointer Predicate::parse(std::string name, Context &context, const Variables ¶meters)
 | 
			
		||||
PredicatePointer Predicate::parse(std::string name, Context &context,
 | 
			
		||||
	ExpressionContext &expressionContext)
 | 
			
		||||
{
 | 
			
		||||
	auto predicate = std::make_unique<Predicate>(Predicate());
 | 
			
		||||
 | 
			
		||||
@@ -41,14 +44,14 @@ PredicatePointer Predicate::parse(std::string name, Context &context, const Vari
 | 
			
		||||
		// Parse variables
 | 
			
		||||
		if (context.parser.currentCharacter() == '?')
 | 
			
		||||
		{
 | 
			
		||||
			const auto *variable = Variable::parseExisting(context, parameters);
 | 
			
		||||
			const auto *variable = Variable::parseAndFind(context, expressionContext);
 | 
			
		||||
			auto variableReference = std::make_unique<Reference<Variable>>(variable);
 | 
			
		||||
			predicate->m_arguments.emplace_back(std::move(variableReference));
 | 
			
		||||
		}
 | 
			
		||||
		// Parse constants
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			const auto *constant = Constant::parseExisting(context);
 | 
			
		||||
			const auto *constant = Constant::parseAndFind(context, expressionContext);
 | 
			
		||||
			auto constantReference = std::make_unique<Reference<Constant>>(constant);
 | 
			
		||||
			predicate->m_arguments.emplace_back(std::move(constantReference));
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
#include <plasp/pddl/expressions/PredicateDeclaration.h>
 | 
			
		||||
 | 
			
		||||
#include <plasp/pddl/Context.h>
 | 
			
		||||
#include <plasp/pddl/Domain.h>
 | 
			
		||||
#include <plasp/pddl/ExpressionContext.h>
 | 
			
		||||
#include <plasp/pddl/ExpressionVisitor.h>
 | 
			
		||||
#include <plasp/pddl/Identifier.h>
 | 
			
		||||
#include <plasp/pddl/expressions/Constant.h>
 | 
			
		||||
@@ -27,7 +29,7 @@ PredicateDeclaration::PredicateDeclaration()
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void PredicateDeclaration::parse(Context &context)
 | 
			
		||||
void PredicateDeclaration::parse(Context &context, Domain &domain)
 | 
			
		||||
{
 | 
			
		||||
	context.parser.expect<std::string>("(");
 | 
			
		||||
 | 
			
		||||
@@ -40,18 +42,19 @@ void PredicateDeclaration::parse(Context &context)
 | 
			
		||||
 | 
			
		||||
	context.parser.skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
	ExpressionContext expressionContext(domain, predicate->m_parameters);
 | 
			
		||||
 | 
			
		||||
	// Parse arguments
 | 
			
		||||
	while (context.parser.currentCharacter() != ')')
 | 
			
		||||
	{
 | 
			
		||||
		expressions::Variable::parseTypedDeclaration(context, predicate->m_arguments);
 | 
			
		||||
		expressions::Variable::parseTypedDeclaration(context, expressionContext);
 | 
			
		||||
 | 
			
		||||
		context.parser.skipWhiteSpace();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	context.parser.expect<std::string>(")");
 | 
			
		||||
 | 
			
		||||
	// Store new predicate
 | 
			
		||||
	context.predicateDeclarations.emplace_back(std::move(predicate));
 | 
			
		||||
	domain.predicates().emplace_back(std::move(predicate));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -86,7 +89,7 @@ const std::string &PredicateDeclaration::name() const
 | 
			
		||||
 | 
			
		||||
const Variables &PredicateDeclaration::arguments() const
 | 
			
		||||
{
 | 
			
		||||
	return m_arguments;
 | 
			
		||||
	return m_parameters;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,8 @@
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
 | 
			
		||||
#include <plasp/pddl/Context.h>
 | 
			
		||||
#include <plasp/pddl/Domain.h>
 | 
			
		||||
#include <plasp/pddl/ExpressionContext.h>
 | 
			
		||||
#include <plasp/pddl/ExpressionVisitor.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
@@ -21,65 +23,61 @@ namespace expressions
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
PrimitiveType::PrimitiveType()
 | 
			
		||||
:	m_isDirty{false},
 | 
			
		||||
:	m_isDirty{true},
 | 
			
		||||
	m_isDeclared{false}
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
PrimitiveType *PrimitiveType::create(std::string name, Context &context)
 | 
			
		||||
PrimitiveType::PrimitiveType(std::string name)
 | 
			
		||||
:	m_isDirty{true},
 | 
			
		||||
	m_isDeclared{false},
 | 
			
		||||
	m_name{name}
 | 
			
		||||
{
 | 
			
		||||
	// Create new primitive type if not already existing
 | 
			
		||||
	auto type = std::make_unique<PrimitiveType>(PrimitiveType());
 | 
			
		||||
 | 
			
		||||
	type->m_name = name;
 | 
			
		||||
 | 
			
		||||
	BOOST_ASSERT(!type->m_name.empty());
 | 
			
		||||
 | 
			
		||||
	// Flag type for potentially upcoming parent type declaration
 | 
			
		||||
	type->setDirty();
 | 
			
		||||
 | 
			
		||||
	// TODO: Store constant in hash map
 | 
			
		||||
	context.primitiveTypes.emplace_back(std::move(type));
 | 
			
		||||
 | 
			
		||||
	return context.primitiveTypes.back().get();
 | 
			
		||||
	BOOST_ASSERT(!m_name.empty());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
PrimitiveType *PrimitiveType::parseDeclaration(Context &context)
 | 
			
		||||
void PrimitiveType::parseDeclaration(Context &context, Domain &domain)
 | 
			
		||||
{
 | 
			
		||||
	auto &types = domain.types();
 | 
			
		||||
 | 
			
		||||
	context.parser.skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
	const auto typeName = context.parser.parseIdentifier(isIdentifier);
 | 
			
		||||
 | 
			
		||||
	// TODO: use hash map
 | 
			
		||||
	const auto match = std::find_if(context.primitiveTypes.cbegin(), context.primitiveTypes.cend(),
 | 
			
		||||
	const auto match = std::find_if(types.cbegin(), types.cend(),
 | 
			
		||||
		[&](const auto &primitiveType)
 | 
			
		||||
		{
 | 
			
		||||
			return primitiveType->name() == typeName;
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
	// Return existing primitive type
 | 
			
		||||
	if (match != context.primitiveTypes.cend())
 | 
			
		||||
	if (match != types.cend())
 | 
			
		||||
	{
 | 
			
		||||
		auto *type = match->get();
 | 
			
		||||
 | 
			
		||||
		type->setDirty();
 | 
			
		||||
 | 
			
		||||
		return type;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return create(typeName, context);
 | 
			
		||||
	types.emplace_back(std::make_unique<PrimitiveType>(typeName));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void PrimitiveType::parseTypedDeclaration(Context &context)
 | 
			
		||||
void PrimitiveType::parseTypedDeclaration(Context &context, Domain &domain)
 | 
			
		||||
{
 | 
			
		||||
	auto &types = domain.types();
 | 
			
		||||
 | 
			
		||||
	// Parse and store type
 | 
			
		||||
	auto *type = parseDeclaration(context);
 | 
			
		||||
	parseDeclaration(context, domain);
 | 
			
		||||
 | 
			
		||||
	auto *type = types.back().get();
 | 
			
		||||
 | 
			
		||||
	// Flag type as correctly declared in the types section
 | 
			
		||||
	type->setDeclared();
 | 
			
		||||
@@ -91,7 +89,7 @@ void PrimitiveType::parseTypedDeclaration(Context &context)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	// If existing, parse and store parent type
 | 
			
		||||
	auto *parentType = parseExisting(context);
 | 
			
		||||
	auto *parentType = parseAndFindOrCreate(context, domain);
 | 
			
		||||
 | 
			
		||||
	parentType->setDirty(false);
 | 
			
		||||
 | 
			
		||||
@@ -99,7 +97,7 @@ void PrimitiveType::parseTypedDeclaration(Context &context)
 | 
			
		||||
	parentType->setDeclared();
 | 
			
		||||
 | 
			
		||||
	// Assign parent type to all types that were previously flagged
 | 
			
		||||
	std::for_each(context.primitiveTypes.begin(), context.primitiveTypes.end(),
 | 
			
		||||
	std::for_each(types.begin(), types.end(),
 | 
			
		||||
		[&](auto &childType)
 | 
			
		||||
		{
 | 
			
		||||
			if (!childType->isDirty())
 | 
			
		||||
@@ -112,8 +110,10 @@ void PrimitiveType::parseTypedDeclaration(Context &context)
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
PrimitiveType *PrimitiveType::parseExisting(Context &context)
 | 
			
		||||
PrimitiveType *PrimitiveType::parseAndFindOrCreate(Context &context, Domain &domain)
 | 
			
		||||
{
 | 
			
		||||
	auto &types = domain.types();
 | 
			
		||||
 | 
			
		||||
	context.parser.skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
	const auto typeName = context.parser.parseIdentifier(isIdentifier);
 | 
			
		||||
@@ -121,19 +121,22 @@ PrimitiveType *PrimitiveType::parseExisting(Context &context)
 | 
			
		||||
	BOOST_ASSERT(!typeName.empty());
 | 
			
		||||
 | 
			
		||||
	// TODO: use hash map
 | 
			
		||||
	const auto match = std::find_if(context.primitiveTypes.cbegin(), context.primitiveTypes.cend(),
 | 
			
		||||
	const auto match = std::find_if(types.cbegin(), types.cend(),
 | 
			
		||||
		[&](const auto &primitiveType)
 | 
			
		||||
		{
 | 
			
		||||
			return primitiveType->name() == typeName;
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
	if (match == context.primitiveTypes.cend())
 | 
			
		||||
	if (match == types.cend())
 | 
			
		||||
	{
 | 
			
		||||
		// Primitive type "object" is implicitly declared
 | 
			
		||||
		if (typeName != "object")
 | 
			
		||||
			context.logger.parserWarning(context.parser, "Primitive type \"" + typeName + "\" used but never declared");
 | 
			
		||||
 | 
			
		||||
		return create(typeName, context);
 | 
			
		||||
		types.emplace_back(std::make_unique<expressions::PrimitiveType>(typeName));
 | 
			
		||||
		types.back()->setDeclared();
 | 
			
		||||
 | 
			
		||||
		return types.back().get();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	auto *type = match->get();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
#include <plasp/pddl/expressions/Type.h>
 | 
			
		||||
 | 
			
		||||
#include <plasp/pddl/Context.h>
 | 
			
		||||
#include <plasp/pddl/ExpressionContext.h>
 | 
			
		||||
#include <plasp/pddl/expressions/PrimitiveType.h>
 | 
			
		||||
#include <plasp/pddl/expressions/Reference.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
@@ -16,9 +18,9 @@ namespace expressions
 | 
			
		||||
//
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
ExpressionPointer parseExistingPrimitiveType(Context &context, const Variables ¶meters)
 | 
			
		||||
ExpressionPointer parseExistingPrimitiveType(Context &context, ExpressionContext &expressionContext)
 | 
			
		||||
{
 | 
			
		||||
	auto primitiveType = PrimitiveType::parseExisting(context);
 | 
			
		||||
	auto *primitiveType = PrimitiveType::parseAndFindOrCreate(context, expressionContext.domain);
 | 
			
		||||
 | 
			
		||||
	return std::make_unique<Reference<PrimitiveType>>(primitiveType);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,10 +2,14 @@
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
 | 
			
		||||
#include <plasp/pddl/Context.h>
 | 
			
		||||
#include <plasp/pddl/ExpressionContext.h>
 | 
			
		||||
#include <plasp/pddl/ExpressionVisitor.h>
 | 
			
		||||
#include <plasp/pddl/Identifier.h>
 | 
			
		||||
#include <plasp/pddl/expressions/Either.h>
 | 
			
		||||
#include <plasp/pddl/expressions/PrimitiveType.h>
 | 
			
		||||
#include <plasp/pddl/expressions/Type.h>
 | 
			
		||||
#include <plasp/utils/ParserException.h>
 | 
			
		||||
 | 
			
		||||
@@ -29,7 +33,7 @@ Variable::Variable()
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
VariablePointer Variable::parseDeclaration(Context &context)
 | 
			
		||||
void Variable::parseDeclaration(Context &context, Variables ¶meters)
 | 
			
		||||
{
 | 
			
		||||
	context.parser.skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
@@ -42,17 +46,19 @@ VariablePointer Variable::parseDeclaration(Context &context)
 | 
			
		||||
	// Flag variable for potentially upcoming type declaration
 | 
			
		||||
	variable->setDirty();
 | 
			
		||||
 | 
			
		||||
	return variable;
 | 
			
		||||
	parameters.emplace_back(std::move(variable));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Variable::parseTypedDeclaration(Context &context, Variables ¶meters)
 | 
			
		||||
void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expressionContext)
 | 
			
		||||
{
 | 
			
		||||
	// Parse and store variable itself
 | 
			
		||||
	parameters.emplace_back(parseDeclaration(context));
 | 
			
		||||
	auto &variables = expressionContext.parameters;
 | 
			
		||||
 | 
			
		||||
	auto ¶meter = parameters.back();
 | 
			
		||||
	// Parse and store variable itself
 | 
			
		||||
	parseDeclaration(context, variables);
 | 
			
		||||
 | 
			
		||||
	auto &variable = variables.back();
 | 
			
		||||
 | 
			
		||||
	context.parser.skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
@@ -66,14 +72,14 @@ void Variable::parseTypedDeclaration(Context &context, Variables ¶meters)
 | 
			
		||||
		[&](const auto *type)
 | 
			
		||||
		{
 | 
			
		||||
			// Set the argument type for all previously flagged arguments
 | 
			
		||||
			std::for_each(parameters.begin(), parameters.end(),
 | 
			
		||||
				[&](auto ¶meter)
 | 
			
		||||
			std::for_each(variables.begin(), variables.end(),
 | 
			
		||||
				[&](auto &variable)
 | 
			
		||||
				{
 | 
			
		||||
					if (!parameter->isDirty())
 | 
			
		||||
					if (!variable->isDirty())
 | 
			
		||||
						return;
 | 
			
		||||
 | 
			
		||||
					parameter->setType(type);
 | 
			
		||||
					parameter->setDirty(false);
 | 
			
		||||
					variable->setType(type);
 | 
			
		||||
					variable->setDirty(false);
 | 
			
		||||
				});
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
@@ -85,23 +91,23 @@ void Variable::parseTypedDeclaration(Context &context, Variables ¶meters)
 | 
			
		||||
		context.parser.expect<std::string>("(");
 | 
			
		||||
		context.parser.expect<std::string>("either");
 | 
			
		||||
 | 
			
		||||
		parameter->m_eitherExpression = Either::parse(context, parameters, parseExistingPrimitiveType);
 | 
			
		||||
		variable->m_eitherExpression = Either::parse(context, expressionContext, parseExistingPrimitiveType);
 | 
			
		||||
 | 
			
		||||
		context.parser.expect<std::string>(")");
 | 
			
		||||
 | 
			
		||||
		setType(parameter->m_eitherExpression.get());
 | 
			
		||||
		setType(variable->m_eitherExpression.get());
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Parse primitive type
 | 
			
		||||
	const auto *type = PrimitiveType::parseExisting(context);
 | 
			
		||||
	const auto *type = PrimitiveType::parseAndFindOrCreate(context, expressionContext.domain);
 | 
			
		||||
 | 
			
		||||
	setType(type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
const Variable *Variable::parseExisting(Context &context, const Variables &variables)
 | 
			
		||||
const Variable *Variable::parseAndFind(Context &context, const ExpressionContext &expressionContext)
 | 
			
		||||
{
 | 
			
		||||
	context.parser.skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
@@ -109,6 +115,8 @@ const Variable *Variable::parseExisting(Context &context, const Variables &varia
 | 
			
		||||
 | 
			
		||||
	const auto variableName = context.parser.parseIdentifier(isIdentifier);
 | 
			
		||||
 | 
			
		||||
	const auto &variables = expressionContext.parameters;
 | 
			
		||||
 | 
			
		||||
	const auto match = std::find_if(variables.cbegin(), variables.cend(),
 | 
			
		||||
		[&](const auto &variable)
 | 
			
		||||
		{
 | 
			
		||||
@@ -116,7 +124,7 @@ const Variable *Variable::parseExisting(Context &context, const Variables &varia
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
	if (match == variables.cend())
 | 
			
		||||
		throw utils::ParserException(context.parser, "Variable \"" + variableName + "\" used but never declared");
 | 
			
		||||
		throw utils::ParserException(context.parser, "Parameter \"" + variableName + "\" used but never declared");
 | 
			
		||||
 | 
			
		||||
	return match->get();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user