方案中的有限状态机
我正在尝试在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 有什么不同?
示例:
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?
谢谢你的回答!
I am trying to finish a finite state machine in Scheme. The problem is, that I am not sure how to tell it what characters it should test. If I want to test a String "abc112" then how do I do that?
Here is the code:
#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))]))]))
And here is the launch code which I am trying to test:
(fsmtrlst (list 'start (lambda (abc112) (char=? abc112 ))))
EDIT:
ok,.. the overall product is okey, but my tutor is not happy with it,.. he wants me to make a finite state machine with transition function -> something like a global definition which would say: when in state X comes character Y go to Z ... and then i will test a list of characters to see if it is false or true ... So the only difference is that the code shouldn't be specific to use only numbers and letters but any character... is it somehow possible? thank you for your answer
EDIT 2: now I have the basic info how it should look like:
That is, the machine looks like
A ---------> B ----------> C ----------> D ----------> (E)
letter number number letter
(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)
but i am not sure how to write the definition of fsmstart.
Thank you for answers.
This accepts sequences of exactly four characters which are letter, number, number, letter, and nothing else.
EDIT 3: I am using tutorials online and a book that my mentor teacher provided. I figured out the fsm I wanted to make. Thank you for your help.
Just out of curiosity:
How would differ to have rather specific fsm?
Example:
START ----"b"-----> STATE A -----"a" ----> STATE B -----"c"-----> FINAL STATE
That the fsm would be true only when the list of characters is "bac" and nothing else.
Is it possible?
Thank you for your feedback.
EDIT 4:
Ok, I managed to do write but once again, I am not sure how to make the input of characters. This is the code:
There are 3 states but it will be true only when going from state A to state 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?
Thank you for your answer!!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我很好奇:我想你没有写这个fsm?这是家庭作业还是你想自学? FSM 的代码看起来不错(事实上,相当不错)。然而,你的发射台词是:
毫无意义。原因如下:
fsmtrlst
是有限状态机转换列表。它是在第一个大代码块中定义的。它不是要调用的函数。我相信您要调用的函数是run-fsm
。它需要一个开始符号、一个转换列表、一个最终状态列表和一个输入。输入实际上不是一个字符串,而是一个列表。因此,您可以使用以下行启动它:这将使用定义的转换列表
fsmtrlst
、定义的最终状态列表和输入来调用run-fsm
- 字符串“abc112”的就绪形式。顺便说一句,除了
'start
之外的所有内容都被定义为最终(接受)状态。但并非所有输入都接受输入。例如,不接受将“abc122”替换为“abc(122”)。这是您想要的吗?
更新:
您的编辑已经澄清了一些事情。您对
fsmstart
的定义是好吧,您确实在fsmtrlst
中的char-alphabetic?
用法中漏掉了一个问号 (?)。新定义?首先,您应该删除fsmtrlst
和fsmfinal
的旧定义,否则,您的新定义可能会出现重复定义错误。应该看起来像:这将返回#t,因为“w00t”是一个字符,后面跟着两个数字,后面跟着一个字符,
我推测您仍然对方案的语法规则有困难,而不仅仅是对逻辑的问题。你可能想尝试一个更简单的练习:
你不应该考虑制定一个新问题吗?
你最近的更新已经破坏了代码,因为转换被定义为一个列表:
您尝试创建转换:
您可以将
(A, "a", B)
更改为(A (lambda (x) (string=? x“a”)B)
。当您尝试调用函数时,您采用了一个需要字符列表的函数,并为其提供了一个字符串列表列表。这些不是同一件事。另外,您是否注意到您在列表中添加了逗号,但它们在代码中的其他位置不存在?这些错误就是我建议您开始计划教程的原因。这些是基本的方案问题,与您的特定练习无关。我建议您将编辑的内容退回到昨天的内容。
不幸的是,我无法再更新这个答案。我想更新我的答案,以便如果有人带着类似的担忧提出您的问题,他们会看到完整的答案。然而,你提供了一个移动的目标。请考虑停止编辑并在有问题时提交新问题。
I am curious: I take it you did not write this fsm? Is this for a homework assignment or are you trying to teach yourself? The code for the FSM looks fine (quite fine, in fact). However, your launch line:
Makes no sense. Here is why:
fsmtrlst
is the finite state machine transition list. It was defined in the first big block of code. It is not a function to be called. I believe the function you want to call isrun-fsm
. That takes a start symbol, a transition list, a list of final states, and an input. The input is not actually a string, but a list. As a consequence, you can launch it with the following line:That will call
run-fsm
with the defined transition listfsmtrlst
, the defined list of final states, and the input-ready form of the string "abc112".Incidentally, everything except
'start
is defined to be a final (accepting) state. Not all inputs are accepting inputs, though. For example, replacing "abc122" with "abc(122" is not accepted.Is this what you want?
Update:
Your edit has clarified things. Your definition of
fsmstart
is fine. You did miss a question mark (?) on one of yourchar-alphabetic?
usages infsmtrlst
. Is your confusion that you don't know how to use your new definitions? First, you should remove the old definitions offsmtrlst
andfsmfinal
. Otherwise, you will likely get a duplicate definition error. From your new definition, your line to execute should look like:This will return #t, because "w00t" is a character followed by two numbers, followed by a character.
I speculate that you are still having difficulty with the syntax rules of scheme, and not just problems with the logic of your particular program. You might want to try a simpler exercise.
UPDATE 2: Shouldn't you consider formulating a new question?
Your most recent update has broken the code. The transition portion of the fsm worked because transitions were defined as a list:
You have attempted to create a transition:
You could change
(A, "a", B)
to(A (lambda (x) (string=? x "a") B)
.When you tried to invoke your function, you took a function that expected a list of characters and gave it a list of list of strings. These are not the same thing. Also, did you notice that you put commas in your lists, but they existed nowhere else in the code? These mistakes are why I suggest you begin a scheme tutorial. These are basic scheme problems, unrelated to your particular exercise. I suggest you rewind your edits to what you had yesterday.
Unfortunately, I can no longer update this answer. I wanted to update my answer so that if someone came along your question with similar concerns, they would see a complete answer. However, you have provided a moving target. Please consider halting your edits and submit a new question when you have one.