Skip to content

Commit b82e028

Browse files
HeinrichApfelmusomelkonian
authored andcommitted
Add containers library with many proofs
1 parent 6c9de68 commit b82e028

File tree

10 files changed

+1814
-0
lines changed

10 files changed

+1814
-0
lines changed

lib/containers/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
`containers.agda-lib` proves properties about the Haskell [containers][] library.
2+
3+
4+
## Roadmap
5+
6+
For the time being, this library is developed as part of the [agda2hs][] repository. There are two reasons:
7+
8+
* Significant backflow of code from `containers.agda-lib` to `base.agda-lib`. For example, proving properties about `Data.Map.spanAntitone` will require additions to `Data.Ord`.
9+
* Informs the development of [agda2hs][]: changes to `agda2hs` are immediately confronted with the fact that there is at least one separate library of considerable size.
10+
11+
However, once [agda2hs][] has become sufficiently complete and stable, we want to move `containers.agda-lib` into a separate repository.
12+
13+
[agda2hs]: https://github.com/agda/agda2hs
14+
[containers]: https://hackage.haskell.org/package/containers

lib/containers/agda/Data/Map.agda

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Data.Map where
2+
3+
open import Haskell.Data.Map public
4+
open import Data.Map.Prop public
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
{-# OPTIONS --erasure #-}
2+
3+
module Data.Map.Maybe
4+
{-
5+
This module adds functions for the 'Maybe' type
6+
that are analogous to the functions in 'Data.Map'.
7+
This is used to make proofs for 'Data.Map' more transparent.
8+
-} where
9+
10+
open import Haskell.Law.Equality
11+
open import Haskell.Prelude hiding (null; map; filter)
12+
13+
open import Haskell.Data.Maybe using
14+
( isJust
15+
)
16+
17+
{-----------------------------------------------------------------------------
18+
Data.Maybe
19+
Functions
20+
------------------------------------------------------------------------------}
21+
22+
null : Maybe a Bool
23+
null Nothing = True
24+
null (Just x) = False
25+
26+
update : (a Maybe a) Maybe a Maybe a
27+
update f Nothing = Nothing
28+
update f (Just x) = f x
29+
30+
filter : (a Bool) Maybe a Maybe a
31+
filter p Nothing = Nothing
32+
filter p (Just x) = if p x then Just x else Nothing
33+
34+
-- | Degenerate 'filter', does not look at the contents.
35+
-- Similar to 'guard'.
36+
filt : Bool Maybe a Maybe a
37+
filt True m = m
38+
filt False m = Nothing
39+
40+
mapMaybe : (a Maybe b) Maybe a Maybe b
41+
mapMaybe f Nothing = Nothing
42+
mapMaybe f (Just x) = f x
43+
44+
unionWith : (a a a) Maybe a Maybe a Maybe a
45+
unionWith f Nothing my = my
46+
unionWith f (Just x) Nothing = Just x
47+
unionWith f (Just x) (Just y) = Just (f x y)
48+
49+
-- | Left-biased union.
50+
union : Maybe a Maybe a Maybe a
51+
union = unionWith (λ x y x)
52+
53+
intersectionWith : (a b c) Maybe a Maybe b Maybe c
54+
intersectionWith f (Just x) (Just y) = Just (f x y)
55+
intersectionWith _ _ _ = Nothing
56+
57+
disjoint : Maybe a Maybe b Bool
58+
disjoint m = null ∘ intersectionWith const m
59+
60+
{-----------------------------------------------------------------------------
61+
Properties
62+
union
63+
------------------------------------------------------------------------------}
64+
65+
--
66+
prop-union-empty-right
67+
: {ma : Maybe a}
68+
union ma Nothing ≡ ma
69+
--
70+
prop-union-empty-right {_} {Nothing} = refl
71+
prop-union-empty-right {_} {Just x} = refl
72+
73+
-- | 'unionWith' is symmetric if we 'flip' the function.
74+
-- Note that 'union' is left-biased, not symmetric.
75+
--
76+
prop-unionWith-sym
77+
: {f : a a a} {ma mb : Maybe a}
78+
unionWith f ma mb ≡ unionWith (flip f) mb ma
79+
--
80+
prop-unionWith-sym {_} {f} {Nothing} {Nothing} = refl
81+
prop-unionWith-sym {_} {f} {Just x} {Nothing} = refl
82+
prop-unionWith-sym {_} {f} {Nothing} {Just y} = refl
83+
prop-unionWith-sym {_} {f} {Just x} {Just y} = refl
84+
85+
--
86+
prop-union-assoc
87+
: {ma mb mc : Maybe a}
88+
union (union ma mb) mc ≡ union ma (union mb mc)
89+
--
90+
prop-union-assoc {_} {Nothing} {mb} {mc} = refl
91+
prop-union-assoc {_} {Just x} {Nothing} {mc} = refl
92+
prop-union-assoc {_} {Just x} {Just y} {Nothing} = refl
93+
prop-union-assoc {_} {Just x} {Just y} {Just z} = refl
94+
95+
-- | 'union' is symmetric if at most one argument is 'Just'.
96+
--
97+
prop-union-sym
98+
: {ma mb : Maybe a}
99+
disjoint ma mb ≡ True
100+
union ma mb ≡ union mb ma
101+
--
102+
prop-union-sym {_} {Nothing} {Nothing} eq = refl
103+
prop-union-sym {_} {Nothing} {Just x} eq = refl
104+
prop-union-sym {_} {Just x} {Nothing} eq = refl
105+
106+
--
107+
prop-union-left
108+
: (x : a) (mb : Maybe a)
109+
union (Just x) mb ≡ Just x
110+
--
111+
prop-union-left x Nothing = refl
112+
prop-union-left x (Just y) = refl
113+
114+
{-----------------------------------------------------------------------------
115+
Properties
116+
intersection
117+
------------------------------------------------------------------------------}
118+
--
119+
prop-isJust-intersectionWith
120+
: {ma : Maybe a} {mb : Maybe b} {f : a b c}
121+
isJust (intersectionWith f ma mb)
122+
≡ (isJust ma && isJust mb)
123+
--
124+
prop-isJust-intersectionWith {_} {_} {_} {Nothing} = refl
125+
prop-isJust-intersectionWith {_} {_} {_} {Just x} {Nothing} = refl
126+
prop-isJust-intersectionWith {_} {_} {_} {Just x} {Just y} = refl
127+
128+
{-----------------------------------------------------------------------------
129+
Properties
130+
filter
131+
------------------------------------------------------------------------------}
132+
-- |
133+
-- Since 'union' is left-biased,
134+
-- filtering commutes with union if the predicate is constant.
135+
--
136+
-- If the predicate is not constant, there are counterexamples.
137+
prop-filter-union
138+
: (p : a Bool) {m1 m2 : Maybe a}
139+
( (x y : a) p x ≡ p y)
140+
filter p (union m1 m2)
141+
≡ union (filter p m1) (filter p m2)
142+
--
143+
prop-filter-union p {Nothing} {m2} flat = refl
144+
prop-filter-union p {Just x} {Nothing} flat
145+
with p x
146+
... | True = refl
147+
... | False = refl
148+
prop-filter-union p {Just x} {Just y} flat
149+
rewrite flat x y
150+
with p y
151+
... | True = refl
152+
... | False = refl
153+
154+
--
155+
@0 prop-filter-||
156+
: {ma : Maybe a} {p q : a Bool}
157+
filter (λ x p x || q x) ma
158+
≡ union (filter p ma) (filter q ma)
159+
--
160+
prop-filter-|| {_} {Nothing} {p} {q} = refl
161+
prop-filter-|| {_} {Just x} {p} {q}
162+
with p x | q x
163+
... | True | True = refl
164+
... | True | False = refl
165+
... | False | True = refl
166+
... | False | False = refl
167+
168+
-- |
169+
-- 'filt' is a special case of 'filter'.
170+
prop-filter-filt
171+
: (b : Bool) (m : Maybe a)
172+
filter (λ x b) m
173+
≡ filt b m
174+
--
175+
prop-filter-filt False Nothing = refl
176+
prop-filter-filt True Nothing = refl
177+
prop-filter-filt False (Just x) = refl
178+
prop-filter-filt True (Just x) = refl
179+
180+
{-----------------------------------------------------------------------------
181+
Properties
182+
filt
183+
------------------------------------------------------------------------------}
184+
-- |
185+
-- Since 'union' is left-biased,
186+
-- filtering commutes with union if the predicate is constant.
187+
--
188+
-- If the predicate is not constant, there are counterexamples.
189+
prop-filt-||
190+
: (x y : Bool) {m : Maybe a}
191+
filt (x || y) m
192+
≡ union (filt x m) (filt y m)
193+
--
194+
prop-filt-|| False y {Nothing} = refl
195+
prop-filt-|| False y {Just x} = refl
196+
prop-filt-|| True False {Nothing} = refl
197+
prop-filt-|| True False {Just x} = refl
198+
prop-filt-|| True True {Nothing} = refl
199+
prop-filt-|| True True {Just x} = refl
200+
201+
--
202+
prop-filt-union
203+
: (x : Bool) {m1 m2 : Maybe a}
204+
filt x (union m1 m2)
205+
≡ union (filt x m1) (filt x m2)
206+
--
207+
prop-filt-union False {Nothing} {m2} = refl
208+
prop-filt-union True {Nothing} {m2} = refl
209+
prop-filt-union False {Just y} {Nothing} = refl
210+
prop-filt-union True {Just y} {Nothing} = refl
211+
prop-filt-union False {Just y} {Just z} = refl
212+
prop-filt-union True {Just y} {Just z} = refl
213+
214+
--
215+
prop-filt-filt
216+
: (x y : Bool) (m : Maybe a)
217+
filt x (filt y m) ≡ filt (x && y) m
218+
--
219+
prop-filt-filt False False m = refl
220+
prop-filt-filt False True m = refl
221+
prop-filt-filt True False m = refl
222+
prop-filt-filt True True m = refl

0 commit comments

Comments
 (0)