可以处理任意确定性有限自动机的Haskell程序

可以处理任意确定性有限自动机的Haskell程序,haskell,dfa,Haskell,Dfa,您在某种程度上是正确的,因为您的DFA结构是正确的,但是您没有实现您获得的所有规范: 对于初学者,DFA应该有5个状态:状态=[0,1,2,3,4] 字母表是正确的,开始状态也是正确的。但是,在您的规范中,您可以看到接受状态是3,因此您需要将其放入代码中:fs=[3] 最后,您的delta函数出错。他们应该是这样的: You kind of are on the right track, as in your structure for the DFA is right, however you

您在某种程度上是正确的,因为您的DFA结构是正确的,但是您没有实现您获得的所有规范:

对于初学者,DFA应该有5个状态
状态=[0,1,2,3,4]

字母表是正确的,开始状态也是正确的。但是,在您的规范中,您可以看到接受状态是3,因此您需要将其放入代码中:
fs=[3]

最后,您的delta函数出错。他们应该是这样的:

You kind of are on the right track, as in your structure for the DFA is right, however you didn't implement all the specs you were given:

For starter, your DFA should have 5 states:
states = [0,1,2,3,4]

The alphabet is right, and so is the starting state. However in your specs you can see that the accepting state is 3, so you need to put it in your code:
fs = [3]

Finally your delta functions were wrong. Here's what they should be:

delta 0 '0' = 1
delta 0 '1' = 1
delta 0 '.' = 2
delta 1 '0' = 1
delta 1 '1' = 1
delta 1 '.' = 3
delta 2 '0' = 3
delta 2 '1' = 3
delta 2 '.' = 4
delta 3 '0' = 3
delta 3 '1' = 3
delta 3 '.' = 4
delta 4 '0' = 4
delta 4 '1' = 4
delta 4 '.' = 4
此外,您可以看到您的增量可以很容易地简化: 在任何状态下输入0或1都是相同的,因此可以通过更简单的模式匹配来实现。另外,4是一个黑洞状态,也就是说它总是映射到自身。因此,您可以将增量重写为:

delta 4  _  = 4
delta 0 '.' = 2
delta 0  _  = 1
delta 1 '.' = 3
delta 1  _  = 1
delta 2 '.' = 4
delta 2  _  = 3
delta 3 '.' = 4
delta 3  _  = 3
另外,正如其他人在评论中指出的,您的extendDelta和deltaStar只是应用左折叠的一种奇怪方式<代码>折叠“
通常更好,因为它不会建立堆栈,所以我将使用它。您需要从
Data.List导入它

这是您的最终DFA:

import import Data.List
type State = Int
type DFA = ([State], [Char], State->Char->State, State, [State])


dfaFactory :: DFA
dfaFactory = (states, alphabet, delta, s, fs)
              where
                states = [0,1,2,3,4]
                alphabet= ['1','0','.']
                s = 0
                fs = [3]
                delta 4  _  = 4
                delta 0 '.' = 2
                delta 0  _  = 1
                delta 1 '.' = 3
                delta 1  _  = 1
                delta 2 '.' = 4
                delta 2  _  = 3
                delta 3 '.' = 4
                delta 3  _  = 3

dfaAccept :: DFA -> String -> Bool
dfaAccept (qs,alpha,delta,s,fs) w = finalState `elem` fs
                                      where
                                        finalState = foldl' delta s w

我只是在为我的代码而挣扎。您需要更具体地说明您正在努力解决的问题。@LHM感谢您的澄清。Pro Stack Overflow tip:您可以使用倒勾来格式化内联代码,就像我在编辑中所做的那样。我刚刚将您的代码复制并粘贴到GHCi中,我很惊讶它甚至可以编译—您的缩进都是错误的。当您在例如
where
let
块中有一组语句时,它们需要缩进到相同的级别。@LHM我一直在查看您的代码,我认为
dfaaaccept dfaffafactory”“
应该是
True
,而不是
False
,因为您的DFA在状态
1
下启动,这也是一种接受状态。您应该开始学习如何调试Haskell代码。这是一个很好的开始。+1是一个有用的答案。然而,我觉得有必要对缩进样式进行评论。。。如果
dfaFactory
被重命名,会发生什么?您是否会被迫根据新名称的长度重新对齐整个
where
子句?如果您使用的是版本控制,那么对于一个相对较小的更改,差异看起来会很大。因此,我个人赞成。值得思考的东西。@jubobs是一个有趣的视角,我从未想过,我确实使用版本控制,但我只是一名本科生,因此从未正确地需要它,也从未注意到它的巨大差异。我将阅读指南并给出一个答案,如果你有合作者(而不是单独编码),我的建议可能更相关。无耻的插件,但我曾经做过一次闪电式的演讲,在演讲中我简要地提到了为什么我认为格式化风格值得考虑Git Diff:我的示例中使用的语言是Java,但我的观点适用于Haskell。谢谢,这真的很有帮助@LHM您可以进一步简化增量,因为大多数跳跃都是+2,但这超出了答案的范围,而且如果您的规格发生变化,这种方式更容易更改