24 [C;M;I], Le, [M;I]; (* ??? *)
26 [I;M;C], Ge, [I;M]; (* ??? *)
38 let swap = function Le -> Ge | Ge -> Le;;
43 | M::tl -> new_dir (swap dir) tl
44 | (C|I)::tl -> new_dir dir tl
49 (List.map (function I -> "i" | C -> "c" | M -> "-") w)
54 let (@@) l1 ll2 = List.map (function l2 -> l1 @ l2) ll2;;
57 let rec aux acc = function
60 | h1::h2::tl when h1=h2 -> aux (h2::acc) tl
61 | h1::tl (* when h1 <> h2 *) -> aux (h1::acc) tl
63 List.rev (aux [] (List.sort compare l))
66 let rec apply_rule_at_beginning (lhs,dir',rhs) (w,dir) =
73 | x::lhs,x'::w when x = x' -> aux (lhs,w)
74 | _,_ -> raise NoMatch
76 rhs @@ apply_rules (aux (lhs,w),new_dir dir lhs)
77 and apply_rules (w,_ as w_and_dir) =
84 (try apply_rule_at_beginning rule w_and_dir
92 let apply_rules (w,dir as w_and_dir) =
93 List.map (fun w' -> w,dir,w')
94 (uniq (apply_rules w_and_dir))
97 let step (l : w list) =
102 List.map (fun x -> x@w)
103 (if List.length (List.filter (fun w -> w = M) w) >= 1 then
115 if i mod 1000 = 0 then
117 print_string ("@" ^ string_of_int i ^ " ");
120 aux (f he :: acc) (i+1) tl
122 let res = List.rev (aux [] 1 l) in
132 if i mod 1000 = 0 then
134 print_string ("@" ^ string_of_int i ^ " ");
143 let normalize (l : w list) =
144 print_endline (string_of_int (List.length l) ^ " nodes to be normalized");
147 (mapi (fun x -> apply_rules (x,Le) @ apply_rules (x,Ge)) l) in
149 List.rev (List.rev_map
150 (function (x,rel,y) -> match rel with Le -> x,y | Ge -> y,x) rels) in
151 let res = uniq arcs in
155 let visualize describe graph =
158 include Graph.Pack.Digraph;;
159 let edge_attributes _ = []
160 let default_edge_attributes _ = []
161 let get_subgraph _ = None
162 let vertex_attributes v = [`Label (describe (Graph.Pack.Digraph.V.label v))]
163 let vertex_name v = "v" ^ string_of_int (Graph.Pack.Digraph.V.label v)
164 let default_vertex_attributes _ = []
165 let graph_attributes _ = []
167 let module D = Graph.Graphviz.Dot(G) in
168 let ch = open_out "/tmp/comb.dot" in
169 D.output_graph ch graph;
171 ignore (Unix.system ("tred /tmp/comb.dot > /tmp/red.dot"));
172 ignore (Unix.system ("dot -Tps /tmp/red.dot > /tmp/red.ps"));
173 (*Unix.system ("ggv /tmp/red.ps");*)
176 let mk_vertex_and_dsc_vertex =
178 let cache1 = Hashtbl.create 5393 in
179 let cache2 = Hashtbl.create 5393 in
182 Hashtbl.find cache1 w
189 | he::tl -> aux (acc * 4 + (match he with I -> 1 | C -> 2 | M -> 3)) tl
193 let v = Graph.Pack.Digraph.V.create n in
194 Hashtbl.add cache1 w v;
195 Hashtbl.add cache2 v w;
197 (Hashtbl.find cache2)
202 let cache1 = Hashtbl.create 5393 in
205 Hashtbl.find cache1 n
208 let v = Graph.Pack.Digraph.V.create n in
209 Hashtbl.add cache1 n v;
213 let string_compare s1 s2 =
214 let c = compare (String.length s1) (String.length s2) in
215 if c = 0 then String.compare s1 s2 else c
218 let normalize_and_describe norm dsc_vertex =
219 let cache = Hashtbl.create 5393 in
220 let canonicals = Hashtbl.create 5393 in
221 let descriptions = Hashtbl.create 5393 in
223 let normalized = norm v in
224 let dsc = dsc_vertex v in
225 if not (List.mem dsc (Hashtbl.find_all cache normalized)) then
226 Hashtbl.add cache normalized dsc;
229 let vertexes = uniq (Hashtbl.fold (fun k _ l -> k::l) cache []) in
234 List.sort string_compare
235 (List.map string_of_w (Hashtbl.find_all cache v))
237 iteri (function (_,w::_) -> Hashtbl.add canonicals w () | _ -> ()) xx;
238 let is_not_redundant s =
239 let len = String.length s in
240 if len <= 1 then true
242 let w = String.sub s 1 (len - 1) in
243 try Hashtbl.find canonicals w; true with Not_found -> false
247 Hashtbl.add descriptions v
248 (let s = String.concat "=" (List.filter is_not_redundant x) in
249 if s = "" then "." else s)) xx),
250 Hashtbl.find descriptions
254 print_endline (string_of_int (List.length arcs) ^ " arcs to be classified");
255 let mk_vertex,dsc_vertex = mk_vertex_and_dsc_vertex () in
256 let graph = Graph.Pack.Digraph.create () in
257 let varcs = mapi (fun (x,y) -> mk_vertex x,mk_vertex y) arcs in
258 iteri (fun (x,y) -> Graph.Pack.Digraph.add_edge graph x y) varcs;
259 print_endline ("<scc>");
260 let classes,norm = Graph.Pack.Digraph.Components.scc graph in
261 print_endline (string_of_int classes ^ " classes");
262 print_endline ("-----");
263 norm,dsc_vertex,varcs
266 let analyze (norm,dsc_vertex,arcs) =
267 print_endline ("building class graph (" ^ string_of_int (List.length arcs) ^ ")");
268 let normalize,finish,describe =
269 normalize_and_describe norm dsc_vertex in
271 uniq (mapi (fun (x,y) -> normalize x,normalize y) arcs) in
272 let cgraph = Graph.Pack.Digraph.create () in
273 let mk_vertex2 = mk_vertex2 () in
277 Graph.Pack.Digraph.add_edge cgraph (mk_vertex2 x) (mk_vertex2 y)) arcs;
278 print_endline "finish";
280 print_endline "visualize";
281 visualize describe cgraph;
282 print_endline ("/////");
286 let pkg = classify (normalize l) in
288 iter (n - 1) (step l)