]> matita.cs.unibo.it Git - helm.git/commitdiff
Two bugs fixed in the apply tactic:
authorClaudio Sacerdoti Coen <claudio.sacerdoticoen@unibo.it>
Tue, 13 Sep 2005 11:56:42 +0000 (11:56 +0000)
committerClaudio Sacerdoti Coen <claudio.sacerdoticoen@unibo.it>
Tue, 13 Sep 2005 11:56:42 +0000 (11:56 +0000)
 1. an application of a term of type t where t reduces to a product does not
    fail any longer: t is unfolded as required to produce enough products.
    E.g. apply (t: ~A) when the goal is False
 2. the apply tactic does not fail any longer when the goal is a product.
    When the head of the type of the term is flexible, the type is a product
    and the goal is a product (e.g. t: A -> ? vs A' -> B) the less instantiated
    term (i.e. t) is tried first; in case of failure (e.g. A not unifiable with
    A') t is instantiated adding one metavariable after another.

helm/ocaml/paramodulation/inference.ml
helm/ocaml/tactics/equalityTactics.ml
helm/ocaml/tactics/primitiveTactics.ml
helm/ocaml/tactics/proofEngineHelpers.ml
helm/ocaml/tactics/proofEngineHelpers.mli

index e92117334acb7cf22964be509ca75d7887ea671b..969d412cef43a28151e995250fdf10d2adc172c4 100644 (file)
@@ -1055,7 +1055,7 @@ let find_equalities ?(eq_uri=HelmLibraryObjects.Logic.eq_URI) context proof =
 (*               let newmeta = ProofEngineHelpers.new_meta_of_proof ~proof in *)
               let (head, newmetas, args, newmeta) =
                 ProofEngineHelpers.saturate_term newmeta []
-                  context (S.lift index term)
+                  context (S.lift index term) 0
               in
               let p =
                 if List.length args = 0 then
@@ -1161,7 +1161,7 @@ let find_library_equalities ~(dbd:Mysql.dbd) context status maxmeta =
           match termty with
           | C.Prod (name, s, t) ->
               let head, newmetas, args, newmeta =
-                ProofEngineHelpers.saturate_term newmeta [] context termty
+                ProofEngineHelpers.saturate_term newmeta [] context termty 0
               in
               let p =
                 if List.length args = 0 then
index 94cb0624bacd7911e184631750ef5fb97b7bc3a4..c56d3de2d75af9c4566d19a98ff568104c4d4699 100644 (file)
@@ -47,7 +47,7 @@ let rewrite_tac ~direction ~pattern equality =
       CicUniv.empty_ugraph in 
   let (ty_eq,metasenv',arguments,fresh_meta) =
    ProofEngineHelpers.saturate_term
-    (ProofEngineHelpers.new_meta_of_proof proof) metasenv context ty_eq in
+    (ProofEngineHelpers.new_meta_of_proof proof) metasenv context ty_eq in
   let equality =
    if List.length arguments = 0 then
     equality
index c43034f93dfd7f672ade503c0723e9474bd021ea..97f40205201446fdf82cebd6ad5a67278edec6c7 100644 (file)
@@ -223,9 +223,9 @@ let
     new_fresh_meta,newmetasenvfragment,exp_named_subst',exp_named_subst_diff
 ;;
 
-let new_metasenv_and_unify_and_t newmeta' metasenv' context term' ty termty =
+let new_metasenv_and_unify_and_t newmeta' metasenv' context term' ty termty goal_arity =
   let (consthead,newmetasenv,arguments,_) =
-   saturate_term newmeta' metasenv' context termty in
+   saturate_term newmeta' metasenv' context termty goal_arity in
   let subst,newmetasenv',_ = 
    CicUnification.fo_unif newmetasenv context consthead ty CicUniv.empty_ugraph
   in
@@ -234,6 +234,11 @@ let new_metasenv_and_unify_and_t newmeta' metasenv' context term' ty termty =
   in
   subst,newmetasenv',t
 
+let rec count_prods context ty =
+ match CicReduction.whd context ty with
+    Cic.Prod (n,s,t) -> 1 + count_prods (Some (n,Cic.Decl s)::context) t
+  | _ -> 0
+
 let apply_tac_verbose ~term (proof, goal) =
   (* Assumption: The term "term" must be closed in the current context *)
  let module T = CicTypeChecker in
@@ -278,18 +283,17 @@ let apply_tac_verbose ~term (proof, goal) =
    let termty,_ = 
      CicTypeChecker.type_of_aux' metasenv' context term' CicUniv.empty_ugraph in
    let termty =
-     CicSubstitution.subst_vars exp_named_subst_diff termty
-   in
-(*CSC: this code is suspect and/or bugged: we try first without reduction
-  and then using whd. However, the saturate_term always tries with full
-  reduction without delta. *)
+     CicSubstitution.subst_vars exp_named_subst_diff termty in
+   let goal_arity = count_prods context ty in
    let subst,newmetasenv',t = 
-    try
+    let rec add_one_argument n =
+     try
       new_metasenv_and_unify_and_t newmeta' metasenv' context term' ty
-        termty
-    with CicUnification.UnificationFailure _ ->
-      new_metasenv_and_unify_and_t newmeta' metasenv' context term' ty
-        (CicReduction.whd context termty)
+        termty n
+     with CicUnification.UnificationFailure _ when n > 0 ->
+      add_one_argument (n - 1)
+    in
+     add_one_argument goal_arity
    in
    let in_subst_domain i = List.exists (function (j,_) -> i=j) subst in
    let apply_subst = CicMetaSubst.apply_subst subst in
@@ -457,7 +461,7 @@ let elim_tac ~term =
     let termty,_ = T.type_of_aux' metasenv context term CicUniv.empty_ugraph in
     let (termty,metasenv',arguments,fresh_meta) =
      ProofEngineHelpers.saturate_term
-      (ProofEngineHelpers.new_meta_of_proof proof) metasenv context termty in
+      (ProofEngineHelpers.new_meta_of_proof proof) metasenv context termty in
     let term = if arguments = [] then term else Cic.Appl (term::arguments) in
     let uri,exp_named_subst,typeno,args =
      match termty with
index a7c1d39bd1953073fff0228f9556c59210047599..23aa20bfb50cb30d4483e5fd2c04400281ce7934 100644 (file)
@@ -608,17 +608,18 @@ let locate_in_conjecture ?(equality=fun _ -> (==)) what (_,context,ty) =
  in
   res @ locate_in_term what ~where:ty context
 
-(* saturate_term newmeta metasenv context ty                                  *)
-(* Given a type [ty] (a backbone), it returns its head and a new metasenv in  *)
-(* which there is new a META for each hypothesis, a list of arguments for the *)
-(* new applications and the index of the last new META introduced. The nth    *)
-(* argument in the list of arguments is just the nth new META.                *)
-let saturate_term newmeta metasenv context ty =
+(* saturate_term newmeta metasenv context ty goal_arity                       *)
+(* Given a type [ty] (a backbone), it returns its suffix of length            *)
+(* [goal_arity] head and a new metasenv in which there is new a META for each *)
+(* hypothesis, a list of arguments for the new applications and the index of  *)
+(* the last new META introduced. The nth argument in the list of arguments is *)
+(* just the nth new META.                                                     *)
+let saturate_term newmeta metasenv context ty goal_arity =
  let module C = Cic in
  let module S = CicSubstitution in
+ assert (goal_arity >= 0);
   let rec aux newmeta ty =
-   let ty' = ty in
-   match ty' with
+   match ty with
       C.Cast (he,_) -> aux newmeta he
 (* CSC: patch to generate ?1 : ?2 : Type in place of ?1 : Type to simulate ?1 :< Type
       (* If the expected type is a Type, then also Set is OK ==>
@@ -643,22 +644,31 @@ let saturate_term newmeta metasenv context ty =
          CicMkImplicit.identity_relocation_list_for_metavariable context
        in
         let newargument = C.Meta (newmeta,irl) in
-         let (res,newmetasenv,arguments,lastmeta) =
+         let res,newmetasenv,arguments,lastmeta,prod_no =
           aux (newmeta + 1) (S.subst newargument t)
          in
-         let s' = CicReduction.normalize ~delta:false context s in
-          res,(newmeta,context,s')::newmetasenv,newargument::arguments,lastmeta
-          (** NORMALIZE RATIONALE 
-           * we normalize the target only NOW since we may be in this case:
-           * A1 -> A2 -> T where T = (\lambda x.A3 -> P) k  
-           * and we want a mesasenv with ?1:A1 and ?2:A2 and not
-           * ?1, ?2, ?3 (that is the one we whould get if we start from the
-           * beta-normalized A1 -> A2 -> A3 -> P **)
-    | t -> (CicReduction.normalize ~delta:false context t),[],[],newmeta
+          if prod_no + 1 = goal_arity then
+           let head = CicReduction.normalize ~delta:false context ty in
+            head,[],[],newmeta,goal_arity + 1
+          else
+           (** NORMALIZE RATIONALE 
+            * we normalize the target only NOW since we may be in this case:
+            * A1 -> A2 -> T where T = (\lambda x.A3 -> P) k  
+            * and we want a mesasenv with ?1:A1 and ?2:A2 and not
+            * ?1, ?2, ?3 (that is the one we whould get if we start from the
+            * beta-normalized A1 -> A2 -> A3 -> P **)
+           let s' = CicReduction.normalize ~delta:false context s in
+            res,(newmeta,context,s')::newmetasenv,newargument::arguments,
+             lastmeta,prod_no + 1
+    | t ->
+       let head = CicReduction.normalize ~delta:false context t in
+        match CicReduction.whd context head with
+           C.Prod _ as head' -> aux newmeta head'
+         | _ -> head,[],[],newmeta,0
   in
    (* WARNING: here we are using the invariant that above the most *)
    (* recente new_meta() there are no used metas.                  *)
-   let (res,newmetasenv,arguments,lastmeta) = aux newmeta ty in
+   let res,newmetasenv,arguments,lastmeta,_ = aux newmeta ty in
     res,metasenv @ newmetasenv,arguments,lastmeta
 
 let lookup_type metasenv context hyp =
index 6d1c7ffaa102a984ec8edef5fab9d0749c9dcbaa..a7603d3a528bd54d978768892725aa1178ad279b 100644 (file)
@@ -103,13 +103,14 @@ val locate_in_conjecture:
  ?equality:(Cic.context -> Cic.term -> Cic.term -> bool) ->
   Cic.term -> Cic.conjecture -> (Cic.context * Cic.term) list
 
-(* saturate_term newmeta metasenv context ty                                  *)
-(* Given a type [ty] (a backbone), it returns its head and a new metasenv in  *)
-(* which there is new a META for each hypothesis, a list of arguments for the *)
-(* new applications and the index of the last new META introduced. The nth    *)
-(* argument in the list of arguments is just the nth new META.                *)
+(* saturate_term newmeta metasenv context ty goal_arity                       *)
+(* Given a type [ty] (a backbone), it returns its suffix of length            *)
+(* [goal_arity] head and a new metasenv in which there is new a META for each *)
+(* hypothesis, a list of arguments for the new applications and the index of  *)
+(* the last new META introduced. The nth argument in the list of arguments is *)
+(* just the nth new META.                                                     *)
 val saturate_term:
- int -> Cic.metasenv -> Cic.context -> Cic.term ->
+ int -> Cic.metasenv -> Cic.context -> Cic.term -> int ->
   Cic.term * Cic.metasenv * Cic.term list * int
 
 (* returns the index and the type of a premise in a context *)