Theorem: FirstOrder.Language.Theory.isSatisfiable_iff_isFinitelySatisfiable
File: Mathlib/ModelTheory/Satisfiability.lean

tactic: classical
  set M : Finset T → Type max u v := fun T0 : Finset T =>
    (h (T0.map (Function.Embedding.subtype fun x => x ∈ T)) T0.map_subtype_subset).some.Carrier
  let M' := Filter.Product (Ultrafilter.of (Filter.atTop : Filter (Finset T))) M
  have h' : M' ⊨ T := by
    refine' ⟨fun φ hφ => _⟩
    rw [Ultraproduct.sentence_realize]
    refine'
      Filter.Eventually.filter_mono (Ultrafilter.of_le _)
        (Filter.eventually_atTop.2
          ⟨{⟨φ, hφ⟩}, fun s h' =>
            Theory.realize_sentence_of_mem (s.map (Function.Embedding.subtype fun x => x ∈ T))
              _⟩)
    simp only [Finset.coe_map, Function.Embedding.coe_subtype, Set.mem_image, Finset.mem_coe,
      Subtype.exists, Subtype.coe_mk, exists_and_right, exists_eq_right]
    exact ⟨hφ, h' (Finset.mem_singleton_self _)⟩
  exact ⟨ModelType.of T M'⟩
state_before: L : Language
T✝ : Theory L
α : Type w
n : ℕ
T' T : Theory L
h : IsFinitelySatisfiable T
⊢ IsSatisfiable T

tactic: set M : Finset T → Type max u v := fun T0 : Finset T =>
  (h (T0.map (Function.Embedding.subtype fun x => x ∈ T)) T0.map_subtype_subset).some.Carrier
state_before: L : Language
T✝ : Theory L
α : Type w
n : ℕ
T' T : Theory L
h : IsFinitelySatisfiable T
⊢ IsSatisfiable T

tactic: let M' := Filter.Product (Ultrafilter.of (Filter.atTop : Filter (Finset T))) M
state_before: L : Language
T✝ : Theory L
α : Type w
n : ℕ
T' T : Theory L
h : IsFinitelySatisfiable T
M : Finset ↑T → Type (max u v) :=
  fun T0 => ↑(Nonempty.some (_ : IsSatisfiable ↑(Finset.map (Function.Embedding.subtype fun x => x ∈ T) T0)))
⊢ IsSatisfiable T

tactic: have h' : M' ⊨ T := by
  refine' ⟨fun φ hφ => _⟩
  rw [Ultraproduct.sentence_realize]
  refine'
    Filter.Eventually.filter_mono (Ultrafilter.of_le _)
      (Filter.eventually_atTop.2
        ⟨{⟨φ, hφ⟩}, fun s h' =>
          Theory.realize_sentence_of_mem (s.map (Function.Embedding.subtype fun x => x ∈ T))
            _⟩)
  simp only [Finset.coe_map, Function.Embedding.coe_subtype, Set.mem_image, Finset.mem_coe,
    Subtype.exists, Subtype.coe_mk, exists_and_right, exists_eq_right]
  exact ⟨hφ, h' (Finset.mem_singleton_self _)⟩
state_before: L : Language
T✝ : Theory L
α : Type w
n : ℕ
T' T : Theory L
h : IsFinitelySatisfiable T
M : Finset ↑T → Type (max u v) :=
  fun T0 => ↑(Nonempty.some (_ : IsSatisfiable ↑(Finset.map (Function.Embedding.subtype fun x => x ∈ T) T0)))
M' : Type (max u v) := Filter.Product (↑(Ultrafilter.of Filter.atTop)) M
⊢ IsSatisfiable T

tactic: exact ⟨ModelType.of T M'⟩
state_before: L : Language
T✝ : Theory L
α : Type w
n : ℕ
T' T : Theory L
h : IsFinitelySatisfiable T
M : Finset ↑T → Type (max u v) :=
  fun T0 => ↑(Nonempty.some (_ : IsSatisfiable ↑(Finset.map (Function.Embedding.subtype fun x => x ∈ T) T0)))
M' : Type (max u v) := Filter.Product (↑(Ultrafilter.of Filter.atTop)) M
h' : M' ⊨ T
⊢ IsSatisfiable T

tactic: refine' ⟨fun φ hφ => _⟩
state_before: L : Language
T✝ : Theory L
α : Type w
n : ℕ
T' T : Theory L
h : IsFinitelySatisfiable T
M : Finset ↑T → Type (max u v) :=
  fun T0 => ↑(Nonempty.some (_ : IsSatisfiable ↑(Finset.map (Function.Embedding.subtype fun x => x ∈ T) T0)))
M' : Type (max u v) := Filter.Product (↑(Ultrafilter.of Filter.atTop)) M
⊢ M' ⊨ T

tactic: rw [Ultraproduct.sentence_realize]
state_before: L : Language
T✝ : Theory L
α : Type w
n : ℕ
T' T : Theory L
h : IsFinitelySatisfiable T
M : Finset ↑T → Type (max u v) :=
  fun T0 => ↑(Nonempty.some (_ : IsSatisfiable ↑(Finset.map (Function.Embedding.subtype fun x => x ∈ T) T0)))
M' : Type (max u v) := Filter.Product (↑(Ultrafilter.of Filter.atTop)) M
φ : Sentence L
hφ : φ ∈ T
⊢ M' ⊨ φ

tactic: refine'
  Filter.Eventually.filter_mono (Ultrafilter.of_le _)
    (Filter.eventually_atTop.2
      ⟨{⟨φ, hφ⟩}, fun s h' =>
        Theory.realize_sentence_of_mem (s.map (Function.Embedding.subtype fun x => x ∈ T))
          _⟩)
state_before: L : Language
T✝ : Theory L
α : Type w
n : ℕ
T' T : Theory L
h : IsFinitelySatisfiable T
M : Finset ↑T → Type (max u v) :=
  fun T0 => ↑(Nonempty.some (_ : IsSatisfiable ↑(Finset.map (Function.Embedding.subtype fun x => x ∈ T) T0)))
M' : Type (max u v) := Filter.Product (↑(Ultrafilter.of Filter.atTop)) M
φ : Sentence L
hφ : φ ∈ T
⊢ ∀ᶠ (a : Finset ↑T) in ↑(Ultrafilter.of Filter.atTop), M a ⊨ φ

tactic: simp only [Finset.coe_map, Function.Embedding.coe_subtype, Set.mem_image, Finset.mem_coe,
  Subtype.exists, Subtype.coe_mk, exists_and_right, exists_eq_right]
state_before: L : Language
T✝ : Theory L
α : Type w
n : ℕ
T' T : Theory L
h : IsFinitelySatisfiable T
M : Finset ↑T → Type (max u v) :=
  fun T0 => ↑(Nonempty.some (_ : IsSatisfiable ↑(Finset.map (Function.Embedding.subtype fun x => x ∈ T) T0)))
M' : Type (max u v) := Filter.Product (↑(Ultrafilter.of Filter.atTop)) M
φ : Sentence L
hφ : φ ∈ T
s : Finset ↑T
h' : s ≥ {{ val := φ, property := hφ }}
⊢ φ ∈ ↑(Finset.map (Function.Embedding.subtype fun x => x ∈ T) s)

tactic: exact ⟨hφ, h' (Finset.mem_singleton_self _)⟩
state_before: L : Language
T✝ : Theory L
α : Type w
n : ℕ
T' T : Theory L
h : IsFinitelySatisfiable T
M : Finset ↑T → Type (max u v) :=
  fun T0 => ↑(Nonempty.some (_ : IsSatisfiable ↑(Finset.map (Function.Embedding.subtype fun x => x ∈ T) T0)))
M' : Type (max u v) := Filter.Product (↑(Ultrafilter.of Filter.atTop)) M
φ : Sentence L
hφ : φ ∈ T
s : Finset ↑T
h' : s ≥ {{ val := φ, property := hφ }}
⊢ ∃ x, { val := φ, property := (_ : φ ∈ T) } ∈ s