]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/ocaml/cic_proof_checking/cicReductionMachine.ml
This commit was manufactured by cvs2svn to create branch
[helm.git] / helm / ocaml / cic_proof_checking / cicReductionMachine.ml
diff --git a/helm/ocaml/cic_proof_checking/cicReductionMachine.ml b/helm/ocaml/cic_proof_checking/cicReductionMachine.ml
deleted file mode 100644 (file)
index 30b6882..0000000
+++ /dev/null
@@ -1,894 +0,0 @@
-(* Copyright (C) 2000, HELM Team.
- * 
- * This file is part of HELM, an Hypertextual, Electronic
- * Library of Mathematics, developed at the Computer Science
- * Department, University of Bologna, Italy.
- * 
- * HELM is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * 
- * HELM is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HELM; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA  02111-1307, USA.
- * 
- * For details, see the HELM World-Wide-Web page,
- * http://cs.unibo.it/helm/.
- *)
-
-exception CicReductionInternalError;;
-exception WrongUriToInductiveDefinition;;
-exception Impossible of int;;
-exception ReferenceToConstant;;
-exception ReferenceToVariable;;
-exception ReferenceToCurrentProof;;
-exception ReferenceToInductiveDefinition;;
-
-let fdebug = ref 1;;
-let debug t env s =
- let rec debug_aux t i =
-  let module C = Cic in
-  let module U = UriManager in
-   CicPp.ppobj (C.Variable ("DEBUG", None, t, [])) ^ "\n" ^ i
- in
-  if !fdebug = 0 then
-   begin
-    print_endline (s ^ "\n" ^ List.fold_right debug_aux (t::env) "") ;
-    flush stdout
-   end
-;;
-
-module type Strategy =
- sig
-  type stack_term
-  type env_term
-  type ens_term
-  val to_stack : Cic.term -> stack_term
-  val to_stack_list : Cic.term list -> stack_term list
-  val to_env : Cic.term -> env_term
-  val to_ens : Cic.term -> ens_term
-  val from_stack :
-   unwind:
-    (int -> env_term list -> ens_term Cic.explicit_named_substitution ->
-      Cic.term -> Cic.term) ->
-   stack_term -> Cic.term
-  val from_stack_list :
-   unwind:
-    (int -> env_term list -> ens_term Cic.explicit_named_substitution ->
-      Cic.term -> Cic.term) ->
-   stack_term list -> Cic.term list
-  val from_env : env_term -> Cic.term
-  val from_ens : ens_term -> Cic.term
-  val stack_to_env :
-   reduce:
-    (int * env_term list * ens_term Cic.explicit_named_substitution *
-      Cic.term * stack_term list -> Cic.term) ->
-   unwind:
-    (int -> env_term list -> ens_term Cic.explicit_named_substitution ->
-      Cic.term -> Cic.term) ->
-   stack_term -> env_term
-  val compute_to_env :
-   reduce:
-    (int * env_term list * ens_term Cic.explicit_named_substitution * Cic.term *
-      stack_term list -> Cic.term) ->
-   unwind:
-    (int -> env_term list -> ens_term Cic.explicit_named_substitution ->
-      Cic.term -> Cic.term) ->
-   int -> env_term list -> ens_term Cic.explicit_named_substitution ->
-    Cic.term -> env_term
-  val compute_to_stack :
-   reduce:
-    (int * env_term list * ens_term Cic.explicit_named_substitution * Cic.term *
-      stack_term list -> Cic.term) ->
-   unwind:
-    (int -> env_term list -> ens_term Cic.explicit_named_substitution ->
-      Cic.term -> Cic.term) ->
-   int -> env_term list -> ens_term Cic.explicit_named_substitution ->
-    Cic.term -> stack_term
- end
-;;
-
-module CallByNameStrategy =
- struct
-  type stack_term = Cic.term
-  type env_term = Cic.term
-  type ens_term = Cic.term
-  let to_stack v = v
-  let to_stack_list l = l
-  let to_env v = v
-  let to_ens v = v
-  let from_stack ~unwind v = v
-  let from_stack_list ~unwind l = l
-  let from_env v = v
-  let from_ens v = v
-  let stack_to_env ~reduce ~unwind v = v
-  let compute_to_stack ~reduce ~unwind k e ens t = unwind k e ens t
-  let compute_to_env ~reduce ~unwind k e ens t = unwind k e ens t
- end
-;;
-
-module CallByValueStrategy =
- struct
-  type stack_term = Cic.term
-  type env_term = Cic.term
-  type ens_term = Cic.term
-  let to_stack v = v
-  let to_stack_list l = l
-  let to_env v = v
-  let to_ens v = v
-  let from_stack ~unwind v = v
-  let from_stack_list ~unwind l = l
-  let from_env v = v
-  let from_ens v = v
-  let stack_to_env ~reduce ~unwind v = v
-  let compute_to_stack ~reduce ~unwind k e ens t = reduce (k,e,ens,t,[])
-  let compute_to_env ~reduce ~unwind k e ens t = reduce (k,e,ens,t,[])
- end
-;;
-
-module CallByValueStrategyByNameOnConstants =
- struct
-  type stack_term = Cic.term
-  type env_term = Cic.term
-  type ens_term = Cic.term
-  let to_stack v = v
-  let to_stack_list l = l
-  let to_env v = v
-  let to_ens v = v
-  let from_stack ~unwind v = v
-  let from_stack_list ~unwind l = l
-  let from_env v = v
-  let from_ens v = v
-  let stack_to_env ~reduce ~unwind v = v
-  let compute_to_stack ~reduce ~unwind k e ens =
-   function
-      Cic.Const _ as t -> unwind k e ens t    
-    | t -> reduce (k,e,ens,t,[])
-  let compute_to_env ~reduce ~unwind k e ens =
-   function
-      Cic.Const _ as t -> unwind k e ens t    
-    | t -> reduce (k,e,ens,t,[])
- end
-;;
-
-module LazyCallByValueStrategy =
- struct
-  type stack_term = Cic.term lazy_t
-  type env_term = Cic.term lazy_t
-  type ens_term = Cic.term lazy_t
-  let to_stack v = lazy v
-  let to_stack_list l = List.map to_stack l
-  let to_env v = lazy v
-  let to_ens v = lazy v
-  let from_stack ~unwind v = Lazy.force v
-  let from_stack_list ~unwind l = List.map (from_stack ~unwind) l
-  let from_env v = Lazy.force v
-  let from_ens v = Lazy.force v
-  let stack_to_env ~reduce ~unwind v = v
-  let compute_to_stack ~reduce ~unwind k e ens t = lazy (reduce (k,e,ens,t,[]))
-  let compute_to_env ~reduce ~unwind k e ens t = lazy (reduce (k,e,ens,t,[]))
- end
-;;
-
-module LazyCallByValueStrategyByNameOnConstants =
- struct
-  type stack_term = Cic.term lazy_t
-  type env_term = Cic.term lazy_t
-  type ens_term = Cic.term lazy_t
-  let to_stack v = lazy v
-  let to_stack_list l = List.map to_stack l
-  let to_env v = lazy v
-  let to_ens v = lazy v
-  let from_stack ~unwind v = Lazy.force v
-  let from_stack_list ~unwind l = List.map (from_stack ~unwind) l
-  let from_env v = Lazy.force v
-  let from_ens v = Lazy.force v
-  let stack_to_env ~reduce ~unwind v = v
-  let compute_to_stack ~reduce ~unwind k e ens t =
-   lazy (
-    match t with
-       Cic.Const _ as t -> unwind k e ens t    
-     | t -> reduce (k,e,ens,t,[]))
-  let compute_to_env ~reduce ~unwind k e ens t =
-   lazy (
-    match t with
-       Cic.Const _ as t -> unwind k e ens t    
-     | t -> reduce (k,e,ens,t,[]))
- end
-;;
-
-module LazyCallByNameStrategy =
- struct
-  type stack_term = Cic.term lazy_t
-  type env_term = Cic.term lazy_t
-  type ens_term = Cic.term lazy_t
-  let to_stack v = lazy v
-  let to_stack_list l = List.map to_stack l
-  let to_env v = lazy v
-  let to_ens v = lazy v
-  let from_stack ~unwind v = Lazy.force v
-  let from_stack_list ~unwind l = List.map (from_stack ~unwind) l
-  let from_env v = Lazy.force v
-  let from_ens v = Lazy.force v
-  let stack_to_env ~reduce ~unwind v = v
-  let compute_to_stack ~reduce ~unwind k e ens t = lazy (unwind k e ens t)
-  let compute_to_env ~reduce ~unwind k e ens t = lazy (unwind k e ens t)
- end
-;;
-
-module
- LazyCallByValueByNameOnConstantsWhenFromStack_ByNameStrategyWhenFromEnvOrEns
-=
- struct
-  type stack_term = reduce:bool -> Cic.term
-  type env_term = reduce:bool -> Cic.term
-  type ens_term = reduce:bool -> Cic.term
-  let to_stack v =
-   let value = lazy v in
-    fun ~reduce -> Lazy.force value
-  let to_stack_list l = List.map to_stack l
-  let to_env v =
-   let value = lazy v in
-    fun ~reduce -> Lazy.force value
-  let to_ens v =
-   let value = lazy v in
-    fun ~reduce -> Lazy.force value
-  let from_stack ~unwind v = (v ~reduce:false)
-  let from_stack_list ~unwind l = List.map (from_stack ~unwind) l
-  let from_env v = (v ~reduce:true)
-  let from_ens v = (v ~reduce:true)
-  let stack_to_env ~reduce ~unwind v = v
-  let compute_to_stack ~reduce ~unwind k e ens t =
-   let svalue =
-     lazy (
-      match t with
-         Cic.Const _ as t -> unwind k e ens t    
-       | t -> reduce (k,e,ens,t,[])
-     ) in
-   let lvalue =
-    lazy (unwind k e ens t)
-   in
-    fun ~reduce ->
-     if reduce then Lazy.force svalue else Lazy.force lvalue
-  let compute_to_env ~reduce ~unwind k e ens t =
-   let svalue =
-     lazy (
-      match t with
-         Cic.Const _ as t -> unwind k e ens t    
-       | t -> reduce (k,e,ens,t,[])
-     ) in
-   let lvalue =
-    lazy (unwind k e ens t)
-   in
-    fun ~reduce ->
-     if reduce then Lazy.force svalue else Lazy.force lvalue
- end
-;;
-
-module ClosuresOnStackByValueFromEnvOrEnsStrategy =
- struct
-  type stack_term =
-   int * Cic.term list * Cic.term Cic.explicit_named_substitution * Cic.term
-  type env_term = Cic.term
-  type ens_term = Cic.term
-  let to_stack v = (0,[],[],v)
-  let to_stack_list l = List.map to_stack l
-  let to_env v = v
-  let to_ens v = v
-  let from_stack ~unwind (k,e,ens,t) = unwind k e ens t
-  let from_stack_list ~unwind l = List.map (from_stack ~unwind) l
-  let from_env v = v
-  let from_ens v = v
-  let stack_to_env ~reduce ~unwind (k,e,ens,t) = reduce (k,e,ens,t,[])
-  let compute_to_env ~reduce ~unwind k e ens t =
-   unwind k e ens t
-  let compute_to_stack ~reduce ~unwind k e ens t = (k,e,ens,t)
- end
-;;
-
-module ClosuresOnStackByValueFromEnvOrEnsByNameOnConstantsStrategy =
- struct
-  type stack_term =
-   int * Cic.term list * Cic.term Cic.explicit_named_substitution * Cic.term
-  type env_term = Cic.term
-  type ens_term = Cic.term
-  let to_stack v = (0,[],[],v)
-  let to_stack_list l = List.map to_stack l
-  let to_env v = v
-  let to_ens v = v
-  let from_stack ~unwind (k,e,ens,t) = unwind k e ens t
-  let from_stack_list ~unwind l = List.map (from_stack ~unwind) l
-  let from_env v = v
-  let from_ens v = v
-  let stack_to_env ~reduce ~unwind (k,e,ens,t) =
-   match t with
-      Cic.Const _ as t -> unwind k e ens t    
-    | t -> reduce (k,e,ens,t,[])
-  let compute_to_env ~reduce ~unwind k e ens t =
-   unwind k e ens t
-  let compute_to_stack ~reduce ~unwind k e ens t = (k,e,ens,t)
- end
-;;
-
-module Reduction(RS : Strategy) =
- struct
-  type env = RS.env_term list
-  type ens = RS.ens_term Cic.explicit_named_substitution
-  type stack = RS.stack_term list
-  type config = int * env * ens * Cic.term * stack
-
-  (* k is the length of the environment e *)
-  (* m is the current depth inside the term *)
-  let unwind' m k e ens t = 
-   let module C = Cic in
-   let module S = CicSubstitution in
-    if k = 0 && ens = [] then
-     t
-    else 
-     let rec unwind_aux m =
-      function
-         C.Rel n as t ->
-          if n <= m then t else
-           let d =
-            try
-             Some (RS.from_env (List.nth e (n-m-1)))
-            with _ -> None
-           in
-            (match d with 
-                Some t' ->
-                 if m = 0 then t' else S.lift m t'
-              | None -> C.Rel (n-k)
-            )
-       | C.Var (uri,exp_named_subst) ->
-(*
-prerr_endline ("%%%%%UWVAR " ^ String.concat " ; " (List.map (function (uri,t) -> UriManager.string_of_uri uri ^ " := " ^ CicPp.ppterm t) ens)) ;
-*)
-         if List.exists (function (uri',_) -> UriManager.eq uri' uri) ens then
-          CicSubstitution.lift m (RS.from_ens (List.assq uri ens))
-         else
-          let params =
-           (match CicEnvironment.get_obj uri with
-               C.Constant _ -> raise ReferenceToConstant
-             | C.Variable (_,_,_,params) -> params
-             | C.CurrentProof _ -> raise ReferenceToCurrentProof
-             | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
-           )
-          in
-           let exp_named_subst' =
-            substaux_in_exp_named_subst params exp_named_subst m 
-           in
-            C.Var (uri,exp_named_subst')
-       | C.Meta (i,l) ->
-          let l' =
-           List.map
-            (function
-                None -> None
-              | Some t -> Some (unwind_aux m t)
-            ) l
-          in
-           C.Meta (i, l')
-       | C.Sort _ as t -> t
-       | C.Implicit as t -> t
-       | C.Cast (te,ty) -> C.Cast (unwind_aux m te, unwind_aux m ty) (*CSC ???*)
-       | C.Prod (n,s,t) -> C.Prod (n, unwind_aux m s, unwind_aux (m + 1) t)
-       | C.Lambda (n,s,t) -> C.Lambda (n, unwind_aux m s, unwind_aux (m + 1) t)
-       | C.LetIn (n,s,t) -> C.LetIn (n, unwind_aux m s, unwind_aux (m + 1) t)
-       | C.Appl l -> C.Appl (List.map (unwind_aux m) l)
-       | C.Const (uri,exp_named_subst) ->
-          let params =
-           (match CicEnvironment.get_obj uri with
-               C.Constant (_,_,_,params) -> params
-             | C.Variable _ -> raise ReferenceToVariable
-             | C.CurrentProof (_,_,_,_,params) -> params
-             | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
-           )
-          in
-           let exp_named_subst' =
-            substaux_in_exp_named_subst params exp_named_subst m 
-           in
-            C.Const (uri,exp_named_subst')
-       | C.MutInd (uri,i,exp_named_subst) ->
-          let params =
-           (match CicEnvironment.get_obj uri with
-               C.Constant _ -> raise ReferenceToConstant
-             | C.Variable _ -> raise ReferenceToVariable
-             | C.CurrentProof _ -> raise ReferenceToCurrentProof
-             | C.InductiveDefinition (_,params,_) -> params
-           )
-          in
-           let exp_named_subst' =
-            substaux_in_exp_named_subst params exp_named_subst m 
-           in
-            C.MutInd (uri,i,exp_named_subst')
-       | C.MutConstruct (uri,i,j,exp_named_subst) ->
-          let params =
-           (match CicEnvironment.get_obj uri with
-               C.Constant _ -> raise ReferenceToConstant
-             | C.Variable _ -> raise ReferenceToVariable
-             | C.CurrentProof _ -> raise ReferenceToCurrentProof
-             | C.InductiveDefinition (_,params,_) -> params
-           )
-          in
-           let exp_named_subst' =
-            substaux_in_exp_named_subst params exp_named_subst m 
-           in
-            C.MutConstruct (uri,i,j,exp_named_subst')
-       | C.MutCase (sp,i,outt,t,pl) ->
-          C.MutCase (sp,i,unwind_aux m outt, unwind_aux m t,
-           List.map (unwind_aux m) pl)
-       | C.Fix (i,fl) ->
-          let len = List.length fl in
-          let substitutedfl =
-           List.map
-            (fun (name,i,ty,bo) ->
-              (name, i, unwind_aux m ty, unwind_aux (m+len) bo))
-             fl
-          in
-           C.Fix (i, substitutedfl)
-       | C.CoFix (i,fl) ->
-          let len = List.length fl in
-          let substitutedfl =
-           List.map
-            (fun (name,ty,bo) -> (name, unwind_aux m ty, unwind_aux (m+len) bo))
-             fl
-          in
-           C.CoFix (i, substitutedfl)
-     and substaux_in_exp_named_subst params exp_named_subst' m  =
-  (*CSC: Idea di Andrea di ordinare compatibilmente con l'ordine dei params
-      let ens' =
-       List.map (function (uri,t) -> uri, unwind_aux m t) exp_named_subst' @
-  (*CSC: qui liftiamo tutti gli ens anche se magari me ne servono la meta'!!! *)
-        List.map (function (uri,t) -> uri, CicSubstitution.lift m t) ens
-      in
-      let rec filter_and_lift =
-       function
-          [] -> []
-        | uri::tl ->
-           let r = filter_and_lift tl in
-            (try
-              (uri,(List.assq uri ens'))::r
-             with
-              Not_found -> r
-            )
-      in
-       filter_and_lift params
-  *)
-  
-  (*CSC: invece di concatenare sarebbe meglio rispettare l'ordine dei params *)
-  (*CSC: e' vero???? una veloce prova non sembra confermare la teoria        *)
-  
-  (*CSC: codice copiato e modificato dalla cicSubstitution.subst_vars *)
-  (*CSC: codice altamente inefficiente *)
-      let rec filter_and_lift already_instantiated =
-       function
-          [] -> []
-        | (uri,t)::tl when
-            List.for_all
-             (function (uri',_)-> not (UriManager.eq uri uri')) exp_named_subst'
-            &&
-             not (List.mem uri already_instantiated)
-            &&
-             List.mem uri params
-           ->
-            (uri,CicSubstitution.lift m (RS.from_ens t)) ::
-             (filter_and_lift (uri::already_instantiated) tl)
-        | _::tl -> filter_and_lift already_instantiated tl
-(*
-        | (uri,_)::tl ->
-prerr_endline ("---- SKIPPO " ^ UriManager.string_of_uri uri) ;
-if List.for_all (function (uri',_) -> not (UriManager.eq uri uri')) exp_named_subst' then prerr_endline "---- OK1" ;
-prerr_endline ("++++ uri " ^ UriManager.string_of_uri uri ^ " not in " ^ String.concat " ; " (List.map UriManager.string_of_uri params)) ;
-if List.mem uri params then prerr_endline "---- OK2" ;
-        filter_and_lift tl
-*)
-      in
-       List.map (function (uri,t) -> uri, unwind_aux m t) exp_named_subst' @
-        (filter_and_lift [] (List.rev ens))
-     in
-      unwind_aux m t          
-  ;;
-  
-  let unwind =
-   unwind' 0 
-  ;;
-  
-  let reduce context : config -> Cic.term = 
-   let module C = Cic in
-   let module S = CicSubstitution in 
-   let rec reduce =
-    function
-       (k, e, _, (C.Rel n as t), s) ->
-        let d =
-         try
-          Some (RS.from_env (List.nth e (n-1)))
-         with
-          _ ->
-           try
-            begin
-             match List.nth context (n - 1 - k) with
-                None -> assert false
-              | Some (_,C.Decl _) -> None
-              | Some (_,C.Def x) -> Some (S.lift (n - k) x)
-            end
-           with
-            _ -> None
-        in
-         (match d with 
-             Some t' -> reduce (0,[],[],t',s)
-           | None ->
-              if s = [] then
-               C.Rel (n-k)
-              else C.Appl (C.Rel (n-k)::(RS.from_stack_list ~unwind s))
-         )
-     | (k, e, ens, (C.Var (uri,exp_named_subst) as t), s) -> 
-         if List.exists (function (uri',_) -> UriManager.eq uri' uri) ens then
-          reduce (0, [], [], RS.from_ens (List.assq uri ens), s)
-         else
-          (match CicEnvironment.get_obj uri with
-              C.Constant _ -> raise ReferenceToConstant
-            | C.CurrentProof _ -> raise ReferenceToCurrentProof
-            | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
-            | C.Variable (_,None,_,_) ->
-               let t' = unwind k e ens t in
-                if s = [] then t' else
-                 C.Appl (t'::(RS.from_stack_list ~unwind s))
-            | C.Variable (_,Some body,_,_) ->
-               let ens' = push_exp_named_subst k e ens exp_named_subst in
-                reduce (0, [], ens', body, s)
-          )
-     | (k, e, ens, (C.Meta _ as t), s) ->
-        let t' = unwind k e ens t in
-         if s = [] then t' else C.Appl (t'::(RS.from_stack_list ~unwind s))
-     | (k, e, _, (C.Sort _ as t), s) -> t (* s should be empty *)
-     | (k, e, _, (C.Implicit as t), s) -> t (* s should be empty *)
-     | (k, e, ens, (C.Cast (te,ty) as t), s) ->
-        reduce (k, e, ens, te, s) (* s should be empty *)
-     | (k, e, ens, (C.Prod _ as t), s) ->
-         unwind k e ens t (* s should be empty *)
-     | (k, e, ens, (C.Lambda (_,_,t) as t'), []) -> unwind k e ens t' 
-     | (k, e, ens, C.Lambda (_,_,t), p::s) ->
-         reduce (k+1, (RS.stack_to_env ~reduce ~unwind p)::e, ens, t,s)
-     | (k, e, ens, (C.LetIn (_,m,t) as t'), s) ->
-        let m' = RS.compute_to_env ~reduce ~unwind k e ens m in
-         reduce (k+1, m'::e, ens, t, s)
-     | (_, _, _, C.Appl [], _) -> raise (Impossible 1)
-     | (k, e, ens, C.Appl (he::tl), s) ->
-        let tl' =
-         List.map
-          (function t -> RS.compute_to_stack ~reduce ~unwind k e ens t) tl
-        in
-         reduce (k, e, ens, he, (List.append tl') s)
-  (* CSC: Old Dead Code 
-     | (k, e, ens, C.Appl ((C.Lambda _ as he)::tl), s) 
-     | (k, e, ens, C.Appl ((C.Const _ as he)::tl), s)  
-     | (k, e, ens, C.Appl ((C.MutCase _ as he)::tl), s) 
-     | (k, e, ens, C.Appl ((C.Fix _ as he)::tl), s) ->
-  (* strict evaluation, but constants are NOT unfolded *)
-        let red =
-         function
-            C.Const _ as t -> unwind k e ens t
-          | t -> reduce (k,e,ens,t,[])
-        in
-         let tl' = List.map red tl in
-          reduce (k, e, ens, he , List.append tl' s)
-     | (k, e, ens, C.Appl l, s) ->
-         C.Appl (List.append (List.map (unwind k e ens) l) s)
-  *)
-     | (k, e, ens, (C.Const (uri,exp_named_subst) as t), s) ->
-        (match CicEnvironment.get_obj uri with
-            C.Constant (_,Some body,_,_) ->
-             let ens' = push_exp_named_subst k e ens exp_named_subst in
-              (* constants are closed *)
-              reduce (0, [], ens', body, s) 
-          | C.Constant (_,None,_,_) ->
-             let t' = unwind k e ens t in
-              if s = [] then t' else C.Appl (t'::(RS.from_stack_list ~unwind s))
-          | C.Variable _ -> raise ReferenceToVariable
-          | C.CurrentProof (_,_,body,_,_) ->
-             let ens' = push_exp_named_subst k e ens exp_named_subst in
-              (* constants are closed *)
-              reduce (0, [], ens', body, s)
-          | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
-        )
-     | (k, e, ens, (C.MutInd _ as t),s) ->
-        let t' = unwind k e ens t in 
-         if s = [] then t' else C.Appl (t'::(RS.from_stack_list ~unwind s))
-     | (k, e, ens, (C.MutConstruct _ as t),s) -> 
-         let t' = unwind k e ens t in
-          if s = [] then t' else C.Appl (t'::(RS.from_stack_list ~unwind s))
-     | (k, e, ens, (C.MutCase (mutind,i,_,term,pl) as t),s) ->
-        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
-               (* the term is the result of a reduction; *)
-               (* so it is already unwinded.             *)
-               reduce (0,[],[],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
-               (* the term is the result of a reduction; *)
-               (* so it is already unwinded.             *)
-               reduce (0,[],[],body',RS.to_stack_list tl)
-          | t -> t
-        in
-         (match decofix (reduce (k,e,ens,term,[])) with
-             C.MutConstruct (_,_,j,_) ->
-              reduce (k, e, ens, (List.nth pl (j-1)), s)
-           | C.Appl (C.MutConstruct (_,_,j,_) :: tl) ->
-              let (arity, r) =
-               match CicEnvironment.get_obj mutind with
-                  C.InductiveDefinition (tl,ingredients,r) ->
-                    let (_,_,arity,_) = List.nth tl i in
-                     (arity,r)
-                | _ -> raise WrongUriToInductiveDefinition
-              in
-               let ts =
-                let num_to_eat = r in
-                 let rec eat_first =
-                  function
-                     (0,l) -> l
-                   | (n,he::tl) when n > 0 -> eat_first (n - 1, tl)
-                   | _ -> raise (Impossible 5)
-                 in
-                  eat_first (num_to_eat,tl)
-               in
-                (* ts are already unwinded because they are a sublist of tl *)
-                reduce (k, e, ens, (List.nth pl (j-1)), (RS.to_stack_list ts)@s)
-          | C.Cast _ | C.Implicit ->
-              raise (Impossible 2) (* we don't trust our whd ;-) *)
-           | _ ->
-             let t' = unwind k e ens t in
-              if s = [] then t' else C.Appl (t'::(RS.from_stack_list ~unwind s))
-         )
-     | (k, e, ens, (C.Fix (i,fl) as t), s) ->
-        let (_,recindex,_,body) = List.nth fl i in
-         let recparam =
-          try
-           Some (RS.from_stack ~unwind (List.nth s recindex))
-          with
-           _ -> None
-         in
-          (match recparam with
-              Some recparam ->
-               (match reduce (0,[],[],recparam,[]) with
-                   (* match recparam with *) 
-                   C.MutConstruct _
-                 | C.Appl ((C.MutConstruct _)::_) ->
-                    (* OLD 
-                    let body' =
-                     let counter = ref (List.length fl) in
-                      List.fold_right
-                       (fun _ -> decr counter ; S.subst (C.Fix (!counter,fl)))
-                       fl
-                       body
-                    in 
-                     reduce (k, e, ens, body', s) *)
-                    (* NEW *)
-                    let leng = List.length fl in
-                    let fl' = 
-                     let unwind_fl (name,recindex,typ,body) = 
-                      (name,recindex,unwind k e ens typ,
-                        unwind' leng k e ens body)
-                     in
-                     List.map unwind_fl fl
-                    in
-                     let new_env =
-                      let counter = ref 0 in
-                      let rec build_env e =
-                       if !counter = leng then e
-                       else
-                        (incr counter ;
-                         build_env ((RS.to_env (C.Fix (!counter -1, fl')))::e))
-                      in
-                       build_env e
-                     in
-                      reduce (k+leng, new_env, ens, body, s)  
-                 | _ ->
-                   let t' = unwind k e ens t in 
-                    if s = [] then t' else
-                     C.Appl (t'::(RS.from_stack_list ~unwind s))
-               )
-            | None ->
-               let t' = unwind k e ens t in 
-                if s = [] then t' else
-                 C.Appl (t'::(RS.from_stack_list ~unwind s))
-          )
-     | (k, e, ens, (C.CoFix (i,fl) as t),s) ->
-        let t' = unwind k e ens t in 
-         if s = [] then t' else C.Appl (t'::(RS.from_stack_list ~unwind s))
-   and push_exp_named_subst k e ens =
-    function
-       [] -> ens
-     | (uri,t)::tl ->
-         push_exp_named_subst k e ((uri,RS.to_ens (unwind k e ens t))::ens) tl
-   in
-    reduce
-  ;;
-  
-  let rec whd context t = reduce context (0, [], [], t, []);;
-  
-(* DEBUGGING ONLY
-let whd context t =
- let res = whd context t in
- let rescsc = CicReductionNaif.whd context t in
-  if not (CicReductionNaif.are_convertible context res rescsc) then
-   begin
-    prerr_endline ("PRIMA: " ^ CicPp.ppterm t) ;
-    flush stderr ;
-    prerr_endline ("DOPO: " ^ CicPp.ppterm res) ;
-    flush stderr ;
-    prerr_endline ("CSC: " ^ CicPp.ppterm rescsc) ;
-    flush stderr ;
-CicReductionNaif.fdebug := 0 ;
-let _ =  CicReductionNaif.are_convertible context res rescsc in
-    assert false ;
-   end
-  else 
-   res
-;;
-*)
- end
-;;
-
-
-(*
-module R = Reduction CallByNameStrategy;;
-module R = Reduction CallByValueStrategy;;
-module R = Reduction CallByValueStrategyByNameOnConstants;;
-module R = Reduction LazyCallByValueStrategy;;
-module R = Reduction LazyCallByValueStrategyByNameOnConstants;;
-module R = Reduction LazyCallByNameStrategy;;
-module R = Reduction
- LazyCallByValueByNameOnConstantsWhenFromStack_ByNameStrategyWhenFromEnvOrEns;;
-module R = Reduction ClosuresOnStackByValueFromEnvOrEnsStrategy;;
-module R = Reduction
- ClosuresOnStackByValueFromEnvOrEnsByNameOnConstantsStrategy;;
-*)
-module R = Reduction ClosuresOnStackByValueFromEnvOrEnsStrategy;;
-
-let whd = R.whd;;
-
-(* t1, t2 must be well-typed *)
-let are_convertible =
- let module U = UriManager in
- let rec aux context t1 t2 =
-  let aux2 t1 t2 =
-   (* this trivial euristic cuts down the total time of about five times ;-) *)
-   (* this because most of the time t1 and t2 are "sintactically" the same   *)
-   if t1 = t2 then
-    true
-   else
-    begin
-     let module C = Cic in
-       match (t1,t2) with
-          (C.Rel n1, C.Rel n2) -> n1 = n2
-        | (C.Var (uri1,exp_named_subst1), C.Var (uri2,exp_named_subst2)) ->
-            U.eq uri1 uri2 &&
-             (try
-               List.fold_right2
-                (fun (uri1,x) (uri2,y) b ->
-                  U.eq uri1 uri2 && aux context x y && b
-                ) exp_named_subst1 exp_named_subst2 true 
-              with
-               Invalid_argument _ -> false
-             )
-        | (C.Meta (n1,l1), C.Meta (n2,l2)) -> 
-            n1 = n2 &&
-             List.fold_left2
-              (fun b t1 t2 ->
-                b &&
-                 match t1,t2 with
-                    None,_
-                  | _,None  -> true
-                  | Some t1',Some t2' -> aux context t1' t2'
-              ) true l1 l2
-        | (C.Sort s1, C.Sort s2) -> true (*CSC da finire con gli universi *)
-        | (C.Prod (name1,s1,t1), C.Prod(_,s2,t2)) ->
-           aux context s1 s2 && aux ((Some (name1, (C.Decl s1)))::context) t1 t2
-        | (C.Lambda (name1,s1,t1), C.Lambda(_,s2,t2)) ->
-           aux context s1 s2 && aux ((Some (name1, (C.Decl s1)))::context) t1 t2
-        | (C.LetIn (name1,s1,t1), C.LetIn(_,s2,t2)) ->
-           aux context s1 s2 && aux ((Some (name1, (C.Def s1)))::context) t1 t2
-        | (C.Appl l1, C.Appl l2) ->
-           (try
-             List.fold_right2 (fun  x y b -> aux context x y && b) l1 l2 true 
-            with
-             Invalid_argument _ -> false
-           )
-        | (C.Const (uri1,exp_named_subst1), C.Const (uri2,exp_named_subst2)) ->
-            U.eq uri1 uri2 &&
-             (try
-               List.fold_right2
-                (fun (uri1,x) (uri2,y) b ->
-                  U.eq uri1 uri2 && aux context x y && b
-                ) exp_named_subst1 exp_named_subst2 true 
-              with
-               Invalid_argument _ -> false
-             )
-        | (C.MutInd (uri1,i1,exp_named_subst1),
-           C.MutInd (uri2,i2,exp_named_subst2)
-          ) ->
-            U.eq uri1 uri2 && i1 = i2 &&
-             (try
-               List.fold_right2
-                (fun (uri1,x) (uri2,y) b ->
-                  U.eq uri1 uri2 && aux context x y && b
-                ) exp_named_subst1 exp_named_subst2 true 
-              with
-               Invalid_argument _ -> false
-             )
-        | (C.MutConstruct (uri1,i1,j1,exp_named_subst1),
-           C.MutConstruct (uri2,i2,j2,exp_named_subst2)
-          ) ->
-            U.eq uri1 uri2 && i1 = i2 && j1 = j2 &&
-             (try
-               List.fold_right2
-                (fun (uri1,x) (uri2,y) b ->
-                  U.eq uri1 uri2 && aux context x y && b
-                ) exp_named_subst1 exp_named_subst2 true 
-              with
-               Invalid_argument _ -> false
-             )
-        | (C.MutCase (uri1,i1,outtype1,term1,pl1),
-           C.MutCase (uri2,i2,outtype2,term2,pl2)) -> 
-            U.eq uri1 uri2 && i1 = i2 && aux context outtype1 outtype2 &&
-             aux context term1 term2 &&
-             List.fold_right2 (fun x y b -> b && aux context x y) pl1 pl2 true
-        | (C.Fix (i1,fl1), C.Fix (i2,fl2)) ->
-           let tys =
-            List.map (function (n,_,ty,_) -> Some (C.Name n,(C.Decl ty))) fl1
-           in
-            i1 = i2 &&
-             List.fold_right2
-              (fun (_,recindex1,ty1,bo1) (_,recindex2,ty2,bo2) b ->
-                b && recindex1 = recindex2 && aux context ty1 ty2 &&
-                 aux (tys@context) bo1 bo2)
-              fl1 fl2 true
-        | (C.CoFix (i1,fl1), C.CoFix (i2,fl2)) ->
-           let tys =
-            List.map (function (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl1
-           in
-            i1 = i2 &&
-             List.fold_right2
-              (fun (_,ty1,bo1) (_,ty2,bo2) b ->
-                b && aux context ty1 ty2 && aux (tys@context) bo1 bo2)
-              fl1 fl2 true
-        | (C.Cast _, _) | (_, C.Cast _)
-        | (C.Implicit, _) | (_, C.Implicit) ->
-           raise (Impossible 3) (* we don't trust our whd ;-) *)
-        | (_,_) -> false
-    end
-  in
-   if aux2 t1 t2 then true
-   else
-    begin
-     debug t1 [t2] "PREWHD";
-     let t1' = whd context t1 in
-     let t2' = whd context t2 in
-      debug t1' [t2'] "POSTWHD";
-      aux2 t1' t2'
-    end
- in
-  aux
-;;