aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorherbelin2000-05-31 11:46:29 +0000
committerherbelin2000-05-31 11:46:29 +0000
commit301d5af223390fa5c82da9ae9958f610493ba814 (patch)
tree304f4b7b194ace4c6fac67af90a0bcdf3ff3537f /kernel
parentaca8a6bbb4fa372cd3b27680eee642082d1c2ad5 (diff)
Nettoyage de Generic
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@482 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'kernel')
-rw-r--r--kernel/abstraction.ml9
-rw-r--r--kernel/generic.ml250
-rw-r--r--kernel/generic.mli112
-rw-r--r--kernel/instantiate.ml2
-rw-r--r--kernel/reduction.ml21
-rw-r--r--kernel/term.ml139
-rw-r--r--kernel/term.mli50
-rw-r--r--kernel/typeops.ml89
-rw-r--r--kernel/typeops.mli4
9 files changed, 287 insertions, 389 deletions
diff --git a/kernel/abstraction.ml b/kernel/abstraction.ml
index e0b86dbf27..9df751b46f 100644
--- a/kernel/abstraction.ml
+++ b/kernel/abstraction.ml
@@ -11,6 +11,15 @@ type abstraction_body = {
abs_arity : int array;
abs_rhs : constr }
+let rec count_dlam = function
+ | DLAM (_,c) -> 1 + (count_dlam c)
+ | _ -> 0
+
+let sAPP c n =
+ match c with
+ | DLAM(na,m) -> subst1 n m
+ | _ -> invalid_arg "SAPP"
+
let contract_abstraction ab args =
if array_for_all2 (fun c i -> (count_dlam c) = i) args ab.abs_arity then
Sosub.soexecute (Array.fold_left sAPP ab.abs_rhs args)
diff --git a/kernel/generic.ml b/kernel/generic.ml
index 2a8af630da..70acca45dd 100644
--- a/kernel/generic.ml
+++ b/kernel/generic.ml
@@ -23,9 +23,6 @@ type 'oper term =
exception FreeVar
exception Occur
-let isRel = function Rel _ -> true | _ -> false
-let isVAR = function VAR _ -> true | _ -> false
-
(* returns the list of free debruijn indices in a term *)
let free_rels m =
@@ -59,7 +56,7 @@ let closedn =
in
closed_rec
-(* (closed M) is true iff M is a (deBruijn) closed term *)
+(* [closed0 M] is true iff [M] is a (deBruijn) closed term *)
let closed0 term =
try closedn 0 term; true with FreeVar -> false
@@ -80,10 +77,10 @@ let noccurn n term =
in
try occur_rec n term; true with Occur -> false
-(* (noccur_bet n m M) returns true iff (Rel p) does NOT occur in term M
+(* (noccur_between n m M) returns true iff (Rel p) does NOT occur in term M
for n <= p < n+m *)
-let noccur_bet n m term =
+let noccur_between n m term =
let rec occur_rec n = function
| Rel(p) -> if n<=p && p<n+m then raise Occur
| VAR _ -> ()
@@ -146,7 +143,8 @@ let liftn k n =
| el -> exliftn el
let lift k = liftn k 1
-let lift1 c = exliftn (ELSHFT(ELID,1)) c
+
+let pop t = lift (-1) t
let lift_context n l =
let k = List.length l in
@@ -242,85 +240,11 @@ let substn_many lamv n =
in
substrec n
+let substnl laml k =
+ substn_many (Array.map make_substituend (Array.of_list laml)) k
let substl laml =
substn_many (Array.map make_substituend (Array.of_list laml)) 0
let subst1 lam = substl [lam]
-let pop t = lift (-1) t
-
-
-(* Various occurs checks *)
-
-let occur_opern s =
- let rec occur_rec = function
- | DOPN(oper,cl) -> s=oper or (array_exists occur_rec cl)
- | DOPL(oper,cl) -> s=oper or (List.exists occur_rec cl)
- | VAR _ -> false
- | DOP1(_,c) -> occur_rec c
- | DOP2(_,c1,c2) -> (occur_rec c1) or (occur_rec c2)
- | DLAM(_,c) -> occur_rec c
- | DLAMV(_,v) -> array_exists occur_rec v
- | _ -> false
- in
- occur_rec
-
-let occur_oper0 s =
- let rec occur_rec = function
- | DOPN(_,cl) -> (array_exists occur_rec cl)
- | DOPL(_,cl) -> (List.exists occur_rec cl)
- | DOP0 oper -> s=oper
- | VAR _ -> false
- | DOP1(_,c) -> occur_rec c
- | DOP2(_,c1,c2) -> (occur_rec c1) or (occur_rec c2)
- | DLAM(_,c) -> occur_rec c
- | DLAMV(_,v) -> array_exists occur_rec v
- | _ -> false
- in
- occur_rec
-
-let occur_var s =
- let rec occur_rec = function
- | DOPN(_,cl) -> array_exists occur_rec cl
- | DOPL(_,cl) -> List.exists occur_rec cl
- | VAR id -> s=id
- | DOP1(_,c) -> occur_rec c
- | DOP2(_,c1,c2) -> (occur_rec c1) or (occur_rec c2)
- | DLAM(_,c) -> occur_rec c
- | DLAMV(_,v) -> array_exists occur_rec v
- | _ -> false
- in
- occur_rec
-
-let occur_oper s =
- let rec occur_rec = function
- | DOPN(oper,cl) -> s=oper or (array_exists occur_rec cl)
- | DOPL(oper,cl) -> s=oper or (List.exists occur_rec cl)
- | VAR _ -> false
- | DOP0 oper -> s=oper
- | DOP1(oper,c) -> s=oper or occur_rec c
- | DOP2(oper,c1,c2) -> s=oper or (occur_rec c1) or (occur_rec c2)
- | DLAM(_,c) -> occur_rec c
- | DLAMV(_,v) -> array_exists occur_rec v
- | _ -> false
- in
- occur_rec
-
-let process_opers_of_term p f l constr =
- let rec filtrec acc = function
- | DOP0 oper -> if p oper then ((f oper)::acc) else acc
- | VAR _ -> acc
- | DOP1(oper,c) -> let newacc = filtrec acc c in
- if p oper then ((f oper)::newacc) else newacc
- | DOP2(oper,c1,c2) -> let newacc = filtrec (filtrec acc c1) c2 in
- if p oper then ((f oper)::newacc) else newacc
- | DOPN(oper,cl) -> let newacc = (Array.fold_left filtrec acc cl) in
- if p oper then ((f oper)::newacc) else newacc
- | DOPL(oper,cl) -> let newacc = (List.fold_left filtrec acc cl) in
- if p oper then ((f oper)::newacc) else newacc
- | DLAM(_,c) -> filtrec acc c
- | DLAMV(_,v) -> Array.fold_left filtrec acc v
- | _ -> acc
- in
- filtrec l constr
(* Returns the list of global variables in a term *)
@@ -352,42 +276,6 @@ let global_vars_set constr =
in
filtrec Idset.empty constr
-(* alpha equality for generic terms : checks first if M and M' are equal,
- otherwise checks equality forgetting the name annotation of DLAM and DLAMV*)
-
-let rec eq_term m m' =
- (m == m')
- or (m = m')
- or (match (m,m') with
- | (DOP1(oper1,c1),DOP1(oper2,c2)) ->
- oper1 = oper2 & eq_term c1 c2
- | (DOP2(oper1,c1,t1),DOP2(oper2,c2,t2)) ->
- oper1 = oper2 & eq_term c1 c2 & eq_term t1 t2
- | (DOPN(oper1,cl1),DOPN(oper2,cl2)) ->
- oper1 = oper2 & array_for_all2 eq_term cl1 cl2
- | (DOPL(oper1,cl1),DOPL(oper2,cl2)) ->
- oper1 = oper2 & List.for_all2 eq_term cl1 cl2
- | (DLAM(_,c1),DLAM(_,c2)) -> eq_term c1 c2
- | (DLAMV(_,cl1),DLAMV(_,cl2)) -> array_for_all2 eq_term cl1 cl2
- | _ -> false)
-
-(* (dependent M N) is true iff M is eq_term with a subterm of N
- M is appropriately lifted through abstractions of N *)
-let dependent =
- let rec deprec m = function t ->
- (eq_term m t)
- or (match t with
- | VAR _ -> false
- | DOP1(_,c) -> deprec m c
- | DOP2(_,c,t) -> deprec m c or deprec m t
- | DOPN(_,cl) -> array_exists (deprec m) cl
- | DOPL(_,cl) -> List.exists (deprec m) cl
- | DLAM(_,c) -> deprec (lift1 m) c
- | DLAMV(_,v) -> array_exists (deprec (lift1 m)) v
- | _ -> false)
- in
- deprec
-
(* (thin_val sigma) removes identity substitutions from sigma *)
let rec thin_val = function
@@ -398,6 +286,8 @@ let rec thin_val = function
(* (replace_vars sigma M) applies substitution sigma to term M *)
let replace_vars var_alist =
+ let var_alist =
+ List.map (fun (str,c) -> (str,make_substituend c)) var_alist in
let var_alist = thin_val var_alist in
let rec substrec n = function
| (VAR(x) as c) ->
@@ -414,54 +304,22 @@ let replace_vars var_alist =
in
if var_alist = [] then (function x -> x) else substrec 0
-let subst_varn str n = replace_vars [(str,make_substituend (Rel n))]
+let subst_varn str n = replace_vars [(str, (Rel n))]
(* (subst_var str t) substitute (VAR str) by (Rel 1) in t *)
let subst_var str = subst_varn str 1
+(* [Rel (n+m);...;Rel(n+1)] *)
-(* renames different ocurrences of (VAR id) in t with a fresh identifier
- wrt. acc *)
-let rename_diff_occ id acc t =
- let rec rename_occ acc = function
- | (VAR(x) as c) ->
- if x <> id then
- acc,c
- else
- let nid = next_ident_away id acc in (nid::acc), (VAR nid)
- | DOPN(oper,cl) ->
- let nacc,ncl = vrename_occ acc cl in nacc,DOPN(oper, ncl)
- | DOPL(oper,cl) ->
- let nacc,ncl = lrename_occ acc cl in nacc, DOPL(oper,ncl)
- | DOP1(oper,c) ->
- let nacc,nc = rename_occ acc c in nacc, DOP1(oper,nc)
- | DOP2(oper,c1,c2) ->
- let nacc,nc1 = rename_occ acc c1 in
- let nacc2,nc2 = rename_occ nacc c2 in
- nacc2, DOP2(oper,nc1,nc2)
- | DLAM(na,c) ->
- let nacc,nc = rename_occ acc c in (nacc, DLAM(na,nc))
- | DLAMV(na,v) ->
- let nacc,nv = vrename_occ acc v in (nacc, DLAMV(na, nv))
- | x -> acc,x
- and lrename_occ acc = function
- | [] -> acc,[]
- | (t::lt) ->
- let nacc,nt = rename_occ acc t in
- let nacc2,nlt = lrename_occ nacc lt
- in nacc2,(nt::nlt)
- and vrename_occ acc v =
- let nacc,nl = lrename_occ acc (Array.to_list v)
- in nacc, Array.of_list nl
- in
- rename_occ acc t
+let rel_vect n m = Array.init m (fun i -> Rel(n+m-i))
+let rel_list n m =
+ let rec reln l p =
+ if p>m then l else reln (Rel(n+p)::l) (p+1)
+ in
+ reln [] 1
-let sAPP c n =
- match c with
- | DLAM(na,m) -> subst1 n m
- | _ -> invalid_arg "SAPP"
-
+(* Obsolète
let sAPPV c n =
match c with
| DLAMV(na,mV) -> Array.map (subst1 n) mV
@@ -480,22 +338,6 @@ let sAPPList constr cl =
in
srec [] (constr,cl)
-let sAPPVList constr cl =
- let rec srec stack = function
- | (DLAM(_,c), (h::t)) -> srec (h::stack) (c,t)
- | (DLAMV(_,c), [h]) -> Array.map (substl (h::stack)) c
- | (_, _) -> failwith "SAPPVList"
- in
- srec [] (constr,cl)
-
-let sAPPViList i constr cl=
- let rec srec stack = function
- | (DLAM(_,c), (h::t)) -> srec (h::stack) (c,t)
- | (DLAMV(_,c), [h]) -> substl (h::stack) c.(i)
- | (_, _) -> failwith "SAPPViList"
- in
- srec [] (constr,cl)
-
let under_dlams f =
let rec apprec = function
| DLAMV(na,c) -> DLAMV(na,Array.map f c)
@@ -504,19 +346,11 @@ let under_dlams f =
in
apprec
-
let put_DLAMSV lna lc =
match lna with
| [] -> anomaly "put_DLAM"
| na::lrest -> List.fold_left (fun c na -> DLAM(na,c)) (DLAMV(na,lc)) lrest
-let put_DLAMSV_subst lid lc =
- match lid with
- | [] -> anomaly "put_DLAM"
- | id::lrest ->
- List.fold_left (fun c id' -> DLAM(Name id',subst_var id' c))
- (DLAMV(Name id,Array.map (subst_var id) lc)) lrest
-
let rec decomp_DLAMV n = function
| DLAM(_,lc) -> decomp_DLAMV (n-1) lc
| DLAMV(_,lc) -> if n = 1 then lc else error "decomp_DLAMV 0"
@@ -537,50 +371,4 @@ let decomp_all_DLAMV_name constr =
| _ -> assert false
in
decomprec [] constr
-
-
-(* [Rel (n+m);...;Rel(n+1)] *)
-
-let rel_vect n m = Array.init m (fun i -> Rel(n+m-i))
-
-let rel_list n m =
- let rec reln l p =
- if p>m then l else reln (Rel(n+p)::l) (p+1)
- in
- reln [] 1
-
-let rec count_dlam = function
- | DLAM (_,c) -> 1 + (count_dlam c)
- | _ -> 0
-
-(* Hash-consing *)
-let comp_term t1 t2 =
- match (t1,t2) with
- | (DOP0 o1, DOP0 o2) -> o1==o2
- | (DOP1(o1,t1), DOP1(o2,t2)) -> o1==o2 & t1==t2
- | (DOP2(o1,t1,u1), DOP2(o2,t2,u2)) -> o1==o2 & t1==t2 & u1==u2
- | (DOPN(o1,v1), DOPN(o2,v2)) ->
- (o1==o2) & (Array.length v1 = Array.length v2)
- & array_for_all2 (==) v1 v2
- | (DOPL(o1,l1), DOPL(o2,l2)) ->
- (o1==o2) & (List.length l1 = List.length l2)
- & List.for_all2 (==) l1 l2
- | (DLAM(x1,t1), DLAM(x2,t2)) -> x1==x2 & t1==t2
- | (DLAMV(x1,v1), DLAMV(x2,v2)) ->
- (x1==x2) & (Array.length v1 = Array.length v2)
- & array_for_all2 (==) v1 v2
- | (Rel i, Rel j) -> i=j
- | (VAR x, VAR y) -> x==y
- | _ -> false
-
-let hash_term (sh_rec,(sh_op,sh_na,sh_id)) t =
- match t with
- | DOP0 o -> DOP0 (sh_op o)
- | DOP1(o,t) -> DOP1(sh_op o, sh_rec t)
- | DOP2(o,t1,t2) -> DOP2(sh_op o, sh_rec t1, sh_rec t2)
- | DOPN(o,v) -> DOPN(sh_op o, Array.map sh_rec v)
- | DOPL(o,l) -> DOPL(sh_op o, List.map sh_rec l)
- | DLAM(n,t) -> DLAM(sh_na n, sh_rec t)
- | DLAMV(n,v) -> DLAMV(sh_na n, Array.map sh_rec v)
- | Rel i -> t
- | VAR x -> VAR (sh_id x)
+*)
diff --git a/kernel/generic.mli b/kernel/generic.mli
index 5f632a94ad..4f2afa9a0f 100644
--- a/kernel/generic.mli
+++ b/kernel/generic.mli
@@ -23,84 +23,91 @@ type 'oper term =
| VAR of identifier
| Rel of int
-val isRel : 'a term -> bool
-val isVAR : 'a term -> bool
val free_rels : 'a term -> Intset.t
-exception FreeVar
-exception Occur
-
-val closedn : int -> 'a term -> unit
+(* [closed0 M] is true iff [M] is a (deBruijn) closed term *)
val closed0 : 'a term -> bool
-val noccurn : int -> 'a term -> bool
-val noccur_bet : int -> int -> 'a term -> bool
-(*s Lifts. [ELSHFT(l,n)] == lift of [n], then apply [lift l].
- [ELLFT(n,l)] == apply [l] to de Bruijn > [n] i.e under n binders. *)
+(* [noccurn n M] returns true iff [Rel n] does NOT occur in term [M] *)
+val noccurn : int -> 'a term -> bool
-type lift_spec =
- | ELID
- | ELSHFT of lift_spec * int
- | ELLFT of int * lift_spec
+(* [noccur_between n m M] returns true iff [Rel p] does NOT occur in term [M]
+ for n <= p < n+m *)
+val noccur_between : int -> int -> 'a term -> bool
-val el_shft : int -> lift_spec -> lift_spec
-val el_lift : lift_spec -> lift_spec
-val el_liftn : int -> lift_spec -> lift_spec
-val reloc_rel: int -> lift_spec -> int
-val exliftn : lift_spec -> 'a term -> 'a term
+(* [liftn n k c] lifts by [n] indexes above [k] in [c] *)
val liftn : int -> int -> 'a term -> 'a term
+
+(* [lift n c] lifts by [n] the positive indexes in [c] *)
val lift : int -> 'a term -> 'a term
+
+(* [pop c] lifts by -1 the positive indexes in [c] *)
val pop : 'a term -> 'a term
(* [lift_context n ctxt] lifts terms in [ctxt] by [n] preserving
(i.e. not lifting) the internal references between terms of [ctxt];
more recent terms come first in [ctxt] *)
-
val lift_context : int -> (name * 'a term) list -> (name * 'a term) list
-(*s Explicit substitutions of type ['a]. [ESID] = identity.
+val substnl : 'a term list -> int -> 'a term -> 'a term
+val substl : 'a term list -> 'a term -> 'a term
+val subst1 : 'a term -> 'a term -> 'a term
+
+(* [global_vars c] returns the list of [id]'s occurring as [VAR id] in [c] *)
+val global_vars : 'a term -> identifier list
+
+val global_vars_set : 'a term -> Idset.t
+val subst_var : identifier -> 'a term -> 'a term
+val replace_vars : (identifier * 'a term) list -> 'a term -> 'a term
+
+(* [rel_list n m] and [rel_vect n m] compute [[Rel (n+m);...;Rel(n+1)]] *)
+val rel_vect : int -> int -> 'a term array
+val rel_list : int -> int -> 'a term list
+
+(*i************************************************************************i*)
+(*i Pour Closure *)
+(* Explicit substitutions of type ['a]. [ESID] = identity.
[CONS(t,S)] = $S.t$ i.e. parallel substitution. [SHIFT(n,S)] =
$(\uparrow n~o~S)$ i.e. terms in S are relocated with n vars.
[LIFT(n,S)] = $(\%n~S)$ stands for $((\uparrow n~o~S).n...1)$. *)
-
type 'a subs =
| ESID
| CONS of 'a * 'a subs
| SHIFT of int * 'a subs
| LIFT of int * 'a subs
-
val subs_cons : 'a * 'a subs -> 'a subs
val subs_lift : 'a subs -> 'a subs
val subs_shft : int * 'a subs -> 'a subs
-val exp_rel : int -> int -> 'a subs -> (int * 'a, int) union
val expand_rel : int -> 'a subs -> (int * 'a, int) union
+(*
+val exp_rel : int -> int -> 'a subs -> (int * 'a, int) union
+*)
+(*i*)
-type info = Closed | Open | Unknown
-type 'a substituend = { mutable sinfo : info; sit : 'a }
+(*i Pour Closure *)
+(*s Lifts. [ELSHFT(l,n)] == lift of [n], then apply [lift l].
+ [ELLFT(n,l)] == apply [l] to de Bruijn > [n] i.e under n binders. *)
+type lift_spec =
+ | ELID
+ | ELSHFT of lift_spec * int
+ | ELLFT of int * lift_spec
+val el_shft : int -> lift_spec -> lift_spec
+val el_lift : lift_spec -> lift_spec
+val reloc_rel: int -> lift_spec -> int
+(*
+val exliftn : lift_spec -> 'a term -> 'a term
+val el_liftn : int -> lift_spec -> lift_spec
+*)
+(*i*)
-val lift_substituend : int -> 'a term substituend -> 'a term
-val make_substituend : 'a term -> 'a term substituend
-val substn_many : 'a term substituend array -> int -> 'a term -> 'a term
-val substl : 'a term list -> 'a term -> 'a term
-val subst1 : 'a term -> 'a term -> 'a term
-val occur_opern : 'a -> 'a term -> bool
-val occur_oper0 : 'a -> 'a term -> bool
-val occur_var : identifier -> 'a term -> bool
-val occur_oper : 'a -> 'a term -> bool
-val process_opers_of_term :
- ('a -> bool) -> ('a -> 'b) -> 'b list -> 'a term -> 'b list
-val dependent : 'a term -> 'a term -> bool
+(*i À virer...
+exception FreeVar
+val closedn : int -> 'a term -> unit
+
+exception Occur
+type info = Closed | Open | Unknown
val global_varsl : identifier list -> 'a term -> identifier list
-val global_vars : 'a term -> identifier list
-val global_vars_set : 'a term -> Idset.t
-val subst_var : identifier -> 'a term -> 'a term
val subst_varn : identifier -> int -> 'a term -> 'a term
-val replace_vars :
- (identifier * 'a term substituend) list -> 'a term -> 'a term
-
-val rename_diff_occ :
- identifier -> identifier list ->'a term -> identifier list * 'a term
-
val sAPP : 'a term -> 'a term -> 'a term
val sAPPV : 'a term -> 'a term -> 'a term array
val sAPPVi : int -> 'a term -> 'a term -> 'a term
@@ -109,24 +116,17 @@ val sAPPList : 'a term -> 'a term list -> 'a term
val sAPPVList : 'a term -> 'a term list-> 'a term array
val sAPPViList : int -> 'a term -> 'a term list -> 'a term
val under_dlams : ('a term -> 'a term) -> 'a term -> 'a term
-val eq_term : 'a term -> 'a term -> bool
-
val put_DLAMSV : name list -> 'a term array -> 'a term
val decomp_DLAMV : int -> 'a term -> 'a term array
val decomp_DLAMV_name : int -> 'a term -> name list * 'a term array
val decomp_all_DLAMV_name : 'a term -> name list * 'a term array
val put_DLAMSV_subst : identifier list -> 'a term array -> 'a term
-
-(* [rel_list n m] and [rel_vect n m] compute [[Rel (n+m);...;Rel(n+1)]] *)
-val rel_vect : int -> int -> 'a term array
-val rel_list : int -> int -> 'a term list
-
val count_dlam : 'a term -> int
-(*s For hash-consing. *)
-
+(*s For hash-consing. (déplacé dans term) *)
val hash_term :
('a term -> 'a term)
* (('a -> 'a) * (name -> name) * (identifier -> identifier))
-> 'a term -> 'a term
val comp_term : 'a term -> 'a term -> bool
+i*)
diff --git a/kernel/instantiate.ml b/kernel/instantiate.ml
index 7a929b9fa3..5ec0e01b0b 100644
--- a/kernel/instantiate.ml
+++ b/kernel/instantiate.ml
@@ -22,7 +22,7 @@ let instantiate_constr ids c args =
if is_id_inst ids args then
c
else
- replace_vars (List.combine ids (List.map make_substituend args)) c
+ replace_vars (List.combine ids args) c
let instantiate_type ids tty args =
typed_app (fun c -> instantiate_constr ids c args) tty
diff --git a/kernel/reduction.ml b/kernel/reduction.ml
index 4dfeca8823..85a335ee8e 100644
--- a/kernel/reduction.ml
+++ b/kernel/reduction.ml
@@ -486,12 +486,19 @@ let reducible_mind_case = function
| DOPN(MutConstruct _,_) | DOPN(CoFix _,_) -> true
| _ -> false
+(*
let contract_cofix = function
| DOPN(CoFix(bodynum),bodyvect) ->
let nbodies = (Array.length bodyvect) -1 in
let make_Fi j = DOPN(CoFix(j),bodyvect) in
sAPPViList bodynum (array_last bodyvect) (list_tabulate make_Fi nbodies)
| _ -> assert false
+*)
+
+let contract_cofix (bodynum,(types,names,bodies as typedbodies)) =
+ let nbodies = Array.length bodies in
+ let make_Fi j = mkCoFix (nbodies-j-1,typedbodies) in
+ substl (list_tabulate make_Fi nbodies) bodies.(bodynum)
let reduce_mind_case mia =
match mia.mconstr with
@@ -500,19 +507,25 @@ let reduce_mind_case mia =
let real_cargs = list_lastn ncargs mia.mcargs in
applist (mia.mlf.(i-1),real_cargs)
| DOPN(CoFix _,_) as cofix ->
- let cofix_def = contract_cofix cofix in
+ let cofix_def = contract_cofix (destCoFix cofix) in
mkMutCaseA mia.mci mia.mP (applist(cofix_def,mia.mcargs)) mia.mlf
| _ -> assert false
(* contracts fix==FIX[nl;i](A1...Ak;[F1...Fk]{B1....Bk}) to produce
Bi[Fj --> FIX[nl;j](A1...Ak;[F1...Fk]{B1...Bk})] *)
+(*
let contract_fix = function
| DOPN(Fix(recindices,bodynum),bodyvect) ->
let nbodies = Array.length recindices in
let make_Fi j = DOPN(Fix(recindices,j),bodyvect) in
sAPPViList bodynum (array_last bodyvect) (list_tabulate make_Fi nbodies)
| _ -> assert false
+*)
+let contract_fix ((recindices,bodynum),(types,names,bodies as typedbodies)) =
+ let nbodies = Array.length recindices in
+ let make_Fi j = mkFix ((recindices,nbodies-j-1),typedbodies) in
+ substl (list_tabulate make_Fi nbodies) bodies.(bodynum)
let fix_recarg fix stack =
match fix with
@@ -537,7 +550,7 @@ let reduce_fix whfun fix stack =
let stack' = list_assign stack recargnum (applist recarg') in
(match recarg'hd with
| DOPN(MutConstruct _,_) ->
- (true,(contract_fix fix,stack'))
+ (true,(contract_fix (destFix fix),stack'))
| _ -> (false,(fix,stack'))))
| _ -> assert false
@@ -981,7 +994,7 @@ let instance s c =
let hnf_prod_app env sigma t n =
match whd_betadeltaiota env sigma t with
- | DOP2(Prod,_,b) -> sAPP b n
+ | DOP2(Prod,_,DLAM(_,b)) -> subst1 n b
| _ -> anomaly "hnf_prod_app: Need a product"
let hnf_prod_appvect env sigma t nl =
@@ -992,7 +1005,7 @@ let hnf_prod_applist env sigma t nl =
let hnf_lam_app env sigma t n =
match whd_betadeltaiota env sigma t with
- | DOP2(Lambda,_,b) -> sAPP b n
+ | DOP2(Lambda,_,DLAM(_,b)) -> subst1 n b
| _ -> anomaly "hnf_lam_app: Need an abstraction"
let hnf_lam_appvect env sigma t nl =
diff --git a/kernel/term.ml b/kernel/term.ml
index 3a58c92665..6b8e094b9a 100644
--- a/kernel/term.ml
+++ b/kernel/term.ml
@@ -153,7 +153,7 @@ let mkCast t1 t2 =
(* Constructs the product (x:t1)t2 *)
let mkProd x t1 t2 = (DOP2 (Prod,t1,(DLAM (x,t2))))
-(* non-dependant product t1 -> t2 *)
+(* non-dependent product t1 -> t2 *)
let mkArrow t1 t2 = mkProd Anonymous t1 t2
(* named product *)
@@ -215,15 +215,14 @@ let mkMutCaseA ci p c ac =
(* Here, we assume the body already constructed *)
let mkFixDlam recindxs i jtypsarray body =
- let typsarray = Array.map incast_type jtypsarray in
+ let typsarray = (*Array.map incast_type*) jtypsarray in
DOPN (Fix (recindxs,i),Array.append typsarray body)
-let mkFix recindxs i jtypsarray funnames bodies =
- let rec wholebody l =
- match l with
- | [h] -> (DLAMV (h,bodies))
- | (x::l) -> (DLAM (x, wholebody l))
- | [] -> anomaly "in Term.mkFix : empty list of funnames"
+let mkFix ((recindxs, i), (jtypsarray, funnames, bodies)) =
+ let rec wholebody = function
+ | [h] -> (DLAMV (h,bodies))
+ | (x::l) -> (DLAM (x, wholebody l))
+ | [] -> anomaly "in Term.mkFix : empty list of funnames"
in
mkFixDlam recindxs i jtypsarray [|(wholebody funnames)|]
@@ -244,10 +243,10 @@ let mkFix recindxs i jtypsarray funnames bodies =
*)
(* Here, we assume the body already constructed *)
let mkCoFixDlam i jtypsarray body =
- let typsarray = Array.map incast_type jtypsarray in
+ let typsarray = (*Array.map incast_type*) jtypsarray in
DOPN ((CoFix i),(Array.append typsarray body))
-let mkCoFix i jtypsarray funnames bodies =
+let mkCoFix (i, (jtypsarray, funnames, bodies)) =
let rec wholebody l =
match l with
| [h] -> (DLAMV (h,bodies))
@@ -387,6 +386,12 @@ let rec strip_all_casts t =
| VAR _ as t -> t
| Rel _ as t -> t
+(* Tests if a de Bruijn index *)
+let isRel = function Rel _ -> true | _ -> false
+
+(* Tests if a variable *)
+let isVar = function VAR _ -> true | _ -> false
+
(* Destructs the product (x:t1)t2 *)
let destProd = function
| DOP2 (Prod, t1, (DLAM (x,t2))) -> (x,t1,t2)
@@ -525,13 +530,13 @@ let destGralFix a =
let destFix = function
| DOPN (Fix (recindxs,i),a) ->
let (types,funnames,bodies) = destGralFix a in
- (recindxs,i,Array.map out_fixcast types,funnames,bodies)
+ ((recindxs,i),((*Array.map out_fixcast *) types,funnames,bodies))
| _ -> invalid_arg "destFix"
let destCoFix = function
| DOPN ((CoFix i),a) ->
let (types,funnames,bodies) = destGralFix a in
- (i,Array.map out_fixcast types,funnames,bodies)
+ (i,((*Array.map out_fixcast *) types,funnames,bodies))
| _ -> invalid_arg "destCoFix"
(* Provisoire, le temps de maitriser les cast *)
@@ -551,7 +556,7 @@ let destUntypedCoFix = function
type binder_kind = BProd | BLambda
-type fix_kind = RFix of int array * int | RCofix of int
+type fix_kind = RFix of (int array * int) | RCofix of int
type 'ctxt reference =
| RConst of section_path * 'ctxt
@@ -565,6 +570,8 @@ type existential = int * constr array
type constant = section_path * constr array
type constructor = constructor_path * constr array
type inductive = inductive_path * constr array
+type fixpoint = (int array * int) * (constr array * name list * constr array)
+type cofixpoint = int * (constr array * name list * constr array)
(******************)
(* Term analysis *)
@@ -586,9 +593,8 @@ type kindOfTerm =
| IsMutInd of inductive
| IsMutConstruct of constructor
| IsMutCase of case_info * constr * constr * constr array
- | IsFix of int array * int * constr array * name list * constr array
- | IsCoFix of int * constr array * name list * constr array
-
+ | IsFix of fixpoint
+ | IsCoFix of cofixpoint
(* Discriminates which kind of term is it.
@@ -616,11 +622,11 @@ let kind_of_term c =
| DOPN (MutCase ci,v) ->
IsMutCase (ci,v.(0),v.(1),Array.sub v 2 (Array.length v - 2))
| DOPN ((Fix (recindxs,i),a)) ->
- let (types,funnames,bodies) = destGralFix a in
- IsFix (recindxs,i,types,funnames,bodies)
+ let typedbodies = destGralFix a in
+ IsFix ((recindxs,i),typedbodies)
| DOPN ((CoFix i),a) ->
- let (types,funnames,bodies) = destGralFix a in
- IsCoFix (i,types,funnames,bodies)
+ let typedbodies = destGralFix a in
+ IsCoFix (i,typedbodies)
| _ -> errorlabstrm "Term.kind_of_term" [< 'sTR "ill-formed constr" >]
(***************************)
@@ -711,7 +717,7 @@ let rec to_prod n lam =
let prod_app t n =
match strip_outer_cast t with
- | DOP2(Prod,_,b) -> sAPP b n
+ | DOP2(Prod,_,DLAM(na,b)) -> subst1 n b
| _ ->
errorlabstrm "prod_app"
[< 'sTR"Needed a product, but didn't find one" ; 'fNL >]
@@ -969,7 +975,7 @@ let rec decomp_app c =
| c -> (c,[])
(* strips head casts and flattens head applications *)
-let strip_head_cast = function
+let rec strip_head_cast = function
| DOPN(AppL,cl) ->
let rec collapse_rec = function
| (DOPN(AppL,cl),l2) -> collapse_rec(array_hd cl, array_app_tl cl l2)
@@ -978,11 +984,41 @@ let strip_head_cast = function
| (f,l) -> let v = Array.of_list (f::l) in DOPN(AppL,v)
in
collapse_rec(array_hd cl, array_app_tl cl [])
+ | DOP2(Cast,c,t) -> strip_head_cast c
| c -> c
+(* Various occurs checks *)
+
+let occur_opern s =
+ let rec occur_rec = function
+ | DOPN(oper,cl) -> s=oper or (array_exists occur_rec cl)
+ | DOPL(oper,cl) -> s=oper or (List.exists occur_rec cl)
+ | VAR _ -> false
+ | DOP1(_,c) -> occur_rec c
+ | DOP2(_,c1,c2) -> (occur_rec c1) or (occur_rec c2)
+ | DLAM(_,c) -> occur_rec c
+ | DLAMV(_,v) -> array_exists occur_rec v
+ | _ -> false
+ in
+ occur_rec
+
(* (occur_const (s:section_path) c) -> true if constant s occurs in c,
* false otherwise *)
let occur_const s = occur_opern (Const s)
+let occur_evar ev = occur_opern (Evar ev)
+
+let occur_var s =
+ let rec occur_rec = function
+ | DOPN(_,cl) -> array_exists occur_rec cl
+ | DOPL(_,cl) -> List.exists occur_rec cl
+ | VAR id -> s=id
+ | DOP1(_,c) -> occur_rec c
+ | DOP2(_,c1,c2) -> (occur_rec c1) or (occur_rec c2)
+ | DLAM(_,c) -> occur_rec c
+ | DLAMV(_,v) -> array_exists occur_rec v
+ | _ -> false
+ in
+ occur_rec
(* let sigma be a finite function mapping sections paths to
constants represented as (identifier list * constr) option.
@@ -1010,9 +1046,7 @@ let replace_consts const_alist =
if List.length hyps <> Array.length cl then
anomaly "found a constant with a bad number of args"
else
- replace_vars
- (List.combine hyps
- (array_map_to_list make_substituend cl')) body
+ replace_vars (List.combine hyps (Array.to_list cl')) body
| None -> anomaly ("a constant which was never"^
" supposed to appear has just appeared")
with Not_found -> DOPN(Const sp,cl'))
@@ -1048,10 +1082,9 @@ let whd_castapp x = applist(whd_castapp_stack x [])
(* alpha conversion : ignore print names and casts *)
let rec eq_constr_rec m n =
+ (m == n) or
(m = n) or
match (strip_head_cast m,strip_head_cast n) with
- | (DOP2(Cast,c1,_),c2) -> eq_constr_rec c1 c2
- | (c1,DOP2(Cast,c2,_)) -> eq_constr_rec c1 c2
| (Rel p1,Rel p2) -> p1=p2
| (DOPN(oper1,cl1),DOPN(oper2,cl2)) ->
oper1=oper2 & array_for_all2 eq_constr_rec cl1 cl2
@@ -1067,10 +1100,9 @@ let rec eq_constr_rec m n =
let eq_constr = eq_constr_rec
let rec eq_constr_with_meta_rec m n=
+ (m == n) or
(m=n) or
(match (strip_head_cast m,strip_head_cast n) with
- | (DOP2(Cast,c1,_),c2) -> eq_constr_rec c1 c2
- | (c1,DOP2(Cast,c2,_)) -> eq_constr_rec c1 c2
| (Rel p1,Rel p2) -> p1=p2
| (DOPN(oper1,cl1),DOPN(oper2,cl2)) ->
oper1=oper2 & array_for_all2 eq_constr_rec cl1 cl2
@@ -1083,6 +1115,24 @@ let rec eq_constr_with_meta_rec m n=
array_for_all2 eq_constr_rec cl1 cl2
| _ -> false)
+(* (dependent M N) is true iff M is eq_term with a subterm of N
+ M is appropriately lifted through abstractions of N *)
+
+let dependent =
+ let rec deprec m t =
+ (eq_constr m t)
+ or (match t with
+ | VAR _ -> false
+ | DOP1(_,c) -> deprec m c
+ | DOP2(_,c,t) -> deprec m c or deprec m t
+ | DOPN(_,cl) -> array_exists (deprec m) cl
+ | DOPL(_,cl) -> List.exists (deprec m) cl
+ | DLAM(_,c) -> deprec (lift 1 m) c
+ | DLAMV(_,v) -> array_exists (deprec (lift 1 m)) v
+ | _ -> false)
+ in
+ deprec
+
(* On reduit une serie d'eta-redex de tete ou rien du tout *)
(* [x1:c1;...;xn:cn]@(f;a1...an;x1;...;xn) --> @(f;a1...an) *)
(* Remplace 2 versions précédentes buggées *)
@@ -1330,6 +1380,37 @@ let occur_existential =
(* hash-consing functions *)
(***************************)
+let comp_term t1 t2 =
+ match (t1,t2) with
+ | (DOP0 o1, DOP0 o2) -> o1==o2
+ | (DOP1(o1,t1), DOP1(o2,t2)) -> o1==o2 & t1==t2
+ | (DOP2(o1,t1,u1), DOP2(o2,t2,u2)) -> o1==o2 & t1==t2 & u1==u2
+ | (DOPN(o1,v1), DOPN(o2,v2)) ->
+ (o1==o2) & (Array.length v1 = Array.length v2)
+ & array_for_all2 (==) v1 v2
+ | (DOPL(o1,l1), DOPL(o2,l2)) ->
+ (o1==o2) & (List.length l1 = List.length l2)
+ & List.for_all2 (==) l1 l2
+ | (DLAM(x1,t1), DLAM(x2,t2)) -> x1==x2 & t1==t2
+ | (DLAMV(x1,v1), DLAMV(x2,v2)) ->
+ (x1==x2) & (Array.length v1 = Array.length v2)
+ & array_for_all2 (==) v1 v2
+ | (Rel i, Rel j) -> i=j
+ | (VAR x, VAR y) -> x==y
+ | _ -> false
+
+let hash_term (sh_rec,(sh_op,sh_na,sh_id)) t =
+ match t with
+ | DOP0 o -> DOP0 (sh_op o)
+ | DOP1(o,t) -> DOP1(sh_op o, sh_rec t)
+ | DOP2(o,t1,t2) -> DOP2(sh_op o, sh_rec t1, sh_rec t2)
+ | DOPN(o,v) -> DOPN(sh_op o, Array.map sh_rec v)
+ | DOPL(o,l) -> DOPL(sh_op o, List.map sh_rec l)
+ | DLAM(n,t) -> DLAM(sh_na n, sh_rec t)
+ | DLAMV(n,v) -> DLAMV(sh_na n, Array.map sh_rec v)
+ | Rel i -> t
+ | VAR x -> VAR (sh_id x)
+
module Hsorts =
Hashcons.Make(
struct
diff --git a/kernel/term.mli b/kernel/term.mli
index 7320b8be89..cc5a8954d0 100644
--- a/kernel/term.mli
+++ b/kernel/term.mli
@@ -76,7 +76,7 @@ val outcast_type : constr -> typed_type
(**********************************************************************)
type binder_kind = BProd | BLambda
-type fix_kind = RFix of int array * int | RCofix of int
+type fix_kind = RFix of (int array * int) | RCofix of int
type 'ctxt reference =
| RConst of section_path * 'ctxt
@@ -96,6 +96,9 @@ type existential = int * constr array
type constant = section_path * constr array
type constructor = constructor_path * constr array
type inductive = inductive_path * constr array
+type fixpoint = (int array * int) * (constr array * name list * constr array)
+type cofixpoint = int * (constr array * name list * constr array)
+
type kindOfTerm =
| IsRel of int
@@ -113,8 +116,8 @@ type kindOfTerm =
| IsMutInd of inductive
| IsMutConstruct of constructor
| IsMutCase of case_info * constr * constr * constr array
- | IsFix of int array * int * constr array * name list * constr array
- | IsCoFix of int * constr array * name list * constr array
+ | IsFix of fixpoint
+ | IsCoFix of cofixpoint
(* Discriminates which kind of term is it.
Note that there is no cases for [DLAM] and [DLAMV]. These terms do not
@@ -212,7 +215,7 @@ val mkMutCaseA : case_info -> constr -> constr -> constr array -> constr
[typarray = [|t1,...tn|]]
[funnames = [f1,.....fn]]
[bodies = [b1,.....bn]]
- then [ mkFix recindxs i typarray funnames bodies]
+ then [ mkFix ((recindxs,i),typarray, funnames, bodies) ]
constructs the $i$th function of the block
[Fixpoint f1 [ctx1] = b1
@@ -222,17 +225,15 @@ val mkMutCaseA : case_info -> constr -> constr -> constr array -> constr
\noindent where the lenght of the $j$th context is $ij$.
*)
-val mkFix : int array -> int -> typed_type array -> name list
- -> constr array -> constr
+val mkFix : fixpoint -> constr
(* Similarly, but we assume the body already constructed *)
-val mkFixDlam : int array -> int -> typed_type array
- -> constr array -> constr
+val mkFixDlam : int array -> int -> constr array -> constr array -> constr
(* If [typarray = [|t1,...tn|]]
[funnames = [f1,.....fn]]
[bodies = [b1,.....bn]] \par\noindent
- then [mkCoFix i typsarray funnames bodies]
+ then [mkCoFix (i, (typsarray, funnames, bodies))]
constructs the ith function of the block
[CoFixpoint f1 = b1
@@ -240,11 +241,10 @@ val mkFixDlam : int array -> int -> typed_type array
...
with fn = bn.]
*)
-val mkCoFix : int -> typed_type array -> name list
- -> constr array -> constr
+val mkCoFix : cofixpoint -> constr
(* Similarly, but we assume the body already constructed *)
-val mkCoFixDlam : int -> typed_type array -> constr array -> constr
+val mkCoFixDlam : int -> constr array -> constr array -> constr
(*s Term destructors.
@@ -292,6 +292,12 @@ val strip_outer_cast : constr -> constr
(* Special function, which keep the key casts under Fix and MutCase. *)
val strip_all_casts : constr -> constr
+(* Tests if a de Bruijn index *)
+val isRel : constr -> bool
+
+(* Tests if a variable *)
+val isVar : constr -> bool
+
(* Destructs the product $(x:t_1)t_2$ *)
val destProd : constr -> name * constr * constr
val hd_of_prod : constr -> constr
@@ -316,7 +322,7 @@ val args_of_const : constr -> constr array
val destEvar : constr -> int * constr array
val num_of_evar : constr -> int
-(* Destrucy an abstract term *)
+(* Destructs an abstract term *)
val destAbst : constr -> section_path * constr array
val path_of_abst : constr -> section_path
val args_of_abst : constr -> constr array
@@ -343,11 +349,9 @@ val destCase : constr -> case_info * constr * constr * constr array
*)
val destGralFix :
constr array -> constr array * Names.name list * constr array
-val destFix : constr ->
- int array * int * typed_type array * Names.name list * constr array
+val destFix : constr -> fixpoint
-val destCoFix :
- constr -> int * typed_type array * Names.name list * constr array
+val destCoFix : constr -> cofixpoint
(* Provisoire, le temps de maitriser les cast *)
val destUntypedFix :
@@ -534,6 +538,18 @@ val rel_vect : int -> int -> constr array
in c, [false] otherwise *)
val occur_const : section_path -> constr -> bool
+(* [(occur_evar ev c)] returns [true] if existential variable [ev] occurs
+ in c, [false] otherwise *)
+val occur_evar : existential_key -> constr -> bool
+
+(* [(occur_var id c)] returns [true] if variable [id] occurs free
+ in c, [false] otherwise *)
+val occur_var : identifier -> 'a term -> bool
+
+(* [dependent M N] is true iff M is eq_constr with a subterm of N
+ M is appropriately lifted through abstractions of N *)
+val dependent : constr -> constr -> bool
+
(* strips head casts and flattens head applications *)
val strip_head_cast : constr -> constr
val whd_castapp_stack : constr -> constr list -> constr * constr list
diff --git a/kernel/typeops.ml b/kernel/typeops.ml
index 1a6c1d885f..e227111d0d 100644
--- a/kernel/typeops.ml
+++ b/kernel/typeops.ml
@@ -351,6 +351,7 @@ let apply_rel_list env sigma nocheck argjl funj =
which may contain the CoFix variables. These occurrences of CoFix variables
are not considered *)
+exception Occur
let noccur_with_meta n m term =
let rec occur_rec n = function
| Rel p -> if n<=p & p<n+m then raise Occur
@@ -629,30 +630,19 @@ nvect is [|n1;..;nk|] which gives for each recursive definition
the inductive-decreasing index
the function checks the convertibility of ti with Ai *)
-let check_fix env sigma = function
- | DOPN(Fix(nvect,j),vargs) ->
- let nbfix = let nv = Array.length vargs in
- if nv < 2 then error "Ill-formed recursive definition" else nv-1 in
- let varit = Array.sub vargs 0 nbfix in
- let ldef = array_last vargs in
- let ln = Array.length nvect
- and la = Array.length varit in
- if ln <> la then
- error "Ill-formed fix term"
- else
- let (lna,vdefs) = decomp_DLAMV_name ln ldef in
- let vlna = Array.of_list lna in
- let check_type i =
- try
- let _ =
- check_subterm_rec_meta env sigma nvect nvect.(i) vdefs.(i) in
- ()
- with UserError (s,str) ->
- error_ill_formed_rec_body CCI env str lna i vdefs
- in
- for i = 0 to ln-1 do check_type i done
-
- | _ -> assert false
+let check_fix env sigma ((nvect,bodynum),(types,names,bodies)) =
+ let nbfix = Array.length bodies in
+ if nbfix = 0
+ or Array.length nvect <> nbfix
+ or Array.length types <> nbfix
+ or List.length names <> nbfix
+ then error "Ill-formed fix term";
+ for i = 0 to nbfix - 1 do
+ try
+ let _ = check_subterm_rec_meta env sigma nvect nvect.(i) bodies.(i) in ()
+ with UserError (s,str) ->
+ error_ill_formed_rec_body CCI env str (List.rev names) i bodies
+ done
(* Co-fixpoints. *)
@@ -733,28 +723,18 @@ let check_guard_rec_meta env sigma nbfix def deftype =
else
error "Recursive call in the type of an abstraction"
- | (DOPN(CoFix(j),vargs),l) ->
- if (List.for_all (noccur_with_meta n nbfix) l)
- then
- let nbfix = let nv = Array.length vargs in
- if nv < 2 then
- error "Ill-formed recursive definition"
- else
- nv-1
- in
- let varit = Array.sub vargs 0 nbfix in
- let ldef = array_last vargs in
- let la = Array.length varit in
- let (lna,vdefs) = decomp_DLAMV_name la ldef in
- let vlna = Array.of_list lna
- in
- if (array_for_all (noccur_with_meta n nbfix) varit) then
- (array_for_all (check_rec_call alreadygrd (n+1) vlra) vdefs)
- &&
- (List.for_all (check_rec_call alreadygrd (n+1) vlra) l)
- else
- error "Recursive call in the type of a declaration"
- else error "Unguarded recursive call"
+ | (DOPN(CoFix(j),vargs) as cofix,l) ->
+ if (List.for_all (noccur_with_meta n nbfix) l)
+ then
+ let (j,(varit,lna,vdefs)) = destFix cofix in
+ let nbfix = Array.length vdefs in
+ if (array_for_all (noccur_with_meta n nbfix) varit) then
+ (array_for_all (check_rec_call alreadygrd (n+1) vlra) vdefs)
+ &&
+ (List.for_all (check_rec_call alreadygrd (n+1) vlra) l)
+ else
+ error "Recursive call in the type of a declaration"
+ else error "Unguarded recursive call"
| (DOPN(MutCase _,_) as mc,l) ->
let (_,p,c,vrest) = destCase mc in
@@ -777,6 +757,17 @@ let check_guard_rec_meta env sigma nbfix def deftype =
(* The function which checks that the whole block of definitions
satisfies the guarded condition *)
+let check_cofix env sigma (bodynum,(types,names,bodies)) =
+ let nbfix = Array.length bodies in
+ for i = 0 to nbfix-1 do
+ try
+ let _ =
+ check_guard_rec_meta env sigma nbfix bodies.(i) types.(i) in
+ ()
+ with UserError (s,str) ->
+ error_ill_formed_rec_body CCI env str (List.rev names) i bodies
+ done
+(*
let check_cofix env sigma f =
match f with
| DOPN(CoFix(j),vargs) ->
@@ -801,7 +792,7 @@ let check_cofix env sigma f =
in
for i = 0 to nbfix-1 do check_type i done
| _ -> assert false
-
+*)
(* Checks the type of a (co)fixpoint.
Fix and CoFix are typed the same way; only the guard condition differs. *)
@@ -831,10 +822,10 @@ let control_only_guard env sigma =
| VAR _ -> ()
| DOP0(_) -> ()
| DOPN(CoFix(_),cl) as cofix ->
- check_cofix env sigma cofix;
+ check_cofix env sigma (destCoFix cofix);
Array.iter control_rec cl
| DOPN(Fix(_),cl) as fix ->
- check_fix env sigma fix;
+ check_fix env sigma (destFix fix);
Array.iter control_rec cl
| DOPN(_,cl) -> Array.iter control_rec cl
| DOPL(_,cl) -> List.iter control_rec cl
diff --git a/kernel/typeops.mli b/kernel/typeops.mli
index 7ab2404f8c..3d2074c977 100644
--- a/kernel/typeops.mli
+++ b/kernel/typeops.mli
@@ -67,8 +67,8 @@ val apply_rel_list :
env -> 'a evar_map -> bool -> unsafe_judgment list -> unsafe_judgment
-> unsafe_judgment * constraints
-val check_fix : env -> 'a evar_map -> constr -> unit
-val check_cofix : env -> 'a evar_map -> constr -> unit
+val check_fix : env -> 'a evar_map -> fixpoint -> unit
+val check_cofix : env -> 'a evar_map -> cofixpoint -> unit
val control_only_guard : env -> 'a evar_map -> constr -> unit
val type_fixpoint : env -> 'a evar_map -> name list -> typed_type array