doc-src/Ref/simplifier.tex
author lcp
Wed, 10 Nov 1993 05:00:57 +0100
changeset 104 d8205bb279a7
child 122 db9043a8e372
permissions -rw-r--r--
Initial revision
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
104
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     1
%% $Id$
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     2
\chapter{Simplification} \label{simp-chap}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     3
\index{simplification|(}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     4
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     5
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     6
This chapter describes Isabelle's generic simplification package, which
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     7
provides a suite of simplification tactics.  This rewriting package is less
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     8
general than its predecessor --- it works only for the equality relation,
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
     9
not arbitrary preorders --- but it is fast and flexible.  It performs
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    10
conditional and unconditional rewriting and uses contextual information
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    11
(``local assumptions'').  It provides a few general hooks, which can
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    12
provide automatic case splits during rewriting, for example.  The
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    13
simplifier is set up for many of Isabelle's logics: {\tt FOL}, {\tt ZF},
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    14
{\tt LCF} and {\tt HOL}.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    15
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    16
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    17
\section{Simplification sets}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    18
\index{simplification sets} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    19
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    20
The simplification tactics are controlled by {\bf simpsets}.  These consist
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    21
of five components: rewrite rules, congruence rules, the subgoaler, the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    22
solver and the looper.  Normally, the simplifier is set up with sensible
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    23
defaults, so that most simplifier calls specify only rewrite rules.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    24
Sophisticated usage of the other components can be highly effective, but
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    25
most users should never worry about them.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    26
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    27
\subsection{Rewrite rules}\index{rewrite rules}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    28
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    29
Rewrite rules are theorems like $Suc(\Var{m}) + \Var{n} = \Var{m} +
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    30
Suc(\Var{n})$, $\Var{P}\conj\Var{P} \bimp \Var{P}$, or $\Var{A} \un \Var{B}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    31
\equiv \{x.x\in A \disj x\in B\}$.  {\bf Conditional} rewrites such as
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    32
$\Var{m}<\Var{n} \Imp \Var{m}/\Var{n} = 0$ are permitted; the conditions
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    33
can be arbitrary terms.  The infix operation \ttindex{addsimps} adds new
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    34
rewrite rules, while \ttindex{delsimps} deletes rewrite rules from a
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    35
simpset.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    36
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    37
Theorems added via \ttindex{addsimps} need not be equalities to start with.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    38
Each simpset contains a (user-definable) function for extracting equalities
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    39
from arbitrary theorems.  For example $\neg(x\in \{\})$ could be turned
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    40
into $x\in \{\} \equiv False$.  This function can be set with
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    41
\ttindex{setmksimps} but only the definer of a logic should need to do
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    42
this.  Exceptionally, one may want to install a selective version of
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    43
\ttindex{mksimps} in order to filter out looping rewrite rules arising from
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    44
local assumptions (see below).
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    45
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    46
Internally, all rewrite rules are translated into meta-equalities:
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    47
theorems with conclusion $lhs \equiv rhs$.  To this end every simpset contains
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    48
a function of type \verb$thm -> thm list$ to extract a list
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    49
of meta-equalities from a given theorem.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    50
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    51
\begin{warn}\index{rewrite rules}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    52
  The left-hand side of a rewrite rule must look like a first-order term:
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    53
  after eta-contraction, none of its unknowns should have arguments.  Hence
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    54
  ${\Var{i}+(\Var{j}+\Var{k})} = {(\Var{i}+\Var{j})+\Var{k}}$ and $\neg(\forall
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    55
  x.\Var{P}(x)) \bimp (\exists x.\neg\Var{P}(x))$ are acceptable, whereas
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    56
  $\Var{f}(\Var{x})\in {\tt range}(\Var{f}) = True$ is not.  However, you can
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    57
  replace the offending subterms by new variables and conditions: $\Var{y} =
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    58
  \Var{f}(\Var{x}) \Imp \Var{y}\in {\tt range}(\Var{f}) = True$ is again
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    59
  acceptable.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    60
\end{warn}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    61
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    62
\subsection {Congruence rules}\index{congruence rules}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    63
Congruence rules are meta-equalities of the form
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    64
\[ \List{\dots} \Imp
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    65
   f(\Var{x@1},\ldots,\Var{x@n}) \equiv f(\Var{y@1},\ldots,\Var{y@n}).
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    66
\]
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    67
They control the simplification of the arguments of certain constants.  For
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    68
example, some arguments can be simplified under additional assumptions:
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    69
\[ \List{\Var{P@1} \bimp \Var{Q@1};\; \Var{Q@1} \Imp \Var{P@2} \bimp \Var{Q@2}}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    70
   \Imp (\Var{P@1} \imp \Var{P@2}) \equiv (\Var{Q@1} \imp \Var{Q@2})
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    71
\]
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    72
This rule assumes $Q@1$ and any rewrite rules it implies, while
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    73
simplifying~$P@2$.  Such ``local'' assumptions are effective for rewriting
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    74
formulae such as $x=0\imp y+x=y$.  The next example makes similar use of
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    75
such contextual information in bounded quantifiers:
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    76
\[ \List{\Var{A}=\Var{B};\; \Forall x. x\in \Var{B} \Imp \Var{P}(x) = \Var{Q}(x)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    77
   \Imp (\forall x\in \Var{A}.\Var{P}(x)) = (\forall x\in \Var{B}.\Var{Q}(x))
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    78
\]
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    79
This congruence rule supplies contextual information for simplifying the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    80
arms of a conditional expressions:
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    81
\[ \List{\Var{p}=\Var{q};~ \Var{q} \Imp \Var{a}=\Var{c};~
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    82
         \neg\Var{q} \Imp \Var{b}=\Var{d}} \Imp
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    83
   if(\Var{p},\Var{a},\Var{b}) \equiv if(\Var{q},\Var{c},\Var{d})
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    84
\]
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    85
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    86
A congruence rule can also suppress simplification of certain arguments.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    87
Here is an alternative congruence rule for conditional expressions:
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    88
\[ \Var{p}=\Var{q} \Imp
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    89
   if(\Var{p},\Var{a},\Var{b}) \equiv if(\Var{q},\Var{a},\Var{b})
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    90
\]
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    91
Only the first argument is simplified; the others remain unchanged.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    92
This can make simplification much faster, but may require an extra case split
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    93
to prove the goal.  
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    94
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    95
Congruence rules are added using \ttindex{addeqcongs}.  Their conclusion
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    96
must be a meta-equality, as in the examples above.  It is more
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    97
natural to derive the rules with object-logic equality, for example
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    98
\[ \List{\Var{P@1} \bimp \Var{Q@1};\; \Var{Q@1} \Imp \Var{P@2} \bimp \Var{Q@2}}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
    99
   \Imp (\Var{P@1} \imp \Var{P@2}) \bimp (\Var{Q@1} \imp \Var{Q@2}),
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   100
\]
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   101
So each object-logic should provide an alternative combinator
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   102
\ttindex{addcongs} that expects object-equalities and translates them into
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   103
meta-equalities.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   104
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   105
\subsection{The subgoaler} \index{subgoaler}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   106
The subgoaler is the tactic used to solve subgoals arising out of
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   107
conditional rewrite rules or congruence rules.  The default should be
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   108
simplification itself.  Occasionally this strategy needs to be changed.  For
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   109
example, if the premise of a conditional rule is an instance of its
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   110
conclusion, as in $Suc(\Var{m}) < \Var{n} \Imp \Var{m} < \Var{n}$, the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   111
default strategy could loop.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   112
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   113
The subgoaler can be set explicitly with \ttindex{setsubgoaler}.  For
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   114
example, the subgoaler
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   115
\begin{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   116
fun subgoal_tac ss = resolve_tac (prems_of_ss ss) ORELSE' 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   117
                     asm_simp_tac ss;
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   118
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   119
tries to solve the subgoal with one of the premises and calls
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   120
simplification only if that fails; here {\tt prems_of_ss} extracts the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   121
current premises from a simpset.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   122
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   123
\subsection{The solver} \index{solver}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   124
The solver attempts to solve a subgoal after simplification, say by
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   125
recognizing it as a tautology. It can be set with \ttindex{setsolver}.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   126
Occasionally, simplification on its own is not enough to reduce the subgoal
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   127
to a tautology; additional means, like \verb$fast_tac$, may be necessary.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   128
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   129
\begin{warn}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   130
  Rewriting does not instantiate unknowns.  Trying to rewrite $a\in
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   131
  \Var{A}$ with the rule $\Var{x}\in \{\Var{x}\}$ leads nowhere.  The
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   132
  solver, however, is an arbitrary tactic and may instantiate unknowns as
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   133
  it pleases.  This is the only way the simplifier can handle a conditional
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   134
  rewrite rule whose condition contains extra variables.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   135
\end{warn}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   136
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   137
\begin{warn}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   138
  If you want to supply your own subgoaler or solver, read on.  The subgoaler
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   139
  is also used to solve the premises of congruence rules, which are usually
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   140
  of the form $s = \Var{x}$, where $s$ needs to be simplified and $\Var{x}$
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   141
  needs to be instantiated with the result. Hence the subgoaler should call
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   142
  the simplifier at some point. The simplifier will then call the solver,
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   143
  which must therefore be prepared to solve goals of the form $t = \Var{x}$,
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   144
  usually by reflexivity. In particular, reflexivity should be tried before
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   145
  any of the fancy tactics like {\tt fast_tac}. It may even happen that, due
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   146
  to simplification, the subgoal is no longer an equality. For example $False
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   147
  \bimp \Var{Q}$ could be rewritten to $\neg\Var{Q}$, in which case the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   148
  solver must also try resolving with the theorem $\neg False$.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   149
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   150
  If the simplifier aborts with the message {\tt Failed congruence proof!},
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   151
  it is due to the subgoaler or solver who failed to prove a premise of a
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   152
  congruence rule.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   153
\end{warn}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   154
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   155
\subsection{The looper} \index{looper}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   156
The looper is a tactic that is applied after simplification, in case the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   157
solver failed to solve the simplified goal.  If the looper succeeds, the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   158
simplification process is started all over again.  Each of the subgoals
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   159
generated by the looper is attacked in turn, in reverse order.  A
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   160
typical looper is case splitting: the expansion of a conditional.  Another
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   161
possibility is to apply an elimination rule on the assumptions.  More
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   162
adventurous loopers could start an induction.  The looper is set with 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   163
\ttindex{setloop}.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   164
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   165
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   166
\begin{figure}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   167
\indexbold{*SIMPLIFIER}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   168
\begin{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   169
infix addsimps addeqcongs delsimps
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   170
      setsubgoaler setsolver setloop setmksimps;
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   171
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   172
signature SIMPLIFIER =
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   173
sig
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   174
  type simpset
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   175
  val simp_tac:          simpset -> int -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   176
  val asm_simp_tac:      simpset -> int -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   177
  val asm_full_simp_tac: simpset -> int -> tactic
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   178
  val addeqcongs:  simpset * thm list -> simpset
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   179
  val addsimps:    simpset * thm list -> simpset
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   180
  val delsimps:    simpset * thm list -> simpset
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   181
  val empty_ss:     simpset
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   182
  val merge_ss:     simpset * simpset -> simpset
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   183
  val setsubgoaler: simpset * (simpset -> int -> tactic) -> simpset
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   184
  val setsolver:    simpset * (thm list -> int -> tactic) -> simpset
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   185
  val setloop:      simpset * (int -> tactic) -> simpset
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   186
  val setmksimps:   simpset * (thm -> thm list) -> simpset
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   187
  val prems_of_ss:  simpset -> thm list
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   188
  val rep_ss:       simpset -> \{simps: thm list, congs: thm list\}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   189
end;
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   190
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   191
\caption{The signature \ttindex{SIMPLIFIER}} \label{SIMPLIFIER}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   192
\end{figure}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   193
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   194
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   195
\section{The simplification tactics} \label{simp-tactics}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   196
\index{simplification!tactics|bold}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   197
\index{tactics!simplification|bold}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   198
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   199
The actual simplification work is performed by the following tactics.  The
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   200
rewriting strategy is strictly bottom up, except for congruence rules, which
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   201
are applied while descending into a term.  Conditions in conditional rewrite
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   202
rules are solved recursively before the rewrite rule is applied.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   203
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   204
There are three basic simplification tactics:
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   205
\begin{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   206
\item[\ttindexbold{simp_tac} $ss$ $i$] simplifies subgoal~$i$ using the rules
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   207
  in~$ss$.  It may solve the subgoal completely if it has become trivial,
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   208
  using the solver.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   209
  
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   210
\item[\ttindexbold{asm_simp_tac}] is like \verb$simp_tac$, but also uses
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   211
  assumptions as additional rewrite rules.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   212
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   213
\item[\ttindexbold{asm_full_simp_tac}] is like \verb$asm_simp_tac$, but also
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   214
  simplifies the assumptions one by one, using each assumption in the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   215
  simplification of the following ones.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   216
\end{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   217
Using the simplifier effectively may take a bit of experimentation.  The
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   218
tactics can be traced with the ML command \verb$trace_simp := true$.  To
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   219
remind yourself of what is in a simpset, use the function \verb$rep_ss$ to
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   220
return its simplification and congruence rules.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   221
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   222
\section{Example: using the simplifier}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   223
\index{simplification!example}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   224
Assume we are working within {\tt FOL} and that
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   225
\begin{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   226
\item[\tt Nat.thy] is a theory including the constants $0$, $Suc$ and $+$,
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   227
\item[\tt add_0] is the rewrite rule $0+n = n$,
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   228
\item[\tt add_Suc] is the rewrite rule $Suc(m)+n = Suc(m+n)$,
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   229
\item[\tt induct] is the induction rule
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   230
$\List{P(0); \Forall x. P(x)\Imp P(Suc(x))} \Imp P(n)$.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   231
\item[\tt FOL_ss] is a basic simpset for {\tt FOL}.\footnote
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   232
{These examples reside on the file {\tt FOL/ex/nat.ML}.} 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   233
\end{description}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   234
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   235
We create a simpset for natural numbers by extending~{\tt FOL_ss}:
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   236
\begin{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   237
val add_ss = FOL_ss addsimps [add_0, add_Suc];
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   238
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   239
Proofs by induction typically involve simplification:
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   240
\begin{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   241
goal Nat.thy "m+0 = m";
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   242
{\out Level 0}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   243
{\out m + 0 = m}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   244
{\out  1. m + 0 = m}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   245
\ttbreak
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   246
by (res_inst_tac [("n","m")] induct 1);
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   247
{\out Level 1}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   248
{\out m + 0 = m}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   249
{\out  1. 0 + 0 = 0}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   250
{\out  2. !!x. x + 0 = x ==> Suc(x) + 0 = Suc(x)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   251
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   252
Simplification solves the first subgoal:
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   253
\begin{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   254
by (simp_tac add_ss 1);
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   255
{\out Level 2}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   256
{\out m + 0 = m}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   257
{\out  1. !!x. x + 0 = x ==> Suc(x) + 0 = Suc(x)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   258
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   259
The remaining subgoal requires \ttindex{asm_simp_tac} in order to use the
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   260
induction hypothesis as a rewrite rule:
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   261
\begin{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   262
by (asm_simp_tac add_ss 1);
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   263
{\out Level 3}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   264
{\out m + 0 = m}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   265
{\out No subgoals!}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   266
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   267
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   268
\medskip
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   269
The next proof is similar.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   270
\begin{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   271
goal Nat.thy "m+Suc(n) = Suc(m+n)";
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   272
{\out Level 0}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   273
{\out m + Suc(n) = Suc(m + n)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   274
{\out  1. m + Suc(n) = Suc(m + n)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   275
\ttbreak
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   276
by (res_inst_tac [("n","m")] induct 1);
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   277
{\out Level 1}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   278
{\out m + Suc(n) = Suc(m + n)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   279
{\out  1. 0 + Suc(n) = Suc(0 + n)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   280
{\out  2. !!x. x + Suc(n) = Suc(x + n) ==> Suc(x) + Suc(n) = Suc(Suc(x) + n)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   281
\ttbreak
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   282
by (simp_tac add_ss 1);
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   283
{\out Level 2}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   284
{\out m + Suc(n) = Suc(m + n)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   285
{\out  1. !!x. x + Suc(n) = Suc(x + n) ==> Suc(x) + Suc(n) = Suc(Suc(x) + n)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   286
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   287
Switching tracing on illustrates how the simplifier solves the remaining
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   288
subgoal: 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   289
\begin{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   290
trace_simp := true;
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   291
by (asm_simp_tac add_ss 1);
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   292
{\out Rewriting:}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   293
{\out Suc(x) + Suc(n) == Suc(x + Suc(n))}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   294
{\out Rewriting:}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   295
{\out x + Suc(n) == Suc(x + n)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   296
{\out Rewriting:}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   297
{\out Suc(x) + n == Suc(x + n)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   298
{\out Rewriting:}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   299
{\out Suc(Suc(x + n)) = Suc(Suc(x + n)) == True}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   300
{\out Level 3}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   301
{\out m + Suc(n) = Suc(m + n)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   302
{\out No subgoals!}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   303
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   304
As usual, many variations are possible.  At Level~1 we could have solved
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   305
both subgoals at once using the tactical \ttindex{ALLGOALS}:
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   306
\begin{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   307
by (ALLGOALS (asm_simp_tac add_ss));
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   308
{\out Level 2}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   309
{\out m + Suc(n) = Suc(m + n)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   310
{\out No subgoals!}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   311
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   312
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   313
\medskip
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   314
Here is a conjecture to be proved for an arbitrary function~$f$ satisfying
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   315
the law $f(Suc(n)) = Suc(f(n))$:\footnote{The previous
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   316
  simplifier required congruence rules for such function variables in
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   317
  order to simplify their arguments.  The present simplifier can be given
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   318
  congruence rules to realize non-standard simplification of a function's
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   319
  arguments, but this is seldom necessary.}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   320
\begin{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   321
val [prem] = goal Nat.thy
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   322
    "(!!n. f(Suc(n)) = Suc(f(n))) ==> f(i+j) = i+f(j)";
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   323
{\out Level 0}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   324
{\out f(i + j) = i + f(j)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   325
{\out  1. f(i + j) = i + f(j)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   326
{\out val prem = "f(Suc(?n)) = Suc(f(?n))  [!!n. f(Suc(n)) = Suc(f(n))]" : thm}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   327
\ttbreak
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   328
by (res_inst_tac [("n","i")] induct 1);
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   329
{\out Level 1}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   330
{\out f(i + j) = i + f(j)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   331
{\out  1. f(0 + j) = 0 + f(j)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   332
{\out  2. !!x. f(x + j) = x + f(j) ==> f(Suc(x) + j) = Suc(x) + f(j)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   333
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   334
We simplify each subgoal in turn.  The first one is trivial:
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   335
\begin{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   336
by (simp_tac add_ss 1);
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   337
{\out Level 2}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   338
{\out f(i + j) = i + f(j)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   339
{\out  1. !!x. f(x + j) = x + f(j) ==> f(Suc(x) + j) = Suc(x) + f(j)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   340
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   341
The remaining subgoal requires rewriting by the premise, so we add it to
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   342
{\tt add_ss}: 
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   343
\begin{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   344
by (asm_simp_tac (add_ss addsimps [prem]) 1);
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   345
{\out Level 3}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   346
{\out f(i + j) = i + f(j)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   347
{\out No subgoals!}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   348
\end{ttbox}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   349
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   350
No documentation is available on setting up the simplifier for new logics.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   351
Please consult {\tt FOL/simpdata.ML} to see how this is done, and {\tt
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   352
  FOL/simpdata.ML} for a fairly sophisticated translation of formulae into
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   353
rewrite rules.
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   354
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   355
%%\section{Setting up the simplifier} \label{SimpFun-input}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   356
%%Should be written!
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   357
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   358
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   359
\index{simplification|)}
d8205bb279a7 Initial revision
lcp
parents:
diff changeset
   360