;;; Missionaries and Cannibals ;;; ;;; JD 30-Jun-94: Initially created. ;;; JD 5-Jul-94: Comments altered. ;;; ;;; At present, there are two "safe" calls per schema even though ;;; each call tests both banks. (This is because "safe" was written ;;; for a version that used "satisfies" and had to work that way.) ;;; So either the safe procedure should be changed or the redundant ;;; computes should be eliminated. ;;; A state has the form {boat_bank m_left c_left m_right c_right}. ;;; Presumably we could omit the counts for one side, since they're ;;; implicit in the counts for the other. language lisp; (defun safe (m c) (and (safe1 m c) ; on one bank (safe1 (- 3 m) ; and the other bank (- 3 c)))) (defun safe1 (m c) ; on one bank (and (>= m 0) (>= c 0) (or (= m 0) (>= m c)))) end_language; ;;; Tasks task mc_problem; nodes 1 start, 2 finish; orderings 1 ---> 2; conditions achieve {state} = {right 0 0 3 3} at 2; effects {state} = {left 3 3 0 0} at 1, {tried ?? ?? ?? ?? ??} = false at 1; end_task; ;;; Schemas that move people to left to right schema move_2_missionaries_right; vars ?ml, ?cl, ?mr, ?cr, ?new_ml, ?new_mr; expands {move 2 m r}; only_use_for_effects {state} = {right ?new_ml ?cl ?new_mr ?cr}; ;;; want {left ?new_ml+2 ?cl ?new_mr-2 ?cr} ;;; hence ?ml = ?new_ml + 2, ;;; ?mr = ?new_mr - 2 conditions compute {+ ?new_ml 2} = ?ml, compute {- ?new_mr 2} = ?mr, compute {safe ?ml ?cl}, compute {safe ?mr ?cr}, only_use_if {tried left ?ml ?cl ?mr ?cr} = false, achieve {state} = {left ?ml ?cl ?mr ?cr}; effects {tried left ?ml ?cl ?mr ?cr} = true; end_schema; schema move_2_cannibals_right; vars ?ml, ?cl, ?mr, ?cr, ?new_cl, ?new_cr; expands {move 2 c r}; only_use_for_effects {state} = {right ?ml ?new_cl ?mr ?new_cr}; conditions compute {+ ?new_cl 2} = ?cl, compute {- ?new_cr 2} = ?cr, compute {safe ?ml ?cl}, compute {safe ?mr ?cr}, only_use_if {tried left ?ml ?cl ?mr ?cr} = false, achieve {state} = {left ?ml ?cl ?mr ?cr}; effects {tried left ?ml ?cl ?mr ?cr} = true; end_schema; schema move_1_missionary_right; vars ?ml, ?cl, ?mr, ?cr, ?new_ml, ?new_mr; expands {move 1 m r}; only_use_for_effects {state} = {right ?new_ml ?cl ?new_mr ?cr}; ;;; want {left ?new_ml+1 ?cl ?new_mr-1 ?cr} ;;; hence ?ml = ?new_ml + 1, ;;; ?mr = ?new_mr - 1 conditions compute {+ ?new_ml 1} = ?ml, compute {- ?new_mr 1} = ?mr, compute {safe ?ml ?cl}, compute {safe ?mr ?cr}, only_use_if {tried left ?ml ?cl ?mr ?cr} = false, achieve {state} = {left ?ml ?cl ?mr ?cr}; effects {tried left ?ml ?cl ?mr ?cr} = true; end_schema; schema move_1_cannibal_right; vars ?ml, ?cl, ?mr, ?cr, ?new_cl, ?new_cr; expands {move 1 c r}; only_use_for_effects {state} = {right ?ml ?new_cl ?mr ?new_cr}; conditions compute {+ ?new_cl 1} = ?cl, compute {- ?new_cr 1} = ?cr, compute {safe ?ml ?cl}, compute {safe ?mr ?cr}, only_use_if {tried left ?ml ?cl ?mr ?cr} = false, achieve {state} = {left ?ml ?cl ?mr ?cr}; effects {tried left ?ml ?cl ?mr ?cr} = true; end_schema; schema move_1_of_each_right; vars ?ml, ?cl, ?mr, ?cr, ?new_ml, ?new_cl, ?new_mr, ?new_cr; expands {move 1 m 1 c r}; only_use_for_effects {state} = {right ?new_ml ?new_cl ?new_mr ?new_cr}; conditions compute {+ ?new_ml 1} = ?ml, compute {+ ?new_cl 1} = ?cl, compute {- ?new_mr 1} = ?mr, compute {- ?new_cr 1} = ?cr, compute {safe ?ml ?cl}, compute {safe ?mr ?cr}, only_use_if {tried left ?ml ?cl ?mr ?cr} = false, achieve {state} = {left ?ml ?cl ?mr ?cr}; effects {tried left ?ml ?cl ?mr ?cr} = true; end_schema; ;;; Schemas that move people right to left schema move_1_missionary_left; vars ?ml, ?cl, ?mr, ?cr, ?new_ml, ?new_mr; expands {move 1 m l}; only_use_for_effects {state} = {left ?new_ml ?cl ?new_mr ?cr}; ;;; want {right ?new_ml-1 ?cl ?new_mr+1 ?cr} ;;; hence ?ml = ?new_ml - 1, ;;; ?mr = ?new_mr + 1 conditions compute {- ?new_ml 1} = ?ml, compute {+ ?new_mr 1} = ?mr, compute {safe ?ml ?cl}, compute {safe ?mr ?cr}, only_use_if {tried right ?ml ?cl ?mr ?cr} = false, achieve {state} = {right ?ml ?cl ?mr ?cr}; effects {tried right ?ml ?cl ?mr ?cr} = true; end_schema; schema move_1_cannibal_left; vars ?ml, ?cl, ?mr, ?cr, ?new_cl, ?new_cr; expands {move 1 c l}; only_use_for_effects {state} = {left ?ml ?new_cl ?mr ?new_cr}; conditions compute {- ?new_cl 1} = ?cl, compute {+ ?new_cr 1} = ?cr, compute {safe ?ml ?cl}, compute {safe ?mr ?cr}, only_use_if {tried right ?ml ?cl ?mr ?cr} = false, achieve {state} = {right ?ml ?cl ?mr ?cr}; effects {tried right ?ml ?cl ?mr ?cr} = true; end_schema; schema move_1_of_each_left; vars ?ml, ?cl, ?mr, ?cr, ?new_ml, ?new_cl, ?new_mr, ?new_cr; expands {move 1 m 1 c l}; only_use_for_effects {state} = {left ?new_ml ?new_cl ?new_mr ?new_cr}; conditions compute {- ?new_ml 1} = ?ml, compute {- ?new_cl 1} = ?cl, compute {+ ?new_mr 1} = ?mr, compute {+ ?new_cr 1} = ?cr, compute {safe ?ml ?cl}, compute {safe ?mr ?cr}, only_use_if {tried right ?ml ?cl ?mr ?cr} = false, achieve {state} = {right ?ml ?cl ?mr ?cr}; effects {tried right ?ml ?cl ?mr ?cr} = true; end_schema; schema move_2_missionaries_left; vars ?ml, ?cl, ?mr, ?cr, ?new_ml, ?new_mr; expands {move 2 m l}; only_use_for_effects {state} = {left ?new_ml ?cl ?new_mr ?cr}; conditions compute {- ?new_ml 2} = ?ml, compute {+ ?new_mr 2} = ?mr, compute {safe ?ml ?cl}, compute {safe ?mr ?cr}, only_use_if {tried right ?ml ?cl ?mr ?cr} = false, achieve {state} = {right ?ml ?cl ?mr ?cr}; effects {tried right ?ml ?cl ?mr ?cr} = true; end_schema; schema move_2_cannibals_left; vars ?ml, ?cl, ?mr, ?cr, ?new_cl, ?new_cr; expands {move 2 c l}; only_use_for_effects {state} = {left ?ml ?new_cl ?mr ?new_cr}; conditions compute {- ?new_cl 2} = ?cl, compute {+ ?new_cr 2} = ?cr, compute {safe ?ml ?cl}, compute {safe ?mr ?cr}, only_use_if {tried right ?ml ?cl ?mr ?cr} = false, achieve {state} = {right ?ml ?cl ?mr ?cr}; effects {tried right ?ml ?cl ?mr ?cr} = true; end_schema; ;;; End