Zulip Chat Archive
Stream: new members
Topic: Automatically synthesize a fact in instance argument
Aymeric Fromherz (Sep 30 2022 at 11:58):
Hi! I've recently been going through the Lean 4 tutorial, and trying to experiment a bit with it.
In particular, I have (a slightly more complicated version of) the following code, where I'm trying to use refinement types:
def isPos (x:Int) := x > 0
def pos : Type := { x : Int // isPos x}
instance (n:Nat) (p: isPos n) : OfNat pos n where
ofNat := ⟨ Int.ofNat n, p ⟩
def test : pos := ⟨ 1, by simp [isPos] ⟩
Ideally, I'd like to write test
as simply def test : pos := 1
, and let the ofNat pos n typeclass instance automatically introduce the coercion. However, in the current state, Lean does not seem to be able to synthesize the isPos
argument automatically.
Is there a way to tell Lean 4 to always try to apply the simplifier during synthesis for this specific argument?
Thanks!
Tomas Skrivan (Sep 30 2022 at 12:49):
You can apply simplifier to synthesize an argument like this:
abbrev isPos (x:Int) := x > 0 -- marked it as abbrev for simp to see through it
def pos : Type := { x : Int // isPos x}
instance posOfNat (n:Nat) (p: isPos n := by simp) : OfNat pos n where
ofNat := ⟨ Int.ofNat n, p ⟩
but it this case it is not doing what you are after, not sure why.
Tomas Skrivan (Sep 30 2022 at 12:51):
When you call the instance explicitly, it works:
#check posOfNat 1
#check posOfNat 10
#check_failure posOfNat 0
Aymeric Fromherz (Sep 30 2022 at 13:00):
Thanks for the answer! the := by simp
syntax was what I was looking for. However, this indeed does not seem to interact well with instance synthesis. Could it be that the by simp
is executed prior to resolving n?
Tomas Skrivan (Sep 30 2022 at 13:02):
In that case calling the instance directly would not work too, no?
Aymeric Fromherz (Sep 30 2022 at 13:18):
Mmh, possibly, but I do not know enough about how Lean 4 solves metavariables. The difference i see is that, when calling the instance directly, there is no metavariable for n
, while if Lean is trying to solve isPos ?m_n
by simp before ?m_n
is resolved, this could lead to issues
Tomas Skrivan (Sep 30 2022 at 14:03):
Could be, I do not understand these things too much either.
Kyle Miller (Sep 30 2022 at 14:11):
My guess is that instance search doesn't attempt running the tactic for (p: isPos n := by simp)
.
Another example:
class foo (n : Nat) where
x : Nat
instance foo_insts (n : Nat) (p : n = n := by rfl) : foo n where
x := n
#check foo_insts 1 -- ok
#check foo.x 1 -- failed to synthesize instance
Kyle Miller (Sep 30 2022 at 14:13):
Maybe it's worth asking on #lean4 about this and whether @Tomas Skrivan's version is expected to work.
Aymeric Fromherz (Sep 30 2022 at 14:33):
Did Lean 3 use to handle this? Thanks for the advice, will do
Last updated: Dec 20 2023 at 11:08 UTC