GNU Common Lisp程序输入流错误求助:对象内输入流终止
问题修复方案
错误原因
这个READ错误是因为代码中存在未闭合的括号,Lisp读取器解析到文件末尾时,仍有未匹配的开括号(来自defmacro里的progn),导致无法完成S表达式解析。
具体修复步骤
1. 闭合未完成的括号
原defmacro mac中的progn语句没有闭合,需要在dfs函数定义结束后添加一个闭合括号,完成progn和defmacro的定义:原代码中(defun dfs ...))))之后直接接了(let ...),补一个)即可让progn的所有内容被正确包裹。
2. 修正状态合法性检查的错误
原valid-state-p函数存在三个问题:
- 传教士数量判断错误:
(< m 3)会排除初始状态的3个传教士,改为(<= m 3) - 船的状态符号不统一:代码里用
I但调用时传的是l,统一改为'(l r) - 遗漏核心规则:传教士与食人魔问题中,当某一岸传教士数量大于0时,不能少于食人魔数量,否则状态非法
修正后的valid-state-p:
(defun valid-state-p (state) (let ((m (car state)) (c (cadr state)) (b (caddr state)) (m-left (- 3 m)) (c-left (- 3 c))) (and (>= m 0) (<= m 3) (>= c 0) (<= c 3) (member b '(l r)) (or (= m 0) (>= m c)) (or (= m-left 0) (>= m-left c-left)))))
3. 补充右岸的合法移动逻辑
原legal-moves函数中,船在右岸(r)时没有任何移动逻辑,导致无法返回左岸,补充对应移动选项:
(when (equal b 'r) (when (and (<= m 1) (<= c 3)) (push (move state 2 0) moves)) (when (and (<= m 2) (<= c 3)) (push (move state 1 0) moves)) (when (and (<= m 3) (<= c 1)) (push (move state 0 2) moves)) (when (and (<= m 3) (<= c 2)) (push (move state 0 1) moves)) (when (and (<= m 2) (<= c 2)) (push (move state 1 1) moves)))
4. 修正DFS函数的条件分支问题
原代码中dfs函数的if分支数量错误,改为unless更简洁正确,避免逻辑执行异常。
修复后的完整代码
(defmacro mac (start end) `(progn (defparameter *start* ',start) (defparameter *end* ',end) (defparameter *visited* '()) (defun valid-state-p (state) (let ((m (car state)) (c (cadr state)) (b (caddr state)) (m-left (- 3 m)) (c-left (- 3 c))) (and (>= m 0) (<= m 3) (>= c 0) (<= c 3) (member b '(l r)) (or (= m 0) (>= m c)) (or (= m-left 0) (>= m-left c-left))))) (defun goal-state-p (state) (equal state *end*)) (defun move (state dm dc) (if (equal (caddr state) 'l) (list (- (car state) dm) (- (cadr state) dc) 'r) (list (+ (car state) dm) (+ (cadr state) dc) 'l))) (defun legal-moves (state) (let* ((m (car state)) (c (cadr state)) (b (caddr state)) (moves '())) (when (equal b 'l) (when (and (>= m 2) (>= c 0)) (push (move state 2 0) moves)) (when (and (>= m 1) (>= c 0)) (push (move state 1 0) moves)) (when (and (>= m 0) (>= c 2)) (push (move state 0 2) moves)) (when (and (>= m 0) (>= c 1)) (push (move state 0 1) moves)) (when (and (>= m 1) (>= c 1)) (push (move state 1 1) moves))) (when (equal b 'r) (when (and (<= m 1) (<= c 3)) (push (move state 2 0) moves)) (when (and (<= m 2) (<= c 3)) (push (move state 1 0) moves)) (when (and (<= m 3) (<= c 1)) (push (move state 0 2) moves)) (when (and (<= m 3) (<= c 2)) (push (move state 0 1) moves)) (when (and (<= m 2) (<= c 2)) (push (move state 1 1) moves))) (remove-if-not #'valid-state-p moves))) (defun dfs (state path) (if (goal-state-p state) (reverse path) (unless (member state *visited*) (setf *visited* (cons state *visited*)) (dolist (next-state (legal-moves state)) (let ((result (dfs next-state (cons next-state path)))) (when result (return result))))))))) (let ((solution (dfs *start* '()))) (if solution (dolist (step solution) (format t "~a ~a ~a~%" (car step) (cadr step) (caddr step))) (format t "nil"))) (mac '(3 3 l) '(0 0 r))
内容的提问来源于stack exchange,提问作者Droopity Droop
相关产品推荐
相关产品推荐

