Zulip Chat Archive

Stream: general

Topic: Successful instance search is followed by failure?


nrs (Dec 16 2024 at 07:30):

The following instance search first succeeds and then fails. Anyone has tips to figure out how to debug this? It works when I replace class SubSig (siga sigb : Signature) where with class SubSig (siga sigb : outParam Signature) where, but I'm not actually sure it is always the case siga and sigb are only inferred after the fact. Is this the right way to solve this?

import Mathlib

namespace myNamespace

structure Signature where
  symbols : Type
  arity : symbols -> Nat

inductive Ext (sig : Signature) (α : Type _)
| mk : (s : sig.symbols) -> (Fin2 (sig.arity s) -> α) -> Ext sig α

def Ext.map (f : α -> β) : Ext sig α -> Ext sig β
| s, g => s, f  g

def Alg (sig : Signature) (α : Type _) : Type _ := Ext sig α -> α

inductive W (sig : Signature)
| sup : Ext sig (W sig) -> W sig

class SubSig (siga sigb : Signature) where
  inj : Ext siga α -> Ext sigb α

def inject {siga sigb : Signature}  (ext : Ext siga (W sigb)) [SubSig siga sigb] : W sigb :=
  SubSig.inj ext

inductive NatTySh | nat
def NatTyE : Signature := NatTySh, fun _ => 0
def NatVal : Alg NatTyE Type := fun
  | ⟨.nat, _⟩ => Nat

inductive IArithExprSymbols {sig : Signature} [inst : SubSig NatTyE sig] : W sig -> Type _
| val : Nat -> IArithExprSymbols (inject (siga := NatTyE) ⟨.nat, (nomatch .)) --succeeds
| add : IArithExprSymbols (inject (⟨.nat, (nomatch .) : Ext NatTyE (W sig))) --succeeds
| add' : IArithExprSymbols (inject _) -- tracing this line
| add'' : IArithExprSymbols (inject NatTySh.nat, (nomatch .))  -- doesn't work either, succeeds with `outParam` change
/-
▶ expected type (71:36-71:37)
sig : Signature
inst : SubSig NatTyE sig
⊢ Ext ?m.6063 (W sig)

▶ 71:29-71:37: error:
typeclass instance problem is stuck, it is often due to metavariables
  SubSig ?m.6063 sig

▶ 71:10-71:38: information:
[Meta.synthInstance] 💥️ SubSig NatTyE ?m.6058 ▼
  [] new goal SubSig NatTyE ?m.6058 ▼
  [instances] #[@SubAlg.toSubSig, inst]
  [] 💥️ apply inst to SubSig NatTyE ?m.6058 ▼
  [tryResolve] 💥️ SubSig NatTyE ?m.6058 ≟ SubSig NatTyE sig

[Meta.synthInstance] 💥️ SubSig NatTyE ?m.6064 ▼
  [] new goal SubSig NatTyE ?m.6064 ▼
  [instances] #[@SubAlg.toSubSig, inst]
  [] 💥️ apply inst to SubSig NatTyE ?m.6064 ▼
  [tryResolve] 💥️ SubSig NatTyE ?m.6064 ≟ SubSig NatTyE sig

[Meta.synthInstance] ✅️ SubSig NatTyE sig ▼
  [] result inst (cached)


▶ 71:29-71:37: information:

[Meta.synthInstance] 💥️ SubSig ?m.6063 ?m.6064 ▼
  [] new goal SubSig ?m.6063 ?m.6064 ▶
  [] 💥️ apply inst to SubSig ?m.6063 ?m.6064 ▶

...

[Meta.synthInstance] 💥️ SubSig ?m.6063 sig ▼
  [] new goal SubSig ?m.6063 sig ▼
  [instances] #[@SubAlg.toSubSig, inst]
  [] 💥️ apply inst to SubSig ?m.6063 sig ▼
  [tryResolve] 💥️ SubSig ?m.6063 sig ≟ SubSig NatTyE sig
-/

Eric Wieser (Dec 16 2024 at 07:41):

Can you add the imports to make your example work?

nrs (Dec 16 2024 at 07:43):

Sorry I should be used to doing this by now

nrs (Dec 16 2024 at 07:43):

done

Eric Wieser (Dec 16 2024 at 07:44):

I get a syntax error after your last line, your (s aren't closed

nrs (Dec 16 2024 at 07:44):

argh fixed my bad

Eric Wieser (Dec 16 2024 at 07:45):

I guess (set_option trace.Meta.synthInstance true in inject _) is needed to see the trace messages

nrs (Dec 16 2024 at 07:46):

I used set_option trace.Meta.synthInstance true at the top of the inductive declaration (didn't know you could literally set_option right inside a term, thanks!)

Eric Wieser (Dec 16 2024 at 07:47):

I think in the term it maybe doesn't show the thing you wanted to show (success followed by failure)

Eric Wieser (Dec 16 2024 at 07:48):

But your issue here is that typeclass synthesis is not allowed to populate metavariables, unless you mark them as outParam or semiOutParam

Eric Wieser (Dec 16 2024 at 07:49):

And you should think carefully about whether those are actually what you want, or if instead the caller should just have provided a type annotation

nrs (Dec 16 2024 at 07:51):

Hm right when I use trace.Meta.synthInstance directly inside the term there's only the failure, but at the top of the inductive it reports that on the same line there's a success before the failure

nrs (Dec 16 2024 at 07:52):

I'll be investigating outParam and semiOutParam more closely, thanks a lot for taking the time!!

Eric Wieser (Dec 16 2024 at 08:10):

Note that the indentation is currently broken for the trace output (lean4#6389), which can make it hard to read

Eric Wieser (Dec 16 2024 at 08:11):

You can work around it by using #guard_msgs in, and then the version that gets copied into a comment has the correct indentation

nrs (Dec 16 2024 at 08:14):

Noted! very useful stuff, thanks a lot!


Last updated: May 02 2025 at 03:31 UTC