exercise 25.1.
Fix the tail symbol and interpret a row prefix as its finite multiplicity function 𝑚 :𝖫𝖺𝖻𝖾𝗅 →ℕ. Then 𝑚⟨ℓ,ℓ∣𝜇⟩(ℓ)=2+𝑚𝜇(ℓ),𝑚⟨ℓ∣𝜇⟩(ℓ)=1+𝑚𝜇(ℓ). Natural-number cancellation would equate 2 and 1, so the rows are not equivalent. Operationally, a handler can consume the first occurrence and re-perform ℓ in its clause. Its input and output effects are therefore ⟨ℓ,ℓ ∣𝜇⟩ and ⟨ℓ ∣𝜇⟩. Contraction would identify those types and erase the fact that the outer request remains observable.
exercise 25.2.
Put 𝜈 =⟨𝗀𝖾𝗍,𝗉𝗎𝗍 ∣𝜉⟩. The fallback instance has premises Γ⊢𝑒:𝖨𝗇𝗍!⟨𝗋𝖺𝗂𝗌𝖾∣𝜈⟩,Γ,𝑥:𝖨𝗇𝗍⊢𝗋𝖾𝗍𝗎𝗋𝗇 𝑥:𝖨𝗇𝗍!𝜈,Γ,𝑝:𝖤𝗋𝗋𝗈𝗋,𝑘:𝟎𝜈→𝖨𝗇𝗍⊢𝗋𝖾𝗍𝗎𝗋𝗇 𝑑:𝖨𝗇𝗍!𝜈. Thus C-Handle changes 𝖨𝗇𝗍!⟨𝗋𝖺𝗂𝗌𝖾,𝗀𝖾𝗍,𝗉𝗎𝗍 ∣𝜉⟩ to 𝖨𝗇𝗍!⟨𝗀𝖾𝗍,𝗉𝗎𝗍 ∣𝜉⟩.
For the rethrower put 𝜀 =⟨𝗋𝖺𝗂𝗌𝖾,𝗀𝖾𝗍,𝗉𝗎𝗍 ∣𝜉⟩. Its premises are Γ⊢𝑒:𝖨𝗇𝗍!⟨𝗋𝖺𝗂𝗌𝖾∣𝜀⟩,Γ,𝑥:𝖨𝗇𝗍⊢𝗋𝖾𝗍𝗎𝗋𝗇 𝑥:𝖨𝗇𝗍!𝜀,Γ,𝑝:𝖤𝗋𝗋𝗈𝗋,𝑘:𝟎𝜀→𝖨𝗇𝗍⊢𝗉𝖾𝗋𝖿𝗈𝗋𝗆 𝗋𝖺𝗂𝗌𝖾 𝑝 𝗍𝗈 𝑧.𝑘𝑧:𝖨𝗇𝗍!𝜀. The last premise follows from C-Op at result 𝟎 and C-To; no value of 𝟎 is required. This instance changes 𝖨𝗇𝗍!⟨𝗋𝖺𝗂𝗌𝖾,𝗋𝖺𝗂𝗌𝖾,𝗀𝖾𝗍,𝗉𝗎𝗍 ∣𝜉⟩ to 𝖨𝗇𝗍!𝜀.
exercise 25.3.
Write the initial computation as 𝑀0. Its innermost handler is 𝐻0, so H-Forward gives 𝑀0⟶𝑀1=𝗁𝖺𝗇𝖽𝗅𝖾(𝗉𝖾𝗋𝖿𝗈𝗋𝗆 ℓ 𝑣 𝗍𝗈 𝑦.𝗁𝖺𝗇𝖽𝗅𝖾 𝑅[𝗋𝖾𝗍𝗎𝗋𝗇 𝑦] 𝗐𝗂𝗍𝗁 𝐻0) 𝗐𝗂𝗍𝗁 𝐻1. For 𝑀0, lemma 25.6 has outside context 𝐸′ =𝗁𝖺𝗇𝖽𝗅𝖾 [ ] 𝗐𝗂𝗍𝗁 𝐻1, request context 𝑅, and nearest handler 𝐻0. In 𝑀1 the request context immediately inside 𝐻1 is 𝑅1=[] 𝗍𝗈 𝑦.𝗁𝖺𝗇𝖽𝗅𝖾 𝑅[𝗋𝖾𝗍𝗎𝗋𝗇 𝑦] 𝗐𝗂𝗍𝗁 𝐻0. Hence H-Op gives 𝑀1⟶𝑒ℓ[𝑣/𝑝,(𝜆𝑧.𝗁𝖺𝗇𝖽𝗅𝖾 𝑅1[𝗋𝖾𝗍𝗎𝗋𝗇 𝑧] 𝗐𝗂𝗍𝗁 𝐻1)/𝑘]. The first body is syntactically 𝗁𝖺𝗇𝖽𝗅𝖾 𝑅[𝗉𝖾𝗋𝖿𝗈𝗋𝗆 ℓ 𝑣] 𝗐𝗂𝗍𝗁 𝐻0; because it contains a handler frame, it cannot be 𝑅′[𝗉𝖾𝗋𝖿𝗈𝗋𝗆 ℓ 𝑣] for handler-free 𝑅′. Thus the outer H-Op is not an initial root.
exercise 25.4.
Invert the typing of 𝗁𝖺𝗇𝖽𝗅𝖾 𝑅[𝗉𝖾𝗋𝖿𝗈𝗋𝗆 ℓ 𝑣] 𝗐𝗂𝗍𝗁 𝐻. If 𝐻 handles ℓ1,…,ℓ𝑛 and has output row 𝜀, the handler premise and typed hole give ⟨ℓ1,…,ℓ𝑛∣𝜀⟩≡⟨ℓ∣𝛿⟩,ℓ∉{ℓ1,…,ℓ𝑛}. The second part of cancellation exposes 𝜀 ≡⟨ℓ ∣𝜀′⟩. For fresh 𝑦 :𝑅ℓ, C-Return types the replacement hole 𝗋𝖾𝗍𝗎𝗋𝗇 𝑦 :𝑅ℓ!𝛿. Request-context replacement therefore reconstructs the input premise, and C-Handle gives Γ,𝑦:𝑅ℓ⊢𝗁𝖺𝗇𝖽𝗅𝖾 𝑅[𝗋𝖾𝗍𝗎𝗋𝗇 𝑦] 𝗐𝗂𝗍𝗁 𝐻:𝐵!𝜀. Choose 𝜀′ as the tail in C-Op; the forwarded request then has effect ⟨ℓ ∣𝜀′⟩ ≡𝜀. C-To with the displayed continuation types the reduct at 𝐵!𝜀, exactly the type of the redex.
exercise 25.5.
For ⟨ℓ1 ∣𝜇⟩ ≐⟨ℓ2 ∣𝜇⟩ with ℓ1 ≠ℓ2, rewriting the right row for ℓ1 skips ℓ2, chooses fresh 𝜈, and returns 𝑆1=[𝜇↦⟨ℓ1∣𝜈⟩],𝜀3=⟨ℓ2∣𝜈⟩. Since tail(𝜇) =𝜇 ∈dom(𝑆1), the guard fails before the recursive equation can recreate the original shape.
For ⟨ℓ1 ∣𝜇⟩ ≐⟨ℓ2,ℓ1 ∣𝜈⟩, rewriting finds the visible ℓ1 after skipping ℓ2, returns the identity and residual ⟨ℓ2 ∣𝜈⟩, and the tail equation is 𝜇 ≐⟨ℓ2 ∣𝜈⟩. Hence the MGU is [𝜇 ↦⟨ℓ2 ∣𝜈⟩].
exercise 25.6.
Expose the leftmost 𝗋𝖺𝗂𝗌𝖾 on the right. It skips 𝗀𝖾𝗍 and leaves ⟨𝗀𝖾𝗍,𝗋𝖺𝗂𝗌𝖾 ∣𝜈⟩. Exposing 𝗀𝖾𝗍 next leaves ⟨𝗋𝖺𝗂𝗌𝖾 ∣𝜈⟩. The residual equation is therefore 𝜇≐⟨𝗋𝖺𝗂𝗌𝖾∣𝜈⟩, so 𝑆 =[𝜇 ↦⟨𝗋𝖺𝗂𝗌𝖾 ∣𝜈⟩] is an MGU. Both rows become ⟨𝗋𝖺𝗂𝗌𝖾,𝗀𝖾𝗍,𝗋𝖺𝗂𝗌𝖾 ∣𝜈⟩. If 𝑇 is any other unifier, cancellation of one 𝗋𝖺𝗂𝗌𝖾 and one 𝗀𝖾𝗍 gives 𝑇𝜇 ≡⟨𝗋𝖺𝗂𝗌𝖾 ∣𝑇𝜈⟩. Define 𝑄 to agree with 𝑇 away from 𝜇; then 𝑇 =𝑄 ∘𝑆 on 𝜇,𝜈.
exercise 25.7.
After the inserted request, name the final-return, log, put, and get tails 𝜌𝑟,𝜌𝑙,𝜌𝑝,𝜌𝑔, and write 𝜀𝑓 for the single latent row of the lambda-bound callback. Working outward from the return, W solves ⟨𝗅𝗈𝗀∣𝜌𝑙⟩≐𝜌𝑟𝜌𝑟↦⟨𝗅𝗈𝗀∣𝜌𝑙⟩⟨𝗉𝗎𝗍∣𝜌𝑝⟩≐⟨𝗅𝗈𝗀∣𝜌𝑙⟩𝜌𝑙↦⟨𝗉𝗎𝗍∣𝜉⟩,𝜌𝑝↦⟨𝗅𝗈𝗀∣𝜉⟩𝜀𝑓≐⟨𝗉𝗎𝗍,𝗅𝗈𝗀∣𝜉⟩𝜀𝑓↦⟨𝗉𝗎𝗍,𝗅𝗈𝗀∣𝜉⟩⟨𝗀𝖾𝗍∣𝜌𝑔⟩≐⟨𝗉𝗎𝗍,𝗅𝗈𝗀∣𝜉⟩𝜉↦⟨𝗀𝖾𝗍∣𝜇⟩,𝜌𝑔↦⟨𝗉𝗎𝗍,𝗅𝗈𝗀∣𝜇⟩. Thus every sequence has common effect 𝐿𝜇 =⟨𝗀𝖾𝗍,𝗉𝗎𝗍,𝗅𝗈𝗀 ∣𝜇⟩, modulo exchange, and 𝜀𝑓 =𝐿𝜇. The wrapper therefore has principal scheme ∀𝜇.(𝟏𝐿𝜇⟶𝖨𝗇𝗍)𝐿𝜇⟶𝖨𝗇𝗍. Instantiating 𝜇 ↦⟨𝗋𝖺𝗂𝗌𝖾 ∣𝜈⟩ gives exactly one 𝗋𝖺𝗂𝗌𝖾 in both callback and body: ⟨𝗀𝖾𝗍,𝗉𝗎𝗍,𝗅𝗈𝗀,𝗋𝖺𝗂𝗌𝖾 ∣𝜈⟩. In the separate let-polymorphic trace, by contrast, the occurrence of 𝑓 first receives its own fresh instance of the quantified callback tail and W then unifies that instance with the surrounding sequence. The monomorphic parameter has only 𝜀𝑓, so its callback and body cannot receive independently quantified row tails. Concretely, the unmodified trace above instantiates the callback’s private 𝜈 with ⟨𝗀𝖾𝗍,𝗉𝗎𝗍 ∣𝜇⟩ and obtains 𝐸𝜇 =⟨𝗀𝖾𝗍,𝗉𝗎𝗍,𝗋𝖺𝗂𝗌𝖾 ∣𝜇⟩. There 𝗋𝖺𝗂𝗌𝖾 comes from the callback scheme; in the present wrapper it comes from instantiating the one shared tail, while the inserted 𝗅𝗈𝗀 is a fixed label of the body.
exercise 25.8.
For the body 𝗉𝖾𝗋𝖿𝗈𝗋𝗆 𝖺𝗌𝗄 (), W returns 𝑆0=𝗂𝖽,𝐴0=𝖤𝗇𝗏,𝜀0=⟨𝖺𝗌𝗄∣𝜇0⟩. Choose fresh 𝛽,𝜇. The return clause 𝗋𝖾𝗍𝗎𝗋𝗇 𝑥 reports 𝖤𝗇𝗏!𝛿𝑟; its two solve steps bind 𝛽 ↦𝖤𝗇𝗏 and 𝛿𝑟 ↦𝜇. The operation clause is inferred under 𝑢:𝟏,𝑘:𝖤𝗇𝗏𝜇→𝖤𝗇𝗏. Application 𝑘 𝑟 unifies its fresh domain with 𝖤𝗇𝗏, its fresh result with 𝖤𝗇𝗏, and its latent row with 𝜇; the two clause-result solves are then identities. The final input equation ⟨𝖺𝗌𝗄∣𝜇0⟩≐⟨𝖺𝗌𝗄∣𝜇⟩ binds 𝜇0 ↦𝜇. Hence 𝑟 :𝖤𝗇𝗏 ⊢ℎ𝑟 :𝖤𝗇𝗏!𝜇, and the principal computation scheme relative to that context is ∀𝜇.(𝖤𝗇𝗏!𝜇). The continuation annotation comes from 𝑘 :𝑅𝖺𝗌𝗄𝜇→𝛽: it is the handler output row. Giving it ⟨𝖺𝗌𝗄 ∣𝜇⟩ would incorrectly reintroduce the consumed occurrence on every resumption and would not be a premise of C-Handle.
exercise 25.9.
Set erasure maps both ⟨𝗋𝖺𝗂𝗌𝖾,𝗋𝖺𝗂𝗌𝖾 ∣𝜈⟩ and ⟨𝗋𝖺𝗂𝗌𝖾 ∣𝜈⟩ to {𝗋𝖺𝗂𝗌𝖾} ∪⌊𝜈⌋. Thus it cannot record that the rethrower consumed one occurrence. If a fallback output tail contains no 𝗋𝖺𝗂𝗌𝖾, its input erases to {𝗋𝖺𝗂𝗌𝖾} ∪⌊𝜈⌋ and its output to ⌊𝜈⌋, so ordinary set difference still distinguishes them. The erased handler is nevertheless well typed. For the rethrower, 𝐸in∖{𝗋𝖺𝗂𝗌𝖾}=⌊𝜈⌋⊆{𝗋𝖺𝗂𝗌𝖾}∪⌊𝜈⌋=𝐸out, which is exactly the target rule’s inclusion premise. What fails is faithful representation: the two source annotations above have the same support, so the target cannot say that exactly one occurrence was consumed. The fallback still changes support and therefore retains that coarser distinction.
exercise 25.10.
Use unique rows with a constrained extension ⟨ℓ ∣𝜇⟩ well formed only under ℓ ∉𝜇. The one-operation handler rule becomes Γ⊢𝑒:𝐴!⟨ℓ∣𝜇⟩ℓ∉𝜇Γ,𝑥:𝐴⊢𝑒𝑟:𝐵!𝜇Γ,𝑝:𝑃ℓ,𝑘:𝑅ℓ𝜇→𝐵⊢𝑒ℓ:𝐵!𝜇Γ⊢𝗁𝖺𝗇𝖽𝗅𝖾 𝑒 𝗐𝗂𝗍𝗁 𝐻:𝐵!𝜇. W’s final equation is still 𝜀0 ≐⟨ℓ ∣𝜇⟩, but solving it generates and must discharge the predicate ℓ ∉𝜇. A principality proof now needs: sound substitutions for equations and lacks predicates; completeness of solving relative to a stated constraint theory; sound and complete constraint entailment; and factorization of every satisfying substitution through the reported substitution together with a residual constraint set. Ordinary unconstrained MGU factorization is no longer enough.
exercise 25.11.
Take a searched label ℓ and a different skipped label 𝑚: 𝜀 =⟨𝑚,𝑚 ∣𝜌⟩. If 𝑇𝜀 ≡⟨ℓ ∣𝛿⟩, the two Rw-Skip steps reduce exposure to 𝜌. Since ℓ ≠𝑚, cancellation and exchange give a row 𝛿′ such that 𝑇𝜌≡⟨ℓ∣𝛿′⟩,𝛿≡⟨𝑚,𝑚∣𝛿′⟩. Apply the induction hypothesis to the first equality. If exposure of 𝜌 returns (𝑆,𝜌′), there is 𝑄 with 𝑇 =𝑄𝑆 on 𝜌 and 𝛿′ ≡𝑄𝜌′. Exchange gives ⟨𝑚,𝑚,ℓ∣𝑄𝜌′⟩≡⟨ℓ,𝑚,𝑚∣𝑄𝜌′⟩, so the residual is ⟨𝑚,𝑚 ∣𝜌′⟩ and the same 𝑄 is the factor. Cancellation removes the one exposed ℓ but retains both 𝑚 occurrences. Treating the prefix as a set would collapse them and could not justify this residual equality; multiplicity is used exactly there.
exercise 25.12.
For one operation, inversion supplies declarative body, return, and operation derivations with common output 𝑇𝛽!𝑇𝜇 and input ⟨ℓ ∣𝑇𝜇⟩. The body induction hypothesis gives 𝑇 =𝑅0𝑄0 after 𝑄0 =𝑆0. The return-clause hypothesis factors through 𝑆𝑟𝑄0; the residual solves 𝐵𝑟 ≐𝛽 and 𝛿𝑟 ≐𝜇. Two applications of MGU factorization produce residuals 𝑅1𝑟,𝑅𝑟 with 𝑇 =𝑅𝑟𝑄𝑟.
Infer the operation clause under 𝑝 :𝑃ℓ,𝑘 :𝑅ℓ𝜇→𝛽. Its induction hypothesis gives a residual after 𝑆1𝑄𝑟; inversion says it solves 𝐵1 ≐𝛽 and 𝛿1 ≐𝜇. The corresponding MGUs produce 𝑄11,𝑄𝑐1 and a residual 𝑅1 with 𝑇 =𝑅1𝑄𝑐1. Finally the inverted body premise solves 𝜀0≐⟨ℓ∣𝜇⟩. Its MGU gives 𝑄′ and 𝑅′ with 𝑇 =𝑅′𝑄′. The rules paired with these four stages are respectively the body induction hypothesis, return-clause C-Handle premise, operation-clause premise, and handler-input premise; every equation uses the MGU theorem, so 𝑄′ is principal.
exercise 25.13.
Let 𝐻0 omit 𝗋𝖺𝗂𝗌𝖾 and let 𝐻1 handle it. If the inner body has effect ⟨𝗋𝖺𝗂𝗌𝖾 ∣𝛿⟩, forwarding inversion and cancellation force the output of 𝐻0 to be equivalent to ⟨𝗋𝖺𝗂𝗌𝖾 ∣𝛿′⟩. The first root is therefore typed by H-Forward at that same row. Its reduct exposes the request immediately inside 𝐻1, whose H-Op premise consumes that occurrence and returns at the outer output row 𝛿′.
Operationally the nearest-handler decompositions are exactly those in the solution to exercise 25.3; there is no competing outer root. If the final row is ⟨⟩, progress permits only a return or a step: an exposed 𝗋𝖺𝗂𝗌𝖾 would require positive 𝗋𝖺𝗂𝗌𝖾-multiplicity in the final row, contradicting its zero multiplicity. Thus forwarding cannot turn a fully handled closed program into an unhandled terminal request.
exercise 25.14.
For unique rows use an exposure judgment 𝐶⊢𝜀⇓ℓ(𝑆,𝜀′;𝐶′) whose variable-tail rule chooses fresh 𝜈, returns 𝑆 =[𝜇 ↦⟨ℓ ∣𝜈⟩], and adds ℓ ∉𝜈 to 𝐶′. Head and skip rules retain and normalize the constraints; every extension carries the well-kindedness premise that its head is absent from its tail. Factorization must say that if 𝑇 satisfies 𝐶 and exposes ℓ, then 𝑇 =𝑄𝑆 on the input variables, 𝑄 satisfies 𝐶′, and the target residual is 𝑄𝜀′.
The one-operation W handler case infers the body and clauses as in the chapter, then solves 𝜀0 ≐⟨ℓ ∣𝜇⟩ together with ℓ ∉𝜇. Its result is principal only relative to the residual lacks constraint: every other typed instance factors through the substitution and entails that residual. Duplicate rows avoid precisely this constraint judgment, its entailment theorem, and the constraint component of factorization; their exposure result (25.11) is an ordinary substitution MGU.
Exercise 31.9.
Let 𝑤0=⟨⟩⟩,𝑤1=⟨ℓ:(𝑚1,ℎ1,𝑤0)∣𝑤0⟩⟩,𝑤2=⟨ℓ:(𝑚2,ℎ2,𝑤1)∣𝑤1⟩⟩. Selection gives 𝑤2.ℓ =(𝑚2,ℎ2,𝑤1). The newest entry therefore yields to 𝑚2, not 𝑚1, using a clause from ℎ2. Internal safety requires both prompts to be reachable from source-generated handler steps; theorem 31.28 then forbids reusing 𝑚1 for the inner prompt. In the displayed 𝐹𝑝𝑤 perform contraction, the lookup binds 𝑤2.ℓ =(𝑚2,ℎ2,𝑤1) but the reduct uses only 𝑚2 and ℎ2. The retained third component belongs to the later tail-resumptive optimization, whose 𝗎𝗇𝖽𝖾𝗋 rules are outside the frozen card.
Exercise 31.10.
One suitable type is 𝗋𝖾𝖼𝗈𝗏𝖾𝗋:(1→{𝗋𝖺𝗂𝗌𝖾}∪𝛽𝐴)→(𝐸→𝛽∖{𝗋𝖺𝗂𝗌𝖾}𝐴)→1→𝛽𝐴. The recovery clause checks its handler body under 𝜑 =𝛽 ∖{𝗋𝖺𝗂𝗌𝖾}. Boolean algebra gives 𝜑∩{𝗋𝖺𝗂𝗌𝖾}=(𝛽∩{𝗋𝖺𝗂𝗌𝖾}𝖼)∩{𝗋𝖺𝗂𝗌𝖾}≡𝖡∅, which is the Ex-Without premise. A duplicate-row variable 𝜇 may be instantiated by a row containing 𝗋𝖺𝗂𝗌𝖾, so it entails no absence. A positive extension ⟨ℓ ∣𝜇⟩ only adds an occurrence; it places no constraint on the tail. The negative property therefore requires the separate Boolean row theory.