quox/lib/Quox/No.idr
2023-08-21 18:43:53 +02:00

69 lines
1.6 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 %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
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
private
0 notFalseTrue : (a : Bool) -> not a = True -> a = False
notFalseTrue False Refl = Refl
export %inline
soNot : So (not a) -> No a
soNot x with 0 (not a) proof eq
soNot Oh | True =
rewrite notFalseTrue a eq in Ah
export %inline
soNot' : So a -> No (not a)
soNot' Oh = Ah