src/HOL/UNITY/Mutex.ML
changeset 5069 3ea049f7979d
parent 4776 1f9362e769c1
child 5111 8f4b72f0c15d
equal deleted inserted replaced
5068:fb28eaa07e01 5069:3ea049f7979d
     9 open Mutex;
     9 open Mutex;
    10 
    10 
    11 val cmd_defs = [mutex_def, cmd0_def, cmd1u_def, cmd1v_def, 
    11 val cmd_defs = [mutex_def, cmd0_def, cmd1u_def, cmd1v_def, 
    12 		cmd2_def, cmd3_def, cmd4_def];
    12 		cmd2_def, cmd3_def, cmd4_def];
    13 
    13 
    14 goalw thy [mutex_def] "id : mutex";
    14 Goalw [mutex_def] "id : mutex";
    15 by (Simp_tac 1);
    15 by (Simp_tac 1);
    16 qed "id_in_mutex";
    16 qed "id_in_mutex";
    17 AddIffs [id_in_mutex];
    17 AddIffs [id_in_mutex];
    18 
    18 
    19 
    19 
    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";
    86 val reachable_subset_invariant' = 
    86 val reachable_subset_invariant' = 
    87     rewrite_rule [invariant_def] reachable_subset_invariant;
    87     rewrite_rule [invariant_def] reachable_subset_invariant;
    88 
    88 
    89 
    89 
    90 (*The safety property (mutual exclusion) follows from the claimed invar_s*)
    90 (*The safety property (mutual exclusion) follows from the claimed invar_s*)
    91 goalw thy [invariant_def]
    91 Goalw [invariant_def]
    92     "{s. s MM = 3 & s NN = 3} <= \
    92     "{s. s MM = 3 & s NN = 3} <= \
    93 \    Compl (invariant 0 UU MM Int invariant 1 VV NN)";
    93 \    Compl (invariant 0 UU MM Int invariant 1 VV NN)";
    94 by Auto_tac;
    94 by Auto_tac;
    95 val lemma = result();
    95 val lemma = result();
    96 
    96 
    97 goal thy "{s. s MM = 3 & s NN = 3} <= Compl (reachable MInit mutex)";
    97 Goal "{s. s MM = 3 & s NN = 3} <= Compl (reachable MInit mutex)";
    98 by (rtac ([lemma, reachable_subset_invariant RS Compl_anti_mono] MRS subset_trans) 1);
    98 by (rtac ([lemma, reachable_subset_invariant RS Compl_anti_mono] MRS subset_trans) 1);
    99 qed "mutual_exclusion";
    99 qed "mutual_exclusion";
   100 
   100 
   101 
   101 
   102 (*The bad invariant FAILS in cmd1v*)
   102 (*The bad invariant FAILS in cmd1v*)
   103 goalw thy [stable_def, bad_invariant_def]
   103 Goalw [stable_def, bad_invariant_def]
   104     "stable mutex (bad_invariant 0 UU MM)";
   104     "stable mutex (bad_invariant 0 UU MM)";
   105 by (constrains_tac 1);
   105 by (constrains_tac 1);
   106 by (trans_tac 1);
   106 by (trans_tac 1);
   107 by (safe_tac (claset() addSEs [le_SucE]));
   107 by (safe_tac (claset() addSEs [le_SucE]));
   108 by (Asm_full_simp_tac 1);
   108 by (Asm_full_simp_tac 1);
   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);
   238 by (auto_tac (claset() addSEs [less_SucE], simpset()));
   238 by (auto_tac (claset() addSEs [less_SucE], simpset()));
   239 qed "m1_leadsto_3";
   239 qed "m1_leadsto_3";
   240 
   240 
   241 
   241 
   242 (*The same for V*)
   242 (*The same for V*)
   243 goal thy "LeadsTo MInit mutex {s. s NN = 1} {s. s NN = 3}";
   243 Goal "LeadsTo MInit mutex {s. s NN = 1} {s. s NN = 3}";
   244 by (rtac LeadsTo_Un_duplicate 1);
   244 by (rtac LeadsTo_Un_duplicate 1);
   245 by (rtac LeadsTo_cancel2 1);
   245 by (rtac LeadsTo_cancel2 1);
   246 by (rtac V_F2 2);
   246 by (rtac V_F2 2);
   247 by (simp_tac (simpset() addsimps [Collect_conj_eq] ) 1);
   247 by (simp_tac (simpset() addsimps [Collect_conj_eq] ) 1);
   248 by (stac Un_commute 1);
   248 by (stac Un_commute 1);