
wenzelm@37936: (*  Title:      HOL/UNITY/Simple/Token.thy
paulson@11195:     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
paulson@11195:     Copyright   1998  University of Cambridge
paulson@11195: *)
paulson@11195: 
paulson@11195: 
wenzelm@58889: section {*The Token Ring*}
paulson@15618: 
paulson@15618: theory Token
paulson@15618: imports "../WFair"
paulson@15618: 
paulson@15618: begin
paulson@11195: 
paulson@15618: text{*From Misra, "A Logic for Concurrent Programming" (1994), sections 5.2 and 13.2.*}
paulson@15618: 
paulson@15618: subsection{*Definitions*}
paulson@15618: 
blanchet@58310: datatype pstate = Hungry | Eating | Thinking
paulson@15618:     --{*process states*}
paulson@11195: 
paulson@11195: record state =
paulson@13785:   token :: "nat"
paulson@13785:   proc  :: "nat => pstate"
paulson@11195: 
paulson@11195: 
haftmann@35416: definition HasTok :: "nat => state set" where
paulson@11195:     "HasTok i == {s. token s = i}"
paulson@11195: 
haftmann@35416: definition H :: "nat => state set" where
paulson@11195:     "H i == {s. proc s i = Hungry}"
paulson@11195: 
haftmann@35416: definition E :: "nat => state set" where
paulson@11195:     "E i == {s. proc s i = Eating}"
paulson@11195: 
haftmann@35416: definition T :: "nat => state set" where
paulson@11195:     "T i == {s. proc s i = Thinking}"
paulson@11195: 
paulson@11195: 
paulson@11195: locale Token =
paulson@13785:   fixes N and F and nodeOrder and "next"   
paulson@13785:   defines nodeOrder_def:
paulson@15618:        "nodeOrder j == measure(%i. ((j+N)-i) mod N) \<inter> {..<N} \<times> {..<N}"
paulson@13785:       and next_def:
paulson@13785:        "next i == (Suc i) mod N"
paulson@13785:   assumes N_positive [iff]: "0<N"
paulson@13806:       and TR2:  "F \<in> (T i) co (T i \<union> H i)"
paulson@13806:       and TR3:  "F \<in> (H i) co (H i \<union> E i)"
paulson@13806:       and TR4:  "F \<in> (H i - HasTok i) co (H i)"
paulson@13806:       and TR5:  "F \<in> (HasTok i) co (HasTok i \<union> -(E i))"
paulson@13806:       and TR6:  "F \<in> (H i \<inter> HasTok i) leadsTo (E i)"
paulson@13806:       and TR7:  "F \<in> (HasTok i) leadsTo (HasTok (next i))"
paulson@13785: 
paulson@13785: 
paulson@13806: lemma HasToK_partition: "[| s \<in> HasTok i; s \<in> HasTok j |] ==> i=j"
paulson@13785: by (unfold HasTok_def, auto)
paulson@11195: 
paulson@13806: lemma not_E_eq: "(s \<notin> E i) = (s \<in> H i | s \<in> T i)"
paulson@13785: apply (simp add: H_def E_def T_def)
wenzelm@46911: apply (cases "proc s i", auto)
paulson@13785: done
paulson@11195: 
wenzelm@46912: context Token
wenzelm@46912: begin
wenzelm@46912: 
wenzelm@46912: lemma token_stable: "F \<in> stable (-(E i) \<union> (HasTok i))"
paulson@13785: apply (unfold stable_def)
paulson@13785: apply (rule constrains_weaken)
paulson@13785: apply (rule constrains_Un [OF constrains_Un [OF TR2 TR4] TR5])
paulson@13785: apply (auto simp add: not_E_eq)
paulson@13785: apply (simp_all add: H_def E_def T_def)
paulson@13785: done
paulson@11195: 
paulson@13785: 
paulson@15618: subsection{*Progress under Weak Fairness*}
paulson@13785: 
wenzelm@46912: lemma wf_nodeOrder: "wf(nodeOrder j)"
paulson@13785: apply (unfold nodeOrder_def)
paulson@15618: apply (rule wf_measure [THEN wf_subset], blast)
paulson@13785: done
paulson@11195: 
wenzelm@46912: lemma nodeOrder_eq: 
paulson@13806:      "[| i<N; j<N |] ==> ((next i, i) \<in> nodeOrder j) = (i \<noteq> j)"
krauss@19769: apply (unfold nodeOrder_def next_def)
paulson@13785: apply (auto simp add: mod_Suc mod_geq)
paulson@13785: apply (auto split add: nat_diff_split simp add: linorder_neq_iff mod_geq)
paulson@13785: done
paulson@11195: 
paulson@15618: text{*From "A Logic for Concurrent Programming", but not used in Chapter 4.
wenzelm@46911:   Note the use of @{text cases}.  Reasoning about leadsTo takes practice!*}
wenzelm@46912: lemma TR7_nodeOrder:
paulson@13785:      "[| i<N; j<N |] ==>    
paulson@13806:       F \<in> (HasTok i) leadsTo ({s. (token s, i) \<in> nodeOrder j} \<union> HasTok j)"
wenzelm@46911: apply (cases "i=j")
paulson@13785: apply (blast intro: subset_imp_leadsTo)
paulson@13785: apply (rule TR7 [THEN leadsTo_weaken_R])
paulson@13785: apply (auto simp add: HasTok_def nodeOrder_eq)
paulson@13785: done
paulson@11195: 
paulson@13785: 
paulson@15618: text{*Chapter 4 variant, the one actually used below.*}
wenzelm@46912: lemma TR7_aux: "[| i<N; j<N; i\<noteq>j |]     
paulson@13806:       ==> F \<in> (HasTok i) leadsTo {s. (token s, i) \<in> nodeOrder j}"
paulson@13785: apply (rule TR7 [THEN leadsTo_weaken_R])
paulson@13785: apply (auto simp add: HasTok_def nodeOrder_eq)
paulson@13785: done
paulson@11195: 
wenzelm@46912: lemma token_lemma:
paulson@13806:      "({s. token s < N} \<inter> token -` {m}) = (if m<N then token -` {m} else {})"
paulson@13785: by auto
paulson@13785: 
paulson@11195: 
paulson@15618: text{*Misra's TR9: the token reaches an arbitrary node*}
wenzelm@46912: lemma leadsTo_j: "j<N ==> F \<in> {s. token s < N} leadsTo (HasTok j)"
paulson@13785: apply (rule leadsTo_weaken_R)
paulson@13785: apply (rule_tac I = "-{j}" and f = token and B = "{}" 
paulson@13785:        in wf_nodeOrder [THEN bounded_induct])
paulson@13785: apply (simp_all (no_asm_simp) add: token_lemma vimage_Diff HasTok_def)
paulson@13785:  prefer 2 apply blast
paulson@13785: apply clarify
paulson@13785: apply (rule TR7_aux [THEN leadsTo_weaken])
paulson@13785: apply (auto simp add: HasTok_def nodeOrder_def)
paulson@13785: done
paulson@13785: 
paulson@15618: text{*Misra's TR8: a hungry process eventually eats*}
wenzelm@46912: lemma token_progress:
paulson@13806:      "j<N ==> F \<in> ({s. token s < N} \<inter> H j) leadsTo (E j)"
paulson@13785: apply (rule leadsTo_cancel1 [THEN leadsTo_Un_duplicate])
paulson@13785: apply (rule_tac [2] TR6)
paulson@13785: apply (rule psp [OF leadsTo_j TR3, THEN leadsTo_weaken], blast+)
paulson@13785: done
paulson@13785: 
wenzelm@46912: end
paulson@11195: 
paulson@11195: end




