1954 |
1954 |
1955 \end{description} |
1955 \end{description} |
1956 *} |
1956 *} |
1957 |
1957 |
1958 |
1958 |
1959 subsection {* The old code generator (S. Berghofer) *} |
|
1960 |
|
1961 text {* This framework generates code from both functional and |
|
1962 relational programs to SML, as explained below. |
|
1963 |
|
1964 \begin{matharray}{rcl} |
|
1965 @{command_def "code_module"} & : & @{text "theory \<rightarrow> theory"} \\ |
|
1966 @{command_def "code_library"} & : & @{text "theory \<rightarrow> theory"} \\ |
|
1967 @{command_def "consts_code"} & : & @{text "theory \<rightarrow> theory"} \\ |
|
1968 @{command_def "types_code"} & : & @{text "theory \<rightarrow> theory"} \\ |
|
1969 @{attribute_def code} & : & @{text attribute} \\ |
|
1970 \end{matharray} |
|
1971 |
|
1972 @{rail " |
|
1973 ( @@{command code_module} | @@{command code_library} ) modespec? @{syntax name}? \\ |
|
1974 ( @'file' name ) ? ( @'imports' ( @{syntax name} + ) ) ? \\ |
|
1975 @'contains' ( ( @{syntax name} '=' @{syntax term} ) + | @{syntax term} + ) |
|
1976 ; |
|
1977 |
|
1978 modespec: '(' ( @{syntax name} * ) ')' |
|
1979 ; |
|
1980 |
|
1981 @@{command (HOL) consts_code} (codespec +) |
|
1982 ; |
|
1983 |
|
1984 codespec: const template attachment ? |
|
1985 ; |
|
1986 |
|
1987 @@{command (HOL) types_code} (tycodespec +) |
|
1988 ; |
|
1989 |
|
1990 tycodespec: @{syntax name} template attachment ? |
|
1991 ; |
|
1992 |
|
1993 const: @{syntax term} |
|
1994 ; |
|
1995 |
|
1996 template: '(' @{syntax string} ')' |
|
1997 ; |
|
1998 |
|
1999 attachment: 'attach' modespec? '{' @{syntax text} '}' |
|
2000 ; |
|
2001 |
|
2002 @@{attribute code} name? |
|
2003 "} |
|
2004 *} |
|
2005 |
|
2006 |
|
2007 subsubsection {* Invoking the code generator *} |
|
2008 |
|
2009 text {* The code generator is invoked via the @{command code_module} |
|
2010 and @{command code_library} commands, which correspond to |
|
2011 \emph{incremental} and \emph{modular} code generation, respectively. |
|
2012 |
|
2013 \begin{description} |
|
2014 |
|
2015 \item [Modular] For each theory, an ML structure is generated, |
|
2016 containing the code generated from the constants defined in this |
|
2017 theory. |
|
2018 |
|
2019 \item [Incremental] All the generated code is emitted into the same |
|
2020 structure. This structure may import code from previously generated |
|
2021 structures, which can be specified via @{keyword "imports"}. |
|
2022 Moreover, the generated structure may also be referred to in later |
|
2023 invocations of the code generator. |
|
2024 |
|
2025 \end{description} |
|
2026 |
|
2027 After the @{command code_module} and @{command code_library} |
|
2028 keywords, the user may specify an optional list of ``modes'' in |
|
2029 parentheses. These can be used to instruct the code generator to |
|
2030 emit additional code for special purposes, e.g.\ functions for |
|
2031 converting elements of generated datatypes to Isabelle terms, or |
|
2032 test data generators. The list of modes is followed by a module |
|
2033 name. The module name is optional for modular code generation, but |
|
2034 must be specified for incremental code generation. |
|
2035 |
|
2036 The code can either be written to a file, in which case a file name |
|
2037 has to be specified after the @{keyword "file"} keyword, or be loaded |
|
2038 directly into Isabelle's ML environment. In the latter case, the |
|
2039 @{command ML} theory command can be used to inspect the results |
|
2040 interactively, for example. |
|
2041 |
|
2042 The terms from which to generate code can be specified after the |
|
2043 @{keyword "contains"} keyword, either as a list of bindings, or just |
|
2044 as a list of terms. In the latter case, the code generator just |
|
2045 produces code for all constants and types occuring in the term, but |
|
2046 does not bind the compiled terms to ML identifiers. |
|
2047 |
|
2048 Here is an example: |
|
2049 *} |
|
2050 |
|
2051 code_module Test |
|
2052 contains test = "foldl op + (0 :: int) [1, 2, 3, 4, 5]" |
|
2053 |
|
2054 text {* \noindent This binds the result of compiling the given term to |
|
2055 the ML identifier @{ML Test.test}. *} |
|
2056 |
|
2057 ML {* @{assert} (Test.test = 15) *} |
|
2058 |
|
2059 |
|
2060 subsubsection {* Configuring the code generator *} |
|
2061 |
|
2062 text {* When generating code for a complex term, the code generator |
|
2063 recursively calls itself for all subterms. When it arrives at a |
|
2064 constant, the default strategy of the code generator is to look up |
|
2065 its definition and try to generate code for it. Constants which |
|
2066 have no definitions that are immediately executable, may be |
|
2067 associated with a piece of ML code manually using the @{command_ref |
|
2068 consts_code} command. It takes a list whose elements consist of a |
|
2069 constant (given in usual term syntax -- an explicit type constraint |
|
2070 accounts for overloading), and a mixfix template describing the ML |
|
2071 code. The latter is very much the same as the mixfix templates used |
|
2072 when declaring new constants. The most notable difference is that |
|
2073 terms may be included in the ML template using antiquotation |
|
2074 brackets @{verbatim "{"}@{verbatim "*"}~@{text "..."}~@{verbatim |
|
2075 "*"}@{verbatim "}"}. |
|
2076 |
|
2077 A similar mechanism is available for types: @{command_ref |
|
2078 types_code} associates type constructors with specific ML code. |
|
2079 |
|
2080 For example, the following declarations copied from @{file |
|
2081 "~~/src/HOL/Product_Type.thy"} describe how the product type of |
|
2082 Isabelle/HOL should be compiled to ML. *} |
|
2083 |
|
2084 typedecl ('a, 'b) prod |
|
2085 consts Pair :: "'a \<Rightarrow> 'b \<Rightarrow> ('a, 'b) prod" |
|
2086 |
|
2087 types_code prod ("(_ */ _)") |
|
2088 consts_code Pair ("(_,/ _)") |
|
2089 |
|
2090 text {* Sometimes, the code associated with a constant or type may |
|
2091 need to refer to auxiliary functions, which have to be emitted when |
|
2092 the constant is used. Code for such auxiliary functions can be |
|
2093 declared using @{keyword "attach"}. For example, the @{const wfrec} |
|
2094 function can be implemented as follows: |
|
2095 *} |
|
2096 |
|
2097 consts_code wfrec ("\<module>wfrec?") (* FIXME !? *) |
|
2098 attach {* fun wfrec f x = f (wfrec f) x *} |
|
2099 |
|
2100 text {* If the code containing a call to @{const wfrec} resides in an |
|
2101 ML structure different from the one containing the function |
|
2102 definition attached to @{const wfrec}, the name of the ML structure |
|
2103 (followed by a ``@{text "."}'') is inserted in place of ``@{text |
|
2104 "\<module>"}'' in the above template. The ``@{text "?"}'' means that |
|
2105 the code generator should ignore the first argument of @{const |
|
2106 wfrec}, i.e.\ the termination relation, which is usually not |
|
2107 executable. |
|
2108 |
|
2109 \medskip Another possibility of configuring the code generator is to |
|
2110 register theorems to be used for code generation. Theorems can be |
|
2111 registered via the @{attribute code} attribute. It takes an optional |
|
2112 name as an argument, which indicates the format of the |
|
2113 theorem. Currently supported formats are equations (this is the |
|
2114 default when no name is specified) and horn clauses (this is |
|
2115 indicated by the name \texttt{ind}). The left-hand sides of |
|
2116 equations may only contain constructors and distinct variables, |
|
2117 whereas horn clauses must have the same format as introduction rules |
|
2118 of inductive definitions. |
|
2119 |
|
2120 The following example specifies three equations from which to |
|
2121 generate code for @{term "op <"} on natural numbers (see also |
|
2122 @{"file" "~~/src/HOL/Nat.thy"}). *} |
|
2123 |
|
2124 lemma [code]: "(Suc m < Suc n) = (m < n)" |
|
2125 and [code]: "((n::nat) < 0) = False" |
|
2126 and [code]: "(0 < Suc n) = True" by simp_all |
|
2127 |
|
2128 |
|
2129 subsubsection {* Specific HOL code generators *} |
|
2130 |
|
2131 text {* The basic code generator framework offered by Isabelle/Pure |
|
2132 has already been extended with additional code generators for |
|
2133 specific HOL constructs. These include datatypes, recursive |
|
2134 functions and inductive relations. The code generator for inductive |
|
2135 relations can handle expressions of the form @{text "(t\<^sub>1, \<dots>, t\<^sub>n) \<in> |
|
2136 r"}, where @{text "r"} is an inductively defined relation. If at |
|
2137 least one of the @{text "t\<^sub>i"} is a dummy pattern ``@{text "_"}'', |
|
2138 the above expression evaluates to a sequence of possible answers. If |
|
2139 all of the @{text "t\<^sub>i"} are proper terms, the expression evaluates |
|
2140 to a boolean value. |
|
2141 |
|
2142 The following example demonstrates this for beta-reduction on lambda |
|
2143 terms (see also @{"file" "~~/src/HOL/Proofs/Lambda/Lambda.thy"}). |
|
2144 *} |
|
2145 |
|
2146 datatype dB = |
|
2147 Var nat |
|
2148 | App dB dB (infixl "\<degree>" 200) |
|
2149 | Abs dB |
|
2150 |
|
2151 primrec lift :: "dB \<Rightarrow> nat \<Rightarrow> dB" |
|
2152 where |
|
2153 "lift (Var i) k = (if i < k then Var i else Var (i + 1))" |
|
2154 | "lift (s \<degree> t) k = lift s k \<degree> lift t k" |
|
2155 | "lift (Abs s) k = Abs (lift s (k + 1))" |
|
2156 |
|
2157 primrec subst :: "dB \<Rightarrow> dB \<Rightarrow> nat \<Rightarrow> dB" ("_[_'/_]" [300, 0, 0] 300) |
|
2158 where |
|
2159 "(Var i)[s/k] = |
|
2160 (if k < i then Var (i - 1) else if i = k then s else Var i)" |
|
2161 | "(t \<degree> u)[s/k] = t[s/k] \<degree> u[s/k]" |
|
2162 | "(Abs t)[s/k] = Abs (t[lift s 0 / k+1])" |
|
2163 |
|
2164 inductive beta :: "dB \<Rightarrow> dB \<Rightarrow> bool" (infixl "\<rightarrow>\<^sub>\<beta>" 50) |
|
2165 where |
|
2166 beta: "Abs s \<degree> t \<rightarrow>\<^sub>\<beta> s[t/0]" |
|
2167 | appL: "s \<rightarrow>\<^sub>\<beta> t \<Longrightarrow> s \<degree> u \<rightarrow>\<^sub>\<beta> t \<degree> u" |
|
2168 | appR: "s \<rightarrow>\<^sub>\<beta> t \<Longrightarrow> u \<degree> s \<rightarrow>\<^sub>\<beta> u \<degree> t" |
|
2169 | abs: "s \<rightarrow>\<^sub>\<beta> t \<Longrightarrow> Abs s \<rightarrow>\<^sub>\<beta> Abs t" |
|
2170 |
|
2171 code_module Test |
|
2172 contains |
|
2173 test1 = "Abs (Var 0) \<degree> Var 0 \<rightarrow>\<^sub>\<beta> Var 0" |
|
2174 test2 = "Abs (Abs (Var 0 \<degree> Var 0) \<degree> (Abs (Var 0) \<degree> Var 0)) \<rightarrow>\<^sub>\<beta> _" |
|
2175 |
|
2176 text {* |
|
2177 In the above example, @{ML Test.test1} evaluates to a boolean, |
|
2178 whereas @{ML Test.test2} is a lazy sequence whose elements can be |
|
2179 inspected separately. |
|
2180 *} |
|
2181 |
|
2182 ML {* @{assert} Test.test1 *} |
|
2183 ML {* val results = DSeq.list_of Test.test2 *} |
|
2184 ML {* @{assert} (length results = 2) *} |
|
2185 |
|
2186 text {* |
|
2187 \medskip The theory underlying the HOL code generator is described |
|
2188 more detailed in \cite{Berghofer-Nipkow:2002}. More examples that |
|
2189 illustrate the usage of the code generator can be found e.g.\ in |
|
2190 @{"file" "~~/src/HOL/MicroJava/J/JListExample.thy"} and @{"file" |
|
2191 "~~/src/HOL/MicroJava/JVM/JVMListExample.thy"}. |
|
2192 *} |
|
2193 |
|
2194 |
|
2195 section {* Definition by specification \label{sec:hol-specification} *} |
1959 section {* Definition by specification \label{sec:hol-specification} *} |
2196 |
1960 |
2197 text {* |
1961 text {* |
2198 \begin{matharray}{rcl} |
1962 \begin{matharray}{rcl} |
2199 @{command_def (HOL) "specification"} & : & @{text "theory \<rightarrow> proof(prove)"} \\ |
1963 @{command_def (HOL) "specification"} & : & @{text "theory \<rightarrow> proof(prove)"} \\ |