Zulip Chat Archive
Stream: new members
Topic: How do I unfold `.1`?
Richard Kiss (Mar 13 2024 at 22:26):
I'm using UInt8
for certain functions for efficiency which means there are a lot of casts which I fastidiously unfold until I get to .1
. Then I'm stuck. How can I unfold this? The underlying type that has me stuck this time is Fin UInt8.size
. I tried unfold Fin.val
and simp [Fin.val]
but nothing happens.
Eric Wieser (Mar 13 2024 at 22:27):
Can you make a #mwe?
Richard Kiss (Mar 13 2024 at 22:28):
at the core is a complex recursive function with multiple deep match
branches, so it'll be challenging. But I'll try to create a smaller version that exhibits the issue
Richard Kiss (Mar 13 2024 at 22:37):
okay, I figured out what's up here. I had a definition def OP_SHA256 : UInt8 := 11
(an opcode) and I needed to unfold it. Computer programmer brain forgot constants work differently in lean
Richard Kiss (Mar 13 2024 at 22:56):
In my attempt at a more minimal example, I can get stuck at the same point, but rfl
solves it. Is there a way to see what sub-tactics rfl
uses so I try some of those?
Richard Kiss (Mar 13 2024 at 22:58):
I get to
int_to_atom ({ natCast := fun n ↦ Int.ofNat n }.1
{ ofNat := UInt8.ofNat 11 }.1.1.1) = instOfNatAtom.1
Richard Kiss (Mar 13 2024 at 23:00):
it seems like it's clear these are all constants, but simp [int_to_atom]
just blows up to a big mess
Richard Kiss (Mar 13 2024 at 23:04):
okay, this has something to do with how OfNat
works and how it "hides" the underlying Nat
(11 in this case) in the instance function
Richard Kiss (Mar 14 2024 at 00:46):
Here's an #mwe:
example: Int.ofNat (Fin.val (UInt8.val (11: UInt8))) = 11 := by
unfold UInt8.val
unfold Fin.val
sorry
It's easy to prove the example with rfl
. But I eventually get stuck when using just unfold
and simp
.
Richard Kiss (Mar 14 2024 at 00:58):
one reduce
does it! But reduce
is not well documented and I don't yet know what it does
Kevin Buzzard (Mar 14 2024 at 01:03):
Is there a way to see what sub-tactics rfl uses so I try some of those?
show_term rfl
. But all it does it tries to unify the goal with Eq.refl [LHS]
, it's not applying any sub-tactics AFAIK.
Kyle Miller (Mar 14 2024 at 01:25):
If you know what it's supposed to be, you can use the change
tactic, which should be able handle anything rfl
/reduce
should
example: Int.ofNat (Fin.val (UInt8.val (11: UInt8))) = 11 := by
change 11 = _
sorry
Kyle Miller (Mar 14 2024 at 01:27):
It looks like simp
is actually able to reduce this one, though perhaps using lemmas you don't have imported.
example (a : Int) : Int.ofNat (Fin.val (UInt8.val (11: UInt8))) = a := by
simp?
-- simp only [UInt8.val_val_eq_toNat, UInt8.reduceToNat, Int.ofNat_eq_coe, Nat.cast_ofNat]
sorry
(the a
is to prevent simp
from proving it with rfl
)
Richard Kiss (Mar 14 2024 at 01:31):
Here's the solution with just unfold
and simp
of the #mwe.
example: Int.ofNat (11: UInt8).val.val = (11: Int) := by
unfold Fin.val
unfold UInt8.val
unfold UInt8.instOfNat
unfold UInt8.ofNat
unfold Fin.ofNat
simp [Int.ofNat]
Now I just need to unwind the casting and get my mind around how that works.
Matt Diamond (Mar 14 2024 at 02:43):
a lot of unfolding is a code smell, IMHO... there should be APIs that make it easier to move between types
for example, if you want a UInt8
as an Int
, you can just do Int.ofNat (11 : UInt8).toNat
, and the example becomes
example : Int.ofNat (11: UInt8).toNat = (11: Int) := by simp
Matt Diamond (Mar 14 2024 at 02:52):
Of course it's a toy example and you could solve it with rfl
, but I think it's instructive that simp
works here while it fails to solve Int.ofNat (11: UInt8).val.val = (11: Int)
without imports. Things are easier when you take advantage of functions that are designed to facilitate casting.
Matt Diamond (Mar 14 2024 at 03:02):
(And with imports, simp
can solve your version thanks to docs#UInt8.val_val_eq_toNat, which re-writes it to use UInt8.toNat
.)
Richard Kiss (Mar 14 2024 at 03:04):
I was on v4.6.1 and some of this stuff seems to only be in 4.7.0-rc2, so I'm upgrading
Last updated: May 02 2025 at 03:31 UTC