Systems D and DC: A Dependent Haskell Core Specification
Prerequisites. Direct starred prerequisites: Chapter 131. The dependent function and equality rules of chapter 26 supply the remaining prerequisites. No later core chapter depends on this route.
Consider the vector zip whose two arguments are known to have the same length: 𝗓𝗂𝗉:Π−𝑛:𝖭𝖺𝗍→Π−𝑎:⋆→Π−𝑏:⋆→𝖵𝖾𝖼𝑎𝑛→𝖵𝖾𝖼𝑏𝑛→𝖵𝖾𝖼(𝑎,𝑏)𝑛. Three of its five arguments are marked Π−: the length 𝑛 and the two element types are to be erased before the program runs. In chapter 131 that decision was made by a syntactic class — types and coercions were erased, terms were kept. Here 𝑛 is a natural number, an ordinary run-time value of an ordinary type, and yet it must be erased. The class “type” has stopped coinciding with the class “erasable”.
Nor can erasability be read off the type. The body of 𝗓𝗂𝗉 matches on a vector whose constructor carries an equality constraint, and the branch for the empty vector must produce a value at type 𝖵𝖾𝖼(𝑎,𝑏)𝑛 using the assumption 𝑛=0. Reusing the mechanism of chapter 131, that assumption is a coercion, and the coercion must also be erased. So a single calculus must classify three different things — what is computed, what is erased, and what is proved — and it must do so while allowing types to contain arbitrary, possibly divergent, terms.
This chapter freezes Systems D and DC of Weirich, Voizard, Azevedo de Amorim and Eisenberg (2017), whose syntax, judgments, typing rules, definitional equality and prop equality are that paper’s Figures 1–9. D is the implicit language: it has no annotations and an undecidable type system, and it is where the soundness argument lives. DC is the annotated language: its type checking is decidable and its types are unique, and it is connected to D by an erasure that forgets exactly the annotations.
𝜌::=+∣−relevance,𝑎,𝑏,𝐴,𝐵::=⋆∣𝑥∣𝐹∣𝜆𝜌𝑥.𝑎∣𝑎𝑏𝜌∣◻∣Π𝜌𝑥:𝐴→𝐵∣Λ𝑐.𝑎∣𝑎[∙]∣∀𝑐:𝜙.𝐴,𝜙::=𝑎∼𝐴𝑏propositions,𝑣::=𝜆+𝑥.𝑎∣𝜆−𝑥.𝑣∣Λ𝑐.𝑎∣⋆∣Π𝜌𝑥:𝐴→𝐵∣∀𝑐:𝜙.𝐴,Γ::=∅∣Γ,𝑥:𝐴∣Γ,𝑐:𝜙,Δ::=∅∣Δ,𝑐availableset,Σ::=∅∣Σ∪{𝐹∼𝑎:𝐴}signature. One sort ⋆ classifies every type, and ⋆:⋆. Terms and types share this syntax. Write 𝐴→𝐵 for Π+𝑥:𝐴→𝐵 when 𝑥 does not occur free in 𝐵, and 𝜙⇒𝐴 for ∀𝑐:𝜙.𝐴 when 𝑐 does not occur free in 𝐴.
Three binders must be distinguished at once. 𝜆+ abstracts a value the body may use; 𝜆− abstracts a value the body may not use, and whose argument is therefore written ◻ at the application site; Λ𝑐 abstracts a proof of an equality proposition, discharged by the token ∙. The three eliminations are 𝑎𝑏+, 𝑎◻− and 𝑎[∙].
Reduction is call by name and deterministic. The one rule that is not standard is E-AbsTerm, which reduces under an irrelevant abstraction; correspondingly 𝜆−𝑥.𝑣 is a value only when its body is one. The reason is visible in the source language: a Haskell generalization Λ𝑎.𝑒 must not delay the evaluation of 𝑒, because the source program has no abstraction there at all. Since D marks the position of an erased argument rather than deleting it, the reduction rule has to compensate.
Two features of definition 132.3 are worth stating before they are used. The relevance side condition of E-Abs is a condition on the body, not on the type: 𝜆−𝑥.𝑎 is well typed exactly when 𝑥 does not occur free in 𝑎, so an irrelevant argument is parametric in the strong sense that the body cannot inspect it. And E-Wff makes propositions homogeneous: 𝑎∼𝐴𝑏 is well formed only when 𝑎 and 𝑏 have the same type 𝐴. Remark 132.23 records what that choice buys.
Take Σ0={𝖥𝗂𝗑∼𝜆−𝑥.𝜆+𝑦.(𝑦(𝖥𝗂𝗑◻𝑦)):Π−𝑥:⋆→(𝑥→𝑥)→𝑥}. This one definition makes D a full-spectrum language with general recursion: every type is inhabited by 𝖥𝗂𝗑◻(𝜆+𝑧.𝑧), which by E-Axiom and two E-AppAbs steps reduces to itself. Nothing in this chapter proves termination or logical consistency, and subsection 132.3.1 explains why the property that is proved, and is also called consistency, is a different statement.
★☆☆ Check ⊨𝖥𝗂𝗑∼𝜆−𝑥.𝜆+𝑦.(𝑦(𝖥𝗂𝗑◻𝑦)):Π−𝑥:⋆→(𝑥→𝑥)→𝑥 against the signature rule, naming the rule at each node and checking the side condition of E-Abs at the 𝜆−. Then compute the first three reduction steps of 𝖥𝗂𝗑◻(𝜆+𝑧.𝑧).
Proof of Lemma 132.6 — Regularity of definitional equality
Proof. Induction on the equality derivation. E-Refl and E-Beta carry the typing of one side as a premise and obtain the other from theorem 132.11. E-Sym and E-Trans are immediate from the induction hypotheses. Each congruence rule reassembles the typing of both sides from the typings supplied by its premises, using the corresponding typing rule. E-Assn reads the proposition 𝑎∼𝐴𝑏 out of Γ; since ⊨Γ, E-Wff was checked when the binding was formed, so both Γ⊨𝑎:𝐴 and Γ⊨𝑏:𝐴. E-EqConv moves both typings along an equality of types by E-Conv. E-PiFst and E-PiSnd obtain their conclusions by inverting the typing of the two Π-types delivered by the induction hypothesis and applying lemma 132.9 in the second case. ◻
E-Assn is what separates this system from an ordinary intensional type theory: an assumed proposition may be used directly as a definitional equality. That is what makes a GADT branch type check, and it is exactly the feature that forces the available set into the judgment.
Let 𝖨𝗇𝗍 and 𝖡𝗈𝗈𝗅 be two distinct constants of type ⋆, and consider ∅;∅⊨∀𝑐:(𝖨𝗇𝗍∼⋆𝖡𝗈𝗈𝗅).𝖨𝗇𝗍≡∀𝑐:(𝖨𝗇𝗍∼⋆𝖡𝗈𝗈𝗅).𝖡𝗈𝗈𝗅:⋆. If E-CPiCong added 𝑐 to Δ when checking the bodies, this equality would be derivable: the propositions are identical, and under 𝑐:(𝖨𝗇𝗍∼⋆𝖡𝗈𝗈𝗅) with 𝑐 available, E-Assn gives 𝖨𝗇𝗍≡𝖡𝗈𝗈𝗅:⋆. The two sides of the conclusion are then two closed types with different head constants that are definitionally equal in the empty available set — and corollary 132.17 says that cannot happen. The rule as printed does not add 𝑐, and remark 132.8 shows the derivation stopping.
With 𝑐∉Δ, the derivation of example 132.7 has no step available at the leaf 𝖨𝗇𝗍≡𝖡𝗈𝗈𝗅: E-Assn requires 𝑐∈Δ, E-Beta requires a primitive reduction between two distinct constants, and no congruence rule matches two atoms. The cost is that some equalities that happen to be harmless are not derivable. The restriction is not needed everywhere: in E-CAppCong the premise Γ;̃Γ⊨𝑎≡𝑏:𝐴 exists only to make the two coercion applications type check, so it may use the full set. A rule uses Δ exactly where its premise is part of the equality being proved.
Proof. Induction on the typing derivation of 𝑏, building the equality congruence that matches each typing rule. At E-Var for 𝑥 the conclusion is the hypothesis; at any other variable, E-Refl. At E-Abs, E-App, E-Pi, E-CAbs and E-CApp the induction hypotheses feed E-AbsCong, E-AppCong, E-PiCong, E-CAbsCong and E-CAppCong, whose available sets are the same Δ in every position that carries the equality. The step that fails in a system whose congruence rules add the bound coercion variable to Δ is E-CAbs: there the body is compared under 𝑐:𝜙, and if that comparison had to be carried out in Δ,𝑐 the induction hypothesis, stated for Δ, would not apply. Because definition 132.5 keeps Δ fixed, the induction goes through. ◻
Proof. Induction on the typing derivation. The derivation ends either in E-Abs, which gives the four conclusions with 𝐴=Π𝜌𝑥:𝐴1→𝐵1 and the equality by E-Refl, or in E-Conv, whose premise Γ⊨𝜆𝜌𝑥.𝑏0:𝐴′ yields the data by the induction hypothesis and whose equality 𝐴′≡𝐴 is composed with the returned one by E-Trans. No other rule has a 𝜆 as its subject. ◻
Proof. The mechanism is worth naming: conversion makes inversion deliver a type that is only definitionally equal to the one in hand, so each beta case needs the injectivity of the corresponding type former to recover the domain and codomain. That is why E-PiFst, E-PiSnd, E-CPiFst and E-CPiSnd belong to definition 132.5 rather than being derived afterwards.
E-AppAbs. Let Γ⊨(𝜆𝜌𝑥.𝑣)𝑎𝜌:𝐴. Inverting the application rule gives Γ⊨𝜆𝜌𝑥.𝑣:Π𝜌𝑥:𝐴0→𝐵0, Γ⊨𝑎:𝐴0 and 𝐴=𝐵0[𝑎/𝑥]. Lemma 132.10 gives 𝐴1,𝐵1 with Γ;̃Γ⊨Π𝜌𝑥:𝐴0→𝐵0≡Π𝜌𝑥:𝐴1→𝐵1:⋆ and Γ,𝑥:𝐴1⊨𝑣:𝐵1. By E-PiFst, Γ;̃Γ⊨𝐴0≡𝐴1:⋆, so E-Conv gives Γ⊨𝑎:𝐴1 and lemma 132.9 applied to the typing of 𝑣 gives Γ⊨𝑣[𝑎/𝑥]:𝐵1[𝑎/𝑥]. By E-PiSnd with E-Refl on 𝑎, Γ;̃Γ⊨𝐵0[𝑎/𝑥]≡𝐵1[𝑎/𝑥]:⋆, and one more E-Conv returns the type 𝐴.
E-CAppCAbs. The same argument with E-CPiFst and E-CPiSnd in place of E-PiFst and E-PiSnd, and with the substitution 𝑏[∙/𝑐] replacing 𝑣[𝑎/𝑥].
E-Axiom.E-Fam types 𝐹 at the 𝐴 recorded in Σ0, and well-formedness of Σ0 gives ∅⊨𝑎:𝐴; weakening moves it to Γ.
For one-step reduction, E-Prim is the three cases above, and E-AbsTerm, E-AppLeft and E-CAppLeft rebuild the typing derivation from the induction hypothesis using E-Abs, E-App or E-IApp, and E-CApp respectively. In E-AbsTerm the side condition 𝑥∉fv(𝑎) is preserved, because reduction does not introduce free variables. ◻
Write 𝖼𝗈𝗇𝗌𝗂𝗌𝗍𝖾𝗇𝗍𝐴𝐵 when it is not the case that 𝐴 and 𝐵 are types with different head forms; the head forms are ⋆, Π𝜌𝑥:𝐴→𝐵, ∀𝑐:𝜙.𝐴 and an applied variable or definition.
The soundness argument now has three steps: equality with an empty available set implies joinability; parallel reduction is confluent; and joinable types are consistent. The middle step is a substantial rewriting theorem and is imported exactly.
This is Theorem 4.6 of Weirich, Voizard, Azevedo de Amorim, and Eisenberg (2017). It is imported for their parallel reduction, defined for the syntax of definition 132.1 with the signature Σ0 treated opaquely. What it supplies here is exactly the diamond property; every use of it below is through theorem 132.16. No other property of parallel reduction is assumed, and nothing in this chapter reproves it.
Proof of Theorem 132.15 — Equality implies joinability
Proof. Induction on the equality derivation. The available set is empty, so E-Assn cannot fire — this is the one place where the restriction of definition 132.5 does the work, and it is why the theorem is stated with ∅. E-Refl gives 𝑎⇒∗𝑎. E-Beta gives 𝑎1⇒𝑎2, since every primitive reduction is a parallel reduction step. E-Sym is symmetry of ⇔. E-Trans needs theorem 132.14: from 𝑎⇒∗𝑑1, 𝑎1⇒∗𝑑1, 𝑎1⇒∗𝑑2, 𝑏⇒∗𝑑2, confluence gives a common reduct of 𝑑1 and 𝑑2, hence of 𝑎 and 𝑏. Every congruence rule is handled by joining the components and reassembling, because parallel reduction is a congruence. E-PiFst, E-PiSnd, E-CPiFst and E-CPiSnd are handled by observing that a common reduct of two Π-types is a Π-type whose components are common reducts of the components, again by theorem 132.14. ◻
Proof of Theorem 132.16 — Joinability implies consistency
Proof. Parallel reduction does not change the head form of ⋆, Π𝜌𝑥:𝐴→𝐵 or ∀𝑐:𝜙.𝐴: no reduction rule has one of these as a redex, and the congruence clauses rebuild the same head. So if 𝐴⇒∗𝑏 and 𝐵⇒∗𝑏 and both 𝐴 and 𝐵 are in head form, both heads equal the head of 𝑏. ◻
Two different statements are called consistency in this subject. Corollary 132.17 says that definitional equality does not identify two types with different heads; it is the canonical-forms input to theorem 132.19. Logical consistency — the existence of an uninhabited type — is false here, because example 132.4 inhabits every type. A Dependent Haskell term is therefore never a proof of the proposition its type encodes, and no result in this chapter should be read as saying otherwise.
Proof. Induction on the typing derivation. E-Star, E-Pi and E-CPi give values. E-Var cannot occur, since 𝑎 has no free term variable. E-Fam gives an E-Axiom step. E-Conv passes to its premise.
E-Abs. If 𝜌=+ the term is a value. If 𝜌=−, the induction hypothesis applies to the body in Γ,𝑥:𝐴; the extra binding is a term variable that does not occur free in the body, by the side condition of E-Abs, so the hypothesis of the theorem is preserved. Either the body is a value, and then 𝜆−𝑥.𝑎 is one, or the body steps, and E-AbsTerm lifts the step.
E-App and E-IApp. Apply the induction hypothesis to the function. If it steps, E-AppLeft lifts the step. If it is a value 𝑣 of type Π𝜌𝑥:𝐴0→𝐵0, then corollary 132.17 applies: by lemma 132.10 and the value grammar, 𝑣 is one of 𝜆𝜌𝑥.𝑏, ⋆, a Π-type, a ∀-type or Λ𝑐.𝑏. A closed value of the last four shapes has type ⋆ or a ∀-type, and Γ;∅⊨ that type ≡Π𝜌𝑥:𝐴0→𝐵0 would identify two different head forms, contradicting corollary 132.17. The available set is empty because Γ has no coercion assumption. Hence 𝑣=𝜆𝜌𝑥.𝑏 and E-AppAbs applies.
E-CApp. The same argument, with the ∀ head form, gives 𝑣=Λ𝑐.𝑏 and an E-CAppCAbs step. ◻
★★☆ Show that theorem 132.19 fails if the hypothesis “Γ contains no coercion assumption” is deleted, by giving a well-typed term in a context with one coercion assumption that is neither a value nor reducible. Then say which step of the proof breaks and which theorem it appealed to.
★★☆ Suppose E-CPiCong added the bound 𝑐 to Δ. Using example 132.7, exhibit a closed derivation of ∅;∅⊨𝖨𝗇𝗍≡𝖡𝗈𝗈𝗅:⋆ in the resulting system. Identify the first line of the proof of theorem 132.15 that becomes false, and the case of theorem 132.19 that then fails.
𝑎,𝑏,𝐴,𝐵::=⋆∣𝑥∣𝐹∣𝜆𝜌𝑥:𝐴.𝑏∣𝑎𝑏𝜌∣Π𝜌𝑥:𝐴→𝐵∣Λ𝑐:𝜙.𝑎∣𝑎[𝛾]∣∀𝑐:𝜙.𝐴∣𝑎▸𝛾,𝛾::=𝑐∣𝗋𝖾𝖿𝗅𝑎∣𝗌𝗒𝗆𝛾∣𝛾1;𝛾2∣𝗋𝖾𝖽𝑎𝑏∣Π𝜌𝑥:𝛾1.𝛾2∣⋯ Neither ◻ nor ∙ occurs: an irrelevant application carries its actual argument, and a coercion application carries an explicit proof.
Three changes carry the whole difference. An-Abs checks relevance against the erasure of the body, because the annotation 𝐴 may legitimately mention 𝑥; An-App needs no separate irrelevant rule, because the argument is present in both cases; and An-Conv replaces the undecidable equality premise by a proof 𝛾 that the checker only has to verify.
The congruence rules carry one extra piece of bookkeeping. For instance An-PiCong compares the codomains under a variable of the left domain and repairs the right-hand side by substitution:
The D proposition 𝑎∼𝐴𝑏 is homogeneous by E-Wff: the two terms have one type. The DC coercion judgment Γ;Δ⊢𝛾:𝑎∼𝑏 does not record a type, and its regularity statement is weaker.
This is Lemma 5.6 of Weirich, Voizard, Azevedo de Amorim, and Eisenberg (2017). Three weaker alternatives were available — requiring 𝐴=𝐵, requiring 𝐴 and 𝐵 to be 𝛼-equivalent, or requiring nothing — and the reason for this one is compositionality: with 𝐴=𝐵, the congruence rule for application would have to insert a coercion around one side to make the two dependent result types agree, and would no longer be symmetric in its two premises.
Proof of Lemma 132.25 — Decidability and uniqueness
Proof. Uniqueness is by induction on 𝑎: every rule of definition 132.21 is determined by the outermost form of its subject, and each reads its result type off the subject’s annotations — An-Abs from 𝐴 and the body’s unique type, An-App by substituting the actual argument, An-Conv from the coercion’s right-hand side, An-CApp by substituting the supplied proof. Since there is no rule whose subject is arbitrary, no conversion rule applies silently. Decidability follows: the syntax-directed reading of the rules is a terminating recursion on 𝑎, whose only non-structural obligation is checking a coercion, and definition 132.22 is likewise syntax directed on 𝛾, with An-Beta requiring only one primitive reduction step of an erased term and a syntactic comparison. ◻
The clause |𝑎𝑏−|=|𝑎|◻− is the one that answers the opening obstruction: the argument disappears, the application site does not. The clause |𝑎▸𝛾|=|𝑎| deletes every equality proof, exactly as in chapter 131.
Proof of the first half. Induction on the DC typing derivation, rule by rule. An-Star, An-Var, An-Fam, An-Pi and An-CPi erase to the identically named D rules. An-Abs erases to E-Abs: its side condition is stated on |𝑎|, which is exactly the side condition of E-Abs at the erased body. An-App at 𝜌=+ erases to E-App; at 𝜌=− it erases to E-IApp, whose premise Γ⊨𝑎:𝐴 is supplied by the induction hypothesis applied to the actual argument that DC carries and D deletes. An-CAbs erases to E-CAbs. An-CApp erases to E-CApp, its coercion premise becoming the equality premise by the erasure of the coercion judgment. An-Conv erases to E-Conv, because the erasure of 𝑎▸𝛾 is |𝑎| and the coercion becomes a definitional equality. The second half is Lemma 5.5 of the frozen source; its proof constructs annotations by recursion on the D derivation and is not reproduced here. ◻
The steps that erase to an equality are exactly those that only move an annotation or a cast; the pattern is the same as theorem 131.35 of chapter 131, and it is what licenses the following reading of the two languages.
Proof of Corollary 132.29 — Annotations do not change behaviour
Proof. Both erase to the same D term, and by lemma 132.28 every DC step of either projects to a step or to nothing in D. Since D reduction is deterministic, the two erased reduction sequences coincide. ◻
That is the practical content of the pair D/DC. In the 𝗓𝗂𝗉 of the opening, a type inferencer may produce the empty-vector branch with the proof 𝑐1 or with the proof 𝑐2; the two annotated programs are different DC terms, they erase to the same D term, and corollary 132.29 says the choice is invisible at run time.
★★☆ Write the two DC versions of the empty-vector branch of 𝗓𝗂𝗉 described above, erase both by definition 132.26, and check that the results are identical. Then exhibit two DC terms with the same erasure but different types, and say why that does not contradict lemma 132.25.
★★☆An-Abs checks 𝑥∉fv(|𝑎|) rather than 𝑥∉fv(𝑎). Give a DC term that is well typed under the printed rule and ill typed under the stricter one, and explain in one sentence which occurrence of 𝑥 the erasure deletes.
The frozen source is Weirich, Voizard, Azevedo de Amorim and Eisenberg (2017), together with its Coq development. Every rule displayed above is theirs, and the theorem statements retain their exact hypotheses: theorem 132.15 holds only for the empty available set; theorem 132.19 holds only for contexts without coercion assumptions and without free term variables; lemma 132.24 relates the types of the two sides only up to a derivable equality. Theorem 132.14 is imported, not reproved.
Four boundaries are worth stating plainly. First, nothing here is a theorem about GHC. D and DC have no primitive datatypes, no pattern matching, no type classes and no roles; the vector examples are encodings, and the compiler’s front end is not modelled. Second, corollary 132.17 is not logical consistency, and example 132.4 shows why: every type is inhabited. Third, the signature Σ0 is treated opaquely, so the results hold for any well-formed signature but say nothing about a particular set of recursive definitions beyond its well-formedness. Fourth, D’s type system is undecidable, so lemma 132.25 is a statement about DC only; the implicit language is a specification and an inspiration for inference, not an algorithm.
The relation to chapter 131 is one of replacement, not extension. FC keeps a syntactic separation of types from terms and erases the former; DC conflates them and erases whatever is marked 𝜌=−. A coercion is explicit in both, and both admit an erasure theorem, but no FC theorem transfers to DC by that resemblance: FC’s consistency is a condition on top-level axioms, whereas D’s is a proved property of definitional equality with an empty available set.
[4]
Suggested first pass.
None of these problems is a prerequisite for a later chapter. Begin with exercise 132.6, then complete exercise 132.9.
★★☆ Encode the two-constructor vector type of the opening as a Scott-encoded D term, give the type of the cons constructor including its equality constraint, and type the empty-vector branch of 𝗓𝗂𝗉, naming the use of E-Assn and the available set at that point.
★★★ The impossible branches of 𝗓𝗂𝗉 are discharged by a contradiction between 𝑛∼0 and 𝑛∼𝖲𝗎𝖼𝖼𝑚. Write the D derivation that takes those two assumptions to an equality of two constructor applications with different heads, and then explain why corollary 132.17 does not apply to it. State precisely what has to be true of the context for the branch to be unreachable.
★★★ Consider three candidate variants of E-CPiCong: the printed rule; the rule that adds 𝑐 to Δ; and the rule that requires 𝜙1=𝜙2 syntactically. For each, say whether theorem 132.15, lemma 132.9 and theorem 132.19 survive, giving either a proof sketch of the surviving case or a counterexample.
★★★Practical project.dc-relevance-erasure Complete project dc-relevance-erasure. Implement, for a finite fragment of D and DC, (i) the DC typing rules An-Star, An-Var, An-Abs, An-App, An-CAbs, An-CApp and An-Conv, (ii) the annotation erasure of definition 132.26, (iii) the D one-step reduction of definition 132.2 including E-AbsTerm, and (iv) the head-form consistency test of definition 132.12. The invariant the implementation must maintain is that a term accepted by the DC checker erases to a term accepted by the D checker at the erased type, so that lemma 132.27 holds on every accepted input. The named cases print
irrelevant-use: rejected
erased-application: ok
two-annotations-one-erasure: ok
reduce-under-irrelevant: value
int-bool: inconsistent
The checker is independent evidence for the finite fragment; it does not prove theorem 132.11, theorem 132.19, does not decide D typing, and does not implement the coercion language of definition 132.22 beyond An-Refl, An-Assn and An-Beta.