Skip to content

Commit

Permalink
factored out tracking and untracking of lists of pddl objects
Browse files Browse the repository at this point in the history
  • Loading branch information
drexlerd committed Jan 6, 2024
1 parent bba05be commit 2f30b73
Show file tree
Hide file tree
Showing 11 changed files with 232 additions and 91 deletions.
19 changes: 6 additions & 13 deletions src/domain/pddl/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "parser/types.hpp"
#include "parser/structure.hpp"
#include "parser/common.hpp"
#include "parser/reference_utils.hpp"

using namespace loki::domain;
using namespace std;
Expand Down Expand Up @@ -72,11 +73,13 @@ pddl::Domain parse(const ast::Domain& domain_node, Context& context) {
if (domain_node.predicates.has_value()) {
predicates = parse(domain_node.predicates.value(), context);
}
track_predicate_references(predicates, context);
/* Functions section */
auto function_skeletons = pddl::FunctionSkeletonList();
if (domain_node.functions.has_value()) {
function_skeletons = parse(domain_node.functions.value(), context);
}
track_function_skeleton_references(function_skeletons, context);
/* Action Schema section */
auto derived_predicate_list = pddl::DerivedPredicateList();
auto action_list = pddl::ActionList();
Expand All @@ -85,19 +88,9 @@ pddl::Domain parse(const ast::Domain& domain_node, Context& context) {
boost::apply_visitor(UnpackingVisitor(action_list, derived_predicate_list), variant);
}
// Check references
for (const auto& predicate : predicates) {
if (context.references.exists(predicate)) {
const auto& [_predicate, position, error_handler] = context.scopes.get<pddl::PredicateImpl>(predicate->get_name()).value();
throw UnusedPredicateError(predicate->get_name(), error_handler(position.value(), ""));
}
}
for (const auto& function_skeleton : function_skeletons) {
if (context.references.exists(function_skeleton)) {
const auto& [_function_skeleton, position, error_handler] = context.scopes.get<pddl::FunctionSkeletonImpl>(function_skeleton->get_name()).value();
throw UnusedFunctionSkeletonError(function_skeleton->get_name(), error_handler(position.value(), ""));
}
}

test_predicate_references(predicates, context);
test_function_skeleton_references(function_skeletons, context);

const auto domain = context.factories.domains.get_or_create<pddl::DomainImpl>(domain_name, context.requirements, types, constants, predicates, function_skeletons, action_list);
context.positions.push_back(domain, domain_node);
return domain;
Expand Down
35 changes: 9 additions & 26 deletions src/domain/pddl/parser/conditions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "literal.hpp"
#include "parameters.hpp"
#include "reference_utils.hpp"

#include "../../../../include/loki/domain/pddl/exceptions.hpp"

Expand Down Expand Up @@ -104,43 +105,25 @@ pddl::Condition parse(const domain::ast::GoalDescriptorExists& node, Context& co
}
context.references.untrack(pddl::RequirementEnum::EXISTENTIAL_PRECONDITIONS);
context.scopes.open_scope();
auto parameters = boost::apply_visitor(ParameterListVisitor(context), node.typed_list_of_variables);
for (const auto& parameter : parameters) {
context.references.track(parameter->get_variable());
}
auto parameter_list = boost::apply_visitor(ParameterListVisitor(context), node.typed_list_of_variables);
track_variable_references(parameter_list, context);
auto child_condition = parse(node.goal_descriptor, context);
// Check referenced_pointers
for (const auto& parameter : parameters) {
if (context.references.exists(parameter->get_variable())) {
const auto& [variable, position, error_handler] = context.scopes.get<pddl::VariableImpl>(parameter->get_variable()->get_name()).value();
throw UnusedVariableError(variable->get_name(), error_handler(position.value(), ""));
}
}

test_variable_references(parameter_list, context);
context.scopes.close_scope();
auto condition = context.factories.conditions.get_or_create<pddl::ConditionExistsImpl>(parameters, child_condition);
auto condition = context.factories.conditions.get_or_create<pddl::ConditionExistsImpl>(parameter_list, child_condition);
context.positions.push_back(condition, node);
return condition;
}

template<typename ConditionNode>
pddl::Condition parse_condition_forall(const domain::ast::TypedListOfVariables& parameters_node, const ConditionNode& condition_node, Context& context) {
context.scopes.open_scope();
auto parameters = boost::apply_visitor(ParameterListVisitor(context), parameters_node);
for (const auto& parameter : parameters) {
context.references.track(parameter->get_variable());
}
auto parameter_list = boost::apply_visitor(ParameterListVisitor(context), parameters_node);
track_variable_references(parameter_list, context);
auto child_condition = parse(condition_node, context);
// Check referenced_pointers
for (const auto& parameter : parameters) {
if (context.references.exists(parameter->get_variable())) {
const auto& [variable, position, error_handler] = context.scopes.get<pddl::VariableImpl>(parameter->get_variable()->get_name()).value();
throw UnusedVariableError(variable->get_name(), error_handler(position.value(), ""));
}
}

test_variable_references(parameter_list, context);
context.scopes.close_scope();
auto condition = context.factories.conditions.get_or_create<pddl::ConditionForallImpl>(parameters, child_condition);
auto condition = context.factories.conditions.get_or_create<pddl::ConditionForallImpl>(parameter_list, child_condition);
context.positions.push_back(condition, condition_node);
return condition;
}
Expand Down
19 changes: 6 additions & 13 deletions src/domain/pddl/parser/effects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "literal.hpp"
#include "parameters.hpp"
#include "functions.hpp"
#include "reference_utils.hpp"

#include "../../../../include/loki/domain/pddl/exceptions.hpp"


Expand Down Expand Up @@ -112,21 +114,12 @@ pddl::Effect parse(const domain::ast::EffectProduction& node, Context& context)

pddl::Effect parse(const domain::ast::EffectConditionalForall& node, Context& context) {
context.scopes.open_scope();
const auto parameters = boost::apply_visitor(ParameterListVisitor(context), node.typed_list_of_variables);
for (const auto& parameter : parameters) {
context.references.track(parameter->get_variable());
}
const auto parameter_list = boost::apply_visitor(ParameterListVisitor(context), node.typed_list_of_variables);
track_variable_references(parameter_list, context);
const auto child_effect = parse(node.effect, context);
// Check referenced_pointers
for (const auto& parameter : parameters) {
if (context.references.exists(parameter->get_variable())) {
const auto& [variable, position, error_handler] = context.scopes.get<pddl::VariableImpl>(parameter->get_variable()->get_name()).value();
throw UnusedVariableError(variable->get_name(), error_handler(position.value(), ""));
}
}

test_variable_references(parameter_list, context);
context.scopes.close_scope();
const auto effect = context.factories.effects.get_or_create<pddl::EffectConditionalForallImpl>(parameters, child_effect);
const auto effect = context.factories.effects.get_or_create<pddl::EffectConditionalForallImpl>(parameter_list, child_effect);
context.positions.push_back(effect, node);
return effect;
}
Expand Down
13 changes: 6 additions & 7 deletions src/domain/pddl/parser/functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pddl::BinaryOperatorEnum MultiToBinaryOperatorVisitor::operator()(const domain::


pddl::BinaryOperatorEnum BinaryOperatorVisitor::operator()(const domain::ast::BinaryOperatorDiv&) const {
return pddl::BinaryOperatorEnum::DIV;
return pddl::BinaryOperatorEnum::DIV;
}

pddl::BinaryOperatorEnum BinaryOperatorVisitor::operator()(const domain::ast::BinaryOperatorMinus&) const {
Expand Down Expand Up @@ -145,7 +145,6 @@ static void test_multiple_definition(const pddl::FunctionSkeleton& function_skel
static void insert_context_information(const pddl::FunctionSkeleton& function_skeleton, const domain::ast::Name& node, Context& context) {
context.positions.push_back(function_skeleton, node);
context.scopes.insert<pddl::FunctionSkeletonImpl>(function_skeleton->get_name(), function_skeleton, node);
context.references.track(function_skeleton);
}


Expand All @@ -167,7 +166,7 @@ pddl::FunctionSkeleton parse(const domain::ast::AtomicFunctionSkeletonTotalCost&
const auto& [type, _position, _error_handler] = context.scopes.get<pddl::TypeImpl>("number").value();
auto function_name = parse(node.function_symbol.name);
auto function_skeleton = context.factories.function_skeletons.get_or_create<pddl::FunctionSkeletonImpl>(function_name, pddl::ParameterList{}, type);

test_multiple_definition(function_skeleton, node.function_symbol.name, context);
insert_context_information(function_skeleton, node.function_symbol.name, context);

Expand All @@ -177,18 +176,18 @@ pddl::FunctionSkeleton parse(const domain::ast::AtomicFunctionSkeletonTotalCost&
pddl::FunctionSkeleton parse(const domain::ast::AtomicFunctionSkeletonGeneral& node, Context& context) {
if (!context.requirements->test(pddl::RequirementEnum::NUMERIC_FLUENTS)) {
throw UndefinedRequirementError(pddl::RequirementEnum::NUMERIC_FLUENTS, context.positions.get_error_handler()(node, ""));
}
}
context.references.untrack(pddl::RequirementEnum::NUMERIC_FLUENTS);

context.scopes.open_scope();
auto function_parameters = boost::apply_visitor(ParameterListVisitor(context), node.arguments);
context.scopes.close_scope();

assert(context.scopes.get<pddl::TypeImpl>("number").has_value());
const auto& [type, _position, _error_handler] = context.scopes.get<pddl::TypeImpl>("number").value();
auto function_name = parse(node.function_symbol.name);
auto function_skeleton = context.factories.function_skeletons.get_or_create<pddl::FunctionSkeletonImpl>(function_name, function_parameters, type);

test_multiple_definition(function_skeleton, node.function_symbol.name, context);
insert_context_information(function_skeleton, node.function_symbol.name, context);

Expand Down Expand Up @@ -216,7 +215,7 @@ pddl::FunctionSkeletonList parse(const std::vector<domain::ast::AtomicFunctionSk

pddl::FunctionSkeletonList parse(const domain::ast::FunctionTypedListOfAtomicFunctionSkeletonsRecursively& function_skeleton_list_recursively_node, Context& context) {
auto function_skeleton_list = parse_function_skeleton_definitions(function_skeleton_list_recursively_node.atomic_function_skeletons, context);

if (function_skeleton_list_recursively_node.function_typed_list_of_atomic_function_skeletons.has_value()) {
auto add_function_skeleton_list = boost::apply_visitor(FunctionSkeletonListVisitor(context), function_skeleton_list_recursively_node.function_typed_list_of_atomic_function_skeletons.value().get());
function_skeleton_list.insert(function_skeleton_list.end(), add_function_skeleton_list.begin(), add_function_skeleton_list.end());
Expand Down
1 change: 0 additions & 1 deletion src/domain/pddl/parser/predicates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ static void test_multiple_definition(const pddl::Predicate& predicate, const dom
static void insert_context_information(const pddl::Predicate& predicate, const domain::ast::Predicate& node, Context& context) {
context.positions.push_back(predicate, node);
context.scopes.insert(predicate->get_name(), predicate, node);
context.references.track(predicate);
}


Expand Down
73 changes: 73 additions & 0 deletions src/domain/pddl/parser/reference_utils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (C) 2023 Dominik Drexler
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#include "reference_utils.hpp"

#include "../../../../include/loki/domain/pddl/exceptions.hpp"


namespace loki {

void track_variable_references(const pddl::ParameterList& parameter_list, Context& context) {
for (const auto& parameter : parameter_list) {
context.references.track(parameter->get_variable());
}
}

void test_variable_references(const pddl::ParameterList& parameter_list, const Context& context) {
for (const auto& parameter : parameter_list) {
if (context.references.exists(parameter->get_variable())) {
const auto& [variable, position, error_handler] = context.scopes.get<pddl::VariableImpl>(parameter->get_variable()->get_name()).value();
throw UnusedVariableError(variable->get_name(), error_handler(position.value(), ""));
}
}
}


void track_predicate_references(const pddl::PredicateList& predicate_list, Context& context) {
for (const auto& predicate : predicate_list) {
context.references.track(predicate);
}
}

void test_predicate_references(const pddl::PredicateList& predicate_list, const Context& context) {
for (const auto& predicate : predicate_list) {
if (context.references.exists(predicate)) {
const auto& [_predicate, position, error_handler] = context.scopes.get<pddl::PredicateImpl>(predicate->get_name()).value();
throw UnusedPredicateError(predicate->get_name(), error_handler(position.value(), ""));
}
}
}


void track_function_skeleton_references(const pddl::FunctionSkeletonList& function_skeleton_list, Context& context) {
for (const auto& function_skeleton : function_skeleton_list) {
context.references.track(function_skeleton);
}
}

void test_function_skeleton_references(const pddl::FunctionSkeletonList& function_skeleton_list, const Context& context) {
for (const auto& function_skeleton : function_skeleton_list) {
if (context.references.exists(function_skeleton)) {
const auto& [_function_skeleton, position, error_handler] = context.scopes.get<pddl::FunctionSkeletonImpl>(function_skeleton->get_name()).value();
throw UnusedFunctionSkeletonError(function_skeleton->get_name(), error_handler(position.value(), ""));
}
}
}


}
46 changes: 46 additions & 0 deletions src/domain/pddl/parser/reference_utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (C) 2023 Dominik Drexler
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#ifndef LOKI_SRC_PROBLEM_PDDL_PARSER_REFERENCE_UTILS_HPP_
#define LOKI_SRC_PROBLEM_PDDL_PARSER_REFERENCE_UTILS_HPP_

#include "../../../../include/loki/common/pddl/context.hpp"
#include "../../../../include/loki/domain/pddl/declarations.hpp"
#include "../../../../include/loki/domain/pddl/parameter.hpp"


namespace loki {

// For tracking an untracking of lists of pddl objects

extern void track_variable_references(const pddl::ParameterList& parameter_list, Context& context);

extern void test_variable_references(const pddl::ParameterList& parameter_list, const Context& context);


extern void track_predicate_references(const pddl::PredicateList& predicate_list, Context& context);

extern void test_predicate_references(const pddl::PredicateList& predicate_list, const Context& context);


extern void track_function_skeleton_references(const pddl::FunctionSkeletonList& function_skeleton_list, Context& context);

extern void test_function_skeleton_references(const pddl::FunctionSkeletonList& function_skeleton_list, const Context& context);

}

#endif
28 changes: 6 additions & 22 deletions src/domain/pddl/parser/structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "effects.hpp"
#include "parameters.hpp"
#include "common.hpp"
#include "reference_utils.hpp"

#include "../../../../include/loki/domain/pddl/exceptions.hpp"
#include "../../../../include/loki/domain/pddl/action.hpp"
Expand All @@ -45,18 +46,9 @@ pddl::Action parse(const domain::ast::Action& node, Context& context) {
context.scopes.open_scope();
auto name = parse(node.action_symbol.name);
auto parameter_list = boost::apply_visitor(ParameterListVisitor(context), node.typed_list_of_variables);
for (const auto& parameter : parameter_list) {
context.references.track(parameter->get_variable());
}
track_variable_references(parameter_list, context);
auto [condition, effect] = parse(node.action_body, context);
// Check references
for (const auto& parameter : parameter_list) {
if (context.references.exists(parameter->get_variable())) {
const auto& [variable, position, error_handler] = context.scopes.get<pddl::VariableImpl>(parameter->get_variable()->get_name()).value();
throw UnusedVariableError(variable->get_name(), error_handler(position.value(), ""));
}
}

test_variable_references(parameter_list, context);
context.scopes.close_scope();
const auto action = context.factories.actions.get_or_create<pddl::ActionImpl>(name, parameter_list, condition, effect);
context.positions.push_back(action, node);
Expand All @@ -70,19 +62,11 @@ pddl::DerivedPredicate parse(const domain::ast::DerivedPredicate& node, Context&
context.references.untrack(pddl::RequirementEnum::DERIVED_PREDICATES);
context.scopes.open_scope();
auto parameter_list = boost::apply_visitor(ParameterListVisitor(context), node.typed_list_of_variables);
for (const auto& parameter : parameter_list) {
context.references.track(parameter->get_variable());
}
track_variable_references(parameter_list, context);
auto condition = parse(node.goal_descriptor, context);
const auto derived_predicate = context.factories.derived_predicates.get_or_create<pddl::DerivedPredicateImpl>(parameter_list, condition);
// Check references
for (const auto& parameter : parameter_list) {
if (context.references.exists(parameter->get_variable())) {
const auto& [variable, position, error_handler] = context.scopes.get<pddl::VariableImpl>(parameter->get_variable()->get_name()).value();
throw UnusedVariableError(variable->get_name(), error_handler(position.value(), ""));
}
}

test_variable_references(parameter_list, context);

context.scopes.close_scope();
context.positions.push_back(derived_predicate, node);
return derived_predicate;
Expand Down
Loading

0 comments on commit 2f30b73

Please sign in to comment.