| author | wenzelm | 
| Mon, 15 Jul 2013 10:42:12 +0200 | |
| changeset 52657 | 42c14dba1daa | 
| parent 46471 | 2289a3869c88 | 
| child 53428 | 3083c611ec40 | 
| permissions | -rw-r--r-- | 
| 37936 | 1 | (* Title: HOL/Auth/Event.thy | 
| 3512 
9dcb4daa15e8
Moving common declarations and proofs from theories "Shared"
 paulson parents: diff
changeset | 2 | Author: Lawrence C Paulson, Cambridge University Computer Laboratory | 
| 
9dcb4daa15e8
Moving common declarations and proofs from theories "Shared"
 paulson parents: diff
changeset | 3 | Copyright 1996 University of Cambridge | 
| 
9dcb4daa15e8
Moving common declarations and proofs from theories "Shared"
 paulson parents: diff
changeset | 4 | |
| 3683 | 5 | Datatype of events; function "spies"; freshness | 
| 3678 | 6 | |
| 3683 | 7 | "bad" agents have been broken by the Spy; their private keys and internal | 
| 3678 | 8 | stores are visible to him | 
| 3512 
9dcb4daa15e8
Moving common declarations and proofs from theories "Shared"
 paulson parents: diff
changeset | 9 | *) | 
| 
9dcb4daa15e8
Moving common declarations and proofs from theories "Shared"
 paulson parents: diff
changeset | 10 | |
| 13956 | 11 | header{*Theory of Events for Security Protocols*}
 | 
| 12 | ||
| 16417 | 13 | theory Event imports Message begin | 
| 11104 | 14 | |
| 3512 
9dcb4daa15e8
Moving common declarations and proofs from theories "Shared"
 paulson parents: diff
changeset | 15 | consts (*Initial states of agents -- parameter of the construction*) | 
| 11104 | 16 | initState :: "agent => msg set" | 
| 3512 
9dcb4daa15e8
Moving common declarations and proofs from theories "Shared"
 paulson parents: diff
changeset | 17 | |
| 6399 
4a9040b85e2e
exchanged the order of Gets and Notes in datatype event
 paulson parents: 
6308diff
changeset | 18 | datatype | 
| 3512 
9dcb4daa15e8
Moving common declarations and proofs from theories "Shared"
 paulson parents: diff
changeset | 19 | event = Says agent agent msg | 
| 6399 
4a9040b85e2e
exchanged the order of Gets and Notes in datatype event
 paulson parents: 
6308diff
changeset | 20 | | Gets agent msg | 
| 3512 
9dcb4daa15e8
Moving common declarations and proofs from theories "Shared"
 paulson parents: diff
changeset | 21 | | Notes agent msg | 
| 6308 
76f3865a2b1d
Added Bella's "Gets" model for Otway_Rees.  Also affects some other theories.
 paulson parents: 
5183diff
changeset | 22 | |
| 
76f3865a2b1d
Added Bella's "Gets" model for Otway_Rees.  Also affects some other theories.
 paulson parents: 
5183diff
changeset | 23 | consts | 
| 32960 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 24 |   bad    :: "agent set"                         -- {* compromised agents *}
 | 
| 6308 
76f3865a2b1d
Added Bella's "Gets" model for Otway_Rees.  Also affects some other theories.
 paulson parents: 
5183diff
changeset | 25 | |
| 14126 
28824746d046
Tidying and replacement of some axioms by specifications
 paulson parents: 
13956diff
changeset | 26 | text{*Spy has access to his own key for spoof messages, but Server is secure*}
 | 
| 
28824746d046
Tidying and replacement of some axioms by specifications
 paulson parents: 
13956diff
changeset | 27 | specification (bad) | 
| 14200 
d8598e24f8fa
Removal of the Key_supply axiom (affects many possbility proofs) and minor
 paulson parents: 
14126diff
changeset | 28 | Spy_in_bad [iff]: "Spy \<in> bad" | 
| 
d8598e24f8fa
Removal of the Key_supply axiom (affects many possbility proofs) and minor
 paulson parents: 
14126diff
changeset | 29 | Server_not_bad [iff]: "Server \<notin> bad" | 
| 14126 
28824746d046
Tidying and replacement of some axioms by specifications
 paulson parents: 
13956diff
changeset | 30 |     by (rule exI [of _ "{Spy}"], simp)
 | 
| 6308 
76f3865a2b1d
Added Bella's "Gets" model for Otway_Rees.  Also affects some other theories.
 paulson parents: 
5183diff
changeset | 31 | |
| 38964 | 32 | primrec knows :: "agent => event list => msg set" | 
| 33 | where | |
| 11104 | 34 | knows_Nil: "knows A [] = initState A" | 
| 38964 | 35 | | knows_Cons: | 
| 6399 
4a9040b85e2e
exchanged the order of Gets and Notes in datatype event
 paulson parents: 
6308diff
changeset | 36 | "knows A (ev # evs) = | 
| 
4a9040b85e2e
exchanged the order of Gets and Notes in datatype event
 paulson parents: 
6308diff
changeset | 37 | (if A = Spy then | 
| 32960 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 38 | (case ev of | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 39 | Says A' B X => insert X (knows Spy evs) | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 40 | | Gets A' X => knows Spy evs | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 41 | | Notes A' X => | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 42 | if A' \<in> bad then insert X (knows Spy evs) else knows Spy evs) | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 43 | else | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 44 | (case ev of | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 45 | Says A' B X => | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 46 | if A'=A then insert X (knows A evs) else knows A evs | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 47 | | Gets A' X => | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 48 | if A'=A then insert X (knows A evs) else knows A evs | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 49 | | Notes A' X => | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 50 | if A'=A then insert X (knows A evs) else knows A evs))" | 
| 6308 
76f3865a2b1d
Added Bella's "Gets" model for Otway_Rees.  Also affects some other theories.
 paulson parents: 
5183diff
changeset | 51 | |
| 
76f3865a2b1d
Added Bella's "Gets" model for Otway_Rees.  Also affects some other theories.
 paulson parents: 
5183diff
changeset | 52 | (* | 
| 
76f3865a2b1d
Added Bella's "Gets" model for Otway_Rees.  Also affects some other theories.
 paulson parents: 
5183diff
changeset | 53 | Case A=Spy on the Gets event | 
| 
76f3865a2b1d
Added Bella's "Gets" model for Otway_Rees.  Also affects some other theories.
 paulson parents: 
5183diff
changeset | 54 | enforces the fact that if a message is received then it must have been sent, | 
| 
76f3865a2b1d
Added Bella's "Gets" model for Otway_Rees.  Also affects some other theories.
 paulson parents: 
5183diff
changeset | 55 | therefore the oops case must use Notes | 
| 
76f3865a2b1d
Added Bella's "Gets" model for Otway_Rees.  Also affects some other theories.
 paulson parents: 
5183diff
changeset | 56 | *) | 
| 3678 | 57 | |
| 38964 | 58 | text{*The constant "spies" is retained for compatibility's sake*}
 | 
| 59 | ||
| 60 | abbreviation (input) | |
| 61 | spies :: "event list => msg set" where | |
| 62 | "spies == knows Spy" | |
| 63 | ||
| 64 | ||
| 65 | (*Set of items that might be visible to somebody: | |
| 3683 | 66 | complement of the set of fresh items*) | 
| 3512 
9dcb4daa15e8
Moving common declarations and proofs from theories "Shared"
 paulson parents: diff
changeset | 67 | |
| 38964 | 68 | primrec used :: "event list => msg set" | 
| 69 | where | |
| 11104 | 70 | used_Nil: "used [] = (UN B. parts (initState B))" | 
| 38964 | 71 | | used_Cons: "used (ev # evs) = | 
| 32960 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 72 | (case ev of | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 73 |                         Says A B X => parts {X} \<union> used evs
 | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 74 | | Gets A X => used evs | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32404diff
changeset | 75 |                       | Notes A X  => parts {X} \<union> used evs)"
 | 
| 13935 | 76 |     --{*The case for @{term Gets} seems anomalous, but @{term Gets} always
 | 
| 77 |         follows @{term Says} in real protocols.  Seems difficult to change.
 | |
| 78 |         See @{text Gets_correct} in theory @{text "Guard/Extensions.thy"}. *}
 | |
| 6308 
76f3865a2b1d
Added Bella's "Gets" model for Otway_Rees.  Also affects some other theories.
 paulson parents: 
5183diff
changeset | 79 | |
| 13926 | 80 | lemma Notes_imp_used [rule_format]: "Notes A X \<in> set evs --> X \<in> used evs" | 
| 81 | apply (induct_tac evs) | |
| 11463 | 82 | apply (auto split: event.split) | 
| 83 | done | |
| 84 | ||
| 13926 | 85 | lemma Says_imp_used [rule_format]: "Says A B X \<in> set evs --> X \<in> used evs" | 
| 86 | apply (induct_tac evs) | |
| 11463 | 87 | apply (auto split: event.split) | 
| 88 | done | |
| 89 | ||
| 13926 | 90 | |
| 91 | subsection{*Function @{term knows}*}
 | |
| 92 | ||
| 13956 | 93 | (*Simplifying | 
| 94 |  parts(insert X (knows Spy evs)) = parts{X} \<union> parts(knows Spy evs).
 | |
| 95 | This version won't loop with the simplifier.*) | |
| 45605 | 96 | lemmas parts_insert_knows_A = parts_insert [of _ "knows A evs"] for A evs | 
| 13926 | 97 | |
| 98 | lemma knows_Spy_Says [simp]: | |
| 99 | "knows Spy (Says A B X # evs) = insert X (knows Spy evs)" | |
| 100 | by simp | |
| 101 | ||
| 14200 
d8598e24f8fa
Removal of the Key_supply axiom (affects many possbility proofs) and minor
 paulson parents: 
14126diff
changeset | 102 | text{*Letting the Spy see "bad" agents' notes avoids redundant case-splits
 | 
| 
d8598e24f8fa
Removal of the Key_supply axiom (affects many possbility proofs) and minor
 paulson parents: 
14126diff
changeset | 103 |       on whether @{term "A=Spy"} and whether @{term "A\<in>bad"}*}
 | 
| 13926 | 104 | lemma knows_Spy_Notes [simp]: | 
| 105 | "knows Spy (Notes A X # evs) = | |
| 106 | (if A:bad then insert X (knows Spy evs) else knows Spy evs)" | |
| 107 | by simp | |
| 108 | ||
| 109 | lemma knows_Spy_Gets [simp]: "knows Spy (Gets A X # evs) = knows Spy evs" | |
| 110 | by simp | |
| 111 | ||
| 112 | lemma knows_Spy_subset_knows_Spy_Says: | |
| 13935 | 113 | "knows Spy evs \<subseteq> knows Spy (Says A B X # evs)" | 
| 13926 | 114 | by (simp add: subset_insertI) | 
| 115 | ||
| 116 | lemma knows_Spy_subset_knows_Spy_Notes: | |
| 13935 | 117 | "knows Spy evs \<subseteq> knows Spy (Notes A X # evs)" | 
| 13926 | 118 | by force | 
| 119 | ||
| 120 | lemma knows_Spy_subset_knows_Spy_Gets: | |
| 13935 | 121 | "knows Spy evs \<subseteq> knows Spy (Gets A X # evs)" | 
| 13926 | 122 | by (simp add: subset_insertI) | 
| 123 | ||
| 124 | text{*Spy sees what is sent on the traffic*}
 | |
| 125 | lemma Says_imp_knows_Spy [rule_format]: | |
| 126 | "Says A B X \<in> set evs --> X \<in> knows Spy evs" | |
| 127 | apply (induct_tac "evs") | |
| 128 | apply (simp_all (no_asm_simp) split add: event.split) | |
| 129 | done | |
| 130 | ||
| 131 | lemma Notes_imp_knows_Spy [rule_format]: | |
| 132 | "Notes A X \<in> set evs --> A: bad --> X \<in> knows Spy evs" | |
| 133 | apply (induct_tac "evs") | |
| 134 | apply (simp_all (no_asm_simp) split add: event.split) | |
| 135 | done | |
| 136 | ||
| 137 | ||
| 138 | text{*Elimination rules: derive contradictions from old Says events containing
 | |
| 139 | items known to be fresh*} | |
| 32404 | 140 | lemmas Says_imp_parts_knows_Spy = | 
| 46471 | 141 | Says_imp_knows_Spy [THEN parts.Inj, elim_format] | 
| 32404 | 142 | |
| 13926 | 143 | lemmas knows_Spy_partsEs = | 
| 46471 | 144 | Says_imp_parts_knows_Spy parts.Body [elim_format] | 
| 13926 | 145 | |
| 18570 | 146 | lemmas Says_imp_analz_Spy = Says_imp_knows_Spy [THEN analz.Inj] | 
| 147 | ||
| 13926 | 148 | text{*Compatibility for the old "spies" function*}
 | 
| 149 | lemmas spies_partsEs = knows_Spy_partsEs | |
| 150 | lemmas Says_imp_spies = Says_imp_knows_Spy | |
| 13935 | 151 | lemmas parts_insert_spies = parts_insert_knows_A [of _ Spy] | 
| 13926 | 152 | |
| 153 | ||
| 154 | subsection{*Knowledge of Agents*}
 | |
| 155 | ||
| 156 | lemma knows_Says: "knows A (Says A B X # evs) = insert X (knows A evs)" | |
| 157 | by simp | |
| 158 | ||
| 159 | lemma knows_Notes: "knows A (Notes A X # evs) = insert X (knows A evs)" | |
| 160 | by simp | |
| 161 | ||
| 162 | lemma knows_Gets: | |
| 163 | "A \<noteq> Spy --> knows A (Gets A X # evs) = insert X (knows A evs)" | |
| 164 | by simp | |
| 165 | ||
| 166 | ||
| 13935 | 167 | lemma knows_subset_knows_Says: "knows A evs \<subseteq> knows A (Says A' B X # evs)" | 
| 168 | by (simp add: subset_insertI) | |
| 13926 | 169 | |
| 13935 | 170 | lemma knows_subset_knows_Notes: "knows A evs \<subseteq> knows A (Notes A' X # evs)" | 
| 171 | by (simp add: subset_insertI) | |
| 13926 | 172 | |
| 13935 | 173 | lemma knows_subset_knows_Gets: "knows A evs \<subseteq> knows A (Gets A' X # evs)" | 
| 174 | by (simp add: subset_insertI) | |
| 13926 | 175 | |
| 176 | text{*Agents know what they say*}
 | |
| 177 | lemma Says_imp_knows [rule_format]: "Says A B X \<in> set evs --> X \<in> knows A evs" | |
| 178 | apply (induct_tac "evs") | |
| 179 | apply (simp_all (no_asm_simp) split add: event.split) | |
| 180 | apply blast | |
| 181 | done | |
| 182 | ||
| 183 | text{*Agents know what they note*}
 | |
| 184 | lemma Notes_imp_knows [rule_format]: "Notes A X \<in> set evs --> X \<in> knows A evs" | |
| 185 | apply (induct_tac "evs") | |
| 186 | apply (simp_all (no_asm_simp) split add: event.split) | |
| 187 | apply blast | |
| 188 | done | |
| 189 | ||
| 190 | text{*Agents know what they receive*}
 | |
| 191 | lemma Gets_imp_knows_agents [rule_format]: | |
| 192 | "A \<noteq> Spy --> Gets A X \<in> set evs --> X \<in> knows A evs" | |
| 193 | apply (induct_tac "evs") | |
| 194 | apply (simp_all (no_asm_simp) split add: event.split) | |
| 195 | done | |
| 196 | ||
| 197 | ||
| 198 | text{*What agents DIFFERENT FROM Spy know 
 | |
| 199 | was either said, or noted, or got, or known initially*} | |
| 200 | lemma knows_imp_Says_Gets_Notes_initState [rule_format]: | |
| 201 | "[| X \<in> knows A evs; A \<noteq> Spy |] ==> EX B. | |
| 202 | Says A B X \<in> set evs | Gets A X \<in> set evs | Notes A X \<in> set evs | X \<in> initState A" | |
| 203 | apply (erule rev_mp) | |
| 204 | apply (induct_tac "evs") | |
| 205 | apply (simp_all (no_asm_simp) split add: event.split) | |
| 206 | apply blast | |
| 207 | done | |
| 208 | ||
| 209 | text{*What the Spy knows -- for the time being --
 | |
| 210 | was either said or noted, or known initially*} | |
| 211 | lemma knows_Spy_imp_Says_Notes_initState [rule_format]: | |
| 212 | "[| X \<in> knows Spy evs |] ==> EX A B. | |
| 213 | Says A B X \<in> set evs | Notes A X \<in> set evs | X \<in> initState Spy" | |
| 214 | apply (erule rev_mp) | |
| 215 | apply (induct_tac "evs") | |
| 216 | apply (simp_all (no_asm_simp) split add: event.split) | |
| 217 | apply blast | |
| 218 | done | |
| 219 | ||
| 13935 | 220 | lemma parts_knows_Spy_subset_used: "parts (knows Spy evs) \<subseteq> used evs" | 
| 221 | apply (induct_tac "evs", force) | |
| 222 | apply (simp add: parts_insert_knows_A knows_Cons add: event.split, blast) | |
| 13926 | 223 | done | 
| 224 | ||
| 225 | lemmas usedI = parts_knows_Spy_subset_used [THEN subsetD, intro] | |
| 226 | ||
| 227 | lemma initState_into_used: "X \<in> parts (initState B) ==> X \<in> used evs" | |
| 228 | apply (induct_tac "evs") | |
| 13935 | 229 | apply (simp_all add: parts_insert_knows_A split add: event.split, blast) | 
| 13926 | 230 | done | 
| 231 | ||
| 232 | lemma used_Says [simp]: "used (Says A B X # evs) = parts{X} \<union> used evs"
 | |
| 233 | by simp | |
| 234 | ||
| 235 | lemma used_Notes [simp]: "used (Notes A X # evs) = parts{X} \<union> used evs"
 | |
| 236 | by simp | |
| 237 | ||
| 238 | lemma used_Gets [simp]: "used (Gets A X # evs) = used evs" | |
| 239 | by simp | |
| 240 | ||
| 13935 | 241 | lemma used_nil_subset: "used [] \<subseteq> used evs" | 
| 242 | apply simp | |
| 13926 | 243 | apply (blast intro: initState_into_used) | 
| 244 | done | |
| 245 | ||
| 246 | text{*NOTE REMOVAL--laws above are cleaner, as they don't involve "case"*}
 | |
| 13935 | 247 | declare knows_Cons [simp del] | 
| 248 | used_Nil [simp del] used_Cons [simp del] | |
| 13926 | 249 | |
| 250 | ||
| 251 | text{*For proving theorems of the form @{term "X \<notin> analz (knows Spy evs) --> P"}
 | |
| 252 | New events added by induction to "evs" are discarded. Provided | |
| 253 | this information isn't needed, the proof will be much shorter, since | |
| 254 |   it will omit complicated reasoning about @{term analz}.*}
 | |
| 255 | ||
| 256 | lemmas analz_mono_contra = | |
| 257 | knows_Spy_subset_knows_Spy_Says [THEN analz_mono, THEN contra_subsetD] | |
| 258 | knows_Spy_subset_knows_Spy_Notes [THEN analz_mono, THEN contra_subsetD] | |
| 259 | knows_Spy_subset_knows_Spy_Gets [THEN analz_mono, THEN contra_subsetD] | |
| 260 | ||
| 11104 | 261 | |
| 13922 | 262 | lemma knows_subset_knows_Cons: "knows A evs \<subseteq> knows A (e # evs)" | 
| 263 | by (induct e, auto simp: knows_Cons) | |
| 264 | ||
| 13935 | 265 | lemma initState_subset_knows: "initState A \<subseteq> knows A evs" | 
| 13926 | 266 | apply (induct_tac evs, simp) | 
| 13922 | 267 | apply (blast intro: knows_subset_knows_Cons [THEN subsetD]) | 
| 268 | done | |
| 269 | ||
| 270 | ||
| 13926 | 271 | text{*For proving @{text new_keys_not_used}*}
 | 
| 13922 | 272 | lemma keysFor_parts_insert: | 
| 13926 | 273 | "[| K \<in> keysFor (parts (insert X G)); X \<in> synth (analz H) |] | 
| 41693 
47532fe9e075
Introduction of metis calls and other cosmetic modifications.
 paulson parents: 
38964diff
changeset | 274 | ==> K \<in> keysFor (parts (G \<union> H)) | Key (invKey K) \<in> parts H" | 
| 13922 | 275 | by (force | 
| 276 | dest!: parts_insert_subset_Un [THEN keysFor_mono, THEN [2] rev_subsetD] | |
| 277 | analz_subset_parts [THEN keysFor_mono, THEN [2] rev_subsetD] | |
| 278 | intro: analz_subset_parts [THEN subsetD] parts_mono [THEN [2] rev_subsetD]) | |
| 279 | ||
| 24122 | 280 | |
| 45605 | 281 | lemmas analz_impI = impI [where P = "Y \<notin> analz (knows Spy evs)"] for Y evs | 
| 27225 | 282 | |
| 24122 | 283 | ML | 
| 284 | {*
 | |
| 285 | val analz_mono_contra_tac = | |
| 27225 | 286 |   rtac @{thm analz_impI} THEN' 
 | 
| 287 |   REPEAT1 o (dresolve_tac @{thms analz_mono_contra})
 | |
| 288 | THEN' mp_tac | |
| 24122 | 289 | *} | 
| 290 | ||
| 11104 | 291 | method_setup analz_mono_contra = {*
 | 
| 30549 | 292 | Scan.succeed (K (SIMPLE_METHOD (REPEAT_FIRST analz_mono_contra_tac))) *} | 
| 13922 | 293 | "for proving theorems of the form X \<notin> analz (knows Spy evs) --> P" | 
| 294 | ||
| 295 | subsubsection{*Useful for case analysis on whether a hash is a spoof or not*}
 | |
| 296 | ||
| 45605 | 297 | lemmas syan_impI = impI [where P = "Y \<notin> synth (analz (knows Spy evs))"] for Y evs | 
| 27225 | 298 | |
| 13922 | 299 | ML | 
| 300 | {*
 | |
| 301 | val synth_analz_mono_contra_tac = | |
| 27225 | 302 |   rtac @{thm syan_impI} THEN'
 | 
| 303 | REPEAT1 o | |
| 304 | (dresolve_tac | |
| 305 |      [@{thm knows_Spy_subset_knows_Spy_Says} RS @{thm synth_analz_mono} RS @{thm contra_subsetD},
 | |
| 306 |       @{thm knows_Spy_subset_knows_Spy_Notes} RS @{thm synth_analz_mono} RS @{thm contra_subsetD},
 | |
| 307 |       @{thm knows_Spy_subset_knows_Spy_Gets} RS @{thm synth_analz_mono} RS @{thm contra_subsetD}])
 | |
| 308 | THEN' | |
| 309 | mp_tac | |
| 13922 | 310 | *} | 
| 311 | ||
| 312 | method_setup synth_analz_mono_contra = {*
 | |
| 30549 | 313 | Scan.succeed (K (SIMPLE_METHOD (REPEAT_FIRST synth_analz_mono_contra_tac))) *} | 
| 13922 | 314 | "for proving theorems of the form X \<notin> synth (analz (knows Spy evs)) --> P" | 
| 3512 
9dcb4daa15e8
Moving common declarations and proofs from theories "Shared"
 paulson parents: diff
changeset | 315 | |
| 
9dcb4daa15e8
Moving common declarations and proofs from theories "Shared"
 paulson parents: diff
changeset | 316 | end |