107 is converted is monomorphic and not a function. |
106 is converted is monomorphic and not a function. |
108 |
107 |
109 You can print out error messages with the function @{ML_ind error in Library}; |
108 You can print out error messages with the function @{ML_ind error in Library}; |
110 for example: |
109 for example: |
111 |
110 |
112 @{ML_matchresult_fake [display,gray] |
111 @{ML_response [display,gray] |
113 \<open>if 0 = 1 then true else (error "foo")\<close> |
112 \<open>if 0 = 1 then true else (error "foo")\<close> |
114 \<open>*** foo |
113 \<open>foo\<close>} |
115 ***\<close>} |
|
116 |
114 |
117 This function raises the exception \<open>ERROR\<close>, which will then |
115 This function raises the exception \<open>ERROR\<close>, which will then |
118 be displayed by the infrastructure indicating that it is an error by |
116 be displayed by the infrastructure indicating that it is an error by |
119 painting the output red. Note that this exception is meant |
117 painting the output red. Note that this exception is meant |
120 for ``user-level'' error messages seen by the ``end-user''. |
118 for ``user-level'' error messages seen by the ``end-user''. |
130 @{ML_structure Syntax}. For more convenience, we bind them to the toplevel. |
128 @{ML_structure Syntax}. For more convenience, we bind them to the toplevel. |
131 \<close> |
129 \<close> |
132 |
130 |
133 ML %grayML\<open>val pretty_term = Syntax.pretty_term |
131 ML %grayML\<open>val pretty_term = Syntax.pretty_term |
134 val pwriteln = Pretty.writeln\<close> |
132 val pwriteln = Pretty.writeln\<close> |
135 |
133 (* We redfine pwriteln to return a value not just a side effect on the output in order to |
|
134 use some checking of output with ML_response antiquotation. *) |
|
135 ML %invisible\<open>val pretty_term = Syntax.pretty_term |
|
136 val pwriteln = YXML.content_of o Pretty.string_of\<close> |
136 text \<open> |
137 text \<open> |
137 They can be used as follows |
138 They can be used as follows |
138 |
139 |
139 @{ML_matchresult_fake [display,gray] |
140 @{ML_response [display,gray] |
140 \<open>pwriteln (pretty_term @{context} @{term "1::nat"})\<close> |
141 \<open>pwriteln (pretty_term @{context} @{term "1::nat"})\<close> |
141 \<open>"1"\<close>} |
142 \<open>"1"\<close>} |
142 |
143 |
143 If there is more than one term to be printed, you can use the |
144 If there is more than one term to be printed, you can use the |
144 function @{ML_ind commas in Pretty} and @{ML_ind block in Pretty} |
145 function @{ML_ind commas in Pretty} and @{ML_ind block in Pretty} |
157 ML %grayML\<open>val show_types_ctxt = Config.put show_types true @{context}\<close> |
158 ML %grayML\<open>val show_types_ctxt = Config.put show_types true @{context}\<close> |
158 |
159 |
159 text \<open> |
160 text \<open> |
160 Now by using this context @{ML pretty_term} prints out |
161 Now by using this context @{ML pretty_term} prints out |
161 |
162 |
162 @{ML_matchresult_fake [display, gray] |
163 @{ML_response [display, gray] |
163 \<open>pwriteln (pretty_term show_types_ctxt @{term "(1::nat, x)"})\<close> |
164 \<open>pwriteln (pretty_term show_types_ctxt @{term "(1::nat, x)"})\<close> |
164 \<open>(1::nat, x::'a)\<close>} |
165 \<open>(1::nat, x::'a)\<close>} |
165 |
166 |
166 where \<open>1\<close> and \<open>x\<close> are displayed with their inferred types. |
167 where \<open>1\<close> and \<open>x\<close> are displayed with their inferred types. |
167 Other configuration values that influence |
168 Other configuration values that influence |
201 \<open>?Q\<close> and so on. They are instantiated by Isabelle when a theorem is applied. |
202 \<open>?Q\<close> and so on. They are instantiated by Isabelle when a theorem is applied. |
202 For example, the theorem |
203 For example, the theorem |
203 @{thm [source] conjI} shown below can be used for any (typable) |
204 @{thm [source] conjI} shown below can be used for any (typable) |
204 instantiation of \<open>?P\<close> and \<open>?Q\<close>. |
205 instantiation of \<open>?P\<close> and \<open>?Q\<close>. |
205 |
206 |
206 @{ML_matchresult_fake [display, gray] |
207 @{ML_response [display, gray] |
207 \<open>pwriteln (pretty_thm @{context} @{thm conjI})\<close> |
208 \<open>pwriteln (pretty_thm @{context} @{thm conjI})\<close> |
208 \<open>\<lbrakk>?P; ?Q\<rbrakk> \<Longrightarrow> ?P \<and> ?Q\<close>} |
209 \<open>\<lbrakk>?P; ?Q\<rbrakk> \<Longrightarrow> ?P \<and> ?Q\<close>} |
209 |
210 |
210 However, to improve the readability when printing theorems, we |
211 However, to improve the readability when printing theorems, we |
211 can switch off the question marks as follows: |
212 can switch off the question marks as follows: |
219 end\<close> |
220 end\<close> |
220 |
221 |
221 text \<open> |
222 text \<open> |
222 With this function, theorem @{thm [source] conjI} is now printed as follows: |
223 With this function, theorem @{thm [source] conjI} is now printed as follows: |
223 |
224 |
224 @{ML_matchresult_fake [display, gray] |
225 @{ML_response [display, gray] |
225 \<open>pwriteln (pretty_thm_no_vars @{context} @{thm conjI})\<close> |
226 \<open>pwriteln (pretty_thm_no_vars @{context} @{thm conjI})\<close> |
226 \<open>\<lbrakk>P; Q\<rbrakk> \<Longrightarrow> P \<and> Q\<close>} |
227 \<open>\<lbrakk>P; Q\<rbrakk> \<Longrightarrow> P \<and> Q\<close>} |
227 |
228 |
228 Again the functions @{ML commas} and @{ML block in Pretty} help |
229 Again the functions @{ML commas} and @{ML block in Pretty} help |
229 with printing more than one theorem. |
230 with printing more than one theorem. |
265 \emph{not} print out information as |
266 \emph{not} print out information as |
266 |
267 |
267 @{ML_matchresult_fake [display,gray] |
268 @{ML_matchresult_fake [display,gray] |
268 \<open>pwriteln (Pretty.str "First half,"); |
269 \<open>pwriteln (Pretty.str "First half,"); |
269 pwriteln (Pretty.str "and second half.")\<close> |
270 pwriteln (Pretty.str "and second half.")\<close> |
270 \<open>First half, |
271 \<open>"First half, |
271 and second half.\<close>} |
272 and second half."\<close>} |
272 |
273 |
273 but as a single string with appropriate formatting. For example |
274 but as a single string with appropriate formatting. For example |
274 |
275 |
275 @{ML_matchresult_fake [display,gray] |
276 @{ML_response [display,gray] |
276 \<open>pwriteln (Pretty.str ("First half," ^ "\\n" ^ "and second half."))\<close> |
277 \<open>pwriteln (Pretty.str ("First half," ^ "\\n" ^ "and second half."))\<close> |
277 \<open>First half, |
278 \<open>First half, |
278 and second half.\<close>} |
279 and second half.\<close>} |
279 |
280 |
280 To ease this kind of string manipulations, there are a number |
281 To ease this kind of string manipulations, there are a number |
281 of library functions in Isabelle. For example, the function |
282 of library functions in Isabelle. For example, the function |
282 @{ML_ind cat_lines in Library} concatenates a list of strings |
283 @{ML_ind cat_lines in Library} concatenates a list of strings |
283 and inserts newlines in between each element. |
284 and inserts newlines in between each element. |
284 |
285 |
285 @{ML_matchresult_fake [display, gray] |
286 @{ML_response [display, gray] |
286 \<open>pwriteln (Pretty.str (cat_lines ["foo", "bar"]))\<close> |
287 \<open>pwriteln (Pretty.str (cat_lines ["foo", "bar"]))\<close> |
287 \<open>foo |
288 \<open>foo |
288 bar\<close>} |
289 bar\<close>} |
289 |
290 |
290 Section \ref{sec:pretty} will explain the infrastructure that Isabelle |
291 Section \ref{sec:pretty} will explain the infrastructure that Isabelle |
385 This function takes a term and a context as arguments. If the term is of function |
386 This function takes a term and a context as arguments. If the term is of function |
386 type, then @{ML \<open>apply_fresh_args\<close>} returns the term with distinct variables |
387 type, then @{ML \<open>apply_fresh_args\<close>} returns the term with distinct variables |
387 applied to it. For example, below three variables are applied to the term |
388 applied to it. For example, below three variables are applied to the term |
388 @{term [show_types] "P::nat \<Rightarrow> int \<Rightarrow> unit \<Rightarrow> bool"}: |
389 @{term [show_types] "P::nat \<Rightarrow> int \<Rightarrow> unit \<Rightarrow> bool"}: |
389 |
390 |
390 @{ML_matchresult_fake [display,gray] |
391 @{ML_response [display,gray] |
391 \<open>let |
392 \<open>let |
392 val trm = @{term "P::nat \<Rightarrow> int \<Rightarrow> unit \<Rightarrow> bool"} |
393 val trm = @{term "P::nat \<Rightarrow> int \<Rightarrow> unit \<Rightarrow> bool"} |
393 val ctxt = @{context} |
394 val ctxt = @{context} |
394 in |
395 in |
395 apply_fresh_args trm ctxt |
396 apply_fresh_args trm ctxt |
412 |
413 |
413 Functions like @{ML apply_fresh_args} are often needed when constructing |
414 Functions like @{ML apply_fresh_args} are often needed when constructing |
414 terms involving fresh variables. For this the infrastructure helps |
415 terms involving fresh variables. For this the infrastructure helps |
415 tremendously to avoid any name clashes. Consider for example: |
416 tremendously to avoid any name clashes. Consider for example: |
416 |
417 |
417 @{ML_matchresult_fake [display,gray] |
418 @{ML_response [display,gray] |
418 \<open>let |
419 \<open>let |
419 val trm = @{term "za::'a \<Rightarrow> 'b \<Rightarrow> 'c"} |
420 val trm = @{term "za::'a \<Rightarrow> 'b \<Rightarrow> 'c"} |
420 val ctxt = @{context} |
421 val ctxt = @{context} |
421 in |
422 in |
422 apply_fresh_args trm ctxt |
423 apply_fresh_args trm ctxt |
597 \<open>acc_incs 1 ||>> (fn x => (x, x + 2))\<close> |
598 \<open>acc_incs 1 ||>> (fn x => (x, x + 2))\<close> |
598 \<open>((((("", 1), 2), 3), 4), 6)\<close>} |
599 \<open>((((("", 1), 2), 3), 4), 6)\<close>} |
599 |
600 |
600 An example where this combinator is useful is as follows |
601 An example where this combinator is useful is as follows |
601 |
602 |
602 @{ML_matchresult_fake [display, gray] |
603 @{ML_matchresult [display, gray] |
603 \<open>let |
604 \<open>let |
604 val ((names1, names2), _) = |
605 val ((names1, names2), _) = |
605 @{context} |
606 @{context} |
606 |> Variable.variant_fixes (replicate 4 "x") |
607 |> Variable.variant_fixes (replicate 4 "x") |
607 ||>> Variable.variant_fixes (replicate 5 "x") |
608 ||>> Variable.variant_fixes (replicate 5 "x") |
637 augmented context, that is @{ML_text "ctxt'"}, but also the side-results containing |
638 augmented context, that is @{ML_text "ctxt'"}, but also the side-results containing |
638 information about the definitions---the function @{ML_ind define in Local_Defs} returns |
639 information about the definitions---the function @{ML_ind define in Local_Defs} returns |
639 both as pairs. We can use this information for example to print out the definiens and |
640 both as pairs. We can use this information for example to print out the definiens and |
640 the theorem corresponding to the definitions. For example for the first definition: |
641 the theorem corresponding to the definitions. For example for the first definition: |
641 |
642 |
642 @{ML_matchresult_fake [display, gray] |
643 @{ML_response [display, gray] |
643 \<open>let |
644 \<open>let |
644 val (one_trm, (_, one_thm)) = one_def |
645 val (one_trm, (_, one_thm)) = one_def |
645 in |
646 in |
646 pwriteln (pretty_term ctxt' one_trm); |
647 (pwriteln (pretty_term ctxt' one_trm), |
647 pwriteln (pretty_thm ctxt' one_thm) |
648 pwriteln (pretty_thm ctxt' one_thm)) |
648 end\<close> |
649 end\<close> |
649 \<open>One |
650 \<open>One |
650 One \<equiv> 1\<close>} |
651 One \<equiv> 1\<close>} |
651 Recall that @{ML \<open>|>\<close>} is the reverse function application. Recall also that |
652 Recall that @{ML \<open>|>\<close>} is the reverse function application. Recall also that |
652 the related reverse function composition is @{ML \<open>#>\<close>}. In fact all the |
653 the related reverse function composition is @{ML \<open>#>\<close>}. In fact all the |
671 plumbing is also needed in situations where a function operates over lists, |
672 plumbing is also needed in situations where a function operates over lists, |
672 but one calculates only with a single element. An example is the function |
673 but one calculates only with a single element. An example is the function |
673 @{ML_ind check_terms in Syntax}, whose purpose is to simultaneously type-check |
674 @{ML_ind check_terms in Syntax}, whose purpose is to simultaneously type-check |
674 a list of terms. Consider the code: |
675 a list of terms. Consider the code: |
675 |
676 |
676 @{ML_matchresult_fake [display, gray] |
677 @{ML_response [display, gray] |
677 \<open>let |
678 \<open>let |
678 val ctxt = @{context} |
679 val ctxt = @{context} |
679 in |
680 in |
680 map (Syntax.parse_term ctxt) ["m + n", "m * n", "m - (n::nat)"] |
681 map (Syntax.parse_term ctxt) ["m + n", "m * n", "m - (n::nat)"] |
681 |> Syntax.check_terms ctxt |
682 |> Syntax.check_terms ctxt |
692 check_terms in Syntax} needs plumbing. This can be done with the function |
693 check_terms in Syntax} needs plumbing. This can be done with the function |
693 @{ML_ind singleton in Library}.\footnote{There is already a function @{ML check_term in |
694 @{ML_ind singleton in Library}.\footnote{There is already a function @{ML check_term in |
694 Syntax} in the file @{ML_file "Pure/Syntax/syntax.ML"} that is implemented |
695 Syntax} in the file @{ML_file "Pure/Syntax/syntax.ML"} that is implemented |
695 in terms of @{ML singleton} and @{ML check_terms in Syntax}.} For example |
696 in terms of @{ML singleton} and @{ML check_terms in Syntax}.} For example |
696 |
697 |
697 @{ML_matchresult_fake [display, gray, linenos] |
698 @{ML_response [display, gray, linenos] |
698 \<open>let |
699 \<open>let |
699 val ctxt = @{context} |
700 val ctxt = @{context} |
700 in |
701 in |
701 Syntax.parse_term ctxt "m - (n::nat)" |
702 Syntax.parse_term ctxt "m - (n::nat)" |
702 |> singleton (Syntax.check_terms ctxt) |
703 |> singleton (Syntax.check_terms ctxt) |
772 defined abbreviations. For example |
773 defined abbreviations. For example |
773 |
774 |
774 @{ML_matchresult_fake [display, gray] |
775 @{ML_matchresult_fake [display, gray] |
775 \<open>Proof_Context.print_abbrevs false @{context}\<close> |
776 \<open>Proof_Context.print_abbrevs false @{context}\<close> |
776 \<open>\<dots> |
777 \<open>\<dots> |
777 INTER \<equiv> INFI |
778 INTER \<equiv> INFIMUM |
778 Inter \<equiv> Inf |
779 Inter \<equiv> Inf |
779 \<dots>\<close>} |
780 \<dots>\<close>} |
780 |
781 |
781 The precise output of course depends on the abbreviations that are |
782 The precise output of course depends on the abbreviations that are |
782 currently defined; this can change over time. |
783 currently defined; this can change over time. |
783 You can also use antiquotations to refer to proved theorems: |
784 You can also use antiquotations to refer to proved theorems: |
784 \<open>@{thm \<dots>}\<close> for a single theorem |
785 \<open>@{thm \<dots>}\<close> for a single theorem |
785 |
786 |
786 @{ML_matchresult_fake [display,gray] \<open>@{thm allI}\<close> \<open>(\<And>x. ?P x) \<Longrightarrow> \<forall>x. ?P x\<close>} |
787 @{ML_response [display,gray] \<open>@{thm allI}\<close> \<open>(\<And>x. ?P x) \<Longrightarrow> \<forall>x. ?P x\<close>} |
787 |
788 |
788 and \<open>@{thms \<dots>}\<close> for more than one |
789 and \<open>@{thms \<dots>}\<close> for more than one |
789 |
790 |
790 @{ML_matchresult_fake [display,gray] |
791 |
|
792 @{ML_response [display,gray] |
791 \<open>@{thms conj_ac}\<close> |
793 \<open>@{thms conj_ac}\<close> |
792 \<open>(?P \<and> ?Q) = (?Q \<and> ?P) |
794 \<open>["(?P \<and> ?Q) = (?Q \<and> ?P)", |
793 (?P \<and> ?Q \<and> ?R) = (?Q \<and> ?P \<and> ?R) |
795 "(?P \<and> ?Q \<and> ?R) = (?Q \<and> ?P \<and> ?R)", |
794 ((?P \<and> ?Q) \<and> ?R) = (?P \<and> ?Q \<and> ?R)\<close>} |
796 "((?P \<and> ?Q) \<and> ?R) = (?P \<and> ?Q \<and> ?R)"]\<close>} |
795 |
797 |
796 The thm-antiquotations can also be used for manipulating theorems. For |
798 The thm-antiquotations can also be used for manipulating theorems. For |
797 example, if you need the version of the theorem @{thm [source] refl} that |
799 example, if you need the version of the theorem @{thm [source] refl} that |
798 has a meta-equality instead of an equality, you can write |
800 has a meta-equality instead of an equality, you can write |
799 |
801 |
800 @{ML_matchresult_fake [display,gray] |
802 @{ML_response [display,gray] |
801 \<open>@{thm refl[THEN eq_reflection]}\<close> |
803 \<open>@{thm refl[THEN eq_reflection]}\<close> |
802 \<open>?x \<equiv> ?x\<close>} |
804 \<open>?x \<equiv> ?x\<close>} |
803 |
805 |
804 The point of these antiquotations is that referring to theorems in this way |
806 The point of these antiquotations is that referring to theorems in this way |
805 makes your code independent from what theorems the user might have stored |
807 makes your code independent from what theorems the user might have stored |
814 ML %grayML\<open>val foo_thms = @{lemma "True" and "False \<Longrightarrow> P" by simp_all}\<close> |
816 ML %grayML\<open>val foo_thms = @{lemma "True" and "False \<Longrightarrow> P" by simp_all}\<close> |
815 |
817 |
816 text \<open> |
818 text \<open> |
817 The result can be printed out as follows. |
819 The result can be printed out as follows. |
818 |
820 |
819 @{ML_matchresult_fake [gray,display] |
821 @{ML_response [gray,display] |
820 \<open>foo_thms |> pretty_thms_no_vars @{context} |
822 \<open>foo_thms |> pretty_thms_no_vars @{context} |
821 |> pwriteln\<close> |
823 |> pwriteln\<close> |
822 \<open>True, False \<Longrightarrow> P\<close>} |
824 \<open>True, False \<Longrightarrow> P\<close>} |
823 |
825 |
824 You can also refer to the current simpset via an antiquotation. To illustrate |
826 You can also refer to the current simpset via an antiquotation. To illustrate |
838 The function @{ML_ind dest_ss in Raw_Simplifier} returns a record containing all |
840 The function @{ML_ind dest_ss in Raw_Simplifier} returns a record containing all |
839 information stored in the simpset, but here we are only interested in the names of the |
841 information stored in the simpset, but here we are only interested in the names of the |
840 simp-rules. Now you can feed in the current simpset into this function. |
842 simp-rules. Now you can feed in the current simpset into this function. |
841 The current simpset can be referred to using @{ML_ind simpset_of in Raw_Simplifier}. |
843 The current simpset can be referred to using @{ML_ind simpset_of in Raw_Simplifier}. |
842 |
844 |
843 @{ML_matchresult_fake [display,gray] |
845 @{ML_response [display,gray] |
844 \<open>get_thm_names_from_ss @{context}\<close> |
846 \<open>get_thm_names_from_ss @{context}\<close> |
845 \<open>["Nat.of_nat_eq_id", "Int.of_int_eq_id", "Nat.One_nat_def", \<dots>]\<close>} |
847 \<open>["Euclidean_Division.euclidean_size_int_def",\<dots>\<close>} |
846 |
848 |
847 Again, this way of referencing simpsets makes you independent from additions |
849 Again, this way of referencing simpsets makes you independent from additions |
848 of lemmas to the simpset by the user, which can potentially cause loops in your |
850 of lemmas to the simpset by the user, which can potentially cause loops in your |
849 code. |
851 code. |
850 |
852 |
882 transformed into a term using the function @{ML_ind read_term_pattern in |
884 transformed into a term using the function @{ML_ind read_term_pattern in |
883 Proof_Context} (Line 5); the next two lines transform the term into a string |
885 Proof_Context} (Line 5); the next two lines transform the term into a string |
884 so that the ML-system can understand it. (All these functions will be explained |
886 so that the ML-system can understand it. (All these functions will be explained |
885 in more detail in later sections.) An example for this antiquotation is: |
887 in more detail in later sections.) An example for this antiquotation is: |
886 |
888 |
887 @{ML_matchresult_fake [display,gray] |
889 @{ML_matchresult [display,gray] |
888 \<open>@{term_pat "Suc (?x::nat)"}\<close> |
890 \<open>@{term_pat "Suc (?x::nat)"}\<close> |
889 \<open>Const ("Suc", "nat \<Rightarrow> nat") $ Var (("x", 0), "nat")\<close>} |
891 \<open>Const ("Nat.Suc", _) $ Var (("x", 0), _)\<close>} |
890 |
892 |
891 which shows the internal representation of the term \<open>Suc ?x\<close>. Similarly |
893 which shows the internal representation of the term \<open>Suc ?x\<close>. Similarly |
892 we can write an antiquotation for type patterns. Its code is |
894 we can write an antiquotation for type patterns. Its code is |
893 \<close> |
895 \<close> |
894 |
896 |
978 end\<close> |
980 end\<close> |
979 |
981 |
980 text \<open> |
982 text \<open> |
981 The data can be retrieved with the projection functions defined above. |
983 The data can be retrieved with the projection functions defined above. |
982 |
984 |
983 @{ML_matchresult_fake [display, gray] |
985 @{ML_response [display, gray] |
984 \<open>project_int (nth foo_list 0); |
986 \<open>(project_int (nth foo_list 0), |
985 project_bool (nth foo_list 1)\<close> |
987 project_bool (nth foo_list 1))\<close> |
986 \<open>13 |
988 \<open>13, |
987 true\<close>} |
989 true\<close>} |
988 |
990 |
989 Notice that we access the integer as an integer and the boolean as |
991 Notice that we access the integer as an integer and the boolean as |
990 a boolean. If we attempt to access the integer as a boolean, then we get |
992 a boolean. If we attempt to access the integer as a boolean, then we get |
991 a runtime error. |
993 a runtime error. |
992 |
994 |
993 @{ML_matchresult_fake [display, gray] |
995 @{ML_response [display, gray] |
994 \<open>project_bool (nth foo_list 0)\<close> |
996 \<open>project_bool (nth foo_list 0)\<close> |
995 \<open>*** exception Match raised\<close>} |
997 \<open>exception Match raised\<close>} |
996 |
998 |
997 This runtime error is the reason why ML is still type-sound despite |
999 This runtime error is the reason why ML is still type-sound despite |
998 containing a universal type. |
1000 containing a universal type. |
999 |
1001 |
1000 Now, Isabelle heavily uses this mechanism for storing all sorts of |
1002 Now, Isabelle heavily uses this mechanism for storing all sorts of |
1060 text \<open> |
1062 text \<open> |
1061 The use of the command \isacommand{setup} makes sure the table in the |
1063 The use of the command \isacommand{setup} makes sure the table in the |
1062 \emph{current} theory is updated (this is explained further in |
1064 \emph{current} theory is updated (this is explained further in |
1063 Section~\ref{sec:theories}). The lookup can now be performed as follows. |
1065 Section~\ref{sec:theories}). The lookup can now be performed as follows. |
1064 |
1066 |
1065 @{ML_matchresult_fake [display, gray] |
1067 @{ML_response [display, gray] |
1066 \<open>lookup @{theory} "conj"\<close> |
1068 \<open>lookup @{theory} "conj"\<close> |
1067 \<open>SOME "\<lbrakk>?P; ?Q\<rbrakk> \<Longrightarrow> ?P \<and> ?Q"\<close>} |
1069 \<open>SOME "\<lbrakk>?P; ?Q\<rbrakk> \<Longrightarrow> ?P \<and> ?Q"\<close>} |
1068 |
1070 |
1069 An important point to note is that these tables (and data in general) |
1071 An important point to note is that these tables (and data in general) |
1070 need to be treated in a purely functional fashion. Although |
1072 need to be treated in a purely functional fashion. Although |
1071 we can update the table as follows |
1073 we can update the table as follows |
1072 \<close> |
1074 \<close> |
1073 |
1075 |
1074 setup %gray \<open>update "conj" @{thm TrueI}\<close> |
1076 setup %gray \<open>update "conj" @{thm TrueI}\<close> |
1075 |
1077 |
|
1078 |
1076 text \<open> |
1079 text \<open> |
1077 and accordingly, @{ML lookup} now produces the introduction rule for @{term "True"} |
1080 and accordingly, @{ML lookup} now produces the introduction rule for @{term "True"} |
1078 |
1081 |
1079 @{ML_matchresult_fake [display, gray] |
1082 @{ML_response [display, gray] |
1080 \<open>lookup @{theory} "conj"\<close> |
1083 \<open>lookup @{theory} "conj"\<close> |
1081 \<open>SOME "True"\<close>} |
1084 \<open>SOME "True"\<close>} |
1082 |
1085 |
1083 there are no references involved. This is one of the most fundamental |
1086 there are no references involved. This is one of the most fundamental |
1084 coding conventions for programming in Isabelle. References |
1087 coding conventions for programming in Isabelle. References |
1269 |
1272 |
1270 text \<open> |
1273 text \<open> |
1271 The rules in the list can be retrieved using the function |
1274 The rules in the list can be retrieved using the function |
1272 @{ML FooRules.get}: |
1275 @{ML FooRules.get}: |
1273 |
1276 |
1274 @{ML_matchresult_fake [display,gray] |
1277 @{ML_response [display,gray] |
1275 \<open>FooRules.get @{context}\<close> |
1278 \<open>FooRules.get @{context}\<close> |
1276 \<open>["True", "?C","?B"]\<close>} |
1279 \<open>["True", "?C", "?B"]\<close>} |
1277 |
1280 |
1278 Note that this function takes a proof context as argument. This might be |
1281 Note that this function takes a proof context as argument. This might be |
1279 confusing, since the theorem list is stored as theory data. It becomes clear by knowing |
1282 confusing, since the theorem list is stored as theory data. It becomes clear by knowing |
1280 that the proof context contains the information about the current theory and so the function |
1283 that the proof context contains the information about the current theory and so the function |
1281 can access the theorem list in the theory via the context. |
1284 can access the theorem list in the theory via the context. |