Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - chore: bump Std, changes for leanprover/std4#366 #8700

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions Mathlib/Data/BitVec/Defs.lean
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ namespace Std.BitVec
/-! ### Arithmetic operators -/

#align bitvec.neg Std.BitVec.neg
/-- Add with carry (no overflow) -/
def adc {n} (x y : BitVec n) (c : Bool) : BitVec (n+1) :=
ofFin (x.toNat + y.toNat + c.toNat)
/-- Add with carry (no overflow)

See also `Std.BitVec.adc`, which stores the carry bit separately. -/
def adc' {n} (x y : BitVec n) (c : Bool) : BitVec (n+1) :=
let a := x.adc y c; .cons a.1 a.2
#align bitvec.adc Std.BitVec.adc

#align bitvec.add Std.BitVec.add
Expand Down
37 changes: 9 additions & 28 deletions Mathlib/Data/BitVec/Lemmas.lean
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,10 @@ theorem toNat_inj {x y : BitVec w} : x.toNat = y.toNat ↔ x = y :=
theorem toNat_lt_toNat {x y : BitVec w} : x.toNat < y.toNat ↔ x < y :=
Iff.rfl

@[simp]
lemma ofNat_eq_mod_two_pow (n : Nat) : (BitVec.ofNat w n).toNat = n % 2^w := rfl

lemma toNat_ofNat {m} (h : m < 2^w) : (BitVec.ofNat w m).toNat = m := Fin.val_cast_of_lt h

@[simp]
lemma toNat_ofFin (x : Fin (2^w)) : (ofFin x).toNat = x.val := rfl
attribute [simp] toNat_ofNat toNat_ofFin

theorem toNat_append (msbs : BitVec w) (lsbs : BitVec v) :
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(msbs ++ lsbs).toNat = msbs.toNat <<< v ||| lsbs.toNat := by
rcases msbs with ⟨msbs, hm⟩
rcases lsbs with ⟨lsbs, hl⟩
simp only [HAppend.hAppend, append, toNat_ofFin]
rw [toNat_ofNat (Nat.add_comm w v ▸ append_lt hl hm)]
lemma toNat_ofNat_of_lt {m} (h : m < 2^w) : (BitVec.ofNat w m).toNat = m := by
simp only [toNat_ofNat, mod_eq_of_lt h]

#noalign bitvec.bits_to_nat_to_bool

Expand All @@ -60,14 +50,9 @@ lemma extractLsb_eq {w : ℕ} (hi lo : ℕ) (a : BitVec w) :

theorem toNat_extractLsb' {i j} {x : BitVec w} :
(extractLsb' i j x).toNat = x.toNat / 2 ^ i % (2 ^ j) := by
simp only [extractLsb', ofNat_eq_mod_two_pow, shiftRight_eq_div_pow]

theorem getLsb_eq_testBit {i} {x : BitVec w} : getLsb x i = x.toNat.testBit i := by
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where did this go?

Copy link
Collaborator

@alexkeizer alexkeizer Nov 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The RHS is now the definition of getLsb, so this is replaced by unfolding getLsb, no need for a theorem

simp only [getLsb, Nat.shiftLeft_eq, one_mul, Nat.and_two_pow]
cases' testBit (BitVec.toNat x) i
<;> simp [pos_iff_ne_zero.mp (two_pow_pos i)]
simp only [extractLsb', toNat_ofNat, shiftRight_eq_div_pow]

theorem ofFin_val {n : ℕ} (i : Fin <| 2 ^ n) : (ofFin i).toNat = i.val := by
theorem ofFin_val {n : ℕ} (i : Fin <| 2 ^ n) : (ofFin i).toNat = i.val :=
rfl
#align bitvec.of_fin_val Std.BitVec.ofFin_val

Expand All @@ -91,16 +76,12 @@ theorem decide_addLsb_mod_two {x b} : decide (addLsb x b % 2 = 1) = b := by
simp [addLsb]
#align bitvec.to_bool_add_lsb_mod_two Std.BitVec.decide_addLsb_mod_two

@[simp]
lemma ofNat_toNat (x : BitVec w) : BitVec.ofNat w x.toNat = x := by
rcases x with ⟨x⟩
simp [BitVec.ofNat]
apply Fin.cast_val_eq_self x
#align bitvec.of_nat_to_nat Std.BitVec.ofNat_toNat
lemma ofNat_toNat' (x : BitVec w) : (x.toNat)#w = x := by
rw [ofNat_toNat, truncate_eq]

lemma ofNat_toNat' (x : BitVec w) (h : w = v):
lemma ofNat_toNat_of_eq (x : BitVec w) (h : w = v):
BitVec.ofNat v x.toNat = x.cast h := by
cases h; rw [ofNat_toNat, cast_eq]
cases h; rw [ofNat_toNat', cast_eq]

theorem toFin_val {n : ℕ} (v : BitVec n) : (toFin v : ℕ) = v.toNat := by
rfl
Expand Down
16 changes: 0 additions & 16 deletions Mathlib/Data/Bool/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,7 @@ theorem of_decide_iff {p : Prop} [Decidable p] : decide p ↔ p :=
coe_decide p
#align bool.of_to_bool_iff Bool.of_decide_iff

@[simp]
theorem true_eq_decide_iff {p : Prop} [Decidable p] : true = decide p ↔ p :=
eq_comm.trans of_decide_iff
#align bool.tt_eq_to_bool_iff Bool.true_eq_decide_iff

@[simp]
theorem false_eq_decide_iff {p : Prop} [Decidable p] : false = decide p ↔ ¬p :=
eq_comm.trans (decide_false_iff _)
#align bool.ff_eq_to_bool_iff Bool.false_eq_decide_iff

theorem decide_not (p : Prop) [Decidable p] : (decide ¬p) = !(decide p) := by
Expand Down Expand Up @@ -308,22 +301,13 @@ theorem right_le_or : ∀ x y : Bool, y ≤ (x || y) := by decide
theorem or_le : ∀ {x y z}, x ≤ z → y ≤ z → (x || y) ≤ z := by decide
#align bool.bor_le Bool.or_le

/-- convert a `Bool` to a `ℕ`, `false -> 0`, `true -> 1` -/
def toNat (b : Bool) : Nat :=
cond b 1 0
#align bool.to_nat Bool.toNat

lemma toNat_le_one (b : Bool) : b.toNat ≤ 1 := by
cases b <;> decide

/-- convert a `ℕ` to a `Bool`, `0 -> false`, everything else -> `true` -/
def ofNat (n : Nat) : Bool :=
decide (n ≠ 0)
#align bool.of_nat Bool.ofNat

@[simp] lemma toNat_true : toNat true = 1 := rfl
@[simp] lemma toNat_false : toNat false = 0 := rfl

@[simp] lemma toNat_beq_zero (b : Bool) : (b.toNat == 0) = !b := by cases b <;> rfl
@[simp] lemma toNat_bne_zero (b : Bool) : (b.toNat != 0) = b := by simp [bne]
@[simp] lemma toNat_beq_one (b : Bool) : (b.toNat == 1) = b := by cases b <;> rfl
Expand Down
10 changes: 5 additions & 5 deletions Mathlib/Data/Int/Bitwise.lean
Original file line number Diff line number Diff line change
Expand Up @@ -407,15 +407,15 @@ attribute [local simp] Int.zero_div

theorem shiftLeft_add : ∀ (m : ℤ) (n : ℕ) (k : ℤ), m <<< (n + k) = (m <<< (n : ℤ)) <<< k
| (m : ℕ), n, (k : ℕ) =>
congr_arg ofNat (by simp [Nat.pow_add, mul_assoc])
congr_arg ofNat (by simp [Nat.shiftLeft_eq, Nat.pow_add, mul_assoc])
| -[m+1], n, (k : ℕ) => congr_arg negSucc (Nat.shiftLeft'_add _ _ _ _)
| (m : ℕ), n, -[k+1] =>
subNatNat_elim n k.succ (fun n k i => (↑m) <<< i = (Nat.shiftLeft' false m n) >>> k)
(fun (i n : ℕ) =>
by dsimp; simp [- Nat.shiftLeft_eq, ← Nat.shiftLeft_sub _ , add_tsub_cancel_left])
by dsimp; simp [← Nat.shiftLeft_sub _ , add_tsub_cancel_left])
fun i n => by
dsimp
simp [- Nat.shiftLeft_eq, Nat.shiftLeft_zero, Nat.shiftRight_add, ← Nat.shiftLeft_sub]
simp [Nat.shiftLeft_zero, Nat.shiftRight_add, ← Nat.shiftLeft_sub]
rfl
| -[m+1], n, -[k+1] =>
subNatNat_elim n k.succ
Expand All @@ -433,7 +433,7 @@ theorem shiftLeft_sub (m : ℤ) (n : ℕ) (k : ℤ) : m <<< (n - k) = (m <<< (n
#align int.shiftl_sub Int.shiftLeft_sub

theorem shiftLeft_eq_mul_pow : ∀ (m : ℤ) (n : ℕ), m <<< (n : ℤ) = m * (2 ^ n : ℕ)
| (m : ℕ), _ => congr_arg ((↑) : ℕ → ℤ) (by simp)
| (m : ℕ), _ => congr_arg ((↑) : ℕ → ℤ) (by simp [Nat.shiftLeft_eq])
| -[_+1], _ => @congr_arg ℕ ℤ _ _ (fun i => -i) (Nat.shiftLeft'_tt_eq_mul_pow _ _)
#align int.shiftl_eq_mul_pow Int.shiftLeft_eq_mul_pow

Expand All @@ -445,7 +445,7 @@ theorem shiftRight_eq_div_pow : ∀ (m : ℤ) (n : ℕ), m >>> (n : ℤ) = m / (
#align int.shiftr_eq_div_pow Int.shiftRight_eq_div_pow

theorem one_shiftLeft (n : ℕ) : 1 <<< (n : ℤ) = (2 ^ n : ℕ) :=
congr_arg ((↑) : ℕ → ℤ) (by simp)
congr_arg ((↑) : ℕ → ℤ) (by simp [Nat.shiftLeft_eq])
#align int.one_shiftl Int.one_shiftLeft

@[simp]
Expand Down
7 changes: 4 additions & 3 deletions Mathlib/Data/Nat/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -838,11 +838,12 @@ theorem lt_mul_div_succ (m : ℕ) {n : ℕ} (n0 : 0 < n) : m < n * (m / n + 1) :
exact lt_succ_self _
#align nat.lt_mul_div_succ Nat.lt_mul_div_succ

theorem mul_add_mod (a b c : ℕ) : (a * b + c) % b = c % b := by simp [Nat.add_mod]
#align nat.mul_add_mod Nat.mul_add_mod
-- TODO: Std4 claimed this name but flipped the order of multiplication
theorem mul_add_mod' (a b c : ℕ) : (a * b + c) % b = c % b := by rw [mul_comm, Nat.mul_add_mod]
#align nat.mul_add_mod Nat.mul_add_mod'

theorem mul_add_mod_of_lt {a b c : ℕ} (h : c < b) : (a * b + c) % b = c := by
rw [Nat.mul_add_mod, Nat.mod_eq_of_lt h]
rw [Nat.mul_add_mod', Nat.mod_eq_of_lt h]
#align nat.mul_add_mod_of_lt Nat.mul_add_mod_of_lt

theorem pred_eq_self_iff {n : ℕ} : n.pred = n ↔ n = 0 := by
Expand Down
71 changes: 17 additions & 54 deletions Mathlib/Data/Nat/Bitwise.lean
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,7 @@ theorem xor_bit : ∀ a m b n, bit a m ^^^ bit b n = bit (bne a b) (m ^^^ n) :=
bitwise_bit
#align nat.lxor_bit Nat.xor_bit

@[simp]
theorem testBit_bitwise {f : Bool → Bool → Bool} (h : f false false = false) (m n k) :
testBit (bitwise f m n) k = f (testBit m k) (testBit n k) := by
induction' k with k ih generalizing m n
<;> cases' m using bitCasesOn with a m
<;> cases' n using bitCasesOn with b n
<;> rw [bitwise_bit h]
· simp [testBit_zero]
· simp [testBit_succ, ih]
attribute [simp] Nat.testBit_bitwise
#align nat.test_bit_bitwise Nat.testBit_bitwise

@[simp]
Expand All @@ -152,9 +144,7 @@ theorem testBit_ldiff : ∀ m n k, testBit (ldiff m n) k = (testBit m k && not (
testBit_bitwise rfl
#align nat.test_bit_ldiff Nat.testBit_ldiff

@[simp]
theorem testBit_xor : ∀ m n k, testBit (m ^^^ n) k = bne (testBit m k) (testBit n k) :=
testBit_bitwise rfl
attribute [simp] testBit_xor
#align nat.test_bit_lxor Nat.testBit_xor

end
Expand Down Expand Up @@ -217,31 +207,19 @@ theorem zero_of_testBit_eq_false {n : ℕ} (h : ∀ i, testBit n i = false) : n
theorem testBit_eq_false_of_lt {n i} (h : n < 2 ^ i) : n.testBit i = false := by
simp [testBit, shiftRight_eq_div_pow, Nat.div_eq_of_lt h]

@[simp]
theorem zero_testBit (i : ℕ) : testBit 0 i = false := by
simp only [testBit, zero_shiftRight, bodd_zero]
#align nat.zero_test_bit Nat.zero_testBit

/-- The ith bit is the ith element of `n.bits`. -/
theorem testBit_eq_inth (n i : ℕ) : n.testBit i = n.bits.getI i := by
induction' i with i ih generalizing n
· simp [testBit, bodd_eq_bits_head, List.getI_zero_eq_headI]
· simp only [testBit, zero_eq, shiftRight_zero, and_one_is_mod, mod_two_of_bodd,
bodd_eq_bits_head, List.getI_zero_eq_headI]
cases List.headI (bits n) <;> rfl
conv_lhs => rw [← bit_decomp n]
rw [testBit_succ, ih n.div2, div2_bits_eq_tail]
cases n.bits <;> simp
#align nat.test_bit_eq_inth Nat.testBit_eq_inth

/-- Bitwise extensionality: Two numbers agree if they agree at every bit position. -/
theorem eq_of_testBit_eq {n m : ℕ} (h : ∀ i, testBit n i = testBit m i) : n = m := by
induction' n using Nat.binaryRec with b n hn generalizing m
· simp only [zero_testBit] at h
exact (zero_of_testBit_eq_false fun i => (h i).symm).symm
induction' m using Nat.binaryRec with b' m
· simp only [zero_testBit] at h
exact zero_of_testBit_eq_false h
suffices h' : n = m by
rw [h', show b = b' by simpa using h 0]
exact hn fun i => by convert h (i + 1) using 1 <;> rw [testBit_succ]
Comment on lines -234 to -244
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This proof looks much nicer to me than the one (for the converse, ne_implies_bit_diff) that landed in Std4 :(.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that is inevitable, since we don't have Nat.binaryRec in std yet (at least, leanprover-community/batteries#314 is still open, and I'm not aware of any alternative PRs)

#align nat.eq_of_test_bit_eq Nat.eq_of_testBit_eq

theorem exists_most_significant_bit {n : ℕ} (h : n ≠ 0) :
Expand Down Expand Up @@ -295,20 +273,20 @@ theorem lt_of_testBit {n m : ℕ} (i : ℕ) (hn : testBit n i = false) (hm : tes

@[simp]
theorem testBit_two_pow_self (n : ℕ) : testBit (2 ^ n) n = true := by
rw [testBit, shiftRight_eq_div_pow, Nat.div_self (pow_pos (α := ℕ) zero_lt_two n), bodd_one]
rw [testBit, shiftRight_eq_div_pow, Nat.div_self (pow_pos (α := ℕ) zero_lt_two n)]
simp
#align nat.test_bit_two_pow_self Nat.testBit_two_pow_self

theorem testBit_two_pow_of_ne {n m : ℕ} (hm : n ≠ m) : testBit (2 ^ n) m = false := by
rw [testBit, shiftRight_eq_div_pow]
cases' hm.lt_or_lt with hm hm
· rw [Nat.div_eq_of_lt, bodd_zero]
exact Nat.pow_lt_pow_of_lt_right one_lt_two hm
· rw [Nat.div_eq_of_lt]
· simp
· exact Nat.pow_lt_pow_of_lt_right one_lt_two hm
· rw [pow_div hm.le zero_lt_two, ← tsub_add_cancel_of_le (succ_le_of_lt <| tsub_pos_of_lt hm)]
-- Porting note: XXX why does this make it work?
rw [(rfl : succ 0 = 1)]
simp only [ge_iff_le, tsub_le_iff_right, pow_succ, bodd_mul,
Bool.and_eq_false_eq_eq_false_or_eq_false, or_true]
exact Or.inr rfl
simp [pow_succ, and_one_is_mod, mul_mod_left]
#align nat.test_bit_two_pow_of_ne Nat.testBit_two_pow_of_ne

theorem testBit_two_pow (n m : ℕ) : testBit (2 ^ n) m = (n = m) := by
Expand Down Expand Up @@ -372,25 +350,10 @@ theorem zero_xor (n : ℕ) : 0 ^^^ n = n := by simp [HXor.hXor, Xor.xor, xor]
theorem xor_zero (n : ℕ) : n ^^^ 0 = n := by simp [HXor.hXor, Xor.xor, xor]
#align nat.lxor_zero Nat.xor_zero

@[simp]
theorem zero_land (n : ℕ) : 0 &&& n = 0 := by
simp only [HAnd.hAnd, AndOp.and, land, bitwise_zero_left, ite_false, Bool.and_true];
#align nat.zero_land Nat.zero_land

@[simp]
theorem land_zero (n : ℕ) : n &&& 0 = 0 := by
simp only [HAnd.hAnd, AndOp.and, land, bitwise_zero_right, ite_false, Bool.and_false]
#align nat.land_zero Nat.land_zero

@[simp]
theorem zero_lor (n : ℕ) : 0 ||| n = n := by
simp only [HOr.hOr, OrOp.or, lor, bitwise_zero_left, ite_true, Bool.or_true]
#align nat.zero_lor Nat.zero_lor

@[simp]
theorem lor_zero (n : ℕ) : n ||| 0 = n := by
simp only [HOr.hOr, OrOp.or, lor, bitwise_zero_right, ite_true, Bool.or_false]
#align nat.lor_zero Nat.lor_zero
#align nat.zero_land Nat.zero_and
#align nat.land_zero Nat.and_zero
#align nat.zero_lor Nat.zero_or
#align nat.lor_zero Nat.or_zero


/-- Proving associativity of bitwise operations in general essentially boils down to a huge case
Expand Down Expand Up @@ -488,11 +451,11 @@ theorem xor_trichotomy {a b c : ℕ} (h : a ≠ b ^^^ c) :
all_goals
exact lt_of_testBit i (by
-- Porting note: this was originally `simp [h, hi]`
rw [Nat.testBit_xor, h, Bool.bne_eq_xor, Bool.true_xor,hi]
rw [Nat.testBit_xor, h, Bool.xor, Bool.true_xor, hi]
rfl
) h fun j hj => by
-- Porting note: this was originally `simp [hi' _ hj]`
rw [Nat.testBit_xor, hi' _ hj, Bool.bne_eq_xor, Bool.xor_false, eq_self_iff_true]
rw [Nat.testBit_xor, hi' _ hj, Bool.xor, Bool.xor_false, eq_self_iff_true]
trivial
#align nat.lxor_trichotomy Nat.xor_trichotomy

Expand Down
5 changes: 0 additions & 5 deletions Mathlib/Data/Nat/Order/Lemmas.lean
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,6 @@ theorem le_of_lt_add_of_dvd (h : a < b + n) : n ∣ a → n ∣ b → a ≤ b :=
exact mul_le_mul_left' (lt_succ_iff.1 <| lt_of_mul_lt_mul_left h bot_le) _
#align nat.le_of_lt_add_of_dvd Nat.le_of_lt_add_of_dvd

@[simp]
theorem mod_div_self (m n : ℕ) : m % n / n = 0 := by
cases n
· exact (m % 0).div_zero
· case succ n => exact Nat.div_eq_of_lt (m.mod_lt n.succ_pos)
#align nat.mod_div_self Nat.mod_div_self

/-- `n` is not divisible by `a` iff it is between `a * k` and `a * (k + 1)` for some `k`. -/
Expand Down
5 changes: 1 addition & 4 deletions Mathlib/Data/Nat/Size.lean
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ theorem shiftLeft'_tt_eq_mul_pow (m) : ∀ n, shiftLeft' true m n + 1 = (m + 1)
end

#align nat.one_shiftl Nat.one_shiftLeft

theorem zero_shiftLeft (n) : 0 <<< n = 0 := by simp
#align nat.zero_shiftl Nat.zero_shiftLeft

#align nat.shiftr_eq_div_pow Nat.shiftRight_eq_div_pow

theorem shiftLeft'_ne_zero_left (b) {m} (h : m ≠ 0) (n) : shiftLeft' b m n ≠ 0 := by
Expand Down Expand Up @@ -118,7 +115,7 @@ theorem lt_size_self (n : ℕ) : n < 2 ^ size n := by
by_cases h : bit b n = 0
· apply this h
rw [size_bit h, shiftLeft_succ, shiftLeft_eq, one_mul, ← bit0_val]
exact bit_lt_bit0 _ (by simpa [shiftRight_eq_div_pow] using IH)
exact bit_lt_bit0 _ (by simpa [shiftLeft_eq, shiftRight_eq_div_pow] using IH)
#align nat.lt_size_self Nat.lt_size_self

theorem size_le {m n : ℕ} : size m ≤ n ↔ m < 2 ^ n :=
Expand Down
29 changes: 10 additions & 19 deletions Mathlib/Data/Num/Lemmas.lean
Original file line number Diff line number Diff line change
Expand Up @@ -970,28 +970,19 @@ theorem castNum_shiftRight (m : Num) (n : Nat) : ↑(m >>> n) = (m : ℕ) >>> (n
@[simp]
theorem castNum_testBit (m n) : testBit m n = Nat.testBit m n := by
-- Porting note: `unfold` → `dsimp only`
cases m <;> dsimp only [testBit, Nat.testBit]
cases m <;> dsimp only [testBit]
case zero =>
change false = Nat.bodd (0 >>> n)
rw [Nat.zero_shiftRight]
rfl
rw [show (Num.zero : Nat) = 0 from rfl, Nat.zero_testBit]
case pos m =>
induction' n with n IH generalizing m <;> cases' m with m m <;> dsimp only [PosNum.testBit]
rw [cast_pos]
induction' n with n IH generalizing m <;> cases' m with m m
<;> dsimp only [PosNum.testBit, Nat.zero_eq]
· rfl
· exact (Nat.bodd_bit _ _).symm
· exact (Nat.bodd_bit _ _).symm
· change false = Nat.bodd (1 >>> (n + 1))
rw [add_comm, Nat.shiftRight_add]
change false = Nat.bodd (0 >>> n)
rw [Nat.zero_shiftRight]; rfl
· change PosNum.testBit m n = Nat.bodd ((Nat.bit true m) >>> (n + 1))
rw [add_comm, Nat.shiftRight_add]
simp only [Nat.shiftRight_succ, Nat.shiftRight_zero, ← Nat.div2_val, Nat.div2_bit]
apply IH
· change PosNum.testBit m n = Nat.bodd ((Nat.bit false m) >>> (n + 1))
rw [add_comm, Nat.shiftRight_add]
simp only [Nat.shiftRight_succ, Nat.shiftRight_zero, ← Nat.div2_val, Nat.div2_bit]
apply IH
· rw [PosNum.cast_bit1, ← Nat.bit_true, Nat.testBit_zero]
· rw [PosNum.cast_bit0, ← Nat.bit_false, Nat.testBit_zero]
· rw [PosNum.cast_one', ← bit1_zero, ← Nat.bit_true, Nat.testBit_succ, Nat.zero_testBit]
· rw [PosNum.cast_bit1, ← Nat.bit_true, Nat.testBit_succ, IH]
· rw [PosNum.cast_bit0, ← Nat.bit_false, Nat.testBit_succ, IH]
#align num.test_bit_to_nat Num.castNum_testBit

end Num
Expand Down
Loading