我正在尝试在Scheme中实现反向跟踪搜索。到目前为止,我有以下内容:
(define (backtrack n graph assignment)
(cond (assignment-complete n assignment) (assignment) )
(define u (select-u graph assignment))
(define c 1)
(define result 0)
(let forLoop ()
(when (valid-choice graph assignment c)
(hash-set! assignment u c)
(set! result (backtrack n graph assignment))
(cond ((not (eq? result #f)) result))
(hash-remove! assignment u)
)
(set! c (+ c 1))
(when (>= n c) (forLoop))
)
#f ; I believe this is where I'm having problems
)
我的函数assignment-complete和select-u通过单元测试。参数赋值是一个带有(make-hash)的哈希表make,所以应该没问题。
我认为我遇到的问题与在循环结束时返回false有关,如果没有递归返回非假值(应该是有效赋值)。是否有一个Scheme等效的显式返回语句?
答案 0 :(得分:0)
您的问题的答案是是:
(define (foo ...)
(call-with-current-continuation
(lambda (return)
...... ; here anywhere inside any sub-expression
...... ; you can call (return 42)
...... ; to return 42 from `foo` right away
)))
这会设置退出 continuation,以便您可以从函数体内返回结果值。通常的Scheme方法是将返回表单作为最后一个表单,因此返回其值:
(let forLoop ()
(when (valid-choice graph assignment c)
(hash-set! assignment u c)
(set! result (backtrack n graph assignment))
(cond
((not (eq? result #f))
result)) ; the value of `cond` form is ignored
(hash-remove! assignment u))
; the value of `when` form is ignored
(set! c (+ c 1))
(if (>= n c) ; `if` must be the last form
(forLoop) ; so that `forLoop` is tail-recursive
;; else:
return-value) ; <<------ the last form's value
) ; is returned from `let` form
;; (let forLoop ...) must be the last form in your function
;; so its value is returned from the function
)
你这里也有问题:
(cond (assignment-complete n assignment) (assignment) )
此代码不拨打电话(assignment-complete n assignment)
。相反,它检查变量assignment-complete
是否具有非空值,如果不是,则检查assignment
变量,但无论如何它的返回值都会被忽略。也许在那里缺少一些括号,和/或else
条款。