feat: drop the universe bump from PSigma, PProd and PULift - #14893
feat: drop the universe bump from PSigma, PProd and PULift#14893nomeata wants to merge 5 commits into
PSigma, PProd and PULift#14893Conversation
This PR gives `PSigma` and `PProd` the resulting universe `Sort (max u v)` instead of `Sort (max 1 u v)`, so a pair of propositions is itself a proposition. Their recursors are correspondingly restricted to motives in `Prop`, while `casesOn` and `recOn` stay universe-polymorphic. The `structure` command now accepts such a resulting universe, subject to `bootstrap.inductiveCheckResultingUniverse` as `inductive` already was. The kernel restricts the recursor of a single-constructor type whose resulting universe can be `Prop`. Projections stay available, since the field-universe check forces every field of such a type to be a proof whenever the type is one, so `Lean.mkCasesOnViaProjs?` builds `casesOn` and `recOn` from `Expr.proj` plus eta for structures. Everything derived from `casesOn` is unaffected; `SizeOf` used the recursor directly and gets a projection-based path of its own, and the guards that read "can eliminate into `Type`" off `.rec`'s level parameters now read it off `.casesOn`. The bump no longer leaks into the universe levels of `below`. `Lean.Meta.PProdN` still packs propositions with `And` rather than `PProd`, but that is now only for readability rather than to stay in `Prop`. A tuple of proofs is now a proof, so it gets abstracted into an auxiliary theorem and a packed well-founded recursion argument is no longer a manifest chain of `PSigma.mk`. `ArgsPacker.Unary.unpack` therefore falls back to projections, which are always valid here, and `FunInd.cleanPackedArgs` reduces `PSigma.casesOn` applied to a proof. `MatcherApp.transform` gained `addProofEqualities` so that functional induction keeps substituting a proof-valued discriminant away instead of leaving a dead binder in the principle; only homogeneous equations are added, since a heterogeneous one cannot be substituted. `casesOnStuckLHS` now reduces the major premise before looking for the variable to case on, and runs in the goal's local context. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014KdqrCEybAM2f7AKbAsJsx
|
!bench |
|
Benchmark results for 978cfd5 against e9c0364 are in. There are significant results. @nomeata
Medium changes (2✅, 1🟥)
Small changes (51✅, 9🟥)
|
|
Mathlib CI status (docs):
|
|
Reference manual CI status:
|
This PR makes `mkNatLookupTableLifting` lift each constructor-elimination type into the universe it declares for the lookup table, instead of relying on `PULift` to contribute the same bump on its own. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5jcJjLLjxhiAueieK4KEj
This PR gives `PULift` the resulting universe `Sort (max s r)` instead of `Sort (max s r 1)`, so lifting a proposition yields a proposition. Its recursor is correspondingly restricted to motives in `Prop`, while `casesOn` and `recOn` stay universe-polymorphic, as for `PSigma` and `PProd`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5jcJjLLjxhiAueieK4KEj
This PR gives `T.ctorElimType` the resulting universe of the motive instead of bumping it past `Prop`, so eliminating into a proposition no longer lifts the constructor-elimination types into `Type`. Now that `PULift` no longer bumps, the lookup table can be declared in the universe of its entries. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M5jcJjLLjxhiAueieK4KEj
PSigma and PProdPSigma, PProd and PULift
|
This probably needs #14901 fixed first. |
|
Can we fix |
|
This PR gives
PSigma,PProdandPULiftthe resulting universeSort (max u v)instead ofSort (max 1 u v), so a pair of propositions is itself a proposition and lifting a proposition yields a proposition. Their recursors are correspondingly restricted to motives inProp, whilecasesOnandrecOnstay universe-polymorphic. Thestructurecommand now accepts such a resulting universe, subject tobootstrap.inductiveCheckResultingUniverseasinductivealready was.The kernel restricts the recursor of a single-constructor type whose resulting universe can be
Prop. Projections stay available, since the field-universe check forces every field of such a type to be a proof whenever the type is one, soLean.mkCasesOnViaProjs?buildscasesOnandrecOnfromExpr.projplus eta for structures. Everything derived fromcasesOnis unaffected;SizeOfused the recursor directly and gets a projection-based path of its own, and the guards that read "can eliminate intoType" off.rec's level parameters now read it off.casesOn.The bump no longer leaks into the universe levels of
below.Lean.Meta.PProdNstill packs propositions withAndrather thanPProd, but that is now only for readability rather than to stay inProp.A tuple of proofs is now a proof, so it gets abstracted into an auxiliary theorem and a packed well-founded recursion argument is no longer a manifest chain of
PSigma.mk.ArgsPacker.Unary.unpacktherefore falls back to projections, which are always valid here, andFunInd.cleanPackedArgsreducesPSigma.casesOnapplied to a proof.MatcherApp.transformgainedaddProofEqualitiesso that functional induction keeps substituting a proof-valued discriminant away instead of leaving a dead binder in the principle; only homogeneous equations are added, since a heterogeneous one cannot be substituted.casesOnStuckLHSnow reduces the major premise before looking for the variable to case on, and runs in the goal's local context.T.ctorElimTypeloses its bump as well: the lookup table holding the constructor-elimination types is declared in the universe of its entries, which is no longer raised pastPropbyPULift, so eliminating into a proposition no longer lifts those types intoType.Subtypewould be eligible for the same treatment — its fields are a value and a proof about that value, so a subtype of a proposition is a proposition — but it is left alone here, because buildingcasesOnfrom projections has a bad effect on meta code. Such acasesOnreduces on any scrutinee rather than getting stuck on a variable, so amatchon the type is no longer a case split: the proof in⟨x, _⟩stops being determined by unification whenever the callee matches on the subtype (22 such sites inStd.Data.DHashMap.Lemmasalone), well-founded recursion loses the split it needs to find a decreasing measure (tests/elab/grind_qsort.lean), andmatchequation generation fails (tests/elab/adamTC.lean). The types touched here are internal enough that this does not come up for them, butSubtypeis written by hand all the time. None of it would arise if the kernel gave such a type a large-eliminating recursor, which would be reasonable: whenever the type is a proposition every one of its fields is a proof, so it is a subsingleton and no impredicativity is being exploited, exactly as forAnd, whose recursor already eliminates into any universe.Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_014KdqrCEybAM2f7AKbAsJsx