2 ||M|| This file is part of HELM, an Hypertextual, Electronic
3 ||A|| Library of Mathematics, developed at the Computer Science
4 ||T|| Department, University of Bologna, Italy.
6 ||T|| HELM is free software; you can redistribute it and/or
7 ||A|| modify it under the terms of the GNU General Public License
8 \ / version 2 or (at your option) any later version.
9 \ / This software is distributed as is, NO WARRANTY.
10 V_______________________________________________________________ *)
12 module ET = RolesTypes
17 let list_union error compare l1 l2 =
18 let rec aux l1 l2 = match l1 with
20 | hd1::tl1 -> match l2 with
23 let b = compare (snd hd1) (snd hd2) in
24 if b > 0 then hd2 :: aux l1 tl2
25 else if b < 0 then hd1 :: aux tl1 l2
26 else raise_error (error (snd hd1))
30 let list_compare compare l1 l2 =
31 let rec aux l1 l2 = match l1 with
33 if l2 = [] then 0 else -1
34 | hd1::tl1 -> match l2 with
37 let b = compare hd1 hd2 in
38 if b = 0 then aux tl1 tl2 else b
42 let rec list_nth n = function
43 | [] -> raise_error ET.ENoEntry
44 | (_,hd)::tl -> if n = 0 then hd else list_nth (pred n) tl
46 let rec list_toggle n = function
47 | [] -> raise_error ET.ENoEntry
48 | (b,hd)::tl -> if n = 0 then (not b,hd)::tl else (b,hd)::list_toggle (pred n) tl
50 let rec list_toggle_all = function
52 | (b,hd)::tl -> (not b,hd)::list_toggle_all tl
54 let rec list_split = function
56 | (b,a) as hd :: tl ->
57 let fs,ts = list_split tl in
58 if fst hd then fs,((false,a)::ts)
61 let rec list_select r = function
65 | false, _ -> list_select r tl
66 | true , None -> list_select (Some hd) tl
67 | true , Some _ -> raise_error (ET.EWrongSelect)
70 let rec list_exists compare = function
74 if b <= 0 then b = 0 else
75 list_exists compare tl
77 let string_of_version v =
78 String.concat "." (List.map string_of_int v)
80 let version_of_string s =
81 List.map int_of_string (String.split_on_char '.' s)
83 let compare_versions v1 v2 =
84 list_compare compare v1 v2
86 let string_of_name n =
89 let name_of_string s =
90 String.split_on_char '_' s
92 let compare_names n1 n2 =
93 list_compare compare n1 n2
95 let names_union ns1 ns2 =
96 let error n = ET.ENameClash n in
97 list_union error compare_names ns1 ns2
99 let string_of_obj (v,n) =
100 Printf.sprintf "%s/%s" (string_of_version v) (string_of_name n)
102 let obj_of_string s =
103 match String.split_on_char '/' s with
104 | [sv;sn] -> version_of_string sv, name_of_string sn
105 | _ -> failwith "obj_of_string"
107 let compare_objs (v1,n1) (v2,n2) =
108 let b = compare_versions v1 v2 in
109 if b = 0 then compare_names n1 n2 else b
111 let objs_union os1 os2 =
112 let error o = ET.EObjClash o in
113 list_union error compare_objs os1 os2
115 let rec rev_objs_of_names v os = function
117 | (b,n)::tl -> rev_objs_of_names v ((b,(v,n))::os) tl
120 let n = match r.ET.n with
126 let string_of_role r =
127 string_of_obj (obj_of_role r)
129 let compare_roles r1 r2 =
130 compare_objs (obj_of_role r1) (obj_of_role r2)
132 let roles_union rs1 rs2 =
133 let error r = ET.ERoleClash r in
134 list_union error compare_roles rs1 rs2
136 let exists_role_deleted v r =
138 let compare r = compare_objs o (obj_of_role r) in
139 list_exists compare r
141 let rec get_tops v = function
144 let ds, ts = get_tops v tl in
145 if compare_versions v r.ET.v = 0 then begin
146 if r.ET.n = [] then objs_union r.ET.o ds, ts else
147 let tops = rev_objs_of_names v [] r.ET.n in
148 ds, objs_union (List.rev tops) ts
152 let rec match_names oi ni os ns =
156 | (_,o)::otl,(_,n)::ntl ->
157 let b = compare_names (snd o) n in
158 if b > 0 then match_names oi (succ ni) os ntl else
159 if b < 0 then match_names (succ oi) ni otl ns else
163 ET.r = []; ET.s = []; ET.t = []; ET.w = [];
166 let pointer_of_string = version_of_string
168 let string_of_error = function
170 Printf.sprintf "unknown input file type %S" x
172 Printf.sprintf "current stage %S" (string_of_version v)
174 Printf.sprintf "current stage not defined"
176 Printf.sprintf "current stage not finished"
178 Printf.sprintf "name clash %S" (string_of_name n)
180 Printf.sprintf "object clash %S" (string_of_obj o)
182 Printf.sprintf "role clash %S" (string_of_role r)
184 Printf.sprintf "entry not found"
186 Printf.sprintf "selected role is not unique"
187 | ET.EWrongVersion ->
188 Printf.sprintf "selected role is not in the current stage"
190 Printf.sprintf "top objects already computed"