(* Title: ZF/UNITY/Union.thy Author: Sidi O Ehmety, Computer Laboratory Copyright 2001 University of Cambridge Unions of programs Partly from Misra's Chapter 5 ∈ Asynchronous Compositions of Programs Theory ported form HOL.. *)
theory Union imports SubstAx FP begin
definition (*FIXME: conjoin Init(F) \<inter> Init(G) \<noteq> 0 *)
ok :: "[i, i] ==> o" (infixl‹ok› 65) where "F ok G ≡ Acts(F) ⊆ AllowedActs(G) ∧ Acts(G) ⊆ AllowedActs(F)"
definition (*FIXME: conjoin (\<Inter>i \<in> I. Init(F(i))) \<noteq> 0 *)
OK :: "[i, i==>i] ==> o"where "OK(I,F) ≡ (∀i ∈ I. ∀j ∈ I-{i}. Acts(F(i)) ⊆ AllowedActs(F(j)))"
definition
JOIN :: "[i, i==>i] ==> i"where "JOIN(I,F) ≡ if I = 0 then SKIP else mk_program(∩i ∈ I. Init(F(i)), ∪i ∈ I. Acts(F(i)), ∩i ∈ I. AllowedActs(F(i)))"
definition
Join :: "[i, i] ==> i" (infixl‹⊔› 65) where "F ⊔ G ≡ mk_program (Init(F) ∩ Init(G), Acts(F) ∪ Acts(G), AllowedActs(F) ∩ AllowedActs(G))" definition (*Characterizes safety properties. Used with specifying AllowedActs*)
safety_prop :: "i ==> o"where "safety_prop(X) ≡ X⊆program ∧ SKIP ∈ X ∧ (∀G ∈ program. Acts(G) ⊆ (∪F ∈ X. Acts(F)) ⟶ G ∈ X)"
(*Fails if I=0 because it collapses to SKIP \<in> A co B, i.e. to A\<subseteq>B. So an alternative precondition is A⊆B, but most proofs using this rule require I to be nonempty for other reasons anyway.*)
lemma JOIN_constrains: "i ∈ I==>(⊔i ∈ I. F(i)) ∈ A co B ⟷ (∀i ∈ I. programify(F(i)) ∈ A co B)"
apply (unfold constrains_def JOIN_def st_set_def, auto) prefer 2 apply blast apply (rename_tac j act y z) apply (cut_tac F = "F (j) "in Acts_type) apply (drule_tac x = act in bspec, auto) done
lemma Join_constrains [iff]: "(F ⊔ G ∈ A co B) ⟷ (programify(F) ∈ A co B ∧ programify(G) ∈ A co B)" by (auto simp add: constrains_def)
lemma Join_unless [iff]: "(F ⊔ G ∈ A unless B) ⟷ (programify(F) ∈ A unless B ∧ programify(G) ∈ A unless B)" by (simp add: Join_constrains unless_def)
(*Analogous weak versions FAIL; see Misra [1994] 5.4.1, Substitution Axiom. reachable (F ⊔ G) could be much bigger than reachable F, reachable G *)
lemma Join_constrains_weaken: "[F ∈ A co A'; G ∈ B co B'] ==> F ⊔ G ∈ (A ∩ B) co (A' ∪ B')" apply (subgoal_tac "st_set (A) ∧ st_set (B) ∧ F ∈ program ∧ G ∈ program") prefer 2 apply (blast dest: constrainsD2, simp) apply (blast intro: constrains_weaken) done
(*If I=0, it degenerates to SKIP \<in> state co 0, which is false.*) lemma JOIN_constrains_weaken: assumes major: "(∧i. i ∈ I ==> F(i) ∈ A(i) co A'(i))" and minor: "i ∈ I" shows"(⊔i ∈ I. F(i)) ∈ (∩i ∈ I. A(i)) co (∪i ∈ I. A'(i))" apply (cut_tac minor) apply (simp (no_asm_simp) add: JOIN_constrains) apply clarify apply (rename_tac "j") apply (frule_tac i = j in major) apply (frule constrainsD2, simp) apply (blast intro: constrains_weaken) done
lemma JOIN_stable: "(⊔i ∈ I. F(i)) ∈ stable(A) ⟷ ((∀i ∈ I. programify(F(i)) ∈ stable(A)) ∧ st_set(A))" apply (auto simp add: stable_def constrains_def JOIN_def) apply (cut_tac F = "F (i) "in Acts_type) apply (drule_tac x = act in bspec, auto) done
lemma initially_JOIN_I: assumes major: "(∧i. i ∈ I ==>F(i) ∈ initially(A))" and minor: "i ∈ I" shows"(⊔i ∈ I. F(i)) ∈ initially(A)" apply (cut_tac minor) apply (auto elim!: not_emptyE simp add: Inter_iff initially_def) apply (frule_tac i = x in major) apply (auto simp add: initially_def) done
lemma invariant_JOIN_I: assumes major: "(∧i. i ∈ I ==> F(i) ∈ invariant(A))" and minor: "i ∈ I" shows"(⊔i ∈ I. F(i)) ∈ invariant(A)" apply (cut_tac minor) apply (auto intro!: initially_JOIN_I dest: major simp add: invariant_def JOIN_stable) apply (erule_tac V = "i ∈ I"in thin_rl) apply (frule major) apply (drule_tac [2] major) apply (auto simp add: invariant_def) apply (frule stableD2, force)+ done
lemma Join_transient_I1: "F ∈ transient(A) ==> F ⊔ G ∈ transient(A)" by (simp add: Join_transient transientD2)
lemma Join_transient_I2: "G ∈ transient(A) ==> F ⊔ G ∈ transient(A)" by (simp add: Join_transient transientD2)
(*If I=0 it degenerates to (SKIP \<in> A ensures B) = False, i.e. to \<not>(A\<subseteq>B) *) lemma JOIN_ensures: "i ∈ I ==> (⊔i ∈ I. F(i)) ∈ A ensures B ⟷ ((∀i ∈ I. programify(F(i)) ∈ (A-B) co (A ∪ B)) ∧ (∃i ∈ I. programify(F(i)) ∈ A ensures B))" by (auto simp add: ensures_def JOIN_constrains JOIN_transient)
lemma Join_ensures: "F ⊔ G ∈ A ensures B ⟷ (programify(F) ∈ (A-B) co (A ∪ B) ∧ programify(G) ∈ (A-B) co (A ∪ B) ∧ (programify(F) ∈ transient (A-B) | programify(G) ∈ transient (A-B)))"
lemma stable_Join_constrains: "[F ∈ stable(A); G ∈ A co A'] ==> F ⊔ G ∈ A co A'" unfolding stable_def constrains_def Join_def st_set_def apply (cut_tac F = F in Acts_type) apply (cut_tac F = G in Acts_type, force) done
(*Premise for G cannot use Always because F \<in> Stable A is weaker than G \<in> stable A *) lemma stable_Join_Always1: "[F ∈ stable(A); G ∈ invariant(A)]==> F ⊔ G ∈ Always(A)" apply (subgoal_tac "F ∈ program ∧ G ∈ program ∧ st_set (A) ") prefer 2 apply (blast dest: invariantD2 stableD2) apply (simp add: Always_def invariant_def initially_def Stable_eq_stable) apply (force intro: stable_Int) done
(*As above, but exchanging the roles of F and G*) lemma stable_Join_Always2: "[F ∈ invariant(A); G ∈ stable(A)]==> F ⊔ G ∈ Always(A)" apply (subst Join_commute) apply (blast intro: stable_Join_Always1) done
lemma stable_Join_ensures1: "[F ∈ stable(A); G ∈ A ensures B]==> F ⊔ G ∈ A ensures B" apply (subgoal_tac "F ∈ program ∧ G ∈ program ∧ st_set (A) ") prefer 2 apply (blast dest: stableD2 ensures_type [THEN subsetD]) apply (simp (no_asm_simp) add: Join_ensures) apply (simp add: stable_def ensures_def) apply (erule constrains_weaken, auto) done
(*As above, but exchanging the roles of F and G*) lemma stable_Join_ensures2: "[F ∈ A ensures B; G ∈ stable(A)]==> F ⊔ G ∈ A ensures B" apply (subst Join_commute) apply (blast intro: stable_Join_ensures1) done
subsection‹The ok and OK relations›
lemma ok_SKIP1 [iff]: "SKIP ok F" by (auto dest: Acts_type [THEN subsetD] simp add: ok_def)
lemma ok_SKIP2 [iff]: "F ok SKIP" by (auto dest: Acts_type [THEN subsetD] simp add: ok_def)
lemma ok_Join_commute: "(F ok G ∧ (F ⊔ G) ok H) ⟷ (G ok H ∧ F ok (G ⊔ H))" by (auto simp add: ok_def)
lemma ok_commute: "(F ok G) ⟷(G ok F)" by (auto simp add: ok_def)
lemmas ok_sym = ok_commute [THEN iffD1]
lemma ok_iff_OK: "OK({⟨0,F⟩,⟨1,G⟩,⟨2,H⟩}, snd) ⟷ (F ok G ∧ (F ⊔ G) ok H)" by (simp add: ok_def Join_def OK_def Int_assoc cons_absorb
Int_Un_distrib2 Ball_def, safe, force+)
lemma ok_Join_iff1 [iff]: "F ok (G ⊔ H) ⟷ (F ok G ∧ F ok H)" by (auto simp add: ok_def)
lemma ok_Join_iff2 [iff]: "(G ⊔ H) ok F ⟷ (G ok F ∧ H ok F)" by (auto simp add: ok_def)
(*useful? Not with the previous two around*) lemma ok_Join_commute_I: "[F ok G; (F ⊔ G) ok H]==> F ok (G ⊔ H)" by (auto simp add: ok_def)
lemma ok_JOIN_iff1 [iff]: "F ok JOIN(I,G) ⟷ (∀i ∈ I. F ok G(i))" by (force dest: Acts_type [THEN subsetD] elim!: not_emptyE simp add: ok_def)
lemma ok_JOIN_iff2 [iff]: "JOIN(I,G) ok F ⟷ (∀i ∈ I. G(i) ok F)" apply (auto elim!: not_emptyE simp add: ok_def) apply (blast dest: Acts_type [THEN subsetD]) done
lemma OK_iff_ok: "OK(I,F) ⟷ (∀i ∈ I. ∀j ∈ I-{i}. F(i) ok (F(j)))" by (auto simp add: ok_def OK_def)
lemma OK_imp_ok: "[OK(I,F); i ∈ I; j ∈ I; i≠j]==> F(i) ok F(j)" by (auto simp add: OK_iff_ok)
lemma OK_0 [iff]: "OK(0,F)" by (simp add: OK_def)
lemma OK_cons_iff: "OK(cons(i, I), F) ⟷ (i ∈ I ∧ OK(I, F)) | (i∉I ∧ OK(I, F) ∧ F(i) ok JOIN(I,F))" apply (simp add: OK_iff_ok) apply (blast intro: ok_sym) done
(*For safety_prop to hold, the property must be satisfiable!*) lemma safety_prop_constrains [iff]: "safety_prop(A co B) ⟷ (A ⊆ B ∧ st_set(A))" by (simp add: safety_prop_def constrains_def st_set_def, blast)
(* To be used with resolution *) lemma safety_prop_constrainsI [iff]: "[A⊆B; st_set(A)]==>safety_prop(A co B)" by auto
lemma safety_prop_stable [iff]: "safety_prop(stable(A)) ⟷ st_set(A)" by (simp add: stable_def)
lemma safety_prop_stableI: "st_set(A) ==> safety_prop(stable(A))" by auto
lemma safety_prop_Int [simp]: "[safety_prop(X) ; safety_prop(Y)]==> safety_prop(X ∩ Y)" apply (simp add: safety_prop_def, safe, blast) apply (drule_tac [2] B = "∪(RepFun (X ∩ Y, Acts))"and C = "∪(RepFun (Y, Acts))"in subset_trans) apply (drule_tac B = "∪(RepFun (X ∩ Y, Acts))"and C = "∪(RepFun (X, Acts))"in subset_trans) apply blast+ done
(* If I=0 the conclusion becomes safety_prop(0) which is false *) lemma safety_prop_Inter: assumes major: "(∧i. i ∈ I ==>safety_prop(X(i)))" and minor: "i ∈ I" shows"safety_prop(∩i ∈ I. X(i))" apply (simp add: safety_prop_def) apply (cut_tac minor, safe) apply (simp (no_asm_use) add: Inter_iff) apply clarify apply (frule major) apply (drule_tac [2] i = xa in major) apply (frule_tac [4] i = xa in major) apply (auto simp add: safety_prop_def) apply (drule_tac B = "∪(RepFun (∩(RepFun (I, X)), Acts))"and C = "∪(RepFun (X (xa), Acts))"in subset_trans) apply blast+ done
lemma def_UNION_ok_iff: "[F ≡ mk_program(init,acts, ∪G ∈ X. Acts(G)); safety_prop(X)] ==> F ok G ⟷ (programify(G) ∈ X ∧ acts ∩ Pow(state*state) ⊆ AllowedActs(G))" unfolding ok_def apply (drule_tac G = G in safety_prop_Acts_iff) apply (cut_tac F = G in AllowedActs_type) apply (cut_tac F = G in Acts_type, auto) done
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet am 2026-04-27)
¤
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 und die Messung sind noch experimentell.