Zulip Chat Archive
Stream: lean4
Topic: Idiomatic way to split into cases 0, 1, and 2≤
Markus Schmaus (May 12 2024 at 11:13):
A couple of times now I had n : ℕ
and wanted to split my proof into three cases, n = 0
, n = 1
, and 2 ≤ n
. I can get there using multiple by_cases
, but I wonder if there is a more idiomatic way to get there. The most recent case also works as an mwe
import Mathlib
theorem Nat.log2_eq_size_pred (n : Nat) : log2 n = size n - 1 := by
induction n using Nat.binaryRec with
| z => rfl
| f b n ih =>
unfold log2
sorry
In this case I want to split into the three cases for bit b n
.
Markus Schmaus (May 12 2024 at 11:15):
This mwe uses Mathlib (due to docs#Nat.size), but I would assume that splitting into those three cases could be done without relying on Mathlib.
Henrik Böving (May 12 2024 at 11:19):
You can use the normal programming match
in tactics as well to pattern match on some number arbitrarily
Damiano Testa (May 12 2024 at 11:23):
Also, rcases n with _|_|n
may get you to the right place (untested).
Markus Schmaus (May 12 2024 at 11:25):
I tried match
, and I can split it into three cases, but how to I get the hypothesis 2 ≤ bit b n
in the last case?
import Mathlib
theorem Nat.log2_eq_size_pred (n : Nat) : log2 n = size n - 1 := by
induction n using Nat.binaryRec with
| z => rfl
| f b n ih =>
unfold log2
match m : bit b n with
| 0 => rfl
| 1 => rfl
| x =>
rw [← m]
sorry
Henrik Böving (May 12 2024 at 11:36):
import Mathlib
theorem Nat.log2_eq_size_pred (n : Nat) : log2 n = size n - 1 := by
induction n using Nat.binaryRec with
| z => rfl
| f b n ih =>
unfold log2
match h : bit b n with
| 0 => rfl
| 1 => rfl
| x + 2 => -- note that we explicitly match on x + 2 here and lean understands that the other cases are not possible
-- You could explicitly derive it now but we can also just do
simp
sorry
Markus Schmaus (May 12 2024 at 12:12):
This is how I completed the proof using match
, rcases n with _|_|n
works as well.
import Mathlib
namespace Nat
@[simp]
theorem bit_div_two {b : Bool} {n : Nat} : bit b n / 2 = n := by
cases b <;> simp only [bit_false, bit_true, Nat.bit1_div_two, Nat.bit0_div_two]
@[simp]
theorem bit_true_zero : bit true 0 = 1 := rfl
@[simp]
theorem bit_false_zero : bit false 0 = 0 := rfl
theorem log2_eq_size_pred (n : Nat) : log2 n = size n - 1 := by
induction n using Nat.binaryRec with
| z => rfl
| f b n ih =>
unfold log2
match hm : bit b n with
| 0 => rfl
| 1 => rfl
| x + 2 =>
simp only [ge_iff_le, le_add_iff_nonneg_left, _root_.zero_le, ↓reduceIte]
simp only [succ_eq_add_one] at hm
rw [← hm]
have : Nat.bit b n ≠ 0 := by omega
simp only [bit_div_two, ih, Nat.size_bit this, succ_eq_add_one, add_tsub_cancel_right]
match n with
| 0 =>
induction b <;> simp at hm
| m + 1 =>
apply Nat.sub_add_cancel
apply Nat.size_le_size (m := 1)
omega
Eric Wieser (May 12 2024 at 12:33):
Are you looking for docs#Nat.binaryRec' (the primed one)?
Markus Schmaus (May 12 2024 at 15:07):
I see that docs#Nat.binaryRec' allows me to replace the induction b <;> simp at hm
line by a simple simp_all
, but I don't see how it would have helped me with any of the case distinctions I made.
Yuyang Zhao (May 13 2024 at 04:54):
import Mathlib
theorem Nat.log2_eq_size_pred (n : Nat) : log2 n = size n - 1 := by
induction n using Nat.binaryRecFromOne with
| z₀ | z₁ => rfl
| f b n n0 ih =>
have : 2 ≤ bit b n := by
rw [bit_val]; omega
sorry
Last updated: May 02 2025 at 03:31 UTC