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