||| 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 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