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) \ {.. {.. (T i) co (T i \ H i)" paulson@13806: and TR3: "F \ (H i) co (H i \ E i)" paulson@13806: and TR4: "F \ (H i - HasTok i) co (H i)" paulson@13806: and TR5: "F \ (HasTok i) co (HasTok i \ -(E i))" paulson@13806: and TR6: "F \ (H i \ HasTok i) leadsTo (E i)" paulson@13806: and TR7: "F \ (HasTok i) leadsTo (HasTok (next i))" paulson@13785: paulson@13785: paulson@13806: lemma HasToK_partition: "[| s \ HasTok i; s \ HasTok j |] ==> i=j" paulson@13785: by (unfold HasTok_def, auto) paulson@11195: paulson@13806: lemma not_E_eq: "(s \ E i) = (s \ H i | s \ 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 \ stable (-(E i) \ (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 ((next i, i) \ nodeOrder j) = (i \ 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 paulson@13806: F \ (HasTok i) leadsTo ({s. (token s, i) \ nodeOrder j} \ 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: "[| ij |] paulson@13806: ==> F \ (HasTok i) leadsTo {s. (token s, i) \ 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} \ token -` {m}) = (if m F \ {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 F \ ({s. token s < N} \ 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