Natural numbers, lists, trees, and vectors have different constructors, yet their maps and folds repeat the same recursion: preserve constant data, recurse at recursive positions, and follow sums and products. Writing that recursion once requires data that describes a datatype without being the datatype.
A regular description sublanguage
We begin with a finite-branching regular normal form. It is the fragment on which the first map, fold, traversal, and fusion calculations are carried out; the exact indexed Morris–Altenkirch–Ghani universe is added only after those programs are in hand. Fix a small sort type 𝐼 :U𝑖. The direct attempt is to call every operator Φ:(𝐼→U𝑖)→(𝐼→U𝑖) a datatype description. A generic map would then have to turn each family ℎ :(𝑗 :𝐼) →𝑋(𝑗) →𝑌(𝑗) into a map Φ(𝑋)(𝑗) →Φ(𝑌)(𝑗), but an arbitrary Φ need not provide such an action. More seriously, Φ(𝑋)(𝑗):=𝑋(𝑗) →𝐴 places the recursive family to the left of an arrow. Its fixed point would evade the strict-positivity condition of remark 28.36.
The repair records only the operations through which a recursive position may be reached. An empty constructor needs a unit code, stored data needs a constant code, and a recursive field needs a named index. Alternative constructors force sums; several fields force products. A tag whose value determines the remaining fields forces a dependent sum.
A regular description is a code built by the constructors 𝗈𝗇𝖾,𝖪(𝐴),𝖷(𝑗),𝐷+𝐸,𝐷×𝐸,𝗌𝗂𝗀𝗆𝖺(𝐴,𝐹), where 𝐴 :U𝑖, 𝑗 :𝐼, 𝐷,𝐸 :𝖣𝖾𝗌𝖼𝑖(𝐼), and 𝐹 :𝐴 →𝖣𝖾𝗌𝖼𝑖(𝐼). The codes inhabit 𝖣𝖾𝗌𝖼𝑖(𝐼) :U𝑖+1; the successor level prevents a universe from containing its own code type.
Referenced from 2 locations
This is a book-normalized, finite-branching sublanguage, not yet the full Morris–Altenkirch–Ghani indexed universe. Sums, products, and constants are convenient derived regular codes; 𝗌𝗂𝗀𝗆𝖺 stores a finite tag whose branch is selected before recursion. The principal indexed syntax and its equality-supporting subfragment impose additional constraints on these regular codes.
For a family 𝑋 :𝐼 →U𝑖 and a code 𝐷 :𝖣𝖾𝗌𝖼𝑖(𝐼), define the type [[𝐷]](𝑋) :U𝑖 by recursion on 𝐷: [[𝗈𝗇𝖾]](𝑋):=𝟏,[[𝖪(𝐴)]](𝑋):=𝐴,[[𝖷(𝑗)]](𝑋):=𝑋(𝑗),[[𝐷+𝐸]](𝑋):=[[𝐷]](𝑋)+[[𝐸]](𝑋),[[𝐷×𝐸]](𝑋):=[[𝐷]](𝑋)×[[𝐸]](𝑋),[[𝗌𝗂𝗀𝗆𝖺(𝐴,𝐹)]](𝑋):=∑𝑎:𝐴[[𝐹(𝑎)]](𝑋).
Referenced from 2 locations
The recursive family occurs only as the argument of 𝖷(𝑗) and then covariantly through sums, products, and Sigma types. A code such as 𝖷(𝑗) →𝐴 cannot be formed: the grammar has no constructor that places 𝖷(𝑗) to the left of a function arrow. This syntactic absence is the strict-positivity check.
The chapter extends 𝑇0 by one instance of the indexed-family schema from chapter 31. No equality, universe, or context rule is replaced.
For a code family 𝐷 :𝐼 →𝖣𝖾𝗌𝖼𝑖(𝐼), the following formation and introduction rules define its least fixed point:
Its nonrecursive destructor and computation equation are 𝗈𝗎𝗍𝑗:𝖬𝗎(𝐷)(𝑗)→[[𝐷(𝑗)]](𝖬𝗎(𝐷)),𝗈𝗎𝗍𝑗(𝗋𝗈𝗅𝗅𝑗(𝑢))≡𝑢. Consequently a path 𝑝 :𝗋𝗈𝗅𝗅𝑗(𝑢) =𝗋𝗈𝗅𝗅𝑗(𝑣) gives 𝖺𝗉𝗈𝗎𝗍𝑗(𝑝) :𝑢 =𝑣. This is the only constructor-injectivity fact used below.
Referenced from 2 locations
The rule names Mu-form and Mu-intro are local to description fixed points. They are not the iso-recursive-type rules with similarly named mnemonics in appendix A; their indexed code-family premises distinguish the two signatures.
The regular case takes 𝐼:=𝟏. Suppressing its unique index, define 𝐷ℕ:=𝗈𝗇𝖾+𝖷(⋆),𝐷𝖫𝗂𝗌𝗍(𝐴):=𝗈𝗇𝖾+(𝖪(𝐴)×𝖷(⋆)),𝐷𝖳𝗋𝖾𝖾(𝐴):=𝖪(𝐴)+(𝖷(⋆)×𝖷(⋆)). Under 𝗋𝗈𝗅𝗅, the left and right summands give the familiar constructors. For example, 𝗇𝗂𝗅:=𝗋𝗈𝗅𝗅(𝗂𝗇𝗅(⋆)),𝖼𝗈𝗇𝗌(𝑎,𝑥𝑠):=𝗋𝗈𝗅𝗅(𝗂𝗇𝗋((𝑎,𝑥𝑠))). For trees, put 𝗅𝖾𝖺𝖿(𝑎):=𝗋𝗈𝗅𝗅(𝗂𝗇𝗅(𝑎)),𝖿𝗈𝗋𝗄(𝑙,𝑟):=𝗋𝗈𝗅𝗅(𝗂𝗇𝗋((𝑙,𝑟))). The ladder has so far used unit, constants, recursive positions, alternatives, and products. To force the remaining code, let a Boolean tag choose the arity: 𝐷𝖳𝖺𝗀𝗀𝖾𝖽:=𝗌𝗂𝗀𝗆𝖺(𝟐,𝑏.𝖼𝖺𝗌𝖾(𝑏;𝖿𝖺𝗅𝗌𝖾.𝗈𝗇𝖾;𝗍𝗋𝗎𝖾.𝖷(⋆)×𝖷(⋆))). Its two layers are (𝖿𝖺𝗅𝗌𝖾, ⋆) and (𝗍𝗋𝗎𝖾,(𝑙,𝑟)). The tag is retained in the layer, and its value determines whether zero or two recursive children must be supplied.
For 𝑃 :∏𝑗:𝐼𝖬𝗎(𝐷)(𝑗) →U𝑘, define 𝖠𝗅𝗅𝐸(𝑃,𝑢) by recursion on 𝐸: 𝖠𝗅𝗅𝗈𝗇𝖾(𝑃,⋆):=𝟏,𝖠𝗅𝗅𝖪(𝐴)(𝑃,𝑎):=𝟏,𝖠𝗅𝗅𝖷(𝑗)(𝑃,𝑥):=𝑃(𝑗,𝑥),𝖠𝗅𝗅𝐸+𝐺(𝑃,𝗂𝗇𝗅(𝑢)):=𝖠𝗅𝗅𝐸(𝑃,𝑢),𝖠𝗅𝗅𝐸+𝐺(𝑃,𝗂𝗇𝗋(𝑣)):=𝖠𝗅𝗅𝐺(𝑃,𝑣),𝖠𝗅𝗅𝐸×𝐺(𝑃,(𝑢,𝑣)):=𝖠𝗅𝗅𝐸(𝑃,𝑢)×𝖠𝗅𝗅𝐺(𝑃,𝑣),𝖠𝗅𝗅𝗌𝗂𝗀𝗆𝖺(𝐴,𝐹)(𝑃,(𝑎,𝑢)):=𝖠𝗅𝗅𝐹(𝑎)(𝑃,𝑢). For 𝑟 :(𝑗 :𝐼) →(𝑥 :𝖬𝗎(𝐷)(𝑗)) →𝑃(𝑗,𝑥), define 𝖼𝖺𝗅𝗅𝗌𝐸(𝑃,𝑟,𝑢) :𝖠𝗅𝗅𝐸(𝑃,𝑢) by the same recursion: use ⋆ at unit and constant codes, use 𝑟𝑗(𝑥) at 𝖷(𝑗), follow a sum injection or Sigma tag, and pair the two recursive results at a product.
If 𝑠:∏𝑗:𝐼∏𝑢:[[𝐷(𝑗)]](𝖬𝗎(𝐷))𝖠𝗅𝗅𝐷(𝑗)(𝑃,𝑢)→𝑃(𝑗,𝗋𝗈𝗅𝗅𝑗(𝑢)), then the elimination rule gives 𝗂𝗇𝖽𝐷(𝑃,𝑠;𝑗,𝑡):𝑃(𝑗,𝑡), with the computation equation 𝗂𝗇𝖽𝐷(𝑃,𝑠;𝑗,𝗋𝗈𝗅𝗅𝑗(𝑢))≡𝑠𝑗(𝑢,𝖼𝖺𝗅𝗅𝗌𝐷(𝑗)(𝑃,𝗂𝗇𝖽𝐷(𝑃,𝑠),𝑢)).
Referenced from 3 locations
For 𝑙,𝑟 :𝖬𝗎(𝐷𝖳𝗋𝖾𝖾(𝐴)), product introduction gives (𝑙,𝑟) :[[𝖷( ⋆) ×𝖷( ⋆)]](𝖬𝗎(𝐷𝖳𝗋𝖾𝖾(𝐴))). Sum introduction and Mu-intro therefore derive 𝖿𝗈𝗋𝗄(𝑙,𝑟):𝖬𝗎(𝐷𝖳𝗋𝖾𝖾(𝐴)). At this constructor, (80.1) replaces the two 𝖠𝗅𝗅 components by the two recursive calls. If instead 𝑥 :𝖬𝗎(𝐷)(𝑗) is a variable, neither 𝗈𝗎𝗍𝑗(𝑥) nor 𝗂𝗇𝖽𝐷(𝑃,𝑠;𝑗,𝑥) has a root computation rule; both are neutral.
★☆☆ Expand the interpretations of the vector code at zero and at 𝗌𝗎𝖼(𝑛). Write the two resulting constructor types and match them with definition 78.1. Then take 𝑃(𝑛,𝑥𝑠):=ℕ and write the two methods of a length-counting use of 𝗂𝗇𝖽𝐷𝖵𝖾𝖼(𝐴).
Referenced from 3 locations
Generic action, folds, and traversals
The interpretation is functorial in its recursive family. For a family of maps ℎ𝑗 :𝑋(𝑗) →𝑌(𝑗), define 𝑢:[[𝐷]](𝑋) ⊢ 𝗆𝖺𝗉𝐷(ℎ,𝑢):[[𝐷]](𝑌). by recursion on 𝐷. It is the identity on 𝗈𝗇𝖾 and constants, applies ℎ𝑗 at 𝖷(𝑗), preserves the chosen summand, maps both product components, and preserves the Sigma tag while mapping its remainder.
Let 𝑋,𝑌,𝑍 :𝐼 →U𝑖, let 𝑓𝑗 :𝑋(𝑗) →𝑌(𝑗) and 𝑔𝑗 :𝑌(𝑗) →𝑍(𝑗), and let 𝐷 :𝖣𝖾𝗌𝖼𝑖(𝐼). For 𝑢 :[[𝐷]](𝑋): 𝗆𝖺𝗉𝐷(𝜆𝑗.𝜆𝑥.𝑥,𝑢)=𝑢,𝗆𝖺𝗉𝐷(𝜆𝑗.𝜆𝑥.𝑔𝑗(𝑓𝑗(𝑥)),𝑢)=𝗆𝖺𝗉𝐷(𝑔,𝗆𝖺𝗉𝐷(𝑓,𝑢)). The laws are stated at the argument 𝑢; they assert no identity between functions.
Referenced from 3 locations
Proof of Lemma 80.5 — Interpretation functor laws
Proof. Induct on 𝐷. The unit, constant, and recursive-position cases reduce to reflexivity or beta computation at 𝑓𝑗,𝑔𝑗; the laws assume no equations about those maps. A sum retains its injection and uses the induction hypothesis on its payload. A product uses the two induction hypotheses and function congruence for pairing. For 𝗌𝗂𝗀𝗆𝖺(𝐴,𝐹), fix 𝑎 :𝐴; the induction hypothesis for 𝐹(𝑎) proves the second component while the first component remains 𝑎. These cases exhaust the code grammar. ◻
Let ℎ,ℎ′ :(𝑗 :𝐼) →𝑋(𝑗) →𝑌(𝑗), and suppose 𝑝𝑗,𝑥 :ℎ𝑗(𝑥) =ℎ′𝑗(𝑥) for every 𝑗 :𝐼 and 𝑥 :𝑋(𝑗). Then, for every 𝐷 :𝖣𝖾𝗌𝖼𝑖(𝐼) and 𝑢 :[[𝐷]](𝑋), 𝗆𝖺𝗉𝐷(ℎ,𝑢)=𝗆𝖺𝗉𝐷(ℎ′,𝑢).
Referenced from 2 locations
Proof of Lemma 80.6 — Congruence of description action
Proof. Induct on 𝐷. The recursive-position case is 𝑝𝑗,𝑢. Unit and constant codes give reflexivity. A sum follows its injection, a product applies the two induction hypotheses under pairing, and a Sigma code fixes its tag 𝑎 :𝐴 and applies the induction hypothesis for the branch 𝐹(𝑎). ◻
Let ℎ,ℎ′ :(𝑗 :𝐼) →𝑋(𝑗) →𝑌(𝑗). For 𝑢 :[[𝐷]](𝑋), an inhabitant of 𝖠𝗅𝗅𝐷(𝜆𝑗.𝜆𝑥.𝖨𝖽𝑌(𝑗)(ℎ𝑗(𝑥),ℎ′𝑗(𝑥)),𝑢) determines an identification 𝗆𝖺𝗉𝐷(ℎ,𝑢) =𝗆𝖺𝗉𝐷(ℎ′,𝑢).
Referenced from 3 locations
Proof of Lemma 80.7 — Layer-local congruence
Proof. Induct on 𝐷. At 𝖷(𝑗) use the supplied path. Unit and constants give reflexivity. Sums follow their injection, products use both components of the 𝖠𝗅𝗅 witness, and Sigma codes retain their tag and use the branch induction hypothesis. ◻
An 𝐷-algebra on 𝑋 :𝐼 →U𝑖 is a family 𝛼𝑗:[[𝐷(𝑗)]](𝑋)→𝑋(𝑗). For 𝐸 :𝖣𝖾𝗌𝖼𝑖(𝐼), 𝑢 :[[𝐸]](𝖬𝗎(𝐷)), and 𝑞 :𝖠𝗅𝗅𝐸(𝜆𝑗.𝜆𝑡.𝑋(𝑗),𝑢), define 𝗋𝖾𝖿𝗂𝗅𝗅𝐸(𝑢,𝑞) :[[𝐸]](𝑋) by the equations 𝗋𝖾𝖿𝗂𝗅𝗅𝗈𝗇𝖾(⋆,⋆)≡⋆,𝗋𝖾𝖿𝗂𝗅𝗅𝖪(𝐴)(𝑎,⋆)≡𝑎,𝗋𝖾𝖿𝗂𝗅𝗅𝖷(𝑗)(𝑥,𝑞)≡𝑞,𝗋𝖾𝖿𝗂𝗅𝗅𝐸+𝐺(𝗂𝗇𝗅(𝑢),𝑞)≡𝗂𝗇𝗅(𝗋𝖾𝖿𝗂𝗅𝗅𝐸(𝑢,𝑞)),𝗋𝖾𝖿𝗂𝗅𝗅𝐸+𝐺(𝗂𝗇𝗋(𝑣),𝑞)≡𝗂𝗇𝗋(𝗋𝖾𝖿𝗂𝗅𝗅𝐺(𝑣,𝑞)),𝗋𝖾𝖿𝗂𝗅𝗅𝐸×𝐺((𝑢,𝑣),(𝑞𝐸,𝑞𝐺))≡(𝗋𝖾𝖿𝗂𝗅𝗅𝐸(𝑢,𝑞𝐸),𝗋𝖾𝖿𝗂𝗅𝗅𝐺(𝑣,𝑞𝐺)),𝗋𝖾𝖿𝗂𝗅𝗅𝗌𝗂𝗀𝗆𝖺(𝐴,𝐻)((𝑎,𝑢),𝑞)≡(𝑎,𝗋𝖾𝖿𝗂𝗅𝗅𝐻(𝑎)(𝑢,𝑞)). Define 𝖿𝗈𝗅𝖽𝐷(𝛼)𝑗 :𝖬𝗎(𝐷)(𝑗) →𝑋(𝑗) by description induction, using the method 𝛼𝑗(𝗋𝖾𝖿𝗂𝗅𝗅𝐷(𝑗)(𝑢,𝑞)).
Referenced from 3 locations
Let 𝐷 :𝐼 →𝖣𝖾𝗌𝖼𝑖(𝐼), let 𝛼 be a 𝐷-algebra on 𝑋 :𝐼 →U𝑖, let 𝑗 :𝐼, and let 𝑢 :[[𝐷(𝑗)]](𝖬𝗎(𝐷)). The generic fold satisfies the propositional calculation rule 𝖿𝗈𝗅𝖽𝐷(𝛼)𝑗(𝗋𝗈𝗅𝗅𝑗(𝑢))=𝛼𝑗(𝗆𝖺𝗉𝐷(𝑗)(𝖿𝗈𝗅𝖽𝐷(𝛼))(𝑢)).
Referenced from 2 locations
Proof of Lemma 80.9 — Fold calculation
Proof. Equation (80.1) reduces the left side to 𝛼𝑗(𝗋𝖾𝖿𝗂𝗅𝗅𝐷(𝑗)(𝑢,𝑞)), where 𝑞 contains the recursive fold results. Induction on 𝐷(𝑗) proves 𝗋𝖾𝖿𝗂𝗅𝗅𝐷(𝑗)(𝑢,𝑞)=𝗆𝖺𝗉𝐷(𝑗)(𝖿𝗈𝗅𝖽𝐷(𝛼),𝑢). The unit, constant, and recursive-position cases are reflexivity. Sums and Sigma codes follow the selected branch, and products use both induction hypotheses under pairing. Applying 𝛼𝑗 to this path gives (80.2). ◻
For lists, the algebra sends the left summand to a chosen 𝑧 :𝑋 and the right summand (𝑎,𝑥) to 𝑐(𝑎,𝑥). Expanding (80.2) gives 𝖿𝗈𝗅𝖽(𝑧,𝑐,𝗇𝗂𝗅)=𝑧,𝖿𝗈𝗅𝖽(𝑧,𝑐,𝖼𝗈𝗇𝗌(𝑎,𝑥𝑠))=𝑐(𝑎,𝖿𝗈𝗅𝖽(𝑧,𝑐,𝑥𝑠)). Thus the familiar fold equations are consequences of the code interpretation, not separate axioms.
For 𝐴 :U𝑖, let 𝖲𝖾𝖾𝖽(𝐴) :U𝑖 have constructors 𝗌𝗍𝗈𝗉:𝐴→𝖲𝖾𝖾𝖽(𝐴),𝗌𝗉𝗅𝗂𝗍:𝖲𝖾𝖾𝖽(𝐴)→𝖲𝖾𝖾𝖽(𝐴)→𝖲𝖾𝖾𝖽(𝐴). Define 𝛾:𝖲𝖾𝖾𝖽(𝐴)→[[𝐷𝖳𝗋𝖾𝖾(𝐴)]](𝖲𝖾𝖾𝖽(𝐴)) by 𝛾(𝗌𝗍𝗈𝗉(𝑎)):=𝗂𝗇𝗅(𝑎),𝛾(𝗌𝗉𝗅𝗂𝗍(𝑙,𝑟)):=𝗂𝗇𝗋((𝑙,𝑟)). Structural recursion on the seed defines 𝖺𝗇𝖺(𝛾,𝑠):=𝗋𝗈𝗅𝗅(𝗆𝖺𝗉𝐷𝖳𝗋𝖾𝖾(𝐴)(𝖺𝗇𝖺(𝛾,−),𝛾(𝑠))). Put 𝑠12:=𝗌𝗉𝗅𝗂𝗍(𝗌𝗍𝗈𝗉(1),𝗌𝗍𝗈𝗉(2)). Then 𝖺𝗇𝖺(𝛾,𝑠12)≡𝗋𝗈𝗅𝗅(𝗂𝗇𝗋((𝖺𝗇𝖺(𝛾,𝗌𝗍𝗈𝗉(1)),𝖺𝗇𝖺(𝛾,𝗌𝗍𝗈𝗉(2)))))≡𝖿𝗈𝗋𝗄(𝗅𝖾𝖺𝖿(1),𝗅𝖾𝖺𝖿(2)). Equation (80.3) is a terminating program on an inductive seed; it does not assert a final-coalgebra or unrestricted corecursion principle.
Referenced from 2 locations
Let 𝛼 be a 𝐷-algebra on 𝑋, let 𝛽 be a 𝐷-algebra on 𝑌, and let ℎ𝑗 :𝑋(𝑗) →𝑌(𝑗). Suppose that for every 𝑗 :𝐼 and 𝑢 :[[𝐷(𝑗)]](𝑋), ℎ𝑗(𝛼𝑗(𝑢))=𝛽𝑗(𝗆𝖺𝗉𝐷(𝑗)(ℎ,𝑢)). Then, for every 𝑡 :𝖬𝗎(𝐷)(𝑗), ℎ𝑗(𝖿𝗈𝗅𝖽𝐷(𝛼)𝑗(𝑡))=𝖿𝗈𝗅𝖽𝐷(𝛽)𝑗(𝑡).
Referenced from 4 locations
Proof of Theorem 80.11 — Fold fusion
Proof. Apply description induction to 𝑡 =𝗋𝗈𝗅𝗅𝑗(𝑢). Write 𝑓:=𝖿𝗈𝗅𝖽𝐷(𝛼) and 𝑔:=𝖿𝗈𝗅𝖽𝐷(𝛽). The induction hypotheses form 𝐻:𝖠𝗅𝗅𝐷(𝑗)(𝜆𝑘.𝜆𝑥.𝖨𝖽𝑌(𝑘)(ℎ𝑘(𝑓𝑘(𝑥)),𝑔𝑘(𝑥)),𝑢). The constructor case is the annotated calculation below. Write (F) for (80.2), (A) for the algebra hypothesis, (M) for map composition from lemma 80.5, and (H) for lemma 80.7 instantiated by the induction hypotheses. ℎ𝑗(𝑓𝑗(𝗋𝗈𝗅𝗅𝑗(𝑢)))(𝐹)=ℎ𝑗(𝛼𝑗(𝗆𝖺𝗉𝐷(𝑗)(𝑓,𝑢)))(𝐴)=𝛽𝑗(𝗆𝖺𝗉𝐷(𝑗)(ℎ,𝗆𝖺𝗉𝐷(𝑗)(𝑓,𝑢)))(𝑀),𝑏𝑎𝑐𝑘𝑤𝑎𝑟𝑑𝑠=𝛽𝑗(𝗆𝖺𝗉𝐷(𝑗)(𝜆𝑘.𝜆𝑥.ℎ𝑘(𝑓𝑘(𝑥)),𝑢))(𝐻)=𝛽𝑗(𝗆𝖺𝗉𝐷(𝑗)(𝑔,𝑢))(𝐹),𝑏𝑎𝑐𝑘𝑤𝑎𝑟𝑑𝑠=𝑔𝑗(𝗋𝗈𝗅𝗅𝑗(𝑢)). ◻
For 𝑔 :(𝑗 :𝐼) →𝑋(𝑗) →ℕ and 𝑢 :[[𝐷]](𝑋), define 𝗌𝗎𝗆𝐷(𝑔,𝑢) :ℕ by recursion on 𝐷: constants and unit contribute zero, a recursive position 𝑥 :𝑋(𝑗) contributes 𝑔𝑗(𝑥), a sum follows its injection, a product adds its contributions, and a Sigma follows its tag. The algebra 𝛼𝑗(𝑢):=𝗌𝗎𝖼(𝗌𝗎𝗆𝐷(𝑗)(𝜆𝑘.𝜆𝑛.𝑛,𝑢)) therefore gives 𝗌𝗂𝗓𝖾𝐷 :𝖬𝗎(𝐷)(𝑗) →ℕ by definition 80.8. For a list, expansion gives 𝗌𝗂𝗓𝖾(𝗇𝗂𝗅)=𝗌𝗎𝖼(𝟢),𝗌𝗂𝗓𝖾(𝖼𝗈𝗇𝗌(𝑎,𝑥𝑠))=𝗌𝗎𝖼(𝗌𝗂𝗓𝖾(𝑥𝑠)). This size counts constructor nodes; it does not count constant payloads.
Referenced from 3 locations
Define 𝑥 ◃𝐸𝑢 by recursion on 𝐸: it holds by reflexivity at a recursive-position code, follows the selected summand or Sigma branch, and follows either component of a product. If 𝑥 ◃𝐷(𝑗)𝑢, then 𝗌𝗎𝖼(𝗌𝗂𝗓𝖾𝐷(𝑥))≤𝗌𝗂𝗓𝖾𝐷(𝗋𝗈𝗅𝗅𝑗(𝑢)).
Referenced from 3 locations
Proof of Lemma 80.13 — An immediate recursive child is smaller
Proof. Induct on the derivation of 𝑥 ◃𝐷(𝑗)𝑢. At a recursive-position code, the fold calculation expands the right side to 𝗌𝗎𝖼(𝗌𝗂𝗓𝖾𝐷(𝑥)). Sums and Sigma codes reduce to the selected branch. At a product, the right side is one plus the sum of the contributions of both components, so the induction hypothesis is preserved by addition of the nonnegative contribution of the other component. These are all clauses of the structurally defined relation. ◻
An applicative traversal interface consists of a type operator 𝐹 :U𝑖 →U𝑖 and, for 𝐴,𝐵 :U𝑖, operations 𝗉𝗎𝗋𝖾𝐴:𝐴→𝐹(𝐴),𝖺𝗉𝗉𝗅𝗒𝐴,𝐵:𝐹(𝐴→𝐵)→𝐹(𝐴)→𝐹(𝐵). Write 𝗆𝖺𝗉𝐹(𝑓,𝑥):=𝖺𝗉𝗉𝗅𝗒(𝗉𝗎𝗋𝖾(𝑓),𝑥). For 𝑓,𝑔 :𝐴 →𝐵, the interface carries the extensional action law ((𝑎:𝐴)→𝑓(𝑎)=𝑔(𝑎))→(𝑥:𝐹(𝐴))→𝗆𝖺𝗉𝐹(𝑓,𝑥)=𝗆𝖺𝗉𝐹(𝑔,𝑥). This law concerns the action on one given 𝑥; it does not assert 𝑓 =𝑔.
For 𝐴,𝐵,𝐶 :U𝑖, put 𝑐:(𝐵→𝐶)→(𝐴→𝐵)→𝐴→𝐶,𝑐(𝑓,𝑔,𝑥):=𝑓(𝑔(𝑥)), and, for 𝑢 :𝐹(𝐵 →𝐶) and 𝑣 :𝐹(𝐴 →𝐵), put 𝑞(𝑢,𝑣):=𝖺𝗉𝗉𝗅𝗒(𝖺𝗉𝗉𝗅𝗒(𝗉𝗎𝗋𝖾(𝑐),𝑢),𝑣). The four pointwise laws are 𝖺𝗉𝗉𝗅𝗒(𝗉𝗎𝗋𝖾(𝗂𝖽𝐴),𝑥)=𝑥,𝖺𝗉𝗉𝗅𝗒(𝑞(𝑢,𝑣),𝑤)=𝖺𝗉𝗉𝗅𝗒(𝑢,𝖺𝗉𝗉𝗅𝗒(𝑣,𝑤)),𝖺𝗉𝗉𝗅𝗒(𝗉𝗎𝗋𝖾(𝑓),𝗉𝗎𝗋𝖾(𝑎))=𝗉𝗎𝗋𝖾(𝑓(𝑎)),𝖺𝗉𝗉𝗅𝗒(𝑢,𝗉𝗎𝗋𝖾(𝑎))=𝖺𝗉𝗉𝗅𝗒(𝗉𝗎𝗋𝖾(𝜆𝑓.𝑓(𝑎)),𝑢). Here 𝑥,𝑤 :𝐹(𝐴) in the first two equations. The third equation quantifies over 𝑓 :𝐴 →𝐵 and 𝑎 :𝐴; the fourth quantifies over 𝑢 :𝐹(𝐴 →𝐵) and 𝑎 :𝐴. The bound variable 𝑓 :𝐴 →𝐵 in the final right-hand side is the argument of the pure evaluation function. Equation (80.5) gives identity for 𝗆𝖺𝗉𝐹. Its composition law uses (80.6) followed by two instances of (80.7); these instances reduce the two pure functions to 𝗉𝗎𝗋𝖾(𝜆𝑥.𝑓(𝑔(𝑥))).
Referenced from 2 locations
Let 𝐹 be an applicative traversal interface, let 𝑋,𝑌 :𝐼 →U𝑖, and let 𝐷 :𝖣𝖾𝗌𝖼𝑖(𝐼). Recursion on 𝐷 defines 𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝐷:(∏𝑗:𝐼𝑋(𝑗)→𝐹(𝑌(𝑗)))→[[𝐷]](𝑋)→𝐹([[𝐷]](𝑌)). The defining clauses are 𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝗈𝗇𝖾(𝑓,⋆):=𝗉𝗎𝗋𝖾(⋆),𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝖪(𝐴)(𝑓,𝑎):=𝗉𝗎𝗋𝖾(𝑎),𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝖷(𝑗)(𝑓,𝑥):=𝑓𝑗(𝑥),𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝐷+𝐸(𝑓,𝗂𝗇𝗅(𝑢)):=𝗆𝖺𝗉𝐹(𝗂𝗇𝗅,𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝐷(𝑓,𝑢)),𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝐷+𝐸(𝑓,𝗂𝗇𝗋(𝑣)):=𝗆𝖺𝗉𝐹(𝗂𝗇𝗋,𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝐸(𝑓,𝑣)),𝑢𝐹:=𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝐷(𝑓,𝑢),𝑣𝐹:=𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝐸(𝑓,𝑣),𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝐷×𝐸(𝑓,(𝑢,𝑣)):=𝖺𝗉𝗉𝗅𝗒(𝗆𝖺𝗉𝐹(𝜆𝑥.𝜆𝑦.(𝑥,𝑦),𝑢𝐹),𝑣𝐹),𝑤𝐹:=𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝐺(𝑎)(𝑓,𝑢),𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝗌𝗂𝗀𝗆𝖺(𝐴,𝐺)(𝑓,(𝑎,𝑢)):=𝗆𝖺𝗉𝐹(𝜆𝑣.(𝑎,𝑣),𝑤𝐹).
Referenced from 2 locations
For applicative interfaces 𝐹 and 𝐺, put 𝖢𝗈𝗆𝗉(𝐹,𝐺)(𝐴):=𝐹(𝐺(𝐴)). Its operations are 𝗉𝗎𝗋𝖾𝖢𝗈𝗆𝗉(𝐹,𝐺)(𝑎):=𝗉𝗎𝗋𝖾𝐹(𝗉𝗎𝗋𝖾𝐺(𝑎)),𝖺𝗉𝗉𝗅𝗒𝖢𝗈𝗆𝗉(𝐹,𝐺)(𝑢,𝑣):=𝖺𝗉𝗉𝗅𝗒𝐹(𝖺𝗉𝗉𝗅𝗒𝐹(𝗉𝗎𝗋𝖾𝐹(𝖺𝗉𝗉𝗅𝗒𝐺),𝑢),𝑣).
Referenced from 3 locations
Let 𝐹 and 𝐺 be applicative traversal interfaces. Assume function extensionality for types in U𝑖: ∏𝐴,𝐵:U𝑖∏𝑓,𝑔:𝐴→𝐵((𝑎:𝐴)→𝑓(𝑎)=𝑔(𝑎))→𝑓=𝑔. The operations of definition 80.16 satisfy (80.5)–(80.8) and (80.4).
Referenced from 3 locations
Proof of Lemma 80.17 — Composite applicative laws
Proof. For composition, expand every composite application and use (80.6) for 𝐹. Both sides then have the outer forms obtained from 𝗅𝗂𝖿𝗍𝟥𝐹(𝑘,𝑢,𝑣,𝑤):=𝖺𝗉𝗉𝗅𝗒𝐹(𝖺𝗉𝗉𝗅𝗒𝐹(𝖺𝗉𝗉𝗅𝗒𝐹(𝗉𝗎𝗋𝖾𝐹(𝑘),𝑢),𝑣),𝑤). They are 𝗅𝗂𝖿𝗍𝟥𝐹(𝑘𝐿,𝑢,𝑣,𝑤) and 𝗅𝗂𝖿𝗍𝟥𝐹(𝑘𝑅,𝑢,𝑣,𝑤). For 𝑢𝐺 :𝐺(𝐵 →𝐶), 𝑣𝐺 :𝐺(𝐴 →𝐵), and 𝑤𝐺 :𝐺(𝐴), the two pure functions satisfy 𝑘𝐿(𝑢𝐺,𝑣𝐺,𝑤𝐺):=𝖺𝗉𝗉𝗅𝗒𝐺(𝑞𝐺(𝑢𝐺,𝑣𝐺),𝑤𝐺),𝑘𝑅(𝑢𝐺,𝑣𝐺,𝑤𝐺):=𝖺𝗉𝗉𝗅𝗒𝐺(𝑢𝐺,𝖺𝗉𝗉𝗅𝗒𝐺(𝑣𝐺,𝑤𝐺)). Equation (80.6) for 𝐺 gives their pointwise equality. Three applications of (80.9) give 𝑘𝐿 =𝑘𝑅. Congruence under 𝗉𝗎𝗋𝖾𝐹 and the three outer applications therefore gives the composite composition law. The extensionality hypothesis is essential at this step: the unary action law (80.4) does not turn equality after three arguments into equality of the intervening function values.
For identity, put 𝑒𝐺(𝑥):=𝖺𝗉𝗉𝗅𝗒𝐺(𝗉𝗎𝗋𝖾𝐺(𝗂𝖽),𝑥). Expansion gives the annotated calculation 𝖺𝗉𝗉𝗅𝗒𝖢𝗈𝗆𝗉(𝐹,𝐺)(𝗉𝗎𝗋𝖾𝖢𝗈𝗆𝗉(𝐹,𝐺)(𝗂𝖽),𝑢)(80.7)𝑓𝑜𝑟𝐹=𝗆𝖺𝗉𝐹(𝑒𝐺,𝑢)(80.4)𝑓𝑜𝑟𝐹𝑎𝑛𝑑(80.5)𝑓𝑜𝑟𝐺=𝗆𝖺𝗉𝐹(𝗂𝖽,𝑢)(80.5)𝑓𝑜𝑟𝐹=𝑢. Homomorphism reduces by two instances of (80.7) for 𝐹 and one for 𝐺. Interchange expands to two outer 𝐹 actions; one application of (80.9) turns the pointwise 𝐺 interchange law into the equality between their pure functions, after which (80.8) for 𝐹 closes the calculation.
Finally, the homomorphism law for 𝐹 gives 𝗆𝖺𝗉𝖢𝗈𝗆𝗉(𝐹,𝐺)(𝑟,𝑢)=𝗆𝖺𝗉𝐹(𝗆𝖺𝗉𝐺(𝑟),𝑢). Pointwise equality 𝑟(𝑎) =𝑠(𝑎) gives 𝗆𝖺𝗉𝐺(𝑟,𝑥) =𝗆𝖺𝗉𝐺(𝑠,𝑥) by extensional action for 𝐺. Extensional action for 𝐹 then proves the displayed law for the composite. ◻
Put 𝖨𝖽(𝐴):=𝐴, 𝗉𝗎𝗋𝖾𝖨𝖽(𝑎):=𝑎, and 𝖺𝗉𝗉𝗅𝗒𝖨𝖽(𝑓,𝑎):=𝑓(𝑎). Its four applicative laws are judgmental beta equalities. Its extensional action is the supplied pointwise path evaluated at 𝑎.
Referenced from 3 locations
Let 𝑋,𝑌,𝑍 :𝐼 →U𝑖, let 𝐷 :𝖣𝖾𝗌𝖼𝑖(𝐼), and let 𝑢 :[[𝐷]](𝑋). For 𝑓𝑗 :𝑋(𝑗) →𝑌(𝑗) and the identity applicative of definition 80.18, 𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝐷(𝑓,𝑢)=𝗆𝖺𝗉𝐷(𝑓,𝑢). Let 𝐹,𝐺 be applicative interfaces and assume (80.9). Put 𝐻:=𝖢𝗈𝗆𝗉(𝐹,𝐺) and give 𝐻 the composite applicative structure. Suppose 𝑓𝑗:𝑋(𝑗)→𝐹(𝑌(𝑗)),𝑔𝑗:𝑌(𝑗)→𝐺(𝑍(𝑗)). Put ℎ𝑗(𝑥):=𝗆𝖺𝗉𝐹(𝑔𝑗,𝑓𝑗(𝑥)) and 𝑣:=𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝐹𝐷(𝑓,𝑢). Then 𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝐻𝐷(ℎ,𝑢)=𝗆𝖺𝗉𝐹(𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝐺𝐷(𝑔),𝑣).
Referenced from 2 locations
Proof of Proposition 80.19 — Traversal laws
Proof. Induct on 𝐷. For identity, unit, constant, and recursive-position codes reduce by beta computation. Sum and Sigma codes apply their induction hypothesis under the corresponding constructor. At a product, the identity applicative reduces the traversal clause to (𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝐷(𝑓,𝑢1),𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝐸(𝑓,𝑢2)). The two induction hypotheses give the two components required by the product clause of 𝗆𝖺𝗉𝐷×𝐸.
For composition, abbreviate 𝗅𝗂𝖿𝗍𝟤𝐹(𝑘,𝑥,𝑦):=𝖺𝗉𝗉𝗅𝗒𝐹(𝗆𝖺𝗉𝐹(𝑘,𝑥),𝑦). Let 𝐴0,𝐴1,𝐵0,𝐵1,𝐶 :U𝑖, let 𝑥 :𝐹(𝐴0) and 𝑦 :𝐹(𝐵0), and let 𝑟 :𝐴0 →𝐺(𝐴1), 𝑠 :𝐵0 →𝐺(𝐵1), and 𝑘 :𝐴1 →𝐵1 →𝐶. Expansion of the composite application, followed by the composition and homomorphism laws for 𝐹, gives 𝗅𝗂𝖿𝗍𝟤𝖢𝗈𝗆𝗉(𝐹,𝐺)(𝑘,𝗆𝖺𝗉𝐹(𝑟,𝑥),𝗆𝖺𝗉𝐹(𝑠,𝑦))=𝗆𝖺𝗉𝐹(𝜆𝑝.𝗅𝗂𝖿𝗍𝟤𝐺(𝑘,𝑟(𝗉𝗋1(𝑝)),𝑠(𝗉𝗋2(𝑝))),𝗅𝗂𝖿𝗍𝟤𝐹(𝗉𝖺𝗂𝗋,𝑥,𝑦)). The only equality between functions in this expansion is obtained from (80.9); its pointwise components are the composition laws for 𝐹 and 𝐺 proved in lemma 80.17. In the product case, apply (80.10) with 𝑘:=𝗉𝖺𝗂𝗋. The two induction hypotheses give the pointwise replacements for 𝑟 and 𝑠, and (80.4) for 𝐹 applies them under the outer action. Sum and Sigma codes are the unary instance of the same calculation. Unit, constant, and recursive-position codes reduce to the applicative identity, homomorphism, and composition equations. The code induction has now treated all constructors. ◻
Define the writer applicative by 𝖶(𝐴):=ℕ×𝐴,𝗉𝗎𝗋𝖾𝖶(𝑎):=(𝟢,𝑎), and 𝖺𝗉𝗉𝗅𝗒𝖶((𝑚,𝑓),(𝑛,𝑎)):=(𝑚+𝑛,𝑓(𝑎)). The unit and associativity equations for addition prove the four applicative laws. Extensional action applies the pointwise path to the second component and preserves the writer count. The product clause of traversal performs visible work on a list layer. Put 𝑇(𝑓,𝑢):=𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝖶𝐷𝖫𝗂𝗌𝗍(𝐴)(𝑓,𝑢). If 𝑓(𝑥) =(𝑛,𝑦), then 𝑇(𝑓,𝗂𝗇𝗋((𝑎,𝑥)))≡𝗆𝖺𝗉𝖶(𝗂𝗇𝗋,𝖺𝗉𝗉𝗅𝗒𝖶(𝗆𝖺𝗉𝖶(𝜆𝑎.𝜆𝑦.(𝑎,𝑦),(𝟢,𝑎)),(𝑛,𝑦)))≡(𝑛,𝗂𝗇𝗋((𝑎,𝑦))). Thus the constant field contributes no effect and the recursive child’s count is retained.
Lift this layer traversal to the fixed point by a fold. For 𝑢:[[𝐷(𝑗)]](𝜆𝑘.𝖶(𝖬𝗎(𝐷)(𝑘))), put 𝑝𝑗(𝑢):=𝗍𝗋𝖺𝗏𝖾𝗋𝗌𝖾𝖶𝐷(𝑗)(𝜆𝑘.𝜆𝑧.𝑧,𝑢),𝛼𝖶𝑗(𝑢):=(𝗌𝗎𝖼(𝗉𝗋1(𝑝𝑗(𝑢))),𝗋𝗈𝗅𝗅𝑗(𝗉𝗋2(𝑝𝑗(𝑢)))). Then 𝗏𝗂𝗌𝗂𝗍𝐷:=𝖿𝗈𝗅𝖽𝐷(𝛼𝖶) has type 𝗏𝗂𝗌𝗂𝗍𝐷,𝑗:𝖬𝗎(𝐷)(𝑗)→𝖶(𝖬𝗎(𝐷)(𝑗)). For the list 𝖼𝗈𝗇𝗌(1,𝖼𝗈𝗇𝗌(2,𝗇𝗂𝗅)), the three fold equations give 𝗏𝗂𝗌𝗂𝗍𝐷𝖫𝗂𝗌𝗍(ℕ)(𝖼𝗈𝗇𝗌(1,𝖼𝗈𝗇𝗌(2,𝗇𝗂𝗅)))=(3,𝖼𝗈𝗇𝗌(1,𝖼𝗈𝗇𝗌(2,𝗇𝗂𝗅))). The result 3 counts two 𝖼𝗈𝗇𝗌 constructors and the terminal 𝗇𝗂𝗅 constructor.
Referenced from 2 locations
★★☆ Encode list map as a fold over 𝐷𝖫𝗂𝗌𝗍(𝐴), then expand (80.2) at 𝗇𝗂𝗅 and 𝖼𝗈𝗇𝗌. Prove the identity-map law by list induction or by theorem 80.11, stating the algebra equation used in the fusion proof.
Referenced from 3 locations
The indexed strictly-positive-family universe
The regular codes above name recursive sorts directly. A genuinely indexed description must also say how constructor data constrain the result index and how recursive arguments are indexed. We now freeze the Morris–Altenkirch–Ghani universe rather than pretending that an arbitrary family of regular codes is already its full syntax.
Let ⃗𝐼 =(𝐼1,…,𝐼𝑛) be a telescope of input-family index types and let 𝑂 :U𝑖 be the output index. An indexed strictly positive type code 𝑇 :𝖨𝖲𝖯𝖳(⃗𝐼) has input variables 𝗏𝗓(𝑖) and 𝗏𝗌(𝑇), the codes 𝟢 and 𝟣, dependent index aggregation Σ𝑓(𝐹,𝑜′) and Π𝑓(𝐹,𝑜′), and the fixed-point code 𝜇(𝐹,𝑜′). Here 𝑓 :𝑂 →𝑂′, 𝐹 :𝑂 →𝖨𝖲𝖯𝖳(⃗𝐼), and 𝑜′ :𝑂′ for Σ and Π, while a family description is 𝖲𝖯𝖥(⃗𝐼,𝑂):=𝑂→𝖨𝖲𝖯𝖳(⃗𝐼). The syntax is indexed by the complete input telescope; the output index is an argument to a family code, not a meta-level case split hidden from the universe.
For an environment 𝜌 assigning a family to each input variable, the interpretation selects that family at 𝗏𝗓/𝗏𝗌 and has [[𝟢]]𝜌:=𝟎,[[𝟣]]𝜌:=𝟏,[[Σ𝑓(𝐹,𝑜′)]]𝜌:=∑𝑜:𝑂𝖨𝖽𝑂′(𝑓(𝑜),𝑜′)×[[𝐹(𝑜)]]𝜌,[[Π𝑓(𝐹,𝑜′)]]𝜌:=∏𝑜:𝑂𝖨𝖽𝑂′(𝑓(𝑜),𝑜′)→[[𝐹(𝑜)]]𝜌,[[𝜇(𝐹,𝑜′)]]𝜌:=𝖬𝗎(𝜆𝑜.[[𝐹(𝑜)]]𝜌,−)(𝑜′). The last line extends 𝜌 by the family being defined before interpreting recursive variables. Its introduction equation is syntactic: 𝗈𝗎𝗍𝑜′(𝗋𝗈𝗅𝗅𝑜′(𝑢))≡𝑢. The Σ𝑓 code chooses one witness whose index maps to 𝑜′; the Π𝑓 code stores data at every such witness. These are distinct codes, not abbreviations for ordinary sum and function types outside the universe.
Finite regular sums and products compile into this universe. A Boolean Σ over the constant map into the unique output yields binary choice; finite Π yields a product. A constant payload is a nonrecursive input field, and a regular recursive position is a variable followed by 𝜇. This recovers the Benke–Dybjer–Jansson regular presentation as a bounded derived normal form: it does not replace the principal indexed syntax.
The vector family is now an internal code. Its zero constructor chooses the result index 𝟢 and carries unit; its cons constructor chooses 𝑛 :ℕ, stores 𝑎 :𝐴, requests one recursive child at 𝑛, and returns 𝗌𝗎𝖼(𝑛). In the earlier regular notation its two fibers normalize to 𝐷𝖵𝖾𝖼(𝐴)(𝟢):=𝗈𝗇𝖾,𝐷𝖵𝖾𝖼(𝐴)(𝗌𝗎𝖼(𝑛)):=𝖪(𝐴)×𝖷(𝑛). Thus 𝗋𝗈𝗅𝗅𝟢( ⋆) and 𝗋𝗈𝗅𝗅𝗌𝗎𝖼(𝑛)((𝑎,𝑥𝑠)) have exactly the constructor indices of definition 78.1. The displayed normal forms are derived from the index equality stored by Σ𝑓; they are not an assertion that every indexed family is an external case split.
Map, fold, traversal, and induction extend by structural recursion on 𝖨𝖲𝖯𝖳. At Σ𝑓 they preserve the witness and its index equality, and at Π𝑓 they act pointwise. At 𝜇 they use the recursive map or fold supplied by the extended environment. The identity/composition and fusion proofs add one congruence case for each constructor. We do not identify these codes with containers: shapes and positions begin in the next chapter.
★★☆ Expand the Σ𝑓 interpretation for the vector cons constructor at output 𝑚 :ℕ. Show that a witness 𝑛 contributes only when 𝗌𝗎𝖼(𝑛) =𝑚, and specialize the calculation to 𝑚 =𝗌𝗎𝖼(𝑘).
Referenced from 3 locations
Induction, equality, and elaboration
Generic equality needs more than strict positivity. The full MAG universe contains Π𝑓, hence possibly infinite branching, and its Σ𝑓 index witnesses need not have decidable equality. We therefore prove equality only for a smaller finite regular fragment, exactly as the source does.
The grammar 𝖤𝗊𝖣𝖾𝗌𝖼𝑖(𝐼) contains 𝗈𝗇𝖾,𝖪(𝐴,𝑑𝐴),𝖷(𝑗),𝐷+𝐸,𝐷×𝐸. where 𝑑𝐴 decides equality on every stored constant type. It contains no 𝗌𝗂𝗀𝗆𝖺, Π𝑓, or arbitrary index-witness code. Tags are the syntactic left/right constructors, so they are decidable by inspection. Erasure ⌊ −⌋ :𝖤𝗊𝖣𝖾𝗌𝖼𝑖(𝐼) →𝖣𝖾𝗌𝖼𝑖(𝐼) forgets the stored decisions.
Referenced from 2 locations
Let 𝑑:∏𝑎,𝑏:𝐴𝖨𝖽𝐴(𝑎,𝑏)+¬𝖨𝖽𝐴(𝑎,𝑏). Then 𝗎𝗂𝗉𝐴:∏𝑎,𝑏:𝐴∏𝑝,𝑞:𝖨𝖽𝐴(𝑎,𝑏)𝖨𝖽𝖨𝖽𝐴(𝑎,𝑏)(𝑝,𝑞).
Referenced from 3 locations
Proof of Lemma 80.22 — Decidable equality gives local UIP
Proof. Fix 𝑎,𝑏 :𝐴 and put 𝐸𝑎,𝑏:=𝖨𝖽𝐴(𝑎,𝑏). Define an endomap 𝑓𝑎,𝑏 :𝐸𝑎,𝑏 →𝐸𝑎,𝑏 by eliminating 𝑑(𝑎,𝑏): 𝑓𝑎,𝑏(𝑝):=𝑟if 𝑑(𝑎,𝑏)≡𝗂𝗇𝗅(𝑟),𝑓𝑎,𝑏(𝑝):=𝗋𝖾𝖼𝟎(𝑛(𝑝))if 𝑑(𝑎,𝑏)≡𝗂𝗇𝗋(𝑛). This endomap is weakly constant. In the positive case both outputs are 𝑟; in the negative case 𝑛(𝑝) :𝟎 eliminates to an identification between the outputs. Write the resulting path as 𝜅𝑎,𝑏(𝑝,𝑞) :𝑓𝑎,𝑏(𝑝) =𝑓𝑎,𝑏(𝑞).
Path induction on 𝑝 :𝐸𝑎,𝑏 gives 𝑝=𝑓𝑎,𝑎(𝗋𝖾𝖿𝗅)−1⋅𝑓𝑎,𝑏(𝑝). The reflexivity case is the inverse law from theorem 30.20. For 𝑝,𝑞 :𝐸𝑎,𝑏, write (P) for (80.12) and (K) for 𝖺𝗉𝜆𝑟.𝑓𝑎,𝑎(𝗋𝖾𝖿𝗅)−1⋅𝑟(𝜅𝑎,𝑏(𝑝,𝑞)). Then 𝑝(𝑃)=𝑓𝑎,𝑎(𝗋𝖾𝖿𝗅)−1⋅𝑓𝑎,𝑏(𝑝)(𝐾)=𝑓𝑎,𝑎(𝗋𝖾𝖿𝗅)−1⋅𝑓𝑎,𝑏(𝑞)(𝑃),𝑏𝑎𝑐𝑘𝑤𝑎𝑟𝑑𝑠=𝑞. Thus the supplied decision procedure gives UIP at this occurrence; no ambient UIP axiom is used. ◻
Let 𝐷 :𝐼 →𝖤𝗊𝖣𝖾𝗌𝖼𝑖(𝐼). Equality on 𝖬𝗎(⌊𝐷⌋)(𝑗) is decidable for every 𝑗 :𝐼.
Referenced from 3 locations
Proof of Theorem 80.23 — Generic decidable equality
Proof. Define a bounded comparison by ordinary natural-number recursion with the fuel bound in its domain. Here 𝑚 >𝑛 abbreviates 𝗌𝗎𝖼(𝑛) ≤𝑚: 𝖣𝖾𝖼𝖤𝗊𝐴(𝑥,𝑦):=𝖨𝖽𝐴(𝑥,𝑦)+¬𝖨𝖽𝐴(𝑥,𝑦). 𝖾𝗊𝑁:∏𝑗:𝐼∏𝑡,𝑢:𝖬𝗎(⌊𝐷⌋)(𝑗)𝑁>𝗌𝗂𝗓𝖾⌊𝐷⌋(𝑡)+𝗌𝗂𝗓𝖾⌊𝐷⌋(𝑢)→𝖣𝖾𝖼𝖤𝗊𝖬𝗎(⌊𝐷⌋)(𝑗)(𝑡,𝑢). At zero, the bound implies 𝟢 >𝗌𝗂𝗓𝖾⌊𝐷⌋(𝑡) +𝗌𝗂𝗓𝖾⌊𝐷⌋(𝑢) and eliminates to the required decision. Thus the zero clause does not manufacture a disequality. At a successor, compare the two layers obtained by 𝗈𝗎𝗍𝑗. The completeness invariant is 𝑁>𝗌𝗂𝗓𝖾⌊𝐷⌋(𝑡)+𝗌𝗂𝗓𝖾⌊𝐷⌋(𝑢). For arbitrary 𝑡,𝑢 :𝖬𝗎(⌊𝐷⌋)(𝑗), invoke it initially at 𝑁:=𝗌𝗂𝗓𝖾⌊𝐷⌋(𝑡)+𝗌𝗂𝗓𝖾⌊𝐷⌋(𝑢)+𝗌𝗎𝖼(𝟢). The successor clause uses a second recursion on the code. Unit layers agree. Constant positions use the decision stored in 𝖪(𝐴,𝑑𝐴). A sum first compares its injections; equal injections recurse on their payloads, and unequal injections use disjointness. Products compare the left components and then the right components, combining positive paths by pair congruence and transporting a negative component decision backwards along the corresponding projection. Recursive positions invoke 𝖾𝗊𝗉𝗋𝖾𝖽(𝑁) on the selected proper subtrees. If 𝑡′,𝑢′ are those children, two applications of lemma 80.13, followed by addition, give 𝗌𝗂𝗓𝖾⌊𝐷⌋(𝑡′)+𝗌𝗂𝗓𝖾⌊𝐷⌋(𝑢′)+2≤𝗌𝗂𝗓𝖾⌊𝐷⌋(𝑡)+𝗌𝗂𝗓𝖾⌊𝐷⌋(𝑢). Hence (80.14) implies 𝗉𝗋𝖾𝖽(𝑁) >𝗌𝗂𝗓𝖾⌊𝐷⌋(𝑡′) +𝗌𝗂𝗓𝖾⌊𝐷⌋(𝑢′), the completeness hypothesis for the recursive call.
The definition is accepted because it is structurally recursive on 𝑁; the size inequality proves completeness rather than termination. For soundness, congruence of 𝗋𝗈𝗅𝗅𝑗 turns an accepted layer path into a path between terms. For completeness, apply 𝖺𝗉𝗈𝗎𝗍𝑗( −) to any path between the two rolls, obtaining a layer path, and then recurse on the code. Products split their path into component paths. Sums use constructor disjointness and injectivity. No dependent tag witness or function-space constructor occurs in this grammar; adding either requires a new coherence or finite-enumerability argument. In particular, lemma 80.22 is not used to enlarge the accepted code fragment. ◻
Let 𝑑ℕ be the usual decision procedure on natural numbers and let 𝐷=𝖳𝗋𝖾𝖾(ℕ) be the 𝖤𝗊𝖣𝖾𝗌𝖼 code obtained from the tree code by storing 𝑑ℕ at its constant position. Its first nontrivial tests expose the sum tag before any recursive call: 𝖾𝗊3(𝗅𝖾𝖺𝖿(1),𝗅𝖾𝖺𝖿(1);𝜋2<3)≡𝗂𝗇𝗅(𝗋𝖾𝖿𝗅),𝖾𝗊5(𝖿𝗈𝗋𝗄(𝗅𝖾𝖺𝖿(1),𝗅𝖾𝖺𝖿(2)),𝗅𝖾𝖺𝖿(1);𝜋4<5)≡𝗂𝗇𝗋(𝑛𝗍𝖺𝗀). Here 𝜋2<3 and 𝜋4<5 are the canonical natural-order witnesses, and 𝑛𝗍𝖺𝗀 is obtained by disjointness of 𝗂𝗇𝗅 and 𝗂𝗇𝗋; the rejected comparison does not inspect either subtree.
Consider the declaration 𝖽𝖺𝗍𝖺𝖳𝗋𝖾𝖾(𝐴)𝗐𝗁𝖾𝗋𝖾𝗅𝖾𝖺𝖿:𝐴→𝖳𝗋𝖾𝖾(𝐴),𝖿𝗈𝗋𝗄:𝖳𝗋𝖾𝖾(𝐴)→𝖳𝗋𝖾𝖾(𝐴)→𝖳𝗋𝖾𝖾(𝐴). Elaboration first assigns one sum tag per constructor. The leaf arguments give 𝖪(𝐴); the two fork arguments give 𝖷( ⋆) ×𝖷( ⋆). Hence the result is 𝐷𝖳𝗋𝖾𝖾(𝐴) defined in section 80.1. Constructor elaboration produces the definitions of 𝗅𝖾𝖺𝖿 and 𝖿𝗈𝗋𝗄 given there. The positivity checker rejects an argument 𝖳𝗋𝖾𝖾(𝐴) →𝐴 because no code constructor translates a recursive occurrence on the left of an arrow. The elaborator therefore produces either a code and constructor translations or the structured diagnostic NegativeRecursiveOccurrence. This diagnostic reports the rejected class but does not retain a source-location path through the surface type.
Referenced from 3 locations
Suppose a surface declaration has well-formed parameters, every constructor result is the declared family at a well-formed index, and the argument elaborator accepts every recursive occurrence as strictly positive. If it returns a description 𝐷 and constructor translations ⃗𝑐, then 𝐷 is well formed in the selected description universe and every 𝑐𝑖 has the source constructor type with the declared family replaced by 𝖬𝗎(𝐷). In particular the displayed Tree declaration elaborates to 𝐷𝖳𝗋𝖾𝖾(𝐴) and both generated constructors are well typed.
Referenced from 2 locations
Proof of Theorem 80.25 — Soundness of the displayed elaboration
Proof. Induct on the constructor list, and inside one constructor induct on its argument telescope. A nonrecursive argument 𝐵 contributes 𝖪(𝐵) after its source formation derivation establishes 𝐵 :U𝑖. A recursive argument at index 𝑗 contributes 𝖷(𝑗) after the result-index premise establishes 𝑗 :𝐼. Products concatenate fields and sums concatenate constructors, preserving well-formedness by the code formation rules. The strict-positivity premise excludes the only unsupported case, a recursive occurrence to the left of an arrow. Finally Mu-intro wraps each interpreted layer. Unfolding the interpretation gives the original constructor telescope, with recursive occurrences replaced by 𝖬𝗎(𝐷), so each generated 𝑐𝑖 has the claimed type. The Tree calculation is the two code clauses displayed in construction 80.24.
This is the local specialization of the soundness shape in Dagand–McBride, Theorem 4 ['EDM12]: their conclusion is validity of the generated declaration after successful elaboration. We have proved it only for the surface grammar and target codes displayed here; no completeness or equivalence with a host language’s inductive declarations follows. ◻
The elaborated code, its fold, its induction principle, and its equality test compose in one bounded derivation: the Tree declaration elaborates to a code, its fold comes from (80.2), its induction principle is definition 80.4, and its equality test uses theorem 80.23 when 𝐴 has decidable equality. No container representation or row-polymorphic extensibility has entered the argument. Extensible generic datatypes additionally assume decidable labels, row membership, and coherent row permutation; those assumptions are not rules of 𝖣𝖾𝗌𝖼𝑖(𝐼).
★★★ Extend the code grammar by 𝗉𝗂(𝐴,𝐹) with interpretation ∏𝑎:𝐴[[𝐹(𝑎)]](𝑋). Prove that the recursive family remains in positive position. State the universe level of the code and interpretation. Then identify the extra hypotheses needed for generic traversal and decidable equality; in particular, explain why decidable equality of each codomain does not decide equality of functions when 𝐴 is infinite.
Referenced from 3 locations
A binding description
Ordinary descriptions treat every recursive child at the same scope. A lambda body instead lives in a context extended by the bound variable. A regular recursive-position code cannot distinguish these two cases. Binding descriptions repair exactly that defect by storing the telescope introduced above each recursive child.
Let 𝑆 :U𝑖 be a type of object sorts, let 𝖢𝗍𝗑(𝑆) be lists of sorts, and let 𝖾𝗑𝗍(Ξ,Γ) denote the context obtained by placing the finite telescope Ξ before Γ: 𝖾𝗑𝗍([],Γ):=Γ,𝖾𝗑𝗍(𝐵::Ξ,Γ):=𝐵::𝖾𝗑𝗍(Ξ,Γ).
A binding description over 𝑆 has codes 𝖻𝗈𝗇𝖾,𝖻𝖪(𝐴),𝐸𝖻+𝐺,𝐸𝖻×𝐺,𝖻𝗌𝗂𝗀𝗆𝖺(𝐴,𝐻),𝗋𝖾𝖼(Ξ,𝐵), where 𝐴 :U𝑖, 𝐵 :𝑆, and Ξ :𝖢𝗍𝗑(𝑆). For a scoped family 𝑋 :(Γ :𝖢𝗍𝗑(𝑆)) →𝑆 →U𝑖, interpretation at Γ is the regular unit, constant, sum, product, and Sigma interpretation, with the recursive clause 𝖤𝗅Γ(𝗋𝖾𝖼(Ξ,𝐵),𝑋):=𝑋(𝖾𝗑𝗍(Ξ,Γ),𝐵).
Fix a constructor code 𝐹 :𝑆 →𝖡𝖣𝖾𝗌𝖼𝑖(𝑆) and a variable family 𝑉 :(Γ :𝖢𝗍𝗑(𝑆)) →𝑆 →U𝑖. The free syntax 𝖳𝗆𝐹(𝑉;Γ,𝐴) has constructors 𝗏𝖺𝗋:𝑉(Γ,𝐴)→𝖳𝗆𝐹(𝑉;Γ,𝐴),𝖼𝗈𝗇:𝖤𝗅Γ(𝐹(𝐴),𝖳𝗆𝐹(𝑉;−,−))→𝖳𝗆𝐹(𝑉;Γ,𝐴). Its induction principle has one method for variables and, at a constructor, one induction hypothesis for every 𝗋𝖾𝖼(Ξ,𝐵) position. Thus the code, rather than an operation defined later, determines where the context is extended.
Referenced from 2 locations
Suppose 𝑋 is scoped over Γ and 𝑌 over Δ. A family ℎΞ,𝐵:𝑋(𝖾𝗑𝗍(Ξ,Γ),𝐵)→𝑌(𝖾𝗑𝗍(Ξ,Δ),𝐵) induces 𝖻𝗆𝖺𝗉𝐸(ℎ) :𝖤𝗅Γ(𝐸,𝑋) →𝖤𝗅Δ(𝐸,𝑌) by recursion on 𝐸. It applies ℎΞ,𝐵 at 𝗋𝖾𝖼(Ξ,𝐵) and follows the remaining code constructors.
Let 𝐸 :𝖡𝖣𝖾𝗌𝖼𝑖(𝑆), and let 𝑋,𝑌,𝑍 be scoped families over Γ,Δ,Θ. Let ℎΞ,𝐵:𝑋(𝖾𝗑𝗍(Ξ,Γ),𝐵)→𝑌(𝖾𝗑𝗍(Ξ,Δ),𝐵),𝑘Ξ,𝐵:𝑌(𝖾𝗑𝗍(Ξ,Δ),𝐵)→𝑍(𝖾𝗑𝗍(Ξ,Θ),𝐵). For 𝑢 :𝖤𝗅Γ(𝐸,𝑋), binding-layer action satisfies 𝖻𝗆𝖺𝗉𝐸(𝜆Ξ.𝜆𝐵.𝗂𝖽,𝑢)=𝑢,𝖻𝗆𝖺𝗉𝐸(𝑘,𝖻𝗆𝖺𝗉𝐸(ℎ,𝑢))=𝖻𝗆𝖺𝗉𝐸(𝜆Ξ.𝜆𝐵.𝜆𝑥.𝑘Ξ,𝐵(ℎΞ,𝐵(𝑥)),𝑢). If ℎ′ has the type of ℎ and 𝑝Ξ,𝐵,𝑥 :ℎΞ,𝐵(𝑥) =ℎ′Ξ,𝐵(𝑥) at every recursive position, then 𝖻𝗆𝖺𝗉𝐸(ℎ,𝑢)=𝖻𝗆𝖺𝗉𝐸(ℎ′,𝑢).
Referenced from 4 locations
Proof of Lemma 80.27 — Binding-layer action laws
Proof. Induct on 𝐸. At 𝗋𝖾𝖼(Ξ,𝐵) the three claims are respectively the identity equation, composition equation, and pointwise path. Unit and constants give reflexivity. Sums follow their injection, products use the two induction hypotheses, and Sigma codes retain their tag and use the branch induction hypothesis. These cases prove all three laws. ◻
Take 𝑉(Γ,𝐴):=𝖵𝖺𝗋(Γ,𝐴), the intrinsically typed de Bruijn variables. For 𝐵 :𝑆, their newest and older constructors have types 𝗏𝗓:𝖵𝖺𝗋(𝐵::Γ,𝐵),𝗏𝗌:𝖵𝖺𝗋(Γ,𝐴)→𝖵𝖺𝗋(𝐵::Γ,𝐴). Define 𝖱𝖾𝗇(Γ,Δ):=(𝐴:𝑆)→𝖵𝖺𝗋(Γ,𝐴)→𝖵𝖺𝗋(Δ,𝐴),𝖲𝗎𝖻𝐹(Γ,Δ):=(𝐴:𝑆)→𝖵𝖺𝗋(Γ,𝐴)→𝖳𝗆𝐹(𝑉;Δ,𝐴). A renaming lifts through a telescope Ξ. For one new sort 𝐵, let 𝗐𝗄Γ𝐵(𝑥):=𝗏𝗌(𝑥) and define 𝗅𝗂𝖿𝗍[𝐵](𝜌)(𝗏𝗓):=𝗏𝗓,𝗅𝗂𝖿𝗍[𝐵](𝜌)(𝗏𝗌(𝑥)):=𝗏𝗌(𝜌(𝑥)). Put 𝗅𝗂𝖿𝗍[](𝜌):=𝜌,𝗅𝗂𝖿𝗍𝐵::Ξ(𝜌):=𝗅𝗂𝖿𝗍[𝐵](𝗅𝗂𝖿𝗍Ξ(𝜌)).
Free-syntax induction defines generic renaming: 𝗋𝖾𝗇𝐹(𝜌,𝗏𝖺𝗋(𝑥)):=𝗏𝖺𝗋(𝜌(𝑥)),𝗋𝖾𝗇𝐹(𝜌,𝖼𝗈𝗇(𝑢)):=𝖼𝗈𝗇(𝖻𝗆𝖺𝗉𝐹(𝐴)(𝜆Ξ.𝜆𝐵.𝗋𝖾𝗇𝐹(𝗅𝗂𝖿𝗍Ξ(𝜌)),𝑢)). A substitution lift may now use this renaming. Define 𝗅𝗂𝖿𝗍[𝐵](𝜎)(𝗏𝗓):=𝗏𝖺𝗋(𝗏𝗓),𝗅𝗂𝖿𝗍[𝐵](𝜎)(𝗏𝗌(𝑥)):=𝗋𝖾𝗇𝐹(𝗐𝗄Δ𝐵,𝜎(𝑥)). Put 𝗅𝗂𝖿𝗍[](𝜎):=𝜎,𝗅𝗂𝖿𝗍𝐵::Ξ(𝜎):=𝗅𝗂𝖿𝗍[𝐵](𝗅𝗂𝖿𝗍Ξ(𝜎)). Thus every newly introduced variable is fixed, and every older image is weakened through the whole telescope. Free-syntax induction then defines generic substitution: 𝗌𝗎𝖻𝐹(𝜎,𝗏𝖺𝗋(𝑥)):=𝜎(𝑥),𝗌𝗎𝖻𝐹(𝜎,𝖼𝗈𝗇(𝑢)):=𝖼𝗈𝗇(𝖻𝗆𝖺𝗉𝐹(𝐴)(𝜆Ξ.𝜆𝐵.𝗌𝗎𝖻𝐹(𝗅𝗂𝖿𝗍Ξ(𝜎)),𝑢)). Every context change occurs at the recursive-position clause that names its telescope.
Let 𝐹 :𝑆 →𝖡𝖣𝖾𝗌𝖼𝑖(𝑆) be any binding signature. Define environment composition pointwise at the following types. For 𝜌 :𝖱𝖾𝗇(Γ,Δ) and 𝜏 :𝖱𝖾𝗇(Δ,Θ), define 𝗋𝖼𝗈𝗆𝗉(𝜏,𝜌) :𝖱𝖾𝗇(Γ,Θ). For 𝜎 :𝖲𝗎𝖻𝐹(Γ,Δ) and 𝜏 :𝖲𝗎𝖻𝐹(Δ,Θ), define 𝜏 ⋆𝜎 :𝖲𝗎𝖻𝐹(Γ,Θ). The two mixed composites have types 𝗋𝗌𝗎𝖻(𝜎,𝜌):𝖲𝗎𝖻𝐹(Γ,Θ)(𝜌:𝖱𝖾𝗇(Γ,Δ),𝜎:𝖲𝗎𝖻𝐹(Δ,Θ)),𝗋𝗉𝗈𝗌𝗍(𝜌,𝜎):𝖲𝗎𝖻𝐹(Γ,Θ)(𝜎:𝖲𝗎𝖻𝐹(Γ,Δ),𝜌:𝖱𝖾𝗇(Δ,Θ)). Their values at a variable are 𝗋𝖼𝗈𝗆𝗉(𝜏,𝜌)(𝑥):=𝜏(𝜌(𝑥)),(𝜏⋆𝜎)(𝑥):=𝗌𝗎𝖻𝐹(𝜏,𝜎(𝑥)),𝗋𝗌𝗎𝖻(𝜎,𝜌)(𝑥):=𝜎(𝜌(𝑥)),𝗋𝗉𝗈𝗌𝗍(𝜌,𝜎)(𝑥):=𝗋𝖾𝗇𝐹(𝜌,𝜎(𝑥)). For every 𝑡 :𝖳𝗆𝐹(𝑉;Γ,𝐴), renaming identity holds. If 𝜌 :𝖱𝖾𝗇(Γ,Δ) and 𝜏 :𝖱𝖾𝗇(Δ,Θ), renaming composition holds: 𝗋𝖾𝗇𝐹(𝗂𝖽,𝑡)=𝑡,𝗋𝖾𝗇𝐹(𝜏,𝗋𝖾𝗇𝐹(𝜌,𝑡))=𝗋𝖾𝗇𝐹(𝗋𝖼𝗈𝗆𝗉(𝜏,𝜌),𝑡). Substitution identity holds. If 𝜎 :𝖲𝗎𝖻𝐹(Γ,Δ) and 𝜏 :𝖲𝗎𝖻𝐹(Δ,Θ), substitution composition holds: 𝗌𝗎𝖻𝐹(𝗏𝖺𝗋,𝑡)=𝑡,𝗌𝗎𝖻𝐹(𝜏,𝗌𝗎𝖻𝐹(𝜎,𝑡))=𝗌𝗎𝖻𝐹(𝜏⋆𝜎,𝑡). For 𝜌 :𝖱𝖾𝗇(Γ,Δ) and 𝜎 :𝖲𝗎𝖻𝐹(Δ,Θ), substitution after renaming is 𝗌𝗎𝖻𝐹(𝜎,𝗋𝖾𝗇𝐹(𝜌,𝑡))=𝗌𝗎𝖻𝐹(𝗋𝗌𝗎𝖻(𝜎,𝜌),𝑡). For 𝜎 :𝖲𝗎𝖻𝐹(Γ,Δ) and 𝜌 :𝖱𝖾𝗇(Δ,Θ), renaming after substitution is 𝗋𝖾𝗇𝐹(𝜌,𝗌𝗎𝖻𝐹(𝜎,𝑡))=𝗌𝗎𝖻𝐹(𝗋𝗉𝗈𝗌𝗍(𝜌,𝜎),𝑡). Finally, if 𝜌,𝜌′ :𝖱𝖾𝗇(Γ,Δ) satisfy 𝑝𝐴,𝑥 :𝜌𝐴(𝑥) =𝜌′𝐴(𝑥) for every 𝐴 :𝑆 and 𝑥 :𝖵𝖺𝗋(Γ,𝐴), then 𝗋𝖾𝗇𝐹(𝜌,𝑡) =𝗋𝖾𝗇𝐹(𝜌′,𝑡). If 𝜎,𝜎′ :𝖲𝗎𝖻𝐹(Γ,Δ) satisfy 𝑞𝐴,𝑥 :𝜎𝐴(𝑥) =𝜎′𝐴(𝑥) pointwise, then 𝗌𝗎𝖻𝐹(𝜎,𝑡) =𝗌𝗎𝖻𝐹(𝜎′,𝑡).
Referenced from 5 locations
Proof of Theorem 80.28 — Generic renaming and substitution laws
Proof. The proof is staged because lift compatibility for substitution composition uses both mixed laws on arbitrary substitution images.
First prove renaming congruence, identity, and composition by free-syntax induction. Variable cases are the corresponding environment paths. For a constructor 𝖼𝗈𝗇(𝑢), the recursive-position premises of lemma 80.27 are the induction hypotheses. Induction on Ξ and variable elimination give 𝗅𝗂𝖿𝗍Ξ(𝗂𝖽)∼𝗂𝖽,𝗅𝗂𝖿𝗍Ξ(𝗋𝖼𝗈𝗆𝗉(𝜏,𝜌))∼𝗋𝖼𝗈𝗆𝗉(𝗅𝗂𝖿𝗍Ξ(𝜏),𝗅𝗂𝖿𝗍Ξ(𝜌)), where 𝑒 ∼𝑒′ means pointwise equality. A newest variable gives reflexivity; an older variable reduces the second line to 𝗏𝗌(𝜏(𝜌(𝑥))) =𝗏𝗌(𝜏(𝜌(𝑥))).
Next prove substitution congruence and identity by the same syntax induction. The older-variable clause of the lifted identity is 𝗋𝖾𝗇𝐹(𝗐𝗄Γ𝐵,𝗏𝖺𝗋(𝑥))≡𝗏𝖺𝗋(𝗏𝗌(𝑥)). Prove substitution after renaming next. At an older variable, preservation of 𝗋𝗌𝗎𝖻 is definitional. Abbreviate ̂𝜎:=𝗅𝗂𝖿𝗍[𝐵](𝜎) and ̂𝜌:=𝗅𝗂𝖿𝗍[𝐵](𝜌). Then 𝗋𝗌𝗎𝖻(̂𝜎,̂𝜌)(𝗏𝗌(𝑥))≡𝗋𝖾𝗇𝐹(𝗐𝗄Θ𝐵,𝜎(𝜌(𝑥)))≡𝗅𝗂𝖿𝗍[𝐵](𝗋𝗌𝗎𝖻(𝜎,𝜌))(𝗏𝗌(𝑥)).
Renaming after substitution follows by syntax induction using the renaming composition law already proved. Its older-variable lift comparison is 𝗋𝗉𝗈𝗌𝗍(𝗅𝗂𝖿𝗍[𝐵](𝜌),𝗅𝗂𝖿𝗍[𝐵](𝜎))(𝗏𝗌(𝑥))definition=𝗋𝖾𝗇𝐹(𝗅𝗂𝖿𝗍[𝐵](𝜌),𝗋𝖾𝗇𝐹(𝗐𝗄Δ𝐵,𝜎(𝑥)))renaming composition=𝗋𝖾𝗇𝐹(𝗋𝖼𝗈𝗆𝗉(𝗅𝗂𝖿𝗍[𝐵](𝜌),𝗐𝗄Δ𝐵),𝜎(𝑥))variable elimination and renaming congruence=𝗋𝖾𝗇𝐹(𝗋𝖼𝗈𝗆𝗉(𝗐𝗄Θ𝐵,𝜌),𝜎(𝑥))renaming composition, backwards=𝗋𝖾𝗇𝐹(𝗐𝗄Θ𝐵,𝗋𝖾𝗇𝐹(𝜌,𝜎(𝑥)))definition=𝗅𝗂𝖿𝗍[𝐵](𝗋𝗉𝗈𝗌𝗍(𝜌,𝜎))(𝗏𝗌(𝑥)).
It remains to prove substitution composition. The newest-variable lift case is reflexivity. At an older variable, the two mixed laws give (𝗅𝗂𝖿𝗍[𝐵](𝜏)⋆𝗅𝗂𝖿𝗍[𝐵](𝜎))(𝗏𝗌(𝑥))substitution after renaming=𝗌𝗎𝖻𝐹(𝗋𝗌𝗎𝖻(𝗅𝗂𝖿𝗍[𝐵](𝜏),𝗐𝗄Δ𝐵),𝜎(𝑥))pointwise lift equation=𝗌𝗎𝖻𝐹(𝗋𝗉𝗈𝗌𝗍(𝗐𝗄Θ𝐵,𝜏),𝜎(𝑥))renaming after substitution, backwards=𝗋𝖾𝗇𝐹(𝗐𝗄Θ𝐵,𝗌𝗎𝖻𝐹(𝜏,𝜎(𝑥)))definition=𝗅𝗂𝖿𝗍[𝐵](𝜏⋆𝜎)(𝗏𝗌(𝑥)). Induction on Ξ iterates each one-sort comparison. Binding-layer congruence converts the resulting pointwise lift paths into constructor paths. At no stage is an equality between environment functions used. ◻
Let 𝗐𝗄Γ𝐵 :𝖱𝖾𝗇(Γ,𝐵 ::Γ) be the inclusion. For 𝜏 :𝖲𝗎𝖻𝐹(Γ,Δ) and 𝑡 :𝖳𝗆𝐹(𝑉;Γ,𝐴), the final equation of theorem 80.28, followed by the substitution-after-renaming equation, gives the naturality law 𝗋𝖾𝗇𝐹(𝗐𝗄Δ𝐵,𝗌𝗎𝖻𝐹(𝜏,𝑡))=𝗌𝗎𝖻𝐹(𝗅𝗂𝖿𝗍[𝐵](𝜏),𝗋𝖾𝗇𝐹(𝗐𝗄Γ𝐵,𝑡)). Indeed, both sides are substitutions into 𝑡. On a variable 𝑥 their environments reduce to 𝗋𝖾𝗇𝐹(𝗐𝗄Δ𝐵,𝜏(𝑥)); generic environment congruence proves the displayed equality. The same derivation applies in an extended context because the theorem quantifies over arbitrary source and target contexts.
For simply typed lambda terms, take 𝑆:=𝖳𝗒, generated by 𝑜 and arrows, and define 𝐹𝜆(𝐴):=𝖻𝗌𝗂𝗀𝗆𝖺(𝖳𝗒,𝐵.𝗋𝖾𝖼([],𝐵→𝐴)𝖻×𝗋𝖾𝖼([],𝐵))𝖻+𝖠𝖻𝗌(𝐴),𝖠𝖻𝗌(𝑜):=𝖻𝖪(𝟎),𝖠𝖻𝗌(𝐵→𝐶):=𝗋𝖾𝖼([𝐵],𝐶). Write 𝖳𝗆(Γ,𝐴) for 𝖳𝗆𝐹𝜆(𝖵𝖺𝗋;Γ,𝐴). The two constructor summands are 𝖺𝗉𝗉 and 𝗅𝖺𝗆. The generic equations become 𝗋𝖾𝗇(𝜌,𝖺𝗉𝗉(𝑡,𝑢))≡𝖺𝗉𝗉(𝗋𝖾𝗇(𝜌,𝑡),𝗋𝖾𝗇(𝜌,𝑢)),𝗋𝖾𝗇(𝜌,𝗅𝖺𝗆(𝑡))≡𝗅𝖺𝗆(𝗋𝖾𝗇(𝗅𝗂𝖿𝗍[𝐵](𝜌),𝑡)),𝗌𝗎𝖻(𝜎,𝗅𝖺𝗆(𝑡))≡𝗅𝖺𝗆(𝗌𝗎𝖻(𝗅𝗂𝖿𝗍[𝐵](𝜎),𝑡)).
The four concrete representations in chapter 23 instantiate different boundaries of this theorem. Typed de Bruijn syntax is the displayed 𝖵𝖺𝗋 instance. Locally nameless syntax changes the variable family but retains telescope lifting. PHOAS replaces environments by a parametric host family, so its exclusion of exotic terms still requires the parametricity theorem proved there. Contextual syntax exposes Γ in open terms and substitutions. The generic theorem gives the common scope-safe traversal and fusion argument; it does not give LF adequacy, nominal freshness, or PHOAS parametricity.
★★☆ Prove the final equation of theorem 80.28 for an abstraction 𝗅𝖺𝗆(𝑡). Write both lifted environments on an arbitrary newest variable and on an arbitrary older variable before invoking induction on 𝑡.
Referenced from 3 locations
Suggested first pass.
Begin with exercise 80.6, exercise 80.7.
★★☆ For binary trees, define a mirror algebra and a node-counting algebra. Use theorem 80.11 to prove that node count is invariant under mirror. Expand the algebra-commuting hypothesis in the leaf and fork summands.
Referenced from 4 locations
★★☆ Reconstruct the renaming-after-substitution equation of theorem 80.28 at a constructor 𝖼𝗈𝗇(𝑢). State the recursive-position premise supplied by lemma 80.27. Then specialize it to the 𝗅𝖺𝗆 constructor, where the stored telescope is [𝐵].
Referenced from 4 locations
★★☆ Run the bounded equality procedure on the two layers (𝖿𝖺𝗅𝗌𝖾, ⋆) and (𝗍𝗋𝗎𝖾,(𝑙,𝑟)) of 𝐷𝖳𝖺𝗀𝗀𝖾𝖽. Identify the first rejected comparison. Then remove the decision procedure for 𝟐 from the Sigma equality data and state the exact algorithmic clause that can no longer be executed.
Referenced from 3 locations
★★★ Practical project.generic-description-interpreter Implement in Kappa the six constructors of 𝖣𝖾𝗌𝖼𝑖(𝐼), their interpretation for regular codes, 𝗋𝗈𝗅𝗅, generic map, fold, and size. Maintain the invariant that every recursive position is interpreted by the family parameter and no negative occurrence is accepted. Elaborate the displayed Tree declaration, construct 𝖿𝗈𝗋𝗄(𝗅𝖾𝖺𝖿(1),𝗅𝖾𝖺𝖿(2)), and produce size 3 and the leaf list [1,2]. Represent the Boolean-indexed instance of 𝗌𝗂𝗀𝗆𝖺 by a tag-to-code lookup, and test that its false tag accepts a unit payload while its true tag accepts a pair of recursive payloads; both crossed payload shapes must be rejected. The acceptance test must also reject a declaration with constructor argument 𝖳𝗋𝖾𝖾(𝐴) →𝐴, reporting a negative recursive occurrence.
Referenced from 4 locations
Sources. The principal indexed syntax is the ISPT/SPF universe of Morris, Altenkirch, and Ghani, pp. 6–12 [MAG09]; its separate indexed-regular equality fragment is the one isolated on pp. 18–20. The finite regular normal form and its generic programs reconstruct the source-bounded method of Benke, Dybjer, and Jansson, Universes for Generic Programs and Proofs in Dependent Type Theory [BDJ03]; it does not replace the principal indexed language. The surface elaboration and local soundness theorem follow the judgment shape and proof decomposition of Dagand and McBride, pp. 12–16 ['EDM12]. The binding instance follows the type- and scope-safe description discipline of Allais, Atkey, Chapman, McBride, and McKinna [AAC^+21]. Hubers and Morris add extensible rows to a different generic universe [HM23b]; no row assumption is used in the core theorems here.