Repository navigation
Expand file tree
/
Copy pathEx03.hs
More file actions
117 lines (72 loc) · 2.86 KB
/
Copy pathEx03.hs
File metadata and controls
117 lines (72 loc) · 2.86 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
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
-- | An example showing the usage of the What4 backend in copilot-theorem for
-- propositional logic on boolean streams.
module Main where
import Control.Monad (forM_)
import qualified Prelude as P
import Copilot.Theorem.What4
import Language.Copilot
spec :: Spec
spec = do
-- The constant value true, which is translated as the corresponding SMT
-- boolean literal.
-- prop "Example 1" (forAll true)
-- -- The constant value false, which is translated as the corresponding SMT
-- -- boolean literal.
-- prop "Example 2" (forAll false)
-- An inductively defined flavor of true, which requires induction to prove.
-- let a = [True] ++ a
-- prop "Example 3" (forAll a)
-- An inductively defined "a or not a" proposition.
--let a = [False] ++ b -- False, True, False, True,...
-- b = [True] ++ a -- True, False, True, False,...
--prop "Example 4" (forAll (a `xor` b))
-- -- A version of "a or not a" proposition which does not require any sort of
-- -- inductive argument.
-- let a = [False] ++ b
-- b = not a
-- prop "Example 5" (forAll (a || b))
-- -- A bit more convoluted version of Example 5, which is provable.
-- let a = [True, False] ++ b
-- b = [False] ++ not (drop 1 a)
-- prop "Example 6" (forAll (a || b))
-- -- Exercises:
-- --
-- -- How would you check if the monitor is always true (always fires).
-- -- That monitor would then be useless!!
-- --
-- -- How would you check if the monitor is always false (never fires).
-- -- That monitor would then be useless!!
-- --
-- -- How would you check if, given two monitors, they are exclusive (they
-- -- can't both fire at the same time)?
-- -- How would you check if, given two properties, one of them will always
-- -- fire.
-- An example using external streams.
let b :: Stream Int32
b = extern "b" Nothing
prop "Example 7" (forAll (b > 10 || b <= 10))
-- -- An example using external streams.
-- --
-- -- This points to the system under study being potentially unrealizable. If
-- -- one of the monitored properties will always fire at some point, that means
-- -- that the system will be permanently correcting an unwanted situation and
-- -- is never in nominal state.
-- let b :: Stream Int32
-- b = extern "b" Nothing
-- p1 = b > 100 -- the temperature is too high
-- p2 = b <= 100 -- the temperature is too low
-- prop "Example 8" (forAll (p1 || p2))
return ()
main :: IO ()
main = do
spec' <- reify spec
-- Use Z3 to prove the properties.
results <- prove Z3 spec'
let printResult (propName, propRes) = do
putStr $ propName <> ": "
case propRes of
Valid -> putStrLn "valid"
Invalid -> putStrLn "invalid"
Unknown -> putStrLn "unknown"
-- Print the results.
forM_ results printResult