src/HOL/UNITY/Client.ML
changeset 8216 e4b3192dfefa
parent 8055 bb15396278fb
child 8251 9be357df93d4
equal deleted inserted replaced
8215:d3eba67a9e67 8216:e4b3192dfefa
     4     Copyright   1998  University of Cambridge
     4     Copyright   1998  University of Cambridge
     5 
     5 
     6 Distributed Resource Management System: the Client
     6 Distributed Resource Management System: the Client
     7 *)
     7 *)
     8 
     8 
     9 
     9 Addsimps [Client_def RS def_prg_Init];
    10 Addsimps [Cli_prg_def RS def_prg_Init];
    10 program_defs_ref := [Client_def];
    11 program_defs_ref := [Cli_prg_def];
       
    12 
    11 
    13 Addsimps (map simp_of_act [rel_act_def, tok_act_def, ask_act_def]);
    12 Addsimps (map simp_of_act [rel_act_def, tok_act_def, ask_act_def]);
    14 
    13 
    15 
    14 
    16 fun invariant_tac i = 
    15 fun invariant_tac i = 
    17     rtac invariantI i  THEN
    16     rtac invariantI i  THEN
    18     constrains_tac (i+1);
    17     constrains_tac (i+1);
    19 
    18 
    20 (*Safety property 1(a): ask is nondecreasing*)
    19 
    21 Goalw [increasing_def] "Cli_prg: increasing ask";
    20 (*Safety property 1: ask, rel are increasing*)
    22 by (Clarify_tac 1);
    21 Goal "Client: UNIV guarantees[funPair rel ask] \
    23 by (constrains_tac 1);
    22 \             Increasing ask Int Increasing rel";
       
    23 by (safe_tac (claset() addSIs [guaranteesI,increasing_imp_Increasing]));
       
    24 by (auto_tac
       
    25     (claset(),
       
    26      simpset() addsimps [impOfSubs preserves_subset_increasing,
       
    27 			 Join_increasing]));
       
    28 by (auto_tac (claset(), simpset() addsimps [increasing_def]));
       
    29 by (ALLGOALS constrains_tac);
    24 by Auto_tac;
    30 by Auto_tac;
    25 qed "increasing_ask";
    31 qed "increasing_ask_rel";
    26 
    32 
    27 (*Safety property 1(b): rel is nondecreasing*)
       
    28 Goalw [increasing_def] "Cli_prg: increasing rel";
       
    29 by (Clarify_tac 1);
       
    30 by (constrains_tac 1);
       
    31 by Auto_tac;
       
    32 qed "increasing_rel";
       
    33 
    33 
    34 Addsimps [nth_append, append_one_prefix];
    34 Addsimps [nth_append, append_one_prefix];
    35 
    35 
    36 Goal "Cli_prg: invariant {s. tok s <= Max}";
    36 
    37 by (invariant_tac 1);
    37 (*Safety property 2: the client never requests too many tokens.
       
    38       With no Substitution Axiom, we must prove the two invariants 
       
    39   simultaneously.
       
    40 *)
       
    41 Goal "G : preserves (funPair ask tok)  \
       
    42 \     ==> Client Join G :  \
       
    43 \             Always ({s. tok s <= NbT}  Int  \
       
    44 \                     {s. ALL elt : set (ask s). elt <= NbT})";
       
    45 by (rtac (invariantI RS stable_Join_Always2) 1);
       
    46 by (fast_tac (claset() addSEs [impOfSubs preserves_subset_stable]
       
    47 		       addSIs [stable_Int]) 3);
       
    48 by (constrains_tac 2);
    38 by Auto_tac;
    49 by Auto_tac;
    39 qed "tok_bounded";
    50 qed "ask_bounded_lemma";
    40 
    51 
    41 (*Safety property 3: no client requests "too many" tokens.
    52 (*export version, with no mention of tok*)
    42       With no Substitution Axiom, we must prove the two invariants 
    53 Goal "Client: UNIV guarantees[funPair ask tok] \
    43   simultaneously.  Could combine tok_bounded, stable_constrains_stable 
    54 \             Always {s. ALL elt : set (ask s). elt <= NbT}";
    44   and a rule invariant_implies_stable...
    55 by (rtac guaranteesI 1);
    45 *)
    56 by (etac (ask_bounded_lemma RS Always_weaken) 1);
    46 Goal "Cli_prg:                             \
    57 by (rtac Int_lower2 1);
    47 \       invariant ({s. tok s <= Max}  Int  \
       
    48 \                  {s. ALL n: lessThan (size (ask s)). ask s!n <= Max})";
       
    49 by (invariant_tac 1);
       
    50 by (auto_tac (claset() addSEs [less_SucE], simpset()));
       
    51 qed "ask_bounded";
    58 qed "ask_bounded";
    52 
    59 
    53 (** Several facts used to prove Lemma 1 **)
       
    54 
    60 
    55 Goal "Cli_prg: stable {s. rel s <= giv s}";
    61 (*** Towards proving the liveness property ***)
       
    62 
       
    63 Goal "Client: stable {s. rel s <= giv s}";
    56 by (constrains_tac 1);
    64 by (constrains_tac 1);
    57 by Auto_tac;
    65 by Auto_tac;
    58 qed "stable_rel_le_giv";
    66 qed "stable_rel_le_giv";
    59 
    67 
    60 Goal "Cli_prg: stable {s. size (rel s) <= size (giv s)}";
    68 Goal "[| Client Join G : Increasing giv;  G : preserves rel |] \
       
    69 \     ==> Client Join G : Stable {s. rel s <= giv s}";
       
    70 by (rtac (stable_rel_le_giv RS Increasing_preserves_Stable) 1);
       
    71 by Auto_tac;
       
    72 qed "Join_Stable_rel_le_giv";
       
    73 
       
    74 Goal "[| Client Join G : Increasing giv;  G : preserves rel |] \
       
    75 \     ==> Client Join G : Always {s. rel s <= giv s}";
       
    76 by (rtac AlwaysI 1);
       
    77 by (rtac Join_Stable_rel_le_giv 2);
       
    78 by Auto_tac;
       
    79 qed "Join_Always_rel_le_giv";
       
    80 
       
    81 Goal "Client : transient {s. rel s = k & k<h & h <= giv s & h pfixGe ask s}";
       
    82 by (res_inst_tac [("act", "rel_act")] transientI 1);
       
    83 by (auto_tac (claset(),
       
    84 	      simpset() addsimps [Domain_def, Client_def]));
       
    85 by (blast_tac (claset() addIs [less_le_trans, prefix_length_le,
       
    86 			       strict_prefix_length_less]) 1);
       
    87 by (auto_tac (claset(), 
       
    88 	      simpset() addsimps [prefix_def, genPrefix_iff_nth, Ge_def]));
       
    89 by (blast_tac (claset() addIs [strict_prefix_length_less]) 1);
       
    90 qed "transient_lemma";
       
    91 
       
    92 
       
    93 
       
    94 Goal "[| Client Join G : Increasing giv;  G : preserves (funPair rel ask) |] \
       
    95 \ ==> Client Join G : {s. rel s = k & k<h & h <= giv s & h pfixGe ask s}  \
       
    96 \                     LeadsTo {s. k < rel s & rel s <= giv s & \
       
    97 \                                 h <= giv s & h pfixGe ask s}";
       
    98 by (rtac single_LeadsTo_I 1);
       
    99 by (ftac (increasing_ask_rel RS guaranteesD) 1);
       
   100 by Auto_tac;
       
   101 by (rtac (transient_lemma RS Join_transient_I1 RS transient_imp_leadsTo RS 
       
   102 	  leadsTo_imp_LeadsTo RS PSP_Stable RS LeadsTo_weaken) 1);
       
   103 by (rtac (Stable_Int RS Stable_Int RS Stable_Int) 1);
       
   104 by (eres_inst_tac [("f", "giv"), ("x", "giv s")] IncreasingD 1);
       
   105 by (eres_inst_tac [("f", "ask"), ("x", "ask s")] IncreasingD 1);
       
   106 by (eres_inst_tac [("f", "rel"), ("x", "rel s")] IncreasingD 1);
       
   107 by (etac Join_Stable_rel_le_giv 1);
       
   108 by (Blast_tac 1);
       
   109 by (blast_tac (claset() addIs [sym, order_less_le RS iffD2, 
       
   110 			       order_trans, prefix_imp_pfixGe, 
       
   111 			       pfixGe_trans]) 2);
       
   112 by (blast_tac (claset() addIs [order_less_imp_le, order_trans]) 1);
       
   113 qed "induct_lemma";
       
   114 
       
   115 
       
   116 Goal "[| Client Join G : Increasing giv;  G : preserves (funPair rel ask) |] \
       
   117 \ ==> Client Join G : {s. rel s < h & h <= giv s & h pfixGe ask s}  \
       
   118 \                     LeadsTo {s. h <= rel s}";
       
   119 by (res_inst_tac [("f", "%s. size h - size (rel s)")] LessThan_induct 1);
       
   120 by (auto_tac (claset(), simpset() addsimps [vimage_def]));
       
   121 by (rtac single_LeadsTo_I 1);
       
   122 by (rtac (induct_lemma RS LeadsTo_weaken) 1);
       
   123 by Auto_tac;
       
   124 by (blast_tac (claset() addIs [order_less_le RS iffD2]
       
   125 			addDs [common_prefix_linear]) 1);
       
   126 by (REPEAT (dtac strict_prefix_length_less 1));
       
   127 by (arith_tac 1);
       
   128 qed "rel_progress_lemma";
       
   129 
       
   130 
       
   131 Goal "[| Client Join G : Increasing giv;  G : preserves (funPair rel ask) |] \
       
   132 \ ==> Client Join G : {s. h <= giv s & h pfixGe ask s}  \
       
   133 \                     LeadsTo {s. h <= rel s}";
       
   134 by (rtac (Join_Always_rel_le_giv RS Always_LeadsToI) 1);
       
   135 by (rtac ([rel_progress_lemma, subset_refl RS subset_imp_LeadsTo] MRS 
       
   136     LeadsTo_Un RS LeadsTo_weaken_L) 3);
       
   137 by Auto_tac;
       
   138 by (blast_tac (claset() addIs [order_less_le RS iffD2]
       
   139 			addDs [common_prefix_linear]) 1);
       
   140 qed "client_progress_lemma";
       
   141 
       
   142 Goal "Client : \
       
   143 \      Increasing giv  guarantees[funPair rel ask]  \
       
   144 \      (INT h. {s. h <= giv s & h pfixGe ask s} LeadsTo {s. h <= rel s})";
       
   145 by (rtac guaranteesI 1);
       
   146 by (Clarify_tac 1);
       
   147 by (blast_tac (claset() addIs [client_progress_lemma]) 1);
       
   148 qed "client_progress";
       
   149 
       
   150 
       
   151 (** Obsolete lemmas from first version of the Client **)
       
   152 
       
   153 Goal "Client: stable {s. size (rel s) <= size (giv s)}";
    61 by (constrains_tac 1);
   154 by (constrains_tac 1);
    62 by Auto_tac;
   155 by Auto_tac;
    63 qed "stable_size_rel_le_giv";
   156 qed "stable_size_rel_le_giv";
    64 
   157 
    65 Goal "Cli_prg: stable {s. size (ask s) <= Suc (size (rel s))}";
   158 (*clients return the right number of tokens*)
    66 by (constrains_tac 1);
   159 Goal "Client : Increasing giv  guarantees[rel]  Always {s. rel s <= giv s}";
    67 by Auto_tac;
       
    68 qed "stable_size_ask_le_rel";
       
    69 
       
    70 
       
    71 (*We no longer need constrains_tac to expand the program definition, and 
       
    72   expanding it is extremely expensive!*)
       
    73 program_defs_ref := [];
       
    74 
       
    75 (*Safety property 2: clients return the right number of tokens*)
       
    76 Goal "Cli_prg : Increasing giv  guarantees[rel]  Always {s. rel s <= giv s}";
       
    77 by (rtac guaranteesI 1);
   160 by (rtac guaranteesI 1);
    78 by (rtac AlwaysI 1);
   161 by (rtac AlwaysI 1);
    79 by (Force_tac 1);
   162 by (Force_tac 1);
    80 by (blast_tac (claset() addIs [Increasing_preserves_Stable, 
   163 by (blast_tac (claset() addIs [Increasing_preserves_Stable, 
    81 			       stable_rel_le_giv]) 1);
   164 			       stable_rel_le_giv]) 1);
    82 qed "ok_guar_rel_prefix_giv";
   165 qed "ok_guar_rel_prefix_giv";
    83 
       
    84 
       
    85 (*** Towards proving the liveness property ***)
       
    86 
       
    87 Goal "Cli_prg Join G   \
       
    88 \       : transient {s. size (giv s) = Suc k &  \
       
    89 \                       size (rel s) = k & ask s ! k <= giv s ! k}";
       
    90 by (res_inst_tac [("act", "rel_act")] transientI 1);
       
    91 by (auto_tac (claset(),
       
    92 	      simpset() addsimps [Domain_def, Cli_prg_def]));
       
    93 qed "transient_lemma";
       
    94 
       
    95 
       
    96 
       
    97 val rewrite_o = rewrite_rule [o_def];
       
    98 
       
    99 val Increasing_length = mono_length RS mono_Increasing_o;
       
   100 
       
   101 Goal "Cli_prg : \
       
   102 \      Increasing giv  guarantees[funPair rel ask] \
       
   103 \      Always ({s. size (ask s) <= Suc (size (rel s))} Int \
       
   104 \              {s. size (rel s) <= size (giv s)})";
       
   105 by (rtac guaranteesI 1);
       
   106 by (dtac (impOfSubs (rewrite_o Increasing_length)) 1);
       
   107 by (rtac AlwaysI 1);
       
   108 by (Force_tac 1);
       
   109 by (rtac Stable_Int 1);
       
   110 by (fast_tac (claset() addEs [rewrite_o (impOfSubs subset_preserves_o)]
       
   111 	               addIs [Increasing_preserves_Stable, 
       
   112 			      stable_size_rel_le_giv]) 2);
       
   113 by (res_inst_tac [("v1", "ask"), ("w1", "rel")]  
       
   114     (stable_localTo_stable2 RS stable_imp_Stable) 1);
       
   115 by (ALLGOALS 
       
   116     (fast_tac (claset() addEs [rewrite_o (impOfSubs subset_preserves_o)]
       
   117 	                addIs [stable_size_ask_le_rel])));
       
   118 val lemma1 = result();
       
   119 
       
   120 
       
   121 Goal "Cli_prg : \
       
   122 \      Increasing giv Int Always giv_meets_ask \
       
   123 \      guarantees[funPair rel ask]  \
       
   124 \        ({s. k < size (giv s)} LeadsTo {s. k < size (rel s)})";
       
   125 by (rtac guaranteesI 1);
       
   126 by (Clarify_tac 1);
       
   127 by (rtac Stable_transient_Always_LeadsTo 1);
       
   128 by (res_inst_tac [("k", "k")] transient_lemma 2);
       
   129 by (force_tac (claset() addDs [impOfSubs Increasing_length,
       
   130 			       impOfSubs Increasing_Stable_less],
       
   131 	       simpset()) 1);
       
   132 by (rtac (make_elim (lemma1 RS guaranteesD)) 1);
       
   133 by Auto_tac;
       
   134 by (force_tac (claset(), 
       
   135 	       simpset() addsimps [Always_eq_includes_reachable, 
       
   136 				  giv_meets_ask_def]) 1);
       
   137 qed "client_correct";