diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index a6a5d45ee4..00df07d298 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 0000000000..803516bf3a --- /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 f003517ac0..67f96da0e3 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 7d8177ba14..6adeaa7675 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 00a53b311c..dc39aa00e1 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 11725c44e1..ed3e66b625 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 50fc870a89..ef0081674e 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 93f6629633..f64ef3537f 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 69fe4f519a..ec6a7baa1c 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 2a852392f5..8de4f82fce 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 de68ceb601..7f9a0b980f 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 4fa9c0a4ab..d489b7e0f6 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 2ee4089fc1..34e4ec27b5 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 c14fa8e94b..cb2f174fc7 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 c97e1712f3..6fb87c64ce 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 be085c5e87..43e30d008a 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 fadadaa7fc..6509624358 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 7aa1d86f51..d6fd893ffe 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 4f990ab802..49088cb29a 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 dbcfc5d1cb..19523c021c 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 a2745f8ac9..6b4fecce60 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 b1b0b27902..70919d26a2 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 441b806ac9..5f6e7fae6b 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 f634d02105..6af8a0c02d 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 0b2edfdcdf..eb986550af 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 fda1fa4ddf..68a9dbce66 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 94c0e405b6..b413afd8aa 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 57c5fb9150..011101e70e 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 31a362e801..7c48b9ac10 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 80c96f0207..edfdf769b1 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 9030deb64e..251910fec5 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 12e0770851..379f31b734 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 b12ac3c87f..c86abc432b 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 fe2d5d42ba..ae30961251 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 b528551c58..36fe4fb596 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 44f668f457..9b88be0047 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 da05b84f7d..4233cd4c48 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 7033760274..5b1547c71f 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 822940e66d..2479136d34 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 06ca91d1ea..87e43da766 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 6b491451c2..5da1623e9b 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 3ec02aedb4..c7d738f634 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 c782fee62f..683d118022 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 5a7cad2ecf..86fa6a3893 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 e93f0b7ec6..38fd55f21b 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 202157a63b..cba4b55818 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 aeb2016815..0b6990ad81 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 b092ac2561..ad0379b458 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 34e091270e..2ad7acdf9b 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 d06434bd91..fe57ebba22 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 8fe81d1bb9..ea8c5e6502 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 a658876d45..76b967d164 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 1f0c3cba53..40051ec2fd 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 7351795509..9ab122d308 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 21aa2157a7..7504a08f53 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 8e50c66f42..be9ea54fe4 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 fe446d2c7a..a66524ce8f 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 cd08edff54..be64e867cd 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 40ddf15d49..8df5978aa5 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 2258f6bc61..35d329c7ea 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 2894b41a30..621b015cc1 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 d8a411faab..9323075cc0 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 f67fb9a3b2..d838480ecf 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 06556d9e1d..f4abb84e5e 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 3469c0c1a1..f298d7e37c 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 01758afd49..7b85bba000 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 0b641a946a..63518d1c73 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 63ca4fe14a..813c6862ae 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 51e5d79579..462cb936ae 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 7107893565..0c2749bf9a 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 97a5e6b7da..813c02cd9b 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 9922974fd7..bd86bc0c92 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 349fac8954..f40484032f 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 dbc1569a3f..97e1825378 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 c37b08f3fb..b03c119a13 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 5818439188..1cdab0128d 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 ac687a56b2..bcfd4ae587 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 c47af5b090..268d552afd 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 9f34d3d520..80e63b4b82 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 a9bdff8c0a..59693ffeab 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 9e4ac0a45d..1b113ab6a4 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 f837cc244b..ff94281afd 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 c1037f7df5..7b678a7663 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 24285dcdef..07f0603072 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 c35f251c93..50940d84d6 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 701c0144d7..2f1f5f63fc 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 7b745ce8dc..29974d26de 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 f2de9cbee8..dff7ba5afb 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 f92fdc5535..75e315b80f 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 a1dceffa3d..99c33a2abb 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 7d5042abc6..7fe4f16622 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 3070085ed0..a35e8877ab 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 90e0eaf9bf..113441c5bc 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 d2e7625443..285cf1fff5 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 8b26a37db6..926409ee1e 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 41d3386338..3d2e974da8 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 772378a889..32c608eafc 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 71a1c3a885..58009e3c8e 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 5858363e96..e3bf5083e8 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 004f7db51b..9f1f5a93a2 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 b087a7d4ce..0bc66dbd37 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 e31fc7eadf..4e5a308d3f 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 2d9dd9ef9f..89fdb3d7b7 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 a08fe75351..14816c4749 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 87dfd8b5e0..81c49398ea 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 037cc9c0c8..5f50ae3307 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 c56279719e..93acfc06ff 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 1c98e0fe4f..cf6c3b896f 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 6a705c75bb..8b30105092 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 b88e8f5f72..516ba2e2d2 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 683a06948b..34f9607072 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 172e45923d..58a023ec44 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 f490421728..0465f23c53 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 749b8f7e46..46caaf74ae 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 6a334cfd52..d2846891c0 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 ff5214a5bf..5ebaac8e1b 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 7b05ab05d2..9b504a8045 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 19ee694b5b..92592ce544 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 8e89087f47..7da73c3c9d 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 ed0ab806b7..c8d436550a 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 6518d0340a..69565583b6 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 ab9cef95b5..edcd3e2af8 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 eda66c79bd..328d96de8b 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 812f55ab94..f0f95ecdb0 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 087ad28083..026020cf30 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 32e99de4fb..a72c34684f 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 711fe2a221..f6c75a3b6d 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 e7a0f1f4f1..d1771e8ef1 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 21f01785af..9811af17e6 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 abdb37faab..76a1e50a82 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 72cf0c717c..858eaa11b0 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 2aa5d0b771..5f81a3bd8e 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 cd1d708a0e..b2e45be109 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 f8837a5a78..be6d0942cd 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 6890d0c2ae..b5f62452a9 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 7adfb543e9..dab21c8b29 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 c2e873f33b..ad7cd47269 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 a844b377bb..0ebe47e856 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 ff0b326039..b7d8ef2b0d 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 72ccacc876..27b512b193 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 7a4b861f20..696bb59aba 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 ca685da232..675e347093 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 471f9bbec4..7d2c42e72b 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 fa7e5b37ac..74f82da891 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 3ef85cf5a2..e796b42a32 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 c428ba9820..2969fdf7a2 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 9557463263..88178481ac 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 57623150e0..4e107ef2d2 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 ce7d5fb089..e24e04eedc 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 58a44f5425..a767122610 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 5622588ee2..32ac888bad 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 4c4cf4c78a..59eb156c0b 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 672eceaf4a..f1c1bc8df7 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 322587b8f6..9b3191ea93 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 d9cf02097e..471bddde9f 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 4b642252da..3499f726f3 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 92ed1d92f9..91fc823d61 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 6e8ea1cfb7..80cb6b16ab 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 dfd31e1d9a..1d6c3d5b84 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 9ed1be1956..27be32d970 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 b6d9aaa37b..a2e9b6d40f 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 ad5b749334..d020e4c46c 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 ccc51adc8d..fc7a05f261 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 3cc412a6bb..d5c6d2aa16 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 8f483104c4..0db2bf98f3 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 f64751674d..ca233eaca7 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 a9b6b6fc4c..2dd22cbfba 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 9bea9e0a6f..b589d400bc 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 6a8a7be03c..7a0066a144 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 2698930bee..02b46a53f1 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 8bb9d70557..daf9d7de61 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 4a177be771..b4b122e1a8 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 4f979ecb2f..1152a06cd1 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 757344a407..35eae18d02 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 b7081da0a4..8b50d4576c 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 edf5f14476..484e4d2eba 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 721e3a433c..4d5f8e98b5 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 3a71d98326..ad1165d21d 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 bd420595ee..036bc8eaea 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 ee5191b8f0..da8f53de6c 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 21e246bbdd..b52ce23b5b 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 b3b396b863..6092a35d9e 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 2bfba4fc4e..7217c2b227 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 4069f9e8e5..eee0ad9285 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 4c4377214d..c54526aec4 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 387788a44b..d47528f3b1 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 912f4fab11..bd00caf72a 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 66c5737328..fd095ee5c6 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 e6eb2e2df0..43479baa26 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 fe5dca83d5..cea876ad70 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 e116965595..dfe2184c25 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 b9500fd089..fbe97a47ef 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 4929e72e67..98624779f2 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 d656d3354a..41b30e7b5f 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 2a2f29016d..51cba6b4e4 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 557fb2b647..11b4c89d7f 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 1aa285da35..5102b80168 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 acd93092cb..3f857dd872 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 9d1a65ae88..78005aebe5 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 a5841d3f4b..402395ddec 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 23c5a21172..e0871a4fda 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 b859a95684..cde64cfb45 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 302c52fbdc..5d52fc0927 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 95c364bb1d..091fc25d30 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 aee27e142f..f58e4bf378 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 5cc6e0c3c9..8ac60024bb 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 eb95a3daf4..5fc2123d7b 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 5f9db288e7..2a6d8366b8 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 519761d0bb..1c2a3e060c 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 531f3771ab..11f7521d74 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 ee9f30811f..c018c45c65 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 32cbb6c86e..29103c7b0f 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 74a91808bc..5ec760e577 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 fcd9399adf..bb328e1fc7 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 73509fe9dc..3899753adb 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 f6f4c23034..f7b3247dfd 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 fc7ea7bb7b..83f66890bd 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 e63ee6d978..3c5ac25ebe 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 0b1b4abd4e..d5ddf84d01 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 6db6e67725..b174d3801c 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 f07ff2ba2b..ac91f82668 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 84eb964ba1..dcbbd3b347 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 a1809993a8..db005c73e7 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 c95bbd390b..0a0ec615ac 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 edc9672e46..f0a3682e85 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 e5bea2cf84..258c000ce1 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 ddec9152a2..742947961f 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 34666636b2..249ced228d 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 4046a879f0..3e7d2996c9 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 4ef9f85ef8..a0227e9bb9 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 b2950bbe8c..c3679b4f5e 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 56d5a21bba..deb761f145 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 c25bd478b9..d01df4b55f 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 0000000000..77b093e36a --- /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