67 |
67 |
68 Let us work a simple example, the definition of a three-element type. |
68 Let us work a simple example, the definition of a three-element type. |
69 It is easily represented by the first three natural numbers: |
69 It is easily represented by the first three natural numbers: |
70 *} |
70 *} |
71 |
71 |
72 typedef three = "{n::nat. n \<le> 2}" |
72 typedef three = "{0::nat, 1, 2}" |
73 |
73 |
74 txt{*\noindent |
74 txt{*\noindent |
75 In order to enforce that the representing set on the right-hand side is |
75 In order to enforce that the representing set on the right-hand side is |
76 non-empty, this definition actually starts a proof to that effect: |
76 non-empty, this definition actually starts a proof to that effect: |
77 @{subgoals[display,indent=0]} |
77 @{subgoals[display,indent=0]} |
78 Fortunately, this is easy enough to show: take 0 as a witness. |
78 Fortunately, this is easy enough to show, even \isa{auto} could do it. |
|
79 In general, one has to provide a witness, in our case 0: |
79 *} |
80 *} |
80 |
81 |
81 apply(rule_tac x = 0 in exI) |
82 apply(rule_tac x = 0 in exI) |
82 by simp |
83 by simp |
83 |
84 |
159 Abs_three} and @{term Rep_three}. Because of the simplicity of the example, |
160 Abs_three} and @{term Rep_three}. Because of the simplicity of the example, |
160 we merely need to prove that @{term A}, @{term B} and @{term C} are distinct |
161 we merely need to prove that @{term A}, @{term B} and @{term C} are distinct |
161 and that they exhaust the type. |
162 and that they exhaust the type. |
162 |
163 |
163 In processing our \isacommand{typedef} declaration, |
164 In processing our \isacommand{typedef} declaration, |
164 Isabelle helpfully proves several lemmas. |
165 Isabelle proves several helpful lemmas. The first two |
165 One, @{thm[source]Abs_three_inject}, |
166 express injectivity of @{term Rep_three} and @{term Abs_three}: |
166 expresses that @{term Abs_three} is injective on the representing subset: |
167 \begin{center} |
167 \begin{center} |
168 \begin{tabular}{@ {}r@ {\qquad}l@ {}} |
168 @{thm Abs_three_inject[no_vars]} |
169 @{thm Rep_three_inject[no_vars]} & (@{thm[source]Rep_three_inject}) \\ |
169 \end{center} |
170 \begin{tabular}{@ {}l@ {}} |
170 Another, @{thm[source]Rep_three_inject}, expresses that the representation |
171 @{text"\<lbrakk>x \<in> three; y \<in> three \<rbrakk>"} \\ |
171 function is also injective: |
172 @{text"\<Longrightarrow> (Abs_three x = Abs_three y) = (x = y)"} |
172 \begin{center} |
173 \end{tabular} & (@{thm[source]Abs_three_inject}) \\ |
173 @{thm Rep_three_inject[no_vars]} |
174 \end{tabular} |
174 \end{center} |
175 \end{center} |
|
176 The following ones allow to replace some @{text"x::three"} by |
|
177 @{text"Abs_three(y::nat)"}, and conversely @{term y} by @{term"Rep_three x"}: |
|
178 \begin{center} |
|
179 \begin{tabular}{@ {}r@ {\qquad}l@ {}} |
|
180 @{thm Rep_three_cases[no_vars]} & (@{thm[source]Rep_three_cases}) \\ |
|
181 @{thm Abs_three_cases[no_vars]} & (@{thm[source]Abs_three_cases}) \\ |
|
182 @{thm Rep_three_induct[no_vars]} & (@{thm[source]Rep_three_induct}) \\ |
|
183 @{thm Abs_three_induct[no_vars]} & (@{thm[source]Abs_three_induct}) \\ |
|
184 \end{tabular} |
|
185 \end{center} |
|
186 These theorems are proved for any type definition, with @{term three} |
|
187 replaced by the name of the type in question. |
|
188 |
175 Distinctness of @{term A}, @{term B} and @{term C} follows immediately |
189 Distinctness of @{term A}, @{term B} and @{term C} follows immediately |
176 if we expand their definitions and rewrite with the injectivity |
190 if we expand their definitions and rewrite with the injectivity |
177 of @{term Abs_three}: |
191 of @{term Abs_three}: |
178 *} |
192 *} |
179 |
193 |
180 lemma "A \<noteq> B \<and> B \<noteq> A \<and> A \<noteq> C \<and> C \<noteq> A \<and> B \<noteq> C \<and> C \<noteq> B" |
194 lemma "A \<noteq> B \<and> B \<noteq> A \<and> A \<noteq> C \<and> C \<noteq> A \<and> B \<noteq> C \<and> C \<noteq> B" |
181 by(simp add: Abs_three_inject A_def B_def C_def three_def) |
195 by(simp add: Abs_three_inject A_def B_def C_def three_def) |
182 |
196 |
183 text{*\noindent |
197 text{*\noindent |
184 Of course we rely on the simplifier to solve goals like @{prop"0 \<noteq> 1"}. |
198 Of course we rely on the simplifier to solve goals like @{prop"(0::nat) \<noteq> 1"}. |
185 |
199 |
186 The fact that @{term A}, @{term B} and @{term C} exhaust type @{typ three} is |
200 The fact that @{term A}, @{term B} and @{term C} exhaust type @{typ three} is |
187 best phrased as a case distinction theorem: if you want to prove @{prop"P x"} |
201 best phrased as a case distinction theorem: if you want to prove @{prop"P x"} |
188 (where @{term x} is of type @{typ three}) it suffices to prove @{prop"P A"}, |
202 (where @{term x} is of type @{typ three}) it suffices to prove @{prop"P A"}, |
189 @{prop"P B"} and @{prop"P C"}. First we prove the analogous proposition for the |
203 @{prop"P B"} and @{prop"P C"}: *} |
190 representation: *} |
|
191 |
|
192 lemma cases_lemma: "\<lbrakk> Q 0; Q 1; Q 2; n \<in> three \<rbrakk> \<Longrightarrow> Q n" |
|
193 |
|
194 txt{*\noindent |
|
195 Expanding @{thm[source]three_def} yields the premise @{prop"n\<le>2"}. Repeated |
|
196 elimination with @{thm[source]le_SucE} |
|
197 @{thm[display]le_SucE} |
|
198 reduces @{prop"n\<le>2"} to the three cases @{prop"n\<le>0"}, @{prop"n=1"} and |
|
199 @{prop"n=2"} which are trivial for simplification: |
|
200 *} |
|
201 |
|
202 apply(simp add: three_def numerals) (* FIXME !? *) |
|
203 apply((erule le_SucE)+) |
|
204 apply simp_all |
|
205 done |
|
206 |
|
207 text{* |
|
208 Now the case distinction lemma on type @{typ three} is easy to derive if you |
|
209 know how: |
|
210 *} |
|
211 |
204 |
212 lemma three_cases: "\<lbrakk> P A; P B; P C \<rbrakk> \<Longrightarrow> P x" |
205 lemma three_cases: "\<lbrakk> P A; P B; P C \<rbrakk> \<Longrightarrow> P x" |
213 |
206 |
214 txt{*\noindent |
207 txt{*\noindent Again this follows easily from a pre-proved general theorem:*} |
215 We start by replacing the @{term x} by @{term"Abs_three(Rep_three x)"}: |
208 |
216 *} |
209 apply(rule_tac x = x in Abs_three_induct) |
217 |
|
218 apply(rule subst[OF Rep_three_inverse]) |
|
219 |
|
220 txt{*\noindent |
|
221 This substitution step worked nicely because there was just a single |
|
222 occurrence of a term of type @{typ three}, namely @{term x}. |
|
223 When we now apply @{thm[source]cases_lemma}, @{term Q} becomes @{term"\<lambda>n. P(Abs_three |
|
224 n)"} because @{term"Rep_three x"} is the only term of type @{typ nat}: |
|
225 *} |
|
226 |
|
227 apply(rule cases_lemma) |
|
228 |
210 |
229 txt{* |
211 txt{* |
230 @{subgoals[display,indent=0]} |
212 @{subgoals[display,indent=0]} |
231 The resulting subgoals are easily solved by simplification: |
213 Simplification with @{thm[source]three_def} leads to the disjunction @{prop"y |
232 *} |
214 = 0 \<or> y = 1 \<or> y = (2::nat)"} which \isa{auto} separates into three |
233 |
215 subgoals, each of which is easily solved by simplification: *} |
234 apply(simp_all add:A_def B_def C_def Rep_three) |
216 |
|
217 apply(auto simp add: three_def A_def B_def C_def) |
235 done |
218 done |
236 |
219 |
237 text{*\noindent |
220 text{*\noindent |
238 This concludes the derivation of the characteristic theorems for |
221 This concludes the derivation of the characteristic theorems for |
239 type @{typ three}. |
222 type @{typ three}. |
251 |
234 |
252 Although @{typ three} could be defined in one line, we have chosen this |
235 Although @{typ three} could be defined in one line, we have chosen this |
253 example to demonstrate \isacommand{typedef} because its simplicity makes the |
236 example to demonstrate \isacommand{typedef} because its simplicity makes the |
254 key concepts particularly easy to grasp. If you would like to see a |
237 key concepts particularly easy to grasp. If you would like to see a |
255 non-trivial example that cannot be defined more directly, we recommend the |
238 non-trivial example that cannot be defined more directly, we recommend the |
256 definition of \emph{finite multisets} in the Library~\cite{isabelle-HOL-lib}. |
239 definition of \emph{finite multisets} in the Library~\cite{HOL-Library}. |
257 |
240 |
258 Let us conclude by summarizing the above procedure for defining a new type. |
241 Let us conclude by summarizing the above procedure for defining a new type. |
259 Given some abstract axiomatic description $P$ of a type $ty$ in terms of a |
242 Given some abstract axiomatic description $P$ of a type $ty$ in terms of a |
260 set of functions $F$, this involves three steps: |
243 set of functions $F$, this involves three steps: |
261 \begin{enumerate} |
244 \begin{enumerate} |