### ### FILE : tower-of-hanoi7.soar ### ### ### AUTHOR(1) : Aladin.Akyurek [ Soar 6.1.0 ] ### AUTHOR(2) : Tim Chapman [ Soar 7.0.4 ] ### tidied Frank Ritter 10 Dec 97 ### ### CREATED(1) : Aug 15, 93 ### ### ### MODIFIED(3) : May 27, 97 [ soar 7.0.4 ] Tim Chapman ### MODIFIED(2) : Feb 18, 94 [ soar 6.1.x ] Aladin.Akyurek ### MODIFIED(1) : Jan 11, 94 [ soar 6.1.x ] Aladin.Akyurek ### ### May 27, 97 : Added Blocksworld problem space for Tower ### Noticing Strategy. ### Feb 18, 94 : Added the Pop operator, removed the Infer space. ### Jan 11, 94 : Collapsed two problem spaces into one from ### the version which was presented at the 7th EuroSoar Workshop ### (Nov 93, Nottingham, UK). ### ### Copyright (C) Aladin Akyurek (NISCALE, Leiden, The Netherlands). ### ### TOP GOAL: ### TOWER-OF-HANOI ### watch learning -print watch -chunks -print learn -on sp {top-goal*elaborate*goal*toh "Create the top goal state" (state ^superstate nil) --> ( ^name tower-of-hanoi)} ### ### TOWER-OF-HANOI PROBLEM SPACE: ### TOWER-OF-HANOI ### sp {toh*propose*space*tower-of-hanoi "Propose the tower-of-hanoi problem space" (state ^name tower-of-hanoi) --> ( ^problem-space

) (

^name tower-of-hanoi)} ### ### TOWER-OF-HANOI PROBLEM SPACE: ### INITIAL-STATE AND DESIRED-STATE ### #prob.5d.1 #A 5-disk problem for the tower-of-hanoi system. # 1 # 2 # 3 # 4 # 5 # --- --- --- # A B C # # Initial State Desired State # This can be modified to create larger or smaller towers sp {toh*propose*state*initial-and-desired-states "A 5-Disk Tower of Hanoi Problem." (state ^name tower-of-hanoi ^problem-space

) (

^name tower-of-hanoi) --> ( ^taskstate ) ( ^disk + &, + &, + &, + &, + & ^peg + &, + &, + & ^holds

+ &,

+ &,

+ &,

+ &,

+ & ) (

^disk ^above ^on ) (

^disk ^above ^on ) (

^disk ^above ^on ) (

^disk ^above ^on ) (
^disk ^above none ^on ) ( ^name 1 ^size 1) ( ^name 2 ^size 2) ( ^name 3 ^size 3) ( ^name 4 ^size 4) ( ^name 5 ^size 5) ( ^name |A|) ( ^name |B|) ( ^name |C|) ( ^desired + &, + &, + &, + &, + & ) ( ^disk ^above ^on ) ( ^disk ^above ^on ) ( ^disk ^above ^on ) ( ^disk ^above ^on ) ( ^disk ^above none ^on )} ### ### TOWER-OF-HANOI PROBLEM SPACE: ### STATE ELABORATION/INFERENCES: ### LARGER, UPPER-DISK, AND ### CLEAR ### sp {toh*object*disk*elaborate*state*larger "If size-of(i) > size-of(j), then larger(i,j)." (state ^superstate nil ^problem-space.name tower-of-hanoi ^taskstate ) ( ^disk { <> }) ( ^size ) ( ^size > ) --> ( ^larger + & )} sp {toh*object*disk*elaborate*state*upper-disk "If not(above(x,disk)), then upper-disk(disk)." (state ^problem-space.name tower-of-hanoi ^taskstate ) ( ^disk ) -{ ( ^holds ) ( ^above ) } --> ( ^upper-disk + & )} sp {toh*object*peg*elaborate*state*clear "If not(on(x,peg)), then clear(peg)." (state ^problem-space.name tower-of-hanoi ^taskstate ) ( ^peg ) -{ ( ^holds ) ( ^on ) } --> ( ^clear + & )} ### ### TOWER-OF-HANOI PROBLEM SPACE OPERATORS: ### SET-FOCUS AND MOVE-DISK ### For POP and GOAL-TEST, see below. ### sp {toh*propose*operator*set-focus*disk-to-move "If no focus [i.e., no disk-to-move], then create one." (state ^problem-space

^taskstate ) (

^name tower-of-hanoi) ( -^disk-to-move) --> ( ^operator + <, = ) ( ^name set-focus ^previous-focus none ^done? no)} ## -fer moveable? sp {toh*propose*operator*set-focus*disk-to-move*alternative "If the disk in focus is not movable, change the focus." (state ^problem-space

^taskstate ) (

^name tower-of-hanoi) ( ^disk-to-move ) # ( ^disk ) # ( -^moveable yes) --> ( ^operator + <, = ) ( ^name set-focus ^previous-focus ^done? no)} sp {toh*propose*operator*move-disk*disk-to-move*onto "Move disk when target peg is clear." (state ^problem-space

^taskstate ) (

^name tower-of-hanoi) ( ^disk-to-move ^upper-disk ^peg ^clear ^holds ) ( ^disk ^from { <> } ^to ) ( ^disk ^on ) --> ( ^operator ) ( ^name move-disk ^disk ^from ^to ^done? no)} sp {toh*propose*operator*move-disk*disk-to-move*above "Move disk where upper disk on the target peg is larger." (state ^problem-space

^taskstate ) (

^name tower-of-hanoi) ( ^disk-to-move ^upper-disk ^peg -^clear ^holds ) ( ^disk ^from { <> } ^to ) ( ^disk ^on ) ( ^disk ^on ) ( ^larger ) --> ( ^operator ) ( ^name move-disk ^disk ^from ^to ^done? no)} ### ### TOWER-OF-HANOI PROBLEM SPACE: ### OPERATOR IMPLEMENTATION ### sp {implement*move-disk*from-above*nodisk*target-peg*is-clear "Carry out the move when target peg is clear" (state ^operator ) (state ^problem-space

^taskstate ) ( ^name move-disk ^disk ^from ^to ^done? no) (

^name ) ( ^upper-disk ^clear ^disk-to-move ^holds ) ( ^disk ^from ^to ) ( ^disk ^above none ^on ) --> ( ^on - ) ( ^done? yes no - )} sp {implement*move-disk*from-above*adisk*target-peg*is-clear "Carry out the move from above a disk when target is clear" (state ^operator ^problem-space

^taskstate ) ( ^name move-disk ^disk ^done? no ^from ^to ) (

^name ) ( ^upper-disk ^clear ^disk-to-move ^holds ) ( ^disk ^from ^to ) ( ^disk ^above { <> none } ^on ) --> ( ^above none - ) ( ^on - ) ( ^done? yes + no - )} sp {implement*move-disk*from-above*adisk-or-nodisk*target-peg*is-not-clear "Carry out the move to a non-clear target peg" (state ^operator ^problem-space

^taskstate ) ( ^name move-disk ^disk ^done? no ^from ^to ) (

^name ) ( ^upper-disk { <> } -^clear ^disk-to-move ^holds ) ( ^disk ^from ^to ) ( ^disk ^above ^on ) ( ^disk ^on ) ( ^larger ) --> ( ^above - ) ( ^on - ) ( ^done? yes no - )} ### ### TOWER-OF-HANOI PROBLEM SPACE: ### OPERATOR TERMINATION ### sp {terminate*set-focus (state ^operator ^problem-space

^taskstate ) ( ^name set-focus ^done? yes) (

^name ) --> ( ^operator @ )} sp {terminate*move-disk (state ^operator ^problem-space

^taskstate ) ( ^name move-disk ^done? yes) (

^name ) --> ( ^operator @ )} ### ### TOWER-OF-HANOI PROBLEM SPACE: POP FOCUS ### sp {toh*propose*operator*pop*object*disk-to-move "Propose pop operator to choose disk to focus on" (state ^problem-space

^taskstate ) (

^name tower-of-hanoi) ( ^holds ^disk-to-move ) ( ^disk ^to ) ( ^disk ^on ) --> ( ^operator + =, < ) ( ^name pop ^focus ^done? no) ( ^pop? yes)} sp {task-space*compare*pop*better "Check that pop is the best operator" (state ^operator + { <> } + ) (state ^problem-space

^taskstate ) ( ^name pop) ( -^name { << pop add del >> }) (

^name ) --> ( ^operator > )} sp {implement*pop "Pop the focus to the most suitable disk" (state ^operator ^problem-space

^taskstate ) ( ^name pop ^focus ^done? no) (

^name ) ( ^ ) ( ^pop? yes) --> ( ^ - ) ( ^done? yes no - )} sp {terminate*pop (state ^operator ^problem-space

^taskstate ) ( ^name pop ^done? yes) (

^name ) --> ( ^operator @ )} ### ### TOWER-OF-HANOI PROBLEM SPACE: GOAL-TEST ### sp {toh*desired-of-disk*satisfied "Check if conditions are satisfied" (state ^desired ^problem-space

^taskstate ) ( ^disk ^above ^on ) (

^name tower-of-hanoi) ( ^holds ) ( ^disk ^above ^on ) --> ( ^satisfied + & )} sp {task-space*mark*state*pursue "Mark goals to pursue" (state ^desired -^satisfied ^problem-space

^taskstate ) (

^name ) --> ( ^pursue + & )} sp {task-space*propose*operator*goal-test*top-goal "Propose operator for if top-goal is reached" (state ^superstate nil ^problem-space

^taskstate ) (

^name ) ( -^pursue -^success) --> ( ^operator =, + ) ( ^name goal-test ^result-type success)} sp {task-space*select*operator*goal-test*better "Check if goal test is best operator" (state ^operator + { <> } + ) (state ^problem-space

^taskstate ) ( ^name goal-test) ( -^name << pop add del >>) (

^name ) ( -^pursue) --> ( ^operator > )} sp {implement*goal-test*top-goal "Implement the goal reached operator" (state ^operator ^problem-space

^taskstate ^desired ^satisfied ^superstate nil) ( ^name goal-test ^result-type ) ( -^pursue -^ ) --> (write (crlf) | ********** Goal State Achieved ********* | ) ( ^ + & ) ( ^ + & ) (halt)} sp {terminate*goal-test (state ^operator ^problem-space

^taskstate ) ( ^name goal-test) (

^name ) --> ( ^operator @ )} ### ### TOWER-OF-HANOI PROBLEM-SPACE SUBGOAL: ### PROBLEM SPACE = SET-FOCUS ### INITIAL STATE = SUPERSTATE ### sp {toh*operator-no-change*create*goal-context*set-focus "Propose the set-focus problem space on impasse" (state ^superstate.operator ^impasse no-change ^attribute operator ^superstate ) ( ^name set-focus) ( ^problem-space ^taskstate ) --> ( ^problem-space ) ( ^name set-focus) ( ^taskstate )} ### ### SET-FOCUS PROBLEM SPACE: ### STATE ELABORATION: ### IS-BLOCKED-BY AND ### LARGEST-BLOCKING-DISK ### sp {set-focus*elaborate*state*disk-to-move*blocking-disks*source "Record blocking disks on source peg" (state ^problem-space

^taskstate ) (

^name set-focus) ( ^disk-to-move ^holds ) ( ^disk ^from ^to ) ( ^disk ^on ) ( ^disk ^on ) ( ^larger ) --> ( ^is-blocked-by + & )} sp {set-focus*elaborate*state*disk-to-move*blocking-disks*target "Record blocking disks on target peg" (state ^problem-space

^taskstate ) (

^name set-focus) ( ^disk-to-move ^holds ) ( ^disk ^from ^to { <> }) ( ^disk ^on ) ( ^disk ^on ) ( ^larger ) --> ( ^is-blocked-by + & )} sp {set-focus*elaborate*state*disk-to-move*largest-blocking-disk "Record the largest blocking disk" (state ^problem-space

^taskstate ) (

^name set-focus) ( ^disk-to-move ) ( ^is-blocked-by ) -{ ( ^disk-to-move ) ( ^is-blocked-by ) ( ^larger ) } --> ( ^largest-blocking-disk )} ### ### SET-FOCUS PROBLEM SPACE OPERATORS: ### CREATE-FOCUS AND CHANGE-FOCUS ### sp {set-focus*propose*operator*create-focus "Propose to create a focus if none exists" (state ^problem-space

^taskstate ^superoperator ) (

^name set-focus) ( ^previous-focus none) --> ( ^operator + = ) ( ^name create-focus ^previous-focus none)} sp {set-focus*propose*operator*change-focus "Propose to change existing focus" (state ^problem-space

^taskstate ^superoperator ) (

^name set-focus) ( ^previous-focus { <> none }) --> ( ^operator + = ) ( ^name change-focus ^previous-focus )} ### ### SET-FOCUS PROBLEM SPACE: ### OPERATOR IMPLEMENTATION ### sp {implement*create-focus*disk-to-move*largest "Set focus to largest blocking disk" (state ^operator ^problem-space

^taskstate ^superoperator ) (

^name ) ( ^name create-focus) ( ^holds ^pursue ) ( ^disk ^on ) ( ^disk ^on ) -{ ( ^pursue ) ( ^disk ) ( ^larger ) } --> ( ^disk-to-move + & ) ( ^disk ^from ^to ) ( ^done? yes no - )} sp {implement*change-focus*disk-to-move*largest-blocker "Set focus to largest blocking disk" (state ^operator ^problem-space

^taskstate ^superoperator ) (

^name ) ( ^name change-focus ^previous-focus ) ( ^peg ^holds ^disk-to-move ) ( ^disk ^largest-blocking-disk ^from { <> } ^to { <> }) ( ^disk ^on { <> }) ( ^larger ) --> ( ^disk-to-move + &, - ) ( ^disk ^from ^to ) ( ^done? yes no - )} ### ### SET-FOCUS PROBLEM SPACE: ### OPERATOR TERMINATION ### sp {terminate*create-focus (state ^operator ^problem-space

^taskstate ) (

^name ) ( ^name create-focus) --> ( ^operator @ )} sp {terminate*change-focus (state ^operator ^problem-space

^taskstate ) (

^name ) ( ^name change-focus) --> ( ^operator @ )} ### ### TOWER-OF-HANOI PROBLEM SPACE: ### MONITOR STATE AND OPERATORS ### Various productions to provide informative output to user sp {toh*monitor*state*holds*above*disk (state ^superstate nil ^taskstate ) ( ^holds ) ( ^disk ^above ^on ) ( ^size ) ( ^size ) ( ^name ) --> (write (crlf) | On(| |,| |),Above(| |,| |).|)} sp {toh*monitor*state*holds*above*none (state ^superstate nil ^taskstate ) ( ^holds ) ( ^disk ^above none ^on ) ( ^size ) ( ^name ) --> (write (crlf) | On(| |,| |),Above(| |,-).|)} sp {toh*monitor*state*upper-disk (state ^superstate nil ^taskstate ) ( ^upper-disk ) ( ^size ) --> (write (crlf) | Upper-Disk(| |).|)} sp {toh*monitor*state*clear (state ^superstate nil ^taskstate ) ( ^clear ) ( ^name ) --> (write (crlf) | Clear(Peg(| |)).|)} sp {toh*monitor*state*disk-to-move (state ^superstate nil ^taskstate ) ( ^disk-to-move ) ( ^disk ) ( ^size ) --> (write (crlf) | Focus(Disk(| |)).|)} sp {toh*desired-state*above*disk (state ^desired ^superstate nil) ( ^disk ^above ^on ) ( ^size ) ( ^size ) ( ^name ) --> (write (crlf) | Desired[On(| |,| |),Above(| |,| |)].|)} sp {toh*desired-state*above*none (state ^desired ^superstate nil) ( ^disk ^above none ^on ) ( ^size ) ( ^name ) --> (write (crlf) | Desired[On(| |,| |),Above(| |,-)].|)} sp {toh*monitor*operator-execution*move-disk (state ^operator ^taskstate ) ( ^name move-disk ^disk ^done? yes ^from ^to ) ( ^holds ) ( ^disk ^on ) ( ^size ) ( ^name ) ( ^name ) --> (write (crlf) | Executing(Move-Disk(| |,| |,| |)).|)} ### NEW PRODUCTION ****************************************** ### Give an output on state of the world when it changes ### by Tim Chapman May 1997 sp {toh*display*operator-execution*move-disk (state ^operator ^taskstate ) ( ^name move-disk ^disk ^done? yes ^from ^to ) ( ^holds

^holds

^holds

^holds

^holds

) (

^disk.size 1 ^on ) (

^disk.size 2 ^on ) (

^disk.size 3 ^on ) (

^disk.size 4 ^on ) (
^disk.size 5 ^on ) ( ^name ) ( ^name ) ( ^name ) ( ^name ) ( ^name ) --> (write (crlf) | Disk 1 on | |, Disk 2 on | |, Disk 3 on | |, Disk 4 on | |, Disk 5 on | )} ### TOWER NOTICING PRODUCTIONS **************************** ### by Tim Chapman ### A set of rules to notice towers of size 2 to 4 sp {toh*notice*stack-size-two (state ^taskstate ) ( ^holds

) (

^above none ^disk ^on ) ( ^size 2) (

^above ^disk ^on ) ( ^size 1) ( ^name ) --> ( ^tower yes ^moveable yes) (write (crlf) | *** NOTICED TOWER SIZE TWO ON PEG (| |).|)} sp {toh*notice*stack-size-three (state ^taskstate ) ( ^holds

) (

^above none ^disk ^on ) ( ^size 3) (

^above ^disk ^on ) ( ^size 2) (

^above ^disk ^on ) ( ^size 1) ( ^name ) --> ( ^tower yes ^moveable yes) (write (crlf) | *** NOTICED TOWER SIZE THREE ON PEG (| |).|)} sp {toh*notice*stack-size-four (state ^taskstate ) ( ^holds

) (

^above none ^disk ^on ) ( ^size 4) (

^above ^disk ^on ) ( ^size 3) (

^above ^disk ^on ) ( ^size 2) (

^above ^disk ^on ) ( ^size 1) ( ^name ) --> ( ^tower yes ^moveable yes) (write (crlf) | NOTICED TOWER SIZE FOUR ON PEG (| |).|)} ### ### DEFAULT PRODUCTION ### #New Default Production For The Operator-No-Change Impasse sp {default*operator-no-change*elaborate*goal*superoperator :default (state ^impasse no-change ^attribute operator ^superstate ) (state ^operator ^problem-space ^taskstate ) --> ( ^superoperator )} ### eof of tower-of-hanoi.s ### NEW RULES FOR TOWER NOTICING ********************************** ### by Tim Chapman May 1997 # Propose to move disks in towers disk rules: sp {toh*propose*operator*move-tower-disk*onto "Move where target peg is clear." (state ^problem-space

^taskstate ) (

^name tower-of-hanoi) ( ^disk-to-move ^peg ^clear ^holds ) ( ^disk ^from { <> } ^to ) ( ^moveable yes) ( ^disk ^on ) --> ( ^operator + >) ( ^name move-disk ^disk ^done? no ^from ^to )} sp {toh*propose*operator*move-tower-disk*above "Move where upper disk on the target peg is larger." (state ^problem-space

^taskstate ) (

^name tower-of-hanoi) ( ^disk-to-move ^upper-disk ^peg -^clear ^holds ) ( ^disk ^from { <> } ^to ) ( ^moveable yes) ( ^disk ^on ) ( ^disk ^on ) ( ^larger ) --> ( ^operator + >) ( ^name move-disk ^disk ^done? no ^from ^to )} ### TOWER-OF-HANOI PROBLEM-SPACE SUBGOAL: ### PROBLEM SPACE = BLOCKSWORLD ### INITIAL STATE = SUPERSTATE or BLOCKSWORLD ### sp {toh*operator-no-change*create*goal-context*blocksworld "Create blocksworld state on impasse" (state ^superstate.operator ^impasse no-change ^attribute operator ^superstate ) ( ^name move-disk ^done? no) ( ^problem-space ^taskstate ) --> ( ^problem-space ) ( ^name blocksworld) ( ^taskstate )} sp {blocksworld*elaborate*state*disk-to-move*blocking-disks*source "Elaborate the blocksworld state to mark blocking disk" (state ^problem-space

^taskstate ^superstate.operator ) (

^name blocksworld) ( ^holds ) ( ^name move-disk ^disk ^from ^to ) ( ^disk ^on ) ( ^disk ^on ) ( ^larger ) --> ( ^disk-blocked-by + & )} sp {blocksworld*elaborate*state*disk-to-move*blocking-disks*target "Elaborate the blocksworld state to mark blocking disk" (state ^problem-space

^taskstate ^superstate.operator ) (

^name blocksworld) ( ^holds ) ( ^name move-disk ^disk ^from ^to { <> }) ( ^disk ^on ) ( ^disk ^on ) ( ^larger ) --> ( ^disk-blocked-by + & )} sp {blocksworld*elaborate*state*disk-to-move*largest-blocking-disk "Select largest blocking disk" (state ^problem-space

^taskstate ) (

^name blocksworld) ( ^disk-blocked-by ) -{ ( ^disk-blocked-by ) ( ^larger ) } --> ( ^largest-blocking-disk )} sp {blocksworld*elaborate*state*disk-to-move*mark-other-peg "Select the peg that moves the blocking disk out of the way" (state ^problem-space.name blocksworld ^superstate.operator ^taskstate ) ( ^peg ) ( ^name move-disk ^disk ^from { <> } ^to { <> }) --> ( ^other-peg )} # propose an operator to move blocking disk. sp {blocksworld*propose*operator*try-to-clear "Propose move-disk operator for blocking disk" (state ^problem-space.name blocksworld ^superstate.operator ^taskstate ) ( ^holds ^peg ) ( ^disk ) ( ^largest-blocking-disk ^other-peg ) ( ^disk ^on { <> }) ( ^larger ) --> ( ^operator + = ) ( ^name move-disk ^disk ^done? no ^from ^to )} # implement move disk op. sp {blocksworld*implement*operator*try-to-clear*from-nodisk-to-clear "Implement the move-disk operator on the blocking disk" (state ^operator ^problem-space.name blocksworld ^taskstate ) ( ^name move-disk ^disk ^done? no ^from ^to ) ( ^upper-disk ^clear ^holds ) ( ^disk ^above none ^on ) --> ( ^on - ) ( ^done? yes no - )} sp {blocksworld*implement*operator*try-to-clear*from-adisk-to-clear "Implement the move-disk operator on the blocking disk" (state ^operator ^problem-space.name blocksworld ^taskstate ) ( ^name move-disk ^disk ^done? no ^from ^to ) ( ^upper-disk ^clear ^holds ) ( ^disk ^above { <> none } ^on ) --> ( ^above none - ) ( ^on - ) ( ^done? yes no - )} sp {blocksworld*implement*operator*try-to-clear*from-any-to-not-clear "Implement the move-disk operator on the blocking disk" (state ^operator ^problem-space.name blocksworld ^taskstate ) ( ^name move-disk ^disk ^done? no ^from ^to ) ( ^upper-disk { <> } -^clear ^holds ) ( ^disk ^above ^on ) ( ^disk ^on ) ( ^larger ) --> ( ^above - ) ( ^on - ) ( ^done? yes no - )} # terminate move-disk operator. sp {terminate*try-to-clear (state ^operator ^problem-space.name blocksworld ^taskstate ) ( ^name move-disk ^done? yes) --> ( ^operator @ ) } ### eof: Tower of Hanoi