diff --git a/aimaPy/csp.py b/aimaPy/csp.py index 414f69fb9..59dfb8b1b 100644 --- a/aimaPy/csp.py +++ b/aimaPy/csp.py @@ -601,7 +601,7 @@ def show_cell(cell): return str(assignment.get(cell, '.')) def abut(lines1, lines2): return list( map(' | '.join, list(zip(lines1, lines2)))) print('\n------+-------+------\n'.join( - '\n'.join(reduce(abut, list(map(show_box, brow)))) for brow in self.bgri)) + '\n'.join(reduce(abut, list(map(show_box, brow)))) for brow in self.bgrid)) #______________________________________________________________________________ # The Zebra Puzzle diff --git a/aimaPy/search.py b/aimaPy/search.py index dc29e9e85..9cd459391 100644 --- a/aimaPy/search.py +++ b/aimaPy/search.py @@ -374,8 +374,35 @@ def simulated_annealing(problem, schedule=exp_schedule()): def and_or_graph_search(problem): + """Used when the environment is nondeterministic and completely observable + Contains OR nodes where the agent is free to choose any action + After every action there is an AND node which contains all possible states the agent may reach due to stochastic nature of environment + The agent must be able to handle all possible states of the AND node(as it may end up in any of them) + returns a conditional plan to reach goal state, or failure if the former is not possible""" "[Fig. 4.11]" - unimplemented() + + #functions used by and_or_search + def or_search(state, problem, path): + if problem.goal_test(state): + return {} + if state in path: + return None + for action in problem.action(state): + plan = and_search(problem.result(state, action), problem, path + [state,]) + if not plan == None: + return [action, plan] + + def and_search(states, problem, path): + "returns plan in form of dictionary where we take action plan[s] if we reach state s" + plan=dict() + for s in states: + plan[s] = or_search(s, problem, path) + if plan[s] == None: + return None + return plan + + #body of and or search + return or_search(problem.initial, problem, []) def online_dfs_agent(s1): diff --git a/tests/utils_test.py b/tests/utils_test.py index 2f5492e58..eb63448bb 100644 --- a/tests/utils_test.py +++ b/tests/utils_test.py @@ -128,10 +128,6 @@ def test_clip(): assert [clip(x, 0, 1) for x in [-1, 0.5, 10]] == [0, 0.5, 1] -def test_vector_clip(): - assert vector_clip((-1, 10), (0, 0), (9, 9)) == (0, 9) - - def test_caller(): assert caller(0) == 'caller'