| 11250 |      1 | (*  Title:      HOL/Auth/Event_lemmas
 | 
|  |      2 |     ID:         $Id$
 | 
|  |      3 |     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
 | 
|  |      4 |     Copyright   1996  University of Cambridge
 | 
|  |      5 | *)
 | 
|  |      6 | 
 | 
|  |      7 | 
 | 
|  |      8 | val knows_Cons     = thm "knows_Cons";
 | 
|  |      9 | val used_Nil       = thm "used_Nil";
 | 
|  |     10 | val used_Cons      = thm "used_Cons";
 | 
|  |     11 | 
 | 
|  |     12 | 
 | 
|  |     13 | (*Inserted by default but later removed.  This declaration lets the file
 | 
|  |     14 |   be re-loaded.*)
 | 
|  |     15 | Addsimps [knows_Cons, used_Nil, used_Cons];
 | 
|  |     16 | 
 | 
|  |     17 | (**** Function "knows" ****)
 | 
|  |     18 | 
 | 
|  |     19 | (** Simplifying   parts (insert X (knows Spy evs))
 | 
|  |     20 |       = parts {X} Un parts (knows Spy evs) -- since general case loops*)
 | 
|  |     21 | 
 | 
|  |     22 | bind_thm ("parts_insert_knows_Spy",
 | 
|  |     23 | 	  inst "H" "knows Spy evs" parts_insert);
 | 
|  |     24 | 
 | 
|  |     25 | 
 | 
|  |     26 | val expand_event_case = thm "event.split";
 | 
|  |     27 | 
 | 
|  |     28 | Goal "knows Spy (Says A B X # evs) = insert X (knows Spy evs)";
 | 
|  |     29 | by (Simp_tac 1);
 | 
|  |     30 | qed "knows_Spy_Says";
 | 
|  |     31 | 
 | 
|  |     32 | (*The point of letting the Spy see "bad" agents' notes is to prevent
 | 
|  |     33 |   redundant case-splits on whether A=Spy and whether A:bad*)
 | 
|  |     34 | Goal "knows Spy (Notes A X # evs) = \
 | 
|  |     35 | \         (if A:bad then insert X (knows Spy evs) else knows Spy evs)";
 | 
|  |     36 | by (Simp_tac 1);
 | 
|  |     37 | qed "knows_Spy_Notes";
 | 
|  |     38 | 
 | 
|  |     39 | Goal "knows Spy (Gets A X # evs) = knows Spy evs";
 | 
|  |     40 | by (Simp_tac 1);
 | 
|  |     41 | qed "knows_Spy_Gets";
 | 
|  |     42 | 
 | 
|  |     43 | Goal "knows Spy evs <= knows Spy (Says A B X # evs)";
 | 
|  |     44 | by (simp_tac (simpset() addsimps [subset_insertI]) 1);
 | 
|  |     45 | qed "knows_Spy_subset_knows_Spy_Says";
 | 
|  |     46 | 
 | 
|  |     47 | Goal "knows Spy evs <= knows Spy (Notes A X # evs)";
 | 
|  |     48 | by (Simp_tac 1);
 | 
|  |     49 | by (Fast_tac 1);
 | 
|  |     50 | qed "knows_Spy_subset_knows_Spy_Notes";
 | 
|  |     51 | 
 | 
|  |     52 | Goal "knows Spy evs <= knows Spy (Gets A X # evs)";
 | 
|  |     53 | by (simp_tac (simpset() addsimps [subset_insertI]) 1);
 | 
|  |     54 | qed "knows_Spy_subset_knows_Spy_Gets";
 | 
|  |     55 | 
 | 
|  |     56 | (*Spy sees what is sent on the traffic*)
 | 
|  |     57 | Goal "Says A B X : set evs --> X : knows Spy evs";
 | 
|  |     58 | by (induct_tac "evs" 1);
 | 
|  |     59 | by (ALLGOALS (asm_simp_tac (simpset() addsplits [expand_event_case])));
 | 
|  |     60 | qed_spec_mp "Says_imp_knows_Spy";
 | 
|  |     61 | 
 | 
|  |     62 | Goal "Notes A X : set evs --> A: bad --> X : knows Spy evs";
 | 
|  |     63 | by (induct_tac "evs" 1);
 | 
|  |     64 | by (ALLGOALS (asm_simp_tac (simpset() addsplits [expand_event_case])));
 | 
|  |     65 | qed_spec_mp "Notes_imp_knows_Spy";
 | 
|  |     66 | 
 | 
|  |     67 | 
 | 
|  |     68 | (*Use with addSEs to derive contradictions from old Says events containing
 | 
|  |     69 |   items known to be fresh*)
 | 
|  |     70 | bind_thms ("knows_Spy_partsEs", 
 | 
|  |     71 |            map make_elim [Says_imp_knows_Spy RS parts.Inj, parts.Body]);
 | 
|  |     72 | 
 | 
|  |     73 | Addsimps [knows_Spy_Says, knows_Spy_Notes, knows_Spy_Gets];
 | 
|  |     74 | 
 | 
|  |     75 | 
 | 
|  |     76 | (*Begin lemmas about agents' knowledge*)
 | 
|  |     77 | 
 | 
|  |     78 | Goal "knows A (Says A B X # evs) = insert X (knows A evs)";
 | 
|  |     79 | by (Simp_tac 1);
 | 
|  |     80 | qed "knows_Says";
 | 
|  |     81 | 
 | 
|  |     82 | Goal "knows A (Notes A X # evs) = insert X (knows A evs)";
 | 
|  |     83 | by (Simp_tac 1);
 | 
|  |     84 | qed "knows_Notes";
 | 
|  |     85 | 
 | 
|  |     86 | Goal "A ~= Spy --> knows A (Gets A X # evs) = insert X (knows A evs)";
 | 
|  |     87 | by (Simp_tac 1);
 | 
|  |     88 | qed "knows_Gets";
 | 
|  |     89 | 
 | 
|  |     90 | 
 | 
|  |     91 | Goal "knows A evs <= knows A (Says A B X # evs)";
 | 
|  |     92 | by (simp_tac (simpset() addsimps [subset_insertI]) 1);
 | 
|  |     93 | qed "knows_subset_knows_Says";
 | 
|  |     94 | 
 | 
|  |     95 | Goal "knows A evs <= knows A (Notes A X # evs)";
 | 
|  |     96 | by (simp_tac (simpset() addsimps [subset_insertI]) 1);
 | 
|  |     97 | qed "knows_subset_knows_Notes";
 | 
|  |     98 | 
 | 
|  |     99 | Goal "knows A evs <= knows A (Gets A X # evs)";
 | 
|  |    100 | by (simp_tac (simpset() addsimps [subset_insertI]) 1);
 | 
|  |    101 | qed "knows_subset_knows_Gets";
 | 
|  |    102 | 
 | 
|  |    103 | (*Agents know what they say*)
 | 
|  |    104 | Goal "Says A B X : set evs --> X : knows A evs";
 | 
|  |    105 | by (induct_tac "evs" 1);
 | 
|  |    106 | by (ALLGOALS (asm_simp_tac (simpset() addsplits [expand_event_case])));
 | 
|  |    107 | by (Blast_tac 1);
 | 
|  |    108 | qed_spec_mp "Says_imp_knows";
 | 
|  |    109 | 
 | 
|  |    110 | (*Agents know what they note*)
 | 
|  |    111 | Goal "Notes A X : set evs --> X : knows A evs";
 | 
|  |    112 | by (induct_tac "evs" 1);
 | 
|  |    113 | by (ALLGOALS (asm_simp_tac (simpset() addsplits [expand_event_case])));
 | 
|  |    114 | by (Blast_tac 1);
 | 
|  |    115 | qed_spec_mp "Notes_imp_knows";
 | 
|  |    116 | 
 | 
|  |    117 | (*Agents know what they receive*)
 | 
|  |    118 | Goal "A ~= Spy --> Gets A X : set evs --> X : knows A evs";
 | 
|  |    119 | by (induct_tac "evs" 1);
 | 
|  |    120 | by (ALLGOALS (asm_simp_tac (simpset() addsplits [expand_event_case])));
 | 
|  |    121 | qed_spec_mp "Gets_imp_knows_agents";
 | 
|  |    122 | 
 | 
|  |    123 | 
 | 
|  |    124 | (*What agents DIFFERENT FROM Spy know 
 | 
|  |    125 |   was either said, or noted, or got, or known initially*)
 | 
|  |    126 | Goal "[| X : knows A evs; A ~= Spy |] ==> EX B. \
 | 
|  |    127 | \ Says A B X : set evs | Gets A X : set evs | Notes A X : set evs | X : initState A";
 | 
|  |    128 | by (etac rev_mp 1);
 | 
|  |    129 | by (induct_tac "evs" 1);
 | 
|  |    130 | by (ALLGOALS (asm_simp_tac (simpset() addsplits [expand_event_case])));
 | 
|  |    131 | by (Blast_tac 1);
 | 
|  |    132 | qed_spec_mp "knows_imp_Says_Gets_Notes_initState";
 | 
|  |    133 | 
 | 
|  |    134 | (*What the Spy knows -- for the time being --
 | 
|  |    135 |   was either said or noted, or known initially*)
 | 
|  |    136 | Goal "[| X : knows Spy evs |] ==> EX A B. \
 | 
|  |    137 | \ Says A B X : set evs | Notes A X : set evs | X : initState Spy";
 | 
|  |    138 | by (etac rev_mp 1);
 | 
|  |    139 | by (induct_tac "evs" 1);
 | 
|  |    140 | by (ALLGOALS (asm_simp_tac (simpset() addsplits [expand_event_case])));
 | 
|  |    141 | by (Blast_tac 1);
 | 
|  |    142 | qed_spec_mp "knows_Spy_imp_Says_Notes_initState";
 | 
|  |    143 | 
 | 
|  |    144 | (*END lemmas about agents' knowledge*)
 | 
|  |    145 | 
 | 
|  |    146 | 
 | 
|  |    147 | 
 | 
|  |    148 | (**** NOTE REMOVAL--laws above are cleaner, as they don't involve "case" ****)
 | 
|  |    149 | Delsimps [knows_Cons];   
 | 
|  |    150 | 
 | 
|  |    151 | 
 | 
|  |    152 | (*** Fresh nonces ***)
 | 
|  |    153 | 
 | 
|  |    154 | Goal "parts (knows Spy evs) <= used evs";
 | 
|  |    155 | by (induct_tac "evs" 1);
 | 
|  |    156 | by (ALLGOALS (asm_simp_tac
 | 
|  |    157 | 	      (simpset() addsimps [parts_insert_knows_Spy]
 | 
|  |    158 | 	                addsplits [expand_event_case])));
 | 
|  |    159 | by (ALLGOALS Blast_tac);
 | 
|  |    160 | qed "parts_knows_Spy_subset_used";
 | 
|  |    161 | 
 | 
|  |    162 | bind_thm ("usedI", impOfSubs parts_knows_Spy_subset_used);
 | 
|  |    163 | AddIs [usedI];
 | 
|  |    164 | 
 | 
|  |    165 | Goal "parts (initState B) <= used evs";
 | 
|  |    166 | by (induct_tac "evs" 1);
 | 
|  |    167 | by (ALLGOALS (asm_simp_tac
 | 
|  |    168 | 	      (simpset() addsimps [parts_insert_knows_Spy]
 | 
|  |    169 | 	                addsplits [expand_event_case])));
 | 
|  |    170 | by (ALLGOALS Blast_tac);
 | 
|  |    171 | bind_thm ("initState_into_used", impOfSubs (result()));
 | 
|  |    172 | 
 | 
|  |    173 | Goal "used (Says A B X # evs) = parts{X} Un used evs";
 | 
|  |    174 | by (Simp_tac 1);
 | 
|  |    175 | qed "used_Says";
 | 
|  |    176 | Addsimps [used_Says];
 | 
|  |    177 | 
 | 
|  |    178 | Goal "used (Notes A X # evs) = parts{X} Un used evs";
 | 
|  |    179 | by (Simp_tac 1);
 | 
|  |    180 | qed "used_Notes";
 | 
|  |    181 | Addsimps [used_Notes];
 | 
|  |    182 | 
 | 
|  |    183 | Goal "used (Gets A X # evs) = used evs";
 | 
|  |    184 | by (Simp_tac 1);
 | 
|  |    185 | qed "used_Gets";
 | 
|  |    186 | Addsimps [used_Gets];
 | 
|  |    187 | 
 | 
|  |    188 | Goal "used [] <= used evs";
 | 
|  |    189 | by (Simp_tac 1);
 | 
|  |    190 | by (blast_tac (claset() addIs [initState_into_used]) 1);
 | 
|  |    191 | qed "used_nil_subset";
 | 
|  |    192 | 
 | 
|  |    193 | (**** NOTE REMOVAL--laws above are cleaner, as they don't involve "case" ****)
 | 
|  |    194 | Delsimps [used_Nil, used_Cons];   
 | 
|  |    195 | 
 | 
|  |    196 | 
 | 
|  |    197 | (*For proving theorems of the form X ~: analz (knows Spy evs) --> P
 | 
|  |    198 |   New events added by induction to "evs" are discarded.  Provided 
 | 
|  |    199 |   this information isn't needed, the proof will be much shorter, since
 | 
|  |    200 |   it will omit complicated reasoning about analz.*)
 | 
|  |    201 | 
 | 
|  |    202 | bind_thms ("analz_mono_contra",
 | 
|  |    203 |        [knows_Spy_subset_knows_Spy_Says RS analz_mono RS contra_subsetD,
 | 
|  |    204 |         knows_Spy_subset_knows_Spy_Notes RS analz_mono RS contra_subsetD,
 | 
|  |    205 | 	knows_Spy_subset_knows_Spy_Gets RS analz_mono RS contra_subsetD]);
 | 
|  |    206 | 
 | 
|  |    207 | val analz_mono_contra_tac = 
 | 
|  |    208 |   let val analz_impI = inst "P" "?Y ~: analz (knows Spy ?evs)" impI
 | 
|  |    209 |   in
 | 
|  |    210 |     rtac analz_impI THEN' 
 | 
|  |    211 |     REPEAT1 o 
 | 
|  |    212 |       (dresolve_tac 
 | 
|  |    213 |        [knows_Spy_subset_knows_Spy_Says RS analz_mono RS contra_subsetD,
 | 
|  |    214 |         knows_Spy_subset_knows_Spy_Notes RS analz_mono RS contra_subsetD,
 | 
|  |    215 | 	knows_Spy_subset_knows_Spy_Gets RS analz_mono RS contra_subsetD])
 | 
|  |    216 |     THEN'
 | 
|  |    217 |     mp_tac
 | 
|  |    218 |   end;
 | 
|  |    219 | 
 | 
|  |    220 | fun Reception_tac i =
 | 
|  |    221 |     blast_tac (claset() addDs [Says_imp_knows_Spy RS parts.Inj, 
 | 
|  |    222 |                                impOfSubs (parts_insert RS equalityD1), 
 | 
|  |    223 | 			       parts_trans,
 | 
|  |    224 |                                Says_imp_knows_Spy RS analz.Inj,
 | 
|  |    225 |                                impOfSubs analz_mono, analz_cut] 
 | 
|  |    226 |                         addIs [less_SucI]) i;
 | 
|  |    227 | 
 | 
|  |    228 | 
 | 
|  |    229 | (*Compatibility for the old "spies" function*)
 | 
|  |    230 | bind_thms ("spies_partsEs", knows_Spy_partsEs);
 | 
|  |    231 | bind_thm ("Says_imp_spies", Says_imp_knows_Spy);
 | 
|  |    232 | bind_thm ("parts_insert_spies", parts_insert_knows_Spy);
 |