module Dickson where
{-
Extracting constructive content from classical proofs
https://agdapad.quasicoherent.io/~cirm2025/Dickson.agda
Plan:
0. Entertaining a ludicrous classical proof in English
1. Formalizing the classical proof
2. Turning the classical proof into a constructive but
uninformative proof
3. Fully constructivizing the proof
Theorem (mini version of Dickson's lemma):
For every function f : ℕ → ℕ, there is a number n : ℕ
such that f(n) ≤ f(n+1).
Proof (classical). By the law of excluded middle,
there is a minimum value f(n). Hence, in particular,
we will have f(n) ≤ f(n+1).
Beautiful constructive proofs can be found in
Iosif Petrakis: Constructive Combinatorics of Dickson's Lemma.
But can we interpret the given classical proof as a blueprint for a
constructive proof?
-}
open import Data.Nat
open import Data.Sum
open import Data.Product
module Classical where
open import Data.Empty
open import Relation.Nullary
postulate
-- Logical reading: For any A, either A or not A.
-- Computational reading: "oracle" is a function
-- which reads a set A as input and outputs
-- either an element of A or a witness that A is empty.
oracle : (A : Set) → A ⊎ (A → ⊥)
-- ∀(f : ℕ → ℕ). ∃n:ℕ. ∀(m : ℕ). f(n) ≤ f(m)
{-# TERMINATING #-}
minimum : (f : ℕ → ℕ) → ∃[ n ] ((m : ℕ) → f n ≤ f m)
minimum f = go 0
where
go : ℕ → ∃[ n ] ((m : ℕ) → f n ≤ f m)
go i with oracle (∃[ j ] f j < f i)
... | inj₁ (j , fj<fi) = go j
... | inj₂ p = (i , h)
where
h : (m : ℕ) → f i ≤ f m
h m with ≤-<-connex (f i) (f m)
... | inj₁ fi≤fm = fi≤fm
... | inj₂ fi>fm = ⊥-elim (p (m , fi>fm))
-- ∀(f : ℕ → ℕ). ∃n:ℕ. f(n) ≤ f(n+1)
theorem : (f : ℕ → ℕ) → ∃[ n ] f n ≤ f (n + 1)
theorem f with minimum f
... | (n , p) = (n , p (n + 1))
-- Here, p is a witness that f n is the minimum of f:
-- Logical reading: p is a witness of ∀(m : ℕ). f(n) ≤ f(m).
-- Computational reading: p is a function which reads as input
-- a number m : ℕ and which outputs a witness that f(n) ≤ f(m).
example : ℕ → ℕ
example 0 = 17
example 1 = 15
example 2 = 14
example _ = 47
module ConstructiveButUninformative (⊥ : Set) where
¬_ : Set → Set
¬ X = (X → ⊥)
escape : ¬ ¬ ⊥ → ⊥
escape x = x (λ z → z)
⊥-elim : {A : Set} → ⊥ → ¬ ¬ A
⊥-elim x = λ z → x
oracle : (A : Set) → ¬ ¬ (A ⊎ (A → ⊥))
oracle A = λ z → z (inj₂ (λ z₁ → z (inj₁ z₁)))
return : {A : Set} → A → ¬ ¬ A
return x = λ z → z x
-- If ¬¬A, and if A → B, then also ¬¬B.
-- If ¬¬A, and if A → ¬¬B, then also ¬¬B.
_>>=_ : {A B : Set} → ¬ ¬ A → (A → ¬ ¬ B) → ¬ ¬ B
m >>= f = λ z → m (λ z₁ → f z₁ z)
{-# TERMINATING #-}
minimum : (f : ℕ → ℕ) → ¬ ¬ (∃[ n ] ((m : ℕ) → ¬ ¬ (f n ≤ f m)))
minimum f = go 0
where
go : ℕ → ¬ ¬ (∃[ n ] ((m : ℕ) → ¬ ¬ (f n ≤ f m)))
go i = oracle (∃[ j ] f j < f i) >>= g
where
g : _ → _
g (inj₁ (j , fj<fi)) = go j
g (inj₂ p) = return (i , h)
where
h : (m : ℕ) → ¬ ¬ (f i ≤ f m)
h m with ≤-<-connex (f i) (f m)
... | inj₁ fi≤fm = return fi≤fm
... | inj₂ fi>fm = ⊥-elim (p (m , fi>fm))
theorem : (f : ℕ → ℕ) → ¬ ¬ (∃[ n ] f n ≤ f (n + 1))
theorem f = do
(n , p) ← minimum f
fn≤fn+1 ← p (n + 1)
return (n , fn≤fn+1)
module Constructive (f : ℕ → ℕ) where
Claim : Set
Claim = ∃[ n ] f n ≤ f (n + 1)
thm : Claim
thm = escape (theorem f)
where
open ConstructiveButUninformative Claim
-- "Now use all the results of the previous section,
-- but with Claim in place of ⊥."
-- Barr's theorem:
-- Friedman's trick works for Π² statements, so statements
-- of the form ∀x ∃y ...
-- ZFC is conservative over IZF for arithmetical Π² statements.
-- By applying the L-translation, ZFC is conservative over ZF
-- for arithmetical statements.
-- By applying the ¬¬-translation followed by Friedman's trick,
-- ZF is conservative over IZF for Π² statements.
-- nontrivial exit continuation trick