【问题标题】:Finite State Machine in SchemeScheme中的有限状态机
【发布时间】:2011-05-25 19:27:54
【问题描述】:

我正在尝试在 Scheme 中完成一个有限状态机。问题是,我不确定如何告诉它应该测试哪些字符。如果我想测试一个字符串 "abc112" 那我该怎么做呢?

代码如下:

#lang racket    
(define (chartest ch)
  (lambda (x) (char=? x ch)))
;; A transition is (list state char!boolean state)
(define fsmtrlst 
  (list
   (list 'start char-alphabetic? 'name)
   (list 'start char-numeric? 'number)
   (list 'start (chartest #\() 'lparen)
   (list 'start (chartest #\)) 'rparen)
   (list 'name char-alphabetic? 'name)
   (list 'name char-numeric? 'name)
   (list 'number char-numeric? 'number)))

(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 fsmfinal '(name number lparen rparen))

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

这是我要测试的启动代码:

(fsmtrlst (list 'start (lambda (abc112) (char=? abc112 ))))

编辑:

好的,.. 整体产品还可以,但我的导师对此并不满意,.. 他希望我制作一个具有转换功能的有限状态机 -> 类似于全局定义,它会说:当处于状态时X 来字符 Y 去 Z ...然后我将测试一个字符列表,看看它是假还是真...所以唯一的区别是代码不应该只使用数字和字母,而是任何角色...有可能吗?谢谢你的回答

编辑 2:现在我有了基本信息:

也就是机器的样子

A ---------> B ----------> C ----------> D ----------> (五) 字母数字数字字母

(define fsmtrlst
 (list
   (list 'A char-alphabetic? 'B)
   (list 'B char-numeric? 'C)
   (list 'C char-numeric? 'D)
   (list 'D char-alphabetic 'E)))

(define fsmfinal '(E))

(define fsmstart 'A)

但我不确定如何编写 fsmstart 的定义。

感谢您的回答。

这接受正好四个字符的序列,即字母、数字、数字、字母,仅此而已。

编辑 3:我正在使用在线教程和我的导师老师提供的一本书。我想出了我想做的fsm。感谢您的帮助。

只是出于好奇:

拥有相当具体的 fsm 会有什么不同?

例子:

开始 ----"b"-----> 状态 A -----"a" ----> 状态 B -----"c"-----> 最终状态

只有当字符列表是“bac”而不是其他时,fsm 才会为真。 有可能吗?

感谢您的反馈。

编辑 4:

好的,我设法写了,但我又不知道如何输入字符。这是代码:

有 3 种状态,但只有从状态 A 到状态 C 时才会成立。

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

    (define fsm-trans
       '((A, "a", B), (A, "b", A), (B, "c", C)))

    (define (find-next-state state ch trl)
      (cond
        [(empty? trl) false] 
        [(and (symbol=? state (first (first trl)))
              ((second (first trl)) ch)) <- And also this line returns an error
         (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 (list '("a", "c")))  <- I know this is the last problem with the code, the definition of the input. How can I tell Scheme what characters I want to test?

谢谢你的回答!!!

【问题讨论】:

  • 请缩进您的代码以使其可读。还有,有限状态机应该做什么?
  • @Heatsink:我将代码导入 dr-scheme 并使用 Tab 键发疯了
  • 在 Emacs 中,你可以只做 C-A-\。只是说。
  • 我已经更新了我的答案,但我担心你会被一些小问题困扰,而这些小问题可以通过尝试更简单的练习来更好地解决。您是否正在使用计划教程或书籍来配合您的辅导?

标签: scheme racket


【解决方案1】:

我很好奇:我认为你没有写这个fsm?这是家庭作业还是您想自学? FSM 的代码看起来很好(实际上很好)。但是,您的启动线:

(fsmtrlst (list 'start (lambda (abc112) (char=? abc112 ))))

没有意义。原因如下:fsmtrlst 是有限状态机转换列表。它是在第一个大代码块中定义的。它不是要调用的函数。我相信你要调用的函数是run-fsm。这需要一个开始符号、一个转换列表、一个最终状态列表和一个输入。输入实际上不是一个字符串,而是一个列表。因此,您可以使用以下行启动它:

(run-fsm 'start fsmtrlst fsmfinal (string->list "abc112"))

这将调用run-fsm,并使用定义的转换列表fsmtrlst、定义的最终状态列表和字符串“abc112”的输入就绪形式。

顺便说一句,除了'start 之外的所有内容都被定义为最终(接受)状态。但是,并非所有输入都接受输入。例如,将“abc122”替换为“abc(122”) 被接受。

这是你想要的吗?

更新:

您的编辑澄清了一些事情。您对fsmstart 的定义很好。您在fsmtrlst 中的一个char-alphabetic? 用法中确实漏掉了一个问号(?)。您是否对不知道如何使用新定义感到困惑?首先,您应该删除 fsmtrlstfsmfinal 的旧定义。否则,您可能会收到重复定义错误。根据您的新定义,您要执行的行应如下所示:

(run-fsm fsmstart fsmtrlst fsmfinal (string->list "w00t"))

这将返回#t,因为“w00t”是一个字符,后跟两个数字,后跟一个字符。

我推测您仍然对方案的语法规则有困难,而不仅仅是您的特定程序的逻辑问题。您可能想尝试一个更简单的练习。

更新 2:您不应该考虑提出一个新问题吗?

您最近的更新破坏了代码。 fsm 的转换部分起作用了,因为转换被定义为一个列表:

(from-state test-function to-state)

您已尝试创建过渡:

(from-state string-literal to-state)

您可以将(A, "a", B) 更改为(A (lambda (x) (string=? x "a") B)

当您尝试调用您的函数时,您获取了一个需要一个字符列表的函数,并给它一个字符串列表列表。这些不是一回事。另外,您是否注意到您在列表中放置了逗号,但它们在代码中的其他任何地方都不存在?这些错误是我建议你开始一个方案教程的原因。这些是基本的计划问题,与您的特定练习无关。我建议您将您的编辑回退到昨天的内容。

很遗憾,我无法再更新此答案。我想更新我的答案,这样如果有人带着类似的担忧提出你的问题,他们会看到一个完整的答案。但是,您提供了一个移动目标。请考虑暂停您的编辑并在有新问题时提交一个新问题。

【讨论】:

  • 我已经(多次)编辑了我的问题。在完成 fsm 之前,我面临着最后一个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多