Zulip Chat Archive
Stream: lean4
Topic: help with `unfold`
Shreyas Srinivas (Dec 19 2022 at 14:58):
Is there a way to unfold only one occurrence of a definition. unfold
unfolds all occurrences. This affects proofs by induction
Shreyas Srinivas (Dec 19 2022 at 14:59):
I am referring to the first occurrence in the goal, so I don't see a way to separately call this occurrence by a name
Ruben Van de Velde (Dec 19 2022 at 15:03):
Maybe with conv
?
Kevin Buzzard (Dec 19 2022 at 15:05):
If unfold
is doing definitional unfolding then you might be able to use change
with some _
.
Shreyas Srinivas (Dec 19 2022 at 15:24):
It did not work. I am at my wits end with some of these proofs
Kevin Buzzard (Dec 19 2022 at 15:30):
Can you post a #mwe ?
Shreyas Srinivas (Dec 19 2022 at 15:33):
It is the same as last time.
import Mathlib.Init.Data.Nat.Lemmas
import Init.WFTactics
-- Imported for Boolean `xor`
import Mathlib.Data.Bool.Basic
import Mathlib.Init.Data.Bool.Lemmas
-- Imported for `bit0` and `bit1`
import Mathlib.Init.ZeroOne
-- Imported for cases'
import Mathlib.Tactic.Cases
universe u
-- The following line helps override the default behaviour, wherein
-- lean equates xor with Nat.xor
-- bxor points to Mathlib.Data.Bool.Basic.xor
--- Author : Shreyas Srinivas
abbrev bxor := xor
namespace Nat
def boddDiv2 : ℕ → Bool × ℕ
| 0 => (false, 0)
| succ n =>
match boddDiv2 n with
| (false, m) => (true, m)
| (true, m) => (false, succ m)
#align nat.bodd_div2 Nat.boddDiv2
def div2 (n : ℕ) : ℕ :=
(boddDiv2 n).2
def bodd (n : ℕ) : Bool :=
(boddDiv2 n).1
@[simp]
theorem bodd_zero : bodd 0 = false :=
rfl
theorem bodd_one : bodd 1 = true :=
rfl
theorem bodd_two : bodd 2 = false :=
rfl
#align nat.bodd_two Nat.bodd_two
@[simp]
theorem bodd_succ (n : ℕ) : bodd (succ n) = not (bodd n) := by
/- unfold bodd boddDiv2 <;> cases boddDiv2 n <;> rename_i fst snd <;> cases fst <;>
simp <;>
cases n <;> simp [add_succ, ]
-/
unfold bodd
unfold boddDiv2
induction' n with n IH
case zero =>
simp
case succ =>
simp[IH]
Kevin Buzzard (Dec 19 2022 at 15:35):
This doesn't compile for me. Can you make it a #mwe ?
Shreyas Srinivas (Dec 19 2022 at 15:39):
I edited it and checked on the lean playground. It works. At the end of case succ
, it seems unfolding boddDiv2 (succ n)
would be useful. unfold boddDiv2
unfolds all occurrences of boddDiv2
Shreyas Srinivas (Dec 19 2022 at 15:40):
So far I have worked around this and fixed a number of other errors in the file (Down from 70 odd messages to 19 messages). But I can't overlook this one anymore
Siddhartha Gadgil (Dec 19 2022 at 15:56):
A workaround is to introduce a statement have l : boddDiv2 (succ n) = ... := by unfold boddDiv2
and then rw [l]
.
Siddhartha Gadgil (Dec 19 2022 at 15:58):
I mean you can see what boddDiv2 (succ n)
unfolds to, copy-paste that (in place of ...
above) to make the claim l
and proceed as above.
Kevin Buzzard (Dec 19 2022 at 16:02):
theorem bodd_succ (n : ℕ) : bodd (succ n) = not (bodd n) := by
simp only [bodd, boddDiv2]
let ⟨b,m⟩ := boddDiv2 n
cases b <;> rfl
Kevin Buzzard (Dec 19 2022 at 16:13):
unfold
was unfolding too far; simp only
gets it right.
Marcus Rossel (Dec 19 2022 at 16:22):
I've also had the general experience that rw
can be useful for performing a single unfold.
Kevin Buzzard (Dec 19 2022 at 16:37):
Ruben's suggestion also works:
theorem bodd_succ (n : ℕ) : bodd (succ n) = not (bodd n) := by
unfold bodd
conv =>
lhs
unfold boddDiv2
let ⟨b,m⟩ := boddDiv2 n
cases b <;> rfl
Kevin Buzzard (Dec 19 2022 at 16:39):
change
works too:
theorem bodd_succ (n : ℕ) : bodd (succ n) = not (bodd n) := by
unfold bodd
change (match boddDiv2 n with
| (false, m) => (true, m)
| (true, m) => (false, succ m)).fst =
!(boddDiv2 n).fst
let ⟨b,m⟩ := boddDiv2 n
cases b <;> rfl
Shreyas Srinivas (Dec 19 2022 at 20:36):
Kevin Buzzard said:
theorem bodd_succ (n : ℕ) : bodd (succ n) = not (bodd n) := by simp only [bodd, boddDiv2] let ⟨b,m⟩ := boddDiv2 n cases b <;> rfl
Yeah this worked. Using simp only also helped with another error. Thanks
Last updated: Dec 20 2023 at 11:08 UTC