Exercise 106.1.
The first product comparison uses the client domain 𝑃: 𝑃<:𝐼𝑥:𝑃⊢𝑄0(𝑥)<:𝑄1(𝑥)(𝑥:𝐼)→𝑄0(𝑥)<:(𝑥:𝑃)→𝑄1(𝑥)Π−Sub. The second uses reflexivity of the same domain: 𝑃<:𝑃𝑥:𝑃⊢𝑄1(𝑥)<:𝑄2(𝑥)(𝑥:𝑃)→𝑄1(𝑥)<:(𝑥:𝑃)→𝑄2(𝑥)Π−Sub. Transitivity gives the required comparison. Reversing only the domain premise would let a function defined merely on positive integers 𝑃 be used at a type whose domain is all integers 𝐼, because 𝑃 <:𝐼. A client may then pass −1 :𝐼. The provider has no premise that permits its body to use −1 as an element of 𝑃; the reversed rule is therefore not substitution safe.
Exercise 106.2.
The source predicate 1 ≤𝜈 entails 0 ≤𝜈, so R-Base-Sub derives 𝑅2 <:𝑅1. Under 𝑥 :𝑅1, give an occurrence of 𝑥 its singleton refinement 𝑋𝑥 ={𝜈 :𝖨𝗇𝗍 ∣𝜈 =𝑥}. Then 𝜆𝑢:𝑋𝑥.𝑢:Π𝑢:𝑋𝑥{𝜈:𝖨𝗇𝗍∣0≤𝜈−𝑥}, because the equality edges 𝑥0→𝜈 and 𝜈0→𝑥 certify 𝑥 −𝜈 ≤0. Narrowing replaces the assumption edge for 𝑅1, 𝑥0→0, by the stronger edge 𝑥−1⟶0 for 𝑅2. The result entailment still uses the two equality edges; the new bound edge is available but is not needed by the zero-weight path 𝜈 →𝑥.
The subtype premise is what permits every old use of 0 ≤𝑥. If a replacement declaration is admitted without that premise, take its unconstrained value to be 𝑥 = −1. It satisfies the replacement’s empty predicate but falsifies 0 ≤𝑥, so any old derivation using the 𝑅1 assumption can no longer be rebuilt. Thus arbitrary context replacement is not narrowing.
Exercise 106.3.
The upcast to an unknown index retains the vector constructor and its index tag. Hence the nil calculation is 𝖼𝖺𝗌𝗍[𝖵𝖾𝖼𝐴0⇐𝖵𝖾𝖼𝐴?](𝖼𝖺𝗌𝗍[𝖵𝖾𝖼𝐴?⇐𝖵𝖾𝖼𝐴0](𝗇𝗂𝗅𝐴))⟶∗𝗇𝗂𝗅𝐴. For the cons value, the retained constructor announces successor index 𝗌𝗎𝖼0. The downcast demands index 0, so its constructor/index test fails and the term reduces to 𝖾𝗋𝗋𝖵𝖾𝖼𝐴0. The first equation is the projection after the embedding of a run-time representation. It compares constructor tags and returns data; it neither compares nor erases two proof terms, so it is not proof irrelevance.
Exercise 106.4.
From 𝐹 :Π𝑥:𝐴1𝐵1, 𝑁 :𝐴2, and 𝐴2 <:𝐴1, subsumption first gives 𝑁 :𝐴1. Rule Π-E therefore derives 𝐹 𝑁 :𝐵1[𝑁/𝑥]. The codomain premise is checked before substitution in the client context Γ,𝑥:𝐴2⊢𝐵1<:𝐵2. Substitution of the already typed argument gives Γ⊢𝐵1[𝑁/𝑥]<:𝐵2[𝑁/𝑥]. A final subsumption step yields 𝐹 𝑁 :𝐵2[𝑁/𝑥]. Thus the smaller-domain context occurs in the premise, and [𝑁/𝑥] occurs only after the application and codomain comparison have both been established.
Exercise 106.5.
Use a two-element type interpretation 0 <1. Let 𝑃 <:𝐼, take 𝐵1(𝑥) =1 and 𝐵2(𝑥) =0 for every 𝑥 :𝑃, and consider Π𝑥:𝐼𝐵1(𝑥)andΠ𝑥:𝑃𝐵2(𝑥). Both products are well formed, and the domain premise 𝑃 <:𝐼 has the required contravariant orientation. The codomain premise would be 1 <:0 under 𝑥 :𝑃, which is false in the interpretation. Therefore the product subtype judgment is not derivable. The same construction with any proper domain inclusion and constant top/bottom codomain families gives the requested pair; dependence does not make the codomain check optional.
Exercise 106.6.
Write 𝐿 =𝗅𝖾𝗇(𝑎). The parameter refinement 0 −𝑖 ≤0 contributes 𝑖0→0. The then-branch test 𝑖 −𝐿 ≤ −1 contributes 𝐿−1⟶𝑖. The goal is the latter constraint itself, so the one-edge path 𝐿−1⟶𝑖 is a shortest-path certificate of weight −1. After deleting the branch assumption, set 𝐿 =0 and 𝑖 =0. The parameter constraint holds, but the goal becomes 0 ≤ −1, which is false. No certificate can be reconstructed from the remaining graph.
Exercise 106.7.
Prove the two statements simultaneously: 𝖼𝗁𝖾𝖼𝗄𝑛(𝖿𝗈𝗋𝗀𝖾𝗍𝑛(𝑣))=𝗌𝗈𝗆𝖾(𝑣),𝖼𝗁𝖾𝖼𝗄𝑛(𝑙)=𝗌𝗈𝗆𝖾(𝑣)⟹𝖿𝗈𝗋𝗀𝖾𝗍𝑛(𝑣)=𝑙. For 𝑛 =0, a vector is 𝗇𝗂𝗅; forgetting gives the empty list, and the zero checker returns 𝗌𝗈𝗆𝖾(𝗇𝗂𝗅). Conversely, the zero checker can return a vector only on the empty list, so the forgotten result is that list.
For 𝑛 =𝗌𝗎𝖼𝑚, write 𝑣 =𝖼𝗈𝗇𝗌(𝑎,𝑤). The head calculation is the reflexive equality 𝑎 =𝑎. The recursive tail equation is 𝖼𝗁𝖾𝖼𝗄𝑚(𝖿𝗈𝗋𝗀𝖾𝗍𝑚(𝑤))=𝗌𝗈𝗆𝖾(𝑤), by the induction hypothesis. The successor checker combines these two facts and returns 𝗌𝗈𝗆𝖾(𝖼𝗈𝗇𝗌(𝑎,𝑤)). Conversely, if 𝖼𝗁𝖾𝖼𝗄𝗌𝗎𝖼𝑚(𝑎 ::𝑙) =𝗌𝗈𝗆𝖾(𝖼𝗈𝗇𝗌(𝑏,𝑤)), its head test gives 𝑎 =𝑏, while its recursive call gives 𝖼𝗁𝖾𝖼𝗄𝑚(𝑙) =𝗌𝗈𝗆𝖾(𝑤). The second induction hypothesis gives 𝖿𝗈𝗋𝗀𝖾𝗍𝑚(𝑤) =𝑙; congruence of list cons with the head equality yields 𝖿𝗈𝗋𝗀𝖾𝗍𝗌𝗎𝖼𝑚(𝖼𝗈𝗇𝗌(𝑏,𝑤)) =𝑎 ::𝑙. These are all vector and list shapes accepted by the indexed checker.