362 end" |
363 end" |
363 "P z za zb"} |
364 "P z za zb"} |
364 |
365 |
365 You can read off this behaviour from how @{ML apply_fresh_args} is |
366 You can read off this behaviour from how @{ML apply_fresh_args} is |
366 coded: in Line 2, the function @{ML [index] fastype_of} calculates the type of the |
367 coded: in Line 2, the function @{ML [index] fastype_of} calculates the type of the |
367 function; @{ML [index] binder_types} in the next line produces the list of argument |
368 term; @{ML [index] binder_types} in the next line produces the list of argument |
368 types (in the case above the list @{text "[nat, int, unit]"}); Line 4 |
369 types (in the case above the list @{text "[nat, int, unit]"}); Line 4 |
369 pairs up each type with the string @{text "z"}; the |
370 pairs up each type with the string @{text "z"}; the |
370 function @{ML [index] variant_frees in Variable} generates for each @{text "z"} a |
371 function @{ML [index] variant_frees in Variable} generates for each @{text "z"} a |
371 unique name avoiding the given @{text f}; the list of name-type pairs is turned |
372 unique name avoiding the given @{text f}; the list of name-type pairs is turned |
372 into a list of variable terms in Line 6, which in the last line is applied |
373 into a list of variable terms in Line 6, which in the last line is applied |
373 by the function @{ML [index] list_comb} to the function. In this last step we have to |
374 by the function @{ML [index] list_comb} to the term. In this last step we have to |
374 use the function @{ML [index] curry}, because @{ML [index] list_comb} expects the |
375 use the function @{ML [index] curry}, because @{ML [index] list_comb} expects the |
375 function and the variables list as a pair. This kind of functions is often needed when |
376 function and the variables list as a pair. This kind of functions is often needed when |
376 constructing terms and the infrastructure helps tremendously to avoid |
377 constructing terms with fresh variables. The infrastructure helps tremendously |
377 any name clashes. Consider for example: |
378 to avoid any name clashes. Consider for example: |
378 |
379 |
379 @{ML_response_fake [display,gray] |
380 @{ML_response_fake [display,gray] |
380 "let |
381 "let |
381 val t = @{term \"za::'a \<Rightarrow> 'b \<Rightarrow> 'c\"} |
382 val t = @{term \"za::'a \<Rightarrow> 'b \<Rightarrow> 'c\"} |
382 val ctxt = @{context} |
383 val ctxt = @{context} |
635 (FIXME give a better example why bindings are important; maybe |
637 (FIXME give a better example why bindings are important; maybe |
636 give a pointer to \isacommand{local\_setup}; if not, then explain |
638 give a pointer to \isacommand{local\_setup}; if not, then explain |
637 why @{ML snd} is needed) |
639 why @{ML snd} is needed) |
638 |
640 |
639 It is also possible to define your own antiquotations. But you should |
641 It is also possible to define your own antiquotations. But you should |
640 exercise care when introducing new one, as they can also make your |
642 exercise care when introducing new ones, as they can also make your |
641 code unreadable. In the next section we will see how the (build in) |
643 code also difficult to read. In the next section we will see how the (build in) |
642 antiquotation @{text "@{term \<dots>}"} can be used to construct terms. |
644 antiquotation @{text "@{term \<dots>}"} can be used to construct terms. |
643 A restriction of this antiquotation is that it does not allow you to |
645 A restriction of this antiquotation is that it does not allow you to |
644 use schematic variables. If you want a antiquotation that does not |
646 use schematic variables. If you want an antiquotation that does not |
645 have this restriction, you can implement your own using the |
647 have this restriction, you can implement your own using the |
646 function @{ML [index] ML_Antiquote.inline}. |
648 function @{ML [index] ML_Antiquote.inline}. The code is as follows. |
647 *} |
649 *} |
648 |
650 |
649 ML %linenosgray{*ML_Antiquote.inline "term_pat" |
651 ML %linenosgray{*ML_Antiquote.inline "term_pat" |
650 (Args.context -- Scan.lift Args.name_source >> |
652 (Args.context -- Scan.lift Args.name_source >> |
651 (fn (ctxt, s) => |
653 (fn (ctxt, s) => |
652 s |> ProofContext.read_term_pattern ctxt |
654 s |> ProofContext.read_term_pattern ctxt |
653 |> ML_Syntax.print_term |
655 |> ML_Syntax.print_term |
654 |> ML_Syntax.atomic))*} |
656 |> ML_Syntax.atomic))*} |
655 |
657 |
656 text {* |
658 text {* |
657 We call the antiquotation @{text "term_pat"} (Line 1); the parser in Line |
659 We call the new antiquotation @{text "term_pat"} (Line 1); the parser in Line |
658 2 provides us with a context and a string; this string is transformed into a |
660 2 provides us with a context and a string; this string is transformed into a |
659 term using the function @{ML read_term_pattern in ProofContext} (Line 4); |
661 term using the function @{ML [index] read_term_pattern in ProofContext} (Line 4); |
660 the next two lines print the term so that the ML-system can understand |
662 the next two lines print the term so that the ML-system can understand |
661 them. An example of this antiquotation is as follows. |
663 them. An example of this antiquotation is as follows. |
662 |
664 |
663 @{ML_response_fake [display,gray] |
665 @{ML_response_fake [display,gray] |
664 "@{term_pat \"Suc (?x::nat)\"}" |
666 "@{term_pat \"Suc (?x::nat)\"}" |
665 "Const (\"Suc\", \"nat \<Rightarrow> nat\") $ Var ((\"x\", 0), \"nat\")"} |
667 "Const (\"Suc\", \"nat \<Rightarrow> nat\") $ Var ((\"x\", 0), \"nat\")"} |
|
668 |
|
669 which is the internal representation of the term @{text "Suc ?x"}. |
666 |
670 |
667 \begin{readmore} |
671 \begin{readmore} |
668 The file @{ML_file "Pure/ML/ml_antiquote.ML"} contains the the definitions |
672 The file @{ML_file "Pure/ML/ml_antiquote.ML"} contains the the definitions |
669 for most antiquotations. |
673 for most antiquotations. |
670 \end{readmore} |
674 \end{readmore} |
671 |
675 |
672 Note also that in Isabelle there are two kinds of antiquotations, which have |
676 Note one source of possible confusion about antiquotations. There are two kinds |
673 very different infrastructures. The first kind, described in this section, |
677 of them in Isabelle, which have very different purpose and infrastructures. The |
674 is sometimes called \emph{ML-antiquotations}. They are used to refer to |
678 first kind, described in this section, are \emph{ML-antiquotations}. They are |
675 entities (like terms, types etc) from Isabelle's logic layer inside ML-code. |
679 used to refer to entities (like terms, types etc) from Isabelle's logic layer |
676 They are ``linked'' statically at compile-time, which limits sometimes |
680 inside ML-code. They are ``linked'' statically at compile-time, which limits |
677 their usefulness in cases where, for example, terms needs to be built up |
681 sometimes their usefulness in cases where, for example, terms needs to be |
678 dynamically. |
682 built up dynamically. |
679 |
683 |
680 The other kind of antiquotations are called \emph{document antiquotations}. |
684 The other kind of antiquotations are \emph{document} antiquotations. |
681 They are used only in the text parts of Isabelle and help with printing logical |
685 They are used only in the text parts of Isabelle and their purpose is to print |
682 entities inside \LaTeX-documents. In this Tutorial we are not interested |
686 logical entities inside \LaTeX-documents. They are part of the user level and |
683 in these antiquotations, except in Appendix \ref{rec:docantiquotations} where |
687 therefore we are not interested in them in this Tutorial, except in |
684 we show how to implement your own document antiquotations. |
688 Appendix \ref{rec:docantiquotations} where we show how to implement your |
|
689 own document antiquotations. |
685 *} |
690 *} |
686 |
691 |
687 section {* Terms and Types *} |
692 section {* Terms and Types *} |
688 |
693 |
689 text {* |
694 text {* |
706 | Bound of int |
711 | Bound of int |
707 | Abs of string * typ * term |
712 | Abs of string * typ * term |
708 | $ of term * term *} |
713 | $ of term * term *} |
709 |
714 |
710 text {* |
715 text {* |
|
716 This datatype implements lambda-terms typed in Church-style. |
711 As can be seen in Line 5, terms use the usual de Bruijn index mechanism |
717 As can be seen in Line 5, terms use the usual de Bruijn index mechanism |
712 for representing bound variables. For |
718 for representing bound variables. For |
713 example in |
719 example in |
714 |
720 |
715 @{ML_response_fake [display, gray] |
721 @{ML_response_fake [display, gray] |
716 "@{term \"\<lambda>x y. x y\"}" |
722 "@{term \"\<lambda>x y. x y\"}" |
717 "Abs (\"x\", \"'a \<Rightarrow> 'b\", Abs (\"y\", \"'a\", Bound 1 $ Bound 0))"} |
723 "Abs (\"x\", \"'a \<Rightarrow> 'b\", Abs (\"y\", \"'a\", Bound 1 $ Bound 0))"} |
718 |
724 |
719 the indices refer to the number of Abstractions (@{ML Abs}) that we need to skip |
725 the indices refer to the number of Abstractions (@{ML Abs}) that we need to |
720 until we hit the @{ML Abs} that binds the corresponding variable. Note that |
726 skip until we hit the @{ML Abs} that binds the corresponding variable. Constructing |
721 the names of bound variables are kept at abstractions for printing purposes, |
727 a term with dangling de Bruijn indices is possible, but will be flagged as |
722 and so should be treated only as ``comments''. Application in Isabelle is |
728 ill-formed when you try to typecheck or certify it (see |
723 realised with the term-constructor @{ML $}. |
729 Section~\ref{sec:typechecking}). Note that the names of bound variables are kept at |
|
730 abstractions for printing purposes, and so should be treated only as |
|
731 ``comments''. Application in Isabelle is realised with the term-constructor |
|
732 @{ML $}. |
|
733 |
724 |
734 |
725 Isabelle makes a distinction between \emph{free} variables (term-constructor @{ML Free}) |
735 Isabelle makes a distinction between \emph{free} variables (term-constructor @{ML Free}) |
726 and variables (term-constructor @{ML Var}). The latter correspond to the schematic |
736 and variables (term-constructor @{ML Var}). The latter correspond to the schematic |
727 variables that when printed show up with a question mark in front of them. Consider |
737 variables that when printed show up with a question mark in front of them. Consider |
728 the following two examples |
738 the following two examples |
729 |
739 |
730 @{ML_response_fake [display, gray] |
740 @{ML_response_fake [display, gray] |
731 "let |
741 "let |
732 val v1 = Var ((\"x\", 3), @{typ bool}) |
742 val v1 = Var ((\"x\", 3), @{typ bool}) |
733 val v2 = Var ((\"x1\", 3), @{typ bool}) |
743 val v2 = Var ((\"x1\", 3), @{typ bool}) |
|
744 val v3 = Free (\"x\", @{typ bool}) |
734 in |
745 in |
735 writeln (Syntax.string_of_term @{context} v1); |
746 writeln (Syntax.string_of_term @{context} v1); |
736 writeln (Syntax.string_of_term @{context} v2) |
747 writeln (Syntax.string_of_term @{context} v2); |
|
748 writeln (Syntax.string_of_term @{context} v3) |
737 end" |
749 end" |
738 "?x3 |
750 "?x3 |
739 ?x1.3"} |
751 ?x1.3 |
740 |
752 x"} |
741 This is different from a free variable |
753 |
742 |
754 When constructing terms, you are usually concerned with free variables (as mentioned earlier, |
743 @{ML_response_fake [display, gray] |
|
744 "writeln (Syntax.string_of_term @{context} (Free (\"x\", @{typ bool})))" |
|
745 "x"} |
|
746 |
|
747 When constructing terms, you are usually concerned with free variables (for example |
|
748 you cannot construct schematic variables using the antiquotation @{text "@{term \<dots>}"}). |
755 you cannot construct schematic variables using the antiquotation @{text "@{term \<dots>}"}). |
749 If you deal with theorems, you have to, however, observe the distinction. A similar |
756 If you deal with theorems, you have to, however, observe the distinction. A similar |
750 distinction holds for types (see below). |
757 distinction holds for types (see below). |
751 |
758 |
752 \begin{readmore} |
759 \begin{readmore} |
828 text {* |
835 text {* |
829 Like with terms, there is the distinction between free type |
836 Like with terms, there is the distinction between free type |
830 variables (term-constructor @{ML "TFree"} and schematic |
837 variables (term-constructor @{ML "TFree"} and schematic |
831 type variables (term-constructor @{ML "TVar"}). A type constant, |
838 type variables (term-constructor @{ML "TVar"}). A type constant, |
832 like @{typ "int"} or @{typ bool}, are types with an empty list |
839 like @{typ "int"} or @{typ bool}, are types with an empty list |
833 of argument types. |
840 of argument types. However, it is a bit difficult to show an |
834 |
841 example, because Isabelle always pretty-prints types (unlike terms). |
|
842 Here is a contrived example: |
|
843 |
|
844 @{ML_response [display, gray] |
|
845 "if Type (\"bool\", []) = @{typ \"bool\"} then true else false" |
|
846 "true"} |
835 |
847 |
836 \begin{readmore} |
848 \begin{readmore} |
837 Types are described in detail in \isccite{sec:types}. Their |
849 Types are described in detail in \isccite{sec:types}. Their |
838 definition and many useful operations are implemented |
850 definition and many useful operations are implemented |
839 in @{ML_file "Pure/type.ML"}. |
851 in @{ML_file "Pure/type.ML"}. |
889 constructing terms. One is the function @{ML [index] list_comb}, which takes a term |
901 constructing terms. One is the function @{ML [index] list_comb}, which takes a term |
890 and a list of terms as arguments, and produces as output the term |
902 and a list of terms as arguments, and produces as output the term |
891 list applied to the term. For example |
903 list applied to the term. For example |
892 |
904 |
893 @{ML_response_fake [display,gray] |
905 @{ML_response_fake [display,gray] |
894 "list_comb (@{term \"P::nat\"}, [@{term \"True\"}, @{term \"False\"}])" |
906 "let |
|
907 val t = @{term \"P::nat\"} |
|
908 val args = [@{term \"True\"}, @{term \"False\"}] |
|
909 in |
|
910 list_comb (t, args) |
|
911 end" |
895 "Free (\"P\", \"nat\") $ Const (\"True\", \"bool\") $ Const (\"False\", \"bool\")"} |
912 "Free (\"P\", \"nat\") $ Const (\"True\", \"bool\") $ Const (\"False\", \"bool\")"} |
896 |
913 |
897 Another handy function is @{ML [index] lambda}, which abstracts a variable |
914 Another handy function is @{ML [index] lambda}, which abstracts a variable |
898 in a term. For example |
915 in a term. For example |
899 |
916 |
900 @{ML_response_fake [display,gray] |
917 @{ML_response_fake [display,gray] |
901 "lambda @{term \"x::nat\"} @{term \"(P::nat \<Rightarrow> bool) x\"}" |
918 "lambda @{term \"x::nat\"} @{term \"(P::nat \<Rightarrow> bool) x\"}" |
902 "Abs (\"x\", \"nat\", Free (\"P\", \"bool \<Rightarrow> bool\") $ Bound 0)"} |
919 "Abs (\"x\", \"nat\", Free (\"P\", \"bool \<Rightarrow> bool\") $ Bound 0)"} |
903 |
920 |
904 In this example, @{ML lambda} produces a de Bruijn index (i.e.~@{ML "Bound 0"}), |
921 In this example, @{ML lambda} produces a de Bruijn index (i.e.~@{ML "Bound 0"}), |
905 and an abstraction. It also records the type of the abstracted |
922 and an abstraction. It also records the type of the abstracted |
906 variable and for printing purposes also its name. Note that because of the |
923 variable and for printing purposes also its name. Note that because of the |
907 typing annotation on @{text "P"}, the variable @{text "x"} in @{text "P x"} |
924 typing annotation on @{text "P"}, the variable @{text "x"} in @{text "P x"} |
908 is of the same type as the abstracted variable. If it is of different type, |
925 is of the same type as the abstracted variable. If it is of different type, |
909 as in |
926 as in |