Zulip Chat Archive

Stream: lean4

Topic: Instance synthesis (almost) infinite recursion


Christian Merten (Nov 25 2024 at 13:13):

Consider the following MWE:

class Foo (X : Type) : Prop where

set_option trace.Meta.synthInstance true

example {X Y : Type} [inst : Foo Y]
    (h :  {X Y : Type} [Foo Y], 3 = 3  Foo X) (hY : ¬3 = 3) : Foo X := by
  have : Foo Y := inferInstance
  sorry

This succeeds, but if you look at the synthInstance trace, you can see that it first tries to repetively use h to deduce Foo Y. After going on for hundreds of iterations, the trace finally get smaller again and it backtracks until eventually using inst.

This appeared while looking at (the non Mathlib-free)

import Mathlib.Tactic.WLOG

class Foo (X : Type) : Prop where

set_option trace.Meta.synthInstance true

example {X Y : Type} [Foo Y] : Foo X := by
  wlog hY : 3 = 3
  · /-
    X Y : Type
    inst✝ : Foo Y
    this : ∀ {X Y : Type} [inst : Foo Y], 3 = 3 → Foo X
    hY : ¬3 = 3
    ⊢ Foo X
    -/
    have : Foo Y := inferInstance
    sorry
  sorry

where the same phenomenon arises, but now the instance search times out. I strongly suspect this has nothing to do with wlog, but I couldn't get the first example to fail without it. The latter example can be fixed with set_option synthInstance.maxSize 50.

I assume instance search is depth first. Is there a way to prevent this from happening?

Daniel Weber (Nov 25 2024 at 13:31):

Note that instance : ∀ {X Y : Type} [Foo Y], 3 = 3 → Foo X := sorry is a bad instance, because there's no valid synthesization order. Perhaps a similar check could be done before using local parameters in typeclass search

Andrew Yang (Nov 25 2024 at 15:30):

Let me guess: wlog is missing some withMainContext

Christian Merten (Nov 25 2024 at 21:29):

Andrew Yang said:

Let me guess: wlog is missing some withMainContext

Not sure, because if we make the goal a bit worse, it also fails without wlog:

class Foo (X : Type) : Prop where

set_option trace.Meta.synthInstance true

example {X Y : Type} [inst : Foo Y]
    (h :  {X Y : Type} [Foo Y], 3 = 3  Foo Y  Foo Y  Foo Y  Foo Y  Foo Y  Foo Y  Foo Y  Foo X)
    (hY : ¬3 = 3) : Foo X := by
  have : Foo Y := inferInstance
  sorry

Last updated: May 02 2025 at 03:31 UTC