-- Mathlib/Combinatorics/Hindman.lean
theorem FP.mul_two {M} [Semigroup M] (a : Stream' M) (i j : ℕ) (ij : i < j) :
    a.get i * a.get j ∈ FP a

Proof state:
case h.intro
M : Type u_1
inst✝ : Semigroup M
a : Stream' M
i j : ℕ
ij : i < j
d : ℕ
hd : j = i.succ + d
⊢ a.get j ∈ FP (Stream'.drop i a).tail

Tactic:
have := FP.singleton (a.drop i).tail d

Result:
case h.intro
M : Type u_1
inst✝ : Semigroup M
a : Stream' M
i j : ℕ
ij : i < j
d : ℕ
hd : j = i.succ + d
this : (Stream'.drop i a).tail.get d ∈ FP (Stream'.drop i a).tail
⊢ a.get j ∈ FP (Stream'.drop i a).tail

Proof state:
case h.intro
M : Type u_1
inst✝ : Semigroup M
a : Stream' M
i j : ℕ
ij : i < j
d : ℕ
hd : j = i.succ + d
this : (Stream'.drop i a).tail.get d ∈ FP (Stream'.drop i a).tail
⊢ a.get j ∈ FP (Stream'.drop i a).tail

Tactic:
rw [Stream'.tail_eq_drop, Stream'.get_drop, Stream'.get_drop] at this

Result:
case h.intro
M : Type u_1
inst✝ : Semigroup M
a : Stream' M
i j : ℕ
ij : i < j
d : ℕ
hd : j = i.succ + d
this : a.get (i + (1 + d)) ∈ FP (Stream'.drop 1 (Stream'.drop i a))
⊢ a.get j ∈ FP (Stream'.drop i a).tail

Proof state:
case h.intro
M : Type u_1
inst✝ : Semigroup M
a : Stream' M
i j : ℕ
ij : i < j
d : ℕ
hd : j = i.succ + d
⊢ FP (Stream'.drop i a).tail (a.get j)

Tactic:
change _ ∈ FP _

Result:
case h.intro
M : Type u_1
inst✝ : Semigroup M
a : Stream' M
i j : ℕ
ij : i < j
d : ℕ
hd : j = i.succ + d
⊢ a.get j ∈ FP (Stream'.drop i a).tail

Proof state:
case h.intro
M : Type u_1
inst✝ : Semigroup M
a : Stream' M
i j : ℕ
ij : i < j
d : ℕ
hd : j = i.succ + d
this : a.get (i + (1 + d)) ∈ FP (Stream'.drop 1 (Stream'.drop i a))
⊢ a.get j ∈ FP (Stream'.drop i a).tail

Tactic:
convert this

Result:
case h.e'_5.h.e'_3
M : Type u_1
inst✝ : Semigroup M
a : Stream' M
i j : ℕ
ij : i < j
d : ℕ
hd : j = i.succ + d
this : a.get (i + (1 + d)) ∈ FP (Stream'.drop 1 (Stream'.drop i a))
⊢ j = i + (1 + d)

Proof state:
case h.e'_5.h.e'_3
M : Type u_1
inst✝ : Semigroup M
a : Stream' M
i j : ℕ
ij : i < j
d : ℕ
hd : j = i.succ + d
this : a.get (i + (1 + d)) ∈ FP (Stream'.drop 1 (Stream'.drop i a))
⊢ j = i + (1 + d)

Tactic:
omega

Result:
no goals

Proof state:
M : Type u_1
inst✝ : Semigroup M
a : Stream' M
i j : ℕ
ij : i < j
⊢ a.get i * a.get j ∈ FP (Stream'.drop i a)

Tactic:
rw [← Stream'.head_drop]

Result:
M : Type u_1
inst✝ : Semigroup M
a : Stream' M
i j : ℕ
ij : i < j
⊢ (Stream'.drop i a).head * a.get j ∈ FP (Stream'.drop i a)

Proof state:
case h
M : Type u_1
inst✝ : Semigroup M
a : Stream' M
i j : ℕ
ij : i < j
⊢ FP (Stream'.drop i a).tail (a.get j)

Tactic:
rcases Nat.exists_eq_add_of_le (Nat.succ_le_of_lt ij) with ⟨d, hd⟩

Result:
case h.intro
M : Type u_1
inst✝ : Semigroup M
a : Stream' M
i j : ℕ
ij : i < j
d : ℕ
hd : j = i.succ + d
⊢ FP (Stream'.drop i a).tail (a.get j)

Proof state:
M : Type u_1
inst✝ : Semigroup M
a : Stream' M
i j : ℕ
ij : i < j
⊢ (Stream'.drop i a).head * a.get j ∈ FP (Stream'.drop i a)

Tactic:
apply FP.cons

Result:
case h
M : Type u_1
inst✝ : Semigroup M
a : Stream' M
i j : ℕ
ij : i < j
⊢ FP (Stream'.drop i a).tail (a.get j)

Proof state:
M : Type u_1
inst✝ : Semigroup M
a : Stream' M
i j : ℕ
ij : i < j
⊢ a.get i * a.get j ∈ FP a

Tactic:
refine FP_drop_subset_FP _ i ?_

Result:
M : Type u_1
inst✝ : Semigroup M
a : Stream' M
i j : ℕ
ij : i < j
⊢ a.get i * a.get j ∈ FP (Stream'.drop i a)