src/HOL/UNITY/UNITY.thy
changeset 13812 91713a1915ee
parent 13805 3786b2fd6808
child 13861 0c18f31d901a
equal deleted inserted replaced
13811:f39f67982854 13812:91713a1915ee
    48     "strongest_rhs F A == Inter {B. F \<in> A co B}"
    48     "strongest_rhs F A == Inter {B. F \<in> A co B}"
    49 
    49 
    50   invariant :: "'a set => 'a program set"
    50   invariant :: "'a set => 'a program set"
    51     "invariant A == {F. Init F \<subseteq> A} \<inter> stable A"
    51     "invariant A == {F. Init F \<subseteq> A} \<inter> stable A"
    52 
    52 
    53   (*Polymorphic in both states and the meaning of \<le> *)
       
    54   increasing :: "['a => 'b::{order}] => 'a program set"
    53   increasing :: "['a => 'b::{order}] => 'a program set"
       
    54     --{*Polymorphic in both states and the meaning of @{text "\<le>"}*}
    55     "increasing f == \<Inter>z. stable {s. z \<le> f s}"
    55     "increasing f == \<Inter>z. stable {s. z \<le> f s}"
    56 
    56 
    57 
    57 
    58 (*Perhaps equalities.ML shouldn't add this in the first place!*)
    58 text{*Perhaps equalities.ML shouldn't add this in the first place!*}
    59 declare image_Collect [simp del]
    59 declare image_Collect [simp del]
    60 
    60 
    61 (*** The abstract type of programs ***)
    61 (*** The abstract type of programs ***)
    62 
    62 
    63 lemmas program_typedef =
    63 lemmas program_typedef =
    81 by (simp add: insert_absorb Id_in_AllowedActs)
    81 by (simp add: insert_absorb Id_in_AllowedActs)
    82 
    82 
    83 (** Inspectors for type "program" **)
    83 (** Inspectors for type "program" **)
    84 
    84 
    85 lemma Init_eq [simp]: "Init (mk_program (init,acts,allowed)) = init"
    85 lemma Init_eq [simp]: "Init (mk_program (init,acts,allowed)) = init"
    86 by (auto simp add: program_typedef)
    86 by (simp add: program_typedef)
    87 
    87 
    88 lemma Acts_eq [simp]: "Acts (mk_program (init,acts,allowed)) = insert Id acts"
    88 lemma Acts_eq [simp]: "Acts (mk_program (init,acts,allowed)) = insert Id acts"
    89 by (auto simp add: program_typedef)
    89 by (simp add: program_typedef)
    90 
    90 
    91 lemma AllowedActs_eq [simp]:
    91 lemma AllowedActs_eq [simp]:
    92      "AllowedActs (mk_program (init,acts,allowed)) = insert Id allowed"
    92      "AllowedActs (mk_program (init,acts,allowed)) = insert Id allowed"
    93 by (auto simp add: program_typedef)
    93 by (simp add: program_typedef)
    94 
    94 
    95 (** Equality for UNITY programs **)
    95 (** Equality for UNITY programs **)
    96 
    96 
    97 lemma surjective_mk_program [simp]:
    97 lemma surjective_mk_program [simp]:
    98      "mk_program (Init F, Acts F, AllowedActs F) = F"
    98      "mk_program (Init F, Acts F, AllowedActs F) = F"
   119      "(F=G) =   
   119      "(F=G) =   
   120       (Init F = Init G & Acts F = Acts G &AllowedActs F = AllowedActs G)"
   120       (Init F = Init G & Acts F = Acts G &AllowedActs F = AllowedActs G)"
   121 by (blast intro: program_equalityI program_equalityE)
   121 by (blast intro: program_equalityI program_equalityE)
   122 
   122 
   123 
   123 
   124 (*** These rules allow "lazy" definition expansion 
       
   125      They avoid expanding the full program, which is a large expression
       
   126 ***)
       
   127 
       
   128 lemma def_prg_Init: "F == mk_program (init,acts,allowed) ==> Init F = init"
       
   129 by auto
       
   130 
       
   131 lemma def_prg_Acts:
       
   132      "F == mk_program (init,acts,allowed) ==> Acts F = insert Id acts"
       
   133 by auto
       
   134 
       
   135 lemma def_prg_AllowedActs:
       
   136      "F == mk_program (init,acts,allowed)  
       
   137       ==> AllowedActs F = insert Id allowed"
       
   138 by auto
       
   139 
       
   140 (*The program is not expanded, but its Init and Acts are*)
       
   141 lemma def_prg_simps:
       
   142     "[| F == mk_program (init,acts,allowed) |]  
       
   143      ==> Init F = init & Acts F = insert Id acts"
       
   144 by simp
       
   145 
       
   146 (*An action is expanded only if a pair of states is being tested against it*)
       
   147 lemma def_act_simp:
       
   148      "[| act == {(s,s'). P s s'} |] ==> ((s,s') \<in> act) = P s s'"
       
   149 by auto
       
   150 
       
   151 (*A set is expanded only if an element is being tested against it*)
       
   152 lemma def_set_simp: "A == B ==> (x \<in> A) = (x \<in> B)"
       
   153 by auto
       
   154 
       
   155 
       
   156 (*** co ***)
   124 (*** co ***)
   157 
   125 
   158 lemma constrainsI: 
   126 lemma constrainsI: 
   159     "(!!act s s'. [| act: Acts F;  (s,s') \<in> act;  s \<in> A |] ==> s': A')  
   127     "(!!act s s'. [| act: Acts F;  (s,s') \<in> act;  s \<in> A |] ==> s': A')  
   160      ==> F \<in> A co A'"
   128      ==> F \<in> A co A'"
   174 by (unfold constrains_def, blast)
   142 by (unfold constrains_def, blast)
   175 
   143 
   176 lemma constrains_UNIV2 [iff]: "F \<in> A co UNIV"
   144 lemma constrains_UNIV2 [iff]: "F \<in> A co UNIV"
   177 by (unfold constrains_def, blast)
   145 by (unfold constrains_def, blast)
   178 
   146 
   179 (*monotonic in 2nd argument*)
   147 text{*monotonic in 2nd argument*}
   180 lemma constrains_weaken_R: 
   148 lemma constrains_weaken_R: 
   181     "[| F \<in> A co A'; A'<=B' |] ==> F \<in> A co B'"
   149     "[| F \<in> A co A'; A'<=B' |] ==> F \<in> A co B'"
   182 by (unfold constrains_def, blast)
   150 by (unfold constrains_def, blast)
   183 
   151 
   184 (*anti-monotonic in 1st argument*)
   152 text{*anti-monotonic in 1st argument*}
   185 lemma constrains_weaken_L: 
   153 lemma constrains_weaken_L: 
   186     "[| F \<in> A co A'; B \<subseteq> A |] ==> F \<in> B co A'"
   154     "[| F \<in> A co A'; B \<subseteq> A |] ==> F \<in> B co A'"
   187 by (unfold constrains_def, blast)
   155 by (unfold constrains_def, blast)
   188 
   156 
   189 lemma constrains_weaken: 
   157 lemma constrains_weaken: 
   225 by (unfold constrains_def, blast)
   193 by (unfold constrains_def, blast)
   226 
   194 
   227 lemma constrains_imp_subset: "F \<in> A co A' ==> A \<subseteq> A'"
   195 lemma constrains_imp_subset: "F \<in> A co A' ==> A \<subseteq> A'"
   228 by (unfold constrains_def, auto)
   196 by (unfold constrains_def, auto)
   229 
   197 
   230 (*The reasoning is by subsets since "co" refers to single actions
   198 text{*The reasoning is by subsets since "co" refers to single actions
   231   only.  So this rule isn't that useful.*)
   199   only.  So this rule isn't that useful.*}
   232 lemma constrains_trans: 
   200 lemma constrains_trans: 
   233     "[| F \<in> A co B; F \<in> B co C |] ==> F \<in> A co C"
   201     "[| F \<in> A co B; F \<in> B co C |] ==> F \<in> A co C"
   234 by (unfold constrains_def, blast)
   202 by (unfold constrains_def, blast)
   235 
   203 
   236 lemma constrains_cancel: 
   204 lemma constrains_cancel: 
   302 (*** invariant ***)
   270 (*** invariant ***)
   303 
   271 
   304 lemma invariantI: "[| Init F \<subseteq> A;  F \<in> stable A |] ==> F \<in> invariant A"
   272 lemma invariantI: "[| Init F \<subseteq> A;  F \<in> stable A |] ==> F \<in> invariant A"
   305 by (simp add: invariant_def)
   273 by (simp add: invariant_def)
   306 
   274 
   307 (*Could also say "invariant A \<inter> invariant B \<subseteq> invariant (A \<inter> B)"*)
   275 text{*Could also say "invariant A \<inter> invariant B \<subseteq> invariant (A \<inter> B)"*}
   308 lemma invariant_Int:
   276 lemma invariant_Int:
   309      "[| F \<in> invariant A;  F \<in> invariant B |] ==> F \<in> invariant (A \<inter> B)"
   277      "[| F \<in> invariant A;  F \<in> invariant B |] ==> F \<in> invariant (A \<inter> B)"
   310 by (auto simp add: invariant_def stable_Int)
   278 by (auto simp add: invariant_def stable_Int)
   311 
   279 
   312 
   280 
   313 (*** increasing ***)
   281 (*** increasing ***)
   314 
   282 
   315 lemma increasingD: 
   283 lemma increasingD: 
   316      "F \<in> increasing f ==> F \<in> stable {s. z \<subseteq> f s}"
   284      "F \<in> increasing f ==> F \<in> stable {s. z \<subseteq> f s}"
   317 
       
   318 by (unfold increasing_def, blast)
   285 by (unfold increasing_def, blast)
   319 
   286 
   320 lemma increasing_constant [iff]: "F \<in> increasing (%s. c)"
   287 lemma increasing_constant [iff]: "F \<in> increasing (%s. c)"
   321 by (unfold increasing_def stable_def, auto)
   288 by (unfold increasing_def stable_def, auto)
   322 
   289 
   339 lemma elimination: 
   306 lemma elimination: 
   340     "[| \<forall>m \<in> M. F \<in> {s. s x = m} co (B m) |]  
   307     "[| \<forall>m \<in> M. F \<in> {s. s x = m} co (B m) |]  
   341      ==> F \<in> {s. s x \<in> M} co (\<Union>m \<in> M. B m)"
   308      ==> F \<in> {s. s x \<in> M} co (\<Union>m \<in> M. B m)"
   342 by (unfold constrains_def, blast)
   309 by (unfold constrains_def, blast)
   343 
   310 
   344 (*As above, but for the trivial case of a one-variable state, in which the
   311 text{*As above, but for the trivial case of a one-variable state, in which the
   345   state is identified with its one variable.*)
   312   state is identified with its one variable.*}
   346 lemma elimination_sing: 
   313 lemma elimination_sing: 
   347     "(\<forall>m \<in> M. F \<in> {m} co (B m)) ==> F \<in> M co (\<Union>m \<in> M. B m)"
   314     "(\<forall>m \<in> M. F \<in> {m} co (B m)) ==> F \<in> M co (\<Union>m \<in> M. B m)"
   348 by (unfold constrains_def, blast)
   315 by (unfold constrains_def, blast)
   349 
   316 
   350 
   317 
   374 by blast
   341 by blast
   375 
   342 
   376 lemma Image_inverse_less_than [simp]: "less_than^-1 `` {k} = lessThan k"
   343 lemma Image_inverse_less_than [simp]: "less_than^-1 `` {k} = lessThan k"
   377 by blast
   344 by blast
   378 
   345 
       
   346 
       
   347 subsection{*Partial versus Total Transitions*}
       
   348 
       
   349 constdefs
       
   350   totalize_act :: "('a * 'a)set => ('a * 'a)set"
       
   351     "totalize_act act == act \<union> diag (-(Domain act))"
       
   352 
       
   353   totalize :: "'a program => 'a program"
       
   354     "totalize F == mk_program (Init F,
       
   355 			       totalize_act ` Acts F,
       
   356 			       AllowedActs F)"
       
   357 
       
   358   mk_total_program :: "('a set * ('a * 'a)set set * ('a * 'a)set set)
       
   359 		   => 'a program"
       
   360     "mk_total_program args == totalize (mk_program args)"
       
   361 
       
   362   all_total :: "'a program => bool"
       
   363     "all_total F == \<forall>act \<in> Acts F. Domain act = UNIV"
       
   364   
       
   365 lemma insert_Id_image_Acts: "f Id = Id ==> insert Id (f`Acts F) = f ` Acts F"
       
   366 by (blast intro: sym [THEN image_eqI])
       
   367 
       
   368 
       
   369 text{*Basic properties*}
       
   370 
       
   371 lemma totalize_act_Id [simp]: "totalize_act Id = Id"
       
   372 by (simp add: totalize_act_def) 
       
   373 
       
   374 lemma Domain_totalize_act [simp]: "Domain (totalize_act act) = UNIV"
       
   375 by (auto simp add: totalize_act_def)
       
   376 
       
   377 lemma Init_totalize [simp]: "Init (totalize F) = Init F"
       
   378 by (unfold totalize_def, auto)
       
   379 
       
   380 lemma Acts_totalize [simp]: "Acts (totalize F) = (totalize_act ` Acts F)"
       
   381 by (simp add: totalize_def insert_Id_image_Acts) 
       
   382 
       
   383 lemma AllowedActs_totalize [simp]: "AllowedActs (totalize F) = AllowedActs F"
       
   384 by (simp add: totalize_def)
       
   385 
       
   386 lemma totalize_constrains_iff [simp]: "(totalize F \<in> A co B) = (F \<in> A co B)"
       
   387 by (simp add: totalize_def totalize_act_def constrains_def, blast)
       
   388 
       
   389 lemma totalize_stable_iff [simp]: "(totalize F \<in> stable A) = (F \<in> stable A)"
       
   390 by (simp add: stable_def)
       
   391 
       
   392 lemma totalize_invariant_iff [simp]:
       
   393      "(totalize F \<in> invariant A) = (F \<in> invariant A)"
       
   394 by (simp add: invariant_def)
       
   395 
       
   396 lemma all_total_totalize: "all_total (totalize F)"
       
   397 by (simp add: totalize_def all_total_def)
       
   398 
       
   399 lemma Domain_iff_totalize_act: "(Domain act = UNIV) = (totalize_act act = act)"
       
   400 by (force simp add: totalize_act_def)
       
   401 
       
   402 lemma all_total_imp_totalize: "all_total F ==> (totalize F = F)"
       
   403 apply (simp add: all_total_def totalize_def) 
       
   404 apply (rule program_equalityI)
       
   405   apply (simp_all add: Domain_iff_totalize_act image_def)
       
   406 done
       
   407 
       
   408 lemma all_total_iff_totalize: "all_total F = (totalize F = F)"
       
   409 apply (rule iffI) 
       
   410  apply (erule all_total_imp_totalize) 
       
   411 apply (erule subst) 
       
   412 apply (rule all_total_totalize) 
       
   413 done
       
   414 
       
   415 lemma mk_total_program_constrains_iff [simp]:
       
   416      "(mk_total_program args \<in> A co B) = (mk_program args \<in> A co B)"
       
   417 by (simp add: mk_total_program_def)
       
   418 
       
   419 
       
   420 subsection{*Rules for Lazy Definition Expansion*}
       
   421 
       
   422 text{*They avoid expanding the full program, which is a large expression*}
       
   423 
       
   424 lemma def_prg_Init:
       
   425      "F == mk_total_program (init,acts,allowed) ==> Init F = init"
       
   426 by (simp add: mk_total_program_def)
       
   427 
       
   428 lemma def_prg_Acts:
       
   429      "F == mk_total_program (init,acts,allowed) 
       
   430       ==> Acts F = insert Id (totalize_act ` acts)"
       
   431 by (simp add: mk_total_program_def)
       
   432 
       
   433 lemma def_prg_AllowedActs:
       
   434      "F == mk_total_program (init,acts,allowed)  
       
   435       ==> AllowedActs F = insert Id allowed"
       
   436 by (simp add: mk_total_program_def)
       
   437 
       
   438 text{*An action is expanded if a pair of states is being tested against it*}
       
   439 lemma def_act_simp:
       
   440      "act == {(s,s'). P s s'} ==> ((s,s') \<in> act) = P s s'"
       
   441 by (simp add: mk_total_program_def)
       
   442 
       
   443 text{*A set is expanded only if an element is being tested against it*}
       
   444 lemma def_set_simp: "A == B ==> (x \<in> A) = (x \<in> B)"
       
   445 by (simp add: mk_total_program_def)
       
   446 
       
   447 (** Inspectors for type "program" **)
       
   448 
       
   449 lemma Init_total_eq [simp]:
       
   450      "Init (mk_total_program (init,acts,allowed)) = init"
       
   451 by (simp add: mk_total_program_def)
       
   452 
       
   453 lemma Acts_total_eq [simp]:
       
   454     "Acts(mk_total_program(init,acts,allowed)) = insert Id (totalize_act`acts)"
       
   455 by (simp add: mk_total_program_def)
       
   456 
       
   457 lemma AllowedActs_total_eq [simp]:
       
   458      "AllowedActs (mk_total_program (init,acts,allowed)) = insert Id allowed"
       
   459 by (auto simp add: mk_total_program_def)
       
   460 
   379 end
   461 end