我正在尝试从教科书“使用Scheme教授不确定性和通用自动机”中测试一些代码。这是Scheme,我已将DrRacket配置为R5RS。
我复制了代码的定义部分,但它仍在抱怨
对未定义标识符的引用:只读磁带
以下是相关代码。
(define tape
(lambda()
(let((blank '$))
(let ((left-part(list blank))
(right-part(list blank)))
(lambda message
(case(car message)
((init!)
(set! left-part(reverse(caadr message)))
(set! right-part(cadadr message)))
((write!)
(if(equal? right-part(list blank))
(set! right-part (cons(cadr message) right-part))
(set! right-part (cons(cadr message)(cdr right-part)))))
((left!)
(set! right-part (cons (car left-part) right-part))
(if(not(equal? left-part (list blank)))
(set! left-part(cdr left-part))))
((right!)
(set! left-part (cons (car right-part) left-part))
(if (not (equal? right-part (list blank)))
(set! right-part (cdr right-part))))
((show)
(list (reverse left-part) right-part))
((read)
(car right-part))
(else (error 'rape "Message ~a cannot be evaluated" (car message)))))))))
(define read-only-tape
(lambda()
(let ((tape-obj (tape)))
(lambda message
(case(car message)
((reconfig!)(tape-obj 'right))
((left! right! write!)
(error 'message "~a is prohibited for read-only-tapes" (car message)))
(else(apply tape-obj message)))))))
它在这里使用只读磁带:
(define automaton
(lambda(start)
(eval
'(letrec
((q0(lambda(tape)
(printf "~a~n~a~n" (contents tape) 'q0)
(case (at tape)
((a)(reconfig! tape)(q2 tape))
((b)(reconfig! tape)(q1 tape))
(else #f))))
(q1(lambda(tape)
(printf "~a~n~a~n" (contents tape) 'q1)
(case (at tape)
((a)(reconfig! tape)(q5 tape))
((b)(reconfig! tape)(q5 tape))
(($) #t)
(else #f))))
(q2(lambda(tape)
(printf "~a~n~a~n" (contents tape) 'q2)
(case (at tape)
((a)(reconfig! tape)(q3 tape))
((b)(reconfig! tape)(q6 tape))
(else #f))))
(q3(lambda(tape)
(printf "~a~n~a~n" (contents tape) 'q3)
(case (at tape)
((a)(reconfig! tape)(q3 tape))
((b)(reconfig! tape)(q4 tape))
(else #f))))
(q4(lambda(tape)
(printf "~a~n~a~n" (contents tape) 'q4)
(case (at tape)
((a)(reconfig! tape)(q5 tape))
((b)(reconfig! tape)(q5 tape))
(($) #t)
(else #f))))
(q5(lambda(tape)
(printf "~a~n~a~n" (contents tape) 'q5)
(case (at tape)
((a)(reconfig! tape)(q5 tape))
((b)(reconfig! tape)(q5 tape))
(else #f))))
(q6(lambda(tape)
(printf "~a~n~a~n" (contents tape) 'q6)
(case (at tape)
((a)(reconfig! tape)(q5 tape))
((b)(reconfig! tape)(q6 tape))
(($) #t)
(else #f)))))
(let((t (read-only-tape)))
(lambda(input)
(init! t input)
(eval (list ,start t)
(null-environment 5)))))
(null-environment 5))))
我用
运行它(run automaton 'q0 '(($)(a a b $)))
这是教科书的例子。 它是否忽略了定义代码?
答案 0 :(得分:1)
程序的最后几行指定eval
为null-environment
的环境,这将排除您之前定义的所有内容。如果您暂停该部分,eval
将使用您当前的顶级环境,这就是您想要的。
此外,您在(list ,start t)
处出现语法错误。我想你可能意味着(list start #t)
。
修改或者,如果`(letrec
位于automaton
而不是'(letrec
,则逗号可能更有意义。