Skip to content

feat(ModelTheory): construct a counterexample to the two-cardinal phenomenon - #42190

Draft
NoneMore wants to merge 11 commits into
leanprover-community:masterfrom
NoneMore:definably-full
Draft

feat(ModelTheory): construct a counterexample to the two-cardinal phenomenon#42190
NoneMore wants to merge 11 commits into
leanprover-community:masterfrom
NoneMore:definably-full

Conversation

@NoneMore

Copy link
Copy Markdown
Contributor

Show the existence of a model of a complete theory with infinite models in a countable language where every infinite definable set has the same cardinality of the model itself for every infinite cardinality, which is a counterexample to the two-cardinal phenomenon.


This result is an ingredient in the proof of Morley’s categoricity theorem. Let $T$ be a complete theory in a countable language with an infinite model, and let $\kappa$ be uncountable. If $T$ is $\omega$-stable and has a Vaughtian pair, the pair can be transferred to a $(\kappa, \aleph_0)$-model of $T$: a model of cardinality $\kappa$ containing a countably infinite definable set. Such a model cannot be isomorphic to the model constructed in this PR, since cardinalities of definable sets are preserved by isomorphisms. Thus, an $\omega$-stable $\kappa$-categorical theory has no Vaughtian pairs. Together with the converse and the fact that neither implication depends on the particular uncountable cardinal $κ$, this yields the categoricity transfer in Morley’s theorem.

The present proof still exposes some foundational infrastructure and auxiliary lemmas that should likely be extracted and developed separately. This PR will remain a draft until this supporting work has been fully implemented.

AI disclosure: Most declarations, comments, and documentation in this PR were generated with Codex. Some proofs were structurally simplified using the /golf command from Lean 4 Skills. I reviewed the resulting code and documentation and can vouch for all submitted content.

Open in Gitpod

@github-actions github-actions Bot added the large-import Automatically added label for PRs with a significant increase in transitive imports label Jul 28, 2026
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown

PR summary e3821a10c3

Import changes exceeding 2%

% File
+7.27% Mathlib.ModelTheory.Semantics

Import changes for modified files

Dependency changes

File Base Count Head Count Change
Mathlib.ModelTheory.Semantics 715 767 +52 (+7.27%)
Mathlib.ModelTheory.ElementaryMaps 799 814 +15 (+1.88%)
Import changes for all files
Files Import difference
Mathlib.ModelTheory.Fraisse Mathlib.ModelTheory.Order 9
Mathlib.ModelTheory.Algebra.Field.CharP 12
14 files Mathlib.ModelTheory.Bundled Mathlib.ModelTheory.Complexity Mathlib.ModelTheory.DirectLimit Mathlib.ModelTheory.ElementaryMaps Mathlib.ModelTheory.ElementarySubstructures Mathlib.ModelTheory.Equivalence Mathlib.ModelTheory.FinitelyGenerated Mathlib.ModelTheory.Graph Mathlib.ModelTheory.PartialEquiv Mathlib.ModelTheory.Satisfiability Mathlib.ModelTheory.Skolem Mathlib.ModelTheory.Substructures Mathlib.ModelTheory.Topology.Types Mathlib.ModelTheory.Types
15
Mathlib.ModelTheory.Algebra.Ring.FreeCommRing 16
Mathlib.ModelTheory.Algebra.Field.Basic 28
Mathlib.ModelTheory.Ultraproducts 49
Mathlib.ModelTheory.Algebra.Ring.Basic Mathlib.ModelTheory.Arithmetic.Presburger.Basic 50
3 files Mathlib.ModelTheory.Definability Mathlib.ModelTheory.Quotients Mathlib.ModelTheory.Semantics
52
Mathlib.SetTheory.Cardinal.DirectLimit (new file) 777
Mathlib.ModelTheory.ElementaryChain (new file) 824
Mathlib.ModelTheory.DefinablyFull (new file) 862

Declarations diff (regex)

+ DefinablyFull
+ ElementaryChain
+ Limit
+ UnaryDefinablyFull
+ card_le
+ coe_natLERec
+ definablyFull_of_unary
+ encard_realizations_eq_coe_iff
+ equivOfForallLE
+ exists_elementaryExtension_card_eq_with_full_unary_realizations
+ exists_finite_common_stage
+ exists_model_of_card_definably_full
+ exists_toLimit
+ finOneRealizationsEquiv
+ iExsAtLeast
+ iExsAtMost
+ iExsExactly
+ iSup_lift_mk_le_mk
+ infinite_realizations_iff
+ le_encard_iff_exists_injection_fin
+ lhomWithConstantsMap_isExpansionOn_of_eq
+ liftElementary
+ limitEquiv
+ limit_models
+ mk_eq_iSup_lift_mk
+ mk_eq_of_forall_lift_mk_eq
+ mk_le_of_aleph0_le
+ mk_le_sum
+ mk_limit_eq_of_forall_lift_mk_eq
+ mk_limit_le_of_lift_mk_le
+ mk_realizations_le
+ natLERec
+ natLERec_self
+ natLERec_succ
+ natLERec_trans
+ ofNatSucc
+ ofNatSucc_map_succ
+ realizationsEmbedding
+ realize_iExsAtLeast
+ realize_iExsAtLeast_iff_exists_injective
+ realize_iExsAtMost
+ realize_iExsAtMost_iff_not_exists_injection
+ realize_iExsAtMost_iff_not_iExsAtLeast_succ
+ realize_iExsExactly
+ realize_iExsExactly_one_iff_iExsUnique
+ realize_iExsExactly_zero
+ realize_toLimit
+ toEmbeddingDirectedSystem
+ toLimit
+ toLimitElementary
+ toLimit_map
++ card_le_withConstants

You can run this locally as follows
## from your `mathlib4` directory:
git clone https://github.com/leanprover-community/mathlib-ci.git ../mathlib-ci

## summary with just the declaration names:
../mathlib-ci/scripts/pr_summary/declarations_diff.sh <optional_commit>

## more verbose report:
../mathlib-ci/scripts/pr_summary/declarations_diff.sh long <optional_commit>

The doc-module for scripts/pr_summary/declarations_diff.sh in the mathlib-ci repository contains some details about this script.

Declarations diff (Lean)

Lean-aware diff — post-build, computed from the Lean environment (commit e3821a1).

  • +74 new declarations
  • −0 removed declarations
+DirectLimit.equivOfForallLE
+DirectLimit.iSup_lift_mk_le_mk
+DirectLimit.mk_eq_iSup_lift_mk
+DirectLimit.mk_eq_of_forall_lift_mk_eq
+DirectLimit.mk_le_of_aleph0_le
+DirectLimit.mk_le_sum
+FirstOrder.Language.BoundedFormula.card_le_withConstants
+FirstOrder.Language.DefinablyFull
+FirstOrder.Language.ElementaryChain
+FirstOrder.Language.ElementaryChain.Limit
+FirstOrder.Language.ElementaryChain.carrier
+FirstOrder.Language.ElementaryChain.casesOn
+FirstOrder.Language.ElementaryChain.ctorIdx
+FirstOrder.Language.ElementaryChain.exists_finite_common_stage
+FirstOrder.Language.ElementaryChain.exists_toLimit
+FirstOrder.Language.ElementaryChain.liftElementary
+FirstOrder.Language.ElementaryChain.limit_models
+FirstOrder.Language.ElementaryChain.map
+FirstOrder.Language.ElementaryChain.map.congr_simp
+FirstOrder.Language.ElementaryChain.map_map
+FirstOrder.Language.ElementaryChain.map_self
+FirstOrder.Language.ElementaryChain.mk
+FirstOrder.Language.ElementaryChain.mk.congr_simp
+FirstOrder.Language.ElementaryChain.mk.inj
+FirstOrder.Language.ElementaryChain.mk.injEq
+FirstOrder.Language.ElementaryChain.mk.noConfusion
+FirstOrder.Language.ElementaryChain.mk.sizeOf_spec
+FirstOrder.Language.ElementaryChain.mk_limit_eq_of_forall_lift_mk_eq
+FirstOrder.Language.ElementaryChain.mk_limit_le_of_lift_mk_le
+FirstOrder.Language.ElementaryChain.noConfusion
+FirstOrder.Language.ElementaryChain.noConfusionType
+FirstOrder.Language.ElementaryChain.ofNatSucc
+FirstOrder.Language.ElementaryChain.ofNatSucc_map_succ
+FirstOrder.Language.ElementaryChain.realize_toLimit
+FirstOrder.Language.ElementaryChain.rec
+FirstOrder.Language.ElementaryChain.recOn
+FirstOrder.Language.ElementaryChain.struc
+FirstOrder.Language.ElementaryChain.toEmbeddingDirectedSystem
+FirstOrder.Language.ElementaryChain.toLimit
+FirstOrder.Language.ElementaryChain.toLimitElementary
+FirstOrder.Language.ElementaryChain.toLimit_map
+FirstOrder.Language.ElementaryEmbedding.encard_realizations_eq_coe_iff
+FirstOrder.Language.ElementaryEmbedding.infinite_realizations_iff
+FirstOrder.Language.ElementaryEmbedding.mk_realizations_le
+FirstOrder.Language.ElementaryEmbedding.natLERec
+FirstOrder.Language.ElementaryEmbedding.natLERec.congr_simp
+FirstOrder.Language.ElementaryEmbedding.natLERec_self
+FirstOrder.Language.ElementaryEmbedding.natLERec_succ
+FirstOrder.Language.ElementaryEmbedding.natLERec_trans
+FirstOrder.Language.ElementaryEmbedding.realizationsEmbedding
+FirstOrder.Language.Formula.card_le
+FirstOrder.Language.Formula.card_le_withConstants
+FirstOrder.Language.Formula.finOneRealizationsEquiv
+FirstOrder.Language.Formula.iExsAtLeast
+FirstOrder.Language.Formula.iExsAtLeast.congr_simp
+FirstOrder.Language.Formula.iExsAtMost
+FirstOrder.Language.Formula.iExsAtMost.congr_simp
+FirstOrder.Language.Formula.iExsExactly
+FirstOrder.Language.Formula.iExsExactly.congr_simp
+FirstOrder.Language.Formula.realize_iExsAtLeast
+FirstOrder.Language.Formula.realize_iExsAtLeast_iff_exists_injective
+FirstOrder.Language.Formula.realize_iExsAtMost
+FirstOrder.Language.Formula.realize_iExsAtMost_iff_not_exists_injection
+FirstOrder.Language.Formula.realize_iExsAtMost_iff_not_iExsAtLeast_succ
+FirstOrder.Language.Formula.realize_iExsExactly
+FirstOrder.Language.Formula.realize_iExsExactly_one_iff_iExsUnique
+FirstOrder.Language.Formula.realize_iExsExactly_zero
+FirstOrder.Language.LHom.lhomWithConstantsMap_isExpansionOn_of_eq
+FirstOrder.Language.Theory.ModelType.of.congr_simp
+FirstOrder.Language.Theory.exists_elementaryExtension_card_eq_with_full_unary_realizations
+FirstOrder.Language.Theory.exists_model_of_card_definably_full
+FirstOrder.Language.UnaryDefinablyFull
+FirstOrder.Language.definablyFull_of_unary
+Set.le_encard_iff_exists_injection_fin

Increase in strong tech debt: (relative, absolute) = (1.00, 0.00)
Current number Change Type (strong)
500 1 erw
Increase in weak tech debt: (relative, absolute) = (3.00, 0.00)
Current number Change Type (weak)
5026 3 exposed public sections

Current commit e3821a10c3
Reference commit 5b1613e1da

This script lives in the mathlib-ci repository. To run it locally, from your mathlib4 directory:

git clone https://github.com/leanprover-community/mathlib-ci.git ../mathlib-ci
../mathlib-ci/scripts/reporting/technical-debt-metrics.sh pr_summary
  • The relative value is the weighted sum of the differences with weight given by the inverse of the current value of the statistic.
  • The absolute value is the relative value divided by the total sum of the inverses of the current values (i.e. the weighted average of the differences).

@mathlib-dependent-issues mathlib-dependent-issues Bot added the blocked-by-other-PR This PR depends on another PR (this label is automatically managed by a bot) label Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

blocked-by-other-PR This PR depends on another PR (this label is automatically managed by a bot) large-import Automatically added label for PRs with a significant increase in transitive imports

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant