import Lean.Meta open Lean open Lean.Meta class HasCoerce (a : semiOutParam Type) (b : Type) := (coerce : a → b) def coerce {a b : Type} [HasCoerce a b] : a → b := @HasCoerce.coerce a b _ instance coerceTrans {a b c : Type} [HasCoerce b c] [HasCoerce a b] : HasCoerce a c := ⟨fun x => coerce (coerce x : b)⟩ instance coerceBoolToProp : HasCoerce Bool Prop := ⟨fun y => y = true⟩ instance coerceDecidableEq (x : Bool) : Decidable (coerce x) := inferInstanceAs (Decidable (x = true)) instance coerceNatToBool : HasCoerce Nat Bool := ⟨fun x => x == 0⟩ instance coerceNatToInt : HasCoerce Nat Int := ⟨fun x => Int.ofNat x⟩ def print {α} [ToString α] (a : α) : MetaM Unit := do trace[Meta.synthInstance] (toString a) def tst1 : MetaM Unit := do let inst ← mkAppM `HasCoerce #[mkConst `Nat, mkSort Level.zero] let r ← synthInstance inst print r set_option trace.Meta.synthInstance true in set_option trace.Meta.synthInstance.tryResolve false in #eval tst1 def tst2 : MetaM Unit := do let inst ← mkAppM `Bind #[mkConst `IO] -- globalInstances ← getGlobalInstances -- print (format globalInstances) -- result ← globalInstances.getUnify inst -- print result let r ← synthInstance inst print r pure () set_option trace.Meta.synthInstance true in set_option trace.Meta.synthInstance.tryResolve false in #eval tst2 def tst3 : MetaM Unit := do let inst ← mkAppM `BEq #[mkConst `Nat] let r ← synthInstance inst print r pure () set_option trace.Meta.synthInstance true in set_option trace.Meta.synthInstance.tryResolve false in #eval tst3