Imports one interface into another. It may refer to any previously-defined
interface. Contracts following the include may refer to signatures from the
included interface.

Include specifications also entail an obligation; if interface C
includes B and B includes A, then C must
include A as well. This obligation may be relaxed in the future,
so that including B will automatically include A.

For example, the interface IAssociative contains a signature describing
a binary function and a contract constraining it to be associative. The
contract mulop-associative refers to the signature mulop as
well as the built-in ACL2 function equal:

The interface IDistributive includes ICommutative,
introduces a new function addop, and states a contract that
mulop distributes over addop. Note that
IDistributive must also include IAssociative to satisfy the
obligation from ICommutative:

The interface IDistributeLists extends IDistributive with
functions that perform addop and mulop on lists. Its contract
addall/mulall-distributive refers to its own signatures, the imported
signatures mulop and addop, and the built-in functions
equal, implies, and proper-consp.

Makes the bindings of any previously defined interface available inside a
module. The module may use signatures as function names and rely on contracts
as axioms. If an imported interface includes any other interfaces, the module
must import them as well.

An import declaration may optionally bind some or all of the interface’s
external names to different internal names inside the module. For instance, the
following import declaration binds mulop from IAssociative to
times:

Makes the implementation of a previously defined interface available to clients
of a module. The module must provide a definition (internal, imported, or ACL2
built-in) for each signature in the interface; these definitions must satisfy
the interface’s contracts. If the interface includes other interfaces, the
module must either import or export them as well.

The export declaration may supply definitions whose internal names differ from
their external signaturse. For instance, the following export declaration
provides the builtin ACL2 function * as mulop to implement
IAssociative.

Creates a composable program fragment by joining together multiple modules.
External names are resolved to link one module’s imports to another’s exports;
the export must come before the import to prevent cyclic dependencies. Internal
names are kept separate; lexical scope is not violated.

The compound module MDist links together MDistributive with
MDistributeLists. The result is a module that exports both
IDistributive and IDistributeLists. It has no imports; the
import of MDistributeLists is resolved to the export of
MDistributive. Despite the duplicate definitions of add and
mul in the component modules, there are no name clashes in
MDist; addop and mulop are based on the functions
from MDistributive, while addall and mulall are based
on the functions from MDistributeLists.

3.3Programs

A complete Modular ACL2 program is a sequence of interfaces,
modules (including compound modules), module invocations,
and expressions.