Lectures onType Theory
Declaration processing, copatterns, and erasure
appendix sectionrules

Declaration processing, copatterns, and erasure

Signed positivity and generated induction

For the families I of one mutual component, direct occurrences pass only at positive sign with an open ancestry flag. Function domains reverse sign and block recursive occurrences: DIϵ=+δ=openIFam(A)=I;ϵ;δDA pos,I;ϵ;blockedA posI;ϵ;δB posI;ϵ;δx:AB pos. An external type-level application Ha, including a local type-family variable or a family accepted earlier, passes at either sign exactly when its head and arguments are block-family-free; a covariant occurrence such as List(D) is positive but needs an All combinator the target does not have. Identity IdB(u,v) and primitive Vec(B,n) pass exactly when all displayed type and term arguments are block-family-free. A type-level eliminator or projection headed by ind2, indN, J, vind, pr1, or pr2 passes exactly when all its immediate subterms are block-family-free; the checker does not reduce that head. A strict lift passes when its argument passes at the same state. The Kappa companion of chapter 122 implements only the five-node subgrammar through external-head application, not these identity, vector, opaque-elimination, or lift clauses.

Every accepted binder x:A contributes the hypothesis type. For a pair type y:BA, choose wFV(B)FV(A)FV(P){x,y}, and put σx:=[π1x/y,π2x/w]: HP(A,x):=1(no family of I in A),HP(Dtpv,x):=Ptpvx,HP(y:BA,x):=y:BHP(A,xy),HP(y:BA,x):=HP(B,π1x)×HP(A,w)[σx],HP(LiftuA,x):=HP(A,x), so a field of type ND receives (y:N)PD(xy) rather than nothing. The Π clause is legitimate only because B was checked at negative sign, hence cannot mention the block.

The computation rule also needs a generated term of that type. With the simultaneous eliminators in scope, define ihP(A,x):=(A is family-free),ihP(Dtpv,x):=indt(p,v,x),ihP(y:BA,x):=λy.ihP(A,xy),ihP(y:BA,x):=(ihP(B,π1x),ihP(A,w)[σx]),ihP(LiftuA,x):=ihP(A,x). The family-free clause takes precedence. The nonpositive-family-free lemma ensures that the recursive calls in the function clause are made only beneath an accepted family-free domain.

Strict positivity is a premise of Block-I, not only a source-side filter. Without it a field of type DpiN would be admitted, and blindly applying the function clause would yield y:Dpi1, a hypothesis quantifying over the family being defined. The hypothesis recursion is total only on accepted binder types.

Datatype rejection returns DataReject(ϕ,Dr,cs,ω,E,O) from definition 122.5. Phase order, declaration order, binder order, and type-preorder make the record deterministic; its expected and observed fields name the exact failed rule premise.

The component is formed simultaneously. Given its motives and one method per constructor, Tfam-block supplies indr:(p:Δp)(i:Δr)(z:Drpi)Prpiz and, for every constructor cs, the rule indrs(p,us,cs(z))bs(z,zih)(Blockcomp). Here zih inserts ihP(A,z) immediately after every field z:A whose type mentions the block, including function- and pair-nested occurrences. Writing lev(Δ) for the maximum universe inhabited by a binder type in Δ, the generated eliminator package has level max(lev(Δp),maxrlev(Δr),maxslev(Θs),maxrr,maxrkr). The encoded empty target has the independent fixed definition and typing EmptyTimpl:=X:U0X:U1. No-confusion is stated at one index instance. For ı:Δr and arguments with us[a]ıut[b], distinct constructor tags eliminate IdDrpı(cs(a),ct(b)) into EmptyTimpl; equal tags produce aΘsb, the homogeneous telescopic equality of their arguments. Without the index premise the identity type is not well formed, because the two constructor applications need not inhabit the same type.

Certified recursive calls

A structural certificate is uChild(x)Θ;xudescx. A structural component over a mutual block B=(D1,,Dr) at common parameters p stores, independently of the q functions, a family map κ:Finind(q)Finind(r). Only this discipline has κ. It uses the total-space carrier LB:=max(0,maxllev(Δl),maxll),PayloadB(l):=ı:ΔlDlpı:ULB, where the payload family is defined by the dependent eliminator for Finind(r), inserting strict lifts into the common universe when required. Then CarrierB(p):=l:Finind(r)PayloadB(l):ULB and the uniform relation generated by childc,r:DChildB((k,(ȷ,xr)),(l,(ı,cx))) for each recursive field xr:Dkpȷ of a constructor c:ΘDlpı. The stored uChild(x) certificate selects one such generator after the leaf substitution. Thus the tagged call relation is defined uniformly on all inputs, rather than by a leaf-specific child set. This relation is a nonrecursive Timpl-data block at KB=max(lev(Δp),LB,maxslev(Θs)), the maximum emitted by definition 122.13; its constructor telescopes contain no occurrence of the relation, so positivity accepts it. A primitive structural component uses either childsuc:DChildN(n,sucn) or, at fixed c, childvcons:DChildVec(c,)((n,xs),(sucn,vcons(n,a,xs))). Accessibility follows from mutual block induction, Nat-elim, or Vec-elim, respectively. The three carriers and state-constructor maps are SXSμiS(a)BCarrierB(p)ικ(i)(api)NNapiVec(c,)n:NVec(c,n)(ni(a),api). For the one discipline chosen by the component, inj(b)RSini(a):=DChildS(μjS(b),μiS(a)). A structural component fixes one common block parameter vector, or one common vector element code. It never coerces a primitive carrier into the mutual block carrier. A lexicographic certificate selects the least k for which ahbh for h<k and bkRkak. The compiled body replaces a call at b by the accessibility recursor hypothesis applied to this stored predecessor proof. Rejection returns RecReject(S,fifj,ω,δ,a,b,F) from definition 123.5. The record names the first internal call without a complete direct-child or least-coordinate predecessor proof and stores the failed comparison rather than a fixture-specific message. For each recursive component S, compilation first generates the nonrecursive Timpl-data block StateS:U,ini:(a:Δi)StateS(fiS). No constructor argument mentions the generated family, so positivity accepts the block. The relation RS and the accessibility recursor range over these state constructors; the generated signature is program data, not a Timpl-rec-core rule. For accepted groups, the signature ΣG contains every fixed Timpl contraction and every generated Block-comp equation used by its clause trees and state blocks. The source program root families are those contractions and R-Call. The target replaces R-Call by the C-Call macro whose deterministic nonempty raw-core expansion is the outer definition beta prefix, generated state-block step, WF-β, and the compiler’s administrative beta prefix. Their dynamic compatible contexts do not enter compiler-generated accessibility proofs, predecessor certificates, or conversion witnesses. Nor are fixed-kernel contractions inside a compiler-marked C-Call administrative region independent target program roots; the macro schedules that whole region atomically. Then tRv and tRCv are finite closures of the respective program steps to a closed constructor normal form. Root-step correspondence treats a fixed contraction, generated block computation, and the R-Call/C-Call pair separately; dynamic-context and finite-closure induction give lemma 123.17, lemma 123.18.

Guarded stream groups

Each finite group fixes one element type A, and all its declarations have codomain Stream(A); heterogeneous streams are checked as separate groups. This side condition is what gives coiterator elaboration one map h:StateGA, where the compiler generates StateG with one constructor ini:(a:Δi)StateG per declaration. The state block is nonrecursive and accepted by Timpl-data. An edge fkg records that k tail observations have been discharged before the call. The card’s two right-side forms make k total and confine it to {0,1}: a head alias emits 0 and a tail step emits 1. A group passes exactly when its zero-weight subgraph is acyclic, which for these weights coincides with every cycle having positive total weight. Each binder retains its inherited Timpl relevance mark. For closed t:A, group-free subevaluation is defined by the extended typed NbE normalizer: tTnn=nfΣ,A(t). Its result is the unique typed βη-long normal form. The optional call-by-value implementation layer tT,cbvv is T-ValT-Vec-Cons, beginning with XvT,cbvvTVal, fT,cbvλϵ,runtime(x:A).baT,cbvvab[va/x]T,cbvvfϵ,runtimeaT,cbvvTAppR, fT,cbvλϵ,erased(x:A).bb[a/x]T,cbvvfϵ,erasedaT,cbvvTAppE. It contains T-Pair, T-Fst, and T-Snd with the exact premises aT,cbvvabT,cbvvb(a,b)T,cbv(va,vb)TPair sT,cbv(va,vb)pr1(s)T,cbvvaTFstsT,cbv(va,vb)pr2(s)T,cbvvbTSnd. For field mark κi, put a^i=vi with premise aiT,cbvvi when it is runtime, and put a^i=ai when it is erased. Then (aiT,cbvvi)κi=runtimec(a)T,cbvc(a^)TCon. eT,cbvck(a^)ek[a^/xk]T,cbvvcase e of {cj(xj)ej}jT,cbvvTCase. The Boolean rules are bT,cbvttetT,cbvvind2(x.C;et,ef,b)T,cbvvTBoolT. bT,cbvffefT,cbvvind2(x.C;et,ef,b)T,cbvvTBoolF. Put NC(e0,es;m):=IC(e0;nϱn.rϱr.es;m). The natural-number rules are mT,cbv0e0T,cbvvNC(e0,es;m)T,cbvvTNatZ mT,cbvsuc(vn)NC(e0,es;vn)T,cbvvres[vn/n,vr/r]T,cbvvNC(e0,es;m)T,cbvvTNatS. Identity elimination has the rule eqT,cbvreflvqer[a/z]T,cbvvJA;a;b(x.y.p.C;zϱz.er;eq)T,cbvvTJ. The vector rules are mT,cbv0ysT,cbvvnile0T,cbvvvind(P;e0;nϱn.aϱa.xs.rϱr.es;m,ys)T,cbvvTVecNil mT,cbvsuc(vn)ysT,cbvvcons(vn,va,vxs)vind(P;e0;nϱn.aϱa.xs.rϱr.es;vn,vxs)T,cbvvres[vn/n,va/a,vxs/xs,vr/r]T,cbvvvind(P;e0;nϱn.aϱa.xs.rϱr.es;m,ys)T,cbvvTVecCons. There is no T-Call rule. The implementation card is not the meaning of T. The accepted NbE normalizer is extended declaration-by-declaration with the nonrecursive Timpl-data constructor, neutral-eliminator, and Block-comp cases. It satisfies tT,cbvvnf(t)=nf(v)andtTnf(v), whereas tTn always returns n=nf(t). Soundness, completeness, stability, substitution, and the implementation bridge are lemma 124.3. The function prepΔ(a) processes a dependent tuple in telescope order. It normalizes a runtime component as demanded subevaluation and canonicalizes an erased component statically with the same typed normalizer; both results are substituted into later components. No runtime CBV frame forces an erased component. Its clauses are prep()=,prepΔ,xruntime:A(a,b)=(v,w)if prepΔ(a)=v and b[v/x]Tw,prepΔ,xerased:A(a,b)=(v,n)if prepΔ(a)=v and n=nfΣ,A[v/x](b[v/x]). The big-step rules are δco(fi)=(Δi;t;et)prepΔi(a)=avt[av/x]Tvhead(fia)vCoHeadProducer, δco(fi)=(Δi;head(gu);et)prepΔi(a)=avprepΔg(u[av/x])=bhead(gb)vhead(fia)vCoHeadAlias, δco(fi)=(Δi;eh;gu)prepΔi(a)=avprepΔg(u[av/x])=btail(fia)gbCoTailUnfold. A closed well-typed group-free tuple has a unique prepared form by lemma 124.3. Preparation composes with group-free simultaneous substitution and is idempotent on prepared tuples; these are lemma 124.12, lemma 124.13. Those two facts justify alias resolution and the generalized induction step in the source/coiterator simulation. A bare stream call has no eager unfolding rule. Observation words and their path rules are o::=headtailo,head(s)vsheadv, and tail(s)ssovstailov. Coiterator elaboration computes by head(coiter(h,t,s))0h(s),tail(coiter(h,t,s))0coiter(h,t,t(s)). Its normalizer-defined state-strict evaluation rules are sTsvh(sv)Tvhead(coiter(h,t,s))vCoiterHead and sTsvt(sv)Tsvtail(coiter(h,t,s))coiter(h,t,sv)CoiterTail.

Dependent copattern frontiers

For a row map ρ^r:ΘrΔ, static acceptance checks Θrer:Ajr[d@Δρ^r/z][ur,<jr/π<jr]. Closed right sides use w::=vda and e contains no call to the copattern groupeTveCvCopatResultVal, d:(Δ)Rpı(blTal)lΔd@ΔbCd@ΔaCopatResultRec. The least matching row for one demanded field is selected only at a closed well-typed ready tuple, using the matching relation of definition 121.6: a is closed, well typed, and readymatches(pr,a,θr)(θq.matches(pq,a,θq))q<r,jq=jrerθrCwdaπjrwCopatRow. Longer source paths are generated only through a recursive field: jNsπjssovsπjovCopatPathStep. An unrelated record-valued nonrecursive field ends a path in this card. The intermediate case-tree relation, also restricted to closed ready tuples, is generated by Qj[a/Δ]wfields{πl(u<l)Ql}l(a)πjwTreeField, axTck(v)Qk[v/yk]wsplit(x;{cl(yl)Ql}l)[a]wTreeSplit,eσCwleaf(r,σ,e)wTreeLeaf. For the tree Qd generated for declaration d, recursive paths use jNQd(a)πjdbQd(b)ovQd(a)πjovTreePathStep. At field πj, a typed frontier records all earlier field terms: Θz:Rpiπ1(z)=u1,,πj1(z)=uj1πj(z):Aj[u/π]. Input splits transport this whole telescope by their dependency-preserving substitution. A complete field spine becomes one sequential Rec-Corec method tuple in the same order. Set kG:=max(lev(Δi),maxdGlev(Δd(ı))). The compiler generates the indexed Timpl-data family StateG:(ı:Δi)UkG,ind:(ı:Δi)(a:Δd(ı))StateG(ı). The maximum is the universe constraint supplied to the level solver. It covers every index and constructor telescope, and the family occurs in none of them, so Timpl-data formation and positivity accept the block. Abbreviate this family by S. A recursive leaf d@Δd(ıj)b translates to ind(ıj,b):Sıj. The Rec-Corec extension is checked transactionally. First place the method-independent declaration corecR:(ı:Δi)(s:Sı)Rpı in a provisional signature. After methods h1,,hj1 have checked, define their actual outputs and decoded fields in the context (ı:Δi)(s:Sı): zs:=corecRıs,vl:=hlıs,v¯l:={corecRılvl,lN,vl,lN. Write σj:=[v¯1,,v¯j1/π1(zs),,πj1(zs)]. Aj[h<j]:={Sıj,jN,Aj[zs/z]σj,jN. Thus every self occurrence is instantiated by the generated record, and later dependent fields see the record generated from each actual recursive method output, not the state itself. The sequential check is XΣ+methodsS():Φ0CorecMethNil. Σ+methodsS(h<j):Φ<jΣ+hj:(ı:Δi)(s:Sı)Aj[h<j]Σ+methodsS(hj):ΦjCorecMethSnoc. Previously checked method terms are substituted literally. Their beta rules are available, but no coprojection equation is available during method checking. Once the finite sequential judgment succeeds, the constant and the following equations are committed together: πj(corecRıs)0hjıs(jN),πj(corecRıs)0corecRıj(hjıs)(jN). for a nonrecursive and a recursive field respectively. A recursive method returns a state, never a record; substitution of v¯l is what types a later field that mentions that recursive projection. The transaction has the displayed Rec-Corec rule form ΣR card record:ΦΣS:(Δi)UkΣ+methodsS(h1,,hm):ΦΣ,corecR,(Ej)1jm signatureRecCorec, where Σ+ contains the provisional method-independent corecursor and Ej is the corresponding displayed equation. No conclusion is committed unless every method premise checks.

Consider the legal unindexed fields label:2,tail:R,flag:Id2(label(tail(z)),tt). The earlier projection label:R2 is already in scope when the flag type is formed. Translation gives v¯2=corecR(h2s),A3[h1,h2]=Id2(label(corecR(h2s)),tt).

The compiled declaration has the exact outer form Qd=λı.λa.corecRı(ind(ı,a)). For an applied compiled declaration, the deterministic nonempty relation qinc contracts only these outer beta-redexes and stops at the displayed primitive corecursor. It never selects an input branch or row, uses Block-comp, contracts a corecursor projection, or enters a method body. Field selection chooses a method first; that method then runs its own translated input-split tree. The bridge into the distinct target observation is qinccCCovqCCovCorePrepare. For a closed target object c=corecRıs, abbreviate cj(s)=corecRıjs. Then its recursive-field rule is narrow enough to display with the value-field rule: jNπj(c)0eeTvcCCπjvCoreFieldVal, jNπj(c)0corecRıj(hjıs)hjısTscCCπjcj(s)CoreFieldRec, and Core-Path-Step composes such an observation with a shorter target path only when jN.

Runtime erasure

The exact first-order source phrases are those of definition 126.3: variables, annotated abstractions and applications, dependent pairs and projections, reflexivity, Boolean, natural, identity, and vector elimination, declared constructors and cases, and saturated recursive calls. Recursive declarations are not first class. The relevance judgments begin with

Γe:A
Γe erased
Rel-Erased
xruntime:AΓ
Γx runtime
Rel-Var
Γ,xruntime:Ab runtime
Γλϵ,runtime(x:A).b runtime
Rel-Lam-R
Γf runtimeΓa runtime
Γfϵ,runtimea runtime
Rel-App-R
Γ,xerased:Ab runtimeΓa erased
Γλϵ,erased(x:A).bϵ,eraseda runtime
Rel-App-E

Rule Rel-App-E accepts only a visible administrative redex; a variable-headed erased application is rejected. Rules Rel-Con, Rel-Case, and Rel-Call require constructor fields, branches, and saturated call inputs at the relevance recorded by the accepted declaration. Dependent pairs, projections, and retained reflexivity are checked by Γa runtimeΓb runtimeΓ(a,b) runtimeRelPairΓs runtimeΓpr1(s) runtimeRelFst Γs runtimeΓpr2(s) runtimeRelSndΓa:AΓrefla runtimeRelRefl. The primitive eliminator rules are Γb runtimeΓet runtimeΓef runtimeΓind2(x.C;et,ef,b) runtimeRelBoolElim, Γe0 runtimeΓ,nϱn:N,rϱr:C(n)es runtimeΓm runtimeΓIC(e0;nϱn.rϱr.es;m) runtimeRelNatElim, Γ,zϱz:Aer runtimeΓa ϱzΓeq erasedΓJA;a;b(x.y.p.C;zϱz.er;eq) runtimeRelJ, Put V:=vind(P;e0;nϱn.aϱa.xs.rϱr.es;m,ys). Put also ΓV:=Γ,nϱn:N,aϱa:A,xsruntime:Vec(A,n),rϱr:P(n,xs). Γe0 runtimeΓVes runtimeΓm ϱmΓys runtimeΓV runtimeRelVecElim. The proof and motive of Rel-J are static. Its endpoint a is retained exactly when the branch uses z. A runtime vector index forces the predecessor constructor-field mark κn to be runtime, and the structural vector child is always runtime. A runtime branch-use mark ϱn or ϱa respectively requires the constructor-field mark κn or κa to be runtime; an erased branch may ignore a retained field. Every binder whose declared type is judgmentally a universe is erased because Texec has no universe or source-type representation. A data-valued index may be runtime only when its value forms occur in the source runtime grammar and target representation.

The source call-by-value relation ev of definition 126.5 is relevance directed. For a marked argument ai, put a^i=vi when the mark is runtime and aivi, and put a^i=ai with no evaluation premise when the mark is erased. Source and Texec share the glyph, but their disjoint grammars select disjoint rule cards. The complete source card begins XvvSValfλϵ,runtime(x:A).bavab[va/x]vfϵ,runtimeavSAppR, fλϵ,erased(x:A).bb[a/x]vfϵ,erasedavSAppE, avabvb(a,b)(va,vb)SPairs(va,vb)pr1(s)vaSFsts(va,vb)pr2(s)vbSSnd, (aivi)κi=runtimec(a1,,an)c(a^1,,a^n)SCon, eck(a^)ek[a^/xk]vcase e of {cj(xj)ej}jvSCase, bttetvind2(x.C;et,ef,b)vSBoolTbffefvind2(x.C;et,ef,b)vSBoolF, Abbreviate N(q):=IC(e0;nϱn.rϱr.es;q). m0e0vN(m)vSNatZ, msuc(vn)N(vn)vres[vn/n,vr/r]vN(m)vSNatS, eqreflvqer[a/z]vJA;a;b(x.y.p.C;zϱz.er;eq)vSJ, m0ysvnile0vvind(P;e0;nϱn.aϱa.xs.rϱr.es;m,ys)vSVecNil, msuc(vn)ysvcons(vn,va,vxs)vind(P;e0;nϱn.aϱa.xs.rϱr.es;vn,vxs)vres[vn/n,va/a,vxs/xs,vr/r]vvind(P;e0;nϱn.aϱa.xs.rϱr.es;m,ys)vSVecCons, (yjuj)σj=runtime(aivi)ϱi=runtimebf[y^/y,a^/x]vδs(f)=(yσ;xϱ;bf)fy(a)vSCall. The relation is partial on raw syntax: neutral or mismatched scrutinees and wrong-arity calls have no rule. Forward simulation assumes a source derivation. Erased arguments are checked static syntax substituted on the source side and are evaluated by neither source nor target.

Runtime binders survive and erased binders disappear: |λϵ,runtime(x:A).b|=λx.|b|,|fϵ,runtimea|=|f||a|,|λϵ,erased(x:A).b|=|b|,|fϵ,eraseda|=|f|. Pairs, projections, retained reflexivity, Boolean elimination, and identity elimination erase by |(a,b)|=Cpair(|a|,|b|),|pr1(s)|=case |s| of {Cpair(x,y)x},|pr2(s)|=case |s| of {Cpair(x,y)y},|refla|=Crefl,|ind2(x.C;et,ef,b)|=case |b| of {Ctt|et|,Cff|ef|},|JA;a;b(x.y.p.C;zϱz.er;eq)|={|er|[|a|/z],ϱz=runtime,|er|,ϱz=erased. The identity clause is structural on the checked branch derivation; marked substitution proves that it equals |er[a/z]|. Thus a proof retained by a Σ-component or constructor is not deleted; it is represented by Crefl. Constructors retain runtime fields in declaration order. A target case pattern retains a binder exactly when the corresponding constructor-field mark κi is runtime, even when its independent branch-use mark ϱi is erased; admissibility requires runtime branch use to imply runtime field retention. Recursive closures retain their tag and runtime environment. For δs(f)=(yσ;xϱ;bf), compilation creates δt(f)=(y|σ=runtime;x|ϱ=runtime;|bf|). A saturated call to one is call(clos(f,w),t).

Every primitive natural or vector eliminator occurrence o receives a stable tag νN(o) or νV(o). The natural tag stores the ordered runtime lexical slots y, one scrutinee parameter m, and the body case m of {C0|e0|,Csuc(n)|es|}, where, when the recursive hypothesis is runtime, |es| is the administrative beta-redex (λr.|es|)call(clos(νN(o),y),n). This forces the recursive call to a value before installing it in the branch, matching source call by value. The vector tag stores its ordered slots, optional runtime index, and vector scrutinee; its successor branch analogously applies λr.|es| to the recursive call(clos(νV(o),z),[n]ϱm,xs). Stable occurrence tags and fixed lexical slots make runtime substitution fill slots without regenerating tags.

Source evaluation is sound for judgmental equality: Γe:AevΓev:A. The rule induction uses computation plus substitution congruence in every dependent case; in particular it converts application results along ava, second projections along the evaluated first component, eliminator motives along evaluated indices and scrutinees, and identity branches along their endpoint equalities. Hence source evaluation preserves Timpl typing. It also preserves runtime relevance by a second induction using marked substitution; that statement supplies the relevance premise required at every runtime substitution in forward simulation.

Texec cases have pairwise distinct branch tags. Texec evaluation is deterministic left-to-right call by value. Its complete rule card begins with XwwEValt1λx.tt2w2t[w2/x]wt1t2wEApp. Constructor blocks and closures evaluate their fields from left to right: (tiwi)1inCk(t1,,tn)Ck(w1,,wn)ECon(tiwi)iclos(f,t)clos(f,w)EClos. The remaining two rules are tCk(w)tk[w/xk]wcase t of {Cj(xj)tj}jwECase δt(f)=(y;x;tf)tclos(f,w)(tiwi)itf[w/y][wi/x]wcall(t,t)wECall. Texec is untyped, so the reference invariant is target well-formedness plus the value representation relation, not a target typing judgment. A configuration with no applicable rule is stuck. Representation well-formedness excludes malformed stored arities; forward simulation, under a source evaluation derivation, constructs the matching dynamic rule sequence and excludes wrong value shapes.

Co-erasure uses the runtime-first-order card of definition 126.15. Every retained field of the element and state data types is recursively data-valued. No retained field has Π-type. Each generated map is one outer state lambda. Its body contains only variables, data constructors, pairs, reflexivity, datatype cases, and first-order instances of the four primitive eliminators. There is no internal application or named call. For such a map g, g(σ)Tn!v. g(σ)v  nf(v)=n  |v|=|n|. This is lemma 126.18; the restriction is what excludes a retained lambda whose CBV body and NbE normal body have different target syntax.

For co-erasure, fresh nullary tags satisfy δt(h)=(s;;|h(s)|), δt(t)=(s;;(λs.Cstream(clos(h,s),clos(t,s)))|t(s)|). Thus the tail tag computes the next state once and returns the next stream block; the ordinary compiled tag of t:SS would return only a state. Finite target observation is the separate judgment Obs(q,o,w), generated by call(h)wObs(Cstream(h,k),head,w)ObsHead and call(k)Cstream(h,k)Obs(Cstream(h,k),o,w)Obs(Cstream(h,k),tailo,w)ObsTail. It is not an unlisted Texec term former.

System Fi index erasure

System Fi extends Fω by index-arrow kinds, index abstraction and application, and index polymorphism. The extra clauses are (Aκ)=κ,(λiA.F)=F,(F{s})=F,(iA.B)=B. Terms are unchanged. The exact typing consequence is ΔΓΔ;Γt:AΔ;(Δ,Γ)Fωt:A. Here Δ moves index bindings to the target term context; it drops out when the term contains no free index variable.

Search the book

Type to search the local edition.