%\newcommand{\fix}{\marginpar{FIX}}
%\newcommand{\new}{\marginpar{NEW}}
%\newcommand{\classmap}{H}
%\newcommand{\linearize}{H_0}
%\newcommand{\linear}{L}
%\newcommand{\FC}{{\mathcal D}}
%\example
Denote $\phi^{\ell}=(\phi^{\ell}_{i,j})\in \mathbb R^{m_{\ell}\times n_{\ell}}$,
by the definitions of convolution \eqref{con1} and stride \eqref{stride}, \eqref{basis:plongation} means that
$$
 \phi^{\ell+1}=R\ast_2 \phi^{{\ell}},
$$
where
\begin{equation}\label{bi-restrict}
R=
%\left\{
\begin{cases}
	\begin{pmatrix}
	\frac{1}{4} &\frac{1}{2}&\frac{1}{4}\\
	\frac{1}{2}& 1&\frac{1}{2}\\
	\frac{1}{4}&\frac{1}{2}&  \frac{1}{4}
	\end{pmatrix}
	\hbox{~~for bilinear functions};\\
	\begin{pmatrix}
	0 &\frac{1}{2}&\frac{1}{2}\\
	\frac{1}{2}& 1&\frac{1}{2}\\
	\frac{1}{2}&\frac{1}{2}&  0
	\end{pmatrix}
	\hbox{~~for linear functions}.
	\end{cases}
	%\right.
	\end{equation}
\section{Deconvolution}
For any linear mapping $\mathcal C: \mathbb{R}^{m\times n} \mapsto \mathbb{R}^{m'\times n'}$,
its transpose is the unique linear mapping $\mathcal C^\top: \mathbb{R}^{m'\times n'} \mapsto \mathbb{R}^{m\times n}$
satisfying
$$
(\mathcal C^\top u, v)_{l^2}=(u, \mathcal C v)_{l^2}~~~\forall~u\in \mathbb{R}^{m'\times n'} , v\in \mathbb{R}^{m\times n}
$$
Associated with any kernel $K$, a deconvolution is defined as the transpose of convolution
with stride $2$ with respect to the $l^2$-inner product as:
\begin{equation}\label{eq:def_deconv}
 (u, K \ast_2^\top v)_{l^2}=(K \ast_2 u, v)_{l^2},
\end{equation}
with
\begin{equation}
u \in \mathbb{R}^{m \times n} \quad \text{and} \quad v \in \mathbb{R}^{\frac{m+1}{2} \times \frac{m+1}{2}}.
\end{equation}

\begin{lemma}\label{lemm:tilde-K}
For any $K \in \mathbb{R}^{(2k+1) \times (2k+1)}$,
\begin{equation}\label{eq:}
K\ast_2^\top = {\tilde K}\ast \mathcal S^\top,
\end{equation}
where $\tilde K$ is defined as
\begin{equation}\label{eq:def_tildeK}
\tilde K_{p,q} = K_{-p, -q}, \quad p,q = -k:k.
\end{equation}
Intuitively, if we take $K_{0,0}$ as the center for the convolutional kernel $K$,
then $\tilde K$ is the central symmetry of $K$.
In 2D case, it can also be understood as the rotation of $\pi$ with respect to
the center $K_{0,0}$.
\end{lemma}

Recalling the definition of deconvolution in \eqref{eq:def_deconv}, we have
\begin{equation}\label{eq:op_deconv}
\begin{aligned}
(u,  K \ast_2^\top v)_{l^2} &= (K \ast_2 u, v)_{l^2} = (\mathcal S \mathcal C_K u, v)_{l^2} \\
&= (u,  \mathcal C^\top_K \mathcal S^\top v)_{l^2},
\end{aligned}
\end{equation}
with definition
\begin{equation}\label{eq:de_stride_dim}
\mathcal S^\top:   \mathbb{R}^{\frac{m+1}{2} \times\frac{n+1}{2}} \mapsto \mathbb{R}^{m\times n},
\end{equation}
and
\begin{equation}\label{eq:de_stride}
[\mathcal S^\top (f)]_{i,j} =
\begin{cases}
0 \quad &\text{if i or j is even}, \\
f_{i/2, j/2}, \quad &\text{else}.
\end{cases}
\end{equation}

Thus to say, we have the simple version of the deconvolution for $K \ast $ as
\begin{equation}\label{eq:simple_deconv}
K \ast_2^\top v = \mathcal C_K^\top \circ \mathcal S^\top (v) = \mathcal C_{\tilde K} \circ \mathcal S^\top (v) = \tilde K \ast \mathcal S^\top (v),
\end{equation}
thus to say
\begin{equation}\label{eq:final}
K \ast_2^\top  = \tilde K \ast \mathcal S^\top.
\end{equation}

In short, we have the next decomposition
\begin{itemize}
	\item convolution with stride = stride $ \circ$ convolution,
	\item deconvolution with stride  = transposed convolution $\circ$ transposed stride = convolution with the central symmetry of original kernel $\circ$ transposed stride.
\end{itemize}

\begin{theorem}\label{thm:deconv_op}

Let us consider
\begin{equation}
K=(K_{p,q}),~~p,q = -1, 0, 1.
\end{equation}
Then we have
$$
K \ast_2^\top v = \tilde K \ast \mathcal S^\top (v).
$$
As in \eqref{eq:de_stride} and the Lemma \ref{lemm:tilde-K}, we have the
final version is
\begin{equation}
\label{eq:7}
[K \ast_2^\top v ]_{2i,2j}=  K_{0,0}v_{i,j},
\end{equation}
with
\begin{equation}
\label{eq:9}
[K \ast_2^\top v ]_{2i-1, 2j} = K_{0,1}v_{i-1,j} + K_{0,-1}v_{i,j}, \quad
[K \ast_2^\top v ]_{2i, 2j-1} = K_{1,0}v_{i,j} + K_{-1,0}v_{i,j-1},
\end{equation}
and
\begin{equation}
%\begin{tiny}
%{\scriptsize
[K \ast_2^\top v ]_{2i-1, 2j-1}  =
K_{1,1}v_{i,j} + K_{-1,1}v_{i-1,j} + K_{1,-1}v_{i,j-1} + K_{-1,-1}v_{i-1,j-1}.
%\end{tiny}
%}
\end{equation}
\end{theorem}
\begin{remark}
Deconvolution can obviously be also defined for general stride $s$, but we believe it is sufficient to use $s=2$
in most applications.
\end{remark}

\section{Linear feature mappings}
We consider the following linear mapping
\begin{equation}
  \label{feature-map}
\mathbf A\mathbf u=\mathbf  f
\end{equation}
where
\begin{equation}
  \label{map-A}
\mathbf A: \mathcal V\mapsto \mathcal V'.
\end{equation}
For example, for the elliptic problem \eqref{laplace}, $(\mathbf A \mathbf u, \mathbf v)=(\nabla u_h, \nabla v_h)$.
We consider the restriction of the mapping $\mathbf A_1\equiv \mathbf A$ on the coarser multilevel spaces:
\begin{equation}
  \label{map-A-ell}
\mathbf A_{\ell}: \mathcal V_\ell\mapsto \mathcal V'_\ell
\end{equation}
and the corresponding equation read as:
\begin{equation}
  \label{feature-map-ell}
\mathbf A_\ell \mathbf u^\ell=\mathbf f^\ell.
\end{equation}
In image process, we can view $\mathbf f$ as the input images and $\mathbf u$ as the extracted features of the original image $\mathbf f$.  We then view $\mathbf f^\ell$ as the projection of images on a coarser resolution and $\mathbf u^\ell$ as the extracted features of the coarsened image $\mathbf f^\ell$.

One main question is how to obtain coarser images and features defined by \eqref{feature-map-ell} from the original equation \eqref{feature-map}.  We now consider a special technique.

We define $\mathbf u^\ell\in \mathcal V_\ell$ by
\begin{equation}
  \label{u_ell}
(\mathbf A\mathbf u^\ell,\mathbf v^\ell)=  (\mathbf f,\mathbf v^\ell), \quad\forall \mathbf v^\ell\in\mathcal V_\ell
\end{equation}
\begin{lemma}
The restricted $\mathbf u^\ell\in\mathcal V_\ell$ defined by \eqref{u_ell} satisfies \eqref{feature-map-ell} if
$\mathbf A_\ell: \mathcal V_\ell\mapsto \mathcal V_\ell'$ and $\mathbf f_\ell\in \mathcal V_\ell'$ are defined by
\begin{equation}
  \label{A-ell}
(\mathbf A_\ell \mathbf u^\ell,\mathbf v^\ell)=  (\mathbf A\mathbf u^\ell,\mathbf v^\ell), \quad\forall \mathbf v^\ell\in\mathcal V_\ell
\end{equation}
\begin{equation}
  \label{u-ell}
(\mathbf f^\ell,\mathbf v^\ell)=  (\mathbf f,\mathbf v^\ell), \quad\forall \mathbf v^\ell\in\mathcal V_\ell
\end{equation}
\end{lemma}

\section{Restriction and prolongation under the convolution notation}
Now we derive the restriction and prolongation as follows. We show the details for the case of bilinear functions here. The
case of linear function can be shown similarly.
Let $f_{i,j}^{\ell+1}=(\mathbf f^\ell,\phi^{\ell+1}_{i,j})_{L^2(\Omega)}$, then we have
\begin{equation}
\begin{split}
  f^{\ell+1}&=\int_{\Omega} \mathbf f^\ell \phi^{\ell+1}=\sum\limits_{i=1}^{m_\ell}\sum\limits_{j=1}^{n_\ell}
 \int_{\Omega}f_{i,j}^{\ell}\psi_{i,j}^\ell\left[(R\ast_2) \phi^\ell\right]
=\sum\limits_{i=1}^{m_\ell}\sum\limits_{j=1}^{n_\ell} f_{i,j}^{\ell}(R\ast_2)\int_{\Omega}\psi_{i,j}^\ell \phi^\ell\\
&=\sum\limits_{i=1}^{m_\ell}\sum\limits_{j=1}^{n_\ell}(R\ast_2)f_{i,j}^{\ell}e_ie_j^T=R\ast_2 f^{\ell}.
\end{split}
\end{equation}
Hence the restriction
$$
R^{\ell+1}_\ell: \mathbb R^{m_{\ell}\times n_{\ell}}\mapsto  \mathbb R^{m_{\ell+1}\times n_{\ell+1}}
$$
is obtain by $R^{\ell+1}_\ell  f^{\ell}= R\ast_2  f^{\ell}$ with $R\in \mathbb R^{3\times 3}$ given by  \eqref{bi-restrict}, namely
\begin{equation}\label{restriction:freedom}
\begin{split}
f_{i,j}^{\ell+1}&=f^{\ell}_{2i,2j}+\frac{1}{2}(f^{\ell}_{2i-1,2j}+f^{\ell}_{2i,2j-1}+f^{\ell}_{2i+1,2j}+f^{\ell}_{2i,2j+1})\\
&+\frac{1}{4}\left(f^{\ell}_{2i-1,2j-1}+f^{\ell}_{2i+1,2j-1}+f^{\ell}_{2i+1,2j+1}+f^{\ell}_{2i-1,2j+1}\right).
\end{split}
\end{equation}

Next
let $\mathbf u^{\ell+1}=\sum\limits_{i=1}^{m_{\ell+1}}\sum\limits_{j=1}^{n_{\ell+1}}u_{i,j}^{\ell+1}\phi^{\ell+1}_{i,j}
=( \mathbf u^{\ell+1}, \phi^{\ell+1})_{l^2}$, then we have
\begin{equation}
\begin{split}
\mathbf u^{\ell+1}&=( u^{\ell+1}, \phi^{\ell+1})_{l^2}
=( u^{\ell+1}, R\ast_2\phi^{\ell})_{l^2}=(R\ast_2^{\top} u^{\ell+1}, \phi^{\ell})_{l^2}\\
&=\sum\limits_{i=1}^{m_{\ell}}\sum\limits_{j=1}^{n_{\ell}}\left(R\ast_2^{\top} u^{\ell+1}\right)_{i,j}\phi^{\ell}_{i,j}.
\end{split}
\end{equation}
Namely
$$
\mathbf u^{\ell+1}(x_i^\ell,y_j^\ell)=\left(R\ast_2^{\top} u^{\ell+1}\right)_{i,j}.
$$
And we obtain the prolongation
$$
P_{\ell+1}^\ell=R\ast_2^{\top} : \mathbb R^{m_{\ell+1}\times n_{\ell+1}}\mapsto  \mathbb R^{m_{\ell}\times n_{\ell} }
$$
is defined by
$$
u^\ell_{2i,2j}=u^{\ell+1}_{i,j},
$$
$$
u^\ell_{2i-1,2j}=\frac{1}{2}(u^\ell_{i,j}+u^\ell_{i-1,j}),~~~ u^\ell_{2i,2j-1}=\frac{1}{2}(u^{\ell+1}_{i,j}+u^{\ell+1}_{i,j-1})
$$
and
$$
u^\ell_{2i-1,2j-1}=\frac{1}{4}(u^{\ell+1}_{i,j}+u^{\ell+1}_{i-1,j}+u^{\ell+1}_{i-1,j-1}+u^{\ell+1}_{i,j-1}).
$$
In summery, we have the restriction and prolongation as follows:
\begin{lemma}\label{ris:plon}
The restriction
$$
R^{\ell+1}_\ell: \mathbb R^{m_\ell\times n_\ell}\mapsto  \mathbb R^{m_{\ell+1}\times n_{\ell+1}}~~\hbox{is}~~ R^{\ell+1}_\ell = R\ast_2
$$
and the prolongation
$$
P_{\ell+1}^{\ell}: \mathbb R^{m_{\ell+1}\times n_{\ell+1}}\mapsto  \mathbb R^{m_{\ell}\times n_{\ell} } ~~\hbox{is}~~ P^{\ell}_{\ell+1} =R\ast_2^{\top}
$$
where
\begin{equation}\label{bi-restrict1}
R=
%\left\{
\begin{cases}
	\begin{pmatrix}
	\frac{1}{4} &\frac{1}{2}&\frac{1}{4}\\
	\frac{1}{2}& 1&\frac{1}{2}\\
	\frac{1}{4}&\frac{1}{2}&  \frac{1}{4}
	\end{pmatrix}
	\hbox{~~for bilinear functions};\\
	\begin{pmatrix}
	0 &\frac{1}{2}&\frac{1}{2}\\
	\frac{1}{2}& 1&\frac{1}{2}\\
	\frac{1}{2}&\frac{1}{2}&  0
	\end{pmatrix}
	\hbox{~~for linear functions}.
	\end{cases}
	%\right.
	\end{equation}
\end{lemma}

Let $(\phi^{\ell}_{i,j})$ is a basis of $\mathcal V_\ell$, for any $\mathbf u^\ell \in \mathcal V_\ell$, then $\mathbf u^{\ell}=\sum\limits_{i=1}^{m_{\ell}}\sum\limits_{j=1}^{n_{\ell}}u_{i,j}^{\ell}\phi^{\ell}_{i,j}$, and we denote $u^\ell=(u_{i,j}^{\ell})\in  \mathbb R^{m_{\ell}\times n_{\ell} }$ the matrix representation of $\mathbf u^\ell$ under the basis $(\phi^{\ell}_{i,j})$.
Let $(\psi^{\ell}_{s,t})$ is a basis of $\mathcal V'_\ell$ which is dual to $(\phi^{\ell}_{i,j})$. Denote $A_\ell=(a_{stij}^{\ell})$ the tensor representation of $\mathbf A_\ell: \mathcal V_\ell\mapsto \mathcal V'_\ell $ and defined as
$$
\mathbf A_\ell \phi^\ell_{i,j}=\sum\limits_{s=1}^{m_{\ell}}\sum\limits_{t=1}^{n_{\ell}}a_{stij}^{\ell}\psi^\ell_{s,t}.
$$
Hence $a_{stij}^{\ell}=(\mathbf A_\ell \phi^\ell_{i,j}, \phi^\ell_{s,t})$. From $(\mathbf A_{\ell+1}\phi^{\ell+1}_{i,j}, \phi^{\ell+1}_{s,t})=(\mathbf A_\ell\phi^{\ell+1}_{i,j}, \phi^{\ell+1}_{s,t})$, we have
$$
a_{stij}^{\ell+1}=\sum_{r=1}^{m_\ell}\sum_{q=1}^{n_\ell}\left(\sum_{k=1}^{m_\ell}\sum_{m=1}^{n_\ell} P_{kmij}^{\ell,{\ell+1}} a_{rqkm}^\ell\right)P_{rqst}^{\ell,{\ell+1}}
$$
Where $P^{\ell,{\ell+1}}=(P_{rqst}^{\ell,{\ell+1}})$ is the tensor representation of the prolongation $P_{\ell+1}^{\ell}$.

Consider the finite element method on two different grids
$\mathcal T_\ell,~\mathcal T_{\ell+1},~h_{\ell+1}=2h_\ell, \mathcal V_{\ell+1}\subset \mathcal V_{\ell}$.
With the restriction $R_{\ell}^{\ell+1}$ and prolongation $P_{\ell+1}^\ell$ obtained in Lemma \ref{ris:plon}, we have the following relationship to define coarse operation
\begin{equation}\label{eq:def_coarse}
\begin{aligned}
 A_{\ell+1}&=R_{\ell}^{\ell+1}  A_{\ell}P_{\ell+1}^{\ell}.  \\
&= R \ast_2 A_\ell \ast (R\ast_2^\top),   \quad (\ell = 1:J-1),
\end{aligned}
\end{equation}
with $A_1 = A$.
\begin{theorem}
If $R$ is consistent with $A_\ell$ which means that $R$ should be linear or bi-linear as $A_\ell$, then we have
the $A_{\ell+1}$ operation in coarse grid defined in \eqref{eq:def_coarse} is the same with $A_\ell$.
\end{theorem}
\begin{proof}
For any $u_{\ell+1}$ and $v_{\ell+1}$ in $\mathcal V_{\ell+1}$, it remains to prove that
$$
(A_\ell P_{\ell+1}^\ell u_{\ell+1},P_{\ell+1}^\ell v_{\ell+1}) = (A_{\ell+1}u_{\ell+1}, v_{\ell+1})
$$
where $A_\ell$ and $A_{\ell+1}$ are the tensor representation of $\mathbf A_\ell$ and $\mathbf A_{\ell+1}$.

We can also view them as convolutions. By the definition of operators $R_{\ell}^{\ell+1}$ and $P_{\ell+1}^\ell$, a direct computation gives the above result.
\end{proof}
\begin{proof}
By the definition above, we have that
\begin{equation}
A_{\ell+1} (v) = \mathcal S\left( (R\ast A_{\ell} \ast R )\ast \mathcal S^\top(v) \right),
\end{equation}
because of the properties of convolution we know that
\begin{equation}\label{eq:K=RAR}
(R\ast A_{\ell} \ast R )\ast = K \ast,
\end{equation}
for some
$$
K \in \mathbb{R}^{7\times 7}.
$$
Then we have the next computation for $A_{\ell+1}(v)$
\begin{equation}\label{eq:compute_A}
\begin{aligned}
[A_{\ell+1} (v)]_{i,j} &= [\mathcal S\left( (R\ast A_{\ell} \ast R )\ast \mathcal S^\top(v) \right)]_{i,j}, \\
&= [ K\ast  \mathcal S^\top(v)]_{2i,2j}, \\
&= \sum_{p,q=-3}^{3} [\mathcal S^\top (v)]_{2i+p, 2j+q} K_{p,q}, \\
&= \sum_{p,q=-1}^1  [\mathcal S^\top (v)]_{2(i+p), 2(j+q)} K_{2p,2q}, \\
&= \sum_{p,q=-1}^1  v_{i+p, j+q} \hat K_{p,q}, \\
\end{aligned}
\end{equation}

Thus to say, we have
\begin{equation}
A_{\ell+1}(v) =  \hat K \ast v,
\end{equation}
with
$$
\hat K_{p,q} = K_{2p,2q}, \quad p,q = -1,0,1,
$$
with $K$ is defined in \eqref{eq:K=RAR}.

Then by the direct computation of \eqref{eq:K=RAR} as
$$
(R\ast A_{\ell} \ast R )\ast = K \ast
$$
and take the even index we have that
\begin{equation}
A_{\ell+1} = \hat K = A_\ell,
\end{equation}
if $R$ is consistent with $A_\ell$ which means that $R$ should be linear or bi-linear as $A_\ell$.
\end{proof}

497-6DL/8 Convolutional Multigrid Method/8.11-XuNet.tex


% !TEX root = ../thesis.tex

\chapter{Introduction}
One of the problems in plasma physics is the issue of plasma confinement.
How does one confine a dense plasma to a reactor vessel for a sustained period of time?
Plasmas are extremely hot,
so any contact with the walls of a reactor would be fatal.
Solving this problem is an important step towards nuclear fusion,
a sustainable energy source that unlike nuclear fission does not produce radioactive byproducts.
Current efforts focus on repelling the plasma
from the walls of the reactor with intense magnetic fields,
although other options might be feasible.
One approach is that of self-stability,
where the magnetic field of the plasma prevents it from deforming too much.
In this thesis we will investigate how self-stability can arise,
and we will construct a few magnetic fields with desirable properties.

As we will see,
linking of the field lines is important for these magnetic fields.
This leads us to the Hopf map,
a differentiable function from $S^3$ to $S^2$ of which the fibres,
the inverse images of points on $S^2\!$,
are linked.
Before we can define the Hopf map,
we will recall some of the theory involved in chapter~\ref{chap:preliminaries},
and we will investigate a few useful group actions.
In chapter~\ref{chap:the-hopf-map} we will turn to the Hopf map itself.
Via stereographic projection we can visualise the fibres in $\R^3\!$,
and with ideas from topology we can quantify linking of the fibres.
To construct a vector field with field lines
based on the fibres of the Hopf map,
we use tools from differential geometry developed in chapter~\ref{chap:differential-forms}.
Finally we make the link to magnetohydrodynamics in chapter~\ref{chap:magnetohydrodynamics}.
The Hopf invariant,
a quantity that appears purely algebraic at first sight,
will turn out to have a direct physical interpretation as the helicity of a field,
a conserved quantity that plays a role in the stability of plasmas.

Chapter~\ref{chap:preliminaries} through~\ref{chap:differential-forms}
are mathematical in nature.
For physicists who are not familiar with the formalism,
or who care about results instead of proofs,
a paragraph with “physical interpretation” has been added after every section whenever possible.
When the theory does not admit a direct physical interpretation,
a paragraph “informal summary” has been added instead.


\chapter{Example: Euclid's Theorem}
\label{chap:euclid}

\setcounter{sessioncount}{0}

In this chapter, we prove in \holn{} that for every number, there is a
prime number that is larger, \ie, that the prime numbers form an
infinite sequence. This proof has been excerpted and adapted from a
much larger example due to John Harrison, in which he proved the $n =
4$ case of Fermat's Last Theorem. The proof development is intended
to serve as an introduction to performing high-level interactive proofs
in \holn.\footnote{The proofs discussed below may be found in
\texttt{examples/euclid.sml} of the \HOL{} distribution.}
Many of the details may be difficult to grasp for the novice reader;
nonetheless, it is recommended that the example be followed through in
order to gain a true taste of using \HOL{} to prove non-trivial theorems.

Some tutorial descriptions of proof systems show the system performing
amazing feats of automated theorem proving. In this example, we have
\textit{not} taken this approach; instead, we try to show how one
actually goes about the business of proving theorems in \holn{}: when
more than one way to prove something is possible, we will consider the
choices; when a difficulty arises, we will attempt to explain how to fight
one's way clear.

One `drives' \holn{} by interacting with the ML top-level loop. In this
interaction style, ML function calls are made to bring in
already-established logical context, \eg, via \ml{load}; to define
new concepts, \eg, via \ml{Hol\_datatype},  \ml{Define}, and \ml{Hol\_reln};
and to perform proofs using the goalstack interface, and
the proof tools from \ml{bossLib} (or if they fail to do the job, from
lower-level libraries).

Let's get started. First, we start the system, with the command \ml{<holdir>/bin/hol}.
We then ``\ml{open}'' the arithmetic theory; this means that all of the \ML{} bindings
from the \HOL{} theory of arithmetic are made available at the top level.
\begin{session}
\begin{verbatim}
- open arithmeticTheory;
  ...
\end{verbatim}
\end{session}
We now begin the formalization. In order to define the concept of
prime number, we first need to define the \emph{divisibility} relation:

\begin{session}
\begin{verbatim}
- val divides_def = Define `divides a b = ?x. b = a * x`;

Definition has been stored under "divides_def".
> val divides_def = |- !a b. divides a b = ?x. b = a * x : thm
\end{verbatim}
\end{session}

The definition is added to the current theory with the name
\ml{divides\_def}, and also returned from the invocation of
\ml{Define}. We take advantage of this and make an \ML{} binding of
the name \ml{divides\_def} to the definition. In the usual way of
interacting with \HOL, such an \ML{} binding is made for each
definition and (useful) proved theorem: the \ML{} environment is thus
being used as a convenient place to hold definitions and theorems for
later reference in the session.

We want to treat \ml{divides} as a (non-associating) infix:
\begin{session}
\begin{verbatim}
- set_fixity "divides" (Infix(NONASSOC, 450));
\end{verbatim}
\end{session}
Next we define the property of a number being \emph{prime}: a number $p$ is
prime if and only if it is not equal to $1$ and it has no divisors other
than $1$ and itself:

\begin{session}
\begin{verbatim}
- val prime_def =
    Define `prime p = ~(p=1) /\ !x. x divides p ==> (x=1) \/ (x=p)`;

Definition has been stored under "prime_def".
> val prime_def =
    |- !p. prime p = ~(p = 1) /\ !x. x divides p ==> (x = 1) \/ (x = p)
    : thm
\end{verbatim}
\end{session}

That concludes the definitions to be made. Now we ``just'' have to prove
that there are infinitely many prime numbers. If we were coming to this
problem fresh, then we would have to go through a not-well-understood
and often tremendously difficult process of finding the right lemmas
required to prove our target theorem.\footnote{This is of course a
general problem in doing any kind of proof.} Fortunately, we are working
from an already completed proof and can devote ourselves to the far
simpler problem of explaining how to prove the required theorems.

\paragraph{Proof tools}
The development will illustrate that there is often more than one way to
tackle a HOL proof, even if one has only a single (informal) proof in
mind. In this example, we often \emph{find} proofs by using
the rewriter \ml{RW\_TAC} to unwind definitions and perform basic
simplifications, often reducing a goal to its essence.
\begin{session}
\begin{verbatim}
RW_TAC;
val it = fn :simpset -> thm list -> term list * term ->
             (term list * term) list * (thm list -> thm)
\end{verbatim}
\end{session}
The ML type of \ml{RW\_TAC} is
\ml{:simpset -> thm list -> tactic}.\footnote{Unfortunately, the MoscowML system does not print out
the type of tactics in its abbreviated form.}
When \ml{RW\_TAC} is applied to a \textit{simpset}---for this example it will
always be \ml{arith\_ss}---and a list of theorems, the
theorems will be added to the simpset as supplementary rewrite rules.
We will see that \ml{arith\_ss} is also somewhat knowledgeable about
arithmetic.\footnote{Linear arithmetic especially: purely universal
formulas involving the operators {\tt SUC}, $+$, $-$, numeric
literals, $<$, $\leq$, $>$, $\geq$, $=$, and multiplication by numeric
literals.}
Sometimes simplification with \ml{RW\_TAC} proves the goal immediately.
Often however, we are left with a goal that requires some study before one
realizes what lemmas are needed to conclude the proof. Once these lemmas
have been proven, or located in ancestor theories,
\ml{METIS\_TAC}\footnote{\ml{METIS\_TAC}
performs resolution-style first-order proof search.} can
be invoked with them, with the expectation that it will find the right
instantiations needed to finish the proof. Note that these two operations,
simplification and resolution-style automatic proof search, will not suffice to
perform all the proofs in this example; in particular, our development will
also need case analysis and induction.

\paragraph{Finding theorems}
This raises the following question: how does one find the right lemmas
and rewrite rules to use? This is quite a problem, especially since the number of
ancestor theories, and the theorems in them,  is large. There are several
possibilities
\begin{itemize}
\item The help system can be used to look up definitions and
theorems, as well as proof procedures; for example, an invocation of
{\small
\begin{verbatim}
   help "arithmeticTheory"
\end{verbatim}}
will display all the definitions and theorems that have been stored in
the theory of arithmetic. However, the complete name of the item being
searched for must be known before the help system is useful, so the following
two search facilities are often more useful.
\item  \verb+DB.match+ allows the use of patterns to locate the
sought-for theorem. Any stored theorem having an instance of the pattern
as a subterm will be returned.
\item \verb+DB.find+ will use fragments of names as keys with which to
lookup information.
\end{itemize}

\paragraph{Tactic composition}
Once a proof of a proposition has been found, it is customary, although
not necessary, to embark on a process of \emph{revision}, in which the
original sequence of tactics is composed into a single tactic. Sometimes
the resulting tactic is much shorter, and more aesthetically pleasing in
some sense. Some users spend a fair bit of time polishing these tactics,
although there doesn't seem much real benefit in doing so, since they
are \emph{ad hoc} proof recipes, one for each theorem. In the
following, we will show how this is done in a few cases.

\section{Divisibility}

We start by proving a number of theorems about the \verb+divides+
relation.  We will see that each of these initial theorems can be
proved with a single invocation of \ml{METIS\_TAC}. Both \ml{RW\_TAC}
and \ml{METIS\_TAC} are quite powerful reasoners, and the choice of a
reasoner in a particular situation is a matter of experience.  The
major reason that \ml{METIS\_TAC} works so well is that \verb+divides+
is defined by means of an existential quantifier, and \ml{METIS\_TAC}
is quite good at automatically instantiating existentials in the
course of proof. For a simple example, consider proving $\forall x.\
x\; \mathtt{divides}\; 0$. A new proposition to be proved is entered
to the proof manager via ``\ml{g}'', which starts a fresh goalstack:

\begin{session}
\begin{verbatim}
- g `!x. x divides 0`;

> val it =
    Proof manager status: 1 proof.
    1. Incomplete:
         Initial goal:
         !x. x divides 0

     : proofs
\end{verbatim}
\end{session}
The proof manager tells us that it has only one proof to manage, and
echoes the given goal.  Now we expand the definition of
\verb+divides+. Notice that $\alpha$-conversion takes place in order to
keep distinct the $x$ of the goal and the $x$ in the definition of
\ml{divides}:
\begin{session}
\begin{verbatim}
- e (RW_TAC arith_ss [divides_def]);

OK..
1 subgoal:
> val it =
    ?x'. (x = 0) \/ (x' = 0)
\end{verbatim}
\end{session}
It is of course quite easy to instantiate the existential quantifier by
hand.
\begin{session}
\begin{verbatim}
- e (EXISTS_TAC ``0``);

OK..
1 subgoal:
> val it =
    (x = 0) \/ (0 = 0)
\end{verbatim}
\end{session}
Then a simplification step finishes the proof.
\begin{session}
\begin{verbatim}
- e (RW_TAC arith_ss []);
OK..

Goal proved.
|- (x = 0) \/ (0 = 0)

Goal proved.
|- ?x'. (x = 0) \/ (x' = 0)
> val it =
    Initial goal proved.
    |- !x. x divides 0
\end{verbatim}
\end{session}

What just happened here? The application of \ml{RW\_TAC} to the goal
decomposed it to an empty list of subgoals; in other words the goal was
proved by \ml{RW\_TAC}.  Once a goal has been proved, it is popped off
the goalstack, prettyprinted to the output, and the theorem becomes
available for use by the level of the stack. When all the sub-goals
required by \textit{that} level are proven, the corresponding goal at
that level can be proven too.  This `unwinding' process continues until
the stack is empty, or until it hits a goal with more than one remaining
unproved subgoal. This process may be hard to
visualize,\footnote{Perhaps since we have used a stack to implement what
is notionally a tree!} but that doesn't matter, since the goalstack was
expressly written to allow the user to ignore such details.

If the three interactions are joined together with \ml{THEN} to
form a single tactic, we can try the proof again from the
beginning (using the \ml{restart} function) and this time it will
take just one step:
\begin{session}
\begin{verbatim}
- restart();
>   ...

- e (RW_TAC arith_ss [divides_def] THEN EXISTS_TAC ``0``
     THEN RW_TAC arith_ss []);
OK..

> val it =
    Initial goal proved.
    |- !x. x divides 0
\end{verbatim}
\end{session}
We have seen one way to prove the theorem. However, as mentioned
earlier, there is another: one can let \ml{METIS\_TAC} expand the
definition of \ml{divides} and find the required instantiation for
\verb+x'+ from the theorem \ml{MULT\_CLAUSES}.\footnote{You might
  like to try typing \ml{MULT\_CLAUSES} into the interactive loop
  to see exactly what it states.}
\begin{session}
\begin{verbatim}
- restart();
>   ...

- e (METIS_TAC [divides_def, MULT_CLAUSES]);
OK..
metis: r[+0+10]+0+0+0+1+2#
> val it =
    Initial goal proved.
    |- !x. x divides 0
\end{verbatim}
\end{session}
As it runs, \ml{METIS\_TAC} prints out some possibly interesting
diagnostics. In any case, having done our proof inside the goalstack package,
    we now want to have access to the theorem value that we have
    proved.  We use the \ml{top\_thm} function to do this, and then
    use \ml{drop} to dispose of the stack:
\begin{session}
\begin{verbatim}
- val DIVIDES_0 = top_thm();

> val DIVIDES_0 = |- !x. x divides 0 : thm

- drop();
OK..
> val it = There are currently no proofs. : proofs
\end{verbatim}
\end{session}

We have used \ml{METIS\_TAC} in this way to prove the following
collection of theorems about \ml{divides}. As mentioned previously, the
theorems supplied to \ml{METIS\_TAC} in the following proofs did not
(usually) come from thin air: in most cases some exploratory work with
\ml{RW\_TAC} was done to open up definitions and see what lemmas would
be required by \ml{METIS\_TAC}.

\begin{description}
\label{euclid:extra-proofs}
\item [\small{({\it DIVIDES\_0\/})}]
\begin{tabular}[t]{l}
\verb+!x. x divides 0+ \\ \hline
 \verb+METIS_TAC [divides_def, MULT_CLAUSES]+
\end{tabular}

\item[\small{({\it DIVIDES\_ZERO\/})}]
\begin{tabular}[t]{l}
\verb+!x. 0 divides x = (x = 0)+ \\ \hline
 \verb+METIS_TAC [divides_def, MULT_CLAUSES]+
\end{tabular}

\item[\small{({\it DIVIDES\_ONE\/})}]
\begin{tabular}[t]{l}
\verb+!x. x divides 1 = (x = 1)+ \\ \hline
 \verb+METIS_TAC [divides_def, MULT_CLAUSES, MULT_EQ_1]+
\end{tabular}

\item[\small{({\it DIVIDES\_REFL\/})}]
\begin{tabular}[t]{l}
\verb+!x. x divides x+ \\ \hline
 \verb+METIS_TAC [divides_def, MULT_CLAUSES]+ \\
\end{tabular}

\item[\small{({\it DIVIDES\_TRANS\/})}]
\begin{tabular}[t]{l}
\verb+!a b c. a divides b /\ b divides c ==> a divides c+ \\ \hline
 \verb+METIS_TAC [divides_def, MULT_ASSOC]+ \\
\end{tabular}
\item[\small{({\it DIVIDES\_ADD\/})}]
\begin{tabular}[t]{l}
\verb|!d a b. d divides a /\ d divides b ==> d divides (a+b)| \\ \hline
 \verb|METIS_TAC [divides_def,LEFT_ADD_DISTRIB]|
\end{tabular}

\item[\small{({\it DIVIDES\_SUB\/})}]
\begin{tabular}[t]{l}
\verb+!d a b. d divides a /\ d divides b ==> d divides (a-b)+ \\ \hline
 \verb+METIS_TAC [divides_def, LEFT_SUB_DISTRIB]+ \\
\end{tabular}

\item[\small{({\it DIVIDES\_ADDL\/})}]
\begin{tabular}[t]{l}
\verb|!d a b. d divides a /\ d divides (a+b) ==> d divides b| \\ \hline
 \verb+METIS_TAC [ADD_SUB, ADD_SYM, DIVIDES_SUB]+ \\
\end{tabular}

\item[\small{({\it DIVIDES\_LMUL\/})}]
\begin{tabular}[t]{l}
\verb+!d a x. d divides a ==> d divides (x * a)+ \\ \hline
 \verb+METIS_TAC [divides_def, MULT_ASSOC, MULT_SYM]+ \\
\end{tabular}

\item[\small{({\it DIVIDES\_RMUL\/})}]
\begin{tabular}[t]{l}
\verb+!d a x. d divides a ==> d divides (a * x)+ \\ \hline
 \verb+METIS_TAC [MULT_SYM, DIVIDES_LMUL]+ \\
\end{tabular}

\end{description}

\noindent We'll assume that the above proofs have been performed, and
that the appropriate ML names have been given to all of the theorems.
Now we encounter a lemma about divisibility that doesn't succumb to a
single invocation of \ml{METIS\_TAC}:
\begin{description}
\item [\small{({\it DIVIDES\_LE\/})}]
\begin{tabular}[t]{l}
\verb+!m n. m divides n ==> m <= n \/ (n = 0)+ \\ \hline
\verb+RW_TAC arith_ss [divides_def]+ \\
\verb+   THEN Cases_on `x`+ \\
\verb+   THEN RW_TAC arith_ss [MULT_CLAUSES]+ \\
\end{tabular}
\end{description}
Let's see how this is proved. The easiest way to start is to simplify
with the definition of \ml{divides}:
\begin{session}
\begin{verbatim}
- g `!m n . m divides n ==> m <= n \/ (n = 0)`;
>   ...

- e (RW_TAC arith_ss [divides_def]);

1 subgoal:
> val it =
    m <= m * x \/ (m * x = 0)
\end{verbatim}
\end{session}

Considering the goal, we basically have three choices: (1) find a
collection of lemmas that together imply the goal and use
\ml{METIS\_TAC}; (2) do a case split on $m$; or (3) do a case split on
$x$. The first doesn't seem simple, because the goal doesn't really fit
in the `shape' of any pre-proved theorem(s) that the author knows
about. Although option (2) will be rejected in the end, let's try it
anyway. To perform the case split, we use \verb+Cases_on+, which stands
for ``find the given term in the goal and do a case split on the
possible means of building it out of datatype constructors''. Since the
occurrence of $m$ in the goal has type $num$, the cases considered will
be whether $m$ is $0$ or a successor.
\begin{session}
\begin{verbatim}
- e (Cases_on `m`);
OK..
2 subgoals:
> val it =
    SUC n <= SUC n * x \/ (SUC n * x = 0)

    0 <= 0 * x \/ (0 * x = 0)
\end{verbatim}
\end{session}
\noindent The first subgoal (the last one printed) is trivial:

\begin{session}
\begin{verbatim}
- e (RW_TAC arith_ss []);
OK..

Goal proved.
  ...

Remaining subgoals:
> val it =
    SUC n <= SUC n * x \/ (SUC n * x = 0)
\end{verbatim}
\end{session}
\noindent Let's try \ml{RW\_TAC} again:
\begin{session}
\begin{verbatim}
- e (RW_TAC arith_ss []);
OK..
1 subgoal:
> val it =
    SUC n <= x * SUC n \/ (x = 0)
\end{verbatim}
\end{session}
The right disjunct has been simplified; however, the left disjunct has
failed to expand the definition of multiplication in the expression
$\mathtt{SUC}\ n * x$, which would have been convenient. In fact, it has
changed it to $x * \mathtt{SUC}\ n$, which is inconvenient.
Why, when \verb+arith_ss+ and hence \ml{RW\_TAC} is supposed to be expert in
arithmetic? The answer is twofold: first, the recursive clauses for addition and
multiplication are not in \verb+arith_ss+ because uncontrolled
application of them by the rewriter seems, in general, to make some
proofs \emph{more} complicated, rather than simpler; second, the simplifier
will rearrange arithmetical terms to make some automated proofs simpler. So
the absence of the recursive clauses for multiplication
means that $\mathtt{SUC}\ n * x$ does not expand to $(n * x) + x$;
instead, the rearrangement yields $x * \mathtt{SUC}\; n$. OK, so let's
add in the definition of multiplication. This uncovers a new problem: how
to locate this definition. The function
\begin{holboxed}
\begin{verbatim}
   DB.match : string list -> term
                -> ((string * string) * (thm * class)) list
\end{verbatim}
\end{holboxed}

\noindent
is often helpful for such tasks. It takes a list of theory names, and
a pattern, and looks in the list of theories for any theorem,
definition, or axiom that has an instance of the pattern as a subterm.
If the list of theory names is empty, then all loaded theories are
included in the search. Let's look in the theory of arithmetic for the
subterm to be rewritten.

\begin{session}
\begin{verbatim}
- DB.match ["arithmetic"] ``SUC n * x``;

> val it =
   [(("arithmetic", "FACT"),
     (|- (FACT 0 = 1) /\ !n. FACT (SUC n) = SUC n * FACT n, Def)),
    (("arithmetic", "LESS_MULT_MONO"),
     (|- !m i n. SUC n * m < SUC n * i = m < i, Thm)),
    (("arithmetic", "MULT"),
     (|- (!n. 0 * n = 0) /\ !m n. SUC m * n = m * n + n, Def)),
    (("arithmetic", "MULT_CLAUSES"),
     (|- !m n.
           (0 * m = 0) /\ (m * 0 = 0) /\ (1 * m = m) /\ (m * 1 = m) /\
           (SUC m * n = m * n + n) /\ (m * SUC n = m + m * n), Thm)),
    (("arithmetic", "MULT_LESS_EQ_SUC"),
     (|- !m n p. m <= n = SUC p * m <= SUC p * n, Thm)),
    (("arithmetic", "MULT_MONO_EQ"),
     (|- !m i n. (SUC n * m = SUC n * i) = m = i, Thm)),
    (("arithmetic", "ODD_OR_EVEN"),
     (|- !n. ?m. (n = SUC (SUC 0) * m) \/ (n = SUC (SUC 0) * m + 1), Thm))]
   : ...
\end{verbatim}
\end{session}

For some, this returns slightly too much information; however, we can
focus the search by stipulating that the pattern look like a rewrite
rule:

\begin{session}
\begin{verbatim}
- DB.match [] ``SUC n * x = M``;

> val it =
    [(("arithmetic", "MULT"),
      (|- (!n. 0 * n = 0) /\ !m n. SUC m * n = m * n + n, Def)),
     (("arithmetic", "MULT_CLAUSES"),
      (|- !m n.
            (0 * m = 0) /\ (m * 0 = 0) /\ (1 * m = m) /\ (m * 1 = m) /\
            (SUC m * n = m * n + n) /\ (m * SUC n = m + m * n), Thm)),
     (("arithmetic", "MULT_MONO_EQ"),
      (|- !m i n. (SUC n * m = SUC n * i) = m = i, Thm))] : ...
\end{verbatim}
\end{session}

Either {\small\verb+arithmeticTheory.MULT+} or
{\small\verb+arithmeticTheory.MULT_CLAUSES+} would be acceptable; we
choose the latter.

\begin{session}
\begin{verbatim}
- b();
  ...

e (RW_TAC arith_ss [MULT_CLAUSES]);

OK..
1 subgoal:
> val it =
    SUC n <= x + n * x \/ (x = 0)
\end{verbatim}
\end{session}
Now we see that, in order to make progress in the proof, we will have to
do a case split on $x$ anyway, and that we should have split on it
originally. Hence we backup. We will have to backup (undo) three times:
\begin{session}
\begin{verbatim}
- b();
> val it =
    SUC n <= SUC n * x \/ (SUC n * x = 0)

- b();
> val it =
    SUC n <= SUC n * x \/ (SUC n * x = 0)

    0 <= 0 * x \/ (0 * x = 0)

- b();
> val it =
    m <= m * x \/ (m * x = 0)
\end{verbatim}
\end{session}

Now we can go forward and do case analysis on $x$. We will also make a
compound tactic invocation, since we already know that we'll have to
invoke \ml{RW\_TAC} in both branches of the case split. This can be
done using \ml{THEN}.  When $t_1 \ \mbox{\ml{THEN}}\ t_2$ is applied
to a goal $g$, first $t_1$ is applied to $g$, giving a list of new
subgoals, then $t_2$ is applied to each member of the list. All goals
resulting from these applications of $t_2$ are gathered together and
returned.
\begin{session}
\begin{verbatim}
- e (Cases_on `x` THEN RW_TAC arith_ss [MULT_CLAUSES]);
OK..

Goal proved.
|- m <= m * x \/ (m * x = 0)
> val it =
    Initial goal proved.
    |- !m n. m divides n ==> m <= n \/ (n = 0)
\end{verbatim}
\end{session}
That was easy! Obviously making a case split on $x$ was the right
choice. The process of {\it finding\/} the proof has now finished, and
all that remains is for the proof to be packaged up into the single
tactic we saw above.  Rather than use \ml{top\_thm} and the goalstack,
we can bypass it and use the \ml{store\_thm} function.  This function
takes a string, a term and a tactic and applies the tactic to the term
to get a theorem, and then stores the theorem in the current theory
under the given name.
\begin{session}
\begin{verbatim}
- val DIVIDES_LE = store_thm (
     "DIVIDES_LE",
     ``!m n. m divides n ==> m <= n \/ (n = 0)``,
     RW_TAC arith_ss  [divides_def]
       THEN Cases_on `x`
       THEN RW_TAC arith_ss  [MULT_CLAUSES]);

> val DIVIDES_LE = |- !m n. m divides n ==> m <= n \/ (n = 0) : thm
\end{verbatim}
\end{session}
Storing theorems in our script record of the session in this style
(rather than with the goalstack) results in a more concise script, and
also makes it easier to turn our script into a theory file, as we do
in section~\ref{sec:script-to-theory}.

\subsection{Divisibility and factorial}

The next lemma, {\small{\it DIVIDES\_FACT\/}}, says that every number
greater than $0$ and $\leq n$ divides the factorial of
$n$. Factorial is found at \verb+arithmeticTheory.FACT+ and has been
defined by primitive recursion:
\begin{description}
\item [\small{({\it FACT\/})}]
\begin{minipage}[t]{0.5\textwidth}
\begin{verbatim}
  (FACT 0 = 1) /\
  (!n. FACT (SUC n) = SUC n * FACT n)
\end{verbatim}
\end{minipage}
\end{description}
A polished proof of {\small{\it DIVIDES\_FACT\/}} is the
following\footnote{This and subsequent proofs use the theorems proved
  on page~\pageref{euclid:extra-proofs}, which were added to the \ML{} environment
  after being proved.}:
\begin{description}
\item [\small{({\it DIVIDES\_FACT\/})}]
\begin{tabular}[t]{l}
\verb+!m n. 0 < m /\ m <= n ==> m divides (FACT n)+ \\ \hline
\verb+RW_TAC arith_ss [LESS_EQ_EXISTS]+ \\
\verb+ THEN Induct_on `p`+ \\
\verb+ THEN RW_TAC arith_ss [FACT,ADD_CLAUSES]+ \\
\verb+ THENL [Cases_on `m`, ALL_TAC]+ \\
\verb+ THEN METIS_TAC [FACT, DECIDE ``!x. ~(x < x)``,+ \\
\verb+                 DIVIDES_RMUL, DIVIDES_LMUL, DIVIDES_REFL]+ \\
\end{tabular}
\end{description}
We will examine this proof in detail, so we should first attempt to
understand why the theorem is true. What's the underlying intuition?
Suppose $0 < m \leq n$, and so $\mbox{\tt FACT}\ n = 1 * \cdots * m *
\cdots * n$. To show $m\ \mbox{\tt divides}\ (\mbox{\tt FACT}\ n)$
means exhibiting a $q$ such that $q * m = \mbox{\tt FACT}\ n$. Thus $q
= \mbox{\tt FACT}\ n \div m$. If we were to take this approach to the
proof, we would end up having to find and apply lemmas about $\div$.
This seems to take us a little out of our way; isn't there a proof
that doesn't use division? Well yes, we can prove the theorem by
induction on $n - m$: in the base case, we will have to prove $n\;
\mbox{\tt divides}\ (\mbox{\tt FACT}\; n)$, which ought to be easy; in
the inductive case, the inductive hypothesis seems like it should give
us what we need. This strategy for the inductive case is a bit vague,
because we are trying to mentally picture a slightly complicated
formula, but we can rely on the system to accurately calculate the
cases of the induction for us. If the inductive case turns out to be
not what we expect, we will have to re-think our approach.
\begin{session}
\begin{verbatim}
- g `!m n. 0 < m /\ m <= n ==> m divides (FACT n)`;

> val it =
    Proof manager status: 1 proof.
    1. Incomplete:
         Initial goal:
         !m n. 0 < m /\ m <= n ==> m divides FACT n
\end{verbatim}
\end{session}
Instead of directly inducting on $n-m$, we will induct on a witness
variable, obtained by use of the theorem \verb+LESS_EQ_EXISTS+.
\begin{session}
\begin{verbatim}
- LESS_EQ_EXISTS;
> val it = |- !m n. m <= n = (?p. n = m + p) : thm

- e (RW_TAC arith_ss [LESS_EQ_EXISTS]);
OK..
1 subgoal:
> val it =
    m divides FACT (m + p)
    ------------------------------------
       0 < m
\end{verbatim}
\end{session}
\noindent Now we induct on $p$:
\begin{session}
\begin{verbatim}
- e (Induct_on `p`);
OK..
2 subgoals:
> val it =
    m divides FACT (m + SUC p)
    ------------------------------------
      0.  0 < m
      1.  m divides FACT (m + p)

    m divides FACT (m + 0)
   ------------------------------------
      0 < m
\end{verbatim}
\end{session}
\noindent The first goal can obviously be simplified:
\begin{session}
\begin{verbatim}
- e (RW_TAC arith_ss []);
OK..
1 subgoal:
> val it =
    m divides FACT m
    ------------------------------------
      0 < m
\end{verbatim}
\end{session}
\noindent Now we can do a case analysis on $m$: if it is $0$, we have a
trivial goal; if it is a successor, then we can use the definition of
\ml{FACT} and the theorems \ml{DIVIDES\_RMUL} and
\ml{DIVIDES\_REFL}.
\begin{session}
\begin{verbatim}
- e (Cases_on `m`);
OK..
2 subgoals:
> val it =
    SUC n divides FACT (SUC n)
    ------------------------------------
      0 < SUC n

    0 divides FACT 0
    ------------------------------------
      0 < 0
\end{verbatim}
\end{session}

 Here the first sub-goal goal has an assumption that is false.  We
 can demonstrate this to the system by using the \ml{DECIDE}
function to prove a simple fact about arithmetic (namely, that no
number $x$ is less than itself), and then passing the resulting
theorem to \ml{METIS\_TAC}, which can combine this with the
contradictory assumption.\footnote{Note how the interactive system
  prints out the proved theorem with \ml{[.]} before the
  turnstile.  This notation indicates that a theorem has an
 assumption (the false $0 < 0$ in this case).}

\begin{session}
\begin{verbatim}
- e (METIS_TAC [DECIDE ``!x. ~(x < x)``]);
OK..
metis: r[+0+4]#

Goal proved.
 [.] |- 0 divides FACT 0

Remaining subgoals:
> val it =
    SUC n divides FACT (SUC n)
    ------------------------------------
      0 < SUC n
\end{verbatim}
\end{session}
Using the theorems identified above the remaining sub-goal can
be proved with \ml{RW\_TAC}.

\begin{session}
\begin{verbatim}
- e (RW_TAC arith_ss [FACT, DIVIDES_LMUL, DIVIDES_REFL]);
OK..

Goal proved.   ...

Remaining subgoals:
> val it =
    m divides FACT (m + SUC p)
    ------------------------------------
      0.  0 < m
      1.  m divides FACT (m + p)
\end{verbatim}
\end{session}
This last step, namely the invocation of \ml{RW\_TAC},
could also have been accomplished with \ml{METIS\_TAC}. Note that
the only difference is the use of \ml{DIVIDES\_LMUL} in the simplifier
\emph{versus} \ml{DIVIDES\_RMUL} in \ml{METIS\_TAC}. This is due to the
already mentioned algebraic rearrangement of arithmetical terms in the simplifier.
\begin{session}
\begin{verbatim}
- b();
> ...

- e (METIS_TAC [FACT, DIVIDES_RMUL, DIVIDES_REFL]);
OK..

Goal proved.  ...
\end{verbatim}
\end{session}
Now we have finished the base case of the induction and can move to the
step case. An obvious thing to try is simplification with the
definitions of addition and factorial:
\begin{session}
\begin{verbatim}
- e (RW_TAC arith_ss [FACT, ADD_CLAUSES]);

OK..
1 subgoal:
> val it =
    m divides FACT (m + p) * SUC (m + p)
    ------------------------------------
      0.  0 < m
      1.  m divides FACT (m + p)
\end{verbatim}
\end{session}
\noindent And now, by \ml{DIVIDES\_RMUL} and the inductive hypothesis, we are
done:
\begin{session}
\begin{verbatim}
- e (METIS_TAC [DIVIDES_RMUL]);
OK..
metis: r[+0+5]+0+0+0+0+1#

Goal proved.
  ...
> val it =
    Initial goal proved.
    |- !m n. 0 < m /\ m <= n ==> m divides FACT n
\end{verbatim}
\end{session}
We have finished the search for the proof, and now turn to the task of
making a single tactic out of the sequence of tactic invocations we have
just made. We assume that the sequence of invocations has been kept
track of in a file or a text editor buffer. We would thus have something
like the following:
\begin{hol}
\begin{verbatim}
    e (RW_TAC arith_ss [LESS_EQ_EXISTS]);
    e (Induct_on `p`);
    (*1*)
    e (RW_TAC arith_ss  []);
    e (Cases_on `m`);
    (*1.1*)
    e (METIS_TAC [DECIDE ``!x. ~(x < x)``]);
    (*1.2*)
    e (RW_TAC arith_ss [FACT, DIVIDES_LMUL, DIVIDES_REFL]);
    (*2*)
    e (RW_TAC arith_ss [FACT, ADD_CLAUSES]);
    e (METIS_TAC [DIVIDES_RMUL]);
\end{verbatim}
\end{hol}
\noindent

We have added a numbering scheme to keep track of the branches in the
proof. We can stitch the above together directly into the following compound
tactic:

\begin{hol}
\begin{verbatim}
    RW_TAC arith_ss [LESS_EQ_EXISTS]
     THEN Induct_on `p`
     THENL [RW_TAC arith_ss [] THEN Cases_on `m`
            THENL [METIS_TAC [DECIDE ``!x. ~(x < x)``],
                   RW_TAC arith_ss [FACT, DIVIDES_LMUL, DIVIDES_REFL]],
            RW_TAC arith_ss [FACT, ADD_CLAUSES] THEN METIS_TAC [DIVIDES_RMUL]]
\end{verbatim}
\end{hol}

\noindent This can be tested to see that we have made no errors:

\begin{session}
\begin{verbatim}
- restart();
> ...

- e (RW_TAC arith_ss [LESS_EQ_EXISTS]
       THEN Induct_on `p` THENL
       [RW_TAC arith_ss [] THEN Cases_on `m` THENL
          [METIS_TAC [DECIDE ``!x. ~(x < x)``],
           RW_TAC arith_ss [FACT, DIVIDES_LMUL, DIVIDES_REFL]],
        RW_TAC arith_ss [FACT, ADD_CLAUSES] THEN METIS_TAC [DIVIDES_RMUL]]);
OK..
metis: r[+0+5]+0+0+0+0+1#
metis: r[+0+4]#
> val it =
    Initial goal proved.
    |- !m n. 0 < m /\ m <= n ==> m divides FACT n
\end{verbatim}
\end{session}

For many users, this would be the end of dealing with this proof: the
tactic can now be packaged into an invocation of
\ml{prove}\footnote{The \ml{prove} function takes a term and a tactic
and attempts to prove the term using the supplied tactic.  It
returns the proved theorem if the tactic succeeds.  It doesn't save
the theorem to the developing theory.} or \ml{store\_thm} and that
would be the end of it. However, another user might notice
that this tactic could be shortened.

To start, both arms of the induction start with an invocation of
\ml{RW\_TAC}, and the semantics of \ml{THEN} allow us to merge the
occurrences of \ml{RW\_TAC} above the \ml{THENL}. The recast tactic
is
\begin{hol}
\begin{verbatim}
 RW_TAC arith_ss [LESS_EQ_EXISTS]
   THEN Induct_on `p`
   THEN RW_TAC arith_ss [FACT, ADD_CLAUSES]
   THENL [Cases_on `m` THENL
            [METIS_TAC [DECIDE ``!x. ~(x < x)``],
             RW_TAC arith_ss [FACT, DIVIDES_LMUL, DIVIDES_REFL]],
          METIS_TAC [DIVIDES_RMUL]]
\end{verbatim}
\end{hol}
(Of course, when a tactic has been revised, it should be tested to see
if it still proves the goal!) Now recall that the use of \ml{RW\_TAC}
in the base case could be replaced by a call to \ml{METIS\_TAC}. Thus
it seems possible to merge the two sub-cases of the base case into a
single invocation of \ml{METIS\_TAC}:

\begin{hol}
\begin{verbatim}
 RW_TAC arith_ss [LESS_EQ_EXISTS]
   THEN Induct_on `p`
   THEN RW_TAC arith_ss [FACT, ADD_CLAUSES]
   THENL [Cases_on `m` THEN
            METIS_TAC[DECIDE ``!x. ~(x<x)``,FACT,DIVIDES_RMUL,DIVIDES_REFL],
          METIS_TAC [DIVIDES_RMUL]]
\end{verbatim}
\end{hol}

\noindent
Finally, pushing this revisionism nearly to its limit, we'd
like there to be only a single invocation of \ml{METIS\_TAC} to finish
the proof off. The semantics of \ml{THEN} and \ml{ALL\_TAC} come to
our rescue: we will split on the construction of $m$ in the base case,
as in the current incarnation of the tactic, but we will let the
inductive case pass unaltered through the \ml{THENL}. This is achieved
by using \verb+ALL_TAC+, which is a tactic that acts as an identity
function on the goal.
\begin{hol}
\begin{verbatim}
   RW_TAC arith_ss [LESS_EQ_EXISTS]
     THEN Induct_on `p`
     THEN RW_TAC arith_ss [FACT, ADD_CLAUSES]
     THENL [Cases_on `m`, ALL_TAC]
     THEN METIS_TAC [DECIDE ``!x. ~(x < x)``,
                     FACT, DIVIDES_RMUL, DIVIDES_REFL]
\end{verbatim}
\end{hol}

\noindent
The result is that there will be three subgoals emerging from the
\ml{THENL}: the two sub-cases in the base case and the unaltered step
case. Each is proved with a call to \ml{METIS\_TAC}. Are we now done?
Not necessarily. For example, the explicit case split, namely \ml{Cases\_on `m`},
can be replaced by providing the \emph{cases} theorem for natural numbers
(\ml{num\_CASES}) to \ml{METIS\_TAC}. With this, the case split on $m$ will be
automatically generated by \ml{METIS\_TAC} as it searches for the proof. Hence we
can shorten the tactic again.
\begin{session}
\begin{verbatim}
- num_CASES;
> val it = |- !m. (m = 0) \/ ?n. m = SUC n : thm

- restart();
- e (RW_TAC arith_ss [LESS_EQ_EXISTS]
     THEN Induct_on `p`
     THEN METIS_TAC [DECIDE ``!x. ~(x < x)``, FACT, num_CASES,
                     DIVIDES_RMUL, DIVIDES_LMUL, DIVIDES_REFL, ADD_CLAUSES]);
\end{verbatim}
\end{session}
We have now finished our exercise in tactic revision. Certainly, it
would be hard to foresee that this final tactic would prove the
goal; the required lemmas for the final invocation of \ml{METIS\_TAC}
have been found by an incremental process of revision.

\subsection{Divisibility and factorial (again!)}

In the previous proof, we made an initial simplification step in order
to expose a variable upon which to induct. However, the proof is
really by induction on $n - m$. Can we express this directly? The
answer is a qualified yes: the induction can be naturally stated, but
it leads to somewhat less natural goals.
\begin{session}
\begin{verbatim}
- restart();

- e (Induct_on `n - m`);

OK..
2 subgoals:
> val it =
    !n m. (SUC v = n - m) ==> 0 < m /\ m <= n ==> m divides FACT n
    ------------------------------------
      !n m. (v = n - m) ==> 0 < m /\ m <= n ==> m divides FACT n

    !n m. (0 = n - m) ==> 0 < m /\ m <= n ==> m divides FACT n
\end{verbatim}
\end{session}
    This is slighly hard to read, so we use \ml{STRIP\_TAC} and
    \ml{REPEAT} to move the antecedents of the goals to the
    assumptions. Use of \ml{THEN} ensures that the tactic gets applied
    in both branches of the induction.
\begin{session}
\begin{verbatim}
- b();
  ...

- e (Induct_on `n - m` THEN REPEAT STRIP_TAC);

OK..
2 subgoals:
> val it =
    m divides FACT n
    ------------------------------------
      0.  !n m. (v = n - m) ==> 0 < m /\ m <= n ==> m divides FACT n
      1.  SUC v = n - m
      2.  0 < m
      3.  m <= n

    m divides FACT n
    ------------------------------------
      0.  0 = n - m
      1.  0 < m
      2.  m <= n
\end{verbatim}
\end{session}
Looking at the first goal, we reason that if $0 = n - m$ and $m
\leq n$, then $m = n$. We can prove this fact, using \ml{DECIDE\_TAC}\footnote
{\ml{DECIDE\_TAC} is a decision procedure for a useful class of arithmetical formulas.}
and add it to the hypotheses by use of the infix operator ``\ml{by}'':
\begin{session}
\begin{verbatim}
- e (`m = n` by DECIDE_TAC);
OK..
1 subgoal:
> val it =
    m divides FACT n
    ------------------------------------
      0.  0 = n - m
      1.  0 < m
      2.  m <= n
      3.  m = n
\end{verbatim}
\end{session}

\noindent We can now use \ml{RW\_TAC} to propagate the newly derived equality
throughout the goal.
\begin{session}
\begin{verbatim}
- e (RW_TAC arith_ss []);

OK..
1 subgoal:
> val it =
    m divides FACT m
    ------------------------------------
      0.  0 = m - m
      1.  0 < m
      2.  m <= m
\end{verbatim}
\end{session}
    At this point in the previous proof we did a case analysis on $m$.
    However, we already have the hypothesis that $m$ is positive
    (along with two other now useless hypotheses). Thus we know that
    $m$ is the successor of some number $k$. We might wish to assert
    this fact with an invocation of ``\ml{by}'' as follows:
\[
    \mbox{\ml{`?k. m = SUC k` by <tactic>}}
\]
But what is the tactic? If we try \ml{DECIDE\_TAC}, it will fail since
it doesn't handle existential statements. An application of
\ml{RW\_TAC} will also prove to be unsatisfactory. What to do?

When such situations occur, it is often best to start a new proof for
the required lemma. This can be done simply by invoking ``\ml{g}''
again. A new goalstack will be created and stacked upon the current
one\footnote{This stacking of proof attempts (goalstacks) is different
  than the stacking of goals and justifications inside a particular
  goalstack.}  and an overview of the extant proof attempts will be
printed:
\begin{session}
\begin{verbatim}
- g `!m. 0 < m ==> ?k. m = SUC k`;

> val it =
    Proof manager status: 2 proofs.
    2. Incomplete:
         Initial goal:
         !m n. 0 < m /\ m <= n ==> m divides FACT n

         Current goal:
         m divides FACT m
         ------------------------------------
           0.  0 = m - m
           1.  0 < m
           2.  m <= m

    1. Incomplete:
         Initial goal:
         !m. 0 < m ==> ?k. m = SUC k
\end{verbatim}
\end{session}
    Our new goal can be proved quite quickly. Once we have proved it,
    we can bind it to an ML name and use it in the previous proof, by
    some sleight of hand with the ``\ml{before}''\footnote{An infix
      version of the {\tt K} combinator, defined by {\tt fun (x before
        y) = x}.} function.
\begin{session}
\begin{verbatim}
- e (Cases THEN RW_TAC arith_ss []);

OK..
> val it =
    Initial goal proved.
    |- !m. 0 < m ==> ?k. m = SUC k

- val lem = top_thm() before drop();

OK..
> val lem = |- !m. 0 < m ==> ?k. m = SUC k : thm
\end{verbatim}
\end{session}

Now we can return to the main thread of the proof.  The state of the
current sub-goal of the proof can be displayed using the function
``\ml{p}''.

\begin{session}
\begin{verbatim}
- p ();

> val it =
    m divides FACT m
    ------------------------------------
      0.  0 = m - m
      1.  0 < m
      2.  m <= m
\end{verbatim}
\end{session}
    Now we can use \ml{lem} in the proof. Somewhat opportunistically,
    we will tack on the invocation used in the earlier proof at
    (roughly) the same point, hoping that it will solve the goal:
\begin{session}
\begin{verbatim}
- e (`?k. m = SUC k` by
     METIS_TAC[lem] THEN RW_TAC arith_ss [FACT, DIVIDES_LMUL, DIVIDES_REFL]);
OK..
metis: r[+0+6]+0+0+0+0+0+1#

Goal proved.   ...

Remaining subgoals:
> val it =
    m divides FACT n
    ------------------------------------
      0.  !n m. (v = n - m) ==> 0 < m /\ m <= n ==> m divides FACT n
      1.  SUC v = n - m
      2.  0 < m
      3.  m <= n
\end{verbatim}
\end{session}
    It does! That takes care of the base case. For the induction step,
    things look a bit more difficult than in the earlier proof.
    However, we can make progress by realizing that the hypotheses
    imply that $0 < n$ and so, again by \ml{lem}, we can transform $n$
    into a successor, thus enabling the unfolding of \ml{FACT}, as in
    the previous proof:
\begin{session}
\begin{verbatim}
- e (`0 < n` by DECIDE_TAC THEN `?k. n = SUC k` by METIS_TAC [lem]);
OK..
metis: r[+0+8]+0+0+0+0+0+0+2#
1 subgoal:
> val it =
    m divides FACT n
    ------------------------------------
      0.  !n m. (v = n - m) ==> 0 < m /\ m <= n ==> m divides FACT n
      1.  SUC v = n - m
      2.  0 < m
      3.  m <= n
      4.  0 < n
      5.  n = SUC k
\end{verbatim}
\end{session}
\noindent The proof now finishes in much the same manner as the previous one:
\begin{session}
\begin{verbatim}
- e (RW_TAC arith_ss [FACT, DIVIDES_RMUL]);
OK..

Goal proved.  ...
> val it =
    Initial goal proved.
    |- !m n. 0 < m /\ m <= n ==> m divides FACT n
\end{verbatim}
\end{session}
\noindent We leave the details of stitching the proof together to the interested
reader.

\section{Primality}

Now we move on to establish some facts about the primality of the
first few numbers: $0$ and $1$ are not prime, but $2$ is. Also, all
primes are positive. These are all quite simple to prove.

\begin{description}

\item [\small{({\it NOT\_PRIME\_0\/})}]
\begin{tabular}[t]{l}
\verb+~prime 0+ \\ \hline
\verb+RW_TAC arith_ss [prime_def,DIVIDES_0]+ \\
\end{tabular}

\item [\small{({\it NOT\_PRIME\_1\/})}]
\begin{tabular}[t]{l}
\verb+~prime 1+ \\ \hline
\verb+RW_TAC arith_ss [prime_def]+ \\
\end{tabular}

\item [\small{({\it PRIME\_2\/})}]
\begin{tabular}[t]{l}
\verb+prime 2+ \\ \hline
\verb+RW_TAC arith_ss [prime_def]+ \\
\verb+ THEN METIS_TAC [DIVIDES_LE, DIVIDES_ZERO,+ \\
\verb+                 DECIDE ``~(2=1)``, DECIDE ``~(2=0)``,+ \\
\verb+                 DECIDE ``x <= 2 = (x=0) \/ (x=1) \/ (x=2)``]+ \\
\end{tabular}

\item [\small{({\it PRIME\_POS\/})}]
\begin{tabular}[t]{l}
\verb+!p. prime p ==> 0<p+ \\ \hline
\verb+Cases THEN RW_TAC arith_ss [NOT_PRIME_0]+ \\
\end{tabular}
\end{description}

\section{Existence of prime factors}

Now we are in position to prove a more substantial lemma: every number
other than $1$ has a prime factor. The proof proceeds by a
\emph{complete induction} on $n$. Complete induction is
necessary since a prime factor won't be the predecessor. After
induction, the proof splits into cases on whether $n$ is prime or
not. The first case ($n$ is prime) is
trivial. In the second case, there must be an $x$ that divides $n$, and
$x$ is not $1$ or $n$. By {\small\it DIVIDES\_LE}, $n=0$ or $x \leq n$. If
$n=0$, then $2$ is a prime that divides $0$. On the other hand, if $x \leq
n$, there are two cases: if $x < n$ then we can use the inductive
hypothesis and by transitivity of divides we are done; otherwise,
$x=n$ and then we have a contradiction with the fact that $x$ is not 1
or $n$.  The polished tactic is the following:
\begin{description}
\item [\small{({\it PRIME\_FACTOR\/})}]
\begin{tabular}[t]{l}
\verb+!n. ~(n = 1) ==> ?p. prime p /\ p divides n+ \\ \hline
\verb+completeInduct_on `n`+ \\
\verb+  THEN RW_TAC arith_ss []+ \\
\verb+  THEN Cases `prime n` THENL+ \\
\verb+  [METIS_TAC [DIVIDES_REFL], + \\
\verb+   `?x. x divides n /\ ~(x=1) /\ ~(x=n)` + \\
\verb+    by METIS_TAC[prime_def]+ \\
\verb+     THEN METIS_TAC [LESS_OR_EQ, PRIME_2, +\\
\verb+                  DIVIDES_LE,DIVIDES_TRANS,DIVIDES_0]]+ \\
\end{tabular}
\end{description}
We start by invoking complete induction. This gives us an inductive
hypothesis that holds at every number $m$ strictly smaller than $n$:
\begin{session}
\begin{verbatim}
- g `!n. ~(n = 1) ==> ?p. prime p /\ p divides n`;

- e (completeInduct_on `n`);
OK..
1 subgoal:
> val it =
    ~(n = 1) ==> ?p. prime p /\ p divides n
    ------------------------------------
      !m. m < n ==> ~(m = 1) ==> ?p. prime p /\ p divides m
\end{verbatim}
\end{session}
We can move the antecedent to the hypotheses and make our case
split. Notice that the term given to \ml{Cases\_on} need not occur in
the goal:
\begin{session}
\begin{verbatim}
- e (RW_TAC arith_ss [] THEN Cases_on `prime n`);
OK..
2 subgoals:
> val it =
    ?p. prime p /\ p divides n
    ------------------------------------
      0.  !m. m < n ==> ~(m = 1) ==> ?p. prime p /\ p divides m
      1.  ~(n = 1)
      2.  ~prime n

    ?p. prime p /\ p divides n
    ------------------------------------
      0.  !m. m < n ==> ~(m = 1) ==> ?p. prime p /\ p divides m
      1.  ~(n = 1)
      2.  prime n
\end{verbatim}
\end{session}
\noindent As mentioned, the first case is proved with the reflexivity of
divisibility:
\begin{session}
\begin{verbatim}
- e (METIS_TAC [DIVIDES_REFL]);
OK..
metis: r[+0+7]+0+0+0+0+1#

Goal proved.  ...
\end{verbatim}
\end{session}
\noindent
In the second case, we can get a divisor of $n$ that isn't $1$ or $n$
(since $n$ is not prime):
\begin{session}
\begin{verbatim}
- e (`?x. x divides n /\ ~(x=1) /\ ~(x=n)` by METIS_TAC [prime_def]);
OK..
metis: r[+0+11]+0+0+0+0+0+0+1+1+1+1+0+1+1#
1 subgoal:
> val it =
    ?p. prime p /\ p divides n
    ------------------------------------
      0.  !m. m < n ==> ~(m = 1) ==> ?p. prime p /\ p divides m
      1.  ~(n = 1)
      2.  ~prime n
      3.  x divides n
      4.  ~(x = 1)
      5.  ~(x = n)
\end{verbatim}
\end{session}
At this point, the polished tactic simply invokes \ml{METIS\_TAC} with
a collection of theorems. We will attempt a more detailed
exposition. Given the hypotheses, and by {\small\it DIVIDES\_LE}, we can
assert $x < n \lor n = 0$ and thus split the proof into two cases:
\begin{session}
\begin{verbatim}
- e (`x < n \/ (n=0)` by METIS_TAC [DIVIDES_LE,LESS_OR_EQ]);
OK..
metis: r[+0+14]+0+0+0+0+0+0+0+0+0+0+1+0+1#
2 subgoals:
> val it =
    ?p. prime p /\ p divides n
    ------------------------------------
      0.  !m. m < n ==> ~(m = 1) ==> ?p. prime p /\ p divides m
      1.  ~(n = 1)
      2.  ~prime n
      3.  x divides n
      4.  ~(x = 1)
      5.  ~(x = n)
      6.  n = 0

    ?p. prime p /\ p divides n
    ------------------------------------
      0.  !m. m < n ==> ~(m = 1) ==> ?p. prime p /\ p divides m
      1.  ~(n = 1)
      2.  ~prime n
      3.  x divides n
      4.  ~(x = 1)
      5.  ~(x = n)
      6.  x < n
\end{verbatim}
\end{session}
In the first subgoal, we can see that the antecedents of the inductive
hypothesis are met and so $x$ has a prime divisor. We can then use the
transitivity of divisibility to get the fact that this divisor of $x$ is
also a divisor of $n$, thus finishing this branch of the proof:
\begin{session}
\begin{verbatim}
- e (METIS_TAC [DIVIDES_TRANS]);
OK..
metis: r[+0+11]+0+0+0+0+0+0+0+1+0+4+1+0+3+0+2+2+1#

Goal proved.
\end{verbatim}
\end{session}
\noindent The remaining goal can be clarified by simplification:
\begin{session}
\begin{verbatim}
- e (RW_TAC arith_ss  []);
OK..
1 subgoal:
> val it =
    ?p. prime p /\ p divides 0
    ------------------------------------
      0.  !m. m < 0 ==> ~(m = 1) ==> ?p. prime p /\ p divides m
      1.  ~(0 = 1)
      2.  ~prime 0
      3.  x divides 0
      4.  ~(x = 1)
      5.  ~(x = 0)

- DIVIDES_0;
> val it = |- !x. x divides 0 : thm

- e (RW_TAC arith_ss  [it]);
OK..
1 subgoal:
> val it =
    ?p. prime p
    ------------------------------------
      0.  !m. m < 0 ==> ~(m = 1) ==> ?p. prime p /\ p divides m
      1.  ~(0 = 1)
      2.  ~prime 0
      3.  x divides 0
      4.  ~(x = 1)
      5.  ~(x = 0)
\end{verbatim}
\end{session}
The two steps of exploratory simplification have led us to a state where
all we have to do is exhibit a prime. And we already have one to hand:
\begin{session}
\begin{verbatim}
- e (METIS_TAC [PRIME_2]);
OK..
metis: r[+0+6]#

Goal proved.   ...
> val it =
    Initial goal proved.
    |- !n. ~(n = 1) ==> ?p. prime p /\ p divides n
\end{verbatim}
\end{session}
Again, work now needs to be done to compose and perhaps polish a single
tactic from the individual proof steps, but we will not describe
it.\footnote{Indeed, the tactic can be simplified into complete induction
 followed by an invocation of \ml{METIS\_TAC} with suitable lemmas.}
 Instead we move forward, because our ultimate goal is in reach.

\section{Euclid's theorem}

\noindent{\bf Theorem.} Every number has a prime greater than it.\\
\noindent  {\it Informal proof.} \\
\noindent Suppose the opposite; then there's an $n$
such that all $p$ greater than $n$ are not prime. Consider $\mbox{\tt
FACT}(n) + 1$: it's not equal to 1 so, by {\small{\it PRIME\_FACTOR}},
there's a prime $p$ that divides it. Note that $p$ also divides
$\mbox{\tt FACT}(n)$ because $p \leq n$. By {\small{\it DIVIDES\_ADDL}},
we have $p=1$. But then $p$ is not prime, which is a contradiction. \\
\noindent {\it End of proof}.

A HOL rendition of the proof may be given as follows:
\begin{description}
\item [\small{({\it EUCLID\/})}]
\begin{tabular}[t]{l}
\verb+!n. ?p. n < p /\ prime p+ \\ \hline
\verb+SPOSE_NOT_THEN STRIP_ASSUME_TAC+ \\
\verb!  THEN MP_TAC (SPEC ``FACT n + 1`` PRIME_FACTOR)! \\
\verb+  THEN RW_TAC arith_ss [FACT_LESS, DECIDE ``~(x=0) = 0<x``]+ \\
\verb+  THEN METIS_TAC [NOT_PRIME_1, NOT_LESS, PRIME_POS, + \\
\verb+                  DIVIDES_FACT, DIVIDES_ADDL, DIVIDES_ONE]+ \\
\end{tabular}
\end{description}
Let's prise this apart and look at it in some detail. A proof by
contradiction can be started by using the \ml{bossLib} function
\ml{SPOSE\_NOT\_THEN}. With it, one assumes the negation of the
current goal and then uses that in an attempt to prove falsity
(\verb+F+). The assumed negation $\neg(\forall n.\ \exists p.\ n < p
\land \mbox{\tt prime}\ p)$ is simplified a bit into $\exists n.\
\forall p.\ n < p \supset \, \neg \,\mbox{\tt prime}\ p$ and then is
passed to the tactic \ml{STRIP\_ASSUME\_TAC}. This moves its argument
to the assumption list of the goal after eliminating the existential
quantification on $n$.
\begin{session}
\begin{verbatim}
- g `!n. ?p. n < p /\ prime p`;

- e (SPOSE_NOT_THEN STRIP_ASSUME_TAC);
OK..
1 subgoal:
> val it =
    F
    ------------------------------------
      !p. n < p ==> ~prime p
\end{verbatim}
\end{session}
Thus we have the hypothesis that all $p$ beyond a certain unspecified
$n$ are not prime, and our task is to show that this cannot be. At this
point we take advantage of Euclid's great inspiration and we build an
explicit term from $n$. In the informal proof we are asked to `consider'
the term $\mbox{\tt FACT}\ n + 1$.\footnote{The HOL parser thinks
$\mbox{\tt FACT}\ n + 1$ is equivalent to $(\mbox{\tt FACT}\ n) + 1$.}
This term will have certain properties (\ie, it has a prime factor) that
lead to contradiction. Question: how do we `consider' this term in the
formal HOL proof? Answer: by instantiating a lemma with it and bringing the
lemma into the proof. The lemma and its instantiation are:\footnote{The
function {\tt SPEC} implements the rule of universal specialization.}
\begin{session}
\begin{verbatim}
- PRIME_FACTOR;
> val it = |- !n. ~(n = 1) ==> (?p. prime p /\ p divides n) : thm

- val th = SPEC ``FACT n + 1`` PRIME_FACTOR;
> val th =
    |- ~(FACT n + 1 = 1) ==> (?p. prime p /\ p divides FACT n + 1)
\end{verbatim}
\end{session}
It is evident that the antecedent of \ml{th} can be eliminated. In
\holn{}, one could do this in a so-called {\it forward\/} proof style (by
proving $\vdash \neg(\mbox{\tt FACT}\ n + 1 = 1)$ and then applying {\it
modus ponens}, the result of which can then be used in the proof), or
one could bring \ml{th} into the proof and simplify it {\it in
situ}. We choose the latter approach.
\begin{session}
\begin{verbatim}
- e (MP_TAC (SPEC ``FACT n + 1`` PRIME_FACTOR));
OK..
1 subgoal:
> val it =
    (~(FACT n + 1 = 1) ==> ?p. prime p /\ p divides FACT n + 1) ==> F
    ------------------------------------
      !p. n < p ==> ~prime p
\end{verbatim}
\end{session}
    The invocation \ml{MP\_TAC} ($\vdash M$) applied to a goal
    $(\Delta, g)$ returns the goal $(\Delta, M \supset g)$. Now we
    simplify:
\begin{session}
\begin{verbatim}
- e (RW_TAC arith_ss []);
OK..
2 subgoals:
> val it =
    ~prime p \/ ~(p divides FACT n + 1)
    ------------------------------------
      0.  !p. n < p ==> ~prime p
      1.  prime p

    ~(FACT n = 0)
    ------------------------------------
      !p. n < p ==> ~prime p
\end{verbatim}
\end{session}
    We recall that zero is less than every factorial, a fact found in
    \ml{arithmeticTheory} under the name \ml{FACT\_LESS}. Thus we can
    solve the top goal by simplification:
\begin{session}
\begin{verbatim}
- e (RW_TAC arith_ss [FACT_LESS, DECIDE ``!x. ~(x=0) = 0 < x``]);
OK..
Goal proved.  ...
\end{verbatim}
\end{session}
Notice the `on-the-fly' use of \verb+DECIDE+ to provide an \textit{ad hoc}
rewrite. Looking at the remaining goal, one might think that our aim, to
prove falsity, has been lost. But this is not so: a goal
$\neg P \lor \neg Q$ is logically equivalent to $P \imp Q \imp \mathtt{F}$.
In the following invocation, we use the equality
$\vdash A \imp B = \neg A \lor B$ as a rewrite rule oriented right to left by
use of \ml{GSYM}.\footnote{Loosely speaking, \ml{GSYM} swaps the left and
right hand sides of any equations it finds.}
\begin{session}
\begin{verbatim}
- IMP_DISJ_THM;
> val it = |- !A B. A ==> B = ~A \/ B : thm

- e (RW_TAC arith_ss [GSYM IMP_DISJ_THM]);
OK..
1 subgoal:
> val it =
    ~(p divides FACT n + 1)
    ------------------------------------
      0.  !p. n < p ==> ~prime p
      1.  prime p
     : goalstack
\end{verbatim}
\end{session}

We can quickly proceed to show that $p \ \mathtt{divides}\ (\mathtt{FACT}\; n)$,
and thus that $p = 1$, hence that $p$ is not prime, at which point we are done.
This can all be packaged into a single invocation of \ml{METIS\_TAC}:
\begin{session}
\begin{verbatim}
- e (METIS_TAC [DIVIDES_FACT, DIVIDES_ADDL, DIVIDES_ONE,
                NOT_PRIME_1, NOT_LESS, PRIME_POS]);
metis: r[+0+12]+0+0+0+0+0+0+0+1+1+0+0+0+0+1+1+1+1+4#

Goal proved.
 [..] |- ~(p divides FACT n + 1)

Goal proved.
 [.] |- ~prime p \/ ~(p divides FACT n + 1)

Goal proved.
 [.]
|- (~(FACT n + 1 = 1) ==> ?p. prime p /\ p divides FACT n + 1) ==> F

Goal proved.
 [.] |- F
> val it =
    Initial goal proved.
    |- !n. ?p. n < p /\ prime p : goalstack
\end{verbatim}
\end{session}
    Euclid's theorem is now proved, and we can rest. However, this
    presentation of the final proof will be unsatisfactory to some,
    because the proof is completely hidden in the invocation of the
    automated reasoner. Well then, let's try another proof, this time
    employing the so-called `assertional' style. When used uniformly,
    this can allow a readable linear presentation that mirrors the
    informal proof. The following proves Euclid's theorem in the
    assertional style. We think it is fairly readable, certainly much
    more so than the standard tactic proof just given.\footnote{Note
      that {\tt CCONTR\_TAC}, which is used to start the proof,
      initiates a proof by contradiction by negating the goal and
      placing it on the hypotheses, leaving {\tt F} as the new goal.}

\begin{description}
\item [\small{({\it AGAIN\/})}]
\begin{tabular}[t]{l}
\verb+!n. ?p. n < p /\ prime p+ \\ \hline
\verb|CCONTR_TAC THEN | \\
\verb|`?n. !p. n < p ==> ~prime p`  by METIS_TAC []             THEN| \\
\verb|`~(FACT n + 1 = 1)`           by RW_TAC arith_ss  [FACT_LESS,| \\
\verb|                                    DECIDE``~(x=0)=0<x``] THEN| \\
\verb|`?p. prime p /\  | \\
\verb|     p divides (FACT n + 1)`  by METIS_TAC [PRIME_FACTOR] THEN| \\
\verb|`0 < p`                       by METIS_TAC [PRIME_POS]    THEN| \\
\verb|`p <= n`                      by METIS_TAC [NOT_LESS]     THEN| \\
\verb|`p divides FACT n`            by METIS_TAC [DIVIDES_FACT] THEN| \\
\verb|`p divides 1`                 by METIS_TAC [DIVIDES_ADDL] THEN| \\
\verb|`p = 1`                       by METIS_TAC [DIVIDES_ONE]  THEN| \\
\verb|`~prime p`                    by METIS_TAC [NOT_PRIME_1]  THEN| \\
\verb|METIS_TAC []| \\
\end{tabular}
\end{description}

\section{Turning the script into a theory}
\label{sec:script-to-theory}

Having proved our result, we probably want to package it up in a way
that makes it available to future sessions, but which doesn't require
us to go all through the theorem-proving effort again.  Even having a
complete script from which it would be possible to cut-and-paste is an
error-prone solution.

In order to do this we need to create a file with the name
$x$\ml{Script.sml}, where $x$ is the name of the theory we wish to
export.  This file then needs to be compiled.  In fact, we really do
use the Moscow ML compiler, carefully augmented with the appropriate
logical context.  However, the language accepted by the compiler is
not quite the same as that accepted by the interactive system, so we
will need to do a little work to massage the original script into the
correct form.

We'll give an illustration of converting to a form that can be
compiled using the script
\[
  \mbox{\ml{<holdir>/examples/euclid.sml}}
\] as our base-line.  This
file is already close to being in the right form.  It has all of the
proofs of the theorems in ``sewn-up'' form so that when run, it does
not involve the goal-stack at all.  In its given form, it can be run
as input to \textsf{hol} thus:

\setcounter{sessioncount}{0}
\begin{session}
\begin{verbatim}
$ cd examples/
$ ../bin/hol < euclid.sml
  ...

> val EUCLID = |- !n. ?p. n < p /\ prime p : thm
  ...

> val EUCLID_AGAIN = |- !n. ?p. n < p /\ prime p : thm
-
\end{verbatim}
\end{session}

However, we now want to create a \ml{euclidTheory} that we can load in
other interactive sessions.  So, our first step is to create a file
\ml{euclidScript.sml}, and to copy the body of \ml{euclid.sml} into
it.

The first non-comment line opens \ml{arithmeticTheory}.  However, when
writing for the compiler, we need to explicitly mention the other
\HOL{} modules that we depend on.  We must add
\[
\mbox{\ml{open HolKernel boolLib Parse bossLib}}
\]
The next line that poses a difficulty is
\[
  \mbox{\ml{set\_fixity "divides" (Infixr 450);}}
\]
While it is legitimate to type expressions directly into the
interactive system, the compiler requires that every top-level phrase
be a declaration.  We satisfy this requirement by altering this line
into a ``do nothing'' declaration that does not record the result of
the expression:
\[
\mbox{\ml{val \_{} = set\_fixity "divides" (Infixr 450)}}
\]
The only extra changes are to bracket the rest of the script text
with calls to \ml{new\_theory} and \ml{export\_theory}.  So,
before the definition of \ml{divides}, we add:
\[
\mbox{\ml{val \_{} = new\_theory "euclid";}}
\]
and at the end of the file:
\[
\mbox{\ml{val \_{} = export\_theory();}}
\]

Now, we can compile the script we have created using the
\textsf{Holmake} tool.  To keep things a little tidier, we first move
our script into a new directory.

\begin{session}
\begin{verbatim}
$ mkdir euclid
$ mv euclidScript.sml euclid
$ cd euclid
$ ../../bin/Holmake
Analysing euclidScript.sml
Trying to create directory .HOLMK for dependency files
Compiling euclidScript.sml
Linking euclidScript.uo to produce theory-builder executable
<<HOL message: Created theory "euclid".>>
Definition has been stored under "divides_def".
Definition has been stored under "prime_def".
Meson search level: .....
Meson search level: .................
 ...
Exporting theory "euclid" ... done.
Analysing euclidTheory.sml
Analysing euclidTheory.sig
Compiling euclidTheory.sig
Compiling euclidTheory.sml
\end{verbatim}
\end{session}

Now we have created four new files, various forms of \ml{euclidTheory}
with four different suffixes.  Only \ml{euclidTheory.sig} is really
suitable for human consumption.  While still in the \ml{euclid}
directory that we created, we can demonstrate:

\begin{session}
\begin{alltt}
\$ ../../bin/hol
[...]

[closing file "/local/scratch/mn200/Work/hol98/tools/end-init-boss.sml"]
- load "euclidTheory";
> val it = () : unit
- open euclidTheory;
> type thm = thm
  val DIVIDES_TRANS =
    |- !a b c. a divides b /\ b divides c ==> a divides c
    : thm
  ...
  val DIVIDES_REFL = |- !x. x divides x : thm
  val DIVIDES_0 = |- !x. x divides 0 : thm
\end{alltt}
\end{session}

\section{Summary}

The reader has now seen an interesting theorem proved, in great detail,
in \holn{}. The discussion illustrated the high-level tools provided in
\ml{bossLib} and touched on issues including tool selection, undo,
`tactic polishing', exploratory simplification, and the `forking-off' of
new proof attempts. We also attempted to give a flavour of the thought
processes a user would employ. Following is a more-or-less random
collection of other observations.
\begin{itemize}

\item Even though the proof of Euclid's theorem is short and easy to
understand when presented informally, a perhaps surprising amount of
support development was required to set the stage for Euclid's classic
argument.

\item The proof support offered by \ml{bossLib}
(\verb+RW_TAC+, \ml{METIS\_TAC}, \ml{DECIDE\_TAC}, \ml{DECIDE},
\ml{Cases\_on}, \ml{Induct\_on}, and the ``\ml{by}'' construct) was
nearly complete for this example: it was rarely necessary to resort to
lower-level tactics.

\item Simplification is a workhorse tactic; even when an automated
reasoner such as \ml{METIS\_TAC} is used, its application has often been
set up by some exploratory simplifications. It therefore pays to become
familiar with the strengths and weaknesses of the simplifier.

\item A common problem with interactive proof systems is dealing with
hypotheses. Often \ml{METIS\_TAC} and the ``\ml{by}'' construct allow
the use of hypotheses without directly resorting to indexing into them
(or naming them, which amounts to the same thing). This is desirable,
since the hypotheses are notionally a {\it set}, and moreover,
experience has shown that profligate indexing into hypotheses results in
hard-to-maintain proof scripts. However, it can be clumsy to work with a
large set of hypotheses, in which case the following approaches may be
useful.

One can directly refer to hypotheses by using \ml{UNDISCH\_TAC} (makes
the designated hypothesis the antecedent to the goal),
\ml{ASSUM\_LIST} (gives the entire hypothesis list to a tactic),
\ml{POP\_ASSUM} (gives the top hypothesis to a tactic), and
\ml{PAT\_ASSUM} (gives the first {\it matching\/} hypothesis to a
tactic). (See the \REFERENCE{} for further details on all of these.)
The numbers attached to hypotheses by the proof manager could likely
be used to access hypotheses (it would be quite simple to write such a
tactic). However, starting a new proof is sometimes the most
clarifying thing to do.

In some cases, it is useful to be able to delete a hypothesis. This can
be accomplished by passing the hypothesis to a tactic that ignores
it. For example, to discard the top hypothesis, one could invoke
\ml{POP\_ASSUM (K ALL\_TAC)}.

\item In the example, we didn't use the more advanced features of
\ml{bossLib}, largely because they do not, as yet, provide much more
functionality than the simple sequencing of simplification, decision
procedures, and automated first order reasoning. The \ml{THEN}
tactical has thus served as an adequate replacement. In the future,
these entrypoints should become more powerful.

\item It is almost always necessary to have an idea of the {\it
    informal\/} proof in order to be successful when doing a formal
  proof. However, all too often the following strategy is adopted by
  novices: (1) rewrite the goal with a few relevant definitions, and
  then (2) rely on the syntax of the resulting goal to guide
  subsequent tactic selection. Such an approach constitutes a clear
  case of the tail wagging the dog, and is a poor strategy to adopt.
  Insight into the high-level structure of the proof is one of the
  most important factors in successful verification exercises.

The author has noticed that many of the most successful verification
experts work using a sheet of paper to keep track of the main steps that
need to be made. Perhaps looking away to the paper helps break the
mesmerizing effect of the computer screen.

On the other hand, one of the advantages of having a mechanized logic
is that the machine can be used as a formal expression calculator,
and thus the user can use it to quickly and accurately explore various
proof possibilities.
\item High powered tools like \ml{METIS\_TAC}, \ml{DECIDE\_TAC}, and
\ml{RW\_TAC} are the principal way of advancing a proof in
\ml{bossLib}. In many cases, they do exactly what is desired, or even
manage to surprise the user with their power. In the formalization of
Euclid's theorem, the tools performed fairly well. However, sometimes
they are overly aggressive, or they simply flounder. In such cases, more
specialized proof tools need to be used, or even written, and hence the
support underlying \ml{bossLib} must eventually be learned.

\item Having a good knowledge of the available lemmas, and where they
are located, is an essential part of being successful. Often powerful
tools can replace lemmas in a restricted domain, but in general, one has
to know what has already been proved. We have found that the entrypoints
in \verb+DB+ help in quickly finding lemmas.

\end{itemize}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: "tutorial"
%%% End: