【问题标题】:Return all reachable states in a DFA starting from the initial state从初始状态开始返回 DFA 中的所有可达状态
【发布时间】:2014-12-21 21:28:31
【问题描述】:

我正在尝试在 Haskell 中编写一个程序,它返回从初始状态开始的可达状态列表,类似于深度优先搜索。

states_reachable :: Eq st => DFA st -> [st]
states_reachable (qs, sigma, delta, s, inF) =
    [delta q a | q <- qs, a <- sigma]

注意:

  • qs 是状态集
  • sigma 是字母表
  • delta 是一个转换函数,它接受一个状态和一个符号并返回下一个状态
  • s 是初始状态
  • inF 是一个函数,如果状态是接受状态,则返回 true,否则返回 false

现在定义函数:

[delta q a | q <- qs, a <- sigma]

返回 DFA 中的所有状态(不正确)。

我想要的是通过从初始状态 s 开始并使用每个输入测试 delta 函数来填充列表。

例如:

// returns the states reachable from the initial state for all symbols in sigma
[delta s a | a <- sigma]

下一步将针对添加到列表中的每个新状态重复该过程。这可能会添加重复项,但我可以稍后将其删除。

然后我尝试了:

[delta q a | q <- [delta s a | a <- sigma], a <- sigma]

我认为这可能有效,但它不起作用,因为它正在创建内部列表,然后使用它来填充外部列表,然后停止。

我需要通过探索 delta 函数返回的所有新状态来递归地构建这个列表。

【问题讨论】:

标签: haskell dfa


【解决方案1】:

您在这里尝试计算关系的传递闭包,其中关系是“x 可以一步到达 y”。因此,我建议使用通用传递闭包解决方案,而不是特定于 DFA 的解决方案,然后从您的 DFA 生成该关系。这是一种相当基本的方法:

module Closure (closure) where                                                  
import Data.List (nub)

closure :: Eq a => (a -> [a]) -> a -> [a]
closure nexts init = go [init]
  where go xs = let xs' = nub $ xs ++ (xs >>= nexts)                            
                in if xs == xs'                                                 
                   then xs                                                      
                   else go xs'                                                  

这里的算法是有一个可达状态的列表,并且在每一步通过从每个状态到所有最近的邻居来扩展它,然后nub这个列表来消除重复。一旦该扩展步骤没有添加新节点,您就完成了。

现在,如何将您的 DFA 问题映射到此?这并不难:您只需要使用sigmadelta 生成一个nexts 函数。这里我们需要假设你的DFA delta 函数是total,即每个节点都为sigma 中的每个字母指定了一个转换。这很容易通过创建一个额外的“失败”节点,如果所有节点不喜欢他们的输入,所有节点都可以转换到该节点,所以我只是假设已经完成。

neighbors :: (node -> letter -> node) -> [letter] -> node -> [node]             
neighbors delta sigma n = map (delta n) sigma                                   

有了这些,你原来的问题就变成了:

closure (neighbors delta sigma) s

【讨论】:

  • 我确信有更好的方法来编写closureiterateunfoldr 或比if 更高级别的东西,但是当我尝试时发现它真的很乱。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-28
  • 2019-05-08
  • 1970-01-01
相关资源
最近更新 更多