From: acondolu Date: Thu, 31 May 2018 12:42:55 +0000 (+0200) Subject: Moved andrea.ml to simple.ml X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=commitdiff_plain;h=3d8ab5897c6aa3d9c1b317e1137b3fcd2668f25e;p=fireball-separation.git Moved andrea.ml to simple.ml --- diff --git a/ocaml/Makefile b/ocaml/Makefile index 5859d51..d5c830b 100644 --- a/ocaml/Makefile +++ b/ocaml/Makefile @@ -2,7 +2,7 @@ OCAMLC = ocamlopt -g -rectypes LIB = unix.cmxa str.cmxa UTILS = util.cmx console.cmx listx.cmx pure.cmx num.cmx parser.cmx parser_andrea.cmx -all: a.out test4.out andrea.out +all: a.out test4.out simple.out run: test4.out bash run @@ -13,8 +13,8 @@ a.out: $(UTILS) lambda4.cmx problems.cmx test4.out: $(UTILS) lambda4.cmx test.ml $(OCAMLC) -o test4.out $(LIB) $^ -andrea.out: $(UTILS) andrea.ml - $(OCAMLC) -o andrea.out $(LIB) $(UTILS) andrea.ml +simple.out: $(UTILS) simple.ml + $(OCAMLC) -o simple.out $(LIB) $(UTILS) simple.ml %.cmi: %.mli $(OCAMLC) -c $< diff --git a/ocaml/andrea.ml b/ocaml/andrea.ml deleted file mode 100644 index 8b47f88..0000000 --- a/ocaml/andrea.ml +++ /dev/null @@ -1,391 +0,0 @@ -let (++) f g x = f (g x);; -let id x = x;; -let rec fold_nat f x n = if n = 0 then x else f (fold_nat f x (n-1)) n ;; - -let print_hline = Console.print_hline;; - -open Pure - -type var = int;; -type t = - | V of var - | A of t * t - | L of t - | B (* bottom *) - | C of int -;; - -let delta = L(A(V 0, V 0));; - -let eta_eq = - let rec aux l1 l2 t1 t2 = match t1, t2 with - | L t1, L t2 -> aux l1 l2 t1 t2 - | L t1, t2 -> aux l1 (l2+1) t1 t2 - | t1, L t2 -> aux (l1+1) l2 t1 t2 - | V a, V b -> a + l1 = b + l2 - | C a, C b -> a = b - | A(t1,t2), A(u1,u2) -> aux l1 l2 t1 u1 && aux l1 l2 t2 u2 - | _, _ -> false - in aux 0 0 -;; - -(* does NOT lift t *) -let mk_lams = fold_nat (fun x _ -> L x) ;; - -let string_of_t = - let string_of_bvar = - let bound_vars = ["x"; "y"; "z"; "w"; "q"] in - let bvarsno = List.length bound_vars in - fun nn -> if nn < bvarsno then List.nth bound_vars nn else "x" ^ (string_of_int (nn - bvarsno + 1)) in - let rec string_of_term_w_pars level = function - | V v -> if v >= level then "`" ^ string_of_int (v-level) else - string_of_bvar (level - v-1) - | C n -> "c" ^ string_of_int n - | A _ - | L _ as t -> "(" ^ string_of_term_no_pars level t ^ ")" - | B -> "BOT" - and string_of_term_no_pars_app level = function - | A(t1,t2) -> string_of_term_no_pars_app level t1 ^ " " ^ string_of_term_w_pars level t2 - | _ as t -> string_of_term_w_pars level t - and string_of_term_no_pars level = function - | L t -> "λ" ^ string_of_bvar level ^ ". " ^ string_of_term_no_pars (level+1) t - | _ as t -> string_of_term_no_pars_app level t - in string_of_term_no_pars 0 -;; - -type problem = { - orig_freshno: int - ; freshno : int - ; div : t - ; conv : t - ; sigma : (var * t) list (* substitutions *) - ; stepped : var list - ; phase : [`One | `Two] (* :'( *) -} - -let string_of_problem p = - let lines = [ - "[stepped] " ^ String.concat " " (List.map string_of_int p.stepped); - "[DV] " ^ string_of_t p.div; - "[CV] " ^ string_of_t p.conv; - ] in - String.concat "\n" lines -;; - -exception Done of (var * t) list (* substitution *);; -exception Fail of int * string;; - -let problem_fail p reason = - print_endline "!!!!!!!!!!!!!!! FAIL !!!!!!!!!!!!!!!"; - print_endline (string_of_problem p); - raise (Fail (-1, reason)) -;; - -let freshvar ({freshno} as p) = - {p with freshno=freshno+1}, freshno+1 -;; - -let rec is_inert = - function - | A(t,_) -> is_inert t - | V _ -> true - | C _ - | L _ | B -> false -;; - -let is_var = function V _ -> true | _ -> false;; -let is_lambda = function L _ -> true | _ -> false;; - -let rec no_leading_lambdas = function - | L t -> 1 + no_leading_lambdas t - | _ -> 0 -;; - -let rec get_inert = function - | V n -> (n,0) - | A(t, _) -> let hd,args = get_inert t in hd,args+1 - | _ -> assert false -;; - -let rec subst level delift sub = - function - | V v -> if v = level + fst sub then lift level (snd sub) else V (if delift && v > level then v-1 else v) - | L t -> let t = subst (level + 1) delift sub t in if t = B then B else L t - | A (t1,t2) -> - let t1 = subst level delift sub t1 in - let t2 = subst level delift sub t2 in - mk_app t1 t2 - | C _ as t -> t - | B -> B -and mk_app t1 t2 = if t2 = B || (t1 = delta && t2 = delta) then B - else match t1 with - | C _ as t -> t - | B -> B - | L t1 -> subst 0 true (0, t2) t1 - | _ -> A (t1, t2) -and lift n = - let rec aux lev = - function - | V m -> V (if m >= lev then m + n else m) - | L t -> L (aux (lev+1) t) - | A (t1, t2) -> A (aux lev t1, aux lev t2) - | C _ as t -> t - | B -> B - in aux 0 -;; -let subst = subst 0 false;; - -let subst_in_problem (sub: var * t) (p: problem) = -print_endline ("-- SUBST " ^ string_of_t (V (fst sub)) ^ " |-> " ^ string_of_t (snd sub)); - {p with - div=subst sub p.div; - conv=subst sub p.conv; - stepped=(fst sub)::p.stepped; - sigma=sub::p.sigma} -;; - -let get_subterm_with_head_and_args hd_var n_args = - let rec aux lev = function - | C _ - | V _ | B -> None - | L t -> aux (lev+1) t - | A(t1,t2) as t -> - let hd_var', n_args' = get_inert t1 in - if hd_var' = hd_var + lev && n_args <= 1 + n_args' - then Some (lift ~-lev t) - else match aux lev t2 with - | None -> aux lev t1 - | Some _ as res -> res - in aux 0 -;; - -let rec purify = function - | L t -> Pure.L (purify t) - | A (t1,t2) -> Pure.A (purify t1, purify t2) - | V n -> Pure.V n - | C _ -> Pure.V max_int (* FIXME *) - | B -> Pure.B -;; - -let check p sigma = - print_endline "Checking..."; - let div = purify p.div in - let conv = purify p.conv in - let sigma = List.map (fun (v,t) -> v, purify t) sigma in - let freshno = List.fold_right (fun (x,_) -> max x) sigma 0 in - let env = Pure.env_of_sigma freshno sigma in - assert (Pure.diverged (Pure.mwhd (env,div,[]))); - assert (not (Pure.diverged (Pure.mwhd (env,conv,[])))); - () -;; - -let sanity p = - print_endline (string_of_problem p); (* non cancellare *) - if p.conv = B then problem_fail p "p.conv diverged"; - if p.div = B then raise (Done p.sigma); - if p.phase = `Two && p.div = delta then raise (Done p.sigma); - if not (is_inert p.div) then problem_fail p "p.div converged" -;; - -(* drops the arguments of t after the n-th *) -let inert_cut_at n t = - let rec aux t = - match t with - | V _ as t -> 0, t - | A(t1,_) as t -> - let k', t' = aux t1 in - if k' = n then n, t' - else k'+1, t - | _ -> assert false - in snd (aux t) -;; - -let find_eta_difference p t n_args = - let t = inert_cut_at n_args t in - let rec aux t u k = match t, u with - | V _, V _ -> assert false (* div subterm of conv *) - | A(t1,t2), A(u1,u2) -> - if not (eta_eq t2 u2) then (print_endline((string_of_t t2) ^ " <> " ^ (string_of_t u2)); k) - else aux t1 u1 (k-1) - | _, _ -> assert false - in aux p.div t n_args -;; - -let compute_max_lambdas_at hd_var j = - let rec aux hd = function - | A(t1,t2) -> - (if get_inert t1 = (hd, j) - then max ( (*FIXME*) - if is_inert t2 && let hd', j' = get_inert t2 in hd' = hd - then let hd', j' = get_inert t2 in j - j' - else no_leading_lambdas t2) - else id) (max (aux hd t1) (aux hd t2)) - | L t -> aux (hd+1) t - | V _ -> 0 - | _ -> assert false - in aux hd_var -;; - -let print_cmd s1 s2 = print_endline (">> " ^ s1 ^ " " ^ s2);; - -(* eat the arguments of the divergent and explode. - It does NOT perform any check, may fail if done unsafely *) -let eat p = -print_cmd "EAT" ""; - let var, k = get_inert p.div in - let phase = p.phase in - let p, t = - match phase with - | `One -> - let n = 1 + max - (compute_max_lambdas_at var k p.div) - (compute_max_lambdas_at var k p.conv) in - (* apply fresh vars *) - let p, t = fold_nat (fun (p, t) _ -> - let p, v = freshvar p in - p, A(t, V (v + k)) - ) (p, V 0) n in - let p = {p with phase=`Two} in p, A(t, delta) - | `Two -> p, delta in - let subst = var, mk_lams t k in - let p = subst_in_problem subst p in - let p = if phase = `One then {p with div = (match p.div with A(t,_) -> t | _ -> assert false)} else p in - sanity p; p -;; - -(* step on the head of div, on the k-th argument, with n fresh vars *) -let step k n p = - let var, _ = get_inert p.div in -print_cmd "STEP" ("on " ^ string_of_t (V var) ^ " (of:" ^ string_of_int n ^ ")"); - let p, t = (* apply fresh vars *) - fold_nat (fun (p, t) _ -> - let p, v = freshvar p in - p, A(t, V (v + k + 1)) - ) (p, V 0) n in - let t = (* apply unused bound variables V_{k-1}..V_1 *) - fold_nat (fun t m -> A(t, V (k-m+1))) t k in - let t = mk_lams t (k+1) in (* make leading lambdas *) - let subst = var, t in - let p = subst_in_problem subst p in - sanity p; p -;; - -let parse strs = - let rec aux level = function - | Parser_andrea.Lam t -> L (aux (level + 1) t) - | Parser_andrea.App (t1, t2) -> - if level = 0 then mk_app (aux level t1) (aux level t2) - else A(aux level t1, aux level t2) - | Parser_andrea.Var v -> V v in - let (tms, free) = Parser_andrea.parse_many strs in - (List.map (aux 0) tms, free) -;; - -let problem_of div conv = - print_hline (); - let [@warning "-8"] [div; conv], var_names = parse ([div; conv]) in - let varno = List.length var_names in - let p = {orig_freshno=varno; freshno=1+varno; div; conv; sigma=[]; stepped=[]; phase=`One} in - (* initial sanity check *) - sanity p; p -;; - -let exec div conv cmds = - let p = problem_of div conv in - try - problem_fail (List.fold_left (|>) p cmds) "Problem not completed" - with - | Done _ -> () -;; - -let rec auto p = - let hd_var, n_args = get_inert p.div in - match get_subterm_with_head_and_args hd_var n_args p.conv with - | None -> - (try - let phase = p.phase in - let p = eat p in - if phase = `Two - then problem_fail p "Auto.2 did not complete the problem" - else auto p - with Done sigma -> sigma) - | Some t -> - let j = find_eta_difference p t n_args - 1 in - let k = 1 + max - (compute_max_lambdas_at hd_var j p.div) - (compute_max_lambdas_at hd_var j p.conv) in - let p = step j k p in - auto p -;; - -let interactive div conv cmds = - let p = problem_of div conv in - try ( - let p = List.fold_left (|>) p cmds in - let rec f p cmds = - let nth spl n = int_of_string (List.nth spl n) in - let read_cmd () = - let s = read_line () in - let spl = Str.split (Str.regexp " +") s in - s, let uno = List.hd spl in - try if uno = "eat" then eat - else if uno = "step" then step (nth spl 1) (nth spl 2) - else failwith "Wrong input." - with Failure s -> print_endline s; (fun x -> x) in - let str, cmd = read_cmd () in - let cmds = (" " ^ str ^ ";")::cmds in - try - let p = cmd p in f p cmds - with - | Done _ -> print_endline "Done! Commands history: "; List.iter print_endline (List.rev cmds) - in f p [] - ) with Done _ -> () -;; - -let rec conv_join = function - | [] -> "@" - | x::xs -> conv_join xs ^ " ("^ x ^")" -;; - -let auto' a b = - let p = problem_of a (conv_join b) in - let sigma = auto p in - check p sigma -;; - -(* Example usage of exec, interactive: - -exec - "x x" - (conv_join["x y"; "y y"; "y x"]) - [ step 0 1; eat ] -;; - -interactive "x y" - "@ (x x) (y x) (y z)" [step 0 1; step 0 2; eat] -;; - -*) - -auto' "x x" ["x y"; "y y"; "y x"] ;; -auto' "x y" ["x (_. x)"; "y z"; "y x"] ;; -auto' "a (x. x b) (x. x c)" ["a (x. b b) @"; "a @ c"; "a (x. x x) a"; "a (a a a) (a c c)"] ;; - -auto' "x (y. x y y)" ["x (y. x y x)"] ;; - -auto' "x a a a a" [ - "x b a a a"; - "x a b a a"; - "x a a b a"; - "x a a a b"; -] ;; - -(* Controesempio ad usare un conto dei lambda che non considere le permutazioni *) -auto' "x a a a a (x (x. x x) @ @ (_._.x. x x) x) b b b" [ - "x a a a a (_. a) b b b"; - "x a a a a (_. _. _. _. x. y. x y)"; -] ;; - - -print_hline(); -print_endline "ALL DONE. " diff --git a/ocaml/simple.ml b/ocaml/simple.ml new file mode 100644 index 0000000..8b47f88 --- /dev/null +++ b/ocaml/simple.ml @@ -0,0 +1,391 @@ +let (++) f g x = f (g x);; +let id x = x;; +let rec fold_nat f x n = if n = 0 then x else f (fold_nat f x (n-1)) n ;; + +let print_hline = Console.print_hline;; + +open Pure + +type var = int;; +type t = + | V of var + | A of t * t + | L of t + | B (* bottom *) + | C of int +;; + +let delta = L(A(V 0, V 0));; + +let eta_eq = + let rec aux l1 l2 t1 t2 = match t1, t2 with + | L t1, L t2 -> aux l1 l2 t1 t2 + | L t1, t2 -> aux l1 (l2+1) t1 t2 + | t1, L t2 -> aux (l1+1) l2 t1 t2 + | V a, V b -> a + l1 = b + l2 + | C a, C b -> a = b + | A(t1,t2), A(u1,u2) -> aux l1 l2 t1 u1 && aux l1 l2 t2 u2 + | _, _ -> false + in aux 0 0 +;; + +(* does NOT lift t *) +let mk_lams = fold_nat (fun x _ -> L x) ;; + +let string_of_t = + let string_of_bvar = + let bound_vars = ["x"; "y"; "z"; "w"; "q"] in + let bvarsno = List.length bound_vars in + fun nn -> if nn < bvarsno then List.nth bound_vars nn else "x" ^ (string_of_int (nn - bvarsno + 1)) in + let rec string_of_term_w_pars level = function + | V v -> if v >= level then "`" ^ string_of_int (v-level) else + string_of_bvar (level - v-1) + | C n -> "c" ^ string_of_int n + | A _ + | L _ as t -> "(" ^ string_of_term_no_pars level t ^ ")" + | B -> "BOT" + and string_of_term_no_pars_app level = function + | A(t1,t2) -> string_of_term_no_pars_app level t1 ^ " " ^ string_of_term_w_pars level t2 + | _ as t -> string_of_term_w_pars level t + and string_of_term_no_pars level = function + | L t -> "λ" ^ string_of_bvar level ^ ". " ^ string_of_term_no_pars (level+1) t + | _ as t -> string_of_term_no_pars_app level t + in string_of_term_no_pars 0 +;; + +type problem = { + orig_freshno: int + ; freshno : int + ; div : t + ; conv : t + ; sigma : (var * t) list (* substitutions *) + ; stepped : var list + ; phase : [`One | `Two] (* :'( *) +} + +let string_of_problem p = + let lines = [ + "[stepped] " ^ String.concat " " (List.map string_of_int p.stepped); + "[DV] " ^ string_of_t p.div; + "[CV] " ^ string_of_t p.conv; + ] in + String.concat "\n" lines +;; + +exception Done of (var * t) list (* substitution *);; +exception Fail of int * string;; + +let problem_fail p reason = + print_endline "!!!!!!!!!!!!!!! FAIL !!!!!!!!!!!!!!!"; + print_endline (string_of_problem p); + raise (Fail (-1, reason)) +;; + +let freshvar ({freshno} as p) = + {p with freshno=freshno+1}, freshno+1 +;; + +let rec is_inert = + function + | A(t,_) -> is_inert t + | V _ -> true + | C _ + | L _ | B -> false +;; + +let is_var = function V _ -> true | _ -> false;; +let is_lambda = function L _ -> true | _ -> false;; + +let rec no_leading_lambdas = function + | L t -> 1 + no_leading_lambdas t + | _ -> 0 +;; + +let rec get_inert = function + | V n -> (n,0) + | A(t, _) -> let hd,args = get_inert t in hd,args+1 + | _ -> assert false +;; + +let rec subst level delift sub = + function + | V v -> if v = level + fst sub then lift level (snd sub) else V (if delift && v > level then v-1 else v) + | L t -> let t = subst (level + 1) delift sub t in if t = B then B else L t + | A (t1,t2) -> + let t1 = subst level delift sub t1 in + let t2 = subst level delift sub t2 in + mk_app t1 t2 + | C _ as t -> t + | B -> B +and mk_app t1 t2 = if t2 = B || (t1 = delta && t2 = delta) then B + else match t1 with + | C _ as t -> t + | B -> B + | L t1 -> subst 0 true (0, t2) t1 + | _ -> A (t1, t2) +and lift n = + let rec aux lev = + function + | V m -> V (if m >= lev then m + n else m) + | L t -> L (aux (lev+1) t) + | A (t1, t2) -> A (aux lev t1, aux lev t2) + | C _ as t -> t + | B -> B + in aux 0 +;; +let subst = subst 0 false;; + +let subst_in_problem (sub: var * t) (p: problem) = +print_endline ("-- SUBST " ^ string_of_t (V (fst sub)) ^ " |-> " ^ string_of_t (snd sub)); + {p with + div=subst sub p.div; + conv=subst sub p.conv; + stepped=(fst sub)::p.stepped; + sigma=sub::p.sigma} +;; + +let get_subterm_with_head_and_args hd_var n_args = + let rec aux lev = function + | C _ + | V _ | B -> None + | L t -> aux (lev+1) t + | A(t1,t2) as t -> + let hd_var', n_args' = get_inert t1 in + if hd_var' = hd_var + lev && n_args <= 1 + n_args' + then Some (lift ~-lev t) + else match aux lev t2 with + | None -> aux lev t1 + | Some _ as res -> res + in aux 0 +;; + +let rec purify = function + | L t -> Pure.L (purify t) + | A (t1,t2) -> Pure.A (purify t1, purify t2) + | V n -> Pure.V n + | C _ -> Pure.V max_int (* FIXME *) + | B -> Pure.B +;; + +let check p sigma = + print_endline "Checking..."; + let div = purify p.div in + let conv = purify p.conv in + let sigma = List.map (fun (v,t) -> v, purify t) sigma in + let freshno = List.fold_right (fun (x,_) -> max x) sigma 0 in + let env = Pure.env_of_sigma freshno sigma in + assert (Pure.diverged (Pure.mwhd (env,div,[]))); + assert (not (Pure.diverged (Pure.mwhd (env,conv,[])))); + () +;; + +let sanity p = + print_endline (string_of_problem p); (* non cancellare *) + if p.conv = B then problem_fail p "p.conv diverged"; + if p.div = B then raise (Done p.sigma); + if p.phase = `Two && p.div = delta then raise (Done p.sigma); + if not (is_inert p.div) then problem_fail p "p.div converged" +;; + +(* drops the arguments of t after the n-th *) +let inert_cut_at n t = + let rec aux t = + match t with + | V _ as t -> 0, t + | A(t1,_) as t -> + let k', t' = aux t1 in + if k' = n then n, t' + else k'+1, t + | _ -> assert false + in snd (aux t) +;; + +let find_eta_difference p t n_args = + let t = inert_cut_at n_args t in + let rec aux t u k = match t, u with + | V _, V _ -> assert false (* div subterm of conv *) + | A(t1,t2), A(u1,u2) -> + if not (eta_eq t2 u2) then (print_endline((string_of_t t2) ^ " <> " ^ (string_of_t u2)); k) + else aux t1 u1 (k-1) + | _, _ -> assert false + in aux p.div t n_args +;; + +let compute_max_lambdas_at hd_var j = + let rec aux hd = function + | A(t1,t2) -> + (if get_inert t1 = (hd, j) + then max ( (*FIXME*) + if is_inert t2 && let hd', j' = get_inert t2 in hd' = hd + then let hd', j' = get_inert t2 in j - j' + else no_leading_lambdas t2) + else id) (max (aux hd t1) (aux hd t2)) + | L t -> aux (hd+1) t + | V _ -> 0 + | _ -> assert false + in aux hd_var +;; + +let print_cmd s1 s2 = print_endline (">> " ^ s1 ^ " " ^ s2);; + +(* eat the arguments of the divergent and explode. + It does NOT perform any check, may fail if done unsafely *) +let eat p = +print_cmd "EAT" ""; + let var, k = get_inert p.div in + let phase = p.phase in + let p, t = + match phase with + | `One -> + let n = 1 + max + (compute_max_lambdas_at var k p.div) + (compute_max_lambdas_at var k p.conv) in + (* apply fresh vars *) + let p, t = fold_nat (fun (p, t) _ -> + let p, v = freshvar p in + p, A(t, V (v + k)) + ) (p, V 0) n in + let p = {p with phase=`Two} in p, A(t, delta) + | `Two -> p, delta in + let subst = var, mk_lams t k in + let p = subst_in_problem subst p in + let p = if phase = `One then {p with div = (match p.div with A(t,_) -> t | _ -> assert false)} else p in + sanity p; p +;; + +(* step on the head of div, on the k-th argument, with n fresh vars *) +let step k n p = + let var, _ = get_inert p.div in +print_cmd "STEP" ("on " ^ string_of_t (V var) ^ " (of:" ^ string_of_int n ^ ")"); + let p, t = (* apply fresh vars *) + fold_nat (fun (p, t) _ -> + let p, v = freshvar p in + p, A(t, V (v + k + 1)) + ) (p, V 0) n in + let t = (* apply unused bound variables V_{k-1}..V_1 *) + fold_nat (fun t m -> A(t, V (k-m+1))) t k in + let t = mk_lams t (k+1) in (* make leading lambdas *) + let subst = var, t in + let p = subst_in_problem subst p in + sanity p; p +;; + +let parse strs = + let rec aux level = function + | Parser_andrea.Lam t -> L (aux (level + 1) t) + | Parser_andrea.App (t1, t2) -> + if level = 0 then mk_app (aux level t1) (aux level t2) + else A(aux level t1, aux level t2) + | Parser_andrea.Var v -> V v in + let (tms, free) = Parser_andrea.parse_many strs in + (List.map (aux 0) tms, free) +;; + +let problem_of div conv = + print_hline (); + let [@warning "-8"] [div; conv], var_names = parse ([div; conv]) in + let varno = List.length var_names in + let p = {orig_freshno=varno; freshno=1+varno; div; conv; sigma=[]; stepped=[]; phase=`One} in + (* initial sanity check *) + sanity p; p +;; + +let exec div conv cmds = + let p = problem_of div conv in + try + problem_fail (List.fold_left (|>) p cmds) "Problem not completed" + with + | Done _ -> () +;; + +let rec auto p = + let hd_var, n_args = get_inert p.div in + match get_subterm_with_head_and_args hd_var n_args p.conv with + | None -> + (try + let phase = p.phase in + let p = eat p in + if phase = `Two + then problem_fail p "Auto.2 did not complete the problem" + else auto p + with Done sigma -> sigma) + | Some t -> + let j = find_eta_difference p t n_args - 1 in + let k = 1 + max + (compute_max_lambdas_at hd_var j p.div) + (compute_max_lambdas_at hd_var j p.conv) in + let p = step j k p in + auto p +;; + +let interactive div conv cmds = + let p = problem_of div conv in + try ( + let p = List.fold_left (|>) p cmds in + let rec f p cmds = + let nth spl n = int_of_string (List.nth spl n) in + let read_cmd () = + let s = read_line () in + let spl = Str.split (Str.regexp " +") s in + s, let uno = List.hd spl in + try if uno = "eat" then eat + else if uno = "step" then step (nth spl 1) (nth spl 2) + else failwith "Wrong input." + with Failure s -> print_endline s; (fun x -> x) in + let str, cmd = read_cmd () in + let cmds = (" " ^ str ^ ";")::cmds in + try + let p = cmd p in f p cmds + with + | Done _ -> print_endline "Done! Commands history: "; List.iter print_endline (List.rev cmds) + in f p [] + ) with Done _ -> () +;; + +let rec conv_join = function + | [] -> "@" + | x::xs -> conv_join xs ^ " ("^ x ^")" +;; + +let auto' a b = + let p = problem_of a (conv_join b) in + let sigma = auto p in + check p sigma +;; + +(* Example usage of exec, interactive: + +exec + "x x" + (conv_join["x y"; "y y"; "y x"]) + [ step 0 1; eat ] +;; + +interactive "x y" + "@ (x x) (y x) (y z)" [step 0 1; step 0 2; eat] +;; + +*) + +auto' "x x" ["x y"; "y y"; "y x"] ;; +auto' "x y" ["x (_. x)"; "y z"; "y x"] ;; +auto' "a (x. x b) (x. x c)" ["a (x. b b) @"; "a @ c"; "a (x. x x) a"; "a (a a a) (a c c)"] ;; + +auto' "x (y. x y y)" ["x (y. x y x)"] ;; + +auto' "x a a a a" [ + "x b a a a"; + "x a b a a"; + "x a a b a"; + "x a a a b"; +] ;; + +(* Controesempio ad usare un conto dei lambda che non considere le permutazioni *) +auto' "x a a a a (x (x. x x) @ @ (_._.x. x x) x) b b b" [ + "x a a a a (_. a) b b b"; + "x a a a a (_. _. _. _. x. y. x y)"; +] ;; + + +print_hline(); +print_endline "ALL DONE. "