src/ZF/UNITY/ClientImpl.thy
changeset 46953 2b6e55924af3
parent 46823 57bf0cecb366
child 58860 fee7cfa69c50
equal deleted inserted replaced
46952:5e1bcfdcb175 46953:2b6e55924af3
    12 abbreviation "rel == Var([1])" (* input history: tokens released *)
    12 abbreviation "rel == Var([1])" (* input history: tokens released *)
    13 abbreviation "tok == Var([2])" (* the number of available tokens *)
    13 abbreviation "tok == Var([2])" (* the number of available tokens *)
    14 
    14 
    15 axiomatization where
    15 axiomatization where
    16   type_assumes:
    16   type_assumes:
    17   "type_of(ask) = list(tokbag) & type_of(giv) = list(tokbag) & 
    17   "type_of(ask) = list(tokbag) & type_of(giv) = list(tokbag) &
    18    type_of(rel) = list(tokbag) & type_of(tok) = nat" and
    18    type_of(rel) = list(tokbag) & type_of(tok) = nat" and
    19   default_val_assumes:
    19   default_val_assumes:
    20   "default_val(ask) = Nil & default_val(giv) = Nil & 
    20   "default_val(ask) = Nil & default_val(giv) = Nil &
    21    default_val(rel) = Nil & default_val(tok) = 0"
    21    default_val(rel) = Nil & default_val(tok) = 0"
    22 
    22 
    23 
    23 
    24 (*Array indexing is translated to list indexing as A[n] == nth(n-1,A). *)
    24 (*Array indexing is translated to list indexing as A[n] == nth(n-1,A). *)
    25 
    25 
    29      {<s,t> \<in> state*state.
    29      {<s,t> \<in> state*state.
    30       \<exists>nrel \<in> nat. nrel = length(s`rel) &
    30       \<exists>nrel \<in> nat. nrel = length(s`rel) &
    31                    t = s(rel:=(s`rel)@[nth(nrel, s`giv)]) &
    31                    t = s(rel:=(s`rel)@[nth(nrel, s`giv)]) &
    32                    nrel < length(s`giv) &
    32                    nrel < length(s`giv) &
    33                    nth(nrel, s`ask) \<le> nth(nrel, s`giv)}"
    33                    nth(nrel, s`ask) \<le> nth(nrel, s`giv)}"
    34   
    34 
    35   (** Choose a new token requirement **)
    35   (** Choose a new token requirement **)
    36   (** Including t=s suppresses fairness, allowing the non-trivial part
    36   (** Including t=s suppresses fairness, allowing the non-trivial part
    37       of the action to be ignored **)
    37       of the action to be ignored **)
    38 definition
    38 definition
    39   "client_tok_act == {<s,t> \<in> state*state. t=s |
    39   "client_tok_act == {<s,t> \<in> state*state. t=s |
    40                      t = s(tok:=succ(s`tok mod NbT))}"
    40                      t = s(tok:=succ(s`tok mod NbT))}"
    41 
    41 
    42 definition
    42 definition
    43   "client_ask_act == {<s,t> \<in> state*state. t=s | (t=s(ask:=s`ask@[s`tok]))}"
    43   "client_ask_act == {<s,t> \<in> state*state. t=s | (t=s(ask:=s`ask@[s`tok]))}"
    44   
    44 
    45 definition
    45 definition
    46   "client_prog ==
    46   "client_prog ==
    47    mk_program({s \<in> state. s`tok \<le> NbT & s`giv = Nil &
    47    mk_program({s \<in> state. s`tok \<le> NbT & s`giv = Nil &
    48                        s`ask = Nil & s`rel = Nil},
    48                        s`ask = Nil & s`rel = Nil},
    49                     {client_rel_act, client_tok_act, client_ask_act},
    49                     {client_rel_act, client_tok_act, client_ask_act},
    89 declare  client_rel_act_def [THEN def_act_simp, simp]
    89 declare  client_rel_act_def [THEN def_act_simp, simp]
    90 declare  client_tok_act_def [THEN def_act_simp, simp]
    90 declare  client_tok_act_def [THEN def_act_simp, simp]
    91 declare  client_ask_act_def [THEN def_act_simp, simp]
    91 declare  client_ask_act_def [THEN def_act_simp, simp]
    92 
    92 
    93 lemma client_prog_ok_iff:
    93 lemma client_prog_ok_iff:
    94   "\<forall>G \<in> program. (client_prog ok G) \<longleftrightarrow>  
    94   "\<forall>G \<in> program. (client_prog ok G) \<longleftrightarrow>
    95    (G \<in> preserves(lift(rel)) & G \<in> preserves(lift(ask)) &  
    95    (G \<in> preserves(lift(rel)) & G \<in> preserves(lift(ask)) &
    96     G \<in> preserves(lift(tok)) &  client_prog \<in> Allowed(G))"
    96     G \<in> preserves(lift(tok)) &  client_prog \<in> Allowed(G))"
    97 by (auto simp add: ok_iff_Allowed client_prog_def [THEN def_prg_Allowed])
    97 by (auto simp add: ok_iff_Allowed client_prog_def [THEN def_prg_Allowed])
    98 
    98 
    99 lemma client_prog_preserves:
    99 lemma client_prog_preserves:
   100     "client_prog:(\<Inter>x \<in> var-{ask, rel, tok}. preserves(lift(x)))"
   100     "client_prog:(\<Inter>x \<in> var-{ask, rel, tok}. preserves(lift(x)))"
   105 
   105 
   106 
   106 
   107 lemma preserves_lift_imp_stable:
   107 lemma preserves_lift_imp_stable:
   108      "G \<in> preserves(lift(ff)) ==> G \<in> stable({s \<in> state. P(s`ff)})";
   108      "G \<in> preserves(lift(ff)) ==> G \<in> stable({s \<in> state. P(s`ff)})";
   109 apply (drule preserves_imp_stable)
   109 apply (drule preserves_imp_stable)
   110 apply (simp add: lift_def) 
   110 apply (simp add: lift_def)
   111 done
   111 done
   112 
   112 
   113 lemma preserves_imp_prefix:
   113 lemma preserves_imp_prefix:
   114      "G \<in> preserves(lift(ff)) 
   114      "G \<in> preserves(lift(ff))
   115       ==> G \<in> stable({s \<in> state. \<langle>k, s`ff\<rangle> \<in> prefix(nat)})";
   115       ==> G \<in> stable({s \<in> state. \<langle>k, s`ff\<rangle> \<in> prefix(nat)})";
   116 by (erule preserves_lift_imp_stable) 
   116 by (erule preserves_lift_imp_stable)
   117 
   117 
   118 (*Safety property 1: ask, rel are increasing: (24) *)
   118 (*Safety property 1 \<in> ask, rel are increasing: (24) *)
   119 lemma client_prog_Increasing_ask_rel: 
   119 lemma client_prog_Increasing_ask_rel:
   120 "client_prog: program guarantees Incr(lift(ask)) \<inter> Incr(lift(rel))"
   120 "client_prog: program guarantees Incr(lift(ask)) \<inter> Incr(lift(rel))"
   121 apply (unfold guar_def)
   121 apply (unfold guar_def)
   122 apply (auto intro!: increasing_imp_Increasing 
   122 apply (auto intro!: increasing_imp_Increasing
   123             simp add: client_prog_ok_iff Increasing.increasing_def preserves_imp_prefix)
   123             simp add: client_prog_ok_iff Increasing.increasing_def preserves_imp_prefix)
   124 apply (safety, force, force)+
   124 apply (safety, force, force)+
   125 done
   125 done
   126 
   126 
   127 declare nth_append [simp] append_one_prefix [simp]
   127 declare nth_append [simp] append_one_prefix [simp]
   129 lemma NbT_pos2: "0<NbT"
   129 lemma NbT_pos2: "0<NbT"
   130 apply (cut_tac NbT_pos)
   130 apply (cut_tac NbT_pos)
   131 apply (rule Ord_0_lt, auto)
   131 apply (rule Ord_0_lt, auto)
   132 done
   132 done
   133 
   133 
   134 (*Safety property 2: the client never requests too many tokens.
   134 (*Safety property 2 \<in> the client never requests too many tokens.
   135 With no Substitution Axiom, we must prove the two invariants simultaneously. *)
   135 With no Substitution Axiom, we must prove the two invariants simultaneously. *)
   136 
   136 
   137 lemma ask_Bounded_lemma: 
   137 lemma ask_Bounded_lemma:
   138 "[| client_prog ok G; G \<in> program |] 
   138 "[| client_prog ok G; G \<in> program |]
   139       ==> client_prog \<squnion> G \<in>    
   139       ==> client_prog \<squnion> G \<in>
   140               Always({s \<in> state. s`tok \<le> NbT}  \<inter>   
   140               Always({s \<in> state. s`tok \<le> NbT}  \<inter>
   141                       {s \<in> state. \<forall>elt \<in> set_of_list(s`ask). elt \<le> NbT})"
   141                       {s \<in> state. \<forall>elt \<in> set_of_list(s`ask). elt \<le> NbT})"
   142 apply (rotate_tac -1)
   142 apply (rotate_tac -1)
   143 apply (auto simp add: client_prog_ok_iff)
   143 apply (auto simp add: client_prog_ok_iff)
   144 apply (rule invariantI [THEN stable_Join_Always2], force) 
   144 apply (rule invariantI [THEN stable_Join_Always2], force)
   145  prefer 2
   145  prefer 2
   146  apply (fast intro: stable_Int preserves_lift_imp_stable, safety)
   146  apply (fast intro: stable_Int preserves_lift_imp_stable, safety)
   147 apply (auto dest: ActsD)
   147 apply (auto dest: ActsD)
   148 apply (cut_tac NbT_pos)
   148 apply (cut_tac NbT_pos)
   149 apply (rule NbT_pos2 [THEN mod_less_divisor])
   149 apply (rule NbT_pos2 [THEN mod_less_divisor])
   150 apply (auto dest: ActsD preserves_imp_eq simp add: set_of_list_append)
   150 apply (auto dest: ActsD preserves_imp_eq simp add: set_of_list_append)
   151 done
   151 done
   152 
   152 
   153 (* Export version, with no mention of tok in the postcondition, but
   153 (* Export version, with no mention of tok in the postcondition, but
   154   unfortunately tok must be declared local.*)
   154   unfortunately tok must be declared local.*)
   155 lemma client_prog_ask_Bounded: 
   155 lemma client_prog_ask_Bounded:
   156     "client_prog \<in> program guarantees  
   156     "client_prog \<in> program guarantees
   157                    Always({s \<in> state. \<forall>elt \<in> set_of_list(s`ask). elt \<le> NbT})"
   157                    Always({s \<in> state. \<forall>elt \<in> set_of_list(s`ask). elt \<le> NbT})"
   158 apply (rule guaranteesI)
   158 apply (rule guaranteesI)
   159 apply (erule ask_Bounded_lemma [THEN Always_weaken], auto)
   159 apply (erule ask_Bounded_lemma [THEN Always_weaken], auto)
   160 done
   160 done
   161 
   161 
   162 (*** Towards proving the liveness property ***)
   162 (*** Towards proving the liveness property ***)
   163 
   163 
   164 lemma client_prog_stable_rel_le_giv: 
   164 lemma client_prog_stable_rel_le_giv:
   165     "client_prog \<in> stable({s \<in> state. <s`rel, s`giv> \<in> prefix(nat)})"
   165     "client_prog \<in> stable({s \<in> state. <s`rel, s`giv> \<in> prefix(nat)})"
   166 by (safety, auto)
   166 by (safety, auto)
   167 
   167 
   168 lemma client_prog_Join_Stable_rel_le_giv: 
   168 lemma client_prog_Join_Stable_rel_le_giv:
   169 "[| client_prog \<squnion> G \<in> Incr(lift(giv)); G \<in> preserves(lift(rel)) |]  
   169 "[| client_prog \<squnion> G \<in> Incr(lift(giv)); G \<in> preserves(lift(rel)) |]
   170     ==> client_prog \<squnion> G \<in> Stable({s \<in> state. <s`rel, s`giv> \<in> prefix(nat)})"
   170     ==> client_prog \<squnion> G \<in> Stable({s \<in> state. <s`rel, s`giv> \<in> prefix(nat)})"
   171 apply (rule client_prog_stable_rel_le_giv [THEN Increasing_preserves_Stable])
   171 apply (rule client_prog_stable_rel_le_giv [THEN Increasing_preserves_Stable])
   172 apply (auto simp add: lift_def)
   172 apply (auto simp add: lift_def)
   173 done
   173 done
   174 
   174 
   175 lemma client_prog_Join_Always_rel_le_giv:
   175 lemma client_prog_Join_Always_rel_le_giv:
   176      "[| client_prog \<squnion> G \<in> Incr(lift(giv)); G \<in> preserves(lift(rel)) |]  
   176      "[| client_prog \<squnion> G \<in> Incr(lift(giv)); G \<in> preserves(lift(rel)) |]
   177     ==> client_prog \<squnion> G  \<in> Always({s \<in> state. <s`rel, s`giv> \<in> prefix(nat)})"
   177     ==> client_prog \<squnion> G  \<in> Always({s \<in> state. <s`rel, s`giv> \<in> prefix(nat)})"
   178 by (force intro!: AlwaysI client_prog_Join_Stable_rel_le_giv)
   178 by (force intro!: AlwaysI client_prog_Join_Stable_rel_le_giv)
   179 
   179 
   180 lemma def_act_eq:
   180 lemma def_act_eq:
   181      "A == {<s, t> \<in> state*state. P(s, t)} ==> A={<s, t> \<in> state*state. P(s, t)}"
   181      "A == {<s, t> \<in> state*state. P(s, t)} ==> A={<s, t> \<in> state*state. P(s, t)}"
   182 by auto
   182 by auto
   183 
   183 
   184 lemma act_subset: "A={<s,t> \<in> state*state. P(s, t)} ==> A<=state*state"
   184 lemma act_subset: "A={<s,t> \<in> state*state. P(s, t)} ==> A<=state*state"
   185 by auto
   185 by auto
   186 
   186 
   187 lemma transient_lemma: 
   187 lemma transient_lemma:
   188 "client_prog \<in>  
   188 "client_prog \<in>
   189   transient({s \<in> state. s`rel = k & <k, h> \<in> strict_prefix(nat)  
   189   transient({s \<in> state. s`rel = k & <k, h> \<in> strict_prefix(nat)
   190    & <h, s`giv> \<in> prefix(nat) & h pfixGe s`ask})"
   190    & <h, s`giv> \<in> prefix(nat) & h pfixGe s`ask})"
   191 apply (rule_tac act = client_rel_act in transientI)
   191 apply (rule_tac act = client_rel_act in transientI)
   192 apply (simp (no_asm) add: client_prog_def [THEN def_prg_Acts])
   192 apply (simp (no_asm) add: client_prog_def [THEN def_prg_Acts])
   193 apply (simp (no_asm) add: client_rel_act_def [THEN def_act_eq, THEN act_subset])
   193 apply (simp (no_asm) add: client_rel_act_def [THEN def_act_eq, THEN act_subset])
   194 apply (auto simp add: client_prog_def [THEN def_prg_Acts] domain_def)
   194 apply (auto simp add: client_prog_def [THEN def_prg_Acts] domain_def)
   206 apply auto
   206 apply auto
   207 apply (simp (no_asm_use) add: gen_prefix_iff_nth)
   207 apply (simp (no_asm_use) add: gen_prefix_iff_nth)
   208 apply (auto simp add: id_def lam_def)
   208 apply (auto simp add: id_def lam_def)
   209 done
   209 done
   210 
   210 
   211 lemma strict_prefix_is_prefix: 
   211 lemma strict_prefix_is_prefix:
   212     "<xs, ys> \<in> strict_prefix(A) \<longleftrightarrow>  <xs, ys> \<in> prefix(A) & xs\<noteq>ys"
   212     "<xs, ys> \<in> strict_prefix(A) \<longleftrightarrow>  <xs, ys> \<in> prefix(A) & xs\<noteq>ys"
   213 apply (unfold strict_prefix_def id_def lam_def)
   213 apply (unfold strict_prefix_def id_def lam_def)
   214 apply (auto dest: prefix_type [THEN subsetD])
   214 apply (auto dest: prefix_type [THEN subsetD])
   215 done
   215 done
   216 
   216 
   217 lemma induct_lemma: 
   217 lemma induct_lemma:
   218 "[| client_prog \<squnion> G \<in> Incr(lift(giv)); client_prog ok G; G \<in> program |]  
   218 "[| client_prog \<squnion> G \<in> Incr(lift(giv)); client_prog ok G; G \<in> program |]
   219   ==> client_prog \<squnion> G \<in>  
   219   ==> client_prog \<squnion> G \<in>
   220   {s \<in> state. s`rel = k & <k,h> \<in> strict_prefix(nat)  
   220   {s \<in> state. s`rel = k & <k,h> \<in> strict_prefix(nat)
   221    & <h, s`giv> \<in> prefix(nat) & h pfixGe s`ask}   
   221    & <h, s`giv> \<in> prefix(nat) & h pfixGe s`ask}
   222         LeadsTo {s \<in> state. <k, s`rel> \<in> strict_prefix(nat)  
   222         LeadsTo {s \<in> state. <k, s`rel> \<in> strict_prefix(nat)
   223                           & <s`rel, s`giv> \<in> prefix(nat) &  
   223                           & <s`rel, s`giv> \<in> prefix(nat) &
   224                                   <h, s`giv> \<in> prefix(nat) &  
   224                                   <h, s`giv> \<in> prefix(nat) &
   225                 h pfixGe s`ask}"
   225                 h pfixGe s`ask}"
   226 apply (rule single_LeadsTo_I)
   226 apply (rule single_LeadsTo_I)
   227  prefer 2 apply simp
   227  prefer 2 apply simp
   228 apply (frule client_prog_Increasing_ask_rel [THEN guaranteesD])
   228 apply (frule client_prog_Increasing_ask_rel [THEN guaranteesD])
   229 apply (rotate_tac [3] 2)
   229 apply (rotate_tac [3] 2)
   237 apply (erule_tac f = "lift (rel) " and a = "s`rel" in Increasing_imp_Stable)
   237 apply (erule_tac f = "lift (rel) " and a = "s`rel" in Increasing_imp_Stable)
   238 apply (simp (no_asm_simp))
   238 apply (simp (no_asm_simp))
   239 apply (erule client_prog_Join_Stable_rel_le_giv, blast, simp_all)
   239 apply (erule client_prog_Join_Stable_rel_le_giv, blast, simp_all)
   240  prefer 2
   240  prefer 2
   241  apply (blast intro: sym strict_prefix_is_prefix [THEN iffD2] prefix_trans prefix_imp_pfixGe pfixGe_trans)
   241  apply (blast intro: sym strict_prefix_is_prefix [THEN iffD2] prefix_trans prefix_imp_pfixGe pfixGe_trans)
   242 apply (auto intro: strict_prefix_is_prefix [THEN iffD1, THEN conjunct1] 
   242 apply (auto intro: strict_prefix_is_prefix [THEN iffD1, THEN conjunct1]
   243                    prefix_trans)
   243                    prefix_trans)
   244 done
   244 done
   245 
   245 
   246 lemma rel_progress_lemma: 
   246 lemma rel_progress_lemma:
   247 "[| client_prog \<squnion> G  \<in> Incr(lift(giv)); client_prog ok G; G \<in> program |]  
   247 "[| client_prog \<squnion> G  \<in> Incr(lift(giv)); client_prog ok G; G \<in> program |]
   248   ==> client_prog \<squnion> G  \<in>  
   248   ==> client_prog \<squnion> G  \<in>
   249      {s \<in> state. <s`rel, h> \<in> strict_prefix(nat)  
   249      {s \<in> state. <s`rel, h> \<in> strict_prefix(nat)
   250            & <h, s`giv> \<in> prefix(nat) & h pfixGe s`ask}   
   250            & <h, s`giv> \<in> prefix(nat) & h pfixGe s`ask}
   251                       LeadsTo {s \<in> state. <h, s`rel> \<in> prefix(nat)}"
   251                       LeadsTo {s \<in> state. <h, s`rel> \<in> prefix(nat)}"
   252 apply (rule_tac f = "\<lambda>x \<in> state. length(h) #- length(x`rel)" 
   252 apply (rule_tac f = "\<lambda>x \<in> state. length(h) #- length(x`rel)"
   253        in LessThan_induct)
   253        in LessThan_induct)
   254 apply (auto simp add: vimage_def)
   254 apply (auto simp add: vimage_def)
   255  prefer 2 apply (force simp add: lam_def) 
   255  prefer 2 apply (force simp add: lam_def)
   256 apply (rule single_LeadsTo_I)
   256 apply (rule single_LeadsTo_I)
   257  prefer 2 apply simp 
   257  prefer 2 apply simp
   258 apply (subgoal_tac "h \<in> list(nat)")
   258 apply (subgoal_tac "h \<in> list(nat)")
   259  prefer 2 apply (blast dest: prefix_type [THEN subsetD]) 
   259  prefer 2 apply (blast dest: prefix_type [THEN subsetD])
   260 apply (rule induct_lemma [THEN LeadsTo_weaken])
   260 apply (rule induct_lemma [THEN LeadsTo_weaken])
   261     apply (simp add: length_type lam_def)
   261     apply (simp add: length_type lam_def)
   262 apply (auto intro: strict_prefix_is_prefix [THEN iffD2]
   262 apply (auto intro: strict_prefix_is_prefix [THEN iffD2]
   263             dest: common_prefix_linear  prefix_type [THEN subsetD])
   263             dest: common_prefix_linear  prefix_type [THEN subsetD])
   264 apply (erule swap)
   264 apply (erule swap)
   265 apply (rule imageI)
   265 apply (rule imageI)
   266  apply (force dest!: simp add: lam_def) 
   266  apply (force dest!: simp add: lam_def)
   267 apply (simp add: length_type lam_def, clarify) 
   267 apply (simp add: length_type lam_def, clarify)
   268 apply (drule strict_prefix_length_lt)+
   268 apply (drule strict_prefix_length_lt)+
   269 apply (drule less_imp_succ_add, simp)+
   269 apply (drule less_imp_succ_add, simp)+
   270 apply clarify 
   270 apply clarify
   271 apply simp 
   271 apply simp
   272 apply (erule diff_le_self [THEN ltD])
   272 apply (erule diff_le_self [THEN ltD])
   273 done
   273 done
   274 
   274 
   275 lemma progress_lemma: 
   275 lemma progress_lemma:
   276 "[| client_prog \<squnion> G \<in> Incr(lift(giv)); client_prog ok G; G \<in> program |] 
   276 "[| client_prog \<squnion> G \<in> Incr(lift(giv)); client_prog ok G; G \<in> program |]
   277  ==> client_prog \<squnion> G
   277  ==> client_prog \<squnion> G
   278        \<in> {s \<in> state. <h, s`giv> \<in> prefix(nat) & h pfixGe s`ask}   
   278        \<in> {s \<in> state. <h, s`giv> \<in> prefix(nat) & h pfixGe s`ask}
   279          LeadsTo  {s \<in> state. <h, s`rel> \<in> prefix(nat)}"
   279          LeadsTo  {s \<in> state. <h, s`rel> \<in> prefix(nat)}"
   280 apply (rule client_prog_Join_Always_rel_le_giv [THEN Always_LeadsToI], 
   280 apply (rule client_prog_Join_Always_rel_le_giv [THEN Always_LeadsToI],
   281        assumption)
   281        assumption)
   282 apply (force simp add: client_prog_ok_iff)
   282 apply (force simp add: client_prog_ok_iff)
   283 apply (rule LeadsTo_weaken_L) 
   283 apply (rule LeadsTo_weaken_L)
   284 apply (rule LeadsTo_Un [OF rel_progress_lemma 
   284 apply (rule LeadsTo_Un [OF rel_progress_lemma
   285                            subset_refl [THEN subset_imp_LeadsTo]])
   285                            subset_refl [THEN subset_imp_LeadsTo]])
   286 apply (auto intro: strict_prefix_is_prefix [THEN iffD2]
   286 apply (auto intro: strict_prefix_is_prefix [THEN iffD2]
   287             dest: common_prefix_linear prefix_type [THEN subsetD])
   287             dest: common_prefix_linear prefix_type [THEN subsetD])
   288 done
   288 done
   289 
   289 
   290 (*Progress property: all tokens that are given will be released*)
   290 (*Progress property: all tokens that are given will be released*)
   291 lemma client_prog_progress: 
   291 lemma client_prog_progress:
   292 "client_prog \<in> Incr(lift(giv))  guarantees   
   292 "client_prog \<in> Incr(lift(giv))  guarantees
   293       (\<Inter>h \<in> list(nat). {s \<in> state. <h, s`giv> \<in> prefix(nat) & 
   293       (\<Inter>h \<in> list(nat). {s \<in> state. <h, s`giv> \<in> prefix(nat) &
   294               h pfixGe s`ask} LeadsTo {s \<in> state. <h, s`rel> \<in> prefix(nat)})"
   294               h pfixGe s`ask} LeadsTo {s \<in> state. <h, s`rel> \<in> prefix(nat)})"
   295 apply (rule guaranteesI)
   295 apply (rule guaranteesI)
   296 apply (blast intro: progress_lemma, auto)
   296 apply (blast intro: progress_lemma, auto)
   297 done
   297 done
   298 
   298 
   299 lemma client_prog_Allowed:
   299 lemma client_prog_Allowed:
   300      "Allowed(client_prog) =  
   300      "Allowed(client_prog) =
   301       preserves(lift(rel)) \<inter> preserves(lift(ask)) \<inter> preserves(lift(tok))"
   301       preserves(lift(rel)) \<inter> preserves(lift(ask)) \<inter> preserves(lift(tok))"
   302 apply (cut_tac v = "lift (ask)" in preserves_type)
   302 apply (cut_tac v = "lift (ask)" in preserves_type)
   303 apply (auto simp add: Allowed_def client_prog_def [THEN def_prg_Allowed] 
   303 apply (auto simp add: Allowed_def client_prog_def [THEN def_prg_Allowed]
   304                       cons_Int_distrib safety_prop_Acts_iff)
   304                       cons_Int_distrib safety_prop_Acts_iff)
   305 done
   305 done
   306 
   306 
   307 end
   307 end