我正在尝试根据讲师的笔记在Haskell中实现PDA,她向我们描述了一般过程,而实际的功能实现则留给我们。我觉得我的大部分工作都{@ {1}}函数中有一个小错误。
PDA的规则如下:
nextsteps
[((1,"a",""),(1,"a")),((1,"b",""),(1,"b")),((1,"a",""),(2,"")),((1,"b",""),(2,"")),((1,"",""),(2,"")),((2,"a","a"),(2,"")),((2,"b","b"),(2,""))]
该程序适用于某些字符串,而不适用于其他字符串,我确定它与我的nextsteps函数有关。在我的讲师笔记中,她举了一个例子
run :: PDA -> String -> Result
run _ "" = Reject
run (state,finalState,rules) str = findpath [(state,str,""(state,finalState,rules)
data Result = Accept | Reject deriving Show
type PDA = (Int,[Int],[Transition])
-- Takes in the start state, the current value read by the input string, the current stack and the new state along with the change to the stack
-- ((1,"a",""),(1,"a"))
type Transition = ((Int, String, String),(Int,String))
-- contains the current state, current input string and current state of the stack
-- (1,"abba","ba")
type Configuration = (Int, String, String)
--if the list of configurations isnt accepted, apply the PDA transitions to it and try again
findpath :: [Configuration] -> PDA -> Result
findpath [] pda = Reject
findpath (h:t) (a,b,c) = if accept (h:t) b == True then Accept else findpath (nextsteps (h:t) c) (a,b,c)
accept' :: Configuration -> [Int] -> Bool
accept' config [] = False
accept' (x,y,z) [a] = if x == a && y == "" && z == "" then True else False
accept:: [Configuration] -> [Int] -> Bool
accept [] _ = False
accept _ [] = False
accept (h:t) finalState = if accept' h finalState then True else accept t finalState
-- apply a given transition to a configuration based on the values in the configuration and transition
step :: Configuration -> Transition -> [Configuration]
step (a,b,"")((d,"",""),(g,"")) = if a == d then [(g,b,"")] else []
step (a,(b:bs),"")((d,"",""),(g,h)) = if a == d then [(g,bs,[b])] else []
step (a,(b:bs),"") ((d,"",f),(g,"")) = if a == d then [(g,(b:bs),f)] else []
step (a,(b:bs),"") ((d,"",f),(g,h)) = if a == d then [(g,(b:bs),h)] else []
step (a,(b:bs),"") ((d,[e],""),(g,"")) = if a == d && b == e then [(g,bs,"")] else []
step (a,(b:bs),"") ((d,[e],""),(g,h)) = if a == d && b == e then [(g,bs,[b])] else []
step (a,(b:bs),"") ((d,[e],f),(g,"")) = if a == d && b == e then [(g,bs,"")] else []
step (a,(b:bs),"") ((d,[e],f),(g,h)) = if a == d && b == e then [] else []
step (a,b,c) ((d,"",""),(g,"")) = if a == d then [(g,b,c)] else []
step (a,(b:bs),c) ((d,"",""),(g,h)) = if a == d then [(g,bs,c)] else []
step (a,b,(c:cs))((d,"",[f]),(g,"")) = if a == d && c == f then [(g,b,cs)] else []
step (a,b,(c:cs)) ((d,"",[f]),(g,h)) = if a == d && c == f then [(g,b,cs++h)] else []
step (a,(b:bs),c) ((d,[e],""),(g,"")) = if a == d then [(g,bs,c)] else []
step (a,(b:bs),c) ((d,[e],""),(g,h)) = if a == d && b == e then [(g,bs,[b]++c)] else []
step (a,(b:bs),(c:cs)) ((d,[e],[f]),(g,""))= if a == d && b == e && c == f then [(g,bs,cs)] else []
step (a,(b:bs),(c:cs)) ((d,[e],[f]),(g,h)) = if a == d && b == e && c == f then [(g,bs,cs++h)] else []
-- apply the entire ruleset of the PDA over one configuration and return a list of the results
steps :: Configuration -> [Transition] -> [Configuration]
steps config [] = []
steps (a,b,c) (h:t) = if b /= "" then step (a,b,c) h ++ steps (a,b,c) t else []
-- take in a list of configurations and apply the entire rulest over each configuration and return a list of results
nextsteps :: [Configuration] -> [Transition] -> [Configuration]
nextsteps config [] = []
nextsteps (h : t) rules = steps h rules ++ nextsteps t rules
但是,当我在完全相同的输入上调用函数时,得到nextsteps [(1,"bbabba","a"),(2,"abbabba",""),(2,"bbabba","") rules = [(1,"babba","ba"),(2,"babba","a"),(2,"bbabba","a")]
。
我不确定这个多余的重复值来自哪里,这是为什么不应该排除的字符串被接受的主要原因。我尝试删除配置列表的尾部,仅将steps函数应用到列表的开头,这将确保不应该接受的任何列表都是[(1,"babba","ba"),(2,"babba","a"),(2,"babba","a"),(2,"bbabba","a")]
,而且是Rejected
输入应为Rejected
。