Zulip Chat Archive

Stream: lean4

Topic: constructor isn't defeq to eta value for mutual definitions


Jakub Nowak (Oct 06 2025 at 05:41):

namespace NotMutual

structure Bar : Type where
  n : Nat

structure Foo : Type where
  bar : Bar

example (foo : Foo) : Prop := by
  have h₁ : foo = ({ bar := foo.bar } : Foo) := rfl
  have h₂ : foo = Foo.mk foo.bar := rfl
  sorry

end NotMutual


namespace Mutual

mutual

  structure Foo : Type where
    bar : Bar

  structure Bar : Type where
    n : Nat

end

example (foo : Foo) : Prop := by
  have h₁ : foo = ({ bar := foo.bar } : Foo) := rfl
  have h₂ : foo = Foo.mk foo.bar := rfl  -- Type mismatch
  sorry

end Mutual

Not sure if this is something that should be reported as an issue?

Btw, the fact that delaboration isn't idempotent in this case was a source of confusion for me (#new members > Prove termination of mutually recursive definitions).

Robin Arnez (Oct 06 2025 at 19:07):

It fails because it isn't defeq. Structure eta only applies to non-recursive inductives with one constructor.

Jakub Nowak (Oct 17 2025 at 22:44):

Robin Arnez said:

It fails because it isn't defeq. Structure eta only applies to non-recursive inductives with one constructor.

But this defeq works: foo = ({ bar := foo.bar } : Foo), while this doesn't foo = Foo.mk foo.bar. So it seems like structure eta works, but only with ({ bar := foo.bar } : Foo), and not with Foo.mk foo.bar.

Robin Arnez (Oct 18 2025 at 07:51):

That's not quite right. The structure instance elaborator uses a version of structure eta, presumably also to counteract some of the flattening it does:
https://github.com/leanprover/lean4/blob/c76411d6c55dfc292934d80914dfa6e5f77598f3/src/Lean/Elab/StructInst.lean#L881
... but this isn't guaranteed to be a defeq transformation! So specifically:

mutual

  structure Foo : Type where
    bar : Bar

  structure Bar : Type where
    n : Nat

end

-- fails, goal foo = { bar := foo.bar }
example (foo : Foo) : ({ bar := foo.bar } : Foo) = Foo.mk foo.bar := rfl

... I guess the delaboration doesn't make it any better though...

Jakub Nowak (Oct 18 2025 at 18:06):

Maybe it would be possible to apply the same elaboration to both structure instance and constructor syntaxes?

If not, then I would say to not delaborate constructor to structure instance syntax, as they're not the same and it's causing confusion. Maybe we could also lint/warn against usage of constructor when structure instance syntax is viable?


Last updated: Dec 20 2025 at 21:32 UTC