{-# OPTIONS --allow-unsolved-metas #-}
module Verona2024.DoubleNegation.Pigeonhole where
open import Data.Nat
open import Data.Nat.Properties
open import Data.Bool using (Bool; false; true)
open import Data.Sum
open import Data.Product
open import Relation.Binary.PropositionalEquality
module Classical where
data ⊥ : Set where
⊥-elim : {X : Set} → ⊥ → X
⊥-elim ()
¬_ : Set → Set
¬ X = X → ⊥
not-true-is-false : {x : Bool} → ¬ (true ≡ x) → false ≡ x
not-true-is-false {false} p = refl
not-true-is-false {true} p = ⊥-elim (p refl)
Boundedly : {X : Set} → (ℕ → X) → (X → Set) → Set
Boundedly α P = Σ[ a ∈ ℕ ] ((b : ℕ) → b ≥ a → ¬ P (α b))
Infinitely : {X : Set} → (ℕ → X) → (X → Set) → Set
Infinitely α P = (a : ℕ) → Σ[ b ∈ ℕ ] b ≥ a × P (α b)
postulate
oracle : {A : Set} → A ⊎ (¬ A)
lemma : {X : Set} → {α : ℕ → X} {P : X → Set} → ¬ Boundedly α P → Infinitely α P
lemma {P = P} p a with oracle
... | inj₁ q = q
... | inj₂ q = ⊥-elim (p (a , λ b b≥a Pb → q (b , b≥a , Pb)))
module _ (α : ℕ → Bool) where
theorem : Infinitely α (false ≡_) ⊎ Infinitely α (true ≡_)
theorem with oracle {Boundedly α (true ≡_)}
... | inj₁ (a , p) = inj₁ λ i → i ⊔ a , m≤m⊔n i a , not-true-is-false (p (i ⊔ a) (m≤n⊔m i a))
... | inj₂ p = inj₂ (lemma {P = (true ≡_)} p)
go : {x : Bool} → Infinitely α (x ≡_) → ∃[ i ] ∃[ j ] i < j × α i ≡ α j
go p =
let
(i , 0≤i , i-good) = p 0
(j , i<j , j-good) = p (suc i)
in i , j , i<j , trans (sym i-good) j-good
corollary : ∃[ i ] ∃[ j ] i < j × α i ≡ α j
corollary with theorem
... | inj₁ p = go p
... | inj₂ p = go p
module ConstructiveButUninformative (⊥ : Set) where
¬_ : Set → Set
¬ X = X → ⊥
⊥-elim : {X : Set} → ⊥ → ¬ ¬ X
⊥-elim a = λ _ → a
return : {X : Set} → X → ¬ ¬ X
return x = λ k → k x
_⟫=_ : {X Y : Set} → ¬ ¬ X → (X → ¬ ¬ Y) → ¬ ¬ Y
m ⟫= f = λ k → m (λ x → f x k)
escape : ¬ ¬ ⊥ → ⊥
escape m = m (λ a → a)
not-true-is-false : {x : Bool} → ¬ (true ≡ x) → ¬ ¬ (false ≡ x)
not-true-is-false {false} p = return refl
not-true-is-false {true} p = ⊥-elim (p refl)
Boundedly : {X : Set} → (ℕ → X) → (X → Set) → Set
Boundedly f P = Σ[ a ∈ ℕ ] ((b : ℕ) → b ≥ a → ¬ P (f b))
Infinitely : {X : Set} → (ℕ → X) → (X → Set) → Set
Infinitely f P = (a : ℕ) → ¬ ¬ (Σ[ b ∈ ℕ ] b ≥ a × P (f b))
oracle : {A : Set} → ¬ ¬ (A ⊎ (¬ A))
oracle = λ k → k (inj₂ (λ x → k (inj₁ x)))
lemma : {X : Set} → {α : ℕ → X} {P : X → Set} → ¬ Boundedly α P → Infinitely α P
lemma {α = α} {P = P} p a = oracle ⟫= go
where
go : (∃[ b ] b ≥ a × P (α b)) ⊎ ((∃[ b ] b ≥ a × P (α b)) → ⊥) → ¬ ¬ (∃[ b ] b ≥ a × P (α b))
go (inj₁ q) = return q
go (inj₂ q) = ⊥-elim (p (a , λ b b≥a Pb → q (b , b≥a , Pb)))
module _ (α : ℕ → Bool) where
theorem : ¬ ¬ (Infinitely α (false ≡_) ⊎ Infinitely α (true ≡_))
theorem = oracle ⟫= go
where
go : Boundedly α (true ≡_) ⊎ ¬ Boundedly α (true ≡_) → ¬ ¬ (Infinitely α (false ≡_) ⊎ Infinitely α (true ≡_))
go (inj₁ (a , p)) = return (inj₁ λ i → not-true-is-false (p (i ⊔ a) (m≤n⊔m i a)) ⟫= λ q → return (i ⊔ a , m≤m⊔n i a , q))
go (inj₂ p) = return (inj₂ (lemma {P = (true ≡_)} p))
go : {x : Bool} → Infinitely α (x ≡_) → ¬ ¬ (∃[ i ] ∃[ j ] i < j × α i ≡ α j)
go p =
p 0 ⟫= λ (i , 0≤i , i-good) →
p (suc i) ⟫= λ (j , i<j , j-good) →
return (i , j , i<j , trans (sym i-good) j-good)
corollary : ¬ ¬ (∃[ i ] ∃[ j ] i < j × α i ≡ α j)
corollary = theorem ⟫= λ { (inj₁ p) → go p; (inj₂ p) → go p }
module Constructive where
module _ (α : ℕ → Bool) where
Claim : Set
Claim = ∃[ i ] ∃[ j ] i < j × α i ≡ α j
open ConstructiveButUninformative (Claim)
result : Claim
result = escape (corollary α)