(* $Id: mostdesc.ml,v 4.6 2004/12/14 09:30:14 ddr Exp $ *) (* Copyright (c) 1998-2005 INRIA *) open Gutil; open Def; value print_result base tab = let m_val = ref Num.zero in let m_list = ref [] in loop () where rec loop () = do { m_val.val := Num.zero; m_list.val := []; for i = 0 to Array.length tab - 1 do { if Num.eq tab.(i) Num.zero then () else if Num.gt tab.(i) m_val.val then do { m_val.val := tab.(i); m_list.val := [i]; } else if Num.eq tab.(i) m_val.val then m_list.val := [i :: m_list.val] else () }; if m_list.val <> [] then do { m_list.val := let f i1 i2 = let p1 = base.data.persons.get i1 in let p2 = base.data.persons.get i2 in let s1 = Name.abbrev (Name.lower (p_surname base p1)) in let s2 = Name.abbrev (Name.lower (p_surname base p2)) in if s1 < s2 then True else if s1 > s2 then False else let f1 = Name.abbrev (Name.lower (p_first_name base p1)) in let f2 = Name.abbrev (Name.lower (p_first_name base p2)) in f1 <= f2 in Sort.list f m_list.val; Num.print print_string "." m_val.val; print_newline (); List.iter (fun i -> let p = base.data.persons.get i in do { Printf.printf "- %s.%d %s\n" (p_first_name base p) p.occ (p_surname base p); flush stdout; }) m_list.val; List.iter (fun i -> tab.(i) := Num.zero) m_list.val; loop () } else () } ; value most_desc base p = let _ = base.data.ascends.array () in let _ = base.data.couples.array () in let id = Consang.topological_sort base aoi in let module Pq = Pqueue.Make (struct type t = iper; value leq x y = id.(Adef.int_of_iper x) > id.(Adef.int_of_iper y); end) in (* let _ = base.data.persons.array () in *) let _ = base.data.descends.array () in let _ = base.data.unions.array () in let tab = Array.create base.data.persons.len Num.zero in let entered = Array.create base.data.persons.len False in let q = ref Pq.empty in do { q.val := Pq.add p.cle_index q.val; tab.(Adef.int_of_iper p.cle_index) := Num.one; while not (Pq.is_empty q.val) do { let (ip, nq) = Pq.take q.val in q.val := nq; let u = uoi base ip in let n = tab.(Adef.int_of_iper ip) in for i = 0 to Array.length u.family - 1 do { let des = doi base u.family.(i) in for j = 0 to Array.length des.children - 1 do { let ip = des.children.(j) in tab.(Adef.int_of_iper ip) := Num.add tab.(Adef.int_of_iper ip) n; if not entered.(Adef.int_of_iper ip) then do { q.val := Pq.add ip q.val; entered.(Adef.int_of_iper ip) := True; } else (); } } }; print_result base tab; } ; value bname = ref ""; value p_fname = ref ""; value p_num = ref 0; value p_sname = ref ""; value usage = "usage: " ^ Sys.argv.(0) ^ " " ; value speclist = []; value main () = let cnt = ref 0 in do { Argl.parse speclist (fun s -> do { match cnt.val with [ 0 -> bname.val := s | 1 -> p_fname.val := s | 2 -> p_num.val := int_of_string s | 3 -> p_sname.val := s | _ -> raise (Arg.Bad "too many parameters") ]; incr cnt; }) usage; if cnt.val <> 4 then do { Printf.eprintf "Missing parameter\n"; Printf.eprintf "Use option -help for usage\n"; flush stderr; exit 2 } else (); Secure.set_base_dir (Filename.dirname bname.val); let base = Iobase.input bname.val in let ip = Gutil.person_ht_find_unique base p_fname.val p_sname.val p_num.val in most_desc base (poi base ip) } ; Printexc.catch main ();