530 likes | 665 Views
Agent Programming in Goal Modules. Koen Hindriks Delft University of Technology, The Netherlands. Agents in Games. Outline. Modules BW4T Assignment. Modules. An Agent is a Set of Modules. init module{ knowledge{ … } beliefs{ %%% INITIAL BELIEFS ONLY IN INIT MODULE %%% }
E N D
Agent Programming in GoalModules Koen Hindriks Delft University of Technology, The Netherlands
Outline • Modules • BW4T Assignment
An Agent is a Set of Modules init module{ knowledge{ … } beliefs{ %%% INITIAL BELIEFS ONLY IN INIT MODULE %%% } goals{ … } program{ %%% PROCESS “SEND ONCE” PERCEPTS HERE %%% } actionspec{ %%% SPECIFY ENVIRONMENT ACTIONS HERE %%% } } main module{ % OPTIONAL knowledge section % NO beliefs section HERE! % OPTIONAL goal section (not advised in ‘main’) program{ %%% ENVIRONMENT ACTION SELECTION HERE %%% } } event module{ program{ %%% PROCESS PERCEPTS HERE %%% %%% PROCESS MESSAGES HERE %%% %%% PERFORM GOAL MANAGEMENT HERE %%% } } Built-in modules: • init module: • Define global knowledge • Define initial beliefs & goals • Process “send once” percepts • Specify environment actions • main module • Action selection strategy • event module • Process percepts • Process messages • Goal management User-defined modules.
Processing Percepts Types of percepts: • “send once” • “send always” • “send on change” • “send on change with negation” How to handle these different type of percepts?
Pattern for Send Always Last Lecture: Rule 1: If the agent • perceives block X is on top of block Y, and • does not believe that X is on top of Y Then inserton(X,Y)into the belief base. Rule 2: If the agent • believes that X is on top of Y, and • does not perceive block X is on top of block Y Then remove on(X,Y)from the belief base. event module { program{ % assumes full observability. forall bel(percept(on(X,Y)), not(on(X,Y))) do insert(on(X,Y)). forall bel(on(X,Y), not(percept(on(X,Y)))) do delete(on(X,Y)). } }
Pattern for Send Once “Send once” percepts are sent only once when the environment just has been launched. Use the init module to insert the beliefs you want to use in the agent’s belief base. init module { … program{ forall bel(percept(place(X)) do insert(place(X)). … } }
Pattern for Send on Change “Send on change” percepts are sent only when something a feature in the environment has changed. Rule: remove old belief and insert the new percept. Put rule in event module. NB: Use ‘forall’ rules for processing percepts. event module { … program{ forall bel(state(Old), percept(state(New)) do delete(state(Old) + insert(state(New)). … } }
Send on Change Percept • “send on change” percepts are sent once when change occurs: • Note that pattern for “send always” percepts does not work for “send on change” due to second rule in that pattern. - at(‘RoomA1’) at(‘FrontA1’) State 2 State 3 State 4 State 1 State 5 event module { % send always pattern program{ … forallbel(on(X,Y), not(percept(on(X,Y)))) do delete(on(X,Y)). } }
Send on Change with Negation “Send on change with negation” percepts: • Positive fact sent once when it becomes true in environment . • Negative fact sent once when it becomes false in environment. Rule: insert positive and remove negative facts. Put rule in event module. event module { … program{ forall bel(percept(in(RoomID)) do insert(in(RoomID)). forall bel(percept(not(in(RoomID))) do delete(in(RoomID)). ... } }
Combining Information In BW4T it is most important to remember in which place a colored block can be found. Idea: combine ‘at’ location with ‘color’ percept using a new ‘block’ predicate. NB: make sure by earlier rule that ‘at’ belief is correct. event module { … program{ … forall bel( percept(color(BlockID, ColorID)), at(PlaceID) ) do insert( block(BlockID, ColorID, PlaceID) ). forall bel( at(PlaceID), block(BlockID, ColorID, PlaceID), percept(not(color(BlockID, ColorID))) ) do delete( block(BlockID, ColorID, PlaceID) ). … } }
Defined Module Components init module{ ... } main module{ program{ } } event module{ ... } %%% YOUR OWN MODULES GO HERE %%% %%% CAN ALSO IMPORT MODULES %%% module moduleName { % may have: [<options>] knowledg{ … } % optional goals{ … } % optional program{ … } % OBLIGATORY actionspec{ … } % optional } • User-defined module is similar to any other module. • Even though knowledge may be specified within a module, knowledge is global. I.e. all knowledge is put in a global knowledge base. • Goals, macros, rules and actions specified within a module are local: They can only be used within that module.
Tower Env: Agent Design % moving X on top of Y is a constructive move if that move results in X being % in position. #define constructiveMove(X, Y) a-goal( tower([X, Y | T]) ), bel( tower([Y | T]), clear(Y), (clear(X) ; holding(X)) ) . main module{ program{ % pick up a block if you can and want to. if a-goal( holding(X) ) then pickup(X) . % put a block you're holding down, ideally where you want it, but otherwise put it on the table. if bel( holding(X) ) then { if constructiveMove(X,Y) then putdown(X, Y) . if true then putdown(X, table) . } % otherwise, there is nothing to do, so we can move the gripper to the top left corner. % no need to check whether we're holding a block because of linear order. if true then nil . } } Design rule: Try to only use action rules that select environment actions in main module. Use main module to define a strategy for handling the environment as above.
Tower Env: Agent Design main module{ program{ … if a-goal( holding(X) ) then pickup(X) . if bel( holding(X) ) then { if constructiveMove(X,Y) then putdown(X, Y) . if true then putdown(X, table) . } if true then nil . } } event module{ program{ … % process percepts from Tower World environment. rules below assume full observability. forallbel( block(X), not(percept(block(X))) ) do delete( block(X) ) . forallbel( percept(block(X)), not(block(X)) ) do insert( block(X) ) . forallbel( holding(X), not(percept(holding(X))) ) do delete( holding(X) ) . forallbel( percept(holding(X)), not(holding(X)) ) do insert( holding(X) ) . forallbel( on(X,Y), not(percept(on(X,Y))) ) do delete( on(X,Y) ) . forallbel( percept(on(X,Y)), not(on(X,Y)) ) do insert( on(X,Y) ) . … } Process perceptsfirst in event module. Always use most up-to-date information.
Tower Env: Agent Design event module{ program{ % a block is *in position* if it achieves a goal. #define inPosition(X) goal-a( tower([X|T]) ) . … % GOAL MANAGEMENT % check for reasons to DROP a goal FIRST. if goal( holding(X) ) then { % first reason: cannot pick up block X because it's not clear. if bel( not(clear(X)) ) then drop( holding(X) ) . % second reason: cannot pick up block X because now holding other block! if bel( holding(_) ) then drop( holding(X) ) . % third reason: block X is already in position, don't touch it. if inPosition( X ) then drop( holding(X) ) . % fourth reason: we can do better by moving another block constructively. listall L <- constructiveMove(Y,Z) do { if bel(not(L=[]), not(member([X,_],L))) then drop( holding(X) ) . } } % check reasons for ADOPTING a goal. % holding(X) is a *single instance goal* to maintain focus. if not(goal( holding(X) )) then adoptgoal. } } … What is adoptgoal? Strategy for adopting goals rules in user-defined module Locate rules for updating the agent’s mental state outside main module. Design rule: for GOAL Mngt, first delete content, then add content.
Tower Env: Agent Design main module{ program{ … if a-goal( holding(X) ) then pickup(X) . … } } event module{ program{ … % holding(X) is a *single instance goal* to maintain focus. if not(goal( holding(X) )) then adoptgoal. } } module adoptgoal{ % default order=linear: adopt at most one goal to hold a block at any time. % gripper cannot hold more than one block. program{ #define obstructingBlock(X) a-goal( on(Y, Z) ), bel( above(X, Z); above(X, Y) ) . if constructiveMove(X, Y) then adopt( holding(X) ) . % prefer making constructive moves. if obstructingBlock(X) then adopt( holding(X) ) . } } … Use of single instance goal for maintaining focus. Standard module: select one applicable action, perform it, and exit module again.
Tower Env: Agent Design main: towerBuilder { … event module{ program{ % a block is *in position* if it achieves a goal. #define inPosition(X) goal-a( tower([X|T]) ) . … % check for reasons to drop or adopt a goal (goal management). if goal( holding(X) ) then { % first reason: cannot pick up block X. if not(bel( clear(X) )) then drop( holding(X) ) . % second reason: block X is already in position, don't touch it. if inPosition( X ) then drop( holding(X) ) . } % adopt new goal only after cleaning up. if not(goal( holding(X) )) then adoptgoal. } } module adoptgoal{ program{ … if constructiveMove(X, Y) then adopt( holding(X) ) . if obstructingBlock(X) then adopt( holding(X) ) . } … Q: Why not put all goal management rules in managegoal module? A: In event module all rules are applied, but we want to adopt at most one goal.
DEMO • Tower Agent • Goal Achievement • Listall • Modules
Multiple Goals in Blocks World init module{ knowledge{ block(X) :- on(X, Y). clear(X) :- block(X), not(on(Y,X)). clear(table). tower([X]) :- on(X, table). tower([X,Y|T]) :- on(X,Y), tower([Y|T]). } goals{ on(a, b), on(b, c), on(c, table). on(d, e), on(e, f), on(f, table). } actionspec{ move(X,Y) { pre{ clear(X),clear(Y),on(X,Z),not(on(X,Y)) } post{ not(on(X,Z)), on(X,Y) } } } } main module{ program[order=random]{ #define misplaced(X) a-goal(tower([X|T])). #define constructiveMove(X,Y) a-goal(tower([X,Y|T])), bel(tower([Y|T])). ifconstructiveMove(X,Y) then move(X,Y). if misplaced(X) then move(X, table). } } ... Objective: Move blocks in initial state such that all goals are achieved. EXERCISE: Q: Does agent achieve goals? A: Yes. Goals are not conflicting.
Multiple Goals in Blocks World init module{ knowledge{ block(X) :- on(X, Y). clear(X) :- block(X), not(on(Y,X)). clear(table). tower([X]) :- on(X, table). tower([X,Y|T]) :- on(X,Y), tower([Y|T]). } goals{ on(a, e), on(e, c), on(c, table). on(d, e), on(e, f), on(f, table). } actionspec{ move(X,Y) { pre{ clear(X),clear(Y),on(X,Z),not(on(X,Y)) } post{ not(on(X,Z)), on(X,Y) } } } } main module{ program[order=random]{ #define misplaced(X) a-goal(tower([X|T])). #define constructiveMove(X,Y) a-goal(tower([X,Y|T])), bel(tower([Y|T])). ifconstructiveMove(X,Y) then move(X,Y). if misplaced(X) then move(X, table). } } Objective: Move blocks in initial state such that all goals are achieved. EXERCISE: Q: Does agent achieve goals? A: No. After achieving one of the goals the agent cannot remove block a or d.
Multiple Goals in Blocks World init module{ knowledge{ block(X) :- on(X, Y). clear(X) :- block(X), not(on(Y,X)). clear(table). tower([X]) :- on(X, table). tower([X,Y|T]) :- on(X,Y), tower([Y|T]). } goals{ on(a, e), on(e, c), on(c, table). on(d, e), on(e, f), on(f, table). } actionspec{ move(X,Y) { pre{ clear(X),clear(Y),on(X,Z),not(on(X,Y)) } post{ not(on(X,Z)), on(X,Y) } } } } main module{ program[order=random]{ #define misplaced(X) a-goal(tower([X|T])). #define constructiveMove(X,Y) a-goal(tower([X,Y|T])), bel(tower([Y|T])). ifconstructiveMove(X,Y) then move(X,Y). if misplaced(X) then move(X, table). } } Objective: Move blocks in initial state such that all goals are achieved. EXERCISE: Q: How can this be fixed?
Multiple Goals in Blocks World init module{ knowledge{ block(X) :- on(X, Y). clear(X) :- block(X), not(on(Y,X)). … above(X,Y) :- on(X,Y). above(X,Y) :- on(X,Z), above(Z,Y). } goals{ on(a, e), on(e, c), on(c, table). on(d, e), on(e, f), on(f, table). } actionspec{ move(X,Y) { pre{ clear(X),clear(Y),on(X,Z),not(on(X,Y)) } post{ not(on(X,Z)), on(X,Y) } } } } main module{ program{ #define misplaced(X) a-goal(tower([Y|T])), bel(above(X,Y) ; X=Y). #define constructiveMove(X,Y) a-goal(tower([X,Y|T])), bel(tower([Y|T])). ifconstructiveMove(X,Y) then move(X,Y). if misplaced(X) then move(X, table). } } Objective: Move blocks in initial state such that all goals are achieved. A: Fixing the problem: A block is misplaced if it is “in the way”.
Multiple Goals in Blocks World (Continued) Agent performs action: move(c,table) Agent performs action: move(e,table) Agent performs action: move(f,table) Agent performs action: move(d,table) Agent performs action: move(e,c) Agent performs action: move(e,table) Agent performs action: move(e,c) Agent performs action: move(e,table) Agent performs action: move(e,f) Agent performs action: move(e,c) Agent performs action: move(e,f) Agent performs action: move(e,c) Agent performs action: move(e,table) Agent performs action: move(e,c) Agent performs action: move(e,f) Agent performs action: move(e,table) Agent performs action: move(e,c) Agent performs action: move(e,f) Agent performs action: move(d,e) Agent performs action: move(d,table) Agent performs action: move(e,table) Agent performs action: move(e,c) Agent performs action: move(f,table) Agent performs action: move(e,f) Agent performs action: move(e,table) Agent performs action: move(e,f) Agent performs action: move(e,table) Agent performs action: move(e,f) … Agent performs action: move(e,f) Agent performs action: move(d,e) Objective: Move blocks in initial state such that all goals are achieved. But the agent achieves its goals very inefficiently!!
Multiple Goals in Blocks World (Continued) init module{ knowledge{ block(X) :- on(X, Y). clear(X) :- block(X), not(on(Y,X)). … above(X,Y) :- on(X,Y). above(X,Y) :- on(X,Z), above(Z,Y). } goals{ on(a, e), on(e, c), on(c, table). on(d, e), on(e, f), on(f, table). } actionspec{ move(X,Y) { pre{ clear(X),clear(Y),on(X,Z),not(on(X,Y)) } post{ not(on(X,Z)), on(X,Y) } } } } main module{ program{ #define misplaced(X) a-goal(tower([Y|T])), bel(above(X,Y) ; X=Y). #define constructiveMove(X,Y) a-goal(tower([X,Y|T])), bel(tower([Y|T])). ifconstructiveMove(X,Y) then move(X,Y). if misplaced(X) then move(X, table). } } Objective: Move blocks in initial state such that all goals are achieved. Fixing the problem (2): Part of the problem is due to randomness, adding order partly fixes this problem.
Multiple Goals in Blocks World (Continued) Agent performs action: move(c,table) Agent performs action: move(e,c) Agent performs action: move(d,table) Agent performs action: move(a,e) Agent performs action: move(a,table) Agent performs action: move(e,table) Agent performs action: move(f,table) Agent performs action: move(e,f) Agent performs action: move(d,e) Objective: Move blocks in initial state such that all goals are achieved. But still the agent performs an unnecessary action…
Multiple Goals in Blocks World init module{ knowledge{ block(X) :- on(X, Y). clear(X) :- block(X), not(on(Y,X)). … } goals{ on(a, e), on(e, c), on(c, table). on(d, e), on(e, f), on(f, table). } actionspec{ … } } main module{ program{ if a-goal(tower([X|T]), clear(X)) then buildTower. } } event module{ ... } modulebuildTower[exit=nogoals, focus=select]{ program{ ifconstructiveMove(X,Y) then move(X,Y). if misplaced(X) then move(X,table). } } Objective: Move blocks in initial state such that all goals are achieved. Fixing the problem (3): The agent also lacks focus on a single goal…
Multiple Goals in Blocks World Agent performs action: Entering module buildTower Agent performs action: move(c,table) Agent performs action: move(e,c) Agent performs action: move(d,table) Agent performs action: move(a,e) Agent performs action: Entering module buildTower Agent performs action: move(f,table) Agent performs action: move(a,table) Agent performs action: move(e,f) Agent performs action: move(d,e) Objective: Move blocks in initial state such that all goals are achieved. Focus of attention on goal removes unnecessary action…
Modules: Focus of Attention init module{ knowledge{ block(X) :- on(X, Y). clear(X) :- block(X), not(on(Y,X)). … } goals{ on(a, e), on(e, c), on(c, table). on(d, e), on(e, f), on(f, table). } actionspec{ … } } main module{ program{ if a-goal(tower([X|T]), clear(X)) then buildTower. } } modulebuildTower[exit=nogoals, focus=select]{ program{ ifconstructiveMove(X,Y) then move(X,Y). if misplaced(X) then move(X,table). } } • Focus option of module creates new attention set (‘local’ goal base): • [….., focus=select] • Mental state conditions that trigger modules act like a filter • One of the (possibly multiple) goals that satisfies the condition is put in the attention set of the module. • In the example both goals satisfy the mental state condition, so either one of: • on(a,b), on(b,c), on(c,table). • on(d,e), on(e,f), on(f,table). • may be selected and put in the attention set of the module. • For example, attention set for buildTower module is: • on(a,b), on(b,c), on(c,table).
Modules: Mental state conditions init module{ knowledge{ block(X) :- on(X, Y). clear(X) :- block(X), not(on(Y,X)). … } goals{ on(a, e), on(e, c), on(c, table). on(d, e), on(e, f), on(f, table). } actionspec{ … } } main module{ program{ if a-goal(tower([X|T]), clear(X)) then buildTower. } } modulebuildTower[exit=nogoals, focus=select]{ program{ ifconstructiveMove(X,Y) then move(X,Y). if misplaced(X) then move(X,table). } } • An attention set functions like a regular goal base. • Mental state conditions used within a module are evaluated on the attention set and the global belief base. • For example, if the attention set is: • on(a,e), on(e,c), on(c,table). • the mental state condition: • goal(tower([X,Y|T])) • yields: • [T/[c],Y/e,X/a] • [T/[],Y/c,X/e]
Modules: Action Rules When a module is activated: • Only action rules within the module’s program section are applied. • Provides: • a scoping mechanism. • encapsulation of action logic. • Actions specified outside module that are specified in init module may be used.
Modules: Options • Set exit condition using [exit=…] [exit=always] :Always exit (default) [exit=nogoals] :Exit focus goals have been achieved. [exit=noaction] :Exit when no actions are enabled. • Set filter condition using [focus=…] [focus=none] : no new attention set, global goal base used (default) [focus=new] : new empty attention set is used instead of global gb [focus=select] : new attention set with selected goal instead of global gb [focus=filter] : new attention set with filtered goal instead of global gb NB: Setting rule order option using [order=…] is associated with program sections, NOT modules. Options are: Default : [order=linear] Other options : random, linearall, randomall
Modules: Focus=Filter (Example) • Suppose current goal is: on(a,b), on(b,c), on(c,table), on(d,e), on(e,f), on(f,table), maintain. • Then mental state condition: a-goal(tower([X,Y|T])), bel(tower([Y|T]),clear(Y),(clear(X);holding(X))) and filter focusyields goals of the form: tower([a,b,c]) a-goal(on(X,table)), bel(clear(X); holding(X)) yields goals of the form: on(a,table)
focus = filter, select • A mental state only acts as a method to focus on a goal if it contains at least one positive goal literal. • a-goal(…), goal(…), goal-a(…) are positive goal literals. these act to select a focus goal. • not(a-goal(…)), not(goal(…)), not(goal-a(…)) are negative goal literals. these do not select or filter goals.
Modules: Exit Condition init module{ knowledge{ block(X) :- on(X, Y). clear(X) :- block(X), not(on(Y,X)). … } goals{ on(a, e), on(e, c), on(c, table). on(d, e), on(e, f), on(f, table). } actionspec{ … } } main module{ program{ if a-goal(tower([X|T]), clear(X)) then buildTower. } } modulebuildTower[exit=nogoals, focus=select]{ program{ ifconstructiveMove(X,Y) then move(X,Y). if misplaced(X) then move(X,table). } } • Example: [exit=nogoals] • Whenever all goals in the attention set are achieved, a module is terminated. • For example, if the attention set is: • on(a,b), on(b,c), on(c,table). • and this goal is achieved, control returns to: • top-level, or • the module from which this module was entered. • NB: modules may be entered from an active module.
Modules: Explicit exit init module{ knowledge{ block(X) :- on(X, Y). clear(X) :- block(X), not(on(Y,X)). … } goals{ on(a, e), on(e, c), on(c, table). on(d, e), on(e, f), on(f, table). } actionspec{ … } } main module{ program{ if a-goal(tower([X|T]), clear(X)) then buildTower. } } modulebuildTower[exit=nogoals, focus=select]{ program{ if bel( cannotBuildTower ) then exit-module. ifconstructiveMove(X,Y) then move(X,Y). if misplaced(X) then move(X,table). } } • The built-in action exit-module may be used to exit a module even if the goals in an attention set have not been achieved. • Use this action as in any other action rule within the program section of a module. • Best practice: if used with other actions (using the + construct), then put exit-module last.
Modules: Adopt and Drop • Semantics of the built-in adopt and drop action within modules: • adopt action within module: • Adds goal to the current attention set. • Only local effect. • drop action within module: • Removes goal from all attention sets (including global goal base) • Has global effect.
Hardcoding Rooms?? • Initial agent has: • Alternatively, use that rooms are special: • Or, use ‘in’ predicate to identify rooms: NB: 2 and 3 say drop zone’ also is a room… Fix this yourself! % list of rooms in the BW4T environment, needed for the lack of a room percept % note that the names of the rooms are strings and not variables rooms(['RoomA1','RoomA2','RoomA3','RoomB1','RoomB2','RoomB3','RoomC1','RoomC2','RoomC3']). % exploit that rooms are the only places that have one exit on all maps we use room(PlaceID) :- navpoint(_,PlaceID,_,_,Neighbours), length(Neighbours,1). % use ‘in’ to identify rooms (by means of percept rule in event module) forallbel( in(PlaceID) ) do insert( room(PlaceID) ).
Hardcoding rooms?? • Better & Simpler: % ????? … if bel(not(visited('RoomC3'))) then adopt(in('RoomC3')). if bel(visited('RoomC3'),not(visited('RoomC2'))) then adopt(in('RoomC2')). if bel(visited('RoomC2'),not(visited('RoomC1'))) then adopt(in('RoomC1')). if bel(visited('RoomC1'),not(visited('RoomB1'))) then adopt(in('RoomB1')). if bel(visited('RoomB1'),not(visited('RoomB2'))) then adopt(in('RoomB2')). if bel(visited('RoomB2'),not(visited('RoomB3'))) then adopt(in('RoomB3')). if bel(visited('RoomB3'),not(visited('RoomA3'))) then adopt(in('RoomA3')). if bel(visited('RoomA3'),not(visited('RoomA2'))) then adopt(in('RoomA2')). if bel(visited('RoomA2'),not(visited('RoomA1'))) then adopt(in('RoomA1')). … % ????? … if bel( percept(room(RoomID)), not(visited(RoomID))) then adopt(in(RoomID)). …
Spec for goToBlock(<BlockID>) Other similar example: goTo(PlaceId) with precondition not(visited(PlaceID)). • Not holding a block is NOT a precondition for being able to perform goToBlock… • goToBlock action takes time (when tick delay>0). Agent should NOT be made to believe it will immediately arrive… Guideline: Pre- and post-condition should match real conditions present in environment! goToBlock(BlockID) { pre{ not(holding(_)) } post{ state(arrived) } }
Spec for goToBlock(<BlockID>) • Doc says: “Precondition: None.” • But executing goToBlock(‘RoomA1’) gives exception (check Console). • include check whether parameter <BlockID> really is a block. • For example, goToBlock(BlockID) { pre{ color(BlockID, _), not(state(traveling)) } post{ true } }
Spec for pickUp • Doc says: “Precondition: Robot is close to a block and does not hold a block yet. Postcondition: Robot is holding the block, and the block is not located anywhere (i.e., there is no ‘at’ percept for the block) until it is dropped.” • For example, pickUp{ pre{ not(holding(_)), atBlock(BlockID) } post{ holding(BlockID) } }
Spec for putDown (1/2) • Doc says: “Precondition: Robot is holding a block at <PlaceID>. Postcondition: (i) If robot is in a room, the block is dropped within a tolerance range of the current position of the robot. (ii) If robot is not in a room and not at the drop zone, then the block leaves the environment and (iii) if robot is at the drop zone, the block is also removed from the environment.” • If robot is not in a room, the block disappears. How code this into action specification?
Spec for putDown (2/2) • If robot is not in a room, the block disappears. • Use two (or more) action specs with different pre- and post-conditions. • For example, % room disappears when it is dropped while robot is not in room. putDown{ pre{ holding(BlockID), at(PlaceID), not(room(PlaceID)) } post{ not(holding(BlockID)) } } % block is in room when putDown is performed while robot is in room. putDown{ pre{ holding(BlockID), at(PlaceID), room(PlaceID), color(BlockID, ColorID) } post{ not(holding(BlockID)), block(BlockID, ColorId, PlaceID) } }
Using the + operator • Rule of thumb: Do NOT combine environment actions that take time with + operator. • Make reasons for doing action explicit! • Increases agent’s flexibility & code readability program{ … if bel(not(holding(_)),color(A,B),nextColorInSeq(B)) then goToBlock(A) + pickUp. % ????? … } % BETTER: … % FIRST THINGS FIRST... LINEAR ORDER IN MAIN MODULE BY DEFAULT if a-goal( holding(ColorID) ), bel( block(BlockID, ColorID, PlaceID), atBlock(BlockID) ) then pickUp. … % if agent wants to be at block, go there. if a-goal( at(Id) ), bel( block(Id, _, _) ) then goToBlock(Id). … FIRST THINGS FIRST... (USE) LINEAR ORDER IN MAIN MODULE (DEFAULT)
Setting Goals • Adopt goals that agent will eventually believe. • For example, use atBlock(Block) en in(Room). • No need to use drop action in this case! Goals: - in(‘RoomA1’) goal adopted goal removed belief inserted Beliefs: in(‘RoomA1’)
?? PARSING ERRORS ?? knowledge{ … % Assignment 3.3: insert a predicate "nextColorInSeq(Color)“ nextColorInSeq(Color){ % ???? sequenceIndex(Q):- sequence(Q). % ???? } % ???? } • Inspect PARSE INFO tab: Prolog Parser error at line 13, position 23 in robot.goal: Missing token; expected ENDTOKEN but got '{'. • Pure Prolog code in knowledge section! • Also check Console Tab for other errors. • Stack overflow -> non-terminating Prolog rule!
ASK QUESTIONS! • If YOU cannot solve a problem… • There are at least FOUR THINGS you can do: • Check http://mmi.tudelft.nl/trac/goal. • Check Programming Guide. • Check FAQ on Goal website. • Send mail to goal@mmi.tudelft.nl or Assistants.