l3lab/ntp-mathlib huggingface dataset:
theorem definable_iff_finitely_definable :
    A.Definable L s ↔ ∃ (A0 : Finset M), (A0 : Set M) ⊆ A ∧
      (A0 : Set M).Definable L s := by
  letI := Classical.decEq M
  letI := Classical.decEq α
  constructor
  · simp only [definable_iff_exists_formula_sum]
    rintro ⟨φ, rfl⟩
    let A0 := (φ.freeVarFinset.preimage Sum.inl
      (Function.Injective.injOn Sum.inl_injective _)).image Subtype.val
    have hA0 : (A0 : Set M) ⊆ A := by simp
    refine ⟨A0, hA0, (φ.restrictFreeVar
      (Set.inclusion (Set.Subset.refl _))).relabel ?_, ?_⟩
    · rintro ⟨a | a, ha⟩
      · exact Sum.inl (Sum.inl ⟨a, by simpa using ha⟩)
      · exact Sum.inl (Sum.inr a)
    · ext v
      simp only [Formula.Realize, BoundedFormula.realize_relabel,
        Set.mem_setOf_eq]
      

Proof state:
case mp.intro.refine_2.h
M : Type w
A : Set M
L : Language
inst✝ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
this✝ : DecidableEq M := Classical.decEq M
this : DecidableEq α := Classical.decEq α
φ : Formula L (↑A ⊕ α)
A0 : Finset M :=
  Finset.image Subtype.val
    (Finset.preimage (BoundedFormula.freeVarFinset φ) Sum.inl
      (_ : InjOn Sum.inl (Sum.inl ⁻¹' ↑(BoundedFormula.freeVarFinset φ))))
hA0 : ↑A0 ⊆ A
v : α → M
⊢ BoundedFormula.Realize φ (Sum.elim Subtype.val v) default ↔
    BoundedFormula.Realize
      (BoundedFormula.restrictFreeVar φ
        (inclusion
          (_ :
            (fun x => x ∈ (BoundedFormula.freeVarFinset φ).val) ⊆ fun x => x ∈ (BoundedFormula.freeVarFinset φ).val)))
      (Sum.elim (Sum.elim Subtype.val v) (default ∘ Fin.castAdd 0) ∘ fun a =>
        Sum.rec (motive := fun x =>
          (x ∈ fun x => x ∈ (BoundedFormula.freeVarFinset φ).val) →
            (↑↑(Finset.image Subtype.val
                      (Finset.preimage (BoundedFormula.freeVarFinset φ) Sum.inl
                        (_ : InjOn Sum.inl (Sum.inl ⁻¹' ↑(BoundedFormula.freeVarFinset φ))))) ⊕
                α) ⊕
              Fin 0)
          (fun val ha => Sum.inl (Sum.inl { val := ↑val, property := (_ : ↑val ∈ ↑A0) }))
          (fun val ha => Sum.inl (Sum.inr val)) ↑a (_ : ↑a ∈ fun x => x ∈ (BoundedFormula.freeVarFinset φ).val))
      (default ∘ Fin.natAdd 0)

Next tactic:
apply Iff.symm
theorem definable_iff_finitely_definable :
    A.Definable L s ↔ ∃ (A0 : Finset M), (A0 : Set M) ⊆ A ∧
      (A0 : Set M).Definable L s := by
  letI := Classical.decEq M
  letI := Classical.decEq α
  constructor
  · simp only [definable_iff_exists_formula_sum]
    rintro ⟨φ, rfl⟩
    let A0 := (φ.freeVarFinset.preimage Sum.inl
      (Function.Injective.injOn Sum.inl_injective _)).image Subtype.val
    have hA0 : (A0 : Set M) ⊆ A := by simp
    refine ⟨A0, hA0, (φ.restrictFreeVar
      (Set.inclusion (Set.Subset.refl _))).relabel ?_, ?_⟩
    · rintro ⟨a | a, ha⟩
      · exact Sum.inl (Sum.inl ⟨a, by simpa using ha⟩)
      · exact Sum.inl (Sum.inr a)
    · ext v
      simp only [Formula.Realize, BoundedFormula.realize_relabel,
        Set.mem_setOf_eq]
      apply Iff.symm
      

Proof state:
case mp.intro.refine_2.h.h
M : Type w
A : Set M
L : Language
inst✝ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
this✝ : DecidableEq M := Classical.decEq M
this : DecidableEq α := Classical.decEq α
φ : Formula L (↑A ⊕ α)
A0 : Finset M :=
  Finset.image Subtype.val
    (Finset.preimage (BoundedFormula.freeVarFinset φ) Sum.inl
      (_ : InjOn Sum.inl (Sum.inl ⁻¹' ↑(BoundedFormula.freeVarFinset φ))))
hA0 : ↑A0 ⊆ A
v : α → M
⊢ BoundedFormula.Realize
      (BoundedFormula.restrictFreeVar φ
        (inclusion
          (_ :
            (fun x => x ∈ (BoundedFormula.freeVarFinset φ).val) ⊆ fun x => x ∈ (BoundedFormula.freeVarFinset φ).val)))
      (Sum.elim (Sum.elim Subtype.val v) (default ∘ Fin.castAdd 0) ∘ fun a =>
        Sum.rec (motive := fun x =>
          (x ∈ fun x => x ∈ (BoundedFormula.freeVarFinset φ).val) →
            (↑↑(Finset.image Subtype.val
                      (Finset.preimage (BoundedFormula.freeVarFinset φ) Sum.inl
                        (_ : InjOn Sum.inl (Sum.inl ⁻¹' ↑(BoundedFormula.freeVarFinset φ))))) ⊕
                α) ⊕
              Fin 0)
          (fun val ha => Sum.inl (Sum.inl { val := ↑val, property := (_ : ↑val ∈ ↑A0) }))
          (fun val ha => Sum.inl (Sum.inr val)) ↑a (_ : ↑a ∈ fun x => x ∈ (BoundedFormula.freeVarFinset φ).val))
      (default ∘ Fin.natAdd 0) ↔
    BoundedFormula.Realize φ (Sum.elim Subtype.val v) default

Next tactic:
convert BoundedFormula.realize_restrictFreeVar _
theorem definable_iff_finitely_definable :
    A.Definable L s ↔ ∃ (A0 : Finset M), (A0 : Set M) ⊆ A ∧
      (A0 : Set M).Definable L s := by
  letI := Classical.decEq M
  letI := Classical.decEq α
  constructor
  · simp only [definable_iff_exists_formula_sum]
    rintro ⟨φ, rfl⟩
    let A0 := (φ.freeVarFinset.preimage Sum.inl
      (Function.Injective.injOn Sum.inl_injective _)).image Subtype.val
    have hA0 : (A0 : Set M) ⊆ A := by simp
    refine ⟨A0, hA0, (φ.restrictFreeVar
      (Set.inclusion (Set.Subset.refl _))).relabel ?_, ?_⟩
    · rintro ⟨a | a, ha⟩
      · exact Sum.inl (Sum.inl ⟨a, by simpa using ha⟩)
      · exact Sum.inl (Sum.inr a)
    · ext v
      simp only [Formula.Realize, BoundedFormula.realize_relabel,
        Set.mem_setOf_eq]
      apply Iff.symm
      convert BoundedFormula.realize_restrictFreeVar _
      · 

Proof state:
case h.e'_1.h.e'_7
M : Type w
A : Set M
L : Language
inst✝ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
this✝ : DecidableEq M := Classical.decEq M
this : DecidableEq α := Classical.decEq α
φ : Formula L (↑A ⊕ α)
A0 : Finset M :=
  Finset.image Subtype.val
    (Finset.preimage (BoundedFormula.freeVarFinset φ) Sum.inl
      (_ : InjOn Sum.inl (Sum.inl ⁻¹' ↑(BoundedFormula.freeVarFinset φ))))
hA0 : ↑A0 ⊆ A
v : α → M
⊢ (Sum.elim (Sum.elim Subtype.val v) (default ∘ Fin.castAdd 0) ∘ fun a =>
      Sum.rec (motive := fun x =>
        (x ∈ fun x => x ∈ (BoundedFormula.freeVarFinset φ).val) →
          (↑↑(Finset.image Subtype.val
                    (Finset.preimage (BoundedFormula.freeVarFinset φ) Sum.inl
                      (_ : InjOn Sum.inl (Sum.inl ⁻¹' ↑(BoundedFormula.freeVarFinset φ))))) ⊕
              α) ⊕
            Fin 0)
        (fun val ha => Sum.inl (Sum.inl { val := ↑val, property := (_ : ↑val ∈ ↑A0) }))
        (fun val ha => Sum.inl (Sum.inr val)) ↑a (_ : ↑a ∈ fun x => x ∈ (BoundedFormula.freeVarFinset φ).val)) =
    Sum.elim Subtype.val v ∘ Subtype.val

Next tactic:
ext a
theorem definable_iff_finitely_definable :
    A.Definable L s ↔ ∃ (A0 : Finset M), (A0 : Set M) ⊆ A ∧
      (A0 : Set M).Definable L s := by
  letI := Classical.decEq M
  letI := Classical.decEq α
  constructor
  · simp only [definable_iff_exists_formula_sum]
    rintro ⟨φ, rfl⟩
    let A0 := (φ.freeVarFinset.preimage Sum.inl
      (Function.Injective.injOn Sum.inl_injective _)).image Subtype.val
    have hA0 : (A0 : Set M) ⊆ A := by simp
    refine ⟨A0, hA0, (φ.restrictFreeVar
      (Set.inclusion (Set.Subset.refl _))).relabel ?_, ?_⟩
    · rintro ⟨a | a, ha⟩
      · exact Sum.inl (Sum.inl ⟨a, by simpa using ha⟩)
      · exact Sum.inl (Sum.inr a)
    · ext v
      simp only [Formula.Realize, BoundedFormula.realize_relabel,
        Set.mem_setOf_eq]
      apply Iff.symm
      convert BoundedFormula.realize_restrictFreeVar _
      · ext a
        

Proof state:
case h.e'_1.h.e'_7.h
M : Type w
A : Set M
L : Language
inst✝ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
this✝ : DecidableEq M := Classical.decEq M
this : DecidableEq α := Classical.decEq α
φ : Formula L (↑A ⊕ α)
A0 : Finset M :=
  Finset.image Subtype.val
    (Finset.preimage (BoundedFormula.freeVarFinset φ) Sum.inl
      (_ : InjOn Sum.inl (Sum.inl ⁻¹' ↑(BoundedFormula.freeVarFinset φ))))
hA0 : ↑A0 ⊆ A
v : α → M
a : ↑fun x => x ∈ (BoundedFormula.freeVarFinset φ).val
⊢ (Sum.elim (Sum.elim Subtype.val v) (default ∘ Fin.castAdd 0) ∘ fun a =>
        Sum.rec (motive := fun x =>
          (x ∈ fun x => x ∈ (BoundedFormula.freeVarFinset φ).val) →
            (↑↑(Finset.image Subtype.val
                      (Finset.preimage (BoundedFormula.freeVarFinset φ) Sum.inl
                        (_ : InjOn Sum.inl (Sum.inl ⁻¹' ↑(BoundedFormula.freeVarFinset φ))))) ⊕
                α) ⊕
              Fin 0)
          (fun val ha => Sum.inl (Sum.inl { val := ↑val, property := (_ : ↑val ∈ ↑A0) }))
          (fun val ha => Sum.inl (Sum.inr val)) ↑a (_ : ↑a ∈ fun x => x ∈ (BoundedFormula.freeVarFinset φ).val))
      a =
    (Sum.elim Subtype.val v ∘ Subtype.val) a

Next tactic:
rcases a with ⟨_ | _, _⟩
theorem definable_iff_finitely_definable :
    A.Definable L s ↔ ∃ (A0 : Finset M), (A0 : Set M) ⊆ A ∧
      (A0 : Set M).Definable L s := by
  letI := Classical.decEq M
  letI := Classical.decEq α
  constructor
  · simp only [definable_iff_exists_formula_sum]
    rintro ⟨φ, rfl⟩
    let A0 := (φ.freeVarFinset.preimage Sum.inl
      (Function.Injective.injOn Sum.inl_injective _)).image Subtype.val
    have hA0 : (A0 : Set M) ⊆ A := by simp
    refine ⟨A0, hA0, (φ.restrictFreeVar
      (Set.inclusion (Set.Subset.refl _))).relabel ?_, ?_⟩
    · rintro ⟨a | a, ha⟩
      · exact Sum.inl (Sum.inl ⟨a, by simpa using ha⟩)
      · exact Sum.inl (Sum.inr a)
    · ext v
      simp only [Formula.Realize, BoundedFormula.realize_relabel,
        Set.mem_setOf_eq]
      apply Iff.symm
      convert BoundedFormula.realize_restrictFreeVar _
      · ext a
        rcases a with ⟨_ | _, _⟩ <;> 

Proof state:
case h.e'_1.h.e'_7.h.mk.inl
M : Type w
A : Set M
L : Language
inst✝ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
this✝ : DecidableEq M := Classical.decEq M
this : DecidableEq α := Classical.decEq α
φ : Formula L (↑A ⊕ α)
A0 : Finset M :=
  Finset.image Subtype.val
    (Finset.preimage (BoundedFormula.freeVarFinset φ) Sum.inl
      (_ : InjOn Sum.inl (Sum.inl ⁻¹' ↑(BoundedFormula.freeVarFinset φ))))
hA0 : ↑A0 ⊆ A
v : α → M
val✝ : ↑A
property✝ : Sum.inl val✝ ∈ fun x => x ∈ (BoundedFormula.freeVarFinset φ).val
⊢ (Sum.elim (Sum.elim Subtype.val v) (default ∘ Fin.castAdd 0) ∘ fun a =>
        Sum.rec (motive := fun x =>
          (x ∈ fun x => x ∈ (BoundedFormula.freeVarFinset φ).val) →
            (↑↑(Finset.image Subtype.val
                      (Finset.preimage (BoundedFormula.freeVarFinset φ) Sum.inl
                        (_ : InjOn Sum.inl (Sum.inl ⁻¹' ↑(BoundedFormula.freeVarFinset φ))))) ⊕
                α) ⊕
              Fin 0)
          (fun val ha => Sum.inl (Sum.inl { val := ↑val, property := (_ : ↑val ∈ ↑A0) }))
          (fun val ha => Sum.inl (Sum.inr val)) ↑a (_ : ↑a ∈ fun x => x ∈ (BoundedFormula.freeVarFinset φ).val))
      { val := Sum.inl val✝, property := property✝ } =
    (Sum.elim Subtype.val v ∘ Subtype.val) { val := Sum.inl val✝, property := property✝ }

Next tactic:
simp
theorem definable_iff_finitely_definable :
    A.Definable L s ↔ ∃ (A0 : Finset M), (A0 : Set M) ⊆ A ∧
      (A0 : Set M).Definable L s := by
  letI := Classical.decEq M
  letI := Classical.decEq α
  constructor
  · simp only [definable_iff_exists_formula_sum]
    rintro ⟨φ, rfl⟩
    let A0 := (φ.freeVarFinset.preimage Sum.inl
      (Function.Injective.injOn Sum.inl_injective _)).image Subtype.val
    have hA0 : (A0 : Set M) ⊆ A := by simp
    refine ⟨A0, hA0, (φ.restrictFreeVar
      (Set.inclusion (Set.Subset.refl _))).relabel ?_, ?_⟩
    · rintro ⟨a | a, ha⟩
      · exact Sum.inl (Sum.inl ⟨a, by simpa using ha⟩)
      · exact Sum.inl (Sum.inr a)
    · ext v
      simp only [Formula.Realize, BoundedFormula.realize_relabel,
        Set.mem_setOf_eq]
      apply Iff.symm
      convert BoundedFormula.realize_restrictFreeVar _
      · ext a
        rcases a with ⟨_ | _, _⟩ <;> 

Proof state:
case h.e'_1.h.e'_7.h.mk.inr
M : Type w
A : Set M
L : Language
inst✝ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
this✝ : DecidableEq M := Classical.decEq M
this : DecidableEq α := Classical.decEq α
φ : Formula L (↑A ⊕ α)
A0 : Finset M :=
  Finset.image Subtype.val
    (Finset.preimage (BoundedFormula.freeVarFinset φ) Sum.inl
      (_ : InjOn Sum.inl (Sum.inl ⁻¹' ↑(BoundedFormula.freeVarFinset φ))))
hA0 : ↑A0 ⊆ A
v : α → M
val✝ : α
property✝ : Sum.inr val✝ ∈ fun x => x ∈ (BoundedFormula.freeVarFinset φ).val
⊢ (Sum.elim (Sum.elim Subtype.val v) (default ∘ Fin.castAdd 0) ∘ fun a =>
        Sum.rec (motive := fun x =>
          (x ∈ fun x => x ∈ (BoundedFormula.freeVarFinset φ).val) →
            (↑↑(Finset.image Subtype.val
                      (Finset.preimage (BoundedFormula.freeVarFinset φ) Sum.inl
                        (_ : InjOn Sum.inl (Sum.inl ⁻¹' ↑(BoundedFormula.freeVarFinset φ))))) ⊕
                α) ⊕
              Fin 0)
          (fun val ha => Sum.inl (Sum.inl { val := ↑val, property := (_ : ↑val ∈ ↑A0) }))
          (fun val ha => Sum.inl (Sum.inr val)) ↑a (_ : ↑a ∈ fun x => x ∈ (BoundedFormula.freeVarFinset φ).val))
      { val := Sum.inr val✝, property := property✝ } =
    (Sum.elim Subtype.val v ∘ Subtype.val) { val := Sum.inr val✝, property := property✝ }

Next tactic:
simp
theorem definable_iff_finitely_definable :
    A.Definable L s ↔ ∃ (A0 : Finset M), (A0 : Set M) ⊆ A ∧
      (A0 : Set M).Definable L s := by
  letI := Classical.decEq M
  letI := Classical.decEq α
  constructor
  · simp only [definable_iff_exists_formula_sum]
    rintro ⟨φ, rfl⟩
    let A0 := (φ.freeVarFinset.preimage Sum.inl
      (Function.Injective.injOn Sum.inl_injective _)).image Subtype.val
    have hA0 : (A0 : Set M) ⊆ A := by simp
    refine ⟨A0, hA0, (φ.restrictFreeVar
      (Set.inclusion (Set.Subset.refl _))).relabel ?_, ?_⟩
    · rintro ⟨a | a, ha⟩
      · exact Sum.inl (Sum.inl ⟨a, by simpa using ha⟩)
      · exact Sum.inl (Sum.inr a)
    · ext v
      simp only [Formula.Realize, BoundedFormula.realize_relabel,
        Set.mem_setOf_eq]
      apply Iff.symm
      convert BoundedFormula.realize_restrictFreeVar _
      · ext a
        rcases a with ⟨_ | _, _⟩ <;> simp
  · 

Proof state:
case mpr
M : Type w
A : Set M
L : Language
inst✝ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
s : Set (α → M)
this✝ : DecidableEq M := Classical.decEq M
this : DecidableEq α := Classical.decEq α
⊢ (∃ A0, ↑A0 ⊆ A ∧ Definable (↑A0) L s) → Definable A L s

Next tactic:
rintro ⟨A0, hA0, hd⟩
theorem definable_iff_finitely_definable :
    A.Definable L s ↔ ∃ (A0 : Finset M), (A0 : Set M) ⊆ A ∧
      (A0 : Set M).Definable L s := by
  letI := Classical.decEq M
  letI := Classical.decEq α
  constructor
  · simp only [definable_iff_exists_formula_sum]
    rintro ⟨φ, rfl⟩
    let A0 := (φ.freeVarFinset.preimage Sum.inl
      (Function.Injective.injOn Sum.inl_injective _)).image Subtype.val
    have hA0 : (A0 : Set M) ⊆ A := by simp
    refine ⟨A0, hA0, (φ.restrictFreeVar
      (Set.inclusion (Set.Subset.refl _))).relabel ?_, ?_⟩
    · rintro ⟨a | a, ha⟩
      · exact Sum.inl (Sum.inl ⟨a, by simpa using ha⟩)
      · exact Sum.inl (Sum.inr a)
    · ext v
      simp only [Formula.Realize, BoundedFormula.realize_relabel,
        Set.mem_setOf_eq]
      apply Iff.symm
      convert BoundedFormula.realize_restrictFreeVar _
      · ext a
        rcases a with ⟨_ | _, _⟩ <;> simp
  · rintro ⟨A0, hA0, hd⟩
    

Proof state:
case mpr.intro.intro
M : Type w
A : Set M
L : Language
inst✝ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
s : Set (α → M)
this✝ : DecidableEq M := Classical.decEq M
this : DecidableEq α := Classical.decEq α
A0 : Finset M
hA0 : ↑A0 ⊆ A
hd : Definable (↑A0) L s
⊢ Definable A L s

Next tactic:
exact Definable.mono hd hA0
/-- This lemma is only intended as a helper for `Definable.image_comp`. -/
theorem Definable.image_comp_sum_inl_fin (m : ℕ) {s : Set (Sum α (Fin m) → M)}
    (h : A.Definable L s) : A.Definable L ((fun g : Sum α (Fin m) → M => g ∘ Sum.inl) '' s) := by
  

Proof state:
M : Type w
A : Set M
L : Language
inst✝ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
s✝ : Set (α → M)
m : ℕ
s : Set (α ⊕ Fin m → M)
h : Definable A L s
⊢ Definable A L ((fun g => g ∘ Sum.inl) '' s)

Next tactic:
obtain ⟨φ, rfl⟩ := h
/-- This lemma is only intended as a helper for `Definable.image_comp`. -/
theorem Definable.image_comp_sum_inl_fin (m : ℕ) {s : Set (Sum α (Fin m) → M)}
    (h : A.Definable L s) : A.Definable L ((fun g : Sum α (Fin m) → M => g ∘ Sum.inl) '' s) := by
  obtain ⟨φ, rfl⟩ := h
  

Proof state:
case intro
M : Type w
A : Set M
L : Language
inst✝ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
s : Set (α → M)
m : ℕ
φ : Formula (L[[↑A]]) (α ⊕ Fin m)
⊢ Definable A L ((fun g => g ∘ Sum.inl) '' setOf (Formula.Realize φ))

Next tactic:
refine' ⟨(BoundedFormula.relabel id φ).exs, _⟩
/-- This lemma is only intended as a helper for `Definable.image_comp`. -/
theorem Definable.image_comp_sum_inl_fin (m : ℕ) {s : Set (Sum α (Fin m) → M)}
    (h : A.Definable L s) : A.Definable L ((fun g : Sum α (Fin m) → M => g ∘ Sum.inl) '' s) := by
  obtain ⟨φ, rfl⟩ := h
  refine' ⟨(BoundedFormula.relabel id φ).exs, _⟩
  

Proof state:
case intro
M : Type w
A : Set M
L : Language
inst✝ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
s : Set (α → M)
m : ℕ
φ : Formula (L[[↑A]]) (α ⊕ Fin m)
⊢ (fun g => g ∘ Sum.inl) '' setOf (Formula.Realize φ) =
    setOf (Formula.Realize (BoundedFormula.exs (BoundedFormula.relabel id φ)))

Next tactic:
ext x
/-- This lemma is only intended as a helper for `Definable.image_comp`. -/
theorem Definable.image_comp_sum_inl_fin (m : ℕ) {s : Set (Sum α (Fin m) → M)}
    (h : A.Definable L s) : A.Definable L ((fun g : Sum α (Fin m) → M => g ∘ Sum.inl) '' s) := by
  obtain ⟨φ, rfl⟩ := h
  refine' ⟨(BoundedFormula.relabel id φ).exs, _⟩
  ext x
  

Proof state:
case intro.h
M : Type w
A : Set M
L : Language
inst✝ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
s : Set (α → M)
m : ℕ
φ : Formula (L[[↑A]]) (α ⊕ Fin m)
x : α → M
⊢ x ∈ (fun g => g ∘ Sum.inl) '' setOf (Formula.Realize φ) ↔
    x ∈ setOf (Formula.Realize (BoundedFormula.exs (BoundedFormula.relabel id φ)))

Next tactic:
simp only [Set.mem_image, mem_setOf_eq, BoundedFormula.realize_exs,
    BoundedFormula.realize_relabel, Function.comp.right_id, Fin.castAdd_zero, Fin.cast_refl]
/-- This lemma is only intended as a helper for `Definable.image_comp`. -/
theorem Definable.image_comp_sum_inl_fin (m : ℕ) {s : Set (Sum α (Fin m) → M)}
    (h : A.Definable L s) : A.Definable L ((fun g : Sum α (Fin m) → M => g ∘ Sum.inl) '' s) := by
  obtain ⟨φ, rfl⟩ := h
  refine' ⟨(BoundedFormula.relabel id φ).exs, _⟩
  ext x
  simp only [Set.mem_image, mem_setOf_eq, BoundedFormula.realize_exs,
    BoundedFormula.realize_relabel, Function.comp.right_id, Fin.castAdd_zero, Fin.cast_refl]
  

Proof state:
case intro.h
M : Type w
A : Set M
L : Language
inst✝ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
s : Set (α → M)
m : ℕ
φ : Formula (L[[↑A]]) (α ⊕ Fin m)
x : α → M
⊢ (∃ x_1, Formula.Realize φ x_1 ∧ x_1 ∘ Sum.inl = x) ↔
    ∃ xs, BoundedFormula.Realize φ (Sum.elim x xs) (xs ∘ Fin.natAdd m)

Next tactic:
constructor
/-- This lemma is only intended as a helper for `Definable.image_comp`. -/
theorem Definable.image_comp_sum_inl_fin (m : ℕ) {s : Set (Sum α (Fin m) → M)}
    (h : A.Definable L s) : A.Definable L ((fun g : Sum α (Fin m) → M => g ∘ Sum.inl) '' s) := by
  obtain ⟨φ, rfl⟩ := h
  refine' ⟨(BoundedFormula.relabel id φ).exs, _⟩
  ext x
  simp only [Set.mem_image, mem_setOf_eq, BoundedFormula.realize_exs,
    BoundedFormula.realize_relabel, Function.comp.right_id, Fin.castAdd_zero, Fin.cast_refl]
  constructor
  · 

Proof state:
case intro.h.mp
M : Type w
A : Set M
L : Language
inst✝ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
s : Set (α → M)
m : ℕ
φ : Formula (L[[↑A]]) (α ⊕ Fin m)
x : α → M
⊢ (∃ x_1, Formula.Realize φ x_1 ∧ x_1 ∘ Sum.inl = x) →
    ∃ xs, BoundedFormula.Realize φ (Sum.elim x xs) (xs ∘ Fin.natAdd m)

Next tactic:
rintro ⟨y, hy, rfl⟩
/-- This lemma is only intended as a helper for `Definable.image_comp`. -/
theorem Definable.image_comp_sum_inl_fin (m : ℕ) {s : Set (Sum α (Fin m) → M)}
    (h : A.Definable L s) : A.Definable L ((fun g : Sum α (Fin m) → M => g ∘ Sum.inl) '' s) := by
  obtain ⟨φ, rfl⟩ := h
  refine' ⟨(BoundedFormula.relabel id φ).exs, _⟩
  ext x
  simp only [Set.mem_image, mem_setOf_eq, BoundedFormula.realize_exs,
    BoundedFormula.realize_relabel, Function.comp.right_id, Fin.castAdd_zero, Fin.cast_refl]
  constructor
  · rintro ⟨y, hy, rfl⟩
    

Proof state:
case intro.h.mp.intro.intro
M : Type w
A : Set M
L : Language
inst✝ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
s : Set (α → M)
m : ℕ
φ : Formula (L[[↑A]]) (α ⊕ Fin m)
y : α ⊕ Fin m → M
hy : Formula.Realize φ y
⊢ ∃ xs, BoundedFormula.Realize φ (Sum.elim (y ∘ Sum.inl) xs) (xs ∘ Fin.natAdd m)

Next tactic:
exact
      ⟨y ∘ Sum.inr, (congr (congr rfl (Sum.elim_comp_inl_inr y).symm) (funext finZeroElim)).mp hy⟩
/-- This lemma is only intended as a helper for `Definable.image_comp`. -/
theorem Definable.image_comp_sum_inl_fin (m : ℕ) {s : Set (Sum α (Fin m) → M)}
    (h : A.Definable L s) : A.Definable L ((fun g : Sum α (Fin m) → M => g ∘ Sum.inl) '' s) := by
  obtain ⟨φ, rfl⟩ := h
  refine' ⟨(BoundedFormula.relabel id φ).exs, _⟩
  ext x
  simp only [Set.mem_image, mem_setOf_eq, BoundedFormula.realize_exs,
    BoundedFormula.realize_relabel, Function.comp.right_id, Fin.castAdd_zero, Fin.cast_refl]
  constructor
  · rintro ⟨y, hy, rfl⟩
    exact
      ⟨y ∘ Sum.inr, (congr (congr rfl (Sum.elim_comp_inl_inr y).symm) (funext finZeroElim)).mp hy⟩
  · 

Proof state:
case intro.h.mpr
M : Type w
A : Set M
L : Language
inst✝ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
s : Set (α → M)
m : ℕ
φ : Formula (L[[↑A]]) (α ⊕ Fin m)
x : α → M
⊢ (∃ xs, BoundedFormula.Realize φ (Sum.elim x xs) (xs ∘ Fin.natAdd m)) →
    ∃ x_1, Formula.Realize φ x_1 ∧ x_1 ∘ Sum.inl = x

Next tactic:
rintro ⟨y, hy⟩
/-- This lemma is only intended as a helper for `Definable.image_comp`. -/
theorem Definable.image_comp_sum_inl_fin (m : ℕ) {s : Set (Sum α (Fin m) → M)}
    (h : A.Definable L s) : A.Definable L ((fun g : Sum α (Fin m) → M => g ∘ Sum.inl) '' s) := by
  obtain ⟨φ, rfl⟩ := h
  refine' ⟨(BoundedFormula.relabel id φ).exs, _⟩
  ext x
  simp only [Set.mem_image, mem_setOf_eq, BoundedFormula.realize_exs,
    BoundedFormula.realize_relabel, Function.comp.right_id, Fin.castAdd_zero, Fin.cast_refl]
  constructor
  · rintro ⟨y, hy, rfl⟩
    exact
      ⟨y ∘ Sum.inr, (congr (congr rfl (Sum.elim_comp_inl_inr y).symm) (funext finZeroElim)).mp hy⟩
  · rintro ⟨y, hy⟩
    

Proof state:
case intro.h.mpr.intro
M : Type w
A : Set M
L : Language
inst✝ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
s : Set (α → M)
m : ℕ
φ : Formula (L[[↑A]]) (α ⊕ Fin m)
x : α → M
y : Fin (m + 0) → M
hy : BoundedFormula.Realize φ (Sum.elim x y) (y ∘ Fin.natAdd m)
⊢ ∃ x_1, Formula.Realize φ x_1 ∧ x_1 ∘ Sum.inl = x

Next tactic:
exact ⟨Sum.elim x y, (congr rfl (funext finZeroElim)).mp hy, Sum.elim_comp_inl _ _⟩
/-- Shows that definability is closed under finite projections. -/
theorem Definable.image_comp_embedding {s : Set (β → M)} (h : A.Definable L s) (f : α ↪ β)
    [Finite β] : A.Definable L ((fun g : β → M => g ∘ f) '' s) := by
  

Proof state:
M : Type w
A : Set M
L : Language
inst✝¹ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
s✝ : Set (α → M)
s : Set (β → M)
h : Definable A L s
f : α ↪ β
inst✝ : Finite β
⊢ Definable A L ((fun g => g ∘ ⇑f) '' s)

Next tactic:
classical
    cases nonempty_fintype β
    refine'
      (congr rfl (ext fun x => _)).mp
        (((h.image_comp_equiv (Equiv.Set.sumCompl (range f))).image_comp_equiv
              (Equiv.sumCongr (Equiv.ofInjective f f.injective)
                (Fintype.equivFin (↥(range f)ᶜ)).symm)).image_comp_sum_inl_fin
          _)
    simp only [mem_preimage, mem_image, exists_exists_and_eq_and]
    refine' exists_congr fun y => and_congr_right fun _ => Eq.congr_left (funext fun a => _)
    simp
/-- Shows that definability is closed under finite projections. -/
theorem Definable.image_comp_embedding {s : Set (β → M)} (h : A.Definable L s) (f : α ↪ β)
    [Finite β] : A.Definable L ((fun g : β → M => g ∘ f) '' s) := by
  classical
    

Proof state:
M : Type w
A : Set M
L : Language
inst✝¹ : Structure L M
α : Type u₁
β : Type u_1
B : Set M
s✝ : Set (α → M)
s : Set (β → M)
h : Definable A L s
f : α ↪ β
inst✝ : Finite β
⊢ Definable A L ((fun g => g ∘ ⇑f) '' s)

Next tactic:
cases nonempty_fintype β