Debuging all the code computing and sorting equivalence classes

送分小仙女□ 提交于 2019-12-13 03:22:21

问题


I have this function compute an equivalence class

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;;

and this function to collect all the classes are equivalence

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;;

I have this function to compare two equivalence 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

After I used this function to sort it by using List.sort

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

My matrix is an boolean matrix, and I computed it with transitive closure.

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

I tested with many counter example to test all these functions, for example with the graph (matrix)

EDIT

matrix:

 a <-> b  c <-> d
 |          
 v          
 e

matrix_2:

a <-> b -> e -> f
|          |
v          v
h <------- g 
|          |
v          v  
u          k    

I input the boolean matrix:

    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 |];
    |]

output of matrix 1: equivalence classes: e d c b a

sort equivalence classes: e d c b a

output of matrix 2: equivalence classes: u h g e b a k f

sort equivalence classes : u h k g f e b a

And the result is correct order like I expected. But when I test it with my data, which is an xsds data, more complicated depended relations. It output for me a wrong order. I had test with function transform to boolean matrix from xsds, and tested transitive closure, it is correct. So I think may be their is some bugs in my functions, (eq_class) or (cmp_classes).

Could you please help me to see what wrong in these code?


回答1:


The problem is in cmp_classes function.

From your source code:

(* 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

Obviously, your code doesn't fulfill your requirement. Several errors could be mentioned:

  1. If m.(i).(j) = true, you don't compare between i and j at all.
  2. If m.(i).(j) = false, you suppose to compare other combinations than i and j, but here you wrongly returns -1.
  3. You only compare using the heads of c and c' and ignore other elements while you suppose to use any pair of elements in two lists before reaching a conclusion.

In your small examples, you got correct results because equivalence classes often have one element. Since they are collected in the order that there is no path from former ones to later ones, your returning of -1 is fortunately correct. It's no longer the case with arbitrary input from xsd trees.

It's not difficult to fix the function if you can define it clearly. Now I still don't know the order of two equivalence classes without any path connecting them together ({a,b} and {c, d} classes in matrix).

In order that you can test your fix more easily, this is a small example which will produce a wrong order:

 a <-> b  c <-> d
 ^     ^  ^     ^
 |     |  |     |
 e     e  e     e


来源:https://stackoverflow.com/questions/8850604/debuging-all-the-code-computing-and-sorting-equivalence-classes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!