Scheme R5RS - 未定义的标识符

时间:2012-03-31 20:11:06

标签: scheme undefined r5rs

我正在尝试从教科书“使用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 $)))

这是教科书的例子。 它是否忽略了定义代码?

1 个答案:

答案 0 :(得分:1)

程序的最后几行指定evalnull-environment的环境,这将排除您之前定义的所有内容。如果您暂停该部分,eval将使用您当前的顶级环境,这就是您想要的。

此外,您在(list ,start t)处出现语法错误。我想你可能意味着(list start #t)修改或者,如果`(letrec位于automaton而不是'(letrec,则逗号可能更有意义。