Ошибка при преобразовании в булеву матрицу

У меня эта проблема до сих пор беспокоит меня много. У меня есть (string * string list) list, и я хочу преобразовать его в логическую матрицу.

У меня есть особое условие при трансформации. Например, у меня есть этот список:

let entries = [("name", ["string"; "label"]); ("label", ["int"; "name"]); 
               ("symbol", ["string"])]

где «string» и «int» — это неопределенный тип, неопределенный тип, потому что в моих реальных данных у меня нет определения, описывающего этот тип. Поэтому я построил список неопределенного типа.

let undefined = ["string"; "int"]

И первая позиция в списке ("name", "label", "symbol") - это определенный тип, определенный тип - это тип, который у меня есть в моих данных.

let defined = ["name"; "label"; "symbol"]

Я пытаюсь сделать это: из entries позиция должна быть:

name: 2; string: 0; label: 3; int: 1; symbol: 4

А при показе отношения зависимости из списка entries не меняет их положение. Например: name(2) ссылается на string(0) и label(3), а label (3) имеет преимущество на int(1) и name (2),` и так далее...

У меня эти функции возвращают позицию (num_of_name) и элемент (name_of_num) в списке.

let rec position x = function
| [] -> raise Not_found
| y :: ys -> if x = y then 0 else 1 + position x ys

let len_undefined = List.length undefined

let num_of_name defined undefined len_undefined s =
  try (position s defined) + len_undefined;
  with Not_found -> position s undefined

let name_of_num defined undefined len_undefined k =
  if k < len_undefined then
    List.nth undefined k else
    List.nth defined (k - len_undefined)

Итак, из списка entries я хочу построить логическую матрицу, показывающую отношение, используя функцию num_of_name. Итак, я пишу свою функцию:

let matrix =
  let len = List.length defined + len_undefined in
  let boolmat = Array.make_matrix len len false in
  List.iter (fun (s, strs) ->
    let pos1 = num_of_name defined undefined len_undefined s in
      List.iter (fun t ->
    let pos2 = num_of_name defined undefined len_undefined t in
    boolmat.(pos1).(pos2) <- true) strs) entries;
    boolmat

let print_mat m =
  for i = 0 to Array.length m - 1 do
    for j = 0 to Array.length m.(0) - 1 do
      print_string (string_of_bool m.(i).(j));
      Printf.printf " ";
    done;
    Printf.printf " \n";
  done;
;;

let test_print = print_mat matrix

Возвращает ошибку "Fatal error: exception Not_found"

Мне требуется ваша помощь. Большое Вам спасибо!!


person Quyen    schedule 10.01.2012    source источник
comment
Не могли бы вы объяснить, что вы хотите сделать? Каковы роли undefined и defined?   -  person pad    schedule 10.01.2012
comment
Действительно?? Я попытался запустить снова, и он возвращает мне ту же ошибку.   -  person Quyen    schedule 10.01.2012
comment
неопределенный тип, потому что в моих реальных данных у меня нет определения, описывающего этот тип. И определенный тип - это тип, который у меня есть в моих данных.   -  person Quyen    schedule 10.01.2012
comment
Ваша функция name_of_num не используется. И ваш тестовый код отлично работает на моей машине. Вы уверены, что используете тот же код, что и здесь?   -  person pad    schedule 10.01.2012
comment
Вы правы, name_of_num - это я пытаюсь показать, что их отношения конвертируются из int -> string и string -> int. Я уверен. Я бегу снова, но это все еще проблемы. Я добавил больше информации, объясняет больше деталей о том, что я хочу.   -  person Quyen    schedule 10.01.2012
comment
Хорошо, я нашел ошибку в коде на моей машине!   -  person Quyen    schedule 10.01.2012
comment
Если где-то в entries есть строка, не принадлежащая ни defined, ни undefined, возникает исключение. В противном случае ваш код правильный.   -  person pad    schedule 10.01.2012
comment
Да это правильно. Большое спасибо.   -  person Quyen    schedule 10.01.2012
comment
Я поставил это как ответ, который включает мое предложение.   -  person pad    schedule 10.01.2012


Ответы (1)


Как я сказал в комментарии, ваша функция num_of_name хрупкая, поскольку она выдает исключение Not_found, когда ее ввод не является элементом ни defined, ни undefined. Один из способов исправить это использовать тип Option:

let num_of_name defined undefined len_undefined s =
  try 
      let p = position s defined in
      Some (p + len_undefined)
  with Not_found -> 
     try
       let p = position s undefined in
       Some p
     with Not_found -> None

а matrix рассчитывается как:

let matrix =
  let len = List.length defined + len_undefined in
  let boolmat = Array.make_matrix len len false in
  List.iter (fun (s, strs) ->
    match num_of_name defined undefined len_undefined s with
    | Some pos1 -> List.iter (fun t ->
                      match num_of_name defined undefined len_undefined t with
                      | Some pos2 -> boolmat.(pos1).(pos2) <- true
                      | None -> ()) strs
    | None -> ()
      ) entries; 
  boolmat

Конечно, если вы применяете свою программу, извлекая defined и undefined из entries, ваш код правильный.

person pad    schedule 10.01.2012