Example 4.3 (Scott 1981, PRG-19, §4) — the natural-number domain N #
Scott's "THE domain of integers" (pages 57–61). The tokens are ℕ, and the
neighbourhoods are
N = {{n} ∣ n ∈ ℕ} ∪ {ℕ}
— a flat domain: the singletons {n} are the finite total elements and the
whole space ℕ
is the least-informative neighbourhood Δ = ⊥. We build N by the
nested-or-disjoint criterion
(ofNestedOrDisjoint): any two neighbourhoods are nested (one is ℕ) or disjoint
(distinct
singletons).
The (ideal) elements of |N| are exactly: the bottom ⊥ = {ℕ} ("undefined"), and
for each n
the total element n̂ = ↑{n} = {{n}, ℕ} (natElem n). Scott then equips N with
the structure
maps
succ, pred : N → N(succMap,predMap)zero : N → T(zeroMap, into the truth domainTof Example 1.2),
making ⟨N, 0, succ, pred, zero⟩ "THE domain of integers". All three are strict
approximable
maps determined by their action on the finite total elements:
succ(n̂) = (n+1)^,succ(⊥) = ⊥;pred((n+1)^) = n̂,pred(0̂) = ⊥,pred(⊥) = ⊥;zero(0̂) = true,zero((n+1)^) = false,zero(⊥) = ⊥.
We capture the common shape — a map N → V sending n̂ ↦ val n and ⊥ ↦ ⊥ —
once and for all in
the combinator constLiftN, whose computation rules
constLiftN_natElem/constLiftN_bot give all
of the displayed equations uniformly. The data (N, constLiftN, succMap,
predMap) is
choice-free (#print axioms ⊆ {propext, Quot.sound}); zeroMap inherits
Classical.choice
structurally from the truth domain T of Example 1.2 exactly as
Example23.parityMap does.
Any two neighbourhoods of N are nested or disjoint: ℕ contains every
singleton, and two
distinct singletons are disjoint.
The total elements n̂. #
Scott's total element n̂ = ↑{n} = {{n}, ℕ}, the principal filter of the
singleton {n}.
Instances For
Scott's 0 ∈ |N|, the distinguished zero of the structured domain.
Instances For
The strict lifting combinator n̂ ↦ val n, ⊥ ↦ ⊥. #
The strict approximable map N → V determined by a choice of value val n ∈ |V| for each
n: it sends the total element n̂ to val n and the bottom ⊥ to ⊥. The
relation
X f Y holds when either X = Δ_N forces the blunt output Y = Δ_V (the strict
⊥ ↦ ⊥ clause),
or X = {n} and Y is a neighbourhood of val n.
Definition 2.1 checks uniformly: (i) Δ_N f Δ_V; (ii) intersect outputs —
distinct inputs are
impossible (ℕ ≠ {n}, singletons are one-one), so both outputs come from the
same val n and
inter_mem of the filter val n applies; (iii) sharpening {n} ⊆ X keeps the
input a singleton
{n}, and up_mem of val n widens the output, while a blunt input Δ_N forces
Δ_V.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Computation on the total elements. f(n̂) = val n.
Computation on bottom (strictness). f(⊥) = ⊥.
Example 4.3 — succ. succ(n) = n + 1, strict (succ(⊥) = ⊥).
Equations
Instances For
succ(n̂) = (n+1)^.
succ(⊥) = ⊥.
The value table for pred: pred(0) = ⊥, pred(k+1) = k.
Equations
Instances For
Example 4.3 — pred. pred(0) = ⊥, pred(n+1) = n, strict (pred(⊥) = ⊥).
Equations
Instances For
pred((n+1)^) = n̂.
pred(0̂) = ⊥: predecessor of zero is undefined.
pred(⊥) = ⊥.
The value table for zero: zero(0) = true, zero(n+1) = false.
Equations
Instances For
Example 4.3 — zero. zero(0) = true, zero(n+1) = false, strict
(zero(⊥) = ⊥).
Equations
Instances For
zero(0̂) = true.
zero((n+1)^) = false.
zero(⊥) = ⊥.
pred undoes succ. #
pred(succ(n̂)) = n̂: the predecessor undoes the successor on total elements.
(A sample of the
"recursion" reasoning Scott highlights; cf. the iterated-summation example.)