-
Notifications
You must be signed in to change notification settings - Fork 381
/
Copy pathBool.idr
135 lines (106 loc) · 3.58 KB
/
Bool.idr
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
module Data.Bool
%default total
export
notInvolutive : (x : Bool) -> not (not x) = x
notInvolutive True = Refl
notInvolutive False = Refl
-- AND
export
andSameNeutral : (x : Bool) -> x && x = x
andSameNeutral False = Refl
andSameNeutral True = Refl
export
andFalseFalse : (x : Bool) -> x && False = False
andFalseFalse False = Refl
andFalseFalse True = Refl
export
andTrueNeutral : (x : Bool) -> x && True = x
andTrueNeutral False = Refl
andTrueNeutral True = Refl
export
andAssociative : (x, y, z : Bool) -> x && (y && z) = (x && y) && z
andAssociative True _ _ = Refl
andAssociative False _ _ = Refl
export
andCommutative : (x, y : Bool) -> x && y = y && x
andCommutative x True = andTrueNeutral x
andCommutative x False = andFalseFalse x
export
andNotFalse : (x : Bool) -> x && not x = False
andNotFalse False = Refl
andNotFalse True = Refl
-- OR
export
orSameNeutral : (x : Bool) -> x || x = x
orSameNeutral False = Refl
orSameNeutral True = Refl
export
orFalseNeutral : (x : Bool) -> x || False = x
orFalseNeutral False = Refl
orFalseNeutral True = Refl
export
orTrueTrue : (x : Bool) -> x || True = True
orTrueTrue False = Refl
orTrueTrue True = Refl
export
orAssociative : (x, y, z : Bool) -> x || (y || z) = (x || y) || z
orAssociative True _ _ = Refl
orAssociative False _ _ = Refl
export
orCommutative : (x, y : Bool) -> x || y = y || x
orCommutative x True = orTrueTrue x
orCommutative x False = orFalseNeutral x
export
orNotTrue : (x : Bool) -> x || not x = True
orNotTrue False = Refl
orNotTrue True = Refl
export
orBothFalse : {0 x, y : Bool} -> (0 prf : x || y = False) -> (x = False, y = False)
orBothFalse prf = unerase $ orBothFalse' prf
where
unerase : (0 prf : (x = False, y = False)) -> (x = False, y = False)
unerase (p, q) = (irrelevantEq p, irrelevantEq q)
orBothFalse' : {x, y : Bool} -> x || y = False -> (x = False, y = False)
orBothFalse' {x = False} yFalse = (Refl, yFalse)
orBothFalse' {x = True} trueFalse = absurd trueFalse
-- interaction & De Morgan's laws
export
orSameAndRightNeutral : (x, y : Bool) -> x || (x && y) = x
orSameAndRightNeutral False _ = Refl
orSameAndRightNeutral True _ = Refl
export
andDistribOrR : (x, y, z : Bool) -> x && (y || z) = (x && y) || (x && z)
andDistribOrR False _ _ = Refl
andDistribOrR True _ _ = Refl
export
orDistribAndR : (x, y, z : Bool) -> x || (y && z) = (x || y) && (x || z)
orDistribAndR False _ _ = Refl
orDistribAndR True _ _ = Refl
export
notAndIsOr : (x, y : Bool) -> not (x && y) = not x || not y
notAndIsOr False _ = Refl
notAndIsOr True _ = Refl
export
notOrIsAnd : (x, y : Bool) -> not (x || y) = not x && not y
notOrIsAnd False _ = Refl
notOrIsAnd True _ = Refl
-- Interaction with typelevel `Not`
export
notTrueIsFalse : {1 x : Bool} -> Not (x = True) -> x = False
notTrueIsFalse {x=False} _ = Refl
notTrueIsFalse {x=True} f = absurd $ f Refl
export
notFalseIsTrue : {1 x : Bool} -> Not (x = False) -> x = True
notFalseIsTrue {x=True} _ = Refl
notFalseIsTrue {x=False} f = absurd $ f Refl
--------------------------------------------------------------------------------
-- Decidability specialized on bool
--------------------------------------------------------------------------------
||| You can reverse decidability when bool is involved.
-- Given a contra on bool equality Not (a = b), produce a proof of the opposite (that (not a) = b)
public export
invertContraBool : (a, b : Bool) -> Not (a = b) -> (not a = b)
invertContraBool False False contra = absurd $ contra Refl
invertContraBool False True contra = Refl
invertContraBool True False contra = Refl
invertContraBool True True contra = absurd $ contra Refl