# HG changeset patch # User blanchet # Date 1272486999 -7200 # Node ID 95bdfa572ceebae0aea4966451e84cc531d19d8f # Parent 2c042d86c7116a7641115785d99b785fef4f8fdc redo some of the metis proofs diff -r 2c042d86c711 -r 95bdfa572cee src/HOL/Metis_Examples/Message.thy --- a/src/HOL/Metis_Examples/Message.thy Wed Apr 28 22:00:48 2010 +0200 +++ b/src/HOL/Metis_Examples/Message.thy Wed Apr 28 22:36:39 2010 +0200 @@ -4,11 +4,12 @@ Testing the metis method. *) -theory Message imports Main begin +theory Message +imports Main +begin -(*Needed occasionally with spy_analz_tac, e.g. in analz_insert_Key_newK*) lemma strange_Un_eq [simp]: "A \ (B \ A) = B \ A" -by blast +by (metis Un_ac(2) Un_ac(3)) types key = nat @@ -20,7 +21,7 @@ specification (invKey) invKey [simp]: "invKey (invKey K) = K" invKey_symmetric: "all_symmetric --> invKey = id" - by (rule exI [of _ id], auto) +by (metis id_apply) text{*The inverse of a symmetric key is itself; that of a public key @@ -74,33 +75,28 @@ | Snd: "{|X,Y|} \ parts H ==> Y \ parts H" | Body: "Crypt K X \ parts H ==> X \ parts H" - -declare [[ atp_problem_prefix = "Message__parts_mono" ]] lemma parts_mono: "G \ H ==> parts(G) \ parts(H)" apply auto -apply (erule parts.induct) -apply (metis Inj set_mp) -apply (metis Fst) -apply (metis Snd) -apply (metis Body) -done - +apply (erule parts.induct) + apply (metis parts.Inj set_rev_mp) + apply (metis parts.Fst) + apply (metis parts.Snd) +by (metis parts.Body) text{*Equations hold because constructors are injective.*} lemma Friend_image_eq [simp]: "(Friend x \ Friend`A) = (x:A)" -by auto +by (metis agent.inject imageI image_iff) -lemma Key_image_eq [simp]: "(Key x \ Key`A) = (x\A)" -by auto +lemma Key_image_eq [simp]: "(Key x \ Key`A) = (x \ A)" +by (metis image_iff msg.inject(4)) -lemma Nonce_Key_image_eq [simp]: "(Nonce x \ Key`A)" -by auto +lemma Nonce_Key_image_eq [simp]: "Nonce x \ Key`A" +by (metis image_iff msg.distinct(23)) subsubsection{*Inverse of keys *} -declare [[ atp_problem_prefix = "Message__invKey_eq" ]] -lemma invKey_eq [simp]: "(invKey K = invKey K') = (K=K')" +lemma invKey_eq [simp]: "(invKey K = invKey K') = (K = K')" by (metis invKey) @@ -155,7 +151,7 @@ [| X \ parts H; Y \ parts H |] ==> P |] ==> P" by (blast dest: parts.Fst parts.Snd) - declare MPair_parts [elim!] parts.Body [dest!] +declare MPair_parts [elim!] parts.Body [dest!] text{*NB These two rules are UNSAFE in the formal sense, as they discard the compound message. They work well on THIS FILE. @{text MPair_parts} is left as SAFE because it speeds up proofs. @@ -200,7 +196,6 @@ apply (simp only: parts_Un) done -declare [[ atp_problem_prefix = "Message__parts_insert_two" ]] lemma parts_insert2: "parts (insert X (insert Y H)) = parts {X} \ parts {Y} \ parts H" by (metis Un_commute Un_empty_left Un_empty_right Un_insert_left Un_insert_right parts_Un) @@ -237,7 +232,6 @@ lemma parts_idem [simp]: "parts (parts H) = parts H" by blast -declare [[ atp_problem_prefix = "Message__parts_subset_iff" ]] lemma parts_subset_iff [simp]: "(parts G \ parts H) = (G \ parts H)" apply (rule iffI) apply (metis Un_absorb1 Un_subset_iff parts_Un parts_increasing) @@ -247,13 +241,10 @@ lemma parts_trans: "[| X\ parts G; G \ parts H |] ==> X\ parts H" by (blast dest: parts_mono); - -declare [[ atp_problem_prefix = "Message__parts_cut" ]] lemma parts_cut: "[|Y\ parts(insert X G); X\ parts H|] ==> Y\ parts(G \ H)" by (metis Un_insert_left Un_insert_right insert_absorb mem_def parts_Un parts_idem sup1CI) - subsubsection{*Rewrite rules for pulling out atomic messages *} lemmas parts_insert_eq_I = equalityI [OF subsetI parts_insert_subset] @@ -312,8 +303,6 @@ apply (erule parts.induct, auto) done - -declare [[ atp_problem_prefix = "Message__msg_Nonce_supply" ]] lemma msg_Nonce_supply: "\N. \n. N\n --> Nonce n \ parts {msg}" apply (induct_tac "msg") apply (simp_all add: parts_insert2) @@ -364,8 +353,6 @@ lemmas not_parts_not_analz = analz_subset_parts [THEN contra_subsetD, standard] - -declare [[ atp_problem_prefix = "Message__parts_analz" ]] lemma parts_analz [simp]: "parts (analz H) = parts H" apply (rule equalityI) apply (metis analz_subset_parts parts_subset_iff) @@ -517,8 +504,8 @@ by (drule analz_mono, blast) -declare [[ atp_problem_prefix = "Message__analz_cut" ]] - declare analz_trans[intro] +declare analz_trans[intro] + lemma analz_cut: "[| Y\ analz (insert X H); X\ analz H |] ==> Y\ analz H" (*TOO SLOW by (metis analz_idem analz_increasing analz_mono insert_absorb insert_mono insert_subset) --{*317s*} @@ -535,7 +522,6 @@ text{*A congruence rule for "analz" *} -declare [[ atp_problem_prefix = "Message__analz_subset_cong" ]] lemma analz_subset_cong: "[| analz G \ analz G'; analz H \ analz H' |] ==> analz (G \ H) \ analz (G' \ H')" @@ -612,9 +598,6 @@ lemma synth_Un: "synth(G) \ synth(H) \ synth(G \ H)" by (intro Un_least synth_mono Un_upper1 Un_upper2) - -declare [[ atp_problem_prefix = "Message__synth_insert" ]] - lemma synth_insert: "insert X (synth H) \ synth(insert X H)" by (metis insert_iff insert_subset subset_insertI synth.Inj synth_mono) @@ -635,7 +618,6 @@ lemma synth_trans: "[| X\ synth G; G \ synth H |] ==> X\ synth H" by (drule synth_mono, blast) -declare [[ atp_problem_prefix = "Message__synth_cut" ]] lemma synth_cut: "[| Y\ synth (insert X H); X\ synth H |] ==> Y\ synth H" (*TOO SLOW by (metis insert_absorb insert_mono insert_subset synth_idem synth_increasing synth_mono) @@ -667,7 +649,6 @@ subsubsection{*Combinations of parts, analz and synth *} -declare [[ atp_problem_prefix = "Message__parts_synth" ]] lemma parts_synth [simp]: "parts (synth H) = parts H \ synth H" apply (rule equalityI) apply (rule subsetI) @@ -679,18 +660,14 @@ apply (metis Un_subset_iff parts_increasing parts_mono synth_increasing) done - - - -declare [[ atp_problem_prefix = "Message__analz_analz_Un" ]] lemma analz_analz_Un [simp]: "analz (analz G \ H) = analz (G \ H)" apply (rule equalityI); apply (metis analz_idem analz_subset_cong order_eq_refl) apply (metis analz_increasing analz_subset_cong order_eq_refl) done -declare [[ atp_problem_prefix = "Message__analz_synth_Un" ]] - declare analz_mono [intro] analz.Fst [intro] analz.Snd [intro] Un_least [intro] +declare analz_mono [intro] analz.Fst [intro] analz.Snd [intro] Un_least [intro] + lemma analz_synth_Un [simp]: "analz (synth G \ H) = analz (G \ H) \ synth G" apply (rule equalityI) apply (rule subsetI) @@ -702,102 +679,81 @@ apply blast done -declare [[ atp_problem_prefix = "Message__analz_synth" ]] lemma analz_synth [simp]: "analz (synth H) = analz H \ synth H" -proof (neg_clausify) -assume 0: "analz (synth H) \ analz H \ synth H" -have 1: "\X1 X3. sup (analz (sup X3 X1)) (synth X3) = analz (sup (synth X3) X1)" - by (metis analz_synth_Un) -have 2: "sup (analz H) (synth H) \ analz (synth H)" - by (metis 0) -have 3: "\X1 X3. sup (synth X3) (analz (sup X3 X1)) = analz (sup (synth X3) X1)" - by (metis 1 Un_commute) -have 4: "\X3. sup (synth X3) (analz X3) = analz (sup (synth X3) {})" - by (metis 3 Un_empty_right) -have 5: "\X3. sup (synth X3) (analz X3) = analz (synth X3)" - by (metis 4 Un_empty_right) -have 6: "\X3. sup (analz X3) (synth X3) = analz (synth X3)" - by (metis 5 Un_commute) -show "False" - by (metis 2 6) +proof - + have "\x\<^isub>2 x\<^isub>1. synth x\<^isub>1 \ analz (x\<^isub>1 \ x\<^isub>2) = analz (synth x\<^isub>1 \ x\<^isub>2)" + by (metis Un_commute analz_synth_Un) + hence "\x\<^isub>3 x\<^isub>1. synth x\<^isub>1 \ analz x\<^isub>1 = analz (synth x\<^isub>1 \ UNION {} x\<^isub>3)" + by (metis UN_extend_simps(3)) + hence "\x\<^isub>1. synth x\<^isub>1 \ analz x\<^isub>1 = analz (synth x\<^isub>1)" + by (metis UN_extend_simps(3)) + hence "\x\<^isub>1. analz x\<^isub>1 \ synth x\<^isub>1 = analz (synth x\<^isub>1)" + by (metis Un_commute) + thus "analz (synth H) = analz H \ synth H" by metis qed subsubsection{*For reasoning about the Fake rule in traces *} -declare [[ atp_problem_prefix = "Message__parts_insert_subset_Un" ]] lemma parts_insert_subset_Un: "X\ G ==> parts(insert X H) \ parts G \ parts H" -proof (neg_clausify) -assume 0: "X \ G" -assume 1: "\ parts (insert X H) \ parts G \ parts H" -have 2: "\ parts (insert X H) \ parts (G \ H)" - by (metis 1 parts_Un) -have 3: "\ insert X H \ G \ H" - by (metis 2 parts_mono) -have 4: "X \ G \ H \ \ H \ G \ H" - by (metis 3 insert_subset) -have 5: "X \ G \ H" - by (metis 4 Un_upper2) -have 6: "X \ G" - by (metis 5 UnCI) -show "False" - by (metis 6 0) +proof - + assume "X \ G" + hence "\u. X \ G \ u" by (metis Un_iff) + hence "X \ G \ H \ H \ G \ H" + by (metis Un_upper2) + hence "insert X H \ G \ H" by (metis insert_subset) + hence "parts (insert X H) \ parts (G \ H)" + by (metis parts_mono) + thus "parts (insert X H) \ parts G \ parts H" + by (metis parts_Un) qed -declare [[ atp_problem_prefix = "Message__Fake_parts_insert" ]] lemma Fake_parts_insert: "X \ synth (analz H) ==> parts (insert X H) \ synth (analz H) \ parts H" -proof (neg_clausify) -assume 0: "X \ synth (analz H)" -assume 1: "\ parts (insert X H) \ synth (analz H) \ parts H" -have 2: "\X3. parts X3 \ synth (analz X3) = parts (synth (analz X3))" - by (metis parts_synth parts_analz) -have 3: "\X3. analz X3 \ synth (analz X3) = analz (synth (analz X3))" - by (metis analz_synth analz_idem) -have 4: "\X3. analz X3 \ analz (synth X3)" - by (metis Un_upper1 analz_synth) -have 5: "\ parts (insert X H) \ parts H \ synth (analz H)" - by (metis 1 Un_commute) -have 6: "\ parts (insert X H) \ parts (synth (analz H))" - by (metis 5 2) -have 7: "\ insert X H \ synth (analz H)" - by (metis 6 parts_mono) -have 8: "X \ synth (analz H) \ \ H \ synth (analz H)" - by (metis 7 insert_subset) -have 9: "\ H \ synth (analz H)" - by (metis 8 0) -have 10: "\X3. X3 \ analz (synth X3)" - by (metis analz_subset_iff 4) -have 11: "\X3. X3 \ analz (synth (analz X3))" - by (metis analz_subset_iff 10) -have 12: "\X3. analz (synth (analz X3)) = synth (analz X3) \ - \ analz X3 \ synth (analz X3)" - by (metis Un_absorb1 3) -have 13: "\X3. analz (synth (analz X3)) = synth (analz X3)" - by (metis 12 synth_increasing) -have 14: "\X3. X3 \ synth (analz X3)" - by (metis 11 13) -show "False" - by (metis 9 14) +sledgehammer +proof - + assume A1: "X \ synth (analz H)" + have F1: "\x\<^isub>1. analz x\<^isub>1 \ synth (analz x\<^isub>1) = analz (synth (analz x\<^isub>1))" + by (metis analz_idem analz_synth) + have F2: "\x\<^isub>1. parts x\<^isub>1 \ synth (analz x\<^isub>1) = parts (synth (analz x\<^isub>1))" + by (metis parts_analz parts_synth) + have F3: "synth (analz H) X" using A1 by (metis mem_def) + have "\x\<^isub>2 x\<^isub>1\msg set. x\<^isub>1 \ sup x\<^isub>1 x\<^isub>2" by (metis inf_sup_ord(3)) + hence F4: "\x\<^isub>1. analz x\<^isub>1 \ analz (synth x\<^isub>1)" by (metis analz_synth) + have F5: "X \ synth (analz H)" using F3 by (metis mem_def) + have "\x\<^isub>1. analz x\<^isub>1 \ synth (analz x\<^isub>1) + \ analz (synth (analz x\<^isub>1)) = synth (analz x\<^isub>1)" + using F1 by (metis subset_Un_eq) + hence F6: "\x\<^isub>1. analz (synth (analz x\<^isub>1)) = synth (analz x\<^isub>1)" + by (metis synth_increasing) + have "\x\<^isub>1. x\<^isub>1 \ analz (synth x\<^isub>1)" using F4 by (metis analz_subset_iff) + hence "\x\<^isub>1. x\<^isub>1 \ analz (synth (analz x\<^isub>1))" by (metis analz_subset_iff) + hence "\x\<^isub>1. x\<^isub>1 \ synth (analz x\<^isub>1)" using F6 by metis + hence "H \ synth (analz H)" by metis + hence "H \ synth (analz H) \ X \ synth (analz H)" using F5 by metis + hence "insert X H \ synth (analz H)" by (metis insert_subset) + hence "parts (insert X H) \ parts (synth (analz H))" by (metis parts_mono) + hence "parts (insert X H) \ parts H \ synth (analz H)" using F2 by metis + thus "parts (insert X H) \ synth (analz H) \ parts H" by (metis Un_commute) qed lemma Fake_parts_insert_in_Un: "[|Z \ parts (insert X H); X: synth (analz H)|] ==> Z \ synth (analz H) \ parts H"; -by (blast dest: Fake_parts_insert [THEN subsetD, dest]) +by (blast dest: Fake_parts_insert [THEN subsetD, dest]) -declare [[ atp_problem_prefix = "Message__Fake_analz_insert" ]] - declare analz_mono [intro] synth_mono [intro] +declare analz_mono [intro] synth_mono [intro] + lemma Fake_analz_insert: - "X\ synth (analz G) ==> + "X \ synth (analz G) ==> analz (insert X H) \ synth (analz G) \ analz (G \ H)" -by (metis Un_commute Un_insert_left Un_insert_right Un_upper1 analz_analz_Un analz_mono analz_synth_Un equalityE insert_absorb order_le_less xt1(12)) +by (metis Un_commute Un_insert_left Un_insert_right Un_upper1 analz_analz_Un + analz_mono analz_synth_Un insert_absorb) -declare [[ atp_problem_prefix = "Message__Fake_analz_insert_simpler" ]] -(*simpler problems? BUT METIS CAN'T PROVE +(* Simpler problems? BUT METIS CAN'T PROVE THE LAST STEP lemma Fake_analz_insert_simpler: - "X\ synth (analz G) ==> + "X \ synth (analz G) ==> analz (insert X H) \ synth (analz G) \ analz (G \ H)" apply (rule subsetI) apply (subgoal_tac "x \ analz (synth (analz G) \ H) ")