% --------------------------------------------------------------------------- %
% DIRECTORY: boyer-moore						      %
%									      %
% DESCRIPTION: Boyer-Moore Automation for HOL				      %
%									      %
% AUTHORS: Richard J. Boulton						      %
%									      %
% ADDRESS: University of Cambridge Computer Laboratory			      %
%	   New Museums Site						      %
%          Pembroke Street						      %
%	   Cambridge, CB2 3QG						      %
%	   England							      %
%									      %
%	   email: rjb@cl.cam.ac.uk					      %
%									      %
% DATE: 92.10.16							      %
% --------------------------------------------------------------------------- %

This directory contains an implementation for the HOL system
(HOL88 Version 2.01) of Boyer and Moore's automatic proof heuristics. The code
is based on the description in `A Computational Logic' and so does not reflect
the advances made to the Boyer-Moore theorem prover since 1979. There are many
limitations, the most significant of which is the assumption that recursive
functions are defined in a `constructor-style' according to the restrictions
of the automatic definition tools currently available in HOL. The code was
written more as an experiment than as a practical tool. However, it may be
found to be useful. Minimal documentation can be found below.

Richard Boulton, 16th October 1992.


% --------------------------------------------------------------------------- %
% References								      %
% --------------------------------------------------------------------------- %

R. S. Boyer and J S. Moore.
"A Computational Logic".
ACM Monograph Series. Academic Press, New York, 1979.

R. J. Boulton.
"Boyer-Moore Automation for the HOL System".
In participants proceedings of the 1992 International Workshop on Higher Order
Logic Theorem Proving and its Applications.
IMEC, Leuven, Belgium. September 1992.


% --------------------------------------------------------------------------- %
% Compiling								      %
% --------------------------------------------------------------------------- %

1) edit the pathnames in the Makefile (if necessary)

2) type "make clean"

3) type "make all"


% --------------------------------------------------------------------------- %
% Loading								      %
% --------------------------------------------------------------------------- %

Load boyer-moore.ml


% --------------------------------------------------------------------------- %
% General Remark                                                              %
% --------------------------------------------------------------------------- %

The automatic proof procedures described below access an environment of
definitions and rewrite rules. You must add definitions and rules to this
environment if the procedures are to be effective. This can be done using the
functions supplied (see below). The most important thing is to provide the
procedures with the definitions of any functions appearing in the formula to
be proved.


% --------------------------------------------------------------------------- %
% Proof Functions							      %
% --------------------------------------------------------------------------- %

BOYER_MOORE : conv

   Boyer-Moore-style automatic theorem prover.
   Given a term "tm", attempts to prove |- tm.

BOYER_MOORE_CONV : conv

   Boyer-Moore-style automatic theorem prover.
   Given a term "tm", attempts to prove |- tm = T.

CLAUSAL_FORM_CONV : conv

   Puts into clausal form terms consisting of =,==>,COND,/\,\/,~ and atoms.


% --------------------------------------------------------------------------- %
% Tactics								      %
% --------------------------------------------------------------------------- %

HEURISTIC_TAC : ((term # bool) -> ((term # bool) list # proof)) list -> tactic

   Tactic to do automatic proof using a list of heuristics. The tactic will
   fail if it thinks the goal is not a theorem. Otherwise it will either
   prove the goal, or return as subgoals the conjectures it couldn't handle.

   If the proof printing flag is set to true, the tactic displays each new
   conjecture it generates, prints blank lines between subconjectures which
   resulted from a split, and prints a final blank line when it can do no
   more.

BOYER_MOORE_TAC : tactic

   Tactic to do automatic proof using Boyer & Moore's heuristics. The tactic
   will fail if it thinks the goal is not a theorem. Otherwise it will either
   prove the goal, or return as subgoals the conjectures it couldn't handle.

   WARNING: the subgoals returned may be invalid even when the original goal
            is valid. This is due to the procedure's generalisation heuristic.

BM_SIMPLIFY_TAC : tactic

   Tactic to do automatic simplification using Boyer & Moore's heuristics.
   The tactic will fail if it thinks the goal is not a theorem. Otherwise, it
   will either prove the goal or return the simplified conjectures as
   subgoals.

BM_INDUCT_TAC : tactic

   Tactic which attempts to do a SINGLE induction using Boyer & Moore's
   heuristics. The cases of the induction are returned as subgoals.


% --------------------------------------------------------------------------- %
% Environment Manipulation Functions					      %
% --------------------------------------------------------------------------- %

new_def : thm -> void

   Makes a definition available to the proof procedures. The theorem must be
   of the form returned by the automatic function definition facilities
   available in HOL.

defs : void -> thm list list

   Returns a list of lists of theorems currently being used as definitions.
   Each list in this list is for one operator.

new_rewrite_rule : thm -> void

   Makes a new rewrite rule available. Checks that the theorem has no
   hypotheses. A conjunction of rules may be given. The function will treat
   each conjunct in the theorem as a separate rule.

rewrite_rules : void -> thm list

   Returns the list of theorems currently being used as rewrites.

new_gen_lemma : thm -> void

   Makes a new generalisation lemma available. Checks that the theorem has no
   hypotheses.

gen_lemmas : void -> thm list

   Returns the list of theorems currently being used as generalisation lemmas.

define_shell : string -> string -> (string # string list) list -> void

   Function for defining a new HOL type together with accessor functions, and
   making a new Boyer-Moore shell from these definitions. If the type already
   exists the function attempts to load the corresponding theorems from the
   current theory hierarchy and use them to make the shell.

   The first two arguments correspond to the arguments taken by the built-in
   HOL function `define_type' and the third argument defines the accessor
   functions. This is a list of constructor names each with names of
   accessors. The function assumes that there are no accessors for a
   constructor that doesn't appear in the list, so it is not necessary to
   include an entry for a nullary constructor. For other constructors there
   must be one accessor name for each argument and they should be given in the
   correct order. The function ignores any item in the list with a constructor
   name that does not belong to the type.

   The constructor and accessor names must all be distinct and must not be
   the names of existing constants.

   Example:

      define_shell `sexp` `sexp = Nil | Atom * | Cons sexp sexp`
         [(`Atom`,[`Tok`]);(`Cons`,[`Car`;`Cdr`])];;

   This results in the following theorems being stored in the current theory
   (or these are the theorems the function would expect to find in the theory
   hierarchy if the type already exists):

      sexp               (type axiom)
      sexp_Induct        (induction theorem)
      sexp_one_one       (injectivity of constructors)
      sexp_distinct      (distinctness of constructors)
      sexp_cases         (cases theorem)

   The following definitions for the accessor functions are also stored:

      Tok                |- !x. Tok(Atom x) = x
      Car                |- !s1 s2. Car(Cons s1 s2) = s1
      Cdr                |- !s1 s2. Cdr(Cons s1 s2) = s2

   In certain cases the distinctness or injectivity theorems may not exist,
   when nothing is saved for them.

   Finally, a new Boyer-Moore shell is added to the environment, based on the
   definitions and theorems.

shells : void -> string list

   Function to compute the names of the currently defined shells.

proof_printer : bool -> bool

   Function for setting the flag that controls the printing of clauses as the
   automatic proof attempt proceeds. Set to `true' to see what the procedure
   is doing.


% --------------------------------------------------------------------------- %
% The Heuristics							      %
% --------------------------------------------------------------------------- %

clausal_form_heuristic : (term # bool) -> ((term # bool) list # proof)

   Heuristic that tests a term to see if it is in clausal form, and if not
   converts it to clausal form and returns the resulting clauses as new
   `goals'. If the term is in clausal form, but is not a single clause, it is
   split into single clauses. If the term is in clausal form but contains
   Boolean constants, the normaliser is applied to it. A single new goal will
   be produced in this case unless the result of the normalisation was true.

subst_heuristic : (term # bool) -> ((term # bool) list # proof)

   Heuristic for eliminating from a clause, a negated equality between a
   variable and another term not containing the variable. For example, given
   the clause:

      x1 \/ ~(x = t) \/ x3 \/ f x \/ x5

   the heuristic returns the clause:

      x1 \/ F \/ x3 \/ f t \/ x5

   So, all occurrences of x are replaced by t, and the equality x = t is
   `thrown away'.

simplify_heuristic : (term # bool) -> ((term # bool) list # proof)

   Heuristic for simplifying a clause by rewriting each literal in turn
   assuming the negations of the others.

use_equality_heuristic : (term # bool) -> ((term # bool) list # proof)

   Heuristic for using equalities, and in particular for cross-fertilizing.
   Given a clause, the function looks for a literal of the form ~(s' = t')
   where t' occurs in another literal and is not an explicit value template.
   If no such literal is present, the function looks for a literal of the
   form ~(t' = s') where t' occurs in another literal and is not an explicit
   value template. If a substitution literal of one of these two forms is
   found, substitution takes place.

generalize_heuristic : (term # bool) -> ((term # bool) list # proof)

   Heuristic for generalising a conjecture when this may help an induction
   to succeed. It may generalise when it shouldn't.

irrelevance_heuristic : (term # bool) -> ((term # bool) list # proof)

   Heuristic for eliminating irrelevant literals, that is ones that can no
   longer contribute to the proof and which could interfere with future
   inductions.

induction_heuristic : (term # bool) -> ((term # bool) list # proof)

   Heuristic for induction. It performs one of the possible unflawed
   inductions on a clause, or failing that, one of the flawed inductions.
   The heuristic fails if no inductions are possible.

