l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem map_boundedFormula (f : M ↪ₑ[L] N) {α : Type*} {n : ℕ} (φ : L.BoundedFormula α n)
    (v : α → M) (xs : Fin n → M) : φ.Realize (f ∘ v) (f ∘ xs) ↔ φ.Realize v xs := by
  classical
    rw [← BoundedFormula.realize_restrictFreeVar Set.Subset.rfl, Set.inclusion_eq_id, iff_eq_eq]
    have h :=
      f.map_formula' ((φ.restrictFreeVar id).toFormula.relabel (Fintype.equivFin _))
        (Sum.elim (v ∘ (↑)) xs ∘ (Fintype.equivFin _).symm)
    simp only [Formula.realize_relabel, BoundedFormula.realize_toFormula, iff_eq_eq] at h
    rw [← Function.comp.assoc _ _ (Fintype.equivFin _).symm,
      Function.comp.assoc _ (Fintype.equivFin _).symm (Fintype.equivFin _), Equiv.symm_comp_self,
      Function.comp.right_id, Function.comp.assoc, Sum.elim_comp_inl,
      Function.comp.assoc _ _ Sum.inr, Sum.elim_comp_inr, ← Function.comp.assoc] at h
    refine' h.trans _
    

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
f : M ↪ₑ[L] N
α : Type u_5
n : ℕ
φ : BoundedFormula L α n
v : α → M
xs : Fin n → M
h :
  BoundedFormula.Realize (BoundedFormula.restrictFreeVar φ id) ((↑f ∘ v) ∘ Subtype.val) (↑f ∘ xs) =
    BoundedFormula.Realize (BoundedFormula.restrictFreeVar φ id)
      (((Sum.elim (v ∘ Subtype.val) xs ∘
            ⇑(Fintype.equivFin ({ x // x ∈ BoundedFormula.freeVarFinset φ } ⊕ Fin n)).symm) ∘
          ⇑(Fintype.equivFin ({ x // x ∈ BoundedFormula.freeVarFinset φ } ⊕ Fin n))) ∘
        Sum.inl)
      (((Sum.elim (v ∘ Subtype.val) xs ∘
            ⇑(Fintype.equivFin ({ x // x ∈ BoundedFormula.freeVarFinset φ } ⊕ Fin n)).symm) ∘
          ⇑(Fintype.equivFin ({ x // x ∈ BoundedFormula.freeVarFinset φ } ⊕ Fin n))) ∘
        Sum.inr)
⊢ BoundedFormula.Realize (BoundedFormula.restrictFreeVar φ id)
      (((Sum.elim (v ∘ Subtype.val) xs ∘
            ⇑(Fintype.equivFin ({ x // x ∈ BoundedFormula.freeVarFinset φ } ⊕ Fin n)).symm) ∘
          ⇑(Fintype.equivFin ({ x // x ∈ BoundedFormula.freeVarFinset φ } ⊕ Fin n))) ∘
        Sum.inl)
      (((Sum.elim (v ∘ Subtype.val) xs ∘
            ⇑(Fintype.equivFin ({ x // x ∈ BoundedFormula.freeVarFinset φ } ⊕ Fin n)).symm) ∘
          ⇑(Fintype.equivFin ({ x // x ∈ BoundedFormula.freeVarFinset φ } ⊕ Fin n))) ∘
        Sum.inr) =
    BoundedFormula.Realize φ v xs

Next tactic:
erw [Function.comp.assoc _ _ (Fintype.equivFin _), Equiv.symm_comp_self, Function.comp.right_id,
      Sum.elim_comp_inl, Sum.elim_comp_inr (v ∘ Subtype.val) xs,
      ← Set.inclusion_eq_id (s := (BoundedFormula.freeVarFinset φ : Set α)) Set.Subset.rfl,
      BoundedFormula.realize_restrictFreeVar Set.Subset.rfl]
@[simp]
theorem map_formula (f : M ↪ₑ[L] N) {α : Type*} (φ : L.Formula α) (x : α → M) :
    φ.Realize (f ∘ x) ↔ φ.Realize x := by
  

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
f : M ↪ₑ[L] N
α : Type u_5
φ : Formula L α
x : α → M
⊢ Formula.Realize φ (⇑f ∘ x) ↔ Formula.Realize φ x

Next tactic:
rw [Formula.Realize, Formula.Realize, ← f.map_boundedFormula, Unique.eq_default (f ∘ default)]
theorem map_sentence (f : M ↪ₑ[L] N) (φ : L.Sentence) : M ⊨ φ ↔ N ⊨ φ := by
  

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
f : M ↪ₑ[L] N
φ : Sentence L
⊢ M ⊨ φ ↔ N ⊨ φ

Next tactic:
rw [Sentence.Realize, Sentence.Realize, ← f.map_formula, Unique.eq_default (f ∘ default)]
theorem theory_model_iff (f : M ↪ₑ[L] N) (T : L.Theory) : M ⊨ T ↔ N ⊨ T := by
  

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
f : M ↪ₑ[L] N
T : Theory L
⊢ M ⊨ T ↔ N ⊨ T

Next tactic:
simp only [Theory.model_iff, f.map_sentence]
@[simp]
theorem injective (φ : M ↪ₑ[L] N) : Function.Injective φ := by
  

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
φ : M ↪ₑ[L] N
⊢ Function.Injective ⇑φ

Next tactic:
intro x y
@[simp]
theorem injective (φ : M ↪ₑ[L] N) : Function.Injective φ := by
  intro x y
  

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
φ : M ↪ₑ[L] N
x y : M
⊢ φ x = φ y → x = y

Next tactic:
have h :=
    φ.map_formula ((var 0).equal (var 1) : L.Formula (Fin 2)) fun i => if i = 0 then x else y
@[simp]
theorem injective (φ : M ↪ₑ[L] N) : Function.Injective φ := by
  intro x y
  have h :=
    φ.map_formula ((var 0).equal (var 1) : L.Formula (Fin 2)) fun i => if i = 0 then x else y
  

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
φ : M ↪ₑ[L] N
x y : M
h :
  Formula.Realize (Term.equal (var 0) (var 1)) (⇑φ ∘ fun i => if i = 0 then x else y) ↔
    Formula.Realize (Term.equal (var 0) (var 1)) fun i => if i = 0 then x else y
⊢ φ x = φ y → x = y

Next tactic:
rw [Formula.realize_equal, Formula.realize_equal] at h
@[simp]
theorem injective (φ : M ↪ₑ[L] N) : Function.Injective φ := by
  intro x y
  have h :=
    φ.map_formula ((var 0).equal (var 1) : L.Formula (Fin 2)) fun i => if i = 0 then x else y
  rw [Formula.realize_equal, Formula.realize_equal] at h
  

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
φ : M ↪ₑ[L] N
x y : M
h :
  Term.realize (⇑φ ∘ fun i => if i = 0 then x else y) (var 0) =
      Term.realize (⇑φ ∘ fun i => if i = 0 then x else y) (var 1) ↔
    Term.realize (fun i => if i = 0 then x else y) (var 0) = Term.realize (fun i => if i = 0 then x else y) (var 1)
⊢ φ x = φ y → x = y

Next tactic:
simp only [Nat.one_ne_zero, Term.realize, Fin.one_eq_zero_iff, if_true, eq_self_iff_true,
    Function.comp_apply, if_false] at h
@[simp]
theorem injective (φ : M ↪ₑ[L] N) : Function.Injective φ := by
  intro x y
  have h :=
    φ.map_formula ((var 0).equal (var 1) : L.Formula (Fin 2)) fun i => if i = 0 then x else y
  rw [Formula.realize_equal, Formula.realize_equal] at h
  simp only [Nat.one_ne_zero, Term.realize, Fin.one_eq_zero_iff, if_true, eq_self_iff_true,
    Function.comp_apply, if_false] at h
  

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
φ : M ↪ₑ[L] N
x y : M
h : φ x = φ (if 2 = 1 then x else y) ↔ x = if 2 = 1 then x else y
⊢ φ x = φ y → x = y

Next tactic:
exact h.1
@[simp]
theorem map_fun (φ : M ↪ₑ[L] N) {n : ℕ} (f : L.Functions n) (x : Fin n → M) :
    φ (funMap f x) = funMap f (φ ∘ x) := by
  

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
φ : M ↪ₑ[L] N
n : ℕ
f : Functions L n
x : Fin n → M
⊢ φ (funMap f x) = funMap f (⇑φ ∘ x)

Next tactic:
have h := φ.map_formula (Formula.graph f) (Fin.cons (funMap f x) x)
@[simp]
theorem map_fun (φ : M ↪ₑ[L] N) {n : ℕ} (f : L.Functions n) (x : Fin n → M) :
    φ (funMap f x) = funMap f (φ ∘ x) := by
  have h := φ.map_formula (Formula.graph f) (Fin.cons (funMap f x) x)
  

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
φ : M ↪ₑ[L] N
n : ℕ
f : Functions L n
x : Fin n → M
h :
  Formula.Realize (Formula.graph f) (⇑φ ∘ Fin.cons (funMap f x) x) ↔
    Formula.Realize (Formula.graph f) (Fin.cons (funMap f x) x)
⊢ φ (funMap f x) = funMap f (⇑φ ∘ x)

Next tactic:
rw [Formula.realize_graph, Fin.comp_cons, Formula.realize_graph] at h
@[simp]
theorem map_fun (φ : M ↪ₑ[L] N) {n : ℕ} (f : L.Functions n) (x : Fin n → M) :
    φ (funMap f x) = funMap f (φ ∘ x) := by
  have h := φ.map_formula (Formula.graph f) (Fin.cons (funMap f x) x)
  rw [Formula.realize_graph, Fin.comp_cons, Formula.realize_graph] at h
  

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
φ : M ↪ₑ[L] N
n : ℕ
f : Functions L n
x : Fin n → M
h : funMap f (⇑φ ∘ x) = φ (funMap f x) ↔ funMap f x = funMap f x
⊢ φ (funMap f x) = funMap f (⇑φ ∘ x)

Next tactic:
rw [eq_comm, h]
/-- An elementary embedding is also a first-order embedding. -/
def toEmbedding (f : M ↪ₑ[L] N) : M ↪[L] N where
  toFun := f
  inj' := f.injective
  map_fun' {_} f x := by 

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
f✝ : M ↪ₑ[L] N
x✝ : ℕ
f : Functions L x✝
x : Fin x✝ → M
⊢ Function.Embedding.toFun { toFun := ⇑f✝, inj' := (_ : Function.Injective ⇑f✝) } (funMap f x) =
    funMap f ({ toFun := ⇑f✝, inj' := (_ : Function.Injective ⇑f✝) }.toFun ∘ x)

Next tactic:
aesop
/-- An elementary embedding is also a first-order embedding. -/
def toEmbedding (f : M ↪ₑ[L] N) : M ↪[L] N where
  toFun := f
  inj' := f.injective
  map_fun' {_} f x := by aesop
  map_rel' {_} R x := by 

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
f : M ↪ₑ[L] N
x✝ : ℕ
R : Relations L x✝
x : Fin x✝ → M
⊢ RelMap R ({ toFun := ⇑f, inj' := (_ : Function.Injective ⇑f) }.toFun ∘ x) ↔ RelMap R x

Next tactic:
aesop
/-- An elementary embedding is also a first-order homomorphism. -/
def toHom (f : M ↪ₑ[L] N) : M →[L] N where
  toFun := f
  map_fun' {_} f x := by 

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
f✝ : M ↪ₑ[L] N
x✝ : ℕ
f : Functions L x✝
x : Fin x✝ → M
⊢ f✝ (funMap f x) = funMap f (⇑f✝ ∘ x)

Next tactic:
aesop
/-- An elementary embedding is also a first-order homomorphism. -/
def toHom (f : M ↪ₑ[L] N) : M →[L] N where
  toFun := f
  map_fun' {_} f x := by aesop
  map_rel' {_} R x := by 

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
f : M ↪ₑ[L] N
x✝ : ℕ
R : Relations L x✝
x : Fin x✝ → M
⊢ RelMap R x → RelMap R (⇑f ∘ x)

Next tactic:
aesop
/-- Composition of elementary embeddings -/
@[trans]
def comp (hnp : N ↪ₑ[L] P) (hmn : M ↪ₑ[L] N) : M ↪ₑ[L] P where
  toFun := hnp ∘ hmn
  map_formula' n φ x := by
    

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
hnp : N ↪ₑ[L] P
hmn : M ↪ₑ[L] N
n : ℕ
φ : Formula L (Fin n)
x : Fin n → M
⊢ Formula.Realize φ ((⇑hnp ∘ ⇑hmn) ∘ x) ↔ Formula.Realize φ x

Next tactic:
cases' hnp with _ hhnp
/-- Composition of elementary embeddings -/
@[trans]
def comp (hnp : N ↪ₑ[L] P) (hmn : M ↪ₑ[L] N) : M ↪ₑ[L] P where
  toFun := hnp ∘ hmn
  map_formula' n φ x := by
    cases' hnp with _ hhnp
    

Proof state:
case mk
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
hmn : M ↪ₑ[L] N
n : ℕ
φ : Formula L (Fin n)
x : Fin n → M
toFun✝ : N → P
hhnp : ∀ ⦃n : ℕ⦄ (φ : Formula L (Fin n)) (x : Fin n → N), Formula.Realize φ (toFun✝ ∘ x) ↔ Formula.Realize φ x
⊢ Formula.Realize φ ((⇑(mk toFun✝) ∘ ⇑hmn) ∘ x) ↔ Formula.Realize φ x

Next tactic:
cases' hmn with _ hhmn
/-- Composition of elementary embeddings -/
@[trans]
def comp (hnp : N ↪ₑ[L] P) (hmn : M ↪ₑ[L] N) : M ↪ₑ[L] P where
  toFun := hnp ∘ hmn
  map_formula' n φ x := by
    cases' hnp with _ hhnp
    cases' hmn with _ hhmn
    

Proof state:
case mk.mk
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
n : ℕ
φ : Formula L (Fin n)
x : Fin n → M
toFun✝¹ : N → P
hhnp : ∀ ⦃n : ℕ⦄ (φ : Formula L (Fin n)) (x : Fin n → N), Formula.Realize φ (toFun✝¹ ∘ x) ↔ Formula.Realize φ x
toFun✝ : M → N
hhmn : ∀ ⦃n : ℕ⦄ (φ : Formula L (Fin n)) (x : Fin n → M), Formula.Realize φ (toFun✝ ∘ x) ↔ Formula.Realize φ x
⊢ Formula.Realize φ ((⇑(mk toFun✝¹) ∘ ⇑(mk toFun✝)) ∘ x) ↔ Formula.Realize φ x

Next tactic:
erw [hhnp, hhmn]
/-- The canonical elementary embedding of an `L`-structure into any model of its elementary diagram
-/
@[simps]
def ElementaryEmbedding.ofModelsElementaryDiagram (N : Type*) [L.Structure N] [L[[M]].Structure N]
    [(lhomWithConstants L M).IsExpansionOn N] [N ⊨ L.elementaryDiagram M] : M ↪ₑ[L] N :=
  ⟨((↑) : L[[M]].Constants → N) ∘ Sum.inr, fun n φ x => by
    

Proof state:
L : Language
M : Type u_1
N✝ : Type u_2
P : Type u_3
Q : Type u_4
inst✝⁷ : Structure L M
inst✝⁶ : Structure L N✝
inst✝⁵ : Structure L P
inst✝⁴ : Structure L Q
N : Type u_5
inst✝³ : Structure L N
inst✝² : Structure (L[[M]]) N
inst✝¹ : LHom.IsExpansionOn (lhomWithConstants L M) N
inst✝ : N ⊨ elementaryDiagram L M
n : ℕ
φ : Formula L (Fin n)
x : Fin n → M
⊢ Formula.Realize φ ((constantMap ∘ Sum.inr) ∘ x) ↔ Formula.Realize φ x

Next tactic:
refine'
      _root_.trans _
        ((realize_iff_of_model_completeTheory M N
              (((L.lhomWithConstants M).onBoundedFormula φ).subst
                  (Constants.term ∘ Sum.inr ∘ x)).alls).trans
          _)
/-- The canonical elementary embedding of an `L`-structure into any model of its elementary diagram
-/
@[simps]
def ElementaryEmbedding.ofModelsElementaryDiagram (N : Type*) [L.Structure N] [L[[M]].Structure N]
    [(lhomWithConstants L M).IsExpansionOn N] [N ⊨ L.elementaryDiagram M] : M ↪ₑ[L] N :=
  ⟨((↑) : L[[M]].Constants → N) ∘ Sum.inr, fun n φ x => by
    refine'
      _root_.trans _
        ((realize_iff_of_model_completeTheory M N
              (((L.lhomWithConstants M).onBoundedFormula φ).subst
                  (Constants.term ∘ Sum.inr ∘ x)).alls).trans
          _)
    · 

Proof state:
case refine'_1
L : Language
M : Type u_1
N✝ : Type u_2
P : Type u_3
Q : Type u_4
inst✝⁷ : Structure L M
inst✝⁶ : Structure L N✝
inst✝⁵ : Structure L P
inst✝⁴ : Structure L Q
N : Type u_5
inst✝³ : Structure L N
inst✝² : Structure (L[[M]]) N
inst✝¹ : LHom.IsExpansionOn (lhomWithConstants L M) N
inst✝ : N ⊨ elementaryDiagram L M
n : ℕ
φ : Formula L (Fin n)
x : Fin n → M
⊢ Formula.Realize φ ((constantMap ∘ Sum.inr) ∘ x) ↔
    N ⊨
      BoundedFormula.alls
        (BoundedFormula.subst (LHom.onBoundedFormula (lhomWithConstants L M) φ) (Constants.term ∘ Sum.inr ∘ x))

Next tactic:
simp_rw [Sentence.Realize, BoundedFormula.realize_alls, BoundedFormula.realize_subst,
        LHom.realize_onBoundedFormula, Formula.Realize, Unique.forall_iff, Function.comp,
        Term.realize_constants]
/-- The canonical elementary embedding of an `L`-structure into any model of its elementary diagram
-/
@[simps]
def ElementaryEmbedding.ofModelsElementaryDiagram (N : Type*) [L.Structure N] [L[[M]].Structure N]
    [(lhomWithConstants L M).IsExpansionOn N] [N ⊨ L.elementaryDiagram M] : M ↪ₑ[L] N :=
  ⟨((↑) : L[[M]].Constants → N) ∘ Sum.inr, fun n φ x => by
    refine'
      _root_.trans _
        ((realize_iff_of_model_completeTheory M N
              (((L.lhomWithConstants M).onBoundedFormula φ).subst
                  (Constants.term ∘ Sum.inr ∘ x)).alls).trans
          _)
    · simp_rw [Sentence.Realize, BoundedFormula.realize_alls, BoundedFormula.realize_subst,
        LHom.realize_onBoundedFormula, Formula.Realize, Unique.forall_iff, Function.comp,
        Term.realize_constants]
    · 

Proof state:
case refine'_2
L : Language
M : Type u_1
N✝ : Type u_2
P : Type u_3
Q : Type u_4
inst✝⁷ : Structure L M
inst✝⁶ : Structure L N✝
inst✝⁵ : Structure L P
inst✝⁴ : Structure L Q
N : Type u_5
inst✝³ : Structure L N
inst✝² : Structure (L[[M]]) N
inst✝¹ : LHom.IsExpansionOn (lhomWithConstants L M) N
inst✝ : N ⊨ elementaryDiagram L M
n : ℕ
φ : Formula L (Fin n)
x : Fin n → M
⊢ M ⊨
      BoundedFormula.alls
        (BoundedFormula.subst (LHom.onBoundedFormula (lhomWithConstants L M) φ) (Constants.term ∘ Sum.inr ∘ x)) ↔
    Formula.Realize φ x

Next tactic:
simp_rw [Sentence.Realize, BoundedFormula.realize_alls, BoundedFormula.realize_subst,
        LHom.realize_onBoundedFormula, Formula.Realize, Unique.forall_iff]
/-- The canonical elementary embedding of an `L`-structure into any model of its elementary diagram
-/
@[simps]
def ElementaryEmbedding.ofModelsElementaryDiagram (N : Type*) [L.Structure N] [L[[M]].Structure N]
    [(lhomWithConstants L M).IsExpansionOn N] [N ⊨ L.elementaryDiagram M] : M ↪ₑ[L] N :=
  ⟨((↑) : L[[M]].Constants → N) ∘ Sum.inr, fun n φ x => by
    refine'
      _root_.trans _
        ((realize_iff_of_model_completeTheory M N
              (((L.lhomWithConstants M).onBoundedFormula φ).subst
                  (Constants.term ∘ Sum.inr ∘ x)).alls).trans
          _)
    · simp_rw [Sentence.Realize, BoundedFormula.realize_alls, BoundedFormula.realize_subst,
        LHom.realize_onBoundedFormula, Formula.Realize, Unique.forall_iff, Function.comp,
        Term.realize_constants]
    · simp_rw [Sentence.Realize, BoundedFormula.realize_alls, BoundedFormula.realize_subst,
        LHom.realize_onBoundedFormula, Formula.Realize, Unique.forall_iff]
      

Proof state:
case refine'_2
L : Language
M : Type u_1
N✝ : Type u_2
P : Type u_3
Q : Type u_4
inst✝⁷ : Structure L M
inst✝⁶ : Structure L N✝
inst✝⁵ : Structure L P
inst✝⁴ : Structure L Q
N : Type u_5
inst✝³ : Structure L N
inst✝² : Structure (L[[M]]) N
inst✝¹ : LHom.IsExpansionOn (lhomWithConstants L M) N
inst✝ : N ⊨ elementaryDiagram L M
n : ℕ
φ : Formula L (Fin n)
x : Fin n → M
⊢ BoundedFormula.Realize φ (fun a => Term.realize default ((Constants.term ∘ Sum.inr ∘ x) a)) default ↔
    BoundedFormula.Realize φ x default

Next tactic:
rfl
/-- The **Tarski-Vaught test** for elementarity of an embedding. -/
theorem isElementary_of_exists (f : M ↪[L] N)
    (htv :
      ∀ (n : ℕ) (φ : L.BoundedFormula Empty (n + 1)) (x : Fin n → M) (a : N),
        φ.Realize default (Fin.snoc (f ∘ x) a : _ → N) →
          ∃ b : M, φ.Realize default (Fin.snoc (f ∘ x) (f b) : _ → N)) :
    ∀ {n} (φ : L.Formula (Fin n)) (x : Fin n → M), φ.Realize (f ∘ x) ↔ φ.Realize x := by
  

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
f : M ↪[L] N
htv :
  ∀ (n : ℕ) (φ : BoundedFormula L Empty (n + 1)) (x : Fin n → M) (a : N),
    BoundedFormula.Realize φ default (Fin.snoc (⇑f ∘ x) a) →
      ∃ b, BoundedFormula.Realize φ default (Fin.snoc (⇑f ∘ x) (f b))
⊢ ∀ {n : ℕ} (φ : Formula L (Fin n)) (x : Fin n → M), Formula.Realize φ (⇑f ∘ x) ↔ Formula.Realize φ x

Next tactic:
suffices h :
    ∀ (n : ℕ) (φ : L.BoundedFormula Empty n) (xs : Fin n → M),
      φ.Realize (f ∘ default) (f ∘ xs) ↔ φ.Realize default xs
/-- The **Tarski-Vaught test** for elementarity of an embedding. -/
theorem isElementary_of_exists (f : M ↪[L] N)
    (htv :
      ∀ (n : ℕ) (φ : L.BoundedFormula Empty (n + 1)) (x : Fin n → M) (a : N),
        φ.Realize default (Fin.snoc (f ∘ x) a : _ → N) →
          ∃ b : M, φ.Realize default (Fin.snoc (f ∘ x) (f b) : _ → N)) :
    ∀ {n} (φ : L.Formula (Fin n)) (x : Fin n → M), φ.Realize (f ∘ x) ↔ φ.Realize x := by
  suffices h :
    ∀ (n : ℕ) (φ : L.BoundedFormula Empty n) (xs : Fin n → M),
      φ.Realize (f ∘ default) (f ∘ xs) ↔ φ.Realize default xs
  · 

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
f : M ↪[L] N
htv :
  ∀ (n : ℕ) (φ : BoundedFormula L Empty (n + 1)) (x : Fin n → M) (a : N),
    BoundedFormula.Realize φ default (Fin.snoc (⇑f ∘ x) a) →
      ∃ b, BoundedFormula.Realize φ default (Fin.snoc (⇑f ∘ x) (f b))
h :
  ∀ (n : ℕ) (φ : BoundedFormula L Empty n) (xs : Fin n → M),
    BoundedFormula.Realize φ (⇑f ∘ default) (⇑f ∘ xs) ↔ BoundedFormula.Realize φ default xs
⊢ ∀ {n : ℕ} (φ : Formula L (Fin n)) (x : Fin n → M), Formula.Realize φ (⇑f ∘ x) ↔ Formula.Realize φ x

Next tactic:
intro n φ x
/-- The **Tarski-Vaught test** for elementarity of an embedding. -/
theorem isElementary_of_exists (f : M ↪[L] N)
    (htv :
      ∀ (n : ℕ) (φ : L.BoundedFormula Empty (n + 1)) (x : Fin n → M) (a : N),
        φ.Realize default (Fin.snoc (f ∘ x) a : _ → N) →
          ∃ b : M, φ.Realize default (Fin.snoc (f ∘ x) (f b) : _ → N)) :
    ∀ {n} (φ : L.Formula (Fin n)) (x : Fin n → M), φ.Realize (f ∘ x) ↔ φ.Realize x := by
  suffices h :
    ∀ (n : ℕ) (φ : L.BoundedFormula Empty n) (xs : Fin n → M),
      φ.Realize (f ∘ default) (f ∘ xs) ↔ φ.Realize default xs
  · intro n φ x
    

Proof state:
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
f : M ↪[L] N
htv :
  ∀ (n : ℕ) (φ : BoundedFormula L Empty (n + 1)) (x : Fin n → M) (a : N),
    BoundedFormula.Realize φ default (Fin.snoc (⇑f ∘ x) a) →
      ∃ b, BoundedFormula.Realize φ default (Fin.snoc (⇑f ∘ x) (f b))
h :
  ∀ (n : ℕ) (φ : BoundedFormula L Empty n) (xs : Fin n → M),
    BoundedFormula.Realize φ (⇑f ∘ default) (⇑f ∘ xs) ↔ BoundedFormula.Realize φ default xs
n : ℕ
φ : Formula L (Fin n)
x : Fin n → M
⊢ Formula.Realize φ (⇑f ∘ x) ↔ Formula.Realize φ x

Next tactic:
refine' φ.realize_relabel_sum_inr.symm.trans (_root_.trans (h n _ _) φ.realize_relabel_sum_inr)
/-- The **Tarski-Vaught test** for elementarity of an embedding. -/
theorem isElementary_of_exists (f : M ↪[L] N)
    (htv :
      ∀ (n : ℕ) (φ : L.BoundedFormula Empty (n + 1)) (x : Fin n → M) (a : N),
        φ.Realize default (Fin.snoc (f ∘ x) a : _ → N) →
          ∃ b : M, φ.Realize default (Fin.snoc (f ∘ x) (f b) : _ → N)) :
    ∀ {n} (φ : L.Formula (Fin n)) (x : Fin n → M), φ.Realize (f ∘ x) ↔ φ.Realize x := by
  suffices h :
    ∀ (n : ℕ) (φ : L.BoundedFormula Empty n) (xs : Fin n → M),
      φ.Realize (f ∘ default) (f ∘ xs) ↔ φ.Realize default xs
  · intro n φ x
    refine' φ.realize_relabel_sum_inr.symm.trans (_root_.trans (h n _ _) φ.realize_relabel_sum_inr)
  

Proof state:
case h
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
f : M ↪[L] N
htv :
  ∀ (n : ℕ) (φ : BoundedFormula L Empty (n + 1)) (x : Fin n → M) (a : N),
    BoundedFormula.Realize φ default (Fin.snoc (⇑f ∘ x) a) →
      ∃ b, BoundedFormula.Realize φ default (Fin.snoc (⇑f ∘ x) (f b))
⊢ ∀ (n : ℕ) (φ : BoundedFormula L Empty n) (xs : Fin n → M),
    BoundedFormula.Realize φ (⇑f ∘ default) (⇑f ∘ xs) ↔ BoundedFormula.Realize φ default xs

Next tactic:
refine' fun n φ => φ.recOn _ _ _ _ _
/-- The **Tarski-Vaught test** for elementarity of an embedding. -/
theorem isElementary_of_exists (f : M ↪[L] N)
    (htv :
      ∀ (n : ℕ) (φ : L.BoundedFormula Empty (n + 1)) (x : Fin n → M) (a : N),
        φ.Realize default (Fin.snoc (f ∘ x) a : _ → N) →
          ∃ b : M, φ.Realize default (Fin.snoc (f ∘ x) (f b) : _ → N)) :
    ∀ {n} (φ : L.Formula (Fin n)) (x : Fin n → M), φ.Realize (f ∘ x) ↔ φ.Realize x := by
  suffices h :
    ∀ (n : ℕ) (φ : L.BoundedFormula Empty n) (xs : Fin n → M),
      φ.Realize (f ∘ default) (f ∘ xs) ↔ φ.Realize default xs
  · intro n φ x
    refine' φ.realize_relabel_sum_inr.symm.trans (_root_.trans (h n _ _) φ.realize_relabel_sum_inr)
  refine' fun n φ => φ.recOn _ _ _ _ _
  · 

Proof state:
case h.refine'_1
L : Language
M : Type u_1
N : Type u_2
P : Type u_3
Q : Type u_4
inst✝³ : Structure L M
inst✝² : Structure L N
inst✝¹ : Structure L P
inst✝ : Structure L Q
f : M ↪[L] N
htv :
  ∀ (n : ℕ) (φ : BoundedFormula L Empty (n + 1)) (x : Fin n → M) (a : N),
    BoundedFormula.Realize φ default (Fin.snoc (⇑f ∘ x) a) →
      ∃ b, BoundedFormula.Realize φ default (Fin.snoc (⇑f ∘ x) (f b))
n : ℕ
φ : BoundedFormula L Empty n
⊢ ∀ {n : ℕ} (xs : Fin n → M),
    BoundedFormula.Realize BoundedFormula.falsum (⇑f ∘ default) (⇑f ∘ xs) ↔
      BoundedFormula.Realize BoundedFormula.falsum default xs

Next tactic:
exact fun {_} _ => Iff.rfl