OCaml中使用“开放式列表”和“差异列表”吗?

时间:2014-03-04 15:52:12

标签: ocaml

有时候,我听说过open-ended listdifference-list。我知道他们来自prolog:Difference between "open-ended lists" and "difference lists"

但OCaml是否使用它们?

我问这个问题,因为在OCaml 99 problems中,有一个问题:

图同构。 (介质)

  

如果存在a,则两个图G1(N1,E1)和G2(N2,E2)是同构的   双射f:N1→N2使得对于任何节点X,N1,Y和Y的Y是   当且仅当f(X)和f(Y)相邻时才相邻。

     

编写一个函数,确定两个图是否同构。   提示:使用开放式列表来表示函数f。

我甚至不理解提示:

  

使用开放式列表来表示函数f

问题:

  1. 有人可以解释一下吗?
  2. 或者确认我们在OCaml中没有这两样东西?
  3. 如果我们没有这两种清单,我们如何解决上述问题?在G1中的节点和G2中的节点之间进行所有可能的映射,并检查每对是否相邻?

1 个答案:

答案 0 :(得分:1)

谷歌搜索“开放式列表图表同构”表明该问题是从一组Prolog练习中复制粘贴的。提示存在于原始版本中,当然在Prolog上下文中比在OCaml中更有意义。

这是a solution in Prolog图同构问题;它可能使用开放式列表(我不熟悉执行检查或扩展同构的工作的标准库memberchk的行为),但这只是一个实现细节。

算法的一般思想是对表示部分同构的结构进行回溯,到目前为止所处理的所有边都是一致的。你可以用任何语言实现它,例如使用非确定性monad,我不认为尾细胞统一在这里发挥重要作用;使用Map(来自标准库的持久关联映射)来操纵从N1的节点到N2的节点的映射就可以了(并且在算法上比在线性搜索中更有效)开放式清单)。

算法的伪代码如下:

let add_edge iso (n1,n2) (n1', n2') =
  if n1 is unbound in iso, extend it with n1->n1'
  same for (n2, n2')
  if n1 is bound to a node different from n1' return None
  same for (n2, n2')
  else Some iso

let graph_iso iso g1 g2 =
  if g1 is empty then Some iso
  else if has an edge e1 then
    for any e2 in g2 such that add_edge iso e1 e2 is Some iso'
      if graph_iso iso' (g1 - e1) (g2 - e2) is not None, return it
    else return None