ocaml - 比较两个等价类

标签 ocaml

我有这个简单的图表:

name -> string
 ^
 |
 v
label

let matrix = [|
[|false; false; false |];  
[|true; false; true  |];
[|false; true; false|] |]

(* compute transitive closure of matrix*)
let transClosure m =
  let n = Array.length m in
  for k = 0 to n - 1 do
    let mk = m.(k) in
    for i = 0 to n - 1 do
      let mi = m.(i) in
      for j = 0 to n - 1 do
    mi.(j) <- max mi.(j) (min mi.(k) mk.(j))
      done;
    done;
  done;
  m;;

传递闭包矩阵的输出为:

假假假
真实真实真实
真实真实真实

函数比较等价类:

let cmp_classes m i j =
  match m.(i).(j), m.(j).(i) with
      (* same class: there is a path between i and j, and between j and i *)
    | true, true -> 0
      (* there is a path between i and j *)
    | true, false -> -1
      (* there is a path between j and i *)
    | false, true -> 1
      (* i and j are not compareable *)
    | false, false -> raise Not_found

let sort_eq_classes m = List.sort (cmp_classes m);;

函数计算等价类:

let eq_class m i =
  let column = m.(i)
  and set = ref [] in
  Array.iteri begin fun j _ ->
    if j = i || column.(j) && m.(j).(i) then
      set := j :: !set
  end column;
  !set;;

let eq_classes m =
  let classes = ref [] in
  Array.iteri begin fun e _ ->
    if not (List.exists (List.mem e) !classes) then
      classes := eq_class m e :: !classes
  end m;
  !classes;;

(* compute transitive closure of given matrix *)
let tc_xsds = transClosure matrix
(* finding equivalence classes in transitive closure matrix *)
let eq_xsds = eq_classes tc_xsds
(* sorting all equivalence classes with transitive closure matrix *)
let sort_eq_xsds = sort_eq_classes tc_xsds (List.flatten eq_xsds)

它给了我顺序:标签、名称、字符串,表示正确的顺序。

问题是,当我用另一个图表进行测试时,例如:

name -> string
 ^
 |
 v
label -> int

name -> int
^   \
|    \
v     v
label string

name -> string
|
v
label -> int

输出是引发Not_found

您能帮我解释一下为什么它不能给出正确的顺序吗?谢谢。

最佳答案

正如我在 previous thread 中所说,它不能给你正确的顺序,因为在某些情况下有很多正确的顺序。

在所有三个反例中,您对 stringint 的顺序有何期望?一个接着一个还是只是随机顺序?由于它们之间没有边缘,因此它们不具有可比性,并且您的代码会引发 Not_found 异常。

处理此问题的一种方法是捕获 Not_found 异常,并指出没有唯一的顺序。或者更温和的方法是返回 0 而不是引发异常,这意味着您不关心不可比较的类之间的顺序。

正如 @ygrek 在评论中所说,使用内置异常是一个坏主意。您应该定义专用于您的目的的自定义异常。

关于ocaml - 比较两个等价类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9287760/

相关文章:

ocaml - 是否有使用OCaml开发的Window Manager?

compilation - 正确编译子文件夹中的模块 (ocamlbuild)

ocaml - 绘图自动机的工具

python - OCaml 将字符串映射到字符串列表

debugging - OCaml 跟踪 : what is the star?

c - 在脚本中定义特定日期 - unix date

syntax-error - #load “unix.cma”导致语法错误

recursion - 尾递归与前向递归

java - 用于 Ocaml 应用程序的 Java GUI

arrays - 从数组元素创建列表,生成数字序列