lean4-htt/tests/lean/run/inductive_univ.lean
Kyle Miller cde237daea
feat: change structure command to elaborate fields as if structures are flat (#7302)
This PR changes how fields are elaborated in the `structure`/`class`
commands and also makes default values respect the structure resolution
order when there is diamond inheritance. Before, the details of
subobjects were exposed during elaboration, and in the local context any
fields that came from a subobject were defined to be projections of the
subobject field. Now, every field is represented as a local variable.
All parents (not just subobject parents) are now represented in the
local context, and they are now local variables defined to be parent
constructors applied to field variables (inverting the previous
relationship). Other notes:
- The entire collection of parents is processed, and all parent
projection names are checked for consistency. Every parent appears in
the local context now.
- For classes, every parent now contributes an instance, not just the
parents represented as subobjects.
- Default values are now processed according to the parent resolution
order. Default value definition/override auxiliary definitions are
stored at `StructName.fieldName._default`, and inherited values are
stored at `StructName.fieldName._inherited_default`. Metaprograms no
longer need to look at parents when doing calculations on default
values.
- Default value omission for structure instance notation pretty printing
has been updated in consideration of this.
- Now the elaborator generates a `_flat_ctor` constructor that will be
used for structure instance elaboration. All types in this constructor
are put in "field normal form" (projections of parent constructors are
reduced, and parent constructors are eta reduced), and all fields with
autoParams are annotated as such. This is not meant for users, but it
may be useful for metaprogramming.
- While elaborating fields, any metavariables whose type is one of the
parents is assigned to that parent. The hypothesis is that, for the
purpose of elaborating structure fields, parents are fixed: there is
only *one* instance of any given parent under consideration. See the
`Magma` test for an example of this being necessary. The hypothesis may
not be true when there are recursive structures, since different values
of the structure might not agree on parent fields.

Other notes:
- The elaborator has been refactored, and it now uses a monad to keep
track of the elaboration state.
- This PR was motivation for #7100, since we need to be able to make all
parents have consistent projection names when there is diamond
inheritance.

Still to do:
- Handle autoParams like we do default values. Inheritance for these is
not correct when there is diamond inheritance.
- Avoid splitting apart parents if the overlap is only on proof fields.
- Non-subobject parent projections do not have parameter binder kinds
that are consistent with other projections (i.e., all implicit by
default, no inst implicits). This needs to wait on adjustments to the
synthOrder algorithm.
- We could elide parents with no fields, letting their projections be
constant functions. This causes some trouble for defeq checking however
(maybe #2258 would address this).
2025-03-22 22:33:10 +00:00

104 lines
2.7 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-!
# Tests of universe constraint testing in the `inductive` command
-/
set_option pp.mvars false
set_option pp.universes true
/-!
Given the resultant type, infer that the `x` parameter is `Type`.
-/
inductive T0 : Type where
| mk (x : PUnit.{_+1})
/-- info: T0.mk (x : PUnit.{1}) : T0 -/
#guard_msgs in #check T0.mk
/-!
Given the resultant type, infer that the `x` parameter is `Type` as well.
-/
inductive T1 : Type where
| mk (x : PUnit.{_+1} × PUnit.{_+1})
/-- info: T1.mk (x : Prod.{0, 0} PUnit.{1} PUnit.{1}) : T1 -/
#guard_msgs in #check T1.mk
/-!
Given the resultant type is `Prop`, do not do this inference. Get two universe levels.
-/
inductive T3 : Prop where
| mk (x : PUnit.{_+1} × PUnit.{_+1})
/-- info: T3.mk.{u_1, u_2} (x : Prod.{u_1, u_2} PUnit.{u_1 + 1} PUnit.{u_2 + 1}) : T3.{u_1, u_2} -/
#guard_msgs in #check T3.mk
/-!
Given the resultant type, fail to infer a level for `PUnit` if there's not a unique solution.
-/
/--
error: invalid universe level in constructor 'E0.mk', parameter 'x' has type
PUnit.{u_1}
at universe level
u_1
which is not less than or equal to the inductive type's resulting universe level
1
-/
#guard_msgs in
inductive E0 : Type where
| mk (x : PUnit)
/-!
Given the resultant type, fail to infer a level for `PUnit` if there's not a unique solution.
-/
/--
error: invalid universe level in constructor 'E1.mk', parameter 'x' has type
Prod.{u_1, u_2} PUnit.{u_1 + 1} PUnit.{u_2 + 1}
at universe level
max (u_1+1) (u_2+1)
which is not less than or equal to the inductive type's resulting universe level
2
-/
#guard_msgs in
inductive E1 : Type 1 where
| mk (x : PUnit × PUnit)
/-!
`Sort` polymorphism is not allowed.
-/
/--
error: invalid universe polymorphic resulting type, the resulting universe is not 'Prop', but it may be 'Prop' for some parameter values:
Sort u
Possible solution: use levels of the form 'max 1 _' or '_ + 1' to ensure the universe is of the form 'Type _'.
-/
#guard_msgs in
inductive P (α : Sort u) : Sort u where
| mk (x : α)
/-!
Errors for `structure` are specialized to talking about fields.
-/
/--
error: invalid universe level for field 'α', has type
Type
at universe level
2
which is not less than or equal to the structure's resulting universe level
1
-/
#guard_msgs in
structure A : Type where
α : Type
/-!
Errors for `structure` talk about parent projection fields too.
(Note: it could easily point to `A'` and say the error is field `α`.)
-/
structure A' where
α : Type
/--
error: invalid universe level for field 'α', has type
Type
at universe level
2
which is not less than or equal to the structure's resulting universe level
1
-/
#guard_msgs in
structure B : Type extends A'