{-# OPTIONS --universe-polymorphism #-}
module Relation.Nullary.Negation where
open import Relation.Nullary
open import Relation.Unary
open import Data.Bool
open import Data.Empty
open import Function
open import Data.Product as Prod
open import Data.Fin
open import Data.Fin.Dec
open import Data.Sum as Sum
open import Category.Monad
open import Level
contradiction : ∀ {p w} {P : Set p} {Whatever : Set w} →
P → ¬ P → Whatever
contradiction p ¬p = ⊥-elim (¬p p)
contraposition : ∀ {p q} {P : Set p} {Q : Set q} →
(P → Q) → ¬ Q → ¬ P
contraposition f ¬q p = contradiction (f p) ¬q
private
note : ∀ {p q} {P : Set p} {Q : Set q} →
(P → ¬ Q) → Q → ¬ P
note = flip
∃⟶¬∀¬ : ∀ {a p} {A : Set a} {P : A → Set p} →
∃ P → ¬ (∀ x → ¬ P x)
∃⟶¬∀¬ = flip uncurry
∀⟶¬∃¬ : ∀ {a p} {A : Set a} {P : A → Set p} →
(∀ x → P x) → ¬ ∃ λ x → ¬ P x
∀⟶¬∃¬ ∀xPx (x , ¬Px) = ¬Px (∀xPx x)
¬∃⟶∀¬ : ∀ {a p} {A : Set a} {P : A → Set p} →
¬ ∃ (λ x → P x) → ∀ x → ¬ P x
¬∃⟶∀¬ = curry
∀¬⟶¬∃ : ∀ {a p} {A : Set a} {P : A → Set p} →
(∀ x → ¬ P x) → ¬ ∃ (λ x → P x)
∀¬⟶¬∃ = uncurry
∃¬⟶¬∀ : ∀ {a p} {A : Set a} {P : A → Set p} →
∃ (λ x → ¬ P x) → ¬ (∀ x → P x)
∃¬⟶¬∀ = flip ∀⟶¬∃¬
¬∀⟶∃¬ : ∀ n {p} (P : Fin n → Set p) → (∀ i → Dec (P i)) →
¬ (∀ i → P i) → ∃ λ i → ¬ P i
¬∀⟶∃¬ n P dec ¬P = Prod.map id proj₁ $ ¬∀⟶∃¬-smallest n P dec ¬P
¬¬-map : ∀ {p q} {P : Set p} {Q : Set q} →
(P → Q) → ¬ ¬ P → ¬ ¬ Q
¬¬-map f = contraposition (contraposition f)
Stable : ∀ {ℓ} → Set ℓ → Set ℓ
Stable P = ¬ ¬ P → P
stable : ∀ {p} {P : Set p} → ¬ ¬ Stable P
stable ¬[¬¬p→p] = ¬[¬¬p→p] (λ ¬¬p → ⊥-elim (¬¬p (¬[¬¬p→p] ∘ const)))
negated-stable : ∀ {p} {P : Set p} → Stable (¬ P)
negated-stable ¬¬¬P P = ¬¬¬P (λ ¬P → ¬P P)
decidable-stable : ∀ {p} {P : Set p} → Dec P → Stable P
decidable-stable (yes p) ¬¬p = p
decidable-stable (no ¬p) ¬¬p = ⊥-elim (¬¬p ¬p)
¬-drop-Dec : ∀ {p} {P : Set p} → Dec (¬ ¬ P) → Dec (¬ P)
¬-drop-Dec (yes ¬¬p) = no ¬¬p
¬-drop-Dec (no ¬¬¬p) = yes (negated-stable ¬¬¬p)
¬¬-Monad : RawMonad (λ P → ¬ ¬ P)
¬¬-Monad = record
{ return = contradiction
; _>>=_ = λ x f → negated-stable (¬¬-map f x)
}
¬¬-push : ∀ {p q} {P : Set p} {Q : P → Set q} →
¬ ¬ ((x : P) → Q x) → (x : P) → ¬ ¬ Q x
¬¬-push ¬¬P⟶Q P ¬Q = ¬¬P⟶Q (λ P⟶Q → ¬Q (P⟶Q P))
excluded-middle : ∀ {p} {P : Set p} → ¬ ¬ Dec P
excluded-middle ¬h = ¬h (no (λ p → ¬h (yes p)))
call/cc : ∀ {w p} {Whatever : Set w} {P : Set p} →
((P → Whatever) → ¬ ¬ P) → ¬ ¬ P
call/cc hyp ¬p = hyp (λ p → ⊥-elim (¬p p)) ¬p
independence-of-premise
: ∀ {p q r} {P : Set p} {Q : Set q} {R : Q → Set r} →
Q → (P → Σ Q R) → ¬ ¬ Σ Q (λ x → P → R x)
independence-of-premise {P = P} q f = ¬¬-map helper excluded-middle
where
helper : Dec P → _
helper (yes p) = Prod.map id const (f p)
helper (no ¬p) = (q , ⊥-elim ∘′ ¬p)
independence-of-premise-⊎
: ∀ {p q r} {P : Set p} {Q : Set q} {R : Set r} →
(P → Q ⊎ R) → ¬ ¬ ((P → Q) ⊎ (P → R))
independence-of-premise-⊎ {P = P} f = ¬¬-map helper excluded-middle
where
helper : Dec P → _
helper (yes p) = Sum.map const const (f p)
helper (no ¬p) = inj₁ (⊥-elim ∘′ ¬p)
private
corollary : ∀ {p ℓ} {P : Set p} {Q R : Set ℓ} →
(P → Q ⊎ R) → ¬ ¬ ((P → Q) ⊎ (P → R))
corollary {P = P} {Q} {R} f =
¬¬-map helper (independence-of-premise
true ([ _,_ true , _,_ false ] ∘′ f))
where
helper : ∃ (λ b → P → if b then Q else R) → (P → Q) ⊎ (P → R)
helper (true , f) = inj₁ f
helper (false , f) = inj₂ f
Excluded-Middle : (ℓ : Level) → Set (suc ℓ)
Excluded-Middle p = {P : Set p} → Dec P
Double-Negation-Elimination : (ℓ : Level) → Set (suc ℓ)
Double-Negation-Elimination p = {P : Set p} → Stable P
private
em⇒dne : ∀ {ℓ} → Excluded-Middle ℓ → Double-Negation-Elimination ℓ
em⇒dne em = decidable-stable em
dne⇒em : ∀ {ℓ} → Double-Negation-Elimination ℓ → Excluded-Middle ℓ
dne⇒em dne = dne excluded-middle