Theorem: Nat.multiplicity_two_factorial_lt
File: Mathlib/Data/Nat/Multiplicity.lean

tactic: have h2 := prime_two.prime
state_before: ⊢ ∀ {n : ℕ}, n ≠ 0 → multiplicity 2 n ! < ↑n
state_after: h2 : _root_.Prime 2
⊢ ∀ {n : ℕ}, n ≠ 0 → multiplicity 2 n ! < ↑n

tactic: refine binaryRec ?_ ?_
state_before: h2 : _root_.Prime 2
⊢ ∀ {n : ℕ}, n ≠ 0 → multiplicity 2 n ! < ↑n
state_after: case refine_1
h2 : _root_.Prime 2
⊢ 0 ≠ 0 → multiplicity 2 0! < ↑0

case refine_2
h2 : _root_.Prime 2
⊢ ∀ (b : Bool) (n : ℕ), (n ≠ 0 → multiplicity 2 n ! < ↑n) → bit b n ≠ 0 → multiplicity 2 (bit b n)! < ↑(bit b n)

tactic: exact fun h => False.elim <| h rfl
state_before: case refine_1
h2 : _root_.Prime 2
⊢ 0 ≠ 0 → multiplicity 2 0! < ↑0
state_after: no goals

tactic: intro b n ih h
state_before: case refine_2
h2 : _root_.Prime 2
⊢ ∀ (b : Bool) (n : ℕ), (n ≠ 0 → multiplicity 2 n ! < ↑n) → bit b n ≠ 0 → multiplicity 2 (bit b n)! < ↑(bit b n)
state_after: case refine_2
h2 : _root_.Prime 2
b : Bool
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
h : bit b n ≠ 0
⊢ multiplicity 2 (bit b n)! < ↑(bit b n)

tactic: by_cases hn : n = 0
state_before: case refine_2
h2 : _root_.Prime 2
b : Bool
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
h : bit b n ≠ 0
⊢ multiplicity 2 (bit b n)! < ↑(bit b n)
state_after: case pos
h2 : _root_.Prime 2
b : Bool
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
h : bit b n ≠ 0
hn : n = 0
⊢ multiplicity 2 (bit b n)! < ↑(bit b n)

case neg
h2 : _root_.Prime 2
b : Bool
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
h : bit b n ≠ 0
hn : ¬n = 0
⊢ multiplicity 2 (bit b n)! < ↑(bit b n)

tactic: have : multiplicity 2 (2 * n)! < (2 * n : ℕ) := by
  rw [prime_two.multiplicity_factorial_mul]
  refine (PartENat.add_lt_add_right (ih hn) (PartENat.natCast_ne_top _)).trans_le ?_
  rw [two_mul]
  norm_cast
state_before: case neg
h2 : _root_.Prime 2
b : Bool
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
h : bit b n ≠ 0
hn : ¬n = 0
⊢ multiplicity 2 (bit b n)! < ↑(bit b n)
state_after: case neg
h2 : _root_.Prime 2
b : Bool
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
h : bit b n ≠ 0
hn : ¬n = 0
this : multiplicity 2 (2 * n)! < ↑(2 * n)
⊢ multiplicity 2 (bit b n)! < ↑(bit b n)

tactic: cases b
state_before: case neg
h2 : _root_.Prime 2
b : Bool
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
h : bit b n ≠ 0
hn : ¬n = 0
this : multiplicity 2 (2 * n)! < ↑(2 * n)
⊢ multiplicity 2 (bit b n)! < ↑(bit b n)
state_after: case neg.false
h2 : _root_.Prime 2
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
hn : ¬n = 0
this : multiplicity 2 (2 * n)! < ↑(2 * n)
h : bit false n ≠ 0
⊢ multiplicity 2 (bit false n)! < ↑(bit false n)

case neg.true
h2 : _root_.Prime 2
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
hn : ¬n = 0
this : multiplicity 2 (2 * n)! < ↑(2 * n)
h : bit true n ≠ 0
⊢ multiplicity 2 (bit true n)! < ↑(bit true n)

tactic: subst hn
state_before: case pos
h2 : _root_.Prime 2
b : Bool
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
h : bit b n ≠ 0
hn : n = 0
⊢ multiplicity 2 (bit b n)! < ↑(bit b n)
state_after: case pos
h2 : _root_.Prime 2
b : Bool
ih : 0 ≠ 0 → multiplicity 2 0! < ↑0
h : bit b 0 ≠ 0
⊢ multiplicity 2 (bit b 0)! < ↑(bit b 0)

tactic: simp only [ne_eq, bit_eq_zero, true_and, Bool.not_eq_false] at h
state_before: case pos
h2 : _root_.Prime 2
b : Bool
ih : 0 ≠ 0 → multiplicity 2 0! < ↑0
h : bit b 0 ≠ 0
⊢ multiplicity 2 (bit b 0)! < ↑(bit b 0)
state_after: case pos
h2 : _root_.Prime 2
b : Bool
ih : 0 ≠ 0 → multiplicity 2 0! < ↑0
h : b = true
⊢ multiplicity 2 (bit b 0)! < ↑(bit b 0)

tactic: simp only [h, bit_true, bit1_zero, factorial, mul_one, Nat.isUnit_iff, cast_one]
state_before: case pos
h2 : _root_.Prime 2
b : Bool
ih : 0 ≠ 0 → multiplicity 2 0! < ↑0
h : b = true
⊢ multiplicity 2 (bit b 0)! < ↑(bit b 0)
state_after: case pos
h2 : _root_.Prime 2
b : Bool
ih : 0 ≠ 0 → multiplicity 2 0! < ↑0
h : b = true
⊢ multiplicity 2 (succ 0) < 1

tactic: rw [Prime.multiplicity_one]
state_before: case pos
h2 : _root_.Prime 2
b : Bool
ih : 0 ≠ 0 → multiplicity 2 0! < ↑0
h : b = true
⊢ multiplicity 2 (succ 0) < 1
state_after: case pos
h2 : _root_.Prime 2
b : Bool
ih : 0 ≠ 0 → multiplicity 2 0! < ↑0
h : b = true
⊢ 0 < 1

case pos
h2 : _root_.Prime 2
b : Bool
ih : 0 ≠ 0 → multiplicity 2 0! < ↑0
h : b = true
⊢ Prime 2

tactic: simp only [zero_lt_one]
state_before: case pos
h2 : _root_.Prime 2
b : Bool
ih : 0 ≠ 0 → multiplicity 2 0! < ↑0
h : b = true
⊢ 0 < 1
state_after: no goals

tactic: decide
state_before: case pos
h2 : _root_.Prime 2
b : Bool
ih : 0 ≠ 0 → multiplicity 2 0! < ↑0
h : b = true
⊢ Prime 2
state_after: no goals

tactic: rw [prime_two.multiplicity_factorial_mul]
state_before: h2 : _root_.Prime 2
b : Bool
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
h : bit b n ≠ 0
hn : ¬n = 0
⊢ multiplicity 2 (2 * n)! < ↑(2 * n)
state_after: h2 : _root_.Prime 2
b : Bool
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
h : bit b n ≠ 0
hn : ¬n = 0
⊢ multiplicity 2 n ! + ↑n < ↑(2 * n)

tactic: refine (PartENat.add_lt_add_right (ih hn) (PartENat.natCast_ne_top _)).trans_le ?_
state_before: h2 : _root_.Prime 2
b : Bool
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
h : bit b n ≠ 0
hn : ¬n = 0
⊢ multiplicity 2 n ! + ↑n < ↑(2 * n)
state_after: h2 : _root_.Prime 2
b : Bool
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
h : bit b n ≠ 0
hn : ¬n = 0
⊢ ↑n + ↑n ≤ ↑(2 * n)

tactic: rw [two_mul]
state_before: h2 : _root_.Prime 2
b : Bool
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
h : bit b n ≠ 0
hn : ¬n = 0
⊢ ↑n + ↑n ≤ ↑(2 * n)
state_after: h2 : _root_.Prime 2
b : Bool
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
h : bit b n ≠ 0
hn : ¬n = 0
⊢ ↑n + ↑n ≤ ↑(n + n)

tactic: norm_cast
state_before: h2 : _root_.Prime 2
b : Bool
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
h : bit b n ≠ 0
hn : ¬n = 0
⊢ ↑n + ↑n ≤ ↑(n + n)
state_after: no goals

tactic: simpa [bit0_eq_two_mul n]
state_before: case neg.false
h2 : _root_.Prime 2
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
hn : ¬n = 0
this : multiplicity 2 (2 * n)! < ↑(2 * n)
h : bit false n ≠ 0
⊢ multiplicity 2 (bit false n)! < ↑(bit false n)
state_after: no goals

tactic: suffices multiplicity 2 (2 * n + 1) + multiplicity 2 (2 * n)! < ↑(2 * n) + 1 by
  simpa [multiplicity.mul, h2, prime_two, Nat.bit1_eq_succ_bit0, bit0_eq_two_mul n,
    factorial]
state_before: case neg.true
h2 : _root_.Prime 2
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
hn : ¬n = 0
this : multiplicity 2 (2 * n)! < ↑(2 * n)
h : bit true n ≠ 0
⊢ multiplicity 2 (bit true n)! < ↑(bit true n)
state_after: case neg.true
h2 : _root_.Prime 2
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
hn : ¬n = 0
this : multiplicity 2 (2 * n)! < ↑(2 * n)
h : bit true n ≠ 0
⊢ multiplicity 2 (2 * n + 1) + multiplicity 2 (2 * n)! < ↑(2 * n) + 1

tactic: rw [multiplicity_eq_zero.2 (two_not_dvd_two_mul_add_one n), zero_add]
state_before: case neg.true
h2 : _root_.Prime 2
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
hn : ¬n = 0
this : multiplicity 2 (2 * n)! < ↑(2 * n)
h : bit true n ≠ 0
⊢ multiplicity 2 (2 * n + 1) + multiplicity 2 (2 * n)! < ↑(2 * n) + 1
state_after: case neg.true
h2 : _root_.Prime 2
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
hn : ¬n = 0
this : multiplicity 2 (2 * n)! < ↑(2 * n)
h : bit true n ≠ 0
⊢ multiplicity 2 (2 * n)! < ↑(2 * n) + 1

tactic: refine this.trans ?_
state_before: case neg.true
h2 : _root_.Prime 2
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
hn : ¬n = 0
this : multiplicity 2 (2 * n)! < ↑(2 * n)
h : bit true n ≠ 0
⊢ multiplicity 2 (2 * n)! < ↑(2 * n) + 1
state_after: case neg.true
h2 : _root_.Prime 2
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
hn : ¬n = 0
this : multiplicity 2 (2 * n)! < ↑(2 * n)
h : bit true n ≠ 0
⊢ ↑(2 * n) < ↑(2 * n) + 1

tactic: exact mod_cast lt_succ_self _
state_before: case neg.true
h2 : _root_.Prime 2
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
hn : ¬n = 0
this : multiplicity 2 (2 * n)! < ↑(2 * n)
h : bit true n ≠ 0
⊢ ↑(2 * n) < ↑(2 * n) + 1
state_after: no goals

tactic: simpa [multiplicity.mul, h2, prime_two, Nat.bit1_eq_succ_bit0, bit0_eq_two_mul n,
  factorial]
state_before: h2 : _root_.Prime 2
n : ℕ
ih : n ≠ 0 → multiplicity 2 n ! < ↑n
hn : ¬n = 0
this✝ : multiplicity 2 (2 * n)! < ↑(2 * n)
h : bit true n ≠ 0
this : multiplicity 2 (2 * n + 1) + multiplicity 2 (2 * n)! < ↑(2 * n) + 1
⊢ multiplicity 2 (bit true n)! < ↑(bit true n)
state_after: no goals