-- Mathlib/LinearAlgebra/CliffordAlgebra/Fold.lean
theorem right_induction {P : CliffordAlgebra Q → Prop} (algebraMap : ∀ r : R, P (algebraMap _ _ r))
    (add : ∀ x y, P x → P y → P (x + y)) (mul_ι : ∀ m x, P x → P (x * ι Q m)) : ∀ x, P x

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
P : CliffordAlgebra Q → Prop
algebraMap : ∀ (r : R), P ((_root_.algebraMap R (CliffordAlgebra Q)) r)
add : ∀ (x y : CliffordAlgebra Q), P x → P y → P (x + y)
mul_ι : ∀ (m : M) (x : CliffordAlgebra Q), P x → P (x * (ι Q) m)
⊢ ∀ (x : CliffordAlgebra Q), P x

Tactic:
intro x

Result:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
P : CliffordAlgebra Q → Prop
algebraMap : ∀ (r : R), P ((_root_.algebraMap R (CliffordAlgebra Q)) r)
add : ∀ (x y : CliffordAlgebra Q), P x → P y → P (x + y)
mul_ι : ∀ (m : M) (x : CliffordAlgebra Q), P x → P (x * (ι Q) m)
x : CliffordAlgebra Q
⊢ P x

Proof state:
case mem
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
P : CliffordAlgebra Q → Prop
algebraMap : ∀ (r : R), P ((_root_.algebraMap R (CliffordAlgebra Q)) r)
add : ∀ (x y : CliffordAlgebra Q), P x → P y → P (x + y)
mul_ι : ∀ (m : M) (x : CliffordAlgebra Q), P x → P (x * (ι Q) m)
x✝ : CliffordAlgebra Q
i : ℕ
x : CliffordAlgebra Q
hx : x ∈ LinearMap.range (ι Q) ^ i
⊢ P x

Tactic:
induction hx using Submodule.pow_induction_on_right' with
| algebraMap r => exact algebraMap r
| add _x _y _i _ _ ihx ihy => exact add _ _ ihx ihy
| mul_mem _i x _hx px m hm =>
  obtain ⟨m, rfl⟩ := hm
  exact mul_ι _ _ px

Result:
no goals

Proof state:
case mem.add
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
P : CliffordAlgebra Q → Prop
algebraMap : ∀ (r : R), P ((_root_.algebraMap R (CliffordAlgebra Q)) r)
add : ∀ (x y : CliffordAlgebra Q), P x → P y → P (x + y)
mul_ι : ∀ (m : M) (x : CliffordAlgebra Q), P x → P (x * (ι Q) m)
x✝ : CliffordAlgebra Q
i : ℕ
x _x _y : CliffordAlgebra Q
_i : ℕ
hx✝ : _x ∈ LinearMap.range (ι Q) ^ _i
hy✝ : _y ∈ LinearMap.range (ι Q) ^ _i
ihx : P _x
ihy : P _y
⊢ P (_x + _y)

Tactic:
exact add _ _ ihx ihy

Result:
no goals

Proof state:
case mem.mul_mem
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
P : CliffordAlgebra Q → Prop
algebraMap : ∀ (r : R), P ((_root_.algebraMap R (CliffordAlgebra Q)) r)
add : ∀ (x y : CliffordAlgebra Q), P x → P y → P (x + y)
mul_ι : ∀ (m : M) (x : CliffordAlgebra Q), P x → P (x * (ι Q) m)
x✝¹ : CliffordAlgebra Q
i : ℕ
x✝ : CliffordAlgebra Q
_i : ℕ
x : CliffordAlgebra Q
_hx : x ∈ LinearMap.range (ι Q) ^ _i
px : P x
m : CliffordAlgebra Q
hm : m ∈ LinearMap.range (ι Q)
⊢ P (x * m)

Tactic:
obtain ⟨m, rfl⟩ := hm

Result:
case mem.mul_mem.intro
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
P : CliffordAlgebra Q → Prop
algebraMap : ∀ (r : R), P ((_root_.algebraMap R (CliffordAlgebra Q)) r)
add : ∀ (x y : CliffordAlgebra Q), P x → P y → P (x + y)
mul_ι : ∀ (m : M) (x : CliffordAlgebra Q), P x → P (x * (ι Q) m)
x✝¹ : CliffordAlgebra Q
i : ℕ
x✝ : CliffordAlgebra Q
_i : ℕ
x : CliffordAlgebra Q
_hx : x ∈ LinearMap.range (ι Q) ^ _i
px : P x
m : M
⊢ P (x * (ι Q) m)

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
P : CliffordAlgebra Q → Prop
algebraMap : ∀ (r : R), P ((_root_.algebraMap R (CliffordAlgebra Q)) r)
add : ∀ (x y : CliffordAlgebra Q), P x → P y → P (x + y)
mul_ι : ∀ (m : M) (x : CliffordAlgebra Q), P x → P (x * (ι Q) m)
x : CliffordAlgebra Q
⊢ P x

Tactic:
have : x ∈ ⊤ := Submodule.mem_top (R := R)

Result:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
P : CliffordAlgebra Q → Prop
algebraMap : ∀ (r : R), P ((_root_.algebraMap R (CliffordAlgebra Q)) r)
add : ∀ (x y : CliffordAlgebra Q), P x → P y → P (x + y)
mul_ι : ∀ (m : M) (x : CliffordAlgebra Q), P x → P (x * (ι Q) m)
x : CliffordAlgebra Q
this : x ∈ ⊤
⊢ P x

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
P : CliffordAlgebra Q → Prop
algebraMap : ∀ (r : R), P ((_root_.algebraMap R (CliffordAlgebra Q)) r)
add : ∀ (x y : CliffordAlgebra Q), P x → P y → P (x + y)
mul_ι : ∀ (m : M) (x : CliffordAlgebra Q), P x → P (x * (ι Q) m)
x : CliffordAlgebra Q
this : x ∈ ⊤
⊢ P x

Tactic:
rw [← iSup_ι_range_eq_top] at this

Result:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
P : CliffordAlgebra Q → Prop
algebraMap : ∀ (r : R), P ((_root_.algebraMap R (CliffordAlgebra Q)) r)
add : ∀ (x y : CliffordAlgebra Q), P x → P y → P (x + y)
mul_ι : ∀ (m : M) (x : CliffordAlgebra Q), P x → P (x * (ι Q) m)
x : CliffordAlgebra Q
this : x ∈ ⨆ i, LinearMap.range (ι Q) ^ i
⊢ P x

Proof state:
case mem.mul_mem.intro
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
P : CliffordAlgebra Q → Prop
algebraMap : ∀ (r : R), P ((_root_.algebraMap R (CliffordAlgebra Q)) r)
add : ∀ (x y : CliffordAlgebra Q), P x → P y → P (x + y)
mul_ι : ∀ (m : M) (x : CliffordAlgebra Q), P x → P (x * (ι Q) m)
x✝¹ : CliffordAlgebra Q
i : ℕ
x✝ : CliffordAlgebra Q
_i : ℕ
x : CliffordAlgebra Q
_hx : x ∈ LinearMap.range (ι Q) ^ _i
px : P x
m : M
⊢ P (x * (ι Q) m)

Tactic:
exact mul_ι _ _ px

Result:
no goals

Proof state:
case add
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
P : CliffordAlgebra Q → Prop
algebraMap : ∀ (r : R), P ((_root_.algebraMap R (CliffordAlgebra Q)) r)
add : ∀ (x y : CliffordAlgebra Q), P x → P y → P (x + y)
mul_ι : ∀ (m : M) (x : CliffordAlgebra Q), P x → P (x * (ι Q) m)
x _x _y : CliffordAlgebra Q
hx✝ : _x ∈ ⨆ i, LinearMap.range (ι Q) ^ i
hy✝ : _y ∈ ⨆ i, LinearMap.range (ι Q) ^ i
ihx : P _x
ihy : P _y
⊢ P (_x + _y)

Tactic:
exact add _ _ ihx ihy

Result:
no goals

Proof state:
case zero
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
P : CliffordAlgebra Q → Prop
algebraMap : ∀ (r : R), P ((_root_.algebraMap R (CliffordAlgebra Q)) r)
add : ∀ (x y : CliffordAlgebra Q), P x → P y → P (x + y)
mul_ι : ∀ (m : M) (x : CliffordAlgebra Q), P x → P (x * (ι Q) m)
x : CliffordAlgebra Q
⊢ P 0

Tactic:
simpa only [map_zero] using algebraMap 0

Result:
no goals

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
P : CliffordAlgebra Q → Prop
algebraMap : ∀ (r : R), P ((_root_.algebraMap R (CliffordAlgebra Q)) r)
add : ∀ (x y : CliffordAlgebra Q), P x → P y → P (x + y)
mul_ι : ∀ (m : M) (x : CliffordAlgebra Q), P x → P (x * (ι Q) m)
x : CliffordAlgebra Q
this : x ∈ ⨆ i, LinearMap.range (ι Q) ^ i
⊢ P x

Tactic:
induction this using Submodule.iSup_induction' with
| mem i x hx =>
  induction hx using Submodule.pow_induction_on_right' with
  | algebraMap r => exact algebraMap r
  | add _x _y _i _ _ ihx ihy => exact add _ _ ihx ihy
  | mul_mem _i x _hx px m hm =>
    obtain ⟨m, rfl⟩ := hm
    exact mul_ι _ _ px
| zero => simpa only [map_zero] using algebraMap 0
| add _x _y _ _ ihx ihy =>
  exact add _ _ ihx ihy

Result:
no goals