src/Benchmarks/Quickcheck_Benchmark/Needham_Schroeder_Base.thy
changeset 62286 705d4c4003ea
parent 61984 cdea44c775fa
child 62290 658276428cfc
equal deleted inserted replaced
62285:747fc3692fca 62286:705d4c4003ea
       
     1 theory Needham_Schroeder_Base
       
     2 imports Main "~~/src/HOL/Library/Predicate_Compile_Quickcheck"
       
     3 begin
       
     4 
       
     5 datatype agent = Alice | Bob | Spy
       
     6 
       
     7 definition agents :: "agent set"
       
     8 where
       
     9   "agents = {Spy, Alice, Bob}"
       
    10 
       
    11 definition bad :: "agent set"
       
    12 where
       
    13   "bad = {Spy}"
       
    14 
       
    15 datatype key = pubEK agent | priEK agent
       
    16 
       
    17 fun invKey
       
    18 where
       
    19   "invKey (pubEK A) = priEK A"
       
    20 | "invKey (priEK A) = pubEK A"
       
    21 
       
    22 datatype
       
    23      msg = Agent  agent
       
    24          | Key    key
       
    25          | Nonce  nat
       
    26          | MPair  msg msg
       
    27          | Crypt  key msg
       
    28 
       
    29 syntax
       
    30   "_MTuple"      :: "['a, args] => 'a * 'b"       ("(2\<lbrace>_,/ _\<rbrace>)")
       
    31 translations
       
    32   "\<lbrace>x, y, z\<rbrace>"   == "\<lbrace>x, \<lbrace>y, z\<rbrace>\<rbrace>"
       
    33   "\<lbrace>x, y\<rbrace>"      == "CONST MPair x y"
       
    34 
       
    35 inductive_set
       
    36   parts :: "msg set => msg set"
       
    37   for H :: "msg set"
       
    38   where
       
    39     Inj [intro]:               "X \<in> H ==> X \<in> parts H"
       
    40   | Fst:         "\<lbrace>X,Y\<rbrace>   \<in> parts H ==> X \<in> parts H"
       
    41   | Snd:         "\<lbrace>X,Y\<rbrace>   \<in> parts H ==> Y \<in> parts H"
       
    42   | Body:        "Crypt K X \<in> parts H ==> X \<in> parts H"
       
    43 
       
    44 inductive_set
       
    45   analz :: "msg set => msg set"
       
    46   for H :: "msg set"
       
    47   where
       
    48     Inj [intro,simp] :    "X \<in> H ==> X \<in> analz H"
       
    49   | Fst:     "\<lbrace>X,Y\<rbrace> \<in> analz H ==> X \<in> analz H"
       
    50   | Snd:     "\<lbrace>X,Y\<rbrace> \<in> analz H ==> Y \<in> analz H"
       
    51   | Decrypt [dest]: 
       
    52              "[|Crypt K X \<in> analz H; Key(invKey K): analz H|] ==> X \<in> analz H"
       
    53 
       
    54 inductive_set
       
    55   synth :: "msg set => msg set"
       
    56   for H :: "msg set"
       
    57   where
       
    58     Inj    [intro]:   "X \<in> H ==> X \<in> synth H"
       
    59   | Agent  [intro]:   "Agent agt \<in> synth H"
       
    60   | MPair  [intro]:   "[|X \<in> synth H;  Y \<in> synth H|] ==> \<lbrace>X,Y\<rbrace> \<in> synth H"
       
    61   | Crypt  [intro]:   "[|X \<in> synth H;  Key(K) \<in> H|] ==> Crypt K X \<in> synth H"
       
    62 
       
    63 primrec initState
       
    64 where
       
    65   initState_Alice:
       
    66     "initState Alice = {Key (priEK Alice)} \<union> (Key ` pubEK ` agents)"
       
    67 | initState_Bob:
       
    68     "initState Bob = {Key (priEK Bob)} \<union> (Key ` pubEK ` agents)"
       
    69 | initState_Spy:
       
    70     "initState Spy        =  (Key ` priEK ` bad) \<union> (Key ` pubEK ` agents)"
       
    71 
       
    72 datatype
       
    73   event = Says  agent agent msg
       
    74         | Gets  agent       msg
       
    75         | Notes agent       msg
       
    76 
       
    77 
       
    78 primrec knows :: "agent => event list => msg set"
       
    79 where
       
    80   knows_Nil:   "knows A [] = initState A"
       
    81 | knows_Cons:
       
    82     "knows A (ev # evs) =
       
    83        (if A = Spy then 
       
    84         (case ev of
       
    85            Says A' B X => insert X (knows Spy evs)
       
    86          | Gets A' X => knows Spy evs
       
    87          | Notes A' X  => 
       
    88              if A' \<in> bad then insert X (knows Spy evs) else knows Spy evs)
       
    89         else
       
    90         (case ev of
       
    91            Says A' B X => 
       
    92              if A'=A then insert X (knows A evs) else knows A evs
       
    93          | Gets A' X    => 
       
    94              if A'=A then insert X (knows A evs) else knows A evs
       
    95          | Notes A' X    => 
       
    96              if A'=A then insert X (knows A evs) else knows A evs))"
       
    97 
       
    98 abbreviation (input)
       
    99   spies  :: "event list => msg set" where
       
   100   "spies == knows Spy"
       
   101 
       
   102 primrec used :: "event list => msg set"
       
   103 where
       
   104   used_Nil:   "used []         = \<Union>(parts ` initState ` agents)"
       
   105 | used_Cons:  "used (ev # evs) =
       
   106                      (case ev of
       
   107                         Says A B X => parts {X} \<union> used evs
       
   108                       | Gets A X   => used evs
       
   109                       | Notes A X  => parts {X} \<union> used evs)"
       
   110 
       
   111 subsection {* Preparations for sets *}
       
   112 
       
   113 fun find_first :: "('a => 'b option) => 'a list => 'b option"
       
   114 where
       
   115   "find_first f [] = None"
       
   116 | "find_first f (x # xs) = (case f x of Some y => Some y | None => find_first f xs)"
       
   117 
       
   118 consts cps_of_set :: "'a set => ('a => term list option) => term list option"
       
   119 
       
   120 lemma
       
   121   [code]: "cps_of_set (set xs) f = find_first f xs"
       
   122 sorry
       
   123 
       
   124 consts pos_cps_of_set :: "'a set => ('a => (bool * term list) option) => natural => (bool * term list) option"
       
   125 consts neg_cps_of_set :: "'a set => ('a Quickcheck_Exhaustive.unknown => term list Quickcheck_Exhaustive.three_valued) => natural => term list Quickcheck_Exhaustive.three_valued"
       
   126 
       
   127 lemma
       
   128   [code]: "pos_cps_of_set (set xs) f i = find_first f xs"
       
   129 sorry
       
   130 
       
   131 consts find_first' :: "('b Quickcheck_Exhaustive.unknown => 'a Quickcheck_Exhaustive.three_valued)
       
   132     => 'b list => 'a Quickcheck_Exhaustive.three_valued"
       
   133 
       
   134 lemma [code]:
       
   135   "find_first' f [] = Quickcheck_Exhaustive.No_value"
       
   136   "find_first' f (x # xs) = (case f (Quickcheck_Exhaustive.Known x) of Quickcheck_Exhaustive.No_value => find_first' f xs | Quickcheck_Exhaustive.Value x => Quickcheck_Exhaustive.Value x | Quickcheck_Exhaustive.Unknown_value => (case find_first' f xs of Quickcheck_Exhaustive.Value x => Quickcheck_Exhaustive.Value x | _ => Quickcheck_Exhaustive.Unknown_value))"
       
   137 sorry
       
   138 
       
   139 lemma
       
   140   [code]: "neg_cps_of_set (set xs) f i = find_first' f xs"
       
   141 sorry
       
   142 
       
   143 setup {*
       
   144 let
       
   145   val Fun = Predicate_Compile_Aux.Fun
       
   146   val Input = Predicate_Compile_Aux.Input
       
   147   val Output = Predicate_Compile_Aux.Output
       
   148   val Bool = Predicate_Compile_Aux.Bool
       
   149   val oi = Fun (Output, Fun (Input, Bool))
       
   150   val ii = Fun (Input, Fun (Input, Bool))
       
   151   fun of_set compfuns (Type ("fun", [T, _])) =
       
   152     case body_type (Predicate_Compile_Aux.mk_monadT compfuns T) of
       
   153       Type ("Quickcheck_Exhaustive.three_valued", _) => 
       
   154         Const(@{const_name neg_cps_of_set}, HOLogic.mk_setT T --> (Predicate_Compile_Aux.mk_monadT compfuns T))
       
   155     | Type ("Predicate.pred", _) => Const(@{const_name pred_of_set}, HOLogic.mk_setT T --> Predicate_Compile_Aux.mk_monadT compfuns T)
       
   156     | _ => Const(@{const_name pos_cps_of_set}, HOLogic.mk_setT T --> (Predicate_Compile_Aux.mk_monadT compfuns T))
       
   157   fun member compfuns (U as Type ("fun", [T, _])) =
       
   158     (absdummy T (absdummy (HOLogic.mk_setT T) (Predicate_Compile_Aux.mk_if compfuns
       
   159       (Const (@{const_name "Set.member"}, T --> HOLogic.mk_setT T --> @{typ bool}) $ Bound 1 $ Bound 0))))
       
   160  
       
   161 in
       
   162   Core_Data.force_modes_and_compilations @{const_name Set.member}
       
   163     [(oi, (of_set, false)), (ii, (member, false))]
       
   164 end
       
   165 *}
       
   166 
       
   167 subsection {* Derived equations for analz, parts and synth *}
       
   168 
       
   169 lemma [code]:
       
   170   "analz H = (let
       
   171      H' = H \<union> (\<Union>((%m. case m of \<lbrace>X, Y\<rbrace> => {X, Y} | Crypt K X => if Key (invKey K) : H then {X} else {} | _ => {}) ` H))
       
   172    in if H' = H then H else analz H')"
       
   173 sorry
       
   174 
       
   175 lemma [code]:
       
   176   "parts H = (let
       
   177      H' = H \<union> (\<Union>((%m. case m of \<lbrace>X, Y\<rbrace> => {X, Y} | Crypt K X => {X} | _ => {}) ` H))
       
   178    in if H' = H then H else parts H')"
       
   179 sorry
       
   180 
       
   181 definition synth' :: "msg set => msg => bool"
       
   182 where
       
   183   "synth' H m = (m : synth H)"
       
   184 
       
   185 lemmas [code_pred_intro] = synth.intros[folded synth'_def]
       
   186 
       
   187 code_pred [generator_cps] synth' unfolding synth'_def by (rule synth.cases) fastforce+
       
   188 
       
   189 setup {* Predicate_Compile_Data.ignore_consts [@{const_name analz}, @{const_name knows}] *}
       
   190 declare ListMem_iff[symmetric, code_pred_inline]
       
   191 declare [[quickcheck_timing]]
       
   192 
       
   193 setup Exhaustive_Generators.setup_exhaustive_datatype_interpretation
       
   194 declare [[quickcheck_full_support = false]]
       
   195 
       
   196 end