2 imports Base |
2 imports Base |
3 begin |
3 begin |
4 |
4 |
5 chapter {* First Steps\label{chp:firststeps} *} |
5 chapter {* First Steps\label{chp:firststeps} *} |
6 |
6 |
|
7 |
|
8 |
7 text {* |
9 text {* |
8 \begin{flushright} |
10 \begin{flushright} |
9 {\em ``The most effective debugging tool is still careful thought,\\ |
11 {\em ``The most effective debugging tool is still careful thought,\\ |
10 coupled with judiciously placed print statements.''} \\[1ex] |
12 coupled with judiciously placed print statements.''} \\[1ex] |
11 Brian Kernighan, in {\em Unix for Beginners}, 1979 |
13 Brian Kernighan, in {\em Unix for Beginners}, 1979 |
12 \end{flushright} |
14 \end{flushright} |
13 |
15 |
14 \medskip |
16 \medskip |
15 Isabelle programming is done in ML. Just like lemmas and proofs, ML-code for |
17 Isabelle programming is done in ML @{cite "isa-imp"}. Just like lemmas and proofs, ML-code for |
16 Isabelle must be part of a theory. If you want to follow the code given in |
18 Isabelle must be part of a theory. If you want to follow the code given in |
17 this chapter, we assume you are working inside the theory starting with |
19 this chapter, we assume you are working inside the theory starting with |
18 |
20 |
19 \begin{quote} |
21 \begin{quote} |
20 \begin{tabular}{@ {}l} |
22 \begin{tabular}{@ {}l} |
177 |
179 |
178 A @{ML_type cterm} can be printed with the following function. |
180 A @{ML_type cterm} can be printed with the following function. |
179 *} |
181 *} |
180 |
182 |
181 ML %grayML %grayML{*fun pretty_cterm ctxt ctrm = |
183 ML %grayML %grayML{*fun pretty_cterm ctxt ctrm = |
182 pretty_term ctxt (term_of ctrm)*} |
184 pretty_term ctxt (Thm.term_of ctrm)*} |
183 |
185 |
184 text {* |
186 text {* |
185 Here the function @{ML_ind term_of in Thm} extracts the @{ML_type |
187 Here the function @{ML_ind term_of in Thm} extracts the @{ML_type |
186 term} from a @{ML_type cterm}. More than one @{ML_type cterm}s can be |
188 term} from a @{ML_type cterm}. More than one @{ML_type cterm}s can be |
187 printed again with @{ML commas in Pretty}. |
189 printed again with @{ML commas in Pretty}. |
194 The easiest way to get the string of a theorem is to transform it |
196 The easiest way to get the string of a theorem is to transform it |
195 into a @{ML_type term} using the function @{ML_ind prop_of in Thm}. |
197 into a @{ML_type term} using the function @{ML_ind prop_of in Thm}. |
196 *} |
198 *} |
197 |
199 |
198 ML %grayML{*fun pretty_thm ctxt thm = |
200 ML %grayML{*fun pretty_thm ctxt thm = |
199 pretty_term ctxt (prop_of thm)*} |
201 pretty_term ctxt (Thm.prop_of thm)*} |
200 |
202 |
201 text {* |
203 text {* |
202 Theorems include schematic variables, such as @{text "?P"}, |
204 Theorems include schematic variables, such as @{text "?P"}, |
203 @{text "?Q"} and so on. They are instantiated by Isabelle when a theorem is applied. |
205 @{text "?Q"} and so on. They are instantiated by Isabelle when a theorem is applied. |
204 For example, the theorem |
206 For example, the theorem |
624 obtained by previous calls. |
626 obtained by previous calls. |
625 |
627 |
626 A more realistic example for this combinator is the following code |
628 A more realistic example for this combinator is the following code |
627 *} |
629 *} |
628 |
630 |
629 ML %grayML{*val (((one_def, two_def), three_def), ctxt') = |
631 ML %grayML{*val ((([one_def], [two_def]), [three_def]), ctxt') = |
630 @{context} |
632 @{context} |
631 |> Local_Defs.add_def ((@{binding "One"}, NoSyn), @{term "1::nat"}) |
633 |> Local_Defs.define [((@{binding "One"}, NoSyn), (Binding.empty_atts, @{term "1::nat"}))] |
632 ||>> Local_Defs.add_def ((@{binding "Two"}, NoSyn), @{term "2::nat"}) |
634 ||>> Local_Defs.define [((@{binding "Two"}, NoSyn), (Binding.empty_atts,@{term "2::nat"}))] |
633 ||>> Local_Defs.add_def ((@{binding "Three"}, NoSyn), @{term "3::nat"})*} |
635 ||>> Local_Defs.define [((@{binding "Three"}, NoSyn), (Binding.empty_atts,@{term "3::nat"}))]*} |
634 |
636 |
635 text {* |
637 text {* |
636 where we make three definitions, namely @{term "One \<equiv> 1::nat"}, @{term "Two \<equiv> 2::nat"} |
638 where we make three definitions, namely @{term "One \<equiv> 1::nat"}, @{term "Two \<equiv> 2::nat"} |
637 and @{term "Three \<equiv> 3::nat"}. The point of this code is that we augment the initial |
639 and @{term "Three \<equiv> 3::nat"}. The point of this code is that we augment the initial |
638 context with the definitions. The result we are interested in is the |
640 context with the definitions. The result we are interested in is the |
639 augmented context, that is @{ML_text "ctxt'"}, but also the side-results containing |
641 augmented context, that is @{ML_text "ctxt'"}, but also the side-results containing |
640 information about the definitions---the function @{ML_ind add_def in Local_Defs} returns |
642 information about the definitions---the function @{ML_ind define in Local_Defs} returns |
641 both as pairs. We can use this information for example to print out the definiens and |
643 both as pairs. We can use this information for example to print out the definiens and |
642 the theorem corresponding to the definitions. For example for the first definition: |
644 the theorem corresponding to the definitions. For example for the first definition: |
643 |
645 |
644 @{ML_response_fake [display, gray] |
646 @{ML_response_fake [display, gray] |
645 "let |
647 "let |
646 val (one_trm, one_thm) = one_def |
648 val (one_trm, (_, one_thm)) = one_def |
647 in |
649 in |
648 pwriteln (pretty_term ctxt' one_trm); |
650 pwriteln (pretty_term ctxt' one_trm); |
649 pwriteln (pretty_thm ctxt' one_thm) |
651 pwriteln (pretty_thm ctxt' one_thm) |
650 end" |
652 end" |
651 "One |
653 "One |
773 \ref{chp:advanced}.) A context is for example needed to use the |
775 \ref{chp:advanced}.) A context is for example needed to use the |
774 function @{ML print_abbrevs in Proof_Context} that list of all currently |
776 function @{ML print_abbrevs in Proof_Context} that list of all currently |
775 defined abbreviations. For example |
777 defined abbreviations. For example |
776 |
778 |
777 @{ML_response_fake [display, gray] |
779 @{ML_response_fake [display, gray] |
778 "Proof_Context.print_abbrevs @{context}" |
780 "Proof_Context.print_abbrevs false @{context}" |
779 "\<dots> |
781 "\<dots> |
780 INTER \<equiv> INFI |
782 INTER \<equiv> INFI |
781 Inter \<equiv> Inf |
783 Inter \<equiv> Inf |
782 \<dots>"} |
784 \<dots>"} |
783 |
785 |
862 for the antiquotation @{text "term_pat"} is as follows. |
864 for the antiquotation @{text "term_pat"} is as follows. |
863 *} |
865 *} |
864 |
866 |
865 ML %linenosgray{*val term_pat_setup = |
867 ML %linenosgray{*val term_pat_setup = |
866 let |
868 let |
867 val parser = Args.context -- Scan.lift Args.name_inner_syntax |
869 val parser = Args.context -- Scan.lift Args.embedded_inner_syntax |
868 |
870 |
869 fun term_pat (ctxt, str) = |
871 fun term_pat (ctxt, str) = |
870 str |> Proof_Context.read_term_pattern ctxt |
872 str |> Proof_Context.read_term_pattern ctxt |
871 |> ML_Syntax.print_term |
873 |> ML_Syntax.print_term |
872 |> ML_Syntax.atomic |
874 |> ML_Syntax.atomic |
895 we can write an antiquotation for type patterns. Its code is |
897 we can write an antiquotation for type patterns. Its code is |
896 *} |
898 *} |
897 |
899 |
898 ML %grayML{*val type_pat_setup = |
900 ML %grayML{*val type_pat_setup = |
899 let |
901 let |
900 val parser = Args.context -- Scan.lift Args.name_inner_syntax |
902 val parser = Args.context -- Scan.lift Args.embedded_inner_syntax |
901 |
903 |
902 fun typ_pat (ctxt, str) = |
904 fun typ_pat (ctxt, str) = |
903 let |
905 let |
904 val ctxt' = Proof_Context.set_mode Proof_Context.mode_schematic ctxt |
906 val ctxt' = Proof_Context.set_mode Proof_Context.mode_schematic ctxt |
905 in |
907 in |
919 |
921 |
920 text {* |
922 text {* |
921 However, a word of warning is in order: new antiquotations should be introduced only after |
923 However, a word of warning is in order: new antiquotations should be introduced only after |
922 careful deliberations. They can potentially make your code harder, rather than easier, to read. |
924 careful deliberations. They can potentially make your code harder, rather than easier, to read. |
923 |
925 |
924 \begin{readmore} |
926 \begin{readmore} @{url "Norbert/ML/ml_antiquotation.ML"} |
925 The files @{ML_file "Pure/ML/ml_antiquotation.ML"} and @{ML_file "Pure/ML/ml_antiquotations.ML"} |
927 The files @{ML_file "Pure/ML/ml_antiquotation.ML"} and @{ML_file "Pure/ML/ml_antiquotations.ML"} |
926 contain the infrastructure and definitions for most antiquotations. Most of the basic operations |
928 contain the infrastructure and definitions for most antiquotations. Most of the basic operations |
927 on ML-syntax are implemented in @{ML_file "Pure/ML/ml_syntax.ML"}. |
929 on ML-syntax are implemented in @{ML_file "Pure/ML/ml_syntax.ML"}. |
928 \end{readmore} |
930 \end{readmore} |
929 *} |
931 *} |
945 above it is important to keep in mind that the universal type does not |
947 above it is important to keep in mind that the universal type does not |
946 destroy type-safety of ML: storing and accessing the data can only be done |
948 destroy type-safety of ML: storing and accessing the data can only be done |
947 in a type-safe manner...though run-time checks are needed for that. |
949 in a type-safe manner...though run-time checks are needed for that. |
948 |
950 |
949 \begin{readmore} |
951 \begin{readmore} |
950 In Isabelle the universal type is implemented as the type @{ML_type |
952 In ML the universal type is implemented as the type @{ML_type |
951 Universal.universal} in the file |
953 Universal.universal}. |
952 @{ML_file "Pure/ML-Systems/universal.ML"}. |
|
953 \end{readmore} |
954 \end{readmore} |
954 |
955 |
955 We will show the usage of the universal type by storing an integer and |
956 We will show the usage of the universal type by storing an integer and |
956 a boolean into a single list. Let us first define injection and projection |
957 a boolean into a single list. Let us first define injection and projection |
957 functions for booleans and integers into and from the type @{ML_type Universal.universal}. |
958 functions for booleans and integers into and from the type @{ML_type Universal.universal}. |
1342 A concrete example for a configuration value is |
1343 A concrete example for a configuration value is |
1343 @{ML_ind simp_trace in Raw_Simplifier}, which switches on trace information |
1344 @{ML_ind simp_trace in Raw_Simplifier}, which switches on trace information |
1344 in the simplifier. This can be used for example in the following proof |
1345 in the simplifier. This can be used for example in the following proof |
1345 *} |
1346 *} |
1346 |
1347 |
|
1348 |
1347 lemma |
1349 lemma |
1348 shows "(False \<or> True) \<and> True" |
1350 shows "(False \<or> True) \<and> True" |
1349 proof (rule conjI) |
1351 proof (rule conjI) |
1350 show "False \<or> True" using [[simp_trace = true]] by simp |
1352 show "False \<or> True" using [[simp_trace = true]] by simp |
1351 next |
1353 next |