在Haskell的输入字符串列表中应用PDA转换

时间:2018-12-20 23:14:36

标签: haskell pushdown-automaton

我正在尝试根据讲师的笔记在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

0 个答案:

没有答案