634 \end{itemize} |
622 \end{itemize} |
635 |
623 |
636 \noindent |
624 \noindent |
637 The case combinator, discriminators, and selectors are collectively called |
625 The case combinator, discriminators, and selectors are collectively called |
638 \emph{destructors}. The prefix ``@{text "t."}'' is an optional component of the |
626 \emph{destructors}. The prefix ``@{text "t."}'' is an optional component of the |
639 name and is normally hidden. |
627 name and is normally hidden. |
640 *} |
628 *} |
641 |
629 |
642 |
630 |
643 subsection {* Generated Theorems |
631 subsection {* Generated Theorems |
644 \label{ssec:datatype-generated-theorems} *} |
632 \label{ssec:datatype-generated-theorems} *} |
1681 long as they occur under a constructor, which itself appears either directly to |
1669 long as they occur under a constructor, which itself appears either directly to |
1682 the right of the equal sign or in a conditional expression: |
1670 the right of the equal sign or in a conditional expression: |
1683 *} |
1671 *} |
1684 |
1672 |
1685 primcorec literate :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a llist" where |
1673 primcorec literate :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a llist" where |
1686 "literate f x = LCons x (literate f (f x))" |
1674 "literate g x = LCons x (literate g (g x))" |
1687 |
1675 |
1688 text {* \blankline *} |
1676 text {* \blankline *} |
1689 |
1677 |
1690 primcorec siterate :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a stream" where |
1678 primcorec siterate :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a stream" where |
1691 "siterate f x = SCons x (siterate f (f x))" |
1679 "siterate g x = SCons x (siterate g (g x))" |
1692 |
1680 |
1693 text {* |
1681 text {* |
1694 \noindent |
1682 \noindent |
1695 The constructor ensures that progress is made---i.e., the function is |
1683 The constructor ensures that progress is made---i.e., the function is |
1696 \emph{productive}. The above functions compute the infinite lazy list or stream |
1684 \emph{productive}. The above functions compute the infinite lazy list or stream |
1697 @{text "[x, f x, f (f x), \<dots>]"}. Productivity guarantees that prefixes |
1685 @{text "[x, g x, g (g x), \<dots>]"}. Productivity guarantees that prefixes |
1698 @{text "[x, f x, f (f x), \<dots>, (f ^^ k) x]"} of arbitrary finite length |
1686 @{text "[x, g x, g (g x), \<dots>, (g ^^ k) x]"} of arbitrary finite length |
1699 @{text k} can be computed by unfolding the code equation a finite number of |
1687 @{text k} can be computed by unfolding the code equation a finite number of |
1700 times. |
1688 times. |
1701 |
1689 |
1702 Corecursive functions construct codatatype values, but nothing prevents them |
1690 Corecursive functions construct codatatype values, but nothing prevents them |
1703 from also consuming such values. The following function drops every second |
1691 from also consuming such values. The following function drops every second |
1712 Constructs such as @{text "let"}---@{text "in"}, @{text |
1700 Constructs such as @{text "let"}---@{text "in"}, @{text |
1713 "if"}---@{text "then"}---@{text "else"}, and @{text "case"}---@{text "of"} may |
1701 "if"}---@{text "then"}---@{text "else"}, and @{text "case"}---@{text "of"} may |
1714 appear around constructors that guard corecursive calls: |
1702 appear around constructors that guard corecursive calls: |
1715 *} |
1703 *} |
1716 |
1704 |
1717 primcorec_notyet lappend :: "'a llist \<Rightarrow> 'a llist \<Rightarrow> 'a llist" where |
1705 primcorec lappend :: "'a llist \<Rightarrow> 'a llist \<Rightarrow> 'a llist" where |
1718 "lappend xs ys = |
1706 "lappend xs ys = |
1719 (case xs of |
1707 (case xs of |
1720 LNil \<Rightarrow> ys |
1708 LNil \<Rightarrow> ys |
1721 | LCons x xs' \<Rightarrow> LCons x (lappend xs' ys))" |
1709 | LCons x xs' \<Rightarrow> LCons x (lappend xs' ys))" |
1722 |
1710 |
1733 The example below constructs a pseudorandom process value. It takes a stream of |
1721 The example below constructs a pseudorandom process value. It takes a stream of |
1734 actions (@{text s}), a pseudorandom function generator (@{text f}), and a |
1722 actions (@{text s}), a pseudorandom function generator (@{text f}), and a |
1735 pseudorandom seed (@{text n}): |
1723 pseudorandom seed (@{text n}): |
1736 *} |
1724 *} |
1737 |
1725 |
1738 primcorec_notyet |
1726 primcorec |
1739 random_process :: "'a stream \<Rightarrow> (int \<Rightarrow> int) \<Rightarrow> int \<Rightarrow> 'a process" |
1727 random_process :: "'a stream \<Rightarrow> (int \<Rightarrow> int) \<Rightarrow> int \<Rightarrow> 'a process" |
1740 where |
1728 where |
1741 "random_process s f n = |
1729 "random_process s f n = |
1742 (if n mod 4 = 0 then |
1730 (if n mod 4 = 0 then |
1743 Fail |
1731 Fail |
1778 |
1766 |
1779 text {* |
1767 text {* |
1780 The next pair of examples generalize the @{const literate} and @{const siterate} |
1768 The next pair of examples generalize the @{const literate} and @{const siterate} |
1781 functions (Section~\ref{sssec:primcorec-nested-corecursion}) to possibly |
1769 functions (Section~\ref{sssec:primcorec-nested-corecursion}) to possibly |
1782 infinite trees in which subnodes are organized either as a lazy list (@{text |
1770 infinite trees in which subnodes are organized either as a lazy list (@{text |
1783 tree\<^sub>i\<^sub>i}) or as a finite set (@{text tree\<^sub>i\<^sub>s}): |
1771 tree\<^sub>i\<^sub>i}) or as a finite set (@{text tree\<^sub>i\<^sub>s}). They rely on the map functions of |
|
1772 the nesting type constructors to lift the corecursive calls: |
1784 *} |
1773 *} |
1785 |
1774 |
1786 primcorec iterate\<^sub>i\<^sub>i :: "('a \<Rightarrow> 'a llist) \<Rightarrow> 'a \<Rightarrow> 'a tree\<^sub>i\<^sub>i" where |
1775 primcorec iterate\<^sub>i\<^sub>i :: "('a \<Rightarrow> 'a llist) \<Rightarrow> 'a \<Rightarrow> 'a tree\<^sub>i\<^sub>i" where |
1787 "iterate\<^sub>i\<^sub>i f x = Node\<^sub>i\<^sub>i x (lmap (iterate\<^sub>i\<^sub>i f) (f x))" |
1776 "iterate\<^sub>i\<^sub>i g x = Node\<^sub>i\<^sub>i x (lmap (iterate\<^sub>i\<^sub>i g) (g x))" |
1788 |
1777 |
1789 text {* \blankline *} |
1778 text {* \blankline *} |
1790 |
1779 |
1791 primcorec iterate\<^sub>i\<^sub>s :: "('a \<Rightarrow> 'a fset) \<Rightarrow> 'a \<Rightarrow> 'a tree\<^sub>i\<^sub>s" where |
1780 primcorec iterate\<^sub>i\<^sub>s :: "('a \<Rightarrow> 'a fset) \<Rightarrow> 'a \<Rightarrow> 'a tree\<^sub>i\<^sub>s" where |
1792 "iterate\<^sub>i\<^sub>s f x = Node\<^sub>i\<^sub>s x (fimage (iterate\<^sub>i\<^sub>s f) (f x))" |
1781 "iterate\<^sub>i\<^sub>s g x = Node\<^sub>i\<^sub>s x (fimage (iterate\<^sub>i\<^sub>s g) (g x))" |
1793 |
1782 |
1794 text {* |
1783 text {* |
1795 \noindent |
1784 \noindent |
1796 Deterministic finite automata (DFAs) are traditionally defined as 5-tuples |
1785 Both examples follow the usual format for constructor arguments associated |
1797 @{text "(Q, \<Sigma>, \<delta>, q\<^sub>0, F)"}, where @{text Q} is a finite set of states, |
1786 with nested recursive occurrences of the datatype. Consider |
|
1787 @{const iterate\<^sub>i\<^sub>i}. The term @{term "g x"} constructs an @{typ "'a llist"} |
|
1788 value, which is turned into an @{typ "'a tree\<^sub>i\<^sub>i llist"} value using |
|
1789 @{const lmap}. |
|
1790 |
|
1791 This format may sometimes feel artificial. The following function constructs |
|
1792 a tree with a single, infinite branch from a stream: |
|
1793 *} |
|
1794 |
|
1795 primcorec tree\<^sub>i\<^sub>i_of_stream :: "'a stream \<Rightarrow> 'a tree\<^sub>i\<^sub>i" where |
|
1796 "tree\<^sub>i\<^sub>i_of_stream s = |
|
1797 Node\<^sub>i\<^sub>i (shd s) (lmap tree\<^sub>i\<^sub>i_of_stream (LCons (stl s) LNil))" |
|
1798 |
|
1799 text {* |
|
1800 \noindent |
|
1801 A more natural syntax, also supported by Isabelle, is to move corecursive calls |
|
1802 under constructors: |
|
1803 *} |
|
1804 |
|
1805 primcorec (*<*)(in late) (*>*)tree\<^sub>i\<^sub>i_of_stream :: "'a stream \<Rightarrow> 'a tree\<^sub>i\<^sub>i" where |
|
1806 "tree\<^sub>i\<^sub>i_of_stream s = Node\<^sub>i\<^sub>i (shd s) (LCons (tree\<^sub>i\<^sub>i_of_stream (stl s)) LNil)" |
|
1807 |
|
1808 text {* |
|
1809 The next example illustrates corecursion through functions, which is a bit |
|
1810 special. Deterministic finite automata (DFAs) are traditionally defined as |
|
1811 5-tuples @{text "(Q, \<Sigma>, \<delta>, q\<^sub>0, F)"}, where @{text Q} is a finite set of states, |
1798 @{text \<Sigma>} is a finite alphabet, @{text \<delta>} is a transition function, @{text q\<^sub>0} |
1812 @{text \<Sigma>} is a finite alphabet, @{text \<delta>} is a transition function, @{text q\<^sub>0} |
1799 is an initial state, and @{text F} is a set of final states. The following |
1813 is an initial state, and @{text F} is a set of final states. The following |
1800 function translates a DFA into a @{type state_machine}: |
1814 function translates a DFA into a @{type state_machine}: |
1801 *} |
1815 *} |
1802 |
1816 |
1831 text {* \blankline *} |
1845 text {* \blankline *} |
1832 |
1846 |
1833 primcorec |
1847 primcorec |
1834 or_sm :: "'a state_machine \<Rightarrow> 'a state_machine \<Rightarrow> 'a state_machine" |
1848 or_sm :: "'a state_machine \<Rightarrow> 'a state_machine \<Rightarrow> 'a state_machine" |
1835 where |
1849 where |
1836 "or_sm M N = |
1850 "or_sm M N = State_Machine (accept M \<or> accept N) |
1837 State_Machine (accept M \<or> accept N) |
1851 (\<lambda>a. or_sm (trans M a) (trans N a))" |
1838 (\<lambda>a. or_sm (trans M a) (trans N a))" |
|
1839 |
1852 |
1840 |
1853 |
1841 subsubsection {* Nested-as-Mutual Corecursion |
1854 subsubsection {* Nested-as-Mutual Corecursion |
1842 \label{sssec:primcorec-nested-as-mutual-corecursion} *} |
1855 \label{sssec:primcorec-nested-as-mutual-corecursion} *} |
1843 |
1856 |
1846 were mutually recursive |
1859 were mutually recursive |
1847 (Section~\ref{sssec:primrec-nested-as-mutual-recursion}), it is possible to |
1860 (Section~\ref{sssec:primrec-nested-as-mutual-recursion}), it is possible to |
1848 pretend that nested codatatypes are mutually corecursive. For example: |
1861 pretend that nested codatatypes are mutually corecursive. For example: |
1849 *} |
1862 *} |
1850 |
1863 |
1851 primcorec_notyet |
1864 primcorec |
1852 iterate\<^sub>i\<^sub>i :: "('a \<Rightarrow> 'a llist) \<Rightarrow> 'a \<Rightarrow> 'a tree\<^sub>i\<^sub>i" and |
1865 (*<*)(in late) (*>*)iterate\<^sub>i\<^sub>i :: "('a \<Rightarrow> 'a llist) \<Rightarrow> 'a \<Rightarrow> 'a tree\<^sub>i\<^sub>i" and |
1853 iterates\<^sub>i\<^sub>i :: "('a \<Rightarrow> 'a llist) \<Rightarrow> 'a llist \<Rightarrow> 'a tree\<^sub>i\<^sub>i llist" |
1866 iterates\<^sub>i\<^sub>i :: "('a \<Rightarrow> 'a llist) \<Rightarrow> 'a llist \<Rightarrow> 'a tree\<^sub>i\<^sub>i llist" |
1854 where |
1867 where |
1855 "iterate\<^sub>i\<^sub>i f x = Node\<^sub>i\<^sub>i x (iterates\<^sub>i\<^sub>i f (f x))" | |
1868 "iterate\<^sub>i\<^sub>i g x = Node\<^sub>i\<^sub>i x (iterates\<^sub>i\<^sub>i g (g x))" | |
1856 "iterates\<^sub>i\<^sub>i f xs = |
1869 "iterates\<^sub>i\<^sub>i g xs = |
1857 (case xs of |
1870 (case xs of |
1858 LNil \<Rightarrow> LNil |
1871 LNil \<Rightarrow> LNil |
1859 | LCons x xs' \<Rightarrow> LCons (iterate\<^sub>i\<^sub>i f x) (iterates\<^sub>i\<^sub>i f xs'))" |
1872 | LCons x xs' \<Rightarrow> LCons (iterate\<^sub>i\<^sub>i g x) (iterates\<^sub>i\<^sub>i g xs'))" |
1860 (*<*) |
1873 (*<*) |
1861 end |
1874 end |
1862 (*>*) |
1875 (*>*) |
1863 |
1876 |
1864 |
1877 |
1949 *} |
1962 *} |
1950 |
1963 |
1951 primcorec literate :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a llist" where |
1964 primcorec literate :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a llist" where |
1952 "\<not> lnull (literate _ x)" | |
1965 "\<not> lnull (literate _ x)" | |
1953 "lhd (literate _ x) = x" | |
1966 "lhd (literate _ x) = x" | |
1954 "ltl (literate f x) = literate f (f x)" |
1967 "ltl (literate g x) = literate g (g x)" |
1955 |
1968 |
1956 text {* \blankline *} |
1969 text {* \blankline *} |
1957 |
1970 |
1958 primcorec siterate :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a stream" where |
1971 primcorec siterate :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a stream" where |
1959 "shd (siterate _ x) = x" | |
1972 "shd (siterate _ x) = x" | |
1960 "stl (siterate f x) = siterate f (f x)" |
1973 "stl (siterate g x) = siterate g (g x)" |
1961 |
1974 |
1962 text {* \blankline *} |
1975 text {* \blankline *} |
1963 |
1976 |
1964 primcorec every_snd :: "'a stream \<Rightarrow> 'a stream" where |
1977 primcorec every_snd :: "'a stream \<Rightarrow> 'a stream" where |
1965 "shd (every_snd s) = shd s" | |
1978 "shd (every_snd s) = shd s" | |