aboutsummaryrefslogtreecommitdiff
path: root/pretyping
diff options
context:
space:
mode:
Diffstat (limited to 'pretyping')
-rw-r--r--pretyping/arguments_renaming.ml12
-rw-r--r--pretyping/arguments_renaming.mli6
-rw-r--r--pretyping/cases.ml199
-rw-r--r--pretyping/cases.mli10
-rw-r--r--pretyping/cbv.ml12
-rw-r--r--pretyping/cbv.mli2
-rw-r--r--pretyping/classops.ml8
-rw-r--r--pretyping/coercion.ml36
-rw-r--r--pretyping/constr_matching.ml20
-rw-r--r--pretyping/constr_matching.mli6
-rw-r--r--pretyping/detyping.ml18
-rw-r--r--pretyping/evarconv.ml209
-rw-r--r--pretyping/evarconv.mli3
-rw-r--r--pretyping/evardefine.ml22
-rw-r--r--pretyping/evarsolve.ml118
-rw-r--r--pretyping/evarsolve.mli11
-rw-r--r--pretyping/find_subterm.ml9
-rw-r--r--pretyping/glob_ops.ml82
-rw-r--r--pretyping/glob_ops.mli12
-rw-r--r--pretyping/indrec.ml52
-rw-r--r--pretyping/indrec.mli7
-rw-r--r--pretyping/inductiveops.ml56
-rw-r--r--pretyping/inductiveops.mli15
-rw-r--r--pretyping/locusops.ml6
-rw-r--r--pretyping/nativenorm.ml22
-rw-r--r--pretyping/patternops.ml24
-rw-r--r--pretyping/pretype_errors.ml87
-rw-r--r--pretyping/pretype_errors.mli54
-rw-r--r--pretyping/pretyping.ml394
-rw-r--r--pretyping/pretyping.mli11
-rw-r--r--pretyping/program.ml48
-rw-r--r--pretyping/program.mli4
-rw-r--r--pretyping/recordops.ml53
-rw-r--r--pretyping/redops.ml14
-rw-r--r--pretyping/reductionops.ml300
-rw-r--r--pretyping/reductionops.mli50
-rw-r--r--pretyping/retyping.ml20
-rw-r--r--pretyping/retyping.mli2
-rw-r--r--pretyping/tacred.ml50
-rw-r--r--pretyping/tacred.mli2
-rw-r--r--pretyping/typeclasses.ml92
-rw-r--r--pretyping/typeclasses.mli23
-rw-r--r--pretyping/typing.ml26
-rw-r--r--pretyping/typing.mli5
-rw-r--r--pretyping/unification.ml114
-rw-r--r--pretyping/vnorm.ml20
46 files changed, 1357 insertions, 989 deletions
diff --git a/pretyping/arguments_renaming.ml b/pretyping/arguments_renaming.ml
index ca1d0b7fba..1bd03491a7 100644
--- a/pretyping/arguments_renaming.ml
+++ b/pretyping/arguments_renaming.ml
@@ -13,15 +13,17 @@ open Term
open Environ
open Util
open Libobject
+
+module NamedDecl = Context.Named.Declaration
(*i*)
let name_table =
- Summary.ref (Refmap.empty : Name.t list list Refmap.t)
+ Summary.ref (Refmap.empty : Name.t list Refmap.t)
~name:"rename-arguments"
type req =
| ReqLocal
- | ReqGlobal of global_reference * Name.t list list
+ | ReqGlobal of global_reference * Name.t list
let load_rename_args _ (_, (_, (r, names))) =
name_table := Refmap.add r names !name_table
@@ -48,8 +50,8 @@ let discharge_rename_args = function
(try
let vars,_,_ = section_segment_of_reference c in
let c' = pop_global_reference c in
- let var_names = List.map (fun (id, _,_,_) -> Name id) vars in
- let names' = List.map (fun l -> var_names @ l) names in
+ let var_names = List.map (fst %> NamedDecl.get_id %> Name.mk_name) vars in
+ let names' = var_names @ names in
Some (ReqGlobal (c', names), (c', names'))
with Not_found -> Some req)
| _ -> None
@@ -83,7 +85,7 @@ let rec rename_prod c = function
| _ -> c
let rename_type ty ref =
- try rename_prod ty (List.hd (arguments_names ref))
+ try rename_prod ty (arguments_names ref)
with Not_found -> ty
let rename_type_of_constant env c =
diff --git a/pretyping/arguments_renaming.mli b/pretyping/arguments_renaming.mli
index a334055011..e123e77862 100644
--- a/pretyping/arguments_renaming.mli
+++ b/pretyping/arguments_renaming.mli
@@ -11,10 +11,10 @@ open Globnames
open Environ
open Term
-val rename_arguments : bool -> global_reference -> Name.t list list -> unit
+val rename_arguments : bool -> global_reference -> Name.t list -> unit
-(** [Not_found] is raised is no names are defined for [r] *)
-val arguments_names : global_reference -> Name.t list list
+(** [Not_found] is raised if no names are defined for [r] *)
+val arguments_names : global_reference -> Name.t list
val rename_type_of_constant : env -> pconstant -> types
val rename_type_of_inductive : env -> pinductive -> types
diff --git a/pretyping/cases.ml b/pretyping/cases.ml
index b8fb61e35d..63c2dde182 100644
--- a/pretyping/cases.ml
+++ b/pretyping/cases.ml
@@ -7,7 +7,7 @@
(************************************************************************)
open Pp
-open Errors
+open CErrors
open Util
open Names
open Nameops
@@ -32,6 +32,9 @@ open Evd
open Sigma.Notations
open Context.Rel.Declaration
+module RelDecl = Context.Rel.Declaration
+module NamedDecl = Context.Named.Declaration
+
(* Pattern-matching errors *)
type pattern_matching_error =
@@ -45,30 +48,32 @@ type pattern_matching_error =
exception PatternMatchingError of env * evar_map * pattern_matching_error
-let raise_pattern_matching_error (loc,env,sigma,te) =
- Loc.raise loc (PatternMatchingError(env,sigma,te))
+let raise_pattern_matching_error ?loc (env,sigma,te) =
+ Loc.raise ?loc (PatternMatchingError(env,sigma,te))
-let error_bad_pattern_loc loc env sigma cstr ind =
- raise_pattern_matching_error
- (loc, env, sigma, BadPattern (cstr,ind))
+let error_bad_pattern ?loc env sigma cstr ind =
+ raise_pattern_matching_error ?loc
+ (env, sigma, BadPattern (cstr,ind))
-let error_bad_constructor_loc loc env cstr ind =
- raise_pattern_matching_error
- (loc, env, Evd.empty, BadConstructor (cstr,ind))
+let error_bad_constructor ?loc env cstr ind =
+ raise_pattern_matching_error ?loc
+ (env, Evd.empty, BadConstructor (cstr,ind))
-let error_wrong_numarg_constructor_loc loc env c n =
- raise_pattern_matching_error (loc, env, Evd.empty, WrongNumargConstructor(c,n))
+let error_wrong_numarg_constructor ?loc env c n =
+ raise_pattern_matching_error ?loc (env, Evd.empty, WrongNumargConstructor(c,n))
-let error_wrong_numarg_inductive_loc loc env c n =
- raise_pattern_matching_error (loc, env, Evd.empty, WrongNumargInductive(c,n))
+let error_wrong_numarg_inductive ?loc env c n =
+ raise_pattern_matching_error ?loc (env, Evd.empty, WrongNumargInductive(c,n))
-let rec list_try_compile f = function
- | [a] -> f a
- | [] -> anomaly (str "try_find_f")
+let list_try_compile f l =
+ let rec aux errors = function
+ | [] -> if errors = [] then anomaly (str "try_find_f") else iraise (List.last errors)
| h::t ->
try f h
- with UserError _ | TypeError _ | PretypeError _ | PatternMatchingError _ ->
- list_try_compile f t
+ with UserError _ | TypeError _ | PretypeError _ | PatternMatchingError _ as e ->
+ let e = CErrors.push e in
+ aux (e::errors) t in
+ aux [] l
let force_name =
let nx = Name default_dependent_ident in function Anonymous -> nx | na -> na
@@ -270,9 +275,9 @@ let rec find_row_ind = function
let inductive_template evdref env tmloc ind =
let indu = evd_comb1 (Evd.fresh_inductive_instance env) evdref ind in
let arsign = inductive_alldecls_env env indu in
- let hole_source = match tmloc with
- | Some loc -> fun i -> (loc, Evar_kinds.TomatchTypeParameter (ind,i))
- | None -> fun _ -> (Loc.ghost, Evar_kinds.InternalHole) in
+ let hole_source i = match tmloc with
+ | Some loc -> (loc, Evar_kinds.TomatchTypeParameter (ind,i))
+ | None -> (Loc.ghost, Evar_kinds.TomatchTypeParameter (ind,i)) in
let (_,evarl,_) =
List.fold_right
(fun decl (subst,evarl,n) ->
@@ -479,32 +484,31 @@ let check_and_adjust_constructor env ind cstrs = function
let args' = adjust_local_defs loc (args, List.rev ci.cs_args)
in PatCstr (loc, cstr, args', alias)
with NotAdjustable ->
- error_wrong_numarg_constructor_loc loc env cstr nb_args_constr
+ error_wrong_numarg_constructor ~loc env cstr nb_args_constr
else
(* Try to insert a coercion *)
try
Coercion.inh_pattern_coerce_to loc env pat ind' ind
with Not_found ->
- error_bad_constructor_loc loc env cstr ind
+ error_bad_constructor ~loc env cstr ind
let check_all_variables env sigma typ mat =
List.iter
(fun eqn -> match current_pattern eqn with
| PatVar (_,id) -> ()
| PatCstr (loc,cstr_sp,_,_) ->
- error_bad_pattern_loc loc env sigma cstr_sp typ)
+ error_bad_pattern ~loc env sigma cstr_sp typ)
mat
let check_unused_pattern env eqn =
if not !(eqn.used) then
- raise_pattern_matching_error
- (eqn.eqn_loc, env, Evd.empty, UnusedClause eqn.patterns)
+ raise_pattern_matching_error ~loc:eqn.eqn_loc (env, Evd.empty, UnusedClause eqn.patterns)
let set_used_pattern eqn = eqn.used := true
let extract_rhs pb =
match pb.mat with
- | [] -> errorlabstrm "build_leaf" (msg_may_need_inversion())
+ | [] -> user_err ~hdr:"build_leaf" (msg_may_need_inversion())
| eqn::_ ->
set_used_pattern eqn;
eqn.rhs
@@ -605,7 +609,7 @@ let relocate_index_tomatch n1 n2 =
NonDepAlias :: genrec depth rest
| Abstract (i,d) :: rest ->
let i = relocate_rel n1 n2 depth i in
- Abstract (i, map_constr (relocate_index n1 n2 depth) d)
+ Abstract (i, RelDecl.map_constr (relocate_index n1 n2 depth) d)
:: genrec (depth+1) rest in
genrec 0
@@ -638,7 +642,7 @@ let replace_tomatch n c =
| NonDepAlias :: rest ->
NonDepAlias :: replrec depth rest
| Abstract (i,d) :: rest ->
- Abstract (i, map_constr (replace_term n c depth) d)
+ Abstract (i, RelDecl.map_constr (replace_term n c depth) d)
:: replrec (depth+1) rest in
replrec 0
@@ -663,7 +667,7 @@ let rec liftn_tomatch_stack n depth = function
NonDepAlias :: liftn_tomatch_stack n depth rest
| Abstract (i,d)::rest ->
let i = if i<depth then i else i+n in
- Abstract (i, map_constr (liftn n depth) d)
+ Abstract (i, RelDecl.map_constr (liftn n depth) d)
::(liftn_tomatch_stack n (depth+1) rest)
let lift_tomatch_stack n = liftn_tomatch_stack n 1
@@ -731,7 +735,7 @@ let get_names env sign eqns =
(* We now replace the names y1 .. yn y by the actual names *)
(* xi1 .. xin xi to be found in the i-th clause of the matrix *)
-let recover_initial_subpattern_names = List.map2 set_name
+let recover_initial_subpattern_names = List.map2 RelDecl.set_name
let recover_and_adjust_alias_names names sign =
let rec aux = function
@@ -756,11 +760,11 @@ let push_rels_eqn_with_names sign eqn =
push_rels_eqn sign eqn
let push_generalized_decl_eqn env n decl eqn =
- match get_name decl with
+ match RelDecl.get_name decl with
| Anonymous ->
push_rels_eqn [decl] eqn
| Name _ ->
- push_rels_eqn [set_name (get_name (Environ.lookup_rel n eqn.rhs.rhs_env)) decl] eqn
+ push_rels_eqn [RelDecl.set_name (RelDecl.get_name (Environ.lookup_rel n eqn.rhs.rhs_env)) decl] eqn
let drop_alias_eqn eqn =
{ eqn with alias_stack = List.tl eqn.alias_stack }
@@ -768,7 +772,7 @@ let drop_alias_eqn eqn =
let push_alias_eqn alias eqn =
let aliasname = List.hd eqn.alias_stack in
let eqn = drop_alias_eqn eqn in
- let alias = set_name aliasname alias in
+ let alias = RelDecl.set_name aliasname alias in
push_rels_eqn [alias] eqn
(**********************************************************************)
@@ -845,7 +849,7 @@ let subst_predicate (subst,copt) ccl tms =
| Some c -> c::subst in
substnl_predicate sigma 0 ccl tms
-let specialize_predicate_var (cur,typ,dep) tms ccl =
+let specialize_predicate_var (cur,typ,dep) env tms ccl =
let c = match dep with
| Anonymous -> None
| Name _ -> Some cur
@@ -853,7 +857,9 @@ let specialize_predicate_var (cur,typ,dep) tms ccl =
let l =
match typ with
| IsInd (_, IndType (_, _), []) -> []
- | IsInd (_, IndType (_, realargs), names) -> realargs
+ | IsInd (_, IndType (indf, realargs), names) ->
+ let arsign,_ = get_arity env indf in
+ subst_of_rel_context_instance arsign realargs
| NotInd _ -> [] in
subst_predicate (l,c) ccl tms
@@ -1195,7 +1201,7 @@ let rec generalize_problem names pb = function
| LocalDef (Anonymous,_,_) -> pb', deps
| _ ->
(* for better rendering *)
- let d = map_type (whd_betaiota !(pb.evdref)) d in
+ let d = RelDecl.map_type (whd_betaiota !(pb.evdref)) d in
let tomatch = lift_tomatch_stack 1 pb'.tomatch in
let tomatch = relocate_index_tomatch (i+1) 1 tomatch in
{ pb' with
@@ -1223,7 +1229,7 @@ let build_branch initial current realargs deps (realnames,curname) pb arsign eqn
(* that had matched constructor C *)
let cs_args = const_info.cs_args in
let names,aliasname = get_names pb.env cs_args eqns in
- let typs = List.map2 set_name names cs_args
+ let typs = List.map2 RelDecl.set_name names cs_args
in
(* We build the matrix obtained by expanding the matching on *)
@@ -1273,7 +1279,7 @@ let build_branch initial current realargs deps (realnames,curname) pb arsign eqn
let typs' =
List.map2
(fun (tm, (tmtyp,_), decl) deps ->
- let na = get_name decl in
+ let na = RelDecl.get_name decl in
let na = match curname, na with
| Name _, Anonymous -> curname
| Name _, Name _ -> na
@@ -1305,8 +1311,7 @@ let build_branch initial current realargs deps (realnames,curname) pb arsign eqn
let submat = adjust_impossible_cases pb pred tomatch submat in
let () = match submat with
| [] ->
- raise_pattern_matching_error
- (Loc.ghost, pb.env, Evd.empty, NonExhaustive (complete_history history))
+ raise_pattern_matching_error (pb.env, Evd.empty, NonExhaustive (complete_history history))
| _ -> ()
in
@@ -1329,14 +1334,6 @@ let build_branch initial current realargs deps (realnames,curname) pb arsign eqn
*)
-let mk_case pb (ci,pred,c,brs) =
- let mib = lookup_mind (fst ci.ci_ind) pb.env in
- match mib.mind_record with
- | Some (Some (_, cs, pbs)) ->
- Reduction.beta_appvect brs.(0)
- (Array.map (fun p -> mkProj (Projection.make p true, c)) cs)
- | _ -> mkCase (ci,pred,c,brs)
-
(**********************************************************************)
(* Main compiling descent *)
let rec compile pb =
@@ -1383,7 +1380,9 @@ and match_current pb (initial,tomatch) =
pred current indt (names,dep) tomatch in
let ci = make_case_info pb.env (fst mind) pb.casestyle in
let pred = nf_betaiota !(pb.evdref) pred in
- let case = mk_case pb (ci,pred,current,brvals) in
+ let case =
+ make_case_or_project pb.env indf ci pred current brvals
+ in
Typing.check_allowed_sort pb.env !(pb.evdref) mind current pred;
{ uj_val = applist (case, inst);
uj_type = prod_applist typ inst }
@@ -1394,7 +1393,7 @@ and match_current pb (initial,tomatch) =
and shift_problem ((current,t),_,na) pb =
let ty = type_of_tomatch t in
let tomatch = lift_tomatch_stack 1 pb.tomatch in
- let pred = specialize_predicate_var (current,t,na) pb.tomatch pb.pred in
+ let pred = specialize_predicate_var (current,t,na) pb.env pb.tomatch pb.pred in
let pb =
{ pb with
env = push_rel (LocalDef (na,current,ty)) pb.env;
@@ -1411,7 +1410,7 @@ and shift_problem ((current,t),_,na) pb =
are already introduced in the context, we avoid creating aliases to
themselves by treating this case specially. *)
and pop_problem ((current,t),_,na) pb =
- let pred = specialize_predicate_var (current,t,na) pb.tomatch pb.pred in
+ let pred = specialize_predicate_var (current,t,na) pb.env pb.tomatch pb.pred in
let pb =
{ pb with
pred = pred;
@@ -1664,8 +1663,7 @@ let abstract_tycon loc env evdref subst tycon extenv t =
List.map (fun a -> not (isRel a) || dependent a u
|| Int.Set.mem (destRel a) depvl) inst in
let named_filter =
- let open Context.Named.Declaration in
- List.map (fun d -> dependent (mkVar (get_id d)) u)
+ List.map (fun d -> dependent (mkVar (NamedDecl.get_id d)) u)
(named_context extenv) in
let filter = Filter.make (rel_filter @ named_filter) in
let candidates = u :: List.map mkRel vl in
@@ -1708,7 +1706,7 @@ let build_inversion_problem loc env sigma tms t =
let id = next_name_away (named_hd env t Anonymous) avoid in
PatVar (Loc.ghost,Name id), ((id,t)::subst, id::avoid) in
let rec reveal_pattern t (subst,avoid as acc) =
- match kind_of_term (whd_betadeltaiota env sigma t) with
+ match kind_of_term (whd_all env sigma t) with
| Construct (cstr,u) -> PatCstr (Loc.ghost,cstr,[],Anonymous), acc
| App (f,v) when isConstruct f ->
let cstr,u = destConstruct f in
@@ -1761,7 +1759,7 @@ let build_inversion_problem loc env sigma tms t =
let sub_tms =
List.map2 (fun deps (tm, (tmtyp,_), decl) ->
- let na = if List.is_empty deps then Anonymous else force_name (get_name decl) in
+ let na = if List.is_empty deps then Anonymous else force_name (RelDecl.get_name decl) in
Pushed (true,((tm,tmtyp),deps,na)))
dep_sign decls in
let subst = List.map (fun (na,t) -> (na,lift n t)) subst in
@@ -1801,14 +1799,10 @@ let build_inversion_problem loc env sigma tms t =
it = None } } ] in
(* [pb] is the auxiliary pattern-matching serving as skeleton for the
return type of the original problem Xi *)
- (* let sigma, s = Evd.new_sort_variable sigma in *)
-(*FIXME TRY *)
- (* let sigma, s = Evd.new_sort_variable univ_flexible sigma in *)
let s' = Retyping.get_sort_of env sigma t in
let sigma, s = Evd.new_sort_variable univ_flexible_alg sigma in
let sigma = Evd.set_leq_sort env sigma s' s in
let evdref = ref sigma in
- (* let ty = evd_comb1 (refresh_universes false) evdref ty in *)
let pb =
{ env = pb_env;
evdref = evdref;
@@ -1828,7 +1822,7 @@ let build_initial_predicate arsign pred =
let rec buildrec n pred tmnames = function
| [] -> List.rev tmnames,pred
| (decl::realdecls)::lnames ->
- let na = get_name decl in
+ let na = RelDecl.get_name decl in
let n' = n + List.length realdecls in
buildrec (n'+1) pred (force_name na::tmnames) lnames
| _ -> assert false
@@ -1844,8 +1838,8 @@ let extract_arity_signature ?(dolift=true) env0 tomatchl tmsign =
| None -> [LocalAssum (na, lift n typ)]
| Some b -> [LocalDef (na, lift n b, lift n typ)])
| Some (loc,_,_) ->
- user_err_loc (loc,"",
- str"Unexpected type annotation for a term of non inductive type."))
+ user_err ~loc
+ (str"Unexpected type annotation for a term of non inductive type."))
| IsInd (term,IndType(indf,realargs),_) ->
let indf' = if dolift then lift_inductive_family n indf else indf in
let ((ind,u),_) = dest_ind_family indf' in
@@ -1855,13 +1849,13 @@ let extract_arity_signature ?(dolift=true) env0 tomatchl tmsign =
match t with
| Some (loc,ind',realnal) ->
if not (eq_ind ind ind') then
- user_err_loc (loc,"",str "Wrong inductive type.");
+ user_err ~loc (str "Wrong inductive type.");
if not (Int.equal nrealargs_ctxt (List.length realnal)) then
anomaly (Pp.str "Ill-formed 'in' clause in cases");
List.rev realnal
| None -> List.make nrealargs_ctxt Anonymous in
LocalAssum (na, build_dependent_inductive env0 indf')
- ::(List.map2 set_name realnal arsign) in
+ ::(List.map2 RelDecl.set_name realnal arsign) in
let rec buildrec n = function
| [],[] -> []
| (_,tm)::ltm, (_,x)::tmsign ->
@@ -1881,7 +1875,7 @@ let inh_conv_coerce_to_tycon loc env evdref j tycon =
(* We put the tycon inside the arity signature, possibly discovering dependencies. *)
let prepare_predicate_from_arsign_tycon env sigma loc tomatchs arsign c =
- let nar = List.fold_left (fun n sign -> List.length sign + n) 0 arsign in
+ let nar = List.fold_left (fun n sign -> Context.Rel.nhyps sign + n) 0 arsign in
let subst, len =
List.fold_right2 (fun (tm, tmtype) sign (subst, len) ->
let signlen = List.length sign in
@@ -1942,14 +1936,22 @@ let prepare_predicate_from_arsign_tycon env sigma loc tomatchs arsign c =
*)
let prepare_predicate loc typing_fun env sigma tomatchs arsign tycon pred =
+ let refresh_tycon sigma t =
+ (** If we put the typing constraint in the term, it has to be
+ refreshed to preserve the invariant that no algebraic universe
+ can appear in the term. *)
+ refresh_universes ~status:Evd.univ_flexible ~onlyalg:true (Some true)
+ env sigma t
+ in
let preds =
match pred, tycon with
- (* No type annotation *)
+ (* No return clause *)
| None, Some t when not (noccur_with_meta 0 max_int t) ->
(* If the tycon is not closed w.r.t real variables, we try *)
(* two different strategies *)
- (* First strategy: we abstract the tycon wrt to the dependencies *)
- let p1 =
+ (* First strategy: we abstract the tycon wrt to the dependencies *)
+ let sigma, t = refresh_tycon sigma t in
+ let p1 =
prepare_predicate_from_arsign_tycon env sigma loc tomatchs arsign t in
(* Second strategy: we build an "inversion" predicate *)
let sigma2,pred2 = build_inversion_problem loc env sigma tomatchs t in
@@ -1960,7 +1962,7 @@ let prepare_predicate loc typing_fun env sigma tomatchs arsign tycon pred =
(* No dependent type constraint, or no constraints at all: *)
(* we use two strategies *)
let sigma,t = match tycon with
- | Some t -> sigma,t
+ | Some t -> refresh_tycon sigma t
| None ->
let sigma = Sigma.Unsafe.of_evar_map sigma in
let Sigma ((t, _), sigma, _) =
@@ -1981,12 +1983,6 @@ let prepare_predicate loc typing_fun env sigma tomatchs arsign tycon pred =
let evdref = ref sigma in
let predcclj = typing_fun (mk_tycon (mkSort newt)) envar evdref rtntyp in
let sigma = !evdref in
- (* let sigma = Option.cata (fun tycon -> *)
- (* let na = Name (Id.of_string "x") in *)
- (* let tms = List.map (fun tm -> Pushed(tm,[],na)) tomatchs in *)
- (* let predinst = extract_predicate predcclj.uj_val tms in *)
- (* Coercion.inh_conv_coerce_to loc env !evdref predinst tycon) *)
- (* !evdref tycon in *)
let predccl = (j_nf_evar sigma predcclj).uj_val in
[sigma, predccl]
in
@@ -2032,7 +2028,9 @@ let mk_JMeq evdref typ x typ' y =
let mk_JMeq_refl evdref typ x =
papp evdref coq_JMeq_refl [| typ; x |]
-let hole = GHole (Loc.ghost, Evar_kinds.QuestionMark (Evar_kinds.Define true), Misctypes.IntroAnonymous, None)
+let hole =
+ GHole (Loc.ghost, Evar_kinds.QuestionMark (Evar_kinds.Define false),
+ Misctypes.IntroAnonymous, None)
let constr_of_pat env evdref arsign pat avoid =
let rec typ env (ty, realargs) pat avoid =
@@ -2050,11 +2048,11 @@ let constr_of_pat env evdref arsign pat avoid =
let cind = inductive_of_constructor cstr in
let IndType (indf, _) =
try find_rectype env ( !evdref) (lift (-(List.length realargs)) ty)
- with Not_found -> error_case_not_inductive env
+ with Not_found -> error_case_not_inductive env !evdref
{uj_val = ty; uj_type = Typing.unsafe_type_of env !evdref ty}
in
let (ind,u), params = dest_ind_family indf in
- if not (eq_ind ind cind) then error_bad_constructor_loc l env cstr ind;
+ if not (eq_ind ind cind) then error_bad_constructor ~loc:l env cstr ind;
let cstrs = get_constructors env indf in
let ci = cstrs.(i-1) in
let nb_args_constr = ci.cs_nargs in
@@ -2062,7 +2060,7 @@ let constr_of_pat env evdref arsign pat avoid =
let patargs, args, sign, env, n, m, avoid =
List.fold_right2
(fun decl ua (patargs, args, sign, env, n, m, avoid) ->
- let t = get_type decl in
+ let t = RelDecl.get_type decl in
let pat', sign', arg', typ', argtypargs, n', avoid =
let liftt = liftn (List.length sign) (succ (List.length args)) t in
typ env (substl args liftt, []) ua avoid
@@ -2102,8 +2100,8 @@ let constr_of_pat env evdref arsign pat avoid =
(* Mark the equality as a hole *)
pat', sign, lift i app, lift i apptype, realargs, n + i, avoid
in
- let pat', sign, patc, patty, args, z, avoid = typ env (get_type (List.hd arsign), List.tl arsign) pat avoid in
- pat', (sign, patc, (get_type (List.hd arsign), args), pat'), avoid
+ let pat', sign, patc, patty, args, z, avoid = typ env (RelDecl.get_type (List.hd arsign), List.tl arsign) pat avoid in
+ pat', (sign, patc, (RelDecl.get_type (List.hd arsign), args), pat'), avoid
(* shadows functional version *)
@@ -2134,7 +2132,7 @@ let vars_of_ctx ctx =
(GRef (Loc.ghost, delayed_force coq_eq_refl_ref, None)),
[hole; GVar (Loc.ghost, prev)])) :: vars
| _ ->
- match get_name decl with
+ match RelDecl.get_name decl with
Anonymous -> invalid_arg "vars_of_ctx"
| Name n -> n, GVar (Loc.ghost, n) :: vars)
ctx (Id.of_string "vars_of_ctx_error", [])
@@ -2311,7 +2309,7 @@ let abstract_tomatch env tomatchs tycon =
let build_dependent_signature env evdref avoid tomatchs arsign =
let avoid = ref avoid in
let arsign = List.rev arsign in
- let allnames = List.rev_map (List.map get_name) arsign in
+ let allnames = List.rev_map (List.map RelDecl.get_name) arsign in
let nar = List.fold_left (fun n names -> List.length names + n) 0 allnames in
let eqs, neqs, refls, slift, arsign' =
List.fold_left2
@@ -2328,14 +2326,14 @@ let build_dependent_signature env evdref avoid tomatchs arsign =
as much as possible *)
let argsign = List.tl arsign in (* arguments in inverse application order *)
let app_decl = List.hd arsign in (* The matched argument *)
- let appn = get_name app_decl in
- let appt = get_type app_decl in
+ let appn = RelDecl.get_name app_decl in
+ let appt = RelDecl.get_type app_decl in
let argsign = List.rev argsign in (* arguments in application order *)
let env', nargeqs, argeqs, refl_args, slift, argsign' =
List.fold_left2
(fun (env, nargeqs, argeqs, refl_args, slift, argsign') arg decl ->
- let name = get_name decl in
- let t = get_type decl in
+ let name = RelDecl.get_name decl in
+ let t = RelDecl.get_type decl in
let argt = Retyping.get_type_of env !evdref arg in
let eq, refl_arg =
if Reductionops.is_conv env !evdref argt t then
@@ -2353,7 +2351,7 @@ let build_dependent_signature env evdref avoid tomatchs arsign =
let previd, id =
let name =
match kind_of_term arg with
- Rel n -> get_name (lookup_rel n env)
+ Rel n -> RelDecl.get_name (lookup_rel n env)
| _ -> name
in
make_prime avoid name
@@ -2362,7 +2360,7 @@ let build_dependent_signature env evdref avoid tomatchs arsign =
(LocalAssum (Name (eq_id avoid previd), eq)) :: argeqs,
refl_arg :: refl_args,
pred slift,
- set_name (Name id) decl :: argsign'))
+ RelDecl.set_name (Name id) decl :: argsign'))
(env, neqs, [], [], slift, []) args argsign
in
let eq = mk_JMeq evdref
@@ -2377,13 +2375,13 @@ let build_dependent_signature env evdref avoid tomatchs arsign =
succ nargeqs,
refl_eq :: refl_args,
pred slift,
- ((set_name (Name id) app_decl :: argsign') :: arsigns))
+ ((RelDecl.set_name (Name id) app_decl :: argsign') :: arsigns))
| _ -> (* Non dependent inductive or not inductive, just use a regular equality *)
let decl = match arsign with [x] -> x | _ -> assert(false) in
- let name = get_name decl in
+ let name = RelDecl.get_name decl in
let previd, id = make_prime avoid name in
- let arsign' = set_name (Name id) decl in
+ let arsign' = RelDecl.set_name (Name id) decl in
let tomatch_ty = type_of_tomatch ty in
let eq =
mk_eq evdref (lift nar tomatch_ty)
@@ -2434,7 +2432,7 @@ let compile_program_cases loc style (typing_function, evdref) tycon env
match tycon' with
| None -> let ev = mkExistential env evdref in ev, ev
| Some t ->
- let pred =
+ let pred =
match prepare_predicate_from_arsign_tycon env !evdref loc tomatchs sign t with
| Some (evd, pred) -> evdref := evd; pred
| None ->
@@ -2513,11 +2511,11 @@ let compile_program_cases loc style (typing_function, evdref) tycon env
(* Main entry of the matching compilation *)
let compile_cases loc style (typing_fun, evdref) tycon env (predopt, tomatchl, eqns) =
- if predopt == None && Flags.is_program_mode () then
- compile_program_cases loc style (typing_fun, evdref)
+ if predopt == None && Flags.is_program_mode () && Program.is_program_cases () then
+ compile_program_cases loc style (typing_fun, evdref)
tycon env (predopt, tomatchl, eqns)
else
-
+
(* We build the matrix of patterns and right-hand side *)
let matx = matx_of_eqns env eqns in
@@ -2579,6 +2577,9 @@ let compile_cases loc style (typing_fun, evdref) tycon env (predopt, tomatchl, e
typing_function = typing_fun } in
let j = compile pb in
+
+ (* We coerce to the tycon (if an elim predicate was provided) *)
+ let j = inh_conv_coerce_to_tycon loc env myevdref j tycon in
evdref := !myevdref;
j in
@@ -2589,6 +2590,4 @@ let compile_cases loc style (typing_fun, evdref) tycon env (predopt, tomatchl, e
(* We check for unused patterns *)
List.iter (check_unused_pattern env) matx;
- (* We coerce to the tycon (if an elim predicate was provided) *)
- inh_conv_coerce_to_tycon loc env evdref j tycon
-
+ j
diff --git a/pretyping/cases.mli b/pretyping/cases.mli
index d7fff8af4b..d8fad1687f 100644
--- a/pretyping/cases.mli
+++ b/pretyping/cases.mli
@@ -28,9 +28,9 @@ type pattern_matching_error =
exception PatternMatchingError of env * evar_map * pattern_matching_error
-val error_wrong_numarg_constructor_loc : Loc.t -> env -> constructor -> int -> 'a
+val error_wrong_numarg_constructor : ?loc:Loc.t -> env -> constructor -> int -> 'a
-val error_wrong_numarg_inductive_loc : Loc.t -> env -> inductive -> int -> 'a
+val error_wrong_numarg_inductive : ?loc:Loc.t -> env -> inductive -> int -> 'a
val irrefutable : env -> cases_pattern -> bool
@@ -114,11 +114,11 @@ val compile : 'a pattern_matching_problem -> Environ.unsafe_judgment
val prepare_predicate : Loc.t ->
(Evarutil.type_constraint ->
- Environ.env -> Evd.evar_map ref -> 'a -> Environ.unsafe_judgment) ->
+ Environ.env -> Evd.evar_map ref -> glob_constr -> Environ.unsafe_judgment) ->
Environ.env ->
Evd.evar_map ->
(Term.types * tomatch_type) list ->
Context.Rel.t list ->
Constr.constr option ->
- 'a option -> (Evd.evar_map * Names.name list * Term.constr) list
-
+ glob_constr option ->
+ (Evd.evar_map * Names.name list * Term.constr) list
diff --git a/pretyping/cbv.ml b/pretyping/cbv.ml
index afd86420e9..84bf849e76 100644
--- a/pretyping/cbv.ml
+++ b/pretyping/cbv.ml
@@ -10,7 +10,7 @@ open Util
open Names
open Term
open Vars
-open Closure
+open CClosure
open Esubst
(**** Call by value reduction ****)
@@ -156,7 +156,7 @@ let strip_appl head stack =
(* Tests if fixpoint reduction is possible. *)
let fixp_reducible flgs ((reci,i),_) stk =
- if red_set flgs fIOTA then
+ if red_set flgs fFIX then
match stk with
| APP(appl,_) ->
Array.length appl > reci.(i) &&
@@ -168,7 +168,7 @@ let fixp_reducible flgs ((reci,i),_) stk =
false
let cofixp_reducible flgs _ stk =
- if red_set flgs fIOTA then
+ if red_set flgs fCOFIX then
match stk with
| (CASE _ | APP(_,CASE _)) -> true
| _ -> false
@@ -296,19 +296,19 @@ and cbv_stack_value info env = function
(* constructor in a Case -> IOTA *)
| (CONSTR(((sp,n),u),[||]), APP(args,CASE(_,br,ci,env,stk)))
- when red_set (info_flags info) fIOTA ->
+ when red_set (info_flags info) fMATCH ->
let cargs =
Array.sub args ci.ci_npar (Array.length args - ci.ci_npar) in
cbv_stack_term info (stack_app cargs stk) env br.(n-1)
(* constructor of arity 0 in a Case -> IOTA *)
| (CONSTR(((_,n),u),[||]), CASE(_,br,_,env,stk))
- when red_set (info_flags info) fIOTA ->
+ when red_set (info_flags info) fMATCH ->
cbv_stack_term info stk env br.(n-1)
(* constructor in a Projection -> IOTA *)
| (CONSTR(((sp,n),u),[||]), APP(args,PROJ(p,pi,stk)))
- when red_set (info_flags info) fIOTA && Projection.unfolded p ->
+ when red_set (info_flags info) fMATCH && Projection.unfolded p ->
let arg = args.(pi.Declarations.proj_npars + pi.Declarations.proj_arg) in
cbv_stack_value info env (strip_appl arg stk)
diff --git a/pretyping/cbv.mli b/pretyping/cbv.mli
index de37d1fc5e..87a03abbd9 100644
--- a/pretyping/cbv.mli
+++ b/pretyping/cbv.mli
@@ -9,7 +9,7 @@
open Names
open Term
open Environ
-open Closure
+open CClosure
open Esubst
(***********************************************************************
diff --git a/pretyping/classops.ml b/pretyping/classops.ml
index 55220f44c0..30d100af9f 100644
--- a/pretyping/classops.ml
+++ b/pretyping/classops.ml
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Errors
+open CErrors
open Util
open Pp
open Flags
@@ -297,7 +297,7 @@ let lookup_path_to_sort_from env sigma s =
let get_coercion_constructor env coe =
let c, _ =
- Reductionops.whd_betadeltaiota_stack env Evd.empty coe.coe_value
+ Reductionops.whd_all_stack env Evd.empty coe.coe_value
in
match kind_of_term c with
| Construct (cstr,u) ->
@@ -387,7 +387,7 @@ let add_coercion_in_graph (ic,source,target) =
end;
let is_ambig = match !ambig_paths with [] -> false | _ -> true in
if is_ambig && is_verbose () then
- Feedback.msg_warning (message_ambig !ambig_paths)
+ Feedback.msg_info (message_ambig !ambig_paths)
type coercion = {
coercion_type : coe_typ;
@@ -538,7 +538,7 @@ let inheritance_graph () =
let coercion_of_reference r =
let ref = Nametab.global r in
if not (coercion_exists ref) then
- errorlabstrm "try_add_coercion"
+ user_err ~hdr:"try_add_coercion"
(Nametab.pr_global_env Id.Set.empty ref ++ str" is not a coercion.");
ref
diff --git a/pretyping/coercion.ml b/pretyping/coercion.ml
index 5c7adf1aa7..2b860ae9c5 100644
--- a/pretyping/coercion.ml
+++ b/pretyping/coercion.ml
@@ -14,7 +14,7 @@
Corbineau, Feb 2008 *)
(* Turned into an abstract compilation unit by Matthieu Sozeau, March 2006 *)
-open Errors
+open CErrors
open Util
open Names
open Term
@@ -63,7 +63,7 @@ let apply_coercion_args env evd check isproj argl funj =
{ uj_val = applist (j_val funj,argl);
uj_type = typ }
| h::restl -> (* On devrait pouvoir s'arranger pour qu'on n'ait pas a faire hnf_constr *)
- match kind_of_term (whd_betadeltaiota env evd typ) with
+ match kind_of_term (whd_all env evd typ) with
| Prod (_,c1,c2) ->
if check && not (e_cumul env evdref (Retyping.get_type_of env evd h) c1) then
raise NoCoercion;
@@ -90,8 +90,9 @@ let inh_pattern_coerce_to loc env pat ind1 ind2 =
open Program
-let make_existential loc ?(opaque = Evar_kinds.Define true) env evdref c =
- Evarutil.e_new_evar env evdref ~src:(loc, Evar_kinds.QuestionMark opaque) c
+let make_existential loc ?(opaque = not (get_proofs_transparency ())) env evdref c =
+ let src = (loc, Evar_kinds.QuestionMark (Evar_kinds.Define opaque)) in
+ Evarutil.e_new_evar env evdref ~src c
let app_opt env evdref f t =
whd_betaiota !evdref (app_opt f t)
@@ -115,7 +116,7 @@ let disc_subset x =
exception NoSubtacCoercion
-let hnf env evd c = whd_betadeltaiota env evd c
+let hnf env evd c = whd_all env evd c
let hnf_nodelta env evd c = whd_betaiota evd c
let lift_args n sign =
@@ -152,7 +153,6 @@ and coerce loc env evdref (x : Term.constr) (y : Term.constr)
and coerce' env x y : (Term.constr -> Term.constr) option =
let subco () = subset_coerce env evdref x y in
let dest_prod c =
- let open Context.Rel.Declaration in
match Reductionops.splay_prod_n env ( !evdref) 1 c with
| [LocalAssum (na,t) | LocalDef (na,_,t)], c -> (na,t), c
| _ -> raise NoSubtacCoercion
@@ -191,7 +191,7 @@ and coerce loc env evdref (x : Term.constr) (y : Term.constr)
let term = co x in
Typing.e_solve_evars env evdref term)
in
- if isEvar c || isEvar c' then
+ if isEvar c || isEvar c' || not (Program.is_program_generalized_coercion ()) then
(* Second-order unification needed. *)
raise NoSubtacCoercion;
aux [] typ typ' 0 (fun x -> x)
@@ -279,7 +279,7 @@ and coerce loc env evdref (x : Term.constr) (y : Term.constr)
let c1 = coerce_unify env a a' in
let c2 = coerce_unify env b b' in
match c1, c2 with
- None, None -> None
+ | None, None -> None
| _, _ ->
Some
(fun x ->
@@ -369,11 +369,11 @@ let apply_coercion env sigma p hj typ_cl =
(hj,typ_cl,sigma) p
in evd, j
with NoCoercion as e -> raise e
- | e when Errors.noncritical e -> anomaly (Pp.str "apply_coercion")
+ | e when CErrors.noncritical e -> anomaly (Pp.str "apply_coercion")
(* Try to coerce to a funclass; raise NoCoercion if not possible *)
let inh_app_fun_core env evd j =
- let t = whd_betadeltaiota env evd j.uj_type in
+ let t = whd_all env evd j.uj_type in
match kind_of_term t with
| Prod (_,_,_) -> (evd,j)
| Evar ev ->
@@ -411,10 +411,10 @@ let inh_tosort_force loc env evd j =
let j2 = on_judgment_type (whd_evar evd) j1 in
(evd,type_judgment env j2)
with Not_found | NoCoercion ->
- error_not_a_type_loc loc env evd j
+ error_not_a_type ~loc env evd j
let inh_coerce_to_sort loc env evd j =
- let typ = whd_betadeltaiota env evd j.uj_type in
+ let typ = whd_all env evd j.uj_type in
match kind_of_term typ with
| Sort s -> (evd,{ utj_val = j.uj_val; utj_type = s })
| Evar ev when not (is_defined evd (fst ev)) ->
@@ -466,8 +466,8 @@ let rec inh_conv_coerce_to_fail loc env evd rigidonly v t c1 =
try inh_coerce_to_fail env evd rigidonly v t c1
with NoCoercion ->
match
- kind_of_term (whd_betadeltaiota env evd t),
- kind_of_term (whd_betadeltaiota env evd c1)
+ kind_of_term (whd_all env evd t),
+ kind_of_term (whd_all env evd c1)
with
| Prod (name,t1,t2), Prod (_,u1,u2) ->
(* Conversion did not work, we may succeed with a coercion. *)
@@ -505,16 +505,16 @@ let inh_conv_coerce_to_gen resolve_tc rigidonly loc env evd cj t =
else raise NoSubtacCoercion
with
| NoSubtacCoercion when not resolve_tc || not !use_typeclasses_for_conversion ->
- error_actual_type_loc loc env best_failed_evd cj t e
+ error_actual_type ~loc env best_failed_evd cj t e
| NoSubtacCoercion ->
let evd' = saturate_evd env evd in
try
if evd' == evd then
- error_actual_type_loc loc env best_failed_evd cj t e
+ error_actual_type ~loc env best_failed_evd cj t e
else
inh_conv_coerce_to_fail loc env evd' rigidonly (Some cj.uj_val) cj.uj_type t
- with NoCoercionNoUnifier (best_failed_evd,e) ->
- error_actual_type_loc loc env best_failed_evd cj t e
+ with NoCoercionNoUnifier (_evd,_error) ->
+ error_actual_type ~loc env best_failed_evd cj t e
in
let val' = match val' with Some v -> v | None -> assert(false) in
(evd',{ uj_val = val'; uj_type = t })
diff --git a/pretyping/constr_matching.ml b/pretyping/constr_matching.ml
index 129725c6d2..5ec44a68d8 100644
--- a/pretyping/constr_matching.ml
+++ b/pretyping/constr_matching.ml
@@ -8,7 +8,7 @@
(*i*)
open Pp
-open Errors
+open CErrors
open Util
open Names
open Globnames
@@ -45,16 +45,17 @@ open Context.Rel.Declaration
*)
+type binding_bound_vars = Id.Set.t
type bound_ident_map = Id.t Id.Map.t
exception PatternMatchingFailure
-let warn_bound_meta name =
- Feedback.msg_warning (str "Collision between bound variable " ++ pr_id name ++
- str " and a metavariable of same name.")
+let warn_meta_collision =
+ CWarnings.create ~name:"meta-collision" ~category:"ltac"
+ (fun name ->
+ strbrk "Collision between bound variable " ++ pr_id name ++
+ strbrk " and a metavariable of same name.")
-let warn_bound_bound name =
- Feedback.msg_warning (str "Collision between bound variables of name " ++ pr_id name)
let constrain n (ids, m as x) (names, terms as subst) =
try
@@ -62,18 +63,19 @@ let constrain n (ids, m as x) (names, terms as subst) =
if List.equal Id.equal ids ids' && eq_constr m m' then subst
else raise PatternMatchingFailure
with Not_found ->
- let () = if Id.Map.mem n names then warn_bound_meta n in
+ let () = if Id.Map.mem n names then warn_meta_collision n in
(names, Id.Map.add n x terms)
let add_binders na1 na2 binding_vars (names, terms as subst) =
match na1, na2 with
| Name id1, Name id2 when Id.Set.mem id1 binding_vars ->
if Id.Map.mem id1 names then
- let () = warn_bound_bound id1 in
+ let () = Glob_ops.warn_variable_collision id1 in
(names, terms)
else
let names = Id.Map.add id1 id2 names in
- let () = if Id.Map.mem id1 terms then warn_bound_meta id1 in
+ let () = if Id.Map.mem id1 terms then
+ warn_meta_collision id1 in
(names, terms)
| _ -> subst
diff --git a/pretyping/constr_matching.mli b/pretyping/constr_matching.mli
index 8d8166f22f..ee6c5141b0 100644
--- a/pretyping/constr_matching.mli
+++ b/pretyping/constr_matching.mli
@@ -13,6 +13,8 @@ open Term
open Environ
open Pattern
+type binding_bound_vars = Id.Set.t
+
(** [PatternMatchingFailure] is the exception raised when pattern
matching fails *)
exception PatternMatchingFailure
@@ -41,7 +43,7 @@ val matches_head : env -> Evd.evar_map -> constr_pattern -> constr -> patvar_map
variables or metavariables have the same name, the metavariable,
or else the rightmost bound variable, takes precedence *)
val extended_matches :
- env -> Evd.evar_map -> Tacexpr.binding_bound_vars * constr_pattern ->
+ env -> Evd.evar_map -> binding_bound_vars * constr_pattern ->
constr -> bound_ident_map * extended_patvar_map
(** [is_matching pat c] just tells if [c] matches against [pat] *)
@@ -75,7 +77,7 @@ val match_appsubterm : env -> Evd.evar_map -> constr_pattern -> constr -> matchi
(** [match_subterm_gen] calls either [match_subterm] or [match_appsubterm] *)
val match_subterm_gen : env -> Evd.evar_map ->
bool (** true = with app context *) ->
- Tacexpr.binding_bound_vars * constr_pattern -> constr ->
+ binding_bound_vars * constr_pattern -> constr ->
matching_result IStream.t
(** [is_matching_appsubterm pat c] tells if a subterm of [c] matches
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index 86921c49b0..cad5551c15 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -7,7 +7,7 @@
(************************************************************************)
open Pp
-open Errors
+open CErrors
open Util
open Names
open Term
@@ -67,15 +67,15 @@ let isomorphic_to_tuple lc = Int.equal (Array.length lc) 1
let encode_bool r =
let (x,lc) = encode_inductive r in
if not (has_two_constructors lc) then
- user_err_loc (loc_of_reference r,"encode_if",
- str "This type has not exactly two constructors.");
+ user_err ~loc:(loc_of_reference r) ~hdr:"encode_if"
+ (str "This type has not exactly two constructors.");
x
let encode_tuple r =
let (x,lc) = encode_inductive r in
if not (isomorphic_to_tuple lc) then
- user_err_loc (loc_of_reference r,"encode_tuple",
- str "This type cannot be seen as a tuple type.");
+ user_err ~loc:(loc_of_reference r) ~hdr:"encode_tuple"
+ (str "This type cannot be seen as a tuple type.");
x
module PrintingInductiveMake =
@@ -323,7 +323,7 @@ let is_nondep_branch c l =
(* FIXME: do better using tags from l *)
let sign,ccl = decompose_lam_n_decls (List.length l) c in
noccur_between 1 (Context.Rel.length sign) ccl
- with e when Errors.noncritical e -> (* Not eta-expanded or not reduced *)
+ with e when CErrors.noncritical e -> (* Not eta-expanded or not reduced *)
false
let extract_nondep_branches test c b l =
@@ -620,7 +620,7 @@ and share_names flags n l avoid env sigma c t =
share_names flags (n-1) ((Name id,Explicit,None,t'')::l) avoid env sigma appc c'
(* If built with the f/n notation: we renounce to share names *)
| _ ->
- if n>0 then Feedback.msg_warning (strbrk "Detyping.detype: cannot factorize fix enough");
+ if n>0 then Feedback.msg_debug (strbrk "Detyping.detype: cannot factorize fix enough");
let c = detype flags avoid env sigma c in
let t = detype flags avoid env sigma t in
(List.rev l,c,t)
@@ -631,7 +631,7 @@ and detype_eqns flags avoid env sigma ci computable constructs consnargsl bl =
let mat = build_tree Anonymous (snd flags) (avoid,env) ci bl in
List.map (fun (pat,((avoid,env),c)) -> (dl,[],[pat],detype flags avoid env sigma c))
mat
- with e when Errors.noncritical e ->
+ with e when CErrors.noncritical e ->
Array.to_list
(Array.map3 (detype_eqn flags avoid env sigma) constructs consnargsl bl)
@@ -689,7 +689,7 @@ and detype_binder (lax,isgoal as flags) bk avoid env sigma na body ty c =
| BLetIn ->
let c = detype (lax,false) avoid env sigma (Option.get body) in
(* Heuristic: we display the type if in Prop *)
- let s = Retyping.get_sort_family_of (snd env) sigma ty in
+ let s = try Retyping.get_sort_family_of (snd env) sigma ty with _ when !Flags.in_debugger || !Flags.in_toplevel -> InType (* Can fail because of sigma missing in debugger *) in
let c = if s != InProp then c else
GCast (dl, c, CastConv (detype (lax,false) avoid env sigma ty)) in
GLetIn (dl, na', c, r)
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index 89cb723bc7..a2ffe12e93 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -6,12 +6,12 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Errors
+open CErrors
open Util
open Names
open Term
open Vars
-open Closure
+open CClosure
open Reduction
open Reductionops
open Termops
@@ -24,7 +24,10 @@ open Globnames
open Evd
open Pretype_errors
open Sigma.Notations
-open Context.Rel.Declaration
+open Context.Named.Declaration
+
+module RelDecl = Context.Rel.Declaration
+module NamedDecl = Context.Named.Declaration
type unify_fun = transparent_state ->
env -> evar_map -> conv_pb -> constr -> constr -> Evarsolve.unification_result
@@ -42,12 +45,7 @@ let _ = Goptions.declare_bool_option {
let unfold_projection env evd ts p c =
let cst = Projection.constant p in
if is_transparent_constant ts cst then
- let c' = Some (mkProj (Projection.make cst true, c)) in
- match ReductionBehaviour.get (Globnames.ConstRef cst) with
- | None -> c'
- | Some (recargs, nargs, flags) ->
- if (List.mem `ReductionNeverUnfold flags) then None
- else c'
+ Some (mkProj (Projection.make cst true, c))
else None
let eval_flexible_term ts env evd c =
@@ -58,14 +56,13 @@ let eval_flexible_term ts env evd c =
else None
| Rel n ->
(try match lookup_rel n env with
- | LocalAssum _ -> None
- | LocalDef (_,v,_) -> Some (lift n v)
+ | RelDecl.LocalAssum _ -> None
+ | RelDecl.LocalDef (_,v,_) -> Some (lift n v)
with Not_found -> None)
| Var id ->
(try
if is_transparent_variable ts id then
- let open Context.Named.Declaration in
- lookup_named id env |> get_value
+ env |> lookup_named id |> NamedDecl.get_value
else None
with Not_found -> None)
| LetIn (_,b,_,c) -> Some (subst1 b c)
@@ -102,21 +99,20 @@ let position_problem l2r = function
| CONV -> None
| CUMUL -> Some l2r
-let occur_rigidly ev evd t =
- let (l, app) = decompose_app_vect t in
- let rec aux t =
+let occur_rigidly (evk,_ as ev) evd t =
+ let rec aux t =
match kind_of_term (whd_evar evd t) with
| App (f, c) -> if aux f then Array.exists aux c else false
| Construct _ | Ind _ | Sort _ | Meta _ | Fix _ | CoFix _ -> true
| Proj (p, c) -> not (aux c)
- | Evar (ev',_) -> if Evar.equal ev ev' then raise Occur else false
+ | Evar (evk',_) -> if Evar.equal evk evk' then raise Occur else false
| Cast (p, _, _) -> aux p
| Lambda _ | LetIn _ -> false
| Const _ -> false
| Prod (_, b, t) -> ignore(aux b || aux t); true
| Rel _ | Var _ -> false
- | Case _ -> false
- in Array.exists (fun t -> try ignore(aux t); false with Occur -> true) app
+ | Case (_,_,c,_) -> if eq_constr (mkEvar ev) c then raise Occur else false
+ in try ignore(aux t); false with Occur -> true
(* [check_conv_record env sigma (t1,stack1) (t2,stack2)] tries to decompose
the problem (t1 stack1) = (t2 stack2) into a problem
@@ -315,7 +311,7 @@ let exact_ise_stack2 env evd f sk1 sk2 =
if Reductionops.Stack.compare_shape sk1 sk2 then
ise_stack2 evd (List.rev sk1) (List.rev sk2)
else UnifFailure (evd, (* Dummy *) NotSameHead)
-
+
let rec evar_conv_x ts env evd pbty term1 term2 =
let term1 = whd_head_evar evd term1 in
let term2 = whd_head_evar evd term2 in
@@ -368,8 +364,6 @@ let rec evar_conv_x ts env evd pbty term1 term2 =
and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
((term1,sk1 as appr1),csts1) ((term2,sk2 as appr2),csts2) =
- let default_fail i = (* costly *)
- UnifFailure (i,ConversionFailed (env, Stack.zip appr1, Stack.zip appr2)) in
let quick_fail i = (* not costly, loses info *)
UnifFailure (i, NotSameHead)
in
@@ -397,7 +391,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
assert (match sk with [] -> true | _ -> false);
let (na,c1,c'1) = destLambda term in
let c = nf_evar evd c1 in
- let env' = push_rel (LocalAssum (na,c)) env in
+ let env' = push_rel (RelDecl.LocalAssum (na,c)) env in
let out1 = whd_betaiota_deltazeta_for_iota_state
(fst ts) env' evd Cst_stack.empty (c'1, Stack.empty) in
let out2 = whd_nored_state evd
@@ -407,21 +401,23 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
else evar_eqappr_x ts env' evd CONV out2 out1
in
let rigids env evd sk term sk' term' =
- let b,univs = Universes.eq_constr_universes term term' in
- if b then
+ let univs = Universes.eq_constr_universes term term' in
+ match univs with
+ | Some univs ->
ise_and evd [(fun i ->
let cstrs = Universes.to_constraints (Evd.universes i) univs in
try Success (Evd.add_constraints i cstrs)
with Univ.UniverseInconsistency p -> UnifFailure (i, UnifUnivInconsistency p));
(fun i -> exact_ise_stack2 env i (evar_conv_x ts) sk sk')]
- else UnifFailure (evd,NotSameHead)
+ | None ->
+ UnifFailure (evd,NotSameHead)
in
let flex_maybeflex on_left ev ((termF,skF as apprF),cstsF) ((termM, skM as apprM),cstsM) vM =
let switch f a b = if on_left then f a b else f b a in
let not_only_app = Stack.not_purely_applicative skM in
let f1 i =
match Stack.list_of_app_stack skF with
- | None -> default_fail evd
+ | None -> quick_fail evd
| Some lF ->
let tM = Stack.zip apprM in
miller_pfenning on_left
@@ -435,7 +431,8 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
else quick_fail i
and delta i =
switch (evar_eqappr_x ts env i pbty) (apprF,cstsF)
- (whd_betaiota_deltazeta_for_iota_state (fst ts) env i cstsM (vM,skM))
+ (whd_betaiota_deltazeta_for_iota_state
+ (fst ts) env i cstsM (vM,skM))
in
let default i = ise_try i [f1; consume apprF apprM; delta]
in
@@ -452,7 +449,8 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
try
let termM' = Retyping.expand_projection env evd p c [] in
let apprM', cstsM' =
- whd_betaiota_deltazeta_for_iota_state (fst ts) env evd cstsM (termM',skM)
+ whd_betaiota_deltazeta_for_iota_state
+ (fst ts) env evd cstsM (termM',skM)
in
let delta' i =
switch (evar_eqappr_x ts env i pbty) (apprF,cstsF) (apprM',cstsM')
@@ -468,10 +466,11 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
let flex_rigid on_left ev (termF, skF as apprF) (termR, skR as apprR) =
let switch f a b = if on_left then f a b else f b a in
let eta evd =
- match kind_of_term termR with
- | Lambda _ -> eta env evd false skR termR skF termF
- | Construct u -> eta_constructor ts env evd skR u skF termF
- | _ -> UnifFailure (evd,NotSameHead)
+ match kind_of_term termR with
+ | Lambda _ when (* if ever problem is ill-typed: *) List.is_empty skR ->
+ eta env evd false skR termR skF termF
+ | Construct u -> eta_constructor ts env evd skR u skF termF
+ | _ -> UnifFailure (evd,NotSameHead)
in
match Stack.list_of_app_stack skF with
| None ->
@@ -483,7 +482,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
ise_try evd
[eta;(* Postpone the use of an heuristic *)
(fun i ->
- if not (occur_rigidly (fst ev) i tR) then
+ if not (occur_rigidly ev i tR) then
let i,tF =
if isRel tR || isVar tR then
(* Optimization so as to generate candidates *)
@@ -506,10 +505,13 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
match (flex_kind_of_term (fst ts) env evd term1 sk1,
flex_kind_of_term (fst ts) env evd term2 sk2) with
| Flexible (sp1,al1 as ev1), Flexible (sp2,al2 as ev2) ->
+ (* sk1[?ev1] =? sk2[?ev2] *)
let f1 i =
+ (* Try first-order unification *)
match ise_stack2 false env i (evar_conv_x ts) sk1 sk2 with
- |None, Success i' ->
- (* Evar can be defined in i' *)
+ | None, Success i' ->
+ (* We do have sk1[] = sk2[]: we now unify ?ev1 and ?ev2 *)
+ (* Note that ?ev1 and ?ev2, may have been instantiated in the meantime *)
let ev1' = whd_evar i' (mkEvar ev1) in
if isEvar ev1' then
solve_simple_eqn (evar_conv_x ts) env i'
@@ -517,7 +519,9 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
else
evar_eqappr_x ts env evd pbty
((ev1', sk1), csts1) ((term2, sk2), csts2)
- |Some (r,[]), Success i' ->
+ | Some (r,[]), Success i' ->
+ (* We have sk1'[] = sk2[] for some sk1' s.t. sk1[]=sk1'[r[]] *)
+ (* we now unify r[?ev1] and ?ev2 *)
let ev2' = whd_evar i' (mkEvar ev2) in
if isEvar ev2' then
solve_simple_eqn (evar_conv_x ts) env i'
@@ -525,16 +529,46 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
else
evar_eqappr_x ts env evd pbty
((ev2', sk1), csts1) ((term2, sk2), csts2)
-
- |Some ([],r), Success i' ->
+ | Some ([],r), Success i' ->
+ (* Symmetrically *)
+ (* We have sk1[] = sk2'[] for some sk2' s.t. sk2[]=sk2'[r[]] *)
+ (* we now unify ?ev1 and r[?ev2] *)
let ev1' = whd_evar i' (mkEvar ev1) in
if isEvar ev1' then
solve_simple_eqn (evar_conv_x ts) env i'
(position_problem true pbty,destEvar ev1',Stack.zip(term2,r))
else evar_eqappr_x ts env evd pbty
((ev1', sk1), csts1) ((term2, sk2), csts2)
- |_, (UnifFailure _ as x) -> x
- |Some _, _ -> UnifFailure (i,NotSameArgSize)
+ | None, (UnifFailure _ as x) ->
+ (* sk1 and sk2 have no common outer part *)
+ if Stack.not_purely_applicative sk2 then
+ (* Ad hoc compatibility with 8.4 which treated non-app as rigid *)
+ flex_rigid true ev1 appr1 appr2
+ else
+ if Stack.not_purely_applicative sk1 then
+ (* Ad hoc compatibility with 8.4 which treated non-app as rigid *)
+ flex_rigid false ev2 appr2 appr1
+ else
+ (* We could instead try Miller unification, then
+ postpone to see if other equations help, as in:
+ [Check fun a b : unit => (eqáµ£efl : _ a = _ a b)] *)
+ x
+ | Some _, Success _ ->
+ (* sk1 and sk2 have a common outer part *)
+ if Stack.not_purely_applicative sk2 then
+ (* Ad hoc compatibility with 8.4 which treated non-app as rigid *)
+ flex_rigid true ev1 appr1 appr2
+ else
+ if Stack.not_purely_applicative sk1 then
+ (* Ad hoc compatibility with 8.4 which treated non-app as rigid *)
+ flex_rigid false ev2 appr2 appr1
+ else
+ (* We could instead try Miller unification, then
+ postpone to see if other equations help, as in:
+ [Check fun a b c : unit => (eqáµ£efl : _ a b = _ c a b)] *)
+ UnifFailure (i,NotSameArgSize)
+ | _, _ -> anomaly (Pp.str "Unexpected result from ise_stack2.")
+
and f2 i =
if Evar.equal sp1 sp2 then
match ise_stack2 false env i (evar_conv_x ts) sk1 sk2 with
@@ -557,14 +591,17 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
| MaybeFlexible v1, MaybeFlexible v2 -> begin
match kind_of_term term1, kind_of_term term2 with
| LetIn (na1,b1,t1,c'1), LetIn (na2,b2,t2,c'2) ->
- let f1 i =
+ let f1 i = (* FO *)
ise_and i
- [(fun i -> evar_conv_x ts env i CONV b1 b2);
+ [(fun i -> ise_try i
+ [(fun i -> evar_conv_x ts env i CUMUL t1 t2);
+ (fun i -> evar_conv_x ts env i CUMUL t2 t1)]);
+ (fun i -> evar_conv_x ts env i CONV b1 b2);
(fun i ->
let b = nf_evar i b1 in
let t = nf_evar i t1 in
let na = Nameops.name_max na1 na2 in
- evar_conv_x ts (push_rel (LocalDef (na,b,t)) env) i pbty c'1 c'2);
+ evar_conv_x ts (push_rel (RelDecl.LocalDef (na,b,t)) env) i pbty c'1 c'2);
(fun i -> exact_ise_stack2 env i (evar_conv_x ts) sk1 sk2)]
and f2 i =
let out1 = whd_betaiota_deltazeta_for_iota_state (fst ts) env i csts1 (v1,sk1)
@@ -615,14 +652,16 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
allow this identification (first-order unification of universes). Otherwise
fallback to unfolding.
*)
- let b,univs = Universes.eq_constr_universes term1 term2 in
- if b then
+ let univs = Universes.eq_constr_universes term1 term2 in
+ match univs with
+ | Some univs ->
ise_and i [(fun i ->
try Success (Evd.add_universe_constraints i univs)
with UniversesDiffer -> UnifFailure (i,NotSameHead)
| Univ.UniverseInconsistency p -> UnifFailure (i, UnifUnivInconsistency p));
(fun i -> exact_ise_stack2 env i (evar_conv_x ts) sk1 sk2)]
- else UnifFailure (i,NotSameHead)
+ | None ->
+ UnifFailure (i,NotSameHead)
and f2 i =
(try
if not (snd ts) then raise Not_found
@@ -679,7 +718,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
(fun i ->
let c = nf_evar i c1 in
let na = Nameops.name_max na1 na2 in
- evar_conv_x ts (push_rel (LocalAssum (na,c)) env) i CONV c'1 c'2)]
+ evar_conv_x ts (push_rel (RelDecl.LocalAssum (na,c)) env) i CONV c'1 c'2)]
| Flexible ev1, Rigid -> flex_rigid true ev1 appr1 appr2
| Rigid, Flexible ev2 -> flex_rigid false ev2 appr2 appr1
@@ -712,10 +751,10 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
ise_try evd [f3; f4]
(* Eta-expansion *)
- | Rigid, _ when isLambda term1 ->
+ | Rigid, _ when isLambda term1 && (* if ever ill-typed: *) List.is_empty sk1 ->
eta env evd true sk1 term1 sk2 term2
- | _, Rigid when isLambda term2 ->
+ | _, Rigid when isLambda term2 && (* if ever ill-typed: *) List.is_empty sk2 ->
eta env evd false sk2 term2 sk1 term1
| Rigid, Rigid -> begin
@@ -730,7 +769,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
in Success evd'
with Univ.UniverseInconsistency p ->
UnifFailure (evd,UnifUnivInconsistency p)
- | e when Errors.noncritical e -> UnifFailure (evd,NotSameHead))
+ | e when CErrors.noncritical e -> UnifFailure (evd,NotSameHead))
| Prod (n1,c1,c'1), Prod (n2,c2,c'2) when app_empty ->
ise_and evd
@@ -738,7 +777,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
(fun i ->
let c = nf_evar i c1 in
let na = Nameops.name_max n1 n2 in
- evar_conv_x ts (push_rel (LocalAssum (na,c)) env) i pbty c'1 c'2)]
+ evar_conv_x ts (push_rel (RelDecl.LocalAssum (na,c)) env) i pbty c'1 c'2)]
| Rel x1, Rel x2 ->
if Int.equal x1 x2 then
@@ -915,7 +954,6 @@ let choose_less_dependent_instance evk evd term args =
| [] -> None
| (id, _) :: _ -> Some (Evd.define evk (mkVar id) evd)
-open Context.Named.Declaration
let apply_on_subterm env evdref f c t =
let rec applyrec (env,(k,c) as acc) t =
(* By using eq_constr, we make an approximation, for instance, we *)
@@ -946,14 +984,16 @@ let filter_possible_projections c ty ctxt args =
List.map_i (fun i decl ->
let () = assert (i < len) in
let a = Array.unsafe_get args i in
- (match decl with LocalAssum _ -> false | LocalDef (_,c,_) -> not (isRel c || isVar c)) ||
+ (match decl with
+ | NamedDecl.LocalAssum _ -> false
+ | NamedDecl.LocalDef (_,c,_) -> not (isRel c || isVar c)) ||
a == c ||
(* Here we make an approximation, for instance, we could also be *)
(* interested in finding a term u convertible to c such that a occurs *)
(* in u *)
isRel a && Int.Set.mem (destRel a) fv1 ||
isVar a && Id.Set.mem (destVar a) fv2 ||
- Id.Set.mem (get_id decl) tyvars)
+ Id.Set.mem (NamedDecl.get_id decl) tyvars)
0 ctxt
let solve_evars = ref (fun _ -> failwith "solve_evars not installed")
@@ -984,10 +1024,10 @@ let second_order_matching ts env_rhs evd (evk,args) argoccs rhs =
let env_evar = evar_filtered_env evi in
let sign = named_context_val env_evar in
let ctxt = evar_filtered_context evi in
- let instance = List.map mkVar (List.map get_id ctxt) in
+ let instance = List.map mkVar (List.map NamedDecl.get_id ctxt) in
let rec make_subst = function
- | decl'::ctxt', c::l, occs::occsl when isVarId (get_id decl') c ->
+ | decl'::ctxt', c::l, occs::occsl when isVarId (NamedDecl.get_id decl') c ->
begin match occs with
| Some _ ->
error "Cannot force abstraction on identity instance."
@@ -995,7 +1035,8 @@ let second_order_matching ts env_rhs evd (evk,args) argoccs rhs =
make_subst (ctxt',l,occsl)
end
| decl'::ctxt', c::l, occs::occsl ->
- let (id,_,t) = to_tuple decl' in
+ let id = NamedDecl.get_id decl' in
+ let t = NamedDecl.get_type decl' in
let evs = ref [] in
let ty = Retyping.get_type_of env_rhs evd c in
let filter' = filter_possible_projections c ty ctxt args in
@@ -1048,7 +1089,7 @@ let second_order_matching ts env_rhs evd (evk,args) argoccs rhs =
match evar_conv_x ts env_evar evd CUMUL idty evty with
| UnifFailure _ -> error "Cannot find an instance"
| Success evd ->
- match reconsider_conv_pbs (evar_conv_x ts) evd with
+ match reconsider_unif_constraints (evar_conv_x ts) evd with
| UnifFailure _ -> error "Cannot find an instance"
| Success evd ->
evd
@@ -1071,7 +1112,7 @@ let second_order_matching ts env_rhs evd (evk,args) argoccs rhs =
abstract_free_holes evd subst, true
with TypingFailed evd -> evd, false
-let second_order_matching_with_args ts env evd ev l t =
+let second_order_matching_with_args ts env evd pbty ev l t =
(*
let evd,ev = evar_absorb_arguments env evd ev l in
let argoccs = Array.map_to_list (fun _ -> None) (snd ev) in
@@ -1079,8 +1120,9 @@ let second_order_matching_with_args ts env evd ev l t =
if b then Success evd
else UnifFailure (evd, ConversionFailed (env,mkApp(mkEvar ev,l),t))
if b then Success evd else
-*)
- UnifFailure (evd, ConversionFailed (env,mkApp(mkEvar ev,l),t))
+ *)
+ let pb = (pbty,env,mkApp(mkEvar ev,l),t) in
+ UnifFailure (evd, CannotSolveConstraint (pb,ProblemBeyondCapabilities))
let apply_conversion_problem_heuristic ts env evd pbty t1 t2 =
let t1 = apprec_nohdbeta ts env evd (whd_head_evar evd t1) in
@@ -1096,7 +1138,9 @@ let apply_conversion_problem_heuristic ts env evd pbty t1 t2 =
type inference *)
(match choose_less_dependent_instance evk1 evd term2 args1 with
| Some evd -> Success evd
- | None -> UnifFailure (evd, ConversionFailed (env,term1,term2)))
+ | None ->
+ let reason = ProblemBeyondCapabilities in
+ UnifFailure (evd, CannotSolveConstraint ((pbty,env,t1,t2),reason)))
| (Rel _|Var _), Evar (evk2,args2) when app_empty
&& List.for_all (fun a -> Term.eq_constr a term1 || isEvar a)
(remove_instance_local_defs evd evk2 args2) ->
@@ -1104,12 +1148,14 @@ let apply_conversion_problem_heuristic ts env evd pbty t1 t2 =
type inference *)
(match choose_less_dependent_instance evk2 evd term1 args2 with
| Some evd -> Success evd
- | None -> UnifFailure (evd, ConversionFailed (env,term1,term2)))
+ | None ->
+ let reason = ProblemBeyondCapabilities in
+ UnifFailure (evd, CannotSolveConstraint ((pbty,env,t1,t2),reason)))
| Evar (evk1,args1), Evar (evk2,args2) when Evar.equal evk1 evk2 ->
let f env evd pbty x y = is_fconv ~reds:ts pbty env evd x y in
Success (solve_refl ~can_drop:true f env evd
(position_problem true pbty) evk1 args1 args2)
- | Evar ev1, Evar ev2 ->
+ | Evar ev1, Evar ev2 when app_empty ->
Success (solve_evar_evar ~force:true
(evar_define (evar_conv_x ts) ~choose:true) (evar_conv_x ts) env evd
(position_problem true pbty) ev1 ev2)
@@ -1119,27 +1165,32 @@ let apply_conversion_problem_heuristic ts env evd pbty t1 t2 =
ise_try evd
[(fun evd -> first_order_unification ts env evd (ev1,l1) appr2);
(fun evd ->
- second_order_matching_with_args ts env evd ev1 l1 t2)]
+ second_order_matching_with_args ts env evd pbty ev1 l1 t2)]
| _,Evar ev2 when Array.length l2 <= Array.length l1 ->
(* On "u u1 .. u(n+p) = ?n t1 .. tn", try first-order unification *)
(* and otherwise second-order matching *)
ise_try evd
[(fun evd -> first_order_unification ts env evd (ev2,l2) appr1);
(fun evd ->
- second_order_matching_with_args ts env evd ev2 l2 t1)]
+ second_order_matching_with_args ts env evd pbty ev2 l2 t1)]
| Evar ev1,_ ->
(* Try second-order pattern-matching *)
- second_order_matching_with_args ts env evd ev1 l1 t2
+ second_order_matching_with_args ts env evd pbty ev1 l1 t2
| _,Evar ev2 ->
(* Try second-order pattern-matching *)
- second_order_matching_with_args ts env evd ev2 l2 t1
+ second_order_matching_with_args ts env evd pbty ev2 l2 t1
| _ ->
(* Some head evar have been instantiated, or unknown kind of problem *)
evar_conv_x ts env evd pbty t1 t2
+let error_cannot_unify env evd pb ?reason t1 t2 =
+ Pretype_errors.error_cannot_unify
+ ~loc:(loc_of_conv_pb evd pb) env
+ evd ?reason (t1, t2)
+
let check_problems_are_solved env evd =
match snd (extract_all_conv_pbs evd) with
- | (pbty,env,t1,t2)::_ -> Pretype_errors.error_cannot_unify env evd (t1, t2)
+ | (pbty,env,t1,t2) as pb::_ -> error_cannot_unify env evd pb t1 t2
| _ -> ()
let max_undefined_with_candidates evd =
@@ -1170,7 +1221,7 @@ let rec solve_unconstrained_evars_with_candidates ts evd =
let conv_algo = evar_conv_x ts in
let evd = check_evar_instance evd evk a conv_algo in
let evd = Evd.define evk a evd in
- match reconsider_conv_pbs conv_algo evd with
+ match reconsider_unif_constraints conv_algo evd with
| Success evd -> solve_unconstrained_evars_with_candidates ts evd
| UnifFailure _ -> aux l
with
@@ -1184,16 +1235,16 @@ let rec solve_unconstrained_evars_with_candidates ts evd =
let solve_unconstrained_impossible_cases env evd =
Evd.fold_undefined (fun evk ev_info evd' ->
match ev_info.evar_source with
- | _,Evar_kinds.ImpossibleCase ->
+ | loc,Evar_kinds.ImpossibleCase ->
let j, ctx = coq_unit_judge () in
- let evd' = Evd.merge_context_set Evd.univ_flexible_alg evd' ctx in
+ let evd' = Evd.merge_context_set Evd.univ_flexible_alg ~loc evd' ctx in
let ty = j_type j in
let conv_algo = evar_conv_x full_transparent_state in
let evd' = check_evar_instance evd' evk ty conv_algo in
Evd.define evk ty evd'
| _ -> evd') evd evd
-let consider_remaining_unif_problems env
+let solve_unif_constraints_with_heuristics env
?(ts=Conv_oracle.get_transp_state (Environ.oracle env)) evd =
let evd = solve_unconstrained_evars_with_candidates ts evd in
let rec aux evd pbs progress stuck =
@@ -1208,23 +1259,23 @@ let consider_remaining_unif_problems env
aux evd pbs progress (pb :: stuck)
end
| UnifFailure (evd,reason) ->
- Pretype_errors.error_cannot_unify_loc (loc_of_conv_pb evd pb)
- env evd ~reason (t1, t2))
+ error_cannot_unify env evd pb ~reason t1 t2)
| _ ->
if progress then aux evd stuck false []
else
match stuck with
| [] -> (* We're finished *) evd
| (pbty,env,t1,t2 as pb) :: _ ->
- (* There remains stuck problems *)
- Pretype_errors.error_cannot_unify_loc (loc_of_conv_pb evd pb)
- env evd (t1, t2)
+ (* There remains stuck problems *)
+ error_cannot_unify env evd pb t1 t2
in
let (evd,pbs) = extract_all_conv_pbs evd in
let heuristic_solved_evd = aux evd pbs false [] in
check_problems_are_solved env heuristic_solved_evd;
solve_unconstrained_impossible_cases env heuristic_solved_evd
+let consider_remaining_unif_problems = solve_unif_constraints_with_heuristics
+
(* Main entry points *)
exception UnableToUnify of evar_map * unification_error
diff --git a/pretyping/evarconv.mli b/pretyping/evarconv.mli
index 14947c8927..2231e5bc30 100644
--- a/pretyping/evarconv.mli
+++ b/pretyping/evarconv.mli
@@ -33,7 +33,10 @@ val e_cumul : env -> ?ts:transparent_state -> evar_map ref -> constr -> constr -
(** Try heuristics to solve pending unification problems and to solve
evars with candidates *)
+val solve_unif_constraints_with_heuristics : env -> ?ts:transparent_state -> evar_map -> evar_map
+
val consider_remaining_unif_problems : env -> ?ts:transparent_state -> evar_map -> evar_map
+(** @deprecated Alias for [solve_unif_constraints_with_heuristics] *)
(** Check all pending unification problems are solved and raise an
error otherwise *)
diff --git a/pretyping/evardefine.ml b/pretyping/evardefine.ml
index d349cf8216..06f619410c 100644
--- a/pretyping/evardefine.ml
+++ b/pretyping/evardefine.ml
@@ -19,21 +19,21 @@ open Evarutil
open Pretype_errors
open Sigma.Notations
+module RelDecl = Context.Rel.Declaration
+
let new_evar_unsafe env evd ?src ?filter ?candidates ?store ?naming ?principal typ =
let evd = Sigma.Unsafe.of_evar_map evd in
let Sigma (evk, evd, _) = new_evar env evd ?src ?filter ?candidates ?store ?naming ?principal typ in
(Sigma.to_evar_map evd, evk)
let env_nf_evar sigma env =
- let open Context.Rel.Declaration in
process_rel_context
- (fun d e -> push_rel (map_constr (nf_evar sigma) d) e) env
+ (fun d e -> push_rel (RelDecl.map_constr (nf_evar sigma) d) e) env
let env_nf_betaiotaevar sigma env =
- let open Context.Rel.Declaration in
process_rel_context
(fun d e ->
- push_rel (map_constr (Reductionops.nf_betaiota sigma) d) e) env
+ push_rel (RelDecl.map_constr (Reductionops.nf_betaiota sigma) d) e) env
(****************************************)
(* Operations on value/type constraints *)
@@ -78,7 +78,7 @@ let define_pure_evar_as_product evd evk =
let evi = Evd.find_undefined evd evk in
let evenv = evar_env evi in
let id = next_ident_away idx (ids_of_named_context (evar_context evi)) in
- let concl = Reductionops.whd_betadeltaiota evenv evd evi.evar_concl in
+ let concl = Reductionops.whd_all evenv evd evi.evar_concl in
let s = destSort concl in
let evd1,(dom,u1) =
let evd = Sigma.Unsafe.of_evar_map evd in
@@ -131,11 +131,11 @@ let define_pure_evar_as_lambda env evd evk =
let open Context.Named.Declaration in
let evi = Evd.find_undefined evd evk in
let evenv = evar_env evi in
- let typ = Reductionops.whd_betadeltaiota evenv evd (evar_concl evi) in
+ let typ = Reductionops.whd_all evenv evd (evar_concl evi) in
let evd1,(na,dom,rng) = match kind_of_term typ with
| Prod (na,dom,rng) -> (evd,(na,dom,rng))
| Evar ev' -> let evd,typ = define_evar_as_product evd ev' in evd,destProd typ
- | _ -> error_not_product_loc Loc.ghost env evd typ in
+ | _ -> error_not_product env evd typ in
let avoid = ids_of_named_context (evar_context evi) in
let id =
next_name_away_with_default_using_types "x" na avoid (Reductionops.whd_evar evd dom) in
@@ -169,7 +169,7 @@ let define_evar_as_sort env evd (ev,args) =
let evd, u = new_univ_variable univ_rigid evd in
let evi = Evd.find_undefined evd ev in
let s = Type u in
- let concl = Reductionops.whd_betadeltaiota (evar_env evi) evd evi.evar_concl in
+ let concl = Reductionops.whd_all (evar_env evi) evd evi.evar_concl in
let sort = destSort concl in
let evd' = Evd.define ev (mkSort s) evd in
Evd.set_leq_sort env evd' (Type (Univ.super u)) sort, s
@@ -181,17 +181,17 @@ let define_evar_as_sort env evd (ev,args) =
let split_tycon loc env evd tycon =
let rec real_split evd c =
- let t = Reductionops.whd_betadeltaiota env evd c in
+ let t = Reductionops.whd_all env evd c in
match kind_of_term t with
| Prod (na,dom,rng) -> evd, (na, dom, rng)
- | Evar ev (* ev is undefined because of whd_betadeltaiota *) ->
+ | Evar ev (* ev is undefined because of whd_all *) ->
let (evd',prod) = define_evar_as_product evd ev in
let (_,dom,rng) = destProd prod in
evd',(Anonymous, dom, rng)
| App (c,args) when isEvar c ->
let (evd',lam) = define_evar_as_lambda env evd (destEvar c) in
real_split evd' (mkApp (lam,args))
- | _ -> error_not_product_loc loc env evd c
+ | _ -> error_not_product ~loc env evd c
in
match tycon with
| None -> evd,(Anonymous,None,None)
diff --git a/pretyping/evarsolve.ml b/pretyping/evarsolve.ml
index 455a7dbd69..92662f07d9 100644
--- a/pretyping/evarsolve.ml
+++ b/pretyping/evarsolve.ml
@@ -7,7 +7,7 @@
(************************************************************************)
open Util
-open Errors
+open CErrors
open Names
open Term
open Vars
@@ -42,28 +42,39 @@ let get_polymorphic_positions f =
templ.template_param_levels)
| _ -> assert false
-let refresh_level evd s =
- match Evd.is_sort_variable evd s with
- | None -> true
- | Some l -> not (Evd.is_flexible_level evd l)
-
-let refresh_universes ?(status=univ_rigid) ?(onlyalg=false) pbty env evd t =
+let refresh_universes ?(status=univ_rigid) ?(onlyalg=false) ?(refreshset=false)
+ pbty env evd t =
let evdref = ref evd in
let modified = ref false in
- let rec refresh status dir t =
- match kind_of_term t with
- | Sort (Type u as s) when
- (match Univ.universe_level u with
- | None -> true
- | Some l -> not onlyalg && refresh_level evd s) ->
+ (* direction: true for fresh universes lower than the existing ones *)
+ let refresh_sort status ~direction s =
let s' = evd_comb0 (new_sort_variable status) evdref in
let evd =
- if dir then set_leq_sort env !evdref s' s
+ if direction then set_leq_sort env !evdref s' s
else set_leq_sort env !evdref s s'
in
- modified := true; evdref := evd; mkSort s'
+ modified := true; evdref := evd; mkSort s'
+ in
+ let rec refresh ~onlyalg status ~direction t =
+ match kind_of_term t with
+ | Sort (Type u as s) ->
+ (match Univ.universe_level u with
+ | None -> refresh_sort status ~direction s
+ | Some l ->
+ (match Evd.universe_rigidity evd l with
+ | UnivRigid ->
+ if not onlyalg then refresh_sort status ~direction s
+ else t
+ | UnivFlexible alg ->
+ if onlyalg && alg then
+ (evdref := Evd.make_flexible_variable !evdref false l; t)
+ else t))
+ | Sort (Prop Pos as s) when refreshset && not direction ->
+ (* Cannot make a universe "lower" than "Set",
+ only refreshing when we want higher universes. *)
+ refresh_sort status ~direction s
| Prod (na,u,v) ->
- mkProd (na,u,refresh status dir v)
+ mkProd (na, u, refresh ~onlyalg status ~direction v)
| _ -> t
(** Refresh the types of evars under template polymorphic references *)
and refresh_term_evars onevars top t =
@@ -76,7 +87,7 @@ let refresh_universes ?(status=univ_rigid) ?(onlyalg=false) pbty env evd t =
Array.iter (refresh_term_evars onevars false) args
| Evar (ev, a) when onevars ->
let evi = Evd.find !evdref ev in
- let ty' = refresh univ_flexible true evi.evar_concl in
+ let ty' = refresh ~onlyalg univ_flexible ~direction:true evi.evar_concl in
if !modified then
evdref := Evd.add !evdref ev {evi with evar_concl = ty'}
else ()
@@ -96,9 +107,11 @@ let refresh_universes ?(status=univ_rigid) ?(onlyalg=false) pbty env evd t =
in
let t' =
if isArity t then
- (match pbty with
- | None -> t
- | Some dir -> refresh status dir t)
+ match pbty with
+ | None ->
+ (* No cumulativity needed, but we still need to refresh the algebraics *)
+ refresh ~onlyalg:true univ_flexible ~direction:false t
+ | Some direction -> refresh ~onlyalg status ~direction t
else (refresh_term_evars false true t; t)
in
if !modified then !evdref, t' else !evdref, t
@@ -140,7 +153,7 @@ let recheck_applications conv_algo env evdref t =
let argsty = Array.map (fun x -> aux env x; Retyping.get_type_of env !evdref x) args in
let rec aux i ty =
if i < Array.length argsty then
- match kind_of_term (whd_betadeltaiota env !evdref ty) with
+ match kind_of_term (whd_all env !evdref ty) with
| Prod (na, dom, codom) ->
(match conv_algo env !evdref Reduction.CUMUL argsty.(i) dom with
| Success evd -> evdref := evd;
@@ -164,7 +177,7 @@ type 'a update =
| NoUpdate
open Context.Named.Declaration
-let inst_of_vars sign = Array.map_of_list (mkVar % get_id) sign
+let inst_of_vars sign = Array.map_of_list (get_id %> mkVar) sign
let restrict_evar_key evd evk filter candidates =
match filter, candidates with
@@ -212,30 +225,29 @@ let restrict_instance evd evk filter argsv =
open Context.Rel.Declaration
let noccur_evar env evd evk c =
let cache = ref Int.Set.empty (* cache for let-ins *) in
- let rec occur_rec (k, env as acc) c =
+ let rec occur_rec check_types (k, env as acc) c =
match kind_of_term c with
| Evar (evk',args' as ev') ->
(match safe_evar_value evd ev' with
- | Some c -> occur_rec acc c
+ | Some c -> occur_rec check_types acc c
| None ->
if Evar.equal evk evk' then raise Occur
- else Array.iter (occur_rec acc) args')
+ else (if check_types then
+ occur_rec false acc (existential_type evd ev');
+ Array.iter (occur_rec check_types acc) args'))
| Rel i when i > k ->
- if not (Int.Set.mem (i-k) !cache) then
- (match Environ.lookup_rel i env with
- | LocalAssum _ -> ()
- | LocalDef (_,b,_) -> cache := Int.Set.add (i-k) !cache; occur_rec acc (lift i b))
- | Proj (p,c) ->
- let c =
- try Retyping.expand_projection env evd p c []
- with Retyping.RetypeError _ ->
- (* Can happen when called from w_unify which doesn't assign evars/metas
- eagerly enough *) c
- in occur_rec acc c
+ if not (Int.Set.mem (i-k) !cache) then
+ let decl = Environ.lookup_rel i env in
+ if check_types then
+ (cache := Int.Set.add (i-k) !cache; occur_rec false acc (lift i (get_type decl)));
+ (match decl with
+ | LocalAssum _ -> ()
+ | LocalDef (_,b,_) -> cache := Int.Set.add (i-k) !cache; occur_rec false acc (lift i b))
+ | Proj (p,c) -> occur_rec true acc c
| _ -> iter_constr_with_full_binders (fun rd (k,env) -> (succ k, push_rel rd env))
- occur_rec acc c
+ (occur_rec check_types) acc c
in
- try occur_rec (0,env) c; true with Occur -> false
+ try occur_rec false (0,env) c; true with Occur -> false
(***************************************)
(* Managing chains of local definitons *)
@@ -520,7 +532,7 @@ let solve_pattern_eqn env l c =
l c in
(* Warning: we may miss some opportunity to eta-reduce more since c'
is not in normal form *)
- whd_eta c'
+ shrink_eta c'
(*****************************************)
(* Refining/solving unification problems *)
@@ -609,7 +621,13 @@ let define_evar_from_virtual_equation define_fun env evd src t_in_env ty_t_in_si
* substitution u1..uq.
*)
+exception MorePreciseOccurCheckNeeeded
+
let materialize_evar define_fun env evd k (evk1,args1) ty_in_env =
+ if Evd.is_defined evd evk1 then
+ (* Some circularity somewhere (see e.g. #3209) *)
+ raise MorePreciseOccurCheckNeeeded;
+ let (evk1,args1) = destEvar (whd_evar evd (mkEvar (evk1,args1))) in
let evi1 = Evd.find_undefined evd evk1 in
let env1,rel_sign = env_rel_context_chop k env in
let sign1 = evar_hyps evi1 in
@@ -628,13 +646,13 @@ let materialize_evar define_fun env evd k (evk1,args1) ty_in_env =
~status:univ_flexible (Some false) env evd (mkSort s) in
define_evar_from_virtual_equation define_fun env evd src t_in_env
ty_t_in_sign sign filter inst_in_env in
- let evd,b_in_sign = match d with
- | LocalAssum _ -> evd,None
+ let evd,d' = match d with
+ | LocalAssum _ -> evd, Context.Named.Declaration.LocalAssum (id,t_in_sign)
| LocalDef (_,b,_) ->
let evd,b = define_evar_from_virtual_equation define_fun env evd src b
t_in_sign sign filter inst_in_env in
- evd,Some b in
- (push_named_context_val (Context.Named.Declaration.of_tuple (id,b_in_sign,t_in_sign)) sign, Filter.extend 1 filter,
+ evd, Context.Named.Declaration.LocalDef (id,b,t_in_sign) in
+ (push_named_context_val d' sign, Filter.extend 1 filter,
(mkRel 1)::(List.map (lift 1) inst_in_env),
(mkRel 1)::(List.map (lift 1) inst_in_sign),
push_rel d env,evd,id::avoid))
@@ -797,7 +815,7 @@ let rec do_projection_effects define_fun env ty evd = function
let evd = Evd.define evk (mkVar id) evd in
(* TODO: simplify constraints involving evk *)
let evd = do_projection_effects define_fun env ty evd p in
- let ty = whd_betadeltaiota env evd (Lazy.force ty) in
+ let ty = whd_all env evd (Lazy.force ty) in
if not (isSort ty) then
(* Don't try to instantiate if a sort because if evar_concl is an
evar it may commit to a univ level which is not the right
@@ -1460,7 +1478,7 @@ let rec invert_definition conv_algo choose env evd pbty (evk,argsv as ev) rhs =
map_constr_with_full_binders (fun d (env,k) -> push_rel d env, k+1)
imitate envk t in
t::l
- with e when Errors.noncritical e -> l in
+ with e when CErrors.noncritical e -> l in
(match candidates with
| [x] -> x
| _ ->
@@ -1549,11 +1567,13 @@ and evar_define conv_algo ?(choose=false) env evd pbty (evk,argsv as ev) rhs =
postpone_non_unique_projection env evd pbty ev sols rhs
| NotEnoughInformationEvarEvar t ->
add_conv_oriented_pb (pbty,env,mkEvar ev,t) evd
+ | MorePreciseOccurCheckNeeeded ->
+ add_conv_oriented_pb (pbty,env,mkEvar ev,rhs) evd
| NotInvertibleUsingOurAlgorithm _ | MetaOccurInBodyInternal as e ->
raise e
| OccurCheckIn (evd,rhs) ->
(* last chance: rhs actually reduces to ev *)
- let c = whd_betadeltaiota env evd rhs in
+ let c = whd_all env evd rhs in
match kind_of_term c with
| Evar (evk',argsv2) when Evar.equal evk evk' ->
solve_refl (fun env sigma pb c c' -> is_fconv pb env sigma c c')
@@ -1591,7 +1611,7 @@ let status_changed lev (pbty,_,t1,t2) =
(try Evar.Set.mem (head_evar t1) lev with NoHeadEvar -> false) ||
(try Evar.Set.mem (head_evar t2) lev with NoHeadEvar -> false)
-let reconsider_conv_pbs conv_algo evd =
+let reconsider_unif_constraints conv_algo evd =
let (evd,pbs) = extract_changed_conv_pbs evd status_changed in
List.fold_left
(fun p (pbty,env,t1,t2 as x) ->
@@ -1604,6 +1624,8 @@ let reconsider_conv_pbs conv_algo evd =
(Success evd)
pbs
+let reconsider_conv_pbs = reconsider_unif_constraints
+
(* Tries to solve problem t1 = t2.
* Precondition: t1 is an uninstantiated evar
* Returns an optional list of evars that were instantiated, or None
@@ -1614,7 +1636,7 @@ let solve_simple_eqn conv_algo ?(choose=false) env evd (pbty,(evk1,args1 as ev1)
try
let t2 = whd_betaiota evd t2 in (* includes whd_evar *)
let evd = evar_define conv_algo ~choose env evd pbty ev1 t2 in
- reconsider_conv_pbs conv_algo evd
+ reconsider_unif_constraints conv_algo evd
with
| NotInvertibleUsingOurAlgorithm t ->
UnifFailure (evd,NotClean (ev1,env,t))
diff --git a/pretyping/evarsolve.mli b/pretyping/evarsolve.mli
index 918ba12f0f..b6bdc07889 100644
--- a/pretyping/evarsolve.mli
+++ b/pretyping/evarsolve.mli
@@ -34,8 +34,12 @@ type conv_fun_bool =
val evar_define : conv_fun -> ?choose:bool -> env -> evar_map ->
bool option -> existential -> constr -> evar_map
-val refresh_universes : ?status:Evd.rigid ->
- ?onlyalg:bool (* Only algebraic universes *) ->
+val refresh_universes :
+ ?status:Evd.rigid ->
+ ?onlyalg:bool (* Only algebraic universes *) ->
+ ?refreshset:bool ->
+ (* Also refresh Prop and Set universes, so that the returned type can be any supertype
+ of the original type *)
bool option (* direction: true for levels lower than the existing levels *) ->
env -> evar_map -> types -> evar_map * types
@@ -50,7 +54,10 @@ val solve_evar_evar : ?force:bool ->
val solve_simple_eqn : conv_fun -> ?choose:bool -> env -> evar_map ->
bool option * existential * constr -> unification_result
+val reconsider_unif_constraints : conv_fun -> evar_map -> unification_result
+
val reconsider_conv_pbs : conv_fun -> evar_map -> unification_result
+(** @deprecated Alias for [reconsider_unif_constraints] *)
val is_unification_pattern_evar : env -> evar_map -> existential -> constr list ->
constr -> constr list option
diff --git a/pretyping/find_subterm.ml b/pretyping/find_subterm.ml
index ae8b91c346..4b9cf415f0 100644
--- a/pretyping/find_subterm.ml
+++ b/pretyping/find_subterm.ml
@@ -8,7 +8,7 @@
open Pp
open Util
-open Errors
+open CErrors
open Names
open Locus
open Term
@@ -16,6 +16,8 @@ open Nameops
open Termops
open Pretype_errors
+module NamedDecl = Context.Named.Declaration
+
(** Processing occurrences *)
type occurrence_error =
@@ -35,7 +37,7 @@ let explain_occurrence_error = function
| IncorrectInValueOccurrence id -> explain_incorrect_in_value_occurrence id
let error_occurrences_error e =
- errorlabstrm "" (explain_occurrence_error e)
+ user_err (explain_occurrence_error e)
let error_invalid_occurrence occ =
error_occurrences_error (InvalidOccurrence occ)
@@ -61,7 +63,7 @@ let proceed_with_occurrences f occs x =
let map_named_declaration_with_hyploc f hyploc acc decl =
let open Context.Named.Declaration in
- let f = f (Some (get_id decl, hyploc)) in
+ let f = f (Some (NamedDecl.get_id decl, hyploc)) in
match decl,hyploc with
| LocalAssum (id,_), InHypValueOnly ->
error_occurrences_error (IncorrectInValueOccurrence id)
@@ -108,7 +110,6 @@ let replace_term_occ_gen_modulo occs like_first test bywhat cl occ t =
raise (SubtermUnificationError (!nested,((cl,!pos),t),lastpos,e)) in
let rec substrec k t =
if nowhere_except_in && !pos > maxocc then t else
- if not (Vars.closed0 t) then subst_below k t else
try
let subst = test.match_fun test.testing_state t in
if Locusops.is_selected !pos occs then
diff --git a/pretyping/glob_ops.ml b/pretyping/glob_ops.ml
index 04100c8a73..51660818f4 100644
--- a/pretyping/glob_ops.ml
+++ b/pretyping/glob_ops.ml
@@ -334,10 +334,14 @@ let glob_visible_short_qualid c =
fold_glob_constr aux acc c
in aux [] c
+let warn_variable_collision =
+ let open Pp in
+ CWarnings.create ~name:"variable-collision" ~category:"ltac"
+ (fun name ->
+ strbrk "Collision between bound variables of name " ++ pr_id name)
+
let add_and_check_ident id set =
- if Id.Set.mem id set then
- Feedback.msg_warning
- Pp.(str "Collision between bound variables of name " ++ Id.print id);
+ if Id.Set.mem id set then warn_variable_collision id;
Id.Set.add id set
let bound_glob_vars =
@@ -466,6 +470,78 @@ let loc_of_glob_constr = function
| GCast (loc,_,_) -> loc
(**********************************************************************)
+(* Alpha-renaming *)
+
+let collide_id l id = List.exists (fun (id',id'') -> Id.equal id id' || Id.equal id id'') l
+let test_id l id = if collide_id l id then raise Not_found
+let test_na l na = name_iter (test_id l) na
+
+let update_subst na l =
+ let in_range id l = List.exists (fun (_,id') -> Id.equal id id') l in
+ let l' = name_fold Id.List.remove_assoc na l in
+ name_fold
+ (fun id _ ->
+ if in_range id l' then
+ let id' = Namegen.next_ident_away_from id (fun id' -> in_range id' l') in
+ Name id', (id,id')::l
+ else na,l)
+ na (na,l)
+
+exception UnsoundRenaming
+
+let rename_var l id =
+ try
+ let id' = Id.List.assoc id l in
+ (* Check that no other earlier binding hide the one found *)
+ let _,(id'',_) = List.extract_first (fun (_,id) -> Id.equal id id') l in
+ if Id.equal id id'' then id' else raise UnsoundRenaming
+ with Not_found ->
+ if List.exists (fun (_,id') -> Id.equal id id') l then raise UnsoundRenaming
+ else id
+
+let rec rename_glob_vars l = function
+ | GVar (loc,id) as r ->
+ let id' = rename_var l id in
+ if id == id' then r else GVar (loc,id')
+ | GRef (_,VarRef id,_) as r ->
+ if List.exists (fun (_,id') -> Id.equal id id') l then raise UnsoundRenaming
+ else r
+ | GProd (loc,na,bk,t,c) ->
+ let na',l' = update_subst na l in
+ GProd (loc,na,bk,rename_glob_vars l t,rename_glob_vars l' c)
+ | GLambda (loc,na,bk,t,c) ->
+ let na',l' = update_subst na l in
+ GLambda (loc,na',bk,rename_glob_vars l t,rename_glob_vars l' c)
+ | GLetIn (loc,na,b,c) ->
+ let na',l' = update_subst na l in
+ GLetIn (loc,na',rename_glob_vars l b,rename_glob_vars l' c)
+ (* Lazy strategy: we fail if a collision with renaming occurs, rather than renaming further *)
+ | GCases (loc,ci,po,tomatchl,cls) ->
+ let test_pred_pat (na,ino) =
+ test_na l na; Option.iter (fun (_,_,nal) -> List.iter (test_na l) nal) ino in
+ let test_clause idl = List.iter (test_id l) idl in
+ let po = Option.map (rename_glob_vars l) po in
+ let tomatchl = Util.List.map_left (fun (tm,x) -> test_pred_pat x; (rename_glob_vars l tm,x)) tomatchl in
+ let cls = Util.List.map_left (fun (loc,idl,p,c) -> test_clause idl; (loc,idl,p,rename_glob_vars l c)) cls in
+ GCases (loc,ci,po,tomatchl,cls)
+ | GLetTuple (loc,nal,(na,po),c,b) ->
+ List.iter (test_na l) (na::nal);
+ GLetTuple (loc,nal,(na,Option.map (rename_glob_vars l) po),
+ rename_glob_vars l c,rename_glob_vars l b)
+ | GIf (loc,c,(na,po),b1,b2) ->
+ test_na l na;
+ GIf (loc,rename_glob_vars l c,(na,Option.map (rename_glob_vars l) po),
+ rename_glob_vars l b1,rename_glob_vars l b2)
+ | GRec (loc,k,idl,decls,bs,ts) ->
+ Array.iter (test_id l) idl;
+ GRec (loc,k,idl,
+ Array.map (List.map (fun (na,k,bbd,bty) ->
+ test_na l na; (na,k,Option.map (rename_glob_vars l) bbd,rename_glob_vars l bty))) decls,
+ Array.map (rename_glob_vars l) bs,
+ Array.map (rename_glob_vars l) ts)
+ | r -> map_glob_constr (rename_glob_vars l) r
+
+(**********************************************************************)
(* Conversion from glob_constr to cases pattern, if possible *)
let rec cases_pattern_of_glob_constr na = function
diff --git a/pretyping/glob_ops.mli b/pretyping/glob_ops.mli
index e0a2de0326..55e6b6533f 100644
--- a/pretyping/glob_ops.mli
+++ b/pretyping/glob_ops.mli
@@ -34,6 +34,8 @@ val map_glob_constr :
val map_glob_constr_left_to_right :
(glob_constr -> glob_constr) -> glob_constr -> glob_constr
+val warn_variable_collision : ?loc:Loc.t -> Id.t -> unit
+
val fold_glob_constr : ('a -> glob_constr -> 'a) -> 'a -> glob_constr -> 'a
val iter_glob_constr : (glob_constr -> unit) -> glob_constr -> unit
val occur_glob_constr : Id.t -> glob_constr -> bool
@@ -42,6 +44,16 @@ val bound_glob_vars : glob_constr -> Id.Set.t
val loc_of_glob_constr : glob_constr -> Loc.t
val glob_visible_short_qualid : glob_constr -> Id.t list
+(* Renaming free variables using a renaming map; fails with
+ [UnsoundRenaming] if applying the renaming would introduce
+ collision, as in, e.g., renaming [P x y] using substitution [(x,y)];
+ inner alpha-conversion done only for forall, fun, let but
+ not for cases and fix *)
+
+exception UnsoundRenaming
+val rename_var : (Id.t * Id.t) list -> Id.t -> Id.t
+val rename_glob_vars : (Id.t * Id.t) list -> glob_constr -> glob_constr
+
(** [map_pattern_binders f m c] applies [f] to all the binding names
in a pattern-matching expression ({!Glob_term.GCases}) represented
here by its relevant components [m] and [c]. It is used to
diff --git a/pretyping/indrec.ml b/pretyping/indrec.ml
index 5d36fc78ef..9cf91a9476 100644
--- a/pretyping/indrec.ml
+++ b/pretyping/indrec.ml
@@ -11,7 +11,7 @@
(* This file builds various inductive schemes *)
open Pp
-open Errors
+open CErrors
open Util
open Names
open Libnames
@@ -36,12 +36,14 @@ type dep_flag = bool
type recursion_scheme_error =
| NotAllowedCaseAnalysis of (*isrec:*) bool * sorts * pinductive
| NotMutualInScheme of inductive * inductive
+ | NotAllowedDependentAnalysis of (*isrec:*) bool * inductive
exception RecursionSchemeError of recursion_scheme_error
let make_prod_dep dep env = if dep then mkProd_name env else mkProd
let mkLambda_string s t c = mkLambda (Name (Id.of_string s), t, c)
+
(*******************************************)
(* Building curryfied elimination *)
(*******************************************)
@@ -53,7 +55,7 @@ let is_private mib =
let check_privacy_block mib =
if is_private mib then
- errorlabstrm ""(str"case analysis on a private inductive type")
+ user_err (str"case analysis on a private inductive type")
(**********************************************************************)
(* Building case analysis schemes *)
@@ -151,7 +153,7 @@ let type_rec_branch is_rec dep env sigma (vargs,depPvect,decP) tyi cs recargs =
let nparams = List.length vargs in
let process_pos env depK pk =
let rec prec env i sign p =
- let p',largs = whd_betadeltaiota_nolet_stack env sigma p in
+ let p',largs = whd_allnolet_stack env sigma p in
match kind_of_term p' with
| Prod (n,t,c) ->
let d = LocalAssum (n,t) in
@@ -168,7 +170,7 @@ let type_rec_branch is_rec dep env sigma (vargs,depPvect,decP) tyi cs recargs =
else
base
| _ ->
- let t' = whd_betadeltaiota env sigma p in
+ let t' = whd_all env sigma p in
if Term.eq_constr p' t' then assert false
else prec env i sign t'
in
@@ -183,9 +185,7 @@ let type_rec_branch is_rec dep env sigma (vargs,depPvect,decP) tyi cs recargs =
| ra::rest ->
(match dest_recarg ra with
| Mrec (_,j) when is_rec -> (depPvect.(j),rest)
- | Imbr _ ->
- Feedback.msg_warning (strbrk "Ignoring recursive call");
- (None,rest)
+ | Imbr _ -> (None,rest)
| _ -> (None, rest))
in
(match optionpos with
@@ -229,7 +229,7 @@ let type_rec_branch is_rec dep env sigma (vargs,depPvect,decP) tyi cs recargs =
let make_rec_branch_arg env sigma (nparrec,fvect,decF) f cstr recargs =
let process_pos env fk =
let rec prec env i hyps p =
- let p',largs = whd_betadeltaiota_nolet_stack env sigma p in
+ let p',largs = whd_allnolet_stack env sigma p in
match kind_of_term p' with
| Prod (n,t,c) ->
let d = LocalAssum (n,t) in
@@ -242,7 +242,7 @@ let make_rec_branch_arg env sigma (nparrec,fvect,decF) f cstr recargs =
and arg = appvect (mkRel (i+1), Context.Rel.to_extended_vect 0 hyps) in
applist(lift i fk,realargs@[arg])
| _ ->
- let t' = whd_betadeltaiota env sigma p in
+ let t' = whd_all env sigma p in
if Term.eq_constr t' p' then assert false
else prec env i hyps t'
in
@@ -377,27 +377,9 @@ let mis_make_indrec env sigma listdepkind mib u =
(Anonymous,depind',concl))
arsign'
in
- let obj =
- let projs = get_projections env indf in
- match projs with
- | None -> (mkCase (ci, pred,
- mkRel 1,
- branches))
- | Some ps ->
- let branch = branches.(0) in
- let ctx, br = decompose_lam_assum branch in
- let n, subst =
- List.fold_right (fun decl (i, subst) ->
- match decl with
- | LocalAssum (na,t) ->
- let t = mkProj (Projection.make ps.(i) true, mkRel 1) in
- i + 1, t :: subst
- | LocalDef (na,b,t) ->
- i, mkRel 0 :: subst)
- ctx (0, [])
- in
- let term = substl subst br in
- term
+ let obj =
+ Inductiveops.make_case_or_project env indf ci pred
+ (mkRel 1) branches
in
it_mkLambda_or_LetIn_name env obj
(Termops.lift_rel_context nrec deparsign)
@@ -485,6 +467,8 @@ let mis_make_indrec env sigma listdepkind mib u =
let build_case_analysis_scheme env sigma pity dep kind =
let (mib,mip) = lookup_mind_specif env (fst pity) in
+ if dep && not (Inductiveops.has_dependent_elim mib) then
+ raise (RecursionSchemeError (NotAllowedDependentAnalysis (false, fst pity)));
mis_make_case_com dep env sigma pity (mib,mip) kind
let is_in_prop mip =
@@ -494,7 +478,7 @@ let is_in_prop mip =
let build_case_analysis_scheme_default env sigma pity kind =
let (mib,mip) = lookup_mind_specif env (fst pity) in
- let dep = not (is_in_prop mip) in
+ let dep = not (is_in_prop mip || not (Inductiveops.has_dependent_elim mib)) in
mis_make_case_com dep env sigma pity (mib,mip) kind
(**********************************************************************)
@@ -555,6 +539,8 @@ let check_arities env listdepkind =
let build_mutual_induction_scheme env sigma = function
| ((mind,u),dep,s)::lrecspec ->
let (mib,mip) = lookup_mind_specif env mind in
+ if dep && not (Inductiveops.has_dependent_elim mib) then
+ raise (RecursionSchemeError (NotAllowedDependentAnalysis (true, mind)));
let (sp,tyi) = mind in
let listdepkind =
((mind,u),mib,mip,dep,s)::
@@ -574,6 +560,8 @@ let build_mutual_induction_scheme env sigma = function
let build_induction_scheme env sigma pind dep kind =
let (mib,mip) = lookup_mind_specif env (fst pind) in
+ if dep && not (Inductiveops.has_dependent_elim mib) then
+ raise (RecursionSchemeError (NotAllowedDependentAnalysis (true, fst pind)));
let sigma, l = mis_make_indrec env sigma [(pind,mib,mip,dep,kind)] mib (snd pind) in
sigma, List.hd l
@@ -606,7 +594,7 @@ let lookup_eliminator ind_sp s =
(* using short name (e.g. for "eq_rec") *)
try Nametab.locate (qualid_of_ident id)
with Not_found ->
- errorlabstrm "default_elim"
+ user_err ~hdr:"default_elim"
(strbrk "Cannot find the elimination combinator " ++
pr_id id ++ strbrk ", the elimination of the inductive definition " ++
pr_global_env Id.Set.empty (IndRef ind_sp) ++
diff --git a/pretyping/indrec.mli b/pretyping/indrec.mli
index f0736d2dda..192b64a5ed 100644
--- a/pretyping/indrec.mli
+++ b/pretyping/indrec.mli
@@ -16,6 +16,7 @@ open Evd
type recursion_scheme_error =
| NotAllowedCaseAnalysis of (*isrec:*) bool * sorts * pinductive
| NotMutualInScheme of inductive * inductive
+ | NotAllowedDependentAnalysis of (*isrec:*) bool * inductive
exception RecursionSchemeError of recursion_scheme_error
@@ -28,13 +29,15 @@ type dep_flag = bool
val build_case_analysis_scheme : env -> 'r Sigma.t -> pinductive ->
dep_flag -> sorts_family -> (constr, 'r) Sigma.sigma
-(** Build a dependent case elimination predicate unless type is in Prop *)
+(** Build a dependent case elimination predicate unless type is in Prop
+ or is a recursive record with primitive projections. *)
val build_case_analysis_scheme_default : env -> 'r Sigma.t -> pinductive ->
sorts_family -> (constr, 'r) Sigma.sigma
(** Builds a recursive induction scheme (Peano-induction style) in the same
- sort family as the inductive family; it is dependent if not in Prop *)
+ sort family as the inductive family; it is dependent if not in Prop
+ or a recursive record with primitive projections. *)
val build_induction_scheme : env -> evar_map -> pinductive ->
dep_flag -> sorts_family -> evar_map * constr
diff --git a/pretyping/inductiveops.ml b/pretyping/inductiveops.ml
index 80f1988a97..ac6d775e34 100644
--- a/pretyping/inductiveops.ml
+++ b/pretyping/inductiveops.ml
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Errors
+open CErrors
open Util
open Names
open Univ
@@ -24,14 +24,14 @@ open Context.Rel.Declaration
let type_of_inductive env (ind,u) =
let (mib,_ as specif) = Inductive.lookup_mind_specif env ind in
- Typeops.check_hyps_inclusion env (mkInd ind) mib.mind_hyps;
+ Typeops.check_hyps_inclusion env mkInd ind mib.mind_hyps;
Inductive.type_of_inductive env (specif,u)
(* Return type as quoted by the user *)
let type_of_constructor env (cstr,u) =
let (mib,_ as specif) =
Inductive.lookup_mind_specif env (inductive_of_constructor cstr) in
- Typeops.check_hyps_inclusion env (mkConstruct cstr) mib.mind_hyps;
+ Typeops.check_hyps_inclusion env mkConstruct cstr mib.mind_hyps;
Inductive.type_of_constructor (cstr,u) specif
(* Return constructor types in user form *)
@@ -269,6 +269,11 @@ let projection_nparams_env env p =
let projection_nparams p = projection_nparams_env (Global.env ()) p
+let has_dependent_elim mib =
+ match mib.mind_record with
+ | Some (Some _) -> mib.mind_finite == Decl_kinds.BiFinite
+ | _ -> true
+
(* Annotation for cases *)
let make_case_info env ind style =
let (mib,mip) = Inductive.lookup_mind_specif env ind in
@@ -338,6 +343,35 @@ let get_projections env (ind,params) =
| Some (Some (id, projs, pbs)) -> Some projs
| _ -> None
+let make_case_or_project env indf ci pred c branches =
+ let projs = get_projections env indf in
+ match projs with
+ | None -> (mkCase (ci, pred, c, branches))
+ | Some ps ->
+ assert(Array.length branches == 1);
+ let () =
+ let _, _, t = destLambda pred in
+ let (ind, _), _ = dest_ind_family indf in
+ let mib, _ = Inductive.lookup_mind_specif env ind in
+ if (* dependent *) not (noccurn 1 t) &&
+ not (has_dependent_elim mib) then
+ user_err ~hdr:"make_case_or_project"
+ Pp.(str"Dependent case analysis not allowed" ++
+ str" on inductive type " ++ Names.MutInd.print (fst ind))
+ in
+ let branch = branches.(0) in
+ let ctx, br = decompose_lam_n_assum (Array.length ps) branch in
+ let n, subst =
+ List.fold_right
+ (fun decl (i, subst) ->
+ match decl with
+ | LocalAssum (na, t) ->
+ let t = mkProj (Projection.make ps.(i) true, c) in
+ (i + 1, t :: subst)
+ | LocalDef (na, b, t) -> (i, substl subst b :: subst))
+ ctx (0, [])
+ in substl subst br
+
(* substitution in a signature *)
let substnl_rel_context subst n sign =
@@ -417,7 +451,7 @@ let extract_mrectype t =
| _ -> raise Not_found
let find_mrectype_vect env sigma c =
- let (t, l) = decompose_appvect (whd_betadeltaiota env sigma c) in
+ let (t, l) = decompose_appvect (whd_all env sigma c) in
match kind_of_term t with
| Ind ind -> (ind, l)
| _ -> raise Not_found
@@ -426,7 +460,7 @@ let find_mrectype env sigma c =
let (ind, v) = find_mrectype_vect env sigma c in (ind, Array.to_list v)
let find_rectype env sigma c =
- let (t, l) = decompose_app (whd_betadeltaiota env sigma c) in
+ let (t, l) = decompose_app (whd_all env sigma c) in
match kind_of_term t with
| Ind (ind,u as indu) ->
let (mib,mip) = Inductive.lookup_mind_specif env ind in
@@ -436,7 +470,7 @@ let find_rectype env sigma c =
| _ -> raise Not_found
let find_inductive env sigma c =
- let (t, l) = decompose_app (whd_betadeltaiota env sigma c) in
+ let (t, l) = decompose_app (whd_all env sigma c) in
match kind_of_term t with
| Ind ind
when (fst (Inductive.lookup_mind_specif env (fst ind))).mind_finite <> Decl_kinds.CoFinite ->
@@ -444,7 +478,7 @@ let find_inductive env sigma c =
| _ -> raise Not_found
let find_coinductive env sigma c =
- let (t, l) = decompose_app (whd_betadeltaiota env sigma c) in
+ let (t, l) = decompose_app (whd_all env sigma c) in
match kind_of_term t with
| Ind ind
when (fst (Inductive.lookup_mind_specif env (fst ind))).mind_finite == Decl_kinds.CoFinite ->
@@ -458,7 +492,7 @@ let find_coinductive env sigma c =
let is_predicate_explicitly_dep env pred arsign =
let rec srec env pval arsign =
- let pv' = whd_betadeltaiota env Evd.empty pval in
+ let pv' = whd_all env Evd.empty pval in
match kind_of_term pv', arsign with
| Lambda (na,t,b), (LocalAssum _)::arsign ->
srec (push_rel_assum (na,t) env) b arsign
@@ -581,7 +615,7 @@ let type_of_projection_knowing_arg env sigma p c ty =
raise (Invalid_argument "type_of_projection_knowing_arg_type: not an inductive type")
in
let (_,u), pars = dest_ind_family pars in
- substl (c :: List.rev pars) (Typeops.type_of_projection env (p,u))
+ substl (c :: List.rev pars) (Typeops.type_of_projection_constant env (p,u))
(***********************************************)
(* Guard condition *)
@@ -592,9 +626,9 @@ let type_of_projection_knowing_arg env sigma p c ty =
let control_only_guard env c =
let check_fix_cofix e c = match kind_of_term c with
| CoFix (_,(_,_,_) as cofix) ->
- Inductive.check_cofix e cofix
+ Inductive.check_cofix e cofix
| Fix (_,(_,_,_) as fix) ->
- Inductive.check_fix e fix
+ Inductive.check_fix e fix
| _ -> ()
in
let rec iter env c =
diff --git a/pretyping/inductiveops.mli b/pretyping/inductiveops.mli
index d25f8a8378..7bd616591f 100644
--- a/pretyping/inductiveops.mli
+++ b/pretyping/inductiveops.mli
@@ -122,11 +122,16 @@ val inductive_has_local_defs : inductive -> bool
val allowed_sorts : env -> inductive -> sorts_family list
+(** (Co)Inductive records with primitive projections do not have eta-conversion,
+ hence no dependent elimination. *)
+val has_dependent_elim : mutual_inductive_body -> bool
+
(** Primitive projections *)
val projection_nparams : projection -> int
val projection_nparams_env : env -> projection -> int
val type_of_projection_knowing_arg : env -> evar_map -> Projection.t ->
- constr -> types -> types
+ constr -> types -> types
+
(** Extract information from an inductive family *)
@@ -175,6 +180,14 @@ val type_case_branches_with_names :
(** Annotation for cases *)
val make_case_info : env -> inductive -> case_style -> case_info
+(** Make a case or substitute projections if the inductive type is a record
+ with primitive projections.
+ Fail with an error if the elimination is dependent while the
+ inductive type does not allow dependent elimination. *)
+val make_case_or_project :
+ env -> inductive_family -> case_info ->
+ (* pred *) constr -> (* term *) constr -> (* branches *) constr array -> constr
+
(*i Compatibility
val make_default_case_info : env -> case_style -> inductive -> case_info
i*)
diff --git a/pretyping/locusops.ml b/pretyping/locusops.ml
index d89aeccd8c..e4fbf8d542 100644
--- a/pretyping/locusops.ml
+++ b/pretyping/locusops.ml
@@ -50,9 +50,9 @@ let is_nowhere = function
let simple_clause_of enum_hyps cl =
let error_occurrences () =
- Errors.error "This tactic does not support occurrences selection" in
+ CErrors.error "This tactic does not support occurrences selection" in
let error_body_selection () =
- Errors.error "This tactic does not support body selection" in
+ CErrors.error "This tactic does not support body selection" in
let hyps =
match cl.onhyps with
| None ->
@@ -84,7 +84,7 @@ let concrete_clause_of enum_hyps cl =
(** Miscellaneous functions *)
let out_arg = function
- | Misctypes.ArgVar _ -> Errors.anomaly (Pp.str "Unevaluated or_var variable")
+ | Misctypes.ArgVar _ -> CErrors.anomaly (Pp.str "Unevaluated or_var variable")
| Misctypes.ArgArg x -> x
let occurrences_of_hyp id cls =
diff --git a/pretyping/nativenorm.ml b/pretyping/nativenorm.ml
index 2a5e999651..1e5f12b209 100644
--- a/pretyping/nativenorm.ml
+++ b/pretyping/nativenorm.ml
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
open Pp
-open Errors
+open CErrors
open Term
open Vars
open Environ
@@ -20,6 +20,8 @@ open Nativecode
open Nativevalues
open Context.Rel.Declaration
+module RelDecl = Context.Rel.Declaration
+
(** This module implements normalization by evaluation to OCaml code *)
exception Find_at of int
@@ -35,13 +37,13 @@ let invert_tag cst tag reloc_tbl =
with Find_at j -> (j+1)
let decompose_prod env t =
- let (name,dom,codom as res) = destProd (whd_betadeltaiota env t) in
+ let (name,dom,codom as res) = destProd (whd_all env t) in
match name with
| Anonymous -> (Name (id_of_string "x"),dom,codom)
| _ -> res
let app_type env c =
- let t = whd_betadeltaiota env c in
+ let t = whd_all env c in
try destApp t with DestKO -> (t,[||])
@@ -122,7 +124,7 @@ let build_case_type dep p realargs c =
(* TODO move this function *)
let type_of_rel env n =
- lookup_rel n env |> get_type |> lift n
+ env |> lookup_rel n |> RelDecl.get_type |> lift n
let type_of_prop = mkSort type1_sort
@@ -133,7 +135,7 @@ let type_of_sort s =
let type_of_var env id =
let open Context.Named.Declaration in
- try lookup_named id env |> get_type
+ try env |> lookup_named id |> get_type
with Not_found ->
anomaly ~label:"type_of_var" (str "variable " ++ Id.print id ++ str " unbound")
@@ -178,7 +180,7 @@ let rec nf_val env v typ =
let name,dom,codom =
try decompose_prod env typ
with DestKO ->
- Errors.anomaly
+ CErrors.anomaly
(Pp.strbrk "Returned a functional value in a type not recognized as a product type.")
in
let env = push_rel (LocalAssum (name,dom)) env in
@@ -224,7 +226,7 @@ and nf_args env accu t =
let _,dom,codom =
try decompose_prod env t with
DestKO ->
- Errors.anomaly
+ CErrors.anomaly
(Pp.strbrk "Returned a functional value in a type not recognized as a product type.")
in
let c = nf_val env arg dom in
@@ -241,7 +243,7 @@ and nf_bargs env b t =
let _,dom,codom =
try decompose_prod env !t with
DestKO ->
- Errors.anomaly
+ CErrors.anomaly
(Pp.strbrk "Returned a functional value in a type not recognized as a product type.")
in
let c = nf_val env (block_field b i) dom in
@@ -289,7 +291,7 @@ and nf_atom_type env atom =
let pT =
hnf_prod_applist env
(Inductiveops.type_of_inductive env ind) (Array.to_list params) in
- let pT = whd_betadeltaiota env pT in
+ let pT = whd_all env pT in
let dep, p = nf_predicate env ind mip params p pT in
(* Calcul du type des branches *)
let btypes = build_branches_type env (fst ind) mib mip u params dep p in
@@ -352,7 +354,7 @@ and nf_predicate env ind mip params v pT =
let name,dom,codom =
try decompose_prod env pT with
DestKO ->
- Errors.anomaly
+ CErrors.anomaly
(Pp.strbrk "Returned a functional value in a type not recognized as a product type.")
in
let dep,body =
diff --git a/pretyping/patternops.ml b/pretyping/patternops.ml
index d6305d81a8..9dcb5d2a57 100644
--- a/pretyping/patternops.ml
+++ b/pretyping/patternops.ml
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Errors
+open CErrors
open Util
open Names
open Globnames
@@ -204,7 +204,7 @@ let error_instantiate_pattern id l =
| [_] -> "is"
| _ -> "are"
in
- errorlabstrm "" (str "Cannot substitute the term bound to " ++ pr_id id
+ user_err (str "Cannot substitute the term bound to " ++ pr_id id
++ strbrk " in pattern because the term refers to " ++ pr_enum pr_id l
++ strbrk " which " ++ str is ++ strbrk " not bound in the pattern.")
@@ -315,7 +315,11 @@ let rec subst_pattern subst pat =
let mkPLambda na b = PLambda(na,PMeta None,b)
let rev_it_mkPLambda = List.fold_right mkPLambda
-let err loc pp = user_err_loc (loc,"pattern_of_glob_constr", pp)
+let err ?loc pp = user_err ?loc ~hdr:"pattern_of_glob_constr" pp
+
+let warn_cast_in_pattern =
+ CWarnings.create ~name:"cast-in-pattern" ~category:"automation"
+ (fun () -> Pp.strbrk "Casts are ignored in patterns")
let rec pat_of_raw metas vars = function
| GVar (_,id) ->
@@ -348,7 +352,7 @@ let rec pat_of_raw metas vars = function
| GHole _ ->
PMeta None
| GCast (_,c,_) ->
- Feedback.msg_warning (strbrk "Cast not taken into account in constr pattern");
+ warn_cast_in_pattern ();
pat_of_raw metas vars c
| GIf (_,c,(_,None),b1,b2) ->
PIf (pat_of_raw metas vars c,
@@ -383,7 +387,7 @@ let rec pat_of_raw metas vars = function
rev_it_mkPLambda nal (mkPLambda na (pat_of_raw metas nvars p))
| (None | Some (GHole _)), _ -> PMeta None
| Some p, None ->
- user_err_loc (loc,"",strbrk "Clause \"in\" expected in patterns over \"match\" expressions with an explicit \"return\" clause.")
+ user_err ~loc (strbrk "Clause \"in\" expected in patterns over \"match\" expressions with an explicit \"return\" clause.")
in
let info =
{ cip_style = sty;
@@ -396,12 +400,12 @@ let rec pat_of_raw metas vars = function
one non-trivial branch. These facts are used in [Constrextern]. *)
PCase (info, pred, pat_of_raw metas vars c, brs)
- | r -> err (loc_of_glob_constr r) (Pp.str "Non supported pattern.")
+ | r -> err ~loc:(loc_of_glob_constr r) (Pp.str "Non supported pattern.")
and pats_of_glob_branches loc metas vars ind brs =
let get_arg = function
| PatVar(_,na) -> na
- | PatCstr(loc,_,_,_) -> err loc (Pp.str "Non supported pattern.")
+ | PatCstr(loc,_,_,_) -> err ~loc (Pp.str "Non supported pattern.")
in
let rec get_pat indexes = function
| [] -> false, []
@@ -410,10 +414,10 @@ and pats_of_glob_branches loc metas vars ind brs =
let () = match ind with
| Some sp when eq_ind sp indsp -> ()
| _ ->
- err loc (Pp.str "All constructors must be in the same inductive type.")
+ err ~loc (Pp.str "All constructors must be in the same inductive type.")
in
if Int.Set.mem (j-1) indexes then
- err loc
+ err ~loc
(str "No unique branch for " ++ int j ++ str"-th constructor.");
let lna = List.map get_arg lv in
let vars' = List.rev lna @ vars in
@@ -421,7 +425,7 @@ and pats_of_glob_branches loc metas vars ind brs =
let ext,pats = get_pat (Int.Set.add (j-1) indexes) brs in
let tags = List.map (fun _ -> false) lv (* approximation, w/o let-in *) in
ext, ((j-1, tags, pat) :: pats)
- | (loc,_,_,_) :: _ -> err loc (Pp.str "Non supported pattern.")
+ | (loc,_,_,_) :: _ -> err ~loc (Pp.str "Non supported pattern.")
in
get_pat Int.Set.empty brs
diff --git a/pretyping/pretype_errors.ml b/pretyping/pretype_errors.ml
index cf5b08c58f..5b09586950 100644
--- a/pretyping/pretype_errors.ml
+++ b/pretyping/pretype_errors.ml
@@ -14,15 +14,16 @@ open Type_errors
type unification_error =
| OccurCheck of existential_key * constr
- | NotClean of existential * env * constr
+ | NotClean of existential * env * constr (* Constr is a variable not in scope *)
| NotSameArgSize
| NotSameHead
| NoCanonicalStructure
- | ConversionFailed of env * constr * constr
+ | ConversionFailed of env * constr * constr (* Non convertible closed terms *)
| MetaOccurInBody of existential_key
| InstanceNotSameType of existential_key * env * types * types
| UnifUnivInconsistency of Univ.univ_inconsistency
| CannotSolveConstraint of Evd.evar_constraint * unification_error
+ | ProblemBeyondCapabilities
type position = (Id.t * Locus.hyp_location_flag) option
@@ -59,47 +60,46 @@ type pretype_error =
exception PretypeError of env * Evd.evar_map * pretype_error
let precatchable_exception = function
- | Errors.UserError _ | TypeError _ | PretypeError _
+ | CErrors.UserError _ | TypeError _ | PretypeError _
| Nametab.GlobalizationError _ -> true
| _ -> false
-let raise_pretype_error (loc,env,sigma,te) =
- Loc.raise loc (PretypeError(env,sigma,te))
+let raise_pretype_error ?loc (env,sigma,te) =
+ Loc.raise ?loc (PretypeError(env,sigma,te))
-let raise_located_type_error (loc,env,sigma,te) =
- Loc.raise loc (PretypeError(env,sigma,TypingError te))
+let raise_type_error ?loc (env,sigma,te) =
+ Loc.raise ?loc (PretypeError(env,sigma,TypingError te))
-
-let error_actual_type_loc loc env sigma {uj_val=c;uj_type=actty} expty reason =
+let error_actual_type ?loc env sigma {uj_val=c;uj_type=actty} expty reason =
let j = {uj_val=c;uj_type=actty} in
- raise_pretype_error
- (loc, env, sigma, ActualTypeNotCoercible (j, expty, reason))
+ raise_pretype_error ?loc
+ (env, sigma, ActualTypeNotCoercible (j, expty, reason))
-let error_cant_apply_not_functional_loc loc env sigma rator randl =
- raise_located_type_error
- (loc, env, sigma, CantApplyNonFunctional (rator, Array.of_list randl))
+let error_cant_apply_not_functional ?loc env sigma rator randl =
+ raise_type_error ?loc
+ (env, sigma, CantApplyNonFunctional (rator, Array.of_list randl))
-let error_cant_apply_bad_type_loc loc env sigma (n,c,t) rator randl =
- raise_located_type_error
- (loc, env, sigma,
+let error_cant_apply_bad_type ?loc env sigma (n,c,t) rator randl =
+ raise_type_error ?loc
+ (env, sigma,
CantApplyBadType ((n,c,t), rator, Array.of_list randl))
-let error_ill_formed_branch_loc loc env sigma c i actty expty =
- raise_located_type_error
- (loc, env, sigma, IllFormedBranch (c, i, actty, expty))
+let error_ill_formed_branch ?loc env sigma c i actty expty =
+ raise_type_error
+ ?loc (env, sigma, IllFormedBranch (c, i, actty, expty))
-let error_number_branches_loc loc env sigma cj expn =
- raise_located_type_error (loc, env, sigma, NumberBranches (cj, expn))
+let error_number_branches ?loc env sigma cj expn =
+ raise_type_error ?loc (env, sigma, NumberBranches (cj, expn))
-let error_case_not_inductive_loc loc env sigma cj =
- raise_located_type_error (loc, env, sigma, CaseNotInductive cj)
+let error_case_not_inductive ?loc env sigma cj =
+ raise_type_error ?loc (env, sigma, CaseNotInductive cj)
-let error_ill_typed_rec_body_loc loc env sigma i na jl tys =
- raise_located_type_error
- (loc, env, sigma, IllTypedRecBody (i, na, jl, tys))
+let error_ill_typed_rec_body ?loc env sigma i na jl tys =
+ raise_type_error ?loc
+ (env, sigma, IllTypedRecBody (i, na, jl, tys))
-let error_not_a_type_loc loc env sigma j =
- raise_located_type_error (loc, env, sigma, NotAType j)
+let error_not_a_type ?loc env sigma j =
+ raise_type_error ?loc (env, sigma, NotAType j)
(*s Implicit arguments synthesis errors. It is hard to find
a precise location. *)
@@ -107,15 +107,12 @@ let error_not_a_type_loc loc env sigma j =
let error_occur_check env sigma ev c =
raise (PretypeError (env, sigma, UnifOccurCheck (ev,c)))
-let error_unsolvable_implicit loc env sigma evk explain =
- Loc.raise loc
+let error_unsolvable_implicit ?loc env sigma evk explain =
+ Loc.raise ?loc
(PretypeError (env, sigma, UnsolvableImplicit (evk, explain)))
-let error_cannot_unify_loc loc env sigma ?reason (m,n) =
- Loc.raise loc (PretypeError (env, sigma,CannotUnify (m,n,reason)))
-
-let error_cannot_unify env sigma ?reason (m,n) =
- raise (PretypeError (env, sigma,CannotUnify (m,n,reason)))
+let error_cannot_unify ?loc env sigma ?reason (m,n) =
+ Loc.raise ?loc (PretypeError (env, sigma,CannotUnify (m,n,reason)))
let error_cannot_unify_local env sigma (m,n,sn) =
raise (PretypeError (env, sigma,CannotUnifyLocal (m,n,sn)))
@@ -139,21 +136,21 @@ let error_non_linear_unification env sigma hdmeta t =
(*s Ml Case errors *)
-let error_cant_find_case_type_loc loc env sigma expr =
- raise_pretype_error (loc, env, sigma, CantFindCaseType expr)
+let error_cant_find_case_type ?loc env sigma expr =
+ raise_pretype_error ?loc (env, sigma, CantFindCaseType expr)
(*s Pretyping errors *)
-let error_unexpected_type_loc loc env sigma actty expty =
- raise_pretype_error (loc, env, sigma, UnexpectedType (actty, expty))
+let error_unexpected_type ?loc env sigma actty expty =
+ raise_pretype_error ?loc (env, sigma, UnexpectedType (actty, expty))
-let error_not_product_loc loc env sigma c =
- raise_pretype_error (loc, env, sigma, NotProduct c)
+let error_not_product ?loc env sigma c =
+ raise_pretype_error ?loc (env, sigma, NotProduct c)
(*s Error in conversion from AST to glob_constr *)
-let error_var_not_found_loc loc s =
- raise_pretype_error (loc, empty_env, Evd.empty, VarNotFound s)
+let error_var_not_found ?loc s =
+ raise_pretype_error ?loc (empty_env, Evd.empty, VarNotFound s)
(*s Typeclass errors *)
@@ -165,7 +162,7 @@ let unsatisfiable_constraints env evd ev comp =
| Some ev ->
let loc, kind = Evd.evar_source ev evd in
let err = UnsatisfiableConstraints (Some (ev, kind), comp) in
- Loc.raise loc (PretypeError (env,evd,err))
+ Loc.raise ~loc (PretypeError (env,evd,err))
let unsatisfiable_exception exn =
match exn with
diff --git a/pretyping/pretype_errors.mli b/pretyping/pretype_errors.mli
index f617df9ee7..73f81923ff 100644
--- a/pretyping/pretype_errors.mli
+++ b/pretyping/pretype_errors.mli
@@ -24,6 +24,7 @@ type unification_error =
| InstanceNotSameType of existential_key * env * types * types
| UnifUnivInconsistency of Univ.univ_inconsistency
| CannotSolveConstraint of Evd.evar_constraint * unification_error
+ | ProblemBeyondCapabilities
type position = (Id.t * Locus.hyp_location_flag) option
@@ -63,35 +64,35 @@ exception PretypeError of env * Evd.evar_map * pretype_error
val precatchable_exception : exn -> bool
(** Raising errors *)
-val error_actual_type_loc :
- Loc.t -> env -> Evd.evar_map -> unsafe_judgment -> constr ->
+val error_actual_type :
+ ?loc:Loc.t -> env -> Evd.evar_map -> unsafe_judgment -> constr ->
unification_error -> 'b
-val error_cant_apply_not_functional_loc :
- Loc.t -> env -> Evd.evar_map ->
+val error_cant_apply_not_functional :
+ ?loc:Loc.t -> env -> Evd.evar_map ->
unsafe_judgment -> unsafe_judgment list -> 'b
-val error_cant_apply_bad_type_loc :
- Loc.t -> env -> Evd.evar_map -> int * constr * constr ->
+val error_cant_apply_bad_type :
+ ?loc:Loc.t -> env -> Evd.evar_map -> int * constr * constr ->
unsafe_judgment -> unsafe_judgment list -> 'b
-val error_case_not_inductive_loc :
- Loc.t -> env -> Evd.evar_map -> unsafe_judgment -> 'b
+val error_case_not_inductive :
+ ?loc:Loc.t -> env -> Evd.evar_map -> unsafe_judgment -> 'b
-val error_ill_formed_branch_loc :
- Loc.t -> env -> Evd.evar_map ->
+val error_ill_formed_branch :
+ ?loc:Loc.t -> env -> Evd.evar_map ->
constr -> pconstructor -> constr -> constr -> 'b
-val error_number_branches_loc :
- Loc.t -> env -> Evd.evar_map ->
+val error_number_branches :
+ ?loc:Loc.t -> env -> Evd.evar_map ->
unsafe_judgment -> int -> 'b
-val error_ill_typed_rec_body_loc :
- Loc.t -> env -> Evd.evar_map ->
+val error_ill_typed_rec_body :
+ ?loc:Loc.t -> env -> Evd.evar_map ->
int -> Name.t array -> unsafe_judgment array -> types array -> 'b
-val error_not_a_type_loc :
- Loc.t -> env -> Evd.evar_map -> unsafe_judgment -> 'b
+val error_not_a_type :
+ ?loc:Loc.t -> env -> Evd.evar_map -> unsafe_judgment -> 'b
val error_cannot_coerce : env -> Evd.evar_map -> constr * constr -> 'b
@@ -100,15 +101,12 @@ val error_cannot_coerce : env -> Evd.evar_map -> constr * constr -> 'b
val error_occur_check : env -> Evd.evar_map -> existential_key -> constr -> 'b
val error_unsolvable_implicit :
- Loc.t -> env -> Evd.evar_map -> existential_key ->
+ ?loc:Loc.t -> env -> Evd.evar_map -> existential_key ->
Evd.unsolvability_explanation option -> 'b
-val error_cannot_unify_loc : Loc.t -> env -> Evd.evar_map ->
+val error_cannot_unify : ?loc:Loc.t -> env -> Evd.evar_map ->
?reason:unification_error -> constr * constr -> 'b
-val error_cannot_unify : env -> Evd.evar_map -> ?reason:unification_error ->
- constr * constr -> 'b
-
val error_cannot_unify_local : env -> Evd.evar_map -> constr * constr * constr -> 'b
val error_cannot_find_well_typed_abstraction : env -> Evd.evar_map ->
@@ -125,20 +123,20 @@ val error_non_linear_unification : env -> Evd.evar_map ->
(** {6 Ml Case errors } *)
-val error_cant_find_case_type_loc :
- Loc.t -> env -> Evd.evar_map -> constr -> 'b
+val error_cant_find_case_type :
+ ?loc:Loc.t -> env -> Evd.evar_map -> constr -> 'b
(** {6 Pretyping errors } *)
-val error_unexpected_type_loc :
- Loc.t -> env -> Evd.evar_map -> constr -> constr -> 'b
+val error_unexpected_type :
+ ?loc:Loc.t -> env -> Evd.evar_map -> constr -> constr -> 'b
-val error_not_product_loc :
- Loc.t -> env -> Evd.evar_map -> constr -> 'b
+val error_not_product :
+ ?loc:Loc.t -> env -> Evd.evar_map -> constr -> 'b
(** {6 Error in conversion from AST to glob_constr } *)
-val error_var_not_found_loc : Loc.t -> Id.t -> 'b
+val error_var_not_found : ?loc:Loc.t -> Id.t -> 'b
(** {6 Typeclass errors } *)
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index efc42aab76..f92110ea56 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -22,7 +22,7 @@
open Pp
-open Errors
+open CErrors
open Util
open Names
open Evd
@@ -43,8 +43,10 @@ open Glob_ops
open Evarconv
open Pattern
open Misctypes
+open Tactypes
open Sigma.Notations
-open Context.Named.Declaration
+
+module NamedDecl = Context.Named.Declaration
type typing_constraint = OfType of types | IsType | WithoutTypeConstraint
type var_map = constr_under_binders Id.Map.t
@@ -58,8 +60,6 @@ type ltac_var_map = {
}
type glob_constr_ltac_closure = ltac_var_map * glob_constr
type pure_open_constr = evar_map * constr
-type 'a delayed_open =
- { delayed : 'r. Environ.env -> 'r Sigma.t -> ('a, 'r) Sigma.sigma }
(************************************************************************)
(* This concerns Cases *)
@@ -68,6 +68,61 @@ open Inductiveops
(************************************************************************)
+module ExtraEnv =
+struct
+
+type t = {
+ env : Environ.env;
+ extra : Evarutil.ext_named_context Lazy.t;
+ (** Delay the computation of the evar extended environment *)
+}
+
+let get_extra env =
+ let open Context.Named.Declaration in
+ let ids = List.map get_id (named_context env) in
+ let avoid = List.fold_right Id.Set.add ids Id.Set.empty in
+ Context.Rel.fold_outside push_rel_decl_to_named_context
+ (Environ.rel_context env) ~init:(empty_csubst, [], avoid, named_context env)
+
+let make_env env = { env = env; extra = lazy (get_extra env) }
+let rel_context env = rel_context env.env
+
+let push_rel d env = {
+ env = push_rel d env.env;
+ extra = lazy (push_rel_decl_to_named_context d (Lazy.force env.extra));
+}
+
+let pop_rel_context n env = make_env (pop_rel_context n env.env)
+
+let push_rel_context ctx env = {
+ env = push_rel_context ctx env.env;
+ extra = lazy (List.fold_right push_rel_decl_to_named_context ctx (Lazy.force env.extra));
+}
+
+let lookup_named id env = lookup_named id env.env
+
+let e_new_evar env evdref ?src ?naming typ =
+ let subst2 subst vsubst c = csubst_subst subst (replace_vars vsubst c) in
+ let open Context.Named.Declaration in
+ let inst_vars = List.map (get_id %> mkVar) (named_context env.env) in
+ let inst_rels = List.rev (rel_list 0 (nb_rel env.env)) in
+ let (subst, vsubst, _, nc) = Lazy.force env.extra in
+ let typ' = subst2 subst vsubst typ in
+ let instance = inst_rels @ inst_vars in
+ let sign = val_of_named_context nc in
+ let sigma = Sigma.Unsafe.of_evar_map !evdref in
+ let Sigma (e, sigma, _) = new_evar_instance sign sigma typ' ?src ?naming instance in
+ evdref := Sigma.to_evar_map sigma;
+ e
+
+let push_rec_types (lna,typarray,_) env =
+ let ctxt = Array.map2_i (fun i na t -> Context.Rel.Declaration.LocalAssum (na, lift i t)) lna typarray in
+ Array.fold_left (fun e assum -> push_rel assum e) env ctxt
+
+end
+
+open ExtraEnv
+
(* An auxiliary function for searching for fixpoint guard indexes *)
exception Found of int array
@@ -81,7 +136,7 @@ let search_guard loc env possible_indexes fixdefs =
let fix = ((indexes, 0),fixdefs) in
(try check_fix env fix
with reraise ->
- let (e, info) = Errors.push reraise in
+ let (e, info) = CErrors.push reraise in
let info = Loc.add_loc info loc in
iraise (e, info));
indexes
@@ -91,12 +146,21 @@ let search_guard loc env possible_indexes fixdefs =
List.iter
(fun l ->
let indexes = Array.of_list l in
- let fix = ((indexes, 0),fixdefs) in
- try check_fix env fix; raise (Found indexes)
+ let fix = ((indexes, 0),fixdefs) in
+ (* spiwack: We search for a unspecified structural
+ argument under the assumption that we need to check the
+ guardedness condition (otherwise the first inductive argument
+ will be chosen). A more robust solution may be to raise an
+ error when totality is assumed but the strutural argument is
+ not specified. *)
+ try
+ let flags = { (typing_flags env) with Declarations.check_guarded = true } in
+ let env = Environ.set_typing_flags flags env in
+ check_fix env fix; raise (Found indexes)
with TypeError _ -> ())
(List.combinations possible_indexes);
let errmsg = "Cannot guess decreasing argument of fix." in
- user_err_loc (loc,"search_guard", Pp.str errmsg)
+ user_err ~loc ~hdr:"search_guard" (Pp.str errmsg)
with Found indexes -> indexes)
(* To force universe name declaration before use *)
@@ -124,7 +188,7 @@ let _ =
(** Miscellaneous interpretation functions *)
let interp_universe_level_name evd (loc,s) =
- let names, _ = Universes.global_universe_names () in
+ let names, _ = Global.global_universe_names () in
if CString.string_contains s "." then
match List.rev (CString.split '.' s) with
| [] -> anomaly (str"Invalid universe name " ++ str s)
@@ -143,12 +207,12 @@ let interp_universe_level_name evd (loc,s) =
with Not_found ->
try
let id = try Id.of_string s with _ -> raise Not_found in
- evd, Idmap.find id names
+ evd, snd (Idmap.find id names)
with Not_found ->
if not (is_strict_universe_declarations ()) then
new_univ_level_variable ~loc ~name:s univ_rigid evd
- else user_err_loc (loc, "interp_universe_level_name",
- Pp.(str "Undeclared universe: " ++ str s))
+ else user_err ~loc ~hdr:"interp_universe_level_name"
+ (Pp.(str "Undeclared universe: " ++ str s))
let interp_universe ?loc evd = function
| [] -> let evd, l = new_univ_level_variable ?loc univ_rigid evd in
@@ -175,25 +239,34 @@ let interp_elimination_sort = function
| GSet -> InSet
| GType _ -> InType
+type inference_hook = env -> evar_map -> evar -> evar_map * constr
+
type inference_flags = {
use_typeclasses : bool;
- use_unif_heuristics : bool;
- use_hook : (env -> evar_map -> evar -> constr) option;
+ solve_unification_constraints : bool;
+ use_hook : inference_hook option;
fail_evar : bool;
expand_evars : bool
}
-let frozen_holes (sigma, sigma') =
- (); fun ev -> Evar.Map.mem ev (Evd.undefined_map sigma)
-
-let pending_holes (sigma, sigma') =
- let fold evk _ accu =
- if not (Evd.mem sigma evk) then Evar.Set.add evk accu else accu
- in
- Evd.fold_undefined fold sigma' Evar.Set.empty
+(* Compute the set of still-undefined initial evars up to restriction
+ (e.g. clearing) and the set of yet-unsolved evars freshly created
+ in the extension [sigma'] of [sigma] (excluding the restrictions of
+ the undefined evars of [sigma] to be freshly created evars of
+ [sigma']). Otherwise said, we partition the undefined evars of
+ [sigma'] into those already in [sigma] or deriving from an evar in
+ [sigma] by restriction, and the evars properly created in [sigma'] *)
+
+let frozen_and_pending_holes (sigma, sigma') =
+ let add_derivative_of evk evi acc =
+ match advance sigma' evk with None -> acc | Some evk' -> Evar.Set.add evk' acc in
+ let frozen = Evd.fold_undefined add_derivative_of sigma Evar.Set.empty in
+ let fold evk _ accu = if not (Evar.Set.mem evk frozen) then Evar.Set.add evk accu else accu in
+ let pending = Evd.fold_undefined fold sigma' Evar.Set.empty in
+ (frozen,pending)
let apply_typeclasses env evdref frozen fail_evar =
- let filter_frozen = frozen in
+ let filter_frozen evk = Evar.Set.mem evk frozen in
evdref := Typeclasses.resolve_typeclasses
~filter:(if Flags.is_program_mode ()
then (fun evk evi -> Typeclasses.no_goals_or_obligations evk evi && not (filter_frozen evk))
@@ -208,7 +281,7 @@ let apply_inference_hook hook evdref pending =
if Evd.is_undefined sigma evk (* in particular not defined by side-effect *)
then
try
- let c = hook sigma evk in
+ let sigma, c = hook sigma evk in
Evd.define evk c sigma
with Exit ->
sigma
@@ -217,10 +290,10 @@ let apply_inference_hook hook evdref pending =
let apply_heuristics env evdref fail_evar =
(* Resolve eagerly, potentially making wrong choices *)
- try evdref := consider_remaining_unif_problems
+ try evdref := solve_unif_constraints_with_heuristics
~ts:(Typeclasses.classes_transparent_state ()) env !evdref
- with e when Errors.noncritical e ->
- let e = Errors.push e in if fail_evar then iraise e
+ with e when CErrors.noncritical e ->
+ let e = CErrors.push e in if fail_evar then iraise e
let check_typeclasses_instances_are_solved env current_sigma frozen =
(* Naive way, call resolution again with failure flag *)
@@ -234,7 +307,7 @@ let check_extra_evars_are_solved env current_sigma pending =
match k with
| Evar_kinds.ImplicitArg (gr, (i, id), false) -> ()
| _ ->
- error_unsolvable_implicit loc env current_sigma evk None) pending
+ error_unsolvable_implicit ~loc env current_sigma evk None) pending
(* [check_evars] fails if some unresolved evar remains *)
@@ -249,7 +322,7 @@ let check_evars env initial_sigma sigma c =
let (loc,k) = evar_source evk sigma in
match k with
| Evar_kinds.ImplicitArg (gr, (i, id), false) -> ()
- | _ -> Pretype_errors.error_unsolvable_implicit loc env sigma evk None)
+ | _ -> Pretype_errors.error_unsolvable_implicit ~loc env sigma evk None)
| _ -> Constr.iter proc_rec c
in proc_rec c
@@ -261,19 +334,17 @@ let check_evars_are_solved env current_sigma frozen pending =
(* Try typeclasses, hooks, unification heuristics ... *)
let solve_remaining_evars flags env current_sigma pending =
- let frozen = frozen_holes pending in
- let pending = pending_holes pending in
+ let frozen,pending = frozen_and_pending_holes pending in
let evdref = ref current_sigma in
if flags.use_typeclasses then apply_typeclasses env evdref frozen false;
if Option.has_some flags.use_hook then
apply_inference_hook (Option.get flags.use_hook env) evdref pending;
- if flags.use_unif_heuristics then apply_heuristics env evdref false;
+ if flags.solve_unification_constraints then apply_heuristics env evdref false;
if flags.fail_evar then check_evars_are_solved env !evdref frozen pending;
!evdref
let check_evars_are_solved env current_sigma pending =
- let frozen = frozen_holes pending in
- let pending = pending_holes pending in
+ let frozen,pending = frozen_and_pending_holes pending in
check_evars_are_solved env current_sigma frozen pending
let process_inference_flags flags env initial_sigma (sigma,c) =
@@ -284,34 +355,19 @@ let process_inference_flags flags env initial_sigma (sigma,c) =
(* Allow references to syntactically nonexistent variables (i.e., if applied on an inductive) *)
let allow_anonymous_refs = ref false
-(* Utilisé pour inférer le prédicat des Cases *)
-(* Semble exagérement fort *)
-(* Faudra préférer une unification entre les types de toutes les clauses *)
-(* et autoriser des ? à rester dans le résultat de l'unification *)
-
-let evar_type_fixpoint loc env evdref lna lar vdefj =
- let lt = Array.length vdefj in
- if Int.equal (Array.length lar) lt then
- for i = 0 to lt-1 do
- if not (e_cumul env evdref (vdefj.(i)).uj_type
- (lift lt lar.(i))) then
- error_ill_typed_rec_body_loc loc env !evdref
- i lna vdefj lar
- done
-
(* coerce to tycon if any *)
let inh_conv_coerce_to_tycon resolve_tc loc env evdref j = function
| None -> j
| Some t ->
- evd_comb2 (Coercion.inh_conv_coerce_to resolve_tc loc env) evdref j t
+ evd_comb2 (Coercion.inh_conv_coerce_to resolve_tc loc env.ExtraEnv.env) evdref j t
let check_instance loc subst = function
| [] -> ()
| (id,_) :: _ ->
if List.mem_assoc id subst then
- user_err_loc (loc,"",pr_id id ++ str "appears more than once.")
+ user_err ~loc (pr_id id ++ str "appears more than once.")
else
- user_err_loc (loc,"",str "No such variable in the signature of the existential variable: " ++ pr_id id ++ str ".")
+ user_err ~loc (str "No such variable in the signature of the existential variable: " ++ pr_id id ++ str ".")
(* used to enforce a name in Lambda when the type constraints itself
is named, hence possibly dependent *)
@@ -326,7 +382,7 @@ let ltac_interp_name { ltac_idents ; ltac_genargs } = function
try Name (Id.Map.find id ltac_idents)
with Not_found ->
if Id.Map.mem id ltac_genargs then
- errorlabstrm "" (str"Ltac variable"++spc()++ pr_id id ++
+ user_err (str"Ltac variable"++spc()++ pr_id id ++
spc()++str"is not bound to an identifier."++spc()++
str"It cannot be used in a binder.")
else n
@@ -339,22 +395,23 @@ let ltac_interp_name_env k0 lvar env =
(* tail is the part of the env enriched by pretyping *)
let n = Context.Rel.length (rel_context env) - k0 in
let ctxt,_ = List.chop n (rel_context env) in
- let env = pop_rel_context n env in
- let ctxt = List.map (Context.Rel.Declaration.map_name (ltac_interp_name lvar)) ctxt in
- push_rel_context ctxt env
+ let open Context.Rel.Declaration in
+ let ctxt' = List.smartmap (map_name (ltac_interp_name lvar)) ctxt in
+ if List.equal (fun d1 d2 -> Name.equal (get_name d1) (get_name d2)) ctxt ctxt' then env
+ else push_rel_context ctxt' (pop_rel_context n env)
let invert_ltac_bound_name lvar env id0 id =
let id' = Id.Map.find id lvar.ltac_idents in
try mkRel (pi1 (lookup_rel_id id' (rel_context env)))
with Not_found ->
- errorlabstrm "" (str "Ltac variable " ++ pr_id id0 ++
+ user_err (str "Ltac variable " ++ pr_id id0 ++
str " depends on pattern variable name " ++ pr_id id ++
str " which is not bound in current context.")
let protected_get_type_of env sigma c =
- try Retyping.get_type_of ~lax:true env sigma c
+ try Retyping.get_type_of ~lax:true env.ExtraEnv.env sigma c
with Retyping.RetypeError _ ->
- errorlabstrm ""
+ user_err
(str "Cannot reinterpret " ++ quote (print_constr c) ++
str " in the current environment.")
@@ -390,16 +447,16 @@ let pretype_id pretype k0 loc env evdref lvar id =
(* and build a nice error message *)
if Id.Map.mem id lvar.ltac_genargs then begin
let Geninterp.Val.Dyn (typ, _) = Id.Map.find id lvar.ltac_genargs in
- user_err_loc (loc,"",
- str "Variable " ++ pr_id id ++ str " should be bound to a term but is \
+ user_err ~loc
+ (str "Variable " ++ pr_id id ++ str " should be bound to a term but is \
bound to a " ++ Geninterp.Val.pr typ ++ str ".")
end;
(* Check if [id] is a section or goal variable *)
try
- { uj_val = mkVar id; uj_type = (get_type (lookup_named id env)) }
+ { uj_val = mkVar id; uj_type = NamedDecl.get_type (lookup_named id env) }
with Not_found ->
(* [id] not found, standard error message *)
- error_var_not_found_loc loc id
+ error_var_not_found ~loc id
let evar_kind_of_term sigma c =
kind_of_term (whd_evar sigma c)
@@ -422,35 +479,35 @@ let pretype_global loc rigid env evd gr us =
let arr = Univ.Instance.to_array (Univ.UContext.instance ctx) in
let len = Array.length arr in
if len != List.length l then
- user_err_loc (loc, "pretype",
- str "Universe instance should have length " ++ int len)
+ user_err ~loc ~hdr:"pretype"
+ (str "Universe instance should have length " ++ int len)
else
let evd, l' = List.fold_left (fun (evd, univs) l ->
let evd, l = interp_universe_level_name loc evd l in
(evd, l :: univs)) (evd, []) l
in
if List.exists (fun l -> Univ.Level.is_prop l) l' then
- user_err_loc (loc, "pretype",
- str "Universe instances cannot contain Prop, polymorphic" ++
+ user_err ~loc ~hdr:"pretype"
+ (str "Universe instances cannot contain Prop, polymorphic" ++
str " universe instances must be greater or equal to Set.");
evd, Some (Univ.Instance.of_array (Array.of_list (List.rev l')))
in
- Evd.fresh_global ~loc ~rigid ?names:instance env evd gr
+ Evd.fresh_global ~loc ~rigid ?names:instance env.ExtraEnv.env evd gr
let pretype_ref loc evdref env ref us =
match ref with
| VarRef id ->
(* Section variable *)
- (try make_judge (mkVar id) (get_type (lookup_named id env))
+ (try make_judge (mkVar id) (NamedDecl.get_type (lookup_named id env))
with Not_found ->
(* This may happen if env is a goal env and section variables have
been cleared - section variables should be different from goal
variables *)
- Pretype_errors.error_var_not_found_loc loc id)
+ Pretype_errors.error_var_not_found ~loc id)
| ref ->
let evd, c = pretype_global loc univ_flexible env !evdref ref us in
let () = evdref := evd in
- let ty = Typing.unsafe_type_of env evd c in
+ let ty = Typing.unsafe_type_of env.ExtraEnv.env evd c in
make_judge c ty
let judge_of_Type loc evd s =
@@ -468,7 +525,7 @@ let pretype_sort loc evdref = function
let new_type_evar env evdref loc =
let sigma = Sigma.Unsafe.of_evar_map !evdref in
let Sigma ((e, _), sigma, _) =
- Evarutil.new_type_evar env sigma
+ Evarutil.new_type_evar env.ExtraEnv.env sigma
univ_flexible_alg ~src:(loc,Evar_kinds.InternalHole)
in
evdref := Sigma.to_evar_map sigma;
@@ -480,7 +537,7 @@ let (f_genarg_interp, genarg_interp_hook) = Hook.make ()
(* in environment [env], with existential variables [evdref] and *)
(* the type constraint tycon *)
-let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_var_map) t =
+let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdref (lvar : ltac_var_map) t =
let inh_conv_coerce_to_tycon = inh_conv_coerce_to_tycon resolve_tc in
let pretype_type = pretype_type k0 resolve_tc in
let pretype = pretype k0 resolve_tc in
@@ -502,11 +559,11 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
let evk =
try Evd.evar_key id !evdref
with Not_found ->
- user_err_loc (loc,"",str "Unknown existential variable.") in
+ user_err ~loc (str "Unknown existential variable.") in
let hyps = evar_filtered_context (Evd.find !evdref evk) in
let args = pretype_instance k0 resolve_tc env evdref lvar loc hyps evk inst in
let c = mkEvar (evk, args) in
- let j = (Retyping.get_judgment_of env !evdref c) in
+ let j = (Retyping.get_judgment_of env.ExtraEnv.env !evdref c) in
inh_conv_coerce_to_tycon loc env evdref j tycon
| GPatVar (loc,(someta,n)) ->
@@ -535,7 +592,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
| None ->
new_type_evar env evdref loc in
let ist = lvar.ltac_genargs in
- let (c, sigma) = Hook.get f_genarg_interp ty env !evdref ist arg in
+ let (c, sigma) = Hook.get f_genarg_interp ty env.ExtraEnv.env !evdref ist arg in
let () = evdref := sigma in
{ uj_val = c; uj_type = ty }
@@ -569,7 +626,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
let fixi = match fixkind with
| GFix (vn,i) -> i
| GCoFix i -> i
- in e_conv env evdref ftys.(fixi) t
+ in e_conv env.ExtraEnv.env evdref ftys.(fixi) t
| None -> true
in
(* Note: bodies are not used by push_rec_types, so [||] is safe *)
@@ -587,7 +644,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
{ uj_val = it_mkLambda_or_LetIn j.uj_val ctxt;
uj_type = it_mkProd_or_LetIn j.uj_type ctxt })
ctxtv vdef in
- evar_type_fixpoint loc env evdref names ftys vdefj;
+ Typing.check_type_fixpoint loc env.ExtraEnv.env evdref names ftys vdefj;
let ftys = Array.map (nf_evar !evdref) ftys in
let fdefs = Array.map (fun x -> nf_evar !evdref (j_val x)) vdefj in
let fixj = match fixkind with
@@ -606,13 +663,16 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
vn)
in
let fixdecls = (names,ftys,fdefs) in
- let indexes = search_guard loc env possible_indexes fixdecls in
+ let indexes =
+ search_guard
+ loc env.ExtraEnv.env possible_indexes fixdecls
+ in
make_judge (mkFix ((indexes,i),fixdecls)) ftys.(i)
| GCoFix i ->
let cofix = (i,(names,ftys,fdefs)) in
- (try check_cofix env cofix
+ (try check_cofix env.ExtraEnv.env cofix
with reraise ->
- let (e, info) = Errors.push reraise in
+ let (e, info) = CErrors.push reraise in
let info = Loc.add_loc info loc in
iraise (e, info));
make_judge (mkCoFix cofix) ftys.(i)
@@ -640,7 +700,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
if Int.equal npars 0 then []
else
try
- let IndType (indf, args) = find_rectype env !evdref ty in
+ let IndType (indf, args) = find_rectype env.ExtraEnv.env !evdref ty in
let ((ind',u'),pars) = dest_ind_family indf in
if eq_ind ind ind' then pars
else (* Let the usual code throw an error *) []
@@ -649,9 +709,9 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
in
let app_f =
match kind_of_term fj.uj_val with
- | Const (p, u) when Environ.is_projection p env ->
+ | Const (p, u) when Environ.is_projection p env.ExtraEnv.env ->
let p = Projection.make p false in
- let pb = Environ.lookup_projection p env in
+ let pb = Environ.lookup_projection p env.ExtraEnv.env in
let npars = pb.Declarations.proj_npars in
fun n ->
if n == npars + 1 then fun _ v -> mkProj (p, v)
@@ -662,8 +722,8 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
| [] -> resj
| c::rest ->
let argloc = loc_of_glob_constr c in
- let resj = evd_comb1 (Coercion.inh_app_fun resolve_tc env) evdref resj in
- let resty = whd_betadeltaiota env !evdref resj.uj_type in
+ let resj = evd_comb1 (Coercion.inh_app_fun resolve_tc env.ExtraEnv.env) evdref resj in
+ let resty = whd_all env.ExtraEnv.env !evdref resj.uj_type in
match kind_of_term resty with
| Prod (na,c1,c2) ->
let tycon = Some c1 in
@@ -672,7 +732,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
match candargs with
| [] -> [], j_val hj
| arg :: args ->
- if e_conv env evdref (j_val hj) arg then
+ if e_conv env.ExtraEnv.env evdref (j_val hj) arg then
args, nf_evar !evdref (j_val hj)
else [], j_val hj
in
@@ -682,22 +742,22 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
| _ ->
let hj = pretype empty_tycon env evdref lvar c in
- error_cant_apply_not_functional_loc
- (Loc.merge floc argloc) env !evdref
- resj [hj]
+ error_cant_apply_not_functional
+ ~loc:(Loc.merge floc argloc) env.ExtraEnv.env !evdref
+ resj [hj]
in
let resj = apply_rec env 1 fj candargs args in
let resj =
match evar_kind_of_term !evdref resj.uj_val with
| App (f,args) ->
let f = whd_evar !evdref f in
- if is_template_polymorphic env f then
+ if is_template_polymorphic env.ExtraEnv.env f then
(* Special case for inductive type applications that must be
refreshed right away. *)
let sigma = !evdref in
let c = mkApp (f,Array.map (whd_evar sigma) args) in
- let c = evd_comb1 (Evarsolve.refresh_universes (Some true) env) evdref c in
- let t = Retyping.get_type_of env !evdref c in
+ let c = evd_comb1 (Evarsolve.refresh_universes (Some true) env.ExtraEnv.env) evdref c in
+ let t = Retyping.get_type_of env.ExtraEnv.env !evdref c in
make_judge c (* use this for keeping evars: resj.uj_val *) t
else resj
| _ -> resj
@@ -710,11 +770,11 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
match tycon with
| None -> evd, tycon
| Some ty ->
- let evd, ty' = Coercion.inh_coerce_to_prod loc env evd ty in
+ let evd, ty' = Coercion.inh_coerce_to_prod loc env.ExtraEnv.env evd ty in
evd, Some ty')
evdref tycon
in
- let (name',dom,rng) = evd_comb1 (split_tycon loc env) evdref tycon' in
+ let (name',dom,rng) = evd_comb1 (split_tycon loc env.ExtraEnv.env) evdref tycon' in
let dom_valcon = valcon_of_tycon dom in
let j = pretype_type dom_valcon env evdref lvar c1 in
(* The name specified by ltac is used also to create bindings. So
@@ -723,7 +783,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
let var = LocalAssum (name, j.utj_val) in
let j' = pretype rng (push_rel var env) evdref lvar c2 in
let name = ltac_interp_name lvar name in
- let resj = judge_of_abstraction env (orelse_name name name') j j' in
+ let resj = judge_of_abstraction env.ExtraEnv.env (orelse_name name name') j j' in
inh_conv_coerce_to_tycon loc env evdref resj tycon
| GProd(loc,name,bk,c1,c2) ->
@@ -736,16 +796,16 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
let j = pretype_type empty_valcon env evdref lvar c2 in
{ j with utj_val = lift 1 j.utj_val }
| Name _ ->
- let var = (name,j.utj_val) in
- let env' = push_rel_assum var env in
+ let var = LocalAssum (name, j.utj_val) in
+ let env' = push_rel var env in
pretype_type empty_valcon env' evdref lvar c2
in
let name = ltac_interp_name lvar name in
let resj =
try
- judge_of_product env name j j'
+ judge_of_product env.ExtraEnv.env name j j'
with TypeError _ as e ->
- let (e, info) = Errors.push e in
+ let (e, info) = CErrors.push e in
let info = Loc.add_loc info loc in
iraise (e, info) in
inh_conv_coerce_to_tycon loc env evdref resj tycon
@@ -759,7 +819,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
| _ -> pretype empty_tycon env evdref lvar c1
in
let t = evd_comb1 (Evarsolve.refresh_universes
- ~onlyalg:true ~status:Evd.univ_flexible (Some false) env)
+ ~onlyalg:true ~status:Evd.univ_flexible (Some false) env.ExtraEnv.env)
evdref j.uj_type in
(* The name specified by ltac is used also to create bindings. So
the substitution must also be applied on variables before they are
@@ -774,21 +834,21 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
| GLetTuple (loc,nal,(na,po),c,d) ->
let cj = pretype empty_tycon env evdref lvar c in
let (IndType (indf,realargs)) =
- try find_rectype env !evdref cj.uj_type
+ try find_rectype env.ExtraEnv.env !evdref cj.uj_type
with Not_found ->
let cloc = loc_of_glob_constr c in
- error_case_not_inductive_loc cloc env !evdref cj
+ error_case_not_inductive ~loc:cloc env.ExtraEnv.env !evdref cj
in
- let cstrs = get_constructors env indf in
+ let cstrs = get_constructors env.ExtraEnv.env indf in
if not (Int.equal (Array.length cstrs) 1) then
- user_err_loc (loc,"",str "Destructing let is only for inductive types" ++
+ user_err ~loc (str "Destructing let is only for inductive types" ++
str " with one constructor.");
let cs = cstrs.(0) in
if not (Int.equal (List.length nal) cs.cs_nargs) then
- user_err_loc (loc,"", str "Destructing let on this type expects " ++
+ user_err ~loc:loc (str "Destructing let on this type expects " ++
int cs.cs_nargs ++ str " variables.");
let fsign, record =
- match get_projections env indf with
+ match get_projections env.ExtraEnv.env indf with
| None ->
List.map2 set_name (List.rev nal) cs.cs_args, false
| Some ps ->
@@ -809,36 +869,36 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
let nal = List.rev nal in
let fsign = List.map2 set_name nal fsign in
let f = it_mkLambda_or_LetIn f fsign in
- let ci = make_case_info env (fst ind) LetStyle in
+ let ci = make_case_info env.ExtraEnv.env (fst ind) LetStyle in
mkCase (ci, p, cj.uj_val,[|f|])
else it_mkLambda_or_LetIn f fsign
in
let env_f = push_rel_context fsign env in
(* Make dependencies from arity signature impossible *)
let arsgn =
- let arsgn,_ = get_arity env indf in
+ let arsgn,_ = get_arity env.ExtraEnv.env indf in
if not !allow_anonymous_refs then
List.map (set_name Anonymous) arsgn
else arsgn
in
- let psign = LocalAssum (na, build_dependent_inductive env indf) :: arsgn in
+ let psign = LocalAssum (na, build_dependent_inductive env.ExtraEnv.env indf) :: arsgn in
let nar = List.length arsgn in
(match po with
| Some p ->
let env_p = push_rel_context psign env in
let pj = pretype_type empty_valcon env_p evdref lvar p in
let ccl = nf_evar !evdref pj.utj_val in
- let psign = make_arity_signature env true indf in (* with names *)
+ let psign = make_arity_signature env.ExtraEnv.env true indf in (* with names *)
let p = it_mkLambda_or_LetIn ccl psign in
let inst =
(Array.to_list cs.cs_concl_realargs)
@[build_dependent_constructor cs] in
let lp = lift cs.cs_nargs p in
- let fty = hnf_lam_applist env !evdref lp inst in
+ let fty = hnf_lam_applist env.ExtraEnv.env !evdref lp inst in
let fj = pretype (mk_tycon fty) env_f evdref lvar d in
let v =
let ind,_ = dest_ind_family indf in
- Typing.check_allowed_sort env !evdref ind cj.uj_val p;
+ Typing.check_allowed_sort env.ExtraEnv.env !evdref ind cj.uj_val p;
obj ind p cj.uj_val fj.uj_val
in
{ uj_val = v; uj_type = substl (realargs@[cj.uj_val]) ccl }
@@ -851,37 +911,37 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
if noccur_between 1 cs.cs_nargs ccl then
lift (- cs.cs_nargs) ccl
else
- error_cant_find_case_type_loc loc env !evdref
+ error_cant_find_case_type ~loc env.ExtraEnv.env !evdref
cj.uj_val in
(* let ccl = refresh_universes ccl in *)
let p = it_mkLambda_or_LetIn (lift (nar+1) ccl) psign in
let v =
let ind,_ = dest_ind_family indf in
- Typing.check_allowed_sort env !evdref ind cj.uj_val p;
+ Typing.check_allowed_sort env.ExtraEnv.env !evdref ind cj.uj_val p;
obj ind p cj.uj_val fj.uj_val
in { uj_val = v; uj_type = ccl })
| GIf (loc,c,(na,po),b1,b2) ->
let cj = pretype empty_tycon env evdref lvar c in
let (IndType (indf,realargs)) =
- try find_rectype env !evdref cj.uj_type
+ try find_rectype env.ExtraEnv.env !evdref cj.uj_type
with Not_found ->
let cloc = loc_of_glob_constr c in
- error_case_not_inductive_loc cloc env !evdref cj in
- let cstrs = get_constructors env indf in
+ error_case_not_inductive ~loc:cloc env.ExtraEnv.env !evdref cj in
+ let cstrs = get_constructors env.ExtraEnv.env indf in
if not (Int.equal (Array.length cstrs) 2) then
- user_err_loc (loc,"",
- str "If is only for inductive types with two constructors.");
+ user_err ~loc
+ (str "If is only for inductive types with two constructors.");
let arsgn =
- let arsgn,_ = get_arity env indf in
+ let arsgn,_ = get_arity env.ExtraEnv.env indf in
if not !allow_anonymous_refs then
(* Make dependencies from arity signature impossible *)
List.map (set_name Anonymous) arsgn
else arsgn
in
let nar = List.length arsgn in
- let psign = LocalAssum (na, build_dependent_inductive env indf) :: arsgn in
+ let psign = LocalAssum (na, build_dependent_inductive env.ExtraEnv.env indf) :: arsgn in
let pred,p = match po with
| Some p ->
let env_p = push_rel_context psign env in
@@ -919,9 +979,9 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
let b2 = f cstrs.(1) b2 in
let v =
let ind,_ = dest_ind_family indf in
- let ci = make_case_info env (fst ind) IfStyle in
+ let ci = make_case_info env.ExtraEnv.env (fst ind) IfStyle in
let pred = nf_evar !evdref pred in
- Typing.check_allowed_sort env !evdref ind cj.uj_val pred;
+ Typing.check_allowed_sort env.ExtraEnv.env !evdref ind cj.uj_val pred;
mkCase (ci, pred, cj.uj_val, [|b1;b2|])
in
let cj = { uj_val = v; uj_type = p } in
@@ -929,43 +989,46 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
| GCases (loc,sty,po,tml,eqns) ->
Cases.compile_cases loc sty
- ((fun vtyc env evdref -> pretype vtyc env evdref lvar),evdref)
- tycon env (* loc *) (po,tml,eqns)
+ ((fun vtyc env evdref -> pretype vtyc (make_env env) evdref lvar),evdref)
+ tycon env.ExtraEnv.env (* loc *) (po,tml,eqns)
| GCast (loc,c,k) ->
let cj =
match k with
| CastCoerce ->
let cj = pretype empty_tycon env evdref lvar c in
- evd_comb1 (Coercion.inh_coerce_to_base loc env) evdref cj
+ evd_comb1 (Coercion.inh_coerce_to_base loc env.ExtraEnv.env) evdref cj
| CastConv t | CastVM t | CastNative t ->
let k = (match k with CastVM _ -> VMcast | CastNative _ -> NATIVEcast | _ -> DEFAULTcast) in
let tj = pretype_type empty_valcon env evdref lvar t in
- let tval = nf_evar !evdref tj.utj_val in
- let cj = match k with
+ let tval = evd_comb1 (Evarsolve.refresh_universes
+ ~onlyalg:true ~status:Evd.univ_flexible (Some false) env.ExtraEnv.env)
+ evdref tj.utj_val in
+ let tval = nf_evar !evdref tval in
+ let cj, tval = match k with
| VMcast ->
let cj = pretype empty_tycon env evdref lvar c in
- let cty = nf_evar !evdref cj.uj_type and tval = nf_evar !evdref tj.utj_val in
+ let cty = nf_evar !evdref cj.uj_type and tval = nf_evar !evdref tval in
if not (occur_existential cty || occur_existential tval) then
- let (evd,b) = Reductionops.vm_infer_conv env !evdref cty tval in
- if b then (evdref := evd; cj)
+ let (evd,b) = Reductionops.vm_infer_conv env.ExtraEnv.env !evdref cty tval in
+ if b then (evdref := evd; cj, tval)
else
- error_actual_type_loc loc env !evdref cj tval
- (ConversionFailed (env,cty,tval))
- else user_err_loc (loc,"",str "Cannot check cast with vm: " ++
+ error_actual_type ~loc env.ExtraEnv.env !evdref cj tval
+ (ConversionFailed (env.ExtraEnv.env,cty,tval))
+ else user_err ~loc (str "Cannot check cast with vm: " ++
str "unresolved arguments remain.")
| NATIVEcast ->
let cj = pretype empty_tycon env evdref lvar c in
- let cty = nf_evar !evdref cj.uj_type and tval = nf_evar !evdref tj.utj_val in
+ let cty = nf_evar !evdref cj.uj_type and tval = nf_evar !evdref tval in
begin
- let (evd,b) = Nativenorm.native_infer_conv env !evdref cty tval in
- if b then (evdref := evd; cj)
+ let (evd,b) = Nativenorm.native_infer_conv env.ExtraEnv.env !evdref cty tval in
+ if b then (evdref := evd; cj, tval)
else
- error_actual_type_loc loc env !evdref cj tval
- (ConversionFailed (env,cty,tval))
+ error_actual_type ~loc env.ExtraEnv.env !evdref cj tval
+ (ConversionFailed (env.ExtraEnv.env,cty,tval))
end
| _ ->
- pretype (mk_tycon tval) env evdref lvar c
+ pretype (mk_tycon tval) env evdref lvar c, tval
in
let v = mkCast (cj.uj_val, k, tval) in
{ uj_val = v; uj_type = tval }
@@ -973,8 +1036,8 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
and pretype_instance k0 resolve_tc env evdref lvar loc hyps evk update =
let f decl (subst,update) =
- let id = get_id decl in
- let t = replace_vars subst (get_type decl) in
+ let id = NamedDecl.get_id decl in
+ let t = replace_vars subst (NamedDecl.get_type decl) in
let c, update =
try
let c = List.assoc id update in
@@ -983,13 +1046,13 @@ and pretype_instance k0 resolve_tc env evdref lvar loc hyps evk update =
with Not_found ->
try
let (n,_,t') = lookup_rel_id id (rel_context env) in
- if is_conv env !evdref t t' then mkRel n, update else raise Not_found
+ if is_conv env.ExtraEnv.env !evdref t t' then mkRel n, update else raise Not_found
with Not_found ->
try
- let t' = lookup_named id env |> get_type in
- if is_conv env !evdref t t' then mkVar id, update else raise Not_found
+ let t' = env |> lookup_named id |> NamedDecl.get_type in
+ if is_conv env.ExtraEnv.env !evdref t t' then mkVar id, update else raise Not_found
with Not_found ->
- user_err_loc (loc,"",str "Cannot interpret " ++
+ user_err ~loc (str "Cannot interpret " ++
pr_existential_key !evdref evk ++
str " in current context: no binding for " ++ pr_id id ++ str ".") in
((id,c)::subst, update) in
@@ -998,17 +1061,17 @@ and pretype_instance k0 resolve_tc env evdref lvar loc hyps evk update =
Array.map_of_list snd subst
(* [pretype_type valcon env evdref lvar c] coerces [c] into a type *)
-and pretype_type k0 resolve_tc valcon env evdref lvar = function
+and pretype_type k0 resolve_tc valcon (env : ExtraEnv.t) evdref lvar = function
| GHole (loc, knd, naming, None) ->
(match valcon with
| Some v ->
let s =
let sigma = !evdref in
- let t = Retyping.get_type_of env sigma v in
- match kind_of_term (whd_betadeltaiota env sigma t) with
+ let t = Retyping.get_type_of env.ExtraEnv.env sigma v in
+ match kind_of_term (whd_all env.ExtraEnv.env sigma t) with
| Sort s -> s
| Evar ev when is_Type (existential_type sigma ev) ->
- evd_comb1 (define_evar_as_sort env) evdref ev
+ evd_comb1 (define_evar_as_sort env.ExtraEnv.env) evdref ev
| _ -> anomaly (Pp.str "Found a type constraint which is not a type")
in
{ utj_val = v;
@@ -1021,16 +1084,17 @@ and pretype_type k0 resolve_tc valcon env evdref lvar = function
| c ->
let j = pretype k0 resolve_tc empty_tycon env evdref lvar c in
let loc = loc_of_glob_constr c in
- let tj = evd_comb1 (Coercion.inh_coerce_to_sort loc env) evdref j in
+ let tj = evd_comb1 (Coercion.inh_coerce_to_sort loc env.ExtraEnv.env) evdref j in
match valcon with
| None -> tj
| Some v ->
- if e_cumul env evdref v tj.utj_val then tj
+ if e_cumul env.ExtraEnv.env evdref v tj.utj_val then tj
else
- error_unexpected_type_loc
- (loc_of_glob_constr c) env !evdref tj.utj_val v
+ error_unexpected_type
+ ~loc:(loc_of_glob_constr c) env.ExtraEnv.env !evdref tj.utj_val v
let ise_pretype_gen flags env sigma lvar kind c =
+ let env = make_env env in
let evdref = ref sigma in
let k0 = Context.Rel.length (rel_context env) in
let c' = match kind with
@@ -1041,18 +1105,18 @@ let ise_pretype_gen flags env sigma lvar kind c =
| IsType ->
(pretype_type k0 flags.use_typeclasses empty_valcon env evdref lvar c).utj_val
in
- process_inference_flags flags env sigma (!evdref,c')
+ process_inference_flags flags env.ExtraEnv.env sigma (!evdref,c')
let default_inference_flags fail = {
use_typeclasses = true;
- use_unif_heuristics = true;
+ solve_unification_constraints = true;
use_hook = None;
fail_evar = fail;
expand_evars = true }
let no_classes_no_fail_inference_flags = {
use_typeclasses = false;
- use_unif_heuristics = true;
+ solve_unification_constraints = true;
use_hook = None;
fail_evar = false;
expand_evars = true }
@@ -1073,19 +1137,21 @@ let on_judgment f j =
{uj_val = c; uj_type = t}
let understand_judgment env sigma c =
+ let env = make_env env in
let evdref = ref sigma in
let k0 = Context.Rel.length (rel_context env) in
let j = pretype k0 true empty_tycon env evdref empty_lvar c in
let j = on_judgment (fun c ->
- let evd, c = process_inference_flags all_and_fail_flags env sigma (!evdref,c) in
+ let evd, c = process_inference_flags all_and_fail_flags env.ExtraEnv.env sigma (!evdref,c) in
evdref := evd; c) j
in j, Evd.evar_universe_context !evdref
let understand_judgment_tcc env evdref c =
+ let env = make_env env in
let k0 = Context.Rel.length (rel_context env) in
let j = pretype k0 true empty_tycon env evdref empty_lvar c in
on_judgment (fun c ->
- let (evd,c) = process_inference_flags all_no_fail_flags env Evd.empty (!evdref,c) in
+ let (evd,c) = process_inference_flags all_no_fail_flags env.ExtraEnv.env Evd.empty (!evdref,c) in
evdref := evd; c) j
let ise_pretype_gen_ctx flags env sigma lvar kind c =
@@ -1114,7 +1180,7 @@ let understand_ltac flags env sigma lvar kind c =
let constr_flags = {
use_typeclasses = true;
- use_unif_heuristics = true;
+ solve_unification_constraints = true;
use_hook = None;
fail_evar = true;
expand_evars = true }
@@ -1134,3 +1200,9 @@ let type_uconstr ?(flags = constr_flags)
let (sigma, c) = understand_ltac flags env sigma vars expected_type term in
Sigma.Unsafe.of_pair (c, sigma)
end }
+
+let pretype k0 resolve_tc typcon env evdref lvar t =
+ pretype k0 resolve_tc typcon (make_env env) evdref lvar t
+
+let pretype_type k0 resolve_tc valcon env evdref lvar t =
+ pretype_type k0 resolve_tc valcon (make_env env) evdref lvar t
diff --git a/pretyping/pretyping.mli b/pretyping/pretyping.mli
index 824bb11aa4..2c6aa7a21b 100644
--- a/pretyping/pretyping.mli
+++ b/pretyping/pretyping.mli
@@ -47,17 +47,16 @@ val empty_lvar : ltac_var_map
type glob_constr_ltac_closure = ltac_var_map * glob_constr
type pure_open_constr = evar_map * constr
+type inference_hook = env -> evar_map -> evar -> evar_map * constr
+
type inference_flags = {
use_typeclasses : bool;
- use_unif_heuristics : bool;
- use_hook : (env -> evar_map -> evar -> constr) option;
+ solve_unification_constraints : bool;
+ use_hook : inference_hook option;
fail_evar : bool;
expand_evars : bool
}
-type 'a delayed_open =
- { delayed : 'r. Environ.env -> 'r Sigma.t -> ('a, 'r) Sigma.sigma }
-
val default_inference_flags : bool -> inference_flags
val no_classes_no_fail_inference_flags : inference_flags
@@ -120,7 +119,7 @@ val understand_judgment_tcc : env -> evar_map ref ->
val type_uconstr :
?flags:inference_flags ->
?expected_type:typing_constraint ->
- Geninterp.interp_sign -> Glob_term.closed_glob_constr -> constr delayed_open
+ Geninterp.interp_sign -> Glob_term.closed_glob_constr -> constr Tactypes.delayed_open
(** Trying to solve remaining evars and remaining conversion problems
possibly using type classes, heuristics, external tactic solver
diff --git a/pretyping/program.ml b/pretyping/program.ml
index 0bd121f6f1..4b6137b539 100644
--- a/pretyping/program.ml
+++ b/pretyping/program.ml
@@ -7,7 +7,7 @@
(************************************************************************)
open Pp
-open Errors
+open CErrors
open Util
open Names
open Term
@@ -15,10 +15,12 @@ open Term
let make_dir l = DirPath.make (List.rev_map Id.of_string l)
let find_reference locstr dir s =
- let sp = Libnames.make_path (make_dir dir) (Id.of_string s) in
+ let dp = make_dir dir in
+ let sp = Libnames.make_path dp (Id.of_string s) in
try Nametab.global_of_path sp
with Not_found ->
- anomaly ~label:locstr (Pp.str "cannot find" ++ spc () ++ Libnames.pr_path sp)
+ user_err (str "Library " ++ Libnames.pr_dirpath dp ++
+ str " has to be required first.")
let coq_reference locstr dir s = find_reference locstr ("Coq"::dir) s
let coq_constant locstr dir s = Universes.constr_of_global (coq_reference locstr dir s)
@@ -67,3 +69,43 @@ let mk_coq_and l =
(fun c conj ->
mkApp (and_typ, [| c ; conj |]))
l
+
+(* true = transparent by default, false = opaque if possible *)
+let proofs_transparency = ref true
+let program_cases = ref true
+let program_generalized_coercion = ref true
+
+let set_proofs_transparency = (:=) proofs_transparency
+let get_proofs_transparency () = !proofs_transparency
+
+let is_program_generalized_coercion () = !program_generalized_coercion
+let is_program_cases () = !program_cases
+
+open Goptions
+
+let _ =
+ declare_bool_option
+ { optsync = true;
+ optdepr = false;
+ optname = "preferred transparency of Program obligations";
+ optkey = ["Transparent";"Obligations"];
+ optread = get_proofs_transparency;
+ optwrite = set_proofs_transparency; }
+
+let _ =
+ declare_bool_option
+ { optsync = true;
+ optdepr = false;
+ optname = "program cases";
+ optkey = ["Program";"Cases"];
+ optread = (fun () -> !program_cases);
+ optwrite = (:=) program_cases }
+
+let _ =
+ declare_bool_option
+ { optsync = true;
+ optdepr = false;
+ optname = "program generalized coercion";
+ optkey = ["Program";"Generalized";"Coercion"];
+ optread = (fun () -> !program_generalized_coercion);
+ optwrite = (:=) program_generalized_coercion }
diff --git a/pretyping/program.mli b/pretyping/program.mli
index b7ebcbc95c..023ff8ca58 100644
--- a/pretyping/program.mli
+++ b/pretyping/program.mli
@@ -37,3 +37,7 @@ val mk_coq_not : constr -> constr
(** Polymorphic application of delayed references *)
val papp : Evd.evar_map ref -> (unit -> global_reference) -> constr array -> constr
+
+val get_proofs_transparency : unit -> bool
+val is_program_cases : unit -> bool
+val is_program_generalized_coercion : unit -> bool
diff --git a/pretyping/recordops.ml b/pretyping/recordops.ml
index bbb6a92663..cda052b796 100644
--- a/pretyping/recordops.ml
+++ b/pretyping/recordops.ml
@@ -13,7 +13,7 @@
(* This file registers properties of records: projections and
canonical structures *)
-open Errors
+open CErrors
open Util
open Pp
open Names
@@ -176,7 +176,7 @@ let cs_pattern_of_constr t =
App (f,vargs) ->
begin
try Const_cs (global_of_constr f) , None, Array.to_list vargs
- with e when Errors.noncritical e -> raise Not_found
+ with e when CErrors.noncritical e -> raise Not_found
end
| Rel n -> Default_cs, Some n, []
| Prod (_,a,b) when not (Termops.dependent (mkRel 1) b) -> Prod_cs, None, [a; Termops.pop b]
@@ -184,11 +184,18 @@ let cs_pattern_of_constr t =
| _ ->
begin
try Const_cs (global_of_constr t) , None, []
- with e when Errors.noncritical e -> raise Not_found
+ with e when CErrors.noncritical e -> raise Not_found
end
+let warn_projection_no_head_constant =
+ CWarnings.create ~name:"projection-no-head-constant" ~category:"typechecker"
+ (fun (t,con_pp,proji_sp_pp) ->
+ strbrk "Projection value has no head constant: "
+ ++ Termops.print_constr t ++ strbrk " in canonical instance "
+ ++ con_pp ++ str " of " ++ proji_sp_pp ++ strbrk ", ignoring it.")
+
(* Intended to always succeed *)
-let compute_canonical_projections (con,ind) =
+let compute_canonical_projections warn (con,ind) =
let env = Global.env () in
let ctx = Univ.instantiate_univ_context (Environ.constant_context env con) in
let u = Univ.UContext.instance ctx in
@@ -213,13 +220,10 @@ let compute_canonical_projections (con,ind) =
let patt, n , args = cs_pattern_of_constr t in
((ConstRef proji_sp, patt, t, n, args) :: l)
with Not_found ->
- if Flags.is_verbose () then
- (let con_pp = Nametab.pr_global_env Id.Set.empty (ConstRef con)
+ let con_pp = Nametab.pr_global_env Id.Set.empty (ConstRef con)
and proji_sp_pp = Nametab.pr_global_env Id.Set.empty (ConstRef proji_sp) in
- Feedback.msg_warning (strbrk "No global reference exists for projection value"
- ++ Termops.print_constr t ++ strbrk " in instance "
- ++ con_pp ++ str " of " ++ proji_sp_pp ++ strbrk ", ignoring it."));
- l
+ if warn then warn_projection_no_head_constant (t,con_pp,proji_sp_pp);
+ l
end
| _ -> l)
[] lps in
@@ -235,9 +239,15 @@ let pr_cs_pattern = function
| Default_cs -> str "_"
| Sort_cs s -> Termops.pr_sort_family s
-let open_canonical_structure i (_,o) =
- if Int.equal i 1 then
- let lo = compute_canonical_projections o in
+let warn_redundant_canonical_projection =
+ CWarnings.create ~name:"redundant-canonical-projection" ~category:"typechecker"
+ (fun (hd_val,prj,new_can_s,old_can_s) ->
+ strbrk "Ignoring canonical projection to " ++ hd_val
+ ++ strbrk " by " ++ prj ++ strbrk " in "
+ ++ new_can_s ++ strbrk ": redundant with " ++ old_can_s)
+
+let add_canonical_structure warn o =
+ let lo = compute_canonical_projections warn o in
List.iter (fun ((proj,(cs_pat,_ as pat)),s) ->
let l = try Refmap.find proj !object_table with Not_found -> [] in
let ocs = try Some (assoc_pat cs_pat l)
@@ -245,17 +255,18 @@ let open_canonical_structure i (_,o) =
in match ocs with
| None -> object_table := Refmap.add proj ((pat,s)::l) !object_table;
| Some (c, cs) ->
- if Flags.is_verbose () then
let old_can_s = (Termops.print_constr cs.o_DEF)
and new_can_s = (Termops.print_constr s.o_DEF) in
let prj = (Nametab.pr_global_env Id.Set.empty proj)
and hd_val = (pr_cs_pattern cs_pat) in
- Feedback.msg_warning (strbrk "Ignoring canonical projection to " ++ hd_val
- ++ strbrk " by " ++ prj ++ strbrk " in "
- ++ new_can_s ++ strbrk ": redundant with " ++ old_can_s)) lo
+ if warn then warn_redundant_canonical_projection (hd_val,prj,new_can_s,old_can_s))
+ lo
+
+let open_canonical_structure i (_, o) =
+ if Int.equal i 1 then add_canonical_structure false o
-let cache_canonical_structure o =
- open_canonical_structure 1 o
+let cache_canonical_structure (_, o) =
+ add_canonical_structure true o
let subst_canonical_structure (subst,(cst,ind as obj)) =
(* invariant: cst is an evaluable reference. Thus we can take *)
@@ -280,7 +291,7 @@ let add_canonical_structure x = Lib.add_anonymous_leaf (inCanonStruc x)
(*s High-level declaration of a canonical structure *)
let error_not_structure ref =
- errorlabstrm "object_declare"
+ user_err ~hdr:"object_declare"
(Nameops.pr_id (basename_of_global ref) ++ str" is not a structure object.")
let check_and_decompose_canonical_structure ref =
@@ -317,7 +328,7 @@ let is_open_canonical_projection env sigma (c,args) =
(** Check if there is some canonical projection attached to this structure *)
let _ = Refmap.find ref !object_table in
try
- let arg = whd_betadeltaiota env sigma (Stack.nth args n) in
+ let arg = whd_all env sigma (Stack.nth args n) in
let hd = match kind_of_term arg with App (hd, _) -> hd | _ -> arg in
not (isConstruct hd)
with Failure _ -> false
diff --git a/pretyping/redops.ml b/pretyping/redops.ml
index c188995a84..7d65925e57 100644
--- a/pretyping/redops.ml
+++ b/pretyping/redops.ml
@@ -14,25 +14,29 @@ let make_red_flag l =
let rec add_flag red = function
| [] -> red
| FBeta :: lf -> add_flag { red with rBeta = true } lf
- | FIota :: lf -> add_flag { red with rIota = true } lf
+ | FMatch :: lf -> add_flag { red with rMatch = true } lf
+ | FFix :: lf -> add_flag { red with rFix = true } lf
+ | FCofix :: lf -> add_flag { red with rCofix = true } lf
| FZeta :: lf -> add_flag { red with rZeta = true } lf
| FConst l :: lf ->
if red.rDelta then
- Errors.error
+ CErrors.error
"Cannot set both constants to unfold and constants not to unfold";
add_flag { red with rConst = union_consts red.rConst l } lf
| FDeltaBut l :: lf ->
if red.rConst <> [] && not red.rDelta then
- Errors.error
+ CErrors.error
"Cannot set both constants to unfold and constants not to unfold";
add_flag
{ red with rConst = union_consts red.rConst l; rDelta = true }
lf
in
add_flag
- {rBeta = false; rIota = false; rZeta = false; rDelta = false; rConst = []}
+ {rBeta = false; rMatch = false; rFix = false; rCofix = false;
+ rZeta = false; rDelta = false; rConst = []}
l
let all_flags =
- {rBeta = true; rIota = true; rZeta = true; rDelta = true; rConst = []}
+ {rBeta = true; rMatch = true; rFix = true; rCofix = true;
+ rZeta = true; rDelta = true; rConst = []}
diff --git a/pretyping/reductionops.ml b/pretyping/reductionops.ml
index 79cb7a2f67..1fdbbb4128 100644
--- a/pretyping/reductionops.ml
+++ b/pretyping/reductionops.ml
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Errors
+open CErrors
open Util
open Names
open Term
@@ -26,6 +26,19 @@ exception Elimconst
their parameters in its stack.
*)
+let refolding_in_reduction = ref false
+let _ = Goptions.declare_bool_option {
+ Goptions.optsync = true; Goptions.optdepr = false;
+ Goptions.optname =
+ "Perform refolding of fixpoints/constants like cbn during reductions";
+ Goptions.optkey = ["Refolding";"Reduction"];
+ Goptions.optread = (fun () -> !refolding_in_reduction);
+ Goptions.optwrite = (fun a -> refolding_in_reduction:=a);
+}
+
+let get_refolding_in_reduction () = !refolding_in_reduction
+let set_refolding_in_reduction = (:=) refolding_in_reduction
+
(** Machinery to custom the behavior of the reduction *)
module ReductionBehaviour = struct
open Globnames
@@ -153,9 +166,6 @@ module Cst_stack = struct
let empty = []
let is_empty = CList.is_empty
- let sanity x y =
- assert(Term.eq_constr x y)
-
let drop_useless = function
| _ :: ((_,_,[])::_ as q) -> q
| l -> l
@@ -164,9 +174,9 @@ module Cst_stack = struct
let append2cst = function
| (c,params,[]) -> (c, h::params, [])
| (c,params,((i,t)::q)) when i = pred (Array.length t) ->
- let () = sanity h t.(i) in (c, params, q)
+ (c, params, q)
| (c,params,(i,t)::q) ->
- let () = sanity h t.(i) in (c, params, (succ i,t)::q)
+ (c, params, (succ i,t)::q)
in
drop_useless (List.map append2cst cst_l)
@@ -619,36 +629,21 @@ let rec strong_prodspine redfun sigma c =
(*** Reduction using bindingss ***)
(*************************************)
-(* Local *)
-let nored = Closure.RedFlags.no_red
-let beta = Closure.beta
-let eta = Closure.RedFlags.mkflags [Closure.RedFlags.fETA]
-let zeta = Closure.RedFlags.mkflags [Closure.RedFlags.fZETA]
-let betaiota = Closure.betaiota
-let betaiotazeta = Closure.betaiotazeta
-
-(* Contextual *)
-let delta = Closure.RedFlags.mkflags [Closure.RedFlags.fDELTA]
-let betalet = Closure.RedFlags.mkflags [Closure.RedFlags.fBETA;Closure.RedFlags.fZETA]
-let betaetalet = Closure.RedFlags.red_add betalet Closure.RedFlags.fETA
-let betadelta = Closure.RedFlags.red_add betalet Closure.RedFlags.fDELTA
-let betadeltaeta = Closure.RedFlags.red_add betadelta Closure.RedFlags.fETA
-let betadeltaiota = Closure.RedFlags.red_add betadelta Closure.RedFlags.fIOTA
-let betadeltaiota_nolet = Closure.betadeltaiotanolet
-let betadeltaiotaeta = Closure.RedFlags.red_add betadeltaiota Closure.RedFlags.fETA
+let eta = CClosure.RedFlags.mkflags [CClosure.RedFlags.fETA]
(* Beta Reduction tools *)
-let apply_subst recfun env cst_l t stack =
+let apply_subst recfun env refold cst_l t stack =
let rec aux env cst_l t stack =
match (Stack.decomp stack,kind_of_term t) with
| Some (h,stacktl), Lambda (_,_,c) ->
- aux (h::env) (Cst_stack.add_param h cst_l) c stacktl
+ let cst_l' = if refold then Cst_stack.add_param h cst_l else cst_l in
+ aux (h::env) cst_l' c stacktl
| _ -> recfun cst_l (substl env t, stack)
in aux env cst_l t stack
let stacklam recfun env t stack =
- apply_subst (fun _ -> recfun) env Cst_stack.empty t stack
+ apply_subst (fun _ -> recfun) env false Cst_stack.empty t stack
let beta_applist (c,l) =
stacklam Stack.zip [] c (Stack.append_app_list l Stack.empty)
@@ -686,13 +681,17 @@ let magicaly_constant_of_fixbody env reference bd = function
match constant_opt_value_in env (cst,u) with
| None -> bd
| Some t ->
- let b, csts = Universes.eq_constr_universes t bd in
- let subst = Universes.Constraints.fold (fun (l,d,r) acc ->
- Univ.LMap.add (Option.get (Universe.level l)) (Option.get (Universe.level r)) acc)
- csts Univ.LMap.empty
- in
- let inst = Instance.subst_fn (fun u -> Univ.LMap.find u subst) u in
- if b then mkConstU (cst,inst) else bd
+ let csts = Universes.eq_constr_universes t bd in
+ begin match csts with
+ | Some csts ->
+ let subst = Universes.Constraints.fold (fun (l,d,r) acc ->
+ Univ.LMap.add (Option.get (Universe.level l)) (Option.get (Universe.level r)) acc)
+ csts Univ.LMap.empty
+ in
+ let inst = Instance.subst_fn (fun u -> Univ.LMap.find u subst) u in
+ mkConstU (cst,inst)
+ | None -> bd
+ end
with
| Not_found -> bd
@@ -713,11 +712,16 @@ let contract_cofix ?env ?reference (bodynum,(names,types,bodies as typedbodies))
substl closure bodies.(bodynum)
(** Similar to the "fix" case below *)
-let reduce_and_refold_cofix recfun env cst_l cofix sk =
- let raw_answer = contract_cofix ~env ?reference:(Cst_stack.reference cst_l) cofix in
+let reduce_and_refold_cofix recfun env refold cst_l cofix sk =
+ let raw_answer =
+ let env = if refold then Some env else None in
+ contract_cofix ?env ?reference:(Cst_stack.reference cst_l) cofix in
apply_subst
- (fun x (t,sk') -> recfun x (Cst_stack.best_replace (mkCoFix cofix) cst_l t,sk'))
- [] Cst_stack.empty raw_answer sk
+ (fun x (t,sk') ->
+ let t' =
+ if refold then Cst_stack.best_replace (mkCoFix cofix) cst_l t else t in
+ recfun x (t',sk'))
+ [] refold Cst_stack.empty raw_answer sk
let reduce_mind_case mia =
match kind_of_term mia.mconstr with
@@ -753,11 +757,18 @@ let contract_fix ?env ?reference ((recindices,bodynum),(names,types,bodies as ty
replace the fixpoint by the best constant from [cst_l]
Other rels are directly substituted by constants "magically found from the
context" in contract_fix *)
-let reduce_and_refold_fix recfun env cst_l fix sk =
- let raw_answer = contract_fix ~env ?reference:(Cst_stack.reference cst_l) fix in
+let reduce_and_refold_fix recfun env refold cst_l fix sk =
+ let raw_answer =
+ let env = if refold then None else Some env in
+ contract_fix ?env ?reference:(Cst_stack.reference cst_l) fix in
apply_subst
- (fun x (t,sk') -> recfun x (Cst_stack.best_replace (mkFix fix) cst_l t,sk'))
- [] Cst_stack.empty raw_answer sk
+ (fun x (t,sk') ->
+ let t' =
+ if refold then
+ Cst_stack.best_replace (mkFix fix) cst_l t
+ else t
+ in recfun x (t',sk'))
+ [] refold Cst_stack.empty raw_answer sk
let fix_recarg ((recindices,bodynum),_) stack =
assert (0 <= bodynum && bodynum < Array.length recindices);
@@ -797,7 +808,7 @@ let equal_stacks (x, l) (y, l') =
| None -> false
| Some (lft1,lft2) -> f_equal (x, lft1) (y, lft2)
-let rec whd_state_gen ?csts tactic_mode flags env sigma =
+let rec whd_state_gen ?csts ~refold ~tactic_mode flags env sigma =
let open Context.Named.Declaration in
let rec whrec cst_l (x, stack as s) =
let () = if !debug_RAKAM then
@@ -806,21 +817,22 @@ let rec whd_state_gen ?csts tactic_mode flags env sigma =
(h 0 (str "<<" ++ Termops.print_constr x ++
str "|" ++ cut () ++ Cst_stack.pr cst_l ++
str "|" ++ cut () ++ Stack.pr Termops.print_constr stack ++
- str ">>") ++ fnl ())
+ str ">>"))
in
let fold () =
let () = if !debug_RAKAM then
- let open Pp in Feedback.msg_notice (str "<><><><><>" ++ fnl ()) in
+ let open Pp in Feedback.msg_notice (str "<><><><><>") in
(s,cst_l)
in
match kind_of_term x with
- | Rel n when Closure.RedFlags.red_set flags Closure.RedFlags.fDELTA ->
+ | Rel n when CClosure.RedFlags.red_set flags CClosure.RedFlags.fDELTA ->
(match lookup_rel n env with
| LocalDef (_,body,_) -> whrec Cst_stack.empty (lift n body, stack)
| _ -> fold ())
- | Var id when Closure.RedFlags.red_set flags (Closure.RedFlags.fVAR id) ->
+ | Var id when CClosure.RedFlags.red_set flags (CClosure.RedFlags.fVAR id) ->
(match lookup_named id env with
- | LocalDef (_,body,_) -> whrec (Cst_stack.add_cst (mkVar id) cst_l) (body, stack)
+ | LocalDef (_,body,_) ->
+ whrec (if refold then Cst_stack.add_cst (mkVar id) cst_l else cst_l) (body, stack)
| _ -> fold ())
| Evar ev ->
(match safe_evar_value sigma ev with
@@ -830,12 +842,13 @@ let rec whd_state_gen ?csts tactic_mode flags env sigma =
(match safe_meta_value sigma ev with
| Some body -> whrec cst_l (body, stack)
| None -> fold ())
- | Const (c,u as const) when Closure.RedFlags.red_set flags (Closure.RedFlags.fCONST c) ->
+ | Const (c,u as const) when CClosure.RedFlags.red_set flags (CClosure.RedFlags.fCONST c) ->
(match constant_opt_value_in env const with
| None -> fold ()
| Some body ->
if not tactic_mode
- then whrec (Cst_stack.add_cst (mkConstU const) cst_l) (body, stack)
+ then whrec (if refold then Cst_stack.add_cst (mkConstU const) cst_l else cst_l)
+ (body, stack)
else (* Looks for ReductionBehaviour *)
match ReductionBehaviour.get (Globnames.ConstRef c) with
| None -> whrec (Cst_stack.add_cst (mkConstU const) cst_l) (body, stack)
@@ -870,7 +883,7 @@ let rec whd_state_gen ?csts tactic_mode flags env sigma =
whrec Cst_stack.empty
(arg,Stack.Cst(Stack.Cst_const const,curr,remains,bef,cst_l)::s')
)
- | Proj (p, c) when Closure.RedFlags.red_projection flags p ->
+ | Proj (p, c) when CClosure.RedFlags.red_projection flags p ->
(let pb = lookup_projection p env in
let kn = Projection.constant p in
let npars = pb.Declarations.proj_npars
@@ -911,21 +924,21 @@ let rec whd_state_gen ?csts tactic_mode flags env sigma =
(arg,Stack.Cst(Stack.Cst_proj p,curr,remains,
Stack.append_app [|c|] bef,cst_l)::s'))
- | LetIn (_,b,_,c) when Closure.RedFlags.red_set flags Closure.RedFlags.fZETA ->
- apply_subst whrec [b] cst_l c stack
+ | LetIn (_,b,_,c) when CClosure.RedFlags.red_set flags CClosure.RedFlags.fZETA ->
+ apply_subst whrec [b] refold cst_l c stack
| Cast (c,_,_) -> whrec cst_l (c, stack)
| App (f,cl) ->
whrec
- (Cst_stack.add_args cl cst_l)
+ (if refold then Cst_stack.add_args cl cst_l else cst_l)
(f, Stack.append_app cl stack)
| Lambda (na,t,c) ->
(match Stack.decomp stack with
- | Some _ when Closure.RedFlags.red_set flags Closure.RedFlags.fBETA ->
- apply_subst whrec [] cst_l x stack
- | None when Closure.RedFlags.red_set flags Closure.RedFlags.fETA ->
+ | Some _ when CClosure.RedFlags.red_set flags CClosure.RedFlags.fBETA ->
+ apply_subst whrec [] refold cst_l x stack
+ | None when CClosure.RedFlags.red_set flags CClosure.RedFlags.fETA ->
let env' = push_rel (LocalAssum (na,t)) env in
- let whrec' = whd_state_gen tactic_mode flags env' sigma in
- (match kind_of_term (Stack.zip ~refold:true (fst (whrec' (c, Stack.empty)))) with
+ let whrec' = whd_state_gen ~refold ~tactic_mode flags env' sigma in
+ (match kind_of_term (Stack.zip ~refold (fst (whrec' (c, Stack.empty)))) with
| App (f,cl) ->
let napp = Array.length cl in
if napp > 0 then
@@ -950,16 +963,18 @@ let rec whd_state_gen ?csts tactic_mode flags env sigma =
whrec Cst_stack.empty (arg, Stack.Fix(f,bef,cst_l)::s'))
| Construct ((ind,c),u) ->
- if Closure.RedFlags.red_set flags Closure.RedFlags.fIOTA then
+ let use_match = CClosure.RedFlags.red_set flags CClosure.RedFlags.fMATCH in
+ let use_fix = CClosure.RedFlags.red_set flags CClosure.RedFlags.fFIX in
+ if use_match || use_fix then
match Stack.strip_app stack with
- |args, (Stack.Case(ci, _, lf,_)::s') ->
+ |args, (Stack.Case(ci, _, lf,_)::s') when use_match ->
whrec Cst_stack.empty (lf.(c-1), (Stack.tail ci.ci_npar args) @ s')
- |args, (Stack.Proj (n,m,p,_)::s') ->
+ |args, (Stack.Proj (n,m,p,_)::s') when use_match ->
whrec Cst_stack.empty (Stack.nth args (n+m), s')
- |args, (Stack.Fix (f,s',cst_l)::s'') ->
+ |args, (Stack.Fix (f,s',cst_l)::s'') when use_fix ->
let x' = Stack.zip(x,args) in
let out_sk = s' @ (Stack.append_app [|x'|] s'') in
- reduce_and_refold_fix whrec env cst_l f out_sk
+ reduce_and_refold_fix whrec env refold cst_l f out_sk
|args, (Stack.Cst (const,curr,remains,s',cst_l) :: s'') ->
let x' = Stack.zip(x,args) in
begin match remains with
@@ -969,7 +984,7 @@ let rec whd_state_gen ?csts tactic_mode flags env sigma =
(match constant_opt_value_in env const with
| None -> fold ()
| Some body ->
- whrec (Cst_stack.add_cst (mkConstU const) cst_l)
+ whrec (if refold then Cst_stack.add_cst (mkConstU const) cst_l else cst_l)
(body, s' @ (Stack.append_app [|x'|] s'')))
| Stack.Cst_proj p ->
let pb = lookup_projection p env in
@@ -988,14 +1003,14 @@ let rec whd_state_gen ?csts tactic_mode flags env sigma =
Stack.Cst (const,next,remains',s' @ (Stack.append_app [|x'|] bef),cst_l) :: s''')
end
|_, (Stack.App _|Stack.Update _|Stack.Shift _)::_ -> assert false
- |_, [] -> fold ()
+ |_, _ -> fold ()
else fold ()
| CoFix cofix ->
- if Closure.RedFlags.red_set flags Closure.RedFlags.fIOTA then
+ if CClosure.RedFlags.red_set flags CClosure.RedFlags.fCOFIX then
match Stack.strip_app stack with
|args, ((Stack.Case _ |Stack.Proj _)::s') ->
- reduce_and_refold_cofix whrec env cst_l cofix stack
+ reduce_and_refold_cofix whrec env refold cst_l cofix stack
|_ -> fold ()
else fold ()
@@ -1010,15 +1025,15 @@ let rec whd_state_gen ?csts tactic_mode flags env sigma =
let local_whd_state_gen flags sigma =
let rec whrec (x, stack as s) =
match kind_of_term x with
- | LetIn (_,b,_,c) when Closure.RedFlags.red_set flags Closure.RedFlags.fZETA ->
+ | LetIn (_,b,_,c) when CClosure.RedFlags.red_set flags CClosure.RedFlags.fZETA ->
stacklam whrec [b] c stack
| Cast (c,_,_) -> whrec (c, stack)
| App (f,cl) -> whrec (f, Stack.append_app cl stack)
| Lambda (_,_,c) ->
(match Stack.decomp stack with
- | Some (a,m) when Closure.RedFlags.red_set flags Closure.RedFlags.fBETA ->
+ | Some (a,m) when CClosure.RedFlags.red_set flags CClosure.RedFlags.fBETA ->
stacklam whrec [a] c m
- | None when Closure.RedFlags.red_set flags Closure.RedFlags.fETA ->
+ | None when CClosure.RedFlags.red_set flags CClosure.RedFlags.fETA ->
(match kind_of_term (Stack.zip (whrec (c, Stack.empty))) with
| App (f,cl) ->
let napp = Array.length cl in
@@ -1034,7 +1049,7 @@ let local_whd_state_gen flags sigma =
| _ -> s)
| _ -> s)
- | Proj (p,c) when Closure.RedFlags.red_projection flags p ->
+ | Proj (p,c) when CClosure.RedFlags.red_projection flags p ->
(let pb = lookup_projection p (Global.env ()) in
whrec (c, Stack.Proj (pb.Declarations.proj_npars, pb.Declarations.proj_arg,
p, Cst_stack.empty)
@@ -1059,21 +1074,23 @@ let local_whd_state_gen flags sigma =
| None -> s)
| Construct ((ind,c),u) ->
- if Closure.RedFlags.red_set flags Closure.RedFlags.fIOTA then
+ let use_match = CClosure.RedFlags.red_set flags CClosure.RedFlags.fMATCH in
+ let use_fix = CClosure.RedFlags.red_set flags CClosure.RedFlags.fFIX in
+ if use_match || use_fix then
match Stack.strip_app stack with
- |args, (Stack.Case(ci, _, lf,_)::s') ->
+ |args, (Stack.Case(ci, _, lf,_)::s') when use_match ->
whrec (lf.(c-1), (Stack.tail ci.ci_npar args) @ s')
- |args, (Stack.Proj (n,m,p,_) :: s') ->
+ |args, (Stack.Proj (n,m,p,_) :: s') when use_match ->
whrec (Stack.nth args (n+m), s')
- |args, (Stack.Fix (f,s',cst)::s'') ->
+ |args, (Stack.Fix (f,s',cst)::s'') when use_fix ->
let x' = Stack.zip(x,args) in
whrec (contract_fix f, s' @ (Stack.append_app [|x'|] s''))
|_, (Stack.App _|Stack.Update _|Stack.Shift _|Stack.Cst _)::_ -> assert false
- |_, [] -> s
+ |_, _ -> s
else s
| CoFix cofix ->
- if Closure.RedFlags.red_set flags Closure.RedFlags.fIOTA then
+ if CClosure.RedFlags.red_set flags CClosure.RedFlags.fCOFIX then
match Stack.strip_app stack with
|args, ((Stack.Case _ | Stack.Proj _)::s') ->
whrec (contract_cofix cofix, stack)
@@ -1085,7 +1102,7 @@ let local_whd_state_gen flags sigma =
whrec
let raw_whd_state_gen flags env =
- let f sigma s = fst (whd_state_gen false flags env sigma s) in
+ let f sigma s = fst (whd_state_gen (get_refolding_in_reduction ()) false flags env sigma s) in
f
let stack_red_of_state_red f =
@@ -1095,7 +1112,7 @@ let stack_red_of_state_red f =
(* Drops the Cst_stack *)
let iterate_whd_gen refold flags env sigma s =
let rec aux t =
- let (hd,sk),_ = whd_state_gen refold flags env sigma (t,Stack.empty) in
+ let (hd,sk),_ = whd_state_gen refold false flags env sigma (t,Stack.empty) in
let whd_sk = Stack.map aux sk in
Stack.zip ~refold (hd,whd_sk)
in aux s
@@ -1105,79 +1122,64 @@ let red_of_state_red f sigma x =
(* 0. No Reduction Functions *)
-let whd_nored_state = local_whd_state_gen nored
+let whd_nored_state = local_whd_state_gen CClosure.nored
let whd_nored_stack = stack_red_of_state_red whd_nored_state
let whd_nored = red_of_state_red whd_nored_state
(* 1. Beta Reduction Functions *)
-let whd_beta_state = local_whd_state_gen beta
+let whd_beta_state = local_whd_state_gen CClosure.beta
let whd_beta_stack = stack_red_of_state_red whd_beta_state
let whd_beta = red_of_state_red whd_beta_state
-(* Nouveau ! *)
-let whd_betaetalet_state = local_whd_state_gen betaetalet
-let whd_betaetalet_stack = stack_red_of_state_red whd_betaetalet_state
-let whd_betaetalet = red_of_state_red whd_betaetalet_state
-
-let whd_betalet_state = local_whd_state_gen betalet
+let whd_betalet_state = local_whd_state_gen CClosure.betazeta
let whd_betalet_stack = stack_red_of_state_red whd_betalet_state
let whd_betalet = red_of_state_red whd_betalet_state
(* 2. Delta Reduction Functions *)
-let whd_delta_state e = raw_whd_state_gen delta e
+let whd_delta_state e = raw_whd_state_gen CClosure.delta e
let whd_delta_stack env = stack_red_of_state_red (whd_delta_state env)
let whd_delta env = red_of_state_red (whd_delta_state env)
-let whd_betadelta_state e = raw_whd_state_gen betadelta e
-let whd_betadelta_stack env =
- stack_red_of_state_red (whd_betadelta_state env)
-let whd_betadelta env =
- red_of_state_red (whd_betadelta_state env)
+let whd_betadeltazeta_state e = raw_whd_state_gen CClosure.betadeltazeta e
+let whd_betadeltazeta_stack env =
+ stack_red_of_state_red (whd_betadeltazeta_state env)
+let whd_betadeltazeta env =
+ red_of_state_red (whd_betadeltazeta_state env)
-let whd_betadeltaeta_state e = raw_whd_state_gen betadeltaeta e
-let whd_betadeltaeta_stack env =
- stack_red_of_state_red (whd_betadeltaeta_state env)
-let whd_betadeltaeta env =
- red_of_state_red (whd_betadeltaeta_state env)
-
(* 3. Iota reduction Functions *)
-let whd_betaiota_state = local_whd_state_gen betaiota
+let whd_betaiota_state = local_whd_state_gen CClosure.betaiota
let whd_betaiota_stack = stack_red_of_state_red whd_betaiota_state
let whd_betaiota = red_of_state_red whd_betaiota_state
-let whd_betaiotazeta_state = local_whd_state_gen betaiotazeta
+let whd_betaiotazeta_state = local_whd_state_gen CClosure.betaiotazeta
let whd_betaiotazeta_stack = stack_red_of_state_red whd_betaiotazeta_state
let whd_betaiotazeta = red_of_state_red whd_betaiotazeta_state
-let whd_betadeltaiota_state env = raw_whd_state_gen betadeltaiota env
-let whd_betadeltaiota_stack env =
- stack_red_of_state_red (whd_betadeltaiota_state env)
-let whd_betadeltaiota env =
- red_of_state_red (whd_betadeltaiota_state env)
-
-let whd_betadeltaiotaeta_state env = raw_whd_state_gen betadeltaiotaeta env
-let whd_betadeltaiotaeta_stack env =
- stack_red_of_state_red (whd_betadeltaiotaeta_state env)
-let whd_betadeltaiotaeta env =
- red_of_state_red (whd_betadeltaiotaeta_state env)
+let whd_all_state env = raw_whd_state_gen CClosure.all env
+let whd_all_stack env =
+ stack_red_of_state_red (whd_all_state env)
+let whd_all env =
+ red_of_state_red (whd_all_state env)
-let whd_betadeltaiota_nolet_state env = raw_whd_state_gen betadeltaiota_nolet env
-let whd_betadeltaiota_nolet_stack env =
- stack_red_of_state_red (whd_betadeltaiota_nolet_state env)
-let whd_betadeltaiota_nolet env =
- red_of_state_red (whd_betadeltaiota_nolet_state env)
+let whd_allnolet_state env = raw_whd_state_gen CClosure.allnolet env
+let whd_allnolet_stack env =
+ stack_red_of_state_red (whd_allnolet_state env)
+let whd_allnolet env =
+ red_of_state_red (whd_allnolet_state env)
-(* 4. Eta reduction Functions *)
+(* 4. Ad-hoc eta reduction, does not subsitute evars *)
-let whd_eta c = Stack.zip (local_whd_state_gen eta Evd.empty (c,Stack.empty))
+let shrink_eta c = Stack.zip (local_whd_state_gen eta Evd.empty (c,Stack.empty))
(* 5. Zeta Reduction Functions *)
-let whd_zeta c = Stack.zip (local_whd_state_gen zeta Evd.empty (c,Stack.empty))
+let whd_zeta_state = local_whd_state_gen CClosure.zeta
+let whd_zeta_stack = stack_red_of_state_red whd_zeta_state
+let whd_zeta = red_of_state_red whd_zeta_state
(****************************************************************************)
(* Reduction Functions *)
@@ -1193,16 +1195,16 @@ let nf_evar = Evarutil.nf_evar
let clos_norm_flags flgs env sigma t =
try
let evars ev = safe_evar_value sigma ev in
- Closure.norm_val
- (Closure.create_clos_infos ~evars flgs env)
- (Closure.inject t)
+ CClosure.norm_val
+ (CClosure.create_clos_infos ~evars flgs env)
+ (CClosure.inject t)
with e when is_anomaly e -> error "Tried to normalize ill-typed term"
-let nf_beta = clos_norm_flags Closure.beta (Global.env ())
-let nf_betaiota = clos_norm_flags Closure.betaiota (Global.env ())
-let nf_betaiotazeta = clos_norm_flags Closure.betaiotazeta (Global.env ())
-let nf_betadeltaiota env sigma =
- clos_norm_flags Closure.betadeltaiota env sigma
+let nf_beta = clos_norm_flags CClosure.beta (Global.env ())
+let nf_betaiota = clos_norm_flags CClosure.betaiota (Global.env ())
+let nf_betaiotazeta = clos_norm_flags CClosure.betaiotazeta (Global.env ())
+let nf_all env sigma =
+ clos_norm_flags CClosure.all env sigma
(********************************************************************)
@@ -1232,8 +1234,8 @@ let pb_equal = function
| Reduction.CONV -> Reduction.CONV
let report_anomaly _ =
- let e = UserError ("", Pp.str "Conversion test raised an anomaly") in
- let e = Errors.push e in
+ let e = UserError (None, Pp.str "Conversion test raised an anomaly") in
+ let e = CErrors.push e in
iraise e
let test_trans_conversion (f: constr Reduction.extended_conversion_function) reds env sigma x y =
@@ -1264,7 +1266,7 @@ let sigma_compare_sorts env pb s0 s1 sigma =
match pb with
| Reduction.CONV -> Evd.set_eq_sort env sigma s0 s1
| Reduction.CUMUL -> Evd.set_leq_sort env sigma s0 s1
-
+
let sigma_compare_instances ~flex i0 i1 sigma =
try Evd.set_eq_instances ~flex sigma i0 i1
with Evd.UniversesDiffer
@@ -1397,7 +1399,7 @@ let instance sigma s c =
* error message. *)
let hnf_prod_app env sigma t n =
- match kind_of_term (whd_betadeltaiota env sigma t) with
+ match kind_of_term (whd_all env sigma t) with
| Prod (_,_,b) -> subst1 n b
| _ -> anomaly ~label:"hnf_prod_app" (Pp.str "Need a product")
@@ -1408,7 +1410,7 @@ let hnf_prod_applist env sigma t nl =
List.fold_left (hnf_prod_app env sigma) t nl
let hnf_lam_app env sigma t n =
- match kind_of_term (whd_betadeltaiota env sigma t) with
+ match kind_of_term (whd_all env sigma t) with
| Lambda (_,_,b) -> subst1 n b
| _ -> anomaly ~label:"hnf_lam_app" (Pp.str "Need an abstraction")
@@ -1420,7 +1422,7 @@ let hnf_lam_applist env sigma t nl =
let splay_prod env sigma =
let rec decrec env m c =
- let t = whd_betadeltaiota env sigma c in
+ let t = whd_all env sigma c in
match kind_of_term t with
| Prod (n,a,c0) ->
decrec (push_rel (LocalAssum (n,a)) env)
@@ -1431,7 +1433,7 @@ let splay_prod env sigma =
let splay_lam env sigma =
let rec decrec env m c =
- let t = whd_betadeltaiota env sigma c in
+ let t = whd_all env sigma c in
match kind_of_term t with
| Lambda (n,a,c0) ->
decrec (push_rel (LocalAssum (n,a)) env)
@@ -1442,7 +1444,7 @@ let splay_lam env sigma =
let splay_prod_assum env sigma =
let rec prodec_rec env l c =
- let t = whd_betadeltaiota_nolet env sigma c in
+ let t = whd_allnolet env sigma c in
match kind_of_term t with
| Prod (x,t,c) ->
prodec_rec (push_rel (LocalAssum (x,t)) env)
@@ -1452,7 +1454,7 @@ let splay_prod_assum env sigma =
(Context.Rel.add (LocalDef (x,b,t)) l) c
| Cast (c,_,_) -> prodec_rec env l c
| _ ->
- let t' = whd_betadeltaiota env sigma t in
+ let t' = whd_all env sigma t in
if Term.eq_constr t t' then l,t
else prodec_rec env l t'
in
@@ -1468,7 +1470,7 @@ let sort_of_arity env sigma c = snd (splay_arity env sigma c)
let splay_prod_n env sigma n =
let rec decrec env m ln c = if Int.equal m 0 then (ln,c) else
- match kind_of_term (whd_betadeltaiota env sigma c) with
+ match kind_of_term (whd_all env sigma c) with
| Prod (n,a,c0) ->
decrec (push_rel (LocalAssum (n,a)) env)
(m-1) (Context.Rel.add (LocalAssum (n,a)) ln) c0
@@ -1478,7 +1480,7 @@ let splay_prod_n env sigma n =
let splay_lam_n env sigma n =
let rec decrec env m ln c = if Int.equal m 0 then (ln,c) else
- match kind_of_term (whd_betadeltaiota env sigma c) with
+ match kind_of_term (whd_all env sigma c) with
| Lambda (n,a,c0) ->
decrec (push_rel (LocalAssum (n,a)) env)
(m-1) (Context.Rel.add (LocalAssum (n,a)) ln) c0
@@ -1487,7 +1489,7 @@ let splay_lam_n env sigma n =
decrec env n Context.Rel.empty
let is_sort env sigma t =
- match kind_of_term (whd_betadeltaiota env sigma t) with
+ match kind_of_term (whd_all env sigma t) with
| Sort s -> true
| _ -> false
@@ -1495,20 +1497,22 @@ let is_sort env sigma t =
of case/fix (heuristic used by evar_conv) *)
let whd_betaiota_deltazeta_for_iota_state ts env sigma csts s =
+ let refold = get_refolding_in_reduction () in
+ let tactic_mode = false in
let rec whrec csts s =
- let (t, stack as s),csts' = whd_state_gen ~csts false betaiota env sigma s in
+ let (t, stack as s),csts' = whd_state_gen ~csts ~refold ~tactic_mode CClosure.betaiota env sigma s in
match Stack.strip_app stack with
|args, (Stack.Case _ :: _ as stack') ->
- let (t_o,stack_o),csts_o = whd_state_gen ~csts:csts' false
- (Closure.RedFlags.red_add_transparent betadeltaiota ts) env sigma (t,args) in
+ let (t_o,stack_o),csts_o = whd_state_gen ~csts:csts' ~refold ~tactic_mode
+ (CClosure.RedFlags.red_add_transparent CClosure.all ts) env sigma (t,args) in
if reducible_mind_case t_o then whrec csts_o (t_o, stack_o@stack') else s,csts'
|args, (Stack.Fix _ :: _ as stack') ->
- let (t_o,stack_o),csts_o = whd_state_gen ~csts:csts' false
- (Closure.RedFlags.red_add_transparent betadeltaiota ts) env sigma (t,args) in
+ let (t_o,stack_o),csts_o = whd_state_gen ~csts:csts' ~refold ~tactic_mode
+ (CClosure.RedFlags.red_add_transparent CClosure.all ts) env sigma (t,args) in
if isConstruct t_o then whrec csts_o (t_o, stack_o@stack') else s,csts'
|args, (Stack.Proj (n,m,p,_) :: stack'') ->
- let (t_o,stack_o),csts_o = whd_state_gen ~csts:csts' false
- (Closure.RedFlags.red_add_transparent betadeltaiota ts) env sigma (t,args) in
+ let (t_o,stack_o),csts_o = whd_state_gen ~csts:csts' ~refold ~tactic_mode
+ (CClosure.RedFlags.red_add_transparent CClosure.all ts) env sigma (t,args) in
if isConstruct t_o then
whrec Cst_stack.empty (Stack.nth stack_o (n+m), stack'')
else s,csts'
@@ -1517,7 +1521,7 @@ let whd_betaiota_deltazeta_for_iota_state ts env sigma csts s =
let find_conclusion env sigma =
let rec decrec env c =
- let t = whd_betadeltaiota env sigma c in
+ let t = whd_all env sigma c in
match kind_of_term t with
| Prod (x,t,c0) -> decrec (push_rel (LocalAssum (x,t)) env) c0
| Lambda (x,t,c0) -> decrec (push_rel (LocalAssum (x,t)) env) c0
diff --git a/pretyping/reductionops.mli b/pretyping/reductionops.mli
index b38252e971..4cd7a2a869 100644
--- a/pretyping/reductionops.mli
+++ b/pretyping/reductionops.mli
@@ -28,6 +28,11 @@ module ReductionBehaviour : sig
val print : Globnames.global_reference -> Pp.std_ppcmds
end
+(** Option telling if reduction should use the refolding machinery of cbn
+ (off by default) *)
+val get_refolding_in_reduction : unit -> bool
+val set_refolding_in_reduction : bool -> unit
+
(** {6 Machinery about a stack of unfolded constant }
cst applied to params must convertible to term of the state applied to args
@@ -134,21 +139,21 @@ val stack_reduction_of_reduction :
i*)
val stacklam : (state -> 'a) -> constr list -> constr -> constr Stack.t -> 'a
-val whd_state_gen : ?csts:Cst_stack.t -> bool -> Closure.RedFlags.reds ->
- Environ.env -> Evd.evar_map -> state -> state * Cst_stack.t
+val whd_state_gen : ?csts:Cst_stack.t -> refold:bool -> tactic_mode:bool ->
+ CClosure.RedFlags.reds -> Environ.env -> Evd.evar_map -> state -> state * Cst_stack.t
-val iterate_whd_gen : bool -> Closure.RedFlags.reds ->
+val iterate_whd_gen : bool -> CClosure.RedFlags.reds ->
Environ.env -> Evd.evar_map -> Term.constr -> Term.constr
(** {6 Generic Optimized Reduction Function using Closures } *)
-val clos_norm_flags : Closure.RedFlags.reds -> reduction_function
+val clos_norm_flags : CClosure.RedFlags.reds -> reduction_function
(** Same as [(strong whd_beta[delta][iota])], but much faster on big terms *)
val nf_beta : local_reduction_function
val nf_betaiota : local_reduction_function
val nf_betaiotazeta : local_reduction_function
-val nf_betadeltaiota : reduction_function
+val nf_all : reduction_function
val nf_evar : evar_map -> constr -> constr
(** Lazy strategy, weak head reduction *)
@@ -158,9 +163,8 @@ val whd_nored : local_reduction_function
val whd_beta : local_reduction_function
val whd_betaiota : local_reduction_function
val whd_betaiotazeta : local_reduction_function
-val whd_betadeltaiota : contextual_reduction_function
-val whd_betadeltaiota_nolet : contextual_reduction_function
-val whd_betaetalet : local_reduction_function
+val whd_all : contextual_reduction_function
+val whd_allnolet : contextual_reduction_function
val whd_betalet : local_reduction_function
(** Removes cast and put into applicative form *)
@@ -168,18 +172,16 @@ val whd_nored_stack : local_stack_reduction_function
val whd_beta_stack : local_stack_reduction_function
val whd_betaiota_stack : local_stack_reduction_function
val whd_betaiotazeta_stack : local_stack_reduction_function
-val whd_betadeltaiota_stack : contextual_stack_reduction_function
-val whd_betadeltaiota_nolet_stack : contextual_stack_reduction_function
-val whd_betaetalet_stack : local_stack_reduction_function
+val whd_all_stack : contextual_stack_reduction_function
+val whd_allnolet_stack : contextual_stack_reduction_function
val whd_betalet_stack : local_stack_reduction_function
val whd_nored_state : local_state_reduction_function
val whd_beta_state : local_state_reduction_function
val whd_betaiota_state : local_state_reduction_function
val whd_betaiotazeta_state : local_state_reduction_function
-val whd_betadeltaiota_state : contextual_state_reduction_function
-val whd_betadeltaiota_nolet_state : contextual_state_reduction_function
-val whd_betaetalet_state : local_state_reduction_function
+val whd_all_state : contextual_state_reduction_function
+val whd_allnolet_state : contextual_state_reduction_function
val whd_betalet_state : local_state_reduction_function
(** {6 Head normal forms } *)
@@ -187,18 +189,14 @@ val whd_betalet_state : local_state_reduction_function
val whd_delta_stack : stack_reduction_function
val whd_delta_state : state_reduction_function
val whd_delta : reduction_function
-val whd_betadelta_stack : stack_reduction_function
-val whd_betadelta_state : state_reduction_function
-val whd_betadelta : reduction_function
-val whd_betadeltaeta_stack : stack_reduction_function
-val whd_betadeltaeta_state : state_reduction_function
-val whd_betadeltaeta : reduction_function
-val whd_betadeltaiotaeta_stack : stack_reduction_function
-val whd_betadeltaiotaeta_state : state_reduction_function
-val whd_betadeltaiotaeta : reduction_function
-
-val whd_eta : constr -> constr
-val whd_zeta : constr -> constr
+val whd_betadeltazeta_stack : stack_reduction_function
+val whd_betadeltazeta_state : state_reduction_function
+val whd_betadeltazeta : reduction_function
+val whd_zeta_stack : local_stack_reduction_function
+val whd_zeta_state : local_state_reduction_function
+val whd_zeta : local_reduction_function
+
+val shrink_eta : constr -> constr
(** Various reduction functions *)
diff --git a/pretyping/retyping.ml b/pretyping/retyping.ml
index 1a6f7832aa..5b67af3e73 100644
--- a/pretyping/retyping.ml
+++ b/pretyping/retyping.ml
@@ -7,7 +7,7 @@
(************************************************************************)
open Pp
-open Errors
+open CErrors
open Util
open Term
open Vars
@@ -20,6 +20,9 @@ open Termops
open Arguments_renaming
open Context.Rel.Declaration
+module RelDecl = Context.Rel.Declaration
+module NamedDecl = Context.Named.Declaration
+
type retype_error =
| NotASort
| NotAnArity
@@ -62,7 +65,7 @@ let get_type_from_constraints env sigma t =
let rec subst_type env sigma typ = function
| [] -> typ
| h::rest ->
- match kind_of_term (whd_betadeltaiota env sigma typ) with
+ match kind_of_term (whd_all env sigma typ) with
| Prod (na,c1,c2) -> subst_type env sigma (subst1 h c2) rest
| _ -> retype_error NonFunctionalConstruction
@@ -71,19 +74,18 @@ let rec subst_type env sigma typ = function
let sort_of_atomic_type env sigma ft args =
let rec concl_of_arity env n ar args =
- match kind_of_term (whd_betadeltaiota env sigma ar), args with
+ match kind_of_term (whd_all env sigma ar), args with
| Prod (na, t, b), h::l -> concl_of_arity (push_rel (LocalDef (na, lift n h, t)) env) (n + 1) b l
| Sort s, [] -> s
| _ -> retype_error NotASort
in concl_of_arity env 0 ft (Array.to_list args)
let type_of_var env id =
- let open Context.Named.Declaration in
- try get_type (lookup_named id env)
+ try NamedDecl.get_type (lookup_named id env)
with Not_found -> retype_error (BadVariable id)
let decomp_sort env sigma t =
- match kind_of_term (whd_betadeltaiota env sigma t) with
+ match kind_of_term (whd_all env sigma t) with
| Sort s -> s
| _ -> retype_error NotASort
@@ -94,7 +96,7 @@ let retype ?(polyprop=true) sigma =
(try strip_outer_cast (Evd.meta_ftype sigma n).Evd.rebus
with Not_found -> retype_error (BadMeta n))
| Rel n ->
- let ty = get_type (lookup_rel n env) in
+ let ty = RelDecl.get_type (lookup_rel n env) in
lift n ty
| Var id -> type_of_var env id
| Const cst -> rename_type_of_constant env cst
@@ -113,7 +115,7 @@ let retype ?(polyprop=true) sigma =
in
let n = inductive_nrealdecls_env env (fst (fst (dest_ind_family indf))) in
let t = betazetaevar_applist sigma n p realargs in
- (match kind_of_term (whd_betadeltaiota env sigma (type_of env t)) with
+ (match kind_of_term (whd_all env sigma (type_of env t)) with
| Prod _ -> whd_beta sigma (applist (t, [c]))
| _ -> t)
| Lambda (name,c1,c2) ->
@@ -239,7 +241,7 @@ let sorts_of_context env evc ctxt =
| [] -> env,[]
| d :: ctxt ->
let env,sorts = aux ctxt in
- let s = get_sort_of env evc (get_type d) in
+ let s = get_sort_of env evc (RelDecl.get_type d) in
(push_rel d env,s::sorts) in
snd (aux ctxt)
diff --git a/pretyping/retyping.mli b/pretyping/retyping.mli
index e4cca2679c..8ca40f829f 100644
--- a/pretyping/retyping.mli
+++ b/pretyping/retyping.mli
@@ -46,3 +46,5 @@ val type_of_global_reference_knowing_conclusion :
val sorts_of_context : env -> evar_map -> Context.Rel.t -> sorts list
val expand_projection : env -> evar_map -> Names.projection -> constr -> constr list -> constr
+
+val print_retype_error : retype_error -> Pp.std_ppcmds
diff --git a/pretyping/tacred.ml b/pretyping/tacred.ml
index 7d2504004f..7da7385089 100644
--- a/pretyping/tacred.ml
+++ b/pretyping/tacred.ml
@@ -7,7 +7,7 @@
(************************************************************************)
open Pp
-open Errors
+open CErrors
open Util
open Names
open Term
@@ -18,13 +18,16 @@ open Termops
open Find_subterm
open Namegen
open Environ
-open Closure
+open CClosure
open Reductionops
open Cbv
open Patternops
open Locus
open Sigma.Notations
+module RelDecl = Context.Rel.Declaration
+module NamedDecl = Context.Named.Declaration
+
(* Errors *)
type reduction_tactic_error =
@@ -38,7 +41,7 @@ exception Elimconst
exception Redelimination
let error_not_evaluable r =
- errorlabstrm "error_not_evaluable"
+ user_err ~hdr:"error_not_evaluable"
(str "Cannot coerce" ++ spc () ++ Nametab.pr_global_env Id.Set.empty r ++
spc () ++ str "to an evaluable reference.")
@@ -54,13 +57,12 @@ let is_evaluable env = function
| EvalVarRef id -> is_evaluable_var env id
let value_of_evaluable_ref env evref u =
- let open Context.Named.Declaration in
match evref with
| EvalConstRef con ->
(try constant_value_in env (con,u)
with NotEvaluableConst IsProj ->
raise (Invalid_argument "value_of_evaluable_ref"))
- | EvalVarRef id -> lookup_named id env |> get_value |> Option.get
+ | EvalVarRef id -> env |> lookup_named id |> NamedDecl.get_value |> Option.get
let evaluable_of_global_reference env = function
| ConstRef cst when is_evaluable_const env cst -> EvalConstRef cst
@@ -112,22 +114,18 @@ let unsafe_reference_opt_value env sigma eval =
| Declarations.Def c -> Some (Mod_subst.force_constr c)
| _ -> None)
| EvalVar id ->
- let open Context.Named.Declaration in
- lookup_named id env |> get_value
+ env |> lookup_named id |> NamedDecl.get_value
| EvalRel n ->
- let open Context.Rel.Declaration in
- lookup_rel n env |> map_value (lift n) |> get_value
+ env |> lookup_rel n |> RelDecl.map_value (lift n) |> RelDecl.get_value
| EvalEvar ev -> Evd.existential_opt_value sigma ev
let reference_opt_value env sigma eval u =
match eval with
| EvalConst cst -> constant_opt_value_in env (cst,u)
| EvalVar id ->
- let open Context.Named.Declaration in
- lookup_named id env |> get_value
+ env |> lookup_named id |> NamedDecl.get_value
| EvalRel n ->
- let open Context.Rel.Declaration in
- lookup_rel n env |> map_value (lift n) |> get_value
+ env |> lookup_rel n |> RelDecl.map_value (lift n) |> RelDecl.get_value
| EvalEvar ev -> Evd.existential_opt_value sigma ev
exception NotEvaluable
@@ -257,7 +255,7 @@ let invert_name labs l na0 env sigma ref = function
let compute_consteval_direct env sigma ref =
let rec srec env n labs onlyproj c =
- let c',l = whd_betadelta_stack env sigma c in
+ let c',l = whd_betadeltazeta_stack env sigma c in
match kind_of_term c' with
| Lambda (id,t,g) when List.is_empty l && not onlyproj ->
let open Context.Rel.Declaration in
@@ -541,11 +539,9 @@ let match_eval_ref_value env sigma constr =
| Const (sp, u) when is_evaluable env (EvalConstRef sp) ->
Some (constant_value_in env (sp, u))
| Var id when is_evaluable env (EvalVarRef id) ->
- let open Context.Named.Declaration in
- lookup_named id env |> get_value
+ env |> lookup_named id |> NamedDecl.get_value
| Rel n ->
- let open Context.Rel.Declaration in
- lookup_rel n env |> map_value (lift n) |> get_value
+ env |> lookup_rel n |> RelDecl.map_value (lift n) |> RelDecl.get_value
| Evar ev -> Evd.existential_opt_value sigma ev
| _ -> None
@@ -870,7 +866,7 @@ let red_product env sigma c =
*)
let whd_simpl_orelse_delta_but_fix_old env sigma c =
- let whd_all = whd_betadeltaiota_state env sigma in
+ let whd_all = whd_all_state env sigma in
let rec redrec (x, stack as s) =
match kind_of_term x with
| Lambda (na,t,c) ->
@@ -993,7 +989,7 @@ let e_contextually byhead (occs,c) f = { e_redfun = begin fun env sigma t ->
incr pos;
if ok then begin
if Option.has_some nested then
- errorlabstrm "" (str "The subterm at occurrence " ++ int (Option.get nested) ++ str " overlaps with the subterm at occurrence " ++ int (!pos-1) ++ str ".");
+ user_err (str "The subterm at occurrence " ++ int (Option.get nested) ++ str " overlaps with the subterm at occurrence " ++ int (!pos-1) ++ str ".");
(* Skip inner occurrences for stable counting of occurrences *)
if locs != [] then
ignore (traverse_below (Some (!pos-1)) envc t);
@@ -1125,7 +1121,7 @@ let cbv_norm_flags flags env sigma t =
let cbv_beta = cbv_norm_flags beta empty_env
let cbv_betaiota = cbv_norm_flags betaiota empty_env
-let cbv_betadeltaiota env sigma = cbv_norm_flags betadeltaiota env sigma
+let cbv_betadeltaiota env sigma = cbv_norm_flags all env sigma
let compute = cbv_betadeltaiota
@@ -1159,13 +1155,13 @@ let pattern_occs loccs_trm = { e_redfun = begin fun env sigma c ->
let check_privacy env ind =
let spec = Inductive.lookup_mind_specif env (fst ind) in
if Inductive.is_private spec then
- errorlabstrm "" (str "case analysis on a private type.")
+ user_err (str "case analysis on a private type.")
else ind
let check_not_primitive_record env ind =
let spec = Inductive.lookup_mind_specif env (fst ind) in
if Inductive.is_primitive_record spec then
- errorlabstrm "" (str "case analysis on a primitive record type: " ++
+ user_err (str "case analysis on a primitive record type: " ++
str "use projections or let instead.")
else ind
@@ -1182,14 +1178,14 @@ let reduce_to_ind_gen allow_product env sigma t =
if allow_product then
elimrec (push_rel (LocalAssum (n,ty)) env) t' ((LocalAssum (n,ty))::l)
else
- errorlabstrm "" (str"Not an inductive definition.")
+ user_err (str"Not an inductive definition.")
| _ ->
(* Last chance: we allow to bypass the Opaque flag (as it
was partially the case between V5.10 and V8.1 *)
- let t' = whd_betadeltaiota env sigma t in
+ let t' = whd_all env sigma t in
match kind_of_term (fst (decompose_app t')) with
| Ind ind-> (check_privacy env ind, it_mkProd_or_LetIn t' l)
- | _ -> errorlabstrm "" (str"Not an inductive product.")
+ | _ -> user_err (str"Not an inductive product.")
in
elimrec env t []
@@ -1239,7 +1235,7 @@ let one_step_reduce env sigma c =
applist (redrec (c,[]))
let error_cannot_recognize ref =
- errorlabstrm ""
+ user_err
(str "Cannot recognize a statement based on " ++
Nametab.pr_global_env Id.Set.empty ref ++ str".")
diff --git a/pretyping/tacred.mli b/pretyping/tacred.mli
index 195b21bbf2..f8dfe1adf2 100644
--- a/pretyping/tacred.mli
+++ b/pretyping/tacred.mli
@@ -66,7 +66,7 @@ val pattern_occs : (occurrences * constr) list -> e_reduction_function
(** Rem: Lazy strategies are defined in Reduction *)
(** Call by value strategy (uses Closures) *)
-val cbv_norm_flags : Closure.RedFlags.reds -> reduction_function
+val cbv_norm_flags : CClosure.RedFlags.reds -> reduction_function
val cbv_beta : local_reduction_function
val cbv_betaiota : local_reduction_function
val cbv_betadeltaiota : reduction_function
diff --git a/pretyping/typeclasses.ml b/pretyping/typeclasses.ml
index 3ff96cd72a..01f3620f1d 100644
--- a/pretyping/typeclasses.ml
+++ b/pretyping/typeclasses.ml
@@ -17,6 +17,9 @@ open Util
open Typeclasses_errors
open Libobject
open Context.Rel.Declaration
+
+module RelDecl = Context.Rel.Declaration
+module NamedDecl = Context.Named.Declaration
(*i*)
let typeclasses_unique_solutions = ref false
@@ -46,10 +49,10 @@ let set_typeclass_transparency gr local c = Hook.get set_typeclass_transparency
let (classes_transparent_state, classes_transparent_state_hook) = Hook.make ()
let classes_transparent_state () = Hook.get classes_transparent_state ()
-let solve_instantiation_problem = ref (fun _ _ _ _ -> assert false)
+let get_solve_one_instance, solve_one_instance_hook = Hook.make ()
let resolve_one_typeclass ?(unique=get_typeclasses_unique_solutions ()) env evm t =
- !solve_instantiation_problem env evm t unique
+ Hook.get get_solve_one_instance env evm t unique
type direction = Forward | Backward
@@ -65,7 +68,8 @@ type typeclass = {
cl_props : Context.Rel.t;
(* The method implementaions as projections. *)
- cl_projs : (Name.t * (direction * int option) option * constant option) list;
+ cl_projs : (Name.t * (direction * Vernacexpr.hint_info_expr) option
+ * constant option) list;
cl_strict : bool;
@@ -76,10 +80,9 @@ type typeclasses = typeclass Refmap.t
type instance = {
is_class: global_reference;
- is_pri: int option;
+ is_info: Vernacexpr.hint_info_expr;
(* Sections where the instance should be redeclared,
- -1 for discard, 0 for none, mutable to avoid redeclarations
- when multiple rebuild_object happen. *)
+ -1 for discard, 0 for none. *)
is_global: int;
is_poly: bool;
is_impl: global_reference;
@@ -89,15 +92,15 @@ type instances = (instance Refmap.t) Refmap.t
let instance_impl is = is.is_impl
-let instance_priority is = is.is_pri
+let hint_priority is = is.is_info.Vernacexpr.hint_priority
-let new_instance cl pri glob poly impl =
+let new_instance cl info glob poly impl =
let global =
if glob then Lib.sections_depth ()
else -1
in
{ is_class = cl.cl_impl;
- is_pri = pri ;
+ is_info = info ;
is_global = global ;
is_poly = poly;
is_impl = impl }
@@ -150,7 +153,7 @@ let dest_class_arity env c =
let class_of_constr c =
try Some (dest_class_arity (Global.env ()) c)
- with e when Errors.noncritical e -> None
+ with e when CErrors.noncritical e -> None
let is_class_constr c =
try let gr, u = Universes.global_of_constr c in
@@ -181,7 +184,7 @@ let subst_class (subst,cl) =
let do_subst_con c = Mod_subst.subst_constant subst c
and do_subst c = Mod_subst.subst_mps subst c
and do_subst_gr gr = fst (subst_global subst gr) in
- let do_subst_ctx = List.smartmap (map_constr do_subst) in
+ let do_subst_ctx = List.smartmap (RelDecl.map_constr do_subst) in
let do_subst_context (grs,ctx) =
List.smartmap (Option.smartmap (fun (gr,b) -> do_subst_gr gr, b)) grs,
do_subst_ctx ctx in
@@ -197,19 +200,16 @@ let subst_class (subst,cl) =
let discharge_class (_,cl) =
let repl = Lib.replacement_context () in
let rel_of_variable_context ctx = List.fold_right
- ( fun (n,_,b,t) (ctx', subst) ->
- let decl = match b with
- | None -> LocalAssum (Name n, substn_vars 1 subst t)
- | Some b -> LocalDef (Name n, substn_vars 1 subst b, substn_vars 1 subst t)
- in
- (decl :: ctx', n :: subst)
+ ( fun (decl,_) (ctx', subst) ->
+ let decl' = decl |> NamedDecl.map_constr (substn_vars 1 subst) |> NamedDecl.to_rel_decl in
+ (decl' :: ctx', NamedDecl.get_id decl :: subst)
) ctx ([], []) in
let discharge_rel_context subst n rel =
let rel = Context.Rel.map (Cooking.expmod_constr repl) rel in
let ctx, _ =
List.fold_right
(fun decl (ctx, k) ->
- map_constr (substn_vars k subst) decl :: ctx, succ k
+ RelDecl.map_constr (substn_vars k subst) decl :: ctx, succ k
)
rel ([], n)
in ctx
@@ -222,7 +222,7 @@ let discharge_class (_,cl) =
let discharge_context ctx' subst (grs, ctx) =
let grs' =
let newgrs = List.map (fun decl ->
- match decl |> get_type |> class_of_constr with
+ match decl |> RelDecl.get_type |> class_of_constr with
| None -> None
| Some (_, ((tc,_), _)) -> Some (tc.cl_impl, true))
ctx'
@@ -249,7 +249,7 @@ let rebuild_class cl =
try
let cst = Tacred.evaluable_of_global_reference (Global.env ()) cl.cl_impl in
set_typeclass_transparency cst false false; cl
- with e when Errors.noncritical e -> cl
+ with e when CErrors.noncritical e -> cl
let class_input : typeclass -> obj =
declare_object
@@ -272,9 +272,11 @@ let check_instance env sigma c =
let (evd, c) = resolve_one_typeclass env sigma
(Retyping.get_type_of env sigma c) in
not (Evd.has_undefined evd)
- with e when Errors.noncritical e -> false
+ with e when CErrors.noncritical e -> false
+
+open Vernacexpr
-let build_subclasses ~check env sigma glob pri =
+let build_subclasses ~check env sigma glob { hint_priority = pri } =
let _id = Nametab.basename_of_global glob in
let _next_id =
let i = ref (-1) in
@@ -297,24 +299,24 @@ let build_subclasses ~check env sigma glob pri =
match b with
| None -> None
| Some (Backward, _) -> None
- | Some (Forward, pri') ->
+ | Some (Forward, info) ->
let proj = Option.get proj in
let body = it_mkLambda_or_LetIn (mkApp (mkConstU (proj,u), projargs)) rels in
if check && check_instance env sigma body then None
else
- let pri =
- match pri, pri' with
+ let newpri =
+ match pri, info.hint_priority with
| Some p, Some p' -> Some (p + p')
| Some p, None -> Some (p + 1)
| _, _ -> None
in
- Some (ConstRef proj, pri, body)) tc.cl_projs
+ Some (ConstRef proj, { info with hint_priority = newpri }, body)) tc.cl_projs
in
- let declare_proj hints (cref, pri, body) =
+ let declare_proj hints (cref, info, body) =
let path' = cref :: path in
let ty = Retyping.get_type_of env sigma body in
let rest = aux pri body ty path' in
- hints @ (path', pri, body) :: rest
+ hints @ (path', info, body) :: rest
in List.fold_left declare_proj [] projs
in
let term = Universes.constr_of_global_univ (glob,Univ.UContext.instance ctx) in
@@ -368,11 +370,11 @@ let is_local i = Int.equal i.is_global (-1)
let add_instance check inst =
let poly = Global.is_polymorphic inst.is_impl in
add_instance_hint (IsGlobal inst.is_impl) [inst.is_impl] (is_local inst)
- inst.is_pri poly;
+ inst.is_info poly;
List.iter (fun (path, pri, c) -> add_instance_hint (IsConstr c) path
(is_local inst) pri poly)
(build_subclasses ~check:(check && not (isVarRef inst.is_impl))
- (Global.env ()) (Evd.from_env (Global.env ())) inst.is_impl inst.is_pri)
+ (Global.env ()) (Evd.from_env (Global.env ())) inst.is_impl inst.is_info)
let rebuild_instance (action, inst) =
let () = match action with
@@ -404,26 +406,22 @@ let remove_instance i =
Lib.add_anonymous_leaf (instance_input (RemoveInstance, i));
remove_instance_hint i.is_impl
-let declare_instance pri local glob =
+let declare_instance info local glob =
let ty = Global.type_of_global_unsafe glob in
+ let info = Option.default {hint_priority = None; hint_pattern = None} info in
match class_of_constr ty with
| Some (rels, ((tc,_), args) as _cl) ->
- add_instance (new_instance tc pri (not local) (Flags.use_polymorphic_flag ()) glob)
-(* let path, hints = build_subclasses (not local) (Global.env ()) Evd.empty glob in *)
-(* let entries = List.map (fun (path, pri, c) -> (pri, local, path, c)) hints in *)
-(* Auto.add_hints local [typeclasses_db] (Auto.HintsResolveEntry entries); *)
-(* Auto.add_hints local [typeclasses_db] *)
-(* (Auto.HintsCutEntry (PathSeq (PathStar (PathAtom PathAny), path))) *)
+ add_instance (new_instance tc info (not local) (Flags.use_polymorphic_flag ()) glob)
| None -> ()
let add_class cl =
add_class cl;
List.iter (fun (n, inst, body) ->
match inst with
- | Some (Backward, pri) ->
+ | Some (Backward, info) ->
(match body with
- | None -> Errors.error "Non-definable projection can not be declared as a subinstance"
- | Some b -> declare_instance pri false (ConstRef b))
+ | None -> CErrors.error "Non-definable projection can not be declared as a subinstance"
+ | Some b -> declare_instance (Some info) false (ConstRef b))
| _ -> ())
cl.cl_projs
@@ -501,7 +499,7 @@ let is_resolvable evi =
Option.is_empty (Store.get evi.evar_extra resolvable)
let mark_resolvability_undef b evi =
- if is_resolvable evi = b then evi
+ if is_resolvable evi == (b : bool) then evi
else
let t = set_resolvable evi.evar_extra b in
{ evi with evar_extra = t }
@@ -539,16 +537,16 @@ let has_typeclasses filter evd =
in
Evar.Map.exists check (Evd.undefined_map evd)
-let solve_instantiations_problem = ref (fun _ _ _ _ _ _ -> assert false)
+let get_solve_all_instances, solve_all_instances_hook = Hook.make ()
-let solve_problem env evd filter unique split fail =
- !solve_instantiations_problem env evd filter unique split fail
+let solve_all_instances env evd filter unique split fail =
+ Hook.get get_solve_all_instances env evd filter unique split fail
(** Profiling resolution of typeclasses *)
(* let solve_classeskey = Profile.declare_profile "solve_typeclasses" *)
(* let solve_problem = Profile.profile5 solve_classeskey solve_problem *)
-let resolve_typeclasses ?(filter=no_goals) ?(unique=get_typeclasses_unique_solutions ())
+let resolve_typeclasses ?(fast_path = true) ?(filter=no_goals) ?(unique=get_typeclasses_unique_solutions ())
?(split=true) ?(fail=true) env evd =
- if not (has_typeclasses filter evd) then evd
- else solve_problem env evd filter unique split fail
+ if fast_path && not (has_typeclasses filter evd) then evd
+ else solve_all_instances env evd filter unique split fail
diff --git a/pretyping/typeclasses.mli b/pretyping/typeclasses.mli
index 7bb0ef3abb..620bc367bd 100644
--- a/pretyping/typeclasses.mli
+++ b/pretyping/typeclasses.mli
@@ -32,7 +32,7 @@ type typeclass = {
Some may be undefinable due to sorting restrictions or simply undefined if
no name is provided. The [int option option] indicates subclasses whose hint has
the given priority. *)
- cl_projs : (Name.t * (direction * int option) option * constant option) list;
+ cl_projs : (Name.t * (direction * Vernacexpr.hint_info_expr) option * constant option) list;
(** Whether we use matching or full unification during resolution *)
cl_strict : bool;
@@ -50,7 +50,7 @@ val all_instances : unit -> instance list
val add_class : typeclass -> unit
-val new_instance : typeclass -> int option -> bool -> Decl_kinds.polymorphic ->
+val new_instance : typeclass -> Vernacexpr.hint_info_expr -> bool -> Decl_kinds.polymorphic ->
global_reference -> instance
val add_instance : instance -> unit
val remove_instance : instance -> unit
@@ -71,7 +71,7 @@ val class_of_constr : constr -> (Context.Rel.t * (typeclass puniverses * constr
val instance_impl : instance -> global_reference
-val instance_priority : instance -> int option
+val hint_priority : instance -> int option
val is_class : global_reference -> bool
val is_instance : global_reference -> bool
@@ -101,7 +101,7 @@ val mark_resolvable : evar_info -> evar_info
val is_class_evar : evar_map -> evar_info -> bool
val is_class_type : evar_map -> types -> bool
-val resolve_typeclasses : ?filter:evar_filter -> ?unique:bool ->
+val resolve_typeclasses : ?fast_path:bool -> ?filter:evar_filter -> ?unique:bool ->
?split:bool -> ?fail:bool -> env -> evar_map -> evar_map
val resolve_one_typeclass : ?unique:bool -> env -> evar_map -> types -> open_constr
@@ -113,21 +113,22 @@ val classes_transparent_state : unit -> transparent_state
val add_instance_hint_hook :
(global_reference_or_constr -> global_reference list ->
- bool (* local? *) -> int option -> Decl_kinds.polymorphic -> unit) Hook.t
+ bool (* local? *) -> Vernacexpr.hint_info_expr -> Decl_kinds.polymorphic -> unit) Hook.t
val remove_instance_hint_hook : (global_reference -> unit) Hook.t
val add_instance_hint : global_reference_or_constr -> global_reference list ->
- bool -> int option -> Decl_kinds.polymorphic -> unit
+ bool -> Vernacexpr.hint_info_expr -> Decl_kinds.polymorphic -> unit
val remove_instance_hint : global_reference -> unit
-val solve_instantiations_problem : (env -> evar_map -> evar_filter -> bool -> bool -> bool -> evar_map) ref
-val solve_instantiation_problem : (env -> evar_map -> types -> bool -> open_constr) ref
+val solve_all_instances_hook : (env -> evar_map -> evar_filter -> bool -> bool -> bool -> evar_map) Hook.t
+val solve_one_instance_hook : (env -> evar_map -> types -> bool -> open_constr) Hook.t
-val declare_instance : int option -> bool -> global_reference -> unit
+val declare_instance : Vernacexpr.hint_info_expr option -> bool -> global_reference -> unit
(** Build the subinstances hints for a given typeclass object.
check tells if we should check for existence of the
subinstances and add only the missing ones. *)
-val build_subclasses : check:bool -> env -> evar_map -> global_reference -> int option (* priority *) ->
- (global_reference list * int option * constr) list
+val build_subclasses : check:bool -> env -> evar_map -> global_reference ->
+ Vernacexpr.hint_info_expr ->
+ (global_reference list * Vernacexpr.hint_info_expr * constr) list
diff --git a/pretyping/typing.ml b/pretyping/typing.ml
index 52afa7f83a..e79e3d46f1 100644
--- a/pretyping/typing.ml
+++ b/pretyping/typing.ml
@@ -7,7 +7,7 @@
(************************************************************************)
open Pp
-open Errors
+open CErrors
open Util
open Term
open Vars
@@ -36,7 +36,7 @@ let inductive_type_knowing_parameters env (ind,u) jl =
Inductive.type_of_inductive_knowing_parameters env (mspec,u) paramstyp
let e_type_judgment env evdref j =
- match kind_of_term (whd_betadeltaiota env !evdref j.uj_type) with
+ match kind_of_term (whd_all env !evdref j.uj_type) with
| Sort s -> {utj_val = j.uj_val; utj_type = s }
| Evar ev ->
let (evd,s) = Evardefine.define_evar_as_sort env !evdref ev in
@@ -54,7 +54,7 @@ let e_judge_of_apply env evdref funj argjv =
{ uj_val = mkApp (j_val funj, Array.map j_val argjv);
uj_type = typ }
| hj::restjl ->
- match kind_of_term (whd_betadeltaiota env !evdref typ) with
+ match kind_of_term (whd_all env !evdref typ) with
| Prod (_,c1,c2) ->
if Evarconv.e_cumul env evdref hj.uj_type c1 then
apply_rec (n+1) (subst1 hj.uj_val c2) restjl
@@ -87,7 +87,7 @@ let e_is_correct_arity env evdref c pj ind specif params =
let allowed_sorts = elim_sorts specif in
let error () = error_elim_arity env ind allowed_sorts c pj None in
let rec srec env pt ar =
- let pt' = whd_betadeltaiota env !evdref pt in
+ let pt' = whd_all env !evdref pt in
match kind_of_term pt', ar with
| Prod (na1,a1,t), (LocalAssum (_,a1'))::ar' ->
if not (Evarconv.e_cumul env evdref a1 a1') then error ();
@@ -110,22 +110,32 @@ let e_type_case_branches env evdref (ind,largs) pj c =
let nparams = inductive_params specif in
let (params,realargs) = List.chop nparams largs in
let p = pj.uj_val in
- let univ = e_is_correct_arity env evdref c pj ind specif params in
+ let () = e_is_correct_arity env evdref c pj ind specif params in
let lc = build_branches_type ind specif params p in
let n = (snd specif).Declarations.mind_nrealdecls in
let ty = whd_betaiota !evdref (lambda_applist_assum (n+1) p (realargs@[c])) in
- (lc, ty, univ)
+ (lc, ty)
let e_judge_of_case env evdref ci pj cj lfj =
let indspec =
try find_mrectype env !evdref cj.uj_type
with Not_found -> error_case_not_inductive env cj in
let _ = check_case_info env (fst indspec) ci in
- let (bty,rslty,univ) = e_type_case_branches env evdref indspec pj cj.uj_val in
+ let (bty,rslty) = e_type_case_branches env evdref indspec pj cj.uj_val in
e_check_branch_types env evdref (fst indspec) cj (lfj,bty);
{ uj_val = mkCase (ci, pj.uj_val, cj.uj_val, Array.map j_val lfj);
uj_type = rslty }
+let check_type_fixpoint loc env evdref lna lar vdefj =
+ let lt = Array.length vdefj in
+ if Int.equal (Array.length lar) lt then
+ for i = 0 to lt-1 do
+ if not (Evarconv.e_cumul env evdref (vdefj.(i)).uj_type
+ (lift lt lar.(i))) then
+ Pretype_errors.error_ill_typed_rec_body ~loc env !evdref
+ i lna vdefj lar
+ done
+
(* FIXME: might depend on the level of actual parameters!*)
let check_allowed_sort env sigma ind c p =
let pj = Retyping.get_judgment_of env sigma p in
@@ -263,7 +273,7 @@ and execute_recdef env evdref (names,lar,vdef) =
let env1 = push_rec_types (names,lara,vdef) env in
let vdefj = execute_array env1 evdref vdef in
let vdefv = Array.map j_val vdefj in
- let _ = type_fixpoint env1 names lara vdefj in
+ let _ = check_type_fixpoint Loc.ghost env1 evdref names lara vdefj in
(names,lara,vdefv)
and execute_array env evdref = Array.map (execute env evdref)
diff --git a/pretyping/typing.mli b/pretyping/typing.mli
index e524edcca8..04e5e40bc2 100644
--- a/pretyping/typing.mli
+++ b/pretyping/typing.mli
@@ -39,3 +39,8 @@ val e_solve_evars : env -> evar_map ref -> constr -> constr
(** (first constr is term to match, second is return predicate) *)
val check_allowed_sort : env -> evar_map -> pinductive -> constr -> constr ->
unit
+
+(** Raise an error message if bodies have types not unifiable with the
+ expected ones *)
+val check_type_fixpoint : Loc.t -> env -> evar_map ref ->
+ Names.Name.t array -> types array -> unsafe_judgment array -> unit
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index cdd543d255..a91c30df6f 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Errors
+open CErrors
open Pp
open Util
open Names
@@ -29,7 +29,9 @@ open Locus
open Locusops
open Find_subterm
open Sigma.Notations
-open Context.Named.Declaration
+
+module RelDecl = Context.Rel.Declaration
+module NamedDecl = Context.Named.Declaration
let keyed_unification = ref (false)
let _ = Goptions.declare_bool_option {
@@ -78,9 +80,8 @@ let occur_meta_evd sigma mv c =
let abstract_scheme env evd c l lname_typ =
List.fold_left2
(fun (t,evd) (locc,a) decl ->
- let open Context.Rel.Declaration in
- let na = get_name decl in
- let ta = get_type decl in
+ let na = RelDecl.get_name decl in
+ let ta = RelDecl.get_type decl in
let na = match kind_of_term a with Var id -> Name id | _ -> na in
(* [occur_meta ta] test removed for support of eelim/ecase but consequences
are unclear...
@@ -460,7 +461,7 @@ let use_metas_pattern_unification flags nb l =
Array.for_all (fun c -> isRel c && destRel c <= nb) l
type key =
- | IsKey of Closure.table_key
+ | IsKey of CClosure.table_key
| IsProj of projection * constr
let expand_table_key env = function
@@ -479,8 +480,8 @@ let unfold_projection env p stk =
let expand_key ts env sigma = function
| Some (IsKey k) -> expand_table_key env k
| Some (IsProj (p, c)) ->
- let red = Stack.zip (fst (whd_betaiota_deltazeta_for_iota_state ts env sigma
- Cst_stack.empty (c, unfold_projection env p [])))
+ let red = Stack.zip (fst (whd_betaiota_deltazeta_for_iota_state ts env sigma
+ Cst_stack.empty (c, unfold_projection env p [])))
in if Term.eq_constr (mkProj (p, c)) red then None else Some red
| None -> None
@@ -557,22 +558,26 @@ let force_eqs c =
c Universes.Constraints.empty
let constr_cmp pb sigma flags t u =
- let b, cstrs =
+ let cstrs =
if pb == Reduction.CONV then Universes.eq_constr_universes t u
else Universes.leq_constr_universes t u
in
- if b then
- try Evd.add_universe_constraints sigma cstrs, b
+ match cstrs with
+ | Some cstrs ->
+ begin try Evd.add_universe_constraints sigma cstrs, true
with Univ.UniverseInconsistency _ -> sigma, false
| Evd.UniversesDiffer ->
if is_rigid_head flags t then
- try Evd.add_universe_constraints sigma (force_eqs cstrs), b
+ try Evd.add_universe_constraints sigma (force_eqs cstrs), true
with Univ.UniverseInconsistency _ -> sigma, false
else sigma, false
- else sigma, b
+ end
+ | None ->
+ sigma, false
let do_reduce ts (env, nb) sigma c =
- Stack.zip (fst (whd_betaiota_deltazeta_for_iota_state ts env sigma Cst_stack.empty (c, Stack.empty)))
+ Stack.zip (fst (whd_betaiota_deltazeta_for_iota_state
+ ts env sigma Cst_stack.empty (c, Stack.empty)))
let use_full_betaiota flags =
flags.modulo_betaiota && Flags.version_strictly_greater Flags.V8_3
@@ -742,7 +747,7 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst) conv_at_top env cv_pb
then Evd.set_leq_sort curenv sigma s1 s2
else Evd.set_eq_sort curenv sigma s1 s2
in (sigma', metasubst, evarsubst)
- with e when Errors.noncritical e ->
+ with e when CErrors.noncritical e ->
error_cannot_unify curenv sigma (m,n))
| Lambda (na,t1,c1), Lambda (_,t2,c2) ->
@@ -1058,8 +1063,10 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst) conv_at_top env cv_pb
let opt = { at_top = conv_at_top; with_types = false; with_cs = true } in
try
let res =
- if occur_meta_or_undefined_evar sigma m || occur_meta_or_undefined_evar sigma n
- || subterm_restriction opt flags then None
+ if subterm_restriction opt flags ||
+ occur_meta_or_undefined_evar sigma m || occur_meta_or_undefined_evar sigma n
+ then
+ None
else
let sigma, b = match flags.modulo_conv_on_closed_terms with
| Some convflags -> infer_conv ~pb:cv_pb ~ts:convflags env sigma m n
@@ -1078,8 +1085,9 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst) conv_at_top env cv_pb
if !debug_unification then Feedback.msg_debug (str "Leaving unification with success");
a
with e ->
+ let e = CErrors.push e in
if !debug_unification then Feedback.msg_debug (str "Leaving unification with failure");
- raise e
+ iraise e
let unify_0 env sigma = unify_0_with_initial_metas (sigma,[],[]) true env
@@ -1088,7 +1096,7 @@ let left = true
let right = false
let rec unify_with_eta keptside flags env sigma c1 c2 =
-(* Question: try whd_betadeltaiota on ci if not two lambdas? *)
+(* Question: try whd_all on ci if not two lambdas? *)
match kind_of_term c1, kind_of_term c2 with
| (Lambda (na,t1,c1'), Lambda (_,t2,c2')) ->
let env' = push_rel_assum (na,t1) env in
@@ -1136,11 +1144,11 @@ let merge_instances env sigma flags st1 st2 c1 c2 =
else (right, st2, res)
| (IsSuperType,IsSubType) ->
(try (left, IsSubType, unify_0 env sigma CUMUL flags c2 c1)
- with e when Errors.noncritical e ->
+ with e when CErrors.noncritical e ->
(right, IsSubType, unify_0 env sigma CUMUL flags c1 c2))
| (IsSubType,IsSuperType) ->
(try (left, IsSuperType, unify_0 env sigma CUMUL flags c1 c2)
- with e when Errors.noncritical e ->
+ with e when CErrors.noncritical e ->
(right, IsSuperType, unify_0 env sigma CUMUL flags c2 c1))
(* Unification
@@ -1198,7 +1206,7 @@ let applyHead env (type r) (evd : r Sigma.t) n c =
if Int.equal n 0 then
Sigma (c, evd, p)
else
- match kind_of_term (whd_betadeltaiota env (Sigma.to_evar_map evd) cty) with
+ match kind_of_term (whd_all env (Sigma.to_evar_map evd) cty) with
| Prod (_,c1,c2) ->
let Sigma (evar, evd', q) = Evarutil.new_evar env evd ~src:(Loc.ghost,Evar_kinds.GoalEvar) c1 in
apprec (n-1) (mkApp(c,[|evar|])) (subst1 evar c2) (p +> q) evd'
@@ -1208,15 +1216,15 @@ let applyHead env (type r) (evd : r Sigma.t) n c =
let is_mimick_head ts f =
match kind_of_term f with
- | Const (c,u) -> not (Closure.is_transparent_constant ts c)
- | Var id -> not (Closure.is_transparent_variable ts id)
+ | Const (c,u) -> not (CClosure.is_transparent_constant ts c)
+ | Var id -> not (CClosure.is_transparent_variable ts id)
| (Rel _|Construct _|Ind _) -> true
| _ -> false
let try_to_coerce env evd c cty tycon =
let j = make_judge c cty in
let (evd',j') = inh_conv_coerce_rigid_to true Loc.ghost env evd j tycon in
- let evd' = Evarconv.consider_remaining_unif_problems env evd' in
+ let evd' = Evarconv.solve_unif_constraints_with_heuristics env evd' in
let evd' = Evd.map_metas_fvalue (nf_evar evd') evd' in
(evd',j'.uj_val)
@@ -1266,7 +1274,11 @@ let solve_simple_evar_eqn ts env evd ev rhs =
| UnifFailure (evd,reason) ->
error_cannot_unify env evd ~reason (mkEvar ev,rhs);
| Success evd ->
- Evarconv.consider_remaining_unif_problems env evd
+ if Flags.version_less_or_equal Flags.V8_5 then
+ (* We used to force solving unrelated problems at arbitrary times *)
+ Evarconv.solve_unif_constraints_with_heuristics env evd
+ else (* solve_simple_eqn calls reconsider_unif_constraints itself *)
+ evd
(* [w_merge env sigma b metas evars] merges common instances in metas
or in evars, possibly generating new unification problems; if [b]
@@ -1293,7 +1305,6 @@ let w_merge env with_types flags (evd,metas,evars) =
if is_mimick_head flags.modulo_delta f then
let evd' =
mimick_undefined_evar evd flags f (Array.length cl) evk in
- (* let evd' = Evarconv.consider_remaining_unif_problems env evd' in *)
w_merge_rec evd' metas evars eqns
else
let evd' =
@@ -1341,7 +1352,7 @@ let w_merge env with_types flags (evd,metas,evars) =
else
let evd' =
if occur_meta_evd evd mv c then
- if isMetaOf mv (whd_betadeltaiota env evd c) then evd
+ if isMetaOf mv (whd_all env evd c) then evd
else error_cannot_unify env evd (mkMeta mv,c)
else
meta_assign mv (c,(status,TypeProcessed)) evd in
@@ -1351,7 +1362,7 @@ let w_merge env with_types flags (evd,metas,evars) =
let rec process_eqns failures = function
| (mv,status,c)::eqns ->
(match (try Inl (unify_type env evd flags mv status c)
- with e when Errors.noncritical e -> Inr e)
+ with e when CErrors.noncritical e -> Inr e)
with
| Inr e -> process_eqns (((mv,status,c),e)::failures) eqns
| Inl (evd,metas,evars) ->
@@ -1385,10 +1396,11 @@ let w_merge env with_types flags (evd,metas,evars) =
in w_merge_rec evd [] [] eqns
in
let res = (* merge constraints *)
- w_merge_rec evd (order_metas metas) (List.rev evars) []
+ w_merge_rec evd (order_metas metas)
+ (* Assign evars in the order of assignments during unification *)
+ (List.rev evars) []
in
- if with_types then check_types res
- else res
+ if with_types then check_types res else res
let w_unify_meta_types env ?(flags=default_unify_flags ()) evd =
let metas,evd = retract_coercible_metas evd in
@@ -1446,7 +1458,7 @@ let w_typed_unify_array env evd flags f1 l1 f2 l2 =
let subst = Array.fold_left2 fold_subst subst l1 l2 in
let evd = w_merge env true flags.merge_unify_flags subst in
try_resolve_typeclasses env evd flags.resolve_evars
- (mkApp(f1,l1)) (mkApp(f2,l2))
+ (mkApp(f1,l1)) (mkApp(f2,l2))
(* takes a substitution s, an open term op and a closed term cl
try to find a subterm of cl which matches op, if op is just a Meta
@@ -1470,10 +1482,10 @@ let indirectly_dependent c d decls =
it is needed otherwise, as e.g. when abstracting over "2" in
"forall H:0=2, H=H:>(0=1+1) -> 0=2." where there is now obvious
way to see that the second hypothesis depends indirectly over 2 *)
- List.exists (fun d' -> dependent_in_decl (mkVar (get_id d')) d) decls
+ List.exists (fun d' -> dependent_in_decl (mkVar (NamedDecl.get_id d')) d) decls
let indirect_dependency d decls =
- decls |> List.filter (fun d' -> dependent_in_decl (mkVar (get_id d')) d) |> List.hd |> get_id
+ decls |> List.filter (fun d' -> dependent_in_decl (mkVar (NamedDecl.get_id d')) d) |> List.hd |> NamedDecl.get_id
let finish_evar_resolution ?(flags=Pretyping.all_and_fail_flags) env current_sigma (pending,c) =
let current_sigma = Sigma.to_evar_map current_sigma in
@@ -1553,7 +1565,7 @@ let make_pattern_test from_prefix_of_ind is_correct_type env sigma (pending,c) =
| PretypeError (_,_,CannotUnify (c1,c2,Some e)) ->
raise (NotUnifiable (Some (c1,c2,e)))
(** MS: This is pretty bad, it catches Not_found for example *)
- | e when Errors.noncritical e -> raise (NotUnifiable None) in
+ | e when CErrors.noncritical e -> raise (NotUnifiable None) in
let merge_fun c1 c2 =
match c1, c2 with
| Some (evd,c1,x), Some (_,c2,_) ->
@@ -1583,8 +1595,8 @@ let make_abstraction_core name (test,out) env sigma c ty occs check_occs concl =
let x = id_of_name_using_hdchar (Global.env()) t name in
let ids = ids_of_named_context (named_context env) in
if name == Anonymous then next_ident_away_in_goal x ids else
- if mem_named_context x (named_context env) then
- errorlabstrm "Unification.make_abstraction_core"
+ if mem_named_context_val x (named_context_val env) then
+ user_err ~hdr:"Unification.make_abstraction_core"
(str "The variable " ++ Nameops.pr_id x ++ str " is already declared.")
else
x
@@ -1592,17 +1604,10 @@ let make_abstraction_core name (test,out) env sigma c ty occs check_occs concl =
let likefirst = clause_with_generic_occurrences occs in
let mkvarid () = mkVar id in
let compute_dependency _ d (sign,depdecls) =
- let hyp = get_id d in
+ let hyp = NamedDecl.get_id d in
match occurrences_of_hyp hyp occs with
| NoOccurrences, InHyp ->
- if indirectly_dependent c d depdecls then
- (* Told explicitly not to abstract over [d], but it is dependent *)
- let id' = indirect_dependency d depdecls in
- errorlabstrm "" (str "Cannot abstract over " ++ Nameops.pr_id id'
- ++ str " without also abstracting or erasing " ++ Nameops.pr_id hyp
- ++ str ".")
- else
- (push_named_context_val d sign,depdecls)
+ (push_named_context_val d sign,depdecls)
| AllOccurrences, InHyp as occ ->
let occ = if likefirst then LikeFirst else AtOccs occ in
let newdecl = replace_term_occ_decl_modulo occ test mkvarid d in
@@ -1629,7 +1634,7 @@ let make_abstraction_core name (test,out) env sigma c ty occs check_occs concl =
replace_term_occ_modulo occ test mkvarid concl
in
let lastlhyp =
- if List.is_empty depdecls then None else Some (get_id (List.last depdecls)) in
+ if List.is_empty depdecls then None else Some (NamedDecl.get_id (List.last depdecls)) in
let res = match out test with
| None -> None
| Some (sigma, c) -> Some (Sigma.Unsafe.of_pair (c, sigma))
@@ -1882,21 +1887,14 @@ let secondOrderAbstraction env evd flags typ (p, oplist) =
error_wrong_abstraction_type env evd'
(Evd.meta_name evd p) pred typp predtyp;
w_merge env false flags.merge_unify_flags
- (evd',[p,pred,(Conv,TypeProcessed)],[])
-
- (* let evd',metas,evars = *)
- (* try unify_0 env evd' CUMUL flags predtyp typp *)
- (* with NotConvertible -> *)
- (* error_wrong_abstraction_type env evd *)
- (* (Evd.meta_name evd p) pred typp predtyp *)
- (* in *)
- (* w_merge env false flags (evd',(p,pred,(Conv,TypeProcessed))::metas,evars) *)
+ (evd',[p,pred,(Conv,TypeProcessed)],[])
let secondOrderDependentAbstraction env evd flags typ (p, oplist) =
let typp = Typing.meta_type evd p in
let evd, pred = abstract_list_all_with_dependencies env evd typp typ oplist in
w_merge env false flags.merge_unify_flags
- (evd,[p,pred,(Conv,TypeProcessed)],[])
+ (evd,[p,pred,(Conv,TypeProcessed)],[])
+
let secondOrderAbstractionAlgo dep =
if dep then secondOrderDependentAbstraction else secondOrderAbstraction
diff --git a/pretyping/vnorm.ml b/pretyping/vnorm.ml
index 7ea9b90635..75159bf8bc 100644
--- a/pretyping/vnorm.ml
+++ b/pretyping/vnorm.ml
@@ -17,6 +17,9 @@ open Reduction
open Vm
open Context.Rel.Declaration
+module RelDecl = Context.Rel.Declaration
+module NamedDecl = Context.Named.Declaration
+
(*******************************************)
(* Calcul de la forme normal d'un terme *)
(*******************************************)
@@ -24,7 +27,7 @@ open Context.Rel.Declaration
let crazy_type = mkSet
let decompose_prod env t =
- let (name,dom,codom as res) = destProd (whd_betadeltaiota env t) in
+ let (name,dom,codom as res) = destProd (whd_all env t) in
match name with
| Anonymous -> (Name (Id.of_string "x"), dom, codom)
| Name _ -> res
@@ -46,7 +49,11 @@ let invert_tag cst tag reloc_tbl =
with Find_at j -> (j+1)
(* Argggg, ces constructeurs de ... qui commencent a 1*)
-let find_rectype_a env c = Inductiveops.find_mrectype_vect env Evd.empty c
+let find_rectype_a env c =
+ let (t, l) = decompose_appvect (whd_all env c) in
+ match kind_of_term t with
+ | Ind ind -> (ind, l)
+ | _ -> assert false
(* Instantiate inductives and parameters in constructor type *)
@@ -203,12 +210,11 @@ and constr_type_of_idkey env (idkey : Vars.id_key) stk =
in
nf_univ_args ~nb_univs mk env stk
| VarKey id ->
- let open Context.Named.Declaration in
- let ty = get_type (lookup_named id env) in
+ let ty = NamedDecl.get_type (lookup_named id env) in
nf_stk env (mkVar id) ty stk
| RelKey i ->
let n = (nb_rel env - i) in
- let ty = get_type (lookup_rel n env) in
+ let ty = RelDecl.get_type (lookup_rel n env) in
nf_stk env (mkRel n) (lift n ty) stk
and nf_stk ?from:(from=0) env c t stk =
@@ -234,7 +240,7 @@ and nf_stk ?from:(from=0) env c t stk =
let params,realargs = Util.Array.chop nparams allargs in
let pT =
hnf_prod_applist env (type_of_ind env (ind,u)) (Array.to_list params) in
- let pT = whd_betadeltaiota env pT in
+ let pT = whd_all env pT in
let dep, p = nf_predicate env (ind,u) mip params (type_of_switch sw) pT in
(* Calcul du type des branches *)
let btypes = build_branches_type env ind mib mip u params dep p in
@@ -305,7 +311,7 @@ and nf_fun env f typ =
try decompose_prod env typ
with DestKO ->
(* 27/2/13: Turned this into an anomaly *)
- Errors.anomaly
+ CErrors.anomaly
(Pp.strbrk "Returned a functional value in a type not recognized as a product type.")
in
let body = nf_val (push_rel (LocalAssum (name,dom)) env) vb codom in