StrongConsensus.hs 11.1 KB
Newer Older
1
2
{-# LANGUAGE FlexibleContexts #-}

Philipp Meyer's avatar
Philipp Meyer committed
3
4
5
module Solver.StrongConsensus
    (checkStrongConsensusSat,
     StrongConsensusCounterExample,
Philipp J. Meyer's avatar
Philipp J. Meyer committed
6
7
     findTrapConstraintsSat,
     findUTrapConstraintsSat,
8
     findUSiphonConstraintsSat)
9
10
11
where

import Data.SBV
12
import qualified Data.Map as M
13
import Data.List ((\\))
14
15

import Util
16
import PopulationProtocol
17
18
19
import Property
import Solver

20
type StrongConsensusCounterExample = (Configuration, Configuration, Configuration, FlowVector, FlowVector)
21

22
23
24
25
26
27
28
stateEquationConstraints :: PopulationProtocol -> SIMap State -> SIMap State -> SIMap Transition -> SBool
stateEquationConstraints pp m0 m x =
            bAnd $ map checkStateEquation $ states pp
        where checkStateEquation q =
                let incoming = map addTransition $ lpre pp q
                    outgoing = map addTransition $ lpost pp q
                in  val m0 q + sum incoming - sum outgoing .== val m q
29
              addTransition (t,w) = literal w * val x t
30

31
nonNegativityConstraints :: (Ord a, Show a) => SIMap a -> SBool
32
33
34
nonNegativityConstraints m =
            bAnd $ map checkVal $ vals m
        where checkVal x = x .>= 0
35

36
37
38
39
40
terminalConstraints :: PopulationProtocol -> SIMap State -> SBool
terminalConstraints pp m =
            bAnd $ map checkTransition $ transitions pp
        where checkTransition t = bOr $ map checkState $ lpre pp t
              checkState (q,w) = val m q .<= literal (fromInteger (w - 1))
41

42
43
initialConfiguration :: PopulationProtocol -> SIMap State -> SBool
initialConfiguration pp m0 =
44
        sum (mval m0 (states pp \\ initialStates pp)) .== 0
45

46
47
differentConsensusConstraints :: PopulationProtocol -> SIMap State -> SIMap State -> SBool
differentConsensusConstraints pp m1 m2 =
48
        (sum (mval m1 (trueStates pp)) .> 0 &&& sum (mval m2 (falseStates pp)) .> 0)
49

50
51
unmarkedByConfiguration :: [State] -> SIMap State -> SBool
unmarkedByConfiguration r m = sum (mval m r) .== 0
Philipp J. Meyer's avatar
Philipp J. Meyer committed
52

53
54
markedByConfiguration :: [State] -> SIMap State -> SBool
markedByConfiguration r m = sum (mval m r) .> 0
Philipp J. Meyer's avatar
Philipp J. Meyer committed
55
56
57
58
59
60
61

sequenceNotIn :: [Transition] -> SIMap Transition -> SBool
sequenceNotIn u x = sum (mval x u) .== 0

sequenceIn :: [Transition] -> SIMap Transition -> SBool
sequenceIn u x = sum (mval x u) .> 0

62
63
checkUTrap :: PopulationProtocol -> SIMap State -> SIMap State -> SIMap State -> SIMap Transition -> SIMap Transition -> Trap -> SBool
checkUTrap pp m0 m1 m2 x1 x2 utrap =
64
65
            (((sequenceIn upre x1) &&& (sequenceNotIn uunmark x1)) ==> (markedByConfiguration utrap m1)) &&&
            (((sequenceIn upre x2) &&& (sequenceNotIn uunmark x2)) ==> (markedByConfiguration utrap m2))
66
67
        where upost = mpost pp utrap
              upre = mpre pp utrap
68
              uunmark = upost \\ upre
Philipp J. Meyer's avatar
Philipp J. Meyer committed
69

70
71
72
checkUTrapConstraints :: PopulationProtocol -> SIMap State -> SIMap State -> SIMap State -> SIMap Transition -> SIMap Transition -> [Trap] -> SBool
checkUTrapConstraints pp m0 m1 m2 x1 x2 traps =
        bAnd $ map (checkUTrap pp m0 m1 m2 x1 x2) traps
Philipp J. Meyer's avatar
Philipp J. Meyer committed
73

74
75
checkUSiphon :: PopulationProtocol -> SIMap State -> SIMap State -> SIMap State -> SIMap Transition -> SIMap Transition -> Siphon -> SBool
checkUSiphon pp m0 m1 m2 x1 x2 usiphon =
76
77
            (((sequenceIn upost x1) &&& (sequenceNotIn umark x1)) ==> (markedByConfiguration usiphon m0)) &&&
            (((sequenceIn upost x2) &&& (sequenceNotIn umark x2)) ==> (markedByConfiguration usiphon m0))
78
79
        where upost = mpost pp usiphon
              upre = mpre pp usiphon
80
              umark = upre \\ upost
Philipp J. Meyer's avatar
Philipp J. Meyer committed
81

82
83
84
checkUSiphonConstraints :: PopulationProtocol -> SIMap State -> SIMap State -> SIMap State -> SIMap Transition -> SIMap Transition -> [Siphon] -> SBool
checkUSiphonConstraints pp m0 m1 m2 x1 x2 siphons =
        bAnd $ map (checkUSiphon pp m0 m1 m2 x1 x2) siphons
85

Philipp Meyer's avatar
Philipp Meyer committed
86
checkStrongConsensus :: PopulationProtocol -> SIMap State -> SIMap State -> SIMap State -> SIMap Transition -> SIMap Transition ->
87
88
        [Trap] -> [Siphon] -> SBool
checkStrongConsensus pp m0 m1 m2 x1 x2 utraps usiphons =
89
90
        stateEquationConstraints pp m0 m1 x1 &&&
        stateEquationConstraints pp m0 m2 x2 &&&
91
        initialConfiguration pp m0 &&&
92
93
94
95
96
        nonNegativityConstraints m0 &&&
        nonNegativityConstraints m1 &&&
        nonNegativityConstraints m2 &&&
        nonNegativityConstraints x1 &&&
        nonNegativityConstraints x2 &&&
97
98
99
100
        terminalConstraints pp m1 &&&
        terminalConstraints pp m2 &&&
        differentConsensusConstraints pp m1 m2 &&&
        checkUTrapConstraints pp m0 m1 m2 x1 x2 utraps &&&
101
        checkUSiphonConstraints pp m0 m1 m2 x1 x2 usiphons
102

103
104
checkStrongConsensusSat :: PopulationProtocol -> [Trap] -> [Siphon] -> ConstraintProblem Integer StrongConsensusCounterExample
checkStrongConsensusSat pp utraps usiphons =
105
106
107
108
109
        let m0 = makeVarMap $ states pp
            m1 = makeVarMapWith prime $ states pp
            m2 = makeVarMapWith (prime . prime) $ states pp
            x1 = makeVarMap $ transitions pp
            x2 = makeVarMapWith prime $ transitions pp
110
        in  ("strong consensus", "(c0, c1, c2, x1, x2)",
111
             getNames m0 ++ getNames m1 ++ getNames m2 ++ getNames x1 ++ getNames x2,
112
             \fm -> checkStrongConsensus pp (fmap fm m0) (fmap fm m1) (fmap fm m2) (fmap fm x1) (fmap fm x2) utraps usiphons,
113
             \fm -> configurationsFromAssignment (fmap fm m0) (fmap fm m1) (fmap fm m2) (fmap fm x1) (fmap fm x2))
114

115
116
configurationsFromAssignment :: IMap State -> IMap State -> IMap State -> IMap Transition -> IMap Transition -> StrongConsensusCounterExample
configurationsFromAssignment m0 m1 m2 x1 x2 =
117
        (makeVector m0, makeVector m1, makeVector m2, makeVector x1, makeVector x2)
118

119
120
-- trap and siphon refinement constraints

121
122
123
trapConstraint :: PopulationProtocol -> SIMap State -> Transition -> SBool
trapConstraint pp b t =
        sum (mval b $ pre pp t) .> 0 ==> sum (mval b $ post pp t) .> 0
Philipp J. Meyer's avatar
Philipp J. Meyer committed
124

125
126
127
siphonConstraint :: PopulationProtocol -> SIMap State -> Transition -> SBool
siphonConstraint pp b t =
        sum (mval b $ post pp t) .> 0 ==> sum (mval b $ pre pp t) .> 0
128

129
130
131
trapConstraints :: PopulationProtocol -> SIMap State -> SBool
trapConstraints pp b =
        bAnd $ map (trapConstraint pp b) $ transitions pp
Philipp J. Meyer's avatar
Philipp J. Meyer committed
132

133
uTrapConstraints :: PopulationProtocol -> FlowVector -> SIMap State -> SBool
134
135
uTrapConstraints pp x b =
        bAnd $ map (trapConstraint pp b) $ elems x
Philipp J. Meyer's avatar
Philipp J. Meyer committed
136

137
uSiphonConstraints :: PopulationProtocol -> FlowVector -> SIMap State -> SBool
138
139
uSiphonConstraints pp x b =
        bAnd $ map (siphonConstraint pp b) $ elems x
140

141
142
statesMarkedByConfiguration :: PopulationProtocol -> Configuration -> SIMap State -> SBool
statesMarkedByConfiguration pp m b = sum (mval b $ elems m) .> 0
143

144
145
statesUnmarkedByConfiguration :: PopulationProtocol -> Configuration -> SIMap State -> SBool
statesUnmarkedByConfiguration pp m b = sum (mval b $ elems m) .== 0
146

147
statesPostsetOfSequence :: PopulationProtocol -> FlowVector -> SIMap State -> SBool
148
statesPostsetOfSequence pp x b = sum (mval b $ mpost pp $ elems x) .> 0
149

150
statesPresetOfSequence :: PopulationProtocol -> FlowVector -> SIMap State -> SBool
151
statesPresetOfSequence pp x b = sum (mval b $ mpre pp $ elems x) .> 0
152

153
noOutputTransitionEnabled :: PopulationProtocol -> Configuration -> SIMap State -> SBool
154
155
noOutputTransitionEnabled pp m b =
            bAnd $ map outputTransitionNotEnabled $ transitions pp
156
157
        where
            outputTransitionNotEnabled t = outputTransitionOfB t ==> transitionNotEnabledInB t
158
159
            outputTransitionOfB t = sum [val b q | (q, w) <- lpre pp t, val m q >= w] .> 0
            transitionNotEnabledInB t = sum [val b q | (q, w) <- lpre pp t, val m q < w] .> 0
160

161
162
nonemptySet :: (Ord a, Show a) => SIMap a -> SBool
nonemptySet b = sum (vals b) .> 0
163

164
checkBinary :: SIMap State -> SBool
165
166
checkBinary = bAnd . map (\x -> x .== 0 ||| x .== 1) . vals

167
checkSizeLimit :: SIMap State -> Maybe (Int, Integer) -> SBool
168
169
170
171
172
173
174
175
176
177
checkSizeLimit _ Nothing = true
checkSizeLimit b (Just (1, curSize)) = (.< literal curSize) $ sumVal b
checkSizeLimit b (Just (2, curSize)) = (.> literal curSize) $ sumVal b
checkSizeLimit _ (Just (_, _)) = error "minimization method not supported"

minimizeMethod :: Int -> Integer -> String
minimizeMethod 1 curSize = "size smaller than " ++ show curSize
minimizeMethod 2 curSize = "size larger than " ++ show curSize
minimizeMethod _ _ = error "minimization method not supported"

178
179
findTrapConstraints :: PopulationProtocol -> StrongConsensusCounterExample -> SIMap State -> Maybe (Int, Integer) -> SBool
findTrapConstraints pp (m0, m1, m2, x1, x2) b sizeLimit =
180
181
        checkSizeLimit b sizeLimit &&&
        checkBinary b &&&
182
        trapConstraints pp b &&&
183
        (
184
185
            (statesPostsetOfSequence pp x1 b &&& statesUnmarkedByConfiguration pp m1 b) |||
            (statesPostsetOfSequence pp x2 b &&& statesUnmarkedByConfiguration pp m2 b)
186
        )
187

188
189
findTrapConstraintsSat :: PopulationProtocol -> StrongConsensusCounterExample -> MinConstraintProblem Integer Trap Integer
findTrapConstraintsSat pp c =
190
        let b = makeVarMap $ states pp
Philipp J. Meyer's avatar
Philipp J. Meyer committed
191
        in  (minimizeMethod, \sizeLimit ->
192
            ("trap marked by x1 or x2 and not marked in m1 or m2", "trap",
Philipp J. Meyer's avatar
Philipp J. Meyer committed
193
             getNames b,
194
             \fm -> findTrapConstraints pp c (fmap fm b) sizeLimit,
195
             \fm -> statesFromAssignment (fmap fm b)))
Philipp J. Meyer's avatar
Philipp J. Meyer committed
196

197
198
findUTrapConstraints :: PopulationProtocol -> StrongConsensusCounterExample -> SIMap State -> Maybe (Int, Integer) -> SBool
findUTrapConstraints pp (m0, m1, m2, x1, x2) b sizeLimit =
Philipp J. Meyer's avatar
Philipp J. Meyer committed
199
200
201
        checkSizeLimit b sizeLimit &&&
        checkBinary b &&&
        (
202
203
            (statesPostsetOfSequence pp x1 b &&& uTrapConstraints pp x1 b &&& statesUnmarkedByConfiguration pp m1 b) |||
            (statesPostsetOfSequence pp x2 b &&& uTrapConstraints pp x2 b &&& statesUnmarkedByConfiguration pp m2 b)
Philipp J. Meyer's avatar
Philipp J. Meyer committed
204
205
        )

206
207
findUTrapConstraintsSat :: PopulationProtocol -> StrongConsensusCounterExample -> MinConstraintProblem Integer Trap Integer
findUTrapConstraintsSat pp c =
208
        let b = makeVarMap $ states pp
209
        in  (minimizeMethod, \sizeLimit ->
210
            ("u-trap (w.r.t. x1 or x2) marked by x1 or x2 and not marked in m1 or m2", "u-trap",
211
             getNames b,
212
             \fm -> findUTrapConstraints pp c (fmap fm b) sizeLimit,
213
             \fm -> statesFromAssignment (fmap fm b)))
214

215
216
findUSiphonConstraints :: PopulationProtocol -> StrongConsensusCounterExample -> SIMap State -> Maybe (Int, Integer) -> SBool
findUSiphonConstraints pp (m0, m1, m2, x1, x2) b sizeLimit =
217
218
        checkSizeLimit b sizeLimit &&&
        checkBinary b &&&
219
        statesUnmarkedByConfiguration pp m0 b &&&
220
        (
221
222
            (statesPresetOfSequence pp x1 b &&& uSiphonConstraints pp x1 b) |||
            (statesPresetOfSequence pp x2 b &&& uSiphonConstraints pp x2 b)
223
        )
224

225
226
findUSiphonConstraintsSat :: PopulationProtocol -> StrongConsensusCounterExample -> MinConstraintProblem Integer Siphon Integer
findUSiphonConstraintsSat pp c =
227
        let b = makeVarMap $ states pp
228
        in  (minimizeMethod, \sizeLimit ->
229
            ("u-siphon (w.r.t. x1 or x2) used by x1 or x2 and unmarked in m0", "u-siphon",
230
             getNames b,
231
             \fm -> findUSiphonConstraints pp c (fmap fm b) sizeLimit,
232
             \fm -> statesFromAssignment (fmap fm b)))
233

234
235
statesFromAssignment :: IMap State -> ([State], Integer)
statesFromAssignment b = (M.keys (M.filter (> 0) b), sum (M.elems b))