]> matita.cs.unibo.it Git - helm.git/commitdiff
resumed ol auto
authorEnrico Tassi <enrico.tassi@inria.fr>
Fri, 6 Oct 2006 16:41:53 +0000 (16:41 +0000)
committerEnrico Tassi <enrico.tassi@inria.fr>
Fri, 6 Oct 2006 16:41:53 +0000 (16:41 +0000)
helm/software/components/tactics/autoTactic.ml
helm/software/components/tactics/metadataQuery.ml
helm/software/components/tactics/metadataQuery.mli
helm/software/matita/library/nat/factorization.ma

index 4b713d46492aa10d0ec03316f3a3dedcbcd828bc..050d5c64333d223a7dbe3a2702495256867233e9 100644 (file)
 
 (* let debug_print = fun _ -> () *)
 
+(* Profiling code
+let new_experimental_hint =
+ let profile = CicUtil.profile "new_experimental_hint" in
+ fun ~dbd ~facts ?signature ~universe status ->
+  profile.profile (MetadataQuery.new_experimental_hint ~dbd ~facts ?signature ~universe) status
+*) let new_experimental_hint = MetadataQuery.new_experimental_hint
+
+(* In this versions of auto_tac we maintain an hash table of all inspected
+   goals. We assume that the context is invariant for application. 
+   To this aim, it is essential to sall hint_verbose, that in turns calls
+   apply_verbose. *)
+
+type exitus = 
+    No of int 
+  | Yes of Cic.term * int 
+  | NotYetInspected
+        
+let inspected_goals = Hashtbl.create 503;;
+
+let search_theorems_in_context status =
+  let (proof, goal) = status in
+  let module C = Cic in
+  let module R = CicReduction in
+  let module S = CicSubstitution in
+  let module PET = ProofEngineTypes in 
+  let module PT = PrimitiveTactics in 
+  let _,metasenv,_,_ = proof in
+  let _,context,ty = CicUtil.lookup_meta goal metasenv in
+  let rec find n = function 
+    | [] -> []
+    | hd::tl ->
+        let res =
+          (* we should check that the hypothesys has not been cleared *)
+          if List.nth context (n-1) = None then
+            None
+          else
+            try
+              let (subst,(proof, goal_list)) =
+                PT.apply_tac_verbose ~term:(C.Rel n) status  
+              in
+              (* 
+                 let goal_list =
+                   List.stable_sort (compare_goal_list proof) goal_list in 
+              *)
+              Some (subst,(proof, goal_list))
+            with 
+             PET.Fail _ -> None 
+        in
+        (match res with
+        | Some res -> res::(find (n+1) tl)
+        | None -> find (n+1) tl)
+  in
+  try 
+    find 1 context
+  with Failure s -> []
+;;     
+
+
+let compare_goals proof goal1 goal2 =
+  let _,metasenv,_,_ = proof in
+  let (_, ey1, ty1) = CicUtil.lookup_meta goal1 metasenv in
+  let (_, ey2, ty2) =  CicUtil.lookup_meta goal2 metasenv in
+  let ty_sort1,_ = CicTypeChecker.type_of_aux' metasenv ey1 ty1 
+                     CicUniv.empty_ugraph in
+  let ty_sort2,_ = CicTypeChecker.type_of_aux' metasenv ey2 ty2 
+                     CicUniv.empty_ugraph in
+  let prop1 =
+    let b,_ = CicReduction.are_convertible ey1 (Cic.Sort Cic.Prop) ty_sort1 
+                CicUniv.empty_ugraph in
+      if b then 0 else 1
+  in
+  let prop2 =
+    let b,_ = CicReduction.are_convertible ey2 (Cic.Sort Cic.Prop) ty_sort2 
+                CicUniv.empty_ugraph in
+      if b then 0 else 1
+  in
+  prop1 - prop2
+
+
+let new_search_theorems f dbd proof goal depth sign =
+  let choices = f (proof,goal)
+  in 
+  List.map 
+    (function (subst,(proof, goallist)) ->
+       (* let goallist = reorder_goals dbd sign proof goallist in *)
+        let goallist = List.sort (compare_goals proof) goallist in 
+       (subst,(proof,(List.map (function g -> (g,depth)) goallist), sign)))
+    choices 
+;;
+
+exception NoOtherChoices;;
+
+let rec auto_single dbd proof goal ey ty depth width sign already_seen_goals
+ universe
+  =
+  if depth = 0 then [] else
+  if List.mem ty already_seen_goals then [] else
+  let already_seen_goals = ty::already_seen_goals in
+  let facts = (depth = 1) in  
+  let _,metasenv,p,_ = proof in
+    (* first of all we check if the goal has been already
+       inspected *)
+  assert (CicUtil.exists_meta goal metasenv);
+  let exitus =
+    try Hashtbl.find inspected_goals ty
+    with Not_found -> NotYetInspected in
+  let is_meta_closed = CicUtil.is_meta_closed ty in
+    begin
+      match exitus with
+          Yes (bo,_) ->
+            (*
+              debug_print (lazy "ALREADY PROVED!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+              debug_print (lazy (CicPp.ppterm ty));
+            *)
+            let subst_in =
+              (* if we just apply the subtitution, the type 
+                 is irrelevant: we may use Implicit, since it will 
+                 be dropped *)
+              CicMetaSubst.apply_subst 
+                [(goal,(ey, bo, Cic.Implicit None))] in
+            let (proof,_) = 
+              ProofEngineHelpers.subst_meta_and_metasenv_in_proof 
+                proof goal subst_in metasenv in
+              [(subst_in,(proof,[],sign))]
+        | No d when (d >= depth) -> 
+            (* debug_print (lazy "PRUNED!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); *)
+            [] (* the empty list means no choices, i.e. failure *)
+        | No _ 
+        | NotYetInspected ->
+              debug_print (lazy ("CURRENT GOAL = " ^ CicPp.ppterm ty));
+              debug_print (lazy ("CURRENT PROOF = " ^ CicPp.ppterm p));
+              debug_print (lazy ("CURRENT HYP = " ^ CicPp.ppcontext ey));
+            let sign, new_sign =
+              if is_meta_closed then
+                None, Some (MetadataConstraints.signature_of ty)
+              else sign,sign in (* maybe the union ? *)
+            let local_choices =
+              new_search_theorems 
+                search_theorems_in_context dbd
+                proof goal (depth-1) new_sign in
+            let global_choices =
+              new_search_theorems 
+                (fun status -> 
+                   List.map snd
+                   (new_experimental_hint 
+                      ~dbd ~facts:facts ?signature:sign ~universe status))
+                dbd proof goal (depth-1) new_sign in 
+            let all_choices =
+              local_choices@global_choices in
+            let sorted_choices = 
+              List.stable_sort
+                (fun (_, (_, goals1, _)) (_, (_, goals2, _)) ->
+                   Pervasives.compare 
+                   (List.length goals1) (List.length goals2))
+                all_choices in 
+              (match (auto_new dbd width already_seen_goals universe sorted_choices) 
+               with
+                   [] -> 
+                     (* no proof has been found; we update the
+                        hastable *)
+                     (* if is_meta_closed then *)
+                       Hashtbl.add inspected_goals ty (No depth);
+                     []
+                 | (subst,(proof,[],sign))::tl1 -> 
+                     (* a proof for goal has been found:
+                        in order to get the proof we apply subst to
+                        Meta[goal] *)
+                     if is_meta_closed  then
+                       begin 
+                         let irl = 
+                           CicMkImplicit.identity_relocation_list_for_metavariable ey in
+                         let meta_proof = 
+                           subst (Cic.Meta(goal,irl)) in
+                           Hashtbl.add inspected_goals 
+                             ty (Yes (meta_proof,depth));
+(*
+                           begin
+                             let cty,_ = 
+                               CicTypeChecker.type_of_aux' metasenv ey meta_proof CicUniv.empty_ugraph
+                             in
+                               if not (cty = ty) then
+                                 begin
+                                   debug_print (lazy ("ty =  "^CicPp.ppterm ty));
+                                   debug_print (lazy ("cty =  "^CicPp.ppterm cty));
+                                   assert false
+                                 end
+                                   Hashtbl.add inspected_goals 
+                                   ty (Yes (meta_proof,depth));
+                           end;
+*)
+                       end;
+                     (subst,(proof,[],sign))::tl1
+                 | _ -> assert false)
+    end
+      
+and auto_new dbd width already_seen_goals universe = function
+  | [] -> []
+  | (subst,(proof, goals, sign))::tl ->
+      let _,metasenv,_,_ = proof in
+      let goals'=
+        List.filter (fun (goal, _) -> CicUtil.exists_meta goal metasenv) goals
+      in
+            auto_new_aux dbd 
+        width already_seen_goals universe ((subst,(proof, goals', sign))::tl)
+
+and auto_new_aux dbd width already_seen_goals universe = function
+  | [] -> []
+  | (subst,(proof, [], sign))::tl -> (subst,(proof, [], sign))::tl
+  | (subst,(proof, (goal,0)::_, _))::tl -> 
+      auto_new dbd width already_seen_goals universe tl
+  | (subst,(proof, goals, _))::tl when 
+      (List.length goals) > width -> 
+      auto_new dbd width already_seen_goals universe tl 
+  | (subst,(proof, (goal,depth)::gtl, sign))::tl -> 
+      let _,metasenv,p,_ = proof in
+      let (_, ey ,ty) = CicUtil.lookup_meta goal metasenv in
+      match (auto_single dbd proof goal ey ty depth
+        (width - (List.length gtl)) sign already_seen_goals) universe
+      with
+          [] -> auto_new dbd width already_seen_goals universe tl 
+        | (local_subst,(proof,[],sign))::tl1 -> 
+            let new_subst f t = f (subst t) in
+            let is_meta_closed = CicUtil.is_meta_closed ty in
+            let all_choices =
+              if is_meta_closed then 
+                (new_subst local_subst,(proof,gtl,sign))::tl
+              else
+                let tl2 = 
+                  (List.map 
+                     (function (f,(p,l,s)) -> (new_subst f,(p,l@gtl,s))) tl1)
+                in                         
+                  (new_subst local_subst,(proof,gtl,sign))::tl2@tl in
+              auto_new dbd width already_seen_goals universe all_choices
+        | _ -> assert false
+ ;; 
+
+let default_depth = 5
+let default_width = 3
+
+let auto_tac_old ?(depth=default_depth) ?(width=default_width) ~(dbd:HMysql.dbd)
+  ()
+=
+  let auto_tac dbd (proof,goal) =
+  let universe = MetadataQuery.signature_of_goal ~dbd (proof,goal) in
+  Hashtbl.clear inspected_goals;
+  debug_print (lazy "Entro in Auto");
+  let id t = t in
+  let t1 = Unix.gettimeofday () in
+  match auto_new dbd width [] universe [id,(proof, [(goal,depth)],None)] with
+      [] ->  debug_print (lazy "Auto failed");
+        raise (ProofEngineTypes.Fail (lazy "No Applicable theorem"))
+    | (_,(proof,[],_))::_ ->
+        let t2 = Unix.gettimeofday () in
+        debug_print (lazy "AUTO_TAC HA FINITO");
+        let _,_,p,_ = proof in
+        debug_print (lazy (CicPp.ppterm p));
+        Printf.printf "tempo: %.9f\n" (t2 -. t1);
+        (proof,[])
+    | _ -> assert false
+  in
+  auto_tac dbd
+;;
+
 let bool params name default =
     try 
       let s = List.assoc name params in 
@@ -59,6 +322,7 @@ let auto_tac ~params ~(dbd:HMysql.dbd) (proof, goal) =
   let int = int params 
   and string = string params 
   and bool = bool params in
+  let newauto = bool "new" false in
   let depth = int "depth" ((AutoTypes.default_flags()).AutoTypes.maxdepth) in
   let width = int "width" ((AutoTypes.default_flags()).AutoTypes.maxwidth) in
   let timeout = int "timeout" 0 in
@@ -70,12 +334,16 @@ let auto_tac ~params ~(dbd:HMysql.dbd) (proof, goal) =
   let table = string "table" "" in
   let subterms_only = bool "subterms_only" false in
   let demod_table = string "demod_table" "" in
+  let newauto = if use_only_paramod then true else newauto in
   match superposition with
   | true -> 
       (* this is the ugly hack to debug paramod *)
       Saturation.superposition_tac 
         ~target ~table ~subterms_only ~demod_table (proof,goal)
   | false -> 
+      if not newauto then 
+        auto_tac_old ~depth ~width ~dbd () (proof,goal)
+      else
       (* this is the real auto *)
       let _, metasenv, _, _ = proof in
       let _, context, goalty = CicUtil.lookup_meta goal metasenv in
index be68c31f750c4a1fb73b5c7fc03ee2b48b5d2566..246df0838ab36706b112b72659b7f0ea86d1e9bb 100644 (file)
@@ -192,7 +192,26 @@ let cmatch' =
 *)
 let apply_tac_verbose = PrimitiveTactics.apply_tac_verbose
 let cmatch' = Constr.cmatch'
-  
+
+(* used only by te old auto *)
+let signature_of_goal ~(dbd:HMysql.dbd) ((proof, goal) as _status) =
+ let (_, metasenv, _, _) = proof in
+ let (_, context, ty) = CicUtil.lookup_meta goal metasenv in
+ let main, sig_constants = Constr.signature_of ty in
+ let set = signature_of_hypothesis context metasenv in
+ let set =
+  match main with
+     None -> set
+   | Some (main,l) ->
+      List.fold_right Constr.UriManagerSet.add (main::l) set in
+ let set = Constr.UriManagerSet.union set sig_constants in
+ let all_constants_closed = close_with_types set metasenv context in
+ let uris =
+  sigmatch ~dbd ~facts:false ~where:`Statement (None,all_constants_closed) in
+ let uris = List.filter nonvar (List.map snd uris) in
+ let uris = List.filter Hashtbl_equiv.not_a_duplicate uris in
+  uris
+
 let is_predicate u = 
     let ty, _ = 
       try CicTypeChecker.type_of_aux' [] []
@@ -269,6 +288,7 @@ let filter_out_predicate set ctx menv =
 ;;
 
 let equations_for_goal ~(dbd:HMysql.dbd) ?signature ((proof, goal) as _status) =
+(*
   let to_string set =
     "{\n" ^
       (String.concat "\n"
@@ -276,6 +296,7 @@ let equations_for_goal ~(dbd:HMysql.dbd) ?signature ((proof, goal) as _status) =
             (fun u l -> ("  "^UriManager.string_of_uri u)::l) set []))
     ^ "\n}"
   in
+*)
  let (_, metasenv, _, _) = proof in
  let (_, context, ty) = CicUtil.lookup_meta goal metasenv in
  let main, sig_constants = 
index c260d5e991bbf899e02ca6ed2b85122d05fac3d8..496041554c307ba535d91cb5295932457c258009 100644 (file)
   * @param pat shell like pattern matching over object names, a string where "*"
   * is interpreted as 0 or more characters and "?" as exactly one character *)
 
+(* used only by the old auto *)
+val signature_of_goal:
+  dbd:HMysql.dbd -> ProofEngineTypes.status ->
+    UriManager.uri list
+
 val universe_of_goals:
   dbd:HMysql.dbd -> ProofEngineTypes.proof -> ProofEngineTypes.goal list ->
     UriManager.uri list
index fc9352e12395cbb117af7054f01b17bc41d1c38d..d0036e4a1fcc147add9d888f359ee80c090ccb09 100644 (file)
@@ -46,13 +46,13 @@ intros; apply divides_b_true_to_divides;
       [ apply (trans_lt ? (S O));
         [ unfold lt; apply le_n;
         | apply lt_SO_smallest_factor; assumption; ]
-      | letin x \def le.auto.
+      | letin x \def le.auto new.
          (*       
        apply divides_smallest_factor_n;
         apply (trans_lt ? (S O));
         [ unfold lt; apply le_n;
         | assumption; ] *) ] ]
-  | letin x \def prime. auto.
+  | letin x \def prime. auto new.
     (* 
     apply prime_to_nth_prime;
     apply prime_smallest_factor_n;
@@ -70,8 +70,8 @@ apply divides_to_divides_b_true.
 cut (prime (nth_prime (max_prime_factor n))).
 apply lt_O_nth_prime_n.apply prime_nth_prime.
 cut (nth_prime (max_prime_factor n) \divides n).
-auto.
-auto.
+auto new.
+auto new.
 (*
   [ apply (transitive_divides ? n);
     [ apply divides_max_prime_factor_n.
@@ -105,7 +105,7 @@ apply divides_max_prime_factor_n.
 assumption.unfold Not.
 intro.
 cut (r \mod (nth_prime (max_prime_factor n)) \neq O);
-  [unfold Not in Hcut1.auto.
+  [unfold Not in Hcut1.auto new.
     (*
     apply Hcut1.apply divides_to_mod_O;
     [ apply lt_O_nth_prime_n.
@@ -114,7 +114,7 @@ cut (r \mod (nth_prime (max_prime_factor n)) \neq O);
     *)
   |letin z \def le.
    cut(pair nat nat q r=p_ord_aux n n (nth_prime (max_prime_factor n)));
-   [2: rewrite < H1.assumption.|letin x \def le.auto width = 4]
+   [2: rewrite < H1.assumption.|letin x \def le.auto width = 4 new]
    (* CERCA COME MAI le_n non lo applica se lo trova come Const e non Rel *)
   ].
 (*