diff options
-rw-r--r-- | kernel/indtypes.ml | 61 | ||||
-rw-r--r-- | kernel/indtypes.mli | 11 | ||||
-rw-r--r-- | kernel/reduction.ml | 4 | ||||
-rw-r--r-- | library/declare.ml | 6 | ||||
-rw-r--r-- | pretyping/evarconv.ml | 6 | ||||
-rw-r--r-- | pretyping/inductiveops.ml | 41 | ||||
-rw-r--r-- | pretyping/inductiveops.mli | 4 | ||||
-rw-r--r-- | test-suite/success/polymorphism.v | 20 | ||||
-rw-r--r-- | vernac/command.ml | 2 | ||||
-rw-r--r-- | vernac/record.ml | 6 |
10 files changed, 106 insertions, 55 deletions
diff --git a/kernel/indtypes.ml b/kernel/indtypes.ml index 15fe90835..a4c7a0573 100644 --- a/kernel/indtypes.ml +++ b/kernel/indtypes.ml @@ -215,20 +215,42 @@ let check_subtyping_arity_constructor env (subst : constr -> constr) (arcn : Ter numchecked := !numchecked + 1 in let check_typ typ typ_env = - match typ with - | LocalAssum (_, typ') -> - begin - try - basic_check env typ'; Environ.push_rel typ typ_env - with NotConvertible -> - anomaly ~label:"bad inductive subtyping relation" (Pp.str "Invalid subtyping relation") - end - | _ -> anomaly (Pp.str "") + match typ with + | LocalAssum (_, typ') -> + begin + try + basic_check typ_env typ'; Environ.push_rel typ typ_env + with NotConvertible -> + anomaly ~label:"bad inductive subtyping relation" (Pp.str "Invalid subtyping relation") + end + | _ -> anomaly (Pp.str "") in let typs, codom = dest_prod env arcn in let last_env = Context.Rel.fold_outside check_typ typs ~init:env in if not is_arity then basic_check last_env codom else () +(* Check that the subtyping information inferred for inductive types in the block is correct. *) +(* This check produces a value of the unit type if successful or raises an anomaly if check fails. *) +let check_subtyping mie paramsctxt env_ar inds = + let numparams = Context.Rel.nhyps paramsctxt in + let sbsubst = UInfoInd.subtyping_susbst mie.mind_entry_universes in + let dosubst = subst_univs_level_constr sbsubst in + let uctx = UInfoInd.univ_context mie.mind_entry_universes in + let instance_other = Univ.subst_univs_level_instance sbsubst (Univ.UContext.instance uctx) in + let constraints_other = Univ.subst_univs_level_constraints sbsubst (Univ.UContext.constraints uctx) in + let uctx_other = Univ.UContext.make (instance_other, constraints_other) in + let env' = Environ.push_context uctx env_ar in + let env'' = Environ.push_context uctx_other env' in + let envsb = push_context (UInfoInd.subtyp_context mie.mind_entry_universes) env'' in + (* process individual inductive types: *) + Array.iter (fun (id,cn,lc,(sign,arity)) -> + match arity with + | RegularArity (_, full_arity, _) -> + check_subtyping_arity_constructor envsb dosubst full_arity numparams true; + Array.iter (fun cnt -> check_subtyping_arity_constructor envsb dosubst cnt numparams false) lc + | TemplateArity _ -> () + ) inds + (* Type-check an inductive definition. Does not check positivity conditions. *) (* TODO check that we don't overgeneralize construcors/inductive arities with @@ -370,26 +392,7 @@ let typecheck_inductive env mie = in (* Check that the subtyping information inferred for inductive types in the block is correct. *) (* This check produces a value of the unit type if successful or raises an anomaly if check fails. *) - let () = - let numparams = List.length paramsctxt in - let sbsubst = UInfoInd.subtyping_susbst mie.mind_entry_universes in - let dosubst = subst_univs_level_constr sbsubst in - let uctx = UInfoInd.univ_context mie.mind_entry_universes in - let instance_other = Univ.subst_univs_level_instance sbsubst (Univ.UContext.instance uctx) in - let constraints_other = Univ.subst_univs_level_constraints sbsubst (Univ.UContext.constraints uctx) in - let uctx_other = Univ.UContext.make (instance_other, constraints_other) in - let env' = Environ.push_context uctx env_ar_par in - let env'' = Environ.push_context uctx_other env' in - let envsb = push_context (UInfoInd.subtyp_context mie.mind_entry_universes) env'' in - (* process individual inductive types: *) - Array.iter (fun (id,cn,lc,(sign,arity)) -> - match arity with - | RegularArity (_, full_arity, _) -> - check_subtyping_arity_constructor envsb dosubst full_arity numparams true; - Array.iter (fun cnt -> check_subtyping_arity_constructor envsb dosubst cnt numparams false) lc - | TemplateArity _ -> () - (* TODO: When disabling template polumorphism raise anomaly if this constructor is not removed from the code base *) - ) inds + let () = check_subtyping mie paramsctxt env_arities inds in (env_arities, env_ar_par, paramsctxt, inds) (************************************************************************) diff --git a/kernel/indtypes.mli b/kernel/indtypes.mli index 5b4615399..7b0f01794 100644 --- a/kernel/indtypes.mli +++ b/kernel/indtypes.mli @@ -32,6 +32,17 @@ type inductive_error = exception InductiveError of inductive_error +val check_subtyping_arity_constructor : Environ.env -> +(Term.constr -> Term.constr) -> Term.types -> int -> bool -> unit + +(* This needs not be exposed. Exposing for debugging purposes! *) +val check_subtyping : Entries.mutual_inductive_entry -> +Context.Rel.t -> +Environ.env -> +('b * 'c * Term.types array * + ('d * ('e * Term.types * 'f, 'g) Declarations.declaration_arity)) +array -> unit + (** The following function does checks on inductive declarations. *) val check_inductive : env -> mutual_inductive -> mutual_inductive_entry -> mutual_inductive_body diff --git a/kernel/reduction.ml b/kernel/reduction.ml index a872a103a..33dd53a5b 100644 --- a/kernel/reduction.ml +++ b/kernel/reduction.ml @@ -500,7 +500,7 @@ and eqappr env cv_pb l2r infos (lft1,st1) (lft2,st2) cuniv = if mind.Declarations.mind_polymorphic then begin let num_param_arity = - Context.Rel.length (mind.Declarations.mind_packets.(snd ind1).Declarations.mind_arity_ctxt) + mind.Declarations.mind_nparams + mind.Declarations.mind_packets.(snd ind1).Declarations.mind_nrealargs in if not (num_param_arity = CClosure.stack_args_size v1 && num_param_arity = CClosure.stack_args_size v2) then fall_back () @@ -535,7 +535,7 @@ and eqappr env cv_pb l2r infos (lft1,st1) (lft2,st2) cuniv = if not (num_cnstr_args = CClosure.stack_args_size v1 && num_cnstr_args = CClosure.stack_args_size v2) then fall_back () else - begin (* we don't consider subtyping for constructors. *) + begin (* we consider subtyping for constructors. *) let uinfind = mind.Declarations.mind_universes in let cuniv = compare_leq_inductives ~flex:false uinfind u1 u2 cuniv in let cuniv = compare_leq_inductives ~flex:false uinfind u2 u1 cuniv in diff --git a/library/declare.ml b/library/declare.ml index fcaadaa6e..bf5313545 100644 --- a/library/declare.ml +++ b/library/declare.ml @@ -364,9 +364,9 @@ let infer_inductive_subtyping (pth, mind_ent) = let env' = Environ.push_context (Univ.UInfoInd.univ_context mind_ent.mind_entry_universes) env in - let (env'', typed_params) = Typeops.infer_local_decls env' (mind_ent.mind_entry_params) in - let evd = Evd.from_env env'' in - (pth, Inductiveops.infer_inductive_subtyping env'' evd mind_ent) + (* let (env'', typed_params) = Typeops.infer_local_decls env' (mind_ent.mind_entry_params) in *) + let evd = Evd.from_env env' in + (pth, Inductiveops.infer_inductive_subtyping env' evd mind_ent) end else (pth, mind_ent) diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml index eb8a0c85a..ea22c3708 100644 --- a/pretyping/evarconv.ml +++ b/pretyping/evarconv.ml @@ -494,7 +494,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty if mind.Declarations.mind_polymorphic then begin let num_param_arity = - Context.Rel.length (mind.Declarations.mind_packets.(snd ind).Declarations.mind_arity_ctxt) + mind.Declarations.mind_nparams + mind.Declarations.mind_packets.(snd ind).Declarations.mind_nrealargs in if not (num_param_arity = nparamsaplied && num_param_arity = nparamsaplied') then UnifFailure (evd, NotSameHead) @@ -520,7 +520,9 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty if mind.Declarations.mind_polymorphic then begin let num_cnstr_args = - let nparamsctxt = Context.Rel.length mind.Declarations.mind_params_ctxt in + let nparamsctxt = + mind.Declarations.mind_nparams + mind.Declarations.mind_packets.(snd ind).Declarations.mind_nrealargs + in nparamsctxt + mind.Declarations.mind_packets.(snd ind).Declarations.mind_consnrealargs.(j - 1) in if not (num_cnstr_args = nparamsaplied && num_cnstr_args = nparamsaplied') then diff --git a/pretyping/inductiveops.ml b/pretyping/inductiveops.ml index 1f8600dc2..ebfb1f8a7 100644 --- a/pretyping/inductiveops.ml +++ b/pretyping/inductiveops.ml @@ -659,14 +659,22 @@ let control_only_guard env c = (* inference of subtyping condition for inductive types *) let infer_inductive_subtyping_arity_constructor - (env, evd, csts) (subst : constr -> constr) (arcn : Term.types) is_arity = + (env, evd, csts) (subst : constr -> constr) (arcn : Term.types) is_arity (params : Context.Rel.t) = + let numchecked = ref 0 in + let numparams = Context.Rel.nhyps params in let update_contexts (env, evd, csts) csts' = (Environ.add_constraints csts' env, Evd.add_constraints evd csts', Univ.Constraint.union csts csts') in let basic_check (env, evd, csts) tp = - let csts' = - Reduction.infer_conv_leq ~evars:(Evd.existential_opt_value evd) env (Evd.universes evd) tp (subst tp) - in update_contexts (env, evd, csts) csts' + let result = + if !numchecked >= numparams then + let csts' = + Reduction.infer_conv_leq ~evars:(Evd.existential_opt_value evd) env (Evd.universes evd) tp (subst tp) + in update_contexts (env, evd, csts) csts' + else + (env, evd, csts) + in + numchecked := !numchecked + 1; result in let infer_typ typ ctxs = match typ with @@ -680,12 +688,14 @@ let infer_inductive_subtyping_arity_constructor end | _ -> anomaly (Pp.str "") in - let typs, codom = Reduction.dest_prod env arcn in + let arcn' = Term.it_mkProd_or_LetIn arcn params in + let typs, codom = Reduction.dest_prod env arcn' in let last_contexts = Context.Rel.fold_outside infer_typ typs ~init:(env, evd, csts) in if not is_arity then basic_check last_contexts codom else last_contexts let infer_inductive_subtyping env evd mind_ent = - let { Entries.mind_entry_inds = entries; + let { Entries.mind_entry_params = params; + Entries.mind_entry_inds = entries; Entries.mind_entry_polymorphic = poly; Entries.mind_entry_universes = ground_uinfind; } = mind_ent @@ -704,15 +714,16 @@ let infer_inductive_subtyping env evd mind_ent = let evd' = Evd.merge_universe_context evd (UState.of_context_set (Univ.ContextSet.of_context uctx_other)) in let (_, _, subtyp_constraints) = List.fold_left - (fun ctxs indentry -> - let ctxs' = infer_inductive_subtyping_arity_constructor - ctxs dosubst indentry.Entries.mind_entry_arity true - in - List.fold_left - (fun ctxs cons -> - infer_inductive_subtyping_arity_constructor ctxs dosubst cons false) - ctxs' indentry.Entries.mind_entry_lc - ) (env', evd', Univ.Constraint.empty) entries + (fun ctxs indentry -> + let _, params = Typeops.infer_local_decls env params in + let ctxs' = infer_inductive_subtyping_arity_constructor + ctxs dosubst indentry.Entries.mind_entry_arity true params + in + List.fold_left + (fun ctxs cons -> + infer_inductive_subtyping_arity_constructor ctxs dosubst cons false params) + ctxs' indentry.Entries.mind_entry_lc + ) (env', evd', Univ.Constraint.empty) entries in Univ.UInfoInd.make (Univ.UInfoInd.univ_context ground_uinfind, Univ.UContext.make (Univ.UContext.instance (Univ.UInfoInd.subtyp_context ground_uinfind), diff --git a/pretyping/inductiveops.mli b/pretyping/inductiveops.mli index 7d89b1b2b..811f47f39 100644 --- a/pretyping/inductiveops.mli +++ b/pretyping/inductiveops.mli @@ -201,6 +201,10 @@ val type_of_inductive_knowing_conclusion : val control_only_guard : env -> types -> unit (* inference of subtyping condition for inductive types *) +(* for debugging purposes only to be removed *) +val infer_inductive_subtyping_arity_constructor : Environ.env * Evd.evar_map * Univ.Constraint.t -> +(Term.constr -> Term.constr) -> +Term.types -> bool -> Context.Rel.t -> Environ.env * Evd.evar_map * Univ.Constraint.t val infer_inductive_subtyping : Environ.env -> Evd.evar_map -> Entries.mutual_inductive_entry -> Entries.mutual_inductive_entry diff --git a/test-suite/success/polymorphism.v b/test-suite/success/polymorphism.v index 66ff55edc..3e90825ab 100644 --- a/test-suite/success/polymorphism.v +++ b/test-suite/success/polymorphism.v @@ -316,6 +316,26 @@ Module Hurkens'. Polymorphic Record box (X : Type) (T := Type) : Type := wrap { unwrap : T }. +Section test_letin_subtyping. + Universe i j k i' j' k'. + Constraint j < j'. + + Context (W : Type) (X : box@{i j k} W). + Definition Y := X : box@{i' j' k'} W. + + Universe i1 j1 k1 i2 j2 k2. + Constraint i1 < i2, k2 < k1. + Definition Z : box@{i1 j1 k1} W := {| unwrap := W |}. + Definition Z' : box@{i2 j2 k2} W := {| unwrap := W |}. + Lemma ZZ' : @eq (box@{i2 j2 k2} W) Z Z'. + Proof. + Set Printing All. Set Printing Universes. + cbv. + reflexivity. + Qed. + +End test_letin_subtyping. + Definition unwrap' := fun (X : Type) (b : box X) => let (unw) := b in unw. Fail Definition bad : False := TypeNeqSmallType.paradox (unwrap' Type (wrap _ diff --git a/vernac/command.ml b/vernac/command.ml index 116a7aee1..6c5997623 100644 --- a/vernac/command.ml +++ b/vernac/command.ml @@ -662,7 +662,7 @@ let interp_mutual_inductive (paramsl,indl) notations poly prv finite = } in (if poly then - Inductiveops.infer_inductive_subtyping env_ar_params evd mind_ent + Inductiveops.infer_inductive_subtyping env_ar evd mind_ent else mind_ent), pl, impls (* Very syntactical equality *) diff --git a/vernac/record.ml b/vernac/record.ml index 84312594d..093a31c19 100644 --- a/vernac/record.ml +++ b/vernac/record.ml @@ -410,9 +410,9 @@ let declare_structure finite poly ctx id idbuild paramimpls params arity templat begin let env = Global.env () in let env' = Environ.push_context (Univ.UInfoInd.univ_context ctx) env in - let env'' = Environ.push_rel_context params env' in - let evd = Evd.from_env env'' in - Inductiveops.infer_inductive_subtyping env'' evd mie + (* let env'' = Environ.push_rel_context params env' in *) + let evd = Evd.from_env env' in + Inductiveops.infer_inductive_subtyping env' evd mie end else mie |