(* Title: HOL/UNITY/Transformers.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 2003 University of Cambridge Predicate Transformers. From David Meier and Beverly Sanders, Composing Leads-to Properties Theoretical Computer Science 243:1-2 (2000), 339-361. David Meier, Progress Properties in Program Refinement and Parallel Composition Swiss Federal Institute of Technology Zurich (1997) *)
section‹Predicate Transformers›
theory Transformers imports Comp begin
subsection‹Defining the Predicate Transformers 🍋‹wp›, 🍋‹awp›and 🍋‹wens›\›
definition wp :: "[('a*'a) set, 'a set] => 'a set"where 🍋‹Dijkstra's weakest-precondition operator (for an individual command)› "wp act B == - (act-1 `` (-B))"
definition awp :: "['a program, 'a set] => 'a set"where 🍋‹Dijkstra's weakest-precondition operator (for a program)› "awp F B == (∩act ∈ Acts F. wp act B)"
definition wens :: "['a program, ('a*'a) set, 'a set] => 'a set"where 🍋‹The weakest-ensures transformer› "wens F act B == gfp(λX. (wp act B ∩ awp F (B ∪ X)) ∪ B)"
text‹The fundamental theorem for wp› theorem wp_iff: "(A <= wp act B) = (act `` A <= B)" by (force simp add: wp_def)
text‹This lemma is a good deal more intuitive than the definition!› lemma in_wp_iff: "(a ∈ wp act B) = (∀x. (a,x) ∈ act --> x ∈ B)" by (simp add: wp_def, blast)
text‹The identity relation is the skip action› lemma wp_Id [simp]: "wp Id B = B" by (simp add: wp_def)
lemma wp_totalize_act: "wp (totalize_act act) B = (wp act B ∩ Domain act) ∪ (B - Domain act)" by (simp add: wp_def totalize_act_def, blast)
lemma awp_subset: "(awp F A ⊆ A)" by (force simp add: awp_def wp_def)
lemma awp_Int_eq: "awp F (A∩B) = awp F A ∩ awp F B" by (simp add: awp_def wp_def, blast)
text‹The fundamental theorem for awp› theorem awp_iff_constrains: "(A <= awp F B) = (F ∈ A co B)" by (simp add: awp_def constrains_def wp_iff INT_subset_iff)
lemma awp_iff_stable: "(A ⊆ awp F A) = (F ∈ stable A)" by (simp add: awp_iff_constrains stable_def)
lemma stable_imp_awp_ident: "F ∈ stable A ==> awp F A = A" apply (rule equalityI [OF awp_subset]) apply (simp add: awp_iff_stable) done
lemma wp_mono: "(A ⊆ B) ==> wp act A ⊆ wp act B" by (simp add: wp_def, blast)
lemma awp_mono: "(A ⊆ B) ==> awp F A ⊆ awp F B" by (simp add: awp_def wp_def, blast)
lemma wens_unfold: "wens F act B = (wp act B ∩ awp F (B ∪ wens F act B)) ∪ B" apply (simp add: wens_def) apply (rule gfp_unfold) apply (simp add: mono_def wp_def awp_def, blast) done
lemma wens_Id [simp]: "wens F Id B = B" by (simp add: wens_def gfp_def wp_def awp_def, blast)
text‹These two theorems justify the claim that 🍋‹wens›returns the weakest assertion satisfying the ensures property› lemma ensures_imp_wens: "F ∈ A ensures B ==> ∃act ∈ Acts F. A ⊆ wens F act B" apply (simp add: wens_def ensures_def transient_def, clarify) apply (rule rev_bexI, assumption) apply (rule gfp_upperbound) apply (simp add: constrains_def awp_def wp_def, blast) done
lemma wens_ensures: "act ∈ Acts F ==> F ∈ (wens F act B) ensures B" by (simp add: wens_def gfp_def constrains_def awp_def wp_def
ensures_def transient_def, blast)
text‹These two results constitute assertion (4.13) of the thesis› lemma wens_mono: "(A ⊆ B) ==> wens F act A ⊆ wens F act B" apply (simp add: wens_def wp_def awp_def) apply (rule gfp_mono, blast) done
lemma wens_weakening: "B ⊆ wens F act B" by (simp add: wens_def gfp_def, blast)
text‹Assertion (6), or 4.16 in the thesis› lemma subset_wens: "A-B ⊆ wp act B ∩ awp F (B ∪ A) ==> A ⊆ wens F act B" apply (simp add: wens_def wp_def awp_def) apply (rule gfp_upperbound, blast) done
text‹Assertion 4.17 in the thesis› lemma Diff_wens_constrains: "F ∈ (wens F act A - A) co wens F act A" by (simp add: wens_def gfp_def wp_def awp_def constrains_def, blast) 🍋‹Proved instantly, yet remarkably fragile. If ‹Un_subset_iff› is declared as an iff-rule, then it's almost impossible to prove. One proof is via ‹meson›after expanding all definitions, but it's slow!›
text‹Assertion (7): 4.18 in the thesis. NOTE that many of these results hold for an arbitrary action. We often do not require 🍋‹act ∈ Acts F›\› lemma stable_wens: "F ∈ stable A ==> F ∈ stable (wens F act A)" apply (simp add: stable_def) apply (drule constrains_Un [OF Diff_wens_constrains [of F act A]]) apply (simp add: Un_Int_distrib2 Compl_partition2) apply (erule constrains_weaken, blast) apply (simp add: wens_weakening) done
text‹Assertion 4.20 in the thesis.› lemma wens_Int_eq_lemma: "[|T-B ⊆ awp F T; act ∈ Acts F|] ==> T ∩ wens F act B ⊆ wens F act (T∩B)" apply (rule subset_wens) apply (rule_tac P="λx. f x ⊆ b"for f b in ssubst [OF wens_unfold]) apply (simp add: wp_def awp_def, blast) done
text‹Assertion (8): 4.21 in the thesis. Here we indeed require 🍋‹act ∈ Acts F›\› lemma wens_Int_eq: "[|T-B ⊆ awp F T; act ∈ Acts F|] ==> T ∩ wens F act B = T ∩ wens F act (T∩B)" apply (rule equalityI) apply (simp_all add: Int_lower1) apply (rule wens_Int_eq_lemma, assumption+) apply (rule subset_trans [OF _ wens_mono [of "T∩B" B]], auto) done
subsection‹Defining the Weakest Ensures Set›
inductive_set
wens_set :: "['a program, 'a set] => 'a set set" for F :: "'a program"and B :: "'a set" where
Basis: "B ∈ wens_set F B"
| Wens: "[|X ∈ wens_set F B; act ∈ Acts F|] ==> wens F act X ∈ wens_set F B"
| Union: "W ≠ {} ==> ∀U ∈ W. U ∈ wens_set F B ==> ∪W ∈ wens_set F B"
lemma wens_set_imp_co: "A ∈ wens_set F B ==> F ∈ (A-B) co A" apply (erule wens_set.induct) apply (simp add: constrains_def) apply (drule_tac act1=act and A1=X in constrains_Un [OF Diff_wens_constrains]) apply (erule constrains_weaken, blast) apply (simp add: wens_weakening) apply (rule constrains_weaken) apply (rule_tac I=W and A="λv. v-B"and A'="λv. v"in constrains_UN, blast+) done
lemma wens_set_imp_leadsTo: "A ∈ wens_set F B ==> F ∈ A leadsTo B" apply (erule wens_set.induct) apply (rule leadsTo_refl) apply (blast intro: wens_ensures leadsTo_Trans) apply (blast intro: leadsTo_Union) done
lemma leadsTo_imp_wens_set: "F ∈ A leadsTo B ==> ∃C ∈ wens_set F B. A ⊆ C" apply (erule leadsTo_induct_pre) apply (blast dest!: ensures_imp_wens intro: wens_set.Basis wens_set.Wens) apply (clarify, drule ensures_weaken_R, assumption) apply (blast dest!: ensures_imp_wens intro: wens_set.Wens) apply (case_tac "S={}") apply (simp, blast intro: wens_set.Basis) apply (clarsimp dest!: bchoice simp: ball_conj_distrib Bex_def) apply (rule_tac x = "∪{Z. ∃U∈S. Z = f U}"in exI) apply (blast intro: wens_set.Union) done
text‹Assertion (9): 4.27 in the thesis.› lemma leadsTo_iff_wens_set: "(F ∈ A leadsTo B) = (∃C ∈ wens_set F B. A ⊆ C)" by (blast intro: leadsTo_imp_wens_set leadsTo_weaken_L wens_set_imp_leadsTo)
text‹This is the result that requires the definition of 🍋‹wens_set›to require 🍋‹W›to be non-empty in the Unio case, for otherwise we should always have 🍋‹{} ∈ wens_set F B›.› lemma wens_set_imp_subset: "A ∈ wens_set F B ==> B ⊆ A" apply (erule wens_set.induct) apply (blast intro: wens_weakening [THEN subsetD])+ done
subsection‹Properties Involving Program Union›
text‹Assertion (4.30) of thesis, reoriented› lemma awp_Join_eq: "awp (F⊔G) B = awp F B ∩ awp G B" by (simp add: awp_def wp_def, blast)
lemma wens_subset: "wens F act B - B ⊆ wp act B ∩ awp F (B ∪ wens F act B)" by (subst wens_unfold, fast)
text‹Assertion (4.31)› lemma subset_wens_Join: "[|A = T ∩ wens F act B; T-B ⊆ awp F T; A-B ⊆ awp G (A ∪ B)|] ==> A ⊆ wens (F⊔G) act B" apply (subgoal_tac "(T ∩ wens F act B) - B ⊆ wp act B ∩ awp F (B ∪ wens F act B) ∩ awp F T") apply (rule subset_wens) apply (simp add: awp_Join_eq awp_Int_eq Un_commute) apply (simp add: awp_def wp_def, blast) apply (insert wens_subset [of F act B], blast) done
lemma atMost_nat_nonempty: "atMost (k::nat) ≠ {}" by force
lemma wens_single_finite_0 [simp]: "wens_single_finite act B 0 = B" by (simp add: wens_single_finite_def)
lemma wens_single_finite_Suc: "single_valued act ==> wens_single_finite act B (Suc k) = wens_single_finite act B k ∪ wp act (wens_single_finite act B k)" apply (simp add: wens_single_finite_def wp_UN_eq [OF _ atMost_nat_nonempty]) apply (force elim!: le_SucE) done
lemma wens_single_finite_Suc_eq_wens: "single_valued act ==> wens_single_finite act B (Suc k) = wens (mk_program (init, {act}, allowed)) act (wens_single_finite act B k)" by (simp add: wens_single_finite_Suc wens_single_eq)
lemma def_wens_single_finite_Suc_eq_wens: "[|F = mk_program (init, {act}, allowed); single_valued act|] ==> wens_single_finite act B (Suc k) = wens F act (wens_single_finite act B k)" by (simp add: wens_single_finite_Suc_eq_wens)
lemma wens_single_finite_Un_eq: "single_valued act ==> wens_single_finite act B k ∪ wp act (wens_single_finite act B k) ∈ range (wens_single_finite act B)" by (simp add: wens_single_finite_Suc [symmetric])
lemma wens_single_eq_Union: "wens_single act B = ∪(range (wens_single_finite act B))" by (simp add: wens_single_finite_def wens_single_def, blast)
lemma wens_single_finite_eq_Union: "wens_single_finite act B n = (∪k∈atMost n. wens_single_finite act B k)" apply (auto simp add: wens_single_finite_def) apply (blast intro: le_trans) done
lemma wens_single_finite_mono: "m ≤ n ==> wens_single_finite act B m ⊆ wens_single_finite act B n" by (force simp add: wens_single_finite_eq_Union [of act B n])
lemma wens_single_finite_subset_wens_single: "wens_single_finite act B k ⊆ wens_single act B" by (simp add: wens_single_eq_Union, blast)
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.