]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/gTopLevel/proofEngineReduction.ml
Many many improvements:
[helm.git] / helm / gTopLevel / proofEngineReduction.ml
index 94e5b353de3534df42cba3016327de56abffdd6c..7d4a799601dad71082943a92b5685480996b60da 100644 (file)
@@ -43,13 +43,14 @@ exception ReferenceToVariable;;
 exception ReferenceToCurrentProof;;
 exception ReferenceToInductiveDefinition;;
 exception WrongUriToInductiveDefinition;;
+exception RelToHiddenHypothesis;;
 
 (* "textual" replacement of a subterm with another one *)
-let replace ~what ~with_what ~where =
+let replace ~equality ~what ~with_what ~where =
  let module C = Cic in
   let rec aux =
    function
-      t when t = what -> with_what
+      t when (equality t what) -> with_what
     | C.Rel _ as t -> t
     | C.Var _ as t  -> t
     | C.Meta _ as t -> t
@@ -92,11 +93,16 @@ let replace ~what ~with_what ~where =
 (* Takes a well-typed term and fully reduces it. *)
 (*CSC: It does not perform reduction in a Case *)
 let reduce context =
- let rec reduceaux l =
+ let rec reduceaux context l =
   let module C = Cic in
   let module S = CicSubstitution in
    function
-      C.Rel _ as t -> if l = [] then t else C.Appl (t::l)
+      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) -> reduceaux context l (S.lift n bo)
+        | None -> raise RelToHiddenHypothesis
+       )
     | C.Var uri as t ->
        (match CicEnvironment.get_cooked_obj uri 0 with
            C.Definition _ -> raise ReferenceToDefinition
@@ -104,32 +110,39 @@ let reduce context =
          | C.CurrentProof _ -> raise ReferenceToCurrentProof
          | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
          | C.Variable (_,None,_) -> if l = [] then t else C.Appl (t::l)
-         | C.Variable (_,Some body,_) -> reduceaux l body
+         | C.Variable (_,Some body,_) -> reduceaux context l body
        )
     | C.Meta _ as t -> if l = [] then t else C.Appl (t::l)
     | C.Sort _ as t -> t (* l should be empty *)
     | C.Implicit as t -> t
-    | C.Cast (te,ty) -> reduceaux l te  (*CSC E' GIUSTO BUTTARE IL CAST? *)
+    | C.Cast (te,ty) ->
+       C.Cast (reduceaux context l te, reduceaux context l ty)
     | C.Prod (name,s,t) ->
        assert (l = []) ;
-       C.Prod (name, reduceaux [] s, reduceaux [] t)
+       C.Prod (name,
+        reduceaux context [] s,
+        reduceaux ((Some (name,C.Decl s))::context) [] t)
     | C.Lambda (name,s,t) ->
        (match l with
-           [] -> C.Lambda (name, reduceaux [] s, reduceaux [] t)
-         | he::tl -> reduceaux tl (S.subst he t)
+           [] ->
+            C.Lambda (name,
+             reduceaux context [] s,
+             reduceaux ((Some (name,C.Decl s))::context) [] t)
+         | he::tl -> reduceaux context tl (S.subst he t)
            (* when name is Anonimous the substitution should be superfluous *)
        )
-    | C.LetIn (n,s,t) -> reduceaux l (S.subst (reduceaux [] s) t)
+    | C.LetIn (n,s,t) ->
+       reduceaux context l (S.subst (reduceaux context [] s) t)
     | C.Appl (he::tl) ->
-       let tl' = List.map (reduceaux []) tl in
-        reduceaux (tl'@l) he
+       let tl' = List.map (reduceaux context []) tl in
+        reduceaux context (tl'@l) he
     | C.Appl [] -> raise (Impossible 1)
     | C.Const (uri,cookingsno) as t ->
        (match CicEnvironment.get_cooked_obj uri cookingsno with
-           C.Definition (_,body,_,_) -> reduceaux l body
+           C.Definition (_,body,_,_) -> reduceaux context l body
          | C.Axiom _ -> if l = [] then t else C.Appl (t::l)
          | C.Variable _ -> raise ReferenceToVariable
-         | C.CurrentProof (_,_,body,_) -> reduceaux l body
+         | C.CurrentProof (_,_,body,_) -> reduceaux context l body
          | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
        )
     | C.Abst _ as t -> t (*CSC l should be empty ????? *)
@@ -139,30 +152,36 @@ let reduce context =
        let decofix =
         function
            C.CoFix (i,fl) as t ->
-            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
-              reduceaux [] body'
+            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
+               reduceaux (tys@context) [] body'
          | C.Appl (C.CoFix (i,fl) :: tl) ->
-            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 []) tl in
-               reduceaux tl body'
+            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 (tys@context) tl' body'
          | t -> t
        in
-        (match decofix (reduceaux [] term) with
-            C.MutConstruct (_,_,_,j) -> reduceaux l (List.nth pl (j-1))
+        (match decofix (reduceaux context [] term) with
+            C.MutConstruct (_,_,_,j) -> reduceaux context l (List.nth pl (j-1))
           | C.Appl (C.MutConstruct (_,_,_,j) :: tl) ->
              let (arity, r, num_ingredients) =
               match CicEnvironment.get_obj mutind with
@@ -187,66 +206,72 @@ let reduce context =
                 in
                  eat_first (num_to_eat,tl)
               in
-               reduceaux (ts@l) (List.nth pl (j-1))
+               reduceaux context (ts@l) (List.nth pl (j-1))
          | C.Abst _ | C.Cast _ | C.Implicit ->
             raise (Impossible 2) (* we don't trust our whd ;-) *)
          | _ ->
-           let outtype' = reduceaux [] outtype in
-           let term' = reduceaux [] term in
-           let pl' = List.map (reduceaux []) pl in
+           let outtype' = reduceaux context [] outtype in
+           let term' = reduceaux context [] term in
+           let pl' = List.map (reduceaux context []) pl in
             let res =
              C.MutCase (mutind,cookingsno,i,outtype',term',pl')
             in
              if l = [] then res else C.Appl (res::l)
        )
     | C.Fix (i,fl) ->
-       let t' () =
-        let fl' =
-         List.map
-          (function (n,recindex,ty,bo) ->
-            (n,recindex,reduceaux [] ty, reduceaux [] bo)
-          ) fl
-        in
-         C.Fix (i, fl')
+       let tys =
+        List.map (function (name,_,ty,_) -> Some (C.Name name, C.Decl ty)) fl
        in
-        let (_,recindex,_,body) = List.nth fl i in
-         let recparam =
-          try
-           Some (List.nth l recindex)
-          with
-           _ -> None
+        let t' () =
+         let fl' =
+          List.map
+           (function (n,recindex,ty,bo) ->
+             (n,recindex,reduceaux context [] ty, reduceaux (tys@context) [] bo)
+           ) fl
          in
-          (match recparam with
-              Some recparam ->
-               (match reduceaux [] recparam with
-                   C.MutConstruct _
-                 | C.Appl ((C.MutConstruct _)::_) ->
-                    let body' =
-                     let counter = ref (List.length fl) in
-                      List.fold_right
-                       (fun _ -> decr counter ; S.subst (C.Fix (!counter,fl)))
-                       fl
-                       body
-                    in
-                     (* Possible optimization: substituting whd recparam in l *)
-                     reduceaux l body'
-                 | _ -> if l = [] then t' () else C.Appl ((t' ())::l)
-               )
-            | None -> if l = [] then t' () else C.Appl ((t' ())::l)
-          )
-    | C.CoFix (i,fl) ->
-       let t' =
-        let fl' =
-         List.map
-          (function (n,ty,bo) ->
-            (n,reduceaux [] ty, reduceaux [] bo)
-          ) fl
+          C.Fix (i, fl')
         in
-         C.CoFix (i, fl')
+         let (_,recindex,_,body) = List.nth fl i in
+          let recparam =
+           try
+            Some (List.nth l recindex)
+           with
+            _ -> None
+          in
+           (match recparam with
+               Some recparam ->
+                (match reduceaux context [] recparam with
+                    C.MutConstruct _
+                  | C.Appl ((C.MutConstruct _)::_) ->
+                     let body' =
+                      let counter = ref (List.length fl) in
+                       List.fold_right
+                        (fun _ -> decr counter ; S.subst (C.Fix (!counter,fl)))
+                        fl
+                        body
+                     in
+                      (* Possible optimization: substituting whd recparam in l*)
+                      reduceaux context l body'
+                  | _ -> if l = [] then t' () else C.Appl ((t' ())::l)
+                )
+             | None -> if l = [] then t' () else C.Appl ((t' ())::l)
+           )
+    | C.CoFix (i,fl) ->
+       let tys =
+        List.map (function (name,ty,_) -> Some (C.Name name, C.Decl ty)) fl
        in
-        if l = [] then t' else C.Appl (t'::l)
+        let t' =
+         let fl' =
+          List.map
+           (function (n,ty,bo) ->
+             (n,reduceaux context [] ty, reduceaux (tys@context) [] bo)
+           ) fl
+         in
+          C.CoFix (i, fl')
+        in
+         if l = [] then t' else C.Appl (t'::l)
  in
-  reduceaux []
+  reduceaux context []
 ;;
 
 exception WrongShape;;
@@ -278,11 +303,16 @@ let simpl context =
  (* reduceaux is equal to the reduceaux locally defined inside *)
  (*reduce, but for the const case.                             *) 
  (**** Step 1 ****)
- let rec reduceaux l =
+ let rec reduceaux context l =
   let module C = Cic in
   let module S = CicSubstitution in
    function
-      C.Rel _ as t -> if l = [] then t else C.Appl (t::l)
+      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) -> reduceaux context l (S.lift n bo)
+        | None -> raise RelToHiddenHypothesis
+       )
     | C.Var uri as t ->
        (match CicEnvironment.get_cooked_obj uri 0 with
            C.Definition _ -> raise ReferenceToDefinition
@@ -290,25 +320,32 @@ let simpl context =
          | C.CurrentProof _ -> raise ReferenceToCurrentProof
          | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
          | C.Variable (_,None,_) -> if l = [] then t else C.Appl (t::l)
-         | C.Variable (_,Some body,_) -> reduceaux l body
+         | C.Variable (_,Some body,_) -> reduceaux context l body
        )
     | C.Meta _ as t -> if l = [] then t else C.Appl (t::l)
     | C.Sort _ as t -> t (* l should be empty *)
     | C.Implicit as t -> t
-    | C.Cast (te,ty) -> reduceaux l te  (*CSC E' GIUSTO BUTTARE IL CAST? *)
+    | C.Cast (te,ty) ->
+       C.Cast (reduceaux context l te, reduceaux context l ty)
     | C.Prod (name,s,t) ->
        assert (l = []) ;
-       C.Prod (name, reduceaux [] s, reduceaux [] t)
+       C.Prod (name,
+        reduceaux context [] s,
+        reduceaux ((Some (name,C.Decl s))::context) [] t)
     | C.Lambda (name,s,t) ->
        (match l with
-           [] -> C.Lambda (name, reduceaux [] s, reduceaux [] t)
-         | he::tl -> reduceaux tl (S.subst he t)
+           [] ->
+            C.Lambda (name,
+             reduceaux context [] s,
+             reduceaux ((Some (name,C.Decl s))::context) [] t)
+         | he::tl -> reduceaux context tl (S.subst he t)
            (* when name is Anonimous the substitution should be superfluous *)
        )
-    | C.LetIn (n,s,t) -> reduceaux l (S.subst (reduceaux [] s) t)
+    | C.LetIn (n,s,t) ->
+       reduceaux context l (S.subst (reduceaux context [] s) t)
     | C.Appl (he::tl) ->
-       let tl' = List.map (reduceaux []) tl in
-        reduceaux (tl'@l) he
+       let tl' = List.map (reduceaux context []) tl in
+        reduceaux context (tl'@l) he
     | C.Appl [] -> raise (Impossible 1)
     | C.Const (uri,cookingsno) as t ->
        (match CicEnvironment.get_cooked_obj uri cookingsno with
@@ -330,28 +367,33 @@ let simpl context =
                     end
                  | C.LetIn (_,_,_) -> raise WhatShouldIDo (*CSC: ?????????? *)
                  | C.Fix (i,fl) as t ->
-                    let (_,recindex,_,body) = List.nth fl i in
-                     let recparam =
-                      try
-                       List.nth l recindex
-                      with
-                       _ -> raise AlreadySimplified
-                     in
-                      (match CicReduction.whd context recparam with
-                          C.MutConstruct _
-                        | C.Appl ((C.MutConstruct _)::_) ->
-                           let body' =
-                            let counter = ref (List.length fl) in
-                             List.fold_right
-                              (function _ ->
-                                decr counter ; S.subst (C.Fix (!counter,fl))
-                              ) fl body
-                           in
-                            (* Possible optimization: substituting whd *)
-                            (* recparam in l                           *)
-                            reduceaux l body', List.rev rev_constant_args
-                        | _ -> raise AlreadySimplified
-                      )
+                    let tys =
+                     List.map (function (name,_,ty,_) ->
+                      Some (C.Name name, C.Decl ty)) fl
+                    in
+                     let (_,recindex,_,body) = List.nth fl i in
+                      let recparam =
+                       try
+                        List.nth l recindex
+                       with
+                        _ -> raise AlreadySimplified
+                      in
+                       (match CicReduction.whd context recparam with
+                           C.MutConstruct _
+                         | C.Appl ((C.MutConstruct _)::_) ->
+                            let body' =
+                             let counter = ref (List.length fl) in
+                              List.fold_right
+                               (function _ ->
+                                 decr counter ; S.subst (C.Fix (!counter,fl))
+                               ) fl body
+                            in
+                             (* Possible optimization: substituting whd *)
+                             (* recparam in l                           *)
+                             reduceaux (tys@context) l body',
+                              List.rev rev_constant_args
+                         | _ -> raise AlreadySimplified
+                       )
                  | _ -> raise WrongShape
                in
                 aux [] l body
@@ -363,14 +405,12 @@ let simpl context =
                  | _ -> C.Appl ((C.Const (uri,cookingsno))::constant_args)
                in
                 let reduced_term_to_fold = reduce context term_to_fold in
-prerr_endline ("TERM TO FOLD: " ^ CicPp.ppterm term_to_fold) ; flush stderr ;
-prerr_endline ("REDUCED TERM TO FOLD: " ^ CicPp.ppterm reduced_term_to_fold) ; flush stderr ;
-                 replace reduced_term_to_fold term_to_fold res
+                 replace (=) reduced_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 l body
+                 reduceaux context l body
               | AlreadySimplified ->
                  (* If we performed delta-reduction, we would find a Fix   *)
                  (* not applied to a constructor. So, we refuse to perform *)
@@ -382,7 +422,7 @@ prerr_endline ("REDUCED TERM TO FOLD: " ^ CicPp.ppterm reduced_term_to_fold) ; f
             end
          | C.Axiom _ -> if l = [] then t else C.Appl (t::l)
          | C.Variable _ -> raise ReferenceToVariable
-         | C.CurrentProof (_,_,body,_) -> reduceaux l body
+         | C.CurrentProof (_,_,body,_) -> reduceaux context l body
          | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
        )
     | C.Abst _ as t -> t (*CSC l should be empty ????? *)
@@ -392,30 +432,34 @@ prerr_endline ("REDUCED TERM TO FOLD: " ^ CicPp.ppterm reduced_term_to_fold) ; f
        let decofix =
         function
            C.CoFix (i,fl) as t ->
-            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
-              reduceaux [] body'
+            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
+               reduceaux (tys@context) [] body'
          | C.Appl (C.CoFix (i,fl) :: tl) ->
-            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 []) tl in
-               reduceaux tl body'
+            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 (tys@context) tl body'
          | t -> t
        in
-        (match decofix (reduceaux [] term) with
-            C.MutConstruct (_,_,_,j) -> reduceaux l (List.nth pl (j-1))
+        (match decofix (reduceaux context [] term) with
+            C.MutConstruct (_,_,_,j) -> reduceaux context l (List.nth pl (j-1))
           | C.Appl (C.MutConstruct (_,_,_,j) :: tl) ->
              let (arity, r, num_ingredients) =
               match CicEnvironment.get_obj mutind with
@@ -440,64 +484,70 @@ prerr_endline ("REDUCED TERM TO FOLD: " ^ CicPp.ppterm reduced_term_to_fold) ; f
                 in
                  eat_first (num_to_eat,tl)
               in
-               reduceaux (ts@l) (List.nth pl (j-1))
+               reduceaux context (ts@l) (List.nth pl (j-1))
          | C.Abst _ | C.Cast _ | C.Implicit ->
             raise (Impossible 2) (* we don't trust our whd ;-) *)
          | _ ->
-           let outtype' = reduceaux [] outtype in
-           let term' = reduceaux [] term in
-           let pl' = List.map (reduceaux []) pl in
+           let outtype' = reduceaux context [] outtype in
+           let term' = reduceaux context [] term in
+           let pl' = List.map (reduceaux context []) pl in
             let res =
              C.MutCase (mutind,cookingsno,i,outtype',term',pl')
             in
              if l = [] then res else C.Appl (res::l)
        )
     | C.Fix (i,fl) ->
-       let t' () =
-        let fl' =
-         List.map
-          (function (n,recindex,ty,bo) ->
-            (n,recindex,reduceaux [] ty, reduceaux [] bo)
-          ) fl
-        in
-         C.Fix (i, fl')
+       let tys =
+        List.map (function (name,_,ty,_) -> Some (C.Name name, C.Decl ty)) fl
        in
-        let (_,recindex,_,body) = List.nth fl i in
-         let recparam =
-          try
-           Some (List.nth l recindex)
-          with
-           _ -> None
+        let t' () =
+         let fl' =
+          List.map
+           (function (n,recindex,ty,bo) ->
+             (n,recindex,reduceaux context [] ty, reduceaux (tys@context) [] bo)
+           ) fl
          in
-          (match recparam with
-              Some recparam ->
-               (match reduceaux [] recparam with
-                   C.MutConstruct _
-                 | C.Appl ((C.MutConstruct _)::_) ->
-                    let body' =
-                     let counter = ref (List.length fl) in
-                      List.fold_right
-                       (fun _ -> decr counter ; S.subst (C.Fix (!counter,fl)))
-                       fl
-                       body
-                    in
-                     (* Possible optimization: substituting whd recparam in l *)
-                     reduceaux l body'
-                 | _ -> if l = [] then t' () else C.Appl ((t' ())::l)
-               )
-            | None -> if l = [] then t' () else C.Appl ((t' ())::l)
-          )
-    | C.CoFix (i,fl) ->
-       let t' =
-        let fl' =
-         List.map
-          (function (n,ty,bo) ->
-            (n,reduceaux [] ty, reduceaux [] bo)
-          ) fl
+          C.Fix (i, fl')
         in
+         let (_,recindex,_,body) = List.nth fl i in
+          let recparam =
+           try
+            Some (List.nth l recindex)
+           with
+            _ -> None
+          in
+           (match recparam with
+               Some recparam ->
+                (match reduceaux context [] recparam with
+                    C.MutConstruct _
+                  | C.Appl ((C.MutConstruct _)::_) ->
+                     let body' =
+                      let counter = ref (List.length fl) in
+                       List.fold_right
+                        (fun _ -> decr counter ; S.subst (C.Fix (!counter,fl)))
+                        fl
+                        body
+                     in
+                      (* Possible optimization: substituting whd recparam in l*)
+                      reduceaux context l body'
+                  | _ -> if l = [] then t' () else C.Appl ((t' ())::l)
+                )
+             | None -> if l = [] then t' () else C.Appl ((t' ())::l)
+           )
+    | C.CoFix (i,fl) ->
+       let tys =
+        List.map (function (name,ty,_) -> Some (C.Name name, C.Decl ty)) fl
+       in
+        let t' =
+         let fl' =
+          List.map
+           (function (n,ty,bo) ->
+             (n,reduceaux context [] ty, reduceaux (tys@context) [] bo)
+           ) fl
+         in
          C.CoFix (i, fl')
        in
-        if l = [] then t' else C.Appl (t'::l)
+         if l = [] then t' else C.Appl (t'::l)
  in
-  reduceaux []
+  reduceaux context []
 ;;