Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bc88cd3

Browse files
committed
Agent.__init__ now takes a program parameter. A few more nonlocal-state-variable problems found and fixed. One agent program rewritten as a callable instance since it uses both state variables and abstract methods.
1 parent 08ed75d commit bc88cd3

File tree

4 files changed

+54
-57
lines changed

4 files changed

+54
-57
lines changed

agents.py

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,12 @@ class Agent(Object):
7373
There is an optional slots, .performance, which is a number giving
7474
the performance measure of the agent in its environment."""
7575

76-
def __init__(self):
76+
def __init__(self, program=None):
7777
self.alive = True
7878
self.bump = False
79-
def program(percept):
80-
return raw_input('Percept=%s; action? ' % percept)
79+
if program is None:
80+
def program(percept):
81+
return raw_input('Percept=%s; action? ' % percept)
8182
self.program = program
8283

8384
def can_grab(self, obj):
@@ -107,21 +108,21 @@ def __init__(self, table):
107108
"Supply as table a dictionary of all {percept_sequence:action} pairs."
108109
## The agent program could in principle be a function, but because
109110
## it needs to store state, we make it a callable instance of a class.
110-
super(TableDrivenAgent, self).__init__()
111111
percepts = []
112112
def program(percept):
113113
percepts.append(percept)
114114
action = table.get(tuple(percepts))
115115
return action
116-
self.program = program
116+
Agent.__init__(self, program)
117117

118118

119119
class RandomAgent(Agent):
120120
"An agent that chooses an action at random, ignoring all percepts."
121121

122122
def __init__(self, actions):
123-
super(RandomAgent, self).__init__()
124-
self.program = lambda percept: random.choice(actions)
123+
def program(percept):
124+
return random.choice(actions)
125+
Agent.__init__(self, program)
125126

126127

127128
#______________________________________________________________________________
@@ -132,12 +133,11 @@ class ReflexVacuumAgent(Agent):
132133
"A reflex agent for the two-state vacuum environment. [Fig. 2.8]"
133134

134135
def __init__(self):
135-
super(ReflexVacuumAgent, self).__init__()
136136
def program((location, status)):
137137
if status == 'Dirty': return 'Suck'
138138
elif location == loc_A: return 'Right'
139139
elif location == loc_B: return 'Left'
140-
self.program = program
140+
Agent.__init__(self, program)
141141

142142
def RandomVacuumAgent():
143143
"Randomly choose one of the actions from the vacuum environment."
@@ -164,7 +164,6 @@ class ModelBasedVacuumAgent(Agent):
164164
"An agent that keeps track of what locations are clean or dirty."
165165

166166
def __init__(self):
167-
super(ModelBasedVacuumAgent, self).__init__()
168167
model = {loc_A: None, loc_B: None}
169168
def program((location, status)):
170169
"Same as ReflexVacuumAgent, except if everything is clean, do NoOp"
@@ -173,7 +172,7 @@ def program((location, status)):
173172
elif status == 'Dirty': return 'Suck'
174173
elif location == loc_A: return 'Right'
175174
elif location == loc_B: return 'Left'
176-
self.program = program
175+
Agent.__init__(self, program)
177176

178177
#______________________________________________________________________________
179178

@@ -454,26 +453,24 @@ class SimpleReflexAgent(Agent):
454453
"""This agent takes action based solely on the percept. [Fig. 2.13]"""
455454

456455
def __init__(self, rules, interpret_input):
457-
super(SimpleReflexAgent, self).__init__()
458456
def program(percept):
459457
state = interpret_input(percept)
460458
rule = rule_match(state, rules)
461459
action = rule.action
462460
return action
463-
self.program = program
461+
Agent.__init__(self, program)
464462

465463
class ReflexAgentWithState(Agent):
466464
"""This agent takes action based on the percept and state. [Fig. 2.16]"""
467465

468466
def __init__(self, rules, update_state):
469-
super(ReflexAgentWithState, self).__init__()
470-
state = [None]
471467
def program(percept):
472-
state[0] = update_state(state[0], action, percept)
473-
rule = rule_match(state[0], rules)
468+
program.state = update_state(program.state, program.action, percept)
469+
rule = rule_match(program.state, rules)
474470
action = rule.action
475471
return action
476-
return program
472+
program.state = program.action = None
473+
Agent.__init__(self, program)
477474

478475
def rule_match(state, rules):
479476
"Find the first rule that matches state."

logic.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,14 @@ def retract(self, sentence):
9494
class KB_Agent(agents.Agent):
9595
"""A generic logical knowledge-based agent. [Fig. 7.1]"""
9696
def __init__(self, KB):
97-
agents.Agent.__init__(self)
9897
steps = itertools.count()
9998
def program(percept):
10099
t = steps.next()
101100
KB.tell(self.make_percept_sentence(percept, t))
102101
action = KB.ask(self.make_action_query(t))[expr('action')]
103102
KB.tell(self.make_action_sentence(action, t))
104103
return action
105-
self.program = program
104+
agents.Agent.__init__(self, program)
106105

107106
def make_percept_sentence(self, percept, t):
108107
return Expr("Percept")(percept, t)
@@ -745,30 +744,31 @@ def WalkSAT(clauses, p=0.5, max_flips=10000):
745744
class PLWumpusAgent(agents.Agent):
746745
"An agent for the wumpus world that does logical inference. [Fig. 7.19]"""
747746
def __init__(self):
748-
agents.Agent.__init__(self)
749747
KB = FolKB() ## shouldn't this be a propositional KB? ***
750748
x, y, orientation = 1, 1, (1, 0)
751749
visited = set() ## squares already visited
752-
action = None
753750
plan = []
754751

755752
def program(percept):
756753
stench, breeze, glitter = percept
757-
x, y, orientation = update_position(x, y, orientation, action)
754+
x, y, orientation = \
755+
update_position(x, y, orientation, program.action)
758756
KB.tell('%sS_%d,%d' % (if_(stench, '', '~'), x, y))
759757
KB.tell('%sB_%d,%d' % (if_(breeze, '', '~'), x, y))
760-
if glitter: action = 'Grab'
761-
elif plan: action = plan.pop()
758+
if glitter: program.action = 'Grab'
759+
elif plan: program.action = plan.pop()
762760
else:
763761
for [i, j] in fringe(visited):
764762
if KB.ask('~P_%d,%d & ~W_%d,%d' % (i, j, i, j)) != False:
765763
raise NotImplementedError
766764
KB.ask('~P_%d,%d | ~W_%d,%d' % (i, j, i, j)) != False
767-
if action is None:
768-
action = random.choice(['Forward', 'Right', 'Left'])
769-
return action
765+
if program.action is None:
766+
program.action = random.choice(['Forward', 'Right', 'Left'])
767+
return program.action
768+
769+
program.action = None
770770

771-
return program
771+
agents.Agent.__init__(self, program)
772772

773773
def update_position(x, y, orientation, action):
774774
if action == 'TurnRight':

probability.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,13 @@ class DTAgent(agents.Agent):
1212
"A decision-theoretic agent. [Fig. 13.1]"
1313

1414
def __init__(self, belief_state):
15-
agents.Agent.__init__(self)
16-
1715
def program(percept):
18-
belief_state.observe(action, percept)
16+
belief_state.observe(program.action, percept)
1917
program.action = argmax(belief_state.actions(),
2018
belief_state.expected_outcome_utility)
2119
return program.action
22-
2320
program.action = None
24-
self.program = program
21+
agents.Agent.__init__(self, program)
2522

2623
#______________________________________________________________________________
2724

search.py

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -88,29 +88,32 @@ def expand(self, problem):
8888

8989
#______________________________________________________________________________
9090

91-
class SimpleProblemSolvingAgent(agents.Agent):
92-
"""Abstract framework for problem-solving agent. [Fig. 3.1]"""
93-
def __init__(self):
94-
# Some nits in this code:
95-
# - We're requiring state to be a list so it can be
96-
# updated as a nonlocal variable.
97-
# - The agent program calls self.foo() methods,
98-
# against the usual policy that agent programs
99-
# be self-contained.
100-
agents.Agent.__init__(self)
101-
state = []
102-
seq = []
103-
104-
def program(percept):
105-
state[:] = self.update_state(state, percept)
106-
if not seq:
107-
goal = self.formulate_goal(state)
108-
problem = self.formulate_problem(state, goal)
109-
seq[:] = self.search(problem)
110-
if not seq: return None
111-
return seq.pop(0)
112-
113-
self.program = program
91+
class SimpleProblemSolvingAgentProgram:
92+
"""Abstract framework for a problem-solving agent. [Fig. 3.1]"""
93+
def __init__(self, initial_state=None):
94+
update(self, state=initial_state, seq=[])
95+
96+
def __call__(self, percept):
97+
self.state = self.update_state(self.state, percept)
98+
if not self.seq:
99+
goal = self.formulate_goal(self.state)
100+
problem = self.formulate_problem(self.state, goal)
101+
self.seq = self.search(problem)
102+
if not self.seq: return None
103+
return self.seq.pop(0)
104+
105+
def update_state(self, percept):
106+
abstract
107+
108+
def formulate_goal(self, state):
109+
abstract
110+
111+
def formulate_problem(self, state, goal):
112+
abstract
113+
114+
def search(self, problem):
115+
abstract
116+
114117
#______________________________________________________________________________
115118
## Uninformed Search algorithms
116119

0 commit comments

Comments
 (0)