39 rewrite_goals_tac cmd_defs, |
39 rewrite_goals_tac cmd_defs, |
40 Auto_tac]); |
40 Auto_tac]); |
41 |
41 |
42 |
42 |
43 (*The booleans p, u, v are always either 0 or 1*) |
43 (*The booleans p, u, v are always either 0 or 1*) |
44 goalw thy [stable_def, boolVars_def] |
44 Goalw [stable_def, boolVars_def] |
45 "stable mutex boolVars"; |
45 "stable mutex boolVars"; |
46 by (constrains_tac 1); |
46 by (constrains_tac 1); |
47 by (auto_tac (claset() addSEs [less_SucE], simpset())); |
47 by (auto_tac (claset() addSEs [less_SucE], simpset())); |
48 qed "stable_boolVars"; |
48 qed "stable_boolVars"; |
49 |
49 |
50 goal thy "reachable MInit mutex <= boolVars"; |
50 Goal "reachable MInit mutex <= boolVars"; |
51 by (rtac strongest_invariant 1); |
51 by (rtac strongest_invariant 1); |
52 by (rtac stable_boolVars 2); |
52 by (rtac stable_boolVars 2); |
53 by (rewrite_goals_tac [MInit_def, boolVars_def]); |
53 by (rewrite_goals_tac [MInit_def, boolVars_def]); |
54 by Auto_tac; |
54 by Auto_tac; |
55 qed "reachable_subset_boolVars"; |
55 qed "reachable_subset_boolVars"; |
56 |
56 |
57 val reachable_subset_boolVars' = |
57 val reachable_subset_boolVars' = |
58 rewrite_rule [boolVars_def] reachable_subset_boolVars; |
58 rewrite_rule [boolVars_def] reachable_subset_boolVars; |
59 |
59 |
60 goalw thy [stable_def, invariant_def] |
60 Goalw [stable_def, invariant_def] |
61 "stable mutex (invariant 0 UU MM)"; |
61 "stable mutex (invariant 0 UU MM)"; |
62 by (constrains_tac 1); |
62 by (constrains_tac 1); |
63 qed "stable_invar_0um"; |
63 qed "stable_invar_0um"; |
64 |
64 |
65 goalw thy [stable_def, invariant_def] |
65 Goalw [stable_def, invariant_def] |
66 "stable mutex (invariant 1 VV NN)"; |
66 "stable mutex (invariant 1 VV NN)"; |
67 by (constrains_tac 1); |
67 by (constrains_tac 1); |
68 qed "stable_invar_1vn"; |
68 qed "stable_invar_1vn"; |
69 |
69 |
70 goalw thy [MInit_def, invariant_def] "MInit <= invariant 0 UU MM"; |
70 Goalw [MInit_def, invariant_def] "MInit <= invariant 0 UU MM"; |
71 by Auto_tac; |
71 by Auto_tac; |
72 qed "MInit_invar_0um"; |
72 qed "MInit_invar_0um"; |
73 |
73 |
74 goalw thy [MInit_def, invariant_def] "MInit <= invariant 1 VV NN"; |
74 Goalw [MInit_def, invariant_def] "MInit <= invariant 1 VV NN"; |
75 by Auto_tac; |
75 by Auto_tac; |
76 qed "MInit_invar_1vn"; |
76 qed "MInit_invar_1vn"; |
77 |
77 |
78 (*The intersection is an invariant of the system*) |
78 (*The intersection is an invariant of the system*) |
79 goal thy "reachable MInit mutex <= invariant 0 UU MM Int invariant 1 VV NN"; |
79 Goal "reachable MInit mutex <= invariant 0 UU MM Int invariant 1 VV NN"; |
80 by (simp_tac (simpset() addsimps |
80 by (simp_tac (simpset() addsimps |
81 [strongest_invariant, Int_greatest, stable_Int, |
81 [strongest_invariant, Int_greatest, stable_Int, |
82 stable_invar_0um, stable_invar_1vn, |
82 stable_invar_0um, stable_invar_1vn, |
83 MInit_invar_0um,MInit_invar_1vn]) 1); |
83 MInit_invar_0um,MInit_invar_1vn]) 1); |
84 qed "reachable_subset_invariant"; |
84 qed "reachable_subset_invariant"; |
113 getgoal 1; |
113 getgoal 1; |
114 |
114 |
115 |
115 |
116 (*** Progress for U ***) |
116 (*** Progress for U ***) |
117 |
117 |
118 goalw thy [unless_def] "unless mutex {s. s MM=2} {s. s MM=3}"; |
118 Goalw [unless_def] "unless mutex {s. s MM=2} {s. s MM=3}"; |
119 by (constrains_tac 1); |
119 by (constrains_tac 1); |
120 qed "U_F0"; |
120 qed "U_F0"; |
121 |
121 |
122 goal thy "LeadsTo MInit mutex {s. s MM=1} {s. s PP = s VV & s MM = 2}"; |
122 Goal "LeadsTo MInit mutex {s. s MM=1} {s. s PP = s VV & s MM = 2}"; |
123 by (rtac leadsTo_imp_LeadsTo 1); (*makes the proof much faster*) |
123 by (rtac leadsTo_imp_LeadsTo 1); (*makes the proof much faster*) |
124 by (ensures_tac "cmd1u" 1); |
124 by (ensures_tac "cmd1u" 1); |
125 qed "U_F1"; |
125 qed "U_F1"; |
126 |
126 |
127 goal thy "LeadsTo MInit mutex {s. s PP = 0 & s MM = 2} {s. s MM = 3}"; |
127 Goal "LeadsTo MInit mutex {s. s PP = 0 & s MM = 2} {s. s MM = 3}"; |
128 by (cut_facts_tac [reachable_subset_invariant'] 1); |
128 by (cut_facts_tac [reachable_subset_invariant'] 1); |
129 by (ensures_tac "cmd2 0 MM" 1); |
129 by (ensures_tac "cmd2 0 MM" 1); |
130 qed "U_F2"; |
130 qed "U_F2"; |
131 |
131 |
132 goalw thy [mutex_def] "LeadsTo MInit mutex {s. s MM = 3} {s. s PP = 1}"; |
132 Goalw [mutex_def] "LeadsTo MInit mutex {s. s MM = 3} {s. s PP = 1}"; |
133 by (rtac leadsTo_imp_LeadsTo 1); |
133 by (rtac leadsTo_imp_LeadsTo 1); |
134 by (res_inst_tac [("B", "{s. s MM = 4}")] leadsTo_Trans 1); |
134 by (res_inst_tac [("B", "{s. s MM = 4}")] leadsTo_Trans 1); |
135 by (ensures_tac "cmd4 1 MM" 2); |
135 by (ensures_tac "cmd4 1 MM" 2); |
136 by (ensures_tac "cmd3 UU MM" 1); |
136 by (ensures_tac "cmd3 UU MM" 1); |
137 qed "U_F3"; |
137 qed "U_F3"; |
138 |
138 |
139 goal thy "LeadsTo MInit mutex {s. s MM = 2} {s. s PP = 1}"; |
139 Goal "LeadsTo MInit mutex {s. s MM = 2} {s. s PP = 1}"; |
140 by (rtac ([LeadsTo_weaken_L, subset_refl RS subset_imp_LeadsTo] |
140 by (rtac ([LeadsTo_weaken_L, subset_refl RS subset_imp_LeadsTo] |
141 MRS LeadsTo_Diff) 1); |
141 MRS LeadsTo_Diff) 1); |
142 by (rtac ([U_F2, U_F3] MRS LeadsTo_Trans) 1); |
142 by (rtac ([U_F2, U_F3] MRS LeadsTo_Trans) 1); |
143 by (cut_facts_tac [reachable_subset_boolVars'] 1); |
143 by (cut_facts_tac [reachable_subset_boolVars'] 1); |
144 by (auto_tac (claset() addSEs [less_SucE], simpset())); |
144 by (auto_tac (claset() addSEs [less_SucE], simpset())); |
145 val lemma2 = result(); |
145 val lemma2 = result(); |
146 |
146 |
147 goal thy "LeadsTo MInit mutex {s. s MM = 1} {s. s PP = 1}"; |
147 Goal "LeadsTo MInit mutex {s. s MM = 1} {s. s PP = 1}"; |
148 by (rtac ([U_F1 RS LeadsTo_weaken_R, lemma2] MRS LeadsTo_Trans) 1); |
148 by (rtac ([U_F1 RS LeadsTo_weaken_R, lemma2] MRS LeadsTo_Trans) 1); |
149 by (Blast_tac 1); |
149 by (Blast_tac 1); |
150 val lemma1 = result(); |
150 val lemma1 = result(); |
151 |
151 |
152 |
152 |
153 goal thy "LeadsTo MInit mutex {s. 1 <= s MM & s MM <= 3} {s. s PP = 1}"; |
153 Goal "LeadsTo MInit mutex {s. 1 <= s MM & s MM <= 3} {s. s PP = 1}"; |
154 by (simp_tac (simpset() addsimps [le_Suc_eq, conj_disj_distribL] |
154 by (simp_tac (simpset() addsimps [le_Suc_eq, conj_disj_distribL] |
155 addcongs [rev_conj_cong]) 1); |
155 addcongs [rev_conj_cong]) 1); |
156 by (simp_tac (simpset() addsimps [Collect_disj_eq, LeadsTo_Un_distrib, |
156 by (simp_tac (simpset() addsimps [Collect_disj_eq, LeadsTo_Un_distrib, |
157 lemma1, lemma2, U_F3] ) 1); |
157 lemma1, lemma2, U_F3] ) 1); |
158 val lemma123 = result(); |
158 val lemma123 = result(); |
159 |
159 |
160 |
160 |
161 (*Misra's F4*) |
161 (*Misra's F4*) |
162 goal thy "LeadsTo MInit mutex {s. s UU = 1} {s. s PP = 1}"; |
162 Goal "LeadsTo MInit mutex {s. s UU = 1} {s. s PP = 1}"; |
163 by (rtac LeadsTo_weaken_L 1); |
163 by (rtac LeadsTo_weaken_L 1); |
164 by (rtac lemma123 1); |
164 by (rtac lemma123 1); |
165 by (cut_facts_tac [reachable_subset_invariant'] 1); |
165 by (cut_facts_tac [reachable_subset_invariant'] 1); |
166 by Auto_tac; |
166 by Auto_tac; |
167 qed "u_leadsto_p"; |
167 qed "u_leadsto_p"; |
168 |
168 |
169 |
169 |
170 (*** Progress for V ***) |
170 (*** Progress for V ***) |
171 |
171 |
172 |
172 |
173 goalw thy [unless_def] "unless mutex {s. s NN=2} {s. s NN=3}"; |
173 Goalw [unless_def] "unless mutex {s. s NN=2} {s. s NN=3}"; |
174 by (constrains_tac 1); |
174 by (constrains_tac 1); |
175 qed "V_F0"; |
175 qed "V_F0"; |
176 |
176 |
177 goal thy "LeadsTo MInit mutex {s. s NN=1} {s. s PP = 1 - s UU & s NN = 2}"; |
177 Goal "LeadsTo MInit mutex {s. s NN=1} {s. s PP = 1 - s UU & s NN = 2}"; |
178 by (rtac leadsTo_imp_LeadsTo 1); (*makes the proof much faster*) |
178 by (rtac leadsTo_imp_LeadsTo 1); (*makes the proof much faster*) |
179 by (ensures_tac "cmd1v" 1); |
179 by (ensures_tac "cmd1v" 1); |
180 qed "V_F1"; |
180 qed "V_F1"; |
181 |
181 |
182 goal thy "LeadsTo MInit mutex {s. s PP = 1 & s NN = 2} {s. s NN = 3}"; |
182 Goal "LeadsTo MInit mutex {s. s PP = 1 & s NN = 2} {s. s NN = 3}"; |
183 by (cut_facts_tac [reachable_subset_invariant'] 1); |
183 by (cut_facts_tac [reachable_subset_invariant'] 1); |
184 by (ensures_tac "cmd2 1 NN" 1); |
184 by (ensures_tac "cmd2 1 NN" 1); |
185 qed "V_F2"; |
185 qed "V_F2"; |
186 |
186 |
187 goalw thy [mutex_def] "LeadsTo MInit mutex {s. s NN = 3} {s. s PP = 0}"; |
187 Goalw [mutex_def] "LeadsTo MInit mutex {s. s NN = 3} {s. s PP = 0}"; |
188 by (rtac leadsTo_imp_LeadsTo 1); |
188 by (rtac leadsTo_imp_LeadsTo 1); |
189 by (res_inst_tac [("B", "{s. s NN = 4}")] leadsTo_Trans 1); |
189 by (res_inst_tac [("B", "{s. s NN = 4}")] leadsTo_Trans 1); |
190 by (ensures_tac "cmd4 0 NN" 2); |
190 by (ensures_tac "cmd4 0 NN" 2); |
191 by (ensures_tac "cmd3 VV NN" 1); |
191 by (ensures_tac "cmd3 VV NN" 1); |
192 qed "V_F3"; |
192 qed "V_F3"; |
193 |
193 |
194 goal thy "LeadsTo MInit mutex {s. s NN = 2} {s. s PP = 0}"; |
194 Goal "LeadsTo MInit mutex {s. s NN = 2} {s. s PP = 0}"; |
195 by (rtac ([LeadsTo_weaken_L, subset_refl RS subset_imp_LeadsTo] |
195 by (rtac ([LeadsTo_weaken_L, subset_refl RS subset_imp_LeadsTo] |
196 MRS LeadsTo_Diff) 1); |
196 MRS LeadsTo_Diff) 1); |
197 by (rtac ([V_F2, V_F3] MRS LeadsTo_Trans) 1); |
197 by (rtac ([V_F2, V_F3] MRS LeadsTo_Trans) 1); |
198 by (cut_facts_tac [reachable_subset_boolVars'] 1); |
198 by (cut_facts_tac [reachable_subset_boolVars'] 1); |
199 by (auto_tac (claset() addSEs [less_SucE], simpset())); |
199 by (auto_tac (claset() addSEs [less_SucE], simpset())); |
200 val lemma2 = result(); |
200 val lemma2 = result(); |
201 |
201 |
202 goal thy "LeadsTo MInit mutex {s. s NN = 1} {s. s PP = 0}"; |
202 Goal "LeadsTo MInit mutex {s. s NN = 1} {s. s PP = 0}"; |
203 by (rtac ([V_F1 RS LeadsTo_weaken_R, lemma2] MRS LeadsTo_Trans) 1); |
203 by (rtac ([V_F1 RS LeadsTo_weaken_R, lemma2] MRS LeadsTo_Trans) 1); |
204 by (Blast_tac 1); |
204 by (Blast_tac 1); |
205 val lemma1 = result(); |
205 val lemma1 = result(); |
206 |
206 |
207 |
207 |
208 goal thy "LeadsTo MInit mutex {s. 1 <= s NN & s NN <= 3} {s. s PP = 0}"; |
208 Goal "LeadsTo MInit mutex {s. 1 <= s NN & s NN <= 3} {s. s PP = 0}"; |
209 by (simp_tac (simpset() addsimps [le_Suc_eq, conj_disj_distribL] |
209 by (simp_tac (simpset() addsimps [le_Suc_eq, conj_disj_distribL] |
210 addcongs [rev_conj_cong]) 1); |
210 addcongs [rev_conj_cong]) 1); |
211 by (simp_tac (simpset() addsimps [Collect_disj_eq, LeadsTo_Un_distrib, |
211 by (simp_tac (simpset() addsimps [Collect_disj_eq, LeadsTo_Un_distrib, |
212 lemma1, lemma2, V_F3] ) 1); |
212 lemma1, lemma2, V_F3] ) 1); |
213 val lemma123 = result(); |
213 val lemma123 = result(); |
214 |
214 |
215 |
215 |
216 (*Misra's F4*) |
216 (*Misra's F4*) |
217 goal thy "LeadsTo MInit mutex {s. s VV = 1} {s. s PP = 0}"; |
217 Goal "LeadsTo MInit mutex {s. s VV = 1} {s. s PP = 0}"; |
218 by (rtac LeadsTo_weaken_L 1); |
218 by (rtac LeadsTo_weaken_L 1); |
219 by (rtac lemma123 1); |
219 by (rtac lemma123 1); |
220 by (cut_facts_tac [reachable_subset_invariant'] 1); |
220 by (cut_facts_tac [reachable_subset_invariant'] 1); |
221 by Auto_tac; |
221 by Auto_tac; |
222 qed "v_leadsto_not_p"; |
222 qed "v_leadsto_not_p"; |
223 |
223 |
224 |
224 |
225 (** Absence of starvation **) |
225 (** Absence of starvation **) |
226 |
226 |
227 (*Misra's F6*) |
227 (*Misra's F6*) |
228 goal thy "LeadsTo MInit mutex {s. s MM = 1} {s. s MM = 3}"; |
228 Goal "LeadsTo MInit mutex {s. s MM = 1} {s. s MM = 3}"; |
229 by (rtac LeadsTo_Un_duplicate 1); |
229 by (rtac LeadsTo_Un_duplicate 1); |
230 by (rtac LeadsTo_cancel2 1); |
230 by (rtac LeadsTo_cancel2 1); |
231 by (rtac U_F2 2); |
231 by (rtac U_F2 2); |
232 by (simp_tac (simpset() addsimps [Collect_conj_eq] ) 1); |
232 by (simp_tac (simpset() addsimps [Collect_conj_eq] ) 1); |
233 by (stac Un_commute 1); |
233 by (stac Un_commute 1); |