2012-03-31 150 views
0

我试图测试一些代码从教科书“教非确定性和通用自动机使用计划”。这是Scheme,我将DrRacket配置为R5RS。计划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

程序的最后几行指定eval的环境为null-environment,它排除了您之前定义的所有内容。如果您只关闭该部分,eval将使用您当前的顶级环境,这正是您想要的。

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

+0

将此部分关闭:procedure meval:期望2个参数,给出1. 逗号部分虽然很奇怪..但我认为这是错误的,但教科书用“注意逗号! – ercliou 2012-03-31 20:31:40

+0

逗号(“非引号运算符”)应该与quasiquote(反引号)运算符一起使用。 r5rs中的 – erjiang 2012-03-31 23:02:32

+0

:(eval'something(interaction-environment))将评估'具有顶级环境的东西 – FooBee 2012-04-01 03:45:36