home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 9 / 09.iso / e / e051 / 2.ddi / EXAMPLES / MAC.OPS < prev    next >
Encoding:
Text File  |  1986-10-18  |  11.3 KB  |  366 lines

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;; A solution to the missionaries and cannibals problem
  3. ;;;
  4. ;;; This is a slightly repaired version of mac2.ops.  We want to make another
  5. ;;; version that makes left-would-be's one at a time, and doesn't make any
  6. ;;; (or at least not many) illegal proposed moves.  However, it must make 
  7. ;;; illegal moves, since it builds on moves to make moves with greater
  8. ;;; numbers in the boat.  It would also be a good
  9. ;;; idea to have it remember things that didn't work, stored out on a file
  10. ;;; as separate productions.
  11. ;;;
  12. ;;; Paul suggests renaming the left-would-be's, etc, so that they don't
  13. ;;; get used in later instantiations
  14. ;;;
  15. ;;; Just split the move-left move-right rules to each make only one
  16. ;;; replacer, which doesn't let things go negative on the left.
  17.  
  18. (literalize left-bank-before move dir cannibals missionaries)
  19. (literalize left-would-be move c-in-boat t-in-boat
  20.               cannibals missionaries uid)
  21.  
  22. ;;;;;;;;;;;;;;;;;;; generate possible moves ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  23. ;;; Generate moves left to right 
  24. ;;;
  25. ;;; Some illegal moves are allowed to generate, so that legal moves may
  26. ;;; be built from them, as in [left 3c 3m, boat holds 3, can't move 2m to
  27. ;;; right, but can move 3m to right
  28.  
  29. ;;; prevent negatives, but allow illegals
  30. (p move-left-to-right-2m
  31.     {<nboat> (num-in-boat 1)}
  32.     (move <i> to-right)
  33.     (left-bank-before ^move <i> ^cannibals <c> ^missionaries {<m> > 1})
  34.   -->
  35.   (make left-would-be ^move <i> ^c-in-boat 0 ^t-in-boat 2 
  36.     ^cannibals <c> ^missionaries (compute <m> - 2) ^uid (genatom)))
  37.  
  38. ;;; only if it is legal
  39. (p move-left-to-right-cm
  40.     {<nboat> (num-in-boat 1)}
  41.     (move <i> to-right)
  42.     (left-bank-before ^move <i> ^cannibals {<c> > 0}
  43.                 ^missionaries {<m> = <c>})
  44.   -->
  45.   (make left-would-be ^move <i> ^c-in-boat 1 ^t-in-boat 2 
  46.     ^cannibals (compute <c> - 1) ^missionaries (compute <m> - 1)
  47.     ^uid (genatom)))
  48.  
  49. ;;; prevent negatives, not illegals
  50. (p move-left-to-right-2c
  51.     {<nboat> (num-in-boat 1)}
  52.     (move <i> to-right)
  53.     (left-bank-before ^move <i> ^cannibals {<c> > 1} ^missionaries <m>)
  54.   -->
  55.   (make left-would-be ^move <i> ^c-in-boat 2 ^t-in-boat 2 
  56.     ^cannibals (compute <c> - 2) ^missionaries <m>     ^uid (genatom)))
  57.                               
  58. (p move-left-to-right-plus-c
  59.     (move <i> to-right)
  60.     (boat-holds <k>)
  61.     (left-bank-before ^move <i> ^cannibals <c> ^missionaries <m>)
  62.     (num-in-boat {<nb> > 1 < <k>})
  63.     (left-would-be ^move <i> ^c-in-boat <cb> ^t-in-boat <nb>  
  64.                  ^cannibals {<cl> > 0} ^missionaries <ml>)
  65.   -->
  66.   (make left-would-be ^move <i> 
  67.     ^c-in-boat (compute <cb> + 1) ^t-in-boat (compute <nb> + 1) 
  68.     ^cannibals (compute <cl> - 1) ^missionaries <ml> ^uid (genatom)))
  69.  
  70. (p move-left-to-right-plus-m  
  71.     (move <i> to-right)
  72.     (start-num <n>) (boat-holds <k>)
  73.     (left-bank-before ^move <i> ^cannibals <c> ^missionaries <m>)
  74.     (num-in-boat {<nb> > 1 < <k>})
  75.     (left-would-be ^move <i> ^c-in-boat <cb> ^t-in-boat <nb>  
  76.                  ^cannibals <cl> ^missionaries {<ml> > 0})
  77.   -->
  78.   (make left-would-be ^move <i> 
  79.     ^c-in-boat <cb> ^t-in-boat (compute <nb> + 1)
  80.     ^cannibals <cl> ^missionaries (compute <ml> - 1) ^uid (genatom)))
  81.  
  82. ;;; Generate moves right to left ;;;
  83.                               
  84. ;;; prevent negatives, not illegals
  85. (p move-right-to-left-1m
  86.     {<nboat> (num-in-boat 0)} 
  87.     (move <i> to-left)
  88.     (start-num <n>)
  89.     (left-bank-before ^move <i> ^cannibals <c>
  90.                 ^missionaries {<m> < <n>})
  91.   -->
  92.   (make left-would-be ^move <i> ^c-in-boat 0 ^t-in-boat 1 
  93.     ^cannibals <c> ^missionaries (compute <m> + 1) ^uid (genatom)))
  94.  
  95. (p move-right-to-left-1c
  96.     {<nboat> (num-in-boat 0)} 
  97.     (move <i> to-left)
  98.     (start-num <n>)
  99.     (left-bank-before ^move <i> ^cannibals {<c> < <n>} ^missionaries <m>)
  100.   -->
  101.   (make left-would-be ^move <i> ^c-in-boat 1 ^t-in-boat 1 
  102.     ^cannibals (compute <c> + 1) ^missionaries <m> ^uid (genatom)))
  103.                               
  104. (p move-right-to-left-plus-c
  105.     (move <i> to-left)
  106.     (start-num <n>)
  107.     (boat-holds <k>)
  108.     (left-bank-before ^move <i> ^cannibals <c> ^missionaries <m>)
  109.     (num-in-boat {<nb> < <k>})
  110.     (left-would-be ^move <i> ^c-in-boat <cb>
  111.                  ^t-in-boat <nb>  
  112.         ^cannibals {<cl> < <n>} ^missionaries <ml>)
  113.   -->
  114.   (make left-would-be ^move <i> 
  115.     ^c-in-boat (compute <cb> + 1) ^t-in-boat (compute <nb> + 1) 
  116.     ^cannibals (compute <cl> + 1) ^missionaries <ml> ^uid (genatom)))
  117.                        
  118.  
  119. (p move-right-to-left-plus-m
  120.     (move <i> to-left)
  121.     (start-num <n>)
  122.     (boat-holds <k>)
  123.     (left-bank-before ^move <i> ^cannibals <c> ^missionaries <m>)
  124.     (num-in-boat {<nb> < <k>})
  125.     (left-would-be ^move <i> ^c-in-boat <cb>
  126.                  ^t-in-boat <nb>  
  127.         ^cannibals <cl> ^missionaries {<ml> < <n>} )
  128.   -->
  129.   (make left-would-be ^move <i> 
  130.     ^c-in-boat <cb> ^t-in-boat (compute <nb> + 1)
  131.     ^cannibals <cl> ^missionaries (compute <ml> + 1) ^uid (genatom)))
  132.  
  133. (p incremental-remove-duplicates
  134.     (num-in-boat)
  135.     -(prune-moves duplicates)
  136.    -->
  137.   (make prune-moves duplicates))
  138.                               
  139. (p increment-num-in-boat
  140.     (boat-holds <k>)
  141.     {<nboat> (num-in-boat {<nb> < <k>})}
  142.     {<duple> (prune-moves duplicates)}
  143.    -->
  144.   (remove <duple>)
  145.   (modify <nboat> ^2 (compute <nb> + 1)))
  146.                               
  147. (p end-move-generate
  148.     (boat-holds <k>)
  149.     {<nboat> (num-in-boat >= <k>)}
  150.     (move <i> <dir>)
  151.    -->
  152.    (remove <nboat>)
  153.    (make prune-moves <dir>))
  154.  
  155. ;;;;;;;;;;;;;;;;;;;;;;;; prune moves left or right ;;;;;;;;;;;;;;;;;
  156. ;;; note that if the before and after conditions on the banks
  157. ;;; are legal, the boat trip must also have been legal
  158.  
  159.  
  160. (p too-many-cannibals-left
  161.     (move <i>)
  162.     {<illegal>
  163.     (left-would-be ^move <i> ^c-in-boat <cb> ^t-in-boat <nb>  
  164.         ^cannibals <cl> ^missionaries {> 0 < <cl>})}
  165.        (prune-moves << to-left to-right >>)
  166.   -->
  167.   (remove <illegal>))
  168.  
  169.  
  170. (p too-many-cannibals-right
  171.     (start-num <n>)
  172.     (move <i>)
  173.     {<illegal>
  174.     (left-would-be ^move <i> ^c-in-boat <cb> ^t-in-boat <nb>  
  175.         ^cannibals <cl> ^missionaries {> <cl> < <n>})}
  176.        (prune-moves << to-left to-right >>)
  177.   -->
  178.   (remove <illegal>))
  179.  
  180.  
  181. (p delete-duplicates
  182.     (move <i>)
  183.     (left-would-be ^move <i> ^c-in-boat <cb> ^t-in-boat <nb>  
  184.                ^cannibals <cl> ^missionaries <ml> ^uid <uid>)
  185.        {(left-would-be ^move <i> ^c-in-boat <cb> ^t-in-boat <nb>  
  186.                   ^cannibals <cl> ^missionaries <ml> ^uid <> <uid>)
  187.     <duple>}
  188.        (prune-moves << duplicates to-left to-right >>)
  189.   -->
  190.   (remove <duple>))
  191.  
  192. (p no-return
  193.        (prune-moves << to-left to-right >>)
  194.     (start-num <n>) (move <i> <dir>)
  195.       (left-bank-before ^dir <> <dir> ^cannibals <cl>
  196.                            ^missionaries <nl>)
  197.     (left-would-be ^move <i> ^cannibals <cl>
  198.                      ^missionaries <nl>)
  199.   -->
  200.   (remove 5))
  201.  
  202. (p done-pruning
  203.     (prune-moves {<dir> << to-left to-right >>})
  204.   -->
  205.   (remove 1)
  206.   (make pick <dir>))
  207.  
  208.  
  209. ;;;;;;;;;;;;;;;;;;; pick move left or right ;;;;;;;;;;;;;;;;;;;;;;;;
  210. ;;; Here is where we look for the end condition, discovering we have
  211. ;;; solved the problem, because we had to end on a move to the right
  212. ;;; success 0 0 is end condition
  213.  
  214. (p pick-move-left-to-right  
  215.     {<picker> (pick to-right)}
  216.     (boat-holds <k>)
  217.     {<mover> (move <i> <dir>)}
  218.     (left-bank-before ^move <i> ^cannibals <c> ^missionaries <m>)
  219.     {<chosen>
  220.     (left-would-be ^move <i> ^c-in-boat <cb> ^t-in-boat <nb>  
  221.                ^cannibals <cl> ^missionaries <ml>)}
  222.     {<winometer> (success)}
  223.     -(left-would-be ^move <i> ^t-in-boat > <nb>)
  224.   -->
  225.   (remove <picker>)
  226.   (remove <mover>)
  227.   (remove <chosen>)
  228.   (make left-bank-before ^move (compute <i> + 1) ^dir to-left
  229.              ^cannibals <cl> ^missionaries <ml>)
  230.   (make num-in-boat 0)
  231.   (make move (compute <i> + 1) to-left)
  232. ;;; success is added last in order to insure the rule looking for
  233. ;;; it fires
  234.   (modify <winometer> success <cl> <ml>))
  235.  
  236. (p pick-move-right-to-left
  237.     {<picker> (pick to-left)}
  238.     (boat-holds <k>)
  239.     {<mover> (move <i> <dir>)}
  240.     (start-num <n>) 
  241.     (left-bank-before ^move <i> ^cannibals <c> ^missionaries <m>)
  242.     {<chosen>
  243.     (left-would-be ^move <i> ^c-in-boat <cb> ^t-in-boat <nb>  
  244.                ^cannibals <cl> ^missionaries <ml>)}
  245.     -(left-would-be ^move <i> ^t-in-boat < <nb>)
  246.   -->
  247.   (remove <picker>)
  248.   (remove <mover>)
  249.   (remove <chosen>)
  250.   (make left-bank-before ^move (compute <i> + 1) ^dir to-right
  251.              ^cannibals <cl> ^missionaries <ml>)
  252.   (make move (compute <i> + 1) to-right)
  253.   (make num-in-boat 1))
  254.  
  255.  
  256. ;;;;;;;;;;;;; back-track if we get stuck ;;;;;;;;;;;;;;;;;;;;;;;
  257.  
  258. (p no-luck-path-1
  259.     (success > 0)
  260.     (pick)
  261.     -(back-track)
  262.    -->
  263.    (make back-track))
  264.  
  265. (p no-luck-path-2
  266.     (success ^3 > 0)
  267.     (pick)
  268.     -(back-track)
  269.    -->
  270.    (make back-track))
  271.  
  272. (p clean-back
  273.     {<keepbacking> (back-track)}
  274.     {<mover> (move <i>)}
  275.     {<wrongpath> (left-bank-before ^move <i>)}
  276.     -(left-would-be ^move <i>)
  277.    -->
  278.    (remove <wrongpath>)
  279.    (modify <mover> ^2 (compute <i> - 1))
  280.    (modify <keepbacking> back-track))
  281.  
  282. (p back-stop-success
  283.     (back-track)
  284.     {<mover> (move <i>)}
  285.     (left-would-be ^move <i>)
  286.     (left-bank-before ^move <i> ^dir <dir>)
  287.     {<pickup> (pick)}
  288.    -->
  289.    (remove 1)
  290.    (modify <pickup> ^2 <dir>) 
  291.    (modify <mover> ^3 <dir>))
  292.  
  293. (p back-stop-failure
  294.     (back-track)
  295.     {<mover> (move 0)}
  296.     -(left-would-be)
  297.    -->
  298.    (remove 1)
  299.    (remove <mover>)
  300.    (make no-path-works))
  301.  
  302.  
  303. ;;;;;;;;;;;;;;;;;;; I/O part ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  304.  
  305. (p get-vals (start)  -->
  306.   (remove 1)
  307.   (write
  308.     (crlf)
  309.     "A production system to solve the generalized missionaries"    (crlf)
  310.     "and cannibals problem.  In this problem we have an equal"    (crlf)
  311.     "number of missionaries and cannibals on the left bank of" (crlf)
  312.     "a river, with a boat to take them across.  The boat will" (crlf)
  313.     "not hold all the missionaries and cannibals, so several" (crlf)
  314.     "crossings are needed.  If ever the cannibals outnumber the" (crlf)
  315.     "missionaries on either bank or in the boat, disaster will" (crlf)
  316.     "strike."
  317.     (crlf) (crlf)
  318.     "Enter the number of missionaries starting at the left bank" (crlf)
  319.     "we assume the same number of cannibals on the left bank," (crlf)
  320.     "and no missionaries or cannibals on the right bank" (crlf))
  321.   (bind <x> (accept))
  322.   (write
  323.     (crlf)
  324.     "Enter the maximum number of people who can travel in the" (crlf)
  325.     "boat in one trip." (crlf))
  326.   (bind <y> (accept))
  327.   (make start-num <x>)
  328.   (make boat-holds <y>)
  329.   (make left-bank-before ^move 1 ^dir to-right
  330.              ^cannibals <x> ^missionaries <x>)
  331.   (make success <x> <x>)
  332.   (make num-in-boat 1) 
  333.   (make move 1 to-right))
  334.  
  335. (p we-did-it    (success 0 0)
  336.         (start-num <n>)
  337.         {<aftermove> (move <i>)}
  338.          {<nboat> (num-in-boat 0)} 
  339.   -->
  340.   (remove 1 <aftermove> <nboat>)
  341.   (bind <movenum> (compute <i> - 1))
  342.   (write (crlf)(crlf)
  343.       "We have succeeded in transporting " <n> " cannibals"
  344.       (crlf)
  345.       "and " <n> " missionaries safely from the left bank"
  346.     (crlf)
  347.     "to the right bank in " <movenum> " moves."
  348.     (crlf)(crlf)))
  349.  
  350. (p no-path-end  (no-path-works)
  351.         (start-num <n>)
  352.   -->
  353.   (remove 1 2)
  354.   (write (crlf)(crlf)
  355.      "We have been unable to find a schedule to transport " <n> " cannibals"
  356.      (crlf)
  357.      "and " <n> " missionaries safely from the left bank to the right bank."
  358.      (crlf)(crlf)))
  359.  
  360. (p no-can-do (start-num > 0) (boat-holds < 2)
  361.    -->
  362.    (write (crlf))
  363.    (write "sorry charlie, no can do.") 
  364.    (write (crlf))
  365.    (halt))
  366.