在OCaml中将一对int列表转换为布尔矩阵

时间:2011-12-22 09:19:40

标签: debugging matrix boolean ocaml

我有一个将(int * int list) list带到布尔矩阵的函数。我用我的反例来测试,它给了我一个正确的答案。像下面的代码一样。

let to_matrix l =
let n = List.length l in
  let m = Array.make_matrix (n + 1) (n + 1) false in
  List.iter (fun (i, j) ->
  List.iter (fun t ->
    m.(i).(t) <- true) j) l;
  m;;

let ex = to_matrix [(0, [1; 0]); (1, [0]); (2, [1])];;

它给了我一个矩阵:

true true false false  
true false false false  
false true false false  
false false false false

我必须在我的真实数据中测试它,它是一个xsds列表,就像下面的数据脚本一样。例如:

[Elt ("name", Some (SimpleType "string"), 1, Bound 1);
   Group ("label",
    Some
     (Choice
       [Elt ("numberLabel",
         Some
          (Sequence
            [Elt ("number", Some (SimpleType "nonNegativeInteger"), 0,
              Unbounded)]),
         1, Bound 1);
        Elt ("symbolLabel",
         Some (Sequence [GroupRef ("name", 0, Unbounded)]), 1, Bound 1)]),
    1, Bound 1)]

编辑:

感谢Thomas的回答。

我错过了关于我从遍历这些树回来的类型的解释。

遍历后的类型看起来像这个列表:

[(“name”; [“string”]); (“label”; [“nonNegativeInteger”;“name”])...]

从这个xsds列表中我想表示一个布尔矩阵来显示它们之间的依赖关系,例如:type name取决于类型字符串;类型 label取决于类型nonNegativeInteger和name。

1 个答案:

答案 0 :(得分:3)

函数to_matrix错误。

如果您使用to_matrix [(0, [2])];;

进行测试,则可以看到它

为了使其有效,您需要找到一种方法将列表的'a映射到[0..(n-1)],其中n是列表中出现的元素数量。< / p>

使用关联列表的可能方式:

let mapping = ref []
let int_of_a a =
  if List.mem_assq a !mapping then
    List.assq a !mapping
  else
    let n = List.length !mapping in
    mapping := (a, n) :: !mapping;
    n

并将您的to_matrix功能更改为:

let to_matrix l =
  (* step 1: registering your inputs *)
  mapping := [];
  let register i = ignore (int_of_a i) in
  List.iter (fun (i, j) ->
    register i;
    List.iter register j
  ) l;
  let n = List.length !mapping in
  (* step 2: creating and populating your matrix *)
  let m = Array.make_matrix n n false in
    List.iter (fun (i, j) ->
      List.iter (fun t ->
        m.(int_of_a i).(int_of_a t) <- true
      ) j
    ) l;
    m;;

这显然不是写这类事情的最佳方式,但你明白了。