23 Coming back to our introductory example, we |
23 Coming back to our introductory example, we |
24 could provide an alternative defining equations for @{const dequeue} |
24 could provide an alternative defining equations for @{const dequeue} |
25 explicitly: |
25 explicitly: |
26 *} |
26 *} |
27 |
27 |
28 lemma %quoteme [code func]: |
28 lemma %quoteme [code]: |
29 "dequeue (Queue xs []) = |
29 "dequeue (Queue xs []) = |
30 (if xs = [] then (None, Queue [] []) |
30 (if xs = [] then (None, Queue [] []) |
31 else dequeue (Queue [] (rev xs)))" |
31 else dequeue (Queue [] (rev xs)))" |
32 "dequeue (Queue xs (y # ys)) = |
32 "dequeue (Queue xs (y # ys)) = |
33 (Some y, Queue xs ys)" |
33 (Some y, Queue xs ys)" |
34 by (cases xs, simp_all) (cases "rev xs", simp_all) |
34 by (cases xs, simp_all) (cases "rev xs", simp_all) |
35 |
35 |
36 text {* |
36 text {* |
37 \noindent The annotation @{text "[code func]"} is an @{text Isar} |
37 \noindent The annotation @{text "[code]"} is an @{text Isar} |
38 @{text attribute} which states that the given theorems should be |
38 @{text attribute} which states that the given theorems should be |
39 considered as defining equations for a @{text fun} statement -- |
39 considered as defining equations for a @{text fun} statement -- |
40 the corresponding constant is determined syntactically. The resulting code: |
40 the corresponding constant is determined syntactically. The resulting code: |
41 *} |
41 *} |
42 |
42 |
253 text {* |
253 text {* |
254 \noindent Of course we also have to provide proper code equations for |
254 \noindent Of course we also have to provide proper code equations for |
255 the operations, e.g. @{term "op + \<Colon> nat \<Rightarrow> nat \<Rightarrow> nat"}: |
255 the operations, e.g. @{term "op + \<Colon> nat \<Rightarrow> nat \<Rightarrow> nat"}: |
256 *} |
256 *} |
257 |
257 |
258 lemma %quoteme plus_Dig [code func]: |
258 lemma %quoteme plus_Dig [code]: |
259 "0 + n = n" |
259 "0 + n = n" |
260 "m + 0 = m" |
260 "m + 0 = m" |
261 "1 + Dig0 n = Dig1 n" |
261 "1 + Dig0 n = Dig1 n" |
262 "Dig0 m + 1 = Dig1 m" |
262 "Dig0 m + 1 = Dig1 m" |
263 "1 + Dig1 n = Dig0 (n + 1)" |
263 "1 + Dig1 n = Dig0 (n + 1)" |
280 \noindent For the former constructor @{term Suc}, we provide a code |
280 \noindent For the former constructor @{term Suc}, we provide a code |
281 equation and remove some parts of the default code generator setup |
281 equation and remove some parts of the default code generator setup |
282 which are an obstacle here: |
282 which are an obstacle here: |
283 *} |
283 *} |
284 |
284 |
285 lemma %quoteme Suc_Dig [code func]: |
285 lemma %quoteme Suc_Dig [code]: |
286 "Suc n = n + 1" |
286 "Suc n = n + 1" |
287 by simp |
287 by simp |
288 |
288 |
289 declare %quoteme One_nat_def [code inline del] |
289 declare %quoteme One_nat_def [code inline del] |
290 declare %quoteme add_Suc_shift [code func del] |
290 declare %quoteme add_Suc_shift [code del] |
291 |
291 |
292 text {* |
292 text {* |
293 \noindent This yields the following code: |
293 \noindent This yields the following code: |
294 *} |
294 *} |
295 |
295 |
314 without relying on a particular representation. |
314 without relying on a particular representation. |
315 \end{itemize} |
315 \end{itemize} |
316 *} |
316 *} |
317 |
317 |
318 code_datatype %invisible "0::nat" Suc |
318 code_datatype %invisible "0::nat" Suc |
319 declare %invisible plus_Dig [code func del] |
319 declare %invisible plus_Dig [code del] |
320 declare %invisible One_nat_def [code inline] |
320 declare %invisible One_nat_def [code inline] |
321 declare %invisible add_Suc_shift [code func] |
321 declare %invisible add_Suc_shift [code] |
322 lemma %invisible [code func]: "0 + n = (n \<Colon> nat)" by simp |
322 lemma %invisible [code]: "0 + n = (n \<Colon> nat)" by simp |
323 |
323 |
324 |
324 |
325 subsection {* Equality and wellsortedness *} |
325 subsection {* Equality and wellsortedness *} |
326 |
326 |
327 text {* |
327 text {* |
365 *} |
365 *} |
366 |
366 |
367 instantiation %quoteme "*" :: (order, order) order |
367 instantiation %quoteme "*" :: (order, order) order |
368 begin |
368 begin |
369 |
369 |
370 definition %quoteme [code func del]: |
370 definition %quoteme [code del]: |
371 "x \<le> y \<longleftrightarrow> fst x < fst y \<or> fst x = fst y \<and> snd x \<le> snd y" |
371 "x \<le> y \<longleftrightarrow> fst x < fst y \<or> fst x = fst y \<and> snd x \<le> snd y" |
372 |
372 |
373 definition %quoteme [code func del]: |
373 definition %quoteme [code del]: |
374 "x < y \<longleftrightarrow> fst x < fst y \<or> fst x = fst y \<and> snd x < snd y" |
374 "x < y \<longleftrightarrow> fst x < fst y \<or> fst x = fst y \<and> snd x < snd y" |
375 |
375 |
376 instance %quoteme proof |
376 instance %quoteme proof |
377 qed (auto simp: less_eq_prod_def less_prod_def intro: order_less_trans) |
377 qed (auto simp: less_eq_prod_def less_prod_def intro: order_less_trans) |
378 |
378 |
379 end %quoteme |
379 end %quoteme |
380 |
380 |
381 lemma %quoteme order_prod [code func]: |
381 lemma %quoteme order_prod [code]: |
382 "(x1 \<Colon> 'a\<Colon>order, y1 \<Colon> 'b\<Colon>order) < (x2, y2) \<longleftrightarrow> |
382 "(x1 \<Colon> 'a\<Colon>order, y1 \<Colon> 'b\<Colon>order) < (x2, y2) \<longleftrightarrow> |
383 x1 < x2 \<or> x1 = x2 \<and> y1 < y2" |
383 x1 < x2 \<or> x1 = x2 \<and> y1 < y2" |
384 "(x1 \<Colon> 'a\<Colon>order, y1 \<Colon> 'b\<Colon>order) \<le> (x2, y2) \<longleftrightarrow> |
384 "(x1 \<Colon> 'a\<Colon>order, y1 \<Colon> 'b\<Colon>order) \<le> (x2, y2) \<longleftrightarrow> |
385 x1 < x2 \<or> x1 = x2 \<and> y1 \<le> y2" |
385 x1 < x2 \<or> x1 = x2 \<and> y1 \<le> y2" |
386 by (simp_all add: less_prod_def less_eq_prod_def) |
386 by (simp_all add: less_prod_def less_eq_prod_def) |
394 |
394 |
395 The solution is to add @{class eq} explicitly to the first sort arguments in the |
395 The solution is to add @{class eq} explicitly to the first sort arguments in the |
396 code theorems: |
396 code theorems: |
397 *} |
397 *} |
398 |
398 |
399 lemma %quoteme order_prod_code [code func]: |
399 lemma %quoteme order_prod_code [code]: |
400 "(x1 \<Colon> 'a\<Colon>{order, eq}, y1 \<Colon> 'b\<Colon>order) < (x2, y2) \<longleftrightarrow> |
400 "(x1 \<Colon> 'a\<Colon>{order, eq}, y1 \<Colon> 'b\<Colon>order) < (x2, y2) \<longleftrightarrow> |
401 x1 < x2 \<or> x1 = x2 \<and> y1 < y2" |
401 x1 < x2 \<or> x1 = x2 \<and> y1 < y2" |
402 "(x1 \<Colon> 'a\<Colon>{order, eq}, y1 \<Colon> 'b\<Colon>order) \<le> (x2, y2) \<longleftrightarrow> |
402 "(x1 \<Colon> 'a\<Colon>{order, eq}, y1 \<Colon> 'b\<Colon>order) \<le> (x2, y2) \<longleftrightarrow> |
403 x1 < x2 \<or> x1 = x2 \<and> y1 \<le> y2" |
403 x1 < x2 \<or> x1 = x2 \<and> y1 \<le> y2" |
404 by (simp_all add: less_prod_def less_eq_prod_def) |
404 by (simp_all add: less_prod_def less_eq_prod_def) |
436 In such cases, you have to provide your own equality equations |
436 In such cases, you have to provide your own equality equations |
437 involving auxiliary constants. In our case, |
437 involving auxiliary constants. In our case, |
438 @{const [show_types] list_all2} can do the job: |
438 @{const [show_types] list_all2} can do the job: |
439 *} |
439 *} |
440 |
440 |
441 lemma %quoteme monotype_eq_list_all2 [code func]: |
441 lemma %quoteme monotype_eq_list_all2 [code]: |
442 "eq_class.eq (Mono tyco1 typargs1) (Mono tyco2 typargs2) \<longleftrightarrow> |
442 "eq_class.eq (Mono tyco1 typargs1) (Mono tyco2 typargs2) \<longleftrightarrow> |
443 eq_class.eq tyco1 tyco2 \<and> list_all2 eq_class.eq typargs1 typargs2" |
443 eq_class.eq tyco1 tyco2 \<and> list_all2 eq_class.eq typargs1 typargs2" |
444 by (simp add: eq list_all2_eq [symmetric]) |
444 by (simp add: eq list_all2_eq [symmetric]) |
445 |
445 |
446 text {* |
446 text {* |