方案中的有限状态机

问题描述

| 我正在尝试在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 ---------->(E)  字母编号字母
(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才为true,而没有别的。 可能吗? 感谢您的反馈意见。 编辑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?
谢谢您的回答!!!     

解决方法

我很好奇:我认为你没有写这个fsm吗?这是用于家庭作业还是您要自学? FSM的代码看起来不错(实际上很好)。但是,您的启动行:
(fsmtrlst (list \'start (lambda (abc112) (char=? abc112 ))))
没有意义。这是为什么:
fsmtrlst
是有限状态机转换列表。它是在第一个大代码块中定义的。它不是要调用的函数。我相信您要调用的函数是
run-fsm
。这需要一个开始符号,一个过渡列表,一个最终状态列表和一个输入。输入实际上不是字符串,而是列表。因此,您可以使用以下行启动它:
(run-fsm \'start fsmtrlst fsmfinal (string->list \"abc112\"))
这将调用带有定义的转换列表
fsmtrlst
,定义的最终状态列表以及字符串\“ abc112 \”的输入就绪形式的
run-fsm
。 顺便提及,除“ 10”以外的所有东西都被定义为最终(接受)状态。但是,并非所有输入都接受输入。例如,不接受将\“ abc122 \”替换为\“ abc(122 \”)。 这是你想要的吗? 更新: 您的修改已使事情变得清晰。您对
fsmstart
的定义很好。您确实在
fsmtrlst
中的
char-alphabetic?
用法中错过了一个问号(?)。您是否因为不知道如何使用新定义而感到困惑?首先,您应删除ѭ5和ѭ15的旧定义。否则,您可能会收到重复的定义错误。根据您的新定义,您要执行的行应如下所示:
(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)
。 当您尝试调用函数时,您采用了一个期望一个字符列表并给它一个字符串列表的函数。这些不是一回事。另外,您是否注意到您在列表中放入了逗号,但是代码中没有逗号?这些错误是为什么我建议您开始一个方案教程的原因。这些是基本的计划问题,与您的特定锻炼无关。我建议您将编辑内容恢复到昨天的内容。 不幸的是,我无法再更新此答案。我想更新我的答案,以便如果有人对您的问题有类似的关注,他们会看到完整的答案。但是,您提供了一个移动目标。请考虑停止编辑,并在提交新问题时提交新问题。