1
------------------------------------------------------------------------
2
-- Lexicographic induction
3
------------------------------------------------------------------------
5
{-# OPTIONS --universe-polymorphism #-}
7
module Induction.Lexicographic where
10
open import Data.Product
12
-- The structure of lexicographic induction.
14
_⊗_ : ∀ {ℓ} {A B : Set ℓ} →
15
RecStruct A → RecStruct B → RecStruct (A × B)
16
_⊗_ RecA RecB P (x , y) =
17
-- Either x is constant and y is "smaller", ...
18
RecB (λ y' → P (x , y')) y
20
-- ...or x is "smaller" and y is arbitrary.
21
RecA (λ x' → ∀ y' → P (x' , y')) x
23
-- Constructs a recursor builder for lexicographic induction.
25
[_⊗_] : ∀ {ℓ} {A B : Set ℓ}
26
{RecA : RecStruct A} → RecursorBuilder RecA →
27
{RecB : RecStruct B} → RecursorBuilder RecB →
28
RecursorBuilder (RecA ⊗ RecB)
29
[_⊗_] {RecA = RecA} recA {RecB = RecB} recB P f (x , y) =
33
RecA (λ x' → ∀ y' → P (x' , y')) x →
34
RecB (λ y' → P (x , y')) y
35
p₁ x y x-rec = recB (λ y' → P (x , y'))
36
(λ y y-rec → f (x , y) (y-rec , x-rec))
39
p₂ : ∀ x → RecA (λ x' → ∀ y' → P (x' , y')) x
40
p₂ = recA (λ x → ∀ y → P (x , y))
41
(λ x x-rec y → f (x , y) (p₁ x y x-rec , x-rec))
45
------------------------------------------------------------------------
51
open import Induction.Nat as N
53
-- The Ackermann function à la Rózsa Péter.
56
ackermann m n = build [ N.rec-builder ⊗ N.rec-builder ]
62
ack : ∀ p → (N.Rec ⊗ N.Rec) AckPred p → AckPred p
63
ack (zero , n) _ = 1 + n
64
ack (suc m , zero) (_ , ackm•) = ackm• 1
65
ack (suc m , suc n) (ack[1+m]n , ackm•) = ackm• ack[1+m]n