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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
module KeyDB(existsDBKey,allDBKeys,getDBInfo,getDBInfos,
deleteDBEntry,updateDBEntry,newDBEntry,cleanDB,
index,sortByIndex,groupByIndex) where
import Dynamic
import Integer(maxlist)
import Sort
import List
existsDBKey :: (Int -> _ -> Dynamic) -> Int -> IO Bool
existsDBKey db key = seq db $ seq key $ do
entries <- getDynamicSolution (\info -> db key info)
return (entries /= Nothing)
allDBKeys :: (Int -> _ -> Dynamic) -> IO [Int]
allDBKeys db = seq db $ do
getDynamicSolutions (\key -> db key unknown)
getDBInfo :: (Int -> a -> Dynamic) -> Int -> IO a
getDBInfo db key = seq db $ seq key $ do
entries <- getDynamicSolutions (\info -> db key info)
if null entries
then error ("getDBInfo: no entry for key '"++show key++"'")
else return (head entries)
index :: a -> [a] -> Int
index x xs = idx 0 xs
where
idx n (y:ys) = if x==y then n else idx (n+1) ys
sortByIndex :: [(Int,b)] -> [b]
sortByIndex = map snd . mergeSortBy (\x y -> fst x < fst y)
groupByIndex :: [(Int,b)] -> [[b]]
groupByIndex = addEmptyIdxs 0 . groupBy (\x y -> fst x == fst y)
. mergeSortBy (\x y -> fst x < fst y)
where
addEmptyIdxs _ [] = []
addEmptyIdxs n (((m,x):xs):ys) =
if n==m then (x:map snd xs) : addEmptyIdxs (n+1) ys
else []:addEmptyIdxs (n+1) (((m,x):xs):ys)
getDBInfos :: (Int -> a -> Dynamic) -> [Int] -> IO [a]
getDBInfos db keys = seq db $ seq (normalForm keys) $ do
entries <- getDynamicSolutions (\ (i,info) -> let key free in
db key info |&> (i=:=index key keys))
return (sortByIndex entries)
deleteDBEntry :: (Int -> _ -> Dynamic) -> Int -> IO ()
deleteDBEntry db key = seq db $ seq key $ do
entries <- getDynamicSolutions (\infos -> db key infos)
mapIO_ (\infos -> retract (db key infos)) entries
updateDBEntry :: (Int -> a -> Dynamic) -> Int -> a -> IO ()
updateDBEntry db key info = do
deleteDBEntry db key
assert (db key info)
newDBKey :: (Int -> _ -> Dynamic) -> IO Int
newDBKey db = do
ids <- getDynamicSolutions (\i -> db i unknown)
return (if null ids then 1 else maxlist ids + 1)
newDBEntry :: (Int -> a -> Dynamic) -> a -> IO Int
newDBEntry db info = do
i <- newDBKey db
assert (db i info)
return i
cleanDB :: (Int -> _ -> Dynamic) -> IO ()
cleanDB db = do
ids <- getDynamicSolutions (\i -> db i unknown)
mapIO_ (\i -> deleteDBEntry db i) ids
|