def test_extract_plan(): op1 = Operator("op1", [], ["a"], []) op2 = Operator("op2", ["a"], ["b"], []) op3 = Operator("op3", ["a", "b"], ["c"], []) op4 = Operator("op4", [], ["a", "b"], []) expected = [ (["not-a-0", "a-1"], [op1], [op1]), (["not-a-0", "a-1", "b-0", "b-1"], [op1, op2], [op1]), ( ["not-a-0", "a-1", "not-b-0", "not-b-1", "a-2", "b-2"], [op1, op2], [op1, op2], ), ([], [op1], []), ( [ "a-0", "not-b-0", "not-c-0", "a-1", "b-1", "not-c-1", "a-2", "b-2", "c-2" ], [op1, op2, op3], [op2, op3], ), (["not-a-0, not-b-0", "a-1", "b-1"], [op1, op4], [op4]), ] for valuation, operators, plan in expected: extracted_plan = sat._extract_plan(operators, valuation) assert extracted_plan == plan
def test_compute_landmark_costs(): op1 = Operator('op1', set(), {'A', 'C'}, set()) op2 = Operator('op2', set(), {'B', 'C'}, set()) op3 = Operator('op3', set(), {'D'}, set()) task = Task('task1', set(), set(), set(), [op1, op2, op3]) costs = landmarks.compute_landmark_costs(task, ['A', 'C', 'D']) print(costs) expected = {'A': 0.5, 'C': 0.5, 'D': 1} assert expected == costs
def test_compute_landmark_costs(): op1 = Operator("op1", set(), {"A", "C"}, set()) op2 = Operator("op2", set(), {"B", "C"}, set()) op3 = Operator("op3", set(), {"D"}, set()) task = Task("task1", set(), set(), set(), [op1, op2, op3]) costs = landmarks.compute_landmark_costs(task, ["A", "C", "D"]) print(costs) expected = {"A": 0.5, "C": 0.5, "D": 1} assert expected == costs
def _get_simple_task(): """ Task with a goal with two facts and an operator with no effect. """ op1 = Operator("op1", {"var1"}, {"var2"}, set()) op2 = Operator("op2", {"var1"}, set(), set()) op3 = Operator("op3", {"var2"}, {"var1"}, set()) init = frozenset(["var1"]) goals = frozenset(["var1", "var2"]) task1 = Task("task1", {"var1", "var2", "var3"}, init, goals, [op1, op2, op3]) return task1
def _get_simple_task_unsolvable(): """ Unsolvable task. """ op1 = Operator("op1", {"var1"}, {"var2"}, set()) op2 = Operator("op2", {"var1"}, set(), set()) op3 = Operator("op3", {"var2"}, {"var1"}, set()) init = frozenset(["var1"]) goals = frozenset(["var1", "var3"]) task1 = Task("task1", {"var1", "var2", "var3"}, init, goals, [op1, op2, op3]) return task1
def _get_simple_task_at_goal(): """ Goal is already reached in the initial state. """ op1 = Operator("op1", {"var1"}, {"var2"}, set()) op2 = Operator("op2", {"var1"}, set(), set()) op3 = Operator("op3", {"var2"}, {"var1"}, set()) init = frozenset(["var1"]) goals = frozenset(["var1"]) task1 = Task("task1", {"var1", "var2", "var3"}, init, goals, [op1, op2, op3]) return task1
def _get_simple_task_always_true(): """ Simple test task with one operator needed. """ op1 = Operator("op1", {}, {"var2"}, set()) op2 = Operator("op2", {"var1"}, set(), set()) op3 = Operator("op3", {"var2"}, {"var1"}, set()) init = frozenset(["var1"]) goals = frozenset(["var1", "var2"]) task1 = Task("task1", {"var1", "var2", "var3"}, init, goals, [op1, op2, op3]) return task1
def _get_simple_task(): """ Task with a goal with two facts and an operator with no effect. """ op1 = Operator('op1', {'var1'}, {'var2'}, set()) op2 = Operator('op2', {'var1'}, set(), set()) op3 = Operator('op3', {'var2'}, {'var1'}, set()) init = frozenset(['var1']) goals = frozenset(['var1', 'var2']) task1 = Task('task1', {'var1', 'var2', 'var3'}, init, goals, [op1, op2, op3]) return task1
def _get_simple_task_unsolvable(): """ Unsolvable task. """ op1 = Operator('op1', {'var1'}, {'var2'}, set()) op2 = Operator('op2', {'var1'}, set(), set()) op3 = Operator('op3', {'var2'}, {'var1'}, set()) init = frozenset(['var1']) goals = frozenset(['var1', 'var3']) task1 = Task('task1', {'var1', 'var2', 'var3'}, init, goals, [op1, op2, op3]) return task1
def _get_simple_task_at_goal(): """ Goal is already reached in the initial state. """ op1 = Operator('op1', {'var1'}, {'var2'}, set()) op2 = Operator('op2', {'var1'}, set(), set()) op3 = Operator('op3', {'var2'}, {'var1'}, set()) init = frozenset(['var1']) goals = frozenset(['var1']) task1 = Task('task1', {'var1', 'var2', 'var3'}, init, goals, [op1, op2, op3]) return task1
def _get_simple_task_always_true(): """ Simple test task with one operator needed. """ op1 = Operator('op1', {}, {'var2'}, set()) op2 = Operator('op2', {'var1'}, set(), set()) op3 = Operator('op3', {'var2'}, {'var1'}, set()) init = frozenset(['var1']) goals = frozenset(['var1', 'var2']) task1 = Task('task1', {'var1', 'var2', 'var3'}, init, goals, [op1, op2, op3]) return task1
def test_relaxation_heuristic_constructor(): op1 = Operator("op1", {"A"}, {"B"}, set()) op2 = Operator("op2", {"B"}, {"C"}, set()) init = frozenset(["A"]) goals = frozenset(["C"]) task = Task("task1", {"A", "B", "C"}, init, goals, [op1, op2]) rh = hAddHeuristic(task) rop1 = RelaxedOperator(op1.name, ["A"], ["B"]) assert len(rh.operators) == 2 assert len(rh.facts) == 3 assert rh.facts["A"].precondition_of[0].name == rop1.name
def test_relaxation_heuristic_constructor(): op1 = Operator('op1', {'A'}, {'B'}, set()) op2 = Operator('op2', {'B'}, {'C'}, set()) init = frozenset(['A']) goals = frozenset(['C']) task = Task('task1', {'A', 'B', 'C'}, init, goals, [op1, op2]) rh = hAddHeuristic(task) rop1 = RelaxedOperator(op1.name, ['A'], ['B']) assert (len(rh.operators) == 2) assert (len(rh.facts) == 3) assert (rh.facts['A'].precondition_of[0].name == rop1.name)
def _create_operator(action, assignment, statics, init): """Create an operator for "action" and "assignment". Statics are handled here. True statics aren't added to the precondition facts of a grounded operator. If there is a false static in the ungrounded precondition, the operator won't be created. @param assignment: mapping from predicate name to object name """ precondition_facts = set() for precondition in action.precondition: fact = _ground_atom(precondition, assignment) predicate_name = precondition.name if predicate_name in statics: # Check if this precondition is false in the initial state if fact not in init: # This precondition is never true -> Don't add operator return None else: # This precondition is not always true -> Add it precondition_facts.add(fact) add_effects = _ground_atoms(action.effect.addlist, assignment) del_effects = _ground_atoms(action.effect.dellist, assignment) # If the same fact is added and deleted by an operator the STRIPS formalism # adds it. del_effects -= add_effects # If a fact is present in the precondition, we do not have to add it. # Note that if a fact is in the delete and in the add effects, # it has already been deleted in the previous step. add_effects -= precondition_facts args = [assignment[name] for name, types in action.signature] name = _get_grounded_string(action.name, args) return Operator(name, precondition_facts, add_effects, del_effects)
def test_extract_plan(): op1 = Operator('op1', [], ['a'], []) op2 = Operator('op2', ['a'], ['b'], []) op3 = Operator('op3', ['a', 'b'], ['c'], []) op4 = Operator('op4', [], ['a', 'b'], []) expected = [(['not-a-0', 'a-1'], [op1], [op1]), (['not-a-0', 'a-1', 'b-0', 'b-1'], [op1, op2], [op1]), (['not-a-0', 'a-1', 'not-b-0', 'not-b-1', 'a-2', 'b-2'], [op1, op2], [op1, op2]), ([], [op1], []), ([ 'a-0', 'not-b-0', 'not-c-0', 'a-1', 'b-1', 'not-c-1', 'a-2', 'b-2', 'c-2' ], [op1, op2, op3], [op2, op3]), (['not-a-0, not-b-0', 'a-1', 'b-1'], [op1, op4], [op4])] for valuation, operators, plan in expected: extracted_plan = sat._extract_plan(operators, valuation) yield assert_equal, extracted_plan, plan
def _create_operator(action, assignment, statics, init): """Create an operator for "action" and "assignment". Statics are handled here. True statics aren't added to the precondition facts of a grounded operator. If there is a false static in the ungrounded precondition, the operator won't be created. @param assignment: mapping from predicate name to object name """ precondition_facts = set() #print('SARAH action:') #print(action) for precondition in action.precondition: #print('SARAH: precondition is ') #print(precondition) fact = _ground_atom(precondition, assignment) #print('fact is:' ) #print(fact) #print(' precondition is rather') #print(precondition) is_postive = True if 'False' in precondition.__str__(): is_postive = False #print('is_positive') #print(is_postive) predicate_name = precondition.name if predicate_name in statics: if is_postive: # Check if this precondition is false in the initial state if fact not in init: # This precondition is never true -> Don't add operator return None # if the precondition is a negative one - we verify it does not exists in the initial state else: # Check if this precondition is in the initial state if fact in init: # This precondition is never true -> Don't add operator return None else: # This precondition is not always true -> Add it precondition_facts.add(fact+'='+str(is_postive)) add_effects = _ground_atoms(action.effect.addlist, assignment) del_effects = _ground_atoms(action.effect.dellist, assignment) # If the same fact is added and deleted by an operator the STRIPS formalism # adds it. del_effects -= add_effects # If a fact is present in the precondition, we do not have to add it. # Note that if a fact is in the delete and in the add effects, # it has already been deleted in the previous step. add_effects -= precondition_facts args = [assignment[name] for name, types in action.signature] name = _get_grounded_string(action.name, args) return Operator(name, precondition_facts, add_effects, del_effects)
def _get_intermediate_task2(): """ Intermediate task """ op1 = Operator('op1', {'v1'}, {'v2'}, set()) op2 = Operator('op2', {'v2'}, {'v3'}, set()) op3 = Operator('op3', {'v3'}, {'v4', 'v5'}, set()) op4 = Operator('op4', {'v7', 'v5'}, {'g'}, set()) op7 = Operator('op7', {'v4'}, {'v7'}, set()) op5 = Operator('op5', {'v2'}, {'v6'}, set()) op6 = Operator('op6', {'v6'}, {'v5'}, set()) init = frozenset(['v1']) goals = frozenset(['g']) task1 = Task('task1', {'v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'g'}, init, goals, [op1, op2, op3, op4, op5, op6, op7]) return task1
def mme_search(search, heuristic, explained_plan, m_r: Task, m_h: Task): eps_mme = [] fringe = PrioQueue(search, heuristic, explained_plan) c_list = [] h_list = [] fringe.push((m_r, []), 0) m_hat = m_h while len(fringe) != 0: x, c = fringe.pop(m_hat) m_hat, eps = x m_hat_optimal = search_plan(m_hat, search, heuristic) if m_hat_optimal is None or not is_plan_applicable( explained_plan, m_hat) or len(explained_plan) > len(m_hat_optimal): h_list.append(m_hat.get_gamma() ^ m_r.get_gamma()) else: c_list.append(m_hat.get_gamma()) for f in m_hat.get_gamma() - m_h.get_gamma(): lamb = Operator("del-{}".format(f), m_hat.get_gamma(), {}, {f}) new_gamma = lamb.apply(m_hat.get_gamma()) if new_gamma not in c_list: sym_diff = m_hat.get_gamma() ^ m_r.get_gamma() prop3_violated = False for s in subsets(sym_diff): if s in h_list: prop3_violated = True break if not prop3_violated: fringe.push((Task.from_gamma(new_gamma), eps + [lamb]), c + 1) if len(eps) > len(eps_mme): eps_mme = eps for f in m_h.get_gamma() - m_hat.get_gamma(): lamb = Operator("add-{}".format(f), m_hat.get_gamma(), {f}, {}) new_gamma = lamb.apply(m_hat.get_gamma()) if new_gamma not in c_list: sym_diff = m_hat.get_gamma() ^ m_r.get_gamma() prop3_violated = False for s in subsets(sym_diff): if s in h_list: prop3_violated = True break if not prop3_violated: fringe.push((Task.from_gamma(new_gamma), eps + [lamb]), c + 1) if len(eps) > len(eps_mme): eps_mme = eps print(m_hat.get_gamma() ^ m_r.get_gamma()) return explained_plan, eps_mme
def _get_intermediate_task(): """ Intermediate test task with four operators needed. """ op1 = Operator('op1', {'v1'}, {'v2'}, set()) op2 = Operator('op2', {'v2'}, {'v3'}, set()) op3 = Operator('op3', {'v3'}, {'v4', 'v5'}, set()) op4 = Operator('op4', {'v4', 'v5'}, {'g'}, set()) op5 = Operator('op5', {'v2'}, {'v6'}, set()) op6 = Operator('op6', {'v6'}, {'v5'}, set()) init = frozenset(['v1']) goals = frozenset(['g']) task1 = Task('task1', {'v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'g'}, init, goals, [op1, op2, op3, op4, op5, op6]) return task1
def _get_intermediate_task2(): """ Intermediate task """ op1 = Operator("op1", {"v1"}, {"v2"}, set()) op2 = Operator("op2", {"v2"}, {"v3"}, set()) op3 = Operator("op3", {"v3"}, {"v4", "v5"}, set()) op4 = Operator("op4", {"v7", "v5"}, {"g"}, set()) op7 = Operator("op7", {"v4"}, {"v7"}, set()) op5 = Operator("op5", {"v2"}, {"v6"}, set()) op6 = Operator("op6", {"v6"}, {"v5"}, set()) init = frozenset(["v1"]) goals = frozenset(["g"]) task1 = Task( "task1", {"v1", "v2", "v3", "v4", "v5", "v6", "v7", "g"}, init, goals, [op1, op2, op3, op4, op5, op6, op7], ) return task1
def mce_search(search, heuristic, explained_plan, m_r: Task, m_h: Task): c_list = [] # Closed list p_r = explained_plan fringe = PrioQueue(search, heuristic, explained_plan) fringe.push((m_h, []), 0) m_hat = m_h i = 0 print(m_r) while True: print(i) i += 1 print("Popping") x, c = fringe.pop(m_hat) m_hat, eps = x print("Checking plan optimality") p_h = search_plan(m_hat, search, heuristic) if is_plan_optimal(p_r, m_hat, p_h): return p_r, eps else: c_list.append(m_hat.get_gamma()) for f in m_hat.get_gamma() - m_r.get_gamma(): print("Fact to be removed:", f) lamb = Operator("del-{}".format(f), m_hat.get_gamma(), {}, {f}) new_gamma = lamb.apply(m_hat.get_gamma()) if new_gamma not in c_list: fringe.push((Task.from_gamma(new_gamma), eps + [lamb]), c + 1) else: print("In c_list !") print("Robot gamma:", m_r.get_gamma(), "\nExplored gamma: ", m_hat.get_gamma(), "\nG(Mr) \\ G(Mh):", m_r.get_gamma() - m_hat.get_gamma()) for f in m_r.get_gamma() - m_hat.get_gamma(): print("fact to be added: ", f) lamb = Operator("add-{}".format(f), m_hat.get_gamma(), {f}, {}) new_gamma = lamb.apply(m_hat.get_gamma()) if new_gamma not in c_list: fringe.push((Task.from_gamma(new_gamma), eps + [lamb]), c + 1) #print(Task.from_gamma(new_gamma)) else: print("In c_list !")
def _get_intermediate_task(): """ Intermediate test task with four operators needed. """ op1 = Operator("op1", {"v1"}, {"v2"}, set()) op2 = Operator("op2", {"v2"}, {"v3"}, set()) op3 = Operator("op3", {"v3"}, {"v4", "v5"}, set()) op4 = Operator("op4", {"v4", "v5"}, {"g"}, set()) op5 = Operator("op5", {"v2"}, {"v6"}, set()) op6 = Operator("op6", {"v6"}, {"v5"}, set()) init = frozenset(["v1"]) goals = frozenset(["g"]) task1 = Task( "task1", {"v1", "v2", "v3", "v4", "v5", "v6", "g"}, init, goals, [op1, op2, op3, op4, op5, op6], ) return task1
def test_heuristics(): # simple task: two operators have to be applied task1 = Task( "task1", {"A", "B", "C"}, frozenset({"A"}), frozenset({"C", "B"}), [ Operator("op1", {"A"}, {"B"}, set()), Operator("op2", {"B"}, {"C"}, set()), Operator("op3", {"B"}, {"A"}, set()), ], ) # initial state is part of the goal state: one operator has to be applied task2 = Task( "task2", {"A", "B", "C"}, frozenset(["A", "B"]), frozenset(["B", "C"]), [ Operator("op1", {"A"}, {"B"}, set()), Operator("op2", {"B"}, {"C"}, set()) ], ) # task with one operator with two preconditions task3 = Task( "task3", {"A", "B", "C"}, frozenset(["A", "B"]), frozenset(["C"]), [Operator("op1", {"A", "B"}, {"C"}, set())], ) # task with one operator with two effects task4 = Task( "task4", {"A", "B", "C"}, frozenset(["A"]), frozenset(["C", "B"]), [Operator("op1", {"A"}, {"B", "C"}, set())], ) # task with one operator with equal precondition and effect, task4b = Task( "task4b", {"A", "B", "C"}, frozenset(["A"]), frozenset(["C", "B"]), [Operator("op1", {"A"}, {"A", "B", "C"}, set())], ) # task with one operator with several effects, # 2 operators have to be applied task5 = Task( "task5", {"A", "B", "C", "D", "E", "F"}, ["A"], ["E", "F"], [ Operator("op1", {"A"}, {"B", "C", "D", "E"}, set()), Operator("op2", {"C"}, {"F"}, set()), ], ) # task with one operator with several preconditions task6 = Task( "task6", {"A", "B", "C", "D", "E"}, ["A"], ["E"], [ Operator("op1", {"A"}, {"B"}, set()), Operator("op2", {"B"}, {"C"}, set()), Operator("op3", {"A"}, {"D"}, set()), Operator("op4", {"A", "C", "B", "D"}, {"E"}, set()), ], ) # task with empty initial state: no operator can be applied task7 = Task( "task7", {"A", "B", "C"}, [], ["C"], [ Operator("op1", {"A"}, {"B"}, set()), Operator("op2", {"B"}, {"C"}, set()) ], ) # task with initial state = goal state: no operator has to be applied task8 = Task( "task8", {"A", "B", "C"}, ["C"], ["C"], [ Operator("op1", {"A"}, {"B"}, set()), Operator("op2", {"B"}, {"C"}, set()) ], ) # task with operator with empty precondition task9 = Task( "task9", {"A", "B", "C"}, [], ["C"], [ Operator("op1", {}, {"B"}, set()), Operator("op2", {"B"}, {"C"}, set()) ], ) # a more complex task task10 = Task( "task10", {"v1", "v2", "v3", "v4", "v5", "v6", "g"}, ["v1"], ["g"], [ Operator("op1", {"v1"}, {"v2"}, set()), Operator("op2", {"v2"}, {"v3"}, set()), Operator("op3", {"v3"}, {"v4", "v5"}, set()), Operator("op4", {"v4", "v5"}, {"g"}, set()), Operator("op5", {"v2"}, {"v6"}, set()), Operator("op6", {"v6"}, {"v5"}, set()), ], ) # another complex task task12 = Task( "task12", {"A", "B", "C", "D", "E", "F", "G", "H", "I"}, ["A", "B"], ["F", "G", "H"], [ Operator("op1", {"A"}, {"C"}, set()), Operator("op2", {"C", "D"}, {"F"}, set()), Operator("op3", {"D", "E"}, {"G", "H"}, set()), Operator("op4", {"B"}, {"D", "E"}, set()), Operator("op5", {"I"}, {"H"}, set()), ], ) # task with no goal: task13 = Task( "task13", {"A", "B", "C"}, ["A", "B"], [], [Operator("op1", {"A", "B"}, {"C"}, set())], ) # task with no reachable goal: task14 = Task( "task14", {"A", "B", "C"}, ["A"], ["B", "C"], [Operator("op1", {"A"}, {"B"}, set())], ) # columns: landmarks lm_costs h expected = [ (task1, {"B", "C"}, { "B": 1, "C": 1 }, 2), (task2, {"B", "C"}, { "B": 1, "C": 1 }, 1), (task3, {"C"}, { "C": 1 }, 1), (task4, {"B", "C"}, { "B": 0.5, "C": 0.5 }, 1), ] for task, expected_landmarks, expected_lmc, exptected_h in expected: assert landmarks.get_landmarks(task) == expected_landmarks assert (landmarks.compute_landmark_costs( task, expected_landmarks) == expected_lmc) assert (landmarks.LandmarkHeuristic(task)(make_root_node( task.initial_state)) == exptected_h)
""" Tests for the task.py module """ import py from task import Task, Operator s1 = frozenset(['var1']) s2 = frozenset(['var2']) s3 = frozenset(['var1', 'var2']) op1 = Operator('op1', {'var1'}, {'var2'}, set()) op2 = Operator('op1', {'var1'}, set(), set()) op3 = Operator('op1', {'var2'}, {'var1'}, set()) # Operator that makes var2 true and false op4 = Operator('op1', {'var1'}, {'var2'}, {'var2'}) init = frozenset(['var1']) goals = frozenset(['var1', 'var2']) task1 = Task('task1', {'var1', 'var2', 'var3'}, init, goals, [op1, op2, op3]) def test_op_applicable1(): assert op1.applicable(s1) def test_op_applicable2(): assert not op1.applicable(s2) def test_op_applicable3():
def test_relaxed_task(): op1 = Operator('op1', {'A'}, {'A', 'C'}, {'B', 'C'}) task = Task('task1', set(), set(), set(), [op1]) relaxed_task = landmarks._get_relaxed_task(task) assert len(relaxed_task.operators[0].del_effects) == 0
def test_landmarks1(): op1 = Operator('op1', set(), {'A'}, set()) op2 = Operator('op2', {'A'}, {'B'}, set()) task = Task('task1', {'A', 'B'}, set(), {'B'}, [op1, op2]) assert landmarks.get_landmarks(task) == {'A', 'B'}
def test_heuristics(): # simple task: two operators have to be applied task1 = Task('task1', {'A', 'B', 'C'}, frozenset({'A'}), frozenset({'C', 'B'}), [ Operator('op1', {'A'}, {'B'}, set()), Operator('op2', {'B'}, {'C'}, set()), Operator('op3', {'B'}, {'A'}, set()) ]) # initial state is part of the goal state: one operator has to be applied task2 = Task('task2', {'A', 'B', 'C'}, frozenset(['A', 'B']), frozenset(['B', 'C']), [ Operator('op1', {'A'}, {'B'}, set()), Operator('op2', {'B'}, {'C'}, set()) ]) # task with one operator with two preconditions task3 = Task('task3', {'A', 'B', 'C'}, frozenset(['A', 'B']), frozenset(['C']), [Operator('op1', {'A', 'B'}, {'C'}, set())]) # task with one operator with two effects task4 = Task('task4', {'A', 'B', 'C'}, frozenset(['A']), frozenset(['C', 'B']), [Operator('op1', {'A'}, {'B', 'C'}, set())]) # task with one operator with equal precondition and effect, task4b = Task('task4b', {'A', 'B', 'C'}, frozenset(['A']), frozenset(['C', 'B']), [Operator('op1', {'A'}, {'A', 'B', 'C'}, set())]) # task with one operator with several effects, # 2 operators have to be applied task5 = Task('task5', {'A', 'B', 'C', 'D', 'E', 'F'}, ['A'], ['E', 'F'], [ Operator('op1', {'A'}, {'B', 'C', 'D', 'E'}, set()), Operator('op2', {'C'}, {'F'}, set()) ]) # task with one operator with several preconditions task6 = Task('task6', {'A', 'B', 'C', 'D', 'E'}, ['A'], ['E'], [ Operator('op1', {'A'}, {'B'}, set()), Operator('op2', {'B'}, {'C'}, set()), Operator('op3', {'A'}, {'D'}, set()), Operator('op4', {'A', 'C', 'B', 'D'}, {'E'}, set()) ]) # task with empty initial state: no operator can be applied task7 = Task('task7', {'A', 'B', 'C'}, [], ['C'], [ Operator('op1', {'A'}, {'B'}, set()), Operator('op2', {'B'}, {'C'}, set()) ]) # task with initial state = goal state: no operator has to be applied task8 = Task('task8', {'A', 'B', 'C'}, ['C'], ['C'], [ Operator('op1', {'A'}, {'B'}, set()), Operator('op2', {'B'}, {'C'}, set()) ]) # task with operator with empty precondition task9 = Task('task9', {'A', 'B', 'C'}, [], ['C'], [ Operator('op1', {}, {'B'}, set()), Operator('op2', {'B'}, {'C'}, set()) ]) # a more complex task task10 = Task('task10', {'v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'g'}, ['v1'], ['g'], [ Operator('op1', {'v1'}, {'v2'}, set()), Operator('op2', {'v2'}, {'v3'}, set()), Operator('op3', {'v3'}, {'v4', 'v5'}, set()), Operator('op4', {'v4', 'v5'}, {'g'}, set()), Operator('op5', {'v2'}, {'v6'}, set()), Operator('op6', {'v6'}, {'v5'}, set()) ]) # another complex task task12 = Task('task12', {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'}, ['A', 'B'], ['F', 'G', 'H'], [ Operator('op1', {'A'}, {'C'}, set()), Operator('op2', {'C', 'D'}, {'F'}, set()), Operator('op3', {'D', 'E'}, {'G', 'H'}, set()), Operator('op4', {'B'}, {'D', 'E'}, set()), Operator('op5', {'I'}, {'H'}, set()) ]) # task with no goal: task13 = Task('task13', {'A', 'B', 'C'}, ['A', 'B'], [], [Operator('op1', {'A', 'B'}, {'C'}, set())]) # task with no reachable goal: task14 = Task('task14', {'A', 'B', 'C'}, ['A'], ['B', 'C'], [Operator('op1', {'A'}, {'B'}, set())]) # columns: landmarks lm_costs h expected = [ (task1, {'B', 'C'}, { 'B': 1, 'C': 1 }, 2), (task2, {'B', 'C'}, { 'B': 1, 'C': 1 }, 1), (task3, {'C'}, { 'C': 1 }, 1), (task4, {'B', 'C'}, { 'B': 0.5, 'C': 0.5 }, 1), ] for task, expected_landmarks, expected_lmc, exptected_h in expected: assert landmarks.get_landmarks(task) == expected_landmarks assert landmarks.compute_landmark_costs( task, expected_landmarks) == expected_lmc assert landmarks.LandmarkHeuristic(task)(make_root_node( task.initial_state)) == exptected_h
def test_collect_facts(): op1 = Operator("op1", {"var1"}, {}, {"var3"}) op2 = Operator("op2", {"var2"}, {"var3"}, {}) op3 = Operator("op3", {}, {"var1"}, {"var4"}) assert {"var1", "var2", "var3", "var4"} == grounding._collect_facts([op1, op2, op3])
def test_sat_solve(): op1 = Operator('op1', set(), {'a'}, set()) op2 = Operator('op2', set('a'), set('b'), set()) op3 = Operator('op3', set(), {'a', 'b', 'c'}, set()) op4 = Operator('op4', {'b'}, {'c'}, set()) op5 = Operator('op5', {'b', 'c'}, {'d'}, set()) op6 = Operator('op6', {'d'}, {'e', 'f'}, set()) op7 = Operator('op7', {'a', 'c', 'f'}, {'g'}, set()) task0 = Task('task0', {'a'}, {'a'}, {'a'}, [op1, op2]) task1 = Task('task1', {'a'}, set(), {'a'}, [op1, op2]) task2 = Task('task2', {'a', 'b'}, set(), {'b'}, [op1, op2]) task3 = Task('task3', {'a', 'b', 'c'}, set(), {'c'}, [op1, op2]) task4 = Task('task4', {'a', 'b', 'c'}, set(), {'c'}, [op1, op2, op3]) task5 = Task('task5', {'a', 'b', 'c'}, set(), {'c'}, [op1, op2, op4]) task6 = Task('task6', {'a', 'b', 'c', 'd'}, {'a'}, {'d'}, [op2, op4, op5]) task7 = Task('task7c', {'a', 'b', 'c', 'd'}, {'a'}, {'d'}, [op3, op5]) task8 = Task('task8', {'a', 'b', 'c', 'd', 'e', 'f', 'g'}, {'a'}, {'g'}, [op2, op3, op4, op5, op6, op7]) op_a = Operator('op_a', set(), {'a'}, set()) op_b = Operator('op_b', {'a'}, {'b'}, set()) op_c = Operator('op_c', {'b'}, {'c'}, set()) op_d = Operator('op_d', {'c'}, {'d'}, set()) op_e = Operator('op_e', {'d'}, {'e'}, set()) op_f = Operator('op_f', {'e'}, {'f'}, set()) task_d = Task('task_a', {'a', 'b', 'c', 'd'}, set(), {'d'}, [op_a, op_b, op_c, op_d]) task_e = Task('task_b', {'a', 'b', 'c', 'd', 'e'}, set(), {'e'}, [op_a, op_b, op_c, op_d, op_f]) op_facts = Operator( 'op_facts', set(), { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w' }, set()) task_facts = Task( 'task_facts', { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w' }, set(), {'v', 'w'}, [op_facts]) op_delete_pre = Operator('delete_pre', {'a'}, {'b'}, {'a'}) task_op_delete_pre = Task('op_delete_pre', {'a', 'b'}, {'a'}, {'b'}, [op_delete_pre]) # Miconic: prob00.pddl (2 floors, 1 person): # <Op (depart f1 p0), PRE: frozenset({'(lift-at f1)', '(boarded p0)'}), # ADD: frozenset({'(served p0)'}), DEL: frozenset({'(boarded p0)'})>, # <Op (board f0 p0), PRE: frozenset({'(lift-at f0)'}), # ADD: frozenset({'(boarded p0)'}), DEL: frozenset()>, # <Op (up f0 f1), PRE: frozenset({'(lift-at f0)'}), # ADD: frozenset({'(lift-at f1)'}), DEL: frozenset({'(lift-at f0)'})>] op_depart = Operator('depart', {'high', 'boarded'}, {'served'}, {'boarded'}) op_board = Operator('board', {'low'}, {'boarded'}, set()) op_up = Operator('up', {'low'}, {'high'}, {'low'}) task_simple_miconic = Task('miconic-simple', {'low', 'high', 'boarded', 'served'}, {'low'}, {'served'}, [op_depart, op_board, op_up]) expected = [(task0, []), (task1, [op1]), (task2, [op1, op2]), (task3, None), (task4, [op3]), (task5, [op1, op2, op4]), (task6, [op2, op4, op5]), (task7, [op3, op5]), (task_facts, [op_facts]), (task_op_delete_pre, [op_delete_pre]), (task_simple_miconic, [op_board, op_up, op_depart])] for task, plan in expected: yield check_plan, task, plan
import logging import sys logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)-8s %(message)s', stream=sys.stdout) import py.test from search import sat from search import minisat from task import Operator, Task import tools fact1 = "at-station" op1 = Operator('op1', set(), {'a'}, set()) op2 = Operator('op2', set(), set(), {'c'}) op3 = Operator('op3', ['d'], ['a'], []) op4 = Operator('op4', [], ['b'], []) task1 = Task('task1', {'a'}, set(), {'a'}, [op1]) task2 = Task('task2', {'a', 'd'}, {'d'}, {'a'}, [op1, op3]) task3 = Task('task3', {'a', 'b'}, set(), {'a', 'b'}, [op1, op4]) task4 = Task('task4', {'a', 'd'}, {'d'}, {'a'}, [op3]) task5 = Task('trivial', {'a'}, {'a'}, {'a'}, []) aux_a_iff_b = [['a<->b', 'a', 'b'], ['a<->b', 'not-a', 'not-b'], ['not-a<->b', 'a', 'not-b'], ['not-a<->b', 'not-a', 'b']] aux_a_and_b = [['not-aANDb', 'a'], ['not-aANDb', 'b'], ['not-a', 'not-b', 'aANDb']]