Copyright (C) 2017 AMPL Optimization.  All Rights Reserved.

File TABLES.RME describes table declarations, the "read table" and
"write table" commands, and table handlers; it applies to AMPL
versions >= 20000209.  Student/demo versions of AMPL that work with
tables are available from the AMPL web site, https://ampl.com .  For
more details, including examples, see

	https://ampl.com/NEW/tables.html

Note that the current version of AMPL is available in option version
(i.e., $version) and in the builtin parameter _version.

File ampltabl.dll and its 64-bit variant, ampltabl_64.dll, provide a
"standard" ODBC table handler.  Files ampltabl.zip and ampltabl_64.zip
contain ampltabl.dll variants that work with Microsoft Windows; they
work with Microsoft Access, Microsoft Excel, and other "databases"
that are accessible via ODBC.  (Source for ampltabl.dll appears in
file amplodbc.c.  Compiled versions of ampltabl.dll for some other
platforms are available from the AMPL web site.)  For learning about
writing table handlers, amplodbc.c is not the best place to start.
Files simpbit.c and fullbit.c, discussed below, should be better
starting places.

The assignment "S = ../solvers" in the sample makefiles provides an
assumption that the parent directory ../solvers  is your "solvers"
directory, which contains some necessary header files.  This
assumption can be overridden by an explicit "S=..." when invoking
"make" or "nmake".

Table handlers are provided by the imported-function mechanism, which
is discussed briefly in the section on "User-defined functions" in
"Hooking Your Solver to AMPL", https://ampl.com/REFS/hooking2.pdf .

See also the platform-specific information in directory
/netlib/ampl/solvers/funclink, e.g.,

	https://ampl.com/netlib/ampl/solvers/funclink

While testing your handlers, you may find it helpful to use AMPL's
commands for loading and unloading shared libraries and removing
files, which are summarized below.

When it starts execution, AMPL tries to import functions and table
handlers from shared libraries named ampltabl.dll and amplfunc.dll.
By default, they are sought in the directory where the AMPL binary was
found and in the invocation directory, i.e., the directory that AMPL
finds current when it starts to run.  One can use AMPL's option
ampl_include to specify nondefault places to look.  Table handlers can
also come from libraries loaded explicitly with the "load" and
"reload" commands.

Two "instructive" examples of table handlers are provided here:

1. simpbit.c is source for simpbit.dll, a simplified form of
AMPL's builtin "bit" table handlers.

2. fullbit.c is source for fullbit.dll, which is equivalent to
AMPL's builtin "bit" and "tab" handlers.

To make it easier to show that simpbit.dll is working, it reads and
writes .bit and .abt files (i.e., files whose names end in .bit or
.abt).  Both have the same format.

The simplified table reader in simpbit.c does not permit column names
to be reordered, requires the table being read to have exactly the
number of columns specified in the AMPL table declaration, requires
the columns to be in the same order as in the declaration, and only
deals with the native binary format.  The reader in fullbit.c, on the
other hand, permits "extra" columns and permits the columns to be
permuted.  It also swaps bytes if necessary, so it can deal with both
little-endian and big-endian IEEE arithmetic numbers (on machines that
use IEEE arithmetic, i.e., most most machines these days).

The simplified table writer in simpbit.c makes no attempt to preserve
any rows or columns it is not writing.  The more complete writers in
fullbit.c do preserve rows and columns that they are not writing.
They do this by reading the old table and adjusting their TableInfo
structure.  Note how they use TI->Lookup while reading the old table.

For starters, it may be helpful to look at the .tab table writer in
fullbit.c, i.e., function Write_ampl_tab, since it is the simplest
example of a table writer.  Reading .tab files is rather more
elaborate, which is why .tab files are not included in simpbit.c.

Files with names ending in ".x" are example AMPL scripts that use
tables.  See the initial comments in the *.x files for details.

-----------------------------------------------
Command summary (load, unload, reload, remove):
-----------------------------------------------

Commands
	load	[libname [, libname ...] ];
	unload	[libname [, libname ...] ];
	reload	[libname [, libname ...] ];
load, unload, or reload shared libraries (from which functions and
table handlers are imported).  When at least one libname is mentioned
in the load and unload commands, $AMPLFUNC is modified to reflect the
full pathnames of the currently loaded libraries.  The reload command
first unloads its arguments, then loads them.  This can change the
order of loaded libraries and affect the visibility of imported
functions: the first name wins.  With no libname arguments, "load;"
loads all the libraries currently in $AMPLFUNC; "unload;" unloads
all currently loaded libraries, and "reload;" reloads them (which
might be useful if some have been recompiled).

To simplify using 32- and 64-bit versions of AMPL and solvers on the
same system, if the "load" does not find the specified library and its
name contains at least one period ("."), a 64-bit AMPL will will
change "_32" before the final period to "_64" or, if "_64" does not
appear there, will insert "_64" before the final period and in either
case will try to load the modified library name.  A 32-bit AMPL
operates similarly, but with _32 and _64 interchanged.  Solvers make
similar modifications.  This applies only to AMPL versions >= 20120126
and to solvers linked with versions >= 20120126 of the solver-
interface library.  A command-line invocation of a solver with just
"-v" for an argument should show ASL(yyyymmdd), where yyyymmdd is the
version of the solver-interface library.  For example, invoking

	knitro -v

might show

	AMPL/KNITRO 8.1.0 (Linux x86_32), driver(20121124), ASL(20121116)

which indicates use of version 20121116 of the solver-interface library.

  New and adjusted system sets:

	_LIBS = basenames of currently loaded libraries.  Note that $AMPLFUNC
			is automatically set to the full pathnames (one per
			line) of the currently loaded libraries.
	_AVAILFUNCS = currently available imported functions
			(which still must be declared before use).
	_AVAILFUNC2 = (available function, library) pairs
			(permits seeing which library is currently
			supplying an available imported function).
	_HANDLERS = currently available handlers.
	_SFUNCS = imported functions that "solve;" currently uses.

  New system symbolic parameters:

	_handler_desc{_HANDLERS}
		For each i in _HANDLERS, _handler_desc[i] is a description
		of the handler.
	_handler_lib{_HANDLERS}
		For each i in _HANDLERS, _handler_lib[i] is the basename
		of the library that provided i.
	_table_errmsg
		The error message from the most recent "read table" or
		"write table" command; if all went well, _table_errmsg
		is the null string, i.e., _table_errmsg == ''.

  Command
	remove [filename [, filename ...]];
closes and removes the files mentioned.  "remove;" does nothing.
Exception: "remove ($log_file);" just truncates (removes and
then reopens) $log_file, much as "close ($log_file);" does.

For example,

	display _HANDLERS;

might report

	set _HANDLERS := tab bit odbc tableproxy simple-bit;


in which case

	print _handler_desc['odbc'];

would tell about the odbc handler and

	print _handler_desc['tableproxy'];

would tell about the tableproxy handler.
