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)";
|
21828
|
44 |
by (simp_tac (simpset() addsimps [thm "subset_insertI"]) 1);
|
11250
|
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)";
|
21828
|
53 |
by (simp_tac (simpset() addsimps [thm "subset_insertI"]) 1);
|
11250
|
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)";
|
21828
|
92 |
by (simp_tac (simpset() addsimps [thm "subset_insertI"]) 1);
|
11250
|
93 |
qed "knows_subset_knows_Says";
|
|
94 |
|
|
95 |
Goal "knows A evs <= knows A (Notes A X # evs)";
|
21828
|
96 |
by (simp_tac (simpset() addsimps [thm "subset_insertI"]) 1);
|
11250
|
97 |
qed "knows_subset_knows_Notes";
|
|
98 |
|
|
99 |
Goal "knows A evs <= knows A (Gets A X # evs)";
|
21828
|
100 |
by (simp_tac (simpset() addsimps [thm "subset_insertI"]) 1);
|
11250
|
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);
|