4 |
4 |
5 section {* Turning Theories into Programs \label{sec:program} *} |
5 section {* Turning Theories into Programs \label{sec:program} *} |
6 |
6 |
7 subsection {* The @{text "Isabelle/HOL"} default setup *} |
7 subsection {* The @{text "Isabelle/HOL"} default setup *} |
8 |
8 |
9 subsection {* Selecting code equations *} |
|
10 |
|
11 text {* |
9 text {* |
12 We have already seen how by default equations stemming from |
10 We have already seen how by default equations stemming from |
13 @{command definition}/@{command primrec}/@{command fun} |
11 @{command definition}/@{command primrec}/@{command fun} |
14 statements are used for code generation. Deviating from this |
12 statements are used for code generation. This default behaviour |
15 \emph{default} behaviour is always possible -- e.g.~we |
13 can be changed, e.g. by providing different defining equations. |
16 could provide an alternative @{text fun} for @{const dequeue} proving |
14 All kinds of customization shown in this section is \emph{safe} |
17 the following equations explicitly: |
15 in the sense that the user does not have to worry about |
|
16 correctness -- all programs generatable that way are partially |
|
17 correct. |
|
18 *} |
|
19 |
|
20 subsection {* Selecting code equations *} |
|
21 |
|
22 text {* |
|
23 Coming back to our introductory example, we |
|
24 could provide an alternative defining equations for @{const dequeue} |
|
25 explicitly: |
18 *} |
26 *} |
19 |
27 |
20 lemma %quoteme [code func]: |
28 lemma %quoteme [code func]: |
21 "dequeue (Queue xs []) = (if xs = [] then (None, Queue [] []) else dequeue (Queue [] (rev xs)))" |
29 "dequeue (Queue xs []) = |
22 "dequeue (Queue xs (y # ys)) = (Some y, Queue xs ys)" |
30 (if xs = [] then (None, Queue [] []) else dequeue (Queue [] (rev xs)))" |
|
31 "dequeue (Queue xs (y # ys)) = |
|
32 (Some y, Queue xs ys)" |
23 by (cases xs, simp_all) (cases "rev xs", simp_all) |
33 by (cases xs, simp_all) (cases "rev xs", simp_all) |
24 |
34 |
25 text {* |
35 text {* |
26 \noindent The annotation @{text "[code func]"} is an @{text Isar} |
36 \noindent The annotation @{text "[code func]"} is an @{text Isar} |
27 @{text attribute} which states that the given theorems should be |
37 @{text attribute} which states that the given theorems should be |
121 *} |
131 *} |
122 |
132 |
123 text %quoteme {*@{code_stmts bexp (Haskell)}*} |
133 text %quoteme {*@{code_stmts bexp (Haskell)}*} |
124 |
134 |
125 text {* |
135 text {* |
126 \noindent An inspection reveals that the equations stemming from the |
136 \noindent This is a convenient place to show how explicit dictionary construction |
127 @{command primrec} statement within instantiation of class |
|
128 @{class semigroup} with type @{typ nat} are mapped to a separate |
|
129 function declaration @{verbatim mult_nat} which in turn is used |
|
130 to provide the right hand side for the @{verbatim "instance Semigroup Nat"}. |
|
131 This perfectly |
|
132 agrees with the restriction that @{text inst} statements may |
|
133 only contain one single equation for each class class parameter |
|
134 The @{command instantiation} mechanism manages that for each |
|
135 overloaded constant @{text "f [\<kappa> \<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>]"} |
|
136 a \emph{shadow constant} @{text "f\<^isub>\<kappa> [\<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>]"} is |
|
137 declared satisfying @{text "f [\<kappa> \<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>] \<equiv> f\<^isub>\<kappa> [\<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>]"}. |
|
138 this equation is indeed the one used for the statement; |
|
139 using it as a rewrite rule, defining equations for |
|
140 @{text "f [\<kappa> \<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>]"} can be turned into |
|
141 defining equations for @{text "f\<^isub>\<kappa> [\<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>]"}. This |
|
142 happens transparently, providing the illusion that class parameters |
|
143 can be instantiated with more than one equation. |
|
144 |
|
145 This is a convenient place to show how explicit dictionary construction |
|
146 manifests in generated code (here, the same example in @{text SML}): |
137 manifests in generated code (here, the same example in @{text SML}): |
147 *} |
138 *} |
148 |
139 |
149 text %quoteme {*@{code_stmts bexp (SML)}*} |
140 text %quoteme {*@{code_stmts bexp (SML)}*} |
150 |
141 |
|
142 text {* |
|
143 \noindent Note the parameters with trailing underscore (@{verbatim "A_"}) |
|
144 which are the dictionary parameters. |
|
145 *} |
151 |
146 |
152 subsection {* The preprocessor \label{sec:preproc} *} |
147 subsection {* The preprocessor \label{sec:preproc} *} |
153 |
148 |
154 text {* |
149 text {* |
155 Before selected function theorems are turned into abstract |
150 Before selected function theorems are turned into abstract |
354 text {* |
347 text {* |
355 \noindent Obviously, polymorphic equality is implemented the Haskell |
348 \noindent Obviously, polymorphic equality is implemented the Haskell |
356 way using a type class. How is this achieved? HOL introduces |
349 way using a type class. How is this achieved? HOL introduces |
357 an explicit class @{class eq} with a corresponding operation |
350 an explicit class @{class eq} with a corresponding operation |
358 @{const eq_class.eq} such that @{thm eq [no_vars]}. |
351 @{const eq_class.eq} such that @{thm eq [no_vars]}. |
359 The preprocessing framework does the rest. |
352 The preprocessing framework does the rest by propagating the |
|
353 @{class eq} constraints through all dependent defining equations. |
360 For datatypes, instances of @{class eq} are implicitly derived |
354 For datatypes, instances of @{class eq} are implicitly derived |
361 when possible. For other types, you may instantiate @{text eq} |
355 when possible. For other types, you may instantiate @{text eq} |
362 manually like any other type class. |
356 manually like any other type class. |
363 |
357 |
364 Though this @{text eq} class is designed to get rarely in |
358 Though this @{text eq} class is designed to get rarely in |
365 the way, a subtlety |
359 the way, a subtlety |
366 enters the stage when definitions of overloaded constants |
360 enters the stage when definitions of overloaded constants |
367 are dependent on operational equality. For example, let |
361 are dependent on operational equality. For example, let |
368 us define a lexicographic ordering on tuples: |
362 us define a lexicographic ordering on tuples |
369 *} |
363 (also see theory @{theory Product_ord}): |
370 |
364 *} |
371 instantiation %quoteme * :: (ord, ord) ord |
365 |
|
366 instantiation %quoteme "*" :: (order, order) order |
372 begin |
367 begin |
373 |
368 |
374 definition %quoteme [code func del]: |
369 definition %quoteme [code func del]: |
375 "p1 < p2 \<longleftrightarrow> (let (x1, y1) = p1; (x2, y2) = p2 in x1 < x2 \<or> (x1 = x2 \<and> y1 < y2))" |
370 "x \<le> y \<longleftrightarrow> fst x < fst y \<or> fst x = fst y \<and> snd x \<le> snd y" |
376 |
371 |
377 definition %quoteme [code func del]: |
372 definition %quoteme [code func del]: |
378 "p1 \<le> p2 \<longleftrightarrow> (let (x1, y1) = p1; (x2, y2) = p2 in x1 < x2 \<or> (x1 = x2 \<and> y1 \<le> y2))" |
373 "x < y \<longleftrightarrow> fst x < fst y \<or> fst x = fst y \<and> snd x < snd y" |
379 |
374 |
380 instance %quoteme .. |
375 instance %quoteme proof |
|
376 qed (auto simp: less_eq_prod_def less_prod_def intro: order_less_trans) |
381 |
377 |
382 end %quoteme |
378 end %quoteme |
383 |
379 |
384 lemma %quoteme ord_prod [code func]: |
380 lemma %quoteme order_prod [code func]: |
385 "(x1 \<Colon> 'a\<Colon>ord, y1 \<Colon> 'b\<Colon>ord) < (x2, y2) \<longleftrightarrow> x1 < x2 \<or> (x1 = x2 \<and> y1 < y2)" |
381 "(x1 \<Colon> 'a\<Colon>order, y1 \<Colon> 'b\<Colon>order) < (x2, y2) \<longleftrightarrow> |
386 "(x1 \<Colon> 'a\<Colon>ord, y1 \<Colon> 'b\<Colon>ord) \<le> (x2, y2) \<longleftrightarrow> x1 < x2 \<or> (x1 = x2 \<and> y1 \<le> y2)" |
382 x1 < x2 \<or> x1 = x2 \<and> y1 < y2" |
387 unfolding less_prod_def less_eq_prod_def by simp_all |
383 "(x1 \<Colon> 'a\<Colon>order, y1 \<Colon> 'b\<Colon>order) \<le> (x2, y2) \<longleftrightarrow> |
|
384 x1 < x2 \<or> x1 = x2 \<and> y1 \<le> y2" |
|
385 by (simp_all add: less_prod_def less_eq_prod_def) |
388 |
386 |
389 text {* |
387 text {* |
390 \noindent Then code generation will fail. Why? The definition |
388 \noindent Then code generation will fail. Why? The definition |
391 of @{term "op \<le>"} depends on equality on both arguments, |
389 of @{term "op \<le>"} depends on equality on both arguments, |
392 which are polymorphic and impose an additional @{class eq} |
390 which are polymorphic and impose an additional @{class eq} |
393 class constraint, which the preprocessort does not propagate for technical |
391 class constraint, which the preprocessor does not propagate |
394 reasons. |
392 (for technical reasons). |
395 |
393 |
396 The solution is to add @{class eq} explicitly to the first sort arguments in the |
394 The solution is to add @{class eq} explicitly to the first sort arguments in the |
397 code theorems: |
395 code theorems: |
398 *} |
396 *} |
399 |
397 |
400 lemma ord_prod_code [code func]: |
398 lemma %quoteme order_prod_code [code func]: |
401 "(x1 \<Colon> 'a\<Colon>{ord, eq}, y1 \<Colon> 'b\<Colon>ord) < (x2, y2) \<longleftrightarrow> |
399 "(x1 \<Colon> 'a\<Colon>{order, eq}, y1 \<Colon> 'b\<Colon>order) < (x2, y2) \<longleftrightarrow> |
402 x1 < x2 \<or> (x1 = x2 \<and> y1 < y2)" |
400 x1 < x2 \<or> x1 = x2 \<and> y1 < y2" |
403 "(x1 \<Colon> 'a\<Colon>{ord, eq}, y1 \<Colon> 'b\<Colon>ord) \<le> (x2, y2) \<longleftrightarrow> |
401 "(x1 \<Colon> 'a\<Colon>{order, eq}, y1 \<Colon> 'b\<Colon>order) \<le> (x2, y2) \<longleftrightarrow> |
404 x1 < x2 \<or> (x1 = x2 \<and> y1 \<le> y2)" |
402 x1 < x2 \<or> x1 = x2 \<and> y1 \<le> y2" |
405 unfolding ord_prod by rule+ |
403 by (simp_all add: less_prod_def less_eq_prod_def) |
406 |
404 |
407 text {* |
405 text {* |
408 \noindent Then code generation succeeds: |
406 \noindent Then code generation succeeds: |
409 *} |
407 *} |
410 |
408 |
411 text %quoteme {*@{code_stmts "op \<le> \<Colon> 'a\<Colon>{eq, ord} \<times> 'b\<Colon>ord \<Rightarrow> 'a \<times> 'b \<Rightarrow> bool" (SML)}*} |
409 text %quoteme {*@{code_stmts "op \<le> \<Colon> _ \<times> _ \<Rightarrow> _ \<times> _ \<Rightarrow> bool" (SML)}*} |
412 |
410 |
413 text {* |
411 text {* |
414 In some cases, the automatically derived defining equations |
412 In some cases, the automatically derived defining equations |
415 for equality on a particular type may not be appropriate. |
413 for equality on a particular type may not be appropriate. |
416 As example, watch the following datatype representing |
414 As example, watch the following datatype representing |