def test_empty_precs_and_effects(): _test_inputs([ ("(and )", "effect"), ("()", "precondition"), ("(and )", "precondition"), ], r=reader()) # This uses one single reader for all tests
def test_effect_free_variables_in_caldera(): instance_file, domain_file = collect_strips_benchmarks(["caldera-opt18-adl:p01.pddl"])[0] problem = reader().read_problem(domain_file, instance_file) act = problem.get_action('get_domain') free = collect_effect_free_parameters(act) names = sorted(x.expr.symbol for x in free) assert names == ['?v00', '?v02'] assert len(act.effects) == 1 free = collect_effect_free_variables(act.effects[0]) names = sorted(x.expr.symbol for x in free) assert names == ['?v01'] projected = project_away_effect_free_variables(act) names1 = sorted(x.symbol for x in act.parameters) names2 = sorted(x.symbol for x in projected.parameters) assert names1 == ['?v00', '?v01', '?v02'] and names2 == ['?v01'] # Check inplace argument works as expected problem2 = project_away_effect_free_variables_from_problem(problem, inplace=False) names1 = sorted(x.symbol for x in problem.get_action('get_domain').parameters) names2 = sorted(x.symbol for x in problem2.get_action('get_domain').parameters) assert names1 == ['?v00', '?v01', '?v02'] and names2 == ['?v01'] problem2 = project_away_effect_free_variables_from_problem(problem, inplace=True) names1 = sorted(x.symbol for x in problem.get_action('get_domain').parameters) names2 = sorted(x.symbol for x in problem2.get_action('get_domain').parameters) assert names1 == names2 == ['?v01']
def _test_inputs(inputs, r=None): """ Test a list of pairs (x, y): x is string to be parsed, y is rule name and return a list with the corresponding outputs of the parser """ r = r or reader() return [_test_input(string, rule, r) for string, rule in inputs]
def test_blocksworld_writing(): problem, _, _, _, table = get_bw_elements() domf, instf = write_problem(problem, domain_constants=[table]) # Make sure that the printed-out problem can be parsed again problem2 = reader().read_problem(domf.name, instf.name) assert len(problem.actions) == len(problem2.actions) # Some silly checks
def test_symbol_declarations(): _test_inputs([ # First rule defines the predicate, necessary for the rest of rules not to raise an "UndefinedPredicate" error ("(at)", "predicate_definition"), ("(at1 ?x)", "predicate_definition"), ("(at5 ?x1 ?x2 ?x3 ?x4 ?x5)", "predicate_definition"), ("(loc1 ?x) - object", "function_definition"), ], r=reader()) # Some additional tests r = reader() problem = r.parse_string("(loc1 ?x) - object", get_rule("function_definition")) lang = problem.language f = lang.get_function("loc1") assert f.codomain == lang.get_sort('object') assert f.domain == (lang.get_sort('object'), )
def _test_inputs(inputs, r=None): """ Test a list of pairs (x, y): x is string to be parsed, y is rule name and return a list with the corresponding outputs of the parser. If no reader `r` is passed, each test is run on a different reader. This might be useful for avoiding duplicate name exceptions, etc, in a sequence of tests. """ return [_test_input(string, rule, r or reader()) for string, rule in inputs]
def test_init(): _test_inputs([ # First rule defines the predicate, necessary for the rest of rules not to raise an "UndefinedPredicate" error ("(at)", "predicate_definition"), ("(at)", "init_atom"), ("(not (at))", "init_atom"), # ("(assign (at))", "init_atom"), ], r=reader())
def check_acyclicity(domain_file, instance_file): problem = reader(case_insensitive=True, strict_with_requirements=False).read_problem( domain_file, instance_file) for a in problem.actions.values(): acyclic = check_hypergraph_acyclicity( compute_schema_constraint_hypergraph(a)) print(f'Action {a.name} is {"acyclic" if acyclic else "cyclic"}.')
def test_cost_function_identification(): problem = generate_fstrips_counters_problem(ncounters=3) functions = identify_cost_related_functions(problem) assert functions == set() instance_file, domain_file = collect_strips_benchmarks(["agricola-opt18-strips:p01.pddl"])[0] problem = reader().read_problem(domain_file, instance_file) functions = identify_cost_related_functions(problem) assert functions == {"group_worker_cost"}
def _setup_predicate_environment(): read = reader() # Set up a few declarations of types objects and functions/predicates _test_inputs([ ("(:types t)", "declaration_of_types"), ("(:constants o1 o2 - t)", "constant_declaration"), ("(p ?o - t)", "predicate_definition"), ], r=read) return read
def _setup_function_environment(theories=None): read = reader(theories=theories) # Set up a few declarations of types objects and functions/predicates _test_inputs([ ("(:types t)", "declaration_of_types"), ("(:constants o1 o2 - t)", "constant_declaration"), ("(f ?o - t) - t", "function_definition"), ], r=read) return read
def test_increase_effects(): output = _test_inputs([ # First rule defines the function, necessary for the rest of rules not to raise some "Undefined" error ("(total-cost) - number", "function_definition"), ("(increase (total-cost) 1)", "effect"), ], r=reader(strict_with_requirements=False)) # This uses one single reader for all tests increase = output[1][0] assert isinstance(increase, FunctionalEffect) and isinstance(increase.condition, Tautology) assert str(increase.rhs) == '+(total-cost(), 1)'
def test_single_atom_goal(): r = reader() _test_inputs([ # First rule defines the predicate, necessary for the rest of rules not to raise an "UndefinedPredicate" error ("(CLEAR ?A - object)", "predicate_definition"), ("(:objects A B C D E)", "object_declaration"), ("(:goal (AND (CLEAR A)))", "goal"), ], r=r) assert isinstance(r.problem.goal, Atom) assert str(r.problem.goal) == "clear(a)"
def compute_acyclicity(instance): instance_file, domain_file = collect_strips_benchmarks([instance])[0] problem = reader(case_insensitive=True).read_problem( domain_file, instance_file) hgraphs = { a.name: compute_schema_constraint_hypergraph(a) for a in problem.actions.values() } return { name: check_hypergraph_acyclicity(h) for name, h in hgraphs.items() }
def test_predicate_effects(): _test_inputs([ # First rule defines the predicate, necessary for the rest of rules not to raise an "UndefinedPredicate" error ("(at)", "predicate_definition"), ("(at)", "effect"), ("(not (at))", "effect"), ("(and (not (at)))", "effect"), ("(and (not (at)) (at) (at))", "effect"), ("(forall (?x) (at))", "effect"), ("(when (not (at)) (at))", "effect"), ("(when (not (at)) (and (at) (at)))", "effect"), ], r=reader()) # This uses one single reader for all tests
def test_formulas(): r = reader() # Test a few names expected to be valid: for domain_name in ["BLOCKS", "blocS-woRlD", "blocks_world"]: tag = "(domain {})".format(domain_name) _ = r.parse_string(tag, get_rule("domain")) # And a few ones expected to be invalid for domain_name in ["BL#OCKS", "@mydomain", "2ndblocksworld", "blocks2.0"]: tag = "(domain {})".format(domain_name) with pytest.raises(ParsingError): _ = r.parse_string(tag, get_rule("domain"))
def test_symbol_casing(): """ Test the special casing for PDDL parsing. See issue #67 """ instance_file, domain_file = collect_strips_benchmarks(["spider-sat18-strips:p01.pddl"])[0] problem = reader().read_problem(domain_file, instance_file) # PDDL parsing represents all symbols in lowercase. The PDDL contains a predicate TO-DEAL, but will get lowercased _ = problem.language.get_predicate("to-deal") with pytest.raises(UndefinedPredicate): _ = problem.language.get_predicate("TO-DEAL") # PDDL predicate current-deal remains unaffected _ = problem.language.get_predicate("current-deal") assert "to-deal" in set(x.symbol for x in get_symbols(problem.language, type_="predicate", include_builtin=False))
def test_effect_free_variables_in_organic_synthesis(): instance_file, domain_file = collect_strips_benchmarks(["organic-synthesis-opt18-strips:p01.pddl"])[0] problem = reader().read_problem(domain_file, instance_file) free = collect_effect_free_parameters(problem.get_action('additionofrohacrossgemdisubstitutedalkene')) names = sorted(x.expr.symbol for x in free) assert names == ['?h_3', '?h_4', '?r0_7', '?r1_8', '?r2_9'] free = collect_effect_free_parameters(problem.get_action('additionofrohacrossmonosubstitutedalkene')) names = sorted(x.expr.symbol for x in free) assert names == ['?h_3', '?h_4', '?h_5', '?r0_8', '?r1_9'] free = collect_effect_free_parameters(problem.get_action('additionofrohacrosstetrasubstitutedalkene')) names = sorted(x.expr.symbol for x in free) assert names == ['?r0_5', '?r1_6', '?r2_7', '?r3_8', '?r4_9'] projected = project_away_effect_free_variables(problem.get_action('additionofrohacrosstetrasubstitutedalkene')) names = sorted(x.symbol for x in projected.parameters) assert names == ['?c_1', '?c_2', '?h_3', '?o_4']
def test_pddl_type_declaration(): r = reader() _test_inputs([ ("type1", "possibly_typed_name_list"), ("type1 type2 type3", "possibly_typed_name_list"), ("type1 - object", "possibly_typed_name_list"), ("type1 type2 type3 - object", "possibly_typed_name_list"), ], r=r) o = _test_input("type1 type2 - object type3 type4 - object type5", "possibly_typed_name_list", r) assert len(o) == 5 and all(parent == 'object' for typename, parent in o) o = _test_input("t t t t", "possibly_typed_name_list", r) assert len(o) == 4 and all(parent == 'object' for typename, parent in o) o = _test_input("t t t t - t", "possibly_typed_name_list", r) assert len(o) == 4 and all(parent == 't' for typename, parent in o) o = _test_input("t t t t - t t2 t3", "possibly_typed_name_list", r) assert len(o) == 6 and len(list(filter(lambda x: x == 'object', (parent for _, parent in o)))) == 2
def test_lp_on_caldera(): instance_file, domain_file = collect_strips_benchmarks( ["caldera-sat18-adl:p01.pddl"])[0] problem = reader().read_problem(domain_file, instance_file) lp, tr = create_reachability_lp(problem, ground_actions=True)