X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=ocaml%2Fsimple.ml;fp=ocaml%2Fsimple.ml;h=45e605b7ee37160d42c606e864273a0971a31f88;hb=dc6b7a6afe8b1fcf4f5998089ed2ef28f255da0a;hp=b640a0fdb2f2d58e3117a3dd647666854aa586bc;hpb=9d007f52d02d23ed95d28c7b805b65bbdc47de6a;p=fireball-separation.git diff --git a/ocaml/simple.ml b/ocaml/simple.ml index b640a0f..45e605b 100644 --- a/ocaml/simple.ml +++ b/ocaml/simple.ml @@ -6,11 +6,19 @@ let print_hline = Console.print_hline;; open Pure +type var_flag = [ + `Inherit | `Some of bool ref + (* bool: + true if original application and may determine a distinction + *) + | `Duplicate +] ;; + type var = int;; type t = | V of var - | A of (bool ref) * t * t - | L of (bool * t) + | A of var_flag * t * t + | L of t ;; let measure_of_t = @@ -19,8 +27,10 @@ let measure_of_t = | A(b,t1,t2) -> let acc, m1 = aux acc t1 in let acc, m2 = aux acc t2 in - if not (List.memq b acc) && !b then b::acc, 1 + m1 + m2 else acc, m1 + m2 - | L(b,t) -> if b then aux acc t else acc, 0 + (match b with + | `Some b when !b && not (List.memq b acc) -> b::acc, 1 + m1 + m2 + | _ -> acc, m1 + m2) + | L t -> aux acc t in snd ++ (aux []) ;; @@ -46,6 +56,12 @@ let sep_of_app = List.length !apps in " " ^ string_of_int i ^ ":" ;; +let string_of_var_flag = function + | `Some b -> sep_of_app b + | `Inherit -> " ?" + | `Duplicate -> " !" + ;; + let string_of_t = let string_of_bvar = @@ -58,19 +74,19 @@ let string_of_t = | A _ | L _ as t -> "(" ^ string_of_term_no_pars level t ^ ")" and string_of_term_no_pars_app level = function - | A(b,t1,t2) -> string_of_term_no_pars_app level t1 ^ sep_of_app b ^ string_of_term_w_pars level t2 + | A(b,t1,t2) -> string_of_term_no_pars_app level t1 ^ string_of_var_flag b ^ 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 + | 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 ;; -let delta = L(true,A(ref true,V 0, V 0));; +let delta = L(A(`Some (ref true),V 0, V 0));; (* does NOT lift the argument *) -let mk_lams = fold_nat (fun x _ -> L(false,x)) ;; +let mk_lams = fold_nat (fun x _ -> L x) ;; type problem = { orig_freshno: int @@ -123,48 +139,62 @@ let rec get_inert = function (* precomputes the number of leading lambdas in a term, after replacing _v_ w/ a term starting with n lambdas *) let rec no_leading_lambdas v n = function - | L(_,t) -> 1 + no_leading_lambdas (v+1) n t + | L t -> 1 + no_leading_lambdas (v+1) n t | A _ as t -> let v', m = get_inert t in if v = v' then max 0 (n - m) else 0 | V v' -> if v = v' then n else 0 ;; -(* b' is true iff we are substituting the argument of a step - and the application of the redex was true. Therefore we need to - set the new app to true. *) -let rec subst b' level delift sub = +let rec erase = function + | L t -> L (erase t) + | A(_,t1,t2) -> A(`Some(ref false), erase t1, erase t2) + | V _ as t -> t +;; + +let rec subst top level delift ((flag, var, tm) as 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(b,t) -> L(b, subst b' (level + 1) delift sub t) - | A(_,t1,(V v as t2)) when b' && v = level + fst sub -> - mk_app (ref true) (subst b' level delift sub t1) (subst b' level delift sub t2) + | V v -> if v = level + var then lift level tm else V (if delift && v > level then v-1 else v) + | L t -> L (subst top (level + 1) delift sub t) | A(b,t1,t2) -> - mk_app b (subst b' level delift sub t1) (subst b' level delift sub t2) -(* b is - - a fresh ref true if we want to create a real application from scratch - - a shared ref true if we substituting in the head of a real application *) -and mk_app b' t1 t2 = if t1 = delta && t2 = delta then raise B + let special = b = `Duplicate && top && t2 = V (level + var) in + let t1' = subst (if special then false else top) level delift sub t1 in + let t2' = subst false level delift sub t2 in + match b with + | `Duplicate when special -> + assert (match t1' with L _ -> false | _ -> true) ; + (match flag with + | `Some b when !b -> b := false + | `Some b -> + print_string "WARNING! Stepping on a useless argument!"; + ignore(read_line()) + | `Inherit | `Duplicate -> assert false); + A(flag, t1', erase t2') + | `Inherit | `Duplicate -> + let b' = if t2 = V (level + var) + then (assert (flag <> `Inherit); flag) + else b in + assert (match t1' with L _ -> false | _ -> true) ; + A(b', t1', t2') + | `Some b' -> mk_app top b' t1' t2' +and mk_app top flag t1 t2 = if t1 = delta && t2 = delta then raise B else match t1 with - | L(b,t1) -> - let last_lam = match t1 with L _ -> false | _ -> true in - if not b && last_lam then b' := false ; - subst (!b' && not b && not last_lam) 0 true (0, t2) t1 - | _ -> A (b', t1, t2) + | L t1 -> subst top 0 true (`Some flag, 0, t2) t1 + | _ -> A (`Some flag, t1, t2) and lift n = let rec aux lev = function | V m -> V (if m >= lev then m + n else m) - | L(b,t) -> L(b,aux (lev+1) t) + | L t -> L(aux (lev+1) t) | A (b,t1, t2) -> A (b,aux lev t1, aux lev t2) in aux 0 ;; -let subst = subst false 0 false;; -let mk_app t1 = mk_app (ref true) t1;; +let subst top = subst top 0 false;; +let mk_app = mk_app true;; let eta_eq = let rec aux t1 t2 = match t1, t2 with - | L(_,t1), L(_,t2) -> aux t1 t2 - | L(_,t1), t2 -> aux t1 (A(ref true,lift 1 t2,V 0)) - | t1, L(_,t2) -> aux (A(ref true,lift 1 t1,V 0)) t2 + | L t1, L t2 -> aux t1 t2 + | L t1, t2 -> aux t1 (A(`Some (ref true),lift 1 t2,V 0)) + | t1, L t2 -> aux (A(`Some (ref true),lift 1 t1,V 0)) t2 | V a, V b -> a = b | A(_,t1,t2), A(_,u1,u2) -> aux t1 u1 && aux t2 u2 | _, _ -> false @@ -173,24 +203,25 @@ let eta_eq = (* is arg1 eta-subterm of arg2 ? *) let eta_subterm u = let rec aux lev t = eta_eq u (lift lev t) || match t with - | L(_, t) -> aux (lev+1) t + | L t -> aux (lev+1) t | A(_, t1, t2) -> aux lev t1 || aux lev t2 | _ -> false in aux 0 ;; -let subst_in_problem ((v, t) as sub) p = +let subst_in_problem ?(top=true) ((v, t) as sub) p = print_endline ("-- SUBST " ^ string_of_t (V v) ^ " |-> " ^ string_of_t t); let sigma = sub::p.sigma in - let div = try subst sub p.div with B -> raise (Done sigma) in - let conv = try subst sub p.conv with B -> raise (Fail(-1,"p.conv diverged")) in + let sub = (`Inherit, v, t) in + let div = try subst top sub p.div with B -> raise (Done sigma) in + let conv = try subst false sub p.conv with B -> raise (Fail(-1,"p.conv diverged")) in {p with div; conv; sigma} ;; let get_subterm_with_head_and_args hd_var n_args = let rec aux lev = function | V _ -> None - | L(_,t) -> aux (lev+1) t + | 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' @@ -203,7 +234,7 @@ let get_subterm_with_head_and_args hd_var n_args = ;; let rec purify = function - | L(_,t) -> Pure.L (purify t) + | L t -> Pure.L (purify t) | A(_,t1,t2) -> Pure.A (purify t1, purify t2) | V n -> Pure.V n ;; @@ -273,7 +304,7 @@ let compute_max_lambdas_at hd_var j = then let hd', j' = get_inert t2 in j - j' else no_leading_lambdas hd_var j t2) else id) (max (aux hd t1) (aux hd t2)) - | L(_,t) -> aux (hd+1) t + | L t -> aux (hd+1) t | V _ -> 0 in aux hd_var ;; @@ -281,19 +312,19 @@ let compute_max_lambdas_at hd_var j = let print_cmd s1 s2 = print_endline (">> " ^ s1 ^ " " ^ s2);; (* step on the head of div, on the k-th argument, with n fresh vars *) -let step k n p = +let step ?(isfinish=false) 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(ref false, t, V (v + k + 1)) + p, A(`Some (ref false), t, V (v + k + 1)) ) (p, V 0) n in let t = (* apply bound variables V_k..V_0 *) - fold_nat (fun t m -> A(ref false, t, V (k-m+1))) t (k+1) in + fold_nat (fun t m -> A((if m = k+1 then `Duplicate else `Inherit), t, V (k-m+1))) t (k+1) 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 + let p = subst_in_problem ~top:(not isfinish) subst p in sanity p ;; @@ -301,7 +332,7 @@ let finish p = let compute_max_arity = let rec aux n = function | A(_,t1,t2) -> max (aux (n+1) t1) (aux 0 t2) - | L(_,t) -> max n (aux 0 t) + | L t -> max n (aux 0 t) | V _ -> n in aux 0 in print_cmd "FINISH" ""; @@ -311,7 +342,7 @@ print_cmd "FINISH" ""; let n = 1 + arity + max (compute_max_lambdas_at div_hd j p.div) (compute_max_lambdas_at div_hd j p.conv) in - let p = step j n p in + let p = step ~isfinish:true j n p in let div_hd, div_nargs = get_inert p.div in let rec aux m = function A(_,t1,t2) -> if is_var t2 then @@ -358,8 +389,8 @@ let rec auto p = let problem_of (label, div, convs, ps, var_names) = print_hline (); let rec aux = function - | `Lam(_, t) -> L (true,aux t) - | `I ((v,_), args) -> Listx.fold_left (fun x y -> mk_app x (aux y)) (V v) args + | `Lam(_,t) -> L (aux t) + | `I ((v,_), args) -> Listx.fold_left (fun x y -> mk_app (ref true) x (aux y)) (V v) args | `Var(v,_) -> V v | `N _ | `Match _ -> assert false in assert (List.length ps = 0);