0
votes

I'm trying to test some code from a textbook "Teaching Nondeterministic and Universal Automata using Scheme". It's Scheme, I've configured DrRacket as R5RS.

I copied the define part of the code, but it's still complaining

reference to undefined identifier: read-only-tape

Here's the relevant code.

(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)))))))

And it's using the read-only-tape here:

(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))))

I run it with

(run automaton 'q0 '(($)(a a b $)))

it's the text book's example. Is it ignoring the define code?

1

1 Answers

1
votes

The last few lines of your program specify the environment for eval to be null-environment, which excludes everything you defined earlier. If you just leave that part off, eval will use your current top-level environment, which is what you want.

Also, you have a syntax error at (list ,start t). I think you might have meant (list start #t). Edit: Or, the comma might make more sense if you had `(letrec at the top of automaton rather than '(letrec.