def setUp(self): self.p = have_cake() self.pg = PlanningGraph(self.p, self.p.initial) # some independent nodes for testing mutex self.na1 = PgNode_a( Action(expr('Go(here)'), [[], []], [[expr('At(here)')], []])) self.na2 = PgNode_a( Action(expr('Go(there)'), [[], []], [[expr('At(there)')], []])) self.na3 = PgNode_a( Action(expr('Noop(At(there))'), [[expr('At(there)')], []], [[expr('At(there)')], []])) self.na4 = PgNode_a( Action(expr('Noop(At(here))'), [[expr('At(here)')], []], [[expr('At(here)')], []])) self.na5 = PgNode_a( Action(expr('Reverse(At(here))'), [[expr('At(here)')], []], [[], [expr('At(here)')]])) self.ns1 = PgNode_s(expr('At(here)'), True) self.ns2 = PgNode_s(expr('At(there)'), True) self.ns3 = PgNode_s(expr('At(here)'), False) self.ns4 = PgNode_s(expr('At(there)'), False) self.na1.children.add(self.ns1) self.ns1.parents.add(self.na1) self.na2.children.add(self.ns2) self.ns2.parents.add(self.na2) self.na1.parents.add(self.ns3) self.na2.parents.add(self.ns4)
def test_inconsistent_support_mutex(self): self.assertFalse( PlanningGraph.inconsistent_support_mutex(self.pg, self.ns1, self.ns2), "Independent node paths should NOT be inconsistent-support mutex") mutexify(self.na1, self.na2) self.assertTrue( PlanningGraph.inconsistent_support_mutex(self.pg, self.ns1, self.ns2), "Mutex parent actions should result in inconsistent-support mutex") self.na6 = PgNode_a( Action(expr('Go(everywhere)'), [[], []], [[expr('At(here)'), expr('At(there)')], []])) self.na6.children.add(self.ns1) self.ns1.parents.add(self.na6) self.na6.children.add(self.ns2) self.ns2.parents.add(self.na6) self.na6.parents.add(self.ns3) self.na6.parents.add(self.ns4) mutexify(self.na1, self.na6) mutexify(self.na2, self.na6) self.assertFalse( PlanningGraph.inconsistent_support_mutex(self.pg, self.ns1, self.ns2), "If one parent action can achieve both states, should NOT be inconsistent-support mutex, even if parent actions are themselves mutex" )
def test_show(self): # validate show() helpers n = PgNode_s("Have(Cake)", False) self.assertEqual(n.__str__(), "s*~Have(Cake){0pr 0ch 0mx}") act1 = Action(expr('Eat(Cake)'), [[expr('Have(Cake)')], []], [[expr('Eaten(Cake)')], [expr('Have(Cake)')]]) n = PgNode_a(act1) self.assertEqual(n.__str__(), "a*Eat(Cake,){0pr 0ch 0mx}")
[precond_pos, precond_neg], [effect_add, effect_rem]) precond_pos = [] precond_neg = [expr("Have(Cake)")] effect_add = [expr("Have(Cake)")] effect_rem = [] bake_action = Action(expr("Bake(Cake)"), [precond_pos, precond_neg], [effect_add, effect_rem]) return [eat_action, bake_action] actions = get_actions() a_node_1 = PgNode_a(actions[0]) a_node_2 = PgNode_a(actions[0]) a_node_3 = PgNode_a(actions[0]) s_node_1 = PgNode_s("eaten", True) s_node_2 = PgNode_s("eaten", True) s_node_3 = PgNode_s("eaten", True) a_nodes = set() s_nodes = set() print(len(a_nodes), len(s_nodes)) a_node_3.children.add(s_node_3) s_node_3.parents.add(a_node_3)
class TestPlanningGraphMutex(unittest.TestCase): def setUp(self): self.p = have_cake() self.pg = PlanningGraph(self.p, self.p.initial) # some independent nodes for testing mutex self.na1 = PgNode_a( Action(expr('Go(here)'), [[], []], [[expr('At(here)')], []])) self.na2 = PgNode_a( Action(expr('Go(there)'), [[], []], [[expr('At(there)')], []])) self.na3 = PgNode_a( Action(expr('Noop(At(there))'), [[expr('At(there)')], []], [[expr('At(there)')], []])) self.na4 = PgNode_a( Action(expr('Noop(At(here))'), [[expr('At(here)')], []], [[expr('At(here)')], []])) self.na5 = PgNode_a( Action(expr('Reverse(At(here))'), [[expr('At(here)')], []], [[], [expr('At(here)')]])) self.ns1 = PgNode_s(expr('At(here)'), True) self.ns2 = PgNode_s(expr('At(there)'), True) self.ns3 = PgNode_s(expr('At(here)'), False) self.ns4 = PgNode_s(expr('At(there)'), False) self.na1.children.add(self.ns1) self.ns1.parents.add(self.na1) self.na2.children.add(self.ns2) self.ns2.parents.add(self.na2) self.na1.parents.add(self.ns3) self.na2.parents.add(self.ns4) def test_serialize_mutex(self): self.assertTrue( PlanningGraph.serialize_actions(self.pg, self.na1, self.na2), "Two persistence action nodes not marked as mutex") self.assertFalse( PlanningGraph.serialize_actions(self.pg, self.na3, self.na4), "Two No-Ops were marked mutex") self.assertFalse( PlanningGraph.serialize_actions(self.pg, self.na1, self.na3), "No-op and persistence action incorrectly marked as mutex") def test_inconsistent_effects_mutex(self): self.assertTrue( PlanningGraph.inconsistent_effects_mutex(self.pg, self.na4, self.na5), "Canceling effects not marked as mutex") self.assertFalse( PlanningGraph.inconsistent_effects_mutex(self.pg, self.na1, self.na2), "Non-Canceling effects incorrectly marked as mutex") def test_interference_mutex(self): self.assertTrue( PlanningGraph.interference_mutex(self.pg, self.na4, self.na5), "Precondition from one node opposite of effect of other node should be mutex" ) self.assertTrue( PlanningGraph.interference_mutex(self.pg, self.na5, self.na4), "Precondition from one node opposite of effect of other node should be mutex" ) self.assertFalse( PlanningGraph.interference_mutex(self.pg, self.na1, self.na2), "Non-interfering incorrectly marked mutex") def test_competing_needs_mutex(self): self.assertFalse( PlanningGraph.competing_needs_mutex(self.pg, self.na1, self.na2), "Non-competing action nodes incorrectly marked as mutex") self.na1.show() mutexify(self.ns3, self.ns4) self.assertTrue( PlanningGraph.competing_needs_mutex(self.pg, self.na1, self.na2), "Opposite preconditions from two action nodes not marked as mutex") def test_negation_mutex(self): self.assertTrue( PlanningGraph.negation_mutex(self.pg, self.ns1, self.ns3), "Opposite literal nodes not found to be Negation mutex") self.assertFalse( PlanningGraph.negation_mutex(self.pg, self.ns1, self.ns2), "Same literal nodes found to be Negation mutex") def test_inconsistent_support_mutex(self): self.assertFalse( PlanningGraph.inconsistent_support_mutex(self.pg, self.ns1, self.ns2), "Independent node paths should NOT be inconsistent-support mutex") mutexify(self.na1, self.na2) self.assertTrue( PlanningGraph.inconsistent_support_mutex(self.pg, self.ns1, self.ns2), "Mutex parent actions should result in inconsistent-support mutex") self.na6 = PgNode_a( Action(expr('Go(everywhere)'), [[], []], [[expr('At(here)'), expr('At(there)')], []])) self.na6.children.add(self.ns1) self.ns1.parents.add(self.na6) self.na6.children.add(self.ns2) self.ns2.parents.add(self.na6) self.na6.parents.add(self.ns3) self.na6.parents.add(self.ns4) mutexify(self.na1, self.na6) mutexify(self.na2, self.na6) self.assertFalse( PlanningGraph.inconsistent_support_mutex(self.pg, self.ns1, self.ns2), "If one parent action can achieve both states, should NOT be inconsistent-support mutex, even if parent actions are themselves mutex" )