def h_pg_levelsum(self, node: Node):
     # uses the planning graph level-sum heuristic calculated
     # from this node to the goal
     # requires implementation in PlanningGraph
     pg = PlanningGraph(self, node.state)
     pg_levelsum = pg.h_levelsum()
     return pg_levelsum
 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")
class TestPlanningGraphHeuristics(unittest.TestCase):
    def setUp(self):
        self.p = have_cake()
        self.pg = PlanningGraph(self.p, self.p.initial)

    def test_levelsum(self):
        self.assertEqual(self.pg.h_levelsum(), 1)

    def test_setlevel(self):
        self.assertEqual(self.pg.h_setlevel(), 2)
 def h_pg_levelsum(self, node: Node):
     """This heuristic uses a planning graph representation of the problem
     state space to estimate the sum of all actions that must be carried
     out from the current state in order to satisfy each individual goal
     condition.
     """
     # requires implemented PlanningGraph class
     pg = PlanningGraph(self, node.state)
     pg_levelsum = pg.h_levelsum()
     return pg_levelsum
Beispiel #5
0
 def h_pg_levelsum(self, node: Node):
     """This heuristic uses a planning graph representation of the problem
     state space to estimate the sum of all actions that must be carried
     out from the current state in order to satisfy each individual goal
     condition.
     """
     # requires implemented PlanningGraph class
     pg = PlanningGraph(self, node.state)
     pg_levelsum = pg.h_levelsum()
     return pg_levelsum
Beispiel #6
0
 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_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")
 def h_pg_levelsum(self, node: Node):
     '''
     This heuristic uses a planning graph representation of the problem
     state space to estimate the sum of all actions that must be carried
     out from the current state in order to satisfy each individual goal
     condition.
     '''
     pg = PlanningGraph(self, node.state)
     level = pg.h_levelsum()
     if level == False: return float("-inf")
     return level
Beispiel #9
0
 def h_pg_levelsum_cn(self, node: Node):
     """Variant of the pg heuristic for analysis purposes.
     Ignores inconsistent_effects_mutex and interference_mutex check.
     """
     # requires implemented PlanningGraph class
     pg = PlanningGraph(self,
                        node.state,
                        inconsistent_effects_mutex=False,
                        interference_mutex=False)
     pg_levelsum = pg.h_levelsum()
     return pg_levelsum
Beispiel #10
0
 def test_levelsum3(self):
     # make sure we can handle multiple steps
     problem = HaveCakeProblem(
         FluentState(
             [],
             [expr('Have(Cake)'), expr('Eaten(Cake)')]),
         [expr('Have(Cake)'), expr('Eaten(Cake)')],
     )
     pg = PlanningGraph(problem, problem.initial)
     # 1. bake 2. eat 3. bake
     self.assertEqual(3, pg.h_levelsum())
Beispiel #11
0
    def h_pg_setlevel(self, node):
        """ This heuristic uses a planning graph representation of the problem
        to estimate the level cost in the planning graph to achieve all of the
        goal literals such that none of them are mutually exclusive.

        See Also
        --------
        Russell-Norvig 10.3.1 (3rd Edition)
        """
        pg = PlanningGraph(self, node.state, serialize=True)
        score = pg.h_setlevel()
        return score
Beispiel #12
0
 def h_pg_setlevel(self, node: Node):
     '''
     This heuristic uses a planning graph representation of the problem
     state space to estimate the minimum number of actions that must be
     carried out from the current state in order to satisfy all of the goal
     conditions.
     '''
     # TODO: Complete the implmentation of this heuristic in the 
     # PlanningGraph class
     pg = PlanningGraph(self, node.state)
     pg_setlevel = pg.h_setlevel()
     return pg_setlevel
Beispiel #13
0
 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")
Beispiel #14
0
    def h_pg_maxlevel(self, node):
        """ This heuristic uses a planning graph representation of the problem
        to estimate the maximum level cost out of all the individual goal literals.
        The level cost is the first level where a goal literal appears in the
        planning graph.

        See Also
        --------
        Russell-Norvig 10.3.1 (3rd Edition)
        """
        pg = PlanningGraph(self, node.state, serialize=True, ignore_mutexes=True)
        score = pg.h_maxlevel()
        return score
Beispiel #15
0
    def h_pg_levelsum(self, node):
        """ This heuristic uses a planning graph representation of the problem
        state space to estimate the sum of the number of actions that must be
        carried out from the current state in order to satisfy each individual
        goal condition.

        See Also
        --------
        Russell-Norvig 10.3.1 (3rd Edition)
        """
        pg = PlanningGraph(self, node.state, serialize=True, ignore_mutexes=True)
        score = pg.h_levelsum()
        return score
Beispiel #16
0
 def h_pg_levelsum(self, node: Node):
     # uses the planning graph level-sum heuristic calculated
     # from this node to the goal
     # requires implementation in PlanningGraph
     pg = PlanningGraph(self, node.state)
     pg_levelsum = pg.h_levelsum
     return pg_levelsum
class TestPlanningGraphHeuristics(unittest.TestCase):
    def setUp(self):
        self.p = have_cake()
        self.pg = PlanningGraph(self.p, self.p.initial)

    def test_levelsum(self):
        self.assertEqual(self.pg.h_levelsum(), 1)
Beispiel #18
0
class TestPlanningGraphHeuristics(unittest.TestCase):
    def setUp(self):
        self.p = have_cake()
        self.pg = PlanningGraph(self.p, self.p.initial)

    def test_levelsum(self):
        self.assertEqual(self.pg.h_levelsum(), 1)

    def test_levelsum2(self):
        # make sure we can handle negations in the goals
        problem = HaveCakeProblem(
            FluentState(
                [],
                [expr('Have(Cake)'), expr('Eaten(Cake)')]),
            [expr('Have(Cake)'), expr('~Eaten(Cake)')],
        )
        pg = PlanningGraph(problem, problem.initial)
        self.assertEqual(1, pg.h_levelsum())

    def test_levelsum3(self):
        # make sure we can handle multiple steps
        problem = HaveCakeProblem(
            FluentState(
                [],
                [expr('Have(Cake)'), expr('Eaten(Cake)')]),
            [expr('Have(Cake)'), expr('Eaten(Cake)')],
        )
        pg = PlanningGraph(problem, problem.initial)
        # 1. bake 2. eat 3. bake
        self.assertEqual(3, pg.h_levelsum())
Beispiel #19
0
 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)
Beispiel #20
0
 def h_pg_levelsum(self, node: Node):
     """This heuristic uses a planning graph representation of the problem
     state space to estimate the sum of all actions that must be carried
     out from the current state in order to satisfy each individual goal
     condition.
     """
     # requires implemented PlanningGraph class
     time_in = time()
     pg = PlanningGraph(self, node.state)
     time_mid = time()
     pg_levelsum = pg.h_levelsum()
     time_out = time()
     print("LSH Timing: {}   {}   {}".format(time_in, time_mid, time_out))
     print("LSH Create PG: {}".format(time_mid - time_in))
     print("LSH Call LS: {}".format(time_out - time_mid))
     return pg_levelsum
Beispiel #21
0
 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"
     )
     print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
     print(self.na5.action.effect_add)
     print(self.na5.action.effect_rem)
     print(self.na4.action.precond_pos)
     print(self.na4.action.precond_neg)
     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")
Beispiel #22
0
class TestPlanningGraphHeuristics(unittest.TestCase):
    #print("in GH")
    def setUp(self):
        #print("in GH setup")
        self.p = have_cake()
        self.pg = PlanningGraph(self.p, self.p.initial)

    def test_levelsum(self):
        #print("in GH level sum")
        self.assertEqual(self.pg.h_levelsum(), 1)
 def setUp(self):
     super().setUp()
     self.ac_problem = air_cargo_p1()
     self.ac_pg_serial = PlanningGraph(self.ac_problem,
                                       self.ac_problem.initial).fill()
     # In(C1, P2) and In(C2, P1) have inconsistent support when they first appear in
     # the air cargo problem,
     self.inconsistent_support_literals = [
         expr("In(C1, P2)"), expr("In(C2, P1)")
     ]
Beispiel #24
0
class TestPlanningGraphHeuristics(unittest.TestCase):
    def setUp(self):
        #import pdb;pdb.set_trace()
        self.p = have_cake()
        self.pg = PlanningGraph(self.p, self.p.initial)

    def test_levelsum(self):
        import pdb
        pdb.set_trace()
        self.assertEqual(self.pg.h_levelsum(), 1)
class TestPlanningGraphHeuristics(unittest.TestCase):
    def setUp(self):
        # print("\n===================== TestPlanningGraphHeuristics.....test_inconsistent_support_mutex")

        self.p = have_cake()
        self.pg = PlanningGraph(self.p, self.p.initial)

    def test_levelsum(self):
        # print("\n===================== TestPlanningGraphHeuristics.....test_levelsum")
        self.assertEqual(self.pg.h_levelsum(), 1)
class TestPlanningGraphHeuristics(unittest.TestCase):
    def setUp(self):
        self.p = have_cake()
        self.pg = PlanningGraph(self.p, self.p.initial)

    def test_levelsum(self):
        # print ("TEST TEST")
        # print (self.p)
        # print (self.pg)
        # print (self.pg.h_levelsum())
        self.assertEqual(self.pg.h_levelsum(), 1)
    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")
Beispiel #28
0
    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")
Beispiel #29
0
    def setUp(self):
        self.cake_problem = have_cake()
        self.cake_pg = PlanningGraph(self.cake_problem,
                                     self.cake_problem.initial,
                                     serialize=False).fill()

        self.eat_action, self.bake_action = [
            a for a in self.cake_pg._actionNodes if not a.no_op
        ]
        no_ops = [a for a in self.cake_pg._actionNodes if a.no_op]
        self.null_action = make_node(
            Action(expr('Null()'), [set(), set()], [set(), set()]))

        # some independent nodes for testing mutexes
        at_here = expr('At(here)')
        at_there = expr('At(there)')
        self.pos_literals = [at_here, at_there]
        self.neg_literals = [~x for x in self.pos_literals]
        self.literal_layer = LiteralLayer(
            self.pos_literals + self.neg_literals, ActionLayer())
        self.literal_layer.update_mutexes()

        # independent actions for testing mutex
        self.actions = [
            make_node(
                Action(expr('Go(here)'), [set(), set()],
                       [set([at_here]), set()])),
            make_node(
                Action(expr('Go(there)'), [set(), set()],
                       [set([at_there]), set()]))
        ]
        self.no_ops = [
            make_node(x)
            for x in chain(*(makeNoOp(l) for l in self.pos_literals))
        ]
        self.action_layer = ActionLayer(self.no_ops + self.actions,
                                        self.literal_layer)
        self.action_layer.update_mutexes()
        for action in self.no_ops + self.actions:
            self.action_layer.add_inbound_edges(action, action.preconditions)
            self.action_layer.add_outbound_edges(action, action.effects)
Beispiel #30
0
 def setUp(self):
     #print("in GH setup")
     self.p = have_cake()
     self.pg = PlanningGraph(self.p, self.p.initial)
Beispiel #31
0
 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")
Beispiel #32
0
 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")
     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")
Beispiel #33
0
 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")
Beispiel #34
0
 def setUp(self):
     self.p = have_cake()
     self.pg = PlanningGraph(self.p, self.p.initial)
 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_competing_needs_mutex(self):
     self.assertFalse(PlanningGraph.competing_needs_mutex(self.pg, self.na1, self.na2),
                      "Non-competing action nodes incorrectly marked as mutex")
     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")
Beispiel #37
0
    def setUp(self):
        self.cake_problem = have_cake()
        self.cake_pg = PlanningGraph(self.cake_problem,
                                     self.cake_problem.initial,
                                     serialize=False).fill()

        eat_action, bake_action = [
            a for a in self.cake_pg._actionNodes if not a.no_op
        ]
        no_ops = [a for a in self.cake_pg._actionNodes if a.no_op]

        # bake has the effect Have(Cake) which is the logical negation of the effect
        # ~Have(cake) from the persistence action ~NoOp::Have(cake)
        self.inconsistent_effects_actions = [bake_action, no_ops[3]]

        # the persistence action ~NoOp::Have(cake) has the effect ~Have(cake), which is
        # the logical negation of Have(cake) -- the precondition for the Eat(cake) action
        self.interference_actions = [eat_action, no_ops[3]]

        # eat has precondition Have(cake) and bake has precondition ~Have(cake)
        # which are logical inverses, so eat & bake should be mutex at every
        # level of the planning graph where both actions appear
        self.competing_needs_actions = [eat_action, bake_action]

        self.ac_problem = air_cargo_p1()
        self.ac_pg_serial = PlanningGraph(self.ac_problem,
                                          self.ac_problem.initial).fill()
        # In(C1, P2) and In(C2, P1) have inconsistent support when they first appear in
        # the air cargo problem,
        self.inconsistent_support_literals = [
            expr("In(C1, P2)"), expr("In(C2, P1)")
        ]

        # some independent nodes for testing mutexes
        at_here = expr('At(here)')
        at_there = expr('At(there)')
        self.pos_literals = [at_here, at_there]
        self.neg_literals = [~x for x in self.pos_literals]
        self.literal_layer = LiteralLayer(
            self.pos_literals + self.neg_literals, ActionLayer())
        self.literal_layer.update_mutexes()

        # independent actions for testing mutex
        self.actions = [
            make_node(
                Action(expr('Go(here)'), [set(), set()],
                       [set([at_here]), set()])),
            make_node(
                Action(expr('Go(there)'), [set(), set()],
                       [set([at_there]), set()]))
        ]
        self.no_ops = [
            make_node(x)
            for x in chain(*(makeNoOp(l) for l in self.pos_literals))
        ]
        self.action_layer = ActionLayer(self.no_ops + self.actions,
                                        self.literal_layer)
        self.action_layer.update_mutexes()
        for action in self.no_ops + self.actions:
            self.action_layer.add_inbound_edges(action, action.preconditions)
            self.action_layer.add_outbound_edges(action, action.effects)

        # competing needs tests -- build two copies of the planning graph: one where
        #  A, B, and C are pairwise mutex, and another where they are not
        A, B, C = expr('A'), expr('B'), expr('C')
        self.fake_competing_needs_actions = [
            make_node(
                Action(expr('FakeAction(A)'), [set([A]), set()],
                       [set([A]), set()])),
            make_node(
                Action(expr('FakeAction(B)'), [set([B]), set()],
                       [set([B]), set()])),
            make_node(
                Action(expr('FakeAction(C)'), [set([C]), set()],
                       [set([C]), set()]))
        ]
        competing_layer = LiteralLayer([A, B, C], ActionLayer())
        for a1, a2 in combinations([A, B, C], 2):
            competing_layer.set_mutex(a1, a2)
        self.competing_action_layer = ActionLayer(competing_layer.parent_layer,
                                                  competing_layer, False, True)
        for action in self.fake_competing_needs_actions:
            self.competing_action_layer.add(action)
            competing_layer |= action.effects
            competing_layer.add_outbound_edges(action, action.preconditions)
            self.competing_action_layer.add_inbound_edges(
                action, action.preconditions)
            self.competing_action_layer.add_outbound_edges(
                action, action.effects)

        not_competing_layer = LiteralLayer([A, B, C], ActionLayer())
        self.not_competing_action_layer = ActionLayer(
            not_competing_layer.parent_layer, not_competing_layer, False, True)
        for action in self.fake_competing_needs_actions:
            self.not_competing_action_layer.add(action)
            not_competing_layer |= action.effects
            not_competing_layer.add_outbound_edges(action,
                                                   action.preconditions)
            self.not_competing_action_layer.add_inbound_edges(
                action, action.preconditions)
            self.not_competing_action_layer.add_outbound_edges(
                action, action.effects)
 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_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 setUp(self):
     self.p = have_cake()
     self.pg = PlanningGraph(self.p, self.p.initial)