changeset 21452 | f825e0b4d566 |
parent 21341 | 3844037a8e2d |
child 21545 | 54cc492d80a9 |
21451:28f1181c1a48 | 21452:f825e0b4d566 |
---|---|
2 (* $Id$ *) |
2 (* $Id$ *) |
3 |
3 |
4 (*<*) |
4 (*<*) |
5 theory Codegen |
5 theory Codegen |
6 imports Main |
6 imports Main |
7 uses "../../../IsarImplementation/Thy/setup.ML" |
7 uses "../../../antiquote_setup.ML" |
8 begin |
8 begin |
9 |
9 |
10 ML {* |
10 ML {* |
11 CodegenSerializer.sml_code_width := 74; |
11 CodegenSerializer.sml_code_width := 74; |
12 *} |
12 *} |
151 |
151 |
152 text {* |
152 text {* |
153 This executable specification is now turned to SML code: |
153 This executable specification is now turned to SML code: |
154 *} |
154 *} |
155 |
155 |
156 code_gen fac (SML "examples/fac.ML") |
156 code_gen fac (*<*)(SML *)(*>*)(SML "examples/fac.ML") |
157 |
157 |
158 text {* |
158 text {* |
159 The @{text "\<CODEGEN>"} command takes a space-separated list of |
159 The @{text "\<CODEGEN>"} command takes a space-separated list of |
160 constants together with \qn{serialization directives} |
160 constants together with \qn{serialization directives} |
161 in parentheses. These start with a \qn{target language} |
161 in parentheses. These start with a \qn{target language} |
267 |
267 |
268 lemma [code func]: |
268 lemma [code func]: |
269 "pick ((k, v)#xs) n = (if n < k then v else pick xs (n - k))" |
269 "pick ((k, v)#xs) n = (if n < k then v else pick xs (n - k))" |
270 by simp |
270 by simp |
271 |
271 |
272 code_gen pick (SML "examples/pick1.ML") |
272 code_gen pick (*<*)(SML *)(*>*)(SML "examples/pick1.ML") |
273 |
273 |
274 text {* |
274 text {* |
275 This theorem is now added to the function equation table: |
275 This theorem is now added to the function equation table: |
276 |
276 |
277 \lstsml{Thy/examples/pick1.ML} |
277 \lstsml{Thy/examples/pick1.ML} |
280 equation, using the \emph{nofunc} attribute: |
280 equation, using the \emph{nofunc} attribute: |
281 *} |
281 *} |
282 |
282 |
283 lemmas [code nofunc] = pick.simps |
283 lemmas [code nofunc] = pick.simps |
284 |
284 |
285 code_gen pick (SML "examples/pick2.ML") |
285 code_gen pick (*<*)(SML *)(*>*)(SML "examples/pick2.ML") |
286 |
286 |
287 text {* |
287 text {* |
288 \lstsml{Thy/examples/pick2.ML} |
288 \lstsml{Thy/examples/pick2.ML} |
289 |
289 |
290 Syntactic redundancies are implicitly dropped. For example, |
290 Syntactic redundancies are implicitly dropped. For example, |
296 |
296 |
297 lemma [code func]: |
297 lemma [code func]: |
298 "fac n = (case n of 0 \<Rightarrow> 1 | Suc m \<Rightarrow> n * fac m)" |
298 "fac n = (case n of 0 \<Rightarrow> 1 | Suc m \<Rightarrow> n * fac m)" |
299 by (cases n) simp_all |
299 by (cases n) simp_all |
300 |
300 |
301 code_gen fac (SML "examples/fac_case.ML") |
301 code_gen fac (*<*)(SML *)(*>*)(SML "examples/fac_case.ML") |
302 |
302 |
303 text {* |
303 text {* |
304 \lstsml{Thy/examples/fac_case.ML} |
304 \lstsml{Thy/examples/fac_case.ML} |
305 |
305 |
306 \begin{warn} |
306 \begin{warn} |
375 (we have left out all other modules). |
375 (we have left out all other modules). |
376 |
376 |
377 The whole code in SML with explicit dictionary passing: |
377 The whole code in SML with explicit dictionary passing: |
378 *} |
378 *} |
379 |
379 |
380 code_gen dummy (SML "examples/class.ML") |
380 code_gen dummy (*<*)(SML *)(*>*)(SML "examples/class.ML") |
381 |
381 |
382 text {* |
382 text {* |
383 \lstsml{Thy/examples/class.ML} |
383 \lstsml{Thy/examples/class.ML} |
384 *} |
384 *} |
385 |
385 |
405 |
405 |
406 print_codethms () |
406 print_codethms () |
407 |
407 |
408 text {* |
408 text {* |
409 \noindent print all cached function equations (i.e.~\emph{after} |
409 \noindent print all cached function equations (i.e.~\emph{after} |
410 any applied transformation. Inside the brackets a |
410 any applied transformation). Inside the brackets a |
411 list of constants may be given; their function |
411 list of constants may be given; their function |
412 equations are added to the cache if not already present. |
412 equations are added to the cache if not already present. |
413 *} |
413 *} |
414 |
414 |
415 |
415 |
441 library; beside being useful in applications, they may serve |
441 library; beside being useful in applications, they may serve |
442 as a tutorial for customizing the code generator setup. |
442 as a tutorial for customizing the code generator setup. |
443 |
443 |
444 \begin{description} |
444 \begin{description} |
445 |
445 |
446 \item[@{theory "ExecutableSet"}] allows to generate code |
446 \item[@{text "ExecutableSet"}] allows to generate code |
447 for finite sets using lists. |
447 for finite sets using lists. |
448 \item[@{theory "ExecutableRat"}] \label{exec_rat} implements rational |
448 \item[@{text "ExecutableRat"}] \label{exec_rat} implements rational |
449 numbers as triples @{text "(sign, enumerator, denominator)"}. |
449 numbers as triples @{text "(sign, enumerator, denominator)"}. |
450 \item[@{theory "EfficientNat"}] \label{eff_nat} implements natural numbers by integers, |
450 \item[@{text "EfficientNat"}] \label{eff_nat} implements natural numbers by integers, |
451 which in general will result in higher efficency; pattern |
451 which in general will result in higher efficency; pattern |
452 matching with @{const "0\<Colon>nat"} / @{const "Suc"} |
452 matching with @{const "0\<Colon>nat"} / @{const "Suc"} |
453 is eliminated. |
453 is eliminated. |
454 \item[@{theory "MLString"}] provides an additional datatype @{text "mlstring"}; |
454 \item[@{text "MLString"}] provides an additional datatype @{text "mlstring"}; |
455 in the HOL default setup, strings in HOL are mapped to list |
455 in the HOL default setup, strings in HOL are mapped to list |
456 of chars in SML; values of type @{text "mlstring"} are |
456 of chars in SML; values of type @{text "mlstring"} are |
457 mapped to strings in SML. |
457 mapped to strings in SML. |
458 |
458 |
459 \end{description} |
459 \end{description} |
519 \emph{Generic preprocessors} provide a most general interface, |
519 \emph{Generic preprocessors} provide a most general interface, |
520 transforming a list of function theorems to another |
520 transforming a list of function theorems to another |
521 list of function theorems, provided that neither the heading |
521 list of function theorems, provided that neither the heading |
522 constant nor its type change. The @{const "0\<Colon>nat"} / @{const Suc} |
522 constant nor its type change. The @{const "0\<Colon>nat"} / @{const Suc} |
523 pattern elimination implemented in |
523 pattern elimination implemented in |
524 theory @{theory "EfficientNat"} (\secref{eff_nat}) uses this |
524 theory @{text "EfficientNat"} (\secref{eff_nat}) uses this |
525 interface. |
525 interface. |
526 |
526 |
527 \begin{warn} |
527 \begin{warn} |
528 The order in which single preprocessing steps are carried |
528 The order in which single preprocessing steps are carried |
529 out currently is not specified; in particular, preprocessing |
529 out currently is not specified; in particular, preprocessing |
555 (SML) |
555 (SML) |
556 code_const %tt True and False and "op \<and>" and Not |
556 code_const %tt True and False and "op \<and>" and Not |
557 (SML and and and) |
557 (SML and and and) |
558 (*>*) |
558 (*>*) |
559 |
559 |
560 code_gen in_interval (SML "examples/bool_literal.ML") |
560 code_gen in_interval (*<*)(SML *)(*>*)(SML "examples/bool_literal.ML") |
561 |
561 |
562 text {* |
562 text {* |
563 \lstsml{Thy/examples/bool_literal.ML} |
563 \lstsml{Thy/examples/bool_literal.ML} |
564 |
564 |
565 Though this is correct code, it is a little bit unsatisfactory: |
565 Though this is correct code, it is a little bit unsatisfactory: |
598 is not used for generated code, we use @{text "\<CODERESERVED>"}. |
598 is not used for generated code, we use @{text "\<CODERESERVED>"}. |
599 |
599 |
600 After this setup, code looks quite more readable: |
600 After this setup, code looks quite more readable: |
601 *} |
601 *} |
602 |
602 |
603 code_gen in_interval (SML "examples/bool_mlbool.ML") |
603 code_gen in_interval (*<*)(SML *)(*>*)(SML "examples/bool_mlbool.ML") |
604 |
604 |
605 text {* |
605 text {* |
606 \lstsml{Thy/examples/bool_mlbool.ML} |
606 \lstsml{Thy/examples/bool_mlbool.ML} |
607 |
607 |
608 This still is not perfect: the parentheses |
608 This still is not perfect: the parentheses |
614 *} |
614 *} |
615 |
615 |
616 code_const %tt "op \<and>" |
616 code_const %tt "op \<and>" |
617 (SML infixl 1 "andalso") |
617 (SML infixl 1 "andalso") |
618 |
618 |
619 code_gen in_interval (SML "examples/bool_infix.ML") |
619 code_gen in_interval (*<*)(SML *)(*>*)(SML "examples/bool_infix.ML") |
620 |
620 |
621 text {* |
621 text {* |
622 \lstsml{Thy/examples/bool_infix.ML} |
622 \lstsml{Thy/examples/bool_infix.ML} |
623 |
623 |
624 Next, we try to map HOL pairs to SML pairs, using the |
624 Next, we try to map HOL pairs to SML pairs, using the |
673 |
673 |
674 code_const %tt "op + \<Colon> int \<Rightarrow> int \<Rightarrow> int" |
674 code_const %tt "op + \<Colon> int \<Rightarrow> int \<Rightarrow> int" |
675 and "op * \<Colon> int \<Rightarrow> int \<Rightarrow> int" |
675 and "op * \<Colon> int \<Rightarrow> int \<Rightarrow> int" |
676 (SML "IntInf.+ (_, _)" and "IntInf.* (_, _)") |
676 (SML "IntInf.+ (_, _)" and "IntInf.* (_, _)") |
677 |
677 |
678 code_gen double_inc (SML "examples/integers.ML") |
678 code_gen double_inc (*<*)(SML *)(*>*)(SML "examples/integers.ML") |
679 |
679 |
680 text {* |
680 text {* |
681 resulting in: |
681 resulting in: |
682 |
682 |
683 \lstsml{Thy/examples/integers.ML} |
683 \lstsml{Thy/examples/integers.ML} |
725 The membership test during preprocessing is rewritten, |
725 The membership test during preprocessing is rewritten, |
726 resulting in @{const List.memberl}, which itself |
726 resulting in @{const List.memberl}, which itself |
727 performs an explicit equality check. |
727 performs an explicit equality check. |
728 *} |
728 *} |
729 |
729 |
730 code_gen collect_duplicates (SML "examples/collect_duplicates.ML") |
730 code_gen collect_duplicates (*<*)(SML *)(*>*)(SML "examples/collect_duplicates.ML") |
731 |
731 |
732 text {* |
732 text {* |
733 \lstsml{Thy/examples/collect_duplicates.ML} |
733 \lstsml{Thy/examples/collect_duplicates.ML} |
734 *} |
734 *} |
735 |
735 |
739 almost trivial definition in the HOL setup: |
739 almost trivial definition in the HOL setup: |
740 *} |
740 *} |
741 |
741 |
742 (*<*) |
742 (*<*) |
743 setup {* Sign.add_path "foo" *} |
743 setup {* Sign.add_path "foo" *} |
744 (*>*) |
744 consts "op =" :: "'a" |
745 |
745 (*>*) |
746 class eq = |
746 |
747 fixes eq :: "'a \<Rightarrow> 'a \<Rightarrow> bool" |
747 axclass eq \<subseteq> type |
748 |
748 attach "op =" |
749 defs |
|
750 eq (*[symmetric, code inline, code func]*): "eq \<equiv> (op =)" |
|
751 |
749 |
752 text {* |
750 text {* |
753 This merely introduces a class @{text eq} with corresponding |
751 This merely introduces a class @{text eq} with corresponding |
754 operation @{const eq}, which by definition is isomorphic |
752 operation @{const "op ="}; |
755 to @{const "op ="}; the preprocessing framework does the rest. |
753 the preprocessing framework does the rest. |
756 *} |
754 *} |
757 |
755 |
758 (*<*) |
756 (*<*) |
759 lemmas [code noinline] = eq |
|
760 |
|
761 hide (open) "class" eq |
757 hide (open) "class" eq |
762 hide (open) const eq |
758 hide (open) const "op =" |
763 |
|
764 lemmas [symmetric, code func] = eq_def |
|
765 |
|
766 setup {* Sign.parent_path *} |
759 setup {* Sign.parent_path *} |
767 (*>*) |
760 (*>*) |
768 |
761 |
769 text {* |
762 text {* |
770 For datatypes, instances of @{text eq} are implicitly derived |
763 For datatypes, instances of @{text eq} are implicitly derived |
771 when possible. |
764 when possible. |
772 |
765 |
773 Though this class is designed to get rarely in the way, there |
766 Though this class is designed to get rarely in the way, there |
774 are some cases when it suddenly comes to surface: |
767 are some cases when it suddenly comes to surface: |
775 *} |
768 *} |
776 |
|
777 subsubsection {* code lemmas and customary serializations for equality *} |
|
778 |
|
779 text {* |
|
780 Examine the following: |
|
781 *} |
|
782 |
|
783 code_const %tt "op = \<Colon> int \<Rightarrow> int \<Rightarrow> bool" |
|
784 (SML "!(_ : IntInf.int = _)") |
|
785 |
|
786 text {* |
|
787 What is wrong here? Since @{const "op ="} is nothing else then |
|
788 a plain constant, this customary serialization will refer |
|
789 to polymorphic equality @{const "op = \<Colon> 'a \<Rightarrow> 'a \<Rightarrow> bool"}. |
|
790 Instead, we want the specific equality on @{typ int}, |
|
791 by using the overloaded constant @{const "Code_Generator.eq"}: |
|
792 *} |
|
793 |
|
794 code_const %tt "Code_Generator.eq \<Colon> int \<Rightarrow> int \<Rightarrow> bool" |
|
795 (SML "!(_ : IntInf.int = _)") |
|
796 |
769 |
797 subsubsection {* typedecls interpreted by customary serializations *} |
770 subsubsection {* typedecls interpreted by customary serializations *} |
798 |
771 |
799 text {* |
772 text {* |
800 A common idiom is to use unspecified types for formalizations |
773 A common idiom is to use unspecified types for formalizations |
816 |
789 |
817 text {* |
790 text {* |
818 This, though, is not sufficient: @{typ key} is no instance |
791 This, though, is not sufficient: @{typ key} is no instance |
819 of @{text eq} since @{typ key} is no datatype; the instance |
792 of @{text eq} since @{typ key} is no datatype; the instance |
820 has to be declared manually, including a serialization |
793 has to be declared manually, including a serialization |
821 for the particular instance of @{const "Code_Generator.eq"}: |
794 for the particular instance of @{const "op ="}: |
822 *} |
795 *} |
823 |
796 |
824 instance key :: eq .. |
797 instance key :: eq .. |
825 |
798 |
826 code_const %tt "Code_Generator.eq \<Colon> key \<Rightarrow> key \<Rightarrow> bool" |
799 code_const %tt "op = \<Colon> key \<Rightarrow> key \<Rightarrow> bool" |
827 (SML "!(_ : string = _)") |
800 (SML "!((_ : string) = _)") |
828 |
801 |
829 text {* |
802 text {* |
830 Then everything goes fine: |
803 Then everything goes fine: |
831 *} |
804 *} |
832 |
805 |
833 code_gen lookup (SML "examples/lookup.ML") |
806 code_gen lookup (*<*)(SML *)(*>*)(SML "examples/lookup.ML") |
834 |
807 |
835 text {* |
808 text {* |
836 \lstsml{Thy/examples/lookup.ML} |
809 \lstsml{Thy/examples/lookup.ML} |
837 *} |
810 *} |
838 |
811 |
845 us define a lexicographic ordering on tuples: |
818 us define a lexicographic ordering on tuples: |
846 *} |
819 *} |
847 |
820 |
848 (*<*) |
821 (*<*) |
849 setup {* Sign.add_path "foobar" *} |
822 setup {* Sign.add_path "foobar" *} |
850 |
|
851 class eq = fixes eq :: "'a \<Rightarrow> 'a \<Rightarrow> bool" |
|
852 class ord = |
823 class ord = |
853 fixes less_eq :: "'a \<Rightarrow> 'a \<Rightarrow> bool" ("(_/ \<^loc>\<le> _)" [50, 51] 50) |
824 fixes less_eq :: "'a \<Rightarrow> 'a \<Rightarrow> bool" ("(_/ \<^loc>\<le> _)" [50, 51] 50) |
854 fixes less :: "'a \<Rightarrow> 'a \<Rightarrow> bool" ("(_/ \<^loc>< _)" [50, 51] 50) |
825 fixes less :: "'a \<Rightarrow> 'a \<Rightarrow> bool" ("(_/ \<^loc>< _)" [50, 51] 50) |
855 (*>*) |
826 (*>*) |
856 |
827 |
858 "p1 < p2 \<equiv> let (x1 \<Colon> 'a\<Colon>ord, y1 \<Colon> 'b\<Colon>ord) = p1; (x2, y2) = p2 in |
829 "p1 < p2 \<equiv> let (x1 \<Colon> 'a\<Colon>ord, y1 \<Colon> 'b\<Colon>ord) = p1; (x2, y2) = p2 in |
859 x1 < x2 \<or> (x1 = x2 \<and> y1 < y2)" |
830 x1 < x2 \<or> (x1 = x2 \<and> y1 < y2)" |
860 "p1 \<le> p2 \<equiv> p1 < p2 \<or> (p1 \<Colon> 'a\<Colon>ord \<times> 'b\<Colon>ord) = p2" .. |
831 "p1 \<le> p2 \<equiv> p1 < p2 \<or> (p1 \<Colon> 'a\<Colon>ord \<times> 'b\<Colon>ord) = p2" .. |
861 |
832 |
862 (*<*) |
833 (*<*) |
863 hide "class" eq ord |
834 hide "class" ord |
864 hide const eq less_eq less |
835 hide const less_eq less |
865 setup {* Sign.parent_path *} |
836 setup {* Sign.parent_path *} |
866 (*>*) |
837 (*>*) |
867 |
838 |
868 text {* |
839 text {* |
869 Then code generation will fail. Why? The definition |
840 Then code generation will fail. Why? The definition |
883 text {* |
854 text {* |
884 Then code generation succeeds: |
855 Then code generation succeeds: |
885 *} |
856 *} |
886 |
857 |
887 code_gen "op \<le> \<Colon> 'a\<Colon>{eq, ord} \<times> 'b\<Colon>{eq, ord} \<Rightarrow> 'a \<times> 'b \<Rightarrow> bool" |
858 code_gen "op \<le> \<Colon> 'a\<Colon>{eq, ord} \<times> 'b\<Colon>{eq, ord} \<Rightarrow> 'a \<times> 'b \<Rightarrow> bool" |
888 (SML "examples/lexicographic.ML") |
859 (*<*)(SML *)(*>*)(SML "examples/lexicographic.ML") |
889 |
860 |
890 text {* |
861 text {* |
891 \lstsml{Thy/examples/lexicographic.ML} |
862 \lstsml{Thy/examples/lexicographic.ML} |
892 *} |
863 *} |
893 |
864 |
987 *} |
958 *} |
988 |
959 |
989 lemma [code func]: |
960 lemma [code func]: |
990 "insert = insert" .. |
961 "insert = insert" .. |
991 |
962 |
992 code_gen dummy_set foobar_set (SML "examples/dirty_set.ML") |
963 code_gen dummy_set foobar_set (*<*)(SML *)(*>*)(SML "examples/dirty_set.ML") |
993 |
964 |
994 text {* |
965 text {* |
995 \lstsml{Thy/examples/dirty_set.ML} |
966 \lstsml{Thy/examples/dirty_set.ML} |
996 |
967 |
997 Reflexive function equations by convention are dropped. |
968 Reflexive function equations by convention are dropped. |
1089 By that, we replace any @{const arbitrary} with option type |
1060 By that, we replace any @{const arbitrary} with option type |
1090 by @{const arbitrary_option} in function equations. |
1061 by @{const arbitrary_option} in function equations. |
1091 |
1062 |
1092 For technical reasons, we further have to provide a |
1063 For technical reasons, we further have to provide a |
1093 synonym for @{const None} which in code generator view |
1064 synonym for @{const None} which in code generator view |
1094 is a function rather than a datatype constructor |
1065 is a function rather than a datatype constructor: |
1095 *} |
1066 *} |
1096 |
1067 |
1097 definition |
1068 definition |
1098 "None' = None" |
1069 "None' = None" |
1099 |
1070 |
1114 "dummy_option [] = arbitrary" |
1085 "dummy_option [] = arbitrary" |
1115 (*<*) |
1086 (*<*) |
1116 declare dummy_option.simps [code func] |
1087 declare dummy_option.simps [code func] |
1117 (*>*) |
1088 (*>*) |
1118 |
1089 |
1119 code_gen dummy_option (SML "examples/arbitrary.ML") |
1090 code_gen dummy_option (*<*)(SML *)(*>*)(SML "examples/arbitrary.ML") |
1120 |
1091 |
1121 text {* |
1092 text {* |
1122 \lstsml{Thy/examples/arbitrary.ML} |
1093 \lstsml{Thy/examples/arbitrary.ML} |
1123 |
1094 |
1124 Another axiomatic extension is code generation |
1095 Another axiomatic extension is code generation |
1125 for abstracted types. For this, the |
1096 for abstracted types. For this, the |
1126 @{theory "ExecutableRat"} (see \secref{exec_rat}) |
1097 @{text "ExecutableRat"} (see \secref{exec_rat}) |
1127 forms a good example. |
1098 forms a good example. |
1128 *} |
1099 *} |
1129 |
1100 |
1130 |
1101 |
1131 section {* ML interfaces \label{sec:ml} *} |
1102 section {* ML interfaces \label{sec:ml} *} |
1364 \begin{warn} |
1335 \begin{warn} |
1365 Some interfaces discussed here have not reached |
1336 Some interfaces discussed here have not reached |
1366 a final state yet. |
1337 a final state yet. |
1367 Changes likely to occur in future. |
1338 Changes likely to occur in future. |
1368 \end{warn} |
1339 \end{warn} |
1369 |
|
1370 \fixme |
|
1371 *} |
1340 *} |
1372 |
1341 |
1373 subsubsection {* Data depending on the theory's executable content *} |
1342 subsubsection {* Data depending on the theory's executable content *} |
1374 |
1343 |
1375 text {* |
1344 text {* |
1345 Due to incrementality of code generation, changes in the |
|
1346 theory's executable content have to be propagated in a |
|
1347 certain fashion. Additionally, such changes may occur |
|
1348 not only during theory extension but also during theory |
|
1349 merge, which is a little bit nasty from an implementation |
|
1350 point of view. The framework provides a solution |
|
1351 to this technical challenge by providing a functorial |
|
1352 data slot @{ML_functor CodeDataFun}; on instantiation |
|
1353 of this functor, the following types and operations |
|
1354 are required: |
|
1355 |
|
1376 \medskip |
1356 \medskip |
1377 \begin{tabular}{l} |
1357 \begin{tabular}{l} |
1378 @{text "val name: string"} \\ |
1358 @{text "val name: string"} \\ |
1379 @{text "type T"} \\ |
1359 @{text "type T"} \\ |
1380 @{text "val empty: T"} \\ |
1360 @{text "val empty: T"} \\ |
1381 @{text "val merge: Pretty.pp \<rightarrow> T * T \<rightarrow> T"} \\ |
1361 @{text "val merge: Pretty.pp \<rightarrow> T * T \<rightarrow> T"} \\ |
1382 @{text "val purge: theory option \<rightarrow> CodegenConsts.const list option \<rightarrow> T \<rightarrow> T"} |
1362 @{text "val purge: theory option \<rightarrow> CodegenConsts.const list option \<rightarrow> T \<rightarrow> T"} |
1383 \end{tabular} |
1363 \end{tabular} |
1384 |
1364 |
1365 \begin{description} |
|
1366 |
|
1367 \item @{text name} is a system-wide unique name identifying the data. |
|
1368 |
|
1369 \item @{text T} the type of data to store. |
|
1370 |
|
1371 \item @{text empty} initial (empty) data. |
|
1372 |
|
1373 \item @{text merge} merging two data slots. |
|
1374 |
|
1375 \item @{text purge}~@{text thy}~@{text cs} propagates changes in executable content; |
|
1376 if possible, the current theory context is handed over |
|
1377 as argument @{text thy} (if there is no current theory context (e.g.~during |
|
1378 theory merge, @{ML NONE}); @{text cs} indicates the kind |
|
1379 of change: @{ML NONE} stands for a fundamental change |
|
1380 which invalidates any existing code, @{text "SOME cs"} |
|
1381 hints that executable content for constants @{text cs} |
|
1382 has changed. |
|
1383 |
|
1384 \end{description} |
|
1385 |
|
1386 An instance of @{ML_functor CodeDataFun} provides the following |
|
1387 interface: |
|
1388 |
|
1385 \medskip |
1389 \medskip |
1386 |
|
1387 \begin{tabular}{l} |
1390 \begin{tabular}{l} |
1388 @{text "init: theory \<rightarrow> theory"} \\ |
1391 @{text "init: theory \<rightarrow> theory"} \\ |
1389 @{text "get: theory \<rightarrow> T"} \\ |
1392 @{text "get: theory \<rightarrow> T"} \\ |
1390 @{text "change: theory \<rightarrow> (T \<rightarrow> T) \<rightarrow> T"} \\ |
1393 @{text "change: theory \<rightarrow> (T \<rightarrow> T) \<rightarrow> T"} \\ |
1391 @{text "change_yield: theory \<rightarrow> (T \<rightarrow> 'a * T) \<rightarrow> 'a * T"} |
1394 @{text "change_yield: theory \<rightarrow> (T \<rightarrow> 'a * T) \<rightarrow> 'a * T"} |
1392 \end{tabular} |
1395 \end{tabular} |
1393 *} |
|
1394 |
|
1395 text %mlref {* |
|
1396 \begin{mldecls} |
|
1397 @{index_ML_functor CodeDataFun} |
|
1398 \end{mldecls} |
|
1399 |
1396 |
1400 \begin{description} |
1397 \begin{description} |
1401 |
1398 |
1402 \item @{ML_functor CodeDataFun}@{text "(spec)"} declares code |
1399 \item @{text init} initialization during theory setup. |
1403 dependent data according to the specification provided as |
1400 |
1404 argument structure. The resulting structure provides data init and |
1401 \item @{text get} retrieval of the current data. |
1405 access operations as described above. |
1402 |
1403 \item @{text change} update of current data (cached!) |
|
1404 by giving a continuation. |
|
1405 |
|
1406 \item @{text change_yield} update with side result. |
|
1406 |
1407 |
1407 \end{description} |
1408 \end{description} |
1408 *} |
1409 *} |
1409 |
1410 |
1410 subsubsection {* Datatype hooks *} |
1411 subsubsection {* Datatype hooks *} |
1412 |
|
1413 text {* |
|
1414 Isabelle/HOL's datatype package provides a mechanism to |
|
1415 extend theories depending on datatype declarations: |
|
1416 \emph{datatype hooks}. For example, when declaring a new |
|
1417 datatype, a hook proves function equations for equality on |
|
1418 that datatype (if possible). |
|
1419 *} |
|
1411 |
1420 |
1412 text %mlref {* |
1421 text %mlref {* |
1413 \begin{mldecls} |
1422 \begin{mldecls} |
1414 @{index_ML_type DatatypeHooks.hook: "string list -> theory -> theory"} \\ |
1423 @{index_ML_type DatatypeHooks.hook: "string list -> theory -> theory"} \\ |
1415 @{index_ML DatatypeHooks.add: "DatatypeHooks.hook -> theory -> theory"} |
1424 @{index_ML DatatypeHooks.add: "DatatypeHooks.hook -> theory -> theory"} |
1416 \end{mldecls} |
1425 \end{mldecls} |
1426 |
|
1427 \begin{description} |
|
1428 |
|
1429 \item @{ML_type DatatypeHooks.hook} specifies the interface |
|
1430 of \emph{datatype hooks}: a theory update |
|
1431 depending on the list of newly introduced |
|
1432 datatype names. |
|
1433 |
|
1434 \item @{ML DatatypeHooks.add} adds a hook to the |
|
1435 chain of all hooks. |
|
1436 |
|
1437 \end{description} |
|
1438 *} |
|
1439 |
|
1440 subsubsection {* Trivial typedefs -- type copies *} |
|
1441 |
|
1442 text {* |
|
1443 Sometimes packages will introduce new types |
|
1444 as \emph{marked type copies} similar to Haskell's |
|
1445 @{text newtype} declaration (e.g. the HOL record package) |
|
1446 \emph{without} tinkering with the overhead of datatypes. |
|
1447 Technically, these type copies are trivial forms of typedefs. |
|
1448 Since these type copies in code generation view are nothing |
|
1449 else than datatypes, they have been given a own package |
|
1450 in order to faciliate code generation: |
|
1417 *} |
1451 *} |
1418 |
1452 |
1419 text %mlref {* |
1453 text %mlref {* |
1420 \begin{mldecls} |
1454 \begin{mldecls} |
1421 @{index_ML_type TypecopyPackage.info: "{ |
1455 @{index_ML_type TypecopyPackage.info} \\ |
1422 vs: (string * sort) list, |
|
1423 constr: string, |
|
1424 typ: typ, |
|
1425 inject: thm, |
|
1426 proj: string * typ, |
|
1427 proj_def: thm |
|
1428 }"} \\ |
|
1429 @{index_ML TypecopyPackage.add_typecopy: " |
1456 @{index_ML TypecopyPackage.add_typecopy: " |
1430 bstring * string list -> typ -> (bstring * bstring) option |
1457 bstring * string list -> typ -> (bstring * bstring) option |
1431 -> theory -> (string * TypecopyPackage.info) * theory"} \\ |
1458 -> theory -> (string * TypecopyPackage.info) * theory"} \\ |
1432 @{index_ML TypecopyPackage.get_typecopies: "theory -> string list"} \\ |
|
1433 @{index_ML TypecopyPackage.get_typecopy_info: "theory |
1459 @{index_ML TypecopyPackage.get_typecopy_info: "theory |
1434 -> string -> TypecopyPackage.info option"} \\ |
1460 -> string -> TypecopyPackage.info option"} \\ |
1435 @{index_ML_type TypecopyPackage.hook} \\ |
|
1436 @{index_ML TypecopyPackage.add_hook: "TypecopyPackage.hook -> theory -> theory"} \\ |
|
1437 @{index_ML TypecopyPackage.get_spec: "theory -> string |
1461 @{index_ML TypecopyPackage.get_spec: "theory -> string |
1438 -> (string * sort) list * (string * typ list) list"} |
1462 -> (string * sort) list * (string * typ list) list"} \\ |
1463 @{index_ML_type TypecopyPackage.hook: "string * TypecopyPackage.info -> theory -> theory"} \\ |
|
1464 @{index_ML TypecopyPackage.add_hook: |
|
1465 "TypecopyPackage.hook -> theory -> theory"} \\ |
|
1439 \end{mldecls} |
1466 \end{mldecls} |
1467 |
|
1468 \begin{description} |
|
1469 |
|
1470 \item @{ML_type TypecopyPackage.info} a record containing |
|
1471 the specification and further data of a type copy. |
|
1472 |
|
1473 \item @{ML TypecopyPackage.add_typecopy} defines a new |
|
1474 type copy. |
|
1475 |
|
1476 \item @{ML TypecopyPackage.get_typecopy_info} retrieves |
|
1477 data of an existing type copy. |
|
1478 |
|
1479 \item @{ML TypecopyPackage.get_spec} retrieves datatype-like |
|
1480 specification of a type copy. |
|
1481 |
|
1482 \item @{ML_type TypecopyPackage.hook},~@{ML TypecopyPackage.add_hook} |
|
1483 provide a hook mechanism corresponding to the hook mechanism |
|
1484 on datatypes. |
|
1485 |
|
1486 \end{description} |
|
1487 *} |
|
1488 |
|
1489 subsubsection {* Unifying type copies and datatypes *} |
|
1490 |
|
1491 text {* |
|
1492 Since datatypes and type copies are mapped to the same concept (datatypes) |
|
1493 by code generation, the view on both is unified \qt{code types}: |
|
1440 *} |
1494 *} |
1441 |
1495 |
1442 text %mlref {* |
1496 text %mlref {* |
1443 \begin{mldecls} |
1497 \begin{mldecls} |
1444 @{index_ML_type DatatypeCodegen.hook: "(string * (bool * ((string * sort) list * (string * typ list) list))) list |
1498 @{index_ML_type DatatypeCodegen.hook: "(string * (bool * ((string * sort) list |
1499 * (string * typ list) list))) list |
|
1445 -> theory -> theory"} \\ |
1500 -> theory -> theory"} \\ |
1446 @{index_ML DatatypeCodegen.add_codetypes_hook_bootstrap: " |
1501 @{index_ML DatatypeCodegen.add_codetypes_hook_bootstrap: " |
1447 DatatypeCodegen.hook -> theory -> theory"} |
1502 DatatypeCodegen.hook -> theory -> theory"} |
1448 \end{mldecls} |
1503 \end{mldecls} |
1449 *} |
1504 *} |
1450 |
1505 |
1451 text {* |
1506 text {* |
1452 \fixme |
1507 \begin{description} |
1453 % \emph{Happy proving, happy hacking!} |
1508 |
1509 \item @{ML_type DatatypeCodegen.hook} specifies the code type hook |
|
1510 interface: a theory transformation depending on a list of |
|
1511 mutual recursive code types; each entry in the list |
|
1512 has the structure @{text "(name, (is_data, (vars, cons)))"} |
|
1513 where @{text name} is the name of the code type, @{text is_data} |
|
1514 is true iff @{text name} is a datatype rather then a type copy, |
|
1515 and @{text "(vars, cons)"} is the specification of the code type. |
|
1516 |
|
1517 \item @{ML DatatypeCodegen.add_codetypes_hook_bootstrap} adds a code |
|
1518 type hook; the hook is immediately processed for all already |
|
1519 existing datatypes, in blocks of mutual recursive datatypes, |
|
1520 where all datatypes a block depends on are processed before |
|
1521 the block. |
|
1522 |
|
1523 \end{description} |
|
1524 |
|
1525 \emph{Happy proving, happy hacking!} |
|
1454 *} |
1526 *} |
1455 |
1527 |
1456 end |
1528 end |