Zulip Chat Archive

Stream: lean4

Topic: (kernel) invalid projection


Adrien Champion (May 24 2023 at 11:13):

I've got this error and I'm not sure what to do. Basically, the problem happens when I rewrite a structure-type using a type-level equality and try to access a field

class Flags (α : Type) where
  toType : α  Type
  consume : (a : α)  (toType a  Unit)  Unit

structure Person where
  name : String
  email : String

class Person.FlagsEq (α : Type) [I : Flags α] where
  flag : α
  flag_spec : I.toType flag = Person

--  vvvvv~~~~~ (kernel) invalid projection `p.1`
def test₂
  [I : Flags α]
  [IEq : Person.FlagsEq α]
:=
  I.consume IEq.flag fun p =>
    let p : Person := IEq.flag_spec  p
    let name := p.name
    ()

Adrien Champion (May 24 2023 at 11:15):

Removing the p.name line yields no error (just the unused var warning)

Max Nowak 🐉 (May 24 2023 at 11:24):

Removing p.name probably yields no error since p is unused and gets removed entirely (is my guess, don't quote me on that, I had similar things happen).

Kyle Miller (May 24 2023 at 12:11):

I checked that it's got nothing to do with name shadowing. This causes the same error too:

def test₂
  [I : Flags α]
  [IEq : Person.FlagsEq α]
:=
  I.consume IEq.flag fun p =>
    let q : Person := IEq.flag_spec  p
    let name := q.name
    ()

Kyle Miller (May 24 2023 at 12:12):

It seems possible that there is a kernel bug with how projections are reduced? This sidesteps the issue:

def Person_name (p : Person) : String := p.name

--  vvvvv~~~~~ (kernel) invalid projection `p.1`
def test₂
  [I : Flags α]
  [IEq : Person.FlagsEq α]
:=
  I.consume IEq.flag fun p =>
    let q : Person := IEq.flag_spec  p
    let name := Person_name q
    ()

Kyle Miller (May 24 2023 at 12:13):

Even with renaming p -> q, you get (kernel) invalid projection p.1 (with p, not q). If you mouse over p, you see it thinks it has type Flags.toType Person.FlagsEq.flag, which explains why it thinks its an invalid projection at this point.

Adrien Champion (May 24 2023 at 12:15):

I did notice that as well, it seems the rewrite makes type-checking go through but after that the kernel somehow still works with the pre-rewrite datatype

Kyle Miller (May 24 2023 at 12:24):

If I were to guess, it looks like the kernel is reducing IEq.flag_spec ▸ p to p (or in that last example, IEq.flag_spec ▸ q to p) before trying to take the projection


Last updated: Dec 20 2023 at 11:08 UTC