/-- If a finset has cardinality larger than `finrank + 1`,
then there is a nontrivial linear relation amongst its elements,
such that the coefficients of the relation sum to zero.
-/
-- TODO: golf this
theorem Module.exists_nontrivial_relation_sum_zero_of_finrank_succ_lt_card [Module.Finite R V]
    {t : Finset V} (h : finrank R V + 1 < t.card) :
    ∃ f : V → R, ∑ e in t, f e • e = 0 ∧ ∑ e in t, f e = 0 ∧ ∃ x ∈ t, f x ≠ 0 := by
  classical
  -- Pick an element x₀ ∈ t,
  have card_pos : 0 < t.card := lt_trans (Nat.succ_pos _) h
  obtain ⟨x₀, m⟩ := (Finset.card_pos.1 card_pos).bex
  -- and apply the previous lemma to the {xᵢ - x₀}
  let shift : V ↪ V := ⟨fun x => x - x₀, sub_left_injective⟩
  let t' := (t.erase x₀).map shift
  have h' : finrank R V < t'.card := by
    simp only [card_map, Finset.card_erase_of_mem m]
    exact Nat.lt_pred_iff.mpr h
  -- to obtain a function `g`.
  obtain ⟨g, gsum, x₁, x₁_mem, nz⟩ := exists_nontrivial_relation_of_finrank_lt_card h'
  -- Then obtain `f` by translating back by `x₀`,
  -- and setting the value of `f` at `x₀` to ensure `∑ e in t, f e = 0`.
  let f : V → R := fun z => if z = x₀ then -∑ z in t.erase x₀, g (z - x₀) else g (z - x₀)
  refine' ⟨f, _, _, _⟩
  -- After this, it's a matter of verifying the properties,
  -- based on the corresponding properties for `g`.
  · show (∑ e : V in t, f e • e) = 0
    -- We prove this by splitting off the `x₀` term of the sum,
    -- which is itself a sum over `t.erase x₀`,
    -- combining the two sums, and
    -- observing that after reindexing we have exactly
    -- ∑ (x : V) in t', g x • x = 0.
    simp only
    conv_lhs =>
      apply_congr
      rfl
      rw [ite_smul]
    rw [Finset.sum_ite]
    conv =>
      congr
      congr
      

Proof state:
case a.a
R : Type u
M : Type v
N : Type w
V : Type v
inst✝⁶ : AddCommGroup V
V₂ : Type v'
inst✝⁵ : AddCommGroup V₂
inst✝⁴ : Ring R
inst✝³ : StrongRankCondition R
inst✝² : Module R V
inst✝¹ : Free R V
K : ?m.334640
inst✝ : Finite R V
t : Finset V
h : finrank R V + 1 < Finset.card t
card_pos : 0 < Finset.card t
x₀ : V
m : x₀ ∈ t
shift : V ↪ V := { toFun := fun x => x - x₀, inj' := (_ : Injective fun a => a - x₀) }
t' : Finset V := Finset.map shift (erase t x₀)
h' : finrank R V < Finset.card t'
g : V → R
gsum : ∑ e in t', g e • e = 0
x₁ : V
x₁_mem : x₁ ∈ t'
nz : g x₁ ≠ 0
f : V → R := fun z => if z = x₀ then -∑ z in erase t x₀, g (z - x₀) else g (z - x₀)
| ∑ x in filter (fun x => x = x₀) t, (-∑ z in erase t x₀, g (z - x₀)) • x
case a.a
R : Type u
M : Type v
N : Type w
V : Type v
inst✝⁶ : AddCommGroup V
V₂ : Type v'
inst✝⁵ : AddCommGroup V₂
inst✝⁴ : Ring R
inst✝³ : StrongRankCondition R
inst✝² : Module R V
inst✝¹ : Free R V
K : ?m.334640
inst✝ : Finite R V
t : Finset V
h : finrank R V + 1 < Finset.card t
card_pos : 0 < Finset.card t
x₀ : V
m : x₀ ∈ t
shift : V ↪ V := { toFun := fun x => x - x₀, inj' := (_ : Injective fun a => a - x₀) }
t' : Finset V := Finset.map shift (erase t x₀)
h' : finrank R V < Finset.card t'
g : V → R
gsum : ∑ e in t', g e • e = 0
x₁ : V
x₁_mem : x₁ ∈ t'
nz : g x₁ ≠ 0
f : V → R := fun z => if z = x₀ then -∑ z in erase t x₀, g (z - x₀) else g (z - x₀)
| ∑ x in filter (fun x => ¬x = x₀) t, g (x - x₀) • x
case a
R : Type u
M : Type v
N : Type w
V : Type v
inst✝⁶ : AddCommGroup V
V₂ : Type v'
inst✝⁵ : AddCommGroup V₂
inst✝⁴ : Ring R
inst✝³ : StrongRankCondition R
inst✝² : Module R V
inst✝¹ : Free R V
K : ?m.334640
inst✝ : Finite R V
t : Finset V
h : finrank R V + 1 < Finset.card t
card_pos : 0 < Finset.card t
x₀ : V
m : x₀ ∈ t
shift : V ↪ V := { toFun := fun x => x - x₀, inj' := (_ : Injective fun a => a - x₀) }
t' : Finset V := Finset.map shift (erase t x₀)
h' : finrank R V < Finset.card t'
g : V → R
gsum : ∑ e in t', g e • e = 0
x₁ : V
x₁_mem : x₁ ∈ t'
nz : g x₁ ≠ 0
f : V → R := fun z => if z = x₀ then -∑ z in erase t x₀, g (z - x₀) else g (z - x₀)
| 0

Next tactic:
apply_congr