]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/ocaml/tactics/proofEngineReduction.ml
removed no longer used METAs
[helm.git] / helm / ocaml / tactics / proofEngineReduction.ml
index e7975793fa748d8d4f8cd46720f0aa7ec0b015ee..0dc4ce4ee3e617a1b1cb6a98efa6dc68db8e922b 100644 (file)
@@ -33,6 +33,7 @@
 (*                                                                            *)
 (******************************************************************************)
 
+(* $Id$ *)
 
 (* The code of this module is derived from the code of CicReduction *)
 
@@ -127,7 +128,7 @@ let replace ~equality ~what ~with_what ~where =
     function
        [],[] -> raise Not_found
      | what::tl1,with_what::tl2 ->
-        if equality t what then with_what else find_image_aux (tl1,tl2)
+        if equality what t then with_what else find_image_aux (tl1,tl2)
      | _,_ -> raise WhatAndWithWhatDoNotHaveTheSameLength
    in
     find_image_aux (what,with_what)
@@ -190,7 +191,7 @@ let replace_lifting ~equality ~what ~with_what ~where =
     function
        [],[] -> raise Not_found
      | what::tl1,with_what::tl2 ->
-        if equality t what then with_what else find_image_aux (tl1,tl2)
+        if equality what t then with_what else find_image_aux (tl1,tl2)
      | _,_ -> raise WhatAndWithWhatDoNotHaveTheSameLength
    in
     find_image_aux (what,with_what)
@@ -206,7 +207,7 @@ let replace_lifting ~equality ~what ~with_what ~where =
         List.map (function (uri,t) -> uri,substaux k what t) exp_named_subst
        in
         C.Var (uri,exp_named_subst')
-    | C.Meta (i, l) as t -> 
+    | C.Meta (i, l) -> 
        let l' =
         List.map
          (function
@@ -288,7 +289,7 @@ let replace_lifting_csc nnn ~equality ~what ~with_what ~where =
     function
        [],[] -> raise Not_found
      | what::tl1,with_what::tl2 ->
-        if equality t what then with_what else find_image_aux (tl1,tl2)
+        if equality what t then with_what else find_image_aux (tl1,tl2)
      | _,_ -> raise WhatAndWithWhatDoNotHaveTheSameLength
    in
     find_image_aux (what,with_what)
@@ -298,14 +299,14 @@ let replace_lifting_csc nnn ~equality ~what ~with_what ~where =
     S.lift (k-1) (find_image t)
    with Not_found ->
     match t with
-       C.Rel n as t ->
+       C.Rel n ->
         if n < k then C.Rel n else C.Rel (n + nnn)
      | C.Var (uri,exp_named_subst) ->
         let exp_named_subst' =
          List.map (function (uri,t) -> uri,substaux k t) exp_named_subst
         in
          C.Var (uri,exp_named_subst')
-     | C.Meta (i, l) as t -> 
+     | C.Meta (i, l) -> 
         let l' =
          List.map
           (function
@@ -389,15 +390,15 @@ let reduce context =
        let exp_named_subst' =
         reduceaux_exp_named_subst context l exp_named_subst
        in
-       (let o,_ = CicEnvironment.get_obj uri CicUniv.empty_ugraph in
+       (let o,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
         match o with
            C.Constant _ -> raise ReferenceToConstant
          | C.CurrentProof _ -> raise ReferenceToCurrentProof
          | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
-         | C.Variable (_,None,_,_) ->
+         | C.Variable (_,None,_,_,_) ->
             let t' = C.Var (uri,exp_named_subst') in
              if l = [] then t' else C.Appl (t'::l)
-         | C.Variable (_,Some body,_,_) ->
+         | C.Variable (_,Some body,_,_,_) ->
             (reduceaux context l
               (CicSubstitution.subst_vars exp_named_subst' body))
        )
@@ -430,16 +431,16 @@ let reduce context =
        let exp_named_subst' =
         reduceaux_exp_named_subst context l exp_named_subst
        in
-        (let o,_ = CicEnvironment.get_obj uri CicUniv.empty_ugraph in
+        (let o,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
          match o with
-            C.Constant (_,Some body,_,_) ->
+            C.Constant (_,Some body,_,_,_) ->
              (reduceaux context l
                (CicSubstitution.subst_vars exp_named_subst' body))
-          | C.Constant (_,None,_,_) ->
+          | C.Constant (_,None,_,_,_) ->
              let t' = C.Const (uri,exp_named_subst') in
               if l = [] then t' else C.Appl (t'::l)
           | C.Variable _ -> raise ReferenceToVariable
-          | C.CurrentProof (_,_,body,_,_) ->
+          | C.CurrentProof (_,_,body,_,_,_) ->
              (reduceaux context l
                (CicSubstitution.subst_vars exp_named_subst' body))
           | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
@@ -450,7 +451,7 @@ let reduce context =
        in
         let t' = C.MutInd (uri,i,exp_named_subst') in
          if l = [] then t' else C.Appl (t'::l)
-    | C.MutConstruct (uri,i,j,exp_named_subst) as t ->
+    | C.MutConstruct (uri,i,j,exp_named_subst) ->
        let exp_named_subst' =
         reduceaux_exp_named_subst context l exp_named_subst
        in
@@ -459,10 +460,7 @@ let reduce context =
     | C.MutCase (mutind,i,outtype,term,pl) ->
        let decofix =
         function
-           C.CoFix (i,fl) as t ->
-            let tys =
-             List.map (function (name,ty,_) -> Some (C.Name name, C.Decl ty)) fl
-            in
+           C.CoFix (i,fl) ->
              let (_,_,body) = List.nth fl i in
               let body' =
                let counter = ref (List.length fl) in
@@ -473,9 +471,6 @@ let reduce context =
               in
                reduceaux context [] body'
          | C.Appl (C.CoFix (i,fl) :: tl) ->
-            let tys =
-             List.map (function (name,ty,_) -> Some (C.Name name, C.Decl ty)) fl
-            in
              let (_,_,body) = List.nth fl i in
               let body' =
                let counter = ref (List.length fl) in
@@ -492,9 +487,9 @@ let reduce context =
             C.MutConstruct (_,_,j,_) -> reduceaux context l (List.nth pl (j-1))
           | C.Appl (C.MutConstruct (_,_,j,_) :: tl) ->
              let (arity, r) =
-              let o,_ = CicEnvironment.get_obj mutind CicUniv.empty_ugraph in
+              let o,_ = CicEnvironment.get_obj CicUniv.empty_ugraph mutind in
                 match o with
-                     C.InductiveDefinition (tl,_,r) ->
+                     C.InductiveDefinition (tl,_,r,_) ->
                        let (_,_,arity,_) = List.nth tl i in
                         (arity,r)
                   | _ -> raise WrongUriToInductiveDefinition
@@ -584,18 +579,21 @@ exception AlreadySimplified;;
 (* Takes a well-typed term and                                               *)
 (*  1) Performs beta-iota-zeta reduction until delta reduction is needed     *)
 (*  2) Attempts delta-reduction. If the residual is a Fix lambda-abstracted  *)
-(*     w.r.t. zero or more variables and if the Fix can be reduced, than it  *)
+(*     w.r.t. zero or more variables and if the Fix can be reductaed, than it*)
 (*     is reduced, the delta-reduction is succesfull and the whole algorithm *)
-(*     is applied again to the new redex; Step 3) is applied to the result   *)
+(*     is applied again to the new redex; Step 3.1) is applied to the result *)
 (*     of the recursive simplification. Otherwise, if the Fix can not be     *)
 (*     reduced, than the delta-reductions fails and the delta-redex is       *)
 (*     not reduced. Otherwise, if the delta-residual is not the              *)
-(*     lambda-abstraction of a Fix, then it is reduced and the result is     *)
-(*     directly returned, without performing step 3).                        *) 
-(*  3) Folds the application of the constant to the arguments that did not   *)
+(*     lambda-abstraction of a Fix, then it performs step 3.2).              *)
+(* 3.1) Folds the application of the constant to the arguments that did not  *)
 (*     change in every iteration, i.e. to the actual arguments for the       *)
 (*     lambda-abstractions that precede the Fix.                             *)
+(* 3.2) Computes the head beta-zeta normal form of the term. Then it tries   *)
+(*     reductions. If the reduction cannot be performed, it returns the      *)
+(*     original term (not the head beta-zeta normal form of the definiendum) *)
 (*CSC: It does not perform simplification in a Case *)
+
 let simpl context =
  (* reduceaux is equal to the reduceaux locally defined inside *)
  (* reduce, but for the const case.                            *) 
@@ -605,25 +603,21 @@ let simpl context =
   let module S = CicSubstitution in
    function
       C.Rel n as t ->
-       (match List.nth context (n-1) with
-           Some (_,C.Decl _) -> if l = [] then t else C.Appl (t::l)
-         | Some (_,C.Def (bo,_)) ->
-            try_delta_expansion l t (S.lift n bo)
-        | None -> raise RelToHiddenHypothesis
-       )
+       (* we never perform delta expansion automatically *)
+       if l = [] then t else C.Appl (t::l)
     | C.Var (uri,exp_named_subst) ->
        let exp_named_subst' =
         reduceaux_exp_named_subst context l exp_named_subst
        in
-        (let o,_ = CicEnvironment.get_obj uri CicUniv.empty_ugraph in
+        (let o,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
          match o with
             C.Constant _ -> raise ReferenceToConstant
           | C.CurrentProof _ -> raise ReferenceToCurrentProof
           | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
-          | C.Variable (_,None,_,_) ->
+          | C.Variable (_,None,_,_,_) ->
             let t' = C.Var (uri,exp_named_subst') in
              if l = [] then t' else C.Appl (t'::l)
-          | C.Variable (_,Some body,_,_) ->
+          | C.Variable (_,Some body,_,_,_) ->
              reduceaux context l
               (CicSubstitution.subst_vars exp_named_subst' body)
         )
@@ -631,7 +625,7 @@ let simpl context =
     | C.Sort _ as t -> t (* l should be empty *)
     | C.Implicit _ as t -> t
     | C.Cast (te,ty) ->
-       C.Cast (reduceaux context l te, reduceaux context l ty)
+       C.Cast (reduceaux context l te, reduceaux context [] ty)
     | C.Prod (name,s,t) ->
        assert (l = []) ;
        C.Prod (name,
@@ -656,17 +650,17 @@ let simpl context =
        let exp_named_subst' =
         reduceaux_exp_named_subst context l exp_named_subst
        in
-        (let o,_ = CicEnvironment.get_obj uri CicUniv.empty_ugraph in
+        (let o,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
          match o with
-           C.Constant (_,Some body,_,_) ->
-            try_delta_expansion l
+           C.Constant (_,Some body,_,_,_) ->
+            try_delta_expansion context l
              (C.Const (uri,exp_named_subst'))
              (CicSubstitution.subst_vars exp_named_subst' body)
-         | C.Constant (_,None,_,_) ->
+         | C.Constant (_,None,_,_,_) ->
             let t' = C.Const (uri,exp_named_subst') in
              if l = [] then t' else C.Appl (t'::l)
          | C.Variable _ -> raise ReferenceToVariable
-         | C.CurrentProof (_,_,body,_,_) -> reduceaux context l body
+         | C.CurrentProof (_,_,body,_,_,_) -> reduceaux context l body
          | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
        )
     | C.MutInd (uri,i,exp_named_subst) ->
@@ -684,9 +678,7 @@ let simpl context =
     | C.MutCase (mutind,i,outtype,term,pl) ->
        let decofix =
         function
-           C.CoFix (i,fl) as t ->
-            let tys =
-             List.map (function (name,ty,_) -> Some (C.Name name, C.Decl ty)) fl            in
+           C.CoFix (i,fl) ->
              let (_,_,body) = List.nth fl i in
               let body' =
                let counter = ref (List.length fl) in
@@ -697,27 +689,25 @@ let simpl context =
               in
                reduceaux context [] body'
          | C.Appl (C.CoFix (i,fl) :: tl) ->
-            let tys =
-             List.map (function (name,ty,_) -> Some (C.Name name, C.Decl ty)) fl            in
              let (_,_,body) = List.nth fl i in
-              let body' =
-               let counter = ref (List.length fl) in
-                List.fold_right
-                 (fun _ -> decr counter ; S.subst (C.CoFix (!counter,fl)))
-                 fl
-                 body
-              in
-               let tl' = List.map (reduceaux context []) tl in
-                reduceaux context tl body'
+             let body' =
+              let counter = ref (List.length fl) in
+               List.fold_right
+                (fun _ -> decr counter ; S.subst (C.CoFix (!counter,fl)))
+                fl
+                body
+             in
+              let tl' = List.map (reduceaux context []) tl in
+               reduceaux context tl' body'
          | t -> t
        in
-        (match decofix (reduceaux context [] term) with
+        (match decofix (CicReduction.whd context term) with
             C.MutConstruct (_,_,j,_) -> reduceaux context l (List.nth pl (j-1))
           | C.Appl (C.MutConstruct (_,_,j,_) :: tl) ->
              let (arity, r) =
-              let o,_ = CicEnvironment.get_obj mutind CicUniv.empty_ugraph in
+              let o,_ = CicEnvironment.get_obj CicUniv.empty_ugraph mutind in
                 match o with
-                     C.InductiveDefinition (tl,ingredients,r) ->
+                     C.InductiveDefinition (tl,ingredients,r,_) ->
                        let (_,_,arity,_) = List.nth tl i in
                         (arity,r)
                   | _ -> raise WrongUriToInductiveDefinition
@@ -798,14 +788,14 @@ let simpl context =
  and reduceaux_exp_named_subst context l =
   List.map (function uri,t -> uri,reduceaux context [] t)
  (**** Step 2 ****)
- and try_delta_expansion l term body =
+ and try_delta_expansion context l term body =
   let module C = Cic in
   let module S = CicSubstitution in
    try
     let res,constant_args =
      let rec aux rev_constant_args l =
       function
-         C.Lambda (name,s,t) as t' ->
+         C.Lambda (name,s,t) ->
           begin
            match l with
               [] -> raise WrongShape
@@ -816,11 +806,7 @@ let simpl context =
           end
        | C.LetIn (_,s,t) ->
           aux rev_constant_args l (S.subst s t)
-       | C.Fix (i,fl) as t ->
-          let tys =
-           List.map (function (name,_,ty,_) ->
-            Some (C.Name name, C.Decl ty)) fl
-          in
+       | C.Fix (i,fl) ->
            let (_,recindex,_,body) = List.nth fl i in
             let recparam =
              try
@@ -848,7 +834,7 @@ let simpl context =
      in
       aux [] l body
     in
-     (**** Step 3 ****)
+     (**** Step 3.1 ****)
      let term_to_fold, delta_expanded_term_to_fold =
       match constant_args with
          [] -> term,body
@@ -860,9 +846,28 @@ let simpl context =
        replace (=) [simplified_term_to_fold] [term_to_fold] res
    with
       WrongShape ->
-       (* The constant does not unfold to a Fix lambda-abstracted  *)
-       (* w.r.t. zero or more variables. We just perform reduction.*)
-       reduceaux context l body
+       (**** Step 3.2 ****)
+       let rec aux l =
+        function
+           C.Lambda (name,s,t) ->
+             (match l with
+                [] -> raise AlreadySimplified
+              | he::tl ->
+                 (* when name is Anonimous the substitution should *)
+                 (* be superfluous                                 *)
+                 aux tl (S.subst he t))
+         | C.LetIn (_,s,t) -> aux l (S.subst s t)
+         | t ->
+            let simplified = reduceaux context l t in
+            if t = simplified then
+             raise AlreadySimplified
+            else
+             simplified
+       in
+        (try aux l body
+         with
+          AlreadySimplified ->
+           if l = [] then term else C.Appl (term::l))
     | AlreadySimplified ->
        (* If we performed delta-reduction, we would find a Fix   *)
        (* not applied to a constructor. So, we refuse to perform *)
@@ -871,3 +876,90 @@ let simpl context =
  in
   reduceaux context []
 ;;
+
+let unfold ?what context where =
+ let contextlen = List.length context in
+ let first_is_the_expandable_head_of_second context' t1 t2 =
+  match t1,t2 with
+     Cic.Const (uri,_), Cic.Const (uri',_)
+   | Cic.Var (uri,_), Cic.Var (uri',_)
+   | Cic.Const (uri,_), Cic.Appl (Cic.Const (uri',_)::_)
+   | Cic.Var (uri,_), Cic.Appl (Cic.Var (uri',_)::_) -> UriManager.eq uri uri'
+   | Cic.Const _, _
+   | Cic.Var _, _ -> false
+   | Cic.Rel n, Cic.Rel m
+   | Cic.Rel n, Cic.Appl (Cic.Rel m::_) ->
+      n + (List.length context' - contextlen) = m
+   | Cic.Rel _, _ -> false
+   | _,_ ->
+     raise
+      (ProofEngineTypes.Fail
+        (lazy "The term to unfold is not a constant, a variable or a bound variable "))
+ in
+ let appl he tl =
+  if tl = [] then he else Cic.Appl (he::tl) in
+ let cannot_delta_expand t =
+  raise
+   (ProofEngineTypes.Fail
+     (lazy ("The term " ^ CicPp.ppterm t ^ " cannot be delta-expanded"))) in
+ let rec hd_delta_beta context tl =
+  function
+    Cic.Rel n as t ->
+     (try
+       match List.nth context (n-1) with
+          Some (_,Cic.Decl _) -> cannot_delta_expand t
+        | Some (_,Cic.Def (bo,_)) ->
+           CicReduction.head_beta_reduce
+            (appl (CicSubstitution.lift n bo) tl)
+        | None -> raise RelToHiddenHypothesis
+      with
+         Failure _ -> assert false)
+  | Cic.Const (uri,exp_named_subst) as t ->
+     let o,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
+      (match o with
+          Cic.Constant (_,Some body,_,_,_) ->
+           CicReduction.head_beta_reduce
+            (appl (CicSubstitution.subst_vars exp_named_subst body) tl)
+        | Cic.Constant (_,None,_,_,_) -> cannot_delta_expand t
+        | Cic.Variable _ -> raise ReferenceToVariable
+        | Cic.CurrentProof _ -> raise ReferenceToCurrentProof
+        | Cic.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
+      )
+  | Cic.Var (uri,exp_named_subst) as t ->
+     let o,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
+      (match o with
+          Cic.Constant _ -> raise ReferenceToConstant
+        | Cic.CurrentProof _ -> raise ReferenceToCurrentProof
+        | Cic.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
+        | Cic.Variable (_,Some body,_,_,_) ->
+           CicReduction.head_beta_reduce
+            (appl (CicSubstitution.subst_vars exp_named_subst body) tl)
+        | Cic.Variable (_,None,_,_,_) -> cannot_delta_expand t
+      )
+   | Cic.Appl [] -> assert false
+   | Cic.Appl (he::tl) -> hd_delta_beta context tl he
+   | t -> cannot_delta_expand t
+ in
+ let context_and_matched_term_list =
+  match what with
+     None -> [context, where]
+   | Some what ->
+      let res =
+       ProofEngineHelpers.locate_in_term
+        ~equality:first_is_the_expandable_head_of_second
+        what ~where context
+      in
+       if res = [] then
+        raise
+         (ProofEngineTypes.Fail
+           (lazy ("Term "^ CicPp.ppterm what ^ " not found in " ^ CicPp.ppterm where)))
+       else
+        res
+ in
+  let reduced_terms =
+   List.map
+    (function (context,where) -> hd_delta_beta context [] where)
+    context_and_matched_term_list in
+  let whats = List.map snd context_and_matched_term_list in
+   replace ~equality:(==) ~what:whats ~with_what:reduced_terms ~where
+;;