|   1281 \begin{boxedminipage}{\textwidth} |   1281 \begin{boxedminipage}{\textwidth} | 
|   1282 \begin{isabelle} *} |   1282 \begin{isabelle} *} | 
|   1283 types  prm = "(nat \<times> nat) list" |   1283 types  prm = "(nat \<times> nat) list" | 
|   1284 consts perm :: "prm \<Rightarrow> 'a \<Rightarrow> 'a"  ("_ \<bullet> _" [80,80] 80) |   1284 consts perm :: "prm \<Rightarrow> 'a \<Rightarrow> 'a"  ("_ \<bullet> _" [80,80] 80) | 
|   1285  |   1285  | 
|   1286 primrec (perm_nat) |   1286 overloading  | 
|   1287  "[]\<bullet>c = c" |   1287   perm_nat \<equiv> "perm :: prm \<Rightarrow> nat \<Rightarrow> nat" | 
|   1288  "(ab#pi)\<bullet>c = (if (pi\<bullet>c)=fst ab then snd ab  |   1288   perm_prod \<equiv> "perm :: prm \<Rightarrow> ('a\<times>'b) \<Rightarrow> ('a\<times>'b)" | 
|   1289                else (if (pi\<bullet>c)=snd ab then fst ab else (pi\<bullet>c)))"  |   1289   perm_list \<equiv> "perm :: prm \<Rightarrow> 'a list \<Rightarrow> 'a list" | 
|   1290  |   1290 begin | 
|   1291 primrec (perm_prod) |   1291  | 
|   1292  "pi\<bullet>(x, y) = (pi\<bullet>x, pi\<bullet>y)" |   1292 fun swap::"nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat" | 
|   1293  |   1293 where | 
|   1294 primrec (perm_list) |   1294  "swap a b c = (if c=a then b else (if c=b then a else c))" | 
|   1295  "pi\<bullet>[] = []" |   1295  | 
|   1296  "pi\<bullet>(x#xs) = (pi\<bullet>x)#(pi\<bullet>xs)" |   1296 primrec perm_nat | 
|         |   1297 where | 
|         |   1298   "perm_nat [] c = c" | 
|         |   1299 | "perm_nat (ab#pi) c = swap (fst ab) (snd ab) (perm_nat pi c)" | 
|         |   1300  | 
|         |   1301 fun perm_prod  | 
|         |   1302 where | 
|         |   1303  "perm_prod pi (x, y) = (pi\<bullet>x, pi\<bullet>y)" | 
|         |   1304  | 
|         |   1305 primrec perm_list | 
|         |   1306 where | 
|         |   1307   "perm_list pi [] = []" | 
|         |   1308 | "perm_list pi (x#xs) = (pi\<bullet>x)#(perm_list pi xs)" | 
|         |   1309  | 
|         |   1310 end | 
|   1297  |   1311  | 
|   1298 lemma perm_append[simp]: |   1312 lemma perm_append[simp]: | 
|   1299   fixes c::"nat" and pi\<^isub>1 pi\<^isub>2::"prm" |   1313 fixes c::"nat" and pi\<^isub>1 pi\<^isub>2::"prm" | 
|   1300   shows "((pi\<^isub>1@pi\<^isub>2)\<bullet>c) = (pi\<^isub>1\<bullet>(pi\<^isub>2\<bullet>c))" |   1314 shows "((pi\<^isub>1@pi\<^isub>2)\<bullet>c) = (pi\<^isub>1\<bullet>(pi\<^isub>2\<bullet>c))" | 
|   1301 by (induct pi\<^isub>1) (auto)  |   1315 by (induct pi\<^isub>1) (auto)  | 
|   1302  |   1316  | 
|   1303 lemma perm_eq[simp]: |   1317 lemma perm_bij[simp]: | 
|   1304   fixes c::"nat" and pi::"prm" |   1318 fixes c d::"nat" and pi::"prm" | 
|   1305   shows "(pi\<bullet>c = pi\<bullet>d) = (c = d)"  |   1319 shows "(pi\<bullet>c = pi\<bullet>d) = (c = d)"  | 
|   1306 by (induct pi) (auto) |   1320 by (induct pi) (auto) | 
|   1307  |   1321  | 
|   1308 lemma perm_rev[simp]: |   1322 lemma perm_rev[simp]: | 
|   1309   fixes c::"nat" and pi::"prm" |   1323 fixes c::"nat" and pi::"prm" | 
|   1310   shows "pi\<bullet>((rev pi)\<bullet>c) = c" |   1324 shows "pi\<bullet>((rev pi)\<bullet>c) = c" | 
|   1311 by (induct pi arbitrary: c) (auto) |   1325 by (induct pi arbitrary: c) (auto) | 
|   1312  |   1326  | 
|   1313 lemma perm_compose: |   1327 lemma perm_compose: | 
|   1314   fixes c::"nat" and pi\<^isub>1 pi\<^isub>2::"prm" |   1328 fixes c::"nat" and pi\<^isub>1 pi\<^isub>2::"prm" | 
|   1315   shows "pi\<^isub>1\<bullet>(pi\<^isub>2\<bullet>c) = (pi\<^isub>1\<bullet>pi\<^isub>2)\<bullet>(pi\<^isub>1\<bullet>c)"  |   1329 shows "pi\<^isub>1\<bullet>(pi\<^isub>2\<bullet>c) = (pi\<^isub>1\<bullet>pi\<^isub>2)\<bullet>(pi\<^isub>1\<bullet>c)"  | 
|   1316 by (induct pi\<^isub>2) (auto) |   1330 by (induct pi\<^isub>2) (auto) | 
|   1317 text_raw {* |   1331 text_raw {* | 
|   1318 \end{isabelle} |   1332 \end{isabelle} | 
|   1319 \end{boxedminipage} |   1333 \end{boxedminipage} | 
|   1320 \caption{A simple theory about permutations over @{typ nat}. The point is that the |   1334 \caption{A simple theory about permutations over @{typ nat}s. The point is that the | 
|   1321   lemma @{thm [source] perm_compose} cannot be directly added to the simplifier, as |   1335   lemma @{thm [source] perm_compose} cannot be directly added to the simplifier, as | 
|   1322   it would cause the simplifier to loop. It can still be used as a simplification  |   1336   it would cause the simplifier to loop. It can still be used as a simplification  | 
|   1323   rule if the permutation is sufficiently protected.\label{fig:perms} |   1337   rule if the permutation in the right-hand side is sufficiently protected. | 
|   1324   (FIXME: Uses old primrec.)} |   1338   \label{fig:perms}} | 
|   1325 \end{figure} *} |   1339 \end{figure} *} | 
|   1326  |   1340  | 
|   1327  |   1341  | 
|   1328 text {* |   1342 text {* | 
|   1329   The simplifier is often used in order to bring terms into a normal form. |   1343   The simplifier is often used in order to bring terms into a normal form. | 
|   1362   "pi \<bullet>aux c \<equiv> pi \<bullet> c" |   1376   "pi \<bullet>aux c \<equiv> pi \<bullet> c" | 
|   1363  |   1377  | 
|   1364 text {* Now the two lemmas *} |   1378 text {* Now the two lemmas *} | 
|   1365  |   1379  | 
|   1366 lemma perm_aux_expand: |   1380 lemma perm_aux_expand: | 
|   1367   fixes c::"nat" and pi\<^isub>1 pi\<^isub>2::"prm" |   1381 fixes c::"nat" and pi\<^isub>1 pi\<^isub>2::"prm" | 
|   1368   shows "pi\<^isub>1\<bullet>(pi\<^isub>2\<bullet>c) = pi\<^isub>1 \<bullet>aux (pi\<^isub>2\<bullet>c)"  |   1382 shows "pi\<^isub>1\<bullet>(pi\<^isub>2\<bullet>c) = pi\<^isub>1 \<bullet>aux (pi\<^isub>2\<bullet>c)"  | 
|   1369 unfolding perm_aux_def by (rule refl) |   1383 unfolding perm_aux_def by (rule refl) | 
|   1370  |   1384  | 
|   1371 lemma perm_compose_aux: |   1385 lemma perm_compose_aux: | 
|   1372   fixes c::"nat" and pi\<^isub>1 pi\<^isub>2::"prm" |   1386 fixes c::"nat" and pi\<^isub>1 pi\<^isub>2::"prm" | 
|   1373   shows "pi\<^isub>1\<bullet>(pi\<^isub>2\<bullet>aux c) = (pi\<^isub>1\<bullet>pi\<^isub>2) \<bullet>aux (pi\<^isub>1\<bullet>c)"  |   1387 shows "pi\<^isub>1\<bullet>(pi\<^isub>2\<bullet>aux c) = (pi\<^isub>1\<bullet>pi\<^isub>2) \<bullet>aux (pi\<^isub>1\<bullet>c)"  | 
|   1374 unfolding perm_aux_def by (rule perm_compose) |   1388 unfolding perm_aux_def by (rule perm_compose) | 
|   1375  |   1389  | 
|   1376 text {*  |   1390 text {*  | 
|   1377   are simple consequence of the definition and @{thm [source] perm_compose}.  |   1391   are simple consequence of the definition and @{thm [source] perm_compose}.  | 
|   1378   More importantly, the lemma @{thm [source] perm_compose_aux} can be safely  |   1392   More importantly, the lemma @{thm [source] perm_compose_aux} can be safely  | 
|   1389 *} |   1403 *} | 
|   1390  |   1404  | 
|   1391 ML %linenosgray{*val perm_simp_tac = |   1405 ML %linenosgray{*val perm_simp_tac = | 
|   1392 let |   1406 let | 
|   1393   val thms1 = [@{thm perm_aux_expand}] |   1407   val thms1 = [@{thm perm_aux_expand}] | 
|   1394   val thms2 = [@{thm perm_append}, @{thm perm_eq}, @{thm perm_rev},  |   1408   val thms2 = [@{thm perm_append}, @{thm perm_bij}, @{thm perm_rev},  | 
|   1395                @{thm perm_compose_aux}] @ @{thms perm_prod.simps} @  |   1409                @{thm perm_compose_aux}] @ @{thms perm_prod.simps} @  | 
|   1396                @{thms perm_list.simps} @ @{thms perm_nat.simps} |   1410                @{thms perm_list.simps} @ @{thms perm_nat.simps} | 
|   1397   val thms3 = [@{thm perm_aux_def}] |   1411   val thms3 = [@{thm perm_aux_def}] | 
|   1398 in |   1412 in | 
|   1399   simp_tac (HOL_basic_ss addsimps thms1) |   1413   simp_tac (HOL_basic_ss addsimps thms1) | 
|   1406   for our purposes here, we can add these lemma to @{ML HOL_basic_ss} in order to obtain |   1420   for our purposes here, we can add these lemma to @{ML HOL_basic_ss} in order to obtain | 
|   1407   the desired results. Now we can solve the following lemma |   1421   the desired results. Now we can solve the following lemma | 
|   1408 *} |   1422 *} | 
|   1409  |   1423  | 
|   1410 lemma  |   1424 lemma  | 
|   1411   fixes c d::"nat" and pi\<^isub>1 pi\<^isub>2::"prm" |   1425 fixes c d::"nat" and pi\<^isub>1 pi\<^isub>2::"prm" | 
|   1412   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)" |   1426 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)" | 
|   1413 apply(tactic {* perm_simp_tac 1 *}) |   1427 apply(tactic {* perm_simp_tac 1 *}) | 
|   1414 done |   1428 done | 
|   1415  |   1429  | 
|   1416  |   1430  | 
|   1417 text {* |   1431 text {* |