summaryrefslogtreecommitdiffstats
path: root/slib_6.html
diff options
context:
space:
mode:
authorSteve Langasek <vorlon@debian.org>2005-01-10 08:53:33 +0000
committerBryan Newbold <bnewbold@robocracy.org>2017-02-20 00:05:30 -0800
commite33f9eb9cf5cc29c36ce2aa7e10cd0f37ae0cc8e (patch)
treeabbf06041619e445f9d0b772b0d58132009d8234 /slib_6.html
parentf559c149c83da84d0b1c285f0298c84aec564af9 (diff)
parent8466d8cfa486fb30d1755c4261b781135083787b (diff)
downloadslib-e33f9eb9cf5cc29c36ce2aa7e10cd0f37ae0cc8e.tar.gz
slib-e33f9eb9cf5cc29c36ce2aa7e10cd0f37ae0cc8e.zip
Import Debian changes 3a1-4.2debian/3a1-4.2
slib (3a1-4.2) unstable; urgency=low * Non-maintainer upload. * Add guile.init.local for use within the build dir, since otherwise we have an (earlier unnoticed) circular build-dep due to a difference between scm and guile. slib (3a1-4.1) unstable; urgency=low * Non-maintainer upload. * Build-depend on guile-1.6 instead of scm, since the new version of scm is wedged in unstable (closes: #281809). slib (3a1-4) unstable; urgency=low * Also check for expected creation on slibcat. (Closes: #240096) slib (3a1-3) unstable; urgency=low * Also check for /usr/share/guile/1.6/slib before installing for guile 1.6. (Closes: #239267) slib (3a1-2) unstable; urgency=low * Add format.scm back into slib until gnucash stops using it. * Call guile-1.6 new-catalog (Closes: #238231) slib (3a1-1) unstable; urgency=low * New upstream release * Remove Info section from doc-base file (Closes: #186950) * Remove period from end of description (linda, lintian) * html gen fixed upstream (Closes: #111778) slib (2d4-2) unstable; urgency=low * Fix url for upstream source (Closes: #144981) * Fix typo in slib.texi (enquque->enqueue) (Closes: #147475) * Add build depends. slib (2d4-1) unstable; urgency=low * New upstream. slib (2d3-1) unstable; urgency=low * New upstream. * Remove texi2html call in debian/rules. Now done upstream. Add make html instead. * Changes to rules and doc-base to conform to upstream html gen * Clean up upstream makefile to make sure it cleans up after itself.
Diffstat (limited to 'slib_6.html')
-rw-r--r--slib_6.html3658
1 files changed, 3658 insertions, 0 deletions
diff --git a/slib_6.html b/slib_6.html
new file mode 100644
index 0000000..804d4e9
--- /dev/null
+++ b/slib_6.html
@@ -0,0 +1,3658 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html40/loose.dtd">
+<HTML>
+<!-- Created on January, 10 2005 by texi2html 1.66 -->
+<!--
+Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
+ Karl Berry <karl@freefriends.org>
+ Olaf Bachmann <obachman@mathematik.uni-kl.de>
+ and many others.
+Maintained by: Many creative people <dev@texi2html.cvshome.org>
+Send bugs and suggestions to <users@texi2html.cvshome.org>
+
+-->
+<HEAD>
+<TITLE>SLIB: Database Packages</TITLE>
+
+<META NAME="description" CONTENT="SLIB: Database Packages">
+<META NAME="keywords" CONTENT="SLIB: Database Packages">
+<META NAME="resource-type" CONTENT="document">
+<META NAME="distribution" CONTENT="global">
+<META NAME="Generator" CONTENT="texi2html 1.66">
+
+</HEAD>
+
+<BODY LANG="en" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
+
+<A NAME="SEC140"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC139"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC141"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 6. Database Packages </H1>
+<!--docid::SEC140::-->
+<P>
+
+<TABLE BORDER="0" CELLSPACING="0">
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC141">6.1 Relational Database</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">'relational-database</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC165">6.2 Relational Infrastructure</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC178">6.3 Weight-Balanced Trees</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">'wt-tree</TD></TR>
+</TABLE>
+<P>
+
+<A NAME="Relational Database"></A>
+<HR SIZE="6">
+<A NAME="SEC141"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC142"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 6.1 Relational Database </H2>
+<!--docid::SEC141::-->
+<P>
+
+<CODE>(require 'relational-database)</CODE>
+<A NAME="IDX917"></A>
+</P>
+<P>
+
+This package implements a database system inspired by the Relational
+Model (<CITE>E. F. Codd, A Relational Model of Data for Large Shared
+Data Banks</CITE>). An SLIB relational database implementation can be created
+from any <A HREF="slib_6.html#SEC166">6.2.1 Base Table</A> implementation.
+</P>
+<P>
+
+Why relational database? For motivations and design issues see<BR>
+<A HREF="http://swissnet.ai.mit.edu/~jaffer/DBManifesto.html">http://swissnet.ai.mit.edu/~jaffer/DBManifesto.html</A>.
+</P>
+<P>
+
+<TABLE BORDER="0" CELLSPACING="0">
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC142">6.1.1 Using Databases</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">'databases</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC147">6.1.2 Table Operations</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC154">6.1.3 Database Interpolation</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">'database-interpolate</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC155">6.1.4 Embedded Commands</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">'database-commands</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC162">6.1.5 Database Macros</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">'within-database</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC164">6.1.6 Database Browser</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">'database-browse</TD></TR>
+</TABLE>
+<P>
+
+<A NAME="Using Databases"></A>
+<HR SIZE="6">
+<A NAME="SEC142"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC141"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC147"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC141"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 6.1.1 Using Databases </H3>
+<!--docid::SEC142::-->
+<P>
+
+<CODE>(require 'databases)</CODE>
+<A NAME="IDX918"></A>
+</P>
+<P>
+
+This enhancement wraps a utility layer on <CODE>relational-database</CODE>
+which provides:
+</P>
+<P>
+
+<UL>
+<LI>
+Identification of open databases by filename.
+<LI>
+Automatic sharing of open (immutable) databases.
+<LI>
+Automatic loading of base-table package when creating a database.
+<LI>
+Detection and automatic loading of the appropriate base-table package
+when opening a database.
+<LI>
+Table and data definition from Scheme lists.
+</UL>
+<P>
+
+<A NAME="SEC143"></A>
+<H4> Database Sharing </H4>
+<!--docid::SEC143::-->
+<P>
+
+<EM>Auto-sharing</EM> refers to a call to the procedure
+<A NAME="IDX919"></A>
+<CODE>open-database</CODE> returning an already open database (procedure),
+rather than opening the database file a second time.
+</P>
+<P>
+
+<BLOCKQUOTE>
+<EM>Note:</EM> Databases returned by <CODE>open-database</CODE> do not include
+wrappers applied by packages like <A HREF="slib_6.html#SEC155">6.1.4 Embedded Commands</A>. But
+wrapped databases do work as arguments to these functions.
+</BLOCKQUOTE>
+<P>
+
+When a database is created, it is mutable by the creator and not
+auto-sharable. A database opened mutably is also not auto-sharable.
+But any number of readers can (open) share a non-mutable database file.
+</P>
+<P>
+
+This next set of procedures mirror the whole-database methods in
+<A HREF="slib_6.html#SEC177">6.2.4 Database Operations</A>. Except for <CODE>create-database</CODE>, each
+procedure will accept either a filename or database procedure for its
+first argument.
+</P>
+<P>
+
+<A NAME="IDX920"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>create-database</B> <I>filename base-table-type</I>
+<DD><P>
+
+<VAR>filename</VAR> should be a string naming a file; or <CODE>#f</CODE>. <VAR>base-table-type</VAR> must be a
+symbol naming a feature which can be passed to <CODE>require</CODE>. <CODE>create-database</CODE>
+returns a new, open relational database (with base-table type <VAR>base-table-type</VAR>)
+associated with <VAR>filename</VAR>, or a new ephemeral database if <VAR>filename</VAR> is <CODE>#f</CODE>.
+</P>
+<P>
+
+<CODE>create-database</CODE> is the only run-time use of require in SLIB
+which crosses module boundaries. When <VAR>base-table-type</VAR> is <CODE>require</CODE>d by <CODE>create-database</CODE>; it
+adds an association of <VAR>base-table-type</VAR> with its <EM>relational-system</EM> procedure
+<A NAME="IDX921"></A>
+to <VAR>mdbm:*databases*</VAR>.
+</P>
+<P>
+
+alist-table is the default base-table type:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(require 'databases)
+(define my-rdb (create-database &quot;my.db&quot; 'alist-table))
+</pre></td></tr></table></DL>
+Only <CODE>alist-table</CODE> and base-table modules which have been
+<CODE>require</CODE>d will dispatch correctly from the
+<CODE>open-database</CODE> procedures. Therefore, either pass two
+arguments to <CODE>open-database</CODE>, or require the base-table of your
+database file uses before calling <CODE>open-database</CODE> with one
+argument.
+<P>
+
+<A NAME="IDX922"></A>
+</P>
+<DL>
+<DT><U>Procedure:</U> <B>open-database!</B> <I>rdb base-table-type</I>
+<DD><P>
+
+Returns <EM>mutable</EM> open relational database or #f.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX923"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>open-database</B> <I>rdb base-table-type</I>
+<DD><P>
+
+Returns an open relational database associated with <VAR>rdb</VAR>. The
+database will be opened with base-table type <VAR>base-table-type</VAR>).
+</P>
+<P>
+
+<A NAME="IDX924"></A>
+<DT><U>Function:</U> <B>open-database</B> <I>rdb</I>
+<DD>Returns an open relational database associated with <VAR>rdb</VAR>.
+<CODE>open-database</CODE> will attempt to deduce the correct base-table-type.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX925"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>write-database</B> <I>rdb filename</I>
+<DD><P>
+
+Writes the mutable relational-database <VAR>rdb</VAR> to <VAR>filename</VAR>.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX926"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>sync-database</B> <I>rdb</I>
+<DD><P>
+
+Writes the mutable relational-database <VAR>rdb</VAR> to the filename it was
+opened with.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX927"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>solidify-database</B> <I>rdb</I>
+<DD><P>
+
+Syncs <VAR>rdb</VAR> and makes it immutable.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX928"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>close-database</B> <I>rdb</I>
+<DD><P>
+
+<VAR>rdb</VAR> will only be closed when the count of <CODE>open-database</CODE> - <CODE>close-database</CODE>
+calls for <VAR>rdb</VAR> (and its filename) is 0. <CODE>close-database</CODE> returns #t if successful;
+and #f otherwise.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX929"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>mdbm:report</B>
+<DD><P>
+
+Prints a table of open database files. The columns are the
+base-table type, number of opens, `<SAMP>!</SAMP>' for mutable, the
+filename, and the lock certificate (if locked).
+</P>
+</DL>
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(mdbm:report)
+-|
+ alist-table 003 /usr/local/lib/slib/clrnamdb.scm
+ alist-table 001 ! sdram.db jaffer@aubrey.jaffer.3166:1038628199
+</pre></td></tr></table><P>
+
+<A NAME="SEC144"></A>
+<H4> Opening Tables </H4>
+<!--docid::SEC144::-->
+<P>
+
+<A NAME="IDX930"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>open-table</B> <I>rdb table-name</I>
+<DD><P>
+
+<VAR>rdb</VAR> must be a relational database and <VAR>table-name</VAR> a symbol.
+</P>
+<P>
+
+<CODE>open-table</CODE> returns a &quot;methods&quot; procedure for an existing relational table in
+<VAR>rdb</VAR> if it exists and can be opened for reading, otherwise returns
+<CODE>#f</CODE>.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX931"></A>
+</P>
+<DL>
+<DT><U>Procedure:</U> <B>open-table!</B> <I>rdb table-name</I>
+<DD><P>
+
+<VAR>rdb</VAR> must be a relational database and <VAR>table-name</VAR> a symbol.
+</P>
+<P>
+
+<CODE>open-table!</CODE> returns a &quot;methods&quot; procedure for an existing relational table in
+<VAR>rdb</VAR> if it exists and can be opened in mutable mode, otherwise returns
+<CODE>#f</CODE>.
+</P>
+</DL>
+<A NAME="SEC145"></A>
+<H4> Defining Tables </H4>
+<!--docid::SEC145::-->
+<P>
+
+<A NAME="IDX932"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>define-domains</B> <I>rdb row5 <small>...</small></I>
+<DD><P>
+
+Adds the domain rows <VAR>row5</VAR> <small>...</small> to the `<SAMP>*domains-data*</SAMP>' table
+in <VAR>rdb</VAR>. The format of the row is given in <A HREF="slib_6.html#SEC175">6.2.2 Catalog Representation</A>.
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(define-domains rdb '(permittivity #f complex? c64 #f))
+</pre></td></tr></table></DL>
+<P>
+
+<A NAME="IDX933"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>add-domain</B> <I>rdb row5</I>
+<DD><P>
+
+Use <CODE>define-domains</CODE> instead.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX934"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>define-tables</B> <I>rdb spec-0 <small>...</small></I>
+<DD><P>
+
+Adds tables as specified in <VAR>spec-0</VAR> <small>...</small> to the open
+relational-database <VAR>rdb</VAR>. Each <VAR>spec</VAR> has the form:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(&lt;name&gt; &lt;descriptor-name&gt; &lt;descriptor-name&gt; &lt;rows&gt;)
+</pre></td></tr></table>or
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(&lt;name&gt; &lt;primary-key-fields&gt; &lt;other-fields&gt; &lt;rows&gt;)
+</pre></td></tr></table><P>
+
+where &lt;name&gt; is the table name, &lt;descriptor-name&gt; is the symbol
+name of a descriptor table, &lt;primary-key-fields&gt; and
+&lt;other-fields&gt; describe the primary keys and other fields
+respectively, and &lt;rows&gt; is a list of data rows to be added to the
+table.
+</P>
+<P>
+
+&lt;primary-key-fields&gt; and &lt;other-fields&gt; are lists of field
+descriptors of the form:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(&lt;column-name&gt; &lt;domain&gt;)
+</pre></td></tr></table>or
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(&lt;column-name&gt; &lt;domain&gt; &lt;column-integrity-rule&gt;)
+</pre></td></tr></table><P>
+
+where &lt;column-name&gt; is the column name, &lt;domain&gt; is the domain
+of the column, and &lt;column-integrity-rule&gt; is an expression whose
+value is a procedure of one argument (which returns <CODE>#f</CODE> to signal
+an error).
+</P>
+<P>
+
+If &lt;domain&gt; is not a defined domain name and it matches the name of
+this table or an already defined (in one of <VAR>spec-0</VAR> <small>...</small>) single
+key field table, a foreign-key domain will be created for it.
+</P>
+</DL>
+<A NAME="SEC146"></A>
+<H4> Listing Tables </H4>
+<!--docid::SEC146::-->
+<P>
+
+<A NAME="IDX935"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>list-table-definition</B> <I>rdb table-name</I>
+<DD><P>
+
+If symbol <VAR>table-name</VAR> exists in the open relational-database
+<VAR>rdb</VAR>, then returns a list of the table-name, its primary key names
+and domains, its other key names and domains, and the table's records
+(as lists). Otherwise, returns #f.
+</P>
+<P>
+
+The list returned by <CODE>list-table-definition</CODE>, when passed as an
+argument to <CODE>define-tables</CODE>, will recreate the table.
+</P>
+</DL>
+<P>
+
+<A NAME="Table Operations"></A>
+<HR SIZE="6">
+<A NAME="SEC147"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC142"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC148"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC141"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 6.1.2 Table Operations </H3>
+<!--docid::SEC147::-->
+<P>
+
+These are the descriptions of the methods available from an open
+relational table. A method is retrieved from a table by calling
+the table with the symbol name of the operation. For example:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>((plat 'get 'processor) 'djgpp) => i386
+</pre></td></tr></table><P>
+
+Some operations described below require primary key arguments. Primary
+keys arguments are denoted <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small>. It is an
+error to call an operation for a table which takes primary key arguments
+with the wrong number of primary keys for that table.
+</P>
+<P>
+
+<A NAME="IDX936"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>get</B> <I>column-name</I>
+<DD>Returns a procedure of arguments <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which
+returns the value for the <VAR>column-name</VAR> column of the row associated
+with primary keys <VAR>key1</VAR>, <VAR>key2</VAR> <small>...</small> if that row exists in
+the table, or <CODE>#f</CODE> otherwise.
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>((plat 'get 'processor) 'djgpp) => i386
+((plat 'get 'processor) 'be-os) => #f
+</pre></td></tr></table></DL>
+<P>
+
+<TABLE BORDER="0" CELLSPACING="0">
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC148">6.1.2.1 Single Row Operations</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC149">6.1.2.2 Match-Keys</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC150">6.1.2.3 Multi-Row Operations</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC151">6.1.2.4 Indexed Sequential Access Methods</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC152">6.1.2.5 Sequential Index Operations</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC153">6.1.2.6 Table Administration</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+</TABLE>
+<P>
+
+<A NAME="Single Row Operations"></A>
+<HR SIZE="6">
+<A NAME="SEC148"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC147"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC149"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC147"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.1.2.1 Single Row Operations </H4>
+<!--docid::SEC148::-->
+<P>
+
+The term <EM>row</EM> used below refers to a Scheme list of values (one for
+each column) in the order specified in the descriptor (table) for this
+table. Missing values appear as <CODE>#f</CODE>. Primary keys must not
+be missing.
+</P>
+<P>
+
+<A NAME="IDX937"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>row:insert</B>
+<DD>Adds the row <VAR>row</VAR> to this table. If a row for the primary key(s)
+specified by <VAR>row</VAR> already exists in this table an error is
+signaled. The value returned is unspecified.
+</DL>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(define telephone-table-desc
+ ((my-database 'create-table) 'telephone-table-desc))
+(define ndrp (telephone-table-desc 'row:insert))
+(ndrp '(1 #t name #f string))
+(ndrp '(2 #f telephone
+ (lambda (d)
+ (and (string? d) (&gt; (string-length d) 2)
+ (every
+ (lambda (c)
+ (memv c '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9
+ #\+ #\( #\ #\) #\-)))
+ (string-&gt;list d))))
+ string))
+</pre></td></tr></table><P>
+
+<A NAME="IDX938"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>row:update</B>
+<DD>Returns a procedure of one argument, <VAR>row</VAR>, which adds the row,
+<VAR>row</VAR>, to this table. If a row for the primary key(s) specified by
+<VAR>row</VAR> already exists in this table, it will be overwritten. The
+value returned is unspecified.
+</DL>
+<P>
+
+<A NAME="IDX939"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>row:retrieve</B>
+<DD>Returns a procedure of arguments <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which
+returns the row associated with primary keys <VAR>key1</VAR>, <VAR>key2</VAR>
+<small>...</small> if it exists, or <CODE>#f</CODE> otherwise.
+</DL>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>((plat 'row:retrieve) 'linux) => (linux i386 linux gcc)
+((plat 'row:retrieve) 'multics) => #f
+</pre></td></tr></table><P>
+
+<A NAME="IDX940"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>row:remove</B>
+<DD>Returns a procedure of arguments <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which
+removes and returns the row associated with primary keys <VAR>key1</VAR>,
+<VAR>key2</VAR> <small>...</small> if it exists, or <CODE>#f</CODE> otherwise.
+</DL>
+<P>
+
+<A NAME="IDX941"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>row:delete</B>
+<DD>Returns a procedure of arguments <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which
+deletes the row associated with primary keys <VAR>key1</VAR>, <VAR>key2</VAR>
+<small>...</small> if it exists. The value returned is unspecified.
+</DL>
+<P>
+
+<A NAME="Match-Keys"></A>
+<HR SIZE="6">
+<A NAME="SEC149"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC148"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC150"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC147"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.1.2.2 Match-Keys </H4>
+<!--docid::SEC149::-->
+<P>
+
+<A NAME="IDX942"></A>
+The (optional) <VAR>match-key1</VAR> <small>...</small> arguments are used to restrict
+actions of a whole-table operation to a subset of that table. Those
+procedures (returned by methods) which accept match-key arguments will
+accept any number of match-key arguments between zero and the number of
+primary keys in the table. Any unspecified <VAR>match-key</VAR> arguments
+default to <CODE>#f</CODE>.
+</P>
+<P>
+
+The <VAR>match-key1</VAR> <small>...</small> restrict the actions of the table command
+to those records whose primary keys each satisfy the corresponding
+<VAR>match-key</VAR> argument. The arguments and their actions are:
+</P>
+<P>
+
+<BLOCKQUOTE>
+<DL COMPACT>
+<DT><CODE>#f</CODE>
+<DD>The false value matches any key in the corresponding position.
+<DT>an object of type procedure
+<DD>This procedure must take a single argument, the key in the corresponding
+position. Any key for which the procedure returns a non-false value is
+a match; Any key for which the procedure returns a <CODE>#f</CODE> is not.
+<DT>other values
+<DD>Any other value matches only those keys <CODE>equal?</CODE> to it.
+</DL>
+</BLOCKQUOTE>
+<P>
+
+<A NAME="IDX943"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>get*</B> <I>column-name</I>
+<DD>Returns a procedure of optional arguments <VAR>match-key1</VAR> <small>...</small> which
+returns a list of the values for the specified column for all rows in
+this table. The optional <VAR>match-key1</VAR> <small>...</small> arguments restrict
+actions to a subset of the table.
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>((plat 'get* 'processor)) =>
+(i386 i8086 i386 i8086 i386 i386 i8086 m68000
+ m68000 m68000 m68000 m68000 powerpc)
+
+((plat 'get* 'processor) #f) =>
+(i386 i8086 i386 i8086 i386 i386 i8086 m68000
+ m68000 m68000 m68000 m68000 powerpc)
+
+(define (a-key? key)
+ (char=? #\a (string-ref (symbol-&gt;string key) 0)))
+
+((plat 'get* 'processor) a-key?) =>
+(m68000 m68000 m68000 m68000 m68000 powerpc)
+
+((plat 'get* 'name) a-key?) =>
+(atari-st-turbo-c atari-st-gcc amiga-sas/c-5.10
+ amiga-aztec amiga-dice-c aix)
+</pre></td></tr></table></DL>
+<P>
+
+<A NAME="Multi-Row Operations"></A>
+<HR SIZE="6">
+<A NAME="SEC150"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC149"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC151"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC147"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.1.2.3 Multi-Row Operations </H4>
+<!--docid::SEC150::-->
+<P>
+
+<A NAME="IDX944"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>row:retrieve*</B>
+<DD>Returns a procedure of optional arguments <VAR>match-key1</VAR> <small>...</small>
+which returns a list of all rows in this table. The optional
+<VAR>match-key1</VAR> <small>...</small> arguments restrict actions to a subset of the
+table. For details see See section <A HREF="slib_6.html#SEC149">6.1.2.2 Match-Keys</A>.
+</DL>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>((plat 'row:retrieve*) a-key?) =>
+((atari-st-turbo-c m68000 atari turbo-c)
+ (atari-st-gcc m68000 atari gcc)
+ (amiga-sas/c-5.10 m68000 amiga sas/c)
+ (amiga-aztec m68000 amiga aztec)
+ (amiga-dice-c m68000 amiga dice-c)
+ (aix powerpc aix -))
+</pre></td></tr></table><P>
+
+<A NAME="IDX945"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>row:remove*</B>
+<DD>Returns a procedure of optional arguments <VAR>match-key1</VAR> <small>...</small> which
+removes and returns a list of all rows in this table. The optional
+<VAR>match-key1</VAR> <small>...</small> arguments restrict actions to a subset of the
+table.
+</DL>
+<P>
+
+<A NAME="IDX946"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>row:delete*</B>
+<DD>Returns a procedure of optional arguments <VAR>match-key1</VAR> <small>...</small>
+which Deletes all rows from this table. The optional <VAR>match-key1</VAR>
+<small>...</small> arguments restrict deletions to a subset of the table. The
+value returned is unspecified. The descriptor table and catalog entry
+for this table are not affected.
+</DL>
+<P>
+
+<A NAME="IDX947"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>for-each-row</B>
+<DD>Returns a procedure of arguments <VAR>proc</VAR> <VAR>match-key1</VAR> <small>...</small>
+which calls <VAR>proc</VAR> with each <VAR>row</VAR> in this table. The
+optional <VAR>match-key1</VAR> <small>...</small> arguments restrict actions to a
+subset of the table. For details see See section <A HREF="slib_6.html#SEC149">6.1.2.2 Match-Keys</A>.
+</DL>
+<P>
+
+Note that <CODE>row:insert*</CODE> and <CODE>row:update*</CODE> do <EM>not</EM> use
+match-keys.
+</P>
+<P>
+
+<A NAME="IDX948"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>row:insert*</B>
+<DD>Returns a procedure of one argument, <VAR>rows</VAR>, which adds each row in
+the list of rows, <VAR>rows</VAR>, to this table. If a row for the primary
+key specified by an element of <VAR>rows</VAR> already exists in this table,
+an error is signaled. The value returned is unspecified.
+</DL>
+<P>
+
+<A NAME="IDX949"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>row:update*</B>
+<DD>Returns a procedure of one argument, <VAR>rows</VAR>, which adds each row in
+the list of rows, <VAR>rows</VAR>, to this table. If a row for the primary
+key specified by an element of <VAR>rows</VAR> already exists in this table,
+it will be overwritten. The value returned is unspecified.
+</DL>
+<P>
+
+<A NAME="Indexed Sequential Access Methods"></A>
+<HR SIZE="6">
+<A NAME="SEC151"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC150"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC152"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC147"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.1.2.4 Indexed Sequential Access Methods </H4>
+<!--docid::SEC151::-->
+<P>
+
+<A NAME="IDX950"></A>
+<EM>Indexed Sequential Access Methods</EM> are a way of arranging
+database information so that records can be accessed both by key and
+by key sequence (ordering). <EM>ISAM</EM> is not part of Codd's
+relational model. Hardcore relational programmers might use some
+least-upper-bound join for every row to get them into an order.
+</P>
+<P>
+
+Associative memory in B-Trees is an example of a database
+implementation which can support a native key ordering. SLIB's
+<CODE>alist-table</CODE> implementation uses <CODE>sort</CODE> to implement
+<CODE>for-each-row-in-order</CODE>, but does not support <CODE>isam-next</CODE>
+and <CODE>isam-prev</CODE>.
+</P>
+<P>
+
+The multi-primary-key ordering employed by these operations is the
+lexicographic collation of those primary-key fields in their given
+order. For example:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(12 a 34) &lt; (12 a 36) &lt; (12 b 1) &lt; (13 a 0)
+</pre></td></tr></table><P>
+
+<A NAME="Sequential Index Operations"></A>
+<HR SIZE="6">
+<A NAME="SEC152"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC151"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC153"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC147"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.1.2.5 Sequential Index Operations </H4>
+<!--docid::SEC152::-->
+<P>
+
+The following procedures are individually optional depending on the
+base-table implememtation. If an operation is <EM>not</EM> supported,
+then calling the table with that operation symbol will return false.
+</P>
+<P>
+
+<A NAME="IDX951"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>for-each-row-in-order</B>
+<DD>Returns a procedure of arguments <VAR>proc</VAR> <VAR>match-key1</VAR> <small>...</small>
+which calls <VAR>proc</VAR> with each <VAR>row</VAR> in this table in the
+(implementation-dependent) natural, repeatable ordering for rows. The
+optional <VAR>match-key1</VAR> <small>...</small> arguments restrict actions to a
+subset of the table. For details see See section <A HREF="slib_6.html#SEC149">6.1.2.2 Match-Keys</A>.
+</DL>
+<P>
+
+<A NAME="IDX952"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>isam-next</B>
+<DD>Returns a procedure of arguments <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which
+returns the key-list identifying the lowest record higher than
+<VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which is stored in the relational-table;
+or false if no higher record is present.
+<P>
+
+<A NAME="IDX953"></A>
+<DT><U>Operation:</U> relational-table <B>isam-next</B> <I>column-name</I>
+<DD>The symbol <VAR>column-name</VAR> names a key field. In the list returned
+by <CODE>isam-next</CODE>, that field, or a field to its left, will be
+changed. This allows one to skip over less significant key fields.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX954"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>isam-prev</B>
+<DD>Returns a procedure of arguments <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which
+returns the key-list identifying the highest record less than
+<VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which is stored in the relational-table;
+or false if no lower record is present.
+<P>
+
+<A NAME="IDX955"></A>
+<DT><U>Operation:</U> relational-table <B>isam-prev</B> <I>index</I>
+<DD>The symbol <VAR>column-name</VAR> names a key field. In the list returned
+by <CODE>isam-next</CODE>, that field, or a field to its left, will be
+changed. This allows one to skip over less significant key fields.
+</P>
+</DL>
+<P>
+
+For example, if a table has key fields:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(col1 col2)
+(9 5)
+(9 6)
+(9 7)
+(9 8)
+(12 5)
+(12 6)
+(12 7)
+</pre></td></tr></table><P>
+
+Then:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>((table 'isam-next) '(9 5)) => (9 6)
+((table 'isam-next 'col2) '(9 5)) => (9 6)
+((table 'isam-next 'col1) '(9 5)) => (12 5)
+((table 'isam-prev) '(12 7)) => (12 6)
+((table 'isam-prev 'col2) '(12 7)) => (12 6)
+((table 'isam-prev 'col1) '(12 7)) => (9 8)
+</pre></td></tr></table><P>
+
+<A NAME="Table Administration"></A>
+<HR SIZE="6">
+<A NAME="SEC153"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC152"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC154"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC147"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.1.2.6 Table Administration </H4>
+<!--docid::SEC153::-->
+<P>
+
+<A NAME="IDX956"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>column-names</B>
+<DD><A NAME="IDX957"></A>
+<DT><U>Operation:</U> relational-table <B>column-foreigns</B>
+<DD><A NAME="IDX958"></A>
+<DT><U>Operation:</U> relational-table <B>column-domains</B>
+<DD><A NAME="IDX959"></A>
+<DT><U>Operation:</U> relational-table <B>column-types</B>
+<DD>Return a list of the column names, foreign-key table names, domain
+names, or type names respectively for this table. These 4 methods are
+different from the others in that the list is returned, rather than a
+procedure to obtain the list.
+<P>
+
+<A NAME="IDX960"></A>
+<DT><U>Operation:</U> relational-table <B>primary-limit</B>
+<DD>Returns the number of primary keys fields in the relations in this
+table.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX961"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-table <B>close-table</B>
+<DD>Subsequent operations to this table will signal an error.
+</DL>
+<P>
+
+<A NAME="Database Interpolation"></A>
+<HR SIZE="6">
+<A NAME="SEC154"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC153"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC155"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC141"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 6.1.3 Database Interpolation </H3>
+<!--docid::SEC154::-->
+<P>
+
+<CODE>(require 'database-interpolate)</CODE>
+</P>
+<P>
+
+Indexed sequential access methods allow finding the keys (having
+associations) closest to a given value. This facilitates the
+interpolation of associations between those in the table.
+</P>
+<P>
+
+<A NAME="IDX962"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>interpolate-from-table</B> <I>table column</I>
+<DD><VAR>Table</VAR> should be a relational table with one numeric primary key
+field which supports the <CODE>isam-prev</CODE> and <CODE>isam-next</CODE>
+operations. <VAR>column</VAR> should be a symbol or exact positive integer
+designating a numerically valued column of <VAR>table</VAR>.
+<P>
+
+<CODE>interpolate-from-table</CODE> calculates and returns a value
+proportionally intermediate between its values in the next and
+previous key records contained in <VAR>table</VAR>. For keys larger than
+all the stored keys the value associated with the largest stored key
+is used. For keys smaller than all the stored keys the value
+associated with the smallest stored key is used.
+</P>
+</DL>
+<P>
+
+<A NAME="Embedded Commands"></A>
+<HR SIZE="6">
+<A NAME="SEC155"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC154"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC156"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC141"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 6.1.4 Embedded Commands </H3>
+<!--docid::SEC155::-->
+<P>
+
+<CODE>(require 'database-commands)</CODE>
+</P>
+<P>
+
+This enhancement wraps a utility layer on <CODE>relational-database</CODE>
+which provides:
+</P>
+<P>
+
+<UL>
+<LI>
+Automatic execution of initialization commands stored in database.
+<LI>
+Transparent execution of database commands stored in <CODE>*commands*</CODE>
+table in database.
+</UL>
+<P>
+
+When an enhanced relational-database is called with a symbol which
+matches a <VAR>name</VAR> in the <CODE>*commands*</CODE> table, the associated
+procedure expression is evaluated and applied to the enhanced
+relational-database. A procedure should then be returned which the user
+can invoke on (optional) arguments.
+</P>
+<P>
+
+The command <CODE>*initialize*</CODE> is special. If present in the
+<CODE>*commands*</CODE> table, <CODE>open-database</CODE> or <CODE>open-database!</CODE>
+will return the value of the <CODE>*initialize*</CODE> command. Notice that
+arbitrary code can be run when the <CODE>*initialize*</CODE> procedure is
+automatically applied to the enhanced relational-database.
+</P>
+<P>
+
+Note also that if you wish to shadow or hide from the user
+relational-database methods described in <A HREF="slib_6.html#SEC177">6.2.4 Database Operations</A>, this
+can be done by a dispatch in the closure returned by the
+<CODE>*initialize*</CODE> expression rather than by entries in the
+<CODE>*commands*</CODE> table if it is desired that the underlying methods
+remain accessible to code in the <CODE>*commands*</CODE> table.
+</P>
+<P>
+
+<TABLE BORDER="0" CELLSPACING="0">
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC156">6.1.4.1 Database Extension</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC157">6.1.4.2 Command Intrinsics</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC158">6.1.4.3 Define-tables Example</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC159">6.1.4.4 The *commands* Table</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC160">6.1.4.5 Command Service</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC161">6.1.4.6 Command Example</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+</TABLE>
+<P>
+
+<A NAME="Database Extension"></A>
+<HR SIZE="6">
+<A NAME="SEC156"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC155"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC157"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC155"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.1.4.1 Database Extension </H4>
+<!--docid::SEC156::-->
+<P>
+
+<A NAME="IDX963"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>wrap-command-interface</B> <I>rdb</I>
+<DD>Returns relational database <VAR>rdb</VAR> wrapped with additional commands
+defined in its *commands* table.
+</DL>
+<P>
+
+<A NAME="IDX964"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>add-command-tables</B> <I>rdb</I>
+<DD>The relational database <VAR>rdb</VAR> must be mutable.
+<VAR>add-command-tables</VAR> adds a *command* table to <VAR>rdb</VAR>; then
+returns <CODE>(wrap-command-interface <VAR>rdb</VAR>)</CODE>.
+</DL>
+<P>
+
+<A NAME="IDX965"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>define-*commands*</B> <I>rdb spec-0 <small>...</small></I>
+<DD><P>
+
+Adds commands to the <CODE>*commands*</CODE> table as specified in
+<VAR>spec-0</VAR> <small>...</small> to the open relational-database <VAR>rdb</VAR>. Each
+<VAR>spec</VAR> has the form:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>((&lt;name&gt; &lt;rdb&gt;) &quot;comment&quot; &lt;expression1&gt; &lt;expression2&gt; <small>...</small>)
+</pre></td></tr></table>or
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>((&lt;name&gt; &lt;rdb&gt;) &lt;expression1&gt; &lt;expression2&gt; <small>...</small>)
+</pre></td></tr></table><P>
+
+where &lt;name&gt; is the command name, &lt;rdb&gt; is a formal passed the
+calling relational database, &quot;comment&quot; describes the
+command, and &lt;expression1&gt;, &lt;expression1&gt;, <small>...</small> are the
+body of the procedure.
+</P>
+<P>
+
+<CODE>define-*commands*</CODE> adds to the <CODE>*commands*</CODE> table a command
+&lt;name&gt;:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(lambda (&lt;name&gt; &lt;rdb&gt;) &lt;expression1&gt; &lt;expression2&gt; <small>...</small>)
+</pre></td></tr></table><P>
+
+</P>
+</DL>
+<P>
+
+<A NAME="IDX966"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>open-command-database</B> <I>filename</I>
+<DD><A NAME="IDX967"></A>
+<DT><U>Function:</U> <B>open-command-database</B> <I>filename base-table-type</I>
+<DD>Returns an open enhanced relational database associated with
+<VAR>filename</VAR>. The database will be opened with base-table type
+<VAR>base-table-type</VAR>) if supplied. If <VAR>base-table-type</VAR> is not
+supplied, <CODE>open-command-database</CODE> will attempt to deduce the correct
+base-table-type. If the database can not be opened or if it lacks the
+<CODE>*commands*</CODE> table, <CODE>#f</CODE> is returned.
+<P>
+
+<A NAME="IDX968"></A>
+<DT><U>Function:</U> <B>open-command-database!</B> <I>filename</I>
+<DD><A NAME="IDX969"></A>
+<DT><U>Function:</U> <B>open-command-database!</B> <I>filename base-table-type</I>
+<DD>Returns <EM>mutable</EM> open enhanced relational database <small>...</small>
+</P>
+<P>
+
+<A NAME="IDX970"></A>
+<DT><U>Function:</U> <B>open-command-database</B> <I>database</I>
+<DD>Returns <VAR>database</VAR> if it is an immutable relational database; #f
+otherwise.
+</P>
+<P>
+
+<A NAME="IDX971"></A>
+<DT><U>Function:</U> <B>open-command-database!</B> <I>database</I>
+<DD>Returns <VAR>database</VAR> if it is a mutable relational database; #f
+otherwise.
+</P>
+</DL>
+<P>
+
+<A NAME="Command Intrinsics"></A>
+<HR SIZE="6">
+<A NAME="SEC157"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC156"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC158"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC155"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.1.4.2 Command Intrinsics </H4>
+<!--docid::SEC157::-->
+<P>
+
+Some commands are defined in all extended relational-databases. The are
+called just like <A HREF="slib_6.html#SEC177">6.2.4 Database Operations</A>.
+</P>
+<P>
+
+<A NAME="IDX972"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-database <B>add-domain</B> <I>domain-row</I>
+<DD>Adds <VAR>domain-row</VAR> to the <EM>domains</EM> table if there is no row in
+the domains table associated with key <CODE>(car <VAR>domain-row</VAR>)</CODE> and
+returns <CODE>#t</CODE>. Otherwise returns <CODE>#f</CODE>.
+<P>
+
+For the fields and layout of the domain table, See section <A HREF="slib_6.html#SEC175">6.2.2 Catalog Representation</A>. Currently, these fields are
+<UL>
+<LI>
+domain-name
+<LI>
+foreign-table
+<LI>
+domain-integrity-rule
+<LI>
+type-id
+<LI>
+type-param
+</UL>
+<P>
+
+The following example adds 3 domains to the `<SAMP>build</SAMP>' database.
+`<SAMP>Optstring</SAMP>' is either a string or <CODE>#f</CODE>. <CODE>filename</CODE> is a
+string and <CODE>build-whats</CODE> is a symbol.
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(for-each (build 'add-domain)
+ '((optstring #f
+ (lambda (x) (or (not x) (string? x)))
+ string
+ #f)
+ (filename #f #f string #f)
+ (build-whats #f #f symbol #f)))
+</pre></td></tr></table></DL>
+<P>
+
+<A NAME="IDX973"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-database <B>delete-domain</B> <I>domain-name</I>
+<DD>Removes and returns the <VAR>domain-name</VAR> row from the <EM>domains</EM>
+table.
+</DL>
+<P>
+
+<A NAME="IDX974"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-database <B>domain-checker</B> <I>domain</I>
+<DD>Returns a procedure to check an argument for conformance to domain
+<VAR>domain</VAR>.
+</DL>
+<P>
+
+<A NAME="Define-tables Example"></A>
+<HR SIZE="6">
+<A NAME="SEC158"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC157"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC159"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC155"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.1.4.3 Define-tables Example </H4>
+<!--docid::SEC158::-->
+<P>
+
+The following example shows a new database with the name of
+`<TT>foo.db</TT>' being created with tables describing processor families
+and processor/os/compiler combinations. The database is then
+solidified; saved and changed to immutable.
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(require 'databases)
+<A NAME="IDX975"></A>(define my-rdb (create-database &quot;foo.db&quot; 'alist-table))
+(define-tables my-rdb
+ '(processor-family
+ ((family atom))
+ ((also-ran processor-family))
+ ((m68000 #f)
+ (m68030 m68000)
+ (i386 i8086)
+ (i8086 #f)
+ (powerpc #f)))
+
+ '(platform
+ ((name symbol))
+ ((processor processor-family)
+ (os symbol)
+ (compiler symbol))
+ ((aix powerpc aix -)
+ (amiga-dice-c m68000 amiga dice-c)
+ (amiga-aztec m68000 amiga aztec)
+ (amiga-sas/c-5.10 m68000 amiga sas/c)
+ (atari-st-gcc m68000 atari gcc)
+ (atari-st-turbo-c m68000 atari turbo-c)
+ (borland-c-3.1 i8086 ms-dos borland-c)
+ (djgpp i386 ms-dos gcc)
+ (linux i386 linux gcc)
+ (microsoft-c i8086 ms-dos microsoft-c)
+ (os/2-emx i386 os/2 gcc)
+ (turbo-c-2 i8086 ms-dos turbo-c)
+ (watcom-9.0 i386 ms-dos watcom))))
+
+(solidify-database my-rdb)
+</pre></td></tr></table><P>
+
+<A NAME="The *commands* Table"></A>
+<HR SIZE="6">
+<A NAME="SEC159"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC158"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC160"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC155"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.1.4.4 The *commands* Table </H4>
+<!--docid::SEC159::-->
+<P>
+
+The table <CODE>*commands*</CODE> in an <EM>enhanced</EM> relational-database has
+the fields (with domains):
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>PRI name symbol
+ parameters parameter-list
+ procedure expression
+ documentation string
+</pre></td></tr></table><P>
+
+The <CODE>parameters</CODE> field is a foreign key (domain
+<CODE>parameter-list</CODE>) of the <CODE>*catalog-data*</CODE> table and should
+have the value of a table described by <CODE>*parameter-columns*</CODE>. This
+<CODE>parameter-list</CODE> table describes the arguments suitable for passing
+to the associated command. The intent of this table is to be of a form
+such that different user-interfaces (for instance, pull-down menus or
+plain-text queries) can operate from the same table. A
+<CODE>parameter-list</CODE> table has the following fields:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>PRI index ordinal
+ name symbol
+ arity parameter-arity
+ domain domain
+ defaulter expression
+ expander expression
+ documentation string
+</pre></td></tr></table><P>
+
+The <CODE>arity</CODE> field can take the values:
+</P>
+<P>
+
+</P>
+<DL COMPACT>
+<DT><CODE>single</CODE>
+<DD>Requires a single parameter of the specified domain.
+<DT><CODE>optional</CODE>
+<DD>A single parameter of the specified domain or zero parameters is
+acceptable.
+<DT><CODE>boolean</CODE>
+<DD>A single boolean parameter or zero parameters (in which case <CODE>#f</CODE>
+is substituted) is acceptable.
+<DT><CODE>nary</CODE>
+<DD>Any number of parameters of the specified domain are acceptable. The
+argument passed to the command function is always a list of the
+parameters.
+<DT><CODE>nary1</CODE>
+<DD>One or more of parameters of the specified domain are acceptable. The
+argument passed to the command function is always a list of the
+parameters.
+</DL>
+<P>
+
+The <CODE>domain</CODE> field specifies the domain which a parameter or
+parameters in the <CODE>index</CODE>th field must satisfy.
+</P>
+<P>
+
+The <CODE>defaulter</CODE> field is an expression whose value is either
+<CODE>#f</CODE> or a procedure of one argument (the parameter-list) which
+returns a <EM>list</EM> of the default value or values as appropriate.
+Note that since the <CODE>defaulter</CODE> procedure is called every time a
+default parameter is needed for this column, <EM>sticky</EM> defaults can
+be implemented using shared state with the domain-integrity-rule.
+</P>
+<P>
+
+<A NAME="Command Service"></A>
+<HR SIZE="6">
+<A NAME="SEC160"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC159"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC161"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC155"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.1.4.5 Command Service </H4>
+<!--docid::SEC160::-->
+<P>
+
+<A NAME="IDX976"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>make-command-server</B> <I>rdb table-name</I>
+<DD>Returns a procedure of 2 arguments, a (symbol) command and a call-back
+procedure. When this returned procedure is called, it looks up
+<VAR>command</VAR> in table <VAR>table-name</VAR> and calls the call-back
+procedure with arguments:
+<DL COMPACT>
+<DT><VAR>command</VAR>
+<DD>The <VAR>command</VAR>
+<DT><VAR>command-value</VAR>
+<DD>The result of evaluating the expression in the <VAR>procedure</VAR> field of
+<VAR>table-name</VAR> and calling it with <VAR>rdb</VAR>.
+<DT><VAR>parameter-name</VAR>
+<DD>A list of the <EM>official</EM> name of each parameter. Corresponds to the
+<CODE>name</CODE> field of the <VAR>command</VAR>'s parameter-table.
+<DT><VAR>positions</VAR>
+<DD>A list of the positive integer index of each parameter. Corresponds to
+the <CODE>index</CODE> field of the <VAR>command</VAR>'s parameter-table.
+<DT><VAR>arities</VAR>
+<DD>A list of the arities of each parameter. Corresponds to the
+<CODE>arity</CODE> field of the <VAR>command</VAR>'s parameter-table. For a
+description of <CODE>arity</CODE> see table above.
+<DT><VAR>types</VAR>
+<DD>A list of the type name of each parameter. Correspnds to the
+<CODE>type-id</CODE> field of the contents of the <CODE>domain</CODE> of the
+<VAR>command</VAR>'s parameter-table.
+<DT><VAR>defaulters</VAR>
+<DD>A list of the defaulters for each parameter. Corresponds to
+the <CODE>defaulters</CODE> field of the <VAR>command</VAR>'s parameter-table.
+<DT><VAR>domain-integrity-rules</VAR>
+<DD>A list of procedures (one for each parameter) which tests whether a
+value for a parameter is acceptable for that parameter. The procedure
+should be called with each datum in the list for <CODE>nary</CODE> arity
+parameters.
+<DT><VAR>aliases</VAR>
+<DD>A list of lists of <CODE>(alias parameter-name)</CODE>. There can be
+more than one alias per <VAR>parameter-name</VAR>.
+</DL>
+</DL>
+<P>
+
+For information about parameters, See section <A HREF="slib_4.html#SEC65">4.4.4 Parameter lists</A>.
+</P>
+<P>
+
+<A NAME="Command Example"></A>
+<HR SIZE="6">
+<A NAME="SEC161"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC160"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC162"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC155"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.1.4.6 Command Example </H4>
+<!--docid::SEC161::-->
+<P>
+
+Here is an example of setting up a command with arguments and parsing
+those arguments from a <CODE>getopt</CODE> style argument list
+(see section <A HREF="slib_4.html#SEC62">4.4.1 Getopt</A>).
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(require 'database-commands)
+<A NAME="IDX977"></A>(require 'databases)
+<A NAME="IDX978"></A>(require 'getopt-parameters)
+<A NAME="IDX979"></A>(require 'parameters)
+<A NAME="IDX980"></A>(require 'getopt)
+<A NAME="IDX981"></A>(require 'fluid-let)
+(require 'printf)
+
+(define my-rdb (add-command-tables (create-database #f 'alist-table)))
+
+(define-tables my-rdb
+ '(foo-params
+ *parameter-columns*
+ *parameter-columns*
+ ((1 single-string single string
+ (lambda (pl) '(&quot;str&quot;)) #f &quot;single string&quot;)
+ (2 nary-symbols nary symbol
+ (lambda (pl) '()) #f &quot;zero or more symbols&quot;)
+ (3 nary1-symbols nary1 symbol
+ (lambda (pl) '(symb)) #f &quot;one or more symbols&quot;)
+ (4 optional-number optional ordinal
+ (lambda (pl) '()) #f &quot;zero or one number&quot;)
+ (5 flag boolean boolean
+ (lambda (pl) '(#f)) #f &quot;a boolean flag&quot;)))
+ '(foo-pnames
+ ((name string))
+ ((parameter-index ordinal))
+ ((&quot;s&quot; 1)
+ (&quot;single-string&quot; 1)
+ (&quot;n&quot; 2)
+ (&quot;nary-symbols&quot; 2)
+ (&quot;N&quot; 3)
+ (&quot;nary1-symbols&quot; 3)
+ (&quot;o&quot; 4)
+ (&quot;optional-number&quot; 4)
+ (&quot;f&quot; 5)
+ (&quot;flag&quot; 5)))
+ '(my-commands
+ ((name symbol))
+ ((parameters parameter-list)
+ (parameter-names parameter-name-translation)
+ (procedure expression)
+ (documentation string))
+ ((foo
+ foo-params
+ foo-pnames
+ (lambda (rdb) (lambda args (print args)))
+ &quot;test command arguments&quot;))))
+
+(define (dbutil:serve-command-line rdb command-table command argv)
+ (set! *argv* (if (vector? argv) (vector-&gt;list argv) argv))
+ ((make-command-server rdb command-table)
+ command
+ (lambda (comname comval options positions
+ arities types defaulters dirs aliases)
+ (apply comval (getopt-&gt;arglist options positions
+ arities types defaulters dirs aliases)))))
+
+(define (cmd . opts)
+ (fluid-let ((*optind* 1))
+ (printf &quot;%-34s => &quot;
+ (call-with-output-string
+ (lambda (pt) (write (cons 'cmd opts) pt))))
+ (set! opts (cons &quot;cmd&quot; opts))
+ (force-output)
+ (dbutil:serve-command-line
+ my-rdb 'my-commands 'foo (length opts) opts)))
+
+(cmd) => (&quot;str&quot; () (symb) () #f)
+(cmd &quot;-f&quot;) => (&quot;str&quot; () (symb) () #t)
+(cmd &quot;--flag&quot;) => (&quot;str&quot; () (symb) () #t)
+(cmd &quot;-o177&quot;) => (&quot;str&quot; () (symb) (177) #f)
+(cmd &quot;-o&quot; &quot;177&quot;) => (&quot;str&quot; () (symb) (177) #f)
+(cmd &quot;--optional&quot; &quot;621&quot;) => (&quot;str&quot; () (symb) (621) #f)
+(cmd &quot;--optional=621&quot;) => (&quot;str&quot; () (symb) (621) #f)
+(cmd &quot;-s&quot; &quot;speciality&quot;) => (&quot;speciality&quot; () (symb) () #f)
+(cmd &quot;-sspeciality&quot;) => (&quot;speciality&quot; () (symb) () #f)
+(cmd &quot;--single&quot; &quot;serendipity&quot;) => (&quot;serendipity&quot; () (symb) () #f)
+(cmd &quot;--single=serendipity&quot;) => (&quot;serendipity&quot; () (symb) () #f)
+(cmd &quot;-n&quot; &quot;gravity&quot; &quot;piety&quot;) => (&quot;str&quot; () (piety gravity) () #f)
+(cmd &quot;-ngravity&quot; &quot;piety&quot;) => (&quot;str&quot; () (piety gravity) () #f)
+(cmd &quot;--nary&quot; &quot;chastity&quot;) => (&quot;str&quot; () (chastity) () #f)
+(cmd &quot;--nary=chastity&quot; &quot;&quot;) => (&quot;str&quot; () ( chastity) () #f)
+(cmd &quot;-N&quot; &quot;calamity&quot;) => (&quot;str&quot; () (calamity) () #f)
+(cmd &quot;-Ncalamity&quot;) => (&quot;str&quot; () (calamity) () #f)
+(cmd &quot;--nary1&quot; &quot;surety&quot;) => (&quot;str&quot; () (surety) () #f)
+(cmd &quot;--nary1=surety&quot;) => (&quot;str&quot; () (surety) () #f)
+(cmd &quot;-N&quot; &quot;levity&quot; &quot;fealty&quot;) => (&quot;str&quot; () (fealty levity) () #f)
+(cmd &quot;-Nlevity&quot; &quot;fealty&quot;) => (&quot;str&quot; () (fealty levity) () #f)
+(cmd &quot;--nary1&quot; &quot;surety&quot; &quot;brevity&quot;) => (&quot;str&quot; () (brevity surety) () #f)
+(cmd &quot;--nary1=surety&quot; &quot;brevity&quot;) => (&quot;str&quot; () (brevity surety) () #f)
+(cmd &quot;-?&quot;)
+-|
+Usage: cmd [OPTION ARGUMENT ...] ...
+
+ -f, --flag
+ -o, --optional[=]&lt;number&gt;
+ -n, --nary[=]&lt;symbols&gt; ...
+ -N, --nary1[=]&lt;symbols&gt; ...
+ -s, --single[=]&lt;string&gt;
+
+ERROR: getopt-&gt;parameter-list &quot;unrecognized option&quot; &quot;-?&quot;
+</pre></td></tr></table><P>
+
+<A NAME="Database Macros"></A>
+<HR SIZE="6">
+<A NAME="SEC162"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC161"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC163"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC141"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 6.1.5 Database Macros </H3>
+<!--docid::SEC162::-->
+<P>
+
+<CODE>(require 'within-database)</CODE>
+</P>
+<P>
+
+The object-oriented programming interface to SLIB relational databases
+has failed to support clear, understandable, and modular code-writing
+for database applications.
+</P>
+<P>
+
+This seems to be a failure of the object-oriented paradigm where the
+type of an object is not manifest (or even traceable) in source code.
+</P>
+<P>
+
+<CODE>within-database</CODE>, along with the `<SAMP>databases</SAMP>' package,
+reorganizes high-level database functions toward a more declarative
+style. Using this package, one can tag database table and command
+declarations for emacs:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>etags -lscheme -r'/ *(define-\(command\|table\) (\([^; \t]+\)/\2/' \
+ source1.scm ...
+</pre></td></tr></table><P>
+
+<TABLE BORDER="0" CELLSPACING="0">
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC163">6.1.5.1 Within-database Example</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+</TABLE>
+<P>
+
+<A NAME="IDX982"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>within-database</B> <I>database statement-1 <small>...</small></I>
+<DD><P>
+
+<CODE>within-database</CODE> creates a lexical scope in which the commands
+<CODE>define-table</CODE> and <CODE>define-command</CODE> create tables and
+<CODE>*commands*</CODE>-table entries respectively in open relational
+database <VAR>database</VAR>.
+</P>
+<P>
+
+<CODE>within-database</CODE> Returns <VAR>database</VAR>.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX983"></A>
+</P>
+<DL>
+<DT><U>Syntax:</U> <B>define-command</B> <I>(&lt;name&gt; &lt;rdb&gt;) &quot;comment&quot; &lt;expression1&gt; &lt;expression2&gt; <small>...</small></I>
+<DD><A NAME="IDX984"></A>
+<DT><U>Syntax:</U> <B>define-command</B> <I>(&lt;name&gt; &lt;rdb&gt;) &lt;expression1&gt; &lt;expression2&gt; <small>...</small></I>
+<DD><P>
+
+Adds to the <CODE>*commands*</CODE> table a command
+&lt;name&gt;:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(lambda (&lt;name&gt; &lt;rdb&gt;) &lt;expression1&gt; &lt;expression2&gt; <small>...</small>)
+</pre></td></tr></table><P>
+
+</P>
+</DL>
+<P>
+
+<A NAME="IDX985"></A>
+</P>
+<DL>
+<DT><U>Syntax:</U> <B>define-table</B> <I>&lt;name&gt; &lt;descriptor-name&gt; &lt;descriptor-name&gt; &lt;rows&gt;</I>
+<DD><A NAME="IDX986"></A>
+<DT><U>Syntax:</U> <B>define-table</B> <I>&lt;name&gt; &lt;primary-key-fields&gt; &lt;other-fields&gt; &lt;rows&gt;</I>
+<DD><P>
+
+where &lt;name&gt; is the table name, &lt;descriptor-name&gt; is the symbol
+name of a descriptor table, &lt;primary-key-fields&gt; and
+&lt;other-fields&gt; describe the primary keys and other fields
+respectively, and &lt;rows&gt; is a list of data rows to be added to the
+table.
+</P>
+<P>
+
+&lt;primary-key-fields&gt; and &lt;other-fields&gt; are lists of field
+descriptors of the form:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(&lt;column-name&gt; &lt;domain&gt;)
+</pre></td></tr></table>or
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(&lt;column-name&gt; &lt;domain&gt; &lt;column-integrity-rule&gt;)
+</pre></td></tr></table><P>
+
+where &lt;column-name&gt; is the column name, &lt;domain&gt; is the domain
+of the column, and &lt;column-integrity-rule&gt; is an expression whose
+value is a procedure of one argument (which returns <CODE>#f</CODE> to signal
+an error).
+</P>
+<P>
+
+If &lt;domain&gt; is not a defined domain name and it matches the name of
+this table or an already defined (in one of <VAR>spec-0</VAR> <small>...</small>) single
+key field table, a foreign-key domain will be created for it.
+</P>
+<P>
+
+</P>
+</DL>
+<P>
+
+<A NAME="Within-database Example"></A>
+<HR SIZE="6">
+<A NAME="SEC163"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC162"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC164"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC162"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.1.5.1 Within-database Example </H4>
+<!--docid::SEC163::-->
+<P>
+
+Here is an example of <CODE>within-database</CODE> macros:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(require 'within-database)
+
+(define my-rdb
+ (add-command-tables
+ (create-database &quot;foo.db&quot; 'alist-table)))
+
+(within-database my-rdb
+ (define-command (*initialize* rdb)
+ &quot;Print Welcome&quot;
+ (display &quot;Welcome&quot;)
+ (newline)
+ rdb)
+ (define-command (without-documentation rdb)
+ (display &quot;without-documentation called&quot;)
+ (newline))
+ (define-table (processor-family
+ ((family atom))
+ ((also-ran processor-family)))
+ (m68000 #f)
+ (m68030 m68000)
+ (i386 i8086)
+ (i8086 #f)
+ (powerpc #f))
+ (define-table (platform
+ ((name symbol))
+ ((processor processor-family)
+ (os symbol)
+ (compiler symbol)))
+ (aix powerpc aix -)
+ ;; ...
+ (amiga-aztec m68000 amiga aztec)
+ (amiga-sas/c-5.10 m68000 amiga sas/c)
+ (atari-st-gcc m68000 atari gcc)
+ ;; ...
+ (watcom-9.0 i386 ms-dos watcom))
+ (define-command (get-processor rdb)
+ &quot;Get processor for given platform.&quot;
+ (((rdb 'open-table) 'platform #f) 'get 'processor)))
+
+(close-database my-rdb)
+
+(set! my-rdb (open-command-database! &quot;foo.db&quot;))
+-|
+Welcome
+
+(my-rdb 'without-documentation)
+-|
+without-documentation called
+
+((my-rdb 'get-processor) 'amiga-sas/c-5.10)
+=> m68000
+
+(close-database my-rdb)
+</pre></td></tr></table><P>
+
+<A NAME="Database Browser"></A>
+<HR SIZE="6">
+<A NAME="SEC164"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC163"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC165"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC141"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 6.1.6 Database Browser </H3>
+<!--docid::SEC164::-->
+<P>
+
+(require 'database-browse)
+</P>
+<P>
+
+<A NAME="IDX987"></A>
+</P>
+<DL>
+<DT><U>Procedure:</U> <B>browse</B> <I>database</I>
+<DD><P>
+
+Prints the names of all the tables in <VAR>database</VAR> and sets browse's
+default to <VAR>database</VAR>.
+</P>
+<P>
+
+<A NAME="IDX988"></A>
+<DT><U>Procedure:</U> <B>browse</B>
+<DD></P>
+<P>
+
+Prints the names of all the tables in the default database.
+</P>
+<P>
+
+<A NAME="IDX989"></A>
+<DT><U>Procedure:</U> <B>browse</B> <I>table-name</I>
+<DD></P>
+<P>
+
+For each record of the table named by the symbol <VAR>table-name</VAR>,
+prints a line composed of all the field values.
+</P>
+<P>
+
+<A NAME="IDX990"></A>
+<DT><U>Procedure:</U> <B>browse</B> <I>pathname</I>
+<DD></P>
+<P>
+
+Opens the database named by the string <VAR>pathname</VAR>, prints the names
+of all its tables, and sets browse's default to the database.
+</P>
+<P>
+
+<A NAME="IDX991"></A>
+<DT><U>Procedure:</U> <B>browse</B> <I>database table-name</I>
+<DD></P>
+<P>
+
+Sets browse's default to <VAR>database</VAR> and prints the records of the
+table named by the symbol <VAR>table-name</VAR>.
+</P>
+<P>
+
+<A NAME="IDX992"></A>
+<DT><U>Procedure:</U> <B>browse</B> <I>pathname table-name</I>
+<DD></P>
+<P>
+
+Opens the database named by the string <VAR>pathname</VAR> and sets browse's
+default to it; <CODE>browse</CODE> prints the records of the table named by
+the symbol <VAR>table-name</VAR>.
+</P>
+<P>
+
+</P>
+</DL>
+<P>
+
+<A NAME="Relational Infrastructure"></A>
+<HR SIZE="6">
+<A NAME="SEC165"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC164"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 6.2 Relational Infrastructure </H2>
+<!--docid::SEC165::-->
+<P>
+
+<TABLE BORDER="0" CELLSPACING="0">
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC166">6.2.1 Base Table</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC175">6.2.2 Catalog Representation</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC176">6.2.3 Relational Database Objects</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC177">6.2.4 Database Operations</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+</TABLE>
+<P>
+
+<A NAME="Base Table"></A>
+<HR SIZE="6">
+<A NAME="SEC166"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC165"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC167"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC165"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 6.2.1 Base Table </H3>
+<!--docid::SEC166::-->
+<P>
+
+<A NAME="IDX993"></A>
+A <EM>base-table</EM> is the primitive database layer upon which SLIB
+relational databases are built. At the minimum, it must support the
+types integer, symbol, string, and boolean. The base-table may restrict
+the size of integers, symbols, and strings it supports.
+</P>
+<P>
+
+A base table implementation is available as the value of the identifier
+naming it (eg. <VAR>alist-table</VAR>) after requiring the symbol of that
+name.
+</P>
+<P>
+
+<A NAME="IDX994"></A>
+</P>
+<DL>
+<DT><U>Feature:</U> <B>alist-table</B>
+<DD><CODE>(require 'alist-table)</CODE>
+<A NAME="IDX995"></A>
+<P>
+
+Association-list base tables support all Scheme types and are suitable
+for small databases. In order to be retrieved after being written to a
+file, the data stored should include only objects which are readable and
+writeable in the Scheme implementation.
+</P>
+<P>
+
+The <EM>alist-table</EM> base-table implementation is included in the
+SLIB distribution.
+</P>
+</DL>
+<P>
+
+<EM>WB</EM> is a B-tree database package with SCM interfaces. Being
+disk-based, WB databases readily store and access hundreds of
+megabytes of data. WB comes with two base-table embeddings.
+</P>
+<P>
+
+<A NAME="IDX996"></A>
+</P>
+<DL>
+<DT><U>Feature:</U> <B>wb-table</B>
+<DD><CODE>(require 'wb-table)</CODE>
+<A NAME="IDX997"></A>
+<P>
+
+<A NAME="IDX998"></A>
+<CODE>wb-table</CODE> supports scheme expressions for keys and values whose
+text representations are less than 255 characters in length.
+See section `wb-table' in <CITE>WB</CITE>.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX999"></A>
+</P>
+<DL>
+<DT><U>Feature:</U> <B>rwb-isam</B>
+<DD><CODE>(require 'rwb-isam)</CODE>
+<A NAME="IDX1000"></A>
+<P>
+
+<EM>rwb-isam</EM> is a sophisticated base-table implementation built on
+WB and SCM which uses binary numerical formats for key and non-key
+fields. It supports IEEE floating-point and fixed-precision integer
+keys with the correct numerical collation order.
+</P>
+</DL>
+<P>
+
+This rest of this section documents the interface for a base table
+implementation from which the <A HREF="slib_6.html#SEC141">6.1 Relational Database</A> package
+constructs a Relational system. It will be of interest primarily to
+those wishing to port or write new base-table implementations.
+</P>
+<P>
+
+<A NAME="IDX1001"></A>
+</P>
+<DL>
+<DT><U>Variable:</U> <B>*base-table-implementations*</B>
+<DD>To support automatic dispatch for <CODE>open-database</CODE>, each base-table
+module adds an association to <VAR>*base-table-implementations*</VAR> when
+loaded. This association is the list of the base-table symbol and the
+value returned by <CODE>(make-relational-system <VAR>base-table</VAR>)</CODE>.
+</DL>
+<P>
+
+<TABLE BORDER="0" CELLSPACING="0">
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC167">6.2.1.1 The Base</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC168">6.2.1.2 Base Tables</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC169">6.2.1.3 Base Field Types</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC170">6.2.1.4 Composite Keys</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC171">6.2.1.5 Base Record Operations</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC172">6.2.1.6 Match Keys</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC173">6.2.1.7 Aggregate Base Operations</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC174">6.2.1.8 Base ISAM Operations</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+</TABLE>
+<P>
+
+<A NAME="The Base"></A>
+<HR SIZE="6">
+<A NAME="SEC167"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC168"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.2.1.1 The Base </H4>
+<!--docid::SEC167::-->
+<P>
+
+All of these functions are accessed through a single procedure by
+calling that procedure with the symbol name of the operation. A
+procedure will be returned if that operation is supported and <CODE>#f</CODE>
+otherwise. For example:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(require 'alist-table)
+<A NAME="IDX1002"></A><A NAME="IDX1003"></A>(define my-base (alist-table 'make-base))
+my-base => *a procedure*
+(define foo (alist-table 'foo))
+foo => #f
+</pre></td></tr></table><P>
+
+<A NAME="IDX1004"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>make-base</B> <I>filename key-dimension column-types</I>
+<DD>Returns a new, open, low-level database (collection of tables)
+associated with <VAR>filename</VAR>. This returned database has an empty
+table associated with <VAR>catalog-id</VAR>. The positive integer
+<VAR>key-dimension</VAR> is the number of keys composed to make a
+<VAR>primary-key</VAR> for the catalog table. The list of symbols
+<VAR>column-types</VAR> describes the types of each column for that table.
+If the database cannot be created as specified, <CODE>#f</CODE> is returned.
+<P>
+
+Calling the <CODE>close-base</CODE> method on this database and possibly other
+operations will cause <VAR>filename</VAR> to be written to. If
+<VAR>filename</VAR> is <CODE>#f</CODE> a temporary, non-disk based database will be
+created if such can be supported by the base table implelentation.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX1005"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>open-base</B> <I>filename mutable</I>
+<DD>Returns an open low-level database associated with <VAR>filename</VAR>. If
+<VAR>mutable</VAR> is <CODE>#t</CODE>, this database will have methods capable of
+effecting change to the database. If <VAR>mutable</VAR> is <CODE>#f</CODE>, only
+methods for inquiring the database will be available. If the database
+cannot be opened as specified <CODE>#f</CODE> is returned.
+<P>
+
+Calling the <CODE>close-base</CODE> (and possibly other) method on a
+<VAR>mutable</VAR> database will cause <VAR>filename</VAR> to be written to.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX1006"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>write-base</B> <I>lldb filename</I>
+<DD>Causes the low-level database <VAR>lldb</VAR> to be written to
+<VAR>filename</VAR>. If the write is successful, also causes <VAR>lldb</VAR> to
+henceforth be associated with <VAR>filename</VAR>. Calling the
+<CODE>close-database</CODE> (and possibly other) method on <VAR>lldb</VAR> may
+cause <VAR>filename</VAR> to be written to. If <VAR>filename</VAR> is <CODE>#f</CODE>
+this database will be changed to a temporary, non-disk based database if
+such can be supported by the underlying base table implelentation. If
+the operations completed successfully, <CODE>#t</CODE> is returned.
+Otherwise, <CODE>#f</CODE> is returned.
+</DL>
+<P>
+
+<A NAME="IDX1007"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>sync-base</B> <I>lldb</I>
+<DD>Causes the file associated with the low-level database <VAR>lldb</VAR> to be
+updated to reflect its current state. If the associated filename is
+<CODE>#f</CODE>, no action is taken and <CODE>#f</CODE> is returned. If this
+operation completes successfully, <CODE>#t</CODE> is returned. Otherwise,
+<CODE>#f</CODE> is returned.
+</DL>
+<P>
+
+<A NAME="IDX1008"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>close-base</B> <I>lldb</I>
+<DD>Causes the low-level database <VAR>lldb</VAR> to be written to its associated
+file (if any). If the write is successful, subsequent operations to
+<VAR>lldb</VAR> will signal an error. If the operations complete
+successfully, <CODE>#t</CODE> is returned. Otherwise, <CODE>#f</CODE> is returned.
+</DL>
+<P>
+
+<A NAME="Base Tables"></A>
+<HR SIZE="6">
+<A NAME="SEC168"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC167"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC169"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.2.1.2 Base Tables </H4>
+<!--docid::SEC168::-->
+<P>
+
+<A NAME="IDX1009"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>make-table</B> <I>lldb key-dimension column-types</I>
+<DD>Returns the ordinal <VAR>base-id</VAR> for a new base table, otherwise
+returns <CODE>#f</CODE>. The base table can then be opened using
+<CODE>(open-table <VAR>lldb</VAR> <VAR>base-id</VAR>)</CODE>. The positive integer
+<VAR>key-dimension</VAR> is the number of keys composed to make a
+<VAR>primary-key</VAR> for this table. The list of symbols
+<VAR>column-types</VAR> describes the types of each column.
+</DL>
+<P>
+
+<A NAME="IDX1010"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>open-table</B> <I>lldb base-id key-dimension column-types</I>
+<DD>Returns a <VAR>handle</VAR> for an existing base table in the low-level
+database <VAR>lldb</VAR> if that table exists and can be opened in the mode
+indicated by <VAR>mutable</VAR>, otherwise returns <CODE>#f</CODE>.
+<P>
+
+As with <CODE>make-table</CODE>, the positive integer <VAR>key-dimension</VAR> is
+the number of keys composed to make a <VAR>primary-key</VAR> for this table.
+The list of symbols <VAR>column-types</VAR> describes the types of each
+column.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX1011"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>kill-table</B> <I>lldb base-id key-dimension column-types</I>
+<DD>Returns <CODE>#t</CODE> if the base table associated with <VAR>base-id</VAR> was
+removed from the low level database <VAR>lldb</VAR>, and <CODE>#f</CODE> otherwise.
+</DL>
+<P>
+
+<A NAME="IDX1012"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>catalog-id</B>
+<DD>A constant <VAR>base-id</VAR> ordinal suitable for passing as a parameter to
+<CODE>open-table</CODE>. <VAR>catalog-id</VAR> will be used as the base table for
+the system catalog.
+</DL>
+<P>
+
+<A NAME="Base Field Types"></A>
+<HR SIZE="6">
+<A NAME="SEC169"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC168"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC170"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.2.1.3 Base Field Types </H4>
+<!--docid::SEC169::-->
+<P>
+
+<A NAME="IDX1013"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>supported-type?</B> <I>symbol</I>
+<DD>Returns <CODE>#t</CODE> if <VAR>symbol</VAR> names a type allowed as a column
+value by the implementation, and <CODE>#f</CODE> otherwise. At a minimum,
+an implementation must support the types <CODE>integer</CODE>,
+<CODE>ordinal</CODE>, <CODE>symbol</CODE>, <CODE>string</CODE>, and <CODE>boolean</CODE>.
+</DL>
+<P>
+
+<A NAME="IDX1014"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>supported-key-type?</B> <I>symbol</I>
+<DD>Returns <CODE>#t</CODE> if <VAR>symbol</VAR> names a type allowed as a key value
+by the implementation, and <CODE>#f</CODE> otherwise. At a minimum, an
+implementation must support the types <CODE>ordinal</CODE>, and
+<CODE>symbol</CODE>.
+</DL>
+<P>
+
+An <EM>ordinal</EM> is an exact positive integer. The other types are
+standard Scheme.
+</P>
+<P>
+
+<A NAME="Composite Keys"></A>
+<HR SIZE="6">
+<A NAME="SEC170"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC169"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC171"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.2.1.4 Composite Keys </H4>
+<!--docid::SEC170::-->
+<P>
+
+<A NAME="IDX1015"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>make-keyifier-1</B> <I>type</I>
+<DD>Returns a procedure which accepts a single argument which must be of
+type <VAR>type</VAR>. This returned procedure returns an object suitable for
+being a <VAR>key</VAR> argument in the functions whose descriptions follow.
+<P>
+
+Any 2 arguments of the supported type passed to the returned function
+which are not <CODE>equal?</CODE> must result in returned values which are not
+<CODE>equal?</CODE>.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX1016"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>make-list-keyifier</B> <I>key-dimension types</I>
+<DD>The list of symbols <VAR>types</VAR> must have at least <VAR>key-dimension</VAR>
+elements. Returns a procedure which accepts a list of length
+<VAR>key-dimension</VAR> and whose types must corresopond to the types named
+by <VAR>types</VAR>. This returned procedure combines the elements of its
+list argument into an object suitable for being a <VAR>key</VAR> argument in
+the functions whose descriptions follow.
+<P>
+
+Any 2 lists of supported types (which must at least include symbols and
+non-negative integers) passed to the returned function which are not
+<CODE>equal?</CODE> must result in returned values which are not
+<CODE>equal?</CODE>.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX1017"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>make-key-extractor</B> <I>key-dimension types column-number</I>
+<DD>Returns a procedure which accepts objects produced by application of the
+result of <CODE>(make-list-keyifier <VAR>key-dimension</VAR> <VAR>types</VAR>)</CODE>.
+This procedure returns a <VAR>key</VAR> which is <CODE>equal?</CODE> to the
+<VAR>column-number</VAR>th element of the list which was passed to create
+<VAR>composite-key</VAR>. The list <VAR>types</VAR> must have at least
+<VAR>key-dimension</VAR> elements.
+</DL>
+<P>
+
+<A NAME="IDX1018"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>make-key-&gt;list</B> <I>key-dimension types</I>
+<DD>Returns a procedure which accepts objects produced by application of
+the result of <CODE>(make-list-keyifier <VAR>key-dimension</VAR>
+<VAR>types</VAR>)</CODE>. This procedure returns a list of <VAR>key</VAR>s which are
+elementwise <CODE>equal?</CODE> to the list which was passed to create
+<VAR>composite-key</VAR>.
+</DL>
+<P>
+
+<A NAME="Base Record Operations"></A>
+<HR SIZE="6">
+<A NAME="SEC171"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC170"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC172"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.2.1.5 Base Record Operations </H4>
+<!--docid::SEC171::-->
+<P>
+
+In the following functions, the <VAR>key</VAR> argument can always be assumed
+to be the value returned by a call to a <EM>keyify</EM> routine.
+</P>
+<P>
+
+<A NAME="IDX1019"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>present?</B> <I>handle key</I>
+<DD>Returns a non-<CODE>#f</CODE> value if there is a row associated with
+<VAR>key</VAR> in the table opened in <VAR>handle</VAR> and <CODE>#f</CODE> otherwise.
+</DL>
+<P>
+
+<A NAME="IDX1020"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>make-getter</B> <I>key-dimension types</I>
+<DD>Returns a procedure which takes arguments <VAR>handle</VAR> and <VAR>key</VAR>.
+This procedure returns a list of the non-primary values of the relation
+(in the base table opened in <VAR>handle</VAR>) whose primary key is
+<VAR>key</VAR> if it exists, and <CODE>#f</CODE> otherwise.
+</DL>
+<P>
+
+<CODE>make-getter-1</CODE> is a new operation. The relational-database
+module works with older base-table implementations by using
+<CODE>make-getter</CODE>.
+</P>
+<P>
+
+<A NAME="IDX1021"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>make-getter-1</B> <I>key-dimension types index</I>
+<DD>Returns a procedure which takes arguments <VAR>handle</VAR> and <VAR>key</VAR>.
+This procedure returns the value of the <VAR>index</VAR>th field (in the
+base table opened in <VAR>handle</VAR>) whose primary key is <VAR>key</VAR> if
+it exists, and <CODE>#f</CODE> otherwise.
+<P>
+
+<VAR>index</VAR> must be larger than <VAR>key-dimension</VAR>.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX1022"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>make-putter</B> <I>key-dimension types</I>
+<DD>Returns a procedure which takes arguments <VAR>handle</VAR> and <VAR>key</VAR> and
+<VAR>value-list</VAR>. This procedure associates the primary key <VAR>key</VAR>
+with the values in <VAR>value-list</VAR> (in the base table opened in
+<VAR>handle</VAR>) and returns an unspecified value.
+</DL>
+<P>
+
+<A NAME="IDX1023"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>delete</B> <I>handle key</I>
+<DD>Removes the row associated with <VAR>key</VAR> from the table opened in
+<VAR>handle</VAR>. An unspecified value is returned.
+</DL>
+<P>
+
+<A NAME="Match Keys"></A>
+<HR SIZE="6">
+<A NAME="SEC172"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC171"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC173"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.2.1.6 Match Keys </H4>
+<!--docid::SEC172::-->
+<P>
+
+<A NAME="IDX1024"></A>
+<A NAME="IDX1025"></A>
+<A NAME="IDX1026"></A>
+A <VAR>match-keys</VAR> argument is a list of length equal to
+the number of primary keys. The <VAR>match-keys</VAR> restrict the actions
+of the table command to those records whose primary keys all satisfy the
+corresponding element of the <VAR>match-keys</VAR> list. The elements and
+their actions are:
+</P>
+<P>
+
+<BLOCKQUOTE>
+<DL COMPACT>
+<DT><CODE>#f</CODE>
+<DD>The false value matches any key in the corresponding position.
+<DT>an object of type procedure
+<DD>This procedure must take a single argument, the key in the corresponding
+position. Any key for which the procedure returns a non-false value is
+a match; Any key for which the procedure returns a <CODE>#f</CODE> is not.
+<DT>other values
+<DD>Any other value matches only those keys <CODE>equal?</CODE> to it.
+</DL>
+</BLOCKQUOTE>
+<P>
+
+<A NAME="Aggregate Base Operations"></A>
+<HR SIZE="6">
+<A NAME="SEC173"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC172"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC174"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.2.1.7 Aggregate Base Operations </H4>
+<!--docid::SEC173::-->
+<P>
+
+The <VAR>key-dimension</VAR> and <VAR>column-types</VAR> arguments are needed to
+decode the composite-keys for matching with <VAR>match-keys</VAR>.
+</P>
+<P>
+
+<A NAME="IDX1027"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>delete*</B> <I>handle key-dimension column-types match-keys</I>
+<DD>Removes all rows which satisfy <VAR>match-keys</VAR> from the table opened in
+<VAR>handle</VAR>. An unspecified value is returned.
+</DL>
+<P>
+
+<A NAME="IDX1028"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>for-each-key</B> <I>handle procedure key-dimension column-types match-keys</I>
+<DD>Calls <VAR>procedure</VAR> once with each <VAR>key</VAR> in the table opened in
+<VAR>handle</VAR> which satisfy <VAR>match-keys</VAR> in an unspecified order.
+An unspecified value is returned.
+</DL>
+<P>
+
+<A NAME="IDX1029"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>map-key</B> <I>handle procedure key-dimension column-types match-keys</I>
+<DD>Returns a list of the values returned by calling <VAR>procedure</VAR> once
+with each <VAR>key</VAR> in the table opened in <VAR>handle</VAR> which satisfy
+<VAR>match-keys</VAR> in an unspecified order.
+</DL>
+<P>
+
+<A NAME="Base ISAM Operations"></A>
+<HR SIZE="6">
+<A NAME="SEC174"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC173"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC175"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC166"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H4> 6.2.1.8 Base ISAM Operations </H4>
+<!--docid::SEC174::-->
+<P>
+
+These operations are optional for a Base-Table implementation.
+</P>
+<P>
+
+<A NAME="IDX1030"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>ordered-for-each-key</B> <I>handle procedure key-dimension column-types match-keys</I>
+<DD>Calls <VAR>procedure</VAR> once with each <VAR>key</VAR> in the table opened in
+<VAR>handle</VAR> which satisfy <VAR>match-keys</VAR> in the natural order for
+the types of the primary key fields of that table. An unspecified value
+is returned.
+</DL>
+<P>
+
+<A NAME="IDX1031"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>make-nexter</B> <I>handle key-dimension column-types index</I>
+<DD>Returns a procedure of arguments <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which
+returns the key-list identifying the lowest record higher than
+<VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which is stored in the base-table and
+which differs in column <VAR>index</VAR> or a lower indexed key; or false
+if no higher record is present.
+</DL>
+<P>
+
+<A NAME="IDX1032"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> base-table <B>make-prever</B> <I>handle key-dimension column-types index</I>
+<DD>Returns a procedure of arguments <VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which
+returns the key-list identifying the highest record less than
+<VAR>key1</VAR> <VAR>key2</VAR> <small>...</small> which is stored in the base-table and
+which differs in column <VAR>index</VAR> or a lower indexed key; or false
+if no higher record is present.
+</DL>
+<P>
+
+<A NAME="Catalog Representation"></A>
+<HR SIZE="6">
+<A NAME="SEC175"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC174"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC176"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC165"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 6.2.2 Catalog Representation </H3>
+<!--docid::SEC175::-->
+<P>
+
+Each database (in an implementation) has a <EM>system catalog</EM> which
+describes all the user accessible tables in that database (including
+itself).
+</P>
+<P>
+
+The system catalog base table has the following fields. <CODE>PRI</CODE>
+indicates a primary key for that table.
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>PRI table-name
+ column-limit the highest column number
+ coltab-name descriptor table name
+ bastab-id data base table identifier
+ user-integrity-rule
+ view-procedure A scheme thunk which, when called,
+ produces a handle for the view. coltab
+ and bastab are specified if and only if
+ view-procedure is not.
+</pre></td></tr></table><P>
+
+Descriptors for base tables (not views) are tables (pointed to by
+system catalog). Descriptor (base) tables have the fields:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>PRI column-number sequential integers from 1
+ primary-key? boolean TRUE for primary key components
+ column-name
+ column-integrity-rule
+ domain-name
+</pre></td></tr></table><P>
+
+A <EM>primary key</EM> is any column marked as <CODE>primary-key?</CODE> in the
+corresponding descriptor table. All the <CODE>primary-key?</CODE> columns
+must have lower column numbers than any non-<CODE>primary-key?</CODE> columns.
+Every table must have at least one primary key. Primary keys must be
+sufficient to distinguish all rows from each other in the table. All of
+the system defined tables have a single primary key.
+</P>
+<P>
+
+A <EM>domain</EM> is a category describing the allowable values to occur in
+a column. It is described by a (base) table with the fields:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>PRI domain-name
+ foreign-table
+ domain-integrity-rule
+ type-id
+ type-param
+</pre></td></tr></table><P>
+
+The <EM>type-id</EM> field value is a symbol. This symbol may be used by
+the underlying base table implementation in storing that field.
+</P>
+<P>
+
+If the <CODE>foreign-table</CODE> field is non-<CODE>#f</CODE> then that field names
+a table from the catalog. The values for that domain must match a
+primary key of the table referenced by the <VAR>type-param</VAR> (or
+<CODE>#f</CODE>, if allowed). This package currently does not support
+composite foreign-keys.
+</P>
+<P>
+
+The types for which support is planned are:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre> atom
+ symbol
+ string [&lt;length&gt;]
+ number [&lt;base&gt;]
+ money &lt;currency&gt;
+ date-time
+ boolean
+
+ foreign-key &lt;table-name&gt;
+ expression
+ virtual &lt;expression&gt;
+</pre></td></tr></table><P>
+
+<A NAME="Relational Database Objects"></A>
+<HR SIZE="6">
+<A NAME="SEC176"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC175"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC177"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC165"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 6.2.3 Relational Database Objects </H3>
+<!--docid::SEC176::-->
+<P>
+
+This object-oriented interface is deprecated for typical database
+applications; <A HREF="slib_6.html#SEC142">6.1.1 Using Databases</A> provides an application programmer
+interface which is easier to understand and use.
+</P>
+<P>
+
+<A NAME="IDX1033"></A>
+</P>
+<DL>
+<DT><U>Function:</U> <B>make-relational-system</B> <I>base-table-implementation</I>
+<DD><P>
+
+Returns a procedure implementing a relational database using the
+<VAR>base-table-implementation</VAR>.
+</P>
+<P>
+
+All of the operations of a base table implementation are accessed
+through a procedure defined by <CODE>require</CODE>ing that implementation.
+Similarly, all of the operations of the relational database
+implementation are accessed through the procedure returned by
+<CODE>make-relational-system</CODE>. For instance, a new relational database
+could be created from the procedure returned by
+<CODE>make-relational-system</CODE> by:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(require 'alist-table)
+<A NAME="IDX1034"></A>(define relational-alist-system
+ (make-relational-system alist-table))
+(define create-alist-database
+ (relational-alist-system 'create-database))
+(define my-database
+ (create-alist-database &quot;mydata.db&quot;))
+</pre></td></tr></table></DL>
+<P>
+
+What follows are the descriptions of the methods available from
+relational system returned by a call to <CODE>make-relational-system</CODE>.
+</P>
+<P>
+
+<A NAME="IDX1035"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-system <B>create-database</B> <I>filename</I>
+<DD><P>
+
+Returns an open, nearly empty relational database associated with
+<VAR>filename</VAR>. The only tables defined are the system catalog and
+domain table. Calling the <CODE>close-database</CODE> method on this database
+and possibly other operations will cause <VAR>filename</VAR> to be written
+to. If <VAR>filename</VAR> is <CODE>#f</CODE> a temporary, non-disk based database
+will be created if such can be supported by the underlying base table
+implelentation. If the database cannot be created as specified
+<CODE>#f</CODE> is returned. For the fields and layout of descriptor tables,
+<A HREF="slib_6.html#SEC175">6.2.2 Catalog Representation</A>
+</P>
+</DL>
+<P>
+
+<A NAME="IDX1036"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-system <B>open-database</B> <I>filename mutable?</I>
+<DD><P>
+
+Returns an open relational database associated with <VAR>filename</VAR>. If
+<VAR>mutable?</VAR> is <CODE>#t</CODE>, this database will have methods capable of
+effecting change to the database. If <VAR>mutable?</VAR> is <CODE>#f</CODE>, only
+methods for inquiring the database will be available. Calling the
+<CODE>close-database</CODE> (and possibly other) method on a <VAR>mutable?</VAR>
+database will cause <VAR>filename</VAR> to be written to. If the database
+cannot be opened as specified <CODE>#f</CODE> is returned.
+</P>
+</DL>
+<P>
+
+<A NAME="Database Operations"></A>
+<HR SIZE="6">
+<A NAME="SEC177"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC176"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC178"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC165"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 6.2.4 Database Operations </H3>
+<!--docid::SEC177::-->
+<P>
+
+This object-oriented interface is deprecated for typical database
+applications; <A HREF="slib_6.html#SEC142">6.1.1 Using Databases</A> provides an application programmer
+interface which is easier to understand and use.
+</P>
+<P>
+
+These are the descriptions of the methods available from an open
+relational database. A method is retrieved from a database by calling
+the database with the symbol name of the operation. For example:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(define my-database
+ (create-alist-database &quot;mydata.db&quot;))
+(define telephone-table-desc
+ ((my-database 'create-table) 'telephone-table-desc))
+</pre></td></tr></table><P>
+
+<A NAME="IDX1037"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-database <B>close-database</B>
+<DD>Causes the relational database to be written to its associated file (if
+any). If the write is successful, subsequent operations to this
+database will signal an error. If the operations completed
+successfully, <CODE>#t</CODE> is returned. Otherwise, <CODE>#f</CODE> is returned.
+</DL>
+<P>
+
+<A NAME="IDX1038"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-database <B>write-database</B> <I>filename</I>
+<DD>Causes the relational database to be written to <VAR>filename</VAR>. If the
+write is successful, also causes the database to henceforth be
+associated with <VAR>filename</VAR>. Calling the <CODE>close-database</CODE> (and
+possibly other) method on this database will cause <VAR>filename</VAR> to be
+written to. If <VAR>filename</VAR> is <CODE>#f</CODE> this database will be
+changed to a temporary, non-disk based database if such can be supported
+by the underlying base table implelentation. If the operations
+completed successfully, <CODE>#t</CODE> is returned. Otherwise, <CODE>#f</CODE> is
+returned.
+</DL>
+<P>
+
+<A NAME="IDX1039"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-database <B>sync-database</B>
+<DD>Causes any pending updates to the database file to be written out. If
+the operations completed successfully, <CODE>#t</CODE> is returned.
+Otherwise, <CODE>#f</CODE> is returned.
+</DL>
+<P>
+
+<A NAME="IDX1040"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-database <B>solidify-database</B>
+<DD>Causes any pending updates to the database file to be written out. If
+the writes completed successfully, then the database is changed to be
+immutable and <CODE>#t</CODE> is returned. Otherwise, <CODE>#f</CODE> is returned.
+</DL>
+<P>
+
+<A NAME="IDX1041"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-database <B>table-exists?</B> <I>table-name</I>
+<DD>Returns <CODE>#t</CODE> if <VAR>table-name</VAR> exists in the system catalog,
+otherwise returns <CODE>#f</CODE>.
+</DL>
+<P>
+
+<A NAME="IDX1042"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-database <B>open-table</B> <I>table-name mutable?</I>
+<DD>Returns a <EM>methods</EM> procedure for an existing relational table in
+this database if it exists and can be opened in the mode indicated by
+<VAR>mutable?</VAR>, otherwise returns <CODE>#f</CODE>.
+</DL>
+<P>
+
+These methods will be present only in mutable databases.
+</P>
+<P>
+
+<A NAME="IDX1043"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-database <B>delete-table</B> <I>table-name</I>
+<DD>Removes and returns the <VAR>table-name</VAR> row from the system catalog if
+the table or view associated with <VAR>table-name</VAR> gets removed from the
+database, and <CODE>#f</CODE> otherwise.
+</DL>
+<P>
+
+<A NAME="IDX1044"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-database <B>create-table</B> <I>table-desc-name</I>
+<DD>Returns a methods procedure for a new (open) relational table for
+describing the columns of a new base table in this database, otherwise
+returns <CODE>#f</CODE>. For the fields and layout of descriptor tables,
+See section <A HREF="slib_6.html#SEC175">6.2.2 Catalog Representation</A>.
+<P>
+
+<A NAME="IDX1045"></A>
+<DT><U>Operation:</U> relational-database <B>create-table</B> <I>table-name table-desc-name</I>
+<DD>Returns a methods procedure for a new (open) relational table with
+columns as described by <VAR>table-desc-name</VAR>, otherwise returns
+<CODE>#f</CODE>.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX1046"></A>
+</P>
+<DL>
+<DT><U>Operation:</U> relational-database <B>create-view</B> <I>??</I>
+<DD><A NAME="IDX1047"></A>
+<DT><U>Operation:</U> relational-database <B>project-table</B> <I>??</I>
+<DD><A NAME="IDX1048"></A>
+<DT><U>Operation:</U> relational-database <B>restrict-table</B> <I>??</I>
+<DD><A NAME="IDX1049"></A>
+<DT><U>Operation:</U> relational-database <B>cart-prod-tables</B> <I>??</I>
+<DD>Not yet implemented.
+</DL>
+<P>
+
+<A NAME="Weight-Balanced Trees"></A>
+<HR SIZE="6">
+<A NAME="SEC178"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC177"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC179"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 6.3 Weight-Balanced Trees </H2>
+<!--docid::SEC178::-->
+<P>
+
+<CODE>(require 'wt-tree)</CODE>
+<A NAME="IDX1050"></A>
+</P>
+<P>
+
+<A NAME="IDX1051"></A>
+<A NAME="IDX1052"></A>
+<A NAME="IDX1053"></A>
+<A NAME="IDX1054"></A>
+Balanced binary trees are a useful data structure for maintaining large
+sets of ordered objects or sets of associations whose keys are ordered.
+MIT Scheme has an comprehensive implementation of weight-balanced binary
+trees which has several advantages over the other data structures for
+large aggregates:
+</P>
+<P>
+
+<UL>
+<LI>
+In addition to the usual element-level operations like insertion,
+deletion and lookup, there is a full complement of collection-level
+operations, like set intersection, set union and subset test, all of
+which are implemented with good orders of growth in time and space.
+This makes weight balanced trees ideal for rapid prototyping of
+functionally derived specifications.
+<P>
+
+</P>
+<LI>
+An element in a tree may be indexed by its position under the ordering
+of the keys, and the ordinal position of an element may be determined,
+both with reasonable efficiency.
+<P>
+
+</P>
+<LI>
+Operations to find and remove minimum element make weight balanced trees
+simple to use for priority queues.
+<P>
+
+</P>
+<LI>
+The implementation is <EM>functional</EM> rather than <EM>imperative</EM>.
+This means that operations like `inserting' an association in a tree do
+not destroy the old tree, in much the same way that <CODE>(+ 1 x)</CODE>
+modifies neither the constant 1 nor the value bound to <CODE>x</CODE>. The
+trees are referentially transparent thus the programmer need not worry
+about copying the trees. Referential transparency allows space
+efficiency to be achieved by sharing subtrees.
+<P>
+
+</UL>
+<P>
+
+These features make weight-balanced trees suitable for a wide range of
+applications, especially those that
+require large numbers of sets or discrete maps. Applications that have
+a few global databases and/or concentrate on element-level operations like
+insertion and lookup are probably better off using hash-tables or
+red-black trees.
+</P>
+<P>
+
+The <EM>size</EM> of a tree is the number of associations that it
+contains. Weight balanced binary trees are balanced to keep the sizes
+of the subtrees of each node within a constant factor of each other.
+This ensures logarithmic times for single-path operations (like lookup
+and insertion). A weight balanced tree takes space that is proportional
+to the number of associations in the tree. For the current
+implementation, the constant of proportionality is six words per
+association.
+</P>
+<P>
+
+<A NAME="IDX1055"></A>
+<A NAME="IDX1056"></A>
+<A NAME="IDX1057"></A>
+<A NAME="IDX1058"></A>
+Weight balanced trees can be used as an implementation for either
+discrete sets or discrete maps (associations). Sets are implemented by
+ignoring the datum that is associated with the key. Under this scheme
+if an associations exists in the tree this indicates that the key of the
+association is a member of the set. Typically a value such as
+<CODE>()</CODE>, <CODE>#t</CODE> or <CODE>#f</CODE> is associated with the key.
+</P>
+<P>
+
+Many operations can be viewed as computing a result that, depending on
+whether the tree arguments are thought of as sets or maps, is known by
+two different names. An example is <CODE>wt-tree/member?</CODE>, which, when
+regarding the tree argument as a set, computes the set membership
+operation, but, when regarding the tree as a discrete map,
+<CODE>wt-tree/member?</CODE> is the predicate testing if the map is defined at
+an element in its domain. Most names in this package have been chosen
+based on interpreting the trees as sets, hence the name
+<CODE>wt-tree/member?</CODE> rather than <CODE>wt-tree/defined-at?</CODE>.
+</P>
+<P>
+
+<A NAME="IDX1059"></A>
+<A NAME="IDX1060"></A>
+The weight balanced tree implementation is a run-time-loadable option.
+To use weight balanced trees, execute
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(load-option 'wt-tree)
+</pre></td></tr></table><A NAME="IDX1061"></A>
+<P>
+
+once before calling any of the procedures defined here.
+</P>
+<P>
+
+<TABLE BORDER="0" CELLSPACING="0">
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC179">6.3.1 Construction of Weight-Balanced Trees</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC180">6.3.2 Basic Operations on Weight-Balanced Trees</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC181">6.3.3 Advanced Operations on Weight-Balanced Trees</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_6.html#SEC182">6.3.4 Indexing Operations on Weight-Balanced Trees</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
+</TABLE>
+<P>
+
+<A NAME="Construction of Weight-Balanced Trees"></A>
+<HR SIZE="6">
+<A NAME="SEC179"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC178"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC180"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC178"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 6.3.1 Construction of Weight-Balanced Trees </H3>
+<!--docid::SEC179::-->
+<P>
+
+Binary trees require there to be a total order on the keys used to
+arrange the elements in the tree. Weight balanced trees are organized
+by <EM>types</EM>, where the type is an object encapsulating the ordering
+relation. Creating a tree is a two-stage process. First a tree type
+must be created from the predicate which gives the ordering. The tree
+type is then used for making trees, either empty or singleton trees or
+trees from other aggregate structures like association lists. Once
+created, a tree `knows' its type and the type is used to test
+compatibility between trees in operations taking two trees. Usually a
+small number of tree types are created at the beginning of a program and
+used many times throughout the program's execution.
+</P>
+<P>
+
+<A NAME="IDX1062"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>make-wt-tree-type</B> <I>key&lt;?</I>
+<DD>This procedure creates and returns a new tree type based on the ordering
+predicate <VAR>key&lt;?</VAR>.
+<VAR>Key&lt;?</VAR> must be a total ordering, having the property that for all
+key values <CODE>a</CODE>, <CODE>b</CODE> and <CODE>c</CODE>:
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(key&lt;? a a) => #f
+(and (key&lt;? a b) (key&lt;? b a)) => #f
+(if (and (key&lt;? a b) (key&lt;? b c))
+ (key&lt;? a c)
+ #t) => #t
+</pre></td></tr></table><P>
+
+Two key values are assumed to be equal if neither is less than the other
+by <VAR>key&lt;?</VAR>.
+</P>
+<P>
+
+Each call to <CODE>make-wt-tree-type</CODE> returns a distinct value, and
+trees are only compatible if their tree types are <CODE>eq?</CODE>. A
+consequence is that trees that are intended to be used in binary tree
+operations must all be created with a tree type originating from the
+same call to <CODE>make-wt-tree-type</CODE>.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX1063"></A>
+</P>
+<DL>
+<DT><U>variable+:</U> <B>number-wt-type</B>
+<DD>A standard tree type for trees with numeric keys. <CODE>Number-wt-type</CODE>
+could have been defined by
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(define number-wt-type (make-wt-tree-type &lt;))
+</pre></td></tr></table></DL>
+<P>
+
+<A NAME="IDX1064"></A>
+</P>
+<DL>
+<DT><U>variable+:</U> <B>string-wt-type</B>
+<DD>A standard tree type for trees with string keys. <CODE>String-wt-type</CODE>
+could have been defined by
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(define string-wt-type (make-wt-tree-type string&lt;?))
+</pre></td></tr></table></DL>
+<P>
+
+<A NAME="IDX1065"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>make-wt-tree</B> <I>wt-tree-type</I>
+<DD>This procedure creates and returns a newly allocated weight balanced
+tree. The tree is empty, i.e. it contains no associations.
+<VAR>Wt-tree-type</VAR> is a weight balanced tree type obtained by calling
+<CODE>make-wt-tree-type</CODE>; the returned tree has this type.
+</DL>
+<P>
+
+<A NAME="IDX1066"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>singleton-wt-tree</B> <I>wt-tree-type key datum</I>
+<DD>This procedure creates and returns a newly allocated weight balanced
+tree. The tree contains a single association, that of <VAR>datum</VAR> with
+<VAR>key</VAR>. <VAR>Wt-tree-type</VAR> is a weight balanced tree type obtained
+by calling <CODE>make-wt-tree-type</CODE>; the returned tree has this type.
+</DL>
+<P>
+
+<A NAME="IDX1067"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>alist-&gt;wt-tree</B> <I>tree-type alist</I>
+<DD>Returns a newly allocated weight-balanced tree that contains the same
+associations as <VAR>alist</VAR>. This procedure is equivalent to:
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(lambda (type alist)
+ (let ((tree (make-wt-tree type)))
+ (for-each (lambda (association)
+ (wt-tree/add! tree
+ (car association)
+ (cdr association)))
+ alist)
+ tree))
+</pre></td></tr></table></DL>
+<P>
+
+<A NAME="Basic Operations on Weight-Balanced Trees"></A>
+<HR SIZE="6">
+<A NAME="SEC180"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC179"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC181"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC178"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 6.3.2 Basic Operations on Weight-Balanced Trees </H3>
+<!--docid::SEC180::-->
+<P>
+
+This section describes the basic tree operations on weight balanced
+trees. These operations are the usual tree operations for insertion,
+deletion and lookup, some predicates and a procedure for determining the
+number of associations in a tree.
+</P>
+<P>
+
+<A NAME="IDX1068"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/empty?</B> <I>wt-tree</I>
+<DD>Returns <CODE>#t</CODE> if <VAR>wt-tree</VAR> contains no associations, otherwise
+returns <CODE>#f</CODE>.
+</DL>
+<P>
+
+<A NAME="IDX1069"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/size</B> <I>wt-tree</I>
+<DD>Returns the number of associations in <VAR>wt-tree</VAR>, an exact
+non-negative integer. This operation takes constant time.
+</DL>
+<P>
+
+<A NAME="IDX1070"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/add</B> <I>wt-tree key datum</I>
+<DD>Returns a new tree containing all the associations in <VAR>wt-tree</VAR> and
+the association of <VAR>datum</VAR> with <VAR>key</VAR>. If <VAR>wt-tree</VAR> already
+had an association for <VAR>key</VAR>, the new association overrides the old.
+The average and worst-case times required by this operation are
+proportional to the logarithm of the number of associations in
+<VAR>wt-tree</VAR>.
+</DL>
+<P>
+
+<A NAME="IDX1071"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/add!</B> <I>wt-tree key datum</I>
+<DD>Associates <VAR>datum</VAR> with <VAR>key</VAR> in <VAR>wt-tree</VAR> and returns an
+unspecified value. If <VAR>wt-tree</VAR> already has an association for
+<VAR>key</VAR>, that association is replaced. The average and worst-case
+times required by this operation are proportional to the logarithm of
+the number of associations in <VAR>wt-tree</VAR>.
+</DL>
+<P>
+
+<A NAME="IDX1072"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/member?</B> <I>key wt-tree</I>
+<DD>Returns <CODE>#t</CODE> if <VAR>wt-tree</VAR> contains an association for
+<VAR>key</VAR>, otherwise returns <CODE>#f</CODE>. The average and worst-case
+times required by this operation are proportional to the logarithm of
+the number of associations in <VAR>wt-tree</VAR>.
+</DL>
+<P>
+
+<A NAME="IDX1073"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/lookup</B> <I>wt-tree key default</I>
+<DD>Returns the datum associated with <VAR>key</VAR> in <VAR>wt-tree</VAR>. If
+<VAR>wt-tree</VAR> doesn't contain an association for <VAR>key</VAR>,
+<VAR>default</VAR> is returned. The average and worst-case times required by
+this operation are proportional to the logarithm of the number of
+associations in <VAR>wt-tree</VAR>.
+</DL>
+<P>
+
+<A NAME="IDX1074"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/delete</B> <I>wt-tree key</I>
+<DD>Returns a new tree containing all the associations in <VAR>wt-tree</VAR>,
+except that if <VAR>wt-tree</VAR> contains an association for <VAR>key</VAR>, it
+is removed from the result. The average and worst-case times required
+by this operation are proportional to the logarithm of the number of
+associations in <VAR>wt-tree</VAR>.
+</DL>
+<P>
+
+<A NAME="IDX1075"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/delete!</B> <I>wt-tree key</I>
+<DD>If <VAR>wt-tree</VAR> contains an association for <VAR>key</VAR> the association
+is removed. Returns an unspecified value. The average and worst-case
+times required by this operation are proportional to the logarithm of
+the number of associations in <VAR>wt-tree</VAR>.
+</DL>
+<P>
+
+<A NAME="Advanced Operations on Weight-Balanced Trees"></A>
+<HR SIZE="6">
+<A NAME="SEC181"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC180"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC182"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC178"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 6.3.3 Advanced Operations on Weight-Balanced Trees </H3>
+<!--docid::SEC181::-->
+<P>
+
+In the following the <EM>size</EM> of a tree is the number of associations
+that the tree contains, and a <EM>smaller</EM> tree contains fewer
+associations.
+</P>
+<P>
+
+<A NAME="IDX1076"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/split&lt;</B> <I>wt-tree bound</I>
+<DD>Returns a new tree containing all and only the associations in
+<VAR>wt-tree</VAR> which have a key that is less than <VAR>bound</VAR> in the
+ordering relation of the tree type of <VAR>wt-tree</VAR>. The average and
+worst-case times required by this operation are proportional to the
+logarithm of the size of <VAR>wt-tree</VAR>.
+</DL>
+<P>
+
+<A NAME="IDX1077"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/split&gt;</B> <I>wt-tree bound</I>
+<DD>Returns a new tree containing all and only the associations in
+<VAR>wt-tree</VAR> which have a key that is greater than <VAR>bound</VAR> in the
+ordering relation of the tree type of <VAR>wt-tree</VAR>. The average and
+worst-case times required by this operation are proportional to the
+logarithm of size of <VAR>wt-tree</VAR>.
+</DL>
+<P>
+
+<A NAME="IDX1078"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/union</B> <I>wt-tree-1 wt-tree-2</I>
+<DD>Returns a new tree containing all the associations from both trees.
+This operation is asymmetric: when both trees have an association for
+the same key, the returned tree associates the datum from <VAR>wt-tree-2</VAR>
+with the key. Thus if the trees are viewed as discrete maps then
+<CODE>wt-tree/union</CODE> computes the map override of <VAR>wt-tree-1</VAR> by
+<VAR>wt-tree-2</VAR>. If the trees are viewed as sets the result is the set
+union of the arguments.
+The worst-case time required by this operation
+is proportional to the sum of the sizes of both trees.
+If the minimum key of one tree is greater than the maximum key of
+the other tree then the time required is at worst proportional to
+the logarithm of the size of the larger tree.
+</DL>
+<P>
+
+<A NAME="IDX1079"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/intersection</B> <I>wt-tree-1 wt-tree-2</I>
+<DD>Returns a new tree containing all and only those associations from
+<VAR>wt-tree-1</VAR> which have keys appearing as the key of an association
+in <VAR>wt-tree-2</VAR>. Thus the associated data in the result are those
+from <VAR>wt-tree-1</VAR>. If the trees are being used as sets the result is
+the set intersection of the arguments. As a discrete map operation,
+<CODE>wt-tree/intersection</CODE> computes the domain restriction of
+<VAR>wt-tree-1</VAR> to (the domain of) <VAR>wt-tree-2</VAR>.
+The time required by this operation is never worse that proportional to
+the sum of the sizes of the trees.
+</DL>
+<P>
+
+<A NAME="IDX1080"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/difference</B> <I>wt-tree-1 wt-tree-2</I>
+<DD>Returns a new tree containing all and only those associations from
+<VAR>wt-tree-1</VAR> which have keys that <EM>do not</EM> appear as the key of
+an association in <VAR>wt-tree-2</VAR>. If the trees are viewed as sets the
+result is the asymmetric set difference of the arguments. As a discrete
+map operation, it computes the domain restriction of <VAR>wt-tree-1</VAR> to
+the complement of (the domain of) <VAR>wt-tree-2</VAR>.
+The time required by this operation is never worse that proportional to
+the sum of the sizes of the trees.
+</DL>
+<P>
+
+<A NAME="IDX1081"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/subset?</B> <I>wt-tree-1 wt-tree-2</I>
+<DD>Returns <CODE>#t</CODE> iff the key of each association in <VAR>wt-tree-1</VAR> is
+the key of some association in <VAR>wt-tree-2</VAR>, otherwise returns <CODE>#f</CODE>.
+Viewed as a set operation, <CODE>wt-tree/subset?</CODE> is the improper subset
+predicate.
+A proper subset predicate can be constructed:
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(define (proper-subset? s1 s2)
+ (and (wt-tree/subset? s1 s2)
+ (&lt; (wt-tree/size s1) (wt-tree/size s2))))
+</pre></td></tr></table><P>
+
+As a discrete map operation, <CODE>wt-tree/subset?</CODE> is the subset
+test on the domain(s) of the map(s). In the worst-case the time
+required by this operation is proportional to the size of
+<VAR>wt-tree-1</VAR>.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX1082"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/set-equal?</B> <I>wt-tree-1 wt-tree-2</I>
+<DD>Returns <CODE>#t</CODE> iff for every association in <VAR>wt-tree-1</VAR> there is
+an association in <VAR>wt-tree-2</VAR> that has the same key, and <EM>vice
+versa</EM>.
+<P>
+
+Viewing the arguments as sets <CODE>wt-tree/set-equal?</CODE> is the set
+equality predicate. As a map operation it determines if two maps are
+defined on the same domain.
+</P>
+<P>
+
+This procedure is equivalent to
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(lambda (wt-tree-1 wt-tree-2)
+ (and (wt-tree/subset? wt-tree-1 wt-tree-2
+ (wt-tree/subset? wt-tree-2 wt-tree-1)))
+</pre></td></tr></table><P>
+
+In the worst-case the time required by this operation is proportional to
+the size of the smaller tree.
+</P>
+</DL>
+<P>
+
+<A NAME="IDX1083"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/fold</B> <I>combiner initial wt-tree</I>
+<DD>This procedure reduces <VAR>wt-tree</VAR> by combining all the associations,
+using an reverse in-order traversal, so the associations are visited in
+reverse order. <VAR>Combiner</VAR> is a procedure of three arguments: a key,
+a datum and the accumulated result so far. Provided <VAR>combiner</VAR>
+takes time bounded by a constant, <CODE>wt-tree/fold</CODE> takes time
+proportional to the size of <VAR>wt-tree</VAR>.
+<P>
+
+A sorted association list can be derived simply:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(wt-tree/fold (lambda (key datum list)
+ (cons (cons key datum) list))
+ '()
+ <VAR>wt-tree</VAR>))
+</pre></td></tr></table><P>
+
+The data in the associations can be summed like this:
+</P>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(wt-tree/fold (lambda (key datum sum) (+ sum datum))
+ 0
+ <VAR>wt-tree</VAR>)
+</pre></td></tr></table></DL>
+<P>
+
+<A NAME="IDX1084"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/for-each</B> <I>action wt-tree</I>
+<DD>This procedure traverses the tree in-order, applying <VAR>action</VAR> to
+each association.
+The associations are processed in increasing order of their keys.
+<VAR>Action</VAR> is a procedure of two arguments which take the key and
+datum respectively of the association.
+Provided <VAR>action</VAR> takes time bounded by a constant,
+<CODE>wt-tree/for-each</CODE> takes time proportional to in the size of
+<VAR>wt-tree</VAR>.
+The example prints the tree:
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(wt-tree/for-each (lambda (key value)
+ (display (list key value)))
+ <VAR>wt-tree</VAR>))
+</pre></td></tr></table></DL>
+<P>
+
+<A NAME="Indexing Operations on Weight-Balanced Trees"></A>
+<HR SIZE="6">
+<A NAME="SEC182"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC181"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC178"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 6.3.4 Indexing Operations on Weight-Balanced Trees </H3>
+<!--docid::SEC182::-->
+<P>
+
+Weight balanced trees support operations that view the tree as sorted
+sequence of associations. Elements of the sequence can be accessed by
+position, and the position of an element in the sequence can be
+determined, both in logarthmic time.
+</P>
+<P>
+
+<A NAME="IDX1085"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/index</B> <I>wt-tree index</I>
+<DD><A NAME="IDX1086"></A>
+<DT><U>procedure+:</U> <B>wt-tree/index-datum</B> <I>wt-tree index</I>
+<DD><A NAME="IDX1087"></A>
+<DT><U>procedure+:</U> <B>wt-tree/index-pair</B> <I>wt-tree index</I>
+<DD>Returns the 0-based <VAR>index</VAR>th association of <VAR>wt-tree</VAR> in the
+sorted sequence under the tree's ordering relation on the keys.
+<CODE>wt-tree/index</CODE> returns the <VAR>index</VAR>th key,
+<CODE>wt-tree/index-datum</CODE> returns the datum associated with the
+<VAR>index</VAR>th key and <CODE>wt-tree/index-pair</CODE> returns a new pair
+<CODE>(<VAR>key</VAR> . <VAR>datum</VAR>)</CODE> which is the <CODE>cons</CODE> of the
+<VAR>index</VAR>th key and its datum. The average and worst-case times
+required by this operation are proportional to the logarithm of the
+number of associations in the tree.
+<P>
+
+These operations signal an error if the tree is empty, if
+<VAR>index</VAR><CODE>&lt;0</CODE>, or if <VAR>index</VAR> is greater than or equal to the
+number of associations in the tree.
+</P>
+<P>
+
+Indexing can be used to find the median and maximum keys in the tree as
+follows:
+</P>
+</DL>
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>median: (wt-tree/index <VAR>wt-tree</VAR> (quotient (wt-tree/size <VAR>wt-tree</VAR>) 2))
+
+maximum: (wt-tree/index <VAR>wt-tree</VAR> (-1+ (wt-tree/size <VAR>wt-tree</VAR>)))
+</pre></td></tr></table><P>
+
+<A NAME="IDX1088"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/rank</B> <I>wt-tree key</I>
+<DD>Determines the 0-based position of <VAR>key</VAR> in the sorted sequence of
+the keys under the tree's ordering relation, or <CODE>#f</CODE> if the tree
+has no association with for <VAR>key</VAR>. This procedure returns either an
+exact non-negative integer or <CODE>#f</CODE>. The average and worst-case
+times required by this operation are proportional to the logarithm of
+the number of associations in the tree.
+</DL>
+<P>
+
+<A NAME="IDX1089"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/min</B> <I>wt-tree</I>
+<DD><A NAME="IDX1090"></A>
+<DT><U>procedure+:</U> <B>wt-tree/min-datum</B> <I>wt-tree</I>
+<DD><A NAME="IDX1091"></A>
+<DT><U>procedure+:</U> <B>wt-tree/min-pair</B> <I>wt-tree</I>
+<DD>Returns the association of <VAR>wt-tree</VAR> that has the least key under
+the tree's ordering relation. <CODE>wt-tree/min</CODE> returns the least key,
+<CODE>wt-tree/min-datum</CODE> returns the datum associated with the least key
+and <CODE>wt-tree/min-pair</CODE> returns a new pair <CODE>(key . datum)</CODE>
+which is the <CODE>cons</CODE> of the minimum key and its datum. The average
+and worst-case times required by this operation are proportional to the
+logarithm of the number of associations in the tree.
+<P>
+
+These operations signal an error if the tree is empty.
+They could be written
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(define (wt-tree/min tree) (wt-tree/index tree 0))
+(define (wt-tree/min-datum tree) (wt-tree/index-datum tree 0))
+(define (wt-tree/min-pair tree) (wt-tree/index-pair tree 0))
+</pre></td></tr></table></DL>
+<P>
+
+<A NAME="IDX1092"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/delete-min</B> <I>wt-tree</I>
+<DD>Returns a new tree containing all of the associations in <VAR>wt-tree</VAR>
+except the association with the least key under the <VAR>wt-tree</VAR>'s
+ordering relation. An error is signalled if the tree is empty. The
+average and worst-case times required by this operation are proportional
+to the logarithm of the number of associations in the tree. This
+operation is equivalent to
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(wt-tree/delete <VAR>wt-tree</VAR> (wt-tree/min <VAR>wt-tree</VAR>))
+</pre></td></tr></table></DL>
+<P>
+
+<A NAME="IDX1093"></A>
+</P>
+<DL>
+<DT><U>procedure+:</U> <B>wt-tree/delete-min!</B> <I>wt-tree</I>
+<DD>Removes the association with the least key under the <VAR>wt-tree</VAR>'s
+ordering relation. An error is signalled if the tree is empty. The
+average and worst-case times required by this operation are proportional
+to the logarithm of the number of associations in the tree. This
+operation is equivalent to
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>(wt-tree/delete! <VAR>wt-tree</VAR> (wt-tree/min <VAR>wt-tree</VAR>))
+</pre></td></tr></table></DL>
+<P>
+
+<A NAME="Other Packages"></A>
+<HR SIZE="6">
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<BR>
+<FONT SIZE="-1">
+This document was generated
+by <I>Steve Langasek</I> on <I>January, 10 2005</I>
+using <A HREF="http://texi2html.cvshome.org"><I>texi2html</I></A>
+</FONT>
+
+</BODY>
+</HTML>