Debugging 调试所有代码计算和排序等价类

Debugging 调试所有代码计算和排序等价类,debugging,ocaml,Debugging,Ocaml,我让这个函数计算一个等价类 let eq_class m i = let column = m.(i) and set = ref [] in Array.iteri begin fun j l -> if j = i || column.(j) && m.(j).(i) then set := j :: !set else ignore l end column; !set;; 而这个函数收集的所有类都是等价的 let eq_cl

我让这个函数计算一个等价类

let eq_class m i =
  let column = m.(i)
  and set = ref [] in
  Array.iteri begin fun j l ->
    if j = i || column.(j) && m.(j).(i) then
      set := j :: !set else ignore l
  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;;
我有这个函数来比较两个等价类:

let cmp_classes m c c' = if c = c' then 0 else
  match c, c' with
    | i :: _, j :: _ -> if m.(i).(j) then 1 else -1
    | _ -> assert false
使用此函数后,我使用List.sort对其进行排序

let sort_eq_classes m = List.sort (cmp_classes m);;
我的矩阵是一个布尔矩阵,我用传递闭包计算它

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 tc = transClosure matrix
let eq = eq_classes tc
let sort_eq = sort_eq_classes tc eq
矩阵1的输出: 等价类:
e d c b a

排序等价类:
e d c b a

矩阵2的输出: 等价类:
u h g e b a k f

排序等价类:
uhkgfeba

结果是正确的顺序,就像我预期的那样。但是当我用我的数据(xsds数据)测试它时,更复杂的依赖关系。它为我输出了一个错误的订单。我测试了从xsds到布尔矩阵的函数转换,并测试了传递闭包,它是正确的。所以我想可能是我的函数中有一些bug,(
eq_类
)或(
cmp_类


你能帮我看看这些代码有什么错误吗

问题出在
cmp\u类
函数中

从您的:


如果你不提供一个简短的反例,调试是非常困难的。ThanksI的意思是一个示例,它演示了代码中的错误结果。我用这些代码测试的所有示例都是正确的。但是当我将它应用到我支持的测试数据时,它并没有给出正确的顺序;这可能是不正确的。此外,要小心一些有副作用的功能。当您调用
let tc=transClosure matrix
时,tc只是已更改的
matrix
的别名。
让cmp_类m c c'=将c,c'与| i:|,j:|->如果i=j,则0 else如果i>=j,则1 else-1 | | |->断言false
我用您给我的示例进行了测试,它给了一个正确的顺序与此比较。我将其应用于xsds数据。它仍然没有返回正确的订单。我试着根据你在1)2)和3)中的建议编写一个函数检查,结果证明我在这里给出的函数是正确的。你的新函数显然是错误的。当可能没有从
i
j
m.(i)。(j)=false
)的路径时,为什么要比较它们?想想我的建议;我帮不了你更多的忙。
让cmp_类mc'=将c,c'与| I::,j::。->如果m.(I)。(j)=true,那么比较I j,如果m.(I)。(j)=false,那么…|assert false
我不理解建议2)支持比较除I和j以外的其他组合。我在考虑c,但它没有给我一个正确的答案。试着将
c
的每个元素与
c'
的每个元素进行比较(不仅仅是比较它们的头部)。如果这些元素在某个点上具有可比性,则返回该点。否则,从
c
元素到
c'
元素没有路径;抛出一个异常。我试图编写另一个函数来比较I和j,并用上面的一个小示例进行了测试,它给出了正确的顺序,但当我使用数据运行它时,它给出了与以前相同的顺序。你能帮帮我吗<代码>让cmp_类m i j=如果i=j,那么0 else如果m.(i)。(j)如果m.(j)。(i)那么0 else 1 else如果m.(j)。(i)那么0 else-1
 a <-> b  c <-> d
 |          
 v          
 e
a <-> b -> e -> f
|          |
v          v
h <------- g 
|          |
v          v  
u          k    
    let matrix =
   [|
   [|false; true; false; false; false|];
   [|true; false; false; false; false|];
   [|false; false; false; true; false|];
   [|false; false; true; false; false|];
   [|false; false; false; false; false|];
   |];;

let matrix_2 =
    [|
    [| false; false; false; false; false; false; false; false |];
    [| false; false; false; false; false; false; false; false |];
    [| false; false; false; true; false; false; true; false |];
    [| false; false; true; false; true; false; false; false |];
    [| true; false; false; false; false; true; false; false |];
    [| false; true; false; false; false; false; true; false |];
    [| false; false; false; false; false; false; false; true |];
    [| false; false; false; false; false; false; false; false |];
    |]
(* We check that if two elements are in the same equivalence class they are
   equal (0); if they have a path from i to j then i < j (-1)
   otherwise i > j (1). We assumes that: each equivalence class only
   appears once and each equivalence class contains at least one
   element. *)

let cmp_classes m c c' = if c = c' then 0 else
  match c, c' with
    | i :: _, j :: _ -> if m.(i).(j) then 1 else -1
    | _ -> assert false
 a <-> b  c <-> d
 ^     ^  ^     ^
 |     |  |     |
 e     e  e     e