55 text {* |
55 text {* |
56 \noindent |
56 \noindent |
57 The package also provides some convenience, notably automatically generated |
57 The package also provides some convenience, notably automatically generated |
58 destructors (discriminators and selectors). |
58 destructors (discriminators and selectors). |
59 |
59 |
60 In addition to plain inductive datatypes, the package supports coinductive |
60 In addition to plain inductive datatypes, the new package supports coinductive |
61 datatypes, or \emph{codatatypes}, which may have infinite values. For example, |
61 datatypes, or \emph{codatatypes}, which may have infinite values. For example, |
62 the following command introduces the type of lazy lists: |
62 the following command introduces the type of lazy lists: |
63 *} |
63 *} |
64 |
64 |
65 codatatype 'a llist = LNil | LCons 'a "'a llist" |
65 codatatype 'a llist (*<*)(map: lmap) (*>*)= LNil | LCons 'a "'a llist" |
66 |
66 |
67 text {* |
67 text {* |
68 \noindent |
68 \noindent |
69 Mixed inductive--coinductive recursion is possible via nesting. Compare the |
69 Mixed inductive--coinductive recursion is possible via nesting. Compare the |
70 following four examples: |
70 following four examples: |
71 |
71 *} |
72 %%% TODO: Avoid 0 |
72 |
73 *} |
73 (*<*) |
74 |
74 locale dummy_tree |
75 datatype_new 'a treeFF0 = NodeFF 'a "'a treeFF0 list" |
75 begin |
76 datatype_new 'a treeFI0 = NodeFI 'a "'a treeFI0 llist" |
76 (*>*) |
77 codatatype 'a treeIF0 = NodeIF 'a "'a treeIF0 list" |
77 datatype_new 'a treeFF = NodeFF 'a "'a treeFF list" |
78 codatatype 'a treeII0 = NodeII 'a "'a treeII0 llist" |
78 datatype_new 'a treeFI = NodeFI 'a "'a treeFI llist" |
|
79 codatatype 'a treeIF = NodeIF 'a "'a treeIF list" |
|
80 codatatype 'a treeII = NodeII 'a "'a treeII llist" |
|
81 (*<*) |
|
82 end |
|
83 (*>*) |
79 |
84 |
80 text {* |
85 text {* |
81 The first two tree types allow only finite branches, whereas the last two allow |
86 The first two tree types allow only finite branches, whereas the last two allow |
82 infinite branches. Orthogonally, the nodes in the first and third types have |
87 infinite branches. Orthogonally, the nodes in the first and third types have |
83 finite branching, whereas those of the second and fourth may have infinitely |
88 finite branching, whereas those of the second and fourth may have infinitely |
271 text {* |
282 text {* |
272 Nested recursion = Have recursion through a type constructor. |
283 Nested recursion = Have recursion through a type constructor. |
273 |
284 |
274 The introduction showed some examples of trees with nesting through lists. |
285 The introduction showed some examples of trees with nesting through lists. |
275 |
286 |
276 More complex example, which reuses our maybe: |
287 More complex example, which reuses our option type: |
277 *} |
288 *} |
278 |
289 |
279 datatype_new 'a btree = |
290 datatype_new 'a btree = |
280 BNode 'a "'a btree maybe" "'a btree maybe" |
291 BNode 'a "'a btree option" "'a btree option" |
281 |
292 |
282 text {* |
293 text {* |
283 Recursion may not be arbitrary; e.g. impossible to define |
294 Recursion may not be arbitrary; e.g. impossible to define |
284 *} |
295 *} |
285 |
296 |
328 The discriminators and selectors are collectively called \emph{destructors}. The |
339 The discriminators and selectors are collectively called \emph{destructors}. The |
329 @{text "t."} prefix is an optional component of the name and is normally hidden. |
340 @{text "t."} prefix is an optional component of the name and is normally hidden. |
330 |
341 |
331 The set functions, map function, relator, discriminators, and selectors can be |
342 The set functions, map function, relator, discriminators, and selectors can be |
332 given custom names, as in the example below: |
343 given custom names, as in the example below: |
333 |
|
334 %%% FIXME: get rid of 0 below |
|
335 *} |
344 *} |
336 |
345 |
337 (*<*) |
346 (*<*) |
338 no_translations |
347 no_translations |
339 "[x, xs]" == "x # [xs]" |
348 "[x, xs]" == "x # [xs]" |
342 no_notation |
351 no_notation |
343 Nil ("[]") and |
352 Nil ("[]") and |
344 Cons (infixr "#" 65) |
353 Cons (infixr "#" 65) |
345 |
354 |
346 hide_const Nil Cons hd tl map |
355 hide_const Nil Cons hd tl map |
|
356 |
|
357 locale dummy_list |
|
358 begin |
347 (*>*) |
359 (*>*) |
348 datatype_new (set0: 'a) list0 (map: map0 rel: list0_all2) = |
360 datatype_new (set: 'a) list (map: map rel: list_all2) = |
349 null: Nil (defaults tl: Nil) |
361 null: Nil (defaults tl: Nil) |
350 | Cons (hd: 'a) (tl: "'a list0") |
362 | Cons (hd: 'a) (tl: "'a list") |
351 |
363 |
352 text {* |
364 text {* |
353 \noindent |
365 \noindent |
354 The command introduces a discriminator @{const null} and a pair of selectors |
366 The command introduces a discriminator @{const null} and a pair of selectors |
355 @{const hd} and @{const tl} characterized as follows: |
367 @{const hd} and @{const tl} characterized as follows: |
356 % |
368 % |
357 \[@{thm list0.collapse(1)[of xs, no_vars]} |
369 \[@{thm list.collapse(1)[of xs, no_vars]} |
358 \qquad @{thm list0.collapse(2)[of xs, no_vars]}\] |
370 \qquad @{thm list.collapse(2)[of xs, no_vars]}\] |
359 % |
371 % |
360 For two-constructor datatypes, a single discriminator constant suffices. The |
372 For two-constructor datatypes, a single discriminator constant suffices. The |
361 discriminator associated with @{const Cons} is simply @{text "\<not> null"}. |
373 discriminator associated with @{const Cons} is simply @{text "\<not> null"}. |
362 |
374 |
363 The \keyw{defaults} keyword following the @{const Nil} constructor specifies a |
375 The \keyw{defaults} keyword following the @{const Nil} constructor specifies a |
378 |
390 |
379 %%% FIXME: remove trailing underscore and use locale trick instead once this is |
391 %%% FIXME: remove trailing underscore and use locale trick instead once this is |
380 %%% supported. |
392 %%% supported. |
381 *} |
393 *} |
382 |
394 |
|
395 (*<*) |
|
396 end |
|
397 (*>*) |
383 datatype_new ('a, 'b) prod (infixr "*" 20) = |
398 datatype_new ('a, 'b) prod (infixr "*" 20) = |
384 Pair 'a 'b |
399 Pair 'a 'b |
385 |
400 |
386 (*<*) |
|
387 hide_const Nil Cons hd tl |
|
388 (*>*) |
|
389 datatype_new (set: 'a) list (map: map rel: list_all2) = |
401 datatype_new (set: 'a) list (map: map rel: list_all2) = |
390 null: Nil ("[]") |
402 null: Nil ("[]") |
391 | Cons (hd: 'a) (tl: "'a list") (infixr "#" 65) |
403 | Cons (hd: 'a) (tl: "'a list") (infixr "#" 65) |
392 |
404 |
393 text {* |
405 text {* |
394 Incidentally, this is how the traditional syntaxes are set up in @{theory List}: |
406 Incidentally, this is how the traditional syntaxes can be set up: |
395 *} |
407 *} |
396 |
408 |
397 syntax "_list" :: "args \<Rightarrow> 'a list" ("[(_)]") |
409 syntax "_list" :: "args \<Rightarrow> 'a list" ("[(_)]") |
398 |
410 |
399 translations |
411 translations |
576 text {* |
588 text {* |
577 * simple (depth 1) pattern matching on the left-hand side |
589 * simple (depth 1) pattern matching on the left-hand side |
578 *} |
590 *} |
579 |
591 |
580 primrec_new bool_of_trool :: "trool \<Rightarrow> bool" where |
592 primrec_new bool_of_trool :: "trool \<Rightarrow> bool" where |
581 "real_of_trool Faalse = False" | |
593 "bool_of_trool Faalse = False" | |
582 "real_of_trool Truue = True" |
594 "bool_of_trool Truue = True" |
583 |
595 |
584 text {* |
596 text {* |
585 * OK to specify the cases in a different order |
597 * OK to specify the cases in a different order |
586 * OK to leave out some case (but get a warning -- maybe we need a "quiet" |
598 * OK to leave out some case (but get a warning -- maybe we need a "quiet" |
587 or "silent" flag?) |
599 or "silent" flag?) |
588 * case is then unspecified |
600 * case is then unspecified |
589 |
601 |
590 More examples: |
602 More examples: |
591 *} |
603 *} |
592 |
604 |
593 primrec_new list_of_maybe :: "'a maybe \<Rightarrow> 'a list" where |
605 primrec_new the_list :: "'a option \<Rightarrow> 'a list" where |
594 "list_of_maybe Nothing = []" | |
606 "the_list None = []" | |
595 "list_of_maybe (Just a) = [a]" |
607 "the_list (Some a) = [a]" |
596 |
608 |
597 primrec_new maybe_def :: "'a \<Rightarrow> 'a maybe \<Rightarrow> 'a" where |
609 primrec_new the_default :: "'a \<Rightarrow> 'a option \<Rightarrow> 'a" where |
598 "maybe_def d Nothing = d" | |
610 "the_default d None = d" | |
599 "maybe_def _ (Just a) = a" |
611 "the_default _ (Some a) = a" |
600 |
612 |
601 primrec_new mirrror :: "('a, 'b, 'c) triple \<Rightarrow> ('c, 'b, 'a) triple" where |
613 primrec_new mirrror :: "('a, 'b, 'c) triple \<Rightarrow> ('c, 'b, 'a) triple" where |
602 "mirrror (Triple a b c) = Triple c b a" |
614 "mirrror (Triple a b c) = Triple c b a" |
603 |
615 |
604 |
616 |
625 |
637 |
626 primrec_new tfold :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> ('a, 'b) tlist \<Rightarrow> 'b" where |
638 primrec_new tfold :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> ('a, 'b) tlist \<Rightarrow> 'b" where |
627 "tfold _ (TNil b) = b" | |
639 "tfold _ (TNil b) = b" | |
628 "tfold f (TCons a as) = f a (tfold f as)" |
640 "tfold f (TCons a as) = f a (tfold f as)" |
629 |
641 |
|
642 text {* |
|
643 Show one example where fun is needed. |
|
644 *} |
630 |
645 |
631 subsubsection {* Mutual Recursion *} |
646 subsubsection {* Mutual Recursion *} |
632 |
647 |
633 text {* |
648 text {* |
634 E.g., converting even/odd naturals to plain old naturals: |
649 E.g., converting even/odd naturals to plain old naturals: |
641 "nat_of_enat EZero = 0" | |
656 "nat_of_enat EZero = 0" | |
642 "nat_of_enat (ESuc n) = Suc (nat_of_onat n)" | |
657 "nat_of_enat (ESuc n) = Suc (nat_of_onat n)" | |
643 "nat_of_onat (OSuc n) = Suc (nat_of_enat n)" |
658 "nat_of_onat (OSuc n) = Suc (nat_of_enat n)" |
644 |
659 |
645 text {* |
660 text {* |
646 Mutual recursion is even possible within a single type, an innovation over the |
661 Mutual recursion is be possible within a single type, but currently only using fun: |
647 old package: |
662 *} |
648 *} |
663 |
649 |
664 (*<*) |
650 primrec_new |
665 (* FIXME: remove hack once "primrec_new" is in place *) |
|
666 rep_datatype "0\<Colon>nat" Suc |
|
667 unfolding zero_nat_def by (erule nat.induct, assumption) auto |
|
668 (*>*) |
|
669 fun |
651 even :: "nat \<Rightarrow> bool" and |
670 even :: "nat \<Rightarrow> bool" and |
652 odd :: "nat \<Rightarrow> bool" |
671 odd :: "nat \<Rightarrow> bool" |
653 where |
672 where |
654 "even 0 = True" | |
673 "even 0 = True" | |
655 "even (Suc n) = odd n" | |
674 "even (Suc n) = odd n" | |
656 "odd 0 = False" | |
675 "odd 0 = False" | |
657 "odd (Suc n) = even n" |
676 "odd (Suc n) = even n" |
658 |
677 |
659 text {* |
678 text {* |
660 More elaborate: |
679 More elaborate example that works with primrec_new: |
661 *} |
680 *} |
662 |
681 |
663 primrec_new |
682 primrec_new |
664 eval\<^sub>e :: "('a, 'b) exp \<Rightarrow> real" and |
683 eval\<^sub>e :: "('a, 'b) exp \<Rightarrow> real" and |
665 eval\<^sub>t :: "('a, 'b) trm \<Rightarrow> real" and |
684 eval\<^sub>t :: "('a, 'b) trm \<Rightarrow> real" and |
678 |
697 |
679 (*<*) |
698 (*<*) |
680 datatype_new 'a treeFF = NodeFF 'a "'a treeFF list" |
699 datatype_new 'a treeFF = NodeFF 'a "'a treeFF list" |
681 datatype_new 'a treeFI = NodeFI 'a "'a treeFI llist" |
700 datatype_new 'a treeFI = NodeFI 'a "'a treeFI llist" |
682 (*>*) |
701 (*>*) |
683 primrec_new atFF0 :: "'a treeFF \<Rightarrow> nat list \<Rightarrow> 'a" where |
702 primrec_new atFF :: "'a treeFF \<Rightarrow> nat list \<Rightarrow> 'a" where |
684 "atFF0 (NodeFF a ts) js = |
703 "atFF (NodeFF a ts) js = |
685 (case js of |
704 (case js of |
686 [] \<Rightarrow> a |
705 [] \<Rightarrow> a |
687 | j # js' \<Rightarrow> at (map (\<lambda>t. atFF0 t js') ts) j)" |
706 | j # js' \<Rightarrow> at (map (\<lambda>t. atFF t js') ts) j)" |
688 |
707 |
689 primrec_new atFI :: "'a treeFI \<Rightarrow> nat list \<Rightarrow> 'a" where |
708 primrec_new atFI :: "'a treeFI \<Rightarrow> nat list \<Rightarrow> 'a" where |
690 "atFF (NodeFI a ts) js = |
709 "atFI (NodeFI a ts) js = |
691 (case js of |
710 (case js of |
692 [] \<Rightarrow> a |
711 [] \<Rightarrow> a |
693 | j # js' \<Rightarrow> at (llist_map (\<lambda>t. atFF t js') ts) j)" |
712 | j # js' \<Rightarrow> at (lmap (\<lambda>t. atFI t js') ts) j)" |
|
713 |
|
714 text {* |
|
715 Explain @{const lmap}. |
|
716 *} |
694 |
717 |
695 primrec_new sum_btree :: "('a\<Colon>plus) btree \<Rightarrow> 'a" where |
718 primrec_new sum_btree :: "('a\<Colon>plus) btree \<Rightarrow> 'a" where |
696 "sum_btree (BNode a lt rt) = |
719 "sum_btree (BNode a lt rt) = |
697 a + maybe_def 0 (maybe_map sum_btree lt) + |
720 a + the_default 0 (option_map sum_btree lt) + |
698 maybe_def 0 (maybe_map sum_btree rt)" |
721 the_default 0 (option_map sum_btree rt)" |
699 |
722 |
700 |
723 |
701 subsubsection {* Nested-as-Mutual Recursion *} |
724 subsubsection {* Nested-as-Mutual Recursion *} |
702 |
725 |
703 text {* |
726 text {* |
719 0 \<Rightarrow> at_treeFF t |
742 0 \<Rightarrow> at_treeFF t |
720 | Suc j' \<Rightarrow> at_treesFF ts j')" |
743 | Suc j' \<Rightarrow> at_treesFF ts j')" |
721 |
744 |
722 primrec_new |
745 primrec_new |
723 sum_btree :: "('a\<Colon>plus) btree \<Rightarrow> 'a" and |
746 sum_btree :: "('a\<Colon>plus) btree \<Rightarrow> 'a" and |
724 sum_btree_maybe :: "('a\<Colon>plus) btree maybe \<Rightarrow> 'a" |
747 sum_btree_option :: "('a\<Colon>plus) btree option \<Rightarrow> 'a" |
725 where |
748 where |
726 "sum_btree (BNode a lt rt) = |
749 "sum_btree (BNode a lt rt) = |
727 a + sum_btree_maybe lt + sum_btree_maybe rt" | |
750 a + sum_btree_option lt + sum_btree_option rt" | |
728 "sum_btree_maybe Nothing = 0" | |
751 "sum_btree_option None = 0" | |
729 "sum_btree_maybe (Just t) = sum_btree t" |
752 "sum_btree_option (Some t) = sum_btree t" |
730 |
753 |
731 text {* |
754 text {* |
732 * this can always be avoided; |
755 * this can always be avoided; |
733 * e.g. in our previous example, we first mapped the recursive |
756 * e.g. in our previous example, we first mapped the recursive |
734 calls, then we used a generic at function to retrieve the result |
757 calls, then we used a generic at function to retrieve the result |
737 just like there's no rule when to use fold and when to use |
760 just like there's no rule when to use fold and when to use |
738 primrec_new |
761 primrec_new |
739 |
762 |
740 * higher-order approach, considering nesting as nesting, is more |
763 * higher-order approach, considering nesting as nesting, is more |
741 compositional -- e.g. we saw how we could reuse an existing polymorphic |
764 compositional -- e.g. we saw how we could reuse an existing polymorphic |
742 at or maybe_def, whereas at_treesFF is much more specific |
765 at or the_default, whereas at_treesFF is much more specific |
743 |
766 |
744 * but: |
767 * but: |
745 * is perhaps less intuitive, because it requires higher-order thinking |
768 * is perhaps less intuitive, because it requires higher-order thinking |
746 * may seem inefficient, and indeed with the code generator the |
769 * may seem inefficient, and indeed with the code generator the |
747 mutually recursive version might be nicer |
770 mutually recursive version might be nicer |
1086 Tobias Nipkow and Makarius Wenzel made this work possible. Andreas Lochbihler |
1109 Tobias Nipkow and Makarius Wenzel made this work possible. Andreas Lochbihler |
1087 provided lots of comments on earlier versions of the package, especially for the |
1110 provided lots of comments on earlier versions of the package, especially for the |
1088 coinductive part. Brian Huffman suggested major simplifications to the internal |
1111 coinductive part. Brian Huffman suggested major simplifications to the internal |
1089 constructions, much of which has yet to be implemented. Florian Haftmann and |
1112 constructions, much of which has yet to be implemented. Florian Haftmann and |
1090 Christian Urban provided general advice advice on Isabelle and package writing. |
1113 Christian Urban provided general advice advice on Isabelle and package writing. |
1091 Stefan Milius and Lutz Schr\"oder suggested an elegant prove to eliminate one of |
1114 Stefan Milius and Lutz Schr\"oder suggested an elegant proof to eliminate one of |
1092 the BNF assumptions. |
1115 the BNF assumptions. |
1093 *} |
1116 *} |
1094 |
1117 |
1095 end |
1118 end |