*** AMPL change log and recent bug fixes ***

Below is a summary of AMPL changes from 30 Nov. 1992,
including a summary of recent bug fixes.  For a much more complete
list of bug fixes, e obtain /netlib/ampl/fixlog, which is available
at various URLs, such as

	http://www.ampl.com/netlib/ampl/fixlog
	http://www.netlib.org/ampl/fixlog
	http://netlib.sandia.gov/ampl/fixlog.gz

Note that AMPL versions are strings of the form yyyymmdd, giving
the date (year = yyyy, month = mm, date = dd) of the last change
affecting the version.  You can determine the version of your
"ampl" program by issuing the AMPL command

	option version;

or by invoking ampl with the -vv option.  To see the version
without executing ampl further, use the invocation

	ampl -vvq

An up-to-date summary of AMPL changes and recent bug fixes is available
by electronic mail: send netlib@netlib.bell-labs.com the E-mail message

	send changes from ampl

Here is a summary of changes and recent bug repairs.  Each block of
changes is preceded by the version (yyyymmdd) in which the changes
first appeared.

19921218:
  Add initial version of "show" command:
	        "show;" or "show >filename;"
	lists all model entities.
	        "show name;" or "show name >filename;"
	shows name's declaration if it has one, or else
	lists model entities of the kind indicated by the
	first letters of name:
	        ch... ==> checks        c... ==> constraints
	        f...  ==> functions     o... ==> objectives
	        p...  ==> parameters    s... ==> sets
	        v...  ==> variables


19930208:
  Add new option relax_integrality:
	option relax_integrality 1;
causes "integer" and "binary" attributes of variables to be ignored
(in solve and write commands).

19930303:
  Variable.lb3, .ub3 withdrawn.
  Add logic and option constraint_drop_tol (default 0) to deal with
subtle presolve bug apparently caused by roundoff error:  with $presolve
> 1 and $var_bounds == 1 (the defaults), constraint bounds were very
occasionally relaxed due to bounds only conveyed for $var_bounds > 1;
this could increase the size of the feasible region, possibly making the
problem unbounded.  (Only known example:  test problem MAROS from
netlib's lp/data.)  The fix involves keeping two sets of constraint
bounds and switching between them based on $var_bounds.  The constraint
bounds for $var_bounds == 1 are only relaxed if roundoff poses no danger
or the deduced bounds on the constraint body are sharper than the
declared bounds by at least $constraint_drop_tol.  (The default
$constraint_drop_tol value 0 causes both sets of constraint bounds to be
the same and gives the same behavior as before this change.)  New
constraint dot values:  constraint.lbs1, .ubs1, lbs2, .ubs2 = versions
of .lbs, .ubs corresponding to $var_bounds <= 1 or > 1, respectively.
Constraint.lbs, .ubs still reflect the bounds sent to the solver.
  Delete warning about possibly incorrect dual values inferred for
constraints eliminated by presolve: the inferred dual values are
now believed to be correct in all cases.

19930315:
  Adjust presolve to use directed roundings on (some) IEEE-arithmetic
machines.  This sometimes leads to fewer surprises, such as an
unbounded objective under default conditions with netlib's "maros
from lp/data".

19930506:
  New command-line option -v2 merges stderr with stdout both for
ampl and for subprocesses (whereas -ve just merges them for ampl).
  Allow negative precision with %f, with formatting as for the
print command with $print_round < 0.

19930515:
  For entities with several subscripts, enforce the rule that literals
must be quoted in the model.  The first printing of thet AMPL book
(middle of p. 252) erroneously shows some unquoted literals, which the
AMPL translator should not have accepted.

19930615:
  Use stronger deduced variable bounds rather than declared variable
bounds in deciding whether an integer variable is binary.

19930208): option presolve 0 ignored integrality.
  Adjust .nl files to convey (in their first 10 lines) counts of
nonlinear integer variables and of nonlinear variables used in both
constraints and objectives (nlvb).  When nlvo > nlvc, arrange for
the first nlvb variables to be the nonlinear variables common to both
constraints and objectives (and the next nlvc - nlvb to be just in
constraints).  Adjust tables in "Hooking Your Solver to AMPL" to
describe the new ordering of nonlinear variables; Postscript for
this revised report is available by E-mail: ask
netlib@netlib.bell-labs.com to

	send 93-10 from research/nam

19930805:
  New option presolve_inteps (default 1e-6) gives tolerance for
rounding updated bounds on integer variables to integer values
during presolve:  if x.dlb and x.dub denote the new deduced lower
and upper bounds on x, then for $presolve_inteps < 1,
x.dlb :=  ceil(x.dlb - $presolve_inteps)  and
x.dub := floor(x.dub + $presolve_inteps).  For $presolve_inteps >= 1,
x.dlb := floor(x.dlb) and x.dub := ceil(x.dub).
  Adjust presolve complaints about impossible deduced bounds to
take $presolve_eps into account.

19930914:
  New dot notation variable.dual applies to defined variables and
gives the dual value for the defining equality constraint; this
gives the partial derivative of the Lagrangian function (objective
minus sum of duals times constraints) with respect to the defined
variable.  For other variables, variable.dual = 0.


19930928:
---------------
FLOW OF CONTROL
---------------
  Several new commands permit conditional execution of and
looping over lists of AMPL commands:

	if lexpr then cmd
	if lexpr then cmd else cmd	# else matches nearest
					# available if
	for opt_name indexing cmd	# dummies from indexing
					# may appear in cmd
	repeat opt_name opt_while { cmds } opt_while ;
	break opt_name ;
	continue opt_name ;

cmd is either a single command (ending with ;) or { cmds } .
cmds is a sequence of 0 or more commands .
lexpr is a logical expression.
opt_name is an optional loop name (which must be an unbound
before the syntactic start of the loop), which goes out of
scope after syntactic end of the loop.
opt_while clauses are optional.  If not null, opt_while
has the form

	while lexpr
or
	until lexpr

If the optional loop name is not specified, break and continue
apply to the immediately enclosing loop; otherwise they apply
to the named loop; break terminates the loop, and continue
causes its next iteration to begin (if permitted by the
optional initial and final opt_while clauses of a repeat loop,
or by the indexing of a for loop).

Loops and if-then-else structures are treasured up until syntactically
complete.  Because else clauses are optional, AMPL must look ahead one
token to check for their presence.  At the outermost level, one must
thus issue a null command (just a semicolon) or some other command or
declaration to execute an outermost else-less "if ...  then stmt".
(In this regard, end-of-file implies an implicit null statement.)

New options cmdprompt1 and cmdprompt2 (called prompt3 and prompt4
until 19930423) control prompting within the new flow-of-control
commands.

19931005:
  New options $abs_boundtol, $rel_boundtol, and $show_boundtol are
meant to help deduce correct dual values for constraints eliminated
by presolve when the solver uses an interior-point algorithm and
returns a solution with no bounds strictly holding.  All three new
options have default value 0, which gives the previous behavior.
Suppose for some variable x that the solver sees the bounds
lb <= x <= ub.  The lower-bound constraint lb <= x is considered
active (during reconstruction of dual values) if

	x <= lb
	or (x - lb < ub - x
		and x - lb <= max($abs_boundtol, |lb|*$rel_boundtol)),

and similarly for the simple upper-bound constraint (x <= ub).
Thus negative values of $abs_boundtol and $rel_boundtol behave
like 0.  The condition x - lb < ub - x ensures that x is closer
to lb than half-way between lb and ub, ensuring that AMPL picks the
more appropriate bound no matter how large $abs_boundtol and
$rel_boundtol are.
  New option $show_boundtol works similarly to $show_stats, except
that it delivers its messages when it is on (nonzero) and
another dual-value computation occurs or (like $show_stats)
when it is set to 1.  It reports changes to $abs_boundtol and
$rel_boundtol that would change the outcome of the dual computation,
and is silent if the values of $abs_boundtol and $rel_boundtol do
not matter.  [$show_boundtol was called $show_boundstats until
20 Dec. 1993.]
  Have option redirections affect printing for "option show_stats 1;"
and "option show_boundtol 1;".

19931029:
  Arrange for expressions involving primal and dual variable values
to be recomputed when those values change.  Example:
	set S := 1..6;
	var x;
	for{i in 2..4} {
		let x := i;
		display {j in S: j > x.val};
		}
formerly displayed the same set thrice; now each is distinct.
  Treat variable as variable.val, constraint as constraint.dual
in indexing expressions for "fix", "unfix", "drop", "restore".
  New syntax for fix and unfix commands: an optional := expr
may appear before the terminating semicolon, in which case the
expression is assigned to the variable being fixed or unfixed
(as though assigned by "let").
  New option ampl_include gives a white-space separated list of
directories in which to search for files in "include", "model",
and "data" commands.  In this list, a single period stands
for the current directory.  The default, '.' (a single period)
gives the same behavior as heretofore.  References to absolute
file names (starting with "/" or, for MSDOS, one of "/", "\", or
"x:", where x is any printing character) are not affected by
$ampl_include .

19931113:
  Add "exit" as synonym for "quit".
  Recognize file names that start with "./" as file names relative to
the current directory (and ignore $ampl_include for such file names).
  Arrange for all (?) expressions involving dot notation to be
recomputed when the "dot value" changes.  This involves adding
"system" parameters _Solution_Count and _Initial_Guess_Count that,
for debugging, may be referenced as params (but which may become
invisible later).
  New option presolve_intepsmax (default 1e-5).  The message
"Setting $presolve_inteps >= nnn might help" is suppressed if
nnn > $presolve_intepsmax.
  New option presolve_warnings (default 5) limits the number of warning
messages printed during presolve; subsequent warning messages are
suppressed, and the number of suppressed warnings (if positive) is
reported at the end of presolve.  When $presolve_warnings < |$eexit|
(as is true by default), a subsequent "Ignoring solve command
because presolve finds no feasible solution possible" may now appear
even when presolve finds at least |$eexit| causes for infeasibility.

19931123:
  New option log_file (default '').  If $log_file is not '', then all
lines read from stdin or written to stdout or stderr are copied to file
$log_file.

19931203:
  New option bad_subscripts: ampl now discards invalid subscripts
(read in a data section or assigned by "let"), and the accompanying
error message now shows at most $bad_subscripts (default 3) invalid
subscripts per entity (when there is more than one bad subscript).

19940303:
  Allow any option value that does not need to be quoted in a
data section to be unquoted in option commands.  Option values
have always been printed without quotes when quotes can be elided
in a data section, which made it impossible for $OPTIONS_INOUT to
restore a value like a.b (or just ".", the default value for
$ampl_include).  Side effect: numeric option values are no
longer rounded (to the shortest decimal string rounding to their
numerical value rounded to the machine's arithmetic).  For example,
previously

	option foo 00123, goo '00123', zoo 1.234567890123456789;
	option foo, goo, zoo;

printed

	option foo 123;
	option goo 00123;
	option zoo 1.2345678901234567;

and now it prints

	option foo 00123;
	option goo 00123;
	option zoo 1.234567890123456789;

19940317:
  Allow "let S := {};" for sets S of arbitrary arity.

19930423:
  Allow any UTF character beyond the 7-bit ASCII characters to appear
in names.
  New options dataprompt1 and dataprompt2 are analogous to prompt1
and prompt2, but for data mode; defaults 'ampl data:' and 'ampl data?'.
  Catch SIGINT ("break" or "del" key).  When received, terminate
reading all files except stdin, and abort compound commands.
Stop if a second SIGINT arrives before a successful read on stdin.

19940429:
  Abort compound commands when solve returns a nonzero status
(e.g., if the solver was stopped by a SIGINT).

19940506:
  Test whether variables fixed by the "fix" command lie within
$presolve_eps of their declared ranges.

19940512:
  Arrange that
	set A default {expr};
	...
	let A := A;
will keep A at its current value when the value of expr changes.  Before
A is assigned a value by let (or in a data section), the value of A will
change when expr changes value.

19940807:
  Abort compound commands when solve or write says "Ignoring ...".
  Rerun presolve after changes to $presolve_eps.
  Allow inconsistencies up to $presolve_eps in declared variable and
constraint lower and upper bounds.
  For inconsistent problems (detected by presolve), tell changes to
$presolve_eps that would make AMPL ignore the inconsistencies,
provided the larger $presolve_eps would be at most $presolve_epsmax
(a new option with default 0).  Report changes (below $presolve_epsmax)
to $presolve_eps that would affect presolve results with $show_stats
output.
  New options presolve_fixeps and presolve_fixepsmax (both with
default 0): if presolve finds or deduces lower and upper bounds on
a variable that differ by at most $presolve_fixeps, it fixes the
variable at the average of the bound values.  When changes below
$presolve_fixepsmax to $presolve_fixeps would affect presolve,
the $show_stats output reports these changes.  Presolve now behaves
as though $presolve_eps were max($presolve_eps, $presolve_fixeps):
when $presolve_eps < $presolve_fixeps, variable bounds declared or
deduced to be within $presolve_fixeps of each other in absolute
value result in the variable being fixed at the average of the bounds.

19941003:
  Instantiate the entire index set of a for loop before starting
execution of the loop, so the set of dummy indices for which the loop
body is executed will be unaffected by assignments in the loop body.
Example:
	set S default {1,2,3,4};
	for {i in S} let S := S union {i + 4};
	display S;	# used to give 1..5; now gives 1..8
	## The loop could be stated more efficiently:
	##	let S := S union setof{i in S} i+4;
  Allow write and solve commands to proceed if only error messages
about discarded subscripts appear.
  Disallow write and solve commands when presolve complains about
inconsistent bounds; at the second attempt, show the least value
of $presolve_eps that would allow the command to proceed.
  Apply $presolve_fixeps test to the declared bounds on each
variable; although the description of $presolve_fixeps suggested
that it should apply to the declared bounds, it did not.
  Change to behavior of "model filename" and "data filename", which
are now commands: AMPL returns to model mode at the end of the file
unless the file ends in the middle of data.
  Change to behavior of "data" and (hitherto undocumented) "commands"
commands: when they appear within a compound command (i.e.,
the body of a loop or the then or else part of an if command,
or simply in a sequence of commands enclosed in braces),
they are now executed when the flow of control reaches them,
instead of when the compound command is being read.  In this case,
if they do not specify a file, AMPL reads commands or data from the
current input file until it encounters either an "end" command or
the end of the current file.  New option insertprompt (default '<%d>'),
if nonnull, specifies an insert-prompt (in which %d is the current
insert level, i.e., nesting of "data" and "commands" commands
specifying files and appearing within a compound command) that
immediately precedes the usual prompt for input from stdin.
  New single-step mode, details of which may change:

	option single_step n;

where n is a positive integer, specifies that if the insert level
is at most n, AMPL should behave as though "commands -;" were inserted
before each command: it should read commands from stdin until "end" or
eof (control-D on Unix systems).  Some special commands may appear in
this mode:

	command		meaning

	step		execute the next command

	skip		skip the next command

	next		if the next command is an if-then-else
			or looping command, execute the entire
			compound command before stopping again
			(unless the compound command itself
			specifies "commands -;")

	cont		execute until the end of the end of all
			currently nested compound commands at the
			current insert level

  Allow "reset data" and "update data" commands to appear in
compound commands.
  New option solver_msg (default 0; called omit_solmsg until 19941007):
if set to 0, the solution message normally printed by the solve and
solution commands is suppressed.

19941028:
  Omit (for now) recognition of @ (which once upon a time was a
synonym for "cross" but now is reserved for future use).
  Adjust some insert-mode details; commands read by "include" or "model"
are now at insert-level 0.
  New "read" command with syntax similar to the print command, except
that the only simple or subscripted params, variables, and constraints
(dual values) can be read.  Optional input redirections are specified
by < filename or < 'quoted_file_name' (before the read command's
terminating semicolon).  If no redirection is specified, values are read
from the current input stream.  To read from stdin, specify <- .
Examples (reading from the current input steam):

	param p;
	read p;
	4.2
	display p;

	param ps symbolic;
	read ps;
	'some funny text\
	with a newline'
	display ps;

	param q{1..3};
	read{i in 1..3} q[i];
	1.1 2.2
	3.3 display q;

	param i;
	param j;
	param A{1..10,1..10};
	param n;
	read n,{1..n}(i,j,A[i,j]);
	3
	2 4 2.4
	3 5 3.5
	4 7 4.7
	display A;

19941127:
  Omit check for violation of declared bound constraints by variables
fixed with the "fix" command.
  Abort compound commands (and the reading of files other than stdin)
after "Ignoring solve command..." or "Ignoring write command...".

19950315:
  Provisional versions (subject to change as we gain experience and
get feedback) of several extensions are now available.

  New reserved word "all", used in "drop all;", "fix all;",
"restore all;", "unfix all;".

  Extension to "objective" command: "objective;" or
"objective >filename;" prints commands establishing the current drop
status of objectives.  In particular, if one had previously said
"objective foo[3];", "objective;" would print "objective foo[3];".

  Similarly, "drop;" or "drop >filename;" or "restore;" or
"restore > filename;" prints commands establishing the
current drop state of the constraints and objectives, and
"fix;" or "fix >filename;" or "unfix;" or "unfix >filename;"
prints commands establishing the current "fix" state
of the variables.  In these contexts, "drop" and "restore"
are interchangeable, as are "fix" and "unfix".

  New "problem" declaration/command has three functions:
declaring a new problem, making a previously declared problem
current, and printing the name of the current problem (in the form
of a problem command establishing the current problem).

	problem name optional_indexing optional_environ : itemlist ;

declares a new problem and specifies the variables, constraints,
and objectives that are in it.  Other variables appearing in the
specified constraints and objectives are fixed (but can be
unfixed by the "unfix" command).  The new problem becomes the
current problem.  Initially the current problem is "Initial".
The "itemlist" in a problem declaration is a comma-separated
list of possibly subscripted names of variables, constraints,
and objectives, each optionally preceded by an indexing, as in
{i in A} foo[i].  More generally, nested indexings similar to
those allowed in function calls may be specified, as in
	{i in A} (foo[i], goo[i], {(i,j) in B} zoo[i,j])

The command

	problem name;

makes name (a previously declared problem) current.  And

	problem;
or
	problem >filename;

prints the current problem name (as "problem name;").
Drop/restore and fix/unfix commands apply only to the
current problem.  Variable values, like params, are global;
just the fixed/unfixed status of a variable depends on the
problem.  Similarly, the drop/restore status of a constraint
depends on the problem (as do reduced costs).  The
current problem does not restrict the "let" command.

When a problem is declared, it can optionally specify an
environment associated with the problem: the optional_environ
phrase has the form

	environ envname

to specify that the problem's initial environment is envname.
Otherwise a new environment with the same name as the problem
is created, and it inherits the then current environment (set of
option values).  In option commands, unadorned (conventional)
option names refer to options in the current environment, and
the notation envname.opname refers to $opname in environment envname.
The new declaration

	environ envname optional_indexing;

declares a environment envname (or a set of environments,
subscripted by the indexing if specified).  If there is no indexing,
envname becomes the current environment for the current problem.

  New command

	environ optional_indexing envname := envname1;

where envname and envname1 are optionally subscripted environment names,
copies environment envname1 to envname.

  New "expand" command prints generated constraints and objectives
(much as the linrc program does):

	expand [indexing] itemlist [>filename];

The itemlist can assume the same forms allowed in problem declarations.
If it is empty, all non-dropped constraints and objectives are expanded.
The variant

	solexpand [indexing] itemlist [>filename];

shows how constraints and objectives appear to the solver.  It omits
constraints and variables eliminated by presolve unless they are
explicitly specified in the itemlist.

  Both the "expand" and "solexpand" commands permit variables to appear
in the itemlist; for each, the commands show the linear coefficients
of the variable in the relevant (non-dropped and, for solexpand,
not eliminated by presolve) constraints and objectives, and indicates
" + nonlinear" when the variable also participates nonlinearly in a
constraint or objective.

  New options expand_precision and expand_round control printing of
numbers by expand.  By default they are currently printed to 6
significant figures (option expand_precision 6).

  Change to function calling conventions: symbolic arguments were
formerly quoted (as though they were symbols in a data section);
now they are stripped of quotes and the \ before a newline.  Examples:

	print 'a b';

now prints

	a b

rather than

	'a b'

  New printf format %q prints with data-section quoting rules
(omit quotes if omitting them is allowed in a data section);
new printf format %Q always quotes strings.

  New concatenation operator & has precedence below all arithmetic
operators and performs string concatenation.  It accepts numeric
operands and converts them to full-precision decimal strings
(as though by printf format "%.g": recall that AMPL's "%.0g"
gives full precision, rather than behaving like "%.1g").

  Contexts (other than alias strings in declarations) that previously
required literal strings now also accept an expression in parentheses.

  Expressions in commands may involve operands of the form $value
(a $ followed by an environment name) and $environ.value (where
environ is the possibly subscripted and previously declared name of
an environment).  $values may not be used in declarations.

  New builtin functions involved with strings:

	num('12.34') = 12.34	# convert string to number
	num('12.34x') = error	# complain if stripping leading and
				# trailing white space doesn't yield
				# a valid decimal number
	num0('12.34x') = 12.34	# strip leading white space, and
				# interpret as much as possible as
				# a number, but never complain
	ichar('A') = 65		# Unicode value of the first character
				# in its argument string
	char(65) = 'A'		# inverse of ichar
	length('abcd') = 4	# length of string
	substr('abcdef',3,2) = 'cd'	# substring
	substr('abcdef',3) = 'cdef'	# substring
	sprintf("stuff %.2f blah %g Blah %.g", 13/3, 2/7, 3/11)
		= 'stuff 4.33 blah 0.285714 Blah 0.2727272727272727'
				# general formatted conversion to string
	match('abcde','cd') = 3 # starting position of arg2 in arg1
	match('abcde','xy') = 0	# or 0 if not found; arg2 can be a general
				# regular expression
	sub('abcdecd','cd','XYZ') = 'abXYZecd'
				# substitute arg3 for the first occurrence
				# of arg2 in arg1
	gsub('abcdecd','cd','XYZ') = 'abXYZeXYZ'
				# substitute arg3 for all occurrences of
				# of arg2 in arg1
	arity('S') = arity of S if S is a set; else 0
				# for use with _SETS, as in
				# display{s in _SETS} arith(s);

  There is no implicit conversion of strings to numbers, but new
builtin functions num(string) and num0(string) perform explicit
conversions.  Both ignore leading and trailing white space; num
complains if what remains is not a valid number, whereas num0 just
converts as much as it can (returning 0 if it sees no digits).

The expressions
		'abc' & x+3
and
		'abc' & sprintf("%.g",x+3)

yield the same strings.  Now, e.g.,

	setof{i in 1..3} 'ABC' & i = {'ABC1', 'ABC2', 'ABC3'}.

The match, sub, and gsub functions accept strings representing
regular expressions as their second arguments.  Such expressions
are as in plan 9.  They are similar to the regular expressions
recognized by the Unix editors ed and sed, except that parentheses
as operators must not be escaped, and, in addition to * for 0 or
more occurrences of the preceding item, + means 1 or more occurrences,
and ? means 0 or 1 occurrence.  The replacement patterns (third
arguments) for sub and gsub are like those for ed and sed: & stands
for the whole matched string, as does \0, and \1, \2, ... \9 stand
for the string matched by the first, second, ..., ninth parenthesized
expression in the pattern.

  New "cd" command reports or changes the current working directory.

  New automatically updated params

	_nvars = number of variables in current model
	_ncons = number of constraints in  "	  "
	_nobjs = number of objectives in   "	  "
	_varname{1.._nvars} = names of variables in current model
	_conname{1.._ncons} =   "   "	    "	   "	"	"
	_objname{1.._nobjs} =   "   "	    "	   "	"	"

and synonyms for current model entities:

	_var{1.._nvars} = synonyms for variables   in current model
	_con{1.._ncons} =     "	    "  constraints  "	"	"
	_obj{1.._nobjs} =     "	    "  objectives   "	"	"

These synonyms can be used in display and other commands.  They
present the modeler's view (before presolve).  Similarly automatically
updated entities with _ changed to _s (i.e., _snvars, _svarnames,
_svar, etc.) give the solver's view, i.e., the view after presolve.

  New automatically updated sets:

	_PARS	= set of all declared param names
	_SETS	=  "   "   "	"     set      "
	_VARS	=  "   "   "	"     variable "
	_CONS	=  "   "   "	"     constraint names
	_OBJS	=  "   "   "	"     objective    "
	_PROBS	=  "   "   "	"     problem	   "
	_ENVS	=  "   "   "	"     environment  "
	_FUNCS	=  "   "   "	"     (user-defined) functions

These sets may appear in commands, such as display and print.

  New additions to the reserved-word list: Current, Initial, all,
environ, option.  The other new names appearing above may be declared
to be something else.

19950412:
  Enforce the restriction that $values and synonyms (such as _VARS
and _nvars) may not appear in declarations.
  Abort reading commands from files other than stdin after
detecting an error.
  WATCOM binaries are now compiled to circumvent the Pentium divide bug.
  Preliminary implementations of xref, delete, purge, and redeclare:
  New command xref shows entities that depend directly or indirectly
on specified entities.  Syntax:
	xref itemlist optional_redirection;
  New command
	delete foo;
deletes foo, restoring any previous meaning foo had, provided no other
entities depend on foo, i.e., if "xref foo;" reports no dependents.
  New command
	purge foo;
deletes foo and all its (direct or indirect) dependents.
  New form of declaration: "redeclare" followed by an ordinary
redeclaration replaces any existing declaration of the specified
entity with the given one, provided either that the entity has no
dependents, or that the new declaration does not change the character
of the entity (its kind, such as set or param, and its number of
subscripts).  Redeclarations that would cause circular dependencies
are rejected.
  New symbolic system parameter solve_message is assigned the message
shown (when not suppressed by "option solver_msg 0;") by the solve
and solution commands.  One can assign solve_message with "let", but
may not delete or redeclare it.
  New variants of break:
	break commands;
	break all;
terminate, respectively, the current commands command or all commands
commands, if any, and otherwise act as a "quit" command.

19950416:
  Extend $solver_auxfiles interpretation: capital letters have no
affect on linear problems, but on nonlinear problems (including
problems with binary or integer variables) are treated the same as
their lower-case equivalents.  The default $minos_auxfiles is now RF
rather than rf, causing .row and .fix files to be written only for
nonlinear problems.

19950501:
  New function
	indexarity('foo')
gives the arity of foo's index set if foo has been declared to be
something indexed, or 0 if foo has been declared as something that
is not indexed, or -1 if foo has not been declared.  Example:
	display{i in _PARS} indexarity(i);

19950517:
  Check statements are now only enforced during solve, write, and
solution commands, or when the new command
	check;
is executed.
  Dot notations that require presolve are now excluded from
declarations.

19950521:
  New variant of close command:
	close;
closes all files opened by redirections.

19950614
  Arrange for option funcwarn only to affect constraint and objective
declarations.  Thus it no longer affects
	function zot;
	param p := zot(3); # used to get msg about variable in :=
	display p;	   # now elicits msg about zot missing
  Change in writing of auxiliary .fix file: values of variables
fixed by presolve are suppressed unless $auxfiles or
$($solver & '_auxfiles') contains "v".  (The primary reason use
of the .fix file is now to convey names of defined variables
for use in printing error messages.  This change omits sometimes
lengthy work that is hardly ever useful.)
  Warn of missing subscripts on sets.  (Later we hope to warn about
other missing subscripts, but that's harder.)

19950619
  Introduce variant _display of the display command; _display is meant
for possible use by front ends.  Like the display command, _display
emits one or more tables, but _display replaces display's table
header with a line consisting of "_display" and three integers:
	s = number of subscripts of each item in each table line
	k = number of items on each table line
	n = number of table lines
Each table line consists of s subscripts followed by k items,
all separated by commas.  No semicolon is appended to the table.

19950720
  Add another variant of the display command: csvdisplay is similar to
_display, except that it only writes one table (complaining if asked
to write more than one), and it replaces the initial _display output
that describes the following table with $1,$2,...,$n  (where n is the
number of items in one line of the table that follows).  New options
csvdisplay_precision and csvdisplay_round govern the precision of
printing for csvdisplay; the defaults  (0 and '') give full precision.

19950726
  Adjust _display's printing so numeric precision is governed by
$csvdisplay_precision and $csvdisplay_round.
  In -M output and printing by the show command, insert "s.t. "
before constraints.
  New option csvdisplay_header (default 1): if nonzero, cvsdisplay's
first line now has the form
	Index_1,Index_2,...,Index_k,Expr_1,...,Expr_n
(where k is the number of subscripts and n the number of
expressions in one line of the table that follows); if the jth
expression is a simple name (not of the form Index_i or Expr_i)
that has not appeared previously in the current csvdisplay header
line, then that name appears rather than "Expr_j".  If
$csvdisplay_header is 0, this header line is omitted.
  Adjust line breaking for "show" and omit some extraneous commas.
  Diagnose some more undefined names (e.g., in problem declarations).
  Recognize repetition counts in
	next nnn
	skip nnn
	step nnn

19950810
  Allow the print command to have no arguments, which causes
it to behave the same as
	printf "\n";

19950827
  New debugging option: $debug_stub, if not '' (its default value),
is used to construct stubs of the form ($debug_stub & '_1'),
($debug_stub & '_2'), ... in solve commands.  If a file named
($debug_stub & '_1.sol'), ($debug_stub & '_2.sol'), etc. exists,
"solve" behaves as "solution" and reads the .sol file.  Otherwise it
leaves behind its .nl and .sol files, so a subsequent ampl run can
read the .sol files (and the .nl files are available for debugging
purposes).  This permits recreating some situations without rerunning
the solvers involved.  The .nl files (and hence .sol) files are ASCII
files to make it easy to create them on one kind of machine and use
them on another.

19951009
  New command:
	reset function;
closes all pipe functions and unlinks all dynamically linked functions,
causing them to be restarted or relinked if invoked again.  For
a specific function foo,
	reset data foo;
acts just on function foo.
  New command:
	delete check n;
deletes the n-th check.
  Extension of redeclare syntax:
	redeclare check n optional_indexing : ...;
redeclares the n-th check.
  New addition to reserved-word list: dotname (for use in a forthcoming
extension).

19951020
  Allow "reset data p;" even when p is declared with a := expression,
to force recomputation of random functions in the := expression (and
to force reevaluation of any user-defined functions in the expression).
Extend "reset data;" to force recomputation of all := expressions.

19951027
  Now problems (including the current one) should be adjusted when
their indexing expressions change, except that previous explicit drop,
restore, fix, and unfix commands remain in effect.  The new
"reset problem" command cancels this treatment of previous explicit
drop, restore, fix, and unfix commands, and brings the problem to its
declared drop/fix state.  This command has the forms

	reset problem;		# applies to the current problem
	reset problem foo;
	reset problem goo[subscripting];

If the latter forms mention the current problem, they have the same
effect as the first form.  For now, at least, "reset problem"
does not affect the problem's environment.

19951202
  Arrange for
	option relax_integrality 2;
to assume integrality during presolve, but tell the solver that there
are no integer variables.  Force presolve to run again after
$relax_integrality has changed.
  Increase default value of $pl_bigM from 1e4 to 1e6.  Arrange for
changes to $pl_bigM to cause presolve to run again when its results
would be affected by the change to $pl_bigM.

19951204
  Arrange to run presolve (when nothing else has caused it to run) so
defined variables involved in dropped objectives or constraints appear
to have the "right" values.  Example:
	var x := 2;
	var y = x^2 + 1;
	minimize zot: y + 10;
	drop zot;
	print zot;	# used to print 11 rather than 15
  Disallow declarations involving defined_variable.val.  (Instead,
declare a new param, use the param in the declaration, and use "let"
to give it the right value.  This helps clarify when things are to be
evaluated.)

19960202
  Adjust DOS .exe files to print nonzero return codes from solve
and shell commands.

19960306
  Allow printf's "+" flag to reveal the sign of 0.

19960313
  Arrange for redeclarations of variables, constraints, and objectives
to retain current values and drop/fix status.

19960330
  New call command for directly invoking user-defined functions
for their side effects: rather than, e.g., saying "print foo(1,2,3);"
or "let Dummy := foo(1,2,3);" to force foo(1,2,3) to be called, you
can now say "call foo(1,2,3);".  Syntax:
	call [indexing] function [(arglist)];

19960418
  Terminate includes within the file in a read command's "<" redirection
when the read command ends.

19960425
  Adjust xref command so it does not show nodes cited in arc
declarations.  Make it possible to delete and purge arcs.

19960606
  Adjust option debug_stub to honor (and retain) ($solver)_auxfiles.
  Pretend a semicolon appears at the end of command files that end with
a compound command with optional final parts missing:
	repeat ...  { ... }	# no final condition or semicolon
	if ... then { ... } 	# no else clause

19960627
  New option (for debugging nonlinear models): option nl_permute
(default 3) tells whether to permute constraints and variables as
described in "Hooking Your Solver to AMPL".  The value, mod 4, tells
what to permute:
		0	nothing
		1	just constraints
		2	just variables
		3	both constraints and variables

Note that some solvers, such as cplex, minos, and osl, require the
permutations.

19960709
  Prevent execution of problem commands from running presolve (and thus
possibly giving an erroneous message about inconsistent constraints).

19960729
  Disallow writing MPS files for problems with nonlinear variables.
  Omit INITIAL bounds from .mps files; they were only needed long ago
by minos.
  New builtin functions: time() returns the current time (in seconds
since 00:00:00 1 Jan. 1970 GMT); ctime() returns a 24-character string
representing the current time, and ctime(t) returns a similar time
representing time t (or the current time, if t is not numeric).

19960816
  New predefined param _pid gives the process ID of the AMPL process
(a number unique among processes running on the system).
  New option format_range_errmsg, if not '', replaces %i, %d, %o, %u,
%x, or %X in printf commands or sprintf invocations in which the
number to be converted is outside the appropriate range of integers.
If $format_range_errmsg has its default value of '', an error message
appears and the command is aborted.
  New automatically determined set:
	_AVAILFUNCS = user-defined functions that have been linked
(statically or dynamically) with AMPL and thus can be declared and
evaluated in the AMPL session.  (Other user-defined functions may be
declared and used in constraints and objectives, but AMPL will not
be able to evaluate them.  It can, however, pass them by name to
solvers that know how to evaluate them.)
  New automatically updated params give some problem statistics
the solver sees:
	_snbvars  = number of binary variables used linearly
	_snivars  = number of general integer variables used linearly
	_snnlcons = number of nonlinear constraints
	_snnlobjs = number of nonlinear objectives
	_snzcons  = number of nonzeros in the constraint Jacobian matrix
	_snzobjs  = number of nonzeros in objective gradients

19960829
  Add "inout" and "out" to the reserved-word list (for use in upcoming
extensions).

19961017
  New option show_write_files controls whether the write command
reports the names of the files it writes:
	0 ==> no (default)
	1 ==> yes for "write;", no for "write gstub;"
	2 ==> yes

19961210
  Adjust most commands (but not declarations) to permit unqualified
objective, constraint, and variable names in () expressions.  Hitherto
one had to use objective.val, constraint.dual, and variable.val.  Now
one can write something like
	option cplex_options (sprintf('... uppercutoff=%.f ',_obj[1]));
(rather than _obj[1].val) to adjust an option to reflect an objective
value from the most recent solve.
  Disallow expressions involving variables in arguments to member, ord,
ord0, next, nextw, prev, and prevw, when they appear in constraint and
objective declarations.

19970307
  Arrange for variable values of 0 assigned by "let" to be explicitly
conveyed to solvers unless $reset_initial_guesses is nonzero.
Previously they were explicitly conveyed only after a solve, or if
they were given in a data section or variable declaration.

19970314
  Arrange for "option gentimes 2" to show total memory rather than
incremental memory.
  Tweak -T output so "genmod times" lines (other than headers) always
start with "## ".  This was hitherto only true for seq numbers <= 99.

19970528
  Extension to expand command: recognize synonyms (possibly subscripted
_con, _obj, _var, _scon, _sobj, _svar).

19970615
  Adjust the tests involving $pl_bigM (done when linearizing nonconvex
piecewise-linear terms) to assume a lower bound of
		(smallest breakpoint) - $pl_bigM
and upper bound of
		(biggest breakpoint)  + $pl_bigM
on the variable "multiplied" by a piecewise-linear coefficient when
the true bounds on the variable exceed these values (instead of just
when the true bounds are infinite).

19970729
  Fix bug with random functions that caused some expressions involving
them not to be reevaluated.  Example:
	set S default {};
	repeat { let S := S union {Uniform(0,15)}; } while(card(S)) < 5;
looped infinitely.
  Change exit to a command of the form
	exit ;
or
	exit expression ;
The expression, if given, must be numeric and specifies the process
return code; an omitted expression is treated as 0.
  Change "quit;" to be equivalent to "exit <oldrc>;", which means it may
now appear in compound commands.  Here, <oldrc> stands for the return
code that "quit" has always given, which reflects recent syntax errors
(and is cleared to 0 by successful command executions).
  Fix some bugs with "break commands;" and "break all;"; adjust these
commands so if no "commands" command is being executed, they terminate
the current nest of includes, if any, and otherwise are no-ops.

19970731
  Fix bug in presolve for problems with integer (or binary) variables:
for $presolve > 1, if a constraint with two remaining nonzeros caused
an integer variable to be fixed and the constraint had previously
implied a bound on the other variable, that bound was not conveyed
to the solver.  (Note that $presolve is 10 by default; specifying
"option presolve 1;" avoids the bug.)
  Add a Caution for writing an MPS file for problems with integer
variables having infinite bounds.  There's no "standard" MPS way to
express such problems.

19970814
  With invocations with -o (and no commands that would cause the -o
command-line option to be ignored), if presolve fixes all variables,
say so and give process return code 16 rather than 0.
  New command-line option -R (recognized only as the first command-line
option and not mentioned in the "-?" listing of options) puts AMPL into
"server mode", in which it declines to execute cd and shell commands,
forbids changes to options TMPDIR, ampl_include, and PATH (or whatever
is the usual name of the search path for the operating system being
used), disallows pipe functions, and restricts names in option solver
and file redirections to be alphanumeric (so they can only write to the
current directory, which, on Unix systems at least, cannot be changed).
By invoking ampl from a shell script that suitably adjusts the current
directory and environment variables TMPDIR, ampl_include, and PATH
before it invokes "ampl -R", one can control the environment in which
"ampl -R" operates.

19980127
  New syntax for expressing complementarity constraints: in addition
to previous forms, constraint declarations may now have the form
	constraint_start : constr1 complements constr2 ;
in which constr1 and constr2 consist of 1, 2, or 3 expressions
separated by the operators <=, >=, or == (or =).  As with other
constraint declarations, constraint_start gives a name to the
constraint, an optional descriptive string (alias), and, if the
declaration describes a collection of constraints, an indexing
expression.  In constr1 and constr2 together, there must be a total
of two explicit inequality operators, with == counting as two.  A
complementarity constraint is satisfied if both constr1 and constr2
hold and at least one inequality is tight, i.e., satisfied as an
equality.  If one of constr1 or constr2 involves two inequalities,
then the constraint must have one of the forms
	expr1 <= expr2 <= expr3 complements expr4
	expr3 >= expr2 >= expr1 complements expr4
	expr4 complements expr1 <= expr2 <= expr3
	expr4 complements expr3 >= expr2 >= expr1
In all of these cases, the constraint requires the inequalities to
hold, with
	expr4 >= 0 if expr1 == expr2
	expr4 <= 0 if expr2 == expr3
	expr4 == 0 if expr1 < expr2 < expr3
  For expressing MPECs (math. programs with equilibrium constraints),
complementarity constraints may coexist with other constraints and
objectives.
  The suffix notations, such as constraint.lb, constraint.body, etc.,
are extended so that for a complementarity constraint,
constraint.Lsuffix and constraint.Rsuffix correspond to constr1.suffix
and constr2.suffix, respectively, and complementarity_constraint.slack
(or the unadorned name) stands for a measure of the extent to which
the complementarity constraint is satisfied: if constr1 and constr2
each involves one inequality, then the new measure is min(constr1.slack,
constr2.slack) (which is positive if both are strictly satisfied,
0 if the complementarity constraint is satisfied exactly, and negative
if at least one of constr1 or constr2 is violated).  For constraints of
the form expr1 <= expr2 <= expr3 complements expr4, the .slack value is
	min(expr1-expr2,  expr4) if expr1 >= expr2
	min(expr2-expr3, -expr4) if expr3 <= expr2
	-abs(expr4)		 if expr1 < expr2 < expr3
so in all cases, the .slack value is 0 if the complementarity constraint
holds exactly and is negative if one of the requisite inequalities
is violated.
  Solvers see complementarity constraints in the standard form
	expr complements lb <= variable <= ub
A new synonym, _scvar{i in 1.._sncons}, indicates which variable, if
any, complements constraint _scon[i]: if _scvar[i] in 1.._snvars, then
variable _svar[_scvar[i]] complements constraint _scon[i]; otherwise
_scvar[i] == 0, and _con[i] is an ordinary constraint.  Other new
synonyms: _cconname{1.._nccons} are the names of the complementarity
constraints as the modeler sees them.
  A forthcoming paper ("Expressing Complementarity Problems in an
Algebraic Modeling Language and Communicating Them to Solvers", by
Michael C. Ferris, Robert Fourer, and David M. Gay) discusses the new
complementarity syntax.  The paper will be available from the AMPL web
site (http://www.ampl.com/ampl/) after it has gone through the Bell Labs
release process.
  Anticipating extensions to be described later, the following words
	IN
	INOUT
	LOCAL
	OUT
	suffix
are now reserved.  This breaks the blend.mod and blend.dat distributed
with the AMPL book, in which it's necessary to change OUT to Out and
IN to In.

19980128
  Introduce some new automatically updated params that give information
about the current problem, either as seen by the modeler (_nccons), or by
the solver (names that start with "_s"):
	Name		Meaning
	_nccons		No. of complementarity constraints before presolve
	_snbvars	No. of binary (0,1) variables
	_snccons	No. of complementarity constraints after presolve
	_snivars	No. of  general integer variables (excluding binaries)
	_snlcc		No. of linear complementarity constraints
	_snlnc		No. of linear network constraints
	_snnlcc		No. of nonlinear compl. constrs.:
				_snccons = _snlcc + _snnlcc
	_snnlcons	No. of nonlinear constraints
	_snnlnc		No. of nonlinear network constraints
	_snnlobjs	No. of nonlinear objectives
	_snnlv		No. of nonlinear variables
	_snzcons	No. of constraint Jacobian matrix nonzeros
	_snzobjs	No. of objective gradient nonzeros

19980208
  New builtin suffixes: variable.defeqn is the subscript of _con for
the corresponding defining constraint if the variable is a defined
variable, and is 0 otherwise.  Similarly, constraint.defvar is the
subscript of _var for the resulting defined variable if the constraint
defines a defined variable (either through the var = syntax or because
of option substout), and is 0 otherwise.
  New options log_model and log_data (default 0): if option log_file
is not '', declarations and commands in included files are copied to
$log_file if $log_model is 1, and included data sections are copied
to $log_file if $log_data is 1.
  Edit change description of 19950619 above to describe _display.
For convenience, here is a summary of _display and csvdisplay.
  Commands _display and csvdisplay are variants of display that emit
tables in a more regular format than does display:  each line of a
table starts with s subscripts and ends with k items, all separated
by commas.  _display and csvdisplay differ in the table headers they
emit.  The header for _display consists of a line starting with
"_display" and followed by three integers s, k, and n (the number of
table lines that follow the header), each preceded by a space.  Whether
csvdisplay emits a header is determined by option csvdisplay_header
(default 1): if $csvdisplay_header is 1, cvsdisplay's first line has
the form
	Index_1,Index_2,...,Index_k,Expr_1,...,Expr_n
(where k is the number of subscripts and n the number of
expressions in one line of the table that follows); if the jth
expression is a simple name (not of the form Index_i or Expr_i)
that has not appeared previously in the current csvdisplay header
line, then that name appears rather than "Expr_j".  If
$csvdisplay_header is 0, this header line is omitted.
  Options csvdisplay_precision and csvdisplay_round govern the
precision of printing for _display and csvdisplay; the defaults
(0 and '') give full precision.

19980302
  Introduce (on all systems other than AIX and MSDOS, but including W95
and NT) a new scheme for acquiring imported functions: execute ampl -i?
for more details.  More extensive documentation will appear later.

19980309
  Change to option pl_linearize: the default value (1) now uses a
more efficient linearization of nonconvex (resp. nonconcave)
piecewise-linear terms and uses suffixes .sos and .sosref to
tell solvers that handle SOS sets about the variables and constraints
that imply the SOS2 constraints introduced by the linearization.
A forthcoming update to the AMPL/solver interface library will
provide sample interfaces that exploit this new information.
To get the old behavior, specify
	option pl_linearize 2;
Versions 19980305 and 19980308 had glitches in this change.

19980325
  New options
	shell_exitcode_max (default 2^16)
	solve_exitcode_max (default 0)
cause compound commands to be aborted if a shell command results in
$shell_exitcode > $shell_exitcode_max or a solve command results in
$solve_exitcode > $solve_exitcode_max .  The defaults give the old
behavior (except for the unlikely case of shell_exitcode > 2^16).

19980408
  Remove prohibition on "reset data" and "update data" commands
appearing in compound commands.

19980525
  When "solve;" fails, set solve_result = '?', solve_result_num = -1,
and solve_message = '?'.

19980605
  Recognize _obj.astatus, _sobj.statsus, _obj.astatus_num, and
_sobj.astatus_num.  The latter two are always 0 (in the problem), the
former two "in" unless $astatus_table has been changed from its default
value.

19980615
  Permit potential defining constraints (other than those introduced by
"var ... = ..." declarations) to participate in the strong bound
deductions attempted when $presolve > 1, unless $substout mod 4 == 2.
Previously, if there were any "var ... = ... " declarations or
$substout was nonzero, potential defining constraints were excluded
from the strong bound deductions.  Specifying "option substout 2" gives
the old behavior of "option substout 0", and "option substout 3" gives
the old behavior of "option substout 1".  The new $substout values 2 and
3 are for possible debugging and their effect may be withdrawn later;
values 0 and 1 are the only ones that should normally be of interest.
  Adjust logic for checking conditions on sets and parameters: when
"update data" and "let" provide new subscripts or modify existing
values, just check the new or changed items.  This changes the time
for some loops from quadratic in the number of iterations to linear.
If reports of failed conditions are interrupted by $eexit, the list
of questionable subscripts is currently not purged.  Otherwise each
new value causes only one warning if it fails a condition.

19980625
  New builtin param _cmdno is 0 initially (or after reset) and is
incremented each time a command is executed.
  New option project_fixed_vars (default 1): if nonzero, presolve
projects fixed variables onto their bounds (even if $presolve is 0).
If $project_fixed_vars == 2, a message is printed for each fixed
variable that is projected (until $presolve_warnings such messages
have appeared).
  It is possible for a variable to appear only in constraints that
imply bounds on the variable.  When $presolve > 0, such constraints
are eliminated.  Presolve now projects such variables onto the interval
given by their tightest deduced bounds.  Here is an example illustrating
this and the new option project_fixed_vars:
	var x >= 3 <= 3 := 4;
	var y >= 0 := 7;
	s.t. foo: x + y <= 3.5;
	display y;
	fix x;
	solexpand;
	display y;

Previously, this example gave the output

	y = 7

	presolve, variable y:
		impossible deduced bounds: lower = 0, upper = -0.5
	Infeasible constraints determined by presolve.
	s.t. foo:
		 <= -0.5;

	y = 7

The message about infeasibility appeared because "fix x" fixed x at 4,
which made constraint foo impossible to satisfy.  Now the example gives

	y = 7

	Solution determined by presolve.
	y = 0.5

Notice that y has been projected onto the interval [0,.5] implied by
constraint foo with x == 3.

19980714
  Upon encountering end-of-file after at least one variable declaration
but no objective or constraint declarations, print "No variables used"
rather than "No variables declared".

19980717
  Do not terminate compound commands when a command, such as solve,
incurs infeasibility (or other) warnings from presolve.
  Have the solve command set solve_result_num to 299 (rather than 200)
when presolve determines that the problem is inconsistent.

19980716
  Minor cosmetic tweak: when echoing new suffix declarations issued by a
solve or solution command, only put an extra newline in front of the
first echoed suffix declaration.

19980722
  For symbolic suffixes, binary or integer applies to the _num value.
  New builtin suffixes .no and .sno: if foo[i] is _xxx[j],
then foo[i].no = j (for xxx in {"con", "var", "obj"}); similarly,
if foo[i] is _sxxx[j] then foo[i].sno = j, and foo[i].sno = 0
if the solver does not see foo[i].
  Permit "display _obj.user_defined_suffix;" and
"display _sobj.user_defined_suffix;".

19980730
  Record settings of $linelim and $substout in .nl files, and adjust
these options, if necessary, when reading solutions.

19980905
  Adjust "display x;", where x is an indexed variable, so it does not
run presolve.

19980912
  Correction to 'Adjust "display x;"' in 19980904 above; if x was a
defined variable, sometimes it was not recomputed.

19981009
  Permit ":= {}" in set declarations.
  Permit set expressions of the forms
	if test then {} else set_expr
and
	if test then set_expr else {}
with the set_expr supplying the dimen (arity) of the empty set {}.

19981014
  Permit "display p.result;" for indexed collections of problems p.
  For infeasibility detected by presolve, have the solution, solve, and
write commands update the 'result' suffix of the current problem.

19981109
  New builtin params recording execution times (where possible):
	_solve_time = _solve_user_time + _solve_system_time
record CPU seconds for the most recent solve command, and
_solve_elapsed_time records wall-clock seconds for the most recent
solve; prepending _total gives sums of the corresponding entities
for all solve commands; changing "solve" to "shell" gives analogous
values for shell commands.  And
	_ampl_time = _ampl_user_time + _ampl_system_time
and _ampl_elapsed_time give analogous times for AMPL itself, excluding
times for shell and solve commands.
  On all systems, the elapsed time params are computed by the time()
function, which has a granularity of whole seconds.  The new CPU time
params report true CPU seconds on Unix and Windows NT systems (with
Win32 binaries, such as
ftp://netlib.bell-labs.com/netlib/ampl/student/mswin/samplnt.exe.gz).
On Windows 9x or 3.x, and on MS-DOS systems, CPU times are not
available; the system times are set to 0, and user times are elapsed
(wall-clock) seconds since the start of execution -- with a finer
granularity than the time() function.

19981214
  Adjust error message for a symbolic data-section value for a numeric
parameter.  For example, the old message
	type['HOST'] cannot be #ENDPOINT
is now
	type['HOST'] must be numeric, not 'ENDPOINT'
  Adjust "objective;" command so it does not try to instantiate the
current problem unless there is a partially dropped array of objectives
(in which case ampl must worry about which subscripts are valid).
  "Invisible" change: put suffix information ahead of nonlinear
information in .nl file, so .nl reading can be influenced by suffixes.

19990112
  Ignore gratuitous reset commands.
  Modified linearization of piecewise-linear terms.  To get the
linearization that had been the default since 19980309, specify
	option pl_linearize 3;

19990120
  New addition to reserved-word list: table.

19990304
  ftp://netlib.bell-labs.com/netlib/ampl/student/mswin/samplnt.exz:
Under W9x, treat '/' as '\' in the names of programs invoked by the
shell and solve commands.  (This already worked under NT, but Microsoft
does not tolerate much consistency among its operating systems.)

19990421
  Try to avoid leaving temporary files behind in the face of various
signals, such as SIGINT and SIGHUP.
  Have
	printf "%q",'';
print '' rather than nothing.
  New builtin symbolic param _cd is set to the current directory
initially and each time the cd command is executed.
  New variant -bs (and -brs) of command-line option -b for GUIs
that want to run solvers themselves.  Ask dmg for details.
  Have "option solver_msg 0;" suppress messages that appear when
presolve determines the solution (as well as the solution_message
returned by a solver).

19990607
  Table and out-arg extensions, to be described later.

19990804
  When an input file ends with a #comment not terminated by a newline,
assume a newline after the comment.
  Permit the close command to mention a comma-separated list of files
to close.
  Change to filename syntax: disallow commas in unquoted filenames.
This permits one to say things like
	load lib1, lib2;
and
	close file1.stuff, file2.xyz;
without treating the "," as part of the file name.
  Change to $ampl_include: previously it was a white-space separated
list of directories in which to look for files mentioned by "include",
"model", and "data"; now spaces are allowed within directory names
(but not before or after them), and directory names in $ampl_include
should be separated by newlines (or tabs, but tabs invite confusion;
for example, X-Windows turns tabs into spaces).
  Change $AMPLFUNC to behave similarly to $ampl_include: directory
and file names may contain internal blanks, and $AMPLFUNC now specifies
a sequence of zero or more file or directory names from which to
import functions.  Each name is first treated as the name of a shared
library (or DLL -- suffixes, such as .dll, must be explicit); if a
library by that name cannot be opened, the name is treated as a
directory name, and "/amplfunc.dll" (or "\amplfunc.dll" under MS
Windows) is appended to obtain the name of a library to load.
  The solve command now adjusts $ampl_funclibs to be a newline-
separated list of full pathnames of libraries from which functions
in the current problem instance were imported.
  New 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).
  New and adjusted system sets:
	_LIB = 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)
	_SFUNCS = imported functions that "solve;" currently uses.
  New 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.
  Extensions of funcadd.h for (still to be described) table handlers;
the updated funcadd.h is now in /netlib/ampl/solvers.

19990818
  MSDOS and Win32 "ampl" binaries: add expansion of * and ? in command-
line arguments, and replace command-line arguments of the form @filename
with the contents of file filename.
  Win32 "ampl" binaries: recognize quoted white space in command-line
arguments, no matter who provides the command line (e.g., another
program calling CreateProcess).  White space may be quoted with either
single or doubled quotes (' or ").  Within a quoted string, the quote
character may appear if it is doubled (as in AMPL strings).

19991130
  Win32 binaries only: adjust the cd command so sequences like
	cd c:/some/place/other/than/the/starting/directory;
	cd d:;
	print 'something' >'c:zot';
	shell;
will show the adjusted current directories to spawned processes
(in "solve" and "shell" commands) and will interpret 'c:zot' correctly
(as c:/some/place/other/than/the/starting/directory/zot).  Note that
under DOS, W9x, and NT, you can use / in place of \ in file names.
[For reasons known only to Microsoft, under W9x, a spawned command.com
gets its current directory information in some other way than do Win32
programs, so "shell" commands under W9x only reflect cd commands for
the current drive.  This problem goes away if you set option COMSPEC
to a Win32 command processor.]

20000128
  New command-line option -vi[nnn] to specify whether stdin should be
treated as interactive.  The default is to choose based on isatty():
if stdin and stderr both appear to be a terminal, i.e., isatty(0) and
isatty(2) both return 1, assume stdin is interactive.  Invoke
	ampl -v?
for a summary of all -v options; the description of -vi is
	-vi[nnn] {interactive mode?  (Must be first.)
		   nnn = 0 ==> no, nnn = 1 ==> yes but no prompts,
		   nnn = 2 ==> yes with prompts,
		   nnn = 3 ==> 0 or 2, based on isatty()}
In non-interactive mode, syntax errors now inhibit execution of
commands and terminate reading of the current file; previously,
commands were sometimes executed.  (Block input mode, used by AMPL Plus
and sample GUIs in http://www.ampl.com/ampl/GUI/expermt.html, remains
interactive.)
  New default presolve behavior: simplifications that appear to convert
nonlinear expressions to linear expressions really do so.
  Change to option linelim: "option linelim 0" and "option linelim 1"
work as before, while "option linelim 2" and "option linelim 3"
suppress the new conversion of "nonlinear" linear expressions
resulting from presolve simplification to true linear expressions,
and otherwise behave like "option linelim 0" and "option linelim 1",
respectively.

20000216
  Increase the resolution of _solve_elapsed_time, _shell_elapsed_time,
and "option randseed 0;".  The latter now changes more quickly.
  Warn about "fix x := 3;" when x is a subscripted variable.
  New builtin LOCAL suffix .relax:  for integer or binary variables,
.relax > 0 indicates that the integrality of the variable should be
ignored.
  Turn <<0;0,0>>x into 0.

20000217
  Arrange for integer_variable.relax values >= 2 to cause solvers to
see the variable as continuous, but for presolve to treat it as an
integer variable.  Also, have nonzero $relax_integrality to take
precedence over .relax suffix values, so
	option relax_integrality 1;	# ignore integrality everywhere
and
	option relax_integrality 2;	# use integrality in presolve,
					# but tell solvers all variables
					# are continuous
operate as heretofore, regardless of .relax settings.
  For "let" assignments to variable.declared_suffix, do not require
the "collect" phase.

20000228
  Under MS Windows, allow for spaces in $TMPDIR.
  In situations where bounds on a defined variable are equivalent to
bounds on a problem variable that the solver sees, reflect bounds on
the defined variable to the problem variable and remove the constraint
that implied the bounds on the defined variable.  Example:
	var x; var y = 3*x + 2;
	s.t. ybound: 5 <= y <= 11;	# reflect into bounds on x
	minimize zot: y^2;
  Deduce bounds on defined variables in more cases.
  Temporary(?) treatment of $substout: the "4" bit of $substout,
i.e., arranging that ($substout mod 8) >= 4, suppresses today's
reflection of bounds and stronger deductions of defined-variable bounds.

20000307
  Arrange for "option presolve_warnings -1;" to suppress both the
presolve message about how many presolve messages were suppressed and
the message about which modified options might help.

20000316
  Increase the resolution of _ampl_elapsed_time, and have "reset;"
reset _ampl_elapsed_time, even when there were no declarations to
discard.  (Otherwise, "reset;" is a no-op in this case.)

20000327
  Tweak to hash-table logic to speed up reading data on some large
examples (with many symbols).
  Tweak to "option linelim 1" output: nonlinear defined variables that
have no linear terms but are used linearly in a constraint or objective
are no longer split into two parts (unless, temporarily, the "4" bit of
$linelim is on, i.e., $linelim mod 8 >= 4).
  Command-line option -L now accepts an optional integer immediately
following the "L" (no space) to specify the initial $linelim setting.
No integer ==> -L1 (the old behavior).
  Change the default option linelim from 0 to 1.

20000427
  Tweak permitting use of AuxInfo (new field ae->AI) in imported
functions.  This is available when ae->ASLdate >= 20000427.  In calls
from AMPL, ae->AI is always null, but solvers can arrange for it to
have useful values.

20000505
  Arrange for "option compl_warn 0" to suppress the warning message
about nonsquare complementarity systems and for "option compl_warn 2"
to cause nonsquare complementarity systems to be infeasible.

20000602
  Treat variables in defining declarations (var x = ...) as defined
variables even when bounds are reflected on them.

20000608
  Addition to funcadd.h: char* getenv(const char*), which lets
imported functions and table handlers access the current environment
(as modified by option, environ, and problem commands).  Only use
getenv (i.e., (*ae->Getenv)) if al->ASLdate >= 20000608.

20000615
  Fussy numeric detail: ignore case in recognizing Infinity and NaN in
data sections and in format %q, so
	printf "%q\n", 'nan';
now prints
	'nan'
rather than
	nan
This fixes a glitch with AMPL's writing of .tab values involving
symbolic parameters with values like 'infinity' and 'nan', which
should be kept as strings, not turned into numbers, much as
'123' and 123 are distinguished.

20000706
  When loading a library, arrange for subsequent unloading of the
library to happen after any at_exit() or at_reset() processing requested
directly or indirectly by addfunc().  (This matters to an experimental
facility for importing Java functions.)
  In calls on imported functions, ensure that al->dig == 0 when
al->deriv == 0.

20000814
  Recognize command-line option -b?.

20000825
  Adjust prompts to indicate "Waiting for end of line after #" and
"Saw /*; waiting for */".  To indicate the former, # is inserted at
the start of the prompt; for the latter, * is similarly inserted.
If the prompt string would otherwise be the empty string, nothing is
inserted.
  Change to builtin "sub" and "gsub" functions: treat \n as newline
(as in the "sam" editor of plan 9).  Thus the pattern (.|\n)* now matches
everything until the end of the string, including intervening newlines.
  Make variable.no independent of whether the variable is fixed.
  Adjust presolve to make more ambitious the extended presolve
iterations that occur when $presolve > 1:  when a variable is fixed,
consider implications of modified constraints involving two or more
remaining (unfixed) variables in the current extended presolve
iteration rather than the next one; and when fixing two or more
variables leads to simplifications of the same constraint, the first
with implications for one bound (lower or upper), the second for
the other, consider implications for both bounds.  (Temporarily,
option presolve_debug 3 suppresses these changes.)
  Have presolve use values of $presolve_eps, $presolve_fixeps, and
$presolve_inteps that are rounded up by function
	R(x) = if x > 0 then 1.1^ceil(log(x)/log(1.1)) else 0.
Encode the relevant values in .nl file headers and arrange for
the solution command to issue option commands if necessary to
set $presolve_eps, $presolve_fixeps, and $presolve_inteps to values
that permit correctly reading the solution.
  In addition to using option presolve_fixeps during simple presolve
reductions (those for $presolve = 1) to decide when tighter bounds
lb and ub on a variable v (lb <= v <= ub) are close enough to
consider v fixed (when ub - lb <= R($presolve_fixeps)), also use this
test when extended presolve iterations ($presolve > 1) reduce ub - lb;
in this case, v is fixed to if ub < 0 then ub else if lb > 0 then lb
else 0.  (Temporarily, "option presolve_debug 8" suppresses this.)
  New system params _presolve_eps_L and _presolve_eps_U
indicate whether changes to $presolve_eps would matter: they should
not matter if
	_presolve_eps_L <= R($presolve_eps) < _presolve_eps_U.
Similarly, new system parameters
	_presolve_fixeps_L	_presolve_fixeps_U
	_presolve_inteps_L	_presolve_inteps_U
give corresponding bounds for $presolve_fixeps and $presolve_inteps:
presolve results should not change as long as
	_presolve_fixeps_L <= $presolve_fixeps < _presolve_fixeps_U
and
	_presolve_inteps_L <= $presolve_inteps < _presolve_inteps_U.
  Rerun presolve if $constraint_drop_tol changes.  This already
happened for $presolve_eps, $presolve_fixeps and $presolve_inteps.
  Arrange for option show_stats 2 to produce the same output as
option show_stats 1, plus an additional line about $presolve settings:
report current $presolve and indicate whether a smaller value would
suffice (albeit saving no time) or a larger value might give stronger
bounds.  In the latter case, the possible improvements are sometimes
minuscule.  Two new builtin params give values that help determine the
new line:  _presolve_req is the value of $presolve needed to
reproduced the results of the last run of presolve.  (This value has
long been encoded in .nl files to facilitate correctly reading .sol
files.)  _presolve_sug = presolve_req if further presolve iterations
would not help and is otherwise either $presolve + 1 (if $presolve >
0) or 10 (if $presolve = 0).
  Values of $presolve_*eps shown in output for $show_stats = 1 or 2
are now rounded to assure changes to R($presolve_*eps).

20000906
  Arrange for redeclarations of unsubscripted sets with no := clause
to retain their values (when redeclared to be a set of the same arity).
Example:
	set S ordered; data; set S := a b c;
	display S; redeclare set S ordered;
	display S; # OK now; previously "no data for set S"

20001002
  Add "contains" to the reserved-word list.  (Later, it will be a
set-comparison operator, with A contains B <==> B within A.)

20001006
  Turn v1*sum{i in A} p[i]*v[i] into zero, where v1 and v[i] are
variables and p[i] == 0 for all i.

20001128
  ampltabl.dll:  handle .dsn files better (no longer require them
to contain DBQ= lines); no longer require DSN=... strings to contain
DBQ=...; permit DRIVER=... to specify a full connection string (as
well as DSN=...); handle driver-specific types in addition to the
ODBC standard ones.

20010129
  In iterated commands and expressions, permit {if logical_expression}
wherever indexing expressions were previously allowed.

20010130
  For completeness, permit {if logical_expression} as the indexing
in iterated reduction operators (sum, prod, min, max, exists, forall).

20010322
  Again adjust "option randseed '';" and AMPL's -s command-line option
to make it more likely that successive invocations will give different
values.  The changes are visible mainly on Microsoft systems.

20010405
  New Caution:  unless $Caution is 0, warn about numeric option
settings where part of the option string is ignored.
  In response to "solve;" after a previous command has caused
presolve to determined the solution or eliminate all variables,
if $solver_msg is nonzero (as it is by default), print solve_message
again -- it should also have appeared after the previous command,
and it explains the situation.  Example:

	var x >= 1 <= 2 := 3; var y = x + 2;
	solve; # "No variables used after elimination of defined variables."
	solve; # now gives the same message, rather than silence.

20010507
  In imported (user-defined) functions, have printf("%s",0) print
"<NULL>" rather than fault.
  When presolve determines a feasible solution, set
solve_result_num = 99.

20010613
  Adjust treatment (probably introduced 19941003) of infeasible
problems:  after presolve detects infeasibility, whether a second
solve or write command is allowed to proceed is now controlled by
new option infeas_clear, whose default value 1 allows the commands
to proceed when issued in interactive mode on stdin.  Specifying
"option infeas_clear 2;" restores the former behavior of letting
second solve and write commands proceed under all circumstances,
and option infeas_clear 0 treats a second such command just like
the first.

20010816
  Sample ampltabl.dll for MS Windows:  when reading tables in an
explicitly specified file, use the full pathname in "DBQ=..." to avoid
confusion with similar names known to the ODBC Data Source
Administrator.  When writing tables, the sample ampltabl.dll still
tries to use "DSN=..." if possible.  Note that to permit writing .xls
files, it's necessary for the ODBC Data Source Administrator to have
a DSN (e.g., a User DSN) associated with the Microsoft Excel driver with
the "Read Only" box unchecked (under Options in ODBC Microsoft Excel
Setup).

20011119
  Ensure that A union B puts members of A first.  Usually it did, but
under some conditions the members of B came first.

20011206
  Adjust processing of (the default) "option linelim 1" so defined
variables that are not involved in the current problem will not be
affected by "option linelim 1" (which took considerable time in a
motivating example).  The temporary interpretation of the "4" bit of
$linelim, introduced 20000327, is rescinded.  Now, temporarily (for
debugging), when the "4" bit of $linelim is on, today's change to
processing for "option linelim 1" will be suppressed.

20011231
  New option presolve_assoc (default 7) affects simplification of constants
in nonlinear contexts during presolve:  sum of
	1 ==> permit using associative law on + and - operations;
	2 ==> permit using associative law on * and / operations;
	4 ==> permit using distributive law on
		const*(const*thing +- const*thing).
  Change command-line option -o to write a .nl file at the end of the last
command-line input file if a "solve;" command would write a new .nl file.
(Note that if no command-line input files are given explicitly, then stdin
is treated as the single command-line input file.)

20020409
  For properly behaving solvers linked with interface library versions
>= 20020402, adjust the reading of .sol files to omit the backspaces
that used to appear when the solvers did not report any option
settings.

20020503
  Add SnprintF and VsnprintF to AmplExports, to make snprintf and
vsnprintf available to imported functions.

20020528
  (Inexact date; change made after discussion in May 2002.  This
note added 20210223.)  Allow "= expr" to act as ":= expr" in param
declarations when new option old_param_eq has its default value 0.
This is for declaring a derived parameter whose value is computed
from the given expression "expr".  Specifying "option old_param_eq 1;"
will cause "= expr" to have its old meaning, which was to specify a
check on the param value.  Option old_param_eq also affects the
"show" command, which prints "= expr" in a relevant param declaration
when $old_param_eq has its default value and ":= expr" when $oldparam_eq
is 1.

20020708
  Change to handling of multiple objectives:  previously objectives
were always reordered so that nonlinear objectives came first.  Now
the default is not to do this reordering.  Option nl_permute is
extended to allow indicating that objectives should be reordered as
heretofore.  $nl_permute is now the sum of
	1 ==> reorder constraints
	2 ==> reorder variables
	4 ==> reorder objectives
The default value for $nl_permute remains 3.

20020716
  Obscure enhancement to handling of complementarity constraints of
the form equation complements unbounded_variable:  indicate to solvers
that the unbounded variable is associated with the equation.
Turning the "4" bit of $compl_warn on (usually by
"option compl_warn 5;") suppresses this adjustment.

20020801
  Tweak to single-step mode: accept a semicolon or white space after
the optional repetition count after "next", "skip", and "step".
  In problems with variables in singleton complementarity constraints,
let the complementarity constraints imply the variable bounds when
$var_bounds is 1 (the default), unless the variables are also matched
with other complementarity conditions.  Example:

	var x; var y;
	s.t. c1: x >= 0 complements y >= 0;
	s.t. c2: x + y = 1;
	display _varname, _var.lb, _var.ub;
	# above now shows no bounds on y

20020814
  In the display command's printing of 2D tables, permit the final ":="
part of the ": ... :=" header to exceed $display_width (to make the
output a bit more regular).  We can always recant this tweak if it
turns out to cause more trouble than it avoids.
  In set and param declarations, treat = (or ==) as a synonym for :=,
so = behaves as it does in var declarations.  For param declarations,
this is simply an extension.  For param declarations, it changes the
meaning of =, which previously implied a surprising test that the
param had the specified value.  (We believe that = was almost never
seriously used in this way, so that this change will be harmless.
If not, "option old_param eq 1;" restores the old meaning of = in
param declarations, at least for now.)
  Arrange that failed consistency checks detected during a "solve"
command will result in solve_result = '?' and solve_result_num = -1,
just as they are at the start of execution.  Previously they retained
their values from the last successful "solve".
  Change "s.t." to "subject to" in "show" and "expand" commands.

20020924
  When foo is a subscripted problem whose declaration does not specify
a subscripted environment, have "problem foo;" make foo's environment
current.

20021025
  Arrange for variables to which piecewise-linear terms are applied
to be defined by the linearizations of the terms.  On problem 14.7(d)
in the AMPL book (first edition; 17.7(d) of the second), this reduces
the numbers of variables and constraints by 1/3.  Turning the "4"
bit of $pl_linearize on, e.g., with
	option pl_linearize 5;
suppresses this change.
  Infer bounds of 0 and 1 on binary variables, even when they are
relaxed by assignment of 1 to their .relax suffix.

20030204
  Cut over to a version that works as described in the second
edition of the AMPL book, including such relatively obscure
features as new tabular forms in data sections, handling of
"in union_of_intervals" phrases in variable declarations, and
$(expr) string expressions.  Some new constraint-logic programming
features, described in INFORMS J. Computing 14#4 (2002) pp. 322-344,
are also recognized.  (Variables in subscripts are still missing.)

20030227
  New option strict_ineq_warn (default 1) determines how to handle
constraints involving a strict inequality when the constraint would
be an algebraic constraint if the comparison were changed to permit
equality (i.e., < were changed to <= or > were changed to >=):
	0 ==> quietly treat the constraint as a logical constraint;
	1 ==> print a caution and treat as a logical constraint;
	2 ==> print a warning and reject the constraint.
Before 20030204, AMPL behaved as though $strict_ineq_warn were 2.

20030319
  Fix glitches with "unload" (which did not completely unload the
indicated library) and "delete function_name" (e.g., when the
function name coincided with a builtin random function).

20030328
  Fix a fault introduced 20030319 in handling ampltabl.dll after a
reset.  Fix a glitch that sometimes caused "unaligned access" errors
on systems with 64-bit addressing.

20030331
  Adjust option relax_integrality so binary variables added to
linear nonconvex piecewise-linear terms are retained under
	option relax_integrality 1;
and are relaxed, with no suffix information about them transmitted
to the .nl file, under
	option relax_integrality 2;
Before this change, solvers might fault unless explicitly told to
ignore SOS information when $relax_integrality was 1 and the problem
had nonconvex piecewise-linear terms.

20030527
  Adjust the output of "expand _con;" and "expand _con[n];" so that
when complementarity constraints are present, they are only indicated
by a ".L" or ".R" suffix on the constraint name.  Previously, if, say,
the first constraint was a complementarity constraint, then
both "expand _con[1];", "expand _con[2];" and "expand _ccon[1];" all
produced the same output, except for the decorations ".L" and ".R" in
the constraint names shown for _con[1] and _con[2].  Similarly,
"expand _con;" showed complementarity constraints twice, distinguished
only by ".L" and ".R" decorations.  These decorations now appear after
rather than before subscripts.

20030626
  Adjust changes made, if necessary, by the "solution" command to
$presolve_eps, $presolve_fixeps, and $presolve_inteps to properly read
a .sol file corresponding to a .nl file written before changes to
those options:  multiply the R(x) value shown in the changes of
20000825 by .95 (to put the value roughly halfway between the relevant
integer powers of 1.1), then round the result to 3 significant
figures.  For example, with a suitable solver and problem instance, in

	write bfoo; solve;
	option presolve_inteps 37; solution b.sol;

the solution command now issues

	option presolve_inteps 1.04e-06;

rather than yesterday's

	option presolve_inteps 1.0950988861107401e-06;

Because of how $presolve_inteps is discretized,
"option presolve_inteps 1.04e-6" has the same effect as the default
"option presolve_inteps 1e-6".  Today's changes also correct a bug in
deciding whether to restore $presolve_inteps.  On the relatively rare
occasions when this bug bit, it might cause reading the .sol file to
fail after a surprising "option presolve_inteps..." command was
generated and presolve ran again.

20030724
  Fix a bug in handling logical constraints (a forthcoming extension):
if $auxfiles or $($solver & '_auxfiles') requested a .row file and the
problem contained both logical constraints and objectives, a fault was
likely.
  New feature related to this bug fix:  when new option
convert_logical_to_algebraic has its default value 1, constraints that
appear to be logical constraints because they are surrounded by
parentheses but that would be recognized as algebraic constraints
without the surrounding parentheses are converted to algebraic
constraints during parsing.  Specifying
	option convert_logical_to_algebraic 0;
suppresses this conversion.

20031017
  Diagnose ": =" instead of ":=" in data tables.

20040103
  Adjust linearization of a nonconvex piecewise-linear term to use
	max($pl_bigM, 2*max{b in Breakpoints} abs(b),
		if lb > -Infinity then abs(lb) else 0,
		if ub < +Infinity then abs(ub) else 0)
where $pl_bigM was previously used (with lb and ub the lower and
upper bounds on the variable that the piecewise-linear term
multiplies).  Turning the "8" bit of $pl_linearize on, e.g., by
	option pl_linearize 9;
suppresses this change, at least for now.

20040821
  Print NaN values as NaN, regardless of their sign bits.  Previously
-Nan was sometimes (incorrectly) printed.  The sign bit of a NaN is not
supposed to have any meaning.
  Add new system param NaN (which, on systems with IEEE arithmetic, has
the value NaN and in general has the value Infinity - Infinity).

20050530
  If a "read" command issued in interactive mode encounters end-of-file,
permit further interactive input.

20050702
  Note that to get correct dual values for constraints removed by presolve
when using an interior-point solver, it's necessary to set $abs_boundtol
or $rel_boundtol to a suitable positive value.  These options are not
described in the AMPL book, but are described in the entry for 19931005
of /netlib/ampl/changes.  Note also that not all changes to $abs_boundtol
and $rel_boundtol cause recomputations; AMPL records ranges of values for
these options that have the same effect and avoids recomputations for
changes that do not matter.

20060314
  For imported functions, change unsigned long args to size_t, to
permit allocating memory blocks of size >= 4GB (a mostly invisible
change; for solvers, this requires ASLdate >= 20060122).

20060430
  Arrange for presolve to turn logical constraints into algebraic
constraints (when deductions make this possible), and then to process
the new algebraic constraints.
  New builtin params:
	_nlog_algcons = number of logical constraints turned by
			presolve into algebraic constraints
	_npre_log_algcons = number of such constraints subsequently
			eliminated by presolve.
These numbers also appear in the output for "option show_stats 3;".

20060725
  Have "display" honor $display_precision when printing symbolic
parameters having numeric values.
  When "expand" or "solexpand" prints out a constant objective,
show its value as "number" or "-number" rather than "0 + number"
or "0 - number".

20060905
  When x is a variable, have "reset data x;" discard x's current
value (and, as before, permit new default data for x's initial value
in a data section).  If x has a random default expression, it gets
resampled when x is next needed.  Previously, "reset data x" worked
this way until x was assigned a value by "let" or "solve", after which
x retained the assigned value.

20060912
  New option csvdisplay_restrict:  with $csvdisplay_restrict at its
default value, an undocumented restriction on csvdisplay is henceforth
relaxed.  Specifying "option csvdisplay_restrict 1;" enforces the
restriction in question, namely that csvdisplay issues an error
message (meant to help debug GUIs that use csvdisplay) when asked to
display more than one table.  Example:
	set A{i in 1..4} = i .. i^2;
	csvdisplay A;	# used to be disallowed
	option csvdisplay_restrict 1;
	csvdisplay A;	# gives the old behavior:
	# complains "csvdisplay would emit 4 tables."

20061023
  Tentatively introduce option presolve_logfile with possible values
"filename" to write file filename anew each time presolve runs;
">>filename" to append to filename each time presolve runs; and
"-" to write to the standard output file (stdout).  When
$presolve_logfile is not "" (its default value), each time presolve
updates a bound, the constraint and variable involved and updated bound
are written to $presolve_logfile.
  New builtin symbolic param _table_errmsg records the last error message
from the most recent "write table" or "read table" command, and is set
to "" if the last such command had no error.
  New option table_errbreak determines whether "write table" and/or
"read table" commands report errors and terminate processing of
commands, or suppress error reports and simply record the last error
in _table_errmsg.  $table_errorbreak (default 0) is the sum of

	1 {suppress error reporting for "write table"}
	2 {suppress error reporting for "read table"}
	4 {for iterated "read table" and "write table" commands,
		do all iterations despite errors}

Hitherto, $table_errbreak = 4 was the old behavior; now the default
value 0 stops iterated table commands at the first error.

20061121
  Add messages distinguishing "Solution determined by presolve" from
"All variables fixed" and "All relevant variables fixed".  (In the
latter case, some unused variables are not fixed.)  All these cases
still get solve_result_num = 99.
  Have main() call exit rather than returning, to prevent a fault
on an odd version of Linux.

20070301
  Tweak to $csvdisplay_restrict: when $csvdisplay_restrict mod 2 == 1,
provide a more detailed error message when csvdisplay would emit more
than one table, unless $csvdisplay_restrict mod 4 == 3, in which case
the former, one-line error message appears.

20070317
  Addition to error messages for commands:  the current _cmdno (the
count of commands executed) is now reported unless input is from the
standard input.  For the standard input, setting option stdin_offset
to 1 causes the input offset and _cmdno to be reported in error
messages for commands.
  New option single_step_cmdno causes $single_step to be set large
enough to cause single stepping when _cmdno == $single_step_cmdno.
This provides a way to repeat the execution (after "reset;" or a fresh
invocation) and enter single-step mode just before an error, to permit
looking at current values, which might shed light on the error.

20070410
  Add "	7	rand	random variable in current problem"
to $astatus_table.

20070612
  Tweak printing of sets under complicated conditions, such as error
messages involving next() and prev() under obscure conditions in
which the sets are now shown as a list of elements, enclosed in
braces.  Previously the braces were omitted and the elements printed
one per line, which was confusing.

20070903
  In the breakpoint and slope lists of piecewise-linear expressions,
i.e., the ... of <<...; ...>>, permit iterating parenthesized lists
of expressions, as in function calls.  Here is an example that is
now acceptable, but formerly elicited a syntax error message:

	var x in [-15,15];
	minimize zot: <<{i in 1..3} i^2; {i in 1..2} (-1,1)>> x;

20070923
  Permit Infinity (as well as NaN) as values in data sections.
  Disallow deleting some suffixes not previously noted as system
suffixes.
  System suffix stage was quietly introduced a while ago, for use with
random variable declarations (a forthcoming extension).  Permit explicit
declaration of suffix stage if no random variables have been declared,
which disallows subsequent declarations of random variables and permits
using stage as an ordinary declared suffix.

20080102
  When a constraint implies a bound on a variable and integrality of
the variable causes a further adjustment to the bound, do not treat
the constraint as tight when inferring dual values.  Before this change,
constraints eliminated by presolve were sometimes given nonzero dual
values, even though they were slack.
  Tweak ODBC table handler so (e.g.) with MS SQL Server it will choose
a better type for numeric data.

20080307
  New variant -Rw of command-line option -R (described in change-log
entry for 19970814) disables output redirections ("> filename" and
">> filename").

20080312
  New option ampl_libpath specifies a sequence of directories,
one per line (analogous to $ampl_include) in which to look for
libraries mentioned in "load" commands.  When $ampl_libpath is
empty or contains only white space, the "load" command looks in
the current directory.  (The "unload" command looks for names
mentioned in previous "load" commands and quietly ignores names
not found; "reload" is a combination of "unload" and "load", so
it honors $ampl_libpath when doing its "load".  Note that
$AMPLFUNC and the builtin sets _AVAILFUNCS, _AVAILFUNC2, _LIBS
are updated by "load", "unload", and hence "reload".)

20080423
  New builtin params _last_solno, _primal_solno, _dual_solno,
_status_solno:  _last_solno is incremented at each "solve" and
"solution" command that reads at least some solution information.
If any primal or dual variable or solver status (.sstatus) values
are read from the .sol file, _primal_solno, _dual_solno, and/or
_status_solno, respectively, is/are set to the new _last_solno value.
If "solve" results in "Solution determined by presolve" or
"Infeasible constraints determined by presolve", these parameters
are also updated.

20080616
  Adjust reporting of memory used to avoid confusion under some
64-bit versions of Linux where there can be large gaps in the
addresses returned by malloc().  This change affects the memory
usage reported with "option times 1;" and "option gentimes 1;".

20080629
  Write "Solution determined by presolve" messages to stdout rather
than stderr.
  New builtin solve_result_num values:
	999 ==> error running solver (nonzero solve_exitcode);
	998 ==> nonexistent .sol file;
	997 ==> error in .sol file;
	996 ==> error in restoring state to read .sol file.
Treat any of these as exit code 1024 from the solver as far as
option solve_exitcode_max is concerned.  (The default value of 0
for $solve_exitcode_max will then cause a break in the execution
of commands.)  This applies to both "solve" and "solution" commands.
(Of course, solve_result_num cannot be set to 999 by a "solution"
command.)

20080701
  In some cases of failed "solve" and "shell" commands, report where
in what input file the error occurs.

20080804
New params (mainly for use in debugging carelessly written models):

	_backslash_map default 0;	# 0 ==> no mapping
					# 1 ==> map \\ to /
	_filename_case default 0;	# 0 == retain given case
					# 1 == force to lower case
	set _file_prefixmap dimen 2;
		# for (a,b) in _file_prefixmap, map prefix a to b

Note that under MS Windows, you have always been able to use / instead
of \ in file names.  Use of \ causes gratuitous unportability.

20080907
  Arrange for
	printf "%+011.0f\n", -12345;
to print "-0000012345" rather than "     -12345".
  Extend printf to accept the C99 formats %a and %A.

20080926
  Add option shell_exitignore to suppress the message
"exit code n" from "shell" commands when n <= $shell_exitignore.
(On Unix and Linux systems, n = shell_exitcode/256.)

20081026
  Add "q" as synonym for "quit".

20081208
  New option mpsfile_numwidth (default 12) controls the field width
and format of floating-point values written by the -om output option
(for MPS files, which are to be discouraged, as they are slow to read
and write and omit important problem details, such as the sense of
optimization).  Positive values specify that field width; negative
values specify fieldwidth -$mpsfile_numwidth with nonnegative values
having an initial space, so both x and -x are printed to the same
number of significant digits.  Specifying "option mpsfile_numwidth 0"
causes numbers to be written to full precision, the same as printf
format %.g (in AMPL -- a sensible departure from the unfortunate C99
provision that %.0g be treated as %.1g).  Some solvers may not cope
properly with values of abs($mpsfile_numwidth) > 12.
  New option no_hexfp.  When $no_hexfp is 0 (its default), C99-style
hexadecimal floating point constants are recognized: they are strings
that start with 0x or 0X followed by a string of hexadecimal digits
possibly containing one decimal point, optionally followed by an
exponent part consisting of p or P, an optional sign (+ or -) and
a nonempty string of decimal digits (the power of 2 by which to
multiply the hexadecimal value preceding the exponent part).  When
$no_hexfp is 1, hexadecimal floating-point values are not recognized,
thus restoring AMPL's previous behavior, in which hexadecimal floating
values without a decimal point could be used as normal identifiers,
and general hexadecimal floating-point values could appear unquoted
in data sections and be treated as symbolic values.
  One reason for interest in hexadecimal floating-point numbers is that
they are faster to read and write than decimal values.  Note that the
printf formats %a or %A can be used to write hexadecimal
floating-point values.  We expect most AMPL users to be unconcerned
with hexadecimal floating-point notation, but on occasion a few may
find it convenient to be able to read and write them.
  New builtin set _LOCAL_OPTIONS is set initially to most of the option
values that AMPL provides, except for ones found in the incoming
environment, and except for
	AMPLFUNC
	amplfunc0
	objective_precision
	version
which are always exported, as some solvers use them.  When carrying
out a "solve" or "shell" command, AMPL does not pass to the invoked
program environment variables whose names appear in _LOCAL_OPTIONS.
This set is retained across reset commands and can by modified by
"let" commands.  To restore the old behavior of exporting all options,
invoke
	let _LOCAL_OPTIONS := {};
initially.

20081210
  New command _solexpand, a variant of solexpand meant for program
rather than human consumption, and only useful (so far) for linear
constraints and objectives.  For each constraint or objective treated,
it writes a one-line header, followed by linear terms, one per line.
The header has the form

	What sno bt nlin isnl bound(s) name

where What is one of
	Min for an objective to be minimized,
	Max for an objective to be maximized, or
	Con for a constraint;
sno is the objective or constraint number as seen by the solver:
0 for the first, 1 for the second, etc.; bt is 0 for objectives
and for constraints is
	  (if the constraint's lower bound is finite then 1 else 0)
	+ (if the constraint's upper bound is finite then 2 else 0);
nlin is the number of linear terms that follow; isnl is 1 if the
objective or constraint also has a nonlinear part and is 0 otherwise;
if 0 <= bt <= 2, bound(s) is a single number, either the objective's
constant term or the constraint's one finite bound; if bt is 3, then
bound(s) is two numbers: the constraint's lower bound followed by the
constraint's upper bound; finally name is the possibly subscripted
name of the objective or constraint in question.  The nlin lines for
linear terms that follow the header line have the form

	varno coef

where varno is 0 for the first variable that the solver sees, 1 for
the second, etc., and coef is the coefficient of the variable.
Floating-point numbers by default are written by format %a (i.e.,
C99-style hexadecimal floating-point format, which now can be read
by the strtod routine in the AMPL/solver interface library); if
$no_hexfp is set to 1, floating-point numbers are written with
format %.g (i.e., full precision decimal).

20090209
  Complain when a var declaration specifies the variable to be in
a disjoint union of intervals involving an infinity.

20090316
  Extension:  in data sections, after a : ... := header, permit ": :="
(which may be written "::=") to reuse the same header.  Example:

	set S dimen 3; param p{S};
	data;
	set S :=
		(a,x,1) (a,x,2) (a,y,1) (a,y,2)
		(b,x,1) (b,x,2) (b,y,1) (b,y,2);
	param p [a,*,*] : 1 2 :=
	x 1.1 2.2
	y 3.3 4.4
	[b,*,*]::=
	x 5.5 6.6
	y 7.7 8.8;
	display p;

  Extension:  in data sections, permit a "param-data-alternate" header
that specifies a set-name and one parameter name to accept ": ... :="
tables instead of a ":= value-item ..." list.  Example:

	set S dimen 3; param p{S};
	data;
	param :S:p [a,*,*] : 1 2 :=
	x 1.1 2.2
	y 3.3 4.4
	[b,*,*]::=
	x 5.5 6.6
	y 7.7 8.8
	[c,*,*]::=
	z 9.9 0.2;
	
	display p, S;

20090323
  New error message "The current problem is empty." appears in
response to a "solve" or "write" command after a new, empty problem
declaration not followed by any subsequent variable, constraint, or
objective declarations.  Previously one of the messages
"All constraints and objectives dropped."  or (if some defined
variables had been declared) "Solution determined by presolve."
appeared in this context.  Examples:

	model diet.mod; data diet.dat;
	problem zork; solve;
	# said "All constraints and objectives dropped."

and a defined-variable variant

	model diet.mod; data diet.dat;
	var Buysum = sum{j in FOOD} Buy[j];
	problem zork; solve;
	# said "Solution determined by presolve."

20090508
  This is a note about a longstanding feature that apparently we missed
documenting:  with interactive input, "/*" leads to prompt "*ampl:" until
"*/" appears in the input.  In general, the prompt the prompt that
would otherwise appear, preceded by *.

20090707
  For linear problems with the student versions of AMPL, increase the
allowed number of variables and objectives+constraints to 500 each.

20090726
  Add option allow_NaN (default 0).  If $allow_NaN is positive,
objective and constraint values are set to NaN in the face of a
numeric evaluation error that depend on current variable values,
rather than giving an error message.

20090811
  Add a warning about comparisons with strings and one of the operators
<, <=, >=, > (to catch some instances of use of & rather than &&).

20090926
  Changing default value of option show_boundtol from 0 to 1
and adding option boundtol_max (default 1e-5).  When
"option show_boundtol 1;" is in effect, report changes that
would affect dual variable computations whenever dual variables
are recomputed, not just when a solution is read, but report
them only if the new $abs_boundtol or $rel_boundtol value would
not be more than $boundtol_max.

20091112
  Exclude defined variables (and their defining constraints) from
the count of constraints used in deciding whether a problem is
small enough for the student version.

20091122
  Fix a glitch that caused an error message of the form
"invalid refct -2147483647 in opgen" after execution of a huge
number of suitable commands.  (In the example that led to this fix,
the message arose at _cmdno 7123157887, which is well over 2^32.)

20100228
  Allow an optional output redirection after "commands filename", which
applies to output that would otherwise go to the standard output.
Closing the target of the redirection during execution of the commands
in filename causes such output again to go to the standard output.

20100320
  Fix a fault with "option presolve 0" on some problems with
piece-wise linear terms.  (Work-around:  leave option presolve at its
default setting.)

20100715
  Extension to the regular expressions processed by sub and gsub:
@ is similar to ., but also matches \n, i.e., @ is a synonym
for (.|\n).  The above example can now be written
    num0(sub(solve_message, '@*^([0-9]+) MIP@*', '\1'))
Of course, a literal @ appearing in a regular expression must now
be escaped, as in
    sub('x@y', '\@', ' at ')
in which previously the \ was not required (but was allowed).

20100928
  Adjust environment changes so if one declares two problems,
(with distinct environments) then sets option randseed to the same
value in each, switching between these problems will not cause option
randseed to be reset to the common value, but the random number
sequence will continue.  For example,

	var x;
	minimize zip: sin(x);
	minimize zap: cos(x);
	problem p1: x, zip;
	problem p2: x, zap;
	option randseed 42;
	print Uniform01();
	problem p1;
	option randseed 42;
	print Uniform01();
	problem p2;
	print Uniform01();

used to print "0.31376060558952107" thrice.  Now the third "print"
gives a different value (0.8653543517772044).  Best practice (least
confusing) is to adjust option randseed before declaring problems or
new environments, in which case the this change to environment
processing makes no difference.
  New builtin suffix "int" on variables is 0 for a continuous variable
and 1 for an integer or binary variable (unless $relax_integrality is
nonzero or the variable's .relax suffix is positive, in which case .int
is 0 and solvers will see the variable as continuous).

20110531
  Adjust processing for $substout=1 to allow mutually recursive
variable definitions from several indexed defining constraints.

20110713
  Change the default computation of c.slack for a complementary
constraint of the form

	c:  L <= expr1 <= U complements expr2

with L and U finite to

	min(expr1 - L, U - expr1,
		if expr1 <= 0.5*(L+U) then expr2 else -expr2)

Setting new option $old_complementarity_slack to 1 restores the
old computation:

	min(expr1 - L, U - expr1,
		if expr1 <= L then expr2
		else if expr1 >= U then -expr2
		else -abs(expr2))

The new default computation is more useful than the old when
an interior-point algorithm is used.  With it, a slack value of
zero means the constraint is satisfied exactly, a small positive
value is a complementarity violation, and a negative value is a
constraint violation.  Unless we hear feedback that having
option old_complementarity_slack is useful, this new option may
eventually be withdrawn.
  When writing a .nl file after a solve or solution command,
i.e., when primal or dual values for implicit variables or
constraints are available, include their values, if nonzero,
with the primal or dual initial guess.
  Fix glitches in "expand cc;" and "solexpand cc;", where cc is
a complementarity constraint:  bounds were sometimes not shown.
  Add two numbers to line 3 of the .nl header when complementarities
are present: nd = number of "double" complementarities, i.e., those
involving a double inequality, such as
	L <= expr <= U complements expr1
and nzlb = number of complemented variables with a nonzero lower
bound.  The new numbers are used in a new facility soon to be added
to the AMPL/ solver interrface library for optionally modifying
complementarity conditions to v1 >= 0 complements v2 >= 0.  (With
older versions of AMPL, the facility uses upper bounds on nd and
nzlb.)

20110813
  In equality constraints in which one side involves numeric variables,
assume the other side must also be numeric.  This matters when the
other side involves an if-then-else expressions whose "then" or "else"
expression consists only of a dummy variable, such as

	set I := 1..2; var x{I}; var y{I};
	subject to c{i in I}: x[i] = if i == 1 then y[i]
				else if i == 2 then i;

which previously was treated as a logical constraint.  (Changing
"then i" to "then i + 0" was necessary to make constraint c into
an algebraic constraint.)

20110906
  Extend "option show_stats 1" output to list the numbers (if
nonzero) of equality, inequality, and range (i.e., double
inequality) constraints.
  On Unix-like systems, add command-line option -g to start in a new
process group.
  Extend option relax_integrality to apply to binary variables
introduced to handle "in union_of_intervals" phrases in variable
declarations.

20111005
  Allow "ampl -R" (server mode) to use imported functions provided by
"load"  commands (but not pipe functions).

20111107
  When imported functions or table handlers see ae->ASLdate >= 20111028
and ae->asl == 0, ae->Getenv(0) returns a char** value for the complete
current environment.
  On Unix-like systems, set FD_CLOEXEC when opening files, to prevent
child processes (e.g., from "solve" or "shell" commands) from seeing
irrelevant open file descriptors, a bit of tidiness seldom relevant in
practice.

20111216
  For the -ix command-line option, in addition to allowing multiple
files on separate lines of a suitably quoted x, allow multiple files
on the same line if each file name is enclosed in single or double
quotes.  Add a brief explanation of multiple files to the "-i?"
output.

20120117
  New builtin suffix ".sense_num" on objectives is -1 for
minimization and 1 for maximization.  New builtin suffix
".sense" is a symbolic version of ".sense_num" with default
values "minimize" and "maximize" given by option sense_table.

20120126
  Adjust "load" command to facilitate using a 32-bit AMPL binary
with a 64-bit solver binary or vice versa:  for a 64-bit AMPL,
if the library name involves '.' and the final '.' is
preceded by "_32", change the "32" to "64".  Otherwise, if the
library fails to load and there is a '.' in the name, insert
"_64" before the final '.' unless it is already preceded by
"_64".  (For a 32-bit AMPL, the rules are similar, with the roles
of "32" and "64" reversed.)  The builtin set _LIBS still shows
the names by which libraries were loaded, whereas option AMPLFUNC
reflects the adjusted names.  The unload command operates on
names in _LIBS.  Temporarily, at least, you can suppress the new
behavior by specifying "option map_32_64 0;".
  Under MS Windows, add a test to the "load" command to ignore
shared libraries (DLLs) compiled for the wrong number of address
bits.  (With more sensible operating systems, such libraries
simply fail to load.)
  Change the default value for $ampl_libpath from "" to the
directory containing the AMPL binary and (if different) the
current directory.  Absent command-line option -i (invoke
ampl "-i?" for details), or an incoming $AMPLFUNC value, look
for both amplfunc.dll and ampltabl.dll at startup by the AMPL
search rules (rather, for ampltabl.dll, than by system-dependent
rules).

20120214
  On Unix-like systems, add command history processing similar to
that of the "sw" program under MS Windows.  The up- and down-arrow
keys move among the history lines, and the left- and right-arrow
keys move left or right one character in the current line.  Where
available, the "home" key moves to the start of the current line,
the "end" key moves to the end of the current line, page-up moves up
10 lines and page-down moves down 10 lines.  The control-right-arrow
key moves forward one alphanumeric "word", and the control-left-arrow
key moves left one "word".  Control-W deletes the preceding "word".
Control-D sends the current text without ending the line and signals
end-of-file when there is no current text.  Command history can be
turned off by invoking "ampl -vi2 ..."; the -vi2 must come first;
invoke
	ampl "-v?"
for more on -v options.

20120306
  Add command-line option --version:  when given as the sole
command-line argument, --version causes AMPL to print its version
and exit, regardless of any needed license file or manager.
  Adjust default computation of $ampl_libdirs to work correctly
with non-ASCII directory names (where "ASCII" means "7-bit ASCII").
Note that AMPL has long handled UTF-8 encoding of Unicode, which
can involve non-ASCII characters.  On MS Windows systems, use of
non-ASCII names can cause confusion when different code pages
are involved.  This is an issue outside the scope of AMPL.

20120317
  Map NaNs in sets to a specific quiet NaN and fix a bug in testing
whether NaN is a set member.  Here is an example that now works and
previously misbehaved:
    set S; param p{S}; data; param :S: p := NaN 37; print p[NaN];

20120406
  Remove ampl_libpath from the default _LOCAL_OPTIONS (thus making
$ampl_libpath available for possible use by the proxy table handle).

20120507
  Add a test to explicitly enforce an implicit limit of 199 on the
lengths of names.

20120515
  On MS Windows systems, if $TMPDIR has a nonblank value, use that
value as the temporary directory name (as documented in the AMPL book).
Otherwise use the value of $TEMP.  Hitherto only $TEMP was considered
on MS Windows systems.  (On most MS Windows systems, $TMPDIR is not
set, but $TEMP is set to a non-blank value by default; on such
systems, this change should be invisible.)

20120522
  On MS Windows systems, when process creation fails, report the
path to the program that would not start, rather than just the
program's name.

20120530
  Under MS Windows, if $Path does not appear in the incoming
environment but $PATH does, use $PATH rather than $Path as
the list of directories in which "solve" and "shell" commands
should look for programs.  Usually $Path is set, but at least
some versions of the MinGW shell supply $PATH rather than $Path.

20120601
  Extend warning that variables in subscripts are not yet allowed
to most subscripts (not just subscripts on variables).

20120831
  Add Addrandinit to struct AmplExports, which is available to
imported functions in al->AE.  An imported function or, more likely
the funcadd_ASL function that makes known the imported functions in
an imported-function library, can invoke addrandinit(rsi,v)
(i.e., ae->Addrandinit(ae,rsi,v)) with apparent signature

	typedef void (*RandSeedSetter)(void*, unsigned long);
	void addrandinit(RandSeedSetter rsi, void*);

to have rsi(v,$randseed) called initially with the current value
of $randseed (as an unsigned long) and again whenever option randseed
is assigned a value.  This is meant to supply a new seed for random
functions provided by the containing imported-function library.
Like calls on at_reset() and unlike calls on at_exit, calls on
addrandinit() are forgotten after a "reset;".  Note that a "reset;"
causes the funcadd_ASL() routines in all currently loaded imported
function libraries to be called again.

20121116
  When a defined variable involves piecewise-linear terms but is
otherwise linear and when convexity (or concavity) permits all
appearances of the defined variable in constraints and objectives
to be linearized, do so.

20130109
  Add an error message about a constraint, objective, or defined
variable declaration that has a piecewise-linear expression with
a variable in the slope or breakpoint list.  In printing commands
(display, print, printf), variables can appear in slope and
breakpoint lists, but not in declarations.

20130117
  Diagnose attempts to add "delete" or "purge" commands to a compound
command (e.g., a for or repeat loop) via a "commands" command.  Such
attempts previously could lead to a fault.

20130218
  Add a complaint about integer variables declared with bounds that
when rounded (up for the lower bound, down for the upper bound) to
integer values are inconsistent.  Example:

	var x integer >= 0.1, <= 0.9;
	maximize obj: x;
	solve; display x;
	# Previously said "Solution determined by presolve;"
	# now says "Infeasible constraints determined by presolve."

20130510
  Not previously noted in the change log are generic synonyms
for logical constraints:

	Name		Meaning
	_nlogcons	number of logical constraints before presolve
			in the current problem
	_snlogcons	number of logical constraints after presolve,
			i.e., as seen by the solver
	_logcon		indexed by {1 .. _nlogcons}: true (1) or
			false (0) values of logical constraints before
			presolve
	_slogcon	indexed by {1 .. _snlogcons}: true or false
			values (1 or 0) of logical constraints seen
			by the solver
	_logconname	indexed by {1 .. _nlogcons}: names of logical
			constraints in the current problem
	_slogconname	indexed by {1 .. _snlogcons}: names of logical
			constraints seen by the solver

20130621
  Adjust "load", "unload", and "reload" commands to canonicalize
library names by simplifying paths and, for MS Windows, changing / to \.
For example, "a/b/../c/foo.dll" becomes "a/c/foo.dll" and "./foo.dll"
becomes "foo.dll" in _LIBS and the associated test for whether the
library is already loaded.  Nonetheless, "./foo.dll" is sought only in
the current directory, whereas "foo.dll" is sought in the directories
listed in $ampl_libpath.  It is still possible to load the same
library more than once by using a different name for it, either via a
hard or symbolic link, by using such variations as "foo.dll",
"foo_32.dll", "foo_64.dll", or using a name that starts with "../" or
otherwise involves enough instances of "/../" to take the apparent
name above the current directory.  Now _LIBS reflects the canonicalized
names, and possibly simplified full pathnames appear in $AMPLFUNC.

20130704
  Adjustments for handling problems with >= 2^31 Jacobian nonzeros.
New .nl file format codes z, h, and (temporarily, for debugging)
B, G, H, and Z.  The z format has a "K" section instead of a "k"
section; the K section has Jacobian column lengths rather than the
the k section's sums of such lengths, permitting entries in the K
section to be encoded with 32-bit integers as long as the problem
has less than 2^31 variables.  (Like the b format, the z format is
a binary format that only uses 32-bit integers.  The z format uses
2 bytes per operation code rather than 4, so it is somewhat more
compact than the b format.)  When the b format is requested and
the problem has at least 2^31 Jacobian nonzeros, AMPL now uses
the z format instead.
  The h format is another binary format, one using 64-bit integers,
permitting encoding of problems with more than 2^31 variables or
constraints.  The current AMPL cannot process such large problems,
but a later version should be able to do so, at least when
appropriately compiled.  The h format is available now to permit
preparing solvers that can handle it.
  Debugging format G is like g, except that it has a K section.
Debugging formats B, H, and Z are like b, h, and z, but with
reversed byte encoding of binary numbers.  (The solver interface
library adjusts for byte ordering if necessary, allowing one to
generate a binary .nl file on a big-endian machine and solve it
on a little-endian machine or vice versa.)
  Reading the new formats requires use of versions >= 20130703 of
ASL, the AMPL/solver interface library.

20130815
  Adjust 64-bit MS Windows binary to avoid trouble (not yet seen)
with "sw" if ever a thread handle cannot be represented in 32 bits.

20131010
  Have "write ...", including "write 0;", set solve_result_num = 299
if presolve finds the problem infeasible.

20131018
  When a solution is read by "solve" or "solution" and no dual
variables are present but could have been, and when presolve
has removed some constraints, delay the computation of dual
variables for the removed constraints until something, such
as a request to print dual values, requires them to be computed
from the then current primal and dual variable values (possibly left
over from a previous "solve" or still at their initial values).

20131108
  Allow "display X;" when X is a param or set indexed over an
infinite set and X has a recursive default value.  The display
just shows the values that so far had to be computed.  Example:

  param f{i in Integers} default if i <= 1 then 1 else i*f[i-1];
  set S{i in Integers} ordered default if i <= 1 then {1}
	else S[i-1] union {i*last(S[i-1])};
  display f[6], S[6], f, S;

20131213
  Allow execution to continue after "write 0;" gives an error message
about infeasibility.

20140130
  Though not previously documented, $csvdisplay_header = 2 has long
caused the csvdisplay command to give headers of the form Expr_1,
Expr_2, ..., whereas the default ($$csvdisplay_header = 1) used the
declared name when appropriate in the header and used Expr_n when the
n-th item was an expression other than a declared name.

20140220
  Improve simplification of piecewise-linear terms:  after summing
terms applied to the same variable, combine adjacent pieces with the
same slope and turn the term into a linear term if only one slope
remains.  Example:
	var x;
	minimize zot: <<1,2;-1,2,-3>>x + sin(x) + <<1,2;1,-2,3>>x;
	solexpand; # now gives sin(x) rather than something messier
  Add new processing for defined variables whose value is a piecewise-
linear expression on a single variable.  Now the example
	var x;
	var y = 0.5*x + <<1,2,4;-3,1,-1,2>> x + .7;
	var z = <<-2.3, -1.55, -.8, 1.7, 3.7; -5, 4, -3, 2, -1, 6>> y;
	minimize zot: 2*y;
	minimize zot2: 3*z;
gives the same .nl file (but for roundoff) as
	var x;
	minimize zot: 2*(0.5*x + <<1,2,4;-3,1,-1,2>> x + .7);
	minimize zot2: 3*<<-1.2,-.4,0.6,0.9,1,7/6,5/3,2,3,4,4.2,5.2,6;
				-15, 2.5, -5, 7.5, -10, 6, -4.5, 3,
				-1, 1.5, -7.5, 5, -2.5, 15>> x + 4.2;
For now, at least, the "16" bit of $pl_linearize suppresses the new
processing, i.e., "option pl_linearize 17" gives the former default
behavior, and the "32" bit of $pl_linearize causes explicit
definitions of variables involved in nonconvex (or nonconcave, as
appropriate) piecewise-linear terms when this gives a sparser
representation.  Thus "option pl_linearize 33" may sometimes result
in the output of "solexpand;" being slightly easier to read.  Today's
changes include recording more pl_linearize bits, including 4 and 8,
which may cause changes to .sol files when nondefault $presolve_fixeps
values matter.

20140312
  New option cmdtrace: "option cmdtrace 1;" turns on printing of the
name of each command executed and, when the command comes from a file
other than stdin, the filename and line number of the command.

20140524
  Extend test for "no variables, but lower bound = ..." to fix a glitch
with "option presolve 0" (which is often a bad idea) whereby infeasible
constraints with no variables were eliminated when defined variables
were present.  When no defined variables are present, such infeasible
constraints are passed to the solver.

20140630
  Adjust computation of _ampl_elapsed_time, _shell_elapsed_time,
_solve_elapsed time to reduce roundoff error and, for MS Windows,
to report elapsed time rather than CPU time.
  Fix glitches with adjustments for some complementarity constraints
that could lead to incorrect .nl files with some uses of nonlinear
defined variables or to incorrectly reading dual variables from a .sol
file.
  Fix a bug with _con[i].status that could give "log" instead of "sub".
  New option display_set_1col is analogous to $display_1col, but applies
to sets:  if S is a set with $display_set_1col >= card(S), the
"display S;" lists each element of S on a separate line.  The default
value 0 for $display_set_1col causes no changes to the hitherto seen
behavior of "display S;".

20141016
  On Unix-like systems, arrange to catch and report surprise SIGPIPE
signals.

20141024
  Do not regard "q" as "quit" if followed on the same line by other
text, other than ";".

20141128
  On nonlinear problems, defer computation of dual variables for
constraints eliminated by presolve until they are needed for some
reason (such as display), lest inability to compute derivatives of
nonlinear expressions should give an error message and terminate the
run.

20150313
  Adjust printf format %q to treat non-ASCII Unicode characters as
alphabetic characters.  This affects the display command's printing
of set members.

20150422
  When history is desired (e.g., stdin is not a file) but cannot be
instantiated, allow "solve" and "shell" to work without the need to
invoke "ampl -vi2".  This is only known to be relevant to 32-bit
Alpine systems.

20150827
  Under "ampl -b4", have error messages show context.

20151104
  Complain in more cases about objectives and constraints involving
NaNs or bounds with inappropriately signed Infinity.  (There was
already a complaint about linear expressions with a Nan or Infinity
as a coefficient.)

20151130
  Disallow defined variables in IN or INOUT table declarations.

20160119
  Arrange for defined variables that do not affect constraints
not to participate in presolve deductions.  Under unusual conditions,
such defined variables could cause incorrect deductions.
  When more than 64 output files would be open, close the least
recently used file and reopen it when necessary.

20160211
  Adjust debugging option nl_permute so when permutations are
suppressed, the .nl file will indicate numbers of nonlinear
constraints and variables based on the last nonlinear constraint
or variable.  Give a Caution message when suppressing permutations
affects the .nl file.  The "8" and "16" bits of $nl_permute can
suppress these new Cautions.  $nl_permute is now the sum of
	 1 ==> reorder constraints
	 2 ==> reorder variables
	 4 ==> reorder objectives
	 8 ==> suppress Caution about constraints
	16 ==> suppress Caution about variables
The default value for $nl_permute remains 3.  Option nl_permute
is not meant for use with solvers; great confusion may arise if
binary or integer variables are present.  Most users should avoid
fiddling with $nl_permute.

20160221
  New builtin function date(fmt,t) returns a string representing time
t (as returned by the builtin time() function), formatted according to
fmt (a character string).  Either or both t and fmt may be omitted;
time() is assumed if t is omitted and "%Y%m%d %H:%M:%S" is assumed if
fmt is omitted; otherwise, date(t,fmt) and date(fmt,t) are treated
alike.  The expected usual usage is simply date(), i.e., omitting
both arguments, as in

	print date();

to print the current time and date.  The fmt string is similar to that
allowed for the "date" command on many Unix-like systems, such as
Linux and AIX; fmt is interpreted by the widely available strftime()
library function.  In short, various letters, when preceded by a %
character, are replaced by details derived from the time t.  Some,
indicated by * below, may be affected by the current locale.  Commonly
available are

	%a	abbreviated day of the week*
	%A	day of the week, fully spelled out*
	%b	abbreviated month*
	%B	month, fully spelled out*
	%c	date and time as preferred in the current locale*
	%d	two-digit day of the month (1-31)
	%H	2-digit hour (00-23) based on 24-hour clock
	%I	2-digit hour (00-11) based on 12-hour clock
	%j	day of year (001-366)
	%m	2-digit month (01-12)
	%M	2-digit minute (00-59)
	%p	AM or PM	
	%U	week number of the current year (00-53), with week 01
		starting on the first Sunday of the year
	%w	day of the week (0-6), with Sunday = 0
	%W	week number of the current year (00-53), with week 01
		starting on the first Monday of the year
	%x	preferred date representation*
	%X	preferred time representation (without date)*
	%y	2-digit year (no century)
	%Y	4-digit year
	%Z	time zone
	%%	% character

Also available on some systems are

	%C	similar to %c, but also including the timezone
	%D	%m/%d/%y
	%e	like %d, but with a space in place of a leading 0
	%F	%Y-%m-%d
	%G	ISO 8601 4-digit year
	%g	IS0 8601 2-digit year -- no century digits
	%h	%b
	%k	like %H, but with leading zero changed to blank
	%l	like %I, but with leading zero changed to blank
	%n	newline character
	%P	lower-case %p: am or pm
	%s	number of seconds since 19700101 00:00:00 UTC
	%t	tab character
	%T	%H:%M:%S
	%u	decimal day of the week (1-7), with Monday = 1
	%V	ISO 8601 week number (01-53)
	%z	the numeric time zone: +-hhmm (4 digits)

On some systems, a #, E, or O may be inserted between % and some of
the function letters indicated above to modify the conversion.  Please
experiment to see what works on your system.
  The fmt string may begin with %K or %L, which are removed and affect
whether the rest of the fmt string reflects UTC time, formerly known
as Greenwich Mean Time (%K), or local time (%L).  Local time is the
default, which %L simply confirms.  If nothing remains after an
initial %K or %L is removed, the default fmt is assumed.  Thus
date("%K") shows the current UTC time.
  The builtin ctime() function is extended to behave like date(), but
with fmt = "%a %b %d %H:%M:%S %Y" assumed if fmt is omitted or is
empty after an initial %K or %L is removed.  Thus ctime("%K") shows
the current UTC time, but formatted differently than date("%K").

20160325
  When a shell command gives shell_exitcode > abs($shell_exitcode_max),
resulting in "<BREAK>", show an option command that would have
suppressed the "<BREAK>".  The new printing of an option command
is suppressed if $shell_exitcode_max < 0.  Previously the test for
issuing a "<BREAK>" was whether shell_exitcode > $shell_exitcode_max.

20160519
  Adjust ordering of sections in .nl files so bounds on variables
and constraint bodies and primal and dual initial guesses precede
constraint bodies.  This change should be invisible to solvers that
use the AMPL/solver interface library.  For other solvers, turning
on the "32" bit of $nl_permute will restore the old ordering.  This
interpretation of the "32" bit will eventually be removed unless we
hear of a good reason to retain it.

20160530
  Extend option infeas_clear so "option infeas_clear 3;" allows
"write" and "solve" commands to proceed when presolve detects
infeasibility.  In short, possible values for infeas_clear are now
	0 ==> always suppress "solve" and "write"
	1 ==> allow a second "solve" or "write" to proceed when
		reading stdin in interactive mode (default)
	2 ==> always allow a second "solve" or "write" to proceed
	3 ==> always allow "solve" or "write" to proceed

20161025
  Adjust presolve to eliminate some defined variables that were
previously rendered as constant-valued variables.  Example:

	var x{i in 1..2} := i+1;
	var y = 1 / x[2];	# appeared in the .nl file as a
	s.t. c: x[2] = 3;	# defined var with constant value 1/3
	minimize zot: (x[1] - y)^2;

20161209
  New command-line option -x sss instructs AMPL to run for at most
about sss wall-clock seconds.  It may run 4 or 5 seconds longer,
particularly under MS Windows, to allow solvers to stop and clean up.
On Unix-like systems, such as Linux, signals SIGHUP (when not being
ignored, e.g., by running under nohup), SIGINT, SIGQUIT and SIGTERM
are now passed to solvers, and SIGHUP (when not ignored) and SIGTERM
cause the AMPL session to terminate.  When the solver is a binary,
the solver now sees all of SIGHUP, SIGINT, SIGQUIT and SIGTERM.
When the solver is a shell script, results depend on what "trap"
settings have been specified.
  New system parameters (automatically maintained, and not adjustable,
e.g., in "let" commands):
	_session_time = wall-clock seconds consumed
	_session_maxtime = wall-clock session specified by "-x sss"
When -x is not given on the AMPL command-line, _session_maxtime is
reported to be 0.

20170111
  Adjust history processing on Unix-like systems so when the current
input line is nonempty, control-D behave like "Delete", deleting the
character under the cursor.  Also arrange for the tab key to do
filename-completion (when unambiguous, except on 32-bit Sparc Solaris).

20170412
  Under -Rw, disable history.

20170531
  Allow an optional comma between phrases in a set declaration
(as already allowed in param, variable, objective, and constraint
declarations -- none of which is described in the AMPL book).
  Allow commas to separate values in "read" commands.

20170616
  Honor "ordered" in

	set S{1..1} ordered; param p{S[1]};
	data; param :S[1]: p := b 1 a 2 c 3;
	display p; # previously ignored the S[1]'s ordering

and in

	set GEN ordered; param a {GEN};
	table Gen IN /*...*/: [GEN] IN, a;
	read table Generators; display a;

20170621
  In commands of the form

	for outerloop {...} {
		for {...} {
			...
			commands foo;
			...
			}
		}

have a "break outerloop;" in file foo terminate the outer loop.

20170706
  Extend the change of 20170621 so in the context of

	for outerloop {...} {
		for {...} {
			...
			commands foo;
			...
			}
		}

a "break outerloop;" in a file in a nest of "commands" commands
in file foo will terminate the outer loop.

20170731
  Allow "and" as a synonym for "for all" and "or" as a synonym for
"there exists".  Thus the logical expressions
	there exists {i in I} b[i]
and
	or {i in I} b[i]
are treated alike, and the logical expressions
	for all all {i in I} b[i]
and
	and {i in I} b[i]
are treated alike.
  In "shell" and "solve" commands, ignore "> filename" and ">> filename"
redirections when the file was specified in "option logfile" (which
makes no sense).  Previously a fault resulted.

20170914
  Add a Caution for "(numeric expression) & (numeric expression)", which
converts both numeric values to strings and concatenates them.  Since
dummy variables may have string or numeric values, the new Caution is not
given for "A & B" when A or B is a dummy variable.

20170924
  Fix a fault that arose under unusual conditions.
  New debug options table_debug (default 0) and table_debug_template
(default "%.dbtab") can cause tables in the format of .tab files to be
read or written rather than or in addition to files specified for
"read table" and "write table" commands.  For this to work, option
table_debug_template must contain one % character and otherwise only
alphanumeric characters or plus, minus, underscore or period.
When $table_debug and $table_debug_template indicate a .tab-format
file, the file's name is obtained by substituting the declared table
name for the % character in $table_debug_template; $table_debug is
the sum of

	1 ==> "read table" should read the .tab-format file
		and ignore the 2 bit if set in $table_debug
	2 ==> "read table" should write the .tab-format file
	4 ==> "write table" should also write the .tab-format file
	8 ==> "write table" should not write the declared table

While the builtin .tab file handlers only act on file names that
end with ".tab", the .tab-format files controlled by $table_debug
act on the constructed .tab-format file names.

20170925
  In $table_debug_template just require one % and no white space.

20171002
  Have printf format %q quote ".".

20171111
  Circumvent scurrilous behavior by Microsoft's ODBC software --
unexpectedly changing arithmetic details when x8087 instructions are
involved.  This was seen in a "write table" example.  A "read table"
likely would also have caused the trouble, which was seen in the
round() function, but would also affect other binary <--> decimal
conversions.

20171122
  Extend option allow_NaN to apply to more contexts, e.g., computation
of reduced costs when some constraints are removed by presolve.
Example of using $allow_NaN in an interactive session:
	ampl: var x{1..2} >= 0;
	ampl: minimize zot: sum{i in 1..2} (x[i] - i)^2 + sqrt(x[1]);
	ampl: s.t. vex: x[1] + x[2] <= 1;
	ampl: s.t. c1: x[1] <= 0;
	ampl: solve;
	MINOS 5.51: optimal solution found.
	1 iterations, objective 2
	Nonlin evals: obj = 4, grad = 3.
	ampl: display x.rc;
	Error executing "display" command:
	
	        Error differentiating zot: can't compute sqrt'(0).
	ampl: option allow_NaN 1;
	ampl: display x.rc;
	x.rc [*] :=
	1  NaN
	2    0
	;

20180115
  Expand and clarify "ampl -v?" output.
  On Unix-like systems, extend history mechanism so escape-backspace
acts like control-w, omitting the preceding word; control-a acts like
the "Home" key, moving the cursor to the start of the line; control-e
acts like the "End" key, moving the cursor to the end of the line;
escape-b moves the cursor back one word; escape-f, like control-w,
moves the cursor ahead one word; and escape-d omits the word ahead.
  On Unix-like systems, suppress history if at least one input file is
given on the command line and no command-line input files are "-" (a
single dash).  This can be overridden by invoking "ampl -vi4 ...",
which could matter if an "include -" phrase appears.

20180123
  Fix a bug that could arise under complicated conditions with
problems involving piecewise-linear terms or "var ... in set..."
constructions.

20180125
  Adjust history mechanism so it may deal better with unexpected
escape sequences, and use a larger stacksize in hopes of avoiding
a bug in Red Hat's glibc-2.17-196.el7_4.2.x86_64.

20180308
  Under -b (block-mode), suppress superfluous command-identification
lines that sometimes appeared.

20180316
  Fix a bug with a sequence of solves involving fixing some but not
all members of a set of variables, then unfixing all of the set of
variables, then doing something causing the set of variables in
question to be regenerated.  The previously fixed variables were
erroneously held fixed.  The update of 20170706 seems to have
revealed, but not caused, this bug.

20180416
  Withdraw option funcwarn and the associated -f command-line option;
now the former "option funcwarn 1" is always assumed.  Fix a bug with
the sequence
	solve;
	# error message about an unavailable function
	load some_library.dll;	# to provide the function
	solve;
The constraint or objective in question was not regenerated using the
newly available function.
  Fix a bug with "load library" providing a decoding function:
the "read" command was not properly handled after decoding
started.  Relevant documentation may only be provided on request.

20180417
  "Invisible" tweak to yesterday's changes.

20180423
  Fix a bug with a double inequality giving a bound on a defined
variable and another constraint giving a stronger bound on the
variable.  The other bound on the variable was sometimes lost.

20180503
  When single-stepping, try to recover from input errors rather
than simply exiting.
  Fix a bug, introduced 20171122, with "param :setname: parname"
followed by a : ... := table (called a value-table on p. 476 of
the AMPL book).  For example,

	set S dimen 2; param p{S};
	data; param :S: p
		: X Y Z :=
		A 1 2 3
		B 4 . 6;
	display S, p;

will now work again.

20180511
  Fix a bug (possible fault) in processing utterly pointless input
of the form "data; param p := .;".

20180519
  Fix a rarely seen bug (e.g., losing some variable or constraint
indices) that bit after an update, such as reordering a set, caused
some entities to be reinstantiated.
  Compute tanh(x) and tanh'(x) for large x without complaint.

20180522
  In data sections, accept "param :setname: parname (tr)" followed
by a : ... := table (called a value-table on p. 476 of
the AMPL book).  For example,

	set S dimen 2; param p{S};
	data; param :S: p (tr)
		: X Y Z :=
		A 1 2 3
		B 4 . 6;
	display S, p;

will now work, with X, Y, and Z as first members of the tuples in S.

20180525
  Compute tanh(x) and tanh'(x) for large |x| without complaint.

20180618
  Fix a bug with string-valued imported functions that seems to have
crept in with version 20070301:  calls involving at least one numeric
argument faulted.  An example using amplfunc.dll compiled from
http://ampl.com/netlib/ampl/solvers/funclink/funcadd.c:

	function kth symbolic; print kth(2,1,3,5); # faulted

20180624
  Add variant "write 1;" of "write 0;" that does not emit the message
"No files written: option outopt is 0."
  Have printf honor field widths given with %c format specifiers.
For example,

	printf "X%4cY%-4cZ\n", 'a', 'b';

formerly printed "XaYbZ" and now prints "X   aYb   Z".

20180820
  Fix a bug seen in scripts of the form

	repeat {
		solve;
		break;
		}
	print solve_exitcode;

in which the "solve" commands gives a nonzero solve_exitcode.
  Modification to changes of 20160325:  when a shell or solve command
gives shell_exitcode > $shell_exitcode_max > 0 or
solve_exitcode > $solve_exitcode_max > 0, respectively, show an option
command that would have suppressed a "<BREAK>" message.  The shell or
solve command behaves as if a BREAK (control-C) had been received
if $shell_exitcode > abs($shell_exitcode_max)
or $solve_exitcode > abs($solve_exitcode_max), respectively.
  Another change:  "exit code" is changed to "exit value" in some
messages.  When a shell or solve process ends, it returns an "exitcode
value" that is assigned to option shell_exitcode or solve_exitcode,
respectively, and on Unix-like systems (such as Linux and MacOSX) is
computed as

	256*(exit_value) + termination_code

in which termination_code is zero if the shell or solve process
ended by calling exit(exit_value) or returning exit_value and is
nonzero if the exit() call could not be reached due to a
segmentation fault (i.e., serious bug) or similar error.  On MS
Windows systems, the "exitcode value" is the exit_value.

20180822
  Fix bugs with simplifying some logical constraints, leading
to an error message about an "unexpected nonvariable type".

20180927
  When an error message of the form
	z must be redeclared without y.val
appears due to y being a defined variable, add text of the form
	because y is a defined variable
	and y.val is not allowed here.
to the error message.

20181005
  Fix a bug in combining linear expressions or with defined variables
involving piecewise-linear terms.  A fault was sometimes possible.

20181018
  Fix a bug with limiting the number of file descriptors in use.
When a file was closed so its file descriptor could be reused and
later was reopened with a different file descriptor, a saved copy
of the original descriptor was not updated.  This caused a surprising
read failure in the example that brought this bug to light.

20181022
  Fix a rarely seen bug (fault) in saving variable values.
  Fix a bug with _ampl_time, _ampl_system_time, _ampl_user_time,
_ampl_elapsed_time, and _session_time, which were not updated
after their first evaluation.

20181026
  Convert "param x random" to "var x random".  Issue a Caution about
this conversion unless "option randparam_warn 0;" has been specified.

20181102
  Fix a bug introduced 20181022 in the logic that determines which
entities need to be updated.  Some were not updated when they should
have been (in a complicated example).

20181114
  Fix bugs (faults) with a "model" or "data" commands of the forms
	model (if t == 1 then 'a.mod' else 'b.mod')
and
	model (if t == 1 then 'a.mod' else if t == 2 then 'b.mod')

20181123
  Fix a seldom-seen bug in saving primal and dual variable values
after the indexing set of the variable or constraint in question has
decreased sufficiently in size.  There was a fault in the
illustrating example.
  Fix a fault with nonlinear use of a defined variable involving
a piecewise-linear term.  Example:

	var x in [-1,10];
	var y = <<1,3,6;-1,1,-1,1>> x;
	minimize zot: exp(2*y); solve; # faulted

20181210
  Fix a bug (fault or worse) with sequences of solves in which a
variable or constraint indexing set starts with positive size, then is
updated to have size 0, then is updated to have size larger than 1.

20181217
  Fix a bug with iterated "let" in the following example:
	set S; var x{S}; let S := {}; /*empty: card(S) = 0*/
	let{i in S} x[i] := i^2 + 1;
	let S := 1..4; /* now card(S) >= 2 */
	let{i in S} x[i] := i^2 + 2;	# corrupted memory

20190122
  Fix a bug with data updates that cause some variables to disappear
completely after being used in a "solve".  A fault (or worse) was
possible in a subsequent solve.

20190130
  When presolve complains about an infeasible constraint with no
variables, retain the constraint, so a second "write" or "solve"
command will emit an infeasible problem when option infeas_clear
has its default value 1, or when a .nl file is written by
a command-line invocation of the form "ampl -ogfoo foo.mod".

20190207
  New command
	sleep [expr];
causes the AMPL process to be suspended for expr seconds (default 1).
  Give a more detailed error message for attempts to use a function
with out-args in a declaration.
  Fix a bug introduced in 20190130 that affected problems with
piecewise-linear terms.
  Adjust the logic for "option randseed 0;" to avoid some trouble
with repeated uses of this option:  on some 64-bit systems, after
a while "option randseed 0;" seemed not to affect the sequence
of pseudo-random numbers generated.

20190220
  Fix a fault with too few dummy variables in an indexing.  Example:
	set S; set T = {t in {S,S}}; # faulted

20190223
  Fix a bug (fault) with "reset options;" in a compound command, such
as a loop.

20190418
  In the contexts
	commands filename;
	data filename
	include filename
	model filename
if filename starts with "<", the remainder of filename is taken to
be a command and operands to be interpreted by the host operating
system (e.g., by /bin/sh on Unix systems), and the standard output
of the command is processed as the contents of filename.  For example,

	model '< gzip -dc foo.mod.gz foo.dat.gz'
and
	model '< unzip -p zap.zip zap.mod zap.dat'

would decompress foo.mod.gz and foo.dat.gz or would extract zap.mod
and zap.dat from zap.zip and take them as input.  (For this to work,
foo.dat or zap.dat would need to begin with "data;".)  For "model",
"data", and "commands" (but not "include")
	model < filename
	data < filename
	commands < filename;
are treated as though filename began with "<", so, .e.g,

	model '< gzip -dc foo.mod.gz foo.dat.gz'
and
	model < 'gzip -dc foo.mod.gz foo.dat.gz'

are treated alike.

20190505
  Redo update of 20190220 (to fix a fault with too few dummy variables
in an indexing) so the arity of the indexing set is maintained.
  Adjust error processing so in interactive mode (reading from stdin
when, e.g., -vi1 was specified on the command line or when stdin is a
console window), execution of a command is not skipped during error
recovery.

20190510
  Fix a bug (possible fault) sometimes seen with logical expressions
of the form lexpr1 ==> lexpr2 else lexpr3, where the lexprn are
logical expressions.

20190529
  Fix a bug with "display p;" involving declarations of the form
	set S; set T{S} ordered; param p{i in S, T[i]};
When the bug bit, it caused a surprising "display bug!" message.
  Fix a glitch with prompts.  For example, after "include junk" typed
at the "AMPL:" prompt, if file "junk" contained another "include",
such as "data foo.dat", the "AMPL:" prompt was lost at the end of file
"junk".

20190612
  Fix a bug with variable.val:  some expressions were not recomputed
when the value of the variable changed.  (Workaound: use variable
rather than variable.val, which is also easier to read.)
  New option load_funcdcl determines whether imported functions are
implicitly declared when their library is loaded or (new possibility)
when an imported function makes another imported function available:
	0 ==> no (default and the old behavior)
	1 ==> yes, quietly
	2 ==> yes, with a report of the declaration.
Explicit declarations after implicit declarations are allowed.

20190616
  Fix a bug with cleaning up after a "not defined" error in a
nested-loop context.  An infinite loop or surprising error message
was possible.  Example:

	set A dimen 2; data; set A := (1,a) (2,b);
	for{i in 1..2}
		for{j in {'a','b'}}
			print {k in U[j]} i,j,k; # U was not declared

20190617
  Fix a bug (possible fault), introduced in version 20190418, with
"option single_step 1; commands 'somefile';".
  Until further unforeseeable changes come along that require solvers
to react to the AMPL version, the date that sometimes appears on line
1 of a .nl file is now fixed at 20190616.  This should facilitate some
kinds of testing, as it removes a gratuitous cause for differences in
.nl files generated with different AMPL versions, at least those with
versions >= 20190616.
  Forbid "load" commands from overriding existing declarations.

20190716
  New builtin symbolic parameter _presolve_messages is assigned
messages produced by presolve.  New option show_presolve_messages
(default 1) determines whether the presolve messages are printed.

20190814
  Fix a bug with suffixes initialized in declarations:  when some
initial values were 0, it was possible for some subsequent initial
values to be lost (converted to 0).  Example:

	set A = 1..5; set C = {2,3,5};
	var x {a in A} >= 0 integer suffix relax if a in C then 1 else 0;
	display x.relax; # x[5].relax was lost.

  Fix a glitch with Unicode (UTF8) characters affecting "show"
commands and the output of "ampl -D" on input without commands.  Some
text was lost.  Examples (requiring a window that understands UTF8):
"ampl" on
	set pá; param cost {pá} > 0; show pá, cost;
"ampl -D" on
	set pá; param cost {pá} > 0; data; set pá := dód cär;

  Fix a glitch introduced 20190716 with demo licenses:  the error
message for oversize problems was lost.

20190817
  Complain when an input file ends in the middle of a comment.

20190819
  Fix a glitch under MS Windows with block mode ("ampl -b ...")
and option show_presolve_messages (at its default value).

20190824
  Fix some seldom-seen bugs (faults or possible misbehavior), e.g.,
with slices in some command sequences or with bad data-section syntax.

20190830
  Fix a bug with suffixes:  after an indexed constraint goes from
having some suffix values to none, due to a decrease in the
indexing-set cardinality, a subsequent addition to the indexing set
could lead to trouble.

20190911
  Fix a rarely-seen glitch (wrong value computed) with a defined
involving a piecewise-linear term applied to another defined variable
involving a piecewise-linear term.
  Fix a fault that was possible with inappropriate outopt values,
such as "write zfoo;".  Invoking "ampl -o?" shows the allowed values.

20190919
  Fix a potential compiler-dependent bug (not yet actually seen) on
64-bit systems with first(Set), last(Set), and card(Set).

20190927
  Fix an obscure fault.

20191001
  Fix bugs with "astatus" and "exitcode" suffixes on problems.
  Banish one reason for a rarely seen "OPDIV botch in e2v" message.

20191015
  Fix memory leaks with "print", "printf", and "display".

20191031
  Fix a bug that arose under complicated conditions involving
the member() function.
  Arrange for "option cmdtrace 1;" to print command numbers with
full precision, which only matters if many commands are executed.

20191108
  Fix a glitch with blockmode ("ampl -b ...") introduced 20190819.
Error messages from presolve had the wrong label.

20191116
  Fix a bug with "drop" and "restore" that arose under complicated
and rarely seen conditions.  Memory corruption was possible.

20191223
  Fix a bug with presolve on problems with piecewise-linear terms:
an incorrect array reference could have an out-of-bounds subscript
on problems of the "right" size.

20200110
  Add a Caution about ignoring a duplicate ":=" in a data section.
The example that caused this addition led to a fault (now avoided).

20200810
  Fix bugs in computing the value of a defined variable,
which was sometimes wrong if the right-hand side involved a
piecewise-linear term or a defined variable with a linear part.

20201019
  Have the delete command recover more memory from constraints
and variables.

20201110
  New option let_domain_check (default 0).  The domain check in
let, introduced 20201031, is now only done if $let_domain_check
is nonzero.  Someone showed us an example where the test greatly
increased run time.

20210123
  When too much memory is used, normally an error message such as
 Bug: Too much memory used -- 4276003800 bytes; couldn't get 32780 more.
appears, but if a memory block needed to print how much memory was
used cannot be allocated, simply print "Too much memory used."
rather than silently quitting.

20210215
  Fix a bug illustrated by:

	param p{i in 1..3} = if (i == 1) then 0 else p[i-1]+1;
	show p;
	display p;
	show p;		# printed ":=" rather than "="

20210220
  Fix an error-message bug seen with interactive input.  If file foo
contains

	set A; var x{A};
	s.t. c{i in A}: x[i] == 1;
	data; set A := a b c;

then the interactive input

	ampl: include foo
	ampl: let{i in B} x[i] := 1;

produced error messages

	B is not defined
	context:  let{i in  >>> B} <<<  x[i] := 1;

	x is already defined
	context:  let{i in B}  >>> x[ <<< i] := 1;

Today's change suppresses the erroneous error message about x.
More generally, today's change only allows the first error message
for a statement to appear.

20210226
  Recant change of 20210220, as it suppressed syntax errors in
interactive declarations.
  Fix a possible bug (e.g., fault) with recursive parameters.
  New command "reset check;" causes all "check" statements to be
executed afresh by a "check" or "solve" or "solution" or "write"
command.  Normally a check statement is only executed at the first
"check" or "solve" or "solution" or "write" command after the check
statement's declaration or at a later "check" or "solve" or "solution"
or "write" command if something the statement is testing has changed.

20210326
  Fix a presolve bug with the default option var_bounds = 1 setting:
if a constraint was dropped because it implied a stronger bound on an
integer variable, the stronger bound was not conveyed to the solver.
(Specifying "option var_bounds 2" was a work-around.)
  Fix a presolve bug with complementarity constraints.  Removing a
constraint after fixing all the variables in it should correctly
resolve a complementarity condition involving the constraint.
  New builtin param _check_failures records how many check statements
failed in the most recent relevant command ("check" or "solve" or
"solution" or "write").

20210330
  Fix a bug with deleting constraints and variables that crept into
version 20201019.  The bug manifested itself at the second delete.

20210414
  New option log_file_flush.  If option log_file is given and
$log_file_flush is 1, $log_file is flushed after each write to it.
By default (option log_file_flush 0), $log_file is only flushed
when the input file is stdin.

20210505
  Fix bugs with data sections appearing after something causes an
entity's declared default value to be used.  Unless a "reset data" or
"update data" command has given permission for the data section to
provide a new value for the entity, there should be an error message.
Example:

	var v default .1;
	display v;	# cause default to be used
	data;
	var v := 0.08;	# should (but did not) elicit an error message
	display v;	# showed the old value, .1
			# For sets, showed the new value.
	# With today's bug fix and with "reset data;" or "reset data p;"
	# or "update data;" or "update data p;" before "data;",
	# "display v;" would show the new value.

20210521
  Fix a bug in the MS Windows binaries with "write ...; solve;".
Binaries for other platforms (such as Linux and MacOS) are unaffected.

20210531
  Fix a bug with complementarity constraints that could incorrectly lead
to the message "presolve finds a nonsquare complementarity system", e.g.,
with econ.mod and econ.dat in the AMPL book.
  Change from 200 to 299 the value assigned to solve_result_num when
presolve eliminates all variables and finds an infeasible constraint.
Now whenever presolve finds the problem infeasible, solve_result_num
should be set to 299.  It is set to 99 when presolve solves a feasible
problem.

20210613
  Fix a couple of glitches in the "expand" and "solexpand" commands:
incorrect printing (under complicated conditions) of comments
"Eliminated by presolve" and "free row".

20210625
  Fix a performance bug:  after a "delete variable" command, some
commands, such as "display", could cause presolve to run
unnecessarily.

20210714
  Fix another performance bug:  assignments to suffixes, such as
"relax", should not cause presolve to run in preparation for the
assignment.
  When bailing out due to option eexit, dump presolve messages before
stopping.
  Under MS Windows, allow blanks in option TMPDIR (a bad idea).
Blanks in $TMPDIR were already allowed on other systems.

20210731
  Fix an obscure bug:  under complicated conditions, variable.val and
constraint.val did not reflect recent changes.  Example:

	var x; fix x := 3; display x.astatus;
	unfix x; let x := 5;
	display x.val, x;	# printed x.val = 3 rather than 5

20210810
  Fix a bug with split defined variables (where the linear part is
sometimes handled separately) introduced in version 20190824.  An
example on which the bug caused a fault:
	var x := 1;
	var y = 2*x + x^2;
	c: x + y >= 1 complements sin(y) <= .5;
  Fix a bug that, under complicated conditions, affected some problems
with complementarity constraints.

20210906
  Fix a bug with suffixes:  if the suffixed entity had not yet been
instantiated, a fault was possible.  Example:

	var x{i in 1..2} := i;
	var y{1..2};
	s.t. c: sum{i in 1..2} x[i].val * y[i] >= 3;
	expand c; # faulted; workaround: "display x;" before "expand c;"

  Change to when an entity is instantiated:  if the entity depends on
suffix values, changes to those values no longer cause the entity to be
instantiated anew.  In the above example, adding

	let x[1] := 1.5;
	expand c;

will give the same constraint as before -- the change to x[1] == x[1].val
does not cause c to be reinstantiated.  This change is partly to facilitate
scripts that add cutting planes.  It is also necessary for consistency with
a forthcoming new implementation of AMPL (that supports functions in AMPL,
among other things).  AMPL has facilities for causing entities to be
reinstantiated when declared prerequisites change.  For example, changing
the above example to use a named parameter for the coefficients of c
will cause c to be reinstantiated when the parameter values change:

	param p{1..2};
	redeclare s.t. c: sum{i in 1..2} p[i]*y[i] >= 3;
	let {i in 1..2} p[i] := x[i];
	expand c;
	let p[1] := x[1] + 2;
	expand c;

20211222
  After an error message "variable in ...", replace the whole
expression in question by a constant (that can be seen with a "show"
command).  Previously the example
	var a := 12; set S := 4 .. a;
	display S;
(if entered interactively) gave different results on different kinds
of machines.  Now "display S;" should give "set S := ; # empty" and
"show S;" should give "set S = 4 .. 0;".

20220110
  Fix a rarely seen bug with deducing bounds on variables, illustrated by
	var x >= 0; display x.ub; # correctly showed x.ub = Infinity
	var y = max{i in {0}} x;# logically the same as "var y = x;"
	display x.ub;		# incorrectly showed x.ub = 0
Specifying "option presolve 0;" bypassed the bug.
  Fix a bug with handling certain errors.  Example:
	ampl: param p {i in 1..10} := j;

	j is not defined
	context:  param p {i in 1..10} :=  >>> j; <<< 
	ampl: redeclare param p {i in 1..10} := i;

	Ignoring redeclaration of p:
	         system parameters may not be redeclared.
	context:  redeclare param p {i in 1..10} :=  >>> i; <<< 
	ampl: display p;
	Segmentation fault (core dumped)
  Fix a bug with redeclare:
	set X; data; set X := 1;
	redeclare set X ordered;
	update data X; data; set X := 1 2; # faulted

20220119
  Restore some error-handling behavior prior to 20220110.  The changes
of 20220110 sometimes resulted in several error messages per statement.
  Fix a parsing bug in error handling (infinite loop, introduced
20220110) seen with
	set A dimen 2; data; set A := (1,a) (2,b);
	for{i in 1..2}
		for{j in {'a','b'}}
			print {k in U[j]} i,j,k; # U was not declared

20220217
  Fix a bug with "data filename;" in a compound statement.  If a second
such statement appeared in the compound statement with the same filename
after the file was recreated after the first "data filename;", wrong data
was read unless an explicit "close filename;" appeared before the file
was recreated.  Example (under Linux):

	set A;	if (1 < 2) then {
		shell 'echo "set A := a b c;"' >foo;
		data foo
	#	close foo;	# uncomment to bypass bug
		display A;
		shell 'echo "set A := x y z;"' >foo;
		update data A;
		data foo
		display A;
		}

For MS Windows, it is necessary to omit the double quotes in the shell
commands and to add "close foo;" immediately after them.  Then the example
runs correctly.
  Fix an obscure fault with an input file without a final newline that
is directly accessed by "include" at the command prompt.  For example,
if file foo contains just "param/" without a newline character, then
"ampl foo" correctly said
	foo, line 1 (offset 5):
		unexpected end of file
	context:   >>> / <<< 
but (in an interactive AMPL session)
	ampl: include foo
faulted.

20220224
  Fix an off-by-one error in line numbers on some error messages.
For example, if "foo1" said "include foo2", foo2 said "model diet.mod"
and the current directory did not have a file named diet.mod, then
invoking ampl and typing "include foo1" gave

	foo2, line 1 (offset 6):
		Can't find  file "diet.mod"
	context:  model  >>> diet.mod <<< 

	include stack...
		-, line 0 includes
		foo1, line 0 includes
		foo2

rather than

	foo2, line 1 (offset 6):
		Can't find  file "diet.mod"
	context:  model  >>> diet.mod <<< 

	include stack...
		-, line 1 includes
		foo1, line 1 includes
		foo2

20220310
  Fix more error-message bugs.  If foo1 said "include foo2" and
foo2 said "model diet.mod data diet.dat" and the current directory
contained diet.mod but not diet.dat, then invoking ampl and typing
"include foo1" gave a fault.  After changing foo2 by moving
"data diet.dat" to a second line, invoking ampl and typing
"include foo1" gave

	foo2, line 2 (offset 159431244):
		Can't find  file "diet.dat"
	context:  data  >>> diet.dat <<< ;
	
	include stack...
		-, line 1 includes
		foo1, line 1 includes
		foo2

with an erroneous offset.

20220323
  Make option bad_subscripts apply in more cases.  For example,

	set S; var x{S}; data; set S := a b;
	var x := b 2.1 a 1.1 c 3.1; display x;

now gives

	Error executing "display" command:
	error processing var x:
		invalid subscript x['c'] discarded.
	x [*] :=
	a  1.1
	b  2.1
	;

Inserting "option bad_subscripts 0;" before the display command
suppresses the error message.  The default $bad_subscripts is
still 3.
  Fix a bug in displaying several items indexed over a cross-product
of sets, some ordered, some not.  A fault was sometimes possible.
Example:
	set A ordered; set B;
	param x{A, B};
	param y{A, A};
	data; set A := 1; set B := 0;
	param x 1 0 1.1; param y 1 1 2.2;
	display x, y; # The 64-bit binaries faulted; 32-bit did not,
	# nor did "display y, x;".

20220505
  Fix a bug in the "show" command, which did not print default (dual)
values for constraints.  Example:

	var x; s.t. cx default 1: x <= 4;
	show cx;

  Allow suffixes (on variables, constraints, objectives, problems)
to appear in data sections.  As usual for data sections, the name
of a constraint, objective, or problem can be introduced with 
"param" or "var".  For example,

	var x;
	minimize o: (x-3)^2;
	suffix foo;
	data;
	var o.foo 3.2; # or "var o := 3.2"; the ":=" is optional here.
	# or "param o.foo 3.2", etc.

This is meant to make "snapshots" more efficient; there is no checking
whether suffix values are replaced.
  When "option show_write_files 2" is specified and no variables remain
used after presolve, print "# No .nl file written:  no variables used."
  Quietly reduce absurdly large precisions in printf formats.  For
example, "%.410g" faulted.  Now it works and "%.500g" is quietly
reduced to "%.415g".

20220506
  In data sections, when x is a variable, treat x.val as x when x does
not yet have a current value, and similarly for c and c.dual when c is
a constraint.
  In the little example
	var x; data; var x.dual := 3;
change the error message from "dual is not a suffix" to "dual is not
an assignable suffix."  (When x is a defined variable, declared with
"var x = expression;", x.dual is the value of the dual variable for
the implied constraint "x = expression".  Defined variables are
substituted out of the problem, so the solver does not see them, but
sometimes it is desirable to see dual variable values for them.)

20220525
  Redo some binaries to incorporate the fix to printf of 20220505.
Due to a botch, the fix was omitted from some binaries.  If
	printf "%.500g\n", 1;
does not fault, the fix made it into your AMPL binary.

20220621
  Fix a glitch with console input:  if the cursor is at the start
of the current line (perhaps because of pressing the HOME key),
the DELETE key did nothing.
  Increase the longest line that can be recalled correctly with
history and the up and down arrow keys from 1000 to 4000 characters.

20220703
  Fix a glitch introduced in version 20220505:  in data sections, an
unquoted "-" in the subscript of a subscripted set gave an error
message.  Example:

	set S; set T{S}; data;
	set S := 2022-06-26_03;
	set T[2022-06-26_03] := a b c;
	display T;

Changing the third line to

	set T['2022-06-26_03'] := a b c;

was a work-around.

20220730
  Fix a bug with defined variables:  if a defined variable used a
problem variable nonlinearly, another defined variable used the first
one linearly, no other use was made of the problem variable, and the
second defined variable was used nonlinearly, then derivatives with
respect to the problem variable were not computed.  Example:

	set I = 1..3; var x{i in I} := i;
	var v1 = x[1] + x[2]^2;
	var v2 = v1 + x[3]^3;
	minimize obj: v2^2;

Derivatives with respect to x[2] were not computed because of an error
in the .nl file.

20220812
  Fix a bug in the changes of 20220730 that caused a fault with some
uses of defined variables -- only when the changes of 20220730 were
relevant.

20220927
  Fix error a couple of error messages caused by inappropriate uses
of variables.  Previously the (silly) example

	var x >= 0 integer; var y >= 0 integer;
	subj to con: x + y in {0,3,5};
	solve;

got the surprising error message

	presolve, constraint con:
		Logical constraint is always false.
	Infeasible constraints determined by presolve.

Now the second line elicits the error message

	Cannot test whether a variable expression is in a set expression.
	context:  subj to con: x + y in  >>> {0,3,5}; <<< 

This example can be restated as

	var x >= 0 integer; var y >= 0 integer;
	var z in {0,3,5};
	s.t. con: x + y == z;

Previously the second line of the little example

	var x >= 0;
	subj to con: x in {0,3,5};

elicited the surprising error message

	continuous variable in tuple
	context:  subj to con: x in  >>> {0,3,5}; <<< 

Not it gets

	Cannot test whether a variable is in a set expression.
	context:  subj to con: x in  >>> {0,3,5}; <<< 

The example can be rewritten (without complaint) as

	var x in {0,3,5};

For a "var x in set_expr" declaration, AMPL quietly generates binary
variables related by an SOS1 condition and a constraint defining x.

20221008
  Fix a configuration bug in the 64-bit ARM binary that caused a wrong
value for some things, such as Normal01(), to be computed.  With
today's 64-bit ARM binary, "ampl -vvq" will report version 20221008.

20221013
  Fix a bug, introduced in version 20220505, in handling data sections.
Example:
	set A := 1..2; param p{A}; param q{A};
	data;
	param: p q :=
	[*] 1 2.5 3	# erroneously complained about "."
	    2 4 5.6;
	display p, q;

20230317
  Change the error message for
	display intersection{i in 1 .. 0} {i};
from "empty iterated intersection" to "empty iterator in iterated
intersection".
  Make integer[1,10] equivalent to 1..10 instead of (erroneously)
giving an error message.
  Fix a possible fault with "display _var;" on some systems.  (If it does
not fault, then there is not a problem here.)
  Fix a little off-by-one formatting bug in displaying some numeric
values, as in
	display {a in 0..1, b in 0..1} (a, b, if a and b then 1 else 0);
which gave
:      a     b   if a && b then 1    :=
0 0   0     0            0
0 1   0     1            0
1 0   1     0            0
1 1   1     1            1
;
rather than
:     a   b  if a && b then 1    :=
0 0   0   0          0
0 1   0   1          0
1 0   1   0          0
1 1   1   1          1
;
  Show error context in blockmode (invocations of "ampl -b ...").
  Fix some bugs with defined variables involving piecewise-linear terms.
Examples:

	var x1 >= -100 := -100;
	var x2 >= -100 := -100;
	var x3 = 3*x1 - 2*x2 + 100;			# should be 0
	var x4 = 0.5*(3*x1 - 2*x2 - 100 + <<0;-1,1>>x3);# should be -100
	var x5 = 3*x1 + 2*x2 - x4;			# should be -400
	var x6 = 0.5*(3*x1 + 2*x2 + x4 + <<0;-1,1>>x5);	# should be -100, not -275
	display x1, x2, x3, x4, x5, x6;
	reset;
	var x1 := 1;
	var x2 := 2;
	var x3 = 2*x1 - 3*x2;			# should be -4
	var x4 = x1 + 2*x2 + <<0;-1,1>> x3;	# should be 9
	var x5 = x1 + x2 + <<.5;1,2>>x4;	# should be 20.5, not 10.5
	var x6 = 2*x1 + 4*x2 + <<1;2,3>>x2;	# should be 15
	display x1, x2, x3, x4, x5, x6;

  After treating (by default) a constraint of the form
	variable = expression
as acting like the variable were a defined variable, allow "let" to
change the variable rather than having it be computed by the expression.
In the following example,

	var x := 1 >= 0;
	var y; ydef: y = x + <<2;-1,2>> x;

x was actually treated as the defined variable, leading to incorrect behavior
after an assignment to x:

	option solver cplex; solve;
	CPLEX 20.1.0.0: optimal integer solution; objective 0
	0 MIP simplex iterations
	0 branch-and-bound nodes
	Objective = find a feasible point.
	ampl: display x, y;
	x = 2
	y = 0
	let x := 3;
	print x; #printed 2 rather than 3

  Fix a bug in generated names for piecewise-linear terms and unions
of intervals:  when more than one set of constraints was generated,
the same names were used.  Now the generation number is appended,
except for the first set.  Also, change the character separating
components of generated names from '+' to '@'.  Example:

	set S := 1 .. 2; var x{S};
	minimize zot: sum{i in S} <<i;-1,1>> x[i];
	solexpand;

produced

	minimize zot:
		-(zot+x[1]+s)[0] + (zot+x[1]+s)[1] - (zot+x[2]+s)[0]
		+ (zot+x[2]+s)[1];

Now it produces

	minimize zot:
		-(zot@x[1]@s)[0] + (zot@x[1]@s)[1] - (zot@x[2]@s_2)[0] +
		(zot@x[2]@s_2)[1];

  Fix a bug with "let".  After, e.g., a "solve" or "solexpand",
assignments of 0 to variables sometimes appeared to be ignored.
Example:

	var x := 100; var z = 3*x + 2;
	solexpand; let x := 0;
	display x; # showed x = 100 rather than x = 0

  Fix a rarely seen bug that some solvers say "integer infeasible"
when a "hard" piecewise-linear term (neither convex nor concave in
a context that would make the term "easy") might vanish.  Example:

	var x1 >= -100 := -100;
	var x2 >= -100 := -100;
	var x3 = 3*x1 - 2*x2 + 100;
	var x4 = 0.5*(3*x1 - 2*x2 - 100 + <<0;-1,1>>x3);
	var x5 = 3*x1 + 2*x2 - x4 + 9;
	var x6; x6def: x6 = 0.5*(3*x1 + 2*x2 + x4 + <<0;-1,1>>x5);
	minimize o: x6;

(Prior to the current bug fixes, an incorrect .nl file led to a wrong
solution on this example.)
  Fix a bug (fault) in simplifying the right-operand of "or".  Example:

	var x binary; var y binary;
	c: x = 0 or x = 0 and y = 0;
	fix0: y = 0;
	write 0; #faulted

  Fix bugs with supplying suffix values in a data section.  Suffix
values supplied this way might not have been transmitted to a .nl file
or might have caused a fault.
  Fix a presolve bug that only mattered when there are two or more
objectives and at least one piecewise-linear term.
  Change the message
	No variables used after elimination of defined variables.
to
	No variables used.
  Fix a bug with the alldisjoint function, which should be true if its
arguments are all distinct sets.  (The sets may have some set members
in common, but alldisjoint should be true if all the sets are distinct
and false if two or more of the sets have all the same elements.)
  Fix a bug in evaluating defined variables in unusual circumstances,
such as a "solve;" followed by an objective command for a previously
declared objective, followed by a display command involving defined
variables.  Current variable values were sometimes not used in
evaluating the defined variables.

20230407
  Fix some bugs, such as a fault, introduced in version 20230317 that
afflicted problems with complementarity constraints.
  Fix a glitch on the third line of the .nl header:  when
complementarity constraints were present and "option presolve 0;" was
specified, nonlinear complementarities were counted as linear
complementarities.
  Fix trouble with ord(a), next(a), and prev(a) when a runs over a
subscripted set with subscripts involving dummy variables of a "for"
loop.  Example:

	set A; set B{A} ordered;
	data; set A := a b;
	set B[a] := c d;
	set B[b] := e f;
	for{a in A, b in B[a]} print a, b, ord(b); #faulted

  Change alldisjoint(...) to alldistinct(...), still true when ...
are all different sets and false otherwise.  Order is ignored, so
alldistinct({'a','b'}, {'b','a'}) is false.  New logical function
alldisjoint(...) is true if ... are all disjoint sets and false
otherwise.
  When linearizing piecewise-linear terms, honor values of declared
variables.  Previously introduced variables were presented to solvers
with initial values of 0.  Now they are presented with initial values
that depend on the declared variables' current values.  This may only
matter to nonlinear solvers.

20230421
  Fix a bug that prevented suffixes on logical constraints from being
conveyed to the .nl file (except in the special case of no algebraic
constraints, in which case the first suffix on a logical constraint
was conveyed).
  Fix a bug introduced in 20230407 with certain uses of nested "for"
loops.  (It's more efficient to avoid "for" loops when iterated
commands suffice.)
  Fix a bug with generation of integer intervals.  Now the following
works:

	set S := integer[0, 5];
	display S;

20230426
  Only print one "not within" error message (instead possibly of
several).  Example:

	set S; set A;
	set B{S} within A;
	data; set S := a b;
	set A := d e f g;
	set B[a] := h i;
	set B[b] := k l;
	display B;

  Disable some possibly inappropriate tests on entities assigned by
"let".  Examples that used to elicit error messages:

	param T; set A = 1..T; set B within A;
	let T := 6; let B := {i in A: i mod 2 = 0};
	display A, B;
	let T := 5; let B := {i in A: i mod 3 = 0}; # elicited error msg
	display A, B; # now works correctly
	reset; # Begin another example
	param T; param p{1..2} != T;
	data; param p := 1 5 2 4; param T := 5;
	let p[1] := 2; # elicited error msg
	display p; # now works correctly

20230516
  Fix bugs introduced 20230426 in some "let" statements for an entity
declared with a side condition, such as a >= expression.

20230816
  Fix a couple of bugs with debugging options -G and -O.  (If you do
not know what they do, you do not need them.)
  Fix a rarely seen memory-overwrite bug with multiple declared
problems.

20230918
  Fix a fault with reading suffix values in a data section.  Example:

	var x{i in 1 .. 2};
	minimize zot{j in 1 .. 3} : sum{i in 1 .. 2} (x[i] - (i + j))^2;
	data;
	param: x.sstatus_num :=
		1 2;
	var x :=
	 1 2
	 2 3;

  Fix a fault simplifying logical expressions involving <==>.  The bug
only bit when the <==> had to be retained but its right-hand side
could be simplified.
  In data sections, for a variable v and constraint c, let v.val
denote the current (primal) value of v and let c.dual denote the
current dual value of c.  Hitherto v.val and v were treated alike, as
were c.dual and c, in both cases giving initial values used for the
first solve.  This change is for the benefit of "snapshot".
  Make the $AMPLFUNC found at startup the $$AMPLFUNC value, so
it survives a "reset option;" command.
  New debugging option -w causes AMPL to give return code 0 when
exiting after producing various error messages.
  Fix a glitch (fault) illustrated by

	var x{i in 1..2} integer := i;
	c: x[1] < x[2]; # logical constraint
	print c; #faulted

Note that if c is a logical constraint, then c.val and c should be
treated alike, but changing "print c;" to "print c.val;" in the above
example avoided the fault.
  When 'e' appears in ($solver & '_auxfiles'), so that a .env file
containing the current environment is written by the solve command,
remove the .env file at the end of the solve, like other temporary
files, such as the .nl file.  When 'e' appears in $auxfiles, have
the write command write a .env file.

20231012
  Fix a glitch in reading values in solution (.sol) files for suffixes
on logical constraints.
  Fix a bug with a new problem after solving a problem with a
"var ... in set_expr" declaration when the new problem does not
involve that variable.  Constraints and variables used to
implement the "in set_expr" phrase were erroneously included
in the new problem.

20231129
  Fix a small performance bug in logical constraints that allowed,
e.g., "|| 0" to creep into the .nl file in unusual cases.  An example
is complicated.
  Fix a bug (seen in a complicated example) in the ordering of
_sconnames; entities should be in declare order.
  When expanding logical constraints by expand or solexpand commands,
force the constraint body onto a new line.
  Do not show the solver logical constraints that are always true.
  New builtin suffix .lno for constraints is positive for logical
constraints seen by solvers, 0 for algebraic constraints seen by
solvers, whereas .sno is now 0 for logical constraints seen by solvers
and positive for algebraic constraints seen by solvers.  Thus if c is
declared a logical constraint, c.lno + c.sno > 0 if the constraint is
seen by solvers.  If presolve turns c into an algebraic constraint,
then c.sno > 0.  If c.lno > 0, then _slogcon[c.lno] is the logical
constraint presented to solvers, and if c.sno > 0, then _scon[c.sno]
is the algebraic constraint presented to solvers.
  Fix a solexpand bug with logical constraints converted by presolve
to algebraic constraints.  Example:

	var x{1..3} >= 0;
	c1: x[1] = .5;
	c2: x[1] > .4 ==> x[1]^2 + x[2]^2 >= 1;
	minimize zot: 2*x[2] + 3*x[3];
	solexpand; # said subject to c2:x[2]^2 + 0.75;
	# rather than
	#subject to c2:
	#	x[2]^2 >= 0.75;

In the example just given, "display c2.lno, c2.sno;" now shows

	c2.lno = 0
	c2.sno = 1

  New builtin suffix .domain for variables to indicate the kind of
values a variable can take:

	0 ==> floating-point (double precision)
	1 ==> integer
	2 ==> in a discrete set
	3 ==> in a union of intervals

The default .domain is 0, but a variable's declaration can specify the
other possibilities.  Specifying a variable's domain to be a single
interval gives .domain 0 and has the same effect as giving explicit
lower and upper bounds.  Integer variables can have nonintegral
values, e.g., due to a "let" command or a "solve" command, and can
have a nonzero .relax suffix to indicate that solvers should view them
as continuous.  Binary variables are integer variables with lower
bound 0 and upper bound 1.

  Additional feature:  it seems we neglected to describe the count
operator in the AMPL book.  It has one of the forms

	count(list_of_expressions)
	count {indexing} (list_of_expressions)

In the second form, dummies from the indexing can be used in the
list_of_expressions.  Both forms return the number of expressions
that are true (if logical) or nonzero (if arithmetic).

20240105
  Fix a bug, introduced in version 20231129, in writing .row files
for problems containing logical constraints.  (Most problems do not
involve such constraints, and .row files are not written by default).
For example, in the (silly) script

	set I = 1..9;
	var x{I};
	function myfunc;
	var t{i in 1..3} = x[i]^2 + 1 + sum{j in 8..9} (i+j)*x[j];
	var u{i in 1..2} = x[7+i]^2 + 2 + sinh(x[1] + 2*t[2] + 6*x[6]);
	maximize zip: if t[2] >= 0 then -t[2]^3 else -t[2]^2;
	minimize zap: sin(t[1]) + cos(2*t[2]) + 4*x[4] + 5*x[5] + x[6]^2 + x[7]^2;
	minimize zot: cosh(<<1,2;3,4,5>>x[6]);
	c1: t[2] + sin(t[3]) <= 4;
	c2: x[5] + cos(x[6]) >= 3;
	c3: sum{i in 3..7} i*x[i] = 1;
	c4: 4.3 <= x[5] + myfunc(t[2], x[3]*x[6], 'some string') <= 15.5;
	b45{i in 4..5}: x[i] >= i;
	b1: x[1] <= 3.5;
	b2: -1 <= x[2] <= 2;
	b3{i in 8..9}: 0 <= x[i] <= 0.1*i;
	lc{i in 1..2}: x[6] + x[7] >= 2.5 ==> (x[5] + x[6]^2)^2 + u[i] <= 35;
	suffix zork;
	let{i in 2.._nvars} _var[i].zork := i;
	option nl_comments 1, auxfiles rc;
	write gsilly;

the resulting silly.row file contained "=u[1]" and "=t[1]" rather than
"lc[1]" and "lc[2]".
  Adjust the third integer in lines that start with V in g format .nl
files to accord with the description in
https://ampl.github.io/nlwrite.pdf.  Whether that integer is 0 or
nonzero is all that really matters and is not affected by this change.
  Fix a bug (fault) with "display _slogcon;" added to the end of the
above example.
  Fix a fault with ord applied to some dummy variables.  Example:

	set I ordered := 1..10;
	for {i in I, j in I:  ord(i) < ord(j)}
		display i, j;

20240110
  New builtin function
	tableindexarity('foo')
analogous to indexarity('foo'), but relevant to table declations,
since tables have their own name space.  Thus the (silly) script

	set A = 1..3; param p{A};
	table test IN: [A], p;
	table test2{a in A} IN: [index] p;
	display indexarity("test"),
		indexarity("test2"),
		tableindexarity("test"),
		tableindexarity("test2");
	param test{A,A,A};
	display indexarity("test");

gives output

	indexarity('test') = -1
	indexarity('test2') = -1
	tableindexarity('test') = 0
	tableindexarity('test2') = 1

	indexarity('test') = 3

20240116
  Fix a glitch in the new tableindexarity function that depended on
whether a table's name was an even or odd member of _TABLES,
illustrated by

	set A = 1..3; param p{A};
	table test1{A} IN: [index] p;
	table test2{A,A} IN: [index] p;
	display tableindexarity('test1');	# gave 0 rather than 1
	display tableindexarity('test2');

  New builtin function environindexarity, analogous to indexarity and
tableindexarity, but for environments.  Example:

	environ foo;
	set A;
	environ goo{A};
	environ zoo{A,A,A};
	display environindexarity('foo'), environindexarity('goo'),
		environindexarity('zoo');
	# environindexarity('foo') = 0
	# environindexarity('goo') = 1
	# environindexarity('zoo') = 3

20240208
  Fix a glitch in converting 0x1.fffffffffffffp-1023 to binary.
(This is very unlikely to affect any real problems.)
The little test script
	param p;
	data;
	param p := 0x1.fffffffffffffp-1023;
	display p, 0x1.fffffffffffffp-1023;
gave
	p = 0
	0 = 0
rather than
	p = 2.22507e-308
	2.2250738585072014e-308 = 2.22507e-308
  Fix a bug, introduced in 20240105, with problems having logical
constraints and an objective.  After a "solve" or "solution" command,
a further "write" without changes omitted "G" segments in the .nl
file.

20240224
  Fix a glitch introduced in version 20231129 seen under "option
presolve 0" (often a bad idea) in problems having complementarity
constraints.

20240308
  Add the possibility of $auxfiles containing 'd', which is treated
like 'c' to cause write commands to emit a .col file that has the
names of defined variables used in the .nl file to appear at the
end of the .col file in the order b, c, o, c1, o1, where
        b = number of defined variables used in both a constraint and
	    an objective;
        c = number of defined variables used in two or more
	    constraints but no objectives;
        o = number of defined variables used in two or more
	    objectives but no constraints;
	c1 = number of defined variables just used in one constraint;
	o1 =  number of defined variables just used in one objective.
  Fix a glitch with printing of expressions involving "prev".
Note that prev(S,n) is rendered as next(S,-n).  Example:

	set S := {1, 2, 3, 4, 5} ordered;
	var x{S} >= 0, integer;
	s.t. con{i in S: i > 2}: x[prev(i,2)] <= x[i];
	param p := prev(3, S, 2);
	show con;
	show p;

should print

	subject to con{i in S: i > 2} : x[next(i, S, -2)] <= x[i];
	param p = next(3, S, -2);

rather than

	subject to con{i in S: i > 2} : x[next(i, S, 2)] <= x[i];
	param p = next(3, S, 2);

20240313
  Fix a fault with write commands when $auxfiles contains "d" and a
defined variable is split into linear and nonlinear parts.  In the
.col file, nonlinear parts are now indicated by a ".nl" suffix.
In the following silly example

	var x;  var y;
	var z = 4*y + y^4 - 6.38;
	var w = 8*x + abs(y) + 18.635;
	minimize O: 5*x + 8*z + 15;
	s.t. C: -200 <= 205*x -17*x^3 - 3.8*w <= 403.2869;
	solexpand;
	option auxfiles rd;
	write gfoo1;

the nonlinear part of z is y^4 and is denoted by z.nl, and the
nonlinear part of w is abs(y) and is denoted by w.nl in the solexpand
output and in foo1.col.

20240519
  Fix a bug with logical constraints eliminated by presolve that led
to an error message of the form "Bug:  presolve has k = ...".
  Fix a fault seen in a complicated example involving two solves.
  Fix a bug introduced in version 20231017 in handling complementarity
constraints in which an inequality could be expressed in a variable
declaration.  Example (from dempe.mod by Sven Leyffer):

	var x;
	var z;
	var w;
	minimize f: (x - 3.5)^2 + (z + 4)^2;
	c1: z - 3 + 2*z*w = 0;
	c2: 0 <= w  complements x - z^2  >= 0;

Solvers sometimes erroneously found this problem to be infeasible.

The bug depended only bit under some conditions; for example, removing
f or c1 in the above example made the bug disappear.
  New bit 128 in pl_linearize to permit defined variables involving
piecewise-linear expressions to be substituted out, which may lead to
slight numerical differences.  Example:

	var X >= 0;
	var Y >= 0;
	C: Y = 2*X + X^2;
	D: Y^2 <= 10;
	minimize zot: X + Y + exp(X + Y)  + <<1,2,3;-1,1,-1,1>> Y;
	option solver knitro; solve;
	Knitro 12.4.0: Locally optimal or satisfactory solution.
	objective 0.9999999997; integrality gap 3.16e-10
	1 nodes; 2 subproblem solves
	# ...
	option pl_linearize 129; solve;
	Knitro 12.4.0: Locally optimal or satisfactory solution.
	objective 1; integrality gap 0
	1 nodes; 2 subproblem solves

  Fix bug introduced in version 20240105 in conveying suffix values
of logical constraints to .nl files.

20240524
  Fix a bug introduced 20240519 with logical constraints.  Example:
	# Adapted from:
	# www.g12.csse.unimelb.edu.au/minizinc/downloads/examples-latest/oss.mzn
	param duration {1..3};
	var Start {1..3} integer >= 0, <= 2809;
	var Makespan integer >= 0, <= 2809;
	minimize Objective: Makespan;
	NoMachineConflicts {m1 in 1..3, m2 in m1+1..3}:
	   Start[m1] + duration[m1] <= Start[m2]  or
	   Start[m2] + duration[m2] <= Start[m1];
	MakespanDefn {m in 1..3}:
	   Start[m] + duration[m] <= Makespan;
	data;
	param duration:=
	   1  121
	   2  333
	   3  343
	;
	solexpand;
	# Incorrectly showed NoMachineConflicts[1,2] thrice and omitted
	# other subscripts of NoMachineConflicts.

20240531
  Fix a recently introduced bug (fault) seen with the little example
	var x; var y;
	maximize o: x + 2*y;
	c: x <= 3 complements y <= 4;

20240619
  Fix a recently introduced bug in models with logical and algebraic
constraints.  Wrong Jacobian details appeared in the .nl file.
  Fix possible trouble in an error message about possible suffix
names.

20240805
  Fix obscure bugs a couple of obscure printing bugs:
"print 6.9999999999999996e-161;" gave 7e161 (a one-bit error with the
usual IEEE 64-bit double arithmetic) and "print .000491831912544516;"
gave 0.0004918319125445159 (which with the same IEEE double arithmetic
rounds to the same value but is longer than necessary).
  Fix a bug with logical constraints seen under complicated conditions.
A simple example seems hard to find.
  Fix a bug seen in the script

	var x;
	data; var x.val := 4.2;
	display x;
	display x, x.val; # printed zeros

  Similarly, fix obscure bugs seen in the scripts

	var x; suffix glop;
	data; var x.init := 4.2; var x.val := 3.7; var x.glop := 5.1;
	display x;
	display x, x.val, x.init, x.glop;
	# printed 0 rather than 3.7 for x and x.val
	update data;
	data; var x.init := 7.4; var x.val := 13.3; var x.glop := 6.1;
	display x, x.val, x.init, x.glop;
	# printed 0 for x, x.val, and x.init

and

	var x{1..3}; suffix glop;
	data; var x.init := 1 4.2 2 4.3 3 4.4;
	var x.val := 1 3.7 2 3.8 3 3.9;
	var x.glop := 1 5.1 2 5.2 3 5.3;
	display x;
	display x, x.val, x.init, x.glop;
	# printed wrong values for x and x.val
	update data;
	data; var x.init := 1 7.4 2 7.5 3 7.6;
	var x.val := 1 13.3 2 13.4 3 13.5;
	var x.glop := 1 6.1 2 6.2 3 6.3;
	display x, x.val, x.init, x.glop;
	# printed wrong values
	update data;
	data;
	var :	x.init	x.val	x.glop :=
	1	1.1	2.1	3.1
	2	1.2	2.2	3.2
	3	1.3	2.3	3.3
	;
	display x, x.val, x.init, x.glop;
	# printed wrong values

Fix bugs computing dual values for constraints eliminated by presolve
when logical constraints are present.  For example,

	set I = 1..4;
	var x{I} >= 0;
	c1: x[1] + x[2] >= 2 ==> x[3] + x[4] <= 3;
	c2: x[2] = 1;
	minimize zot: sum{i in I} i*x[i];
	write 0; # causes presolve to run
	display c2; # said 0 rather than 2

Another example (involving another bug) is

	set I = 1..5;
	var x{I} >= 0;
	c1{j in 1..2}: x[j] + x[3] >= 2 ==> x[3] + x[4] <= 3;
	c2{j in 2..3}: x[j] = 1;
	minimize zot: sum{i in I} i*x[i];
	write 0;
	display c2; # gave c2[3] = 0 rather than  3

  Fix a bug presolving complementarity constraints:  if the
complementarity condition is resolved because one constraint
holds with equality, the other must still be enforced.  Example:

	set I = 1..5; var x{I};
	c: x[1] + 2*x[2] >= 3 complements x[1] + x[3] + 2*x[4] + x[5]^2 <= 7;
	f{i in 1..4}: x[i] = 1;
	solexpand c; # showed a free row rather than a constraint

  Fix a fault seen in

	set I = 1..6; var x{I};
	c: x[1] + 2*x[2] >= 3 complements x[1] + x[3] + 2*x[4] + x[5]^2 <= 7;
	f{i in 1..4}: x[i] = 1;
	l: x[5]^2 >= 1 ==> x[6]^2 <= 2;
	solexpand c, l; # faulted

20240825
  Fix a bug with suffix values in two data sections separated by
a command involving the first suffix.  Example:

	model diet.mod data diet.dat
	suffix sos2;
	data; var Buy.sos2 := BEEF 1 CHK 1 FISH 2 HAM 1 MCH 2 SPG 2 TUR 2;
	display Buy.sos2;
	suffix zork;
	data; var Buy.zork := BEEF 1 CHK 1.5 FISH 2.3;
	display Buy.zork; # displayed all zeros

  Fix a bug with specifying v.val in a data section for a scalar
(i.e., unsubscripted) variable v.  Example:

	var x := 4.3;
	data; param x.val = 3.2;
	display x.val; # showed 0 instead of 3.2

  Fix a glitch introduced 20240805 in handling declared initial
variables under some conditions.  Example:

	var x{i in 1..2} := i + 1.5;
	var y{i in 1..2} = x[i]^2 + 1; # bug not shown with "display x;"
	let x[1] := 4;
	display x, y;	# Showed x[2] = 0 rather than 3.5.
			# To see the bug, need to display both x and y.

20240826
  Fix a bug introduced 20230317 with defined variables used in
piecewise-linear terms.
  Fix a bug that sometimes bit with general piecewise-linear terms
(i.e., those not convex in a context where convexity can be exploited
and are not concave in a context where concavity can be exploited)
introduced 20240519.  An example afflicted by both bugs:

	var x >= 0 <= 10;
	var z = <<1;-1,1>> x;
	c: <<1.1, 2.2; -1, .2, 1>> x + z*z >= 5.41;

20241028
  On machines with arithmetic conforming to IEEE standard 754 (most
modern machines)

	option allow_NaN 2;

now permits handling Infinity and NaN (Not a Number) as specified in
the IEEE standard, whereas

	option allow_NaN 1;

turns Infinity into NaN and the default

	option allow_NaN 0;

causes computations that would involve NaNs and Infinities to give
error messages.  "option allow_NaN 1" has long been available;
"option allow_NaN 2" is new.  For example, if file krf defines and
uses a rational function

	# See W. Kahan (1987), "Presubstitution, and Continued Fractions"
	# http://www.arithmazium.org/classroom/lib/Kahan_Presubstitution_and_Continued_Fractions.pdf
	var x;
	var f = 4 - 3/(x - 2 - 1/(x - 7 + 10/(x - 2 - 2/(x-3))));
	for{i in 1..4} {
		let x := i;
		display x, f;
		}

then by default "ampl krf" says

	x = 1
	Error at _cmdno 3 executing "display" command
	(file f/krf, line 7, offset 255):
	error computing defined variable f:
		can't compute 10/0

but the input "option allow_NaN 2; include krf" gives

	x = 1
	f = 7

	x = 2
	f = 4

	x = 3
	f = 1.6

	x = 4
	f = 2.5

and "option allow_NaN 1; include krf" gives

	x = 1
	f = NaN

	x = 2
	f = NaN

	x = 3
	f = NaN

	x = 4
	f = NaN

If file zork contains

	option allow_NaN 2;
	display exp(3000);
	option allow_NaN 1;
	display exp(3000);
	option allow_NaN 0;
	display exp(3000);

then "ampl zork" gives

	exp(3000) = Infinity

	exp(3000) = NaN

	Error at _cmdno 6 executing "display" command
	(file zork, line 6, offset 98):
		can't evaluate exp(3000): Numerical result out of range

  Fix some bugs with a defined variable involving a piecewise-linear
term applied to another defined variable that involves another
piecewise-linear term, possibly indirectly.  Examples:

	var x1 >= -100 := -100;
	var x2 >= -100 := -100;
	var x3 = 3*x1 - 2*x2 + 100;
	var x4; x4def: x4 = 0.5*(3*x1 - 2*x2 - 100 + <<0;-1,1>>x3);
	var x5 = 3*x1 + 2*x2 - x4 + 9;
	minimize o: 0.5*(3*x1 + 2*x2 + x4 + <<0;-1,1>>x5);
	option solver cplex; solve;
	CPLEX 20.1.0.0: Constraint _scon[1] is not convex quadratic since it is an equality constraint.

With the bug fixed, "solve;" says

	CPLEX 20.1.0.0: optimal integer solution; objective -104.5

Another, similar but more troublesome example is the above with x4
as a defined variable, i.e.,

	var x1 >= -100 := -100;
	var x2 >= -100 := -100;
	var x3 = 3*x1 - 2*x2 + 100;
	var x4 = 0.5*(3*x1 - 2*x2 - 100 + <<0;-1,1>>x3);
	var x5 = 3*x1 + 2*x2 - x4 + 9;
	minimize o: 0.5*(3*x1 + 2*x2 + x4 + <<0;-1,1>>x5);

After the fixes, "option solver cplex; solve;" says

	CPLEX 20.1.0.0: optimal integer solution; objective -104.5
	2 MIP simplex iterations
	0 branch-and-bound nodes

  Fix a bug (corrupted del_mblk arg) with ord(i) when i is a dummy
variable.  The bug appeared in a complicated example; some simple
examples work correctly.

  Allow "from", "to" and some more obscure values to appear as
dummy variables.  Example:

	set A dimen 2; var x{(to,from) in A: to != from};

previously elicited a syntax error message.  Now it is accepted.

20241209
  Recant a change that appeared in version 20240825 because it caused
trouble in a large example.  Smaller examples of the need for this
change are so far unknown.
  Change internal handling of linear defined variables, sometimes
making handling of mpsi.mod
(https://www.ampl.com/ampl/models/mpsi.mod) much faster.  The old
internal handling is used if the "8" bit of option substout is on
(e.g., "option substout 8;" or "option substout 9;").  Processing
of mpsi1.mod (https://www.ampl.com/ampl/models/mpsi1.mod) is still
a bit faster, but not dramatically so.

20250206
  Fix bugs with piecewise-linear terms where a nonconvex term
following a convex term on the same variable was forgotten.  Example:

	var x in [-10,10];
	var y = <<1;2,3>>x;
	minimize Convex: 4*y;
	minimize Nonvex: <<-1;1,-2>> y;
	solexpand; # showed 0 for Nonvex

A related example that gave an invalid .nl file:

	set I = 1..2;
	var x{I} in [-10,10];
	var y{i in I} = <<i;2,3>>x[i];
	var y1{i in I} = <<i;2.1,3.1>>x[i];
	var z = y[1] + 2*y[2];
	var z1 = 3*y1[1] + 4*y1[1];
	minimize zot: sin(z) + cos(z1);

Fix a rarely seen bug in handling nonlinear expressions in the
presence of piecewise-linear terms.  Example:

	var x := .1;
	var y = x^2 + 1;
	var z = <<2; -1,1>> y;
	minimize zot: sin(z);
	print y; # gave .99 rather than 1.01

New bits for option substout:  16 ==> do not treat "var ...  ="
declarations as defining a constraint if the defined variable is used
nonlinearly; because of a bug (fixed in 20250131), AMPL usually
behaved as though the "16" bit was on, but the new default behavior
may result in problems that are easier to solve, despite having
more apparent variables; 32 ==> warn when treating a "var ="
constraint as defining an equation.

20250227
  Fix a bug in printing and "let" commands sometimes seen computing
the value of a defined variable that depends on another defined
variable involving a piecewise-linear term.  For example,

	var x; 
	var y = <<1;2,3>>x; 
	var z = cos(y); 
	minimize zot: sin(z);
	display y, z; # z was wrong

exhibited the bug, but without the "minimize zot" line, the bug did
not bite.
  New bit 256 in option pl_linearize causes piecewise-linear terms
appearing in nonlinear expressions to be rendered as constraints
rather than (nonlinear) OPPLTERM operations.
  Sometimes initial values for some variables generated to express
piecewise-linear terms are now computed differently.  New bit 512 of
option pl_linearize causes the old initialization scheme to be used,
which might make a difference on some (obscure) problems.  Example:

	var x; var y;
	ydef: y = <<-3,-2,-1,2,3; -1.1,1.2,-1.3,1.4,-1.5,1.6>>x;
	minimize zot: (y - 2)^2;

Fix a bug introduced 20241209 that caused a fault on the following
example:

	var x{i in 1..3} >= i := i;
	var y = x[1] + <<1;-1,1>>x[2];
	var z = 3*x[3] + <<1,2;-1,2,-3>>y;
	c: sin(z) >= .5;
	display x, y, z, c.body;