Skip to content

Instantly share code, notes, and snippets.

@andrejbauer
Last active February 1, 2026 16:45
Show Gist options
  • Select an option

  • Save andrejbauer/2b79042fe01ac14db420a29d08c44966 to your computer and use it in GitHub Desktop.

Select an option

Save andrejbauer/2b79042fe01ac14db420a29d08c44966 to your computer and use it in GitHub Desktop.
The definition of Ackermann function by double primitive recursion
module Ackermann where
open import Data.Nat
open import Relation.Binary.PropositionalEquality
-- Primitive recursion a la System T, for defining maps ℕ → τ for any type τ.
primrec : : Set} τ (ℕ τ τ) τ
primrec x f zero = x
primrec x f (suc m) = f m (primrec x f m)
-- The standard definition of Ackermann function
A :
A zero = suc
A (suc m) 0 = A m 1
A (suc m) (suc n) = A m (A (suc m) n)
-- The definition of Ackermann function by double primitive recursion.
-- Note that the outer recursion maps to τ = ℕ → ℕ, which is not possible
-- in the usual primitive recursion.
B :
B = primrec {τ = ℕ} suc (λ m a primrec {τ = ℕ} (a 1) (λ n b a b))
-- A and B coincide
A≡B : m n A m n ≡ B m n
A≡B zero n = refl
A≡B (suc m) zero = A≡B m 1
A≡B (suc m) (suc n) = trans (cong (A m) (A≡B (suc m) n)) (trans (A≡B m (B (suc m) n)) refl)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment