A model of ZFC #
In this file, we model Zermelo-Fraenkel set theory (+ Choice) using Lean's underlying type theory. We do this in four main steps:
- Define pre-sets inductively.
- Define extensional equivalence on pre-sets and give it a
setoid
instance. - Define ZFC sets by quotienting pre-sets by extensional equivalence.
- Define classes as sets of ZFC sets. Then the rest is usual set theory.
The model #
PSet
: Pre-set. A pre-set is inductively defined by its indexing type and its members, which are themselves pre-sets.ZFSet
: ZFC set. Defined asPSet
quotiented byPSet.Equiv
, the extensional equivalence.Class
: Class. Defined asSet ZFSet
.ZFSet.choice
: Axiom of choice. Proved from Lean's axiom of choice.
Other definitions #
PSet.Type
: Underlying type of a pre-set.PSet.Func
: Underlying family of pre-sets of a pre-set.PSet.Equiv
: Extensional equivalence of pre-sets. Defined inductively.PSet.omega
,ZFSet.omega
: The von Neumann ordinalω
as aPSet
, as aSet
.PSet.Arity.Equiv
: Extensional equivalence ofn
-aryPSet
-valued functions. Extension ofPSet.Equiv
.PSet.Resp
: Collection ofn
-aryPSet
-valued functions that respect extensional equivalence.PSet.eval
: Turns aPSet
-valued function that respect extensional equivalence into aZFSet
-valued function.Classical.allDefinable
: All functions are classically definable.ZFSet.IsFunc
: Predicate that a ZFC set is a subset ofx × y
that can be considered as a ZFC functionx → y
. That is, each member ofx
is related by the ZFC set to exactly one member ofy
.ZFSet.funs
: ZFC set of ZFC functionsx → y
.ZFSet.Hereditarily p x
: Predicate that every set in the transitive closure ofx
has propertyp
.Class.iota
: Definite description operator.
Notes #
To avoid confusion between the Lean set
and the ZFC Set
, docstrings in this file refer to them
respectively as "set
" and "ZFC set".
TODO #
Prove Set.map_definable_aux
computably.
Two pre-sets are extensionally equivalent if every element of the first family is extensionally equivalent to some element of the second family and vice-versa.
Equations
- PSet.Equiv (PSet.mk α A) (PSet.mk α_1 B) = ((∀ (a : α), ∃ (b : α_1), PSet.Equiv (A a) (B b)) ∧ ∀ (b : α_1), ∃ (a : α), PSet.Equiv (A a) (B b))
Instances For
Equations
- PSet.setoid = { r := PSet.Equiv, iseqv := PSet.setoid.proof_1 }
A pre-set is a subset of another pre-set if every element of the first family is extensionally equivalent to some element of the second family.
Equations
- PSet.Subset x y = ∀ (a : PSet.Type x), ∃ (b : PSet.Type y), PSet.Equiv (PSet.Func x a) (PSet.Func y b)
Instances For
Equations
- PSet.instHasSubsetPSet = { Subset := PSet.Subset }
Equations
- PSet.instMembershipPSetPSet = { mem := PSet.Mem }
Equations
- PSet.instWellFoundedRelationPSet = { rel := fun (x x_1 : PSet) => x ∈ x_1, wf := PSet.mem_wf }
A nonempty set is one that contains some element.
Equations
- PSet.Nonempty u = Set.Nonempty (PSet.toSet u)
Instances For
Two pre-sets are equivalent iff they have the same members.
Equations
- PSet.instCoePSetSetPSet = { coe := PSet.toSet }
Equations
- PSet.instEmptyCollectionPSet = { emptyCollection := PSet.empty }
Equations
- PSet.instInhabitedPSet = { default := ∅ }
Insert an element into a pre-set
Equations
- PSet.insert x y = PSet.mk (Option (PSet.Type y)) fun (o : Option (PSet.Type y)) => Option.casesOn o x (PSet.Func y)
Instances For
Equations
- PSet.instInsertPSetPSet = { insert := PSet.insert }
Equations
- PSet.instSingletonPSetPSet = { singleton := fun (s : PSet) => insert s ∅ }
Equations
The n-th von Neumann ordinal
Equations
- PSet.ofNat 0 = ∅
- PSet.ofNat (Nat.succ n) = insert (PSet.ofNat n) (PSet.ofNat n)
Instances For
The von Neumann ordinal ω
Equations
- PSet.omega = PSet.mk (ULift.{u_1, 0} ℕ) fun (n : ULift.{u_1, 0} ℕ) => PSet.ofNat n.down
Instances For
Equations
- PSet.instSepPSetPSet = { sep := PSet.sep }
The pre-set union operator
Equations
- One or more equations did not get rendered due to their size.
Instances For
The pre-set union operator
Equations
- PSet.«term⋃₀_» = Lean.ParserDescr.node `PSet.term⋃₀_ 110 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol "⋃₀ ") (Lean.ParserDescr.cat `term 110))
Instances For
Embedding of one universe in another
Equations
- PSet.embed = PSet.mk (ULift.{v, u + 1} PSet) fun (x : ULift.{v, u + 1} PSet) => match x with | { down := x } => PSet.Lift x
Instances For
Function equivalence is defined so that f ~ g
iff ∀ x y, x ~ y → f x ~ g y
. This extends to
equivalence of n
-ary functions.
Equations
- PSet.Arity.Equiv a b = PSet.Equiv a b
- PSet.Arity.Equiv a b = ∀ (x y : PSet), PSet.Equiv x y → PSet.Arity.Equiv (a x) (b y)
Instances For
Equations
- One or more equations did not get rendered due to their size.
The n
-ary image of a (n + 1)
-ary function respecting equivalence as a function respecting
equivalence.
Equations
- PSet.Resp.f f x = { val := ↑f x, property := (_ : PSet.Arity.Equiv (↑f x) (↑f x)) }
Instances For
Function equivalence for functions respecting equivalence. See PSet.Arity.Equiv
.
Equations
- PSet.Resp.Equiv a b = PSet.Arity.Equiv ↑a ↑b
Instances For
Equations
- PSet.Resp.setoid = { r := PSet.Resp.Equiv, iseqv := (_ : Equivalence PSet.Resp.Equiv) }
Helper function for PSet.eval
.
Equations
- One or more equations did not get rendered due to their size.
- PSet.Resp.evalAux = { val := fun (a : PSet.Resp 0) => ⟦↑a⟧, property := PSet.Resp.evalAux.proof_4 }
Instances For
An equivalence-respecting function yields an n-ary ZFC set function.
Equations
- PSet.Resp.eval n = ↑PSet.Resp.evalAux
Instances For
A set function is "definable" if it is the image of some n-ary pre-set function. This isn't exactly definability, but is useful as a sufficient condition for functions that have a computable image.
- mk: {n : ℕ} → (f : PSet.Resp n) → PSet.Definable n (PSet.Resp.eval n f)
Instances
The evaluation of a function respecting equivalence is definable, by that same function.
Equations
- PSet.Definable.EqMk f x = match x✝, x with | .(PSet.Resp.eval n f), (_ : PSet.Resp.eval n f = PSet.Resp.eval n f) => PSet.Definable.mk f
Instances For
Turns a definable function into a function that respects equivalence.
Equations
- PSet.Definable.Resp x✝ = match x✝, x with | .(PSet.Resp.eval n f), PSet.Definable.mk f => f
Instances For
All functions are classically definable.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The membership relation for ZFC sets is inherited from the membership relation for pre-sets.
Equations
Instances For
Equations
- ZFSet.instMembershipZFSetZFSet = { mem := ZFSet.Mem }
Equations
- (_ : Small.{u, u + 1} ↑(ZFSet.toSet x)) = (_ : Small.{u, u + 1} ↑(ZFSet.toSet x))
A nonempty set is one that contains some element.
Equations
Instances For
x ⊆ y
as ZFC sets means that all members of x
are members of y
.
Equations
- ZFSet.Subset x y = ∀ ⦃z : ZFSet⦄, z ∈ x → z ∈ y
Instances For
Equations
- ZFSet.hasSubset = { Subset := ZFSet.Subset }
Equations
- ZFSet.instIsAntisymmZFSetSubsetHasSubset = (_ : IsAntisymm ZFSet fun (x x_1 : ZFSet) => x ⊆ x_1)
Equations
- ZFSet.instEmptyCollectionZFSet = { emptyCollection := ZFSet.empty }
Equations
- ZFSet.instInhabitedZFSet = { default := ∅ }
Insert x y
is the set {x} ∪ y
Equations
- ZFSet.Insert = PSet.Resp.eval 2 { val := PSet.insert, property := ZFSet.Insert.proof_1 }
Instances For
Equations
- ZFSet.instInsertZFSetZFSet = { insert := ZFSet.Insert }
Equations
- ZFSet.instSingletonZFSetZFSet = { singleton := fun (x : ZFSet) => insert x ∅ }
Equations
- ZFSet.instSepZFSetZFSet = { sep := ZFSet.sep }
The powerset operation, the collection of subsets of a ZFC set
Equations
- ZFSet.powerset = PSet.Resp.eval 1 { val := PSet.powerset, property := ZFSet.powerset.proof_1 }
Instances For
The union operator, the collection of elements of elements of a ZFC set
Equations
- ZFSet.sUnion = PSet.Resp.eval 1 { val := PSet.sUnion, property := ZFSet.sUnion.proof_1 }
Instances For
The union operator, the collection of elements of elements of a ZFC set
Equations
- ZFSet.«term⋃₀_» = Lean.ParserDescr.node `ZFSet.term⋃₀_ 110 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol "⋃₀ ") (Lean.ParserDescr.cat `term 110))
Instances For
The intersection operator, the collection of elements in all of the elements of a ZFC set. We
special-case ⋂₀ ∅ = ∅
.
Equations
- ⋂₀ x = if h : ZFSet.Nonempty x then ZFSet.sep (fun (y : ZFSet) => ∀ z ∈ x, y ∈ z) (Set.Nonempty.some h) else ∅
Instances For
The intersection operator, the collection of elements in all of the elements of a ZFC set. We
special-case ⋂₀ ∅ = ∅
.
Equations
- ZFSet.«term⋂₀_» = Lean.ParserDescr.node `ZFSet.term⋂₀_ 110 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol "⋂₀ ") (Lean.ParserDescr.cat `term 110))
Instances For
The binary intersection operation
Equations
- ZFSet.inter x y = ZFSet.sep (fun (z : ZFSet) => z ∈ y) x
Instances For
The set difference operation
Equations
- ZFSet.diff x y = ZFSet.sep (fun (z : ZFSet) => z ∉ y) x
Instances For
Equations
- ZFSet.instUnionZFSet = { union := ZFSet.union }
Equations
- ZFSet.instInterZFSet = { inter := ZFSet.inter }
Equations
- ZFSet.instSDiffZFSet = { sdiff := ZFSet.diff }
Equations
- ZFSet.instWellFoundedRelationZFSet = { rel := fun (x x_1 : ZFSet) => x ∈ x_1, wf := ZFSet.mem_wf }
The image of a (definable) ZFC set function
Equations
- One or more equations did not get rendered due to their size.
Instances For
The range of an indexed family of sets. The universes allow for a more general index type
without manual use of ULift
.
Equations
- ZFSet.range f = ⟦PSet.mk (ULift.{v, u} α) (Quotient.out ∘ f ∘ ULift.down)⟧
Instances For
A subset of pairs {(a, b) ∈ x × y | p a b}
Equations
- ZFSet.pairSep p x y = ZFSet.sep (fun (z : ZFSet) => ∃ a ∈ x, ∃ b ∈ y, z = ZFSet.pair a b ∧ p a b) (ZFSet.powerset (ZFSet.powerset (x ∪ y)))
Instances For
The cartesian product, {(a, b) | a ∈ x, b ∈ y}
Equations
- ZFSet.prod = ZFSet.pairSep fun (x x : ZFSet) => True
Instances For
isFunc x y f
is the assertion that f
is a subset of x × y
which relates to each element
of x
a unique element of y
, so that we can consider f
as a ZFC function x → y
.
Equations
- ZFSet.IsFunc x y f = (f ⊆ ZFSet.prod x y ∧ ∀ z ∈ x, ∃! (w : ZFSet), ZFSet.pair z w ∈ f)
Instances For
funs x y
is y ^ x
, the set of all set functions x → y
Equations
- ZFSet.funs x y = ZFSet.sep (ZFSet.IsFunc x y) (ZFSet.powerset (ZFSet.prod x y))
Instances For
Equations
- ZFSet.mapDefinableAux f = Classical.allDefinable fun (y : ZFSet) => ZFSet.pair y (f y)
Graph of a function: map f x
is the ZFC function which maps a ∈ x
to f a
Equations
- ZFSet.map f = ZFSet.image fun (y : ZFSet) => ZFSet.pair y (f y)
Instances For
Given a predicate p
on ZFC sets. Hereditarily p x
means that x
has property p
and the
members of x
are all Hereditarily p
.
Equations
- ZFSet.Hereditarily p x = (p x ∧ ∀ y ∈ x, ZFSet.Hereditarily p y)
Instances For
Alias of the forward direction of ZFSet.hereditarily_iff
.
Equations
- instInsertZFSetClass = { insert := Set.insert }
Equations
- Class.instCoeZFSetClass = { coe := Class.ofSet }
Assert that A
is a ZFC set satisfying B
Equations
- Class.ToSet B A = ∃ (x : ZFSet), ↑x = A ∧ B x
Instances For
Equations
- Class.instMembershipClassClass = { mem := Class.Mem }
Equations
- Class.instWellFoundedRelationClass = { rel := fun (x x_1 : Class) => x ∈ x_1, wf := Class.mem_wf }
Convert a conglomerate (a collection of classes) into a class
Equations
- Class.congToClass x = {y : ZFSet | ↑y ∈ x}
Instances For
Convert a class into a conglomerate (a collection of classes)
Equations
- Class.classToCong x = {y : Class | y ∈ x}
Instances For
The power class of a class is the class of all subclasses that are ZFC sets
Equations
- Class.powerset x = Class.congToClass (𝒫 x)
Instances For
The union of a class is the class of all members of ZFC sets in the class
Equations
- ⋃₀ x = ⋃₀ Class.classToCong x
Instances For
The union of a class is the class of all members of ZFC sets in the class
Equations
- Class.«term⋃₀_» = Lean.ParserDescr.node `Class.term⋃₀_ 110 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol "⋃₀ ") (Lean.ParserDescr.cat `term 110))
Instances For
The intersection of a class is the class of all members of ZFC sets in the class
Equations
- ⋂₀ x = ⋂₀ Class.classToCong x
Instances For
The intersection of a class is the class of all members of ZFC sets in the class
Equations
- Class.«term⋂₀_» = Lean.ParserDescr.node `Class.term⋂₀_ 110 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol "⋂₀ ") (Lean.ParserDescr.cat `term 110))
Instances For
An induction principle for sets. If every subset of a class is a member, then the class is universal.
Function value
Equations
- F ′ A = Class.iota fun (y : ZFSet) => Class.ToSet (fun (x : ZFSet) => F (ZFSet.pair x y)) A
Instances For
Function value
Equations
- Class.«term_′_» = Lean.ParserDescr.trailingNode `Class.term_′_ 100 100 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ′ ") (Lean.ParserDescr.cat `term 101))
Instances For
A choice function on the class of nonempty ZFC sets.
Equations
- ZFSet.choice x = ZFSet.map (fun (y : ZFSet) => Classical.epsilon fun (z : ZFSet) => z ∈ y) x
Instances For
ZFSet.toSet
as an equivalence.
Equations
- One or more equations did not get rendered due to their size.