Lectures onType Theory
Chapter 162
Chapter 162Optional

Guarded and Clocked Dependent Type Theory

Prerequisites. Direct starred prerequisites: none. No later core chapter depends on this route.

Two definitions that ought to be admissible are rejected by the guardedness conditions of chapter 33, chapter 124.

The first is a stream. Let map send a function and a stream of naturals to the stream of its values, and consider nats:=0::map suc nats. Every finite prefix of nats is determined: the first element is 0, and the (k+1)st is the successor of the kth. A syntactic guardedness check nevertheless rejects (162.1), because the recursive occurrence is an argument of map rather than an immediate argument of the constructor (::). The check inspects the position of the recursive call and cannot inspect what map does with it.

The second is a type. Solve D(DN). No inductive or coinductive definition produces D: the variable occurs negatively, so (162.2) is not the initial algebra or the final coalgebra of a functor. A positivity check rejects it for that reason.

Both rejections come from a check on where a recursive occurrence sits. This chapter replaces that check by a type former. Write A for the type of elements of A that are available one step later. Then (162.1) becomes a definition whose recursive occurrence has type Str rather than Str, and (162.2) becomes D(DN), which has a unique solution, negative occurrence and all. The chapter’s task is to give the rules for , to interpret them, and to prove that the resulting programs deliver every finite observation.

A calculus with a later modality

Convention 162.1 — Base signature

The ambient theory is extensional Martin-Löf type theory: contexts, the judgments Γ ctx, ΓA type, Γt:A, ΓAB type and Γtu:A; dependent products and sums; the natural numbers N with 0 and suc; identity types IdA(t,u) with equality reflection, so that an inhabitant of IdA(t,u) gives Γtu:A; and Tarski universes U with decoding El(). Every rule of that theory remains available; this chapter states only what is added.

The first attempt at the delta is the following pair of rules, which say that is an applicative functor: data available now is available later, and a function available later can be applied to an argument available later. Γt:AΓnextt:AΓf:(AB)Γt:AΓft:B These two rules suffice while types do not depend on terms. They fail as soon as they do. Suppose Γf:(x:AB) and Γt:A. What is the type of ft? If t were nextu, the answer would be (B[u/x]). For an arbitrary t there is no such u to substitute, and (162.3) cannot be stated.

The situation is not hypothetical. Let A be a type of guarded streams and let B be a predicate on streams. A proof by guarded recursion has an induction hypothesis of type (x:AB), and it must be applied to the tail of a stream, whose type is A. The type of the result must mention the tail, which is available only later.

The repair is to keep the substitution and delay it.

Definition 162.2 — Delayed substitutions

The raw syntax of convention 162.1 is extended by A,B::=ξ.A,t,u::=nextξ.t^t,ξ::=ξ[xt]. A delayed substitution ξ is a list of assignments of terms of -types to variables; the judgment Γξ:Γ says that ξ assigns, to each variable of the telescope Γ, a term available one step later. In ξ.A and nextξ.t the variables assigned by ξ are bound in A and in t respectively. We write A for .A and nextt for next.t.

Γ ctx
Γ:
DS-Emp
Γξ:ΓΓt:ξ.A
Γξ[xt]:Γ,x:A
DS-Cons
Γ,ΓA typeΓξ:Γ
Γξ.A type
Later-F
Γ,Γt:AΓξ:Γ
Γnextξ.t:ξ.A
Later-I
ΓA:U
Γ^A:U
Later-Code
Γ,x:At:A
Γfixx.t:A
Fix

Definition 162.3 — Equations of the guarded calculus

The following equations are added to the judgmental equality of convention 162.1. In Later-Weak and Next-Weak the type A and the term u are well formed in a context without x; in Later-Exch and Next-Exch the type of x does not mention y and the type of y does not mention x. ξ[xt].Aξ.ALaterWeakξ[xt,yu]ξ.Aξ[yu,xt]ξ.ALaterExchξ[xnextξ.t].Aξ.A[t/x]LaterForceEl(^(nextξ.t))ξ.El(t)LaterElIdξ.A(nextξ.t,nextξ.s)ξ.IdA(t,s)LaterIdnextξ[xt].unextξ.uNextWeaknextξ[xt].xtNextVarnextξ[xt,yu]ξ.vnextξ[yu,xt]ξ.vNextExchnextξ[xnextξ.t].unextξ.u[t/x]NextForcefixx.tt[next(fixx.t)/x]FixUnfold

The applicative operation of (162.3) is not a primitive of this calculus. It is definable, and its dependent typing rule is derivable.

Proposition 162.4 — Dependent application

Define ft:=next[gf,xt].gx. Then the rule Γf:ξ.x:ABΓt:ξ.AΓft:ξ[xt].B is derivable, and the two applicative-functor laws (nextξ.f)(nextξ.t)nextξ.(ft),(nextξ.λx.x)tt hold.

Proof of Proposition 162.4 — Dependent application

Proof. For the typing rule, extend ξ twice. From Γf:ξ.x:AB and DS-Cons we obtain Γξ[gf]:Γ,g:x:AB; from Γt:ξ.A and Later-Weak we obtain Γt:ξ[gf].A, so DS-Cons applies again and gives Γξ[gf,xt]:Γ,g:x:AB,x:A. In that extended telescope gx:B, so Later-I types next[gf,xt].gx at ξ[gf,xt].B. The variable g does not occur in B, so Later-Weak and Later-Exch remove it, leaving ξ[xt].B.

For the first law, (nextξ.f)(nextξ.t)def.next[gnextξ.f,xnextξ.t].gxNextForcenextξ.(ft), the last step applying Next-Force twice, once for each assignment.

For the second law, (nextξ.λx.x)tdef.next[gnextξ.λx.x,yt].gyNextForcenext[yt].yNextVart. ◻

Exercise 162.1

★☆☆ Derive the non-dependent rule Γf:ξ.(AB)Γt:ξ.AΓft:ξ.B from proposition 162.4, naming the equation of definition 162.3 that removes the extra assignment. Then show that is not a monad by attempting to derive a term of type AA and identifying the rule that would be needed.

Guarded fixed points

Definition 162.5 — Guarded recursion and L"ob induction

A term formed by Fix is defined by guarded recursion. When the type A is a proposition, the same rule reads Γ,x:At:AΓfixx.t:A, and is called Löb induction: to prove A it suffices to prove A from the assumption that A holds one step later.

Löb induction is not a valid principle of ordinary logic. Taking A to be the false proposition and A to be A would prove falsity; what prevents that is exactly that A is not A. The next lemma is the precise form of the difference, and it is proved in the model in section 162.3.

Proposition 162.6 — Uniqueness of guarded fixed points

Let Γ,x:At:A. If Γu:A satisfies Γut[nextu/x]:A, then Γufixx.t:A is validated by the interpretation of section 162.3.

The statement is deliberately about the interpretation and not about the calculus: Fix-Unfold makes fixx.t a fixed point, and uniqueness is a semantic fact that theorem 162.14 supplies.

Definition 162.7 — Guarded streams

Let ΓA^:U be a code with A:=El(A^). Define the code Str^A:=fixX. A^×^^X,StrA:=El(Str^A), where ×^ is the code of the product type. The guarded stream type StrA satisfies StrAA×StrA, and we write hd:=pr1,tl:=pr2,cons:=λa.λas.(a,as):AStrAStrA.

Proof of Definition 162.7 — Guarded streams

Derivation of the displayed equation. Unfolding the fixed point and decoding, StrAdef.El(Str^A)FixUnfoldEl(A^×^^(nextStr^A))LaterElA×El(Str^A)def.A×StrA, where the third step uses Later-El with the empty delayed substitution and the decoding of ×^ as a product. ◻

Example 162.8 — The stream rejected in eq:gdtt-nats

Define, for A:=N, map:=fixφ.λf.λs.cons(f(hds))(φnextftls):(NN)StrNStrN,nats:=fixx.cons0((next(mapsuc))x):StrN. In nats the recursion variable x has type StrN, and the only operation applied to it is , which by proposition 162.4 returns a term of -type again. The definition is therefore typed by Fix exactly because the recursive occurrence stays under . The syntactic check that rejected (162.1) inspected the position of the recursive occurrence; Fix inspects its type.

Exercise 162.2

★★☆ Define zipWith:(NNN)StrNStrNStrN by guarded recursion, giving the type of every subterm containing the recursion variable. Then attempt to define the function that deletes every second element of a stream, with type StrNStrN, and identify the exact judgment that cannot be derived. State which type the second element of the output would have to be read from.

Exercise 162.2 exhibits the boundary of the single-modality calculus: a function whose nth output uses the (2n)th input cannot be typed, because tl moves one step later each time it is applied and nothing brings the result back. Section 162.5 adds the operation that does.

The topos of trees

Definition 162.9 — The category S

Let ω be the poset 123 of positive integers. The topos of trees is the presheaf category S:=[ωop,Set]. Concretely, an object X is a family of sets X1,X2, together with restriction maps rnX:Xn+1Xn for n1, and a map f:XY is a family fn:XnYn with rnYfn+1=fnrnX.

Read Xn as the information about an element of X that is available after n steps, and rnX as forgetting the last step. A global element of X, that is a map 1X, is a compatible family xnXn with rnX(xn+1)=xn.

Definition 162.10 — The later functor

Define :SS by (X)1:={},(X)n+1:=Xn,r1X:=!,rn+1X:=rnX, with (f)1:=id and (f)n+1:=fn. Define nextX:XX by (nextX)1:=! and (nextX)n+1:=rnX.

Lemma 162.11 — Preservation of finite limits

preserves finite limits, and next is natural in X.

Proof of Lemma 162.11 — Preservation of finite limits

Proof. Finite limits in S are computed levelwise. At level 1 the value of is the one-point set, which is the limit of any finite diagram of one-point sets; at level n+1 the value is the level-n value of the argument, and the limit at level n is preserved because the identity function preserves it. Naturality of next at level 1 holds because the codomain is a one-point set, and at level n+1 it is the naturality square of f at level n. ◻

Remark 162.12 — is not a monad

There is no natural transformation . Such a transformation would supply, at level 2, a function (X)2=(X)1={}(X)2=X1 natural in X, hence a global element of X1 uniform in X; taking X with X1= makes that impossible. This is the semantic reason that exercise 162.1 has no term of type AA.

Definition 162.13 — Contractive morphisms

A map f:XY is contractive when there is g:XY with f=gnextX; the map g is a witness for f.

Theorem 162.14 — Unique guarded fixed points

Let g:XX. There is exactly one global element x:1X with x=gnextXx, namely x1:=g1(),xn+1:=gn+1(xn). Consequently every contractive endomorphism of X has exactly one fixed point.

Proof of Theorem 162.14 — Unique guarded fixed points

Proof. The family is a global element. The displayed clauses are typed: (X)1={} and (X)n+1=Xn, so g1()X1 and gn+1(xn)Xn+1. Compatibility is proved by induction on n. For n=1, naturality of g at level 1 gives r1Xg2=g1r1X=g1!, hence r1X(x2)=def.r1X(g2(x1))=nat.g1()=def.x1. For n2, naturality gives rnXgn+1=gnrn1X, hence rnX(xn+1)=def.rnX(gn+1(xn))=nat.gn(rn1X(xn))=IHgn(xn1)=def.xn.

It is a fixed point. (nextXx)1= and (nextXx)n+1=rnX(xn+1)=xn, so (gnextXx)1=g1()=x1 and (gnextXx)n+1=gn+1(xn)=xn+1.

Uniqueness. Let y be a global element with y=gnextXy. Then y1=g1()=x1, and if yn=xn then yn+1=gn+1(rnX(yn+1))=gn+1(yn)=gn+1(xn)=xn+1. By induction y=x.

For the consequence, a contractive f:XX with witness g satisfies fx=gnextXx for every x, so the fixed points of f are exactly the solutions of the displayed equation. ◻

Definition 162.15 — Semantics of contexts, types and terms

A context Γ is interpreted as an object [[Γ]] of S. A type ΓA type is interpreted as a family [[A]] assigning to every n1 and every γ[[Γ]]n a set [[A]]n(γ), together with restriction maps rnA(γ):[[A]]n+1(γ)[[A]]n(rn[[Γ]](γ)). A term Γt:A is interpreted as a family of elements [[t]]n(γ)[[A]]n(γ) commuting with restriction. Context extension is [[Γ,x:A]]n:={(γ,a)γ[[Γ]]n, a[[A]]n(γ)}. The new clauses are [[A]]1(γ):={},[[A]]n+1(γ):=[[A]]n(rn(γ)),[[[xt].B]]1(γ):={},[[[xt].B]]n+1(γ):=[[B]]n(rn(γ),[[t]]n+1(γ)),[[nextu]]1(γ):=,[[nextu]]n+1(γ):=[[u]]n(rn(γ)),[[next[xt].u]]1(γ):=,[[next[xt].u]]n+1(γ):=[[u]]n(rn(γ),[[t]]n+1(γ)), and a longer delayed substitution is interpreted by iterating the second and fourth clauses from left to right. A term fixx.t formed by Fix in the empty context is interpreted as the unique fixed point of theorem 162.14 for the map g:[[A]][[A]] with g1():=[[t]]1() and gn+1(a):=[[t]]n+1(a).

The second clause is the whole content of the delayed substitution: at stage n+1 the argument t is available, with value [[t]]n+1(γ)[[A]]n(rnγ), and the type B is reindexed along it. The delay in the syntax is the shift of index in the model.

Theorem 162.16 — Soundness

Every rule of definition 162.2 other than Later-Code, and every equation of definition 162.3 other than Later-El, is validated by definition 162.15.

Proof of Theorem 162.16 — Soundness

Proof. The rules DS-Emp, DS-Cons, Later-F and Later-I hold because each displayed clause of definition 162.15 is defined exactly when its premises are, and Fix holds by theorem 162.14. Each equation is checked at level 1, where both sides are the one-point set or the element , and at level n+1. We display the level-(n+1) computation for each; throughout, γ ranges over [[Γ]]n+1 and rn abbreviates rn[[Γ]].

Later-Weak. If x does not occur in A, then [[A]]n(rnγ,a) does not depend on a, so [[[xt].A]]n+1(γ)=def.[[A]]n(rnγ,[[t]]n+1(γ))=xA[[A]]n(rnγ)=def.[[A]]n+1(γ).

Later-Force. Substituting a next recovers an ordinary substitution: [[[xnextt].A]]n+1(γ)=def.[[A]]n(rnγ,[[nextt]]n+1(γ))=def.[[A]]n(rnγ,[[t]]n(rnγ))=subst.[[(A[t/x])]]n+1(γ).

Later-Exch. The two clauses for x and y evaluate [[t]]n+1(γ) and [[u]]n+1(γ) at the same index n+1, and neither type mentions the other variable, so the resulting reindexing of [[A]]n is the same pair in either order.

Later-Id. Interpret the extensional identity type by setting [[IdA(t,s)]]n(γ) to {} when [[t]]n(γ)=[[s]]n(γ), and to otherwise. Then [[IdA(nextt,nexts)]]n+1(γ) is inhabited[[t]]n(rnγ)=[[s]]n(rnγ)[[IdA(t,s)]]n+1(γ) is inhabited, and at level 1 both sides are {}, because [[nextt]]1(γ)==[[nexts]]1(γ).

Next-Weak and Next-Exch. As in Later-Weak and Later-Exch, with the term clause of definition 162.15 in place of the type clause.

Next-Var. At level n+1, [[next[xt].x]]n+1(γ) is the value assigned to x, namely [[t]]n+1(γ). At level 1 both sides lie in the one-point set [[A]]1(γ).

Next-Force. As in Later-Force, with u in place of A.

Fix-Unfold. By theorem 162.14 the interpretation x of fixx.t satisfies x=gnextx, and gnextx is by construction the interpretation of t[next(fixx.t)/x]. ◻

Proposition 162.6 now follows: the uniqueness clause of theorem 162.14 identifies any two global elements satisfying the unfolding equation.

Remark 162.17 — The two rules left out, and what supplies them

Theorem 162.16 omits Later-Code and Later-El, which concern the universe. Interpreting them requires a semantic universe in S closed under and equipped with a code for it, and in the multi-clock calculus of section 162.5 the universes must in addition be indexed by clock contexts. That construction is carried out by Bizjak and Møgelberg, Denotational semantics for guarded dependent type theory, §7, where the universes are built so that inclusions of clock contexts give inclusions of universes commuting with the type operations on the nose [BM20]. It is not reproved here. In the remainder of this chapter the guarded stream type is interpreted directly by theorem 162.18, so no universe is needed for the productivity theorem.

Guarded streams and finite observations

Theorem 162.18 — The guarded stream object

Let Δ(N) be the constant object with Δ(N)n=N and identity restrictions. There is exactly one object X of S, up to isomorphism, with XΔ(N)×X, and it is given by Xn=Nn,rnX(a1,,an+1)=(a1,,an).

Proof of Theorem 162.18 — The guarded stream object

Proof. The displayed object is a solution. Compute both sides levelwise: (Δ(N)×X)1=N×{}=N=X1,(Δ(N)×X)n+1=N×Xn=Nn+1=Xn+1. Under these identifications the restriction map of the right-hand side sends (a1,(a2,,an+1)) to (a1,rnX(a2,,an+1))=(a1,(a2,,an)), which is the displayed rnX.

Uniqueness. Let Y satisfy YΔ(N)×Y with isomorphism i. At level 1 the right-hand side is N×{}, so i1 is a bijection Y1N=X1. Suppose i induces a bijection YnXn. At level n+1 the right-hand side is N×Yn, so in+1 composed with id×(the bijection YnXn) is a bijection Yn+1N×Xn=Xn+1. These bijections commute with the restriction maps because i does, so YX in S. ◻

Definition 162.19 — Finite observations

Let t be a closed term with t:StrN, interpreted as a global element [[t]] of the object X of theorem 162.18. For k1 the kth observation of t is obsk(t):=the kth coordinate of [[t]]nNn,for any nk.

Proposition 162.20 — The observation is well defined

For every closed t of type StrN and every k1, the coordinate named in definition 162.19 is the same for every nk.

Proof of Proposition 162.20 — The observation is well defined

Proof. [[t]] is a global element, so rnX([[t]]n+1)=[[t]]n; by theorem 162.18 that restriction deletes the last coordinate and leaves the first n unchanged. Hence for kn the kth coordinate of [[t]]n+1 equals the kth coordinate of [[t]]n, and the claim follows by induction on nk. ◻

Theorem 162.21 — Productivity of finite observations

For every closed term t with t:StrN and every k1, the observation obsk(t) is a natural number. If tu:StrN then obsk(t)=obsk(u) for every k.

Proof of Theorem 162.21 — Productivity of finite observations

Proof. By theorem 162.16 the interpretation of a closed term of type StrN is a global element of the object X of theorem 162.18, so [[t]]k is an element of Nk and its kth coordinate is a natural number; proposition 162.20 shows that no other choice of n changes it. Judgmentally equal terms have equal interpretations, again by theorem 162.16, hence equal coordinates. ◻

Theorem 162.21 is the exact repair of the failure recorded at (162.1): the definition is now accepted, and every finite observation of it is a determinate number. The following calculation exhibits those numbers.

Example 162.22 — Observations of map and nats

Write m:=[[mapsuc]] for the interpretation of the function of example 162.8. We claim mn(a1,,an)=(a1+1,,an+1). By Fix-Unfold, mapsucscons(suc(hds))((next(mapsuc))tls). At level 1 the second component lies in the one-point set, so m1(a1)=(a1+1). At level n+1, the clause for in definition 162.15 evaluates next(mapsuc) at index n, so mn+1(a1,,an+1)=FixUnfold(a1+1, mn(a2,,an+1))=IH(a1+1,,an+1+1). Now let x:=[[nats]]. By definition 162.15 the witness g for nats satisfies g1()=(0) and gn+1(w)=(0,mn(w)), so theorem 162.14 gives x1=(0),x2=(0,m1(0))=(0,1),x3=(0,m2(0,1))=(0,1,2), and by induction xn=(0,1,,n1). Hence obsk(nats)=k1.

Example 162.23 — A recursive type with a negative occurrence

The equation (162.2) rejected at the opening becomes solvable once the occurrence is guarded. Define F:SS by F(Y):=(YΔ(N)). Then D1={}N=N,Dn+1=(maps DnN at level n+1), and the same levelwise induction as in theorem 162.18 shows that DF(D) has a solution determined at each level by the previous one. The variable occurs negatively, and the solution exists because lowers the level at which the occurrence is read.

Exercise 162.3

★★☆ Compute obsk for the following closed terms of type StrN, in each case by exhibiting the witness g of theorem 162.14 and the first three levels of the fixed point: ones:=fixx.cons(suc0)x,alt:=fixx.cons0((next(λs.cons(suc0)(nexts)))x). State for each whether the value of obsk depends on k, and name the level of the model at which that dependence first appears.

Exercise 162.4

★★☆ Let be the empty type. Löb induction would give a term of type from a term of type .

  1. Compute [[]] in S and exhibit a global element of if one exists.

  2. Using theorem 162.14, determine whether [[]] has a global element, and state which level of the model decides the question.

  3. Conclude which of the two, or , is uninhabited, and state in one sentence why Löb induction is therefore consistent.

Clocks

Exercise 162.2 asks for a function whose nth output is read from the 2nth input. Each application of tl moves one step later, and the calculus of section 162.1 has no operation moving back. The addition that supplies one is a second binder: quantification over the dimension along which delays.

Definition 162.24 — Clock contexts and clock quantification

Fix a countable set of clock variables and one clock constant κ0. A clock context Δ is a finite set of clock variables, and Δκ says that κ is a member of Δ or is κ0. Every judgment of convention 162.1 and definition 162.2 is annotated with a clock context, written ΓΔ, and the modality of definition 162.2 is written κ, one for each clock κ with Δκ. All judgments are closed under clock weakening and clock substitution. The added formers are

ΓA type in Δ,κκΔ
Γκ.A type in Δ
All-F
ΓΔ,κt:AκΔ
ΓΔΛκ.t:κ.A
All-I
ΓΔt:κ.AΔκ
ΓΔt[κ]:A[κ/κ]
All-E
ΓΔ,κt:κAκΔ
ΓΔprevκ.t:κ.A
Prev

with the equations (Λκ.t)[κ]t[κ/κ]AllβΛκ.t[κ]tAllηt[κ]t[κ]ClockIrrprevκ.nextκtΛκ.tPrevβnextκ((prevκ.t)[κ])tPrevη where All-η requires κΔ, and Clock-Irr requires ΓΔt:κ.A with κ not free in A, and Δκ, Δκ.

Clock-Irr is the clock irrelevance equation: when the type does not mention the clock, the value of a clock-quantified term does not depend on which clock it is instantiated at. It is the equation that turns a guarded type into a genuinely coinductive one, and it is the hardest of the five to model.

Lemma 162.25 — Clock quantification is trivial on clock-free types

If κ is not free in A, then κ.AA, with the isomorphism given by g:=λx.Λκ.x and f:=λx.x[κ0].

Proof of Lemma 162.25 — Clock quantification is trivial on clock-free types

Proof. For one composite, f(gx)β(Λκ.x)[κ0]Allβx. For the other, let Γy:κ.A. Then g(fy)βΛκ.y[κ0]ClockIrrΛκ.y[κ]Allηy, the middle step instantiating Clock-Irr at κ=κ0 and κ=κ, which is legal because κ is not free in A. ◻

The clock constant κ0 is used in an essential way in lemma 162.25: without it, the term f has nothing to instantiate at.

Definition 162.26 — Coinductive streams

Let κ be a fresh clock and let StrNκ be the guarded stream type of definition 162.7 formed with κ. Define StrN:=κ.StrNκ, hd:=λxs.hdκ0(xs[κ0]):StrNN,tl:=λxs.prevκ.tlκ(xs[κ]):StrNStrN,cons:=λx.λxs.Λκ.consκx(nextκ(xs[κ])):NStrNStrN.

The tail is the operation that was missing. Applying tlκ inside the scope of Λκ produces a term of type κStrNκ, and Prev converts a κ under a clock binder into a κ, removing the delay.

Example 162.27 — The function rejected in ex:gdtt-zipwith

Define eoκ:=fixκφ.λxs.consκ(hdxs)(φκnextκ(tl(tlxs))):StrNStrNκ, and eo:=λxs.Λκ.eoκxs of type StrNStrN. The recursion variable φ still has a κ-type, so Fix applies; what has changed is that the argument xs has the coinductive type, so tl may be applied to it twice with no delay incurred. The typing of eoκ fails if StrN is replaced by StrNκ, because tlκ then returns a κ-type and the second application has no argument of the right type.

Theorem 162.28 — Bisimulation for guarded streams

Let s and t be closed terms of type StrN in the single-clock calculus. If obsk(s)=obsk(t) for every k1, then [[s]]=[[t]].

Proof of Theorem 162.28 — Bisimulation for guarded streams

Proof. By theorem 162.18 the interpretations are global elements of the object with Xn=Nn, so [[s]]n and [[t]]n are n-tuples. By definition 162.19 the kth coordinate of [[s]]n is obsk(s) for every kn, and likewise for t. Two n-tuples with the same coordinates are equal, so [[s]]n=[[t]]n for every n. ◻

Remark 162.29 — Guarded streams and final coalgebras

Chapter 33 defines the type of streams as the carrier of the final coalgebra of YN×Y and derives corecursion from finality. The two constructions differ in what they take as primitive.

  1. Finality gives a unique map into the carrier from every coalgebra; the productivity of a definition is then the requirement that it be presented as a coalgebra, and a definition such as (162.1) must be rewritten to expose one.

  2. Theorem 162.14 gives a unique fixed point for every map out of X; productivity is then the requirement that the recursive occurrence carry a , which example 162.8 shows is satisfied by (162.1) as written.

  3. The guarded type StrNκ is not the final coalgebra: by theorem 162.18 its stage-n elements are n-tuples, whereas the final coalgebra has infinite sequences as elements. The type that recovers the final coalgebra is κ.StrNκ, and it does so only because Clock-Irr is available. That identification is Møgelberg’s theorem for the set-based semantics and is not proved here.

Which theorem holds at which signature

The results of section 162.3section 162.4 are proved for the single-clock calculus of definition 162.2, definition 162.3 without universes. Four further systems appear in the literature, each with its own rule table, and their theorems are stated here at those signatures.

The multi-clock model. Bizjak and Møgelberg give a denotational model of guarded dependent type theory with the clock rules of definition 162.24. Their model is built from covariant presheaves over a category of time objects, with clock quantification interpreted by a presheaf of clocks. The point requiring work is Clock-Irr: to validate it, types must be interpreted as presheaves internally right orthogonal to the object of clocks, which for dependent types is a lifting condition with uniqueness of lifts. Because Hofmann–Streicher universes in that model do not satisfy the condition, the universes must be indexed by clock contexts [BM20]. This supplies the two rules omitted from theorem 162.16, at their signature and not at the one of definition 162.15.

Clocked type theory. Bahr, Grathwohl and Møgelberg replace the term former nextκ by tick variables and obtain a reduction semantics. For that calculus they prove subject reduction, confluence, and strong normalization of well-typed terms and types; decidability of the equational theory follows from the last two, since normal forms are unique and computable. They further prove canonicity in the form: if Δt:N then t reduces to sucn0 for some n, where t may contain free clock variables; and productivity in the form: if t is a closed term of the coinductive stream type and n is a closed term of N, then nthnt reduces to a numeral. Their translation from guarded dependent type theory into clocked type theory preserves equality. None of these is a theorem about the calculus of definition 162.2, whose equality is not presented by a reduction relation at all.

Guarded computational type theory. Sterling and Harper give an operational account with a clock intersection connective in place of clock quantification, enjoying clock irrelevance, and with a predicative hierarchy of universes that is not indexed by clock contexts. For that theory they prove canonicity at the Boolean type: every closed expression of type bool is equal to one of the two constants; consistency follows [SH18]. Its definitional equality is a computational one in the sense of chapter 36 and is not the judgmental equality of definition 162.3.

Guarded cubical type theory. Combining with a cubical interval is a further system with its own rule table. Nothing in section 162.1section 162.5 makes the univalence axiom available: the model of definition 162.9 interprets the identity type extensionally, and no path structure has been introduced. The combination is not used in this chapter.

Exercise 162.5

★★☆ Clock-Irr requires κ not free in A.

  1. Take A:=κN and exhibit a term t:κ.κN for which the conclusion of Clock-Irr is not derivable, saying which side condition fails.

  2. Prove κ.Aκ.κA for κ not free in A, using Prev-β and Prev-η, and state why this does not contradict remark 162.12.

Suggested first pass.

Problems exercise 162.7, exercise 162.6, and exercise 162.9 form the suggested first pass. None of these problems is a prerequisite for a later chapter.

Exercise 162.6

★★★ Theorem 162.16 verifies the equations of definition 162.3 at levels 1 and n+1. Carry out the two verifications that the proof compressed.

  1. Write, in full and as a function of n and γ, the interpretation of a delayed substitution ξ=[x1t1,,xmtm] of length m, and prove by induction on m that [[ξ.A]] is a well-formed type in the sense of definition 162.15.

  2. Verify Later-Exch and Next-Exch for m=2 by displaying both reindexings, and state the exact hypothesis on the types of x and y that makes them equal.

  3. Give a pair of assignments for which the exchange hypothesis fails and the two sides of Later-Exch denote different types.

Exercise 162.7

★★★ A guarded covector is a stream of a length given by a guarded conatural. Define the guarded conaturals by CoNκ:=fixκX.1^+^^κX and the covector family by guarded recursion over CoNκ.

  1. Give the two clauses of the family and derive the type isomorphisms CoVec01 and CoVec(succn)N×κCoVecn.

  2. Type the tail function on covectors, showing where the second isomorphism is used.

  3. Type the map function on covectors, and mark the one place where a delayed substitution of length two is unavoidable. State what the type of the recursive call would be if only the applicative rule (162.3) were available.

Exercise 162.8

★★☆ Proposition 162.6 was obtained from the model. Investigate whether it can be obtained from the calculus.

  1. Assume u satisfies ut[nextu/x] and attempt to derive ufixx.t using only definition 162.3. Identify the step that would require an induction principle for .

  2. Using Later-Id, formulate the statement IdA(u,fixx.t) as the conclusion of a Löb induction, and write the term of type IdA(u,fixx.t)IdA(u,fixx.t) that the induction requires.

  3. State the extra equation on t under which that term exists, and check it for t:=cons0x.

Exercise 162.9

★★★ Practical project.guarded-observation-evaluator Implement, in Kappa, a finite-level evaluator for the single-clock guarded calculus, and use it to compute the observations of definition 162.19.

Calculus to implement. The syntax of definition 162.2, restricted to the fragment needed for streams: N with 0 and suc, products with both projections, function types with abstraction and application, with next and , and fix. Represent terms with de Bruijn indices and implement capture-avoiding substitution. Evaluate a term at a stage n by the clauses of definition 162.15: a value at stage n is a finite tree, a -value at stage n+1 is a value at stage n, and a -value at stage 1 carries no information.

Invariant. Evaluation at stage n must never inspect a -value beyond stage n1, and the restriction map must satisfy rn(evaln+1(t))=evaln(t) for every closed term t of the fragment. The program must check this equation for every evaluated term and report a failure when it does not hold; that check is the executable form of proposition 162.20.

Concrete result. A function taking a closed term of stream type and a bound N, and returning the list obs1,,obsN.

Acceptance test. Run the program on the named inputs of example 162.8, exercise 162.3 with N=6. The outputs must be exactly nats[0,1,2,3,4,5],ones[1,1,1,1,1,1],mapsucnats[1,2,3,4,5,6],zipWith(+)natsnats[0,2,4,6,8,10]. The program must also reject the term fixx.cons(hdx)(tlx), in which the recursion variable is used at type StrN rather than StrN, and must report the offending occurrence. Produce three mutations that still run — delete the stage shift in the clause for next, evaluate at stage n instead of n1, and drop the restriction check — and confirm that each makes at least one named case fail. State explicitly that the program illustrates theorem 162.21 for finitely many programs and finitely many stages, and does not prove it.

Search the book

Type to search the local edition.