record'a clientState_d =
clientState +
dummy :: 'a \ \dummy field for new variables\
definition \<comment> \<open>DUPLICATED FROM Client.thy, but with "tok" removed\<close> \<comment> \<open>Maybe want a special theory section to declare such maps\<close>
non_dummy :: "'a clientState_d => clientState" where"non_dummy s = (|giv = giv s, ask = ask s, rel = rel s|)"
definition \<comment> \<open>Renaming map to put a Client into the standard form\<close>
client_map :: "'a clientState_d => clientState*'a" where"client_map = funPair non_dummy dummy"
record allocState =
allocGiv :: "nat => nat list"\<comment> \<open>OUTPUT history: source of "giv" for i\<close>
allocAsk :: "nat => nat list"\<comment> \<open>INPUT: allocator's copy of "ask" for i\<close>
allocRel :: "nat => nat list"\<comment> \<open>INPUT: allocator's copy of "rel" for i\<close>
record'a allocState_d =
allocState +
dummy :: 'a \ \dummy field for new variables\
record'a systemState =
allocState +
client :: "nat => clientState"\<comment> \<open>states of all clients\<close>
dummy :: 'a \ \dummy field for new variables\
subsubsection \<open>Resource allocation system specification\<close>
definition \<comment> \<open>spec (1)\<close>
system_safety :: "'a systemState program set" where"system_safety =
Always {s. (\<Sum>i \<in> lessThan Nclients. (tokens o giv o sub i o client)s) \<le> NbT + (\<Sum>i \<in> lessThan Nclients. (tokens o rel o sub i o client)s)}"
definition \<comment> \<open>spec (2)\<close>
system_progress :: "'a systemState program set" where"system_progress = (INT i : lessThan Nclients.
INT h.
{s. h \<le> (ask o sub i o client)s} LeadsTo
{s. h pfixLe (giv o sub i o client) s})"
definition
system_spec :: "'a systemState program set" where"system_spec = system_safety Int system_progress"
definition \<comment> \<open>spec (5)\<close>
client_progress :: "'a clientState_d program set" where"client_progress =
Increasing giv guarantees
(INT h. {s. h \<le> giv s & h pfixGe ask s}
LeadsTo {s. tokens h \<le> (tokens o rel) s})"
definition \<comment> \<open>spec: preserves part\<close>
client_preserves :: "'a clientState_d program set" where"client_preserves = preserves giv Int preserves clientState_d.dummy"
definition \<comment> \<open>environmental constraints\<close>
client_allowed_acts :: "'a clientState_d program set" where"client_allowed_acts =
{F. AllowedActs F =
insert Id (\<Union> (Acts ` preserves (funPair rel ask)))}"
definition
client_spec :: "'a clientState_d program set" where"client_spec = client_increasing Int client_bounded Int client_progress
Int client_allowed_acts Int client_preserves"
definition \<comment> \<open>spec (6)\<close>
alloc_increasing :: "'a allocState_d program set" where"alloc_increasing =
UNIV guarantees
(INT i : lessThan Nclients. Increasing (sub i o allocGiv))"
definition \<comment> \<open>spec (7)\<close>
alloc_safety :: "'a allocState_d program set" where"alloc_safety =
(INT i : lessThan Nclients. Increasing (sub i o allocRel))
guarantees
Always {s. (\<Sum>i \<in> lessThan Nclients. (tokens o sub i o allocGiv)s) \<le> NbT + (\<Sum>i \<in> lessThan Nclients. (tokens o sub i o allocRel)s)}"
definition \<comment> \<open>spec (8)\<close>
alloc_progress :: "'a allocState_d program set" where"alloc_progress =
(INT i : lessThan Nclients. Increasing (sub i o allocAsk) Int
Increasing (sub i o allocRel))
Int
Always {s. \<forall>i<Nclients. \<forall>elt \<in> set ((sub i o allocAsk) s). elt \<le> NbT}
Int
(INT i : lessThan Nclients.
INT h. {s. h \<le> (sub i o allocGiv)s & h pfixGe (sub i o allocAsk)s}
LeadsTo
{s. tokens h \<le> (tokens o sub i o allocRel)s})
guarantees
(INT i : lessThan Nclients.
INT h. {s. h \<le> (sub i o allocAsk) s}
LeadsTo
{s. h pfixLe (sub i o allocGiv) s})"
(*NOTE: to follow the original paper, the formula above should have had INT h. {s. h i \<le> (sub i o allocGiv)s & h i pfixGe (sub i o allocAsk)s} LeadsTo {s. tokens h i \<le> (tokens o sub i o allocRel)s}) thus h should have been a function variable. However, only h i is ever
looked at.*)
definition \<comment> \<open>spec: preserves part\<close>
alloc_preserves :: "'a allocState_d program set" where"alloc_preserves = preserves allocRel Int preserves allocAsk Int
preserves allocState_d.dummy"
definition \<comment> \<open>environmental constraints\<close>
alloc_allowed_acts :: "'a allocState_d program set" where"alloc_allowed_acts =
{F. AllowedActs F =
insert Id (\<Union>(Acts ` (preserves allocGiv)))}"
definition
alloc_spec :: "'a allocState_d program set" where"alloc_spec = alloc_increasing Int alloc_safety Int alloc_progress Int
alloc_allowed_acts Int alloc_preserves"
definition \<comment> \<open>spec (9.1)\<close>
network_ask :: "'a systemState program set" where"network_ask = (INT i : lessThan Nclients.
Increasing (ask o sub i o client) guarantees
((sub i o allocAsk) Fols (ask o sub i o client)))"
definition \<comment> \<open>spec (9.2)\<close>
network_giv :: "'a systemState program set" where"network_giv = (INT i : lessThan Nclients.
Increasing (sub i o allocGiv)
guarantees
((giv o sub i o client) Fols (sub i o allocGiv)))"
definition \<comment> \<open>spec (9.3)\<close>
network_rel :: "'a systemState program set" where"network_rel = (INT i : lessThan Nclients.
Increasing (rel o sub i o client)
guarantees
((sub i o allocRel) Fols (rel o sub i o client)))"
definition \<comment> \<open>spec: preserves part\<close>
network_preserves :: "'a systemState program set" where"network_preserves =
preserves allocGiv Int
(INT i : lessThan Nclients. preserves (rel o sub i o client) Int
preserves (ask o sub i o client))"
definition \<comment> \<open>environmental constraints\<close>
network_allowed_acts :: "'a systemState program set" where"network_allowed_acts =
{F. AllowedActs F = insert Id
(\<Union> (Acts ` (preserves allocRel \<inter> (\<Inter>i<Nclients.
preserves (giv \<circ> sub i \<circ> client)))))}"
definition
network_spec :: "'a systemState program set" where"network_spec = network_ask Int network_giv Int
network_rel Int network_allowed_acts Int
network_preserves"
subsubsection \<open>State mappings\<close>
definition
sysOfAlloc :: "((nat => clientState) * 'a) allocState_d => 'a systemState" where"sysOfAlloc = (%s. let (cl,xtr) = allocState_d.dummy s in (| allocGiv = allocGiv s,
allocAsk = allocAsk s,
allocRel = allocRel s,
client = cl,
dummy = xtr|))"
(** locale System = fixes Alloc :: 'a allocState_d program Client :: 'a clientState_d program Network :: 'a systemState program System :: 'a systemState program
ML \<open>ML_Thms.bind_thms ("allocRel_o_inv_sysOfAlloc_eq'", make_o_equivs \<^context> @{thm allocRel_o_inv_sysOfAlloc_eq})\<close> declare allocRel_o_inv_sysOfAlloc_eq' [simp]
lemma rel_inv_client_map_drop_map: "(rel o inv client_map o drop_map i o inv sysOfClient) =
rel o sub i o client" apply (simp add: o_def drop_map_def) done
ML \<open>ML_Thms.bind_thms ("rel_inv_client_map_drop_map'", make_o_equivs \<^context> @{thm rel_inv_client_map_drop_map})\<close> declare rel_inv_client_map_drop_map [simp]
lemma ask_inv_client_map_drop_map: "(ask o inv client_map o drop_map i o inv sysOfClient) =
ask o sub i o client" apply (simp add: o_def drop_map_def) done
ML \<open>ML_Thms.bind_thms ("ask_inv_client_map_drop_map'", make_o_equivs \<^context> @{thm ask_inv_client_map_drop_map})\<close> declare ask_inv_client_map_drop_map [simp]
text\<open>* These preservation laws should be generated automatically *\<close>
lemma Client_Allowed [simp]: "Allowed Client = preserves rel Int preserves ask" by (auto simp add: Allowed_def Client_AllowedActs safety_prop_Acts_iff)
lemma Network_Allowed [simp]: "Allowed Network =
preserves allocRel Int
(INT i: lessThan Nclients. preserves(giv o sub i o client))" by (auto simp add: Allowed_def Network_AllowedActs safety_prop_Acts_iff)
lemma fst_o_lift_map' [simp]: "(f \ sub i \ fst \ lift_map i \ g) = f o fst o g" apply (subst fst_o_lift_map [symmetric]) apply (simp only: o_assoc) done
(*The proofs of rename_Client_Increasing, rename_Client_Bounded and rename_Client_Progress are similar. All require copying out the original Client property. A forward proof can be constructed as follows:
text\<open>Lifting \<open>Client_Increasing\<close> to \<^term>\<open>systemState\<close>\<close> lemma rename_Client_Increasing: "i \ I
==> rename sysOfClient (plam x: I. rename client_map Client) \<in>
UNIV guarantees
Increasing (ask o sub i o client) Int
Increasing (rel o sub i o client)" by rename_client_map
lemma preserves_sub_fst_lift_map: "[| F \ preserves w; i \ j |]
==> F \<in> preserves (sub i o fst o lift_map j o funPair v w)" apply (auto simp add: lift_map_def split_def linorder_neq_iff o_def) apply (drule_tac [!] subset_preserves_o [THEN [2] rev_subsetD]) apply (auto simp add: o_def) done
lemma client_preserves_giv_oo_client_map: "[| i < Nclients; j < Nclients |]
==> Client \<in> preserves (giv o sub i o fst o lift_map j o client_map)" apply (cases "i=j") apply (simp, simp add: o_def non_dummy_def) apply (drule Client_preserves_dummy [THEN preserves_sub_fst_lift_map]) apply (drule_tac [!] subset_preserves_o [THEN [2] rev_subsetD]) apply (simp add: o_def client_map_def) done
lemma rename_sysOfClient_ok_Network: "rename sysOfClient (plam x: lessThan Nclients. rename client_map Client)
ok Network" by (auto simp add: ok_iff_Allowed client_preserves_giv_oo_client_map)
lemma rename_sysOfClient_ok_Alloc: "rename sysOfClient (plam x: lessThan Nclients. rename client_map Client)
ok rename sysOfAlloc Alloc" by (simp add: ok_iff_Allowed)
lemma rename_sysOfAlloc_ok_Network: "rename sysOfAlloc Alloc ok Network" by (simp add: ok_iff_Allowed)
text\<open>The "ok" laws, re-oriented.
But not sure this works: theorem\<open>ok_commute\<close> is needed below\<close> declare
rename_sysOfClient_ok_Network [THEN ok_sym, iff]
rename_sysOfClient_ok_Alloc [THEN ok_sym, iff]
rename_sysOfAlloc_ok_Network [THEN ok_sym]
lemma System_Increasing: "i < Nclients
==> System \<in> Increasing (ask o sub i o client) Int
Increasing (rel o sub i o client)" apply (rule component_guaranteesD [OF rename_Client_Increasing Client_component_System]) apply auto done
lemmas rename_guarantees_sysOfAlloc_I =
bij_sysOfAlloc [THEN rename_rename_guarantees_eq, THEN iffD2]
(*Lifting Alloc_Increasing up to the level of systemState*) lemmas rename_Alloc_Increasing =
Alloc_Increasing
[THEN rename_guarantees_sysOfAlloc_I,
simplified surj_rename o_def sub_apply
rename_image_Increasing bij_sysOfAlloc
allocGiv_o_inv_sysOfAlloc_eq']
lemma System_Increasing_allocGiv: "i < Nclients \ System \ Increasing (sub i o allocGiv)" apply (unfold System_def) apply (simp add: o_def) apply (rule rename_Alloc_Increasing [THEN guarantees_Join_I1, THEN guaranteesD]) apply auto done
ML \<open>
ML_Thms.bind_thms ("System_Increasing'", list_of_Int @{thm System_Increasing}) \<close>
declare System_Increasing' [intro!]
text\<open>Follows consequences.
The "Always (INT ...) formulation expresses the general safety property and allows it to be combined using\<open>Always_Int_rule\<close> below.\<close>
lemma System_Follows_rel: "i < Nclients ==> System \ ((sub i o allocRel) Fols (rel o sub i o client))" apply (auto intro!: Network_Rel [THEN component_guaranteesD]) apply (simp add: ok_commute [of Network]) done
lemma System_Follows_ask: "i < Nclients ==> System \ ((sub i o allocAsk) Fols (ask o sub i o client))" apply (auto intro!: Network_Ask [THEN component_guaranteesD]) apply (simp add: ok_commute [of Network]) done
lemma System_Follows_allocGiv: "i < Nclients ==> System \ (giv o sub i o client) Fols (sub i o allocGiv)" apply (auto intro!: Network_Giv [THEN component_guaranteesD]
rename_Alloc_Increasing [THEN component_guaranteesD]) apply (simp_all add: o_def non_dummy_def ok_commute [of Network]) apply (auto intro!: rename_Alloc_Increasing [THEN component_guaranteesD]) done
lemma Always_giv_le_allocGiv: "System \ Always (INT i: lessThan Nclients.
{s. (giv o sub i o client) s \<le> (sub i o allocGiv) s})" apply auto apply (erule System_Follows_allocGiv [THEN Follows_Bounded]) done
lemma Always_allocAsk_le_ask: "System \ Always (INT i: lessThan Nclients.
{s. (sub i o allocAsk) s \<le> (ask o sub i o client) s})" apply auto apply (erule System_Follows_ask [THEN Follows_Bounded]) done
lemma Always_allocRel_le_rel: "System \ Always (INT i: lessThan Nclients.
{s. (sub i o allocRel) s \<le> (rel o sub i o client) s})" by (auto intro!: Follows_Bounded System_Follows_rel)
subsection\<open>Proof of the safety property (1)\<close>
text\<open>safety (1), step 1 is \<open>System_Follows_rel\<close>\<close>
text\<open>safety (1), step 2\<close> (* i < Nclients ==> System : Increasing (sub i o allocRel) *) lemmas System_Increasing_allocRel = System_Follows_rel [THEN Follows_Increasing1]
(*Lifting Alloc_safety up to the level of systemState. Simplifying with o_def gets rid of the translations but it unfortunately
gets rid of the other "o"s too.*)
text\<open>safety (1), step 3\<close> lemma System_sum_bounded: "System \ Always {s. (\i \ lessThan Nclients. (tokens o sub i o allocGiv) s) \<le> NbT + (\<Sum>i \<in> lessThan Nclients. (tokens o sub i o allocRel) s)}" apply (simp add: o_apply) apply (insert Alloc_Safety [THEN rename_guarantees_sysOfAlloc_I]) apply (simp add: o_def) apply (erule component_guaranteesD) apply (auto simp add: System_Increasing_allocRel [simplified sub_apply o_def]) done
text\<open>Follows reasoning\<close>
lemma Always_tokens_giv_le_allocGiv: "System \ Always (INT i: lessThan Nclients.
{s. (tokens o giv o sub i o client) s \<le> (tokens o sub i o allocGiv) s})" apply (rule Always_giv_le_allocGiv [THEN Always_weaken]) apply (auto intro: tokens_mono_prefix simp add: o_apply) done
lemma Always_tokens_allocRel_le_rel: "System \ Always (INT i: lessThan Nclients.
{s. (tokens o sub i o allocRel) s \<le> (tokens o rel o sub i o client) s})" apply (rule Always_allocRel_le_rel [THEN Always_weaken]) apply (auto intro: tokens_mono_prefix simp add: o_apply) done
subsection \<open>Proof of the progress property (2)\<close>
text\<open>progress (2), step 1 is \<open>System_Follows_ask\<close> and \<open>System_Follows_rel\<close>\<close>
text\<open>progress (2), step 2; see also \<open>System_Increasing_allocRel\<close>\<close> (* i < Nclients ==> System : Increasing (sub i o allocAsk) *) lemmas System_Increasing_allocAsk = System_Follows_ask [THEN Follows_Increasing1]
text\<open>progress (2), step 3: lifting \<open>Client_Bounded\<close> to systemState\<close> lemma rename_Client_Bounded: "i \ I
==> rename sysOfClient (plam x: I. rename client_map Client) \<in>
UNIV guarantees
Always {s. \<forall>elt \<in> set ((ask o sub i o client) s). elt \<le> NbT}" using image_cong_simp [cong del] by rename_client_map
lemma System_Bounded_ask: "i < Nclients
==> System \<in> Always
{s. \<forall>elt \<in> set ((ask o sub i o client) s). elt \<le> NbT}" apply (rule component_guaranteesD [OF rename_Client_Bounded Client_component_System]) apply auto done
lemma Collect_all_imp_eq: "{x. \y. P y \ Q x y} = (INT y: {y. P y}. {x. Q x y})" apply blast done
text\<open>progress (2), step 5 is \<open>System_Increasing_allocGiv\<close>\<close>
text\<open>progress (2), step 6\<close> (* i < Nclients ==> System : Increasing (giv o sub i o client) *) lemmas System_Increasing_giv = System_Follows_allocGiv [THEN Follows_Increasing1]
lemma rename_Client_Progress: "i \ I
==> rename sysOfClient (plam x: I. rename client_map Client) \<in> Increasing (giv o sub i o client)
guarantees
(INT h. {s. h \<le> (giv o sub i o client) s &
h pfixGe (ask o sub i o client) s}
LeadsTo {s. tokens h \<le> (tokens o rel o sub i o client) s})"
supply image_cong_simp [cong del] apply rename_client_map apply (simp add: Client_Progress [simplified o_def]) done
text\<open>progress (2), step 7\<close> lemma System_Client_Progress: "System \ (INT i : (lessThan Nclients).
INT h. {s. h \<le> (giv o sub i o client) s &
h pfixGe (ask o sub i o client) s}
LeadsTo {s. tokens h \<le> (tokens o rel o sub i o client) s})" apply (rule INT_I) (*Couldn't have just used Auto_tac since the "INT h" must be kept*) apply (rule component_guaranteesD [OF rename_Client_Progress Client_component_System]) apply (auto simp add: System_Increasing_giv) done
(*Concludes System : {s. k \<le> (sub i o allocGiv) s} LeadsTo {s. (sub i o allocAsk) s \<le> (ask o sub i o client) s} Int
{s. k \<le> (giv o sub i o client) s} *)
lemma System_lemma3: "i < Nclients
==> System \<in> {s. h \<le> (sub i o allocGiv) s &
h pfixGe (sub i o allocAsk) s}
LeadsTo
{s. h \<le> (giv o sub i o client) s &
h pfixGe (ask o sub i o client) s}" apply (rule single_LeadsTo_I) apply (rule_tac k1 = h and x1 = "(sub i o allocAsk) s" in System_lemma2 [THEN LeadsTo_weaken]) apply auto apply (blast intro: trans_Ge [THEN trans_genPrefix, THEN transD] prefix_imp_pfixGe) done
text\<open>progress (2), step 8: Client i's "release" action is visible system-wide\<close> lemma System_Alloc_Client_Progress: "i < Nclients
==> System \<in> {s. h \<le> (sub i o allocGiv) s &
h pfixGe (sub i o allocAsk) s}
LeadsTo {s. tokens h \<le> (tokens o sub i o allocRel) s}" apply (rule LeadsTo_Trans) prefer 2 apply (drule System_Follows_rel [THEN
mono_tokens [THEN mono_Follows_o, THEN [2] rev_subsetD], THEN Follows_LeadsTo]) apply (simp add: o_assoc) apply (rule LeadsTo_Trans) apply (cut_tac [2] System_Client_Progress) prefer 2 apply (blast intro: LeadsTo_Basis) apply (erule System_lemma3) done
text\<open>Lifting \<open>Alloc_Progress\<close> up to the level of systemState\<close>
text\<open>progress (2), step 9\<close> lemma System_Alloc_Progress: "System \ (INT i : (lessThan Nclients).
INT h. {s. h \<le> (sub i o allocAsk) s}
LeadsTo {s. h pfixLe (sub i o allocGiv) s})" apply (simp only: o_apply sub_def) apply (insert Alloc_Progress [THEN rename_guarantees_sysOfAlloc_I]) apply (simp add: o_def del: INT_iff) apply (drule component_guaranteesD) apply (auto simp add:
System_Increasing_allocRel [simplified sub_apply o_def]
System_Increasing_allocAsk [simplified sub_apply o_def]
System_Bounded_allocAsk [simplified sub_apply o_def]
System_Alloc_Client_Progress [simplified sub_apply o_def]) done
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.