457 |
457 |
458 To remind yourself of what is in a simpset, use the function \verb$rep_ss$ to |
458 To remind yourself of what is in a simpset, use the function \verb$rep_ss$ to |
459 return its simplification and congruence rules. |
459 return its simplification and congruence rules. |
460 |
460 |
461 \section{Examples using the simplifier} |
461 \section{Examples using the simplifier} |
462 \index{examples!of simplification} |
462 \index{examples!of simplification} Assume we are working within {\tt |
463 Assume we are working within {\tt FOL} and that |
463 FOL} (cf.\ \texttt{FOL/ex/Nat}) and that |
464 \begin{ttdescription} |
464 \begin{ttdescription} |
465 \item[Nat.thy] |
465 \item[Nat.thy] |
466 is a theory including the constants $0$, $Suc$ and $+$, |
466 is a theory including the constants $0$, $Suc$ and $+$, |
467 \item[add_0] |
467 \item[add_0] |
468 is the rewrite rule $0+\Var{n} = \Var{n}$, |
468 is the rewrite rule $0+\Var{n} = \Var{n}$, |
469 \item[add_Suc] |
469 \item[add_Suc] |
470 is the rewrite rule $Suc(\Var{m})+\Var{n} = Suc(\Var{m}+\Var{n})$, |
470 is the rewrite rule $Suc(\Var{m})+\Var{n} = Suc(\Var{m}+\Var{n})$, |
471 \item[induct] |
471 \item[induct] |
472 is the induction rule $\List{\Var{P}(0);\; \Forall x. \Var{P}(x)\Imp |
472 is the induction rule $\List{\Var{P}(0);\; \Forall x. \Var{P}(x)\Imp |
473 \Var{P}(Suc(x))} \Imp \Var{P}(\Var{n})$. |
473 \Var{P}(Suc(x))} \Imp \Var{P}(\Var{n})$. |
474 \item[FOL_ss] |
|
475 is a basic simpset for {\tt FOL}.% |
|
476 \footnote{These examples reside on the file {\tt FOL/ex/Nat.ML}.} |
|
477 \end{ttdescription} |
474 \end{ttdescription} |
478 |
475 We augment the implicit simpset of {\FOL} with the basic rewrite rules |
479 We create a simpset for natural numbers by extending~{\tt FOL_ss}: |
476 for natural numbers: |
480 \begin{ttbox} |
477 \begin{ttbox} |
481 val add_ss = FOL_ss addsimps [add_0, add_Suc]; |
478 Addsimps [add_0, add_Suc]; |
482 \end{ttbox} |
479 \end{ttbox} |
483 |
480 |
484 \subsection{A trivial example} |
481 \subsection{A trivial example} |
485 Proofs by induction typically involve simplification. Here is a proof |
482 Proofs by induction typically involve simplification. Here is a proof |
486 that~0 is a right identity: |
483 that~0 is a right identity: |
499 {\out 1. 0 + 0 = 0} |
496 {\out 1. 0 + 0 = 0} |
500 {\out 2. !!x. x + 0 = x ==> Suc(x) + 0 = Suc(x)} |
497 {\out 2. !!x. x + 0 = x ==> Suc(x) + 0 = Suc(x)} |
501 \end{ttbox} |
498 \end{ttbox} |
502 Simplification solves the first subgoal trivially: |
499 Simplification solves the first subgoal trivially: |
503 \begin{ttbox} |
500 \begin{ttbox} |
504 by (simp_tac add_ss 1); |
501 by (Simp_tac 1); |
505 {\out Level 2} |
502 {\out Level 2} |
506 {\out m + 0 = m} |
503 {\out m + 0 = m} |
507 {\out 1. !!x. x + 0 = x ==> Suc(x) + 0 = Suc(x)} |
504 {\out 1. !!x. x + 0 = x ==> Suc(x) + 0 = Suc(x)} |
508 \end{ttbox} |
505 \end{ttbox} |
509 The remaining subgoal requires \ttindex{asm_simp_tac} in order to use the |
506 The remaining subgoal requires \ttindex{Asm_simp_tac} in order to use the |
510 induction hypothesis as a rewrite rule: |
507 induction hypothesis as a rewrite rule: |
511 \begin{ttbox} |
508 \begin{ttbox} |
512 by (asm_simp_tac add_ss 1); |
509 by (Asm_simp_tac 1); |
513 {\out Level 3} |
510 {\out Level 3} |
514 {\out m + 0 = m} |
511 {\out m + 0 = m} |
515 {\out No subgoals!} |
512 {\out No subgoals!} |
516 \end{ttbox} |
513 \end{ttbox} |
517 |
514 |
535 {\out Suc(x) + Suc(n) = Suc(Suc(x) + n)} |
532 {\out Suc(x) + Suc(n) = Suc(Suc(x) + n)} |
536 \end{ttbox} |
533 \end{ttbox} |
537 Simplification solves the first subgoal, this time rewriting two |
534 Simplification solves the first subgoal, this time rewriting two |
538 occurrences of~0: |
535 occurrences of~0: |
539 \begin{ttbox} |
536 \begin{ttbox} |
540 by (simp_tac add_ss 1); |
537 by (Simp_tac 1); |
541 {\out Level 2} |
538 {\out Level 2} |
542 {\out m + Suc(n) = Suc(m + n)} |
539 {\out m + Suc(n) = Suc(m + n)} |
543 {\out 1. !!x. x + Suc(n) = Suc(x + n) ==>} |
540 {\out 1. !!x. x + Suc(n) = Suc(x + n) ==>} |
544 {\out Suc(x) + Suc(n) = Suc(Suc(x) + n)} |
541 {\out Suc(x) + Suc(n) = Suc(Suc(x) + n)} |
545 \end{ttbox} |
542 \end{ttbox} |
546 Switching tracing on illustrates how the simplifier solves the remaining |
543 Switching tracing on illustrates how the simplifier solves the remaining |
547 subgoal: |
544 subgoal: |
548 \begin{ttbox} |
545 \begin{ttbox} |
549 trace_simp := true; |
546 trace_simp := true; |
550 by (asm_simp_tac add_ss 1); |
547 by (Asm_simp_tac 1); |
|
548 \ttbreak |
|
549 {\out Adding rewrite rule:} |
|
550 {\out .x + Suc(n) == Suc(.x + n)} |
551 \ttbreak |
551 \ttbreak |
552 {\out Rewriting:} |
552 {\out Rewriting:} |
553 {\out Suc(x) + Suc(n) == Suc(x + Suc(n))} |
553 {\out Suc(.x) + Suc(n) == Suc(.x + Suc(n))} |
554 \ttbreak |
554 \ttbreak |
555 {\out Rewriting:} |
555 {\out Rewriting:} |
556 {\out x + Suc(n) == Suc(x + n)} |
556 {\out .x + Suc(n) == Suc(.x + n)} |
557 \ttbreak |
557 \ttbreak |
558 {\out Rewriting:} |
558 {\out Rewriting:} |
559 {\out Suc(x) + n == Suc(x + n)} |
559 {\out Suc(.x) + n == Suc(.x + n)} |
560 \ttbreak |
560 \ttbreak |
561 {\out Rewriting:} |
561 {\out Rewriting:} |
562 {\out Suc(Suc(x + n)) = Suc(Suc(x + n)) == True} |
562 {\out Suc(Suc(.x + n)) = Suc(Suc(.x + n)) == True} |
563 \ttbreak |
563 \ttbreak |
564 {\out Level 3} |
564 {\out Level 3} |
565 {\out m + Suc(n) = Suc(m + n)} |
565 {\out m + Suc(n) = Suc(m + n)} |
566 {\out No subgoals!} |
566 {\out No subgoals!} |
567 \end{ttbox} |
567 \end{ttbox} |
568 Many variations are possible. At Level~1 (in either example) we could have |
568 Many variations are possible. At Level~1 (in either example) we could have |
569 solved both subgoals at once using the tactical \ttindex{ALLGOALS}: |
569 solved both subgoals at once using the tactical \ttindex{ALLGOALS}: |
570 \begin{ttbox} |
570 \begin{ttbox} |
571 by (ALLGOALS (asm_simp_tac add_ss)); |
571 by (ALLGOALS Asm_simp_tac); |
572 {\out Level 2} |
572 {\out Level 2} |
573 {\out m + Suc(n) = Suc(m + n)} |
573 {\out m + Suc(n) = Suc(m + n)} |
574 {\out No subgoals!} |
574 {\out No subgoals!} |
575 \end{ttbox} |
575 \end{ttbox} |
576 \index{tracing!of simplification|)} |
576 \index{tracing!of simplification|)} |
597 {\out 1. f(0 + j) = 0 + f(j)} |
597 {\out 1. f(0 + j) = 0 + f(j)} |
598 {\out 2. !!x. f(x + j) = x + f(j) ==> f(Suc(x) + j) = Suc(x) + f(j)} |
598 {\out 2. !!x. f(x + j) = x + f(j) ==> f(Suc(x) + j) = Suc(x) + f(j)} |
599 \end{ttbox} |
599 \end{ttbox} |
600 We simplify each subgoal in turn. The first one is trivial: |
600 We simplify each subgoal in turn. The first one is trivial: |
601 \begin{ttbox} |
601 \begin{ttbox} |
602 by (simp_tac add_ss 1); |
602 by (Simp_tac 1); |
603 {\out Level 2} |
603 {\out Level 2} |
604 {\out f(i + j) = i + f(j)} |
604 {\out f(i + j) = i + f(j)} |
605 {\out 1. !!x. f(x + j) = x + f(j) ==> f(Suc(x) + j) = Suc(x) + f(j)} |
605 {\out 1. !!x. f(x + j) = x + f(j) ==> f(Suc(x) + j) = Suc(x) + f(j)} |
606 \end{ttbox} |
606 \end{ttbox} |
607 The remaining subgoal requires rewriting by the premise, so we add it to |
607 The remaining subgoal requires rewriting by the premise, so we add it |
608 {\tt add_ss}:% |
608 to the current simpset:\footnote{The previous simplifier required |
609 \footnote{The previous simplifier required congruence rules for function |
609 congruence rules for function variables like~$f$ in order to |
610 variables like~$f$ in order to simplify their arguments. It was more |
610 simplify their arguments. It was more general than the current |
611 general than the current simplifier, but harder to use and slower. The |
611 simplifier, but harder to use and slower. The present simplifier |
612 present simplifier can be given congruence rules to realize non-standard |
612 can be given congruence rules to realize non-standard simplification |
613 simplification of a function's arguments, but this is seldom necessary.} |
613 of a function's arguments, but this is seldom necessary.} |
614 \begin{ttbox} |
614 \begin{ttbox} |
615 by (asm_simp_tac (add_ss addsimps [prem]) 1); |
615 by (asm_simp_tac (!simpset addsimps [prem]) 1); |
616 {\out Level 3} |
616 {\out Level 3} |
617 {\out f(i + j) = i + f(j)} |
617 {\out f(i + j) = i + f(j)} |
618 {\out No subgoals!} |
618 {\out No subgoals!} |
619 \end{ttbox} |
619 \end{ttbox} |
620 |
620 |
1022 \] |
1022 \] |
1023 Case splits should be allowed only when necessary; they are expensive |
1023 Case splits should be allowed only when necessary; they are expensive |
1024 and hard to control. Here is a typical example of use, where {\tt |
1024 and hard to control. Here is a typical example of use, where {\tt |
1025 expand_if} is the first rule above: |
1025 expand_if} is the first rule above: |
1026 \begin{ttbox} |
1026 \begin{ttbox} |
1027 by (simp_tac (prop_rec_ss setloop (split_tac [expand_if])) 1); |
1027 by (simp_tac (!simpset setloop (split_tac [expand_if])) 1); |
1028 \end{ttbox} |
1028 \end{ttbox} |
1029 |
1029 |
1030 |
1030 |
1031 |
1031 |
1032 \index{simplification|)} |
1032 \index{simplification|)} |