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