src/HOL/UNITY/Comp/AllocImpl.thy
changeset 14089 7b34f58b1b81
parent 11194 ea13ff5a26d1
child 14114 e97ca1034caa
equal deleted inserted replaced
14088:61bd46feb919 14089:7b34f58b1b81
     1 (*  Title:      HOL/UNITY/AllocImpl
     1 (*  Title:      HOL/UNITY/AllocImpl
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     3     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     4     Copyright   1998  University of Cambridge
     4     Copyright   1998  University of Cambridge
     5 
       
     6 Implementation of a multiple-client allocator from a single-client allocator
       
     7 *)
     5 *)
     8 
     6 
     9 AllocImpl = AllocBase + Follows + PPROD + 
     7 header{*Implementation of a multiple-client allocator from a single-client allocator*}
       
     8 
       
     9 theory AllocImpl = AllocBase + Follows + PPROD:
    10 
    10 
    11 
    11 
    12 (** State definitions.  OUTPUT variables are locals **)
    12 (** State definitions.  OUTPUT variables are locals **)
    13 
    13 
    14 (*Type variable 'b is the type of items being merged*)
    14 (*Type variable 'b is the type of items being merged*)
    15 record 'b merge =
    15 record 'b merge =
    16   In   :: nat => 'b list   (*merge's INPUT histories: streams to merge*)
    16   In   :: "nat => 'b list"   (*merge's INPUT histories: streams to merge*)
    17   Out  :: 'b list          (*merge's OUTPUT history: merged items*)
    17   Out  :: "'b list"          (*merge's OUTPUT history: merged items*)
    18   iOut :: nat list         (*merge's OUTPUT history: origins of merged items*)
    18   iOut :: "nat list"        (*merge's OUTPUT history: origins of merged items*)
    19 
    19 
    20 record ('a,'b) merge_d =
    20 record ('a,'b) merge_d =
    21   'b merge +
    21   "'b merge" +
    22   dummy :: 'a       (*dummy field for new variables*)
    22   dummy :: 'a       (*dummy field for new variables*)
    23 
    23 
    24 constdefs
    24 constdefs
    25   non_dummy :: ('a,'b) merge_d => 'b merge
    25   non_dummy :: "('a,'b) merge_d => 'b merge"
    26     "non_dummy s == (|In = In s, Out = Out s, iOut = iOut s|)"
    26     "non_dummy s == (|In = In s, Out = Out s, iOut = iOut s|)"
    27 
    27 
    28 record 'b distr =
    28 record 'b distr =
    29   In  :: 'b list          (*items to distribute*)
    29   In  :: "'b list"          (*items to distribute*)
    30   iIn :: nat list         (*destinations of items to distribute*)
    30   iIn :: "nat list"         (*destinations of items to distribute*)
    31   Out :: nat => 'b list   (*distributed items*)
    31   Out :: "nat => 'b list"   (*distributed items*)
    32 
    32 
    33 record ('a,'b) distr_d =
    33 record ('a,'b) distr_d =
    34   'b distr +
    34   "'b distr" +
    35   dummy :: 'a       (*dummy field for new variables*)
    35   dummy :: 'a       (*dummy field for new variables*)
    36 
    36 
    37 record allocState =
    37 record allocState =
    38   giv :: nat list   (*OUTPUT history: source of tokens*)
    38   giv :: "nat list"   (*OUTPUT history: source of tokens*)
    39   ask :: nat list   (*INPUT: tokens requested from allocator*)
    39   ask :: "nat list"   (*INPUT: tokens requested from allocator*)
    40   rel :: nat list   (*INPUT: tokens released to allocator*)
    40   rel :: "nat list"   (*INPUT: tokens released to allocator*)
    41 
    41 
    42 record 'a allocState_d =
    42 record 'a allocState_d =
    43   allocState +
    43   allocState +
    44   dummy    :: 'a                (*dummy field for new variables*)
    44   dummy    :: 'a                (*dummy field for new variables*)
    45 
    45 
    46 record 'a systemState =
    46 record 'a systemState =
    47   allocState +
    47   allocState +
    48   mergeRel :: nat merge
    48   mergeRel :: "nat merge"
    49   mergeAsk :: nat merge
    49   mergeAsk :: "nat merge"
    50   distr    :: nat distr
    50   distr    :: "nat distr"
    51   dummy    :: 'a                  (*dummy field for new variables*)
    51   dummy    :: 'a                  (*dummy field for new variables*)
    52 
    52 
    53 
    53 
    54 constdefs
    54 constdefs
    55 
    55 
    56 (** Merge specification (the number of inputs is Nclients) ***)
    56 (** Merge specification (the number of inputs is Nclients) ***)
    57 
    57 
    58   (*spec (10)*)
    58   (*spec (10)*)
    59   merge_increasing :: ('a,'b) merge_d program set
    59   merge_increasing :: "('a,'b) merge_d program set"
    60     "merge_increasing ==
    60     "merge_increasing ==
    61          UNIV guarantees (Increasing merge.Out) Int (Increasing merge.iOut)"
    61          UNIV guarantees (Increasing merge.Out) Int (Increasing merge.iOut)"
    62 
    62 
    63   (*spec (11)*)
    63   (*spec (11)*)
    64   merge_eqOut :: ('a,'b) merge_d program set
    64   merge_eqOut :: "('a,'b) merge_d program set"
    65     "merge_eqOut ==
    65     "merge_eqOut ==
    66          UNIV guarantees
    66          UNIV guarantees
    67          Always {s. length (merge.Out s) = length (merge.iOut s)}"
    67          Always {s. length (merge.Out s) = length (merge.iOut s)}"
    68 
    68 
    69   (*spec (12)*)
    69   (*spec (12)*)
    70   merge_bounded :: ('a,'b) merge_d program set
    70   merge_bounded :: "('a,'b) merge_d program set"
    71     "merge_bounded ==
    71     "merge_bounded ==
    72          UNIV guarantees
    72          UNIV guarantees
    73          Always {s. ALL elt : set (merge.iOut s). elt < Nclients}"
    73          Always {s. \<forall>elt \<in> set (merge.iOut s). elt < Nclients}"
    74 
    74 
    75   (*spec (13)*)
    75   (*spec (13)*)
    76   merge_follows :: ('a,'b) merge_d program set
    76   merge_follows :: "('a,'b) merge_d program set"
    77     "merge_follows ==
    77     "merge_follows ==
    78 	 (INT i : lessThan Nclients. Increasing (sub i o merge.In))
    78 	 (\<Inter>i \<in> lessThan Nclients. Increasing (sub i o merge.In))
    79 	 guarantees
    79 	 guarantees
    80 	 (INT i : lessThan Nclients. 
    80 	 (\<Inter>i \<in> lessThan Nclients. 
    81 	  (%s. sublist (merge.Out s) 
    81 	  (%s. sublist (merge.Out s) 
    82                        {k. k < size(merge.iOut s) & merge.iOut s! k = i})
    82                        {k. k < size(merge.iOut s) & merge.iOut s! k = i})
    83 	  Fols (sub i o merge.In))"
    83 	  Fols (sub i o merge.In))"
    84 
    84 
    85   (*spec: preserves part*)
    85   (*spec: preserves part*)
    86   merge_preserves :: ('a,'b) merge_d program set
    86   merge_preserves :: "('a,'b) merge_d program set"
    87     "merge_preserves == preserves merge.In Int preserves merge_d.dummy"
    87     "merge_preserves == preserves merge.In Int preserves merge_d.dummy"
    88 
    88 
    89   (*environmental constraints*)
    89   (*environmental constraints*)
    90   merge_allowed_acts :: ('a,'b) merge_d program set
    90   merge_allowed_acts :: "('a,'b) merge_d program set"
    91     "merge_allowed_acts ==
    91     "merge_allowed_acts ==
    92        {F. AllowedActs F =
    92        {F. AllowedActs F =
    93 	    insert Id (UNION (preserves (funPair merge.Out merge.iOut)) Acts)}"
    93 	    insert Id (UNION (preserves (funPair merge.Out merge.iOut)) Acts)}"
    94 
    94 
    95   merge_spec :: ('a,'b) merge_d program set
    95   merge_spec :: "('a,'b) merge_d program set"
    96     "merge_spec == merge_increasing Int merge_eqOut Int merge_bounded Int
    96     "merge_spec == merge_increasing Int merge_eqOut Int merge_bounded Int
    97                    merge_follows Int merge_allowed_acts Int merge_preserves"
    97                    merge_follows Int merge_allowed_acts Int merge_preserves"
    98 
    98 
    99 (** Distributor specification (the number of outputs is Nclients) ***)
    99 (** Distributor specification (the number of outputs is Nclients) ***)
   100 
   100 
   101   (*spec (14)*)
   101   (*spec (14)*)
   102   distr_follows :: ('a,'b) distr_d program set
   102   distr_follows :: "('a,'b) distr_d program set"
   103     "distr_follows ==
   103     "distr_follows ==
   104 	 Increasing distr.In Int Increasing distr.iIn Int
   104 	 Increasing distr.In Int Increasing distr.iIn Int
   105 	 Always {s. ALL elt : set (distr.iIn s). elt < Nclients}
   105 	 Always {s. \<forall>elt \<in> set (distr.iIn s). elt < Nclients}
   106 	 guarantees
   106 	 guarantees
   107 	 (INT i : lessThan Nclients. 
   107 	 (\<Inter>i \<in> lessThan Nclients. 
   108 	  (sub i o distr.Out) Fols
   108 	  (sub i o distr.Out) Fols
   109 	  (%s. sublist (distr.In s) 
   109 	  (%s. sublist (distr.In s) 
   110                        {k. k < size(distr.iIn s) & distr.iIn s ! k = i}))"
   110                        {k. k < size(distr.iIn s) & distr.iIn s ! k = i}))"
   111 
   111 
   112   distr_allowed_acts :: ('a,'b) distr_d program set
   112   distr_allowed_acts :: "('a,'b) distr_d program set"
   113     "distr_allowed_acts ==
   113     "distr_allowed_acts ==
   114        {D. AllowedActs D = insert Id (UNION (preserves distr.Out) Acts)}"
   114        {D. AllowedActs D = insert Id (UNION (preserves distr.Out) Acts)}"
   115 
   115 
   116   distr_spec :: ('a,'b) distr_d program set
   116   distr_spec :: "('a,'b) distr_d program set"
   117     "distr_spec == distr_follows Int distr_allowed_acts"
   117     "distr_spec == distr_follows Int distr_allowed_acts"
   118 
   118 
   119 (** Single-client allocator specification (required) ***)
   119 (** Single-client allocator specification (required) ***)
   120 
   120 
   121   (*spec (18)*)
   121   (*spec (18)*)
   122   alloc_increasing :: 'a allocState_d program set
   122   alloc_increasing :: "'a allocState_d program set"
   123     "alloc_increasing == UNIV  guarantees  Increasing giv"
   123     "alloc_increasing == UNIV  guarantees  Increasing giv"
   124 
   124 
   125   (*spec (19)*)
   125   (*spec (19)*)
   126   alloc_safety :: 'a allocState_d program set
   126   alloc_safety :: "'a allocState_d program set"
   127     "alloc_safety ==
   127     "alloc_safety ==
   128 	 Increasing rel
   128 	 Increasing rel
   129          guarantees  Always {s. tokens (giv s) <= NbT + tokens (rel s)}"
   129          guarantees  Always {s. tokens (giv s) <= NbT + tokens (rel s)}"
   130 
   130 
   131   (*spec (20)*)
   131   (*spec (20)*)
   132   alloc_progress :: 'a allocState_d program set
   132   alloc_progress :: "'a allocState_d program set"
   133     "alloc_progress ==
   133     "alloc_progress ==
   134 	 Increasing ask Int Increasing rel Int
   134 	 Increasing ask Int Increasing rel Int
   135          Always {s. ALL elt : set (ask s). elt <= NbT}
   135          Always {s. \<forall>elt \<in> set (ask s). elt <= NbT}
   136          Int
   136          Int
   137          (INT h. {s. h <= giv s & h pfixGe (ask s)}
   137          (\<Inter>h. {s. h <= giv s & h pfixGe (ask s)}
   138 		 LeadsTo
   138 		 LeadsTo
   139 	         {s. tokens h <= tokens (rel s)})
   139 	         {s. tokens h <= tokens (rel s)})
   140          guarantees  (INT h. {s. h <= ask s} LeadsTo {s. h pfixLe giv s})"
   140          guarantees  (\<Inter>h. {s. h <= ask s} LeadsTo {s. h pfixLe giv s})"
   141 
   141 
   142   (*spec: preserves part*)
   142   (*spec: preserves part*)
   143   alloc_preserves :: 'a allocState_d program set
   143   alloc_preserves :: "'a allocState_d program set"
   144     "alloc_preserves == preserves rel Int
   144     "alloc_preserves == preserves rel Int
   145                         preserves ask Int
   145                         preserves ask Int
   146                         preserves allocState_d.dummy"
   146                         preserves allocState_d.dummy"
   147   
   147   
   148 
   148 
   149   (*environmental constraints*)
   149   (*environmental constraints*)
   150   alloc_allowed_acts :: 'a allocState_d program set
   150   alloc_allowed_acts :: "'a allocState_d program set"
   151     "alloc_allowed_acts ==
   151     "alloc_allowed_acts ==
   152        {F. AllowedActs F = insert Id (UNION (preserves giv) Acts)}"
   152        {F. AllowedActs F = insert Id (UNION (preserves giv) Acts)}"
   153 
   153 
   154   alloc_spec :: 'a allocState_d program set
   154   alloc_spec :: "'a allocState_d program set"
   155     "alloc_spec == alloc_increasing Int alloc_safety Int alloc_progress Int
   155     "alloc_spec == alloc_increasing Int alloc_safety Int alloc_progress Int
   156                    alloc_allowed_acts Int alloc_preserves"
   156                    alloc_allowed_acts Int alloc_preserves"
   157 
   157 
   158 locale Merge =
   158 locale Merge =
   159   fixes 
   159   fixes M :: "('a,'b::order) merge_d program"
   160     M   :: ('a,'b::order) merge_d program
       
   161   assumes
   160   assumes
   162     Merge_spec  "M  : merge_spec"
   161     Merge_spec:  "M  \<in> merge_spec"
   163 
   162 
   164 locale Distrib =
   163 locale Distrib =
   165   fixes 
   164   fixes D :: "('a,'b::order) distr_d program"
   166     D   :: ('a,'b::order) distr_d program
       
   167   assumes
   165   assumes
   168     Distrib_spec  "D : distr_spec"
   166     Distrib_spec:  "D \<in> distr_spec"
   169 
   167 
   170 
   168 
   171 (****
   169 (****
   172 #  (** Network specification ***)
   170 #  {** Network specification ***}
   173 
   171 
   174 #    (*spec (9.1)*)
   172 #    {*spec (9.1)*}
   175 #    network_ask :: 'a systemState program set
   173 #    network_ask :: "'a systemState program set
   176 #	"network_ask == INT i : lessThan Nclients.
   174 #	"network_ask == \<Inter>i \<in> lessThan Nclients.
   177 #			    Increasing (ask o sub i o client)
   175 #			    Increasing (ask o sub i o client)
   178 #			    guarantees[ask]
   176 #			    guarantees[ask]
   179 #			    (ask  Fols (ask o sub i o client))"
   177 #			    (ask  Fols (ask o sub i o client))"
   180 
   178 
   181 #    (*spec (9.2)*)
   179 #    {*spec (9.2)*}
   182 #    network_giv :: 'a systemState program set
   180 #    network_giv :: "'a systemState program set
   183 #	"network_giv == INT i : lessThan Nclients.
   181 #	"network_giv == \<Inter>i \<in> lessThan Nclients.
   184 #			    Increasing giv 
   182 #			    Increasing giv 
   185 #			    guarantees[giv o sub i o client]
   183 #			    guarantees[giv o sub i o client]
   186 #			    ((giv o sub i o client) Fols giv )"
   184 #			    ((giv o sub i o client) Fols giv)"
   187 
   185 
   188 #    (*spec (9.3)*)
   186 #    {*spec (9.3)*}
   189 #    network_rel :: 'a systemState program set
   187 #    network_rel :: "'a systemState program set
   190 #	"network_rel == INT i : lessThan Nclients.
   188 #	"network_rel == \<Inter>i \<in> lessThan Nclients.
   191 #			    Increasing (rel o sub i o client)
   189 #			    Increasing (rel o sub i o client)
   192 #			    guarantees[rel]
   190 #			    guarantees[rel]
   193 #			    (rel  Fols (rel o sub i o client))"
   191 #			    (rel  Fols (rel o sub i o client))"
   194 
   192 
   195 #    (*spec: preserves part*)
   193 #    {*spec: preserves part*}
   196 #	network_preserves :: 'a systemState program set
   194 #	network_preserves :: "'a systemState program set
   197 #	"network_preserves == preserves giv  Int
   195 #	"network_preserves == preserves giv  Int
   198 #			      (INT i : lessThan Nclients.
   196 #			      (\<Inter>i \<in> lessThan Nclients.
   199 #			       preserves (funPair rel ask o sub i o client))"
   197 #			       preserves (funPair rel ask o sub i o client))"
   200 
   198 
   201 #    network_spec :: 'a systemState program set
   199 #    network_spec :: "'a systemState program set
   202 #	"network_spec == network_ask Int network_giv Int
   200 #	"network_spec == network_ask Int network_giv Int
   203 #			 network_rel Int network_preserves"
   201 #			 network_rel Int network_preserves"
   204 
   202 
   205 
   203 
   206 #  (** State mappings **)
   204 #  {** State mappings **}
   207 #    sysOfAlloc :: "((nat => merge) * 'a) allocState_d => 'a systemState"
   205 #    sysOfAlloc :: "((nat => merge) * 'a) allocState_d => 'a systemState"
   208 #	"sysOfAlloc == %s. let (cl,xtr) = allocState_d.dummy s
   206 #	"sysOfAlloc == %s. let (cl,xtr) = allocState_d.dummy s
   209 #			   in (| giv = giv s,
   207 #			   in (| giv = giv s,
   210 #				 ask = ask s,
   208 #				 ask = ask s,
   211 #				 rel = rel s,
   209 #				 rel = rel s,
   219 #				     rel = rel al,
   217 #				     rel = rel al,
   220 #				     client   = cl,
   218 #				     client   = cl,
   221 #				     systemState.dummy = allocState_d.dummy al|)"
   219 #				     systemState.dummy = allocState_d.dummy al|)"
   222 ****)
   220 ****)
   223 
   221 
       
   222 
       
   223 declare subset_preserves_o [THEN subsetD, intro]
       
   224 declare funPair_o_distrib [simp]
       
   225 declare Always_INT_distrib [simp]
       
   226 declare o_apply [simp del]
       
   227 
       
   228 
       
   229 subsection{*Theorems for Merge*}
       
   230 
       
   231 lemma (in Merge) Merge_Allowed:
       
   232      "Allowed M = (preserves merge.Out) Int (preserves merge.iOut)"
       
   233 apply (cut_tac Merge_spec)
       
   234 apply (auto simp add: merge_spec_def merge_allowed_acts_def Allowed_def safety_prop_Acts_iff)
       
   235 done
       
   236 
       
   237 lemma (in Merge) M_ok_iff [iff]:
       
   238      "M ok G = (G \<in> preserves merge.Out & G \<in> preserves merge.iOut &  
       
   239                      M \<in> Allowed G)"
       
   240 by (auto simp add: Merge_Allowed ok_iff_Allowed)
       
   241 
       
   242 
       
   243 lemma (in Merge) Merge_Always_Out_eq_iOut:
       
   244      "[| G \<in> preserves merge.Out; G \<in> preserves merge.iOut; M \<in> Allowed G |]  
       
   245       ==> M Join G \<in> Always {s. length (merge.Out s) = length (merge.iOut s)}"
       
   246 apply (cut_tac Merge_spec)
       
   247 apply (force dest: guaranteesD simp add: merge_spec_def merge_eqOut_def)
       
   248 done
       
   249 
       
   250 lemma (in Merge) Merge_Bounded:
       
   251      "[| G \<in> preserves merge.iOut; G \<in> preserves merge.Out; M \<in> Allowed G |]  
       
   252       ==> M Join G \<in> Always {s. \<forall>elt \<in> set (merge.iOut s). elt < Nclients}"
       
   253 apply (cut_tac Merge_spec)
       
   254 apply (force dest: guaranteesD simp add: merge_spec_def merge_bounded_def)
       
   255 done
       
   256 
       
   257 lemma (in Merge) Merge_Bag_Follows_lemma:
       
   258      "[| G \<in> preserves merge.iOut; G \<in> preserves merge.Out; M \<in> Allowed G |]  
       
   259   ==> M Join G \<in> Always  
       
   260           {s. (\<Sum>i: lessThan Nclients. bag_of (sublist (merge.Out s)  
       
   261                                   {k. k < length (iOut s) & iOut s ! k = i})) =  
       
   262               (bag_of o merge.Out) s}"
       
   263 apply (rule Always_Compl_Un_eq [THEN iffD1]) 
       
   264 apply (blast intro: Always_Int_I [OF Merge_Always_Out_eq_iOut Merge_Bounded]) 
       
   265 apply (rule UNIV_AlwaysI, clarify) 
       
   266 apply (subst bag_of_sublist_UN_disjoint [symmetric])
       
   267   apply (simp)
       
   268  apply blast
       
   269 apply (simp add: set_conv_nth)
       
   270 apply (subgoal_tac
       
   271        "(\<Union>i \<in> lessThan Nclients. {k. k < length (iOut x) & iOut x ! k = i}) =
       
   272        lessThan (length (iOut x))")
       
   273  apply (simp (no_asm_simp) add: o_def)
       
   274 apply blast
       
   275 done
       
   276 
       
   277 lemma (in Merge) Merge_Bag_Follows:
       
   278      "M \<in> (\<Inter>i \<in> lessThan Nclients. Increasing (sub i o merge.In))  
       
   279           guarantees   
       
   280              (bag_of o merge.Out) Fols  
       
   281              (%s. \<Sum>i: lessThan Nclients. (bag_of o sub i o merge.In) s)"
       
   282 apply (rule Merge_Bag_Follows_lemma [THEN Always_Follows1, THEN guaranteesI], auto)
       
   283 apply (rule Follows_setsum)
       
   284 apply (cut_tac Merge_spec)
       
   285 apply (auto simp add: merge_spec_def merge_follows_def o_def)
       
   286 apply (drule guaranteesD) 
       
   287   prefer 3
       
   288   apply (best intro: mono_bag_of [THEN mono_Follows_apply, THEN subsetD], auto)
       
   289 done
       
   290 
       
   291 
       
   292 subsection{*Theorems for Distributor*}
       
   293 
       
   294 lemma (in Distrib) Distr_Increasing_Out:
       
   295      "D \<in> Increasing distr.In Int Increasing distr.iIn Int  
       
   296           Always {s. \<forall>elt \<in> set (distr.iIn s). elt < Nclients}  
       
   297           guarantees  
       
   298           (\<Inter>i \<in> lessThan Nclients. Increasing (sub i o distr.Out))"
       
   299 apply (cut_tac Distrib_spec)
       
   300 apply (simp add: distr_spec_def distr_follows_def)
       
   301 apply clarify
       
   302 apply (blast intro: guaranteesI Follows_Increasing1 dest: guaranteesD)
       
   303 done
       
   304 
       
   305 lemma (in Distrib) Distr_Bag_Follows_lemma:
       
   306      "[| G \<in> preserves distr.Out;  
       
   307          D Join G \<in> Always {s. \<forall>elt \<in> set (distr.iIn s). elt < Nclients} |]  
       
   308   ==> D Join G \<in> Always  
       
   309           {s. (\<Sum>i \<in> lessThan Nclients. bag_of (sublist (distr.In s)  
       
   310                                   {k. k < length (iIn s) & iIn s ! k = i})) =  
       
   311               bag_of (sublist (distr.In s) (lessThan (length (iIn s))))}"
       
   312 apply (erule Always_Compl_Un_eq [THEN iffD1])
       
   313 apply (rule UNIV_AlwaysI, clarify)
       
   314 apply (subst bag_of_sublist_UN_disjoint [symmetric])
       
   315   apply (simp (no_asm))
       
   316  apply blast
       
   317 apply (simp add: set_conv_nth)
       
   318 apply (subgoal_tac
       
   319        "(\<Union>i \<in> lessThan Nclients. {k. k < length (iIn x) & iIn x ! k = i}) = 
       
   320         lessThan (length (iIn x))")
       
   321  apply (simp (no_asm_simp))
       
   322 apply blast
       
   323 done
       
   324 
       
   325 lemma (in Distrib) D_ok_iff [iff]:
       
   326      "D ok G = (G \<in> preserves distr.Out & D \<in> Allowed G)"
       
   327 apply (cut_tac Distrib_spec)
       
   328 apply (auto simp add: distr_spec_def distr_allowed_acts_def Allowed_def 
       
   329                       safety_prop_Acts_iff ok_iff_Allowed)
       
   330 done
       
   331 
       
   332 lemma (in Distrib) Distr_Bag_Follows: 
       
   333  "D \<in> Increasing distr.In Int Increasing distr.iIn Int  
       
   334       Always {s. \<forall>elt \<in> set (distr.iIn s). elt < Nclients}  
       
   335       guarantees   
       
   336        (\<Inter>i \<in> lessThan Nclients.  
       
   337         (%s. \<Sum>i: lessThan Nclients. (bag_of o sub i o distr.Out) s)  
       
   338         Fols  
       
   339         (%s. bag_of (sublist (distr.In s) (lessThan (length(distr.iIn s))))))"
       
   340 apply (rule guaranteesI, clarify)
       
   341 apply (rule Distr_Bag_Follows_lemma [THEN Always_Follows2], auto)
       
   342 apply (rule Follows_setsum)
       
   343 apply (cut_tac Distrib_spec)
       
   344 apply (auto simp add: distr_spec_def distr_follows_def o_def)
       
   345 apply (drule guaranteesD)
       
   346   prefer 3
       
   347   apply (best intro: mono_bag_of [THEN mono_Follows_apply, THEN subsetD], auto)
       
   348 done
       
   349 
       
   350 
       
   351 subsection{*Theorems for Allocator*}
       
   352 
       
   353 lemma alloc_refinement_lemma:
       
   354      "!!f::nat=>nat. (\<Inter>i \<in> lessThan n. {s. f i <= g i s})   
       
   355       <= {s. (\<Sum>x \<in> lessThan n. f x) <= (\<Sum>x: lessThan n. g x s)}"
       
   356 apply (induct_tac "n")
       
   357 apply (auto simp add: lessThan_Suc)
       
   358 done
       
   359 
       
   360 lemma alloc_refinement: 
       
   361 "(\<Inter>i \<in> lessThan Nclients. Increasing (sub i o allocAsk) Int   
       
   362                              Increasing (sub i o allocRel))      
       
   363   Int    
       
   364   Always {s. \<forall>i. i<Nclients -->       
       
   365               (\<forall>elt \<in> set ((sub i o allocAsk) s). elt <= NbT)}        
       
   366   Int    
       
   367   (\<Inter>i \<in> lessThan Nclients.    
       
   368    \<Inter>h. {s. h <= (sub i o allocGiv)s & h pfixGe (sub i o allocAsk)s}   
       
   369            LeadsTo {s. tokens h <= (tokens o sub i o allocRel)s})         
       
   370   <=      
       
   371  (\<Inter>i \<in> lessThan Nclients. Increasing (sub i o allocAsk) Int   
       
   372                              Increasing (sub i o allocRel))      
       
   373   Int    
       
   374   Always {s. \<forall>i. i<Nclients -->       
       
   375               (\<forall>elt \<in> set ((sub i o allocAsk) s). elt <= NbT)}        
       
   376   Int    
       
   377   (\<Inter>hf. (\<Inter>i \<in> lessThan Nclients.   
       
   378          {s. hf i <= (sub i o allocGiv)s & hf i pfixGe (sub i o allocAsk)s})  
       
   379   LeadsTo {s. (\<Sum>i: lessThan Nclients. tokens (hf i)) <=          
       
   380     (\<Sum>i: lessThan Nclients. (tokens o sub i o allocRel)s)})"
       
   381 apply (auto simp add: ball_conj_distrib)
       
   382 apply (rename_tac F hf)
       
   383 apply (rule LeadsTo_weaken_R [OF Finite_stable_completion alloc_refinement_lemma], blast, blast)
       
   384 apply (subgoal_tac "F \<in> Increasing (tokens o (sub i o allocRel))")
       
   385  apply (simp add: Increasing_def o_assoc)
       
   386 apply (blast intro: mono_tokens [THEN mono_Increasing_o, THEN subsetD])
       
   387 done
       
   388 
   224 end
   389 end