493 To see what these functions do, let us suppose we have the following three |
493 To see what these functions do, let us suppose we have the following three |
494 theorems. |
494 theorems. |
495 *} |
495 *} |
496 |
496 |
497 lemma all_elims_test: |
497 lemma all_elims_test: |
498 fixes P::"nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool" |
498 fixes P::"nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool" |
499 shows "\<forall>x y z. P x y z" sorry |
499 shows "\<forall>x y z. P x y z" sorry |
500 |
500 |
501 lemma imp_elims_test: |
501 lemma imp_elims_test: |
502 shows "A \<longrightarrow> B \<longrightarrow> C" sorry |
502 shows "A \<longrightarrow> B \<longrightarrow> C" sorry |
503 |
503 |
504 lemma imp_elims_test': |
504 lemma imp_elims_test': |
505 shows "A" "B" sorry |
505 shows "A" "B" sorry |
506 |
506 |
507 text {* |
507 text {* |
508 The function @{ML all_elims} takes a list of (certified) terms and instantiates |
508 The function @{ML all_elims} takes a list of (certified) terms and instantiates |
509 theorems of the form @{thm [source] all_elims_test}. For example we can instantiate |
509 theorems of the form @{thm [source] all_elims_test}. For example we can instantiate |
510 the quantifiers in this theorem with @{term a}, @{term b} and @{term c} as follows: |
510 the quantifiers in this theorem with @{term a}, @{term b} and @{term c} as follows: |
899 Lines 2 to 4 in this tactic correspond to the function @{ML expand_tac}. |
899 Lines 2 to 4 in this tactic correspond to the function @{ML expand_tac}. |
900 Some testcases for this tactic are: |
900 Some testcases for this tactic are: |
901 *} |
901 *} |
902 |
902 |
903 lemma even0_intro: |
903 lemma even0_intro: |
904 shows "even 0" |
904 shows "even 0" |
905 by (tactic {* intro_tac eo_defs eo_rules eo_preds 0 @{context} *}) |
905 by (tactic {* intro_tac eo_defs eo_rules eo_preds 0 @{context} *}) |
906 |
906 |
907 lemma evenS_intro: |
907 lemma evenS_intro: |
908 shows "\<And>m. odd m \<Longrightarrow> even (Suc m)" |
908 shows "\<And>m. odd m \<Longrightarrow> even (Suc m)" |
909 by (tactic {* intro_tac eo_defs eo_rules eo_preds 1 @{context} *}) |
909 by (tactic {* intro_tac eo_defs eo_rules eo_preds 1 @{context} *}) |
910 |
910 |
911 lemma fresh_App: |
911 lemma fresh_App: |
912 shows "\<And>a t s. \<lbrakk>fresh a t; fresh a s\<rbrakk> \<Longrightarrow> fresh a (App t s)" |
912 shows "\<And>a t s. \<lbrakk>fresh a t; fresh a s\<rbrakk> \<Longrightarrow> fresh a (App t s)" |
913 by (tactic {* |
913 by (tactic {* |
914 intro_tac @{thms fresh_def} fresh_rules [fresh_pred] 1 @{context} *}) |
914 intro_tac @{thms fresh_def} fresh_rules [fresh_pred] 1 @{context} *}) |
915 |
915 |
916 text {* |
916 text {* |
917 The second function sets up in Line 4 the goals to be proved (this is easy |
917 The second function sets up in Line 4 the goals to be proved (this is easy |
1026 corresponds to the case names that are used by Isar to reference the proof |
1026 corresponds to the case names that are used by Isar to reference the proof |
1027 obligations in the induction. The second @{ML "consumes 1" in RuleCases} |
1027 obligations in the induction. The second @{ML "consumes 1" in RuleCases} |
1028 indicates that the first premise of the induction principle (namely |
1028 indicates that the first premise of the induction principle (namely |
1029 the predicate over which the induction proceeds) is eliminated. |
1029 the predicate over which the induction proceeds) is eliminated. |
1030 |
1030 |
1031 (FIXME: What does @{ML Induct.induct_pred} do?) |
|
1032 |
|
1033 (FIXME: why the mut-name?) |
|
1034 |
|
1035 (FIXME: What does @{ML Binding.qualify} do?) |
|
1036 |
|
1037 |
|
1038 This completes all the code and fits in with the ``front end'' described |
1031 This completes all the code and fits in with the ``front end'' described |
1039 in Section \ref{sec:interface} |
1032 in Section~\ref{sec:interface}.\footnote{FIXME: Describe @{ML Induct.induct_pred}. Why the mut-name? |
1040 *} |
1033 What does @{ML Binding.qualify} do?} |
1041 |
1034 *} |
1042 |
|
1043 ML{*fun add_inductive_cmd pred_specs rule_specs lthy = |
|
1044 let |
|
1045 val ((pred_specs', rule_specs'), _) = |
|
1046 Specification.read_spec pred_specs rule_specs lthy |
|
1047 in |
|
1048 add_inductive pred_specs' rule_specs' lthy |
|
1049 end*} |
|
1050 |
|
1051 ML{*val spec_parser = |
|
1052 OuterParse.fixes -- |
|
1053 Scan.optional |
|
1054 (OuterParse.$$$ "where" |-- |
|
1055 OuterParse.!!! |
|
1056 (OuterParse.enum1 "|" |
|
1057 (SpecParse.opt_thm_name ":" -- OuterParse.prop))) []*} |
|
1058 |
|
1059 ML{*val specification = |
|
1060 spec_parser >> |
|
1061 (fn (pred_specs, rule_specs) => add_inductive_cmd pred_specs rule_specs)*} |
|
1062 |
|
1063 ML{*val _ = OuterSyntax.local_theory "simple_inductive" |
|
1064 "define inductive predicates" |
|
1065 OuterKeyword.thy_decl specification*} |
|
1066 |
|
1067 |
|
1068 section {* Extensions (TBD) *} |
|
1069 |
|
1070 text {* |
|
1071 Things to include at the end: |
|
1072 |
|
1073 \begin{itemize} |
|
1074 \item include the code for the parameters |
|
1075 \item say something about add-inductive-i to return |
|
1076 the rules |
|
1077 \item say that the induction principle is weaker (weaker than |
|
1078 what the standard inductive package generates) |
|
1079 \item say that no conformity test is done |
|
1080 \item exercise about strong induction principles |
|
1081 \item exercise about the test for the intro rules |
|
1082 \end{itemize} |
|
1083 |
|
1084 *} |
|
1085 |
|
1086 (* |
|
1087 simple_inductive |
|
1088 Even and Odd |
|
1089 where |
|
1090 Even0: "Even 0" |
|
1091 | EvenS: "Odd n \<Longrightarrow> Even (Suc n)" |
|
1092 | OddS: "Even n \<Longrightarrow> Odd (Suc n)" |
|
1093 |
|
1094 thm Even0 |
|
1095 thm EvenS |
|
1096 thm OddS |
|
1097 |
|
1098 thm Even_Odd.intros |
|
1099 thm Even.induct |
|
1100 thm Odd.induct |
|
1101 |
|
1102 thm Even_def |
|
1103 thm Odd_def |
|
1104 *) |
|
1105 |
|
1106 (* |
|
1107 text {* |
|
1108 Second, we want that the user can specify fixed parameters. |
|
1109 Remember in the previous section we stated that the user can give the |
|
1110 specification for the transitive closure of a relation @{text R} as |
|
1111 *} |
|
1112 *) |
|
1113 |
|
1114 (* |
|
1115 simple_inductive |
|
1116 trcl\<iota>\<iota> :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool" |
|
1117 where |
|
1118 base: "trcl\<iota>\<iota> R x x" |
|
1119 | step: "trcl\<iota>\<iota> R x y \<Longrightarrow> R y z \<Longrightarrow> trcl\<iota>\<iota> R x z" |
|
1120 *) |
|
1121 |
|
1122 (* |
|
1123 text {* |
|
1124 Note that there is no locale given in this specification---the parameter |
|
1125 @{text "R"} therefore needs to be included explicitly in @{term trcl\<iota>\<iota>}, but |
|
1126 stays fixed throughout the specification. The problem with this way of |
|
1127 stating the specification for the transitive closure is that it derives the |
|
1128 following induction principle. |
|
1129 |
|
1130 \begin{center}\small |
|
1131 \mprset{flushleft} |
|
1132 \mbox{\inferrule{ |
|
1133 @{thm_style prem1 trcl\<iota>\<iota>.induct[where P=P, where z=R, where za=x, where zb=y]}\\\\ |
|
1134 @{thm_style prem2 trcl\<iota>\<iota>.induct[where P=P, where z=R, where za=x, where zb=y]}\\\\ |
|
1135 @{thm_style prem3 trcl\<iota>\<iota>.induct[where P=P, where z=R, where za=x, where zb=y]}} |
|
1136 {@{thm_style concl trcl\<iota>\<iota>.induct[where P=P, where z=R, where za=x, where zb=y]}}} |
|
1137 \end{center} |
|
1138 |
|
1139 But this does not correspond to the induction principle we derived by hand, which |
|
1140 was |
|
1141 |
|
1142 |
|
1143 %\begin{center}\small |
|
1144 %\mprset{flushleft} |
|
1145 %\mbox{\inferrule{ |
|
1146 % @ { thm_style prem1 trcl_induct[no_vars]}\\\\ |
|
1147 % @ { thm_style prem2 trcl_induct[no_vars]}\\\\ |
|
1148 % @ { thm_style prem3 trcl_induct[no_vars]}} |
|
1149 % {@ { thm_style concl trcl_induct[no_vars]}}} |
|
1150 %\end{center} |
|
1151 |
|
1152 The difference is that in the one derived by hand the relation @{term R} is not |
|
1153 a parameter of the proposition @{term P} to be proved and it is also not universally |
|
1154 qunatified in the second and third premise. The point is that the parameter @{term R} |
|
1155 stays fixed thoughout the definition and we do not want to regard it as an ``ordinary'' |
|
1156 argument of the transitive closure, but one that can be freely instantiated. |
|
1157 In order to recognise such parameters, we have to extend the specification |
|
1158 to include a mechanism to state fixed parameters. The user should be able |
|
1159 to write |
|
1160 |
|
1161 *} |
|
1162 *) |
|
1163 (* |
|
1164 simple_inductive |
|
1165 trcl'' for R :: "'a \<Rightarrow> 'a \<Rightarrow> bool" |
|
1166 where |
|
1167 base: "trcl'' R x x" |
|
1168 | step: "trcl'' R x y \<Longrightarrow> R y z \<Longrightarrow> trcl'' R x z" |
|
1169 |
|
1170 simple_inductive |
|
1171 accpart'' for R :: "'a \<Rightarrow> 'a \<Rightarrow> bool" |
|
1172 where |
|
1173 accpartI: "(\<And>y. R y x \<Longrightarrow> accpart'' R y) \<Longrightarrow> accpart'' R x" |
|
1174 *) |
|
1175 (*<*)end(*>*) |
1035 (*<*)end(*>*) |