Exercise 7.6.
Let 𝑀(𝑐):=∀𝑎::𝖳𝗒.∀𝑏::𝖳𝗒.(𝑎→𝑏)→𝑐𝑎→𝑐𝑏. The kinding calculation in the context 𝑐 ::𝖳𝗒 →𝖳𝗒,𝑎 ::𝖳𝗒,𝑏 ::𝖳𝗒 gives 𝑐 𝑎,𝑐 𝑏 ::𝖳𝗒 by K-App; K-Arr forms the three arrows, and two uses of K-All give 𝑐::𝖳𝗒→𝖳𝗒⊢𝑀(𝑐)::𝖳𝗒. Thus the existential body has precisely the kind required by T-Pack. The complete final rule is ⋅⊢𝖯::𝖳𝗒→𝖳𝗒𝑐::𝖳𝗒→𝖳𝗒⊢𝑀(𝑐)::𝖳𝗒⋅;⋅⊢𝖽𝗆𝖺𝗉:𝑀(𝖯)⋅;⋅⊢𝗉𝖺𝖼𝗄[𝖯,𝖽𝗆𝖺𝗉] 𝖺𝗌 ∃𝑐::𝖳𝗒→𝖳𝗒.𝑀(𝑐):𝖬𝖺𝗉𝗉𝖾𝗋T−Pack. The third premise is the previously derived typing 𝖽𝗆𝖺𝗉 :𝖬𝖺𝗉 𝖯, since 𝑀(𝖯) =𝖬𝖺𝗉 𝖯 after unfolding the abbreviation.
If the witness is replaced by ℕ, the first premise would have to be ⋅⊢ℕ::𝖳𝗒→𝖳𝗒. Kinding instead uniquely gives ⋅ ⊢ℕ ::𝖳𝗒. The first premise therefore fails before a payload is considered: ℕ is a type, whereas this package hides a unary type constructor that can be applied to 𝑎 and 𝑏.
exercise 7.7.
Define 𝗋𝖾𝗌𝖾𝖺𝗅:=𝜆𝑐:𝖢𝗈𝗎𝗇𝗍𝖾𝗋.𝗎𝗇𝗉𝖺𝖼𝗄[𝑋,𝑧]=𝑐 𝗂𝗇 𝗉𝖺𝖼𝗄[𝑋,𝑧] 𝖺𝗌 𝖢𝗈𝗎𝗇𝗍𝖾𝗋. In the unpacking body, 𝑋::𝖳𝗒;𝑧:𝑋×((𝑋→𝑋)×(𝑋→ℕ)). Rule T-Pack uses witness 𝑋 and the variable premise for 𝑧, producing the outer type 𝖢𝗈𝗎𝗇𝗍𝖾𝗋. That result type is formed in the empty kind context: 𝑋 occurs only beneath the existential binder of 𝖢𝗈𝗎𝗇𝗍𝖾𝗋. Hence T-Unpack discharges the local 𝑋, and T-Lam gives 𝗋𝖾𝗌𝖾𝖺𝗅 :𝖢𝗈𝗎𝗇𝗍𝖾𝗋 →𝖢𝗈𝗎𝗇𝗍𝖾𝗋.
Exercise 7.8.
Inversion of the unpacking judgment supplies a kind 𝜅, a body constructor 𝐴, and the three premises Δ;Γ,𝑦:𝐷⊢𝑝:∃𝑢::𝜅.𝐴,Δ,𝑢::𝜅;Γ,𝑦:𝐷,𝑥:𝐴⊢𝑒:𝐵,Δ⊢𝐵::𝖳𝗒. The binders have been chosen fresh for 𝑑. Term substitution in the scrutinee gives the first required transformed premise Δ;Γ⊢𝑝[𝑑/𝑦]:∃𝑢::𝜅.𝐴.(1) To substitute in the body, first use constructor-context weakening on the given derivation of 𝑑: Δ,𝑢::𝜅;Γ⊢𝑑:𝐷.(2) This is the exact use of weakening under the hidden constructor. Applying term substitution to the body derivation, with 𝑥 :𝐴 in its trailing context, gives the second transformed premise Δ,𝑢::𝜅;Γ,𝑥:𝐴⊢𝑒[𝑑/𝑦]:𝐵.(3) Equivalently, one may weaken (2) through 𝑥 :𝐴 inside the variable case of that substitution induction. Neither 𝐴 nor 𝐵 changes because term substitution does not act on constructors.
The old no-escape premise still forms 𝐵 outside 𝑢. Reassembling (1), (3), and that premise gives Δ;Γ⊢𝑝[𝑑/𝑦]:∃𝑢::𝜅.𝐴Δ,𝑢::𝜅;Γ,𝑥:𝐴⊢𝑒[𝑑/𝑦]:𝐵Δ⊢𝐵::𝖳𝗒Δ;Γ⊢𝗎𝗇𝗉𝖺𝖼𝗄[𝑢,𝑥]=𝑝[𝑑/𝑦] 𝗂𝗇 𝑒[𝑑/𝑦]:𝐵T−Unpack. Capture-avoiding substitution identifies the subject in the conclusion with (𝗎𝗇𝗉𝖺𝖼𝗄[𝑢,𝑥] =𝑝 𝗂𝗇 𝑒)[𝑑/𝑦].
Exercise 7.9.
Put 𝑞+2𝑁:=(𝟢,(𝑠+2𝑁,𝑟𝑁)),𝐶+2𝑁:=𝗉𝖺𝖼𝗄[ℕ,𝑞+2𝑁] 𝖺𝗌 𝖢𝗈𝗎𝗇𝗍𝖾𝗋. Here 𝑠+2𝑁 =𝜆𝑛 :ℕ.𝗌𝗎𝖼(𝗌𝗎𝖼(𝑛)), so the ordinary product and arrow rules type the payload at ℕ ×((ℕ →ℕ) ×(ℕ →ℕ)); T-Pack gives 𝐶+2𝑁 :𝖢𝗈𝗎𝗇𝗍𝖾𝗋.
Write 𝑞 =𝑞+2𝑁, 𝑠 =𝑠+2𝑁, and 𝑟 =𝑟𝑁. Expanding every projection, the complete call-by-value contraction sequence is 𝗍𝗂𝖼𝗄2𝐶+2𝑁⟶𝗎𝗇𝗉𝖺𝖼𝗄[𝑋,𝑧]=𝐶+2𝑁 𝗂𝗇 𝑟𝑧(𝑠𝑧(𝑠𝑧𝑖𝑧))⟶𝑟𝑞(𝑠𝑞(𝑠𝑞𝑖𝑞))=𝗉𝗋2(𝗉𝗋2𝑞)(𝑠𝑞(𝑠𝑞𝑖𝑞))⟶𝗉𝗋2((𝑠,𝑟))(𝑠𝑞(𝑠𝑞𝑖𝑞))⟶𝑟(𝑠𝑞(𝑠𝑞𝑖𝑞))=𝑟(𝗉𝗋1(𝗉𝗋2𝑞)(𝑠𝑞𝑖𝑞))⟶𝑟(𝗉𝗋1((𝑠,𝑟))(𝑠𝑞𝑖𝑞))⟶𝑟(𝑠(𝑠𝑞𝑖𝑞))=𝑟(𝑠(𝗉𝗋1(𝗉𝗋2𝑞)𝑖𝑞))⟶𝑟(𝑠(𝗉𝗋1((𝑠,𝑟))𝑖𝑞))⟶𝑟(𝑠(𝑠𝑖𝑞))=𝑟(𝑠(𝑠(𝗉𝗋1𝑞)))⟶𝑟(𝑠(𝑠𝟢))⟶𝑟(𝑠(𝗌𝗎𝖼(𝗌𝗎𝖼(𝟢))))⟶𝑟(𝗌𝗎𝖼(𝗌𝗎𝖼(𝗌𝗎𝖼(𝗌𝗎𝖼(𝟢)))))⟶𝗌𝗎𝖼(𝗌𝗎𝖼(𝗌𝗎𝖼(𝗌𝗎𝖼(𝟢)))). The first step is the outer term beta contraction, the second opens the package, the next projection steps expose 𝑟, the two copies of 𝑠, and 𝟢, the next two term-beta steps advance by two each, and the final term-beta step applies the identity observer. The result is the normal numeral four. The same typed client applied to 𝐶𝑁 has the normal result two; constructor injectivity makes the two numeral normal forms distinct. Thus the common existential type enforces opacity but does not equate these two implementations.
Exercise 7.10.
Constructor reduction gives 𝖢𝗈𝗆𝗉𝖯𝖯=𝛽𝜆𝑎::𝖳𝗒.𝖯(𝖯𝑎). Apply the abstraction/action clause to 𝑄 =(𝐴0,𝐴1,𝑅). It first yields [[𝖯(𝖯𝑎)]]𝑎↦𝑄. The outer application clause applies the action of 𝖯 to the relational object denoted by 𝖯𝑎. By a second application clause, followed by the product clause, [[𝖯𝑎]]𝑎↦𝑄=[[𝖯]]∅(𝐴0,𝐴1,𝑅)=𝑅×𝑅. The endpoints of that intermediate object are 𝐴0 ×𝐴0 and 𝐴1 ×𝐴1. Applying the outer 𝖯 action and unfolding its product body once more gives [[𝖢𝗈𝗆𝗉𝖯𝖯]]∅(𝐴0,𝐴1,𝑅)=(𝑅×𝑅)×(𝑅×𝑅). This relation has endpoint types (𝐴0×𝐴0)×(𝐴0×𝐴0),(𝐴1×𝐴1)×(𝐴1×𝐴1), exactly the two constructor endpoints of 𝖢𝗈𝗆𝗉 𝖯 𝖯 applied to 𝐴0 and 𝐴1. For the nonconstant action, [[𝖣]]∅(𝐴0,𝐴1,𝑅)=[[𝑎→𝑎]]𝑎↦(𝐴0,𝐴1,𝑅)=𝑅⇒𝑅. Changing 𝑅 while keeping 𝐴0,𝐴1 fixed changes which function pairs the arrow lifting relates. Thus an arrow-kind relational object must carry an action on the relation argument, not only a pair of endpoint constructors.
exercise 7.11.
The initial states satisfy 𝑖+𝑃=(𝟢,𝗌𝗎𝖼(𝟢)), so [𝑖𝑁]𝑅+[𝑖+𝑃]. If [𝑛]𝑅+[𝑝], then 𝑝 =𝛽(𝑛,𝗌𝗎𝖼(𝑛)), whence 𝑠+𝑃𝑝=𝛽(𝗌𝗎𝖼(𝑛),𝗌𝗎𝖼(𝗌𝗎𝖼(𝑛))). This is exactly the witness for [𝑠𝑁 𝑛]𝑅+[𝑠+𝑃 𝑝]. The observer calculation is 𝑟+𝑃𝑝=𝛽𝑛=𝛽𝑟𝑁𝑛. Thus the three payload components are related at 𝑅+×((𝑅+⇒𝑅+)×(𝑅+⇒𝖤𝗊ℕ)). Existential lifting relates 𝐶𝑁 and 𝐶+𝑃. The single use of self-parametricity relates a closed 𝑘 :𝖢𝗈𝗎𝗇𝗍𝖾𝗋 →ℕ to itself at [[𝖢𝗈𝗎𝗇𝗍𝖾𝗋]] ⇒𝖤𝗊ℕ; applying it to the packages gives 𝑘 𝐶𝑁 =𝛽𝑘 𝐶+𝑃.
exercise 7.20.
The unknown-remainder display requires a row kind 𝖱𝗈𝗐, a row extension constructor {ℓ :𝐴 ∣𝜉}, and a lacks judgment 𝜉\ℓ; none belongs to the fixed-record extension.
Rules Rec-E and T-Lam give 𝗉𝗈𝗋𝗍𝖮𝖿:{𝗉𝗈𝗋𝗍:ℕ}→ℕ, while Rec-I gives 𝗌𝖾𝗋𝗏𝖾𝗋:{𝗉𝗈𝗋𝗍:ℕ,𝗌𝖾𝖼𝗎𝗋𝖾:𝖡𝗈𝗈𝗅𝐹}. At their application, T-App demands the smaller record type for the argument. The two sorted record types are distinct normal constructors, so T-Conv cannot supply it. Adding Width and Sub derives 𝑋{𝗉𝗈𝗋𝗍:ℕ,𝗌𝖾𝖼𝗎𝗋𝖾:𝖡𝗈𝗈𝗅𝐹}<:{𝗉𝗈𝗋𝗍:ℕ}Width and then 𝗌𝖾𝗋𝗏𝖾𝗋:{𝗉𝗈𝗋𝗍:ℕ,𝗌𝖾𝖼𝗎𝗋𝖾:𝖡𝗈𝗈𝗅𝐹}{𝗉𝗈𝗋𝗍:ℕ,𝗌𝖾𝖼𝗎𝗋𝖾:𝖡𝗈𝗈𝗅𝐹}<:{𝗉𝗈𝗋𝗍:ℕ}𝗌𝖾𝗋𝗏𝖾𝗋:{𝗉𝗈𝗋𝗍:ℕ}Sub. Now T-App gives 𝗉𝗈𝗋𝗍𝖮𝖿 𝗌𝖾𝗋𝗏𝖾𝗋 :ℕ from the displayed domain and argument judgments. Width and Sub add no row kind, extension constructor, or lacks predicate, so the first display remains unformed.
Exercise 7.13.
Let 𝐴(𝑋):=𝑋×((𝑋→𝑋)×(𝑋→ℕ)). The Church encoding of 𝐶𝑁 is 𝖼𝐶𝑁:=Λ𝑅::𝖳𝗒.𝜆𝑘:∀𝑋::𝖳𝗒.𝐴(𝑋)→𝑅.𝑘[ℕ]𝑞𝑁. The witness premise ℕ ::𝖳𝗒 and the payload typing 𝑞𝑁 :𝐴(ℕ) show 𝖼𝐶𝑁:𝖲𝗈𝗆𝖾𝖳𝗒(𝑋.𝐴(𝑋)).
Use the continuation 𝐾:=Λ𝑋::𝖳𝗒.𝜆𝑧:𝐴(𝑋).𝑟𝑧(𝑠𝑧(𝑠𝑧𝑖𝑧)). Under 𝑋 ::𝖳𝗒;𝑧 :𝐴(𝑋), the projections synthesize 𝑖𝑧 :𝑋, 𝑠𝑧 :𝑋 →𝑋, and 𝑟𝑧 :𝑋 →ℕ. The two step applications have type 𝑋 and the observation has type ℕ. Hence 𝐾:∀𝑋::𝖳𝗒.𝐴(𝑋)→ℕ. Opening the package with this continuation reproduces the four administrative contractions without abbreviation: 𝖼𝐶𝑁[ℕ]𝐾=(Λ𝑅.𝜆𝑘.𝑘[ℕ]𝑞𝑁)[ℕ]𝐾⟶(𝜆𝑘.𝑘[ℕ]𝑞𝑁)𝐾⟶𝐾[ℕ]𝑞𝑁⟶(𝜆𝑧:𝐴(ℕ).𝑟𝑧(𝑠𝑧(𝑠𝑧𝑖𝑧)))𝑞𝑁⟶𝑟𝑞𝑁(𝑠𝑞𝑁(𝑠𝑞𝑁𝑖𝑞𝑁)). The remaining projection and counter contractions are the native calculation and end in 𝗌𝗎𝖼(𝗌𝗎𝖼(𝟢)).
At result type ℕ, the continuation arrow in the package instance is (∀𝑋::𝖳𝗒.𝐴(𝑋)→ℕ―――――――――――)→ℕ. When 𝐴(𝑋) and ℕ contain no nested universal quantifiers, the underlined continuation has rank one. Placing that polymorphic type to the left of the enclosing arrow raises the enclosing arrow to rank two. The kind of 𝑋 is only 𝖳𝗒; the rank increase is caused by arrow position, not by a higher kind.
Exercise 7.14.
In the context 𝑏 :𝖡𝗈𝗈𝗅𝐹,𝑚 :𝖢𝗈𝗎𝗇𝗍𝖾𝗋,𝑛 :𝖢𝗈𝗎𝗇𝗍𝖾𝗋, the body tree is 𝑏:𝖡𝗈𝗈𝗅𝐹∈ΓΓ⊢𝑏:𝖡𝗈𝗈𝗅𝐹T−Var⋅⊢𝖢𝗈𝗎𝗇𝗍𝖾𝗋::𝖳𝗒Γ⊢𝑏[𝖢𝗈𝗎𝗇𝗍𝖾𝗋]:𝖢𝗈𝗎𝗇𝗍𝖾𝗋→𝖢𝗈𝗎𝗇𝗍𝖾𝗋→𝖢𝗈𝗎𝗇𝗍𝖾𝗋T−TApp𝑚:𝖢𝗈𝗎𝗇𝗍𝖾𝗋∈ΓΓ⊢𝑚:𝖢𝗈𝗎𝗇𝗍𝖾𝗋T−VarΓ⊢𝑏[𝖢𝗈𝗎𝗇𝗍𝖾𝗋]𝑚:𝖢𝗈𝗎𝗇𝗍𝖾𝗋→𝖢𝗈𝗎𝗇𝗍𝖾𝗋T−App𝑛:𝖢𝗈𝗎𝗇𝗍𝖾𝗋∈ΓΓ⊢𝑛:𝖢𝗈𝗎𝗇𝗍𝖾𝗋T−VarΓ⊢𝑏[𝖢𝗈𝗎𝗇𝗍𝖾𝗋]𝑚𝑛:𝖢𝗈𝗎𝗇𝗍𝖾𝗋T−App. Three applications of T-Lam, discharging 𝑛,𝑚,𝑏 in that order, therefore derive 𝖼𝗁𝗈𝗈𝗌𝖾𝖢𝗈𝗎𝗇𝗍𝖾𝗋:𝖡𝗈𝗈𝗅𝐹→𝖢𝗈𝗎𝗇𝗍𝖾𝗋→𝖢𝗈𝗎𝗇𝗍𝖾𝗋→𝖢𝗈𝗎𝗇𝗍𝖾𝗋.
For the false branch, the three Boolean contractions are visible after the three outer lambda contractions: 𝖼𝗁𝗈𝗈𝗌𝖾𝖢𝗈𝗎𝗇𝗍𝖾𝗋𝖿𝖺𝗅𝗌𝖾𝐹𝐶𝑁𝐶𝑃⟶∗𝖿𝖺𝗅𝗌𝖾𝐹[𝖢𝗈𝗎𝗇𝗍𝖾𝗋]𝐶𝑁𝐶𝑃⟶(𝜆𝑚:𝖢𝗈𝗎𝗇𝗍𝖾𝗋.𝜆𝑛:𝖢𝗈𝗎𝗇𝗍𝖾𝗋.𝑛)𝐶𝑁𝐶𝑃⟶(𝜆𝑛:𝖢𝗈𝗎𝗇𝗍𝖾𝗋.𝑛)𝐶𝑃⟶𝐶𝑃. Consequently the client opens 𝐶𝑃. With the states from the chapter, its two counter steps and observation are 𝑝0=(𝟢,𝟢),𝑠𝑃𝑝0⟶∗𝑝1,𝑠𝑃𝑝1⟶∗𝑝2,𝑟𝑃𝑝2⟶∗𝗌𝗎𝖼(𝗌𝗎𝖼(𝟢)).
The selected expression has the existential type 𝖢𝗈𝗎𝗇𝗍𝖾𝗋. Typing it at the representation type ℕ would reveal that the true branch used witness ℕ and would be false for the pair-state branch, whose witness is 𝑃 =ℕ ×ℕ. No rule projects an existential witness into the surrounding type, and T-Unpack deliberately prevents that witness from escaping. Assigning ℕ would therefore violate the package’s opacity invariant.
Practical route.
The package checker of exercise 12.10 is built in appendix F; its two-representation observation and scope-boundary mutation are recorded in appendix E.