-- Mathlib/Combinatorics/HalesJewett.lean
theorem exists_mono_homothetic_copy {M κ : Type*} [AddCommMonoid M] (S : Finset M) [Finite κ]
    (C : M → κ) : ∃ a > 0, ∃ (b : M) (c : κ), ∀ s ∈ S, C (a • s + b) = c

Proof state:
case intro.intro.intro.intro.refine_3.e_a.e_a
M : Type u_5
κ : Type u_6
inst✝¹ : AddCommMonoid M
S : Finset M
inst✝ : Finite κ
C : M → κ
ι : Type
_inst : Fintype ι
l : Line { x // x ∈ S } ι
c : κ
s : Finset ι := Finset.filter (fun i => l.idxFun i = none) Finset.univ
hs : s = Finset.filter (fun i => l.idxFun i = none) Finset.univ
x : M
xs : x ∈ S
⊢ ∑ i ∈ sᶜ, (Option.map (fun m => ↑m) (l.idxFun i)).getD 0 = ∑ i ∈ sᶜ, ↑(↑l ⟨x, xs⟩ i)

Tactic:
apply Finset.sum_congr rfl

Result:
case intro.intro.intro.intro.refine_3.e_a.e_a
M : Type u_5
κ : Type u_6
inst✝¹ : AddCommMonoid M
S : Finset M
inst✝ : Finite κ
C : M → κ
ι : Type
_inst : Fintype ι
l : Line { x // x ∈ S } ι
c : κ
s : Finset ι := Finset.filter (fun i => l.idxFun i = none) Finset.univ
hs : s = Finset.filter (fun i => l.idxFun i = none) Finset.univ
x : M
xs : x ∈ S
⊢ ∀ x_1 ∈ sᶜ, (Option.map (fun m => ↑m) (l.idxFun x_1)).getD 0 = ↑(↑l ⟨x, xs⟩ x_1)

Proof state:
case intro.intro.intro.intro.refine_3.e_a.e_a
M : Type u_5
κ : Type u_6
inst✝¹ : AddCommMonoid M
S : Finset M
inst✝ : Finite κ
C : M → κ
ι : Type
_inst : Fintype ι
l : Line { x // x ∈ S } ι
c : κ
s : Finset ι := Finset.filter (fun i => l.idxFun i = none) Finset.univ
hs : s = Finset.filter (fun i => l.idxFun i = none) Finset.univ
x : M
xs : x ∈ S
i : ι
hi : i ∈ Finset.univ ∧ l.idxFun i = none
⊢ x = ↑(↑l ⟨x, xs⟩ i)

Tactic:
rw [l.apply_none _ _ hi.right, Subtype.coe_mk]

Result:
no goals

Proof state:
case intro.intro.intro.intro.refine_3
M : Type u_5
κ : Type u_6
inst✝¹ : AddCommMonoid M
S : Finset M
inst✝ : Finite κ
C : M → κ
ι : Type
_inst : Fintype ι
l : Line { x // x ∈ S } ι
c : κ
s : Finset ι := Finset.filter (fun i => l.idxFun i = none) Finset.univ
hs : s = Finset.filter (fun i => l.idxFun i = none) Finset.univ
x : M
xs : x ∈ S
⊢ C (s.card • x + ∑ i ∈ sᶜ, (Option.map (fun m => ↑m) (l.idxFun i)).getD 0) =
    (fun v => C (∑ i : ι, ↑(v i))) (↑l ⟨x, xs⟩)

Tactic:
congr

Result:
case intro.intro.intro.intro.refine_3.e_a
M : Type u_5
κ : Type u_6
inst✝¹ : AddCommMonoid M
S : Finset M
inst✝ : Finite κ
C : M → κ
ι : Type
_inst : Fintype ι
l : Line { x // x ∈ S } ι
c : κ
s : Finset ι := Finset.filter (fun i => l.idxFun i = none) Finset.univ
hs : s = Finset.filter (fun i => l.idxFun i = none) Finset.univ
x : M
xs : x ∈ S
⊢ s.card • x + ∑ i ∈ sᶜ, (Option.map (fun m => ↑m) (l.idxFun i)).getD 0 = ∑ i : ι, ↑(↑l ⟨x, xs⟩ i)

Proof state:
case intro.intro.intro.intro.refine_3.e_a.e_a.intro
M : Type u_5
κ : Type u_6
inst✝¹ : AddCommMonoid M
S : Finset M
inst✝ : Finite κ
C : M → κ
ι : Type
_inst : Fintype ι
l : Line { x // x ∈ S } ι
c : κ
s : Finset ι := Finset.filter (fun i => l.idxFun i = none) Finset.univ
hs : s = Finset.filter (fun i => l.idxFun i = none) Finset.univ
x : M
xs : x ∈ S
i : ι
hi : i ∈ Finset.univ ∧ ¬l.idxFun i = none
y : { x // x ∈ S }
hy : some y = l.idxFun i
⊢ (Option.map (fun m => ↑m) (l.idxFun i)).getD 0 = ↑(↑l ⟨x, xs⟩ i)

Tactic:
simp [← hy, Option.map_some', Option.getD]

Result:
no goals

Proof state:
case intro.intro.intro.intro.refine_1
M : Type u_5
κ : Type u_6
inst✝¹ : AddCommMonoid M
S : Finset M
inst✝ : Finite κ
C : M → κ
ι : Type
_inst : Fintype ι
l : Line { x // x ∈ S } ι
c : κ
hl : ∀ (x : { x // x ∈ S }), (fun v => C (∑ i : ι, ↑(v i))) (↑l x) = c
s : Finset ι := Finset.filter (fun i => l.idxFun i = none) Finset.univ
hs : s = Finset.filter (fun i => l.idxFun i = none) Finset.univ
⊢ ⋯.choose ∈ s

Tactic:
rw [hs, Finset.mem_filter]

Result:
case intro.intro.intro.intro.refine_1
M : Type u_5
κ : Type u_6
inst✝¹ : AddCommMonoid M
S : Finset M
inst✝ : Finite κ
C : M → κ
ι : Type
_inst : Fintype ι
l : Line { x // x ∈ S } ι
c : κ
hl : ∀ (x : { x // x ∈ S }), (fun v => C (∑ i : ι, ↑(v i))) (↑l x) = c
s : Finset ι := Finset.filter (fun i => l.idxFun i = none) Finset.univ
hs : s = Finset.filter (fun i => l.idxFun i = none) Finset.univ
⊢ ⋯.choose ∈ Finset.univ ∧ l.idxFun ⋯.choose = none

Proof state:
case intro.intro.intro.intro
M : Type u_5
κ : Type u_6
inst✝¹ : AddCommMonoid M
S : Finset M
inst✝ : Finite κ
C : M → κ
ι : Type
_inst : Fintype ι
l : Line { x // x ∈ S } ι
c : κ
hl : ∀ (x : { x // x ∈ S }), (fun v => C (∑ i : ι, ↑(v i))) (↑l x) = c
⊢ ∃ a > 0, ∃ b c, ∀ s ∈ S, C (a • s + b) = c

Tactic:
set s : Finset ι := Finset.univ.filter (fun i => l.idxFun i = none) with hs

Result:
case intro.intro.intro.intro
M : Type u_5
κ : Type u_6
inst✝¹ : AddCommMonoid M
S : Finset M
inst✝ : Finite κ
C : M → κ
ι : Type
_inst : Fintype ι
l : Line { x // x ∈ S } ι
c : κ
hl : ∀ (x : { x // x ∈ S }), (fun v => C (∑ i : ι, ↑(v i))) (↑l x) = c
s : Finset ι := Finset.filter (fun i => l.idxFun i = none) Finset.univ
hs : s = Finset.filter (fun i => l.idxFun i = none) Finset.univ
⊢ ∃ a > 0, ∃ b c, ∀ s ∈ S, C (a • s + b) = c

Proof state:
case intro.intro.intro.intro.refine_3
M : Type u_5
κ : Type u_6
inst✝¹ : AddCommMonoid M
S : Finset M
inst✝ : Finite κ
C : M → κ
ι : Type
_inst : Fintype ι
l : Line { x // x ∈ S } ι
c : κ
hl : ∀ (x : { x // x ∈ S }), (fun v => C (∑ i : ι, ↑(v i))) (↑l x) = c
s : Finset ι := Finset.filter (fun i => l.idxFun i = none) Finset.univ
hs : s = Finset.filter (fun i => l.idxFun i = none) Finset.univ
x : M
xs : x ∈ S
⊢ C (s.card • x + ∑ i ∈ sᶜ, (Option.map (fun m => ↑m) (l.idxFun i)).getD 0) = c

Tactic:
rw [← hl ⟨x, xs⟩]

Result:
case intro.intro.intro.intro.refine_3
M : Type u_5
κ : Type u_6
inst✝¹ : AddCommMonoid M
S : Finset M
inst✝ : Finite κ
C : M → κ
ι : Type
_inst : Fintype ι
l : Line { x // x ∈ S } ι
c : κ
hl : ∀ (x : { x // x ∈ S }), (fun v => C (∑ i : ι, ↑(v i))) (↑l x) = c
s : Finset ι := Finset.filter (fun i => l.idxFun i = none) Finset.univ
hs : s = Finset.filter (fun i => l.idxFun i = none) Finset.univ
x : M
xs : x ∈ S
⊢ C (s.card • x + ∑ i ∈ sᶜ, (Option.map (fun m => ↑m) (l.idxFun i)).getD 0) =
    (fun v => C (∑ i : ι, ↑(v i))) (↑l ⟨x, xs⟩)

Proof state:
case intro.intro.intro.intro.refine_3
M : Type u_5
κ : Type u_6
inst✝¹ : AddCommMonoid M
S : Finset M
inst✝ : Finite κ
C : M → κ
ι : Type
_inst : Fintype ι
l : Line { x // x ∈ S } ι
c : κ
hl : ∀ (x : { x // x ∈ S }), (fun v => C (∑ i : ι, ↑(v i))) (↑l x) = c
s : Finset ι := Finset.filter (fun i => l.idxFun i = none) Finset.univ
hs : s = Finset.filter (fun i => l.idxFun i = none) Finset.univ
⊢ ∀ s_1 ∈ S, C (s.card • s_1 + ∑ i ∈ sᶜ, (Option.map (fun m => ↑m) (l.idxFun i)).getD 0) = c

Tactic:
intro x xs

Result:
case intro.intro.intro.intro.refine_3
M : Type u_5
κ : Type u_6
inst✝¹ : AddCommMonoid M
S : Finset M
inst✝ : Finite κ
C : M → κ
ι : Type
_inst : Fintype ι
l : Line { x // x ∈ S } ι
c : κ
hl : ∀ (x : { x // x ∈ S }), (fun v => C (∑ i : ι, ↑(v i))) (↑l x) = c
s : Finset ι := Finset.filter (fun i => l.idxFun i = none) Finset.univ
hs : s = Finset.filter (fun i => l.idxFun i = none) Finset.univ
x : M
xs : x ∈ S
⊢ C (s.card • x + ∑ i ∈ sᶜ, (Option.map (fun m => ↑m) (l.idxFun i)).getD 0) = c

Proof state:
case intro.intro.intro.intro.refine_1
M : Type u_5
κ : Type u_6
inst✝¹ : AddCommMonoid M
S : Finset M
inst✝ : Finite κ
C : M → κ
ι : Type
_inst : Fintype ι
l : Line { x // x ∈ S } ι
c : κ
hl : ∀ (x : { x // x ∈ S }), (fun v => C (∑ i : ι, ↑(v i))) (↑l x) = c
s : Finset ι := Finset.filter (fun i => l.idxFun i = none) Finset.univ
hs : s = Finset.filter (fun i => l.idxFun i = none) Finset.univ
⊢ ⋯.choose ∈ Finset.univ ∧ l.idxFun ⋯.choose = none

Tactic:
exact ⟨Finset.mem_univ _, l.proper.choose_spec⟩

Result:
no goals