dribbling to file "09-13-01.dribble" NIL CL-USER(17): ;;; Shortest Path example from Graham, Section 3.15 CL-USER(17): (setf map '((a b c) (b c) (c d))) ((A B C) (B C) (C D)) CL-USER(18): ;; Want (shortest 'a 'd map) => (A C D) CL-USER(20): ; ;;; How? Represent partial path in reverse order. Easy to push ;;; on front and test front. CL-USER(20): ;;; (A) ;;;(C A) ;;;(D C A) CL-USER(20): ;;; Need a queue of these partial paths. Always try extending ;;; first one by one step, then move to end of queue. CL-USER(20): ;;; ((A)) ;;; ((B A) (C A)) ;;; ((C A) (C B A)) ;;; ((C B A) (D C A)) CL-USER(31): ;;;How to go from ((A)) to ((C A)(B A)) ? ;;; Need set of all successors to A. Then way to add to path. CL-USER(31): (setf node 'a) A CL-USER(32): (assoc node map) (A B C) CL-USER(33): (cdr (assoc node map)) (B C) CL-USER(34): ;;; For each of these, add to front of path CL-USER(34): (setf path '((a))) ((A)) CL-USER(35): (mapcar #'(lambda (new) (cons new path)) (cdr (assoc node map))) ((B (A)) (C (A))) CL-USER(36): (setf path '(a)) (A) CL-USER(37): (mapcar #'(lambda (new) (cons new path)) (cdr (assoc node map))) ((B A) (C A)) CL-USER(38): ;;; Kind of complicated. Let's put it into a new function CL-USER(38): (defun new-paths (path node map) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc node map)))) NEW-PATHS CL-USER(39): ;; Test it. CL-USER(39): (new-paths '((a)) 'a map) ((B (A)) (C (A))) CL-USER(40): (new-paths '(a) 'a map) ((B A) (C A)) CL-USER(41): ;; Now, do this for each path in queue so far. CL-USER(41): (setf queue '((a))) ((A)) CL-USER(42): (dolist (path queue) (new-paths path (car path) map)) NIL CL-USER(43): (dolist (path queue) (print (new-paths path (car path) map))) ((B A) (C A)) NIL CL-USER(44): (setf queue '((a)(b))) ((A) (B)) CL-USER(45): (dolist (path queue) (print (new-paths path (car path) map))) ((B A) (C A)) ((C B)) NIL CL-USER(46): ;; But results aren't being collected, and goal is not being ;;checked for. Try representing the queue differently. Getting kind of ;;hard again. A recursive approach probably more intuitive. ;;Given a path we will be removing it and adding all possible next paths. ;; Not handled as well with iteration. Let the recursive calls build ;; up the result. CL-USER(46): ;;Let's do a recursive algorithm: ;; if queue is empty, return nil ;; if first element of first path on queue is goal, return first path. ;; otherwise, search queue formed from all but first path plus new ;; paths formed from first path. CL-USER(46): (defun search (goal queue map) (cond ((endp queue) nil) (t (let* ((firstpath (first queue)) (lastnode (first firstpath))) (if (eql lastnode goal) (reverse firstpath) ;;else (search goal (append (rest queue) (new-paths firstpath lastnode map)) map)))))) Error: Attempt to make a FUNCTION definition for the name SEARCH. This name is in the COMMON-LISP package and redefining it is a violation for portable programs. Replacing the current definition of # may be dangerous. The package COMMON-LISP has PACKAGE-DEFINITION-LOCK set, which causes the system to signal this violation. [condition type: PACKAGE-LOCKED-ERROR] Restart actions (select using :continue): 0: Set the FUNCTION definition of the name SEARCH anyway. 1: Return to Top Level (an "abort" restart) 2: Abort # [1c] CL-USER(47): :pop CL-USER(48): (defun mysearch (goal queue map) (cond ((endp queue) nil) (t (let* ((firstpath (first queue)) (lastnode (first firstpath))) (if (eql lastnode goal) (reverse firstpath) ;;else (mysearch goal (append (rest queue) (new-paths firstpath lastnode map)) map)))))) MYSEARCH CL-USER(49): (defun shortest (start goal map) (mysearch goal (list (list start)) map)) SHORTEST CL-USER(50): (shortest 'a 'b map) (A B) CL-USER(51): (shortest 'a 'd map) (A C D) CL-USER(52): (trace mysearch) (MYSEARCH) CL-USER(53): (shortest 'a 'd map) 0: (MYSEARCH D ((A)) ((A B C) (B C) (C D))) 1: (MYSEARCH D ((B A) (C A)) ((A B C) (B C) (C D))) 2: (MYSEARCH D ((C A) (C B A)) ((A B C) (B C) (C D))) 3: (MYSEARCH D ((C B A) (D C A)) ((A B C) (B C) (C D))) 4: (MYSEARCH D ((D C A) (D C B A)) ((A B C) (B C) (C D))) 4: returned (A C D) 3: returned (A C D) 2: returned (A C D) 1: returned (A C D) 0: returned (A C D) (A C D) CL-USER(54): (setf bigmap '((a b c d z) (b e f) (c g h) (d i j) (e k z))) ((A B C D Z) (B E F) (C G H) (D I J) (E K Z)) CL-USER(55): (sdraw bigmap) [*|*]--------------------------------------------->[*|*]--->etc. | | v v [*|*]--->[*|*]--->[*|*]--->[*|*]--->[*|*]--->NIL [*|*]--->[*|*]--->etc. | | | | | | | v v v v v v v A B C D Z B E CL-USER(56): (mysearch 'z (list (list 'a)) map) 0: (MYSEARCH Z ((A)) ((A B C) (B C) (C D))) 1: (MYSEARCH Z ((B A) (C A)) ((A B C) (B C) (C D))) 2: (MYSEARCH Z ((C A) (C B A)) ((A B C) (B C) (C D))) 3: (MYSEARCH Z ((C B A) (D C A)) ((A B C) (B C) (C D))) 4: (MYSEARCH Z ((D C A) (D C B A)) ((A B C) (B C) (C D))) 5: (MYSEARCH Z ((D C B A)) ((A B C) (B C) (C D))) 6: (MYSEARCH Z NIL ((A B C) (B C) (C D))) 6: returned NIL 5: returned NIL 4: returned NIL 3: returned NIL 2: returned NIL 1: returned NIL 0: returned NIL NIL CL-USER(57): (mysearch 'b (list (list 'a)) map) 0: (MYSEARCH B ((A)) ((A B C) (B C) (C D))) 1: (MYSEARCH B ((B A) (C A)) ((A B C) (B C) (C D))) 1: returned (A B) 0: returned (A B) (A B) CL-USER(58): (mysearch 'e (list (list 'a)) map) 0: (MYSEARCH E ((A)) ((A B C) (B C) (C D))) 1: (MYSEARCH E ((B A) (C A)) ((A B C) (B C) (C D))) 2: (MYSEARCH E ((C A) (C B A)) ((A B C) (B C) (C D))) 3: (MYSEARCH E ((C B A) (D C A)) ((A B C) (B C) (C D))) 4: (MYSEARCH E ((D C A) (D C B A)) ((A B C) (B C) (C D))) 5: (MYSEARCH E ((D C B A)) ((A B C) (B C) (C D))) 6: (MYSEARCH E NIL ((A B C) (B C) (C D))) 6: returned NIL 5: returned NIL 4: returned NIL 3: returned NIL 2: returned NIL 1: returned NIL 0: returned NIL NIL CL-USER(59): (mysearch 'e (list (list 'a)) bigmap) 0: (MYSEARCH E ((A)) ((A B C D Z) (B E F) (C G H) (D I J) (E K Z))) 1: (MYSEARCH E ((B A) (C A) (D A) (Z A)) ((A B C D Z) (B E F) (C G H) (D I J) (E K Z))) 2: (MYSEARCH E ((C A) (D A) (Z A) (E B A) (F B A)) ((A B C D Z) (B E F) (C G H) (D I J) (E K Z))) 3: (MYSEARCH E ((D A) (Z A) (E B A) (F B A) (G C A) (H C A)) ((A B C D Z) (B E F) (C G H) (D I J) (E K Z))) 4: (MYSEARCH E ((Z A) (E B A) (F B A) (G C A) (H C A) (I D A) (J D A)) ((A B C D Z) (B E F) (C G H) (D I J) (E K Z))) 5: (MYSEARCH E ((E B A) (F B A) (G C A) (H C A) (I D A) (J D A)) ((A B C D Z) (B E F) (C G H) (D I J) (E K Z))) 5: returned (A B E) 4: returned (A B E) 3: returned (A B E) 2: returned (A B E) 1: returned (A B E) 0: returned (A B E) (A B E) CL-USER(60): (mysearch 'z (list (list 'a)) bigmap) 0: (MYSEARCH Z ((A)) ((A B C D Z) (B E F) (C G H) (D I J) (E K Z))) 1: (MYSEARCH Z ((B A) (C A) (D A) (Z A)) ((A B C D Z) (B E F) (C G H) (D I J) (E K Z))) 2: (MYSEARCH Z ((C A) (D A) (Z A) (E B A) (F B A)) ((A B C D Z) (B E F) (C G H) (D I J) (E K Z))) 3: (MYSEARCH Z ((D A) (Z A) (E B A) (F B A) (G C A) (H C A)) ((A B C D Z) (B E F) (C G H) (D I J) (E K Z))) 4: (MYSEARCH Z ((Z A) (E B A) (F B A) (G C A) (H C A) (I D A) (J D A)) ((A B C D Z) (B E F) (C G H) (D I J) (E K Z))) 4: returned (A Z) 3: returned (A Z) 2: returned (A Z) 1: returned (A Z) 0: returned (A Z) (A Z) CL-USER(62): (defun mysearch2 (goal queue map) (cond ((endp queue) nil) (t (let* ((firstpath (first queue)) (lastnode (first firstpath))) (if (eql lastnode goal) (reverse firstpath) ;;else (mysearch2 goal (append (new-paths firstpath lastnode map) (rest queue)) map)))))) MYSEARCH2 CL-USER(63): (mysearch2 'z (list (list 'a)) bigmap) (A B E Z) CL-USER(64): (defun mysearch2 (goal queue map) (cond ((endp queue) nil) (t (let ((firstpath (first queue))) (if (eql goal (first firstpath)) (reverse firstpath) ;;else (mysearch2 goal (append (new-paths firstpath map) (rest queue)) map)))))) MYSEARCH2 CL-USER(65): (defun new-paths (path map) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first map) node map)))) NEW-PATHS CL-USER(66): (mysearch2 'z (list (list 'a)) bigmap) Error: &key list isn't even. [condition type: PROGRAM-ERROR] Restart actions (select using :continue): 0: Return to Top Level (an "abort" restart) 1: Abort # [1] CL-USER(67): :bt Evaluation stack: ASSOC <- NEW-PATHS <- LET <- MYSEARCH2 <- EVAL <- TPL:TOP-LEVEL-READ-EVAL-PRINT-LOOP <- TPL:START-INTERACTIVE-TOP-LEVEL [1] CL-USER(68): :pop CL-USER(69): (defun new-paths (path map) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first map) map)))) NEW-PATHS CL-USER(70): (mysearch2 'z (list (list 'a)) bigmap) NIL CL-USER(71): (new-paths '(a) bigmap) NIL CL-USER(72): (defun new-paths (path map) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) map)))) NEW-PATHS CL-USER(73): (new-paths '(a) bigmap) ((B A) (C A) (D A) (Z A)) CL-USER(74): (mysearch2 'z (list (list 'a)) bigmap) (A B E Z) CL-USER(75): (defun breadth-first (goal queue map) (cond ((endp queue) nil) (t (let ((firstpath (first queue))) (if (eql goal (first firstpath)) (reverse firstpath) ;;else (breadth-first goal (append (rest queue) (new-paths firstpath map)) map)))))) BREADTH-FIRST CL-USER(76): (breadth-first 'z' '((a)) bigmap) Error: Attempt to take the car of QUOTE which is not listp. [condition type: SIMPLE-ERROR] Restart actions (select using :continue): 0: Return to Top Level (an "abort" restart) 1: Abort # [1] CL-USER(77): :pop CL-USER(78): (breadth-first 'z '((a)) bigmap) (A Z) CL-USER(79): (defun depth-first (goal queue map) (cond ((endp queue) nil) (t (let ((firstpath (first queue))) (if (eql goal (first firstpath)) (reverse firstpath) ;;else (depth-first goal (append (new-paths firstpath map) (rest queue)) map)))))) DEPTH-FIRST CL-USER(80): (depth-first 'z '((a)) bigmap) (A B E Z) CL-USER(81): ;; Can we generalize this code for general tree search ? ;; The specific parts are goal, map, and how to add new paths to queue. ;; Let goal be specified by some goal predicate function, called goalp ;; Let map be specified by function that takes a state and returns all successor states ;; Let method of adding new paths be done by function named combiner. CL-USER(81): (defun tree-search (goalp queue successors combiner) (cond ((endp queue) nil) (t (let ((firstpath (first queue))) (if (goalp (first firstpath)) (reverse firstpath) ;;else (tree-search goalp (funcall combiner queue (funcall successors (first firstpath))) successors combiner)))))) TREE-SEARCH CL-USER(82): ;; Test by redoing our previous example using this general code. CL-USER(82): (tree-search #'(lambda (s) (eql s 'z)) #'(lambda (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) map)))) #'append) Error: TREE-SEARCH got 3 args, wanted 4 args. [condition type: PROGRAM-ERROR] Restart actions (select using :continue): 0: Return to Top Level (an "abort" restart) 1: Abort # [1] CL-USER(83): :reset CL-USER(84): (defun tree-search (goalp queue successors combiner) (cond ((endp queue) nil) (t (let ((firstpath (first queue))) (if (goalp (first firstpath)) (reverse firstpath) ;;else (tree-search goalp (funcall combiner queue (funcall successors firstpath)) successors combiner)))))) TREE-SEARCH CL-USER(85): (tree-search #'(lambda (s) (eql s 'z)) #'(lambda (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) map)))) #'append) Error: TREE-SEARCH got 3 args, wanted 4 args. [condition type: PROGRAM-ERROR] Restart actions (select using :continue): 0: Return to Top Level (an "abort" restart) 1: Abort # [1] CL-USER(86): :pop CL-USER(87): (trace tree-search) (TREE-SEARCH) CL-USER(88): (tree-search #'(lambda (s) (eql s 'z)) #'(lambda (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) map)))) #'append) 0: (TREE-SEARCH # # #) Error: TREE-SEARCH got 3 args, wanted 4 args. [condition type: PROGRAM-ERROR] Restart actions (select using :continue): 0: Return to Top Level (an "abort" restart) 1: Abort # [1] CL-USER(89): :reset 0: returned-by-throwing NIL CL-USER(90): (tree-search #'(lambda (s) (eql s 'z)) '((a)) #'(lambda (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) bigmap)))) #'append) 0: (TREE-SEARCH # ((A)) # #) Error: attempt to call `GOALP' which is an undefined function. [condition type: UNDEFINED-FUNCTION] Restart actions (select using :continue): 0: Try calling GOALP again. 1: Return a value instead of calling GOALP. 2: Try calling a function other than GOALP. 3: Setf the symbol-function of GOALP and call it again. 4: Return to Top Level (an "abort" restart) 5: Abort # [1] CL-USER(91): :pop 0: returned-by-throwing :DEBUG-POP 0 2 CL-USER(92): (defun tree-search (goalp queue successors combiner) (cond ((endp queue) nil) (t (let ((firstpath (first queue))) (if (funcall goalp (first firstpath)) (reverse firstpath) ;;else (tree-search goalp (funcall combiner queue (funcall successors firstpath)) successors combiner)))))) TREE-SEARCH CL-USER(93): (tree-search #'(lambda (s) (eql s 'z)) '((a)) #'(lambda (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) bigmap)))) #'append) 0: (TREE-SEARCH # ((A)) # #) 1: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A)) # #) 2: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 3: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 4: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 5: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 6: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 7: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 8: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 9: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 10: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 11: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) Error: Received signal number 2 (Keyboard interrupt) [condition type: INTERRUPT-SIGNAL] Restart actions (select using :continue): 0: continue computation 1: Return to Top Level (an "abort" restart) 2: Abort # [1c] CL-USER(94): :reset 60: returned-by-throwing NIL 59: returned-by-throwing NIL 58: returned-by-throwing NIL 57: returned-by-throwing NIL 56: returned-by-throwing NIL 55: returned-by-throwing NIL 54: returned-by-throwing NIL 53: returned-by-throwing NIL 52: returned-by-throwing NIL 51: returned-by-throwing NIL 50: returned-by-throwing NIL 49: returned-by-throwing NIL 48: returned-by-throwing NIL 47: returned-by-throwing NIL 46: returned-by-throwing NIL 45: returned-by-throwing NIL 44: returned-by-throwing NIL 43: returned-by-throwing NIL 42: returned-by-throwing NIL 41: returned-by-throwing NIL 40: returned-by-throwing NIL 39: returned-by-throwing NIL 38: returned-by-throwing NIL 37: returned-by-throwing NIL 36: returned-by-throwing NIL 35: returned-by-throwing NIL 34: returned-by-throwing NIL 33: returned-by-throwing NIL 32: returned-by-throwing NIL 31: returned-by-throwing NIL 30: returned-by-throwing NIL 29: returned-by-throwing NIL 28: returned-by-throwing NIL 27: returned-by-throwing NIL 26: returned-by-throwing NIL 25: returned-by-throwing NIL 24: returned-by-throwing NIL 23: returned-by-throwing NIL 22: returned-by-throwing NIL 21: returned-by-throwing NIL 20: returned-by-throwing NIL 19: returned-by-throwing NIL 18: returned-by-throwing NIL 17: returned-by-throwing NIL 16: returned-by-throwing NIL 15: returned-by-throwing NIL 14: returned-by-throwing NIL 13: returned-by-throwing NIL 12: returned-by-throwing NIL 11: returned-by-throwing NIL 10: returned-by-throwing NIL 9: returned-by-throwing NIL 8: returned-by-throwing NIL 7: returned-by-throwing NIL 6: returned-by-throwing NIL 5: returned-by-throwing NIL 4: returned-by-throwing NIL 3: returned-by-throwing NIL 2: returned-by-throwing NIL 1: returned-by-throwing NIL 0: returned-by-throwing NIL CL-USER(95): (defun goalp (s) tree-search #'(lambda (s) (eql s 'z)) '((a)) #'(lambda (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) bigmap)))) #'append) GOALP CL-USER(96): CL-USER(96): (defun goalp (s) (eql s 'z)) GOALP CL-USER(97): (goalp 'z) T CL-USER(98): (defun successors (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) bigmap)))) SUCCESSORS CL-USER(99): (successors '((a))) NIL CL-USER(100): (successors '(a)) ((B A) (C A) (D A) (Z A)) CL-USER(101): (defun combiner (new old) (append new old)) COMBINER CL-USER(102): (tree-search #'goalp '((a)) #'successors #'combiner) 0: (TREE-SEARCH # ((A)) # #) 1: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A)) # #) 2: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 3: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 4: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 5: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 6: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 7: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 8: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 9: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 10: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 11: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 12: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A)) # #) 13: (TREE-SEARCH # ((A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) (Z A) (B A) (C A) (D A) Error: Received signal number 2 (Keyboard interrupt) [condition type: INTERRUPT-SIGNAL] Restart actions (select using :continue): 0: continue computation 1: Return to Top Level (an "abort" restart) 2: Abort # [1c] CL-USER(103): :reset 32: returned-by-throwing NIL 31: returned-by-throwing NIL 30: returned-by-throwing NIL 29: returned-by-throwing NIL 28: returned-by-throwing NIL 27: returned-by-throwing NIL 26: returned-by-throwing NIL 25: returned-by-throwing NIL 24: returned-by-throwing NIL 23: returned-by-throwing NIL 22: returned-by-throwing NIL 21: returned-by-throwing NIL 20: returned-by-throwing NIL 19: returned-by-throwing NIL 18: returned-by-throwing NIL 17: returned-by-throwing NIL 16: returned-by-throwing NIL 15: returned-by-throwing NIL 14: returned-by-throwing NIL 13: returned-by-throwing NIL 12: returned-by-throwing NIL 11: returned-by-throwing NIL 10: returned-by-throwing NIL 9: returned-by-throwing NIL 8: returned-by-throwing NIL 7: returned-by-throwing NIL 6: returned-by-throwing NIL 5: returned-by-throwing NIL 4: returned-by-throwing NIL 3: returned-by-throwing NIL 2: returned-by-throwing NIL 1: returned-by-throwing NIL 0: returned-by-throwing NIL CL-USER(104): CL-USER(104): (defun tree-search (goalp queue successors combiner) (cond ((endp queue) nil) (t (let ((firstpath (first queue))) (if (funcall goalp (first firstpath)) (reverse firstpath) ;;else (tree-search goalp (funcall combiner (rest queue) (funcall successors firstpath)) successors combiner)))))) TREE-SEARCH CL-USER(105): (tree-search #'goalp '((a)) #'successors #'combiner) 0: (TREE-SEARCH # ((A)) # #) 1: (TREE-SEARCH # ((B A) (C A) (D A) (Z A)) # #) 2: (TREE-SEARCH # ((C A) (D A) (Z A) (E B A) (F B A)) # #) 3: (TREE-SEARCH # ((D A) (Z A) (E B A) (F B A) (G C A) (H C A)) # #) 4: (TREE-SEARCH # ((Z A) (E B A) (F B A) (G C A) (H C A) (I D A) (J D A)) # #) 4: returned (A Z) 3: returned (A Z) 2: returned (A Z) 1: returned (A Z) 0: returned (A Z) (A Z) CL-USER(106): (defun combiner (new old) (append old new)) COMBINER CL-USER(107): (tree-search #'goalp '((a)) #'successors #'combiner) 0: (TREE-SEARCH # ((A)) # #) 1: (TREE-SEARCH # ((B A) (C A) (D A) (Z A)) # #) 2: (TREE-SEARCH # ((E B A) (F B A) (C A) (D A) (Z A)) # #) 3: (TREE-SEARCH # ((K E B A) (Z E B A) (F B A) (C A) (D A) (Z A)) # #) 4: (TREE-SEARCH # ((Z E B A) (F B A) (C A) (D A) (Z A)) # #) 4: returned (A B E Z) 3: returned (A B E Z) 2: returned (A B E Z) 1: returned (A B E Z) 0: returned (A B E Z) (A B E Z) CL-USER(112): (tree-search #'(lambda (s) (eql s 'z)) '((a)) #'(lambda (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) bigmap)))) #'append) 0: (TREE-SEARCH # ((A)) # #) 1: (TREE-SEARCH # ((B A) (C A) (D A) (Z A)) # #) 2: (TREE-SEARCH # ((C A) (D A) (Z A) (E B A) (F B A)) # #) 3: (TREE-SEARCH # ((D A) (Z A) (E B A) (F B A) (G C A) (H C A)) # #) 4: (TREE-SEARCH # ((Z A) (E B A) (F B A) (G C A) (H C A) (I D A) (J D A)) # #) 4: returned (A Z) 3: returned (A Z) 2: returned (A Z) 1: returned (A Z) 0: returned (A Z) (A Z) CL-USER(113): :pop CL-USER(114): (tree-search #'(lambda (s) (eql s 'z)) '((a)) #'(lambda (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) bigmap)))) #'(lambda (old new) (append new old))) 0: (TREE-SEARCH # ((A)) # #) 1: (TREE-SEARCH # ((B A) (C A) (D A) (Z A)) # #) 2: (TREE-SEARCH # ((E B A) (F B A) (C A) (D A) (Z A)) # #) 3: (TREE-SEARCH # ((K E B A) (Z E B A) (F B A) (C A) (D A) (Z A)) # #) 4: (TREE-SEARCH # ((Z E B A) (F B A) (C A) (D A) (Z A)) # #) 4: returned (A B E Z) 3: returned (A B E Z) 2: returned (A B E Z) 1: returned (A B E Z) 0: returned (A B E Z) (A B E Z) CL-USER(115): (tree-search #'(lambda (s) (eql s 'z)) '((a)) #'(lambda (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) bigmap)))) #'(lambda (old new) (append old new))) 0: (TREE-SEARCH # ((A)) # #) 1: (TREE-SEARCH # ((B A) (C A) (D A) (Z A)) # #) 2: (TREE-SEARCH # ((C A) (D A) (Z A) (E B A) (F B A)) # #) 3: (TREE-SEARCH # ((D A) (Z A) (E B A) (F B A) (G C A) (H C A)) # #) 4: (TREE-SEARCH # ((Z A) (E B A) (F B A) (G C A) (H C A) (I D A) (J D A)) # #) 4: returned (A Z) 3: returned (A Z) 2: returned (A Z) 1: returned (A Z) 0: returned (A Z) (A Z) CL-USER(116): (untrace tree-search) (TREE-SEARCH) CL-USER(117): (tree-search #'(lambda (s) (eql s 'z)) '((a)) #'(lambda (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) bigmap)))) #'(lambda (old new) (append old new))) (A Z) CL-USER(118): (tree-search #'(lambda (s) (eql s 'z)) '((a)) #'(lambda (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) bigmap)))) #'(lambda (old new) (append new old))) (A B E Z) CL-USER(119): (defun pathproblem () (defun goalp (s) (eql s 'z)) (defun successors (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) bigmap)))) (defun combiner (old new) (append new old))) PATHPROBLEM CL-USER(120): (pathproblem) COMBINER CL-USER(121): (tree-search #'goalp '((a)) #'successors #'combiner) (A B E Z) CL-USER(122): (defun pathproblem () (defun goalp (s) (eql s 'z)) (defun initial-state (s) (list (list s))) (defun successors (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) bigmap)))) (defun combiner (old new) (append new old))) PATHPROBLEM CL-USER(123): (pathproblem) COMBINER CL-USER(124): (tree-search #'goalp #'initial-state #'successors #'combiner) Error: Attempt to take the cdr of # which is not listp. [condition type: SIMPLE-ERROR] Restart actions (select using :continue): 0: Return to Top Level (an "abort" restart) 1: Abort # [1] CL-USER(125): :pop CL-USER(126): (tree-search #'goalp (initial-state 'a) #'successors #'combiner) (A B E Z) CL-USER(127): (defun pathproblem (start goal map) (defun goalp (s) (eql s goal)) (defun initial-state (start) (list (list start))) (defun successors (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) map)))) (defun combiner (old new) (append new old))) PATHPROBLEM CL-USER(128): (pathproblem 'a 'z bigmap) COMBINER CL-USER(129): (tree-search #'goalp (initial-state 'a) #'successors #'combiner) (A B E Z) CL-USER(130): (defun pathproblem (start goal map) (defun goalp (s) (eql s goal)) (defun initial-state () (list (list start))) (defun successors (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) map)))) (defun combiner (old new) (append new old))) PATHPROBLEM CL-USER(131): Error: Received signal number 2 (Keyboard interrupt) [condition type: INTERRUPT-SIGNAL] Restart actions (select using :continue): 0: continue computation 1: Abort # [1c] CL-USER(132): [1c] CL-USER(132): :reset CL-USER(133): CL-USER(133): CL-USER(133): (defun pathproblem (start goal map) (defun goalp (s) (eql s goal)) (defun initial-queue () (list (list start))) (defun successors (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) map)))) (defun combiner (old new) (append new old))) PATHPROBLEM CL-USER(134): (tree-search #'goalp (initial-queue) #'successors #'combiner) Error: attempt to call `INITIAL-QUEUE' which is an undefined function. [condition type: UNDEFINED-FUNCTION] Restart actions (select using :continue): 0: Try calling INITIAL-QUEUE again. 1: Return a value instead of calling INITIAL-QUEUE. 2: Try calling a function other than INITIAL-QUEUE. 3: Setf the symbol-function of INITIAL-QUEUE and call it again. 4: Return to Top Level (an "abort" restart) 5: Abort # [1] CL-USER(135): :pop CL-USER(136): (initial-queue) Error: attempt to call `INITIAL-QUEUE' which is an undefined function. [condition type: UNDEFINED-FUNCTION] Restart actions (select using :continue): 0: Try calling INITIAL-QUEUE again. 1: Return a value instead of calling INITIAL-QUEUE. 2: Try calling a function other than INITIAL-QUEUE. 3: Setf the symbol-function of INITIAL-QUEUE and call it again. 4: Return to Top Level (an "abort" restart) 5: Abort # [1] CL-USER(137): :pop CL-USER(138): (pathproblem 'a 'z bigmap) COMBINER CL-USER(139): (tree-search #'goalp (initial-queue) #'successors #'combiner) (A B E Z) CL-USER(140): ;;;clutters main lisp space with functions. Better to do with local functions: CL-USER(140): (defun pathproblem (start goal map) (labels ((goalp (s) (eql s goal)) (initial-queue () (list (list start))) (successors (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) map)))) (combiner (old new) (append new old))) (tree-search #'goalp (initial-queue) #'successors #'combiner))) PATHPROBLEM CL-USER(141): (pathproblem 'a 'z bigmap) (A B E Z) CL-USER(142): ;;or since each function so short, go back to lambda's CL-USER(142): (defun pathproblem (start goal map) (tree-search #'(lambda (s) (eql s goal)) (initial-queue () (list (list start))) (successors (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) map)))) (combiner (old new) (append new old))) (tree-search #'goalp (initial-queue) #'successors #'combiner)) PATHPROBLEM CL-USER(143): (defun pathproblem (start goal map) (tree-search #'(lambda (s) (eql s goal)) (list (list start)) #'(lambda (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) map)))) #'(lambda (old new) (append new old)))) PATHPROBLEM CL-USER(144): (pathproblem 'a 'z bigmap) (A B E Z) CL-USER(145): (defun pathproblem (start goal map) (tree-search #'(lambda (s) (eql s goal)) (list (list start)) #'(lambda (path) (mapcar #'(lambda (n) (cons n path)) (cdr (assoc (first path) map)))) #'(lambda (old new) (append old new)))) PATHPROBLEM CL-USER(146): (pathproblem 'a 'z bigmap) (A Z) CL-USER(147): (pathproblem 'a 'e bigmap) (A B E) CL-USER(148): (defun robot-xy (start goal world-size) (tree-search ;;goalp #'(lambda (s) (equal s goal)) ;; initial queue (list (list start)) ;; successors #'(lambda (path) (let* ((s (first path)) (x (first s)) (y (second s)) (succ (list (list x (+ y 1)) (list x (- y 1)) (list (+ 1 x) y) (list (- x 1) y)))) (remove-if #'(lambda (s) (let ((x (first s)) (y (second s))) (or (< x 1) (> x world-size) (< y 1) (> y world-size)))) succ))) ;; combiner #'(lambda (old new) (append old new)))) ROBOT-XY CL-USER(149): (robot-xy '(1 1) '(5 5) 10) Error: Attempt to take the car of 1 which is not listp. [condition type: SIMPLE-ERROR] Restart actions (select using :continue): 0: Return to Top Level (an "abort" restart) 1: Abort # [1] CL-USER(150): :bt Evaluation stack: FIRST <- [... EXCL::%EVAL ] <- LET* <- [... EXCL::%EVAL ] <- (:INTERNAL ROBOT-XY) <- FUNCALL <- LET <- TREE-SEARCH <- LET <- TREE-SEARCH <- ROBOT-XY <- EVAL <- TPL:TOP-LEVEL-READ-EVAL-PRINT-LOOP <- TPL:START-INTERACTIVE-TOP-LEVEL [1] CL-USER(151): :reset CL-USER(152): (trace tree-search) (TREE-SEARCH) CL-USER(153): (robot-xy '(1 1) '(5 5) 10) 0: (TREE-SEARCH # (((1 1))) # #) 1: (TREE-SEARCH # ((1 2) (2 1)) # #) Error: Attempt to take the car of 1 which is not listp. [condition type: SIMPLE-ERROR] Restart actions (select using :continue): 0: Return to Top Level (an "abort" restart) 1: Abort # [1] CL-USER(154): :pop 1: returned-by-throwing :DEBUG-POP 0 2 0: returned-by-throwing :DEBUG-POP 0 2 CL-USER(155): ;; looks like successors is not returning paths, just the new state CL-USER(155): (defun robot-xy (start goal world-size) (tree-search ;;goalp #'(lambda (s) (equal s goal)) ;; initial queue (list (list start)) ;; successors #'(lambda (path) (let* ((s (first path)) (x (first s)) (y (second s)) (succ (list (list x (+ y 1)) (list x (- y 1)) (list (+ 1 x) y) (list (- x 1) y))) (legal-succ (remove-if #'(lambda (s) (let ((x (first s)) (y (second s))) (or (< x 1) (> x world-size) (< y 1) (> y world-size))))))) (mapcar #'(lambda (newone) (cons newone path)) legal-succ))) ;; combiner #'(lambda (old new) (append old new)))) ROBOT-XY CL-USER(156): (robot-xy '(1 1) '(5 5) 10) 0: (TREE-SEARCH # (((1 1))) # #) Error: REMOVE-IF got 1 arg, wanted at least 2 args. [condition type: PROGRAM-ERROR] Restart actions (select using :continue): 0: Return to Top Level (an "abort" restart) 1: Abort # [1] CL-USER(157): :reset 0: returned-by-throwing NIL CL-USER(158): (defun robot-xy (start goal world-size) (tree-search ;;goalp #'(lambda (s) (equal s goal)) ;; initial queue (list (list start)) ;; successors #'(lambda (path) (let* ((s (first path)) (x (first s)) (y (second s)) (succ (list (list x (+ y 1)) (list x (- y 1)) (list (+ 1 x) y) (list (- x 1) y))) (legal-succ (remove-if #'(lambda (s) (let ((x (first s)) (y (second s))) (or (< x 1) (> x world-size) (< y 1) (> y world-size)))) succ))) (mapcar #'(lambda (newone) (cons newone path)) legal-succ))) ;; combiner #'(lambda (old new) (append old new)))) ROBOT-XY CL-USER(159): (robot-xy '(1 1) '(5 5) 10) 0: (TREE-SEARCH # (((1 1))) # #) 1: (TREE-SEARCH # (((1 2) (1 1)) ((2 1) (1 1))) # #) 2: (TREE-SEARCH # (((2 1) (1 1)) ((1 3) (1 2) (1 1)) ((1 1) (1 2) (1 1)) ((2 2) (1 2) (1 1))) # #) 3: (TREE-SEARCH # (((1 3) (1 2) (1 1)) ((1 1) (1 2) (1 1)) ((2 2) (1 2) (1 1)) ((2 2) (2 1) (1 1)) ((3 1) (2 1) (1 1)) ((1 1) (2 1) (1 1))) # #) 4: (TREE-SEARCH # (((1 1) (1 2) (1 1)) ((2 2) (1 2) (1 1)) ((2 2) (2 1) (1 1)) ((3 1) (2 1) (1 1)) ((1 1) (2 1) (1 1)) ((1 4) (1 3) (1 2) (1 1)) ((1 2) (1 3) (1 2) (1 1)) ((2 3) (1 3) (1 2) (1 1))) # #) 5: (TREE-SEARCH # (((2 2) (1 2) (1 1)) ((2 2) (2 1) (1 1)) ((3 1) (2 1) (1 1)) ((1 1) (2 1) (1 1)) ((1 4) (1 3) (1 2) (1 1)) ((1 2) (1 3) (1 2) (1 1)) ((2 3) (1 3) (1 2) (1 1)) ((1 2) (1 1) (1 2) (1 1)) ((2 1) (1 1) (1 2) (1 1))) # #) 6: (TREE-SEARCH # (((2 2) (2 1) (1 1)) ((3 1) (2 1) (1 1)) ((1 1) (2 1) (1 1)) ((1 4) (1 3) (1 2) (1 1)) ((1 2) (1 3) (1 2) (1 1)) ((2 3) (1 3) (1 2) (1 1)) ((1 2) (1 1) (1 2) (1 1)) ((2 1) (1 1) (1 2) (1 1)) ((2 3) (2 2) (1 2) (1 1)) ((2 1) (2 2) (1 2) (1 1)) ((3 2) (2 2) (1 2) (1 1)) ((1 2) (2 2) (1 2) (1 1))) # #) 7: (TREE-SEARCH # (((3 1) (2 1) (1 1)) ((1 1) (2 1) (1 1)) ((1 4) (1 3) (1 2) (1 1)) ((1 2) (1 3) (1 2) (1 1)) ((2 3) (1 3) (1 2) (1 1)) ((1 2) (1 1) (1 2) (1 1)) ((2 1) (1 1) (1 2) (1 1)) ((2 3) (2 2) (1 2) (1 1)) ((2 1) (2 2) (1 2) (1 1)) ((3 2) (2 2) (1 2) (1 1)) ((1 2) (2 2) (1 2) (1 1)) ((2 3) (2 2) (2 1) (1 1)) ((2 1) (2 2) (2 1) (1 1)) ((3 2) (2 2) (2 1) (1 1)) ((1 2) (2 2) (2 1) (1 1))) # #) 8: (TREE-SEARCH # (((1 1) (2 1) (1 1)) ((1 4) (1 3) (1 2) (1 1)) ((1 2) (1 3) (1 2) (1 1)) ((2 3) (1 3) (1 2) (1 1)) ((1 2) (1 1) (1 2) (1 1)) ((2 1) (1 1) (1 2) (1 1)) ((2 3) (2 2) (1 2) (1 1)) ((2 1) (2 2) (1 2) (1 1)) ((3 2) (2 2) (1 2) (1 1)) ((1 2) (2 2) (1 2) (1 1)) ((2 3) (2 2) (2 1) (1 1)) ((2 1) (2 2) (2 1) (1 1)) ((3 2) (2 2) (2 1) (1 1)) ((1 2) (2 2) (2 1) (1 1)) ((3 2) (3 1) (2 1) (1 1)) ((4 1) (3 1) (2 1) (1 1)) ((2 1) (3 1) (2 1) (1 1))) # #) 9: (TREE-SEARCH # (((1 4) (1 3) (1 2) (1 1)) ((1 2) (1 3) (1 2) (1 1)) ((2 3) (1 3) (1 2) (1 1)) ((1 2) (1 1) (1 2) (1 1)) ((2 1) (1 1) (1 2) (1 1)) ((2 3) (2 2) (1 2) (1 1)) ((2 1) (2 2) (1 2) (1 1)) ((3 2) (2 2) (1 2) (1 1)) ((1 2) (2 2) (1 2) (1 1)) ((2 3) (2 2) (2 1) (1 1)) ((2 1) (2 2) (2 1) (1 1)) ((3 2) (2 2) (2 1) (1 1)) ((1 2) (2 2) (2 1) (1 1)) ((3 2) (3 1) (2 1) (1 1)) ((4 1) (3 1) (2 1) (1 1)) ((2 1) (3 1) (2 1) (1 1)) ((1 2) (1 1) (2 1) (1 1)) ((2 1) (1 1) (2 1) (1 1))) # #) 10: (TREE-SEARCH # (((1 2) (1 3) (1 2) (1 1)) ((2 3) (1 3) (1 2) (1 1)) ((1 2) (1 1) (1 2) (1 1)) ((2 1) (1 1) (1 2) (1 1)) ((2 3) (2 2) (1 2) (1 1)) ((2 1) (2 2) (1 2) (1 1)) ((3 2) (2 2) (1 2) (1 1)) ((1 2) (2 2) (1 2) (1 1)) ((2 3) (2 2) (2 1) (1 1)) ((2 1) (2 2) (2 1) (1 1)) ((3 2) (2 2) (2 1) (1 1)) ((1 2) (2 2) (2 1) (1 1)) ((3 2) (3 1) (2 1) (1 1)) ((4 1) (3 1) (2 1) (1 1)) ((2 1) (3 1) (2 1) (1 1)) ((1 2) (1 1) (2 1) (1 1)) ((2 1) (1 1) (2 1) (1 1)) ((1 5) (1 4) (1 3) (1 2) (1 1)) ((1 3) (1 4) (1 3) (1 2) (1 1)) ((2 4) (1 4) (1 3) (1 2) (1 1))) # #) 11: (TREE-SEARCH # (((2 3) (1 3) (1 2) (1 1)) ((1 2) (1 1) (1 2) (1 1)) ((2 1) (1 1) (1 2) (1 1)) ((2 3) (2 2) (1 2) (1 1)) ((2 1) (2 2) (1 2) (1 1)) ((3 2) (2 2) (1 2) (1 1)) ((1 2) (2 2) (1 2) (1 1)) ((2 3) (2 2) (2 1) (1 1)) ((2 1) (2 2) (2 1) (1 1)) ((3 2) (2 2) (2 1) (1 1)) ((1 2) (2 2) (2 1) (1 1)) ((3 2) (3 1) (2 1) (1 1)) ((4 1) (3 1) (2 1) (1 1)) ((2 1) (3 1) (2 1) (1 1)) ((1 2) (1 1) (2 1) (1 1)) ((2 1) (1 1) (2 1) (1 1)) ((1 5) (1 4) (1 3) (1 2) (1 1)) ((1 3) (1 4) (1 3) (1 2) (1 1)) ((2 4) (1 4) (1 3) (1 2) (1 1)) ((1 3) (1 2) (1 3) (1 2) (1 1)) ((1 1) (1 2) (1 3) (1 2) (1 1)) ((2 2) (1 2) (1 3) (1 2) (1 1))) # #) 12: (TREE-SEARCH # (((1 2) (1 1) (1 2) (1 1)) ((2 1) (1 1) (1 2) (1 1)) ((2 3) (2 2) (1 2) (1 1)) ((2 1) (2 2) (1 2) (1 1)) ((3 2) (2 2) (1 2) (1 1)) ((1 2) (2 2) (1 2) (1 1)) ((2 3) (2 2) (2 1) (1 1)) ((2 1) (2 2) (2 1) (1 1)) ((3 2) (2 2) (2 1) (1 1)) ((1 2) (2 2) (2 1) (1 1)) ((3 2) (3 1) (2 1) (1 1)) ((4 1) (3 1) (2 1) (1 1)) ((2 1) (3 1) (2 1) (1 1)) ((1 2) (1 1) (2 1) (1 1)) ((2 1) (1 1) (2 1) (1 1)) ((1 5) (1 4) (1 3) (1 2) (1 1)) ((1 3) (1 4) (1 3) (1 2) (1 1)) ((2 4) (1 4) (1 3) (1 2) (1 1)) ((1 3) (1 2) (1 3) (1 2) (1 1)) ((1 1) (1 2) (1 3) (1 2) (1 1)) ((2 2) (1 2) (1 3) (1 2) (1 1)) ((2 4) (2 3) (1 3) (1 2) (1 1)) ((2 2) (2 3) (1 3) (1 2) (1 1)) ((3 3) (2 3) (1 3) (1 2) (1 1)) ((1 3) (2 3) (1 3) (1 2) (1 1))) # #) 13: (TREE-SEARCH # (((2 1) (1 1) (1 2) (1 1)) ((2 3) (2 2) (1 2) (1 1)) ((2 1) (2 2) (1 2) (1 1)) ((3 2) (2 2) (1 2) (1 1)) ((1 2) (2 2) (1 2) (1 1)) ((2 3) (2 2) (2 1) (1 1)) ((2 1) (2 2) (2 1) (1 1)) ((3 2) (2 2) (2 1) (1 1)) ((1 2) (2 2) (2 1) (1 1)) ((3 2) (3 1) (2 1) (1 1)) ((4 1) (3 1) (2 1) (1 1)) ((2 1) (3 1) (2 1) (1 1)) ((1 2) (1 1) (2 1) (1 1)) ((2 1) (1 1) (2 1) (1 1)) ((1 5) (1 4) (1 3) (1 2) (1 1)) ((1 3) (1 4) (1 3) (1 2) (1 1)) Error: Received signal number 2 (Keyboard interrupt) [condition type: INTERRUPT-SIGNAL] Restart actions (select using :continue): 0: continue computation 1: Return to Top Level (an "abort" restart) 2: Abort # [1c] CL-USER(160): :reset 38: returned-by-throwing NIL 37: returned-by-throwing NIL 36: returned-by-throwing NIL 35: returned-by-throwing NIL 34: returned-by-throwing NIL 33: returned-by-throwing NIL 32: returned-by-throwing NIL 31: returned-by-throwing NIL 30: returned-by-throwing NIL 29: returned-by-throwing NIL 28: returned-by-throwing NIL 27: returned-by-throwing NIL 26: returned-by-throwing NIL 25: returned-by-throwing NIL 24: returned-by-throwing NIL 23: returned-by-throwing NIL 22: returned-by-throwing NIL 21: returned-by-throwing NIL 20: returned-by-throwing NIL 19: returned-by-throwing NIL 18: returned-by-throwing NIL 17: returned-by-throwing NIL 16: returned-by-throwing NIL 15: returned-by-throwing NIL 14: returned-by-throwing NIL 13: returned-by-throwing NIL 12: returned-by-throwing NIL 11: returned-by-throwing NIL 10: returned-by-throwing NIL 9: returned-by-throwing NIL 8: returned-by-throwing NIL 7: returned-by-throwing NIL 6: returned-by-throwing NIL 5: returned-by-throwing NIL 4: returned-by-throwing NIL 3: returned-by-throwing NIL 2: returned-by-throwing NIL 1: returned-by-throwing NIL 0: returned-by-throwing NIL CL-USER(161): (robot-xy '(1 1) '(5 5) 10) 0: (TREE-SEARCH # (((1 1))) # #) 1: (TREE-SEARCH # (((1 2) (1 1)) ((2 1) (1 1))) # #) 2: (TREE-SEARCH # (((2 1) (1 1)) ((1 3) (1 2) (1 1)) ((1 1) (1 2) (1 1)) ((2 2) (1 2) (1 1))) # #) 3: (TREE-SEARCH # (((1 3) (1 2) (1 1)) ((1 1) (1 2) (1 1)) ((2 2) (1 2) (1 1)) ((2 2) (2 1) (1 1)) ((3 1) (2 1) (1 1)) ((1 1) (2 1) (1 1))) # #) 4: (TREE-SEARCH # (((1 1) (1 2) (1 1)) ((2 2) (1 2) (1 1)) ((2 2) (2 1) (1 1)) ((3 1) (2 1) (1 1)) ((1 1) (2 1) (1 1)) ((1 4) (1 3) (1 2) (1 1)) ((1 2) (1 3) (1 2) (1 1)) ((2 3) (1 3) (1 2) (1 1))) # #) 5: (TREE-SEARCH # (((2 2) (1 2) (1 1)) ((2 2) (2 1) (1 1)) ((3 1) (2 1) (1 1)) ((1 1) (2 1) (1 1)) ((1 4) (1 3) (1 2) (1 1)) ((1 2) (1 3) (1 2) (1 1)) ((2 3) (1 3) (1 2) (1 1)) ((1 2) (1 1) (1 2) (1 1)) ((2 1) (1 1) (1 2) (1 1))) # #) 6: (TREE-SEARCH # (((2 2) (2 1) (1 1)) ((3 1) (2 1) (1 1)) ((1 1) (2 1) (1 1)) ((1 4) (1 3) (1 2) (1 1)) ((1 2) (1 3) (1 2) (1 1)) ((2 3) (1 3) (1 2) (1 1)) ((1 2) (1 1) (1 2) (1 1)) ((2 1) (1 1) (1 2) (1 1)) ((2 3) (2 2) (1 2) (1 1)) ((2 1) (2 2) (1 2) (1 1)) ((3 2) (2 2) (1 2) (1 1)) ((1 2) (2 2) (1 2) (1 1))) # #) 7: (TREE-SEARCH # (((3 1) (2 1) (1 1)) ((1 1) (2 1) (1 1)) ((1 4) (1 3) (1 2) (1 1)) ((1 2) (1 3) (1 2) (1 1)) ((2 3) (1 3) (1 2) (1 1)) ((1 2) (1 1) (1 2) (1 1)) ((2 1) (1 1) (1 2) (1 1)) ((2 3) (2 2) (1 2) (1 1)) ((2 1) (2 2) (1 2) (1 1)) ((3 2) (2 2) (1 2) (1 1)) ((1 2) (2 2) (1 2) (1 1)) ((2 3) (2 2) (2 1) (1 1)) ((2 1) (2 2) (2 1) (1 1)) ((3 2) (2 2) (2 1) (1 1)) ((1 2) (2 2) (2 1) (1 1))) # #) 8: (TREE-SEARCH # (((1 1) (2 1) (1 1)) ((1 4) (1 3) (1 2) (1 1)) ((1 2) (1 3) (1 2) (1 1)) ((2 3) (1 3) (1 2) (1 1)) ((1 2) (1 1) (1 2) (1 1)) ((2 1) (1 1) (1 2) (1 1)) ((2 3) (2 2) (1 2) (1 1)) ((2 1) (2 2) (1 2) (1 1)) ((3 2) (2 2) (1 2) (1 1)) ((1 2) (2 2) (1 2) (1 1)) ((2 3) (2 2) (2 1) (1 1)) ((2 1) (2 2) (2 1) (1 1)) ((3 2) (2 2) (2 1) (1 1)) ((1 2) (2 2) (2 1) (1 1)) ((3 2) (3 1) (2 1) (1 1)) ((4 1) (3 1) (2 1) (1 1)) ((2 1) (3 1) (2 1) (1 1))) # #) 9: (TREE-SEARCH # (((1 4) (1 3) (1 2) (1 1)) ((1 2) (1 3) (1 2) (1 1)) ((2 3) (1 3) (1 2) (1 1)) ((1 2) (1 1) (1 2) (1 1)) Error: Received signal number 2 (Keyboard interrupt) [condition type: INTERRUPT-SIGNAL] Restart actions (select using :continue): 0: continue computation 1: Return to Top Level (an "abort" restart) 2: Abort # [1c] CL-USER(162): :reset 19: returned-by-throwing NIL 18: returned-by-throwing NIL 17: returned-by-throwing NIL 16: returned-by-throwing NIL 15: returned-by-throwing NIL 14: returned-by-throwing NIL 13: returned-by-throwing NIL 12: returned-by-throwing NIL 11: returned-by-throwing NIL 10: returned-by-throwing NIL 9: returned-by-throwing NIL 8: returned-by-throwing NIL 7: returned-by-throwing NIL 6: returned-by-throwing NIL 5: returned-by-throwing NIL 4: returned-by-throwing NIL 3: returned-by-throwing NIL 2: returned-by-throwing NIL 1: returned-by-throwing NIL 0: returned-by-throwing NIL CL-USER(163): (untrace tree-search) (TREE-SEARCH) CL-USER(164): (robot-xy '(1 1) '(5 5) 10) Error: Received signal number 2 (Keyboard interrupt) [condition type: INTERRUPT-SIGNAL] Restart actions (select using :continue): 0: continue computation 1: Return to Top Level (an "abort" restart) 2: Abort # [1c] CL-USER(165): :reset CL-USER(166): (robot-xy '(1 1) '(2 2) 10) ((1 1) (1 2) (2 2)) CL-USER(167): (robot-xy '(1 1) '(3 3) 10) ((1 1) (1 2) (1 3) (2 3) (3 3)) CL-USER(168): (robot-xy '(1 1) '(3 4) 10) ((1 1) (1 2) (1 3) (1 4) (2 4) (3 4)) CL-USER(169): (robot-xy '(1 1) '(4 4) 10) ((1 1) (1 2) (1 3) (1 4) (2 4) (3 4) (4 4)) CL-USER(170): (robot-xy '(1 1) '(4 5) 10) ((1 1) (1 2) (1 3) (1 4) (1 5) (2 5) (3 5) (4 5)) CL-USER(171): (robot-xy '(1 1) '(5 5) 10) Error: Received signal number 2 (Keyboard interrupt) [condition type: INTERRUPT-SIGNAL] Restart actions (select using :continue): 0: continue computation 1: Return to Top Level (an "abort" restart) 2: Abort # [1c] CL-USER(172): :reset CL-USER(173): ;;maybe we are doing depth-first. Try breadth-first CL-USER(173): (defun robot-xy (start goal world-size) (tree-search ;;goalp #'(lambda (s) (equal s goal)) ;; initial queue (list (list start)) ;; successors #'(lambda (path) (let* ((s (first path)) (x (first s)) (y (second s)) (succ (list (list x (+ y 1)) (list x (- y 1)) (list (+ 1 x) y) (list (- x 1) y))) (legal-succ (remove-if #'(lambda (s) (let ((x (first s)) (y (second s))) (or (< x 1) (> x world-size) (< y 1) (> y world-size)))) succ))) (mapcar #'(lambda (newone) (cons newone path)) legal-succ))) ;; combiner #'(lambda (old new) (append new old)))) ROBOT-XY CL-USER(174): (robot-xy '(1 1) '(5 5) 10) Error: Stack overflow (signal 1000) [condition type: SYNCHRONOUS-OPERATING-SYSTEM-SIGNAL] Restart actions (select using :continue): 0: continue computation 1: Return to Top Level (an "abort" restart) 2: Abort # [1c] CL-USER(175): :pop Error: Received signal number 2 (Keyboard interrupt) [condition type: INTERRUPT-SIGNAL] Restart actions (select using :continue): 0: continue computation 1: Return to Top Level (an "abort" restart) 2: Abort # [1c] CL-USER(176): :reset CL-USER(177): ;;nope, we were doing breadth first! CL-USER(177): (defun robot-xy (start goal world-size) (tree-search ;;goalp #'(lambda (s) (equal s goal)) ;; initial queue (list (list start)) ;; successors #'(lambda (path) (let* ((s (first path)) (x (first s)) (y (second s)) (succ (list (list x (+ y 1)) (list x (- y 1)) (list (+ 1 x) y) (list (- x 1) y))) (legal-succ (remove-if #'(lambda (s) (let ((x (first s)) (y (second s))) (or (< x 1) (> x world-size) (< y 1) (> y world-size)))) succ))) (mapcar #'(lambda (newone) (cons newone path)) legal-succ))) ;; combiner #'(lambda (old new) (append old new)))) ROBOT-XY CL-USER(178): (robot-xy '(1 1) '(5 5) 6) 11407112 bytes have been tenured, next gc will be global. See the documentation for variable *GLOBAL-GC-BEHAVIOR* for more information. Error: Received signal number 2 (Keyboard interrupt) [condition type: INTERRUPT-SIGNAL] Restart actions (select using :continue): 0: continue computation 1: Return to Top Level (an "abort" restart) 2: Abort # [1c] CL-USER(179): :reset CL-USER(180): (robot-xy '(1 1) '(3 3) 6) ((1 1) (1 2) (1 3) (2 3) (3 3)) CL-USER(181): (robot-xy '(1 1) '(4 4) 6) ((1 1) (1 2) (1 3) (1 4) (2 4) (3 4) (4 4)) CL-USER(182): (robot-xy '(1 1) '(4 4) 5) ((1 1) (1 2) (1 3) (1 4) (2 4) (3 4) (4 4)) CL-USER(183): ; try more movement, along diagonals CL-USER(183): (defun robot-xy (start goal world-size) (tree-search ;;goalp #'(lambda (s) (equal s goal)) ;; initial queue (list (list start)) ;; successors #'(lambda (path) (let* ((s (first path)) (x (first s)) (y (second s)) (succ (list (list x (+ y 1)) (list x (- y 1)) (list (+ 1 x) y) (list (- x 1) y) (list (- x 1) (- y 1)) (list (- x 1) (+ y 1)) (list (+ x 1) (- y 1)) (list (+ x 1) (+ y 1)))) (legal-succ (remove-if #'(lambda (s) (let ((x (first s)) (y (second s))) (or (< x 1) (> x world-size) (< y 1) (> y world-size)))) succ))) (mapcar #'(lambda (newone) (cons newone path)) legal-succ))) ;; combiner #'(lambda (old new) (append old new)))) ROBOT-XY CL-USER(184): (robot-xy '(1 1) '(4 4) 5) ((1 1) (2 2) (3 3) (4 4)) CL-USER(185): (robot-xy '(1 1) '(5 5) 5) ((1 1) (2 2) (3 3) (4 4) (5 5)) CL-USER(186): (robot-xy '(1 1) '(5 5) 6) ((1 1) (2 2) (3 3) (4 4) (5 5)) CL-USER(187): (dribble)