CookBook/Tactical.thy
changeset 162 3fb9f820a294
parent 161 83f36a1c62f2
child 163 2319cff107f0
equal deleted inserted replaced
161:83f36a1c62f2 162:3fb9f820a294
     1 theory Tactical
     1 theory Tactical
     2 imports Base FirstSteps
     2 imports Base FirstSteps
     3 begin
     3 begin
     4 
       
     5 
     4 
     6 chapter {* Tactical Reasoning\label{chp:tactical} *}
     5 chapter {* Tactical Reasoning\label{chp:tactical} *}
     7 
     6 
     8 text {*
     7 text {*
     9   The main reason for descending to the ML-level of Isabelle is to be able to
     8   The main reason for descending to the ML-level of Isabelle is to be able to
    64   \begin{readmore}
    63   \begin{readmore}
    65   To learn more about the function @{ML Goal.prove} see \isccite{sec:results}
    64   To learn more about the function @{ML Goal.prove} see \isccite{sec:results}
    66   and the file @{ML_file "Pure/goal.ML"}.  See @{ML_file
    65   and the file @{ML_file "Pure/goal.ML"}.  See @{ML_file
    67   "Pure/tactic.ML"} and @{ML_file "Pure/tctical.ML"} for the code of basic
    66   "Pure/tactic.ML"} and @{ML_file "Pure/tctical.ML"} for the code of basic
    68   tactics and tactic combinators; see also Chapters 3 and 4 in the old
    67   tactics and tactic combinators; see also Chapters 3 and 4 in the old
    69   Isabelle Reference Manual.
    68   Isabelle Reference Manual, and Chapter 3 in the Isabelle/Isar Implementation Manual. 
    70   \end{readmore}
    69   \end{readmore}
    71 
    70 
    72   Note that in the code above we use antiquotations for referencing the theorems. Many theorems
    71   Note that in the code above we use antiquotations for referencing the theorems. Many theorems
    73   also have ML-bindings with the same name. Therefore, we could also just have
    72   also have ML-bindings with the same name. Therefore, we could also just have
    74   written @{ML "etac disjE 1"}, or in case where there are no ML-binding obtain
    73   written @{ML "etac disjE 1"}, or in case where there are no ML-binding obtain
  1009 
  1008 
  1010 section {* Simplifier Tactics *}
  1009 section {* Simplifier Tactics *}
  1011 
  1010 
  1012 text {*
  1011 text {*
  1013   A lot of convenience in the reasoning with Isabelle derives from its
  1012   A lot of convenience in the reasoning with Isabelle derives from its
  1014   powerful simplifier. The power of simplifier is at the same time a
  1013   powerful simplifier. The power of simplifier is a strength and a weakness at
  1015   strength and a weakness, because you can easily make the simplifier to
  1014   the same time, because you can easily make the simplifier to run into a  loop and its
  1016   loop and its behaviour can sometimes be difficult to predict. There is also
  1015   behaviour can be difficult to predict. There is also a multitude
  1017   a multitude of options that configurate the behaviour of the simplifier. We
  1016   of options that you can configurate to control the behaviour of the simplifier. 
  1018   describe some of them in this and the next section.
  1017   We describe some of them in this and the next section.
  1019 
  1018 
  1020   There are the following five main tactics behind 
  1019   There are the following five main tactics behind 
  1021   the simplifier (in parentheses is their user-level counterparts):
  1020   the simplifier (in parentheses is their user-level counterpart):
  1022 
  1021 
  1023   \begin{isabelle}
  1022   \begin{isabelle}
  1024   \begin{center}
  1023   \begin{center}
  1025   \begin{tabular}{l@ {\hspace{2cm}}l}
  1024   \begin{tabular}{l@ {\hspace{2cm}}l}
  1026    @{ML simp_tac}            & @{text "(simp (no_asm))"} \\
  1025    @{ML simp_tac}            & @{text "(simp (no_asm))"} \\
  1030    @{ML asm_full_simp_tac}   & @{text "(simp)"}
  1029    @{ML asm_full_simp_tac}   & @{text "(simp)"}
  1031   \end{tabular}
  1030   \end{tabular}
  1032   \end{center}
  1031   \end{center}
  1033   \end{isabelle}
  1032   \end{isabelle}
  1034 
  1033 
  1035   All of them take a simpset and an interger as argument (the latter to specify the goal 
  1034   All of the tactics take a simpset and an interger as argument (the latter as usual 
  1036   to be analysed). So the proof
  1035   to specify  the goal to be analysed). So the proof
  1037 *}
  1036 *}
  1038 
  1037 
  1039 lemma "Suc (1 + 2) < 3 + 2"
  1038 lemma "Suc (1 + 2) < 3 + 2"
  1040 apply(simp)
  1039 apply(simp)
  1041 done
  1040 done
  1047 lemma "Suc (1 + 2) < 3 + 2"
  1046 lemma "Suc (1 + 2) < 3 + 2"
  1048 apply(tactic {* asm_full_simp_tac @{simpset} 1 *})
  1047 apply(tactic {* asm_full_simp_tac @{simpset} 1 *})
  1049 done
  1048 done
  1050 
  1049 
  1051 text {*
  1050 text {*
  1052   If the simplifier cannot make any progress, then it leaves the goal unchanged
  1051   If the simplifier cannot make any progress, then it leaves the goal unchanged,
  1053   and does not raise any error message. That means if you use it to unfold a definition
  1052   i.e.~does not raise any error message. That means if you use it to unfold a 
  1054   for a constant and this constant is not present in a goal state, you can still
  1053   definition for a constant and this constant is not present in the goal state, 
  1055   safely apply the simplifier.
  1054   you can still safely apply the simplifier.
  1056 
  1055 
  1057   When using the simplifier, the crucial information you have to control is
  1056   When using the simplifier, the crucial information you have to provide is
  1058   the simpset. If not handled with care, then the simplifier can easily run
  1057   the simpset. If this information is not handled with care, then the
  1059   into a loop. It might be surprising that a simpset is more complex than just a
  1058   simplifier can easily run into a loop. Therefore a good rule of thumb is to
  1060   simple collection of theorems used as simplification rules. One reason for
  1059   use simpsets that are as minimal as possible. It might be surprising that a
  1061   the complexity is that the simplifier must be able to rewrite inside terms
  1060   simpset is more complex than just a simple collection of theorems used as
  1062   and should also be able to rewrite according to rules that have
  1061   simplification rules. One reason for the complexity is that the simplifier
  1063   precoditions.
  1062   must be able to rewrite inside terms and should also be able to rewrite
       
  1063   according to rules that have precoditions.
  1064 
  1064 
  1065 
  1065 
  1066   The rewriting inside terms requires congruence rules, which
  1066   The rewriting inside terms requires congruence rules, which
  1067   are meta-equalities typical of the form
  1067   are meta-equalities typical of the form
  1068 
  1068 
  1069   \begin{isabelle}
  1069   \begin{isabelle}
  1070   \begin{center}
  1070   \begin{center}
  1071   \mbox{\inferrule{@{text "t\<^isub>i \<equiv> s\<^isub>i"}}
  1071   \mbox{\inferrule{@{text "t\<^isub>1 \<equiv> s\<^isub>1 \<dots> t\<^isub>n \<equiv> s\<^isub>n"}}
  1072                   {@{text "constr t\<^isub>1\<dots>t\<^isub>n \<equiv> constr s\<^isub>1\<dots>s\<^isub>n"}}}
  1072                   {@{text "constr t\<^isub>1\<dots>t\<^isub>n \<equiv> constr s\<^isub>1\<dots>s\<^isub>n"}}}
  1073   \end{center}
  1073   \end{center}
  1074   \end{isabelle}
  1074   \end{isabelle}
  1075 
  1075 
  1076   with @{text "constr"} being a term-constructor. Every simpset contains only
  1076   with @{text "constr"} being a term-constructor, like @{const "If"} or @{const "Let"}. 
       
  1077   Every simpset contains only
  1077   one concruence rule for each term-constructor, which however can be
  1078   one concruence rule for each term-constructor, which however can be
  1078   overwritten. The user can declare lemmas to be congruence rules using the
  1079   overwritten. The user can declare lemmas to be congruence rules using the
  1079   attribute @{text "[cong]"}. In HOL, the user usually states these lemmas as
  1080   attribute @{text "[cong]"}. In HOL, the user usually states these lemmas as
  1080   equations, which are then internally transformed into meta-equations.
  1081   equations, which are then internally transformed into meta-equations.
  1081 
  1082 
  1082 
  1083 
  1083   The rewriting with rules involving preconditions requires what is in
  1084   The rewriting with rules involving preconditions requires what is in
  1084   Isabelle called a subgoaler, a solver and a looper. These can be arbitrary
  1085   Isabelle called a subgoaler, a solver and a looper. These can be arbitrary
  1085   tactics that can be installed in a simpset. However, simpsets also include
  1086   tactics that can be installed in a simpset and which are called during
       
  1087   various stages during simplification. However, simpsets also include
  1086   simprocs, which can produce rewrite rules on demand (see next
  1088   simprocs, which can produce rewrite rules on demand (see next
  1087   section). Another component are split-rules, which can simplify for example
  1089   section). Another component are split-rules, which can simplify for example
  1088   the ``then'' and ``else'' branches of if-statements under the corresponding
  1090   the ``then'' and ``else'' branches of if-statements under the corresponding
  1089   precoditions.
  1091   precoditions.
       
  1092 
  1090 
  1093 
  1091   \begin{readmore}
  1094   \begin{readmore}
  1092   For more information about the simplifier see @{ML_file "Pure/meta_simplifier.ML"}
  1095   For more information about the simplifier see @{ML_file "Pure/meta_simplifier.ML"}
  1093   and @{ML_file "Pure/simplifier.ML"}. The simplifier for HOL is set up in 
  1096   and @{ML_file "Pure/simplifier.ML"}. The simplifier for HOL is set up in 
  1094   @{ML_file "HOL/Tools/simpdata.ML"}. Generic splitters are implemented in 
  1097   @{ML_file "HOL/Tools/simpdata.ML"}. Generic splitters are implemented in 
  1160 \end{figure} *}
  1163 \end{figure} *}
  1161 
  1164 
  1162 text {* 
  1165 text {* 
  1163   To see how they work, consider the two functions in Figure~\ref{fig:prettyss}, which
  1166   To see how they work, consider the two functions in Figure~\ref{fig:prettyss}, which
  1164   print out some parts of a simpset. If you use them to print out the components of the
  1167   print out some parts of a simpset. If you use them to print out the components of the
  1165   empty simpset, the most primitive simpset
  1168   empty simpset, in ML @{ML empty_ss} and the most primitive simpset
  1166   
  1169   
  1167   @{ML_response_fake [display,gray]
  1170   @{ML_response_fake [display,gray]
  1168   "print_parts @{context} empty_ss"
  1171   "print_parts @{context} empty_ss"
  1169 "Simplification rules:
  1172 "Simplification rules:
  1170 Congruences rules:"}
  1173 Congruences rules:"}
  1175 *}
  1178 *}
  1176 
  1179 
  1177 ML{*val ss1 = empty_ss addsimps [@{thm Diff_Int} RS @{thm eq_reflection}] *}
  1180 ML{*val ss1 = empty_ss addsimps [@{thm Diff_Int} RS @{thm eq_reflection}] *}
  1178 
  1181 
  1179 text {*
  1182 text {*
  1180   Printing out the components of this simpset gives:
  1183   Printing then out the components of the simpset gives:
  1181 
  1184 
  1182   @{ML_response_fake [display,gray]
  1185   @{ML_response_fake [display,gray]
  1183   "print_parts @{context} ss1"
  1186   "print_parts @{context} ss1"
  1184 "Simplification rules:
  1187 "Simplification rules:
  1185   ??.unknown: A - B \<inter> C \<equiv> A - B \<union> (A - C)
  1188   ??.unknown: A - B \<inter> C \<equiv> A - B \<union> (A - C)
  1186 Congruences rules:"}
  1189 Congruences rules:"}
  1187 
  1190 
  1188   (FIXME: Why does it print out ??.unknown)
  1191   (FIXME: Why does it print out ??.unknown)
  1189 
  1192 
  1190   Adding the congruence rule @{thm [source] UN_cong} 
  1193   Adding also the congruence rule @{thm [source] UN_cong} 
  1191 *}
  1194 *}
  1192 
  1195 
  1193 ML{*val ss2 = ss1 addcongs [@{thm UN_cong} RS @{thm eq_reflection}] *}
  1196 ML{*val ss2 = ss1 addcongs [@{thm UN_cong} RS @{thm eq_reflection}] *}
  1194 
  1197 
  1195 text {*
  1198 text {*
  1202 Congruences rules:
  1205 Congruences rules:
  1203   UNION: \<lbrakk>A = B; \<And>x. x \<in> B \<Longrightarrow> C x = D x\<rbrakk> \<Longrightarrow> \<Union>x\<in>A. C x \<equiv> \<Union>x\<in>B. D x"}
  1206   UNION: \<lbrakk>A = B; \<And>x. x \<in> B \<Longrightarrow> C x = D x\<rbrakk> \<Longrightarrow> \<Union>x\<in>A. C x \<equiv> \<Union>x\<in>B. D x"}
  1204 
  1207 
  1205   Notice that we had to add these lemmas as meta-equations. The @{ML empty_ss} 
  1208   Notice that we had to add these lemmas as meta-equations. The @{ML empty_ss} 
  1206   expects this form of the simplification and congruence rules. However, even 
  1209   expects this form of the simplification and congruence rules. However, even 
  1207   adding these lemmas to @{ML empty_ss} we do not end up with anything useful yet.
  1210   when adding these lemmas to @{ML empty_ss} we do not end up with anything useful yet.
  1208 
  1211 
  1209   In the context of HOL the first useful simpset is @{ML HOL_basic_ss}. While
  1212   In the context of HOL, the first really useful simpset is @{ML HOL_basic_ss}. While
  1210   printing out the components of this simpset
  1213   printing out the components of this simpset
  1211 
  1214 
  1212   @{ML_response_fake [display,gray]
  1215   @{ML_response_fake [display,gray]
  1213   "print_parts @{context} HOL_basic_ss"
  1216   "print_parts @{context} HOL_basic_ss"
  1214 "Simplification rules:
  1217 "Simplification rules:
  1215 Congruences rules:"}
  1218 Congruences rules:"}
  1216 
  1219 
  1217   also produces ``nothing'', the printout is misleading. In fact
  1220   also produces ``nothing'', the printout is misleading. In fact
  1218   the simpset @{ML HOL_basic_ss} is setup so that it can be used to solve goals of the
  1221   the @{ML HOL_basic_ss} is setup so that it can solve goals of the
  1219   form  @{thm TrueI}, @{thm refl[no_vars]}, @{term "t \<equiv> t"} and @{thm FalseE[no_vars]}, 
  1222   form  @{thm TrueI}, @{thm refl[no_vars]}, @{term "t \<equiv> t"} and @{thm FalseE[no_vars]}; 
  1220   and resolve with assumptions.
  1223   and also resolve with assumptions. For example:
  1221 *}
  1224 *}
  1222 
  1225 
  1223 lemma 
  1226 lemma 
  1224  "True" and "t = t" and "t \<equiv> t" and "False \<Longrightarrow> Foo" and "\<lbrakk>A; B; C\<rbrakk> \<Longrightarrow> A"
  1227  "True" and "t = t" and "t \<equiv> t" and "False \<Longrightarrow> Foo" and "\<lbrakk>A; B; C\<rbrakk> \<Longrightarrow> A"
  1225 apply(tactic {* ALLGOALS (simp_tac HOL_basic_ss) *})
  1228 apply(tactic {* ALLGOALS (simp_tac HOL_basic_ss) *})
  1226 done
  1229 done
  1227 
  1230 
  1228 text {*
  1231 text {*
  1229   This is because how the tactics for the subgoaler, solver and looper are set 
  1232   This behaviour is not because of simplification rules, but how the subgoaler, solver 
  1230   up. 
  1233   and looper are set up. @{ML HOL_basic_ss} is usually a good start to build your 
  1231 
  1234   own simpsets, because of the low danger of causing loops via interacting simplifiction
  1232   The simpset @{ML HOL_ss}, which is an extention of @{ML HOL_basic_ss}, contains 
  1235   rules.
  1233   already many useful simplification rules for the logical connectives in HOL. 
  1236 
       
  1237   The simpset @{ML HOL_ss} is an extention of @{ML HOL_basic_ss} containing 
       
  1238   already many useful simplification and congruence rules for the logical 
       
  1239   connectives in HOL. 
  1234 
  1240 
  1235   @{ML_response_fake [display,gray]
  1241   @{ML_response_fake [display,gray]
  1236   "print_parts @{context} HOL_ss"
  1242   "print_parts @{context} HOL_ss"
  1237 "Simplification rules:
  1243 "Simplification rules:
  1238   Pure.triv_forall_equality: (\<And>x. PROP V) \<equiv> PROP V
  1244   Pure.triv_forall_equality: (\<And>x. PROP V) \<equiv> PROP V
  1243   HOL.simp_implies: \<dots>
  1249   HOL.simp_implies: \<dots>
  1244     \<Longrightarrow> (PROP P =simp=> PROP Q) \<equiv> (PROP P' =simp=> PROP Q')
  1250     \<Longrightarrow> (PROP P =simp=> PROP Q) \<equiv> (PROP P' =simp=> PROP Q')
  1245   op -->: \<lbrakk>P \<equiv> P'; P' \<Longrightarrow> Q \<equiv> Q'\<rbrakk> \<Longrightarrow> P \<longrightarrow> Q \<equiv> P' \<longrightarrow> Q'"}
  1251   op -->: \<lbrakk>P \<equiv> P'; P' \<Longrightarrow> Q \<equiv> Q'\<rbrakk> \<Longrightarrow> P \<longrightarrow> Q \<equiv> P' \<longrightarrow> Q'"}
  1246 
  1252 
  1247   
  1253   
  1248   The main point of these simpsets is that they are small enough to
  1254   The simplifier is often used to unfold definitions in a proof. For this the
  1249   not cause any loops with most of the simplification rules that
  1255   simplifier contains the @{ML rewrite_goals_tac}. Suppose for example the
  1250   you might like to add. 
  1256   definition
       
  1257 *}
       
  1258 
       
  1259 definition "MyTrue \<equiv> True"
       
  1260 
       
  1261 lemma shows "MyTrue \<Longrightarrow> True \<and> True"
       
  1262 apply(rule conjI)
       
  1263 apply(tactic {* rewrite_goals_tac [@{thm MyTrue_def}] *})
       
  1264 txt{* then the tactic produces the goal state
       
  1265 
       
  1266       \begin{minipage}{\textwidth}
       
  1267       @{subgoals [display]}
       
  1268       \end{minipage} *}
       
  1269 (*<*)oops(*>*)
       
  1270 
       
  1271 text {*
       
  1272   As you can see, the tactic unfolds the definitions in all subgoals.
  1251 *}
  1273 *}
  1252 
  1274 
  1253 
  1275 
  1254 text_raw {*
  1276 text_raw {*
  1255 \begin{figure}[tp]
  1277 \begin{figure}[tp]
  1257 types  prm = "(nat \<times> nat) list"
  1279 types  prm = "(nat \<times> nat) list"
  1258 consts perm :: "prm \<Rightarrow> 'a \<Rightarrow> 'a"  ("_ \<bullet> _" [80,80] 80)
  1280 consts perm :: "prm \<Rightarrow> 'a \<Rightarrow> 'a"  ("_ \<bullet> _" [80,80] 80)
  1259 
  1281 
  1260 primrec (perm_nat)
  1282 primrec (perm_nat)
  1261  "[]\<bullet>c = c"
  1283  "[]\<bullet>c = c"
  1262  "(ab#pi)\<bullet>c = (if (pi\<bullet>c)=fst ab 
  1284  "(ab#pi)\<bullet>c = (if (pi\<bullet>c)=fst ab then snd ab 
  1263                  then snd ab 
  1285                else (if (pi\<bullet>c)=snd ab then fst ab else (pi\<bullet>c)))" 
  1264                  else (if (pi\<bullet>c)=snd ab then fst ab else (pi\<bullet>c)))" 
       
  1265 
  1286 
  1266 primrec (perm_prod)
  1287 primrec (perm_prod)
  1267  "pi\<bullet>(x, y) = (pi\<bullet>x, pi\<bullet>y)"
  1288  "pi\<bullet>(x, y) = (pi\<bullet>x, pi\<bullet>y)"
  1268 
  1289 
  1269 primrec (perm_list)
  1290 primrec (perm_list)
  1298   (FIXME: Uses old primrec.)}
  1319   (FIXME: Uses old primrec.)}
  1299 \end{figure} *}
  1320 \end{figure} *}
  1300 
  1321 
  1301 
  1322 
  1302 text {*
  1323 text {*
  1303   Often the situation arises that simplification rules will cause the
  1324   The simplifier is often used in order to bring terms into a normal form.
  1304   simplifier to run into an infinite loop. Consider for example the simple
  1325   Unfortunately, often the situation arises that the corresponding
  1305   theory about permutations shown in Figure~\ref{fig:perms}. The purpose of
  1326   simplification rules will cause the simplifier to run into an infinite
  1306   the lemmas is to pus permutations as far inside a term where they might
  1327   loop. Consider for example the simple theory about permutations over natural
  1307   disappear using the lemma @{thm [source] perm_rev}. However, to fully
  1328   numbers shown in Figure~\ref{fig:perms}. The purpose of the lemmas is to
  1308   simplifiy all instances, it would be desirable to add also the lemma @{thm
  1329   push permutations as far inside as possible, where they might disappear by
  1309   [source] perm_compose} to the simplifier in order to push permutations over
  1330   Lemma @{thm [source] perm_rev}. However, to fully normalise all instances,
  1310   other permutations. Unfortunately, the right-hand side of this lemma is
  1331   it would be desirable to add also the lemma @{thm [source] perm_compose} to
  1311   again an instance of the left-hand side and so causes an infinite
  1332   the simplifier for pushing permutations over other permutations. Unfortunately, 
  1312   loop. On the user-level it is difficult to work around such situations
  1333   the right-hand side of this lemma is again an instance of the left-hand side 
  1313   and we end up with clunky proofs such as:
  1334   and so causes an infinite loop. The seems to be no easy way to reformulate 
       
  1335   this rule and so one ends up with clunky proofs like:
  1314 *}
  1336 *}
  1315 
  1337 
  1316 lemma 
  1338 lemma 
  1317   fixes c d::"nat" and pi\<^isub>1 pi\<^isub>2::"prm"
  1339   fixes c d::"nat" and pi\<^isub>1 pi\<^isub>2::"prm"
  1318   shows "pi\<^isub>1\<bullet>(c, pi\<^isub>2\<bullet>((rev pi\<^isub>1)\<bullet>d)) = (pi\<^isub>1\<bullet>c, (pi\<^isub>1\<bullet>pi\<^isub>2)\<bullet>d)"
  1340   shows "pi\<^isub>1\<bullet>(c, pi\<^isub>2\<bullet>((rev pi\<^isub>1)\<bullet>d)) = (pi\<^isub>1\<bullet>c, (pi\<^isub>1\<bullet>pi\<^isub>2)\<bullet>d)"
  1321 apply(rule perm_compose)
  1343 apply(rule perm_compose)
  1322 apply(simp)
  1344 apply(simp)
  1323 done 
  1345 done 
  1324 
  1346 
  1325 text {*
  1347 text {*
  1326   On the ML-level, we can however generate a single simplifier tactic that solves
  1348   It is however possible to create a single simplifier tactic that solves
  1327   such proofs. The trick is to introduce an auxiliary constant for permutations 
  1349   such proofs. The trick is to introduce an auxiliary constant for permutations 
  1328   and split the simplification into two phases. Let us say the auxiliary constant is
  1350   and split the simplification into two phases (below actually three). Let 
       
  1351   assume the auxiliary constant is
  1329 *}
  1352 *}
  1330 
  1353 
  1331 definition
  1354 definition
  1332   perm_aux :: "prm \<Rightarrow> 'a \<Rightarrow> 'a" ("_ \<bullet>aux _" [80,80] 80)
  1355   perm_aux :: "prm \<Rightarrow> 'a \<Rightarrow> 'a" ("_ \<bullet>aux _" [80,80] 80)
  1333 where
  1356 where
  1334   "pi \<bullet>aux c \<equiv> pi \<bullet> c"
  1357   "pi \<bullet>aux c \<equiv> pi \<bullet> c"
  1335 
  1358 
  1336 text {* Now the lemmas *}
  1359 text {* Now the two lemmas *}
  1337 
  1360 
  1338 lemma perm_aux_expand:
  1361 lemma perm_aux_expand:
  1339   fixes c::"nat" and pi\<^isub>1 pi\<^isub>2::"prm"
  1362   fixes c::"nat" and pi\<^isub>1 pi\<^isub>2::"prm"
  1340   shows "pi\<^isub>1\<bullet>(pi\<^isub>2\<bullet>c) = pi\<^isub>1 \<bullet>aux (pi\<^isub>2\<bullet>c)" 
  1363   shows "pi\<^isub>1\<bullet>(pi\<^isub>2\<bullet>c) = pi\<^isub>1 \<bullet>aux (pi\<^isub>2\<bullet>c)" 
  1341 unfolding perm_aux_def by (rule refl)
  1364 unfolding perm_aux_def by (rule refl)
  1347 
  1370 
  1348 text {* 
  1371 text {* 
  1349   are simple consequence of the definition and @{thm [source] perm_compose}. 
  1372   are simple consequence of the definition and @{thm [source] perm_compose}. 
  1350   More importantly, the lemma @{thm [source] perm_compose_aux} can be safely 
  1373   More importantly, the lemma @{thm [source] perm_compose_aux} can be safely 
  1351   added to the simplifier, because now the right-hand side is not anymore an instance 
  1374   added to the simplifier, because now the right-hand side is not anymore an instance 
  1352   of the left-hand side. So you can write 
  1375   of the left-hand side. In a sense it freezes all redexes of permutation compositions
       
  1376   after one step. In this way, we can split simplification of permutations
       
  1377   into three phases without the user not noticing anything about the auxiliary 
       
  1378   contant. We first freeze any instance of permutation compositions in the term using 
       
  1379   lemma @{thm [source] "perm_aux_expand"} (Line 9);
       
  1380   then simplifiy all other permutations including pusing permutations over
       
  1381   other permutations by rule @{thm [source] perm_compose_aux} (Line 10); and
       
  1382   finally ``unfreeze'' all instances of permutation compositions by unfolding 
       
  1383   the definition of the auxiliary constant. 
  1353 *}
  1384 *}
  1354 
  1385 
  1355 ML %linenosgray{*val perm_simp_tac =
  1386 ML %linenosgray{*val perm_simp_tac =
  1356 let
  1387 let
  1357   val thms1 = [@{thm perm_aux_expand}]
  1388   val thms1 = [@{thm perm_aux_expand}]
  1364   THEN' simp_tac (HOL_basic_ss addsimps thms2)
  1395   THEN' simp_tac (HOL_basic_ss addsimps thms2)
  1365   THEN' simp_tac (HOL_basic_ss addsimps thms3)
  1396   THEN' simp_tac (HOL_basic_ss addsimps thms3)
  1366 end*}
  1397 end*}
  1367 
  1398 
  1368 text {*
  1399 text {*
  1369   This trick is not noticable for the user.
  1400   For all three phases we have to build simpsets addig specific lemmas. As is sufficient
       
  1401   for our purposes here, we can add these lemma to @{ML HOL_basic_ss} in order to obtain
       
  1402   the desired results. Now we can solve the following lemma
  1370 *}
  1403 *}
  1371 
  1404 
  1372 lemma 
  1405 lemma 
  1373   fixes c d::"nat" and pi\<^isub>1 pi\<^isub>2::"prm"
  1406   fixes c d::"nat" and pi\<^isub>1 pi\<^isub>2::"prm"
  1374   shows "pi\<^isub>1\<bullet>(c, pi\<^isub>2\<bullet>((rev pi\<^isub>1)\<bullet>d)) = (pi\<^isub>1\<bullet>c, (pi\<^isub>1\<bullet>pi\<^isub>2)\<bullet>d)"
  1407   shows "pi\<^isub>1\<bullet>(c, pi\<^isub>2\<bullet>((rev pi\<^isub>1)\<bullet>d)) = (pi\<^isub>1\<bullet>c, (pi\<^isub>1\<bullet>pi\<^isub>2)\<bullet>d)"
  1375 apply(tactic {* perm_simp_tac 1 *})
  1408 apply(tactic {* perm_simp_tac 1 *})
  1376 done
  1409 done
  1377 
  1410 
  1378 
  1411 
  1379 text {*
  1412 text {*
       
  1413   in one step. This tactic can deal with most instances of normalising permutations;
       
  1414   in order to solve all cases we have to deal with corner-cases such as the
       
  1415   lemma being an exact instance of the permutation composition lemma. This can
       
  1416   often be done easier by implementing a simproc or a conversion. Both will be 
       
  1417   explained in the next two chapters.
       
  1418 
  1380   (FIXME: Is it interesting to say something about @{term "op =simp=>"}?)
  1419   (FIXME: Is it interesting to say something about @{term "op =simp=>"}?)
  1381 
  1420 
  1382   (FIXME: Unfortunately one cannot access any simproc, as there is 
  1421   (FIXME: Unfortunately one cannot access any simproc, as there is 
  1383   no @{text rep_proc} in function @{ML get_parts}.)
  1422   no @{text rep_proc} in function @{ML get_parts}.)
  1384 
  1423 
  1385   (FIXME: What are the second components of the congruence rules---something to
  1424   (FIXME: What are the second components of the congruence rules---something to
  1386   do with weak congruence constants?)
  1425   do with weak congruence constants?)
  1387 
  1426 
  1388   (FIXME: Anything interesting to say about @{ML Simplifier.clear_ss}?)
  1427   (FIXME: Anything interesting to say about @{ML Simplifier.clear_ss}?)
  1389 
  1428 
  1390   (FIXME: @{ML rewrite_goals_tac}, @{ML ObjectLogic.full_atomize_tac}, 
  1429   (FIXME: @{ML ObjectLogic.full_atomize_tac}, 
  1391   @{ML ObjectLogic.rulify_tac})
  1430   @{ML ObjectLogic.rulify_tac})
  1392 
  1431 
  1393 *}
  1432 *}
  1394 
  1433 
  1395 section {* Simprocs *}
  1434 section {* Simprocs *}