{-# OPTIONS --safe #-}
module Cubical.Relation.Nullary.DecidablePropositions where

open import Cubical.Foundations.Prelude
open import Cubical.Foundations.HLevels
open import Cubical.Foundations.Equiv renaming (_∙ₑ_ to _⋆_)

open import Cubical.Data.Bool
open import Cubical.Data.Sigma

open import Cubical.Relation.Nullary.Base
open import Cubical.Relation.Nullary.Properties

private
  variable
     ℓ'  : Level

DecProp : ( : Level)  Type (ℓ-suc )
DecProp  = Σ[ P  hProp  ] Dec (P .fst)

isSetDecProp : isSet (DecProp )
isSetDecProp = isOfHLevelΣ 2 isSetHProp  P  isProp→isSet (isPropDec (P .snd)))

-- the following is an alternative formulation of decidable propositions
-- it separates the boolean value from more proof-relevant part
-- so it performs better when doing computation

isDecProp : Type   Type 
isDecProp P = Σ[ t  Bool ] P  Bool→Type t

DecProp' : ( : Level)  Type (ℓ-suc )
DecProp'  = Σ[ P  Type  ] isDecProp P

-- properties of the alternative formulation

isDecProp→isProp : {P : Type }  isDecProp P  isProp P
isDecProp→isProp h = isOfHLevelRespectEquiv 1 (invEquiv (h .snd)) isPropBool→Type

isDecProp→Dec : {P : Type }  isDecProp P  Dec P
isDecProp→Dec h = EquivPresDec (invEquiv (h .snd)) DecBool→Type

isPropIsDecProp : {P : Type }  isProp (isDecProp P)
isPropIsDecProp p q =
  Σ≡PropEquiv  _  isOfHLevel⁺≃ᵣ 0 isPropBool→Type) .fst
    (Bool→TypeInj _ _ (invEquiv (p .snd)  q .snd))

isDecPropRespectEquiv : {P : Type } {Q : Type ℓ'}
   P  Q  isDecProp Q  isDecProp P
isDecPropRespectEquiv e (t , e') = t , e  e'