Lectures onType Theory
ch:control-operators: ch:control-operators
appendix sectionsolutions

ch:control-operators: ch:control-operators

exercise 35.1.

Let FL=throw [] to cont(K0). The complete first invocation is Lthrow 5 tocont(K0)L;FL5L;FL5L;throw 5 to []cont(K0)L;throw 5 to []cont(K0)K056. The last step uses K0=;add1[]. Replacing L by L changes only the first four states: Lthrow 5 tocont(K0)K056. In both runs the final throw transition pattern-matches the same value cont(K0), discards the current stack, and produces K05. Its right-hand side contains K0, not a modified or consumed stack. That transition is the operational evidence that the continuation is persistent rather than one-shot.

exercise 35.2.

Fix the ambient answer R, suppose K:BR, and invert T-Throw to obtain Re1:A, Re2:ContA, and the arbitrary local result B. For the push step, K:BRthrow [] to e2:ABK;throw [] to e2:AR, so the reduct evaluating e1:A is a state of result R.

For the first return, suppose Rv:A. The old top frame accepts A and produces B. The new top frame has throw v to []:ContAB by the value premise v:A; hence K;throw v to [] accepts the type of e2 and still returns R.

For the final return, state typing gives K;throw v to []:ContAR,Rw:ContA. Canonical continuations is used exactly here: w=cont(K) with K:AR. Since v:A, the reduct Kv has result type R. The discarded stack K was allowed to produce the unrelated local type B; the ambient subscript forces the restored stack K to have the same final answer R.

exercise 35.3.

Write V=Av. In the letcc clause the translated captured variable has type c:V0. If ec:(V0)0, then λk:V0.(ec[k/c])k:(V0)0=Ac. For throw, if e1:A, e2:ContA, and the arbitrary source result is B, then a:V,c:V0,ca:0,λc.ca:(V0)0. Thus e2c(λc.ca):0, λa.e2c(λc.ca):V0, and λk:Bv0.e1c(λa.e2c(λc.ca)):Bc. The binder k is unused, matching the discarded throw site.

Here are all four machine roots; in particular this includes the three throw transitions. Capture has the marked beta step (letcc c in e)cKhkβ+ec[Khk/c]Khk. The initial throw push is (throw e1 to e2)cKhkβ+e1c(λa.e2c(λc.ca)). Returning v to the first throw frame contracts the displayed a: (λa.e2c(λc.ca))vvβ+e2c(λc.cvv). Finally, returning cont(K) contracts c: (λc.cvv)Khkβ+Khkvv. Each source root therefore contributes at least one target beta step.

exercise 35.4.

Put V=Av and S=V+(V0). Expanding the two letcc clauses, both injections, and throw, then contracting administrative beta redexes, gives lemAcβλh:S0.h(inr(λa:V.h(inla))). Indeed λa.h(inla):V0, so the right injection has type S; its application to h has type 0, and abstraction gives (S0)0, the required type.

The outer occurrence h(inr(λa.h(inla))) is the first call of the supplied continuation, with apparent evidence for the right summand. If a client invokes that evidence at a:V, the inner occurrence h(inla) calls the same continuation again with evidence for the left summand. The repeated occurrence of h, rather than an equation between the two injections, is the CPS image of the change of mind.

exercise 35.5.

With Δ0=(γ::T), τ=γ, and ρ=ι, the first effect clause of theorem 35.30 is α::T.γ::T.((αιγ)ιγ)α. For an operation result α, the parameter is one function which, for every chosen γ, consumes a captured continuation αγ and produces an answer γ. Therefore γ must bind both the continuation codomain and the answer codomain. The ill-scoped alternative (γ.αγ)γ leaves the final γ free; moving the quantifier only into the continuation type also allows its instantiation to disagree with the surrounding answer. Neither is the image of the well-kinded source effect.

exercise 35.6.

The four rows are: translation(delimiter reinstated, target recursive, closure)shift0DHdeep(yes, no,+)deepDDshift0(yes, no,i+)control0SHshallow(no, yes,+)shallowSDcontrol0(no, yes,+) In the first row the handler resumption is λz.handle E[z]D; in the second the translated operation passes λx.kxh, so the reset/return code is retained. The second root contracts λw.Q[w] beneath λz, which is precisely why only that direction needs arbitrary-context i.

In the shallow rows the captured resumption is λz.E[z], with no handler, reset, or return clause. Its type may expose the same leading effect, so both target effects are defined by μα. Both displayed shallow root calculations contract only in evaluation position and hence use ordinary +.

exercise 35.7.

Under k:¬(x:Nat.x=1), the leaves and pair are 1:Nat,refl:1=1,(1,refl):x:Nat.x=1. Rule Dep-Throw-P assigns throwk(1,refl) the arbitrary local result type 0=1. Hence (0,throwk(1,refl)):x:Nat.x=1, and Dep-Callcc-P gives p0:x:Nat.x=1.

All three reductions, including the transformed throw, are witp0callcck(wit(0,throwk(wit(1,refl))))callcck00. The first step is commuting projection, the second is pair projection under number-level callcc, and the third is vacuity. Projection gives prfp0:witp0=1. Conversion along the displayed reduction gives refl:witp0=0. Taking B(x)x=0, Dep-Subst derives subst(prfp0)refl:B(1),B(1)(1=0). The absent λK rule is the call-by-name commuting rule which moves wit([]) through a captured continuation (together with its compatibility closure beneath number-level callcc). The CBV stack machine has no dependent projection root of this form.

exercise 35.8.

For a fresh u, λz.z:uu. Since the surrounding context is empty, ML-Let closes this type to i:u.uu. Instantiating the first occurrence at int gives i1:int; instantiating the second at bool gives itrue:bool. The sequencing abbreviation discards the first result, so the displayed term has type bool. Its right-hand side is a lambda, hence it satisfies values-only let.

For the unrestricted continuation-plugging calculation, assume that x has a monotype τ. Closing the type of the bound expression x relative to the context x:τ quantifies no variable: every variable free in τ is already free in the context. Thus f also has monotype τ. Typing f1 forces its domain to be int, whereas typing ftrue forces the same domain to be bool. No monotype satisfies both constraints. With x:u.uu, the let can instantiate its right-hand side at a fresh uu, close that type again, and let the two occurrences of f instantiate u separately. Thus K0[x] is typable. The plugged expression is not a term of the values-only fragment, because its let right-hand side is a variable rather than a value; it is used only to test the unrestricted evaluator’s continuation invariant. This is precisely the gap between the monomorphic premise needed to reify the continuation and the polymorphic premise available to unrestricted let-generalization.

In P, the rejected node is the outer let whose right-hand side is E=callcc(λk.λx.throw k (λy.x)): E is an application, not a syntactic value. Changing the body to f1;f1 makes the saved continuation monomorphically typable at intint, but it does not change that syntactic node. The selected values-only repair rejects it nonetheless; the theorem does not perform a finer safety analysis of individual nonvalues.

exercise 35.9.

Let K3=;add3[]. Since add3[]:NatNat, K3:NatNat. The top frame has []7:(NatNat)Nat, so K=K3;[]7:(NatNat)Nat. Writing add3v=λn.λk.k(3+n), the stack translation is (K3)hk=λn.add3vnh:Nat0,Khk=λf.7c(λa.fa(K3)hk):(NatNatc)0. Here a:Nat, f:Nat(Nat0)0, and (K3)hk:Nat0, so every application is typed.

For i=λx.x, the source run is KiK3;i[]7K3;i[]7K37K3710. On the target side the exact typed spine is Khkivβ7c(λa.iva(K3)hk)β+iv7(K3)hkβ+(K3)hk7βδh10. The first reductions pass 7 to iv, then pass its result to (K3)hk, and finally compute 3+7.

exercise 35.10.

The two branches of C return A: the left branch returns x:A, and T-Throw gives the right branch arbitrary result A from a:A and q:ContA. Thus C:(A+ContA)A, and K;C:(A+ContA)R.

Put J=K;C and J=J;inl[]. Splicing the two traces gives one run: JlemAJinr(cont(J))Kthrow a tocont(J)JaJinlaKaKa. The case-frame translation is Jhk=λs.case s of{inlxxcKhk;inrq(throw a to q)cKhk}, and the restored injection frame is Jhk=λb.Jhk(inlb). The CPS normal form from the preceding solution first supplies inr(Jhk) to Jhk; the right branch applies Jhk to av, after which the injection continuation calls Jhk again with inlav. The left branch then calls Khkav, the translation of the endpoint.

exercise 35.11.

Let D={f,r.fr; x.DH(er)},vc=λz.handle DH(E)[z]D. Then the entire root calculation is DH(E[shift0 k.e]x.er)=handle DH(E)[do(λk.DH(e))]D(λk.DH(e))vcβDH(e)[vc/k]=DH(e[(λz.E[z]x.er)/k]). The first contraction is legal only because E is 0-free. Translation preserves freeness, so the deep handler sees the translated operation before any nearer delimiter. The last equality uses translation of plugging and value substitution; it is not an extra reduction.

exercise 35.12.

Choose a target value u and define T(s)=u for every source state. For each source step ss, one has T(s)=u=T(s), hence T(s)T(s) by the empty target reduction. Nevertheless an infinite source run s0s1 translates to the constant sequence u,u,, not to an infinite target reduction. Target strong normalization says nothing about repetitions joined by zero steps.

In theorem 35.13, positivity is used when the per-source-step reductions are concatenated: T(s0)+T(s1)+T(s2)+. Because every segment contains at least one target step, infinitely many source steps yield infinitely many target steps, contradicting target strong normalization. Replacing + by invalidates exactly that inference.

exercise 35.13.

Under the value-restricted grammar, p0 is not a proof value: its outer constructor is callcc. Consequently both witp0andprfp0 are ill formed. The first was needed to commute projection through control and to convert it to 0; the second was needed for the certificate witp0=1. Hence the two premises of Dep-Subst cannot be assembled and this inconsistency derivation is blocked.

This syntactic observation is not a soundness theorem. A complete dependent control calculus must still define every evaluation context and conversion, prove substitution and preservation for all of them, and show that no other eliminator observes a nonvalue computation in a dependent type. The value restriction removes this counterexample; it does not supply those missing metatheoretic arguments.

Search the book

Type to search the local edition.