550 "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"} |
551 "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"} |
551 |
552 |
552 Again, this way of referencing simpsets makes you independent from additions |
553 Again, this way of referencing simpsets makes you independent from additions |
553 of lemmas to the simpset by the user that potentially cause loops. |
554 of lemmas to the simpset by the user that potentially cause loops. |
554 |
555 |
555 On the ML-level of Isabelle, you often have to work with qualified names; |
556 On the ML-level of Isabelle, you often have to work with qualified names. |
556 these are strings with some additional information, such as positional information |
557 These are strings with some additional information, such as positional information |
557 and qualifiers. Such qualified names can be generated with the antiquotation |
558 and qualifiers. Such qualified names can be generated with the antiquotation |
558 @{text "@{binding \<dots>}"}. |
559 @{text "@{binding \<dots>}"}. |
559 |
560 |
560 @{ML_response [display,gray] |
561 @{ML_response [display,gray] |
561 "@{binding \"name\"}" |
562 "@{binding \"name\"}" |
562 "name"} |
563 "name"} |
563 |
564 |
564 An example where a binding is needed is the function @{ML define in |
565 An example where a binding is needed is the function @{ML define in |
565 LocalTheory}. Below, this function is used to define the constant @{term |
566 LocalTheory}. This function is below used to define the constant @{term |
566 "TrueConj"} as the conjunction |
567 "TrueConj"} as the conjunction |
567 @{term "True \<and> True"}. |
568 @{term "True \<and> True"}. |
568 *} |
569 *} |
569 |
570 |
570 local_setup %gray {* |
571 local_setup %gray {* |
611 "@{term \"(a::nat) + b = c\"}" |
612 "@{term \"(a::nat) + b = c\"}" |
612 "Const (\"op =\", \<dots>) $ |
613 "Const (\"op =\", \<dots>) $ |
613 (Const (\"HOL.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"} |
614 (Const (\"HOL.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"} |
614 |
615 |
615 will show the term @{term "(a::nat) + b = c"}, but printed using the internal |
616 will show the term @{term "(a::nat) + b = c"}, but printed using the internal |
616 representation corresponding to the datatype @{ML_type "term"}. Since Isabelle |
617 representation corresponding to the datatype @{ML_type "term"} defined as follows: |
617 uses Church-style terms, the datatype @{ML_type term} must be defined in |
|
618 conjunction with types, that is the datatype @{ML_type typ}: |
|
619 *} |
618 *} |
620 |
619 |
621 ML_val{*datatype typ = |
620 ML_val{*datatype term = |
622 Type of string * typ list |
|
623 | TFree of string * sort |
|
624 | TVar of indexname * sort |
|
625 datatype term = |
|
626 Const of string * typ |
621 Const of string * typ |
627 | Free of string * typ |
622 | Free of string * typ |
628 | Var of indexname * typ |
623 | Var of indexname * typ |
629 | Bound of int |
624 | Bound of int |
630 | Abs of string * typ * term |
625 | Abs of string * typ * term |
631 | $ of term * term *} |
626 | $ of term * term *} |
632 |
627 |
633 text {* |
628 text {* |
634 The datatype for terms uses the usual de Bruijn index mechanism---where |
629 Terms use the usual de Bruijn index mechanism---where |
635 bound variables are represented by the constructor @{ML Bound}. |
630 bound variables are represented by the constructor @{ML Bound}. For |
|
631 example in |
636 |
632 |
637 @{ML_response_fake [display, gray] |
633 @{ML_response_fake [display, gray] |
638 "@{term \"\<lambda>x y. x y\"}" |
634 "@{term \"\<lambda>x y. x y\"}" |
639 "Abs (\"x\", \"'a \<Rightarrow> 'b\", Abs (\"y\", \"'a\", Bound 1 $ Bound 0))"} |
635 "Abs (\"x\", \"'a \<Rightarrow> 'b\", Abs (\"y\", \"'a\", Bound 1 $ Bound 0))"} |
640 |
636 |
641 The index in |
637 the indices refer to the number of Abstractions (@{ML Abs}) that we need to skip |
642 @{ML Bound} refers to the number of Abstractions (@{ML Abs}) we have to skip |
|
643 until we hit the @{ML Abs} that binds the corresponding variable. Note that |
638 until we hit the @{ML Abs} that binds the corresponding variable. Note that |
644 the names of bound variables are kept at abstractions for printing purposes, |
639 the names of bound variables are kept at abstractions for printing purposes, |
645 and so should be treated only as ``comments''. Application in Isabelle is |
640 and so should be treated only as ``comments''. Application in Isabelle is |
646 realised with the term-constructor @{ML $}. |
641 realised with the term-constructor @{ML $}. |
647 |
642 |
648 Isabelle makes a distinction between \emph{free} variables (term-constructor @{ML Free}) |
643 Isabelle makes a distinction between \emph{free} variables (term-constructor @{ML Free}) |
649 and variables (term-constructor @{ML Var}). The latter correspond to the schematic |
644 and variables (term-constructor @{ML Var}). The latter correspond to the schematic |
650 variables that show up with a question mark in front of them. Consider the following |
645 variables that when printed show up with a question mark in front of them. Consider |
651 two examples |
646 the following two examples |
652 |
647 |
653 @{ML_response_fake [display, gray] |
648 @{ML_response_fake [display, gray] |
654 "let |
649 "let |
655 val v1 = Var ((\"x\", 3), @{typ bool}) |
650 val v1 = Var ((\"x\", 3), @{typ bool}) |
656 val v2 = Var ((\"x1\",3), @{typ bool}) |
651 val v2 = Var ((\"x1\", 3), @{typ bool}) |
657 in |
652 in |
658 writeln (Syntax.string_of_term @{context} v1); |
653 writeln (Syntax.string_of_term @{context} v1); |
659 writeln (Syntax.string_of_term @{context} v2) |
654 writeln (Syntax.string_of_term @{context} v2) |
660 end" |
655 end" |
661 "?x3 |
656 "?x3 |
662 ?x1.3"} |
657 ?x1.3"} |
663 |
658 |
664 This is different from a free variable |
659 This is different from a free variable |
665 |
660 |
666 @{ML_response_fake [display, gray] |
661 @{ML_response_fake [display, gray] |
667 "@{term \"x\"}" |
662 "writeln (Syntax.string_of_term @{context} (Free (\"x\", @{typ bool})))" |
668 "x"} |
663 "x"} |
669 |
664 |
670 When constructing terms, you are usually concerned with free variables (for example |
665 When constructing terms, you are usually concerned with free variables (for example |
671 you cannot construct schematic variables using the antiquotation @{text "@{term \<dots>}"}). |
666 you cannot construct schematic variables using the antiquotation @{text "@{term \<dots>}"}). |
672 If you deal with theorems, you have to observe the distinction. The same holds |
667 If you deal with theorems, you have to observe the distinction. A similar |
673 for types. |
668 distinction holds for types (see below). |
674 |
669 |
675 \begin{readmore} |
670 \begin{readmore} |
676 Terms and types are described in detail in \isccite{sec:terms}. Their |
671 Terms and types are described in detail in \isccite{sec:terms}. Their |
677 definition and many useful operations are implemented in @{ML_file "Pure/term.ML"}. |
672 definition and many useful operations are implemented in @{ML_file "Pure/term.ML"}. |
678 \end{readmore} |
673 \end{readmore} |
683 @{ML_response_fake_both [display,gray] |
678 @{ML_response_fake_both [display,gray] |
684 "@{term \"x x\"}" |
679 "@{term \"x x\"}" |
685 "Type unification failed: Occurs check!"} |
680 "Type unification failed: Occurs check!"} |
686 |
681 |
687 raises a typing error, while it perfectly ok to construct the term |
682 raises a typing error, while it perfectly ok to construct the term |
688 |
683 |
689 @{ML [display,gray] "Free (\"x\", @{typ nat}) $ Free (\"x\", @{typ nat})"} |
684 @{ML_response_fake [display,gray] |
|
685 "let |
|
686 val omega = Free (\"x\", @{typ nat}) $ Free (\"x\", @{typ nat}) |
|
687 in |
|
688 writeln (Syntax.string_of_term @{context} omega) |
|
689 end" |
|
690 "x x"} |
690 |
691 |
691 with the raw ML-constructors. |
692 with the raw ML-constructors. |
692 Sometimes the internal representation of terms can be surprisingly different |
693 Sometimes the internal representation of terms can be surprisingly different |
693 from what you see at the user-level, because the layers of |
694 from what you see at the user-level, because the layers of |
694 parsing/type-checking/pretty printing can be quite elaborate. |
695 parsing/type-checking/pretty printing can be quite elaborate. |
728 |
729 |
729 As already seen above, types can be constructed using the antiquotation |
730 As already seen above, types can be constructed using the antiquotation |
730 @{text "@{typ \<dots>}"}. For example: |
731 @{text "@{typ \<dots>}"}. For example: |
731 |
732 |
732 @{ML_response_fake [display,gray] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"} |
733 @{ML_response_fake [display,gray] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"} |
|
734 |
|
735 Their definition is |
|
736 *} |
|
737 |
|
738 ML_val{*datatype typ = |
|
739 Type of string * typ list |
|
740 | TFree of string * sort |
|
741 | TVar of indexname * sort *} |
|
742 |
|
743 text {* |
|
744 Like with terms, there is the distinction between free type |
|
745 variables (term-constructor @{ML "TFree"} and schematic |
|
746 type variables (term-constructor @{ML "TVar"}). A type constant, |
|
747 like @{typ "int"} or @{typ bool}, are types with an empty list |
|
748 of argument types. |
|
749 |
733 |
750 |
734 \begin{readmore} |
751 \begin{readmore} |
735 Types are described in detail in \isccite{sec:types}. Their |
752 Types are described in detail in \isccite{sec:types}. Their |
736 definition and many useful operations are implemented |
753 definition and many useful operations are implemented |
737 in @{ML_file "Pure/type.ML"}. |
754 in @{ML_file "Pure/type.ML"}. |
990 @{ML_response_fake [display,gray] |
1009 @{ML_response_fake [display,gray] |
991 "map_types nat_to_int @{term \"a = (1::nat)\"}" |
1010 "map_types nat_to_int @{term \"a = (1::nat)\"}" |
992 "Const (\"op =\", \"int \<Rightarrow> int \<Rightarrow> bool\") |
1011 "Const (\"op =\", \"int \<Rightarrow> int \<Rightarrow> bool\") |
993 $ Free (\"a\", \"int\") $ Const (\"HOL.one_class.one\", \"int\")"} |
1012 $ Free (\"a\", \"int\") $ Const (\"HOL.one_class.one\", \"int\")"} |
994 |
1013 |
995 (FIXME: a readmore about types) |
1014 If you want to obtain the list of free type-variables of a term, you |
996 |
1015 can use the function @{ML Term.add_tfrees} (similarly @{ML Term.add_tvars} |
997 (Explain @{ML Term.add_tvarsT} and @{ML Term.add_tfreesT}) |
1016 for the schematic type-variables). One would expect that such functions |
|
1017 take a term as input and return a list of types. But their type is actually |
|
1018 |
|
1019 @{text[display] "Term.term -> (string * Term.sort) list -> (string * Term.sort) list"} |
|
1020 |
|
1021 that is they take, besides a term, also a list of type-variables as input. |
|
1022 So in order to obtain the list of type-variables of a term you have to |
|
1023 call them as follows |
|
1024 |
|
1025 @{ML_response [gray,display] |
|
1026 "Term.add_tfrees @{term \"(a,b)\"} []" |
|
1027 "[(\"'b\", [\"HOL.type\"]), (\"'a\", [\"HOL.type\"])]"} |
|
1028 |
|
1029 The reason for this definition is that @{ML Term.add_tfrees} can |
|
1030 be easily folded over a list of terms. Similarly for all functions |
|
1031 named @{text "add_"}some\_name in @{ML_file "Pure/term.ML"}. |
|
1032 |
998 *} |
1033 *} |
999 |
1034 |
1000 |
1035 |
1001 section {* Type-Checking *} |
1036 section {* Type-Checking *} |
1002 |
1037 |