@@ -0,0 +1,74 @@
1+module Data.List.Quantifiers
5+||| A proof that some element of a list satisfies some property
7+||| @ P the property to be satsified
8+data Any : (P : a -> Type) -> List a -> Type where
9+ ||| A proof that the satisfying element is the first one in the `List`
10+ Here : {P : a -> Type} -> {xs : List a} -> P x -> Any P (x :: xs)
11+ ||| A proof that the satsifying element is in the tail of the `List`
12+ There : {P : a -> Type} -> {xs : List a} -> Any P xs -> Any P (x :: xs)
14+||| No element of an empty list satisfies any property
15+anyNilAbsurd : {P : a -> Type} -> Any P Nil -> Void
16+anyNilAbsurd (Here _) impossible
17+anyNilAbsurd (There _) impossible
19+instance Uninhabited (Any p Nil) where
20+ uninhabited = anyNilAbsurd
22+anyElim : {xs : List a} -> {P : a -> Type} -> (Any P xs -> b) -> (P x -> b) -> Any P (x :: xs) -> b
23+anyElim _ f (Here p) = f p
24+anyElim f _ (There p) = f p
26+||| Given a decision procedure for a property, determine if an element of a
27+||| list satisfies it.
29+||| @ P the property to be satisfied
30+||| @ dec the decision procedure
31+||| @ xs the list to examine
32+any : {P : a -> Type} -> (dec : (x : a) -> Dec (P x)) -> (xs : List a) -> Dec (Any P xs)
33+any _ Nil = No anyNilAbsurd
34+any p (x::xs) with (p x)
35+ | Yes prf = Yes (Here prf)
38+ Yes prf' => Yes (There prf')
39+ No prf' => No (anyElim prf' prf)
41+||| A proof that all elements of a list satisfy a property. It is a list of
42+||| proofs, corresponding element-wise to the `List`.
43+data All : (P : a -> Type) -> List a -> Type where
44+ Nil : {P : a -> Type} -> All P Nil
45+ (::) : {P : a -> Type} -> {xs : List a} -> P x -> All P xs -> All P (x :: xs)
47+||| If there does not exist an element that satifies the property, then it is
48+||| the case that all elements do not satisfy.
49+negAnyAll : {P : a -> Type} -> {xs : List a} -> Not (Any P xs) -> All (\x => Not (P x)) xs
50+negAnyAll {xs=Nil} _ = Nil
51+negAnyAll {xs=(x::xs)} f = (\x => f (Here x)) :: negAnyAll (\x => f (There x))
53+notAllHere : {P : a -> Type} -> {xs : List a} -> Not (P x) -> All P (x :: xs) -> Void
54+notAllHere _ Nil impossible
55+notAllHere np (p :: _) = np p
57+notAllThere : {P : a -> Type} -> {xs : List a} -> Not (All P xs) -> All P (x :: xs) -> Void
58+notAllThere _ Nil impossible
59+notAllThere np (_ :: ps) = np ps
61+||| Given a decision procedure for a property, decide whether all elements of
62+||| a list satisfy it.
65+||| @ dec the decision procedure
66+||| @ xs the list to examine
67+all : {P : a -> Type} -> (dec : (x : a) -> Dec (P x)) -> (xs : List a) -> Dec (All P xs)
69+all d (x::xs) with (d x)
70+ | No prf = No (notAllHere prf)
73+ Yes prf' => Yes (prf :: prf')
74+ No prf' => No (notAllThere prf')