The equations 𝖾𝗏𝖾𝗇(0)=𝗍𝗍,𝖾𝗏𝖾𝗇(𝗌𝗎𝖼𝑛)=𝗈𝖽𝖽(𝑛),𝗈𝖽𝖽(0)=𝖿𝖿,𝗈𝖽𝖽(𝗌𝗎𝖼𝑛)=𝖾𝗏𝖾𝗇(𝑛) compute by crossing from one definition to the other. Neither definition is a structural recursion in isolation. The group terminates because every crossing removes one successor. Replacing the last argument by 𝗌𝗎𝖼𝑛 preserves typing and destroys that reason. A recursive-definition checker must therefore inspect a call graph, not just the type of each right side.
Groups and certified calls
Timpl-rec accepts a finite mutually recursive group G={𝑓𝑖:(Δ𝑖)→𝐵𝑖 𝗐𝗁𝖾𝗋𝖾 𝐶𝑖∣1≤𝑖≤𝑞}. Each 𝐶𝑖 is an ordered Timpl-clauses matrix accepted by definition 121.1. Every strongly connected component chooses one of two decrease disciplines.
A structural certificate names one explicit argument position of every function in the component. All named arguments inhabit either one mutual Timpl-data block at one common parameter vector or one primitive Timpl inductive type, ℕ or 𝖵𝖾𝖼(𝑐, −) at one common element code 𝑐. At a recursive call the argument supplied in the callee’s named position must be a direct constructor child exposed by a clause split at the caller’s named position.
A lexicographic certificate names a finite tuple of arguments and a well-founded relation for each coordinate. At a recursive call, the first coordinate that changes must strictly decrease; every earlier coordinate must be definitionally unchanged.
The target Timpl-rec-core is the literal union of the indexed Timpl fragment with the accessibility predicate, eliminator, and computation rule of definition 82.2, definition 82.6. No general fixpoint is added. Every accepted call is translated with its checked accessibility predecessor proof. Size-change matrices, sized types, semantic termination, effects, and higher-order recursive arguments are outside this card.
Referenced from 5 locations
The target must contain both indexed families and accessibility. The accessibility fragment of definition 82.2, definition 82.6 alone would type the well-founded eliminator but has no vector family; bare Timpl has vectors but no accessibility eliminator. The named union states the exact delta.
The function call graph has one vertex for each 𝑓𝑖. An edge 𝑓𝑖 →𝑓𝑗 records every syntactic call to 𝑓𝑗 in a reachable right side of 𝑓𝑖, together with its clause path and candidate decrease certificate. Calls in shadowed rows are omitted because they cannot occur at run time. A strongly connected component is recursive exactly when it has more than one vertex or a self-loop.
Referenced from 3 locations
The opening group yields one component with two vertices. All four clauses are reachable. Its two recursive edges carry the direct-child certificate 𝑛 ≺𝗌𝗎𝖼𝑛.
At a clause leaf with branch context Θ, let 𝑥 be the designated argument before splitting. The compiler records the finite set 𝖢𝗁𝗂𝗅𝖽(𝑥) ⊆Θ of recursive fields introduced by the single constructor split whose scrutinee is 𝑥. A later split of one of those fields does not add its descendants to 𝖢𝗁𝗂𝗅𝖽(𝑥). The judgment Θ;𝑥⊢𝑢𝖽𝖾𝗌𝖼𝑥 holds exactly when 𝑢 is definitionally one of those recorded fields. It is not closed under arbitrary evaluation, transitivity, projections not introduced by the split, or user propositions about size.
Referenced from 6 locations
Thus the call 𝗈𝖽𝖽(𝑛) in the successor clause passes. The calls 𝗈𝖽𝖽(𝗌𝗎𝖼𝑛) and 𝗈𝖽𝖽(𝑛 +0) fail: the first is not a child, and the second is only propositionally equal to a child unless the selected Timpl conversion actually reduces it to 𝑛.
Fix well-founded relations 𝑅ℎ on 𝐴ℎ, for 1 ≤ℎ ≤𝑑. A call from tuple ⃗𝑎 to ⃗𝑏 has a lexicographic certificate when there is a least coordinate 𝑘 such that 𝑎1≡𝑏1,…,𝑎𝑘−1≡𝑏𝑘−1,𝑏𝑘𝑅𝑘𝑎𝑘. Later coordinates are unrestricted. The certificate stores 𝑘, the conversion derivations for the prefix, and the proof of the strict step.
Referenced from 6 locations
The least-coordinate requirement prevents a later decrease from masking an earlier increase. For pairs of naturals, (𝑚,𝗌𝗎𝖼𝑛) is below (𝗌𝗎𝖼𝑚,0) only if the first coordinate decreases; the change in the second coordinate cannot repair a failed first comparison.
The Timpl-rec checker either returns a certified component list or one record 𝖱𝖾𝖼𝖱𝖾𝗃𝖾𝖼𝗍(𝑆,𝑓𝑖→𝑓𝑗,𝜔,𝛿,⃗𝑎,⃗𝑏,𝐹). Here 𝑆 is the computed component; 𝑓𝑖 →𝑓𝑗 and 𝜔 name the source, target, and exact clause-tree call site; 𝛿 is the chosen structural or lexicographic discipline; ⃗𝑎 and ⃗𝑏 are the typed caller and callee tuples after the leaf substitution; and 𝐹 is the failed certificate premise. In the structural case, 𝐹 prints the named positions, the exposed direct-child set, and the failed definitional comparison. In the lexicographic case, it prints every earlier comparison through the first unequal coordinate and identifies either the earlier increase, the missing strict proof, or the exhausted equal tuple.
The checker computes components in source-vertex order, scans their reachable clause trees and call sites left to right, and compares lexicographic coordinates from first to last. Edges leaving 𝑆 are recorded but require no predecessor certificate. The first internal edge without a complete certificate is returned; no diagnostic is selected by a fixture name.
Referenced from 4 locations
If Timpl-rec returns 𝖱𝖾𝖼𝖱𝖾𝗃𝖾𝖼𝗍(𝑆,𝑓𝑖 →𝑓𝑗,𝜔,𝛿,⃗𝑎,⃗𝑏,𝐹), then the call at 𝜔 has no predecessor proof under the selected discipline using the checked comparisons stored in 𝐹.
Referenced from 3 locations
Proof of Lemma 123.6 — Recursive rejection records a failed predecessor premise
Proof. For a structural discipline, inversion of definition 123.3 says that a predecessor proof must select a member of the finite direct-child set and convert the callee’s named argument to it. The diagnostic has enumerated that set and its stored comparison fails for every member. For a lexicographic discipline, inversion of definition 123.4 requires a least coordinate with an unchanged prefix and a supplied strict step. The left-to-right record either exhibits an earlier unequal coordinate without its strict step or exhausts the tuple without one. In either case the required constructor of the certified call relation cannot be formed. These are the two accepted disciplines. ◻
For one recursive component 𝑆, the compiler first generates the nonrecursive datatype 𝖲𝗍𝖺𝗍𝖾𝑆:Uℓ,𝗂𝗇𝑖:(⃗𝑎:Δ𝑖)→𝖲𝗍𝖺𝗍𝖾𝑆(𝑓𝑖∈𝑆), at the maximum level of its constructor telescopes. This is an ordinary one-family Timpl-data block: no constructor argument mentions 𝖲𝗍𝖺𝗍𝖾𝑆, so the occurrence checker of definition 122.4 accepts it. The generated declaration and its eliminator are program data, not a new Timpl-rec-core rule. Its result family has branch 𝐵𝑆(𝗂𝗇𝑖(⃗𝑎)):=𝐵𝑖[⃗𝑎/Δ𝑖]. The relation over which the component recurses is the following one; every later statement of this chapter is about it.
Fix the common parameter vector ⃗𝑝 of a mutual datatype block B =(𝐷1,…,𝐷𝑟) named by a structural certificate. The number 𝑟 of block families is independent of the number 𝑞 of functions. The certificate therefore stores, for every 𝑓𝑖, a family tag 𝜅(𝑖) :𝖥𝗂𝗇𝗂𝗇𝖽(𝑟) for its named argument. Here 𝖥𝗂𝗇𝗂𝗇𝖽 is the indexed family, constructors, and eliminator fixed in chapter 31; the extensional finite-set presentation is not being used.
To make the varying index telescopes well formed, set 𝐿B:=max(0,max𝑙𝗅𝖾𝗏(Δ𝑙),max𝑙ℓ𝑙) and define the tagged block payload by dependent elimination on 𝑙 :𝖥𝗂𝗇𝗂𝗇𝖽(𝑟): 𝖯𝖺𝗒𝗅𝗈𝖺𝖽B(𝑙):=∑⃗ı:Δ𝑙𝐷𝑙⃗𝑝⃗ı:U𝐿B. Each of the finitely many eliminator branches is the displayed iterated dependent sum. When a branch inhabits a smaller universe, the processor inserts the strict lift of definition 29.10; its decoding equation makes the lifted branch judgmentally equal to the displayed payload. Put 𝖢𝖺𝗋𝗋𝗂𝖾𝗋B(⃗𝑝):=∑𝑙:𝖥𝗂𝗇𝗂𝗇𝖽(𝑟)𝖯𝖺𝗒𝗅𝗈𝖺𝖽B(𝑙):U𝐿B. Its uniform direct-child relation 𝖣𝖢𝗁𝗂𝗅𝖽B is generated once on this total space. More precisely, let 𝐾B:=max(𝗅𝖾𝗏(Δ𝑝),𝐿B,max𝑠𝗅𝖾𝗏(Θ𝑠)). The processor submits the nonrecursive Timpl-data family 𝖣𝖢𝗁𝗂𝗅𝖽B:𝖢𝖺𝗋𝗋𝗂𝖾𝗋B(⃗𝑝)→𝖢𝖺𝗋𝗋𝗂𝖾𝗋B(⃗𝑝)→U𝐾B with the constructors below. The maximum emitted by definition 122.13 is exactly 𝐾B: it includes the parameter telescope, both carrier-index binders, every constructor telescope, and the displayed family level. No constructor argument mentions 𝖣𝖢𝗁𝗂𝗅𝖽B, so definition 122.4 accepts the generated block. For every constructor 𝑐 :Θ →𝐷𝑙 ⃗𝑝 ⃗ı and every field 𝑥𝑟 :𝐷𝑘 ⃗𝑝 ⃗ȷ of Θ whose head is a family of B, it has the constructor 𝖼𝗁𝗂𝗅𝖽𝑐,𝑟:𝖣𝖢𝗁𝗂𝗅𝖽B((𝑘,(⃗ȷ,𝑥𝑟)),(𝑙,(⃗ı,𝑐⃗𝑥))). The relation is defined on all tagged block inhabitants; it does not mention a clause leaf. Mutual induction on B constructs accessibility of every (𝑙,(⃗ı,𝑎)), because each predecessor proof selects one recursive constructor field and the induction hypothesis supplies its accessibility proof.
Referenced from 3 locations
For the two primitive choices the same notation has a separate, exact instance. On ℕ, its only generator is 𝖼𝗁𝗂𝗅𝖽𝗌𝗎𝖼:𝖣𝖢𝗁𝗂𝗅𝖽ℕ(𝑛,𝗌𝗎𝖼𝑛). At fixed 𝑐 :Uℓ, the vector carrier is ∑𝑛:ℕ𝖵𝖾𝖼(𝑐,𝑛), and its only generator is 𝖼𝗁𝗂𝗅𝖽𝗏𝖼𝗈𝗇𝗌:𝖣𝖢𝗁𝗂𝗅𝖽𝖵𝖾𝖼(𝑐,−)((𝑛,𝑥𝑠),(𝗌𝗎𝖼𝑛,𝗏𝖼𝗈𝗇𝗌(𝑛,𝑎,𝑥𝑠))). The Nat-elim and Vec-elim rules construct the respective accessibility proofs. Thus the opening even–odd group uses 𝖣𝖢𝗁𝗂𝗅𝖽ℕ; it does not pretend that ℕ was declared by a Timpl-data block.
Let 𝜇 :𝐴 →𝐵, let 𝑅 be a well-founded relation on 𝐵, and define 𝑎′ ≺𝜇𝑎 by 𝜇(𝑎′)𝑅𝜇(𝑎). Then ≺𝜇 is well founded on 𝐴.
Referenced from 5 locations
Proof of Lemma 123.8 — Inverse images preserve well-foundedness
Proof. Fix 𝑎 :𝐴. Eliminate the supplied proof 𝖠𝖼𝖼𝑅(𝜇(𝑎)). Its step premise assigns 𝖠𝖼𝖼𝑅(𝑏′) to every 𝑏′𝑅𝜇(𝑎). Given 𝑎′ ≺𝜇𝑎, instantiate that premise at 𝑏′ =𝜇(𝑎′) and apply the accessibility induction hypothesis to obtain 𝖠𝖼𝖼≺𝜇(𝑎′). The accessibility constructor therefore gives 𝖠𝖼𝖼≺𝜇(𝑎). Since 𝑎 was arbitrary, the inverse-image relation is well founded. ◻
For 𝑛 ≥1, if each 𝑅ℎ is well founded on 𝐴ℎ, then the right-associated relation 𝗅𝖾𝗑(𝑅1):=𝑅1,𝗅𝖾𝗑(𝑅1,…,𝑅𝑛):=𝖫𝖾𝗑(𝑅1,𝗅𝖾𝗑(𝑅2,…,𝑅𝑛))(𝑛≥2) is well founded on 𝐴1 ×⋯ ×𝐴𝑛, with products associated to the right in the same way as the relation.
Referenced from 5 locations
Proof of Lemma 123.9 — Finite lexicographic products are well founded
Proof. Induct on 𝑛. The case 𝑛 =1 is the supplied well-foundedness proof for 𝑅1. For 𝑛 =𝑚 +1, the induction hypothesis makes 𝗅𝖾𝗑(𝑅2,…,𝑅𝑚+1) well founded on 𝐴2 ×⋯ ×𝐴𝑚+1. Apply theorem 82.16 to 𝑅1 and this relation. Its carrier is 𝐴1 ×(𝐴2 ×⋯ ×𝐴𝑚+1), which is the stipulated right-associated product. ◻
Let 𝑆 choose the structural discipline and let 𝑝𝑖 be the position named by its certificate for 𝑓𝑖. The carrier and the measure map out of each state constructor depend on the single discipline chosen by the component: discipline𝑋𝑆𝜇𝑆𝑖:Δ𝑖→𝑋𝑆B𝖢𝖺𝗋𝗋𝗂𝖾𝗋B(⃗𝑝)𝜇B𝑖(⃗𝑎)=𝜄𝜅(𝑖)(𝑎𝑝𝑖)ℕℕ𝜇ℕ𝑖(⃗𝑎)=𝑎𝑝𝑖𝖵𝖾𝖼(𝑐,−)∑𝑛:ℕ𝖵𝖾𝖼(𝑐,𝑛)𝜇𝖵𝖾𝖼𝑖(⃗𝑎)=(𝑛𝑖(⃗𝑎),𝑎𝑝𝑖). Here 𝜅(𝑖) is present only in the mutual-block row, while 𝑛𝑖(⃗𝑎) is the index at which the named vector argument is typed. In the mutual row, 𝜄𝑙(𝑎) abbreviates (𝑙,(⃗ı𝑖(⃗𝑎),𝑎)) when 𝑎 :𝐷𝑙 ⃗𝑝 ⃗ı𝑖(⃗𝑎). Write 𝖣𝖢𝗁𝗂𝗅𝖽𝑆 respectively for 𝖣𝖢𝗁𝗂𝗅𝖽B, 𝖣𝖢𝗁𝗂𝗅𝖽ℕ, or 𝖣𝖢𝗁𝗂𝗅𝖽𝖵𝖾𝖼(𝑐,−). Put 𝗂𝗇𝑗(⃗𝑏)𝑅𝑆𝗂𝗇𝑖(⃗𝑎):=𝖣𝖢𝗁𝗂𝗅𝖽𝑆(𝜇𝑆𝑗(⃗𝑏),𝜇𝑆𝑖(⃗𝑎)). Thus neither 𝜅 nor a mutual-block carrier is silently assigned to a primitive discipline. Let 𝑆 instead choose the lexicographic discipline with coordinates 1 ≤ℎ ≤𝑑, relations 𝑅ℎ, and coordinate projections ⃗𝜋. Put 𝗂𝗇𝑗(⃗𝑏)𝑅𝑆𝗂𝗇𝑖(⃗𝑎):=⃗𝜋(𝗂𝗇𝑗(⃗𝑏))𝗅𝖾𝗑(𝑅1,…,𝑅𝑑)⃗𝜋(𝗂𝗇𝑖(⃗𝑎)), the finite lexicographic product of lemma 123.9. In both cases the tag is not part of the measure: it selects which projection is read, and a call may cross to any 𝑓𝑗 of the component. By construction each accepted recursive edge of definition 123.2 is one 𝑅𝑆 step, and its certificate is a proof of that step.
Referenced from 4 locations
Suppose a clause split exposes constructor 𝑐 at the caller’s named position and records 𝑢 ∈𝖢𝗁𝗂𝗅𝖽(𝑥). After applying the leaf substitution, the stored certificate determines 𝖣𝖢𝗁𝗂𝗅𝖽𝑆(𝜇𝑆𝑗(⃗𝑏),𝜇𝑆𝑖(⃗𝑎)), where ⃗𝑎 is the caller tuple and ⃗𝑏 is the callee tuple after that substitution.
Referenced from 4 locations
Proof of Lemma 123.11 — A stored structural certificate gives its discipline's child step
Proof. By definition 123.3, 𝑢 is definitionally one of the recursive fields introduced by that constructor split. There are three discipline cases. For a mutual block, let 𝑟 be the field position and 𝐷𝜅(𝑗) its family. The generator 𝖼𝗁𝗂𝗅𝖽𝑐,𝑟 relates 𝜄𝜅(𝑗)(𝑢) to 𝜄𝜅(𝑖)(𝑐 ⃗𝑥); the stored conversion identifies these terms with 𝜇B𝑗(⃗𝑏) and 𝜇B𝑖(⃗𝑎). For ℕ, the only constructor that can expose a recursive field is 𝗌𝗎𝖼, and 𝖼𝗁𝗂𝗅𝖽𝗌𝗎𝖼 relates the stored predecessor to the successor scrutinee. For 𝖵𝖾𝖼(𝑐, −), the only such constructor is 𝗏𝖼𝗈𝗇𝗌; 𝖼𝗁𝗂𝗅𝖽𝗏𝖼𝗈𝗇𝗌 relates the tagged tail (𝑛,𝑥𝑠) to the tagged scrutinee (𝗌𝗎𝖼𝑛,𝗏𝖼𝗈𝗇𝗌(𝑛,𝑎,𝑥𝑠)). The callee typing conversion identifies its vector index with 𝑛. In every case the stored definitional equality identifies the callee’s named argument with the exposed field 𝑢, giving the displayed instance and no other child step. ◻
The relation 𝑅𝑆 of definition 123.10 is well founded on 𝖲𝗍𝖺𝗍𝖾𝑆 under either discipline, and every accepted recursive edge of the component is one 𝑅𝑆 step.
Referenced from 7 locations
Proof of Lemma 123.12 — The accepted call relation is well founded
Proof. In the mutual-block structural case, mutual induction on the accepted block constructs accessibility for 𝖣𝖢𝗁𝗂𝗅𝖽B on 𝖢𝖺𝗋𝗋𝗂𝖾𝗋B(⃗𝑝). Pull it back along the map whose restriction to 𝗂𝗇𝑖 is 𝜇B𝑖, using lemma 123.8. In the ℕ case, Nat-elim constructs accessibility for 𝖣𝖢𝗁𝗂𝗅𝖽ℕ; pull it back along the map with restrictions 𝜇ℕ𝑖. In the vector case, Vec-elim constructs accessibility for 𝖣𝖢𝗁𝗂𝗅𝖽𝖵𝖾𝖼(𝑐,−) on ∑𝑛:ℕ𝖵𝖾𝖼(𝑐,𝑛); pull it back along the map with restrictions 𝜇𝖵𝖾𝖼𝑖. These codomains differ, but a component chooses exactly one of them, so each use of the inverse-image lemma is typed. By lemma 123.11, every accepted syntactic 𝖢𝗁𝗂𝗅𝖽 certificate constructs exactly the predecessor proof for the chosen discipline. The function tag may change because the applicable measure map is selected by the state constructor.
In the lexicographic case, each edge contains the data required by definition 123.4: a least changed coordinate 𝑘, conversion derivations 𝑎ℎ ≡𝑏ℎ for ℎ <𝑘, and a proof of 𝑏𝑘𝑅𝑘𝑎𝑘. That is exactly one step of 𝗅𝖾𝗑(𝑅1,…,𝑅𝑑), which lemma 123.9 shows well founded from the declared 𝑅ℎ. Pull it back along ⃗𝜋 by lemma 123.8. Hence 𝑅𝑆 is well founded and each certificate is a predecessor proof. ◻
★☆☆ For the lexicographic order 𝗅𝖾𝗑( <, <) on ℕ ×ℕ, classify calls from (𝗌𝗎𝖼𝑚,𝑛) to (𝑚,𝗌𝗎𝖼(𝗌𝗎𝖼𝑛)), (𝗌𝗎𝖼𝑚,0), and (𝗌𝗎𝖼(𝗌𝗎𝖼𝑚),0). In the second call, distinguish 𝑛 =0 from 𝑛 =𝗌𝗎𝖼𝑘. Give the decisive coordinate or the failed premise.
Referenced from 3 locations
Compilation through accessibility
By lemma 123.12, every tagged input of the component has an accessibility proof for 𝑅𝑆.
The translation of a case-tree leaf replaces a recursive call 𝑓𝑗 ⃗𝑏 made while defining 𝑓𝑖 ⃗𝑎 by the recursive hypothesis supplied at the stored proof 𝗂𝗇𝑗(⃗𝑏)𝑅𝑆𝗂𝗇𝑖(⃗𝑎). Nonrecursive calls and constructors are translated homomorphically. Constructor splits remain the Timpl eliminators generated by the clause compiler.
Referenced from 5 locations
For even and odd, constructor 𝗂𝗇𝖾𝗏𝖾𝗇 denotes even and constructor 𝗂𝗇𝗈𝖽𝖽 denotes odd. The translated body at 𝗂𝗇𝖾𝗏𝖾𝗇(𝗌𝗎𝖼𝑛) invokes the recursive hypothesis at 𝗂𝗇𝗈𝖽𝖽(𝑛); the odd body makes the opposite crossing. Eliminating the well-founded recursive function at the two state constructors reproduces the four opening equations.
Assume the clause compiler accepts every 𝐶𝑖, and every recursive edge in the component carries a certificate accepted by Timpl-rec. In the well-founded-recursion step context for 𝗂𝗇𝑖(⃗𝑎), translation of the body of 𝑓𝑖 has type 𝐵𝑖[⃗𝑎/Δ𝑖].
Referenced from 3 locations
Proof of Lemma 123.14 — Body translation is typed
Proof. Induct on the accepted case tree. A leaf without a recursive call uses clause compiler typing. At a recursive call, the stored structural or lexicographic certificate is a proof of 𝗂𝗇𝑗(⃗𝑏)𝑅𝑆𝗂𝗇𝑖(⃗𝑎); applying the recursive hypothesis to that proof yields the callee result type. Constructor-split nodes use the indexed eliminator and the induction hypotheses for their branches. A conversion node applies the Timpl conversion derivation already stored by the clause compiler. These are all node families. ◻
Two evaluation relations are needed to state what compilation preserves. A phrase such as “the two evaluations agree” would not identify either one.
For an accepted group G, let ΣG contain its accepted ambient Timpl signature, every Timpl-data block scrutinized by a clause tree, and every generated state block. A program root contraction is either a root contraction of definition 111.22 or a generated Block-comp equation belonging to one of those accepted blocks. The signature parameter matters because a split over a user declaration computes by its generated equation rather than by a fixed-kernel rule.
Let 𝗌𝖾𝗅𝖾𝖼𝗍(𝐶𝑖,⃗𝑎) =(𝜎,𝑒) mean that the ordered clause tree for 𝑓𝑖, on the closed constructor tuple ⃗𝑎, selects the reachable leaf 𝑒 with branch substitution 𝜎. The source root family also has 𝗌𝖾𝗅𝖾𝖼𝗍(𝐶𝑖,⃗𝑎)=(𝜎,𝑒)𝑓𝑖⃗𝑎𝑅−𝐶𝑎𝑙𝑙⇝0𝑒[𝜎]R−Call. Let C(G) be the Timpl-rec-core definition produced by definition 123.13, and write 𝖼𝗈𝗆𝗉𝗂𝗅𝖾G(𝑡) for its homomorphic extension to source term contexts. The target root family replaces R-Call by the macro-contraction 𝗌𝖾𝗅𝖾𝖼𝗍(𝐶𝑖,⃗𝑎)=(𝜎,𝑒)𝖼𝗈𝗆𝗉𝗂𝗅𝖾G(𝑓𝑖⃗𝑎)𝐶−𝐶𝑎𝑙𝑙⇝0𝖼𝗈𝗆𝗉𝗂𝗅𝖾G(𝑒[𝜎])C−Call. The macro is licensed only when its left side contracts to its right side by the nonempty deterministic Timpl-rec-core sequence consisting of the generated outer definition beta contractions, the generated state-block equation, WF-𝛽, and the administrative beta contractions introduced by body translation. It is a trace boundary, not a new target equality rule. The compiler marks that whole expansion as one administrative region. A fixed-kernel contraction strictly inside such a region is not an independent target program root; it is scheduled only as part of C-Call. Fixed-kernel contractions in homomorphic source positions and all shared Block-comp roots remain independent program roots.
For either grammar, a dynamic compatible context is a compatible term context of definition 111.22 except that it has no hole in an accessibility proof, a stored predecessor certificate, or a conversion witness introduced by the compiler. These positions remain available to kernel conversion and typing, but the program evaluator does not schedule them. Ordinary proof terms written by the programmer are not frozen. Write ⟶ for closure of the appropriate root family under dynamic compatible contexts. The source and target grammars determine whether the third root family is R-Call or C-Call.
For closed terms, 𝑡 ⇓𝖱𝑣 means that a finite ⟶-sequence using the source root family carries 𝑡 to the closed constructor normal form 𝑣. For closed target terms, 𝑡 ⇓𝖱𝖢𝑣 means the analogous finite sequence using the target root family. Thus one source R-Call and one target C-Call have the same visible granularity, while every C-Call has the stated nonempty raw-core expansion. Neither relation borrows the execution calculus introduced in a later chapter.
Referenced from 4 locations
Suppose 𝗌𝖾𝗅𝖾𝖼𝗍(𝐶𝑖,⃗𝑎) =(𝜎,𝑒). The source definition has the R-Call contraction 𝑓𝑖 ⃗𝑎 𝑅−𝐶𝑎𝑙𝑙⇝0𝑒[𝜎]. Its compiled target has the C-Call contraction to 𝖼𝗈𝗆𝗉𝗂𝗅𝖾G(𝑒[𝜎]), and this contraction expands to a nonempty deterministic Timpl-rec-core sequence. Every recursive call in the target body uses the recursive hypothesis at its stored 𝑅𝑆-predecessor proof.
Referenced from 3 locations
Proof of Lemma 123.16 — Generated equations
Proof. The source contraction is the defining instance of definition 123.15. For the target expansion, the outer definition applications first install ⃗𝑎, after which the generated state eliminator selects constructor 𝗂𝗇𝑖. The accessibility proof begins with 𝖺𝖼𝖼, so WF-𝛽 exposes the step term. The finitely many outer applications introduced by translation then beta-contract. By definition 123.13, the selected branch is 𝖼𝗈𝗆𝗉𝗂𝗅𝖾G(𝑒[𝜎]), and each recursive leaf receives exactly the hypothesis indexed by its stored predecessor certificate. The state tag and ordered clause selection make every contraction in this administrative prefix deterministic. This is precisely the side condition that licenses C-Call. ◻
Let 𝑡 be a closed term reachable from a clause body of an accepted group G.
If 𝑡 takes one source step to 𝑡′, then 𝖼𝗈𝗆𝗉𝗂𝗅𝖾G(𝑡) takes one target program step to 𝖼𝗈𝗆𝗉𝗂𝗅𝖾G(𝑡′).
If 𝖼𝗈𝗆𝗉𝗂𝗅𝖾G(𝑡) takes one target step, its reduct is 𝖼𝗈𝗆𝗉𝗂𝗅𝖾G(𝑡′) for a unique source reduct 𝑡′ of 𝑡.
Referenced from 5 locations
Proof of Lemma 123.17 — One-step operational correspondence
Proof. First inspect a root step. A fixed-kernel contraction is preserved literally because translation is homomorphic on that redex. A generated Block-comp step is also preserved literally: both sides use the same declaration from ΣG, constructor, and generated branch equation. A source R-Call and its target C-Call are the two contractions of lemma 123.16. Conversely, a root contraction of a translated reachable term belongs to exactly one of these three rule families. The first two reflect the identical source contraction. In the third, the state-constructor tag determines 𝑖, and ordered clause selection determines the unique R-Call reduct.
For a non-root step, induct on the dynamic compatible context. Rebuild the same context around the root argument in the forward direction. In the reverse direction, homomorphic translation identifies the unique source subterm at the hole; apply the induction hypothesis there and rebuild the context. A binder context first renames its bound variable fresh, while a conversion context retains its stored conversion derivation. There is no target-only hole inside compiler evidence by definition of a dynamic context. These are all dynamic compatible-context forms of definition 111.22 and the generated block rules. ◻
For every closed reachable 𝑡 and closed constructor normal form 𝑣, 𝑡⇓𝖱𝑣⟺𝖼𝗈𝗆𝗉𝗂𝗅𝖾G(𝑡)⇓𝖱𝖢𝑣.
Referenced from 5 locations
Proof of Lemma 123.18 — Finite operational correspondence
Proof. For the forward implication, induct on the source sequence and append the target program step from item 1 of lemma 123.17. Translation fixes constructor normal forms. For the reverse implication, repeatedly apply item 2 to the first target step. Each application consumes exactly that target program step; the finite target derivation therefore yields a finite source derivation. At its end, translation fixes 𝑣. If the target derivation has length zero, its source is already a constructor normal form because translation changes only recursive-call heads and neither creates nor removes such a normal form. ◻
★☆☆ For the opening group, write the R-Call contraction at 𝖾𝗏𝖾𝗇(𝗌𝗎𝖼𝑛) and the corresponding C-Call contraction. Expand the latter through its generated state-block and WF-𝛽 steps at 𝗂𝗇𝖾𝗏𝖾𝗇(𝗌𝗎𝖼𝑛). Name the 𝖣𝖢𝗁𝗂𝗅𝖽ℕ proof supplied to the recursive hypothesis.
Referenced from 3 locations
If Timpl-rec accepts G, then its checker terminates and returns a well-typed Timpl-rec-core definition for every 𝑓𝑖. Evaluation of a compiled function at closed constructor data takes only finitely many recursive unfoldings. For every closed constructor input ⃗𝑎 and closed constructor value 𝑣, 𝑓𝑖⃗𝑎⇓𝖱𝑣⟺C(G)𝑖⃗𝑎⇓𝖱𝖢𝑣.
Referenced from 3 locations
Proof of Theorem 123.19 — Termination and elaboration of accepted groups
Proof. The checker traverses finite clause trees and call sites. Structural checking compares a call argument with a finite child set; lexicographic checking scans a finite tuple and invokes the already terminating Timpl conversion checker. Thus checker execution terminates.
For each recursive component, lemma 123.12 gives the accessibility proof and lemma 123.14 gives the step of the well-founded recursor. Eliminating its result at each generated state constructor gives the typed target definitions. Accessibility induction shows that evaluation can unfold only at predecessor inputs, so a closed run has finitely many recursive unfoldings.
For the equivalence, apply lemma 123.18 to the closed term 𝑓𝑖 ⃗𝑎. Its translation is C(G)𝑖 ⃗𝑎, and translation fixes 𝑣. The one-step lemma treats fixed-kernel, generated Block-comp, recursive, binder, and conversion contexts separately, so the finite-closure argument does not assume an unprinted congruence case. ◻
Let Timpl-rec accept a component 𝑆. For every 𝑓𝑖 ∈𝑆, fix a predicate 𝑄𝑖:(⃗𝑎:Δ𝑖)→𝐵𝑖[⃗𝑎/Δ𝑖]→U𝑘. Suppose that, for each reachable clause leaf of 𝑓𝑖 at input ⃗𝑎, the clause body establishes 𝑄𝑖(⃗𝑎,𝑣) whenever every recursive call 𝑓𝑗 ⃗𝑏 in that leaf is supplied with 𝑄𝑗(⃗𝑏,𝑣𝑗) for its result 𝑓𝑗 ⃗𝑏 ⇓𝖱𝑣𝑗. Then every closed constructor input ⃗𝑎 for which 𝑓𝑖 ⃗𝑎 ⇓𝖱𝑣 satisfies 𝑄𝑖(⃗𝑎,𝑣).
Referenced from 3 locations
Proof of Corollary 123.20 — Functional induction for an accepted group
Proof. Apply accessibility induction to the tagged input 𝗂𝗇𝑖(⃗𝑎) under the well-founded relation of lemma 123.12. Clause compilation selects one reachable leaf. Every recursive call in that leaf carries a stored predecessor proof, so the accessibility induction hypothesis supplies its required 𝑄𝑗 premise. The assumed clause case then gives 𝑄𝑖(⃗𝑎,𝑣). These cases cover every leaf of every function in the component. ◻
The call-order viewpoint and its predicative soundness proof are due to Abel and Altenkirch, Sections 2–5 [AA02]. Timpl-rec deliberately uses only direct structural children and explicit lexicographic witnesses; it does not import the more general foetus analysis.
Suggested first pass.
None of these problems is a prerequisite for a later chapter. Begin with exercise 123.3, then complete exercise 123.5.
★★☆ Construct the tagged input relation for even and odd. Give all four body translations. Calculate the compiled value of 𝖾𝗏𝖾𝗇(𝗌𝗎𝖼(𝗌𝗎𝖼0)), annotating both recursive unfoldings.
Referenced from 4 locations
★★☆ Change only the last opening equation to 𝗈𝖽𝖽(𝗌𝗎𝖼𝑛) =𝗈𝖽𝖽(𝗌𝗎𝖼𝑛). Show the self-edge, the failed structural premise, and the infinite operational trace from 𝗈𝖽𝖽(𝗌𝗎𝖼0).
Referenced from 3 locations
★★★ Practical project.recursive-group-descent-checker
Implement finite call graphs, strongly connected components, direct-child and two-coordinate lexicographic certificates in Kappa. Certify exactly the edges internal to a component, each by one verified predecessor proof. Bound reachability by the vertex count and justify that bound. Represent an edge by its source, target, call site, and coordinate comparisons; compute components from those edges rather than from fixture names. Accept even-odd, whose increasing auxiliary call leaves its component, and lex-reset. Reject same-argument and later-coordinate-only, computing the failing edge rather than printing a fixed verdict. Replay two oracle-failing mutations: ignore an earlier lexicographic increase, and drop the component filter. Each mutant must still typecheck, fail its exact stdout oracle, and retain an empty audit. The checker illustrates lemma 123.12; it proves no general termination theorem.
Referenced from 5 locations