-- Mathlib/Data/List/ToFinsupp.lean
theorem toFinsupp_append {R : Type*} [AddZeroClass R] (l₁ l₂ : List R)
    [DecidablePred (getD (l₁ ++ l₂) · 0 ≠ 0)] [DecidablePred (getD l₁ · 0 ≠ 0)]
    [DecidablePred (getD l₂ · 0 ≠ 0)] :
    toFinsupp (l₁ ++ l₂) =
      toFinsupp l₁ + (toFinsupp l₂).embDomain (addLeftEmbedding l₁.length)

Proof state:
case h.inl
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => (l₁ ++ l₂).getD x 0 ≠ 0
inst✝¹ : DecidablePred fun x => l₁.getD x 0 ≠ 0
inst✝ : DecidablePred fun x => l₂.getD x 0 ≠ 0
n : ℕ
h : n < l₁.length
⊢ (l₁ ++ l₂).getD n 0 = l₁.getD n 0 + (Finsupp.embDomain (addLeftEmbedding l₁.length) l₂.toFinsupp) n

Tactic:
rw [getD_append _ _ _ _ h, Finsupp.embDomain_notin_range, add_zero]

Result:
case h.inl.h
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => (l₁ ++ l₂).getD x 0 ≠ 0
inst✝¹ : DecidablePred fun x => l₁.getD x 0 ≠ 0
inst✝ : DecidablePred fun x => l₂.getD x 0 ≠ 0
n : ℕ
h : n < l₁.length
⊢ n ∉ Set.range ⇑(addLeftEmbedding l₁.length)

Proof state:
case h.inl.h.intro
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => (l₁ ++ l₂).getD x 0 ≠ 0
inst✝¹ : DecidablePred fun x => l₁.getD x 0 ≠ 0
inst✝ : DecidablePred fun x => l₂.getD x 0 ≠ 0
k : ℕ
h : l₁.length + k < l₁.length
⊢ False

Tactic:
omega

Result:
no goals

Proof state:
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => (l₁ ++ l₂).getD x 0 ≠ 0
inst✝¹ : DecidablePred fun x => l₁.getD x 0 ≠ 0
inst✝ : DecidablePred fun x => l₂.getD x 0 ≠ 0
⊢ (l₁ ++ l₂).toFinsupp = l₁.toFinsupp + Finsupp.embDomain (addLeftEmbedding l₁.length) l₂.toFinsupp

Tactic:
ext n

Result:
case h
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => (l₁ ++ l₂).getD x 0 ≠ 0
inst✝¹ : DecidablePred fun x => l₁.getD x 0 ≠ 0
inst✝ : DecidablePred fun x => l₂.getD x 0 ≠ 0
n : ℕ
⊢ (l₁ ++ l₂).toFinsupp n = (l₁.toFinsupp + Finsupp.embDomain (addLeftEmbedding l₁.length) l₂.toFinsupp) n

Proof state:
case h
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => (l₁ ++ l₂).getD x 0 ≠ 0
inst✝¹ : DecidablePred fun x => l₁.getD x 0 ≠ 0
inst✝ : DecidablePred fun x => l₂.getD x 0 ≠ 0
n : ℕ
⊢ (l₁ ++ l₂).toFinsupp n = (l₁.toFinsupp + Finsupp.embDomain (addLeftEmbedding l₁.length) l₂.toFinsupp) n

Tactic:
simp only [toFinsupp_apply, Finsupp.add_apply]

Result:
case h
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => (l₁ ++ l₂).getD x 0 ≠ 0
inst✝¹ : DecidablePred fun x => l₁.getD x 0 ≠ 0
inst✝ : DecidablePred fun x => l₂.getD x 0 ≠ 0
n : ℕ
⊢ (l₁ ++ l₂).getD n 0 = l₁.getD n 0 + (Finsupp.embDomain (addLeftEmbedding l₁.length) l₂.toFinsupp) n

Proof state:
case h.inr.intro
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => (l₁ ++ l₂).getD x 0 ≠ 0
inst✝¹ : DecidablePred fun x => l₁.getD x 0 ≠ 0
inst✝ : DecidablePred fun x => l₂.getD x 0 ≠ 0
k : ℕ
h : l₁.length ≤ l₁.length + k
⊢ (l₁ ++ l₂).getD (l₁.length + k) 0 =
    l₁.getD (l₁.length + k) 0 + (Finsupp.embDomain (addLeftEmbedding l₁.length) l₂.toFinsupp) (l₁.length + k)

Tactic:
rw [getD_append_right _ _ _ _ h, Nat.add_sub_cancel_left, getD_eq_default _ _ h, zero_add]

Result:
case h.inr.intro
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => (l₁ ++ l₂).getD x 0 ≠ 0
inst✝¹ : DecidablePred fun x => l₁.getD x 0 ≠ 0
inst✝ : DecidablePred fun x => l₂.getD x 0 ≠ 0
k : ℕ
h : l₁.length ≤ l₁.length + k
⊢ l₂.getD k 0 = (Finsupp.embDomain (addLeftEmbedding l₁.length) l₂.toFinsupp) (l₁.length + k)

Proof state:
case h.inr
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => (l₁ ++ l₂).getD x 0 ≠ 0
inst✝¹ : DecidablePred fun x => l₁.getD x 0 ≠ 0
inst✝ : DecidablePred fun x => l₂.getD x 0 ≠ 0
n : ℕ
h : l₁.length ≤ n
⊢ (l₁ ++ l₂).getD n 0 = l₁.getD n 0 + (Finsupp.embDomain (addLeftEmbedding l₁.length) l₂.toFinsupp) n

Tactic:
rcases Nat.exists_eq_add_of_le h with ⟨k, rfl⟩

Result:
case h.inr.intro
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => (l₁ ++ l₂).getD x 0 ≠ 0
inst✝¹ : DecidablePred fun x => l₁.getD x 0 ≠ 0
inst✝ : DecidablePred fun x => l₂.getD x 0 ≠ 0
k : ℕ
h : l₁.length ≤ l₁.length + k
⊢ (l₁ ++ l₂).getD (l₁.length + k) 0 =
    l₁.getD (l₁.length + k) 0 + (Finsupp.embDomain (addLeftEmbedding l₁.length) l₂.toFinsupp) (l₁.length + k)

Proof state:
case h.inl.h
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => (l₁ ++ l₂).getD x 0 ≠ 0
inst✝¹ : DecidablePred fun x => l₁.getD x 0 ≠ 0
inst✝ : DecidablePred fun x => l₂.getD x 0 ≠ 0
n : ℕ
h : n < l₁.length
⊢ n ∉ Set.range ⇑(addLeftEmbedding l₁.length)

Tactic:
rintro ⟨k, rfl : length l₁ + k = n⟩

Result:
case h.inl.h.intro
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => (l₁ ++ l₂).getD x 0 ≠ 0
inst✝¹ : DecidablePred fun x => l₁.getD x 0 ≠ 0
inst✝ : DecidablePred fun x => l₂.getD x 0 ≠ 0
k : ℕ
h : l₁.length + k < l₁.length
⊢ False

Proof state:
case h
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => (l₁ ++ l₂).getD x 0 ≠ 0
inst✝¹ : DecidablePred fun x => l₁.getD x 0 ≠ 0
inst✝ : DecidablePred fun x => l₂.getD x 0 ≠ 0
n : ℕ
⊢ (l₁ ++ l₂).getD n 0 = l₁.getD n 0 + (Finsupp.embDomain (addLeftEmbedding l₁.length) l₂.toFinsupp) n

Tactic:
cases lt_or_le n l₁.length with
| inl h =>
  rw [getD_append _ _ _ _ h, Finsupp.embDomain_notin_range, add_zero]
  rintro ⟨k, rfl : length l₁ + k = n⟩
  omega
| inr h =>
  rcases Nat.exists_eq_add_of_le h with ⟨k, rfl⟩
  rw [getD_append_right _ _ _ _ h, Nat.add_sub_cancel_left, getD_eq_default _ _ h, zero_add]
  exact Eq.symm (Finsupp.embDomain_apply _ _ _)

Result:
no goals

Proof state:
case h.inr.intro
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => (l₁ ++ l₂).getD x 0 ≠ 0
inst✝¹ : DecidablePred fun x => l₁.getD x 0 ≠ 0
inst✝ : DecidablePred fun x => l₂.getD x 0 ≠ 0
k : ℕ
h : l₁.length ≤ l₁.length + k
⊢ l₂.getD k 0 = (Finsupp.embDomain (addLeftEmbedding l₁.length) l₂.toFinsupp) (l₁.length + k)

Tactic:
exact Eq.symm (Finsupp.embDomain_apply _ _ _)

Result:
no goals