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