Lectures onType Theory
Chapter 125
Chapter 125Core route

Elaborating Dependent Copattern Definitions

Fix a type A:Ui, a function q:AA, and a starting value a:A. Consider a stream record whose state is visible in its fields: next:Orbit(q,a)A,step:(z:Orbit(q,a))IdA(next(z),q(a)),tail:Orbit(q,a)Orbit(q,q(a)). The three copattern equations for iterate(q,a) return, in field order, q(a),reflq(a),iterate(q,q(a)). If a compiler translates step before recording next, it checks reflexivity against an unknown endpoint. A productive clause list is therefore not yet a typed primitive corecursor. Both intermediate translations must preserve the field dependencies.

Three frozen representations

Definition 125.1 — The dependent-copattern elaboration card

The source Tcop-clause inherits Timpl-clauses patterns and the Timpl-co stream evaluation discipline. It adds finite coinductive records whose fields form a telescope Φ=(π1:A1,,πm:Am), where Aj may mention the record parameters, indices, the self object, and earlier projections π1,,πj1. A clause left side is an ordered sequence of input patterns followed by one coprojection path. The path follows the declared field telescope and binds no variable. One finite definition group is written in indexed-fiber form d:(ı:Δi)(Δd(ı))Rpı(dG). This fibered header makes the state tag of a recursive call well typed; a surface declaration whose result index is computed from unconstrained inputs must first be elaborated to this form with its index-equality witness. That reindexing elaboration is outside Tcop-clause. For a nonrecursive field, a right side contains no call to the copattern definition group. For a recursive field, the entire right side is one saturated call d@Δb to that group, and every argument bl is group-free Timpl. Nested group calls and group calls in computational fields are outside Tcop-clause.

The intermediate Tcop-tree has leaves, indexed input-split nodes, and coprojection nodes. A coprojection node for πj carries the earlier field terms needed to instantiate Aj. The target Tcop-core is Timpl-rec-core plus the primitive record corecursor Rec-Corec of definition 125.9 for exactly these finite telescopes, and nothing else. An elaborated mutual group may generate one nonrecursive indexed state family through Timpl-data; the generated family, constructors, and eliminator are signature declarations rather than a new Tcop-core rule. Clause priority is first match. Coverage is required at every reachable constructor and coprojection node. Higher-order patterns, projection overloading, hidden eta laws, effects, and arbitrary coinductive families are outside the card.

The rule delta enables a dependent result field and its tail. It changes the case-tree typing invariant: a branch context must carry not only refined input indices but also the values of all earlier projections on the same path.

Definition 125.2 — Tcop-clause typing and source observation

For an accepted record declaration R:(Δp)(Δi)U with field telescope Φ=(π1:A1,,πm:Am), the declarations are checked from left to right under z:Rpı. The generated projection rule is Γr:RpıΓπj(r):Aj[r/z]CoprojTy. Occurrences of πl(r) for l<j in the conclusion are typed by the earlier generated rules; a mention of πl with lj makes the field telescope ill formed.

A source definition has one checked fibered header from the finite group G and finite ordered rows Mr=(pr;πjr;er). The pattern telescope pr covers (ı:Δi)(Δd(ı)) and is checked by the matrix rules of definition 121.1. Static pattern elaboration produces the symbolic, dependency-preserving row map ρ^r:Θr((ı:Δi)(Δd(ı))). If ur,l is the stored symbolic term for the earlier field πl on the same path, the right side must satisfy the single finite judgment Θrer:Ajr[d@(ı,Δd)ρ^r/z][ur,<jr/π<jr], where Θr is the refined branch context. This is a static row check; it neither chooses closed inputs nor runs the matcher. Acceptance also checks the right-side shape fixed in definition 125.1: a field outside N is group-free, while a field in N is exactly one saturated group call with group-free arguments.

Write tTv for the closed group-free Timpl evaluation recalled in definition 124.2. A closed copattern right side has one of two weak-head results w::=vda. The auxiliary judgment eCw is generated by e contains no call to the copattern groupeTveCvCopatResultVal. The recursive-result rule is d:(Δ)Rpı(blTal)lΔd@ΔbCd@ΔaCopatResultRec. Thus a recursive-field call is a weak-head record result, but its arguments must first be closed typed Timpl normal forms. No rule unfolds that record call. Source field observation is defined only for a closed tuple a that is ready for the indexed declaration telescope in the sense of definition 121.5. It reuses the relational matcher of definition 121.6; in particular, no new partial function named “match” is assumed. The root rule is a is closed, well typed, and readymatches(pr,a,θr)(θq.matches(pq,a,θq))q<r,jq=jrerθrCwdaπjrwCopatRow. Thus priority is least matching row for the demanded field, not least row in a different field. Finite paths have grammar o::=πjπjo. A one-field path uses Copat-Row; path extension uses jNsπjssovsπjovCopatPathStep. The first premise restricts extension to the declared recursive set N. A nonrecursive field may itself have an unrelated record type, but such a field ends a path in this card; admitting observations through that record would require a second record signature and translation case.

Definition 125.3 — Tcop-tree syntax and execution

The intermediate syntax is Q::=leaf(r,σ,e)split(x;{ck(yk)Qk}k)fields{πj(u<j)Qj}1jm. A leaf stores its source row, typed branch substitution, checked right side, and its group-free or saturated-recursive shape certificate. A split node stores the indexed motive and branch substitutions generated by definition 121.1. A fields node stores the complete ordered frontier; its j-th child is checked at Aj[u<j/π<j]. These requirements define the judgment ΘQ:Φ.

Execution is defined only for closed ready input tuples. It first selects the demanded field, then follows input splits, and finally evaluates the leaf: Qj[a/Δ]wfields{πl(u<l)Ql}l(a)πjwTreeField. Input splitting uses axTck(v)Qk[v/yk]wsplit(x;{cl(yl)Ql}l)[a]wTreeSplit. Finally, leaf execution is eσCwleaf(r,σ,e)wTreeLeaf. For an accepted mutual group, write Qd for the covered tree generated for declaration d. Longer paths pass from a recursive leaf to the tree of the declaration named by that leaf: jNQd(a)πjdbQd(b)ovQd(a)πjovTreePathStep. There is no rule for a missing constructor or field branch; coverage excludes those states for an accepted tree.

Definition 125.4 — Typed copattern frontier

A typed copattern frontier is a telescope Θz:Rpiπ1(z)=u1,,πj1(z)=uj1  πj(z):Aj[u/π]. The equations on the left are typed substitution data, not kernel equality reflection. The compiler realizes them by extending the branch substitution with the earlier field terms. A leaf at field πj must synthesize a right side at exactly Aj[u/π].

For iterate, the frontier at step contains next(z)=q(a). Its expected type is therefore IdA(q(a),q(a)), so reflq(a) checks. Deleting that one frontier equation recreates the opening failure.

Clauses become typed case trees

Definition 125.5 — Copattern splitting

The clauses-to-tree judgment ΘM ctQ:(Φ,j) uses the first blocking item of the first surviving row.

  1. An input constructor pattern creates the indexed split and transports the whole frontier by the restricted substitution of definition 78.9.

  2. A coprojection πj creates a field node only when every earlier field on that record path has already produced a term. It extends the frontier by πj(z)=uj before compiling later fields.

  3. A variable pattern extends the row map. An inaccessible pattern checks against the accumulated substitution and introduces no run-time branch.

  4. A leaf checks the right side against the instantiated field type and retains the first surviving source row number.

Failure reports the blocking row, input or field path, expected type, and unresolved index or missing earlier projection.

Input splitting and coprojection splitting do not commute without a proof. If an input constructor refines an index occurring in a later field type, the coprojection node must receive the refined substitution. The algorithm fixes the first blocker, so its certificate records one deterministic order.

Lemma 125.6 — Frontier substitution

Let σ:ΘΘ be a dependency-preserving substitution returned by indexed splitting. If a frontier in Θ types field πj at Aj[u/π], then its pointwise image in Θ types πj at Aj[uσ/π]σ.

Proof of Lemma 125.6 — Frontier substitution

Proof. Induct on the field position j. The first field has no earlier projection equation, so ordinary Timpl substitution gives its type. At position j+1, apply the induction hypothesis to each earlier field term. The dependency-preserving property keeps every declaration before its uses, so the substituted frontier is a telescope. Timpl substitution in Aj+1, followed by the pointwise substitutions for the earlier projections, gives the displayed type. ◻

Theorem 125.7 — Clause-to-case-tree typing

If Tcop-clause accepts a definition d and produces Q, then Q is a well-typed, covered Tcop-tree at the declaration type of d. Every leaf retains the least reachable source row and checks at the field type determined by its typed frontier.

Proof of Theorem 125.7 — Clause-to-case-tree typing

Proof. Induct on the compiler derivation. At an input split, clause specialization preserves the least row by lemma 121.4; dependent frontiers remain typed by lemma 125.6. At a coprojection node, field-order checking supplies all earlier field terms, so the frontier extension is well typed by telescope formation. Variable and inaccessible items use the stored row map and equality check. At a leaf, acceptance supplies both the right-side typing judgment at the instantiated field type and the group-free or saturated-recursive shape certificate. Coverage acceptance supplies every reachable constructor and field branch. These are all compiler rules. ◻

Lemma 125.8 — Source and case-tree observations agree

Let an accepted Tcop-clause group produce covered trees (Qd)d, and let a be a closed well-typed ready tuple for declaration d.

  1. For every declared field πj and closed weak-head result w::=vdb, daπjwQd(a)πjw. Both derivations select the same least matching row among the rows for πj.

  2. For every finite coprojection path o ending in a computational field and every closed value v, daovQd(a)ov.

Proof of Lemma 125.8 — Source and case-tree observations agree

Proof. For item 1, select the child for πj by Tree-Field and induct on that finite field tree. At a split, readiness gives a closed constructor value at the split-family position. Group-free normalization therefore returns that constructor with the same children. The specialization and default-matrix clauses of lemma 121.4 say that a source row matches the original tuple exactly when its residual row matches the selected branch, and they preserve row order. Apply the induction hypothesis in that branch. At a leaf, the stored branch substitution is the unique substitution θr collected by matches(pr,a,θr). The leaf certificate says that every earlier row for πj fails. Hence Copat-Row and Tree-Leaf have the identical final premise erθrCw. In the converse direction, inversion of the same split nodes reconstructs the constructor branches; inversion of the leaf certificate reconstructs the matching substitution and the failure of every earlier field-specific row. These are all tree-node forms.

For item 2, induct on the length of o. A one-field path is item 1. If o=πjo, inversion of either path rule gives jN, a recursive result db, and the remaining observation. Item 1 transports the first premise between source and tree. The recursive-result rule prepares every component of b as a closed value or erased normal form, so b is ready for d; apply the induction hypothesis to o, then rebuild the corresponding path rule. ◻

Exercise 125.1

★☆☆ Write the three successive frontiers for iterate(q,a). Give the expected type at each leaf and the substitution that changes the tail state from a to q(a).

Case trees become primitive eliminators

The second translation must not re-run source matching. It consumes only a typed case tree and therefore has a smaller proof surface. Its target rule is the following one, which Tcop-core adds and which definition 125.1 named but did not display.

Definition 125.9 — The Tcop-core record corecursor

Let R:(Δp)(Δi)U be a card record with field telescope Φ=(π1:A1,,πm:Am). Let N{1,,m} collect the fields whose type is a recursive occurrence Rpıj with ıj a term over Δp,Δi; no other occurrence of R is permitted in Φ. Fix a state family S:(Δi)Uk. In a provisional signature, declare the method-independent constant corecR:(ı:Δi)(s:Sı)Rpı. The provisional signature is local to the rule check and is committed only after every method below has checked. Earlier results are not represented by arbitrary binders. Instead, after methods h1,,hj1 have checked, define their actual outputs and decoded fields in the context (ı:Δi)(s:Sı) by vl(ı,s):=hlıs,v¯l(ı,s):={corecRılvl(ı,s),lN,vl(ı,s),lN. Abbreviate zs:=corecRıs. The output type of the next method uses the substitution σj[h<j]:=[v¯1(ı,s),,v¯j1(ı,s)/π1(zs),,πj1(zs)]. Its output type is Aj[h<j]:={Sıj,jN,Aj[zs/z]σj[h<j],jN. Thus a later field sees the actual output of each earlier method. A recursive output is decoded to the record generated from its state before substitution.

The sequential method judgment is generated by XΣ+methodsS():Φ0CorecMethNil. The extension rule is Σ+methodsS(h<j):Φ<jΣ+hj:(ı:Δi)(s:Sı)Aj[h<j]Σ+methodsS(hj):ΦjCorecMethSnoc. The second premise is checked with the previously checked method terms substituted literally into its codomain. Their ordinary beta and definition rules are available; no coprojection equation is available during this check. The Rec-Corec transaction first declares the displayed corecursor provisionally, then checks this finite judgment, and only then commits the constant and the following m computation rules together: πj(corecRıs)0hjıs(jN),πj(corecRıs)0corecRıj(hjıs)(jN). Only a state, never a record, is returned by a recursive method: that is what makes the rule primitive. The decoded actual output v¯l, rather than a state or an unconstrained variable, is substituted into later field types. Tcop-core adds Rec-Corec for the finite record telescopes of definition 125.1 and nothing else.

Writing Σ+ for the provisional signature and Ej(ı,s) for the corresponding displayed coprojection equation, the transaction is the signature rule ΣR card record:ΦΣS:(Δi)UkΣ+=Σ,corecR:(ı:Δi)(s:Sı)RpıΣ+methodsS(h1,,hm):ΦΣ,corecR,(Ej(ı,s))1jm signatureRecCorec. All premises are checked before the conclusion extends Σ; failure of one method therefore commits neither the constant nor any equation.

The occurrences of corecR in v¯l refer to the provisional constant introduced at stage one. Its type is method-independent, which makes the later stages well founded. Each such occurrence only reconstructs an earlier recursive projection from a state; no method returns an arbitrary R-value. A target that forbade the generated constant from method types would have to impose the stricter boundary that no later field depends on an earlier recursive projection. Tcop-core chooses the displayed simultaneous dependent-corecursor rule instead.

For a legal dependency after recursion, take the unindexed record fields label:2,tail:R,flag:Id2(label(tail(z)),tt). The projection label:R2 is introduced by the earlier field of the same record before the flag type is checked; it is not an ambient constant that mentions a record still being declared. The flag type contains no syntactic occurrence of R, so it satisfies the card. The tail method has actual output v2=h2s:S, and the flag method has type A3[h1,h2]=Id2(label(corecR(h2s)),tt),v¯2=corecR(h2s). Putting the state h2s itself in that identity type would require label to accept a state of type S although its domain is R. This example forces the decoded-field substitution without weakening the occurrence restriction.

Exercise 125.2

★☆☆ For the label–tail–flag record, derive A3[h1,h2] and v¯2 from definition 125.9. Then replace v¯2 by the state h2s and state the exact failed typing judgment.

Definition 125.10 — Generated copattern state block

For a finite accepted group G, set kG:=max(lev(Δi),maxdGlev(Δd(ı))), using the telescope-level function of definition 122.13. The generated block is StateG:(ı:Δi)UkG,ind:(ı:Δi)(a:Δd(ı))StateG(ı). The maximum is formed after the Timpl level solver has accepted every input telescope; a stuck or inconsistent maximum rejects the translation.

Lemma 125.11 — Generated state-block formation

The block of definition 125.10 is a well-formed nonrecursive Timpl-data block.

Proof of Lemma 125.11 — Generated state-block formation

Proof. Every index-binder type and every constructor-field type inhabits a universe at most kG by the two components of its defining maximum. The family does not occur in an index or constructor telescope, so every constructor scan uses a block-free argument and passes the occurrence judgment of definition 122.4. The dependency graph has one vertex and no edge. The universe-output procedure of definition 122.13 therefore emits only inequalities bounded by the displayed maximum, all of which the chosen level satisfies. Timpl-data formation supplies the family, constructors, and indexed eliminator. ◻

Definition 125.12 — Tree-to-core translation

Write Q for the following translation.

  1. A nonrecursive leaf becomes its checked group-free Timpl term. A recursive leaf is handled by item 4; no other leaf contains a group call.

  2. An input-split node becomes the corresponding generated inductive eliminator. Its motive is the result field type transported by the node’s frontier substitution.

  3. A complete sequence of coprojection nodes becomes the sequential method tuple (hj)j of one Rec-Corec instance, using the generated state block of definition 125.10. Its formation is lemma 125.11, and its constructor ind(ı,a) records both the declaration tag and its fiber input. The method for πj is checked after the methods π1,,πj1, and its type and body substitute their actual decoded outputs v¯1,,v¯j1, and substitute corecRıs for the source self object z. Thus a source occurrence of an earlier recursive projection becomes the guarded term corecRıl(hlıs), not the state hlıs. The compiled declaration itself is Qd:=λı.λa.corecRı(ind(ı,a)). Field selection therefore precedes every translated input split: the j-th method contains the input-split tree compiled from the j-th child of the fields node.

  4. A recursive leaf for the checked call d@Δd(ıj)b, whose field lies in N, becomes the tagged state ind(ıj,b):StateG(ıj). Its group-free arguments are translated componentwise. The leaf does not call the method hj being defined and never returns a record of R.

For the orbit example, the declaration has an empty fiber telescope, so the generated family has the constructor initerate:(b:A)StateG(b). The three sequential methods are h1:=λa.λs.q(a),h2:=λa.λs.reflq(a),h3:=λa.λs.initerate(q(a)). After h1 has checked, the second method’s codomain is IdA(h1as,q(a))IdA(q(a),q(a)) by ordinary beta-reduction of h1; hence h2 checks before any corecursor equation is committed. The third codomain is StateG(q(a)). The recursive field carries no record, only the state at the moved index q(a), which is where iterate(q,q(a)) is recovered. Writing Orbit(q,q(a)) in the third position instead would make the third method accept an arbitrary record and turn the corecursor back into the unrestricted fixed point that definition 125.9 excludes.

Lemma 125.13 — Coprojection method typing

If a complete Tcop-tree coprojection spine is typed at frontier Φ, then the methods generated by definition 125.12 satisfy the sequential method judgment of definition 125.9.

Proof of Lemma 125.13 — Coprojection method typing

Proof. Induct on the field position. At position one, suppose first that 1N. Case-tree typing gives a term of A1 under z:Rpı. The staged corecursor rule types corecRıs at that record type, so source substitution gives the first method at A1[corecRıs/z]. If 1N, the stored call certificate and lemma 125.11 instead give the translated leaf type Sı1. In either case, Corec-Meth-Nil followed by Corec-Meth-Snoc establishes the sequential judgment at position one. Assume that judgment holds through position j. For each lj, method typing gives the actual output vl=hlıs; decode it as itself when lN and as corecRılvl when lN. The corecursor typing rule gives every decoded term its declared field type. The frontier at field j+1 records precisely these terms. Substitute the generated self object and the decoded actual outputs into that frontier. If field j+1 is nonrecursive, theorem 125.7 and the stored group-free certificate type its translated leaf at Aj+1[hj]. If it is recursive, the stored call certificate has some tag d, moved index ıj+1, and translated arguments b:Δd(ıj+1). The generated constructor rule therefore gives ind(ıj+1,b):StateG(ıj+1), again exactly Aj+1[hj]. Rule Corec-Meth-Snoc adds the method in either case. Finite induction establishes the complete sequential method judgment. ◻

Theorem 125.14 — Case-tree-to-core typing

If Q is a well-typed covered Tcop-tree for declaration d, then Q is a Tcop-core term at the declared type of d.

Proof of Theorem 125.14 — Case-tree-to-core typing

Proof. Induct on Q. A nonrecursive leaf is typed by its group-free certificate. An input split uses the generated inductive eliminator, and the induction hypotheses type every branch at its transported motive. For a coprojection spine, lemma 125.13 gives the complete sequential method judgment required by Rec-Corec. A recursive leaf certificate types b:Δd(ıj), so the generated constructor rule types ind(ıj,b) at StateG(ıj), which is the type Aj[h<j] demanded for jN. Hence every translated node is typed, including the root. ◻

Definition 125.15 — Compiled application preparation

A compiled declaration applied to closed inputs may still have outer lambda redexes before its primitive corecursor is visible. Write qinc when a nonempty deterministic sequence contracts exactly the outer beta-redexes of Qdıa, from left to right, and stops at c=corecRı(ind(ı,a)). The sequence does not contract a Rec-Corec projection, enter a method body, evaluate a state field, or use a generated Block-comp equation. Translated input splits occur inside the demanded field method and are therefore not preparation steps.

Lemma 125.16 — Compiled application preparation is total and functional

Let Qd be a well-typed covered Tcop-tree, let a be a closed well-typed ready fiber-argument tuple at a closed ready index tuple ı, and put q=Qdıa. Either q is already a primitive corecursor object, or there is a unique object c=corecRıs with qinc. In both cases, s=ind(ı,a); preparation has not selected a field, an input branch, or a source row.

Proof of Lemma 125.16 — Compiled application preparation is total and functional

Proof. Unfold the displayed clause for Qd in definition 125.12. Successive beta-contractions substitute the closed index tuple and then the closed fiber tuple. Lambda arity fixes their order and their number. The resulting term is exactly corecRı(ind(ı,a)). If both telescopes are empty, that object was present before any contraction; otherwise the stated nonempty sequence is unique. Since no method is projected during this sequence, no field-specific split tree and hence no row can be selected. ◻

Definition 125.17 — Tcop-core observation

The target observation relation is distinct from source o. Its root-bridge rule is qinccCCovqCCovCorePrepare. For a closed generated object c=corecRıs, a nonrecursive field uses jNπj(c)0eeTvcCCπjvCoreFieldVal, where the root contraction is the j-th committed Rec-Corec equation. A recursive field exposes the decoded next object: jNπj(c)0corecRıj(hjıs)hjısTscCCπjcorecRıjsCoreFieldRec. Longer observations are generated only through recursive fields: jNcCCπjccCCovcCCπjovCorePathStep. There is no target path rule through an unrelated record-valued field, matching the source restriction in definition 125.2.

Lemma 125.18 — Case-tree and core observations agree

Let Qd be a well-typed covered tree in an accepted Tcop-clause group, and let c=(ı,a) be a closed well-typed ready argument tuple for d. For every finite coprojection path o ending in a computational field and every closed value v, Qd(c)ovQdcCCov.

Proof of Lemma 125.18 — Case-tree and core observations agree

Proof. Induct on the length of o. First suppose o=πj with jN. By lemma 125.16, outer beta-contraction exposes the unique object with state ind(ı,a) and selects no field or row. The committed Rec-Corec equation for πj exposes exactly the translated j-th child of the fields node. Induct on that finite child. A translated split is the generated datatype eliminator. Because the input tuple is ready, its scrutinee is a closed constructor value, and the corresponding Block-comp equation selects the same branch as Tree-Split. A translated leaf is the same closed group-free Timpl term with the same frontier substitution. Soundness, completeness, and functionality of group-free normalization from lemma 124.3 therefore equate its T result with the Tree-Leaf result. These arguments work in both directions by inversion of Core-Prepare, the committed field equation, and each generated Block-comp equation. They exhaust the split and leaf forms, so Core-Field-Val gives the claimed equivalence for a one-field computational path.

Now let o=πjo. Inversion of Tree-Path-Step gives jN and a recursive leaf result db. The same structural induction on the j-th child shows that its translated method normalizes to the state ind(ıj,b): at a recursive leaf, this is item 4 of definition 125.12, and the group-free normalizer evaluates the stored arguments in the same telescope order as Copat-Result-Rec. Rule Core-Field-Rec therefore returns corecRıj(ind(ıj,b)), the compiled object for the recursive result. The argument tuple b is ready by the premises of Copat-Result-Rec. Apply the induction hypothesis to Qd(b) and o, then rebuild Tree-Path-Step and Core-Path-Step. Conversely, inversion of Core-Field-Rec and the method’s generated block equations recovers the same declaration tag, prepared arguments, and recursive tree leaf; the induction hypothesis recovers the remaining tree observation. Thus both directions hold for every finite path. ◻

Theorem 125.19 — Composed elaboration and observation preservation

If Tcop-clause accepts d, then the composed output Qd is well typed in Tcop-core. For every closed well-typed ready argument tuple c=(ı,a), finite coprojection path o ending in a computational field, and closed value v, the two exact implications are dcovQdcCCov,QdcCCovdcov. At each projection in the path, both derivations select the same least matching source row among the rows for that demanded field.

Proof of Theorem 125.19 — Composed elaboration and observation preservation

Proof. Typing is the composition of theorem 125.7 followed by theorem 125.14. Apply lemma 125.8 to identify source observation with the covered-tree observation, including the least selected row at each field. Apply lemma 125.18 to identify that tree observation with target observation. Composition gives each displayed implication. The first lemma supplies the row statement; the second translation consumes the selected leaves and does not run matching again. ◻

Cockx and Abel formalize elaboration from dependent pattern and copattern clauses to well-typed case trees. They prove that a signature all of whose functions are given by well-typed case trees is respectful, hence type-preserving, in Definitions 13–14, Lemmas 15–16, and Theorem 17 [CA20]. The second translation and the Tcop-core signature are fixed and proved locally here; the source theorem does not by itself justify a translation to unnamed primitive eliminators.

Suggested first pass.

None of these problems is a prerequisite for a later chapter. Begin with exercise 125.3, then complete exercise 125.5.

Exercise 125.3

★★☆ Draw the complete Tcop-tree for iterate(q,a), including each frontier. Translate it to the sequential primitive method tuple and calculate the first two tail observations followed by next.

Exercise 125.4

★★☆ Swap the next and step declarations in the orbit record without changing their types. Locate the first ill-scoped occurrence, and prove that no field permutation preserving dependencies can put step first.

Exercise 125.5

★★★ Practical project.dependent-copattern-case-tree Implement in Kappa the single-definition, finite-input-pattern, three-field orbit fragment. The general indexed helper-state datatype for a mutual group is outside this runner. Compile an ordered clause list to a coprojection spine in which every field node stores the frontier accumulated before it, then read back the case tree, the field frontiers, and the observation trace from that spine; none of the three may be printed as a literal. Preserve the invariant that field j stores terms for all fields below j. Accept iterate and print observations 1,2,3 from successor at zero; reject step-before-next, naming the earlier field that is missing, and uncovered-input, naming the field and constructor with no branch. Additional rejections must name a wholly missing field, a field whose own rows omit a constructor, and a field whose right side has the wrong finite type. Five mutations must fail the acceptance oracle: dropping next from the declared predecessors of step, letting one constructor pattern count as covering, failing to advance the frontier stored by the compiled spine, using global rather than per-field coverage, and bypassing the finite right-side type checker. The interpreter checks this finite compiler; it does not prove the general Cockx–Abel theorem.

Search the book

Type to search the local edition.