[{"data":1,"prerenderedAt":4},["ShallowReactive",2],{"ChRHD8DU8j":3},"# DCC - The Dependent Combinator Calculus\n\n## Overview\n\nThe DCC is a dependently-typed calculus based on [SK combinators](https://en.wikipedia.org/wiki/SKI_combinator_calculus). My goal is to formalize a proof of strong normalization of the dependently-typed calculus.\n\n## Background / Definitions\n\n### SK Combinators\n\nThe [SK combinator calculus](https://en.wikipedia.org/wiki/SKI_combinator_calculus) is a turing complete model of computation equivalent to the lambda calculus. It has two equational / algebraic rewrite rules:\n\n```\nS x y z = (x z) (y z)\n```\n\n```\nK x y = x\n```\n\n`S` is the driver of computation, since it duplicates the variable `z`, allowing infinite recursion.\nHerein, we specifically refer to the *dependently typed* variant of SK. As such, we attach \"type arguments:\"\n\n```\nS α β γ x y z = (x z) (y z)\n```\n\n```\nK α β x y = x\n```\n\nRewrite rules are left unchaged. α and β are strictly information for the kernel.\n\n### Dependent Types\n\nHerein, when we refer to dependent types, we are specifically referring to [*pure* lambda calculi](https://en.wikipedia.org/wiki/Pure_type_system). We have an infinite hierarchy of sorts, and Π binders are the only mechanism of forming types (→ is created with Π and the `K` combinator).\n\nInductive types are out of the scope of this project. As such, an explicit notion of propositional equality is out of scope. Our ideal calculus is essentially the raw [Calculus of Constructions](https://en.wikipedia.org/wiki/Calculus_of_constructions), but without contexts or variables.\n\n#### Type of S\n\nWe are using the standard definition of the `S` combinator's dependent type:\n\n```lean\nS : ∀ (α : Type) (β : α → Type) (γ : ∀ (x : α), β x → Type) (x : ∀ (x : α) (y : β x), γ x y) (y : ∀ (x : α), β x) (z : α), γ z (y z)\n```\n\n#### Type of K and K'\n\nWe also use the standard type of the `K` combinator, and have a special case of `K` called `K'` to close the \"loop\" of type dependency:\n\n```lean\nK : ∀ (α : Type) (β : α → Type) (x : α) (y : β x), α\n```\n\n```lean\nK' : ∀ (α : Type) (β : Type) (x : α) (y : β), α\n```\n\n### All Objects in the Calculus\n\n`S`, `K`, and `K'` are our only computationally relevant objects. All other objects are for forming types, though they can appear as terms, but have no rewrite rules accessible to the user:\n\n| Object   | Purpose                                        | Rewrite Rule                    | Type                                                                                                     | Computationally Relevant?                   |\n|----------|------------------------------------------------|---------------------------------|----------------------------------------------------------------------------------------------------------|---------------------------------------------|\n| `S`      | Duplication and composition in computation     | `S x y z = (x z) (y z)`         | See above. Requires explicit type arguments `α`, `β`, `γ`.                                               | Yes                                         |\n| `K`      | Weakening, dependent type                      | `K x y = x`                     | See above. Requires explicit type arguments `α`, `β`.                                                    | Yes                                         |\n| `K'`     | Weakening, nondependent type                   | `K' x y = x`                    | See above. Requires explicit type arguments `α`, `β`.                                                    | Yes                                         |\n| `Sort m` | Prevent self-type paradox                      | n/a                             | `⊢ Sort m : Sort m.succ`, `Prop` is shorthand for `Sort 0`                                               | No, cannot pattern match.                   |\n| `Π`      | Form dependent types.                          | `((Π α, β) x) = Π (α x), (β x)` | `Γ x : α, β x : Sort m ⊢ Π α, β : Sort m`                                                                | No. Only kernel has access to rewrite rule. |\n| `B`      | Type combinator, composition.                  | `B f g x = f (g x)`             | No explicit type arguments. Inferred from `Π`.\u003Cbr>`Γ g : Π α, K* β, f : Π β, γ ⊢ (Π α, B f g) : γ (g x)` | No. Only kernel has access to rewrite rule. |\n| `C`      | Type combinator, flip arguments to a function. | `C f x y = f y x`               | Inferred from `Π`. Omitted for brevity. No explicit type arguments.                                      | No. Only kernel has access to rewrite rule. |\n| `K*`     | Type combinator, discard argument.             | `K* x y = x`                    | Inferred from `Π`. Omitted for brevity. No explicit type arguments.                                      | No. Only kernel has access to rewrite rule. |\n| `I`      | Type combinator, identity.                     | `I x = x`                       | Inferred from `Π`. Omitted for brevity. No explicit type arguments.                                      | No. Only kernel has access to rewrite rule. |\n\n#### Decreasing Measure: Why BCKI Combinators?\n\nBCKI combinators are the preferred mechanism for forming types inside `Π` binders. This is because none of the arguments of the types of `K`, `K'`, or `S` duplicate any argument in context:\n\n```lean\nK : ∀ (α : Type) (β : α → Type) (x : α) (y : β x), α\nK' : ∀ (α : Type) (β : Type) (x : α) (y : β), α\nS : ∀ (α : Type) (β : α → Type) (γ : ∀ (x : α), β x → Type) (x : ∀ (x : α) (y : β x), γ x y) (y : ∀ (x : α), β x) (z : α), γ z (y z)\n```\n\nEach argument uses each element in the context at most once. By argument, I refer to each nested `(_ : _)` under a `Π` binder. The only duplication under a `Π` binder has the codomain of `S`.\nThis enables strong normalization of type formation in SK, since each argument type merely rearranges or discards elements in context, but never duplicates them. As such, **whenever an argument is applied to a function, the number of \"type combinators\" in its type strictly decreases**.\n\n# Main Theorems\n\n*Note: See [eval.lean](https://github.com/lexzaiello/DCC/blob/868e86ccb34a3cabcb71cdfaa05d48bb16d43397/Dcc/Eval.lean) for the full list of my results as of March 19, 2026.*\n\nOur main goal is to prove strong normalization of well-typed dependent SK programs. We intend to do so by using our *decreasing measure* for types as a proxy. If a program is well-typed, then its type will strictly decrease upon applying an argument.\n\n## BCKI Evaluation Rules\n\nHere are the rewrite rules for our type combinators. Note that no duplication is possible, and we use call-by-name reduction to allow deterministic reduction:\n\n```lean\ninductive Expr.RedTy : Expr → Expr → Prop\n  | next      : RedTy (SK (K* A b)) A\n  | comp      : RedTy (SK (B f g x)) (SK (f (g x)))\n  | flip      : RedTy (SK (C x y z)) (SK (x z y))\n  | read      : RedTy (SK (I x)) x\n  | congrFun  : Expr.RedTy f f'\n    → Expr.RedTy (SK (f x)) (SK (f' x))\n```\n\n## Decreasing Measure in Types:\n\nThis is our definition of the \"size\" of an argument type under a `Π` binder:\n\n```lean\ninductive Expr.TySize : Expr → ℕ → Prop\n  | next : Expr.TySize (SK K*) 1\n  | comp : Expr.TySize (SK B) 1\n  | flip : Expr.TySize (SK C) 1\n  | read : Expr.TySize (SK I) 1\n  | pi   : Expr.TySize (SK Π α, β) 0\n  | comb : Expr.TySize (.comb c) 0\n  | hole : Expr.TySize (SK __ ∶ t) 0\n  | srt  : Expr.TySize (SK Sort m) 0\n  | app  : Expr.TySize f n\n    → Expr.TySize x m\n    → Expr.TySize (SK (f x)) (n + m)\n```\n\n```lean\ndef Expr.ty_size : Expr → ℕ\n  | (SK K*) | (SK B) | (SK C) | (SK I) => 1\n  | (SK Π _α, _β) | .comb _c | SK __ ∶ _t | SK Sort _m => 0\n  | SK (f x) =>\n    let n := f.ty_size\n    let m := x.ty_size\n    (n + m)\n```\n\nWe have proven soundness and completeness of our `ty_size` function with respect to `TySize`.\n\nNote that due to our notion of congruence, the left-most head of an application must always fire for reduction to occur. As a result, the size of the application will strictly decrease.\n\n## Existence of a decreasing size:\n\n```lean\ntheorem Expr.RedTy.decreasing (h_red : Expr.RedTy e e') (h_size : e.TySize n) : ∃ m, e'.TySize m ∧ m \u003C n := by\n  induction h_red generalizing n\n  · cases h_size\n    iterate 2 (rename_i h _; cases h)\n    exact ⟨_, (by assumption), by grind only⟩\n  · cases h_size\n    iterate 3 (rename_i h _; cases h)\n    exact ⟨_, .app (by assumption) (.app (by assumption) (by assumption)), by grind only⟩\n  · cases h_size\n    iterate 3 (rename_i h _; cases h)\n    exact ⟨_, .app (.app (by assumption) (by assumption)) (by assumption), by grind only⟩\n  · cases h_size\n    rename_i h _; cases h\n    exact ⟨_, by assumption, by grind only⟩\n  case congrFun f f' x hrf ih =>\n    cases h_size\n    rename_i n_x _ _\n    have h := ih (by assumption)\n    have ⟨m, hf, h₁⟩ := h\n    exact ⟨m + n_x, .app (by assumption) (by assumption), by grind⟩\n```\n\nTogether with uniqueness of type sizes, this shows that the type size *strictly decreases*:\n\n```lean\ntheorem Expr.TySize.unique (h₁ : Expr.TySize e n) (h₂ : e.TySize m) : m = n := by\n  induction h₁ generalizing m\n  repeat (cases h₂; rfl)\n  case app f n x m _ _ ih₁ ih₂ =>\n    cases h₂\n    rename_i hnf hnx\n    have ha := ih₁ hnf\n    have hb := ih₂ hnx\n    grind only\n```\n\nWe have also shown that the size decreases with respect to the transitive closure of `RedTy` (single-step reduction):\n\n```lean\ntheorem Expr.RedTyTrans.decreasing (h_red : Expr.RedTyTrans a b) (hn : a.TySize n) : ∃ m, b.TySize m ∧ m \u003C n := by\n  induction h_red\n  · rename_i hr\n    exact hr.decreasing hn\n  · rename_i b c htrans hr ih\n    have ⟨m, hbm₁, hbm₂⟩ := ih\n    have ⟨mc, hcm₁, hcm₂⟩ := hr.decreasing hbm₁\n    exact ⟨mc, hcm₁, by grind only⟩\n\ntheorem Expr.RedTy.decreasing' (h_red : Expr.RedTy e e') : e'.ty_size \u003C e.ty_size := by\n  let h_size := e.ty_size\n  have ⟨m, h, hp⟩ := Expr.RedTy.decreasing h_red (Expr.TySize.sound (e := e) (n := h_size) rfl)\n  have h := h.complete\n  exact h.symm ▸ hp\n```\n\n## Strong Normalization Proof (single step and transitive closure)\n\nWe use a fairly standard definition of `SN` with Lean's `Acc` accessibility predicate. We have proven it using our decreasing measure for both the transitive closure and single-step reduction:\n\n```lean\ndef Expr.RedTy.SN (e : Expr) : Acc (fun b a => Expr.RedTy a b) e := Acc.intro e (fun e' hr => by\n  have h := hr.decreasing'\n  exact Expr.RedTy.SN e')\ntermination_by e.ty_size\n\ndef Expr.RedTyTrans.SN (e : Expr) : Acc (fun b a => Expr.RedTyTrans a b) e := Acc.intro e (fun e' hr => by\n  have h := hr.decreasing'\n  exact Expr.RedTyTrans.SN e')\ntermination_by e.ty_size\n```\n\nOur decreasing measure is extremely powerful, and allows us to recurse in proofs where Lean would have easily hung otherwise.\n\n## Other proofs:\n\nHere is a list of other proofs we have omitted for brevity:\n\n* Completeness of the full beta reducer `reduce : Expr → Expr` with respect to normal transitive forms:\n  * `theorem Expr.RedTyTrans.complete' : Expr.RedTyTrans a b → IsNorm b → Expr.reduce a = b := ...`\n    * This essentially proves uniqueness of normal forms due to soundness of the reducer.\n* Completeness of the full beta reducer with respect to definitional equality:\n  * `theorem Expr.RedTyTrans.complete : Expr.RedTyTrans a b → Expr.reduce a = Expr.reduce b := ...`\n  * `theorem Expr.RedTyTrans.reduce_same : Expr.RedTyTrans a b → Expr.RedTyTrans a c → reduce b = reduce c := ...`\n    * **Note that this is essentially Church-Rosser, as we have also shown soundness of the reducer:**\n* Soundness of the full beta reducer:\n  * `theorem reduce_sound : Expr.reduce e = e' → Expr.RedTyReflTrans e e' := ...`\n* More of these proofs, but for single-step reduction and the `step?` function.\n  * Deterministic single-step reduction: `theorem Expr.RedTy.unique : Expr.RedTy a b → Expr.RedTy a c → b = c := ...`\n\n# References:\n\nMuch of this current iteration of the paper is original work, but I have absorbed a great deal of information. Here is my Bibtex file of various sources I consulted:\n\n* Altenkirch, T., Kaposi, A., Šinkarovs, A., & Végh, T. (2023). The Münchhausen Method in Type Theory. In 28th International Conference on Types for Proofs and Programs (TYPES 2022) (pp. 10:1–10:20). Schloss Dagstuhl – Leibniz-Zentrum fur Informatik.\n\n* Mazza, D. (2007). A denotational semantics for the symmetric interaction combinators. Mathematical Structures in Computer Science, 17(3), 527–562.\n\n* Eli Ben-Sasson, Iddo Bentov, Yinon Horesh, & Michael Riabzev. (2018). Scalable, transparent, and post-quantum secure computational integrity. .\n\n* Maribel Fernández, & Ian Mackie (2003). Operational equivalence for interaction nets. Theoretical Computer Science, 297(1), 157–181.\n\n* Lévy, J.J. (1976). An algebraic interpretation of the λβ K-calculus; and an application of a labelled λ-calculus. Theoretical computer science, 2(1), 97-114.\n\n* Yves Lafont (1997). Interaction Combinators. Information and Computation, 137(1), 69-101.\n\n* Micali, S. (2000). Computationally Sound Proofs. SIAM J. Comput., 30(4), 1253–1298.\n\n* Eli Ben-Sasson, Alessandro Chiesa, Eran Tromer, & Madars Virza. (2014). Scalable Zero Knowledge via Cycles of Elliptic Curves. .\n\n* Arora, S., & Safra, S. (1998). Probabilistic checking of proofs: a new characterization of NP. J. ACM, 45(1), 70–122.\n\n* Goldwasser, S., Micali, S., & Rackoff, C. (1985). The knowledge complexity of interactive proof-systems. In Proceedings of the Seventeenth Annual ACM Symposium on Theory of Computing (pp. 291–304). Association for Computing Machinery.\n\n* Lior Goldberg, Shahar Papini, & Michael Riabzev. (2021). Cairo – a Turing-complete STARK-friendly CPU architecture. .\n\n* Lafont, Y. (1989). Interaction nets. In Proceedings of the 17th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (pp. 95–108). Association for Computing Machinery.\n\n* Y. Lafont (1988). The linear abstract machine. Theoretical Computer Science, 59(1), 157-180.\n\n* Cousineau, M. (1985). The categorical abstract machine. In Functional Programming Languages and Computer Architecture (pp. 50–64). Springer Berlin Heidelberg.\n\n* Peyton Jones, S. (1987). The Implementation of Functional Programming Languages (Prentice-Hall International Series in Computer Science). Prentice-Hall, Inc..\n\n* Seely, R. (1984). Locally cartesian closed categories and type theory. Mathematical Proceedings of the Cambridge Philosophical Society, 95(1), 33–48.\n\n* P.-L. Curien (1986). Categorical combinators. Information and Control, 69(1), 188-254.\n\n* Andreas Abel, Klaus Aehlig, & Peter Dybjer (2007). Normalization by Evaluation for Martin-Löf Type Theory with One Universe. Electronic Notes in Theoretical Computer Science, 173, 17-39.\n\n* David Turner (1979). A new implementation technique for applicative languages. Software: Practice and Experience, 9.\n\n# Future Work\n\nMy next primary objective is to formalize a proof of strong normalization of well-typed term-level SK programs using my type-level decreasing measure as a proxy. This is my final objective. Then, I intend to type-set the paper.\n\n## Lean Toolchain\n\nI am using Lean4 with the toolchain `leanprover/lean4:v4.26.0`. Lean support with Nix is not well-maintained, so you will have to install it manually.\n\n## Docs\n\nTo view the documentation, use:\n\n```shell\nnix run .#serve\n```\n\nIf the docs are not up-to-date, please run `lake build`.\n\nBy *Lexi Aiello*.\n",1777138846371]