Zulip Chat Archive

Stream: lean4

Topic: Use just-defined instance of substructure in superstructure?


Thomas Murrills (Mar 14 2023 at 03:19):

Consider the following #mwe:

class Foo (α : Type) where
  x : Bool

def f (α) [Foo α] : Nat := 0

class Bar (α : Type) extends Foo α where
  y : f α = 0

theorem fIsZero (α) [Foo α] : f α = 0 := rfl

def baz : Bar Nat := { x := true, y := fIsZero Nat} -- failed to synthesize instance
  Foo 

We've just defined an instance of Foo Nat by providing x, but fIsZero can't see it.

How do we get something like fIsZero to use the Foo α we've just defined? Is there a better option than just "precariously" inlining an instance of Foo Nat which happens to be equal to the one we're defining?

Adam Topaz (Mar 14 2023 at 03:24):

you could do this:

def baz : Bar Nat :=
  let t : Foo Nat := true
  { t with y := fIsZero Nat}

Thomas Murrills (Mar 14 2023 at 04:07):

Nice, thanks!

Jireh Loreaux (Mar 14 2023 at 05:11):

Don't you want to use letI so that it actually gets inlined?

Thomas Murrills (Mar 14 2023 at 05:32):

Ok, sounds good—but just wondering, what's the actual difference, there? Why would I want let to not inline sometimes? (Or when can it not?)

Reid Barton (Mar 14 2023 at 06:43):

Usually you don't want let to inline, to avoid computing something more than once, or to avoid blowing up the term size.

Adam Topaz (Mar 14 2023 at 16:28):

Jireh Loreaux said:

Don't you want to use letI so that it actually gets inlined?

Yes, letI would be better here. I only used let because I wasn't sure whether Thomas wanted to rely on std4 (which is where letI is defined)


Last updated: Dec 20 2023 at 11:08 UTC