1118 The same principle applies for arbitrary type constructors through which |
1118 The same principle applies for arbitrary type constructors through which |
1119 recursion is possible. Notably, the map function for the function type |
1119 recursion is possible. Notably, the map function for the function type |
1120 (@{text \<Rightarrow>}) is simply composition (@{text "op \<circ>"}): |
1120 (@{text \<Rightarrow>}) is simply composition (@{text "op \<circ>"}): |
1121 *} |
1121 *} |
1122 |
1122 |
1123 primrec_new (*<*)(in early) (*>*)ftree_map :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a ftree \<Rightarrow> 'a ftree" where |
1123 primrec_new (*<*)(in early) (*>*)relabel_ft :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a ftree \<Rightarrow> 'a ftree" where |
1124 "ftree_map f (FTLeaf x) = FTLeaf (f x)" | |
1124 "relabel_ft f (FTLeaf x) = FTLeaf (f x)" | |
1125 "ftree_map f (FTNode g) = FTNode (ftree_map f \<circ> g)" |
1125 "relabel_ft f (FTNode g) = FTNode (relabel_ft f \<circ> g)" |
1126 |
1126 |
1127 text {* |
1127 text {* |
1128 \noindent |
1128 \noindent |
1129 (No such map function is defined by the package because the type |
|
1130 variable @{typ 'a} is dead in @{typ "'a ftree"}.) |
|
1131 For convenience, recursion through functions can also be expressed using |
1129 For convenience, recursion through functions can also be expressed using |
1132 $\lambda$-expressions and function application rather than through composition. |
1130 $\lambda$-abstractions and function application rather than through composition. |
1133 For example: |
1131 For example: |
1134 *} |
1132 *} |
1135 |
1133 |
1136 primrec_new ftree_map :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a ftree \<Rightarrow> 'a ftree" where |
1134 primrec_new relabel_ft :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a ftree \<Rightarrow> 'a ftree" where |
1137 "ftree_map f (FTLeaf x) = FTLeaf (f x)" | |
1135 "relabel_ft f (FTLeaf x) = FTLeaf (f x)" | |
1138 "ftree_map f (FTNode g) = FTNode (\<lambda>x. ftree_map f (g x))" |
1136 "relabel_ft f (FTNode g) = FTNode (\<lambda>x. relabel_ft f (g x))" |
|
1137 |
|
1138 text {* |
|
1139 \noindent |
|
1140 For recursion through curried $n$-ary functions, $n$ applications of |
|
1141 @{term "op \<circ>"} are necessary. The examples below illustrate the case where |
|
1142 $n = 2$: |
|
1143 *} |
|
1144 |
|
1145 datatype_new 'a ftree2 = FTLeaf2 'a | FTNode2 "'a \<Rightarrow> 'a \<Rightarrow> 'a ftree2" |
|
1146 |
|
1147 text {* \blankline *} |
|
1148 |
|
1149 primrec_new (*<*)(in early) (*>*)relabel_ft2 :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a ftree2 \<Rightarrow> 'a ftree2" where |
|
1150 "relabel_ft2 f (FTLeaf2 x) = FTLeaf2 (f x)" | |
|
1151 "relabel_ft2 f (FTNode2 g) = FTNode2 (op \<circ> (op \<circ> (relabel_ft2 f)) g)" |
|
1152 |
|
1153 text {* \blankline *} |
|
1154 |
|
1155 primrec_new relabel_ft2 :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a ftree2 \<Rightarrow> 'a ftree2" where |
|
1156 "relabel_ft2 f (FTLeaf2 x) = FTLeaf2 (f x)" | |
|
1157 "relabel_ft2 f (FTNode2 g) = FTNode2 (\<lambda>x y. relabel_ft2 f (g x y))" |
1139 |
1158 |
1140 |
1159 |
1141 subsubsection {* Nested-as-Mutual Recursion |
1160 subsubsection {* Nested-as-Mutual Recursion |
1142 \label{sssec:primrec-nested-as-mutual-recursion} *} |
1161 \label{sssec:primrec-nested-as-mutual-recursion} *} |
1143 |
1162 |
1656 view is favored in the examples below. Sections |
1675 view is favored in the examples below. Sections |
1657 \ref{ssec:primrec-constructor-view} and \ref{ssec:primrec-destructor-view} |
1676 \ref{ssec:primrec-constructor-view} and \ref{ssec:primrec-destructor-view} |
1658 present the same examples expressed using the constructor and destructor views. |
1677 present the same examples expressed using the constructor and destructor views. |
1659 *} |
1678 *} |
1660 |
1679 |
1661 (*<*) |
|
1662 locale code_view |
|
1663 begin |
|
1664 (*>*) |
|
1665 |
|
1666 subsubsection {* Simple Corecursion |
1680 subsubsection {* Simple Corecursion |
1667 \label{sssec:primcorec-simple-corecursion} *} |
1681 \label{sssec:primcorec-simple-corecursion} *} |
1668 |
1682 |
1669 text {* |
1683 text {* |
1670 Following the code view, corecursive calls are allowed on the right-hand side as |
1684 Following the code view, corecursive calls are allowed on the right-hand side as |
1817 *} |
1831 *} |
1818 |
1832 |
1819 primcorec |
1833 primcorec |
1820 (*<*)(in early) (*>*)sm_of_dfa :: "('q \<Rightarrow> 'a \<Rightarrow> 'q) \<Rightarrow> 'q set \<Rightarrow> 'q \<Rightarrow> 'a state_machine" |
1834 (*<*)(in early) (*>*)sm_of_dfa :: "('q \<Rightarrow> 'a \<Rightarrow> 'q) \<Rightarrow> 'q set \<Rightarrow> 'q \<Rightarrow> 'a state_machine" |
1821 where |
1835 where |
1822 "sm_of_dfa \<delta> F q = State_Machine (q \<in> F) (sm_of_dfa \<delta> F o \<delta> q)" |
1836 "sm_of_dfa \<delta> F q = State_Machine (q \<in> F) (sm_of_dfa \<delta> F \<circ> \<delta> q)" |
1823 |
1837 |
1824 text {* |
1838 text {* |
1825 \noindent |
1839 \noindent |
1826 The map function for the function type (@{text \<Rightarrow>}) is composition |
1840 The map function for the function type (@{text \<Rightarrow>}) is composition |
1827 (@{text "op \<circ>"}). For convenience, corecursion through functions can |
1841 (@{text "op \<circ>"}). For convenience, corecursion through functions can |
1828 also be expressed using $\lambda$-expressions and function application rather |
1842 also be expressed using $\lambda$-abstractions and function application rather |
1829 than through composition. For example: |
1843 than through composition. For example: |
1830 *} |
1844 *} |
1831 |
1845 |
1832 primcorec |
1846 primcorec |
1833 sm_of_dfa :: "('q \<Rightarrow> 'a \<Rightarrow> 'q) \<Rightarrow> 'q set \<Rightarrow> 'q \<Rightarrow> 'a state_machine" |
1847 sm_of_dfa :: "('q \<Rightarrow> 'a \<Rightarrow> 'q) \<Rightarrow> 'q set \<Rightarrow> 'q \<Rightarrow> 'a state_machine" |
1834 where |
1848 where |
1835 "sm_of_dfa \<delta> F q = State_Machine (q \<in> F) (sm_of_dfa \<delta> F o \<delta> q)" |
1849 "sm_of_dfa \<delta> F q = State_Machine (q \<in> F) (\<lambda>a. sm_of_dfa \<delta> F (\<delta> q a))" |
1836 |
1850 |
1837 text {* \blankline *} |
1851 text {* \blankline *} |
1838 |
1852 |
1839 primcorec empty_sm :: "'a state_machine" where |
1853 primcorec empty_sm :: "'a state_machine" where |
1840 "empty_sm = State_Machine False (\<lambda>_. empty_sm)" |
1854 "empty_sm = State_Machine False (\<lambda>_. empty_sm)" |
1849 primcorec |
1863 primcorec |
1850 or_sm :: "'a state_machine \<Rightarrow> 'a state_machine \<Rightarrow> 'a state_machine" |
1864 or_sm :: "'a state_machine \<Rightarrow> 'a state_machine \<Rightarrow> 'a state_machine" |
1851 where |
1865 where |
1852 "or_sm M N = State_Machine (accept M \<or> accept N) |
1866 "or_sm M N = State_Machine (accept M \<or> accept N) |
1853 (\<lambda>a. or_sm (trans M a) (trans N a))" |
1867 (\<lambda>a. or_sm (trans M a) (trans N a))" |
|
1868 |
|
1869 text {* |
|
1870 \noindent |
|
1871 For recursion through curried $n$-ary functions, $n$ applications of |
|
1872 @{term "op \<circ>"} are necessary. The examples below illustrate the case where |
|
1873 $n = 2$: |
|
1874 *} |
|
1875 |
|
1876 codatatype ('a, 'b) state_machine2 = |
|
1877 State_Machine2 (accept2: bool) (trans2: "'a \<Rightarrow> 'b \<Rightarrow> ('a, 'b) state_machine2") |
|
1878 |
|
1879 text {* \blankline *} |
|
1880 |
|
1881 primcorec |
|
1882 (*<*)(in early) (*>*)sm2_of_dfa :: "('q \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> 'q) \<Rightarrow> 'q set \<Rightarrow> 'q \<Rightarrow> ('a, 'b) state_machine2" |
|
1883 where |
|
1884 "sm2_of_dfa \<delta> F q = State_Machine2 (q \<in> F) (op \<circ> (op \<circ> (sm2_of_dfa \<delta> F)) (\<delta> q))" |
|
1885 |
|
1886 text {* \blankline *} |
|
1887 |
|
1888 primcorec |
|
1889 sm2_of_dfa :: "('q \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> 'q) \<Rightarrow> 'q set \<Rightarrow> 'q \<Rightarrow> ('a, 'b) state_machine2" |
|
1890 where |
|
1891 "sm2_of_dfa \<delta> F q = State_Machine2 (q \<in> F) (\<lambda>a b. sm2_of_dfa \<delta> F (\<delta> q a b))" |
1854 |
1892 |
1855 |
1893 |
1856 subsubsection {* Nested-as-Mutual Corecursion |
1894 subsubsection {* Nested-as-Mutual Corecursion |
1857 \label{sssec:primcorec-nested-as-mutual-corecursion} *} |
1895 \label{sssec:primcorec-nested-as-mutual-corecursion} *} |
1858 |
1896 |
1870 "iterate\<^sub>i\<^sub>i g x = Node\<^sub>i\<^sub>i x (iterates\<^sub>i\<^sub>i g (g x))" | |
1908 "iterate\<^sub>i\<^sub>i g x = Node\<^sub>i\<^sub>i x (iterates\<^sub>i\<^sub>i g (g x))" | |
1871 "iterates\<^sub>i\<^sub>i g xs = |
1909 "iterates\<^sub>i\<^sub>i g xs = |
1872 (case xs of |
1910 (case xs of |
1873 LNil \<Rightarrow> LNil |
1911 LNil \<Rightarrow> LNil |
1874 | LCons x xs' \<Rightarrow> LCons (iterate\<^sub>i\<^sub>i g x) (iterates\<^sub>i\<^sub>i g xs'))" |
1912 | LCons x xs' \<Rightarrow> LCons (iterate\<^sub>i\<^sub>i g x) (iterates\<^sub>i\<^sub>i g xs'))" |
1875 (*<*) |
|
1876 end |
|
1877 (*>*) |
|
1878 |
1913 |
1879 |
1914 |
1880 subsubsection {* Constructor View |
1915 subsubsection {* Constructor View |
1881 \label{ssec:primrec-constructor-view} *} |
1916 \label{ssec:primrec-constructor-view} *} |
1882 |
1917 |
1883 (*<*) |
1918 (*<*) |
1884 locale ctr_view = code_view |
1919 locale ctr_view |
1885 begin |
1920 begin |
1886 (*>*) |
1921 (*>*) |
1887 |
1922 |
1888 text {* |
1923 text {* |
1889 The constructor view is similar to the code view, but there is one separate |
1924 The constructor view is similar to the code view, but there is one separate |
2005 constructor should be taken otherwise. This can be made explicit by adding |
2040 constructor should be taken otherwise. This can be made explicit by adding |
2006 *} |
2041 *} |
2007 |
2042 |
2008 (*<*) |
2043 (*<*) |
2009 end |
2044 end |
|
2045 |
|
2046 locale dtr_view2 |
|
2047 begin |
2010 |
2048 |
2011 primcorec lappend :: "'a llist \<Rightarrow> 'a llist \<Rightarrow> 'a llist" where |
2049 primcorec lappend :: "'a llist \<Rightarrow> 'a llist \<Rightarrow> 'a llist" where |
2012 "lnull xs \<Longrightarrow> lnull ys \<Longrightarrow> lnull (lappend xs ys)" | |
2050 "lnull xs \<Longrightarrow> lnull ys \<Longrightarrow> lnull (lappend xs ys)" | |
2013 (*>*) |
2051 (*>*) |
2014 "_ \<Longrightarrow> \<not> lnull (lappend xs ys)" |
2052 "_ \<Longrightarrow> \<not> lnull (lappend xs ys)" |
2015 (*<*) | |
2053 (*<*) | |
2016 "lhd (lappend xs ys) = lhd (if lnull xs then ys else xs)" | |
2054 "lhd (lappend xs ys) = lhd (if lnull xs then ys else xs)" | |
2017 "ltl (lappend xs ys) = (if xs = LNil then ltl ys else lappend (ltl xs) ys)" |
2055 "ltl (lappend xs ys) = (if xs = LNil then ltl ys else lappend (ltl xs) ys)" |
2018 |
|
2019 context dest_view begin |
|
2020 (*>*) |
2056 (*>*) |
2021 |
2057 |
2022 text {* |
2058 text {* |
2023 \noindent |
2059 \noindent |
2024 to the specification. The generated selector theorems are conditional. |
2060 to the specification. The generated selector theorems are conditional. |