prolog homework
Prolog/.DS_Store
__MACOSX/Prolog/._.DS_Store
Prolog/COMP9414:9814 Assignment 3.html
COMP9414/9814 Artificial Intelligence
Session 1, 2015
Project 3, Option 1: Prolog (BDI Agent)
Due: Sunday 31 May, 11:59 pm Marks: 12% of final assessment
Introduction
In this assignment, you will implement the basic functions of a simple BDI Agent that operates in a Gridworld, and by doing so, learn about the ideas underlying BDI agents.Gridworld
The Gridworld consists of a two-dimensional grid of locations, extending to infinity in both directions. Some locations contain "junk" which the agent must "clean up" in order to score points. An agent cleans up a piece of junk by moving to its location and executing a pickup action. Agents can move one square at a time either horizontally or vertically. The world is dynamic in that junk may spontaneously appear at randomly determined locations at any time, though there is never more than one item of junk in the same location.
Figure 1: Gridworld State: Agent (circle) with junk (squares)
A supplied Prolog program implements a system for conducting an experimental trial consisting of one agent in the Gridworld that repeatedly executes the BDI interpretation cycle for 20 iterations (this is a deliberately small number for ease of writing and debugging the program). The initial state of the world is always that there is no junk and the agent is at the location (0,0).
The agent's beliefs at any time simply consist of a list containing one term of the form at(X,Y) representing the current location of the agent. The agent's beliefs are always correct (i.e. if the agent "thinks" it is at location (3,4) then it is at location (3,4)). Hence the initial belief state of the agent is represented by the list [at(0,0)].
The agent's goals at any time are a list of locations of junk and their values. Each goal of the agent is represented as a term goal(X,Y,S), where (X,Y) is the location of a piece of junk and S is its value. The agent's intentions are a list of pairs, each of the form [Goal, Plan], representing a goal with an associated plan (that may be the empty plan), ordered according to some priority.
Each plan is a list of actions. To fulfil an intention, the agent executes the plan associated with the goal, which will make the agent move along a path towards the goal and clean it up. If, when the agent chooses a goal to pursue, the plan associated with the goal is empty or cannot be executed, the agent creates a new plan for the goal and then begins to execute this plan.
In each cycle the agent executes one action; there are two types of action the agent can execute:
pickup(X,Y) - the agent picks up the junk at (X,Y) and scores the associated points move(X,Y) - the agent moves to the location (X,Y)
BDI Interpreter
In each time cycle, the agent executes the interpreter shown abstractly in Figure 2. The new external events on each cycle are represented as a list of terms of the form junk(X,Y,S), indicating the perception of junk at location (X,Y) with value S within some viewing distance of the agent. The agent will repeatedly perceive the same junk item for as long as it is in viewing range. It is not assumed that the agent can see all of the grid, so a new external event may occur as the agent moves (unknowingly) towards a piece of junk. Each new perceived event junk(X,Y,S) triggers a goal for the agent, represented as a term of the form goal(X,Y,S). Any new goal is incorporated into the agent's list of intentions according to the agent's prioritization strategy (see below). The agent then selects one action for execution from the current list of intentions (here the agent always selects the first intention on the list if there is one, creates or modifies the associated plan if necessary, then selects the first action in that plan, removes the selected action from the chosen plan, executes the action, and updates the list of intentions by removing any successfully achieved goals. If there are no current intentions, the agent simply moves to any adjacent location.
| Abstract BDI Interpreter: |
| initialize-state(); |
| do |
| get-new-external-event(events); |
| G := trigger(events); |
| incorporate-goals(G, I); |
| action := select-action(B, I); |
| execute(action); |
| observe(action, facts); |
| update-beliefs(facts, B); |
| update-intentions(facts, I); |
| until quit |
The agent's prioritization strategy is very simple: without reordering existing goals, each new goal is inserted into the list of intentions in order of distance (closer before further away), but if the new goal is the same distance as existing goal(s), the new goal is inserted into the list of goals with the same distance in order of value (higher values before lower values). This means the agent maintains a "commitment" to pursuing its goals (the agent only changes its intention to pick up a close item or an item at the same distance with higher value).
Assignment [12 marks]
You are supplied with a Prolog program in a file gridworld.pro that implements the experimental setup, including the generation of events (appearance of junk) and the execution of actions, and the agent's BDI interpretation cycle and observation functions.
[1 mark] Write a Prolog procedure trigger(Events, Goals) which takes a list of events, each of the form junk(X,Y,S), and computes the corresponding list of goals for the agent, each of the form goal(X,Y,S). This is a very simple procedure!
[4 marks] Write a Prolog procedure incorporate_goals(Goals, Beliefs, Intentions, Intentions1) which has four arguments: a list of goals each of the form goal(X,Y,S), a list of beliefs (containing one term of the form at(X,Y)), the current list of intentions each of the form [goal(X,Y,S), Plan], and a list to be computed which contains the new goals inserted into the current list of intentions in increasing order of distance, using the value of the item to break ties. More precisely, a new goal should be placed immediately before the first goal in the list that is further away from the agent's current position, or which is at the same distance from the agent but of lower value, without reordering the current list of goals. Note that because of repeated perception of the same event, only new goals should be inserted into the list of intentions. The plan associated with each new goal should be the empty plan (represented as the empty list).
[3 marks] Write a Prolog procedure select_action(Beliefs, Intentions, Intentions1, Action) which takes the agent's beliefs (a singleton list containing a term for the agent's location) and the list of intentions, and computes an action to be taken by the agent and the updated list of intentions. The intention selected by the agent is the first on the list of intentions (if any). If the first action in this plan is applicable, the agent selects this action and updates the plan to remove the selected action. If there is no associated plan (i.e. the plan is the empty list) or the first action in the plan for the first intention is not applicable in the current state, the agent constructs a new plan to go from its current position to the goal state and pick up the junk there (this plan will be a list of move actions followed by an pick up action), selects the first action in this new plan, and updates the list of intentions to incorporate the new plan (minus the selected first action). Due to the fact that there are no obstacles in the world, the exact path the agent takes towards the goal does not matter, so choose any convenient way of implementing this procedure. The procedure applicable is defined in gridworld.pro
[1 mark] Write two Prolog procedures update_beliefs(Observation, Beliefs, Beliefs1) and update_intentions(Observation, Intentions, Intentions1) to compute the lists of beliefs and intentions resulting from the agent's observations. These are very simple procedures (one line for each possible observation type)!
There are 3 marks allocated for comments and programming style.
Submission
Submit one file called agent.pro using the command
give cs9414 hw3prolog agent.proYour solution should work with the supplied file gridworld.pro. Do not change any of the procedures in this file and do not include the code from this file with your submission.
__MACOSX/Prolog/._COMP9414:9814 Assignment 3.html
Prolog/FAQ/.DS_Store
__MACOSX/Prolog/FAQ/._.DS_Store
Prolog/FAQ/agent_trial.txt
% gridworld.pro compiled 0.00 sec, 8,200 bytes % agent.pro compiled 0.00 sec, 9,196 bytes % run compiled 0.00 sec, 20,104 bytes Welcome to SWI-Prolog (Multi-threaded, 32 bits, Version 5.10.4) Copyright (c) 1990-2011 University of Amsterdam, VU Amsterdam SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. Please visit http://www.swi-prolog.org for details. For help, use ?- help(Topic). or ?- apropos(Word). ?- agent_trial. Cycle 0: Event: junk value 9 appears at (3,1) World: [junk(3,1,9)] Beliefs: [at(0,0)] Percepts: [junk(3,1,9)] Intentions: [[goal(3,1,9),[]]] New Intentions: [[goal(3,1,9),[move(2,0),move(3,0),move(3,1),pickup(3,1)]]] Action: move(1,0) scores 0 Updated World: [junk(3,1,9)] Observation: at(1,0) Updated Beliefs: [at(1,0)] Updated Intentions: [[goal(3,1,9),[move(2,0),move(3,0),move(3,1),pickup(3,1)]]] Cycle 1: Event: junk value 9 appears at (3,3) World: [junk(3,1,9),junk(3,3,9)] Beliefs: [at(1,0)] Percepts: [junk(3,1,9),junk(3,3,9)] Intentions: [[goal(3,1,9),[move(2,0),move(3,0),move(3,1),pickup(3,1)]],[goal(3,3,9),[]]] New Intentions: [[goal(3,1,9),[move(3,0),move(3,1),pickup(3,1)]],[goal(3,3,9),[]]] Action: move(2,0) scores 0 Updated World: [junk(3,1,9),junk(3,3,9)] Observation: at(2,0) Updated Beliefs: [at(2,0)] Updated Intentions: [[goal(3,1,9),[move(3,0),move(3,1),pickup(3,1)]],[goal(3,3,9),[]]] Cycle 2: World: [junk(3,1,9),junk(3,3,9)] Beliefs: [at(2,0)] Percepts: [junk(3,1,9),junk(3,3,9)] Intentions: [[goal(3,1,9),[move(3,0),move(3,1),pickup(3,1)]],[goal(3,3,9),[]]] New Intentions: [[goal(3,1,9),[move(3,1),pickup(3,1)]],[goal(3,3,9),[]]] Action: move(3,0) scores 0 Updated World: [junk(3,1,9),junk(3,3,9)] Observation: at(3,0) Updated Beliefs: [at(3,0)] Updated Intentions: [[goal(3,1,9),[move(3,1),pickup(3,1)]],[goal(3,3,9),[]]] Cycle 3: World: [junk(3,1,9),junk(3,3,9)] Beliefs: [at(3,0)] Percepts: [junk(3,1,9),junk(3,3,9)] Intentions: [[goal(3,1,9),[move(3,1),pickup(3,1)]],[goal(3,3,9),[]]] New Intentions: [[goal(3,1,9),[pickup(3,1)]],[goal(3,3,9),[]]] Action: move(3,1) scores 0 Updated World: [junk(3,1,9),junk(3,3,9)] Observation: at(3,1) Updated Beliefs: [at(3,1)] Updated Intentions: [[goal(3,1,9),[pickup(3,1)]],[goal(3,3,9),[]]] Cycle 4: World: [junk(3,1,9),junk(3,3,9)] Beliefs: [at(3,1)] Percepts: [junk(3,1,9),junk(3,3,9)] Intentions: [[goal(3,1,9),[pickup(3,1)]],[goal(3,3,9),[]]] New Intentions: [[goal(3,1,9),[]],[goal(3,3,9),[]]] Action: pickup(3,1) scores 9 Updated World: [junk(3,3,9)] Observation: cleaned(3,1) Updated Beliefs: [at(3,1)] Updated Intentions: [[goal(3,3,9),[]]] Cycle 5: World: [junk(3,3,9)] Beliefs: [at(3,1)] Percepts: [junk(3,3,9)] Intentions: [[goal(3,3,9),[]]] New Intentions: [[goal(3,3,9),[move(3,3),pickup(3,3)]]] Action: move(3,2) scores 0 Updated World: [junk(3,3,9)] Observation: at(3,2) Updated Beliefs: [at(3,2)] Updated Intentions: [[goal(3,3,9),[move(3,3),pickup(3,3)]]] Cycle 6: World: [junk(3,3,9)] Beliefs: [at(3,2)] Percepts: [junk(3,3,9)] Intentions: [[goal(3,3,9),[move(3,3),pickup(3,3)]]] New Intentions: [[goal(3,3,9),[pickup(3,3)]]] Action: move(3,3) scores 0 Updated World: [junk(3,3,9)] Observation: at(3,3) Updated Beliefs: [at(3,3)] Updated Intentions: [[goal(3,3,9),[pickup(3,3)]]] Cycle 7: World: [junk(3,3,9)] Beliefs: [at(3,3)] Percepts: [junk(3,3,9)] Intentions: [[goal(3,3,9),[pickup(3,3)]]] New Intentions: [[goal(3,3,9),[]]] Action: pickup(3,3) scores 9 Updated World: [] Observation: cleaned(3,3) Updated Beliefs: [at(3,3)] Updated Intentions: [] Cycle 8: World: [] Beliefs: [at(3,3)] Percepts: [] Intentions: [] New Intentions: [] Action: move(4,3) scores 0 Updated World: [] Observation: at(4,3) Updated Beliefs: [at(4,3)] Updated Intentions: [] Cycle 9: World: [] Beliefs: [at(4,3)] Percepts: [] Intentions: [] New Intentions: [] Action: move(5,3) scores 0 Updated World: [] Observation: at(5,3) Updated Beliefs: [at(5,3)] Updated Intentions: [] Cycle 10: Event: junk value 0 appears at (1,9) World: [junk(1,9,0)] Beliefs: [at(5,3)] Percepts: [] Intentions: [] New Intentions: [] Action: move(6,3) scores 0 Updated World: [junk(1,9,0)] Observation: at(6,3) Updated Beliefs: [at(6,3)] Updated Intentions: [] Cycle 11: World: [junk(1,9,0)] Beliefs: [at(6,3)] Percepts: [] Intentions: [] New Intentions: [] Action: move(7,3) scores 0 Updated World: [junk(1,9,0)] Observation: at(7,3) Updated Beliefs: [at(7,3)] Updated Intentions: [] Cycle 12: Event: junk value 9 appears at (4,9) World: [junk(1,9,0),junk(4,9,9)] Beliefs: [at(7,3)] Percepts: [junk(4,9,9)] Intentions: [[goal(4,9,9),[]]] New Intentions: [[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]]] Action: move(6,3) scores 0 Updated World: [junk(1,9,0),junk(4,9,9)] Observation: at(6,3) Updated Beliefs: [at(6,3)] Updated Intentions: [[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]]] Cycle 13: Event: junk value 3 appears at (6,2) Event: junk value 2 appears at (3,1) World: [junk(1,9,0),junk(4,9,9),junk(6,2,3),junk(3,1,2)] Beliefs: [at(6,3)] Percepts: [junk(4,9,9),junk(6,2,3),junk(3,1,2)] Intentions: [[goal(6,2,3),[]],[goal(3,1,2),[]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]]] New Intentions: [[goal(6,2,3),[pickup(6,2)]],[goal(3,1,2),[]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]]] Action: move(6,2) scores 0 Updated World: [junk(1,9,0),junk(4,9,9),junk(6,2,3),junk(3,1,2)] Observation: at(6,2) Updated Beliefs: [at(6,2)] Updated Intentions: [[goal(6,2,3),[pickup(6,2)]],[goal(3,1,2),[]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]]] Cycle 14: World: [junk(1,9,0),junk(4,9,9),junk(6,2,3),junk(3,1,2)] Beliefs: [at(6,2)] Percepts: [junk(4,9,9),junk(6,2,3),junk(3,1,2)] Intentions: [[goal(6,2,3),[pickup(6,2)]],[goal(3,1,2),[]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]]] New Intentions: [[goal(6,2,3),[]],[goal(3,1,2),[]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]]] Action: pickup(6,2) scores 3 Updated World: [junk(1,9,0),junk(4,9,9),junk(3,1,2)] Observation: cleaned(6,2) Updated Beliefs: [at(6,2)] Updated Intentions: [[goal(3,1,2),[]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]]] Cycle 15: World: [junk(1,9,0),junk(4,9,9),junk(3,1,2)] Beliefs: [at(6,2)] Percepts: [junk(4,9,9),junk(3,1,2)] Intentions: [[goal(3,1,2),[]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]]] New Intentions: [[goal(3,1,2),[move(4,2),move(3,2),move(3,1),pickup(3,1)]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]]] Action: move(5,2) scores 0 Updated World: [junk(1,9,0),junk(4,9,9),junk(3,1,2)] Observation: at(5,2) Updated Beliefs: [at(5,2)] Updated Intentions: [[goal(3,1,2),[move(4,2),move(3,2),move(3,1),pickup(3,1)]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]]] Cycle 16: World: [junk(1,9,0),junk(4,9,9),junk(3,1,2)] Beliefs: [at(5,2)] Percepts: [junk(4,9,9),junk(3,1,2)] Intentions: [[goal(3,1,2),[move(4,2),move(3,2),move(3,1),pickup(3,1)]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]]] New Intentions: [[goal(3,1,2),[move(3,2),move(3,1),pickup(3,1)]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]]] Action: move(4,2) scores 0 Updated World: [junk(1,9,0),junk(4,9,9),junk(3,1,2)] Observation: at(4,2) Updated Beliefs: [at(4,2)] Updated Intentions: [[goal(3,1,2),[move(3,2),move(3,1),pickup(3,1)]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]]] Cycle 17: World: [junk(1,9,0),junk(4,9,9),junk(3,1,2)] Beliefs: [at(4,2)] Percepts: [junk(4,9,9),junk(3,1,2)] Intentions: [[goal(3,1,2),[move(3,2),move(3,1),pickup(3,1)]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]]] New Intentions: [[goal(3,1,2),[move(3,1),pickup(3,1)]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]]] Action: move(3,2) scores 0 Updated World: [junk(1,9,0),junk(4,9,9),junk(3,1,2)] Observation: at(3,2) Updated Beliefs: [at(3,2)] Updated Intentions: [[goal(3,1,2),[move(3,1),pickup(3,1)]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]]] Cycle 18: World: [junk(1,9,0),junk(4,9,9),junk(3,1,2)] Beliefs: [at(3,2)] Percepts: [junk(1,9,0),junk(4,9,9),junk(3,1,2)] Intentions: [[goal(3,1,2),[move(3,1),pickup(3,1)]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]],[goal(1,9,0),[]]] New Intentions: [[goal(3,1,2),[pickup(3,1)]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]],[goal(1,9,0),[]]] Action: move(3,1) scores 0 Updated World: [junk(1,9,0),junk(4,9,9),junk(3,1,2)] Observation: at(3,1) Updated Beliefs: [at(3,1)] Updated Intentions: [[goal(3,1,2),[pickup(3,1)]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]],[goal(1,9,0),[]]] Cycle 19: World: [junk(1,9,0),junk(4,9,9),junk(3,1,2)] Beliefs: [at(3,1)] Percepts: [junk(4,9,9),junk(3,1,2)] Intentions: [[goal(3,1,2),[pickup(3,1)]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]],[goal(1,9,0),[]]] New Intentions: [[goal(3,1,2),[]],[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]],[goal(1,9,0),[]]] Action: pickup(3,1) scores 2 Updated World: [junk(1,9,0),junk(4,9,9)] Observation: cleaned(3,1) Updated Beliefs: [at(3,1)] Updated Intentions: [[goal(4,9,9),[move(5,3),move(4,3),move(4,4),move(4,5),move(4,6),move(4,7),move(4,8),move(4,9),pickup(4,9)]],[goal(1,9,0),[]]] Total score: 23 true.
__MACOSX/Prolog/FAQ/._agent_trial.txt
Prolog/FAQ/FAQ.png
__MACOSX/Prolog/FAQ/._FAQ.png
Prolog/gridworld.pro
% Simulates a single agent in the Gridworld where junk appears on each cycle % at randomly determined locations in the 10x10 grid with probability 0.1 % run a trial of 20 cycles of the BDI interpreter starting with the agent at (0,0) agent_trial :- init, agent_trials(0, 20, [at(0,0)], [], 0, Score), write('Total score: '), writeln(Score), !. % initial state of the world init :- assert(junk(0,0,0)), retractall(junk(_,_,_)), retractall(robot_at(_,_)), assert(robot_at(0,0)). % run trials up to N agent_trials(N, N, _, _, Score, Score) :- !. agent_trials(N1, N, Beliefs, Intentions, Score, Score2) :- N1 < N, agent_cycle(N1, Beliefs, Beliefs1, Intentions, Intentions1, S), Score1 is Score + S, N2 is N1 + 1, agent_trials(N2, N, Beliefs1, Intentions1, Score1, Score2). % the BDI interpretation cycle used by the agent agent_cycle(N, Beliefs, Beliefs1, Intentions, Intentions3, S) :- write('Cycle '), write(N), writeln(':'), new_events(3), world(World), write(' World: '), writeln(World), write(' Beliefs: '), writeln(Beliefs), percepts(World, Beliefs, Percepts), write(' Percepts: '), writeln(Percepts), trigger(Percepts, Goals), incorporate_goals(Goals, Beliefs, Intentions, Intentions1), write(' Intentions: '), writeln(Intentions1), select_action(Beliefs, Intentions1, Intentions2, Action), write(' New Intentions: '), writeln(Intentions2), write(' Action: '), write(Action), execute(Action, S), write(' scores '), writeln(S), world(World1), write(' Updated World: '), writeln(World1), observe(Action, Observation), write(' Observation: '), writeln(Observation), update_beliefs(Observation, Beliefs, Beliefs1), write(' Updated Beliefs: '), writeln(Beliefs1), update_intentions(Observation, Intentions2, Intentions3), write(' Updated Intentions: '), writeln(Intentions3). % list of junk items in the world world(World) :- bagof(junk(X,Y,S), junk(X,Y,S), World), !. world([]). % each with probability 0.1, a new junk item appears in at most M random locations on the 10x10 grid new_events(0). new_events(M) :- Prob is random(10), Prob = 0, X is round(random(10)), Y is round(random(10)), not(junk(X,Y,_)), !, % check that no junk is already at location S is round(random(10)), write(' Event: junk value '), write(S), write(' appears at '), write('('), write(X), write(','), write(Y), writeln(')'), assert(junk(X,Y,S)), M1 is M - 1, new_events(M1). new_events(M) :- M1 is M - 1, new_events(M1). % new percepts are junk items within a viewing range of 10 of the agent percepts([], _, []). percepts([junk(X,Y,S)|World], [at(X1,Y1)], [junk(X,Y,S)|Percepts]) :- distance((X,Y), (X1,Y1), D), D < 10, !, percepts(World, [at(X1,Y1)], Percepts). percepts([junk(_,_,_)|World], Beliefs, Percepts) :- percepts(World, Beliefs, Percepts). % applicable actions in a state applicable([at(X,Y)], move(X1,Y1)) :- distance((X,Y), (X1,Y1), 1). applicable([at(X,Y)], pickup(X,Y)). % execute action in the Gridworld -- always successfully! execute(pickup(X,Y), S) :- retract(junk(X,Y,S)), assert(cleaned(X,Y)). execute(move(X,Y), 0) :- retract(robot_at(X1,Y1)), distance((X1,Y1), (X,Y), 1), assert(robot_at(X,Y)). % Manhattan distance between two squares distance((X,Y), (X1,Y1), D) :- dif(X, X1, Dx), dif(Y, Y1, Dy), D is Dx + Dy. % D is |A - B| dif(A, B, D) :- D is A - B, D >= 0, !. dif(A, B, D) :- D is B - A. % observe result of action -- always correctly! observe(move(_,_), at(X,Y)) :- robot_at(X, Y). observe(pickup(_,_), cleaned(X,Y)) :- retract(cleaned(X,Y)).