From 5a18eb393fa1175296da4b9782595036c5db679d Mon Sep 17 00:00:00 2001 From: Dominik Drexler Date: Thu, 2 Jan 2025 09:51:29 +0100 Subject: [PATCH] added function expression comparison goal descriptor of :numeric-fluents requirement --- include/loki/details/pddl/conditions.hpp | 47 +++++++++++++++++-- include/loki/details/pddl/declarations.hpp | 2 + .../details/pddl/function_expressions.hpp | 12 +++++ include/loki/details/pddl/repositories.hpp | 8 ++++ src/ast/parser_def.hpp | 4 +- src/pddl/conditions.cpp | 38 +++++++++++---- src/pddl/formatter.cpp | 9 ++++ src/pddl/formatter.hpp | 1 + src/pddl/function_expressions.cpp | 14 ++++++ src/pddl/parser/conditions.cpp | 11 ++++- src/pddl/parser/functions.cpp | 11 +++++ src/pddl/parser/functions.hpp | 10 ++++ src/pddl/repositories.cpp | 14 ++++++ 13 files changed, 164 insertions(+), 17 deletions(-) diff --git a/include/loki/details/pddl/conditions.hpp b/include/loki/details/pddl/conditions.hpp index 862fc0a3..5071d20c 100644 --- a/include/loki/details/pddl/conditions.hpp +++ b/include/loki/details/pddl/conditions.hpp @@ -19,6 +19,7 @@ #define LOKI_INCLUDE_LOKI_PDDL_CONDITIONS_HPP_ #include "loki/details/pddl/declarations.hpp" +#include "loki/details/pddl/function_expressions.hpp" #include @@ -213,15 +214,52 @@ class ConditionForallImpl auto identifiable_members() const { return std::forward_as_tuple(std::as_const(m_parameters), std::as_const(m_condition)); } }; +class ConditionFunctionExpressionComparisonImpl +{ +private: + size_t m_index; + BinaryComparatorEnum m_binary_comparator; + FunctionExpression m_function_expression_left; + FunctionExpression m_function_expression_right; + + ConditionFunctionExpressionComparisonImpl(size_t index, + BinaryComparatorEnum binary_comparator, + FunctionExpression function_expression_left, + FunctionExpression function_expression_right); + + // Give access to the constructor. + template + friend class SegmentedRepository; + +public: + // moveable but not copyable + ConditionFunctionExpressionComparisonImpl(const ConditionFunctionExpressionComparisonImpl& other) = delete; + ConditionFunctionExpressionComparisonImpl& operator=(const ConditionFunctionExpressionComparisonImpl& other) = delete; + ConditionFunctionExpressionComparisonImpl(ConditionFunctionExpressionComparisonImpl&& other) = default; + ConditionFunctionExpressionComparisonImpl& operator=(ConditionFunctionExpressionComparisonImpl&& other) = default; + + size_t get_index() const; + const BinaryComparatorEnum& get_binary_comparator() const; + const FunctionExpression& get_function_expression_left() const; + const FunctionExpression& get_function_expression_right() const; + + auto identifiable_members() const + { + return std::forward_as_tuple(std::as_const(m_binary_comparator), std::as_const(m_function_expression_left), std::as_const(m_function_expression_right)); + } +}; + /* Condition */ +using ConditionVariant = std:: + variant; + class ConditionImpl { private: size_t m_index; - std::variant m_condition; + ConditionVariant m_condition; - ConditionImpl(size_t index, - std::variant condition); + ConditionImpl(size_t index, ConditionVariant condition); // Give access to the constructor. template @@ -235,7 +273,7 @@ class ConditionImpl ConditionImpl& operator=(ConditionImpl&& other) = default; size_t get_index() const; - const std::variant& get_condition() const; + const ConditionVariant& get_condition() const; auto identifiable_members() const { return std::forward_as_tuple(std::as_const(m_condition)); } }; @@ -247,6 +285,7 @@ extern std::ostream& operator<<(std::ostream& out, const ConditionNotImpl& eleme extern std::ostream& operator<<(std::ostream& out, const ConditionImplyImpl& element); extern std::ostream& operator<<(std::ostream& out, const ConditionExistsImpl& element); extern std::ostream& operator<<(std::ostream& out, const ConditionForallImpl& element); +extern std::ostream& operator<<(std::ostream& out, const ConditionFunctionExpressionComparisonImpl& element); extern std::ostream& operator<<(std::ostream& out, const ConditionImpl& element); } diff --git a/include/loki/details/pddl/declarations.hpp b/include/loki/details/pddl/declarations.hpp index fce6e62f..a8c24139 100644 --- a/include/loki/details/pddl/declarations.hpp +++ b/include/loki/details/pddl/declarations.hpp @@ -96,6 +96,8 @@ class ConditionExistsImpl; using ConditionExists = const ConditionExistsImpl*; class ConditionForallImpl; using ConditionForall = const ConditionForallImpl*; +class ConditionFunctionExpressionComparisonImpl; +using ConditionFunctionExpressionComparison = const ConditionFunctionExpressionComparisonImpl*; class ConditionImpl; using Condition = const ConditionImpl*; using ConditionList = std::vector; diff --git a/include/loki/details/pddl/function_expressions.hpp b/include/loki/details/pddl/function_expressions.hpp index 68792973..58706507 100644 --- a/include/loki/details/pddl/function_expressions.hpp +++ b/include/loki/details/pddl/function_expressions.hpp @@ -25,6 +25,18 @@ namespace loki { +enum class BinaryComparatorEnum +{ + GREATER, ///< ">" + LESS, ///< "<" + EQUAL, ///< "=" + GREATER_EQUAL, ///< ">=" + LESS_EQUAL, ///< "<=" +}; + +extern std::unordered_map binary_comparator_enum_to_string; +extern const std::string& to_string(BinaryComparatorEnum binary_comparator); + enum class BinaryOperatorEnum { MUL, diff --git a/include/loki/details/pddl/repositories.hpp b/include/loki/details/pddl/repositories.hpp index 3734d257..143c062b 100644 --- a/include/loki/details/pddl/repositories.hpp +++ b/include/loki/details/pddl/repositories.hpp @@ -74,6 +74,7 @@ using ConditionNotRepository = SegmentedPDDLRepository; using ConditionImplyRepository = SegmentedPDDLRepository; using ConditionExistsRepository = SegmentedPDDLRepository; using ConditionForallRepository = SegmentedPDDLRepository; +using ConditionFunctionExpressionComparisonRepository = SegmentedPDDLRepository; using ConditionRepository = SegmentedPDDLRepository; using EffectLiteralRepository = SegmentedPDDLRepository; using EffectAndRepository = SegmentedPDDLRepository; @@ -114,6 +115,7 @@ using PDDLTypeToRepository = boost::hana::pair, ConditionImplyRepository>, boost::hana::pair, ConditionExistsRepository>, boost::hana::pair, ConditionForallRepository>, + boost::hana::pair, ConditionFunctionExpressionComparisonRepository>, boost::hana::pair, ConditionRepository>, boost::hana::pair, EffectLiteralRepository>, boost::hana::pair, EffectAndRepository>, @@ -205,6 +207,10 @@ class PDDLRepositories ConditionForall get_or_create_condition_forall(ParameterList parameters, Condition condition); + ConditionFunctionExpressionComparison get_or_create_condition_function_expression_comparison(BinaryComparatorEnum binary_comparator, + FunctionExpression function_expression_left, + FunctionExpression function_expression_right); + Condition get_or_create_condition(ConditionLiteral condition); Condition get_or_create_condition(ConditionAnd condition); @@ -219,6 +225,8 @@ class PDDLRepositories Condition get_or_create_condition(ConditionForall condition); + Condition get_or_create_condition(ConditionFunctionExpressionComparison condition); + EffectLiteral get_or_create_effect_literal(Literal literal); EffectAnd get_or_create_effect_and(EffectList effects); diff --git a/src/ast/parser_def.hpp b/src/ast/parser_def.hpp index 6138e402..2217f43b 100644 --- a/src/ast/parser_def.hpp +++ b/src/ast/parser_def.hpp @@ -333,7 +333,7 @@ const auto binary_comparator_equal_def = lit('=') > x3::attr(ast::BinaryComparat const auto binary_comparator_greater_equal_def = lit(">=") > x3::attr(ast::BinaryComparatorGreaterEqual {}); const auto binary_comparator_less_equal_def = lit("<=") > x3::attr(ast::BinaryComparatorLessEqual {}); const auto binary_comparator_def = - binary_comparator_greater | binary_comparator_less | binary_comparator_equal | binary_comparator_greater_equal | binary_comparator_less_equal; + binary_comparator_greater_equal | binary_comparator_less_equal | binary_comparator_greater | binary_comparator_less | binary_comparator_equal; const auto function_head_def = ((lit('(') >> function_symbol > *term) > lit(')')) | (function_symbol > x3::attr(std::vector {})); const auto function_expression_def = function_expression_binary_op | function_expression_minus | function_expression_head | function_expression_number; @@ -353,7 +353,7 @@ const auto goal_descriptor_not_def = (lit('(') >> keyword_lit("not")) > goal_des const auto goal_descriptor_imply_def = (lit('(') >> keyword_lit("imply")) > goal_descriptor > goal_descriptor > lit(')'); const auto goal_descriptor_exists_def = (lit('(') >> keyword_lit("exists")) > lit('(') > typed_list_of_variables > lit(')') > goal_descriptor > lit(')'); const auto goal_descriptor_forall_def = (lit('(') >> keyword_lit("forall")) > lit('(') > typed_list_of_variables > lit(')') > goal_descriptor > lit(')'); -const auto goal_descriptor_function_comparison_def = (lit('(') >> binary_comparator) >> function_expression > function_expression > lit(')'); +const auto goal_descriptor_function_comparison_def = (lit('(') >> binary_comparator) > function_expression > function_expression > lit(')'); const auto constraint_goal_descriptor_def = constraint_goal_descriptor_and | constraint_goal_descriptor_forall | constraint_goal_descriptor_at_end | constraint_goal_descriptor_always | constraint_goal_descriptor_sometime | constraint_goal_descriptor_within diff --git a/src/pddl/conditions.cpp b/src/pddl/conditions.cpp index aefdd435..1b498225 100644 --- a/src/pddl/conditions.cpp +++ b/src/pddl/conditions.cpp @@ -94,22 +94,33 @@ const ParameterList& ConditionForallImpl::get_parameters() const { return m_para const Condition& ConditionForallImpl::get_condition() const { return m_condition; } -/* Condition */ -ConditionImpl::ConditionImpl( - size_t index, - std::variant condition) : +/* ConditionFunctionExpressionComparison */ + +ConditionFunctionExpressionComparisonImpl::ConditionFunctionExpressionComparisonImpl(size_t index, + BinaryComparatorEnum binary_comparator, + FunctionExpression function_expression_left, + FunctionExpression function_expression_right) : m_index(index), - m_condition(std::move(condition)) + m_binary_comparator(binary_comparator), + m_function_expression_left(function_expression_left), + m_function_expression_right(function_expression_right) { } +size_t ConditionFunctionExpressionComparisonImpl::get_index() const { return m_index; } + +const BinaryComparatorEnum& ConditionFunctionExpressionComparisonImpl::get_binary_comparator() const { return m_binary_comparator; } + +const FunctionExpression& ConditionFunctionExpressionComparisonImpl::get_function_expression_left() const { return m_function_expression_left; } + +const FunctionExpression& ConditionFunctionExpressionComparisonImpl::get_function_expression_right() const { return m_function_expression_right; } + +/* Condition */ +ConditionImpl::ConditionImpl(size_t index, ConditionVariant condition) : m_index(index), m_condition(std::move(condition)) {} + size_t ConditionImpl::get_index() const { return m_index; } -const std::variant& -ConditionImpl::get_condition() const -{ - return m_condition; -} +const ConditionVariant& ConditionImpl::get_condition() const { return m_condition; } std::ostream& operator<<(std::ostream& out, const ConditionLiteralImpl& element) { @@ -160,6 +171,13 @@ std::ostream& operator<<(std::ostream& out, const ConditionForallImpl& element) return out; } +std::ostream& operator<<(std::ostream& out, const ConditionFunctionExpressionComparisonImpl& element) +{ + auto formatter = PDDLFormatter(); + formatter.write(element, out); + return out; +} + std::ostream& operator<<(std::ostream& out, const ConditionImpl& element) { auto formatter = PDDLFormatter(); diff --git a/src/pddl/formatter.cpp b/src/pddl/formatter.cpp index 2e4a8d03..ec5bdf07 100644 --- a/src/pddl/formatter.cpp +++ b/src/pddl/formatter.cpp @@ -159,6 +159,15 @@ void PDDLFormatter::write(const ConditionForallImpl& element, std::ostream& out) out << ")"; } +void PDDLFormatter::write(const ConditionFunctionExpressionComparisonImpl& element, std::ostream& out) +{ + out << "(" << to_string(element.get_binary_comparator()) << " "; + write(*element.get_function_expression_left(), out); + out << " "; + write(*element.get_function_expression_right(), out); + out << ")"; +} + void PDDLFormatter::write(const ConditionImpl& element, std::ostream& out) { std::visit([this, &out](const auto& arg) { this->write(*arg, out); }, element.get_condition()); diff --git a/src/pddl/formatter.hpp b/src/pddl/formatter.hpp index 2e6764ca..e861b0d3 100644 --- a/src/pddl/formatter.hpp +++ b/src/pddl/formatter.hpp @@ -66,6 +66,7 @@ class PDDLFormatter void write(const ConditionImplyImpl& element, std::ostream& out); void write(const ConditionExistsImpl& element, std::ostream& out); void write(const ConditionForallImpl& element, std::ostream& out); + void write(const ConditionFunctionExpressionComparisonImpl& element, std::ostream& out); void write(const ConditionImpl& element, std::ostream& out); void write(const DomainImpl& element, std::ostream& out); void write(const EffectLiteralImpl& element, std::ostream& out); diff --git a/src/pddl/function_expressions.cpp b/src/pddl/function_expressions.cpp index 49f753b8..9efa1c82 100644 --- a/src/pddl/function_expressions.cpp +++ b/src/pddl/function_expressions.cpp @@ -25,6 +25,20 @@ namespace loki { +std::unordered_map binary_comparator_enum_to_string = { + { BinaryComparatorEnum::GREATER, ">" }, // + { BinaryComparatorEnum::LESS, "<" }, // + { BinaryComparatorEnum::EQUAL, "=" }, // + { BinaryComparatorEnum::GREATER_EQUAL, ">=" }, // + { BinaryComparatorEnum::LESS_EQUAL, "<=" }, +}; + +const std::string& to_string(BinaryComparatorEnum binary_comparator) +{ + assert(binary_comparator_enum_to_string.count(binary_comparator)); + return binary_comparator_enum_to_string.at(binary_comparator); +} + std::unordered_map binary_operator_enum_to_string = { { BinaryOperatorEnum::MUL, "*" }, { BinaryOperatorEnum::PLUS, "+" }, diff --git a/src/pddl/parser/conditions.cpp b/src/pddl/parser/conditions.cpp index 6910b968..61687c1c 100644 --- a/src/pddl/parser/conditions.cpp +++ b/src/pddl/parser/conditions.cpp @@ -18,6 +18,7 @@ #include "conditions.hpp" #include "error_handling.hpp" +#include "functions.hpp" #include "literal.hpp" #include "loki/details/ast/printer.hpp" #include "loki/details/pddl/conditions.hpp" @@ -141,7 +142,15 @@ Condition parse(const ast::GoalDescriptorFunctionComparison& node, Context& cont { throw UndefinedRequirementError(RequirementEnum::NUMERIC_FLUENTS, context.scopes.top().get_error_handler()(node, "")); } - throw NotImplementedError("parse(const ast::GoalDescriptorFunctionComparison& node, Context& context)"); + context.references.untrack(RequirementEnum::NUMERIC_FLUENTS); + + auto binary_comparator = boost::apply_visitor(BinaryComparatorVisitor(), node.binary_comparator); + auto function_expression_left = parse(node.function_expression_left, context); + auto function_expression_right = parse(node.function_expression_right, context); + auto condition = context.factories.get_or_create_condition( + context.factories.get_or_create_condition_function_expression_comparison(binary_comparator, function_expression_left, function_expression_right)); + context.positions.push_back(condition, node); + return condition; } Condition parse(const ast::ConstraintGoalDescriptor& node, Context& context) { return boost::apply_visitor(ConditionVisitor(context), node); } diff --git a/src/pddl/parser/functions.cpp b/src/pddl/parser/functions.cpp index e4c8ac41..1dab77c6 100644 --- a/src/pddl/parser/functions.cpp +++ b/src/pddl/parser/functions.cpp @@ -26,6 +26,17 @@ namespace loki { +/* BinaryComparatorEnum */ +BinaryComparatorEnum BinaryComparatorVisitor::operator()(const ast::BinaryComparatorGreater&) const { return BinaryComparatorEnum::GREATER; } + +BinaryComparatorEnum BinaryComparatorVisitor::operator()(const ast::BinaryComparatorLess&) const { return BinaryComparatorEnum::LESS; } + +BinaryComparatorEnum BinaryComparatorVisitor::operator()(const ast::BinaryComparatorEqual&) const { return BinaryComparatorEnum::EQUAL; } + +BinaryComparatorEnum BinaryComparatorVisitor::operator()(const ast::BinaryComparatorGreaterEqual&) const { return BinaryComparatorEnum::GREATER_EQUAL; } + +BinaryComparatorEnum BinaryComparatorVisitor::operator()(const ast::BinaryComparatorLessEqual&) const { return BinaryComparatorEnum::LESS_EQUAL; } + /* MultiOperator */ MultiOperatorEnum MultiOperatorVisitor::operator()(const ast::MultiOperatorMul&) const { return MultiOperatorEnum::MUL; } diff --git a/src/pddl/parser/functions.hpp b/src/pddl/parser/functions.hpp index 28180641..f260fecd 100644 --- a/src/pddl/parser/functions.hpp +++ b/src/pddl/parser/functions.hpp @@ -28,6 +28,16 @@ namespace loki { +/* BinaryComparator */ +struct BinaryComparatorVisitor : boost::static_visitor +{ + BinaryComparatorEnum operator()(const ast::BinaryComparatorGreater& node) const; + BinaryComparatorEnum operator()(const ast::BinaryComparatorLess& node) const; + BinaryComparatorEnum operator()(const ast::BinaryComparatorEqual& node) const; + BinaryComparatorEnum operator()(const ast::BinaryComparatorGreaterEqual& node) const; + BinaryComparatorEnum operator()(const ast::BinaryComparatorLessEqual& node) const; +}; + /* MultiOperator */ struct MultiOperatorVisitor : boost::static_visitor { diff --git a/src/pddl/repositories.cpp b/src/pddl/repositories.cpp index 3ce61462..13e06c74 100644 --- a/src/pddl/repositories.cpp +++ b/src/pddl/repositories.cpp @@ -49,6 +49,7 @@ PDDLTypeToRepository create_default_pddl_type_to_repository() boost::hana::make_pair(boost::hana::type_c, ConditionImplyRepository {}), boost::hana::make_pair(boost::hana::type_c, ConditionExistsRepository {}), boost::hana::make_pair(boost::hana::type_c, ConditionForallRepository {}), + boost::hana::make_pair(boost::hana::type_c, ConditionFunctionExpressionComparisonRepository {}), boost::hana::make_pair(boost::hana::type_c, ConditionRepository {}), boost::hana::make_pair(boost::hana::type_c, EffectLiteralRepository {}), boost::hana::make_pair(boost::hana::type_c, EffectAndRepository {}), @@ -235,6 +236,14 @@ ConditionForall PDDLRepositories::get_or_create_condition_forall(ParameterList p return boost::hana::at_key(m_repositories, boost::hana::type {}).get_or_create(std::move(parameters), std::move(condition)); } +ConditionFunctionExpressionComparison PDDLRepositories::get_or_create_condition_function_expression_comparison(BinaryComparatorEnum binary_comparator, + FunctionExpression function_expression_left, + FunctionExpression function_expression_right) +{ + return boost::hana::at_key(m_repositories, boost::hana::type {}) + .get_or_create(std::move(binary_comparator), std::move(function_expression_left), std::move(function_expression_right)); +} + Condition PDDLRepositories::get_or_create_condition(ConditionLiteral condition) { return boost::hana::at_key(m_repositories, boost::hana::type {}).get_or_create(condition); @@ -270,6 +279,11 @@ Condition PDDLRepositories::get_or_create_condition(ConditionForall condition) return boost::hana::at_key(m_repositories, boost::hana::type {}).get_or_create(condition); } +Condition PDDLRepositories::get_or_create_condition(ConditionFunctionExpressionComparison condition) +{ + return boost::hana::at_key(m_repositories, boost::hana::type {}).get_or_create(condition); +} + EffectLiteral PDDLRepositories::get_or_create_effect_literal(Literal literal) { return boost::hana::at_key(m_repositories, boost::hana::type {}).get_or_create(std::move(literal));