以下来自http://htdp.org/2003-09-26/Book/curriculum-Z-H-38.html#node_chap_30的代码似乎无法正常工作(我已经添加了println语句进行调试)
(define (neighbor a-node sg)
(println "in neighbor fn")
(cond
[(empty? sg) (error "neighbor: impossible")]
[else (cond
[(symbol=? (first (first sg)) a-node)
(second (first sg))]
[else (neighbor a-node (rest sg))])]))
(define (route-exists? orig dest sg)
(println "in route-exits? fn")
(cond
[(symbol=? orig dest) true]
[else (route-exists? (neighbor orig sg) dest sg)]))
我也尝试了第二个版本(我添加了包含fn):
(define (contains item sl)
(ormap (lambda (x) (equal? item x)) sl) )
(define (route-exists2? orig dest sg)
(local ((define (re-accu? orig dest sg accu-seen)
(cond
[(symbol=? orig dest) true]
[(contains orig accu-seen) false]
[else (re-accu? (neighbor orig sg) dest sg (cons orig accu-seen))])))
(re-accu? orig dest sg empty)))
来自该页面的示例本身会创建无限循环:
(route-exists? 'C 'D '((A B) (B C) (C E) (D E) (E B) (F F)))
以下产生#f,即使解决方案显然是可能的:
(route-exists2? 'C 'D '((A B) (B C) (C E) (D E) (E B) (F F)))
以下测试(列表是我的)在这里产生错误,即使解决方案显然是可能的:
(route-exists?
'A 'C
'('('A 'B) '('B 'C) '('A 'C) '('A 'D) '('B 'E) '('E 'F) '('B 'F) '('F 'G) )
)
(route-exists2?
'A 'C
'('('A 'B) '('B 'C) '('A 'C) '('A 'D) '('B 'E) '('E 'F) '('B 'F) '('F 'G) )
)
问题出在哪里?如何解决?
编辑:
即使在选择新功能并删除多余的引号后,以下操作也不起作用(即使A和D之间有直接路径):
(route-exists2?
'A 'D
'((A B) (B C) (A C) (A D) (B E) (E F) (B F) (F G) ) )
输出错误:
neighbor: impossible
答案 0 :(得分:2)
对于第一种情况:
来自该页面的示例本身会创建无限循环:
(route-exists? 'C 'D '((A B) (B C) (C E) (D E) (E B) (F F)))
在您链接的页面中,定义了函数后的十行,显然是说:
手工评估证实,当函数重复出现时,它会一次又一次地使用完全相同的参数调用自身。换句话说,评估永远不会停止。
所以,这正是你观察到的行为。
对于第二种情况:
以下产生#f,即使解决方案显然是可能的:
(route-exists2? 'C 'D '((A B) (B C) (C E) (D E) (E B) (F F)))
第一个函数定义后的四行,显然是说:
再看一下图85.在这个简单的图表中,没有从C到D的路线。
因此,函数必须正确地返回#f
,因为没有从C到D的路径(请记住,弧实际上是在示例之前) ,明确地说:“......每个节点只有一个(单向)连接到另一个节点”)。
最后,在最后两个例子中:
以下测试(列表是我的)在这里产生错误,即使解决方案显然是可能的:
(route-exists? 'A 'C '('('A 'B) '('B 'C) '('A 'C) '('A 'D) '('B 'E) '('E 'F) '('B 'F) '('F 'G) ) )
(route-exists2? 'A 'C '('('A 'B) '('B 'C) '('A 'C) '('A 'D) '('B 'E) '('E 'F) '('B 'F) '('F 'G) ) )
您引用的内容过多,因此您要为该函数提供与所需数据不同的数据。
请记住,'X
是(quote X)
的缩写。这意味着您的上一个参数不是正确的图形,因为它等于:
((quote (quote A) (quote B)) (quote (quote B) (quote C)) ...)
而不是
((A B) (B C) ...)
<强>加强>
这是最后一个问题的答案:
即使在选择新功能并删除多余的引号后,以下操作也不起作用(即使A和D之间有直接路径):
(route-exists2? 'A 'D '((A B) (B C) (A C) (A D) (B E) (E F) (B F) (F G) ) )
输出错误:
neighbor: impossible
在您关联的页面中,在“A Problem with Generative Recursion"部分的第一段中,明确指出:
在这里,我们研究简单图形问题的稍微简单的版本,其中每个节点与另一个节点只有一个(单向)连接。
由于您的图表与节点有多个连接(例如A连接到B,C和D等),在这种情况下,程序 不起作用。
如果您考虑函数neighbor
,您可以立即看到原因:它找到连接到某个节点的第一个节点,而不考虑所有其他节点。因此,例如,从A
开始,唯一返回的neighbor
为B
,它不会直接或间接连接到D
,因此函数route-exists2?
会回复(正确地,根据规范),没有这样的路线。