quox/lib/Quox/No.idr

63 lines
1.5 KiB
Idris

||| like Data.So, but for False instead.
||| less messing about with `not` (and constantly rewriting everything)
||| or `Not` (unfriendly to proof search).
module Quox.No
import public Data.So
import public Quox.Decidable
import Data.Bool
public export
data No : Pred Bool where
Ah : No False
export Uninhabited (No True) where uninhabited _ impossible
export Eq (No p) where _ == _ = True
export Ord (No p) where compare _ _ = EQ
export Show (No p) where showPrec _ _ = "Ah"
export %inline
soNo : So b -> No b -> Void
soNo Oh Ah impossible
private
0 orFalse : (a, b : Bool) -> (a || b) = False -> (a = False, b = False)
orFalse a b eq1 with (a || b) proof eq2
orFalse False False Refl | False = (Refl, Refl)
orFalse False True Refl | False = absurd eq2
orFalse True False Refl | False = absurd eq2
orFalse True True Refl | False = absurd eq2
parameters {0 a, b : Bool}
export %inline
noOr : No (a || b) -> (No a, No b)
noOr n with 0 (a || b) proof eq
noOr Ah | False =
let 0 eqs = orFalse a b eq in
(rewrite fst eqs in Ah, rewrite snd eqs in Ah)
export %inline
noOr1 : No (a || b) -> No a
noOr1 = fst . noOr
export %inline
noOr2 : No (a || b) -> No b
noOr2 = snd . noOr
export infixr 1 `orNo`
export %inline
orNo : No a -> No b -> No (a || b)
orNo Ah Ah = Ah
export %inline
nchoose : (b : Bool) -> Either (So b) (No b)
nchoose True = Left Oh
nchoose False = Right Ah
export
0 notYesNo : {f : Dec p} -> Not p -> No (isYes f)
notYesNo {f = Yes y} g = absurd $ g y
notYesNo {f = No n} g = Ah