From 54e866946968b2bfbc54a55415f86757631ff129 Mon Sep 17 00:00:00 2001 From: SimonDold <48084373+SimonDold@users.noreply.github.com> Date: Fri, 5 Jul 2024 23:12:40 +0200 Subject: [PATCH 01/28] [issue1082] Use Options objects only in Features (#218) * We changed the constructor signature of the features to expect the parameters as in the CLI instead of the options object. * Additionally, we added a test to the GitHub actions to confirm that the CLI feature and the cpp class constructor have the same parameters (names and order). --- .github/workflows/ubuntu.yml | 4 +- misc/tests/test-parameters.py | 232 ++++++++++++++++++ misc/tox.ini | 7 +- src/search/CMakeLists.txt | 1 + .../additive_cartesian_heuristic.cc | 53 ++-- .../additive_cartesian_heuristic.h | 10 +- .../cartesian_abstractions/cost_saturation.cc | 4 +- .../cartesian_abstractions/cost_saturation.h | 4 +- .../cartesian_abstractions/split_selector.cc | 5 +- .../subtask_generators.cc | 62 +++-- .../subtask_generators.h | 8 +- src/search/cartesian_abstractions/utils.cc | 11 - src/search/cartesian_abstractions/utils.h | 3 - .../cartesian_abstractions/utils_landmarks.cc | 12 +- src/search/evaluator.cc | 27 +- src/search/evaluator.h | 14 +- src/search/evaluators/combining_evaluator.cc | 25 +- src/search/evaluators/combining_evaluator.h | 11 +- src/search/evaluators/const_evaluator.cc | 20 +- src/search/evaluators/const_evaluator.h | 6 +- src/search/evaluators/g_evaluator.cc | 19 +- src/search/evaluators/g_evaluator.h | 4 +- src/search/evaluators/max_evaluator.cc | 26 +- src/search/evaluators/max_evaluator.h | 5 +- src/search/evaluators/pref_evaluator.cc | 21 +- src/search/evaluators/pref_evaluator.h | 4 +- src/search/evaluators/sum_evaluator.cc | 26 +- src/search/evaluators/sum_evaluator.h | 5 +- src/search/evaluators/weighted_evaluator.cc | 29 ++- src/search/evaluators/weighted_evaluator.h | 7 +- src/search/heuristic.cc | 27 +- src/search/heuristic.h | 12 +- src/search/heuristics/additive_heuristic.cc | 21 +- src/search/heuristics/additive_heuristic.h | 5 +- .../heuristics/blind_search_heuristic.cc | 25 +- .../heuristics/blind_search_heuristic.h | 6 +- src/search/heuristics/cea_heuristic.cc | 18 +- src/search/heuristics/cea_heuristic.h | 5 +- src/search/heuristics/cg_cache.cc | 3 - src/search/heuristics/cg_cache.h | 1 - src/search/heuristics/cg_heuristic.cc | 25 +- src/search/heuristics/cg_heuristic.h | 7 +- src/search/heuristics/ff_heuristic.cc | 20 +- src/search/heuristics/ff_heuristic.h | 5 +- src/search/heuristics/goal_count_heuristic.cc | 19 +- src/search/heuristics/goal_count_heuristic.h | 5 +- src/search/heuristics/hm_heuristic.cc | 23 +- src/search/heuristics/hm_heuristic.h | 5 +- src/search/heuristics/lm_cut_heuristic.cc | 22 +- src/search/heuristics/lm_cut_heuristic.h | 6 +- src/search/heuristics/lm_cut_landmarks.cc | 3 - src/search/heuristics/lm_cut_landmarks.h | 1 - src/search/heuristics/max_heuristic.cc | 19 +- src/search/heuristics/max_heuristic.h | 5 +- src/search/heuristics/relaxation_heuristic.cc | 6 +- src/search/heuristics/relaxation_heuristic.h | 5 +- .../landmark_cost_partitioning_heuristic.cc | 60 +++-- .../landmark_cost_partitioning_heuristic.h | 17 +- src/search/landmarks/landmark_factory.cc | 25 +- src/search/landmarks/landmark_factory.h | 8 +- src/search/landmarks/landmark_factory_h_m.cc | 27 +- src/search/landmarks/landmark_factory_h_m.h | 3 +- .../landmarks/landmark_factory_merged.cc | 22 +- .../landmarks/landmark_factory_merged.h | 4 +- .../landmark_factory_reasonable_orders_hps.cc | 19 +- .../landmark_factory_reasonable_orders_hps.h | 4 +- .../landmarks/landmark_factory_relaxation.cc | 5 +- .../landmarks/landmark_factory_relaxation.h | 2 +- .../landmarks/landmark_factory_rpg_exhaust.cc | 20 +- .../landmarks/landmark_factory_rpg_exhaust.h | 3 +- .../landmarks/landmark_factory_rpg_sasp.cc | 27 +- .../landmarks/landmark_factory_rpg_sasp.h | 4 +- .../landmarks/landmark_factory_zhu_givan.cc | 20 +- .../landmarks/landmark_factory_zhu_givan.h | 3 +- src/search/landmarks/landmark_heuristic.cc | 46 ++-- src/search/landmarks/landmark_heuristic.h | 23 +- .../landmarks/landmark_sum_heuristic.cc | 28 ++- src/search/landmarks/landmark_sum_heuristic.h | 7 +- src/search/lp/lp_solver.cc | 5 + src/search/lp/lp_solver.h | 3 + .../merge_and_shrink/label_reduction.cc | 36 ++- src/search/merge_and_shrink/label_reduction.h | 5 +- .../merge_and_shrink_algorithm.cc | 59 ++++- .../merge_and_shrink_algorithm.h | 18 +- .../merge_and_shrink_heuristic.cc | 35 ++- .../merge_and_shrink_heuristic.h | 15 +- .../merge_scoring_function_dfp.cc | 3 +- .../merge_scoring_function_dfp.h | 1 - .../merge_scoring_function_goal_relevance.cc | 3 +- .../merge_scoring_function_goal_relevance.h | 1 - .../merge_scoring_function_miasm.cc | 30 ++- .../merge_scoring_function_miasm.h | 6 +- .../merge_scoring_function_single_random.cc | 19 +- .../merge_scoring_function_single_random.h | 7 +- .../merge_scoring_function_total_order.cc | 29 ++- .../merge_scoring_function_total_order.h | 6 +- .../merge_selector_score_based_filtering.cc | 18 +- .../merge_selector_score_based_filtering.h | 4 +- .../merge_strategy_factory.cc | 10 +- .../merge_and_shrink/merge_strategy_factory.h | 5 +- .../merge_strategy_factory_precomputed.cc | 18 +- .../merge_strategy_factory_precomputed.h | 5 +- .../merge_strategy_factory_sccs.cc | 40 +-- .../merge_strategy_factory_sccs.h | 7 +- .../merge_strategy_factory_stateless.cc | 19 +- .../merge_strategy_factory_stateless.h | 5 +- .../merge_and_shrink/merge_tree_factory.cc | 19 +- .../merge_and_shrink/merge_tree_factory.h | 10 +- .../merge_tree_factory_linear.cc | 25 +- .../merge_tree_factory_linear.h | 5 +- .../merge_and_shrink/shrink_bisimulation.cc | 18 +- .../merge_and_shrink/shrink_bisimulation.h | 7 +- .../merge_and_shrink/shrink_bucket_based.cc | 18 +- .../merge_and_shrink/shrink_bucket_based.h | 9 +- src/search/merge_and_shrink/shrink_fh.cc | 23 +- src/search/merge_and_shrink/shrink_fh.h | 3 +- src/search/merge_and_shrink/shrink_random.cc | 17 +- src/search/merge_and_shrink/shrink_random.h | 7 +- src/search/open_list_factory.cc | 14 ++ src/search/open_list_factory.h | 7 + .../open_lists/alternation_open_list.cc | 39 +-- src/search/open_lists/alternation_open_list.h | 9 +- src/search/open_lists/best_first_open_list.cc | 37 +-- src/search/open_lists/best_first_open_list.h | 9 +- .../open_lists/epsilon_greedy_open_list.cc | 51 ++-- .../open_lists/epsilon_greedy_open_list.h | 12 +- src/search/open_lists/pareto_open_list.cc | 51 ++-- src/search/open_lists/pareto_open_list.h | 12 +- .../open_lists/tiebreaking_open_list.cc | 49 ++-- src/search/open_lists/tiebreaking_open_list.h | 11 +- src/search/open_lists/type_based_open_list.cc | 42 ++-- src/search/open_lists/type_based_open_list.h | 10 +- src/search/operator_cost.cc | 9 +- src/search/operator_cost.h | 8 +- .../delete_relaxation_if_constraints.cc | 18 +- .../delete_relaxation_if_constraints.h | 3 +- .../operator_counting/lm_cut_constraints.cc | 3 +- .../operator_counting_heuristic.cc | 36 +-- .../operator_counting_heuristic.h | 10 +- .../operator_counting/pho_constraints.cc | 17 +- .../operator_counting/pho_constraints.h | 3 +- .../state_equation_constraints.cc | 14 +- .../state_equation_constraints.h | 2 +- src/search/pdbs/canonical_pdbs_heuristic.cc | 43 +++- src/search/pdbs/canonical_pdbs_heuristic.h | 11 +- src/search/pdbs/cegar.cc | 4 + src/search/pdbs/cegar.h | 3 + .../pattern_collection_generator_combo.cc | 21 +- .../pdbs/pattern_collection_generator_combo.h | 7 +- ...ern_collection_generator_disjoint_cegar.cc | 34 ++- ...tern_collection_generator_disjoint_cegar.h | 5 +- .../pattern_collection_generator_genetic.cc | 37 ++- .../pattern_collection_generator_genetic.h | 5 +- ...ttern_collection_generator_hillclimbing.cc | 89 ++++--- ...attern_collection_generator_hillclimbing.h | 12 +- .../pattern_collection_generator_manual.cc | 20 +- .../pattern_collection_generator_manual.h | 5 +- .../pattern_collection_generator_multiple.cc | 45 +++- .../pattern_collection_generator_multiple.h | 12 +- ...ern_collection_generator_multiple_cegar.cc | 29 ++- ...tern_collection_generator_multiple_cegar.h | 8 +- ...rn_collection_generator_multiple_random.cc | 28 ++- ...ern_collection_generator_multiple_random.h | 7 +- ...pattern_collection_generator_systematic.cc | 23 +- .../pattern_collection_generator_systematic.h | 4 +- src/search/pdbs/pattern_generator.cc | 14 +- src/search/pdbs/pattern_generator.h | 6 +- src/search/pdbs/pattern_generator_cegar.cc | 31 ++- src/search/pdbs/pattern_generator_cegar.h | 4 +- src/search/pdbs/pattern_generator_greedy.cc | 18 +- src/search/pdbs/pattern_generator_greedy.h | 3 +- src/search/pdbs/pattern_generator_manual.cc | 18 +- src/search/pdbs/pattern_generator_manual.h | 4 +- src/search/pdbs/pattern_generator_random.cc | 31 ++- src/search/pdbs/pattern_generator_random.h | 4 +- src/search/pdbs/pdb_heuristic.cc | 31 ++- src/search/pdbs/pdb_heuristic.h | 16 +- src/search/pdbs/random_pattern.cc | 5 + src/search/pdbs/random_pattern.h | 4 + src/search/pdbs/zero_one_pdbs_heuristic.cc | 31 ++- src/search/pdbs/zero_one_pdbs_heuristic.h | 8 +- src/search/plugins/plugin.h | 18 ++ .../diverse_potential_heuristics.cc | 47 +++- .../potentials/diverse_potential_heuristics.h | 6 +- src/search/potentials/potential_heuristic.cc | 8 +- src/search/potentials/potential_heuristic.h | 7 +- .../potentials/potential_max_heuristic.cc | 7 +- .../potentials/potential_max_heuristic.h | 9 +- src/search/potentials/potential_optimizer.cc | 10 +- src/search/potentials/potential_optimizer.h | 4 +- .../sample_based_potential_heuristics.cc | 42 +++- .../potentials/single_potential_heuristics.cc | 52 +++- src/search/potentials/util.cc | 17 +- src/search/potentials/util.h | 12 +- src/search/pruning/limited_pruning.cc | 27 +- src/search/pruning/limited_pruning.h | 6 +- src/search/pruning/null_pruning_method.cc | 14 +- src/search/pruning/null_pruning_method.h | 2 +- src/search/pruning/stubborn_sets.cc | 4 +- src/search/pruning/stubborn_sets.h | 2 +- .../pruning/stubborn_sets_action_centric.cc | 5 +- .../pruning/stubborn_sets_action_centric.h | 2 +- .../pruning/stubborn_sets_atom_centric.cc | 23 +- .../pruning/stubborn_sets_atom_centric.h | 5 +- src/search/pruning/stubborn_sets_ec.cc | 14 +- src/search/pruning/stubborn_sets_ec.h | 2 +- src/search/pruning/stubborn_sets_simple.cc | 14 +- src/search/pruning/stubborn_sets_simple.h | 2 +- src/search/pruning_method.cc | 9 +- src/search/pruning_method.h | 4 +- src/search/search_algorithm.cc | 96 ++++++-- src/search/search_algorithm.h | 29 ++- src/search/search_algorithms/eager_search.cc | 45 +++- src/search/search_algorithms/eager_search.h | 18 +- .../enforced_hill_climbing_search.cc | 71 +++--- .../enforced_hill_climbing_search.h | 8 +- .../search_algorithms/iterated_search.cc | 5 +- .../search_algorithms/iterated_search.h | 2 +- src/search/search_algorithms/lazy_search.cc | 27 +- src/search/search_algorithms/lazy_search.h | 14 +- src/search/search_algorithms/plugin_astar.cc | 26 +- src/search/search_algorithms/plugin_eager.cc | 18 +- .../search_algorithms/plugin_eager_greedy.cc | 40 +-- .../search_algorithms/plugin_eager_wastar.cc | 26 +- src/search/search_algorithms/plugin_lazy.cc | 27 +- .../search_algorithms/plugin_lazy_greedy.cc | 56 +++-- .../search_algorithms/plugin_lazy_wastar.cc | 35 ++- src/search/search_algorithms/search_common.cc | 112 +++------ src/search/search_algorithms/search_common.h | 38 ++- src/search/tasks/cost_adapted_task.cc | 14 +- src/search/tasks/root_task.cc | 3 +- src/search/utils/logging.cc | 17 +- src/search/utils/logging.h | 5 +- src/search/utils/rng_options.cc | 11 +- src/search/utils/rng_options.h | 13 +- src/search/utils/tuples.h | 31 +++ 236 files changed, 3009 insertions(+), 1222 deletions(-) create mode 100644 misc/tests/test-parameters.py create mode 100644 src/search/utils/tuples.h diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index a6a5d45ee..00df07d29 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -98,7 +98,7 @@ jobs: # only need to archive that one. if: ${{ matrix.version.run_tox_tests }} run: | - files_to_archive="fast-downward.py driver misc builds/debug/bin/ \ + files_to_archive="fast-downward.py driver misc src builds/debug/bin/ \ builds/release/bin/ ${SOPLEX_LIB} ${SOPLEX_INCLUDE}" if [[ ! -z "${CPLEX_URL}" ]]; then files_to_archive="${files_to_archive} ${CPLEX_LIB}" @@ -169,7 +169,7 @@ jobs: - name: Run driver, translator and search tests run: | cd misc/ - tox -e driver,translator,search,autodoc + tox -e driver,translator,search,parameters,autodoc - name: Run CPLEX tests if: ${{ env.CPLEX_URL != 0 }} diff --git a/misc/tests/test-parameters.py b/misc/tests/test-parameters.py new file mode 100644 index 000000000..803516bf3 --- /dev/null +++ b/misc/tests/test-parameters.py @@ -0,0 +1,232 @@ +#! /usr/bin/env python3 + +HELP = """\ +Check that parameters for the command line features match the parameters + of the C++ constructors. Use txt2tags to compare the parameters + mentioned in the wiki to the parameters in the corresponding .cc file. +""" + +import argparse +from pathlib import Path +import re +import subprocess +import sys + +DIR = Path(__file__).resolve().parent +REPO = DIR.parents[1] +SRC_DIR = REPO / "src" + +SHORT_HANDS = [ + "ipdb", # cpdbs(hillclimbing()) + "astar", # eager(tiebreaking([sum([g(), h]), h], + # unsafe_pruning=false), reopen_closed=true, + # f_eval=sum([g(), h])) + "lazy_greedy", # lazy(alt([single(h1), single(h1, + # pref_only=true), single(h2), single(h2, + # pref_only=true)], boost=100), preferred=h2) + "lazy_wastar", # lazy(single(sum([g(), weight(eval1, 2)])), + # reopen_closed=true) + "eager_greedy", # eager(single(eval1)) + "eager_wastar", # See corresponding notes for + # "(Weighted) A* search (lazy)" + # eager_wastar(evals=[eval1, eval2],prefered=pref1, + # reopen_closed=rc1, boost=boo1, w=w1, + # pruning=pru1, cost_type=ct1, bound = bou1, + # max_time=mt1, verbosity=v1) + # Is equivalent to: + # eager(open = alt([single(sum([g(), weight(eval1, w1)])), + # single(sum([g(), weight(eval2, w1)]))], + # boost=boo1), + # reopen_closed=rc1, f_eval = , + # preferred = pref1, pruning = pru1, + # cost_type=ct1, bound=bou1, max_time=mt1, + # verbosity=v1) +] + +TEMPORARY_EXCEPTIONS = [ + "iterated", + "eager", + "sample_based_potentials", + "initial_state_potential", + "all_states_potential", + "diverse_potentials", +] + +PERMANENT_EXCEPTIONS = [ + "adapt_costs" +] + +CREATE_COMPONENT_REGEX = r"(^|\s|\W)create_component" +NON_C_VAR_PATTERN = r'[^a-zA-Z0-9_]' # overapproximation + +def extract_cpp_class(input_string): + pattern = r'<(.*?)>' + match = re.search(pattern, input_string) + assert match + return match.group(1) + +def get_constructor_parameters(cc_file, class_name): + with open(cc_file, 'r') as file: + content = file.read() + pattern = rf'{class_name}\s*\((.*?)\)' + match = re.search(pattern, content, re.DOTALL) + if match: + parameters = match.group(1).strip() + return (True, parameters) + else: + return (False, "") + +def matching(opening, closing): + return ((opening, closing) == ('(', ')') or + (opening, closing) == ('[', ']')) + +def extract_feature_parameter_list(feature_name): + s = str(subprocess.run(["./../../builds/release/bin/downward", + "--help", "--txt2tags", + "{}".format(feature_name)], + stdout=subprocess.PIPE).stdout) + position = s.find(feature_name + "(") + assert position != -1 + s = s[position + len(feature_name) + 1::] # start after the first '(' + stack = ['('] + result = [] + for c in s: + if c == '(' or c == "[": + stack.append(c) + elif c == ')' or c == "]": + assert matching(stack[-1], c) + stack.pop() + if not stack: + break + if len(stack) == 1: # not within nested parenthesis/brackets + result.append(c) + result = ''.join(result) + result = re.sub(r'=.*?,', ',', result + ",").split() + result = [re.sub(',', '', word) for word in result] + return result + +def extract_feature_name_and_cpp_class(cc_file, cc_files, cwd, num): + source_without_comments = subprocess.check_output( + ["gcc", "-fpreprocessed", "-dD", "-E", cc_file]).decode("utf-8") + name_pattern = r'TypedFeature\("([^"]*)"\)' + class_pattern = r'TypedFeature<(.*?)> {' + feature_names = [] + class_names = [] + feature_error_msgs = [] + class_error_msgs = [] + for line in source_without_comments.splitlines(): + if re.search(name_pattern, line): + feature_name = re.search(name_pattern, line).group(1) + feature_error_msg = "feature_name: " + feature_name + "\n" + feature_names.append(feature_name) + feature_error_msgs.append(feature_error_msg) + if re.search(class_pattern, line): + feature_class = re.search(class_pattern, line).group(1) + class_name = feature_class.split()[-1].split("::")[-1] + class_error_msg = "class_name: " + class_name + "\n" + class_names.append(class_name) + class_error_msgs.append(class_error_msg) + return (feature_names[num], class_names[num], + feature_error_msgs[num] + class_error_msgs[num]) + +def get_cpp_class_parameters( + class_name, cc_file, cc_files, cwd): + found_in_file, parameters = get_constructor_parameters( + cc_file, class_name) + if not found_in_file: + # check in all files + for cc_file2 in cc_files: + found_in_file, parameters = get_constructor_parameters( + cc_file2, class_name) + if found_in_file: + break + if found_in_file: + parameters = parameters.replace("\n", "") + "," + parameters = parameters.split() + parameters = [word for word in parameters if "," in word] + parameters = [re.sub(NON_C_VAR_PATTERN, '', word) + for word in parameters] + return parameters + else: + # assume default constructor + return [''] + +def get_create_component_lines(cc_file): + source_without_comments = subprocess.check_output( + ["gcc", "-fpreprocessed", "-dD", "-E", cc_file]).decode("utf-8") + lines = [] + for line in source_without_comments.splitlines(): + if re.search(CREATE_COMPONENT_REGEX, line): + lines.append(line.strip()) + return lines + +def compare_component_parameters(cc_file, cc_files, cwd): + error_msg = "" + create_component_lines = get_create_component_lines(cc_file) + if create_component_lines: + for i, create_component_line in enumerate( + create_component_lines): + (feature_name, cpp_class, extracted_error_msg) = ( + extract_feature_name_and_cpp_class( + cc_file, cc_files, cwd, i)) + feature_parameters = extract_feature_parameter_list( + feature_name) + cpp_class_parameters = get_cpp_class_parameters( + cpp_class, cc_file, cc_files, cwd) + if feature_name in SHORT_HANDS: + print(f"feature_name '{feature_name}' is ignored" + " because it is marked as shorthand") + elif feature_name in PERMANENT_EXCEPTIONS: + print(f"feature_name '{feature_name}' is ignored" + " because it is marked as PERMANENT_EXCEPTION") + elif feature_name in TEMPORARY_EXCEPTIONS: + print(f"feature_name '{feature_name}' is ignored" + " because it is marked as TEMPORARY_EXCEPTION") + elif feature_parameters != cpp_class_parameters: + error_msg += ("\n\n=====================================\n" + + "= = = " + cpp_class + " = = =\n" + + extracted_error_msg + "\n" + + "== FEATURE PARAMETERS '" + + feature_name + "' ==\n" + + str(feature_parameters) + "\n" + + "== CLASS PARAMETERS '" + + cpp_class + "' ==\n" + + str(cpp_class_parameters) + "\n") + if not len(feature_parameters) == len(cpp_class_parameters): + error_msg += "Wrong sizes\n" + for i in range(min(len(feature_parameters), + len(cpp_class_parameters))): + if feature_parameters[i] != cpp_class_parameters[i]: + error_msg += (feature_parameters[i] + + " =/= " + cpp_class_parameters[i] + "\n") + error_msg += cc_file + "\n" + return error_msg + +def error_check(cc_files, cwd): + errors = [] + for cc_file in cc_files: + error_msg = compare_component_parameters( + cc_file, cc_files, cwd) + if error_msg: + errors.append(error_msg) + if errors: + print("############### ERRORS ##########################") + for error in errors: + print(error) + sys.exit(1) + +def main(): + """ + Currently, we only check that the parameters in the Constructor in + the .cc file matches the parameters for the CLI. + """ + search_dir = SRC_DIR / "search" + cc_files = [str(file) for file in search_dir.rglob('*.cc') + if file.is_file()] + assert len(cc_files) > 0 + print("Checking Component Parameters of" + " {} *.cc files".format(len(cc_files))) + return error_check(cc_files, cwd=DIR) == 0 + +if __name__ == "__main__": + main() diff --git a/misc/tox.ini b/misc/tox.ini index f003517ac..67f96da0e 100644 --- a/misc/tox.ini +++ b/misc/tox.ini @@ -5,7 +5,7 @@ # the translator tests it is sufficient to build the 'translate' configuration. [tox] -envlist = build, driver, translator, search, style, autodoc, clang-tidy +envlist = build, driver, translator, parameters, search, style, autodoc, clang-tidy basepython = python3 skip_missing_interpreters = true skipsdist = true @@ -39,6 +39,11 @@ changedir = {toxinidir}/tests/ commands = python test-translator.py benchmarks/ all +[testenv:parameters] +changedir = {toxinidir}/tests/ +commands = + python test-parameters.py + [testenv:search] changedir = {toxinidir}/tests/ deps = diff --git a/src/search/CMakeLists.txt b/src/search/CMakeLists.txt index 7d8177ba1..6adeaa767 100644 --- a/src/search/CMakeLists.txt +++ b/src/search/CMakeLists.txt @@ -146,6 +146,7 @@ create_fast_downward_library( utils/system_unix utils/system_windows utils/timer + utils/tuples CORE_LIBRARY ) # On Linux, find the rt library for clock_gettime(). diff --git a/src/search/cartesian_abstractions/additive_cartesian_heuristic.cc b/src/search/cartesian_abstractions/additive_cartesian_heuristic.cc index 00a53b311..dc39aa00e 100644 --- a/src/search/cartesian_abstractions/additive_cartesian_heuristic.cc +++ b/src/search/cartesian_abstractions/additive_cartesian_heuristic.cc @@ -17,31 +17,32 @@ using namespace std; namespace cartesian_abstractions { static vector generate_heuristic_functions( - const plugins::Options &opts, utils::LogProxy &log) { + const vector> &subtask_generators, + int max_states, int max_transitions, double max_time, + PickSplit pick, bool use_general_costs, int random_seed, + const shared_ptr &transform, utils::LogProxy &log) { if (log.is_at_least_normal()) { log << "Initializing additive Cartesian heuristic..." << endl; } - vector> subtask_generators = - opts.get_list>("subtasks"); shared_ptr rng = - utils::parse_rng_from_options(opts); + utils::get_rng(random_seed); CostSaturation cost_saturation( - subtask_generators, - opts.get("max_states"), - opts.get("max_transitions"), - opts.get("max_time"), - opts.get("use_general_costs"), - opts.get("pick"), - *rng, - log); - return cost_saturation.generate_heuristic_functions( - opts.get>("transform")); + subtask_generators, max_states, max_transitions, max_time, pick, + use_general_costs, *rng, log); + return cost_saturation.generate_heuristic_functions(transform); } AdditiveCartesianHeuristic::AdditiveCartesianHeuristic( - const plugins::Options &opts) - : Heuristic(opts), - heuristic_functions(generate_heuristic_functions(opts, log)) { + const vector> &subtasks, + int max_states, int max_transitions, double max_time, + PickSplit pick, bool use_general_costs, int random_seed, + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : Heuristic(transform, cache_estimates, description, verbosity), + heuristic_functions(generate_heuristic_functions( + subtasks, max_states, max_transitions, + max_time, pick, use_general_costs, + random_seed, transform, log)) { } int AdditiveCartesianHeuristic::compute_heuristic(const State &ancestor_state) { @@ -125,8 +126,8 @@ class AdditiveCartesianHeuristicFeature "use_general_costs", "allow negative costs in cost partitioning", "true"); - Heuristic::add_options_to_feature(*this); - utils::add_rng_options(*this); + utils::add_rng_options_to_feature(*this); + add_heuristic_options_to_feature(*this, "cegar"); document_language_support("action costs", "supported"); document_language_support("conditional effects", "not supported"); @@ -137,6 +138,20 @@ class AdditiveCartesianHeuristicFeature document_property("safe", "yes"); document_property("preferred operators", "no"); } + + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get_list>("subtasks"), + opts.get("max_states"), + opts.get("max_transitions"), + opts.get("max_time"), + opts.get("pick"), + opts.get("use_general_costs"), + utils::get_rng_arguments_from_options(opts), + get_heuristic_arguments_from_options(opts)); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/cartesian_abstractions/additive_cartesian_heuristic.h b/src/search/cartesian_abstractions/additive_cartesian_heuristic.h index 11725c44e..ed3e66b62 100644 --- a/src/search/cartesian_abstractions/additive_cartesian_heuristic.h +++ b/src/search/cartesian_abstractions/additive_cartesian_heuristic.h @@ -7,6 +7,8 @@ namespace cartesian_abstractions { class CartesianHeuristicFunction; +class SubtaskGenerator; +enum class PickSplit; /* Store CartesianHeuristicFunctions and compute overall heuristic by @@ -19,7 +21,13 @@ class AdditiveCartesianHeuristic : public Heuristic { virtual int compute_heuristic(const State &ancestor_state) override; public: - explicit AdditiveCartesianHeuristic(const plugins::Options &opts); + explicit AdditiveCartesianHeuristic( + const std::vector> &subtasks, + int max_states, int max_transitions, double max_time, + PickSplit pick, bool use_general_costs, int random_seed, + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); }; } diff --git a/src/search/cartesian_abstractions/cost_saturation.cc b/src/search/cartesian_abstractions/cost_saturation.cc index 50fc870a8..ef0081674 100644 --- a/src/search/cartesian_abstractions/cost_saturation.cc +++ b/src/search/cartesian_abstractions/cost_saturation.cc @@ -86,16 +86,16 @@ CostSaturation::CostSaturation( int max_states, int max_non_looping_transitions, double max_time, - bool use_general_costs, PickSplit pick_split, + bool use_general_costs, utils::RandomNumberGenerator &rng, utils::LogProxy &log) : subtask_generators(subtask_generators), max_states(max_states), max_non_looping_transitions(max_non_looping_transitions), max_time(max_time), - use_general_costs(use_general_costs), pick_split(pick_split), + use_general_costs(use_general_costs), rng(rng), log(log), num_abstractions(0), diff --git a/src/search/cartesian_abstractions/cost_saturation.h b/src/search/cartesian_abstractions/cost_saturation.h index 93f662963..f64ef3537 100644 --- a/src/search/cartesian_abstractions/cost_saturation.h +++ b/src/search/cartesian_abstractions/cost_saturation.h @@ -30,8 +30,8 @@ class CostSaturation { const int max_states; const int max_non_looping_transitions; const double max_time; - const bool use_general_costs; const PickSplit pick_split; + const bool use_general_costs; utils::RandomNumberGenerator &rng; utils::LogProxy &log; @@ -58,8 +58,8 @@ class CostSaturation { int max_states, int max_non_looping_transitions, double max_time, - bool use_general_costs, PickSplit pick_split, + bool use_general_costs, utils::RandomNumberGenerator &rng, utils::LogProxy &log); diff --git a/src/search/cartesian_abstractions/split_selector.cc b/src/search/cartesian_abstractions/split_selector.cc index 69fe4f519..ec6a7baa1 100644 --- a/src/search/cartesian_abstractions/split_selector.cc +++ b/src/search/cartesian_abstractions/split_selector.cc @@ -22,7 +22,10 @@ SplitSelector::SplitSelector( task_proxy(*task), pick(pick) { if (pick == PickSplit::MIN_HADD || pick == PickSplit::MAX_HADD) { - additive_heuristic = create_additive_heuristic(task); + additive_heuristic = + utils::make_unique_ptr( + task, false, "h^add within CEGAR abstractions", + utils::Verbosity::SILENT); additive_heuristic->compute_heuristic_for_cegar( task_proxy.get_initial_state()); } diff --git a/src/search/cartesian_abstractions/subtask_generators.cc b/src/search/cartesian_abstractions/subtask_generators.cc index 2a852392f..8de4f82fc 100644 --- a/src/search/cartesian_abstractions/subtask_generators.cc +++ b/src/search/cartesian_abstractions/subtask_generators.cc @@ -34,7 +34,9 @@ class SortFactsByIncreasingHaddValues { public: explicit SortFactsByIncreasingHaddValues( const shared_ptr &task) - : hadd(create_additive_heuristic(task)) { + : hadd(utils::make_unique_ptr( + task, false, "h^add within CEGAR abstractions", + utils::Verbosity::SILENT)) { TaskProxy task_proxy(*task); hadd->compute_heuristic_for_cegar(task_proxy.get_initial_state()); } @@ -94,8 +96,8 @@ static Facts filter_and_order_facts( } -TaskDuplicator::TaskDuplicator(const plugins::Options &opts) - : num_copies(opts.get("copies")) { +TaskDuplicator::TaskDuplicator(int copies) + : num_copies(copies) { } SharedTasks TaskDuplicator::get_subtasks( @@ -108,9 +110,9 @@ SharedTasks TaskDuplicator::get_subtasks( return subtasks; } -GoalDecomposition::GoalDecomposition(const plugins::Options &opts) - : fact_order(opts.get("order")), - rng(utils::parse_rng_from_options(opts)) { +GoalDecomposition::GoalDecomposition(FactOrder order, int random_seed) + : fact_order(order), + rng(utils::get_rng(random_seed)) { } SharedTasks GoalDecomposition::get_subtasks( @@ -128,10 +130,11 @@ SharedTasks GoalDecomposition::get_subtasks( } -LandmarkDecomposition::LandmarkDecomposition(const plugins::Options &opts) - : fact_order(opts.get("order")), - combine_facts(opts.get("combine_facts")), - rng(utils::parse_rng_from_options(opts)) { +LandmarkDecomposition::LandmarkDecomposition( + FactOrder order, int random_seed, bool combine_facts) + : fact_order(order), + combine_facts(combine_facts), + rng(utils::get_rng(random_seed)) { } shared_ptr LandmarkDecomposition::build_domain_abstracted_task( @@ -173,10 +176,17 @@ static void add_fact_order_option(plugins::Feature &feature) { "order", "ordering of goal or landmark facts", "hadd_down"); - utils::add_rng_options(feature); + utils::add_rng_options_to_feature(feature); } -class TaskDuplicatorFeature : public plugins::TypedFeature { +static tuple get_fact_order_arguments_from_options( + const plugins::Options &opts) { + return tuple_cat(make_tuple(opts.get("order")), + utils::get_rng_arguments_from_options(opts)); +} + +class TaskDuplicatorFeature + : public plugins::TypedFeature { public: TaskDuplicatorFeature() : TypedFeature("original") { add_option( @@ -185,21 +195,37 @@ class TaskDuplicatorFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get("copies")); + } }; static plugins::FeaturePlugin _plugin_original; -class GoalDecompositionFeature : public plugins::TypedFeature { +class GoalDecompositionFeature + : public plugins::TypedFeature { public: GoalDecompositionFeature() : TypedFeature("goals") { add_fact_order_option(*this); } + + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_fact_order_arguments_from_options(opts)); + } }; static plugins::FeaturePlugin _plugin_goals; -class LandmarkDecompositionFeature : public plugins::TypedFeature { +class LandmarkDecompositionFeature + : public plugins::TypedFeature { public: LandmarkDecompositionFeature() : TypedFeature("landmarks") { add_fact_order_option(*this); @@ -208,6 +234,14 @@ class LandmarkDecompositionFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_fact_order_arguments_from_options(opts), + opts.get("combine_facts")); + } }; static plugins::FeaturePlugin _plugin_landmarks; diff --git a/src/search/cartesian_abstractions/subtask_generators.h b/src/search/cartesian_abstractions/subtask_generators.h index de68ceb60..7f9a0b980 100644 --- a/src/search/cartesian_abstractions/subtask_generators.h +++ b/src/search/cartesian_abstractions/subtask_generators.h @@ -51,7 +51,7 @@ class TaskDuplicator : public SubtaskGenerator { int num_copies; public: - explicit TaskDuplicator(const plugins::Options &opts); + explicit TaskDuplicator(int copies); virtual SharedTasks get_subtasks( const std::shared_ptr &task, @@ -67,7 +67,7 @@ class GoalDecomposition : public SubtaskGenerator { std::shared_ptr rng; public: - explicit GoalDecomposition(const plugins::Options &opts); + explicit GoalDecomposition(FactOrder order, int random_seed); virtual SharedTasks get_subtasks( const std::shared_ptr &task, @@ -92,7 +92,9 @@ class LandmarkDecomposition : public SubtaskGenerator { const FactPair &fact) const; public: - explicit LandmarkDecomposition(const plugins::Options &opts); + explicit LandmarkDecomposition(FactOrder order, + int random_seed, + bool combine_facts); virtual SharedTasks get_subtasks( const std::shared_ptr &task, diff --git a/src/search/cartesian_abstractions/utils.cc b/src/search/cartesian_abstractions/utils.cc index 4fa9c0a4a..d489b7e0f 100644 --- a/src/search/cartesian_abstractions/utils.cc +++ b/src/search/cartesian_abstractions/utils.cc @@ -1,8 +1,6 @@ #include "utils.h" -#include "../plugins/plugin.h" #include "../heuristics/additive_heuristic.h" -#include "../task_utils/task_properties.h" #include "../utils/logging.h" #include "../utils/memory.h" @@ -13,15 +11,6 @@ using namespace std; namespace cartesian_abstractions { -unique_ptr create_additive_heuristic( - const shared_ptr &task) { - plugins::Options opts; - opts.set>("transform", task); - opts.set("cache_estimates", false); - opts.set("verbosity", utils::Verbosity::SILENT); - return utils::make_unique_ptr(opts); -} - static bool operator_applicable( const OperatorProxy &op, const utils::HashSet &facts) { for (FactProxy precondition : op.get_preconditions()) { diff --git a/src/search/cartesian_abstractions/utils.h b/src/search/cartesian_abstractions/utils.h index 2ee4089fc..34e4ec27b 100644 --- a/src/search/cartesian_abstractions/utils.h +++ b/src/search/cartesian_abstractions/utils.h @@ -17,9 +17,6 @@ class AdditiveHeuristic; } namespace cartesian_abstractions { -extern std::unique_ptr -create_additive_heuristic(const std::shared_ptr &task); - /* The set of relaxed-reachable facts is the possibly-before set of facts that can be reached in the delete-relaxation before 'fact' is reached the first diff --git a/src/search/cartesian_abstractions/utils_landmarks.cc b/src/search/cartesian_abstractions/utils_landmarks.cc index c14fa8e94..cb2f174fc 100644 --- a/src/search/cartesian_abstractions/utils_landmarks.cc +++ b/src/search/cartesian_abstractions/utils_landmarks.cc @@ -19,14 +19,10 @@ static FactPair get_fact(const Landmark &landmark) { return landmark.facts[0]; } -shared_ptr get_landmark_graph(const shared_ptr &task) { - plugins::Options hm_opts; - hm_opts.set("m", 1); - hm_opts.set("only_causal_landmarks", false); - hm_opts.set("conjunctive_landmarks", false); - hm_opts.set("use_orders", true); - hm_opts.set("verbosity", utils::Verbosity::SILENT); - LandmarkFactoryHM lm_graph_factory(hm_opts); +shared_ptr get_landmark_graph( + const shared_ptr &task) { + LandmarkFactoryHM lm_graph_factory( + 1, false, true, utils::Verbosity::SILENT); return lm_graph_factory.compute_lm_graph(task); } diff --git a/src/search/evaluator.cc b/src/search/evaluator.cc index c97e1712f..6fb87c64c 100644 --- a/src/search/evaluator.cc +++ b/src/search/evaluator.cc @@ -9,15 +9,15 @@ using namespace std; -Evaluator::Evaluator(const plugins::Options &opts, - bool use_for_reporting_minima, - bool use_for_boosting, - bool use_for_counting_evaluations) - : description(opts.get_unparsed_config()), +Evaluator::Evaluator( + bool use_for_reporting_minima, bool use_for_boosting, + bool use_for_counting_evaluations, const string &description, + utils::Verbosity verbosity) + : description(description), use_for_reporting_minima(use_for_reporting_minima), use_for_boosting(use_for_boosting), use_for_counting_evaluations(use_for_counting_evaluations), - log(utils::get_log_from_options(opts)) { + log(utils::get_log_for_verbosity(verbosity)) { } bool Evaluator::dead_ends_are_reliable() const { @@ -74,10 +74,23 @@ int Evaluator::get_cached_estimate(const State &) const { ABORT("Called get_cached_estimate when estimate is not cached."); } -void add_evaluator_options_to_feature(plugins::Feature &feature) { +void add_evaluator_options_to_feature( + plugins::Feature &feature, const string &description) { + feature.add_option( + "description", + "description used to identify evaluator in logs", + "\"" + description + "\""); utils::add_log_options_to_feature(feature); } +tuple get_evaluator_arguments_from_options( + const plugins::Options &opts) { + return tuple_cat( + make_tuple(opts.get("description")), + utils::get_log_arguments_from_options(opts) + ); +} + static class EvaluatorCategoryPlugin : public plugins::TypedCategoryPlugin { public: EvaluatorCategoryPlugin() : TypedCategoryPlugin("Evaluator") { diff --git a/src/search/evaluator.h b/src/search/evaluator.h index be085c5e8..43e30d008 100644 --- a/src/search/evaluator.h +++ b/src/search/evaluator.h @@ -22,11 +22,10 @@ class Evaluator { protected: mutable utils::LogProxy log; public: - explicit Evaluator( - const plugins::Options &opts, - bool use_for_reporting_minima = false, - bool use_for_boosting = false, - bool use_for_counting_evaluations = false); + Evaluator( + bool use_for_reporting_minima, bool use_for_boosting, + bool use_for_counting_evaluations, + const std::string &description, utils::Verbosity verbosity); virtual ~Evaluator() = default; /* @@ -100,6 +99,9 @@ class Evaluator { virtual int get_cached_estimate(const State &state) const; }; -extern void add_evaluator_options_to_feature(plugins::Feature &feature); +extern void add_evaluator_options_to_feature( + plugins::Feature &feature, const std::string &description); +extern std::tuple +get_evaluator_arguments_from_options(const plugins::Options &opts); #endif diff --git a/src/search/evaluators/combining_evaluator.cc b/src/search/evaluators/combining_evaluator.cc index fadadaa7f..650962435 100644 --- a/src/search/evaluators/combining_evaluator.cc +++ b/src/search/evaluators/combining_evaluator.cc @@ -8,18 +8,17 @@ using namespace std; namespace combining_evaluator { -CombiningEvaluator::CombiningEvaluator(const plugins::Options &opts) - : Evaluator(opts), - subevaluators(opts.get_list>("evals")) { +CombiningEvaluator::CombiningEvaluator( + const vector> &evals, + const string &description, utils::Verbosity verbosity) + : Evaluator(false, false, false, description, verbosity), + subevaluators(evals) { all_dead_ends_are_reliable = true; for (const shared_ptr &subevaluator : subevaluators) if (!subevaluator->dead_ends_are_reliable()) all_dead_ends_are_reliable = false; } -CombiningEvaluator::~CombiningEvaluator() { -} - bool CombiningEvaluator::dead_ends_are_reliable() const { return all_dead_ends_are_reliable; } @@ -52,9 +51,19 @@ void CombiningEvaluator::get_path_dependent_evaluators( for (auto &subevaluator : subevaluators) subevaluator->get_path_dependent_evaluators(evals); } -void add_combining_evaluator_options_to_feature(plugins::Feature &feature) { +void add_combining_evaluator_options_to_feature( + plugins::Feature &feature, const string &description) { feature.add_list_option>( "evals", "at least one evaluator"); - add_evaluator_options_to_feature(feature); + add_evaluator_options_to_feature(feature, description); +} + +tuple>, const string, utils::Verbosity> +get_combining_evaluator_arguments_from_options( + const plugins::Options &opts) { + return tuple_cat( + make_tuple(opts.get_list>("evals")), + get_evaluator_arguments_from_options(opts) + ); } } diff --git a/src/search/evaluators/combining_evaluator.h b/src/search/evaluators/combining_evaluator.h index 7aa1d86f5..d6fd893ff 100644 --- a/src/search/evaluators/combining_evaluator.h +++ b/src/search/evaluators/combining_evaluator.h @@ -19,8 +19,9 @@ class CombiningEvaluator : public Evaluator { protected: virtual int combine_values(const std::vector &values) = 0; public: - explicit CombiningEvaluator(const plugins::Options &opts); - virtual ~CombiningEvaluator() override; + CombiningEvaluator( + const std::vector> &evals, + const std::string &description, utils::Verbosity verbosity); /* Note: dead_ends_are_reliable() is a state-independent method, so @@ -44,7 +45,11 @@ class CombiningEvaluator : public Evaluator { }; extern void add_combining_evaluator_options_to_feature( - plugins::Feature &feature); + plugins::Feature &feature, const std::string &description); +extern std::tuple>, + const std::string, utils::Verbosity> +get_combining_evaluator_arguments_from_options( + const plugins::Options &opts); } #endif diff --git a/src/search/evaluators/const_evaluator.cc b/src/search/evaluators/const_evaluator.cc index 4f990ab80..49088cb29 100644 --- a/src/search/evaluators/const_evaluator.cc +++ b/src/search/evaluators/const_evaluator.cc @@ -5,8 +5,10 @@ using namespace std; namespace const_evaluator { -ConstEvaluator::ConstEvaluator(const plugins::Options &opts) - : Evaluator(opts), value(opts.get("value")) { +ConstEvaluator::ConstEvaluator( + int value, const string &description, utils::Verbosity verbosity) + : Evaluator(false, false, false, description, verbosity), + value(value) { } EvaluationResult ConstEvaluator::compute_result(EvaluationContext &) { @@ -15,7 +17,8 @@ EvaluationResult ConstEvaluator::compute_result(EvaluationContext &) { return result; } -class ConstEvaluatorFeature : public plugins::TypedFeature { +class ConstEvaluatorFeature + : public plugins::TypedFeature { public: ConstEvaluatorFeature() : TypedFeature("const") { document_subcategory("evaluators_basic"); @@ -27,7 +30,16 @@ class ConstEvaluatorFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get("value"), + get_evaluator_arguments_from_options(opts) + ); } }; diff --git a/src/search/evaluators/const_evaluator.h b/src/search/evaluators/const_evaluator.h index dbcfc5d1c..19523c021 100644 --- a/src/search/evaluators/const_evaluator.h +++ b/src/search/evaluators/const_evaluator.h @@ -16,10 +16,12 @@ class ConstEvaluator : public Evaluator { EvaluationContext &eval_context) override; public: - explicit ConstEvaluator(const plugins::Options &opts); + ConstEvaluator( + int value, + const std::string &description, + utils::Verbosity verbosity); virtual void get_path_dependent_evaluators( std::set &) override {} - virtual ~ConstEvaluator() override = default; }; } diff --git a/src/search/evaluators/g_evaluator.cc b/src/search/evaluators/g_evaluator.cc index a2745f8ac..6b4fecce6 100644 --- a/src/search/evaluators/g_evaluator.cc +++ b/src/search/evaluators/g_evaluator.cc @@ -7,24 +7,35 @@ using namespace std; namespace g_evaluator { -GEvaluator::GEvaluator(const plugins::Options &opts) - : Evaluator(opts) { +GEvaluator::GEvaluator(const string &description, + utils::Verbosity verbosity) + : Evaluator(false, false, false, description, verbosity) { } + EvaluationResult GEvaluator::compute_result(EvaluationContext &eval_context) { EvaluationResult result; result.set_evaluator_value(eval_context.get_g_value()); return result; } -class GEvaluatorFeature : public plugins::TypedFeature { +class GEvaluatorFeature + : public plugins::TypedFeature { public: GEvaluatorFeature() : TypedFeature("g") { document_subcategory("evaluators_basic"); document_title("g-value evaluator"); document_synopsis( "Returns the g-value (path cost) of the search node."); - add_evaluator_options_to_feature(*this); + add_evaluator_options_to_feature(*this, "g"); + } + + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_evaluator_arguments_from_options(opts) + ); } }; diff --git a/src/search/evaluators/g_evaluator.h b/src/search/evaluators/g_evaluator.h index b1b0b2790..70919d26a 100644 --- a/src/search/evaluators/g_evaluator.h +++ b/src/search/evaluators/g_evaluator.h @@ -6,8 +6,8 @@ namespace g_evaluator { class GEvaluator : public Evaluator { public: - explicit GEvaluator(const plugins::Options &opts); - virtual ~GEvaluator() override = default; + GEvaluator( + const std::string &description, utils::Verbosity verbosity); virtual EvaluationResult compute_result( EvaluationContext &eval_context) override; diff --git a/src/search/evaluators/max_evaluator.cc b/src/search/evaluators/max_evaluator.cc index 441b806ac..5f6e7fae6 100644 --- a/src/search/evaluators/max_evaluator.cc +++ b/src/search/evaluators/max_evaluator.cc @@ -7,11 +7,10 @@ using namespace std; namespace max_evaluator { -MaxEvaluator::MaxEvaluator(const plugins::Options &opts) - : CombiningEvaluator(opts) { -} - -MaxEvaluator::~MaxEvaluator() { +MaxEvaluator::MaxEvaluator( + const vector> &evals, + const string &description, utils::Verbosity verbosity) + : CombiningEvaluator(evals, description, verbosity) { } int MaxEvaluator::combine_values(const vector &values) { @@ -23,19 +22,26 @@ int MaxEvaluator::combine_values(const vector &values) { return result; } -class MaxEvaluatorFeature : public plugins::TypedFeature { +class MaxEvaluatorFeature + : public plugins::TypedFeature { public: MaxEvaluatorFeature() : TypedFeature("max") { document_subcategory("evaluators_basic"); document_title("Max evaluator"); document_synopsis( "Calculates the maximum of the sub-evaluators."); - combining_evaluator::add_combining_evaluator_options_to_feature(*this); + combining_evaluator::add_combining_evaluator_options_to_feature( + *this, "max"); } - virtual shared_ptr create_component(const plugins::Options &options, const utils::Context &context) const override { - plugins::verify_list_non_empty>(context, options, "evals"); - return make_shared(options); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &context) const override { + plugins::verify_list_non_empty>( + context, opts, "evals"); + return plugins::make_shared_from_arg_tuples( + combining_evaluator::get_combining_evaluator_arguments_from_options( + opts)); } }; diff --git a/src/search/evaluators/max_evaluator.h b/src/search/evaluators/max_evaluator.h index f634d0210..6af8a0c02 100644 --- a/src/search/evaluators/max_evaluator.h +++ b/src/search/evaluators/max_evaluator.h @@ -15,8 +15,9 @@ class MaxEvaluator : public combining_evaluator::CombiningEvaluator { virtual int combine_values(const std::vector &values) override; public: - explicit MaxEvaluator(const plugins::Options &opts); - virtual ~MaxEvaluator() override; + MaxEvaluator( + const std::vector> &evals, + const std::string &description, utils::Verbosity verbosity); }; } diff --git a/src/search/evaluators/pref_evaluator.cc b/src/search/evaluators/pref_evaluator.cc index 0b2edfdcd..eb986550a 100644 --- a/src/search/evaluators/pref_evaluator.cc +++ b/src/search/evaluators/pref_evaluator.cc @@ -7,11 +7,9 @@ using namespace std; namespace pref_evaluator { -PrefEvaluator::PrefEvaluator(const plugins::Options &opts) - : Evaluator(opts) { -} - -PrefEvaluator::~PrefEvaluator() { +PrefEvaluator::PrefEvaluator( + const string &description, utils::Verbosity verbosity) + : Evaluator(false, false, false, description, verbosity) { } EvaluationResult PrefEvaluator::compute_result( @@ -24,14 +22,23 @@ EvaluationResult PrefEvaluator::compute_result( return result; } -class PrefEvaluatorFeature : public plugins::TypedFeature { +class PrefEvaluatorFeature + : public plugins::TypedFeature { public: PrefEvaluatorFeature() : TypedFeature("pref") { document_subcategory("evaluators_basic"); document_title("Preference evaluator"); document_synopsis("Returns 0 if preferred is true and 1 otherwise."); - add_evaluator_options_to_feature(*this); + add_evaluator_options_to_feature(*this, "pref"); + } + + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_evaluator_arguments_from_options(opts) + ); } }; diff --git a/src/search/evaluators/pref_evaluator.h b/src/search/evaluators/pref_evaluator.h index fda1fa4dd..68a9dbce6 100644 --- a/src/search/evaluators/pref_evaluator.h +++ b/src/search/evaluators/pref_evaluator.h @@ -9,8 +9,8 @@ namespace pref_evaluator { class PrefEvaluator : public Evaluator { public: - explicit PrefEvaluator(const plugins::Options &opts); - virtual ~PrefEvaluator() override; + PrefEvaluator( + const std::string &description, utils::Verbosity verbosity); virtual EvaluationResult compute_result( EvaluationContext &eval_context) override; diff --git a/src/search/evaluators/sum_evaluator.cc b/src/search/evaluators/sum_evaluator.cc index 94c0e405b..b413afd8a 100644 --- a/src/search/evaluators/sum_evaluator.cc +++ b/src/search/evaluators/sum_evaluator.cc @@ -7,11 +7,10 @@ using namespace std; namespace sum_evaluator { -SumEvaluator::SumEvaluator(const plugins::Options &opts) - : CombiningEvaluator(opts) { -} - -SumEvaluator::~SumEvaluator() { +SumEvaluator::SumEvaluator( + const vector> &evals, + const string &description, utils::Verbosity verbosity) + : CombiningEvaluator(evals, description, verbosity) { } int SumEvaluator::combine_values(const vector &values) { @@ -24,19 +23,26 @@ int SumEvaluator::combine_values(const vector &values) { return result; } -class SumEvaluatorFeature : public plugins::TypedFeature { +class SumEvaluatorFeature + : public plugins::TypedFeature { public: SumEvaluatorFeature() : TypedFeature("sum") { document_subcategory("evaluators_basic"); document_title("Sum evaluator"); document_synopsis("Calculates the sum of the sub-evaluators."); - combining_evaluator::add_combining_evaluator_options_to_feature(*this); + combining_evaluator::add_combining_evaluator_options_to_feature( + *this, "sum"); } - virtual shared_ptr create_component(const plugins::Options &options, const utils::Context &context) const override { - plugins::verify_list_non_empty>(context, options, "evals"); - return make_shared(options); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &context) const override { + plugins::verify_list_non_empty>( + context, opts, "evals"); + return plugins::make_shared_from_arg_tuples( + combining_evaluator::get_combining_evaluator_arguments_from_options( + opts)); } }; diff --git a/src/search/evaluators/sum_evaluator.h b/src/search/evaluators/sum_evaluator.h index 57c5fb915..011101e70 100644 --- a/src/search/evaluators/sum_evaluator.h +++ b/src/search/evaluators/sum_evaluator.h @@ -15,8 +15,9 @@ class SumEvaluator : public combining_evaluator::CombiningEvaluator { protected: virtual int combine_values(const std::vector &values) override; public: - explicit SumEvaluator(const plugins::Options &opts); - virtual ~SumEvaluator() override; + SumEvaluator( + const std::vector> &evals, + const std::string &description, utils::Verbosity verbosity); }; } diff --git a/src/search/evaluators/weighted_evaluator.cc b/src/search/evaluators/weighted_evaluator.cc index 31a362e80..7c48b9ac1 100644 --- a/src/search/evaluators/weighted_evaluator.cc +++ b/src/search/evaluators/weighted_evaluator.cc @@ -10,14 +10,14 @@ using namespace std; namespace weighted_evaluator { -WeightedEvaluator::WeightedEvaluator(const plugins::Options &opts) - : Evaluator(opts), - evaluator(opts.get>("eval")), - w(opts.get("weight")) { +WeightedEvaluator::WeightedEvaluator( + const shared_ptr &eval, int weight, + const string &description, utils::Verbosity verbosity) + : Evaluator(false, false, false, description, verbosity), + evaluator(eval), + weight(weight) { } -WeightedEvaluator::~WeightedEvaluator() { -} bool WeightedEvaluator::dead_ends_are_reliable() const { return evaluator->dead_ends_are_reliable(); @@ -30,7 +30,7 @@ EvaluationResult WeightedEvaluator::compute_result( int value = eval_context.get_evaluator_value_or_infinity(evaluator.get()); if (value != EvaluationResult::INFTY) { // TODO: Check for overflow? - value *= w; + value *= weight; } result.set_evaluator_value(value); return result; @@ -40,7 +40,8 @@ void WeightedEvaluator::get_path_dependent_evaluators(set &evals) { evaluator->get_path_dependent_evaluators(evals); } -class WeightedEvaluatorFeature : public plugins::TypedFeature { +class WeightedEvaluatorFeature + : public plugins::TypedFeature { public: WeightedEvaluatorFeature() : TypedFeature("weight") { document_subcategory("evaluators_basic"); @@ -50,7 +51,17 @@ class WeightedEvaluatorFeature : public plugins::TypedFeature>("eval", "evaluator"); add_option("weight", "weight"); - add_evaluator_options_to_feature(*this); + add_evaluator_options_to_feature(*this, "weight"); + } + + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get>("eval"), + opts.get("weight"), + get_evaluator_arguments_from_options(opts) + ); } }; diff --git a/src/search/evaluators/weighted_evaluator.h b/src/search/evaluators/weighted_evaluator.h index 80c96f020..edfdf769b 100644 --- a/src/search/evaluators/weighted_evaluator.h +++ b/src/search/evaluators/weighted_evaluator.h @@ -12,11 +12,12 @@ class Options; namespace weighted_evaluator { class WeightedEvaluator : public Evaluator { std::shared_ptr evaluator; - int w; + int weight; public: - explicit WeightedEvaluator(const plugins::Options &opts); - virtual ~WeightedEvaluator() override; + WeightedEvaluator( + const std::shared_ptr &eval, int weight, + const std::string &description, utils::Verbosity verbosity); virtual bool dead_ends_are_reliable() const override; virtual EvaluationResult compute_result( diff --git a/src/search/heuristic.cc b/src/search/heuristic.cc index 9030deb64..251910fec 100644 --- a/src/search/heuristic.cc +++ b/src/search/heuristic.cc @@ -13,12 +13,14 @@ #include using namespace std; - -Heuristic::Heuristic(const plugins::Options &opts) - : Evaluator(opts, true, true, true), +Heuristic::Heuristic( + const shared_ptr &transform, + bool cache_estimates, const string &description, + utils::Verbosity verbosity) + : Evaluator(true, true, true, description, verbosity), heuristic_cache(HEntry(NO_VALUE, true)), //TODO: is true really a good idea here? - cache_evaluator_values(opts.get("cache_estimates")), - task(opts.get>("transform")), + cache_evaluator_values(cache_estimates), + task(transform), task_proxy(*task) { } @@ -33,14 +35,25 @@ State Heuristic::convert_ancestor_state(const State &ancestor_state) const { return task_proxy.convert_ancestor_state(ancestor_state); } -void Heuristic::add_options_to_feature(plugins::Feature &feature) { - add_evaluator_options_to_feature(feature); +void add_heuristic_options_to_feature( + plugins::Feature &feature, const string &description) { feature.add_option>( "transform", "Optional task transformation for the heuristic." " Currently, adapt_costs() and no_transform() are available.", "no_transform()"); feature.add_option("cache_estimates", "cache heuristic estimates", "true"); + add_evaluator_options_to_feature(feature, description); +} + +tuple, bool, string, utils::Verbosity> +get_heuristic_arguments_from_options(const plugins::Options &opts) { + return tuple_cat( + make_tuple( + opts.get>("transform"), + opts.get("cache_estimates") + ), + get_evaluator_arguments_from_options(opts)); } EvaluationResult Heuristic::compute_result(EvaluationContext &eval_context) { diff --git a/src/search/heuristic.h b/src/search/heuristic.h index 12e077085..379f31b73 100644 --- a/src/search/heuristic.h +++ b/src/search/heuristic.h @@ -73,15 +73,16 @@ class Heuristic : public Evaluator { State convert_ancestor_state(const State &ancestor_state) const; public: - explicit Heuristic(const plugins::Options &opts); + Heuristic( + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); virtual ~Heuristic() override; virtual void get_path_dependent_evaluators( std::set & /*evals*/) override { } - static void add_options_to_feature(plugins::Feature &feature); - virtual EvaluationResult compute_result( EvaluationContext &eval_context) override; @@ -90,4 +91,9 @@ class Heuristic : public Evaluator { virtual int get_cached_estimate(const State &state) const override; }; +extern void add_heuristic_options_to_feature( + plugins::Feature &feature, const std::string &description); +extern std::tuple< + std::shared_ptr, bool, std::string, utils::Verbosity> +get_heuristic_arguments_from_options(const plugins::Options &opts); #endif diff --git a/src/search/heuristics/additive_heuristic.cc b/src/search/heuristics/additive_heuristic.cc index b12ac3c87..c86abc432 100644 --- a/src/search/heuristics/additive_heuristic.cc +++ b/src/search/heuristics/additive_heuristic.cc @@ -13,9 +13,11 @@ using namespace std; namespace additive_heuristic { const int AdditiveHeuristic::MAX_COST_VALUE; -// construction and destruction -AdditiveHeuristic::AdditiveHeuristic(const plugins::Options &opts) - : RelaxationHeuristic(opts), +AdditiveHeuristic::AdditiveHeuristic( + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : RelaxationHeuristic( + transform, cache_estimates, description, verbosity), did_write_overflow_warning(false) { if (log.is_at_least_normal()) { log << "Initializing additive heuristic..." << endl; @@ -145,12 +147,13 @@ void AdditiveHeuristic::compute_heuristic_for_cegar(const State &state) { compute_heuristic(state); } -class AdditiveHeuristicFeature : public plugins::TypedFeature { +class AdditiveHeuristicFeature + : public plugins::TypedFeature { public: AdditiveHeuristicFeature() : TypedFeature("add") { document_title("Additive heuristic"); - Heuristic::add_options_to_feature(*this); + add_heuristic_options_to_feature(*this, "add"); document_language_support("action costs", "supported"); document_language_support("conditional effects", "supported"); @@ -165,6 +168,14 @@ class AdditiveHeuristicFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_heuristic_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/heuristics/additive_heuristic.h b/src/search/heuristics/additive_heuristic.h index fe2d5d42b..ae3096125 100644 --- a/src/search/heuristics/additive_heuristic.h +++ b/src/search/heuristics/additive_heuristic.h @@ -65,7 +65,10 @@ class AdditiveHeuristic : public relaxation_heuristic::RelaxationHeuristic { // Common part of h^add and h^ff computation. int compute_add_and_ff(const State &state); public: - explicit AdditiveHeuristic(const plugins::Options &opts); + AdditiveHeuristic( + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); /* TODO: The two methods below are temporarily needed for the CEGAR diff --git a/src/search/heuristics/blind_search_heuristic.cc b/src/search/heuristics/blind_search_heuristic.cc index b528551c5..36fe4fb59 100644 --- a/src/search/heuristics/blind_search_heuristic.cc +++ b/src/search/heuristics/blind_search_heuristic.cc @@ -12,17 +12,17 @@ using namespace std; namespace blind_search_heuristic { -BlindSearchHeuristic::BlindSearchHeuristic(const plugins::Options &opts) - : Heuristic(opts), - min_operator_cost(task_properties::get_min_operator_cost(task_proxy)) { +BlindSearchHeuristic::BlindSearchHeuristic( + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : Heuristic(transform, cache_estimates, description, verbosity), + min_operator_cost( + task_properties::get_min_operator_cost(task_proxy)) { if (log.is_at_least_normal()) { log << "Initializing blind search heuristic..." << endl; } } -BlindSearchHeuristic::~BlindSearchHeuristic() { -} - int BlindSearchHeuristic::compute_heuristic(const State &ancestor_state) { State state = convert_ancestor_state(ancestor_state); if (task_properties::is_goal_state(task_proxy, state)) @@ -31,7 +31,8 @@ int BlindSearchHeuristic::compute_heuristic(const State &ancestor_state) { return min_operator_cost; } -class BlindSearchHeuristicFeature : public plugins::TypedFeature { +class BlindSearchHeuristicFeature + : public plugins::TypedFeature { public: BlindSearchHeuristicFeature() : TypedFeature("blind") { document_title("Blind heuristic"); @@ -39,7 +40,7 @@ class BlindSearchHeuristicFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_heuristic_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/heuristics/blind_search_heuristic.h b/src/search/heuristics/blind_search_heuristic.h index 44f668f45..9b88be004 100644 --- a/src/search/heuristics/blind_search_heuristic.h +++ b/src/search/heuristics/blind_search_heuristic.h @@ -9,8 +9,10 @@ class BlindSearchHeuristic : public Heuristic { protected: virtual int compute_heuristic(const State &ancestor_state) override; public: - BlindSearchHeuristic(const plugins::Options &opts); - ~BlindSearchHeuristic(); + BlindSearchHeuristic( + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); }; } diff --git a/src/search/heuristics/cea_heuristic.cc b/src/search/heuristics/cea_heuristic.cc index da05b84f7..4233cd4c4 100644 --- a/src/search/heuristics/cea_heuristic.cc +++ b/src/search/heuristics/cea_heuristic.cc @@ -409,8 +409,9 @@ int ContextEnhancedAdditiveHeuristic::compute_heuristic( } ContextEnhancedAdditiveHeuristic::ContextEnhancedAdditiveHeuristic( - const plugins::Options &opts) - : Heuristic(opts), + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : Heuristic(transform, cache_estimates, description, verbosity), min_action_cost(task_properties::get_min_operator_cost(task_proxy)) { if (log.is_at_least_normal()) { log << "Initializing context-enhanced additive heuristic..." << endl; @@ -443,12 +444,13 @@ bool ContextEnhancedAdditiveHeuristic::dead_ends_are_reliable() const { return false; } -class ContextEnhancedAdditiveHeuristicFeature : public plugins::TypedFeature { +class ContextEnhancedAdditiveHeuristicFeature + : public plugins::TypedFeature { public: ContextEnhancedAdditiveHeuristicFeature() : TypedFeature("cea") { document_title("Context-enhanced additive heuristic"); - Heuristic::add_options_to_feature(*this); + add_heuristic_options_to_feature(*this, "cea"); document_language_support("action costs", "supported"); document_language_support("conditional effects", "supported"); @@ -463,6 +465,14 @@ class ContextEnhancedAdditiveHeuristicFeature : public plugins::TypedFeature + create_component(const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_heuristic_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/heuristics/cea_heuristic.h b/src/search/heuristics/cea_heuristic.h index 703376027..5b1547c71 100644 --- a/src/search/heuristics/cea_heuristic.h +++ b/src/search/heuristics/cea_heuristic.h @@ -50,7 +50,10 @@ class ContextEnhancedAdditiveHeuristic : public Heuristic { protected: virtual int compute_heuristic(const State &ancestor_state) override; public: - explicit ContextEnhancedAdditiveHeuristic(const plugins::Options &opts); + ContextEnhancedAdditiveHeuristic( + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); ~ContextEnhancedAdditiveHeuristic(); virtual bool dead_ends_are_reliable() const override; }; diff --git a/src/search/heuristics/cg_cache.cc b/src/search/heuristics/cg_cache.cc index 822940e66..2479136d3 100644 --- a/src/search/heuristics/cg_cache.cc +++ b/src/search/heuristics/cg_cache.cc @@ -71,9 +71,6 @@ CGCache::CGCache(const TaskProxy &task_proxy, int max_cache_size, utils::LogProx } } -CGCache::~CGCache() { -} - int CGCache::compute_required_cache_size( int var_id, const vector &depends_on, int max_cache_size) const { /* diff --git a/src/search/heuristics/cg_cache.h b/src/search/heuristics/cg_cache.h index 06ca91d1e..87e43da76 100644 --- a/src/search/heuristics/cg_cache.h +++ b/src/search/heuristics/cg_cache.h @@ -27,7 +27,6 @@ class CGCache { static const int NOT_COMPUTED = -2; CGCache(const TaskProxy &task_proxy, int max_cache_size, utils::LogProxy &log); - ~CGCache(); bool is_cached(int var) const { return !cache[var].empty(); diff --git a/src/search/heuristics/cg_heuristic.cc b/src/search/heuristics/cg_heuristic.cc index 6b491451c..5da1623e9 100644 --- a/src/search/heuristics/cg_heuristic.cc +++ b/src/search/heuristics/cg_heuristic.cc @@ -16,8 +16,11 @@ using namespace std; using namespace domain_transition_graph; namespace cg_heuristic { -CGHeuristic::CGHeuristic(const plugins::Options &opts) - : Heuristic(opts), +CGHeuristic::CGHeuristic( + int max_cache_size, const shared_ptr &transform, + bool cache_estimates, const string &description, + utils::Verbosity verbosity) + : Heuristic(transform, cache_estimates, description, verbosity), cache_hits(0), cache_misses(0), helpful_transition_extraction_counter(0), @@ -26,7 +29,6 @@ CGHeuristic::CGHeuristic(const plugins::Options &opts) log << "Initializing causal graph heuristic..." << endl; } - int max_cache_size = opts.get("max_cache_size"); if (max_cache_size > 0) cache = utils::make_unique_ptr(task_proxy, max_cache_size, log); @@ -41,9 +43,6 @@ CGHeuristic::CGHeuristic(const plugins::Options &opts) transition_graphs = factory.build_dtgs(); } -CGHeuristic::~CGHeuristic() { -} - bool CGHeuristic::dead_ends_are_reliable() const { return false; } @@ -285,7 +284,8 @@ void CGHeuristic::mark_helpful_transitions(const State &state, } } -class CGHeuristicFeature : public plugins::TypedFeature { +class CGHeuristicFeature + : public plugins::TypedFeature { public: CGHeuristicFeature() : TypedFeature("cg") { document_title("Causal graph heuristic"); @@ -295,7 +295,7 @@ class CGHeuristicFeature : public plugins::TypedFeature "maximum number of cached entries per variable (set to 0 to disable cache)", "1000000", plugins::Bounds("0", "infinity")); - Heuristic::add_options_to_feature(*this); + add_heuristic_options_to_feature(*this, "cg"); document_language_support("action costs", "supported"); document_language_support("conditional effects", "supported"); @@ -310,6 +310,15 @@ class CGHeuristicFeature : public plugins::TypedFeature document_property("safe", "no"); document_property("preferred operators", "yes"); } + + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get("max_cache_size"), + get_heuristic_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/heuristics/cg_heuristic.h b/src/search/heuristics/cg_heuristic.h index 3ec02aedb..c7d738f63 100644 --- a/src/search/heuristics/cg_heuristic.h +++ b/src/search/heuristics/cg_heuristic.h @@ -43,8 +43,11 @@ class CGHeuristic : public Heuristic { protected: virtual int compute_heuristic(const State &ancestor_state) override; public: - explicit CGHeuristic(const plugins::Options &opts); - ~CGHeuristic(); + explicit CGHeuristic( + int max_cache_size, + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); virtual bool dead_ends_are_reliable() const override; }; } diff --git a/src/search/heuristics/ff_heuristic.cc b/src/search/heuristics/ff_heuristic.cc index c782fee62..683d11802 100644 --- a/src/search/heuristics/ff_heuristic.cc +++ b/src/search/heuristics/ff_heuristic.cc @@ -11,8 +11,11 @@ using namespace std; namespace ff_heuristic { // construction and destruction -FFHeuristic::FFHeuristic(const plugins::Options &opts) - : AdditiveHeuristic(opts), +FFHeuristic::FFHeuristic( + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : AdditiveHeuristic( + transform, cache_estimates, description, verbosity), relaxed_plan(task_proxy.get_operators().size(), false) { if (log.is_at_least_normal()) { log << "Initializing FF heuristic..." << endl; @@ -69,12 +72,13 @@ int FFHeuristic::compute_heuristic(const State &ancestor_state) { return h_ff; } -class FFHeuristicFeature : public plugins::TypedFeature { +class FFHeuristicFeature + : public plugins::TypedFeature { public: FFHeuristicFeature() : TypedFeature("ff") { document_title("FF heuristic"); - Heuristic::add_options_to_feature(*this); + add_heuristic_options_to_feature(*this, "ff"); document_language_support("action costs", "supported"); document_language_support("conditional effects", "supported"); @@ -89,6 +93,14 @@ class FFHeuristicFeature : public plugins::TypedFeature document_property("safe", "yes for tasks without axioms"); document_property("preferred operators", "yes"); } + + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_heuristic_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/heuristics/ff_heuristic.h b/src/search/heuristics/ff_heuristic.h index 5a7cad2ec..86fa6a389 100644 --- a/src/search/heuristics/ff_heuristic.h +++ b/src/search/heuristics/ff_heuristic.h @@ -32,7 +32,10 @@ class FFHeuristic : public additive_heuristic::AdditiveHeuristic { protected: virtual int compute_heuristic(const State &ancestor_state) override; public: - explicit FFHeuristic(const plugins::Options &opts); + FFHeuristic( + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); }; } diff --git a/src/search/heuristics/goal_count_heuristic.cc b/src/search/heuristics/goal_count_heuristic.cc index e93f0b7ec..38fd55f21 100644 --- a/src/search/heuristics/goal_count_heuristic.cc +++ b/src/search/heuristics/goal_count_heuristic.cc @@ -8,8 +8,10 @@ using namespace std; namespace goal_count_heuristic { -GoalCountHeuristic::GoalCountHeuristic(const plugins::Options &opts) - : Heuristic(opts) { +GoalCountHeuristic::GoalCountHeuristic( + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : Heuristic(transform, cache_estimates, description, verbosity) { if (log.is_at_least_normal()) { log << "Initializing goal count heuristic..." << endl; } @@ -28,12 +30,13 @@ int GoalCountHeuristic::compute_heuristic(const State &ancestor_state) { return unsatisfied_goal_count; } -class GoalCountHeuristicFeature : public plugins::TypedFeature { +class GoalCountHeuristicFeature + : public plugins::TypedFeature { public: GoalCountHeuristicFeature() : TypedFeature("goalcount") { document_title("Goal count heuristic"); - Heuristic::add_options_to_feature(*this); + add_heuristic_options_to_feature(*this, "goalcount"); document_language_support("action costs", "ignored by design"); document_language_support("conditional effects", "supported"); @@ -44,6 +47,14 @@ class GoalCountHeuristicFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_heuristic_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/heuristics/goal_count_heuristic.h b/src/search/heuristics/goal_count_heuristic.h index 202157a63..cba4b5581 100644 --- a/src/search/heuristics/goal_count_heuristic.h +++ b/src/search/heuristics/goal_count_heuristic.h @@ -8,7 +8,10 @@ class GoalCountHeuristic : public Heuristic { protected: virtual int compute_heuristic(const State &ancestor_state) override; public: - explicit GoalCountHeuristic(const plugins::Options &opts); + GoalCountHeuristic( + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); }; } diff --git a/src/search/heuristics/hm_heuristic.cc b/src/search/heuristics/hm_heuristic.cc index aeb201681..0b6990ad8 100644 --- a/src/search/heuristics/hm_heuristic.cc +++ b/src/search/heuristics/hm_heuristic.cc @@ -12,9 +12,12 @@ using namespace std; namespace hm_heuristic { -HMHeuristic::HMHeuristic(const plugins::Options &opts) - : Heuristic(opts), - m(opts.get("m")), +HMHeuristic::HMHeuristic( + int m, const shared_ptr &transform, + bool cache_estimates, const string &description, + utils::Verbosity verbosity) + : Heuristic(transform, cache_estimates, description, verbosity), + m(m), has_cond_effects(task_properties::has_conditional_effects(task_proxy)), goals(task_properties::get_fact_pairs(task_proxy.get_goals())) { if (log.is_at_least_normal()) { @@ -263,13 +266,14 @@ void HMHeuristic::dump_table() const { } } -class HMHeuristicFeature : public plugins::TypedFeature { +class HMHeuristicFeature + : public plugins::TypedFeature { public: HMHeuristicFeature() : TypedFeature("hm") { document_title("h^m heuristic"); add_option("m", "subset size", "2", plugins::Bounds("1", "infinity")); - Heuristic::add_options_to_feature(*this); + add_heuristic_options_to_feature(*this, "hm"); document_language_support("action costs", "supported"); document_language_support("conditional effects", "ignored"); @@ -286,6 +290,15 @@ class HMHeuristicFeature : public plugins::TypedFeature "yes for tasks without conditional effects or axioms"); document_property("preferred operators", "no"); } + + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get("m"), + get_heuristic_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/heuristics/hm_heuristic.h b/src/search/heuristics/hm_heuristic.h index b092ac256..ad0379b45 100644 --- a/src/search/heuristics/hm_heuristic.h +++ b/src/search/heuristics/hm_heuristic.h @@ -61,7 +61,10 @@ class HMHeuristic : public Heuristic { virtual int compute_heuristic(const State &ancestor_state) override; public: - explicit HMHeuristic(const plugins::Options &opts); + HMHeuristic( + int m, const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); virtual bool dead_ends_are_reliable() const override; }; diff --git a/src/search/heuristics/lm_cut_heuristic.cc b/src/search/heuristics/lm_cut_heuristic.cc index 34e091270..2ad7acdf9 100644 --- a/src/search/heuristics/lm_cut_heuristic.cc +++ b/src/search/heuristics/lm_cut_heuristic.cc @@ -14,17 +14,16 @@ using namespace std; namespace lm_cut_heuristic { -LandmarkCutHeuristic::LandmarkCutHeuristic(const plugins::Options &opts) - : Heuristic(opts), +LandmarkCutHeuristic::LandmarkCutHeuristic( + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : Heuristic(transform, cache_estimates, description, verbosity), landmark_generator(utils::make_unique_ptr(task_proxy)) { if (log.is_at_least_normal()) { log << "Initializing landmark cut heuristic..." << endl; } } -LandmarkCutHeuristic::~LandmarkCutHeuristic() { -} - int LandmarkCutHeuristic::compute_heuristic(const State &ancestor_state) { State state = convert_ancestor_state(ancestor_state); int total_cost = 0; @@ -38,12 +37,13 @@ int LandmarkCutHeuristic::compute_heuristic(const State &ancestor_state) { return total_cost; } -class LandmarkCutHeuristicFeature : public plugins::TypedFeature { +class LandmarkCutHeuristicFeature + : public plugins::TypedFeature { public: LandmarkCutHeuristicFeature() : TypedFeature("lmcut") { document_title("Landmark-cut heuristic"); - Heuristic::add_options_to_feature(*this); + add_heuristic_options_to_feature(*this, "lmcut"); document_language_support("action costs", "supported"); document_language_support("conditional effects", "not supported"); @@ -54,6 +54,14 @@ class LandmarkCutHeuristicFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_heuristic_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/heuristics/lm_cut_heuristic.h b/src/search/heuristics/lm_cut_heuristic.h index d06434bd9..fe57ebba2 100644 --- a/src/search/heuristics/lm_cut_heuristic.h +++ b/src/search/heuristics/lm_cut_heuristic.h @@ -17,8 +17,10 @@ class LandmarkCutHeuristic : public Heuristic { virtual int compute_heuristic(const State &ancestor_state) override; public: - explicit LandmarkCutHeuristic(const plugins::Options &opts); - virtual ~LandmarkCutHeuristic() override; + LandmarkCutHeuristic( + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); }; } diff --git a/src/search/heuristics/lm_cut_landmarks.cc b/src/search/heuristics/lm_cut_landmarks.cc index 8fe81d1bb..ea8c5e650 100644 --- a/src/search/heuristics/lm_cut_landmarks.cc +++ b/src/search/heuristics/lm_cut_landmarks.cc @@ -53,9 +53,6 @@ LandmarkCutLandmarks::LandmarkCutLandmarks(const TaskProxy &task_proxy) { } } -LandmarkCutLandmarks::~LandmarkCutLandmarks() { -} - void LandmarkCutLandmarks::build_relaxed_operator(const OperatorProxy &op) { vector precondition; vector effects; diff --git a/src/search/heuristics/lm_cut_landmarks.h b/src/search/heuristics/lm_cut_landmarks.h index a658876d4..76b967d16 100644 --- a/src/search/heuristics/lm_cut_landmarks.h +++ b/src/search/heuristics/lm_cut_landmarks.h @@ -88,7 +88,6 @@ class LandmarkCutLandmarks { using LandmarkCallback = std::function; LandmarkCutLandmarks(const TaskProxy &task_proxy); - virtual ~LandmarkCutLandmarks(); /* Compute LM-cut landmarks for the given state. diff --git a/src/search/heuristics/max_heuristic.cc b/src/search/heuristics/max_heuristic.cc index 1f0c3cba5..40051ec2f 100644 --- a/src/search/heuristics/max_heuristic.cc +++ b/src/search/heuristics/max_heuristic.cc @@ -22,8 +22,11 @@ namespace max_heuristic { */ // construction and destruction -HSPMaxHeuristic::HSPMaxHeuristic(const plugins::Options &opts) - : RelaxationHeuristic(opts) { +HSPMaxHeuristic::HSPMaxHeuristic( + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : RelaxationHeuristic( + transform, cache_estimates, description, verbosity) { if (log.is_at_least_normal()) { log << "Initializing HSP max heuristic..." << endl; } @@ -98,12 +101,13 @@ int HSPMaxHeuristic::compute_heuristic(const State &ancestor_state) { return total_cost; } -class HSPMaxHeuristicFeature : public plugins::TypedFeature { +class HSPMaxHeuristicFeature + : public plugins::TypedFeature { public: HSPMaxHeuristicFeature() : TypedFeature("hmax") { document_title("Max heuristic"); - Heuristic::add_options_to_feature(*this); + add_heuristic_options_to_feature(*this, "hmax"); document_language_support("action costs", "supported"); document_language_support("conditional effects", "supported"); @@ -118,6 +122,13 @@ class HSPMaxHeuristicFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_heuristic_arguments_from_options(opts)); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/heuristics/max_heuristic.h b/src/search/heuristics/max_heuristic.h index 735179550..9ab122d30 100644 --- a/src/search/heuristics/max_heuristic.h +++ b/src/search/heuristics/max_heuristic.h @@ -33,7 +33,10 @@ class HSPMaxHeuristic : public relaxation_heuristic::RelaxationHeuristic { protected: virtual int compute_heuristic(const State &ancestor_state) override; public: - explicit HSPMaxHeuristic(const plugins::Options &opts); + HSPMaxHeuristic( + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); }; } diff --git a/src/search/heuristics/relaxation_heuristic.cc b/src/search/heuristics/relaxation_heuristic.cc index 21aa2157a..7504a08f5 100644 --- a/src/search/heuristics/relaxation_heuristic.cc +++ b/src/search/heuristics/relaxation_heuristic.cc @@ -35,8 +35,10 @@ UnaryOperator::UnaryOperator( // construction and destruction -RelaxationHeuristic::RelaxationHeuristic(const plugins::Options &opts) - : Heuristic(opts) { +RelaxationHeuristic::RelaxationHeuristic( + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : Heuristic(transform, cache_estimates, description, verbosity) { // Build propositions. propositions.resize(task_properties::get_num_facts(task_proxy)); diff --git a/src/search/heuristics/relaxation_heuristic.h b/src/search/heuristics/relaxation_heuristic.h index 8e50c66f4..be9ea54fe 100644 --- a/src/search/heuristics/relaxation_heuristic.h +++ b/src/search/heuristics/relaxation_heuristic.h @@ -110,7 +110,10 @@ class RelaxationHeuristic : public Heuristic { Proposition *get_proposition(int var, int value); Proposition *get_proposition(const FactProxy &fact); public: - explicit RelaxationHeuristic(const plugins::Options &options); + RelaxationHeuristic( + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); virtual bool dead_ends_are_reliable() const override; }; diff --git a/src/search/landmarks/landmark_cost_partitioning_heuristic.cc b/src/search/landmarks/landmark_cost_partitioning_heuristic.cc index fe446d2c7..a66524ce8 100644 --- a/src/search/landmarks/landmark_cost_partitioning_heuristic.cc +++ b/src/search/landmarks/landmark_cost_partitioning_heuristic.cc @@ -16,27 +16,30 @@ using namespace std; namespace landmarks { LandmarkCostPartitioningHeuristic::LandmarkCostPartitioningHeuristic( - const plugins::Options &opts) - : LandmarkHeuristic(opts) { + const shared_ptr &lm_factory, bool pref, + bool prog_goal, bool prog_gn, bool prog_r, + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity, + CostPartitioningMethod cost_partitioning, bool alm, + lp::LPSolverType lpsolver) + : LandmarkHeuristic( + pref, transform, cache_estimates, description, verbosity) { if (log.is_at_least_normal()) { log << "Initializing landmark cost partitioning heuristic..." << endl; } - check_unsupported_features(opts); - initialize(opts); - set_cost_partitioning_algorithm(opts); + check_unsupported_features(lm_factory); + initialize(lm_factory, prog_goal, prog_gn, prog_r); + set_cost_partitioning_algorithm(cost_partitioning, lpsolver, alm); } void LandmarkCostPartitioningHeuristic::check_unsupported_features( - const plugins::Options &opts) { - shared_ptr lm_graph_factory = - opts.get>("lm_factory"); - + const shared_ptr &lm_factory) { if (task_properties::has_axioms(task_proxy)) { cerr << "Cost partitioning does not support axioms." << endl; utils::exit_with(utils::ExitCode::SEARCH_UNSUPPORTED); } - if (!lm_graph_factory->supports_conditional_effects() + if (!lm_factory->supports_conditional_effects() && task_properties::has_conditional_effects(task_proxy)) { cerr << "Conditional effects not supported by the landmark " << "generation method." << endl; @@ -45,18 +48,18 @@ void LandmarkCostPartitioningHeuristic::check_unsupported_features( } void LandmarkCostPartitioningHeuristic::set_cost_partitioning_algorithm( - const plugins::Options &opts) { - auto method = opts.get("cost_partitioning"); - if (method == CostPartitioningMethod::OPTIMAL) { + CostPartitioningMethod cost_partitioning, lp::LPSolverType lpsolver, + bool alm) { + if (cost_partitioning == CostPartitioningMethod::OPTIMAL) { cost_partitioning_algorithm = utils::make_unique_ptr( task_properties::get_operator_costs(task_proxy), - *lm_graph, opts.get("lpsolver")); - } else if (method == CostPartitioningMethod::UNIFORM) { + *lm_graph, lpsolver); + } else if (cost_partitioning == CostPartitioningMethod::UNIFORM) { cost_partitioning_algorithm = utils::make_unique_ptr( task_properties::get_operator_costs(task_proxy), - *lm_graph, opts.get("alm")); + *lm_graph, alm); } else { ABORT("Unknown cost partitioning method"); } @@ -80,7 +83,8 @@ bool LandmarkCostPartitioningHeuristic::dead_ends_are_reliable() const { return true; } -class LandmarkCostPartitioningHeuristicFeature : public plugins::TypedFeature { +class LandmarkCostPartitioningHeuristicFeature + : public plugins::TypedFeature { public: LandmarkCostPartitioningHeuristicFeature() : TypedFeature("landmark_cost_partitioning") { document_title("Landmark cost partitioning heuristic"); @@ -107,7 +111,16 @@ class LandmarkCostPartitioningHeuristicFeature : public plugins::TypedFeature( "cost_partitioning", "strategy for partitioning operator costs among landmarks", @@ -152,6 +165,17 @@ class LandmarkCostPartitioningHeuristicFeature : public plugins::TypedFeature + create_component(const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_landmark_heuristic_arguments_from_options(opts), + opts.get("cost_partitioning"), + opts.get("alm"), + lp::get_lp_solver_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/landmarks/landmark_cost_partitioning_heuristic.h b/src/search/landmarks/landmark_cost_partitioning_heuristic.h index cd08edff5..be64e867c 100644 --- a/src/search/landmarks/landmark_cost_partitioning_heuristic.h +++ b/src/search/landmarks/landmark_cost_partitioning_heuristic.h @@ -2,6 +2,7 @@ #define LANDMARKS_LANDMARK_COST_PARTITIONING_HEURISTIC_H #include "landmark_heuristic.h" +#include "../lp/lp_solver.h" namespace landmarks { class CostPartitioningAlgorithm; @@ -14,12 +15,22 @@ enum class CostPartitioningMethod { class LandmarkCostPartitioningHeuristic : public LandmarkHeuristic { std::unique_ptr cost_partitioning_algorithm; - void check_unsupported_features(const plugins::Options &opts); - void set_cost_partitioning_algorithm(const plugins::Options &opts); + void check_unsupported_features( + const std::shared_ptr &lm_factory); + void set_cost_partitioning_algorithm( + CostPartitioningMethod cost_partitioning, + lp::LPSolverType lpsolver, bool alm); int get_heuristic_value(const State &ancestor_state) override; public: - explicit LandmarkCostPartitioningHeuristic(const plugins::Options &opts); + LandmarkCostPartitioningHeuristic( + const std::shared_ptr &lm_factory, bool pref, + bool prog_goal, bool prog_gn, bool prog_r, + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity, + CostPartitioningMethod cost_partitioning, bool alm, + lp::LPSolverType lpsolver); virtual bool dead_ends_are_reliable() const override; }; diff --git a/src/search/landmarks/landmark_factory.cc b/src/search/landmarks/landmark_factory.cc index 40ddf15d4..8df5978aa 100644 --- a/src/search/landmarks/landmark_factory.cc +++ b/src/search/landmarks/landmark_factory.cc @@ -17,8 +17,8 @@ using namespace std; namespace landmarks { -LandmarkFactory::LandmarkFactory(const plugins::Options &opts) - : log(utils::get_log_from_options(opts)), lm_graph(nullptr) { +LandmarkFactory::LandmarkFactory(utils::Verbosity verbosity) + : log(utils::get_log_for_verbosity(verbosity)), lm_graph(nullptr) { } /* @@ -167,6 +167,12 @@ void add_landmark_factory_options_to_feature(plugins::Feature &feature) { utils::add_log_options_to_feature(feature); } +tuple +get_landmark_factory_arguments_from_options( + const plugins::Options &opts) { + return utils::get_log_arguments_from_options(opts); +} + void add_use_orders_option_to_feature(plugins::Feature &feature) { feature.add_option( "use_orders", @@ -174,6 +180,11 @@ void add_use_orders_option_to_feature(plugins::Feature &feature) { "true"); } +bool get_use_orders_arguments_from_options( + const plugins::Options &opts) { + return opts.get("use_orders"); +} + void add_only_causal_landmarks_option_to_feature( plugins::Feature &feature) { feature.add_option( @@ -182,14 +193,20 @@ void add_only_causal_landmarks_option_to_feature( "false"); } +bool get_only_causal_landmarks_arguments_from_options( + const plugins::Options &opts) { + return opts.get("only_causal_landmarks"); +} + static class LandmarkFactoryCategoryPlugin : public plugins::TypedCategoryPlugin { public: LandmarkFactoryCategoryPlugin() : TypedCategoryPlugin("LandmarkFactory") { document_synopsis( "A landmark factory specification is either a newly created " "instance or a landmark factory that has been defined previously. " - "This page describes how one can specify a new landmark factory instance. " - "For re-using landmark factories, see OptionSyntax#Landmark_Predefinitions."); + "This page describes how one can specify a new landmark factory " + "instance. For re-using landmark factories, see " + "OptionSyntax#Landmark_Predefinitions."); allow_variable_binding(); } } diff --git a/src/search/landmarks/landmark_factory.h b/src/search/landmarks/landmark_factory.h index 2258f6bc6..35d329c7e 100644 --- a/src/search/landmarks/landmark_factory.h +++ b/src/search/landmarks/landmark_factory.h @@ -39,7 +39,7 @@ class LandmarkFactory { } protected: - explicit LandmarkFactory(const plugins::Options &opts); + explicit LandmarkFactory(utils::Verbosity verbosity); mutable utils::LogProxy log; std::shared_ptr lm_graph; bool achievers_calculated = false; @@ -64,8 +64,14 @@ class LandmarkFactory { }; extern void add_landmark_factory_options_to_feature(plugins::Feature &feature); +extern std::tuple get_landmark_factory_arguments_from_options( + const plugins::Options &opts); extern void add_use_orders_option_to_feature(plugins::Feature &feature); +extern bool get_use_orders_arguments_from_options( + const plugins::Options &opts); extern void add_only_causal_landmarks_option_to_feature(plugins::Feature &feature); +extern bool get_only_causal_landmarks_arguments_from_options( + const plugins::Options &opts); } #endif diff --git a/src/search/landmarks/landmark_factory_h_m.cc b/src/search/landmarks/landmark_factory_h_m.cc index 2894b41a3..621b015cc 100644 --- a/src/search/landmarks/landmark_factory_h_m.cc +++ b/src/search/landmarks/landmark_factory_h_m.cc @@ -568,11 +568,13 @@ bool LandmarkFactoryHM::interesting(const VariablesProxy &variables, variables[fact2.var].get_fact(fact2.value)); } -LandmarkFactoryHM::LandmarkFactoryHM(const plugins::Options &opts) - : LandmarkFactory(opts), - m_(opts.get("m")), - conjunctive_landmarks(opts.get("conjunctive_landmarks")), - use_orders(opts.get("use_orders")) { +LandmarkFactoryHM::LandmarkFactoryHM( + int m, bool conjunctive_landmarks, bool use_orders, + utils::Verbosity verbosity) + : LandmarkFactory(verbosity), + m_(m), + conjunctive_landmarks(conjunctive_landmarks), + use_orders(use_orders) { } void LandmarkFactoryHM::initialize(const TaskProxy &task_proxy) { @@ -1012,7 +1014,8 @@ bool LandmarkFactoryHM::supports_conditional_effects() const { return false; } -class LandmarkFactoryHMFeature : public plugins::TypedFeature { +class LandmarkFactoryHMFeature + : public plugins::TypedFeature { public: LandmarkFactoryHMFeature() : TypedFeature("lm_hm") { // document_group(""); @@ -1027,13 +1030,23 @@ class LandmarkFactoryHMFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get("m"), + opts.get("conjunctive_landmarks"), + get_use_orders_arguments_from_options(opts), + get_landmark_factory_arguments_from_options(opts)); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/landmarks/landmark_factory_h_m.h b/src/search/landmarks/landmark_factory_h_m.h index d8a411faa..9323075cc 100644 --- a/src/search/landmarks/landmark_factory_h_m.h +++ b/src/search/landmarks/landmark_factory_h_m.h @@ -138,7 +138,8 @@ class LandmarkFactoryHM : public LandmarkFactory { void print_proposition(const VariablesProxy &variables, const FactPair &fluent) const; public: - explicit LandmarkFactoryHM(const plugins::Options &opts); + LandmarkFactoryHM(int m, bool conjunctive_landmarks, + bool use_orders, utils::Verbosity verbosity); virtual bool supports_conditional_effects() const override; }; diff --git a/src/search/landmarks/landmark_factory_merged.cc b/src/search/landmarks/landmark_factory_merged.cc index f67fb9a3b..d838480ec 100644 --- a/src/search/landmarks/landmark_factory_merged.cc +++ b/src/search/landmarks/landmark_factory_merged.cc @@ -13,9 +13,11 @@ using utils::ExitCode; namespace landmarks { class LandmarkNode; -LandmarkFactoryMerged::LandmarkFactoryMerged(const plugins::Options &opts) - : LandmarkFactory(opts), - lm_factories(opts.get_list>("lm_factories")) { +LandmarkFactoryMerged::LandmarkFactoryMerged( + const vector> &lm_factories, + utils::Verbosity verbosity) + : LandmarkFactory(verbosity), + lm_factories(lm_factories) { } LandmarkNode *LandmarkFactoryMerged::get_matching_landmark(const Landmark &landmark) const { @@ -141,7 +143,8 @@ bool LandmarkFactoryMerged::supports_conditional_effects() const { return true; } -class LandmarkFactoryMergedFeature : public plugins::TypedFeature { +class LandmarkFactoryMergedFeature + : public plugins::TypedFeature { public: LandmarkFactoryMergedFeature() : TypedFeature("lm_merged") { document_title("Merged Landmarks"); @@ -165,9 +168,14 @@ class LandmarkFactoryMergedFeature : public plugins::TypedFeature create_component(const plugins::Options &options, const utils::Context &context) const override { - plugins::verify_list_non_empty>(context, options, "lm_factories"); - return make_shared(options); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &context) const override { + plugins::verify_list_non_empty>( + context, opts, "lm_factories"); + return plugins::make_shared_from_arg_tuples( + opts.get_list>("lm_factories"), + get_landmark_factory_arguments_from_options(opts)); } }; diff --git a/src/search/landmarks/landmark_factory_merged.h b/src/search/landmarks/landmark_factory_merged.h index 06556d9e1..f4abb84e5 100644 --- a/src/search/landmarks/landmark_factory_merged.h +++ b/src/search/landmarks/landmark_factory_merged.h @@ -13,7 +13,9 @@ class LandmarkFactoryMerged : public LandmarkFactory { void postprocess(); LandmarkNode *get_matching_landmark(const Landmark &landmark) const; public: - explicit LandmarkFactoryMerged(const plugins::Options &opts); + LandmarkFactoryMerged( + const std::vector> &lm_factories, + utils::Verbosity verbosity); virtual bool supports_conditional_effects() const override; }; diff --git a/src/search/landmarks/landmark_factory_reasonable_orders_hps.cc b/src/search/landmarks/landmark_factory_reasonable_orders_hps.cc index 3469c0c1a..f298d7e37 100644 --- a/src/search/landmarks/landmark_factory_reasonable_orders_hps.cc +++ b/src/search/landmarks/landmark_factory_reasonable_orders_hps.cc @@ -11,9 +11,11 @@ using namespace std; namespace landmarks { -LandmarkFactoryReasonableOrdersHPS::LandmarkFactoryReasonableOrdersHPS(const plugins::Options &opts) - : LandmarkFactory(opts), - lm_factory(opts.get>("lm_factory")) { +LandmarkFactoryReasonableOrdersHPS::LandmarkFactoryReasonableOrdersHPS( + const shared_ptr &lm_factory, + utils::Verbosity verbosity) + : LandmarkFactory(verbosity), + lm_factory(lm_factory) { } void LandmarkFactoryReasonableOrdersHPS::generate_landmarks(const shared_ptr &task) { @@ -353,7 +355,8 @@ bool LandmarkFactoryReasonableOrdersHPS::supports_conditional_effects() const { return lm_factory->supports_conditional_effects(); } -class LandmarkFactoryReasonableOrdersHPSFeature : public plugins::TypedFeature { +class LandmarkFactoryReasonableOrdersHPSFeature + : public plugins::TypedFeature { public: LandmarkFactoryReasonableOrdersHPSFeature() : TypedFeature("lm_reasonable_orders_hps") { document_title("HPS Orders"); @@ -388,6 +391,14 @@ class LandmarkFactoryReasonableOrdersHPSFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get>("lm_factory"), + get_landmark_factory_arguments_from_options(opts)); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/landmarks/landmark_factory_reasonable_orders_hps.h b/src/search/landmarks/landmark_factory_reasonable_orders_hps.h index 01758afd4..7b85bba00 100644 --- a/src/search/landmarks/landmark_factory_reasonable_orders_hps.h +++ b/src/search/landmarks/landmark_factory_reasonable_orders_hps.h @@ -19,7 +19,9 @@ class LandmarkFactoryReasonableOrdersHPS : public LandmarkFactory { const VariablesProxy &variables, const EffectsProxy &effects, std::set &eff) const; public: - LandmarkFactoryReasonableOrdersHPS(const plugins::Options &opts); + LandmarkFactoryReasonableOrdersHPS( + const std::shared_ptr &lm_factory, + utils::Verbosity verbosity); virtual bool supports_conditional_effects() const override; }; diff --git a/src/search/landmarks/landmark_factory_relaxation.cc b/src/search/landmarks/landmark_factory_relaxation.cc index 0b641a946..63518d1c7 100644 --- a/src/search/landmarks/landmark_factory_relaxation.cc +++ b/src/search/landmarks/landmark_factory_relaxation.cc @@ -8,8 +8,9 @@ using namespace std; namespace landmarks { -LandmarkFactoryRelaxation::LandmarkFactoryRelaxation(const plugins::Options &opts) - : LandmarkFactory(opts) { +LandmarkFactoryRelaxation::LandmarkFactoryRelaxation( + utils::Verbosity verbosity) + : LandmarkFactory(verbosity) { } void LandmarkFactoryRelaxation::generate_landmarks(const shared_ptr &task) { diff --git a/src/search/landmarks/landmark_factory_relaxation.h b/src/search/landmarks/landmark_factory_relaxation.h index 63ca4fe14..813c6862a 100644 --- a/src/search/landmarks/landmark_factory_relaxation.h +++ b/src/search/landmarks/landmark_factory_relaxation.h @@ -8,7 +8,7 @@ class Exploration; class LandmarkFactoryRelaxation : public LandmarkFactory { protected: - explicit LandmarkFactoryRelaxation(const plugins::Options &opts); + explicit LandmarkFactoryRelaxation(utils::Verbosity verbosity); /* Test whether the relaxed planning task is solvable without diff --git a/src/search/landmarks/landmark_factory_rpg_exhaust.cc b/src/search/landmarks/landmark_factory_rpg_exhaust.cc index 51e5d7957..462cb936a 100644 --- a/src/search/landmarks/landmark_factory_rpg_exhaust.cc +++ b/src/search/landmarks/landmark_factory_rpg_exhaust.cc @@ -16,9 +16,10 @@ namespace landmarks { that are inferred later.) It's thus best to combine this landmark generation method with others, don't use it by itself. */ -LandmarkFactoryRpgExhaust::LandmarkFactoryRpgExhaust(const plugins::Options &opts) - : LandmarkFactoryRelaxation(opts), - only_causal_landmarks(opts.get("only_causal_landmarks")) { +LandmarkFactoryRpgExhaust::LandmarkFactoryRpgExhaust( + bool only_causal_landmarks, utils::Verbosity verbosity) + : LandmarkFactoryRelaxation(verbosity), + only_causal_landmarks(only_causal_landmarks) { } void LandmarkFactoryRpgExhaust::generate_relaxed_landmarks( @@ -57,7 +58,8 @@ bool LandmarkFactoryRpgExhaust::supports_conditional_effects() const { return false; } -class LandmarkFactoryRpgExhaustFeature : public plugins::TypedFeature { +class LandmarkFactoryRpgExhaustFeature + : public plugins::TypedFeature { public: LandmarkFactoryRpgExhaustFeature() : TypedFeature("lm_exhaust") { document_title("Exhaustive Landmarks"); @@ -65,13 +67,21 @@ class LandmarkFactoryRpgExhaustFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_only_causal_landmarks_arguments_from_options(opts), + get_landmark_factory_arguments_from_options(opts)); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/landmarks/landmark_factory_rpg_exhaust.h b/src/search/landmarks/landmark_factory_rpg_exhaust.h index 710789356..0c2749bf9 100644 --- a/src/search/landmarks/landmark_factory_rpg_exhaust.h +++ b/src/search/landmarks/landmark_factory_rpg_exhaust.h @@ -10,7 +10,8 @@ class LandmarkFactoryRpgExhaust : public LandmarkFactoryRelaxation { Exploration &exploration) override; public: - explicit LandmarkFactoryRpgExhaust(const plugins::Options &opts); + explicit LandmarkFactoryRpgExhaust(bool only_causal_landmarks, + utils::Verbosity verbosity); virtual bool supports_conditional_effects() const override; }; diff --git a/src/search/landmarks/landmark_factory_rpg_sasp.cc b/src/search/landmarks/landmark_factory_rpg_sasp.cc index 97a5e6b7d..813c02cd9 100644 --- a/src/search/landmarks/landmark_factory_rpg_sasp.cc +++ b/src/search/landmarks/landmark_factory_rpg_sasp.cc @@ -17,11 +17,13 @@ using namespace std; using utils::ExitCode; namespace landmarks { -LandmarkFactoryRpgSasp::LandmarkFactoryRpgSasp(const plugins::Options &opts) - : LandmarkFactoryRelaxation(opts), - disjunctive_landmarks(opts.get("disjunctive_landmarks")), - use_orders(opts.get("use_orders")), - only_causal_landmarks(opts.get("only_causal_landmarks")) { +LandmarkFactoryRpgSasp::LandmarkFactoryRpgSasp( + bool disjunctive_landmarks, bool use_orders, + bool only_causal_landmarks, utils::Verbosity verbosity) + : LandmarkFactoryRelaxation(verbosity), + disjunctive_landmarks(disjunctive_landmarks), + use_orders(use_orders), + only_causal_landmarks(only_causal_landmarks) { } void LandmarkFactoryRpgSasp::build_dtg_successors(const TaskProxy &task_proxy) { @@ -631,7 +633,8 @@ bool LandmarkFactoryRpgSasp::supports_conditional_effects() const { return true; } -class LandmarkFactoryRpgSaspFeature : public plugins::TypedFeature { +class LandmarkFactoryRpgSaspFeature + : public plugins::TypedFeature { public: LandmarkFactoryRpgSaspFeature() : TypedFeature("lm_rhw") { document_title("RHW Landmarks"); @@ -643,14 +646,24 @@ class LandmarkFactoryRpgSaspFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get("disjunctive_landmarks"), + get_use_orders_arguments_from_options(opts), + get_only_causal_landmarks_arguments_from_options(opts), + get_landmark_factory_arguments_from_options(opts)); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/landmarks/landmark_factory_rpg_sasp.h b/src/search/landmarks/landmark_factory_rpg_sasp.h index 9922974fd..bd86bc0c9 100644 --- a/src/search/landmarks/landmark_factory_rpg_sasp.h +++ b/src/search/landmarks/landmark_factory_rpg_sasp.h @@ -62,7 +62,9 @@ class LandmarkFactoryRpgSasp : public LandmarkFactoryRelaxation { void discard_disjunctive_landmarks(); public: - explicit LandmarkFactoryRpgSasp(const plugins::Options &opts); + LandmarkFactoryRpgSasp( + bool disjunctive_landmarks, bool use_orders, + bool only_causal_landmarks, utils::Verbosity verbosity); virtual bool supports_conditional_effects() const override; }; diff --git a/src/search/landmarks/landmark_factory_zhu_givan.cc b/src/search/landmarks/landmark_factory_zhu_givan.cc index 349fac895..f40484032 100644 --- a/src/search/landmarks/landmark_factory_zhu_givan.cc +++ b/src/search/landmarks/landmark_factory_zhu_givan.cc @@ -16,9 +16,10 @@ using namespace std; namespace landmarks { -LandmarkFactoryZhuGivan::LandmarkFactoryZhuGivan(const plugins::Options &opts) - : LandmarkFactoryRelaxation(opts), - use_orders(opts.get("use_orders")) { +LandmarkFactoryZhuGivan::LandmarkFactoryZhuGivan( + bool use_orders, utils::Verbosity verbosity) + : LandmarkFactoryRelaxation(verbosity), + use_orders(use_orders) { } void LandmarkFactoryZhuGivan::generate_relaxed_landmarks( @@ -304,7 +305,8 @@ bool LandmarkFactoryZhuGivan::supports_conditional_effects() const { return true; } -class LandmarkFactoryZhuGivanFeature : public plugins::TypedFeature { +class LandmarkFactoryZhuGivanFeature + : public plugins::TypedFeature { public: LandmarkFactoryZhuGivanFeature() : TypedFeature("lm_zg") { document_title("Zhu/Givan Landmarks"); @@ -312,14 +314,22 @@ class LandmarkFactoryZhuGivanFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_use_orders_arguments_from_options(opts), + get_landmark_factory_arguments_from_options(opts)); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/landmarks/landmark_factory_zhu_givan.h b/src/search/landmarks/landmark_factory_zhu_givan.h index dbc1569a3..97e182537 100644 --- a/src/search/landmarks/landmark_factory_zhu_givan.h +++ b/src/search/landmarks/landmark_factory_zhu_givan.h @@ -75,7 +75,8 @@ class LandmarkFactoryZhuGivan : public LandmarkFactoryRelaxation { Exploration &exploration) override; public: - explicit LandmarkFactoryZhuGivan(const plugins::Options &opts); + LandmarkFactoryZhuGivan( + bool use_orders, utils::Verbosity verbosity); virtual bool supports_conditional_effects() const override; }; diff --git a/src/search/landmarks/landmark_heuristic.cc b/src/search/landmarks/landmark_heuristic.cc index c37b08f3f..b03c119a1 100644 --- a/src/search/landmarks/landmark_heuristic.cc +++ b/src/search/landmarks/landmark_heuristic.cc @@ -14,13 +14,17 @@ using namespace std; namespace landmarks { LandmarkHeuristic::LandmarkHeuristic( - const plugins::Options &opts) - : Heuristic(opts), - use_preferred_operators(opts.get("pref")), + bool use_preferred_operators, + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : Heuristic(transform, cache_estimates, description, verbosity), + use_preferred_operators(use_preferred_operators), successor_generator(nullptr) { } -void LandmarkHeuristic::initialize(const plugins::Options &opts) { +void LandmarkHeuristic::initialize( + const shared_ptr &lm_factory, bool prog_goal, + bool prog_gn, bool prog_r) { /* Actually, we should test if this is the root task or a CostAdaptedTask *of the root task*, but there is currently no good @@ -34,10 +38,9 @@ void LandmarkHeuristic::initialize(const plugins::Options &opts) { utils::exit_with(utils::ExitCode::SEARCH_UNSUPPORTED); } - compute_landmark_graph(opts); + compute_landmark_graph(lm_factory); lm_status_manager = utils::make_unique_ptr( - *lm_graph, opts.get("prog_goal"), - opts.get("prog_gn"), opts.get("prog_r")); + *lm_graph, prog_goal, prog_gn, prog_r); initial_landmark_graph_has_cycle_of_natural_orderings = landmark_graph_has_cycle_of_natural_orderings(); @@ -90,16 +93,15 @@ bool LandmarkHeuristic::depth_first_search_for_cycle_of_natural_orderings( return false; } -void LandmarkHeuristic::compute_landmark_graph(const plugins::Options &opts) { +void LandmarkHeuristic::compute_landmark_graph( + const shared_ptr &lm_factory) { utils::Timer lm_graph_timer; if (log.is_at_least_normal()) { log << "Generating landmark graph..." << endl; } - shared_ptr lm_graph_factory = - opts.get>("lm_factory"); - lm_graph = lm_graph_factory->compute_lm_graph(task); - assert(lm_graph_factory->achievers_are_calculated()); + lm_graph = lm_factory->compute_lm_graph(task); + assert(lm_factory->achievers_are_calculated()); if (log.is_at_least_normal()) { log << "Landmark graph generation time: " << lm_graph_timer << endl; @@ -190,7 +192,8 @@ void LandmarkHeuristic::notify_state_transition( } } -void LandmarkHeuristic::add_options_to_feature(plugins::Feature &feature) { +void add_landmark_heuristic_options_to_feature( + plugins::Feature &feature, const string &description) { feature.document_synopsis( "Landmark progression is implemented according to the following paper:" + utils::format_conference_reference( @@ -220,9 +223,24 @@ void LandmarkHeuristic::add_options_to_feature(plugins::Feature &feature) { "prog_gn", "Use greedy-necessary ordering progression.", "true"); feature.add_option( "prog_r", "Use reasonable ordering progression.", "true"); - Heuristic::add_options_to_feature(feature); + add_heuristic_options_to_feature(feature, description); feature.document_property("preferred operators", "yes (if enabled; see ``pref`` option)"); } + +tuple, bool, bool, bool, bool, + shared_ptr, bool, string, utils::Verbosity> +get_landmark_heuristic_arguments_from_options( + const plugins::Options &opts) { + return tuple_cat( + make_tuple( + opts.get>("lm_factory"), + opts.get("pref"), + opts.get("prog_goal"), + opts.get("prog_gn"), + opts.get("prog_r") + ), + get_heuristic_arguments_from_options(opts)); +} } diff --git a/src/search/landmarks/landmark_heuristic.h b/src/search/landmarks/landmark_heuristic.h index 581843918..1cdab0128 100644 --- a/src/search/landmarks/landmark_heuristic.h +++ b/src/search/landmarks/landmark_heuristic.h @@ -31,8 +31,11 @@ class LandmarkHeuristic : public Heuristic { std::unique_ptr lm_status_manager; std::unique_ptr successor_generator; - void initialize(const plugins::Options &opts); - void compute_landmark_graph(const plugins::Options &opts); + void initialize( + const std::shared_ptr &lm_factory, + bool prog_goal, bool prog_gn, bool prog_r); + void compute_landmark_graph( + const std::shared_ptr &lm_factory); virtual int get_heuristic_value(const State &ancestor_state) = 0; @@ -40,20 +43,30 @@ class LandmarkHeuristic : public Heuristic { const State &state, ConstBitsetView &future); virtual int compute_heuristic(const State &ancestor_state) override; public: - explicit LandmarkHeuristic(const plugins::Options &opts); + LandmarkHeuristic( + bool use_preferred_operators, + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); virtual void get_path_dependent_evaluators( std::set &evals) override { evals.insert(this); } - static void add_options_to_feature(plugins::Feature &feature); - virtual void notify_initial_state(const State &initial_state) override; virtual void notify_state_transition(const State &parent_state, OperatorID op_id, const State &state) override; }; + +extern void add_landmark_heuristic_options_to_feature( + plugins::Feature &feature, const std::string &description); +extern std::tuple, bool, bool, bool, + bool, std::shared_ptr, bool, + std::string, utils::Verbosity> +get_landmark_heuristic_arguments_from_options( + const plugins::Options &opts); } #endif diff --git a/src/search/landmarks/landmark_sum_heuristic.cc b/src/search/landmarks/landmark_sum_heuristic.cc index ac687a56b..bcfd4ae58 100644 --- a/src/search/landmarks/landmark_sum_heuristic.cc +++ b/src/search/landmarks/landmark_sum_heuristic.cc @@ -30,16 +30,19 @@ static bool are_dead_ends_reliable( return true; } -LandmarkSumHeuristic::LandmarkSumHeuristic(const plugins::Options &opts) - : LandmarkHeuristic(opts), +LandmarkSumHeuristic::LandmarkSumHeuristic( + const shared_ptr &lm_factory, bool pref, + bool prog_goal, bool prog_gn, bool prog_r, + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : LandmarkHeuristic( + pref, transform, cache_estimates, description, verbosity), dead_ends_reliable( - are_dead_ends_reliable( - opts.get>("lm_factory"), - task_proxy)) { + are_dead_ends_reliable(lm_factory, task_proxy)) { if (log.is_at_least_normal()) { log << "Initializing landmark sum heuristic..." << endl; } - initialize(opts); + initialize(lm_factory, prog_goal, prog_gn, prog_r); compute_landmark_costs(); } @@ -109,7 +112,8 @@ bool LandmarkSumHeuristic::dead_ends_are_reliable() const { return dead_ends_reliable; } -class LandmarkSumHeuristicFeature : public plugins::TypedFeature { +class LandmarkSumHeuristicFeature + : public plugins::TypedFeature { public: LandmarkSumHeuristicFeature() : TypedFeature("landmark_sum") { document_title("Landmark sum heuristic"); @@ -136,7 +140,8 @@ class LandmarkSumHeuristicFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_landmark_heuristic_arguments_from_options(opts)); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/landmarks/landmark_sum_heuristic.h b/src/search/landmarks/landmark_sum_heuristic.h index c47af5b09..268d552af 100644 --- a/src/search/landmarks/landmark_sum_heuristic.h +++ b/src/search/landmarks/landmark_sum_heuristic.h @@ -16,7 +16,12 @@ class LandmarkSumHeuristic : public LandmarkHeuristic { int get_heuristic_value(const State &ancestor_state) override; public: - explicit LandmarkSumHeuristic(const plugins::Options &opts); + LandmarkSumHeuristic( + const std::shared_ptr &lm_factory, bool pref, + bool prog_goal, bool prog_gn, bool prog_r, + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); virtual bool dead_ends_are_reliable() const override; }; diff --git a/src/search/lp/lp_solver.cc b/src/search/lp/lp_solver.cc index 9f34d3d52..80e63b4b8 100644 --- a/src/search/lp/lp_solver.cc +++ b/src/search/lp/lp_solver.cc @@ -24,6 +24,11 @@ void add_lp_solver_option_to_feature(plugins::Feature &feature) { "See [build instructions https://github.com/aibasel/downward/blob/main/BUILD.md]."); } +tuple get_lp_solver_arguments_from_options( + const plugins::Options &opts) { + return make_tuple(opts.get("lpsolver")); +} + LPConstraint::LPConstraint(double lower_bound, double upper_bound) : lower_bound(lower_bound), upper_bound(upper_bound) { diff --git a/src/search/lp/lp_solver.h b/src/search/lp/lp_solver.h index a9bdff8c0..59693ffea 100644 --- a/src/search/lp/lp_solver.h +++ b/src/search/lp/lp_solver.h @@ -12,6 +12,7 @@ namespace plugins { class Feature; +class Options; } namespace lp { @@ -24,6 +25,8 @@ enum class LPObjectiveSense { }; void add_lp_solver_option_to_feature(plugins::Feature &feature); +std::tuple get_lp_solver_arguments_from_options( + const plugins::Options &opts); class LinearProgram; diff --git a/src/search/merge_and_shrink/label_reduction.cc b/src/search/merge_and_shrink/label_reduction.cc index 9e4ac0a45..1b113ab6a 100644 --- a/src/search/merge_and_shrink/label_reduction.cc +++ b/src/search/merge_and_shrink/label_reduction.cc @@ -25,12 +25,15 @@ using namespace std; using utils::ExitCode; namespace merge_and_shrink { -LabelReduction::LabelReduction(const plugins::Options &options) - : lr_before_shrinking(options.get("before_shrinking")), - lr_before_merging(options.get("before_merging")), - lr_method(options.get("method")), - lr_system_order(options.get("system_order")), - rng(utils::parse_rng_from_options(options)) { +LabelReduction::LabelReduction( + bool before_shrinking, bool before_merging, + LabelReductionMethod method, LabelReductionSystemOrder system_order, + int random_seed) + : lr_before_shrinking(before_shrinking), + lr_before_merging(before_merging), + lr_method(method), + lr_system_order(system_order), + rng(utils::get_rng(random_seed)) { } bool LabelReduction::initialized() const { @@ -287,7 +290,8 @@ void LabelReduction::dump_options(utils::LogProxy &log) const { } } -class LabelReductionFeature : public plugins::TypedFeature { +class LabelReductionFeature + : public plugins::TypedFeature { public: LabelReductionFeature() : TypedFeature("exact") { document_title("Exact generalized label reduction"); @@ -332,18 +336,26 @@ class LabelReductionFeature : public plugins::TypedFeature create_component(const plugins::Options &options, const utils::Context &context) const override { - bool lr_before_shrinking = options.get("before_shrinking"); - bool lr_before_merging = options.get("before_merging"); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &context) const override { + bool lr_before_shrinking = opts.get("before_shrinking"); + bool lr_before_merging = opts.get("before_merging"); if (!lr_before_shrinking && !lr_before_merging) { context.error( "Please turn on at least one of the options " "before_shrinking or before_merging!"); } - return make_shared(options); + return plugins::make_shared_from_arg_tuples( + opts.get("before_shrinking"), + opts.get("before_merging"), + opts.get("method"), + opts.get("system_order"), + utils::get_rng_arguments_from_options(opts) + ); } }; diff --git a/src/search/merge_and_shrink/label_reduction.h b/src/search/merge_and_shrink/label_reduction.h index f837cc244..ff94281af 100644 --- a/src/search/merge_and_shrink/label_reduction.h +++ b/src/search/merge_and_shrink/label_reduction.h @@ -75,7 +75,10 @@ class LabelReduction { int ts_index, const FactoredTransitionSystem &fts) const; public: - explicit LabelReduction(const plugins::Options &options); + LabelReduction( + bool before_shrinking, bool before_merging, + LabelReductionMethod method, + LabelReductionSystemOrder system_order, int random_seed); void initialize(const TaskProxy &task_proxy); bool reduce( const std::pair &next_merge, diff --git a/src/search/merge_and_shrink/merge_and_shrink_algorithm.cc b/src/search/merge_and_shrink/merge_and_shrink_algorithm.cc index c1037f7df..7b678a766 100644 --- a/src/search/merge_and_shrink/merge_and_shrink_algorithm.cc +++ b/src/search/merge_and_shrink/merge_and_shrink_algorithm.cc @@ -36,19 +36,25 @@ namespace merge_and_shrink { static void log_progress(const utils::Timer &timer, const string &msg, utils::LogProxy &log) { log << "M&S algorithm timer: " << timer << " (" << msg << ")" << endl; } - -MergeAndShrinkAlgorithm::MergeAndShrinkAlgorithm(const plugins::Options &opts) : - merge_strategy_factory(opts.get>("merge_strategy")), - shrink_strategy(opts.get>("shrink_strategy")), - label_reduction(opts.get>("label_reduction", nullptr)), - max_states(opts.get("max_states")), - max_states_before_merge(opts.get("max_states_before_merge")), - shrink_threshold_before_merge(opts.get("threshold_before_merge")), - prune_unreachable_states(opts.get("prune_unreachable_states")), - prune_irrelevant_states(opts.get("prune_irrelevant_states")), - log(utils::get_log_from_options(opts)), - main_loop_max_time(opts.get("main_loop_max_time")), - starting_peak_memory(0) { +MergeAndShrinkAlgorithm::MergeAndShrinkAlgorithm( + const shared_ptr &merge_strategy, + const shared_ptr &shrink_strategy, + const shared_ptr &label_reduction, + bool prune_unreachable_states, bool prune_irrelevant_states, + int max_states, int max_states_before_merge, + int threshold_before_merge, double main_loop_max_time, + utils::Verbosity verbosity) + : merge_strategy_factory(merge_strategy), + shrink_strategy(shrink_strategy), + label_reduction(label_reduction), + max_states(max_states), + max_states_before_merge(max_states_before_merge), + shrink_threshold_before_merge(threshold_before_merge), + prune_unreachable_states(prune_unreachable_states), + prune_irrelevant_states(prune_irrelevant_states), + log(utils::get_log_for_verbosity(verbosity)), + main_loop_max_time(main_loop_max_time), + starting_peak_memory(0) { assert(max_states_before_merge > 0); assert(max_states >= max_states_before_merge); assert(shrink_threshold_before_merge <= max_states_before_merge); @@ -453,6 +459,23 @@ void add_merge_and_shrink_algorithm_options_to_feature(plugins::Feature &feature Bounds("0.0", "infinity")); } +tuple, shared_ptr, + shared_ptr, bool, bool, int, int, int, double> +get_merge_and_shrink_algorithm_arguments_from_options( + const plugins::Options &opts) { + return tuple_cat( + make_tuple( + opts.get>("merge_strategy"), + opts.get>("shrink_strategy"), + opts.get>( + "label_reduction", nullptr), + opts.get("prune_unreachable_states"), + opts.get("prune_irrelevant_states")), + get_transition_system_size_limit_arguments_from_options(opts), + make_tuple(opts.get("main_loop_max_time")) + ); +} + void add_transition_system_size_limit_options_to_feature(plugins::Feature &feature) { feature.add_option( "max_states", @@ -474,6 +497,16 @@ void add_transition_system_size_limit_options_to_feature(plugins::Feature &featu Bounds("-1", "infinity")); } +tuple +get_transition_system_size_limit_arguments_from_options( + const plugins::Options &opts) { + return make_tuple( + opts.get("max_states"), + opts.get("max_states_before_merge"), + opts.get("threshold_before_merge") + ); +} + void handle_shrink_limit_options_defaults(plugins::Options &opts, const utils::Context &context) { int max_states = opts.get("max_states"); int max_states_before_merge = opts.get("max_states_before_merge"); diff --git a/src/search/merge_and_shrink/merge_and_shrink_algorithm.h b/src/search/merge_and_shrink/merge_and_shrink_algorithm.h index 24285dcde..07f060307 100644 --- a/src/search/merge_and_shrink/merge_and_shrink_algorithm.h +++ b/src/search/merge_and_shrink/merge_and_shrink_algorithm.h @@ -57,12 +57,28 @@ class MergeAndShrinkAlgorithm { FactoredTransitionSystem &fts, const TaskProxy &task_proxy); public: - explicit MergeAndShrinkAlgorithm(const plugins::Options &opts); + MergeAndShrinkAlgorithm( + const std::shared_ptr &merge_strategy, + const std::shared_ptr &shrink_strategy, + const std::shared_ptr &label_reduction, + bool prune_unreachable_states, bool prune_irrelevant_states, + int max_states, int max_states_before_merge, + int threshold_before_merge, double main_loop_max_time, + utils::Verbosity verbosity); FactoredTransitionSystem build_factored_transition_system(const TaskProxy &task_proxy); }; extern void add_merge_and_shrink_algorithm_options_to_feature(plugins::Feature &feature); +std::tuple, + std::shared_ptr, + std::shared_ptr, bool, bool, int, int, int, + double> +get_merge_and_shrink_algorithm_arguments_from_options( + const plugins::Options &opts); extern void add_transition_system_size_limit_options_to_feature(plugins::Feature &feature); +std::tuple +get_transition_system_size_limit_arguments_from_options( + const plugins::Options &opts); extern void handle_shrink_limit_options_defaults(plugins::Options &opts, const utils::Context &context); } diff --git a/src/search/merge_and_shrink/merge_and_shrink_heuristic.cc b/src/search/merge_and_shrink/merge_and_shrink_heuristic.cc index c35f251c9..50940d84d 100644 --- a/src/search/merge_and_shrink/merge_and_shrink_heuristic.cc +++ b/src/search/merge_and_shrink/merge_and_shrink_heuristic.cc @@ -20,10 +20,22 @@ using namespace std; using utils::ExitCode; namespace merge_and_shrink { -MergeAndShrinkHeuristic::MergeAndShrinkHeuristic(const plugins::Options &opts) - : Heuristic(opts) { +MergeAndShrinkHeuristic::MergeAndShrinkHeuristic( + const shared_ptr &merge_strategy, + const shared_ptr &shrink_strategy, + const shared_ptr &label_reduction, + bool prune_unreachable_states, bool prune_irrelevant_states, + int max_states, int max_states_before_merge, + int threshold_before_merge, double main_loop_max_time, + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : Heuristic(transform, cache_estimates, description, verbosity) { log << "Initializing merge-and-shrink heuristic..." << endl; - MergeAndShrinkAlgorithm algorithm(opts); + MergeAndShrinkAlgorithm algorithm( + merge_strategy, shrink_strategy, label_reduction, max_states, + max_states_before_merge, threshold_before_merge, + prune_unreachable_states, prune_irrelevant_states, + main_loop_max_time, verbosity); FactoredTransitionSystem fts = algorithm.build_factored_transition_system(task_proxy); extract_factors(fts); log << "Done initializing merge-and-shrink heuristic." << endl << endl; @@ -122,7 +134,8 @@ int MergeAndShrinkHeuristic::compute_heuristic(const State &ancestor_state) { return heuristic; } -class MergeAndShrinkHeuristicFeature : public plugins::TypedFeature { +class MergeAndShrinkHeuristicFeature + : public plugins::TypedFeature { public: MergeAndShrinkHeuristicFeature() : TypedFeature("merge_and_shrink") { document_title("Merge-and-shrink heuristic"); @@ -171,8 +184,8 @@ class MergeAndShrinkHeuristicFeature : public plugins::TypedFeature create_component(const plugins::Options &options, const utils::Context &context) const override { - plugins::Options options_copy(options); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &context) const override { + plugins::Options options_copy(opts); handle_shrink_limit_options_defaults(options_copy, context); - return make_shared(options_copy); + + return plugins::make_shared_from_arg_tuples( + get_merge_and_shrink_algorithm_arguments_from_options(options_copy), + get_heuristic_arguments_from_options(options_copy) + ); } }; diff --git a/src/search/merge_and_shrink/merge_and_shrink_heuristic.h b/src/search/merge_and_shrink/merge_and_shrink_heuristic.h index 701c0144d..2f1f5f63f 100644 --- a/src/search/merge_and_shrink/merge_and_shrink_heuristic.h +++ b/src/search/merge_and_shrink/merge_and_shrink_heuristic.h @@ -9,6 +9,10 @@ namespace merge_and_shrink { class FactoredTransitionSystem; class MergeAndShrinkRepresentation; +class MergeStrategyFactory; +class ShrinkStrategy; +class LabelReduction; + class MergeAndShrinkHeuristic : public Heuristic { // The final merge-and-shrink representations, storing goal distances. std::vector> mas_representations; @@ -20,7 +24,16 @@ class MergeAndShrinkHeuristic : public Heuristic { protected: virtual int compute_heuristic(const State &ancestor_state) override; public: - explicit MergeAndShrinkHeuristic(const plugins::Options &opts); + MergeAndShrinkHeuristic( + const std::shared_ptr &merge_strategy, + const std::shared_ptr &shrink_strategy, + const std::shared_ptr &label_reduction, + bool prune_unreachable_states, bool prune_irrelevant_states, + int max_states, int max_states_before_merge, + int threshold_before_merge, double main_loop_max_time, + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); }; } diff --git a/src/search/merge_and_shrink/merge_scoring_function_dfp.cc b/src/search/merge_and_shrink/merge_scoring_function_dfp.cc index 7b745ce8d..29974d26d 100644 --- a/src/search/merge_and_shrink/merge_scoring_function_dfp.cc +++ b/src/search/merge_and_shrink/merge_scoring_function_dfp.cc @@ -100,7 +100,8 @@ string MergeScoringFunctionDFP::name() const { return "dfp"; } -class MergeScoringFunctionDFPFeature : public plugins::TypedFeature { +class MergeScoringFunctionDFPFeature + : public plugins::TypedFeature { public: MergeScoringFunctionDFPFeature() : TypedFeature("dfp") { document_title("DFP scoring"); diff --git a/src/search/merge_and_shrink/merge_scoring_function_dfp.h b/src/search/merge_and_shrink/merge_scoring_function_dfp.h index f2de9cbee..dff7ba5af 100644 --- a/src/search/merge_and_shrink/merge_scoring_function_dfp.h +++ b/src/search/merge_and_shrink/merge_scoring_function_dfp.h @@ -8,7 +8,6 @@ class MergeScoringFunctionDFP : public MergeScoringFunction { virtual std::string name() const override; public: MergeScoringFunctionDFP() = default; - virtual ~MergeScoringFunctionDFP() override = default; virtual std::vector compute_scores( const FactoredTransitionSystem &fts, const std::vector> &merge_candidates) override; diff --git a/src/search/merge_and_shrink/merge_scoring_function_goal_relevance.cc b/src/search/merge_and_shrink/merge_scoring_function_goal_relevance.cc index f92fdc553..75e315b80 100644 --- a/src/search/merge_and_shrink/merge_scoring_function_goal_relevance.cc +++ b/src/search/merge_and_shrink/merge_scoring_function_goal_relevance.cc @@ -39,7 +39,8 @@ string MergeScoringFunctionGoalRelevance::name() const { return "goal relevance"; } -class MergeScoringFunctionGoalRelevanceFeature : public plugins::TypedFeature { +class MergeScoringFunctionGoalRelevanceFeature + : public plugins::TypedFeature { public: MergeScoringFunctionGoalRelevanceFeature() : TypedFeature("goal_relevance") { document_title("Goal relevance scoring"); diff --git a/src/search/merge_and_shrink/merge_scoring_function_goal_relevance.h b/src/search/merge_and_shrink/merge_scoring_function_goal_relevance.h index a1dceffa3..99c33a2ab 100644 --- a/src/search/merge_and_shrink/merge_scoring_function_goal_relevance.h +++ b/src/search/merge_and_shrink/merge_scoring_function_goal_relevance.h @@ -8,7 +8,6 @@ class MergeScoringFunctionGoalRelevance : public MergeScoringFunction { virtual std::string name() const override; public: MergeScoringFunctionGoalRelevance() = default; - virtual ~MergeScoringFunctionGoalRelevance() override = default; virtual std::vector compute_scores( const FactoredTransitionSystem &fts, const std::vector> &merge_candidates) override; diff --git a/src/search/merge_and_shrink/merge_scoring_function_miasm.cc b/src/search/merge_and_shrink/merge_scoring_function_miasm.cc index 7d5042abc..7fe4f1662 100644 --- a/src/search/merge_and_shrink/merge_scoring_function_miasm.cc +++ b/src/search/merge_and_shrink/merge_scoring_function_miasm.cc @@ -17,12 +17,14 @@ using namespace std; namespace merge_and_shrink { MergeScoringFunctionMIASM::MergeScoringFunctionMIASM( - const plugins::Options &options) - : use_caching(options.get("use_caching")), - shrink_strategy(options.get>("shrink_strategy")), - max_states(options.get("max_states")), - max_states_before_merge(options.get("max_states_before_merge")), - shrink_threshold_before_merge(options.get("threshold_before_merge")), + shared_ptr shrink_strategy, int max_states, + int max_states_before_merge, int threshold_before_merge, + bool use_caching) + : use_caching(use_caching), + shrink_strategy(move(shrink_strategy)), + max_states(max_states), + max_states_before_merge(max_states_before_merge), + shrink_threshold_before_merge(threshold_before_merge), silent_log(utils::get_silent_log()) { } @@ -97,7 +99,8 @@ string MergeScoringFunctionMIASM::name() const { return "miasm"; } -class MergeScoringFunctionMIASMFeature : public plugins::TypedFeature { +class MergeScoringFunctionMIASMFeature + : public plugins::TypedFeature { public: MergeScoringFunctionMIASMFeature() : TypedFeature("sf_miasm") { document_title("MIASM"); @@ -166,10 +169,17 @@ class MergeScoringFunctionMIASMFeature : public plugins::TypedFeature create_component(const plugins::Options &options, const utils::Context &context) const override { - plugins::Options options_copy(options); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &context) const override { + plugins::Options options_copy(opts); handle_shrink_limit_options_defaults(options_copy, context); - return make_shared(options_copy); + return plugins::make_shared_from_arg_tuples( + options_copy.get>("shrink_strategy"), + get_transition_system_size_limit_arguments_from_options( + options_copy), + options_copy.get("use_caching") + ); } }; diff --git a/src/search/merge_and_shrink/merge_scoring_function_miasm.h b/src/search/merge_and_shrink/merge_scoring_function_miasm.h index 3070085ed..a35e8877a 100644 --- a/src/search/merge_and_shrink/merge_scoring_function_miasm.h +++ b/src/search/merge_and_shrink/merge_scoring_function_miasm.h @@ -22,8 +22,10 @@ class MergeScoringFunctionMIASM : public MergeScoringFunction { virtual std::string name() const override; virtual void dump_function_specific_options(utils::LogProxy &log) const override; public: - explicit MergeScoringFunctionMIASM(const plugins::Options &options); - virtual ~MergeScoringFunctionMIASM() override = default; + MergeScoringFunctionMIASM( + std::shared_ptr shrink_strategy, + int max_states, int max_states_before_merge, + int threshold_before_merge, bool use_caching); virtual std::vector compute_scores( const FactoredTransitionSystem &fts, const std::vector> &merge_candidates) override; diff --git a/src/search/merge_and_shrink/merge_scoring_function_single_random.cc b/src/search/merge_and_shrink/merge_scoring_function_single_random.cc index 90e0eaf9b..113441c5b 100644 --- a/src/search/merge_and_shrink/merge_scoring_function_single_random.cc +++ b/src/search/merge_and_shrink/merge_scoring_function_single_random.cc @@ -13,9 +13,9 @@ using namespace std; namespace merge_and_shrink { MergeScoringFunctionSingleRandom::MergeScoringFunctionSingleRandom( - const plugins::Options &options) - : random_seed(options.get("random_seed")), - rng(utils::parse_rng_from_options(options)) { + int random_seed) + : random_seed(random_seed), + rng(utils::get_rng(random_seed)) { } vector MergeScoringFunctionSingleRandom::compute_scores( @@ -46,7 +46,8 @@ void MergeScoringFunctionSingleRandom::dump_function_specific_options( } } -class MergeScoringFunctionSingleRandomFeature : public plugins::TypedFeature { +class MergeScoringFunctionSingleRandomFeature + : public plugins::TypedFeature { public: MergeScoringFunctionSingleRandomFeature() : TypedFeature("single_random") { document_title("Single random"); @@ -54,7 +55,15 @@ class MergeScoringFunctionSingleRandomFeature : public plugins::TypedFeature + create_component(const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + utils::get_rng_arguments_from_options(opts) + ); } }; diff --git a/src/search/merge_and_shrink/merge_scoring_function_single_random.h b/src/search/merge_and_shrink/merge_scoring_function_single_random.h index d2e762544..285cf1fff 100644 --- a/src/search/merge_and_shrink/merge_scoring_function_single_random.h +++ b/src/search/merge_and_shrink/merge_scoring_function_single_random.h @@ -5,10 +5,6 @@ #include -namespace plugins { -class Options; -} - namespace utils { class RandomNumberGenerator; } @@ -21,8 +17,7 @@ class MergeScoringFunctionSingleRandom : public MergeScoringFunction { virtual std::string name() const override; virtual void dump_function_specific_options(utils::LogProxy &log) const override; public: - explicit MergeScoringFunctionSingleRandom(const plugins::Options &options); - virtual ~MergeScoringFunctionSingleRandom() override = default; + explicit MergeScoringFunctionSingleRandom(int random_seed); virtual std::vector compute_scores( const FactoredTransitionSystem &fts, const std::vector> &merge_candidates) override; diff --git a/src/search/merge_and_shrink/merge_scoring_function_total_order.cc b/src/search/merge_and_shrink/merge_scoring_function_total_order.cc index 8b26a37db..926409ee1 100644 --- a/src/search/merge_and_shrink/merge_scoring_function_total_order.cc +++ b/src/search/merge_and_shrink/merge_scoring_function_total_order.cc @@ -17,12 +17,13 @@ using namespace std; namespace merge_and_shrink { MergeScoringFunctionTotalOrder::MergeScoringFunctionTotalOrder( - const plugins::Options &options) - : atomic_ts_order(options.get("atomic_ts_order")), - product_ts_order(options.get("product_ts_order")), - atomic_before_product(options.get("atomic_before_product")), - random_seed(options.get("random_seed")), - rng(utils::parse_rng_from_options(options)) { + AtomicTSOrder atomic_ts_order, ProductTSOrder product_ts_order, + bool atomic_before_product, int random_seed) + : atomic_ts_order(atomic_ts_order), + product_ts_order(product_ts_order), + atomic_before_product(atomic_before_product), + random_seed(random_seed), + rng(utils::get_rng(random_seed)) { } vector MergeScoringFunctionTotalOrder::compute_scores( @@ -173,10 +174,11 @@ void MergeScoringFunctionTotalOrder::add_options_to_feature( "Consider atomic transition systems before composite ones iff true.", "false"); - utils::add_rng_options(feature); + utils::add_rng_options_to_feature(feature); } -class MergeScoringFunctionTotalOrderFeature : public plugins::TypedFeature { +class MergeScoringFunctionTotalOrderFeature + : public plugins::TypedFeature { public: MergeScoringFunctionTotalOrderFeature() : TypedFeature("total_order") { document_title("Total order"); @@ -201,6 +203,17 @@ class MergeScoringFunctionTotalOrderFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get("atomic_ts_order"), + opts.get("product_ts_order"), + opts.get("atomic_before_product"), + utils::get_rng_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/merge_and_shrink/merge_scoring_function_total_order.h b/src/search/merge_and_shrink/merge_scoring_function_total_order.h index 41d338633..3d2e974da 100644 --- a/src/search/merge_and_shrink/merge_scoring_function_total_order.h +++ b/src/search/merge_and_shrink/merge_scoring_function_total_order.h @@ -6,7 +6,6 @@ #include namespace plugins { -class Options; class Feature; } @@ -38,8 +37,9 @@ class MergeScoringFunctionTotalOrder : public MergeScoringFunction { virtual std::string name() const override; virtual void dump_function_specific_options(utils::LogProxy &log) const override; public: - explicit MergeScoringFunctionTotalOrder(const plugins::Options &options); - virtual ~MergeScoringFunctionTotalOrder() override = default; + explicit MergeScoringFunctionTotalOrder( + AtomicTSOrder atomic_ts_order, ProductTSOrder product_ts_order, + bool atomic_before_product, int random_seed); virtual std::vector compute_scores( const FactoredTransitionSystem &fts, const std::vector> &merge_candidates) override; diff --git a/src/search/merge_and_shrink/merge_selector_score_based_filtering.cc b/src/search/merge_and_shrink/merge_selector_score_based_filtering.cc index 772378a88..32c608eaf 100644 --- a/src/search/merge_and_shrink/merge_selector_score_based_filtering.cc +++ b/src/search/merge_and_shrink/merge_selector_score_based_filtering.cc @@ -11,10 +11,8 @@ using namespace std; namespace merge_and_shrink { MergeSelectorScoreBasedFiltering::MergeSelectorScoreBasedFiltering( - const plugins::Options &options) - : merge_scoring_functions( - options.get_list>( - "scoring_functions")) { + const vector> &scoring_functions) + : merge_scoring_functions(scoring_functions) { } static vector> get_remaining_candidates( @@ -104,7 +102,8 @@ bool MergeSelectorScoreBasedFiltering::requires_goal_distances() const { return false; } -class MergeSelectorScoreBasedFilteringFeature : public plugins::TypedFeature { +class MergeSelectorScoreBasedFilteringFeature + : public plugins::TypedFeature { public: MergeSelectorScoreBasedFilteringFeature() : TypedFeature("score_based_filtering") { document_title("Score based filtering merge selector"); @@ -117,6 +116,15 @@ class MergeSelectorScoreBasedFilteringFeature : public plugins::TypedFeature + create_component(const plugins::Options &opts, + const utils::Context &) const override { + return make_shared( + opts.get_list>( + "scoring_functions") + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/merge_and_shrink/merge_selector_score_based_filtering.h b/src/search/merge_and_shrink/merge_selector_score_based_filtering.h index 71a1c3a88..58009e3c8 100644 --- a/src/search/merge_and_shrink/merge_selector_score_based_filtering.h +++ b/src/search/merge_and_shrink/merge_selector_score_based_filtering.h @@ -18,8 +18,8 @@ class MergeSelectorScoreBasedFiltering : public MergeSelector { virtual std::string name() const override; virtual void dump_selector_specific_options(utils::LogProxy &log) const override; public: - explicit MergeSelectorScoreBasedFiltering(const plugins::Options &options); - virtual ~MergeSelectorScoreBasedFiltering() override = default; + explicit MergeSelectorScoreBasedFiltering( + const std::vector> &scoring_functions); virtual std::pair select_merge( const FactoredTransitionSystem &fts, const std::vector &indices_subset = std::vector()) const override; diff --git a/src/search/merge_and_shrink/merge_strategy_factory.cc b/src/search/merge_and_shrink/merge_strategy_factory.cc index 5858363e9..e3bf5083e 100644 --- a/src/search/merge_and_shrink/merge_strategy_factory.cc +++ b/src/search/merge_and_shrink/merge_strategy_factory.cc @@ -7,8 +7,8 @@ using namespace std; namespace merge_and_shrink { -MergeStrategyFactory::MergeStrategyFactory(const plugins::Options &options) - : log(utils::get_log_from_options(options)) { +MergeStrategyFactory::MergeStrategyFactory(utils::Verbosity verbosity) + : log(utils::get_log_for_verbosity(verbosity)) { } void MergeStrategyFactory::dump_options() const { @@ -23,6 +23,12 @@ void add_merge_strategy_options_to_feature(plugins::Feature &feature) { utils::add_log_options_to_feature(feature); } +tuple get_merge_strategy_arguments_from_options( + const plugins::Options &opts) { + return utils::get_log_arguments_from_options(opts); +} + + static class MergeStrategyFactoryCategoryPlugin : public plugins::TypedCategoryPlugin { public: MergeStrategyFactoryCategoryPlugin() : TypedCategoryPlugin("MergeStrategy") { diff --git a/src/search/merge_and_shrink/merge_strategy_factory.h b/src/search/merge_and_shrink/merge_strategy_factory.h index 004f7db51..9f1f5a93a 100644 --- a/src/search/merge_and_shrink/merge_strategy_factory.h +++ b/src/search/merge_and_shrink/merge_strategy_factory.h @@ -24,7 +24,7 @@ class MergeStrategyFactory { virtual std::string name() const = 0; virtual void dump_strategy_specific_options() const = 0; public: - explicit MergeStrategyFactory(const plugins::Options &options); + MergeStrategyFactory(utils::Verbosity verbosity); virtual ~MergeStrategyFactory() = default; void dump_options() const; virtual std::unique_ptr compute_merge_strategy( @@ -35,6 +35,9 @@ class MergeStrategyFactory { }; extern void add_merge_strategy_options_to_feature(plugins::Feature &feature); +extern std::tuple +get_merge_strategy_arguments_from_options( + const plugins::Options &opts); } #endif diff --git a/src/search/merge_and_shrink/merge_strategy_factory_precomputed.cc b/src/search/merge_and_shrink/merge_strategy_factory_precomputed.cc index b087a7d4c..0bc66dbd3 100644 --- a/src/search/merge_and_shrink/merge_strategy_factory_precomputed.cc +++ b/src/search/merge_and_shrink/merge_strategy_factory_precomputed.cc @@ -11,9 +11,10 @@ using namespace std; namespace merge_and_shrink { MergeStrategyFactoryPrecomputed::MergeStrategyFactoryPrecomputed( - const plugins::Options &options) - : MergeStrategyFactory(options), - merge_tree_factory(options.get>("merge_tree")) { + const shared_ptr &merge_tree, + utils::Verbosity verbosity) + : MergeStrategyFactory(verbosity), + merge_tree_factory(merge_tree) { } unique_ptr MergeStrategyFactoryPrecomputed::compute_merge_strategy( @@ -41,7 +42,8 @@ void MergeStrategyFactoryPrecomputed::dump_strategy_specific_options() const { } } -class MergeStrategyFactoryPrecomputedFeature : public plugins::TypedFeature { +class MergeStrategyFactoryPrecomputedFeature + : public plugins::TypedFeature { public: MergeStrategyFactoryPrecomputedFeature() : TypedFeature("merge_precomputed") { document_title("Precomputed merge strategy"); @@ -66,6 +68,14 @@ class MergeStrategyFactoryPrecomputedFeature : public plugins::TypedFeature))" "\n}}}"); } + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get>("merge_tree"), + get_merge_strategy_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/merge_and_shrink/merge_strategy_factory_precomputed.h b/src/search/merge_and_shrink/merge_strategy_factory_precomputed.h index e31fc7ead..4e5a308d3 100644 --- a/src/search/merge_and_shrink/merge_strategy_factory_precomputed.h +++ b/src/search/merge_and_shrink/merge_strategy_factory_precomputed.h @@ -12,8 +12,9 @@ class MergeStrategyFactoryPrecomputed : public MergeStrategyFactory { virtual std::string name() const override; virtual void dump_strategy_specific_options() const override; public: - explicit MergeStrategyFactoryPrecomputed(const plugins::Options &options); - virtual ~MergeStrategyFactoryPrecomputed() override = default; + MergeStrategyFactoryPrecomputed( + const std::shared_ptr &merge_tree, + utils::Verbosity verbosity); virtual std::unique_ptr compute_merge_strategy( const TaskProxy &task_proxy, const FactoredTransitionSystem &fts) override; diff --git a/src/search/merge_and_shrink/merge_strategy_factory_sccs.cc b/src/search/merge_and_shrink/merge_strategy_factory_sccs.cc index 2d9dd9ef9..89fdb3d7b 100644 --- a/src/search/merge_and_shrink/merge_strategy_factory_sccs.cc +++ b/src/search/merge_and_shrink/merge_strategy_factory_sccs.cc @@ -29,17 +29,15 @@ static bool compare_sccs_decreasing(const vector &lhs, const vector &r return lhs.size() > rhs.size(); } -MergeStrategyFactorySCCs::MergeStrategyFactorySCCs(const plugins::Options &options) - : MergeStrategyFactory(options), - order_of_sccs(options.get("order_of_sccs")), - merge_tree_factory(nullptr), - merge_selector(nullptr) { - if (options.contains("merge_tree")) { - merge_tree_factory = options.get>("merge_tree"); - } - if (options.contains("merge_selector")) { - merge_selector = options.get>("merge_selector"); - } +MergeStrategyFactorySCCs::MergeStrategyFactorySCCs( + const OrderOfSCCs &order_of_sccs, + const shared_ptr &merge_tree, + const shared_ptr &merge_selector, + utils::Verbosity verbosity) + : MergeStrategyFactory(verbosity), + order_of_sccs(order_of_sccs), + merge_tree_factory(merge_tree), + merge_selector(merge_selector) { } unique_ptr MergeStrategyFactorySCCs::compute_merge_strategy( @@ -156,7 +154,8 @@ string MergeStrategyFactorySCCs::name() const { return "sccs"; } -class MergeStrategyFactorySCCsFeature : public plugins::TypedFeature { +class MergeStrategyFactorySCCsFeature + : public plugins::TypedFeature { public: MergeStrategyFactorySCCsFeature() : TypedFeature("merge_sccs") { document_title("Merge strategy SSCs"); @@ -196,15 +195,24 @@ class MergeStrategyFactorySCCsFeature : public plugins::TypedFeature create_component(const plugins::Options &options, const utils::Context &context) const override { - bool merge_tree = options.contains("merge_tree"); - bool merge_selector = options.contains("merge_selector"); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &context) const override { + bool merge_tree = opts.contains("merge_tree"); + bool merge_selector = opts.contains("merge_selector"); if ((merge_tree && merge_selector) || (!merge_tree && !merge_selector)) { context.error( "You have to specify exactly one of the options merge_tree " "and merge_selector!"); } - return make_shared(options); + return plugins::make_shared_from_arg_tuples( + opts.get("order_of_sccs"), + opts.get> ( + "merge_tree", nullptr), + opts.get> ( + "merge_selector", nullptr), + get_merge_strategy_arguments_from_options(opts) + ); } }; diff --git a/src/search/merge_and_shrink/merge_strategy_factory_sccs.h b/src/search/merge_and_shrink/merge_strategy_factory_sccs.h index a08fe7535..14816c474 100644 --- a/src/search/merge_and_shrink/merge_strategy_factory_sccs.h +++ b/src/search/merge_and_shrink/merge_strategy_factory_sccs.h @@ -22,8 +22,11 @@ class MergeStrategyFactorySCCs : public MergeStrategyFactory { virtual std::string name() const override; virtual void dump_strategy_specific_options() const override; public: - explicit MergeStrategyFactorySCCs(const plugins::Options &options); - virtual ~MergeStrategyFactorySCCs() override = default; + MergeStrategyFactorySCCs( + const OrderOfSCCs &order_of_sccs, + const std::shared_ptr &merge_tree, + const std::shared_ptr &merge_selector, + utils::Verbosity verbosity); virtual std::unique_ptr compute_merge_strategy( const TaskProxy &task_proxy, const FactoredTransitionSystem &fts) override; diff --git a/src/search/merge_and_shrink/merge_strategy_factory_stateless.cc b/src/search/merge_and_shrink/merge_strategy_factory_stateless.cc index 87dfd8b5e..81c49398e 100644 --- a/src/search/merge_and_shrink/merge_strategy_factory_stateless.cc +++ b/src/search/merge_and_shrink/merge_strategy_factory_stateless.cc @@ -10,9 +10,10 @@ using namespace std; namespace merge_and_shrink { MergeStrategyFactoryStateless::MergeStrategyFactoryStateless( - const plugins::Options &options) - : MergeStrategyFactory(options), - merge_selector(options.get>("merge_selector")) { + const shared_ptr &merge_selector, + utils::Verbosity verbosity) + : MergeStrategyFactory(verbosity), + merge_selector(merge_selector) { } unique_ptr MergeStrategyFactoryStateless::compute_merge_strategy( @@ -40,7 +41,8 @@ bool MergeStrategyFactoryStateless::requires_goal_distances() const { return merge_selector->requires_goal_distances(); } -class MergeStrategyFactoryStatelessFeature : public plugins::TypedFeature { +class MergeStrategyFactoryStatelessFeature + : public plugins::TypedFeature { public: MergeStrategyFactoryStatelessFeature() : TypedFeature("merge_stateless") { document_title("Stateless merge strategy"); @@ -68,6 +70,15 @@ class MergeStrategyFactoryStatelessFeature : public plugins::TypedFeature),total_order()]" "\n}}}"); } + + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get>("merge_selector"), + get_merge_strategy_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/merge_and_shrink/merge_strategy_factory_stateless.h b/src/search/merge_and_shrink/merge_strategy_factory_stateless.h index 037cc9c0c..5f50ae330 100644 --- a/src/search/merge_and_shrink/merge_strategy_factory_stateless.h +++ b/src/search/merge_and_shrink/merge_strategy_factory_stateless.h @@ -12,8 +12,9 @@ class MergeStrategyFactoryStateless : public MergeStrategyFactory { virtual std::string name() const override; virtual void dump_strategy_specific_options() const override; public: - explicit MergeStrategyFactoryStateless(const plugins::Options &options); - virtual ~MergeStrategyFactoryStateless() override = default; + MergeStrategyFactoryStateless( + const std::shared_ptr &merge_selector, + utils::Verbosity verbosity); virtual std::unique_ptr compute_merge_strategy( const TaskProxy &task_proxy, const FactoredTransitionSystem &fts) override; diff --git a/src/search/merge_and_shrink/merge_tree_factory.cc b/src/search/merge_and_shrink/merge_tree_factory.cc index c56279719..93acfc06f 100644 --- a/src/search/merge_and_shrink/merge_tree_factory.cc +++ b/src/search/merge_and_shrink/merge_tree_factory.cc @@ -12,9 +12,10 @@ using namespace std; namespace merge_and_shrink { -MergeTreeFactory::MergeTreeFactory(const plugins::Options &options) - : rng(utils::parse_rng_from_options(options)), - update_option(options.get("update_option")) { +MergeTreeFactory::MergeTreeFactory( + int random_seed, UpdateOption update_option) + : rng(utils::get_rng(random_seed)), + update_option(update_option) { } void MergeTreeFactory::dump_options(utils::LogProxy &log) const { @@ -45,8 +46,8 @@ unique_ptr MergeTreeFactory::compute_merge_tree( utils::exit_with(utils::ExitCode::SEARCH_CRITICAL_ERROR); } -void MergeTreeFactory::add_options_to_feature(plugins::Feature &feature) { - utils::add_rng_options(feature); +void add_merge_tree_options_to_feature(plugins::Feature &feature) { + utils::add_rng_options_to_feature(feature); feature.add_option( "update_option", "When the merge tree is used within another merge strategy, how " @@ -55,6 +56,14 @@ void MergeTreeFactory::add_options_to_feature(plugins::Feature &feature) { "use_random"); } +tuple get_merge_tree_arguments_from_options( + const plugins::Options &opts) { + return tuple_cat( + utils::get_rng_arguments_from_options(opts), + make_tuple(opts.get("update_option")) + ); +} + static class MergeTreeFactoryCategoryPlugin : public plugins::TypedCategoryPlugin { public: MergeTreeFactoryCategoryPlugin() : TypedCategoryPlugin("MergeTree") { diff --git a/src/search/merge_and_shrink/merge_tree_factory.h b/src/search/merge_and_shrink/merge_tree_factory.h index 1c98e0fe4..cf6c3b896 100644 --- a/src/search/merge_and_shrink/merge_tree_factory.h +++ b/src/search/merge_and_shrink/merge_tree_factory.h @@ -29,7 +29,7 @@ class MergeTreeFactory { virtual std::string name() const = 0; virtual void dump_tree_specific_options(utils::LogProxy &) const {} public: - explicit MergeTreeFactory(const plugins::Options &options); + MergeTreeFactory(int random_seed, UpdateOption update_option); virtual ~MergeTreeFactory() = default; void dump_options(utils::LogProxy &log) const; // Compute a merge tree for the given entire task. @@ -43,9 +43,13 @@ class MergeTreeFactory { const std::vector &indices_subset); virtual bool requires_init_distances() const = 0; virtual bool requires_goal_distances() const = 0; - // Derived classes must call this method in their parsing methods. - static void add_options_to_feature(plugins::Feature &feature); }; + +// Derived classes must call this method in their parsing methods. +extern void add_merge_tree_options_to_feature( + plugins::Feature &feature); +extern std::tuple +get_merge_tree_arguments_from_options(const plugins::Options &opts); } #endif diff --git a/src/search/merge_and_shrink/merge_tree_factory_linear.cc b/src/search/merge_and_shrink/merge_tree_factory_linear.cc index 6a705c75b..8b3010509 100644 --- a/src/search/merge_and_shrink/merge_tree_factory_linear.cc +++ b/src/search/merge_and_shrink/merge_tree_factory_linear.cc @@ -17,11 +17,11 @@ using namespace std; namespace merge_and_shrink { -MergeTreeFactoryLinear::MergeTreeFactoryLinear(const plugins::Options &options) - : MergeTreeFactory(options), - variable_order_type( - options.get("variable_order")), - rng(utils::parse_rng_from_options(options)) { +MergeTreeFactoryLinear::MergeTreeFactoryLinear( + variable_order_finder::VariableOrderType variable_order, + int random_seed, UpdateOption update_option) + : MergeTreeFactory(random_seed, update_option), + variable_order_type(variable_order) { } unique_ptr MergeTreeFactoryLinear::compute_merge_tree( @@ -109,14 +109,15 @@ void MergeTreeFactoryLinear::dump_tree_specific_options(utils::LogProxy &log) co } void MergeTreeFactoryLinear::add_options_to_feature(plugins::Feature &feature) { - MergeTreeFactory::add_options_to_feature(feature); feature.add_option( "variable_order", "the order in which atomic transition systems are merged", "cg_goal_level"); + add_merge_tree_options_to_feature(feature); } -class MergeTreeFactoryLinearFeature : public plugins::TypedFeature { +class MergeTreeFactoryLinearFeature + : public plugins::TypedFeature { public: MergeTreeFactoryLinearFeature() : TypedFeature("linear") { document_title("Linear merge trees"); @@ -134,6 +135,16 @@ class MergeTreeFactoryLinearFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get( + "variable_order"), + get_merge_tree_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/merge_and_shrink/merge_tree_factory_linear.h b/src/search/merge_and_shrink/merge_tree_factory_linear.h index b88e8f5f7..516ba2e2d 100644 --- a/src/search/merge_and_shrink/merge_tree_factory_linear.h +++ b/src/search/merge_and_shrink/merge_tree_factory_linear.h @@ -17,8 +17,9 @@ class MergeTreeFactoryLinear : public MergeTreeFactory { virtual std::string name() const override; virtual void dump_tree_specific_options(utils::LogProxy &log) const override; public: - explicit MergeTreeFactoryLinear(const plugins::Options &options); - virtual ~MergeTreeFactoryLinear() override = default; + MergeTreeFactoryLinear( + variable_order_finder::VariableOrderType variable_order, + int random_seed, UpdateOption update_option); virtual std::unique_ptr compute_merge_tree( const TaskProxy &task_proxy) override; virtual std::unique_ptr compute_merge_tree( diff --git a/src/search/merge_and_shrink/shrink_bisimulation.cc b/src/search/merge_and_shrink/shrink_bisimulation.cc index 683a06948..34f960707 100644 --- a/src/search/merge_and_shrink/shrink_bisimulation.cc +++ b/src/search/merge_and_shrink/shrink_bisimulation.cc @@ -93,9 +93,9 @@ struct Signature { }; -ShrinkBisimulation::ShrinkBisimulation(const plugins::Options &opts) - : greedy(opts.get("greedy")), - at_limit(opts.get("at_limit")) { +ShrinkBisimulation::ShrinkBisimulation(bool greedy, AtLimit at_limit) + : greedy(greedy), + at_limit(at_limit) { } int ShrinkBisimulation::initialize_groups( @@ -376,7 +376,8 @@ void ShrinkBisimulation::dump_strategy_specific_options(utils::LogProxy &log) co } } -class ShrinkBisimulationFeature : public plugins::TypedFeature { +class ShrinkBisimulationFeature + : public plugins::TypedFeature { public: ShrinkBisimulationFeature() : TypedFeature("shrink_bisimulation") { document_title("Bismulation based shrink strategy"); @@ -420,6 +421,15 @@ class ShrinkBisimulationFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return make_shared( + opts.get("greedy"), + opts.get("at_limit") + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/merge_and_shrink/shrink_bisimulation.h b/src/search/merge_and_shrink/shrink_bisimulation.h index 172e45923..58a023ec4 100644 --- a/src/search/merge_and_shrink/shrink_bisimulation.h +++ b/src/search/merge_and_shrink/shrink_bisimulation.h @@ -3,10 +3,6 @@ #include "shrink_strategy.h" -namespace plugins { -class Options; -} - namespace merge_and_shrink { struct Signature; @@ -39,8 +35,7 @@ class ShrinkBisimulation : public ShrinkStrategy { virtual void dump_strategy_specific_options(utils::LogProxy &log) const override; virtual std::string name() const override; public: - explicit ShrinkBisimulation(const plugins::Options &opts); - virtual ~ShrinkBisimulation() override = default; + explicit ShrinkBisimulation(bool greedy, AtLimit at_limit); virtual StateEquivalenceRelation compute_equivalence_relation( const TransitionSystem &ts, const Distances &distances, diff --git a/src/search/merge_and_shrink/shrink_bucket_based.cc b/src/search/merge_and_shrink/shrink_bucket_based.cc index f49042172..0465f23c5 100644 --- a/src/search/merge_and_shrink/shrink_bucket_based.cc +++ b/src/search/merge_and_shrink/shrink_bucket_based.cc @@ -1,5 +1,6 @@ #include "shrink_bucket_based.h" +#include "../plugins/plugin.h" #include "../utils/logging.h" #include "../utils/rng.h" #include "../utils/rng_options.h" @@ -11,12 +12,8 @@ using namespace std; namespace merge_and_shrink { -ShrinkBucketBased::ShrinkBucketBased(const plugins::Options &opts) - : rng(utils::parse_rng_from_options(opts)) { -} - -void ShrinkBucketBased::add_options_to_feature(plugins::Feature &feature) { - utils::add_rng_options(feature); +ShrinkBucketBased::ShrinkBucketBased(int random_seed) + : rng(utils::get_rng(random_seed)) { } StateEquivalenceRelation ShrinkBucketBased::compute_abstraction( @@ -99,4 +96,13 @@ StateEquivalenceRelation ShrinkBucketBased::compute_equivalence_relation( vector buckets = partition_into_buckets(ts, distances); return compute_abstraction(buckets, target_size, log); } + +void add_shrink_bucket_options_to_feature(plugins::Feature &feature) { + utils::add_rng_options_to_feature(feature); +} + +tuple get_shrink_bucket_arguments_from_options( + const plugins::Options &opts) { + return utils::get_rng_arguments_from_options(opts); +} } diff --git a/src/search/merge_and_shrink/shrink_bucket_based.h b/src/search/merge_and_shrink/shrink_bucket_based.h index 749b8f7e4..46caaf74a 100644 --- a/src/search/merge_and_shrink/shrink_bucket_based.h +++ b/src/search/merge_and_shrink/shrink_bucket_based.h @@ -51,15 +51,18 @@ class ShrinkBucketBased : public ShrinkStrategy { const TransitionSystem &ts, const Distances &Distances) const = 0; public: - explicit ShrinkBucketBased(const plugins::Options &opts); - virtual ~ShrinkBucketBased() override = default; + explicit ShrinkBucketBased(int random_seed); virtual StateEquivalenceRelation compute_equivalence_relation( const TransitionSystem &ts, const Distances &distances, int target_size, utils::LogProxy &log) const override; - static void add_options_to_feature(plugins::Feature &feature); }; + +extern void add_shrink_bucket_options_to_feature( + plugins::Feature &feature); +extern std::tuple get_shrink_bucket_arguments_from_options( + const plugins::Options &opts); } #endif diff --git a/src/search/merge_and_shrink/shrink_fh.cc b/src/search/merge_and_shrink/shrink_fh.cc index 6a334cfd5..d2846891c 100644 --- a/src/search/merge_and_shrink/shrink_fh.cc +++ b/src/search/merge_and_shrink/shrink_fh.cc @@ -19,10 +19,10 @@ using namespace std; namespace merge_and_shrink { -ShrinkFH::ShrinkFH(const plugins::Options &opts) - : ShrinkBucketBased(opts), - f_start(opts.get("shrink_f")), - h_start(opts.get("shrink_h")) { +ShrinkFH::ShrinkFH(HighLow shrink_f, HighLow shrink_h, int random_seed) + : ShrinkBucketBased(random_seed), + f_start(shrink_f), + h_start(shrink_h) { } vector ShrinkFH::partition_into_buckets( @@ -189,7 +189,8 @@ void ShrinkFH::dump_strategy_specific_options(utils::LogProxy &log) const { } } -class ShrinkFHFeature : public plugins::TypedFeature { +class ShrinkFHFeature + : public plugins::TypedFeature { public: ShrinkFHFeature() : TypedFeature("shrink_fh") { document_title("f-preserving shrink strategy"); @@ -205,7 +206,6 @@ class ShrinkFHFeature : public plugins::TypedFeature { "AAAI Press", "2007")); - ShrinkBucketBased::add_options_to_feature(*this); add_option( "shrink_f", "in which direction the f based shrink priority is ordered", @@ -214,6 +214,7 @@ class ShrinkFHFeature : public plugins::TypedFeature { "shrink_h", "in which direction the h based shrink priority is ordered", "low"); + add_shrink_bucket_options_to_feature(*this); document_note( "Note", @@ -242,6 +243,16 @@ class ShrinkFHFeature : public plugins::TypedFeature { "approach for partitioning states rather than the more efficient " "vector-based approach."); } + + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get("shrink_f"), + opts.get("shrink_h"), + get_shrink_bucket_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/merge_and_shrink/shrink_fh.h b/src/search/merge_and_shrink/shrink_fh.h index ff5214a5b..5ebaac8e1 100644 --- a/src/search/merge_and_shrink/shrink_fh.h +++ b/src/search/merge_and_shrink/shrink_fh.h @@ -46,8 +46,7 @@ class ShrinkFH : public ShrinkBucketBased { const Distances &distances) const override; public: - explicit ShrinkFH(const plugins::Options &opts); - virtual ~ShrinkFH() override = default; + ShrinkFH(HighLow shrink_f, HighLow shrink_h, int random_seed); virtual bool requires_init_distances() const override { return true; diff --git a/src/search/merge_and_shrink/shrink_random.cc b/src/search/merge_and_shrink/shrink_random.cc index 7b05ab05d..9b504a804 100644 --- a/src/search/merge_and_shrink/shrink_random.cc +++ b/src/search/merge_and_shrink/shrink_random.cc @@ -11,8 +11,8 @@ using namespace std; namespace merge_and_shrink { -ShrinkRandom::ShrinkRandom(const plugins::Options &opts) - : ShrinkBucketBased(opts) { +ShrinkRandom::ShrinkRandom(int random_seed) + : ShrinkBucketBased(random_seed) { } vector ShrinkRandom::partition_into_buckets( @@ -33,13 +33,22 @@ string ShrinkRandom::name() const { return "random"; } -class ShrinkRandomFeature : public plugins::TypedFeature { +class ShrinkRandomFeature + : public plugins::TypedFeature { public: ShrinkRandomFeature() : TypedFeature("shrink_random") { document_title("Random"); document_synopsis(""); - ShrinkBucketBased::add_options_to_feature(*this); + add_shrink_bucket_options_to_feature(*this); + } + + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_shrink_bucket_arguments_from_options(opts) + ); } }; diff --git a/src/search/merge_and_shrink/shrink_random.h b/src/search/merge_and_shrink/shrink_random.h index 19ee694b5..92592ce54 100644 --- a/src/search/merge_and_shrink/shrink_random.h +++ b/src/search/merge_and_shrink/shrink_random.h @@ -3,10 +3,6 @@ #include "shrink_bucket_based.h" -namespace plugins { -class Options; -} - namespace merge_and_shrink { class ShrinkRandom : public ShrinkBucketBased { protected: @@ -17,8 +13,7 @@ class ShrinkRandom : public ShrinkBucketBased { virtual std::string name() const override; void dump_strategy_specific_options(utils::LogProxy &) const override {} public: - explicit ShrinkRandom(const plugins::Options &opts); - virtual ~ShrinkRandom() override = default; + explicit ShrinkRandom(int random_seed); virtual bool requires_init_distances() const override { return false; diff --git a/src/search/open_list_factory.cc b/src/search/open_list_factory.cc index 8e89087f4..7da73c3c9 100644 --- a/src/search/open_list_factory.cc +++ b/src/search/open_list_factory.cc @@ -1,5 +1,6 @@ #include "open_list_factory.h" +#include "plugins/options.h" #include "plugins/plugin.h" using namespace std; @@ -15,6 +16,19 @@ unique_ptr OpenListFactory::create_open_list() { return create_edge_open_list(); } +void add_open_list_options_to_feature( + plugins::Feature &feature) { + feature.add_option( + "pref_only", + "insert only nodes generated by preferred operators", + "false"); +} + +tuple get_open_list_arguments_from_options( + const plugins::Options &opts) { + return make_tuple(opts.get("pref_only")); +} + static class OpenListFactoryCategoryPlugin : public plugins::TypedCategoryPlugin { public: OpenListFactoryCategoryPlugin() : TypedCategoryPlugin("OpenList") { diff --git a/src/search/open_list_factory.h b/src/search/open_list_factory.h index ed0ab806b..c8d436550 100644 --- a/src/search/open_list_factory.h +++ b/src/search/open_list_factory.h @@ -3,6 +3,8 @@ #include "open_list.h" +#include "plugins/plugin.h" + #include @@ -26,4 +28,9 @@ class OpenListFactory { std::unique_ptr> create_open_list(); }; + +extern void add_open_list_options_to_feature( + plugins::Feature &feature); +extern std::tuple +get_open_list_arguments_from_options(const plugins::Options &opts); #endif diff --git a/src/search/open_lists/alternation_open_list.cc b/src/search/open_lists/alternation_open_list.cc index 6518d0340..69565583b 100644 --- a/src/search/open_lists/alternation_open_list.cc +++ b/src/search/open_lists/alternation_open_list.cc @@ -25,8 +25,8 @@ class AlternationOpenList : public OpenList { const Entry &entry) override; public: - explicit AlternationOpenList(const plugins::Options &opts); - virtual ~AlternationOpenList() override = default; + AlternationOpenList( + const vector> &sublists, int boost); virtual Entry remove_min() override; virtual bool empty() const override; @@ -42,10 +42,10 @@ class AlternationOpenList : public OpenList { template -AlternationOpenList::AlternationOpenList(const plugins::Options &opts) - : boost_amount(opts.get("boost")) { - vector> open_list_factories( - opts.get_list>("sublists")); +AlternationOpenList::AlternationOpenList( + const vector> &sublists, int boost) + : boost_amount(boost) { + vector> open_list_factories(sublists); open_lists.reserve(open_list_factories.size()); for (const auto &factory : open_list_factories) open_lists.push_back(factory->create_open_list()); @@ -127,21 +127,26 @@ bool AlternationOpenList::is_reliable_dead_end( } -AlternationOpenListFactory::AlternationOpenListFactory(const plugins::Options &options) - : options(options) { +AlternationOpenListFactory::AlternationOpenListFactory( + const vector> &sublists, int boost) + : sublists(sublists), + boost(boost) { } unique_ptr AlternationOpenListFactory::create_state_open_list() { - return utils::make_unique_ptr>(options); + return utils::make_unique_ptr>( + sublists, boost); } unique_ptr AlternationOpenListFactory::create_edge_open_list() { - return utils::make_unique_ptr>(options); + return utils::make_unique_ptr>( + sublists, boost); } -class AlternationOpenListFeature : public plugins::TypedFeature { +class AlternationOpenListFeature + : public plugins::TypedFeature { public: AlternationOpenListFeature() : TypedFeature("alt") { document_title("Alternation open list"); @@ -158,9 +163,15 @@ class AlternationOpenListFeature : public plugins::TypedFeature create_component(const plugins::Options &options, const utils::Context &context) const override { - plugins::verify_list_non_empty>(context, options, "sublists"); - return make_shared(options); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &context) const override { + plugins::verify_list_non_empty>( + context, opts, "sublists"); + return plugins::make_shared_from_arg_tuples( + opts.get_list>("sublists"), + opts.get("boost") + ); } }; diff --git a/src/search/open_lists/alternation_open_list.h b/src/search/open_lists/alternation_open_list.h index ab9cef95b..edcd3e2af 100644 --- a/src/search/open_lists/alternation_open_list.h +++ b/src/search/open_lists/alternation_open_list.h @@ -2,14 +2,15 @@ #define OPEN_LISTS_ALTERNATION_OPEN_LIST_H #include "../open_list_factory.h" -#include "../plugins/options.h" namespace alternation_open_list { class AlternationOpenListFactory : public OpenListFactory { - plugins::Options options; + std::vector> sublists; + int boost; public: - explicit AlternationOpenListFactory(const plugins::Options &options); - virtual ~AlternationOpenListFactory() override = default; + AlternationOpenListFactory( + const std::vector> &sublists, + int boost); virtual std::unique_ptr create_state_open_list() override; virtual std::unique_ptr create_edge_open_list() override; diff --git a/src/search/open_lists/best_first_open_list.cc b/src/search/open_lists/best_first_open_list.cc index eda66c79b..328d96de8 100644 --- a/src/search/open_lists/best_first_open_list.cc +++ b/src/search/open_lists/best_first_open_list.cc @@ -27,9 +27,7 @@ class BestFirstOpenList : public OpenList { const Entry &entry) override; public: - explicit BestFirstOpenList(const plugins::Options &opts); BestFirstOpenList(const shared_ptr &eval, bool preferred_only); - virtual ~BestFirstOpenList() override = default; virtual Entry remove_min() override; virtual bool empty() const override; @@ -41,14 +39,6 @@ class BestFirstOpenList : public OpenList { EvaluationContext &eval_context) const override; }; - -template -BestFirstOpenList::BestFirstOpenList(const plugins::Options &opts) - : OpenList(opts.get("pref_only")), - size(0), - evaluator(opts.get>("eval")) { -} - template BestFirstOpenList::BestFirstOpenList( const shared_ptr &evaluator, bool preferred_only) @@ -110,21 +100,25 @@ bool BestFirstOpenList::is_reliable_dead_end( } BestFirstOpenListFactory::BestFirstOpenListFactory( - const plugins::Options &options) - : options(options) { + const shared_ptr &eval, bool pref_only) + : eval(eval), + pref_only(pref_only) { } unique_ptr BestFirstOpenListFactory::create_state_open_list() { - return utils::make_unique_ptr>(options); + return utils::make_unique_ptr>( + eval, pref_only); } unique_ptr BestFirstOpenListFactory::create_edge_open_list() { - return utils::make_unique_ptr>(options); + return utils::make_unique_ptr>( + eval, pref_only); } -class BestFirstOpenListFeature : public plugins::TypedFeature { +class BestFirstOpenListFeature + : public plugins::TypedFeature { public: BestFirstOpenListFeature() : TypedFeature("single") { document_title("Best-first open list"); @@ -132,9 +126,7 @@ class BestFirstOpenListFeature : public plugins::TypedFeature>("eval", "evaluator"); - add_option( - "pref_only", - "insert only nodes generated by preferred operators", "false"); + add_open_list_options_to_feature(*this); document_note( "Implementation Notes", @@ -144,6 +136,15 @@ class BestFirstOpenListFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get>("eval"), + get_open_list_arguments_from_options(opts)); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/open_lists/best_first_open_list.h b/src/search/open_lists/best_first_open_list.h index 812f55ab9..f0f95ecdb 100644 --- a/src/search/open_lists/best_first_open_list.h +++ b/src/search/open_lists/best_first_open_list.h @@ -3,8 +3,6 @@ #include "../open_list_factory.h" -#include "../plugins/options.h" - /* Open list indexed by a single int, using FIFO tie-breaking. @@ -13,10 +11,11 @@ namespace standard_scalar_open_list { class BestFirstOpenListFactory : public OpenListFactory { - plugins::Options options; + std::shared_ptr eval; + bool pref_only; public: - explicit BestFirstOpenListFactory(const plugins::Options &options); - virtual ~BestFirstOpenListFactory() override = default; + BestFirstOpenListFactory( + const std::shared_ptr &eval, bool pref_only); virtual std::unique_ptr create_state_open_list() override; virtual std::unique_ptr create_edge_open_list() override; diff --git a/src/search/open_lists/epsilon_greedy_open_list.cc b/src/search/open_lists/epsilon_greedy_open_list.cc index 087ad2808..026020cf3 100644 --- a/src/search/open_lists/epsilon_greedy_open_list.cc +++ b/src/search/open_lists/epsilon_greedy_open_list.cc @@ -45,8 +45,9 @@ class EpsilonGreedyOpenList : public OpenList { const Entry &entry) override; public: - explicit EpsilonGreedyOpenList(const plugins::Options &opts); - virtual ~EpsilonGreedyOpenList() override = default; + EpsilonGreedyOpenList( + const shared_ptr &eval, double epsilon, + int random_seed, bool pref_only); virtual Entry remove_min() override; virtual bool is_dead_end( @@ -81,11 +82,13 @@ void EpsilonGreedyOpenList::do_insertion( } template -EpsilonGreedyOpenList::EpsilonGreedyOpenList(const plugins::Options &opts) - : OpenList(opts.get("pref_only")), - rng(utils::parse_rng_from_options(opts)), - evaluator(opts.get>("eval")), - epsilon(opts.get("epsilon")), +EpsilonGreedyOpenList::EpsilonGreedyOpenList( + const shared_ptr &eval, double epsilon, + int random_seed, bool pref_only) + : OpenList(pref_only), + rng(utils::get_rng(random_seed)), + evaluator(eval), + epsilon(epsilon), size(0), next_id(0) { } @@ -136,21 +139,28 @@ void EpsilonGreedyOpenList::clear() { } EpsilonGreedyOpenListFactory::EpsilonGreedyOpenListFactory( - const plugins::Options &options) - : options(options) { + const shared_ptr &eval, double epsilon, + int random_seed, bool pref_only) + : eval(eval), + epsilon(epsilon), + random_seed(random_seed), + pref_only(pref_only) { } unique_ptr EpsilonGreedyOpenListFactory::create_state_open_list() { - return utils::make_unique_ptr>(options); + return utils::make_unique_ptr>( + eval, epsilon, random_seed, pref_only); } unique_ptr EpsilonGreedyOpenListFactory::create_edge_open_list() { - return utils::make_unique_ptr>(options); + return utils::make_unique_ptr>( + eval, epsilon, random_seed, pref_only); } -class EpsilonGreedyOpenListFeature : public plugins::TypedFeature { +class EpsilonGreedyOpenListFeature + : public plugins::TypedFeature { public: EpsilonGreedyOpenListFeature() : TypedFeature("epsilon_greedy") { document_title("Epsilon-greedy open list"); @@ -170,15 +180,24 @@ class EpsilonGreedyOpenListFeature : public plugins::TypedFeature>("eval", "evaluator"); - add_option( - "pref_only", - "insert only nodes generated by preferred operators", "false"); add_option( "epsilon", "probability for choosing the next entry randomly", "0.2", plugins::Bounds("0.0", "1.0")); - utils::add_rng_options(*this); + utils::add_rng_options_to_feature(*this); + add_open_list_options_to_feature(*this); + } + + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get>("eval"), + opts.get("epsilon"), + utils::get_rng_arguments_from_options(opts), + get_open_list_arguments_from_options(opts) + ); } }; diff --git a/src/search/open_lists/epsilon_greedy_open_list.h b/src/search/open_lists/epsilon_greedy_open_list.h index 32e99de4f..a72c34684 100644 --- a/src/search/open_lists/epsilon_greedy_open_list.h +++ b/src/search/open_lists/epsilon_greedy_open_list.h @@ -3,8 +3,6 @@ #include "../open_list_factory.h" -#include "../plugins/options.h" - /* Epsilon-greedy open list based on Valenzano et al. (ICAPS 2014). @@ -44,10 +42,14 @@ namespace epsilon_greedy_open_list { class EpsilonGreedyOpenListFactory : public OpenListFactory { - plugins::Options options; + std::shared_ptr eval; + double epsilon; + int random_seed; + bool pref_only; public: - explicit EpsilonGreedyOpenListFactory(const plugins::Options &options); - virtual ~EpsilonGreedyOpenListFactory() override = default; + EpsilonGreedyOpenListFactory( + const std::shared_ptr &eval, double epsilon, + int random_seed, bool pref_only); virtual std::unique_ptr create_state_open_list() override; virtual std::unique_ptr create_edge_open_list() override; diff --git a/src/search/open_lists/pareto_open_list.cc b/src/search/open_lists/pareto_open_list.cc index 711fe2a22..f6c75a3b6 100644 --- a/src/search/open_lists/pareto_open_list.cc +++ b/src/search/open_lists/pareto_open_list.cc @@ -43,8 +43,9 @@ class ParetoOpenList : public OpenList { const Entry &entry) override; public: - explicit ParetoOpenList(const plugins::Options &opts); - virtual ~ParetoOpenList() override = default; + ParetoOpenList( + const vector> &evals, + bool state_uniform_selection, int random_seed, bool pref_only); virtual Entry remove_min() override; virtual bool empty() const override; @@ -57,11 +58,13 @@ class ParetoOpenList : public OpenList { }; template -ParetoOpenList::ParetoOpenList(const plugins::Options &opts) - : OpenList(opts.get("pref_only")), - rng(utils::parse_rng_from_options(opts)), - state_uniform_selection(opts.get("state_uniform_selection")), - evaluators(opts.get_list>("evals")) { +ParetoOpenList::ParetoOpenList( + const vector> &evals, + bool state_uniform_selection, int random_seed, bool pref_only) + : OpenList(pref_only), + rng(utils::get_rng(random_seed)), + state_uniform_selection(state_uniform_selection), + evaluators(evals) { } template @@ -219,21 +222,28 @@ bool ParetoOpenList::is_reliable_dead_end( } ParetoOpenListFactory::ParetoOpenListFactory( - const plugins::Options &options) - : options(options) { + const vector> &evals, + bool state_uniform_selection, int random_seed, bool pref_only) + : evals(evals), + state_uniform_selection(state_uniform_selection), + random_seed(random_seed), + pref_only(pref_only) { } unique_ptr ParetoOpenListFactory::create_state_open_list() { - return utils::make_unique_ptr>(options); + return utils::make_unique_ptr>( + evals, state_uniform_selection, random_seed, pref_only); } unique_ptr ParetoOpenListFactory::create_edge_open_list() { - return utils::make_unique_ptr>(options); + return utils::make_unique_ptr>( + evals, state_uniform_selection, random_seed, pref_only); } -class ParetoOpenListFeature : public plugins::TypedFeature { +class ParetoOpenListFeature + : public plugins::TypedFeature { public: ParetoOpenListFeature() : TypedFeature("pareto") { document_title("Pareto open list"); @@ -242,9 +252,6 @@ class ParetoOpenListFeature : public plugins::TypedFeature>("evals", "evaluators"); - add_option( - "pref_only", - "insert only nodes generated by preferred operators", "false"); add_option( "state_uniform_selection", "When removing an entry, we select a non-dominated bucket " @@ -252,7 +259,19 @@ class ParetoOpenListFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get_list>("evals"), + opts.get("state_uniform_selection"), + utils::get_rng_arguments_from_options(opts), + get_open_list_arguments_from_options(opts) + ); } }; diff --git a/src/search/open_lists/pareto_open_list.h b/src/search/open_lists/pareto_open_list.h index e7a0f1f4f..d1771e8ef 100644 --- a/src/search/open_lists/pareto_open_list.h +++ b/src/search/open_lists/pareto_open_list.h @@ -3,14 +3,16 @@ #include "../open_list_factory.h" -#include "../plugins/options.h" - namespace pareto_open_list { class ParetoOpenListFactory : public OpenListFactory { - plugins::Options options; + std::vector> evals; + bool state_uniform_selection; + int random_seed; + bool pref_only; public: - explicit ParetoOpenListFactory(const plugins::Options &options); - virtual ~ParetoOpenListFactory() override = default; + ParetoOpenListFactory( + const std::vector> &evals, + bool state_uniform_selection, int random_seed, bool pref_only); virtual std::unique_ptr create_state_open_list() override; virtual std::unique_ptr create_edge_open_list() override; diff --git a/src/search/open_lists/tiebreaking_open_list.cc b/src/search/open_lists/tiebreaking_open_list.cc index 21f01785a..9811af17e 100644 --- a/src/search/open_lists/tiebreaking_open_list.cc +++ b/src/search/open_lists/tiebreaking_open_list.cc @@ -37,8 +37,9 @@ class TieBreakingOpenList : public OpenList { const Entry &entry) override; public: - explicit TieBreakingOpenList(const plugins::Options &opts); - virtual ~TieBreakingOpenList() override = default; + TieBreakingOpenList( + const vector> &evals, + bool unsafe_pruning, bool pref_only); virtual Entry remove_min() override; virtual bool empty() const override; @@ -52,10 +53,12 @@ class TieBreakingOpenList : public OpenList { template -TieBreakingOpenList::TieBreakingOpenList(const plugins::Options &opts) - : OpenList(opts.get("pref_only")), - size(0), evaluators(opts.get_list>("evals")), - allow_unsafe_pruning(opts.get("unsafe_pruning")) { +TieBreakingOpenList::TieBreakingOpenList( + const vector> &evals, + bool unsafe_pruning, bool pref_only) + : OpenList(pref_only), + size(0), evaluators(evals), + allow_unsafe_pruning(unsafe_pruning) { } template @@ -137,39 +140,51 @@ bool TieBreakingOpenList::is_reliable_dead_end( return false; } -TieBreakingOpenListFactory::TieBreakingOpenListFactory(const plugins::Options &options) - : options(options) { +TieBreakingOpenListFactory::TieBreakingOpenListFactory( + const vector> &evals, + bool unsafe_pruning, bool pref_only) + : evals(evals), + unsafe_pruning(unsafe_pruning), + pref_only(pref_only) { } unique_ptr TieBreakingOpenListFactory::create_state_open_list() { - return utils::make_unique_ptr>(options); + return utils::make_unique_ptr>( + evals, unsafe_pruning, pref_only); } unique_ptr TieBreakingOpenListFactory::create_edge_open_list() { - return utils::make_unique_ptr>(options); + return utils::make_unique_ptr>( + evals, unsafe_pruning, pref_only); } -class TieBreakingOpenListFeature : public plugins::TypedFeature { +class TieBreakingOpenListFeature + : public plugins::TypedFeature { public: TieBreakingOpenListFeature() : TypedFeature("tiebreaking") { document_title("Tie-breaking open list"); document_synopsis(""); add_list_option>("evals", "evaluators"); - add_option( - "pref_only", - "insert only nodes generated by preferred operators", "false"); add_option( "unsafe_pruning", "allow unsafe pruning when the main evaluator regards a state a dead end", "true"); + add_open_list_options_to_feature(*this); } - virtual shared_ptr create_component(const plugins::Options &options, const utils::Context &context) const override { - plugins::verify_list_non_empty>(context, options, "evals"); - return make_shared(options); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &context) const override { + plugins::verify_list_non_empty>( + context, opts, "evals"); + return plugins::make_shared_from_arg_tuples( + opts.get_list>("evals"), + opts.get("unsafe_pruning"), + get_open_list_arguments_from_options(opts) + ); } }; diff --git a/src/search/open_lists/tiebreaking_open_list.h b/src/search/open_lists/tiebreaking_open_list.h index abdb37faa..76a1e50a8 100644 --- a/src/search/open_lists/tiebreaking_open_list.h +++ b/src/search/open_lists/tiebreaking_open_list.h @@ -3,14 +3,15 @@ #include "../open_list_factory.h" -#include "../plugins/plugin.h" - namespace tiebreaking_open_list { class TieBreakingOpenListFactory : public OpenListFactory { - plugins::Options options; + std::vector> evals; + bool unsafe_pruning; + bool pref_only; public: - explicit TieBreakingOpenListFactory(const plugins::Options &options); - virtual ~TieBreakingOpenListFactory() override = default; + TieBreakingOpenListFactory( + const std::vector> &evals, + bool unsafe_pruning, bool pref_only); virtual std::unique_ptr create_state_open_list() override; virtual std::unique_ptr create_edge_open_list() override; diff --git a/src/search/open_lists/type_based_open_list.cc b/src/search/open_lists/type_based_open_list.cc index 72cf0c717..858eaa11b 100644 --- a/src/search/open_lists/type_based_open_list.cc +++ b/src/search/open_lists/type_based_open_list.cc @@ -20,8 +20,8 @@ using namespace std; namespace type_based_open_list { template class TypeBasedOpenList : public OpenList { - shared_ptr rng; vector> evaluators; + shared_ptr rng; using Key = vector; using Bucket = vector; @@ -33,8 +33,9 @@ class TypeBasedOpenList : public OpenList { EvaluationContext &eval_context, const Entry &entry) override; public: - explicit TypeBasedOpenList(const plugins::Options &opts); - virtual ~TypeBasedOpenList() override = default; + explicit TypeBasedOpenList( + const vector> &evaluators, + int random_seed); virtual Entry remove_min() override; virtual bool empty() const override; @@ -67,9 +68,10 @@ void TypeBasedOpenList::do_insertion( } template -TypeBasedOpenList::TypeBasedOpenList(const plugins::Options &opts) - : rng(utils::parse_rng_from_options(opts)), - evaluators(opts.get_list>("evaluators")) { +TypeBasedOpenList::TypeBasedOpenList( + const vector> &evaluators, int random_seed) + : evaluators(evaluators), + rng(utils::get_rng(random_seed)) { } template @@ -135,21 +137,25 @@ void TypeBasedOpenList::get_path_dependent_evaluators( } TypeBasedOpenListFactory::TypeBasedOpenListFactory( - const plugins::Options &options) - : options(options) { + const vector> &evaluators, int random_seed) + : evaluators(evaluators), + random_seed(random_seed) { } unique_ptr TypeBasedOpenListFactory::create_state_open_list() { - return utils::make_unique_ptr>(options); + return utils::make_unique_ptr>( + evaluators, random_seed); } unique_ptr TypeBasedOpenListFactory::create_edge_open_list() { - return utils::make_unique_ptr>(options); + return utils::make_unique_ptr>( + evaluators, random_seed); } -class TypeBasedOpenListFeature : public plugins::TypedFeature { +class TypeBasedOpenListFeature + : public plugins::TypedFeature { public: TypeBasedOpenListFeature() : TypedFeature("type_based") { document_title("Type-based open list"); @@ -173,12 +179,18 @@ class TypeBasedOpenListFeature : public plugins::TypedFeature>( "evaluators", "Evaluators used to determine the bucket for each entry."); - utils::add_rng_options(*this); + utils::add_rng_options_to_feature(*this); } - virtual shared_ptr create_component(const plugins::Options &options, const utils::Context &context) const override { - plugins::verify_list_non_empty>(context, options, "evaluators"); - return make_shared(options); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &context) const override { + plugins::verify_list_non_empty>( + context, opts, "evaluators"); + return plugins::make_shared_from_arg_tuples( + opts.get_list>("evaluators"), + utils::get_rng_arguments_from_options(opts) + ); } }; diff --git a/src/search/open_lists/type_based_open_list.h b/src/search/open_lists/type_based_open_list.h index 2aa5d0b77..5f81a3bd8 100644 --- a/src/search/open_lists/type_based_open_list.h +++ b/src/search/open_lists/type_based_open_list.h @@ -3,8 +3,6 @@ #include "../open_list_factory.h" -#include "../plugins/plugin.h" - /* Type-based open list based on Xie et al. (AAAI 2014; see detailed reference in plug-in documentation). @@ -26,10 +24,12 @@ namespace type_based_open_list { class TypeBasedOpenListFactory : public OpenListFactory { - plugins::Options options; + std::vector> evaluators; + int random_seed; public: - explicit TypeBasedOpenListFactory(const plugins::Options &options); - virtual ~TypeBasedOpenListFactory() override = default; + TypeBasedOpenListFactory( + const std::vector> &evaluators, + int random_seed); virtual std::unique_ptr create_state_open_list() override; virtual std::unique_ptr create_edge_open_list() override; diff --git a/src/search/operator_cost.cc b/src/search/operator_cost.cc index cd1d708a0..b2e45be10 100644 --- a/src/search/operator_cost.cc +++ b/src/search/operator_cost.cc @@ -6,7 +6,7 @@ #include "utils/system.h" #include -#include + using namespace std; static int get_adjusted_action_cost(int cost, OperatorCost cost_type, bool is_unit_cost) { @@ -32,7 +32,7 @@ int get_adjusted_action_cost(const OperatorProxy &op, OperatorCost cost_type, bo return get_adjusted_action_cost(op.get_cost(), cost_type, is_unit_cost); } -void add_cost_type_option_to_feature(plugins::Feature &feature) { +void add_cost_type_options_to_feature(plugins::Feature &feature) { feature.add_option( "cost_type", "Operator cost adjustment type. " @@ -41,6 +41,11 @@ void add_cost_type_option_to_feature(plugins::Feature &feature) { "normal"); } +tuple get_cost_type_arguments_from_options( + const plugins::Options &opts) { + return make_tuple(opts.get("cost_type")); +} + static plugins::TypedEnumPlugin _enum_plugin({ {"normal", "all actions are accounted for with their real cost"}, {"one", "all actions are accounted for as unit cost"}, diff --git a/src/search/operator_cost.h b/src/search/operator_cost.h index f8837a5a7..be6d0942c 100644 --- a/src/search/operator_cost.h +++ b/src/search/operator_cost.h @@ -1,15 +1,19 @@ #ifndef OPERATOR_COST_H #define OPERATOR_COST_H +#include + class OperatorProxy; namespace plugins { class Feature; +class Options; } enum OperatorCost {NORMAL = 0, ONE = 1, PLUSONE = 2, MAX_OPERATOR_COST}; int get_adjusted_action_cost(const OperatorProxy &op, OperatorCost cost_type, bool is_unit_cost); -void add_cost_type_option_to_feature(plugins::Feature &feature); - +extern void add_cost_type_options_to_feature(plugins::Feature &feature); +extern std::tuple get_cost_type_arguments_from_options( + const plugins::Options &opts); #endif diff --git a/src/search/operator_counting/delete_relaxation_if_constraints.cc b/src/search/operator_counting/delete_relaxation_if_constraints.cc index 6890d0c2a..b5f62452a 100644 --- a/src/search/operator_counting/delete_relaxation_if_constraints.cc +++ b/src/search/operator_counting/delete_relaxation_if_constraints.cc @@ -21,9 +21,10 @@ static void add_lp_variables(int count, LPVariables &variables, vector &ind } -DeleteRelaxationIFConstraints::DeleteRelaxationIFConstraints(const plugins::Options &opts) - : use_time_vars(opts.get("use_time_vars")), - use_integer_vars(opts.get("use_integer_vars")) { +DeleteRelaxationIFConstraints::DeleteRelaxationIFConstraints( + bool use_time_vars, bool use_integer_vars) + : use_time_vars(use_time_vars), + use_integer_vars(use_integer_vars) { } int DeleteRelaxationIFConstraints::get_var_op_used(const OperatorProxy &op) { @@ -236,7 +237,8 @@ bool DeleteRelaxationIFConstraints::update_constraints( return false; } -class DeleteRelaxationIFConstraintsFeature : public plugins::TypedFeature { +class DeleteRelaxationIFConstraintsFeature + : public plugins::TypedFeature { public: DeleteRelaxationIFConstraintsFeature() : TypedFeature("delete_relaxation_if_constraints") { document_title("Delete relaxation constraints"); @@ -285,6 +287,14 @@ class DeleteRelaxationIFConstraintsFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return make_shared( + opts.get("use_time_vars"), + opts.get("use_integer_vars")); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/operator_counting/delete_relaxation_if_constraints.h b/src/search/operator_counting/delete_relaxation_if_constraints.h index 7adfb543e..dab21c8b2 100644 --- a/src/search/operator_counting/delete_relaxation_if_constraints.h +++ b/src/search/operator_counting/delete_relaxation_if_constraints.h @@ -63,7 +63,8 @@ class DeleteRelaxationIFConstraints : public ConstraintGenerator { const TaskProxy &task_proxy, LPVariables &variables); void create_constraints(const TaskProxy &task_proxy, lp::LinearProgram &lp); public: - explicit DeleteRelaxationIFConstraints(const plugins::Options &opts); + explicit DeleteRelaxationIFConstraints( + bool use_time_vars, bool use_integer_vars); virtual void initialize_constraints( const std::shared_ptr &task, diff --git a/src/search/operator_counting/lm_cut_constraints.cc b/src/search/operator_counting/lm_cut_constraints.cc index c2e873f33..ad7cd4726 100644 --- a/src/search/operator_counting/lm_cut_constraints.cc +++ b/src/search/operator_counting/lm_cut_constraints.cc @@ -44,7 +44,8 @@ bool LMCutConstraints::update_constraints(const State &state, } } -class LMCutConstraintsFeature : public plugins::TypedFeature { +class LMCutConstraintsFeature + : public plugins::TypedFeature { public: LMCutConstraintsFeature() : TypedFeature("lmcut_constraints") { document_title("LM-cut landmark constraints"); diff --git a/src/search/operator_counting/operator_counting_heuristic.cc b/src/search/operator_counting/operator_counting_heuristic.cc index a844b377b..0ebe47e85 100644 --- a/src/search/operator_counting/operator_counting_heuristic.cc +++ b/src/search/operator_counting/operator_counting_heuristic.cc @@ -11,12 +11,14 @@ using namespace std; namespace operator_counting { -OperatorCountingHeuristic::OperatorCountingHeuristic(const plugins::Options &opts) - : Heuristic(opts), - constraint_generators( - opts.get_list>("constraint_generators")), - lp_solver(opts.get("lpsolver")), - use_integer_operator_counts(opts.get("use_integer_operator_counts")) { +OperatorCountingHeuristic::OperatorCountingHeuristic( + const vector> &constraint_generators, + bool use_integer_operator_counts, lp::LPSolverType lpsolver, + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : Heuristic(transform, cache_estimates, description, verbosity), + constraint_generators(constraint_generators), + lp_solver(lpsolver) { lp_solver.set_mip_gap(0); named_vector::NamedVector variables; double infinity = lp_solver.get_infinity(); @@ -34,9 +36,6 @@ OperatorCountingHeuristic::OperatorCountingHeuristic(const plugins::Options &opt lp_solver.load_problem(lp); } -OperatorCountingHeuristic::~OperatorCountingHeuristic() { -} - int OperatorCountingHeuristic::compute_heuristic(const State &ancestor_state) { State state = convert_ancestor_state(ancestor_state); assert(!lp_solver.has_temporary_constraints()); @@ -60,7 +59,8 @@ int OperatorCountingHeuristic::compute_heuristic(const State &ancestor_state) { return result; } -class OperatorCountingHeuristicFeature : public plugins::TypedFeature { +class OperatorCountingHeuristicFeature + : public plugins::TypedFeature { public: OperatorCountingHeuristicFeature() : TypedFeature("operatorcounting") { document_title("Operator-counting heuristic"); @@ -95,7 +95,7 @@ class OperatorCountingHeuristicFeature : public plugins::TypedFeature create_component(const plugins::Options &options, const utils::Context &context) const override { + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &context) const override { plugins::verify_list_non_empty>( - context, options, "constraint_generators"); - return make_shared(options); + context, opts, "constraint_generators"); + return plugins::make_shared_from_arg_tuples( + opts.get_list>( + "constraint_generators"), + opts.get("use_integer_operator_counts"), + lp::get_lp_solver_arguments_from_options(opts), + get_heuristic_arguments_from_options(opts) + ); } }; diff --git a/src/search/operator_counting/operator_counting_heuristic.h b/src/search/operator_counting/operator_counting_heuristic.h index ff0b32603..b7d8ef2b0 100644 --- a/src/search/operator_counting/operator_counting_heuristic.h +++ b/src/search/operator_counting/operator_counting_heuristic.h @@ -18,12 +18,16 @@ class ConstraintGenerator; class OperatorCountingHeuristic : public Heuristic { std::vector> constraint_generators; lp::LPSolver lp_solver; - const bool use_integer_operator_counts; protected: virtual int compute_heuristic(const State &ancestor_state) override; public: - explicit OperatorCountingHeuristic(const plugins::Options &opts); - ~OperatorCountingHeuristic(); + OperatorCountingHeuristic( + const std::vector> + &constraint_generators, + bool use_integer_operator_counts, lp::LPSolverType lpsolver, + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); }; } diff --git a/src/search/operator_counting/pho_constraints.cc b/src/search/operator_counting/pho_constraints.cc index 72ccacc87..27b512b19 100644 --- a/src/search/operator_counting/pho_constraints.cc +++ b/src/search/operator_counting/pho_constraints.cc @@ -15,9 +15,9 @@ using namespace std; namespace operator_counting { -PhOConstraints::PhOConstraints(const plugins::Options &opts) - : pattern_generator( - opts.get>("patterns")) { +PhOConstraints::PhOConstraints( + const shared_ptr &patterns) + : pattern_generator(patterns) { } void PhOConstraints::initialize_constraints( @@ -62,7 +62,8 @@ bool PhOConstraints::update_constraints(const State &state, return false; } -class PhOConstraintsFeature : public plugins::TypedFeature { +class PhOConstraintsFeature + : public plugins::TypedFeature { public: PhOConstraintsFeature() : TypedFeature("pho_constraints") { document_title("Posthoc optimization constraints"); @@ -84,6 +85,14 @@ class PhOConstraintsFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get>( + "patterns")); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/operator_counting/pho_constraints.h b/src/search/operator_counting/pho_constraints.h index 7a4b861f2..696bb59ab 100644 --- a/src/search/operator_counting/pho_constraints.h +++ b/src/search/operator_counting/pho_constraints.h @@ -24,7 +24,8 @@ class PhOConstraints : public ConstraintGenerator { int constraint_offset; std::shared_ptr pdbs; public: - explicit PhOConstraints(const plugins::Options &opts); + explicit PhOConstraints( + const std::shared_ptr &patterns); virtual void initialize_constraints( const std::shared_ptr &task, lp::LinearProgram &lp) override; diff --git a/src/search/operator_counting/state_equation_constraints.cc b/src/search/operator_counting/state_equation_constraints.cc index ca685da23..675e34709 100644 --- a/src/search/operator_counting/state_equation_constraints.cc +++ b/src/search/operator_counting/state_equation_constraints.cc @@ -12,8 +12,8 @@ using namespace std; namespace operator_counting { StateEquationConstraints::StateEquationConstraints( - const plugins::Options &opts) - : log(utils::get_log_from_options(opts)) { + utils::Verbosity verbosity) + : log(utils::get_log_for_verbosity(verbosity)) { } static void add_indices_to_constraint(lp::LPConstraint &constraint, @@ -119,7 +119,8 @@ bool StateEquationConstraints::update_constraints(const State &state, return false; } -class StateEquationConstraintsFeature : public plugins::TypedFeature { +class StateEquationConstraintsFeature + : public plugins::TypedFeature { public: StateEquationConstraintsFeature() : TypedFeature("state_equation_constraints") { document_title("State equation constraints"); @@ -159,6 +160,13 @@ class StateEquationConstraintsFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + utils::get_log_arguments_from_options(opts)); + } }; diff --git a/src/search/operator_counting/state_equation_constraints.h b/src/search/operator_counting/state_equation_constraints.h index 471f9bbec..7d2c42e72 100644 --- a/src/search/operator_counting/state_equation_constraints.h +++ b/src/search/operator_counting/state_equation_constraints.h @@ -40,7 +40,7 @@ class StateEquationConstraints : public ConstraintGenerator { void build_propositions(const TaskProxy &task_proxy); void add_constraints(named_vector::NamedVector &constraints, double infinity); public: - explicit StateEquationConstraints(const plugins::Options &opts); + explicit StateEquationConstraints(utils::Verbosity verbosity); virtual void initialize_constraints( const std::shared_ptr &task, lp::LinearProgram &lp) override; virtual bool update_constraints(const State &state, lp::LPSolver &lp_solver) override; diff --git a/src/search/pdbs/canonical_pdbs_heuristic.cc b/src/search/pdbs/canonical_pdbs_heuristic.cc index fa7e5b37a..74f82da89 100644 --- a/src/search/pdbs/canonical_pdbs_heuristic.cc +++ b/src/search/pdbs/canonical_pdbs_heuristic.cc @@ -1,7 +1,6 @@ #include "canonical_pdbs_heuristic.h" #include "dominance_pruning.h" -#include "pattern_generator.h" #include "utils.h" #include "../plugins/plugin.h" @@ -15,10 +14,10 @@ using namespace std; namespace pdbs { -static CanonicalPDBs get_canonical_pdbs_from_options( - const shared_ptr &task, const plugins::Options &opts, utils::LogProxy &log) { - shared_ptr pattern_generator = - opts.get>("patterns"); +static CanonicalPDBs get_canonical_pdbs( + const shared_ptr &task, + const shared_ptr &pattern_generator, + double max_time_dominance_pruning, utils::LogProxy &log) { utils::Timer timer; if (log.is_at_least_normal()) { log << "Initializing canonical PDB heuristic..." << endl; @@ -36,7 +35,6 @@ static CanonicalPDBs get_canonical_pdbs_from_options( shared_ptr> pattern_cliques = pattern_collection_info.get_pattern_cliques(); - double max_time_dominance_pruning = opts.get("max_time_dominance_pruning"); if (max_time_dominance_pruning > 0.0) { int num_variables = TaskProxy(*task).get_variables().size(); /* @@ -62,9 +60,15 @@ static CanonicalPDBs get_canonical_pdbs_from_options( return CanonicalPDBs(pdbs, pattern_cliques); } -CanonicalPDBsHeuristic::CanonicalPDBsHeuristic(const plugins::Options &opts) - : Heuristic(opts), - canonical_pdbs(get_canonical_pdbs_from_options(task, opts, log)) { +CanonicalPDBsHeuristic::CanonicalPDBsHeuristic( + const shared_ptr &patterns, + double max_time_dominance_pruning, + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : Heuristic(transform, cache_estimates, description, verbosity), + canonical_pdbs( + get_canonical_pdbs( + task, patterns, max_time_dominance_pruning, log)) { } int CanonicalPDBsHeuristic::compute_heuristic(const State &ancestor_state) { @@ -88,7 +92,13 @@ void add_canonical_pdbs_options_to_feature(plugins::Feature &feature) { plugins::Bounds("0.0", "infinity")); } -class CanonicalPDBsHeuristicFeature : public plugins::TypedFeature { +tuple get_canonical_pdbs_arguments_from_options( + const plugins::Options &opts) { + return make_tuple(opts.get("max_time_dominance_pruning")); +} + +class CanonicalPDBsHeuristicFeature + : public plugins::TypedFeature { public: CanonicalPDBsHeuristicFeature() : TypedFeature("cpdbs") { document_subcategory("heuristics_pdb"); @@ -106,7 +116,7 @@ class CanonicalPDBsHeuristicFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get>( + "patterns"), + get_canonical_pdbs_arguments_from_options(opts), + get_heuristic_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pdbs/canonical_pdbs_heuristic.h b/src/search/pdbs/canonical_pdbs_heuristic.h index 3ef85cf5a..e796b42a3 100644 --- a/src/search/pdbs/canonical_pdbs_heuristic.h +++ b/src/search/pdbs/canonical_pdbs_heuristic.h @@ -2,6 +2,7 @@ #define PDBS_CANONICAL_PDBS_HEURISTIC_H #include "canonical_pdbs.h" +#include "pattern_generator.h" #include "../heuristic.h" @@ -18,11 +19,17 @@ class CanonicalPDBsHeuristic : public Heuristic { virtual int compute_heuristic(const State &ancestor_state) override; public: - explicit CanonicalPDBsHeuristic(const plugins::Options &opts); - virtual ~CanonicalPDBsHeuristic() = default; + CanonicalPDBsHeuristic( + const std::shared_ptr &patterns, + double max_time_dominance_pruning, + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); }; void add_canonical_pdbs_options_to_feature(plugins::Feature &feature); +std::tuple get_canonical_pdbs_arguments_from_options( + const plugins::Options &opts); } #endif diff --git a/src/search/pdbs/cegar.cc b/src/search/pdbs/cegar.cc index c428ba982..2969fdf7a 100644 --- a/src/search/pdbs/cegar.cc +++ b/src/search/pdbs/cegar.cc @@ -786,4 +786,8 @@ void add_cegar_wildcard_option_to_feature(plugins::Feature &feature) { "plans which are sequences of single operators", "true"); } +tuple get_cegar_wildcard_arguments_from_options( + const plugins::Options &opts) { + return make_tuple(opts.get("use_wildcard_plans")); +} } diff --git a/src/search/pdbs/cegar.h b/src/search/pdbs/cegar.h index 955746326..88178481a 100644 --- a/src/search/pdbs/cegar.h +++ b/src/search/pdbs/cegar.h @@ -10,6 +10,7 @@ namespace plugins { class Feature; +class Options; } namespace utils { @@ -63,6 +64,8 @@ extern PatternInformation generate_pattern_with_cegar( extern void add_cegar_implementation_notes_to_feature(plugins::Feature &feature); extern void add_cegar_wildcard_option_to_feature(plugins::Feature &feature); +std::tuple get_cegar_wildcard_arguments_from_options( + const plugins::Options &opts); } #endif diff --git a/src/search/pdbs/pattern_collection_generator_combo.cc b/src/search/pdbs/pattern_collection_generator_combo.cc index 57623150e..4e107ef2d 100644 --- a/src/search/pdbs/pattern_collection_generator_combo.cc +++ b/src/search/pdbs/pattern_collection_generator_combo.cc @@ -18,8 +18,10 @@ using namespace std; namespace pdbs { PatternCollectionGeneratorCombo::PatternCollectionGeneratorCombo( - const plugins::Options &opts) - : PatternCollectionGenerator(opts), opts(opts) { + int max_states, utils::Verbosity verbosity) + : PatternCollectionGenerator(verbosity), + max_states(max_states), + verbosity(verbosity) { } string PatternCollectionGeneratorCombo::name() const { @@ -31,7 +33,8 @@ PatternCollectionInformation PatternCollectionGeneratorCombo::compute_patterns( TaskProxy task_proxy(*task); shared_ptr patterns = make_shared(); - PatternGeneratorGreedy large_pattern_generator(opts); + PatternGeneratorGreedy large_pattern_generator( + max_states, verbosity); Pattern large_pattern = large_pattern_generator.generate(task).get_pattern(); set used_vars(large_pattern.begin(), large_pattern.end()); patterns->push_back(move(large_pattern)); @@ -47,7 +50,8 @@ PatternCollectionInformation PatternCollectionGeneratorCombo::compute_patterns( return pci; } -class PatternCollectionGeneratorComboFeature : public plugins::TypedFeature { +class PatternCollectionGeneratorComboFeature + : public plugins::TypedFeature { public: PatternCollectionGeneratorComboFeature() : TypedFeature("combo") { add_option( @@ -57,6 +61,15 @@ class PatternCollectionGeneratorComboFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get("max_states"), + get_generator_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pdbs/pattern_collection_generator_combo.h b/src/search/pdbs/pattern_collection_generator_combo.h index ce7d5fb08..e24e04eed 100644 --- a/src/search/pdbs/pattern_collection_generator_combo.h +++ b/src/search/pdbs/pattern_collection_generator_combo.h @@ -9,14 +9,15 @@ namespace pdbs { /* Take one large pattern and then single-variable patterns for all goal variables that are not in the large pattern. */ class PatternCollectionGeneratorCombo : public PatternCollectionGenerator { - plugins::Options opts; + int max_states; + utils::Verbosity verbosity; virtual std::string name() const override; virtual PatternCollectionInformation compute_patterns( const std::shared_ptr &task) override; public: - explicit PatternCollectionGeneratorCombo(const plugins::Options &opts); - virtual ~PatternCollectionGeneratorCombo() = default; + PatternCollectionGeneratorCombo( + int max_states, utils::Verbosity verbosity); }; } diff --git a/src/search/pdbs/pattern_collection_generator_disjoint_cegar.cc b/src/search/pdbs/pattern_collection_generator_disjoint_cegar.cc index 58a44f542..a76712261 100644 --- a/src/search/pdbs/pattern_collection_generator_disjoint_cegar.cc +++ b/src/search/pdbs/pattern_collection_generator_disjoint_cegar.cc @@ -11,13 +11,15 @@ using namespace std; namespace pdbs { PatternCollectionGeneratorDisjointCegar::PatternCollectionGeneratorDisjointCegar( - const plugins::Options &opts) - : PatternCollectionGenerator(opts), - max_pdb_size(opts.get("max_pdb_size")), - max_collection_size(opts.get("max_collection_size")), - max_time(opts.get("max_time")), - use_wildcard_plans(opts.get("use_wildcard_plans")), - rng(utils::parse_rng_from_options(opts)) { + int max_pdb_size, int max_collection_size, double max_time, + bool use_wildcard_plans, int random_seed, + utils::Verbosity verbosity) + : PatternCollectionGenerator(verbosity), + max_pdb_size(max_pdb_size), + max_collection_size(max_collection_size), + max_time(max_time), + use_wildcard_plans(use_wildcard_plans), + rng(utils::get_rng(random_seed)) { } string PatternCollectionGeneratorDisjointCegar::name() const { @@ -41,7 +43,8 @@ PatternCollectionInformation PatternCollectionGeneratorDisjointCegar::compute_pa move(goals)); } -class PatternCollectionGeneratorDisjointCegarFeature : public plugins::TypedFeature { +class PatternCollectionGeneratorDisjointCegarFeature + : public plugins::TypedFeature { public: PatternCollectionGeneratorDisjointCegarFeature() : TypedFeature("disjoint_cegar") { document_title("Disjoint CEGAR"); @@ -75,11 +78,24 @@ class PatternCollectionGeneratorDisjointCegarFeature : public plugins::TypedFeat "infinity", plugins::Bounds("0.0", "infinity")); add_cegar_wildcard_option_to_feature(*this); + utils::add_rng_options_to_feature(*this); add_generator_options_to_feature(*this); - utils::add_rng_options(*this); add_cegar_implementation_notes_to_feature(*this); } + + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get("max_pdb_size"), + opts.get("max_collection_size"), + opts.get("max_time"), + get_cegar_wildcard_arguments_from_options(opts), + utils::get_rng_arguments_from_options(opts), + get_generator_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pdbs/pattern_collection_generator_disjoint_cegar.h b/src/search/pdbs/pattern_collection_generator_disjoint_cegar.h index 5622588ee..32ac888ba 100644 --- a/src/search/pdbs/pattern_collection_generator_disjoint_cegar.h +++ b/src/search/pdbs/pattern_collection_generator_disjoint_cegar.h @@ -23,7 +23,10 @@ class PatternCollectionGeneratorDisjointCegar : public PatternCollectionGenerato virtual PatternCollectionInformation compute_patterns( const std::shared_ptr &task) override; public: - explicit PatternCollectionGeneratorDisjointCegar(const plugins::Options &opts); + PatternCollectionGeneratorDisjointCegar( + int max_pdb_size, int max_collection_size, double max_time, + bool use_wildcard_plans, int random_seed, + utils::Verbosity verbosity); }; } diff --git a/src/search/pdbs/pattern_collection_generator_genetic.cc b/src/search/pdbs/pattern_collection_generator_genetic.cc index 4c4cf4c78..59eb156c0 100644 --- a/src/search/pdbs/pattern_collection_generator_genetic.cc +++ b/src/search/pdbs/pattern_collection_generator_genetic.cc @@ -25,14 +25,16 @@ using namespace std; namespace pdbs { PatternCollectionGeneratorGenetic::PatternCollectionGeneratorGenetic( - const plugins::Options &opts) - : PatternCollectionGenerator(opts), - pdb_max_size(opts.get("pdb_max_size")), - num_collections(opts.get("num_collections")), - num_episodes(opts.get("num_episodes")), - mutation_probability(opts.get("mutation_probability")), - disjoint_patterns(opts.get("disjoint")), - rng(utils::parse_rng_from_options(opts)) { + int pdb_max_size, int num_collections, int num_episodes, + double mutation_probability, bool disjoint, int random_seed, + utils::Verbosity verbosity) + : PatternCollectionGenerator(verbosity), + pdb_max_size(pdb_max_size), + num_collections(num_collections), + num_episodes(num_episodes), + mutation_probability(mutation_probability), + disjoint_patterns(disjoint), + rng(utils::get_rng(random_seed)) { } void PatternCollectionGeneratorGenetic::select( @@ -297,7 +299,8 @@ PatternCollectionInformation PatternCollectionGeneratorGenetic::compute_patterns return PatternCollectionInformation(task_proxy, best_patterns, log); } -class PatternCollectionGeneratorGeneticFeature : public plugins::TypedFeature { +class PatternCollectionGeneratorGeneticFeature + : public plugins::TypedFeature { public: PatternCollectionGeneratorGeneticFeature() : TypedFeature("genetic") { document_title("Genetic Algorithm Patterns"); @@ -344,7 +347,7 @@ class PatternCollectionGeneratorGeneticFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get("pdb_max_size"), + opts.get("num_collections"), + opts.get("num_episodes"), + opts.get("mutation_probability"), + opts.get("disjoint"), + utils::get_rng_arguments_from_options(opts), + get_generator_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pdbs/pattern_collection_generator_genetic.h b/src/search/pdbs/pattern_collection_generator_genetic.h index 672eceaf4..f1c1bc8df 100644 --- a/src/search/pdbs/pattern_collection_generator_genetic.h +++ b/src/search/pdbs/pattern_collection_generator_genetic.h @@ -113,7 +113,10 @@ class PatternCollectionGeneratorGenetic : public PatternCollectionGenerator { virtual PatternCollectionInformation compute_patterns( const std::shared_ptr &task) override; public: - explicit PatternCollectionGeneratorGenetic(const plugins::Options &opts); + PatternCollectionGeneratorGenetic( + int pdb_max_size, int num_collections, int num_episodes, + double mutation_probability, bool disjoint, int random_seed, + utils::Verbosity verbosity); }; } diff --git a/src/search/pdbs/pattern_collection_generator_hillclimbing.cc b/src/search/pdbs/pattern_collection_generator_hillclimbing.cc index 322587b8f..9b3191ea9 100644 --- a/src/search/pdbs/pattern_collection_generator_hillclimbing.cc +++ b/src/search/pdbs/pattern_collection_generator_hillclimbing.cc @@ -112,14 +112,17 @@ static vector> compute_relevant_neighbours(const TaskProxy &task_pro } -PatternCollectionGeneratorHillclimbing::PatternCollectionGeneratorHillclimbing(const plugins::Options &opts) - : PatternCollectionGenerator(opts), - pdb_max_size(opts.get("pdb_max_size")), - collection_max_size(opts.get("collection_max_size")), - num_samples(opts.get("num_samples")), - min_improvement(opts.get("min_improvement")), - max_time(opts.get("max_time")), - rng(utils::parse_rng_from_options(opts)), +PatternCollectionGeneratorHillclimbing::PatternCollectionGeneratorHillclimbing( + int pdb_max_size, int collection_max_size, int num_samples, + int min_improvement, double max_time, int random_seed, + utils::Verbosity verbosity) + : PatternCollectionGenerator(verbosity), + pdb_max_size(pdb_max_size), + collection_max_size(collection_max_size), + num_samples(num_samples), + min_improvement(min_improvement), + max_time(max_time), + rng(utils::get_rng(random_seed)), num_rejected(0), hill_climbing_timer(nullptr) { } @@ -459,7 +462,7 @@ PatternCollectionInformation PatternCollectionGeneratorHillclimbing::compute_pat return current_pdbs->get_pattern_collection_information(log); } -static void add_hillclimbing_options(plugins::Feature &feature) { +void add_hillclimbing_options_to_feature(plugins::Feature &feature) { feature.document_note( "Note", "The pattern collection created by the algorithm will always contain " @@ -551,7 +554,19 @@ static void add_hillclimbing_options(plugins::Feature &feature) { "spent for pruning dominated patterns.", "infinity", plugins::Bounds("0.0", "infinity")); - utils::add_rng_options(feature); + utils::add_rng_options_to_feature(feature); +} + +tuple +get_hillclimbing_arguments_from_options(const plugins::Options &opts) { + return tuple_cat( + make_tuple( + opts.get("pdb_max_size"), + opts.get("collection_max_size"), + opts.get("num_samples"), + opts.get("min_improvement"), + opts.get("max_time")), + utils::get_rng_arguments_from_options(opts)); } static void check_hillclimbing_options( @@ -586,7 +601,8 @@ static basic_string paper_references() { "2012"); } -class PatternCollectionGeneratorHillclimbingFeature : public plugins::TypedFeature { +class PatternCollectionGeneratorHillclimbingFeature + : public plugins::TypedFeature { public: PatternCollectionGeneratorHillclimbingFeature() : TypedFeature("hillclimbing") { document_title("Hill climbing"); @@ -594,19 +610,25 @@ class PatternCollectionGeneratorHillclimbingFeature : public plugins::TypedFeatu "This algorithm uses hill climbing to generate patterns " "optimized for the Evaluator#Canonical_PDB heuristic. It it described " "in the following paper:" + paper_references()); - add_hillclimbing_options(*this); + add_hillclimbing_options_to_feature(*this); add_generator_options_to_feature(*this); } - virtual shared_ptr create_component(const plugins::Options &options, const utils::Context &context) const override { - check_hillclimbing_options(options, context); - return make_shared(options); + virtual shared_ptr + create_component(const plugins::Options &opts, + const utils::Context &context) const override { + check_hillclimbing_options(opts, context); + return plugins::make_shared_from_arg_tuples( + get_hillclimbing_arguments_from_options(opts), + get_generator_arguments_from_options(opts) + ); } }; static plugins::FeaturePlugin _plugin; -class IPDBFeature : public plugins::TypedFeature { +class IPDBFeature + : public plugins::TypedFeature { public: IPDBFeature() : TypedFeature("ipdb") { document_subcategory("heuristics_pdb"); @@ -622,7 +644,7 @@ class IPDBFeature : public plugins::TypedFeature create_component(const plugins::Options &options, const utils::Context &context) const override { - check_hillclimbing_options(options, context); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &context) const override { + check_hillclimbing_options(opts, context); shared_ptr pgh = - make_shared(options); - - plugins::Options heuristic_opts; - heuristic_opts.set( - "verbosity", options.get("verbosity")); - heuristic_opts.set>( - "transform", options.get>("transform")); - heuristic_opts.set( - "cache_estimates", options.get("cache_estimates")); - heuristic_opts.set>( - "patterns", pgh); - heuristic_opts.set( - "max_time_dominance_pruning", options.get("max_time_dominance_pruning")); - - return make_shared(heuristic_opts); + plugins::make_shared_from_arg_tuples( + get_hillclimbing_arguments_from_options(opts), + get_generator_arguments_from_options(opts) + ); + + return plugins::make_shared_from_arg_tuples( + pgh, + opts.get("max_time_dominance_pruning"), + get_heuristic_arguments_from_options(opts) + ); } }; diff --git a/src/search/pdbs/pattern_collection_generator_hillclimbing.h b/src/search/pdbs/pattern_collection_generator_hillclimbing.h index d9cf02097..471bddde9 100644 --- a/src/search/pdbs/pattern_collection_generator_hillclimbing.h +++ b/src/search/pdbs/pattern_collection_generator_hillclimbing.h @@ -132,9 +132,17 @@ class PatternCollectionGeneratorHillclimbing : public PatternCollectionGenerator virtual PatternCollectionInformation compute_patterns( const std::shared_ptr &task) override; public: - explicit PatternCollectionGeneratorHillclimbing(const plugins::Options &opts); - virtual ~PatternCollectionGeneratorHillclimbing() = default; + PatternCollectionGeneratorHillclimbing( + int pdb_max_size, int collection_max_size, int num_samples, + int min_improvement, double max_time, int random_seed, + utils::Verbosity verbosity); }; + +extern void add_hillclimbing_options_to_feature( + plugins::Feature &feature); +std::tuple +get_hillclimbing_arguments_from_options( + const plugins::Options &opts); } #endif diff --git a/src/search/pdbs/pattern_collection_generator_manual.cc b/src/search/pdbs/pattern_collection_generator_manual.cc index 4b642252d..3499f726f 100644 --- a/src/search/pdbs/pattern_collection_generator_manual.cc +++ b/src/search/pdbs/pattern_collection_generator_manual.cc @@ -12,9 +12,10 @@ using namespace std; namespace pdbs { -PatternCollectionGeneratorManual::PatternCollectionGeneratorManual(const plugins::Options &opts) - : PatternCollectionGenerator(opts), - patterns(make_shared(opts.get_list("patterns"))) { +PatternCollectionGeneratorManual::PatternCollectionGeneratorManual( + const vector &patterns, utils::Verbosity verbosity) + : PatternCollectionGenerator(verbosity), + patterns(make_shared(patterns)) { } string PatternCollectionGeneratorManual::name() const { @@ -30,7 +31,8 @@ PatternCollectionInformation PatternCollectionGeneratorManual::compute_patterns( return PatternCollectionInformation(task_proxy, patterns, log); } -class PatternCollectionGeneratorManualFeature : public plugins::TypedFeature { +class PatternCollectionGeneratorManualFeature + : public plugins::TypedFeature { public: PatternCollectionGeneratorManualFeature() : TypedFeature("manual_patterns") { add_list_option( @@ -39,6 +41,16 @@ class PatternCollectionGeneratorManualFeature : public plugins::TypedFeature + create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get_list("patterns"), + get_generator_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pdbs/pattern_collection_generator_manual.h b/src/search/pdbs/pattern_collection_generator_manual.h index 92ed1d92f..91fc823d6 100644 --- a/src/search/pdbs/pattern_collection_generator_manual.h +++ b/src/search/pdbs/pattern_collection_generator_manual.h @@ -14,8 +14,9 @@ class PatternCollectionGeneratorManual : public PatternCollectionGenerator { virtual PatternCollectionInformation compute_patterns( const std::shared_ptr &task) override; public: - explicit PatternCollectionGeneratorManual(const plugins::Options &opts); - virtual ~PatternCollectionGeneratorManual() = default; + explicit PatternCollectionGeneratorManual( + const std::vector &patterns, + utils::Verbosity verbosity); }; } diff --git a/src/search/pdbs/pattern_collection_generator_multiple.cc b/src/search/pdbs/pattern_collection_generator_multiple.cc index 6e8ea1cfb..80cb6b16a 100644 --- a/src/search/pdbs/pattern_collection_generator_multiple.cc +++ b/src/search/pdbs/pattern_collection_generator_multiple.cc @@ -16,17 +16,22 @@ using namespace std; namespace pdbs { PatternCollectionGeneratorMultiple::PatternCollectionGeneratorMultiple( - const plugins::Options &opts) - : PatternCollectionGenerator(opts), - max_pdb_size(opts.get("max_pdb_size")), - pattern_generation_max_time(opts.get("pattern_generation_max_time")), - total_max_time(opts.get("total_max_time")), - stagnation_limit(opts.get("stagnation_limit")), - blacklisting_start_time(total_max_time * opts.get("blacklist_trigger_percentage")), - enable_blacklist_on_stagnation(opts.get("enable_blacklist_on_stagnation")), - rng(utils::parse_rng_from_options(opts)), - random_seed(opts.get("random_seed")), - remaining_collection_size(opts.get("max_collection_size")), + int max_pdb_size, int max_collection_size, + double pattern_generation_max_time, double total_max_time, + double stagnation_limit, double blacklist_trigger_percentage, + bool enable_blacklist_on_stagnation, int random_seed, + utils::Verbosity verbosity) + : PatternCollectionGenerator(verbosity), + max_pdb_size(max_pdb_size), + pattern_generation_max_time(pattern_generation_max_time), + total_max_time(total_max_time), + stagnation_limit(stagnation_limit), + blacklisting_start_time( + total_max_time * blacklist_trigger_percentage), + enable_blacklist_on_stagnation(enable_blacklist_on_stagnation), + rng(utils::get_rng(random_seed)), + random_seed(random_seed), + remaining_collection_size(max_collection_size), blacklisting(false), time_point_of_last_new_pattern(0.0) { } @@ -322,7 +327,23 @@ void add_multiple_options_to_feature(plugins::Feature &feature) { "generation is terminated already the first time stagnation_limit is " "hit.", "true"); + utils::add_rng_options_to_feature(feature); add_generator_options_to_feature(feature); - utils::add_rng_options(feature); +} + +tuple +get_multiple_arguments_from_options(const plugins::Options &opts) { + return tuple_cat( + make_tuple( + opts.get("max_pdb_size"), + opts.get("max_collection_size"), + opts.get("pattern_generation_max_time"), + opts.get("total_max_time"), + opts.get("stagnation_limit"), + opts.get("blacklist_trigger_percentage"), + opts.get("enable_blacklist_on_stagnation")), + utils::get_rng_arguments_from_options(opts), + get_generator_arguments_from_options(opts)); } } diff --git a/src/search/pdbs/pattern_collection_generator_multiple.h b/src/search/pdbs/pattern_collection_generator_multiple.h index dfd31e1d9..1d6c3d5b8 100644 --- a/src/search/pdbs/pattern_collection_generator_multiple.h +++ b/src/search/pdbs/pattern_collection_generator_multiple.h @@ -72,13 +72,21 @@ class PatternCollectionGeneratorMultiple : public PatternCollectionGenerator { virtual PatternCollectionInformation compute_patterns( const std::shared_ptr &task) override; public: - explicit PatternCollectionGeneratorMultiple(const plugins::Options &opts); - virtual ~PatternCollectionGeneratorMultiple() override = default; + PatternCollectionGeneratorMultiple( + int max_pdb_size, int max_collection_size, + double pattern_generation_max_time, double total_max_time, + double stagnation_limit, double blacklist_trigger_percentage, + bool enable_blacklist_on_stagnation, int random_seed, + utils::Verbosity verbosity); }; extern void add_multiple_algorithm_implementation_notes_to_feature( plugins::Feature &feature); extern void add_multiple_options_to_feature(plugins::Feature &feature); + +extern std::tuple +get_multiple_arguments_from_options(const plugins::Options &opts); } #endif diff --git a/src/search/pdbs/pattern_collection_generator_multiple_cegar.cc b/src/search/pdbs/pattern_collection_generator_multiple_cegar.cc index 9ed1be195..27be32d97 100644 --- a/src/search/pdbs/pattern_collection_generator_multiple_cegar.cc +++ b/src/search/pdbs/pattern_collection_generator_multiple_cegar.cc @@ -11,9 +11,17 @@ using namespace std; namespace pdbs { PatternCollectionGeneratorMultipleCegar::PatternCollectionGeneratorMultipleCegar( - const plugins::Options &opts) - : PatternCollectionGeneratorMultiple(opts), - use_wildcard_plans(opts.get("use_wildcard_plans")) { + bool use_wildcard_plans, int max_pdb_size, int max_collection_size, + double pattern_generation_max_time, double total_max_time, + double stagnation_limit, double blacklist_trigger_percentage, + bool enable_blacklist_on_stagnation, int random_seed, + utils::Verbosity verbosity) + : PatternCollectionGeneratorMultiple( + max_pdb_size, max_collection_size, + pattern_generation_max_time, total_max_time, stagnation_limit, + blacklist_trigger_percentage, enable_blacklist_on_stagnation, + random_seed, verbosity), + use_wildcard_plans(use_wildcard_plans) { } string PatternCollectionGeneratorMultipleCegar::id() const { @@ -39,7 +47,8 @@ PatternInformation PatternCollectionGeneratorMultipleCegar::compute_pattern( move(blacklisted_variables)); } -class PatternCollectionGeneratorMultipleCegarFeature : public plugins::TypedFeature { +class PatternCollectionGeneratorMultipleCegarFeature + : public plugins::TypedFeature { public: PatternCollectionGeneratorMultipleCegarFeature() : TypedFeature("multiple_cegar") { document_title("Multiple CEGAR"); @@ -51,12 +60,22 @@ class PatternCollectionGeneratorMultipleCegarFeature : public plugins::TypedFeat "restricted to a single goal variable. See below for descriptions of " "the algorithms."); - add_multiple_options_to_feature(*this); add_cegar_wildcard_option_to_feature(*this); + add_multiple_options_to_feature(*this); add_cegar_implementation_notes_to_feature(*this); add_multiple_algorithm_implementation_notes_to_feature(*this); } + + virtual shared_ptr + create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_cegar_wildcard_arguments_from_options(opts), + get_multiple_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pdbs/pattern_collection_generator_multiple_cegar.h b/src/search/pdbs/pattern_collection_generator_multiple_cegar.h index b6d9aaa37..a2e9b6d40 100644 --- a/src/search/pdbs/pattern_collection_generator_multiple_cegar.h +++ b/src/search/pdbs/pattern_collection_generator_multiple_cegar.h @@ -17,7 +17,13 @@ class PatternCollectionGeneratorMultipleCegar : public PatternCollectionGenerato const FactPair &goal, std::unordered_set &&blacklisted_variables) override; public: - explicit PatternCollectionGeneratorMultipleCegar(const plugins::Options &opts); + PatternCollectionGeneratorMultipleCegar( + bool use_wildcard_plans, int max_pdb_size, + int max_collection_size, double pattern_generation_max_time, + double total_max_time, double stagnation_limit, + double blacklist_trigger_percentage, + bool enable_blacklist_on_stagnation, int random_seed, + utils::Verbosity verbosity); }; } diff --git a/src/search/pdbs/pattern_collection_generator_multiple_random.cc b/src/search/pdbs/pattern_collection_generator_multiple_random.cc index ad5b74933..d020e4c46 100644 --- a/src/search/pdbs/pattern_collection_generator_multiple_random.cc +++ b/src/search/pdbs/pattern_collection_generator_multiple_random.cc @@ -14,9 +14,17 @@ using namespace std; namespace pdbs { PatternCollectionGeneratorMultipleRandom::PatternCollectionGeneratorMultipleRandom( - const plugins::Options &opts) - : PatternCollectionGeneratorMultiple(opts), - bidirectional(opts.get("bidirectional")) { + bool bidirectional, int max_pdb_size, int max_collection_size, + double pattern_generation_max_time, double total_max_time, + double stagnation_limit, double blacklist_trigger_percentage, + bool enable_blacklist_on_stagnation, int random_seed, + utils::Verbosity verbosity) + : PatternCollectionGeneratorMultiple( + max_pdb_size, max_collection_size, + pattern_generation_max_time, total_max_time, stagnation_limit, + blacklist_trigger_percentage, enable_blacklist_on_stagnation, + random_seed, verbosity), + bidirectional(bidirectional) { } string PatternCollectionGeneratorMultipleRandom::id() const { @@ -51,7 +59,8 @@ PatternInformation PatternCollectionGeneratorMultipleRandom::compute_pattern( return result; } -class PatternCollectionGeneratorMultipleRandomFeature : public plugins::TypedFeature { +class PatternCollectionGeneratorMultipleRandomFeature + : public plugins::TypedFeature { public: PatternCollectionGeneratorMultipleRandomFeature() : TypedFeature("random_patterns") { document_title("Multiple Random Patterns"); @@ -64,12 +73,21 @@ class PatternCollectionGeneratorMultipleRandomFeature : public plugins::TypedFea "pattern algorithm, called 'single randomized causal graph' (sRCG) " "in the paper. See below for descriptions of the algorithms."); - add_multiple_options_to_feature(*this); add_random_pattern_bidirectional_option_to_feature(*this); + add_multiple_options_to_feature(*this); add_random_pattern_implementation_notes_to_feature(*this); add_multiple_algorithm_implementation_notes_to_feature(*this); } + + virtual shared_ptr + create_component(const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_random_pattern_bidirectional_arguments_from_options(opts), + get_multiple_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pdbs/pattern_collection_generator_multiple_random.h b/src/search/pdbs/pattern_collection_generator_multiple_random.h index ccc51adc8..fc7a05f26 100644 --- a/src/search/pdbs/pattern_collection_generator_multiple_random.h +++ b/src/search/pdbs/pattern_collection_generator_multiple_random.h @@ -18,7 +18,12 @@ class PatternCollectionGeneratorMultipleRandom : public PatternCollectionGenerat const FactPair &goal, std::unordered_set &&blacklisted_variables) override; public: - explicit PatternCollectionGeneratorMultipleRandom(const plugins::Options &opts); + PatternCollectionGeneratorMultipleRandom( + bool bidirectional, int max_pdb_size, int max_collection_size, + double pattern_generation_max_time, double total_max_time, + double stagnation_limit, double blacklist_trigger_percentage, + bool enable_blacklist_on_stagnation, int random_seed, + utils::Verbosity verbosity); }; } diff --git a/src/search/pdbs/pattern_collection_generator_systematic.cc b/src/search/pdbs/pattern_collection_generator_systematic.cc index 3cc412a6b..d5c6d2aa1 100644 --- a/src/search/pdbs/pattern_collection_generator_systematic.cc +++ b/src/search/pdbs/pattern_collection_generator_systematic.cc @@ -47,10 +47,11 @@ static void compute_union_pattern( PatternCollectionGeneratorSystematic::PatternCollectionGeneratorSystematic( - const plugins::Options &opts) - : PatternCollectionGenerator(opts), - max_pattern_size(opts.get("pattern_max_size")), - only_interesting_patterns(opts.get("only_interesting_patterns")) { + int pattern_max_size, bool only_interesting_patterns, + utils::Verbosity verbosity) + : PatternCollectionGenerator(verbosity), + max_pattern_size(pattern_max_size), + only_interesting_patterns(only_interesting_patterns) { } void PatternCollectionGeneratorSystematic::compute_eff_pre_neighbors( @@ -284,7 +285,8 @@ PatternCollectionInformation PatternCollectionGeneratorSystematic::compute_patte return PatternCollectionInformation(task_proxy, patterns, log); } -class PatternCollectionGeneratorSystematicFeature : public plugins::TypedFeature { +class PatternCollectionGeneratorSystematicFeature + : public plugins::TypedFeature { public: PatternCollectionGeneratorSystematicFeature() : TypedFeature("systematic") { document_title("Systematically generated patterns"); @@ -313,6 +315,17 @@ class PatternCollectionGeneratorSystematicFeature : public plugins::TypedFeature "true"); add_generator_options_to_feature(*this); } + + virtual shared_ptr + create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get("pattern_max_size"), + opts.get("only_interesting_patterns"), + get_generator_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pdbs/pattern_collection_generator_systematic.h b/src/search/pdbs/pattern_collection_generator_systematic.h index 8f483104c..0db2bf98f 100644 --- a/src/search/pdbs/pattern_collection_generator_systematic.h +++ b/src/search/pdbs/pattern_collection_generator_systematic.h @@ -44,7 +44,9 @@ class PatternCollectionGeneratorSystematic : public PatternCollectionGenerator { virtual PatternCollectionInformation compute_patterns( const std::shared_ptr &task) override; public: - explicit PatternCollectionGeneratorSystematic(const plugins::Options &opts); + PatternCollectionGeneratorSystematic( + int pattern_max_size, bool only_interesting_patterns, + utils::Verbosity verbosity); }; } diff --git a/src/search/pdbs/pattern_generator.cc b/src/search/pdbs/pattern_generator.cc index f64751674..ca233eaca 100644 --- a/src/search/pdbs/pattern_generator.cc +++ b/src/search/pdbs/pattern_generator.cc @@ -7,8 +7,9 @@ using namespace std; namespace pdbs { -PatternCollectionGenerator::PatternCollectionGenerator(const plugins::Options &opts) - : log(utils::get_log_from_options(opts)) { +PatternCollectionGenerator::PatternCollectionGenerator( + utils::Verbosity verbosity) + : log(utils::get_log_for_verbosity(verbosity)) { } PatternCollectionInformation PatternCollectionGenerator::generate( @@ -23,8 +24,8 @@ PatternCollectionInformation PatternCollectionGenerator::generate( return pci; } -PatternGenerator::PatternGenerator(const plugins::Options &opts) - : log(utils::get_log_from_options(opts)) { +PatternGenerator::PatternGenerator(utils::Verbosity verbosity) + : log(utils::get_log_for_verbosity(verbosity)) { } PatternInformation PatternGenerator::generate( @@ -46,6 +47,11 @@ void add_generator_options_to_feature(plugins::Feature &feature) { utils::add_log_options_to_feature(feature); } +tuple get_generator_arguments_from_options( + const plugins::Options &opts) { + return utils::get_log_arguments_from_options(opts); +} + static class PatternCollectionGeneratorCategoryPlugin : public plugins::TypedCategoryPlugin { public: PatternCollectionGeneratorCategoryPlugin() : TypedCategoryPlugin("PatternCollectionGenerator") { diff --git a/src/search/pdbs/pattern_generator.h b/src/search/pdbs/pattern_generator.h index a9b6b6fc4..2dd22cbfb 100644 --- a/src/search/pdbs/pattern_generator.h +++ b/src/search/pdbs/pattern_generator.h @@ -29,7 +29,7 @@ class PatternCollectionGenerator { protected: mutable utils::LogProxy log; public: - explicit PatternCollectionGenerator(const plugins::Options &opts); + explicit PatternCollectionGenerator(utils::Verbosity verbosity); virtual ~PatternCollectionGenerator() = default; PatternCollectionInformation generate( @@ -43,13 +43,15 @@ class PatternGenerator { protected: mutable utils::LogProxy log; public: - explicit PatternGenerator(const plugins::Options &opts); + explicit PatternGenerator(utils::Verbosity verbosity); virtual ~PatternGenerator() = default; PatternInformation generate(const std::shared_ptr &task); }; extern void add_generator_options_to_feature(plugins::Feature &feature); +extern std::tuple +get_generator_arguments_from_options(const plugins::Options &opts); } #endif diff --git a/src/search/pdbs/pattern_generator_cegar.cc b/src/search/pdbs/pattern_generator_cegar.cc index 9bea9e0a6..b589d400b 100644 --- a/src/search/pdbs/pattern_generator_cegar.cc +++ b/src/search/pdbs/pattern_generator_cegar.cc @@ -16,12 +16,14 @@ using namespace std; namespace pdbs { -PatternGeneratorCEGAR::PatternGeneratorCEGAR(const plugins::Options &opts) - : PatternGenerator(opts), - max_pdb_size(opts.get("max_pdb_size")), - max_time(opts.get("max_time")), - use_wildcard_plans(opts.get("use_wildcard_plans")), - rng(utils::parse_rng_from_options(opts)) { +PatternGeneratorCEGAR::PatternGeneratorCEGAR( + int max_pdb_size, double max_time, bool use_wildcard_plans, + int random_seed, utils::Verbosity verbosity) + : PatternGenerator(verbosity), + max_pdb_size(max_pdb_size), + max_time(max_time), + use_wildcard_plans(use_wildcard_plans), + rng(utils::get_rng(random_seed)) { } string PatternGeneratorCEGAR::name() const { @@ -42,7 +44,8 @@ PatternInformation PatternGeneratorCEGAR::compute_pattern( goals[0]); } -class PatternGeneratorCEGARFeature : public plugins::TypedFeature { +class PatternGeneratorCEGARFeature + : public plugins::TypedFeature { public: PatternGeneratorCEGARFeature() : TypedFeature("cegar_pattern") { document_title("CEGAR"); @@ -65,11 +68,23 @@ class PatternGeneratorCEGARFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get("max_pdb_size"), + opts.get("max_time"), + get_cegar_wildcard_arguments_from_options(opts), + utils::get_rng_arguments_from_options(opts), + get_generator_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pdbs/pattern_generator_cegar.h b/src/search/pdbs/pattern_generator_cegar.h index 6a8a7be03..7a0066a14 100644 --- a/src/search/pdbs/pattern_generator_cegar.h +++ b/src/search/pdbs/pattern_generator_cegar.h @@ -18,7 +18,9 @@ class PatternGeneratorCEGAR : public PatternGenerator { virtual PatternInformation compute_pattern( const std::shared_ptr &task) override; public: - explicit PatternGeneratorCEGAR(const plugins::Options &opts); + PatternGeneratorCEGAR( + int max_pdb_size, double max_time, bool use_wildcard_plans, + int random_seed, utils::Verbosity verbosity); }; } diff --git a/src/search/pdbs/pattern_generator_greedy.cc b/src/search/pdbs/pattern_generator_greedy.cc index 2698930be..02b46a53f 100644 --- a/src/search/pdbs/pattern_generator_greedy.cc +++ b/src/search/pdbs/pattern_generator_greedy.cc @@ -16,8 +16,10 @@ using namespace std; namespace pdbs { -PatternGeneratorGreedy::PatternGeneratorGreedy(const plugins::Options &opts) - : PatternGenerator(opts), max_states(opts.get("max_states")) { +PatternGeneratorGreedy::PatternGeneratorGreedy( + int max_states, utils::Verbosity verbosity) + : PatternGenerator(verbosity), + max_states(max_states) { } string PatternGeneratorGreedy::name() const { @@ -49,7 +51,8 @@ PatternInformation PatternGeneratorGreedy::compute_pattern(const shared_ptr { +class PatternGeneratorGreedyFeature + : public plugins::TypedFeature { public: PatternGeneratorGreedyFeature() : TypedFeature("greedy") { add_option( @@ -59,6 +62,15 @@ class PatternGeneratorGreedyFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get("max_states"), + get_generator_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pdbs/pattern_generator_greedy.h b/src/search/pdbs/pattern_generator_greedy.h index 8bb9d7055..daf9d7de6 100644 --- a/src/search/pdbs/pattern_generator_greedy.h +++ b/src/search/pdbs/pattern_generator_greedy.h @@ -11,8 +11,7 @@ class PatternGeneratorGreedy : public PatternGenerator { virtual PatternInformation compute_pattern( const std::shared_ptr &task) override; public: - explicit PatternGeneratorGreedy(const plugins::Options &opts); - virtual ~PatternGeneratorGreedy() = default; + PatternGeneratorGreedy(int max_states, utils::Verbosity verbosity); }; } diff --git a/src/search/pdbs/pattern_generator_manual.cc b/src/search/pdbs/pattern_generator_manual.cc index 4a177be77..b4b122e1a 100644 --- a/src/search/pdbs/pattern_generator_manual.cc +++ b/src/search/pdbs/pattern_generator_manual.cc @@ -12,8 +12,10 @@ using namespace std; namespace pdbs { -PatternGeneratorManual::PatternGeneratorManual(const plugins::Options &opts) - : PatternGenerator(opts), pattern(opts.get_list("pattern")) { +PatternGeneratorManual::PatternGeneratorManual( + const vector &pattern, utils::Verbosity verbosity) + : PatternGenerator(verbosity), + pattern(pattern) { } string PatternGeneratorManual::name() const { @@ -29,7 +31,8 @@ PatternInformation PatternGeneratorManual::compute_pattern( return pattern_info; } -class PatternGeneratorManualFeature : public plugins::TypedFeature { +class PatternGeneratorManualFeature + : public plugins::TypedFeature { public: PatternGeneratorManualFeature() : TypedFeature("manual_pattern") { add_list_option( @@ -38,6 +41,15 @@ class PatternGeneratorManualFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get_list("pattern"), + get_generator_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pdbs/pattern_generator_manual.h b/src/search/pdbs/pattern_generator_manual.h index 4f979ecb2..1152a06cd 100644 --- a/src/search/pdbs/pattern_generator_manual.h +++ b/src/search/pdbs/pattern_generator_manual.h @@ -12,8 +12,8 @@ class PatternGeneratorManual : public PatternGenerator { virtual PatternInformation compute_pattern( const std::shared_ptr &task) override; public: - explicit PatternGeneratorManual(const plugins::Options &opts); - virtual ~PatternGeneratorManual() = default; + PatternGeneratorManual( + const std::vector &pattern, utils::Verbosity verbosity); }; } diff --git a/src/search/pdbs/pattern_generator_random.cc b/src/search/pdbs/pattern_generator_random.cc index 757344a40..35eae18d0 100644 --- a/src/search/pdbs/pattern_generator_random.cc +++ b/src/search/pdbs/pattern_generator_random.cc @@ -16,12 +16,14 @@ using namespace std; namespace pdbs { -PatternGeneratorRandom::PatternGeneratorRandom(const plugins::Options &opts) - : PatternGenerator(opts), - max_pdb_size(opts.get("max_pdb_size")), - max_time(opts.get("max_time")), - bidirectional(opts.get("bidirectional")), - rng(utils::parse_rng_from_options(opts)) { +PatternGeneratorRandom::PatternGeneratorRandom( + int max_pdb_size, double max_time, bool bidirectional, + int random_seed, utils::Verbosity verbosity) + : PatternGenerator(verbosity), + max_pdb_size(max_pdb_size), + max_time(max_time), + bidirectional(bidirectional), + rng(utils::get_rng(random_seed)) { } string PatternGeneratorRandom::name() const { @@ -47,7 +49,8 @@ PatternInformation PatternGeneratorRandom::compute_pattern( return PatternInformation(task_proxy, pattern, log); } -class PatternGeneratorRandomFeature : public plugins::TypedFeature { +class PatternGeneratorRandomFeature + : public plugins::TypedFeature { public: PatternGeneratorRandomFeature() : TypedFeature("random_pattern") { document_title("Random Pattern"); @@ -70,11 +73,23 @@ class PatternGeneratorRandomFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get("max_pdb_size"), + opts.get("max_time"), + get_random_pattern_bidirectional_arguments_from_options(opts), + utils::get_rng_arguments_from_options(opts), + get_generator_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pdbs/pattern_generator_random.h b/src/search/pdbs/pattern_generator_random.h index b7081da0a..8b50d4576 100644 --- a/src/search/pdbs/pattern_generator_random.h +++ b/src/search/pdbs/pattern_generator_random.h @@ -18,7 +18,9 @@ class PatternGeneratorRandom : public PatternGenerator { virtual PatternInformation compute_pattern( const std::shared_ptr &task) override; public: - explicit PatternGeneratorRandom(const plugins::Options &opts); + PatternGeneratorRandom( + int max_pdb_size, double max_time, bool bidirectional, + int random_seed, utils::Verbosity verbosity); }; } diff --git a/src/search/pdbs/pdb_heuristic.cc b/src/search/pdbs/pdb_heuristic.cc index edf5f1447..484e4d2eb 100644 --- a/src/search/pdbs/pdb_heuristic.cc +++ b/src/search/pdbs/pdb_heuristic.cc @@ -1,7 +1,6 @@ #include "pdb_heuristic.h" #include "pattern_database.h" -#include "pattern_generator.h" #include "../plugins/plugin.h" @@ -11,17 +10,19 @@ using namespace std; namespace pdbs { -static shared_ptr get_pdb_from_options(const shared_ptr &task, - const plugins::Options &opts) { - shared_ptr pattern_generator = - opts.get>("pattern"); +static shared_ptr get_pdb_from_generator( + const shared_ptr &task, + const shared_ptr &pattern_generator) { PatternInformation pattern_info = pattern_generator->generate(task); return pattern_info.get_pdb(); } -PDBHeuristic::PDBHeuristic(const plugins::Options &opts) - : Heuristic(opts), - pdb(get_pdb_from_options(task, opts)) { +PDBHeuristic::PDBHeuristic( + const shared_ptr &pattern, + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : Heuristic(transform, cache_estimates, description, verbosity), + pdb(get_pdb_from_generator(task, pattern)) { } int PDBHeuristic::compute_heuristic(const State &ancestor_state) { @@ -32,7 +33,8 @@ int PDBHeuristic::compute_heuristic(const State &ancestor_state) { return h; } -class PDBHeuristicFeature : public plugins::TypedFeature { +class PDBHeuristicFeature + : public plugins::TypedFeature { public: PDBHeuristicFeature() : TypedFeature("pdb") { document_subcategory("heuristics_pdb"); @@ -43,7 +45,7 @@ class PDBHeuristicFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get>("pattern"), + get_heuristic_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pdbs/pdb_heuristic.h b/src/search/pdbs/pdb_heuristic.h index 721e3a433..4d5f8e98b 100644 --- a/src/search/pdbs/pdb_heuristic.h +++ b/src/search/pdbs/pdb_heuristic.h @@ -1,6 +1,8 @@ #ifndef PDBS_PDB_HEURISTIC_H #define PDBS_PDB_HEURISTIC_H +#include "pattern_generator.h" + #include "../heuristic.h" namespace pdbs { @@ -13,16 +15,20 @@ class PDBHeuristic : public Heuristic { virtual int compute_heuristic(const State &ancestor_state) override; public: /* - Important: It is assumed that the pattern (passed via Options) is - sorted, contains no duplicates and is small enough so that the - number of abstract states is below numeric_limits::max() + Important: It is assumed that the pattern (passed via + pattern_generator) is sorted, contains no duplicates and is small + enough so that the number of abstract states is below + numeric_limits::max() Parameters: operator_costs: Can specify individual operator costs for each operator. This is useful for action cost partitioning. If left empty, default operator costs are used. */ - PDBHeuristic(const plugins::Options &opts); - virtual ~PDBHeuristic() override = default; + PDBHeuristic( + const std::shared_ptr &pattern_generator, + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); }; } diff --git a/src/search/pdbs/random_pattern.cc b/src/search/pdbs/random_pattern.cc index 3a71d9832..ad1165d21 100644 --- a/src/search/pdbs/random_pattern.cc +++ b/src/search/pdbs/random_pattern.cc @@ -103,4 +103,9 @@ void add_random_pattern_bidirectional_option_to_feature(plugins::Feature &featur "predecessor.", "true"); } + +tuple get_random_pattern_bidirectional_arguments_from_options( + const plugins::Options &opts) { + return make_tuple(opts.get("bidirectional")); +} } diff --git a/src/search/pdbs/random_pattern.h b/src/search/pdbs/random_pattern.h index bd420595e..036bc8eae 100644 --- a/src/search/pdbs/random_pattern.h +++ b/src/search/pdbs/random_pattern.h @@ -9,6 +9,7 @@ class TaskProxy; namespace plugins { class Feature; +class Options; } namespace utils { @@ -37,6 +38,9 @@ extern void add_random_pattern_implementation_notes_to_feature( plugins::Feature &feature); extern void add_random_pattern_bidirectional_option_to_feature( plugins::Feature &feature); +extern std::tuple +get_random_pattern_bidirectional_arguments_from_options( + const plugins::Options &opts); } #endif diff --git a/src/search/pdbs/zero_one_pdbs_heuristic.cc b/src/search/pdbs/zero_one_pdbs_heuristic.cc index ee5191b8f..da8f53de6 100644 --- a/src/search/pdbs/zero_one_pdbs_heuristic.cc +++ b/src/search/pdbs/zero_one_pdbs_heuristic.cc @@ -1,7 +1,5 @@ #include "zero_one_pdbs_heuristic.h" -#include "pattern_generator.h" - #include "../plugins/plugin.h" #include @@ -9,10 +7,9 @@ using namespace std; namespace pdbs { -static ZeroOnePDBs get_zero_one_pdbs_from_options( - const shared_ptr &task, const plugins::Options &opts) { - shared_ptr pattern_generator = - opts.get>("patterns"); +static ZeroOnePDBs get_zero_one_pdbs_from_generator( + const shared_ptr &task, + const shared_ptr &pattern_generator) { PatternCollectionInformation pattern_collection_info = pattern_generator->generate(task); shared_ptr patterns = @@ -22,9 +19,11 @@ static ZeroOnePDBs get_zero_one_pdbs_from_options( } ZeroOnePDBsHeuristic::ZeroOnePDBsHeuristic( - const plugins::Options &opts) - : Heuristic(opts), - zero_one_pdbs(get_zero_one_pdbs_from_options(task, opts)) { + const shared_ptr &patterns, + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : Heuristic(transform, cache_estimates, description, verbosity), + zero_one_pdbs(get_zero_one_pdbs_from_generator(task, patterns)) { } int ZeroOnePDBsHeuristic::compute_heuristic(const State &ancestor_state) { @@ -35,7 +34,8 @@ int ZeroOnePDBsHeuristic::compute_heuristic(const State &ancestor_state) { return h; } -class ZeroOnePDBsHeuristicFeature : public plugins::TypedFeature { +class ZeroOnePDBsHeuristicFeature + : public plugins::TypedFeature { public: ZeroOnePDBsHeuristicFeature() : TypedFeature("zopdbs") { document_subcategory("heuristics_pdb"); @@ -55,7 +55,7 @@ class ZeroOnePDBsHeuristicFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get>("patterns"), + get_heuristic_arguments_from_options(opts) + ); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pdbs/zero_one_pdbs_heuristic.h b/src/search/pdbs/zero_one_pdbs_heuristic.h index 21e246bbd..b52ce23b5 100644 --- a/src/search/pdbs/zero_one_pdbs_heuristic.h +++ b/src/search/pdbs/zero_one_pdbs_heuristic.h @@ -1,6 +1,7 @@ #ifndef PDBS_ZERO_ONE_PDBS_HEURISTIC_H #define PDBS_ZERO_ONE_PDBS_HEURISTIC_H +#include "pattern_generator.h" #include "zero_one_pdbs.h" #include "../heuristic.h" @@ -13,8 +14,11 @@ class ZeroOnePDBsHeuristic : public Heuristic { protected: virtual int compute_heuristic(const State &ancestor_state) override; public: - ZeroOnePDBsHeuristic(const plugins::Options &opts); - virtual ~ZeroOnePDBsHeuristic() = default; + ZeroOnePDBsHeuristic( + const std::shared_ptr &patterns, + const std::shared_ptr &transform, + bool cache_estimates, const std::string &name, + utils::Verbosity verbosity); }; } diff --git a/src/search/plugins/plugin.h b/src/search/plugins/plugin.h index b3b396b86..6092a35d9 100644 --- a/src/search/plugins/plugin.h +++ b/src/search/plugins/plugin.h @@ -8,6 +8,7 @@ #include "../utils/strings.h" #include "../utils/system.h" +#include "../utils/tuples.h" #include #include @@ -115,6 +116,23 @@ class TypedFeature : public FeatureAuto { } }; +/* + Expects constructor arguments of T. Consecutive arguments may be + grouped in a tuple. All tuples in the arguments will be flattened + before calling the constructor. The resulting arguments will be used + as arguments to make_shared. +*/ +template +std::shared_ptr make_shared_from_arg_tuples(Arguments... arguments) { + return std::apply( + [](auto &&... flattened_args) { + return std::make_shared( + std::forward(flattened_args) ...); + }, + utils::flatten_tuple( + std::tuple(std::forward(arguments) ...))); +} + class Plugin { public: Plugin(); diff --git a/src/search/potentials/diverse_potential_heuristics.cc b/src/search/potentials/diverse_potential_heuristics.cc index 2bfba4fc4..7217c2b22 100644 --- a/src/search/potentials/diverse_potential_heuristics.cc +++ b/src/search/potentials/diverse_potential_heuristics.cc @@ -15,12 +15,19 @@ using namespace std; namespace potentials { -DiversePotentialHeuristics::DiversePotentialHeuristics(const plugins::Options &opts) - : optimizer(opts), - max_num_heuristics(opts.get("max_num_heuristics")), - num_samples(opts.get("num_samples")), - rng(utils::parse_rng_from_options(opts)), - log(utils::get_log_from_options(opts)) { +DiversePotentialHeuristics::DiversePotentialHeuristics( + int num_samples, int max_num_heuristics, double max_potential, + lp::LPSolverType lpsolver, + const shared_ptr &transform, int random_seed, + utils::Verbosity verbosity) + : optimizer( + transform, + lpsolver, + max_potential), + max_num_heuristics(max_num_heuristics), + num_samples(num_samples), + rng(utils::get_rng(random_seed)), + log(utils::get_log_for_verbosity(verbosity)) { } SamplesToFunctionsMap @@ -144,7 +151,8 @@ DiversePotentialHeuristics::find_functions() { return move(diverse_functions); } -class DiversePotentialMaxHeuristicFeature : public plugins::TypedFeature { +class DiversePotentialMaxHeuristicFeature + : public plugins::TypedFeature { public: DiversePotentialMaxHeuristicFeature() : TypedFeature("diverse_potentials") { document_subcategory("heuristics_potentials"); @@ -162,13 +170,28 @@ class DiversePotentialMaxHeuristicFeature : public plugins::TypedFeature create_component(const plugins::Options &options, const utils::Context &) const override { - DiversePotentialHeuristics factory(options); - return make_shared(options, factory.find_functions()); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return make_shared( + DiversePotentialHeuristics( + opts.get("num_samples"), + opts.get("max_num_heuristics"), + opts.get("max_potential"), + opts.get("lpsolver"), + opts.get>("transform"), + opts.get("random_seed"), + opts.get("verbosity") + ).find_functions(), + opts.get>("transform"), + opts.get("cache_estimates"), + opts.get("description"), + opts.get("verbosity") + ); } }; diff --git a/src/search/potentials/diverse_potential_heuristics.h b/src/search/potentials/diverse_potential_heuristics.h index 4069f9e8e..eee0ad928 100644 --- a/src/search/potentials/diverse_potential_heuristics.h +++ b/src/search/potentials/diverse_potential_heuristics.h @@ -54,7 +54,11 @@ class DiversePotentialHeuristics { void cover_samples(SamplesToFunctionsMap &samples_to_functions); public: - explicit DiversePotentialHeuristics(const plugins::Options &opts); + DiversePotentialHeuristics( + int num_samples, int max_num_heuristics, double max_potential, + lp::LPSolverType lpsolver, + const std::shared_ptr &transform, int random_seed, + utils::Verbosity verbosity); ~DiversePotentialHeuristics() = default; // Sample states, then cover them. diff --git a/src/search/potentials/potential_heuristic.cc b/src/search/potentials/potential_heuristic.cc index 4c4377214..c54526aec 100644 --- a/src/search/potentials/potential_heuristic.cc +++ b/src/search/potentials/potential_heuristic.cc @@ -8,13 +8,13 @@ using namespace std; namespace potentials { PotentialHeuristic::PotentialHeuristic( - const plugins::Options &opts, unique_ptr function) - : Heuristic(opts), + unique_ptr function, + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : Heuristic(transform, cache_estimates, description, verbosity), function(move(function)) { } -PotentialHeuristic::~PotentialHeuristic() { -} int PotentialHeuristic::compute_heuristic(const State &ancestor_state) { State state = convert_ancestor_state(ancestor_state); diff --git a/src/search/potentials/potential_heuristic.h b/src/search/potentials/potential_heuristic.h index 387788a44..d47528f3b 100644 --- a/src/search/potentials/potential_heuristic.h +++ b/src/search/potentials/potential_heuristic.h @@ -19,9 +19,10 @@ class PotentialHeuristic : public Heuristic { public: explicit PotentialHeuristic( - const plugins::Options &opts, std::unique_ptr function); - // Define in .cc file to avoid include in header. - ~PotentialHeuristic(); + std::unique_ptr function, + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); }; } diff --git a/src/search/potentials/potential_max_heuristic.cc b/src/search/potentials/potential_max_heuristic.cc index 912f4fab1..bd00caf72 100644 --- a/src/search/potentials/potential_max_heuristic.cc +++ b/src/search/potentials/potential_max_heuristic.cc @@ -8,9 +8,10 @@ using namespace std; namespace potentials { PotentialMaxHeuristic::PotentialMaxHeuristic( - const plugins::Options &opts, - vector> &&functions) - : Heuristic(opts), + vector> &&functions, + const shared_ptr &transform, bool cache_estimates, + const string &description, utils::Verbosity verbosity) + : Heuristic(transform, cache_estimates, description, verbosity), functions(move(functions)) { } diff --git a/src/search/potentials/potential_max_heuristic.h b/src/search/potentials/potential_max_heuristic.h index 66c573732..fd095ee5c 100644 --- a/src/search/potentials/potential_max_heuristic.h +++ b/src/search/potentials/potential_max_heuristic.h @@ -19,10 +19,11 @@ class PotentialMaxHeuristic : public Heuristic { virtual int compute_heuristic(const State &ancestor_state) override; public: - explicit PotentialMaxHeuristic( - const plugins::Options &opts, - std::vector> &&functions); - ~PotentialMaxHeuristic() = default; + PotentialMaxHeuristic( + std::vector> &&functions, + const std::shared_ptr &transform, + bool cache_estimates, const std::string &description, + utils::Verbosity verbosity); }; } diff --git a/src/search/potentials/potential_optimizer.cc b/src/search/potentials/potential_optimizer.cc index e6eb2e2df..43479baa2 100644 --- a/src/search/potentials/potential_optimizer.cc +++ b/src/search/potentials/potential_optimizer.cc @@ -19,11 +19,13 @@ static int get_undefined_value(VariableProxy var) { return var.get_domain_size(); } -PotentialOptimizer::PotentialOptimizer(const plugins::Options &opts) - : task(opts.get>("transform")), +PotentialOptimizer::PotentialOptimizer( + const shared_ptr &transform, + lp::LPSolverType lpsolver, double max_potential) + : task(transform), task_proxy(*task), - lp_solver(opts.get("lpsolver")), - max_potential(opts.get("max_potential")), + lp_solver(lpsolver), + max_potential(max_potential), num_lp_vars(0) { task_properties::verify_no_axioms(task_proxy); task_properties::verify_no_conditional_effects(task_proxy); diff --git a/src/search/potentials/potential_optimizer.h b/src/search/potentials/potential_optimizer.h index fe5dca83d..cea876ad7 100644 --- a/src/search/potentials/potential_optimizer.h +++ b/src/search/potentials/potential_optimizer.h @@ -57,7 +57,9 @@ class PotentialOptimizer { void extract_lp_solution(); public: - explicit PotentialOptimizer(const plugins::Options &opts); + PotentialOptimizer( + const std::shared_ptr &transform, + lp::LPSolverType lpsolver, double max_potential); ~PotentialOptimizer() = default; std::shared_ptr get_task() const; diff --git a/src/search/potentials/sample_based_potential_heuristics.cc b/src/search/potentials/sample_based_potential_heuristics.cc index e11696559..dfe2184c2 100644 --- a/src/search/potentials/sample_based_potential_heuristics.cc +++ b/src/search/potentials/sample_based_potential_heuristics.cc @@ -40,19 +40,24 @@ static void optimize_for_samples( Compute multiple potential functions that are optimized for different sets of samples. */ -static vector> create_sample_based_potential_functions( - const plugins::Options &opts) { +static vector> +create_sample_based_potential_functions( + int num_samples, int num_heuristics, double max_potential, + lp::LPSolverType lpsolver, + const shared_ptr &transform, int random_seed) { vector> functions; - PotentialOptimizer optimizer(opts); - shared_ptr rng(utils::parse_rng_from_options(opts)); - for (int i = 0; i < opts.get("num_heuristics"); ++i) { - optimize_for_samples(optimizer, opts.get("num_samples"), *rng); + PotentialOptimizer optimizer(transform, lpsolver, max_potential); + shared_ptr rng( + utils::get_rng(random_seed)); + for (int i = 0; i < num_heuristics; ++i) { + optimize_for_samples(optimizer, num_samples, *rng); functions.push_back(optimizer.get_potential_function()); } return functions; } -class SampleBasedPotentialMaxHeuristicFeature : public plugins::TypedFeature { +class SampleBasedPotentialMaxHeuristicFeature + : public plugins::TypedFeature { public: SampleBasedPotentialMaxHeuristicFeature() : TypedFeature("sample_based_potentials") { document_subcategory("heuristics_potentials"); @@ -70,13 +75,28 @@ class SampleBasedPotentialMaxHeuristicFeature : public plugins::TypedFeature create_component(const plugins::Options &options, const utils::Context &) const override { + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { return make_shared( - options, create_sample_based_potential_functions(options)); + create_sample_based_potential_functions( + opts.get("num_samples"), + opts.get("num_heuristics"), + opts.get("max_potential"), + opts.get("lpsolver"), + opts.get>("transform"), + opts.get("random_seed") + ), + opts.get>("transform"), + opts.get("cache_estimates"), + opts.get("description"), + opts.get("verbosity") + ); } }; diff --git a/src/search/potentials/single_potential_heuristics.cc b/src/search/potentials/single_potential_heuristics.cc index b9500fd08..fbe97a47e 100644 --- a/src/search/potentials/single_potential_heuristics.cc +++ b/src/search/potentials/single_potential_heuristics.cc @@ -15,9 +15,11 @@ enum class OptimizeFor { }; static unique_ptr create_potential_function( - const plugins::Options &opts, OptimizeFor opt_func) { - PotentialOptimizer optimizer(opts); - const AbstractTask &task = *opts.get>("transform"); + const shared_ptr &transform, + lp::LPSolverType lpsolver, double max_potential, + OptimizeFor opt_func) { + PotentialOptimizer optimizer(transform, lpsolver, max_potential); + const AbstractTask &task = *transform; TaskProxy task_proxy(task); switch (opt_func) { case OptimizeFor::INITIAL_STATE: @@ -32,35 +34,63 @@ static unique_ptr create_potential_function( return optimizer.get_potential_function(); } -class InitialStatePotentialHeuristicFeature : public plugins::TypedFeature { +class InitialStatePotentialHeuristicFeature + : public plugins::TypedFeature { public: InitialStatePotentialHeuristicFeature() : TypedFeature("initial_state_potential") { document_subcategory("heuristics_potentials"); document_title("Potential heuristic optimized for initial state"); document_synopsis(get_admissible_potentials_reference()); - prepare_parser_for_admissible_potentials(*this); + add_admissible_potentials_options_to_feature( + *this, "initial_state_potential"); } - virtual shared_ptr create_component(const plugins::Options &options, const utils::Context &) const override { - return make_shared(options, create_potential_function(options, OptimizeFor::INITIAL_STATE)); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return make_shared( + create_potential_function( + opts.get>("transform"), + opts.get("lpsolver"), + opts.get("max_potential"), + OptimizeFor::INITIAL_STATE), + opts.get>("transform"), + opts.get("cache_estimates"), + opts.get("description"), + opts.get("verbosity") + ); } }; static plugins::FeaturePlugin _plugin_initial_state; -class AllStatesPotentialHeuristicFeature : public plugins::TypedFeature { +class AllStatesPotentialHeuristicFeature + : public plugins::TypedFeature { public: AllStatesPotentialHeuristicFeature() : TypedFeature("all_states_potential") { document_subcategory("heuristics_potentials"); document_title("Potential heuristic optimized for all states"); document_synopsis(get_admissible_potentials_reference()); - prepare_parser_for_admissible_potentials(*this); + add_admissible_potentials_options_to_feature( + *this, "all_states_potential"); } - virtual shared_ptr create_component(const plugins::Options &options, const utils::Context &) const override { - return make_shared(options, create_potential_function(options, OptimizeFor::ALL_STATES)); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return make_shared( + create_potential_function( + opts.get>("transform"), + opts.get("lpsolver"), + opts.get("max_potential"), + OptimizeFor::ALL_STATES), + opts.get>("transform"), + opts.get("cache_estimates"), + opts.get("description"), + opts.get("verbosity") + ); } }; diff --git a/src/search/potentials/util.cc b/src/search/potentials/util.cc index 4929e72e6..98624779f 100644 --- a/src/search/potentials/util.cc +++ b/src/search/potentials/util.cc @@ -44,7 +44,8 @@ string get_admissible_potentials_reference() { "2015"); } -void prepare_parser_for_admissible_potentials(plugins::Feature &feature) { +void add_admissible_potentials_options_to_feature( + plugins::Feature &feature, const string &description) { feature.document_language_support("action costs", "supported"); feature.document_language_support("conditional effects", "not supported"); feature.document_language_support("axioms", "not supported"); @@ -63,6 +64,18 @@ void prepare_parser_for_admissible_potentials(plugins::Feature &feature) { "1e8", plugins::Bounds("0.0", "infinity")); lp::add_lp_solver_option_to_feature(feature); - Heuristic::add_options_to_feature(feature); + add_heuristic_options_to_feature(feature, description); +} + + +tuple, bool, string, + utils::Verbosity> +get_admissible_potential_arguments_from_options( + const plugins::Options &opts) { + return tuple_cat( + make_tuple(opts.get("max_potential")), + lp::get_lp_solver_arguments_from_options(opts), + get_heuristic_arguments_from_options(opts) + ); } } diff --git a/src/search/potentials/util.h b/src/search/potentials/util.h index d656d3354..41b30e7b5 100644 --- a/src/search/potentials/util.h +++ b/src/search/potentials/util.h @@ -4,11 +4,16 @@ #include #include #include +#include "../lp/lp_solver.h" +#include "../utils/logging.h" + +class AbstractTask; class State; namespace plugins { class Feature; +class Options; } namespace utils { @@ -24,7 +29,12 @@ std::vector sample_without_dead_end_detection( utils::RandomNumberGenerator &rng); std::string get_admissible_potentials_reference(); -void prepare_parser_for_admissible_potentials(plugins::Feature &feature); +void add_admissible_potentials_options_to_feature( + plugins::Feature &feature, const std::string &description); +std::tuple, + bool, std::string, utils::Verbosity> +get_admissible_potential_arguments_from_options( + const plugins::Options &opts); } #endif diff --git a/src/search/pruning/limited_pruning.cc b/src/search/pruning/limited_pruning.cc index 2a2f29016..51cba6b4e 100644 --- a/src/search/pruning/limited_pruning.cc +++ b/src/search/pruning/limited_pruning.cc @@ -6,12 +6,16 @@ using namespace std; namespace limited_pruning { -LimitedPruning::LimitedPruning(const plugins::Options &opts) - : PruningMethod(opts), - pruning_method(opts.get>("pruning")), - min_required_pruning_ratio(opts.get("min_required_pruning_ratio")), +LimitedPruning::LimitedPruning( + const shared_ptr &pruning, + double min_required_pruning_ratio, + int expansions_before_checking_pruning_ratio, + utils::Verbosity verbosity) + : PruningMethod(verbosity), + pruning_method(pruning), + min_required_pruning_ratio(min_required_pruning_ratio), num_expansions_before_checking_pruning_ratio( - opts.get("expansions_before_checking_pruning_ratio")), + expansions_before_checking_pruning_ratio), num_pruning_calls(0), is_pruning_disabled(false) { } @@ -49,7 +53,8 @@ void LimitedPruning::prune( pruning_method->prune(state, op_ids); } -class LimitedPruningFeature : public plugins::TypedFeature { +class LimitedPruningFeature + : public plugins::TypedFeature { public: LimitedPruningFeature() : TypedFeature("limited_pruning") { document_title("Limited pruning"); @@ -83,6 +88,16 @@ class LimitedPruningFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get>("pruning"), + opts.get("min_required_pruning_ratio"), + opts.get("expansions_before_checking_pruning_ratio"), + get_pruning_arguments_from_options(opts)); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pruning/limited_pruning.h b/src/search/pruning/limited_pruning.h index 557fb2b64..11b4c89d7 100644 --- a/src/search/pruning/limited_pruning.h +++ b/src/search/pruning/limited_pruning.h @@ -18,7 +18,11 @@ class LimitedPruning : public PruningMethod { virtual void prune( const State &state, std::vector &op_ids) override; public: - explicit LimitedPruning(const plugins::Options &opts); + explicit LimitedPruning( + const std::shared_ptr &pruning, + double min_required_pruning_ratio, + int expansions_before_checking_pruning_ratio, + utils::Verbosity verbosity); virtual void initialize(const std::shared_ptr &) override; }; } diff --git a/src/search/pruning/null_pruning_method.cc b/src/search/pruning/null_pruning_method.cc index 1aa285da3..5102b8016 100644 --- a/src/search/pruning/null_pruning_method.cc +++ b/src/search/pruning/null_pruning_method.cc @@ -6,8 +6,8 @@ using namespace std; namespace null_pruning_method { -NullPruningMethod::NullPruningMethod(const plugins::Options &opts) - : PruningMethod(opts) { +NullPruningMethod::NullPruningMethod(utils::Verbosity verbosity) + : PruningMethod(verbosity) { } void NullPruningMethod::initialize(const shared_ptr &task) { @@ -15,7 +15,8 @@ void NullPruningMethod::initialize(const shared_ptr &task) { log << "pruning method: none" << endl; } -class NullPruningMethodFeature : public plugins::TypedFeature { +class NullPruningMethodFeature + : public plugins::TypedFeature { public: NullPruningMethodFeature() : TypedFeature("null") { // document_group(""); @@ -26,6 +27,13 @@ class NullPruningMethodFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_pruning_arguments_from_options(opts)); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pruning/null_pruning_method.h b/src/search/pruning/null_pruning_method.h index acd93092c..3f857dd87 100644 --- a/src/search/pruning/null_pruning_method.h +++ b/src/search/pruning/null_pruning_method.h @@ -8,7 +8,7 @@ class NullPruningMethod : public PruningMethod { virtual void prune( const State &, std::vector &) override {} public: - explicit NullPruningMethod(const plugins::Options &opts); + explicit NullPruningMethod(utils::Verbosity verbosity); virtual void initialize(const std::shared_ptr &) override; virtual void print_statistics() const override {} }; diff --git a/src/search/pruning/stubborn_sets.cc b/src/search/pruning/stubborn_sets.cc index 9d1a65ae8..78005aebe 100644 --- a/src/search/pruning/stubborn_sets.cc +++ b/src/search/pruning/stubborn_sets.cc @@ -6,8 +6,8 @@ using namespace std; namespace stubborn_sets { -StubbornSets::StubbornSets(const plugins::Options &opts) - : PruningMethod(opts), +StubbornSets::StubbornSets(utils::Verbosity verbosity) + : PruningMethod(verbosity), num_operators(-1) { } diff --git a/src/search/pruning/stubborn_sets.h b/src/search/pruning/stubborn_sets.h index a5841d3f4..402395dde 100644 --- a/src/search/pruning/stubborn_sets.h +++ b/src/search/pruning/stubborn_sets.h @@ -54,7 +54,7 @@ class StubbornSets : public PruningMethod { virtual void compute_stubborn_set(const State &state) = 0; public: - explicit StubbornSets(const plugins::Options &opts); + explicit StubbornSets(utils::Verbosity verbosity); virtual void initialize(const std::shared_ptr &task) override; }; diff --git a/src/search/pruning/stubborn_sets_action_centric.cc b/src/search/pruning/stubborn_sets_action_centric.cc index 23c5a2117..e0871a4fd 100644 --- a/src/search/pruning/stubborn_sets_action_centric.cc +++ b/src/search/pruning/stubborn_sets_action_centric.cc @@ -23,8 +23,9 @@ static bool contain_conflicting_fact(const vector &facts1, return false; } -StubbornSetsActionCentric::StubbornSetsActionCentric(const plugins::Options &opts) - : StubbornSets(opts) { +StubbornSetsActionCentric::StubbornSetsActionCentric( + utils::Verbosity verbosity) + : StubbornSets(verbosity) { } void StubbornSetsActionCentric::compute_stubborn_set(const State &state) { diff --git a/src/search/pruning/stubborn_sets_action_centric.h b/src/search/pruning/stubborn_sets_action_centric.h index b859a9568..cde64cfb4 100644 --- a/src/search/pruning/stubborn_sets_action_centric.h +++ b/src/search/pruning/stubborn_sets_action_centric.h @@ -17,7 +17,7 @@ class StubbornSetsActionCentric : public stubborn_sets::StubbornSets { virtual void handle_stubborn_operator(const State &state, int op_no) = 0; virtual void compute_stubborn_set(const State &state) override; protected: - explicit StubbornSetsActionCentric(const plugins::Options &opts); + explicit StubbornSetsActionCentric(utils::Verbosity verbosity); bool can_disable(int op1_no, int op2_no) const; bool can_conflict(int op1_no, int op2_no) const; diff --git a/src/search/pruning/stubborn_sets_atom_centric.cc b/src/search/pruning/stubborn_sets_atom_centric.cc index 302c52fbd..5d52fc092 100644 --- a/src/search/pruning/stubborn_sets_atom_centric.cc +++ b/src/search/pruning/stubborn_sets_atom_centric.cc @@ -9,10 +9,13 @@ using namespace std; namespace stubborn_sets_atom_centric { -StubbornSetsAtomCentric::StubbornSetsAtomCentric(const plugins::Options &opts) - : StubbornSets(opts), - use_sibling_shortcut(opts.get("use_sibling_shortcut")), - atom_selection_strategy(opts.get("atom_selection_strategy")) { +StubbornSetsAtomCentric::StubbornSetsAtomCentric( + bool use_sibling_shortcut, + AtomSelectionStrategy atom_selection_strategy, + utils::Verbosity verbosity) + : StubbornSets(verbosity), + use_sibling_shortcut(use_sibling_shortcut), + atom_selection_strategy(atom_selection_strategy) { } void StubbornSetsAtomCentric::initialize(const shared_ptr &task) { @@ -242,7 +245,8 @@ void StubbornSetsAtomCentric::handle_stubborn_operator(const State &state, int o } } -class StubbornSetsAtomCentricFeature : public plugins::TypedFeature { +class StubbornSetsAtomCentricFeature + : public plugins::TypedFeature { public: StubbornSetsAtomCentricFeature() : TypedFeature("atom_centric_stubborn_sets") { document_title("Atom-centric stubborn sets"); @@ -275,6 +279,15 @@ class StubbornSetsAtomCentricFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get("use_sibling_shortcut"), + opts.get("atom_selection_strategy"), + get_pruning_arguments_from_options(opts)); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pruning/stubborn_sets_atom_centric.h b/src/search/pruning/stubborn_sets_atom_centric.h index 95c364bb1..091fc25d3 100644 --- a/src/search/pruning/stubborn_sets_atom_centric.h +++ b/src/search/pruning/stubborn_sets_atom_centric.h @@ -51,7 +51,10 @@ class StubbornSetsAtomCentric : public stubborn_sets::StubbornSets { void handle_stubborn_operator(const State &state, int op); virtual void compute_stubborn_set(const State &state) override; public: - explicit StubbornSetsAtomCentric(const plugins::Options &opts); + explicit StubbornSetsAtomCentric( + bool use_sibling_shortcut, + AtomSelectionStrategy atom_selection_strategy, + utils::Verbosity verbosity); virtual void initialize(const std::shared_ptr &task) override; }; } diff --git a/src/search/pruning/stubborn_sets_ec.cc b/src/search/pruning/stubborn_sets_ec.cc index aee27e142..f58e4bf37 100644 --- a/src/search/pruning/stubborn_sets_ec.cc +++ b/src/search/pruning/stubborn_sets_ec.cc @@ -102,8 +102,8 @@ static void get_conflicting_vars(const vector &facts1, } } -StubbornSetsEC::StubbornSetsEC(const plugins::Options &opts) - : StubbornSetsActionCentric(opts) { +StubbornSetsEC::StubbornSetsEC(utils::Verbosity verbosity) + : StubbornSetsActionCentric(verbosity) { } void StubbornSetsEC::initialize(const shared_ptr &task) { @@ -324,7 +324,8 @@ void StubbornSetsEC::handle_stubborn_operator(const State &state, int op_no) { } } -class StubbornSetsECFeature : public plugins::TypedFeature { +class StubbornSetsECFeature + : public plugins::TypedFeature { public: StubbornSetsECFeature() : TypedFeature("stubborn_sets_ec") { document_title("StubbornSetsEC"); @@ -346,6 +347,13 @@ class StubbornSetsECFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_pruning_arguments_from_options(opts)); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pruning/stubborn_sets_ec.h b/src/search/pruning/stubborn_sets_ec.h index 5cc6e0c3c..8ac60024b 100644 --- a/src/search/pruning/stubborn_sets_ec.h +++ b/src/search/pruning/stubborn_sets_ec.h @@ -32,7 +32,7 @@ class StubbornSetsEC : public stubborn_sets::StubbornSetsActionCentric { virtual void initialize_stubborn_set(const State &state) override; virtual void handle_stubborn_operator(const State &state, int op_no) override; public: - explicit StubbornSetsEC(const plugins::Options &opts); + explicit StubbornSetsEC(utils::Verbosity verbosity); virtual void initialize(const std::shared_ptr &task) override; }; } diff --git a/src/search/pruning/stubborn_sets_simple.cc b/src/search/pruning/stubborn_sets_simple.cc index eb95a3daf..5fc2123d7 100644 --- a/src/search/pruning/stubborn_sets_simple.cc +++ b/src/search/pruning/stubborn_sets_simple.cc @@ -7,8 +7,8 @@ using namespace std; namespace stubborn_sets_simple { -StubbornSetsSimple::StubbornSetsSimple(const plugins::Options &opts) - : StubbornSetsActionCentric(opts) { +StubbornSetsSimple::StubbornSetsSimple(utils::Verbosity verbosity) + : StubbornSetsActionCentric(verbosity) { } void StubbornSetsSimple::initialize(const shared_ptr &task) { @@ -73,7 +73,8 @@ void StubbornSetsSimple::handle_stubborn_operator(const State &state, } } -class StubbornSetsSimpleFeature : public plugins::TypedFeature { +class StubbornSetsSimpleFeature + : public plugins::TypedFeature { public: StubbornSetsSimpleFeature() : TypedFeature("stubborn_sets_simple") { document_title("Stubborn sets simple"); @@ -104,6 +105,13 @@ class StubbornSetsSimpleFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + get_pruning_arguments_from_options(opts)); + } }; static plugins::FeaturePlugin _plugin; diff --git a/src/search/pruning/stubborn_sets_simple.h b/src/search/pruning/stubborn_sets_simple.h index 5f9db288e..2a6d8366b 100644 --- a/src/search/pruning/stubborn_sets_simple.h +++ b/src/search/pruning/stubborn_sets_simple.h @@ -26,7 +26,7 @@ class StubbornSetsSimple : public stubborn_sets::StubbornSetsActionCentric { virtual void handle_stubborn_operator(const State &state, int op_no) override; public: - explicit StubbornSetsSimple(const plugins::Options &opts); + explicit StubbornSetsSimple(utils::Verbosity verbosity); virtual void initialize(const std::shared_ptr &task) override; }; } diff --git a/src/search/pruning_method.cc b/src/search/pruning_method.cc index 519761d0b..1c2a3e060 100644 --- a/src/search/pruning_method.cc +++ b/src/search/pruning_method.cc @@ -9,9 +9,9 @@ using namespace std; -PruningMethod::PruningMethod(const plugins::Options &opts) +PruningMethod::PruningMethod(utils::Verbosity verbosity) : timer(false), - log(utils::get_log_from_options(opts)), + log(utils::get_log_for_verbosity(verbosity)), task(nullptr) { } @@ -69,6 +69,11 @@ void add_pruning_options_to_feature(plugins::Feature &feature) { "normal verbosity for running experiments."); } +tuple get_pruning_arguments_from_options( + const plugins::Options &opts) { + return utils::get_log_arguments_from_options(opts); +} + static class PruningMethodCategoryPlugin : public plugins::TypedCategoryPlugin { public: PruningMethodCategoryPlugin() : TypedCategoryPlugin("PruningMethod") { diff --git a/src/search/pruning_method.h b/src/search/pruning_method.h index 531f3771a..11f7521d7 100644 --- a/src/search/pruning_method.h +++ b/src/search/pruning_method.h @@ -33,7 +33,7 @@ class PruningMethod { long num_successors_before_pruning; long num_successors_after_pruning; public: - explicit PruningMethod(const plugins::Options &opts); + explicit PruningMethod(utils::Verbosity verbosity); virtual ~PruningMethod() = default; virtual void initialize(const std::shared_ptr &task); void prune_operators(const State &state, std::vector &op_ids); @@ -41,5 +41,7 @@ class PruningMethod { }; extern void add_pruning_options_to_feature(plugins::Feature &feature); +extern std::tuple get_pruning_arguments_from_options( + const plugins::Options &opts); #endif diff --git a/src/search/search_algorithm.cc b/src/search/search_algorithm.cc index ee9f30811..c018c45c6 100644 --- a/src/search/search_algorithm.cc +++ b/src/search/search_algorithm.cc @@ -20,7 +20,6 @@ using namespace std; using utils::ExitCode; -class PruningMethod; static successor_generator::SuccessorGenerator &get_successor_generator( const TaskProxy &task_proxy, utils::LogProxy &log) { @@ -40,13 +39,38 @@ static successor_generator::SuccessorGenerator &get_successor_generator( return successor_generator; } -SearchAlgorithm::SearchAlgorithm(const plugins::Options &opts) +SearchAlgorithm::SearchAlgorithm( + OperatorCost cost_type, int bound, double max_time, + const string &description, utils::Verbosity verbosity) + : description(description), + status(IN_PROGRESS), + solution_found(false), + task(tasks::g_root_task), + task_proxy(*task), + log(utils::get_log_for_verbosity(verbosity)), + state_registry(task_proxy), + successor_generator(get_successor_generator(task_proxy, log)), + search_space(state_registry, log), + statistics(log), + bound(bound), + cost_type(cost_type), + is_unit_cost(task_properties::is_unit_cost(task_proxy)), + max_time(max_time) { + if (bound < 0) { + cerr << "error: negative cost bound " << bound << endl; + utils::exit_with(ExitCode::SEARCH_INPUT_ERROR); + } + task_properties::print_variable_statistics(task_proxy); +} + +SearchAlgorithm::SearchAlgorithm(const plugins::Options &opts) // TODO options object is needed for iterated search, the prototype for issue559 resolves this : description(opts.get_unparsed_config()), status(IN_PROGRESS), solution_found(false), task(tasks::g_root_task), task_proxy(*task), - log(utils::get_log_from_options(opts)), + log(utils::get_log_for_verbosity( + opts.get("verbosity"))), state_registry(task_proxy), successor_generator(get_successor_generator(task_proxy, log)), search_space(state_registry, log), @@ -119,12 +143,25 @@ int SearchAlgorithm::get_adjusted_cost(const OperatorProxy &op) const { return get_adjusted_action_cost(op, cost_type, is_unit_cost); } + + +void print_initial_evaluator_values( + const EvaluationContext &eval_context) { + eval_context.get_cache().for_each_evaluator_result( + [] (const Evaluator *eval, const EvaluationResult &result) { + if (eval->is_used_for_reporting_minima()) { + eval->report_value_for_initial_state(result); + } + } + ); +} + /* TODO: merge this into add_options_to_feature when all search algorithms support pruning. Method doesn't belong here because it's only useful for certain derived classes. TODO: Figure out where it belongs and move it there. */ -void SearchAlgorithm::add_pruning_option(plugins::Feature &feature) { +void add_search_pruning_options_to_feature(plugins::Feature &feature) { feature.add_option>( "pruning", "Pruning methods can prune or reorder the set of applicable operators in " @@ -133,8 +170,15 @@ void SearchAlgorithm::add_pruning_option(plugins::Feature &feature) { "null()"); } -void SearchAlgorithm::add_options_to_feature(plugins::Feature &feature) { - ::add_cost_type_option_to_feature(feature); +tuple> +get_search_pruning_arguments_from_options( + const plugins::Options &opts) { + return make_tuple(opts.get>("pruning")); +} + +void add_search_algorithm_options_to_feature( + plugins::Feature &feature, const string &description) { + ::add_cost_type_options_to_feature(feature); feature.add_option( "bound", "exclusive depth bound on g-values. Cutoffs are always performed according to " @@ -148,13 +192,31 @@ void SearchAlgorithm::add_options_to_feature(plugins::Feature &feature) { "experiments. Timed-out searches are treated as failed searches, " "just like incomplete search algorithms that exhaust their search space.", "infinity"); + feature.add_option( + "description", + "description used to identify search algorithm in logs", + "\"" + description + "\""); utils::add_log_options_to_feature(feature); } +tuple +get_search_algorithm_arguments_from_options( + const plugins::Options &opts) { + return tuple_cat( + ::get_cost_type_arguments_from_options(opts), + make_tuple( + opts.get("bound"), + opts.get("max_time"), + opts.get("description") + ), + utils::get_log_arguments_from_options(opts) + ); +} + /* Method doesn't belong here because it's only useful for certain derived classes. TODO: Figure out where it belongs and move it there. */ -void SearchAlgorithm::add_succ_order_options(plugins::Feature &feature) { - vector options; +void add_successors_order_options_to_feature( + plugins::Feature &feature) { feature.add_option( "randomize_successors", "randomize the order in which successors are generated", @@ -168,17 +230,17 @@ void SearchAlgorithm::add_succ_order_options(plugins::Feature &feature) { "When using randomize_successors=true and " "preferred_successors_first=true, randomization happens before " "preferred operators are moved to the front."); - utils::add_rng_options(feature); + utils::add_rng_options_to_feature(feature); } -void print_initial_evaluator_values( - const EvaluationContext &eval_context) { - eval_context.get_cache().for_each_evaluator_result( - [] (const Evaluator *eval, const EvaluationResult &result) { - if (eval->is_used_for_reporting_minima()) { - eval->report_value_for_initial_state(result); - } - } +tuple get_successors_order_arguments_from_options( + const plugins::Options &opts) { + return tuple_cat( + make_tuple( + opts.get("randomize_successors"), + opts.get("preferred_successors_first") + ), + utils::get_rng_arguments_from_options(opts) ); } diff --git a/src/search/search_algorithm.h b/src/search/search_algorithm.h index 32cbb6c86..29103c7b0 100644 --- a/src/search/search_algorithm.h +++ b/src/search/search_algorithm.h @@ -60,7 +60,10 @@ class SearchAlgorithm { bool check_goal_and_set_plan(const State &state); int get_adjusted_cost(const OperatorProxy &op) const; public: - SearchAlgorithm(const plugins::Options &opts); + SearchAlgorithm( + OperatorCost cost_type, int bound, double max_time, + const std::string &description, utils::Verbosity verbosity); + explicit SearchAlgorithm(const plugins::Options &opts); // TODO options object is needed for iterated search, the prototype for issue559 resolves this virtual ~SearchAlgorithm(); virtual void print_statistics() const = 0; virtual void save_plan_if_necessary(); @@ -73,12 +76,6 @@ class SearchAlgorithm { int get_bound() {return bound;} PlanManager &get_plan_manager() {return plan_manager;} std::string get_description() {return description;} - - /* The following three methods should become functions as they - do not require access to private/protected class members. */ - static void add_pruning_option(plugins::Feature &feature); - static void add_options_to_feature(plugins::Feature &feature); - static void add_succ_order_options(plugins::Feature &feature); }; /* @@ -91,4 +88,22 @@ extern void collect_preferred_operators( EvaluationContext &eval_context, Evaluator *preferred_operator_evaluator, ordered_set::OrderedSet &preferred_operators); +class PruningMethod; + +extern void add_search_pruning_options_to_feature( + plugins::Feature &feature); +extern std::tuple> +get_search_pruning_arguments_from_options(const plugins::Options &opts); +extern void add_search_algorithm_options_to_feature( + plugins::Feature &feature, const std::string &description); +extern std::tuple< + OperatorCost, int, double, std::string, utils::Verbosity> +get_search_algorithm_arguments_from_options( + const plugins::Options &opts); +extern void add_successors_order_options_to_feature( + plugins::Feature &feature); +extern std::tuple +get_successors_order_arguments_from_options( + const plugins::Options &opts); + #endif diff --git a/src/search/search_algorithms/eager_search.cc b/src/search/search_algorithms/eager_search.cc index 74a91808b..5ec760e57 100644 --- a/src/search/search_algorithms/eager_search.cc +++ b/src/search/search_algorithms/eager_search.cc @@ -19,15 +19,22 @@ using namespace std; namespace eager_search { -EagerSearch::EagerSearch(const plugins::Options &opts) - : SearchAlgorithm(opts), - reopen_closed_nodes(opts.get("reopen_closed")), - open_list(opts.get>("open")-> - create_state_open_list()), - f_evaluator(opts.get>("f_eval", nullptr)), - preferred_operator_evaluators(opts.get_list>("preferred")), - lazy_evaluator(opts.get>("lazy_evaluator", nullptr)), - pruning_method(opts.get>("pruning")) { +EagerSearch::EagerSearch( + const shared_ptr &open, bool reopen_closed, + const shared_ptr &f_eval, + const vector> &preferred, + const shared_ptr &pruning, + const shared_ptr &lazy_evaluator, OperatorCost cost_type, + int bound, double max_time, const string &description, + utils::Verbosity verbosity) + : SearchAlgorithm( + cost_type, bound, max_time, description, verbosity), + reopen_closed_nodes(reopen_closed), + open_list(open->create_state_open_list()), + f_evaluator(f_eval), // default nullptr + preferred_operator_evaluators(preferred), + lazy_evaluator(lazy_evaluator), // default nullptr + pruning_method(pruning) { if (lazy_evaluator && !lazy_evaluator->does_cache_estimates()) { cerr << "lazy_evaluator must cache its estimates" << endl; utils::exit_with(utils::ExitCode::SEARCH_INPUT_ERROR); @@ -307,8 +314,22 @@ void EagerSearch::update_f_value_statistics(EvaluationContext &eval_context) { } } -void add_options_to_feature(plugins::Feature &feature) { - SearchAlgorithm::add_pruning_option(feature); - SearchAlgorithm::add_options_to_feature(feature); +void add_eager_search_options_to_feature( + plugins::Feature &feature, const string &description) { + add_search_pruning_options_to_feature(feature); + // We do not add a lazy_evaluator options here + // because it is only used for astar but not the other plugins. + add_search_algorithm_options_to_feature(feature, description); +} + +tuple, shared_ptr, OperatorCost, + int, double, string, utils::Verbosity> +get_eager_search_arguments_from_options(const plugins::Options &opts) { + return tuple_cat( + get_search_pruning_arguments_from_options(opts), + make_tuple(opts.get>( + "lazy_evaluator", nullptr)), + get_search_algorithm_arguments_from_options(opts) + ); } } diff --git a/src/search/search_algorithms/eager_search.h b/src/search/search_algorithms/eager_search.h index fcd9399ad..bb328e1fc 100644 --- a/src/search/search_algorithms/eager_search.h +++ b/src/search/search_algorithms/eager_search.h @@ -9,6 +9,7 @@ class Evaluator; class PruningMethod; +class OpenListFactory; namespace plugins { class Feature; @@ -36,15 +37,26 @@ class EagerSearch : public SearchAlgorithm { virtual SearchStatus step() override; public: - explicit EagerSearch(const plugins::Options &opts); - virtual ~EagerSearch() = default; + explicit EagerSearch( + const std::shared_ptr &open, + bool reopen_closed, const std::shared_ptr &f_eval, + const std::vector> &preferred, + const std::shared_ptr &pruning, + const std::shared_ptr &lazy_evaluator, + OperatorCost cost_type, int bound, double max_time, + const std::string &description, utils::Verbosity verbosity); virtual void print_statistics() const override; void dump_search_space() const; }; -extern void add_options_to_feature(plugins::Feature &feature); +extern void add_eager_search_options_to_feature( + plugins::Feature &feature, const std::string &description); +extern std::tuple, + std::shared_ptr, OperatorCost, int, double, + std::string, utils::Verbosity> +get_eager_search_arguments_from_options(const plugins::Options &opts); } #endif diff --git a/src/search/search_algorithms/enforced_hill_climbing_search.cc b/src/search/search_algorithms/enforced_hill_climbing_search.cc index 73509fe9d..3899753ad 100644 --- a/src/search/search_algorithms/enforced_hill_climbing_search.cc +++ b/src/search/search_algorithms/enforced_hill_climbing_search.cc @@ -18,31 +18,20 @@ using GEval = g_evaluator::GEvaluator; using PrefEval = pref_evaluator::PrefEvaluator; static shared_ptr create_ehc_open_list_factory( - const plugins::Options &opts, bool use_preferred, PreferredUsage preferred_usage) { + utils::Verbosity verbosity, bool use_preferred, + PreferredUsage preferred_usage) { /* TODO: this g-evaluator should probably be set up to always ignore costs since EHC is supposed to implement a breadth-first search, not a uniform-cost search. So this seems to be a bug. */ - plugins::Options g_evaluator_options; - g_evaluator_options.set( - "verbosity", opts.get("verbosity")); - shared_ptr g_evaluator = make_shared(g_evaluator_options); + shared_ptr g_evaluator = make_shared( + "ehc.g_eval", verbosity); if (!use_preferred || preferred_usage == PreferredUsage::PRUNE_BY_PREFERRED) { - /* - TODO: Reduce code duplication with search_common.cc, - function create_standard_scalar_open_list_factory. - - It would probably make sense to add a factory function or - constructor that encapsulates this work to the standard - scalar open list code. - */ - plugins::Options options; - options.set("eval", g_evaluator); - options.set("pref_only", false); - return make_shared(options); + return make_shared( + g_evaluator, false); } else { /* TODO: Reduce code duplication with search_common.cc, @@ -52,25 +41,25 @@ static shared_ptr create_ehc_open_list_factory( constructor that encapsulates this work to the tie-breaking open list code. */ - plugins::Options pref_evaluator_options; - pref_evaluator_options.set( - "verbosity", opts.get("verbosity")); - vector> evals = {g_evaluator, make_shared(pref_evaluator_options)}; - plugins::Options options; - options.set("evals", evals); - options.set("pref_only", false); - options.set("unsafe_pruning", true); - return make_shared(options); + vector> evals = { + g_evaluator, make_shared( + "ehc.pref_eval", verbosity)}; + return make_shared( + evals, false, true); } } EnforcedHillClimbingSearch::EnforcedHillClimbingSearch( - const plugins::Options &opts) - : SearchAlgorithm(opts), - evaluator(opts.get>("h")), - preferred_operator_evaluators(opts.get_list>("preferred")), - preferred_usage(opts.get("preferred_usage")), + const shared_ptr &h, PreferredUsage preferred_usage, + const vector> &preferred, + OperatorCost cost_type, int bound, double max_time, + const string &description, utils::Verbosity verbosity) + : SearchAlgorithm( + cost_type, bound, max_time, description, verbosity), + evaluator(h), + preferred_operator_evaluators(preferred), + preferred_usage(preferred_usage), current_eval_context(state_registry.get_initial_state(), &statistics), current_phase_start_g(-1), num_ehc_phases(0), @@ -89,11 +78,9 @@ EnforcedHillClimbingSearch::EnforcedHillClimbingSearch( preferred_operator_evaluators.end(); open_list = create_ehc_open_list_factory( - opts, use_preferred, preferred_usage)->create_edge_open_list(); + verbosity, use_preferred, preferred_usage)->create_edge_open_list(); } -EnforcedHillClimbingSearch::~EnforcedHillClimbingSearch() { -} void EnforcedHillClimbingSearch::reach_state( const State &parent, OperatorID op_id, const State &state) { @@ -271,7 +258,8 @@ void EnforcedHillClimbingSearch::print_statistics() const { } } -class EnforcedHillClimbingSearchFeature : public plugins::TypedFeature { +class EnforcedHillClimbingSearchFeature + : public plugins::TypedFeature { public: EnforcedHillClimbingSearchFeature() : TypedFeature("ehc") { document_title("Lazy enforced hill-climbing"); @@ -286,7 +274,18 @@ class EnforcedHillClimbingSearchFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get>("h"), + opts.get("preferred_usage"), + opts.get_list>("preferred"), + get_search_algorithm_arguments_from_options(opts) + ); } }; diff --git a/src/search/search_algorithms/enforced_hill_climbing_search.h b/src/search/search_algorithms/enforced_hill_climbing_search.h index f6f4c2303..f7b3247df 100644 --- a/src/search/search_algorithms/enforced_hill_climbing_search.h +++ b/src/search/search_algorithms/enforced_hill_climbing_search.h @@ -60,8 +60,12 @@ class EnforcedHillClimbingSearch : public SearchAlgorithm { virtual SearchStatus step() override; public: - explicit EnforcedHillClimbingSearch(const plugins::Options &opts); - virtual ~EnforcedHillClimbingSearch() override; + EnforcedHillClimbingSearch( + const std::shared_ptr &h, + PreferredUsage preferred_usage, + const std::vector> &preferred, + OperatorCost cost_type, int bound, double max_time, + const std::string &description, utils::Verbosity verbosity); virtual void print_statistics() const override; }; diff --git a/src/search/search_algorithms/iterated_search.cc b/src/search/search_algorithms/iterated_search.cc index fc7ea7bb7..83f66890b 100644 --- a/src/search/search_algorithms/iterated_search.cc +++ b/src/search/search_algorithms/iterated_search.cc @@ -129,7 +129,8 @@ void IteratedSearch::save_plan_if_necessary() { // each successful search iteration. } -class IteratedSearchFeature : public plugins::TypedFeature { +class IteratedSearchFeature + : public plugins::TypedFeature { public: IteratedSearchFeature() : TypedFeature("iterated") { document_title("Iterated search"); @@ -157,7 +158,7 @@ class IteratedSearchFeature : public plugins::TypedFeature>("open")-> - create_edge_open_list()), - reopen_closed_nodes(opts.get("reopen_closed")), - randomize_successors(opts.get("randomize_successors")), - preferred_successors_first(opts.get("preferred_successors_first")), - rng(utils::parse_rng_from_options(opts)), +LazySearch::LazySearch( + const shared_ptr &open, bool reopen_closed, + const vector> &preferred, + bool randomize_successors, bool preferred_successors_first, + int random_seed, OperatorCost cost_type, int bound, double max_time, + const string &description, utils::Verbosity verbosity) + : SearchAlgorithm( + cost_type, bound, max_time, description, verbosity), + open_list(open->create_edge_open_list()), + reopen_closed_nodes(reopen_closed), + randomize_successors(randomize_successors), + preferred_successors_first(preferred_successors_first), + rng(utils::get_rng(random_seed)), + preferred_operator_evaluators(preferred), current_state(state_registry.get_initial_state()), current_predecessor_id(StateID::no_state), current_operator_id(OperatorID::no_operator), @@ -37,11 +43,6 @@ LazySearch::LazySearch(const plugins::Options &opts) */ } -void LazySearch::set_preferred_operator_evaluators( - vector> &evaluators) { - preferred_operator_evaluators = evaluators; -} - void LazySearch::initialize() { log << "Conducting lazy best first search, (real) bound = " << bound << endl; diff --git a/src/search/search_algorithms/lazy_search.h b/src/search/search_algorithms/lazy_search.h index e63ee6d97..3c5ac25eb 100644 --- a/src/search/search_algorithms/lazy_search.h +++ b/src/search/search_algorithms/lazy_search.h @@ -14,6 +14,8 @@ #include #include +class OpenListFactory; + namespace lazy_search { class LazySearch : public SearchAlgorithm { protected: @@ -47,10 +49,14 @@ class LazySearch : public SearchAlgorithm { const ordered_set::OrderedSet &preferred_operators) const; public: - explicit LazySearch(const plugins::Options &opts); - virtual ~LazySearch() = default; - - void set_preferred_operator_evaluators(std::vector> &evaluators); + LazySearch( + const std::shared_ptr &open, + bool reopen_closed, + const std::vector> &evaluators, + bool randomize_successors, bool preferred_successors_first, + int random_seed, OperatorCost cost_type, int bound, + double max_time, const std::string &description, + utils::Verbosity verbosity); virtual void print_statistics() const override; }; diff --git a/src/search/search_algorithms/plugin_astar.cc b/src/search/search_algorithms/plugin_astar.cc index 0b1b4abd4..d5ddf84d0 100644 --- a/src/search/search_algorithms/plugin_astar.cc +++ b/src/search/search_algorithms/plugin_astar.cc @@ -6,7 +6,8 @@ using namespace std; namespace plugin_astar { -class AStarSearchFeature : public plugins::TypedFeature { +class AStarSearchFeature + : public plugins::TypedFeature { public: AStarSearchFeature() : TypedFeature("astar") { document_title("A* search (eager)"); @@ -20,7 +21,8 @@ class AStarSearchFeature : public plugins::TypedFeature create_component(const plugins::Options &options, const utils::Context &) const override { - plugins::Options options_copy(options); - auto temp = search_common::create_astar_open_list_factory_and_f_eval(options); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + plugins::Options options_copy(opts); + auto temp = + search_common::create_astar_open_list_factory_and_f_eval( + opts.get>("eval"), + opts.get("verbosity")); options_copy.set("open", temp.first); options_copy.set("f_eval", temp.second); options_copy.set("reopen_closed", true); vector> preferred_list; options_copy.set("preferred", preferred_list); - return make_shared(options_copy); + return plugins::make_shared_from_arg_tuples( + options_copy.get>("open"), + options_copy.get("reopen_closed"), + options_copy.get>("f_eval", nullptr), + options_copy.get_list>("preferred"), + eager_search::get_eager_search_arguments_from_options( + options_copy) + ); } }; diff --git a/src/search/search_algorithms/plugin_eager.cc b/src/search/search_algorithms/plugin_eager.cc index 6db6e6772..b174d3801 100644 --- a/src/search/search_algorithms/plugin_eager.cc +++ b/src/search/search_algorithms/plugin_eager.cc @@ -6,7 +6,8 @@ using namespace std; namespace plugin_eager { -class EagerSearchFeature : public plugins::TypedFeature { +class EagerSearchFeature + : public plugins::TypedFeature { public: EagerSearchFeature() : TypedFeature("eager") { document_title("Eager best-first search"); @@ -26,7 +27,20 @@ class EagerSearchFeature : public plugins::TypedFeature create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get>("open"), + opts.get("reopen_closed"), + opts.get>("f_eval", nullptr), + opts.get_list>("preferred"), + eager_search::get_eager_search_arguments_from_options(opts) + ); } }; diff --git a/src/search/search_algorithms/plugin_eager_greedy.cc b/src/search/search_algorithms/plugin_eager_greedy.cc index f07ff2ba2..ac91f8266 100644 --- a/src/search/search_algorithms/plugin_eager_greedy.cc +++ b/src/search/search_algorithms/plugin_eager_greedy.cc @@ -6,7 +6,8 @@ using namespace std; namespace plugin_eager_greedy { -class EagerGreedySearchFeature : public plugins::TypedFeature { +class EagerGreedySearchFeature + : public plugins::TypedFeature { public: EagerGreedySearchFeature() : TypedFeature("eager_greedy") { document_title("Greedy search (eager)"); @@ -19,7 +20,8 @@ class EagerGreedySearchFeature : public plugins::TypedFeature( "boost", "boost value for preferred operator open lists", "0"); - eager_search::add_options_to_feature(*this); + eager_search::add_eager_search_options_to_feature( + *this, "eager_greedy"); document_note( "Open list", @@ -37,38 +39,46 @@ class EagerGreedySearchFeature : public plugins::TypedFeature create_component(const plugins::Options &options, const utils::Context &context) const override { - plugins::verify_list_non_empty>(context, options, "evals"); - plugins::Options options_copy(options); - options_copy.set("open", search_common::create_greedy_open_list_factory(options_copy)); - options_copy.set("reopen_closed", false); - shared_ptr evaluator = nullptr; - options_copy.set("f_eval", evaluator); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &context) const override { + plugins::verify_list_non_empty>( + context, opts, "evals"); - return make_shared(options_copy); + return plugins::make_shared_from_arg_tuples( + search_common::create_greedy_open_list_factory( + opts.get_list>("evals"), + opts.get_list>("preferred"), + opts.get("boost") + ), + false, + nullptr, + opts.get_list>("preferred"), + eager_search::get_eager_search_arguments_from_options(opts) + ); } }; diff --git a/src/search/search_algorithms/plugin_eager_wastar.cc b/src/search/search_algorithms/plugin_eager_wastar.cc index 84eb964ba..dcbbd3b34 100644 --- a/src/search/search_algorithms/plugin_eager_wastar.cc +++ b/src/search/search_algorithms/plugin_eager_wastar.cc @@ -6,7 +6,8 @@ using namespace std; namespace plugin_eager_wastar { -class EagerWAstarSearchFeature : public plugins::TypedFeature { +class EagerWAstarSearchFeature + : public plugins::TypedFeature { public: EagerWAstarSearchFeature() : TypedFeature("eager_wastar") { document_title("Eager weighted A* search"); @@ -31,7 +32,8 @@ class EagerWAstarSearchFeature : public plugins::TypedFeature create_component(const plugins::Options &options, const utils::Context &) const override { - plugins::Options options_copy(options); - options_copy.set("open", search_common::create_wastar_open_list_factory(options)); - return make_shared(options_copy); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + search_common::create_wastar_open_list_factory( + opts.get_list>("evals"), + opts.get_list>("preferred"), + opts.get("boost"), + opts.get("w"), + opts.get("verbosity") + ), + opts.get("reopen_closed"), + opts.get>("f_eval", nullptr), + opts.get_list>("preferred"), + eager_search::get_eager_search_arguments_from_options(opts) + ); } }; diff --git a/src/search/search_algorithms/plugin_lazy.cc b/src/search/search_algorithms/plugin_lazy.cc index a1809993a..db005c73e 100644 --- a/src/search/search_algorithms/plugin_lazy.cc +++ b/src/search/search_algorithms/plugin_lazy.cc @@ -6,7 +6,8 @@ using namespace std; namespace plugin_lazy { -class LazySearchFeature : public plugins::TypedFeature { +class LazySearchFeature + : public plugins::TypedFeature { public: LazySearchFeature() : TypedFeature("lazy") { document_title("Lazy best-first search"); @@ -17,20 +18,20 @@ class LazySearchFeature : public plugins::TypedFeature>( "preferred", "use preferred operators of these evaluators", "[]"); - SearchAlgorithm::add_succ_order_options(*this); - SearchAlgorithm::add_options_to_feature(*this); + add_successors_order_options_to_feature(*this); + add_search_algorithm_options_to_feature(*this, "lazy"); } - virtual shared_ptr create_component(const plugins::Options &options, const utils::Context &) const override { - shared_ptr search_algorithm = make_shared(options); - /* - TODO: The following two lines look fishy. If they serve a - purpose, shouldn't the constructor take care of this? - */ - vector> preferred_list = options.get_list>("preferred"); - search_algorithm->set_preferred_operator_evaluators(preferred_list); - - return search_algorithm; + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + opts.get>("open"), + opts.get("reopen_closed"), + opts.get_list>("preferred"), + get_successors_order_arguments_from_options(opts), + get_search_algorithm_arguments_from_options(opts) + ); } }; diff --git a/src/search/search_algorithms/plugin_lazy_greedy.cc b/src/search/search_algorithms/plugin_lazy_greedy.cc index c95bbd390..0a0ec615a 100644 --- a/src/search/search_algorithms/plugin_lazy_greedy.cc +++ b/src/search/search_algorithms/plugin_lazy_greedy.cc @@ -8,7 +8,8 @@ using namespace std; namespace plugin_lazy_greedy { static const string DEFAULT_LAZY_BOOST = "1000"; -class LazyGreedySearchFeature : public plugins::TypedFeature { +class LazyGreedySearchFeature + : public plugins::TypedFeature { public: LazyGreedySearchFeature() : TypedFeature("lazy_greedy") { document_title("Greedy search (lazy)"); @@ -17,21 +18,22 @@ class LazyGreedySearchFeature : public plugins::TypedFeature>( "evals", "evaluators"); - add_list_option>( - "preferred", - "use preferred operators of these evaluators", - "[]"); - add_option( - "reopen_closed", - "reopen closed nodes", - "false"); add_option( "boost", "boost value for alternation queues that are restricted " "to preferred operator nodes", DEFAULT_LAZY_BOOST); - SearchAlgorithm::add_succ_order_options(*this); - SearchAlgorithm::add_options_to_feature(*this); + + add_option( + "reopen_closed", + "reopen closed nodes", + "false"); + add_list_option>( + "preferred", + "use preferred operators of these evaluators", + "[]"); + add_successors_order_options_to_feature(*this); + add_search_algorithm_options_to_feature(*this, "lazy_greedy"); document_note( "Open lists", @@ -46,37 +48,43 @@ class LazyGreedySearchFeature : public plugins::TypedFeature create_component(const plugins::Options &options, const utils::Context &) const override { - plugins::Options options_copy(options); - options_copy.set("open", search_common::create_greedy_open_list_factory(options)); - shared_ptr search_algorithm = make_shared(options_copy); - // TODO: The following two lines look fishy. See similar comment in _parse. - vector> preferred_list = options_copy.get_list>("preferred"); - search_algorithm->set_preferred_operator_evaluators(preferred_list); - return search_algorithm; + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + search_common::create_greedy_open_list_factory( + opts.get_list>("evals"), + opts.get_list>("preferred"), + opts.get("boost") + ), + opts.get("reopen_closed"), + opts.get_list>("preferred"), + get_successors_order_arguments_from_options(opts), + get_search_algorithm_arguments_from_options(opts) + ); } }; diff --git a/src/search/search_algorithms/plugin_lazy_wastar.cc b/src/search/search_algorithms/plugin_lazy_wastar.cc index edc9672e4..f0a3682e8 100644 --- a/src/search/search_algorithms/plugin_lazy_wastar.cc +++ b/src/search/search_algorithms/plugin_lazy_wastar.cc @@ -8,7 +8,8 @@ using namespace std; namespace plugin_lazy_wastar { static const string DEFAULT_LAZY_BOOST = "1000"; -class LazyWAstarSearchFeature : public plugins::TypedFeature { +class LazyWAstarSearchFeature + : public plugins::TypedFeature { public: LazyWAstarSearchFeature() : TypedFeature("lazy_wastar") { document_title("(Weighted) A* search (lazy)"); @@ -31,8 +32,8 @@ class LazyWAstarSearchFeature : public plugins::TypedFeature("w", "evaluator weight", "1"); - SearchAlgorithm::add_succ_order_options(*this); - SearchAlgorithm::add_options_to_feature(*this); + add_successors_order_options_to_feature(*this); + add_search_algorithm_options_to_feature(*this, "lazy_wastar"); document_note( "Open lists", @@ -77,15 +78,25 @@ class LazyWAstarSearchFeature : public plugins::TypedFeature create_component(const plugins::Options &options, const utils::Context &context) const override { - plugins::verify_list_non_empty>(context, options, "evals"); - plugins::Options options_copy(options); - options_copy.set("open", search_common::create_wastar_open_list_factory(options_copy)); - shared_ptr search_algorithm = make_shared(options_copy); - // TODO: The following two lines look fishy. See similar comment in _parse. - vector> preferred_list = options_copy.get_list>("preferred"); - search_algorithm->set_preferred_operator_evaluators(preferred_list); - return search_algorithm; + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &context) const override { + plugins::verify_list_non_empty>( + context, opts, "evals"); + + return plugins::make_shared_from_arg_tuples( + search_common::create_wastar_open_list_factory( + opts.get_list>("evals"), + opts.get_list>("preferred"), + opts.get("boost"), + opts.get("w"), + opts.get("verbosity") + ), + opts.get("reopen_closed"), + opts.get_list>("preferred"), + get_successors_order_arguments_from_options(opts), + get_search_algorithm_arguments_from_options(opts) + ); } }; diff --git a/src/search/search_algorithms/search_common.cc b/src/search/search_algorithms/search_common.cc index e5bea2cf8..258c000ce 100644 --- a/src/search/search_algorithms/search_common.cc +++ b/src/search/search_algorithms/search_common.cc @@ -5,7 +5,6 @@ #include "../evaluators/g_evaluator.h" #include "../evaluators/sum_evaluator.h" #include "../evaluators/weighted_evaluator.h" -#include "../plugins/options.h" #include "../open_lists/alternation_open_list.h" #include "../open_lists/best_first_open_list.h" #include "../open_lists/tiebreaking_open_list.h" @@ -19,22 +18,6 @@ using GEval = g_evaluator::GEvaluator; using SumEval = sum_evaluator::SumEvaluator; using WeightedEval = weighted_evaluator::WeightedEvaluator; -shared_ptr create_standard_scalar_open_list_factory( - const shared_ptr &eval, bool pref_only) { - plugins::Options options; - options.set("eval", eval); - options.set("pref_only", pref_only); - return make_shared(options); -} - -static shared_ptr create_alternation_open_list_factory( - const vector> &subfactories, int boost) { - plugins::Options options; - options.set("sublists", subfactories); - options.set("boost", boost); - return make_shared(options); -} - /* Helper function for common code of create_greedy_open_list_factory and create_wastar_open_list_factory. @@ -44,29 +27,31 @@ static shared_ptr create_alternation_open_list_factory_aux( const vector> &preferred_evaluators, int boost) { if (evals.size() == 1 && preferred_evaluators.empty()) { - return create_standard_scalar_open_list_factory(evals[0], false); + return make_shared( + evals[0], false); } else { vector> subfactories; for (const shared_ptr &evaluator : evals) { subfactories.push_back( - create_standard_scalar_open_list_factory( + make_shared( evaluator, false)); if (!preferred_evaluators.empty()) { subfactories.push_back( - create_standard_scalar_open_list_factory( + make_shared( evaluator, true)); } } - return create_alternation_open_list_factory(subfactories, boost); + return make_shared( + subfactories, boost); } } shared_ptr create_greedy_open_list_factory( - const plugins::Options &options) { + const vector> &evals, + const vector> &preferred_evaluators, + int boost) { return create_alternation_open_list_factory_aux( - options.get_list>("evals"), - options.get_list>("preferred"), - options.get("boost")); + evals, preferred_evaluators, boost); } /* @@ -79,73 +64,56 @@ shared_ptr create_greedy_open_list_factory( If w = 0, we omit the h-evaluator altogether: we use g instead of g + 0 * h. */ -static shared_ptr create_wastar_eval(const plugins::Options &options, - const shared_ptr &g_eval, int w, - const shared_ptr &h_eval) { - if (w == 0) { +static shared_ptr create_wastar_eval( + utils::Verbosity verbosity, const shared_ptr &g_eval, + int weight, const shared_ptr &h_eval) { + if (weight == 0) { return g_eval; } shared_ptr w_h_eval = nullptr; - if (w == 1) { + if (weight == 1) { w_h_eval = h_eval; } else { - plugins::Options weighted_evaluator_options; - weighted_evaluator_options.set( - "verbosity", options.get("verbosity")); - weighted_evaluator_options.set>("eval", h_eval); - weighted_evaluator_options.set("weight", w); - w_h_eval = make_shared(weighted_evaluator_options); + w_h_eval = make_shared( + h_eval, weight, "wastar.w_h_eval", verbosity); } - plugins::Options sum_evaluator_options; - sum_evaluator_options.set( - "verbosity", options.get("verbosity")); - sum_evaluator_options.set>>( - "evals", vector>({g_eval, w_h_eval})); - return make_shared(sum_evaluator_options); + return make_shared( + vector>({g_eval, w_h_eval}), + "wastar.eval", verbosity); } shared_ptr create_wastar_open_list_factory( - const plugins::Options &options) { - vector> base_evals = - options.get_list>("evals"); - int w = options.get("w"); - - plugins::Options g_evaluator_options; - g_evaluator_options.set( - "verbosity", options.get("verbosity")); - shared_ptr g_eval = make_shared(g_evaluator_options); + const vector> &base_evals, + const vector> &preferred, int boost, + int weight, utils::Verbosity verbosity) { + shared_ptr g_eval = make_shared( + "wastar.g_eval", verbosity); vector> f_evals; f_evals.reserve(base_evals.size()); for (const shared_ptr &eval : base_evals) - f_evals.push_back(create_wastar_eval(options, g_eval, w, eval)); + f_evals.push_back(create_wastar_eval( + verbosity, g_eval, weight, eval)); return create_alternation_open_list_factory_aux( f_evals, - options.get_list>("preferred"), - options.get("boost")); + preferred, + boost); } pair, const shared_ptr> -create_astar_open_list_factory_and_f_eval(const plugins::Options &opts) { - plugins::Options g_evaluator_options; - g_evaluator_options.set( - "verbosity", opts.get("verbosity")); - shared_ptr g = make_shared(g_evaluator_options); - shared_ptr h = opts.get>("eval"); - plugins::Options f_evaluator_options; - f_evaluator_options.set( - "verbosity", opts.get("verbosity")); - f_evaluator_options.set>>( - "evals", vector>({g, h})); - shared_ptr f = make_shared(f_evaluator_options); - vector> evals = {f, h}; +create_astar_open_list_factory_and_f_eval( + const shared_ptr &h_eval, utils::Verbosity verbosity + ) { + shared_ptr g = make_shared("astar.g_eval", verbosity); + shared_ptr f = + make_shared( + vector>({g, h_eval}), + "astar.f_eval", verbosity); + vector> evals = {f, h_eval}; - plugins::Options options; - options.set("evals", evals); - options.set("pref_only", false); - options.set("unsafe_pruning", false); shared_ptr open = - make_shared(options); + make_shared( + evals, false, false); return make_pair(open, f); } } diff --git a/src/search/search_algorithms/search_common.h b/src/search/search_algorithms/search_common.h index ddec9152a..742947961 100644 --- a/src/search/search_algorithms/search_common.h +++ b/src/search/search_algorithms/search_common.h @@ -19,28 +19,16 @@ */ #include +#include +#include "../utils/logging.h" class Evaluator; class OpenListFactory; -namespace plugins { -class Options; -} - namespace search_common { -/* - Create a standard scalar open list factory with the given "eval" and - "pref_only" options. -*/ -extern std::shared_ptr create_standard_scalar_open_list_factory( - const std::shared_ptr &eval, bool pref_only); - /* Create open list factory for the eager_greedy or lazy_greedy plugins. - Uses "evals", "preferred" and "boost" from the passed-in Options - object to construct an open list factory of the appropriate type. - This is usually an alternation open list with: - one sublist for each evaluator, considering all successors - one sublist for each evaluator, considering only preferred successors @@ -51,32 +39,34 @@ extern std::shared_ptr create_standard_scalar_open_list_factory directly. */ extern std::shared_ptr create_greedy_open_list_factory( - const plugins::Options &opts); + const std::vector> &evals, + const std::vector> &preferred_evaluators, + int boost); /* Create open list factory for the lazy_wastar plugin. - Uses "evals", "preferred", "boost" and "w" from the passed-in - Options object to construct an open list factory of the appropriate - type. - This works essentially the same way as parse_greedy (see documentation there), except that the open lists use evalators based on g + w * h rather than using h directly. */ extern std::shared_ptr create_wastar_open_list_factory( - const plugins::Options &opts); + const std::vector> &base_evals, + const std::vector> &preferred, int boost, + int weight, utils::Verbosity verbosity); /* Create open list factory and f_evaluator (used for displaying progress statistics) for A* search. The resulting open list factory produces a tie-breaking open list - ordered primarily on g + h and secondarily on h. Uses "eval" from - the passed-in Options object as the h evaluator. + ordered primarily on g + h and secondarily on h. */ -extern std::pair, const std::shared_ptr> -create_astar_open_list_factory_and_f_eval(const plugins::Options &opts); +extern std::pair, + const std::shared_ptr> +create_astar_open_list_factory_and_f_eval( + const std::shared_ptr &h_eval, + utils::Verbosity verbosity); } #endif diff --git a/src/search/tasks/cost_adapted_task.cc b/src/search/tasks/cost_adapted_task.cc index 34666636b..249ced228 100644 --- a/src/search/tasks/cost_adapted_task.cc +++ b/src/search/tasks/cost_adapted_task.cc @@ -27,19 +27,23 @@ int CostAdaptedTask::get_operator_cost(int index, bool is_axiom) const { return get_adjusted_action_cost(op, cost_type, parent_is_unit_cost); } -class CostAdaptedTaskFeature : public plugins::TypedFeature { +class CostAdaptedTaskFeature + : public plugins::TypedFeature { public: CostAdaptedTaskFeature() : TypedFeature("adapt_costs") { document_title("Cost-adapted task"); document_synopsis( "A cost-adapting transformation of the root task."); - add_cost_type_option_to_feature(*this); + add_cost_type_options_to_feature(*this); } - virtual shared_ptr create_component(const plugins::Options &options, const utils::Context &) const override { - OperatorCost cost_type = options.get("cost_type"); - return make_shared(g_root_task, cost_type); + virtual shared_ptr create_component( + const plugins::Options &opts, + const utils::Context &) const override { + return plugins::make_shared_from_arg_tuples( + g_root_task, + get_cost_type_arguments_from_options(opts)); } }; diff --git a/src/search/tasks/root_task.cc b/src/search/tasks/root_task.cc index 4046a879f..3e7d2996c 100644 --- a/src/search/tasks/root_task.cc +++ b/src/search/tasks/root_task.cc @@ -497,7 +497,8 @@ void read_root_task(istream &in) { g_root_task = make_shared(in); } -class RootTaskFeature : public plugins::TypedFeature { +class RootTaskFeature + : public plugins::TypedFeature { public: RootTaskFeature() : TypedFeature("no_transform") { } diff --git a/src/search/utils/logging.cc b/src/search/utils/logging.cc index 4ef9f85ef..a0227e9bb 100644 --- a/src/search/utils/logging.cc +++ b/src/search/utils/logging.cc @@ -29,19 +29,20 @@ void add_log_options_to_feature(plugins::Feature &feature) { "normal"); } -LogProxy get_log_from_options(const plugins::Options &options) { - /* NOTE: We return (a proxy to) the global log if all options match the - default values of the global log. */ - if (options.get("verbosity") == Verbosity::NORMAL) { +tuple get_log_arguments_from_options( + const plugins::Options &opts) { + return make_tuple(opts.get("verbosity")); +} + +LogProxy get_log_for_verbosity(const Verbosity &verbosity) { + if (verbosity == Verbosity::NORMAL) { return LogProxy(global_log); } - return LogProxy(make_shared(options.get("verbosity"))); + return LogProxy(make_shared(verbosity)); } LogProxy get_silent_log() { - plugins::Options opts; - opts.set("verbosity", utils::Verbosity::SILENT); - return utils::get_log_from_options(opts); + return utils::get_log_for_verbosity(utils::Verbosity::SILENT); } ContextError::ContextError(const string &msg) diff --git a/src/search/utils/logging.h b/src/search/utils/logging.h index b2950bbe8..c3679b4f5 100644 --- a/src/search/utils/logging.h +++ b/src/search/utils/logging.h @@ -130,7 +130,10 @@ class LogProxy { extern LogProxy g_log; extern void add_log_options_to_feature(plugins::Feature &feature); -extern LogProxy get_log_from_options(const plugins::Options &options); +extern std::tuple get_log_arguments_from_options( + const plugins::Options &opts); + +extern LogProxy get_log_for_verbosity(const Verbosity &verbosity); extern LogProxy get_silent_log(); class ContextError : public utils::Exception { diff --git a/src/search/utils/rng_options.cc b/src/search/utils/rng_options.cc index 56d5a21bb..deb761f14 100644 --- a/src/search/utils/rng_options.cc +++ b/src/search/utils/rng_options.cc @@ -7,7 +7,7 @@ using namespace std; namespace utils { -void add_rng_options(plugins::Feature &feature) { +void add_rng_options_to_feature(plugins::Feature &feature) { feature.add_option( "random_seed", "Set to -1 (default) to use the global random number generator. " @@ -17,9 +17,12 @@ void add_rng_options(plugins::Feature &feature) { plugins::Bounds("-1", "infinity")); } -shared_ptr parse_rng_from_options( - const plugins::Options &options) { - int seed = options.get("random_seed"); +tuple get_rng_arguments_from_options( + const plugins::Options &opts) { + return make_tuple(opts.get("random_seed")); +} + +shared_ptr get_rng(int seed) { if (seed == -1) { // Use an arbitrary default seed. static shared_ptr rng = diff --git a/src/search/utils/rng_options.h b/src/search/utils/rng_options.h index c25bd478b..d01df4b55 100644 --- a/src/search/utils/rng_options.h +++ b/src/search/utils/rng_options.h @@ -12,15 +12,16 @@ namespace utils { class RandomNumberGenerator; // Add random_seed option to parser. -extern void add_rng_options(plugins::Feature &feature); +extern void add_rng_options_to_feature(plugins::Feature &feature); +extern std::tuple get_rng_arguments_from_options( + const plugins::Options &opts); /* - Return an RNG based on the given options, which can either be the global - RNG or a local one with a user-specified seed. Only use this together with - "add_rng_options()". + Return an RNG for the given seed, which can either be the global + RNG or a local one with a user-specified seed. Only use this together + with "add_rng_options_to_feature()". */ -extern std::shared_ptr parse_rng_from_options( - const plugins::Options &options); +extern std::shared_ptr get_rng(int seed); } #endif diff --git a/src/search/utils/tuples.h b/src/search/utils/tuples.h new file mode 100644 index 000000000..77b093e36 --- /dev/null +++ b/src/search/utils/tuples.h @@ -0,0 +1,31 @@ +#ifndef UTILS_TUPLES_H +#define UTILS_TUPLES_H + +#include + +namespace utils { +template +auto flatten_tuple_elements( + std::tuple &&t, std::index_sequence); + +template +auto flatten_tuple(T &&t) { + return std::make_tuple(std::move(t)); +} + +template +auto flatten_tuple(std::tuple &&t) { + constexpr std::size_t tuple_size = + std::tuple_size>::value; + return flatten_tuple_elements( + std::move(t), std::make_index_sequence()); +} + +template +auto flatten_tuple_elements( + std::tuple &&t, std::index_sequence) { + return std::tuple_cat(flatten_tuple(std::get(std::move(t)))...); +} +} + +#endif From ba7f864880c7d3aefcdf18c6aa3c944a71fe691f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Clemens=20B=C3=BCchner?= Date: Tue, 9 Jul 2024 14:51:36 +0200 Subject: [PATCH 02/28] [issue1111] Change how data is passed to CPLEX to avoid crashes. We fix a bug where CPLEX crashed when provided with an empty constraint system. --- src/search/lp/cplex_solver_interface.h | 39 ++++++++++++++++++-------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/search/lp/cplex_solver_interface.h b/src/search/lp/cplex_solver_interface.h index 5ba35cd53..8104a23ee 100644 --- a/src/search/lp/cplex_solver_interface.h +++ b/src/search/lp/cplex_solver_interface.h @@ -11,6 +11,21 @@ #include namespace lp { +template +static T *to_cplex_array(std::vector &v) { + /* + CPLEX expects a non-nullptr even for empty arrays but the C++ standard + does not guarantee any particular value for data for empty vectors (see + issue1111). + */ + if (v.empty()) { + static T dummy; + return &dummy; + } else { + return v.data(); + } +} + class CplexSolverInterface : public SolverInterface { CPXENVptr env; CPXLPptr problem; @@ -90,10 +105,10 @@ class CplexSolverInterface : public SolverInterface { void assign_row_by_row( const named_vector::NamedVector &constraints); - double *get_coefficients() {return coefficients.data();} - int *get_indices() {return indices.data();} - int *get_starts() {return starts.data();} - int *get_counts() {return counts.data();} + double *get_coefficients() {return to_cplex_array(coefficients);} + int *get_indices() {return to_cplex_array(indices);} + int *get_starts() {return to_cplex_array(starts);} + int *get_counts() {return to_cplex_array(counts);} int get_num_nonzeros() {return coefficients.size();} }; @@ -108,10 +123,10 @@ class CplexSolverInterface : public SolverInterface { std::vector objective; public: void assign(const named_vector::NamedVector &variables); - double *get_lb() {return lb.data();} - double *get_ub() {return ub.data();} - char *get_type() {return type.data();} - double *get_objective() {return objective.data();} + double *get_lb() {return to_cplex_array(lb);} + double *get_ub() {return to_cplex_array(ub);} + char *get_type() {return to_cplex_array(type);} + double *get_objective() {return to_cplex_array(objective);} }; class CplexRowsInfo { @@ -131,10 +146,10 @@ class CplexSolverInterface : public SolverInterface { std::vector range_indices; public: void assign(const named_vector::NamedVector &constraints, int offset = 0, bool dense_range_values = true); - double *get_rhs() {return rhs.data();} - char *get_sense() {return sense.data();} - double *get_range_values() {return range_values.data();} - int *get_range_indices() {return range_indices.data();} + double *get_rhs() {return to_cplex_array(rhs);} + char *get_sense() {return to_cplex_array(sense);} + double *get_range_values() {return to_cplex_array(range_values);} + int *get_range_indices() {return to_cplex_array(range_indices);} int get_num_ranged_rows() {return range_indices.size();} }; From e18adecff03c9c9b13cef3f5ccd4874e893b86a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Clemens=20B=C3=BCchner?= Date: Wed, 10 Jul 2024 12:30:00 +0200 Subject: [PATCH 03/28] [issue1130] Limit when iterated search passes bounds to component searches. --- src/search/search_algorithms/iterated_search.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/search/search_algorithms/iterated_search.cc b/src/search/search_algorithms/iterated_search.cc index 83f66890b..5755623be 100644 --- a/src/search/search_algorithms/iterated_search.cc +++ b/src/search/search_algorithms/iterated_search.cc @@ -47,9 +47,7 @@ shared_ptr IteratedSearch::create_current_phase() { this overrides continue_on_fail. */ if (repeat_last_phase && last_phase_found_solution) { - return get_search_algorithm( - algorithm_configs.size() - - 1); + return get_search_algorithm(algorithm_configs.size() - 1); } else { return nullptr; } @@ -63,7 +61,7 @@ SearchStatus IteratedSearch::step() { if (!current_search) { return found_solution() ? SOLVED : FAILED; } - if (pass_bound) { + if (pass_bound && best_bound < current_search->get_bound()) { current_search->set_bound(best_bound); } ++phase; @@ -143,8 +141,10 @@ class IteratedSearchFeature true); add_option( "pass_bound", - "use bound from previous search. The bound is the real cost " - "of the plan found before, regardless of the cost_type parameter.", + "use the bound of iterated search as a bound for its component " + "search algorithms, unless these already have a lower bound set. " + "The iterated search bound is tightened whenever a component finds " + "a cheaper plan.", "true"); add_option( "repeat_last", From 7aae43f8c4eea3e849083d4f159dffd9d7777a76 Mon Sep 17 00:00:00 2001 From: Florian Pommerening Date: Sun, 14 Jul 2024 10:44:06 +0200 Subject: [PATCH 04/28] [trivial] Add a hint path so CPLEX is found on M2 Macs. --- src/search/cmake/FindCplex.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search/cmake/FindCplex.cmake b/src/search/cmake/FindCplex.cmake index 606bba2a4..750dd0085 100644 --- a/src/search/cmake/FindCplex.cmake +++ b/src/search/cmake/FindCplex.cmake @@ -82,7 +82,7 @@ target_link_libraries(cplex::cplex INTERFACE Threads::Threads) if(${CMAKE_SIZEOF_VOID_P} EQUAL 4) set(BITWIDTH_HINTS "x86") elseif(${CMAKE_SIZEOF_VOID_P} EQUAL 8) - set(BITWIDTH_HINTS "x86-64" "x64") + set(BITWIDTH_HINTS "x86-64" "x64" "arm64") endif() if(APPLE) From 308812cf7315fe896dbcd319493277d82aa36bd2 Mon Sep 17 00:00:00 2001 From: ClemensBuechner Date: Tue, 16 Jul 2024 14:24:45 +0200 Subject: [PATCH 05/28] [trivial] Clean up documentation of iterated search. --- .../search_algorithms/iterated_search.cc | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/search/search_algorithms/iterated_search.cc b/src/search/search_algorithms/iterated_search.cc index 5755623be..23c009a4d 100644 --- a/src/search/search_algorithms/iterated_search.cc +++ b/src/search/search_algorithms/iterated_search.cc @@ -164,7 +164,8 @@ class IteratedSearchFeature "Note 1", "We don't cache heuristic values between search iterations at" " the moment. If you perform a LAMA-style iterative search," - " heuristic values will be computed multiple times."); + " heuristic values and other per-state information will be computed" + " multiple times."); document_note( "Note 2", "The configuration\n```\n" @@ -173,18 +174,12 @@ class IteratedSearchFeature "lazy_wastar([ipdb()],w=2), lazy_wastar([ipdb()],w=1)])\"\n" "```\nwould perform the preprocessing phase of the ipdb heuristic " "5 times (once before each iteration).\n\n" - "To avoid this, use heuristic predefinition, which avoids duplicate " - "preprocessing, as follows:\n```\n" - "--evaluator \"h=ipdb()\" --search " - "\"iterated([lazy_wastar([h],w=10), lazy_wastar([h],w=5), lazy_wastar([h],w=3), " - "lazy_wastar([h],w=2), lazy_wastar([h],w=1)])\"\n" + "To avoid this, use heuristic predefinition, which avoids " + "duplicate preprocessing, as follows:\n```\n" + "\"let(h,ipdb(),iterated([lazy_wastar([h],w=10), " + "lazy_wastar([h],w=5), lazy_wastar([h],w=3), lazy_wastar([h],w=2), " + "lazy_wastar([h],w=1)]))\"\n" "```"); - document_note( - "Note 3", - "If you reuse the same landmark count heuristic " - "(using heuristic predefinition) between iterations, " - "the path data (that is, landmark status for each visited state) " - "will be saved between iterations."); } virtual shared_ptr create_component(const plugins::Options &options, const utils::Context &context) const override { From f75018fd06a3ad476ffff794fa92edabd578e8ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Salom=C3=A9=20Eriksson?= Date: Fri, 19 Jul 2024 12:26:48 +0200 Subject: [PATCH 06/28] [issue454] Move computation of negated axioms to search component Negated axioms are now only computed for heuristics that need it. Specifically these are: - additive heuristic - context-enhanced additive heuristic - causal graph heuristic - FF heuristic - max heuristic - landmark heuristics (landmark sum and landmark cost partitioning) Each heuristic computes the negated axioms separately. This can negatively affect performance if a search with several such heuristics is performed, as is for example done in LAMA (ff and landmark sum). Heuristics that support axioms but do not need negated axioms might now be faster tasks with axioms, since they avoid the unnecessary computation. A new enum option "axioms" has been added to all heuristics that need negated axioms to determine how the negated axioms are computed. - overapproximate_negated_cycles (default): Computes exact negation except for derived variables that have cyclic dependencies, which are trivially overapproximated (see issue453). This is the old behavior that can lead to an exponential explosion. - overapproximate_negated: Trivially overapproximates all negations. This avoids the exponential explosion but makes the heuristic weaker. --- src/search/CMakeLists.txt | 20 +- src/search/axioms.cc | 33 +- .../cartesian_abstractions/split_selector.cc | 3 +- .../subtask_generators.cc | 3 +- src/search/heuristics/additive_heuristic.cc | 8 +- src/search/heuristics/additive_heuristic.h | 1 + src/search/heuristics/cea_heuristic.cc | 7 +- src/search/heuristics/cea_heuristic.h | 2 + src/search/heuristics/cg_heuristic.cc | 9 +- src/search/heuristics/cg_heuristic.h | 2 + src/search/heuristics/ff_heuristic.cc | 8 +- src/search/heuristics/ff_heuristic.h | 1 + src/search/heuristics/max_heuristic.cc | 9 +- src/search/heuristics/max_heuristic.h | 1 + src/search/heuristics/relaxation_heuristic.cc | 20 +- src/search/heuristics/relaxation_heuristic.h | 9 +- .../landmark_cost_partitioning_heuristic.cc | 3 +- .../landmark_cost_partitioning_heuristic.h | 1 + src/search/landmarks/landmark_heuristic.cc | 27 +- src/search/landmarks/landmark_heuristic.h | 8 +- .../landmarks/landmark_sum_heuristic.cc | 4 +- src/search/landmarks/landmark_sum_heuristic.h | 1 + src/search/tasks/default_value_axioms_task.cc | 429 ++++++++++++++++++ src/search/tasks/default_value_axioms_task.h | 94 ++++ src/translate/axiom_rules.py | 171 ++----- src/translate/translate.py | 20 +- 26 files changed, 698 insertions(+), 196 deletions(-) create mode 100644 src/search/tasks/default_value_axioms_task.cc create mode 100644 src/search/tasks/default_value_axioms_task.h diff --git a/src/search/CMakeLists.txt b/src/search/CMakeLists.txt index 6adeaa767..393c2b2ed 100644 --- a/src/search/CMakeLists.txt +++ b/src/search/CMakeLists.txt @@ -577,6 +577,8 @@ create_fast_downward_library( SOURCES heuristics/array_pool heuristics/relaxation_heuristic + DEPENDS + default_value_axioms_task DEPENDENCY_ONLY ) @@ -606,6 +608,7 @@ create_fast_downward_library( SOURCES heuristics/cea_heuristic DEPENDS + default_value_axioms_task domain_transition_graph priority_queues task_properties @@ -617,6 +620,7 @@ create_fast_downward_library( SOURCES heuristics/cg_heuristic heuristics/cg_cache DEPENDS + default_value_axioms_task domain_transition_graph priority_queues task_properties @@ -700,6 +704,18 @@ create_fast_downward_library( DEPENDENCY_ONLY ) +create_fast_downward_library( + NAME default_value_axioms_task + HELP "Task transformation adding axioms describing under which circumstances a derived variable is set to its default value." + SOURCES + tasks/default_value_axioms_task + DEPENDS + core_tasks + sccs + task_properties + DEPENDENCY_ONLY +) + create_fast_downward_library( NAME causal_graph HELP "Causal Graph" @@ -846,6 +862,7 @@ create_fast_downward_library( landmarks/landmark_sum_heuristic landmarks/util DEPENDS + default_value_axioms_task lp_solver priority_queues successor_generator @@ -937,8 +954,7 @@ create_fast_downward_library( create_fast_downward_library( NAME sccs - HELP "Algorithm to compute the strongly connected components (SCCs) of a " - "directed graph." + HELP "Algorithm to compute the strongly connected components (SCCs) of a directed graph." SOURCES algorithms/sccs DEPENDENCY_ONLY diff --git a/src/search/axioms.cc b/src/search/axioms.cc index 57f97a2eb..235234e75 100644 --- a/src/search/axioms.cc +++ b/src/search/axioms.cc @@ -22,35 +22,28 @@ AxiomEvaluator::AxiomEvaluator(const TaskProxy &task_proxy) { axiom_literals.emplace_back(var.get_domain_size()); // Initialize rules - // Since we are skipping some axioms, we cannot access them through - // their id position directly. - vector axiom_id_to_position(axioms.size(), -1); for (OperatorProxy axiom : axioms) { assert(axiom.get_effects().size() == 1); EffectProxy cond_effect = axiom.get_effects()[0]; FactPair effect = cond_effect.get_fact().get_pair(); int num_conditions = cond_effect.get_conditions().size(); - // Ignore axioms which set the variable to its default value. - if (effect.value != variables[effect.var].get_default_axiom_value()) { - AxiomLiteral *eff_literal = &axiom_literals[effect.var][effect.value]; - axiom_id_to_position[axiom.get_id()] = rules.size(); - rules.emplace_back( - num_conditions, effect.var, effect.value, eff_literal); - } + + // We don't allow axioms that set the variable to its default value. + assert(effect.value != variables[effect.var].get_default_axiom_value()); + AxiomLiteral *eff_literal = &axiom_literals[effect.var][effect.value]; + rules.emplace_back( + num_conditions, effect.var, effect.value, eff_literal); } // Cross-reference rules and literals for (OperatorProxy axiom : axioms) { - // Ignore axioms which set the variable to its default value. - int position = axiom_id_to_position[axiom.get_id()]; - if (position != -1) { - EffectProxy effect = axiom.get_effects()[0]; - for (FactProxy condition : effect.get_conditions()) { - int var_id = condition.get_variable().get_id(); - int val = condition.get_value(); - AxiomRule *rule = &rules[position]; - axiom_literals[var_id][val].condition_of.push_back(rule); - } + int id = axiom.get_id(); + EffectProxy effect = axiom.get_effects()[0]; + for (FactProxy condition : effect.get_conditions()) { + int var_id = condition.get_variable().get_id(); + int val = condition.get_value(); + AxiomRule *rule = &rules[id]; + axiom_literals[var_id][val].condition_of.push_back(rule); } } diff --git a/src/search/cartesian_abstractions/split_selector.cc b/src/search/cartesian_abstractions/split_selector.cc index ec6a7baa1..d9a3b1c4f 100644 --- a/src/search/cartesian_abstractions/split_selector.cc +++ b/src/search/cartesian_abstractions/split_selector.cc @@ -24,7 +24,8 @@ SplitSelector::SplitSelector( if (pick == PickSplit::MIN_HADD || pick == PickSplit::MAX_HADD) { additive_heuristic = utils::make_unique_ptr( - task, false, "h^add within CEGAR abstractions", + tasks::AxiomHandlingType::APPROXIMATE_NEGATIVE, task, + false, "h^add within CEGAR abstractions", utils::Verbosity::SILENT); additive_heuristic->compute_heuristic_for_cegar( task_proxy.get_initial_state()); diff --git a/src/search/cartesian_abstractions/subtask_generators.cc b/src/search/cartesian_abstractions/subtask_generators.cc index 8de4f82fc..ce38b099c 100644 --- a/src/search/cartesian_abstractions/subtask_generators.cc +++ b/src/search/cartesian_abstractions/subtask_generators.cc @@ -35,7 +35,8 @@ class SortFactsByIncreasingHaddValues { explicit SortFactsByIncreasingHaddValues( const shared_ptr &task) : hadd(utils::make_unique_ptr( - task, false, "h^add within CEGAR abstractions", + tasks::AxiomHandlingType::APPROXIMATE_NEGATIVE, task, + false, "h^add within CEGAR abstractions", utils::Verbosity::SILENT)) { TaskProxy task_proxy(*task); hadd->compute_heuristic_for_cegar(task_proxy.get_initial_state()); diff --git a/src/search/heuristics/additive_heuristic.cc b/src/search/heuristics/additive_heuristic.cc index c86abc432..aff35d07b 100644 --- a/src/search/heuristics/additive_heuristic.cc +++ b/src/search/heuristics/additive_heuristic.cc @@ -14,10 +14,12 @@ namespace additive_heuristic { const int AdditiveHeuristic::MAX_COST_VALUE; AdditiveHeuristic::AdditiveHeuristic( + tasks::AxiomHandlingType axioms, const shared_ptr &transform, bool cache_estimates, const string &description, utils::Verbosity verbosity) : RelaxationHeuristic( - transform, cache_estimates, description, verbosity), + axioms, transform, cache_estimates, description, + verbosity), did_write_overflow_warning(false) { if (log.is_at_least_normal()) { log << "Initializing additive heuristic..." << endl; @@ -153,7 +155,7 @@ class AdditiveHeuristicFeature AdditiveHeuristicFeature() : TypedFeature("add") { document_title("Additive heuristic"); - add_heuristic_options_to_feature(*this, "add"); + relaxation_heuristic::add_relaxation_heuristic_options_to_feature(*this, "add"); document_language_support("action costs", "supported"); document_language_support("conditional effects", "supported"); @@ -173,7 +175,7 @@ class AdditiveHeuristicFeature const plugins::Options &opts, const utils::Context &) const override { return plugins::make_shared_from_arg_tuples( - get_heuristic_arguments_from_options(opts) + relaxation_heuristic::get_relaxation_heuristic_arguments_from_options(opts) ); } }; diff --git a/src/search/heuristics/additive_heuristic.h b/src/search/heuristics/additive_heuristic.h index ae3096125..ad76e4041 100644 --- a/src/search/heuristics/additive_heuristic.h +++ b/src/search/heuristics/additive_heuristic.h @@ -66,6 +66,7 @@ class AdditiveHeuristic : public relaxation_heuristic::RelaxationHeuristic { int compute_add_and_ff(const State &state); public: AdditiveHeuristic( + tasks::AxiomHandlingType axioms, const std::shared_ptr &transform, bool cache_estimates, const std::string &description, utils::Verbosity verbosity); diff --git a/src/search/heuristics/cea_heuristic.cc b/src/search/heuristics/cea_heuristic.cc index 4233cd4c4..952f90522 100644 --- a/src/search/heuristics/cea_heuristic.cc +++ b/src/search/heuristics/cea_heuristic.cc @@ -409,9 +409,12 @@ int ContextEnhancedAdditiveHeuristic::compute_heuristic( } ContextEnhancedAdditiveHeuristic::ContextEnhancedAdditiveHeuristic( + tasks::AxiomHandlingType axioms, const shared_ptr &transform, bool cache_estimates, const string &description, utils::Verbosity verbosity) - : Heuristic(transform, cache_estimates, description, verbosity), + : Heuristic(tasks::get_default_value_axioms_task_if_needed( + transform, axioms), + cache_estimates, description, verbosity), min_action_cost(task_properties::get_min_operator_cost(task_proxy)) { if (log.is_at_least_normal()) { log << "Initializing context-enhanced additive heuristic..." << endl; @@ -450,6 +453,7 @@ class ContextEnhancedAdditiveHeuristicFeature ContextEnhancedAdditiveHeuristicFeature() : TypedFeature("cea") { document_title("Context-enhanced additive heuristic"); + tasks::add_axioms_option_to_feature(*this); add_heuristic_options_to_feature(*this, "cea"); document_language_support("action costs", "supported"); @@ -470,6 +474,7 @@ class ContextEnhancedAdditiveHeuristicFeature create_component(const plugins::Options &opts, const utils::Context &) const override { return plugins::make_shared_from_arg_tuples( + tasks::get_axioms_arguments_from_options(opts), get_heuristic_arguments_from_options(opts) ); } diff --git a/src/search/heuristics/cea_heuristic.h b/src/search/heuristics/cea_heuristic.h index 5b1547c71..1774a3f8f 100644 --- a/src/search/heuristics/cea_heuristic.h +++ b/src/search/heuristics/cea_heuristic.h @@ -6,6 +6,7 @@ #include "../heuristic.h" #include "../algorithms/priority_queues.h" +#include "../tasks/default_value_axioms_task.h" #include @@ -51,6 +52,7 @@ class ContextEnhancedAdditiveHeuristic : public Heuristic { virtual int compute_heuristic(const State &ancestor_state) override; public: ContextEnhancedAdditiveHeuristic( + tasks::AxiomHandlingType axioms, const std::shared_ptr &transform, bool cache_estimates, const std::string &description, utils::Verbosity verbosity); diff --git a/src/search/heuristics/cg_heuristic.cc b/src/search/heuristics/cg_heuristic.cc index 5da1623e9..a8dea593d 100644 --- a/src/search/heuristics/cg_heuristic.cc +++ b/src/search/heuristics/cg_heuristic.cc @@ -17,10 +17,13 @@ using namespace domain_transition_graph; namespace cg_heuristic { CGHeuristic::CGHeuristic( - int max_cache_size, const shared_ptr &transform, + int max_cache_size, tasks::AxiomHandlingType axioms, + const shared_ptr &transform, bool cache_estimates, const string &description, utils::Verbosity verbosity) - : Heuristic(transform, cache_estimates, description, verbosity), + : Heuristic(tasks::get_default_value_axioms_task_if_needed( + transform, axioms), + cache_estimates, description, verbosity), cache_hits(0), cache_misses(0), helpful_transition_extraction_counter(0), @@ -295,6 +298,7 @@ class CGHeuristicFeature "maximum number of cached entries per variable (set to 0 to disable cache)", "1000000", plugins::Bounds("0", "infinity")); + tasks::add_axioms_option_to_feature(*this); add_heuristic_options_to_feature(*this, "cg"); document_language_support("action costs", "supported"); @@ -316,6 +320,7 @@ class CGHeuristicFeature const utils::Context &) const override { return plugins::make_shared_from_arg_tuples( opts.get("max_cache_size"), + tasks::get_axioms_arguments_from_options(opts), get_heuristic_arguments_from_options(opts) ); } diff --git a/src/search/heuristics/cg_heuristic.h b/src/search/heuristics/cg_heuristic.h index c7d738f63..7252e1607 100644 --- a/src/search/heuristics/cg_heuristic.h +++ b/src/search/heuristics/cg_heuristic.h @@ -4,6 +4,7 @@ #include "../heuristic.h" #include "../algorithms/priority_queues.h" +#include "../tasks/default_value_axioms_task.h" #include #include @@ -45,6 +46,7 @@ class CGHeuristic : public Heuristic { public: explicit CGHeuristic( int max_cache_size, + tasks::AxiomHandlingType axiom_hanlding, const std::shared_ptr &transform, bool cache_estimates, const std::string &description, utils::Verbosity verbosity); diff --git a/src/search/heuristics/ff_heuristic.cc b/src/search/heuristics/ff_heuristic.cc index 683d11802..39f727258 100644 --- a/src/search/heuristics/ff_heuristic.cc +++ b/src/search/heuristics/ff_heuristic.cc @@ -12,10 +12,12 @@ using namespace std; namespace ff_heuristic { // construction and destruction FFHeuristic::FFHeuristic( + tasks::AxiomHandlingType axioms, const shared_ptr &transform, bool cache_estimates, const string &description, utils::Verbosity verbosity) : AdditiveHeuristic( - transform, cache_estimates, description, verbosity), + axioms, transform, cache_estimates, description, + verbosity), relaxed_plan(task_proxy.get_operators().size(), false) { if (log.is_at_least_normal()) { log << "Initializing FF heuristic..." << endl; @@ -78,7 +80,7 @@ class FFHeuristicFeature FFHeuristicFeature() : TypedFeature("ff") { document_title("FF heuristic"); - add_heuristic_options_to_feature(*this, "ff"); + relaxation_heuristic::add_relaxation_heuristic_options_to_feature(*this, "ff"); document_language_support("action costs", "supported"); document_language_support("conditional effects", "supported"); @@ -98,7 +100,7 @@ class FFHeuristicFeature const plugins::Options &opts, const utils::Context &) const override { return plugins::make_shared_from_arg_tuples( - get_heuristic_arguments_from_options(opts) + relaxation_heuristic::get_relaxation_heuristic_arguments_from_options(opts) ); } }; diff --git a/src/search/heuristics/ff_heuristic.h b/src/search/heuristics/ff_heuristic.h index 86fa6a389..d0302ed30 100644 --- a/src/search/heuristics/ff_heuristic.h +++ b/src/search/heuristics/ff_heuristic.h @@ -33,6 +33,7 @@ class FFHeuristic : public additive_heuristic::AdditiveHeuristic { virtual int compute_heuristic(const State &ancestor_state) override; public: FFHeuristic( + tasks::AxiomHandlingType axioms, const std::shared_ptr &transform, bool cache_estimates, const std::string &description, utils::Verbosity verbosity); diff --git a/src/search/heuristics/max_heuristic.cc b/src/search/heuristics/max_heuristic.cc index 40051ec2f..a0d78e2f8 100644 --- a/src/search/heuristics/max_heuristic.cc +++ b/src/search/heuristics/max_heuristic.cc @@ -23,10 +23,12 @@ namespace max_heuristic { // construction and destruction HSPMaxHeuristic::HSPMaxHeuristic( + tasks::AxiomHandlingType axioms, const shared_ptr &transform, bool cache_estimates, const string &description, utils::Verbosity verbosity) : RelaxationHeuristic( - transform, cache_estimates, description, verbosity) { + axioms, transform, cache_estimates, description, + verbosity) { if (log.is_at_least_normal()) { log << "Initializing HSP max heuristic..." << endl; } @@ -107,7 +109,7 @@ class HSPMaxHeuristicFeature HSPMaxHeuristicFeature() : TypedFeature("hmax") { document_title("Max heuristic"); - add_heuristic_options_to_feature(*this, "hmax"); + relaxation_heuristic::add_relaxation_heuristic_options_to_feature(*this, "hmax"); document_language_support("action costs", "supported"); document_language_support("conditional effects", "supported"); @@ -127,7 +129,8 @@ class HSPMaxHeuristicFeature const plugins::Options &opts, const utils::Context &) const override { return plugins::make_shared_from_arg_tuples( - get_heuristic_arguments_from_options(opts)); + relaxation_heuristic::get_relaxation_heuristic_arguments_from_options(opts) + ); } }; diff --git a/src/search/heuristics/max_heuristic.h b/src/search/heuristics/max_heuristic.h index 9ab122d30..06364721d 100644 --- a/src/search/heuristics/max_heuristic.h +++ b/src/search/heuristics/max_heuristic.h @@ -34,6 +34,7 @@ class HSPMaxHeuristic : public relaxation_heuristic::RelaxationHeuristic { virtual int compute_heuristic(const State &ancestor_state) override; public: HSPMaxHeuristic( + tasks::AxiomHandlingType axioms, const std::shared_ptr &transform, bool cache_estimates, const std::string &description, utils::Verbosity verbosity); diff --git a/src/search/heuristics/relaxation_heuristic.cc b/src/search/heuristics/relaxation_heuristic.cc index 7504a08f5..f98b3c6fb 100644 --- a/src/search/heuristics/relaxation_heuristic.cc +++ b/src/search/heuristics/relaxation_heuristic.cc @@ -1,5 +1,6 @@ #include "relaxation_heuristic.h" +#include "../plugins/plugin.h" #include "../task_utils/task_properties.h" #include "../utils/collections.h" #include "../utils/logging.h" @@ -33,12 +34,29 @@ UnaryOperator::UnaryOperator( operator_no(operator_no) { } +void add_relaxation_heuristic_options_to_feature( + plugins::Feature &feature, const string &description) { + tasks::add_axioms_option_to_feature(feature); + add_heuristic_options_to_feature(feature, description); +} + +tuple, bool, string, + utils::Verbosity> +get_relaxation_heuristic_arguments_from_options(const plugins::Options &opts) { + return tuple_cat( + tasks::get_axioms_arguments_from_options(opts), + get_heuristic_arguments_from_options(opts)); +} + // construction and destruction RelaxationHeuristic::RelaxationHeuristic( + tasks::AxiomHandlingType axioms, const shared_ptr &transform, bool cache_estimates, const string &description, utils::Verbosity verbosity) - : Heuristic(transform, cache_estimates, description, verbosity) { + : Heuristic(tasks::get_default_value_axioms_task_if_needed( + transform, axioms), + cache_estimates, description, verbosity) { // Build propositions. propositions.resize(task_properties::get_num_facts(task_proxy)); diff --git a/src/search/heuristics/relaxation_heuristic.h b/src/search/heuristics/relaxation_heuristic.h index be9ea54fe..218f46109 100644 --- a/src/search/heuristics/relaxation_heuristic.h +++ b/src/search/heuristics/relaxation_heuristic.h @@ -5,6 +5,7 @@ #include "../heuristic.h" +#include "../tasks/default_value_axioms_task.h" #include "../utils/collections.h" #include @@ -111,12 +112,18 @@ class RelaxationHeuristic : public Heuristic { Proposition *get_proposition(const FactProxy &fact); public: RelaxationHeuristic( + tasks::AxiomHandlingType axioms, const std::shared_ptr &transform, bool cache_estimates, const std::string &description, utils::Verbosity verbosity); virtual bool dead_ends_are_reliable() const override; }; -} +extern void add_relaxation_heuristic_options_to_feature( + plugins::Feature &feature, const std::string &description); +extern std::tuple, + bool, std::string, utils::Verbosity> +get_relaxation_heuristic_arguments_from_options(const plugins::Options &opts); +} #endif diff --git a/src/search/landmarks/landmark_cost_partitioning_heuristic.cc b/src/search/landmarks/landmark_cost_partitioning_heuristic.cc index a66524ce8..b1adc45d0 100644 --- a/src/search/landmarks/landmark_cost_partitioning_heuristic.cc +++ b/src/search/landmarks/landmark_cost_partitioning_heuristic.cc @@ -18,12 +18,13 @@ namespace landmarks { LandmarkCostPartitioningHeuristic::LandmarkCostPartitioningHeuristic( const shared_ptr &lm_factory, bool pref, bool prog_goal, bool prog_gn, bool prog_r, + tasks::AxiomHandlingType axioms, const shared_ptr &transform, bool cache_estimates, const string &description, utils::Verbosity verbosity, CostPartitioningMethod cost_partitioning, bool alm, lp::LPSolverType lpsolver) : LandmarkHeuristic( - pref, transform, cache_estimates, description, verbosity) { + axioms, pref, transform, cache_estimates, description, verbosity) { if (log.is_at_least_normal()) { log << "Initializing landmark cost partitioning heuristic..." << endl; } diff --git a/src/search/landmarks/landmark_cost_partitioning_heuristic.h b/src/search/landmarks/landmark_cost_partitioning_heuristic.h index be64e867c..fb57717c0 100644 --- a/src/search/landmarks/landmark_cost_partitioning_heuristic.h +++ b/src/search/landmarks/landmark_cost_partitioning_heuristic.h @@ -26,6 +26,7 @@ class LandmarkCostPartitioningHeuristic : public LandmarkHeuristic { LandmarkCostPartitioningHeuristic( const std::shared_ptr &lm_factory, bool pref, bool prog_goal, bool prog_gn, bool prog_r, + tasks::AxiomHandlingType axioms, const std::shared_ptr &transform, bool cache_estimates, const std::string &description, utils::Verbosity verbosity, diff --git a/src/search/landmarks/landmark_heuristic.cc b/src/search/landmarks/landmark_heuristic.cc index b03c119a1..cd0d75e1b 100644 --- a/src/search/landmarks/landmark_heuristic.cc +++ b/src/search/landmarks/landmark_heuristic.cc @@ -14,10 +14,12 @@ using namespace std; namespace landmarks { LandmarkHeuristic::LandmarkHeuristic( - bool use_preferred_operators, + tasks::AxiomHandlingType axioms, bool use_preferred_operators, const shared_ptr &transform, bool cache_estimates, const string &description, utils::Verbosity verbosity) - : Heuristic(transform, cache_estimates, description, verbosity), + : Heuristic(tasks::get_default_value_axioms_task_if_needed( + transform, axioms), + cache_estimates, description, verbosity), use_preferred_operators(use_preferred_operators), successor_generator(nullptr) { } @@ -27,14 +29,17 @@ void LandmarkHeuristic::initialize( bool prog_gn, bool prog_r) { /* Actually, we should test if this is the root task or a - CostAdaptedTask *of the root task*, but there is currently no good - way to do this, so we use this incomplete, slightly less safe test. + task that *only* transforms costs and/or adds negated axioms. + However, there is currently no good way to do this, so we use + this incomplete, slightly less safe test. */ if (task != tasks::g_root_task - && dynamic_cast(task.get()) == nullptr) { + && dynamic_cast(task.get()) == nullptr + && dynamic_cast(task.get()) == nullptr) { cerr << "The landmark heuristics currently only support " - << "task transformations that modify the operator costs. " - << "See issues 845 and 686 for details." << endl; + << "task transformations that modify the operator costs " + << "or add negated axioms. See issues 845, 686 and 454 " + << "for details." << endl; utils::exit_with(utils::ExitCode::SEARCH_UNSUPPORTED); } @@ -223,6 +228,7 @@ void add_landmark_heuristic_options_to_feature( "prog_gn", "Use greedy-necessary ordering progression.", "true"); feature.add_option( "prog_r", "Use reasonable ordering progression.", "true"); + tasks::add_axioms_option_to_feature(feature); add_heuristic_options_to_feature(feature, description); feature.document_property("preferred operators", @@ -230,7 +236,8 @@ void add_landmark_heuristic_options_to_feature( } tuple, bool, bool, bool, bool, - shared_ptr, bool, string, utils::Verbosity> + tasks::AxiomHandlingType, shared_ptr, bool, string, + utils::Verbosity> get_landmark_heuristic_arguments_from_options( const plugins::Options &opts) { return tuple_cat( @@ -239,8 +246,8 @@ get_landmark_heuristic_arguments_from_options( opts.get("pref"), opts.get("prog_goal"), opts.get("prog_gn"), - opts.get("prog_r") - ), + opts.get("prog_r")), + tasks::get_axioms_arguments_from_options(opts), get_heuristic_arguments_from_options(opts)); } } diff --git a/src/search/landmarks/landmark_heuristic.h b/src/search/landmarks/landmark_heuristic.h index 1cdab0128..55f0deab0 100644 --- a/src/search/landmarks/landmark_heuristic.h +++ b/src/search/landmarks/landmark_heuristic.h @@ -3,6 +3,8 @@ # include "../heuristic.h" +#include "../tasks/default_value_axioms_task.h" + class ConstBitsetView; namespace successor_generator { @@ -44,6 +46,7 @@ class LandmarkHeuristic : public Heuristic { virtual int compute_heuristic(const State &ancestor_state) override; public: LandmarkHeuristic( + tasks::AxiomHandlingType axioms, bool use_preferred_operators, const std::shared_ptr &transform, bool cache_estimates, const std::string &description, @@ -63,8 +66,9 @@ class LandmarkHeuristic : public Heuristic { extern void add_landmark_heuristic_options_to_feature( plugins::Feature &feature, const std::string &description); extern std::tuple, bool, bool, bool, - bool, std::shared_ptr, bool, - std::string, utils::Verbosity> + bool, tasks::AxiomHandlingType, + std::shared_ptr, bool, std::string, + utils::Verbosity> get_landmark_heuristic_arguments_from_options( const plugins::Options &opts); } diff --git a/src/search/landmarks/landmark_sum_heuristic.cc b/src/search/landmarks/landmark_sum_heuristic.cc index bcfd4ae58..51f447a54 100644 --- a/src/search/landmarks/landmark_sum_heuristic.cc +++ b/src/search/landmarks/landmark_sum_heuristic.cc @@ -33,10 +33,12 @@ static bool are_dead_ends_reliable( LandmarkSumHeuristic::LandmarkSumHeuristic( const shared_ptr &lm_factory, bool pref, bool prog_goal, bool prog_gn, bool prog_r, + tasks::AxiomHandlingType axioms, const shared_ptr &transform, bool cache_estimates, const string &description, utils::Verbosity verbosity) : LandmarkHeuristic( - pref, transform, cache_estimates, description, verbosity), + axioms, pref, transform, cache_estimates, + description, verbosity), dead_ends_reliable( are_dead_ends_reliable(lm_factory, task_proxy)) { if (log.is_at_least_normal()) { diff --git a/src/search/landmarks/landmark_sum_heuristic.h b/src/search/landmarks/landmark_sum_heuristic.h index 268d552af..70775e658 100644 --- a/src/search/landmarks/landmark_sum_heuristic.h +++ b/src/search/landmarks/landmark_sum_heuristic.h @@ -19,6 +19,7 @@ class LandmarkSumHeuristic : public LandmarkHeuristic { LandmarkSumHeuristic( const std::shared_ptr &lm_factory, bool pref, bool prog_goal, bool prog_gn, bool prog_r, + tasks::AxiomHandlingType axioms, const std::shared_ptr &transform, bool cache_estimates, const std::string &description, utils::Verbosity verbosity); diff --git a/src/search/tasks/default_value_axioms_task.cc b/src/search/tasks/default_value_axioms_task.cc new file mode 100644 index 000000000..61241f7b5 --- /dev/null +++ b/src/search/tasks/default_value_axioms_task.cc @@ -0,0 +1,429 @@ +#include "default_value_axioms_task.h" + +#include "../task_proxy.h" + +#include "../algorithms/sccs.h" +#include "../task_utils/task_properties.h" + +#include +#include +#include +#include + +using namespace std; +using utils::ExitCode; + +namespace tasks { +DefaultValueAxiomsTask::DefaultValueAxiomsTask( + const shared_ptr &parent, + AxiomHandlingType axioms) + : DelegatingTask(parent), + axioms(axioms), + default_value_axioms_start_index(parent->get_num_axioms()) { + TaskProxy task_proxy(*parent); + + /* + (non)default_dependencies store for each variable v all derived + variables that appear with their (non)default value in the body of + an axiom that sets v. + axiom_ids_for_var stores for each derived variable v which + axioms set v to their nondefault value. + Note that the vectors go over *all* variables (also non-derived ones), + but only the indices that correspond to a variable ID of a derived + variable actually have content. + */ + vector> nondefault_dependencies(task_proxy.get_variables().size()); + vector> default_dependencies(task_proxy.get_variables().size()); + vector> axiom_ids_for_var(task_proxy.get_variables().size()); + for (OperatorProxy axiom: task_proxy.get_axioms()) { + EffectProxy effect = axiom.get_effects()[0]; + int head_var = effect.get_fact().get_variable().get_id(); + axiom_ids_for_var[head_var].push_back(axiom.get_id()); + for (FactProxy cond: effect.get_conditions()) { + VariableProxy var_proxy = cond.get_variable(); + if (var_proxy.is_derived()) { + int var = cond.get_variable().get_id(); + if (cond.get_value() == var_proxy.get_default_axiom_value()) { + default_dependencies[head_var].push_back(var); + } else { + nondefault_dependencies[head_var].push_back(var); + } + } + } + } + + /* + Get the sccs induced by nondefault dependencies. + We do not include default dependencies because they cannot + introduce additional cycles (this would imply that the axioms + are not stratifiable, which is already checked in the translator). + */ + vector> sccs; + vector *> var_to_scc; + // We don't need the sccs if we set axioms "v=default <- {}" everywhere. + if (axioms == AxiomHandlingType::APPROXIMATE_NEGATIVE_CYCLES) { + sccs = sccs::compute_maximal_sccs(nondefault_dependencies); + var_to_scc = vector *>( + task_proxy.get_variables().size(), nullptr); + for (int i = 0; i < (int)sccs.size(); ++i) { + for (int var: sccs[i]) { + var_to_scc[var] = &sccs[i]; + } + } + } + + unordered_set default_value_needed = + get_vars_with_relevant_default_value(nondefault_dependencies, + default_dependencies, + var_to_scc); + + for (int var: default_value_needed) { + vector &axiom_ids = axiom_ids_for_var[var]; + int default_value = + task_proxy.get_variables()[var].get_default_axiom_value(); + + if (axioms == AxiomHandlingType::APPROXIMATE_NEGATIVE + || var_to_scc[var]->size() > 1) { + /* + If there is a cyclic dependency between several derived + variables, the "obvious" way of negating the formula + defining the derived variable is semantically wrong + (see issue453). + + In this case we perform a naive overapproximation + instead, which assumes that derived variables occurring + in the cycle can be false unconditionally. This is good + enough for correctness of the code that uses these + default value axioms, but loses accuracy. Negating the + axioms in an exact (non-overapproximating) way is possible + but more expensive (again, see issue453). + */ + default_value_axioms.emplace_back( + FactPair(var, default_value), vector()); + } else { + add_default_value_axioms_for_var( + FactPair(var, default_value), axiom_ids); + } + } +} + +/* + Collect for which derived variables it is relevant to know how they + can obtain their default value. This is done by tracking for all + derived variables which of their values are needed. + + Initially, we know that var=val is needed if it appears in a goal or + operator condition. Then we iteratively do the following: + a) If var=val is needed and var'=nondefault is in the body of an + axiom setting var=nondefault, then var'=val is needed. + b) If var=val is needed and var'=default is in the body of an axiom + setting var=nondefault, then var'=!val is needed, where + - !val=nondefault if val=default + - !val=default if val=nondefault + (var and var' are always derived variables.) + + If var=default is needed but we already know that the axioms we will + introduce for var=default are going to have an empty body, then we don't + apply a)/b) (because the axiom for var=default will not depend on anything). +*/ +unordered_set DefaultValueAxiomsTask::get_vars_with_relevant_default_value( + const vector> &nondefault_dependencies, + const vector> &default_dependencies, + const vector *> &var_to_scc) { + // Store which derived vars are needed default (true) / nondefault(false). + utils::HashSet> needed; + + TaskProxy task_proxy(*parent); + + // Collect derived variables that occur as their default value. + for (const FactProxy &goal: task_proxy.get_goals()) { + VariableProxy var_proxy = goal.get_variable(); + if (var_proxy.is_derived()) { + bool default_value = + goal.get_value() == var_proxy.get_default_axiom_value(); + needed.emplace(goal.get_pair().var, default_value); + } + } + for (OperatorProxy op: task_proxy.get_operators()) { + for (FactProxy condition: op.get_preconditions()) { + VariableProxy var_proxy = condition.get_variable(); + if (var_proxy.is_derived()) { + bool default_value = + condition.get_value() == var_proxy.get_default_axiom_value(); + needed.emplace(condition.get_pair().var, default_value); + } + } + for (EffectProxy effect: op.get_effects()) { + for (FactProxy condition: effect.get_conditions()) { + VariableProxy var_proxy = condition.get_variable(); + if (var_proxy.is_derived()) { + bool default_value = + condition.get_value() == var_proxy.get_default_axiom_value(); + needed.emplace(condition.get_pair().var, default_value); + } + } + } + } + + deque> to_process(needed.begin(), needed.end()); + while (!to_process.empty()) { + int var = to_process.front().first; + bool default_value = to_process.front().second; + to_process.pop_front(); + + /* + If we process a default value and already know that the axiom we + will introduce has an empty body (either because we trivially + overapproximate everything or because the variable has cyclic + dependencies), then the axiom (and thus the current variable/value + pair) doesn't depend on anything. + */ + if ((default_value) && + (axioms == AxiomHandlingType::APPROXIMATE_NEGATIVE + || var_to_scc[var]->size() > 1)) { + continue; + } + + for (int nondefault_dep : nondefault_dependencies[var]) { + auto insert_retval = needed.emplace(nondefault_dep, default_value); + if (insert_retval.second) { + to_process.emplace_back(nondefault_dep, default_value); + } + } + for (int default_dep : default_dependencies[var]) { + auto insert_retval = needed.emplace(default_dep, !default_value); + if (insert_retval.second) { + to_process.emplace_back(default_dep, !default_value); + } + } + } + + unordered_set default_needed; + for (pair entry : needed) { + if (entry.second) { + default_needed.insert(entry.first); + } + } + return default_needed; +} + + +void DefaultValueAxiomsTask::add_default_value_axioms_for_var( + FactPair head, vector &axiom_ids) { + TaskProxy task_proxy(*parent); + + /* + If no axioms change the variable to its non-default value, + then the default is always true. + */ + if (axiom_ids.empty()) { + default_value_axioms.emplace_back(head, vector()); + return; + } + + vector> conditions_as_cnf; + conditions_as_cnf.reserve(axiom_ids.size()); + for (int axiom_id : axiom_ids) { + OperatorProxy axiom = task_proxy.get_axioms()[axiom_id]; + conditions_as_cnf.emplace_back(); + for (FactProxy fact : axiom.get_effects()[0].get_conditions()) { + int var_id = fact.get_variable().get_id(); + int num_vals = task_proxy.get_variables()[var_id].get_domain_size(); + for (int value = 0; value < num_vals; ++value) { + if (value != fact.get_value()) { + conditions_as_cnf.back().insert({var_id, value}); + } + } + } + } + + // We can see multiplying out the cnf as collecting all hitting sets. + set current; + unordered_set current_vars; + set> hitting_sets; + collect_non_dominated_hitting_sets_recursively( + conditions_as_cnf, 0, current, current_vars, hitting_sets); + + for (const set &c : hitting_sets) { + default_value_axioms.emplace_back( + head, vector(c.begin(), c.end())); + } +} + + +void DefaultValueAxiomsTask::collect_non_dominated_hitting_sets_recursively( + const vector> &set_of_sets, size_t index, + set &hitting_set, unordered_set &hitting_set_vars, + set> &results) { + if (index == set_of_sets.size()) { + /* + Check whether the hitting set is dominated. + If we find a fact f in hitting_set such that no set in the + set of sets is covered by *only* f, then hitting_set \ {f} + is still a hitting set that dominates hitting_set. + */ + set not_uniquely_used(hitting_set); + for (const set &set : set_of_sets) { + vector intersection; + set_intersection(set.begin(), set.end(), + hitting_set.begin(), hitting_set.end(), + back_inserter(intersection)); + if (intersection.size() == 1) { + not_uniquely_used.erase(intersection[0]); + } + } + if (not_uniquely_used.empty()) { + results.insert(hitting_set); + } + return; + } + + const set &set = set_of_sets[index]; + for (const FactPair &elem : set) { + /* + If the current set is covered with the current hitting set + elements, we continue with the next set. + */ + if (hitting_set.find(elem) != hitting_set.end()) { + collect_non_dominated_hitting_sets_recursively( + set_of_sets, index + 1, hitting_set, hitting_set_vars, + results); + return; + } + } + + for (const FactPair &elem : set) { + // We don't allow choosing different facts from the same variable. + if (hitting_set_vars.find(elem.var) != hitting_set_vars.end()) { + continue; + } + + hitting_set.insert(elem); + hitting_set_vars.insert(elem.var); + collect_non_dominated_hitting_sets_recursively( + set_of_sets, index + 1, hitting_set, hitting_set_vars, + results); + hitting_set.erase(elem); + hitting_set_vars.erase(elem.var); + } +} + + +int DefaultValueAxiomsTask::get_operator_cost(int index, bool is_axiom) const { + if (!is_axiom || index < default_value_axioms_start_index) { + return parent->get_operator_cost(index, is_axiom); + } + + return 0; +} + +string DefaultValueAxiomsTask::get_operator_name(int index, bool is_axiom) const { + if (!is_axiom || index < default_value_axioms_start_index) { + return parent->get_operator_name(index, is_axiom); + } + + return ""; +} + +int DefaultValueAxiomsTask::get_num_operator_preconditions(int index, bool is_axiom) const { + if (!is_axiom || index < default_value_axioms_start_index) { + return parent->get_num_operator_preconditions(index, is_axiom); + } + + return 1; +} + +FactPair DefaultValueAxiomsTask::get_operator_precondition( + int op_index, int fact_index, bool is_axiom) const { + if (!is_axiom || (op_index < default_value_axioms_start_index)) { + return parent->get_operator_precondition(op_index, fact_index, is_axiom); + } + + assert(fact_index == 0); + FactPair head = default_value_axioms[op_index - default_value_axioms_start_index].head; + return FactPair(head.var, 1 - head.value); +} + +int DefaultValueAxiomsTask::get_num_operator_effects(int op_index, bool is_axiom) const { + if (!is_axiom || op_index < default_value_axioms_start_index) { + return parent->get_num_operator_effects(op_index, is_axiom); + } + + return 1; +} + +int DefaultValueAxiomsTask::get_num_operator_effect_conditions( + int op_index, int eff_index, bool is_axiom) const { + if (!is_axiom || op_index < default_value_axioms_start_index) { + return parent->get_num_operator_effect_conditions( + op_index, eff_index, is_axiom); + } + + assert(eff_index == 0); + return default_value_axioms[op_index - default_value_axioms_start_index].condition.size(); +} + +FactPair DefaultValueAxiomsTask::get_operator_effect_condition( + int op_index, int eff_index, int cond_index, bool is_axiom) const { + if (!is_axiom || op_index < default_value_axioms_start_index) { + return parent->get_operator_effect_condition( + op_index, eff_index, cond_index, is_axiom); + } + + assert(eff_index == 0); + return default_value_axioms[op_index - default_value_axioms_start_index].condition[cond_index]; +} + +FactPair DefaultValueAxiomsTask::get_operator_effect( + int op_index, int eff_index, bool is_axiom) const { + if (!is_axiom || op_index < default_value_axioms_start_index) { + return parent->get_operator_effect(op_index, eff_index, is_axiom); + } + + assert(eff_index == 0); + return default_value_axioms[op_index - default_value_axioms_start_index].head; +} + +int DefaultValueAxiomsTask::get_num_axioms() const { + return parent->get_num_axioms() + default_value_axioms.size(); +} + +shared_ptr get_default_value_axioms_task_if_needed( + const shared_ptr &task, + AxiomHandlingType axioms) { + TaskProxy proxy(*task); + if (task_properties::has_axioms(proxy)) { + return make_shared( + DefaultValueAxiomsTask(task, axioms)); + } + return task; +} + +void add_axioms_option_to_feature(plugins::Feature &feature) { + feature.add_option( + "axioms", + "How to compute axioms that describe how the negated " + "(=default) value of a derived variable can be achieved.", + "approximate_negative_cycles"); +} + +tuple get_axioms_arguments_from_options( + const plugins::Options &opts) { + return make_tuple( + opts.get("axioms")); +} + +static plugins::TypedEnumPlugin _enum_plugin({ + {"approximate_negative", + "Overapproximate negated axioms for all derived variables by " + "setting an empty condition, indicating the default value can " + "always be achieved for free."}, + {"approximate_negative_cycles", + "Overapproximate negated axioms for all derived variables which " + "have cyclic dependencies by setting an empty condition, " + "indicating the default value can always be achieved for free." + "For all other derived variables, the negated axioms are computed" + "exactly. Note that this can potentially lead to a combinatorial " + "explosion"} + }); +} diff --git a/src/search/tasks/default_value_axioms_task.h b/src/search/tasks/default_value_axioms_task.h new file mode 100644 index 000000000..1511a0d63 --- /dev/null +++ b/src/search/tasks/default_value_axioms_task.h @@ -0,0 +1,94 @@ +#ifndef TASKS_DEFAULT_VALUE_AXIOMS_TASK_H +#define TASKS_DEFAULT_VALUE_AXIOMS_TASK_H + +#include "delegating_task.h" + +#include "../plugins/plugin.h" + +#include + +/* + This task transformation adds explicit axioms for how the default value + of derived variables can be achieved. In general this is done as follows: + Given derived variable v with n axioms v <- c_1, ..., v <- c_n, add axioms + that together represent ¬v <- ¬c_1 ^ ... ^ ¬c_n. + + Notes: + - Technically, this transformation is illegal since it adds axioms which set + derived variables to their default value. Do not use it for search; the + axiom evaluator expects that all axioms set variables to their non-default + values (checked with an assertion). + - We assume that derived variables are binary. + - THE TRANSFORMATION CAN BE SLOW! The rule ¬v <- ¬c_1 ^ ... ^ ¬c_n must + be split up into axioms whose conditions are simple conjunctions. Since + all c_i are also simple conjunctions, this amounts to converting a CNF + to a DNF. + - The transformation is not exact. For derived variables v that have cyclic + dependencies, the general approach is incorrect. We instead trivially + overapproximate such cases with "¬v <- T" (see issue453). + - If you wish to avoid the combinatorial explosion from converting a + CNF to a DNF, you can set the option "axioms" to "approximate_negative"; + this will use the trivial overapproximation "¬v <- T" for *all* derived + variables. Note that this can negatively impact the heuristic values. + */ + +namespace tasks { +enum class AxiomHandlingType { + APPROXIMATE_NEGATIVE, APPROXIMATE_NEGATIVE_CYCLES +}; + +struct DefaultValueAxiom { + FactPair head; + std::vector condition; + + DefaultValueAxiom(FactPair head, std::vector &&condition) + : head(head), condition(condition) {} +}; + +class DefaultValueAxiomsTask : public DelegatingTask { + AxiomHandlingType axioms; + std::vector default_value_axioms; + int default_value_axioms_start_index; + + std::unordered_set get_vars_with_relevant_default_value( + const std::vector> &nondefault_dependencies, + const std::vector> &default_dependencies, + const std::vector *> &var_to_scc); + void add_default_value_axioms_for_var( + FactPair head, std::vector &axiom_ids); + void collect_non_dominated_hitting_sets_recursively( + const std::vector> &set_of_sets, size_t index, + std::set &hitting_set, + std::unordered_set &hitting_set_vars, + std::set> &results); +public: + explicit DefaultValueAxiomsTask( + const std::shared_ptr &parent, + AxiomHandlingType axioms); + virtual ~DefaultValueAxiomsTask() override = default; + + virtual int get_operator_cost(int index, bool is_axiom) const override; + virtual std::string get_operator_name(int index, bool is_axiom) const override; + virtual int get_num_operator_preconditions(int index, bool is_axiom) const override; + virtual FactPair get_operator_precondition( + int op_index, int fact_index, bool is_axiom) const override; + virtual int get_num_operator_effects(int op_index, bool is_axiom) const override; + virtual int get_num_operator_effect_conditions( + int op_index, int eff_index, bool is_axiom) const override; + virtual FactPair get_operator_effect_condition( + int op_index, int eff_index, int cond_index, bool is_axiom) const override; + virtual FactPair get_operator_effect( + int op_index, int eff_index, bool is_axiom) const override; + + virtual int get_num_axioms() const override; +}; + +extern std::shared_ptr get_default_value_axioms_task_if_needed( + const std::shared_ptr &task, + AxiomHandlingType axioms); +extern void add_axioms_option_to_feature(plugins::Feature &feature); +extern std::tuple get_axioms_arguments_from_options( + const plugins::Options &opts); +} + +#endif diff --git a/src/translate/axiom_rules.py b/src/translate/axiom_rules.py index 036ee9359..4a2b4511b 100644 --- a/src/translate/axiom_rules.py +++ b/src/translate/axiom_rules.py @@ -26,16 +26,16 @@ def __init__(self, axioms): else: self.positive_dependencies[head].add(body_atom) - # Remove all information for variables whose literals are not necessary. + # Remove all information for variables that are not necessary. # We do not need to remove single entries from the dicts because if the key # (= head of an axiom) is relevant, then all its values (= body of axiom) # must be relevant by definition. - def remove_unnecessary_variables(self, necessary_literals): - for var in self.derived_variables.copy(): - if var not in necessary_literals and var.negate() not in necessary_literals: - self.derived_variables.remove(var) + def remove_unnecessary_variables(self, necessary_atoms): + for var in self.derived_variables: + if var not in necessary_atoms: self.positive_dependencies.pop(var, None) self.negative_dependencies.pop(var, None) + self.derived_variables &= necessary_atoms class AxiomCluster(object): @@ -48,63 +48,46 @@ def __init__(self, derived_variables): # in the body. self.positive_children = set() self.negative_children = set() - self.needed_negatively = False self.layer = 0 def handle_axioms(operators, axioms, goals, layer_strategy): clusters = compute_clusters(axioms, goals, operators) axiom_layers = compute_axiom_layers(clusters, layer_strategy) - - # TODO: It would be cleaner if these negated rules were an implementation - # detail of the heuristics in the search component that make use of them - # rather than part of the translation process. They should be removed in - # the future. Similarly, it would be a good idea to remove the notion of - # axiom layers and derived variable default values from the output. - # (All derived variables should be binary and default to false.) - with timers.timing("Computing negative axioms"): - compute_negative_axioms(clusters) - axioms = get_axioms(clusters) if DEBUG: verify_layering_condition(axioms, axiom_layers) return axioms, axiom_layers -def compute_necessary_literals(dependencies, goals, operators): - necessary_literals = set() +def compute_necessary_atoms(dependencies, goals, operators): + necessary_atoms = set() for g in goals: - if g.positive() in dependencies.derived_variables: - necessary_literals.add(g) + g = g.positive() + if g in dependencies.derived_variables: + necessary_atoms.add(g) for op in operators: - derived_preconditions = (l for l in op.precondition if l.positive() + derived_preconditions = (l.positive() for l in op.precondition if l.positive() in dependencies.derived_variables) - necessary_literals.update(derived_preconditions) + necessary_atoms.update(derived_preconditions) for condition, effect in chain(op.add_effects, op.del_effects): for c in condition: - if c.positive() in dependencies.derived_variables: - necessary_literals.add(c) - necessary_literals.add(c.negate()) - - literals_to_process = list(necessary_literals) - while literals_to_process: - l = literals_to_process.pop() - atom = l.positive() - for body_atom in dependencies.positive_dependencies[atom]: - l2 = body_atom.negate() if l.negated else body_atom - if l2 not in necessary_literals: - literals_to_process.append(l2) - necessary_literals.add(l2) - for body_atom in dependencies.negative_dependencies[atom]: - l2 = body_atom if l.negated else body_atom.negate() - if l2 not in necessary_literals: - literals_to_process.append(l2) - necessary_literals.add(l2) - - return necessary_literals + c_atom = c.positive() + if c_atom in dependencies.derived_variables: + necessary_atoms.add(c_atom) + + atoms_to_process = list(necessary_atoms) + while atoms_to_process: + atom = atoms_to_process.pop() + for body_atom in chain(dependencies.positive_dependencies[atom], + dependencies.negative_dependencies[atom]): + if body_atom not in necessary_atoms: + atoms_to_process.append(body_atom) + necessary_atoms.add(body_atom) + return necessary_atoms # Compute strongly connected components of the dependency graph. @@ -167,19 +150,17 @@ def compute_clusters(axioms, goals, operators): dependencies = AxiomDependencies(axioms) # Compute necessary literals and prune unnecessary vars from dependencies. - necessary_literals = compute_necessary_literals(dependencies, goals, operators) - dependencies.remove_unnecessary_variables(necessary_literals) + necessary_atoms = compute_necessary_atoms(dependencies, goals, operators) + dependencies.remove_unnecessary_variables(necessary_atoms) groups = get_strongly_connected_components(dependencies) clusters = [AxiomCluster(group) for group in groups] - # Compute mapping from variables to their clusters and set needed_negatively. + # Compute mapping from variables to their clusters. variable_to_cluster = {} for cluster in clusters: for variable in cluster.variables: variable_to_cluster[variable] = cluster - if variable.negate() in necessary_literals: - cluster.needed_negatively = True # Assign axioms to their clusters. for axiom in axioms: @@ -247,60 +228,6 @@ def compute_axiom_layers(clusters, strategy): return layers -def compute_negative_axioms(clusters): - for cluster in clusters: - if cluster.needed_negatively: - if len(cluster.variables) > 1: - # If the cluster contains multiple variables, they have a cyclic - # positive dependency. In this case, the "obvious" way of - # negating the formula defining the derived variable is - # semantically wrong. For details, see issue453. - # - # Therefore, in this case we perform a naive overapproximation - # instead, which assumes that derived variables occurring in - # such clusters can be false unconditionally. This is good - # enough for correctness of the code that uses these negated - # axioms (within heuristics of the search component), but loses - # accuracy. Negating the rules in an exact - # (non-overapproximating) way is possible but more expensive. - # Again, see issue453 for details. - for variable in cluster.variables: - name = cluster.axioms[variable][0].name - negated_axiom = pddl.PropositionalAxiom(name, [], variable.negate()) - cluster.axioms[variable].append(negated_axiom) - else: - variable = next(iter(cluster.variables)) - negated_axioms = negate(cluster.axioms[variable]) - cluster.axioms[variable] += negated_axioms - - -def negate(axioms): - assert axioms - result = [pddl.PropositionalAxiom(axioms[0].name, [], axioms[0].effect.negate())] - for axiom in axioms: - condition = axiom.condition - if len(condition) == 0: - # The derived fact we want to negate is triggered with an - # empty condition, so it is always true and its negation - # is always false. - return [] - elif len(condition) == 1: # Handle easy special case quickly. - new_literal = condition[0].negate() - for result_axiom in result: - result_axiom.condition.append(new_literal) - else: - new_result = [] - for literal in condition: - literal = literal.negate() - for result_axiom in result: - new_axiom = result_axiom.clone() - new_axiom.condition.append(literal) - new_result.append(new_axiom) - result = new_result - result = compute_simplified_axioms(result) - return result - - def get_axioms(clusters): axioms = [] for cluster in clusters: @@ -312,13 +239,12 @@ def get_axioms(clusters): def verify_layering_condition(axioms, axiom_layers): # This function is only used for debugging. variables_in_heads = set() - literals_in_heads = set() variables_with_layers = set() for axiom in axioms: head = axiom.effect - variables_in_heads.add(head.positive()) - literals_in_heads.add(head) + assert not head.negated + variables_in_heads.add(head) variables_with_layers = set(axiom_layers.keys()) # 1. A variable has a defined layer iff it appears in a head. @@ -335,39 +261,20 @@ def verify_layering_condition(axioms, axiom_layers): assert isinstance(layer, int) assert layer >= 0 - # 2. For every rule head <- ... cond ... where cond is a literal - # of a derived variable where the layer of head is equal to - # the layer of cond, cond occurs with the same polarity in heads. - # - # Note regarding issue454 and issue453: Because of the negated axioms - # mentioned in these issues, a derived variable may appear with *both* - # polarities in heads. This makes this test less strong than it would - # be otherwise. When these issues are addressed and axioms only occur - # with one polarity in heads, this test will remain correct in its - # current form, but it will be able to detect more violations of the - # layering property. + # 2. For every rule head <- ... cond ... where cond is a literal of + # a derived variable, the layer of cond is strictly smaller than the + # layer of cond or it is equal and cond is an atom (not a negative + # literal). print("Verifying 2...") for axiom in axioms: head = axiom.effect - head_positive = head.positive() - body = axiom.condition - for cond in body: - cond_positive = cond.positive() - if (cond_positive in variables_in_heads and - axiom_layers[cond_positive] == axiom_layers[head_positive]): - assert cond in literals_in_heads - - # 3. For every rule head <- ... cond ... where cond is a literal - # of a derived variable, the layer of head is greater or equal - # to the layer of cond. - print("Verifying 3...") - for axiom in axioms: - head = axiom.effect - head_positive = head.positive() + head_layer = axiom_layers[head] body = axiom.condition for cond in body: cond_positive = cond.positive() - if cond_positive in variables_in_heads: + if cond_positive in variables_in_heads: # cond is derived variable + cond_layer = axiom_layers[cond_positive] + assert (cond_layer <= head_layer), (cond_layer, head_layer) # We need the assertion to be on a single line for # our error handler to be able to print the line. - assert (axiom_layers[cond_positive] <= axiom_layers[head_positive]), (axiom_layers[cond_positive], axiom_layers[head_positive]) + assert (not cond.negated or cond_layer < head_layer), (cond_layer, head_layer) diff --git a/src/translate/translate.py b/src/translate/translate.py index e060e8a59..d2df8cafb 100755 --- a/src/translate/translate.py +++ b/src/translate/translate.py @@ -379,18 +379,14 @@ def translate_strips_axiom(axiom, dictionary, ranges, mutex_dict, mutex_ranges): ranges, mutex_dict, mutex_ranges) if conditions is None: return [] - if axiom.effect.negated: - [(var, _)] = dictionary[axiom.effect.positive()] - effect = (var, ranges[var] - 1) - else: - [effect] = dictionary[axiom.effect] - # Here we exploit that due to the invariant analysis algorithm derived - # variables cannot have more than one representation in the dictionary, - # even with the full encoding. They can never be part of a non-trivial - # mutex group. - axioms = [] - for condition in conditions: - axioms.append(sas_tasks.SASAxiom(condition.items(), effect)) + assert not axiom.effect.negated + [effect] = dictionary[axiom.effect] + # Here we exploit that due to the invariant analysis algorithm derived + # variables cannot have more than one representation in the dictionary, + # even with the full encoding. They can never be part of a non-trivial + # mutex group. + axioms = [sas_tasks.SASAxiom(condition.items(), effect) + for condition in conditions] return axioms From e408c7d03f2319a4283d6dc5213fe7483684462e Mon Sep 17 00:00:00 2001 From: remochristen Date: Mon, 22 Jul 2024 18:56:27 +0200 Subject: [PATCH 07/28] [issue1140] Reinsert open nodes into open list upon finding cheaper paths. Functionally, this change only affects EagerSearch. Until now, upon finding a cheaper path to an open node, it was only reinserted into the open list if the reopen_closed flag was set to true. This caused the unintuitive behavior that an EagerSearch configuration equivalent to the astar plugin, except with reopen_closed set to false, combined with a consistent heuristic did not guarantee optimal solutions. We remedy this by reinserting independent of the reopen_closed flag when discovering a cheaper path to a node. At the same time we restructure functions in search_space.* which causes renaming in other search algorithms, but their behavior does not change. --- src/search/search_algorithms/eager_search.cc | 94 +++++++++---------- .../enforced_hill_climbing_search.cc | 3 +- src/search/search_algorithms/lazy_search.cc | 7 +- src/search/search_space.cc | 55 ++++++----- src/search/search_space.h | 21 +++-- 5 files changed, 93 insertions(+), 87 deletions(-) diff --git a/src/search/search_algorithms/eager_search.cc b/src/search/search_algorithms/eager_search.cc index 5ec760e57..951906fbc 100644 --- a/src/search/search_algorithms/eager_search.cc +++ b/src/search/search_algorithms/eager_search.cc @@ -139,15 +139,16 @@ SearchStatus EagerSearch::step() { With lazy evaluators (and only with these) we can have dead nodes in the open list. - For example, consider a state s that is reached twice before it is expanded. - The first time we insert it into the open list, we compute a finite - heuristic value. The second time we insert it, the cached value is reused. - - During first expansion, the heuristic value is recomputed and might become - infinite, for example because the reevaluation uses a stronger heuristic or - because the heuristic is path-dependent and we have accumulated more - information in the meantime. Then upon second expansion we have a dead-end - node which we must ignore. + For example, consider a state s that is reached twice before it is + expanded. The first time we insert it into the open list, we + compute a finite heuristic value. The second time we insert it, + the cached value is reused. + + During first expansion, the heuristic value is recomputed and + might become infinite, for example because the reevaluation uses a + stronger heuristic or because the heuristic is path-dependent and + we have accumulated more information in the meantime. Then upon + second expansion we have a dead-end node which we must ignore. */ if (node->is_dead_end()) continue; @@ -216,12 +217,14 @@ SearchStatus EagerSearch::step() { continue; if (succ_node.is_new()) { - // We have not seen this state before. - // Evaluate and create a new node. + /* + We have not seen this state before. + Evaluate and create a new node. - // Careful: succ_node.get_g() is not available here yet, - // hence the stupid computation of succ_g. - // TODO: Make this less fragile. + Careful: succ_node.get_g() is not available here yet, + hence the stupid computation of succ_g. + TODO: Make this less fragile. + */ int succ_g = node->get_g() + get_adjusted_cost(op); EvaluationContext succ_eval_context( @@ -233,7 +236,7 @@ SearchStatus EagerSearch::step() { statistics.inc_dead_ends(); continue; } - succ_node.open(*node, op, get_adjusted_cost(op)); + succ_node.open_new_node(*node, op, get_adjusted_cost(op)); open_list->insert(succ_eval_context, succ_state.get_id()); if (search_progress.check_progress(succ_eval_context)) { @@ -242,49 +245,42 @@ SearchStatus EagerSearch::step() { } } else if (succ_node.get_g() > node->get_g() + get_adjusted_cost(op)) { // We found a new cheapest path to an open or closed state. - if (reopen_closed_nodes) { - if (succ_node.is_closed()) { - /* - TODO: It would be nice if we had a way to test - that reopening is expected behaviour, i.e., exit - with an error when this is something where - reopening should not occur (e.g. A* with a - consistent heuristic). - */ - statistics.inc_reopened(); - } - succ_node.reopen(*node, op, get_adjusted_cost(op)); - + if (succ_node.is_open()) { + succ_node.update_open_node_parent( + *node, op, get_adjusted_cost(op)); EvaluationContext succ_eval_context( succ_state, succ_node.get_g(), is_preferred, &statistics); - + open_list->insert(succ_eval_context, succ_state.get_id()); + } else if (succ_node.is_closed() && reopen_closed_nodes) { /* - Note: our old code used to retrieve the h value from - the search node here. Our new code recomputes it as - necessary, thus avoiding the incredible ugliness of - the old "set_evaluator_value" approach, which also - did not generalize properly to settings with more - than one evaluator. - - Reopening should not happen all that frequently, so - the performance impact of this is hopefully not that - large. In the medium term, we want the evaluators to - remember evaluator values for states themselves if - desired by the user, so that such recomputations - will just involve a look-up by the Evaluator object - rather than a recomputation of the evaluator value - from scratch. + TODO: It would be nice if we had a way to test + that reopening is expected behaviour, i.e., exit + with an error when this is something where + reopening should not occur (e.g. A* with a + consistent heuristic). */ + statistics.inc_reopened(); + succ_node.reopen_closed_node(*node, op, get_adjusted_cost(op)); + EvaluationContext succ_eval_context( + succ_state, succ_node.get_g(), is_preferred, &statistics); open_list->insert(succ_eval_context, succ_state.get_id()); } else { - // If we do not reopen closed nodes, we just update the parent pointers. - // Note that this could cause an incompatibility between - // the g-value and the actual path that is traced back. - succ_node.update_parent(*node, op, get_adjusted_cost(op)); + /* + If we do not reopen closed nodes, we just update the parent + pointers. Note that this could cause an incompatibility + between the g-value and the actual path that is traced back. + */ + assert(succ_node.is_closed() && !reopen_closed_nodes); + succ_node.update_closed_node_parent( + *node, op, get_adjusted_cost(op)); } + } else { + /* + We found an equally or more expensive path to an open or closed + state. + */ } } - return IN_PROGRESS; } diff --git a/src/search/search_algorithms/enforced_hill_climbing_search.cc b/src/search/search_algorithms/enforced_hill_climbing_search.cc index 3899753ad..a8c1b3b94 100644 --- a/src/search/search_algorithms/enforced_hill_climbing_search.cc +++ b/src/search/search_algorithms/enforced_hill_climbing_search.cc @@ -214,7 +214,8 @@ SearchStatus EnforcedHillClimbingSearch::ehc() { } int h = eval_context.get_evaluator_value(evaluator.get()); - node.open(parent_node, last_op, get_adjusted_cost(last_op)); + node.open_new_node(parent_node, last_op, + get_adjusted_cost(last_op)); if (h < current_eval_context.get_evaluator_value(evaluator.get())) { ++num_ehc_phases; diff --git a/src/search/search_algorithms/lazy_search.cc b/src/search/search_algorithms/lazy_search.cc index 6b9870217..b4f933cea 100644 --- a/src/search/search_algorithms/lazy_search.cc +++ b/src/search/search_algorithms/lazy_search.cc @@ -183,10 +183,13 @@ SearchStatus LazySearch::step() { SearchNode parent_node = search_space.get_node(parent_state); OperatorProxy current_operator = task_proxy.get_operators()[current_operator_id]; if (reopen) { - node.reopen(parent_node, current_operator, get_adjusted_cost(current_operator)); + node.reopen_closed_node(parent_node, current_operator, + get_adjusted_cost( + current_operator)); statistics.inc_reopened(); } else { - node.open(parent_node, current_operator, get_adjusted_cost(current_operator)); + node.open_new_node(parent_node, current_operator, + get_adjusted_cost(current_operator)); } } node.close(); diff --git a/src/search/search_space.cc b/src/search/search_space.cc index 7ad271632..800103719 100644 --- a/src/search/search_space.cc +++ b/src/search/search_space.cc @@ -53,44 +53,43 @@ void SearchNode::open_initial() { info.creating_operator = OperatorID::no_operator; } -void SearchNode::open(const SearchNode &parent_node, - const OperatorProxy &parent_op, - int adjusted_cost) { - assert(info.status == SearchNodeInfo::NEW); - info.status = SearchNodeInfo::OPEN; +void SearchNode::update_parent(const SearchNode &parent_node, + const OperatorProxy &parent_op, + int adjusted_cost) { info.g = parent_node.info.g + adjusted_cost; info.real_g = parent_node.info.real_g + parent_op.get_cost(); info.parent_state_id = parent_node.get_state().get_id(); info.creating_operator = OperatorID(parent_op.get_id()); } -void SearchNode::reopen(const SearchNode &parent_node, - const OperatorProxy &parent_op, - int adjusted_cost) { - assert(info.status == SearchNodeInfo::OPEN || - info.status == SearchNodeInfo::CLOSED); +void SearchNode::open_new_node(const SearchNode &parent_node, + const OperatorProxy &parent_op, + int adjusted_cost) { + assert(info.status == SearchNodeInfo::NEW); + info.status = SearchNodeInfo::OPEN; + update_parent(parent_node, parent_op, adjusted_cost); +} - // The latter possibility is for inconsistent heuristics, which - // may require reopening closed nodes. +void SearchNode::reopen_closed_node(const SearchNode &parent_node, + const OperatorProxy &parent_op, + int adjusted_cost) { + assert(info.status == SearchNodeInfo::CLOSED); info.status = SearchNodeInfo::OPEN; - info.g = parent_node.info.g + adjusted_cost; - info.real_g = parent_node.info.real_g + parent_op.get_cost(); - info.parent_state_id = parent_node.get_state().get_id(); - info.creating_operator = OperatorID(parent_op.get_id()); + update_parent(parent_node, parent_op, adjusted_cost); } -// like reopen, except doesn't change status -void SearchNode::update_parent(const SearchNode &parent_node, - const OperatorProxy &parent_op, - int adjusted_cost) { - assert(info.status == SearchNodeInfo::OPEN || - info.status == SearchNodeInfo::CLOSED); - // The latter possibility is for inconsistent heuristics, which - // may require reopening closed nodes. - info.g = parent_node.info.g + adjusted_cost; - info.real_g = parent_node.info.real_g + parent_op.get_cost(); - info.parent_state_id = parent_node.get_state().get_id(); - info.creating_operator = OperatorID(parent_op.get_id()); +void SearchNode::update_open_node_parent(const SearchNode &parent_node, + const OperatorProxy &parent_op, + int adjusted_cost) { + assert(info.status == SearchNodeInfo::OPEN); + update_parent(parent_node, parent_op, adjusted_cost); +} + +void SearchNode::update_closed_node_parent(const SearchNode &parent_node, + const OperatorProxy &parent_op, + int adjusted_cost) { + assert(info.status == SearchNodeInfo::CLOSED); + update_parent(parent_node, parent_op, adjusted_cost); } void SearchNode::close() { diff --git a/src/search/search_space.h b/src/search/search_space.h index 1b2802b21..01aca776b 100644 --- a/src/search/search_space.h +++ b/src/search/search_space.h @@ -18,6 +18,10 @@ class LogProxy; class SearchNode { State state; SearchNodeInfo &info; + + void update_parent(const SearchNode &parent_node, + const OperatorProxy &parent_op, + int adjusted_cost); public: SearchNode(const State &state, SearchNodeInfo &info); @@ -32,15 +36,18 @@ class SearchNode { int get_real_g() const; void open_initial(); - void open(const SearchNode &parent_node, - const OperatorProxy &parent_op, - int adjusted_cost); - void reopen(const SearchNode &parent_node, - const OperatorProxy &parent_op, - int adjusted_cost); - void update_parent(const SearchNode &parent_node, + void open_new_node(const SearchNode &parent_node, const OperatorProxy &parent_op, int adjusted_cost); + void reopen_closed_node(const SearchNode &parent_node, + const OperatorProxy &parent_op, + int adjusted_cost); + void update_open_node_parent(const SearchNode &parent_node, + const OperatorProxy &parent_op, + int adjusted_cost); + void update_closed_node_parent(const SearchNode &parent_node, + const OperatorProxy &parent_op, + int adjusted_cost); void close(); void mark_as_dead_end(); From 261b03e537db0df2e1eb5302923df6ef5f8e8029 Mon Sep 17 00:00:00 2001 From: Florian Pommerening Date: Thu, 25 Jul 2024 18:26:20 +0200 Subject: [PATCH 08/28] [issue1142] Test newer OS and software versions in Github actions. * Mac: We now test on macOS 13 and 14 instead of 11 and 12. Both versions use Python 3.10. * Linux: We now test on Ubuntu 24.04 and no longer test on Ubuntu 20.04. On Ubuntu 22.04, we no longer test g++-11 and clang++-14 but now test g++-12 and clang++-15. On Ubuntu 24.04 we now test g++-14 and clang++-18. * SoPlex: our build now requires SoPlex 7.1.0 instead of a specific version based on SoPlex 6.0.3. This change affects performance slightly in some configurations with LP-based heuristics (see issue 1142 for details.) * We switched our style checks from clang-tidy-12 to clang-tidy-16. For instructions on how to install clang-tidy-16 on older systems, see https://www.fast-downward.org/ForDevelopers/DevelopmentSetup --- .github/workflows/autodoc.yml | 2 +- .github/workflows/mac.yml | 4 +-- .github/workflows/style.yml | 11 ++------ .github/workflows/ubuntu.yml | 25 ++++++------------- misc/releases/templates/_Dockerfile.tpl | 14 +++-------- misc/releases/templates/_Vagrantfile.tpl | 5 ++-- misc/style/run-clang-tidy.py | 8 +++--- src/search/CMakeLists.txt | 3 +-- src/search/cmake/common_cxx_flags.cmake | 8 ++++++ src/search/command_line.cc | 6 ++--- src/search/heuristics/hm_heuristic.cc | 2 -- src/search/heuristics/lm_cut_landmarks.cc | 2 -- .../landmarks/landmark_factory_rpg_sasp.cc | 1 + src/search/lp/soplex_solver_interface.cc | 2 ++ .../factored_transition_system.cc | 4 +-- .../merge_and_shrink_algorithm.cc | 3 --- 16 files changed, 40 insertions(+), 60 deletions(-) diff --git a/.github/workflows/autodoc.yml b/.github/workflows/autodoc.yml index eef77cad0..36759a50e 100644 --- a/.github/workflows/autodoc.yml +++ b/.github/workflows/autodoc.yml @@ -11,7 +11,7 @@ jobs: name: Autodoc if: github.repository == 'aibasel/downward' timeout-minutes: 60 - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 env: DOWNWARD_AUTODOC_PASSWORD: ${{ secrets.DOWNWARD_AUTODOC_PASSWORD }} steps: diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index c79ba3144..cc7a95ab1 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -15,8 +15,8 @@ jobs: strategy: matrix: version: - - {macos: macos-11, python: '3.8'} - - {macos: macos-12, python: '3.10'} + - {macos: macos-13, python: '3.10'} + - {macos: macos-14, python: '3.10'} steps: - name: Clone repository uses: actions/checkout@v3 diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index 5fc5f6df8..88ea3acac 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -10,7 +10,7 @@ on: jobs: style: name: Test code style - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Clone repository uses: actions/checkout@v3 @@ -23,14 +23,7 @@ jobs: - name: Install dependencies run: | pip3 install tox - sudo apt-get -y install clang-tidy-12 - - # TODO: Remove once issue with Ubuntu 22.04 and clang++-14 is resolved. - - name: Work around https://github.com/actions/runner-images/issues/8659 - run: | - sudo rm -f /etc/apt/sources.list.d/ubuntu-toolchain-r-ubuntu-test-jammy.list - sudo apt-get update - sudo apt-get install -y --allow-downgrades libc6=2.35-* libc6-dev=2.35-* libstdc++6=12.3.0-* libgcc-s1=12.3.0-* + sudo apt-get -y install clang-tidy-16 - name: Install uncrustify run: | diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 00df07d29..a179d7198 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -20,20 +20,19 @@ jobs: strategy: matrix: version: - - {ubuntu: 'ubuntu-20.04', python: '3.8', cc: gcc-10, cxx: g++-10, run_tox_tests: true} - - {ubuntu: 'ubuntu-20.04', python: '3.8', cc: clang-12, cxx: clang++-12, run_tox_tests: false} - - {ubuntu: 'ubuntu-22.04', python: '3.10', cc: gcc-11, cxx: g++-11, run_tox_tests: false} - {ubuntu: 'ubuntu-22.04', python: '3.10', cc: gcc-12, cxx: g++-12, run_tox_tests: true} - - {ubuntu: 'ubuntu-22.04', python: '3.10', cc: clang-14, cxx: clang++-14, run_tox_tests: false} + - {ubuntu: 'ubuntu-22.04', python: '3.10', cc: clang-15, cxx: clang++-15, run_tox_tests: false} + - {ubuntu: 'ubuntu-24.04', python: '3.10', cc: gcc-14, cxx: g++-14, run_tox_tests: true} + - {ubuntu: 'ubuntu-24.04', python: '3.10', cc: clang-18, cxx: clang++-18, run_tox_tests: false} env: CC: ${{ matrix.version.cc }} CXX: ${{ matrix.version.cxx }} CPLEX_URL: ${{ secrets.CPLEX2211_LINUX_URL }} cplex_DIR: /home/runner/lib/ibm/ILOG/CPLEX_Studio2211/cplex CPLEX_LIB: /home/runner/lib/ibm/ILOG/CPLEX_Studio2211/cplex/bin/x86-64_linux/libcplex2211.so - soplex_DIR: /home/runner/lib/soplex-6.0.3x - SOPLEX_LIB: /home/runner/lib/soplex-6.0.3x/lib/ - SOPLEX_INCLUDE: /home/runner/lib/soplex-6.0.3x/include/ + soplex_DIR: /home/runner/lib/soplex-7.1.0 + SOPLEX_LIB: /home/runner/lib/soplex-7.1.0/lib/ + SOPLEX_INCLUDE: /home/runner/lib/soplex-7.1.0/include/ steps: - name: Clone repository uses: actions/checkout@v3 @@ -57,14 +56,6 @@ jobs: run: | sudo apt-get -y install ${{ matrix.version.cxx }} - # TODO: Remove once issue with Ubuntu 22.04 and clang++-14 is resolved. - - name: Work around https://github.com/actions/runner-images/issues/8659 - if: matrix.version.cxx == 'clang++-14' - run: | - sudo rm -f /etc/apt/sources.list.d/ubuntu-toolchain-r-ubuntu-test-jammy.list - sudo apt-get update - sudo apt-get install -y --allow-downgrades libc6=2.35-* libc6-dev=2.35-* libstdc++6=12.3.0-* libgcc-s1=12.3.0-* - # Only install CPLEX if its URL/secret is set. - name: Install CPLEX if: ${{ env.CPLEX_URL != 0 }} @@ -80,7 +71,7 @@ jobs: run: | git clone https://github.com/scipopt/soplex.git cd soplex - git checkout a5df0814d67812c13a00f06eec507b4d071fb862 + git checkout release-710 cd .. cmake -S soplex -B build cmake --build build @@ -121,8 +112,8 @@ jobs: strategy: matrix: version: - - {ubuntu: ubuntu-20.04, python: '3.8'} - {ubuntu: ubuntu-22.04, python: '3.10'} + - {ubuntu: ubuntu-24.04, python: '3.10'} env: CPLEX_URL: ${{ secrets.CPLEX2211_LINUX_URL }} steps: diff --git a/misc/releases/templates/_Dockerfile.tpl b/misc/releases/templates/_Dockerfile.tpl index c301bf0ae..f70e5077d 100644 --- a/misc/releases/templates/_Dockerfile.tpl +++ b/misc/releases/templates/_Dockerfile.tpl @@ -6,7 +6,7 @@ ############################################################################### # A first image to build the planner ############################################################################### -FROM ubuntu:22.04 AS builder +FROM ubuntu:24.04 AS builder RUN apt-get update && apt-get install --no-install-recommends -y \ ca-certificates \ @@ -20,18 +20,12 @@ RUN apt-get update && apt-get install --no-install-recommends -y \ # Set up some environment variables. ENV CXX g++ -# TODO: on next release, replace this with a tagged SoPlex release > 6.0.3. -ENV SOPLEX_REVISION a5df081 +ENV SOPLEX_REVISION release-710 ENV soplex_DIR /opt/soplex # Install SoPlex. WORKDIR /workspace/soplex -# TODO: on next release, work with a tagged SoPlex release again if possible. -# We might continue using git clone, replacing this with `--depth 1 --branch $SOPLEX_REVISION` -# ($SOPLEX_REVISION needs to be a branch or tag, not a commit hash) or use -# another distribution mechanism. -RUN git clone --branch master https://github.com/scipopt/soplex.git . && \ - git checkout $SOPLEX_REVISION && \ +RUN git clone --depth 1 --branch $SOPLEX_REVISION https://github.com/scipopt/soplex.git . && \ cmake -DCMAKE_INSTALL_PREFIX="$soplex_DIR" -S . -B build && \ cmake --build build && \ cmake --install build @@ -46,7 +40,7 @@ RUN git clone --depth 1 --branch TAG https://github.com/aibasel/downward.git . & ############################################################################### # The final image to run the planner ############################################################################### -FROM ubuntu:22.04 AS runner +FROM ubuntu:24.04 AS runner RUN apt-get update && apt-get install --no-install-recommends -y \ python3 \ diff --git a/misc/releases/templates/_Vagrantfile.tpl b/misc/releases/templates/_Vagrantfile.tpl index 5b392053d..3fb8b0f2b 100644 --- a/misc/releases/templates/_Vagrantfile.tpl +++ b/misc/releases/templates/_Vagrantfile.tpl @@ -11,7 +11,7 @@ Vagrant.configure("2") do |config| v.memory = 2048 end - config.vm.box = "ubuntu/jammy64" + config.vm.box = "ubuntu/noble64" # To compile the planner with support for CPLEX, download the 64-bit Linux # installer of CPLEX 22.1.1 and set the environment variable @@ -56,9 +56,8 @@ Vagrant.configure("2") do |config| export soplex_DIR="/opt/soplex" EOM source /etc/profile.d/downward-soplex.sh - git clone --branch master https://github.com/scipopt/soplex.git soplex + git clone --depth 1 --branch release-710 https://github.com/scipopt/soplex.git soplex cd soplex - git checkout a5df081 cmake -DCMAKE_INSTALL_PREFIX="$soplex_DIR" -S . -B build cmake --build build cmake --install build diff --git a/misc/style/run-clang-tidy.py b/misc/style/run-clang-tidy.py index 2bc557ccd..8b3360b43 100755 --- a/misc/style/run-clang-tidy.py +++ b/misc/style/run-clang-tidy.py @@ -103,10 +103,10 @@ def check_search_code_with_clang_tidy(): {{key: performance-unnecessary-value-param.AllowedTypes, value: "{';'.join(LIGHTWEIGHT_TYPES)}"}},\ ]}}""".replace(" ", "") cmd = [ - "run-clang-tidy-12", + "run-clang-tidy-16", "-quiet", "-p", build_dir, - "-clang-tidy-binary=clang-tidy-12", + "-clang-tidy-binary=clang-tidy-16", "-checks=-*," + ",".join(checks), f"-config={config}", ] @@ -116,7 +116,7 @@ def check_search_code_with_clang_tidy(): try: p = subprocess.run(cmd, cwd=DIR, text=True, capture_output=True, check=False) except FileNotFoundError: - sys.exit(f"run-clang-tidy-12 not found. Is it on the PATH?") + sys.exit(f"run-clang-tidy-16 not found. Is it on the PATH?") output = f"{p.stdout}\n{p.stderr}" errors = re.findall(r"^(.*:\d+:\d+: .*(?:warning|error): .*)$", output, flags=re.M) filtered_errors = [error for error in errors if not any(ignore in error for ignore in IGNORES)] @@ -126,7 +126,7 @@ def check_search_code_with_clang_tidy(): for error in filtered_errors: print(error) fix_cmd = cmd + [ - "-clang-apply-replacements-binary=clang-apply-replacements-12", "-fix"] + "-clang-apply-replacements-binary=clang-apply-replacements-16", "-fix"] print("\nYou may be able to fix some of these issues with the following command:\n" + " ".join(pipes.quote(x) for x in fix_cmd)) sys.exit(1) diff --git a/src/search/CMakeLists.txt b/src/search/CMakeLists.txt index 393c2b2ed..2ed853265 100644 --- a/src/search/CMakeLists.txt +++ b/src/search/CMakeLists.txt @@ -561,8 +561,7 @@ if(USE_LP) target_sources(lp_solver INTERFACE lp/cplex_solver_interface.h lp/cplex_solver_interface.cc) endif() - # TODO: we actually require a version greater than 6.0.3 but it is not released yet. - find_package(soplex 6.0.3 QUIET) + find_package(soplex 7.1.0 QUIET) if (SOPLEX_FOUND) message(STATUS "Found SoPlex: ${SOPLEX_INCLUDE_DIRS}") target_link_libraries(lp_solver INTERFACE libsoplex) diff --git a/src/search/cmake/common_cxx_flags.cmake b/src/search/cmake/common_cxx_flags.cmake index 5d5cbd777..fcb160312 100644 --- a/src/search/cmake/common_cxx_flags.cmake +++ b/src/search/cmake/common_cxx_flags.cmake @@ -45,3 +45,11 @@ target_compile_options(common_cxx_warnings INTERFACE # /wd4244: conversion with possible loss of data # /wd4267: conversion from size_t to int with possible loss of data target_link_libraries(common_cxx_flags INTERFACE common_cxx_warnings) + +set(v15_or_later "$,15>") +set(using_clang "$") +set(using_apple_clang "$") +set(using_clang_like "$") +set(should_ignore_std_warning "$") +target_compile_options(common_cxx_warnings INTERFACE + "$<${should_ignore_std_warning}:-Wno-unqualified-std-cast-call>") diff --git a/src/search/command_line.cc b/src/search/command_line.cc index 714b5c962..e8934d924 100644 --- a/src/search/command_line.cc +++ b/src/search/command_line.cc @@ -89,7 +89,7 @@ static shared_ptr parse_cmd_line_aux(const vector &args SearchPtr search_algorithm = nullptr; // TODO: Remove code duplication. for (size_t i = 0; i < args.size(); ++i) { - string arg = args[i]; + const string &arg = args[i]; bool is_last = (i == args.size() - 1); if (arg == "--search") { if (search_algorithm) @@ -97,7 +97,7 @@ static shared_ptr parse_cmd_line_aux(const vector &args if (is_last) input_error("missing argument after --search"); ++i; - string search_arg = args[i]; + const string &search_arg = args[i]; try { parser::TokenStream tokens = parser::split_tokens(search_arg); parser::ASTNodePtr parsed = parser::parse(tokens); @@ -112,7 +112,7 @@ static shared_ptr parse_cmd_line_aux(const vector &args bool txt2tags = false; vector plugin_names; for (size_t j = i + 1; j < args.size(); ++j) { - string help_arg = args[j]; + const string &help_arg = args[j]; if (help_arg == "--txt2tags") { txt2tags = true; } else { diff --git a/src/search/heuristics/hm_heuristic.cc b/src/search/heuristics/hm_heuristic.cc index 0b6990ad8..63022ef27 100644 --- a/src/search/heuristics/hm_heuristic.cc +++ b/src/search/heuristics/hm_heuristic.cc @@ -64,9 +64,7 @@ void HMHeuristic::init_hm_table(const Tuple &t) { void HMHeuristic::update_hm_table() { - int round = 0; do { - ++round; was_updated = false; for (OperatorProxy op : task_proxy.get_operators()) { diff --git a/src/search/heuristics/lm_cut_landmarks.cc b/src/search/heuristics/lm_cut_landmarks.cc index ea8c5e650..590c070e6 100644 --- a/src/search/heuristics/lm_cut_landmarks.cc +++ b/src/search/heuristics/lm_cut_landmarks.cc @@ -288,9 +288,7 @@ bool LandmarkCutLandmarks::compute_landmarks( if (artificial_goal.status == UNREACHED) return true; - int num_iterations = 0; while (artificial_goal.h_max_cost != 0) { - ++num_iterations; mark_goal_plateau(&artificial_goal); assert(cut.empty()); second_exploration(state, second_exploration_queue, cut); diff --git a/src/search/landmarks/landmark_factory_rpg_sasp.cc b/src/search/landmarks/landmark_factory_rpg_sasp.cc index 813c02cd9..bb1b59216 100644 --- a/src/search/landmarks/landmark_factory_rpg_sasp.cc +++ b/src/search/landmarks/landmark_factory_rpg_sasp.cc @@ -175,6 +175,7 @@ void LandmarkFactoryRpgSasp::found_simple_lm_and_order( // Retrieve incoming edges from disj_lm vector predecessors; + predecessors.reserve(disj_lm->parents.size()); for (auto &pred : disj_lm->parents) { predecessors.push_back(pred.first); } diff --git a/src/search/lp/soplex_solver_interface.cc b/src/search/lp/soplex_solver_interface.cc index 02c7cdb22..e0331c638 100644 --- a/src/search/lp/soplex_solver_interface.cc +++ b/src/search/lp/soplex_solver_interface.cc @@ -143,8 +143,10 @@ void SoPlexSolverInterface::print_failure_analysis() const { case SPxSolverBase::Status::NOT_INIT: cout << "Not initialized" << endl; break; +#if SOPLEX_VERSION < 700 case SPxSolverBase::Status::ABORT_EXDECOMP: case SPxSolverBase::Status::ABORT_DECOMP: +#endif case SPxSolverBase::Status::ABORT_CYCLING: case SPxSolverBase::Status::ABORT_TIME: case SPxSolverBase::Status::ABORT_ITER: diff --git a/src/search/merge_and_shrink/factored_transition_system.cc b/src/search/merge_and_shrink/factored_transition_system.cc index d60e9afe0..f7ec99c7c 100644 --- a/src/search/merge_and_shrink/factored_transition_system.cc +++ b/src/search/merge_and_shrink/factored_transition_system.cc @@ -82,8 +82,8 @@ void FactoredTransitionSystem::assert_index_valid(int index) const { assert(utils::in_bounds(index, transition_systems)); assert(utils::in_bounds(index, mas_representations)); assert(utils::in_bounds(index, distances)); - if (!(transition_systems[index] && mas_representations[index] && distances[index]) && - !(!transition_systems[index] && !mas_representations[index] && !distances[index])) { + if ((!transition_systems[index] || !mas_representations[index] || !distances[index]) && + (transition_systems[index] || mas_representations[index] || distances[index])) { cerr << "Factor at index is in an inconsistent state!" << endl; utils::exit_with(utils::ExitCode::SEARCH_CRITICAL_ERROR); } diff --git a/src/search/merge_and_shrink/merge_and_shrink_algorithm.cc b/src/search/merge_and_shrink/merge_and_shrink_algorithm.cc index 7b678a766..dc9530d6d 100644 --- a/src/search/merge_and_shrink/merge_and_shrink_algorithm.cc +++ b/src/search/merge_and_shrink/merge_and_shrink_algorithm.cc @@ -200,7 +200,6 @@ void MergeAndShrinkAlgorithm::main_loop( << timer.get_elapsed_time() << " (" << msg << ")" << endl; }; - int iteration_counter = 0; while (fts.get_num_active_entries() > 1) { // Choose next transition systems to merge pair merge_indices = merge_strategy->get_next(); @@ -321,8 +320,6 @@ void MergeAndShrinkAlgorithm::main_loop( if (log.is_at_least_normal()) { log << endl; } - - ++iteration_counter; } log << "End of merge-and-shrink algorithm, statistics:" << endl; From f0fbdcb63d027cc5b2e117bc29935c7438529c49 Mon Sep 17 00:00:00 2001 From: Florian Pommerening Date: Fri, 26 Jul 2024 10:24:44 +0200 Subject: [PATCH 09/28] [issue1144] Ensure string parameters are listed as string in the documentation. Previously, string parameters showed up as std::cxx11::basic_string. --- src/search/plugins/types.cc | 12 ++++++------ src/search/plugins/types.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/search/plugins/types.cc b/src/search/plugins/types.cc index c1ca2c372..3f68ff99a 100644 --- a/src/search/plugins/types.cc +++ b/src/search/plugins/types.cc @@ -291,16 +291,16 @@ EmptyListType TypeRegistry::EMPTY_LIST_TYPE; BasicType TypeRegistry::NO_TYPE = BasicType(typeid(void), ""); TypeRegistry::TypeRegistry() { - insert_basic_type(); - insert_basic_type(); - insert_basic_type(); - insert_basic_type(); + insert_basic_type("bool"); + insert_basic_type("string"); + insert_basic_type("int"); + insert_basic_type("double"); } template -void TypeRegistry::insert_basic_type() { +void TypeRegistry::insert_basic_type(const string &name) { type_index type = typeid(T); - registered_types[type] = utils::make_unique_ptr(type, utils::get_type_name()); + registered_types[type] = utils::make_unique_ptr(type, name); } const FeatureType &TypeRegistry::create_feature_type(const CategoryPlugin &plugin) { diff --git a/src/search/plugins/types.h b/src/search/plugins/types.h index e0bb2523d..6ffe72b45 100644 --- a/src/search/plugins/types.h +++ b/src/search/plugins/types.h @@ -162,7 +162,7 @@ class TypeRegistry { std::unordered_map, SemanticHash, SemanticEqual> registered_list_types; template - void insert_basic_type(); + void insert_basic_type(const std::string &name); const Type &get_nonlist_type(std::type_index type) const; public: static BasicType NO_TYPE; From bff55bb83cdd6663e46f6ef940e8dc4dcd7ef321 Mon Sep 17 00:00:00 2001 From: Florian Pommerening Date: Fri, 26 Jul 2024 15:42:38 +0200 Subject: [PATCH 10/28] [issue1147] Use pathlib in driver. We updated the Python code of the driver to use `pathlib` instead of `os.path`. --- driver/aliases.py | 13 ++-- driver/arguments.py | 70 ++++++++++++------- driver/call.py | 9 ++- driver/cleanup.py | 18 +---- driver/main.py | 13 ++-- driver/plan_manager.py | 43 ++++++------ driver/portfolio_runner.py | 22 +++--- driver/run_components.py | 49 ++++++------- driver/tests.py | 13 ++-- driver/util.py | 28 ++++---- .../pddl_parser/parsing_functions.py | 2 +- 11 files changed, 138 insertions(+), 142 deletions(-) diff --git a/driver/aliases.py b/driver/aliases.py index 88dfb09ce..28b162d20 100644 --- a/driver/aliases.py +++ b/driver/aliases.py @@ -1,9 +1,7 @@ -import os - from .util import DRIVER_DIR -PORTFOLIO_DIR = os.path.join(DRIVER_DIR, "portfolios") +PORTFOLIO_DIR = DRIVER_DIR / "portfolios" ALIASES = {} @@ -143,12 +141,11 @@ def _get_lama(pref): PORTFOLIOS = {} -for portfolio in os.listdir(PORTFOLIO_DIR): - if portfolio == "__pycache__": +for portfolio in PORTFOLIO_DIR.iterdir(): + if portfolio.name == "__pycache__": continue - name, ext = os.path.splitext(portfolio) - assert ext == ".py", portfolio - PORTFOLIOS[name.replace("_", "-")] = os.path.join(PORTFOLIO_DIR, portfolio) + assert portfolio.suffix == ".py", str(portfolio) + PORTFOLIOS[portfolio.stem.replace("_", "-")] = PORTFOLIO_DIR / portfolio def show_aliases(): diff --git a/driver/arguments.py b/driver/arguments.py index cb61f8f94..9800d1e79 100644 --- a/driver/arguments.py +++ b/driver/arguments.py @@ -1,5 +1,5 @@ import argparse -import os.path +from pathlib import Path import re import sys @@ -47,8 +47,7 @@ that exceed their time or memory limit are aborted, and the next configuration is run.""" -EXAMPLE_PORTFOLIO = os.path.relpath( - aliases.PORTFOLIOS["seq-opt-fdss-1"], start=util.REPO_ROOT_DIR) +EXAMPLE_PORTFOLIO = aliases.PORTFOLIOS["seq-opt-fdss-1"].relative_to(util.REPO_ROOT_DIR) EXAMPLES = [ ("Translate and find a plan with A* + LM-Cut:", @@ -60,7 +59,7 @@ ("Run predefined configuration (LAMA-2011) on translated task:", ["--alias", "seq-sat-lama-2011", "output.sas"]), ("Run a portfolio on a translated task:", - ["--portfolio", EXAMPLE_PORTFOLIO, + ["--portfolio", str(EXAMPLE_PORTFOLIO), "--search-time-limit", "30m", "output.sas"]), ("Run the search component in debug mode (with assertions enabled) " "and validate the resulting plan:", @@ -81,7 +80,17 @@ "--evaluator", '"hff=ff()"', "--search", '"eager_greedy([hff], preferred=[hff])"']), ] -EPILOG = """component options: + +def _format_example(description, parameters): + call_string = " ".join([Path(sys.argv[0]).name] + parameters) + return f"{description}\n{call_string}" + + +def _format_examples(examples): + return "\n\n".join(_format_example(*example) for example in examples) + + +EPILOG = f"""component options: --translate-options OPTION1 OPTION2 ... --search-options OPTION1 OPTION2 ... pass OPTION1 OPTION2 ... to specified planner component @@ -89,11 +98,11 @@ Examples: -%s -""" % "\n\n".join("%s\n%s" % (desc, " ".join([os.path.basename(sys.argv[0])] + parameters)) for desc, parameters in EXAMPLES) +{_format_examples(EXAMPLES)} +""" COMPONENTS_PLUS_OVERALL = ["translate", "search", "validate", "overall"] -DEFAULT_SAS_FILE = "output.sas" +DEFAULT_SAS_FILE = Path("output.sas") """ @@ -102,7 +111,7 @@ """ def print_usage_and_exit_with_driver_input_error(parser, msg): parser.print_usage() - returncodes.exit_with_driver_input_error("{}: error: {}".format(os.path.basename(sys.argv[0]), msg)) + returncodes.exit_with_driver_input_error(f"{Path(sys.argv[0]).name}: error: {msg}") class RawHelpFormatter(argparse.HelpFormatter): @@ -211,8 +220,8 @@ def _set_components_automatically(parser, args): def _set_components_and_inputs(parser, args): """Set args.components to the planner components to be run and set - args.translate_inputs and args.search_input to the correct input - filenames. + args.translate_inputs, args.search_input, and args.validate_inputs + to the correct input filenames. Rules: 1. If any --run-xxx option is specified, then the union @@ -239,7 +248,6 @@ def _set_components_and_inputs(parser, args): assert args.components first = args.components[0] - num_files = len(args.filenames) # When passing --help to any of the components (or -h to the # translator), we don't require input filenames and silently # swallow any that are provided. This is undocumented to avoid @@ -247,26 +255,36 @@ def _set_components_and_inputs(parser, args): if first == "translate": if "--help" in args.translate_options or "-h" in args.translate_options: args.translate_inputs = [] - elif num_files == 1: - task_file, = args.filenames - domain_file = util.find_domain_filename(task_file) - args.translate_inputs = [domain_file, task_file] - elif num_files == 2: - args.translate_inputs = args.filenames else: - print_usage_and_exit_with_driver_input_error( - parser, "translator needs one or two input files") + args.translate_inputs = _get_pddl_input_files(args, parser, "translator") elif first == "search": if "--help" in args.search_options: args.search_input = None - elif num_files == 1: - args.search_input, = args.filenames + elif len(args.filenames) == 1: + args.search_input = Path(args.filenames[0]) else: print_usage_and_exit_with_driver_input_error( parser, "search needs exactly one input file") else: assert False, first + if "validate" in args.components: + args.validate_inputs = _get_pddl_input_files(args, parser, "validate") + + +def _get_pddl_input_files(args, parser, component): + num_files = len(args.filenames) + if num_files == 1: + task = Path(args.filenames[0]) + domain = util.find_domain_path(task) + elif num_files == 2: + domain = Path(args.filenames[0]) + task = Path(args.filenames[1]) + else: + print_usage_and_exit_with_driver_input_error( + parser, f"{component} needs one or two PDDL input files") + return [domain, task] + def _set_translator_output_options(parser, args): if any("--sas-file" in opt for opt in args.translate_options): @@ -397,20 +415,20 @@ def parse_args(): help="set log level (most verbose: debug; least verbose: warning; default: %(default)s)") driver_other.add_argument( - "--plan-file", metavar="FILE", default="sas_plan", + "--plan-file", metavar="FILE", default="sas_plan", type=Path, help="write plan(s) to FILE (default: %(default)s; anytime configurations append .1, .2, ...)") driver_other.add_argument( - "--sas-file", metavar="FILE", + "--sas-file", metavar="FILE", type=Path, help="intermediate file for storing the translator output " - "(implies --keep-sas-file, default: {})".format(DEFAULT_SAS_FILE)) + f"(implies --keep-sas-file, default: {DEFAULT_SAS_FILE})") driver_other.add_argument( "--keep-sas-file", action="store_true", help="keep translator output file (implied by --sas-file, default: " "delete file if translator and search component are active)") driver_other.add_argument( - "--portfolio", metavar="FILE", + "--portfolio", metavar="FILE", type=Path, help="run a portfolio specified in FILE") driver_other.add_argument( "--portfolio-bound", metavar="VALUE", default=None, type=int, diff --git a/driver/call.py b/driver/call.py index 4b583ee08..5509bf37d 100644 --- a/driver/call.py +++ b/driver/call.py @@ -10,9 +10,14 @@ import sys +def _replace_paths_with_strings(cmd): + return [str(x) for x in cmd] + + def print_call_settings(nick, cmd, stdin, time_limit, memory_limit): + cmd = _replace_paths_with_strings(cmd) if stdin is not None: - stdin = shlex.quote(stdin) + stdin = shlex.quote(str(stdin)) logging.info("{} stdin: {}".format(nick, stdin)) limits.print_limits(nick, time_limit, memory_limit) @@ -47,6 +52,7 @@ def fail(exception, exitcode): def check_call(nick, cmd, stdin=None, time_limit=None, memory_limit=None): + cmd = _replace_paths_with_strings(cmd) print_call_settings(nick, cmd, stdin, time_limit, memory_limit) kwargs = {"preexec_fn": _get_preexec_function(time_limit, memory_limit)} @@ -60,6 +66,7 @@ def check_call(nick, cmd, stdin=None, time_limit=None, memory_limit=None): def get_error_output_and_returncode(nick, cmd, time_limit=None, memory_limit=None): + cmd = _replace_paths_with_strings(cmd) print_call_settings(nick, cmd, None, time_limit, memory_limit) preexec_fn = _get_preexec_function(time_limit, memory_limit) diff --git a/driver/cleanup.py b/driver/cleanup.py index 7046ad529..a9f616366 100644 --- a/driver/cleanup.py +++ b/driver/cleanup.py @@ -1,17 +1,5 @@ -from itertools import count -import os - -def _try_remove(f): - try: - os.remove(f) - except OSError: - return False - return True +from .plan_manager import PlanManager def cleanup_temporary_files(args): - _try_remove(args.sas_file) - _try_remove(args.plan_file) - - for i in count(1): - if not _try_remove("%s.%s" % (args.plan_file, i)): - break + args.sas_file.unlink(missing_ok=True) + PlanManager(args.plan_file).delete_existing_plans() diff --git a/driver/main.py b/driver/main.py index 7c41781b8..e9ff38a51 100644 --- a/driver/main.py +++ b/driver/main.py @@ -1,5 +1,4 @@ import logging -import os import sys from . import aliases @@ -16,7 +15,7 @@ def main(): logging.basicConfig(level=getattr(logging, args.log_level.upper()), format="%(levelname)-8s %(message)s", stream=sys.stdout) - logging.debug("processed args: %s" % args) + logging.debug(f"processed args: {args}") if args.version: print(__version__) @@ -40,16 +39,16 @@ def main(): elif component == "search": (exitcode, continue_execution) = run_components.run_search(args) if not args.keep_sas_file: - print("Remove intermediate file {}".format(args.sas_file)) - os.remove(args.sas_file) + print(f"Remove intermediate file {args.sas_file}") + args.sas_file.unlink() elif component == "validate": (exitcode, continue_execution) = run_components.run_validate(args) else: - assert False, "Error: unhandled component: {}".format(component) - print("{component} exit code: {exitcode}".format(**locals())) + assert False, f"Error: unhandled component: {component}" + print(f"{component} exit code: {exitcode}") print() if not continue_execution: - print("Driver aborting after {}".format(component)) + print(f"Driver aborting after {component}") break try: diff --git a/driver/plan_manager.py b/driver/plan_manager.py index bca027762..58937eaca 100644 --- a/driver/plan_manager.py +++ b/driver/plan_manager.py @@ -1,6 +1,5 @@ import itertools -import os -import os.path +from pathlib import Path import re from . import returncodes @@ -9,20 +8,19 @@ _PLAN_INFO_REGEX = re.compile(r"; cost = (\d+) \((unit cost|general cost)\)\n") -def _read_last_line(filename): +def _read_last_line(path: Path): line = None - with open(filename) as input_file: + with path.open() as input_file: for line in input_file: pass return line -def _parse_plan(plan_filename): +def _parse_plan(plan_path: Path): """Parse a plan file and return a pair (cost, problem_type) summarizing the salient information. Return (None, None) for incomplete plans.""" - - last_line = _read_last_line(plan_filename) or "" + last_line = _read_last_line(plan_path) or "" match = _PLAN_INFO_REGEX.match(last_line) if match: return int(match.group(1)), match.group(2) @@ -31,7 +29,7 @@ def _parse_plan(plan_filename): class PlanManager: - def __init__(self, plan_prefix, portfolio_bound=None, single_plan=False): + def __init__(self, plan_prefix: Path, portfolio_bound=None, single_plan=False): self._plan_prefix = plan_prefix self._plan_costs = [] self._problem_type = None @@ -73,23 +71,22 @@ def process_new_plans(self): Read newly generated plans and store the relevant information. If the last plan file is incomplete, delete it. """ - had_incomplete_plan = False for counter in itertools.count(self.get_plan_counter() + 1): - plan_filename = self._get_plan_file(counter) + plan_path = self._get_plan_path(counter) def bogus_plan(msg): - returncodes.exit_with_driver_critical_error("%s: %s" % (plan_filename, msg)) - if not os.path.exists(plan_filename): + returncodes.exit_with_driver_critical_error(f"{str(plan_path)}: {msg}") + if not plan_path.exists(): break if had_incomplete_plan: bogus_plan("plan found after incomplete plan") - cost, problem_type = _parse_plan(plan_filename) + cost, problem_type = _parse_plan(plan_path) if cost is None: had_incomplete_plan = True - print("%s is incomplete. Deleted the file." % plan_filename) - os.remove(plan_filename) + print(f"{plan_path} is incomplete. Deleted the file.") + plan_path.unlink() else: - print("plan manager: found new plan with cost %d" % cost) + print(f"plan manager: found new plan with cost {cost}") if self._problem_type is None: # This is the first plan we found. self._problem_type = problem_type @@ -103,20 +100,20 @@ def bogus_plan(msg): def get_existing_plans(self): """Yield all plans that match the given plan prefix.""" - if os.path.exists(self._plan_prefix): + if self._plan_prefix.exists(): yield self._plan_prefix for counter in itertools.count(start=1): - plan_filename = self._get_plan_file(counter) - if os.path.exists(plan_filename): - yield plan_filename + plan_path = self._get_plan_path(counter) + if plan_path.exists(): + yield plan_path else: break def delete_existing_plans(self): """Delete all plans that match the given plan prefix.""" for plan in self.get_existing_plans(): - os.remove(plan) + plan.unlink() - def _get_plan_file(self, number): - return "%s.%d" % (self._plan_prefix, number) + def _get_plan_path(self, number): + return Path(f"{(self._plan_prefix)}.{number}") diff --git a/driver/portfolio_runner.py b/driver/portfolio_runner.py index 011ecff05..746020596 100644 --- a/driver/portfolio_runner.py +++ b/driver/portfolio_runner.py @@ -15,6 +15,7 @@ __all__ = ["run"] +from pathlib import Path import subprocess import sys @@ -184,17 +185,16 @@ def can_change_cost_type(args): return any("S_COST_TYPE" in part or "H_COST_TRANSFORM" in part for part in args) -def get_portfolio_attributes(portfolio): +def get_portfolio_attributes(portfolio: Path): attributes = {} - with open(portfolio, "rb") as portfolio_file: - content = portfolio_file.read() - try: - exec(content, attributes) - except Exception: - returncodes.exit_with_driver_critical_error( - "The portfolio %s could not be loaded. Maybe it still " - "uses the old portfolio syntax? See the FDSS portfolios " - "for examples using the new syntax." % portfolio) + content = portfolio.read_bytes() + try: + exec(content, attributes) + except Exception: + returncodes.exit_with_driver_critical_error( + f"The portfolio {portfolio} could not be loaded. Maybe it still " + "uses the old portfolio syntax? See the FDSS portfolios " + "for examples using the new syntax.") if "CONFIGS" not in attributes: returncodes.exit_with_driver_critical_error("portfolios must define CONFIGS") if "OPTIMAL" not in attributes: @@ -202,7 +202,7 @@ def get_portfolio_attributes(portfolio): return attributes -def run(portfolio, executable, sas_file, plan_manager, time, memory): +def run(portfolio: Path, executable, sas_file, plan_manager, time, memory): """ Run the configs in the given portfolio file. diff --git a/driver/run_components.py b/driver/run_components.py index 6043ce333..bdb5df127 100644 --- a/driver/run_components.py +++ b/driver/run_components.py @@ -1,6 +1,6 @@ -import errno import logging -import os.path +import os +from pathlib import Path import shutil import subprocess import sys @@ -20,35 +20,36 @@ returncodes.exit_with_driver_unsupported_error("Unsupported OS: " + os.name) # TODO: We might want to turn translate into a module and call it with "python3 -m translate". -REL_TRANSLATE_PATH = os.path.join("translate", "translate.py") -REL_SEARCH_PATH = f"downward{BINARY_EXT}" +REL_TRANSLATE_PATH = Path("translate") / "translate.py" +REL_SEARCH_PATH = Path(f"downward{BINARY_EXT}") # Older versions of VAL use lower case, newer versions upper case. We prefer the # older version because this is what our build instructions recommend. -VALIDATE = (shutil.which(f"validate{BINARY_EXT}") or - shutil.which(f"Validate{BINARY_EXT}")) +_VALIDATE_NAME = (shutil.which(f"validate{BINARY_EXT}") or + shutil.which(f"Validate{BINARY_EXT}")) +VALIDATE = Path(_VALIDATE_NAME) if _VALIDATE_NAME else None -def get_executable(build, rel_path): +def get_executable(build: str, rel_path: Path): # First, consider 'build' to be a path directly to the binaries. # The path can be absolute or relative to the current working # directory. - build_dir = build - if not os.path.exists(build_dir): + build_dir = Path(build) + if not build_dir.exists(): # If build is not a full path to the binaries, it might be the # name of a build in our standard directory structure. # in this case, the binaries are in # '/builds//bin'. - build_dir = os.path.join(util.BUILDS_DIR, build, "bin") - if not os.path.exists(build_dir): + build_dir = util.BUILDS_DIR / build / "bin" + if not build_dir.exists(): returncodes.exit_with_driver_input_error( - "Could not find build '{build}' at {build_dir}. " - "Please run './build.py {build}'.".format(**locals())) + f"Could not find build '{build}' at {build_dir}. " + f"Please run './build.py {build}'.") - abs_path = os.path.join(build_dir, rel_path) - if not os.path.exists(abs_path): + abs_path = build_dir / rel_path + if not abs_path.exists(): returncodes.exit_with_driver_input_error( - "Could not find '{rel_path}' in build '{build}'. " - "Please run './build.py {build}'.".format(**locals())) + f"Could not find '{rel_path}' in build '{build}'. " + f"Please run './build.py {build}'.") return abs_path @@ -115,7 +116,7 @@ def run_search(args): if args.portfolio: assert not args.search_options - logging.info("search portfolio: %s" % args.portfolio) + logging.info(f"search portfolio: {args.portfolio}") return portfolio_runner.run( args.portfolio, executable, args.search_input, plan_manager, time_limit, memory_limit) @@ -150,25 +151,15 @@ def run_validate(args): "Error: Trying to run validate but it was not found on the PATH.") logging.info("Running validate.") - num_files = len(args.filenames) - if num_files == 1: - task, = args.filenames - domain = util.find_domain_filename(task) - elif num_files == 2: - domain, task = args.filenames - else: - returncodes.exit_with_driver_input_error("validate needs one or two PDDL input files.") - plan_files = list(PlanManager(args.plan_file).get_existing_plans()) if not plan_files: print("Not running validate since no plans found.") return (0, True) - validate_inputs = [domain, task] + plan_files try: call.check_call( "validate", - [VALIDATE] + validate_inputs, + [VALIDATE] + args.validate_inputs + plan_files, time_limit=args.validate_time_limit, memory_limit=args.validate_memory_limit) except OSError as err: diff --git a/driver/tests.py b/driver/tests.py index 7b060dca8..33f6c61d9 100644 --- a/driver/tests.py +++ b/driver/tests.py @@ -14,11 +14,11 @@ from .aliases import ALIASES, PORTFOLIOS from .arguments import EXAMPLES -from .call import check_call +from .call import check_call, _replace_paths_with_strings from . import limits from . import returncodes from .run_components import get_executable, REL_SEARCH_PATH -from .util import REPO_ROOT_DIR, find_domain_filename +from .util import REPO_ROOT_DIR, find_domain_path def cleanup(): @@ -32,6 +32,7 @@ def teardown_module(module): def run_driver(parameters): cmd = [sys.executable, "fast-downward.py", "--keep"] + parameters + cmd = _replace_paths_with_strings(cmd) return subprocess.check_call(cmd, cwd=REPO_ROOT_DIR) @@ -59,7 +60,7 @@ def test_portfolios(): def _get_portfolio_configs(portfolio: Path): - content = portfolio.read_text() + content = portfolio.read_bytes() attributes = {} try: exec(content, attributes) @@ -95,7 +96,7 @@ def _run_search(config): def _get_all_portfolio_configs(): all_configs = set() for portfolio in PORTFOLIOS.values(): - configs = _get_portfolio_configs(Path(portfolio)) + configs = _get_portfolio_configs(portfolio) all_configs |= set(tuple(_convert_to_standalone_config(config)) for config in configs) return all_configs @@ -125,8 +126,8 @@ def preexec_fn(): def test_automatic_domain_file_name_computation(): - benchmarks_dir = os.path.join(REPO_ROOT_DIR, "benchmarks") + benchmarks_dir = REPO_ROOT_DIR / "benchmarks" for dirpath, dirnames, filenames in os.walk(benchmarks_dir): for filename in filenames: if "domain" not in filename: - assert find_domain_filename(os.path.join(dirpath, filename)) + assert find_domain_path(dirpath / filename) diff --git a/driver/util.py b/driver/util.py index 2bc571097..7016a2b80 100644 --- a/driver/util.py +++ b/driver/util.py @@ -1,11 +1,12 @@ import os +from pathlib import Path from . import returncodes -DRIVER_DIR = os.path.abspath(os.path.dirname(__file__)) -REPO_ROOT_DIR = os.path.dirname(DRIVER_DIR) -BUILDS_DIR = os.path.join(REPO_ROOT_DIR, "builds") +DRIVER_DIR = Path(__file__).parent.resolve() +REPO_ROOT_DIR = DRIVER_DIR.parent +BUILDS_DIR = REPO_ROOT_DIR / "builds" def get_elapsed_time(): @@ -19,25 +20,22 @@ def get_elapsed_time(): return sum(os.times()[:4]) -def find_domain_filename(task_filename): +def find_domain_path(task_path: Path): """ - Find domain filename for the given task using automatic naming rules. + Find domain path for the given task using automatic naming rules. """ - dirname, basename = os.path.split(task_filename) - basename_root, ext = os.path.splitext(basename) - domain_basenames = [ "domain.pddl", - basename_root + "-domain" + ext, - basename[:3] + "-domain.pddl", # for airport - "domain_" + basename, - "domain-" + basename, + task_path.stem + "-domain" + task_path.suffix, + task_path.name[:3] + "-domain.pddl", # for airport + "domain_" + task_path.name, + "domain-" + task_path.name, ] for domain_basename in domain_basenames: - domain_filename = os.path.join(dirname, domain_basename) - if os.path.exists(domain_filename): - return domain_filename + domain_path = task_path.parent / domain_basename + if domain_path.exists(): + return domain_path returncodes.exit_with_driver_input_error( "Error: Could not find domain file using automatic naming rules.") diff --git a/src/translate/pddl_parser/parsing_functions.py b/src/translate/pddl_parser/parsing_functions.py index e21e81b9d..bbfce44ae 100644 --- a/src/translate/pddl_parser/parsing_functions.py +++ b/src/translate/pddl_parser/parsing_functions.py @@ -297,7 +297,7 @@ def parse_literal(context, alist, type_dict, predicate_dict, negated=False): if arity != len(alist) - 1: context.error(f"Predicate '{predicate_name}' of arity {arity} used" - f" with {len(alist) -1} arguments.", alist) + f" with {len(alist) - 1} arguments.", alist) if negated: return pddl.NegatedAtom(pred_id, alist[1:]) From 8989cfbfb47aaccefd1fc86378522b1728db6b88 Mon Sep 17 00:00:00 2001 From: Malte Helmert Date: Mon, 19 Aug 2024 19:32:58 +0200 Subject: [PATCH 11/28] [trivial] Remove src/translate/{tests,regression-tests}. We discussed this in Discord, and there were no objections. Copying the relevant message: While working on some translator code, we stumbled over the directories src/translate/tests and src/translate/regression-tests/. We haven't touched tests since 2015 except for global changes like Python 2 => Python 3. We haven't touched regression-tests since 2013. As far as I remember, these predate the tests we actually use (and which live in a different part of the repository), and they don't satisfy the requirements you'd typically want of tests (not all are meant to be automatic tests in the usual way; the ones that are don't necessarily pass, even though there isn't a bug; the one that perhaps passes doesn't test something we still consider important, such as direct executability of certain translator source files). I suggest we delete these directories. If someone is keen on the functionality they were intended for, I think we would need to invest some work to make them useful. But I'm not convinced this is good value for time. --- src/translate/regression-tests/README | 7 - .../regression-tests/issue34-domain.pddl | 375 -- .../regression-tests/issue34-problem.pddl | 95 - .../regression-tests/issue405-domain.pddl | 50 - .../regression-tests/issue405-problem.pddl | 19 - .../issue49-falsegoal-domain.pddl | 14 - .../issue49-falsegoal-problem.pddl | 9 - .../regression-tests/issue49-orig-domain.pddl | 4159 ----------------- .../issue49-orig-problem.pddl | 470 -- .../issue49-truegoal-domain.pddl | 14 - .../issue49-truegoal-problem.pddl | 9 - .../regression-tests/issue58-domain.pddl | 17 - .../regression-tests/issue58-problem.pddl | 6 - .../regression-tests/issue7-domain.pddl | 243 - .../regression-tests/issue7-problem.pddl | 34 - .../regression-tests/issue73-domain.pddl | 979 ---- .../regression-tests/issue73-problem.pddl | 20 - src/translate/tests/__init__.py | 0 src/translate/tests/test_normalization.py | 37 - src/translate/tests/test_scripts.py | 25 - 20 files changed, 6582 deletions(-) delete mode 100644 src/translate/regression-tests/README delete mode 100644 src/translate/regression-tests/issue34-domain.pddl delete mode 100644 src/translate/regression-tests/issue34-problem.pddl delete mode 100644 src/translate/regression-tests/issue405-domain.pddl delete mode 100644 src/translate/regression-tests/issue405-problem.pddl delete mode 100644 src/translate/regression-tests/issue49-falsegoal-domain.pddl delete mode 100644 src/translate/regression-tests/issue49-falsegoal-problem.pddl delete mode 100644 src/translate/regression-tests/issue49-orig-domain.pddl delete mode 100644 src/translate/regression-tests/issue49-orig-problem.pddl delete mode 100644 src/translate/regression-tests/issue49-truegoal-domain.pddl delete mode 100644 src/translate/regression-tests/issue49-truegoal-problem.pddl delete mode 100644 src/translate/regression-tests/issue58-domain.pddl delete mode 100644 src/translate/regression-tests/issue58-problem.pddl delete mode 100644 src/translate/regression-tests/issue7-domain.pddl delete mode 100644 src/translate/regression-tests/issue7-problem.pddl delete mode 100644 src/translate/regression-tests/issue73-domain.pddl delete mode 100644 src/translate/regression-tests/issue73-problem.pddl delete mode 100644 src/translate/tests/__init__.py delete mode 100644 src/translate/tests/test_normalization.py delete mode 100644 src/translate/tests/test_scripts.py diff --git a/src/translate/regression-tests/README b/src/translate/regression-tests/README deleted file mode 100644 index 05f9654af..000000000 --- a/src/translate/regression-tests/README +++ /dev/null @@ -1,7 +0,0 @@ -- issue405: The goal violates a mutex, which the translator should - detect and produce a trivial unsolvable problem. The search code - should then report the problem as unsolvable. (It may be the case - that this example is a bit fragile because it's based on - Blocksworld, and I guess there's no guarantee which of the two major - Blocksworld encodings we get. I think only one of them will detect - that there is a mutex violation.) diff --git a/src/translate/regression-tests/issue34-domain.pddl b/src/translate/regression-tests/issue34-domain.pddl deleted file mode 100644 index bf64ca047..000000000 --- a/src/translate/regression-tests/issue34-domain.pddl +++ /dev/null @@ -1,375 +0,0 @@ -;; PipesWorld - -(define (domain pipesworld_strips) - -(:requirements :strips :typing ) - -;; Types -;; pipe: a pipeline segment -;; area: operational areas -;; product: an oil derivative product, such as gasoline, -;; kerosene, etc. -;; batch-atom: an unitary batch - -(:types pipe area product batch-atom ) - -;; Define the products (petroleum derivatives) -(:constants lco gasoleo rat-a oca1 oc1b - product ) -(:predicates - - ;; Indicates that a pipeline segment connects - ;; two areas - (connect ?from ?to - area ?pipe - pipe) - - ;; Special case for unitary pipes - (unitary ?pipe - pipe) - (not-unitary ?pipe - pipe) - - ;; These predicates represent the pipeline segment contents - ;; We define the first (nearest to ``from'' area) and - ;; last (nearest to ``to'' area) batch-atom in a pipeline - ;; segment, and their sequence is represented by the - ;; (follow) predicate - (last ?batch-atom - batch-atom ?pipe - pipe) - (first ?batch-atom - batch-atom ?pipe - pipe) - (follow ?next ?previous - batch-atom) - - ;; An unitary batch product - (is-product ?batch-atom - batch-atom ?product - product) - - ;; Unitary batches that are on areas - (on ?batch-atom - batch-atom ?area - area) - - ;; Indicates that two products may interface in the - ;; pipeline segment - (may-interface ?product-a ?product-b - product) - - ;; to control splitting process (push/pop vs. update) - (normal ?pipe - pipe) - (push-updating ?pipe - pipe) - (pop-updating ?pipe - pipe) -) - -;; PUSH-START action -;; Moves a batch-atom from a tankage to a pipeline segment -;; The PUSH-START action moves the pipeline segment contents towards -;; the ``to-area'' defined in the ``connect'' predicate -;; first part -- initialise the push and turn control -;; over to contents update operators - -(:action PUSH-START - :parameters( - ;; Pipeline segment that will be moved - ?pipe - pipe - ;; Unitary batch that will be inserted into the pipeline - ;; segment - ?batch-atom-in - batch-atom - ?from-area - area - ?to-area - area - ?first-batch-atom - batch-atom - ?product-batch-atom-in - product - ?product-first-batch - product - ) - :precondition - (and - - ;; normal planning mode - (normal ?pipe) - ;; Binds :vars section - (first ?first-batch-atom ?pipe) - (connect ?from-area ?to-area ?pipe) - ;; Inserted batch must be in 'from-area' - (on ?batch-atom-in ?from-area) - ;; Action is applicable only in non-unitary pipeline segments - (not-unitary ?pipe) - ;; Bind batch-atom products - (is-product ?batch-atom-in ?product-batch-atom-in) - (is-product ?first-batch-atom ?product-first-batch) - ;; Interface restriction - (may-interface ?product-batch-atom-in ?product-first-batch) - - ) - :effect - (and - ;; switch into correct update mode for this pipe - (push-updating ?pipe) - (not (normal ?pipe)) - ;; The inserted unitary batch will be the pipeline segment - ;; new first batch - (first ?batch-atom-in ?pipe) - (not (first ?first-batch-atom ?pipe)) - - ;; Updates the follow and last relationship to the new - ;; pipeline segment configuration - (follow ?first-batch-atom ?batch-atom-in) - ;; Inserted batch-atom is removed from area - (not (on ?batch-atom-in ?from-area)) - ;; Batch-atom removed from pipeline segment is inserted - ;; into the destination area -) -) -;; PUSH-END action -;; Moves a batch-atom from a tankage to a pipeline segment -;; The PUSH-END action moves the pipeline segment contents towards -;; the ``to-area'' defined in the ``connect'' predicate -;; second part -- when start of pipe has been done, care about the -;; end of the pipe - -(:action PUSH-END - :parameters( - ;; Pipeline segment that will be moved - ?pipe - pipe - ;; Unitary batch that will be inserted into the pipeline - ;; segment - ?from-area - area - ?to-area - area - ?last-batch-atom - batch-atom - ?next-last-batch-atom - batch-atom - ) - :precondition - (and - - ;; are we in the correct mode? - (push-updating ?pipe) - ;; Binds :vars section - (last ?last-batch-atom ?pipe) - (connect ?from-area ?to-area ?pipe) - ;; Action is applicable only in non-unitary pipeline segments - (not-unitary ?pipe) - (follow ?last-batch-atom ?next-last-batch-atom) - - ) - :effect - (and - ;; back to normal mode - (not (push-updating ?pipe)) - (normal ?pipe) - - ;; Updates the follow and last relationship to the new - ;; pipeline segment configuration - (not (follow ?last-batch-atom ?next-last-batch-atom)) - (last ?next-last-batch-atom ?pipe) - ;; Previous last batch is not last anymore - (not (last ?last-batch-atom ?pipe)) - ;; Batch-atom removed from pipeline segment is inserted - ;; into the destination area - (on ?last-batch-atom ?to-area) -) -) -;; POP-START action -;; Moves a batch-atom from a tankage to a pipeline segment -;; The POP-START action moves the pipeline segment contents towards -;; the ``from-area'' defined in the ``connect'' predicate -;; first part -- initialise the pop and turn control -;; over to contents update operators - -(:action POP-START - :parameters( - ;; Pipeline segment that will be moved - ?pipe - pipe - ;; Unitary batch that will be inserted into the pipeline - ;; segment - ?batch-atom-in - batch-atom - ?from-area - area - ?to-area - area - ?last-batch-atom - batch-atom - ?product-batch-atom-in - product - ?product-last-batch - product - ) - :precondition - (and - - ;; normal planning mode - (normal ?pipe) - ;; Binds :vars section - (last ?last-batch-atom ?pipe) - (connect ?from-area ?to-area ?pipe) - ;; Inserted batch must be in 'to-area' - (on ?batch-atom-in ?to-area) - ;; Action is applicable only in non-unitary pipeline segments - (not-unitary ?pipe) - ;; Bind batch-atom products - (is-product ?batch-atom-in ?product-batch-atom-in) - (is-product ?last-batch-atom ?product-last-batch) - ;; Interface restriction - (may-interface ?product-batch-atom-in ?product-last-batch) - - ) - :effect - (and - ;; switch into correct update mode for this pipe - (pop-updating ?pipe) - (not (normal ?pipe)) - ;; The inserted unitary batch will be the pipeline segment - ;; new last batch - (last ?batch-atom-in ?pipe) - (not (last ?last-batch-atom ?pipe)) - - ;; Updates the follow and first relationship to the new - ;; pipeline segment configuration - (follow ?batch-atom-in ?last-batch-atom) - ;; Inserted batch-atom is removed from area - (not (on ?batch-atom-in ?to-area)) - ;; Batch-atom removed from pipeline segment is inserted - ;; into the destination area -) -) -;; POP-END action -;; Moves a batch-atom from a tankage to a pipeline segment -;; The POP-END action moves the pipeline segment contents towards -;; the ``from-area'' defined in the ``connect'' predicate -;; second part -- when start of pipe has been done, care about the -;; end of the pipe - -(:action POP-END - :parameters( - ;; Pipeline segment that will be moved - ?pipe - pipe - ;; Unitary batch that will be inserted into the pipeline - ;; segment - ?from-area - area - ?to-area - area - ?first-batch-atom - batch-atom - ?next-first-batch-atom - batch-atom - ) - :precondition - (and - - ;; are we in the correct mode? - (pop-updating ?pipe) - ;; Binds :vars section - (first ?first-batch-atom ?pipe) - (connect ?from-area ?to-area ?pipe) - ;; Action is applicable only in non-unitary pipeline segments - (not-unitary ?pipe) - (follow ?next-first-batch-atom ?first-batch-atom) - - ) - :effect - (and - ;; back to normal mode - (not (pop-updating ?pipe)) - (normal ?pipe) - - ;; Updates the follow and first relationship to the new - ;; pipeline segment configuration - (not (follow ?next-first-batch-atom ?first-batch-atom)) - (first ?next-first-batch-atom ?pipe) - ;; Previous first batch is not first anymore - (not (first ?first-batch-atom ?pipe)) - ;; Batch-atom removed from pipeline segment is inserted - ;; into the destination area - (on ?first-batch-atom ?from-area) -) -) -;; PUSH-UNITARYPIPE action -;; Moves a batch-atom from a tankage to a pipeline segment -;; The PUSH-UNITARYPIPE action moves the pipeline segment contents towards -;; the ``to-area'' defined in the ``connect'' predicate -;; first part -- initialise the push and turn control -;; over to contents update operators - -(:action PUSH-UNITARYPIPE - :parameters( - ;; Pipeline segment that will be moved - ?pipe - pipe - ;; Unitary batch that will be inserted into the pipeline - ;; segment - ?batch-atom-in - batch-atom - ?from-area - area - ?to-area - area - ?first-batch-atom - batch-atom - ?product-batch-atom-in - product - ?product-first-batch - product - ) - :precondition - (and - - ;; Binds :vars section - (first ?first-batch-atom ?pipe) - (connect ?from-area ?to-area ?pipe) - ;; Inserted batch must be in 'from-area' - (on ?batch-atom-in ?from-area) - ;; Action is applicable only in unitary pipeline segments - (unitary ?pipe) - ;; Bind batch-atom products - (is-product ?batch-atom-in ?product-batch-atom-in) - (is-product ?first-batch-atom ?product-first-batch) - ;; Interface restriction - (may-interface ?product-batch-atom-in ?product-first-batch) - - ) - :effect - (and - ;; The inserted unitary batch will be the pipeline segment - ;; new first batch - (first ?batch-atom-in ?pipe) - (not (first ?first-batch-atom ?pipe)) - - ;; Updates the follow and last relationship to the new - ;; pipeline segment configuration - (last ?batch-atom-in ?pipe) - (not (last ?first-batch-atom ?pipe)) - ;; Inserted batch-atom is removed from area - (not (on ?batch-atom-in ?from-area)) - ;; Batch-atom removed from pipeline segment is inserted - ;; into the destination area - (on ?first-batch-atom ?to-area) -) -) -;; POP-UNITARYPIPE action -;; Moves a batch-atom from a tankage to a pipeline segment -;; The POP-UNITARYPIPE action moves the pipeline segment contents towards -;; the ``from-area'' defined in the ``connect'' predicate -;; first part -- initialise the pop and turn control -;; over to contents update operators - -(:action POP-UNITARYPIPE - :parameters( - ;; Pipeline segment that will be moved - ?pipe - pipe - ;; Unitary batch that will be inserted into the pipeline - ;; segment - ?batch-atom-in - batch-atom - ?from-area - area - ?to-area - area - ?last-batch-atom - batch-atom - ?product-batch-atom-in - product - ?product-last-batch - product - ) - :precondition - (and - - ;; Binds :vars section - (last ?last-batch-atom ?pipe) - (connect ?from-area ?to-area ?pipe) - ;; Inserted batch must be in 'to-area' - (on ?batch-atom-in ?to-area) - ;; Action is applicable only in unitary pipeline segments - (unitary ?pipe) - ;; Bind batch-atom products - (is-product ?batch-atom-in ?product-batch-atom-in) - (is-product ?last-batch-atom ?product-last-batch) - ;; Interface restriction - (may-interface ?product-batch-atom-in ?product-last-batch) - - ) - :effect - (and - ;; The inserted unitary batch will be the pipeline segment - ;; new last batch - (last ?batch-atom-in ?pipe) - (not (last ?last-batch-atom ?pipe)) - - ;; Updates the follow and first relationship to the new - ;; pipeline segment configuration - (first ?batch-atom-in ?pipe) - (not (first ?last-batch-atom ?pipe)) - ;; Inserted batch-atom is removed from area - (not (on ?batch-atom-in ?to-area)) - ;; Batch-atom removed from pipeline segment is inserted - ;; into the destination area - (on ?last-batch-atom ?from-area) -) -) -) diff --git a/src/translate/regression-tests/issue34-problem.pddl b/src/translate/regression-tests/issue34-problem.pddl deleted file mode 100644 index 154575b02..000000000 --- a/src/translate/regression-tests/issue34-problem.pddl +++ /dev/null @@ -1,95 +0,0 @@ - -(define (problem network3new_all_12_2_instance) - (:domain pipesworld_strips) - (:objects - - B10 B0 B1 B4 B6 B7 B9 B3 B8 B2 B11 B5 - batch-atom - A1 A2 A3 A4 - area - S12 S13 S34 - pipe - - - ) - (:init - - ;; All pipelines segments are in normal state - (normal S12) - (normal S13) - (normal S34) - - ;; Interfaces restrictions - (may-interface lco lco) - (may-interface gasoleo gasoleo) - (may-interface rat-a rat-a) - (may-interface oca1 oca1) - (may-interface oc1b oc1b) - (may-interface lco gasoleo) - (may-interface gasoleo lco) - (may-interface lco oca1) - (may-interface oca1 lco) - (may-interface lco oc1b) - (may-interface oc1b lco) - (may-interface lco rat-a) - (may-interface rat-a lco) - (may-interface gasoleo rat-a) - (may-interface rat-a gasoleo) - (may-interface gasoleo oca1) - (may-interface oca1 gasoleo) - (may-interface gasoleo oc1b) - (may-interface oc1b gasoleo) - (may-interface oca1 oc1b) - (may-interface oc1b oca1) - - - ;; Network topology definition - (connect A1 A2 S12) - (connect A1 A3 S13) - (connect A3 A4 S34) - - - ;; Batch-atoms products - (is-product B10 oc1b) - (is-product B0 lco) - (is-product B1 gasoleo) - (is-product B4 rat-a) - (is-product B6 rat-a) - (is-product B7 lco) - (is-product B9 gasoleo) - (is-product B3 gasoleo) - (is-product B8 oca1) - (is-product B2 rat-a) - (is-product B11 gasoleo) - (is-product B5 oc1b) - - - ;; Batch-atoms initially located in areas - (on B10 A4) - (on B1 A1) - (on B6 A1) - (on B3 A4) - (on B8 A4) - (on B2 A2) - (on B11 A2) - - - ;; Batch-atoms initially located in pipes - (first B5 S12) - (follow B0 B5) - (last B0 S12) - (first B7 S13) - (follow B9 B7) - (last B9 S13) - (first B4 S34) - (last B4 S34) - - ;; Unitary pipeline segments - (not-unitary S12) - (not-unitary S13) - (unitary S34) - - ) - (:goal (and - (on B6 A2) - (on B11 A1) - - )) -) diff --git a/src/translate/regression-tests/issue405-domain.pddl b/src/translate/regression-tests/issue405-domain.pddl deleted file mode 100644 index d11e32b52..000000000 --- a/src/translate/regression-tests/issue405-domain.pddl +++ /dev/null @@ -1,50 +0,0 @@ -(define (domain blocksworld) - (:requirements :strips :typing) - (:types block) - (:predicates (on ?x - block ?y - block) - (ontable ?x - block) - (clear ?x - block) - (handempty) - (holding ?x - block) - ) - - (:action pick-up - :parameters (?x - block) - :precondition (and (clear ?x) (ontable ?x) (handempty)) - :effect - (and (not (ontable ?x)) - (not (clear ?x)) - (not (handempty)) - (holding ?x))) - - (:action put-down - :parameters (?x - block) - :precondition (holding ?x) - :effect - (and (not (holding ?x)) - (clear ?x) - (handempty) - (ontable ?x))) - - (:action stack - :parameters (?x - block ?y - block) - :precondition (and (holding ?x) (clear ?y)) - :effect - (and (not (holding ?x)) - (not (clear ?y)) - (clear ?x) - (handempty) - (on ?x ?y))) - (:action unstack - :parameters (?x - block ?y - block) - :precondition (and (on ?x ?y) (clear ?x) (handempty)) - :effect - (and (holding ?x) - (clear ?y) - (not (clear ?x)) - (not (handempty)) - (not (on ?x ?y)))) - -) - - diff --git a/src/translate/regression-tests/issue405-problem.pddl b/src/translate/regression-tests/issue405-problem.pddl deleted file mode 100644 index 8d24ad128..000000000 --- a/src/translate/regression-tests/issue405-problem.pddl +++ /dev/null @@ -1,19 +0,0 @@ -(define (problem BW-rand-50) -(:domain blocksworld) -(:objects b1 b2 b3 - block) -(:init -(handempty) -(on b1 b2) -(on b2 b3) -(ontable b3) -(clear b1) -) -(:goal -(and -(on b1 b2) -(on b1 b3) -) -) -) - - diff --git a/src/translate/regression-tests/issue49-falsegoal-domain.pddl b/src/translate/regression-tests/issue49-falsegoal-domain.pddl deleted file mode 100644 index 526fc2bf7..000000000 --- a/src/translate/regression-tests/issue49-falsegoal-domain.pddl +++ /dev/null @@ -1,14 +0,0 @@ -;; Small test domain for the problem of issue49. - -(define (domain issue49) - (:predicates - (A) - (B) - (C) - ) - - (:action action-a - :precondition (A) - :effect (B) - ) -) diff --git a/src/translate/regression-tests/issue49-falsegoal-problem.pddl b/src/translate/regression-tests/issue49-falsegoal-problem.pddl deleted file mode 100644 index addac806b..000000000 --- a/src/translate/regression-tests/issue49-falsegoal-problem.pddl +++ /dev/null @@ -1,9 +0,0 @@ -(define (problem issue49-statically-false-goal) - (:domain issue49) - - (:objects) - - (:init (A)) - - (:goal (and (A) (B) (C))) -) diff --git a/src/translate/regression-tests/issue49-orig-domain.pddl b/src/translate/regression-tests/issue49-orig-domain.pddl deleted file mode 100644 index 201f338aa..000000000 --- a/src/translate/regression-tests/issue49-orig-domain.pddl +++ /dev/null @@ -1,4159 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; SeedSet -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - (define (domain SeedSet) - (:requirements :strips :typing :action-costs) - - (:predicates - (C00022) - (C00024) - (C00031) - (C00033) - (C00036) - (C00068) - (C00074) - (C00084) - (C00103) - (C00111) - (C00118) - (C00186) - (C00197) - (C00221) - (C00236) - (C00267) - (C00469) - (C00631) - (C00668) - (C01159) - (C01172) - (C01451) - (C05125) - (C05345) - (C05378) - (C06186) - (C06187) - (C06188) - (C15972) - (C15973) - (C16255) - (C00026) - (C00042) - (C00091) - (C00122) - (C00149) - (C00158) - (C00311) - (C00417) - (C05379) - (C05381) - (C16254) - (C00117) - (C00119) - (C00121) - (C00198) - (C00199) - (C00204) - (C00231) - (C00257) - (C00258) - (C00279) - (C00345) - (C00577) - (C00620) - (C00672) - (C00673) - (C01151) - (C01218) - (C01236) - (C01801) - (C03752) - (C04442) - (C05382) - (C06473) - (C00029) - (C00085) - (C00167) - (C00181) - (C00191) - (C00259) - (C00266) - (C00309) - (C00310) - (C00312) - (C00333) - (C00379) - (C00470) - (C00474) - (C00476) - (C00502) - (C00508) - (C00514) - (C00532) - (C00558) - (C00618) - (C00714) - (C00789) - (C00800) - (C00817) - (C00905) - (C01068) - (C01101) - (C01508) - (C01904) - (C02266) - (C02273) - (C03033) - (C03291) - (C03826) - (C04053) - (C04349) - (C04575) - (C05385) - (C05411) - (C05412) - (C06019) - (C06118) - (C06441) - (C14899) - (C00095) - (C00096) - (C00159) - (C00247) - (C00275) - (C00325) - (C00392) - (C00424) - (C00464) - (C00507) - (C00636) - (C00644) - (C00665) - (C00794) - (C00861) - (C00937) - (C00976) - (C01019) - (C01094) - (C01096) - (C01099) - (C01131) - (C01222) - (C01355) - (C01680) - (C01721) - (C01768) - (C01934) - (C02431) - (C02492) - (C02888) - (C02977) - (C02985) - (C02991) - (C03117) - (C03267) - (C03979) - (C05392) - (C06159) - (C06192) - (C11516) - (C11544) - (C00052) - (C00089) - (C00116) - (C00124) - (C00137) - (C00243) - (C00446) - (C00492) - (C00795) - (C00880) - (C01097) - (C01113) - (C01132) - (C01216) - (C01235) - (C01286) - (C01613) - (C01697) - (C02262) - (C03383) - (C03785) - (C05396) - (C05399) - (C05400) - (C05401) - (C05402) - (C05404) - (C05796) - (C06311) - (C06376) - (C06377) - (C00072) - (C00433) - (C00545) - (C00679) - (C00684) - (C00818) - (C00879) - (C01040) - (C01041) - (C01114) - (C01115) - (C01146) - (C01620) - (C01825) - (C02280) - (C02670) - (C03064) - (C03289) - (C03921) - (C05406) - (C05422) - (C15923) - (C15924) - (C15925) - (C15926) - (C15930) - (C16186) - (C00083) - (C00229) - (C00249) - (C00712) - (C01203) - (C01209) - (C01530) - (C01571) - (C02679) - (C03939) - (C04088) - (C04246) - (C04419) - (C04618) - (C04619) - (C04620) - (C04633) - (C04688) - (C05223) - (C05744) - (C05745) - (C05746) - (C05747) - (C05748) - (C05749) - (C05750) - (C05751) - (C05752) - (C05753) - (C05754) - (C05755) - (C05756) - (C05757) - (C05758) - (C05759) - (C05760) - (C05761) - (C05762) - (C05763) - (C05764) - (C06250) - (C06423) - (C06424) - (C08362) - (C16219) - (C16220) - (C16221) - (C16520) - (C00136) - (C00154) - (C01832) - (C01944) - (C02593) - (C03221) - (C05258) - (C05259) - (C05260) - (C05261) - (C05262) - (C05263) - (C05264) - (C05265) - (C05266) - (C05267) - (C05268) - (C05269) - (C05270) - (C05271) - (C05272) - (C05273) - (C05274) - (C05275) - (C05276) - (C00010) - (C00071) - (C00162) - (C00173) - (C00226) - (C00332) - (C00340) - (C00435) - (C00489) - (C00517) - (C00527) - (C00638) - (C00823) - (C00877) - (C01144) - (C01371) - (C02990) - (C03547) - (C03561) - (C05102) - (C05279) - (C05280) - ) - - (:functions (total-cost) - number) - - (:action insert_C00022 - :effect - (and (C00022) - (increase (total-cost) 10))) - - (:action insert_C00024 - :effect - (and (C00024) - (increase (total-cost) 10))) - - (:action insert_C00031 - :effect - (and (C00031) - (increase (total-cost) 10))) - - (:action insert_C00033 - :effect - (and (C00033) - (increase (total-cost) 10))) - - (:action insert_C00036 - :effect - (and (C00036) - (increase (total-cost) 10))) - - (:action insert_C00068 - :effect - (and (C00068) - (increase (total-cost) 10))) - - (:action insert_C00074 - :effect - (and (C00074) - (increase (total-cost) 10))) - - (:action insert_C00084 - :effect - (and (C00084) - (increase (total-cost) 10))) - - (:action insert_C00103 - :effect - (and (C00103) - (increase (total-cost) 10))) - - (:action insert_C00111 - :effect - (and (C00111) - (increase (total-cost) 10))) - - (:action insert_C00118 - :effect - (and (C00118) - (increase (total-cost) 10))) - - (:action insert_C00197 - :effect - (and (C00197) - (increase (total-cost) 10))) - - (:action insert_C00236 - :effect - (and (C00236) - (increase (total-cost) 10))) - - (:action insert_C00267 - :effect - (and (C00267) - (increase (total-cost) 10))) - - (:action insert_C00469 - :effect - (and (C00469) - (increase (total-cost) 10))) - - (:action insert_C00631 - :effect - (and (C00631) - (increase (total-cost) 10))) - - (:action insert_C00668 - :effect - (and (C00668) - (increase (total-cost) 10))) - - (:action insert_C01159 - :effect - (and (C01159) - (increase (total-cost) 10))) - - (:action insert_C01172 - :effect - (and (C01172) - (increase (total-cost) 10))) - - (:action insert_C05125 - :effect - (and (C05125) - (increase (total-cost) 10))) - - (:action insert_C05345 - :effect - (and (C05345) - (increase (total-cost) 10))) - - (:action insert_C05378 - :effect - (and (C05378) - (increase (total-cost) 10))) - - (:action insert_C15972 - :effect - (and (C15972) - (increase (total-cost) 10))) - - (:action insert_C15973 - :effect - (and (C15973) - (increase (total-cost) 10))) - - (:action insert_C16255 - :effect - (and (C16255) - (increase (total-cost) 10))) - - (:action insert_C00026 - :effect - (and (C00026) - (increase (total-cost) 10))) - - (:action insert_C00042 - :effect - (and (C00042) - (increase (total-cost) 10))) - - (:action insert_C00091 - :effect - (and (C00091) - (increase (total-cost) 10))) - - (:action insert_C00122 - :effect - (and (C00122) - (increase (total-cost) 10))) - - (:action insert_C00149 - :effect - (and (C00149) - (increase (total-cost) 10))) - - (:action insert_C00158 - :effect - (and (C00158) - (increase (total-cost) 10))) - - (:action insert_C00311 - :effect - (and (C00311) - (increase (total-cost) 10))) - - (:action insert_C00417 - :effect - (and (C00417) - (increase (total-cost) 10))) - - (:action insert_C05379 - :effect - (and (C05379) - (increase (total-cost) 10))) - - (:action insert_C05381 - :effect - (and (C05381) - (increase (total-cost) 10))) - - (:action insert_C16254 - :effect - (and (C16254) - (increase (total-cost) 10))) - - (:action insert_C00117 - :effect - (and (C00117) - (increase (total-cost) 10))) - - (:action insert_C00119 - :effect - (and (C00119) - (increase (total-cost) 10))) - - (:action insert_C00199 - :effect - (and (C00199) - (increase (total-cost) 10))) - - (:action insert_C00204 - :effect - (and (C00204) - (increase (total-cost) 10))) - - (:action insert_C00231 - :effect - (and (C00231) - (increase (total-cost) 10))) - - (:action insert_C00279 - :effect - (and (C00279) - (increase (total-cost) 10))) - - (:action insert_C00345 - :effect - (and (C00345) - (increase (total-cost) 10))) - - (:action insert_C00577 - :effect - (and (C00577) - (increase (total-cost) 10))) - - (:action insert_C01236 - :effect - (and (C01236) - (increase (total-cost) 10))) - - (:action insert_C04442 - :effect - (and (C04442) - (increase (total-cost) 10))) - - (:action insert_C05382 - :effect - (and (C05382) - (increase (total-cost) 10))) - - (:action insert_C06473 - :effect - (and (C06473) - (increase (total-cost) 10))) - - (:action insert_C00029 - :effect - (and (C00029) - (increase (total-cost) 10))) - - (:action insert_C00167 - :effect - (and (C00167) - (increase (total-cost) 10))) - - (:action insert_C00310 - :effect - (and (C00310) - (increase (total-cost) 10))) - - (:action insert_C00514 - :effect - (and (C00514) - (increase (total-cost) 10))) - - (:action insert_C00905 - :effect - (and (C00905) - (increase (total-cost) 10))) - - (:action insert_C00159 - :effect - (and (C00159) - (increase (total-cost) 10))) - - (:action insert_C00275 - :effect - (and (C00275) - (increase (total-cost) 10))) - - (:action insert_C00644 - :effect - (and (C00644) - (increase (total-cost) 10))) - - (:action insert_C00794 - :effect - (and (C00794) - (increase (total-cost) 10))) - - (:action insert_C01094 - :effect - (and (C01094) - (increase (total-cost) 10))) - - (:action insert_C01096 - :effect - (and (C01096) - (increase (total-cost) 10))) - - (:action insert_C01934 - :effect - (and (C01934) - (increase (total-cost) 10))) - - (:action insert_C02888 - :effect - (and (C02888) - (increase (total-cost) 10))) - - (:action insert_C03979 - :effect - (and (C03979) - (increase (total-cost) 10))) - - (:action insert_C00052 - :effect - (and (C00052) - (increase (total-cost) 10))) - - (:action insert_C00089 - :effect - (and (C00089) - (increase (total-cost) 10))) - - (:action insert_C00116 - :effect - (and (C00116) - (increase (total-cost) 10))) - - (:action insert_C00124 - :effect - (and (C00124) - (increase (total-cost) 10))) - - (:action insert_C00137 - :effect - (and (C00137) - (increase (total-cost) 10))) - - (:action insert_C00492 - :effect - (and (C00492) - (increase (total-cost) 10))) - - (:action insert_C01097 - :effect - (and (C01097) - (increase (total-cost) 10))) - - (:action insert_C01216 - :effect - (and (C01216) - (increase (total-cost) 10))) - - (:action insert_C01235 - :effect - (and (C01235) - (increase (total-cost) 10))) - - (:action insert_C01286 - :effect - (and (C01286) - (increase (total-cost) 10))) - - (:action insert_C03785 - :effect - (and (C03785) - (increase (total-cost) 10))) - - (:action insert_C05399 - :effect - (and (C05399) - (increase (total-cost) 10))) - - (:action insert_C05400 - :effect - (and (C05400) - (increase (total-cost) 10))) - - (:action insert_C05401 - :effect - (and (C05401) - (increase (total-cost) 10))) - - (:action insert_C05402 - :effect - (and (C05402) - (increase (total-cost) 10))) - - (:action insert_C05404 - :effect - (and (C05404) - (increase (total-cost) 10))) - - (:action insert_C00433 - :effect - (and (C00433) - (increase (total-cost) 10))) - - (:action insert_C00679 - :effect - (and (C00679) - (increase (total-cost) 10))) - - (:action insert_C00818 - :effect - (and (C00818) - (increase (total-cost) 10))) - - (:action insert_C00879 - :effect - (and (C00879) - (increase (total-cost) 10))) - - (:action insert_C01115 - :effect - (and (C01115) - (increase (total-cost) 10))) - - (:action insert_C02670 - :effect - (and (C02670) - (increase (total-cost) 10))) - - (:action insert_C00083 - :effect - (and (C00083) - (increase (total-cost) 10))) - - (:action insert_C00229 - :effect - (and (C00229) - (increase (total-cost) 10))) - - (:action insert_C01209 - :effect - (and (C01209) - (increase (total-cost) 10))) - - (:action insert_C04246 - :effect - (and (C04246) - (increase (total-cost) 10))) - - (:action insert_C04419 - :effect - (and (C04419) - (increase (total-cost) 10))) - - (:action insert_C04618 - :effect - (and (C04618) - (increase (total-cost) 10))) - - (:action insert_C04619 - :effect - (and (C04619) - (increase (total-cost) 10))) - - (:action insert_C04620 - :effect - (and (C04620) - (increase (total-cost) 10))) - - (:action insert_C04633 - :effect - (and (C04633) - (increase (total-cost) 10))) - - (:action insert_C04688 - :effect - (and (C04688) - (increase (total-cost) 10))) - - (:action insert_C05223 - :effect - (and (C05223) - (increase (total-cost) 10))) - - (:action insert_C05744 - :effect - (and (C05744) - (increase (total-cost) 10))) - - (:action insert_C05745 - :effect - (and (C05745) - (increase (total-cost) 10))) - - (:action insert_C05746 - :effect - (and (C05746) - (increase (total-cost) 10))) - - (:action insert_C05747 - :effect - (and (C05747) - (increase (total-cost) 10))) - - (:action insert_C05748 - :effect - (and (C05748) - (increase (total-cost) 10))) - - (:action insert_C05749 - :effect - (and (C05749) - (increase (total-cost) 10))) - - (:action insert_C05750 - :effect - (and (C05750) - (increase (total-cost) 10))) - - (:action insert_C05751 - :effect - (and (C05751) - (increase (total-cost) 10))) - - (:action insert_C05752 - :effect - (and (C05752) - (increase (total-cost) 10))) - - (:action insert_C05753 - :effect - (and (C05753) - (increase (total-cost) 10))) - - (:action insert_C05754 - :effect - (and (C05754) - (increase (total-cost) 10))) - - (:action insert_C05755 - :effect - (and (C05755) - (increase (total-cost) 10))) - - (:action insert_C05756 - :effect - (and (C05756) - (increase (total-cost) 10))) - - (:action insert_C05757 - :effect - (and (C05757) - (increase (total-cost) 10))) - - (:action insert_C05758 - :effect - (and (C05758) - (increase (total-cost) 10))) - - (:action insert_C05759 - :effect - (and (C05759) - (increase (total-cost) 10))) - - (:action insert_C05760 - :effect - (and (C05760) - (increase (total-cost) 10))) - - (:action insert_C05761 - :effect - (and (C05761) - (increase (total-cost) 10))) - - (:action insert_C05762 - :effect - (and (C05762) - (increase (total-cost) 10))) - - (:action insert_C05763 - :effect - (and (C05763) - (increase (total-cost) 10))) - - (:action insert_C05764 - :effect - (and (C05764) - (increase (total-cost) 10))) - - (:action insert_C06250 - :effect - (and (C06250) - (increase (total-cost) 10))) - - (:action insert_C16219 - :effect - (and (C16219) - (increase (total-cost) 10))) - - (:action insert_C16220 - :effect - (and (C16220) - (increase (total-cost) 10))) - - (:action insert_C16221 - :effect - (and (C16221) - (increase (total-cost) 10))) - - (:action insert_C00136 - :effect - (and (C00136) - (increase (total-cost) 10))) - - (:action insert_C01832 - :effect - (and (C01832) - (increase (total-cost) 10))) - - (:action insert_C01944 - :effect - (and (C01944) - (increase (total-cost) 10))) - - (:action insert_C02593 - :effect - (and (C02593) - (increase (total-cost) 10))) - - (:action insert_C03221 - :effect - (and (C03221) - (increase (total-cost) 10))) - - (:action insert_C05258 - :effect - (and (C05258) - (increase (total-cost) 10))) - - (:action insert_C05259 - :effect - (and (C05259) - (increase (total-cost) 10))) - - (:action insert_C05260 - :effect - (and (C05260) - (increase (total-cost) 10))) - - (:action insert_C05261 - :effect - (and (C05261) - (increase (total-cost) 10))) - - (:action insert_C05262 - :effect - (and (C05262) - (increase (total-cost) 10))) - - (:action insert_C05263 - :effect - (and (C05263) - (increase (total-cost) 10))) - - (:action insert_C05264 - :effect - (and (C05264) - (increase (total-cost) 10))) - - (:action insert_C05265 - :effect - (and (C05265) - (increase (total-cost) 10))) - - (:action insert_C05266 - :effect - (and (C05266) - (increase (total-cost) 10))) - - (:action insert_C05267 - :effect - (and (C05267) - (increase (total-cost) 10))) - - (:action insert_C05268 - :effect - (and (C05268) - (increase (total-cost) 10))) - - (:action insert_C05269 - :effect - (and (C05269) - (increase (total-cost) 10))) - - (:action insert_C05270 - :effect - (and (C05270) - (increase (total-cost) 10))) - - (:action insert_C05271 - :effect - (and (C05271) - (increase (total-cost) 10))) - - (:action insert_C05272 - :effect - (and (C05272) - (increase (total-cost) 10))) - - (:action insert_C05273 - :effect - (and (C05273) - (increase (total-cost) 10))) - - (:action insert_C05274 - :effect - (and (C05274) - (increase (total-cost) 10))) - - (:action insert_C05275 - :effect - (and (C05275) - (increase (total-cost) 10))) - - (:action insert_C05276 - :effect - (and (C05276) - (increase (total-cost) 10))) - - (:action insert_C00010 - :effect - (and (C00010) - (increase (total-cost) 10))) - - (:action insert_C00071 - :effect - (and (C00071) - (increase (total-cost) 10))) - - (:action insert_C00173 - :effect - (and (C00173) - (increase (total-cost) 10))) - - (:action insert_C00226 - :effect - (and (C00226) - (increase (total-cost) 10))) - - (:action insert_C00332 - :effect - (and (C00332) - (increase (total-cost) 10))) - - (:action insert_C00638 - :effect - (and (C00638) - (increase (total-cost) 10))) - - (:action insert_C00877 - :effect - (and (C00877) - (increase (total-cost) 10))) - - (:action insert_C01144 - :effect - (and (C01144) - (increase (total-cost) 10))) - - (:action insert_C03561 - :effect - (and (C03561) - (increase (total-cost) 10))) - - (:action insert_C05279 - :effect - (and (C05279) - (increase (total-cost) 10))) - - (:action insert_C05280 - :effect - (and (C05280) - (increase (total-cost) 10))) - - (:action reaction_R00014left - :precondition - (and - (C00022) - (C00068) - ) - :effect - (and - (C05125) - (increase (total-cost) 1))) - - (:action reaction_R00200left - :precondition - (and - (C00074) - ) - :effect - (and - (C00022) - (increase (total-cost) 1))) - - (:action reaction_R00235left - :precondition - (and - (C00024) - ) - :effect - (and - (C00033) - (increase (total-cost) 1))) - - (:action reaction_R00341left - :precondition - (and - (C00036) - ) - :effect - (and - (C00074) - (increase (total-cost) 1))) - - (:action reaction_R00658left - :precondition - (and - (C00631) - ) - :effect - (and - (C00074) - (increase (total-cost) 1))) - - (:action reaction_R00658right - :precondition - (and - (C00074) - ) - :effect - (and - (C00631) - (increase (total-cost) 1))) - - (:action reaction_R00710left - :precondition - (and - (C00084) - ) - :effect - (and - (C00033) - (increase (total-cost) 1))) - - (:action reaction_R00710right - :precondition - (and - (C00033) - ) - :effect - (and - (C00084) - (increase (total-cost) 1))) - - (:action reaction_R00754left - :precondition - (and - (C00469) - ) - :effect - (and - (C00084) - (increase (total-cost) 1))) - - (:action reaction_R00754right - :precondition - (and - (C00084) - ) - :effect - (and - (C00469) - (increase (total-cost) 1))) - - (:action reaction_R01015left - :precondition - (and - (C00118) - ) - :effect - (and - (C00111) - (increase (total-cost) 1))) - - (:action reaction_R01015right - :precondition - (and - (C00111) - ) - :effect - (and - (C00118) - (increase (total-cost) 1))) - - (:action reaction_R01061left - :precondition - (and - (C00118) - ) - :effect - (and - (C00236) - (increase (total-cost) 1))) - - (:action reaction_R01061right - :precondition - (and - (C00236) - ) - :effect - (and - (C00118) - (increase (total-cost) 1))) - - (:action reaction_R01070left - :precondition - (and - (C05378) - ) - :effect - (and - (C00111) - (C00118) - (increase (total-cost) 1))) - - (:action reaction_R01070right - :precondition - (and - (C00111) - (C00118) - ) - :effect - (and - (C05378) - (increase (total-cost) 1))) - - (:action reaction_R01512left - :precondition - (and - (C00197) - ) - :effect - (and - (C00236) - (increase (total-cost) 1))) - - (:action reaction_R01512right - :precondition - (and - (C00236) - ) - :effect - (and - (C00197) - (increase (total-cost) 1))) - - (:action reaction_R01518left - :precondition - (and - (C00631) - ) - :effect - (and - (C00197) - (increase (total-cost) 1))) - - (:action reaction_R01518right - :precondition - (and - (C00197) - ) - :effect - (and - (C00631) - (increase (total-cost) 1))) - - (:action reaction_R01600left - :precondition - (and - (C00221) - ) - :effect - (and - (C01172) - (increase (total-cost) 1))) - - (:action reaction_R01662left - :precondition - (and - (C00236) - ) - :effect - (and - (C01159) - (increase (total-cost) 1))) - - (:action reaction_R01662right - :precondition - (and - (C01159) - ) - :effect - (and - (C00236) - (increase (total-cost) 1))) - - (:action reaction_R01786left - :precondition - (and - (C00267) - ) - :effect - (and - (C00668) - (increase (total-cost) 1))) - - (:action reaction_R02569left - :precondition - (and - (C15973) - (C00024) - ) - :effect - (and - (C16255) - (increase (total-cost) 1))) - - (:action reaction_R02569right - :precondition - (and - (C16255) - ) - :effect - (and - (C15973) - (C00024) - (increase (total-cost) 1))) - - (:action reaction_R02739left - :precondition - (and - (C00668) - ) - :effect - (and - (C01172) - (increase (total-cost) 1))) - - (:action reaction_R02739right - :precondition - (and - (C01172) - ) - :effect - (and - (C00668) - (increase (total-cost) 1))) - - (:action reaction_R02740left - :precondition - (and - (C00668) - ) - :effect - (and - (C05345) - (increase (total-cost) 1))) - - (:action reaction_R02740right - :precondition - (and - (C05345) - ) - :effect - (and - (C00668) - (increase (total-cost) 1))) - - (:action reaction_R03270left - :precondition - (and - (C05125) - (C15972) - ) - :effect - (and - (C16255) - (C00068) - (increase (total-cost) 1))) - - (:action reaction_R03321left - :precondition - (and - (C01172) - ) - :effect - (and - (C05345) - (increase (total-cost) 1))) - - (:action reaction_R03321right - :precondition - (and - (C05345) - ) - :effect - (and - (C01172) - (increase (total-cost) 1))) - - (:action reaction_R04779left - :precondition - (and - (C05345) - ) - :effect - (and - (C05378) - (increase (total-cost) 1))) - - (:action reaction_R04780left - :precondition - (and - (C05378) - ) - :effect - (and - (C05345) - (increase (total-cost) 1))) - - (:action reaction_R07618left - :precondition - (and - (C15973) - ) - :effect - (and - (C15972) - (increase (total-cost) 1))) - - (:action reaction_R07618right - :precondition - (and - (C15972) - ) - :effect - (and - (C15973) - (increase (total-cost) 1))) - - (:action reaction_R00014left - :precondition - (and - (C00068) - (C00022) - ) - :effect - (and - (C05125) - (increase (total-cost) 1))) - - (:action reaction_R00268left - :precondition - (and - (C05379) - ) - :effect - (and - (C00026) - (increase (total-cost) 1))) - - (:action reaction_R00268right - :precondition - (and - (C00026) - ) - :effect - (and - (C05379) - (increase (total-cost) 1))) - - (:action reaction_R00341left - :precondition - (and - (C00036) - ) - :effect - (and - (C00074) - (increase (total-cost) 1))) - - (:action reaction_R00342left - :precondition - (and - (C00149) - ) - :effect - (and - (C00036) - (increase (total-cost) 1))) - - (:action reaction_R00342right - :precondition - (and - (C00036) - ) - :effect - (and - (C00149) - (increase (total-cost) 1))) - - (:action reaction_R00351left - :precondition - (and - (C00036) - (C00024) - ) - :effect - (and - (C00158) - (increase (total-cost) 1))) - - (:action reaction_R00351right - :precondition - (and - (C00158) - ) - :effect - (and - (C00036) - (C00024) - (increase (total-cost) 1))) - - (:action reaction_R00405left - :precondition - (and - (C00042) - ) - :effect - (and - (C00091) - (increase (total-cost) 1))) - - (:action reaction_R00405right - :precondition - (and - (C00091) - ) - :effect - (and - (C00042) - (increase (total-cost) 1))) - - (:action reaction_R00412left - :precondition - (and - (C00042) - ) - :effect - (and - (C00122) - (increase (total-cost) 1))) - - (:action reaction_R00412right - :precondition - (and - (C00122) - ) - :effect - (and - (C00042) - (increase (total-cost) 1))) - - (:action reaction_R00621left - :precondition - (and - (C00068) - (C00026) - ) - :effect - (and - (C05381) - (increase (total-cost) 1))) - - (:action reaction_R01082left - :precondition - (and - (C00149) - ) - :effect - (and - (C00122) - (increase (total-cost) 1))) - - (:action reaction_R01082right - :precondition - (and - (C00122) - ) - :effect - (and - (C00149) - (increase (total-cost) 1))) - - (:action reaction_R01325left - :precondition - (and - (C00158) - ) - :effect - (and - (C00417) - (increase (total-cost) 1))) - - (:action reaction_R01325right - :precondition - (and - (C00417) - ) - :effect - (and - (C00158) - (increase (total-cost) 1))) - - (:action reaction_R01899left - :precondition - (and - (C00311) - ) - :effect - (and - (C05379) - (increase (total-cost) 1))) - - (:action reaction_R01899right - :precondition - (and - (C05379) - ) - :effect - (and - (C00311) - (increase (total-cost) 1))) - - (:action reaction_R01900left - :precondition - (and - (C00417) - ) - :effect - (and - (C00311) - (increase (total-cost) 1))) - - (:action reaction_R01900right - :precondition - (and - (C00311) - ) - :effect - (and - (C00417) - (increase (total-cost) 1))) - - (:action reaction_R02569left - :precondition - (and - (C15973) - (C00024) - ) - :effect - (and - (C16255) - (increase (total-cost) 1))) - - (:action reaction_R02569right - :precondition - (and - (C16255) - ) - :effect - (and - (C15973) - (C00024) - (increase (total-cost) 1))) - - (:action reaction_R02570left - :precondition - (and - (C15973) - (C00091) - ) - :effect - (and - (C16254) - (increase (total-cost) 1))) - - (:action reaction_R02570right - :precondition - (and - (C16254) - ) - :effect - (and - (C15973) - (C00091) - (increase (total-cost) 1))) - - (:action reaction_R03270left - :precondition - (and - (C15972) - (C05125) - ) - :effect - (and - (C16255) - (C00068) - (increase (total-cost) 1))) - - (:action reaction_R03316left - :precondition - (and - (C15972) - (C05381) - ) - :effect - (and - (C16254) - (C00068) - (increase (total-cost) 1))) - - (:action reaction_R07618left - :precondition - (and - (C15973) - ) - :effect - (and - (C15972) - (increase (total-cost) 1))) - - (:action reaction_R07618right - :precondition - (and - (C15972) - ) - :effect - (and - (C15973) - (increase (total-cost) 1))) - - (:action reaction_R01049left - :precondition - (and - (C00117) - ) - :effect - (and - (C00119) - (increase (total-cost) 1))) - - (:action reaction_R01049right - :precondition - (and - (C00119) - ) - :effect - (and - (C00117) - (increase (total-cost) 1))) - - (:action reaction_R01056left - :precondition - (and - (C00117) - ) - :effect - (and - (C00199) - (increase (total-cost) 1))) - - (:action reaction_R01056right - :precondition - (and - (C00199) - ) - :effect - (and - (C00117) - (increase (total-cost) 1))) - - (:action reaction_R01070left - :precondition - (and - (C05378) - ) - :effect - (and - (C00118) - (increase (total-cost) 1))) - - (:action reaction_R01070right - :precondition - (and - (C00118) - ) - :effect - (and - (C05378) - (increase (total-cost) 1))) - - (:action reaction_R01529left - :precondition - (and - (C00199) - ) - :effect - (and - (C00231) - (increase (total-cost) 1))) - - (:action reaction_R01529right - :precondition - (and - (C00231) - ) - :effect - (and - (C00199) - (increase (total-cost) 1))) - - (:action reaction_R01541left - :precondition - (and - (C00204) - ) - :effect - (and - (C04442) - (increase (total-cost) 1))) - - (:action reaction_R01641left - :precondition - (and - (C05382) - (C00118) - ) - :effect - (and - (C00231) - (C00117) - (increase (total-cost) 1))) - - (:action reaction_R01641right - :precondition - (and - (C00231) - (C00117) - ) - :effect - (and - (C05382) - (C00118) - (increase (total-cost) 1))) - - (:action reaction_R01737left - :precondition - (and - (C00257) - ) - :effect - (and - (C00345) - (increase (total-cost) 1))) - - (:action reaction_R01741left - :precondition - (and - (C00257) - ) - :effect - (and - (C06473) - (increase (total-cost) 1))) - - (:action reaction_R01827left - :precondition - (and - (C05382) - (C00118) - ) - :effect - (and - (C00279) - (C05345) - (increase (total-cost) 1))) - - (:action reaction_R01827right - :precondition - (and - (C00279) - (C05345) - ) - :effect - (and - (C05382) - (C00118) - (increase (total-cost) 1))) - - (:action reaction_R01830left - :precondition - (and - (C05345) - (C00118) - ) - :effect - (and - (C00279) - (C00231) - (increase (total-cost) 1))) - - (:action reaction_R01830right - :precondition - (and - (C00279) - (C00231) - ) - :effect - (and - (C05345) - (C00118) - (increase (total-cost) 1))) - - (:action reaction_R02035left - :precondition - (and - (C01236) - ) - :effect - (and - (C00345) - (increase (total-cost) 1))) - - (:action reaction_R02035right - :precondition - (and - (C00345) - ) - :effect - (and - (C01236) - (increase (total-cost) 1))) - - (:action reaction_R02036left - :precondition - (and - (C00345) - ) - :effect - (and - (C04442) - (increase (total-cost) 1))) - - (:action reaction_R02736left - :precondition - (and - (C01172) - ) - :effect - (and - (C01236) - (increase (total-cost) 1))) - - (:action reaction_R02739left - :precondition - (and - (C00668) - ) - :effect - (and - (C01172) - (increase (total-cost) 1))) - - (:action reaction_R02739right - :precondition - (and - (C01172) - ) - :effect - (and - (C00668) - (increase (total-cost) 1))) - - (:action reaction_R02740left - :precondition - (and - (C00668) - ) - :effect - (and - (C05345) - (increase (total-cost) 1))) - - (:action reaction_R02740right - :precondition - (and - (C05345) - ) - :effect - (and - (C00668) - (increase (total-cost) 1))) - - (:action reaction_R04779left - :precondition - (and - (C05345) - ) - :effect - (and - (C05378) - (increase (total-cost) 1))) - - (:action reaction_R04780left - :precondition - (and - (C05378) - ) - :effect - (and - (C05345) - (increase (total-cost) 1))) - - (:action reaction_R05605left - :precondition - (and - (C04442) - ) - :effect - (and - (C00022) - (C00118) - (increase (total-cost) 1))) - - (:action reaction_R05605right - :precondition - (and - (C00022) - (C00118) - ) - :effect - (and - (C04442) - (increase (total-cost) 1))) - - (:action reaction_R06836left - :precondition - (and - (C01151) - ) - :effect - (and - (C00119) - (increase (total-cost) 1))) - - (:action reaction_R00286left - :precondition - (and - (C00029) - ) - :effect - (and - (C00167) - (increase (total-cost) 1))) - - (:action reaction_R00286right - :precondition - (and - (C00167) - ) - :effect - (and - (C00029) - (increase (total-cost) 1))) - - (:action reaction_R00289left - :precondition - (and - (C00103) - ) - :effect - (and - (C00029) - (increase (total-cost) 1))) - - (:action reaction_R01529left - :precondition - (and - (C00199) - ) - :effect - (and - (C00231) - (increase (total-cost) 1))) - - (:action reaction_R01529right - :precondition - (and - (C00231) - ) - :effect - (and - (C00199) - (increase (total-cost) 1))) - - (:action reaction_R01541left - :precondition - (and - (C00204) - ) - :effect - (and - (C04442) - (increase (total-cost) 1))) - - (:action reaction_R01541right - :precondition - (and - (C04442) - ) - :effect - (and - (C00204) - (increase (total-cost) 1))) - - (:action reaction_R01639left - :precondition - (and - (C00310) - ) - :effect - (and - (C00231) - (increase (total-cost) 1))) - - (:action reaction_R01639right - :precondition - (and - (C00231) - ) - :effect - (and - (C00310) - (increase (total-cost) 1))) - - (:action reaction_R02454left - :precondition - (and - (C00514) - ) - :effect - (and - (C00905) - (increase (total-cost) 1))) - - (:action reaction_R02454right - :precondition - (and - (C00905) - ) - :effect - (and - (C00514) - (increase (total-cost) 1))) - - (:action reaction_R05605left - :precondition - (and - (C04442) - ) - :effect - (and - (C00118) - (increase (total-cost) 1))) - - (:action reaction_R05605right - :precondition - (and - (C00118) - ) - :effect - (and - (C04442) - (increase (total-cost) 1))) - - (:action reaction_R00867left - :precondition - (and - (C00095) - ) - :effect - (and - (C05345) - (increase (total-cost) 1))) - - (:action reaction_R01015left - :precondition - (and - (C00118) - ) - :effect - (and - (C00111) - (increase (total-cost) 1))) - - (:action reaction_R01015right - :precondition - (and - (C00111) - ) - :effect - (and - (C00118) - (increase (total-cost) 1))) - - (:action reaction_R01070left - :precondition - (and - (C05378) - ) - :effect - (and - (C00118) - (increase (total-cost) 1))) - - (:action reaction_R01070right - :precondition - (and - (C00118) - ) - :effect - (and - (C05378) - (increase (total-cost) 1))) - - (:action reaction_R02071left - :precondition - (and - (C01094) - ) - :effect - (and - (C05378) - (increase (total-cost) 1))) - - (:action reaction_R02071right - :precondition - (and - (C05378) - ) - :effect - (and - (C01094) - (increase (total-cost) 1))) - - (:action reaction_R02568left - :precondition - (and - (C01094) - ) - :effect - (and - (C00577) - (C00111) - (increase (total-cost) 1))) - - (:action reaction_R02568right - :precondition - (and - (C00577) - (C00111) - ) - :effect - (and - (C01094) - (increase (total-cost) 1))) - - (:action reaction_R02630left - :precondition - (and - (C00159) - ) - :effect - (and - (C00275) - (increase (total-cost) 1))) - - (:action reaction_R02704left - :precondition - (and - (C00392) - ) - :effect - (and - (C00644) - (increase (total-cost) 1))) - - (:action reaction_R03232left - :precondition - (and - (C00095) - ) - :effect - (and - (C01094) - (increase (total-cost) 1))) - - (:action reaction_R03774left - :precondition - (and - (C01934) - ) - :effect - (and - (C03979) - (increase (total-cost) 1))) - - (:action reaction_R03774right - :precondition - (and - (C03979) - ) - :effect - (and - (C01934) - (increase (total-cost) 1))) - - (:action reaction_R04076left - :precondition - (and - (C00247) - ) - :effect - (and - (C02888) - (increase (total-cost) 1))) - - (:action reaction_R04779left - :precondition - (and - (C05345) - ) - :effect - (and - (C05378) - (increase (total-cost) 1))) - - (:action reaction_R04780left - :precondition - (and - (C05378) - ) - :effect - (and - (C05345) - (increase (total-cost) 1))) - - (:action reaction_R05820left - :precondition - (and - (C00794) - ) - :effect - (and - (C01096) - (increase (total-cost) 1))) - - (:action reaction_R00289left - :precondition - (and - (C00103) - ) - :effect - (and - (C00029) - (increase (total-cost) 1))) - - (:action reaction_R00289right - :precondition - (and - (C00029) - ) - :effect - (and - (C00103) - (increase (total-cost) 1))) - - (:action reaction_R00291left - :precondition - (and - (C00029) - ) - :effect - (and - (C00052) - (increase (total-cost) 1))) - - (:action reaction_R00291right - :precondition - (and - (C00052) - ) - :effect - (and - (C00029) - (increase (total-cost) 1))) - - (:action reaction_R01064left - :precondition - (and - (C01286) - ) - :effect - (and - (C00118) - (increase (total-cost) 1))) - - (:action reaction_R01101left - :precondition - (and - (C05402) - ) - :effect - (and - (C00124) - (C00031) - (increase (total-cost) 1))) - - (:action reaction_R01103left - :precondition - (and - (C00492) - ) - :effect - (and - (C00089) - (increase (total-cost) 1))) - - (:action reaction_R01104left - :precondition - (and - (C05401) - ) - :effect - (and - (C00124) - (C00116) - (increase (total-cost) 1))) - - (:action reaction_R01104right - :precondition - (and - (C00124) - (C00116) - ) - :effect - (and - (C05401) - (increase (total-cost) 1))) - - (:action reaction_R01194left - :precondition - (and - (C01235) - ) - :effect - (and - (C00137) - (C00124) - (increase (total-cost) 1))) - - (:action reaction_R01194right - :precondition - (and - (C00137) - (C00124) - ) - :effect - (and - (C01235) - (increase (total-cost) 1))) - - (:action reaction_R01329left - :precondition - (and - (C05400) - ) - :effect - (and - (C00159) - (C00124) - (increase (total-cost) 1))) - - (:action reaction_R01329right - :precondition - (and - (C00159) - (C00124) - ) - :effect - (and - (C05400) - (increase (total-cost) 1))) - - (:action reaction_R01786left - :precondition - (and - (C00267) - ) - :effect - (and - (C00668) - (increase (total-cost) 1))) - - (:action reaction_R01786right - :precondition - (and - (C00668) - ) - :effect - (and - (C00267) - (increase (total-cost) 1))) - - (:action reaction_R02410left - :precondition - (and - (C00492) - ) - :effect - (and - (C05402) - (increase (total-cost) 1))) - - (:action reaction_R02926left - :precondition - (and - (C05399) - ) - :effect - (and - (C00794) - (C00124) - (increase (total-cost) 1))) - - (:action reaction_R02926right - :precondition - (and - (C00794) - (C00124) - ) - :effect - (and - (C05399) - (increase (total-cost) 1))) - - (:action reaction_R03033left - :precondition - (and - (C00880) - ) - :effect - (and - (C01216) - (increase (total-cost) 1))) - - (:action reaction_R03236left - :precondition - (and - (C01097) - ) - :effect - (and - (C03785) - (increase (total-cost) 1))) - - (:action reaction_R03236right - :precondition - (and - (C03785) - ) - :effect - (and - (C01097) - (increase (total-cost) 1))) - - (:action reaction_R03237left - :precondition - (and - (C01097) - ) - :effect - (and - (C03785) - (increase (total-cost) 1))) - - (:action reaction_R03237right - :precondition - (and - (C03785) - ) - :effect - (and - (C01097) - (increase (total-cost) 1))) - - (:action reaction_R03238left - :precondition - (and - (C01097) - ) - :effect - (and - (C03785) - (increase (total-cost) 1))) - - (:action reaction_R03238right - :precondition - (and - (C03785) - ) - :effect - (and - (C01097) - (increase (total-cost) 1))) - - (:action reaction_R03239left - :precondition - (and - (C01097) - ) - :effect - (and - (C03785) - (increase (total-cost) 1))) - - (:action reaction_R03239right - :precondition - (and - (C03785) - ) - :effect - (and - (C01097) - (increase (total-cost) 1))) - - (:action reaction_R03387left - :precondition - (and - (C01216) - ) - :effect - (and - (C01286) - (increase (total-cost) 1))) - - (:action reaction_R03634left - :precondition - (and - (C01613) - ) - :effect - (and - (C00124) - (C00492) - (increase (total-cost) 1))) - - (:action reaction_R03635left - :precondition - (and - (C01613) - ) - :effect - (and - (C05404) - (increase (total-cost) 1))) - - (:action reaction_R05549left - :precondition - (and - (C05404) - ) - :effect - (and - (C00124) - (C05402) - (increase (total-cost) 1))) - - (:action reaction_R00286left - :precondition - (and - (C00029) - ) - :effect - (and - (C00167) - (increase (total-cost) 1))) - - (:action reaction_R02279left - :precondition - (and - (C00679) - ) - :effect - (and - (C00433) - (increase (total-cost) 1))) - - (:action reaction_R02279right - :precondition - (and - (C00433) - ) - :effect - (and - (C00679) - (increase (total-cost) 1))) - - (:action reaction_R02957left - :precondition - (and - (C02670) - ) - :effect - (and - (C00818) - (increase (total-cost) 1))) - - (:action reaction_R02957right - :precondition - (and - (C00818) - ) - :effect - (and - (C02670) - (increase (total-cost) 1))) - - (:action reaction_R05608left - :precondition - (and - (C00879) - ) - :effect - (and - (C00679) - (increase (total-cost) 1))) - - (:action reaction_R05608right - :precondition - (and - (C00679) - ) - :effect - (and - (C00879) - (increase (total-cost) 1))) - - (:action reaction_R07675left - :precondition - (and - (C01825) - ) - :effect - (and - (C01115) - (increase (total-cost) 1))) - - (:action reaction_R01626left - :precondition - (and - (C00083) - ) - :effect - (and - (C01209) - (increase (total-cost) 1))) - - (:action reaction_R01626right - :precondition - (and - (C01209) - ) - :effect - (and - (C00083) - (increase (total-cost) 1))) - - (:action reaction_R04355left - :precondition - (and - (C01209) - (C03939) - ) - :effect - (and - (C05744) - (increase (total-cost) 1))) - - (:action reaction_R04385left - :precondition - (and - (C06250) - ) - :effect - (and - (C04419) - (increase (total-cost) 1))) - - (:action reaction_R04386left - :precondition - (and - (C04419) - (C00024) - ) - :effect - (and - (C06250) - (C00083) - (increase (total-cost) 1))) - - (:action reaction_R04386right - :precondition - (and - (C06250) - (C00083) - ) - :effect - (and - (C04419) - (C00024) - (increase (total-cost) 1))) - - (:action reaction_R04429left - :precondition - (and - (C04246) - ) - :effect - (and - (C05745) - (increase (total-cost) 1))) - - (:action reaction_R04429right - :precondition - (and - (C05745) - ) - :effect - (and - (C04246) - (increase (total-cost) 1))) - - (:action reaction_R04533left - :precondition - (and - (C04618) - ) - :effect - (and - (C05744) - (increase (total-cost) 1))) - - (:action reaction_R04533right - :precondition - (and - (C05744) - ) - :effect - (and - (C04618) - (increase (total-cost) 1))) - - (:action reaction_R04534left - :precondition - (and - (C05753) - ) - :effect - (and - (C04619) - (increase (total-cost) 1))) - - (:action reaction_R04534right - :precondition - (and - (C04619) - ) - :effect - (and - (C05753) - (increase (total-cost) 1))) - - (:action reaction_R04535left - :precondition - (and - (C04619) - ) - :effect - (and - (C05754) - (increase (total-cost) 1))) - - (:action reaction_R04535right - :precondition - (and - (C05754) - ) - :effect - (and - (C04619) - (increase (total-cost) 1))) - - (:action reaction_R04536left - :precondition - (and - (C05750) - ) - :effect - (and - (C04620) - (increase (total-cost) 1))) - - (:action reaction_R04536right - :precondition - (and - (C04620) - ) - :effect - (and - (C05750) - (increase (total-cost) 1))) - - (:action reaction_R04543left - :precondition - (and - (C05762) - ) - :effect - (and - (C04633) - (increase (total-cost) 1))) - - (:action reaction_R04543right - :precondition - (and - (C04633) - ) - :effect - (and - (C05762) - (increase (total-cost) 1))) - - (:action reaction_R04566left - :precondition - (and - (C05759) - ) - :effect - (and - (C04688) - (increase (total-cost) 1))) - - (:action reaction_R04566right - :precondition - (and - (C04688) - ) - :effect - (and - (C05759) - (increase (total-cost) 1))) - - (:action reaction_R04724left - :precondition - (and - (C05758) - ) - :effect - (and - (C05223) - (increase (total-cost) 1))) - - (:action reaction_R04724right - :precondition - (and - (C05223) - ) - :effect - (and - (C05758) - (increase (total-cost) 1))) - - (:action reaction_R04726left - :precondition - (and - (C01209) - (C05223) - ) - :effect - (and - (C05759) - (increase (total-cost) 1))) - - (:action reaction_R04952left - :precondition - (and - (C01209) - (C05745) - ) - :effect - (and - (C05746) - (increase (total-cost) 1))) - - (:action reaction_R04953left - :precondition - (and - (C05746) - ) - :effect - (and - (C05747) - (increase (total-cost) 1))) - - (:action reaction_R04953right - :precondition - (and - (C05747) - ) - :effect - (and - (C05746) - (increase (total-cost) 1))) - - (:action reaction_R04955left - :precondition - (and - (C05748) - ) - :effect - (and - (C05749) - (increase (total-cost) 1))) - - (:action reaction_R04955right - :precondition - (and - (C05749) - ) - :effect - (and - (C05748) - (increase (total-cost) 1))) - - (:action reaction_R04957left - :precondition - (and - (C01209) - (C05749) - ) - :effect - (and - (C05750) - (increase (total-cost) 1))) - - (:action reaction_R04958left - :precondition - (and - (C05751) - ) - :effect - (and - (C05752) - (increase (total-cost) 1))) - - (:action reaction_R04958right - :precondition - (and - (C05752) - ) - :effect - (and - (C05751) - (increase (total-cost) 1))) - - (:action reaction_R04960left - :precondition - (and - (C01209) - (C05752) - ) - :effect - (and - (C05753) - (increase (total-cost) 1))) - - (:action reaction_R04961left - :precondition - (and - (C05754) - ) - :effect - (and - (C05755) - (increase (total-cost) 1))) - - (:action reaction_R04961right - :precondition - (and - (C05755) - ) - :effect - (and - (C05754) - (increase (total-cost) 1))) - - (:action reaction_R04963left - :precondition - (and - (C01209) - (C05755) - ) - :effect - (and - (C05756) - (increase (total-cost) 1))) - - (:action reaction_R04964left - :precondition - (and - (C05756) - ) - :effect - (and - (C05757) - (increase (total-cost) 1))) - - (:action reaction_R04964right - :precondition - (and - (C05757) - ) - :effect - (and - (C05756) - (increase (total-cost) 1))) - - (:action reaction_R04965left - :precondition - (and - (C05757) - ) - :effect - (and - (C05758) - (increase (total-cost) 1))) - - (:action reaction_R04965right - :precondition - (and - (C05758) - ) - :effect - (and - (C05757) - (increase (total-cost) 1))) - - (:action reaction_R04966left - :precondition - (and - (C05760) - ) - :effect - (and - (C05761) - (increase (total-cost) 1))) - - (:action reaction_R04966right - :precondition - (and - (C05761) - ) - :effect - (and - (C05760) - (increase (total-cost) 1))) - - (:action reaction_R04968left - :precondition - (and - (C01209) - (C05761) - ) - :effect - (and - (C05762) - (increase (total-cost) 1))) - - (:action reaction_R04969left - :precondition - (and - (C05763) - ) - :effect - (and - (C05764) - (increase (total-cost) 1))) - - (:action reaction_R04969right - :precondition - (and - (C05764) - ) - :effect - (and - (C05763) - (increase (total-cost) 1))) - - (:action reaction_R07762left - :precondition - (and - (C01209) - (C05764) - ) - :effect - (and - (C16219) - (increase (total-cost) 1))) - - (:action reaction_R07762right - :precondition - (and - (C16219) - ) - :effect - (and - (C01209) - (C05764) - (increase (total-cost) 1))) - - (:action reaction_R07763left - :precondition - (and - (C16219) - ) - :effect - (and - (C16220) - (increase (total-cost) 1))) - - (:action reaction_R07763right - :precondition - (and - (C16220) - ) - :effect - (and - (C16219) - (increase (total-cost) 1))) - - (:action reaction_R07764left - :precondition - (and - (C16220) - ) - :effect - (and - (C16221) - (increase (total-cost) 1))) - - (:action reaction_R07764right - :precondition - (and - (C16221) - ) - :effect - (and - (C16220) - (increase (total-cost) 1))) - - (:action reaction_R04170left - :precondition - (and - (C05262) - ) - :effect - (and - (C03221) - (increase (total-cost) 1))) - - (:action reaction_R04170right - :precondition - (and - (C03221) - ) - :effect - (and - (C05262) - (increase (total-cost) 1))) - - (:action reaction_R04737left - :precondition - (and - (C05259) - ) - :effect - (and - (C05258) - (increase (total-cost) 1))) - - (:action reaction_R04737right - :precondition - (and - (C05258) - ) - :effect - (and - (C05259) - (increase (total-cost) 1))) - - (:action reaction_R04738left - :precondition - (and - (C05258) - ) - :effect - (and - (C05272) - (increase (total-cost) 1))) - - (:action reaction_R04738right - :precondition - (and - (C05272) - ) - :effect - (and - (C05258) - (increase (total-cost) 1))) - - (:action reaction_R04739left - :precondition - (and - (C05261) - ) - :effect - (and - (C05260) - (increase (total-cost) 1))) - - (:action reaction_R04739right - :precondition - (and - (C05260) - ) - :effect - (and - (C05261) - (increase (total-cost) 1))) - - (:action reaction_R04740left - :precondition - (and - (C05260) - ) - :effect - (and - (C05273) - (increase (total-cost) 1))) - - (:action reaction_R04740right - :precondition - (and - (C05273) - ) - :effect - (and - (C05260) - (increase (total-cost) 1))) - - (:action reaction_R04741left - :precondition - (and - (C05263) - ) - :effect - (and - (C05262) - (increase (total-cost) 1))) - - (:action reaction_R04741right - :precondition - (and - (C05262) - ) - :effect - (and - (C05263) - (increase (total-cost) 1))) - - (:action reaction_R04743left - :precondition - (and - (C05265) - ) - :effect - (and - (C05264) - (increase (total-cost) 1))) - - (:action reaction_R04743right - :precondition - (and - (C05264) - ) - :effect - (and - (C05265) - (increase (total-cost) 1))) - - (:action reaction_R04744left - :precondition - (and - (C05264) - ) - :effect - (and - (C05275) - (increase (total-cost) 1))) - - (:action reaction_R04744right - :precondition - (and - (C05275) - ) - :effect - (and - (C05264) - (increase (total-cost) 1))) - - (:action reaction_R04745left - :precondition - (and - (C05267) - ) - :effect - (and - (C05266) - (increase (total-cost) 1))) - - (:action reaction_R04745right - :precondition - (and - (C05266) - ) - :effect - (and - (C05267) - (increase (total-cost) 1))) - - (:action reaction_R04746left - :precondition - (and - (C05266) - ) - :effect - (and - (C05276) - (increase (total-cost) 1))) - - (:action reaction_R04746right - :precondition - (and - (C05276) - ) - :effect - (and - (C05266) - (increase (total-cost) 1))) - - (:action reaction_R04748left - :precondition - (and - (C05269) - ) - :effect - (and - (C05268) - (increase (total-cost) 1))) - - (:action reaction_R04748right - :precondition - (and - (C05268) - ) - :effect - (and - (C05269) - (increase (total-cost) 1))) - - (:action reaction_R04749left - :precondition - (and - (C05268) - ) - :effect - (and - (C05271) - (increase (total-cost) 1))) - - (:action reaction_R04749right - :precondition - (and - (C05271) - ) - :effect - (and - (C05268) - (increase (total-cost) 1))) - - (:action reaction_R00238left - :precondition - (and - (C00024) - ) - :effect - (and - (C00332) - (increase (total-cost) 1))) - - (:action reaction_R00238right - :precondition - (and - (C00332) - ) - :effect - (and - (C00024) - (increase (total-cost) 1))) - - (:action reaction_R00623left - :precondition - (and - (C00226) - ) - :effect - (and - (C00071) - (increase (total-cost) 1))) - - (:action reaction_R00623right - :precondition - (and - (C00071) - ) - :effect - (and - (C00226) - (increase (total-cost) 1))) - - (:action reaction_R00631left - :precondition - (and - (C00162) - ) - :effect - (and - (C00071) - (increase (total-cost) 1))) - - (:action reaction_R01175left - :precondition - (and - (C00136) - ) - :effect - (and - (C00877) - (increase (total-cost) 1))) - - (:action reaction_R01177left - :precondition - (and - (C00136) - (C00024) - ) - :effect - (and - (C05269) - (C00010) - (increase (total-cost) 1))) - - (:action reaction_R01177right - :precondition - (and - (C05269) - (C00010) - ) - :effect - (and - (C00136) - (C00024) - (increase (total-cost) 1))) - - (:action reaction_R01279left - :precondition - (and - (C00154) - ) - :effect - (and - (C05272) - (increase (total-cost) 1))) - - (:action reaction_R01406left - :precondition - (and - (C00638) - (C00229) - ) - :effect - (and - (C00173) - (increase (total-cost) 1))) - - (:action reaction_R01406right - :precondition - (and - (C00173) - ) - :effect - (and - (C00638) - (C00229) - (increase (total-cost) 1))) - - (:action reaction_R01975left - :precondition - (and - (C01144) - ) - :effect - (and - (C00332) - (increase (total-cost) 1))) - - (:action reaction_R01975right - :precondition - (and - (C00332) - ) - :effect - (and - (C01144) - (increase (total-cost) 1))) - - (:action reaction_R02487left - :precondition - (and - (C00527) - ) - :effect - (and - (C00877) - (increase (total-cost) 1))) - - (:action reaction_R03026left - :precondition - (and - (C01144) - ) - :effect - (and - (C00877) - (increase (total-cost) 1))) - - (:action reaction_R03026right - :precondition - (and - (C00877) - ) - :effect - (and - (C01144) - (increase (total-cost) 1))) - - (:action reaction_R03276left - :precondition - (and - (C01144) - ) - :effect - (and - (C03561) - (increase (total-cost) 1))) - - (:action reaction_R03276right - :precondition - (and - (C03561) - ) - :effect - (and - (C01144) - (increase (total-cost) 1))) - - (:action reaction_R03777left - :precondition - (and - (C01944) - ) - :effect - (and - (C05276) - (increase (total-cost) 1))) - - (:action reaction_R03778left - :precondition - (and - (C00024) - (C01944) - ) - :effect - (and - (C05265) - (C00010) - (increase (total-cost) 1))) - - (:action reaction_R03778right - :precondition - (and - (C05265) - (C00010) - ) - :effect - (and - (C00024) - (C01944) - (increase (total-cost) 1))) - - (:action reaction_R03857left - :precondition - (and - (C01832) - ) - :effect - (and - (C03221) - (increase (total-cost) 1))) - - (:action reaction_R03858left - :precondition - (and - (C01832) - (C00024) - ) - :effect - (and - (C00010) - (C05261) - (increase (total-cost) 1))) - - (:action reaction_R03858right - :precondition - (and - (C00010) - (C05261) - ) - :effect - (and - (C01832) - (C00024) - (increase (total-cost) 1))) - - (:action reaction_R03990left - :precondition - (and - (C02593) - ) - :effect - (and - (C05273) - (increase (total-cost) 1))) - - (:action reaction_R03991left - :precondition - (and - (C02593) - (C00024) - ) - :effect - (and - (C05259) - (C00010) - (increase (total-cost) 1))) - - (:action reaction_R03991right - :precondition - (and - (C05259) - (C00010) - ) - :effect - (and - (C02593) - (C00024) - (increase (total-cost) 1))) - - (:action reaction_R04170left - :precondition - (and - (C05262) - ) - :effect - (and - (C03221) - (increase (total-cost) 1))) - - (:action reaction_R04170right - :precondition - (and - (C03221) - ) - :effect - (and - (C05262) - (increase (total-cost) 1))) - - (:action reaction_R04737left - :precondition - (and - (C05258) - ) - :effect - (and - (C05259) - (increase (total-cost) 1))) - - (:action reaction_R04737right - :precondition - (and - (C05259) - ) - :effect - (and - (C05258) - (increase (total-cost) 1))) - - (:action reaction_R04738left - :precondition - (and - (C05258) - ) - :effect - (and - (C05272) - (increase (total-cost) 1))) - - (:action reaction_R04738right - :precondition - (and - (C05272) - ) - :effect - (and - (C05258) - (increase (total-cost) 1))) - - (:action reaction_R04739left - :precondition - (and - (C05260) - ) - :effect - (and - (C05261) - (increase (total-cost) 1))) - - (:action reaction_R04739right - :precondition - (and - (C05261) - ) - :effect - (and - (C05260) - (increase (total-cost) 1))) - - (:action reaction_R04740left - :precondition - (and - (C05260) - ) - :effect - (and - (C05273) - (increase (total-cost) 1))) - - (:action reaction_R04740right - :precondition - (and - (C05273) - ) - :effect - (and - (C05260) - (increase (total-cost) 1))) - - (:action reaction_R04741left - :precondition - (and - (C05262) - ) - :effect - (and - (C05263) - (increase (total-cost) 1))) - - (:action reaction_R04741right - :precondition - (and - (C05263) - ) - :effect - (and - (C05262) - (increase (total-cost) 1))) - - (:action reaction_R04742left - :precondition - (and - (C00024) - (C05274) - ) - :effect - (and - (C00010) - (C05263) - (increase (total-cost) 1))) - - (:action reaction_R04742right - :precondition - (and - (C00010) - (C05263) - ) - :effect - (and - (C00024) - (C05274) - (increase (total-cost) 1))) - - (:action reaction_R04743left - :precondition - (and - (C05264) - ) - :effect - (and - (C05265) - (increase (total-cost) 1))) - - (:action reaction_R04743right - :precondition - (and - (C05265) - ) - :effect - (and - (C05264) - (increase (total-cost) 1))) - - (:action reaction_R04744left - :precondition - (and - (C05264) - ) - :effect - (and - (C05275) - (increase (total-cost) 1))) - - (:action reaction_R04744right - :precondition - (and - (C05275) - ) - :effect - (and - (C05264) - (increase (total-cost) 1))) - - (:action reaction_R04745left - :precondition - (and - (C05266) - ) - :effect - (and - (C05267) - (increase (total-cost) 1))) - - (:action reaction_R04745right - :precondition - (and - (C05267) - ) - :effect - (and - (C05266) - (increase (total-cost) 1))) - - (:action reaction_R04746left - :precondition - (and - (C05266) - ) - :effect - (and - (C05276) - (increase (total-cost) 1))) - - (:action reaction_R04746right - :precondition - (and - (C05276) - ) - :effect - (and - (C05266) - (increase (total-cost) 1))) - - (:action reaction_R04747left - :precondition - (and - (C05270) - (C00024) - ) - :effect - (and - (C05267) - (C00010) - (increase (total-cost) 1))) - - (:action reaction_R04747right - :precondition - (and - (C05267) - (C00010) - ) - :effect - (and - (C05270) - (C00024) - (increase (total-cost) 1))) - - (:action reaction_R04748left - :precondition - (and - (C05268) - ) - :effect - (and - (C05269) - (increase (total-cost) 1))) - - (:action reaction_R04748right - :precondition - (and - (C05269) - ) - :effect - (and - (C05268) - (increase (total-cost) 1))) - - (:action reaction_R04749left - :precondition - (and - (C05268) - ) - :effect - (and - (C05271) - (increase (total-cost) 1))) - - (:action reaction_R04749right - :precondition - (and - (C05271) - ) - :effect - (and - (C05268) - (increase (total-cost) 1))) - - (:action reaction_R04754left - :precondition - (and - (C05274) - ) - :effect - (and - (C05275) - (increase (total-cost) 1))) - - (:action reaction_R04756left - :precondition - (and - (C05280) - ) - :effect - (and - (C05279) - (increase (total-cost) 1))) - - (:action reaction_R04756right - :precondition - (and - (C05279) - ) - :effect - (and - (C05280) - (increase (total-cost) 1))) - - -) diff --git a/src/translate/regression-tests/issue49-orig-problem.pddl b/src/translate/regression-tests/issue49-orig-problem.pddl deleted file mode 100644 index 5b1004762..000000000 --- a/src/translate/regression-tests/issue49-orig-problem.pddl +++ /dev/null @@ -1,470 +0,0 @@ -(define (problem SeedSet-small) - -(:domain SeedSet) - -(:objects ) - -(:INIT - (C00186) - (C00221) - (C01451) - (C06186) - (C06187) - (C06188) - (C00121) - (C00198) - (C00257) - (C00258) - (C00620) - (C00672) - (C00673) - (C01151) - (C01218) - (C01801) - (C03752) - (C00085) - (C00181) - (C00191) - (C00259) - (C00266) - (C00309) - (C00312) - (C00333) - (C00379) - (C00470) - (C00474) - (C00476) - (C00502) - (C00508) - (C00532) - (C00558) - (C00618) - (C00714) - (C00789) - (C00800) - (C00817) - (C01068) - (C01101) - (C01508) - (C01904) - (C02266) - (C02273) - (C03033) - (C03291) - (C03826) - (C04053) - (C04349) - (C04575) - (C05385) - (C05411) - (C05412) - (C06019) - (C06118) - (C06441) - (C14899) - (C00095) - (C00096) - (C00247) - (C00325) - (C00392) - (C00424) - (C00464) - (C00507) - (C00636) - (C00665) - (C00861) - (C00937) - (C00976) - (C01019) - (C01099) - (C01131) - (C01222) - (C01355) - (C01680) - (C01721) - (C01768) - (C02431) - (C02492) - (C02977) - (C02985) - (C02991) - (C03117) - (C03267) - (C05392) - (C06159) - (C06192) - (C11516) - (C11544) - (C00243) - (C00446) - (C00795) - (C00880) - (C01113) - (C01132) - (C01613) - (C01697) - (C02262) - (C03383) - (C05396) - (C05796) - (C06311) - (C06376) - (C06377) - (C00072) - (C00545) - (C00684) - (C01040) - (C01041) - (C01114) - (C01146) - (C01620) - (C01825) - (C02280) - (C03064) - (C03289) - (C03921) - (C05406) - (C05422) - (C15923) - (C15924) - (C15925) - (C15926) - (C15930) - (C16186) - (C00249) - (C00712) - (C01203) - (C01530) - (C01571) - (C02679) - (C03939) - (C04088) - (C06423) - (C06424) - (C08362) - (C16520) - (C00154) - (C00162) - (C00340) - (C00435) - (C00489) - (C00517) - (C00527) - (C00823) - (C01371) - (C02990) - (C03547) - (C05102) - (= (total-cost) 0)) - -(:goal (AND - (C00022) - (C00024) - (C00031) - (C00033) - (C00036) - (C00068) - (C00074) - (C00084) - (C00103) - (C00111) - (C00118) - (C00186) - (C00197) - (C00221) - (C00236) - (C00267) - (C00469) - (C00631) - (C00668) - (C01159) - (C01172) - (C01451) - (C05125) - (C05345) - (C05378) - (C06186) - (C06187) - (C06188) - (C15972) - (C15973) - (C16255) - (C00026) - (C00042) - (C00091) - (C00122) - (C00149) - (C00158) - (C00311) - (C00417) - (C05379) - (C05381) - (C16254) - (C00117) - (C00119) - (C00121) - (C00198) - (C00199) - (C00204) - (C00231) - (C00257) - (C00258) - (C00279) - (C00345) - (C00577) - (C00620) - (C00672) - (C00673) - (C01151) - (C01218) - (C01236) - (C01801) - (C03752) - (C04442) - (C05382) - (C06473) - (C00029) - (C00085) - (C00167) - (C00181) - (C00191) - (C00259) - (C00266) - (C00309) - (C00310) - (C00312) - (C00333) - (C00379) - (C00470) - (C00474) - (C00476) - (C00502) - (C00508) - (C00514) - (C00532) - (C00558) - (C00618) - (C00714) - (C00789) - (C00800) - (C00817) - (C00905) - (C01068) - (C01101) - (C01508) - (C01904) - (C02266) - (C02273) - (C03033) - (C03291) - (C03826) - (C04053) - (C04349) - (C04575) - (C05385) - (C05411) - (C05412) - (C06019) - (C06118) - (C06441) - (C14899) - (C00095) - (C00096) - (C00159) - (C00247) - (C00275) - (C00325) - (C00392) - (C00424) - (C00464) - (C00507) - (C00636) - (C00644) - (C00665) - (C00794) - (C00861) - (C00937) - (C00976) - (C01019) - (C01094) - (C01096) - (C01099) - (C01131) - (C01222) - (C01355) - (C01680) - (C01721) - (C01768) - (C01934) - (C02431) - (C02492) - (C02888) - (C02977) - (C02985) - (C02991) - (C03117) - (C03267) - (C03979) - (C05392) - (C06159) - (C06192) - (C11516) - (C11544) - (C00052) - (C00089) - (C00116) - (C00124) - (C00137) - (C00243) - (C00446) - (C00492) - (C00795) - (C00880) - (C01097) - (C01113) - (C01132) - (C01216) - (C01235) - (C01286) - (C01613) - (C01697) - (C02262) - (C03383) - (C03785) - (C05396) - (C05399) - (C05400) - (C05401) - (C05402) - (C05404) - (C05796) - (C06311) - (C06376) - (C06377) - (C00072) - (C00433) - (C00545) - (C00679) - (C00684) - (C00818) - (C00879) - (C01040) - (C01041) - (C01114) - (C01115) - (C01146) - (C01620) - (C01825) - (C02280) - (C02670) - (C03064) - (C03289) - (C03921) - (C05406) - (C05422) - (C15923) - (C15924) - (C15925) - (C15926) - (C15930) - (C16186) - (C00083) - (C00229) - (C00249) - (C00712) - (C01203) - (C01209) - (C01530) - (C01571) - (C02679) - (C03939) - (C04088) - (C04246) - (C04419) - (C04618) - (C04619) - (C04620) - (C04633) - (C04688) - (C05223) - (C05744) - (C05745) - (C05746) - (C05747) - (C05748) - (C05749) - (C05750) - (C05751) - (C05752) - (C05753) - (C05754) - (C05755) - (C05756) - (C05757) - (C05758) - (C05759) - (C05760) - (C05761) - (C05762) - (C05763) - (C05764) - (C06250) - (C06423) - (C06424) - (C08362) - (C16219) - (C16220) - (C16221) - (C16520) - (C00136) - (C00154) - (C01832) - (C01944) - (C02593) - (C03221) - (C05258) - (C05259) - (C05260) - (C05261) - (C05262) - (C05263) - (C05264) - (C05265) - (C05266) - (C05267) - (C05268) - (C05269) - (C05270) - (C05271) - (C05272) - (C05273) - (C05274) - (C05275) - (C05276) - (C00010) - (C00071) - (C00162) - (C00173) - (C00226) - (C00332) - (C00340) - (C00435) - (C00489) - (C00517) - (C00527) - (C00638) - (C00823) - (C00877) - (C01144) - (C01371) - (C02990) - (C03547) - (C03561) - (C05102) - (C05279) - (C05280) -)) - -(:metric minimize (total-cost)) -) - diff --git a/src/translate/regression-tests/issue49-truegoal-domain.pddl b/src/translate/regression-tests/issue49-truegoal-domain.pddl deleted file mode 100644 index 526fc2bf7..000000000 --- a/src/translate/regression-tests/issue49-truegoal-domain.pddl +++ /dev/null @@ -1,14 +0,0 @@ -;; Small test domain for the problem of issue49. - -(define (domain issue49) - (:predicates - (A) - (B) - (C) - ) - - (:action action-a - :precondition (A) - :effect (B) - ) -) diff --git a/src/translate/regression-tests/issue49-truegoal-problem.pddl b/src/translate/regression-tests/issue49-truegoal-problem.pddl deleted file mode 100644 index 868db20b9..000000000 --- a/src/translate/regression-tests/issue49-truegoal-problem.pddl +++ /dev/null @@ -1,9 +0,0 @@ -(define (problem issue49-statically-true-goal) - (:domain issue49) - - (:objects) - - (:init (A)) - - (:goal (and (A) (B))) -) diff --git a/src/translate/regression-tests/issue58-domain.pddl b/src/translate/regression-tests/issue58-domain.pddl deleted file mode 100644 index 63f44d73d..000000000 --- a/src/translate/regression-tests/issue58-domain.pddl +++ /dev/null @@ -1,17 +0,0 @@ -(define (domain desire) -(:types robot location - object) -(:constants unknown - object - desiree - robot) -(:predicates (loc ?o - object ?val - location)) - -(:action move - :parameters (?from - location ?to - location) - :precondition (loc desiree ?from) - :effect (and (not (loc desiree ?from)) - (loc desiree ?to))) - -(:action set-loc-init - :parameters (?o - robot) - :precondition (loc ?o unknown) - :effect (not (loc ?o unknown))) -) diff --git a/src/translate/regression-tests/issue58-problem.pddl b/src/translate/regression-tests/issue58-problem.pddl deleted file mode 100644 index 2693e92a8..000000000 --- a/src/translate/regression-tests/issue58-problem.pddl +++ /dev/null @@ -1,6 +0,0 @@ -(define (problem desire-prob) -(:domain desire) -(:objects pos1 pos2 - location) -(:init (loc desiree pos1)) -(:goal (loc desiree pos2)) -) diff --git a/src/translate/regression-tests/issue7-domain.pddl b/src/translate/regression-tests/issue7-domain.pddl deleted file mode 100644 index 7a6b17a3d..000000000 --- a/src/translate/regression-tests/issue7-domain.pddl +++ /dev/null @@ -1,243 +0,0 @@ -;; See problem file for a description of what this is about. - -(define (domain GROUNDED-TRUCKS) - -(:requirements -:strips -) - -(:predicates -(at-destination_package1_l1) -(at-destination_package1_l2) -(at_package1_l1) -(at_package1_l2) -(at_truck1_l1) -(at_truck1_l2) -(delivered_package1_l1_t1) -(delivered_package1_l1_t2) -(delivered_package1_l2_t1) -(delivered_package1_l2_t2) -(free_a1_truck1) -(in_package1_truck1_a1) -(time-now_t0) -(time-now_t1) -(time-now_t2) -) - -(:action LOAD_PACKAGE1_TRUCK1_A1_L1 -:parameters () -:precondition -(and -(at_truck1_l1) -(at_package1_l1) -(free_a1_truck1) -) -:effect -(and -(in_package1_truck1_a1) -(not (free_a1_truck1)) -(not (at_package1_l1)) -) -) - -(:action LOAD_PACKAGE1_TRUCK1_A1_L2 -:parameters () -:precondition -(and -(at_truck1_l2) -(at_package1_l2) -(free_a1_truck1) -) -:effect -(and -(in_package1_truck1_a1) -(not (free_a1_truck1)) -(not (at_package1_l2)) -) -) - -(:action UNLOAD_PACKAGE1_TRUCK1_A1_L1 -:parameters () -:precondition -(and -(at_truck1_l1) -(in_package1_truck1_a1) -) -:effect -(and -(at_package1_l1) -(free_a1_truck1) -(not (in_package1_truck1_a1)) -) -) - -(:action UNLOAD_PACKAGE1_TRUCK1_A1_L2 -:parameters () -:precondition -(and -(at_truck1_l2) -(in_package1_truck1_a1) -) -:effect -(and -(at_package1_l2) -(free_a1_truck1) -(not (in_package1_truck1_a1)) -) -) - -(:action DELIVER_PACKAGE1_L1_T1_T1 -:parameters () -:precondition -(and -(time-now_t1) -(at_package1_l1) -) -:effect -(and -(delivered_package1_l1_t1) -(at-destination_package1_l1) -(not (at_package1_l1)) -) -) - -(:action DELIVER_PACKAGE1_L1_T1_T2 -:parameters () -:precondition -(and -(time-now_t1) -(at_package1_l1) -) -:effect -(and -(delivered_package1_l1_t2) -(at-destination_package1_l1) -(not (at_package1_l1)) -) -) - -(:action DELIVER_PACKAGE1_L1_T2_T2 -:parameters () -:precondition -(and -(time-now_t2) -(at_package1_l1) -) -:effect -(and -(delivered_package1_l1_t2) -(at-destination_package1_l1) -(not (at_package1_l1)) -) -) - -(:action DELIVER_PACKAGE1_L2_T1_T1 -:parameters () -:precondition -(and -(time-now_t1) -(at_package1_l2) -) -:effect -(and -(delivered_package1_l2_t1) -(at-destination_package1_l2) -(not (at_package1_l2)) -) -) - -(:action DELIVER_PACKAGE1_L2_T1_T2 -:parameters () -:precondition -(and -(time-now_t1) -(at_package1_l2) -) -:effect -(and -(delivered_package1_l2_t2) -(at-destination_package1_l2) -(not (at_package1_l2)) -) -) - -(:action DELIVER_PACKAGE1_L2_T2_T2 -:parameters () -:precondition -(and -(time-now_t2) -(at_package1_l2) -) -:effect -(and -(delivered_package1_l2_t2) -(at-destination_package1_l2) -(not (at_package1_l2)) -) -) - -(:action DRIVE_TRUCK1_L1_L2_T0_T1 -:parameters () -:precondition -(and -(time-now_t0) -(at_truck1_l1) -) -:effect -(and -(time-now_t1) -(at_truck1_l2) -(not (at_truck1_l1)) -(not (time-now_t0)) -) -) - -(:action DRIVE_TRUCK1_L1_L2_T1_T2 -:parameters () -:precondition -(and -(time-now_t1) -(at_truck1_l1) -) -:effect -(and -(time-now_t2) -(at_truck1_l2) -(not (at_truck1_l1)) -(not (time-now_t1)) -) -) - -(:action DRIVE_TRUCK1_L2_L1_T0_T1 -:parameters () -:precondition -(and -(time-now_t0) -(at_truck1_l2) -) -:effect -(and -(time-now_t1) -(at_truck1_l1) -(not (at_truck1_l2)) -(not (time-now_t0)) -) -) - -(:action DRIVE_TRUCK1_L2_L1_T1_T2 -:parameters () -:precondition -(and -(time-now_t1) -(at_truck1_l2) -) -:effect -(and -(time-now_t2) -(at_truck1_l1) -(not (at_truck1_l2)) -(not (time-now_t1)) -) -) - -) diff --git a/src/translate/regression-tests/issue7-problem.pddl b/src/translate/regression-tests/issue7-problem.pddl deleted file mode 100644 index 9dfd1b075..000000000 --- a/src/translate/regression-tests/issue7-problem.pddl +++ /dev/null @@ -1,34 +0,0 @@ -;; Problem to test issue75. If we add the implied preconditions, the -;; preprocessor cannot prune any variables; if we do, it can prune lots. -;; -;; Pruning the variables is safe and should be done: the variables -;; that are pruned are ones that are only set by effects, but not -;; mentioned in the goal or used as preconditions. (Adding the implied -;; preconditions causes them to be mentioned in the preconditions, -;; which means that relevance analysis can't detect them as useless -;; any more.) -;; -;; This is based on Trucks-Strips #1, with the following modifications: -;; -;; - Removed everything pertaining to packages 2 and 3. -;; - Removed atom (foo). -;; - Changed goal deadline from t3 to t2. -;; - Removed storage space (if that's what it is) a2. -;; - Removed everything pertaining to timesteps t3, t4, t5 and t6. -;; - Changed truck init location and package goal location to l2. -;; - Removed everything pertaining to location l3. - -(define (problem GROUNDED-TRUCK-1) -(:domain GROUNDED-TRUCKS) -(:init -(at_package1_l2) -(at_truck1_l1) -(free_a1_truck1) -(time-now_t0) -) -(:goal -(and -(delivered_package1_l1_t2) -) -) -) diff --git a/src/translate/regression-tests/issue73-domain.pddl b/src/translate/regression-tests/issue73-domain.pddl deleted file mode 100644 index fc153719b..000000000 --- a/src/translate/regression-tests/issue73-domain.pddl +++ /dev/null @@ -1,979 +0,0 @@ -(define (domain rover) - - (:predicates (at_rover0_waypoint0) (at_rover0_waypoint3) - (at_rover0_waypoint1) (at_rover0_waypoint2) - (at_soil_sample_waypoint0) (empty_rover0store) (full_rover0store) - (have_soil_analysis_rover0_waypoint0) (at_soil_sample_waypoint2) - (have_soil_analysis_rover0_waypoint2) (at_soil_sample_waypoint3) - (have_soil_analysis_rover0_waypoint3) (at_rock_sample_waypoint1) - (have_rock_analysis_rover0_waypoint1) (at_rock_sample_waypoint2) - (have_rock_analysis_rover0_waypoint2) (at_rock_sample_waypoint3) - (have_rock_analysis_rover0_waypoint3) (calibrated_camera0_rover0) - (have_image_rover0_objective0_colour) - (have_image_rover0_objective0_high_res) - (have_image_rover0_objective1_colour) - (have_image_rover0_objective1_high_res) - (communicated_soil_data_waypoint0) (communicated_soil_data_waypoint2) - (communicated_soil_data_waypoint3) (communicated_rock_data_waypoint1) - (communicated_rock_data_waypoint2) (communicated_rock_data_waypoint3) - (communicated_image_data_objective0_colour) - (communicated_image_data_objective0_high_res) - (communicated_image_data_objective1_colour) - (communicated_image_data_objective1_high_res) (ok_a0) (ok_a1) (ok_e0) - (ok_e1) (ok_e2) (ok_o0) (once_o0) (negof_once_o0) (ok_o1) (once_o1) - (negof_once_o1) (ok_o2) (once_o2) (negof_once_o2) (ok_o3) (once_o3) - (negof_once_o3) (safe_sb3) (ok_sb3) (safe_sb7) (ok_sb7) (safe_sb8) - (ok_sb8) (safe_sb11) (ok_sb11) (safe_sb12) (ok_sb12) (safe_sb13) - (ok_sb13) (safe_sb16) (ok_sb16) (safe_sb17) (ok_sb17) (safe_sb19) - (ok_sb19) (safe_sb20) (ok_sb20) (normal-mode) (a0) (a1) (e0) (e1) - (e2) (o0) (o1) (o2) (o3) (sb3) (sb7) (sb8) (sb11) (sb12) (sb13) - (sb16) (sb17) (sb19) (sb20)) - - (:functions (total-cost)) - - (:action copy_0_navigate_rover0_waypoint1_waypoint2 :parameters () - :precondition (and (at_rover0_waypoint1) (safe_sb3) (normal-mode)) - :effect (and (at_rover0_waypoint2) (once_o1) (safe_sb12) (not - (at_rover0_waypoint1)) (not (negof_once_o1)) (increase (total-cost) - 0)) ) - - (:action copy_0_navigate_rover0_waypoint3_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint3) (normal-mode)) - :effect (and (at_rover0_waypoint0) (ok_e0) (once_o0) (safe_sb11) (not (at_rover0_waypoint3)) (not (negof_once_o0)) (increase (total-cost) 0)) - ) - (:action copy_0_navigate_rover0_waypoint3_waypoint1 - :parameters () - :precondition (and (at_rover0_waypoint3) (negof_once_o1) (normal-mode)) - :effect (and (at_rover0_waypoint1) (once_o0) (not (at_rover0_waypoint3)) (not (negof_once_o0)) (increase (total-cost) 0)) - ) - (:action copy_0_sample_soil_rover0_rover0store_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint0) (at_soil_sample_waypoint0) (empty_rover0store) (negof_once_o3) (normal-mode)) - :effect (and (full_rover0store) (have_soil_analysis_rover0_waypoint0) (ok_e1) (once_o2) (safe_sb3) (safe_sb7) (safe_sb8) (safe_sb13) (safe_sb19) (not (at_soil_sample_waypoint0)) (not (empty_rover0store)) (not (ok_a0)) (not (negof_once_o2)) (increase (total-cost) 0)) - ) - (:action copy_0_sample_soil_rover0_rover0store_waypoint2 - :parameters () - :precondition (and (at_rover0_waypoint2) (empty_rover0store) (at_soil_sample_waypoint2) (negof_once_o3) (safe_sb7) (safe_sb8) (normal-mode)) - :effect (and (full_rover0store) (have_soil_analysis_rover0_waypoint2) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (not (empty_rover0store)) (not (at_soil_sample_waypoint2)) (not (negof_once_o2)) (increase (total-cost) 0)) - ) - (:action copy_0_sample_soil_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_soil_sample_waypoint3) (negof_once_o3) (normal-mode)) - :effect (and (full_rover0store) (have_soil_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (not (empty_rover0store)) (not (at_soil_sample_waypoint3)) (not (negof_once_o2)) (increase (total-cost) 0)) - ) - (:action copy_0_sample_rock_rover0_rover0store_waypoint1 - :parameters () - :precondition (and (at_rover0_waypoint1) (empty_rover0store) (at_rock_sample_waypoint1) (negof_once_o3) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint1) (ok_e2) (once_o2) (safe_sb7) (safe_sb13) (safe_sb16) (safe_sb19) (not (empty_rover0store)) (not (at_rock_sample_waypoint1)) (not (ok_a1)) (not (negof_once_o2)) (increase (total-cost) 0)) - ) - (:action copy_0_sample_rock_rover0_rover0store_waypoint2 - :parameters () - :precondition (and (at_rover0_waypoint2) (empty_rover0store) (at_rock_sample_waypoint2) (negof_once_o3) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint2) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (not (empty_rover0store)) (not (at_rock_sample_waypoint2)) (not (negof_once_o2)) (increase (total-cost) 0)) - ) - (:action copy_0_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb11) (safe_sb12) (safe_sb13) (safe_sb16) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (increase (total-cost) 0)) - ) - (:action copy_0_calibrate_rover0_camera0_objective1_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint0) (normal-mode)) - :effect (and (calibrated_camera0_rover0) (increase (total-cost) 0)) - ) - (:action copy_0_calibrate_rover0_camera0_objective1_waypoint1 - :parameters () - :precondition (and (at_rover0_waypoint1) (normal-mode)) - :effect (and (calibrated_camera0_rover0) (increase (total-cost) 0)) - ) - (:action copy_0_calibrate_rover0_camera0_objective1_waypoint2 - :parameters () - :precondition (and (at_rover0_waypoint2) (normal-mode)) - :effect (and (calibrated_camera0_rover0) (increase (total-cost) 0)) - ) - (:action copy_0_calibrate_rover0_camera0_objective1_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (normal-mode)) - :effect (and (calibrated_camera0_rover0) (increase (total-cost) 0)) - ) - (:action copy_0_take_image_rover0_waypoint0_objective0_camera0_colour - :parameters () - :precondition (and (at_rover0_waypoint0) (calibrated_camera0_rover0) (normal-mode)) - :effect (and (have_image_rover0_objective0_colour) (not (calibrated_camera0_rover0)) (increase (total-cost) 0)) - ) - (:action copy_0_take_image_rover0_waypoint0_objective0_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint0) (calibrated_camera0_rover0) (normal-mode)) - :effect (and (have_image_rover0_objective0_high_res) (not (calibrated_camera0_rover0)) (increase (total-cost) 0)) - ) - (:action copy_0_take_image_rover0_waypoint0_objective1_camera0_colour - :parameters () - :precondition (and (at_rover0_waypoint0) (calibrated_camera0_rover0) (normal-mode)) - :effect (and (have_image_rover0_objective1_colour) (not (calibrated_camera0_rover0)) (increase (total-cost) 0)) - ) - (:action copy_0_take_image_rover0_waypoint0_objective1_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint0) (calibrated_camera0_rover0) (safe_sb19) (safe_sb20) (normal-mode)) - :effect (and (have_image_rover0_objective1_high_res) (safe_sb17) (not (calibrated_camera0_rover0)) (increase (total-cost) 0)) - ) - (:action copy_0_take_image_rover0_waypoint1_objective0_camera0_colour - :parameters () - :precondition (and (at_rover0_waypoint1) (calibrated_camera0_rover0) (normal-mode)) - :effect (and (have_image_rover0_objective0_colour) (not (calibrated_camera0_rover0)) (increase (total-cost) 0)) - ) - (:action copy_0_take_image_rover0_waypoint1_objective0_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint1) (calibrated_camera0_rover0) (normal-mode)) - :effect (and (have_image_rover0_objective0_high_res) (not (calibrated_camera0_rover0)) (increase (total-cost) 0)) - ) - (:action copy_0_take_image_rover0_waypoint1_objective1_camera0_colour - :parameters () - :precondition (and (at_rover0_waypoint1) (calibrated_camera0_rover0) (normal-mode)) - :effect (and (have_image_rover0_objective1_colour) (not (calibrated_camera0_rover0)) (increase (total-cost) 0)) - ) - (:action copy_0_take_image_rover0_waypoint1_objective1_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint1) (calibrated_camera0_rover0) (safe_sb19) (safe_sb20) (normal-mode)) - :effect (and (have_image_rover0_objective1_high_res) (safe_sb17) (not (calibrated_camera0_rover0)) (increase (total-cost) 0)) - ) - (:action copy_0_take_image_rover0_waypoint2_objective0_camera0_colour - :parameters () - :precondition (and (at_rover0_waypoint2) (calibrated_camera0_rover0) (normal-mode)) - :effect (and (have_image_rover0_objective0_colour) (not (calibrated_camera0_rover0)) (increase (total-cost) 0)) - ) - (:action copy_0_take_image_rover0_waypoint2_objective0_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint2) (calibrated_camera0_rover0) (normal-mode)) - :effect (and (have_image_rover0_objective0_high_res) (not (calibrated_camera0_rover0)) (increase (total-cost) 0)) - ) - (:action copy_0_take_image_rover0_waypoint2_objective1_camera0_colour - :parameters () - :precondition (and (at_rover0_waypoint2) (calibrated_camera0_rover0) (normal-mode)) - :effect (and (have_image_rover0_objective1_colour) (not (calibrated_camera0_rover0)) (increase (total-cost) 0)) - ) - (:action copy_0_take_image_rover0_waypoint2_objective1_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint2) (calibrated_camera0_rover0) (safe_sb19) (safe_sb20) (normal-mode)) - :effect (and (have_image_rover0_objective1_high_res) (safe_sb17) (not (calibrated_camera0_rover0)) (increase (total-cost) 0)) - ) - (:action copy_0_take_image_rover0_waypoint3_objective0_camera0_colour - :parameters () - :precondition (and (at_rover0_waypoint3) (calibrated_camera0_rover0) (normal-mode)) - :effect (and (have_image_rover0_objective0_colour) (not (calibrated_camera0_rover0)) (increase (total-cost) 0)) - ) - (:action copy_0_take_image_rover0_waypoint3_objective0_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint3) (calibrated_camera0_rover0) (normal-mode)) - :effect (and (have_image_rover0_objective0_high_res) (not (calibrated_camera0_rover0)) (increase (total-cost) 0)) - ) - (:action copy_0_take_image_rover0_waypoint3_objective1_camera0_colour - :parameters () - :precondition (and (at_rover0_waypoint3) (calibrated_camera0_rover0) (normal-mode)) - :effect (and (have_image_rover0_objective1_colour) (not (calibrated_camera0_rover0)) (increase (total-cost) 0)) - ) - (:action copy_0_take_image_rover0_waypoint3_objective1_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint3) (calibrated_camera0_rover0) (safe_sb19) (safe_sb20) (normal-mode)) - :effect (and (have_image_rover0_objective1_high_res) (safe_sb17) (not (calibrated_camera0_rover0)) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_soil_data_rover0_general_waypoint0_waypoint1_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint1) (have_soil_analysis_rover0_waypoint0) (normal-mode)) - :effect (and (communicated_soil_data_waypoint0) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_soil_data_rover0_general_waypoint0_waypoint2_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint2) (have_soil_analysis_rover0_waypoint0) (normal-mode)) - :effect (and (communicated_soil_data_waypoint0) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_soil_data_rover0_general_waypoint0_waypoint3_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint3) (have_soil_analysis_rover0_waypoint0) (normal-mode)) - :effect (and (communicated_soil_data_waypoint0) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_soil_data_rover0_general_waypoint2_waypoint1_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint1) (have_soil_analysis_rover0_waypoint2) (normal-mode)) - :effect (and (communicated_soil_data_waypoint2) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_soil_data_rover0_general_waypoint2_waypoint2_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint2) (have_soil_analysis_rover0_waypoint2) (normal-mode)) - :effect (and (communicated_soil_data_waypoint2) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_soil_data_rover0_general_waypoint2_waypoint3_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint3) (have_soil_analysis_rover0_waypoint2) (normal-mode)) - :effect (and (communicated_soil_data_waypoint2) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_soil_data_rover0_general_waypoint3_waypoint1_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint1) (have_soil_analysis_rover0_waypoint3) (normal-mode)) - :effect (and (communicated_soil_data_waypoint3) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_soil_data_rover0_general_waypoint3_waypoint2_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint2) (have_soil_analysis_rover0_waypoint3) (normal-mode)) - :effect (and (communicated_soil_data_waypoint3) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_soil_data_rover0_general_waypoint3_waypoint3_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint3) (have_soil_analysis_rover0_waypoint3) (normal-mode)) - :effect (and (communicated_soil_data_waypoint3) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_rock_data_rover0_general_waypoint1_waypoint1_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint1) (have_rock_analysis_rover0_waypoint1) (normal-mode)) - :effect (and (communicated_rock_data_waypoint1) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_rock_data_rover0_general_waypoint1_waypoint2_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint2) (have_rock_analysis_rover0_waypoint1) (normal-mode)) - :effect (and (communicated_rock_data_waypoint1) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_rock_data_rover0_general_waypoint1_waypoint3_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint3) (have_rock_analysis_rover0_waypoint1) (normal-mode)) - :effect (and (communicated_rock_data_waypoint1) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_rock_data_rover0_general_waypoint2_waypoint1_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint1) (have_rock_analysis_rover0_waypoint2) (normal-mode)) - :effect (and (communicated_rock_data_waypoint2) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_rock_data_rover0_general_waypoint2_waypoint2_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint2) (have_rock_analysis_rover0_waypoint2) (normal-mode)) - :effect (and (communicated_rock_data_waypoint2) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_rock_data_rover0_general_waypoint2_waypoint3_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint3) (have_rock_analysis_rover0_waypoint2) (normal-mode)) - :effect (and (communicated_rock_data_waypoint2) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_rock_data_rover0_general_waypoint3_waypoint1_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint1) (have_rock_analysis_rover0_waypoint3) (normal-mode)) - :effect (and (communicated_rock_data_waypoint3) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_rock_data_rover0_general_waypoint3_waypoint2_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint2) (have_rock_analysis_rover0_waypoint3) (normal-mode)) - :effect (and (communicated_rock_data_waypoint3) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_rock_data_rover0_general_waypoint3_waypoint3_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint3) (have_rock_analysis_rover0_waypoint3) (normal-mode)) - :effect (and (communicated_rock_data_waypoint3) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_image_data_rover0_general_objective0_colour_waypoint1_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint1) (have_image_rover0_objective0_colour) (normal-mode)) - :effect (and (communicated_image_data_objective0_colour) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_image_data_rover0_general_objective0_colour_waypoint2_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint2) (have_image_rover0_objective0_colour) (normal-mode)) - :effect (and (communicated_image_data_objective0_colour) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_image_data_rover0_general_objective0_colour_waypoint3_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint3) (have_image_rover0_objective0_colour) (normal-mode)) - :effect (and (communicated_image_data_objective0_colour) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_image_data_rover0_general_objective0_high_res_waypoint1_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint1) (have_image_rover0_objective0_high_res) (normal-mode)) - :effect (and (communicated_image_data_objective0_high_res) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_image_data_rover0_general_objective0_high_res_waypoint2_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint2) (have_image_rover0_objective0_high_res) (normal-mode)) - :effect (and (communicated_image_data_objective0_high_res) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_image_data_rover0_general_objective0_high_res_waypoint3_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint3) (have_image_rover0_objective0_high_res) (normal-mode)) - :effect (and (communicated_image_data_objective0_high_res) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_image_data_rover0_general_objective1_colour_waypoint1_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint1) (have_image_rover0_objective1_colour) (normal-mode)) - :effect (and (communicated_image_data_objective1_colour) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_image_data_rover0_general_objective1_colour_waypoint2_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint2) (have_image_rover0_objective1_colour) (normal-mode)) - :effect (and (communicated_image_data_objective1_colour) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_image_data_rover0_general_objective1_colour_waypoint3_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint3) (have_image_rover0_objective1_colour) (normal-mode)) - :effect (and (communicated_image_data_objective1_colour) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_image_data_rover0_general_objective1_high_res_waypoint1_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint1) (have_image_rover0_objective1_high_res) (normal-mode)) - :effect (and (communicated_image_data_objective1_high_res) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_image_data_rover0_general_objective1_high_res_waypoint2_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint2) (have_image_rover0_objective1_high_res) (normal-mode)) - :effect (and (communicated_image_data_objective1_high_res) (increase (total-cost) 0)) - ) - (:action copy_0_communicate_image_data_rover0_general_objective1_high_res_waypoint3_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint3) (have_image_rover0_objective1_high_res) (normal-mode)) - :effect (and (communicated_image_data_objective1_high_res) (increase (total-cost) 0)) - ) - (:action copy_0_navigate_rover0_waypoint0_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint0) (once_o0) (normal-mode)) - :effect (and (at_rover0_waypoint3) (not (at_rover0_waypoint0)) (not (ok_o0)) (increase (total-cost) 0)) - ) - (:action copy_0_navigate_rover0_waypoint1_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint1) (once_o0) (normal-mode)) - :effect (and (at_rover0_waypoint3) (once_o1) (not (at_rover0_waypoint1)) (not (ok_o0)) (not (negof_once_o1)) (increase (total-cost) 0)) - ) - (:action copy_0_navigate_rover0_waypoint2_waypoint1 - :parameters () - :precondition (and (at_rover0_waypoint2) (once_o1) (normal-mode)) - :effect (and (at_rover0_waypoint1) (not (at_rover0_waypoint2)) (not (ok_o1)) (increase (total-cost) 0)) - ) - (:action copy_1_navigate_rover0_waypoint3_waypoint1 - :parameters () - :precondition (and (at_rover0_waypoint3) (once_o1) (normal-mode)) - :effect (and (at_rover0_waypoint1) (once_o0) (not (at_rover0_waypoint3)) (not (negof_once_o0)) (not (ok_o1)) (increase (total-cost) 0)) - ) - (:action copy_0_drop_rover0_rover0store - :parameters () - :precondition (and (full_rover0store) (once_o2) (normal-mode)) - :effect (and (empty_rover0store) (once_o3) (not (full_rover0store)) (not (ok_o2)) (not (negof_once_o3)) (increase (total-cost) 0)) - ) - (:action copy_1_sample_soil_rover0_rover0store_waypoint0 - :parameters () - :precondition (and (at_rover0_waypoint0) (at_soil_sample_waypoint0) (empty_rover0store) (once_o3) (normal-mode)) - :effect (and (full_rover0store) (have_soil_analysis_rover0_waypoint0) (ok_e1) (once_o2) (safe_sb3) (safe_sb7) (safe_sb8) (safe_sb13) (safe_sb19) (not (at_soil_sample_waypoint0)) (not (empty_rover0store)) (not (ok_a0)) (not (negof_once_o2)) (not (ok_o3)) (increase (total-cost) 0)) - ) - (:action copy_1_sample_soil_rover0_rover0store_waypoint2 - :parameters () - :precondition (and (at_rover0_waypoint2) (empty_rover0store) (at_soil_sample_waypoint2) (once_o3) (safe_sb7) (safe_sb8) (normal-mode)) - :effect (and (full_rover0store) (have_soil_analysis_rover0_waypoint2) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (not (empty_rover0store)) (not (at_soil_sample_waypoint2)) (not (negof_once_o2)) (not (ok_o3)) (increase (total-cost) 0)) - ) - (:action copy_1_sample_soil_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_soil_sample_waypoint3) (once_o3) (normal-mode)) - :effect (and (full_rover0store) (have_soil_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (not (empty_rover0store)) (not (at_soil_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (increase (total-cost) 0)) - ) - (:action copy_1_sample_rock_rover0_rover0store_waypoint1 - :parameters () - :precondition (and (at_rover0_waypoint1) (empty_rover0store) (at_rock_sample_waypoint1) (once_o3) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint1) (ok_e2) (once_o2) (safe_sb7) (safe_sb13) (safe_sb16) (safe_sb19) (not (empty_rover0store)) (not (at_rock_sample_waypoint1)) (not (ok_a1)) (not (negof_once_o2)) (not (ok_o3)) (increase (total-cost) 0)) - ) - (:action copy_1_sample_rock_rover0_rover0store_waypoint2 - :parameters () - :precondition (and (at_rover0_waypoint2) (empty_rover0store) (at_rock_sample_waypoint2) (once_o3) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint2) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (not (empty_rover0store)) (not (at_rock_sample_waypoint2)) (not (negof_once_o2)) (not (ok_o3)) (increase (total-cost) 0)) - ) - (:action copy_1_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb11) (safe_sb12) (safe_sb13) (safe_sb16) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (increase (total-cost) 0)) - ) - (:action copy_1_navigate_rover0_waypoint1_waypoint2 - :parameters () - :precondition (and (at_rover0_waypoint1) (normal-mode)) - :effect (and (at_rover0_waypoint2) (once_o1) (safe_sb12) (not (at_rover0_waypoint1)) (not (negof_once_o1)) (not (ok_sb3)) (increase (total-cost) 0)) - ) - (:action copy_2_sample_soil_rover0_rover0store_waypoint2 - :parameters () - :precondition (and (at_rover0_waypoint2) (empty_rover0store) (at_soil_sample_waypoint2) (negof_once_o3) (safe_sb8) (normal-mode)) - :effect (and (full_rover0store) (have_soil_analysis_rover0_waypoint2) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (not (empty_rover0store)) (not (at_soil_sample_waypoint2)) (not (negof_once_o2)) (not (ok_sb7)) (increase (total-cost) 0)) - ) - (:action copy_3_sample_soil_rover0_rover0store_waypoint2 - :parameters () - :precondition (and (at_rover0_waypoint2) (empty_rover0store) (at_soil_sample_waypoint2) (once_o3) (safe_sb8) (normal-mode)) - :effect (and (full_rover0store) (have_soil_analysis_rover0_waypoint2) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (not (empty_rover0store)) (not (at_soil_sample_waypoint2)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb7)) (increase (total-cost) 0)) - ) - (:action copy_4_sample_soil_rover0_rover0store_waypoint2 - :parameters () - :precondition (and (at_rover0_waypoint2) (empty_rover0store) (at_soil_sample_waypoint2) (negof_once_o3) (safe_sb7) (normal-mode)) - :effect (and (full_rover0store) (have_soil_analysis_rover0_waypoint2) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (not (empty_rover0store)) (not (at_soil_sample_waypoint2)) (not (negof_once_o2)) (not (ok_sb8)) (increase (total-cost) 0)) - ) - (:action copy_5_sample_soil_rover0_rover0store_waypoint2 - :parameters () - :precondition (and (at_rover0_waypoint2) (empty_rover0store) (at_soil_sample_waypoint2) (once_o3) (safe_sb7) (normal-mode)) - :effect (and (full_rover0store) (have_soil_analysis_rover0_waypoint2) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (not (empty_rover0store)) (not (at_soil_sample_waypoint2)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb8)) (increase (total-cost) 0)) - ) - (:action copy_6_sample_soil_rover0_rover0store_waypoint2 - :parameters () - :precondition (and (at_rover0_waypoint2) (empty_rover0store) (at_soil_sample_waypoint2) (negof_once_o3) (normal-mode)) - :effect (and (full_rover0store) (have_soil_analysis_rover0_waypoint2) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (not (empty_rover0store)) (not (at_soil_sample_waypoint2)) (not (negof_once_o2)) (not (ok_sb7)) (not (ok_sb8)) (increase (total-cost) 0)) - ) - (:action copy_7_sample_soil_rover0_rover0store_waypoint2 - :parameters () - :precondition (and (at_rover0_waypoint2) (empty_rover0store) (at_soil_sample_waypoint2) (once_o3) (normal-mode)) - :effect (and (full_rover0store) (have_soil_analysis_rover0_waypoint2) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (not (empty_rover0store)) (not (at_soil_sample_waypoint2)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb7)) (not (ok_sb8)) (increase (total-cost) 0)) - ) - (:action copy_2_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb12) (safe_sb13) (safe_sb16) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb11)) (increase (total-cost) 0)) - ) - (:action copy_3_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb12) (safe_sb13) (safe_sb16) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb11)) (increase (total-cost) 0)) - ) - (:action copy_4_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb11) (safe_sb13) (safe_sb16) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb12)) (increase (total-cost) 0)) - ) - (:action copy_5_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb11) (safe_sb13) (safe_sb16) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb12)) (increase (total-cost) 0)) - ) - (:action copy_6_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb13) (safe_sb16) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb11)) (not (ok_sb12)) (increase (total-cost) 0)) - ) - (:action copy_7_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb13) (safe_sb16) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb11)) (not (ok_sb12)) (increase (total-cost) 0)) - ) - (:action copy_8_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb11) (safe_sb12) (safe_sb16) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb13)) (increase (total-cost) 0)) - ) - (:action copy_9_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb11) (safe_sb12) (safe_sb16) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb13)) (increase (total-cost) 0)) - ) - (:action copy_10_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb12) (safe_sb16) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb11)) (not (ok_sb13)) (increase (total-cost) 0)) - ) - (:action copy_11_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb12) (safe_sb16) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb11)) (not (ok_sb13)) (increase (total-cost) 0)) - ) - (:action copy_12_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb11) (safe_sb16) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb12)) (not (ok_sb13)) (increase (total-cost) 0)) - ) - (:action copy_13_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb11) (safe_sb16) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb12)) (not (ok_sb13)) (increase (total-cost) 0)) - ) - (:action copy_14_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb16) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb11)) (not (ok_sb12)) (not (ok_sb13)) (increase (total-cost) 0)) - ) - (:action copy_15_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb16) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb11)) (not (ok_sb12)) (not (ok_sb13)) (increase (total-cost) 0)) - ) - (:action copy_16_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb11) (safe_sb12) (safe_sb13) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb16)) (increase (total-cost) 0)) - ) - (:action copy_17_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb11) (safe_sb12) (safe_sb13) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb16)) (increase (total-cost) 0)) - ) - (:action copy_18_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb12) (safe_sb13) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb11)) (not (ok_sb16)) (increase (total-cost) 0)) - ) - (:action copy_19_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb12) (safe_sb13) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb11)) (not (ok_sb16)) (increase (total-cost) 0)) - ) - (:action copy_20_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb11) (safe_sb13) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb12)) (not (ok_sb16)) (increase (total-cost) 0)) - ) - (:action copy_21_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb11) (safe_sb13) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb12)) (not (ok_sb16)) (increase (total-cost) 0)) - ) - (:action copy_22_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb13) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb11)) (not (ok_sb12)) (not (ok_sb16)) (increase (total-cost) 0)) - ) - (:action copy_23_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb13) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb11)) (not (ok_sb12)) (not (ok_sb16)) (increase (total-cost) 0)) - ) - (:action copy_24_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb11) (safe_sb12) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb13)) (not (ok_sb16)) (increase (total-cost) 0)) - ) - (:action copy_25_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb11) (safe_sb12) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb13)) (not (ok_sb16)) (increase (total-cost) 0)) - ) - (:action copy_26_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb12) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb11)) (not (ok_sb13)) (not (ok_sb16)) (increase (total-cost) 0)) - ) - (:action copy_27_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb12) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb11)) (not (ok_sb13)) (not (ok_sb16)) (increase (total-cost) 0)) - ) - (:action copy_28_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb11) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb12)) (not (ok_sb13)) (not (ok_sb16)) (increase (total-cost) 0)) - ) - (:action copy_29_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb11) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb12)) (not (ok_sb13)) (not (ok_sb16)) (increase (total-cost) 0)) - ) - (:action copy_30_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb11)) (not (ok_sb12)) (not (ok_sb13)) (not (ok_sb16)) (increase (total-cost) 0)) - ) - (:action copy_31_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb17) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb11)) (not (ok_sb12)) (not (ok_sb13)) (not (ok_sb16)) (increase (total-cost) 0)) - ) - (:action copy_32_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb11) (safe_sb12) (safe_sb13) (safe_sb16) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_33_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb11) (safe_sb12) (safe_sb13) (safe_sb16) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_34_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb12) (safe_sb13) (safe_sb16) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb11)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_35_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb12) (safe_sb13) (safe_sb16) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb11)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_36_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb11) (safe_sb13) (safe_sb16) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb12)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_37_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb11) (safe_sb13) (safe_sb16) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb12)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_38_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb13) (safe_sb16) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb11)) (not (ok_sb12)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_39_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb13) (safe_sb16) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb11)) (not (ok_sb12)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_40_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb11) (safe_sb12) (safe_sb16) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb13)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_41_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb11) (safe_sb12) (safe_sb16) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb13)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_42_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb12) (safe_sb16) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb11)) (not (ok_sb13)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_43_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb12) (safe_sb16) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb11)) (not (ok_sb13)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_44_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb11) (safe_sb16) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb12)) (not (ok_sb13)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_45_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb11) (safe_sb16) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb12)) (not (ok_sb13)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_46_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb16) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb11)) (not (ok_sb12)) (not (ok_sb13)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_47_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb16) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb11)) (not (ok_sb12)) (not (ok_sb13)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_48_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb11) (safe_sb12) (safe_sb13) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb16)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_49_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb11) (safe_sb12) (safe_sb13) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb16)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_50_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb12) (safe_sb13) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb11)) (not (ok_sb16)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_51_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb12) (safe_sb13) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb11)) (not (ok_sb16)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_52_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb11) (safe_sb13) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb12)) (not (ok_sb16)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_53_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb11) (safe_sb13) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb12)) (not (ok_sb16)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_54_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb13) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb11)) (not (ok_sb12)) (not (ok_sb16)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_55_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb13) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb11)) (not (ok_sb12)) (not (ok_sb16)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_56_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb11) (safe_sb12) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb13)) (not (ok_sb16)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_57_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb11) (safe_sb12) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb13)) (not (ok_sb16)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_58_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb12) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb11)) (not (ok_sb13)) (not (ok_sb16)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_59_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb12) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb11)) (not (ok_sb13)) (not (ok_sb16)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_60_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (safe_sb11) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb12)) (not (ok_sb13)) (not (ok_sb16)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_61_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (safe_sb11) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb12)) (not (ok_sb13)) (not (ok_sb16)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_62_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (negof_once_o3) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_sb11)) (not (ok_sb12)) (not (ok_sb13)) (not (ok_sb16)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_63_sample_rock_rover0_rover0store_waypoint3 - :parameters () - :precondition (and (at_rover0_waypoint3) (empty_rover0store) (at_rock_sample_waypoint3) (once_o3) (normal-mode)) - :effect (and (full_rover0store) (have_rock_analysis_rover0_waypoint3) (once_o2) (safe_sb7) (safe_sb13) (safe_sb19) (safe_sb20) (not (empty_rover0store)) (not (at_rock_sample_waypoint3)) (not (negof_once_o2)) (not (ok_o3)) (not (ok_sb11)) (not (ok_sb12)) (not (ok_sb13)) (not (ok_sb16)) (not (ok_sb17)) (increase (total-cost) 0)) - ) - (:action copy_1_take_image_rover0_waypoint0_objective1_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint0) (calibrated_camera0_rover0) (safe_sb20) (normal-mode)) - :effect (and (have_image_rover0_objective1_high_res) (safe_sb17) (not (calibrated_camera0_rover0)) (not (ok_sb19)) (increase (total-cost) 0)) - ) - (:action copy_1_take_image_rover0_waypoint1_objective1_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint1) (calibrated_camera0_rover0) (safe_sb20) (normal-mode)) - :effect (and (have_image_rover0_objective1_high_res) (safe_sb17) (not (calibrated_camera0_rover0)) (not (ok_sb19)) (increase (total-cost) 0)) - ) - (:action copy_1_take_image_rover0_waypoint2_objective1_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint2) (calibrated_camera0_rover0) (safe_sb20) (normal-mode)) - :effect (and (have_image_rover0_objective1_high_res) (safe_sb17) (not (calibrated_camera0_rover0)) (not (ok_sb19)) (increase (total-cost) 0)) - ) - (:action copy_1_take_image_rover0_waypoint3_objective1_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint3) (calibrated_camera0_rover0) (safe_sb20) (normal-mode)) - :effect (and (have_image_rover0_objective1_high_res) (safe_sb17) (not (calibrated_camera0_rover0)) (not (ok_sb19)) (increase (total-cost) 0)) - ) - (:action copy_2_take_image_rover0_waypoint0_objective1_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint0) (calibrated_camera0_rover0) (safe_sb19) (normal-mode)) - :effect (and (have_image_rover0_objective1_high_res) (safe_sb17) (not (calibrated_camera0_rover0)) (not (ok_sb20)) (increase (total-cost) 0)) - ) - (:action copy_2_take_image_rover0_waypoint1_objective1_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint1) (calibrated_camera0_rover0) (safe_sb19) (normal-mode)) - :effect (and (have_image_rover0_objective1_high_res) (safe_sb17) (not (calibrated_camera0_rover0)) (not (ok_sb20)) (increase (total-cost) 0)) - ) - (:action copy_2_take_image_rover0_waypoint2_objective1_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint2) (calibrated_camera0_rover0) (safe_sb19) (normal-mode)) - :effect (and (have_image_rover0_objective1_high_res) (safe_sb17) (not (calibrated_camera0_rover0)) (not (ok_sb20)) (increase (total-cost) 0)) - ) - (:action copy_2_take_image_rover0_waypoint3_objective1_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint3) (calibrated_camera0_rover0) (safe_sb19) (normal-mode)) - :effect (and (have_image_rover0_objective1_high_res) (safe_sb17) (not (calibrated_camera0_rover0)) (not (ok_sb20)) (increase (total-cost) 0)) - ) - (:action copy_3_take_image_rover0_waypoint0_objective1_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint0) (calibrated_camera0_rover0) (normal-mode)) - :effect (and (have_image_rover0_objective1_high_res) (safe_sb17) (not (calibrated_camera0_rover0)) (not (ok_sb19)) (not (ok_sb20)) (increase (total-cost) 0)) - ) - (:action copy_3_take_image_rover0_waypoint1_objective1_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint1) (calibrated_camera0_rover0) (normal-mode)) - :effect (and (have_image_rover0_objective1_high_res) (safe_sb17) (not (calibrated_camera0_rover0)) (not (ok_sb19)) (not (ok_sb20)) (increase (total-cost) 0)) - ) - (:action copy_3_take_image_rover0_waypoint2_objective1_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint2) (calibrated_camera0_rover0) (normal-mode)) - :effect (and (have_image_rover0_objective1_high_res) (safe_sb17) (not (calibrated_camera0_rover0)) (not (ok_sb19)) (not (ok_sb20)) (increase (total-cost) 0)) - ) - (:action copy_3_take_image_rover0_waypoint3_objective1_camera0_high_res - :parameters () - :precondition (and (at_rover0_waypoint3) (calibrated_camera0_rover0) (normal-mode)) - :effect (and (have_image_rover0_objective1_high_res) (safe_sb17) (not (calibrated_camera0_rover0)) (not (ok_sb19)) (not (ok_sb20)) (increase (total-cost) 0)) - ) - (:action copy_0_sat_a0 - :parameters () - :precondition (and (ok_a0)) - :effect (and (a0) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_a0 - :parameters () - :precondition (and) :effect (and (a0) (not (normal-mode)) (increase (total-cost) 16.53)) - ) - (:action copy_0_sat_a1 - :parameters () - :precondition (and (ok_a1) (a0)) - :effect (and (a1) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_a1 - :parameters () - :precondition (and (a0)) - :effect (and (a1) (not (normal-mode)) (increase (total-cost) 8.208)) - ) - (:action copy_0_sat_e0 - :parameters () - :precondition (and (ok_e0) (a1)) - :effect (and (e0) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_e0 - :parameters () - :precondition (and (a1)) - :effect (and (e0) (not (normal-mode)) (increase (total-cost) 12.35)) - ) - (:action copy_0_sat_e1 - :parameters () - :precondition (and (ok_e1) (e0)) - :effect (and (e1) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_e1 - :parameters () - :precondition (and (e0)) - :effect (and (e1) (not (normal-mode)) (increase (total-cost) 10.2093)) - ) - (:action copy_0_sat_e2 - :parameters () - :precondition (and (ok_e2) (e1)) - :effect (and (e2) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_e2 - :parameters () - :precondition (and (e1)) - :effect (and (e2) (not (normal-mode)) (increase (total-cost) 10.0447)) - ) - (:action copy_0_sat_o0 - :parameters () - :precondition (and (ok_o0) (e2)) - :effect (and (o0) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_o0 - :parameters () - :precondition (and (e2)) - :effect (and (o0) (not (normal-mode)) (increase (total-cost) 9.804)) - ) - (:action copy_0_sat_o1 - :parameters () - :precondition (and (ok_o1) (o0)) - :effect (and (o1) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_o1 - :parameters () - :precondition (and (o0)) - :effect (and (o1) (not (normal-mode)) (increase (total-cost) 5.434)) - ) - (:action copy_0_sat_o2 - :parameters () - :precondition (and (ok_o2) (o1)) - :effect (and (o2) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_o2 - :parameters () - :precondition (and (o1)) - :effect (and (o2) (not (normal-mode)) (increase (total-cost) 8.55)) - ) - (:action copy_0_sat_o3 - :parameters () - :precondition (and (ok_o3) (o2)) - :effect (and (o3) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_o3 - :parameters () - :precondition (and (o2)) - :effect (and (o3) (not (normal-mode)) (increase (total-cost) 9.55067)) - ) - (:action copy_0_sat_sb3 - :parameters () - :precondition (and (ok_sb3) (o3)) - :effect (and (sb3) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_sb3 - :parameters () - :precondition (and (o3)) - :effect (and (sb3) (not (normal-mode)) (increase (total-cost) 9.22133)) - ) - (:action copy_0_sat_sb7 - :parameters () - :precondition (and (ok_sb7) (sb3)) - :effect (and (sb7) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_sb7 - :parameters () - :precondition (and (sb3)) - :effect (and (sb7) (not (normal-mode)) (increase (total-cost) 4.28133)) - ) - (:action copy_0_sat_sb8 - :parameters () - :precondition (and (ok_sb8) (sb7)) - :effect (and (sb8) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_sb8 - :parameters () - :precondition (and (sb7)) - :effect (and (sb8) (not (normal-mode)) (increase (total-cost) 5.10467)) - ) - (:action copy_0_sat_sb11 - :parameters () - :precondition (and (ok_sb11) (sb8)) - :effect (and (sb11) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_sb11 - :parameters () - :precondition (and (sb8)) - :effect (and (sb11) (not (normal-mode)) (increase (total-cost) 10.0447)) - ) - (:action copy_0_sat_sb12 - :parameters () - :precondition (and (ok_sb12) (sb11)) - :effect (and (sb12) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_sb12 - :parameters () - :precondition (and (sb11)) - :effect (and (sb12) (not (normal-mode)) (increase (total-cost) 7.41)) - ) - (:action copy_0_sat_sb13 - :parameters () - :precondition (and (ok_sb13) (sb12)) - :effect (and (sb13) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_sb13 - :parameters () - :precondition (and (sb12)) - :effect (and (sb13) (not (normal-mode)) (increase (total-cost) 11.856)) - ) - (:action copy_0_sat_sb16 - :parameters () - :precondition (and (ok_sb16) (sb13)) - :effect (and (sb16) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_sb16 - :parameters () - :precondition (and (sb13)) - :effect (and (sb16) (not (normal-mode)) (increase (total-cost) 7.32767)) - ) - (:action copy_0_sat_sb17 - :parameters () - :precondition (and (ok_sb17) (sb16)) - :effect (and (sb17) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_sb17 - :parameters () - :precondition (and (sb16)) - :effect (and (sb17) (not (normal-mode)) (increase (total-cost) 9.96233)) - ) - (:action copy_0_sat_sb19 - :parameters () - :precondition (and (ok_sb19) (sb17)) - :effect (and (sb19) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_sb19 - :parameters () - :precondition (and (sb17)) - :effect (and (sb19) (not (normal-mode)) (increase (total-cost) 6.726)) - ) - (:action copy_0_sat_sb20 - :parameters () - :precondition (and (ok_sb20) (sb19)) - :effect (and (sb20) (not (normal-mode)) (increase (total-cost) 0)) - ) - (:action copy_0_unsat_sb20 - :parameters () - :precondition (and (sb19)) - :effect (and (sb20) (not (normal-mode)) (increase (total-cost) 14.592)) - ) -) diff --git a/src/translate/regression-tests/issue73-problem.pddl b/src/translate/regression-tests/issue73-problem.pddl deleted file mode 100644 index 6b9dd2987..000000000 --- a/src/translate/regression-tests/issue73-problem.pddl +++ /dev/null @@ -1,20 +0,0 @@ -(define (problem roverprob1234) - (:domain rover) - - (:init (at_rover0_waypoint3) (at_soil_sample_waypoint0) - (empty_rover0store) (at_soil_sample_waypoint2) - (at_soil_sample_waypoint3) (at_rock_sample_waypoint1) - (at_rock_sample_waypoint2) (at_rock_sample_waypoint3) (ok_a0) (ok_a1) - (ok_o0) (negof_once_o0) (ok_o1) (negof_once_o1) (ok_o2) - (negof_once_o2) (ok_o3) (negof_once_o3) (ok_sb3) (ok_sb7) (ok_sb8) - (ok_sb11) (ok_sb12) (ok_sb13) (ok_sb16) (ok_sb17) (ok_sb19) (ok_sb20) - (normal-mode) (= (total-cost) 0)) - - (:goal (and (communicated_soil_data_waypoint2) - (communicated_rock_data_waypoint3) - (communicated_image_data_objective1_high_res) (a0) (a1) (e0) (e1) - (e2) (o0) (o1) (o2) (o3) (sb3) (sb7) (sb8) (sb11) (sb12) (sb13) - (sb16) (sb17) (sb19) (sb20))) - - (:metric minimize (total-cost)) -) diff --git a/src/translate/tests/__init__.py b/src/translate/tests/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/translate/tests/test_normalization.py b/src/translate/tests/test_normalization.py deleted file mode 100644 index cf87d6be8..000000000 --- a/src/translate/tests/test_normalization.py +++ /dev/null @@ -1,37 +0,0 @@ -from io import StringIO - -import pddl -from pddl_to_prolog import Rule, PrologProgram - -def test_normalization(): - prog = PrologProgram() - prog.add_fact(pddl.Atom("at", ["foo", "bar"])) - prog.add_fact(pddl.Atom("truck", ["bollerwagen"])) - prog.add_fact(pddl.Atom("truck", ["segway"])) - prog.add_rule(Rule([pddl.Atom("truck", ["?X"])], pddl.Atom("at", ["?X", "?Y"]))) - prog.add_rule(Rule([pddl.Atom("truck", ["X"]), pddl.Atom("location", ["?Y"])], - pddl.Atom("at", ["?X", "?Y"]))) - prog.add_rule(Rule([pddl.Atom("truck", ["?X"]), pddl.Atom("location", ["?Y"])], - pddl.Atom("at", ["?X", "?X"]))) - prog.add_rule(Rule([pddl.Atom("p", ["?Y", "?Z", "?Y", "?Z"])], - pddl.Atom("q", ["?Y", "?Y"]))) - prog.add_rule(Rule([], pddl.Atom("foo", []))) - prog.add_rule(Rule([], pddl.Atom("bar", ["X"]))) - prog.normalize() - output = StringIO() - prog.dump(file=output) - sorted_output = "\n".join(sorted(output.getvalue().splitlines())) - assert sorted_output == """\ -Atom @object(bar). -Atom @object(bollerwagen). -Atom @object(foo). -Atom @object(segway). -Atom at(foo, bar). -Atom bar(X). -Atom foo(). -Atom truck(bollerwagen). -Atom truck(segway). -none Atom at(?X, ?X@0) :- Atom truck(?X), Atom location(?Y), Atom =(?X, ?X@0). -none Atom at(?X, ?Y) :- Atom truck(?X), Atom @object(?Y). -none Atom at(?X, ?Y) :- Atom truck(X), Atom location(?Y), Atom @object(?X). -none Atom q(?Y, ?Y@0) :- Atom p(?Y, ?Z, ?Y, ?Z), Atom =(?Y, ?Y@0), Atom =(?Y, ?Y@1), Atom =(?Z, ?Z@2).""" diff --git a/src/translate/tests/test_scripts.py b/src/translate/tests/test_scripts.py deleted file mode 100644 index 8024614dd..000000000 --- a/src/translate/tests/test_scripts.py +++ /dev/null @@ -1,25 +0,0 @@ -import os.path -import subprocess -import sys - -DIR = os.path.dirname(os.path.abspath(__file__)) -TRANSLATE_DIR = os.path.dirname(DIR) -REPO = os.path.abspath(os.path.join(DIR, "..", "..", "..")) -BENCHMARKS = os.path.join(REPO, "misc", "tests", "benchmarks") -DOMAIN = os.path.join(BENCHMARKS, "gripper", "domain.pddl") -PROBLEM = os.path.join(BENCHMARKS, "gripper", "prob01.pddl") -SCRIPTS = [ - "build_model.py", - "graph.py", - "instantiate.py", - "invariant_finder.py", - "normalize.py", - "pddl_to_prolog.py", - "translate.py", -] - -def test_scripts(): - for script in SCRIPTS: - script = os.path.join(TRANSLATE_DIR, script) - folder, filename = os.path.split(script) - assert subprocess.check_call([sys.executable, filename, DOMAIN, PROBLEM], cwd=folder) == 0 From f2f132d469d8d2ea59a0b00fb2a7c75475e1e70d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2024 13:22:35 +0200 Subject: [PATCH 12/28] [trivial] Bump version of upload-artifact and download-artifact from 3 to 4 --- .github/workflows/ubuntu.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index a179d7198..8cae29a8f 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -98,7 +98,7 @@ jobs: - name: Upload archive if: ${{ matrix.version.run_tox_tests }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4.4.0 with: name: compiled-planner-${{ matrix.version.ubuntu }} path: archive.tar.gz @@ -118,7 +118,7 @@ jobs: CPLEX_URL: ${{ secrets.CPLEX2211_LINUX_URL }} steps: - name: Download archive - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4.1.8 with: name: compiled-planner-${{ matrix.version.ubuntu }} From eecab21667b7109b4ffc353f29fd7c593cefff5f Mon Sep 17 00:00:00 2001 From: Florian Pommerening Date: Thu, 5 Sep 2024 15:23:03 +0200 Subject: [PATCH 13/28] [issue1150] Allow prevail conditions with effects in potential optimizer. Previously, potential optimizer expected prevail conditions to be encoded as a precondition without an effect. It now accepts tasks where the prevail condition also occurs as an effect. This way task transformations that violate this assumption can be used. --- src/search/potentials/potential_optimizer.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/search/potentials/potential_optimizer.cc b/src/search/potentials/potential_optimizer.cc index 43479baa2..0a79a9fd0 100644 --- a/src/search/potentials/potential_optimizer.cc +++ b/src/search/potentials/potential_optimizer.cc @@ -136,9 +136,16 @@ void PotentialOptimizer::construct_lp() { int post = effect.get_fact().get_value(); int pre_lp = lp_var_ids[var_id][pre]; int post_lp = lp_var_ids[var_id][post]; - assert(pre_lp != post_lp); - coefficients.emplace_back(pre_lp, 1); - coefficients.emplace_back(post_lp, -1); + if (pre_lp != post_lp) { + /* + Prevail conditions with pre = post can occur in transformed + tasks, see issue1150. We ignore them since they cancel out and + LPConstraints may not have two coefficients for the same + variable. + */ + coefficients.emplace_back(pre_lp, 1); + coefficients.emplace_back(post_lp, -1); + } } sort(coefficients.begin(), coefficients.end()); for (const auto &coeff : coefficients) From f39b35b215f144c4f659a1f1f4fb9243c80a88ba Mon Sep 17 00:00:00 2001 From: SimonDold <48084373+SimonDold@users.noreply.github.com> Date: Tue, 17 Sep 2024 09:10:48 +0200 Subject: [PATCH 14/28] [trivial] Update pdb synopsis. (#232) Update pdb synopsis. --- src/search/pdbs/pdb_heuristic.cc | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/search/pdbs/pdb_heuristic.cc b/src/search/pdbs/pdb_heuristic.cc index 484e4d2eb..4e6efae28 100644 --- a/src/search/pdbs/pdb_heuristic.cc +++ b/src/search/pdbs/pdb_heuristic.cc @@ -3,6 +3,7 @@ #include "pattern_database.h" #include "../plugins/plugin.h" +#include "../utils/markup.h" #include #include @@ -33,13 +34,37 @@ int PDBHeuristic::compute_heuristic(const State &ancestor_state) { return h; } +static basic_string paper_references() { + return utils::format_conference_reference( + {"Stefan Edelkamp"}, + "Planning with Pattern Databases", + "https://aaai.org/papers/7280-ecp-01-2001/", + "Proceedings of the Sixth European Conference on Planning (ECP 2001)", + "84-90", + "AAAI Press", + "2001") + + "For implementation notes, see:" + utils::format_conference_reference( + {"Silvan Sievers", "Manuela Ortlieb", "Malte Helmert"}, + "Efficient Implementation of Pattern Database Heuristics for" + " Classical Planning", + "https://ai.dmi.unibas.ch/papers/sievers-et-al-socs2012.pdf", + "Proceedings of the Fifth Annual Symposium on Combinatorial" + " Search (SoCS 2012)", + "105-111", + "AAAI Press", + "2012"); +} class PDBHeuristicFeature : public plugins::TypedFeature { public: PDBHeuristicFeature() : TypedFeature("pdb") { document_subcategory("heuristics_pdb"); document_title("Pattern database heuristic"); - document_synopsis("TODO"); + document_synopsis( + "Computes goal distance in " + "state space abstractions based on projections. " + "First used in domain-independent planning by:" + + paper_references()); add_option>( "pattern", From 5d1bd6a0083e1350536717dd23385264e14e7412 Mon Sep 17 00:00:00 2001 From: Florian Pommerening Date: Fri, 27 Sep 2024 16:24:55 +0200 Subject: [PATCH 15/28] [trivial] Update BUILD.md to simplify installation instructions of SoPlex. --- BUILD.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/BUILD.md b/BUILD.md index 9d9d8f941..8dcce563b 100644 --- a/BUILD.md +++ b/BUILD.md @@ -38,22 +38,19 @@ Note that on Windows, setting up the environment variable might require using `/ **Important:** The GNU Multiple Precision library (GMP) is critical for the performance of SoPlex but the build does not complain if it is not present. Make sure that the build uses the library (check the output of CMake for `Found GMP`). -As of SoPlex 6.0.4, the release does not support C++-20, so we build from the tip of the [GitHub main branch](https://github.com/scipopt/soplex) (adapt the path if you install a different version or want to use a different location): +We require at least SoPlex 7.1.0, which can be built from source as follows (adapt the paths if you install a different version or want to use a different location): ```bash sudo apt install libgmp3-dev -git clone https://github.com/scipopt/soplex.git -export soplex_DIR=/opt/soplex-6.0.4x -export CXXFLAGS="$CXXFLAGS -Wno-use-after-free" # Ignore compiler warnings about use-after-free -cmake -S soplex -B build +wget https://github.com/scipopt/soplex/archive/refs/tags/release-710.tar.gz -O - | tar -xz +cmake -S soplex-release-710 -B build cmake --build build +export soplex_DIR=/opt/soplex-7.1.0 cmake --install build --prefix $soplex_DIR -rm -rf soplex build +rm -rf soplex-release-710 build ``` After installation, permanently set the environment variable `soplex_DIR` to the value you used during the installation. -**Note:** Once [support for C++-20](https://github.com/scipopt/soplex/pull/15) has been included in a SoPlex release, we can update this and can recommend the [SoPlex homepage](https://soplex.zib.de/index.php#download) for downloads instead. - ### Optional: Plan Validator From 45e1e6f96aac8c517408694011cd02f564b12010 Mon Sep 17 00:00:00 2001 From: Florian Pommerening Date: Mon, 7 Oct 2024 14:14:25 +0200 Subject: [PATCH 16/28] [issue1151] Improve error message when passing a heuristic to --search. Previously, the planner crashed with a bad anycast in cases where the argument of `--search` could be parsed but had the wrong type, e.g. `--search "lmcut()"`. --- src/search/command_line.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/search/command_line.cc b/src/search/command_line.cc index e8934d924..579471812 100644 --- a/src/search/command_line.cc +++ b/src/search/command_line.cc @@ -104,6 +104,8 @@ static shared_ptr parse_cmd_line_aux(const vector &args parser::DecoratedASTNodePtr decorated = parsed->decorate(); plugins::Any constructed = decorated->construct(); search_algorithm = plugins::any_cast(constructed); + } catch (const plugins::BadAnyCast &) { + input_error("Could not interpret the argument of --search as a search algorithm."); } catch (const utils::ContextError &e) { input_error(e.get_message()); } From 3ff4081193ac8138e6ffe55b3d0af300b13716aa Mon Sep 17 00:00:00 2001 From: Remo Christen Date: Mon, 7 Oct 2024 14:11:03 +0200 Subject: [PATCH 17/28] [trivial] Add author names to delete relaxation constraint documentation. --- .../operator_counting/delete_relaxation_if_constraints.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search/operator_counting/delete_relaxation_if_constraints.cc b/src/search/operator_counting/delete_relaxation_if_constraints.cc index b5f62452a..9a41f0c6d 100644 --- a/src/search/operator_counting/delete_relaxation_if_constraints.cc +++ b/src/search/operator_counting/delete_relaxation_if_constraints.cc @@ -241,7 +241,7 @@ class DeleteRelaxationIFConstraintsFeature : public plugins::TypedFeature { public: DeleteRelaxationIFConstraintsFeature() : TypedFeature("delete_relaxation_if_constraints") { - document_title("Delete relaxation constraints"); + document_title("Delete relaxation constraints from Imai and Fukunaga"); document_synopsis( "Operator-counting constraints based on the delete relaxation. By " "default the constraints encode an easy-to-compute relaxation of h^+^. " From 036fffa1167cea530efb2f67aca6f82bb005a2c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Salom=C3=A9=20Eriksson?= Date: Mon, 7 Oct 2024 15:00:22 +0200 Subject: [PATCH 18/28] [trivial] Update documentation regarding safety for tasks with axioms. --- src/search/heuristics/additive_heuristic.cc | 8 ++--- src/search/heuristics/cea_heuristic.cc | 6 +--- src/search/heuristics/cg_heuristic.cc | 6 +--- src/search/heuristics/ff_heuristic.cc | 8 ++--- src/search/heuristics/max_heuristic.cc | 8 ++--- .../landmark_cost_partitioning_heuristic.cc | 3 +- .../landmark_cost_partitioning_heuristic.h | 1 - src/search/landmarks/landmark_heuristic.cc | 11 ++----- src/search/landmarks/landmark_heuristic.h | 4 +-- .../landmarks/landmark_sum_heuristic.cc | 33 ++++++++++++------- src/search/landmarks/landmark_sum_heuristic.h | 3 +- src/search/tasks/default_value_axioms_task.cc | 4 +-- 12 files changed, 37 insertions(+), 58 deletions(-) diff --git a/src/search/heuristics/additive_heuristic.cc b/src/search/heuristics/additive_heuristic.cc index aff35d07b..943c2789c 100644 --- a/src/search/heuristics/additive_heuristic.cc +++ b/src/search/heuristics/additive_heuristic.cc @@ -159,15 +159,11 @@ class AdditiveHeuristicFeature document_language_support("action costs", "supported"); document_language_support("conditional effects", "supported"); - document_language_support( - "axioms", - "supported (in the sense that the planner won't complain -- " - "handling of axioms might be very stupid " - "and even render the heuristic unsafe)"); + document_language_support("axioms", "supported"); document_property("admissible", "no"); document_property("consistent", "no"); - document_property("safe", "yes for tasks without axioms"); + document_property("safe", "yes"); document_property("preferred operators", "yes"); } diff --git a/src/search/heuristics/cea_heuristic.cc b/src/search/heuristics/cea_heuristic.cc index 952f90522..8f1c25f84 100644 --- a/src/search/heuristics/cea_heuristic.cc +++ b/src/search/heuristics/cea_heuristic.cc @@ -458,11 +458,7 @@ class ContextEnhancedAdditiveHeuristicFeature document_language_support("action costs", "supported"); document_language_support("conditional effects", "supported"); - document_language_support( - "axioms", - "supported (in the sense that the planner won't complain -- " - "handling of axioms might be very stupid " - "and even render the heuristic unsafe)"); + document_language_support("axioms", "supported"); document_property("admissible", "no"); document_property("consistent", "no"); diff --git a/src/search/heuristics/cg_heuristic.cc b/src/search/heuristics/cg_heuristic.cc index a8dea593d..313f3e8ee 100644 --- a/src/search/heuristics/cg_heuristic.cc +++ b/src/search/heuristics/cg_heuristic.cc @@ -303,11 +303,7 @@ class CGHeuristicFeature document_language_support("action costs", "supported"); document_language_support("conditional effects", "supported"); - document_language_support( - "axioms", - "supported (in the sense that the planner won't complain -- " - "handling of axioms might be very stupid " - "and even render the heuristic unsafe)"); + document_language_support("axioms", "supported"); document_property("admissible", "no"); document_property("consistent", "no"); diff --git a/src/search/heuristics/ff_heuristic.cc b/src/search/heuristics/ff_heuristic.cc index 39f727258..3c98e97bc 100644 --- a/src/search/heuristics/ff_heuristic.cc +++ b/src/search/heuristics/ff_heuristic.cc @@ -84,15 +84,11 @@ class FFHeuristicFeature document_language_support("action costs", "supported"); document_language_support("conditional effects", "supported"); - document_language_support( - "axioms", - "supported (in the sense that the planner won't complain -- " - "handling of axioms might be very stupid " - "and even render the heuristic unsafe)"); + document_language_support("axioms", "supported"); document_property("admissible", "no"); document_property("consistent", "no"); - document_property("safe", "yes for tasks without axioms"); + document_property("safe", "yes"); document_property("preferred operators", "yes"); } diff --git a/src/search/heuristics/max_heuristic.cc b/src/search/heuristics/max_heuristic.cc index a0d78e2f8..ee7691278 100644 --- a/src/search/heuristics/max_heuristic.cc +++ b/src/search/heuristics/max_heuristic.cc @@ -113,15 +113,11 @@ class HSPMaxHeuristicFeature document_language_support("action costs", "supported"); document_language_support("conditional effects", "supported"); - document_language_support( - "axioms", - "supported (in the sense that the planner won't complain -- " - "handling of axioms might be very stupid " - "and even render the heuristic unsafe)"); + document_language_support("axioms", "supported"); document_property("admissible", "yes for tasks without axioms"); document_property("consistent", "yes for tasks without axioms"); - document_property("safe", "yes for tasks without axioms"); + document_property("safe", "yes"); document_property("preferred operators", "no"); } diff --git a/src/search/landmarks/landmark_cost_partitioning_heuristic.cc b/src/search/landmarks/landmark_cost_partitioning_heuristic.cc index b1adc45d0..a66524ce8 100644 --- a/src/search/landmarks/landmark_cost_partitioning_heuristic.cc +++ b/src/search/landmarks/landmark_cost_partitioning_heuristic.cc @@ -18,13 +18,12 @@ namespace landmarks { LandmarkCostPartitioningHeuristic::LandmarkCostPartitioningHeuristic( const shared_ptr &lm_factory, bool pref, bool prog_goal, bool prog_gn, bool prog_r, - tasks::AxiomHandlingType axioms, const shared_ptr &transform, bool cache_estimates, const string &description, utils::Verbosity verbosity, CostPartitioningMethod cost_partitioning, bool alm, lp::LPSolverType lpsolver) : LandmarkHeuristic( - axioms, pref, transform, cache_estimates, description, verbosity) { + pref, transform, cache_estimates, description, verbosity) { if (log.is_at_least_normal()) { log << "Initializing landmark cost partitioning heuristic..." << endl; } diff --git a/src/search/landmarks/landmark_cost_partitioning_heuristic.h b/src/search/landmarks/landmark_cost_partitioning_heuristic.h index fb57717c0..be64e867c 100644 --- a/src/search/landmarks/landmark_cost_partitioning_heuristic.h +++ b/src/search/landmarks/landmark_cost_partitioning_heuristic.h @@ -26,7 +26,6 @@ class LandmarkCostPartitioningHeuristic : public LandmarkHeuristic { LandmarkCostPartitioningHeuristic( const std::shared_ptr &lm_factory, bool pref, bool prog_goal, bool prog_gn, bool prog_r, - tasks::AxiomHandlingType axioms, const std::shared_ptr &transform, bool cache_estimates, const std::string &description, utils::Verbosity verbosity, diff --git a/src/search/landmarks/landmark_heuristic.cc b/src/search/landmarks/landmark_heuristic.cc index cd0d75e1b..d8a5a8d6d 100644 --- a/src/search/landmarks/landmark_heuristic.cc +++ b/src/search/landmarks/landmark_heuristic.cc @@ -14,12 +14,10 @@ using namespace std; namespace landmarks { LandmarkHeuristic::LandmarkHeuristic( - tasks::AxiomHandlingType axioms, bool use_preferred_operators, + bool use_preferred_operators, const shared_ptr &transform, bool cache_estimates, const string &description, utils::Verbosity verbosity) - : Heuristic(tasks::get_default_value_axioms_task_if_needed( - transform, axioms), - cache_estimates, description, verbosity), + : Heuristic(transform, cache_estimates, description, verbosity), use_preferred_operators(use_preferred_operators), successor_generator(nullptr) { } @@ -228,7 +226,6 @@ void add_landmark_heuristic_options_to_feature( "prog_gn", "Use greedy-necessary ordering progression.", "true"); feature.add_option( "prog_r", "Use reasonable ordering progression.", "true"); - tasks::add_axioms_option_to_feature(feature); add_heuristic_options_to_feature(feature, description); feature.document_property("preferred operators", @@ -236,8 +233,7 @@ void add_landmark_heuristic_options_to_feature( } tuple, bool, bool, bool, bool, - tasks::AxiomHandlingType, shared_ptr, bool, string, - utils::Verbosity> + shared_ptr, bool, string, utils::Verbosity> get_landmark_heuristic_arguments_from_options( const plugins::Options &opts) { return tuple_cat( @@ -247,7 +243,6 @@ get_landmark_heuristic_arguments_from_options( opts.get("prog_goal"), opts.get("prog_gn"), opts.get("prog_r")), - tasks::get_axioms_arguments_from_options(opts), get_heuristic_arguments_from_options(opts)); } } diff --git a/src/search/landmarks/landmark_heuristic.h b/src/search/landmarks/landmark_heuristic.h index 55f0deab0..ab50bf9a0 100644 --- a/src/search/landmarks/landmark_heuristic.h +++ b/src/search/landmarks/landmark_heuristic.h @@ -46,7 +46,6 @@ class LandmarkHeuristic : public Heuristic { virtual int compute_heuristic(const State &ancestor_state) override; public: LandmarkHeuristic( - tasks::AxiomHandlingType axioms, bool use_preferred_operators, const std::shared_ptr &transform, bool cache_estimates, const std::string &description, @@ -66,8 +65,7 @@ class LandmarkHeuristic : public Heuristic { extern void add_landmark_heuristic_options_to_feature( plugins::Feature &feature, const std::string &description); extern std::tuple, bool, bool, bool, - bool, tasks::AxiomHandlingType, - std::shared_ptr, bool, std::string, + bool, std::shared_ptr, bool, std::string, utils::Verbosity> get_landmark_heuristic_arguments_from_options( const plugins::Options &opts); diff --git a/src/search/landmarks/landmark_sum_heuristic.cc b/src/search/landmarks/landmark_sum_heuristic.cc index 51f447a54..08067e770 100644 --- a/src/search/landmarks/landmark_sum_heuristic.cc +++ b/src/search/landmarks/landmark_sum_heuristic.cc @@ -31,14 +31,15 @@ static bool are_dead_ends_reliable( } LandmarkSumHeuristic::LandmarkSumHeuristic( - const shared_ptr &lm_factory, bool pref, - bool prog_goal, bool prog_gn, bool prog_r, - tasks::AxiomHandlingType axioms, + const shared_ptr &lm_factory, + bool pref, bool prog_goal, bool prog_gn, bool prog_r, const shared_ptr &transform, bool cache_estimates, - const string &description, utils::Verbosity verbosity) + const string &description, utils::Verbosity verbosity, + tasks::AxiomHandlingType axioms) : LandmarkHeuristic( - axioms, pref, transform, cache_estimates, - description, verbosity), + pref, + tasks::get_default_value_axioms_task_if_needed(transform, axioms), + cache_estimates, description, verbosity), dead_ends_reliable( are_dead_ends_reliable(lm_factory, task_proxy)) { if (log.is_at_least_normal()) { @@ -141,9 +142,17 @@ class LandmarkSumHeuristicFeature "39", "127-177", "2010")); - + /* + We usually have the options of base classes behind the options + of specific implementations. In the case of landmark + heuristics, we decided to have the common options at the front + because it feels more natural to specify the landmark factory + before the more specific arguments like the used LP solver in + the case of an optimal cost partitioning heuristic. + */ add_landmark_heuristic_options_to_feature( *this, "landmark_sum_heuristic"); + tasks::add_axioms_option_to_feature(*this); document_note( "Note on performance for satisficing planning", @@ -185,22 +194,22 @@ class LandmarkSumHeuristicFeature "conditional_effects", "supported if the LandmarkFactory supports them; otherwise " "ignored"); - document_language_support("axioms", "ignored"); + document_language_support("axioms", "supported"); document_property("admissible", "no"); document_property("consistent", "no"); document_property( "safe", - "yes except on tasks with axioms or on tasks with " - "conditional effects when using a LandmarkFactory " - "not supporting them"); + "yes except on tasks with conditional effects when " + "using a LandmarkFactory not supporting them"); } virtual shared_ptr create_component( const plugins::Options &opts, const utils::Context &) const override { return plugins::make_shared_from_arg_tuples( - get_landmark_heuristic_arguments_from_options(opts)); + get_landmark_heuristic_arguments_from_options(opts), + tasks::get_axioms_arguments_from_options(opts)); } }; diff --git a/src/search/landmarks/landmark_sum_heuristic.h b/src/search/landmarks/landmark_sum_heuristic.h index 70775e658..9783f43bd 100644 --- a/src/search/landmarks/landmark_sum_heuristic.h +++ b/src/search/landmarks/landmark_sum_heuristic.h @@ -19,10 +19,9 @@ class LandmarkSumHeuristic : public LandmarkHeuristic { LandmarkSumHeuristic( const std::shared_ptr &lm_factory, bool pref, bool prog_goal, bool prog_gn, bool prog_r, - tasks::AxiomHandlingType axioms, const std::shared_ptr &transform, bool cache_estimates, const std::string &description, - utils::Verbosity verbosity); + utils::Verbosity verbosity, tasks::AxiomHandlingType axioms); virtual bool dead_ends_are_reliable() const override; }; diff --git a/src/search/tasks/default_value_axioms_task.cc b/src/search/tasks/default_value_axioms_task.cc index 61241f7b5..e080bcf49 100644 --- a/src/search/tasks/default_value_axioms_task.cc +++ b/src/search/tasks/default_value_axioms_task.cc @@ -421,9 +421,9 @@ static plugins::TypedEnumPlugin _enum_plugin({ {"approximate_negative_cycles", "Overapproximate negated axioms for all derived variables which " "have cyclic dependencies by setting an empty condition, " - "indicating the default value can always be achieved for free." + "indicating the default value can always be achieved for free. " "For all other derived variables, the negated axioms are computed" "exactly. Note that this can potentially lead to a combinatorial " - "explosion"} + "explosion."} }); } From e820c0d02f02cfe51479ab07d1473a3c9c5fa07f Mon Sep 17 00:00:00 2001 From: Gabriele Roeger Date: Tue, 8 Oct 2024 12:18:06 +0200 Subject: [PATCH 19/28] [trivial] Update contributors. --- README.md | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index eacf77096..98bbee194 100644 --- a/README.md +++ b/README.md @@ -52,19 +52,22 @@ Currently, this list is sorted by the last year the person has been active, and in case of ties, by the earliest year the person started contributing, and finally by last name. -- 2003-2023 Malte Helmert -- 2008-2016, 2018-2023 Gabriele Roeger -- 2010-2023 Jendrik Seipp -- 2010-2011, 2013-2023 Silvan Sievers -- 2012-2023 Florian Pommerening -- 2013, 2015-2023 Salomé Eriksson +- 2003-2024 Malte Helmert +- 2008-2016, 2018-2024 Gabriele Roeger +- 2010-2024 Jendrik Seipp +- 2010-2011, 2013-2024 Silvan Sievers +- 2012-2024 Florian Pommerening +- 2013, 2015-2024 Salomé Eriksson +- 2018-2024 Patrick Ferber +- 2021-2024 Clemens Büchner +- 2022-2024 Remo Christen +- 2023-2024 Simon Dold +- 2023-2024 Claudia S. Grundke +- 2024 Tanja Schindler +- 2024 David Speck +- 2024 Martín Pozo - 2015, 2021-2023 Thomas Keller -- 2018-2023 Patrick Ferber - 2018-2020, 2023 Augusto B. Corrêa -- 2021-2023 Clemens Büchner -- 2022-2023 Remo Christen -- 2023 Simon Dold -- 2023 Claudia S. Grundke - 2023 Victor Paléologue - 2023 Emanuele Tirendi - 2021-2022 Dominik Drexler From 99495cb52f97f3c9f181e7f9eec44f1e556640b3 Mon Sep 17 00:00:00 2001 From: Gabriele Roeger Date: Tue, 8 Oct 2024 14:19:33 +0200 Subject: [PATCH 20/28] [trivial] Use ubuntu jammy in vagrant file. --- misc/releases/templates/_Vagrantfile.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/releases/templates/_Vagrantfile.tpl b/misc/releases/templates/_Vagrantfile.tpl index 3fb8b0f2b..ad0ac2a6a 100644 --- a/misc/releases/templates/_Vagrantfile.tpl +++ b/misc/releases/templates/_Vagrantfile.tpl @@ -11,7 +11,7 @@ Vagrant.configure("2") do |config| v.memory = 2048 end - config.vm.box = "ubuntu/noble64" + config.vm.box = "ubuntu/jammy64" # To compile the planner with support for CPLEX, download the 64-bit Linux # installer of CPLEX 22.1.1 and set the environment variable From 2e739a533c78f64c8727ae233400bac0160e1472 Mon Sep 17 00:00:00 2001 From: Gabriele Roeger Date: Tue, 8 Oct 2024 14:33:15 +0200 Subject: [PATCH 21/28] [trivial] Update copyright year in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 98bbee194..97e4ffe62 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Fast Downward is a domain-independent classical planning system. -Copyright 2003-2023 Fast Downward contributors (see below). +Copyright 2003-2024 Fast Downward contributors (see below). For further information: - Fast Downward website: From beb7062b1730ea78910422007c270043acbf34f8 Mon Sep 17 00:00:00 2001 From: Florian Pommerening Date: Thu, 10 Oct 2024 13:51:21 +0200 Subject: [PATCH 22/28] [trivial] Update software versions in README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 97e4ffe62..4b5df3e75 100644 --- a/README.md +++ b/README.md @@ -27,13 +27,13 @@ This version of Fast Downward has been tested with the following software versio | OS | Python | C++ compiler | CMake | | ------------ | ------ | ---------------------------------------------------------------- | ----- | -| Ubuntu 22.04 | 3.10 | GCC 11, GCC 12, Clang 14 | 3.22 | -| Ubuntu 20.04 | 3.8 | GCC 10, Clang 12 | 3.16 | -| macOS 12 | 3.10 | AppleClang 14 | 3.24 | -| macOS 11 | 3.8 | AppleClang 13 | 3.24 | -| Windows 10 | 3.8 | Visual Studio Enterprise 2019 (MSVC 19.29) and 2022 (MSVC 19.31) | 3.22 | +| Ubuntu 24.04 | 3.10 | GCC 14, Clang 18 | 3.30 | +| Ubuntu 22.04 | 3.10 | GCC 12, Clang 15 | 3.30 | +| macOS 14 | 3.10 | AppleClang 15 | 3.30 | +| macOS 13 | 3.10 | AppleClang 15 | 3.30 | +| Windows 10 | 3.8 | Visual Studio Enterprise 2019 (MSVC 19.29) and 2022 (MSVC 19.41) | 3.30 | -We test LP support with CPLEX 22.1.1 and SoPlex 6.0.3+. On Ubuntu we +We test LP support with CPLEX 22.1.1 and SoPlex 7.1.1. On Ubuntu we test both CPLEX and SoPlex. On Windows we currently only test CPLEX, and on macOS we do not test LP solvers (yet). From fea6b41a162f8d5aa8343077c11efd1a508dd360 Mon Sep 17 00:00:00 2001 From: Gabi Roeger Date: Thu, 10 Oct 2024 13:57:02 +0200 Subject: [PATCH 23/28] [trivial] Update contributors in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b5df3e75..1335104ef 100644 --- a/README.md +++ b/README.md @@ -63,9 +63,9 @@ contributing, and finally by last name. - 2022-2024 Remo Christen - 2023-2024 Simon Dold - 2023-2024 Claudia S. Grundke +- 2024 Martín Pozo - 2024 Tanja Schindler - 2024 David Speck -- 2024 Martín Pozo - 2015, 2021-2023 Thomas Keller - 2018-2020, 2023 Augusto B. Corrêa - 2023 Victor Paléologue From c6c48f3754770fae6b2deca8895219a5f49a87f0 Mon Sep 17 00:00:00 2001 From: Malte Helmert Date: Thu, 10 Oct 2024 15:16:11 +0200 Subject: [PATCH 24/28] [trivial] Add change log for version 24.06. --- CHANGES.md | 232 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index d227b31d5..4dd43ce9a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,238 @@ For more details, check the repository history (). Repository branches are named after the corresponding tracker issues. +## Fast Downward 24.06 + +Released on October 10, 2024. + +Highlights: + +- We have improved the translator in several dimensions. Key + improvements include a revised and faster version of the invariant + algorithm, full support for negated predicates in the goal, and + improved error reporting for invalid PDDL. In addition, we have + moved the generation of negated axioms to the search component, + which can significantly improve the performance of configurations + that do not rely on negated axioms. + +- We have implemented a new theory of landmark progression that, among + other things, closes a completeness gap for search configurations + like LAMA. Furthermore, this change makes it possible to use + reasonable orders for admissible landmark heuristics. + +- We added the delete-relaxation operator-counting constraints + described by Masood Feyzbakhsh Rankooh and Jussi Rintanen. + +- We have modernized the CMake build system, which now requires a + minimal version of CMake 3.16. + +Details: + +- bug fix: The planner now invokes destructors when terminating + (except for emergency situations where this is not possible) and + exits gracefully when running out of memory. + + + +- bug fix: Removed a dangling pointer in the state registry caused by + state copying. + + +- build: On M2 Macs it is now easier to build Fast Downward with CPLEX. + +- build: We now support static linking of CPLEX. + + +- build: We modernized the CMake build system by updating the + requirement to CMake 3.16. New files must now be listed in + src/search/CMakeLists.txt for compilation. For Soplex support, users + need to set the soplex_DIR environment variable instead of + DOWNWARD_SOPLEX_ROOT. Futhermore, we renamed CMake options from + PLUGIN_FF_HEURISTIC_ENABLED to LIBRARY_FF_HEURISTIC_ENABLED. + + +- build: We added support for the `Validate` binary from newer VAL + versions, defaulting to `Validate` if `validate` is not found on the + PATH. + + +- build, for developers: We introduced the + `-Wzero-as-null-pointer-constant` flag to warn when 0 is used + instead of `nullptr` and the `-Wmissing-declarations` flag to detect + global functions not declared in header files, promoting static + declarations for visibility control. + + + +- command line, for users: usage errors are now printed to stderr. + + +- command line, bug fix: Line breaks in command lines are now + correctly handled on Windows. + + +- driver: When running a portfolio, its component now prints the + absolute runtime as well as the relative runtime. + + +- driver: We have added the alias `seq-sat-fdss-2023` for the + satisficing Fast Downward Stone Soup 2023 portfolio. + + +- infrastructure: We have restructured the documentation for building + and running experiments. The build instructions are in the + [BUILD.md](BUILD.md) file. Developer-specific build information + has been moved to the "for developers" wiki section. + . + +- infrastructure: We have removed the experiments directory from the + repository. + + +- infrastructure: We have updated the operating system versions and + software versions used for our GitHub actions test suite. + + +- landmarks, for users: We no longer break cycles in + landmark graphs because landmark progression can now deal + with cycles. Obedient-reasonable orderings are no longer used + because they had little impact on performance in our experiments + and they are not well-supported by theory. + + + +- landmarks, for users: Configurations with landmark heuristics are up + to 30% faster due to data structure optimizations. + + +- landmarks, for users: The landmark cost partitioning heuristic now + uses an enumeration to define the type of cost partitioning instead + of a Boolean. This affects the command line: `optimal={true,false}` + is now `cost_partitioning={optimal,uniform}`. + + +- landmarks, for developers: We updated variable, function, class and + file names within the landmark cost partitioning code. + + +- landmarks, for users: The algorithm for generating reasonable + landmark orderings is now deterministic and finds more orderings. + This has a positive impact on performance (number of + expansions, plan quality for satisficing configurations). + + +- landmarks, for users: the landmark heuristics now consider an + operator preferred iff it achieves a landmark that is needed in the + future according to the heuristic. This replaces the previous, much + more convoluted definition. + + +- landmarks, bug fix: Landmark progression is now sound. The new + progression stores more information per state, leading to higher + memory requirements, but overall performance is only minimally + affected. With this change, it is now safe to use reasonable + orderings in the `landmark_cost_partitioning` heuristic. Since this + is in general beneficial, The `seq-opt-bjolp` alias now uses + reasonable orderings. + + +- landmarks, bug fix: We no longer wrongly assert that conjunctive + landmarks do not overlap with simple or disjunctive landmarks. + + +- LP/MIP solvers, bug fix: Empty constraint systems no longer lead to + crashes when using CPLEX. + + +- LP/MIP solvers, bug fix: We now call the correct methods of the LP + solvers for setting variable bounds. + + + +- LP/MIP solvers, bug fix: CPLEX now compiles correctly on Windows for + arbitrary repository names. + + +- merge-and-shrink, for developers: We refactored and simplified the code + of the `merge_sccs` merge strategy. + + +- operator counting, for users: We implemented the delete-relaxation + operator-counting constraints described in "Efficient Computation and + Informative Estimation of h+ by Integer and Linear + Programming" (Rankooh and Rintanen, ICAPS 2022). + For details, see + + + +- option parser, for users and developers: constructors no longer use + an encapsulated `Options` object, but take their parameters + directly. As a side effect, some command-line options now take their + parameters in a different order. + + +- option parser, for developers: We now support string arguments in + double quotes. Strings may use escape symbols `\"`, `\\`, and `\n` + for double quotes, backslashes and newlines. + + +- potential heuristics, bug fix: The potential optimizer now supports + effects that set a variable to a value that is already required by a + precondition. (The code will never generate such effects, but this + makes it possible to use task transformations that do generate such + effects.) + + +- search algorithms, bug fix: in the `eager` search algorithm, the + setting `reopen_closed=false` also affected open nodes, not just + closed nodes. This has now been fixed. Note that the previous + behavior did not affect the optimality of A* because it does not use + this setting. + + +- search algorithms, bug fix: Correctly propagate plan cost bounds to + components in iterated search in cases where manual cost bounds are + combined with bounds derived from incumbent solutions. + + +- translator and heuristics, for users: Negated axioms are now + computed in the search component and only for heuristics that need + them (relaxation heuristics, landmark heuristics, `cea` and `cg`). + This can lead to a large performance improvement for configurations + that do not use the aforementioned heuristics. We added a new option + for heuristics using negated axioms: + + `axioms={approximate_negative,approximate_negative_cycles}` + + `approximate_negative_cycles` is the old behavior and the new + default, while `approximate_negative` may result in less informative + heuristics, but avoids a potentially exponential number of negated + axioms. + + +- translator, for users: We added full support for negative literals + in goals. + + +- translator: We removed a source of nondeterminism in the translator. + The translator should now be deterministic except for the effect of + the invariant synthesis timeout (option + `--invariant-generation-max-time`). + + +- translator, for users: We improved error reporting for invalid PDDL + input. + + +- translator, bug fix: Uninitialized numeric expressions are now + handled correctly by the translator. + + +- translator, bug fix: There was a conceptual gap in the invariant + synthesis algorithm. This has been fixed by a revised algorithm, + which is also faster. + + ## Fast Downward 23.06 Released on July 31, 2023. From f1a8f644d02a66e635c4c6c181c866462959b540 Mon Sep 17 00:00:00 2001 From: Malte Helmert Date: Thu, 10 Oct 2024 18:09:32 +0200 Subject: [PATCH 25/28] [trivial] Further polishing of the change log for the upcoming release. --- CHANGES.md | 74 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 4dd43ce9a..c30fc50d8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,23 +16,42 @@ Released on October 10, 2024. Highlights: - We have improved the translator in several dimensions. Key - improvements include a revised and faster version of the invariant - algorithm, full support for negated predicates in the goal, and - improved error reporting for invalid PDDL. In addition, we have - moved the generation of negated axioms to the search component, - which can significantly improve the performance of configurations - that do not rely on negated axioms. - -- We have implemented a new theory of landmark progression that, among - other things, closes a completeness gap for search configurations - like LAMA. Furthermore, this change makes it possible to use - reasonable orders for admissible landmark heuristics. - -- We added the delete-relaxation operator-counting constraints - described by Masood Feyzbakhsh Rankooh and Jussi Rintanen. - -- We have modernized the CMake build system, which now requires a - minimal version of CMake 3.16. + improvements include better error reporting for invalid PDDL, + revised and faster version of the invariant algorithm and full + support for negated predicates in the goal. + +- Negated axioms are now computed in the search component, and only in + configurations that actually use them. This eliminates a worst-case + exponential performance bottleneck in cases where negated axioms are + not used. Heuristics that use negated axioms have a new option + (`axioms=approximate_negative`) to avoid this computation at the + cost of some heuristic accuracy. + +- There are many improvements to the `landmark_sum` and + `landmark_cost_partitioning` heuristics. This includes a new theory + of landmark progression that fixes a gap in the completeness in + search configurations like LAMA and can deal directly with cyclic + landmark orders, support for reasonable orders in admissible + landmark heuristics, a cleaner definition of preferred operators, + deterministic synthesis of reasonable orders, and performance + improvements. Please note that the command-line options for landmark + heuristics have changed. + +- We added a new set of operator-counting constraints + (`delete_relaxation_rr_constraints`), which implements the + delete-relaxation operator-counting constraints by Rankooh and + Rintanen. The old `delete_relaxation_constraints` plugin using the + constraints by Imai and Fukunaga has been renamed to + `delete_relaxation_if_constraints`. + +- We added the alias `seq-sat-fdss-2023` for the satisficing Fast + Downward Stone Soup 2023 portfolio from IPC 2023. + +- For developers: planner component objects (such as heuristics or + search algorithms) are now constructed with individual parameters + rather than having all parameters encapsulated in an `Options` + object. (We mention this primarily for developers maintaining their + own forks, as this change affects more than 200 source files.) Details: @@ -55,7 +74,7 @@ Details: requirement to CMake 3.16. New files must now be listed in src/search/CMakeLists.txt for compilation. For Soplex support, users need to set the soplex_DIR environment variable instead of - DOWNWARD_SOPLEX_ROOT. Futhermore, we renamed CMake options from + DOWNWARD_SOPLEX_ROOT. Furthermore, we renamed CMake options from PLUGIN_FF_HEURISTIC_ENABLED to LIBRARY_FF_HEURISTIC_ENABLED. @@ -101,6 +120,10 @@ Details: software versions used for our GitHub actions test suite. +- infrastructure: Windows builds using CPLEX in GitHub actions now + work with arbitrary repository names. + + - landmarks, for users: We no longer break cycles in landmark graphs because landmark progression can now deal with cycles. Obedient-reasonable orderings are no longer used @@ -157,18 +180,17 @@ Details: -- LP/MIP solvers, bug fix: CPLEX now compiles correctly on Windows for - arbitrary repository names. - - - merge-and-shrink, for developers: We refactored and simplified the code of the `merge_sccs` merge strategy. -- operator counting, for users: We implemented the delete-relaxation - operator-counting constraints described in "Efficient Computation and - Informative Estimation of h+ by Integer and Linear - Programming" (Rankooh and Rintanen, ICAPS 2022). +- operator counting, for users: We added + `delete_relaxation_rr_constraints`, which implements the + delete-relaxation operator-counting constraints described in + "Efficient Computation and Informative Estimation of h+ + by Integer and Linear Programming" (Rankooh and Rintanen, ICAPS + 2022). The old `delete_relaxation_constraints` plugin is now called + `delete_relaxation_if_constraints`. For details, see From 113fe1a626176f0c34888c645d4c25e7c31db372 Mon Sep 17 00:00:00 2001 From: Florian Pommerening Date: Thu, 10 Oct 2024 18:16:42 +0200 Subject: [PATCH 26/28] [release-24.06] Release version 24.06.0. --- driver/version.py | 2 +- misc/releases/24.06/Dockerfile.24.06 | 61 ++++++++++++++++++++++ misc/releases/24.06/Vagrantfile.24.06 | 74 +++++++++++++++++++++++++++ misc/releases/latest/Dockerfile | 2 +- misc/releases/latest/Vagrantfile | 2 +- 5 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 misc/releases/24.06/Dockerfile.24.06 create mode 100644 misc/releases/24.06/Vagrantfile.24.06 diff --git a/driver/version.py b/driver/version.py index 969142edb..2cc128953 100644 --- a/driver/version.py +++ b/driver/version.py @@ -1,4 +1,4 @@ # This file is auto-generated by the scripts in misc/release. # Do not modify it. -__version__ = "23.06+" +__version__ = "24.06" diff --git a/misc/releases/24.06/Dockerfile.24.06 b/misc/releases/24.06/Dockerfile.24.06 new file mode 100644 index 000000000..702999bf7 --- /dev/null +++ b/misc/releases/24.06/Dockerfile.24.06 @@ -0,0 +1,61 @@ +# This file has been automatically generated. + +# The recipe below implements a Docker multi-stage build: +# + +############################################################################### +# A first image to build the planner +############################################################################### +FROM ubuntu:24.04 AS builder + +RUN apt-get update && apt-get install --no-install-recommends -y \ + ca-certificates \ + cmake \ + g++ \ + git \ + libgmp3-dev \ + make \ + python3 \ + zlib1g-dev + +# Set up some environment variables. +ENV CXX g++ +ENV SOPLEX_REVISION release-710 +ENV soplex_DIR /opt/soplex + +# Install SoPlex. +WORKDIR /workspace/soplex +RUN git clone --depth 1 --branch $SOPLEX_REVISION https://github.com/scipopt/soplex.git . && \ + cmake -DCMAKE_INSTALL_PREFIX="$soplex_DIR" -S . -B build && \ + cmake --build build && \ + cmake --install build + +# Install Fast Downward. +WORKDIR /workspace/downward/ +RUN git clone --depth 1 --branch release-24.06.0 https://github.com/aibasel/downward.git . && \ + ./build.py release debug && \ + strip --strip-all builds/release/bin/downward + + +############################################################################### +# The final image to run the planner +############################################################################### +FROM ubuntu:24.04 AS runner + +RUN apt-get update && apt-get install --no-install-recommends -y \ + python3 \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /workspace/downward/ + +# Copy the relevant files from the previous docker build into this build. +COPY --from=builder /workspace/downward/fast-downward.py . +COPY --from=builder /workspace/downward/builds/release/bin/ ./builds/release/bin/ +COPY --from=builder /workspace/downward/builds/debug/bin/ ./builds/debug/bin/ +COPY --from=builder /workspace/downward/driver ./driver +COPY --from=builder /opt/soplex /opt/soplex + +ENV soplex_DIR=/opt/soplex +ENV LD_LIBRARY_PATH=$soplex_DIR/lib + +ENTRYPOINT ["/workspace/downward/fast-downward.py"] diff --git a/misc/releases/24.06/Vagrantfile.24.06 b/misc/releases/24.06/Vagrantfile.24.06 new file mode 100644 index 000000000..9d285c58c --- /dev/null +++ b/misc/releases/24.06/Vagrantfile.24.06 @@ -0,0 +1,74 @@ +# All Vagrant configuration is done below. The "2" in Vagrant.configure +# configures the configuration version (we support older styles for +# backwards compatibility). Please don't change it unless you know what +# you're doing. +Vagrant.configure("2") do |config| + # For a complete reference of vagrant options see https://docs.vagrantup.com. + + # We increase the RAM from a default of 1GB for compiling with SoPlex. + # See issue1101 for details. + config.vm.provider "virtualbox" do |v| + v.memory = 2048 + end + + config.vm.box = "ubuntu/jammy64" + + # To compile the planner with support for CPLEX, download the 64-bit Linux + # installer of CPLEX 22.1.1 and set the environment variable + # DOWNWARD_LP_INSTALLERS to an absolute path containing them before + # provisioning the VM. + provision_env = {} + if !ENV["DOWNWARD_LP_INSTALLERS"].nil? + cplex_installer = ENV["DOWNWARD_LP_INSTALLERS"] + "/cplex_studio2211.linux_x86_64.bin" + if File.exists?(cplex_installer) + config.vm.synced_folder ENV["DOWNWARD_LP_INSTALLERS"], "/lp", :mount_options => ["ro"] + provision_env["CPLEX_INSTALLER"] = "/lp/" + File.basename(cplex_installer) + end + end + + config.vm.provision "shell", env: provision_env, inline: <<-SHELL + + apt-get update && apt-get install --no-install-recommends -y \ + ca-certificates \ + cmake \ + default-jre \ + g++ \ + git \ + libgmp3-dev \ + make \ + python3 \ + unzip \ + zlib1g-dev + + if [ -f "$CPLEX_INSTALLER" ]; then + # Set environment variables for CPLEX. + cat > /etc/profile.d/downward-cplex.sh <<-EOM + export cplex_DIR="/opt/ibm/ILOG/CPLEX_Studio2211/cplex" + EOM + source /etc/profile.d/downward-cplex.sh + + # Install CPLEX. + $CPLEX_INSTALLER -DLICENSE_ACCEPTED=TRUE -i silent + fi + + # Set environment variables for SoPlex. + cat > /etc/profile.d/downward-soplex.sh <<-EOM + export soplex_DIR="/opt/soplex" + EOM + source /etc/profile.d/downward-soplex.sh + git clone --depth 1 --branch release-710 https://github.com/scipopt/soplex.git soplex + cd soplex + cmake -DCMAKE_INSTALL_PREFIX="$soplex_DIR" -S . -B build + cmake --build build + cmake --install build + + cd /home/vagrant + + if ! [ -e downward ] ; then + git clone --branch release-24.06.0 https://github.com/aibasel/downward.git downward + ./downward/build.py release debug + chown -R vagrant.vagrant downward + fi + + SHELL +end diff --git a/misc/releases/latest/Dockerfile b/misc/releases/latest/Dockerfile index 00cd48ce7..2715b3c8e 120000 --- a/misc/releases/latest/Dockerfile +++ b/misc/releases/latest/Dockerfile @@ -1 +1 @@ -../23.06/Dockerfile.23.06 \ No newline at end of file +../24.06/Dockerfile.24.06 \ No newline at end of file diff --git a/misc/releases/latest/Vagrantfile b/misc/releases/latest/Vagrantfile index 967211af3..844d61121 120000 --- a/misc/releases/latest/Vagrantfile +++ b/misc/releases/latest/Vagrantfile @@ -1 +1 @@ -../23.06/Vagrantfile.23.06 \ No newline at end of file +../24.06/Vagrantfile.24.06 \ No newline at end of file From 6e708b8f8c5962bab226ea649681c95b550346d7 Mon Sep 17 00:00:00 2001 From: Florian Pommerening Date: Thu, 10 Oct 2024 18:16:42 +0200 Subject: [PATCH 27/28] [main] Update version number to 24.06+. --- driver/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver/version.py b/driver/version.py index 2cc128953..2e8808cab 100644 --- a/driver/version.py +++ b/driver/version.py @@ -1,4 +1,4 @@ # This file is auto-generated by the scripts in misc/release. # Do not modify it. -__version__ = "24.06" +__version__ = "24.06+" From c7d6a4d87a10a4c2857285c3b49a14e8d18717a2 Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Tue, 19 Nov 2024 14:31:39 +0100 Subject: [PATCH 28/28] [trivial] Fix typo. --- src/search/merge_and_shrink/merge_scoring_function_dfp.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search/merge_and_shrink/merge_scoring_function_dfp.cc b/src/search/merge_and_shrink/merge_scoring_function_dfp.cc index 29974d26d..3115d4341 100644 --- a/src/search/merge_and_shrink/merge_scoring_function_dfp.cc +++ b/src/search/merge_and_shrink/merge_scoring_function_dfp.cc @@ -106,7 +106,7 @@ class MergeScoringFunctionDFPFeature MergeScoringFunctionDFPFeature() : TypedFeature("dfp") { document_title("DFP scoring"); document_synopsis( - "This scoring function computes the 'DFP' score as descrdibed in the " + "This scoring function computes the 'DFP' score as described in the " "paper \"Directed model checking with distance-preserving abstractions\" " "by Draeger, Finkbeiner and Podelski (SPIN 2006), adapted to planning in " "the following paper:" + utils::format_conference_reference(