Skip to content

Commit

Permalink
chore(ModelTheory/ElementarySubstructures): Split elementary substruc…
Browse files Browse the repository at this point in the history
…tures into their own file (#9026)

This PR splits the file `ModelTheory/ElementaryMaps` into two files, moving elementary substructure code into `ModelTheory/ElementarySubstructures`, to make room for new API on those.

Two basic lemmas, `FirstOrder.Language.Substructure.realize_boundedFormula_top` and `FirstOrder.Language.Substructure.realize_formula_top`, are instead moved to the file `ModelTheory/Substructures`.



Co-authored-by: Yaël Dillies <yael.dillies@gmail.com>
Co-authored-by: Aaron Anderson <65780815+awainverse@users.noreply.github.com>
  • Loading branch information
3 people committed Dec 16, 2023
1 parent a45fd77 commit a5732e8
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 148 deletions.
1 change: 1 addition & 0 deletions Mathlib.lean
Expand Up @@ -2685,6 +2685,7 @@ import Mathlib.ModelTheory.Bundled
import Mathlib.ModelTheory.Definability
import Mathlib.ModelTheory.DirectLimit
import Mathlib.ModelTheory.ElementaryMaps
import Mathlib.ModelTheory.ElementarySubstructures
import Mathlib.ModelTheory.Encoding
import Mathlib.ModelTheory.FinitelyGenerated
import Mathlib.ModelTheory.Fraisse
Expand Down
2 changes: 1 addition & 1 deletion Mathlib/ModelTheory/Bundled.lean
Expand Up @@ -3,7 +3,7 @@ Copyright (c) 2022 Aaron Anderson. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Aaron Anderson
-/
import Mathlib.ModelTheory.ElementaryMaps
import Mathlib.ModelTheory.ElementarySubstructures
import Mathlib.CategoryTheory.ConcreteCategory.Bundled

#align_import model_theory.bundled from "leanprover-community/mathlib"@"b3951c65c6e797ff162ae8b69eab0063bcfb3d73"
Expand Down
146 changes: 0 additions & 146 deletions Mathlib/ModelTheory/ElementaryMaps.lean
Expand Up @@ -14,8 +14,6 @@ import Mathlib.ModelTheory.Substructures
## Main Definitions
* A `FirstOrder.Language.ElementaryEmbedding` is an embedding that commutes with the
realizations of formulas.
* A `FirstOrder.Language.ElementarySubstructure` is a substructure where the realization of each
formula agrees with the realization in the larger model.
* The `FirstOrder.Language.elementaryDiagram` of a structure is the set of all sentences with
parameters that the structure satisfies.
* `FirstOrder.Language.ElementaryEmbedding.ofModelsElementaryDiagram` is the canonical
Expand All @@ -24,9 +22,6 @@ elementary embedding of any structure into a model of its elementary diagram.
## Main Results
* The Tarski-Vaught Test for embeddings: `FirstOrder.Language.Embedding.isElementary_of_exists`
gives a simple criterion for an embedding to be elementary.
* The Tarski-Vaught Test for substructures:
`FirstOrder.Language.Substructure.isElementary_of_exists` gives a simple criterion for a
substructure to be elementary.
-/


Expand Down Expand Up @@ -351,147 +346,6 @@ theorem realize_term_substructure {α : Type*} {S : L.Substructure M} (v : α
S.subtype.realize_term t
#align first_order.language.realize_term_substructure FirstOrder.Language.realize_term_substructure

namespace Substructure

@[simp]
theorem realize_boundedFormula_top {α : Type*} {n : ℕ} {φ : L.BoundedFormula α n}
{v : α → (⊤ : L.Substructure M)} {xs : Fin n → (⊤ : L.Substructure M)} :
φ.Realize v xs ↔ φ.Realize (((↑) : _ → M) ∘ v) ((↑) ∘ xs) := by
rw [← Substructure.topEquiv.realize_boundedFormula φ]
simp
#align first_order.language.substructure.realize_bounded_formula_top FirstOrder.Language.Substructure.realize_boundedFormula_top

@[simp]
theorem realize_formula_top {α : Type*} {φ : L.Formula α} {v : α → (⊤ : L.Substructure M)} :
φ.Realize v ↔ φ.Realize (((↑) : (⊤ : L.Substructure M) → M) ∘ v) := by
rw [← Substructure.topEquiv.realize_formula φ]
simp
#align first_order.language.substructure.realize_formula_top FirstOrder.Language.Substructure.realize_formula_top

/-- A substructure is elementary when every formula applied to a tuple in the subtructure
agrees with its value in the overall structure. -/
def IsElementary (S : L.Substructure M) : Prop :=
∀ ⦃n⦄ (φ : L.Formula (Fin n)) (x : Fin n → S), φ.Realize (((↑) : _ → M) ∘ x) ↔ φ.Realize x
#align first_order.language.substructure.is_elementary FirstOrder.Language.Substructure.IsElementary

end Substructure

variable (L M)

/-- An elementary substructure is one in which every formula applied to a tuple in the subtructure
agrees with its value in the overall structure. -/
structure ElementarySubstructure where
toSubstructure : L.Substructure M
isElementary' : toSubstructure.IsElementary
#align first_order.language.elementary_substructure FirstOrder.Language.ElementarySubstructure
#align first_order.language.elementary_substructure.to_substructure FirstOrder.Language.ElementarySubstructure.toSubstructure
#align first_order.language.elementary_substructure.is_elementary' FirstOrder.Language.ElementarySubstructure.isElementary'

variable {L M}

namespace ElementarySubstructure

attribute [coe] toSubstructure

instance instCoe : Coe (L.ElementarySubstructure M) (L.Substructure M) :=
⟨ElementarySubstructure.toSubstructure⟩
#align first_order.language.elementary_substructure.first_order.language.substructure.has_coe FirstOrder.Language.ElementarySubstructure.instCoe

instance instSetLike : SetLike (L.ElementarySubstructure M) M :=
fun x => x.toSubstructure.carrier, fun ⟨⟨s, hs1⟩, hs2⟩ ⟨⟨t, ht1⟩, _⟩ _ => by
congr⟩
#align first_order.language.elementary_substructure.set_like FirstOrder.Language.ElementarySubstructure.instSetLike

instance inducedStructure (S : L.ElementarySubstructure M) : L.Structure S :=
Substructure.inducedStructure
set_option linter.uppercaseLean3 false in
#align first_order.language.elementary_substructure.induced_Structure FirstOrder.Language.ElementarySubstructure.inducedStructure

@[simp]
theorem isElementary (S : L.ElementarySubstructure M) : (S : L.Substructure M).IsElementary :=
S.isElementary'
#align first_order.language.elementary_substructure.is_elementary FirstOrder.Language.ElementarySubstructure.isElementary

/-- The natural embedding of an `L.Substructure` of `M` into `M`. -/
def subtype (S : L.ElementarySubstructure M) : S ↪ₑ[L] M where
toFun := (↑)
map_formula' := S.isElementary
#align first_order.language.elementary_substructure.subtype FirstOrder.Language.ElementarySubstructure.subtype

@[simp]
theorem coeSubtype {S : L.ElementarySubstructure M} : ⇑S.subtype = ((↑) : S → M) :=
rfl
#align first_order.language.elementary_substructure.coe_subtype FirstOrder.Language.ElementarySubstructure.coeSubtype

/-- The substructure `M` of the structure `M` is elementary. -/
instance instTop : Top (L.ElementarySubstructure M) :=
⟨⟨⊤, fun _ _ _ => Substructure.realize_formula_top.symm⟩⟩
#align first_order.language.elementary_substructure.has_top FirstOrder.Language.ElementarySubstructure.instTop

instance instInhabited : Inhabited (L.ElementarySubstructure M) :=
⟨⊤⟩
#align first_order.language.elementary_substructure.inhabited FirstOrder.Language.ElementarySubstructure.instInhabited

@[simp]
theorem mem_top (x : M) : x ∈ (⊤ : L.ElementarySubstructure M) :=
Set.mem_univ x
#align first_order.language.elementary_substructure.mem_top FirstOrder.Language.ElementarySubstructure.mem_top

@[simp]
theorem coe_top : ((⊤ : L.ElementarySubstructure M) : Set M) = Set.univ :=
rfl
#align first_order.language.elementary_substructure.coe_top FirstOrder.Language.ElementarySubstructure.coe_top

@[simp]
theorem realize_sentence (S : L.ElementarySubstructure M) (φ : L.Sentence) : S ⊨ φ ↔ M ⊨ φ :=
S.subtype.map_sentence φ
#align first_order.language.elementary_substructure.realize_sentence FirstOrder.Language.ElementarySubstructure.realize_sentence

@[simp]
theorem theory_model_iff (S : L.ElementarySubstructure M) (T : L.Theory) : S ⊨ T ↔ M ⊨ T := by
simp only [Theory.model_iff, realize_sentence]
set_option linter.uppercaseLean3 false in
#align first_order.language.elementary_substructure.Theory_model_iff FirstOrder.Language.ElementarySubstructure.theory_model_iff

instance theory_model {T : L.Theory} [h : M ⊨ T] {S : L.ElementarySubstructure M} : S ⊨ T :=
(theory_model_iff S T).2 h
set_option linter.uppercaseLean3 false in
#align first_order.language.elementary_substructure.Theory_model FirstOrder.Language.ElementarySubstructure.theory_model

instance instNonempty [Nonempty M] {S : L.ElementarySubstructure M} : Nonempty S :=
(model_nonemptyTheory_iff L).1 inferInstance
#align first_order.language.elementary_substructure.nonempty FirstOrder.Language.ElementarySubstructure.instNonempty

theorem elementarilyEquivalent (S : L.ElementarySubstructure M) : S ≅[L] M :=
S.subtype.elementarilyEquivalent
#align first_order.language.elementary_substructure.elementarily_equivalent FirstOrder.Language.ElementarySubstructure.elementarilyEquivalent

end ElementarySubstructure

namespace Substructure

/-- The Tarski-Vaught test for elementarity of a substructure. -/
theorem isElementary_of_exists (S : L.Substructure M)
(htv :
∀ (n : ℕ) (φ : L.BoundedFormula Empty (n + 1)) (x : Fin n → S) (a : M),
φ.Realize default (Fin.snoc ((↑) ∘ x) a : _ → M) →
∃ b : S, φ.Realize default (Fin.snoc ((↑) ∘ x) b : _ → M)) :
S.IsElementary := fun _ => S.subtype.isElementary_of_exists htv
#align first_order.language.substructure.is_elementary_of_exists FirstOrder.Language.Substructure.isElementary_of_exists

/-- Bundles a substructure satisfying the Tarski-Vaught test as an elementary substructure. -/
@[simps]
def toElementarySubstructure (S : L.Substructure M)
(htv :
∀ (n : ℕ) (φ : L.BoundedFormula Empty (n + 1)) (x : Fin n → S) (a : M),
φ.Realize default (Fin.snoc ((↑) ∘ x) a : _ → M) →
∃ b : S, φ.Realize default (Fin.snoc ((↑) ∘ x) b : _ → M)) :
L.ElementarySubstructure M :=
⟨S, S.isElementary_of_exists htv⟩
#align first_order.language.substructure.to_elementary_substructure FirstOrder.Language.Substructure.toElementarySubstructure

end Substructure

end Language

end FirstOrder
158 changes: 158 additions & 0 deletions Mathlib/ModelTheory/ElementarySubstructures.lean
@@ -0,0 +1,158 @@
/-
Copyright (c) 2022 Aaron Anderson. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Aaron Anderson
-/
import Mathlib.ModelTheory.ElementaryMaps

/-!
# Elementary Substructures
## Main Definitions
* A `FirstOrder.Language.ElementarySubstructure` is a substructure where the realization of each
formula agrees with the realization in the larger model.
## Main Results
* The Tarski-Vaught Test for substructures:
`FirstOrder.Language.Substructure.isElementary_of_exists` gives a simple criterion for a
substructure to be elementary.
-/


open FirstOrder

namespace FirstOrder

namespace Language

open Structure

variable {L : Language} {M : Type*} {N : Type*} {P : Type*} {Q : Type*}

variable [L.Structure M] [L.Structure N] [L.Structure P] [L.Structure Q]

/-- A substructure is elementary when every formula applied to a tuple in the subtructure
agrees with its value in the overall structure. -/
def Substructure.IsElementary (S : L.Substructure M) : Prop :=
∀ ⦃n⦄ (φ : L.Formula (Fin n)) (x : Fin n → S), φ.Realize (((↑) : _ → M) ∘ x) ↔ φ.Realize x
#align first_order.language.substructure.is_elementary FirstOrder.Language.Substructure.IsElementary

variable (L M)

/-- An elementary substructure is one in which every formula applied to a tuple in the subtructure
agrees with its value in the overall structure. -/
structure ElementarySubstructure where
toSubstructure : L.Substructure M
isElementary' : toSubstructure.IsElementary
#align first_order.language.elementary_substructure FirstOrder.Language.ElementarySubstructure
#align first_order.language.elementary_substructure.to_substructure FirstOrder.Language.ElementarySubstructure.toSubstructure
#align first_order.language.elementary_substructure.is_elementary' FirstOrder.Language.ElementarySubstructure.isElementary'

variable {L M}

namespace ElementarySubstructure

attribute [coe] toSubstructure

instance instCoe : Coe (L.ElementarySubstructure M) (L.Substructure M) :=
⟨ElementarySubstructure.toSubstructure⟩
#align first_order.language.elementary_substructure.first_order.language.substructure.has_coe FirstOrder.Language.ElementarySubstructure.instCoe

instance instSetLike : SetLike (L.ElementarySubstructure M) M :=
fun x => x.toSubstructure.carrier, fun ⟨⟨s, hs1⟩, hs2⟩ ⟨⟨t, ht1⟩, _⟩ _ => by
congr⟩
#align first_order.language.elementary_substructure.set_like FirstOrder.Language.ElementarySubstructure.instSetLike

instance inducedStructure (S : L.ElementarySubstructure M) : L.Structure S :=
Substructure.inducedStructure
set_option linter.uppercaseLean3 false in
#align first_order.language.elementary_substructure.induced_Structure FirstOrder.Language.ElementarySubstructure.inducedStructure

@[simp]
theorem isElementary (S : L.ElementarySubstructure M) : (S : L.Substructure M).IsElementary :=
S.isElementary'
#align first_order.language.elementary_substructure.is_elementary FirstOrder.Language.ElementarySubstructure.isElementary

/-- The natural embedding of an `L.Substructure` of `M` into `M`. -/
def subtype (S : L.ElementarySubstructure M) : S ↪ₑ[L] M where
toFun := (↑)
map_formula' := S.isElementary
#align first_order.language.elementary_substructure.subtype FirstOrder.Language.ElementarySubstructure.subtype

@[simp]
theorem coeSubtype {S : L.ElementarySubstructure M} : ⇑S.subtype = ((↑) : S → M) :=
rfl
#align first_order.language.elementary_substructure.coe_subtype FirstOrder.Language.ElementarySubstructure.coeSubtype

/-- The substructure `M` of the structure `M` is elementary. -/
instance instTop : Top (L.ElementarySubstructure M) :=
⟨⟨⊤, fun _ _ _ => Substructure.realize_formula_top.symm⟩⟩
#align first_order.language.elementary_substructure.has_top FirstOrder.Language.ElementarySubstructure.instTop

instance instInhabited : Inhabited (L.ElementarySubstructure M) :=
⟨⊤⟩
#align first_order.language.elementary_substructure.inhabited FirstOrder.Language.ElementarySubstructure.instInhabited

@[simp]
theorem mem_top (x : M) : x ∈ (⊤ : L.ElementarySubstructure M) :=
Set.mem_univ x
#align first_order.language.elementary_substructure.mem_top FirstOrder.Language.ElementarySubstructure.mem_top

@[simp]
theorem coe_top : ((⊤ : L.ElementarySubstructure M) : Set M) = Set.univ :=
rfl
#align first_order.language.elementary_substructure.coe_top FirstOrder.Language.ElementarySubstructure.coe_top

@[simp]
theorem realize_sentence (S : L.ElementarySubstructure M) (φ : L.Sentence) : S ⊨ φ ↔ M ⊨ φ :=
S.subtype.map_sentence φ
#align first_order.language.elementary_substructure.realize_sentence FirstOrder.Language.ElementarySubstructure.realize_sentence

@[simp]
theorem theory_model_iff (S : L.ElementarySubstructure M) (T : L.Theory) : S ⊨ T ↔ M ⊨ T := by
simp only [Theory.model_iff, realize_sentence]
set_option linter.uppercaseLean3 false in
#align first_order.language.elementary_substructure.Theory_model_iff FirstOrder.Language.ElementarySubstructure.theory_model_iff

instance theory_model {T : L.Theory} [h : M ⊨ T] {S : L.ElementarySubstructure M} : S ⊨ T :=
(theory_model_iff S T).2 h
set_option linter.uppercaseLean3 false in
#align first_order.language.elementary_substructure.Theory_model FirstOrder.Language.ElementarySubstructure.theory_model

instance instNonempty [Nonempty M] {S : L.ElementarySubstructure M} : Nonempty S :=
(model_nonemptyTheory_iff L).1 inferInstance
#align first_order.language.elementary_substructure.nonempty FirstOrder.Language.ElementarySubstructure.instNonempty

theorem elementarilyEquivalent (S : L.ElementarySubstructure M) : S ≅[L] M :=
S.subtype.elementarilyEquivalent
#align first_order.language.elementary_substructure.elementarily_equivalent FirstOrder.Language.ElementarySubstructure.elementarilyEquivalent

end ElementarySubstructure

namespace Substructure

/-- The Tarski-Vaught test for elementarity of a substructure. -/
theorem isElementary_of_exists (S : L.Substructure M)
(htv :
∀ (n : ℕ) (φ : L.BoundedFormula Empty (n + 1)) (x : Fin n → S) (a : M),
φ.Realize default (Fin.snoc ((↑) ∘ x) a : _ → M) →
∃ b : S, φ.Realize default (Fin.snoc ((↑) ∘ x) b : _ → M)) :
S.IsElementary := fun _ => S.subtype.isElementary_of_exists htv
#align first_order.language.substructure.is_elementary_of_exists FirstOrder.Language.Substructure.isElementary_of_exists

/-- Bundles a substructure satisfying the Tarski-Vaught test as an elementary substructure. -/
@[simps]
def toElementarySubstructure (S : L.Substructure M)
(htv :
∀ (n : ℕ) (φ : L.BoundedFormula Empty (n + 1)) (x : Fin n → S) (a : M),
φ.Realize default (Fin.snoc ((↑) ∘ x) a : _ → M) →
∃ b : S, φ.Realize default (Fin.snoc ((↑) ∘ x) b : _ → M)) :
L.ElementarySubstructure M :=
⟨S, S.isElementary_of_exists htv⟩
#align first_order.language.substructure.to_elementary_substructure FirstOrder.Language.Substructure.toElementarySubstructure

end Substructure

end Language

end FirstOrder
2 changes: 1 addition & 1 deletion Mathlib/ModelTheory/Skolem.lean
Expand Up @@ -3,7 +3,7 @@ Copyright (c) 2022 Aaron Anderson. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Aaron Anderson
-/
import Mathlib.ModelTheory.ElementaryMaps
import Mathlib.ModelTheory.ElementarySubstructures

#align_import model_theory.skolem from "leanprover-community/mathlib"@"3d7987cda72abc473c7cdbbb075170e9ac620042"

Expand Down
15 changes: 15 additions & 0 deletions Mathlib/ModelTheory/Substructures.lean
Expand Up @@ -685,6 +685,21 @@ theorem coe_topEquiv :
rfl
#align first_order.language.substructure.coe_top_equiv FirstOrder.Language.Substructure.coe_topEquiv

@[simp]
theorem realize_boundedFormula_top {α : Type*} {n : ℕ} {φ : L.BoundedFormula α n}
{v : α → (⊤ : L.Substructure M)} {xs : Fin n → (⊤ : L.Substructure M)} :
φ.Realize v xs ↔ φ.Realize (((↑) : _ → M) ∘ v) ((↑) ∘ xs) := by
rw [← Substructure.topEquiv.realize_boundedFormula φ]
simp
#align first_order.language.substructure.realize_bounded_formula_top FirstOrder.Language.Substructure.realize_boundedFormula_top

@[simp]
theorem realize_formula_top {α : Type*} {φ : L.Formula α} {v : α → (⊤ : L.Substructure M)} :
φ.Realize v ↔ φ.Realize (((↑) : (⊤ : L.Substructure M) → M) ∘ v) := by
rw [← Substructure.topEquiv.realize_formula φ]
simp
#align first_order.language.substructure.realize_formula_top FirstOrder.Language.Substructure.realize_formula_top

/-- A dependent version of `Substructure.closure_induction`. -/
@[elab_as_elim]
theorem closure_induction' (s : Set M) {p : ∀ x, x ∈ closure L s → Prop}
Expand Down

0 comments on commit a5732e8

Please sign in to comment.