X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=ocaml%2Flambda4.ml;h=77449b4681a7887cde71c8cbd170588b8a53241a;hb=08d2b663e5089ed046ef771bfb2555a31e525f1c;hp=3e9f1ef81c9e27fb96f7693baeb71c9b3da7b887;hpb=b609e8cfc37360748de4fcbc4e80bba556fadc87;p=fireball-separation.git diff --git a/ocaml/lambda4.ml b/ocaml/lambda4.ml index 3e9f1ef..77449b4 100644 --- a/ocaml/lambda4.ml +++ b/ocaml/lambda4.ml @@ -3,7 +3,7 @@ open Util.Vars open Pure open Num -let bomb = ref(`Var ~-1);; +let bomb = ref(`Var(-1,-666));; type problem = { freshno: int @@ -12,42 +12,13 @@ type problem = ; ps: i_n_var list (* the n-th inert must become n *) ; sigma: (int * nf) list (* the computed substitution *) ; deltas: (int * nf) list ref list (* collection of all branches *) - } - - -(* let heads = Util.sort_uniq (List.map hd_of_i_var p.ps) in -for all head - List.map (fun (_, bs) -> List.map (fun (x,_) -> List.nth p.ps x) !bs) p.deltas *) - -(* let ($) f x = f x;; *) - -let subterms tms freshno = - let apply_var = - let no = ref freshno in - function t -> incr no; mk_app t (`Var !no) in - let applicative hd args = snd ( - List.fold_left (fun (hd, acc) t -> let hd = mk_app hd t in hd, hd::acc) (hd, []) args) in - let rec aux t = match t with - | `Var _ -> [] - | `I(v,ts) -> - (* applicative (`Var v) (Listx.to_list ts) @ *) - Util.concat_map aux (Listx.to_list ts) @ List.map apply_var (Listx.to_list ts) - | `Lam(_,_,t) -> aux (lift ~-1 t) - | `Match(u,_,bs_lift,bs,args) -> - aux (u :> nf) @ - (* applicative (`Match(u,bs_lift,bs,[])) args @ *) - Util.concat_map aux args @ List.map apply_var args - (* @ Util.concat_map (aux ++ (lift bs_lift) ++ snd) !bs *) - | `N _ -> [] - in let tms' = (* Util.sort_uniq ~compare:eta_compare*) (Util.concat_map aux tms) in - tms @ tms' - (* List.map (fun (t, v) -> match t with `N _ -> t | _ -> mk_app t v) (List.combine tms (List.mapi (fun i _ -> `Var(freshno+i)) tms)) *) -;; + ; initialSpecialK: int +};; let all_terms p = -(match p.div with None -> [] | Some t -> [(t :> i_n_var)]) -@ p.conv -@ p.ps + (match p.div with None -> [] | Some t -> [(t :> i_n_var)]) + @ p.conv + @ p.ps ;; let problem_measure p = 0 ;; @@ -77,41 +48,41 @@ let failwithProblem p reason = failwith reason ;; -let make_fresh_var p = +let make_fresh_var p arity = let freshno = p.freshno + 1 in - {p with freshno}, `Var freshno + {p with freshno}, `Var(freshno,arity) ;; -let make_fresh_vars p m = - Array.fold_left - (* fold_left vs. fold_right hides/shows the bug in problem q7 *) - (fun (p, vars) _ -> let p, var = make_fresh_var p in p, var::vars) +let make_fresh_vars p arities = + List.fold_right + (fun arity (p, vars) -> let p, var = make_fresh_var p arity in p, var::vars) + arities (p, []) - (Array.make m ()) ;; let simple_expand_match ps = - let rec aux level = function + let rec aux level = function | #i_num_var as t -> aux_i_num_var level t - | `Lam(b,ar,t) -> `Lam(b,ar,aux (level+1) t) - and aux_i_num_var level = function - | `Match(u,ar,bs_lift,bs,args) as torig -> + | `Lam(b,t) -> `Lam(b,aux (level+1) t) + and aux_i_num_var level = function + | `Match(u,v,bs_lift,bs,args) as torig -> let u = aux_i_num_var level u in bs := List.map (fun (n, x) -> n, aux 0 x) !bs; (try (match u with | #i_n_var as u -> let i = index_of (lift (-level) u) (ps :> nf list) (* can raise Not_found *) - in let t = mk_match (`N i) ar bs_lift bs args in + in let t = mk_match (`N i) v bs_lift bs args in if t <> torig then aux level (t :> nf) else raise Not_found | _ -> raise Not_found) with Not_found -> - `Match(cast_to_i_num_var u,ar,bs_lift,bs,List.map (aux level) args)) - | `I(k,args) -> `I(k,Listx.map (aux level) args) + `Match(cast_to_i_num_var u,v,bs_lift,bs,List.map (aux level) args)) + | `I(v,args) -> `I(v,Listx.map (aux level) args) | `N _ | `Var _ as t -> t -in aux_i_num_var 0;; + in aux_i_num_var 0 +;; let fixpoint f = let rec aux x = let x' = f x in if x <> x' then aux x' else x in aux @@ -140,10 +111,10 @@ prerr_endline ("# INST0: " ^ string_of_var x ^ " := " ^ print ~l inst));*) | [] -> acc | t::todo_ps -> (*prerr_endline ("EXPAND t:" ^ print (t :> nf));*) - let t = subst false x inst (t :> nf) in + let t = subst false false x inst (t :> nf) in (*prerr_endline ("SUBSTITUTED t:" ^ print (t :> nf));*) let freshno,new_t,acc_new_ps = - expand_match (freshno,acc_ps@`Var(max_int/3)::todo_ps,acc_new_ps) t + expand_match (freshno,acc_ps@`Var(max_int/3,-666)::todo_ps,acc_new_ps) t in aux (freshno,acc_ps@[new_t],acc_new_ps) todo_ps @@ -154,7 +125,7 @@ prerr_endline ("# INST0: " ^ string_of_var x ^ " := " ^ print ~l inst));*) | t::todo_conv -> (*prerr_endline ("EXPAND t:" ^ print (t :> nf));*) (* try *) - let t = subst false x inst (t :> nf) in + let t = subst false false x inst (t :> nf) in (*prerr_endline ("SUBSTITUTED t:" ^ print (t :> nf));*) let freshno,new_t,acc_new_ps = expand_match (freshno,ps,acc_new_ps) t @@ -167,7 +138,7 @@ prerr_endline ("# INST0: " ^ string_of_var x ^ " := " ^ print ~l inst));*) function | None -> freshno, None, acc_new_ps | Some t -> - let t = subst false x inst (t :> nf) in + let t = subst false false x inst (t :> nf) in let freshno,new_t,acc_new_ps = expand_match (freshno,ps,acc_new_ps) t in @@ -175,13 +146,13 @@ prerr_endline ("# INST0: " ^ string_of_var x ^ " := " ^ print ~l inst));*) and expand_match ((freshno,acc_ps,acc_new_ps) as acc) t = match t with - | `Match(u',ar,bs_lift,bs,args) -> + | `Match(u',orig,bs_lift,bs,args) -> let freshno,u,acc_new_ps = expand_match acc (u' :> nf) in let acc_new_ps,i = match u with | `N i -> acc_new_ps,i | _ -> - let ps = List.map (fun t -> cast_to_i_num_var (subst false x inst (t:> nf))) (acc_ps@acc_new_ps) in + let ps = List.map (fun t -> cast_to_i_num_var (subst false false x inst (t:> nf))) (acc_ps@acc_new_ps) in let super_simplified_ps = super_simplify_ps ps ps in (*prerr_endline ("CERCO u:" ^ print (fst u :> nf)); List.iter (fun x -> prerr_endline ("IN: " ^ print (fst x :> nf))) ps; @@ -194,11 +165,11 @@ List.iter (fun x -> prerr_endline ("IN2: " ^ print (fst x :> nf))) super_simplif if List.exists (fun (j,_) -> i=j) !bs then freshno else - let freshno,v = freshno+1, `Var (freshno+1) in (* make_fresh_var freshno in *) + let freshno,v = freshno+1, `Var (freshno+1, snd orig - 1) in (* make_fresh_var freshno in *) bs := !bs @ [i, v] ; freshno in (*prerr_endlie ("t DA RIDURRE:" ^ print (`Match(`N i,arity,bs_lift,bs,args) :> nf) ^ " more_args=" ^ string_of_int more_args);*) - let t = mk_match (`N i) ar bs_lift bs args in + let t = mk_match (`N i) orig bs_lift bs args in (*prerr_endline ("NUOVO t:" ^ print (fst t :> nf) ^ " more_args=" ^ string_of_int (snd t));*) expand_match (freshno,acc_ps,acc_new_ps) t | `Lam _ -> raise ExpandedToLambda @@ -243,10 +214,10 @@ let rec dangerous arities showstoppers = (match t with `N _ -> List.iter (dangerous arities showstoppers) args | `Match _ as t -> dangerous arities showstoppers t ; List.iter (dangerous arities showstoppers) args - | `Var x -> dangerous_inert arities showstoppers x args 2 (* 2 coming from Scott's encoding *) - | `I(x,args') -> dangerous_inert arities showstoppers x (Listx.to_list args' @ args) 2 (* 2 coming from Scott's encoding *) + | `Var(x,_) -> dangerous_inert arities showstoppers x args 2 (* 2 coming from Scott's encoding *) + | `I((x,_),args') -> dangerous_inert arities showstoppers x (Listx.to_list args' @ args) 2 (* 2 coming from Scott's encoding *) ) - | `I(k,args) -> dangerous_inert arities showstoppers k (Listx.to_list args) 0 + | `I((k,_),args) -> dangerous_inert arities showstoppers k (Listx.to_list args) 0 and dangerous_inert arities showstoppers k args more_args = List.iter (dangerous arities showstoppers) args ; @@ -268,10 +239,10 @@ let rec dangerous_conv arities showstoppers = (match t with `N _ -> concat_map (dangerous_conv arities showstoppers) args | `Match _ as t -> dangerous_conv arities showstoppers t @ concat_map (dangerous_conv arities showstoppers) args - | `Var x -> dangerous_inert_conv arities showstoppers x args 2 (* 2 coming from Scott's encoding *) - | `I(x,args') -> dangerous_inert_conv arities showstoppers x (Listx.to_list args' @ args) 2 (* 2 coming from Scott's encoding *) + | `Var(x,_) -> dangerous_inert_conv arities showstoppers x args 2 (* 2 coming from Scott's encoding *) + | `I((x,_),args') -> dangerous_inert_conv arities showstoppers x (Listx.to_list args' @ args) 2 (* 2 coming from Scott's encoding *) ) - | `I(k,args) -> dangerous_inert_conv arities showstoppers k (Listx.to_list args) 0 + | `I((k,_),args) -> dangerous_inert_conv arities showstoppers k (Listx.to_list args) 0 and dangerous_inert_conv arities showstoppers k args more_args = concat_map (dangerous_conv arities showstoppers) args @ @@ -345,7 +316,7 @@ let critical_showstoppers p = let showstoppers_eat = let heads_and_arities = List.sort (fun (k,_) (h,_) -> compare k h) - (filter_map (function `Var k -> Some (k,0) | `I(k,args) -> Some (k,Listx.length args) | _ -> None ) p.ps) in + (filter_map (function `Var(k,_) -> Some (k,0) | `I((k,_),args) -> Some (k,Listx.length args) | _ -> None ) p.ps) in let rec multiple_arities = function [] @@ -397,8 +368,8 @@ prerr_endline ("# INST_IN_EAT: " ^ string_of_var x ^ " := " ^ print ~l inst)); then p else let n = match div with `I(_,args) -> Listx.length args | `Var _ -> 0 in - let p, bomb' = make_fresh_var p in - (if !bomb <> `Var (-1) then + let p, bomb' = make_fresh_var p (-666) in + (if !bomb <> `Var (-1,-666) then failwithProblem p ("Bomb was duplicated! It was " ^ string_of_nf !bomb ^ ", tried to change it to " ^ string_of_nf bomb')); @@ -446,25 +417,31 @@ List.iter (fun l -> prerr_endline (String.concat " " (List.map string_of_var l)) `Continue p let instantiate p x n = - (if `Var x = !bomb + (if hd_of_i_var (cast_to_i_var !bomb) = x then failwithProblem p ("BOMB (" ^ string_of_nf !bomb ^ ") cannot be instantiated!")); - let p,vars = make_fresh_vars p n in - let p,zero = make_fresh_var p in - let zero = Listx.Nil zero in - let args = if n = 0 then zero else Listx.append zero (Listx.from_list vars) in + let arity_of_x = max_arity_tms x (all_terms p) in + (if arity_of_x = None then failwithProblem p "step on var non occurring in problem"); + (if Util.option_get(arity_of_x) = min_int then failwithProblem p "step on fake variable"); + (if Util.option_get(arity_of_x) <= 0 then failwithProblem p "step on var of non-positive arity"); + let n = (prerr_endline "WARNING: using constant initialSpecialK"); p.initialSpecialK in + (* AC: Once upon a time, it was: + let arities = Num.compute_arities x (n+1) (all_terms p :> nf list) in *) + (* let arities = Array.to_list (Array.make (n+1) 0) in *) + let arities = Array.to_list (Array.make (n+1) min_int) in + let p,vars = make_fresh_vars p arities in + let args = Listx.from_list (vars :> nf list) in let bs = ref [] in - let arity1 = (*assert false; -666*) 0 in - let arity2 = (*assert false; -666*) 0 in - let inst = `Lam(false,arity1,`Match(`I(0,Listx.map (lift 1) args),arity2,1,bs,[])) in + (* 666, since it will be replaced anyway during subst: *) + let inst = `Lam(false,`Match(`I((0,n+2),Listx.map (lift 1) args),(x,666),1,bs,[])) in let p = {p with deltas=bs::p.deltas} in subst_in_problem x inst p ;; let compute_special_k tms = let rec aux k (t: nf) = Pervasives.max k (match t with - | `Lam(b,_,t) -> aux (k + if b then 1 else 0) t + | `Lam(b,t) -> aux (k + if b then 1 else 0) t | `I(n, tms) -> Listx.max (Listx.map (aux 0) tms) - | `Match(t,_,liftno, bs, args) -> + | `Match(t, _, liftno, bs, args) -> List.fold_left max 0 (List.map (aux 0) ((t :> nf)::args@List.map snd !bs)) | `N _ -> 0 | `Var _ -> 0 @@ -478,7 +455,10 @@ let auto_instantiate (n,p) = | [], y::_ -> prerr_endline ("INSTANTIATING CRITICAL TO EAT " ^ string_of_var y); y | [], [] -> - let heads = List.sort compare (filter_map (fun t -> match t with `Var _ -> None | x -> hd_of x) ((match p.div with Some t -> [(t :> i_n_var)] | _ -> []) @ p.ps)) in + let heads = + List.sort compare (filter_map ( + fun t -> match t with `Var _ -> None | x -> if arity_of_hd x < 0 then None else hd_of x + ) ((match p.div with Some t -> [(t :> i_n_var)] | _ -> []) @ p.ps)) in (match heads with [] -> assert false | x::_ -> @@ -487,11 +467,13 @@ let auto_instantiate (n,p) = | x::_, _ -> prerr_endline ("INSTANTIATING " ^ string_of_var x); x in -(* Strategy that decreases the special_k to 0 first (round robin) +(* Strategy that decreases the special_k to 0 first (round robin) 1:11m42 2:14m5 3:11m16s 4:14m46s 5:12m7s 6:6m31s *) let x = try - match hd_of (List.find (fun t -> compute_special_k (Listx.Nil (t :> nf)) > 0) (all_terms p)) with + match hd_of (List.find (fun t -> + compute_special_k (Listx.Nil (t :> nf)) > 0 && arity_of_hd t >= 0 + ) (all_terms p)) with None -> assert false | Some x -> prerr_endline ("INSTANTIATING AND HOPING " ^ string_of_var x); @@ -590,7 +572,7 @@ let optimize_numerals p = | `N n -> `N (List.nth perm n) | `I _ -> assert false | `Var _ as t -> t - | `Lam(v,ar,t) -> `Lam(v, ar, aux t) + | `Lam(v,t) -> `Lam(v, aux t) | `Match(_,_,_,bs,_) as t -> (bs := List.map (fun (n,t) -> (List.nth perm n, t)) !bs); t in List.map (fun (n,t) -> (n,aux t)) in @@ -617,7 +599,7 @@ let env_of_sigma freshno sigma should_explode = e,Pure.lift (-n-1) (snd (List.find (fun (i,_) -> i = n) sigma)),[] with Not_found -> - if should_explode && `Var n = !bomb + if should_explode && n = hd_of_i_var (cast_to_i_var !bomb) then ([], (let f t = Pure.A(t,t) in f (Pure.L (f (Pure.V 0)))), []) else ([],Pure.V n,[]))::e in aux 0 @@ -657,7 +639,7 @@ let main problems = List.iter (fun (p,n,cmds) -> Console.print_hline(); - bomb := `Var (-1); + bomb := `Var (-1,-666); let p_finale = aux p n cmds in let freshno,sigma = p_finale.freshno, p_finale.sigma in prerr_endline ("------- ------\n "); @@ -727,7 +709,7 @@ in (********************** problems *******************) -let zero = `Var 0;; +let zero = `Var(0,0);; let append_zero = function @@ -748,22 +730,22 @@ let magic_conv ~div ~conv ~nums cmds = if match div with None -> false | Some div -> List.exists (eta_subterm div) (tms@conv) then ( prerr_endline "--- TEST SKIPPED ---"; - {freshno=0; div=None; conv=[]; ps=[]; sigma=[]; deltas=[]}, 0, [] + {freshno=0; div=None; conv=[]; ps=[]; sigma=[]; deltas=[]; initialSpecialK=0}, 0, [] ) else let tms = sort_uniq ~compare:eta_compare tms in let special_k = compute_special_k (Listx.from_list all_tms) in (* compute initial special K *) (* casts *) let div = option_map cast_to_i_var div in - let conv = List.map cast_to_i_n_var conv in + let conv = Util.filter_map (function #i_n_var as t -> Some (cast_to_i_n_var t) | _ -> None) conv in let tms = List.map cast_to_i_n_var tms in let ps = List.map append_zero tms in (* crea lista applicando zeri o dummies *) let freshno = List.length var_names in let deltas = - let dummy = `Var (max_int / 2) in + let dummy = `Var (max_int / 2, -666) in [ ref (Array.to_list (Array.init (List.length ps) (fun i -> i, dummy))) ] in - {freshno; div; conv; ps; sigma=[] ; deltas}, special_k, cmds + {freshno; div; conv; ps; sigma=[] ; deltas; initialSpecialK=special_k}, special_k, cmds ;; let magic strings cmds = magic_conv None [] strings cmds;;