The exact signature of chapter 25 is 𝜏::=𝛼∣𝑏∣𝜏𝜀→𝜏,𝜀::=𝜇∣⟨⟩∣⟨ℓ∣𝜀⟩,𝜎::=∀¯𝛼¯𝜇.𝜏,𝜒::=∀¯𝛼¯𝜇.(𝜏!𝜀),𝑣::=𝑥∣𝑐∣𝜆𝑥.𝑒,𝑒::=𝗋𝖾𝗍𝗎𝗋𝗇𝑣∣𝑣𝑣∣𝑒𝗍𝗈𝑥.𝑒∣𝗉𝖾𝗋𝖿𝗈𝗋𝗆ℓ𝑣∣𝗁𝖺𝗇𝖽𝗅𝖾𝑒𝗐𝗂𝗍𝗁𝐻∣𝗅𝖾𝗍𝑥=𝑒𝗂𝗇𝑒,𝐻::={𝗋𝖾𝗍𝗎𝗋𝗇𝑥↦𝑒𝑟;ℓ𝑖(𝑝𝑖;𝑘𝑖)↦𝑒𝑖}𝑛𝑖=1. The handled labels are distinct. The fixed finite signature satisfies Σ(ℓ)=𝑃ℓ⇝𝑅ℓ, with every 𝑃ℓ,𝑅ℓ closed and well kinded. Constants have a fixed signature C(𝑐)=∀¯𝛼¯𝜇.𝐴 whose declarations are closed and well kinded. Row equality is the least congruence generated by ⟨ℓ1,ℓ2∣𝜀⟩≡⟨ℓ2,ℓ1∣𝜀⟩. It has no contraction equation. Substitutions preserve the type and row kinds. Computation and value generalization are gen𝑐(Γ,𝐴!𝜀)=∀(ftv(𝐴!𝜀)∖ftv(Γ)).(𝐴!𝜀),gen𝑣(Γ,𝐴)=∀(ftv(𝐴)∖ftv(Γ)).𝐴.
The value and computation judgments are generated by the following complete rules; constants have their declared closed schemes and variable instantiation is kind preserving.
Rows in common premises may be replaced by equivalent rows.
Evaluation and handler-free request contexts are 𝐸::=[]∣𝐸𝗍𝗈𝑥.𝑒∣𝗅𝖾𝗍𝑥=𝐸𝗂𝗇𝑒∣𝗁𝖺𝗇𝖽𝗅𝖾𝐸𝗐𝗂𝗍𝗁𝐻,𝑅::=[]∣𝑅𝗍𝗈𝑥.𝑒∣𝗅𝖾𝗍𝑥=𝑅𝗂𝗇𝑒. Reduction is closed under 𝐸. Its complete roots are (𝜆𝑥.𝑒)𝑣⇝0𝑒[𝑣/𝑥],𝐵𝑒𝑡𝑎(𝗋𝖾𝗍𝗎𝗋𝗇𝑣)𝗍𝗈𝑥.𝑒⇝0𝑒[𝑣/𝑥],𝑇𝑜𝗅𝖾𝗍𝑥=𝗋𝖾𝗍𝗎𝗋𝗇𝑣𝗂𝗇𝑒⇝0𝑒[𝑣/𝑥],𝐿𝑒𝑡𝗁𝖺𝗇𝖽𝗅𝖾(𝗋𝖾𝗍𝗎𝗋𝗇𝑣)𝗐𝗂𝗍𝗁𝐻⇝0𝑒𝑟[𝑣/𝑥],𝐻−𝑅𝑒𝑡𝑢𝑟𝑛. For the nearest syntactic handler, whose body context 𝑅 contains no handler frame, 𝗁𝖺𝗇𝖽𝗅𝖾𝑅[𝗉𝖾𝗋𝖿𝗈𝗋𝗆ℓ𝑖𝑣]𝗐𝗂𝗍𝗁𝐻⇝0𝑒𝑖[𝑣/𝑝𝑖,(𝜆𝑦.𝗁𝖺𝗇𝖽𝗅𝖾𝑅[𝗋𝖾𝗍𝗎𝗋𝗇𝑦]𝗐𝗂𝗍𝗁𝐻)/𝑘𝑖],𝐻−𝑂𝑝,𝗁𝖺𝗇𝖽𝗅𝖾𝑅[𝗉𝖾𝗋𝖿𝗈𝗋𝗆ℓ𝑣]𝗐𝗂𝗍𝗁𝐻⇝0𝗉𝖾𝗋𝖿𝗈𝗋𝗆ℓ𝑣𝗍𝗈𝑦.𝗁𝖺𝗇𝖽𝗅𝖾𝑅[𝗋𝖾𝗍𝗎𝗋𝗇𝑦]𝗐𝗂𝗍𝗁𝐻,𝐻−𝐹𝑜𝑟𝑤𝑎𝑟𝑑, where the first rule requires ℓ𝑖∈𝗁𝖺𝗇𝖽𝗅𝖾𝖽(𝐻) and the second requires ℓ∉𝗁𝖺𝗇𝖽𝗅𝖾𝖽(𝐻). These tests are complementary; forwarding crosses exactly one handler layer.
Row exposure is the partial operation 𝗋𝖾𝗐𝗋𝗂𝗍𝖾(𝜀,ℓ)=(𝑆,𝜀′) defined by 𝗋𝖾𝗐𝗋𝗂𝗍𝖾(⟨ℓ∣𝜀⟩,ℓ)=(𝗂𝖽,𝜀)𝑅𝑤−𝐻𝑒𝑎𝑑𝗋𝖾𝗐𝗋𝗂𝗍𝖾(⟨ℓ′∣𝜀⟩,ℓ)=(𝑆,⟨ℓ′∣𝜀′⟩)𝑅𝑤−𝑆𝑘𝑖𝑝ℓ′≠ℓ,𝗋𝖾𝗐𝗋𝗂𝗍𝖾(𝜀,ℓ)=(𝑆,𝜀′),𝗋𝖾𝗐𝗋𝗂𝗍𝖾(𝜇,ℓ)=([𝜇↦⟨ℓ∣𝜈⟩],𝜈)𝑅𝑤−𝑉𝑎𝑟, with fresh 𝜈; rewriting ⟨⟩ fails. It satisfies 𝑆𝜀≡⟨ℓ∣𝑆𝜀′⟩. The complete unifier first applies reflexivity and variable binding, then uses 𝖴(𝑎,𝑎)=𝗂𝖽𝑈−𝑅𝑒𝑓𝑙𝖴(𝑎,𝑋)=[𝑎↦𝑋]𝑈−𝑉𝑎𝑟,𝑎∉ftv(𝑋),𝑎≠𝑋𝖴(𝑋,𝑎)=𝖴(𝑎,𝑋)𝑈−𝑆𝑦𝑚,𝑋isnotavariable𝖴(𝑏,𝑏)=𝗂𝖽𝑈−𝐵𝑎𝑠𝑒𝖴(⟨⟩,⟨⟩)=𝗂𝖽𝑈−𝐸𝑚𝑝𝑡𝑦. The same-kind clash cases, tried after reflexivity and variables, are 𝖴(𝑏,𝑏′)=𝖿𝖺𝗂𝗅𝑈−𝐶𝑙𝑎𝑠ℎ−𝐵𝑎𝑠𝑒,𝑏≠𝑏′𝖴(𝑏,𝐴𝜀→𝐵)=𝖿𝖺𝗂𝗅𝑈−𝐶𝑙𝑎𝑠ℎ−𝐵𝑎𝑠𝑒𝐴𝑟𝑟𝑜𝑤𝖴(𝐴𝜀→𝐵,𝑏)=𝖿𝖺𝗂𝗅𝑈−𝐶𝑙𝑎𝑠ℎ−𝐴𝑟𝑟𝑜𝑤𝐵𝑎𝑠𝑒𝖴(⟨⟩,⟨ℓ∣𝜀⟩)=𝖿𝖺𝗂𝗅𝑈−𝐶𝑙𝑎𝑠ℎ−𝐸𝑚𝑝𝑡𝑦𝐸𝑥𝑡𝑒𝑛𝑑𝖴(⟨ℓ∣𝜀⟩,⟨⟩)=𝖿𝖺𝗂𝗅𝑈−𝐶𝑙𝑎𝑠ℎ−𝐸𝑥𝑡𝑒𝑛𝑑𝐸𝑚𝑝𝑡𝑦. A type–row equation is rejected as ill kinded before unification; U-Var fails its occurs check. Arrows solve domain, effect, then codomain: 𝑆1=𝖴(𝐴1,𝐴2),𝑆2=𝖴(𝑆1𝜀1,𝑆1𝜀2),𝑆3=𝖴(𝑆2𝑆1𝐵1,𝑆2𝑆1𝐵2),𝖴(𝐴1𝜀1⟶𝐵1,𝐴2𝜀2⟶𝐵2)=𝑆3𝑆2𝑆1. For 𝖴(⟨ℓ∣𝜀1⟩,𝜀2) expose (𝑆1,𝜀3) on the right, reject when tail(𝜀1)∈dom(𝑆1), solve 𝑆2=𝖴(𝑆1𝜀1,𝑆1𝜀3), and return 𝑆2𝑆1.
Inference reports 𝖶𝑣(Γ,𝑣)=(𝑆,𝐴) and 𝖶𝑐(Γ,𝑒)=(𝑆,𝐴,𝜀). Variables instantiate every quantifier. If C(𝑐)=∀¯𝛼¯𝜇.𝐴, the constant case replaces the displayed quantifiers by fresh variables through 𝑇, and returns (𝗂𝖽,𝑇𝐴). A lambda infers its body under a fresh monotype. The computation clauses are, in source order:
return a value and a fresh row variable;
infer both application values and unify the operator with 𝐴𝜇→𝛼;
infer both sides of sequencing and unify their effects;
infer an operation parameter, unify it with 𝑃ℓ, and return 𝑅ℓ!⟨ℓ∣𝜇⟩;
infer a let-bound computation, unify its effect with ⟨⟩, generalize its value type, and infer the body;
for a handler, infer the body as (𝑆0,𝐴0,𝜀0), choose fresh 𝛽,𝜇, and accumulate substitutions through the return clause and every operation clause. Each clause result is unified first with 𝛽 and then with 𝜇; clause 𝑖 is inferred under 𝑝𝑖:𝑃𝑖 and 𝑘𝑖:𝑅𝑖𝜇→𝛽. Finally unify 𝜀0 with ⟨ℓ1,…,ℓ𝑛∣𝜇⟩ and report 𝛽!𝜇 after the accumulated substitution.
Here is the exact handler accumulator. For a current substitution 𝑄, put 𝑅=𝖴(𝑄𝑋,𝑄𝑌),solve(𝑄;𝑋≐𝑌)=𝑅∘𝑄. Choose fresh 𝛽,𝜇, compute (𝑆0,𝐴0,𝜀0)=𝖶𝑐(Γ,𝑒), and set 𝑄0=𝑆0. Infer the return clause and compose its local substitution before solving its two outputs: (𝑆𝑟,𝐵𝑟,𝛿𝑟)=𝖶𝑐(𝑄0Γ,𝑥:𝑄0𝐴0,𝑒𝑟),𝑄0𝑟=𝑆𝑟𝑄0,𝑄1𝑟=solve(𝑄0𝑟;𝐵𝑟≐𝛽),𝑄𝑟=solve(𝑄1𝑟;𝛿𝑟≐𝜇). Starting with 𝑄𝑐0=𝑄𝑟, process operation clauses in source order: (𝑆𝑖,𝐵𝑖,𝛿𝑖)=𝖶𝑐(𝑄𝑐𝑖−1Γ,𝑝𝑖:𝑃𝑖,𝑘𝑖:𝑅𝑖𝑄𝑐𝑖−1𝜇←←←←←←←←←←→𝑄𝑐𝑖−1𝛽;𝑒𝑖),𝑄0𝑖=𝑆𝑖𝑄𝑐𝑖−1,𝑄1𝑖=solve(𝑄0𝑖;𝐵𝑖≐𝛽),𝑄𝑐𝑖=solve(𝑄1𝑖;𝛿𝑖≐𝜇). Finally set 𝑄′=solve(𝑄𝑐𝑛;𝜀0≐⟨ℓ1,…,ℓ𝑛∣𝜇⟩) and return (𝑄′,𝑄′𝛽,𝑄′𝜇). Every recursive inference call receives the environment after the current substitution; every displayed result is likewise fully substituted.
Generalized-evidence and exclusion cards
The generalized-evidence source and intermediate use 𝜀::=⟨⟩∣⟨ℓ∣𝜀⟩∣𝛼𝖾𝖿𝖿,𝑒::=𝑣∣𝑒𝑒∣𝑒𝜎∣𝗉𝗋𝗈𝗆𝗉𝗍𝑚ℎ𝑒∣𝗒𝗂𝖾𝗅𝖽𝑚𝑣,𝑞::=(𝑚,ℎ,𝑤),𝑤::=⟨⟩⟩∣⟨ℓ:𝑞∣𝑤⟩⟩. Evidence extension and selection satisfy ⟨ℓ:𝑞∣𝑤⟩⟩.ℓ=𝑞,⟨ℓ′:𝑞∣𝑤⟩⟩.ℓ=𝑤.ℓ(ℓ≠ℓ′). A prompt evaluates its body under ⟨ℓ:(𝑚,ℎ,𝑤)∣𝑤⟩⟩. An operation for label ℓ selects 𝑤.ℓ=(𝑚,ℎ,𝑤′), selects its clause from ℎ, and yields to 𝑚. Only internal-safe terms generated from source terms may contain prompt, yield, or markers.
The monadic target has ordinary higher-kinded polymorphic lambda terms and 𝖬𝗈𝗇𝜀𝐴=𝖤𝗏𝗏𝜀→𝖢𝗍𝗅𝜀𝐴. The translation judgment is Γ⊢𝑒:𝜎∣𝜀⇝𝑒′. Its representative clauses are ⟨⟨𝑣⟩⟩𝗀𝖾𝗉=𝜆𝑤:𝖤𝗏𝗏𝜀.𝖯𝗎𝗋𝖾𝜀⟨⟨𝜎⟩⟩𝗀𝖾𝗉⟨⟨𝑣⟩⟩𝗀𝖾𝗉,𝑣,⟨⟨𝑒1𝑒2⟩⟩𝗀𝖾𝗉=⟨⟨𝑒1⟩⟩𝗀𝖾𝗉▹(𝜆𝑓.⟨⟨𝑒2⟩⟩𝗀𝖾𝗉▹𝑓),⟨⟨𝗉𝖾𝗋𝖿𝗈𝗋𝗆op⟩⟩𝗀𝖾𝗉=𝗉𝖾𝗋𝖿𝗈𝗋𝗆ℓ(𝗌𝖾𝗅𝖾𝖼𝗍op). Here ▹ is the target control-monad bind: 𝑒▹𝑔 runs 𝑒 under the current evidence vector, passes a 𝖯𝗎𝗋𝖾 result to 𝑔, and extends the resumption of a 𝖸𝗂𝖾𝗅𝖽. The omitted type parameters are the explicit source annotations shown in Figure 5 and Figure 11 (Appendix E, “Full rules”) of the version-4 report [XL21]; this card does not reconstruct them by inference.
For effect exclusion, fix a finite universe U and Boolean effect formulas 𝜑::=𝛽∣∅∣{𝐹}∣𝜑𝖼∣𝜑∪𝜑∣𝜑∩𝜑. The source uses a 𝑇-prefix; this appendix renames it to 𝖤𝗑 to avoid collision with the adjacent tunnelling and System-𝖷𝗂 cards. The local runtime interface is 𝑊𝐹:=[]𝗐𝗂𝗍𝗁𝗈𝗎𝗍𝐹,𝐿𝑥,𝑒:=𝗅𝖾𝗍𝑥=[]𝗂𝗇𝑒,𝑘::=∙∣𝑊𝐹::𝑘∣𝐿𝑥,𝑒::𝑘,𝖿𝗈𝗋𝖻(∙)=∅,𝖿𝗈𝗋𝖻(𝑊𝐹::𝑘)={𝐹}∪𝖿𝗈𝗋𝖻(𝑘),𝖿𝗈𝗋𝖻(𝐿𝑥,𝑒::𝑘)=𝖿𝗈𝗋𝖻(𝑘). Configurations are ⟨𝑒∣𝑘⟩; 𝜏⊢𝑘𝑘∖𝜑 types a stack and ⊢𝑚⟨𝑒∣𝑘⟩𝗈𝗄 types a configuration. The characteristic typing, stack, and machine rules are
Γ⊢∁𝑒:𝜏∣𝜑𝜑∩{𝐹}≡𝖡∅
Γ⊢∁𝑒𝗐𝗂𝗍𝗁𝗈𝗎𝗍𝐹:𝜏∣𝜑
Ex-Without
𝜏⊢𝑘𝑘∖𝜑
𝜏⊢𝑘([]𝗐𝗂𝗍𝗁𝗈𝗎𝗍𝐹)::𝑘∖(𝜑∪{𝐹})
Ex-Forbid
⋅⊢∁𝑒:𝜏∣𝜑1𝜏⊢𝑘𝑘∖𝜑2𝜑1∩𝜑2≡𝖡∅
⊢𝑚⟨𝑒∣𝑘⟩𝗈𝗄
Ex-Machine
The machine step for 𝖽𝗈𝐹(𝑣) has the side condition 𝐹∉𝖿𝗈𝗋𝖻(𝑘). Pushing a 𝗐𝗂𝗍𝗁𝗈𝗎𝗍𝐹 expression creates the displayed forbid frame; a returned value pops it. There is no subeffecting rule.