doc-src/Ref/simplifier.tex
changeset 3112 0f764be1583a
parent 3108 335efc3f5632
child 3128 d01d4c0c4b44
equal deleted inserted replaced
3111:00fb015d27aa 3112:0f764be1583a
   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|)}