-
Notifications
You must be signed in to change notification settings - Fork 75
Expand file tree
/
Copy pathSerialBoyerMoore.hs
More file actions
62 lines (45 loc) · 1.59 KB
/
SerialBoyerMoore.hs
File metadata and controls
62 lines (45 loc) · 1.59 KB
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
{-# LANGUAGE RebindableSyntax #-}
module SerialBoyerMoore where
import Copilot.Language
import Copilot.Theorem
import Copilot.Theorem.Prover.SMT (def, Options (..), induction, kInduction, z3)
import Prelude ()
import Data.String (fromString)
conj :: [Stream Bool] -> Stream Bool
conj = foldl (&&) true
disj :: [Stream Bool] -> Stream Bool
disj = foldl (||) false
forAllCst :: Typed a => [a] -> (Stream a -> Stream Bool) -> Stream Bool
forAllCst l f = conj $ map (f . constant) l
existsCst :: Typed a => [a] -> (Stream a -> Stream Bool) -> Stream Bool
existsCst l f = disj $ map (f . constant) l
allowed :: [Word64]
allowed = [1, 2]
majority :: Stream Word64 -> (Stream Word64, Stream Word64, Stream Bool)
majority l = (p, s, j)
where
p = [0] ++ if s <= 0 then l else p
s = [0] ++ if (p == l) || (s <= 0) then s + 1 else s - 1
k = [0] ++ (1 + k)
count m = cnt
where
cnt = [0] ++ if l == m then cnt + 1 else cnt
j = forAllCst allowed $ \m ->
local (count m) $ \cnt ->
let j0 = (m /= p) ==> ((s + 2 * cnt) <= k)
j1 = (m == p) ==> ((2 * cnt) <= (s + k))
in j0 && j1
spec = do
observer "i" input
observer "p" p
observer "s" s
observer "j" j
inRange <- prop "inRange" (forAll $ input < 3)
theorem "J" (forAll j) $ assume inRange >> induct
where
input = externW64 "in" (Just [1, 1, 2, 1, 2, 2, 1, 2, 2, 1, 2, 1])
(p, s, j) = majority input
induct :: Proof Universal
induct = induction def { debug = False } z3
kinduct :: Word32 -> Proof Universal
kinduct k = kInduction def { startK = k, maxK = k, debug = False } z3