drscheme - 有限状态机

Voj*_*ech 1 scheme fsm racket

感谢在这个伟大的网站上的人们,我设法将几乎完整和有效的代码放在一起.我有一个最后的问题.

这是代码:

     (define (chartest ch)
       (lambda (x) (char=? x ch)))

     (define fsm-trans
        '((A (lambda (x) (string=? x "a") B), (B (lambda (x) (string=? x "a") C)))))

     (define (find-next-state state ch trl)
       (cond
         [(empty? trl) false] 
         [(and (symbol=? state (first (first trl)))
              ((second (first trl)) ch))
          (third (first trl))]
         [else (find-next-state state ch (rest trl))]))


     (define fsm-final '(C))

     (define start-state 'A)

     (define (run-fsm start trl final input)
       (cond
         [(empty? input)
          (cond
            [(member start final) true]
            [else false])]
         [else 
          (local ((define next (find-next-state start (first input) trl)))
            (cond
              [(boolean? next) false]
              [else (run-fsm next trl final (rest input))]))]))


     (run-fsm start-state fsm-trans fsm-final (string->list "ac"))
Run Code Online (Sandbox Code Playgroud)

我有转换函数find-next-state的问题.我如何定义它来测试传入的字符,并在此基础上,当fsm到达最终状态时返回true值,否则返回false值?

谢谢您的回答.

更新:

感谢您的回答,我很抱歉代码令人困惑.我修复了转换的定义,现在看起来像这样:

    (define fsm-trans
       '((A (lambda (x) (string=? x "a") B)
         (B (lambda (x) (string=? x "a") C)))))
Run Code Online (Sandbox Code Playgroud)

但现在我正在尝试定义过渡功能.当我没有固定的过渡角色而且我使用了char-alphabetic?和char-numeric?,这些代码行就像一个魅力:

    (define (find-next-state state ch trl)
      (cond
        [(empty? trl) false] 
        [(and (symbol=? state (first (first trl)))
             ((second (first trl)) ch))
         (third (first trl))]
        [else (find-next-state state ch (rest trl))]))
Run Code Online (Sandbox Code Playgroud)

但是我应该改变什么才能使用fsm-trans中的状态新定义?当在DrScheme中输入此代码时,它会显示一行错误:((second(first trl))ch)).

感谢您的进一步帮助!

Eli*_*lay 5

看起来这段代码中的主要问题是对引号,quasiquotes和unquotes的混淆.具体来说,'(foo (lambda (x) x) baz)引用整个事物,所以那里没有任何功能,只是一个符号表示.此外,您使用,看起来像是混淆它作为分隔列表中的值的东西.另一个问题是parens看起来不匹配.你可能想要这样的东西,使用quasiquote:

(define fsm-trans
  `((A ,(lambda (x) (string=? x "a") B))
    (B ,(lambda (x) (string=? x "a") C))))
Run Code Online (Sandbox Code Playgroud)

考虑到你不清楚这些东西,那么它会更好地坚持只有简单的报价,并用list在需要的时候:

(define fsm-trans
  (list (list 'A (lambda (x) (string=? x "a") B))
        (list 'B (lambda (x) (string=? x "a") C))))
Run Code Online (Sandbox Code Playgroud)

你可能还有一些问题需要克服,但这样做可以让你朝着正确的方向前进.