19 |
19 |
20 @{text [display] "pred \<equiv> \<lambda>zs. \<forall>preds. orules \<longrightarrow> pred zs"} |
20 @{text [display] "pred \<equiv> \<lambda>zs. \<forall>preds. orules \<longrightarrow> pred zs"} |
21 |
21 |
22 and then ``register'' the definition inside a local theory. |
22 and then ``register'' the definition inside a local theory. |
23 To do the latter, we use the following wrapper for the function |
23 To do the latter, we use the following wrapper for the function |
24 @{ML [index] define in LocalTheory}. The wrapper takes a predicate name, a syntax |
24 @{ML_ind [index] define in LocalTheory}. The wrapper takes a predicate name, a syntax |
25 annotation and a term representing the right-hand side of the definition. |
25 annotation and a term representing the right-hand side of the definition. |
26 *} |
26 *} |
27 |
27 |
28 ML %linenosgray{*fun make_defn ((predname, mx), trm) lthy = |
28 ML %linenosgray{*fun make_defn ((predname, mx), trm) lthy = |
29 let |
29 let |
33 (thm, lthy') |
33 (thm, lthy') |
34 end*} |
34 end*} |
35 |
35 |
36 text {* |
36 text {* |
37 It returns the definition (as a theorem) and the local theory in which the |
37 It returns the definition (as a theorem) and the local theory in which the |
38 definition has been made. In Line 4, @{ML [index] internalK in Thm} is a flag |
38 definition has been made. In Line 4, @{ML_ind [index] internalK in Thm} is a flag |
39 attached to the theorem (other possibile flags are @{ML [index] definitionK in Thm} |
39 attached to the theorem (other possibile flags are @{ML_ind [index] definitionK in Thm} |
40 and @{ML [index] axiomK in Thm}). These flags just classify theorems and have no |
40 and @{ML_ind [index] axiomK in Thm}). These flags just classify theorems and have no |
41 significant meaning, except for tools that, for example, find theorems in |
41 significant meaning, except for tools that, for example, find theorems in |
42 the theorem database.\footnote{FIXME: put in the section about theorems.} We |
42 the theorem database.\footnote{FIXME: put in the section about theorems.} We |
43 also use @{ML [index] empty_binding in Attrib} in Line 3, since the definitions for |
43 also use @{ML_ind [index] empty_binding in Attrib} in Line 3, since the definitions for |
44 our inductive predicates are not meant to be seen by the user and therefore |
44 our inductive predicates are not meant to be seen by the user and therefore |
45 do not need to have any theorem attributes. A testcase for this function is |
45 do not need to have any theorem attributes. A testcase for this function is |
46 *} |
46 *} |
47 |
47 |
48 local_setup %gray {* fn lthy => |
48 local_setup %gray {* fn lthy => |
171 text {* |
171 text {* |
172 The user will state the introduction rules using meta-implications and |
172 The user will state the introduction rules using meta-implications and |
173 meta-quanti\-fications. In Line 4, we transform these introduction rules |
173 meta-quanti\-fications. In Line 4, we transform these introduction rules |
174 into the object logic (since definitions cannot be stated with |
174 into the object logic (since definitions cannot be stated with |
175 meta-connectives). To do this transformation we have to obtain the theory |
175 meta-connectives). To do this transformation we have to obtain the theory |
176 behind the local theory using the function @{ML [index] theory_of in ProofContext} |
176 behind the local theory using the function @{ML_ind [index] theory_of in ProofContext} |
177 (Line 3); with this theory we can use the function |
177 (Line 3); with this theory we can use the function |
178 @{ML [index] atomize_term in ObjectLogic} to make the transformation (Line 4). The call |
178 @{ML_ind [index] atomize_term in ObjectLogic} to make the transformation (Line 4). The call |
179 to @{ML defn_aux} in Line 5 produces all right-hand sides of the |
179 to @{ML defn_aux} in Line 5 produces all right-hand sides of the |
180 definitions. The actual definitions are then made in Line 7. The result of |
180 definitions. The actual definitions are then made in Line 7. The result of |
181 the function is a list of theorems and a local theory (the theorems are |
181 the function is a list of theorems and a local theory (the theorems are |
182 registered with the local theory). A testcase for this function is |
182 registered with the local theory). A testcase for this function is |
183 *} |
183 *} |
377 case that no introduction rules are given, the conclusion of this |
377 case that no introduction rules are given, the conclusion of this |
378 implication needs to be wrapped inside a @{term Trueprop}, otherwise |
378 implication needs to be wrapped inside a @{term Trueprop}, otherwise |
379 the Isabelle's goal mechanism will fail.\footnote{FIXME: check with |
379 the Isabelle's goal mechanism will fail.\footnote{FIXME: check with |
380 Stefan...is this so?} |
380 Stefan...is this so?} |
381 |
381 |
382 In Line 11 we set up the goal to be proved using the function @{ML [index] |
382 In Line 11 we set up the goal to be proved using the function @{ML_ind [index] |
383 prove in Goal}; in the next line we call the tactic for proving the |
383 prove in Goal}; in the next line we call the tactic for proving the |
384 induction principle. As mentioned before, this tactic expects the |
384 induction principle. As mentioned before, this tactic expects the |
385 definitions, the premise and the (certified) predicates with which the |
385 definitions, the premise and the (certified) predicates with which the |
386 introduction rules have been substituted. The code in these two lines will |
386 introduction rules have been substituted. The code in these two lines will |
387 return a theorem. However, it is a theorem proved inside the local theory |
387 return a theorem. However, it is a theorem proved inside the local theory |
445 the new local theory @{text "lthy'"}. From the local theory we extract |
445 the new local theory @{text "lthy'"}. From the local theory we extract |
446 the ambient theory in Line 6. We need this theory in order to certify |
446 the ambient theory in Line 6. We need this theory in order to certify |
447 the new predicates. In Line 8, we construct the types of these new predicates |
447 the new predicates. In Line 8, we construct the types of these new predicates |
448 using the given argument types. Next we turn them into terms and subsequently |
448 using the given argument types. Next we turn them into terms and subsequently |
449 certify them (Line 9 and 10). We can now produce the substituted introduction rules |
449 certify them (Line 9 and 10). We can now produce the substituted introduction rules |
450 (Line 11) using the function @{ML [index] subst_free}. Line 14 and 15 just iterate |
450 (Line 11) using the function @{ML_ind [index] subst_free}. Line 14 and 15 just iterate |
451 the proofs for all predicates. |
451 the proofs for all predicates. |
452 From this we obtain a list of theorems. Finally we need to export the |
452 From this we obtain a list of theorems. Finally we need to export the |
453 fixed variables @{text "Ps"} to obtain the schematic variables @{text "?Ps"} |
453 fixed variables @{text "Ps"} to obtain the schematic variables @{text "?Ps"} |
454 (Line 16). |
454 (Line 16). |
455 |
455 |
591 first two) and assumptions from the definition of the predicate (assumption |
591 first two) and assumptions from the definition of the predicate (assumption |
592 three to six). We need to treat these parameters and assumptions |
592 three to six). We need to treat these parameters and assumptions |
593 differently. In the code below we will therefore separate them into @{text |
593 differently. In the code below we will therefore separate them into @{text |
594 "params1"} and @{text params2}, respectively @{text "prems1"} and @{text |
594 "params1"} and @{text params2}, respectively @{text "prems1"} and @{text |
595 "prems2"}. To do this separation, it is best to open a subproof with the |
595 "prems2"}. To do this separation, it is best to open a subproof with the |
596 tactic @{ML [index] SUBPROOF}, since this tactic provides us with the parameters (as |
596 tactic @{ML_ind [index] SUBPROOF}, since this tactic provides us with the parameters (as |
597 list of @{ML_type cterm}s) and the assumptions (as list of @{ML_type thm}s). |
597 list of @{ML_type cterm}s) and the assumptions (as list of @{ML_type thm}s). |
598 The problem with @{ML SUBPROOF}, however, is that it always expects us to |
598 The problem with @{ML SUBPROOF}, however, is that it always expects us to |
599 completely discharge the goal (see Section~\ref{sec:simpletacs}). This is |
599 completely discharge the goal (see Section~\ref{sec:simpletacs}). This is |
600 a bit inconvenient for our gradual explanation of the proof here. Therefore |
600 a bit inconvenient for our gradual explanation of the proof here. Therefore |
601 we use first the function @{ML [index] FOCUS in Subgoal}, which does s |
601 we use first the function @{ML_ind [index] FOCUS in Subgoal}, which does s |
602 ame as @{ML SUBPROOF} |
602 ame as @{ML SUBPROOF} |
603 but does not require us to completely discharge the goal. |
603 but does not require us to completely discharge the goal. |
604 *} |
604 *} |
605 (*<*)oops(*>*) |
605 (*<*)oops(*>*) |
606 text_raw {* |
606 text_raw {* |
630 First we calculate the values for @{text "params1/2"} and @{text "prems1/2"} |
630 First we calculate the values for @{text "params1/2"} and @{text "prems1/2"} |
631 from @{text "params"} and @{text "prems"}, respectively. To better see what is |
631 from @{text "params"} and @{text "prems"}, respectively. To better see what is |
632 going in our example, we will print out these values using the printing |
632 going in our example, we will print out these values using the printing |
633 function in Figure~\ref{fig:chopprint}. Since @{ML FOCUS in Subgoal} will |
633 function in Figure~\ref{fig:chopprint}. Since @{ML FOCUS in Subgoal} will |
634 supply us the @{text "params"} and @{text "prems"} as lists, we can |
634 supply us the @{text "params"} and @{text "prems"} as lists, we can |
635 separate them using the function @{ML [index] chop}. |
635 separate them using the function @{ML_ind [index] chop}. |
636 *} |
636 *} |
637 |
637 |
638 ML %linenosgray{*fun chop_test_tac preds rules = |
638 ML %linenosgray{*fun chop_test_tac preds rules = |
639 Subgoal.FOCUS (fn {params, prems, context, ...} => |
639 Subgoal.FOCUS (fn {params, prems, context, ...} => |
640 let |
640 let |
697 |
697 |
698 @{term [display] "\<forall>a b t. a \<noteq> b \<longrightarrow> fresh a t \<longrightarrow> fresh a (Lam a t)"} |
698 @{term [display] "\<forall>a b t. a \<noteq> b \<longrightarrow> fresh a t \<longrightarrow> fresh a (Lam a t)"} |
699 |
699 |
700 To use this premise with @{ML rtac}, we need to instantiate its |
700 To use this premise with @{ML rtac}, we need to instantiate its |
701 quantifiers (with @{text params1}) and transform it into rule |
701 quantifiers (with @{text params1}) and transform it into rule |
702 format (using @{ML [index] rulify in ObjectLogic}). So we can modify the |
702 format (using @{ML_ind [index] rulify in ObjectLogic}). So we can modify the |
703 code as follows: |
703 code as follows: |
704 *} |
704 *} |
705 |
705 |
706 ML %linenosgray{*fun apply_prem_tac i preds rules = |
706 ML %linenosgray{*fun apply_prem_tac i preds rules = |
707 Subgoal.FOCUS (fn {params, prems, context, ...} => |
707 Subgoal.FOCUS (fn {params, prems, context, ...} => |
861 |
861 |
862 text {* |
862 text {* |
863 In Line 4 we use the @{text prems} from the @{ML SUBPROOF} and resolve |
863 In Line 4 we use the @{text prems} from the @{ML SUBPROOF} and resolve |
864 them with @{text prem}. In the simple cases, that is where the @{text prem} |
864 them with @{text prem}. In the simple cases, that is where the @{text prem} |
865 comes from a non-recursive premise of the rule, @{text prems} will be |
865 comes from a non-recursive premise of the rule, @{text prems} will be |
866 just the empty list and the function @{ML [index] MRS} does nothing. Similarly, in the |
866 just the empty list and the function @{ML_ind [index] MRS} does nothing. Similarly, in the |
867 cases where the recursive premises of the rule do not have preconditions. |
867 cases where the recursive premises of the rule do not have preconditions. |
868 In case there are preconditions, then Line 4 discharges them. After |
868 In case there are preconditions, then Line 4 discharges them. After |
869 that we can proceed as before, i.e., check whether the outermost |
869 that we can proceed as before, i.e., check whether the outermost |
870 connective is @{text "\<forall>"}. |
870 connective is @{text "\<forall>"}. |
871 |
871 |
940 in |
940 in |
941 map_index intros_aux rules |
941 map_index intros_aux rules |
942 end*} |
942 end*} |
943 |
943 |
944 text {* |
944 text {* |
945 The iteration is done with the function @{ML [index] map_index} since we |
945 The iteration is done with the function @{ML_ind [index] map_index} since we |
946 need the introduction rule together with its number (counted from |
946 need the introduction rule together with its number (counted from |
947 @{text 0}). This completes the code for the functions deriving the |
947 @{text 0}). This completes the code for the functions deriving the |
948 reasoning infrastructure. It remains to implement some administrative |
948 reasoning infrastructure. It remains to implement some administrative |
949 code that strings everything together. |
949 code that strings everything together. |
950 *} |
950 *} |
953 |
953 |
954 text {* |
954 text {* |
955 We have produced various theorems (definitions, induction principles and |
955 We have produced various theorems (definitions, induction principles and |
956 introduction rules), but apart from the definitions, we have not yet |
956 introduction rules), but apart from the definitions, we have not yet |
957 registered them with the theorem database. This is what the functions |
957 registered them with the theorem database. This is what the functions |
958 @{ML [index] note in LocalTheory} does. |
958 @{ML_ind [index] note in LocalTheory} does. |
959 |
959 |
960 |
960 |
961 For convenience, we use the following |
961 For convenience, we use the following |
962 three wrappers this function: |
962 three wrappers this function: |
963 *} |
963 *} |
1035 @{text "mut_name.inducts"}, respectively (see previous paragraph). |
1035 @{text "mut_name.inducts"}, respectively (see previous paragraph). |
1036 |
1036 |
1037 Line 20 add further every introduction rule under its own name |
1037 Line 20 add further every introduction rule under its own name |
1038 (given by the user).\footnote{FIXME: what happens if the user did not give |
1038 (given by the user).\footnote{FIXME: what happens if the user did not give |
1039 any name.} Line 21 registers the induction principles. For this we have |
1039 any name.} Line 21 registers the induction principles. For this we have |
1040 to use some specific attributes. The first @{ML [index] case_names in RuleCases} |
1040 to use some specific attributes. The first @{ML_ind [index] case_names in RuleCases} |
1041 corresponds to the case names that are used by Isar to reference the proof |
1041 corresponds to the case names that are used by Isar to reference the proof |
1042 obligations in the induction. The second @{ML "consumes 1" in RuleCases} |
1042 obligations in the induction. The second @{ML "consumes 1" in RuleCases} |
1043 indicates that the first premise of the induction principle (namely |
1043 indicates that the first premise of the induction principle (namely |
1044 the predicate over which the induction proceeds) is eliminated. |
1044 the predicate over which the induction proceeds) is eliminated. |
1045 |
1045 |