{-# OPTIONS --cubical-compatible --safe #-}
module Relation.Nullary.Decidable.Core where
open import Level using (Level; Lift)
open import Data.Bool.Base using (Bool; T; false; true; not; _∧_; _∨_)
open import Data.Unit.Base using (⊤)
open import Data.Empty using (⊥)
open import Data.Empty.Irrelevant using (⊥-elim)
open import Data.Product.Base using (_×_)
open import Data.Sum.Base using (_⊎_)
open import Function.Base using (_∘_; const; _$_; flip)
open import Relation.Nullary.Reflects
open import Relation.Nullary.Negation.Core
private
variable
a b : Level
A B : Set a
infix 2 _because_
record Dec (A : Set a) : Set a where
constructor _because_
field
does : Bool
proof : Reflects A does
open Dec public
pattern yes a = true because ofʸ a
pattern no ¬a = false because ofⁿ ¬a
module _ {A : Set a} where
From-yes : Dec A → Set a
From-yes (true because _) = A
From-yes (false because _) = Lift a ⊤
From-no : Dec A → Set a
From-no (false because _) = ¬ A
From-no (true because _) = Lift a ⊤
recompute : Dec A → .A → A
recompute (yes a) _ = a
recompute (no ¬a) a = ⊥-elim (¬a a)
infixr 1 _⊎-dec_
infixr 2 _×-dec_ _→-dec_
T? : ∀ x → Dec (T x)
T? x = x because T-reflects x
¬? : Dec A → Dec (¬ A)
does (¬? a?) = not (does a?)
proof (¬? a?) = ¬-reflects (proof a?)
_×-dec_ : Dec A → Dec B → Dec (A × B)
does (a? ×-dec b?) = does a? ∧ does b?
proof (a? ×-dec b?) = proof a? ×-reflects proof b?
_⊎-dec_ : Dec A → Dec B → Dec (A ⊎ B)
does (a? ⊎-dec b?) = does a? ∨ does b?
proof (a? ⊎-dec b?) = proof a? ⊎-reflects proof b?
_→-dec_ : Dec A → Dec B → Dec (A → B)
does (a? →-dec b?) = not (does a?) ∨ does b?
proof (a? →-dec b?) = proof a? →-reflects proof b?
isYes : Dec A → Bool
isYes (true because _) = true
isYes (false because _) = false
isNo : Dec A → Bool
isNo = not ∘ isYes
True : Dec A → Set
True = T ∘ isYes
False : Dec A → Set
False = T ∘ isNo
⌊_⌋ = isYes
toWitness : {a? : Dec A} → True a? → A
toWitness {a? = true because [a]} _ = invert [a]
toWitness {a? = false because _ } ()
fromWitness : {a? : Dec A} → A → True a?
fromWitness {a? = true because _ } = const _
fromWitness {a? = false because [¬a]} = invert [¬a]
toWitnessFalse : {a? : Dec A} → False a? → ¬ A
toWitnessFalse {a? = true because _ } ()
toWitnessFalse {a? = false because [¬a]} _ = invert [¬a]
fromWitnessFalse : {a? : Dec A} → ¬ A → False a?
fromWitnessFalse {a? = true because [a]} = flip _$_ (invert [a])
fromWitnessFalse {a? = false because _ } = const _
from-yes : (a? : Dec A) → From-yes a?
from-yes (true because [a]) = invert [a]
from-yes (false because _ ) = _
from-no : (a? : Dec A) → From-no a?
from-no (false because [¬a]) = invert [¬a]
from-no (true because _ ) = _
map′ : (A → B) → (B → A) → Dec A → Dec B
does (map′ A→B B→A a?) = does a?
proof (map′ A→B B→A (true because [a])) = ofʸ (A→B (invert [a]))
proof (map′ A→B B→A (false because [¬a])) = ofⁿ (invert [¬a] ∘ B→A)
decidable-stable : Dec A → Stable A
decidable-stable (yes a) ¬¬a = a
decidable-stable (no ¬a) ¬¬a = ⊥-elim (¬¬a ¬a)
¬-drop-Dec : Dec (¬ ¬ A) → Dec (¬ A)
¬-drop-Dec ¬¬a? = map′ negated-stable contradiction (¬? ¬¬a?)
¬¬-excluded-middle : DoubleNegation (Dec A)
¬¬-excluded-middle ¬?a = ¬?a (no (λ a → ¬?a (yes a)))
excluded-middle = ¬¬-excluded-middle
{-# WARNING_ON_USAGE excluded-middle
"Warning: excluded-middle was deprecated in v2.0.
Please use ¬¬-excluded-middle instead."
#-}