module Quox.Decidable import public Data.Bool.Decidable import public Decidable.Decidable import public Decidable.Equality import public Control.Relation public export 0 REL : Type -> Type -> Type REL a b = a -> b -> Type public export 0 Pred : Type -> Type Pred a = a -> Type public export 0 Dec1 : Pred a -> Type Dec1 p = (x : a) -> Dec (p x) public export 0 Dec2 : REL a b -> Type Dec2 p = (x : a) -> (y : b) -> Dec (p x y) public export 0 Reflects1 : Pred a -> (a -> Bool) -> Type p `Reflects1` f = (x : a) -> p x `Reflects` f x public export 0 Reflects2 : REL a b -> (a -> b -> Bool) -> Type p `Reflects2` f = (x : a) -> (y : b) -> p x y `Reflects` f x y public export (||) : Dec p -> Dec q -> Dec (Either p q) Yes y1 || _ = Yes $ Left y1 No _ || Yes y2 = Yes $ Right y2 No n1 || No n2 = No $ \case Left y1 => n1 y1; Right y2 => n2 y2 public export (&&) : Dec p -> Dec q -> Dec (p, q) Yes y1 && Yes y2 = Yes (y1, y2) Yes _ && No n2 = No $ n2 . snd No n1 && _ = No $ n1 . fst public export map : p <=> q -> Dec p -> Dec q map (MkEquivalence l r) (Yes y) = Yes $ l y map (MkEquivalence l r) (No n) = No $ n . r public export reflectToDec : p `Reflects` b -> Dec p reflectToDec (RTrue y) = Yes y reflectToDec (RFalse n) = No n