Zulip Chat Archive
Stream: Type theory
Topic: Debugging universe levels for minimal brecOn metatheory
nrs (Jan 01 2025 at 05:04):
I've been attempting to make a small formalization of brecOn
to get a better hang of Lean's metatheory. In the code below, Ctors
is implicitly representing an inductive type by exhausting its constructors. Let ctors : Ctors
. Then i : ctors.ctor_indexer
will provide an index that will allow us to grab a constructor through ctors.ctor_at i
, and so term : ctors.ctor_at i
is effectively a value of the type given by ctors
. This is encoded in the TermOf
structure. Ctors
is a special case of mathlib'sPFunctor
and TermOf
is a special case of mathlib's WType
, and we encode Lean's rec
by giving a way to witness some motive for each constructor.
Everything was going more or less well until the definition of brecOn_aux
in the code that follows, which fails to solve universe levels, and I'm not entirely sure I understand why. Before below
, it seems to me we don't need more than one universe, but to encode below
we need at least two universes: one containing the witness of the motive, and another one containing the witnessing that there is a witness to the motive, which needs to be a single universe level higher (right?), and from this point onwards I think we need to start keeping explicit track of universe levels, because just using Type _
will produce said failure to solve universe level constraints at brecOn_aux
.
I am not entirely sure how to progress forwards given this fact. Anyone have hints/suggestions/free associations to share from looking at the code below? Meanwhile I will be reviewing the source code for inductive types, the code for compile_inductive
and Mario Carneiro's metatheory code.
structure Ctors where
ctor_indexer : Type
ctor_at : ctor_indexer -> Type _
structure TermOf (ctors : Ctors) where
ctor_choice : ctors.ctor_indexer
ctor_wness : ctors.ctor_at ctor_choice
continuation_index : ctors.ctor_indexer
continuation : ctors.ctor_at continuation_index -> TermOf ctors
structure rec (ctors : Ctors) where
indexed_motives : (ctor_choice : ctors.ctor_indexer) -> ((ctor_wness : ctors.ctor_at ctor_choice) -> Type _)
motive_wness_from_term : (term : TermOf ctors) -> indexed_motives term.ctor_choice term.ctor_wness
def below (base_rec : rec ctors) : rec ctors where
indexed_motives := (fun _ _ => Type _)
motive_wness_from_term := fun term => PProd
(base_rec.indexed_motives term.ctor_choice term.ctor_wness)
(Type _)
-- failure to solve universe levels in the following
def brecOn_aux (base_rec : rec ctors) : rec ctors where
indexed_motives := fun ctor_choice ctor_wness => PProd
(base_rec.indexed_motives ctor_choice ctor_wness)
((below base_rec).indexed_motives ctor_choice ctor_wness)
motive_wness_from_term := fun term => .mk
(base_rec.motive_wness_from_term term)
((below base_rec).motive_wness_from_term term)
-- if definition had succeeded, we would have defined brecOn by projecting the left value from the above's `motive_wness_from_term`
nrs (Jan 01 2025 at 07:07):
was re-reading Lean's below
and might have made a mistake in my encoding above. Here's another version that works and doesn't need explicit universe levels. comments or suggestions are still welcome!
structure Ctors where
ctor_indexer : Type
ctor_at : ctor_indexer -> Type _
structure TermOf (ctors : Ctors) where
ctor_choice : ctors.ctor_indexer
ctor_wness : ctors.ctor_at ctor_choice
continuation_index : ctors.ctor_indexer
continuation : ctors.ctor_at continuation_index -> TermOf ctors
structure rec (ctors : Ctors) where
indexed_motives : (ctor_choice : ctors.ctor_indexer) -> ((ctor_wness : ctors.ctor_at ctor_choice) -> Type _)
motive_wness_from_term : (term : TermOf ctors) -> indexed_motives term.ctor_choice term.ctor_wness
def below (base_rec : rec ctors) : rec ctors where
indexed_motives := (fun _ _ => Type _)
motive_wness_from_term := fun term => @PProd
(base_rec.indexed_motives term.ctor_choice term.ctor_wness)
(ctors.ctor_at term.ctor_choice)
def brecOn_aux (base_rec : rec ctors) : rec ctors where
indexed_motives := fun ctor_choice ctor_wness => Prod
(base_rec.indexed_motives ctor_choice ctor_wness)
((below base_rec).indexed_motives ctor_choice ctor_wness)
motive_wness_from_term := fun term => .mk
(base_rec.motive_wness_from_term term)
((below base_rec).motive_wness_from_term term)
def brecOn (base_rec : rec ctors) : rec ctors where
indexed_motives := fun ctor_choice ctor_wness => base_rec.indexed_motives ctor_choice ctor_wness
motive_wness_from_term := fun term => ((brecOn_aux base_rec).motive_wness_from_term <| term).fst
edit: the above will not work, a working definition needs to stick closer to the definitions for polynomial functors and wtypes
Last updated: May 02 2025 at 03:31 UTC