diff options
Diffstat (limited to 'pretyping')
| -rw-r--r-- | pretyping/arguments_renaming.ml | 6 | ||||
| -rw-r--r-- | pretyping/cases.ml | 387 | ||||
| -rw-r--r-- | pretyping/cases.mli | 26 | ||||
| -rw-r--r-- | pretyping/classops.ml | 53 | ||||
| -rw-r--r-- | pretyping/classops.mli | 4 | ||||
| -rw-r--r-- | pretyping/coercion.ml | 9 | ||||
| -rw-r--r-- | pretyping/globEnv.ml | 201 | ||||
| -rw-r--r-- | pretyping/globEnv.mli | 83 | ||||
| -rw-r--r-- | pretyping/glob_ops.ml | 20 | ||||
| -rw-r--r-- | pretyping/glob_ops.mli | 1 | ||||
| -rw-r--r-- | pretyping/inferCumulativity.ml | 2 | ||||
| -rw-r--r-- | pretyping/ltac_pretype.ml | 2 | ||||
| -rw-r--r-- | pretyping/pretyping.ml | 459 | ||||
| -rw-r--r-- | pretyping/pretyping.mli | 8 | ||||
| -rw-r--r-- | pretyping/pretyping.mllib | 1 | ||||
| -rw-r--r-- | pretyping/recordops.ml | 14 | ||||
| -rw-r--r-- | pretyping/reductionops.ml | 19 | ||||
| -rw-r--r-- | pretyping/reductionops.mli | 3 | ||||
| -rw-r--r-- | pretyping/typeclasses.ml | 40 |
19 files changed, 735 insertions, 603 deletions
diff --git a/pretyping/arguments_renaming.ml b/pretyping/arguments_renaming.ml index 9d4badc60a..b8958ca944 100644 --- a/pretyping/arguments_renaming.ml +++ b/pretyping/arguments_renaming.ml @@ -21,7 +21,7 @@ module NamedDecl = Context.Named.Declaration (*i*) let name_table = - Summary.ref (Refmap.empty : Name.t list Refmap.t) + Summary.ref (GlobRef.Map.empty : Name.t list GlobRef.Map.t) ~name:"rename-arguments" type req = @@ -29,7 +29,7 @@ type req = | ReqGlobal of GlobRef.t * Name.t list let load_rename_args _ (_, (_, (r, names))) = - name_table := Refmap.add r names !name_table + name_table := GlobRef.Map.add r names !name_table let cache_rename_args o = load_rename_args 1 o @@ -68,7 +68,7 @@ let rename_arguments local r names = let req = if local then ReqLocal else ReqGlobal (r, names) in Lib.add_anonymous_leaf (inRenameArgs (req, (r, names))) -let arguments_names r = Refmap.find r !name_table +let arguments_names r = GlobRef.Map.find r !name_table let rec rename_prod c = function | [] -> c diff --git a/pretyping/cases.ml b/pretyping/cases.ml index ad33297f0a..7baa755ab5 100644 --- a/pretyping/cases.ml +++ b/pretyping/cases.ml @@ -35,7 +35,7 @@ open Evarsolve open Evarconv open Evd open Context.Rel.Declaration -open Ltac_pretype +open GlobEnv module RelDecl = Context.Rel.Declaration module NamedDecl = Context.Named.Declaration @@ -114,8 +114,10 @@ let rec relocate_index sigma n1 n2 k t = (**********************************************************************) (* Structures used in compiling pattern-matching *) +let (!!) env = GlobEnv.env env + type 'a rhs = - { rhs_env : env; + { rhs_env : GlobEnv.t; rhs_vars : Id.Set.t; avoid_ids : Id.Set.t; it : 'a option} @@ -247,8 +249,7 @@ let push_history_pattern n pci cont = *) type 'a pattern_matching_problem = - { env : env; - lvar : Ltac_pretype.ltac_var_map; + { env : GlobEnv.t; evdref : evar_map ref; pred : constr; tomatch : tomatch_stack; @@ -256,7 +257,7 @@ type 'a pattern_matching_problem = mat : 'a matrix; caseloc : Loc.t option; casestyle : case_style; - typing_function: type_constraint -> env -> evar_map ref -> 'a option -> unsafe_judgment } + typing_function: type_constraint -> GlobEnv.t -> evar_map ref -> 'a option -> unsafe_judgment } (*--------------------------------------------------------------------------* * A few functions to infer the inductive type from the patterns instead of * @@ -331,6 +332,10 @@ let binding_vars_of_inductive sigma = function | NotInd _ -> [] | IsInd (_,IndType(_,realargs),_) -> List.filter (isRel sigma) realargs +let set_tomatch_realnames names = function + | NotInd _ as t -> t + | IsInd (typ,ind,_) -> IsInd (typ,ind,names) + let extract_inductive_data env sigma decl = match decl with | LocalAssum (_,t) -> @@ -357,58 +362,58 @@ let find_tomatch_tycon evdref env loc = function | None -> empty_tycon,None -let make_return_predicate_ltac_lvar sigma na tm c lvar = +let make_return_predicate_ltac_lvar env sigma na tm c = + (* If we have an [x as x return ...] clause and [x] expands to [c], + we have to update the status of [x] in the substitution: + - if [c] is a variable [id'], then [x] should now become [id'] + - otherwise, [x] should be hidden *) match na, DAst.get tm with | Name id, (GVar id' | GRef (Globnames.VarRef id', _)) when Id.equal id id' -> - if Id.Map.mem id lvar.ltac_genargs then - let ltac_genargs = Id.Map.remove id lvar.ltac_genargs in - let ltac_idents = match kind sigma c with - | Var id' -> Id.Map.add id id' lvar.ltac_idents - | _ -> lvar.ltac_idents in - { lvar with ltac_genargs; ltac_idents } - else lvar - | _ -> lvar - -let ltac_interp_realnames lvar = function - | t, IsInd (ty,ind,realnal) -> t, IsInd (ty,ind,List.map (ltac_interp_name lvar) realnal) - | _ as x -> x + let expansion = match kind sigma c with + | Var id' -> Name id' + | _ -> Anonymous in + GlobEnv.hide_variable env expansion id + | _ -> env let is_patvar pat = match DAst.get pat with | PatVar _ -> true | _ -> false -let coerce_row typing_fun evdref env lvar pats (tomatch,(na,indopt)) = +let coerce_row typing_fun evdref env pats (tomatch,(na,indopt)) = let loc = loc_of_glob_constr tomatch in - let tycon,realnames = find_tomatch_tycon evdref env loc indopt in - let j = typing_fun tycon env evdref !lvar tomatch in - let j = evd_comb1 (Coercion.inh_coerce_to_base ?loc:(loc_of_glob_constr tomatch) env) evdref j in + let tycon,realnames = find_tomatch_tycon evdref !!env loc indopt in + let j = typing_fun tycon env evdref tomatch in + let j = evd_comb1 (Coercion.inh_coerce_to_base ?loc:(loc_of_glob_constr tomatch) !!env) evdref j in let typ = nf_evar !evdref j.uj_type in - lvar := make_return_predicate_ltac_lvar !evdref na tomatch j.uj_val !lvar; + let env = make_return_predicate_ltac_lvar env !evdref na tomatch j.uj_val in let t = if realnames = None && pats <> [] && List.for_all is_patvar pats then NotInd (None,typ) else - try try_find_ind env !evdref typ realnames + try try_find_ind !!env !evdref typ realnames with Not_found -> - unify_tomatch_with_patterns evdref env loc typ pats realnames in - (j.uj_val,t) + unify_tomatch_with_patterns evdref !!env loc typ pats realnames in + (env,(j.uj_val,t)) -let coerce_to_indtype typing_fun evdref env lvar matx tomatchl = +let coerce_to_indtype typing_fun evdref env matx tomatchl = let pats = List.map (fun r -> r.patterns) matx in let matx' = match matrix_transpose pats with | [] -> List.map (fun _ -> []) tomatchl (* no patterns at all *) | m -> m in - let lvar = ref lvar in - let tms = List.map2 (coerce_row typing_fun evdref env lvar) matx' tomatchl in - let tms = List.map (ltac_interp_realnames !lvar) tms in - !lvar,tms + let env,tms = List.fold_left2_map (fun env -> coerce_row typing_fun evdref env) env matx' tomatchl in + env,tms (************************************************************************) (* Utils *) let mkExistential env ?(src=(Loc.tag Evar_kinds.InternalHole)) evdref = - let (e, u) = evd_comb1 (new_type_evar env ~src:src) evdref univ_flexible_alg in + let (e, u) = evd_comb1 (new_type_evar env ~src:src) evdref univ_flexible_alg in e +let evd_comb2 f evdref x y = + let (evd',y) = f !evdref x y in + evdref := evd'; + y + let adjust_tomatch_to_pattern pb ((current,typ),deps,dep) = (* Ideally, we could find a common inductive type to which both the term to match and the patterns coerce *) @@ -418,7 +423,7 @@ let adjust_tomatch_to_pattern pb ((current,typ),deps,dep) = let typ,names = match typ with IsInd(t,_,names) -> t,Some names | NotInd(_,t) -> t,None in let tmtyp = - try try_find_ind pb.env !(pb.evdref) typ names + try try_find_ind !!(pb.env) !(pb.evdref) typ names with Not_found -> NotInd (None,typ) in match tmtyp with | NotInd (None,typ) -> @@ -426,17 +431,17 @@ let adjust_tomatch_to_pattern pb ((current,typ),deps,dep) = (match find_row_ind tm1 with | None -> (current,tmtyp) | Some (_,(ind,_)) -> - let indt = inductive_template pb.evdref pb.env None ind in + let indt = inductive_template pb.evdref !!(pb.env) None ind in let current = if List.is_empty deps && isEvar !(pb.evdref) typ then (* Don't insert coercions if dependent; only solve evars *) - let () = Option.iter ((:=) pb.evdref) (cumul pb.env !(pb.evdref) indt typ) in + let () = Option.iter ((:=) pb.evdref) (cumul !!(pb.env) !(pb.evdref) indt typ) in current else - (evd_comb2 (Coercion.inh_conv_coerce_to true pb.env) + (evd_comb2 (Coercion.inh_conv_coerce_to true !!(pb.env)) pb.evdref (make_judge current typ) indt).uj_val in let sigma = !(pb.evdref) in - (current,try_find_ind pb.env sigma indt names)) + (current,try_find_ind !!(pb.env) sigma indt names)) | _ -> (current,tmtyp) let type_of_tomatch = function @@ -466,10 +471,10 @@ let remove_current_pattern eqn = alias_stack = alias_of_pat pat :: eqn.alias_stack } | [] -> anomaly (Pp.str "Empty list of patterns.") -let push_current_pattern (cur,ty) eqn = +let push_current_pattern sigma (cur,ty) eqn = match eqn.patterns with | pat::pats -> - let rhs_env = push_rel (LocalDef (alias_of_pat pat,cur,ty)) eqn.rhs.rhs_env in + let _,rhs_env = push_rel sigma (LocalDef (alias_of_pat pat,cur,ty)) eqn.rhs.rhs_env in { eqn with rhs = { eqn.rhs with rhs_env = rhs_env }; patterns = pats } @@ -739,7 +744,7 @@ let merge_name get_name obj = function let merge_names get_name = List.map2 (merge_name get_name) -let get_names env sigma sign eqns = +let get_names avoid env sigma sign eqns = let names1 = List.make (Context.Rel.length sign) Anonymous in (* If any, we prefer names used in pats, from top to bottom *) let names2,aliasname = @@ -752,7 +757,7 @@ let get_names env sigma sign eqns = avoiding conflicts with user ids *) let allvars = List.fold_left (fun l (_,_,eqn) -> Id.Set.union l eqn.rhs.avoid_ids) - Id.Set.empty eqns in + avoid eqns in let names3,_ = List.fold_left2 (fun (l,avoid) d na -> @@ -774,7 +779,7 @@ let get_names env sigma sign eqns = let recover_initial_subpattern_names = List.map2 RelDecl.set_name -let recover_and_adjust_alias_names names sign = +let recover_and_adjust_alias_names (_,avoid) names sign = let rec aux = function | [],[] -> [] @@ -786,31 +791,31 @@ let recover_and_adjust_alias_names names sign = in List.split (aux (names,sign)) -let push_rels_eqn sign eqn = +let push_rels_eqn sigma sign eqn = {eqn with - rhs = {eqn.rhs with rhs_env = push_rel_context sign eqn.rhs.rhs_env} } + rhs = {eqn.rhs with rhs_env = snd (push_rel_context sigma sign eqn.rhs.rhs_env) } } -let push_rels_eqn_with_names sign eqn = +let push_rels_eqn_with_names sigma sign eqn = let subpats = List.rev (List.firstn (List.length sign) eqn.patterns) in let subpatnames = List.map alias_of_pat subpats in let sign = recover_initial_subpattern_names subpatnames sign in - push_rels_eqn sign eqn + push_rels_eqn sigma sign eqn -let push_generalized_decl_eqn env n decl eqn = +let push_generalized_decl_eqn env sigma n decl eqn = match RelDecl.get_name decl with | Anonymous -> - push_rels_eqn [decl] eqn + push_rels_eqn sigma [decl] eqn | Name _ -> - push_rels_eqn [RelDecl.set_name (RelDecl.get_name (Environ.lookup_rel n eqn.rhs.rhs_env)) decl] eqn + push_rels_eqn sigma [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 } -let push_alias_eqn alias eqn = +let push_alias_eqn sigma alias eqn = let aliasname = List.hd eqn.alias_stack in let eqn = drop_alias_eqn eqn in let alias = RelDecl.set_name aliasname alias in - push_rels_eqn [alias] eqn + push_rels_eqn sigma [alias] eqn (**********************************************************************) (* Functions to deal with elimination predicate *) @@ -958,7 +963,7 @@ let rec extract_predicate ccl = function ccl let abstract_predicate env sigma indf cur realargs (names,na) tms ccl = - let sign = make_arity_signature env sigma true indf in + let sign = make_arity_signature !!env sigma true indf in (* n is the number of real args + 1 (+ possible let-ins in sign) *) let n = List.length sign in (* Before abstracting we generalize over cur and on those realargs *) @@ -979,7 +984,7 @@ let abstract_predicate env sigma indf cur realargs (names,na) tms ccl = let pred = extract_predicate ccl tms in (* Build the predicate properly speaking *) let sign = List.map2 set_name (na::names) sign in - it_mkLambda_or_LetIn_name env sigma pred sign + it_mkLambda_or_LetIn_name !!env sigma pred sign (* [expand_arg] is used by [specialize_predicate] if Yk denotes [Xk;xk] or [Xk], @@ -1208,7 +1213,7 @@ let first_clause_irrefutable env = function let group_equations pb ind current cstrs mat = let mat = - if first_clause_irrefutable pb.env mat then [List.hd mat] else mat in + if first_clause_irrefutable !!(pb.env) mat then [List.hd mat] else mat in let brs = Array.make (Array.length cstrs) [] in let only_default = ref None in let _ = @@ -1216,7 +1221,7 @@ let group_equations pb ind current cstrs mat = (fun eqn () -> let rest = remove_current_pattern eqn in let pat = current_pattern eqn in - match DAst.get (check_and_adjust_constructor pb.env ind cstrs pat) with + match DAst.get (check_and_adjust_constructor !!(pb.env) ind cstrs pat) with | PatVar name -> (* This is a default clause that we expand *) for i=1 to Array.length cstrs do @@ -1238,7 +1243,7 @@ let rec generalize_problem names pb = function | [] -> pb, [] | i::l -> let pb',deps = generalize_problem names pb l in - let d = map_constr (lift i) (lookup_rel i pb.env) in + let d = map_constr (lift i) (lookup_rel i !!(pb.env)) in begin match d with | LocalDef (Anonymous,_,_) -> pb', deps | _ -> @@ -1271,7 +1276,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 cs_args = List.map (fun d -> map_rel_decl EConstr.of_constr d) cs_args in - let names,aliasname = get_names pb.env !(pb.evdref) cs_args eqns in + let names,aliasname = get_names (GlobEnv.vars_of_env pb.env) !!(pb.env) !(pb.evdref) cs_args eqns in let typs = List.map2 RelDecl.set_name names cs_args in @@ -1279,7 +1284,7 @@ let build_branch initial current realargs deps (realnames,curname) pb arsign eqn (* This is a bit too strong I think, in the sense that what we would *) (* really like is to have beta-iota reduction only at the positions where *) (* parameters are substituted *) - let typs = List.map (map_type (nf_betaiota pb.env !(pb.evdref))) typs in + let typs = List.map (map_type (nf_betaiota !!(pb.env) !(pb.evdref))) typs in (* We build the matrix obtained by expanding the matching on *) (* "C x1..xn as x" followed by a residual matching on eqn into *) @@ -1291,11 +1296,11 @@ let build_branch initial current realargs deps (realnames,curname) pb arsign eqn let typs' = List.map_i (fun i d -> (mkRel i, map_constr (lift i) d)) 1 typs in - let extenv = push_rel_context typs pb.env in + let typs,extenv = push_rel_context !(pb.evdref) typs pb.env in let typs' = List.map (fun (c,d) -> - (c,extract_inductive_data extenv !(pb.evdref) d,d)) typs' in + (c,extract_inductive_data !!extenv !(pb.evdref) d,d)) typs' in (* We compute over which of x(i+1)..xn and x matching on xi will need a *) (* generalization *) @@ -1360,7 +1365,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 (pb.env, Evd.empty, NonExhaustive (complete_history history)) + raise_pattern_matching_error (!!(pb.env), Evd.empty, NonExhaustive (complete_history history)) | _ -> () in @@ -1370,7 +1375,7 @@ let build_branch initial current realargs deps (realnames,curname) pb arsign eqn tomatch = tomatch; pred = pred; history = history; - mat = List.map (push_rels_eqn_with_names typs) submat } + mat = List.map (push_rels_eqn_with_names !(pb.evdref) typs) submat } (********************************************************************** INVARIANT: @@ -1400,13 +1405,13 @@ and match_current pb (initial,tomatch) = let ((current,typ),deps,dep) = tomatch in match typ with | NotInd (_,typ) -> - check_all_variables pb.env !(pb.evdref) typ pb.mat; + check_all_variables !!(pb.env) !(pb.evdref) typ pb.mat; compile_all_variables initial tomatch pb | IsInd (_,(IndType(indf,realargs) as indt),names) -> let mind,_ = dest_ind_family indf in - let mind = Tacred.check_privacy pb.env mind in - let cstrs = get_constructors pb.env indf in - let arsign, _ = get_arity pb.env indf in + let mind = Tacred.check_privacy !!(pb.env) mind in + let cstrs = get_constructors !!(pb.env) indf in + let arsign, _ = get_arity !!(pb.env) indf in let eqns,onlydflt = group_equations pb (fst mind) current cstrs pb.mat in let no_cstr = Int.equal (Array.length cstrs) 0 in if (not no_cstr || not (List.is_empty pb.mat)) && onlydflt then @@ -1423,18 +1428,17 @@ and match_current pb (initial,tomatch) = postprocess_dependencies !(pb.evdref) depstocheck brvals pb.tomatch pb.pred deps cstrs in let brvals = Array.map (fun (sign,body) -> - let sign = List.map (map_name (ltac_interp_name pb.lvar)) sign in it_mkLambda_or_LetIn body sign) brvals in let (pred,typ) = - find_predicate pb.caseloc pb.env pb.evdref + find_predicate pb.caseloc pb.env pb.evdref pred current indt (names,dep) tomatch in - let ci = make_case_info pb.env (fst mind) pb.casestyle in - let pred = nf_betaiota pb.env !(pb.evdref) pred in + let ci = make_case_info !!(pb.env) (fst mind) pb.casestyle in + let pred = nf_betaiota !!(pb.env) !(pb.evdref) pred in let case = - make_case_or_project pb.env !(pb.evdref) indf ci pred current brvals + make_case_or_project !!(pb.env) !(pb.evdref) indf ci pred current brvals in - let _ = Evarutil.evd_comb1 (Typing.type_of pb.env) pb.evdref pred in - Typing.check_allowed_sort pb.env !(pb.evdref) mind current pred; + let _ = Evarutil.evd_comb1 (Typing.type_of !!(pb.env)) pb.evdref pred in + Typing.check_allowed_sort !!(pb.env) !(pb.evdref) mind current pred; { uj_val = applist (case, inst); uj_type = prod_applist !(pb.evdref) typ inst } @@ -1444,14 +1448,15 @@ 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.env pb.tomatch pb.pred in + let pred = specialize_predicate_var (current,t,na) !!(pb.env) pb.tomatch pb.pred in + let env = Name.fold_left (fun env id -> hide_variable env Anonymous id) pb.env na in let pb = { pb with - env = push_rel (LocalDef (na,current,ty)) pb.env; + env = snd (push_rel !(pb.evdref) (LocalDef (na,current,ty)) env); tomatch = tomatch; pred = lift_predicate 1 pred tomatch; history = pop_history pb.history; - mat = List.map (push_current_pattern (current,ty)) pb.mat } in + mat = List.map (push_current_pattern !(pb.evdref) (current,ty)) pb.mat } in let j = compile pb in { uj_val = subst1 current j.uj_val; uj_type = subst1 current j.uj_type } @@ -1461,7 +1466,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.env 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; @@ -1483,9 +1488,9 @@ and compile_branch initial current realargs names deps pb arsign eqns cstr = and compile_generalization pb i d rest = let pb = { pb with - env = push_rel d pb.env; + env = snd (push_rel !(pb.evdref) d pb.env); tomatch = rest; - mat = List.map (push_generalized_decl_eqn pb.env i d) pb.mat } in + mat = List.map (push_generalized_decl_eqn pb.env !(pb.evdref) i d) pb.mat } in let j = compile pb in { uj_val = mkLambda_or_LetIn d j.uj_val; uj_type = mkProd_wo_LetIn d j.uj_type } @@ -1498,11 +1503,11 @@ and compile_alias initial pb (na,orig,(expanded,expanded_typ)) rest = let alias = LocalDef (na,c,t) in let pb = { pb with - env = push_rel alias pb.env; + env = snd (push_rel !(pb.evdref) alias pb.env); tomatch = lift_tomatch_stack 1 rest; pred = lift_predicate 1 pb.pred pb.tomatch; history = pop_history_pattern pb.history; - mat = List.map (push_alias_eqn alias) pb.mat } in + mat = List.map (push_alias_eqn !(pb.evdref) alias) pb.mat } in let j = compile pb in let sigma = !(pb.evdref) in { uj_val = @@ -1534,7 +1539,7 @@ and compile_alias initial pb (na,orig,(expanded,expanded_typ)) rest = if not (Flags.is_program_mode ()) && (isRel sigma orig || isVar sigma orig) then (* Try to compile first using non expanded alias *) try - if initial then f orig (Retyping.get_type_of pb.env sigma orig) + if initial then f orig (Retyping.get_type_of !!(pb.env) sigma orig) else just_pop () with e when precatchable_exception e -> (* Try then to compile using expanded alias *) @@ -1549,7 +1554,7 @@ and compile_alias initial pb (na,orig,(expanded,expanded_typ)) rest = (* Could be needed in case of a recursive call which requires to be on a variable for size reasons *) pb.evdref := sigma; - if initial then f orig (Retyping.get_type_of pb.env !(pb.evdref) orig) + if initial then f orig (Retyping.get_type_of !!(pb.env) !(pb.evdref) orig) else just_pop () @@ -1573,7 +1578,7 @@ substituer après par les initiaux *) * Syntactic correctness has already been done in constrintern *) let matx_of_eqns env eqns = let build_eqn {CAst.loc;v=(ids,initial_lpat,initial_rhs)} = - let avoid = ids_of_named_context_val (named_context_val env) in + let avoid = ids_of_named_context_val (named_context_val !!env) in let avoid = List.fold_left (fun accu id -> Id.Set.add id accu) avoid ids in let rhs = { rhs_env = env; @@ -1616,8 +1621,8 @@ let matx_of_eqns env eqns = *) let adjust_to_extended_env_and_remove_deps env extenv sigma subst t = - let n = Context.Rel.length (rel_context env) in - let n' = Context.Rel.length (rel_context extenv) in + let n = Context.Rel.length (rel_context !!env) in + let n' = Context.Rel.length (rel_context !!extenv) in (* We first remove the bindings that are dependently typed (they are difficult to manage and it is not sure these are so useful in practice); Notes: @@ -1630,22 +1635,22 @@ let adjust_to_extended_env_and_remove_deps env extenv sigma subst t = (* d1 ... dn dn+1 ... dn'-p+1 ... dn' *) (* \--env-/ (= x:ty) *) (* \--------------extenv------------/ *) - let (p, _, _) = lookup_rel_id x (rel_context extenv) in + let (p, _, _) = lookup_rel_id x (rel_context !!extenv) in let rec traverse_local_defs p = - match lookup_rel p extenv with + match lookup_rel p !!extenv with | LocalDef (_,c,_) -> assert (isRel sigma c); traverse_local_defs (p + destRel sigma c) | LocalAssum _ -> p in let p = traverse_local_defs p in let u = lift (n' - n) u in - try Some (p, u, expand_vars_in_term extenv sigma u) + try Some (p, u, expand_vars_in_term !!extenv sigma u) (* pedrot: does this really happen to raise [Failure _]? *) with Failure _ -> None in let subst0 = List.map_filter map subst in let t0 = lift (n' - n) t in (subst0, t0) -let push_binder d (k,env,subst) = - (k+1,push_rel d env,List.map (fun (na,u,d) -> (na,lift 1 u,d)) subst) +let push_binder sigma d (k,env,subst) = + (k+1,snd (push_rel sigma d env),List.map (fun (na,u,d) -> (na,lift 1 u,d)) subst) let rec list_assoc_in_triple x = function [] -> raise Not_found @@ -1667,7 +1672,7 @@ let rec list_assoc_in_triple x = function *) let abstract_tycon ?loc env evdref subst tycon extenv t = - let t = nf_betaiota env !evdref t in (* it helps in some cases to remove K-redex*) + let t = nf_betaiota !!env !evdref t in (* it helps in some cases to remove K-redex*) let src = match EConstr.kind !evdref t with | Evar (evk,_) -> (Loc.tag ?loc @@ Evar_kinds.SubEvar (None,evk)) | _ -> (Loc.tag ?loc @@ Evar_kinds.CasesType true) in @@ -1679,31 +1684,31 @@ let abstract_tycon ?loc env evdref subst tycon extenv t = convertible subterms of the substitution *) let rec aux (k,env,subst as x) t = match EConstr.kind !evdref t with - | Rel n when is_local_def (lookup_rel n env) -> t + | Rel n when is_local_def (lookup_rel n !!env) -> t | Evar ev -> - let ty = get_type_of env !evdref t in - let ty = Evarutil.evd_comb1 (refresh_universes (Some false) env) evdref ty in + let ty = get_type_of !!env !evdref t in + let ty = Evarutil.evd_comb1 (refresh_universes (Some false) !!env) evdref ty in let inst = List.map_i (fun i _ -> try list_assoc_in_triple i subst0 with Not_found -> mkRel i) - 1 (rel_context env) in - let ev' = evd_comb1 (Evarutil.new_evar env ~src) evdref ty in - begin match solve_simple_eqn (evar_conv_x full_transparent_state) env !evdref (None,ev,substl inst ev') with + 1 (rel_context !!env) in + let ev' = evd_comb1 (Evarutil.new_evar !!env ~src) evdref ty in + begin match solve_simple_eqn (evar_conv_x full_transparent_state) !!env !evdref (None,ev,substl inst ev') with | Success evd -> evdref := evd | UnifFailure _ -> assert false end; ev' | _ -> - let good = List.filter (fun (_,u,_) -> is_conv_leq env !evdref t u) subst in + let good = List.filter (fun (_,u,_) -> is_conv_leq !!env !evdref t u) subst in match good with | [] -> - map_constr_with_full_binders !evdref push_binder aux x t + map_constr_with_full_binders !evdref (push_binder !evdref) aux x t | (_, _, u) :: _ -> (* u is in extenv *) let vl = List.map pi1 good in let ty = - let ty = get_type_of env !evdref t in - Evarutil.evd_comb1 (refresh_universes (Some false) env) evdref ty + let ty = get_type_of !!env !evdref t in + Evarutil.evd_comb1 (refresh_universes (Some false) !!env) evdref ty in let dummy_subst = List.init k (fun _ -> mkProp) in let ty = substl dummy_subst (aux x ty) in @@ -1711,7 +1716,7 @@ let abstract_tycon ?loc env evdref subst tycon extenv t = let inst = List.map_i (fun i _ -> if Int.List.mem i vl then u else mkRel i) 1 - (rel_context extenv) in + (rel_context !!extenv) in let map a = match EConstr.kind !evdref a with | Rel n -> not (noccurn !evdref n u) || Int.Set.mem n depvl | _ -> true @@ -1719,10 +1724,10 @@ let abstract_tycon ?loc env evdref subst tycon extenv t = let rel_filter = List.map map inst in let named_filter = List.map (fun d -> local_occur_var !evdref (NamedDecl.get_id d) u) - (named_context extenv) in + (named_context !!extenv) in let filter = Filter.make (rel_filter @ named_filter) in let candidates = u :: List.map mkRel vl in - let ev = evd_comb1 (Evarutil.new_evar extenv ~src ~filter ~candidates) evdref ty in + let ev = evd_comb1 (Evarutil.new_evar !!extenv ~src ~filter ~candidates) evdref ty in lift k ev in aux (0,extenv,subst0) t0 @@ -1732,19 +1737,19 @@ let build_tycon ?loc env tycon_env s subst tycon extenv evdref t = | None -> (* This is the situation we are building a return predicate and we are in an impossible branch *) - let n = Context.Rel.length (rel_context env) in - let n' = Context.Rel.length (rel_context tycon_env) in + let n = Context.Rel.length (rel_context !!env) in + let n' = Context.Rel.length (rel_context !!tycon_env) in let impossible_case_type, u = evd_comb1 - (new_type_evar (reset_context env) ~src:(Loc.tag ?loc Evar_kinds.ImpossibleCase)) + (new_type_evar (reset_context !!env) ~src:(Loc.tag ?loc Evar_kinds.ImpossibleCase)) evdref univ_flexible_alg in (lift (n'-n) impossible_case_type, mkSort u) | Some t -> let t = abstract_tycon ?loc tycon_env evdref subst tycon extenv t in - let tt = evd_comb1 (Typing.type_of extenv) evdref t in + let tt = evd_comb1 (Typing.type_of !!extenv) evdref t in (t,tt) in - match cumul env !evdref tt (mkSort s) with + match cumul !!env !evdref tt (mkSort s) with | None -> anomaly (Pp.str "Build_tycon: should be a type."); | Some sigma -> evdref := sigma; { uj_val = t; uj_type = tt } @@ -1761,14 +1766,14 @@ let build_tycon ?loc env tycon_env s subst tycon extenv evdref t = let build_inversion_problem loc env sigma tms t = let make_patvar t (subst,avoid) = - let id = next_name_away (named_hd env sigma t Anonymous) avoid in + let id = next_name_away (named_hd !!env sigma t Anonymous) avoid in DAst.make @@ PatVar (Name id), ((id,t)::subst, Id.Set.add id avoid) in let rec reveal_pattern t (subst,avoid as acc) = - match EConstr.kind sigma (whd_all env sigma t) with + match EConstr.kind sigma (whd_all !!env sigma t) with | Construct (cstr,u) -> DAst.make (PatCstr (cstr,[],Anonymous)), acc | App (f,v) when isConstruct sigma f -> let cstr,u = destConstruct sigma f in - let n = constructor_nrealargs_env env cstr in + let n = constructor_nrealargs_env !!env cstr in let l = List.lastn n (Array.to_list v) in let l,acc = List.fold_right_map reveal_pattern l acc in DAst.make (PatCstr (cstr,l,Anonymous)), acc @@ -1780,19 +1785,19 @@ let build_inversion_problem loc env sigma tms t = let patl,acc = List.fold_right_map reveal_pattern realargs acc in let pat,acc = make_patvar t acc in let indf' = lift_inductive_family n indf in - let sign = make_arity_signature env sigma true indf' in + let sign = make_arity_signature !!env sigma true indf' in let patl = pat :: List.rev patl in - let patl,sign = recover_and_adjust_alias_names patl sign in + let patl,sign = recover_and_adjust_alias_names acc patl sign in let p = List.length patl in - let env' = push_rel_context sign env in + let _,env' = push_rel_context sigma sign env in let patl',acc_sign,acc = aux (n+p) env' (sign@acc_sign) tms acc in List.rev_append patl patl',acc_sign,acc | (t, NotInd (bo,typ)) :: tms -> let pat,acc = make_patvar t acc in let d = LocalAssum (alias_of_pat pat,typ) in - let patl,acc_sign,acc = aux (n+1) (push_rel d env) (d::acc_sign) tms acc in + let patl,acc_sign,acc = aux (n+1) (snd (push_rel sigma d env)) (d::acc_sign) tms acc in pat::patl,acc_sign,acc in - let avoid0 = vars_of_env env in + let avoid0 = GlobEnv.vars_of_env env in (* [patl] is a list of patterns revealing the substructure of constructors present in the constraints on the type of the multiple terms t1..tn that are matched in the original problem; @@ -1808,9 +1813,9 @@ let build_inversion_problem loc env sigma tms t = let decls = List.map_i (fun i d -> (mkRel i, map_constr (lift i) d)) 1 sign in - let pb_env = push_rel_context sign env in + let _,pb_env = push_rel_context sigma sign env in let decls = - List.map (fun (c,d) -> (c,extract_inductive_data pb_env sigma d,d)) decls in + List.map (fun (c,d) -> (c,extract_inductive_data !!(pb_env) sigma d,d)) decls in let decls = List.rev decls in let dep_sign = find_dependencies_signature sigma (List.make n true) decls in @@ -1843,7 +1848,7 @@ let build_inversion_problem loc env sigma tms t = constraints are incompatible with the constraints on the inductive types of the multiple terms matched in Xi *) let catch_all_eqn = - if List.for_all (irrefutable env) patl then + if List.for_all (irrefutable !!env) patl then (* No need for a catch all clause *) [] else @@ -1857,13 +1862,12 @@ 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 s' = Retyping.get_sort_of env sigma t in + let s' = Retyping.get_sort_of !!env sigma t in let sigma, s = Evd.new_sort_variable univ_flexible sigma in - let sigma = Evd.set_leq_sort env sigma s' s in + let sigma = Evd.set_leq_sort !!env sigma s' s in let evdref = ref sigma in let pb = { env = pb_env; - lvar = empty_lvar; evdref = evdref; pred = (*ty *) mkSort s; tomatch = sub_tms; @@ -1878,16 +1882,16 @@ let build_inversion_problem loc env sigma tms t = (* Here, [pred] is assumed to be in the context built from all *) (* realargs and terms to match *) let build_initial_predicate arsign pred = - let rec buildrec n pred tmnames = function + let rec buildrec pred tmnames = function | [] -> List.rev tmnames,pred | (decl::realdecls)::lnames -> let na = RelDecl.get_name decl in - let n' = n + List.length realdecls in - buildrec (n'+1) pred (force_name na::tmnames) lnames + let realnames = List.map RelDecl.get_name realdecls in + buildrec pred ((force_name na,realnames)::tmnames) lnames | _ -> assert false - in buildrec 0 pred [] (List.rev arsign) + in buildrec pred [] (List.rev arsign) -let extract_arity_signature ?(dolift=true) env0 lvar tomatchl tmsign = +let extract_arity_signature ?(dolift=true) env0 tomatchl tmsign = let lift = if dolift then lift else fun n t -> t in let get_one_sign n tm (na,t) = match tm with @@ -1895,7 +1899,7 @@ let extract_arity_signature ?(dolift=true) env0 lvar tomatchl tmsign = (match t with | None -> let sign = match bo with | None -> [LocalAssum (na, lift n typ)] - | Some b -> [LocalDef (na, lift n b, lift n typ)] in sign,sign + | Some b -> [LocalDef (na, lift n b, lift n typ)] in sign | Some {CAst.loc} -> user_err ?loc (str"Unexpected type annotation for a term of non inductive type.")) @@ -1905,31 +1909,23 @@ let extract_arity_signature ?(dolift=true) env0 lvar tomatchl tmsign = let nrealargs_ctxt = inductive_nrealdecls_env env0 ind in let arsign = fst (get_arity env0 indf') in let arsign = List.map (fun d -> map_rel_decl EConstr.of_constr d) arsign in - let realnal, realnal' = + let realnal = match t with | Some {CAst.loc;v=(ind',realnal)} -> if not (eq_ind ind ind') then 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."); - let realnal = List.rev realnal in - let realnal' = List.map (ltac_interp_name lvar) realnal in - realnal,realnal' + List.rev realnal | None -> - let realnal = List.make nrealargs_ctxt Anonymous in - realnal, realnal in - let na' = ltac_interp_name lvar na in + List.make nrealargs_ctxt Anonymous in let t = EConstr.of_constr (build_dependent_inductive env0 indf') in - (* Context with names for typing *) - let arsign1 = LocalAssum (na, t) :: List.map2 RelDecl.set_name realnal arsign in - (* Context with names for building the term *) - let arsign2 = LocalAssum (na', t) :: List.map2 RelDecl.set_name realnal' arsign in - arsign1,arsign2 in + LocalAssum (na, t) :: List.map2 RelDecl.set_name realnal arsign in let rec buildrec n = function | [],[] -> [] | (_,tm)::ltm, (_,x)::tmsign -> let l = get_one_sign n tm x in - l :: buildrec (n + List.length (fst l)) (ltm,tmsign) + l :: buildrec (n + List.length l) (ltm,tmsign) | _ -> assert false in List.rev (buildrec 0 (tomatchl,tmsign)) @@ -1986,9 +1982,9 @@ let prepare_predicate_from_arsign_tycon env sigma loc tomatchs arsign c = in assert (len == 0); let p = predicate 0 c in - let env' = List.fold_right push_rel_context arsign env in - try let sigma' = fst (Typing.type_of env' sigma p) in - Some (sigma', p) + let arsign,env' = List.fold_right_map (push_rel_context sigma) arsign env in + try let sigma' = fst (Typing.type_of !!env' sigma p) in + Some (sigma', p, arsign) with e when precatchable_exception e -> None (* Builds the predicate. If the predicate is dependent, its context is @@ -2017,15 +2013,14 @@ let noccur_with_meta sigma n m term = in try (occur_rec n term; true) with LocalOccur -> false -let prepare_predicate ?loc typing_fun env sigma lvar tomatchs arsign tycon pred = +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 + !!env sigma t in - let typing_arsign,building_arsign = List.split arsign in let preds = match pred, tycon with (* No return clause *) @@ -2035,12 +2030,12 @@ let prepare_predicate ?loc typing_fun env sigma lvar tomatchs arsign tycon pred (* 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 typing_arsign t in + 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 (match p1 with - | Some (sigma1,pred1) -> [sigma1, pred1; sigma2, pred2] - | None -> [sigma2, pred2]) + | Some (sigma1,pred1,arsign) -> [sigma1, pred1, arsign; sigma2, pred2, arsign] + | None -> [sigma2, pred2, arsign]) | None, _ -> (* No dependent type constraint, or no constraints at all: *) (* we use two strategies *) @@ -2048,28 +2043,28 @@ let prepare_predicate ?loc typing_fun env sigma lvar tomatchs arsign tycon pred | Some t -> refresh_tycon sigma t | None -> let (sigma, (t, _)) = - new_type_evar env sigma univ_flexible_alg ~src:(Loc.tag ?loc @@ Evar_kinds.CasesType false) in + new_type_evar !!env sigma univ_flexible_alg ~src:(Loc.tag ?loc @@ Evar_kinds.CasesType false) in sigma, t in (* First strategy: we build an "inversion" predicate *) let sigma1,pred1 = build_inversion_problem loc env sigma tomatchs t in (* Second strategy: we directly use the evar as a non dependent pred *) - let pred2 = lift (List.length (List.flatten typing_arsign)) t in - [sigma1, pred1; sigma, pred2] + let pred2 = lift (List.length (List.flatten arsign)) t in + [sigma1, pred1, arsign; sigma, pred2, arsign] (* Some type annotation *) | Some rtntyp, _ -> (* We extract the signature of the arity *) - let envar = List.fold_right push_rel_context typing_arsign env in + let building_arsign,envar = List.fold_right_map (push_rel_context sigma) arsign env in let sigma, newt = new_sort_variable univ_flexible_alg sigma in let evdref = ref sigma in - let predcclj = typing_fun (mk_tycon (mkSort newt)) envar evdref lvar rtntyp in + let predcclj = typing_fun (mk_tycon (mkSort newt)) envar evdref rtntyp in let sigma = !evdref in let predccl = nf_evar sigma predcclj.uj_val in - [sigma, predccl] + [sigma, predccl, building_arsign] in List.map - (fun (sigma,pred) -> - let (nal,pred) = build_initial_predicate building_arsign pred in + (fun (sigma,pred,arsign) -> + let (nal,pred) = build_initial_predicate arsign pred in sigma,nal,pred) preds @@ -2152,7 +2147,7 @@ let constr_of_pat env evdref arsign pat avoid = typ env (substl args liftt, []) ua avoid in let args' = arg' :: List.map (lift n') args in - let env' = push_rel_context sign' env in + let env' = EConstr.push_rel_context sign' env in (pat' :: patargs, args', sign' @ sign, env', n' + n, succ m, avoid)) ci.cs_args (List.rev args) ([], [], [], env, 0, 0, avoid) in @@ -2172,8 +2167,8 @@ let constr_of_pat env evdref arsign pat avoid = let avoid = Id.Set.add id avoid in let sign, i, avoid = try - let env = push_rel_context sign env in - evdref := the_conv_x_leq (push_rel_context sign env) + let env = EConstr.push_rel_context sign env in + evdref := the_conv_x_leq (EConstr.push_rel_context sign env) (lift (succ m) ty) (lift 1 apptype) !evdref; let eq_t = mk_eq evdref (lift (succ m) ty) (mkRel 1) (* alias *) @@ -2240,7 +2235,6 @@ let lift_rel_context n l = full signature. However prevpatterns are in the original one signature per pattern form. *) let build_ineqs evdref prevpatterns pats liftsign = - let _tomatchs = List.length pats in let diffs = List.fold_left (fun c eqnpats -> @@ -2288,7 +2282,7 @@ let constrs_of_pats typing_fun env evdref eqns tomatchs sign neqs arity = let _, newpatterns, pats = List.fold_left2 (fun (idents, newpatterns, pats) pat arsign -> - let pat', cpat, idents = constr_of_pat env evdref arsign pat idents in + let pat', cpat, idents = constr_of_pat !!env evdref arsign pat idents in (idents, pat' :: newpatterns, cpat :: pats)) (Id.Set.empty, [], []) eqn.patterns sign in @@ -2315,7 +2309,7 @@ let constrs_of_pats typing_fun env evdref eqns tomatchs sign neqs arity = in let ineqs = build_ineqs evdref prevpatterns pats signlen in let rhs_rels' = rels_of_patsign !evdref rhs_rels in - let _signenv = push_rel_context rhs_rels' env in + let _signenv,_ = push_rel_context !evdref rhs_rels' env in let arity = let args, nargs = List.fold_right (fun (sign, c, (_, args), _) (allargs,n) -> @@ -2335,11 +2329,11 @@ let constrs_of_pats typing_fun env evdref eqns tomatchs sign neqs arity = let eqs_rels, arity = decompose_prod_n_assum !evdref neqs arity in eqs_rels @ neqs_rels @ rhs_rels', arity in - let rhs_env = push_rel_context rhs_rels' env in + let _,rhs_env = push_rel_context !evdref rhs_rels' env in let j = typing_fun (mk_tycon tycon) rhs_env eqn.rhs.it in let bbody = it_mkLambda_or_LetIn j.uj_val rhs_rels' and btype = it_mkProd_or_LetIn j.uj_type rhs_rels' in - let _btype = evd_comb1 (Typing.type_of env) evdref bbody in + let _btype = evd_comb1 (Typing.type_of !!env) evdref bbody in let branch_name = Id.of_string ("program_branch_" ^ (string_of_int !i)) in let branch_decl = LocalDef (Name branch_name, lift !i bbody, lift !i btype) in let branch = @@ -2492,10 +2486,10 @@ let context_of_arsign l = l ([], 0) in x -let compile_program_cases ?loc style (typing_function, evdref) tycon env lvar +let compile_program_cases ?loc style (typing_function, evdref) tycon env (predopt, tomatchl, eqns) = let typing_fun tycon env = function - | Some t -> typing_function tycon env evdref lvar t + | Some t -> typing_function tycon env evdref t | None -> Evarutil.evd_comb0 use_unit_judge evdref in (* We build the matrix of patterns and right-hand side *) @@ -2503,29 +2497,28 @@ let compile_program_cases ?loc style (typing_function, evdref) tycon env lvar (* We build the vector of terms to match consistently with the *) (* constructors found in patterns *) - let predlvar,tomatchs = coerce_to_indtype typing_function evdref env lvar matx tomatchl in + let env,tomatchs = coerce_to_indtype typing_function evdref env matx tomatchl in let tycon = valcon_of_tycon tycon in let tomatchs, tomatchs_lets, tycon' = abstract_tomatch env !evdref tomatchs tycon in - let env = push_rel_context tomatchs_lets env in + let _,env = push_rel_context !evdref tomatchs_lets env in let len = List.length eqns in let sign, allnames, signlen, eqs, neqs, args = (* The arity signature *) - let arsign = extract_arity_signature ~dolift:false env predlvar tomatchs tomatchl in - let arsign = List.map fst arsign in (* Because no difference between the arity for typing and the arity for building *) + let arsign = extract_arity_signature ~dolift:false !!env tomatchs tomatchl in (* Build the dependent arity signature, the equalities which makes the first part of the predicate and their instantiations. *) let avoid = Id.Set.empty in - build_dependent_signature env evdref avoid tomatchs arsign + build_dependent_signature !!env evdref avoid tomatchs arsign in let tycon, arity = let nar = List.fold_left (fun n sign -> List.length sign + n) 0 sign in match tycon' with - | None -> let ev = mkExistential env evdref in ev, lift nar ev + | None -> let ev = mkExistential !!env evdref in ev, lift nar ev | Some t -> let pred = match prepare_predicate_from_arsign_tycon env !evdref loc tomatchs sign t with - | Some (evd, pred) -> evdref := evd; pred + | Some (evd, pred, arsign) -> evdref := evd; pred | None -> lift nar t in Option.get tycon, pred @@ -2541,7 +2534,7 @@ let compile_program_cases ?loc style (typing_function, evdref) tycon env lvar in let matx = List.rev matx in let _ = assert (Int.equal len (List.length lets)) in - let env = push_rel_context lets env in + let _,env = push_rel_context !evdref lets env in let matx = List.map (fun eqn -> { eqn with rhs = { eqn.rhs with rhs_env = env } }) matx in let tomatchs = List.map (fun (x, y) -> lift len x, lift_tomatch_type len y) tomatchs in let args = List.rev_map (lift len) args in @@ -2554,10 +2547,10 @@ let compile_program_cases ?loc style (typing_function, evdref) tycon env lvar let out_tmt na = function NotInd (None,t) -> LocalAssum (na,t) | NotInd (Some b, t) -> LocalDef (na,b,t) | IsInd (typ,_,_) -> LocalAssum (na,typ) in - let typs = List.map2 (fun na (tm,tmt) -> (tm,out_tmt na tmt)) nal tomatchs in + let typs = List.map2 (fun (na,_) (tm,tmt) -> (tm,out_tmt na tmt)) nal tomatchs in let typs = - List.map (fun (c,d) -> (c,extract_inductive_data env !evdref d,d)) typs in + List.map (fun (c,d) -> (c,extract_inductive_data !!env !evdref d,d)) typs in let dep_sign = find_dependencies_signature !evdref @@ -2566,20 +2559,20 @@ let compile_program_cases ?loc style (typing_function, evdref) tycon env lvar let typs' = List.map3 - (fun (tm,tmt) deps na -> + (fun (tm,tmt) deps (na,realnames) -> let deps = if not (isRel !evdref tm) then [] else deps in + let tmt = set_tomatch_realnames realnames tmt in ((tm,tmt),deps,na)) tomatchs dep_sign nal in let initial_pushed = List.map (fun x -> Pushed (true,x)) typs' in let typing_function tycon env evdref = function - | Some t -> typing_function tycon env evdref lvar t + | Some t -> typing_function tycon env evdref t | None -> evd_comb0 use_unit_judge evdref in let pb = { env = env; - lvar = lvar; evdref = evdref; pred = pred; tomatch = initial_pushed; @@ -2591,7 +2584,7 @@ let compile_program_cases ?loc style (typing_function, evdref) tycon env lvar let j = compile pb in (* We check for unused patterns *) - List.iter (check_unused_pattern env) matx; + List.iter (check_unused_pattern !!env) matx; let body = it_mkLambda_or_LetIn (applist (j.uj_val, args)) lets in let j = { uj_val = it_mkLambda_or_LetIn body tomatchs_lets; @@ -2602,10 +2595,10 @@ let compile_program_cases ?loc style (typing_function, evdref) tycon env lvar (**************************************************************************) (* Main entry of the matching compilation *) -let compile_cases ?loc style (typing_fun, evdref) tycon env lvar (predopt, tomatchl, eqns) = +let compile_cases ?loc style (typing_fun, evdref) tycon env (predopt, tomatchl, eqns) = if predopt == None && Flags.is_program_mode () && Program.is_program_cases () then compile_program_cases ?loc style (typing_fun, evdref) - tycon env lvar (predopt, tomatchl, eqns) + tycon env (predopt, tomatchl, eqns) else (* We build the matrix of patterns and right-hand side *) @@ -2613,15 +2606,13 @@ let compile_cases ?loc style (typing_fun, evdref) tycon env lvar (predopt, tomat (* We build the vector of terms to match consistently with the *) (* constructors found in patterns *) - let predlvar,tomatchs = coerce_to_indtype typing_fun evdref env lvar matx tomatchl in - - + let predenv,tomatchs = coerce_to_indtype typing_fun evdref env matx tomatchl in (* If an elimination predicate is provided, we check it is compatible with the type of arguments to match; if none is provided, we build alternative possible predicates *) - let arsign = extract_arity_signature env predlvar tomatchs tomatchl in - let preds = prepare_predicate ?loc typing_fun env !evdref predlvar tomatchs arsign tycon predopt in + let arsign = extract_arity_signature !!env tomatchs tomatchl in + let preds = prepare_predicate ?loc typing_fun predenv !evdref tomatchs arsign tycon predopt in let compile_for_one_predicate (sigma,nal,pred) = (* We push the initial terms to match and push their alias to rhs' envs *) @@ -2631,10 +2622,10 @@ let compile_cases ?loc style (typing_fun, evdref) tycon env lvar (predopt, tomat let out_tmt na = function NotInd (None,t) -> LocalAssum (na,t) | NotInd (Some b,t) -> LocalDef (na,b,t) | IsInd (typ,_,_) -> LocalAssum (na,typ) in - let typs = List.map2 (fun na (tm,tmt) -> (tm,out_tmt na tmt)) nal tomatchs in + let typs = List.map2 (fun (na,_) (tm,tmt) -> (tm,out_tmt na tmt)) nal tomatchs in let typs = - List.map (fun (c,d) -> (c,extract_inductive_data env sigma d,d)) typs in + List.map (fun (c,d) -> (c,extract_inductive_data !!env sigma d,d)) typs in let dep_sign = find_dependencies_signature !evdref @@ -2643,8 +2634,9 @@ let compile_cases ?loc style (typing_fun, evdref) tycon env lvar (predopt, tomat let typs' = List.map3 - (fun (tm,tmt) deps na -> + (fun (tm,tmt) deps (na,realnames) -> let deps = if not (isRel !evdref tm) then [] else deps in + let tmt = set_tomatch_realnames realnames tmt in ((tm,tmt),deps,na)) tomatchs dep_sign nal in @@ -2652,14 +2644,13 @@ let compile_cases ?loc style (typing_fun, evdref) tycon env lvar (predopt, tomat (* A typing function that provides with a canonical term for absurd cases*) let typing_fun tycon env evdref = function - | Some t -> typing_fun tycon env evdref lvar t + | Some t -> typing_fun tycon env evdref t | None -> evd_comb0 use_unit_judge evdref in let myevdref = ref sigma in let pb = { env = env; - lvar = lvar; evdref = myevdref; pred = pred; tomatch = initial_pushed; @@ -2672,7 +2663,7 @@ let compile_cases ?loc style (typing_fun, evdref) tycon env lvar (predopt, tomat 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 + let j = inh_conv_coerce_to_tycon ?loc !!env myevdref j tycon in evdref := !myevdref; j in @@ -2681,6 +2672,6 @@ let compile_cases ?loc style (typing_fun, evdref) tycon env lvar (predopt, tomat let j = list_try_compile compile_for_one_predicate preds in (* We check for unused patterns *) - List.iter (check_unused_pattern env) matx; + List.iter (check_unused_pattern !!env) matx; j diff --git a/pretyping/cases.mli b/pretyping/cases.mli index 04a3464679..76b81a58c1 100644 --- a/pretyping/cases.mli +++ b/pretyping/cases.mli @@ -15,7 +15,6 @@ open Environ open EConstr open Inductiveops open Glob_term -open Ltac_pretype open Evardefine (** {5 Compilation of pattern-matching } *) @@ -42,9 +41,9 @@ val irrefutable : env -> cases_pattern -> bool val compile_cases : ?loc:Loc.t -> case_style -> - (type_constraint -> env -> evar_map ref -> ltac_var_map -> glob_constr -> unsafe_judgment) * evar_map ref -> + (type_constraint -> GlobEnv.t -> evar_map ref -> glob_constr -> unsafe_judgment) * evar_map ref -> type_constraint -> - env -> ltac_var_map -> glob_constr option * tomatch_tuples * cases_clauses -> + GlobEnv.t -> glob_constr option * tomatch_tuples * cases_clauses -> unsafe_judgment val constr_of_pat : @@ -59,7 +58,7 @@ val constr_of_pat : Names.Id.Set.t type 'a rhs = - { rhs_env : env; + { rhs_env : GlobEnv.t; rhs_vars : Id.Set.t; avoid_ids : Id.Set.t; it : 'a option} @@ -103,8 +102,7 @@ and pattern_continuation = | Result of cases_pattern list type 'a pattern_matching_problem = - { env : env; - lvar : Ltac_pretype.ltac_var_map; + { env : GlobEnv.t; evdref : evar_map ref; pred : constr; tomatch : tomatch_stack; @@ -112,21 +110,19 @@ type 'a pattern_matching_problem = mat : 'a matrix; caseloc : Loc.t option; casestyle : case_style; - typing_function: type_constraint -> env -> evar_map ref -> 'a option -> unsafe_judgment } - + typing_function: type_constraint -> GlobEnv.t -> evar_map ref -> 'a option -> unsafe_judgment } val compile : 'a pattern_matching_problem -> unsafe_judgment val prepare_predicate : ?loc:Loc.t -> (type_constraint -> - Environ.env -> Evd.evar_map ref -> ltac_var_map -> glob_constr -> unsafe_judgment) -> - Environ.env -> + GlobEnv.t -> Evd.evar_map ref -> glob_constr -> unsafe_judgment) -> + GlobEnv.t -> Evd.evar_map -> - Ltac_pretype.ltac_var_map -> (types * tomatch_type) list -> - (rel_context * rel_context) list -> + rel_context list -> constr option -> - glob_constr option -> (Evd.evar_map * Name.t list * constr) list + glob_constr option -> (Evd.evar_map * (Name.t * Name.t list) list * constr) list -val make_return_predicate_ltac_lvar : Evd.evar_map -> Name.t -> - Glob_term.glob_constr -> constr -> Ltac_pretype.ltac_var_map -> ltac_var_map +val make_return_predicate_ltac_lvar : GlobEnv.t -> Evd.evar_map -> Name.t -> + Glob_term.glob_constr -> constr -> GlobEnv.t diff --git a/pretyping/classops.ml b/pretyping/classops.ml index 542fb5456c..94da51626f 100644 --- a/pretyping/classops.ml +++ b/pretyping/classops.ml @@ -16,7 +16,6 @@ open Constr open Libnames open Globnames open Nametab -open Environ open Libobject open Mod_subst @@ -39,7 +38,7 @@ type cl_info_typ = { type coe_typ = GlobRef.t -module CoeTypMap = Refmap_env +module CoeTypMap = GlobRef.Map_env type coe_info_typ = { coe_value : GlobRef.t; @@ -118,6 +117,9 @@ let class_tab = let coercion_tab = ref (CoeTypMap.empty : coe_info_typ CoeTypMap.t) +let coercions_in_scope = + ref GlobRef.Set_env.empty + module ClPairOrd = struct type t = cl_index * cl_index @@ -131,12 +133,13 @@ module ClPairMap = Map.Make(ClPairOrd) let inheritance_graph = ref (ClPairMap.empty : inheritance_path ClPairMap.t) -let freeze _ = (!class_tab, !coercion_tab, !inheritance_graph) +let freeze _ = (!class_tab, !coercion_tab, !inheritance_graph, !coercions_in_scope) -let unfreeze (fcl,fco,fig) = +let unfreeze (fcl,fco,fig,in_scope) = class_tab:=fcl; coercion_tab:=fco; - inheritance_graph:=fig + inheritance_graph:=fig; + coercions_in_scope:=in_scope (* ajout de nouveaux "objets" *) @@ -316,16 +319,16 @@ let lookup_pattern_path_between env (s,t) = (* rajouter une coercion dans le graphe *) -let path_printer : (env -> Evd.evar_map -> (Bijint.Index.t * Bijint.Index.t) * inheritance_path -> Pp.t) ref = - ref (fun _ _ _ -> str "<a class path>") +let path_printer : ((Bijint.Index.t * Bijint.Index.t) * inheritance_path -> Pp.t) ref = + ref (fun _ -> str "<a class path>") let install_path_printer f = path_printer := f -let print_path env sigma x = !path_printer env sigma x +let print_path x = !path_printer x -let message_ambig env sigma l = +let message_ambig l = str"Ambiguous paths:" ++ spc () ++ - prlist_with_sep fnl (fun ijp -> print_path env sigma ijp) l + prlist_with_sep fnl print_path l (* add_coercion_in_graph : coe_index * cl_index * cl_index -> unit coercion,source,target *) @@ -339,7 +342,7 @@ let different_class_params i = | CL_CONST c -> Global.is_polymorphic (ConstRef c) | _ -> false -let add_coercion_in_graph env sigma (ic,source,target) = +let add_coercion_in_graph (ic,source,target) = let old_inheritance_graph = !inheritance_graph in let ambig_paths = (ref [] : ((cl_index * cl_index) * inheritance_path) list ref) in @@ -381,7 +384,7 @@ let add_coercion_in_graph env sigma (ic,source,target) = end; let is_ambig = match !ambig_paths with [] -> false | _ -> true in if is_ambig && not !Flags.quiet then - Feedback.msg_info (message_ambig env sigma !ambig_paths) + Feedback.msg_info (message_ambig !ambig_paths) type coercion = { coercion_type : coe_typ; @@ -426,7 +429,7 @@ let _ = optread = (fun () -> !automatically_import_coercions); optwrite = (:=) automatically_import_coercions } -let cache_coercion env sigma (_, c) = +let cache_coercion (_, c) = let () = add_class c.coercion_source in let () = add_class c.coercion_target in let is, _ = class_info c.coercion_source in @@ -439,15 +442,22 @@ let cache_coercion env sigma (_, c) = coe_param = c.coercion_params; } in let () = add_new_coercion c.coercion_type xf in - add_coercion_in_graph env sigma (xf,is,it) + add_coercion_in_graph (xf,is,it) let load_coercion _ o = if !automatically_import_coercions then - cache_coercion (Global.env ()) Evd.empty o + cache_coercion o + +let set_coercion_in_scope (_, c) = + let r = c.coercion_type in + coercions_in_scope := GlobRef.Set_env.add r !coercions_in_scope let open_coercion i o = - if Int.equal i 1 && not !automatically_import_coercions then - cache_coercion (Global.env ()) Evd.empty o + if Int.equal i 1 then begin + set_coercion_in_scope o; + if not !automatically_import_coercions then + cache_coercion o + end let subst_coercion (subst, c) = let coe = subst_coe_typ subst c.coercion_type in @@ -492,8 +502,8 @@ let inCoercion : coercion -> obj = open_function = open_coercion; load_function = load_coercion; cache_function = (fun objn -> - let env = Global.env () in cache_coercion env Evd.empty objn - ); + set_coercion_in_scope objn; + cache_coercion objn); subst_function = subst_coercion; classify_function = classify_coercion; discharge_function = discharge_coercion } @@ -535,7 +545,7 @@ let coercion_of_reference r = module CoercionPrinting = struct type t = coe_typ - let compare = RefOrdered.compare + let compare = GlobRef.Ordered.compare let encode = coercion_of_reference let subst = subst_coe_typ let printer x = pr_global_env Id.Set.empty x @@ -553,3 +563,6 @@ let hide_coercion coe = let coe_info = coercion_info coe in Some coe_info.coe_param else None + +let is_coercion_in_scope r = + GlobRef.Set_env.mem r !coercions_in_scope diff --git a/pretyping/classops.mli b/pretyping/classops.mli index af00c0a8dc..7c4842c8ae 100644 --- a/pretyping/classops.mli +++ b/pretyping/classops.mli @@ -99,7 +99,7 @@ val lookup_pattern_path_between : (**/**) (* Crade *) val install_path_printer : - (env -> evar_map -> (cl_index * cl_index) * inheritance_path -> Pp.t) -> unit + ((cl_index * cl_index) * inheritance_path -> Pp.t) -> unit (**/**) (** {6 This is for printing purpose } *) @@ -113,3 +113,5 @@ val coercions : unit -> coe_info_typ list (** [hide_coercion] returns the number of params to skip if the coercion must be hidden, [None] otherwise; it raises [Not_found] if not a coercion *) val hide_coercion : coe_typ -> int option + +val is_coercion_in_scope : GlobRef.t -> bool diff --git a/pretyping/coercion.ml b/pretyping/coercion.ml index 5e3821edf1..e15c00f7dc 100644 --- a/pretyping/coercion.ml +++ b/pretyping/coercion.ml @@ -363,12 +363,20 @@ let saturate_evd env evd = Typeclasses.resolve_typeclasses ~filter:Typeclasses.no_goals ~split:true ~fail:false env evd +let warn_coercion_not_in_scope = + CWarnings.create ~name:"coercion-not-in-scope" ~category:"deprecated" + Pp.(fun r -> str "Coercion used but not in scope: " ++ + Nametab.pr_global_env Id.Set.empty r ++ str ". If you want to use " + ++ str "this coercion, please Import the module that contains it.") + (* Apply coercion path from p to hj; raise NoCoercion if not applicable *) let apply_coercion env sigma p hj typ_cl = try let j,t,evd = List.fold_left (fun (ja,typ_cl,sigma) i -> + if not (is_coercion_in_scope i.coe_value) then + warn_coercion_not_in_scope i.coe_value; let isid = i.coe_is_identity in let isproj = i.coe_is_projection in let sigma, c = new_global sigma i.coe_value in @@ -386,7 +394,6 @@ 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 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 = diff --git a/pretyping/globEnv.ml b/pretyping/globEnv.ml new file mode 100644 index 0000000000..12788e5ec5 --- /dev/null +++ b/pretyping/globEnv.ml @@ -0,0 +1,201 @@ +(************************************************************************) +(* * The Coq Proof Assistant / The Coq Development Team *) +(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *) +(* <O___,, * (see CREDITS file for the list of authors) *) +(* \VV/ **************************************************************) +(* // * This file is distributed under the terms of the *) +(* * GNU Lesser General Public License Version 2.1 *) +(* * (see LICENSE file for the text of the license) *) +(************************************************************************) + +open Util +open Pp +open CErrors +open Names +open Environ +open EConstr +open Evarutil +open Termops +open Vars +open Ltac_pretype + +(** This files provides a level of abstraction for the kind of + environment used for type inference (so-called pretyping); in + particular: + - it supports that term variables can be interpreted as Ltac + variables pointing to the effective expected name + - it incrementally and lazily computes the renaming of rel + variables used to build purely-named evar contexts +*) + +type t = { + static_env : env; + (** For locating indices *) + renamed_env : env; + (** For name management *) + extra : ext_named_context Lazy.t; + (** Delay the computation of the evar extended environment *) + lvar : ltac_var_map; +} + +let make env sigma lvar = + let get_extra env sigma = + let avoid = Environ.ids_of_named_context_val (Environ.named_context_val env) in + Context.Rel.fold_outside (fun d acc -> push_rel_decl_to_named_context sigma d acc) + (rel_context env) ~init:(empty_csubst, avoid, named_context env) in + { + static_env = env; + renamed_env = env; + extra = lazy (get_extra env sigma); + lvar = lvar; + } + +let env env = env.static_env + +let vars_of_env env = + Id.Set.union (Id.Map.domain env.lvar.ltac_genargs) (vars_of_env env.static_env) + +let ltac_interp_name { ltac_idents ; ltac_genargs } = function + | Anonymous -> Anonymous + | Name id as na -> + try Name (Id.Map.find id ltac_idents) + with Not_found -> + if Id.Map.mem id ltac_genargs then + user_err (str "Ltac variable" ++ spc () ++ Id.print id ++ + spc () ++ str "is not bound to an identifier." ++ + spc () ++str "It cannot be used in a binder.") + else na + +let push_rel sigma d env = + let d' = Context.Rel.Declaration.map_name (ltac_interp_name env.lvar) d in + let env = { + static_env = push_rel d env.static_env; + renamed_env = push_rel d' env.renamed_env; + extra = lazy (push_rel_decl_to_named_context sigma d' (Lazy.force env.extra)); + lvar = env.lvar; + } in + d', env + +let push_rel_context ?(force_names=false) sigma ctx env = + let open Context.Rel.Declaration in + let ctx' = List.Smart.map (map_name (ltac_interp_name env.lvar)) ctx in + let ctx' = if force_names then Namegen.name_context env.renamed_env sigma ctx' else ctx' in + let env = { + static_env = push_rel_context ctx env.static_env; + renamed_env = push_rel_context ctx' env.renamed_env; + extra = lazy (List.fold_right (fun d acc -> push_rel_decl_to_named_context sigma d acc) ctx' (Lazy.force env.extra)); + lvar = env.lvar; + } in + ctx', env + +let push_rec_types sigma (lna,typarray) env = + let open Context.Rel.Declaration in + let ctxt = Array.map2_i (fun i na t -> Context.Rel.Declaration.LocalAssum (na, lift i t)) lna typarray in + let env,ctx = Array.fold_left_map (fun e assum -> let (d,e) = push_rel sigma assum e in (e,d)) env ctxt in + Array.map get_name ctx, env + +let e_new_evar env evdref ?src ?naming typ = + let open Context.Named.Declaration in + let inst_vars = List.map (get_id %> mkVar) (named_context env.renamed_env) in + let inst_rels = List.rev (rel_list 0 (nb_rel env.renamed_env)) in + let (subst, _, nc) = Lazy.force env.extra in + let typ' = csubst_subst subst typ in + let instance = inst_rels @ inst_vars in + let sign = val_of_named_context nc in + let sigma = !evdref in + let (sigma, e) = new_evar_instance sign sigma typ' ?src ?naming instance in + evdref := sigma; + e + +let e_new_type_evar env evdref ~src = + let (evd', s) = Evd.new_sort_variable Evd.univ_flexible_alg !evdref in + evdref := evd'; + e_new_evar env evdref ~src (EConstr.mkSort s) + +let hide_variable env expansion id = + let lvar = env.lvar in + if Id.Map.mem id lvar.ltac_genargs then + let lvar = match expansion with + | Name id' -> + (* We are typically in a situation [match id return P with ... end] + which we interpret as [match id' as id' return P with ... end], + with [P] interpreted in an environment where [id] is bound to [id']. + The variable is already bound to [id'], so nothing to do *) + lvar + | _ -> + (* We are typically in a situation [match id return P with ... end] + with [id] bound to a non-variable term [c]. We interpret as + [match c as id return P with ... end], and hides [id] while + interpreting [P], since it has become a binder and cannot be anymore be + substituted by a variable coming from the Ltac substitution. *) + { lvar with + ltac_uconstrs = Id.Map.remove id lvar.ltac_uconstrs; + ltac_constrs = Id.Map.remove id lvar.ltac_constrs; + ltac_genargs = Id.Map.remove id lvar.ltac_genargs } in + { env with lvar } + else + env + +let protected_get_type_of env sigma c = + try Retyping.get_type_of ~lax:true env sigma c + with Retyping.RetypeError _ -> + user_err + (str "Cannot reinterpret " ++ quote (print_constr c) ++ + str " in the current environment.") + +let invert_ltac_bound_name env id0 id = + try mkRel (pi1 (lookup_rel_id id (rel_context env.static_env))) + with Not_found -> + user_err (str "Ltac variable " ++ Id.print id0 ++ + str " depends on pattern variable name " ++ Id.print id ++ + str " which is not bound in current context.") + +let interp_ltac_variable ?loc typing_fun env sigma id = + (* Check if [id] is an ltac variable *) + try + let (ids,c) = Id.Map.find id env.lvar.ltac_constrs in + let subst = List.map (invert_ltac_bound_name env id) ids in + let c = substl subst c in + { uj_val = c; uj_type = protected_get_type_of env.renamed_env sigma c } + with Not_found -> + try + let {closure;term} = Id.Map.find id env.lvar.ltac_uconstrs in + let lvar = { + ltac_constrs = closure.typed; + ltac_uconstrs = closure.untyped; + ltac_idents = closure.idents; + ltac_genargs = Id.Map.empty; } + in + (* spiwack: I'm catching [Not_found] potentially too eagerly + here, as the call to the main pretyping function is caught + inside the try but I want to avoid refactoring this function + too much for now. *) + typing_fun {env with lvar} term + with Not_found -> + (* Check if [id] is a ltac variable not bound to a term *) + (* and build a nice error message *) + if Id.Map.mem id env.lvar.ltac_genargs then begin + let Geninterp.Val.Dyn (typ, _) = Id.Map.find id env.lvar.ltac_genargs in + user_err ?loc + (str "Variable " ++ Id.print id ++ str " should be bound to a term but is \ + bound to a " ++ Geninterp.Val.pr typ ++ str ".") + end; + raise Not_found + +module ConstrInterpObj = +struct + type ('r, 'g, 't) obj = + unbound_ltac_var_map -> env -> Evd.evar_map -> types -> 'g -> constr * Evd.evar_map + let name = "constr_interp" + let default _ = None +end + +module ConstrInterp = Genarg.Register(ConstrInterpObj) + +let register_constr_interp0 = ConstrInterp.register0 + +let interp_glob_genarg env sigma ty arg = + let open Genarg in + let GenArg (Glbwit tag, arg) = arg in + let interp = ConstrInterp.obj tag in + interp env.lvar.ltac_genargs env.renamed_env sigma ty arg diff --git a/pretyping/globEnv.mli b/pretyping/globEnv.mli new file mode 100644 index 0000000000..4038523211 --- /dev/null +++ b/pretyping/globEnv.mli @@ -0,0 +1,83 @@ +(************************************************************************) +(* * The Coq Proof Assistant / The Coq Development Team *) +(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *) +(* <O___,, * (see CREDITS file for the list of authors) *) +(* \VV/ **************************************************************) +(* // * This file is distributed under the terms of the *) +(* * GNU Lesser General Public License Version 2.1 *) +(* * (see LICENSE file for the text of the license) *) +(************************************************************************) + +open Names +open Environ +open Evd +open EConstr +open Ltac_pretype + +(** To embed constr in glob_constr *) + +val register_constr_interp0 : + ('r, 'g, 't) Genarg.genarg_type -> + (unbound_ltac_var_map -> env -> evar_map -> types -> 'g -> constr * evar_map) -> unit + +(** {6 Pretyping name management} *) + +(** The following provides a level of abstraction for the kind of + environment used for type inference (so-called pretyping); in + particular: + - it supports that term variables can be interpreted as Ltac + variables pointing to the effective expected name + - it incrementally and lazily computes the renaming of rel + variables used to build purely-named evar contexts +*) + +(** Type of environment extended with naming and ltac interpretation data *) + +type t + +(** Build a pretyping environment from an ltac environment *) + +val make : env -> evar_map -> ltac_var_map -> t + +(** Export the underlying environement *) + +val env : t -> env + +val vars_of_env : t -> Id.Set.t + +(** Push to the environment, returning the declaration(s) with interpreted names *) + +val push_rel : evar_map -> rel_declaration -> t -> rel_declaration * t +val push_rel_context : ?force_names:bool -> evar_map -> rel_context -> t -> rel_context * t +val push_rec_types : evar_map -> Name.t array * constr array -> t -> Name.t array * t + +(** Declare an evar using renaming information *) + +val e_new_evar : t -> evar_map ref -> ?src:Evar_kinds.t Loc.located -> + ?naming:Namegen.intro_pattern_naming_expr -> constr -> constr + +val e_new_type_evar : t -> evar_map ref -> src:Evar_kinds.t Loc.located -> constr + +(** [hide_variable env na id] tells to hide the binding of [id] in + the ltac environment part of [env] and to additionally rebind + it to [id'] in case [na] is some [Name id']. It is useful e.g. + for the dual status of [y] as term and binder. This is the case + of [match y return p with ... end] which implicitly denotes + [match z as z return p with ... end] when [y] is bound to a + variable [z] and [match t as y return p with ... end] when [y] + is bound to a non-variable term [t]. In the latter case, the + binding of [y] to [t] should be hidden in [p]. *) + +val hide_variable : t -> Name.t -> Id.t -> t + +(** In case a variable is not bound by a term binder, look if it has + an interpretation as a term in the ltac_var_map *) + +val interp_ltac_variable : ?loc:Loc.t -> (t -> Glob_term.glob_constr -> unsafe_judgment) -> + t -> evar_map -> Id.t -> unsafe_judgment + +(** Interpreting a generic argument, typically a "ltac:(...)", taking + into account the possible renaming *) + +val interp_glob_genarg : t -> evar_map -> constr -> + Genarg.glob_generic_argument -> constr * evar_map diff --git a/pretyping/glob_ops.ml b/pretyping/glob_ops.ml index 24eb666828..bd13f1d00a 100644 --- a/pretyping/glob_ops.ml +++ b/pretyping/glob_ops.ml @@ -15,7 +15,6 @@ open Nameops open Globnames open Glob_term open Evar_kinds -open Ltac_pretype (* Untyped intermediate terms, after ASTs and before constr. *) @@ -577,22 +576,9 @@ let glob_constr_of_closed_cases_pattern p = match DAst.get p with let glob_constr_of_cases_pattern p = glob_constr_of_cases_pattern_aux false p -(**********************************************************************) -(* Interpreting ltac variables *) - -open Pp -open CErrors - -let ltac_interp_name { ltac_idents ; ltac_genargs } = function - | Anonymous -> Anonymous - | Name id as n -> - try Name (Id.Map.find id ltac_idents) - with Not_found -> - if Id.Map.mem id ltac_genargs then - user_err (str"Ltac variable"++spc()++ Id.print id ++ - spc()++str"is not bound to an identifier."++spc()++ - str"It cannot be used in a binder.") - else n +(* This has to be in some file... *) + +open Ltac_pretype let empty_lvar : ltac_var_map = { ltac_constrs = Id.Map.empty; diff --git a/pretyping/glob_ops.mli b/pretyping/glob_ops.mli index c967f4e884..91a2ef9c1e 100644 --- a/pretyping/glob_ops.mli +++ b/pretyping/glob_ops.mli @@ -101,5 +101,4 @@ val glob_constr_of_cases_pattern : 'a cases_pattern_g -> 'a glob_constr_g val add_patterns_for_params_remove_local_defs : constructor -> 'a cases_pattern_g list -> 'a cases_pattern_g list -val ltac_interp_name : Ltac_pretype.ltac_var_map -> Name.t -> Name.t val empty_lvar : Ltac_pretype.ltac_var_map diff --git a/pretyping/inferCumulativity.ml b/pretyping/inferCumulativity.ml index eb283a0220..be79b8b07d 100644 --- a/pretyping/inferCumulativity.ml +++ b/pretyping/inferCumulativity.ml @@ -99,7 +99,7 @@ let rec infer_fterm cv_pb infos variances hd stk = | FEvar ((_,args),e) -> let variances = infer_stack infos variances stk in infer_vect infos variances (Array.map (mk_clos e) args) - | FRel _ -> variances + | FRel _ -> infer_stack infos variances stk | FFlex fl -> let variances = infer_table_key infos variances fl in infer_stack infos variances stk diff --git a/pretyping/ltac_pretype.ml b/pretyping/ltac_pretype.ml index be8579c2e5..ac59b96eef 100644 --- a/pretyping/ltac_pretype.ml +++ b/pretyping/ltac_pretype.ml @@ -64,5 +64,5 @@ type ltac_var_map = { ltac_idents: Id.t Id.Map.t; (** Ltac variables bound to identifiers *) ltac_genargs : unbound_ltac_var_map; - (** Ltac variables bound to other kinds of arguments *) + (** All Ltac variables (to pass on ltac subterms, and for error reporting) *) } diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml index a315376aca..d10c00fa6e 100644 --- a/pretyping/pretyping.ml +++ b/pretyping/pretyping.ml @@ -38,19 +38,20 @@ open Reductionops open Type_errors open Typing open Globnames -open Nameops open Evarutil open Evardefine open Pretype_errors open Glob_term open Glob_ops +open GlobEnv open Evarconv -open Ltac_pretype module NamedDecl = Context.Named.Declaration type typing_constraint = OfType of types | IsType | WithoutTypeConstraint +let (!!) env = GlobEnv.env env + (************************************************************************) (* This concerns Cases *) open Inductive @@ -58,58 +59,6 @@ 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 sigma = - let avoid = Environ.ids_of_named_context_val (Environ.named_context_val env) in - Context.Rel.fold_outside (fun d acc -> push_rel_decl_to_named_context sigma d acc) - (rel_context env) ~init:(empty_csubst, avoid, named_context env) - -let make_env env sigma = { env = env; extra = lazy (get_extra env sigma) } -let rel_context env = rel_context env.env - -let push_rel sigma d env = { - env = push_rel d env.env; - extra = lazy (push_rel_decl_to_named_context sigma d (Lazy.force env.extra)); -} - -let pop_rel_context n env sigma = make_env (pop_rel_context n env.env) sigma - -let push_rel_context sigma ctx env = { - env = push_rel_context ctx env.env; - extra = lazy (List.fold_right (fun d acc -> push_rel_decl_to_named_context sigma d acc) 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 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, _, nc) = Lazy.force env.extra in - let typ' = csubst_subst subst typ in - let instance = inst_rels @ inst_vars in - let sign = val_of_named_context nc in - let sigma = !evdref in - let (sigma, e) = new_evar_instance sign sigma typ' ?src ?naming instance in - evdref := sigma; - e - -let push_rec_types sigma (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 sigma assum e) env ctxt - -end - -open ExtraEnv - (* An auxiliary function for searching for fixpoint guard indexes *) exception Found of int array @@ -400,7 +349,7 @@ let adjust_evar_source evdref na c = let inh_conv_coerce_to_tycon ?loc resolve_tc env evdref j = function | None -> j | Some t -> - evd_comb2 (Coercion.inh_conv_coerce_to ?loc resolve_tc env.ExtraEnv.env) evdref j t + evd_comb2 (Coercion.inh_conv_coerce_to ?loc resolve_tc !!env) evdref j t let check_instance loc subst = function | [] -> () @@ -417,76 +366,21 @@ let orelse_name name name' = match name with | Anonymous -> name' | _ -> name -let ltac_interp_name_env k0 lvar env sigma = - (* envhd is the initial part of the env when pretype was called first *) - (* (in practice is is probably 0, but we have to grant the - specification of pretype which accepts to start with a non empty - rel_context) *) - (* 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 open Context.Rel.Declaration in - let ctxt' = List.Smart.map (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 sigma ctxt' (pop_rel_context n env sigma) - -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 -> - user_err (str "Ltac variable " ++ Id.print id0 ++ - str " depends on pattern variable name " ++ Id.print 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.ExtraEnv.env sigma c - with Retyping.RetypeError _ -> - user_err - (str "Cannot reinterpret " ++ quote (print_constr c) ++ - str " in the current environment.") - -let pretype_id pretype k0 loc env evdref lvar id = - let sigma = !evdref in +let pretype_id pretype k0 loc env evdref id = (* Look for the binder of [id] *) try - let (n,_,typ) = lookup_rel_id id (rel_context env) in + let (n,_,typ) = lookup_rel_id id (rel_context !!env) in { uj_val = mkRel n; uj_type = lift n typ } with Not_found -> - let env = ltac_interp_name_env k0 lvar env !evdref in - (* Check if [id] is an ltac variable *) - try - let (ids,c) = Id.Map.find id lvar.ltac_constrs in - let subst = List.map (invert_ltac_bound_name lvar env id) ids in - let c = substl subst c in - { uj_val = c; uj_type = protected_get_type_of env sigma c } - with Not_found -> try - let {closure;term} = Id.Map.find id lvar.ltac_uconstrs in - let lvar = { - ltac_constrs = closure.typed; - ltac_uconstrs = closure.untyped; - ltac_idents = closure.idents; - ltac_genargs = Id.Map.empty; } - in - (* spiwack: I'm catching [Not_found] potentially too eagerly - here, as the call to the main pretyping function is caught - inside the try but I want to avoid refactoring this function - too much for now. *) - pretype env evdref lvar term - with Not_found -> - (* Check if [id] is a ltac variable not bound to a term *) - (* 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 - (str "Variable " ++ Id.print 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 = NamedDecl.get_type (lookup_named id env) } - with Not_found -> - (* [id] not found, standard error message *) - error_var_not_found ?loc id + try + GlobEnv.interp_ltac_variable ?loc (fun env -> pretype env evdref) env !evdref id + with Not_found -> + (* Check if [id] is a section or goal variable *) + try + { 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 id (*************************************************************************) (* Main pretyping function *) @@ -524,18 +418,18 @@ let pretype_global ?loc rigid env evd gr us = match us with | None -> evd, None | Some l -> - let _, ctx = Global.constr_of_global_in_context env.ExtraEnv.env gr in + let _, ctx = Global.constr_of_global_in_context !!env gr in let len = Univ.AUContext.size ctx in interp_instance ?loc evd ~len l in - let (sigma, c) = Evd.fresh_global ?loc ~rigid ?names:instance env.ExtraEnv.env evd gr in + let (sigma, c) = Evd.fresh_global ?loc ~rigid ?names:instance !!env evd gr in (sigma, c) let pretype_ref ?loc evdref env ref us = match ref with | VarRef id -> (* Section variable *) - (try make_judge (mkVar id) (NamedDecl.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 @@ -544,7 +438,7 @@ let pretype_ref ?loc evdref env ref us = | ref -> let evd, c = pretype_global ?loc univ_flexible env !evdref ref us in let () = evdref := evd in - let ty = unsafe_type_of env.ExtraEnv.env evd c in + let ty = unsafe_type_of !!env evd c in make_judge c ty let judge_of_Type ?loc evd s = @@ -560,31 +454,13 @@ let pretype_sort ?loc evdref = function | GType s -> evd_comb1 (judge_of_Type ?loc) evdref s let new_type_evar env evdref loc = - let sigma = !evdref in - let (sigma, (e, _)) = - Evarutil.new_type_evar env.ExtraEnv.env sigma - univ_flexible_alg ~src:(loc,Evar_kinds.InternalHole) - in - evdref := sigma; - e - -module ConstrInterpObj = -struct - type ('r, 'g, 't) obj = - unbound_ltac_var_map -> env -> evar_map -> types -> 'g -> constr * evar_map - let name = "constr_interp" - let default _ = None -end - -module ConstrInterp = Genarg.Register(ConstrInterpObj) - -let register_constr_interp0 = ConstrInterp.register0 + e_new_type_evar env evdref ~src:(Loc.tag ?loc Evar_kinds.InternalHole) (* [pretype tycon env evdref lvar lmeta cstr] attempts to type [cstr] *) (* in environment [env], with existential variables [evdref] and *) (* the type constraint tycon *) -let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdref (lvar : ltac_var_map) t = +let rec pretype k0 resolve_tc (tycon : type_constraint) (env : GlobEnv.t) evdref t = let inh_conv_coerce_to_tycon ?loc = inh_conv_coerce_to_tycon ?loc resolve_tc in let pretype_type = pretype_type k0 resolve_tc in let pretype = pretype k0 resolve_tc in @@ -598,7 +474,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre | GVar id -> inh_conv_coerce_to_tycon ?loc env evdref - (pretype_id (fun e r l t -> pretype tycon e r l t) k0 loc env evdref lvar id) + (pretype_id (fun e r t -> pretype tycon e r t) k0 loc env evdref id) tycon | GEvar (id, inst) -> @@ -609,13 +485,12 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre with Not_found -> 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 args = pretype_instance k0 resolve_tc env evdref loc hyps evk inst in let c = mkEvar (evk, args) in - let j = (Retyping.get_judgment_of env.ExtraEnv.env !evdref c) in + let j = (Retyping.get_judgment_of !!env !evdref c) in inh_conv_coerce_to_tycon ?loc env evdref j tycon | GPatVar kind -> - let env = ltac_interp_name_env k0 lvar env !evdref in let ty = match tycon with | Some ty -> ty @@ -624,48 +499,40 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre { uj_val = e_new_evar env evdref ~src:(loc,k) ty; uj_type = ty } | GHole (k, naming, None) -> - let env = ltac_interp_name_env k0 lvar env !evdref in let ty = match tycon with | Some ty -> ty - | None -> - new_type_evar env evdref loc in + | None -> new_type_evar env evdref loc in { uj_val = e_new_evar env evdref ~src:(loc,k) ~naming ty; uj_type = ty } | GHole (k, _naming, Some arg) -> - let env = ltac_interp_name_env k0 lvar env !evdref in let ty = match tycon with | Some ty -> ty - | None -> - new_type_evar env evdref loc in - let open Genarg in - let ist = lvar.ltac_genargs in - let GenArg (Glbwit tag, arg) = arg in - let interp = ConstrInterp.obj tag in - let (c, sigma) = interp ist env.ExtraEnv.env !evdref ty arg in + | None -> new_type_evar env evdref loc in + let (c, sigma) = GlobEnv.interp_glob_genarg env !evdref ty arg in let () = evdref := sigma in { uj_val = c; uj_type = ty } | GRec (fixkind,names,bl,lar,vdef) -> let rec type_bl env ctxt = function - [] -> ctxt + | [] -> ctxt | (na,bk,None,ty)::bl -> - let ty' = pretype_type empty_valcon env evdref lvar ty in + let ty' = pretype_type empty_valcon env evdref ty in let dcl = LocalAssum (na, ty'.utj_val) in - let dcl' = LocalAssum (ltac_interp_name lvar na,ty'.utj_val) in - type_bl (push_rel !evdref dcl env) (Context.Rel.add dcl' ctxt) bl + let dcl', env = push_rel !evdref dcl env in + type_bl env (Context.Rel.add dcl' ctxt) bl | (na,bk,Some bd,ty)::bl -> - let ty' = pretype_type empty_valcon env evdref lvar ty in - let bd' = pretype (mk_tycon ty'.utj_val) env evdref lvar bd in + let ty' = pretype_type empty_valcon env evdref ty in + let bd' = pretype (mk_tycon ty'.utj_val) env evdref bd in let dcl = LocalDef (na, bd'.uj_val, ty'.utj_val) in - let dcl' = LocalDef (ltac_interp_name lvar na, bd'.uj_val, ty'.utj_val) in - type_bl (push_rel !evdref dcl env) (Context.Rel.add dcl' ctxt) bl in + let dcl', env = push_rel !evdref dcl env in + type_bl env (Context.Rel.add dcl' ctxt) bl in let ctxtv = Array.map (type_bl env Context.Rel.empty) bl in let larj = Array.map2 (fun e ar -> - pretype_type empty_valcon (push_rel_context !evdref e env) evdref lvar ar) + pretype_type empty_valcon (snd (push_rel_context !evdref e env)) evdref ar) ctxtv lar in let lara = Array.map (fun a -> a.utj_val) larj in let ftys = Array.map2 (fun e a -> it_mkProd_or_LetIn a e) ctxtv lara in @@ -678,14 +545,14 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre | GFix (vn,i) -> i | GCoFix i -> i in - begin match conv env.ExtraEnv.env !evdref ftys.(fixi) t with + begin match conv !!env !evdref ftys.(fixi) t with | None -> () | Some sigma -> evdref := sigma end | None -> () in (* Note: bodies are not used by push_rec_types, so [||] is safe *) - let newenv = push_rec_types !evdref (names,ftys,[||]) env in + let names,newenv = push_rec_types !evdref (names,ftys) env in let vdefj = Array.map2_i (fun i ctxt def -> @@ -694,12 +561,12 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre let (ctxt,ty) = decompose_prod_n_assum !evdref (Context.Rel.length ctxt) (lift nbfix ftys.(i)) in - let nenv = push_rel_context !evdref ctxt newenv in - let j = pretype (mk_tycon ty) nenv evdref lvar def in + let ctxt,nenv = push_rel_context !evdref ctxt newenv in + let j = pretype (mk_tycon ty) nenv evdref def in { uj_val = it_mkLambda_or_LetIn j.uj_val ctxt; uj_type = it_mkProd_or_LetIn j.uj_type ctxt }) ctxtv vdef in - evdref := Typing.check_type_fixpoint ?loc env.ExtraEnv.env !evdref names ftys vdefj; + evdref := Typing.check_type_fixpoint ?loc !!env !evdref names ftys vdefj; let nf c = nf_evar !evdref c in let ftys = Array.map nf ftys in (** FIXME *) let fdefs = Array.map (fun x -> nf (j_val x)) vdefj in @@ -721,13 +588,13 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre let fixdecls = (names,ftys,fdefs) in let indexes = search_guard - ?loc env.ExtraEnv.env possible_indexes (nf_fix !evdref fixdecls) + ?loc !!env possible_indexes (nf_fix !evdref fixdecls) in make_judge (mkFix ((indexes,i),fixdecls)) ftys.(i) | GCoFix i -> let fixdecls = (names,ftys,fdefs) in let cofix = (i, fixdecls) in - (try check_cofix env.ExtraEnv.env (i, nf_fix !evdref fixdecls) + (try check_cofix !!env (i, nf_fix !evdref fixdecls) with reraise -> let (e, info) = CErrors.push reraise in let info = Option.cata (Loc.add_loc info) info loc in @@ -742,11 +609,11 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre | GProj (p, c) -> (* TODO: once GProj is used as an input syntax, use bidirectional typing here *) - let cj = pretype empty_tycon env evdref lvar c in - judge_of_projection env.ExtraEnv.env !evdref p cj + let cj = pretype empty_tycon env evdref c in + judge_of_projection !!env !evdref p cj | GApp (f,args) -> - let fj = pretype empty_tycon env evdref lvar f in + let fj = pretype empty_tycon env evdref f in let floc = loc_of_glob_constr f in let length = List.length args in let candargs = @@ -762,7 +629,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre if Int.equal npars 0 then [] else try - let IndType (indf, args) = find_rectype env.ExtraEnv.env !evdref ty in + let IndType (indf, args) = find_rectype !!env !evdref ty in let ((ind',u'),pars) = dest_ind_family indf in if eq_ind ind ind' then List.map EConstr.of_constr pars else (* Let the usual code throw an error *) [] @@ -784,17 +651,17 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre | [] -> resj | c::rest -> let argloc = loc_of_glob_constr c 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 + let resj = evd_comb1 (Coercion.inh_app_fun resolve_tc !!env) evdref resj in + let resty = whd_all !!env !evdref resj.uj_type in match EConstr.kind !evdref resty with | Prod (na,c1,c2) -> let tycon = Some c1 in - let hj = pretype tycon env evdref lvar c in + let hj = pretype tycon env evdref c in let candargs, ujval = match candargs with | [] -> [], j_val hj | arg :: args -> - begin match conv env.ExtraEnv.env !evdref (j_val hj) arg with + begin match conv !!env !evdref (j_val hj) arg with | Some sigma -> evdref := sigma; args, nf_evar !evdref (j_val hj) | None -> @@ -807,104 +674,96 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre apply_rec env (n+1) j candargs rest | _ -> - let hj = pretype empty_tycon env evdref lvar c in + let hj = pretype empty_tycon env evdref c in error_cant_apply_not_functional - ?loc:(Loc.merge_opt floc argloc) env.ExtraEnv.env !evdref + ?loc:(Loc.merge_opt floc argloc) !!env !evdref resj [|hj|] in let resj = apply_rec env 1 fj candargs args in let resj = match EConstr.kind !evdref resj.uj_val with | App (f,args) -> - if is_template_polymorphic env.ExtraEnv.env !evdref f then + if is_template_polymorphic !!env !evdref f then (* Special case for inductive type applications that must be refreshed right away. *) let c = mkApp (f, args) 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 + let c = evd_comb1 (Evarsolve.refresh_universes (Some true) !!env) evdref c in + let t = Retyping.get_type_of !!env !evdref c in make_judge c (* use this for keeping evars: resj.uj_val *) t else resj | _ -> resj in inh_conv_coerce_to_tycon ?loc env evdref resj tycon - | GLambda(name,bk,c1,c2) -> + | GLambda(name,bk,c1,c2) -> let tycon' = evd_comb1 (fun evd tycon -> match tycon with | None -> evd, tycon | Some ty -> - let evd, ty' = Coercion.inh_coerce_to_prod ?loc env.ExtraEnv.env evd ty in + let evd, ty' = Coercion.inh_coerce_to_prod ?loc !!env evd ty in evd, Some ty') evdref tycon in - let (name',dom,rng) = evd_comb1 (split_tycon ?loc env.ExtraEnv.env) evdref tycon' in + let (name',dom,rng) = evd_comb1 (split_tycon ?loc !!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 - the substitution must also be applied on variables before they are - looked up in the rel context. *) + let j = pretype_type dom_valcon env evdref c1 in let var = LocalAssum (name, j.utj_val) in - let j' = pretype rng (push_rel !evdref var env) evdref lvar c2 in - let name = ltac_interp_name lvar name in - let resj = judge_of_abstraction env.ExtraEnv.env (orelse_name name name') j j' in + let var',env' = push_rel !evdref var env in + let j' = pretype rng env' evdref c2 in + let name = get_name var' in + let resj = judge_of_abstraction !!env (orelse_name name name') j j' in inh_conv_coerce_to_tycon ?loc env evdref resj tycon - | GProd(name,bk,c1,c2) -> - let j = pretype_type empty_valcon env evdref lvar c1 in - (* The name specified by ltac is used also to create bindings. So - the substitution must also be applied on variables before they are - looked up in the rel context. *) - let j' = match name with + | GProd(name,bk,c1,c2) -> + let j = pretype_type empty_valcon env evdref c1 in + let name, j' = match name with | Anonymous -> - let j = pretype_type empty_valcon env evdref lvar c2 in - { j with utj_val = lift 1 j.utj_val } + let j = pretype_type empty_valcon env evdref c2 in + name, { j with utj_val = lift 1 j.utj_val } | Name _ -> let var = LocalAssum (name, j.utj_val) in - let env' = push_rel !evdref var env in - pretype_type empty_valcon env' evdref lvar c2 + let var, env' = push_rel !evdref var env in + get_name var, pretype_type empty_valcon env' evdref c2 in - let name = ltac_interp_name lvar name in let resj = try - judge_of_product env.ExtraEnv.env name j j' + judge_of_product !!env name j j' with TypeError _ as e -> let (e, info) = CErrors.push e in let info = Option.cata (Loc.add_loc info) info loc in iraise (e, info) in inh_conv_coerce_to_tycon ?loc env evdref resj tycon - | GLetIn(name,c1,t,c2) -> + | GLetIn(name,c1,t,c2) -> let tycon1 = match t with | Some t -> - mk_tycon (pretype_type empty_valcon env evdref lvar t).utj_val + mk_tycon (pretype_type empty_valcon env evdref t).utj_val | None -> empty_tycon in - let j = pretype tycon1 env evdref lvar c1 in + let j = pretype tycon1 env evdref c1 in let t = evd_comb1 (Evarsolve.refresh_universes - ~onlyalg:true ~status:Evd.univ_flexible (Some false) env.ExtraEnv.env) + ~onlyalg:true ~status:Evd.univ_flexible (Some false) !!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 - looked up in the rel context. *) let var = LocalDef (name, j.uj_val, t) in let tycon = lift_tycon 1 tycon in - let j' = pretype tycon (push_rel !evdref var env) evdref lvar c2 in - let name = ltac_interp_name lvar name in + let var, env = push_rel !evdref var env in + let j' = pretype tycon env evdref c2 in + let name = get_name var in { uj_val = mkLetIn (name, j.uj_val, t, j'.uj_val) ; uj_type = subst1 j.uj_val j'.uj_type } | GLetTuple (nal,(na,po),c,d) -> - let cj = pretype empty_tycon env evdref lvar c in + let cj = pretype empty_tycon env evdref c in let (IndType (indf,realargs)) = - try find_rectype env.ExtraEnv.env !evdref cj.uj_type + try find_rectype !!env !evdref cj.uj_type with Not_found -> let cloc = loc_of_glob_constr c in - error_case_not_inductive ?loc:cloc env.ExtraEnv.env !evdref cj + error_case_not_inductive ?loc:cloc !!env !evdref cj in let ind = fst (fst (dest_ind_family indf)) in - let cstrs = get_constructors env.ExtraEnv.env indf in + let cstrs = get_constructors !!env indf in if not (Int.equal (Array.length cstrs) 1) then user_err ?loc (str "Destructing let is only for inductive types" ++ str " with one constructor."); @@ -914,7 +773,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre int cs.cs_nargs ++ str " variables."); let fsign, record = let set_name na d = set_name na (map_rel_decl EConstr.of_constr d) in - match Environ.get_projections env.ExtraEnv.env ind with + match Environ.get_projections !!env ind with | None -> List.map2 set_name (List.rev nal) cs.cs_args, false | Some ps -> @@ -933,108 +792,97 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre let fsign = if Flags.version_strictly_greater Flags.V8_6 then Context.Rel.map (whd_betaiota !evdref) fsign else fsign (* beta-iota-normalization regression in 8.5 and 8.6 *) in + let fsign,env_f = push_rel_context !evdref fsign env in let obj ind p v f = - if not record then - let nal = List.map (fun na -> ltac_interp_name lvar na) nal in - let nal = List.rev nal in - let fsign = List.map2 set_name nal fsign in + if not record then let f = it_mkLambda_or_LetIn f fsign in - let ci = make_case_info env.ExtraEnv.env (fst ind) LetStyle in + let ci = make_case_info !!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 !evdref fsign env in - (* Make dependencies from arity signature impossible *) + (* Make dependencies from arity signature impossible *) let arsgn = - let arsgn,_ = get_arity env.ExtraEnv.env indf in + let arsgn,_ = get_arity !!env indf in List.map (set_name Anonymous) arsgn in - let indt = build_dependent_inductive env.ExtraEnv.env indf in + let indt = build_dependent_inductive !!env indf in let psign = LocalAssum (na, indt) :: arsgn in (* For locating names in [po] *) - let predlvar = Cases.make_return_predicate_ltac_lvar !evdref na c cj.uj_val lvar in - let psign' = LocalAssum (ltac_interp_name predlvar na, indt) :: arsgn in - let psign' = List.map (fun d -> map_rel_decl EConstr.of_constr d) psign' in - let psign' = Namegen.name_context env.ExtraEnv.env !evdref psign' in (* For naming abstractions in [po] *) let psign = List.map (fun d -> map_rel_decl EConstr.of_constr d) psign in + let predenv = Cases.make_return_predicate_ltac_lvar env !evdref na c cj.uj_val in let nar = List.length arsgn in + let psign',env_p = push_rel_context ~force_names:true !evdref psign predenv in (match po with | Some p -> - let env_p = push_rel_context !evdref psign env in - let pj = pretype_type empty_valcon env_p evdref predlvar p in + let pj = pretype_type empty_valcon env_p evdref p in let ccl = nf_evar !evdref pj.utj_val in let p = it_mkLambda_or_LetIn ccl psign' in let inst = (Array.map_to_list EConstr.of_constr cs.cs_concl_realargs) @[EConstr.of_constr (build_dependent_constructor cs)] in let lp = lift cs.cs_nargs p 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 fty = hnf_lam_applist !!env !evdref lp inst in + let fj = pretype (mk_tycon fty) env_f evdref d in let v = let ind,_ = dest_ind_family indf in - Typing.check_allowed_sort env.ExtraEnv.env !evdref ind cj.uj_val p; + Typing.check_allowed_sort !!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) } | None -> let tycon = lift_tycon cs.cs_nargs tycon in - let fj = pretype tycon env_f evdref predlvar d in + let fj = pretype tycon env_f evdref d in let ccl = nf_evar !evdref fj.uj_type in let ccl = if noccur_between !evdref 1 cs.cs_nargs ccl then lift (- cs.cs_nargs) ccl else - error_cant_find_case_type ?loc env.ExtraEnv.env !evdref + error_cant_find_case_type ?loc !!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.ExtraEnv.env !evdref ind cj.uj_val p; + Typing.check_allowed_sort !!env !evdref ind cj.uj_val p; obj ind p cj.uj_val fj.uj_val in { uj_val = v; uj_type = ccl }) | GIf (c,(na,po),b1,b2) -> - let cj = pretype empty_tycon env evdref lvar c in + let cj = pretype empty_tycon env evdref c in let (IndType (indf,realargs)) = - try find_rectype env.ExtraEnv.env !evdref cj.uj_type + try find_rectype !!env !evdref cj.uj_type with Not_found -> let cloc = loc_of_glob_constr c in - error_case_not_inductive ?loc:cloc env.ExtraEnv.env !evdref cj in - let cstrs = get_constructors env.ExtraEnv.env indf in + error_case_not_inductive ?loc:cloc !!env !evdref cj in + let cstrs = get_constructors !!env indf in if not (Int.equal (Array.length cstrs) 2) then user_err ?loc (str "If is only for inductive types with two constructors."); let arsgn = - let arsgn,_ = get_arity env.ExtraEnv.env indf in + let arsgn,_ = get_arity !!env indf in (* Make dependencies from arity signature impossible *) List.map (set_name Anonymous) arsgn in let nar = List.length arsgn in - let indt = build_dependent_inductive env.ExtraEnv.env indf in + let indt = build_dependent_inductive !!env indf in let psign = LocalAssum (na, indt) :: arsgn in (* For locating names in [po] *) - let predlvar = Cases.make_return_predicate_ltac_lvar !evdref na c cj.uj_val lvar in - let psign' = LocalAssum (ltac_interp_name predlvar na, indt) :: arsgn in - let psign' = List.map (fun d -> map_rel_decl EConstr.of_constr d) psign' in - let psign' = Namegen.name_context env.ExtraEnv.env !evdref psign' in (* For naming abstractions in [po] *) let psign = List.map (fun d -> map_rel_decl EConstr.of_constr d) psign in + let predenv = Cases.make_return_predicate_ltac_lvar env !evdref na c cj.uj_val in + let psign,env_p = push_rel_context !evdref psign predenv in let pred,p = match po with | Some p -> - let env_p = push_rel_context !evdref psign env in - let pj = pretype_type empty_valcon env_p evdref predlvar p in + let pj = pretype_type empty_valcon env_p evdref p in let ccl = nf_evar !evdref pj.utj_val in - let pred = it_mkLambda_or_LetIn ccl psign' in + let pred = it_mkLambda_or_LetIn ccl psign in let typ = lift (- nar) (beta_applist !evdref (pred,[cj.uj_val])) in pred, typ | None -> let p = match tycon with | Some ty -> ty - | None -> - let env = ltac_interp_name_env k0 lvar env !evdref in - new_type_evar env evdref loc + | None -> new_type_evar env evdref loc in - it_mkLambda_or_LetIn (lift (nar+1) p) psign', p in + it_mkLambda_or_LetIn (lift (nar+1) p) psign, p in let pred = nf_evar !evdref pred in let p = nf_evar !evdref p in let f cs b = @@ -1049,85 +897,83 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre let csgn = List.map (set_name Anonymous) cs_args in - let env_c = push_rel_context !evdref csgn env in - let bj = pretype (mk_tycon pi) env_c evdref lvar b in + let _,env_c = push_rel_context !evdref csgn env in + let bj = pretype (mk_tycon pi) env_c evdref b in it_mkLambda_or_LetIn bj.uj_val cs_args in let b1 = f cstrs.(0) b1 in let b2 = f cstrs.(1) b2 in let v = let ind,_ = dest_ind_family indf in - let ci = make_case_info env.ExtraEnv.env (fst ind) IfStyle in + let ci = make_case_info !!env (fst ind) IfStyle in let pred = nf_evar !evdref pred in - Typing.check_allowed_sort env.ExtraEnv.env !evdref ind cj.uj_val pred; + Typing.check_allowed_sort !!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 inh_conv_coerce_to_tycon ?loc env evdref cj tycon | GCases (sty,po,tml,eqns) -> - Cases.compile_cases ?loc sty - ((fun vtyc env evdref -> pretype vtyc (make_env env !evdref) evdref),evdref) - tycon env.ExtraEnv.env (* loc *) lvar (po,tml,eqns) + Cases.compile_cases ?loc sty (pretype,evdref) tycon env (po,tml,eqns) | GCast (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.ExtraEnv.env) evdref cj + let cj = pretype empty_tycon env evdref c in + evd_comb1 (Coercion.inh_coerce_to_base ?loc !!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 tj = pretype_type empty_valcon env evdref t in let tval = evd_comb1 (Evarsolve.refresh_universes - ~onlyalg:true ~status:Evd.univ_flexible (Some false) env.ExtraEnv.env) + ~onlyalg:true ~status:Evd.univ_flexible (Some false) !!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 cj = pretype empty_tycon env evdref c in let cty = nf_evar !evdref cj.uj_type and tval = nf_evar !evdref tval in if not (occur_existential !evdref cty || occur_existential !evdref tval) then - match Reductionops.vm_infer_conv env.ExtraEnv.env !evdref cty tval with + match Reductionops.vm_infer_conv !!env !evdref cty tval with | Some evd -> (evdref := evd; cj, tval) | None -> - error_actual_type ?loc env.ExtraEnv.env !evdref cj tval - (ConversionFailed (env.ExtraEnv.env,cty,tval)) + error_actual_type ?loc !!env !evdref cj tval + (ConversionFailed (!!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 cj = pretype empty_tycon env evdref c in let cty = nf_evar !evdref cj.uj_type and tval = nf_evar !evdref tval in begin - match Nativenorm.native_infer_conv env.ExtraEnv.env !evdref cty tval with + match Nativenorm.native_infer_conv !!env !evdref cty tval with | Some evd -> (evdref := evd; cj, tval) | None -> - error_actual_type ?loc env.ExtraEnv.env !evdref cj tval - (ConversionFailed (env.ExtraEnv.env,cty,tval)) + error_actual_type ?loc !!env !evdref cj tval + (ConversionFailed (!!env,cty,tval)) end | _ -> - pretype (mk_tycon tval) env evdref lvar c, tval + pretype (mk_tycon tval) env evdref c, tval in let v = mkCast (cj.uj_val, k, tval) in { uj_val = v; uj_type = tval } in inh_conv_coerce_to_tycon ?loc env evdref cj tycon -and pretype_instance k0 resolve_tc env evdref lvar loc hyps evk update = +and pretype_instance k0 resolve_tc env evdref loc hyps evk update = let f decl (subst,update) = 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 - let c = pretype k0 resolve_tc (mk_tycon t) env evdref lvar c in + let c = pretype k0 resolve_tc (mk_tycon t) env evdref c in c.uj_val, List.remove_assoc id update with Not_found -> try - let (n,_,t') = lookup_rel_id id (rel_context env) in - if is_conv env.ExtraEnv.env !evdref t (lift n t') then mkRel n, update else raise Not_found + let (n,_,t') = lookup_rel_id id (rel_context !!env) in + if is_conv !!env !evdref t (lift n t') then mkRel n, update else raise Not_found with Not_found -> try - 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 + let t' = !!env |> lookup_named id |> NamedDecl.get_type in + if is_conv !!env !evdref t t' then mkVar id, update else raise Not_found with Not_found -> user_err ?loc (str "Cannot interpret " ++ pr_existential_key !evdref evk ++ @@ -1137,19 +983,19 @@ and pretype_instance k0 resolve_tc env evdref lvar loc hyps evk update = check_instance loc subst inst; 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 : ExtraEnv.t) evdref lvar c = match DAst.get c with +(* [pretype_type valcon env evdref c] coerces [c] into a type *) +and pretype_type k0 resolve_tc valcon (env : GlobEnv.t) evdref c = match DAst.get c with | GHole (knd, naming, None) -> let loc = loc_of_glob_constr c in (match valcon with | Some v -> let s = let sigma = !evdref in - let t = Retyping.get_type_of env.ExtraEnv.env sigma v in - match EConstr.kind sigma (whd_all env.ExtraEnv.env sigma t) with + let t = Retyping.get_type_of !!env sigma v in + match EConstr.kind sigma (whd_all !!env sigma t) with | Sort s -> ESorts.kind sigma s | Evar ev when is_Type sigma (existential_type sigma ev) -> - evd_comb1 (define_evar_as_sort env.ExtraEnv.env) evdref ev + evd_comb1 (define_evar_as_sort !!env) evdref ev | _ -> anomaly (Pp.str "Found a type constraint which is not a type.") in (* Correction of bug #5315 : we need to define an evar for *all* holes *) @@ -1160,40 +1006,39 @@ and pretype_type k0 resolve_tc valcon (env : ExtraEnv.t) evdref lvar c = match D { utj_val = v; utj_type = s } | None -> - let env = ltac_interp_name_env k0 lvar env !evdref in let s = evd_comb0 (new_sort_variable univ_flexible_alg) evdref in { utj_val = e_new_evar env evdref ~src:(loc, knd) ~naming (mkSort s); utj_type = s}) | _ -> - let j = pretype k0 resolve_tc empty_tycon env evdref lvar c in + let j = pretype k0 resolve_tc empty_tycon env evdref c in let loc = loc_of_glob_constr c in - let tj = evd_comb1 (Coercion.inh_coerce_to_sort ?loc env.ExtraEnv.env) evdref j in + let tj = evd_comb1 (Coercion.inh_coerce_to_sort ?loc !!env) evdref j in match valcon with | None -> tj | Some v -> - begin match cumul env.ExtraEnv.env !evdref v tj.utj_val with + begin match cumul !!env !evdref v tj.utj_val with | Some sigma -> evdref := sigma; tj | None -> error_unexpected_type - ?loc:(loc_of_glob_constr c) env.ExtraEnv.env !evdref tj.utj_val v + ?loc:(loc_of_glob_constr c) !!env !evdref tj.utj_val v end let ise_pretype_gen flags env sigma lvar kind c = - let env = make_env env sigma in + let env = GlobEnv.make env sigma lvar in let evdref = ref sigma in - let k0 = Context.Rel.length (rel_context env) in + let k0 = Context.Rel.length (rel_context !!env) in let c', c'_ty = match kind with | WithoutTypeConstraint -> - let j = pretype k0 flags.use_typeclasses empty_tycon env evdref lvar c in + let j = pretype k0 flags.use_typeclasses empty_tycon env evdref c in j.uj_val, j.uj_type | OfType exptyp -> - let j = pretype k0 flags.use_typeclasses (mk_tycon exptyp) env evdref lvar c in + let j = pretype k0 flags.use_typeclasses (mk_tycon exptyp) env evdref c in j.uj_val, j.uj_type | IsType -> - let tj = pretype_type k0 flags.use_typeclasses empty_valcon env evdref lvar c in + let tj = pretype_type k0 flags.use_typeclasses empty_valcon env evdref c in tj.utj_val, mkSort tj.utj_type in - process_inference_flags flags env.ExtraEnv.env sigma (!evdref,c',c'_ty) + process_inference_flags flags !!env sigma (!evdref,c',c'_ty) let default_inference_flags fail = { use_typeclasses = true; @@ -1236,7 +1081,7 @@ let understand_ltac flags env sigma lvar kind c = (sigma, c) let pretype k0 resolve_tc typcon env evdref lvar t = - pretype k0 resolve_tc typcon (make_env env !evdref) evdref lvar t + pretype k0 resolve_tc typcon (GlobEnv.make env !evdref lvar) evdref t let pretype_type k0 resolve_tc valcon env evdref lvar t = - pretype_type k0 resolve_tc valcon (make_env env !evdref) evdref lvar t + pretype_type k0 resolve_tc valcon (GlobEnv.make env !evdref lvar) evdref t diff --git a/pretyping/pretyping.mli b/pretyping/pretyping.mli index 73f5b77e0e..fcc361b16b 100644 --- a/pretyping/pretyping.mli +++ b/pretyping/pretyping.mli @@ -122,11 +122,3 @@ val pretype_type : val ise_pretype_gen : inference_flags -> env -> evar_map -> ltac_var_map -> typing_constraint -> glob_constr -> evar_map * constr * types - -(**/**) - -(** To embed constr in glob_constr *) - -val register_constr_interp0 : - ('r, 'g, 't) Genarg.genarg_type -> - (unbound_ltac_var_map -> env -> evar_map -> types -> 'g -> constr * evar_map) -> unit diff --git a/pretyping/pretyping.mllib b/pretyping/pretyping.mllib index 5da5aff449..d0359b43f4 100644 --- a/pretyping/pretyping.mllib +++ b/pretyping/pretyping.mllib @@ -32,6 +32,7 @@ Program Coercion Detyping Indrec +GlobEnv Cases Pretyping Unification diff --git a/pretyping/recordops.ml b/pretyping/recordops.ml index 2f861c117b..bd41e61b34 100644 --- a/pretyping/recordops.ml +++ b/pretyping/recordops.ml @@ -192,11 +192,11 @@ let rec assoc_pat a = function let object_table = - Summary.ref (Refmap.empty : ((cs_pattern * constr) * obj_typ) list Refmap.t) + Summary.ref (GlobRef.Map.empty : ((cs_pattern * constr) * obj_typ) list GlobRef.Map.t) ~name:"record-canonical-structs" let canonical_projections () = - Refmap.fold (fun x -> List.fold_right (fun ((y,_),c) acc -> ((x,y),c)::acc)) + GlobRef.Map.fold (fun x -> List.fold_right (fun ((y,_),c) acc -> ((x,y),c)::acc)) !object_table [] let keep_true_projections projs kinds = @@ -289,11 +289,11 @@ let warn_redundant_canonical_projection = 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 l = try GlobRef.Map.find proj !object_table with Not_found -> [] in let ocs = try Some (assoc_pat cs_pat l) with Not_found -> None in match ocs with - | None -> object_table := Refmap.add proj ((pat,s)::l) !object_table; + | None -> object_table := GlobRef.Map.add proj ((pat,s)::l) !object_table; | Some (c, cs) -> let old_can_s = (Termops.print_constr (EConstr.of_constr cs.o_DEF)) and new_can_s = (Termops.print_constr (EConstr.of_constr s.o_DEF)) in @@ -372,18 +372,18 @@ let declare_canonical_structure ref = add_canonical_structure (check_and_decompose_canonical_structure ref) let lookup_canonical_conversion (proj,pat) = - assoc_pat pat (Refmap.find proj !object_table) + assoc_pat pat (GlobRef.Map.find proj !object_table) let decompose_projection sigma c args = match EConstr.kind sigma c with | Const (c, u) -> let n = find_projection_nparams (ConstRef c) in (** Check if there is some canonical projection attached to this structure *) - let _ = Refmap.find (ConstRef c) !object_table in + let _ = GlobRef.Map.find (ConstRef c) !object_table in let arg = Stack.nth args n in arg | Proj (p, c) -> - let _ = Refmap.find (ConstRef (Projection.constant p)) !object_table in + let _ = GlobRef.Map.find (ConstRef (Projection.constant p)) !object_table in c | _ -> raise Not_found diff --git a/pretyping/reductionops.ml b/pretyping/reductionops.ml index ba40262815..f4c8a6cd66 100644 --- a/pretyping/reductionops.ml +++ b/pretyping/reductionops.ml @@ -88,6 +88,7 @@ let set_reduction_effect x funkey = (** Machinery to custom the behavior of the reduction *) module ReductionBehaviour = struct open Globnames + open Names open Libobject type t = { @@ -97,7 +98,7 @@ module ReductionBehaviour = struct } let table = - Summary.ref (Refmap.empty : t Refmap.t) ~name:"reductionbehaviour" + Summary.ref (GlobRef.Map.empty : t GlobRef.Map.t) ~name:"reductionbehaviour" type flag = [ `ReductionDontExposeCase | `ReductionNeverUnfold ] type req = @@ -105,7 +106,7 @@ module ReductionBehaviour = struct | ReqGlobal of GlobRef.t * (int list * int * flag list) let load _ (_,(_,(r, b))) = - table := Refmap.add r b !table + table := GlobRef.Map.add r b !table let cache o = load 1 o @@ -160,7 +161,7 @@ module ReductionBehaviour = struct let get r = try - let b = Refmap.find r !table in + let b = GlobRef.Map.find r !table in let flags = if Int.equal b.b_nargs max_int then [`ReductionNeverUnfold] else if b.b_dont_expose_case then [`ReductionDontExposeCase] else [] in @@ -628,6 +629,18 @@ let safe_meta_value sigma ev = try Some (Evd.meta_value sigma ev) with Not_found -> None +let strong_with_flags whdfun flags env sigma t = + let push_rel_check_zeta d env = + let open CClosure.RedFlags in + let d = match d with + | LocalDef (na,c,t) when not (red_set flags fZETA) -> LocalAssum (na,t) + | d -> d in + push_rel d env in + let rec strongrec env t = + map_constr_with_full_binders sigma + push_rel_check_zeta strongrec env (whdfun flags env sigma t) in + strongrec env t + let strong whdfun env sigma t = let rec strongrec env t = map_constr_with_full_binders sigma push_rel strongrec env (whdfun env sigma t) in diff --git a/pretyping/reductionops.mli b/pretyping/reductionops.mli index 07eeec9276..dd3cd26f0f 100644 --- a/pretyping/reductionops.mli +++ b/pretyping/reductionops.mli @@ -144,6 +144,9 @@ val pr_state : state -> Pp.t (** {6 Reduction Function Operators } *) +val strong_with_flags : + (CClosure.RedFlags.reds -> reduction_function) -> + (CClosure.RedFlags.reds -> reduction_function) val strong : reduction_function -> reduction_function val local_strong : local_reduction_function -> local_reduction_function val strong_prodspine : local_reduction_function -> local_reduction_function diff --git a/pretyping/typeclasses.ml b/pretyping/typeclasses.ml index efb3c339ac..55d9838bbb 100644 --- a/pretyping/typeclasses.ml +++ b/pretyping/typeclasses.ml @@ -88,7 +88,7 @@ type typeclass = { cl_unique : bool; } -type typeclasses = typeclass Refmap.t +type typeclasses = typeclass GlobRef.Map.t type instance = { is_class: GlobRef.t; @@ -99,7 +99,7 @@ type instance = { is_impl: GlobRef.t; } -type instances = (instance Refmap.t) Refmap.t +type instances = (instance GlobRef.Map.t) GlobRef.Map.t let instance_impl is = is.is_impl @@ -121,8 +121,8 @@ let new_instance cl info glob impl = * states management *) -let classes : typeclasses ref = Summary.ref Refmap.empty ~name:"classes" -let instances : instances ref = Summary.ref Refmap.empty ~name:"instances" +let classes : typeclasses ref = Summary.ref GlobRef.Map.empty ~name:"classes" +let instances : instances ref = Summary.ref GlobRef.Map.empty ~name:"instances" let typeclass_univ_instance (cl, u) = assert (Univ.AUContext.size cl.cl_univs == Univ.Instance.length u); @@ -131,7 +131,7 @@ let typeclass_univ_instance (cl, u) = cl_props = subst_ctx cl.cl_props} let class_info c = - try Refmap.find c !classes + try GlobRef.Map.find c !classes with Not_found -> not_a_class (Global.env()) (EConstr.of_constr (printable_constr_of_global c)) let global_class_of_constr env sigma c = @@ -154,7 +154,7 @@ let class_of_constr sigma c = let is_class_constr sigma c = try let gr, u = Termops.global_of_constr sigma c in - Refmap.mem gr !classes + GlobRef.Map.mem gr !classes with Not_found -> false let rec is_class_type evd c = @@ -172,7 +172,7 @@ let is_class_evar evd evi = *) let load_class (_, cl) = - classes := Refmap.add cl.cl_impl cl !classes + classes := GlobRef.Map.add cl.cl_impl cl !classes let cache_class = load_class @@ -336,17 +336,17 @@ type instance_action = let load_instance inst = let insts = - try Refmap.find inst.is_class !instances - with Not_found -> Refmap.empty in - let insts = Refmap.add inst.is_impl inst insts in - instances := Refmap.add inst.is_class insts !instances + try GlobRef.Map.find inst.is_class !instances + with Not_found -> GlobRef.Map.empty in + let insts = GlobRef.Map.add inst.is_impl inst insts in + instances := GlobRef.Map.add inst.is_class insts !instances let remove_instance inst = let insts = - try Refmap.find inst.is_class !instances + try GlobRef.Map.find inst.is_class !instances with Not_found -> assert false in - let insts = Refmap.remove inst.is_impl insts in - instances := Refmap.add inst.is_class insts !instances + let insts = GlobRef.Map.remove inst.is_impl insts in + instances := GlobRef.Map.add inst.is_class insts !instances let cache_instance (_, (action, i)) = match action with @@ -464,23 +464,23 @@ let instance_constructor (cl,u) args = (term, applist (mkConstU cst, pars)) | _ -> assert false -let typeclasses () = Refmap.fold (fun _ l c -> l :: c) !classes [] +let typeclasses () = GlobRef.Map.fold (fun _ l c -> l :: c) !classes [] -let cmap_elements c = Refmap.fold (fun k v acc -> v :: acc) c [] +let cmap_elements c = GlobRef.Map.fold (fun k v acc -> v :: acc) c [] let instances_of c = - try cmap_elements (Refmap.find c.cl_impl !instances) with Not_found -> [] + try cmap_elements (GlobRef.Map.find c.cl_impl !instances) with Not_found -> [] let all_instances () = - Refmap.fold (fun k v acc -> - Refmap.fold (fun k v acc -> v :: acc) v acc) + GlobRef.Map.fold (fun k v acc -> + GlobRef.Map.fold (fun k v acc -> v :: acc) v acc) !instances [] let instances r = let cl = class_info r in instances_of cl let is_class gr = - Refmap.exists (fun _ v -> GlobRef.equal v.cl_impl gr) !classes + GlobRef.Map.exists (fun _ v -> GlobRef.equal v.cl_impl gr) !classes let is_instance = function | ConstRef c -> |
