l3lab/ntp-mathlib huggingface dataset:
/-- `E.mkSol` indeed gives solutions to `E`. -/
theorem is_sol_mkSol (init : Fin E.order → α) : E.IsSolution (E.mkSol init) := by
  intro n
  

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
init : Fin E.order → α
n : ℕ
⊢ mkSol E init (n + E.order) = ∑ i : Fin E.order, coeffs E i * mkSol E init (n + ↑i)

Next tactic:
rw [mkSol]
/-- `E.mkSol` indeed gives solutions to `E`. -/
theorem is_sol_mkSol (init : Fin E.order → α) : E.IsSolution (E.mkSol init) := by
  intro n
  rw [mkSol]
  

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
init : Fin E.order → α
n : ℕ
⊢ (if h : n + E.order < E.order then init { val := n + E.order, isLt := h }
    else
      ∑ k : Fin E.order,
        let_fun x := (_ : n + E.order - E.order + ↑k < n + E.order);
        coeffs E k * mkSol E init (n + E.order - E.order + ↑k)) =
    ∑ i : Fin E.order, coeffs E i * mkSol E init (n + ↑i)

Next tactic:
simp
/-- `E.mkSol init`'s first `E.order` terms are `init`. -/
theorem mkSol_eq_init (init : Fin E.order → α) : ∀ n : Fin E.order, E.mkSol init n = init n := by
  

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
init : Fin E.order → α
⊢ ∀ (n : Fin E.order), mkSol E init ↑n = init n

Next tactic:
intro n
/-- `E.mkSol init`'s first `E.order` terms are `init`. -/
theorem mkSol_eq_init (init : Fin E.order → α) : ∀ n : Fin E.order, E.mkSol init n = init n := by
  intro n
  

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
init : Fin E.order → α
n : Fin E.order
⊢ mkSol E init ↑n = init n

Next tactic:
rw [mkSol]
/-- `E.mkSol init`'s first `E.order` terms are `init`. -/
theorem mkSol_eq_init (init : Fin E.order → α) : ∀ n : Fin E.order, E.mkSol init n = init n := by
  intro n
  rw [mkSol]
  

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
init : Fin E.order → α
n : Fin E.order
⊢ (if h : ↑n < E.order then init { val := ↑n, isLt := h }
    else
      ∑ k : Fin E.order,
        let_fun x := (_ : ↑n - E.order + ↑k < ↑n);
        coeffs E k * mkSol E init (↑n - E.order + ↑k)) =
    init n

Next tactic:
simp only [n.is_lt, dif_pos, Fin.mk_val, Fin.eta]
/-- If `u` is a solution to `E` and `init` designates its first `E.order` values,
  then `∀ n, u n = E.mkSol init n`. -/
theorem eq_mk_of_is_sol_of_eq_init {u : ℕ → α} {init : Fin E.order → α} (h : E.IsSolution u)
    (heq : ∀ n : Fin E.order, u n = init n) : ∀ n, u n = E.mkSol init n := by
  

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
⊢ ∀ (n : ℕ), u n = mkSol E init n

Next tactic:
intro n
/-- If `u` is a solution to `E` and `init` designates its first `E.order` values,
  then `∀ n, u n = E.mkSol init n`. -/
theorem eq_mk_of_is_sol_of_eq_init {u : ℕ → α} {init : Fin E.order → α} (h : E.IsSolution u)
    (heq : ∀ n : Fin E.order, u n = init n) : ∀ n, u n = E.mkSol init n := by
  intro n
  

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
⊢ u n = mkSol E init n

Next tactic:
rw [mkSol]
/-- If `u` is a solution to `E` and `init` designates its first `E.order` values,
  then `∀ n, u n = E.mkSol init n`. -/
theorem eq_mk_of_is_sol_of_eq_init {u : ℕ → α} {init : Fin E.order → α} (h : E.IsSolution u)
    (heq : ∀ n : Fin E.order, u n = init n) : ∀ n, u n = E.mkSol init n := by
  intro n
  rw [mkSol]
  

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
⊢ u n =
    if h : n < E.order then init { val := n, isLt := h }
    else
      ∑ k : Fin E.order,
        let_fun x := (_ : n - E.order + ↑k < n);
        coeffs E k * mkSol E init (n - E.order + ↑k)

Next tactic:
split_ifs with h'
/-- If `u` is a solution to `E` and `init` designates its first `E.order` values,
  then `∀ n, u n = E.mkSol init n`. -/
theorem eq_mk_of_is_sol_of_eq_init {u : ℕ → α} {init : Fin E.order → α} (h : E.IsSolution u)
    (heq : ∀ n : Fin E.order, u n = init n) : ∀ n, u n = E.mkSol init n := by
  intro n
  rw [mkSol]
  split_ifs with h'
  · 

Proof state:
case pos
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : n < E.order
⊢ u n = init { val := n, isLt := h' }

Next tactic:
exact mod_cast heq ⟨n, h'⟩
/-- If `u` is a solution to `E` and `init` designates its first `E.order` values,
  then `∀ n, u n = E.mkSol init n`. -/
theorem eq_mk_of_is_sol_of_eq_init {u : ℕ → α} {init : Fin E.order → α} (h : E.IsSolution u)
    (heq : ∀ n : Fin E.order, u n = init n) : ∀ n, u n = E.mkSol init n := by
  intro n
  rw [mkSol]
  split_ifs with h'
  · exact mod_cast heq ⟨n, h'⟩
  

Proof state:
case neg
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
⊢ u n =
    ∑ k : Fin E.order,
      let_fun x := (_ : n - E.order + ↑k < n);
      coeffs E k * mkSol E init (n - E.order + ↑k)

Next tactic:
simp only
/-- If `u` is a solution to `E` and `init` designates its first `E.order` values,
  then `∀ n, u n = E.mkSol init n`. -/
theorem eq_mk_of_is_sol_of_eq_init {u : ℕ → α} {init : Fin E.order → α} (h : E.IsSolution u)
    (heq : ∀ n : Fin E.order, u n = init n) : ∀ n, u n = E.mkSol init n := by
  intro n
  rw [mkSol]
  split_ifs with h'
  · exact mod_cast heq ⟨n, h'⟩
  simp only
  

Proof state:
case neg
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
⊢ u n = ∑ x : Fin E.order, coeffs E x * mkSol E init (n - E.order + ↑x)

Next tactic:
rw [← tsub_add_cancel_of_le (le_of_not_lt h'), h (n - E.order)]
/-- If `u` is a solution to `E` and `init` designates its first `E.order` values,
  then `∀ n, u n = E.mkSol init n`. -/
theorem eq_mk_of_is_sol_of_eq_init {u : ℕ → α} {init : Fin E.order → α} (h : E.IsSolution u)
    (heq : ∀ n : Fin E.order, u n = init n) : ∀ n, u n = E.mkSol init n := by
  intro n
  rw [mkSol]
  split_ifs with h'
  · exact mod_cast heq ⟨n, h'⟩
  simp only
  rw [← tsub_add_cancel_of_le (le_of_not_lt h'), h (n - E.order)]
  

Proof state:
case neg
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
⊢ ∑ i : Fin E.order, coeffs E i * u (n - E.order + ↑i) =
    ∑ x : Fin E.order, coeffs E x * mkSol E init (n - E.order + E.order - E.order + ↑x)

Next tactic:
congr with k
/-- If `u` is a solution to `E` and `init` designates its first `E.order` values,
  then `∀ n, u n = E.mkSol init n`. -/
theorem eq_mk_of_is_sol_of_eq_init {u : ℕ → α} {init : Fin E.order → α} (h : E.IsSolution u)
    (heq : ∀ n : Fin E.order, u n = init n) : ∀ n, u n = E.mkSol init n := by
  intro n
  rw [mkSol]
  split_ifs with h'
  · exact mod_cast heq ⟨n, h'⟩
  simp only
  rw [← tsub_add_cancel_of_le (le_of_not_lt h'), h (n - E.order)]
  congr with k
  

Proof state:
case neg.e_f.h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
k : Fin E.order
⊢ coeffs E k * u (n - E.order + ↑k) = coeffs E k * mkSol E init (n - E.order + E.order - E.order + ↑k)

Next tactic:
have : n - E.order + k < n := by
    rw [add_comm, ← add_tsub_assoc_of_le (not_lt.mp h'), tsub_lt_iff_left]
    · exact add_lt_add_right k.is_lt n
    · convert add_le_add (zero_le (k : ℕ)) (not_lt.mp h')
      simp only [zero_add]
/-- If `u` is a solution to `E` and `init` designates its first `E.order` values,
  then `∀ n, u n = E.mkSol init n`. -/
theorem eq_mk_of_is_sol_of_eq_init {u : ℕ → α} {init : Fin E.order → α} (h : E.IsSolution u)
    (heq : ∀ n : Fin E.order, u n = init n) : ∀ n, u n = E.mkSol init n := by
  intro n
  rw [mkSol]
  split_ifs with h'
  · exact mod_cast heq ⟨n, h'⟩
  simp only
  rw [← tsub_add_cancel_of_le (le_of_not_lt h'), h (n - E.order)]
  congr with k
  have : n - E.order + k < n := by
    

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
k : Fin E.order
⊢ n - E.order + ↑k < n

Next tactic:
rw [add_comm, ← add_tsub_assoc_of_le (not_lt.mp h'), tsub_lt_iff_left]
/-- If `u` is a solution to `E` and `init` designates its first `E.order` values,
  then `∀ n, u n = E.mkSol init n`. -/
theorem eq_mk_of_is_sol_of_eq_init {u : ℕ → α} {init : Fin E.order → α} (h : E.IsSolution u)
    (heq : ∀ n : Fin E.order, u n = init n) : ∀ n, u n = E.mkSol init n := by
  intro n
  rw [mkSol]
  split_ifs with h'
  · exact mod_cast heq ⟨n, h'⟩
  simp only
  rw [← tsub_add_cancel_of_le (le_of_not_lt h'), h (n - E.order)]
  congr with k
  have : n - E.order + k < n := by
    rw [add_comm, ← add_tsub_assoc_of_le (not_lt.mp h'), tsub_lt_iff_left]
    · 

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
k : Fin E.order
⊢ ↑k + n < E.order + n

Next tactic:
exact add_lt_add_right k.is_lt n
/-- If `u` is a solution to `E` and `init` designates its first `E.order` values,
  then `∀ n, u n = E.mkSol init n`. -/
theorem eq_mk_of_is_sol_of_eq_init {u : ℕ → α} {init : Fin E.order → α} (h : E.IsSolution u)
    (heq : ∀ n : Fin E.order, u n = init n) : ∀ n, u n = E.mkSol init n := by
  intro n
  rw [mkSol]
  split_ifs with h'
  · exact mod_cast heq ⟨n, h'⟩
  simp only
  rw [← tsub_add_cancel_of_le (le_of_not_lt h'), h (n - E.order)]
  congr with k
  have : n - E.order + k < n := by
    rw [add_comm, ← add_tsub_assoc_of_le (not_lt.mp h'), tsub_lt_iff_left]
    · exact add_lt_add_right k.is_lt n
    · 

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
k : Fin E.order
⊢ E.order ≤ ↑k + n

Next tactic:
convert add_le_add (zero_le (k : ℕ)) (not_lt.mp h')
/-- If `u` is a solution to `E` and `init` designates its first `E.order` values,
  then `∀ n, u n = E.mkSol init n`. -/
theorem eq_mk_of_is_sol_of_eq_init {u : ℕ → α} {init : Fin E.order → α} (h : E.IsSolution u)
    (heq : ∀ n : Fin E.order, u n = init n) : ∀ n, u n = E.mkSol init n := by
  intro n
  rw [mkSol]
  split_ifs with h'
  · exact mod_cast heq ⟨n, h'⟩
  simp only
  rw [← tsub_add_cancel_of_le (le_of_not_lt h'), h (n - E.order)]
  congr with k
  have : n - E.order + k < n := by
    rw [add_comm, ← add_tsub_assoc_of_le (not_lt.mp h'), tsub_lt_iff_left]
    · exact add_lt_add_right k.is_lt n
    · convert add_le_add (zero_le (k : ℕ)) (not_lt.mp h')
      

Proof state:
case h.e'_3
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
k : Fin E.order
⊢ E.order = 0 + E.order

Next tactic:
simp only [zero_add]
/-- If `u` is a solution to `E` and `init` designates its first `E.order` values,
  then `∀ n, u n = E.mkSol init n`. -/
theorem eq_mk_of_is_sol_of_eq_init {u : ℕ → α} {init : Fin E.order → α} (h : E.IsSolution u)
    (heq : ∀ n : Fin E.order, u n = init n) : ∀ n, u n = E.mkSol init n := by
  intro n
  rw [mkSol]
  split_ifs with h'
  · exact mod_cast heq ⟨n, h'⟩
  simp only
  rw [← tsub_add_cancel_of_le (le_of_not_lt h'), h (n - E.order)]
  congr with k
  have : n - E.order + k < n := by
    rw [add_comm, ← add_tsub_assoc_of_le (not_lt.mp h'), tsub_lt_iff_left]
    · exact add_lt_add_right k.is_lt n
    · convert add_le_add (zero_le (k : ℕ)) (not_lt.mp h')
      simp only [zero_add]
  

Proof state:
case neg.e_f.h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
k : Fin E.order
this : n - E.order + ↑k < n
⊢ coeffs E k * u (n - E.order + ↑k) = coeffs E k * mkSol E init (n - E.order + E.order - E.order + ↑k)

Next tactic:
rw [eq_mk_of_is_sol_of_eq_init h heq (n - E.order + k)]
/-- If `u` is a solution to `E` and `init` designates its first `E.order` values,
  then `∀ n, u n = E.mkSol init n`. -/
theorem eq_mk_of_is_sol_of_eq_init {u : ℕ → α} {init : Fin E.order → α} (h : E.IsSolution u)
    (heq : ∀ n : Fin E.order, u n = init n) : ∀ n, u n = E.mkSol init n := by
  intro n
  rw [mkSol]
  split_ifs with h'
  · exact mod_cast heq ⟨n, h'⟩
  simp only
  rw [← tsub_add_cancel_of_le (le_of_not_lt h'), h (n - E.order)]
  congr with k
  have : n - E.order + k < n := by
    rw [add_comm, ← add_tsub_assoc_of_le (not_lt.mp h'), tsub_lt_iff_left]
    · exact add_lt_add_right k.is_lt n
    · convert add_le_add (zero_le (k : ℕ)) (not_lt.mp h')
      simp only [zero_add]
  rw [eq_mk_of_is_sol_of_eq_init h heq (n - E.order + k)]
  

Proof state:
case neg.e_f.h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ℕ → α
init : Fin E.order → α
h : IsSolution E u
heq : ∀ (n : Fin E.order), u ↑n = init n
n : ℕ
h' : ¬n < E.order
k : Fin E.order
this : n - E.order + ↑k < n
⊢ coeffs E k * mkSol E (fun n => init n) (n - E.order + ↑k) =
    coeffs E k * mkSol E init (n - E.order + E.order - E.order + ↑k)

Next tactic:
simp
/-- The space of solutions of `E`, as a `Submodule` over `α` of the module `ℕ → α`. -/
def solSpace : Submodule α (ℕ → α) where
  carrier := { u | E.IsSolution u }
  zero_mem' n := by simp
  add_mem' {u v} hu hv n := by 

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u v : ℕ → α
hu : u ∈ {u | IsSolution E u}
hv : v ∈ {u | IsSolution E u}
n : ℕ
⊢ (u + v) (n + E.order) = ∑ i : Fin E.order, coeffs E i * (u + v) (n + ↑i)

Next tactic:
simp [mul_add, sum_add_distrib, hu n, hv n]
/-- The space of solutions of `E`, as a `Submodule` over `α` of the module `ℕ → α`. -/
def solSpace : Submodule α (ℕ → α) where
  carrier := { u | E.IsSolution u }
  zero_mem' n := by 

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
n : ℕ
⊢ OfNat.ofNat 0 (n + E.order) = ∑ i : Fin E.order, coeffs E i * OfNat.ofNat 0 (n + ↑i)

Next tactic:
simp
/-- The space of solutions of `E`, as a `Submodule` over `α` of the module `ℕ → α`. -/
def solSpace : Submodule α (ℕ → α) where
  carrier := { u | E.IsSolution u }
  zero_mem' n := by simp
  add_mem' {u v} hu hv n := by simp [mul_add, sum_add_distrib, hu n, hv n]
  smul_mem' a u hu n := by 

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
a : α
u : ℕ → α
hu :
  u ∈
    {
          toAddSubsemigroup :=
            { carrier := {u | IsSolution E u},
              add_mem' :=
                (_ :
                  ∀ {u v : ℕ → α},
                    u ∈ {u | IsSolution E u} →
                      v ∈ {u | IsSolution E u} →
                        ∀ (n : ℕ),
                          u (n + E.order) + v (n + E.order) = ∑ i : Fin E.order, coeffs E i * (u + v) (n + ↑i)) },
          zero_mem' :=
            (_ : ∀ (n : ℕ), 0 = ∑ i : Fin E.order, coeffs E i * OfNat.ofNat 0 (n + ↑i)) }.toAddSubsemigroup.carrier
n : ℕ
⊢ (a • u) (n + E.order) = ∑ i : Fin E.order, coeffs E i * (a • u) (n + ↑i)

Next tactic:
simp [hu n, mul_sum]
/-- The space of solutions of `E`, as a `Submodule` over `α` of the module `ℕ → α`. -/
def solSpace : Submodule α (ℕ → α) where
  carrier := { u | E.IsSolution u }
  zero_mem' n := by simp
  add_mem' {u v} hu hv n := by simp [mul_add, sum_add_distrib, hu n, hv n]
  smul_mem' a u hu n := by simp [hu n, mul_sum]; 

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
a : α
u : ℕ → α
hu :
  u ∈
    {
          toAddSubsemigroup :=
            { carrier := {u | IsSolution E u},
              add_mem' :=
                (_ :
                  ∀ {u v : ℕ → α},
                    u ∈ {u | IsSolution E u} →
                      v ∈ {u | IsSolution E u} →
                        ∀ (n : ℕ),
                          u (n + E.order) + v (n + E.order) = ∑ i : Fin E.order, coeffs E i * (u + v) (n + ↑i)) },
          zero_mem' :=
            (_ : ∀ (n : ℕ), 0 = ∑ i : Fin E.order, coeffs E i * OfNat.ofNat 0 (n + ↑i)) }.toAddSubsemigroup.carrier
n : ℕ
⊢ ∑ x : Fin E.order, a * (coeffs E x * u (n + ↑x)) = ∑ x : Fin E.order, coeffs E x * (a * u (n + ↑x))

Next tactic:
congr
/-- The space of solutions of `E`, as a `Submodule` over `α` of the module `ℕ → α`. -/
def solSpace : Submodule α (ℕ → α) where
  carrier := { u | E.IsSolution u }
  zero_mem' n := by simp
  add_mem' {u v} hu hv n := by simp [mul_add, sum_add_distrib, hu n, hv n]
  smul_mem' a u hu n := by simp [hu n, mul_sum]; congr; 

Proof state:
case e_f
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
a : α
u : ℕ → α
hu :
  u ∈
    {
          toAddSubsemigroup :=
            { carrier := {u | IsSolution E u},
              add_mem' :=
                (_ :
                  ∀ {u v : ℕ → α},
                    u ∈ {u | IsSolution E u} →
                      v ∈ {u | IsSolution E u} →
                        ∀ (n : ℕ),
                          u (n + E.order) + v (n + E.order) = ∑ i : Fin E.order, coeffs E i * (u + v) (n + ↑i)) },
          zero_mem' :=
            (_ : ∀ (n : ℕ), 0 = ∑ i : Fin E.order, coeffs E i * OfNat.ofNat 0 (n + ↑i)) }.toAddSubsemigroup.carrier
n : ℕ
⊢ (fun x => a * (coeffs E x * u (n + ↑x))) = fun x => coeffs E x * (a * u (n + ↑x))

Next tactic:
ext
/-- The space of solutions of `E`, as a `Submodule` over `α` of the module `ℕ → α`. -/
def solSpace : Submodule α (ℕ → α) where
  carrier := { u | E.IsSolution u }
  zero_mem' n := by simp
  add_mem' {u v} hu hv n := by simp [mul_add, sum_add_distrib, hu n, hv n]
  smul_mem' a u hu n := by simp [hu n, mul_sum]; congr; ext; 

Proof state:
case e_f.h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
a : α
u : ℕ → α
hu :
  u ∈
    {
          toAddSubsemigroup :=
            { carrier := {u | IsSolution E u},
              add_mem' :=
                (_ :
                  ∀ {u v : ℕ → α},
                    u ∈ {u | IsSolution E u} →
                      v ∈ {u | IsSolution E u} →
                        ∀ (n : ℕ),
                          u (n + E.order) + v (n + E.order) = ∑ i : Fin E.order, coeffs E i * (u + v) (n + ↑i)) },
          zero_mem' :=
            (_ : ∀ (n : ℕ), 0 = ∑ i : Fin E.order, coeffs E i * OfNat.ofNat 0 (n + ↑i)) }.toAddSubsemigroup.carrier
n : ℕ
x✝ : Fin E.order
⊢ a * (coeffs E x✝ * u (n + ↑x✝)) = coeffs E x✝ * (a * u (n + ↑x✝))

Next tactic:
ac_rfl
/-- The function that maps a solution `u` of `E` to its first
  `E.order` terms as a `LinearEquiv`. -/
def toInit : E.solSpace ≃ₗ[α] Fin E.order → α where
  toFun u x := (u : ℕ → α) x
  map_add' u v := by
    

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u v : ↥(solSpace E)
⊢ (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v

Next tactic:
ext
/-- The function that maps a solution `u` of `E` to its first
  `E.order` terms as a `LinearEquiv`. -/
def toInit : E.solSpace ≃ₗ[α] Fin E.order → α where
  toFun u x := (u : ℕ → α) x
  map_add' u v := by
    ext
    

Proof state:
case h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u v : ↥(solSpace E)
x✝ : Fin E.order
⊢ (fun u x => ↑u ↑x) (u + v) x✝ = ((fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) x✝

Next tactic:
simp
/-- The function that maps a solution `u` of `E` to its first
  `E.order` terms as a `LinearEquiv`. -/
def toInit : E.solSpace ≃ₗ[α] Fin E.order → α where
  toFun u x := (u : ℕ → α) x
  map_add' u v := by
    ext
    simp
  map_smul' a u := by
    

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
a : α
u : ↥(solSpace E)
⊢ AddHom.toFun
      { toFun := fun u x => ↑u ↑x,
        map_add' :=
          (_ : ∀ (u v : ↥(solSpace E)), (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
      (a • u) =
    (RingHom.id α) a •
      AddHom.toFun
        { toFun := fun u x => ↑u ↑x,
          map_add' :=
            (_ : ∀ (u v : ↥(solSpace E)), (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
        u

Next tactic:
ext
/-- The function that maps a solution `u` of `E` to its first
  `E.order` terms as a `LinearEquiv`. -/
def toInit : E.solSpace ≃ₗ[α] Fin E.order → α where
  toFun u x := (u : ℕ → α) x
  map_add' u v := by
    ext
    simp
  map_smul' a u := by
    ext
    

Proof state:
case h
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
a : α
u : ↥(solSpace E)
x✝ : Fin E.order
⊢ AddHom.toFun
      { toFun := fun u x => ↑u ↑x,
        map_add' :=
          (_ : ∀ (u v : ↥(solSpace E)), (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
      (a • u) x✝ =
    ((RingHom.id α) a •
        AddHom.toFun
          { toFun := fun u x => ↑u ↑x,
            map_add' :=
              (_ : ∀ (u v : ↥(solSpace E)), (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
          u)
      x✝

Next tactic:
simp
/-- The function that maps a solution `u` of `E` to its first
  `E.order` terms as a `LinearEquiv`. -/
def toInit : E.solSpace ≃ₗ[α] Fin E.order → α where
  toFun u x := (u : ℕ → α) x
  map_add' u v := by
    ext
    simp
  map_smul' a u := by
    ext
    simp
  invFun u := ⟨E.mkSol u, E.is_sol_mkSol u⟩
  left_inv u := by 

Proof state:
α : Type u_1
inst✝ : CommSemiring α
E : LinearRecurrence α
u : ↥(solSpace E)
⊢ (fun u => { val := mkSol E u, property := (_ : IsSolution E (mkSol E u)) })
      (AddHom.toFun
        {
            toAddHom :=
              { toFun := fun u x => ↑u ↑x,
                map_add' :=
                  (_ :
                    ∀ (u v : ↥(solSpace E)),
                      (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) },
            map_smul' :=
              (_ :
                ∀ (a : α) (u : ↥(solSpace E)),
                  AddHom.toFun
                      { toFun := fun u x => ↑u ↑x,
                        map_add' :=
                          (_ :
                            ∀ (u v : ↥(solSpace E)),
                              (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
                      (a • u) =
                    (RingHom.id α) a •
                      AddHom.toFun
                        { toFun := fun u x => ↑u ↑x,
                          map_add' :=
                            (_ :
                              ∀ (u v : ↥(solSpace E)),
                                (fun u x => ↑u ↑x) (u + v) = (fun u x => ↑u ↑x) u + (fun u x => ↑u ↑x) v) }
                        u) }.toAddHom
        u) =
    u

Next tactic:
ext n