src/HOL/Auth/Guard/Extensions.thy
changeset 61830 4f5ab843cf5b
parent 58889 5b7a9633cfa8
child 61956 38b73f7940af
equal deleted inserted replaced
61829:55c85d25e18c 61830:4f5ab843cf5b
     1 (*  Title:      HOL/Auth/Guard/Extensions.thy
     1 (*  Title:      HOL/Auth/Guard/Extensions.thy
     2     Author:     Frederic Blanqui, University of Cambridge Computer Laboratory
     2     Author:     Frederic Blanqui, University of Cambridge Computer Laboratory
     3     Copyright   2001  University of Cambridge
     3     Copyright   2001  University of Cambridge
     4 *)
     4 *)
     5 
     5 
     6 section {*Extensions to Standard Theories*}
     6 section \<open>Extensions to Standard Theories\<close>
     7 
     7 
     8 theory Extensions
     8 theory Extensions
     9 imports "../Event"
     9 imports "../Event"
    10 begin
    10 begin
    11 
    11 
    12 subsection{*Extensions to Theory @{text Set}*}
    12 subsection\<open>Extensions to Theory \<open>Set\<close>\<close>
    13 
    13 
    14 lemma eq: "[| !!x. x:A ==> x:B; !!x. x:B ==> x:A |] ==> A=B"
    14 lemma eq: "[| !!x. x:A ==> x:B; !!x. x:B ==> x:A |] ==> A=B"
    15 by auto
    15 by auto
    16 
    16 
    17 lemma insert_Un: "P ({x} Un A) ==> P (insert x A)"
    17 lemma insert_Un: "P ({x} Un A) ==> P (insert x A)"
    19 
    19 
    20 lemma in_sub: "x:A ==> {x}<=A"
    20 lemma in_sub: "x:A ==> {x}<=A"
    21 by auto
    21 by auto
    22 
    22 
    23 
    23 
    24 subsection{*Extensions to Theory @{text List}*}
    24 subsection\<open>Extensions to Theory \<open>List\<close>\<close>
    25 
    25 
    26 subsubsection{*"remove l x" erase the first element of "l" equal to "x"*}
    26 subsubsection\<open>"remove l x" erase the first element of "l" equal to "x"\<close>
    27 
    27 
    28 primrec remove :: "'a list => 'a => 'a list" where
    28 primrec remove :: "'a list => 'a => 'a list" where
    29 "remove [] y = []" |
    29 "remove [] y = []" |
    30 "remove (x#xs) y = (if x=y then xs else x # remove xs y)"
    30 "remove (x#xs) y = (if x=y then xs else x # remove xs y)"
    31 
    31 
    32 lemma set_remove: "set (remove l x) <= set l"
    32 lemma set_remove: "set (remove l x) <= set l"
    33 by (induct l, auto)
    33 by (induct l, auto)
    34 
    34 
    35 subsection{*Extensions to Theory @{text Message}*}
    35 subsection\<open>Extensions to Theory \<open>Message\<close>\<close>
    36 
    36 
    37 subsubsection{*declarations for tactics*}
    37 subsubsection\<open>declarations for tactics\<close>
    38 
    38 
    39 declare analz_subset_parts [THEN subsetD, dest]
    39 declare analz_subset_parts [THEN subsetD, dest]
    40 declare parts_insert2 [simp]
    40 declare parts_insert2 [simp]
    41 declare analz_cut [dest]
    41 declare analz_cut [dest]
    42 declare split_if_asm [split]
    42 declare split_if_asm [split]
    43 declare analz_insertI [intro]
    43 declare analz_insertI [intro]
    44 declare Un_Diff [simp]
    44 declare Un_Diff [simp]
    45 
    45 
    46 subsubsection{*extract the agent number of an Agent message*}
    46 subsubsection\<open>extract the agent number of an Agent message\<close>
    47 
    47 
    48 primrec agt_nb :: "msg => agent" where
    48 primrec agt_nb :: "msg => agent" where
    49 "agt_nb (Agent A) = A"
    49 "agt_nb (Agent A) = A"
    50 
    50 
    51 subsubsection{*messages that are pairs*}
    51 subsubsection\<open>messages that are pairs\<close>
    52 
    52 
    53 definition is_MPair :: "msg => bool" where
    53 definition is_MPair :: "msg => bool" where
    54 "is_MPair X == EX Y Z. X = {|Y,Z|}"
    54 "is_MPair X == EX Y Z. X = {|Y,Z|}"
    55 
    55 
    56 declare is_MPair_def [simp]
    56 declare is_MPair_def [simp]
    88 definition has_no_pair :: "msg set => bool" where
    88 definition has_no_pair :: "msg set => bool" where
    89 "has_no_pair H == ALL X Y. {|X,Y|} ~:H"
    89 "has_no_pair H == ALL X Y. {|X,Y|} ~:H"
    90 
    90 
    91 declare has_no_pair_def [simp]
    91 declare has_no_pair_def [simp]
    92 
    92 
    93 subsubsection{*well-foundedness of messages*}
    93 subsubsection\<open>well-foundedness of messages\<close>
    94 
    94 
    95 lemma wf_Crypt1 [iff]: "Crypt K X ~= X"
    95 lemma wf_Crypt1 [iff]: "Crypt K X ~= X"
    96 by (induct X, auto)
    96 by (induct X, auto)
    97 
    97 
    98 lemma wf_Crypt2 [iff]: "X ~= Crypt K X"
    98 lemma wf_Crypt2 [iff]: "X ~= Crypt K X"
   102 by (erule parts.induct, auto)
   102 by (erule parts.induct, auto)
   103 
   103 
   104 lemma wf_Crypt_parts [iff]: "Crypt K X ~:parts {X}"
   104 lemma wf_Crypt_parts [iff]: "Crypt K X ~:parts {X}"
   105 by (auto dest: parts_size)
   105 by (auto dest: parts_size)
   106 
   106 
   107 subsubsection{*lemmas on keysFor*}
   107 subsubsection\<open>lemmas on keysFor\<close>
   108 
   108 
   109 definition usekeys :: "msg set => key set" where
   109 definition usekeys :: "msg set => key set" where
   110 "usekeys G == {K. EX Y. Crypt K Y:G}"
   110 "usekeys G == {K. EX Y. Crypt K Y:G}"
   111 
   111 
   112 lemma finite_keysFor [intro]: "finite G ==> finite (keysFor G)"
   112 lemma finite_keysFor [intro]: "finite G ==> finite (keysFor G)"
   118 apply (subgoal_tac "{Ka. EX Xa. (Ka=K & Xa=X) | Crypt Ka Xa:F}
   118 apply (subgoal_tac "{Ka. EX Xa. (Ka=K & Xa=X) | Crypt Ka Xa:F}
   119 = insert K (usekeys F)", auto simp: usekeys_def)
   119 = insert K (usekeys F)", auto simp: usekeys_def)
   120 by (subgoal_tac "{K. EX X. Crypt K X = x | Crypt K X:F} = usekeys F",
   120 by (subgoal_tac "{K. EX X. Crypt K X = x | Crypt K X:F} = usekeys F",
   121 auto simp: usekeys_def)
   121 auto simp: usekeys_def)
   122 
   122 
   123 subsubsection{*lemmas on parts*}
   123 subsubsection\<open>lemmas on parts\<close>
   124 
   124 
   125 lemma parts_sub: "[| X:parts G; G<=H |] ==> X:parts H"
   125 lemma parts_sub: "[| X:parts G; G<=H |] ==> X:parts H"
   126 by (auto dest: parts_mono)
   126 by (auto dest: parts_mono)
   127 
   127 
   128 lemma parts_Diff [dest]: "X:parts (G - H) ==> X:parts G"
   128 lemma parts_Diff [dest]: "X:parts (G - H) ==> X:parts G"
   151 
   151 
   152 lemma parts_parts_Crypt: "[| Crypt K X:parts G; Nonce n:parts {X} |]
   152 lemma parts_parts_Crypt: "[| Crypt K X:parts G; Nonce n:parts {X} |]
   153 ==> Nonce n:parts G"
   153 ==> Nonce n:parts G"
   154 by (blast intro: parts.Body dest: parts_parts)
   154 by (blast intro: parts.Body dest: parts_parts)
   155 
   155 
   156 subsubsection{*lemmas on synth*}
   156 subsubsection\<open>lemmas on synth\<close>
   157 
   157 
   158 lemma synth_sub: "[| X:synth G; G<=H |] ==> X:synth H"
   158 lemma synth_sub: "[| X:synth G; G<=H |] ==> X:synth H"
   159 by (auto dest: synth_mono)
   159 by (auto dest: synth_mono)
   160 
   160 
   161 lemma Crypt_synth [rule_format]: "[| X:synth G; Key K ~:G |] ==>
   161 lemma Crypt_synth [rule_format]: "[| X:synth G; Key K ~:G |] ==>
   162 Crypt K Y:parts {X} --> Crypt K Y:parts G"
   162 Crypt K Y:parts {X} --> Crypt K Y:parts G"
   163 by (erule synth.induct, auto dest: parts_sub)
   163 by (erule synth.induct, auto dest: parts_sub)
   164 
   164 
   165 subsubsection{*lemmas on analz*}
   165 subsubsection\<open>lemmas on analz\<close>
   166 
   166 
   167 lemma analz_UnI1 [intro]: "X:analz G ==> X:analz (G Un H)"
   167 lemma analz_UnI1 [intro]: "X:analz G ==> X:analz (G Un H)"
   168   by (subgoal_tac "G <= G Un H") (blast dest: analz_mono)+
   168   by (subgoal_tac "G <= G Un H") (blast dest: analz_mono)+
   169 
   169 
   170 lemma analz_sub: "[| X:analz G; G <= H |] ==> X:analz H"
   170 lemma analz_sub: "[| X:analz G; G <= H |] ==> X:analz H"
   192 by (erule analz.induct, auto)
   192 by (erule analz.induct, auto)
   193 
   193 
   194 lemma notin_analz_insert: "X ~:analz (insert Y G) ==> X ~:analz G"
   194 lemma notin_analz_insert: "X ~:analz (insert Y G) ==> X ~:analz G"
   195 by auto
   195 by auto
   196 
   196 
   197 subsubsection{*lemmas on parts, synth and analz*}
   197 subsubsection\<open>lemmas on parts, synth and analz\<close>
   198 
   198 
   199 lemma parts_invKey [rule_format,dest]:"X:parts {Y} ==>
   199 lemma parts_invKey [rule_format,dest]:"X:parts {Y} ==>
   200 X:analz (insert (Crypt K Y) H) --> X ~:analz H --> Key (invKey K):analz H"
   200 X:analz (insert (Crypt K Y) H) --> X ~:analz H --> Key (invKey K):analz H"
   201 by (erule parts.induct, auto dest: parts.Fst parts.Snd parts.Body)
   201 by (erule parts.induct, auto dest: parts.Fst parts.Snd parts.Body)
   202 
   202 
   211 apply (frule in_sub)
   211 apply (frule in_sub)
   212 apply (frule parts_mono)
   212 apply (frule parts_mono)
   213 apply auto
   213 apply auto
   214 done
   214 done
   215 
   215 
   216 subsubsection{*greatest nonce used in a message*}
   216 subsubsection\<open>greatest nonce used in a message\<close>
   217 
   217 
   218 fun greatest_msg :: "msg => nat"
   218 fun greatest_msg :: "msg => nat"
   219 where
   219 where
   220   "greatest_msg (Nonce n) = n"
   220   "greatest_msg (Nonce n) = n"
   221 | "greatest_msg {|X,Y|} = max (greatest_msg X) (greatest_msg Y)"
   221 | "greatest_msg {|X,Y|} = max (greatest_msg X) (greatest_msg Y)"
   223 | "greatest_msg other = 0"
   223 | "greatest_msg other = 0"
   224 
   224 
   225 lemma greatest_msg_is_greatest: "Nonce n:parts {X} ==> n <= greatest_msg X"
   225 lemma greatest_msg_is_greatest: "Nonce n:parts {X} ==> n <= greatest_msg X"
   226 by (induct X, auto)
   226 by (induct X, auto)
   227 
   227 
   228 subsubsection{*sets of keys*}
   228 subsubsection\<open>sets of keys\<close>
   229 
   229 
   230 definition keyset :: "msg set => bool" where
   230 definition keyset :: "msg set => bool" where
   231 "keyset G == ALL X. X:G --> (EX K. X = Key K)"
   231 "keyset G == ALL X. X:G --> (EX K. X = Key K)"
   232 
   232 
   233 lemma keyset_in [dest]: "[| keyset G; X:G |] ==> EX K. X = Key K"
   233 lemma keyset_in [dest]: "[| keyset G; X:G |] ==> EX K. X = Key K"
   243 by auto
   243 by auto
   244 
   244 
   245 lemma parts_keyset [simp]: "keyset G ==> parts G = G"
   245 lemma parts_keyset [simp]: "keyset G ==> parts G = G"
   246 by (auto, erule parts.induct, auto)
   246 by (auto, erule parts.induct, auto)
   247 
   247 
   248 subsubsection{*keys a priori necessary for decrypting the messages of G*}
   248 subsubsection\<open>keys a priori necessary for decrypting the messages of G\<close>
   249 
   249 
   250 definition keysfor :: "msg set => msg set" where
   250 definition keysfor :: "msg set => msg set" where
   251 "keysfor G == Key ` keysFor (parts G)"
   251 "keysfor G == Key ` keysFor (parts G)"
   252 
   252 
   253 lemma keyset_keysfor [iff]: "keyset (keysfor G)"
   253 lemma keyset_keysfor [iff]: "keyset (keysfor G)"
   263 by (auto dest: keysfor_Crypt)
   263 by (auto dest: keysfor_Crypt)
   264 
   264 
   265 lemma finite_keysfor [intro]: "finite G ==> finite (keysfor G)"
   265 lemma finite_keysfor [intro]: "finite G ==> finite (keysfor G)"
   266 by (auto simp: keysfor_def intro: finite_UN_I)
   266 by (auto simp: keysfor_def intro: finite_UN_I)
   267 
   267 
   268 subsubsection{*only the keys necessary for G are useful in analz*}
   268 subsubsection\<open>only the keys necessary for G are useful in analz\<close>
   269 
   269 
   270 lemma analz_keyset: "keyset H ==>
   270 lemma analz_keyset: "keyset H ==>
   271 analz (G Un H) = H - keysfor G Un (analz (G Un (H Int keysfor G)))"
   271 analz (G Un H) = H - keysfor G Un (analz (G Un (H Int keysfor G)))"
   272 apply (rule eq)
   272 apply (rule eq)
   273 apply (erule analz.induct, blast)
   273 apply (erule analz.induct, blast)
   278 by (auto intro: analz_sub)
   278 by (auto intro: analz_sub)
   279 
   279 
   280 lemmas analz_keyset_substD = analz_keyset [THEN sym, THEN ssubst]
   280 lemmas analz_keyset_substD = analz_keyset [THEN sym, THEN ssubst]
   281 
   281 
   282 
   282 
   283 subsection{*Extensions to Theory @{text Event}*}
   283 subsection\<open>Extensions to Theory \<open>Event\<close>\<close>
   284 
   284 
   285 
   285 
   286 subsubsection{*general protocol properties*}
   286 subsubsection\<open>general protocol properties\<close>
   287 
   287 
   288 definition is_Says :: "event => bool" where
   288 definition is_Says :: "event => bool" where
   289 "is_Says ev == (EX A B X. ev = Says A B X)"
   289 "is_Says ev == (EX A B X. ev = Says A B X)"
   290 
   290 
   291 lemma is_Says_Says [iff]: "is_Says (Says A B X)"
   291 lemma is_Says_Says [iff]: "is_Says (Says A B X)"
   328 
   328 
   329 lemma has_only_Says_imp_Gets_correct [simp]: "has_only_Says p
   329 lemma has_only_Says_imp_Gets_correct [simp]: "has_only_Says p
   330 ==> Gets_correct p"
   330 ==> Gets_correct p"
   331 by (auto simp: has_only_Says_def Gets_correct_def)
   331 by (auto simp: has_only_Says_def Gets_correct_def)
   332 
   332 
   333 subsubsection{*lemma on knows*}
   333 subsubsection\<open>lemma on knows\<close>
   334 
   334 
   335 lemma Says_imp_spies2: "Says A B {|X,Y|}:set evs ==> Y:parts (spies evs)"
   335 lemma Says_imp_spies2: "Says A B {|X,Y|}:set evs ==> Y:parts (spies evs)"
   336 by (drule Says_imp_spies, drule parts.Inj, drule parts.Snd, simp)
   336 by (drule Says_imp_spies, drule parts.Inj, drule parts.Snd, simp)
   337 
   337 
   338 lemma Says_not_parts: "[| Says A B X:set evs; Y ~:parts (spies evs) |]
   338 lemma Says_not_parts: "[| Says A B X:set evs; Y ~:parts (spies evs) |]
   339 ==> Y ~:parts {X}"
   339 ==> Y ~:parts {X}"
   340 by (auto dest: Says_imp_spies parts_parts)
   340 by (auto dest: Says_imp_spies parts_parts)
   341 
   341 
   342 subsubsection{*knows without initState*}
   342 subsubsection\<open>knows without initState\<close>
   343 
   343 
   344 primrec knows' :: "agent => event list => msg set" where
   344 primrec knows' :: "agent => event list => msg set" where
   345   knows'_Nil: "knows' A [] = {}" |
   345   knows'_Nil: "knows' A [] = {}" |
   346   knows'_Cons0:
   346   knows'_Cons0:
   347  "knows' A (ev # evs) = (
   347  "knows' A (ev # evs) = (
   359 
   359 
   360 abbreviation
   360 abbreviation
   361   spies' :: "event list => msg set" where
   361   spies' :: "event list => msg set" where
   362   "spies' == knows' Spy"
   362   "spies' == knows' Spy"
   363 
   363 
   364 subsubsection{*decomposition of knows into knows' and initState*}
   364 subsubsection\<open>decomposition of knows into knows' and initState\<close>
   365 
   365 
   366 lemma knows_decomp: "knows A evs = knows' A evs Un (initState A)"
   366 lemma knows_decomp: "knows A evs = knows' A evs Un (initState A)"
   367 by (induct evs, auto split: event.split simp: knows.simps)
   367 by (induct evs, auto split: event.split simp: knows.simps)
   368 
   368 
   369 lemmas knows_decomp_substI = knows_decomp [THEN ssubst]
   369 lemmas knows_decomp_substI = knows_decomp [THEN ssubst]
   392 
   392 
   393 lemma knows'_sub_spies': "[| evs:p; has_only_Says p; one_step p |]
   393 lemma knows'_sub_spies': "[| evs:p; has_only_Says p; one_step p |]
   394 ==> knows' A evs <= spies' evs"
   394 ==> knows' A evs <= spies' evs"
   395 by (induct evs, auto split: event.splits)
   395 by (induct evs, auto split: event.splits)
   396 
   396 
   397 subsubsection{*knows' is finite*}
   397 subsubsection\<open>knows' is finite\<close>
   398 
   398 
   399 lemma finite_knows' [iff]: "finite (knows' A evs)"
   399 lemma finite_knows' [iff]: "finite (knows' A evs)"
   400 by (induct evs, auto split: event.split simp: knows.simps)
   400 by (induct evs, auto split: event.split simp: knows.simps)
   401 
   401 
   402 subsubsection{*monotonicity of knows*}
   402 subsubsection\<open>monotonicity of knows\<close>
   403 
   403 
   404 lemma knows_sub_Cons: "knows A evs <= knows A (ev#evs)"
   404 lemma knows_sub_Cons: "knows A evs <= knows A (ev#evs)"
   405 by(cases A, induct evs, auto simp: knows.simps split:event.split)
   405 by(cases A, induct evs, auto simp: knows.simps split:event.split)
   406 
   406 
   407 lemma knows_ConsI: "X:knows A evs ==> X:knows A (ev#evs)"
   407 lemma knows_ConsI: "X:knows A evs ==> X:knows A (ev#evs)"
   411 apply (induct evs, auto)
   411 apply (induct evs, auto)
   412 apply (simp add: knows_decomp)
   412 apply (simp add: knows_decomp)
   413 apply (rename_tac a b c)
   413 apply (rename_tac a b c)
   414 by (case_tac a, auto simp: knows.simps)
   414 by (case_tac a, auto simp: knows.simps)
   415 
   415 
   416 subsubsection{*maximum knowledge an agent can have
   416 subsubsection\<open>maximum knowledge an agent can have
   417 includes messages sent to the agent*}
   417 includes messages sent to the agent\<close>
   418 
   418 
   419 primrec knows_max' :: "agent => event list => msg set" where
   419 primrec knows_max' :: "agent => event list => msg set" where
   420 knows_max'_def_Nil: "knows_max' A [] = {}" |
   420 knows_max'_def_Nil: "knows_max' A [] = {}" |
   421 knows_max'_def_Cons: "knows_max' A (ev # evs) = (
   421 knows_max'_def_Cons: "knows_max' A (ev # evs) = (
   422   if A=Spy then (
   422   if A=Spy then (
   440 
   440 
   441 abbreviation
   441 abbreviation
   442   spies_max :: "event list => msg set" where
   442   spies_max :: "event list => msg set" where
   443   "spies_max evs == knows_max Spy evs"
   443   "spies_max evs == knows_max Spy evs"
   444 
   444 
   445 subsubsection{*basic facts about @{term knows_max}*}
   445 subsubsection\<open>basic facts about @{term knows_max}\<close>
   446 
   446 
   447 lemma spies_max_spies [iff]: "spies_max evs = spies evs"
   447 lemma spies_max_spies [iff]: "spies_max evs = spies evs"
   448 by (induct evs, auto simp: knows_max_def split: event.splits)
   448 by (induct evs, auto simp: knows_max_def split: event.splits)
   449 
   449 
   450 lemma knows_max'_Cons: "knows_max' A (ev#evs)
   450 lemma knows_max'_Cons: "knows_max' A (ev#evs)
   482 by (simp add: in_set_conv_decomp, clarify, simp add: knows_max'_app)
   482 by (simp add: in_set_conv_decomp, clarify, simp add: knows_max'_app)
   483 
   483 
   484 lemma Says_from_knows_max': "Says A B X:set evs ==> X:knows_max' A evs"
   484 lemma Says_from_knows_max': "Says A B X:set evs ==> X:knows_max' A evs"
   485 by (simp add: in_set_conv_decomp, clarify, simp add: knows_max'_app)
   485 by (simp add: in_set_conv_decomp, clarify, simp add: knows_max'_app)
   486 
   486 
   487 subsubsection{*used without initState*}
   487 subsubsection\<open>used without initState\<close>
   488 
   488 
   489 primrec used' :: "event list => msg set" where
   489 primrec used' :: "event list => msg set" where
   490 "used' [] = {}" |
   490 "used' [] = {}" |
   491 "used' (ev # evs) = (
   491 "used' (ev # evs) = (
   492   case ev of
   492   case ev of
   509 apply (rename_tac a b)
   509 apply (rename_tac a b)
   510 apply (case_tac a, simp_all) 
   510 apply (case_tac a, simp_all) 
   511 apply (blast dest: parts_trans)+ 
   511 apply (blast dest: parts_trans)+ 
   512 done
   512 done
   513 
   513 
   514 subsubsection{*monotonicity of used*}
   514 subsubsection\<open>monotonicity of used\<close>
   515 
   515 
   516 lemma used_sub_Cons: "used evs <= used (ev#evs)"
   516 lemma used_sub_Cons: "used evs <= used (ev#evs)"
   517 by (induct evs, (induct ev, auto)+)
   517 by (induct evs, (induct ev, auto)+)
   518 
   518 
   519 lemma used_ConsI: "X:used evs ==> X:used (ev#evs)"
   519 lemma used_ConsI: "X:used evs ==> X:used (ev#evs)"
   548 apply (drule_tac evs="[Says A B Y]" in used_parts, simp, blast)
   548 apply (drule_tac evs="[Says A B Y]" in used_parts, simp, blast)
   549 apply (drule_tac evs'=evs' in used_appIR)
   549 apply (drule_tac evs'=evs' in used_appIR)
   550 apply (drule_tac evs'=evs in used_appIL)
   550 apply (drule_tac evs'=evs in used_appIL)
   551 by simp
   551 by simp
   552 
   552 
   553 subsubsection{*lemmas on used and knows*}
   553 subsubsection\<open>lemmas on used and knows\<close>
   554 
   554 
   555 lemma initState_used: "X:parts (initState A) ==> X:used evs"
   555 lemma initState_used: "X:parts (initState A) ==> X:used evs"
   556 by (induct evs, auto simp: used.simps split: event.split)
   556 by (induct evs, auto simp: used.simps split: event.split)
   557 
   557 
   558 lemma Says_imp_used: "Says A B X:set evs ==> parts {X} <= used evs"
   558 lemma Says_imp_used: "Says A B X:set evs ==> parts {X} <= used evs"
   603 
   603 
   604 lemma not_used_not_known_max: "[| evs:p; X ~:used evs;
   604 lemma not_used_not_known_max: "[| evs:p; X ~:used evs;
   605 Gets_correct p; one_step p |] ==> X ~:parts (knows_max A evs)"
   605 Gets_correct p; one_step p |] ==> X ~:parts (knows_max A evs)"
   606 by (case_tac "A=Spy", auto dest: not_used_not_spied known_max_used)
   606 by (case_tac "A=Spy", auto dest: not_used_not_spied known_max_used)
   607 
   607 
   608 subsubsection{*a nonce or key in a message cannot equal a fresh nonce or key*}
   608 subsubsection\<open>a nonce or key in a message cannot equal a fresh nonce or key\<close>
   609 
   609 
   610 lemma Nonce_neq [dest]: "[| Nonce n' ~:used evs;
   610 lemma Nonce_neq [dest]: "[| Nonce n' ~:used evs;
   611 Says A B X:set evs; Nonce n:parts {X} |] ==> n ~= n'"
   611 Says A B X:set evs; Nonce n:parts {X} |] ==> n ~= n'"
   612 by (drule not_used_not_spied, auto dest: Says_imp_knows_Spy parts_sub)
   612 by (drule not_used_not_spied, auto dest: Says_imp_knows_Spy parts_sub)
   613 
   613 
   614 lemma Key_neq [dest]: "[| Key n' ~:used evs;
   614 lemma Key_neq [dest]: "[| Key n' ~:used evs;
   615 Says A B X:set evs; Key n:parts {X} |] ==> n ~= n'"
   615 Says A B X:set evs; Key n:parts {X} |] ==> n ~= n'"
   616 by (drule not_used_not_spied, auto dest: Says_imp_knows_Spy parts_sub)
   616 by (drule not_used_not_spied, auto dest: Says_imp_knows_Spy parts_sub)
   617 
   617 
   618 subsubsection{*message of an event*}
   618 subsubsection\<open>message of an event\<close>
   619 
   619 
   620 primrec msg :: "event => msg"
   620 primrec msg :: "event => msg"
   621 where
   621 where
   622   "msg (Says A B X) = X"
   622   "msg (Says A B X) = X"
   623 | "msg (Gets A X) = X"
   623 | "msg (Gets A X) = X"