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
|
module Search.CaseMap where
import qualified Data.FiniteMap as FM
import List (intersect, union)
import Language.SMTLIB.Goodies (tvar)
import Language.SMTLIB.Types (QIdent, Sort, Term)
import Symbolic (BranchNr (..), CoverInfo (..), CoveredCs (..))
class (Ord k) => ContextKey k where
primKey :: k -> Int
ctxtKey :: k -> k
instance ContextKey Int where
primKey = id
ctxtKey = id
instance ContextKey a => ContextKey [a] where
primKey [] = error "ContextKey.primKey: Invalid context key"
primKey (k:_) = primKey k
ctxtKey [] = error "ContextKey.ctxtKey: Invalid context key"
ctxtKey (_:ks) = ks
data ContextMap k v = CM { cm :: FM.FM Int (FM.FM k v) }
class CaseMap m where
emptyCM :: ContextKey k => m k v
updateCM :: ContextKey k => k -> v -> m k v -> m k v
updateWithCM :: ContextKey k => (v -> v -> v) -> k -> v -> m k v -> m k v
lookupCM :: ContextKey k => k -> m k v -> Maybe v
isCovered :: (ContextKey k, Show k, CaseMap m) => k -> m k CoverInfo -> Bool
isCovered k cm = case lookupCM k cm of
Nothing -> error $ "CaseMap.isCovered: No coverage info for key " ++ show k
Just ci -> null $ uncovered ci
covered :: (ContextKey k, Show k, CaseMap m) => k -> m k CoverInfo -> CoveredCs
covered k cm = case lookupCM k cm of
Nothing -> error $ "CaseMap.covered: No coverage info for key " ++ show k
Just ci -> coveredCs ci
cover :: (ContextKey k, CaseMap m) => k -> BranchNr -> CoveredCs
-> m k CoverInfo -> m k CoverInfo
cover k (BNr m n) cc cm = updateWithCM combInfo k info cm
where
info = CoverInfo [b | b <- [1 .. n], b /= m] cc
combInfo :: CoverInfo -> CoverInfo -> CoverInfo
combInfo (CoverInfo u1 cc1) (CoverInfo u2 cc2)
= let cc' = case (cc1, cc2) of
(CCons cs1, CCons cs2) -> CCons (cs1 `union` cs2)
(CConstr lc1 l1, CConstr _ _) -> CConstr lc1 l1
_ ->
error "CaseMap.combInfo: Incompatible coverage info"
in CoverInfo (u1 `intersect` u2) cc'
coverAll :: (ContextKey k, CaseMap m) => k -> m k CoverInfo -> m k CoverInfo
coverAll k cm = case lookupCM k cm of
Nothing -> cm
Just (CoverInfo _ cc) -> updateCM k (CoverInfo [] cc) cm
instance CaseMap FM.FM where
emptyCM = FM.emptyFM (<)
updateCM k v cm = FM.addToFM cm k v
updateWithCM f k v cm = FM.addToFM_C f cm k v
lookupCM = flip FM.lookupFM
instance CaseMap ContextMap where
emptyCM = CM (FM.emptyFM (<))
updateCM k v m =
CM $ FM.addToFM_C FM.plusFM (cm m) (primKey k) (FM.unitFM (<) (ctxtKey k) v)
updateWithCM f k v m =
CM $ FM.addToFM_C (FM.plusFM_C f) (cm m) (primKey k) (FM.unitFM (<) (ctxtKey k) v)
lookupCM k m = case FM.lookupFM (cm m) (primKey k) of
Nothing -> Nothing
Just fm -> FM.lookupFM fm (ctxtKey k)
|