-
Notifications
You must be signed in to change notification settings - Fork 24
/
State.hs
43 lines (34 loc) · 1.29 KB
/
State.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
{-@ LIQUID "--reflection" @-}
{-@ LIQUID "--ple" @-}
module State where
import Prelude hiding ((++), const, max)
import ProofCombinators
-- | A Generic "State"
data GState k v = GState
{ sVals :: [(k, v)] -- ^ binders and their values
, sDef :: v -- ^ default value (for missing binder)
}
{-@ reflect init @-}
init :: v -> GState k v
init def = GState [] def
{-@ reflect set @-}
set :: GState k v -> k -> v -> GState k v
set (GState kvs v0) k v = GState ((k,v) : kvs) v0
{-@ reflect getDefault @-}
getDefault :: (Eq k) => v -> k -> [(k, v)] -> v
getDefault v0 key ((k, v) : kvs)
| key == k = v
| otherwise = getDefault v0 key kvs
getDefault v0 _ [] = v0
{-@ reflect get @-}
get :: (Eq k) => GState k v -> k -> v
-- get (GState kvs v0) key = getDefault v0 key kvs
get (GState [] v0) key = v0
get (GState ((k,v):kvs) v0) key = if key == k then v else get (GState kvs v0) key
{-@ lemma_get_set :: k:_ -> v:_ -> s:_ -> { get (set s k v) k == v } @-}
lemma_get_set :: k -> v -> GState k v -> Proof
lemma_get_set _ _ _ = ()
{-@ lemma_get_not_set :: k0:_ -> k:{k /= k0} -> val:_ -> s:_
-> { get (set s k val) k0 = get s k0 } @-}
lemma_get_not_set :: k -> k -> v -> GState k v -> Proof
lemma_get_not_set _ _ _ (GState {}) = ()