aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfilliatr1999-11-29 14:29:18 +0000
committerfilliatr1999-11-29 14:29:18 +0000
commit958b0daa566c3735e054eb76d05255101ef29851 (patch)
tree083f3fc4e78e4cbd5ce18539cc3c574276a04118
parentc4aad6897210f9e55cb41a9dd40fc1fd01321f6b (diff)
portage modules Evarconv et Evarutil
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@161 85f007b7-540e-0410-9357-904b9bb8a0f7
-rw-r--r--.depend30
-rw-r--r--kernel/reduction.ml16
-rw-r--r--kernel/reduction.mli11
-rw-r--r--kernel/type_errors.ml2
-rw-r--r--kernel/type_errors.mli2
-rw-r--r--pretyping/evarconv.ml492
-rw-r--r--pretyping/evarconv.mli20
-rw-r--r--pretyping/evarutil.ml352
-rw-r--r--pretyping/evarutil.mli28
-rw-r--r--pretyping/pretype_errors.ml20
-rw-r--r--pretyping/pretype_errors.mli10
-rw-r--r--proofs/typing_ev.ml6
-rw-r--r--proofs/typing_ev.mli3
-rw-r--r--toplevel/himsg.ml16
14 files changed, 538 insertions, 470 deletions
diff --git a/.depend b/.depend
index 479d2d0e5f..0a04467eae 100644
--- a/.depend
+++ b/.depend
@@ -418,22 +418,24 @@ pretyping/coercion.cmx: pretyping/classops.cmx kernel/environ.cmx \
pretyping/recordops.cmx kernel/reduction.cmx kernel/term.cmx \
kernel/type_errors.cmx kernel/typeops.cmx lib/util.cmx \
pretyping/coercion.cmi
-pretyping/evarconv.cmo: pretyping/classops.cmi pretyping/evarutil.cmi \
- kernel/generic.cmi kernel/names.cmi pretyping/recordops.cmi \
- kernel/reduction.cmi kernel/term.cmi lib/util.cmi pretyping/evarconv.cmi
-pretyping/evarconv.cmx: pretyping/classops.cmx pretyping/evarutil.cmx \
- kernel/generic.cmx kernel/names.cmx pretyping/recordops.cmx \
- kernel/reduction.cmx kernel/term.cmx lib/util.cmx pretyping/evarconv.cmi
+pretyping/evarconv.cmo: pretyping/classops.cmi kernel/environ.cmi \
+ pretyping/evarutil.cmi kernel/generic.cmi kernel/instantiate.cmi \
+ kernel/names.cmi pretyping/recordops.cmi kernel/reduction.cmi \
+ kernel/term.cmi proofs/typing_ev.cmi lib/util.cmi pretyping/evarconv.cmi
+pretyping/evarconv.cmx: pretyping/classops.cmx kernel/environ.cmx \
+ pretyping/evarutil.cmx kernel/generic.cmx kernel/instantiate.cmx \
+ kernel/names.cmx pretyping/recordops.cmx kernel/reduction.cmx \
+ kernel/term.cmx proofs/typing_ev.cmx lib/util.cmx pretyping/evarconv.cmi
pretyping/evarutil.cmo: kernel/environ.cmi kernel/evd.cmi kernel/generic.cmi \
- library/indrec.cmi kernel/names.cmi lib/pp.cmi kernel/reduction.cmi \
- kernel/sign.cmi kernel/term.cmi kernel/univ.cmi lib/util.cmi \
- pretyping/evarutil.cmi
+ library/indrec.cmi kernel/instantiate.cmi kernel/names.cmi lib/pp.cmi \
+ pretyping/pretype_errors.cmi kernel/reduction.cmi kernel/sign.cmi \
+ kernel/term.cmi kernel/univ.cmi lib/util.cmi pretyping/evarutil.cmi
pretyping/evarutil.cmx: kernel/environ.cmx kernel/evd.cmx kernel/generic.cmx \
- library/indrec.cmx kernel/names.cmx lib/pp.cmx kernel/reduction.cmx \
- kernel/sign.cmx kernel/term.cmx kernel/univ.cmx lib/util.cmx \
- pretyping/evarutil.cmi
-pretyping/pretype_errors.cmo: pretyping/pretype_errors.cmi
-pretyping/pretype_errors.cmx: pretyping/pretype_errors.cmi
+ library/indrec.cmx kernel/instantiate.cmx kernel/names.cmx lib/pp.cmx \
+ pretyping/pretype_errors.cmx kernel/reduction.cmx kernel/sign.cmx \
+ kernel/term.cmx kernel/univ.cmx lib/util.cmx pretyping/evarutil.cmi
+pretyping/pretype_errors.cmo: kernel/names.cmi pretyping/pretype_errors.cmi
+pretyping/pretype_errors.cmx: kernel/names.cmx pretyping/pretype_errors.cmi
pretyping/pretyping.cmo: parsing/ast.cmi pretyping/classops.cmi \
pretyping/coercion.cmi kernel/environ.cmi pretyping/evarconv.cmi \
pretyping/evarutil.cmi kernel/evd.cmi kernel/generic.cmi \
diff --git a/kernel/reduction.ml b/kernel/reduction.ml
index 5f011c06d8..4bc551c6aa 100644
--- a/kernel/reduction.ml
+++ b/kernel/reduction.ml
@@ -933,7 +933,7 @@ let test_conversion f env sigma x y =
let is_conv env sigma = test_conversion conv env sigma
let is_conv_leq env sigma = test_conversion conv_leq env sigma
-
+let is_fconv = function | CONV -> is_conv | CONV_LEQ -> is_conv_leq
(********************************************************************)
(* Special-Purpose Reduction *)
@@ -1268,30 +1268,30 @@ let poly_args env sigma t =
exception Uninstantiated_evar of int
-let rec whd_ise env sigma = function
+let rec whd_ise sigma = function
| DOPN(Evar sp,_) as k ->
if Evd.in_dom sigma sp then
if Evd.is_defined sigma sp then
- whd_ise env sigma (existential_value sigma k)
+ whd_ise sigma (existential_value sigma k)
else raise (Uninstantiated_evar sp)
else k
- | DOP2(Cast,c,_) -> whd_ise env sigma c
+ | DOP2(Cast,c,_) -> whd_ise sigma c
| DOP0(Sort(Type _)) -> DOP0(Sort(Type dummy_univ))
| c -> c
(* 2- undefined existentials are left unchanged *)
-let rec whd_ise1 env sigma = function
+let rec whd_ise1 sigma = function
| (DOPN(Evar sp,_) as k) ->
if Evd.in_dom sigma sp & Evd.is_defined sigma sp then
- whd_ise1 env sigma (existential_value sigma k)
+ whd_ise1 sigma (existential_value sigma k)
else
k
- | DOP2(Cast,c,_) -> whd_ise1 env sigma c
+ | DOP2(Cast,c,_) -> whd_ise1 sigma c
| DOP0(Sort(Type _)) -> DOP0(Sort(Type dummy_univ))
| c -> c
-let nf_ise1 env sigma = strong whd_ise1 env sigma
+let nf_ise1 sigma = strong (fun _ -> whd_ise1) empty_env sigma
(* Same as whd_ise1, but replaces the remaining ISEVAR by Metavariables
* Similarly we have is_fmachine1_metas and is_resolve1_metas *)
diff --git a/kernel/reduction.mli b/kernel/reduction.mli
index 3e2fc9ffd1..9945b36cb7 100644
--- a/kernel/reduction.mli
+++ b/kernel/reduction.mli
@@ -172,6 +172,7 @@ val conv_forall2_i :
val is_conv : unsafe_env -> 'a evar_map -> constr -> constr -> bool
val is_conv_leq : unsafe_env -> 'a evar_map -> constr -> constr -> bool
+val is_fconv : conv_pb -> unsafe_env -> 'a evar_map -> constr -> constr -> bool
(*s Special-Purpose Reduction Functions *)
@@ -182,11 +183,13 @@ val instance : (int * constr) list -> 'a reduction_function
(* whd_ise raise Uninstantiated_evar if an evar remains uninstantiated *)
(* the '*_ise1*' leave uninstantiated evar as it *)
+
exception Uninstantiated_evar of int
-val whd_ise : 'a reduction_function
-val whd_ise1 : 'a reduction_function
-val nf_ise1 : 'a reduction_function
-val whd_ise1_metas : 'a reduction_function
+
+val whd_ise : 'a evar_map -> constr -> constr
+val whd_ise1 : 'a evar_map -> constr -> constr
+val nf_ise1 : 'a evar_map -> constr -> constr
+val whd_ise1_metas : 'a evar_map -> constr -> constr
(*s Obsolete Reduction Functions *)
diff --git a/kernel/type_errors.ml b/kernel/type_errors.ml
index eaef2dafc0..f3cb78205a 100644
--- a/kernel/type_errors.ml
+++ b/kernel/type_errors.ml
@@ -29,6 +29,8 @@ type type_error =
| NotInductive of constr
| MLCase of string * constr * constr * constr * constr
| CantFindCaseType of constr
+ | OccurCheck of int * constr
+ | NotClean of int * constr
exception TypeError of path_kind * context * type_error
diff --git a/kernel/type_errors.mli b/kernel/type_errors.mli
index 23fed99f3e..a3820217ba 100644
--- a/kernel/type_errors.mli
+++ b/kernel/type_errors.mli
@@ -31,6 +31,8 @@ type type_error =
| NotInductive of constr
| MLCase of string * constr * constr * constr * constr
| CantFindCaseType of constr
+ | OccurCheck of int * constr
+ | NotClean of int * constr
exception TypeError of path_kind * context * type_error
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index 83d38efa22..cd9e6d9211 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -6,6 +6,9 @@ open Names
open Generic
open Term
open Reduction
+open Instantiate
+open Environ
+open Typing_ev
open Classops
open Recordops
open Evarutil
@@ -16,12 +19,12 @@ open Evarutil
*)
(* Fonctions temporaires pour relier la forme castée de la forme jugement *)
let tjudge_of_cast_safe sigma env var =
- match under_casts (nf_ise1 sigma) var with
- DOP2 (Cast, b, t) ->
- (match whd_betadeltaiota sigma t with
- DOP0 (Sort s) -> {body=b; typ=s}
- | _ -> anomaly "Not a type (tjudge_of_cast)")
- | c -> Mach.execute_rec_type sigma env c
+ match under_casts (fun _ -> nf_ise1) env sigma var with
+ | DOP2 (Cast, b, t) ->
+ (match whd_betadeltaiota env sigma t with
+ | DOP0 (Sort s) -> {body=b; typ=s}
+ | _ -> anomaly "Not a type (tjudge_of_cast)")
+ | c -> execute_rec_type env sigma c
(* FIN TMP ***** *)
@@ -51,12 +54,12 @@ let tjudge_of_cast_safe sigma env var =
* ass.
*)
-let rec evar_apprec isevars stack c =
- let (t,stack) = Reduction.apprec !isevars c stack in
- if ise_defined isevars t
- then evar_apprec isevars stack (const_value !isevars t)
- else (t,stack)
-
+let rec evar_apprec env isevars stack c =
+ let (t,stack) = Reduction.apprec env !isevars c stack in
+ if ise_defined isevars t then
+ evar_apprec env isevars stack (existential_value !isevars t)
+ else
+ (t,stack)
let conversion_problems = ref ([] : (conv_pb * constr * constr) list)
@@ -64,245 +67,268 @@ let reset_problems () = conversion_problems := []
let add_conv_pb pb = (conversion_problems := pb::!conversion_problems)
-let get_changed_pb lsp =
- let (pbs,pbs1) = List.fold_left
+let get_changed_pb lev =
+ let (pbs,pbs1) =
+ List.fold_left
(fun (pbs,pbs1) pb ->
- if status_changed lsp pb then (pb::pbs,pbs1)
- else (pbs,pb::pbs1))
+ if status_changed lev pb then
+ (pb::pbs,pbs1)
+ else
+ (pbs,pb::pbs1))
([],[])
- !conversion_problems in
+ !conversion_problems
+ in
conversion_problems := pbs1;
pbs
-
-
(* Precondition: one of the terms of the pb is an uninstanciated evar,
- * possibly applied to arguments.
- *)
-let rec solve_pb isevars pb =
- match solve_simple_eqn (evar_conv_x isevars None CONV_X) isevars pb with
- Some lsp ->
- let pbs = get_changed_pb lsp in
- List.for_all
- (fun (pbty,t1,t2) -> evar_conv_x isevars None pbty t1 t2)
- pbs
- | None -> (add_conv_pb pb; true)
-
-and evar_conv_x isevars b pbty term1 term2 =
- let term1 = whd_ise1 !isevars term1
- and term2 = whd_ise1 !isevars term2 in
- if eq_constr term1 term2 then true
- else if (not(has_undefined_isevars isevars term1)) &
- not(has_undefined_isevars isevars term2)
- then fconv pbty !isevars term1 term2
- else if ise_undefined isevars term1 or ise_undefined isevars term2
- then solve_pb isevars (pbty,term1,term2)
- else
- let (t1,l1) = evar_apprec isevars [] term1
- and (t2,l2) = evar_apprec isevars [] term2 in
- if (head_is_embedded_exist isevars t1 & not(is_eliminator t2))
- or (head_is_embedded_exist isevars t2 & not(is_eliminator t1))
- then (add_conv_pb (pbty,applist(t1,l1),applist(t2,l2)); true)
- else evar_eqappr_x isevars b pbty (t1,l1) (t2,l2)
-
-and evar_eqappr_x isevars b pbty appr1 appr2 =
+ * possibly applied to arguments. *)
+
+let rec solve_pb env isevars pb =
+ match solve_simple_eqn (evar_conv_x env isevars CONV) isevars pb with
+ | Some lsp ->
+ let pbs = get_changed_pb lsp in
+ List.for_all
+ (fun (pbty,t1,t2) -> evar_conv_x env isevars pbty t1 t2)
+ pbs
+ | None -> (add_conv_pb pb; true)
+
+and evar_conv_x env isevars pbty term1 term2 =
+ let term1 = whd_ise1 !isevars term1 in
+ let term2 = whd_ise1 !isevars term2 in
+ if eq_constr term1 term2 then
+ true
+ else if (not(has_undefined_isevars isevars term1)) &
+ not(has_undefined_isevars isevars term2)
+ then
+ is_fconv pbty env !isevars term1 term2
+ else if ise_undefined isevars term1 or ise_undefined isevars term2
+ then
+ solve_pb env isevars (pbty,term1,term2)
+ else
+ let (t1,l1) = evar_apprec env isevars [] term1 in
+ let (t2,l2) = evar_apprec env isevars [] term2 in
+ if (head_is_embedded_exist isevars t1 & not(is_eliminator t2))
+ or (head_is_embedded_exist isevars t2 & not(is_eliminator t1))
+ then
+ (add_conv_pb (pbty,applist(t1,l1),applist(t2,l2)); true)
+ else
+ evar_eqappr_x env isevars pbty (t1,l1) (t2,l2)
+
+and evar_eqappr_x env isevars pbty appr1 appr2 =
match (appr1,appr2) with
- ((DOPN(Const sp1,al1) as term1,l1), (DOPN(Const sp2,al2) as term2,l2)) ->
- let f1 () =
- (ise_undefined isevars term1 or ise_undefined isevars term2) &
- if List.length l1 > List.length l2 then
- let (deb1,rest1) = chop_list (List.length l1-List.length l2) l1
- in solve_pb isevars(pbty,applist(term1,deb1),term2)
- & for_all2eq (evar_conv_x isevars b CONV_X) rest1 l2
- else
- let (deb2,rest2) = chop_list (List.length l2-List.length l1) l2
- in solve_pb isevars(pbty,term1,applist(term2,deb2))
- & for_all2eq (evar_conv_x isevars b CONV_X) l1 rest2
- and f2 () =
- (sp1 = sp2)
- & (for_all2eq_vect (evar_conv_x isevars b CONV_X) al1 al2)
- & (for_all2eq (evar_conv_x isevars b CONV_X) l1 l2)
- and f3 () =
- b<>None
- & (try conv_record isevars b
- (try check_conv_record appr1 appr2
- with Not_found -> check_conv_record appr2 appr1)
- with _ -> false)
- and f4 () =
- if evaluable_const !isevars term2 then
- evar_eqappr_x isevars b pbty
- appr1 (evar_apprec isevars l2 (const_value !isevars term2))
- else if evaluable_const !isevars term1 then
- evar_eqappr_x isevars b pbty
- (evar_apprec isevars l1 (const_value !isevars term1)) appr2
- else false
- in ise_try isevars [f1; f2; f3; f4]
-
- | ((DOPN(Const _,_) as term1,l1),(t2,l2)) ->
- let f1 () =
- ise_undefined isevars term1 &
- (List.length l1 <= List.length l2) &
- let (deb2,rest2) = chop_list (List.length l2-List.length l1) l2
- in solve_pb isevars(pbty,term1,applist(t2,deb2))
- & for_all2eq (evar_conv_x isevars b CONV_X) l1 rest2
- and f2 () =
- b<>None &
- (try conv_record isevars b (check_conv_record appr1 appr2)
- with _ -> false)
- and f3 () =
- evaluable_const !isevars term1 &
- evar_eqappr_x isevars b pbty
- (evar_apprec isevars l1 (const_value !isevars term1)) appr2
- in ise_try isevars [f1; f2; f3]
-
- | ((t1,l1),(DOPN(Const _,_) as t2,l2)) ->
- let f1 () =
- ise_undefined isevars t2 &
- (List.length l2 <= List.length l1) &
- let (deb1,rest1) = chop_list (List.length l1-List.length l2) l1
- in solve_pb isevars(pbty,applist(t1,deb1),t2)
- & for_all2eq (evar_conv_x isevars b CONV_X) rest1 l2
- and f2 () =
- b<>None &
- (try (conv_record isevars b (check_conv_record appr2 appr1))
- with _ -> false)
- and f3 () =
- evaluable_const !isevars t2 &
- evar_eqappr_x isevars b pbty
- appr1 (evar_apprec isevars l2 (const_value !isevars t2))
- in ise_try isevars [f1; f2; f3]
-
- | ((DOPN(Abst _,_) as term1,l1),(DOPN(Abst _,_) as term2,l2)) ->
- let f1 () =
- (term1=term2) &
- (List.length(l1) = List.length(l2)) &
- (for_all2 (evar_conv_x isevars b CONV_X) l1 l2)
- and f2 () =
- if (evaluable_abst term2)
- then evar_eqappr_x isevars b pbty
- appr1 (evar_apprec isevars l2 (abst_value term2))
- else evaluable_abst term1
- & evar_eqappr_x isevars b pbty
- (evar_apprec isevars l1 (abst_value term1)) appr2
- in ise_try isevars [f1; f2]
-
- | ((DOPN(Abst _,_) as term1,l1),_) ->
- (evaluable_abst term1)
- & evar_eqappr_x isevars b pbty
- (evar_apprec isevars l1 (abst_value term1)) appr2
-
- | (_,(DOPN(Abst _,_) as term2,l2)) ->
- (evaluable_abst term2)
- & evar_eqappr_x isevars b pbty
- appr1 (evar_apprec isevars l2 (abst_value term2))
-
- | ((Rel(n),l1),(Rel(m),l2)) ->
- n=m
- & (List.length(l1) = List.length(l2))
- & (for_all2 (evar_conv_x isevars b CONV_X) l1 l2)
- | ((DOP2(Cast,c,_),l),_) -> evar_eqappr_x isevars b pbty (c,l) appr2
- | (_,(DOP2(Cast,c,_),l)) -> evar_eqappr_x isevars b pbty appr1 (c,l)
- | ((VAR id1,l1),(VAR id2,l2)) ->
- (id1=id2 & (List.length l1 = List.length l2)
- & (for_all2 (evar_conv_x isevars b CONV_X) l1 l2))
- | ((DOP0(Meta(n)),l1),(DOP0(Meta(m)),l2)) ->
- (n=m & (List.length(l1) = List.length(l2))
- & (for_all2 (evar_conv_x isevars b CONV_X) l1 l2))
- | ((DOP0(Sort s1),[]),(DOP0(Sort s2),[])) -> sort_cmp pbty s1 s2
- | ((DOP2(Lambda,c1,DLAM(_,c2)),[]), (DOP2(Lambda,c'1,DLAM(_,c'2)),[])) ->
- evar_conv_x isevars b CONV_X c1 c'1
- & evar_conv_x isevars b CONV_X c2 c'2
- | ((DOP2(Prod,c1,DLAM(n,c2)),[]), (DOP2(Prod,c'1,DLAM(_,c'2)),[])) ->
- evar_conv_x isevars b CONV_X c1 c'1
- & evar_conv_x isevars
- (option_app
- (add_rel (n,tjudge_of_cast_safe !isevars (outSOME b) c1)) b)
- pbty c2 c'2
- | ((DOPN(MutInd _ as o1,cl1) as ind1,l'1),
- (DOPN(MutInd _ as o2,cl2) as ind2,l'2)) ->
- o1=o2
- & for_all2eq_vect (evar_conv_x isevars b CONV_X) cl1 cl2
- & for_all2eq (evar_conv_x isevars b CONV_X) l'1 l'2
-
- | ((DOPN(MutConstruct _ as o1,cl1) as constr1,l1),
- (DOPN(MutConstruct _ as o2,cl2) as constr2,l2)) ->
- o1=o2
- & for_all2eq_vect (evar_conv_x isevars b CONV_X) cl1 cl2
- & for_all2eq (evar_conv_x isevars b CONV_X) l1 l2
-
- | ((DOPN(MutCase _,_) as constr1,l'1),
- (DOPN(MutCase _,_) as constr2,l'2)) ->
- let (_,p1,c1,cl1) = destCase constr1 in
- let (_,p2,c2,cl2) = destCase constr2 in
- evar_conv_x isevars b CONV_X p1 p2
- & evar_conv_x isevars b CONV_X c1 c2
- & (for_all2eq_vect (evar_conv_x isevars b CONV_X) cl1 cl2)
- & (for_all2eq (evar_conv_x isevars b CONV_X) l'1 l'2)
-
- | ((DOPN(Fix _ as o1,cl1),l1),(DOPN(Fix _ as o2,cl2),l2)) ->
- o1=o2 &
- (for_all2eq_vect (evar_conv_x isevars b CONV_X) cl1 cl2) &
- (for_all2eq (evar_conv_x isevars b CONV_X) l1 l2)
-
- | ((DOPN(CoFix(i1),cl1),l1),(DOPN(CoFix(i2),cl2),l2)) ->
- i1=i2 &
- (for_all2eq_vect (evar_conv_x isevars b CONV_X) cl1 cl2) &
- (for_all2eq (evar_conv_x isevars b CONV_X) l1 l2)
-
- | (DOP0(Implicit),[]),(DOP0(Implicit),[]) -> true
-(* added to compare easily the specification of fixed points
- * But b (optional env) is not updated!
- *)
- | (DLAM(_,c1),[]),(DLAM(_,c2),[]) -> evar_conv_x isevars b pbty c1 c2
- | (DLAMV(_,vc1),[]),(DLAMV(_,vc2),[]) ->
- for_all2eq_vect (evar_conv_x isevars b pbty) vc1 vc2
- | _ -> false
-
-
-and conv_record isevars ((Some env) as b) (c,bs,(xs,xs1),(us,us1),(ts,ts1),t) =
- let ks =
- List.fold_left
- (fun ks b ->
+ | ((DOPN(Const sp1,al1) as term1,l1), (DOPN(Const sp2,al2) as term2,l2)) ->
+ let f1 () =
+ (ise_undefined isevars term1 or ise_undefined isevars term2) &
+ if List.length l1 > List.length l2 then
+ let (deb1,rest1) = list_chop (List.length l1-List.length l2) l1 in
+ solve_pb env isevars(pbty,applist(term1,deb1),term2)
+ & list_for_all2eq (evar_conv_x env isevars CONV) rest1 l2
+ else
+ let (deb2,rest2) = list_chop (List.length l2-List.length l1) l2 in
+ solve_pb env isevars(pbty,term1,applist(term2,deb2))
+ & list_for_all2eq (evar_conv_x env isevars CONV) l1 rest2
+ and f2 () =
+ (sp1 = sp2)
+ & (array_for_all2 (evar_conv_x env isevars CONV) al1 al2)
+ & (list_for_all2eq (evar_conv_x env isevars CONV) l1 l2)
+ and f3 () =
+ (try conv_record env isevars
+ (try check_conv_record appr1 appr2
+ with Not_found -> check_conv_record appr2 appr1)
+ with _ -> false)
+ and f4 () =
+ if evaluable_constant env term2 then
+ evar_eqappr_x env isevars pbty
+ appr1 (evar_apprec env isevars l2 (constant_value env term2))
+ else if evaluable_constant env term1 then
+ evar_eqappr_x env isevars pbty
+ (evar_apprec env isevars l1 (constant_value env term1)) appr2
+ else
+ false
+ in
+ ise_try isevars [f1; f2; f3; f4]
+
+ | ((DOPN(Const _,_) as term1,l1),(t2,l2)) ->
+ let f1 () =
+ ise_undefined isevars term1 &
+ (List.length l1 <= List.length l2) &
+ let (deb2,rest2) = list_chop (List.length l2-List.length l1) l2 in
+ solve_pb env isevars(pbty,term1,applist(t2,deb2))
+ & list_for_all2eq (evar_conv_x env isevars CONV) l1 rest2
+ and f2 () =
+ (try conv_record env isevars (check_conv_record appr1 appr2)
+ with _ -> false)
+ and f3 () =
+ evaluable_constant env term1 &
+ evar_eqappr_x env isevars pbty
+ (evar_apprec env isevars l1 (constant_value env term1)) appr2
+ in
+ ise_try isevars [f1; f2; f3]
+
+ | ((t1,l1),(DOPN(Const _,_) as t2,l2)) ->
+ let f1 () =
+ ise_undefined isevars t2 &
+ (List.length l2 <= List.length l1) &
+ let (deb1,rest1) = list_chop (List.length l1-List.length l2) l1 in
+ solve_pb env isevars(pbty,applist(t1,deb1),t2)
+ & list_for_all2eq (evar_conv_x env isevars CONV) rest1 l2
+ and f2 () =
+ (try (conv_record env isevars (check_conv_record appr2 appr1))
+ with _ -> false)
+ and f3 () =
+ evaluable_constant env t2 &
+ evar_eqappr_x env isevars pbty
+ appr1 (evar_apprec env isevars l2 (constant_value env t2))
+ in
+ ise_try isevars [f1; f2; f3]
+
+ | ((DOPN(Abst _,_) as term1,l1),(DOPN(Abst _,_) as term2,l2)) ->
+ let f1 () =
+ (term1=term2) &
+ (List.length(l1) = List.length(l2)) &
+ (List.for_all2 (evar_conv_x env isevars CONV) l1 l2)
+ and f2 () =
+ if evaluable_abst env term2 then
+ evar_eqappr_x env isevars pbty
+ appr1 (evar_apprec env isevars l2 (abst_value env term2))
+ else
+ evaluable_abst env term1
+ & evar_eqappr_x env isevars pbty
+ (evar_apprec env isevars l1 (abst_value env term1)) appr2
+ in
+ ise_try isevars [f1; f2]
+
+ | ((DOPN(Abst _,_) as term1,l1),_) ->
+ (evaluable_abst env term1)
+ & evar_eqappr_x env isevars pbty
+ (evar_apprec env isevars l1 (abst_value env term1)) appr2
+
+ | (_,(DOPN(Abst _,_) as term2,l2)) ->
+ (evaluable_abst env term2)
+ & evar_eqappr_x env isevars pbty
+ appr1 (evar_apprec env isevars l2 (abst_value env term2))
+
+ | ((Rel(n),l1),(Rel(m),l2)) ->
+ n=m
+ & (List.length(l1) = List.length(l2))
+ & (List.for_all2 (evar_conv_x env isevars CONV) l1 l2)
+
+ | ((DOP2(Cast,c,_),l),_) -> evar_eqappr_x env isevars pbty (c,l) appr2
+
+ | (_,(DOP2(Cast,c,_),l)) -> evar_eqappr_x env isevars pbty appr1 (c,l)
+
+ | ((VAR id1,l1),(VAR id2,l2)) ->
+ (id1=id2 & (List.length l1 = List.length l2)
+ & (List.for_all2 (evar_conv_x env isevars CONV) l1 l2))
+
+ | ((DOP0(Meta(n)),l1),(DOP0(Meta(m)),l2)) ->
+ (n=m & (List.length(l1) = List.length(l2))
+ & (List.for_all2 (evar_conv_x env isevars CONV) l1 l2))
+
+ | ((DOP0(Sort s1),[]),(DOP0(Sort s2),[])) -> base_sort_cmp pbty s1 s2
+
+ | ((DOP2(Lambda,c1,DLAM(_,c2)),[]), (DOP2(Lambda,c'1,DLAM(_,c'2)),[])) ->
+ evar_conv_x env isevars CONV c1 c'1
+ & evar_conv_x env isevars CONV c2 c'2
+
+ | ((DOP2(Prod,c1,DLAM(n,c2)),[]), (DOP2(Prod,c'1,DLAM(_,c'2)),[])) ->
+ evar_conv_x env isevars CONV c1 c'1
+ & evar_conv_x
+ (push_rel (n,tjudge_of_cast_safe !isevars env c1) env) isevars
+ pbty c2 c'2
+
+ | ((DOPN(MutInd _ as o1,cl1) as ind1,l'1),
+ (DOPN(MutInd _ as o2,cl2) as ind2,l'2)) ->
+ o1=o2
+ & array_for_all2 (evar_conv_x env isevars CONV) cl1 cl2
+ & list_for_all2eq (evar_conv_x env isevars CONV) l'1 l'2
+
+ | ((DOPN(MutConstruct _ as o1,cl1) as constr1,l1),
+ (DOPN(MutConstruct _ as o2,cl2) as constr2,l2)) ->
+ o1=o2
+ & array_for_all2 (evar_conv_x env isevars CONV) cl1 cl2
+ & list_for_all2eq (evar_conv_x env isevars CONV) l1 l2
+
+ | ((DOPN(MutCase _,_) as constr1,l'1),
+ (DOPN(MutCase _,_) as constr2,l'2)) ->
+ let (_,p1,c1,cl1) = destCase constr1 in
+ let (_,p2,c2,cl2) = destCase constr2 in
+ evar_conv_x env isevars CONV p1 p2
+ & evar_conv_x env isevars CONV c1 c2
+ & (array_for_all2 (evar_conv_x env isevars CONV) cl1 cl2)
+ & (list_for_all2eq (evar_conv_x env isevars CONV) l'1 l'2)
+
+ | ((DOPN(Fix _ as o1,cl1),l1),(DOPN(Fix _ as o2,cl2),l2)) ->
+ o1=o2 &
+ (array_for_all2 (evar_conv_x env isevars CONV) cl1 cl2) &
+ (list_for_all2eq (evar_conv_x env isevars CONV) l1 l2)
+
+ | ((DOPN(CoFix(i1),cl1),l1),(DOPN(CoFix(i2),cl2),l2)) ->
+ i1=i2 &
+ (array_for_all2 (evar_conv_x env isevars CONV) cl1 cl2) &
+ (list_for_all2eq (evar_conv_x env isevars CONV) l1 l2)
+
+ (***
+ | (DOP0(Implicit),[]),(DOP0(Implicit),[]) -> true
+ (* added to compare easily the specification of fixed points
+ * But b (optional env) is not updated! *)
+ ***)
+
+ | (DLAM(_,c1),[]),(DLAM(_,c2),[]) ->
+ evar_conv_x env isevars pbty c1 c2
+
+ | (DLAMV(_,vc1),[]),(DLAMV(_,vc2),[]) ->
+ array_for_all2 (evar_conv_x env isevars pbty) vc1 vc2
+
+ | _ -> false
+
+and conv_record env isevars (c,bs,(xs,xs1),(us,us1),(ts,ts1),t) =
+ let ks =
+ List.fold_left
+ (fun ks b ->
let (k,_) = new_isevar isevars env (substl ks b) CCI in (k::ks))
- [] bs
- in
- if (for_all2eq
- (fun u1 u -> evar_conv_x isevars b CONV_X u1 (substl ks u))
- us1 us)
- &
- (for_all2eq
- (fun x1 x -> evar_conv_x isevars b CONV_X x1 (substl ks x))
- xs1 xs)
- & (for_all2eq (evar_conv_x isevars b CONV_X) ts ts1)
- & (evar_conv_x isevars b CONV_X t
- (if ks=[] then c
- else (DOPN(AppL,Array.of_list(c::(List.rev ks))))))
- then
- (*TR*) (if !compter then (nbstruc:=!nbstruc+1;
- nbimplstruc:=!nbimplstruc+(List.length ks);true)
- else true)
- else false
-
+ [] bs
+ in
+ if (list_for_all2eq
+ (fun u1 u -> evar_conv_x env isevars CONV u1 (substl ks u))
+ us1 us)
+ &
+ (list_for_all2eq
+ (fun x1 x -> evar_conv_x env isevars CONV x1 (substl ks x))
+ xs1 xs)
+ & (list_for_all2eq (evar_conv_x env isevars CONV) ts ts1)
+ & (evar_conv_x env isevars CONV t
+ (if ks=[] then c
+ else (DOPN(AppL,Array.of_list(c::(List.rev ks))))))
+ then
+ (*TR*) (if !compter then (nbstruc:=!nbstruc+1;
+ nbimplstruc:=!nbimplstruc+(List.length ks);true)
+ else true)
+ else false
and check_conv_record (t1,l1) (t2,l2) =
try
let {o_DEF=c;o_TABS=bs;o_TPARAMS=xs;o_TCOMPS=us} =
objdef_info (cte_of_constr t1,cte_of_constr t2) in
- let xs1,t::ts = chop_list (List.length xs) l1 in
- let us1,ts1= chop_list (List.length us) l2 in
+ let xs1,t,ts =
+ match list_chop (List.length xs) l1 with
+ | xs1,t::ts -> xs1,t,ts
+ | _ -> assert false
+ in
+ let us1,ts1 = list_chop (List.length us) l2 in
c,bs,(xs,xs1),(us,us1),(ts,ts1),t
- with _ -> raise Not_found (* try ... with _ -> ... *)
-
-
+ with _ ->
+ raise Not_found
-let the_conv_x isevars env t1 t2 =
- conv_x !isevars t1 t2 or evar_conv_x isevars (Some env) CONV_X t1 t2
+let the_conv_x env isevars t1 t2 =
+ is_conv env !isevars t1 t2 or evar_conv_x env isevars CONV t1 t2
(* Si conv_x_leq repond true, pourquoi diable est-ce qu'on repasse une couche
* avec evar_conv_x! Si quelqu'un comprend pourquoi, qu'il remplace ce
* commentaire. Sinon, il va y avoir un bon coup de balai. B.B.
*)
-let the_conv_x_leq isevars env t1 t2 =
- conv_x_leq !isevars t1 t2
- or evar_conv_x isevars (Some env) CONV_X_LEQ t1 t2
+let the_conv_x_leq env isevars t1 t2 =
+ is_conv_leq env !isevars t1 t2
+ or evar_conv_x env isevars CONV_LEQ t1 t2
diff --git a/pretyping/evarconv.mli b/pretyping/evarconv.mli
index 0a44a9553e..59dfc7895c 100644
--- a/pretyping/evarconv.mli
+++ b/pretyping/evarconv.mli
@@ -10,13 +10,19 @@ open Evarutil
(*i*)
val reset_problems : unit -> unit
-val the_conv_x : unsafe_env -> 'a evar_defs -> constr -> constr -> bool
-val the_conv_x_leq : unsafe_env -> 'a evar_defs -> constr -> constr -> bool
+val the_conv_x : unsafe_env -> unit evar_defs -> constr -> constr -> bool
+
+val the_conv_x_leq : unsafe_env -> unit evar_defs -> constr -> constr -> bool
(* For debugging *)
-val solve_pb : 'c evar_defs -> conv_pb * constr * constr -> bool
-val evar_conv_x : 'c evar_defs -> context option ->
- conv_pb -> constr -> constr -> bool
-val evar_eqappr_x : 'c evar_defs -> context option ->
- conv_pb -> constr * constr list -> constr * constr list -> bool
+val solve_pb :
+ unsafe_env -> unit evar_defs -> conv_pb * constr * constr -> bool
+
+val evar_conv_x :
+ unsafe_env -> unit evar_defs ->
+ conv_pb -> constr -> constr -> bool
+
+val evar_eqappr_x :
+ unsafe_env -> unit evar_defs ->
+ conv_pb -> constr * constr list -> constr * constr list -> bool
diff --git a/pretyping/evarutil.ml b/pretyping/evarutil.ml
index f51bea7753..43653f80d4 100644
--- a/pretyping/evarutil.ml
+++ b/pretyping/evarutil.ml
@@ -10,8 +10,10 @@ open Term
open Sign
open Environ
open Evd
+open Instantiate
open Reduction
open Indrec
+open Pretype_errors
let rec filter_unique = function
| [] -> []
@@ -51,7 +53,6 @@ let new_isevar_sign env sigma typ args =
evar_body = Evar_empty; evar_info = () } in
(Evd.add sigma newev info, mkEvar newev args)
-
(* We don't try to guess in which sort the type should be defined, since
any type has type Type. May cause some trouble, but not so far... *)
let dummy_sort = mkType dummy_univ
@@ -89,30 +90,30 @@ let split_evar_to_arrow sigma c =
* ?3 <-- ?1 no pb: env of ?3 is larger than ?1's
* ?1 <-- (list ?2) pb: ?2 may depend on x, but not ?1.
* What we do is that ?2 is defined by a new evar ?4 whose context will be
- * a prefix of ?2's env, included in ?1's env.
- *)
+ * a prefix of ?2's env, included in ?1's env. *)
+
let do_restrict_hyps sigma c =
- let (ev,argsv) = destEvar c in
- let args = Array.to_list argsv in
+ let (ev,args) = destEvar c in
+ let args = Array.to_list args in
let evd = Evd.map sigma ev in
let env = evd.evar_env in
+ let hyps = get_globals (context env) in
let (_,(rsign,ncargs)) =
- List.fold_left (fun (sign,(rs,na)) a ->
- (tl_sign sign,
- if not(closed0 a) then (rs,na)
- else (add_sign (hd_sign sign) rs, a::na)))
- (hyps,(nil_sign,[])) args in
-(* let (_,(rsign,ncargs)) =
- List.fold_left (fun (sign,(rs,na)) a ->
- (tl_sign sign,
- if not(closed0 a) then (nil_sign,[])
- else (add_sign (hd_sign sign) rs, a::na)))
- (hyps,(nil_sign,[])) args in *)
- let nsign = rev_sign rsign in
- let nargs = (Array.of_list (List.map mkVar (ids_of_sign nsign))) in
- let (sigma',nc) = new_isevar_sign sigma nsign evd.concl nargs k in
- let sigma'' = Evd.define sigma' sp nc in
- (sigma'', mkConst (path_of_const nc) (Array.of_list (List.rev ncargs)))
+ List.fold_left
+ (fun (sign,(rs,na)) a ->
+ (tl_sign sign,
+ if not(closed0 a) then
+ (rs,na)
+ else
+ (add_sign (hd_sign sign) rs, a::na)))
+ (hyps,(nil_sign,[])) args
+ in
+ let sign' = rev_sign rsign in
+ let env' = change_hyps (fun _ -> sign') env in
+ let args' = Array.of_list (List.map mkVar (ids_of_sign sign')) in
+ let (sigma',nc) = new_isevar_sign env' sigma evd.evar_concl args' in
+ let sigma'' = Evd.define sigma' ev nc in
+ (sigma'', nc)
@@ -149,48 +150,21 @@ let ise_map isevars sp = Evd.map !isevars sp
let ise_define isevars sp body = isevars := Evd.define !isevars sp body
(* Does k corresponds to an (un)defined existential ? *)
-let ise_undefined isevars k =
- match k with
- DOPN(Const _,_) ->
- ise_in_dom isevars (path_of_const k) &
- not (defined_const !isevars k)
+let ise_undefined isevars = function
+ | DOPN(Evar n,_) -> not (Evd.is_defined !isevars n)
| _ -> false
-
-let ise_defined isevars k =
- match k with
- DOPN(Const _,_) -> Termenv.defined_existential !isevars k
+let ise_defined isevars = function
+ | DOPN(Evar n,_) -> Evd.is_defined !isevars n
| _ -> false
-
let restrict_hyps isevars c =
- if ise_undefined isevars c & not (closed0 c)
- then
- (let (sigma,rc) = do_restrict_hyps !isevars c in
+ if ise_undefined isevars c & not (closed0 c) then begin
+ let (sigma,rc) = do_restrict_hyps !isevars c in
isevars := sigma;
- rc)
- else c
-
-
-
-let error_occur_check sp rhs =
- let id = string_of_id (Names.basename sp) in
- let pt = prterm rhs in
- errorlabstrm "Trad.occur_check"
- [< 'sTR"Occur check failed: tried to define "; 'sTR id;
- 'sTR" with term"; 'bRK(1,1); pt >]
-
-
-(* We need the environment here *)
-let error_not_clean sp t =
- let c = Rel (List.hd (Listset.elements(free_rels t))) in
- let id = string_of_id (Names.basename sp) in
- let var = pTERM(c) in
- errorlabstrm "Trad.not_clean"
- [< 'sTR"Tried to define "; 'sTR id;
- 'sTR" with a term using variable "; var; 'sPC;
- 'sTR"which is not in its scope." >]
-
+ rc
+ end else
+ c
(* We try to instanciate the evar assuming the body won't depend
* on arguments that are not Rels or VARs, or appearing several times.
@@ -215,30 +189,33 @@ let real_clean isevars sp args rhs =
| DLAM(n,a) -> DLAM(n, subs (k+1) a)
| DLAMV(n,v) -> DLAMV(n, Array.map (subs (k+1)) v) in
let body = subs 0 rhs in
- if not (closed0 body) then error_not_clean sp body;
+ if not (closed0 body) then error_not_clean CCI empty_env sp body;
body
(* [new_isevar] declares a new existential in an env env with type typ *)
(* Converting the env into the sign of the evar to define *)
+
let new_isevar isevars env typ k =
- let (ENVIRON(sign,dbenv)) = env in
+ let (ENVIRON(sign,dbenv)) = context env in
let t =
List.fold_left (fun b (na,d)-> mkLambda na (incast_type d) b) typ dbenv in
let rec aux sign = function
- (0, t) -> (sign,t)
- | (n, (DOP2(Lambda,d,(DLAM(na,b))))) ->
+ | (0, t) -> (sign,t)
+ | (n, DOP2(Lambda,d,(DLAM(na,b)))) ->
let na = if na = Anonymous then Name(id_of_string"_") else na in
let id = next_name_away na (ids_of_sign sign) in
aux (add_sign (id,(outcast_type d)) sign) (n-1, subst1 (VAR id) b)
- | (_, _) -> anomaly "Trad.new_isevar" in
+ | (_, _) -> anomaly "Trad.new_isevar"
+ in
let (sign',typ') = aux sign (List.length dbenv, t) in
+ let env' = change_hyps (fun _ -> sign') env in
let newargs =
(List.rev(rel_list 0 (List.length dbenv)))
@(List.map (fun id -> VAR id) (ids_of_sign sign)) in
let (sigma',evar) =
- new_isevar_sign !isevars sign' typ' (Array.of_list newargs) k in
+ new_isevar_sign env' !isevars typ' (Array.of_list newargs) in
isevars := sigma';
(evar,typ')
@@ -262,67 +239,76 @@ let new_isevar isevars env typ k =
* ?1 would be instantiated by (le y y) but y is not in the scope of ?1
*)
let evar_define isevars lhs rhs =
- let (sp,argsv) = destConst lhs in
- let _ = if occur_opern (Const sp) rhs then error_occur_check sp rhs in
+ let (ev,argsv) = destEvar lhs in
+ if occur_opern (Evar ev) rhs then error_occur_check CCI empty_env ev rhs;
let args = List.map (function (VAR _ | Rel _) as t -> t | _ -> mkImplicit)
(Array.to_list argsv) in
- let evd = ise_map isevars sp in
- let hyps= evd.hyps in
+ let evd = ise_map isevars ev in
+ let hyps = get_globals (context evd.evar_env) in
(* the substitution to invert *)
let worklist = List.combine (ids_of_sign hyps) args in
- let body = real_clean isevars sp worklist rhs in
- ise_define isevars sp body;
- [sp]
+ let body = real_clean isevars ev worklist rhs in
+ ise_define isevars ev body;
+ [ev]
(* Solve pbs (?i x1..xn) = (?i y1..yn) which arises often in fixpoint
* definitions. We try to unify the xi with the yi pairwise. The pairs
* that don't unify are discarded (i.e. ?i is redefined so that it does not
- * depend on these args).
- *)
+ * depend on these args). *)
+
let solve_refl conv_algo isevars c1 c2 =
- let (sp,argsv1) = destConst c1
- and (_,argsv2) = destConst c2 in
- let evd = Evd.map !isevars sp in
- let hyps = evd.Evd.hyps in
- let (_,rsign) = it_vect2
+ let (ev,argsv1) = destEvar c1
+ and (_,argsv2) = destEvar c2 in
+ let evd = Evd.map !isevars ev in
+ let env = evd.evar_env in
+ let hyps = get_globals (context env) in
+ let (_,rsign) =
+ array_fold_left2
(fun (sgn,rsgn) a1 a2 ->
- if conv_algo a1 a2
- then (tl_sign sgn, add_sign (hd_sign sgn) rsgn)
- else (tl_sign sgn, rsgn))
- (hyps,nil_sign) argsv1 argsv2 in
+ if conv_algo a1 a2 then
+ (tl_sign sgn, add_sign (hd_sign sgn) rsgn)
+ else
+ (tl_sign sgn, rsgn))
+ (hyps,nil_sign) argsv1 argsv2
+ in
let nsign = rev_sign rsign in
+ let nenv = change_hyps (fun _ -> nsign) env in
let nargs = (Array.of_list (List.map mkVar (ids_of_sign nsign))) in
- let newsp = new_isevar_path CCI in
+ let newev = Evd.new_evar () in
+ let info = { evar_concl = evd.evar_concl; evar_env = nenv;
+ evar_body = Evar_empty; evar_info = () } in
isevars :=
- Evd.define (Evd.add_noinfo !isevars newsp nsign evd.Evd.concl)
- sp (mkConst newsp nargs);
- Some [sp]
+ Evd.define (Evd.add !isevars newev info) ev (mkEvar newev nargs);
+ Some [ev]
(* Tries to solve problem t1 = t2.
* Precondition: one of t1,t2 is an uninstanciated evar, possibly
* applied to arguments.
* Returns an optional list of evars that were instantiated, or None
- * if the problem couldn't be solved.
- *)
+ * if the problem couldn't be solved. *)
+
(* Rq: uncomplete algorithm if pbty = CONV_X_LEQ ! *)
let rec solve_simple_eqn conv_algo isevars ((pbty,t1,t2) as pb) =
let t1 = nf_ise1 !isevars t1 in
let t2 = nf_ise1 !isevars t2 in
- if eq_constr t1 t2 then Some []
- else match (ise_undefined isevars t1, ise_undefined isevars t2) with
- (true,true) ->
- if path_of_const t1 = path_of_const t2
- then solve_refl conv_algo isevars t1 t2
- else if Array.length(args_of_const t1) < Array.length(args_of_const t2)
- then Some (evar_define isevars t2 t1)
- else Some (evar_define isevars t1 t2)
- | (true,false) -> Some (evar_define isevars t1 t2)
- | (false,true) -> Some (evar_define isevars t2 t1)
- | _ -> None
-
+ if eq_constr t1 t2 then
+ Some []
+ else
+ match (ise_undefined isevars t1, ise_undefined isevars t2) with
+ | (true,true) ->
+ if path_of_const t1 = path_of_const t2 then
+ solve_refl conv_algo isevars t1 t2
+ else if Array.length(args_of_const t1) <
+ Array.length(args_of_const t2) then
+ Some (evar_define isevars t2 t1)
+ else
+ Some (evar_define isevars t1 t2)
+ | (true,false) -> Some (evar_define isevars t1 t2)
+ | (false,true) -> Some (evar_define isevars t2 t1)
+ | _ -> None
(*-------------------*)
(* Now several auxiliary functions for the conversion algorithms modulo
@@ -332,69 +318,63 @@ let rec solve_simple_eqn conv_algo isevars ((pbty,t1,t2) as pb) =
let has_undefined_isevars isevars c =
let rec hasrec = function
- DOPN(Const sp,cl) as k ->
- if ise_in_dom isevars sp then
- if defined_const !isevars k
- then hasrec (const_value !isevars k)
- else failwith "caught"
- else Array.iter hasrec cl
-
- | DOP1(_,c) -> hasrec c
- | DOP2(_,c1,c2) -> (hasrec c1; hasrec c2)
- | DOPL(_,l) -> List.iter hasrec l
- | DOPN(_,cl) -> Array.iter hasrec cl
- | DLAM(_,c) -> hasrec c
- | DLAMV(_,cl) -> Array.iter hasrec cl
- | (VAR _|Rel _|DOP0 _) -> ()
- in (try (hasrec c ; false) with Failure "caught" -> true)
-
-
+ | DOPN(Evar ev,cl) as k ->
+ if ise_in_dom isevars ev then
+ if ise_defined isevars k then
+ hasrec (existential_value !isevars k)
+ else
+ failwith "caught"
+ else
+ Array.iter hasrec cl
+ | DOP1(_,c) -> hasrec c
+ | DOP2(_,c1,c2) -> (hasrec c1; hasrec c2)
+ | DOPL(_,l) -> List.iter hasrec l
+ | DOPN(_,cl) -> Array.iter hasrec cl
+ | DLAM(_,c) -> hasrec c
+ | DLAMV(_,cl) -> Array.iter hasrec cl
+ | (VAR _|Rel _|DOP0 _) -> ()
+ in
+ (try (hasrec c ; false) with Failure "caught" -> true)
let head_is_exist isevars =
- let rec hrec = function
- DOPN(Const _,_) as k -> ise_undefined isevars k
- | DOPN(AppL,cl) -> hrec (hd_vect cl)
- | DOP2(Cast,c,_) -> hrec c
- | _ -> false
- in hrec
-
-
+ let rec hrec = function
+ | DOPN(Evar _,_) as k -> ise_undefined isevars k
+ | DOPN(AppL,cl) -> hrec (array_hd cl)
+ | DOP2(Cast,c,_) -> hrec c
+ | _ -> false
+ in
+ hrec
let rec is_eliminator = function
- DOPN (AppL,_) -> true
- | DOPN(MutCase _,_) -> true
- | DOP2 (Cast,c,_) -> is_eliminator c
+ | DOPN (AppL,_) -> true
+ | DOPN (MutCase _,_) -> true
+ | DOP2 (Cast,c,_) -> is_eliminator c
| _ -> false
-
let head_is_embedded_exist isevars c =
- (head_is_exist isevars c) & (is_eliminator c)
-
-
-let headconstant =
- let rec hrec = function
- DOPN(Const sp,_) -> sp
- | DOPN(MutCase _,_) as mc ->
- let (_,_,c,_) = destCase mc in
- hrec c
- | DOPN(AppL,cl) -> hrec (hd_vect cl)
- | DOP2(Cast,c,_) -> hrec c
- | _ -> failwith "headconstant"
- in hrec
-
-
-let status_changed lsp (pbty,t1,t2) =
- try List.mem (headconstant t1) lsp or List.mem (headconstant t2) lsp
- with Failure _ ->
- try List.mem (headconstant t2) lsp
- with Failure _ -> false
-
-
-
+ (head_is_exist isevars c) & (is_eliminator c)
+
+let head_evar =
+ let rec hrec = function
+ | DOPN(Evar ev,_) -> ev
+ | DOPN(MutCase _,_) as mc ->
+ let (_,_,c,_) = destCase mc in hrec c
+ | DOPN(AppL,cl) -> hrec (array_hd cl)
+ | DOP2(Cast,c,_) -> hrec c
+ | _ -> failwith "headconstant"
+ in
+ hrec
+
+let status_changed lev (pbty,t1,t2) =
+ try
+ List.mem (head_evar t1) lev or List.mem (head_evar t2) lev
+ with Failure _ ->
+ try List.mem (head_evar t2) lev with Failure _ -> false
(* Operations on value/type constraints used in trad and progmach *)
type trad_constraint = bool * (constr option * constr option)
+
(* Basically, we have the following kind of constraints (in increasing
* strength order):
* (false,(None,None)) -> no constraint at all
@@ -408,8 +388,6 @@ type trad_constraint = bool * (constr option * constr option)
* of Set.
*)
-
-
(* The empty constraint *)
let mt_tycon = (false,(None,None))
@@ -425,51 +403,49 @@ let mk_tycon2 (is_ass,_) ty = (is_ass,(None,Some ty))
(* Given a type constraint on a term, returns the type constraint on its first
* argument. If the input constraint is an evar instantiate it with the product
- * of 2 new evars.
- *)
-let prod_dom_tycon_unif isevars = function
- None -> None
- | Some c ->
- (match whd_betadeltaiota !isevars c with
- DOP2(Prod,c1,_) -> Some c1
- | t ->
- if (ise_undefined isevars t) then
- (let (sigma,dom,_) = split_evar_to_arrow !isevars t in
- isevars := sigma;
- Some dom)
- else None)
+ * of 2 new evars. *)
+let prod_dom_tycon_unif env isevars = function
+ | None -> None
+ | Some c ->
+ (match whd_betadeltaiota env !isevars c with
+ | DOP2(Prod,c1,_) -> Some c1
+ | t ->
+ if (ise_undefined isevars t) then begin
+ let (sigma,dom,_) = split_evar_to_arrow !isevars t in
+ isevars := sigma;
+ Some dom
+ end else
+ None)
(* Given a constraint on a term, returns the constraint corresponding to its
- * first argument.
- *)
-let app_dom_tycon isevars (_,(_,tyc)) =
- (false,(None, prod_dom_tycon_unif isevars tyc))
+ * first argument. *)
+
+let app_dom_tycon env isevars (_,(_,tyc)) =
+ (false,(None, prod_dom_tycon_unif env isevars tyc))
(* Given a constraint on a term, returns the constraint corresponding to this
- * term applied to arg.
- *)
-let app_rng_tycon isevars arg = function
- (_,(_,None)) as vtcon -> vtcon
- | (_,(_,Some c)) ->
- (match whd_betadeltaiota !isevars c with
- DOP2(Prod,_,DLAM(_,b)) -> mk_tycon (subst1 arg b)
- | _ -> mt_tycon)
+ * term applied to arg. *)
+let app_rng_tycon env isevars arg = function
+ | (_,(_,None)) as vtcon -> vtcon
+ | (_,(_,Some c)) ->
+ (match whd_betadeltaiota env !isevars c with
+ | DOP2(Prod,_,DLAM(_,b)) -> mk_tycon (subst1 arg b)
+ | _ -> mt_tycon)
(* Given a constraint on an abstraction, returns the constraint on the value
* of the domain type. If we had no constraint, we still know it should be
- * a type.
- *)
-let abs_dom_valcon isevars (_,(_,tyc)) =
- (true,(prod_dom_tycon_unif isevars tyc, None))
-
+ * a type. *)
+
+let abs_dom_valcon env isevars (_,(_,tyc)) =
+ (true,(prod_dom_tycon_unif env isevars tyc, None))
(* Given a constraint on an abstraction, returns the constraint on the body *)
-let abs_rng_tycon isevars = function
- (_,(_,None)) -> mt_tycon
+let abs_rng_tycon env isevars = function
+ | (_,(_,None)) -> mt_tycon
| (_,(_,Some c)) ->
- (match whd_betadeltaiota !isevars c with
- | DOP2(Prod,_,DLAM(_,b)) -> mk_tycon b
- | _ -> mt_tycon)
+ (match whd_betadeltaiota env !isevars c with
+ | DOP2(Prod,_,DLAM(_,b)) -> mk_tycon b
+ | _ -> mt_tycon)
diff --git a/pretyping/evarutil.mli b/pretyping/evarutil.mli
index d7ef3620fb..c8d6b91acc 100644
--- a/pretyping/evarutil.mli
+++ b/pretyping/evarutil.mli
@@ -19,7 +19,7 @@ val filter_sign :
'a * identifier list * var_context
val dummy_sort : constr
-val do_restrict_hyps : 'a evar_map -> constr -> 'a evar_map * constr
+val do_restrict_hyps : unit evar_map -> constr -> unit evar_map * constr
type 'a evar_defs = 'a evar_map ref
@@ -30,20 +30,19 @@ val ise_undefined : 'a evar_defs -> constr -> bool
val ise_defined : 'a evar_defs -> constr -> bool
val real_clean :
- 'a evar_defs ->
- section_path -> (identifier * constr) list -> constr -> constr
+ unit evar_defs -> int -> (identifier * constr) list -> constr -> constr
val new_isevar :
- unsafe_env -> 'a evar_defs -> constr -> path_kind -> constr * constr
-val evar_define : 'a evar_defs -> constr -> constr -> section_path list
-val solve_simple_eqn : (constr -> constr -> bool) -> 'a evar_defs ->
- (conv_pb * constr * constr) -> section_path list option
+ unit evar_defs -> unsafe_env -> constr -> path_kind -> constr * constr
+val evar_define : unit evar_defs -> constr -> constr -> int list
+val solve_simple_eqn : (constr -> constr -> bool) -> unit evar_defs ->
+ (conv_pb * constr * constr) -> int list option
val has_undefined_isevars : 'a evar_defs -> constr -> bool
val head_is_exist : 'a evar_defs -> constr -> bool
val is_eliminator : constr -> bool
val head_is_embedded_exist : 'a evar_defs -> constr -> bool
-val headconstant : constr -> section_path
-val status_changed : section_path list -> conv_pb * constr * constr -> bool
+val head_evar : constr -> int
+val status_changed : int list -> conv_pb * constr * constr -> bool
(* Value/Type constraints *)
@@ -56,13 +55,16 @@ val mk_tycon : constr -> trad_constraint
val mk_tycon2 : trad_constraint -> constr -> trad_constraint
(* application *)
-val app_dom_tycon : 'a evar_defs -> trad_constraint -> trad_constraint
+val app_dom_tycon :
+ unsafe_env -> unit evar_defs -> trad_constraint -> trad_constraint
val app_rng_tycon :
- 'a evar_defs -> constr -> trad_constraint -> trad_constraint
+ unsafe_env -> 'a evar_defs -> constr -> trad_constraint -> trad_constraint
(* abstraction *)
-val abs_dom_valcon : 'a evar_defs -> trad_constraint -> trad_constraint
-val abs_rng_tycon : 'a evar_defs -> trad_constraint -> trad_constraint
+val abs_dom_valcon :
+ unsafe_env -> unit evar_defs -> trad_constraint -> trad_constraint
+val abs_rng_tycon :
+ unsafe_env -> 'a evar_defs -> trad_constraint -> trad_constraint
(* $Id$ *)
diff --git a/pretyping/pretype_errors.ml b/pretyping/pretype_errors.ml
index 8892eaf7fa..c3baf8ea06 100644
--- a/pretyping/pretype_errors.ml
+++ b/pretyping/pretype_errors.ml
@@ -1,4 +1,14 @@
+(* $Id$ *)
+
+open Names
+open Sign
+open Environ
+open Type_errors
+open Rawterm
+
+exception PretypeError of loc * path_kind * context * type_error
+
let error_cant_find_case_type_loc loc env expr =
raise (PretypeError (loc,CCI,context env,CantFindCaseType expr))
@@ -7,3 +17,13 @@ let error_ill_formed_branch k env c i actty expty =
let error_number_branches_loc loc k env c ct expn =
raise (PretypeError (loc, k, context env, NumberBranches (c,ct,expn)))
+
+let error_ill_formed_branch_loc loc k env c i actty expty =
+ raise (PretypeError (loc, k, context env, IllFormedBranch (c,i,actty,expty)))
+
+let error_occur_check k env ev c =
+ raise (TypeError (k, context env, OccurCheck (ev,c)))
+
+let error_not_clean k env ev c =
+ raise (TypeError (k, context env, NotClean (ev,c)))
+
diff --git a/pretyping/pretype_errors.mli b/pretyping/pretype_errors.mli
index c8f6dc463b..ac605f196a 100644
--- a/pretyping/pretype_errors.mli
+++ b/pretyping/pretype_errors.mli
@@ -11,9 +11,10 @@ open Rawterm
(* The type of errors raised by the pretyper *)
-exception PreTypeError of loc * path_kind * context * type_error
+exception PretypeError of loc * path_kind * context * type_error
-val error_cant_find_case_type_loc : loc -> unsafe_env -> constr -> 'a
+val error_cant_find_case_type_loc :
+ loc -> unsafe_env -> constr -> 'a
val error_ill_formed_branch_loc :
loc -> path_kind -> unsafe_env -> constr -> int -> constr -> constr -> 'b
@@ -21,3 +22,8 @@ val error_ill_formed_branch_loc :
val error_number_branches_loc :
loc -> path_kind -> unsafe_env -> constr -> constr -> int -> 'b
+val error_occur_check : path_kind -> unsafe_env -> int -> constr -> 'a
+
+val error_not_clean : path_kind -> unsafe_env -> int -> constr -> 'a
+
+
diff --git a/proofs/typing_ev.ml b/proofs/typing_ev.ml
index 5e48153719..741ef10409 100644
--- a/proofs/typing_ev.ml
+++ b/proofs/typing_ev.ml
@@ -146,5 +146,9 @@ let type_of env sigma c =
(* The typed type of a judgment. *)
let execute_type env sigma constr =
- let j = safe_machine env sigma constr in
+ let j = execute { fix=false; nocheck=true } env sigma constr in
+ assumption_of_judgment env sigma j
+
+let execute_type env sigma constr =
+ let j = execute { fix=false; nocheck=false } env sigma constr in
assumption_of_judgment env sigma j
diff --git a/proofs/typing_ev.mli b/proofs/typing_ev.mli
index f24ee3914a..b12cd369d3 100644
--- a/proofs/typing_ev.mli
+++ b/proofs/typing_ev.mli
@@ -13,3 +13,6 @@ open Evd
val type_of : unsafe_env -> 'a evar_map -> constr -> constr
val execute_type : unsafe_env -> 'a evar_map -> constr -> typed_type
+
+val execute_rec_type : unsafe_env -> 'a evar_map -> constr -> typed_type
+
diff --git a/toplevel/himsg.ml b/toplevel/himsg.ml
index 53b35ff6d1..04f96a8721 100644
--- a/toplevel/himsg.ml
+++ b/toplevel/himsg.ml
@@ -273,4 +273,20 @@ let explain_refiner_cannot_applt k ctx t harg =
P.pr_term k ctx t; 'sPC; 'sTR"could not be applied to"; 'bRK(1,1);
P.pr_term k ctx harg >]
+let error_occur_check ev rhs =
+ let id = "?" ^ string_of_int ev in
+ let pt = prterm rhs in
+ errorlabstrm "Trad.occur_check"
+ [< 'sTR"Occur check failed: tried to define "; 'sTR id;
+ 'sTR" with term"; 'bRK(1,1); pt >]
+
+let error_not_clean sp t =
+ let c = Rel (List.hd (Listset.elements(free_rels t))) in
+ let id = string_of_id (Names.basename sp) in
+ let var = pTERM(c) in
+ errorlabstrm "Trad.not_clean"
+ [< 'sTR"Tried to define "; 'sTR id;
+ 'sTR" with a term using variable "; var; 'sPC;
+ 'sTR"which is not in its scope." >]
+
end