\chapter{The numeral Library}

This manual describes the use of the \ml{numeral} library.  The library allows
HOL to automatically simplify arithmetic expressions that contain numbers, and
does it in a way that efficiently copes with large numbers.

\section{The problem the numeral library addresses}

The HOL kernel has built-in mechanisms for naming and defining whole-number
constants.  Any parse token that is a series of digits (where 0,1,...8,9 are
digits) is taken to be the name of a numeric constant.  The constant 0 has a
built-in definition, and the function {\ml num\_CONV} can be used to generate
the definition of any non-zero numeric constant.

Proofs about numeric expressions are extremely tedious if done directly with
the definitions provided by {\ml num\_CONV}.  The reduce library defines
functions that allow HOL to automatically simplify arithmetic expressions that
contain numbers, but the functions are very slow when applied to expressions
containing large numbers.  (The number of inferences involved in simplifying an
expression is often proportional to the numbers involved, or even to the square
of the numbers involved.)

The numeral library defines another set of functions for simplifying arithmetic
expressions, but is much more efficient when applied to expressions containing
large numbers.  (The number of inferences is often proportional to the log of
the numbers involved, or to the square of the log.)  In fact, the numeral
library's functions are substantially faster for all but single-digit numbers,
and are about as fast for those.  The disadvantage is that the numeral library
requires the use of a different representation for numbers.

\section{The theory of numerals}

The numeral library depends on HOL's mechanism for defining digits zero through
{$r-1$} (where $r$ is the radix),{\footnote Actually, the numeral library uses
HOL's mechanism to define constants from zero up to {$r\sup{2}$}, where {$r$}
is the largest radix supported (currently 16).  This is more than just zero
through {$r-1$}, but it is still finite, and relatively small.} and then groups
the digits into lists.  The numeral representation is interpreted by new HOL
constants, the most visible of which is "BASEN".  For example, using the
numeral library, the number 56789 can be represented by a base-10 numeral:
{\ml "BASEN 10 [5;6;7;8;9]"}.  The library includes functions that generate
proofs of equivalence between the numeral representation and the
numeric-constant representation, returning theorems like this:

\begin{hol}\begin{verbatim}
        |- 56789 = BASEN 10 [5;6;7;8;9]
\end{verbatim}\end{hol}

The HOL constant {\ml "BASEN: num -> num list -> num"} is a function from the
numeral representation of a number to the value of the number.  The value of
the numeral is the sum of the digits, after each digit has been multiplied by
its place value.  Note that this representation allows an infinite number of
representations (in the same radix) for each number.  One source of redundant
representations is denormalized numerals (that is, numerals with leading zero
digits).  So, for example:

\begin{hol}\begin{verbatim}
        |- BASEN 10 [0;0;0;3;4;5] = BASEN 10 [3;4;5]
\end{verbatim}\end{hol}

The HOL constant {\ml "IS\_NORMALIZED: num list -> bool"} returns true if and
only if its argument (a digit list) is normalized.  Thus:

\begin{hol}\begin{verbatim}
        |- ( (IS_NORMALIZED [3;4;5]) = T ) /\
           ( (IS_NORMALIZED [0;0;0;3;4;5]) = F )
\end{verbatim}\end{hol}

A less expected feature of the representation is that a numeral's digits need
not be less than the radix.  For example:

\begin{hol}\begin{verbatim}
        |- BASEN 10 [3;4;11] = 351
\end{verbatim}\end{hol}

The HOL constant {\ml "IS\_BASEN: num -> num list -> bool"} is a function of a
radix and a list of digits.  {\ml IS\_BASEN} returns true if the list contains
only digits less than the radix, and returns false otherwise.  Thus:

\begin{hol}\begin{verbatim}
        |- IS_BASEN 10 [3;4;11] = F
\end{verbatim}\end{hol}

Together these two constraints define a canonical representation for a number
in each radix.  The library's functions will handle expressions containing
unnormalized numerals, but will not generally handle numerals with digits
larger than the radix.  (Reduced forms generated by the library are always in
canonical form.)

The library also defines abbreviations for four particular radices: decimal,
hexadecimal, octal, and binary.  So for example:

\begin{hol}\begin{verbatim}
        |- DECIMAL [5;1;9] = BASEN 10 [5;1;9]

        |- HEX [9;10;11;12] = BASEN 16 [9;10;11;12]

        |- OCTAL = BASEN 8

        |- BINARY = BASEN 2
\end{verbatim}\end{hol}

\section{The numeral library's functions}

The functions provided in the library can be used to reduce arithmetic and
logical expressions containing numerals. An expression or subexpression will
be completely reduced (that is, reduced to a single numeral or truth value)
if it contains only numerals (in a single radix), logical operators (/\, \/, ~,
==>, and =>), and the following arithmetic operators:

\begin{hol}\begin{verbatim}
  Complexity    Operator
  ----------    -----------------------------------------------------------
  O(log n)      +       -       SUC     PRE
                =       <       <=      >       >=      IS_BASEN
  O((log n)^2)  *       DIV     MOD
  O((log n)^3)  EXP
\end{verbatim}\end{hol}

The left column of the table gives the complexity of reducing a simple
expression, as a function of the length of the numerals.  Thus an addition of
two numerals takes time proportional to the number of digits in the addend
plus the number of digits in the augend.  (It's about 10 primitive inferences
per digit.)  A multiplication takes time proportional to the number of digits
in the multiplicand times the number of digits in the multiplier.


\section{Using the library}

To use the library in a HOL session, do:

\begin{hol}\begin{verbatim}
        load_library `numeral`;;
\end{verbatim}\end{hol}

Because the numeral library depends on some extensions to basic HOL theories,
and such extensions can be loaded only while HOL is in draft mode, HOL must be
in draft mode for this to succeed.  To put your HOL session in draft mode if it
is not, start a new theory, with a command like:

\begin{hol}\begin{verbatim}
        new_theory `foo`;;
\end{verbatim}\end{hol}

Once the library is loaded, the following ML functions are sufficient for
normal use of the library.

The ML function {\ml BASEN\_OF\_NUM\_CONV} can be used to convert a number from
a numeric constant representation to a numeral representation.  For example:

\begin{hol}\begin{verbatim}
    #BASEN_OF_NUM_CONV "BASEN_OF_NUM 10 234";;
    |- 234 = BASEN 10 [2;3;4]
\end{verbatim}\end{hol}

The ML function {\ml BASEN\_CONV } can be used to convert a number from a
numeral representation to a numeric constant representation.

\begin{hol}\begin{verbatim}
    #BASEN_CONV "BASEN 2 [1;0;0;0]";;
    |- BASEN 2 [1;0;0;0] = 8
\end{verbatim}\end{hol}

Together, {\ml BASEN\_OF\_NUM\_CONV } and {\ml BASEN\_CONV } allow you to mix
numeric-constant representations and numeral representations within a proof.
Note in particular that you may begin a proof, and part-way through may choose
to load the numeral library for assistance.  Using the library's functions, you
can change numeric constants to numerals, then reduce expressions, then (if
desired) convert the results back into numeric constants.

The reduction is accomplished by an ML function that has three forms:

{\ml NUM\_ARITH\_CONV} takes a term, and returns a theorem saying that the
expression in the term is equal to its reduced version.  For example:

\begin{hol}\begin{verbatim}
    NUM_ARITH_CONV "DECIMAL [3;4;5] + DECIMAL [7;7]";;
    |- DECIMAL [3;4;5] + DECIMAL [7;7] = DECIMAL [4;2;2]

    NUM_ARITH_CONV "(DECIMAL [3] * 4) + ((DECIMAL [6]) DIV (DECIMAL [2]))";;
    |- (DECIMAL [3] * 4) + ((DECIMAL [6]) DIV (DECIMAL [2])) =
       (DECIMAL [3] * 4) + DECIMAL [3]

    NUM_ARITH_CONV "(DECIMAL [5;6;7] < DECIMAL [8;9;4;2]) /\
       ((DECIMAL [2;2] * DECIMAL [3]) >= DECIMAL [4;1])";;
    |- ((DECIMAL [5;6;7] < DECIMAL [8;9;4;2]) /\
        ((DECIMAL [2;2] * DECIMAL [3]) >= DECIMAL [4;1])) = T
\end{verbatim}\end{hol}

{\ml NUM\_ARITH\_RULE} takes a theorem, and returns a theorem with all subterms
reduced as {\ml NUM\_ARITH\_CONV} reduces them.

{\ml NUM\_ARITH\_TAC} performs the same reductions on a goal.

These functions are a convenient packaging of a few dozen much more specific
functions.  If you need more control of the reduction, or if you need to apply
reductions more efficiently, you can use the more specific functions directly.

\section{A solicitation of volunteers}

The current HOL mechanism for dealing with numbers requires a infinite number
of constant definitions (one for each number).  HOL gets around the need for an
infinite initial theory by using {\ml num\_CONV}, which uses {\ml mk\_thm} to
generate the definition for any particular numeric constant.  The numeral
package reduces the problem of defining an infinite set of numeric constants to
one of representing an infinity of lists, which the HOL kernel already does
much more satisfactorily.

Eventually, the numeral library should be integrated into the HOL kernel, so
that HOL's current mechanism for numeric constants can be replaced with the
few ordinary definitions needed for numerals.  The parser and pretty printer
can provide the obvious syntactic sugar so that most users won't see a
difference.  I am unlikely to do the integration myself.  If anyone else is
interested in doing it, please let me know.
