【问题标题】:Scheme R5RS - Undefined identifier方案 R5RS - 未定义的标识符
【发布时间】:2012-03-31 20:11:05
【问题描述】:

我正在尝试测试教科书“使用方案教授非确定性和通用自动机”中的一些代码。这是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 $)))

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

【问题讨论】:

    标签: scheme undefined r5rs


    【解决方案1】:

    程序的最后几行将eval 的环境指定为null-environment,这不包括您之前定义的所有内容。如果您不考虑该部分,eval 将使用您当前的顶级环境,这就是您想要的。

    另外,(list ,start t) 存在语法错误。我想你的意思可能是(list start #t)编辑: 或者,如果您在 automaton 的顶部使用 `(letrec 而不是 '(letrec,则逗号可能更有意义。

    【讨论】:

    • 离开那部分:过程 meval:需要 2 个参数,给定 1。虽然逗号部分很奇怪.. 我认为这是错误的,但教科书 cmets 用“注意逗号!”跨度>
    • 逗号(“取消引用运算符”)应与准引号(反引号)运算符一起使用。
    • in r5rs:(eval 'something (interaction-environment)) 将评估'something with top-level environment
    猜你喜欢
    • 2012-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-23
    • 1970-01-01
    相关资源
    最近更新 更多