[GOAL]
⊢ catalan 0 = 1
[PROOFSTEP]
rw [catalan]
[GOAL]
n : ℕ
⊢ catalan (n + 1) = ∑ i : Fin (Nat.succ n), catalan ↑i * catalan (n - ↑i)
[PROOFSTEP]
rw [catalan]
[GOAL]
n : ℕ
⊢ catalan (n + 1) = ∑ ij in Nat.antidiagonal n, catalan ij.fst * catalan ij.snd
[PROOFSTEP]
rw [catalan_succ, Nat.sum_antidiagonal_eq_sum_range_succ (fun x y => catalan x * catalan y) n, sum_range]
[GOAL]
⊢ catalan 1 = 1
[PROOFSTEP]
simp [catalan_succ]
[GOAL]
n i : ℕ
h : i ≤ n
⊢ gosperCatalan (n + 1) (i + 1) - gosperCatalan (n + 1) i =
    ↑(Nat.centralBinom i) / (↑i + 1) * ↑(Nat.centralBinom (n - i)) / (↑n - ↑i + 1)
[PROOFSTEP]
have l₁ : (n : ℚ) + 1 ≠ 0 := by norm_cast; exact n.succ_ne_zero
[GOAL]
n i : ℕ
h : i ≤ n
⊢ ↑n + 1 ≠ 0
[PROOFSTEP]
norm_cast
[GOAL]
n i : ℕ
h : i ≤ n
⊢ ¬n + 1 = 0
[PROOFSTEP]
exact n.succ_ne_zero
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
⊢ gosperCatalan (n + 1) (i + 1) - gosperCatalan (n + 1) i =
    ↑(Nat.centralBinom i) / (↑i + 1) * ↑(Nat.centralBinom (n - i)) / (↑n - ↑i + 1)
[PROOFSTEP]
have l₂ : (n : ℚ) + 1 + 1 ≠ 0 := by norm_cast; exact (n + 1).succ_ne_zero
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
⊢ ↑n + 1 + 1 ≠ 0
[PROOFSTEP]
norm_cast
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
⊢ ¬n + 1 + 1 = 0
[PROOFSTEP]
exact (n + 1).succ_ne_zero
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
⊢ gosperCatalan (n + 1) (i + 1) - gosperCatalan (n + 1) i =
    ↑(Nat.centralBinom i) / (↑i + 1) * ↑(Nat.centralBinom (n - i)) / (↑n - ↑i + 1)
[PROOFSTEP]
have l₃ : (i : ℚ) + 1 ≠ 0 := by norm_cast; exact i.succ_ne_zero
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
⊢ ↑i + 1 ≠ 0
[PROOFSTEP]
norm_cast
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
⊢ ¬i + 1 = 0
[PROOFSTEP]
exact i.succ_ne_zero
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
l₃ : ↑i + 1 ≠ 0
⊢ gosperCatalan (n + 1) (i + 1) - gosperCatalan (n + 1) i =
    ↑(Nat.centralBinom i) / (↑i + 1) * ↑(Nat.centralBinom (n - i)) / (↑n - ↑i + 1)
[PROOFSTEP]
have l₄ : (n : ℚ) - i + 1 ≠ 0 := by norm_cast; exact (n - i).succ_ne_zero
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
l₃ : ↑i + 1 ≠ 0
⊢ ↑n - ↑i + 1 ≠ 0
[PROOFSTEP]
norm_cast
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
l₃ : ↑i + 1 ≠ 0
⊢ ¬n - i + 1 = 0
[PROOFSTEP]
exact (n - i).succ_ne_zero
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
l₃ : ↑i + 1 ≠ 0
l₄ : ↑n - ↑i + 1 ≠ 0
⊢ gosperCatalan (n + 1) (i + 1) - gosperCatalan (n + 1) i =
    ↑(Nat.centralBinom i) / (↑i + 1) * ↑(Nat.centralBinom (n - i)) / (↑n - ↑i + 1)
[PROOFSTEP]
have h₁ := (mul_div_cancel_left (↑(Nat.centralBinom (i + 1))) l₃).symm
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
l₃ : ↑i + 1 ≠ 0
l₄ : ↑n - ↑i + 1 ≠ 0
h₁ : ↑(Nat.centralBinom (i + 1)) = (↑i + 1) * ↑(Nat.centralBinom (i + 1)) / (↑i + 1)
⊢ gosperCatalan (n + 1) (i + 1) - gosperCatalan (n + 1) i =
    ↑(Nat.centralBinom i) / (↑i + 1) * ↑(Nat.centralBinom (n - i)) / (↑n - ↑i + 1)
[PROOFSTEP]
have h₂ := (mul_div_cancel_left (↑(Nat.centralBinom (n - i + 1))) l₄).symm
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
l₃ : ↑i + 1 ≠ 0
l₄ : ↑n - ↑i + 1 ≠ 0
h₁ : ↑(Nat.centralBinom (i + 1)) = (↑i + 1) * ↑(Nat.centralBinom (i + 1)) / (↑i + 1)
h₂ : ↑(Nat.centralBinom (n - i + 1)) = (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) / (↑n - ↑i + 1)
⊢ gosperCatalan (n + 1) (i + 1) - gosperCatalan (n + 1) i =
    ↑(Nat.centralBinom i) / (↑i + 1) * ↑(Nat.centralBinom (n - i)) / (↑n - ↑i + 1)
[PROOFSTEP]
have h₃ : ((i : ℚ) + 1) * (i + 1).centralBinom = 2 * (2 * i + 1) * i.centralBinom := by
  exact_mod_cast Nat.succ_mul_centralBinom_succ i
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
l₃ : ↑i + 1 ≠ 0
l₄ : ↑n - ↑i + 1 ≠ 0
h₁ : ↑(Nat.centralBinom (i + 1)) = (↑i + 1) * ↑(Nat.centralBinom (i + 1)) / (↑i + 1)
h₂ : ↑(Nat.centralBinom (n - i + 1)) = (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) / (↑n - ↑i + 1)
⊢ (↑i + 1) * ↑(Nat.centralBinom (i + 1)) = 2 * (2 * ↑i + 1) * ↑(Nat.centralBinom i)
[PROOFSTEP]
exact_mod_cast Nat.succ_mul_centralBinom_succ i
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
l₃ : ↑i + 1 ≠ 0
l₄ : ↑n - ↑i + 1 ≠ 0
h₁ : ↑(Nat.centralBinom (i + 1)) = (↑i + 1) * ↑(Nat.centralBinom (i + 1)) / (↑i + 1)
h₂ : ↑(Nat.centralBinom (n - i + 1)) = (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) / (↑n - ↑i + 1)
h₃ : (↑i + 1) * ↑(Nat.centralBinom (i + 1)) = 2 * (2 * ↑i + 1) * ↑(Nat.centralBinom i)
⊢ gosperCatalan (n + 1) (i + 1) - gosperCatalan (n + 1) i =
    ↑(Nat.centralBinom i) / (↑i + 1) * ↑(Nat.centralBinom (n - i)) / (↑n - ↑i + 1)
[PROOFSTEP]
have h₄ : ((n : ℚ) - i + 1) * (n - i + 1).centralBinom = 2 * (2 * (n - i) + 1) * (n - i).centralBinom := by
  exact_mod_cast Nat.succ_mul_centralBinom_succ (n - i)
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
l₃ : ↑i + 1 ≠ 0
l₄ : ↑n - ↑i + 1 ≠ 0
h₁ : ↑(Nat.centralBinom (i + 1)) = (↑i + 1) * ↑(Nat.centralBinom (i + 1)) / (↑i + 1)
h₂ : ↑(Nat.centralBinom (n - i + 1)) = (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) / (↑n - ↑i + 1)
h₃ : (↑i + 1) * ↑(Nat.centralBinom (i + 1)) = 2 * (2 * ↑i + 1) * ↑(Nat.centralBinom i)
⊢ (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) = 2 * (2 * (↑n - ↑i) + 1) * ↑(Nat.centralBinom (n - i))
[PROOFSTEP]
exact_mod_cast Nat.succ_mul_centralBinom_succ (n - i)
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
l₃ : ↑i + 1 ≠ 0
l₄ : ↑n - ↑i + 1 ≠ 0
h₁ : ↑(Nat.centralBinom (i + 1)) = (↑i + 1) * ↑(Nat.centralBinom (i + 1)) / (↑i + 1)
h₂ : ↑(Nat.centralBinom (n - i + 1)) = (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) / (↑n - ↑i + 1)
h₃ : (↑i + 1) * ↑(Nat.centralBinom (i + 1)) = 2 * (2 * ↑i + 1) * ↑(Nat.centralBinom i)
h₄ : (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) = 2 * (2 * (↑n - ↑i) + 1) * ↑(Nat.centralBinom (n - i))
⊢ gosperCatalan (n + 1) (i + 1) - gosperCatalan (n + 1) i =
    ↑(Nat.centralBinom i) / (↑i + 1) * ↑(Nat.centralBinom (n - i)) / (↑n - ↑i + 1)
[PROOFSTEP]
simp only [gosperCatalan]
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
l₃ : ↑i + 1 ≠ 0
l₄ : ↑n - ↑i + 1 ≠ 0
h₁ : ↑(Nat.centralBinom (i + 1)) = (↑i + 1) * ↑(Nat.centralBinom (i + 1)) / (↑i + 1)
h₂ : ↑(Nat.centralBinom (n - i + 1)) = (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) / (↑n - ↑i + 1)
h₃ : (↑i + 1) * ↑(Nat.centralBinom (i + 1)) = 2 * (2 * ↑i + 1) * ↑(Nat.centralBinom i)
h₄ : (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) = 2 * (2 * (↑n - ↑i) + 1) * ↑(Nat.centralBinom (n - i))
⊢ ↑(Nat.centralBinom (i + 1)) * ↑(Nat.centralBinom (n + 1 - (i + 1))) * (2 * ↑(i + 1) - ↑(n + 1)) /
        (2 * ↑(n + 1) * (↑(n + 1) + 1)) -
      ↑(Nat.centralBinom i) * ↑(Nat.centralBinom (n + 1 - i)) * (2 * ↑i - ↑(n + 1)) / (2 * ↑(n + 1) * (↑(n + 1) + 1)) =
    ↑(Nat.centralBinom i) / (↑i + 1) * ↑(Nat.centralBinom (n - i)) / (↑n - ↑i + 1)
[PROOFSTEP]
push_cast
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
l₃ : ↑i + 1 ≠ 0
l₄ : ↑n - ↑i + 1 ≠ 0
h₁ : ↑(Nat.centralBinom (i + 1)) = (↑i + 1) * ↑(Nat.centralBinom (i + 1)) / (↑i + 1)
h₂ : ↑(Nat.centralBinom (n - i + 1)) = (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) / (↑n - ↑i + 1)
h₃ : (↑i + 1) * ↑(Nat.centralBinom (i + 1)) = 2 * (2 * ↑i + 1) * ↑(Nat.centralBinom i)
h₄ : (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) = 2 * (2 * (↑n - ↑i) + 1) * ↑(Nat.centralBinom (n - i))
⊢ ↑(Nat.centralBinom (i + 1)) * ↑(Nat.centralBinom (n + 1 - (i + 1))) * (2 * (↑i + 1) - (↑n + 1)) /
        (2 * (↑n + 1) * (↑n + 1 + 1)) -
      ↑(Nat.centralBinom i) * ↑(Nat.centralBinom (n + 1 - i)) * (2 * ↑i - (↑n + 1)) / (2 * (↑n + 1) * (↑n + 1 + 1)) =
    ↑(Nat.centralBinom i) / (↑i + 1) * ↑(Nat.centralBinom (n - i)) / (↑n - ↑i + 1)
[PROOFSTEP]
rw [show n + 1 - i = n - i + 1 by rw [Nat.add_comm (n - i) 1, ← (Nat.add_sub_assoc h 1), add_comm]]
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
l₃ : ↑i + 1 ≠ 0
l₄ : ↑n - ↑i + 1 ≠ 0
h₁ : ↑(Nat.centralBinom (i + 1)) = (↑i + 1) * ↑(Nat.centralBinom (i + 1)) / (↑i + 1)
h₂ : ↑(Nat.centralBinom (n - i + 1)) = (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) / (↑n - ↑i + 1)
h₃ : (↑i + 1) * ↑(Nat.centralBinom (i + 1)) = 2 * (2 * ↑i + 1) * ↑(Nat.centralBinom i)
h₄ : (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) = 2 * (2 * (↑n - ↑i) + 1) * ↑(Nat.centralBinom (n - i))
⊢ n + 1 - i = n - i + 1
[PROOFSTEP]
rw [Nat.add_comm (n - i) 1, ← (Nat.add_sub_assoc h 1), add_comm]
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
l₃ : ↑i + 1 ≠ 0
l₄ : ↑n - ↑i + 1 ≠ 0
h₁ : ↑(Nat.centralBinom (i + 1)) = (↑i + 1) * ↑(Nat.centralBinom (i + 1)) / (↑i + 1)
h₂ : ↑(Nat.centralBinom (n - i + 1)) = (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) / (↑n - ↑i + 1)
h₃ : (↑i + 1) * ↑(Nat.centralBinom (i + 1)) = 2 * (2 * ↑i + 1) * ↑(Nat.centralBinom i)
h₄ : (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) = 2 * (2 * (↑n - ↑i) + 1) * ↑(Nat.centralBinom (n - i))
⊢ ↑(Nat.centralBinom (i + 1)) * ↑(Nat.centralBinom (n + 1 - (i + 1))) * (2 * (↑i + 1) - (↑n + 1)) /
        (2 * (↑n + 1) * (↑n + 1 + 1)) -
      ↑(Nat.centralBinom i) * ↑(Nat.centralBinom (n - i + 1)) * (2 * ↑i - (↑n + 1)) / (2 * (↑n + 1) * (↑n + 1 + 1)) =
    ↑(Nat.centralBinom i) / (↑i + 1) * ↑(Nat.centralBinom (n - i)) / (↑n - ↑i + 1)
[PROOFSTEP]
rw [h₁, h₂, h₃, h₄]
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
l₃ : ↑i + 1 ≠ 0
l₄ : ↑n - ↑i + 1 ≠ 0
h₁ : ↑(Nat.centralBinom (i + 1)) = (↑i + 1) * ↑(Nat.centralBinom (i + 1)) / (↑i + 1)
h₂ : ↑(Nat.centralBinom (n - i + 1)) = (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) / (↑n - ↑i + 1)
h₃ : (↑i + 1) * ↑(Nat.centralBinom (i + 1)) = 2 * (2 * ↑i + 1) * ↑(Nat.centralBinom i)
h₄ : (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) = 2 * (2 * (↑n - ↑i) + 1) * ↑(Nat.centralBinom (n - i))
⊢ 2 * (2 * ↑i + 1) * ↑(Nat.centralBinom i) / (↑i + 1) * ↑(Nat.centralBinom (n + 1 - (i + 1))) *
          (2 * (↑i + 1) - (↑n + 1)) /
        (2 * (↑n + 1) * (↑n + 1 + 1)) -
      ↑(Nat.centralBinom i) * (2 * (2 * (↑n - ↑i) + 1) * ↑(Nat.centralBinom (n - i)) / (↑n - ↑i + 1)) *
          (2 * ↑i - (↑n + 1)) /
        (2 * (↑n + 1) * (↑n + 1 + 1)) =
    ↑(Nat.centralBinom i) / (↑i + 1) * ↑(Nat.centralBinom (n - i)) / (↑n - ↑i + 1)
[PROOFSTEP]
field_simp
[GOAL]
n i : ℕ
h : i ≤ n
l₁ : ↑n + 1 ≠ 0
l₂ : ↑n + 1 + 1 ≠ 0
l₃ : ↑i + 1 ≠ 0
l₄ : ↑n - ↑i + 1 ≠ 0
h₁ : ↑(Nat.centralBinom (i + 1)) = (↑i + 1) * ↑(Nat.centralBinom (i + 1)) / (↑i + 1)
h₂ : ↑(Nat.centralBinom (n - i + 1)) = (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) / (↑n - ↑i + 1)
h₃ : (↑i + 1) * ↑(Nat.centralBinom (i + 1)) = 2 * (2 * ↑i + 1) * ↑(Nat.centralBinom i)
h₄ : (↑n - ↑i + 1) * ↑(Nat.centralBinom (n - i + 1)) = 2 * (2 * (↑n - ↑i) + 1) * ↑(Nat.centralBinom (n - i))
⊢ (2 * (2 * ↑i + 1) * ↑(Nat.centralBinom i) * ↑(Nat.centralBinom (n - i)) * (2 * (↑i + 1) - (↑n + 1)) *
          ((↑n - ↑i + 1) * (2 * (↑n + 1) * (↑n + 1 + 1))) -
        (↑i + 1) * (2 * (↑n + 1) * (↑n + 1 + 1)) *
          (↑(Nat.centralBinom i) * (2 * (2 * (↑n - ↑i) + 1) * ↑(Nat.centralBinom (n - i))) * (2 * ↑i - (↑n + 1)))) *
      ((↑i + 1) * (↑n - ↑i + 1)) =
    ↑(Nat.centralBinom i) * ↑(Nat.centralBinom (n - i)) *
      ((↑i + 1) * (2 * (↑n + 1) * (↑n + 1 + 1)) * ((↑n - ↑i + 1) * (2 * (↑n + 1) * (↑n + 1 + 1))))
[PROOFSTEP]
ring
[GOAL]
n : ℕ
⊢ gosperCatalan (n + 1) (n + 1) - gosperCatalan (n + 1) 0 = ↑(Nat.centralBinom (n + 1)) / (↑n + 2)
[PROOFSTEP]
have : (n : ℚ) + 1 ≠ 0 := by norm_cast; exact n.succ_ne_zero
[GOAL]
n : ℕ
⊢ ↑n + 1 ≠ 0
[PROOFSTEP]
norm_cast
[GOAL]
n : ℕ
⊢ ¬n + 1 = 0
[PROOFSTEP]
exact n.succ_ne_zero
[GOAL]
n : ℕ
this : ↑n + 1 ≠ 0
⊢ gosperCatalan (n + 1) (n + 1) - gosperCatalan (n + 1) 0 = ↑(Nat.centralBinom (n + 1)) / (↑n + 2)
[PROOFSTEP]
have : (n : ℚ) + 1 + 1 ≠ 0 := by norm_cast; exact (n + 1).succ_ne_zero
[GOAL]
n : ℕ
this : ↑n + 1 ≠ 0
⊢ ↑n + 1 + 1 ≠ 0
[PROOFSTEP]
norm_cast
[GOAL]
n : ℕ
this : ↑n + 1 ≠ 0
⊢ ¬n + 1 + 1 = 0
[PROOFSTEP]
exact (n + 1).succ_ne_zero
[GOAL]
n : ℕ
this✝ : ↑n + 1 ≠ 0
this : ↑n + 1 + 1 ≠ 0
⊢ gosperCatalan (n + 1) (n + 1) - gosperCatalan (n + 1) 0 = ↑(Nat.centralBinom (n + 1)) / (↑n + 2)
[PROOFSTEP]
have h : (n : ℚ) + 2 ≠ 0 := by norm_cast; exact (n + 1).succ_ne_zero
[GOAL]
n : ℕ
this✝ : ↑n + 1 ≠ 0
this : ↑n + 1 + 1 ≠ 0
⊢ ↑n + 2 ≠ 0
[PROOFSTEP]
norm_cast
[GOAL]
n : ℕ
this✝ : ↑n + 1 ≠ 0
this : ↑n + 1 + 1 ≠ 0
⊢ ¬n + 2 = 0
[PROOFSTEP]
exact (n + 1).succ_ne_zero
[GOAL]
n : ℕ
this✝ : ↑n + 1 ≠ 0
this : ↑n + 1 + 1 ≠ 0
h : ↑n + 2 ≠ 0
⊢ gosperCatalan (n + 1) (n + 1) - gosperCatalan (n + 1) 0 = ↑(Nat.centralBinom (n + 1)) / (↑n + 2)
[PROOFSTEP]
simp only [gosperCatalan, Nat.sub_zero, Nat.centralBinom_zero, Nat.sub_self]
[GOAL]
n : ℕ
this✝ : ↑n + 1 ≠ 0
this : ↑n + 1 + 1 ≠ 0
h : ↑n + 2 ≠ 0
⊢ ↑(Nat.centralBinom (n + 1)) * ↑1 * (2 * ↑(n + 1) - ↑(n + 1)) / (2 * ↑(n + 1) * (↑(n + 1) + 1)) -
      ↑1 * ↑(Nat.centralBinom (n + 1)) * (2 * ↑0 - ↑(n + 1)) / (2 * ↑(n + 1) * (↑(n + 1) + 1)) =
    ↑(Nat.centralBinom (n + 1)) / (↑n + 2)
[PROOFSTEP]
field_simp
[GOAL]
n : ℕ
this✝ : ↑n + 1 ≠ 0
this : ↑n + 1 + 1 ≠ 0
h : ↑n + 2 ≠ 0
⊢ (↑(Nat.centralBinom (n + 1)) * (2 * (↑n + 1) - (↑n + 1)) - ↑(Nat.centralBinom (n + 1)) * (-1 + -↑n)) * (↑n + 2) =
    ↑(Nat.centralBinom (n + 1)) * (2 * (↑n + 1) * (↑n + 1 + 1))
[PROOFSTEP]
ring
[GOAL]
n : ℕ
⊢ catalan n = Nat.centralBinom n / (n + 1)
[PROOFSTEP]
suffices (catalan n : ℚ) = Nat.centralBinom n / (n + 1)
  by
  have h := Nat.succ_dvd_centralBinom n
  exact_mod_cast this
[GOAL]
n : ℕ
this : ↑(catalan n) = ↑(Nat.centralBinom n) / (↑n + 1)
⊢ catalan n = Nat.centralBinom n / (n + 1)
[PROOFSTEP]
have h := Nat.succ_dvd_centralBinom n
[GOAL]
n : ℕ
this : ↑(catalan n) = ↑(Nat.centralBinom n) / (↑n + 1)
h : n + 1 ∣ Nat.centralBinom n
⊢ catalan n = Nat.centralBinom n / (n + 1)
[PROOFSTEP]
exact_mod_cast this
[GOAL]
n : ℕ
⊢ ↑(catalan n) = ↑(Nat.centralBinom n) / (↑n + 1)
[PROOFSTEP]
induction' n using Nat.case_strong_induction_on with d hd
[GOAL]
case hz
⊢ ↑(catalan 0) = ↑(Nat.centralBinom 0) / (↑0 + 1)
[PROOFSTEP]
simp
[GOAL]
case hi
d : ℕ
hd : ∀ (m : ℕ), m ≤ d → ↑(catalan m) = ↑(Nat.centralBinom m) / (↑m + 1)
⊢ ↑(catalan (Nat.succ d)) = ↑(Nat.centralBinom (Nat.succ d)) / (↑(Nat.succ d) + 1)
[PROOFSTEP]
simp_rw [catalan_succ, Nat.cast_sum, Nat.cast_mul]
[GOAL]
case hi
d : ℕ
hd : ∀ (m : ℕ), m ≤ d → ↑(catalan m) = ↑(Nat.centralBinom m) / (↑m + 1)
⊢ ∑ x : Fin (Nat.succ d), ↑(catalan ↑x) * ↑(catalan (d - ↑x)) = ↑(Nat.centralBinom (Nat.succ d)) / (↑(Nat.succ d) + 1)
[PROOFSTEP]
trans (∑ i : Fin d.succ, Nat.centralBinom i / (i + 1) * (Nat.centralBinom (d - i) / (d - i + 1)) : ℚ)
[GOAL]
d : ℕ
hd : ∀ (m : ℕ), m ≤ d → ↑(catalan m) = ↑(Nat.centralBinom m) / (↑m + 1)
⊢ ∑ x : Fin (Nat.succ d), ↑(catalan ↑x) * ↑(catalan (d - ↑x)) =
    ∑ i : Fin (Nat.succ d), ↑(Nat.centralBinom ↑i) / (↑↑i + 1) * (↑(Nat.centralBinom (d - ↑i)) / (↑d - ↑↑i + 1))
[PROOFSTEP]
congr
[GOAL]
case e_f
d : ℕ
hd : ∀ (m : ℕ), m ≤ d → ↑(catalan m) = ↑(Nat.centralBinom m) / (↑m + 1)
⊢ (fun x => ↑(catalan ↑x) * ↑(catalan (d - ↑x))) = fun i =>
    ↑(Nat.centralBinom ↑i) / (↑↑i + 1) * (↑(Nat.centralBinom (d - ↑i)) / (↑d - ↑↑i + 1))
[PROOFSTEP]
ext1 x
[GOAL]
case e_f.h
d : ℕ
hd : ∀ (m : ℕ), m ≤ d → ↑(catalan m) = ↑(Nat.centralBinom m) / (↑m + 1)
x : Fin (Nat.succ d)
⊢ ↑(catalan ↑x) * ↑(catalan (d - ↑x)) =
    ↑(Nat.centralBinom ↑x) / (↑↑x + 1) * (↑(Nat.centralBinom (d - ↑x)) / (↑d - ↑↑x + 1))
[PROOFSTEP]
have m_le_d : x.val ≤ d := by apply Nat.le_of_lt_succ; apply x.2
[GOAL]
d : ℕ
hd : ∀ (m : ℕ), m ≤ d → ↑(catalan m) = ↑(Nat.centralBinom m) / (↑m + 1)
x : Fin (Nat.succ d)
⊢ ↑x ≤ d
[PROOFSTEP]
apply Nat.le_of_lt_succ
[GOAL]
case a
d : ℕ
hd : ∀ (m : ℕ), m ≤ d → ↑(catalan m) = ↑(Nat.centralBinom m) / (↑m + 1)
x : Fin (Nat.succ d)
⊢ ↑x < Nat.succ d
[PROOFSTEP]
apply x.2
[GOAL]
case e_f.h
d : ℕ
hd : ∀ (m : ℕ), m ≤ d → ↑(catalan m) = ↑(Nat.centralBinom m) / (↑m + 1)
x : Fin (Nat.succ d)
m_le_d : ↑x ≤ d
⊢ ↑(catalan ↑x) * ↑(catalan (d - ↑x)) =
    ↑(Nat.centralBinom ↑x) / (↑↑x + 1) * (↑(Nat.centralBinom (d - ↑x)) / (↑d - ↑↑x + 1))
[PROOFSTEP]
have d_minus_x_le_d : (d - x.val) ≤ d := tsub_le_self
[GOAL]
case e_f.h
d : ℕ
hd : ∀ (m : ℕ), m ≤ d → ↑(catalan m) = ↑(Nat.centralBinom m) / (↑m + 1)
x : Fin (Nat.succ d)
m_le_d : ↑x ≤ d
d_minus_x_le_d : d - ↑x ≤ d
⊢ ↑(catalan ↑x) * ↑(catalan (d - ↑x)) =
    ↑(Nat.centralBinom ↑x) / (↑↑x + 1) * (↑(Nat.centralBinom (d - ↑x)) / (↑d - ↑↑x + 1))
[PROOFSTEP]
rw [hd _ m_le_d, hd _ d_minus_x_le_d]
[GOAL]
case e_f.h
d : ℕ
hd : ∀ (m : ℕ), m ≤ d → ↑(catalan m) = ↑(Nat.centralBinom m) / (↑m + 1)
x : Fin (Nat.succ d)
m_le_d : ↑x ≤ d
d_minus_x_le_d : d - ↑x ≤ d
⊢ ↑(Nat.centralBinom ↑x) / (↑↑x + 1) * (↑(Nat.centralBinom (d - ↑x)) / (↑(d - ↑x) + 1)) =
    ↑(Nat.centralBinom ↑x) / (↑↑x + 1) * (↑(Nat.centralBinom (d - ↑x)) / (↑d - ↑↑x + 1))
[PROOFSTEP]
norm_cast
[GOAL]
d : ℕ
hd : ∀ (m : ℕ), m ≤ d → ↑(catalan m) = ↑(Nat.centralBinom m) / (↑m + 1)
⊢ ∑ i : Fin (Nat.succ d), ↑(Nat.centralBinom ↑i) / (↑↑i + 1) * (↑(Nat.centralBinom (d - ↑i)) / (↑d - ↑↑i + 1)) =
    ↑(Nat.centralBinom (Nat.succ d)) / (↑(Nat.succ d) + 1)
[PROOFSTEP]
trans (∑ i : Fin d.succ, (gosperCatalan (d + 1) (i + 1) - gosperCatalan (d + 1) i))
[GOAL]
d : ℕ
hd : ∀ (m : ℕ), m ≤ d → ↑(catalan m) = ↑(Nat.centralBinom m) / (↑m + 1)
⊢ ∑ i : Fin (Nat.succ d), ↑(Nat.centralBinom ↑i) / (↑↑i + 1) * (↑(Nat.centralBinom (d - ↑i)) / (↑d - ↑↑i + 1)) =
    ∑ i : Fin (Nat.succ d), (gosperCatalan (d + 1) (↑i + 1) - gosperCatalan (d + 1) ↑i)
[PROOFSTEP]
refine' sum_congr rfl fun i _ => _
[GOAL]
d : ℕ
hd : ∀ (m : ℕ), m ≤ d → ↑(catalan m) = ↑(Nat.centralBinom m) / (↑m + 1)
i : Fin (Nat.succ d)
x✝ : i ∈ univ
⊢ ↑(Nat.centralBinom ↑i) / (↑↑i + 1) * (↑(Nat.centralBinom (d - ↑i)) / (↑d - ↑↑i + 1)) =
    gosperCatalan (d + 1) (↑i + 1) - gosperCatalan (d + 1) ↑i
[PROOFSTEP]
rw [gosper_trick i.is_le, mul_div]
[GOAL]
d : ℕ
hd : ∀ (m : ℕ), m ≤ d → ↑(catalan m) = ↑(Nat.centralBinom m) / (↑m + 1)
⊢ ∑ i : Fin (Nat.succ d), (gosperCatalan (d + 1) (↑i + 1) - gosperCatalan (d + 1) ↑i) =
    ↑(Nat.centralBinom (Nat.succ d)) / (↑(Nat.succ d) + 1)
[PROOFSTEP]
rw [← sum_range fun i => gosperCatalan (d + 1) (i + 1) - gosperCatalan (d + 1) i, sum_range_sub, Nat.succ_eq_add_one]
[GOAL]
d : ℕ
hd : ∀ (m : ℕ), m ≤ d → ↑(catalan m) = ↑(Nat.centralBinom m) / (↑m + 1)
⊢ gosperCatalan (d + 1) (d + 1) - gosperCatalan (d + 1) 0 = ↑(Nat.centralBinom (d + 1)) / (↑(d + 1) + 1)
[PROOFSTEP]
rw [gosper_catalan_sub_eq_central_binom_div d]
[GOAL]
d : ℕ
hd : ∀ (m : ℕ), m ≤ d → ↑(catalan m) = ↑(Nat.centralBinom m) / (↑m + 1)
⊢ ↑(Nat.centralBinom (d + 1)) / (↑d + 2) = ↑(Nat.centralBinom (d + 1)) / (↑(d + 1) + 1)
[PROOFSTEP]
norm_cast
[GOAL]
⊢ catalan 2 = 2
[PROOFSTEP]
unfold catalan
[GOAL]
⊢ ∑ i : Fin (Nat.succ 1), catalan ↑i * catalan (1 - ↑i) = 2
[PROOFSTEP]
rfl
[GOAL]
⊢ catalan 3 = 5
[PROOFSTEP]
unfold catalan
[GOAL]
⊢ ∑ i : Fin (Nat.succ 2), catalan ↑i * catalan (2 - ↑i) = 5
[PROOFSTEP]
rfl
[GOAL]
a b : Finset (Tree Unit)
x✝¹ x✝ : Tree Unit × Tree Unit
x₁ x₂ y₁ y₂ : Tree Unit
h : (fun x => node () x.fst x.snd) (x₁, x₂) = (fun x => node () x.fst x.snd) (y₁, y₂)
⊢ (x₁, x₂) = (y₁, y₂)
[PROOFSTEP]
simpa using h
[GOAL]
n : ℕ
ijh : { x // x ∈ Nat.antidiagonal n }
⊢ (invImage (fun a => sizeOf a) instWellFoundedRelation).1 (↑ijh).fst (Nat.succ n)
[PROOFSTEP]
simp_wf
[GOAL]
n : ℕ
ijh : { x // x ∈ Nat.antidiagonal n }
⊢ (↑ijh).fst < Nat.succ n
[PROOFSTEP]
try exact Nat.lt_succ_of_le (fst_le ijh.2)
[GOAL]
n : ℕ
ijh : { x // x ∈ Nat.antidiagonal n }
⊢ (↑ijh).fst < Nat.succ n
[PROOFSTEP]
exact Nat.lt_succ_of_le (fst_le ijh.2)
[GOAL]

[PROOFSTEP]
try exact Nat.lt_succ_of_le (snd_le ijh.2)
[GOAL]

[PROOFSTEP]
exact Nat.lt_succ_of_le (snd_le ijh.2)
[GOAL]
n : ℕ
ijh : { x // x ∈ Nat.antidiagonal n }
⊢ (invImage (fun a => sizeOf a) instWellFoundedRelation).1 (↑ijh).snd (Nat.succ n)
[PROOFSTEP]
simp_wf
[GOAL]
n : ℕ
ijh : { x // x ∈ Nat.antidiagonal n }
⊢ (↑ijh).snd < Nat.succ n
[PROOFSTEP]
try exact Nat.lt_succ_of_le (fst_le ijh.2)
[GOAL]
n : ℕ
ijh : { x // x ∈ Nat.antidiagonal n }
⊢ (↑ijh).snd < Nat.succ n
[PROOFSTEP]
exact Nat.lt_succ_of_le (fst_le ijh.2)
[GOAL]
n : ℕ
ijh : { x // x ∈ Nat.antidiagonal n }
⊢ (↑ijh).snd < Nat.succ n
[PROOFSTEP]
try exact Nat.lt_succ_of_le (snd_le ijh.2)
[GOAL]
n : ℕ
ijh : { x // x ∈ Nat.antidiagonal n }
⊢ (↑ijh).snd < Nat.succ n
[PROOFSTEP]
exact Nat.lt_succ_of_le (snd_le ijh.2)
[GOAL]
⊢ treesOfNumNodesEq 0 = {nil}
[PROOFSTEP]
rw [treesOfNumNodesEq]
[GOAL]
n : ℕ
⊢ treesOfNumNodesEq (n + 1) =
    Finset.biUnion (Nat.antidiagonal n) fun ij => pairwiseNode (treesOfNumNodesEq ij.fst) (treesOfNumNodesEq ij.snd)
[PROOFSTEP]
rw [treesOfNumNodesEq]
[GOAL]
n : ℕ
⊢ (Finset.biUnion (attach (Nat.antidiagonal n)) fun ijh =>
      pairwiseNode (treesOfNumNodesEq (↑ijh).fst) (treesOfNumNodesEq (↑ijh).snd)) =
    Finset.biUnion (Nat.antidiagonal n) fun ij => pairwiseNode (treesOfNumNodesEq ij.fst) (treesOfNumNodesEq ij.snd)
[PROOFSTEP]
ext
[GOAL]
case a
n : ℕ
a✝ : Tree Unit
⊢ (a✝ ∈
      Finset.biUnion (attach (Nat.antidiagonal n)) fun ijh =>
        pairwiseNode (treesOfNumNodesEq (↑ijh).fst) (treesOfNumNodesEq (↑ijh).snd)) ↔
    a✝ ∈
      Finset.biUnion (Nat.antidiagonal n) fun ij => pairwiseNode (treesOfNumNodesEq ij.fst) (treesOfNumNodesEq ij.snd)
[PROOFSTEP]
simp
[GOAL]
x : Tree Unit
n : ℕ
⊢ x ∈ treesOfNumNodesEq n ↔ numNodes x = n
[PROOFSTEP]
induction x using Tree.unitRecOn generalizing n
[GOAL]
case base
n : ℕ
⊢ nil ∈ treesOfNumNodesEq n ↔ numNodes nil = n
[PROOFSTEP]
cases n
[GOAL]
case ind
x✝ y✝ : Tree Unit
a✝¹ : ∀ {n : ℕ}, x✝ ∈ treesOfNumNodesEq n ↔ numNodes x✝ = n
a✝ : ∀ {n : ℕ}, y✝ ∈ treesOfNumNodesEq n ↔ numNodes y✝ = n
n : ℕ
⊢ node () x✝ y✝ ∈ treesOfNumNodesEq n ↔ numNodes (node () x✝ y✝) = n
[PROOFSTEP]
cases n
[GOAL]
case base.zero
⊢ nil ∈ treesOfNumNodesEq Nat.zero ↔ numNodes nil = Nat.zero
[PROOFSTEP]
simp [treesOfNumNodesEq_succ, Nat.succ_eq_add_one, *]
[GOAL]
case base.succ
n✝ : ℕ
⊢ nil ∈ treesOfNumNodesEq (Nat.succ n✝) ↔ numNodes nil = Nat.succ n✝
[PROOFSTEP]
simp [treesOfNumNodesEq_succ, Nat.succ_eq_add_one, *]
[GOAL]
case ind.zero
x✝ y✝ : Tree Unit
a✝¹ : ∀ {n : ℕ}, x✝ ∈ treesOfNumNodesEq n ↔ numNodes x✝ = n
a✝ : ∀ {n : ℕ}, y✝ ∈ treesOfNumNodesEq n ↔ numNodes y✝ = n
⊢ node () x✝ y✝ ∈ treesOfNumNodesEq Nat.zero ↔ numNodes (node () x✝ y✝) = Nat.zero
[PROOFSTEP]
simp [treesOfNumNodesEq_succ, Nat.succ_eq_add_one, *]
[GOAL]
case ind.succ
x✝ y✝ : Tree Unit
a✝¹ : ∀ {n : ℕ}, x✝ ∈ treesOfNumNodesEq n ↔ numNodes x✝ = n
a✝ : ∀ {n : ℕ}, y✝ ∈ treesOfNumNodesEq n ↔ numNodes y✝ = n
n✝ : ℕ
⊢ node () x✝ y✝ ∈ treesOfNumNodesEq (Nat.succ n✝) ↔ numNodes (node () x✝ y✝) = Nat.succ n✝
[PROOFSTEP]
simp [treesOfNumNodesEq_succ, Nat.succ_eq_add_one, *]
[GOAL]
case base.succ
n✝ : ℕ
⊢ ¬0 = n✝ + 1
[PROOFSTEP]
exact (Nat.succ_ne_zero _).symm
[GOAL]
n : ℕ
⊢ ∀ (x : Tree Unit), x ∈ ↑(treesOfNumNodesEq n) ↔ x ∈ {x | numNodes x = n}
[PROOFSTEP]
simp
[GOAL]
n : ℕ
⊢ card (treesOfNumNodesEq n) = catalan n
[PROOFSTEP]
induction' n using Nat.case_strong_induction_on with n ih
[GOAL]
case hz
⊢ card (treesOfNumNodesEq 0) = catalan 0
[PROOFSTEP]
simp
[GOAL]
case hi
n : ℕ
ih : ∀ (m : ℕ), m ≤ n → card (treesOfNumNodesEq m) = catalan m
⊢ card (treesOfNumNodesEq (Nat.succ n)) = catalan (Nat.succ n)
[PROOFSTEP]
rw [treesOfNumNodesEq_succ, card_biUnion, catalan_succ']
[GOAL]
case hi
n : ℕ
ih : ∀ (m : ℕ), m ≤ n → card (treesOfNumNodesEq m) = catalan m
⊢ ∑ u in Nat.antidiagonal n, card (pairwiseNode (treesOfNumNodesEq u.fst) (treesOfNumNodesEq u.snd)) =
    ∑ ij in Nat.antidiagonal n, catalan ij.fst * catalan ij.snd
[PROOFSTEP]
apply sum_congr rfl
[GOAL]
case hi
n : ℕ
ih : ∀ (m : ℕ), m ≤ n → card (treesOfNumNodesEq m) = catalan m
⊢ ∀ (x : ℕ × ℕ),
    x ∈ Nat.antidiagonal n →
      card (pairwiseNode (treesOfNumNodesEq x.fst) (treesOfNumNodesEq x.snd)) = catalan x.fst * catalan x.snd
[PROOFSTEP]
rintro ⟨i, j⟩ H
[GOAL]
case hi.mk
n : ℕ
ih : ∀ (m : ℕ), m ≤ n → card (treesOfNumNodesEq m) = catalan m
i j : ℕ
H : (i, j) ∈ Nat.antidiagonal n
⊢ card (pairwiseNode (treesOfNumNodesEq (i, j).fst) (treesOfNumNodesEq (i, j).snd)) =
    catalan (i, j).fst * catalan (i, j).snd
[PROOFSTEP]
rw [card_map, card_product, ih _ (fst_le H), ih _ (snd_le H)]
[GOAL]
case hi
n : ℕ
ih : ∀ (m : ℕ), m ≤ n → card (treesOfNumNodesEq m) = catalan m
⊢ ∀ (x : ℕ × ℕ),
    x ∈ Nat.antidiagonal n →
      ∀ (y : ℕ × ℕ),
        y ∈ Nat.antidiagonal n →
          x ≠ y →
            Disjoint (pairwiseNode (treesOfNumNodesEq x.fst) (treesOfNumNodesEq x.snd))
              (pairwiseNode (treesOfNumNodesEq y.fst) (treesOfNumNodesEq y.snd))
[PROOFSTEP]
simp_rw [disjoint_left]
[GOAL]
case hi
n : ℕ
ih : ∀ (m : ℕ), m ≤ n → card (treesOfNumNodesEq m) = catalan m
⊢ ∀ (x : ℕ × ℕ),
    x ∈ Nat.antidiagonal n →
      ∀ (y : ℕ × ℕ),
        y ∈ Nat.antidiagonal n →
          x ≠ y →
            ∀ ⦃a : Tree Unit⦄,
              a ∈ pairwiseNode (treesOfNumNodesEq x.fst) (treesOfNumNodesEq x.snd) →
                ¬a ∈ pairwiseNode (treesOfNumNodesEq y.fst) (treesOfNumNodesEq y.snd)
[PROOFSTEP]
rintro ⟨i, j⟩ _ ⟨i', j'⟩
  _
      -- Porting note: was clear * -; tidy
[GOAL]
case hi.mk.mk
n : ℕ
ih : ∀ (m : ℕ), m ≤ n → card (treesOfNumNodesEq m) = catalan m
i j : ℕ
a✝¹ : (i, j) ∈ Nat.antidiagonal n
i' j' : ℕ
a✝ : (i', j') ∈ Nat.antidiagonal n
⊢ (i, j) ≠ (i', j') →
    ∀ ⦃a : Tree Unit⦄,
      a ∈ pairwiseNode (treesOfNumNodesEq (i, j).fst) (treesOfNumNodesEq (i, j).snd) →
        ¬a ∈ pairwiseNode (treesOfNumNodesEq (i', j').fst) (treesOfNumNodesEq (i', j').snd)
[PROOFSTEP]
intros h a
[GOAL]
case hi.mk.mk
n : ℕ
ih : ∀ (m : ℕ), m ≤ n → card (treesOfNumNodesEq m) = catalan m
i j : ℕ
a✝¹ : (i, j) ∈ Nat.antidiagonal n
i' j' : ℕ
a✝ : (i', j') ∈ Nat.antidiagonal n
h : (i, j) ≠ (i', j')
a : Tree Unit
⊢ a ∈ pairwiseNode (treesOfNumNodesEq (i, j).fst) (treesOfNumNodesEq (i, j).snd) →
    ¬a ∈ pairwiseNode (treesOfNumNodesEq (i', j').fst) (treesOfNumNodesEq (i', j').snd)
[PROOFSTEP]
cases' a with a l r
[GOAL]
case hi.mk.mk.nil
n : ℕ
ih : ∀ (m : ℕ), m ≤ n → card (treesOfNumNodesEq m) = catalan m
i j : ℕ
a✝¹ : (i, j) ∈ Nat.antidiagonal n
i' j' : ℕ
a✝ : (i', j') ∈ Nat.antidiagonal n
h : (i, j) ≠ (i', j')
⊢ nil ∈ pairwiseNode (treesOfNumNodesEq (i, j).fst) (treesOfNumNodesEq (i, j).snd) →
    ¬nil ∈ pairwiseNode (treesOfNumNodesEq (i', j').fst) (treesOfNumNodesEq (i', j').snd)
[PROOFSTEP]
intro h
[GOAL]
case hi.mk.mk.nil
n : ℕ
ih : ∀ (m : ℕ), m ≤ n → card (treesOfNumNodesEq m) = catalan m
i j : ℕ
a✝¹ : (i, j) ∈ Nat.antidiagonal n
i' j' : ℕ
a✝ : (i', j') ∈ Nat.antidiagonal n
h✝ : (i, j) ≠ (i', j')
h : nil ∈ pairwiseNode (treesOfNumNodesEq (i, j).fst) (treesOfNumNodesEq (i, j).snd)
⊢ ¬nil ∈ pairwiseNode (treesOfNumNodesEq (i', j').fst) (treesOfNumNodesEq (i', j').snd)
[PROOFSTEP]
simp at h
[GOAL]
case hi.mk.mk.node
n : ℕ
ih : ∀ (m : ℕ), m ≤ n → card (treesOfNumNodesEq m) = catalan m
i j : ℕ
a✝¹ : (i, j) ∈ Nat.antidiagonal n
i' j' : ℕ
a✝ : (i', j') ∈ Nat.antidiagonal n
h : (i, j) ≠ (i', j')
a : Unit
l r : Tree Unit
⊢ node a l r ∈ pairwiseNode (treesOfNumNodesEq (i, j).fst) (treesOfNumNodesEq (i, j).snd) →
    ¬node a l r ∈ pairwiseNode (treesOfNumNodesEq (i', j').fst) (treesOfNumNodesEq (i', j').snd)
[PROOFSTEP]
intro h1 h2
[GOAL]
case hi.mk.mk.node
n : ℕ
ih : ∀ (m : ℕ), m ≤ n → card (treesOfNumNodesEq m) = catalan m
i j : ℕ
a✝¹ : (i, j) ∈ Nat.antidiagonal n
i' j' : ℕ
a✝ : (i', j') ∈ Nat.antidiagonal n
h : (i, j) ≠ (i', j')
a : Unit
l r : Tree Unit
h1 : node a l r ∈ pairwiseNode (treesOfNumNodesEq (i, j).fst) (treesOfNumNodesEq (i, j).snd)
h2 : node a l r ∈ pairwiseNode (treesOfNumNodesEq (i', j').fst) (treesOfNumNodesEq (i', j').snd)
⊢ False
[PROOFSTEP]
apply h
[GOAL]
case hi.mk.mk.node
n : ℕ
ih : ∀ (m : ℕ), m ≤ n → card (treesOfNumNodesEq m) = catalan m
i j : ℕ
a✝¹ : (i, j) ∈ Nat.antidiagonal n
i' j' : ℕ
a✝ : (i', j') ∈ Nat.antidiagonal n
h : (i, j) ≠ (i', j')
a : Unit
l r : Tree Unit
h1 : node a l r ∈ pairwiseNode (treesOfNumNodesEq (i, j).fst) (treesOfNumNodesEq (i, j).snd)
h2 : node a l r ∈ pairwiseNode (treesOfNumNodesEq (i', j').fst) (treesOfNumNodesEq (i', j').snd)
⊢ (i, j) = (i', j')
[PROOFSTEP]
trans (numNodes l, numNodes r)
[GOAL]
n : ℕ
ih : ∀ (m : ℕ), m ≤ n → card (treesOfNumNodesEq m) = catalan m
i j : ℕ
a✝¹ : (i, j) ∈ Nat.antidiagonal n
i' j' : ℕ
a✝ : (i', j') ∈ Nat.antidiagonal n
h : (i, j) ≠ (i', j')
a : Unit
l r : Tree Unit
h1 : node a l r ∈ pairwiseNode (treesOfNumNodesEq (i, j).fst) (treesOfNumNodesEq (i, j).snd)
h2 : node a l r ∈ pairwiseNode (treesOfNumNodesEq (i', j').fst) (treesOfNumNodesEq (i', j').snd)
⊢ (i, j) = (numNodes l, numNodes r)
[PROOFSTEP]
simp at h1
[GOAL]
n : ℕ
ih : ∀ (m : ℕ), m ≤ n → card (treesOfNumNodesEq m) = catalan m
i j : ℕ
a✝¹ : (i, j) ∈ Nat.antidiagonal n
i' j' : ℕ
a✝ : (i', j') ∈ Nat.antidiagonal n
h : (i, j) ≠ (i', j')
a : Unit
l r : Tree Unit
h2 : node a l r ∈ pairwiseNode (treesOfNumNodesEq (i', j').fst) (treesOfNumNodesEq (i', j').snd)
h1 : numNodes l = i ∧ numNodes r = j
⊢ (i, j) = (numNodes l, numNodes r)
[PROOFSTEP]
simp [h1]
[GOAL]
n : ℕ
ih : ∀ (m : ℕ), m ≤ n → card (treesOfNumNodesEq m) = catalan m
i j : ℕ
a✝¹ : (i, j) ∈ Nat.antidiagonal n
i' j' : ℕ
a✝ : (i', j') ∈ Nat.antidiagonal n
h : (i, j) ≠ (i', j')
a : Unit
l r : Tree Unit
h1 : node a l r ∈ pairwiseNode (treesOfNumNodesEq (i, j).fst) (treesOfNumNodesEq (i, j).snd)
h2 : node a l r ∈ pairwiseNode (treesOfNumNodesEq (i', j').fst) (treesOfNumNodesEq (i', j').snd)
⊢ (numNodes l, numNodes r) = (i', j')
[PROOFSTEP]
simp at h2
[GOAL]
n : ℕ
ih : ∀ (m : ℕ), m ≤ n → card (treesOfNumNodesEq m) = catalan m
i j : ℕ
a✝¹ : (i, j) ∈ Nat.antidiagonal n
i' j' : ℕ
a✝ : (i', j') ∈ Nat.antidiagonal n
h : (i, j) ≠ (i', j')
a : Unit
l r : Tree Unit
h1 : node a l r ∈ pairwiseNode (treesOfNumNodesEq (i, j).fst) (treesOfNumNodesEq (i, j).snd)
h2 : numNodes l = i' ∧ numNodes r = j'
⊢ (numNodes l, numNodes r) = (i', j')
[PROOFSTEP]
simp [h2]


[GOAL]
m n k : ℕ
⊢ gcd m (n + k * m) = gcd m n
[PROOFSTEP]
simp [gcd_rec m (n + k * m), gcd_rec m n]
[GOAL]
m n k : ℕ
⊢ gcd m (n + m * k) = gcd m n
[PROOFSTEP]
simp [gcd_rec m (n + m * k), gcd_rec m n]
[GOAL]
m n k : ℕ
⊢ gcd m (k * m + n) = gcd m n
[PROOFSTEP]
simp [add_comm _ n]
[GOAL]
m n k : ℕ
⊢ gcd m (m * k + n) = gcd m n
[PROOFSTEP]
simp [add_comm _ n]
[GOAL]
m n k : ℕ
⊢ gcd (m + k * n) n = gcd m n
[PROOFSTEP]
rw [gcd_comm, gcd_add_mul_right_right, gcd_comm]
[GOAL]
m n k : ℕ
⊢ gcd (m + n * k) n = gcd m n
[PROOFSTEP]
rw [gcd_comm, gcd_add_mul_left_right, gcd_comm]
[GOAL]
m n k : ℕ
⊢ gcd (k * n + m) n = gcd m n
[PROOFSTEP]
rw [gcd_comm, gcd_mul_right_add_right, gcd_comm]
[GOAL]
m n k : ℕ
⊢ gcd (n * k + m) n = gcd m n
[PROOFSTEP]
rw [gcd_comm, gcd_mul_left_add_right, gcd_comm]
[GOAL]
m n : ℕ
⊢ gcd m (n + m) = gcd m (n + 1 * m)
[PROOFSTEP]
rw [one_mul]
[GOAL]
m n : ℕ
⊢ gcd (m + n) n = gcd m n
[PROOFSTEP]
rw [gcd_comm, gcd_add_self_right, gcd_comm]
[GOAL]
m n : ℕ
⊢ gcd (m + n) m = gcd n m
[PROOFSTEP]
rw [add_comm, gcd_add_self_left]
[GOAL]
m n : ℕ
⊢ gcd m (m + n) = gcd m n
[PROOFSTEP]
rw [add_comm, gcd_add_self_right]
[GOAL]
m n : ℕ
⊢ 0 < m → 0 < n → 0 < lcm m n
[PROOFSTEP]
simp_rw [pos_iff_ne_zero]
[GOAL]
m n : ℕ
⊢ m ≠ 0 → n ≠ 0 → lcm m n ≠ 0
[PROOFSTEP]
exact lcm_ne_zero
[GOAL]
m n : ℕ
h : coprime m n
⊢ lcm m n = m * n
[PROOFSTEP]
rw [← one_mul (lcm m n), ← h.gcd_eq_one, gcd_mul_lcm]
[GOAL]
m n : ℕ
⊢ coprime m (n + m) ↔ coprime m n
[PROOFSTEP]
rw [coprime, coprime, gcd_add_self_right]
[GOAL]
m n : ℕ
⊢ coprime m (m + n) ↔ coprime m n
[PROOFSTEP]
rw [add_comm, coprime_add_self_right]
[GOAL]
m n : ℕ
⊢ coprime (m + n) n ↔ coprime m n
[PROOFSTEP]
rw [coprime, coprime, gcd_add_self_left]
[GOAL]
m n : ℕ
⊢ coprime (m + n) m ↔ coprime n m
[PROOFSTEP]
rw [coprime, coprime, gcd_self_add_left]
[GOAL]
m n k : ℕ
⊢ coprime m (n + k * m) ↔ coprime m n
[PROOFSTEP]
rw [coprime, coprime, gcd_add_mul_right_right]
[GOAL]
m n k : ℕ
⊢ coprime m (n + m * k) ↔ coprime m n
[PROOFSTEP]
rw [coprime, coprime, gcd_add_mul_left_right]
[GOAL]
m n k : ℕ
⊢ coprime m (k * m + n) ↔ coprime m n
[PROOFSTEP]
rw [coprime, coprime, gcd_mul_right_add_right]
[GOAL]
m n k : ℕ
⊢ coprime m (m * k + n) ↔ coprime m n
[PROOFSTEP]
rw [coprime, coprime, gcd_mul_left_add_right]
[GOAL]
m n k : ℕ
⊢ coprime (m + k * n) n ↔ coprime m n
[PROOFSTEP]
rw [coprime, coprime, gcd_add_mul_right_left]
[GOAL]
m n k : ℕ
⊢ coprime (m + n * k) n ↔ coprime m n
[PROOFSTEP]
rw [coprime, coprime, gcd_add_mul_left_left]
[GOAL]
m n k : ℕ
⊢ coprime (k * n + m) n ↔ coprime m n
[PROOFSTEP]
rw [coprime, coprime, gcd_mul_right_add_left]
[GOAL]
m n k : ℕ
⊢ coprime (n * k + m) n ↔ coprime m n
[PROOFSTEP]
rw [coprime, coprime, gcd_mul_left_add_left]
[GOAL]
n : ℕ
hn : 0 < n
a b : ℕ
⊢ coprime (a ^ n) b ↔ coprime a b
[PROOFSTEP]
obtain ⟨n, rfl⟩ := exists_eq_succ_of_ne_zero hn.ne'
[GOAL]
case intro
a b n : ℕ
hn : 0 < succ n
⊢ coprime (a ^ succ n) b ↔ coprime a b
[PROOFSTEP]
rw [pow_succ, Nat.coprime_mul_iff_left]
[GOAL]
case intro
a b n : ℕ
hn : 0 < succ n
⊢ coprime (a ^ n) b ∧ coprime a b ↔ coprime a b
[PROOFSTEP]
exact ⟨And.right, fun hab => ⟨hab.pow_left _, hab⟩⟩
[GOAL]
n : ℕ
hn : 0 < n
a b : ℕ
⊢ coprime a (b ^ n) ↔ coprime a b
[PROOFSTEP]
rw [Nat.coprime_comm, coprime_pow_left_iff hn, Nat.coprime_comm]
[GOAL]
⊢ ¬coprime 0 0
[PROOFSTEP]
simp
[GOAL]
n : ℕ
⊢ coprime 1 n ↔ True
[PROOFSTEP]
simp [coprime]
[GOAL]
n : ℕ
⊢ coprime n 1 ↔ True
[PROOFSTEP]
simp [coprime]
[GOAL]
a b c : ℕ
hac : coprime a c
b_dvd_c : b ∣ c
⊢ gcd (a * b) c = b
[PROOFSTEP]
rcases exists_eq_mul_left_of_dvd b_dvd_c with ⟨d, rfl⟩
[GOAL]
case intro
a b d : ℕ
hac : coprime a (d * b)
b_dvd_c : b ∣ d * b
⊢ gcd (a * b) (d * b) = b
[PROOFSTEP]
rw [gcd_mul_right]
[GOAL]
case intro
a b d : ℕ
hac : coprime a (d * b)
b_dvd_c : b ∣ d * b
⊢ gcd a d * b = b
[PROOFSTEP]
convert one_mul b
[GOAL]
case h.e'_2.h.e'_5
a b d : ℕ
hac : coprime a (d * b)
b_dvd_c : b ∣ d * b
⊢ gcd a d = 1
[PROOFSTEP]
exact coprime.coprime_mul_right_right hac
[GOAL]
m n k : ℕ
H : k ∣ m * n
⊢ { d // k = ↑d.fst * ↑d.snd }
[PROOFSTEP]
cases h0 : gcd k m
[GOAL]
case zero
m n k : ℕ
H : k ∣ m * n
h0 : gcd k m = zero
⊢ { d // k = ↑d.fst * ↑d.snd }
case succ m n k : ℕ H : k ∣ m * n n✝ : ℕ h0 : gcd k m = succ n✝ ⊢ { d // k = ↑d.fst * ↑d.snd }
[PROOFSTEP]
case zero =>
  obtain rfl : k = 0 := eq_zero_of_gcd_eq_zero_left h0
  obtain rfl : m = 0 := eq_zero_of_gcd_eq_zero_right h0
  exact ⟨⟨⟨0, dvd_refl 0⟩, ⟨n, dvd_refl n⟩⟩, (zero_mul n).symm⟩
[GOAL]
m n k : ℕ
H : k ∣ m * n
h0 : gcd k m = zero
⊢ { d // k = ↑d.fst * ↑d.snd }
[PROOFSTEP]
case zero =>
  obtain rfl : k = 0 := eq_zero_of_gcd_eq_zero_left h0
  obtain rfl : m = 0 := eq_zero_of_gcd_eq_zero_right h0
  exact ⟨⟨⟨0, dvd_refl 0⟩, ⟨n, dvd_refl n⟩⟩, (zero_mul n).symm⟩
[GOAL]
m n k : ℕ
H : k ∣ m * n
h0 : gcd k m = zero
⊢ { d // k = ↑d.fst * ↑d.snd }
[PROOFSTEP]
obtain rfl : k = 0 := eq_zero_of_gcd_eq_zero_left h0
[GOAL]
m n : ℕ
H : 0 ∣ m * n
h0 : gcd 0 m = zero
⊢ { d // 0 = ↑d.fst * ↑d.snd }
[PROOFSTEP]
obtain rfl : m = 0 := eq_zero_of_gcd_eq_zero_right h0
[GOAL]
n : ℕ
H : 0 ∣ 0 * n
h0 : gcd 0 0 = zero
⊢ { d // 0 = ↑d.fst * ↑d.snd }
[PROOFSTEP]
exact ⟨⟨⟨0, dvd_refl 0⟩, ⟨n, dvd_refl n⟩⟩, (zero_mul n).symm⟩
[GOAL]
case succ
m n k : ℕ
H : k ∣ m * n
n✝ : ℕ
h0 : gcd k m = succ n✝
⊢ { d // k = ↑d.fst * ↑d.snd }
[PROOFSTEP]
case succ tmp =>
  have hpos : 0 < gcd k m := h0.symm ▸ Nat.zero_lt_succ _; clear h0 tmp
  have hd : gcd k m * (k / gcd k m) = k := Nat.mul_div_cancel' (gcd_dvd_left k m)
  refine' ⟨⟨⟨gcd k m, gcd_dvd_right k m⟩, ⟨k / gcd k m, _⟩⟩, hd.symm⟩
  apply Nat.dvd_of_mul_dvd_mul_left hpos
  rw [hd, ← gcd_mul_right]
  exact dvd_gcd (dvd_mul_right _ _) H
[GOAL]
m n k : ℕ
H : k ∣ m * n
tmp : ℕ
h0 : gcd k m = succ tmp
⊢ { d // k = ↑d.fst * ↑d.snd }
[PROOFSTEP]
case succ tmp =>
  have hpos : 0 < gcd k m := h0.symm ▸ Nat.zero_lt_succ _; clear h0 tmp
  have hd : gcd k m * (k / gcd k m) = k := Nat.mul_div_cancel' (gcd_dvd_left k m)
  refine' ⟨⟨⟨gcd k m, gcd_dvd_right k m⟩, ⟨k / gcd k m, _⟩⟩, hd.symm⟩
  apply Nat.dvd_of_mul_dvd_mul_left hpos
  rw [hd, ← gcd_mul_right]
  exact dvd_gcd (dvd_mul_right _ _) H
[GOAL]
m n k : ℕ
H : k ∣ m * n
tmp : ℕ
h0 : gcd k m = succ tmp
⊢ { d // k = ↑d.fst * ↑d.snd }
[PROOFSTEP]
have hpos : 0 < gcd k m := h0.symm ▸ Nat.zero_lt_succ _
[GOAL]
m n k : ℕ
H : k ∣ m * n
tmp : ℕ
h0 : gcd k m = succ tmp
hpos : 0 < gcd k m
⊢ { d // k = ↑d.fst * ↑d.snd }
[PROOFSTEP]
clear h0 tmp
[GOAL]
m n k : ℕ
H : k ∣ m * n
hpos : 0 < gcd k m
⊢ { d // k = ↑d.fst * ↑d.snd }
[PROOFSTEP]
have hd : gcd k m * (k / gcd k m) = k := Nat.mul_div_cancel' (gcd_dvd_left k m)
[GOAL]
m n k : ℕ
H : k ∣ m * n
hpos : 0 < gcd k m
hd : gcd k m * (k / gcd k m) = k
⊢ { d // k = ↑d.fst * ↑d.snd }
[PROOFSTEP]
refine' ⟨⟨⟨gcd k m, gcd_dvd_right k m⟩, ⟨k / gcd k m, _⟩⟩, hd.symm⟩
[GOAL]
m n k : ℕ
H : k ∣ m * n
hpos : 0 < gcd k m
hd : gcd k m * (k / gcd k m) = k
⊢ k / gcd k m ∣ n
[PROOFSTEP]
apply Nat.dvd_of_mul_dvd_mul_left hpos
[GOAL]
m n k : ℕ
H : k ∣ m * n
hpos : 0 < gcd k m
hd : gcd k m * (k / gcd k m) = k
⊢ gcd k m * (k / gcd k m) ∣ gcd k m * n
[PROOFSTEP]
rw [hd, ← gcd_mul_right]
[GOAL]
m n k : ℕ
H : k ∣ m * n
hpos : 0 < gcd k m
hd : gcd k m * (k / gcd k m) = k
⊢ k ∣ gcd (k * n) (m * n)
[PROOFSTEP]
exact dvd_gcd (dvd_mul_right _ _) H
[GOAL]
x m n : ℕ
⊢ x ∣ m * n ↔ ∃ y z, y ∣ m ∧ z ∣ n ∧ y * z = x
[PROOFSTEP]
constructor
[GOAL]
case mp
x m n : ℕ
⊢ x ∣ m * n → ∃ y z, y ∣ m ∧ z ∣ n ∧ y * z = x
[PROOFSTEP]
intro h
[GOAL]
case mp
x m n : ℕ
h : x ∣ m * n
⊢ ∃ y z, y ∣ m ∧ z ∣ n ∧ y * z = x
[PROOFSTEP]
obtain ⟨⟨⟨y, hy⟩, ⟨z, hz⟩⟩, rfl⟩ := prod_dvd_and_dvd_of_dvd_prod h
[GOAL]
case mp.mk.mk.mk.mk
m n y : ℕ
hy : y ∣ m
z : ℕ
hz : z ∣ n
h :
  ↑({ val := y, property := hy }, { val := z, property := hz }).fst *
      ↑({ val := y, property := hy }, { val := z, property := hz }).snd ∣
    m * n
⊢ ∃ y_1 z_1,
    y_1 ∣ m ∧
      z_1 ∣ n ∧
        y_1 * z_1 =
          ↑({ val := y, property := hy }, { val := z, property := hz }).fst *
            ↑({ val := y, property := hy }, { val := z, property := hz }).snd
[PROOFSTEP]
exact ⟨y, z, hy, hz, rfl⟩
[GOAL]
case mpr
x m n : ℕ
⊢ (∃ y z, y ∣ m ∧ z ∣ n ∧ y * z = x) → x ∣ m * n
[PROOFSTEP]
rintro ⟨y, z, hy, hz, rfl⟩
[GOAL]
case mpr.intro.intro.intro.intro
m n y z : ℕ
hy : y ∣ m
hz : z ∣ n
⊢ y * z ∣ m * n
[PROOFSTEP]
exact mul_dvd_mul hy hz
[GOAL]
a b n : ℕ
n0 : 0 < n
⊢ a ^ n ∣ b ^ n ↔ a ∣ b
[PROOFSTEP]
refine' ⟨fun h => _, fun h => pow_dvd_pow_of_dvd h _⟩
[GOAL]
a b n : ℕ
n0 : 0 < n
h : a ^ n ∣ b ^ n
⊢ a ∣ b
[PROOFSTEP]
cases' Nat.eq_zero_or_pos (gcd a b) with g0 g0
[GOAL]
case inl
a b n : ℕ
n0 : 0 < n
h : a ^ n ∣ b ^ n
g0 : gcd a b = 0
⊢ a ∣ b
[PROOFSTEP]
simp [eq_zero_of_gcd_eq_zero_right g0]
[GOAL]
case inr
a b n : ℕ
n0 : 0 < n
h : a ^ n ∣ b ^ n
g0 : gcd a b > 0
⊢ a ∣ b
[PROOFSTEP]
rcases exists_coprime' g0 with ⟨g, a', b', g0', co, rfl, rfl⟩
[GOAL]
case inr.intro.intro.intro.intro.intro.intro
n : ℕ
n0 : 0 < n
g : ℕ
a' b' : ℕ
g0' : 0 < g
co : coprime a' b'
h : (a' * g) ^ n ∣ (b' * g) ^ n
g0 : gcd (a' * g) (b' * g) > 0
⊢ a' * g ∣ b' * g
[PROOFSTEP]
rw [mul_pow, mul_pow] at h
[GOAL]
case inr.intro.intro.intro.intro.intro.intro
n : ℕ
n0 : 0 < n
g : ℕ
a' b' : ℕ
g0' : 0 < g
co : coprime a' b'
h : a' ^ n * g ^ n ∣ b' ^ n * g ^ n
g0 : gcd (a' * g) (b' * g) > 0
⊢ a' * g ∣ b' * g
[PROOFSTEP]
replace h := Nat.dvd_of_mul_dvd_mul_right (pow_pos g0' _) h
[GOAL]
case inr.intro.intro.intro.intro.intro.intro
n : ℕ
n0 : 0 < n
g : ℕ
a' b' : ℕ
g0' : 0 < g
co : coprime a' b'
g0 : gcd (a' * g) (b' * g) > 0
h : a' ^ n ∣ b' ^ n
⊢ a' * g ∣ b' * g
[PROOFSTEP]
have := pow_dvd_pow a' n0
[GOAL]
case inr.intro.intro.intro.intro.intro.intro
n : ℕ
n0 : 0 < n
g : ℕ
a' b' : ℕ
g0' : 0 < g
co : coprime a' b'
g0 : gcd (a' * g) (b' * g) > 0
h : a' ^ n ∣ b' ^ n
this : a' ^ succ 0 ∣ a' ^ n
⊢ a' * g ∣ b' * g
[PROOFSTEP]
rw [pow_one, (co.pow n n).eq_one_of_dvd h] at this
[GOAL]
case inr.intro.intro.intro.intro.intro.intro
n : ℕ
n0 : 0 < n
g : ℕ
a' b' : ℕ
g0' : 0 < g
co : coprime a' b'
g0 : gcd (a' * g) (b' * g) > 0
h : a' ^ n ∣ b' ^ n
this : a' ∣ 1
⊢ a' * g ∣ b' * g
[PROOFSTEP]
simp [eq_one_of_dvd_one this]
[GOAL]
a b k : ℕ
h_ab_coprime : coprime a b
hka : k ∣ a
hkb : k ∣ b
⊢ k = 1
[PROOFSTEP]
rw [coprime_iff_gcd_eq_one] at h_ab_coprime
[GOAL]
a b k : ℕ
h_ab_coprime : gcd a b = 1
hka : k ∣ a
hkb : k ∣ b
⊢ k = 1
[PROOFSTEP]
have h1 := dvd_gcd hka hkb
[GOAL]
a b k : ℕ
h_ab_coprime : gcd a b = 1
hka : k ∣ a
hkb : k ∣ b
h1 : k ∣ gcd a b
⊢ k = 1
[PROOFSTEP]
rw [h_ab_coprime] at h1
[GOAL]
a b k : ℕ
h_ab_coprime : gcd a b = 1
hka : k ∣ a
hkb : k ∣ b
h1 : k ∣ 1
⊢ k = 1
[PROOFSTEP]
exact Nat.dvd_one.mp h1
[GOAL]
m n a b : ℕ
cop : coprime m n
ha : a ≠ 0
hb : b ≠ 0
⊢ a * m + b * n ≠ m * n
[PROOFSTEP]
intro h
[GOAL]
m n a b : ℕ
cop : coprime m n
ha : a ≠ 0
hb : b ≠ 0
h : a * m + b * n = m * n
⊢ False
[PROOFSTEP]
obtain ⟨x, rfl⟩ : n ∣ a :=
  cop.symm.dvd_of_dvd_mul_right
    ((Nat.dvd_add_iff_left (Nat.dvd_mul_left n b)).mpr ((congr_arg _ h).mpr (Nat.dvd_mul_left n m)))
[GOAL]
case intro
m n b : ℕ
cop : coprime m n
hb : b ≠ 0
x : ℕ
ha : n * x ≠ 0
h : n * x * m + b * n = m * n
⊢ False
[PROOFSTEP]
obtain ⟨y, rfl⟩ : m ∣ b :=
  cop.dvd_of_dvd_mul_right
    ((Nat.dvd_add_iff_right (Nat.dvd_mul_left m (n * x))).mpr ((congr_arg _ h).mpr (Nat.dvd_mul_right m n)))
[GOAL]
case intro.intro
m n : ℕ
cop : coprime m n
x : ℕ
ha : n * x ≠ 0
y : ℕ
hb : m * y ≠ 0
h : n * x * m + m * y * n = m * n
⊢ False
[PROOFSTEP]
rw [mul_comm, mul_ne_zero_iff, ← one_le_iff_ne_zero] at ha hb
[GOAL]
case intro.intro
m n : ℕ
cop : coprime m n
x : ℕ
ha : 1 ≤ x ∧ n ≠ 0
y : ℕ
hb : 1 ≤ y ∧ m ≠ 0
h : n * x * m + m * y * n = m * n
⊢ False
[PROOFSTEP]
refine' mul_ne_zero hb.2 ha.2 (eq_zero_of_mul_eq_self_left (ne_of_gt (add_le_add ha.1 hb.1)) _)
[GOAL]
case intro.intro
m n : ℕ
cop : coprime m n
x : ℕ
ha : 1 ≤ x ∧ n ≠ 0
y : ℕ
hb : 1 ≤ y ∧ m ≠ 0
h : n * x * m + m * y * n = m * n
⊢ (x + y) * (m * n) = m * n
[PROOFSTEP]
rw [← mul_assoc, ← h, add_mul, add_mul, mul_comm _ n, ← mul_assoc, mul_comm y]


[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
r : R
⊢ ↑(ι (Q' Q)) (m, r) = ↑(v Q) m + r • e0 Q
[PROOFSTEP]
rw [e0, v, LinearMap.comp_apply, LinearMap.inl_apply, ← LinearMap.map_smul, Prod.smul_mk, smul_zero, smul_eq_mul,
  mul_one, ← LinearMap.map_add, Prod.mk_add_mk, zero_add, add_zero]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
⊢ ↑(algebraMap R (CliffordAlgebra (Q' Q))) (↑(Q' Q) (0, 1)) = -1
[PROOFSTEP]
simp
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(algebraMap R (CliffordAlgebra (Q' Q))) (↑(Q' Q) (↑(LinearMap.inl R M R) m)) =
    ↑(algebraMap R (CliffordAlgebra (Q' Q))) (↑Q m)
[PROOFSTEP]
simp
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ -(e0 Q * ↑(v Q) m) = ↑(v Q) m * e0 Q
[PROOFSTEP]
refine' neg_eq_of_add_eq_zero_right ((ι_mul_ι_add_swap _ _).trans _)
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(algebraMap R (CliffordAlgebra (Q' Q))) (QuadraticForm.polar ↑(Q' Q) (0, 1) (↑(LinearMap.inl R M R) m)) = 0
[PROOFSTEP]
dsimp [QuadraticForm.polar]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(algebraMap R (CliffordAlgebra (Q' Q))) (↑Q (0 + m) + -((1 + 0) * (1 + 0)) - (↑Q 0 + -(1 * 1)) - (↑Q m + -(0 * 0))) =
    0
[PROOFSTEP]
simp only [add_zero, mul_zero, mul_one, zero_add, neg_zero, QuadraticForm.map_zero, add_sub_cancel, sub_self, map_zero,
  zero_sub]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ -(↑(v Q) m * e0 Q) = e0 Q * ↑(v Q) m
[PROOFSTEP]
rw [neg_eq_iff_eq_neg]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(v Q) m * e0 Q = -(e0 Q * ↑(v Q) m)
[PROOFSTEP]
exact (neg_e0_mul_v _ m).symm
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ e0 Q * ↑(v Q) m * e0 Q = ↑(v Q) m
[PROOFSTEP]
rw [← neg_v_mul_e0, ← neg_mul, mul_assoc, e0_mul_e0, mul_neg_one, neg_neg]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
⊢ CliffordAlgebra Q →ₐ[R] { x // x ∈ even (Q' Q) }
[PROOFSTEP]
refine' CliffordAlgebra.lift Q ⟨_, fun m => _⟩
[GOAL]
case refine'_1
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
⊢ M →ₗ[R] { x // x ∈ even (Q' Q) }
[PROOFSTEP]
refine' LinearMap.codRestrict _ _ fun m => Submodule.mem_iSup_of_mem ⟨2, rfl⟩ _
[GOAL]
case refine'_1.refine'_1
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
⊢ M →ₗ[R] CliffordAlgebra (Q' Q)
case refine'_1.refine'_2
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑?refine'_1.refine'_1 m ∈ LinearMap.range (ι (Q' Q)) ^ ↑{ val := 2, property := (_ : ↑2 = ↑2) }
[PROOFSTEP]
exact (LinearMap.mulLeft R <| e0 Q).comp (v Q)
[GOAL]
case refine'_1.refine'_2
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q)) m ∈
    LinearMap.range (ι (Q' Q)) ^ ↑{ val := 2, property := (_ : ↑2 = ↑2) }
[PROOFSTEP]
rw [Subtype.coe_mk, pow_two]
[GOAL]
case refine'_1.refine'_2
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q)) m ∈ LinearMap.range (ι (Q' Q)) * LinearMap.range (ι (Q' Q))
[PROOFSTEP]
exact Submodule.mul_mem_mul (LinearMap.mem_range_self _ _) (LinearMap.mem_range_self _ _)
[GOAL]
case refine'_2
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(LinearMap.codRestrict (⨆ (i : { n // ↑n = 0 }), LinearMap.range (ι (Q' Q)) ^ ↑i)
            (LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q))
            (_ :
              ∀ (m : M),
                ↑(LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q)) m ∈
                  ⨆ (i : { n // ↑n = 0 }), LinearMap.range (ι (Q' Q)) ^ ↑i))
        m *
      ↑(LinearMap.codRestrict (⨆ (i : { n // ↑n = 0 }), LinearMap.range (ι (Q' Q)) ^ ↑i)
            (LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q))
            (_ :
              ∀ (m : M),
                ↑(LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q)) m ∈
                  ⨆ (i : { n // ↑n = 0 }), LinearMap.range (ι (Q' Q)) ^ ↑i))
        m =
    ↑(algebraMap R { x // x ∈ even (Q' Q) }) (↑Q m)
[PROOFSTEP]
ext1
[GOAL]
case refine'_2.a
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(↑(LinearMap.codRestrict (⨆ (i : { n // ↑n = 0 }), LinearMap.range (ι (Q' Q)) ^ ↑i)
              (LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q))
              (_ :
                ∀ (m : M),
                  ↑(LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q)) m ∈
                    ⨆ (i : { n // ↑n = 0 }), LinearMap.range (ι (Q' Q)) ^ ↑i))
          m *
        ↑(LinearMap.codRestrict (⨆ (i : { n // ↑n = 0 }), LinearMap.range (ι (Q' Q)) ^ ↑i)
              (LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q))
              (_ :
                ∀ (m : M),
                  ↑(LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q)) m ∈
                    ⨆ (i : { n // ↑n = 0 }), LinearMap.range (ι (Q' Q)) ^ ↑i))
          m) =
    ↑(↑(algebraMap R { x // x ∈ even (Q' Q) }) (↑Q m))
[PROOFSTEP]
rw [Subalgebra.coe_mul]
  -- porting note: was part of the `dsimp only` below
[GOAL]
case refine'_2.a
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(↑(LinearMap.codRestrict (⨆ (i : { n // ↑n = 0 }), LinearMap.range (ι (Q' Q)) ^ ↑i)
              (LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q))
              (_ :
                ∀ (m : M),
                  ↑(LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q)) m ∈
                    ⨆ (i : { n // ↑n = 0 }), LinearMap.range (ι (Q' Q)) ^ ↑i))
          m) *
      ↑(↑(LinearMap.codRestrict (⨆ (i : { n // ↑n = 0 }), LinearMap.range (ι (Q' Q)) ^ ↑i)
              (LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q))
              (_ :
                ∀ (m : M),
                  ↑(LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q)) m ∈
                    ⨆ (i : { n // ↑n = 0 }), LinearMap.range (ι (Q' Q)) ^ ↑i))
          m) =
    ↑(↑(algebraMap R { x // x ∈ even (Q' Q) }) (↑Q m))
[PROOFSTEP]
erw [LinearMap.codRestrict_apply]
  -- porting note: was part of the `dsimp only` below
[GOAL]
case refine'_2.a
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q)) m * ↑(LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q)) m =
    ↑(↑(algebraMap R { x // x ∈ even (Q' Q) }) (↑Q m))
[PROOFSTEP]
dsimp only [LinearMap.comp_apply, LinearMap.mulLeft_apply, Subalgebra.coe_algebraMap]
[GOAL]
case refine'_2.a
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ e0 Q * ↑(v Q) m * (e0 Q * ↑(v Q) m) = ↑(algebraMap R (CliffordAlgebra (Q' Q))) (↑Q m)
[PROOFSTEP]
rw [← mul_assoc, e0_mul_v_mul_e0, v_sq_scalar]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(↑(toEven Q) (↑(ι Q) m)) = e0 Q * ↑(v Q) m
[PROOFSTEP]
rw [toEven, CliffordAlgebra.lift_ι_apply]
  -- porting note: was `rw`
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(↑(LinearMap.codRestrict (⨆ (i : { n // ↑n = 0 }), LinearMap.range (ι (Q' Q)) ^ ↑i)
            (LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q))
            (_ :
              ∀ (m : M),
                ↑(LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q)) m ∈
                  ⨆ (i : { n // ↑n = 0 }), LinearMap.range (ι (Q' Q)) ^ ↑i))
        m) =
    e0 Q * ↑(v Q) m
[PROOFSTEP]
erw [LinearMap.codRestrict_apply]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(LinearMap.comp (LinearMap.mulLeft R (e0 Q)) (v Q)) m = e0 Q * ↑(v Q) m
[PROOFSTEP]
rfl
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
⊢ { x // x ∈ even (Q' Q) } →ₐ[R] CliffordAlgebra Q
[PROOFSTEP]
let f : M × R →ₗ[R] M × R →ₗ[R] CliffordAlgebra Q :=
  ((Algebra.lmul R (CliffordAlgebra Q)).toLinearMap.comp <|
        (ι Q).comp (LinearMap.fst _ _ _) + (Algebra.linearMap R _).comp (LinearMap.snd _ _ _)).compl₂
    ((ι Q).comp (LinearMap.fst _ _ _) - (Algebra.linearMap R _).comp (LinearMap.snd _ _ _))
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
f : M × R →ₗ[R] M × R →ₗ[R] CliffordAlgebra Q :=
  LinearMap.compl₂
    (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
      (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
        LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
    (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
      LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R))
⊢ { x // x ∈ even (Q' Q) } →ₐ[R] CliffordAlgebra Q
[PROOFSTEP]
haveI f_apply : ∀ x y, f x y = (ι Q x.1 + algebraMap R _ x.2) * (ι Q y.1 - algebraMap R _ y.2) := fun x y => by rfl
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
f : M × R →ₗ[R] M × R →ₗ[R] CliffordAlgebra Q :=
  LinearMap.compl₂
    (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
      (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
        LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
    (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
      LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R))
x y : M × R
⊢ ↑(↑f x) y =
    (↑(ι Q) x.fst + ↑(algebraMap R (CliffordAlgebra Q)) x.snd) *
      (↑(ι Q) y.fst - ↑(algebraMap R (CliffordAlgebra Q)) y.snd)
[PROOFSTEP]
rfl
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
f : M × R →ₗ[R] M × R →ₗ[R] CliffordAlgebra Q :=
  LinearMap.compl₂
    (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
      (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
        LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
    (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
      LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R))
f_apply :
  ∀ (x y : M × R),
    ↑(↑f x) y =
      (↑(ι Q) x.fst + ↑(algebraMap R (CliffordAlgebra Q)) x.snd) *
        (↑(ι Q) y.fst - ↑(algebraMap R (CliffordAlgebra Q)) y.snd)
⊢ { x // x ∈ even (Q' Q) } →ₐ[R] CliffordAlgebra Q
[PROOFSTEP]
haveI hc : ∀ (r : R) (x : CliffordAlgebra Q), Commute (algebraMap _ _ r) x := Algebra.commutes
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
f : M × R →ₗ[R] M × R →ₗ[R] CliffordAlgebra Q :=
  LinearMap.compl₂
    (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
      (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
        LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
    (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
      LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R))
f_apply :
  ∀ (x y : M × R),
    ↑(↑f x) y =
      (↑(ι Q) x.fst + ↑(algebraMap R (CliffordAlgebra Q)) x.snd) *
        (↑(ι Q) y.fst - ↑(algebraMap R (CliffordAlgebra Q)) y.snd)
hc : ∀ (r : R) (x : CliffordAlgebra Q), Commute (↑(algebraMap R (CliffordAlgebra Q)) r) x
⊢ { x // x ∈ even (Q' Q) } →ₐ[R] CliffordAlgebra Q
[PROOFSTEP]
haveI hm : ∀ m : M × R, ι Q m.1 * ι Q m.1 - algebraMap R _ m.2 * algebraMap R _ m.2 = algebraMap R _ (Q' Q m) :=
  by
  intro m
  rw [ι_sq_scalar, ← RingHom.map_mul, ← RingHom.map_sub, sub_eq_add_neg, Q'_apply, sub_eq_add_neg]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
f : M × R →ₗ[R] M × R →ₗ[R] CliffordAlgebra Q :=
  LinearMap.compl₂
    (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
      (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
        LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
    (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
      LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R))
f_apply :
  ∀ (x y : M × R),
    ↑(↑f x) y =
      (↑(ι Q) x.fst + ↑(algebraMap R (CliffordAlgebra Q)) x.snd) *
        (↑(ι Q) y.fst - ↑(algebraMap R (CliffordAlgebra Q)) y.snd)
hc : ∀ (r : R) (x : CliffordAlgebra Q), Commute (↑(algebraMap R (CliffordAlgebra Q)) r) x
⊢ ∀ (m : M × R),
    ↑(ι Q) m.fst * ↑(ι Q) m.fst -
        ↑(algebraMap R (CliffordAlgebra Q)) m.snd * ↑(algebraMap R (CliffordAlgebra Q)) m.snd =
      ↑(algebraMap R (CliffordAlgebra Q)) (↑(Q' Q) m)
[PROOFSTEP]
intro m
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
f : M × R →ₗ[R] M × R →ₗ[R] CliffordAlgebra Q :=
  LinearMap.compl₂
    (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
      (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
        LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
    (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
      LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R))
f_apply :
  ∀ (x y : M × R),
    ↑(↑f x) y =
      (↑(ι Q) x.fst + ↑(algebraMap R (CliffordAlgebra Q)) x.snd) *
        (↑(ι Q) y.fst - ↑(algebraMap R (CliffordAlgebra Q)) y.snd)
hc : ∀ (r : R) (x : CliffordAlgebra Q), Commute (↑(algebraMap R (CliffordAlgebra Q)) r) x
m : M × R
⊢ ↑(ι Q) m.fst * ↑(ι Q) m.fst - ↑(algebraMap R (CliffordAlgebra Q)) m.snd * ↑(algebraMap R (CliffordAlgebra Q)) m.snd =
    ↑(algebraMap R (CliffordAlgebra Q)) (↑(Q' Q) m)
[PROOFSTEP]
rw [ι_sq_scalar, ← RingHom.map_mul, ← RingHom.map_sub, sub_eq_add_neg, Q'_apply, sub_eq_add_neg]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
f : M × R →ₗ[R] M × R →ₗ[R] CliffordAlgebra Q :=
  LinearMap.compl₂
    (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
      (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
        LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
    (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
      LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R))
f_apply :
  ∀ (x y : M × R),
    ↑(↑f x) y =
      (↑(ι Q) x.fst + ↑(algebraMap R (CliffordAlgebra Q)) x.snd) *
        (↑(ι Q) y.fst - ↑(algebraMap R (CliffordAlgebra Q)) y.snd)
hc : ∀ (r : R) (x : CliffordAlgebra Q), Commute (↑(algebraMap R (CliffordAlgebra Q)) r) x
hm :
  ∀ (m : M × R),
    ↑(ι Q) m.fst * ↑(ι Q) m.fst -
        ↑(algebraMap R (CliffordAlgebra Q)) m.snd * ↑(algebraMap R (CliffordAlgebra Q)) m.snd =
      ↑(algebraMap R (CliffordAlgebra Q)) (↑(Q' Q) m)
⊢ { x // x ∈ even (Q' Q) } →ₐ[R] CliffordAlgebra Q
[PROOFSTEP]
refine' even.lift (Q' Q) ⟨f, _, _⟩
[GOAL]
case refine'_1
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
f : M × R →ₗ[R] M × R →ₗ[R] CliffordAlgebra Q :=
  LinearMap.compl₂
    (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
      (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
        LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
    (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
      LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R))
f_apply :
  ∀ (x y : M × R),
    ↑(↑f x) y =
      (↑(ι Q) x.fst + ↑(algebraMap R (CliffordAlgebra Q)) x.snd) *
        (↑(ι Q) y.fst - ↑(algebraMap R (CliffordAlgebra Q)) y.snd)
hc : ∀ (r : R) (x : CliffordAlgebra Q), Commute (↑(algebraMap R (CliffordAlgebra Q)) r) x
hm :
  ∀ (m : M × R),
    ↑(ι Q) m.fst * ↑(ι Q) m.fst -
        ↑(algebraMap R (CliffordAlgebra Q)) m.snd * ↑(algebraMap R (CliffordAlgebra Q)) m.snd =
      ↑(algebraMap R (CliffordAlgebra Q)) (↑(Q' Q) m)
⊢ ∀ (m : M × R), ↑(↑f m) m = ↑(algebraMap R (CliffordAlgebra Q)) (↑(Q' Q) m)
[PROOFSTEP]
simp_rw [f_apply]
[GOAL]
case refine'_2
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
f : M × R →ₗ[R] M × R →ₗ[R] CliffordAlgebra Q :=
  LinearMap.compl₂
    (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
      (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
        LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
    (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
      LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R))
f_apply :
  ∀ (x y : M × R),
    ↑(↑f x) y =
      (↑(ι Q) x.fst + ↑(algebraMap R (CliffordAlgebra Q)) x.snd) *
        (↑(ι Q) y.fst - ↑(algebraMap R (CliffordAlgebra Q)) y.snd)
hc : ∀ (r : R) (x : CliffordAlgebra Q), Commute (↑(algebraMap R (CliffordAlgebra Q)) r) x
hm :
  ∀ (m : M × R),
    ↑(ι Q) m.fst * ↑(ι Q) m.fst -
        ↑(algebraMap R (CliffordAlgebra Q)) m.snd * ↑(algebraMap R (CliffordAlgebra Q)) m.snd =
      ↑(algebraMap R (CliffordAlgebra Q)) (↑(Q' Q) m)
⊢ ∀ (m₁ m₂ m₃ : M × R), ↑(↑f m₁) m₂ * ↑(↑f m₂) m₃ = ↑(Q' Q) m₂ • ↑(↑f m₁) m₃
[PROOFSTEP]
simp_rw [f_apply]
[GOAL]
case refine'_1
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
f : M × R →ₗ[R] M × R →ₗ[R] CliffordAlgebra Q :=
  LinearMap.compl₂
    (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
      (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
        LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
    (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
      LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R))
f_apply :
  ∀ (x y : M × R),
    ↑(↑f x) y =
      (↑(ι Q) x.fst + ↑(algebraMap R (CliffordAlgebra Q)) x.snd) *
        (↑(ι Q) y.fst - ↑(algebraMap R (CliffordAlgebra Q)) y.snd)
hc : ∀ (r : R) (x : CliffordAlgebra Q), Commute (↑(algebraMap R (CliffordAlgebra Q)) r) x
hm :
  ∀ (m : M × R),
    ↑(ι Q) m.fst * ↑(ι Q) m.fst -
        ↑(algebraMap R (CliffordAlgebra Q)) m.snd * ↑(algebraMap R (CliffordAlgebra Q)) m.snd =
      ↑(algebraMap R (CliffordAlgebra Q)) (↑(Q' Q) m)
⊢ ∀ (m : M × R),
    (↑(ι Q) m.fst + ↑(algebraMap R (CliffordAlgebra Q)) m.snd) *
        (↑(ι Q) m.fst - ↑(algebraMap R (CliffordAlgebra Q)) m.snd) =
      ↑(algebraMap R (CliffordAlgebra Q)) (↑(Q' Q) m)
[PROOFSTEP]
intro m
[GOAL]
case refine'_1
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
f : M × R →ₗ[R] M × R →ₗ[R] CliffordAlgebra Q :=
  LinearMap.compl₂
    (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
      (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
        LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
    (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
      LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R))
f_apply :
  ∀ (x y : M × R),
    ↑(↑f x) y =
      (↑(ι Q) x.fst + ↑(algebraMap R (CliffordAlgebra Q)) x.snd) *
        (↑(ι Q) y.fst - ↑(algebraMap R (CliffordAlgebra Q)) y.snd)
hc : ∀ (r : R) (x : CliffordAlgebra Q), Commute (↑(algebraMap R (CliffordAlgebra Q)) r) x
hm :
  ∀ (m : M × R),
    ↑(ι Q) m.fst * ↑(ι Q) m.fst -
        ↑(algebraMap R (CliffordAlgebra Q)) m.snd * ↑(algebraMap R (CliffordAlgebra Q)) m.snd =
      ↑(algebraMap R (CliffordAlgebra Q)) (↑(Q' Q) m)
m : M × R
⊢ (↑(ι Q) m.fst + ↑(algebraMap R (CliffordAlgebra Q)) m.snd) *
      (↑(ι Q) m.fst - ↑(algebraMap R (CliffordAlgebra Q)) m.snd) =
    ↑(algebraMap R (CliffordAlgebra Q)) (↑(Q' Q) m)
[PROOFSTEP]
rw [← (hc _ _).symm.mul_self_sub_mul_self_eq, hm]
[GOAL]
case refine'_2
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
f : M × R →ₗ[R] M × R →ₗ[R] CliffordAlgebra Q :=
  LinearMap.compl₂
    (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
      (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
        LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
    (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
      LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R))
f_apply :
  ∀ (x y : M × R),
    ↑(↑f x) y =
      (↑(ι Q) x.fst + ↑(algebraMap R (CliffordAlgebra Q)) x.snd) *
        (↑(ι Q) y.fst - ↑(algebraMap R (CliffordAlgebra Q)) y.snd)
hc : ∀ (r : R) (x : CliffordAlgebra Q), Commute (↑(algebraMap R (CliffordAlgebra Q)) r) x
hm :
  ∀ (m : M × R),
    ↑(ι Q) m.fst * ↑(ι Q) m.fst -
        ↑(algebraMap R (CliffordAlgebra Q)) m.snd * ↑(algebraMap R (CliffordAlgebra Q)) m.snd =
      ↑(algebraMap R (CliffordAlgebra Q)) (↑(Q' Q) m)
⊢ ∀ (m₁ m₂ m₃ : M × R),
    (↑(ι Q) m₁.fst + ↑(algebraMap R (CliffordAlgebra Q)) m₁.snd) *
          (↑(ι Q) m₂.fst - ↑(algebraMap R (CliffordAlgebra Q)) m₂.snd) *
        ((↑(ι Q) m₂.fst + ↑(algebraMap R (CliffordAlgebra Q)) m₂.snd) *
          (↑(ι Q) m₃.fst - ↑(algebraMap R (CliffordAlgebra Q)) m₃.snd)) =
      ↑(Q' Q) m₂ •
        ((↑(ι Q) m₁.fst + ↑(algebraMap R (CliffordAlgebra Q)) m₁.snd) *
          (↑(ι Q) m₃.fst - ↑(algebraMap R (CliffordAlgebra Q)) m₃.snd))
[PROOFSTEP]
intro m₁ m₂ m₃
[GOAL]
case refine'_2
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
f : M × R →ₗ[R] M × R →ₗ[R] CliffordAlgebra Q :=
  LinearMap.compl₂
    (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
      (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
        LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
    (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
      LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R))
f_apply :
  ∀ (x y : M × R),
    ↑(↑f x) y =
      (↑(ι Q) x.fst + ↑(algebraMap R (CliffordAlgebra Q)) x.snd) *
        (↑(ι Q) y.fst - ↑(algebraMap R (CliffordAlgebra Q)) y.snd)
hc : ∀ (r : R) (x : CliffordAlgebra Q), Commute (↑(algebraMap R (CliffordAlgebra Q)) r) x
hm :
  ∀ (m : M × R),
    ↑(ι Q) m.fst * ↑(ι Q) m.fst -
        ↑(algebraMap R (CliffordAlgebra Q)) m.snd * ↑(algebraMap R (CliffordAlgebra Q)) m.snd =
      ↑(algebraMap R (CliffordAlgebra Q)) (↑(Q' Q) m)
m₁ m₂ m₃ : M × R
⊢ (↑(ι Q) m₁.fst + ↑(algebraMap R (CliffordAlgebra Q)) m₁.snd) *
        (↑(ι Q) m₂.fst - ↑(algebraMap R (CliffordAlgebra Q)) m₂.snd) *
      ((↑(ι Q) m₂.fst + ↑(algebraMap R (CliffordAlgebra Q)) m₂.snd) *
        (↑(ι Q) m₃.fst - ↑(algebraMap R (CliffordAlgebra Q)) m₃.snd)) =
    ↑(Q' Q) m₂ •
      ((↑(ι Q) m₁.fst + ↑(algebraMap R (CliffordAlgebra Q)) m₁.snd) *
        (↑(ι Q) m₃.fst - ↑(algebraMap R (CliffordAlgebra Q)) m₃.snd))
[PROOFSTEP]
rw [← mul_smul_comm, ← mul_assoc, mul_assoc (_ + _), ← (hc _ _).symm.mul_self_sub_mul_self_eq', Algebra.smul_def, ←
  mul_assoc, hm]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
x y : M × R
⊢ ↑(ofEven Q) (↑(↑(even.ι (Q' Q)).bilin x) y) =
    (↑(ι Q) x.fst + ↑(algebraMap R (CliffordAlgebra Q)) x.snd) *
      (↑(ι Q) y.fst - ↑(algebraMap R (CliffordAlgebra Q)) y.snd)
[PROOFSTEP]
unfold ofEven
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
x y : M × R
⊢ ↑(let f :=
          LinearMap.compl₂
            (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
              (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
                LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
            (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
              LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R));
        ↑(even.lift (Q' Q))
          { bilin := f,
            contract :=
              (_ :
                ∀ (m : M × R),
                  ↑(↑(LinearMap.compl₂
                              (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
                                (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
                                  LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                              (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
                                LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                          m)
                      m =
                    ↑(algebraMap R (CliffordAlgebra Q)) (↑(Q' Q) m)),
            contract_mid :=
              (_ :
                ∀ (m₁ m₂ m₃ : M × R),
                  ↑(↑(LinearMap.compl₂
                                (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
                                  (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
                                    LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                                (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
                                  LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                            m₁)
                        m₂ *
                      ↑(↑(LinearMap.compl₂
                                (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
                                  (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
                                    LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                                (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
                                  LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                            m₂)
                        m₃ =
                    ↑(Q' Q) m₂ •
                      ↑(↑(LinearMap.compl₂
                                (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
                                  (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
                                    LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                                (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
                                  LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                            m₁)
                        m₃) })
      (↑(↑(even.ι (Q' Q)).bilin x) y) =
    (↑(ι Q) x.fst + ↑(algebraMap R (CliffordAlgebra Q)) x.snd) *
      (↑(ι Q) y.fst - ↑(algebraMap R (CliffordAlgebra Q)) y.snd)
[PROOFSTEP]
lift_lets
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
x y : M × R
⊢ let f :=
    LinearMap.compl₂
      (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
        (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
          LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
      (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
        LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R));
  ↑(↑(even.lift (Q' Q))
          { bilin := f,
            contract :=
              (_ :
                ∀ (m : M × R),
                  ↑(↑(LinearMap.compl₂
                              (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
                                (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
                                  LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                              (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
                                LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                          m)
                      m =
                    ↑(algebraMap R (CliffordAlgebra Q)) (↑(Q' Q) m)),
            contract_mid :=
              (_ :
                ∀ (m₁ m₂ m₃ : M × R),
                  ↑(↑(LinearMap.compl₂
                                (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
                                  (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
                                    LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                                (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
                                  LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                            m₁)
                        m₂ *
                      ↑(↑(LinearMap.compl₂
                                (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
                                  (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
                                    LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                                (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
                                  LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                            m₂)
                        m₃ =
                    ↑(Q' Q) m₂ •
                      ↑(↑(LinearMap.compl₂
                                (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
                                  (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
                                    LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                                (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
                                  LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                            m₁)
                        m₃) })
      (↑(↑(even.ι (Q' Q)).bilin x) y) =
    (↑(ι Q) x.fst + ↑(algebraMap R (CliffordAlgebra Q)) x.snd) *
      (↑(ι Q) y.fst - ↑(algebraMap R (CliffordAlgebra Q)) y.snd)
[PROOFSTEP]
intro f
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
x y : M × R
f : M × R →ₗ[R] M × R →ₗ[R] CliffordAlgebra Q :=
  LinearMap.compl₂
    (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
      (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
        LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
    (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
      LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R))
⊢ ↑(↑(even.lift (Q' Q))
          { bilin := f,
            contract :=
              (_ :
                ∀ (m : M × R),
                  ↑(↑(LinearMap.compl₂
                              (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
                                (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
                                  LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                              (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
                                LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                          m)
                      m =
                    ↑(algebraMap R (CliffordAlgebra Q)) (↑(Q' Q) m)),
            contract_mid :=
              (_ :
                ∀ (m₁ m₂ m₃ : M × R),
                  ↑(↑(LinearMap.compl₂
                                (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
                                  (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
                                    LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                                (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
                                  LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                            m₁)
                        m₂ *
                      ↑(↑(LinearMap.compl₂
                                (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
                                  (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
                                    LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                                (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
                                  LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                            m₂)
                        m₃ =
                    ↑(Q' Q) m₂ •
                      ↑(↑(LinearMap.compl₂
                                (LinearMap.comp (AlgHom.toLinearMap (Algebra.lmul R (CliffordAlgebra Q)))
                                  (LinearMap.comp (ι Q) (LinearMap.fst R M R) +
                                    LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                                (LinearMap.comp (ι Q) (LinearMap.fst R M R) -
                                  LinearMap.comp (Algebra.linearMap R (CliffordAlgebra Q)) (LinearMap.snd R M R)))
                            m₁)
                        m₃) })
      (↑(↑(even.ι (Q' Q)).bilin x) y) =
    (↑(ι Q) x.fst + ↑(algebraMap R (CliffordAlgebra Q)) x.snd) *
      (↑(ι Q) y.fst - ↑(algebraMap R (CliffordAlgebra Q)) y.snd)
[PROOFSTEP]
refine @even.lift_ι R (M × R) _ _ _ (Q' Q) _ _ _ ⟨f, ?_, ?_⟩ x y
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m₁✝ m₂✝ : M × R
m₁ : M
r₁ : R
m₂ : M
r₂ : R
⊢ ↑(↑(toEven Q) (↑(ofEven Q) (↑(↑(even.ι (Q' Q)).bilin (m₁, r₁)) (m₂, r₂)))) =
    (e0 Q * ↑(v Q) m₁ + ↑(algebraMap R (CliffordAlgebra (Q' Q))) r₁) *
      (e0 Q * ↑(v Q) m₂ - ↑(algebraMap R (CliffordAlgebra (Q' Q))) r₂)
[PROOFSTEP]
rw [ofEven_ι, AlgHom.map_mul, AlgHom.map_add, AlgHom.map_sub, AlgHom.commutes, AlgHom.commutes, Subalgebra.coe_mul,
  Subalgebra.coe_add, Subalgebra.coe_sub, toEven_ι, toEven_ι, Subalgebra.coe_algebraMap, Subalgebra.coe_algebraMap]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m₁✝ m₂✝ : M × R
m₁ : M
r₁ : R
m₂ : M
r₂ : R
⊢ (e0 Q * ↑(v Q) m₁ + ↑(algebraMap R (CliffordAlgebra (Q' Q))) r₁) *
      (e0 Q * ↑(v Q) m₂ - ↑(algebraMap R (CliffordAlgebra (Q' Q))) r₂) =
    e0 Q * ↑(v Q) m₁ * (e0 Q * ↑(v Q) m₂) + r₁ • e0 Q * ↑(v Q) m₂ - r₂ • e0 Q * ↑(v Q) m₁ -
      ↑(algebraMap R (CliffordAlgebra (Q' Q))) (r₁ * r₂)
[PROOFSTEP]
rw [mul_sub, add_mul, add_mul, ← Algebra.commutes, ← Algebra.smul_def, ← map_mul, ← Algebra.smul_def,
  sub_add_eq_sub_sub, smul_mul_assoc, smul_mul_assoc]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m₁✝ m₂✝ : M × R
m₁ : M
r₁ : R
m₂ : M
r₂ : R
⊢ e0 Q * ↑(v Q) m₁ * (e0 Q * ↑(v Q) m₂) + r₁ • e0 Q * ↑(v Q) m₂ - r₂ • e0 Q * ↑(v Q) m₁ -
      ↑(algebraMap R (CliffordAlgebra (Q' Q))) (r₁ * r₂) =
    ↑(v Q) m₁ * ↑(v Q) m₂ + r₁ • e0 Q * ↑(v Q) m₂ + ↑(v Q) m₁ * r₂ • e0 Q + r₁ • e0 Q * r₂ • e0 Q
[PROOFSTEP]
have h1 : e0 Q * v Q m₁ * (e0 Q * v Q m₂) = v Q m₁ * v Q m₂ := by rw [← mul_assoc, e0_mul_v_mul_e0]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m₁✝ m₂✝ : M × R
m₁ : M
r₁ : R
m₂ : M
r₂ : R
⊢ e0 Q * ↑(v Q) m₁ * (e0 Q * ↑(v Q) m₂) = ↑(v Q) m₁ * ↑(v Q) m₂
[PROOFSTEP]
rw [← mul_assoc, e0_mul_v_mul_e0]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m₁✝ m₂✝ : M × R
m₁ : M
r₁ : R
m₂ : M
r₂ : R
h1 : e0 Q * ↑(v Q) m₁ * (e0 Q * ↑(v Q) m₂) = ↑(v Q) m₁ * ↑(v Q) m₂
⊢ e0 Q * ↑(v Q) m₁ * (e0 Q * ↑(v Q) m₂) + r₁ • e0 Q * ↑(v Q) m₂ - r₂ • e0 Q * ↑(v Q) m₁ -
      ↑(algebraMap R (CliffordAlgebra (Q' Q))) (r₁ * r₂) =
    ↑(v Q) m₁ * ↑(v Q) m₂ + r₁ • e0 Q * ↑(v Q) m₂ + ↑(v Q) m₁ * r₂ • e0 Q + r₁ • e0 Q * r₂ • e0 Q
[PROOFSTEP]
have h2 : -(r₂ • e0 Q * v Q m₁) = v Q m₁ * r₂ • e0 Q := by rw [mul_smul_comm, smul_mul_assoc, ← smul_neg, neg_e0_mul_v]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m₁✝ m₂✝ : M × R
m₁ : M
r₁ : R
m₂ : M
r₂ : R
h1 : e0 Q * ↑(v Q) m₁ * (e0 Q * ↑(v Q) m₂) = ↑(v Q) m₁ * ↑(v Q) m₂
⊢ -(r₂ • e0 Q * ↑(v Q) m₁) = ↑(v Q) m₁ * r₂ • e0 Q
[PROOFSTEP]
rw [mul_smul_comm, smul_mul_assoc, ← smul_neg, neg_e0_mul_v]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m₁✝ m₂✝ : M × R
m₁ : M
r₁ : R
m₂ : M
r₂ : R
h1 : e0 Q * ↑(v Q) m₁ * (e0 Q * ↑(v Q) m₂) = ↑(v Q) m₁ * ↑(v Q) m₂
h2 : -(r₂ • e0 Q * ↑(v Q) m₁) = ↑(v Q) m₁ * r₂ • e0 Q
⊢ e0 Q * ↑(v Q) m₁ * (e0 Q * ↑(v Q) m₂) + r₁ • e0 Q * ↑(v Q) m₂ - r₂ • e0 Q * ↑(v Q) m₁ -
      ↑(algebraMap R (CliffordAlgebra (Q' Q))) (r₁ * r₂) =
    ↑(v Q) m₁ * ↑(v Q) m₂ + r₁ • e0 Q * ↑(v Q) m₂ + ↑(v Q) m₁ * r₂ • e0 Q + r₁ • e0 Q * r₂ • e0 Q
[PROOFSTEP]
have h3 : -algebraMap R _ (r₁ * r₂) = r₁ • e0 Q * r₂ • e0 Q := by
  rw [Algebra.algebraMap_eq_smul_one, smul_mul_smul, e0_mul_e0, smul_neg]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m₁✝ m₂✝ : M × R
m₁ : M
r₁ : R
m₂ : M
r₂ : R
h1 : e0 Q * ↑(v Q) m₁ * (e0 Q * ↑(v Q) m₂) = ↑(v Q) m₁ * ↑(v Q) m₂
h2 : -(r₂ • e0 Q * ↑(v Q) m₁) = ↑(v Q) m₁ * r₂ • e0 Q
⊢ -↑(algebraMap R (CliffordAlgebra (Q' Q))) (r₁ * r₂) = r₁ • e0 Q * r₂ • e0 Q
[PROOFSTEP]
rw [Algebra.algebraMap_eq_smul_one, smul_mul_smul, e0_mul_e0, smul_neg]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m₁✝ m₂✝ : M × R
m₁ : M
r₁ : R
m₂ : M
r₂ : R
h1 : e0 Q * ↑(v Q) m₁ * (e0 Q * ↑(v Q) m₂) = ↑(v Q) m₁ * ↑(v Q) m₂
h2 : -(r₂ • e0 Q * ↑(v Q) m₁) = ↑(v Q) m₁ * r₂ • e0 Q
h3 : -↑(algebraMap R (CliffordAlgebra (Q' Q))) (r₁ * r₂) = r₁ • e0 Q * r₂ • e0 Q
⊢ e0 Q * ↑(v Q) m₁ * (e0 Q * ↑(v Q) m₂) + r₁ • e0 Q * ↑(v Q) m₂ - r₂ • e0 Q * ↑(v Q) m₁ -
      ↑(algebraMap R (CliffordAlgebra (Q' Q))) (r₁ * r₂) =
    ↑(v Q) m₁ * ↑(v Q) m₂ + r₁ • e0 Q * ↑(v Q) m₂ + ↑(v Q) m₁ * r₂ • e0 Q + r₁ • e0 Q * r₂ • e0 Q
[PROOFSTEP]
rw [sub_eq_add_neg, sub_eq_add_neg, h1, h2, h3]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m₁✝ m₂✝ : M × R
m₁ : M
r₁ : R
m₂ : M
r₂ : R
⊢ ↑(v Q) m₁ * ↑(v Q) m₂ + r₁ • e0 Q * ↑(v Q) m₂ + ↑(v Q) m₁ * r₂ • e0 Q + r₁ • e0 Q * r₂ • e0 Q =
    ↑(ι (Q' Q)) (m₁, r₁) * ↑(ι (Q' Q)) (m₂, r₂)
[PROOFSTEP]
rw [ι_eq_v_add_smul_e0, ι_eq_v_add_smul_e0, mul_add, add_mul, add_mul, add_assoc]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(ofEven Q) (↑(toEven Q) (↑(ι Q) m)) =
    ↑(ofEven Q) { val := ↑(↑(toEven Q) (↑(ι Q) m)), property := (_ : ↑(↑(toEven Q) (↑(ι Q) m)) ∈ even (Q' Q)) }
[PROOFSTEP]
rw [Subtype.coe_eta]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(ofEven Q) { val := ↑(↑(toEven Q) (↑(ι Q) m)), property := (_ : ↑(↑(toEven Q) (↑(ι Q) m)) ∈ even (Q' Q)) } =
    (↑(ι Q) 0 + ↑(algebraMap R (CliffordAlgebra Q)) 1) * (↑(ι Q) m - ↑(algebraMap R (CliffordAlgebra Q)) 0)
[PROOFSTEP]
simp_rw [toEven_ι]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(ofEven Q) { val := e0 Q * ↑(v Q) m, property := (_ : (fun x => x ∈ even (Q' Q)) (e0 Q * ↑(v Q) m)) } =
    (↑(ι Q) 0 + ↑(algebraMap R (CliffordAlgebra Q)) 1) * (↑(ι Q) m - ↑(algebraMap R (CliffordAlgebra Q)) 0)
[PROOFSTEP]
exact ofEven_ι Q _ _
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ (↑(ι Q) 0 + ↑(algebraMap R (CliffordAlgebra Q)) 1) * (↑(ι Q) m - ↑(algebraMap R (CliffordAlgebra Q)) 0) = ↑(ι Q) m
[PROOFSTEP]
rw [map_one, map_zero, map_zero, sub_zero, zero_add, one_mul]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
x : CliffordAlgebra Q
⊢ ↑(↑(toEven Q) (↑reverse (↑involute x))) = ↑reverse ↑(↑(toEven Q) x)
[PROOFSTEP]
induction x using CliffordAlgebra.induction
[GOAL]
case h_grade0
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
r✝ : R
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (↑(algebraMap R (CliffordAlgebra Q)) r✝)))) =
    ↑reverse ↑(↑(toEven Q) (↑(algebraMap R (CliffordAlgebra Q)) r✝))
case h_grade1
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
x✝ : M
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (↑(ι Q) x✝)))) = ↑reverse ↑(↑(toEven Q) (↑(ι Q) x✝))
case h_mul
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
a✝² b✝ : CliffordAlgebra Q
a✝¹ : ↑(↑(toEven Q) (↑reverse (↑involute a✝²))) = ↑reverse ↑(↑(toEven Q) a✝²)
a✝ : ↑(↑(toEven Q) (↑reverse (↑involute b✝))) = ↑reverse ↑(↑(toEven Q) b✝)
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (a✝² * b✝)))) = ↑reverse ↑(↑(toEven Q) (a✝² * b✝))
case h_add
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
a✝² b✝ : CliffordAlgebra Q
a✝¹ : ↑(↑(toEven Q) (↑reverse (↑involute a✝²))) = ↑reverse ↑(↑(toEven Q) a✝²)
a✝ : ↑(↑(toEven Q) (↑reverse (↑involute b✝))) = ↑reverse ↑(↑(toEven Q) b✝)
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (a✝² + b✝)))) = ↑reverse ↑(↑(toEven Q) (a✝² + b✝))
[PROOFSTEP]
case h_grade0 r => simp only [AlgHom.commutes, Subalgebra.coe_algebraMap, reverse.commutes]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
r : R
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (↑(algebraMap R (CliffordAlgebra Q)) r)))) =
    ↑reverse ↑(↑(toEven Q) (↑(algebraMap R (CliffordAlgebra Q)) r))
[PROOFSTEP]
case h_grade0 r => simp only [AlgHom.commutes, Subalgebra.coe_algebraMap, reverse.commutes]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
r : R
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (↑(algebraMap R (CliffordAlgebra Q)) r)))) =
    ↑reverse ↑(↑(toEven Q) (↑(algebraMap R (CliffordAlgebra Q)) r))
[PROOFSTEP]
simp only [AlgHom.commutes, Subalgebra.coe_algebraMap, reverse.commutes]
[GOAL]
case h_grade1
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
x✝ : M
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (↑(ι Q) x✝)))) = ↑reverse ↑(↑(toEven Q) (↑(ι Q) x✝))
case h_mul
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
a✝² b✝ : CliffordAlgebra Q
a✝¹ : ↑(↑(toEven Q) (↑reverse (↑involute a✝²))) = ↑reverse ↑(↑(toEven Q) a✝²)
a✝ : ↑(↑(toEven Q) (↑reverse (↑involute b✝))) = ↑reverse ↑(↑(toEven Q) b✝)
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (a✝² * b✝)))) = ↑reverse ↑(↑(toEven Q) (a✝² * b✝))
case h_add
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
a✝² b✝ : CliffordAlgebra Q
a✝¹ : ↑(↑(toEven Q) (↑reverse (↑involute a✝²))) = ↑reverse ↑(↑(toEven Q) a✝²)
a✝ : ↑(↑(toEven Q) (↑reverse (↑involute b✝))) = ↑reverse ↑(↑(toEven Q) b✝)
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (a✝² + b✝)))) = ↑reverse ↑(↑(toEven Q) (a✝² + b✝))
[PROOFSTEP]
case h_grade1 m =>
  -- porting note: added `letI`
  letI : SubtractionMonoid (even (Q' Q)) := AddGroup.toSubtractionMonoid
  simp only [involute_ι, Subalgebra.coe_neg, toEven_ι, reverse.map_mul, reverse_v, reverse_e0, reverse_ι, neg_e0_mul_v,
    map_neg]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (↑(ι Q) m)))) = ↑reverse ↑(↑(toEven Q) (↑(ι Q) m))
[PROOFSTEP]
case h_grade1 m =>
  -- porting note: added `letI`
  letI : SubtractionMonoid (even (Q' Q)) := AddGroup.toSubtractionMonoid
  simp only [involute_ι, Subalgebra.coe_neg, toEven_ι, reverse.map_mul, reverse_v, reverse_e0, reverse_ι, neg_e0_mul_v,
    map_neg]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (↑(ι Q) m)))) = ↑reverse ↑(↑(toEven Q) (↑(ι Q) m))
[PROOFSTEP]
letI : SubtractionMonoid (even (Q' Q)) := AddGroup.toSubtractionMonoid
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
m : M
this : SubtractionMonoid { x // x ∈ even (Q' Q) } := AddGroup.toSubtractionMonoid
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (↑(ι Q) m)))) = ↑reverse ↑(↑(toEven Q) (↑(ι Q) m))
[PROOFSTEP]
simp only [involute_ι, Subalgebra.coe_neg, toEven_ι, reverse.map_mul, reverse_v, reverse_e0, reverse_ι, neg_e0_mul_v,
  map_neg]
[GOAL]
case h_mul
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
a✝² b✝ : CliffordAlgebra Q
a✝¹ : ↑(↑(toEven Q) (↑reverse (↑involute a✝²))) = ↑reverse ↑(↑(toEven Q) a✝²)
a✝ : ↑(↑(toEven Q) (↑reverse (↑involute b✝))) = ↑reverse ↑(↑(toEven Q) b✝)
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (a✝² * b✝)))) = ↑reverse ↑(↑(toEven Q) (a✝² * b✝))
case h_add
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
a✝² b✝ : CliffordAlgebra Q
a✝¹ : ↑(↑(toEven Q) (↑reverse (↑involute a✝²))) = ↑reverse ↑(↑(toEven Q) a✝²)
a✝ : ↑(↑(toEven Q) (↑reverse (↑involute b✝))) = ↑reverse ↑(↑(toEven Q) b✝)
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (a✝² + b✝)))) = ↑reverse ↑(↑(toEven Q) (a✝² + b✝))
[PROOFSTEP]
case h_mul x y hx hy => simp only [map_mul, Subalgebra.coe_mul, reverse.map_mul, hx, hy]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
x y : CliffordAlgebra Q
hx : ↑(↑(toEven Q) (↑reverse (↑involute x))) = ↑reverse ↑(↑(toEven Q) x)
hy : ↑(↑(toEven Q) (↑reverse (↑involute y))) = ↑reverse ↑(↑(toEven Q) y)
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (x * y)))) = ↑reverse ↑(↑(toEven Q) (x * y))
[PROOFSTEP]
case h_mul x y hx hy => simp only [map_mul, Subalgebra.coe_mul, reverse.map_mul, hx, hy]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
x y : CliffordAlgebra Q
hx : ↑(↑(toEven Q) (↑reverse (↑involute x))) = ↑reverse ↑(↑(toEven Q) x)
hy : ↑(↑(toEven Q) (↑reverse (↑involute y))) = ↑reverse ↑(↑(toEven Q) y)
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (x * y)))) = ↑reverse ↑(↑(toEven Q) (x * y))
[PROOFSTEP]
simp only [map_mul, Subalgebra.coe_mul, reverse.map_mul, hx, hy]
[GOAL]
case h_add
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
a✝² b✝ : CliffordAlgebra Q
a✝¹ : ↑(↑(toEven Q) (↑reverse (↑involute a✝²))) = ↑reverse ↑(↑(toEven Q) a✝²)
a✝ : ↑(↑(toEven Q) (↑reverse (↑involute b✝))) = ↑reverse ↑(↑(toEven Q) b✝)
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (a✝² + b✝)))) = ↑reverse ↑(↑(toEven Q) (a✝² + b✝))
[PROOFSTEP]
case h_add x y hx hy => simp only [map_add, Subalgebra.coe_add, hx, hy]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
x y : CliffordAlgebra Q
hx : ↑(↑(toEven Q) (↑reverse (↑involute x))) = ↑reverse ↑(↑(toEven Q) x)
hy : ↑(↑(toEven Q) (↑reverse (↑involute y))) = ↑reverse ↑(↑(toEven Q) y)
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (x + y)))) = ↑reverse ↑(↑(toEven Q) (x + y))
[PROOFSTEP]
case h_add x y hx hy => simp only [map_add, Subalgebra.coe_add, hx, hy]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
x y : CliffordAlgebra Q
hx : ↑(↑(toEven Q) (↑reverse (↑involute x))) = ↑reverse ↑(↑(toEven Q) x)
hy : ↑(↑(toEven Q) (↑reverse (↑involute y))) = ↑reverse ↑(↑(toEven Q) y)
⊢ ↑(↑(toEven Q) (↑reverse (↑involute (x + y)))) = ↑reverse ↑(↑(toEven Q) (x + y))
[PROOFSTEP]
simp only [map_add, Subalgebra.coe_add, hx, hy]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q Q' : QuadraticForm R M
h : Q' = -Q
this✝ : AddCommGroup { x // x ∈ even Q' } := AddSubgroupClass.toAddCommGroup (even Q')
this : HasDistribNeg { x // x ∈ even Q' } := NonUnitalNonAssocRing.toHasDistribNeg
m : M
⊢ ↑(↑(-(even.ι Q').bilin) m) m = ↑(algebraMap R { x // x ∈ even Q' }) (↑Q m)
[PROOFSTEP]
simp_rw [LinearMap.neg_apply, EvenHom.contract, h, QuadraticForm.neg_apply, map_neg, neg_neg]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q Q' : QuadraticForm R M
h : Q' = -Q
this✝ : AddCommGroup { x // x ∈ even Q' } := AddSubgroupClass.toAddCommGroup (even Q')
this : HasDistribNeg { x // x ∈ even Q' } := NonUnitalNonAssocRing.toHasDistribNeg
m₁ m₂ m₃ : M
⊢ ↑(↑(-(even.ι Q').bilin) m₁) m₂ * ↑(↑(-(even.ι Q').bilin) m₂) m₃ = ↑Q m₂ • ↑(↑(-(even.ι Q').bilin) m₁) m₃
[PROOFSTEP]
simp_rw [LinearMap.neg_apply, neg_mul_neg, EvenHom.contract_mid, h, QuadraticForm.neg_apply, smul_neg, neg_smul]
[GOAL]
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q Q' : QuadraticForm R M
h : Q' = -Q
h' : Q = -Q'
⊢ AlgHom.comp (evenToNeg Q' Q h') (evenToNeg Q Q' h) = AlgHom.id R { x // x ∈ even Q }
[PROOFSTEP]
ext m₁ m₂ : 4
[GOAL]
case h.bilin.h.h
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q Q' : QuadraticForm R M
h : Q' = -Q
h' : Q = -Q'
m₁ m₂ : M
⊢ ↑(↑(EvenHom.compr₂ (even.ι Q) (AlgHom.comp (evenToNeg Q' Q h') (evenToNeg Q Q' h))).bilin m₁) m₂ =
    ↑(↑(EvenHom.compr₂ (even.ι Q) (AlgHom.id R { x // x ∈ even Q })).bilin m₁) m₂
[PROOFSTEP]
dsimp only [EvenHom.compr₂_bilin, LinearMap.compr₂_apply, AlgHom.toLinearMap_apply, AlgHom.comp_apply, AlgHom.id_apply]
[GOAL]
case h.bilin.h.h
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q Q' : QuadraticForm R M
h : Q' = -Q
h' : Q = -Q'
m₁ m₂ : M
⊢ ↑(evenToNeg Q' Q h') (↑(evenToNeg Q Q' h) (↑(↑(even.ι Q).bilin m₁) m₂)) = ↑(↑(even.ι Q).bilin m₁) m₂
[PROOFSTEP]
rw [evenToNeg_ι, map_neg, evenToNeg_ι, neg_neg]