diff options
author | Matthieu Sozeau <mattam@mattam.org> | 2013-10-28 14:08:46 +0100 |
---|---|---|
committer | Matthieu Sozeau <mattam@mattam.org> | 2014-05-06 09:58:54 +0200 |
commit | 001ff72b2c17fb7b2fcaefa2555c115f0d909a03 (patch) | |
tree | 9e83ae395173699a7c5b6f00648c4336bedb7afd /kernel | |
parent | 84cbc09bd1400f732a6c70e8a840e4c13d018478 (diff) |
Initial work on reintroducing old-style polymorphism for compatibility (the stdlib does not compile entirely).
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/cooking.ml | 29 | ||||
-rw-r--r-- | kernel/declarations.mli | 23 | ||||
-rw-r--r-- | kernel/declareops.ml | 130 | ||||
-rw-r--r-- | kernel/declareops.mli | 5 | ||||
-rw-r--r-- | kernel/environ.ml | 17 | ||||
-rw-r--r-- | kernel/environ.mli | 8 | ||||
-rw-r--r-- | kernel/fast_typeops.ml | 33 | ||||
-rw-r--r-- | kernel/indtypes.ml | 22 | ||||
-rw-r--r-- | kernel/inductive.ml | 79 | ||||
-rw-r--r-- | kernel/inductive.mli | 3 | ||||
-rw-r--r-- | kernel/subtyping.ml | 8 | ||||
-rw-r--r-- | kernel/term_typing.ml | 38 | ||||
-rw-r--r-- | kernel/typeops.ml | 56 | ||||
-rw-r--r-- | kernel/typeops.mli | 20 |
14 files changed, 315 insertions, 156 deletions
diff --git a/kernel/cooking.ml b/kernel/cooking.ml index 4bae6de66..3d580d713 100644 --- a/kernel/cooking.ml +++ b/kernel/cooking.ml @@ -183,21 +183,17 @@ let cook_constant env { from = cb; info = { Opaqueproof.modlist; abstract } } = Context.fold_named_context (fun (h,_,_) hyps -> List.filter (fun (id,_,_) -> not (Id.equal id h)) hyps) hyps ~init:cb.const_hyps in - - (* let typ = match cb.const_type with *) - (* | NonPolymorphicType t -> *) - (* let typ = *) - (* abstract_constant_type (expmod_constr cache r.d_modlist t) hyps in *) - (* NonPolymorphicType typ *) - (* | PolymorphicArity (ctx,s) -> *) - (* let t = mkArity (ctx,Type s.poly_level) in *) - (* let typ = *) - (* abstract_constant_type (expmod_constr cache r.d_modlist t) hyps in *) - (* let j = make_judge (constr_of_def body) typ in *) - (* Typeops.make_polymorphic_if_constant_for_ind env j *) - (* in *) - let typ = - abstract_constant_type (expmod_constr cache modlist cb.const_type) hyps + let typ = match cb.const_type with + | RegularArity t -> + let typ = + abstract_constant_type (expmod_constr cache modlist t) hyps in + RegularArity typ + | TemplateArity (ctx,s) -> + let t = mkArity (ctx,Type s.template_level) in + let typ = + abstract_constant_type (expmod_constr cache modlist t) hyps in + let j = make_judge (constr_of_def body) typ in + Typeops.make_polymorphic_if_constant_for_ind env j in let projection pb = let c' = abstract_constant_body (expmod_constr cache modlist pb.proj_body) hyps in @@ -210,6 +206,9 @@ let cook_constant env { from = cb; info = { Opaqueproof.modlist; abstract } } = | _ -> assert false with Not_found -> (((pb.proj_ind,0),Univ.Instance.empty), 0) in + let typ = (* By invariant, a regular arity *) + match typ with RegularArity t -> t | TemplateArity _ -> assert false + in let ctx, ty' = decompose_prod_n (n' + pb.proj_npars + 1) typ in { proj_ind = mind; proj_npars = pb.proj_npars + n'; proj_arg = pb.proj_arg; proj_type = ty'; proj_body = c' } diff --git a/kernel/declarations.mli b/kernel/declarations.mli index f3cb41f32..f269e165e 100644 --- a/kernel/declarations.mli +++ b/kernel/declarations.mli @@ -18,7 +18,24 @@ type engagement = ImpredicativeSet (** {6 Representation of constants (Definition/Axiom) } *) -type constant_type = types +(** Non-universe polymorphic mode polymorphism (Coq 8.2+): inductives + and constants hiding inductives are implicitely polymorphic when + applied to parameters, on the universes appearing in the whnf of + their parameters and their conclusion, in a template style. + + In truely universe polymorphic mode, we always use RegularArity. +*) + +type template_arity = { + template_param_levels : Univ.universe option list; + template_level : Univ.universe; +} + +type ('a, 'b) declaration_arity = + | RegularArity of 'a + | TemplateArity of 'b + +type constant_type = (types, rel_context * template_arity) declaration_arity (** Inlining level of parameters at functor applications. None means no inlining *) @@ -79,11 +96,13 @@ type wf_paths = recarg Rtree.t v} *) -type inductive_arity = { +type regular_inductive_arity = { mind_user_arity : types; mind_sort : sorts; } +type inductive_arity = (regular_inductive_arity, template_arity) declaration_arity + type one_inductive_body = { (** {8 Primitive datas } *) diff --git a/kernel/declareops.ml b/kernel/declareops.ml index 0e4b80495..be6c18810 100644 --- a/kernel/declareops.ml +++ b/kernel/declareops.ml @@ -13,6 +13,28 @@ open Util (** Operations concernings types in [Declarations] : [constant_body], [mutual_inductive_body], [module_body] ... *) +(** {6 Arities } *) + +let subst_decl_arity f g sub ar = + match ar with + | RegularArity x -> + let x' = f sub x in + if x' == x then ar + else RegularArity x' + | TemplateArity x -> + let x' = g sub x in + if x' == x then ar + else TemplateArity x' + +let map_decl_arity f g = function + | RegularArity a -> RegularArity (f a) + | TemplateArity a -> TemplateArity (g a) + +let hcons_template_arity ar = + { template_param_levels = + List.smartmap (Option.smartmap Univ.hcons_univ) ar.template_param_levels; + template_level = Univ.hcons_univ ar.template_level } + (** {6 Constants } *) let body_of_constant cb = match cb.const_body with @@ -44,14 +66,10 @@ let subst_rel_declaration sub (id,copt,t as x) = let subst_rel_context sub = List.smartmap (subst_rel_declaration sub) -(* let subst_const_type sub arity = match arity with *) -(* | NonPolymorphicType s -> *) -(* let s' = subst_mps sub s in *) -(* if s==s' then arity else NonPolymorphicType s' *) -(* | PolymorphicArity (ctx,s) -> *) -(* let ctx' = subst_rel_context sub ctx in *) -(* if ctx==ctx' then arity else PolymorphicArity (ctx',s) *) - +let subst_template_cst_arity sub (ctx,s as arity) = + let ctx' = subst_rel_context sub ctx in + if ctx==ctx' then arity else (ctx',s) + let subst_const_type sub arity = if is_empty_subst sub then arity else subst_mps sub arity @@ -73,7 +91,7 @@ let subst_const_body sub cb = if is_empty_subst sub then cb else let body' = subst_const_def sub cb.const_body in - let type' = subst_const_type sub cb.const_type in + let type' = subst_decl_arity subst_const_type subst_template_cst_arity sub cb.const_type in let proj' = Option.smartmap (subst_const_proj sub) cb.const_proj in if body' == cb.const_body && type' == cb.const_type && proj' == cb.const_proj then cb @@ -102,7 +120,13 @@ let hcons_rel_decl ((n,oc,t) as d) = let hcons_rel_context l = List.smartmap hcons_rel_decl l -let hcons_const_type t = Term.hcons_constr t +let hcons_regular_const_arity t = Term.hcons_constr t + +let hcons_template_const_arity (ctx, ar) = + (hcons_rel_context ctx, hcons_template_arity ar) + +let hcons_const_type = + map_decl_arity hcons_regular_const_arity hcons_template_const_arity let hcons_const_def = function | Undef inl -> Undef inl @@ -164,72 +188,15 @@ let subst_wf_paths sub p = Rtree.smartmap (subst_recarg sub) p (** {7 Substitution of inductive declarations } *) -(* OLD POLYMORPHISM *) -(* let subst_indarity sub ar = match ar with *) -(* | Monomorphic s -> *) -(* let uar' = subst_mps sub s.mind_user_arity in *) -(* if uar' == s.mind_user_arity then ar *) -(* else Monomorphic { mind_user_arity = uar'; mind_sort = s.mind_sort } *) -(* | Polymorphic _ -> ar *) - -(* let subst_mind_packet sub mip = *) -(* let { mind_nf_lc = nf; *) -(* mind_user_lc = user; *) -(* mind_arity_ctxt = ctxt; *) -(* mind_arity = ar; *) -(* mind_recargs = ra } = mip *) -(* in *) -(* let nf' = Array.smartmap (subst_mps sub) nf in *) -(* let user' = *) -(* (\* maintain sharing of [mind_user_lc] and [mind_nf_lc] *\) *) -(* if user==nf then nf' *) -(* else Array.smartmap (subst_mps sub) user *) -(* in *) -(* let ctxt' = subst_rel_context sub ctxt in *) -(* let ar' = subst_indarity sub ar in *) -(* let ra' = subst_wf_paths sub ra in *) -(* if nf==nf' && user==user' && ctxt==ctxt' && ar==ar' && ra==ra' *) -(* then mip *) -(* else *) -(* { mip with *) -(* mind_nf_lc = nf'; *) -(* mind_user_lc = user'; *) -(* mind_arity_ctxt = ctxt'; *) -(* mind_arity = ar'; *) -(* mind_recargs = ra' } *) - -(* let subst_mind sub mib = *) -(* assert (List.is_empty mib.mind_hyps); (\* we're outside sections *\) *) -(* if is_empty_subst sub then mib *) -(* else *) -(* let params = mib.mind_params_ctxt in *) -(* let params' = Context.map_rel_context (subst_mps sub) params in *) -(* let packets = mib.mind_packets in *) -(* let packets' = Array.smartmap (subst_mind_packet sub) packets in *) -(* if params==params' && packets==packets' then mib *) -(* else *) -(* { mib with *) -(* mind_params_ctxt = params'; *) -(* mind_packets = packets'; *) -(* mind_native_name = ref NotLinked } *) - -(* (\** {6 Hash-consing of inductive declarations } *\) *) - -(* (\** Just as for constants, this hash-consing is quite partial *\) *) - -(* let hcons_indarity = function *) -(* | Monomorphic a -> *) -(* Monomorphic *) -(* { mind_user_arity = Term.hcons_constr a.mind_user_arity; *) -(* mind_sort = Term.hcons_sorts a.mind_sort } *) -(* | Polymorphic a -> Polymorphic (hcons_polyarity a) *) +let subst_regular_ind_arity sub s = + let uar' = subst_mps sub s.mind_user_arity in + if uar' == s.mind_user_arity then s + else { mind_user_arity = uar'; mind_sort = s.mind_sort } -(** Substitution of inductive declarations *) +let subst_template_ind_arity sub s = s -let subst_indarity sub s = - { mind_user_arity = subst_mps sub s.mind_user_arity; - mind_sort = s.mind_sort; - } +let subst_ind_arity = + subst_decl_arity subst_regular_ind_arity subst_template_ind_arity let subst_mind_packet sub mbp = { mind_consnames = mbp.mind_consnames; @@ -238,7 +205,7 @@ let subst_mind_packet sub mbp = mind_typename = mbp.mind_typename; mind_nf_lc = Array.smartmap (subst_mps sub) mbp.mind_nf_lc; mind_arity_ctxt = subst_rel_context sub mbp.mind_arity_ctxt; - mind_arity = subst_indarity sub mbp.mind_arity; + mind_arity = subst_ind_arity sub mbp.mind_arity; mind_user_lc = Array.smartmap (subst_mps sub) mbp.mind_user_lc; mind_nrealargs = mbp.mind_nrealargs; mind_nrealargs_ctxt = mbp.mind_nrealargs_ctxt; @@ -261,12 +228,19 @@ let subst_mind_body sub mib = mind_polymorphic = mib.mind_polymorphic; mind_universes = mib.mind_universes } -(** Hash-consing of inductive declarations *) +(** {6 Hash-consing of inductive declarations } *) -let hcons_indarity a = +let hcons_regular_ind_arity a = { mind_user_arity = Term.hcons_constr a.mind_user_arity; mind_sort = Term.hcons_sorts a.mind_sort } +(** Just as for constants, this hash-consing is quite partial *) + +let hcons_ind_arity = + map_decl_arity hcons_regular_ind_arity hcons_template_arity + +(** Substitution of inductive declarations *) + let hcons_mind_packet oib = let user = Array.smartmap Term.hcons_types oib.mind_user_lc in let nf = Array.smartmap Term.hcons_types oib.mind_nf_lc in @@ -275,7 +249,7 @@ let hcons_mind_packet oib = { oib with mind_typename = Names.Id.hcons oib.mind_typename; mind_arity_ctxt = hcons_rel_context oib.mind_arity_ctxt; - mind_arity = hcons_indarity oib.mind_arity; + mind_arity = hcons_ind_arity oib.mind_arity; mind_consnames = Array.smartmap Names.Id.hcons oib.mind_consnames; mind_user_lc = user; mind_nf_lc = nf } diff --git a/kernel/declareops.mli b/kernel/declareops.mli index 0c5f3584e..9f5197668 100644 --- a/kernel/declareops.mli +++ b/kernel/declareops.mli @@ -12,6 +12,11 @@ open Mod_subst (** Operations concerning types in [Declarations] : [constant_body], [mutual_inductive_body], [module_body] ... *) +(** {6 Arities} *) + +val map_decl_arity : ('a -> 'c) -> ('b -> 'd) -> + ('a, 'b) declaration_arity -> ('c, 'd) declaration_arity + (** {6 Constants} *) val subst_const_body : substitution -> constant_body -> constant_body diff --git a/kernel/environ.ml b/kernel/environ.ml index 323d6fcea..1f29fd67a 100644 --- a/kernel/environ.ml +++ b/kernel/environ.ml @@ -214,12 +214,22 @@ let universes_and_subst_of cb u = let subst = Univ.make_universe_subst u univs in subst, Univ.instantiate_univ_context subst univs +let get_regular_arity = function + | RegularArity a -> a + | TemplateArity _ -> assert false + +let map_regular_arity f = function + | RegularArity a as ar -> + let a' = f a in + if a' == a then ar else RegularArity a' + | TemplateArity _ -> assert false + (* constant_type gives the type of a constant *) let constant_type env (kn,u) = let cb = lookup_constant kn env in if cb.const_polymorphic then let subst, csts = universes_and_subst_of cb u in - (subst_univs_constr subst cb.const_type, csts) + (map_regular_arity (subst_univs_constr subst) cb.const_type, csts) else cb.const_type, Univ.Constraint.empty let constant_type_in_ctx env kn = @@ -260,7 +270,8 @@ let constant_value_and_type env (kn, u) = | Def l_body -> Some (subst_univs_constr subst (Mod_subst.force_constr l_body)) | OpaqueDef _ -> None | Undef _ -> None - in b', subst_univs_constr subst cb.const_type, cst + in + b', map_regular_arity (subst_univs_constr subst) cb.const_type, cst else let b' = match cb.const_body with | Def l_body -> Some (Mod_subst.force_constr l_body) @@ -277,7 +288,7 @@ let constant_type_in env (kn,u) = let cb = lookup_constant kn env in if cb.const_polymorphic then let subst = Univ.make_universe_subst u (Future.force cb.const_universes) in - subst_univs_constr subst cb.const_type + map_regular_arity (subst_univs_constr subst) cb.const_type else cb.const_type let constant_value_in env (kn,u) = diff --git a/kernel/environ.mli b/kernel/environ.mli index fb5d79718..330d9c277 100644 --- a/kernel/environ.mli +++ b/kernel/environ.mli @@ -140,12 +140,12 @@ type const_evaluation_result = NoBody | Opaque | IsProj exception NotEvaluableConst of const_evaluation_result val constant_value : env -> constant puniverses -> constr constrained -val constant_type : env -> constant puniverses -> types constrained -val constant_type_in_ctx : env -> constant -> types Univ.in_universe_context +val constant_type : env -> constant puniverses -> constant_type constrained +val constant_type_in_ctx : env -> constant -> constant_type Univ.in_universe_context val constant_opt_value : env -> constant puniverses -> (constr * Univ.constraints) option val constant_value_and_type : env -> constant puniverses -> - types option * constr * Univ.constraints + constr option * constant_type * Univ.constraints (** The universe context associated to the constant, empty if not polymorphic *) val constant_context : env -> constant -> Univ.universe_context @@ -154,7 +154,7 @@ val constant_context : env -> constant -> Univ.universe_context already contains the constraints corresponding to the constant application. *) val constant_value_in : env -> constant puniverses -> constr -val constant_type_in : env -> constant puniverses -> types +val constant_type_in : env -> constant puniverses -> constant_type val constant_opt_value_in : env -> constant puniverses -> constr option diff --git a/kernel/fast_typeops.ml b/kernel/fast_typeops.ml index b441e02a3..8b7230c3b 100644 --- a/kernel/fast_typeops.ml +++ b/kernel/fast_typeops.ml @@ -109,17 +109,40 @@ let check_hyps_inclusion env f c sign = (* Type of constants *) -let type_of_constant env cst = constant_type env cst -let type_of_constant_in env cst = constant_type_in env cst -let type_of_constant_knowing_parameters env t _ = t -let judge_of_constant env (kn,u as cst) = +let type_of_constant_knowing_parameters_arity env t paramtyps = + match t with + | RegularArity t -> t + | TemplateArity (sign,ar) -> + let ctx = List.rev sign in + let ctx,s = instantiate_universes env ctx ar paramtyps in + mkArity (List.rev ctx,s) + +let type_of_constant_knowing_parameters env cst paramtyps = + let ty, cu = constant_type env cst in + type_of_constant_knowing_parameters_arity env ty paramtyps, cu + +let type_of_constant_type env t = + type_of_constant_knowing_parameters_arity env t [||] + +let type_of_constant env cst = + type_of_constant_knowing_parameters env cst [||] + +let type_of_constant_in env cst = + let ar = constant_type_in env cst in + type_of_constant_knowing_parameters_arity env ar [||] + +let judge_of_constant_knowing_parameters env (kn,u as cst) jl = let cb = lookup_constant kn env in let () = check_hyps_inclusion env mkConstU cst cb.const_hyps in - let ty, cu = type_of_constant env cst in + let paramstyp = Array.map (fun j -> lazy j.uj_type) jl in + let ty, cu = type_of_constant_knowing_parameters env cst paramstyp in let () = check_constraints cu env in ty +let judge_of_constant env cst = + judge_of_constant_knowing_parameters env cst [||] + let type_of_projection env (cst,u) = let cb = lookup_constant cst env in match cb.const_proj with diff --git a/kernel/indtypes.ml b/kernel/indtypes.ml index 0ac6a4e4a..e89bbf0d9 100644 --- a/kernel/indtypes.ml +++ b/kernel/indtypes.ml @@ -300,7 +300,7 @@ let typecheck_inductive env ctx mie = Universe.pr defu ++ Pp.str " declared for inductive type, inferred level is " ++ Universe.pr infu) in - (id,cn,lc,(sign,(not is_natural,full_arity,defu)))) + (id,cn,lc,(sign,RegularArity (not is_natural,full_arity,defu)))) inds in (env_arities, params, inds) @@ -615,9 +615,13 @@ let allowed_sorts is_smashed s = (* - all_sorts in case of small, unitary Prop (not smashed) *) (* - logical_sorts in case of large, unitary Prop (smashed) *) +let arity_conclusion = function + | RegularArity (_, c, _) -> c + | TemplateArity s -> mkType s.template_level + let fold_inductive_blocks f = Array.fold_left (fun acc (_,_,lc,(arsign,ar)) -> - f (Array.fold_left f acc lc) (it_mkProd_or_LetIn (pi2 ar) arsign)) + f (Array.fold_left f acc lc) (it_mkProd_or_LetIn (arity_conclusion ar) arsign)) let used_section_variables env inds = let ids = fold_inductive_blocks @@ -675,12 +679,14 @@ let build_inductive env p ctx env_ar params kn isrecord isfinite inds nmr recarg splayed_lc in (* Elimination sorts *) let arkind,kelim = - let (info,ar,defs) = ar_kind in - let s = sort_of_univ defs in - let kelim = allowed_sorts info s in - { mind_user_arity = ar; - mind_sort = s; - }, kelim in + match ar_kind with + | TemplateArity ar -> TemplateArity ar, all_sorts + | RegularArity (info,ar,defs) -> + let s = sort_of_univ defs in + let kelim = allowed_sorts info s in + let ar = RegularArity + { mind_user_arity = ar; mind_sort = s; } in + ar, kelim in (* Assigning VM tags to constructors *) let nconst, nblock = ref 0, ref 0 in let transf num = diff --git a/kernel/inductive.ml b/kernel/inductive.ml index e57b0b4ad..9862ffd3e 100644 --- a/kernel/inductive.ml +++ b/kernel/inductive.ml @@ -152,30 +152,93 @@ let sort_as_univ = function | Prop Null -> Universe.type0m | Prop Pos -> Universe.type0 +(* Template polymorphism *) + let cons_subst u su subst = try (u, Universe.sup su (List.assoc_f Universe.eq u subst)) :: List.remove_assoc_f Universe.eq u subst with Not_found -> (u, su) :: subst +let actualize_decl_level env lev t = + let sign,s = dest_arity env t in + mkArity (sign,lev) + +(* Bind expected levels of parameters to actual levels *) +(* Propagate the new levels in the signature *) +let rec make_subst env = function + | (_,Some _,_ as t)::sign, exp, args -> + let ctx,subst = make_subst env (sign, exp, args) in + t::ctx, subst + | d::sign, None::exp, args -> + let args = match args with _::args -> args | [] -> [] in + let ctx,subst = make_subst env (sign, exp, args) in + d::ctx, subst + | d::sign, Some u::exp, a::args -> + (* We recover the level of the argument, but we don't change the *) + (* level in the corresponding type in the arity; this level in the *) + (* arity is a global level which, at typing time, will be enforce *) + (* to be greater than the level of the argument; this is probably *) + (* a useless extra constraint *) + let s = sort_as_univ (snd (dest_arity env (Lazy.force a))) in + let ctx,subst = make_subst env (sign, exp, args) in + d::ctx, cons_subst u s subst + | (na,None,t as d)::sign, Some u::exp, [] -> + (* No more argument here: we instantiate the type with a fresh level *) + (* which is first propagated to the corresponding premise in the arity *) + (* (actualize_decl_level), then to the conclusion of the arity (via *) + (* the substitution) *) + let ctx,subst = make_subst env (sign, exp, []) in + d::ctx, subst + | sign, [], _ -> + (* Uniform parameters are exhausted *) + sign,[] + | [], _, _ -> + assert false + exception SingletonInductiveBecomesProp of Id.t +let instantiate_universes env ctx ar argsorts = + let args = Array.to_list argsorts in + let ctx,subst = make_subst env (ctx,ar.template_param_levels,args) in + let level = subst_large_constraints subst ar.template_level in + let ty = + (* Singleton type not containing types are interpretable in Prop *) + if is_type0m_univ level then prop_sort + (* Non singleton type not containing types are interpretable in Set *) + else if is_type0_univ level then set_sort + (* This is a Type with constraints *) + else Type level + in + (ctx, ty) + (* Type of an inductive type *) -let type_of_inductive_gen env ((mib,mip),u) = - let subst = make_inductive_subst mib u in - (subst_univs_constr subst mip.mind_arity.mind_user_arity, subst) +let type_of_inductive_gen ?(polyprop=true) env ((mib,mip),u) paramtyps = + match mip.mind_arity with + | RegularArity a -> + let subst = make_inductive_subst mib u in + (subst_univs_constr subst a.mind_user_arity, subst) + | TemplateArity ar -> + let ctx = List.rev mip.mind_arity_ctxt in + let ctx,s = instantiate_universes env ctx ar paramtyps in + (* The Ocaml extraction cannot handle (yet?) "Prop-polymorphism", i.e. + the situation where a non-Prop singleton inductive becomes Prop + when applied to Prop params *) + if not polyprop && not (is_type0m_univ ar.template_level) && is_prop_sort s + then raise (SingletonInductiveBecomesProp mip.mind_typename); + mkArity (List.rev ctx,s), Univ.LMap.empty let type_of_inductive env pind = - fst (type_of_inductive_gen env pind) + fst (type_of_inductive_gen env pind [||]) let constrained_type_of_inductive env ((mib,mip),u as pind) = - let ty, subst = type_of_inductive_gen env pind in + let ty, subst = type_of_inductive_gen env pind [||] in let cst = instantiate_inductive_constraints mib subst in (ty, cst) let type_of_inductive_knowing_parameters env ?(polyprop=false) mip args = - type_of_inductive env mip + fst (type_of_inductive_gen env mip args) (* The max of an array of universes *) @@ -248,7 +311,9 @@ let local_rels ctxt = (* Get type of inductive, with parameters instantiated *) let inductive_sort_family mip = - family_of_sort mip.mind_arity.mind_sort + match mip.mind_arity with + | RegularArity s -> family_of_sort s.mind_sort + | TemplateArity _ -> InType let mind_arity mip = mip.mind_arity_ctxt, inductive_sort_family mip diff --git a/kernel/inductive.mli b/kernel/inductive.mli index c4a7452f0..a403003e2 100644 --- a/kernel/inductive.mli +++ b/kernel/inductive.mli @@ -109,6 +109,9 @@ exception SingletonInductiveBecomesProp of Id.t val max_inductive_sort : sorts array -> universe +val instantiate_universes : env -> rel_context -> + template_arity -> constr Lazy.t array -> rel_context * sorts + (** {6 Debug} *) type size = Large | Strict diff --git a/kernel/subtyping.ml b/kernel/subtyping.ml index 2c093939a..56e94ba0d 100644 --- a/kernel/subtyping.ml +++ b/kernel/subtyping.ml @@ -277,8 +277,8 @@ let check_constant cst env mp1 l info1 cb2 spec2 subst1 subst2 = let cb1 = Declareops.subst_const_body subst1 cb1 in let cb2 = Declareops.subst_const_body subst2 cb2 in (* Start by checking types*) - let typ1 = cb1.const_type in - let typ2 = cb2.const_type in + let typ1 = Typeops.type_of_constant_type env cb1.const_type in + let typ2 = Typeops.type_of_constant_type env cb2.const_type in let cst = check_type cst env typ1 typ2 in (* Now we check the bodies: - A transparent constant can only be implemented by a compatible @@ -309,7 +309,7 @@ let check_constant cst env mp1 l info1 cb2 spec2 subst1 subst2 = let arity1,cst1 = constrained_type_of_inductive env ((mind1,mind1.mind_packets.(i)),u1) in let cst2 = UContext.constraints (Future.force cb2.const_universes) in - let typ2 = cb2.const_type in + let typ2 = Typeops.type_of_constant_type env cb2.const_type in let cst = Constraint.union cst (Constraint.union cst1 cst2) in let error = NotConvertibleTypeField (env, arity1, typ2) in check_conv error cst infer_conv_leq env arity1 typ2 @@ -324,7 +324,7 @@ let check_constant cst env mp1 l info1 cb2 spec2 subst1 subst2 = let u1 = inductive_instance mind1 in let ty1,cst1 = constrained_type_of_constructor (cstr,u1) (mind1,mind1.mind_packets.(i)) in let cst2 = UContext.constraints (Future.force cb2.const_universes) in - let ty2 = cb2.const_type in + let ty2 = Typeops.type_of_constant_type env cb2.const_type in let cst = Constraint.union cst (Constraint.union cst1 cst2) in let error = NotConvertibleTypeField (env, ty1, ty2) in check_conv error cst infer_conv env ty1 ty2 diff --git a/kernel/term_typing.ml b/kernel/term_typing.ml index a7f2125a7..c655e2f33 100644 --- a/kernel/term_typing.ml +++ b/kernel/term_typing.ml @@ -29,17 +29,20 @@ let prerr_endline = if debug then prerr_endline else fun _ -> () let constrain_type env j poly = function - | `None -> j.uj_type + | `None -> + if not poly then (* Old-style polymorphism *) + make_polymorphic_if_constant_for_ind env j + else RegularArity j.uj_type | `Some t -> let tj = infer_type env t in let _ = judge_of_cast env j DEFAULTcast tj in assert (eq_constr t tj.utj_val); - t + RegularArity t | `SomeWJ (t, tj) -> let tj = infer_type env t in let _ = judge_of_cast env j DEFAULTcast tj in assert (eq_constr t tj.utj_val); - t + RegularArity t let map_option_typ = function None -> `None | Some x -> `Some x @@ -72,12 +75,12 @@ let handle_side_effects env body side_eff = | Undef _ -> assert false | Def b -> let b = Mod_subst.force_constr b in - let b_ty = cb.const_type in + let b_ty = Typeops.type_of_constant_type env cb.const_type in let t = sub c 1 (Vars.lift 1 t) in mkLetIn (cname c, b, b_ty, t) | OpaqueDef b -> let b = Opaqueproof.force_proof b in - let b_ty = cb.const_type in + let b_ty = Typeops.type_of_constant_type env cb.const_type in let t = sub c 1 (Vars.lift 1 t) in mkApp (mkLambda (cname c, b_ty, t), [|b|]) in List.fold_right fix_body cbl t @@ -98,7 +101,7 @@ let infer_declaration env kn dcl = let env = push_context uctx env in let j = infer env t in let t = hcons_constr (Typeops.assumption_of_judgment env j) in - Undef nl, t, None, poly, Future.from_val uctx, false, ctx + Undef nl, RegularArity t, None, poly, Future.from_val uctx, false, ctx | DefinitionEntry ({ const_entry_type = Some typ; const_entry_opaque = true } as c) -> let env = push_context (Future.join c.const_entry_universes) env in (* FIXME *) @@ -113,7 +116,7 @@ let infer_declaration env kn dcl = feedback_completion_typecheck feedback_id; j.uj_val, Univ.empty_constraint) in let def = OpaqueDef (Opaqueproof.create proofterm) in - def, typ, None, c.const_entry_polymorphic, c.const_entry_universes, + def, RegularArity typ, None, c.const_entry_polymorphic, c.const_entry_universes, c.const_entry_inline_code, c.const_entry_secctx | DefinitionEntry c -> let env = push_context (Future.join c.const_entry_universes) env in (* FIXME *) @@ -129,13 +132,13 @@ let infer_declaration env kn dcl = def, typ, None, c.const_entry_polymorphic, c.const_entry_universes, c.const_entry_inline_code, c.const_entry_secctx -(* let global_vars_set_constant_type env = function *) -(* | NonPolymorphicType t -> global_vars_set env t *) -(* | PolymorphicArity (ctx,_) -> *) -(* Context.fold_rel_context *) -(* (fold_rel_declaration *) -(* (fun t c -> Id.Set.union (global_vars_set env t) c)) *) -(* ctx ~init:Id.Set.empty *) +let global_vars_set_constant_type env = function + | RegularArity t -> global_vars_set env t + | TemplateArity (ctx,_) -> + Context.fold_rel_context + (fold_rel_declaration + (fun t c -> Id.Set.union (global_vars_set env t) c)) + ctx ~init:Id.Set.empty let record_aux env s1 s2 = let v = @@ -162,7 +165,7 @@ let build_constant_declaration kn env (def,typ,proj,poly,univs,inline_code,ctx) | None when not (List.is_empty context_ids) -> (* No declared section vars, and non-empty section context: we must look at the body NOW, if any *) - let ids_typ = global_vars_set env typ in + let ids_typ = global_vars_set_constant_type env typ in let ids_def = match def with | Undef _ -> Idset.empty | Def cs -> global_vars_set env (Mod_subst.force_constr cs) @@ -186,14 +189,14 @@ let build_constant_declaration kn env (def,typ,proj,poly,univs,inline_code,ctx) match def with | Undef _ as x -> x (* nothing to check *) | Def cs as x -> - let ids_typ = global_vars_set env typ in + let ids_typ = global_vars_set_constant_type env typ in let ids_def = global_vars_set env (Mod_subst.force_constr cs) in let inferred = keep_hyps env (Idset.union ids_typ ids_def) in check declared inferred; x | OpaqueDef lc -> (* In this case we can postpone the check *) OpaqueDef (Opaqueproof.iter_direct_opaque (fun c -> - let ids_typ = global_vars_set env typ in + let ids_typ = global_vars_set_constant_type env typ in let ids_def = global_vars_set env c in let inferred = keep_hyps env (Idset.union ids_typ ids_def) in check declared inferred) lc) in @@ -229,6 +232,7 @@ let translate_recipe env kn r = let translate_local_def env id centry = let def,typ,proj,poly,univs,inline_code,ctx = infer_declaration env None (DefinitionEntry centry) in + let typ = type_of_constant_type env typ in def, typ, univs (* Insertion of inductive types. *) diff --git a/kernel/typeops.ml b/kernel/typeops.ml index 09fd4cc7f..09e2fb1d5 100644 --- a/kernel/typeops.ml +++ b/kernel/typeops.ml @@ -113,20 +113,62 @@ let check_hyps_inclusion env c sign = (* Make a type polymorphic if an arity *) +let extract_level env p = + let _,c = dest_prod_assum env p in + match kind_of_term c with Sort (Type u) -> Some u | _ -> None + +let extract_context_levels env l = + let fold l (_, b, p) = match b with + | None -> extract_level env p :: l + | _ -> l + in + List.fold_left fold [] l + +let make_polymorphic_if_constant_for_ind env {uj_val = c; uj_type = t} = + let params, ccl = dest_prod_assum env t in + match kind_of_term ccl with + | Sort (Type u) when isInd (fst (decompose_app (whd_betadeltaiota env c))) -> + let param_ccls = extract_context_levels env params in + let s = { template_param_levels = param_ccls; template_level = u} in + TemplateArity (params,s) + | _ -> + RegularArity t + (* Type of constants *) -let type_of_constant env cst = constant_type env cst -let type_of_constant_in env cst = constant_type_in env cst -let type_of_constant_knowing_parameters env t _ = t -let type_of_constant_type env cst = cst +let type_of_constant_type_knowing_parameters env t paramtyps = + match t with + | RegularArity t -> t + | TemplateArity (sign,ar) -> + let ctx = List.rev sign in + let ctx,s = instantiate_universes env ctx ar paramtyps in + mkArity (List.rev ctx,s) + +let type_of_constant_knowing_parameters env cst paramtyps = + let ty, cu = constant_type env cst in + type_of_constant_type_knowing_parameters env ty paramtyps, cu + +let type_of_constant_type env t = + type_of_constant_type_knowing_parameters env t [||] -let judge_of_constant env (kn,u as cst) = +let type_of_constant env cst = + type_of_constant_knowing_parameters env cst [||] + +let type_of_constant_in env cst = + let ar = constant_type_in env cst in + type_of_constant_type_knowing_parameters env ar [||] + +let judge_of_constant_knowing_parameters env (kn,u as cst) jl = let c = mkConstU cst in let cb = lookup_constant kn env in let _ = check_hyps_inclusion env c cb.const_hyps in - let ty, cu = type_of_constant env cst in + let paramstyp = Array.map (fun j -> lazy j.uj_type) jl in + let ty, cu = type_of_constant_knowing_parameters env cst paramstyp in let _ = Environ.check_constraints cu env in - (make_judge c ty) + make_judge c ty + +let judge_of_constant env cst = + judge_of_constant_knowing_parameters env cst [||] let type_of_projection env (cst,u) = let cb = lookup_constant cst env in diff --git a/kernel/typeops.mli b/kernel/typeops.mli index 6bc1ce496..9747dbe83 100644 --- a/kernel/typeops.mli +++ b/kernel/typeops.mli @@ -51,10 +51,13 @@ val judge_of_relative : env -> int -> unsafe_judgment val judge_of_variable : env -> variable -> unsafe_judgment (** {6 type of a constant } *) -val judge_of_constant : env -> constant puniverses -> unsafe_judgment -(* val judge_of_constant_knowing_parameters : *) -(* env -> constant -> unsafe_judgment array -> unsafe_judgment *) +val judge_of_constant : env -> pconstant -> unsafe_judgment + +val judge_of_constant_knowing_parameters : + env -> pconstant -> unsafe_judgment array -> unsafe_judgment + +(** {6 type of an applied projection } *) val judge_of_projection : env -> Names.projection -> unsafe_judgment -> unsafe_judgment @@ -103,15 +106,20 @@ val judge_of_case : env -> case_info val type_fixpoint : env -> Name.t array -> types array -> unsafe_judgment array -> unit -val type_of_constant : env -> constant puniverses -> types constrained +val type_of_constant : env -> pconstant -> types constrained val type_of_constant_type : env -> constant_type -> types val type_of_projection : env -> Names.projection puniverses -> types -val type_of_constant_in : env -> constant puniverses -> types +val type_of_constant_in : env -> pconstant -> types -val type_of_constant_knowing_parameters : +val type_of_constant_type_knowing_parameters : env -> constant_type -> types Lazy.t array -> types +val type_of_constant_knowing_parameters : + env -> pconstant -> types Lazy.t array -> types constrained +(** Make a type polymorphic if an arity *) +val make_polymorphic_if_constant_for_ind : env -> unsafe_judgment -> + constant_type |