-(* 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/.
- *)
+(*
+ ||M|| This file is part of HELM, an Hypertextual, Electronic
+ ||A|| Library of Mathematics, developed at the Computer Science
+ ||T|| Department, University of Bologna, Italy.
+ ||I||
+ ||T|| HELM is free software; you can redistribute it and/or
+ ||A|| modify it under the terms of the GNU General Public License
+ \ / version 2 or (at your option) any later version.
+ \ / This software is distributed as is, NO WARRANTY.
+ V_______________________________________________________________ *)
(* $Id$ *)
end
;;
-(*
-module CallByValueByNameForUnwind =
+module CallByValueByNameForUnwind' =
+ struct
+ type config = int * env_term list * NCic.term * stack_term list
+ and stack_term = config lazy_t * NCic.term lazy_t (* cbv, cbn *)
+ and env_term = config lazy_t * NCic.term lazy_t (* cbv, cbn *)
+ let to_env ~reduce ~unwind c = lazy (reduce c),lazy (unwind c)
+ let from_stack (c,_) = Lazy.force c
+ let from_stack_list_for_unwind ~unwind:_ l =
+ List.map (function (_,c) -> Lazy.force c) l
+ let from_env (c,_) = Lazy.force c
+ let from_env_for_unwind ~unwind:_ (_,c) = Lazy.force c
+ let stack_to_env ~reduce:_ ~unwind:_ config = config
+ let compute_to_env ~reduce ~unwind k e t =
+ lazy (reduce (k,e,t,[])), lazy (unwind (k,e,t,[]))
+ let compute_to_stack ~reduce ~unwind config =
+ lazy (reduce config), lazy (unwind config)
+ end
+;;
+
+
+(* {{{ module CallByValueByNameForUnwind =
struct
type config = int * env_term list * ens_term Cic.explicit_named_substitution * Cic.term * stack_term list
and stack_term = config
let compute_to_stack ~reduce ~unwind config = config
end
;;
-*)
-
-module CallByValueByNameForUnwind' =
- struct
- type config = int * env_term list * NCic.term * stack_term list
- and stack_term = config lazy_t * NCic.term lazy_t (* cbv, cbn *)
- and env_term = config lazy_t * NCic.term lazy_t (* cbv, cbn *)
- let to_env ~reduce ~unwind c = lazy (reduce c),lazy (unwind c)
- let from_stack (c,_) = Lazy.force c
- let from_stack_list_for_unwind ~unwind:_ l =
- List.map (function (_,c) -> Lazy.force c) l
- let from_env (c,_) = Lazy.force c
- let from_env_for_unwind ~unwind:_ (_,c) = Lazy.force c
- let stack_to_env ~reduce:_ ~unwind:_ config = config
- let compute_to_env ~reduce ~unwind k e t =
- lazy (reduce (k,e,t,[])), lazy (unwind (k,e,t,[]))
- let compute_to_stack ~reduce ~unwind config =
- lazy (reduce config), lazy (unwind config)
- end
-;;
-(* Old Machine
+(* Old Machine *)
module CallByNameStrategy =
struct
type stack_term = Cic.term
end
;;
-*)
+}}} *)
module Reduction(RS : Strategy) =
struct
List.map (fun t->RS.compute_to_stack ~reduce:aux ~unwind (k,e,t,[])) tl
in
aux (k, e, he, tl' @ s)
- | (_, _, NCic.Const(NReference.Ref (_,_,NReference.Def) as refer), s) as config ->
+ | (_, _, NCic.Const
+ (NReference.Ref (_,_,NReference.Def) as refer), s) as config ->
let _,_,body,_,_,height = NCicEnvironment.get_checked_def refer in
if delta >= height then config else aux (0, [], body, s)
| (_, _, NCic.Const (NReference.Ref
;;
-(* ROTTO = rompe l'unificazione poiche' riduce gli argomenti di un'applicazione
+(* {{{ ROTTO = rompe l'unificazione poiche' riduce gli argomenti di un'applicazione
senza ridurre la testa
module R = Reduction CallByNameStrategy;; OK 56.368s
module R = Reduction CallByValueStrategy;; ROTTO
module R = Reduction
ClosuresOnStackByValueFromEnvOrEnsByNameOnConstantsStrategy;; OK 58.094s
module R = Reduction(ClosuresOnStackByValueFromEnvOrEnsStrategy);; OK 58.127s
-*)
-(*module R = Reduction(CallByValueByNameForUnwind);;*)
+module R = Reduction(CallByValueByNameForUnwind);;
+module R = Reduction(CallByNameStrategy);;
+module R = Reduction(ClosuresOnStackByValueFromEnvOrEnsStrategy);;}}} *)
module RS = CallByValueByNameForUnwind';;
-(*module R = Reduction(CallByNameStrategy);;*)
-(*module R = Reduction(ClosuresOnStackByValueFromEnvOrEnsStrategy);;*)
-(*
module R = Reduction(RS);;
module U = UriManager;;
let whd = R.whd
-*)
(*
let whd =
profiler_whd.HExtlib.profile (whd ~delta ~subst context) t
*)
-(*
+(* mimic ocaml (<< 3.08) "=" behaviour. Tests physical equality first then
+ * fallbacks to structural equality *)
+let (===) x y = Pervasives.compare x y = 0 ;;
- (* mimic ocaml (<< 3.08) "=" behaviour. Tests physical equality first then
- * fallbacks to structural equality *)
-let (===) x y =
- Pervasives.compare x y = 0
+module C = NCic
(* t1, t2 must be well-typed *)
let are_convertible whd ?(subst=[]) ?(metasenv=[]) =
- let heuristic = ref true in
- let rec aux test_equality_only context t1 t2 ugraph =
- let rec aux2 test_equality_only t1 t2 ugraph =
-
- (* 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,ugraph
- else
- begin
- let module C = Cic in
+ let rec aux test_equality_only context t1 t2 =
+ let rec aux2 test_equality_only t1 t2 =
+ if t1 === t2 then
+ true
+ else
match (t1,t2) with
- (C.Rel n1, C.Rel n2) -> (n1 = n2),ugraph
- | (C.Var (uri1,exp_named_subst1), C.Var (uri2,exp_named_subst2)) ->
- if U.eq uri1 uri2 then
- (try
- List.fold_right2
- (fun (uri1,x) (uri2,y) (b,ugraph) ->
- let b',ugraph' = aux test_equality_only context x y ugraph in
- (U.eq uri1 uri2 && b' && b),ugraph'
- ) exp_named_subst1 exp_named_subst2 (true,ugraph)
- with
- Invalid_argument _ -> false,ugraph
- )
- else
- false,ugraph
- | (C.Meta (n1,l1), C.Meta (n2,l2)) ->
- if n1 = n2 then
- let b2, ugraph1 =
- let l1 = CicUtil.clean_up_local_context subst metasenv n1 l1 in
- let l2 = CicUtil.clean_up_local_context subst metasenv n2 l2 in
- List.fold_left2
- (fun (b,ugraph) t1 t2 ->
- if b then
- match t1,t2 with
- None,_
- | _,None -> true,ugraph
- | Some t1',Some t2' ->
- aux test_equality_only context t1' t2' ugraph
- else
- false,ugraph
- ) (true,ugraph) l1 l2
- in
- if b2 then true,ugraph1 else false,ugraph
- else
- false,ugraph
- | C.Meta (n1,l1), _ ->
- (try
- let _,term,_ = NCicUtils.lookup_subst n1 subst in
- let term' = CicSubstitution.subst_meta l1 term in
-(*
-prerr_endline ("%?: " ^ CicPp.ppterm t1 ^ " <==> " ^ CicPp.ppterm t2);
-prerr_endline ("%%%%%%: " ^ CicPp.ppterm term' ^ " <==> " ^ CicPp.ppterm t2);
-*)
- aux test_equality_only context term' t2 ugraph
- with CicUtil.Subst_not_found _ -> false,ugraph)
- | _, C.Meta (n2,l2) ->
- (try
- let _,term,_ = CicUtil.lookup_subst n2 subst in
- let term' = CicSubstitution.subst_meta l2 term in
-(*
-prerr_endline ("%?: " ^ CicPp.ppterm t1 ^ " <==> " ^ CicPp.ppterm t2);
-prerr_endline ("%%%%%%: " ^ CicPp.ppterm term' ^ " <==> " ^ CicPp.ppterm t1);
-*)
- aux test_equality_only context t1 term' ugraph
- with CicUtil.Subst_not_found _ -> false,ugraph)
- (* TASSI: CONSTRAINTS *)
- | (C.Sort (C.Type t1), C.Sort (C.Type t2)) when test_equality_only ->
- (try
- true,(CicUniv.add_eq t2 t1 ugraph)
- with CicUniv.UniverseInconsistency _ -> false,ugraph)
- | (C.Sort (C.Type t1), C.Sort (C.Type t2)) ->
- (try
- true,(CicUniv.add_ge t2 t1 ugraph)
- with CicUniv.UniverseInconsistency _ -> false,ugraph)
- | (C.Sort s1, C.Sort (C.Type _)) -> (not test_equality_only),ugraph
- | (C.Sort s1, C.Sort s2) -> (s1 = s2),ugraph
- | (C.Prod (name1,s1,t1), C.Prod(_,s2,t2)) ->
- let b',ugraph' = aux true context s1 s2 ugraph in
- if b' then
- aux test_equality_only ((Some (name1, (C.Decl s1)))::context)
- t1 t2 ugraph'
- else
- false,ugraph
- | (C.Lambda (name1,s1,t1), C.Lambda(_,s2,t2)) ->
- let b',ugraph' = aux test_equality_only context s1 s2 ugraph in
- if b' then
- aux test_equality_only ((Some (name1, (C.Decl s1)))::context)
- t1 t2 ugraph'
- else
- false,ugraph
- | (C.LetIn (name1,s1,t1), C.LetIn(_,s2,t2)) ->
- let b',ugraph' = aux test_equality_only context s1 s2 ugraph in
- if b' then
- aux test_equality_only
- ((Some (name1, (C.Def (s1,None))))::context) t1 t2 ugraph'
- else
- false,ugraph
- | (C.Appl l1, C.Appl l2) ->
- (try
- List.fold_right2
- (fun x y (b,ugraph) ->
- if b then
- aux test_equality_only context x y ugraph
- else
- false,ugraph) l1 l2 (true,ugraph)
- with
- Invalid_argument _ -> false,ugraph
- )
- | (C.Const (uri1,exp_named_subst1), C.Const (uri2,exp_named_subst2)) ->
- let b' = U.eq uri1 uri2 in
- if b' then
- (try
- List.fold_right2
- (fun (uri1,x) (uri2,y) (b,ugraph) ->
- if b && U.eq uri1 uri2 then
- aux test_equality_only context x y ugraph
- else
- false,ugraph
- ) exp_named_subst1 exp_named_subst2 (true,ugraph)
- with
- Invalid_argument _ -> false,ugraph
- )
- else
- false,ugraph
- | (C.MutInd (uri1,i1,exp_named_subst1),
- C.MutInd (uri2,i2,exp_named_subst2)
- ) ->
- let b' = U.eq uri1 uri2 && i1 = i2 in
- if b' then
- (try
- List.fold_right2
- (fun (uri1,x) (uri2,y) (b,ugraph) ->
- if b && U.eq uri1 uri2 then
- aux test_equality_only context x y ugraph
- else
- false,ugraph
- ) exp_named_subst1 exp_named_subst2 (true,ugraph)
- with
- Invalid_argument _ -> false,ugraph
- )
- else
- false,ugraph
- | (C.MutConstruct (uri1,i1,j1,exp_named_subst1),
- C.MutConstruct (uri2,i2,j2,exp_named_subst2)
- ) ->
- let b' = U.eq uri1 uri2 && i1 = i2 && j1 = j2 in
- if b' then
- (try
- List.fold_right2
- (fun (uri1,x) (uri2,y) (b,ugraph) ->
- if b && U.eq uri1 uri2 then
- aux test_equality_only context x y ugraph
- else
- false,ugraph
- ) exp_named_subst1 exp_named_subst2 (true,ugraph)
- with
- Invalid_argument _ -> false,ugraph
- )
- else
- false,ugraph
- | (C.MutCase (uri1,i1,outtype1,term1,pl1),
- C.MutCase (uri2,i2,outtype2,term2,pl2)) ->
- let b' = U.eq uri1 uri2 && i1 = i2 in
- if b' then
- let b'',ugraph''=aux test_equality_only context
- outtype1 outtype2 ugraph in
- if b'' then
- let b''',ugraph'''= aux test_equality_only context
- term1 term2 ugraph'' in
- List.fold_right2
- (fun x y (b,ugraph) ->
- if b then
- aux test_equality_only context x y ugraph
- else
- false,ugraph)
- pl1 pl2 (b''',ugraph''')
- else
- false,ugraph
- else
- false,ugraph
- | (C.Fix (i1,fl1), C.Fix (i2,fl2)) ->
- let tys,_ =
- List.fold_left
- (fun (types,len) (n,_,ty,_) ->
- (Some (C.Name n,(C.Decl (CicSubstitution.lift len ty)))::types,
- len+1)
- ) ([],0) fl1
- in
- if i1 = i2 then
- List.fold_right2
- (fun (_,recindex1,ty1,bo1) (_,recindex2,ty2,bo2) (b,ugraph) ->
- if b && recindex1 = recindex2 then
- let b',ugraph' = aux test_equality_only context ty1 ty2
- ugraph in
- if b' then
- aux test_equality_only (tys@context) bo1 bo2 ugraph'
- else
- false,ugraph
- else
- false,ugraph)
- fl1 fl2 (true,ugraph)
- else
- false,ugraph
- | (C.CoFix (i1,fl1), C.CoFix (i2,fl2)) ->
- let tys,_ =
- List.fold_left
- (fun (types,len) (n,ty,_) ->
- (Some (C.Name n,(C.Decl (CicSubstitution.lift len ty)))::types,
- len+1)
- ) ([],0) fl1
- in
- if i1 = i2 then
- List.fold_right2
- (fun (_,ty1,bo1) (_,ty2,bo2) (b,ugraph) ->
- if b then
- let b',ugraph' = aux test_equality_only context ty1 ty2
- ugraph in
- if b' then
- aux test_equality_only (tys@context) bo1 bo2 ugraph'
- else
- false,ugraph
- else
- false,ugraph)
- fl1 fl2 (true,ugraph)
- else
- false,ugraph
- | C.Cast (bo,_),t -> aux2 test_equality_only bo t ugraph
- | t,C.Cast (bo,_) -> aux2 test_equality_only t bo ugraph
- | (C.Implicit _, _) | (_, C.Implicit _) -> assert false
- | (_,_) -> false,ugraph
- end
+ | (C.Sort (C.Type a), C.Sort (C.Type b)) -> a <= b
+ | (C.Sort s1,C.Sort (C.Type _)) -> (not test_equality_only)
+ | (C.Sort s1, C.Sort s2) -> s1 = s2
+
+ | (C.Prod (name1,s1,t1), C.Prod(_,s2,t2)) ->
+ aux true context s1 s2 &&
+ aux test_equality_only ((name1, C.Decl s1)::context) t1 t2
+ | (C.Lambda (name1,s1,t1), C.Lambda(_,s2,t2)) ->
+ aux true context s1 s2 &&
+ aux true ((name1, C.Decl s1)::context) t1 t2
+ | (C.LetIn (name1,ty1,s1,t1), C.LetIn(_,ty2,s2,t2)) ->
+ aux test_equality_only context ty1 ty2 &&
+ aux test_equality_only context s1 s2 &&
+ aux test_equality_only ((name1, C.Def (s1,ty1))::context) t1 t2
+
+ | (C.Meta (n1,(s1, C.Irl i1)), C.Meta (n2,(s2, C.Irl i2)))
+ when n1 = n2 && s1 = s2 -> true
+ | (C.Meta (n1,(s1, l1)), C.Meta (n2,(s2, l2))) when n1 = n2 ->
+ let l1 = NCicUtils.expand_local_context l1 in
+ let l2 = NCicUtils.expand_local_context l2 in
+ (try List.for_all2
+ (fun t1 t2 -> aux test_equality_only context
+ (NCicSubstitution.lift s1 t1)
+ (NCicSubstitution.lift s2 t2))
+ l1 l2
+ with Invalid_argument _ -> false)
+
+ | C.Meta (n1,l1), _ ->
+ (try
+ let _,_,term,_ = NCicUtils.lookup_subst n1 subst in
+ let term = NCicSubstitution.subst_meta l1 term in
+ aux test_equality_only context term t2
+ with NCicUtils.Subst_not_found _ -> false)
+ | _, C.Meta (n2,l2) ->
+ (try
+ let _,_,term,_ = NCicUtils.lookup_subst n2 subst in
+ let term = NCicSubstitution.subst_meta l2 term in
+ aux test_equality_only context t1 term
+ with NCicUtils.Subst_not_found _ -> false)
+
+ | (C.Appl l1, C.Appl l2) ->
+ (try List.for_all2 (aux test_equality_only context) l1 l2
+ with Invalid_argument _ -> false)
+
+ | (C.Match (ref1,outtype1,term1,pl1),
+ C.Match (ref2,outtype2,term2,pl2)) ->
+ NReference.eq ref1 ref2 &&
+ aux test_equality_only context outtype1 outtype2 &&
+ aux test_equality_only context term1 term2 &&
+ (try List.for_all2 (aux test_equality_only context) pl1 pl2
+ with Invalid_argument _ -> false)
+
+ | (C.Implicit _, _) | (_, C.Implicit _) -> assert false
+ | (_,_) -> false
in
- let res =
- if !heuristic then
- aux2 test_equality_only t1 t2 ugraph
- else
- false,ugraph
- in
- if fst res = true then
- res
- else
-begin
-(*if !heuristic then prerr_endline ("NON FACILE: " ^ CicPp.ppterm t1 ^ " <===> " ^ CicPp.ppterm t2);*)
- (* heuristic := false; *)
- debug t1 [t2] "PREWHD";
-(*prerr_endline ("PREWHD: " ^ CicPp.ppterm t1 ^ " <===> " ^ CicPp.ppterm t2);*)
-(*
-prerr_endline ("PREWHD: " ^ CicPp.ppterm t1 ^ " <===> " ^ CicPp.ppterm t2);
- let t1' = whd ?delta:(Some true) ?subst:(Some subst) context t1 in
- let t2' = whd ?delta:(Some true) ?subst:(Some subst) context t2 in
- debug t1' [t2'] "POSTWHD";
-*)
-let rec convert_machines ugraph =
- function
- [] -> true,ugraph
- | ((k1,env1,ens1,h1,s1),(k2,env2,ens2,h2,s2))::tl ->
- let (b,ugraph) as res =
- aux2 test_equality_only
- (R.unwind (k1,env1,ens1,h1,[])) (R.unwind (k2,env2,ens2,h2,[])) ugraph
+ if aux2 test_equality_only t1 t2 then
+ true
+ else
+ let rec convert_machines = function
+ | [] -> true
+ | ((k1,env1,h1,s1),(k2,env2,h2,s2))::tl ->
+ aux2 test_equality_only
+ (R.unwind (k1,env1,h1,[])) (R.unwind (k2,env2,h2,[])) &&
+ let problems =
+ let red_stack =
+ List.map
+ (fun si-> R.reduce ~delta:0 ~subst context(RS.from_stack si))
+ in
+ try Some (List.combine (red_stack s1) (red_stack s2) @ tl)
+ with Invalid_argument _ -> None
+ in
+ match problems with
+ | None -> false
+ | Some problems -> convert_machines problems
in
- if b then
- let problems =
- try
- Some
- (List.combine
- (List.map
- (fun si-> R.reduce ~delta:false ~subst context(RS.from_stack si))
- s1)
- (List.map
- (fun si-> R.reduce ~delta:false ~subst context(RS.from_stack si))
- s2)
- @ tl)
- with
- Invalid_argument _ -> None
- in
- match problems with
- None -> false,ugraph
- | Some problems -> convert_machines ugraph problems
- else
- res
-in
- convert_machines ugraph
- [R.reduce ~delta:true ~subst context (0,[],[],t1,[]),
- R.reduce ~delta:true ~subst context (0,[],[],t2,[])]
-(*prerr_endline ("POSTWH: " ^ CicPp.ppterm t1' ^ " <===> " ^ CicPp.ppterm t2');*)
-(*
- aux2 test_equality_only t1' t2' ugraph
-*)
-end
+ convert_machines
+ [R.reduce ~delta:0 ~subst context (0,[],t1,[]),
+ R.reduce ~delta:0 ~subst context (0,[],t2,[])]
in
- aux false (*c t1 t2 ugraph *)
+ aux false
;;
-*)
-(* DEBUGGING ONLY
-let whd ?(delta=true) ?(subst=[]) context t =
- let res = whd ~delta ~subst context t in
- let rescsc = CicReductionNaif.whd ~delta ~subst context t in
- if not (fst (are_convertible CicReductionNaif.whd ~subst context res rescsc CicUniv.empty_ugraph)) then
- begin
- debug_print (lazy ("PRIMA: " ^ CicPp.ppterm t)) ;
- flush stderr ;
- debug_print (lazy ("DOPO: " ^ CicPp.ppterm res)) ;
- flush stderr ;
- debug_print (lazy ("CSC: " ^ CicPp.ppterm rescsc)) ;
- flush stderr ;
-fdebug := 0 ;
-let _ = are_convertible CicReductionNaif.whd ~subst context res rescsc CicUniv.empty_ugraph in
- assert false ;
- end
- else
- res
-;;
-*)
-
-(*
let are_convertible = are_convertible whd
-let whd = R.whd
-*)
-
-(*
-let profiler_other_whd = HExtlib.profile ~enable:profile "~are_convertible.whd"
-let whd ?(delta=true) ?(subst=[]) context t =
- let foo () =
- whd ~delta ~subst context t
- in
- profiler_other_whd.HExtlib.profile foo ()
-*)
+let rec head_beta_reduce ?(delta=max_int) ?(upto=(-1)) t l =
+ match upto, t, l with
+ | 0, C.Appl l1, _ -> C.Appl (l1 @ l)
+ | 0, t, [] -> t
+ | 0, t, _ -> C.Appl (t::l)
+ | _, C.Appl (hd::tl), _ -> head_beta_reduce ~delta ~upto hd (tl @ l)
+ | _, C.Lambda(_,_,bo), arg::tl ->
+ let bo = NCicSubstitution.subst arg bo in
+ head_beta_reduce ~delta ~upto:(upto - 1) bo tl
+ | _, C.Const (NReference.Ref (height, _, NReference.Def) as re), _
+ when delta <= height ->
+ let _, _, bo, _, _, _ = NCicEnvironment.get_checked_def re in
+ head_beta_reduce ~upto ~delta bo l
+ | _, t, [] -> t
+ | _, t, _ -> C.Appl (t::l)
+;;
-(*
-let rec normalize ?(delta=true) ?(subst=[]) ctx term =
- let module C = Cic in
- let t = whd ~delta ~subst ctx term in
- let aux = normalize ~delta ~subst in
- let decl name t = Some (name, C.Decl t) in
- match t with
- | C.Rel n -> t
- | C.Var (uri,exp_named_subst) ->
- C.Var (uri, List.map (fun (n,t) -> n,aux ctx t) exp_named_subst)
- | C.Meta (i,l) ->
- C.Meta (i,List.map (function Some t -> Some (aux ctx t) | None -> None) l)
- | C.Sort _ -> t
- | C.Implicit _ -> t
- | C.Cast (te,ty) -> C.Cast (aux ctx te, aux ctx ty)
- | C.Prod (n,s,t) ->
- let s' = aux ctx s in
- C.Prod (n, s', aux ((decl n s')::ctx) t)
- | C.Lambda (n,s,t) ->
- let s' = aux ctx s in
- C.Lambda (n, s', aux ((decl n s')::ctx) t)
- | C.LetIn (n,s,t) ->
- (* the term is already in weak head normal form *)
- assert false
- | C.Appl (h::l) -> C.Appl (h::(List.map (aux ctx) l))
- | C.Appl [] -> assert false
- | C.Const (uri,exp_named_subst) ->
- C.Const (uri, List.map (fun (n,t) -> n,aux ctx t) exp_named_subst)
- | C.MutInd (uri,typeno,exp_named_subst) ->
- C.MutInd (uri,typeno, List.map (fun (n,t) -> n,aux ctx t) exp_named_subst)
- | C.MutConstruct (uri,typeno,consno,exp_named_subst) ->
- C.MutConstruct (uri, typeno, consno,
- List.map (fun (n,t) -> n,aux ctx t) exp_named_subst)
- | C.MutCase (sp,i,outt,t,pl) ->
- C.MutCase (sp,i, aux ctx outt, aux ctx t, List.map (aux ctx) pl)
-(*CSC: to be completed, I suppose *)
- | C.Fix _ -> t
- | C.CoFix _ -> t
-*)
+let head_beta_reduce ?delta ?upto t = head_beta_reduce ?delta ?upto t [];;
-(*
-let normalize ?delta ?subst ctx term =
-(* prerr_endline ("NORMALIZE:" ^ CicPp.ppterm term); *)
- let t = normalize ?delta ?subst ctx term in
-(* prerr_endline ("NORMALIZED:" ^ CicPp.ppterm t); *)
- t
-*)
-
-(* performs an head beta/cast reduction
-let rec head_beta_reduce ?(delta=false) ?(upto=(-1)) t =
- match upto with
- 0 -> t
- | n ->
- match t with
- (Cic.Appl (Cic.Lambda (_,_,t)::he'::tl')) ->
- let he'' = CicSubstitution.subst he' t in
- if tl' = [] then
- he''
- else
- let he''' =
- match he'' with
- Cic.Appl l -> Cic.Appl (l@tl')
- | _ -> Cic.Appl (he''::tl')
- in
- head_beta_reduce ~delta ~upto:(upto - 1) he'''
- | Cic.Cast (te,_) -> head_beta_reduce ~delta ~upto te
- | Cic.Appl (Cic.Const (uri,ens)::tl) as t when delta=true ->
- let bo =
- match fst (CicEnvironment.get_cooked_obj CicUniv.empty_ugraph uri) with
- Cic.Constant (_,bo,_,_,_) -> bo
- | Cic.Variable _ -> raise ReferenceToVariable
- | Cic.CurrentProof (_,_,bo,_,_,_) -> Some bo
- | Cic.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
- in
- (match bo with
- None -> t
- | Some bo ->
- head_beta_reduce ~upto
- ~delta (Cic.Appl ((CicSubstitution.subst_vars ens bo)::tl)))
- | Cic.Const (uri,ens) as t when delta=true ->
- let bo =
- match fst (CicEnvironment.get_cooked_obj CicUniv.empty_ugraph uri) with
- Cic.Constant (_,bo,_,_,_) -> bo
- | Cic.Variable _ -> raise ReferenceToVariable
- | Cic.CurrentProof (_,_,bo,_,_,_) -> Some bo
- | Cic.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
- in
- (match bo with
- None -> t
- | Some bo ->
- head_beta_reduce ~delta ~upto (CicSubstitution.subst_vars ens bo))
- | t -> t
-*)
-(*
-let are_convertible ?subst ?metasenv context t1 t2 ugraph =
- let before = Unix.gettimeofday () in
- let res = are_convertible ?subst ?metasenv context t1 t2 ugraph in
- let after = Unix.gettimeofday () in
- let diff = after -. before in
- if diff > 0.1 then
- begin
- let nc = List.map (function None -> None | Some (n,_) -> Some n) context in
- prerr_endline
- ("\n#(" ^ string_of_float diff ^ "):\n" ^ CicPp.pp t1 nc ^ "\n<=>\n" ^ CicPp.pp t2 nc);
- end;
- res
-*)
+(* vim:set foldmethod=marker: *)