1 (* Title: HOL/Induct/QuoDataType.thy
2 Author: Lawrence C Paulson, Cambridge University Computer Laboratory
3 Copyright 2004 University of Cambridge
6 section{*Defining an Initial Algebra by Quotienting a Free Algebra*}
8 theory QuoDataType imports Main begin
10 subsection{*Defining the Free Algebra*}
12 text{*Messages with encryption and decryption as free constructors.*}
15 | MPAIR freemsg freemsg
19 text{*The equivalence relation, which makes encryption and decryption inverses
20 provided the keys are the same.
22 The first two rules are the desired equations. The next four rules
23 make the equations applicable to subterms. The last two rules are symmetry
27 msgrel :: "(freemsg * freemsg) set"
28 and msg_rel :: "[freemsg, freemsg] => bool" (infixl "\<sim>" 50)
30 "X \<sim> Y == (X,Y) \<in> msgrel"
31 | CD: "CRYPT K (DECRYPT K X) \<sim> X"
32 | DC: "DECRYPT K (CRYPT K X) \<sim> X"
33 | NONCE: "NONCE N \<sim> NONCE N"
34 | MPAIR: "\<lbrakk>X \<sim> X'; Y \<sim> Y'\<rbrakk> \<Longrightarrow> MPAIR X Y \<sim> MPAIR X' Y'"
35 | CRYPT: "X \<sim> X' \<Longrightarrow> CRYPT K X \<sim> CRYPT K X'"
36 | DECRYPT: "X \<sim> X' \<Longrightarrow> DECRYPT K X \<sim> DECRYPT K X'"
37 | SYM: "X \<sim> Y \<Longrightarrow> Y \<sim> X"
38 | TRANS: "\<lbrakk>X \<sim> Y; Y \<sim> Z\<rbrakk> \<Longrightarrow> X \<sim> Z"
41 text{*Proving that it is an equivalence relation*}
43 lemma msgrel_refl: "X \<sim> X"
44 by (induct X) (blast intro: msgrel.intros)+
46 theorem equiv_msgrel: "equiv UNIV msgrel"
48 have "refl msgrel" by (simp add: refl_on_def msgrel_refl)
49 moreover have "sym msgrel" by (simp add: sym_def, blast intro: msgrel.SYM)
50 moreover have "trans msgrel" by (simp add: trans_def, blast intro: msgrel.TRANS)
51 ultimately show ?thesis by (simp add: equiv_def)
55 subsection{*Some Functions on the Free Algebra*}
57 subsubsection{*The Set of Nonces*}
59 text{*A function to return the set of nonces present in a message. It will
60 be lifted to the initial algrebra, to serve as an example of that process.*}
61 primrec freenonces :: "freemsg \<Rightarrow> nat set" where
62 "freenonces (NONCE N) = {N}"
63 | "freenonces (MPAIR X Y) = freenonces X \<union> freenonces Y"
64 | "freenonces (CRYPT K X) = freenonces X"
65 | "freenonces (DECRYPT K X) = freenonces X"
67 text{*This theorem lets us prove that the nonces function respects the
68 equivalence relation. It also helps us prove that Nonce
69 (the abstract constructor) is injective*}
70 theorem msgrel_imp_eq_freenonces: "U \<sim> V \<Longrightarrow> freenonces U = freenonces V"
71 by (induct set: msgrel) auto
74 subsubsection{*The Left Projection*}
76 text{*A function to return the left part of the top pair in a message. It will
77 be lifted to the initial algrebra, to serve as an example of that process.*}
78 primrec freeleft :: "freemsg \<Rightarrow> freemsg" where
79 "freeleft (NONCE N) = NONCE N"
80 | "freeleft (MPAIR X Y) = X"
81 | "freeleft (CRYPT K X) = freeleft X"
82 | "freeleft (DECRYPT K X) = freeleft X"
84 text{*This theorem lets us prove that the left function respects the
85 equivalence relation. It also helps us prove that MPair
86 (the abstract constructor) is injective*}
87 theorem msgrel_imp_eqv_freeleft:
88 "U \<sim> V \<Longrightarrow> freeleft U \<sim> freeleft V"
89 by (induct set: msgrel) (auto intro: msgrel.intros)
92 subsubsection{*The Right Projection*}
94 text{*A function to return the right part of the top pair in a message.*}
95 primrec freeright :: "freemsg \<Rightarrow> freemsg" where
96 "freeright (NONCE N) = NONCE N"
97 | "freeright (MPAIR X Y) = Y"
98 | "freeright (CRYPT K X) = freeright X"
99 | "freeright (DECRYPT K X) = freeright X"
101 text{*This theorem lets us prove that the right function respects the
102 equivalence relation. It also helps us prove that MPair
103 (the abstract constructor) is injective*}
104 theorem msgrel_imp_eqv_freeright:
105 "U \<sim> V \<Longrightarrow> freeright U \<sim> freeright V"
106 by (induct set: msgrel) (auto intro: msgrel.intros)
109 subsubsection{*The Discriminator for Constructors*}
111 text{*A function to distinguish nonces, mpairs and encryptions*}
112 primrec freediscrim :: "freemsg \<Rightarrow> int" where
113 "freediscrim (NONCE N) = 0"
114 | "freediscrim (MPAIR X Y) = 1"
115 | "freediscrim (CRYPT K X) = freediscrim X + 2"
116 | "freediscrim (DECRYPT K X) = freediscrim X - 2"
118 text{*This theorem helps us prove @{term "Nonce N \<noteq> MPair X Y"}*}
119 theorem msgrel_imp_eq_freediscrim:
120 "U \<sim> V \<Longrightarrow> freediscrim U = freediscrim V"
121 by (induct set: msgrel) auto
124 subsection{*The Initial Algebra: A Quotiented Message Type*}
126 definition "Msg = UNIV//msgrel"
129 morphisms Rep_Msg Abs_Msg
130 unfolding Msg_def by (auto simp add: quotient_def)
133 text{*The abstract message constructors*}
135 Nonce :: "nat \<Rightarrow> msg" where
136 "Nonce N = Abs_Msg(msgrel``{NONCE N})"
139 MPair :: "[msg,msg] \<Rightarrow> msg" where
141 Abs_Msg (\<Union>U \<in> Rep_Msg X. \<Union>V \<in> Rep_Msg Y. msgrel``{MPAIR U V})"
144 Crypt :: "[nat,msg] \<Rightarrow> msg" where
146 Abs_Msg (\<Union>U \<in> Rep_Msg X. msgrel``{CRYPT K U})"
149 Decrypt :: "[nat,msg] \<Rightarrow> msg" where
151 Abs_Msg (\<Union>U \<in> Rep_Msg X. msgrel``{DECRYPT K U})"
154 text{*Reduces equality of equivalence classes to the @{term msgrel} relation:
155 @{term "(msgrel `` {x} = msgrel `` {y}) = ((x,y) \<in> msgrel)"} *}
156 lemmas equiv_msgrel_iff = eq_equiv_class_iff [OF equiv_msgrel UNIV_I UNIV_I]
158 declare equiv_msgrel_iff [simp]
161 text{*All equivalence classes belong to set of representatives*}
162 lemma [simp]: "msgrel``{U} \<in> Msg"
163 by (auto simp add: Msg_def quotient_def intro: msgrel_refl)
165 lemma inj_on_Abs_Msg: "inj_on Abs_Msg Msg"
166 apply (rule inj_on_inverseI)
167 apply (erule Abs_Msg_inverse)
170 text{*Reduces equality on abstractions to equality on representatives*}
171 declare inj_on_Abs_Msg [THEN inj_on_iff, simp]
173 declare Abs_Msg_inverse [simp]
176 subsubsection{*Characteristic Equations for the Abstract Constructors*}
178 lemma MPair: "MPair (Abs_Msg(msgrel``{U})) (Abs_Msg(msgrel``{V})) =
179 Abs_Msg (msgrel``{MPAIR U V})"
181 have "(\<lambda>U V. msgrel `` {MPAIR U V}) respects2 msgrel"
182 by (auto simp add: congruent2_def msgrel.MPAIR)
184 by (simp add: MPair_def UN_equiv_class2 [OF equiv_msgrel equiv_msgrel])
187 lemma Crypt: "Crypt K (Abs_Msg(msgrel``{U})) = Abs_Msg (msgrel``{CRYPT K U})"
189 have "(\<lambda>U. msgrel `` {CRYPT K U}) respects msgrel"
190 by (auto simp add: congruent_def msgrel.CRYPT)
192 by (simp add: Crypt_def UN_equiv_class [OF equiv_msgrel])
196 "Decrypt K (Abs_Msg(msgrel``{U})) = Abs_Msg (msgrel``{DECRYPT K U})"
198 have "(\<lambda>U. msgrel `` {DECRYPT K U}) respects msgrel"
199 by (auto simp add: congruent_def msgrel.DECRYPT)
201 by (simp add: Decrypt_def UN_equiv_class [OF equiv_msgrel])
204 text{*Case analysis on the representation of a msg as an equivalence class.*}
205 lemma eq_Abs_Msg [case_names Abs_Msg, cases type: msg]:
206 "(!!U. z = Abs_Msg(msgrel``{U}) ==> P) ==> P"
207 apply (rule Rep_Msg [of z, unfolded Msg_def, THEN quotientE])
208 apply (drule arg_cong [where f=Abs_Msg])
209 apply (auto simp add: Rep_Msg_inverse intro: msgrel_refl)
212 text{*Establishing these two equations is the point of the whole exercise*}
213 theorem CD_eq [simp]: "Crypt K (Decrypt K X) = X"
214 by (cases X, simp add: Crypt Decrypt CD)
216 theorem DC_eq [simp]: "Decrypt K (Crypt K X) = X"
217 by (cases X, simp add: Crypt Decrypt DC)
220 subsection{*The Abstract Function to Return the Set of Nonces*}
223 nonces :: "msg \<Rightarrow> nat set" where
224 "nonces X = (\<Union>U \<in> Rep_Msg X. freenonces U)"
226 lemma nonces_congruent: "freenonces respects msgrel"
227 by (auto simp add: congruent_def msgrel_imp_eq_freenonces)
230 text{*Now prove the four equations for @{term nonces}*}
232 lemma nonces_Nonce [simp]: "nonces (Nonce N) = {N}"
233 by (simp add: nonces_def Nonce_def
234 UN_equiv_class [OF equiv_msgrel nonces_congruent])
236 lemma nonces_MPair [simp]: "nonces (MPair X Y) = nonces X \<union> nonces Y"
237 apply (cases X, cases Y)
238 apply (simp add: nonces_def MPair
239 UN_equiv_class [OF equiv_msgrel nonces_congruent])
242 lemma nonces_Crypt [simp]: "nonces (Crypt K X) = nonces X"
244 apply (simp add: nonces_def Crypt
245 UN_equiv_class [OF equiv_msgrel nonces_congruent])
248 lemma nonces_Decrypt [simp]: "nonces (Decrypt K X) = nonces X"
250 apply (simp add: nonces_def Decrypt
251 UN_equiv_class [OF equiv_msgrel nonces_congruent])
255 subsection{*The Abstract Function to Return the Left Part*}
258 left :: "msg \<Rightarrow> msg" where
259 "left X = Abs_Msg (\<Union>U \<in> Rep_Msg X. msgrel``{freeleft U})"
261 lemma left_congruent: "(\<lambda>U. msgrel `` {freeleft U}) respects msgrel"
262 by (auto simp add: congruent_def msgrel_imp_eqv_freeleft)
264 text{*Now prove the four equations for @{term left}*}
266 lemma left_Nonce [simp]: "left (Nonce N) = Nonce N"
267 by (simp add: left_def Nonce_def
268 UN_equiv_class [OF equiv_msgrel left_congruent])
270 lemma left_MPair [simp]: "left (MPair X Y) = X"
271 apply (cases X, cases Y)
272 apply (simp add: left_def MPair
273 UN_equiv_class [OF equiv_msgrel left_congruent])
276 lemma left_Crypt [simp]: "left (Crypt K X) = left X"
278 apply (simp add: left_def Crypt
279 UN_equiv_class [OF equiv_msgrel left_congruent])
282 lemma left_Decrypt [simp]: "left (Decrypt K X) = left X"
284 apply (simp add: left_def Decrypt
285 UN_equiv_class [OF equiv_msgrel left_congruent])
289 subsection{*The Abstract Function to Return the Right Part*}
292 right :: "msg \<Rightarrow> msg" where
293 "right X = Abs_Msg (\<Union>U \<in> Rep_Msg X. msgrel``{freeright U})"
295 lemma right_congruent: "(\<lambda>U. msgrel `` {freeright U}) respects msgrel"
296 by (auto simp add: congruent_def msgrel_imp_eqv_freeright)
298 text{*Now prove the four equations for @{term right}*}
300 lemma right_Nonce [simp]: "right (Nonce N) = Nonce N"
301 by (simp add: right_def Nonce_def
302 UN_equiv_class [OF equiv_msgrel right_congruent])
304 lemma right_MPair [simp]: "right (MPair X Y) = Y"
305 apply (cases X, cases Y)
306 apply (simp add: right_def MPair
307 UN_equiv_class [OF equiv_msgrel right_congruent])
310 lemma right_Crypt [simp]: "right (Crypt K X) = right X"
312 apply (simp add: right_def Crypt
313 UN_equiv_class [OF equiv_msgrel right_congruent])
316 lemma right_Decrypt [simp]: "right (Decrypt K X) = right X"
318 apply (simp add: right_def Decrypt
319 UN_equiv_class [OF equiv_msgrel right_congruent])
323 subsection{*Injectivity Properties of Some Constructors*}
325 lemma NONCE_imp_eq: "NONCE m \<sim> NONCE n \<Longrightarrow> m = n"
326 by (drule msgrel_imp_eq_freenonces, simp)
328 text{*Can also be proved using the function @{term nonces}*}
329 lemma Nonce_Nonce_eq [iff]: "(Nonce m = Nonce n) = (m = n)"
330 by (auto simp add: Nonce_def msgrel_refl dest: NONCE_imp_eq)
332 lemma MPAIR_imp_eqv_left: "MPAIR X Y \<sim> MPAIR X' Y' \<Longrightarrow> X \<sim> X'"
333 by (drule msgrel_imp_eqv_freeleft, simp)
335 lemma MPair_imp_eq_left:
336 assumes eq: "MPair X Y = MPair X' Y'" shows "X = X'"
339 have "left (MPair X Y) = left (MPair X' Y')" by simp
343 lemma MPAIR_imp_eqv_right: "MPAIR X Y \<sim> MPAIR X' Y' \<Longrightarrow> Y \<sim> Y'"
344 by (drule msgrel_imp_eqv_freeright, simp)
346 lemma MPair_imp_eq_right: "MPair X Y = MPair X' Y' \<Longrightarrow> Y = Y'"
347 apply (cases X, cases X', cases Y, cases Y')
348 apply (simp add: MPair)
349 apply (erule MPAIR_imp_eqv_right)
352 theorem MPair_MPair_eq [iff]: "(MPair X Y = MPair X' Y') = (X=X' & Y=Y')"
353 by (blast dest: MPair_imp_eq_left MPair_imp_eq_right)
355 lemma NONCE_neqv_MPAIR: "NONCE m \<sim> MPAIR X Y \<Longrightarrow> False"
356 by (drule msgrel_imp_eq_freediscrim, simp)
358 theorem Nonce_neq_MPair [iff]: "Nonce N \<noteq> MPair X Y"
359 apply (cases X, cases Y)
360 apply (simp add: Nonce_def MPair)
361 apply (blast dest: NONCE_neqv_MPAIR)
364 text{*Example suggested by a referee*}
365 theorem Crypt_Nonce_neq_Nonce: "Crypt K (Nonce M) \<noteq> Nonce N"
366 by (auto simp add: Nonce_def Crypt dest: msgrel_imp_eq_freediscrim)
368 text{*...and many similar results*}
369 theorem Crypt2_Nonce_neq_Nonce: "Crypt K (Crypt K' (Nonce M)) \<noteq> Nonce N"
370 by (auto simp add: Nonce_def Crypt dest: msgrel_imp_eq_freediscrim)
372 theorem Crypt_Crypt_eq [iff]: "(Crypt K X = Crypt K X') = (X=X')"
374 assume "Crypt K X = Crypt K X'"
375 hence "Decrypt K (Crypt K X) = Decrypt K (Crypt K X')" by simp
376 thus "X = X'" by simp
379 thus "Crypt K X = Crypt K X'" by simp
382 theorem Decrypt_Decrypt_eq [iff]: "(Decrypt K X = Decrypt K X') = (X=X')"
384 assume "Decrypt K X = Decrypt K X'"
385 hence "Crypt K (Decrypt K X) = Crypt K (Decrypt K X')" by simp
386 thus "X = X'" by simp
389 thus "Decrypt K X = Decrypt K X'" by simp
392 lemma msg_induct [case_names Nonce MPair Crypt Decrypt, cases type: msg]:
393 assumes N: "\<And>N. P (Nonce N)"
394 and M: "\<And>X Y. \<lbrakk>P X; P Y\<rbrakk> \<Longrightarrow> P (MPair X Y)"
395 and C: "\<And>K X. P X \<Longrightarrow> P (Crypt K X)"
396 and D: "\<And>K X. P X \<Longrightarrow> P (Decrypt K X)"
400 have "P (Abs_Msg (msgrel `` {U}))"
403 with N show ?case by (simp add: Nonce_def)
406 with M [of "Abs_Msg (msgrel `` {X})" "Abs_Msg (msgrel `` {Y})"]
407 show ?case by (simp add: MPair)
410 with C [of "Abs_Msg (msgrel `` {X})"]
411 show ?case by (simp add: Crypt)
414 with D [of "Abs_Msg (msgrel `` {X})"]
415 show ?case by (simp add: Decrypt)
417 with Abs_Msg show ?thesis by (simp only:)
421 subsection{*The Abstract Discriminator*}
423 text{*However, as @{text Crypt_Nonce_neq_Nonce} above illustrates, we don't
424 need this function in order to prove discrimination theorems.*}
427 discrim :: "msg \<Rightarrow> int" where
428 "discrim X = the_elem (\<Union>U \<in> Rep_Msg X. {freediscrim U})"
430 lemma discrim_congruent: "(\<lambda>U. {freediscrim U}) respects msgrel"
431 by (auto simp add: congruent_def msgrel_imp_eq_freediscrim)
433 text{*Now prove the four equations for @{term discrim}*}
435 lemma discrim_Nonce [simp]: "discrim (Nonce N) = 0"
436 by (simp add: discrim_def Nonce_def
437 UN_equiv_class [OF equiv_msgrel discrim_congruent])
439 lemma discrim_MPair [simp]: "discrim (MPair X Y) = 1"
440 apply (cases X, cases Y)
441 apply (simp add: discrim_def MPair
442 UN_equiv_class [OF equiv_msgrel discrim_congruent])
445 lemma discrim_Crypt [simp]: "discrim (Crypt K X) = discrim X + 2"
447 apply (simp add: discrim_def Crypt
448 UN_equiv_class [OF equiv_msgrel discrim_congruent])
451 lemma discrim_Decrypt [simp]: "discrim (Decrypt K X) = discrim X - 2"
453 apply (simp add: discrim_def Decrypt
454 UN_equiv_class [OF equiv_msgrel discrim_congruent])