87 then there is a convenient, though again ``quick-and-dirty'', method for |
87 then there is a convenient, though again ``quick-and-dirty'', method for |
88 converting values into strings, namely the function @{ML makestring}: |
88 converting values into strings, namely the function @{ML makestring}: |
89 |
89 |
90 @{ML_response_fake [display,gray] "warning (makestring 1)" "\"1\""} |
90 @{ML_response_fake [display,gray] "warning (makestring 1)" "\"1\""} |
91 |
91 |
92 However @{ML makestring} only works if the type of what is converted is monomorphic |
92 However, @{ML makestring} only works if the type of what is converted is monomorphic |
93 and not a function. |
93 and not a function. |
94 |
94 |
95 The function @{ML "warning"} should only be used for testing purposes, because any |
95 The function @{ML "warning"} should only be used for testing purposes, because any |
96 output this function generates will be overwritten as soon as an error is |
96 output this function generates will be overwritten as soon as an error is |
97 raised. For printing anything more serious and elaborate, the |
97 raised. For printing anything more serious and elaborate, the |
359 intermediate result inside the tracing buffer. The function @{ML tap} can |
359 intermediate result inside the tracing buffer. The function @{ML tap} can |
360 only be used for side-calculations, because any value that is computed |
360 only be used for side-calculations, because any value that is computed |
361 cannot be merged back into the ``main waterfall''. To do this, you can use |
361 cannot be merged back into the ``main waterfall''. To do this, you can use |
362 the next combinator. |
362 the next combinator. |
363 |
363 |
364 The combinator @{ML "`"} is similar to @{ML tap}, but applies a function to the value |
364 The combinator @{ML "`"} (a backtick) is similar to @{ML tap}, but applies a |
365 and returns the result together with the value (as a pair). For example |
365 function to the value and returns the result together with the value (as a |
366 the function |
366 pair). For example the function |
367 *} |
367 *} |
368 |
368 |
369 ML{*fun inc_as_pair x = |
369 ML{*fun inc_as_pair x = |
370 x |> `(fn x => x + 1) |
370 x |> `(fn x => x + 1) |
371 |> (fn (x, y) => (x, y + 1))*} |
371 |> (fn (x, y) => (x, y + 1))*} |
403 ML{*fun double x = |
403 ML{*fun double x = |
404 x |> (fn x => (x, x)) |
404 x |> (fn x => (x, x)) |
405 |-> (fn x => fn y => x + y)*} |
405 |-> (fn x => fn y => x + y)*} |
406 |
406 |
407 text {* |
407 text {* |
408 Recall that @{ML "|>"} is the reverse function applications. Recall also that the related |
408 Recall that @{ML "|>"} is the reverse function application. Recall also that |
|
409 the related |
409 reverse function composition is @{ML "#>"}. In fact all the combinators @{ML "|->"}, |
410 reverse function composition is @{ML "#>"}. In fact all the combinators @{ML "|->"}, |
410 @{ML "|>>"} and @{ML "||>"} described above have related combinators for function |
411 @{ML "|>>"} and @{ML "||>"} described above have related combinators for function |
411 composition, namely @{ML "#->"}, @{ML "#>>"} and @{ML "##>"}. Using @{ML "#->"}, |
412 composition, namely @{ML "#->"}, @{ML "#>>"} and @{ML "##>"}. Using @{ML "#->"}, |
412 for example, the function @{text double} can also be written as: |
413 for example, the function @{text double} can also be written as: |
413 *} |
414 *} |
493 |
495 |
494 @{ML_response_fake [display,gray] |
496 @{ML_response_fake [display,gray] |
495 "get_thm_names_from_ss @{simpset}" |
497 "get_thm_names_from_ss @{simpset}" |
496 "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"} |
498 "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"} |
497 |
499 |
498 Again, this way or referencing simpsets makes you independent from additions |
500 Again, this way of referencing simpsets makes you independent from additions |
499 of lemmas to the simpset by the user that potentially cause loops. |
501 of lemmas to the simpset by the user that potentially cause loops. |
500 |
502 |
501 On the ML-level of Isabelle, you often have to work with qualified names; |
503 On the ML-level of Isabelle, you often have to work with qualified names; |
502 these are strings with some additional information, such positional information |
504 these are strings with some additional information, such as positional information |
503 and qualifiers. Such bindings can be generated with the antiquotation |
505 and qualifiers. Such bindings can be generated with the antiquotation |
504 @{text "@{binding \<dots>}"}. |
506 @{text "@{binding \<dots>}"}. |
505 |
507 |
506 @{ML_response [display,gray] |
508 @{ML_response [display,gray] |
507 "@{binding \"name\"}" |
509 "@{binding \"name\"}" |
508 "name"} |
510 "name"} |
509 |
511 |
510 An example where a binding is needed is the function @{ML define in LocalTheory}. |
512 An example where a binding is needed is the function @{ML define in |
511 Below this function defines the constant @{term "TrueConj"} as the conjunction |
513 LocalTheory}. Below, this function is used to define the constant @{term |
|
514 "TrueConj"} as the conjunction |
512 @{term "True \<and> True"}. |
515 @{term "True \<and> True"}. |
513 *} |
516 *} |
514 |
517 |
515 local_setup %gray {* |
518 local_setup %gray {* |
516 snd o LocalTheory.define Thm.internalK |
519 snd o LocalTheory.define Thm.internalK |
517 ((@{binding "TrueConj"}, NoSyn), |
520 ((@{binding "TrueConj"}, NoSyn), |
518 (Attrib.empty_binding, @{term "True \<and> True"})) *} |
521 (Attrib.empty_binding, @{term "True \<and> True"})) *} |
519 |
522 |
|
523 <<<<<<< local |
520 text {* |
524 text {* |
521 Now querying the definition you obtain: |
525 Now querying the definition you obtain: |
522 |
526 |
523 \begin{isabelle} |
527 \begin{isabelle} |
524 \isacommand{thm}~@{text "TrueConj_def"}\\ |
528 \isacommand{thm}~@{text "TrueConj_def"}\\ |
526 \end{isabelle} |
530 \end{isabelle} |
527 |
531 |
528 (FIXME give a better example why bindings are important; maybe |
532 (FIXME give a better example why bindings are important; maybe |
529 give a pointer to \isacommand{local\_setup}) |
533 give a pointer to \isacommand{local\_setup}) |
530 |
534 |
531 While antiquotations have many applications, they were originally introduced in order |
535 While antiquotations have many applications, they were originally introduced |
532 to avoid explicit bindings for theorems such as: |
536 in order to avoid explicit bindings of theorems such as: |
533 *} |
537 *} |
534 |
538 |
535 ML{*val allI = thm "allI" *} |
539 ML{*val allI = thm "allI" *} |
536 |
540 |
537 text {* |
541 text {* |
538 These bindings are difficult to maintain and also can be accidentally |
542 Such bindings are difficult to maintain and can be overwritten by the |
539 overwritten by the user. This often broke Isabelle |
543 user accidentally. This often broke Isabelle |
540 packages. Antiquotations solve this problem, since they are ``linked'' |
544 packages. Antiquotations solve this problem, since they are ``linked'' |
541 statically at compile-time. However, this static linkage also limits their |
545 statically at compile-time. However, this static linkage also limits their |
542 usefulness in cases where data needs to be build up dynamically. In the |
546 usefulness in cases where data needs to be built up dynamically. In the |
543 course of this chapter you will learn more about these antiquotations: |
547 course of this chapter you will learn more about antiquotations: |
544 they can simplify Isabelle programming since one can directly access all |
548 they can simplify Isabelle programming since one can directly access all |
545 kinds of logical elements from th ML-level. |
549 kinds of logical elements from the ML-level. |
546 *} |
550 *} |
547 |
551 |
548 section {* Terms and Types *} |
552 section {* Terms and Types *} |
549 |
553 |
550 text {* |
554 text {* |
551 One way to construct terms of Isabelle is by using the antiquotation |
555 One way to construct Isabelle terms, is by using the antiquotation |
552 \mbox{@{text "@{term \<dots>}"}}. For example: |
556 \mbox{@{text "@{term \<dots>}"}}. For example: |
553 |
557 |
554 @{ML_response [display,gray] |
558 @{ML_response [display,gray] |
555 "@{term \"(a::nat) + b = c\"}" |
559 "@{term \"(a::nat) + b = c\"}" |
556 "Const (\"op =\", \<dots>) $ |
560 "Const (\"op =\", \<dots>) $ |
557 (Const (\"HOL.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"} |
561 (Const (\"HOL.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"} |
558 |
562 |
559 This will show the term @{term "(a::nat) + b = c"}, but printed using the internal |
563 will show the term @{term "(a::nat) + b = c"}, but printed using an internal |
560 representation of this term. This internal representation corresponds to the |
564 representation corresponding to the data type @{ML_type "term"}. |
561 datatype @{ML_type "term"}. |
565 |
562 |
566 This internal representation uses the usual de Bruijn index mechanism---where |
563 The internal representation of terms uses the usual de Bruijn index mechanism where bound |
567 bound variables are represented by the constructor @{ML Bound}. The index in |
564 variables are represented by the constructor @{ML Bound}. The index in @{ML Bound} refers to |
568 @{ML Bound} refers to the number of Abstractions (@{ML Abs}) we have to skip |
565 the number of Abstractions (@{ML Abs}) we have to skip until we hit the @{ML Abs} that |
569 until we hit the @{ML Abs} that binds the corresponding variable. Note that |
566 binds the corresponding variable. However, in Isabelle the names of bound variables are |
570 the names of bound variables are kept at abstractions for printing purposes, |
567 kept at abstractions for printing purposes, and so should be treated only as ``comments''. |
571 and so should be treated only as ``comments''. Application in Isabelle is |
568 Application in Isabelle is realised with the term-constructor @{ML $}. |
572 realised with the term-constructor @{ML $}. |
569 |
573 |
570 \begin{readmore} |
574 \begin{readmore} |
571 Terms are described in detail in \isccite{sec:terms}. Their |
575 Terms are described in detail in \isccite{sec:terms}. Their |
572 definition and many useful operations are implemented in @{ML_file "Pure/term.ML"}. |
576 definition and many useful operations are implemented in @{ML_file "Pure/term.ML"}. |
573 \end{readmore} |
577 \end{readmore} |
677 Abs (\"x\", \<dots>, |
681 Abs (\"x\", \<dots>, |
678 Const \<dots> $ (Const \<dots> $ (Free (\"P\",\<dots>) $ \<dots>)) $ |
682 Const \<dots> $ (Const \<dots> $ (Free (\"P\",\<dots>) $ \<dots>)) $ |
679 (Const \<dots> $ (Free (\"Q\",\<dots>) $ \<dots>)))"} |
683 (Const \<dots> $ (Free (\"Q\",\<dots>) $ \<dots>)))"} |
680 |
684 |
681 There are a number of handy functions that are frequently used for |
685 There are a number of handy functions that are frequently used for |
682 constructing terms. One is the function @{ML list_comb}, which takes |
686 constructing terms. One is the function @{ML list_comb}, which takes a term |
683 a term and a list of terms as arguments, and produces as output the term |
687 and a list of terms as arguments, and produces as output the term |
684 list applied to the term. For example |
688 list applied to the term. For example |
685 |
689 |
686 @{ML_response_fake [display,gray] |
690 @{ML_response_fake [display,gray] |
687 "list_comb (@{term \"P::nat\"}, [@{term \"True\"}, @{term \"False\"}])" |
691 "list_comb (@{term \"P::nat\"}, [@{term \"True\"}, @{term \"False\"}])" |
688 "Free (\"P\", \"nat\") $ Const (\"True\", \"bool\") $ Const (\"False\", \"bool\")"} |
692 "Free (\"P\", \"nat\") $ Const (\"True\", \"bool\") $ Const (\"False\", \"bool\")"} |
744 associates to the left. Try your function on some examples. |
748 associates to the left. Try your function on some examples. |
745 \end{exercise} |
749 \end{exercise} |
746 |
750 |
747 \begin{exercise}\label{fun:makesum} |
751 \begin{exercise}\label{fun:makesum} |
748 Write a function which takes two terms representing natural numbers |
752 Write a function which takes two terms representing natural numbers |
749 in unary notation (like @{term "Suc (Suc (Suc 0))"}), and produce the |
753 in unary notation (like @{term "Suc (Suc (Suc 0))"}), and produces the |
750 number representing their sum. |
754 number representing their sum. |
751 \end{exercise} |
755 \end{exercise} |
752 |
756 |
753 There are a few subtle issues with constants. They usually crop up when |
757 There are a few subtle issues with constants. They usually crop up when |
754 pattern matching terms or types, or when constructing them. While it is perfectly ok |
758 pattern matching terms or types, or when constructing them. While it is perfectly ok |
806 by @{ML "Const (\"All\", some_type)" for some_type}. However, if you look at |
810 by @{ML "Const (\"All\", some_type)" for some_type}. However, if you look at |
807 |
811 |
808 @{ML_response [display,gray] "@{term \"Nil\"}" "Const (\"List.list.Nil\", \<dots>)"} |
812 @{ML_response [display,gray] "@{term \"Nil\"}" "Const (\"List.list.Nil\", \<dots>)"} |
809 |
813 |
810 the name of the constant @{text "Nil"} depends on the theory in which the |
814 the name of the constant @{text "Nil"} depends on the theory in which the |
811 term constructor is defined (@{text "List"}) and also in which datatype |
815 term constructor is defined (@{text "List"}) and also in which data type |
812 (@{text "list"}). Even worse, some constants have a name involving |
816 (@{text "list"}). Even worse, some constants have a name involving |
813 type-classes. Consider for example the constants for @{term "zero"} and |
817 type-classes. Consider for example the constants for @{term "zero"} and |
814 \mbox{@{text "(op *)"}}: |
818 \mbox{@{text "(op *)"}}: |
815 |
819 |
816 @{ML_response [display,gray] "(@{term \"0::nat\"}, @{term \"op *\"})" |
820 @{ML_response [display,gray] "(@{term \"0::nat\"}, @{term \"op *\"})" |
818 Const (\"HOL.times_class.times\", \<dots>))"} |
822 Const (\"HOL.times_class.times\", \<dots>))"} |
819 |
823 |
820 While you could use the complete name, for example |
824 While you could use the complete name, for example |
821 @{ML "Const (\"List.list.Nil\", some_type)" for some_type}, for referring to or |
825 @{ML "Const (\"List.list.Nil\", some_type)" for some_type}, for referring to or |
822 matching against @{text "Nil"}, this would make the code rather brittle. |
826 matching against @{text "Nil"}, this would make the code rather brittle. |
823 The reason is that the theory and the name of the datatype can easily change. |
827 The reason is that the theory and the name of the data type can easily change. |
824 To make the code more robust, it is better to use the antiquotation |
828 To make the code more robust, it is better to use the antiquotation |
825 @{text "@{const_name \<dots>}"}. With this antiquotation you can harness the |
829 @{text "@{const_name \<dots>}"}. With this antiquotation you can harness the |
826 variable parts of the constant's name. Therefore a functions for |
830 variable parts of the constant's name. Therefore a function for |
827 matching against constants that have a polymorphic type should |
831 matching against constants that have a polymorphic type should |
828 be written as follows. |
832 be written as follows. |
829 *} |
833 *} |
830 |
834 |
831 ML{*fun is_nil_or_all (Const (@{const_name "Nil"}, _)) = true |
835 ML{*fun is_nil_or_all (Const (@{const_name "Nil"}, _)) = true |
832 | is_nil_or_all (Const (@{const_name "All"}, _) $ _) = true |
836 | is_nil_or_all (Const (@{const_name "All"}, _) $ _) = true |
833 | is_nil_or_all _ = false *} |
837 | is_nil_or_all _ = false *} |
834 |
838 |
835 text {* |
839 text {* |
836 Occasional you have to calculate what the ``base'' name of a given |
840 Occasionally you have to calculate what the ``base'' name of a given |
837 constant is. For this you can use the function @{ML Sign.extern_const} or |
841 constant is. For this you can use the function @{ML Sign.extern_const} or |
838 @{ML Long_Name.base_name}. For example: |
842 @{ML Long_Name.base_name}. For example: |
839 |
843 |
840 @{ML_response [display,gray] "Sign.extern_const @{theory} \"List.list.Nil\"" "\"Nil\""} |
844 @{ML_response [display,gray] "Sign.extern_const @{theory} \"List.list.Nil\"" "\"Nil\""} |
841 |
845 |
872 @{typ nat} => @{typ int} |
876 @{typ nat} => @{typ int} |
873 | Type (s, ts) => Type (s, map nat_to_int ts) |
877 | Type (s, ts) => Type (s, map nat_to_int ts) |
874 | _ => t)*} |
878 | _ => t)*} |
875 |
879 |
876 text {* |
880 text {* |
877 An example as follows: |
881 Here is an example: |
878 |
882 |
879 @{ML_response_fake [display,gray] |
883 @{ML_response_fake [display,gray] |
880 "map_types nat_to_int @{term \"a = (1::nat)\"}" |
884 "map_types nat_to_int @{term \"a = (1::nat)\"}" |
881 "Const (\"op =\", \"int \<Rightarrow> int \<Rightarrow> bool\") |
885 "Const (\"op =\", \"int \<Rightarrow> int \<Rightarrow> bool\") |
882 $ Free (\"a\", \"int\") $ Const (\"HOL.one_class.one\", \"int\")"} |
886 $ Free (\"a\", \"int\") $ Const (\"HOL.one_class.one\", \"int\")"} |
941 \begin{exercise} |
945 \begin{exercise} |
942 Check that the function defined in Exercise~\ref{fun:revsum} returns a |
946 Check that the function defined in Exercise~\ref{fun:revsum} returns a |
943 result that type-checks. |
947 result that type-checks. |
944 \end{exercise} |
948 \end{exercise} |
945 |
949 |
946 Remember Isabelle follows the Church-style typing for terms, i.e.~a term contains |
950 Remember Isabelle follows the Church-style typing for terms, i.e., a term contains |
947 enough typing information (constants, free variables and abstractions all have typing |
951 enough typing information (constants, free variables and abstractions all have typing |
948 information) so that it is always clear what the type of a term is. |
952 information) so that it is always clear what the type of a term is. |
949 Given a well-typed term, the function @{ML type_of} returns the |
953 Given a well-typed term, the function @{ML type_of} returns the |
950 type of a term. Consider for example: |
954 type of a term. Consider for example: |
951 |
955 |
991 end" |
995 end" |
992 "Const (\"HOL.plus_class.plus\", \"nat \<Rightarrow> nat \<Rightarrow> nat\") $ |
996 "Const (\"HOL.plus_class.plus\", \"nat \<Rightarrow> nat \<Rightarrow> nat\") $ |
993 Const (\"HOL.one_class.one\", \"nat\") $ Free (\"x\", \"nat\")"} |
997 Const (\"HOL.one_class.one\", \"nat\") $ Free (\"x\", \"nat\")"} |
994 |
998 |
995 Instead of giving explicitly the type for the constant @{text "plus"} and the free |
999 Instead of giving explicitly the type for the constant @{text "plus"} and the free |
996 variable @{text "x"}, the type-inference fills in the missing information. |
1000 variable @{text "x"}, type-inference fills in the missing information. |
997 |
1001 |
998 \begin{readmore} |
1002 \begin{readmore} |
999 See @{ML_file "Pure/Syntax/syntax.ML"} where more functions about reading, |
1003 See @{ML_file "Pure/Syntax/syntax.ML"} where more functions about reading, |
1000 checking and pretty-printing of terms are defined. Functions related to the |
1004 checking and pretty-printing of terms are defined. Functions related to |
1001 type inference are implemented in @{ML_file "Pure/type.ML"} and |
1005 type-inference are implemented in @{ML_file "Pure/type.ML"} and |
1002 @{ML_file "Pure/type_infer.ML"}. |
1006 @{ML_file "Pure/type_infer.ML"}. |
1003 \end{readmore} |
1007 \end{readmore} |
1004 |
1008 |
1005 (FIXME: say something about sorts) |
1009 (FIXME: say something about sorts) |
1006 *} |
1010 *} |
1008 |
1012 |
1009 section {* Theorems *} |
1013 section {* Theorems *} |
1010 |
1014 |
1011 text {* |
1015 text {* |
1012 Just like @{ML_type cterm}s, theorems are abstract objects of type @{ML_type thm} |
1016 Just like @{ML_type cterm}s, theorems are abstract objects of type @{ML_type thm} |
1013 that can only be build by going through interfaces. As a consequence, every proof |
1017 that can only be built by going through interfaces. As a consequence, every proof |
1014 in Isabelle is correct by construction. This follows the tradition of the LCF approach |
1018 in Isabelle is correct by construction. This follows the tradition of the LCF approach |
1015 \cite{GordonMilnerWadsworth79}. |
1019 \cite{GordonMilnerWadsworth79}. |
1016 |
1020 |
1017 |
1021 |
1018 To see theorems in ``action'', let us give a proof on the ML-level for the following |
1022 To see theorems in ``action'', let us give a proof on the ML-level for the following |
1079 "[simp]"} and so on. Such attributes are \emph{neither} tags \emph{nor} flags |
1083 "[simp]"} and so on. Such attributes are \emph{neither} tags \emph{nor} flags |
1080 annotated to theorems, but functions that do further processing once a |
1084 annotated to theorems, but functions that do further processing once a |
1081 theorem is proved. In particular, it is not possible to find out |
1085 theorem is proved. In particular, it is not possible to find out |
1082 what are all theorems that have a given attribute in common, unless of course |
1086 what are all theorems that have a given attribute in common, unless of course |
1083 the function behind the attribute stores the theorems in a retrievable |
1087 the function behind the attribute stores the theorems in a retrievable |
1084 datastructure. |
1088 data structure. |
1085 |
1089 |
1086 If you want to print out all currently known attributes a theorem can have, |
1090 If you want to print out all currently known attributes a theorem can have, |
1087 you can use the Isabelle command |
1091 you can use the Isabelle command |
1088 |
1092 |
1089 \begin{isabelle} |
1093 \begin{isabelle} |
1437 section {* Setups (TBD) *} |
1441 section {* Setups (TBD) *} |
1438 |
1442 |
1439 text {* |
1443 text {* |
1440 In the previous section we used \isacommand{setup} in order to make |
1444 In the previous section we used \isacommand{setup} in order to make |
1441 a theorem attribute known to Isabelle. What happens behind the scenes |
1445 a theorem attribute known to Isabelle. What happens behind the scenes |
1442 is that \isacommand{setup} expects a functions of type |
1446 is that \isacommand{setup} expects a function of type |
1443 @{ML_type "theory -> theory"}: the input theory is the current theory and the |
1447 @{ML_type "theory -> theory"}: the input theory is the current theory and the |
1444 output the theory where the theory attribute has been stored. |
1448 output the theory where the theory attribute has been stored. |
1445 |
1449 |
1446 This is a fundamental principle in Isabelle. A similar situation occurs |
1450 This is a fundamental principle in Isabelle. A similar situation occurs |
1447 for example with declaring constants. The function that declares a |
1451 for example with declaring constants. The function that declares a |
1493 There are theories, proof contexts and local theories (in this order, if you |
1497 There are theories, proof contexts and local theories (in this order, if you |
1494 want to order them). |
1498 want to order them). |
1495 |
1499 |
1496 In contrast to an ordinary theory, which simply consists of a type |
1500 In contrast to an ordinary theory, which simply consists of a type |
1497 signature, as well as tables for constants, axioms and theorems, a local |
1501 signature, as well as tables for constants, axioms and theorems, a local |
1498 theory also contains additional context information, such as locally fixed |
1502 theory contains additional context information, such as locally fixed |
1499 variables and local assumptions that may be used by the package. The type |
1503 variables and local assumptions that may be used by the package. The type |
1500 @{ML_type local_theory} is identical to the type of \emph{proof contexts} |
1504 @{ML_type local_theory} is identical to the type of \emph{proof contexts} |
1501 @{ML_type "Proof.context"}, although not every proof context constitutes a |
1505 @{ML_type "Proof.context"}, although not every proof context constitutes a |
1502 valid local theory. |
1506 valid local theory. |
1503 *} |
1507 *} |