
\chapter{Example: a simple parity checker}\label{parity}

This chapter consists of a worked example: the specification and
verification of a simple sequential parity checker.  The intention is
to   accomplish two things:

\begin{myenumerate}
\item To present a complete piece of work with \HOL.
\item To give a flavour of what it is like to use the \HOL\
system for a tricky proof.  
\end{myenumerate}

Concerning (ii), note that although the theorems proved are, in fact,
rather simple, the way they are proved illustrates the kind of
intricate `proof engineering' that is typical.  The proofs could be
done more elegantly, but presenting them that way would defeat the
purpose of illustrating various features of \HOL. It is hoped that the
small example here will give the reader a feel for what it is like to
do a big one. 

Readers who are not interested in hardware verification
should be able to learn something about the
\HOL\ system even if they do not wish to penetrate the details of the
parity-checking example used here.  The specification and verification of a
slightly more complex parity checker is set as an exercise (a solution
is provided).

\section{Introduction}

This case study is supported by three files in
the \HOL\ distribution directory. These files are:

\begin{hol}\begin{verbatim}
   hol/Training/parity/PARITY.ml
   hol/Training/parity/RESET_REG.ml
   hol/Training/parity/RESET_PARITY.ml
\end{verbatim}\end{hol}

The file {\verb%PARITY.ml%} contains the \HOL\ sessions
in this chapter; the files {\verb%RESET_REG.ml%} and
{\verb%RESET_PARITY.ml%} contain the solutions
to the exercises described in Section~\ref{exercises}.

The goal of the case study is to illustrate detailed `proof hacking' on
a small and fairly simple example.

The boxes below contain a little session with the \HOL\ system.  The interactions
in these boxes should be understood as occurring in sequence.  For example,
variable bindings made in earlier boxes are assumed to persist to later ones.
These interactions comprise the specification and verification of a device that
computes the parity of a sequence of bits.  More specifically, a detailed
verification is given of a device with an input {\small\verb%in%}, an output
{\small\verb%out%} and the specification that the $n$th output on
{\small\verb%out%} is {\small\verb%T%} if and only if there have been an even
number of {\small\verb%T%}'s input on {\small\verb%in%}. A
theory named {\small\verb%PARITY%} is constructed; this contains the
specification and verification of the device. All the \ML\ input in the boxes below
can be found in the file {\small\verb%parity/PARITY.ml%}. It is suggested that the
reader interactively input this to get a `hands on' feel for the example.


\section{Specification}
\label{example}
The first step
is to start up the \HOL\ system and then enter draft mode for a new theory
called {\small\verb%PARITY%}.
The \HOL\ system
is entered by typing {\small\verb%hol%} to Unix.\footnote{The Unix 
prompt on the author's machine is {\small{\tt gwyndir\%}}.}
The \HOL\ system then prints a sign-on message
and puts the user into \ML.
The \ML\ prompt is {\small\verb%#%},  so lines beginning
with {\small\verb%#%} 
are typed by the user and other lines are the system's response.

\setcounter{sessioncount}{1}
\begin{session}\begin{verbatim}
gwyndir% hol

       _  _    __    _      __    __
|___   |__|   |  |   |     |__|  |__|
|      |  |   |__|   |__   |__|  |__|

          Version 2.0 (Sun3/Franz), built on Sep 1 1991 

#new_theory`PARITY`;;
() : void
\end{verbatim}
\end{session}

\noindent To specify the device, a primitive recursive
function {\small\verb%PARITY%} is defined 
so that for $n>0$, {\small\tt PARITY} $n f$ is true if the number
of {\small\verb%T%}'s in the sequence 
$f${\small\tt (}$1${\small\tt)}, $\ldots$ , $f${\small\tt (}$n${\small\tt)}
is even.

\begin{session}
\begin{verbatim}
#let PARITY_DEF =
# new_prim_rec_definition
#  (`PARITY_DEF`,
#   "(PARITY 0 f = T) /\
#    (PARITY(SUC n)f = (f(SUC n) => ~(PARITY n f) | PARITY n f))");;
PARITY_DEF = 
|- (!f. PARITY 0 f = T) /\
   (!n f. PARITY(SUC n)f = (f(SUC n) => ~PARITY n f | PARITY n f))
\end{verbatim}
\end{session}

\noindent 
The effect of {\small\verb%new_prim_rec_definition%} 
is to store the definition of {\small\verb%PARITY%}  on the  
current theory with
name {\small\verb%PARITY_DEF%} and to bind the defining theorem to the \ML\
variable with the same name.
Notice  that there  are two name spaces being
written into:  the names of constants in theories and the names of variables in
\ML.  The user is free to manage these names however he or  she wishes (subject
to the various lexical requirements), but a common  convention is  (as here) to
give the definition of a constant {\small\tt CON} the name
{\small\verb%CON_DEF%} in the theory  and also  in \ML.   Another commonly-used
convention is to use just {\small\verb%CON%}  for the  theory and  \ML\ name of
the definition  of  a  constant  {\small\verb%CON%}.   Unfortunately, the \HOL\
system does not use a uniform  convention, but  users are  recommended to adopt
one.


The specification of the parity checking device can now be given as:

{\small\baselineskip\HOLSpacing\begin{verbatim}
   !t. out t = PARITY t in
\end{verbatim}}

\noindent It is {\it intuitively\/} clear that this specification will be satisfied
if the signal\footnote{Signals are modelled as functions from numbers, representing
times, to booleans.} functions {\small\verb%in%} and {\small\verb%out%} satisfy:

{\small\baselineskip\HOLSpacing\begin{verbatim}
   out(0) = T
\end{verbatim}}

\noindent and

{\small\baselineskip\HOLSpacing\begin{verbatim}
   !t. out(t+1)  =  (in(t+1) => ~(out t) | out t)
\end{verbatim}}

\noindent This can be verified formally in \HOL\ by proving the
following lemma:

{\small\baselineskip\HOLSpacing\begin{verbatim}
   !in out. 
    (out 0 = T) /\ (!t. out(SUC t) = (in(SUC t) => ~(out t) | out t))
    ==>
    (!t. out t = PARITY t in)
\end{verbatim}}

\noindent The proof of this is done by Mathematical Induction and, although
trivial, is a good illustration of how such proofs are done.
The lemma is proved interactively using \HOL's subgoal 
package.
The proof is started by putting the goal
to be proved on a goal stack using the function
{\small\verb%set_goal%} which takes a goal as argument. 

\begin{session}
\begin{verbatim}
#set_goal
#([],
# "!in out. 
#   (out 0 = T) /\ (!t. out(SUC t) = (in(SUC t) => ~(out t) | out t))
#   ==>
#   (!t. out t = PARITY t in)");;
"!in out.
  (out 0 = T) /\ (!t. out(SUC t) = (in(SUC t) => ~out t | out t)) ==>
  (!t. out t = PARITY t in)"
\end{verbatim}
\end{session}


\noindent The subgoal package prints out the goal on the top of the goal stack.
The top  goal  is  expanded  by  stripping  off the  universal quantifier (with
{\small\verb%GEN_TAC%}) and then making the two conjuncts of  the antecedent of
the implication into assumptions  of the  goal (with {\small\verb%STRIP_TAC%}).
The \ML\ function {\small\verb%expand%} takes  a tactic  and applies  it to the
top goal; the resulting subgoals are pushed on to the goal stack.   The message
`{\small\verb%OK..%}' is printed out  just before  the tactic  is applied.
The resulting subgoal is then printed.


\begin{session}
\begin{verbatim}
#expand(REPEAT GEN_TAC THEN STRIP_TAC);;
OK..
"!t. out t = PARITY t in"
    [ "out 0 = T" ]
    [ "!t. out(SUC t) = (in(SUC t) => ~out t | out t)" ]
\end{verbatim}
\end{session}

\noindent Next induction on {\small\verb%t%} is done
using {\small\verb%INDUCT_TAC%}, which does
induction on the outermost universally quantified variable.

\begin{session}
\begin{verbatim}
#expand INDUCT_TAC;;
OK..
2 subgoals
"out(SUC t) = PARITY(SUC t)in"
    [ "out 0 = T" ]
    [ "!t. out(SUC t) = (in(SUC t) => ~out t | out t)" ]
    [ "out t = PARITY t in" ]

"out 0 = PARITY 0 in"
    [ "out 0 = T" ]
    [ "!t. out(SUC t) = (in(SUC t) => ~out t | out t)" ]
\end{verbatim}
\end{session}

\noindent The assumptions of the two subgoals
are shown in square brackets. The last goal printed is the one on the top of
the stack, which is the basis case. This is solved by rewriting with its
assumptions and the definition of {\small\verb%PARITY%}.


\begin{session}
\begin{verbatim}
#expand(ASM_REWRITE_TAC[PARITY_DEF]);;
OK..
goal proved
. |- out 0 = PARITY 0 in

Previous subproof:
"out(SUC t) = PARITY(SUC t)in"
    [ "out 0 = T" ]
    [ "!t. out(SUC t) = (in(SUC t) => ~out t | out t)" ]
    [ "out t = PARITY t in" ]
\end{verbatim}
\end{session}

The top goal is proved, so the system pops it from the goal stack
(and puts the proved theorem on a stack of theorems). The new top goal
is the step case of the induction. This goal is also solved by rewriting.

\begin{session}
\begin{verbatim}
#expand(ASM_REWRITE_TAC[PARITY_DEF]);;
OK..
goal proved
.. |- out(SUC t) = PARITY(SUC t)in
.. |- !t. out t = PARITY t in
|- !in out.
    (out 0 = T) /\ (!t. out(SUC t) = (in(SUC t) => ~out t | out t)) ==>
    (!t. out t = PARITY t in)

Previous subproof:
goal proved
\end{verbatim}
\end{session}

\noindent The goal is proved, \ie\ the empty list of subgoals is produced.
The system now applies
the justification functions produced by the 
tactics to the lists of theorems achieving the 
subgoals (starting with the empty list). 
These theorems are printed out in the order in which they are generated
(note that assumptions
of theorems are printed as dots).

The \ML\ function

{\small\baselineskip\HOLSpacing\begin{verbatim}
   save_top_thm : string -> thm
\end{verbatim}}

\noindent saves the theorem just proved (\ie\ on the top of the theorem stack)
in the current theory with a given name.

\begin{session}
\begin{verbatim}
#let UNIQUENESS_LEMMA = save_top_thm `UNIQUENESS_LEMMA`;;
UNIQUENESS_LEMMA = 
|- !in out.
    (out 0 = T) /\ (!t. out(SUC t) = (in(SUC t) => ~out t | out t)) ==>
    (!t. out t = PARITY t in)
\end{verbatim}
\end{session}

\noindent this saves the theorem in the theory {\small\verb%PARITY%} with name
{\small\verb%UNIQUENESS_LEMMA%} and also binds it to an \ML\ variable with the
 same name.

\section{Implementation}
\label{implementation}

The lemma just proved suggests that the parity checker can be implemented by
holding the parity value in a register and then complementing the contents
of the register whenever {\small\verb%T%} is input. To make the implementation
more interesting, it will be assumed that registers `power up' 
storing {\small\verb%F%}. Thus the output at time {\small\verb%0%} cannot be 
taken directly from a register,
because the output of the parity checker at time {\small\verb%0%} is 
specified to be {\small\verb%T%}. Another tricky thing to notice is that 
if {\small\verb%t>0%},
then the output of the parity checker at time {\small\verb%t%} is a 
function of the input at time {\small\verb%t%}. Thus there must be a 
combinational path from the input to the output.

The schematic diagram below shows the design of
a device that is intended to implement this specification.
(The leftmost input to \ml{MUX} is the selector.)
This works by storing the parity of the sequence input so far in the
lower of the two registers.  Each time {\small\verb%T%} is input at
{\small\verb%in%}, this stored value is complemented. Registers are assumed to
`power up' in a state in which they are storing {\small\verb%F%}.  The second
register (connected to {\small\verb%ONE%}) initially outputs
 {\small\verb%F%} and
then outputs {\small\verb%T%} forever.  Its role is just to ensure that the 
device
works during the first cycle by connecting the output {\small\verb%out%} to the
device {\small\verb%ONE%} via the lower multiplexer.  For all subsequent cycles
{\small\verb%out%} is connected to {\small\verb%l3%} and so either carries the
stored parity value (if the current input is {\small\verb%F%}) or the 
complement of this value (if the current input is {\small\verb%T%}).


\setlength{\unitlength}{5mm}
\begin{center}
\begin{picture}(14,30)(0,0.5)
\put(8,20){\framebox(2,2){\small{\tt NOT}}}
\put(6,16){\framebox(6,2){\small{\tt MUX}}}
\put(2,16){\framebox(2,2){\small{\tt ONE}}}
\put(2,12){\framebox(2,2){\small{\tt REG}}}
\put(6,8){\framebox(6,2){\small{\tt MUX}}}
\put(8,4){\framebox(2,2){\small{\tt REG}}}

\puthrule(9,24){4}
\puthrule(3,15){8}
\puthrule(3,11){4}
\puthrule(7,7){2}
\puthrule(9,3){4}

\putvrule(3,11){1}
\putvrule(3,14){2}
\putvrule(7,2){5}
\putvrule(7,10){1}
\putvrule(7,18){8}
\putvrule(9,3){1}
\putvrule(9,6){2}
\putvrule(9,10){6}
\putvrule(9,18){2}
\putvrule(9,22){2}
\putvrule(11,10){5}
\putvrule(11,18){6}
\putvrule(13,3){21}

\put(6,26){\makebox(2,2){\small{\tt in}}}
\put(6,0){\makebox(2,2){\small{\tt out}}}
\put(9,18){\makebox(1.8,2){\small{\tt l1}}}
\put(13,18){\makebox(1.8,2){\small{\tt l2}}}
\put(9,12){\makebox(1.8,2){\small{\tt l3}}}
\put(11,12){\makebox(1.8,2){\small{\tt l4}}}
\put(4,11){\makebox(3,1){\small{\tt l5}}}

\put(10,23){\makebox(2,2){$\bullet$}}
\put(8,6){\makebox(2,2){$\bullet$}}
\put(2,14){\makebox(2,2){$\bullet$}}

\end{picture}
\end{center}
\setlength{\unitlength}{1mm}


The devices making up this schematic will be modelled with predicates
\cite{Why-HOL-paper}. For example, the predicate {\small\verb%ONE%} is true 
of a signal {\small\verb%out%} if for all times {\small\verb%t%} the value of
{\small\verb%out%} is {\small\verb%T%}.

\begin{session}
\begin{verbatim}
#let ONE_DEF =
# new_definition
#  (`ONE_DEF`, "ONE(out:num->bool) = !t. out t = T");;
ONE_DEF = |- !out. ONE out = (!t. out t = T)
\end{verbatim}
\end{session}

\noindent Note that, as discussed above, `{\small\verb%ONE_DEF%}'  is used both
as an \ML\ variable and as the name of the definition in the theory
{\small\verb%PARITY%}.  Note  also  how  `{\small\verb%:num->bool%}' has been
added to resolve type ambiguities; without this (or some other type
information) the typechecker would not be able to  infer that  {\small\tt t} is
to have type {\small\tt num}.

The binary predicate {\small\verb%NOT%} is true of a pair of signals
{\small\verb%(in,out)%} 
if the value of {\small\verb%out%} is always the negation of the value of
{\small\verb%in%}. Inverters are thus modelled
as having no delay. This is appropriate
for a register-transfer level model, but not at a lower level.

\begin{session}
\begin{verbatim}
#let NOT_DEF =
# new_definition
#  (`NOT_DEF`, "NOT(in,out:num->bool) = !t. out t = ~(in t)");;
NOT_DEF = |- !in out. NOT(in,out) = (!t. out t = ~in t)
\end{verbatim}
\end{session}

\noindent The final combinational device needed is a multiplexer.
This is a `hardware conditional'; the input 
{\small\verb%sw%} selects which of the other
two inputs are to be connected to the output {\small\verb%out%}.

\begin{session}
\begin{verbatim}
#let MUX_DEF =
# new_definition
#  (`MUX_DEF`, 
#   "MUX(sw,in1,in2,out:num->bool) = 
#     !t. out t = (sw t => in1 t | in2 t)");;
MUX_DEF = 
|- !sw in1 in2 out.
    MUX(sw,in1,in2,out) = (!t. out t = (sw t => in1 t | in2 t))
\end{verbatim}
\end{session}

The remaining devices in the schematic are registers.
These are unit-delay elements; the values output at time {\small\verb%t+1%} are
the values input at the preceding time {\small\verb%t%}, 
except at time {\small\verb%0%}
when the register
outputs {\small\verb%F%}.\footnote{Time {\tt {\small 0}} 
represents when the device is switched on.}

\begin{session}
\begin{verbatim}
#let REG_DEF =
# new_definition
# (`REG_DEF`, "REG(in,out:num->bool) = 
#              !t. out t = ((t=0) => F | in(t-1))");;
REG_DEF = 
|- !in out. REG(in,out) = (!t. out t = ((t = 0) => F | in(t - 1)))
\end{verbatim}
\end{session}

The schematic diagram above can be represented as a predicate by
conjoining the relations holding between the various 
signals and then existentially quantifying the internal lines.
This technique is explained elsewhere 
(\eg\ see \cite{Camilleri-et-al,Why-HOL-paper}).

\begin{session}
\begin{verbatim}
#let PARITY_IMP_DEF =
# new_definition
#  (`PARITY_IMP_DEF`,
#   "PARITY_IMP(in,out) =
#    ?l1 l2 l3 l4 l5. 
#     NOT(l2,l1) /\ MUX(in,l1,l2,l3) /\ REG(out,l2) /\
#     ONE l4     /\ REG(l4,l5)       /\ MUX(l5,l3,l4,out)");;
PARITY_IMP_DEF = 
|- !in out.
    PARITY_IMP(in,out) =
    (?l1 l2 l3 l4 l5.
      NOT(l2,l1) /\
      MUX(in,l1,l2,l3) /\
      REG(out,l2) /\
      ONE l4 /\
      REG(l4,l5) /\
      MUX(l5,l3,l4,out))
\end{verbatim}
\end{session}\label{parity-imp}

\section{Verification}

The following theorem will eventually be proved:
{\small\baselineskip\HOLSpacing\begin{verbatim}
   |- !in out. PARITY_IMP(in,out) ==> (!t. out t = PARITY t in)
\end{verbatim}}
This states that {\it if\/} {\small\verb%in%} and {\small\verb%out%} 
are related as in the schematic
diagram (\ie\ as in the definition of {\small\verb%PARITY_IMP%}), 
{\it then\/} the 
pair of signals {\small\verb%(in,out)%} satisfies the specification.

First, the following lemma is proved; the correctness of the parity checker
 follows from this and 
{\small\verb%UNIQUENESS_LEMMA%} by the transitivity of {\small{\tt\verb+==>+}}.

\begin{session}
\begin{verbatim}
#set_goal
# ([], "!in out. 
#         PARITY_IMP(in,out) ==> 
#         (out 0 = T) /\ 
#         !t. out(SUC t) = (in(SUC t) => ~(out t) | out t)");;
"!in out.
  PARITY_IMP(in,out) ==>
  (out 0 = T) /\ (!t. out(SUC t) = (in(SUC t) => ~out t | out t))"
\end{verbatim}
\end{session}

The first step in proving this goal is to rewrite with definitions 
followed by a decomposition of the resulting goal using 
{\small\verb%STRIP_TAC%}. The rewriting
tactic {\small\verb%PURE_REWRITE_TAC%} is used; this
does no built-in simplifications, only the ones
explicitly given in the list of theorems supplied as an argument. 
One of the
built-in simplifications used by
{\small\verb%REWRITE_TAC%} is {\small\tt |-~(x~=~T)~=~x}. 
{\small\verb%PURE_REWRITE_TAC%} is used to prevent rewriting with this being done.
\begin{session}
\begin{verbatim}
#expand(PURE_REWRITE_TAC
#        [PARITY_IMP_DEF;ONE_DEF;NOT_DEF;MUX_DEF;REG_DEF]
#        THEN REPEAT STRIP_TAC);;
OK..
2 subgoals
"out(SUC t) = (in(SUC t) => ~out t | out t)"
    [ "!t. l1 t = ~l2 t" ]
    [ "!t. l3 t = (in t => l1 t | l2 t)" ]
    [ "!t. l2 t = ((t = 0) => F | out(t - 1))" ]
    [ "!t. l4 t = T" ]
    [ "!t. l5 t = ((t = 0) => F | l4(t - 1))" ]
    [ "!t. out t = (l5 t => l3 t | l4 t)" ]

"out 0 = T"
    [ "!t. l1 t = ~l2 t" ]
    [ "!t. l3 t = (in t => l1 t | l2 t)" ]
    [ "!t. l2 t = ((t = 0) => F | out(t - 1))" ]
    [ "!t. l4 t = T" ]
    [ "!t. l5 t = ((t = 0) => F | l4(t - 1))" ]
    [ "!t. out t = (l5 t => l3 t | l4 t)" ]
\end{verbatim}
\end{session}

The top goal is the one printed last; its conclusion is 
{\small\verb%out 0 = T%} and its assumptions are
equations relating the values on the lines in the circuit.
The natural next step is to expand the top goal
by rewriting with the assumptions.
However, if this is done the system will go into an infinite 
loop because the equations 
for {\small\verb%out%}, {\small\verb%l2%} and {\small\verb%l3%} are mutually
recursive. To prevent looping,
rewriting must be done with a non-looping subset of the assumptions. 

To enable the assumptions corresponding to particular lines to
be selected for rewriting, an \ML\ function {\small\verb%lines%} is defined
such that {\small\verb%lines `%}$l_1\ldots l_n${\small\verb%` %}$t$ is 
true whenever $t$ has the
form {\small\verb%"!t. %}$l_i${\small\verb% t = %}$\cdots${\small\verb% "%} 
for some $l_i$ in the
set specified by the string {\small\verb%`%}$l_1\ldots l_n${\small\verb%`%}. 
The functions
{\small\verb%words%} and {\small\verb%rator%} used below
are predeclared in \ML.
\begin{session}
\begin{verbatim}
#let lines tok t =
# (let x = fst(dest_var(rator(lhs(snd(dest_forall t)))))
#  in
#  mem x (words tok)) ? false;;
lines = - : (string -> term -> bool)
\end{verbatim}
\end{session}
{\small\verb%FILTER_ASM_REWRITE_TAC(lines`out l4 l5`)[]%}
is a tactic which rewrites 
with only those assumptions that involve {\small\verb%out%},
{\small\verb%l4%} and {\small\verb%l5%}.
\begin{session}
\begin{verbatim}
#expand(FILTER_ASM_REWRITE_TAC(lines`out l4 l5`)[]);;
OK..
goal proved
... |- out 0 = T

Previous subproof:
"out(SUC t) = (in(SUC t) => ~out t | out t)"
    [ "!t. l1 t = ~l2 t" ]
    [ "!t. l3 t = (in t => l1 t | l2 t)" ]
    [ "!t. l2 t = ((t = 0) => F | out(t - 1))" ]
    [ "!t. l4 t = T" ]
    [ "!t. l5 t = ((t = 0) => F | l4(t - 1))" ]
    [ "!t. out t = (l5 t => l3 t | l4 t)" ]
\end{verbatim}
\end{session}
The first of the two subgoals
is proved.  Inspecting the remaining 
goal it can be seen that it will be solved if its left hand side,
{\small\verb%out(SUC t)%}, is expanded using the assumption:
\medskip

{\small\verb%!t. out t = (l5 t => l3 t | l4 t)%}

\medskip
However, if this assumption is used for rewriting, 
then all the subterms of the form {\small\verb%out t%} will also
be expanded. To prevent this, the messy and \adhoc\ tactic shown
below will be used. 

{\small\baselineskip\HOLSpacing\begin{verbatim}
   FIRST_ASSUM
    (\th. if lines`out`(concl th) 
           then SUBST_TAC[SPEC "SUC t" th]
           else NO_TAC)
\end{verbatim}}

{\small\verb%FIRST_ASSUM%}~$f$ is a built-in tactical 
that applies $f$ in succession to the assumed assumptions of the goal;
the tactic resulting from the first successful application is applied.
The argument to {\small\verb%FIRST_ASSUM%} used here is:

{\small\baselineskip\HOLSpacing\begin{verbatim}
   (\th. if lines`out`(concl th) 
          then SUBST_TAC[SPEC "SUC t" th]
          else NO_TAC)
\end{verbatim}}

\noindent which converts a theorem of the form:

\medskip

{\small\verb%  |- !t. out t = %}$tm${\small\verb%[t]%}

\medskip

\noindent
to a tactic that replaces occurrences of
{\small\verb%out(SUC t)%} by $tm${\small\verb%[SUC t]%}.
All other theorems are mapped to {\small\verb%NO_TAC%}, 
a tactic that always fails.

\begin{session}
\begin{verbatim}
#expand
# (FIRST_ASSUM
#   (\th. if lines`out`(concl th) 
#          then SUBST_TAC[SPEC "SUC t" th]
#          else NO_TAC));;
OK..
"(l5(SUC t) => l3(SUC t) | l4(SUC t)) = (in(SUC t) => ~out t | out t)"
    [ "!t. l1 t = ~l2 t" ]
    [ "!t. l3 t = (in t => l1 t | l2 t)" ]
    [ "!t. l2 t = ((t = 0) => F | out(t - 1))" ]
    [ "!t. l4 t = T" ]
    [ "!t. l5 t = ((t = 0) => F | l4(t - 1))" ]
    [ "!t. out t = (l5 t => l3 t | l4 t)" ]
\end{verbatim}
\end{session}

The fact that this messy use
of {\small\verb%FIRST_ASSUM%} was resorted to in the proof shown above
illustrates both the strengths and weaknesses of \HOL.
Trivial deductions sometimes require elaborate tactics, but on the
other hand one never reaches an impasse. \HOL\ experts can prove 
arbitrarily complicated theorems if
they are willing to use sufficient ingenuity. Furthermore, 
the type discipline ensures
that no matter how complicated and \adhoc\ are the tactics, it is impossible
to prove an invalid theorem.

Inspecting the goal above, it can be seen that the next step is to unwind
the equations for lines {\small\verb%l1%}, 
{\small\verb%l3%}, {\small\verb%l4%} and {\small\verb%l5%}
and then, when this is done, unwind with the equation for line
{\small\verb%l2%}.
\vfill
\newpage

\begin{session}
\begin{verbatim}
#expand(FILTER_ASM_REWRITE_TAC(lines`l1 l3 l4 l5`)[]
#        THEN FILTER_ASM_REWRITE_TAC(lines`l2`)[]);;
OK..
"(((SUC t = 0) => F | T) => 
  (in(SUC t) => 
   ~((SUC t = 0) => F | out((SUC t) - 1)) | 
   ((SUC t = 0) => F | out((SUC t) - 1))) | 
  T) =
 (in(SUC t) => ~out t | out t)"
    [ "!t. l1 t = ~l2 t" ]
    [ "!t. l3 t = (in t => l1 t | l2 t)" ]
    [ "!t. l2 t = ((t = 0) => F | out(t - 1))" ]
    [ "!t. l4 t = T" ]
    [ "!t. l5 t = ((t = 0) => F | l4(t - 1))" ]
    [ "!t. out t = (l5 t => l3 t | l4 t)" ]
\end{verbatim}
\end{session}

This goal can now be solved by rewriting with two
standard built-in theorems:

{\small\baselineskip\HOLSpacing\begin{verbatim}
   NOT_SUC   =     |- !n. ~(SUC n = 0)

   SUC_SUB1  =     |- !m. (SUC m) - 1 = m
\end{verbatim}}

\begin{session}
\begin{verbatim}
#expand(REWRITE_TAC[NOT_SUC;SUC_SUB1]);;
OK..
Theorem SUC_SUB1 autoloaded from theory `arithmetic`.
SUC_SUB1 = |- !m. (SUC m) - 1 = m

OK..
goal proved
|- (((SUC t = 0) => F | T) => 
    (in(SUC t) => 
     ~((SUC t = 0) => F | out((SUC t) - 1)) | 
     ((SUC t = 0) => F | out((SUC t) - 1))) | 
    T) =
   (in(SUC t) => ~out t | out t)
..... |- (l5(SUC t) => l3(SUC t) | l4(SUC t)) =
         (in(SUC t) => ~out t | out t)
...... |- out(SUC t) = (in(SUC t) => ~out t | out t)
|- !in out.
    PARITY_IMP(in,out) ==>
    (out 0 = T) /\ (!t. out(SUC t) = (in(SUC t) => ~out t | out t))

Previous subproof:
goal proved
\end{verbatim}
\end{session}

\noindent The theorem just proved is named
{\small\verb%PARITY_LEMMA%} and saved in the current theory.

\begin{session}
\begin{verbatim}
#let PARITY_LEMMA = save_top_thm `PARITY_LEMMA`;;
PARITY_LEMMA = 
|- !in out.
    PARITY_IMP(in,out) ==>
    (out 0 = T) /\ (!t. out(SUC t) = (in(SUC t) => ~out t | out t))
\end{verbatim}
\end{session}

{\small\verb%PARITY_LEMMA%} could have been proved in one step with a single
compound tactic. This is illustrated below:

\begin{session}
\begin{verbatim}
#set_goal
# ([], "!in out. 
#         PARITY_IMP(in,out) ==> 
#         (out 0 = T) /\ 
#         !t. out(SUC t) = (in(SUC t) => ~(out t) | out t)");;
"!in out.
  PARITY_IMP(in,out) ==>
  (out 0 = T) /\ (!t. out(SUC t) = (in(SUC t) => ~out t | out t))"
\end{verbatim}
\end{session}

\noindent This goal can be expanded with a single tactic corresponding to the
sequence of tactics that were used interactively.

\begin{session}
\begin{verbatim}
#expand
# (PURE_REWRITE_TAC[PARITY_IMP_DEF;ONE_DEF;NOT_DEF;MUX_DEF;REG_DEF]
#  THEN REPEAT STRIP_TAC
#  THENL
#   [FILTER_ASM_REWRITE_TAC(lines`out l4 l5`)[];ALL_TAC]
#  THEN FIRST_ASSUM
#        (\th. if lines`out`(concl th) 
#               then SUBST_TAC[SPEC "SUC t" th]
#               else NO_TAC)
#  THEN FILTER_ASM_REWRITE_TAC(lines`l1 l3 l4 l5`)[]
#  THEN FILTER_ASM_REWRITE_TAC(lines`l2`)[]
#  THEN REWRITE_TAC[NOT_SUC;SUC_SUB1]);;
OK..
goal proved
|- !in out.
    PARITY_IMP(in,out) ==>
    (out 0 = T) /\ (!t. out(SUC t) = (in(SUC t) => ~out t | out t))

Previous subproof:
goal proved
\end{verbatim}
\end{session}

Armed with {\small\verb%PARITY_LEMMA%}, 
the final theorem is easily proved.
This will be done in one step using the \ML\ function
{\small\verb%prove_thm%}.
\vfill
\newpage

\begin{session}
\begin{verbatim}
#let PARITY_CORRECT =
# prove_thm
#  (`PARITY_CORRECT`,
#   "!in out. PARITY_IMP(in,out) ==> (!t. out t = PARITY t in)",
#   REPEAT GEN_TAC
#    THEN DISCH_TAC
#    THEN IMP_RES_TAC PARITY_LEMMA
#    THEN IMP_RES_TAC UNIQUENESS_LEMMA);;
PARITY_CORRECT = 
|- !in out. PARITY_IMP(in,out) ==> (!t. out t = PARITY t in)

#close_theory();;
() : void
\end{verbatim}
\end{session}

\noindent This completes the proof of the
parity checking device. 

\section{Exercises}
\label{exercises}

Two exercises are given in this section:
Exercise~1 is straightforward, but Exercise~2 is quite tricky and
might take a beginner several days to solve. The solutions to these exercises are
in the files:

\begin{hol}\begin{verbatim}
   hol/Training/parity/RESET_REG.ml
   hol/Training/parity/RESET_PARITY.ml
\end{verbatim}\end{hol}


\subsection{Exercise 1}

Using {\it only\/} the devices {\small\verb%ONE%}, {\small\verb%NOT%},
{\small\verb%MUX%} and {\small\verb%REG%} defined in Section~\ref{implementation},
design and verify a register {\small\verb%RESET_REG%} 
with an input {\small\verb%in%}, reset line {\small\verb%reset%},
output {\small\verb%out%} and behaviour specified as follows.
\begin{itemize}
\item If {\small\verb%reset%} is {\small\verb%T%} at time {\small\verb%t%},
then the value at {\small\verb%out%} at time {\small\verb%t%} is also
{\small\verb%T%}.
\item If {\small\verb%reset%} is {\small\verb%T%} at time {\small\verb%t%} or
{\small\verb%t+1%},
then the value output at {\small\verb%out%} at time {\small\verb%t+1%} is
{\small\verb%T%}, otherwise it is equal to
the value input at time {\small\verb%t%} on {\small\verb%in%}.
\end{itemize}
This is formalized in \HOL\ by the definition:

{\small\baselineskip\HOLSpacing\begin{verbatim}
   RESET_REG(reset,in,out) =
    (!t. reset t ==> (out t = T)) /\
    (!t. out(t+1) = ((reset t  \/ reset(t+1)) => T | in t))
\end{verbatim}}

\noindent Note that this specification is only partial; it doesn't specify the
output at time {\small\verb%0%} in the case that there is no reset.

The solution to the exercise should be a definition of a predicate
{\small\verb%RESET_REG_IMP%} as an existential quantification  of a conjunction
of applications  of  {\small\verb%ONE%}, {\small\verb%NOT%}, {\small\verb%MUX%}
and {\small\verb%REG%} to suitable line  names,\footnote{i.e.   a definition of
the same form as that of {\small\tt PARITY\_IMP} on page~\pageref{parity-imp}.}
together with a proof of:

{\small\baselineskip\HOLSpacing\begin{verbatim}
   RESET_REG_IMP(reset,in,out) ==> RESET_REG(reset,in,out)
\end{verbatim}}


\subsection{Exercise 2}

\begin{enumerate}
\item Formally specify a resetable parity checker that has two boolean
inputs {\small\tt reset}
and {\small\tt in}, and one boolean 
output {\small\tt out} with the following behaviour:
\begin{quote}
The value at {\small\tt out} is {\small\tt T} if and only if there
have been an even number of {\small\tt T}s input at {\small\tt in} since
the last time that {\small\tt T} was input at {\small\tt reset}.
\end{quote}
\item Design an implementation of this specification built
using {\it only\/} the devices {\small\verb%ONE%}, {\small\verb%NOT%},
{\small\verb%MUX%} and {\small\verb%REG%} defined in Section~\ref{implementation}.
\item Verify the correctness of your implementation in \HOL.
\end{enumerate}
