1
+ -------------------------- MODULE MajorityProof ------------------------------
2
+ EXTENDS Majority , FiniteSetTheorems , TLAPS
3
+
4
+ (* **************************************************************************)
5
+ (* Proving type correctness is easy. *)
6
+ (************************************************************************** *)
7
+ LEMMA TypeCorrect == Spec => [] TypeOK
8
+ < 1 > 1 . Init => TypeOK
9
+ BY DEF Init , TypeOK
10
+ < 1 > 2 . TypeOK /\ [ Next ]_ vars => TypeOK '
11
+ BY DEF TypeOK , Next , vars
12
+ < 1 > . QED BY < 1 > 1 , < 1 > 2 , PTL DEF Spec
13
+
14
+ (* **************************************************************************)
15
+ (* Auxiliary lemmas about positions and occurrences. *)
16
+ (************************************************************************** *)
17
+ LEMMA PositionsOne == \A v : PositionsBefore ( v , 1 ) = { }
18
+ BY DEF PositionsBefore
19
+
20
+ LEMMA PositionsType == \A v , j : PositionsBefore ( v , j ) \in SUBSET ( 1 .. j - 1 )
21
+ BY DEF PositionsBefore
22
+
23
+ LEMMA PositionsFinite ==
24
+ ASSUME NEW v , NEW j \in Int
25
+ PROVE IsFiniteSet ( PositionsBefore ( v , j ) )
26
+ BY 1 \in Int , j - 1 \in Int , PositionsType , FS_Interval , FS_Subset , Zenon
27
+
28
+ LEMMA PositionsPlusOne ==
29
+ ASSUME TypeOK , NEW j \in 1 .. Len ( seq ) , NEW v
30
+ PROVE PositionsBefore ( v , j + 1 ) =
31
+ IF seq [ j ] = v THEN PositionsBefore ( v , j ) \union { j }
32
+ ELSE PositionsBefore ( v , j )
33
+ BY DEF TypeOK , PositionsBefore
34
+
35
+ LEMMA OccurrencesType == \A v : \A j \in Int : OccurrencesBefore ( v , j ) \in Nat
36
+ BY PositionsFinite , FS_CardinalityType DEF OccurrencesBefore
37
+
38
+ LEMMA OccurrencesOne == \A v : OccurrencesBefore ( v , 1 ) = 0
39
+ BY PositionsOne , FS_EmptySet DEF OccurrencesBefore
40
+
41
+ LEMMA OccurrencesPlusOne ==
42
+ ASSUME TypeOK , NEW j \in 1 .. Len ( seq ) , NEW v
43
+ PROVE OccurrencesBefore ( v , j + 1 ) =
44
+ IF seq [ j ] = v THEN OccurrencesBefore ( v , j ) + 1
45
+ ELSE OccurrencesBefore ( v , j )
46
+ < 1 > 1 . CASE seq [ j ] = v
47
+ < 2 > 1 . IsFiniteSet ( PositionsBefore ( v , j ) )
48
+ BY PositionsFinite
49
+ < 2 > 2 . j \notin PositionsBefore ( v , j )
50
+ BY PositionsType
51
+ < 2 > 3 . PositionsBefore ( v , j + 1 ) = PositionsBefore ( v , j ) \union { j }
52
+ BY < 1 > 1 , PositionsPlusOne , Zenon
53
+ < 2 > . QED BY < 1 > 1 , < 2 > 1 , < 2 > 2 , < 2 > 3 , FS_AddElement DEF OccurrencesBefore
54
+ < 1 > 2 . CASE seq [ j ] # v
55
+ BY < 1 > 2 , PositionsPlusOne , Zenon DEF OccurrencesBefore
56
+ < 1 > . QED BY < 1 > 1 , < 1 > 2
57
+
58
+ (* **************************************************************************)
59
+ (* We prove correctness based on the inductive invariant. *)
60
+ (************************************************************************** *)
61
+ LEMMA Correctness == Spec => [] Correct
62
+ < 1 > 1 . Init => Inv
63
+ BY OccurrencesOne DEF Init , Inv
64
+ < 1 > 2 . TypeOK /\ Inv /\ [ Next ]_ vars => Inv '
65
+ < 2 > . SUFFICES ASSUME TypeOK , Inv , Next PROVE Inv '
66
+ BY DEF Inv , vars , OccurrencesBefore , PositionsBefore
67
+ < 2 > . i <= Len ( seq ) /\ i ' = i + 1 /\ seq ' = seq
68
+ BY DEF Next
69
+ < 2 > 0 . \A v \in Value : OccurrencesBefore ( v , i ) ' = OccurrencesBefore ( v , i ' )
70
+ BY DEF OccurrencesBefore , PositionsBefore
71
+ < 2 > . USE OccurrencesType DEF TypeOK
72
+ < 2 > 1 . CASE cnt = 0 /\ cand ' = seq [ i ] /\ cnt ' = 1
73
+ < 3 > 1 . i \in PositionsBefore ( seq [ i ] , i + 1 )
74
+ BY DEF PositionsBefore
75
+ < 3 > 2 . 1 <= OccurrencesBefore ( seq [ i ] , i + 1 )
76
+ BY < 3 > 1 , PositionsFinite , FS_EmptySet DEF OccurrencesBefore
77
+ < 3 > 3 . 2 * ( OccurrencesBefore ( seq [ i ] , i + 1 ) - 1 ) <= ( i + 1 ) - 1 - 1
78
+ BY < 2 > 1 , OccurrencesPlusOne DEF Inv
79
+ < 3 > 4 . ASSUME NEW v \in Value \ { seq [ i ] }
80
+ PROVE 2 * OccurrencesBefore ( v , i + 1 ) <= ( i + 1 ) - 1 - 1
81
+ BY < 2 > 1 , OccurrencesPlusOne DEF Inv
82
+ < 3 > . QED BY < 2 > 0 , < 2 > 1 , < 3 > 2 , < 3 > 3 , < 3 > 4 DEF Inv
83
+ < 2 > 2 . CASE cnt # 0 /\ cand = seq [ i ] /\ cand ' = cand /\ cnt ' = cnt + 1
84
+ BY < 2 > 0 , < 2 > 2 , OccurrencesPlusOne DEF Inv
85
+ < 2 > 3 . CASE cnt # 0 /\ cand # seq [ i ] /\ cand ' = cand /\ cnt ' = cnt - 1
86
+ < 3 > 10 . cnt ' <= OccurrencesBefore ( cand ' , i ' )
87
+ BY < 2 > 3 , OccurrencesPlusOne DEF Inv
88
+ < 3 > 20 . 2 * ( OccurrencesBefore ( cand ' , i ' ) - cnt ' ) <= i ' - 1 - cnt '
89
+ BY < 2 > 3 , OccurrencesPlusOne DEF Inv
90
+ < 3 > 30 . ASSUME NEW v \in Value \ { cand ' }
91
+ PROVE 2 * OccurrencesBefore ( v , i ' ) <= i ' - 1 - cnt '
92
+ BY < 2 > 3 , OccurrencesPlusOne DEF Inv
93
+ < 3 > . QED BY < 2 > 0 , < 2 > 3 , < 3 > 10 , < 3 > 20 , < 3 > 30 DEF Inv
94
+ < 2 > . QED BY < 2 > 1 , < 2 > 2 , < 2 > 3 DEF Next
95
+ < 1 > 3 . TypeOK /\ Inv => Correct
96
+ BY OccurrencesType DEF TypeOK , Inv , Correct , Occurrences
97
+ < 1 > . QED BY < 1 > 1 , < 1 > 2 , < 1 > 3 , TypeCorrect , PTL DEF Spec
98
+
99
+ ==============================================================================
0 commit comments