\chapter{The taut Library}

This document describes the facilities provided by the \ml{taut} library
for the HOL system~\cite{description}. Functions for proving propositional
formulae and instances of propositional formulae are provided. There is a
conversion which given a universally quantified propositional term proves it
to be either true or false, a conversion which given a valid propositional
formula returns it as a theorem, and a tactic for proving propositional goals.
There are also similar conversions and tactics for proving instances of
propositional formulae.

The library is designed for proving propositional formulae valid (true under
all interpretations), but if the argument formula is closed (with universal
quantifiers), the main function (\ml{PTAUT\_CONV}) is capable of evaluating
the formula to either true or false. The function assumes that any variable
occurring free is to be taken as universally quantified. \ml{PTAUT\_CONV} is
described in more detail below.

Given a term of the form {\small\verb%"!x1 ... xn. t"%} where {\small\verb%t%}
contains only Boolean constants, Boolean-valued variables, Boolean equalities,
implications, conjunctions, disjunctions, negations and Boolean-valued
conditionals, and all the variables in {\small\verb%t%} appear in
{\small\verb%x1 ... xn%}, the conversion \ml{PTAUT\_CONV} proves the term to be
either true or false, that is, one of the following theorems is returned:

\begin{boxed}\begin{verbatim}
   |- (!x1 ... xn. t) = T
   |- (!x1 ... xn. t) = F
\end{verbatim}\end{boxed}

\noindent
\ml{PTAUT\_CONV} also accepts propositional terms that are not fully
universally quantified. However, for such a term, the conversion will only
succeed if the term is valid.

\ml{PTAUT\_CONV} has two failure modes. The failure string
{\small\verb%`PTAUT_CONV`%} indicates that the argument term is not a
propositional formula. The string:

\begin{small}\begin{verbatim}
   `PTAUT_CONV -- false for at least one interpretation`
\end{verbatim}\end{small}

\noindent
indicates that the argument term is not fully universally quantified and is
false for at least one interpretation of the variables.

The conversion \ml{TAUT\_CONV} performs a similar operation to \ml{PTAUT\_CONV}
but also works for instances of propositional formulae provided they are
valid (it won't prove invalid formulae false). An
instance\index{instantiation of variables!with terms} of a propositional
formula is a formula in which one or more of the variables have been replaced
by terms of the same type. \ml{TAUT\_CONV} does not require the variables of
the formula to be universally quantified but will accept such terms.


\section{An outline of the method of proof}

A propositional formula is proved true or false by performing a Boolean case
analysis\index{case analysis!on Boolean values} on each of the variables in
the formula. The outermost universally quantified variable is chosen and two
new formulae are generated: one with the variable replaced by {\small\verb%T%}
(true) and the other with the variable replaced by {\small\verb%F%} (false). A
propositional simplifier\index{simplifier!for propositional formulae} is
then called on each of these formulae. The entire process of
instantiation\index{instantiation of variables!with true and false} and
simplification is repeated for each of the resulting formulae. When all the
variables have been instantiated, the simplifier will return either
{\small\verb%T%} or {\small\verb%F%}.

Suppose the original formula was of the form {\small\verb%"!x. f[x]"%}. If the
theorems returned from the subcalls are {\small\verb%|- f[T] = T%} and
{\small\verb%|- f[F] = T%}, we can deduce {\small\verb%|- (!x. f[x]) = T%}. If
either of the results are {\small\verb%F%} we can deduce that
{\small\verb%|- (!x. f[x]) = F%}.

\index{optimization}
The procedure is optimized for terms with more than two variables by
eliminating\index{duplicated subcalls!elimination of} some duplicated
subcalls. These arise if having instantiated a variable the two new formulae
simplify to the same term. The procedure is also optimized for cases when the
body simplifies to true or false before all the variables have been analysed.
Also, the simplification function is optimized to
avoid\index{rebuilding terms!avoiding when no change} rebuilding subterms
that are not changed.

Experiments have been performed with special code for cases when the first
argument of a conjunction, disjunction, implication, or conditional simplifies
to a value that makes simplification of certain other arguments unnecessary.
For example, if the first argument of a conjunction is false the entire
conjunction must be false. The results suggested that in general slightly
fewer intermediate theorems are generated, but that due to the overhead of
testing, the execution times are slightly longer.

Instances of propositional formulae are proved by replacing the
non-propositional subterms with unique variables. The procedure for purely
propositional formulae is used to prove this generalized formula (if possible).
The result is then specialized to obtain a theorem for the original formula.


\section{Proving formulae containing free variables}

In addition to closed terms, the \ml{PTAUT\_CONV} function accepts
propositional terms that are not fully universally quantified. However, for
such a term, the conversion will fail unless it is valid. Consider the term
{\small\verb%"!x2 ... xn. f[x1,...,xn]"%}. The conversion first proves one of
the following theorems:

\begin{boxed}\begin{verbatim}
   |- (!x1 ... xn. f[x1,...,xn]) = T
   |- (!x1 ... xn. f[x1,...,xn]) = F
\end{verbatim}\end{boxed}

\noindent
To obtain the required result, the former can be manipulated as follows:

\begin{boxed}\begin{verbatim}
   |- (!x1 ... xn. f[x1,...,xn]) = T
   |- !x1 ... xn. f[x1,...,xn]
   |- !x2 ... xn. f[x1,...,xn]
   |- (!x2 ... xn. f[x1,...,xn]) = T
\end{verbatim}\end{boxed}

\noindent
However when the fully quantified term is false, we have:

\begin{boxed}\begin{verbatim}
   |- (!x1 ... xn. f[x1,...,xn]) = F
   |- ~(!x1 ... xn. f[x1,...,xn])
   |- ?x1. ~(!x2 ... xn. f[x1,...,xn])
   |- ?x1. ((!x2 ... xn. f[x1,...,xn]) = F)
\end{verbatim}\end{boxed}

\noindent
whereas we want:

\begin{boxed}\begin{verbatim}
   |- !x1. ((!x2 ... xn. f[x1,...,xn]) = F)
\end{verbatim}\end{boxed}

\noindent
because it is equivalent to:

\begin{boxed}\begin{verbatim}
   |- (!x2 ... xn. f[x1,...,xn]) = F
\end{verbatim}\end{boxed}

\noindent
The conversions in the \ml{taut} library are not capable of proving this
theorem.


\section{Using the library}

The \ml{taut} library can be loaded into a user's \HOL\ session using the
function \ml{load\_library}\index{load\_library@{\ptt load\_library}} (see the
\HOL\ manual for a general description of library loading). The first action
in the load sequence initiated by \ml{load\_library} is to update the \HOL\
help\index{help!updating search path} search path. The help search path is
updated with a pathname to online help files for the \ML\ functions in the
library. After updating the help search path, the \ML\ functions in the
library are loaded into \HOL.

The following session shows how the \ml{taut} library may be loaded using
\ml{load\_library}:

\setcounter{sessioncount}{1}
\begin{session}\begin{verbatim}
#load_library `taut`;;
Loading library `taut` ...
Updating help search path
........................................
Library `taut` loaded.
() : void

#
\end{verbatim}\end{session}
