
======================================================================

ACL2 Library Overview

======================================================================

  An ACL2 library is a collection of books intended to enable and to
ease the reasoning process over a particular domain.  Here we describe
some idealized attributes of a good library.

Documented:
----------

  Each library should contain documentation that describes the
organization of that library.

Interface:
---------

  Each library should contain a set of interface files that a user can
include to gain access to various library features.  The standard or
primary file should be called "top"

Focused:
-------

  A library should focus on a particular domain.  In addition, the
books within that library should be organized so that they, too, focus
on particular aspects of that domain or on how that domain interacts
with other domains.

Localized: 
---------

  A library should have minimal name space and theory footprints.  This
means minimizing exposure to irrelevant details and other libraries.
Libraries should avoid non-local (in-theory) events.  Libraries should
maximize the use of (local (include-book)). It is sometimes useful to
provide different top-level books that provide varying levels of
exposure to domain details and to other libraries.

Partitioned:
-----------

  Often a library can support different styles of reasoning about a
particular domain.  Sometimes these different styles are in conflict.
A library should provide clear delineation between such styles and
allow the user to easily choices between styles.

Versioned:
---------

  It should be possible to "lock down" a particular version of a
library for a particular proof effort.  Library enhancements should
be done so as to maximize (preserve) backward compatibility.

Packaged:
--------

  Each library should be developed in its own package to minimize
name space pollution.  Even within the library, developers should
strive to use names that are unlikely to cause future conflicts.

Robust:
------

  Libraries should be designed to withstand change.  Proofs should be
automated to the greatest extent possible.  Hints and in-theory events
should avoid using theorem names outside of the current library and
even outside of the current book.

Efficient:
---------

  The functions exported from the library should lend themselves to
efficient execution.  Tail recursion should be used for executable
counterparts when feasible.  Guards for exported functions should be
specified and verified. Non-trivial macros should be defined in terms
of functions, ideally functions whose guards have been verified.

======================================================================

Library Organizational Tools

======================================================================

  Here we describe certain tools that can be used to enhance the
library development process.

Rule Sets
---------

  Rule sets allow rules to be grouped together and enabled/disabled
en-mass.  Rule sets differ from theories primarily in that they can be
updated incrementally.

World Query (future)
--------------------

  Tools for harvesting (characterizing?) theorems and definitions from
a given ACL2 state.

defthm Wrapper (future)
-----------------------

  Helps classify rules on the spot.

defun wrapper (future)
----------------------

  Automatically generates the various theorems one typically needs for
reasoning about functions.  

Import Command (future)
-----------------------

  Automated support for localizing functions and theorems from other
library and another package.  I imagine this as a make-event that
would actually replicate the original function/theorem in the current
context.  My reasons for considering this are:

  - The variables on the theorems would be imported into the new
    package.  This is nice for instantiations.

  - One cannot otherwise import new symbols into an existing package
    which sucks when trying to work with new package names in the 
    "ACL2" package.

  - This functionality may be useful in generating encapsulated
    events "automatically" from existing functions and properties.
    In the distant future this might be one way to combat
    library incompatibility.

Create Encapsulate (future)
---------------------------

  Takes a list of functions and a set of theorems and produces
an encapsulation of those events.

======================================================================

File Organization

======================================================================

  Each file should be characterized under the following broad
classes of files:

packages:

  The package definition files for the library.  Such libraries
should import (include) only other packages.

definitions:

  The definition files contains definitions for all of the functions
to be exported by the library.  The definition file should import only
packages and other definition files.

development:

  The set of files containing theorems essential for developing and
extending theorems within the domain.  These often include hack lemmas
and more expensive, more general rules.  Development libraries should
only ever be included locally.

congruences:

  The equivalences (defequiv), refinements (defrefinement), and
congruences (defcong) for the functions in the domain.  Presumably
this would locally include some development libraries, but it should
export only these relations plus the definitions.  nary congruences
may be included as well.

properties:

  These files build upon the definitions and congruences as well as upon
the definitions, congruences, properties of the libraries upon which it
is constructed.

extensions:

  Interactions between the domain of this library and other domains.

styles:

  Variations in induction schemes, pick-a-point and normalization.

interfaces:

  This should include one file called "top.lisp" which provides a
typical interface to the library.  Perhaps an "all.lisp" as well, to
ensure that all of the books in the library play well with each other.

======================================================================

Packages

======================================================================

  Packages should be used to avoid name space pollution.

  Package-qualified rules are easy to observe in theorem prover
output.

======================================================================

Rule observations

======================================================================

- Rules with fewer hyps are better than those with hyps (although, 
  rules with zero hyps become abbreviation rules .. which may change
  the order in which they are applied)

- Rules that cause case splits may be expensive (especially early in
  the proof)

- Which is better, types or congruences?

  o congruences often have fewer hyps
  o equality rules with type predicates may apply in more
    cases

======================================================================

Rule sets

======================================================================

Some possible generic (universal) rule classifications:
-------------------------------------------------------

case-split      : likely to cause a case split (either theorems or non-recursive
                  function definitions.

equiv           : rules hung on an equivalence relation

type-forward    : forward-chaining rule for type inference
type-rewrite    : backchaining rule for type inference (more expensive?)

expensive       : rules that are likely to be expensive
                  It might be nice if there were cheap versions
                  of expensive rules, as appropriate

devel           : rules only useful in library development

Libraries
---------

:library name
:version tag
:rule-sets (a b c)

All library files should begin with an event of the form

  (library name)

  o This will set the "default library" value in the rule set
    table to the current library.  Can this event be local?

All classified rules should then be (automagically) associated w/ a library

o Rule sets include a library and version by default.

- Libraries

  o A library is a tag associated with all (classified) rules.  Every
    book in a library should begin by setting the current library.

  o The current (default) library (the one into which new rules will
    be added) can be set via:

  (default-library library)

Versioning
----------

The version of a library is determined simply by which rules are
enabled.  It may also be possible (desirable) to provide different
interfaces to a library.

A versioning process that might possibly work:

- Each consumer of a library should have to explicitly call out a
  version of that library.

  o Alternately, a user may wish to use the "newest" version of the
    library as long as they can, possibly until something breaks in 
    a way that they are unwilling to try to fix.  Then they might
    "lock down" the version.

- All changes to a released library should be done under a new
  version.

- Library consumers may upgrade to new versions as they wish

- All versions of a library should be namespace compatible

o (only?) Libraries are versioned.

  o At any point, a specific version of a library may be active.
    By default, the version is 0.

  o Individual rules may be added to a specific version of a
    library.

    (version 1 (rule-set name :version version))

  o During development, the version can be set via:

    (current-library library :version xxx)

  o Entering a version entails:
    - disable all versions greater than the current version
    - enable the current version

    (set-version library version)

======================================================================

ACL2 Enhancements

======================================================================

Tools for profiling libraries.  It would be nice to get empirical data
on the cost of various rules and a sense for how "valuable" certain
rules are.

The ability to add guarded executable bodies to function symbols post
facto, including encapsulated functions.
