Unfortunately, we have not yet had time to update "Hooking Your Solver
to AMPL" to explain facilities we added a few years ago for exchanging
suffixes with AMPL.  Use of these facilities from a user's perspective
are described in chapter 14 of the second edition of the AMPL book,
with older descriptions appearing in

	http://www.ampl.com/NEW/statuses.html
and
	http://www.ampl.com/NEW/suffixes.html

If your solver deals with a basis, it would be good if your driver
could accept an incoming basis and return an optimal basis.  The
process is fairly straightforward.  You declare

	 static SufDecl
	suftab[] = {
		{ "sstatus", 0, ASL_Sufkind_var, 1 },
		{ "sstatus", 0, ASL_Sufkind_con, 1 }
		};

Before calling the .nl reader, you invoke

	suf_declare(suftab, sizeof(suftab)/sizeof(SufDecl));

to tell the reader to save the incoming .sstatus values.  If you were
interested in other incoming or outgoing suffix values, you would also
include lines for them in suftab.  See, for example,
/netlib/ampl/solvers/cplex/cplex.c or /netlib/ampl/solvers/osl/osl.c .

To access an incoming suffix array (after calling the .nl reader,
which reads them), say an array of priorities on variables, declare

	SufDesc *dp;

and invoke

	dp = suf_get("priority", ASL_Sufkind_var);

suf_get returns a pointer to a SufDesc (which is declared in asl.h);
the second argument indicates the kind of entity to which the suffix
pertains:  variable, constraints, objective, or problem.

If you wanted to see integer values for the suffix, then dp->u.i is
the array of suffix values; otherwise dp->u.r is the array of (real)
suffix values.

To return .sstatus values (i.e., a basis), you call suf_iput
twice, once for constraint.sstatus and once for variable.sstatus.
It's probably simplest to proceed as in /netlib/ampl/solvers/minos/m55.c:
having declared

	int *varstat;
	SufDesc *csd, *vsd;

and having computed NB = M + N, where M >= n_con and N >= n_var are the
numbers of constraints and variables (possibly adjusted, depending on the
needs of your solver -- for example, some solvers require adding an
extra variable and possibly an extra constraint to add a constant term
to the objective values that they report if they're asked to print
progress lines during their solution process), you allocate storage
for the .sstatus values by (something equivalent to)

	varstat = (int*)M1alloc(NB*sizeof(int));
	vsd = suf_iput("sstatus", ASL_Sufkind_var, varstat);
	csd = suf_iput("sstatus", ASL_Sufkind_con, varstat + N);

before invoking the .nl reader.  After calling the reader, deal
appropriately with the incoming .sstatus values, if present:

	if (vsd->kind & ASL_Sufkind_input)

then you have incoming variable.sstatus values in array varstat
(the third argument to suf_iput); similarly,

	if (csd->kind & ASL_Sufkind_input)

then you have incoming constraint.sstatus values (which, in the
above example, are in varstat+N, though you might wish to give
a separate name to this array).  The values are encoded as in
the first column of AMPL's default $sstatus_table:

	0	none	no status assigned
	1	bas	basic
	2	sup	superbasic
	3	low	nonbasic <= (normally =) lower bound
	4	upp	nonbasic >= (normally =) upper bound
	5	equ	nonbasic at equal lower and upper bounds
	6	btw	nonbasic between bounds

After solving the problem and before calling write_sol (which will
transmit the suffix arrays mentioned in previous suf_iput and, for
real, i.e., double, values, suf_rput calls), translate your basis
information to values in the outgoing status arrays that accord with
the above table.

For returning real (floating-point) suffix values, call suf_rput
rather than suf_iput.  Examples (for sensitivity information, i.e.,
suffixes .up, .current, and .down) appear in the cplex.c and osl.c
files mentioned above.

Another detail not yet documented in "Hooking Your Solver..." is that
you should assign a solve_result_num value to indicate success,
failure, iteration limit, etc. before calling write_sol.  This is
an integer value in one of the ranges indicated by AMPL's default
$solve_result_table:

	0	solved
	100	solved?
	200	infeasible
	300	unbounded
	400	limit
	500	failure

For successful solves, solve_result_num should thus be an integer
in [0,99].  If the problem might be solved, but tolerances may have
been too tight to satisfy all stopping tests, assign an integer in
[100,199], etc. -- any value >= 500 indicates failure (such as
insufficient memory).  Then AMPL's symbolic solve_result will be
assigned one of the values in the second column of the above table,
and scripts that need more detail can base tests on solve_result_num.

Many of the sample solver interfaces appearing in subdirectories
of netlib's ampl/solvers directory make use of suffixes and supply
solve_result_num.
