forked from udacity/AIND-Planning
-
Notifications
You must be signed in to change notification settings - Fork 0
/
example_have_cake.py
145 lines (129 loc) · 5.05 KB
/
example_have_cake.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
from aimacode.logic import PropKB
from aimacode.planning import Action
from aimacode.search import (
Node, breadth_first_search, astar_search, depth_first_graph_search,
uniform_cost_search, greedy_best_first_graph_search, Problem,
)
from aimacode.utils import expr
from lp_utils import (
FluentState, encode_state, decode_state
)
from my_planning_graph import PlanningGraph
from run_search import run_search
from functools import lru_cache
class HaveCakeProblem(Problem):
def __init__(self, initial: FluentState, goal: list):
self.state_map = initial.pos + initial.neg
Problem.__init__(self, encode_state(initial, self.state_map), goal=goal)
self.actions_list = self.get_actions()
def get_actions(self):
precond_pos = [expr("Have(Cake)")]
precond_neg = []
effect_add = [expr("Eaten(Cake)")]
effect_rem = [expr("Have(Cake)")]
eat_action = Action(expr("Eat(Cake)"),
[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]
def actions(self, state: str) -> list: # of Action
possible_actions = []
kb = PropKB()
kb.tell(decode_state(state, self.state_map).pos_sentence())
for action in self.actions_list:
is_possible = True
for clause in action.precond_pos:
if clause not in kb.clauses:
is_possible = False
for clause in action.precond_neg:
if clause in kb.clauses:
is_possible = False
if is_possible:
possible_actions.append(action)
return possible_actions
def result(self, state: str, action: Action):
new_state = FluentState([], [])
old_state = decode_state(state, self.state_map)
for fluent in old_state.pos:
if fluent not in action.effect_rem:
new_state.pos.append(fluent)
for fluent in action.effect_add:
if fluent not in new_state.pos:
new_state.pos.append(fluent)
for fluent in old_state.neg:
if fluent not in action.effect_add:
new_state.neg.append(fluent)
for fluent in action.effect_rem:
if fluent not in new_state.neg:
new_state.neg.append(fluent)
return encode_state(new_state, self.state_map)
def goal_test(self, state: str) -> bool:
kb = PropKB()
kb.tell(decode_state(state, self.state_map).pos_sentence())
for clause in self.goal:
if clause not in kb.clauses:
return False
return True
def h_1(self, node: Node):
# note that this is not a true heuristic
h_const = 1
return h_const
@lru_cache(maxsize=8192)
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
@lru_cache(maxsize=8192)
def h_ignore_preconditions(self, node: Node):
# not implemented
count = 0
return count
def have_cake():
def get_init():
pos = [expr('Have(Cake)'),
]
neg = [expr('Eaten(Cake)'),
]
return FluentState(pos, neg)
def get_goal():
return [expr('Have(Cake)'),
expr('Eaten(Cake)'),
]
return HaveCakeProblem(get_init(), get_goal())
if __name__ == '__main__':
p = have_cake()
print("**** Have Cake example problem setup ****")
print("Initial state for this problem is {}".format(p.initial))
print("Actions for this domain are:")
for a in p.actions_list:
print(' {}{}'.format(a.name, a.args))
print("Fluents in this problem are:")
for f in p.state_map:
print(' {}'.format(f))
print("Goal requirement for this problem are:")
for g in p.goal:
print(' {}'.format(g))
print()
print("*** Breadth First Search")
run_search(p, breadth_first_search)
print("*** Depth First Search")
run_search(p, depth_first_graph_search)
print("*** Uniform Cost Search")
run_search(p, uniform_cost_search)
print("*** Greedy Best First Graph Search - null heuristic")
run_search(p, greedy_best_first_graph_search, parameter=p.h_1)
print("*** A-star null heuristic")
run_search(p, astar_search, p.h_1)
# print("A-star ignore preconditions heuristic")
# rs(p, "astar_search - ignore preconditions heuristic", astar_search, p.h_ignore_preconditions)
# print(""A-star levelsum heuristic)
# rs(p, "astar_search - levelsum heuristic", astar_search, p.h_pg_levelsum)