2 1: 29 6 0.549 3 8 16 24 29
3 2: 120 10 25.525 3 8 19 39 66 95 113 119 120
4 3: > 327 >9 3 8 19 39 75 134 208 274
5 4: > 657 >9 3 8 19 39 75 139 245
6 5: > 526 >8 3 8 19 39 75 139 245
21 s <= s' s <= s' s <= s' s <= s'
22 =========== =========== ============ ==========
23 ws <= Cws' Cs <= Cs' CMs' <= Ms Ms' <= MCs
26 =========== ============
47 [C;M;I], Le, [M;I]; (* ??? *)
49 [I;M;C], Ge, [I;M]; (* ??? *)
62 let cache = Hashtbl.create 5393 in
71 | he::tl -> aux (4 * acc + (match he with I -> 1 | C -> 2 | M -> 3)) tl
73 let res = 0, aux 0 w, w in
74 Hashtbl.add cache w res;
82 let hash = Hashtbl.hash
86 module GL = Graph.Imperative.Digraph.Concrete(VL);;
88 let swap = function Le -> Ge | Ge -> Le;;
93 | M::tl -> new_dir (swap dir) tl
94 | (C|I)::tl -> new_dir dir tl
100 (List.map (function I -> "i" | C -> "c" | M -> "-") w)
102 if s = "" then "." else s
108 (List.map (function I -> "i" | C -> "c" | M -> "m") w)
110 if s = "" then "E" else s
113 let string_of_eqclass l = String.concat "=" (List.map string_of_w l);;
115 let name_of_eqclass l = String.concat "_" (List.map string_of_w' l);;
119 let (@@) l1 ll2 = List.map (function l2 -> l1 @ l2) ll2;;
122 let rec aux acc = function
125 | h1::h2::tl when h1=h2 -> aux (h2::acc) tl
126 | h1::tl (* when h1 <> h2 *) -> aux (h1::acc) tl
128 List.rev (aux [] (List.sort compare l))
131 let rec apply_rule_at_beginning (lhs,dir',rhs) (w,dir) =
138 | x::lhs,x'::w when x = x' -> aux (lhs,w)
139 | _,_ -> raise NoMatch in
140 let w' = aux (lhs,w) in
141 if List.length rhs < List.length lhs then rhs @@ [w']
142 else rhs @@ apply_rules (aux (lhs,w),new_dir dir lhs)
143 and apply_rules (w,_ as w_and_dir) =
150 (try apply_rule_at_beginning rule w_and_dir
158 let apply_rules (w,dir as w_and_dir) =
159 List.map (fun w' -> w,dir,w')
160 (uniq (apply_rules w_and_dir))
163 let step (l : w list) =
168 List.map (fun x -> x@w)
169 (if List.length (List.filter (fun w -> w = M) w) >= 5 then
181 if i mod 1000 = 0 then
183 print_string ("@" ^ string_of_int i ^ " ");
186 aux (f he :: acc) (i+1) tl
188 let res = List.rev (aux [] 1 l) in
198 if i mod 1000 = 0 then
200 print_string ("@" ^ string_of_int i ^ " ");
209 let normalize canonical (l : w list) =
210 print_endline (string_of_int (List.length l) ^ " nodes to be normalized");
214 (mapi (fun x -> apply_rules (x,Le) @ apply_rules (x,Ge)) l) in
217 (function (x,rel,y) ->
218 let x = canonical x(*(inject x)*) in
219 let y = canonical y(*(inject y)*) in
220 match rel with Le -> x,y | Ge -> y,x) rels in
221 let res = uniq arcs in
222 let nodes = uniq (l @ List.map (fun (_,_,n) -> n) rels) in
223 let new_nodes = List.filter (fun n -> not (List.mem n all)) nodes in
224 let new_nodes = List.filter (function n -> [n] = canonical n) new_nodes in
225 if new_nodes = [] then
228 uniq (res @ aux nodes new_nodes)
233 let visualize graph =
237 let edge_attributes _ = []
238 let default_edge_attributes _ = []
239 let get_subgraph _ = None
240 let vertex_attributes v = [`Label (string_of_eqclass (GL.V.label v))]
241 let vertex_name v = name_of_eqclass (GL.V.label v)
242 let default_vertex_attributes _ = []
243 let graph_attributes _ = []
245 let module D = Graph.Graphviz.Dot(GL) in
246 let ch = open_out "/tmp/comb.dot" in
247 D.output_graph ch graph;
249 ignore (Unix.system ("tred /tmp/comb.dot > /tmp/red.dot"));
250 ignore (Unix.system ("dot -Tps /tmp/red.dot > /tmp/red.ps"));
251 (*Unix.system ("ggv /tmp/red.ps");*)
254 let w_compare s1 s2 =
255 let c = compare (List.length s1) (List.length s2) in
256 if c = 0 then compare s1 s2 else c
259 exception Found of GL.V.t;;
261 let rec iter n cgraph (canonical: w -> GL.V.t) =
262 print_endline ("STEP " ^ string_of_int n);
263 let nodes = GL.fold_vertex (fun n l -> n::l) cgraph [] in
264 let nodes = step (List.map List.hd nodes) in
265 (*let nodes = [[C;M];[C;M;C;M];[C;M;C;M;C;M];[C;M;C;M;C;M;C;M];[C;M;C;M;C;M;C;M;C;M]] in*)
266 (*let nodes = [[C;I;C;I;C;I]] in*)
267 (*let nodes = step (List.concat nodes) in*)
268 (*List.iter (fun x -> prerr_endline ("#@ " ^ string_of_w x)) nodes;*)
269 let arcs = normalize canonical nodes in
270 iteri (fun (x,y) -> if x <> y then GL.add_edge cgraph x y) arcs;
271 (*List.iter (fun (x,y) -> prerr_endline (string_of_eqclass x ^ " -> " ^ string_of_eqclass y)) arcs;*)
273 print_endline ("<scc>");
275 let module SCC = Graph.Components.Make(GL) in SCC.scc cgraph in
277 let module SCC = Graph.Components.Make(GL) in SCC.scc_array cgraph in
278 print_endline ("</scc>");
279 let get_canonical n =
280 try List.sort w_compare (List.concat (xxx.(norm n)))
283 let nodes = GL.fold_vertex (fun n l -> n::l) cgraph [] in
284 print_endline "get_canonical";
285 let nodes = mapi (fun n -> n,get_canonical n) nodes in
286 print_endline "/get_canonical";
287 print_endline ("collapse " ^ string_of_int (List.length nodes));
290 let succ = GL.succ cgraph n in
291 let pred = GL.pred cgraph n in
292 GL.remove_vertex cgraph n;
293 let add_edge s t = if s <> t then GL.add_edge cgraph s t in
294 List.iter (fun s -> add_edge n' (get_canonical s)) succ;
295 List.iter (fun p -> add_edge (get_canonical p) n') pred)
297 print_endline (string_of_int classes ^ " classes");
298 print_endline ("-----");
299 print_endline "visualize";
301 print_endline ("/////");
302 GL.iter_vertex (fun l -> print_endline ("?" ^ string_of_eqclass l)) cgraph;
304 function (*_,_,*)w ->
306 GL.iter_vertex (fun l -> if List.mem w l then raise (Found l)) cgraph;
311 iter (n - 1) cgraph canonical
315 let cgraph = GL.create () in
316 GL.add_vertex cgraph [[]];
317 iter 9 cgraph (fun w(*(_,_,w)*) -> [w])