knaster-tarski theorem in type theory
Based on a very patient and kind explanation by bollu. It’s taking me a lot to understand the gist of this theorem and its implication and uses.
statement: the set of fixed points of a monotone function over a complete lattice is itself a complete lattice. we will need a bunch of definitions around lattices to get to the theorem.
A lattice is a set of elements such that
- there exists two binary operations and such that
- is associative:
- is commutative:
- is idempotent:
- is associative:
- is commutative:
- is idempotent:
- there exists two elements and such that
- is an identity element for :
- is an absorbing element for :
- is an identity element for :
- is an absorbing element for :
- there exists a partial order, which we indicate as , such that
- is below everything:
- is above everything:
- is the “greatest lower bound (GLB) of x and y”, where: (i) the lower bound of is if and (ii) is the greatest lower bound if , where and , we also have
- is the “least upper bound (LUB) of x and y”, where: (i) the upper bound of is if and (ii) is the least upper bound if , where and , we also have
From the definitions we have:
- and
- and
graph A($$\top $$)-->B(join: $$x\lor y$$ = LUB) B-->C($$x$$) B-->D($$y$$) C-->E(meet:$$x\land y$$ =GLB) D-->E E-->F($$\bot$$)
Other examples:
- Given any set, the set of its subsets is a lattice, with the partial order
- between is a latice with being
max, beingmin, and the order relation being - same for between
We can also reason the other way around and get a lattice out of a partial order: consider with order relation , we need to define and .
We can have a lattice with , and , …
graph TB A((d))-->B((b)) A((d))-->C((c)) B-->E((a)) C-->E((a))
In this case:
graph TB
A((d))-->B((c))
A((d))-->C((e))
B-->D((b))
B-->E((f))
C-->D
C-->E
D-->G((a))
E-->G
We have a lattice with , and , but also ? In this lattice we can’t decide what’s the actual LUB between c and e. This goes against the actual definition of join, hence this is not a lattice. To make this a proper lattice we can just add:
graph TB
A((d))-->B((c))
A((d))-->C((e))
B-->D((b))
B-->E((f))
B-->C
C-->D
C-->E
D-->G((a))
E-->G
meaning that since , and it can’t be since is not the least upper bound.
If a partial order fails to become a lattice it’s usually because there’s no , no or two elements don’t have a unique LUB\GLB.
We now need to define a complete lattice. Given the above definitions, we can reason about meet and join over sets with different number of elements:
- and given that , we can just pick
from which it follows for that where:
- is always true, since the existence of a certain to compare against is itself a contradiction.
- is always true for the same reason leaving us with , meaning .
meet finds the highest point in the lattice that is lower than the given points (GLB) and in particular, the lattice definition ensures that if such point exists, it is unique.
Let’s consider the set , i.e., containing the set of natural numbers and any subset of natural numbers with finite cardinality. Let’s make sure this is actually a lattice by defining:
- meet =
- join =
- , note that has finite cardinality and is a subset of , thus belongs to
- any two elements have GLB and LUB with respect to the relation : given the GLB is also finite and by definition , else if one of them is , then
Let’s consider the infinite family of elements in this lattice : The points in do not have a LUB in !
While this structure is a lattice, it is not a complete lattice: pairs (or more in general, finite collections of elements) have a LUB (join, or in this case suffices), but not every infinite collection does. To handle the join over an infinite collection of elements, we need more guarantees.
The same happens for meet: let’s consider , which looks something like:
graph TB A(ℕ)-->B(ℕ \ 0) A-->C(ℕ \ 1) A-->D(ℕ \ 2) C-->E(ℕ \ 1, 2) D-->E E-->F(...) A-->G(...)
We can build an infinite collection of elements whose intersections is finite, for example consider . any finite intersection of the elements in will only miss a finite number of elements (“from the highest onwards”), however the intersection over all the elements in fill have finite cardinality and will eventually like , since is common to every element of the collection.
Incomplete lattices often have the structure of : everything works up to finite collections of elements, but when meet/join need to handle an infinite number of elements, the structure stops working.
Other examples:
- with order relation is not complete, e.g. is missing and sub-lattices around that area will not have the appropriate upper/lower bounds.
- with order relation is a complete lattice
- In Lean, with order relation is a lattice, where join is disjunction and meet is conjunction, is false and is true
Moving on with the theorem statement, we need to define a monotone function on a partial order . Let , where has a partial order given by and has a partial order given by .
is monotone with
Basically, a function is monotone if it preserves the order relation existing in the codomain into the domain, without establishing a relation between the two order relation themselves (no hypothesis is required for ).
We then define a fixed point: given and , we say is a fixed point (FP) .
We now have enough definitions to go back to the theorem statement: given a function that is monotone, with being a complete lattice, then we know:
- has a FP
- let be the set of FPs of , then at least one least FP, i.e., one element smaller than all other FPs
- the set of FPs is a complete sub-lattice of
Example: let’s consider with partial order :
- meet =
- join = and think about a few functions:
- , in which case the set of FPs is
- , meaning only contains one element: . Note that is itself a complete lattice!
- with fixed points , , … and therefore :
is the set of subsets of such that the subset is contained in .
With this in mind, we define for the sublattice:
- meet = : even in the case infinite meet, the resulting subset is and this be part of the sub-lattice ()
- join = , again the infinite union is which is in
- given : LUB = given that will still be in the union
- given : GLB = given that at least are always in the intersection
The final objective of my effort with this theorem, is to understand its implication in type theory and in particular concerning types definitions in Lean, so let’s try to move towards that domain.
Let’s consider and introduce the concept of indicator function : when we say , we really are defining a function where . We can re-interpret lattices considering this idea. is a complete lattice, with and , , . From this lattice, we derive a new lattice by pointwise definition:
- join: given then is the join on functions such that: . For each point , we consider the behavior of in the domain.
- meet: we use the same approach, given then is the meet on functions such that: . For each point , we consider the behavior of in the domain.
Knaster-Tarski theorem in analysis
A more analytical explanation. We construct a lattice using and adding two arbitrary elements and :
⊤
0, 1, 2, ...
⊥
forming a complete lattice with:
- LUB() = $\bot: any element is an upper bound of an empty set
- LUB() =
- LUB() =
We now consider any set X: the space of functions will be a complete lattice, with
- bottom function , “spits out for any input”
- join function
- meet function
in particular, the lattice is complete, in fact:
- infinite join given a family of functions : the join of infinitely many elements is the LUB. This still belongs in , since all do - also was complete in the first place, meaning that infinite join belongs in !
- infinite meet given a family of functions : the meet of infinitely many elements is the GLB. The same reasoning as join applies.
We instantiate this construction with and equipped with (). This construction contains, for example:
- almost identity function
fun (x : ℕ) => x - always-returns-bottom function
fun (x : ℕ) => ⊥ - weird function 1
fun (x : ℕ) => if x = 0 then 1 else ⊥ - weird function 2
fun (x : ℕ) => if x = 0 then 1 else if x = 1 then 1 else ⊥ - weird function 3
fun (x : ℕ) => if x = 0 then 1 else if x = 1 then 1 else if x =- 2 then 2 else ⊥ - weird function 4
fun (x : ℕ) => if x = 0 then 1 else if x = 1 then 1 else if x =- 2 then 2 else if x = 3 then 6 else ⊥
these weird functions are all finite approximations of the factorial function (up to a- certain x).
We now can build a monotone function from this space of functions to itself , i.e. :
---
config:
theme: 'forest'
timeline:
disableMulticolor: true
---
timeline
- : f0 = fun x => ⊥
: f1 = m f0
: f2 = m f1
: f3 = m f2
: f4 = m f3
: f1 ∪ f2
0 : ⊥
: 1
: 1
: 1
: 1
: 1
1 : ⊥
: ⊥
: 1
: 1
: 1
: 1
2 : we cheat and
: ⊥
: ⊥
: 2
: 2
: ⊥
3 : multiply a natural
: ...
: ⊥
: ⊥
: 6
: we take the join
4 : number by ⊥
: ...
: ⊥
: ⊥
: ⊥
: of {f1(0), f(0)} etc
given two said functions we define
A concrete construction of naturals using this setting:
- we consider a function $f(S) = {0}\cup {succ(s) ;|;s\in S}
- this function is monotone with respect to : in fact
- according to Knaster Tarski, the set of fixed points of over a complete lattice is itself a complete lattice: in this case the fixed point is a set : is the fixed point itself. In other words, Knaster Tarski guarantees that the recursive function defining the set has a fixed point and therefore the set actually exists!
For example, let’s consider a function with no fixed points: in the lattice : we can’t get a set of elements out of this function.
Think about the lattice for “normal functions” (i.e. real analysis). Then think about sets: e.g. the set of naturals (each set is a node of the lattice), with the lattice structure given by ∪, the monotone function we consider to reason about the theorem is such that: : Knaster Tarski allows to use the recursive definitions to create an actual “math object”.
For example, if we consider a function with no fixed points over , e.g. In lean, the positivity check verifies that the function we’re using to build a type is monotone!
For example, when defining the type Nat, the constructor might have a parameter of type Nat, e.g. :
def Nat :
| zero : Nat
| succ (n : Nat) : Nat
the positivity check ensures that the function f mapping a set of candidates for Nat to a new,
larger set is indeed a monotone function on the lattice of all possible subsets of Nat.
On the complete lattice , the function we use to construct
the type is and checking its monotonicity ensures that the
has a fixed point, i.e. a set ensuring the validity of the construction.
I am on a quest for an example with a non monotone function and would love a suggestion on this!