28 |
28 |
29 |
29 |
30 Addsimps [invariantU_def, invariantV_def]; |
30 Addsimps [invariantU_def, invariantV_def]; |
31 |
31 |
32 |
32 |
33 Goalw [MInit_def] "invariant (MInit,mutex) invariantU"; |
33 Goalw [Mprg_def] "invariant Mprg invariantU"; |
34 by (rtac invariantI 1); |
34 by (rtac invariantI 1); |
35 by (constrains_tac cmd_defs 2); |
35 by (constrains_tac cmd_defs 2); |
36 by Auto_tac; |
36 by Auto_tac; |
37 qed "invariantU"; |
37 qed "invariantU"; |
38 |
38 |
39 Goalw [MInit_def] "invariant (MInit,mutex) invariantV"; |
39 Goalw [Mprg_def] "invariant Mprg invariantV"; |
40 by (rtac invariantI 1); |
40 by (rtac invariantI 1); |
41 by (constrains_tac cmd_defs 2); |
41 by (constrains_tac cmd_defs 2); |
42 by Auto_tac; |
42 by Auto_tac; |
43 qed "invariantV"; |
43 qed "invariantV"; |
44 |
44 |
45 val mutex_invariant = invariant_Int_rule [invariantU, invariantV]; |
45 val invariantUV = invariant_Int_rule [invariantU, invariantV]; |
46 |
46 |
47 |
47 |
48 (*The safety property: mutual exclusion*) |
48 (*The safety property: mutual exclusion*) |
49 Goal "disjoint (reachable (MInit,mutex)) {s. MM s = 3 & NN s = 3}"; |
49 Goal "(reachable Mprg) Int {s. MM s = 3 & NN s = 3} = {}"; |
50 by (cut_facts_tac [mutex_invariant RS invariant_includes_reachable] 1); |
50 by (cut_facts_tac [invariantUV RS invariant_includes_reachable] 1); |
51 by Auto_tac; |
51 by Auto_tac; |
52 qed "mutual_exclusion"; |
52 qed "mutual_exclusion"; |
53 |
53 |
54 |
54 |
55 (*The bad invariant FAILS in cmd1V*) |
55 (*The bad invariant FAILS in cmd1V*) |
56 Goalw [bad_invariantU_def] "stable mutex bad_invariantU"; |
56 Goalw [bad_invariantU_def] "stable (Acts Mprg) bad_invariantU"; |
57 by (constrains_tac cmd_defs 1); |
57 by (constrains_tac cmd_defs 1); |
58 by (REPEAT (trans_tac 1)); |
58 by (REPEAT (trans_tac 1)); |
59 by (safe_tac (claset() addSEs [le_SucE])); |
59 by (safe_tac (claset() addSEs [le_SucE])); |
60 by (Asm_full_simp_tac 1); |
60 by (Asm_full_simp_tac 1); |
61 (*Resulting state: n=1, p=false, m=4, u=false. |
61 (*Resulting state: n=1, p=false, m=4, u=false. |
65 getgoal 1; |
65 getgoal 1; |
66 |
66 |
67 |
67 |
68 (*** Progress for U ***) |
68 (*** Progress for U ***) |
69 |
69 |
70 Goalw [unless_def] "unless mutex {s. MM s=2} {s. MM s=3}"; |
70 Goalw [unless_def] "unless (Acts Mprg) {s. MM s=2} {s. MM s=3}"; |
71 by (constrains_tac cmd_defs 1); |
71 by (constrains_tac cmd_defs 1); |
72 qed "U_F0"; |
72 qed "U_F0"; |
73 |
73 |
74 Goal "LeadsTo(MInit,mutex) {s. MM s=1} {s. PP s = VV s & MM s = 2}"; |
74 Goal "LeadsTo Mprg {s. MM s=1} {s. PP s = VV s & MM s = 2}"; |
75 by (ensures_tac cmd_defs "cmd1U" 1); |
75 by (ensures_tac cmd_defs "cmd1U" 1); |
76 qed "U_F1"; |
76 qed "U_F1"; |
77 |
77 |
78 Goal "LeadsTo(MInit,mutex) {s. ~ PP s & MM s = 2} {s. MM s = 3}"; |
78 Goal "LeadsTo Mprg {s. ~ PP s & MM s = 2} {s. MM s = 3}"; |
79 by (cut_facts_tac [mutex_invariant] 1); |
79 by (cut_facts_tac [invariantUV] 1); |
|
80 bw Mprg_def; |
80 by (ensures_tac cmd_defs "cmd2U" 1); |
81 by (ensures_tac cmd_defs "cmd2U" 1); |
81 qed "U_F2"; |
82 qed "U_F2"; |
82 |
83 |
83 Goalw [mutex_def] "LeadsTo(MInit,mutex) {s. MM s = 3} {s. PP s}"; |
84 Goal "LeadsTo Mprg {s. MM s = 3} {s. PP s}"; |
84 by (rtac leadsTo_imp_LeadsTo 1); |
85 by (rtac leadsTo_imp_LeadsTo 1); |
85 by (res_inst_tac [("B", "{s. MM s = 4}")] leadsTo_Trans 1); |
86 by (res_inst_tac [("B", "{s. MM s = 4}")] leadsTo_Trans 1); |
86 by (ensures_tac cmd_defs "cmd4U" 2); |
87 by (ensures_tac cmd_defs "cmd4U" 2); |
87 by (ensures_tac cmd_defs "cmd3U" 1); |
88 by (ensures_tac cmd_defs "cmd3U" 1); |
88 qed "U_F3"; |
89 qed "U_F3"; |
89 |
90 |
90 Goal "LeadsTo(MInit,mutex) {s. MM s = 2} {s. PP s}"; |
91 Goal "LeadsTo Mprg {s. MM s = 2} {s. PP s}"; |
91 by (rtac ([LeadsTo_weaken_L, subset_refl RS subset_imp_LeadsTo] |
92 by (rtac ([LeadsTo_weaken_L, subset_refl RS subset_imp_LeadsTo] |
92 MRS LeadsTo_Diff) 1); |
93 MRS LeadsTo_Diff) 1); |
93 by (rtac ([U_F2, U_F3] MRS LeadsTo_Trans) 1); |
94 by (rtac ([U_F2, U_F3] MRS LeadsTo_Trans) 1); |
94 by (auto_tac (claset() addSEs [less_SucE], simpset())); |
95 by (auto_tac (claset() addSEs [less_SucE], simpset())); |
95 val U_lemma2 = result(); |
96 val U_lemma2 = result(); |
96 |
97 |
97 Goal "LeadsTo(MInit,mutex) {s. MM s = 1} {s. PP s}"; |
98 Goal "LeadsTo Mprg {s. MM s = 1} {s. PP s}"; |
98 by (rtac ([U_F1 RS LeadsTo_weaken_R, U_lemma2] MRS LeadsTo_Trans) 1); |
99 by (rtac ([U_F1 RS LeadsTo_weaken_R, U_lemma2] MRS LeadsTo_Trans) 1); |
99 by (Blast_tac 1); |
100 by (Blast_tac 1); |
100 val U_lemma1 = result(); |
101 val U_lemma1 = result(); |
101 |
102 |
102 |
103 Goal "LeadsTo Mprg {s. 1 <= MM s & MM s <= 3} {s. PP s}"; |
103 Goal "LeadsTo(MInit,mutex) {s. 1 <= MM s & MM s <= 3} {s. PP s}"; |
|
104 by (simp_tac (simpset() addsimps [le_Suc_eq, conj_disj_distribL] |
104 by (simp_tac (simpset() addsimps [le_Suc_eq, conj_disj_distribL] |
105 addcongs [rev_conj_cong]) 1); |
105 addcongs [rev_conj_cong]) 1); |
106 by (simp_tac (simpset() addsimps [Collect_disj_eq, LeadsTo_Un_distrib, |
106 by (simp_tac (simpset() addsimps [Collect_disj_eq, LeadsTo_Un_distrib, |
107 U_lemma1, U_lemma2, U_F3] ) 1); |
107 U_lemma1, U_lemma2, U_F3] ) 1); |
108 val U_lemma123 = result(); |
108 val U_lemma123 = result(); |
109 |
109 |
110 |
|
111 (*Misra's F4*) |
110 (*Misra's F4*) |
112 Goal "LeadsTo(MInit,mutex) {s. UU s} {s. PP s}"; |
111 Goal "LeadsTo Mprg {s. UU s} {s. PP s}"; |
113 by (rtac ([invariantU, U_lemma123] MRS invariant_LeadsTo_weaken) 1); |
112 by (rtac ([invariantU, U_lemma123] MRS invariant_LeadsTo_weaken) 1); |
114 by Auto_tac; |
113 by Auto_tac; |
115 qed "u_leadsto_p"; |
114 qed "u_leadsto_p"; |
116 |
115 |
117 |
116 |
118 (*** Progress for V ***) |
117 (*** Progress for V ***) |
119 |
118 |
120 |
119 |
121 Goalw [unless_def] "unless mutex {s. NN s=2} {s. NN s=3}"; |
120 Goalw [unless_def] "unless (Acts Mprg) {s. NN s=2} {s. NN s=3}"; |
122 by (constrains_tac cmd_defs 1); |
121 by (constrains_tac cmd_defs 1); |
123 qed "V_F0"; |
122 qed "V_F0"; |
124 |
123 |
125 Goal "LeadsTo(MInit,mutex) {s. NN s=1} {s. PP s = (~ UU s) & NN s = 2}"; |
124 Goal "LeadsTo Mprg {s. NN s=1} {s. PP s = (~ UU s) & NN s = 2}"; |
126 by (ensures_tac cmd_defs "cmd1V" 1); |
125 by (ensures_tac cmd_defs "cmd1V" 1); |
127 qed "V_F1"; |
126 qed "V_F1"; |
128 |
127 |
129 Goal "LeadsTo(MInit,mutex) {s. PP s & NN s = 2} {s. NN s = 3}"; |
128 Goal "LeadsTo Mprg {s. PP s & NN s = 2} {s. NN s = 3}"; |
130 by (cut_facts_tac [mutex_invariant] 1); |
129 by (cut_facts_tac [invariantUV] 1); |
131 by (ensures_tac cmd_defs "cmd2V" 1); |
130 by (ensures_tac cmd_defs "cmd2V" 1); |
132 qed "V_F2"; |
131 qed "V_F2"; |
133 |
132 |
134 Goalw [mutex_def] "LeadsTo(MInit,mutex) {s. NN s = 3} {s. ~ PP s}"; |
133 Goal "LeadsTo Mprg {s. NN s = 3} {s. ~ PP s}"; |
135 by (rtac leadsTo_imp_LeadsTo 1); |
134 by (rtac leadsTo_imp_LeadsTo 1); |
136 by (res_inst_tac [("B", "{s. NN s = 4}")] leadsTo_Trans 1); |
135 by (res_inst_tac [("B", "{s. NN s = 4}")] leadsTo_Trans 1); |
137 by (ensures_tac cmd_defs "cmd4V" 2); |
136 by (ensures_tac cmd_defs "cmd4V" 2); |
138 by (ensures_tac cmd_defs "cmd3V" 1); |
137 by (ensures_tac cmd_defs "cmd3V" 1); |
139 qed "V_F3"; |
138 qed "V_F3"; |
140 |
139 |
141 Goal "LeadsTo(MInit,mutex) {s. NN s = 2} {s. ~ PP s}"; |
140 Goal "LeadsTo Mprg {s. NN s = 2} {s. ~ PP s}"; |
142 by (rtac ([LeadsTo_weaken_L, subset_refl RS subset_imp_LeadsTo] |
141 by (rtac ([LeadsTo_weaken_L, subset_refl RS subset_imp_LeadsTo] |
143 MRS LeadsTo_Diff) 1); |
142 MRS LeadsTo_Diff) 1); |
144 by (rtac ([V_F2, V_F3] MRS LeadsTo_Trans) 1); |
143 by (rtac ([V_F2, V_F3] MRS LeadsTo_Trans) 1); |
145 by (auto_tac (claset() addSEs [less_SucE], simpset())); |
144 by (auto_tac (claset() addSEs [less_SucE], simpset())); |
146 val V_lemma2 = result(); |
145 val V_lemma2 = result(); |
147 |
146 |
148 Goal "LeadsTo(MInit,mutex) {s. NN s = 1} {s. ~ PP s}"; |
147 Goal "LeadsTo Mprg {s. NN s = 1} {s. ~ PP s}"; |
149 by (rtac ([V_F1 RS LeadsTo_weaken_R, V_lemma2] MRS LeadsTo_Trans) 1); |
148 by (rtac ([V_F1 RS LeadsTo_weaken_R, V_lemma2] MRS LeadsTo_Trans) 1); |
150 by (Blast_tac 1); |
149 by (Blast_tac 1); |
151 val V_lemma1 = result(); |
150 val V_lemma1 = result(); |
152 |
151 |
153 Goal "LeadsTo(MInit,mutex) {s. 1 <= NN s & NN s <= 3} {s. ~ PP s}"; |
152 Goal "LeadsTo Mprg {s. 1 <= NN s & NN s <= 3} {s. ~ PP s}"; |
154 by (simp_tac (simpset() addsimps [le_Suc_eq, conj_disj_distribL] |
153 by (simp_tac (simpset() addsimps [le_Suc_eq, conj_disj_distribL] |
155 addcongs [rev_conj_cong]) 1); |
154 addcongs [rev_conj_cong]) 1); |
156 by (simp_tac (simpset() addsimps [Collect_disj_eq, LeadsTo_Un_distrib, |
155 by (simp_tac (simpset() addsimps [Collect_disj_eq, LeadsTo_Un_distrib, |
157 V_lemma1, V_lemma2, V_F3] ) 1); |
156 V_lemma1, V_lemma2, V_F3] ) 1); |
158 val V_lemma123 = result(); |
157 val V_lemma123 = result(); |
159 |
158 |
160 |
159 |
161 (*Misra's F4*) |
160 (*Misra's F4*) |
162 Goal "LeadsTo(MInit,mutex) {s. VV s} {s. ~ PP s}"; |
161 Goal "LeadsTo Mprg {s. VV s} {s. ~ PP s}"; |
163 by (rtac ([invariantV, V_lemma123] MRS invariant_LeadsTo_weaken) 1); |
162 by (rtac ([invariantV, V_lemma123] MRS invariant_LeadsTo_weaken) 1); |
164 by Auto_tac; |
163 by Auto_tac; |
165 qed "v_leadsto_not_p"; |
164 qed "v_leadsto_not_p"; |
166 |
165 |
167 |
166 |
168 (** Absence of starvation **) |
167 (** Absence of starvation **) |
169 |
168 |
170 (*Misra's F6*) |
169 (*Misra's F6*) |
171 Goal "LeadsTo(MInit,mutex) {s. MM s = 1} {s. MM s = 3}"; |
170 Goal "LeadsTo Mprg {s. MM s = 1} {s. MM s = 3}"; |
172 by (rtac LeadsTo_Un_duplicate 1); |
171 by (rtac LeadsTo_Un_duplicate 1); |
173 by (rtac LeadsTo_cancel2 1); |
172 by (rtac LeadsTo_cancel2 1); |
174 by (rtac U_F2 2); |
173 by (rtac U_F2 2); |
175 by (simp_tac (simpset() addsimps [Collect_conj_eq] ) 1); |
174 by (simp_tac (simpset() addsimps [Collect_conj_eq] ) 1); |
176 by (stac Un_commute 1); |
175 by (stac Un_commute 1); |