]> matita.cs.unibo.it Git - fireball-separation.git/blobdiff - ocaml/lambda4.ml
Bug fix: x (y z) where y was conv_dangerous did not make x so
[fireball-separation.git] / ocaml / lambda4.ml
index 8498513a86be7d7a24ad5bc79539414deadc224c..35f03ca8bf4af09dc6bde54560cc789edbff12e7 100644 (file)
@@ -5,6 +5,13 @@ open Num
 
 let bomb = ref(`Var(-1,-666));;
 
+(*
+ The number of arguments which can applied to numbers
+ safely, depending on the encoding of numbers.
+ For Scott's encoding, two.
+*)
+let num_more_args = 2;;
+
 type problem =
  { freshno: int
  ; div: i_var option (* None = bomb *)
@@ -12,6 +19,7 @@ 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 *)
+ ; initialSpecialK: int
 };;
 
 let all_terms p =
@@ -20,7 +28,33 @@ let all_terms p =
  @ p.ps
 ;;
 
-let problem_measure p = 0 ;;
+let sum_arities p =
+ let rec aux = function
+ | `N _ -> 0
+ | `Var(_,ar) -> if ar = min_int then 0 else max 0 ar (*assert (ar >= 0); ar*)
+ | `Lam(_,t) -> aux t
+ | `I(v,args) -> aux (`Var v) + aux_many (Listx.to_list args)
+ | `Match(u,(_,ar),_,_,args) -> aux (u :> nf) + (if ar = min_int then 0 else ar - 1) + aux_many args
+ and aux_many tms = List.fold_right ((+) ++ aux) tms 0 in
+ aux_many (all_terms p :> nf list)
+ ;;
+
+let count_fakevars p =
+ let rec aux = function
+ | `N _ -> 0
+ | `Var(_,ar) -> if ar = min_int then 1 else 0
+ | `Lam(_,t) -> aux t
+ | `I(v,args) -> aux (`Var v) + aux_many (Listx.to_list args)
+ | `Match(u,v,_,_,args) -> aux (u :> nf) + aux (`Var v) + aux_many args
+ and aux_many tms = List.fold_right ((+) ++ aux) tms 0 in
+ aux_many (all_terms p :> nf list)
+;;
+
+(* let problem_measure p = count_fakevars p, sum_arities p;;
+let string_of_measure (a,b) = "(fakevars="^string_of_int a^",sum_arities="^string_of_int b^")" *)
+
+let problem_measure p = sum_arities p;;
+let string_of_measure = string_of_int;;
 
 let print_problem label ({freshno; div; conv; ps; deltas} as p) =
  Console.print_hline ();
@@ -28,7 +62,7 @@ let print_problem label ({freshno; div; conv; ps; deltas} as p) =
  let nl = "\n| " in
  let deltas = String.concat nl (List.map (fun r -> String.concat " <> " (List.map (fun (i,_) -> string_of_int i) !r)) deltas) in
  let l = Array.to_list (Array.init (freshno + 1) string_of_var) in
-    nl ^ "measure="^string_of_int(problem_measure p)^" freshno = " ^ string_of_int freshno
+    nl ^ "measure="^string_of_measure(problem_measure p)^" freshno = " ^ string_of_int freshno
  ^ nl ^ "\b> DISCRIMINATING SETS (deltas)"
  ^ nl ^ deltas ^ (if deltas = "" then "" else nl)
  ^ "\b> DIVERGENT" ^ nl
@@ -164,7 +198,7 @@ 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, snd orig - 1) in (* make_fresh_var freshno in *)
+           let freshno,v = freshno+1, `Var (freshno+1, -666) 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);*)
@@ -187,7 +221,7 @@ prerr_endline ("# INST: " ^ string_of_var x ^ " := " ^ print ~l inst));
  let p = {p with freshno; div; conv; ps} in
  ( (* check if double substituting a variable *)
   if List.exists (fun (x',_) -> x = x') sigma
-   then failwithProblem p "Variable replaced twice"
+   then failwithProblem p ("Variable "^ string_of_var x ^"replaced twice")
  );
  let p = {p with sigma = sigma@[x,inst]} in
  let p = super_simplify p in
@@ -213,8 +247,8 @@ 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 num_more_args
+        | `I((x,_),args') -> dangerous_inert arities showstoppers x (Listx.to_list args' @ args) num_more_args
       )
   | `I((k,_),args) -> dangerous_inert arities showstoppers k (Listx.to_list args) 0
 
@@ -238,20 +272,24 @@ 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
+        | `I((x,_),args') -> dangerous_inert_conv arities showstoppers x (Listx.to_list args') args 2
       )
-  | `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 @
- if List.mem k showstoppers then k :: concat_map free_vars args else
+and dangerous_inert_conv arities showstoppers k args match_args more_args =
+ let all_args = args @ match_args in
+ let dangerous_args = concat_map (dangerous_conv arities showstoppers) all_args in
+ if dangerous_args = [] then (
+ if List.mem k showstoppers then k :: concat_map free_vars all_args else
  try
   let arity = arity_of arities k in
-  prerr_endline ("dangerous_inert_conv: ar=" ^ string_of_int arity ^ " k="^string_of_var k ^ " listlenargs=" ^ (string_of_int (List.length args)) );
-  if List.length args + more_args > arity then k :: concat_map free_vars args else []
+prerr_endline ("dangerous_inert_conv: ar=" ^ string_of_int arity ^ " k="^string_of_var k ^ " listlenargs=" ^ (string_of_int (List.length args)) ^ " more_args=" ^ string_of_int more_args);
+  if more_args > 0 (* match argument*) && List.length args = arity then []
+  else if List.length all_args + more_args > arity then k :: concat_map free_vars all_args else []
  with
   Not_found -> []
+ ) else k :: concat_map free_vars all_args
 
 (* inefficient algorithm *)
 let rec edible arities div ps conv showstoppers =
@@ -281,8 +319,9 @@ let rec edible arities div ps conv showstoppers =
     let dangerous_conv =
      List.map (dangerous_conv arities showstoppers) (conv :> nf list) in
 
-    prerr_endline ("dangerous_conv lenght:" ^ string_of_int (List.length dangerous_conv));
-    List.iter (fun l -> prerr_endline (String.concat " " (List.map string_of_var l))) dangerous_conv;
+prerr_endline ("dangerous_conv lenght:" ^ string_of_int (List.length dangerous_conv));
+List.iter (fun l -> prerr_endline (String.concat " " (List.map string_of_var l))) dangerous_conv;
+
     let showstoppers' = showstoppers @ List.concat dangerous_conv in
     let showstoppers' = sort_uniq (match div with
      | None -> showstoppers'
@@ -419,7 +458,10 @@ let instantiate p x n =
  (if hd_of_i_var (cast_to_i_var !bomb) = x
    then failwithProblem p ("BOMB (" ^ string_of_nf !bomb ^ ") cannot be instantiated!"));
  let arity_of_x = max_arity_tms x (all_terms p) in
- (if arity_of_x < 0 then failwithProblem p "step on a var of negative arity");
+ (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 *)
@@ -427,8 +469,8 @@ let instantiate p x n =
  let p,vars = make_fresh_vars p arities in
  let args = Listx.from_list (vars :> nf list) in
  let bs = ref [] in
- (* min_int, since it will be replaced anyway during subst: *)
- let inst = `Lam(false,`Match(`I((0,n+1),Listx.map (lift 1) args),(x,min_int),1,bs,[])) in
+ (* 666, since it will be replaced anyway during subst: *)
+ let inst = `Lam(false,`Match(`I((0,min_int),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
 ;;
@@ -452,11 +494,13 @@ let auto_instantiate (n,p) =
       prerr_endline ("INSTANTIATING CRITICAL TO EAT " ^ string_of_var y); y
     | [], [] ->
      let heads =
+      (* Choose only variables still alive (with arity > 0) *)
       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
+       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
+         [] ->
+         assert false
        | x::_ ->
           prerr_endline ("INSTANTIATING TO EAT " ^ string_of_var x);
           x)
@@ -468,7 +512,7 @@ let auto_instantiate (n,p) =
 let x =
  try
   match hd_of (List.find (fun t ->
-   compute_special_k (Listx.Nil (t :> nf)) > 0 && arity_of_hd t >= 0
+   compute_special_k (Listx.Nil (t :> nf)) > 0 && arity_of_hd t > 0
    ) (all_terms p)) with
       None -> assert false
     | Some x ->
@@ -497,7 +541,7 @@ in*)
  special_k,p
 
 
-let rec auto_eat (n,({ps} as p)) =
+let rec auto_eat (n,p) =
  prerr_endline "{{{{{{{{ Computing measure before auto_instantiate }}}}}}";
  let m = problem_measure p in
  let (n,p') = auto_instantiate (n,p) in
@@ -505,10 +549,13 @@ let rec auto_eat (n,({ps} as p)) =
    `Finished p -> p
  | `Continue p ->
      prerr_endline "{{{{{{{{ Computing measure inafter auto_instantiate }}}}}}";
-     let delta = m - problem_measure p' in
+     let m' = problem_measure p in
+     let delta = compare m m' in
+     print_endline ("compare " ^ string_of_measure m' ^ " " ^ string_of_measure m ^ "= " ^ string_of_int delta);
+     (* let delta = m - problem_measure p' in *)
      if delta <= 0 then (
-      (* failwithProblem p' *)
-      prerr_endline
+      failwith
+      (* prerr_endline *)
       ("Measure did not decrease (delta=" ^ string_of_int delta ^ ")"))
      else prerr_endline ("$ Measure decreased by " ^ string_of_int delta);
      auto_eat (n,p)
@@ -726,7 +773,7 @@ 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 *)
@@ -741,7 +788,7 @@ let magic_conv ~div ~conv ~nums cmds =
    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;;