1 let (++) f g x = f (g x);;
\r
3 let print_hline = Console.print_hline;;
\r
12 | Stuck of var * int
\r
16 let rec consts = (* const_apps, const_lambda *)
\r
17 let rec aux1 = function
\r
18 | A(t, _) -> 1 + aux1 t
\r
20 let rec aux2 = function
\r
25 let a1, b1 = consts t1 in
\r
26 let a2, b2 = consts t2 in
\r
27 max (aux1 t) (max a1 a2), max b1 b2
\r
29 let a, b = consts t' in
\r
40 ; matches : (var (* variable originating this match *) * ((int (* index of the term to discriminate *) * var option (* continuation *))) list) list
\r
41 ; sigma : (var * t) list (* substitutions *)
\r
42 ; stepped : var list
\r
43 ; arities : (var * int) list
\r
48 let dummy_p = {orig_freshno=0; freshno=0; div=B; conv=[]; matches=[]; sigma=[]; stepped=[]; arities=[]; k_app=0;k_lam=0};;
\r
50 let append_conv p t = let len = List.length p.conv in let p = {p with conv=t::p.conv} in p, len;;
\r
51 let get_conv p n = List.nth p.conv (List.length p.conv - 1 - n);;
\r
52 let index_of_conv t conv = List.length conv - 1 - (Util.index_of t conv);;
\r
55 let eq_conv_indices p i j = eq_conv (get_conv p i) (get_conv p j);;
\r
56 let all_terms p = p.div :: p.conv;;
\r
58 exception Done of (var * t) list (* substitution *);;
\r
59 exception Fail of int * string;;
\r
62 let bound_vars = ["x"; "y"; "z"; "w"; "q"; "x1"; "x2"; "x3"; "x4"; "x5"] in
\r
63 let rec string_of_term_w_pars level = function
\r
64 | V v -> if v >= level then "`" ^ string_of_int (v-level) else List.nth bound_vars (level - v-1)
\r
66 | L _ as t -> "(" ^ string_of_term_no_pars_lam level t ^ ")"
\r
69 | Stuck _ as t -> "(" ^ string_of_term_no_pars_app level t ^ ")"
\r
70 (* | Ptr _ as t-> "(" ^ string_of_term_no_pars_app level t ^ ")" *)
\r
71 (* "&" ^ string_of_int n *)
\r
72 and string_of_term_no_pars_app level = function
\r
73 | A(t1,t2) -> (string_of_term_no_pars_app level t1) ^ " " ^ (string_of_term_w_pars level t2)
\r
74 | Stuck(v,n) -> ":" ^ string_of_term_no_pars_app level (V v) ^ " " ^ (string_of_term_w_pars level (get_conv p n))
\r
75 (* | Ptr n -> string_of_term_no_pars_app level (get_conv p n) *)
\r
76 (* | Ptr n -> "&" ^ string_of_int n *)
\r
77 | _ as t -> string_of_term_w_pars level t
\r
78 and string_of_term_no_pars_lam level = function
\r
79 | L t -> "λ" ^ string_of_term_w_pars (level+1) (V 0) ^ ". " ^ (string_of_term_no_pars_lam (level+1) t)
\r
80 | _ as t -> string_of_term_no_pars level t
\r
81 and string_of_term_no_pars level = function
\r
82 | L _ as t -> string_of_term_no_pars_lam level t
\r
83 | _ as t -> string_of_term_no_pars_app level t
\r
84 in string_of_term_no_pars 0
\r
87 let string_of_problem p =
\r
89 "[arities] " ^ String.concat " " (List.map (fun (v,n) -> "`" ^ string_of_int v ^ "=" ^ string_of_int n) p.arities);
\r
90 "[stepped]" ^ String.concat " " (List.map string_of_int p.stepped);
\r
91 "[DV] " ^ (string_of_t p p.div);
\r
92 "[CV] " ^ String.concat "\n " (List.map (string_of_t p) p.conv);
\r
94 ] @ Util.concat_map (fun (v, lst) -> ("[<>] of "^(string_of_t p (V v))) :: List.map (fun (n,c) -> " " ^ string_of_t p (get_conv p n)
\r
95 ^ (match c with None -> "" | Some v -> " -> " ^ string_of_t p (V v))
\r
96 ) lst) p.matches @ [""] in
\r
97 String.concat "\n" lines
\r
100 let problem_fail p reason =
\r
101 print_endline "!!!!!!!!!!!!!!! FAIL !!!!!!!!!!!!!!!";
\r
102 print_endline (string_of_problem p);
\r
103 raise (Fail (-1, reason))
\r
106 let freshvar ({freshno} as p) =
\r
107 {p with freshno=freshno+1}, freshno+1
\r
110 let add_to_match p id t =
\r
113 p, index_of_conv t p.conv
\r
115 | Not_found -> append_conv p t in
\r
116 let entry' = entry, None in
\r
118 List.map (fun (id',lst as x) -> if id <> id' then x else (id, entry'::lst)) p.matches
\r
120 {p with matches}, entry
\r
123 let var_occurs_in p v =
\r
124 let rec aux level = function
\r
125 | V v' -> v + level = v'
\r
126 | Stuck(v',n) -> assert (v <> v'); aux level (get_conv p n)
\r
127 | A(t1,t2) -> (aux level t1) || (aux level t2)
\r
128 | L t -> aux (level+1) t
\r
131 (* | Ptr n -> aux level (get_conv p n) *)
\r
136 let rec is_inert p =
\r
138 | A(t,_) -> is_inert p t
\r
139 (* | Ptr n -> is_inert p (get_conv p n) *)
\r
140 | V _ | Stuck _ -> true
\r
141 | L _ | B | P -> false
\r
144 let is_var = function V _ -> true | _ -> false;;
\r
145 let is_lambda = function L _ -> true | _ -> false;;
\r
146 let is_pacman = function P -> true | _ -> false;;
\r
148 let rec subst level delift sub p =
\r
150 | V v -> p, if v = level + fst sub then lift level (snd sub) else V (if delift && v > level then v-1 else v)
\r
151 | L t -> let p, t = subst (level + 1) delift sub p t in p, L t
\r
153 let p, t1 = subst level delift sub p t1 in
\r
154 let p, t2 = subst level delift sub p t2 in
\r
155 if t1 = B || t2 = B then p, B else
\r
156 if level = 0 then mk_app p t1 t2 else p, A (t1, t2)
\r
159 (* | Ptr _ as t -> p, t *)
\r
161 assert (v <> level + fst sub); (* can't instantiate v twice after a step *)
\r
162 (* FIXME!!!! URGENT!!! *)
\r
164 and mk_app p t1 t2 = let t1 = if t1 = P then L P else t1 in match t1 with
\r
165 | L t1 -> subst 0 true (0, t2) p t1
\r
166 | V v when List.mem v p.stepped ->
\r
167 let p, n = add_to_match p v t2 in
\r
169 | B | _ when t2 = B -> p, B
\r
170 | t1 -> p, A (t1, t2)
\r
174 | t'::ts -> let p, t = mk_app p t t' in mk_apps p t ts
\r
178 | V m -> V (if m >= n' then m + n else m)
\r
179 | L t -> L (aux (n'+1) t)
\r
180 | A (t1, t2) -> A (aux n' t1, aux n' t2)
\r
183 | Stuck(m,ptr) -> assert (m >= n'); Stuck(m + n, ptr)
\r
184 (* | Ptr _ as t -> t *)
\r
188 let subst = subst 0 false;;
\r
190 let mk_lambda t = L (lift 1 t) ;;
\r
192 let subst_many sub =
\r
193 let rec aux p = function
\r
196 let p, tms = aux p tms in
\r
197 let p, t = subst sub p t in
\r
202 let subst_in_problem (sub: var * t) (p: problem) =
\r
203 (* print_endline ("SUBST IN PROBLEM: " ^ string_of_t p (V (fst sub)) ^ " |-> " ^ string_of_t p (snd sub)); *)
\r
204 (* BUG QUI FIXME!!!! *)
\r
205 let rec mix l1 l2 = match l1, l2 with
\r
207 | x::xs, _::ys -> x:: (mix xs ys)
\r
208 | _ -> assert false in
\r
209 let p, conv = subst_many sub p p.conv in
\r
210 let p, div = subst sub p p.div in
\r
211 let conv = List.rev (mix (List.rev conv) (List.rev p.conv)) in
\r
212 let p = {p with div; conv} in
\r
213 (* print_endline ("after sub: \n" ^ string_of_problem p); *)
\r
214 {p with sigma=sub::p.sigma}
\r
217 let problem_done p =
\r
218 let all_separated = List.for_all (fun (_, lst) -> List.for_all (fun (n,_) -> is_var (get_conv p n)) lst) p.matches in
\r
219 all_separated && p.div = B
\r
222 let free_vars p t =
\r
223 let rec aux level = function
\r
224 | V v -> if v >= level then [v] else []
\r
225 | A(t1,t2) -> (aux level t1) @ (aux level t2)
\r
226 | L t -> aux (level+1) t
\r
229 (* | Ptr n -> aux 0 (get_conv p n) *)
\r
230 in Util.sort_uniq (aux 0 t)
\r
233 let visible_vars p t =
\r
234 let rec aux = function
\r
236 | A(t1,t2) -> (aux t1) @ (aux t2)
\r
238 | Stuck _ | L _ -> []
\r
239 (* | Ptr n -> aux (get_conv p n) *)
\r
240 in Util.sort_uniq (aux t)
\r
244 let apply_substs p t = t;;
\r
246 let unblock var index cont p =
\r
247 let rec aux p = function
\r
248 | Stuck(v',n') as t -> p, (if var = v' && index = n' then apply_substs p (V cont) else t)
\r
250 let p, t1 = aux p t1 in
\r
251 let p, t2 = aux p t2 in
\r
253 | _ as t -> p, t in
\r
254 let p, div = aux p p.div in
\r
255 let _, conv = List.fold_right (fun c (p, conv) -> let p, c = aux p c in p, c::conv) p.conv (p,[]) in
\r
259 let rec unblock_all p =
\r
260 let aux (orig, m) (matches, news, p) =
\r
261 let nn = List.filter (fun (n,c) -> is_var (get_conv p n) && c = None) m in
\r
262 let p, conts = List.fold_left (fun (p,conts) (n,_) ->
\r
263 match Util.find_opt (function (n', c) when eq_conv_indices p n' n -> c | _ -> None) m
\r
264 with Some c -> p, (n, c)::conts | None ->
\r
265 (* c is the new continuation *)
\r
266 let p, c = freshvar p in
\r
267 let arity = c, List.assoc orig p.arities - 1 in
\r
268 print_endline ("``" ^ string_of_int orig);
\r
269 assert ((snd arity) > -1 );
\r
270 let p = {p with arities=arity::p.arities} in
\r
273 let m = List.map (fun (n,c) -> n, try
\r
274 Some (List.assoc n conts)
\r
276 | Not_found -> c) m in
\r
277 (orig, m) :: matches, (List.map (fun x -> orig, x) conts) @ news, p
\r
279 let matches, news, p = List.fold_right aux p.matches ([],[], p) in
\r
282 let f = List.fold_left (fun f (a,(b,c)) -> f ++ (unblock a b c)) (fun p -> p) news in
\r
283 unblock_all (f {p with matches}) else p
\r
286 let rec simple_explode p =
\r
289 let subst = var, B in
\r
290 sanity (subst_in_problem subst p)
\r
294 (* Sanity checks: *)
\r
295 if (function | P | L _ -> true | _ -> false) p.div then problem_fail p "p.div converged";
\r
296 if List.mem B p.conv then problem_fail p "p.conv diverged";
\r
297 if not (List.for_all (fun (_, lst) -> List.for_all (fun (n,_) -> is_inert p (get_conv p n)) lst) p.matches)
\r
298 then problem_fail p "Unsolvable discrimination";
\r
300 let p = unblock_all p in
\r
301 print_endline (string_of_problem p); (* non cancellare *)
\r
302 let p = if problem_done p then raise (Done p.sigma) else p in
\r
303 let p = if is_var p.div then simple_explode p else p in
\r
307 let print_cmd s1 s2 = print_endline (">> " ^ s1 ^ " " ^ s2);;
\r
309 let rec hd_args t = match t with
\r
311 | A(t1,t2) -> let a, b = hd_args t1 in a, b @ [t2]
\r
315 let max_arity_of_var v =
\r
316 let rec aux level =
\r
319 | A _ as t -> print_string (string_of_t dummy_p t); let hd, args = hd_args t in
\r
320 let acc = if hd = level + v then List.length args else 0 in
\r
321 List.fold_right (max ++ (aux level)) args acc
\r
322 | L t -> aux (level + 1) t
\r
324 (* | Ptr n -> assert false *)
\r
329 let ignore var n p =
\r
330 print_cmd "EAT" ("on " ^ string_of_t p (V var) ^ " (of:" ^ string_of_int n ^ ")");
\r
334 else L (aux (m-1) t) in
\r
335 let p, fresh = freshvar p in
\r
336 let subst = var, aux n (V fresh) in
\r
337 sanity (subst_in_problem subst p)
\r
343 print_cmd "EAT" ("var " ^ string_of_t p (V var));
\r
344 let rec is_hd v' = function
\r
345 | A (t,_) -> is_hd v' t
\r
348 let rec app_length = function
\r
349 | A (t,_) -> 1 + app_length t
\r
351 let rec find_app_no = function
\r
352 | V _ | L _ | P | B -> 0
\r
353 | A (t1,t2) as t ->
\r
354 max (max (find_app_no t1) (find_app_no t2))
\r
355 (if is_hd var t1 then app_length t else 0)
\r
357 (* | Ptr n -> find_app_no (get_conv p n) *)
\r
358 in let n = List.fold_right (max ++ find_app_no) (all_terms p) 0 in
\r
362 else L (aux (m-1) t) in
\r
363 let p, fresh = freshvar p in
\r
364 let subst = var, aux n (V fresh) in
\r
365 sanity (subst_in_problem subst p)
\r
369 let fv1 = visible_vars p p.div in
\r
370 let fv2 = List.concat (List.map (visible_vars p) p.conv) in
\r
371 let fv = List.filter (fun x -> not (List.mem x fv2)) fv1 in
\r
372 let fv = List.filter ((<) p.orig_freshno) fv in
\r
375 print_cmd "EXPLODE" ("on " ^ string_of_t p (V var));
\r
376 let subst = var, B in
\r
377 sanity (subst_in_problem subst p)
\r
378 | _ -> raise (Fail (-1,"premature explosion"))
\r
382 print_cmd "STEP" ("on " ^ string_of_t p (V var));
383 let matches = (var,[])::p.matches in
384 let p = {p with matches;stepped=var::p.stepped} in
385 let subst = var, V var in
386 sanity (subst_in_problem subst p)
\r
390 print_cmd "CHOOSE" ("#" ^ string_of_int n);
\r
391 let rec aux n t = match t with
\r
393 | A(t1,_) -> let n', t' = aux n t1 in if n = n' then n', t' else n'+1, t
\r
394 | _ -> assert false
\r
395 in let n', div = aux n p.div in
\r
396 if n' <> n then problem_fail p "wrong choose";
\r
397 let p = {p with div} in
\r
401 let apply var appk p =
\r
403 (string_of_t p (V var) ^ " applies no." ^ string_of_int appk ^ " fresh variables");
\r
404 let rec mk_freshvars n p =
\r
408 let p, vs = mk_freshvars (n-1) p in
\r
409 let p, v = freshvar p in
\r
411 let p, vars = mk_freshvars appk p in
\r
412 let p, t = mk_apps p (V 0) (List.map (lift 1) vars) in
\r
413 let t = L (A (lift 1 (V var), t)) in
\r
414 let subst = var, t in
\r
415 sanity (subst_in_problem subst p)
\r
418 let find_arities_after_app p =
\r
419 let rec aux level n = function
\r
420 | L t -> assert (n > 0); max_arity_of_var level t :: aux (level+1) (n-1) t
\r
421 | _ -> Array.to_list (Array.make n 0)
\r
424 let find_all_first_args_of v =
\r
425 let rec aux level = function
\r
426 | L t -> aux (level+1) t
\r
428 | A(V v', t2) -> (if v + level = v' then [t2] else []) @ aux level t2
\r
429 | A(t1,t2) -> aux level t1 @ aux level t2
\r
435 let appk = p.k_lam + p.k_app + 1 in
\r
436 print_cmd "STEP'" ("on " ^ string_of_t p (V var) ^ " and applies no." ^ string_of_int appk ^ " fresh variables");
\r
437 let p, vars = (* +1 below because of lifting *)
\r
438 Array.fold_left (fun (p,vars) _ -> let p, v = freshvar p in p, (v+1)::vars)
\r
439 (p, []) (Array.make appk ()) in
\r
440 let p, t = mk_apps p (V 0) (List.map (fun x -> V x) vars) in
\r
442 let first_args = Util.sort_uniq (List.fold_right ((@) ++ (find_all_first_args_of var)) (all_terms p) []) in
\r
443 let map = List.fold_left (fun acc t -> let acc' = find_arities_after_app p appk t in List.map (fun (x,y) -> max x y) (List.combine acc acc')) (Array.to_list (Array.make appk 0)) first_args in
\r
444 let arities = List.combine (List.map ((+) (-1)) vars) map in
\r
446 (* let p, var' = freshvar p in *)
\r
447 let p, var' = p, var in
\r
448 let matches = (var', []) :: p.matches in
\r
449 let p = {p with matches; stepped=var'::p.stepped; arities=arities@p.arities} in
\r
450 let t = L (A (lift 1 (V var'), t)) in
\r
451 let subst = var, t in
\r
452 sanity (subst_in_problem subst p)
\r
456 if n = 1 then p else (
\r
457 print_cmd "PERM" ("on " ^ string_of_t p (V var) ^ " (of:" ^ string_of_int n ^ ")");
\r
458 (* let p, v = freshvar p in *)
\r
459 let p, v = p, var in
\r
460 let rec aux' m t = if m < 0 then t else A(aux' (m-1) t, V m) in
\r
464 else L (aux (m-1) t) in
\r
465 let t = aux n (lift n (V v)) in
\r
466 let subst = var, t in
\r
467 (* let p = {p with arities=(v, List.assoc var p.arities)::p.arities} in *)
\r
468 sanity (subst_in_problem subst p)
\r
471 let free_vars_of_p p =
\r
472 Util.sort_uniq (Util.concat_map (free_vars p) (all_terms p));;
\r
474 let rec applied_vars p = function
\r
476 | L _ -> [] (* ??? *)
\r
478 | A(V v,t2) -> v :: applied_vars p t2
\r
479 | A(t1,t2) -> applied_vars p t1 @ applied_vars p t2
\r
480 (* | Ptr n -> applied_vars p (get_conv p n) *)
\r
481 | Stuck _ -> [] (* ??? *)
\r
484 let applied_vars_of_p p =
\r
485 Util.sort_uniq (Util.concat_map (applied_vars p) (all_terms p));;
\r
492 | Done _ as d -> raise d
\r
493 | Fail(_, s) -> print_endline ("<<< Backtracking because: " ^ s) in
\r
494 print_endline ">>> auto called";
\r
495 (* Compute useful free variables *)
\r
496 let fv = applied_vars_of_p p in
\r
497 let fv = List.filter (fun v -> not (List.mem v p.stepped)) fv in
\r
498 List.iter (fun v -> print_string ("@`" ^ string_of_int v)) fv;
\r
499 let fv0 = List.filter (fun v -> List.assoc v p.arities > 0) fv in (* remove variable with arity left 0, cannot step there *)
\r
500 if fv0 = [] then (print_endline "warning! empty step fv0"; List.iter (fun v -> print_string ("@`" ^ string_of_int v)) fv);
\r
501 let permute_and_step p v =
\r
502 let step'' problem prm var =
\r
503 let problem = perm var prm problem in
\r
504 (* let _ = read_line () in *)
\r
505 let problem = step' var problem in
\r
507 let arity = List.assoc v p.arities in
\r
508 let _, perms = Array.fold_left (fun (arity, acc) () -> let a = arity + 1 in a, a::acc) (1,[1]) (Array.make (arity-1) ()) in
\r
509 List.iter (fun perm -> aux (step'' p perm) v) perms
\r
511 List.iter (permute_and_step p) fv0;
\r
512 List.iter (aux (fun v -> eat v p)) fv;
\r
513 (* mancano: applicazioni e choose; ??? *)
\r
517 let rec aux level = function
\r
518 | Parser.Lam t -> L (aux (level + 1) t)
\r
519 | Parser.App (t1, t2) ->
\r
520 if level = 0 then snd (mk_app dummy_p (aux level t1) (aux level t2))
\r
521 else A(aux level t1, aux level t2)
\r
522 | Parser.Var v -> V v
\r
523 in let (tms, free) = Parser.parse_many strs
\r
524 in (List.map (aux 0) tms, free)
\r
527 let magic6 div conv cmds =
\r
529 let all_tms, var_names = parse (div :: conv) in
\r
530 let div, conv = List.hd all_tms, List.tl all_tms in
\r
531 let varno = List.length var_names in
\r
532 let k_app, k_lam = List.fold_left (fun (a, b) t -> let a', b' = consts t in max a a', max b b') (0,0) all_tms in
\r
533 let p = {orig_freshno=varno; freshno=1+varno; div; conv; matches=[]; sigma=[]; stepped=[];k_app;k_lam;arities=[]} in
\r
534 let fv = Util.sort_uniq (Util.concat_map (free_vars p) all_tms) in
\r
535 let arities = List.map (fun var -> var, k_app) fv in
\r
536 let p = {p with arities} in
\r
538 let subst = Util.index_of "BOMB" var_names, L B in
\r
539 let p = subst_in_problem subst p in p
\r
540 with Not_found -> p in
\r
541 let p = sanity p in
\r
543 problem_fail (List.fold_left (|>) p cmds) "Problem not completed"
\r
548 let auto div conv =
\r
550 let all_tms, var_names = parse (div :: conv) in
\r
551 let div, conv = List.hd all_tms, List.tl all_tms in
\r
552 let varno = List.length var_names in
\r
553 let k_app, k_lam = List.fold_left (fun (a, b) t -> let a', b' = consts t in max a a', max b b') (0,0) all_tms in
\r
554 let p = {orig_freshno=varno; freshno=1+varno; div; conv; matches=[]; sigma=[]; stepped=[];k_app;k_lam;arities=[]} in
\r
555 let fv = Util.sort_uniq (Util.concat_map (free_vars p) all_tms) in
\r
556 let max_arity_of_var_in_p var p =
\r
557 1 + List.fold_right (max ++ (max_arity_of_var var)) (all_terms p) 0 in
\r
558 let arities = List.map (fun var -> var, max_arity_of_var_in_p var p) fv in
\r
559 let p = {p with arities} in
\r
561 let subst = Util.index_of "BOMB" var_names, L B in
\r
562 let p = subst_in_problem subst p in p
\r
563 with Not_found -> p in
\r
564 let p = sanity p in
\r
567 failwith "auto failed."
\r
569 | Done _ -> print_endline "<<< auto ok >>>"; (* TODO: print and verify substitution *)
\r
572 (* let interactive div conv cmds =
\r
574 let all_tms, var_names = parse (div @ conv) in
\r
575 let div, conv = list_split (List.length div) all_tms in
\r
576 let varno = List.length var_names in
\r
577 let p = {orig_freshno=varno; freshno=1+varno; div; conv; matches=[]; sigma=[]} in
\r
578 (* activate bombs *)
\r
580 let subst = Util.index_of "BOMB" var_names, L B in
\r
581 subst_in_problem subst p
\r
582 with Not_found -> p in
\r
583 (* activate pacmans *)
\r
585 let subst = Util.index_of "PACMAN" var_names, P in
\r
586 let p = subst_in_problem subst p in
\r
587 (print_endline ("after subst in problem " ^ string_of_problem p); p)
\r
588 with Not_found -> p in
\r
589 (* initial sanity check *)
\r
590 let p = sanity p in
\r
591 let p = List.fold_left (|>) p cmds in
\r
593 let nth spl n = int_of_string (List.nth spl n) in
\r
595 let s = read_line () in
\r
596 let spl = Str.split (Str.regexp " +") s in
\r
597 s, let uno = List.hd spl in
\r
598 try if uno = "explode" then explode
\r
599 else if uno = "ignore" then ignore (nth spl 1) (nth spl 2)
\r
600 else if uno = "step" then step (nth spl 1)
\r
601 else if uno = "perm" then perm (nth spl 1) (nth spl 2)
\r
602 else if uno = "apply" then apply (nth spl 1) (nth spl 2)
\r
603 (* else if uno = "forget" then forget (nth spl 1) (nth spl 2) *)
\r
604 else if uno = "id" then id (nth spl 1)
\r
605 else failwith "Wrong input."
\r
606 with Failure s -> print_endline s; (fun x -> x) in
\r
607 let str, cmd = read_cmd () in
\r
608 let cmds = (" " ^ str ^ ";")::cmds in
\r
610 let p = cmd p in f p cmds
\r
612 | Done -> print_endline "Done! Commands history: "; List.iter print_endline (List.rev cmds)
\r
626 (* [ perm 1 3; step' 8 ; eat 4; eat 5; eat 15; ] *)
\r
632 [ "x y BOMB d"; "x BOMB a2 c" ]
\r
633 (* [ perm 1 3 ; step' 10 ; eat 4; eat 6; step' 17; eat 3; eat 7; eat 27; ] *)
\r
639 [ "x x" ; "x x x" ]
\r
642 eat 6; eat 9; eat 13;
\r
649 [ "x (_._. BOMB)" ]
\r
650 (* [ apply 1 2; ] *)
\r
657 (* [ apply 1 1; ignore 1 1; explode; ] *)
\r
662 "y (x a1 BOMB c) (x BOMB b1 d)"
\r
663 [ "y (x a2 BOMB c) (x BOMB b1 d)";
\r
664 "y (x a1 BOMB c) (x BOMB b2 d)";]
\r
683 [ "z (y (x.x))"; "y (_. BOMB)" ]
\r
684 [ apply 2 1; step 3; explode; ]
\r
689 [ "y (x.x)"; "x (_. BOMB)" ]
\r
690 [ apply 1 1; ignore 2 1; step 1; explode; ]
\r
695 [ "z (y (x.x))"; "y (_. BOMB)" ]
\r
696 [ step 1; explode; apply 2 1; id 2; ignore 3 1; ]
\r
701 [ "y (x b)"; "x BOMB" ] [
\r
708 ["y (x a)"] [ "y (x b)"; "x BOMB"; "y a" ]
\r
717 [ "y (b c)"; "y (x a)"; "y (x b)"; "x BOMB" ] *)
\r
720 ["x a (x (a.y BOMB))"]
\r
721 [ "x b"; "x (y c)"; "x (y d)" ]
\r
729 (* ma si puo' fare anche senza forget *) *)
\r
733 (* dipendente dalla codifica? no, ma si risolve solo con id *)
\r
735 ["y a"] ["y b"; "x (y (_.BOMB))"]
\r
741 (* [id 1; explode];; *)
\r
744 ["PACMAN (x x x)"] ["PACMAN (x x)"]
\r
751 print_endline "ALL DONE. "
\r