-- Mathlib/ModelTheory/Ultraproducts.lean
theorem boundedFormula_realize_cast {β : Type*} {n : ℕ} (φ : L.BoundedFormula β n)
    (x : β → ∀ a, M a) (v : Fin n → ∀ a, M a) :
    (φ.Realize (fun i : β => (x i : (u : Filter α).Product M))
        (fun i => (v i : (u : Filter α).Product M))) ↔
      ∀ᶠ a : α in u, φ.Realize (fun i : β => x i a) fun i => v i a

Proof state:
case all
α : Type u_1
M : α → Type u_2
u : Ultrafilter α
L : Language
inst✝¹ : (a : α) → L.Structure (M a)
inst✝ : ∀ (a : α), Nonempty (M a)
β : Type u_3
n : ℕ
x : β → (a : α) → M a
this : Setoid ((a : α) → M a) := (↑u).productSetoid M
k : ℕ
φ : L.BoundedFormula β (k + 1)
ih :
  ∀ (v : Fin (k + 1) → (a : α) → M a),
    (φ.Realize (fun i => Quotient.mk' (x i)) fun i => Quotient.mk' (v i)) ↔
      ∀ᶠ (a : α) in ↑u, φ.Realize (fun i => x i a) fun i => v i a
v : Fin k → (a : α) → M a
⊢ (∀ (x_1 : Quotient ((↑u).productSetoid M)),
      φ.Realize (fun i => Quotient.mk' (x i)) (Fin.snoc (fun i => Quotient.mk' (v i)) x_1)) ↔
    ∀ᶠ (a : α) in ↑u, ∀ (x_1 : M a), φ.Realize (fun i => x i a) (Fin.snoc (fun i => v i a) x_1)

Tactic:
apply Iff.trans (b := ∀ m : ∀ a : α, M a,
  φ.Realize (fun i : β => (x i : (u : Filter α).Product M))
    (Fin.snoc (((↑) : (∀ a, M a) → (u : Filter α).Product M) ∘ v)
      (m : (u : Filter α).Product M)))

Result:
case all.h₁
α : Type u_1
M : α → Type u_2
u : Ultrafilter α
L : Language
inst✝¹ : (a : α) → L.Structure (M a)
inst✝ : ∀ (a : α), Nonempty (M a)
β : Type u_3
n : ℕ
x : β → (a : α) → M a
this : Setoid ((a : α) → M a) := (↑u).productSetoid M
k : ℕ
φ : L.BoundedFormula β (k + 1)
ih :
  ∀ (v : Fin (k + 1) → (a : α) → M a),
    (φ.Realize (fun i => Quotient.mk' (x i)) fun i => Quotient.mk' (v i)) ↔
      ∀ᶠ (a : α) in ↑u, φ.Realize (fun i => x i a) fun i => v i a
v : Fin k → (a : α) → M a
⊢ (∀ (x_1 : Quotient ((↑u).productSetoid M)),
      φ.Realize (fun i => Quotient.mk' (x i)) (Fin.snoc (fun i => Quotient.mk' (v i)) x_1)) ↔
    ∀ (m : (a : α) → M a), φ.Realize (fun i => Quotient.mk' (x i)) (Fin.snoc (Quotient.mk' ∘ v) (Quotient.mk' m))

case all.h₂
α : Type u_1
M : α → Type u_2
u : Ultrafilter α
L : Language
inst✝¹ : (a : α) → L.Structure (M a)
inst✝ : ∀ (a : α), Nonempty (M a)
β : Type u_3
n : ℕ
x : β → (a : α) → M a
this : Setoid ((a : α) → M a) := (↑u).productSetoid M
k : ℕ
φ : L.BoundedFormula β (k + 1)
ih :
  ∀ (v : Fin (k + 1) → (a : α) → M a),
    (φ.Realize (fun i => Quotient.mk' (x i)) fun i => Quotient.mk' (v i)) ↔
      ∀ᶠ (a : α) in ↑u, φ.Realize (fun i => x i a) fun i => v i a
v : Fin k → (a : α) → M a
⊢ (∀ (m : (a : α) → M a), φ.Realize (fun i => Quotient.mk' (x i)) (Fin.snoc (Quotient.mk' ∘ v) (Quotient.mk' m))) ↔
    ∀ᶠ (a : α) in ↑u, ∀ (x_1 : M a), φ.Realize (fun i => x i a) (Fin.snoc (fun i => v i a) x_1)

Proof state:
case refine_2
α : Type u_1
M : α → Type u_2
u : Ultrafilter α
L : Language
inst✝¹ : (a : α) → L.Structure (M a)
inst✝ : ∀ (a : α), Nonempty (M a)
β : Type u_3
n : ℕ
x : β → (a : α) → M a
this : Setoid ((a : α) → M a) := (↑u).productSetoid M
k : ℕ
φ : L.BoundedFormula β (k + 1)
ih :
  ∀ (v : Fin (k + 1) → (a : α) → M a),
    (φ.Realize (fun i => Quotient.mk' (x i)) fun i => Quotient.mk' (v i)) ↔
      ∀ᶠ (a : α) in ↑u, φ.Realize (fun i => x i a) fun i => v i a
v : Fin k → (a : α) → M a
m : (a : α) → M a
a : α
i : Fin k
x✝ : Fin.snoc v m i.succ a = Fin.snoc (fun i => v i a) (m a) i.succ
⊢ Fin.snoc v m i.castSucc a = Fin.snoc (fun i => v i a) (m a) i.castSucc

Tactic:
simp only [Fin.snoc_castSucc]

Result:
no goals

Proof state:
case all.h₂.refine_1
α : Type u_1
M : α → Type u_2
u : Ultrafilter α
L : Language
inst✝¹ : (a : α) → L.Structure (M a)
inst✝ : ∀ (a : α), Nonempty (M a)
β : Type u_3
n : ℕ
x : β → (a : α) → M a
this : Setoid ((a : α) → M a) := (↑u).productSetoid M
k : ℕ
φ : L.BoundedFormula β (k + 1)
ih :
  ∀ (v : Fin (k + 1) → (a : α) → M a),
    (φ.Realize (fun i => Quotient.mk' (x i)) fun i => Quotient.mk' (v i)) ↔
      ∀ᶠ (a : α) in ↑u, φ.Realize (fun i => x i a) fun i => v i a
v : Fin k → (a : α) → M a
h' : ∀ (m : (a : α) → M a) (a : α), (fun i => Fin.snoc v m i a) = Fin.snoc (fun i => v i a) (m a)
h : ∀ (m : (a : α) → M a), ∀ᶠ (a : α) in ↑u, φ.Realize (fun i => x i a) (Fin.snoc (fun i => v i a) (m a))
⊢ ∀ᶠ (a : α) in ↑u, ∀ (x_1 : M a), φ.Realize (fun i => x i a) (Fin.snoc (fun i => v i a) x_1)

Tactic:
contrapose! h

Result:
case all.h₂.refine_1
α : Type u_1
M : α → Type u_2
u : Ultrafilter α
L : Language
inst✝¹ : (a : α) → L.Structure (M a)
inst✝ : ∀ (a : α), Nonempty (M a)
β : Type u_3
n : ℕ
x : β → (a : α) → M a
this : Setoid ((a : α) → M a) := (↑u).productSetoid M
k : ℕ
φ : L.BoundedFormula β (k + 1)
ih :
  ∀ (v : Fin (k + 1) → (a : α) → M a),
    (φ.Realize (fun i => Quotient.mk' (x i)) fun i => Quotient.mk' (v i)) ↔
      ∀ᶠ (a : α) in ↑u, φ.Realize (fun i => x i a) fun i => v i a
v : Fin k → (a : α) → M a
h' : ∀ (m : (a : α) → M a) (a : α), (fun i => Fin.snoc v m i a) = Fin.snoc (fun i => v i a) (m a)
h : ¬∀ᶠ (a : α) in ↑u, ∀ (x_1 : M a), φ.Realize (fun i => x i a) (Fin.snoc (fun i => v i a) x_1)
⊢ ∃ m, ¬∀ᶠ (a : α) in ↑u, φ.Realize (fun i => x i a) (Fin.snoc (fun i => v i a) (m a))

Proof state:
case all.h₂
α : Type u_1
M : α → Type u_2
u : Ultrafilter α
L : Language
inst✝¹ : (a : α) → L.Structure (M a)
inst✝ : ∀ (a : α), Nonempty (M a)
β : Type u_3
n : ℕ
x : β → (a : α) → M a
this : Setoid ((a : α) → M a) := (↑u).productSetoid M
k : ℕ
φ : L.BoundedFormula β (k + 1)
ih :
  ∀ (v : Fin (k + 1) → (a : α) → M a),
    (φ.Realize (fun i => Quotient.mk' (x i)) fun i => Quotient.mk' (v i)) ↔
      ∀ᶠ (a : α) in ↑u, φ.Realize (fun i => x i a) fun i => v i a
v : Fin k → (a : α) → M a
h' : ∀ (m : (a : α) → M a) (a : α), (fun i => Fin.snoc v m i a) = Fin.snoc (fun i => v i a) (m a)
⊢ (∀ (m : (a : α) → M a), φ.Realize (fun i => Quotient.mk' (x i)) (Quotient.mk' ∘ Fin.snoc v m)) ↔
    ∀ᶠ (a : α) in ↑u, ∀ (x_1 : M a), φ.Realize (fun i => x i a) (Fin.snoc (fun i => v i a) x_1)

Tactic:
simp only [Function.comp_def, ih, h']

Result:
case all.h₂
α : Type u_1
M : α → Type u_2
u : Ultrafilter α
L : Language
inst✝¹ : (a : α) → L.Structure (M a)
inst✝ : ∀ (a : α), Nonempty (M a)
β : Type u_3
n : ℕ
x : β → (a : α) → M a
this : Setoid ((a : α) → M a) := (↑u).productSetoid M
k : ℕ
φ : L.BoundedFormula β (k + 1)
ih :
  ∀ (v : Fin (k + 1) → (a : α) → M a),
    (φ.Realize (fun i => Quotient.mk' (x i)) fun i => Quotient.mk' (v i)) ↔
      ∀ᶠ (a : α) in ↑u, φ.Realize (fun i => x i a) fun i => v i a
v : Fin k → (a : α) → M a
h' : ∀ (m : (a : α) → M a) (a : α), (fun i => Fin.snoc v m i a) = Fin.snoc (fun i => v i a) (m a)
⊢ (∀ (m : (a : α) → M a), ∀ᶠ (a : α) in ↑u, φ.Realize (fun i => x i a) (Fin.snoc (fun i => v i a) (m a))) ↔
    ∀ᶠ (a : α) in ↑u, ∀ (x_1 : M a), φ.Realize (fun i => x i a) (Fin.snoc (fun i => v i a) x_1)

Proof state:
case all.h₂.refine_2
α : Type u_1
M : α → Type u_2
u : Ultrafilter α
L : Language
inst✝¹ : (a : α) → L.Structure (M a)
inst✝ : ∀ (a : α), Nonempty (M a)
β : Type u_3
n : ℕ
x : β → (a : α) → M a
this : Setoid ((a : α) → M a) := (↑u).productSetoid M
k : ℕ
φ : L.BoundedFormula β (k + 1)
ih :
  ∀ (v : Fin (k + 1) → (a : α) → M a),
    (φ.Realize (fun i => Quotient.mk' (x i)) fun i => Quotient.mk' (v i)) ↔
      ∀ᶠ (a : α) in ↑u, φ.Realize (fun i => x i a) fun i => v i a
v : Fin k → (a : α) → M a
h' : ∀ (m : (a : α) → M a) (a : α), (fun i => Fin.snoc v m i a) = Fin.snoc (fun i => v i a) (m a)
h : {x_1 | ∀ (x_2 : M x_1), φ.Realize (fun i => x i x_1) (Fin.snoc (fun i => v i x_1) x_2)} ∈ ↑u
m : (a : α) → M a
⊢ {x_1 | φ.Realize (fun i => x i x_1) (Fin.snoc (fun i => v i x_1) (m x_1))} ∈ ↑u

Tactic:
exact Filter.mem_of_superset h fun a ha => ha (m a)

Result:
no goals