*** Complete AMPL fix and change log ***

Below is a summary of AMPL bug fixes and changes from 30 Nov. 1992.
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

To get the current version of this file, ask netlib to

	send fixlog from ampl

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

19921130:
  Fix bug with option omit_zero_rows: numeric set members were sometimes
treated as zero.  Example:
	option omit_zero_rows;
	display{i in -3..3} i;

19921210:
  Fix bug with print and printf illustrated by
	print{1..3}: 1;
which only printed 1 once.
  Fix bug in detecting common expressions in function arguments.
Example:
	function nfcall(); print{i in 1..3} ncall();
used to print "1 2 3"; now prints "1 1 1" (where ncall returns its
invocation count -- it's one of the examples in the sample funcadd.c).

19921216:
  Fix horrid bug in (and following), e.g., assignment to a new
param of computed values involving a variable other than the
first-declared variable.

19921218:
  Fix possible memory fault with objective.invalid_suffix.
  Fix possible confusion that might have resulted if changed data
caused constraints, objectives, or variables to be regenerated after
some components were dropped or fixed.  For now [until 19930813],
partial drops and fixes are forgotten when an entity is regenerated.
Complete drops/fixes ("drop foo;" or "fix goo;") are still honored.
  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

19921221:
  Fix bug in linearizing "easy" piecewise-linear terms (convex terms
in minimizing objectives, concave in maximizing, etc.) with negative
breakpoints.

19921231:
  Fix bug in
	ampl -omfoo
	model steel.mod; data steel.dat;
	solve;
	write;	# "solve;" had destroyed command-line outopt setting
  Fix bugs in reset data and reading data for parameters that have a
default.  Example:
	set A := 1..3;
	var x{A};
	param b{A} default Uniform01();
	minimize zot: sum{i in A} (x[i] - b[i])^2;
	solve;
	data;
	param b 2 27;	# no complain about b already having
			# a value computed from its default
	reset data b;
	solve;		# the model was not instantiated anew
  Adjust "update data" command to retain previously computed default
values unless explicitly assigned in a subsequent data section.
This mainly affects random default values.
  Fix bugs in the error messages for parameters that have
previously computed default values and (absent "update data"
permission) are given new values in a data section.

19930103:
  Fix bugs with params that have a default that gets evaluated
before a data section provides values for some other components, e.g.:
	param p{1..10} default Uniform01();
	display{i in 9..10} p[i];
	data;param p 1 3 2 37;
	display p;	# wrong values for p
	reset data p;
	display p;
	data; param p 3 23 5 42;
	display p;	# memory fault

19930111:
  Fix obscure bugs: (1) If let or a data section changed a variable that
had been fixed by presolve, subsequent solve commands (without some other
intervening event to provoke running presolve again) did not restore the
variable.  Example:
	var x; var y;
	minimize obj: (x - y)^2;
	c1: x + y >= 7;
	c2: x = 0;
	let x := 9; let y := 11;	# x correctly set to 0
	solve;
	display x,y;
	let x := 9; let y := 11;
	solve;
	display x, y;			# x was left at 9

(2) Constraint.body (etc.) values were not correctly computed after
"let" or a data section changed a variable that had been fixed by
presolve and appeared nonlinearly in the constraint, and similarly
for objective values.
  Adjust logic for deciding if "solve" needs to rewrite the .nl file
(e.g. after a "write" command).  Previously, changes to variables
by "let" examined $reset_initial_guesses at the time of the let
command; now ampl notes that there are changes, and examines the
state of $reset_initial_guesses and $dual_initial_guesses when it is
time to consider rewriting the .nl file.
  Fix bug with "show" revealed in
	var x{1..3};
	minimize zot: sum{i in 1..3} (x[i]-i)^2;
	solve;
	display x;
	show x;
	display x;	# wrong values

19930112:
  Fix infinite loop that could result from typing "end" (rather than
"quit") after certain error messages.
  Keep end-of-file in data mode from causing instantiation of the
current problem if commands have been seen.

19930114:
  Fix bug with -on (or option outopt n...).

19930119:
  Fix bug revealed in

	var x{1..2};
	minimize obj: sum{i in 1..2} (x[i] - i)^2;
	solve;
	show x;
	let {i in 1..2} x[i] := 10;	# memory fault

  Fix bug revealed in

	var x{1..4};
	let {i in 1..4} x[i] := i;	# rhs = unadorned dummy variable
	display x;			# wrong values

  Tweak some details of printing by "show": no more ".if." or "recpd.";
show recursive parameter defs with := rather than "default" (when the
declaration specifies :=).
  Adjust rule for making "if" symbolic or numeric.  This should be
invisible, except that
	var x{i in 1..4} := if i = 1 then i else x[i-1]+2;
now elicits an error message about "variable in := expression".

19930126:
  Adjust solve command to notice changes in $reset_initial_guesses
and $dual_initial_guesses since the last write command.
  Fix bugs in update data:
   1. Some derived sets were not cleared properly.
   2. Check statements were not run again after data updates.
      This could cause some derived sets not to be recomputed.

19930213:
  Coerce if (expression involving variables) to if (expression != 0)
rather than complaining about variables in a logical expression.
  Supply missing subscript in error message for
	set A; param p{A}; data; param p := a 1 a 2;

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).

19930209:
  Adjust interlocks so changing option var_bounds after a write
command will cause a subsequent solve command to write temporary
files (to pass the alternate variable bounds to the solver).

19930303:
  Fix glitch in constraint.lb, .ub, .lbs, .ubs: constraint.lb and .ub
do not require presolve, .lbs and .ubs do.
  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.
  Fix bug (memory fault) in use of constraint[subscript].suffix
before a solve or solution command.
  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.

19930311:
  Fix some bugs in handling defined variables after "let" changes
the problem's size.

19930315:
  Fix bug (giving error msg "invalid refct 0 in opgen") revealed in
	param M{1..2};
	param t := M[1] / (M[1] + M[2]);
	param n := M[1] + M[2];
	param p{1..n} := Uniform01();
	var x{i in 1..2};
	minimize zot: (sum{i in 1..2} (sum{j in 1..n} p[j])*
				(x[i] - M[i])^2)/(M[1] + M[2]);
	data;
	param M := 1 1 2 2;
	print zot;
	print t;
	let M[1] := 3;
	print zot;
  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".

19930319:
  Fix bug after the message "Ignoring solve command because presolve
finds no feasible solution possible."  Neither reset nor drop cleared
the "infeasible" flag.

19930331:
  Fix bug in printf's handling of %e, which rounded to one too few
decimal places.

19930406:
  Fix bug (mix-up of convex versus concave) in linearizing
piecewise-linear constraints.  Convex <= constraints had integer
variables added unnecessarily, and convex >= constraints did not
have them added.
  Fix a bug that currently only matters to osl when a problem contains
some piecewise-linear terms that require adding integer variables
and others that do not require this.

19930409:
  Fix horrid bug in handling slices after "let" or "reset data"
changes the slice's base set.  Some slices were not recomputed.
Example:

	set A dimen 2;
	set I := setof{(i,j) in A} i;
	set B{i in I} := {(i,j) in A};
	data; set A := (a,b) (a,c) (b,c);
	display B;
	reset data; data; set A := (a,y) (w,z);
	display B;

The second display printed

	set B[a] := b c;
	set B[w] := ; # empty

rather than the correct

	set B[x] := y;
	set B[w] := z;

  Fix a bug that sometimes appeared after reset data when e.g. variables
or constraints are indexed over a setof or over a union or subscripted
set whose size was a power of 2.

19930421:
  Fix bug in "let" assigning 0 to a param after an error message about
the param not having a value.

19930422:
  Fix rare memory allocation bug that might be encountered with printf
format %.24e (on systems with 32-bit ints; for 16-bit ints, %.16e could
elicit the bug).  [For the MS-DOS Student Edition, AMPL.EXE has 32-bit
ints, and AMPLC.EXE has 16-bit ints.]

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.
  Fix botch with printf %wg (w = integral width): integers had
as many extra spaces as trailing zeros.

19930514:
  Added an fflush(stderr) that affects placement of error messages
in invocations like
	ampl foo >goo 2>&1
and
	ampl -v2 2>foo
(which should result in an empty foo).
  Fix bugs revealed in

	c1: to_come = 1;
	param p;
	var x coef c1 p := 1/3;
	data; param p := 3;
	let p := 2;
	print c1.body;
	print p;
	print x;	#garbage
and
	model prod.mod
	data prod.dat
	solve;
	reset data;
	data prod.mod	# wrong file
	reset data;
	data prod.dat
	solve;		# memory fault

  Arrange for errors that stop genmod to terminate current file
inclusions (as other errors do); close the files involved.
  Close current input file right after EOF, rather then just before
opening a new (command-line) input file.

19930515:
  Adjust logic so "let" can reference current variable values without
instantiating an updated problem instance (which could elicit
complaints about missing values -- being supplied by "let").
  Avoid a memory fault when a command references an unavailable
subscripted set after the first error message about its absence.
  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.

19930521:
  Fix bugs with "objective" and "drop" that caused these commands
to be ignored when applied to simple objectives or constraints
involving to_come, net_in, or net_out.
  Fix bug in option Cautions, which did not suppress Cautions
about multiple "to" and "from" clauses issued during genmod.
  Modify printing of objectives (by "show" and -M) so
	minimize cars;
prints as on the previous line, rather than (the equivalent)
	minimize cars: 0 + to_come;

19930609:
  Fix memory fault revealed in the sequence
	model diet.mod
	data diet.dat
	reset data;
	data diet.mod	# elicits many error messages
	reset data;	# memory fault

19930615:
  Fix bug in writing .fix file: if the .unv file was not requested
and there were unused variables, they went into the .fix file.
  Fix bug in reporting values of unused variables: they were reported
as having their initial guess, which might be infeasible (i.e., might
not satisfy their bounds).  Now they're adjusted to be in bounds.
  Use stronger deduced variable bounds rather than declared variable
bounds in deciding whether an integer variable is binary.
  Fix error message that complains about duplicate entries in
subscripted sets read in a data section: the subscripts were
wrong and could cause a memory fault.

19930616:
  Fix bug in printing the subscript of an indexed set in certain
error messages.  Example:
	set A;
	set B{A};
	set C := union{i in A} B[i];
	param p{C};
	data;
	set A := a b;
	set B[a] := 1 2;
	# no set B[b];
	display C;	# Bus error while complaining about B[b]

19930630:
  Fix bug introduced 8 Feb. 1993 (with relax_integrality, version
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

19930702:
  Fix bug (e.g., memory fault) sometimes revealed in
	solve; display foo;
where foo is a simple or indexed variable, none of whose components
are used in the model.

19930711:
  Fix bug with defined variables: they were not recomputed after "let"
should have caused them to change.
  Fix bug in recompiling "if" expressions whose "then" or "else"
clauses involve variables.  Recompilation is necessary after some
"let" and "reset data" commands.

19930711:
  Fix bug in restoring variable values when regenerating an instance
(e.g. after "let") whose model has defined variables declared before
some non-defined variables: the subsequent non-defined variables
got some wrong (seemingly random) values.

19930712:
  Fix bug with -L (option linelim 1): nonlinear uses of a linear
defined variable did not cause the right-hand side variables to
be recorded as nonlinear variables.  Example:
	var x;
	var y = x + 4;
	var z = y^2 + 2*y + 1;
	minimize zot: z^2;	# x not recorded as nonlinear
	# bug caused gradient == 0

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.

19930813:
  Change ">=" to ">" in error message "lower bound = ... > upper
bound = ...".
  Fix nasty bug with dropping only some components of an indexed
constraint: unless only the final constraints were dropped,
the constraints got the wrong left- and right-hand side bounds.
  Arrange for $relax_integrality to apply to declared bounds
(which formerly got rounded to integer, even if
		option relax_integrality 1;
was specified).  Apply $presolve_inteps to the rounding of bounds
declared with variables (when $relax_integrality is 0).
  Fix memory fault (or worse) occasionally seen after drop or restore.
  Omit interlock that gave the message "x.rc cannot be used until
after a solve or solution command", which (confusingly) could be
circumvented by displaying x.rc first.
  Stop iterated "let" at first invalid left-hand side subscript.
  Adjust bounds on integer variables to tightest available bounds
(thus always passing bounds of 0 and 1 for variables that the solver
is told are binary variables).
  Retain dropped status of constraints, fixed status of variables,
and current values of scalar variables and dual values of constraints
when the problem changes.  (Current values of subscripted variables
were already retained.  Dual values were previously discarded.)

19930901:
  Fix memory fault in
	set S := {1..5} cross {3..9};
	display {(i,j) in S: i=j};
	display {i in 1..5}: {(i,j) in S};	# memory fault

  Fix optimization bug: constraints or objectives involving a context
of the form
	{i in A, j in B: condition(i,j)}
and a linear expression of the form
	("constant" expression involving i but not j)
	* (expression involving variables)
did not have ("constant" expression involving i but not j)
re-evaluated when i changed but condition(i,j) was false
for the first j in B.  Example:

	param p{i in 1..2, j in 1..2} := 10*i + j;
	var x{i in 1..2} >= 0;
	minimize zot: sum{i in 1..2, k in 1..2: k > 1}
		(sum{j in 1..2} p[i,j]) * sum{L in 1..2} x[L];

  Also fixed: memory fault when the above example is fed to "ampl -O".

19930914:
  Fix bugs in handling "if" expressions yielding symbolic (character)
values used as arguments to functions involving variables (i.e.,
functions that the solver must evaluate).  Example:
	function foo;
	var x;
	minimize zot: foo(x, if x > 3 then 'abc' else 'def');

  Fix bug in handling defined variables whose right-hand sides
involve (linear occurrences of) piecewise-linear terms when option
pl_linearize has its default value 1.
  Fix storage-overwriting bugs that sometimes arose when an
entity was indexed over a set whose cardinality changed from 1
to some larger value (as a result of "let" or "reset data"),
or when the set over which a defined variable is indexed
similarly got (sufficiently) larger.
  Add automatic differentiation facilities for computing reduced
costs of variables in nonlinear problems (and dual values of
definitional constraints and constraints eliminated by presolve).
This eliminates the old message "Ignoring nonlinearities in
computing dual values for constraints eliminated by presolve."
  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.

19930922:
  Fix bus errors and erroneous "bad subscript" messages revealed by
	param n integer >= 0;
	set S := 1..n;
	set T;
	param p {T,S} >= 0;
	check {i in T}: sum {j in S} j * p[i,j] <= 2;
	var x{S,T} >= 0;
	minimize zot: sum{i in S, j in T} x[i,j];
	data;
	param n := 0;
	set T := a b c;
	let n := n + 1;
	let p['a',n] := 1/n;
	let{j in T: j != 'a'} p[j,n] := 2/n;
	solve;
[The "check" first executes at the first "let", then again at the
"solve"; there was a bus error in preparing this second execution
of the "check".  There was also a bus error associated with the
references to n in commands after n had been incremented.  And
there was a bug in handling sets like S that go from being empty
(n = 0) to having members.]

19930928:
  Fix bug in handling a variable indexed over a computed set: if the
set changed and had to be recomputed before the variable was
re-instantiated, saved values could be wrong and (if the set got
sufficiently bigger) a memory fault could result.  Example:
	param n default 2;
	set S := n..n+2;
	var x{i in S};
	let{i in S} x[i] := 10*i;
	display x;
	let n := n + 1;
	display S;	# forces S, but not x, to be recomputed
	display x;	# wrong values -- subscripts not adjusted
  Fix bug in subscripts shown in error messages for failed check
clauses in param declarations (for params with values given in a
data section).
  Apply $solution_precision and $solution_round to dual as well as
primal solution values.
  Fix printf buglet: printf "%04.2d\n",3  printed 0003 rather than 03.
  Fix a bug in solving a problem, increasing the index set of a
variable beyond the next power of 2, and solving a modified problem.
  Fix bugs in combining "option presolve 0" with "fix" and with "fix"
before "let", "solve", or "solution" changes variable values.  Example:
	var x{1..2} >= 0;
	minimize zot: sum{i in 1..2} i*x[i];
	s.t. convex: sum{i in 1..2} x[i] = 1;
	let x[1] := .3;
	fix x[1];	# was ignored if previous "let" was omitted
	option presolve 0;
	solve;		# Memory fault;

---------------
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.

19930930:
  Fix unlikely bug in constraints omitted by an "indexing" of the
form {if false_expression}: the bug only appeared if certain virgin
memory was nonzero in the right way.
  Fix bug in handling variables in flow-of-control tests before any
solve, write, solution, or printing command.  Example:
	var x;
	if x > 0 then print 'Yikes!';
  Fix long-standing memory-overwrite bug in "show" (when listing the
names of all entities of a class, such as all variables or all
constraints) that only bit occasionally.

19931005:
  Fix bug in recovering dual values for constraints eliminated by
presolve when $solution_round or $solution_precision caused the
solution to be rounded:  the rounding occurred before the dual
values were computed, sometimes leading to wrong decisions about
which constraints were active.
  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;".
  Fix bug in computing constraint.ldual and constraint.udual
for constraints after the first one: the decision whether to
the constraint is binding was in error and could memory fault.
  Fix bug in handling constraints and objectives declared with
syntax errors: references to them were botched.
  Fix memory faults with various variable.suffix and
constraint.suffix notations before the first solve or other
command that caused the model to be instantiated fully enough.

19931006:
  Fix bug in handling ord(dummy), next(dummy), prev(dummy),
next(dummy,n), and prev(dummy,n) after "reset data;".  Example:
	set S ordered;
	set T := {i in S, j in S: ord(i) < ord(j)};
	data;
	set S := A B D;
	display T;
	reset data;
	data;
	set S := A B C D;
	display T;		# complained that B was not in S.
Forms that explicitly specify the set involved were handled correctly,
e.g.: set T := {i in S, j in S: ord(i,S) < ord(j,S)};

19931012:
  Arrange for errors in "let" commands to terminate all "for" and
"repeat" loops.
  Fix bugs in use of "first", "last", "card" in "for" and "repeat"
loops.
  Fix bugs in "ordered by" for sets given values in a data section.
Example:
	set A ordered;
	set B ordered by A;
	data; set A := a b c; set B := b c a;
	display B;	# memory fault
  Fix bug in "update data S" where S is a set.  Example:
	set A;
	set B default A;
	data; set A := a b c;
	display B;
	update data B;
	data;
	set B := c a;	# erroneous complaints of duplicate members
	display B;
  Under option relax_integrality, infer a lower bound of 0 and upper
bound of 1 for binary variables.
  Fix bug in handling sequence "if ... then {...} if ...": the
second if should cause the first to be complete (have a null else part).
Example:
	if 1 > 2 then print 3; if 4 < 5 then print 6; else print 7;
should print 6; with the bug, it did nothing.
  Fix bug that caused default expressions not to be evaluated in
situations with incomplete "if" commands.  Example:
	param p default atan(1);
	param p;
	if 1 < 2 then display 3;
	let q := p + 1;		# memory fault
  Fix bug in handling dropped constraints after "let" or "update data"
causes changes to some constraints.  The dropped constraints came
back into the problem.

19931018:
  Fix bug in references to variable.lb or variable.ub for hitherto
unreferenced variables (after, e.g., "solve" or "display" has
caused some entities to be instantiated) that do not appear in any
constraints or objectives.
  Fix memory overwrite bug sometimes seen in displays involving
more than 4000 characters.

19931022:
  Fix an obscure bug that arose in a complicated "display" before
"solve" indirectly involving "prev" or "next".  A simple example
seems hard to create.

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".
  Fix bug (memory fault) introduced 6 Oct. 1993 in handing some
next() and prev() references.
  Fix bug in handling sets involving dummy variables instantiated
by for{...}.  Example:
	for{i in 2..8 by 3} print{j in i..i+2} j;
formerly printed "2 3 4" thrice.
  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.
  Fix bug (perhaps introduced 13 Oct. 1993) in checking changes to
subscripted sets that are ordered by or within another set, and
which have a different number of subscripts than their dimension.

19931201:
  Fix memory fault in
	param p symbolic; let p := 3;	# core dump
  Correct offsets in error messages in PC versions (which with
some compilers were corrupted by MS-DOS's \r\n idiocy).

19931203:
  Fix bug with "let" commands inside "for" or "repeat" loops,
when "let" assigns the same set to two or more other sets.
  Adjust error messages to mention the command being executed
(and, if the command came from a file, to mention the file, line
number, and offset) when an error occurs in a flow-of-control
context, such as a loop.
  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).

19931205:
  Tweak error message for aborted solve commands on Unix systems.

19931206:
  Fix memory fault in referencing (e.g.) an indexed param after
"update data" if the param had no value before "update data".
Example:
	set A; param p{A}; update data;
	data; param :A: p := a 1 b 2;
	display p;	# memory fault

19931217:
  Fix bug in handling card, first, last in certain complicated
situations.  Example:
	set A;
	set B{A};
	param p{i in A} := sum {j in B[i]} card({i} union {j});
	# memory fault when p was instantiated
  Fix some memory leaks in solving sequences of problems.
  Fix memory fault that resulted when $log_file was initially set.

19931220:
  Fix glitch in changes of 13 Nov. 1993 (version 19931113) that caused
the second solve in the following (pathological) example to have optimal
value 3 rather than 6:
	var x >= 0;
	param a := x.val;
	maximize obj: x;
	subject to con: x <= a + 3;
	solve;
	solve;
  Fix an obscure memory fault.
  Change $show_boundstats to $show_boundtol.
  Retain dual values deduced for constaints eliminated by presolve.
They were hitherto lost when a new problem was instantiated.

19931230:
  Fix memory fault in "reset data;" introduced in version 19931113.

19940103:
  Fix glitch introduced in 19931203 in the file name reported by error
messages: in the invocation
	ampl foo -
error messages for commands issued from stdin claimed to be in file foo.

19940113:
  Fix bug that prevented drop and restore from recognizing objectives.

19940119:
  Fix erroneous printing of a file name in error messages for commands
typed on stdin after "reset".  Fix occasional omission of file name
from error messages (under complicated circumstances).
  Adjust a presolve error message so
	var x;
	fix x := 2;
	s.t. zot: x^2 <= 3;
	solve;
gets the error message
	all variables eliminated, but upper bound = -1 < 0
rather than
	no variables, but lower bound = -Infinity, upper = -1
which is now reserved for constraints like
	s.t. zot: 0 <= -1;

19940128:
  Fix bug (possible loop or worse) in handling decimal numbers with
an outrageously negative exponent field, such as 1.8826e-512.
  Adjust hashing to work better on {1..25,1..25,1..25,1..25}.
  Add column headings to output for -t and -T, and added incremental
memory column to -T.
  Fix memory fault resulting from an attempt to display something
about a hitherto unused variable after "solve".  Example:
	var x;
	var y;
	minimize zot: (x-2)^2;
	solve;
	display y.lb;
  Fix rarely seen bug in the interaction of option show_stats and
redirections on printing commands: if a printing command forced
presolve to run (with "option show_stats 1" in effect), the redirection
got lost and the printing went to stdout.

19940203:
  Fix bug that appeared under circumstances for which giving a short
example seems hard: after a "solve" and printing variables that only
appear in dropped constraints, printing components of some variables
(before a display that printed all their values) sometimes showed the
wrong values for them.  Under similar circumstances, a memory fault
(or worse) was possible with nonlinear defined variables.
  Fix possible memory fault in card expressions that involve a
dummy index for a collection of constraints, objectives, checks,
column generation syntax, or iterated function arguments.
Example:
	set A;
	param p{A};
	set B;
	var x{A,B};
	s.t. zot{i in A}: sum {j in B} x[i,j] = card{j in A: p[j] = i};
	# zot suffered a memory fault in "compile".

19940207:
  Fix an obscure memory fault illustrated by
	set P := 1..2;
	param d { P,P };
	set PP := {P,P};
	s.t. symmetry {p1 in P, p2 in P}: d[p1,p2] == d[p2,p1];
	# Silly constraint: should be a check.
	var phi { P } >= 0;
	minimize pot: phi[1];
		for{i in 1..2} {
		for {(p1,p2) in PP: p1 <= p2} {
			let d[p1,p2]:= Uniform01();
			let d[p2,p1] := d[p1,p2];
			}
		display symmetry.slack;	# fault when i = 2
		}

19940208:
  Fix bug introduced in 19940128 in handling subscripted sets of
arity >= 2 and more than 16 elements that are only used for membership
tests: the membership tests could come out wrong.  Example:
	param n integer > 0;
	set A{1..n} dimen 2;
	set B{1..n} dimen 2;
	set C{i in 1..n} := A[i] union B[i];
	set D{1..n};
	set E{i in 1..n} := {j in D[i]: (j,j) in C[i]}; #silly

	let n := 1;
	let A[1] := setof{i in 1..50, j in i-1..i+1} (i,j);
	let B[1] := setof{i in 45..130, j in i-2..i+2} (i,j);
	let D[1] := 40..55;
	display E;	# erroneously empty; should be 40..55

19940210:
  Fix fault in use of next and prev in some contexts.  Example:
	set s circular := 1..7;
	param b {s};
	let {i in s} b[i] := i;
	let {i in s} b[i] := b[next(i)];	# segmentation fault
  Fix remotely possible bug with option log_file and "reset;".

19940217:
  Fix obscure bug with output style 'm' (option outopt m... or
command-line option -om...): initial guesses (in the form expected
by MINOS: "FR INITIAL" lines in the BOUNDS section) were omitted from
MPS files for linear problems.
  Fix "solveout bug" message that could arise under complicated
conditions with -L ("option linelim 1;").
  Fix memory fault possible with -L and variables defined by a linear
expression plus nonzero constant.
  Fix bug, under -L, with nonlinear defined variables that have
linear terms and are only used linearly: if there were no nonlinearly
used nonlinear defined variables with linear terms, an erroneous .nl
file resulted (and ampl could fault).
  Fix possible error associated with options OPTIONS_IN and
OPTIONS_INOUT in the file name shown in error messages for commands.
  Fix bug in interaction of option outopt (or the write command) and
certain display commands that could cause extra work (an an extra
display of presolve statistics if "option show_stats 1" is in effect)
when the session ended with end-of-file (rather than a quit command).

19940303:
  Continue execution when either $OPTIONS_IN or $OPTIONS_INOUT is
unreadable at the start of execution.
  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:
  Fix possible memory fault under "ampl -M" with cross products.
Example:
	set ORIG;   # origins
	set DEST;   # destinations
	set PROD;   # products
	set orig {PROD} within ORIG;
	set dest {PROD} within DEST;
	set links {p in PROD} := orig[p] cross dest[p];
Side effect: A cross B now prints as A cross B rather than {A,B}.
  Turn {A cross B} into {A,B}.
  Do not let "let" assign set values of the wrong arity.
  Fix bugs with "reset data foo;", where foo is a variable or
constraint (a rarely used feature: updating .init and .init0 values).
  Avoid generating unused variables in response to printing commands
(that leave the variables unused).
  Allow "let S := {};" for sets S of arbitrary arity.

19940329:
  Fix bug in handling if expressions involving a symbolic then and
numeric else part, or vice versa: coerce the numeric part to symbolic,
rather than vice versa.

19930401:
  Fix storage allocation bug revealed by complicated interaction of
let with a variable indexed by a growing set.  Example (from Leslie
Hall, giving an erroneous error message about an invalid subscript):
modified data for cut.run from Chvatal exercise 13.2b:
	param roll_width := 181 ;
	param: WIDTHS: orders :=
	        21.625  90
	        20.5    51
	        20      45
	        17.25   11;

19930423:
  Fix error messages for "can't multiply ... by NaN" and "can't
multiply ... by Infinity" to get subscripts in ... right.
  Fix error message for bad subscripts in column-generation
notations (including arc declarations) to get subscripts right.
  Have the reset command close pipe functions.
  Fix bug in handling option commands after "solve" in loops: the
name and value of the option were sometimes overwritten.
  Fix buglet that could force values returned by a solver subsequently
to be forced in bounds when a subsequent "let" or "update data"
causes more variables to be generated.  This has a minor effect
on example looping/multi.run (change by one in number of iterations
in one of the solves).
  Allow any UTF character beyond the 7-bit ASCII characters to appear
in names.
  Fix nasty bug in generating command prompts after "reset;":
if command prompts for named loops were generated before the reset,
such prompts generated after the reset could scribble on memory now
being used for something else.
  Change prompt3 and prompt4 to cmdprompt1 and cmdprompt2.
  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:
  Fix bug that, under rare conditions hard to describe, caused defined
variables sometimes to have the wrong value after "let".
  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.
  Fix some memory faults that were possible after "fix" and "objective"
commands in problems involving defined variables.
  Fix a bug that sometimes kept presolve from running (again in examples
involving defined variables).

19940605:
  Fix storage allocation bug with "reset data".  The bug sometimes
caused subsequent unpredictable results.
  Fix bug with "restore" and defined variables: if "restore" caused
variables declared after variables referenced by the defined variables
to be instantiated, incorrect linear terms were generated, possibly
causing a "solve_out bug" message.  Example:
	var x{1..2} >= 0;
	var w;
	var y{1..1} = sum{i in 1..2} i*x[i];
	minimize zot: 3*y[1];
	foo: 4*x[1] + 5*x[2] = w;
	goo: 6*w = 1;
	drop foo;
	drop goo;
	solve;
	restore foo;
	restore goo;
	solve;	# solve_out bug!
  Fix bug in handling recursive params and sets that have a := clause.
The := values were not recomputed when values upon which they depend
changed. Example:
	param p default 3;
	param q{i in 1..2} := if i == 1 then p else q[1]*p;
	display q;
	let p := 4;
	display q;	# Did not change.
  Complain about "reset data foo;" and "let foo[...] := ...;" and data-
mode assignments to foo if foo has a recursive := clause.

19940608:
  Fix some obscure glitches in error messages.

19940610:
  Fix bug in handling {if lexpr} notation (in an objective or a
constraint declaration, when the lexpr is true).  Example:
	var x{1..2} >= 0;
	minimize zot: x[1] + 2*x[2];
	s.t. C{if 0 == 0}: x[1] + x[2] == 1;
	solve;	# memory fault

19940613:
  Fix possible botch when there is an indexed collection of objectives
and an "objective" command appears (e.g.) before all variables have
had to be instantiated.

19940616:
  Fix glitch in flushing buffers after control-C (i.e., SIGINT) or
after a nonzero return code from a solver.  The glitch was only
apparent with invocations like "ampl <foo" or with include files
that had "reset;" commands.

19940705:
  Fix bug in simplifying nonlinear min and max expressions.  The
bug only bit if presolve fixed at least one variable.

19940707:
  Fix bug involving fix and defined variables: the sequence
	solve;
	fix ...;
	solve;
could (under the right circumstances) encounter a storage-overwrite
bug, leading to subsequent unpredictable behavior (such as a fault).

19940713:
  Fix buglet in computing objective and constraint body values
for objectives and constraints not sent to the solver (and thus
not involved in presolve): outer nonlinear terms were being summed
in reverse order.  This could lead to slightly different values
for the "same" expression.
  Complain at let assignments to defined variables.
  Fix memory-overwrite bug that surfaced after recent changes.  It
appeared under circumstances that are hard to describe and that
arise in multi-commodity flow example looping/multi.*; it's related
to saving values and/or partial fix or drop status of variables
and constraints that themselves are not required for the current
task, but whose index sets may change.

19940803:
  Close $log_file before spawning a process (for shell or, under MS-DOS,
solve), and reopen it when the process ends.  On systems where such
is possible, when $log_file is not '', arrange (without help from the
solver) for the solver's standard output and standard error to be
appended to $log_file.
  Print -t heading every time option times is set to a nonzero integer.
  Fix memory allocation bug that bit when a constraint was partially
dropped (or a variable partially fixed) before, e.g.,
	solve;
	option linelim 1;
	solve;
Changing $linelim caused constraints and variables to be regenerated.
Any other changes causing the partially dropped or fixed entities
to be regenerated would have encountered this bug, which could cause
unpredictable subsequent behavior.  Just changing $linelim no longer
causes entities to be regenerated.

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.

19940828:
  Fix glitch in diagnosing attempts to assign values in a data section
to sets and params whose declarations specify := values.  Example:
	set I := 1..3;
	data;
	set I := 1 2 3;	# memory fault
  Fix (seldom seen) bug in handling output redirections (>filename).
The bug could cause a memory fault or other untoward behavior in shell
and solve commands.
  Fix failure to correctly instantiate variables under complicated
conditions involving "fix".  Example:
	var x{1..2} := 1;
	var y{1..2} >= 0  := sqrt(.5);
	circle: sum{i in 1 .. 2} y[i]^2 = 1;
	var z = x[1]*x[2]^2 + 1;
	minimize zot: (z - 5)^2 + (x[1]-2)^2;
	drop circle;	# now y is not needed
	solve;
	display x, z;
	fix y[1];	# Forces generation of y, which, in this
			# example, caused confusion with z.  A simple
			# "fix y;" did not cause any problem.
	solve;
	display x, z;	# Results should be the same as before
			# but were not.  (In a more elaborate example,
			# the second solve gave a memory fault.)

19940829:
  Supply missing newline in "difference = ..." lines from presolve.
The newline disappeared during the changes for version 19940808.

19940901:
  Fix bug in writing .nl files for problems in which one defined
variable appears exclusively in a single network constraint (node
declaration), and another appears exclusively in a general constraint.
The bug caused solvers to suffer a memory fault.  Example:
	var w;
	var x = 2 - w;
	node foo: net_in + x <= 1;
	var y;
	var z = y + 1;
	goo: z >= 2;

19940908:
  Fix a bug that could bite when linearization of piecewise-linear terms
increases the number of variables beyond the next power of 2.
  Adjust option command and $ notation to treat options (environment
variables) for which AMPL does not provide a default as described
in the AMPL book.  For example,
	option PATH;
now will show the current PATH (used in Unix and MS-DOS systems for
finding the programs invoked by the solve and shell commands), rather
than saying "option PATH ''; #not defined", and if you change option
PATH, then you can now restore it to its original value by saying
	option PATH $$PATH;
  Fix (rarely seen) bug related to common expressions that appear in
entities, only some of which must be recomputed after a change.
The fix could cause some changes in -T (option gentimes 1) output.
Example:
	param p default 1;
	param n integer >= 0 default 1;
	var x{1..n} >= p-1;
	var x1{i in 1..n} = x[i]*p;
	var y >= p-1 <= 2;
	var y1 = y*p;
	zot: sum{i in 1..n}(x[i] + y1) = 1;
	solve;
	let n := n + 1;
	solve;	# fault

19940914:
  Fix memory overwrite possible with the sequence
	1. Do something that generates a variable.
	2. Change something that causes the variable to be
	   regenerated, but with an error (e.g., failed check or bad
	   subscript) that interrupts the regeneration.
	3. Correct the mistake and regenerate the variable.
  Fix bug in simplifying nonlinear sums of two terms, the second of
which can have a unary minus operation "moved up".  (The bug was only
possible if presolve fixed at least one variable, so turning presolve
off avoids the problem.)  Example:
	param p default 0;
	var x := -1;
	var y = if x < 0 then x + 1 / (p - x) else x;
	var z;
	fix_z: z = 0;
	minimize zot: y;

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;
  Fix memory fault in "reset data p" when p has no data but
has been displayed.  Example:
	param p{i in 1..3} default i;
	display p;
	reset data p;	# memory fault
  Fix glitch in handling missing ; after final end-of-file: in
data mode, no error message appeared.
  Fix bug in discarding invalid subscripts: if a data section supplied
values for a param or indexed collection of sets, and the associated
set of subscripts duplicated a valid set, the latter was corrupted.
This bug could only bite when the -o command-line option caused an
instantiated problem to be written out, as in
	ampl -ogfoo foo
Example:
	set J; set K;
	param a{J,K};
	param b{K}; param c{J};
	var x{J};
	minimize zot: sum{k in K} b[k]*(sum{j in J} a[j,k]*x[j])^2
		+ sum{j in J} c[j]*x[j];
	data;
	set J := 1 2 3;
	set K := 1 2 3 4;
	param a : 1 2 3 4 :=
	1 1.1 1.2 1.3 1.4
	2 2.1 2.2 2.3 2.4
	3 3.1 3.2 3.3 3.4 ;
	param b :=
		1 10.1
		2 10.2
		3 10.3
		4 10.4
		;
	param c :=
		1 11.1
		2 11.2
		3 11.3
		4 11.4	# Discarding this bad subscript made all
		;	# values of subscript [4] disappear.
  Fix an unlikely trap due to an uninitialized floating-point value
being read as a signaling NaN (or denormalized number on systems
with faulty hardware or systems software) in the course of a "let"
command that assigns a value for the first time to a subscripted
param.
  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.

19941005:
  Fix bug in handling repeat commands with omitted opt_until.
Example:
	set A default {};
	param p{A};
	repeat {break;}
	display p;	# memory fault
  Fix bug in { comandlist } within compound commands.
  Adjust some details of single-step mode.

19941007:
  Fix bug that caused default set expressions to be recomputed.
Example:
	param p default 3;
	set S default p..p+2;
	display S;
	let p := 7;
	display S;	# S was recomputed
  Change option omit_solmsg to solver_msg (default 1).

19941009:
  Fix glitch in "commands foo;" that kept commands following a
compound command from executing.
  Diagnose premature end of file in "commands foo;".

19941028:
  Fix bugs in let commands assigning to a set or param that
has a default expression when the set or param has not yet been
assigned a value and appears on the right-hand side.  Examples:
	param p{i in 1..3} default i^2;
	let{i in 3..3} p[3] := p[i] + 20;
	display p;	# p[3] was 20 rather than 29
			# did work correctly with p[i] changed to p[3]
	set T {1..4} default {};
	let T[1] := T[1] union {"a"};
	display T;	# wrongly complained invalid subscript T[1]
  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.
  Fix glitch in handling "option relax_integrality 1" when there are
general (nonconvex resp. nonconcave) piecewise-linear terms.
  Fix bug leading to "tva top error" in the following example:
	param S;
	set A;
	param pmin{A} >= 0;
	param pmax{A} >= 0;
	param a{A};
	param b{A};
	param c{A};
	# The consistency checks (>= ... and >...) on r
	# and L are necessary to elicit the bug.
	param r{i in A, s in 1..S}
		>= if s = 1 then 0 else r[i,s-1];
	param L{i in A, s in 1..S-1}
		>  if s = 1 then 0 else L[i,s-1];
	data;
	param  :A:    pmin    pmax	  a     b       c  :=
		a	 2	16	 12	2.4	3
		b	 5	25	103	3.4	2
		c	 1	 5	 24	1.5	5
		d	10	54	105	1	5
		e	 1	 5	  1	5	0
		f	 0	13	 16	2.4	3
		g	 0	22	107	3.4	2
		h	 0	 5	 28	1.5	5
		i	 0	51	109	1	5
		j	 0	 5	  1	5	0
	;
	param S := 6;
	for {i in A}	# back to model/commands mode
		let r[i,1] := b[i];
	##The previous 2 lines would better be written
	##	let{i in A} r[i,1] := b[i];
	##but this did not reveal the bug.
	for {i in A, s in 1..S-1} {
		let L[i,s] := if pmin[i]=pmax[i]
			then pmin[i]+ .1*s
			else pmin[i] + (pmax[i]-pmin[i])/S * s;
		let r[i,s+1] := b[i] + 2*c[i]*L[i,s];
		};
	##The above for loop would execute faster if written
	## let{i in A, s in 1..S-1} L[i,s]   := ...
	## let{i in A, s in 1..S-1} r[i,s+1] := ...
	display r, L;

  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;

19941030:
  Fix bug in reading sets in data mode after "update data": if two
sets previously had the same value (and some command, such as "solve"
or "display" gave occasion to check for sets having the same value),
a data update to one changed the value of both, or (when both had
default values) gave an erroneous error message about no data for
the updated set.  Examples:

	set A;
	set B;
	data;set A := ; set B := ;
	display A,B;
	update data A;
	data; set A := a b c;
	display A,B;	# A = B (erroneously)
	reset;
	set A default {};
	set B default {};
	display A,B;
	updata data A;
	data; set A := a b c;
	display A,B;	# erroneous message about no data for A

19941110:
  Arrange for $prompt2 to be shown for read commands inside general
loop bodies.  It was shown for
	for{i in 1..3} read p[i];
and the preferred
	read{i in 1..3} p[i];
but not for
	for{i in 1..3}{read p[i];}

  Fix glitch that sometimes caused "show" to mention set $display.
Example:
	set A dimen 2;
	param p{A};
	data; param :A: p :=
		a b 1
		b c 2
		a c 3
		;
	option display_1col 1;
	display p;
	show;	# sets:   $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...".
  Fix memory fault in display of items with a declared index
that is an ordered or circular subscripted set with no "by set"
specification.  Example:
	set A;
	set S{A} circular;
	param p{i in A, S[i]};
	data;
	set A := a b;
	set S[a] := c d;
	set S[b] := d e;
	param p := a c 1   a d 2   b d 4   b e 5;
	display p;
  Fix bug with recursive symbolic parameters: if the value of such
a param was another component of the same param, unpredictable
behavior was sometimes possible.  Example:
	set A circular;
	set B circular by A;
	param p{i in A} symbolic := if i in B then i else p[next(i)];
	param q{B};
	param r{i in A} := q[p[i]];
	data;
	set A := A B C D E F G H I J K L M N O P Q R S T U V W X Y Z;
	set B := B F G J P Q V;
	param q := B 1  F 2  G 3  J 4  P 5  Q 6  V 7;
	display r;

19941205:
  Fix error handling common expressions in some sequences of commands,
such as:
	param p in [0,10] default 7;
	param q in [0,p] default 4;
	set Z default 1..p;
	set W default 1..q;	# p is common to q, W, and Z.
	let Z := 1..3;
	display Z,W;	# faulted evaluating [0,p] for q.
  Fix bug in sets involving random functions used in contexts that only
involve membership tests.  Example:
	set ZL := {1..5: Uniform01() < .3};
	param p{i in 1..5} := if i in ZL then 0 else Uniform01() + 1;
	display p;	# only requires testing membership in ZL
	display ZL;	# forces ZL to be fully generated
  Fix bug in handling file redirections introduced with the read
command.  Unpredictable results could result from a memory-overwrite
bug associated with redirections.
  Fix bug (introduced 28 Aug 1994?) in generating variables (without
suitable data changes) that appear syntactically before previously
generated variables.  The bug could cause objectives or constraint
bodies to be miscomputed.  Example:
	var unused >= 0;
	var x{1..2} >= 0;
	convex: x[1] + x[2] = 1;
	var v;
	vdef: v = x[1] + 2*x[2];
	minimize zot: v;
	solve;
	print unused;	# appears syntatically before the other vars
	print zot;	# wrong value

19941209:
  Fix bug in handling variables used as params (not used in any
constraints or objectives).  Instantiating them after a "solve"
could cause a fault in a second "solve" if nothing has intervened
to suitably change the problem.  Example:

	var x{1..2} >= 0;
	var y;
	minimize zot: sum{i in 1..2} i*x[i];
	s.t. convex:  sum{i in 1..2} x[i] = 1;
	solve;
	let y := sum{i in 1..2} i*x[i];
	print y, zot;
	solve;		# fault
  Fix bug in handling repeat loops that appear at the end of the last
input file and do not end with a semicolon.  In one lengthy example,
an infinite loop resulted.

19941212:
  Fix infinite loop in linearizing piecewise-linear terms for problems
with both "easy" terms (not requiring integer programming) and at least
one "hard" term in a constraint eliminated by presolve.  Example:
	var x{1..2} >= 0;
	var y >= 0;
	minimize zot: sum{i in 1..2} i*x[i] + <<.7;3,4>>x[1];
	s.t. convex: sum{i in 1..2} x[i] = 1;
	s.t. bletch: <<.5;1,2>>x[1] >= y;
	s.t. fix_y: y = 0; # presolve deduces that bletch always holds

19941220:
  Fix bug (e.g., memory fault) in regenerating variables after entities
in their declarations, such as their index sets, have changed and the
variables have participated in commands that do not require
instantiating the entire current problem (i.e., most commands other
than solution, solve, or write, unless dot notation forces the problem
to be instantiated).  Example:
	set A ordered;
	var x{A} >= 0 <= 10;
	minimize zip: sum{i in A} ord(i)*x[i];
	var y{i in A: i != last(A)} = x[i] + x[next(i)];
	s.t. zot{i in A: i != last(A)}: y[i] = 1;
	data;
	set A := a b c d;
	solve;
	reset data A;
	data;
	set A := g h i j;
	drop{i in {'g','h'}} zot[i];
	solve;	# fault
  Fix memory-overwrite bug with "update data": the sequence
	data;
	/* read one or more indexed params */
	update data;	# no use made yet of the params just read
	data;
	/* read more of the same params */
caused unpredictable behavior.

19950101:
  Fix bug that crept in sometime in or about fall, 1994: after
data changes (e.g., "reset data" or "let"), objectives or constraints
used with column-generation (including arcs) were sometimes miscomputed.
Example:
	minimize cost;
	param p{i in 1..2} default i;
	var x{i in 1..2} >= 0 obj cost p[i];
	convex: sum{i in 1..2} x[i] = 1;
	solve;	# objective 1 (correctly)
	reset data;
	solve;	# objective 2 (wrong! should be 1)

19950204:
  Fix bug in handling changes to option substout.
  Allow UTF-encoded Unicode in option names.  Fix glitch in reading
UTF in models on machines where chars are signed by default.
  Fix memory allocation bug that could appear after a message
about discarding bad subscripts for a subscripted param (or set)
that was given a single value in a data section, as in
	set A;
	param p{A};
	data; set A := abc; param p := xyz 3;
	display p;
  Fix two bugs with option linelim 1:
1. Nonlinear defined variables involving an additive constant
(nonlinear expression + constant) had the constant added twice to
constraints, objectives, and other defined-variable values linearly
involving the defined variable.  Example (before bug fix):
	ampl: var x;
	ampl: var y = x^2 + 1;
	ampl: var z = 3*y + 4;
	ampl: minimize zot: y + z;
	ampl: option linelim 1;
	ampl: solve;
	MINOS 5.4: optimal solution found.
	2 iterations, objective 19	# should be 8
	ampl: display x,y,z,zot;
	x = -5.42101e-20
	y = 1
	z = 10		# should be 7
	zot = 11	# should be 8
2. In a problem with nonlinear defined variables involving some
variables linearly and only used linearly, the linear contributions
to the nonlinear defined variable were added in twice.  Example (before
bug fix):
	ampl: var x;
	ampl: var y = x^2 - 2*x;
	ampl: var z = 3*y;
	ampl: minimize foo: y + z;
	ampl: option linelim 1;
	ampl: solve;
	MINOS 5.4: optimal solution found.
	2 iterations, objective -30.25	# should be -4 at x = 1
	ampl: display x,y,z,foo;
	x = 2.75
	y = 2.0625
	z = -10.3125	# should be 6.1875 (for x = 2.75): low by 6*2.75
	foo = -8.25	# should be +8.25  (for x = 2.75)
(Without a previous "solve", "solution", or "write", the display
commands in the last two examples computed correct values from the
original expressions.)

19950209:
  Fix a bug (introduced in 19941028) that could cause a memory fault
in or after a "close" command.  (With the bug, "close" commands are
often harmless, which is why we didn't see the bug until now...)

19950211:
  Fix some memory leaks (visible with repeated "reset data" commands).
  Fix glitch that caused
	for {k in 1..10} commands foo;
to read from stdin after reading foo (on every iteration).

19950307:
  Fix bug in handling partially dropped defining constraints.

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.

19950317:
  Fix memory fault in single-stepping when data turn up missing after
an immediate command.
  Fix bugs in subscripted references to _varname, _conname, _objname,
and to dot notation with subscripted _var, _con, _obj.

19950412:
  Recover somewhat better from floating-point exceptions.
  Fix glitch that prevented overriding builtin function names with
problem names.
  Fix bug in an unadvertised check statement syntax:
	check {if lexpr}: lexpr1;
Such checks appeared never to be tested.  Now they are enforced.
  Fix bug that caused
	var x := 2; print x;
to say "ungenerated variable x".
  Enforce the restriction that $values and synonyms (such as _VARS
and _nvars) may not appear in declarations.
  Fix glitch that caused the script

	param p;
	var x;
	minimize zot: (x-p)^2;
	for{i in 1..2}{
		let p := i;
		solve;
		display x, x.rc;
		}
to give

	Error executing "let" command
	error processing objective zot:
	        no value for p

The problem was in handling dot notations (like x.rc) that
require instantiating a model; the script ran correctly with
the param p declaration changed to "param p default 0;".
  Abort reading commands from files other than stdin after
detecting an error.
  Fix glitch that prevented the command following a command
referencing an undeclared entity from being executed (when reading
commands from stdin).  For example,
	print c; # with c not declared
	print 3; # didn't execute
  Fix bugs in the Gamma and Poisson random function (a failure to retain
values across calls that could cause them to compute wrong values or
memory fault).
  Fix bugs in reading dual variable values for partially dropped
constraints from .sol files (in the solve or solution commands),
and in evaluating expressions involving dual values of dropped
constraints.
  Fix glitch that (on some systems) could cause the error message
"adjoin: SBUFLEN (bug!) is too small".
  Fix possible memory fault with single-stepping of break and
continue commands.
  WATCOM binaries are now compiled to circumvent the Pentium divide bug.
  New xref command tells which entities depend directly or
indirectly on specified item.  Syntax:

	xref item_list opt_redirect;

where item_list is a (white-space or comma separated) list of
model entities and opt_redirect is an optional file redirection.
  Preliminary (and possibly still buggy) 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:
  Fix memory fault caused by evaluating variable.val before some
command such as "solve" forces presolve to run.
  Fix bug in switching to a new environment with values that are set
in the current environment but unset in the new one.
  Fix a bug (memory overwrite) in handling subscripted problems.
  Fix bug introduced in version 19950314 that made $solver_oopt
(specification of output format for $solver) and $solver_auxfiles
misbehave.
  Fix bug in handling subscripted objectives with differing constant
terms: if some elements were dropped, the remaining (nondropped) ones
got the wrong constant term (in the .nl file).  This only affected
objective values reported by solvers.
  Fix glitches in expand command that suppressed variables fixed by
presolve and constraints removed by presolve; that was only supposed
to happen for solexpand.
  Adjust the delete and purge commands to act on more than the first
element in their itemlists.
  Allow items of the form "option opname" in the itemlist for delete.
This removes opname from the current environment.
  Adjust "reset;" command to terminate all "commands" and "data"
commands: "reset;" is an immediate command, executed when seen.
Previously, it appeared to work when executed in single-step mode,
but a commands-reading procedure was left running, and chaos could
ensue when it terminated.
  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:
  Fix memory fault in redeclaring objectives.
  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:
  Quote symbolic subscripts in more error messages.
  Expand command: try to keep number*variable on the same line (so far
just for linear terms).
  Fix bug in handling nonlinear defined variables under -L
(option linelim 1) when they involve linear terms and appear linearly
in constraints, objectives, or other defined variables.  Example:
	var x;
	var y = x^2 - 2*x + 1;
	minimize zot: 2*x + 3*y;
	option linelim 1, nl_comments 1;
	write gf; # bogus v number for 3*y (in f.nl)
Fixing this bug led to an improvement in the classification of nonlinear
variables sometimes changes the resulting .nl file (and could slightly
reduce the work some solvers do).  It also revealed a long-standing bug
in the AMPL/solver interface that caused wrong derivatives to be
computed in problems that involve defined variables with right-hand
sides of the form
	another_defined_variable + linear_expression
  Fix bug in printing a hitherto unused variable after a solve.  Example:
	var x{1..2} >= 0;
	var y := 42;
	convex: x[1] + x[2] = 1;
	minimize zot: x[1] + 2*x[2];
	solve;
	display y;	#bogus value
  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.

19950519:
  Fix horrid, long-standing bug with subscripted sets of arity > 1
(apparently introduced in version 19940128):  when such sets had
more than 32 members, tests of membership in them went awry.
Example:
	set A;
	set B{A} dimen 2;
	set C dimen 2;
	set D := {i in A, (j,k) in C diff B[i]};
	data;
	set A := a b;
	set B[a] := (x,x) (x,y);
	set B[b] := (y,x) (y,y);
	set C := (x,x) (w,x) (y,y) (y,z);

	display D;	# correct
	let B['a'] := B['a'] union {1..4,1..8};
			# now B['a'] has more than 32 members
	display D;	# botched: (a,w,x) was erroneously in D

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

19950524:
  Fix bug in presolve's handling of piecewise-linear terms that can be
turned into linear terms because of deduced variable bounds:
constraints (and defined variables) specifying a variable to be the sum
of such terms where mishandled.
  Break out of compound commands when the solution, write, solve
commands fail.

19950530:
  Fix bug (possible memory fault or at least botched error message) in
the error message
	xxx does not work with variables
for xxx = "match", "OPNUM2STR".
  Fix possible glitch in the expand commands printing of nonlinear expressions
(a length value wasn't returned, which could cause some lines to be too long
or too short).
  Fix memory fault with multiple occurrences of the same $env[something].val
expression (under the right circumstances).  Example:
	set A default {'a'};
	environ E{A};
	option E['a'].solver cplex;
	print {a in A}: $E[a].solver, $E[a].solver;	# fault
  Fix bug in testing membership in Cartesian products (under the
right conditions).  Depending on the compiler, the test may have come
out wrong.

19950608
  Fix bug in "reset data;": storage for subscripted items whose
actual index set has only a single member (e.g., which are given
a single value in a data section), and for subscripted sets in
general, went onto the wrong free-list, possibly causing
unpredictable subsequent behavior.

19950614
  Fix bugs in handling strings in the ord, next, and prev functions.
Example:
	set A ordered := {'a', 'b', 'c'};
	print ord('b',A);	# fault
	print next('b',A);	# fault
  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.)
  Fix glitch in dropping nodes: if something forced a dropped node to
be regenerated (because of its appearance in arc declarations),
incorrect constraint names might sometimes appear, unpredictable
behavior might occur because of a memory-overwrite error, and if the
problem had defined variables, an infinite loop resulted (in, e.g.,
solve and write commands).
  Fix bug in handling set expressions in read commands: expressions
within the set expressions were sometimes not computed, which could
cause a memory fault or other untoward behavior.  Example:
	param p default 2;
	param q{1..p};
	read{i in 1..p} q[i];	# memory fault
	1.1
	2.2
	display q;
  Warn of missing subscripts on sets.  (Later we hope to warn about
other missing subscripts, but that's harder.)

19950618
  Fix glitch with "system sets" _PARS, _SETS, etc.: displaying
two at once led to "unexpected subtype 16 in same_set".

19950620
  Fix long-standing bug in handling if expressions in a nonlinear
context when the test can be moved outside of a loop.  Example:
	ampl: var x{1..2,1..2} >= 0;;
	ampl: minimize zot: sum{i in 1..2, j in 1..2}
	ampl?	sin((if i == 2 then 10+j else j)*x[i,j]);
	ampl: solve;
	error processing objective zot:
		unexpected rewclass 4 for op 0x14e2 in ecopy

19950716
  Fix bug in redeclarations of, e.g., indexed params with
default expressions.  Something got freed twice, causing
unpredictable subsequent behavior.
  Increase by a factor of 256 the largest allowed single memory
allocation.  This increases the number of subscripts (members in
indexing set) for an indexed param from 4194304 to 1073741824.
  Banish the message "More than 2000 columns; must increase CNMAX."
  In redeclarations that do not specify a := value, retain data
where possible.
  Fix bug in deleting for and repeat loops: if the loops' controlling
expressions involved constants (such as 0) or expressions involving
only constants (such as atan(1)) that appeared in the model, subsequent
attempts to solve the model could lead to unpredictable behavior.
  Fix bug (e.g., memory fault) in evaluating objective values and
constraint bodies after an error interrupts a solve or write command.
  Fix memory-overwrite bug in initially dropping a constraint, changing
something (e.g., a set or param) on which the constraint depends,
then restoring and trying to use the constraint.  (The change to the
ungenerated constraint's prerequisites caused an erroneous attempt
to save the constraint's dual variables before generating the
constraint.)

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
  Fix memory fault in "write;" (which is supposed to be the same
as "write $outopt;").
  Fix bug in simplifying constant expressions in a nonlinear context.
Example:
	set S; set T;
	var x{T} >= 0;
	param p{S,T};
	minimize zot: sum{i in S}
			exp(sum{j in T} p[i,j]*(p[i,j]+1)*x[j]);
	data;
	set S := a b; set T := d e;
	param p := [a,*] d 0 e -1  [b,*] d 3 e 4;
	# For i = 'a', exp(sum{j in T} p[i,j]*(p[i,j]+1)*x[j])
	# vanishes; a bug caused a memory fault during simplification.
  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
  Fix bug (possible memory corruption) in handling solver messages
over 120 characters long.
  Fix failure to complain about invalid subscripts in
	set A;
	set B{A};
	data; set A := a b c;
	set B[a] := ab bc;
	set B[b] := ba bb;
	display B;
	let A := {};
	display B;	# didn't complain about bad B subscripts
  Fix bugs introduced in 19950315 in handling option commands with
old-style concatenations as values.  Examples:
	option solver $solver b;	# should append b to $solver,
					# but gave syntax error
	option solver $solver 'b';	# same: but it looped.
  Fix bug in handling "reset data; data diet.dat; solution diet.sol;"
before reading any data: the solution command appeared to be ignored.

19950727
  Adjust show command to omit $display from the list of declared sets.
Example:
	display{i in 1..5,j in 5..10} 10*i+j;
	show s;	# erroneously mentioned $display

19950801
  Fix glitches in -MD and -O introduced in the last changes (19950727).
  Do not break compound commands or command-line file processing when
presolve determines the solution (e.g., eliminates or fixes all
variables).
  Fix glitch in parsing
	if $solver == $$solver then
(Workaround: put parens around the logical expression.)
  Fix possible memory fault associated with the match and sub functions.

19950802
  Fix glitch with csvdisplay's display of 2-D tables with
	option display_1col 0, omit_zero_rows 1 /* small value */;
  Adjust "show" to reflect current drop/restore status after
a problem command.

19950804
  Fix bug in saving problem drop/restore (and fix/unfix) status:
changes away from the status declared for the problem made the
first time the problem is current were lost.  Example:
	# First two problem declarations
	problem Sub: Artif_Reduced_Cost, Trans, Supply, Demand;
	problem Master: Artificial, Weight, Excess, Multi, Convex;
	# Master is current; change away from its declaration:
	drop Artificial; restore Total_Cost; fix Excess;
	# Do something with another problem
	problem Sub;
	drop Artif_Reduced_Cost; restore Reduced_Cost;
	# Switch problems: changes away from problem declaration
	# were lost.
	problem Master;
	show obj; show var;
  Inhibit executing commands in files other than stdin after the
message "Abandoning compound command to accept ...".

19950808
  Fix bug with -P (option presolve 0):  if declared bounds caused a
piecewise-linear term in a constraint to turn into a linear term,
memory could be corrupted in an unpredictable way (leading to
subsequent chaos).
  Fix glitch in show command: in the following example, the show
command gave "(o.0 := avail)" rather than "avail" as the right-
hand side.
	model steel.mod;
	data steel.dat;
	print total_profit, avail;
	show Time;

19950810
  Fix bug in "expand": piecewise-linear terms after the first
one printed had the wrong slope and breakpoint lists: they
duplicated those of the first (in each constraint or objective).
  Allow the expand and solexpand commands to show dropped families of
constraints.  Previously, the sequence
	set A;
	s.t. foo{A}: /* ... */;
	drop foo;
	expand foo;
resulted in no output; now it shows the foo constraints, adorned
with the comment "# Dropped".
  Fix bug in solexpand's test for constraints eliminated by presolve.
  Adjust solexpand to say "# Presolve completely eliminated foo."
in response to "solexpand foo;" when appropriate.  Previously the
solexpand command gave no output in this case.
  Add the comment "# Eliminated by presolve." when appropriate to
solexpand output for a subscripted constraint.  Thus
	solexpand foo[3];
might elicit this comment, whereas
	solexpand foo;
might elicit the comment "# Presolve completely eliminated foo."
  Correct a possible memory fault with the show command (in complicated
situations).
  Allow the print command to have no arguments, which causes
it to behave the same as
	printf "\n";

19950811
  Fix bug in reading dual values for problems with free rows when -P
(option presolve 0) is in effect.  Presolve eliminates free rows
(i.e., constraints of the form -Infinity <= stuff <= Infinity), but
-P allows them to be conveyed to the solver.  The bug could result
in incorrect dual values for some constraints, and could cause
memory overwrites and subsequent unpredictable behavior.

19950815
  Fix possible memory fault in the cd command with WATCOM-compiled
binaries.
  Fix botch in deleting subscripted set references in command contexts
other than expressions appearing in an indexing expression (memory
for which is not yet recovered).  Subsequent commands referencing
the subscripted set could give unpredictable behavior.  Example:
	set A;
	set B{A};
	data;
	set A := a b c;
	set B[a] := x;
	set B[b] := ;
	set B[c] := x;
	for{i in A}
		printf "'x' is%s in B[%s]\n", if 'x' in B[i]
			then '' else ' not', i;
	# deletion of ('x' in B[i]) was botched, giving different
	# results to a repeat of the same command:
	for{i in A}
		printf "'x' is%s in B[%s]\n", if 'x' in B[i]
			then '' else ' not', i;

19950827
  Fix bug in handling in handling string-valued loop invariants, as in
	set A;
	param p{A} symbolic;
	set B;
	param q{B} symbolic;
	for{i in A, j in B} { if p[i] == q[j] then print i,j; }
(in which p[i] is invariant as j ranges over B).  If it bit, the bug
could cause unpredictable behavior.
  Fix a bug that could give the error message "presolve vT bug".  The
bug sometimes bit after presolve deduced sharper bounds that turned a
piecewise-linear term into a linear term.
  Fix a bug in handling complicated column-generation structures after,
e.g., a data update followed by a printing command that caused some (but
not all) entities necessary for "solve" to be updated.  An ensuing solve
sent the wrong problem to the solver.  (The bug fix entails a significant
change to the logic for deciding what needs to be recomputed.)
  Fix a memory fault in executing "expand undefined_name;".
  Fix a bug with renumbering defined variables after some change forces
"earlier" variables to be regenerated (or generated for the first time).
The bug could cause the message "solve_out bug" (or worse, could
silently cause the wrong problem to be generated).
  Fix an infinite loop in deleting a sum that expanded into the sum
of two variables.
  Fix glitch in displaying a variable indexed over an empty set
when the variable has no := or default clause and is not given
an (empty) initial value in a data section.
  Put parens around names generated for variables added to linearize
piecewise-linear terms.
  Fix glitch in recomputing some set expressions in for loops.
  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
  Fix glitch that forced one to use .val notation when referring to
the value of a variable in the set specification of a for loop.
  Fix bug with
	drop scalar_constraint; solve; restore scalar_constraint;
	expand;
(where scalar_constraint is an unsubscripted constraint):  the
"expand;" did not show scalar_constraint.
  Fix bug that caused
	set A dimen 2 default {};
	var x{1..3};
	s.t. c{(i,j) in A}: sum{k in 1..3} i*x[k] >= j;
	display c;
to give the error message "No values for c.".  Now it says "c; #empty".
  Fix botch in handling slices of the same kind over different sets
when the sets turn out to be the same (have the same members): because
of erroneously freed memory, unpredictable behavior was possible.
  Fix redeclare bug revealed by:
	var x {0..10};
	minimize obj: sum {j in 1..10} x[j];
	subj to jump {j in 1..10}: x[j-1] = x[j] - 1;
	solve;
	redeclare subj to jump {j in 1..10}: x[j] = x[j-1] + 1;
	solve;	#fault
  Fix a bug with arcs as defined variables: sometimes they gave rise to
a constraint with an unutterable name, rather than a nonlinear defined
variable.  Now they act as other defined variables.
  Fix bug with "delete" and "purge" that could cause subsequent "show"
commands to fault or print the wrong entity.
  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).

19951010
  Fix botch with "let" set assignments, revealed by
	set S ordered; let S := {"A","B","C","D"};
	display {i in S} ord(i);	# A had ord 4 rather than 1

19951015
  Fix bug in computing .dual, .lb1, .lb2, .lbs, .ub1, .ub2, .lbs, .ubs
notations for partially dropped constraints.

19951019
  Fix buglet with "fix;" that caused it to show defined variables
(as unfixed).
  Fix bug in handling indexed params (etc.) that have a default
expression.  If "let" or "read" or "update data" caused the param
to have data for invalid subscripts, causing an error message about
the data being discarded, and some subsequent command caused the
default expression to be evaluated, chaos could ensue.
  Fix bug in handling problem declarations with indexing expressions:
the indexing expressions were not necessarily reevaluated after "let"
or "read" or "update data" should have affected them.
  Fix bug with "commands foo.dat;" when foo.dat consists of or ends with
a data section that starts with "data;".

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
  Fix bug with "show" after "delete":
	param p;
	param q;
	show par;
	delete p;
	show par;
said "parameter:   p".
  Fix bug in deleting objectives (with the delete or purge command):
an expression got deleted twice, which could cause subsequent chaos.
  Fix memory allocation bug in discarding subscripted problems when
the problem's indexing set shrinks.
  Fix another bug in handling problem declarations with indexing --
another context where the indexing expressions were not necessarily
reevaluated after "let" or "read" or "update data" should have affected
them.
  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.

19951130
  Fix precedence bug in printing nonlinear expressions involving
sums: parentheses were omitted incorrectly.  Example:
	var x;
	minimize zot: (x + 2)^2 + x*(x^2 + 3*x);
	expand;
gave
	minimize zot:
		2 + x^2 + x*x^2 + 3*x;
  Adjust error reporting for discarded subscripts so this "error" won't
cause compound commands to be aborted, or "solve" to think that presolve
found the problem infeasible.
  Fix bug in handling slices: chaos could sometimes ensue if, e.g., one
tried to compute with a set for which no data had been given.

19951202
  Fix bug in evaluating a dropped objective before anything else
requires the collect phase.  Example:
	var x;
	minimize zip: (x-1)^2;
	minimize zap: (x-2)^2;
	objective zap;
	print zip;
  Fix bug introduced 19951027 in the above example with "objective zap"
changed to "drop zip".
  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
  Fix memory fault (or worse) with "delete" after "redeclare".
Example:
	param p;
	redeclare set p;
	delete p;
	display p;	# fault
  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.)

19951219
  Fix bug with deleting or redeclaring a variable, constraint, or
objective or an entity declared before a variable, constraint, or
objective.
  Fix memory fault with "update data" after deleting something, but
not everything declared after it.
  Fix bug with redeclaring a param with a recursive := clause.

19960101
  Fix a glitch in processing var = declarations in which the same
variable appears linearly two or more times in the right-hand side.
The glitch only affects a forthcoming extension to the AMPL/solver
interface for recognizing partially separable structure and computing
Hessians.

19960104
  Fix bug in handling slices of sets declared with := when the
right-hand side changes.  Example:
	set A;
	param p{A};
	set B := setof{i in A} (i,p[i]);
	data;
	param :A: p := 1 11 2 12 3 13;
	display {(i,12) in B};
	reset data;
	data;
	param :A: p := 7 12 14 12;
	display {(i,12) in B};	# said ":= 14" instead of ":= 7 14"
  Fix bugs in "expand" and "solexpand" of a dropped objective or
constraint.  Example:
	param N := 5;
	var x{1..N} >= 0;
	fix12: x[1] + x[2] <= 0;
	convex: sum{i in 1..N} x[i] = 1;
	minimize zot: sum{i in 1..N} i*x[i];
	blotch: sum{i in 1..N} x[i] + sum{i in 1..N} x[i] = 2;
	fix_x4: x[4] = .3;
	drop blotch;
	expand blotch;	# memory fault
	solexpand blotch;

19960116
  Fix bug in handling some file names of the form (i), as in
	for{i in S} commands (i);

19960125
  Fix a bug that could cause the error message
"invalid refct 0 in opgen" under conditions that seem hard to describe.

19960202
  Adjust DOS .exe files to print nonzero return codes from solve
and shell commands.
  Fix bug in handling a defined variable after some change causes a
nontrivial linear, piecewise-linear, or nonlinear part to go away.
Example:
	var x := 2;
	param t default 1;
	var y = t*(x + 1)^2;
	minimize zot: x^2 + y^2;
	print zot;	# 85
	let t := 0;
	print zot;	# should be 4; was 85 again

19960207
  Fix a bug revealed by an example with two objectives, each involving
variables with the same literal subscripts, in a loop that alternated
between objectives and forced them to be regenerated.  A symptom of
the bug was that a linear objective suddenly appeared nonlinear.
Example:
	param p;
	var x{1..2, 1..2} >= 0;
	minimize zip: p*x[1,2] + 2*x[2,1];
	maximize zap: p*x[1,2] + 3*x[2,1];
	s.t. convex: x[1,2] + x[2,1] == 1;
	option solver cplex;
	for{i in 1..3} {
		let p := i;
		solve zip;
		solve zap;
		}
  Fix botch in handling named problems that could cause unpredictable
results (under conditions hard to describe).

19960219
  Fix bug (apparently introduced in version 19951019) in handling files
that do not end with a newline: the last partial line was ignored, and,
under -t, a memory fault was possible.  [In the MS-DOS student binaries,
this is fixed in version 19960219a.]
  Fix memory fault in
	var x <= 3;
	minimize zot: (x - 4)^2;
	let x := x.ub;	# before something made presolve run

19960223
  Fix a bug in handling several slices over the same set.  The bug was
revealed by a memory fault in a very complicated example.

19960227
  Fix memory fault revealed in a "repeat" loop as the first command
executed, such as
	param i default 0;
	repeat {
		display i;
		let i := i + 1;
		} while i < 3;
  Fix glitch in exiting "for" and "repeat" loops after an error: for
example, on infeasible problems, the sequence "expand; solve;" caused
enclosing loops to terminate after the "expand" without for loops being
torn down properly; this could make dummy variables of the "for" loops
still appear to be known.  Example:
	var x >= 0;
	param p;
	maximize foo: x;
	s.t. zot: x <= p;
	let p := 4;
	repeat {
		for{k in 1..4} {
			let p := p - 1;
			display p,k;
			expand;
			solve;
			display x;
			}
		} while p > -3;
  Fix bugs in, e.g., "display _svar, _svar.ub, _svarname;" and in
evaluating _svarname[i].

19960306
  Allow printf's "+" flag to reveal the sign of 0.
  Fix glitch (e.g., memory fault) with redeclaring variables,
constraints, or objectives when a subsequent "solve", or "solution"
command occurs before anything else forces the problem to be
reinstantiated (as the redeclaration should have been doing).
  Fix bug with "option presolve 0" when bounds turn piecewise-linear
terms into linear terms.

19960313
  Fix bug in handling index sets common to several entities when some
change (e.g., a let command) caused some of the entities to be
recomputed.  It was possible for the common index set to be deleted
prematurely, leading to subsequent chaos.
  Arrange for redeclarations of variables, constraints, and objectives
to retain current values and drop/fix status.
  Fix bug introduced 19960223 in handling multiple occurrences of the
same slice of a subscripted set.

19960330
  Fix glitch (possible memory fault, or wrong subscripts in error
messages) with dummy variables instantiated in linear sums appearing
in objectives and constraints.
  Fix glitch in evaluating logical expressions: in (A and B) with A
false or (A1 or B) with A1 true, if B appeared several times, it
might be evaluated, possibly leading to an error message.  Example:
	set I := 1..2;
	param p{i in I, j in I: j >= i} := i + j;
	set S := {i in I, j in I: j >= i && p[i,j] > 1 && p[i,j] < 3};
	var x{S};
	minimize zot: sum{(i,j) in S} (x[i,j] - p[i,j])^2;
	solve;	# "invalid subscript p[2,1]"
  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)];

19960403
  Fix glitches introduced 19960401 during "improvements" in set
generation.  For example, sets with "such-that" conditions that do not
depend on anything in the set were effectively ignored.  Example:
		display sum {i in 1..2: 0 == 1} i;
should print 0 (but printed 3 with the bug).

19960411
  Banish "adjoin: SBUFLEN is too small" message arising from reading
a large "param foo := ..." table in a data section.
  Fix bug in handling updates to sets that turn out to be the same.
Example:
	set A;
	set B;
	let A := {'abc'};
	let B := A;
	for{i in 1..2} {
		let A := A union {i};
		let B := B union {i+10};
		}
	display A, B;	# said no data for set A
	# listed B twice with the "for" changed to "for{i in 1..1}"
  Fix memory fault with nested "for" commands in which an inner "for"
has a "such that" clause that causes the inner "for"'s body not to
be executed on the last iteration of the outer "for".  Example:
	param p;
	for{i in 1..3} {
		let p := 10 + i;
		for{j in 11..13: j > p}
			print i,j;
		}

19960417
  Fix bug (memory fault) in handling constant subscripts in problem
declarations.
  Fix bug in recording partial drop statuses in certain circumstances;
the bug could cause the erroneous conclusion that all members of an
indexed collection of variables were dropped.  Example:
	var x{1..4} >= 0;
	var y{1..4} >= 0;
	minimize foo{i in 1..2}: sum{j in 2*i-1..2*i} j*x[j];
	minimize goo{i in 1..2}: sum{j in 2*i-1..2*i} j*y[j];
	s.t. zip{i in 1..2}: sum{j in 2*i-1..2*i} x[j] = 1;
	s.t. zap{i in 1..2}: sum{j in 2*i-1..2*i} y[j] = 1;

	problem p{i in 1..2}: x[2*i-1], x[2*i], foo[i], zip[i];
	problem q{i in 1..2}: y[2*i-1], y[2*i], goo[i], zap[i];
	solve p[1];
	solve q[1];	# erroneously said "all variables fixed"
  Following Fortran 90, add "/=" as a synonym for "!=".

19960418
  Fix bug introduced 19960331 with read commands with "<" redirections.
  Terminate includes within the file in a read command's "<" redirection
when the read command ends.

19960425
  Fix buglet with the builtin "num" function: it complained at trailing
white space rather than ignoring it.
  Fix bug (possible memory fault) with displaying strings involving '$'
followed by a numeral.
Example:
	display 'ab$123';	# memory fault
  Fix bug printing an error message for a symbolic parameter that fails
an assertion (such as an "in" clause) in its declaration (after being
assigned a value by the "read"command).  Example:
	set S := {'A', 'BCD'};
	param p symbolic in S;
	read p;
	E
	display p;	# fault
  Fix bug (memory fault, or worse) with "purge" and "delete" commands
applied to problems.
  Fix erroneous message about circular dependencies in redeclarations
of arcs.
  Fix memory fault with certain sequences of redeclarations and
expression evaluations involving variables fixed by presolve.  Example:
	var x;
	s.t. f: x = 0;
	display x.lb0;
	redeclare var x >= 0;
	display x.lb0;		# fault
  Adjust xref command so it does not show nodes cited in arc
declarations.  Make it possible to delete and purge arcs.
  Fix bug (e.g., memory fault) freeing "continue" commands after
execution of compound commands containing them.

19960510
  Fix bug with the display command's handling of unsubscripted _con
references: chaos could sometimes ensue if there were more constraints
than variables (with numbers on different sides of a power of 2).

19960516
  Fix bug with "reset data foo;" when foo is not declared with an
indexing set.  Unpredictable results were possible.
  Fix bug displaying symbolic parameters that look like numbers.
Example:
	param p symbolic := '1D23'; display p; # said p = '1e23'

19960516
  Fix bug with "reset data foo;" when foo is not declared with an
indexing set.  Unpredictable results were possible.
  Fix bug displaying symbolic parameters that look like numbers.
Example:
	param p symbolic := '1D23'; display p; # said p = '1e23'

19960606
  Fix glitch with "cd" command, which could fail if it involved
a param that had not been evaluated previously.
  Adjust option debug_stub to honor (and retain) ($solver)_auxfiles.
  Fix bug in handling loops containing data commands: more than a
dozen or so iterations elicited an erroneous message about includes
being nested too deeply.  Example:
	model diet.mod;
	for{1..20}{update data; data diet.dat;}
  Fix bug in handling nonconvex (resp. nonconcave) piecewise-linear
terms: when the problem had "unused" variables, either because some
indexed variable had an indexing set larger than the set of indices
used in the problem, or because some previous command forced another
variable to be instantiated that did not appear in the current problem
and was declared before one of the problem's variables, the resulting
".nl" file had an incorrect first line.  Example:
	var x{i in 0..2} >= -20;	# x[0] is "unused"
	convex: x[1] + x[2] == 1;
	minimize z: <<-1,1,4; -1,1,-1,1>> x[1] + <<4;-1,1>>x[2];
  Fix some single-stepping glitches, e.g., in handling a command
entered in single-step mode that fails for want of data.
  Fix nasty but seldom-seen bug in computing the right-hand side of
a set-valued "let" command and the indexing set of a "for" loop
(but not other indexing sets): if the set was represented by a
memory previously used for an indexing expression whose scope
involved common expressions that changed with the set members,
the set was treated as empty.
  Fix some memory leaks (in scripts that execute many commands).
  Fix glitch with "continue foo;" in a "for" loop within loop foo:
dummy variables of the inner "for" were not restored properly, which
could cause subsequent parsing errors in declarations or commands
involving the dummy names.
  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

19960609
  Fix bug in computing recursively defined params when several
independent recursions are needed.  Example:
	set A circular := 1..146;
	set B circular by A ;
	param c { d in A } in B :=
	    if   d in B
	    then d
	    else c[next(d)] ;
	data; set B := 1 4 21 26 36 39 44 57 60 68 71 94 97 101 134 137 142 146;
	display c; #fault
  Diagnose (illegal) circular recursive set definitions (rather than
looping until memory is exhausted).

19960615
  Fix bug in handling "repeat" commands with a "while" or "until".
Under complicated conditions, a fault was possible.
  Fix glitch with "expand" and "problem": an "expand" command executed
as the first command after various declarations, including problem
declarations, sometimes resulted in a surprising error message
("unexpected type ... in collect_setup()").
  Fix bug in the interaction of named problems and drop/restore,
fix/unfix: trouble was possible if explicit "drop" or "fix" commands
eliminated all members or "restore" or "unfix" commands brought them
all back into the problem.
  Fix bug (memory fault) with the sequence
	s.t. foo{...}: ...;	#new constraint declaration
	display foo;
	solve;	# memory fault after the solver message is echoed.
  Fix bug, probably introduced in version 19960330, in handling the
logical expressions
		not (a == b)
and
		not (a != b)
when a or b was symbolic (e.g., a symbolic param).
  Fix glitches with option single_step: there was no break at the first
command of a compound command, and using control-D (Unix) or control-Z
(MS-DOS) to single step the last command of a compound command resulted
in EOF.

19960627
  Fix bug simplifying piecewise-linear expressions: example:
	var x; minimize foo: <<1;-1,1>> x + <<2;3,4>> x;
was turned into <<1, 0; 2, 4, 5>>x rather than into <<1, 2; 2, 4, 5>x,
but
	var x; minimize foo:  <<2;3,4>> x + <<1;-1,1>> x;
was handled correctly: there was a glitch in one of the end cases.
  Fix glitch with cd command in Symantec DOS AMPL.EXE: explicit
letters were interpreted off by one.
  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.

19960707
  Fix glitch with var = declarations with "constant" right-hand sides
(not involving any variables, i.e., declarations that should have
said "param" rather than "var"): in some cases, such variables did
not appear to have been initialized with the right-hand side value.
Example:
	var x = 3;
	var y = 4;
	display x;	# correct: x = 3
	display y;	# wrong:   y = 0
  Fix bug in updating slices over sets declared without := or default.
Example:
	set A;
	set B dimen 2;
	param p{i in A, (i,j) in B} := i + j;
	display B;	# provokes error message: no data for B
	set C;
	data;
	set C := a b c;
	set A := 1 2 3, 10, 20, 30, 40, 50;
	set B := (1,10), (1,20), (2,30), (3,40), (3,50);
	display p;	# fault
  Quietly omit defined variables from problem declarations.  (This
repairs a memory fault previously associated with such declarations.)

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

19960718
  Fix bug with "option nl_permute 0" and "option nl_permute 1": wrong
information on Jacobian nonzeros sometimes went into the .nl file.
  Fix bug in reading .sol files corresponding to option nl_permute at
nondefault values.

19960729
  Fix glitch in reading data sections having sets of arity > 10.
  Disallow writing MPS files for problems with nonlinear variables.
  Fix glitch in reading g-format .sol files written with \r\n at the
ends of lines.
  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).

19960731
  Fix bug in numbering variables when an error (such as "no value" for
a param) interrupts problem instantiation.  Symptom: wrong variable
names in "expand" command.  The bug bit under complicated conditions.

19960816
  Fix glitch in the numbers of nonlinear and linear variables reported
by option show_stats when option nl_permute has the nondefault values
0 or 1.
  Fix faults under complicated conditions (a) after discarding invalid
subscripts and (b) with missing data.
  Fix bug in the expand command applied to a constraint or objective
declared with "{if test}" when "test" turns out false, as in
	param a := 1; var x; s.t. c{if a > 2}: x >= 1;
  Fix infinite loop in processing the erroneous input
	var x;
	s.t. con2: {if 1 > 2} x >= 1;	# syntax error (misplaced : )
	expand con2;
  Fix bug in naming constraints and objectives when an {if false}
constructs appear.  Example:
	var x;
	s.t. c {if 1 > 2}: x >= 1;
	expand c;
	s.t. con2 {if 1 <= 2}: x >= 1.5;
	expand con2;	# con2 >= 1.5;
  Fix bug (fault) in "delete" applied to a pipe function.
  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

19960819
  Fix glitch in handling "default nnn" in a data section when not
followed by ":=" and when applied to a param indexed by a set of
arity > 1.  Example:
	set A dimen 2;
	param p{A};
	data;
	set A := a b c d e f;
	param p default 3 [c,d] 4;	# default phrase appeared
	display{(i,j) in A} p[i,j];	# to be ignored.

19960822
  Fix a glitch that sometimes caused a "bad binary file" message
from the "solve" and "solution" commands on the DEC Alpha.  The
glitch was in handling 64-bit "long" integer variables and had no
effect on most (32-bit) machines.

19960825
  Fix a bug in handling common set expressions whose first uses
involve membership tests and whose later uses involve iteration over
the set expressions, as in
	set A; set B;
	...
	s.t. c1{i in C}: ... if (i in A union B) then ...;
	s.t. c2: ... sum{i in A union B} ...;
	solve;
	# Change something that will force c1 and c2 to be regenerated
	solve;	# possible fault or worse

19960826
  Fix botch in error message given when a data section provides a
subscript for a set that is declared not to be subscripted.  The
botch could cause a fault or a strange name in the error message.
Example:
	set A;
	data;
	set A[1] := a b c;

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

19960922
  Fix glitch with option log_file under block mode: some input didn't
get copied to the log file.
  Fix performance bug (which slowed execution and burned memory,
but did not affect correctness of results) in handling slices of
subscripted sets.
  Terminate all (not just some) commands in which genmod detects errors.

19961003
  Fix bug (leading to a memory fault during execution) in parsing
superfluous braces within a compound command, such as those around
the display command in
	for{i in 1..2}{ if i < 2 then print 'yes'; {display i;}}

19961016
  Fix glitch (loop) in recovering from a syntax error in a list
of commands gratuitously enclosed in braces.
  Fix bug that bit (e.g., with a fault) under complicated conditions
with recursive params (including those with a recursive "check"
condition) that have a default expression.
  Fix bug with option linelim: in a model with defined variables,
the sequence
	option linelim 1; solve;
	/* adjust something, then... */
	option linelim 0; solve; display _var;
could lead to a fault (or worse).

19961017
  Fix fault with defined variables in certain sequences of commands,
such as
	display a_defined_variable;
	problem another_problem;
	let variable := ...;
  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

19961023
  Fix bugs with ord(i), next(i), prev(i) and their relatives when i
is a dummy in a for loop.

19961100
  Fix some bugs in handling subscripted environments and problems:
faults were possible under the right complicated conditions.  Example:
	environ E{1..3};
	set I := 1..2;
	var x{i in I} >= 0;
	minimize zot: sum{i in I} i*x[i];
	s.t. convex: sum{i in I} x[i] = 1;
	problem foo{i in 1..3} environ E[i]: x, zot, convex;
	problem foo[1];	# fault
  Fix bug in "show e;" (to show environment names) after a "reset;"
following environment declarations (including the implicit ones
associated with problem declarations).

19961109
  Fix bug with defined variables:  under certain conditions, a scalar or
subscripted defined variable evaluated as 0 rather than its correctly
computed value.  (The situation in which this happened could be seen
with "option times 1;": the bug bit when collect ran without a
subsequent presolve before the defined-variable evaluation.)

19961112
  Fix glitch with "redeclare": it faulted when applied to a declaration
for a name that had not been declared (or had been deleted).

19961130
  Fix glitch with recursive set declarations: in situations where the
same expression appears twice or more, it was sometimes evaluated when
not needed, possibly giving rise to an erroneous error message about an
invalid subscript, as in the following example:
	param p{i in 2..4} := i;
	set S{i in 1..4} := if i == 1 then {}
				else if p[i] == 2 then {1}
				else if p[i] == 3 then 2..3 else 1..4;
	display S[1];	# error message about evaluating p[1]
  Fix fault with evaluating certain nonlinear "if" expressions in which
the condition does not involve variables and can be evaluated in an
outer context.
  The show command's printing of recursive parameter definitions will
now say ":= /*recpd.*/(...)" or ":= /*srecpd.*/(...)" rather than
":= recpd.(...)" or ":= srecpd.(...)".

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.

19970104
  Fix another bug in recursive set definitions involving literal sets
(such as {1}), setof expressions and iterated unions.  Unpredictable
results were possible.

19970212
  Fix rarely seen bug (resulting in a memory fault) that arises under
complicated conditions.

19970219
  Fix (rarely seen) bug that could cause a fatal "solve_out bug!"
message.  Work-around: "option presolve 1;".
  Fix failure to diagnose nonnumeric values in the following context:
	param p{1..2}; data; param p := 1 abc 2 xyz;
	display p;	# bogus values for p
  Fix bug (memory fault) in deleting defined variables.
  In data sections, recognize as numeric values Infinity, -Infinity,
+Infinity and, on IEEE-arithmetic systems, NaN, -Nan, +NaN.
  Code around WATCOM bug in comparing NaNs: the bug caused the display
command to turn NaNs into zeros.

19970307
  Complain at the appearance of problem names in the itemlist of a
problem declaration.
  Tweak "show problem_name;" to print the itemlist in the declared
order (rather than its reverse).
  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
  Fix bug in evaluating expressions involving problem-dependent
synonyms (such as _nvars and _snvars): sometimes, e.g., when they
appeared in printing commands after a problem command had changed
the current problem (and before anything else caused the new
problem to be instantiated), they were not recomputed.
  Fix memory leak with nonlinear expressions (in constraints and
objectives).
  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.

19970402
  In the (weird) context
	set I := 1..2;
	var x{I};
	for{i in I} if i >= 2 then print i,3;
	minimize zot: sum{i in I} i*x[i];
before processing the "minimize zot" declaration, recognize that there
is no "else" command to match the "if" command.
  When a program (e.g., solver) cannot be invoked (under Unix), say why.
  Adjust generation of file names with option debug_stub to avoid
confusion when all variables are fixed by presolve.
  Fix glitch (possible fault) introduced 19970212 affecting string
functions ctime, gsub, sprintf, sub, substr.

19970408
  Fix glitch in handling redirections in the "read" command: entities
in them were not instantiated by the read command.  Example:
	param dummy;
	param fname symbolic := "seq.dat";
	read dummy < (fname);	# error message: fname not instantiated
	display dummy;
  Adjust the handling of the default-value symbol in data sections so
it is only recognized when given with the same kind of quotes (none,
" or ') with which it is declared.  (The initial default-value symbol
continues to be . with no quotes.)  Thus, for example,
	param p symbolic;
	data; param p := ".";
	display p;
will now show that p has the value "." rather than no value.

19970413
  Under MSDOS (and MSWIN), quietly ignore command-line options
-v2 and -ve (which are always in effect).
  Fix bug in handling "if" expressions in some contexts when the "if"
test can be done at a more outer loop level than the "then" or "else"
expressions.  Example:
	param j := 1;
	set T := 1..10; param x{T};
	let{t in T} x[t] := max(0, if j == 0 then t else 0.5*t);
	display x;	# all x components had the x[1]'s value (0.5).

19970417
  Fix bug that could give "tva top error" message when evaluating
complicated recursive parameters or sets (when first evaluated in
certain contexts, such as a printing command).  Example:
	param M default 5;
	set I  := 0 .. M;
	set A := {i in I, j in I, k in 0..1:
			(i < M || k == 1) && (j < M || k == 0)};
	param N{(i,j,k) in A} :=
		if max(i,j,k) == 0 then 1
		else 1 + (if k == 1 then (if i < M then N[i,j,0]
						else N[M-1,j,1])
				    else if i > 0 then
					(if j == M then N[i-1,M,0]
						   else N[i-1,j,1])
				    else N[M,j-1,1]);
	display N;
Workaround: declare something that forces the recursive entity to
be evaluated.  For example, changing the display command to
	param Nlast := N[M-1,M,0];
	display Nlast, N;
bypasses this bug.  (Uses of recursively defined entities within a
model bypass the bug.)
  Suppress (e.g.) printing commands when they involve a wrong number
of subscripts.

19970420
  Fix bug introduced 19970402 in handling the trailing opt_while
of a repeat command.

19970516
  Fix trivial performance bug in display.
  Fix glitch that could cause an erroneous missing data message in
a command immediately following an error message (under the right
conditions).
  Fix infinite loop with a nested
	commands 'foo';
command when foo has the form
	if something then {...};
(with no outermost else).
  Fix bug with indexed collections of problems: under just the "right"
conditions, the actual indexing set of the problems was aliased
with other sets, wreaking havoc when a new member was added to the
actual indexing set (if the aliased sets should remain fixed).
  Fix bug with "redeclare": dependents shown by "xref" were not
updated properly.

19970517
  Fix bug in delete, purge, and redeclare commands: sometimes an
internal structure was deleted twice, leading to chaos.  Example:
	model nlmodels/ljcluster.mod;
	s.t. constr {i in I, j in I: i < j}: r[i,j] >= 1e-6;
	solve;	# error in constr[1,2]: bad subscript
	redeclare s.t. constr{(i,j) in P}: r[i,j] >= 1e-6;
	solve;	# fault
  Fix glitch in show command: default (initial) values for variables
were not printed.

19970528
  Fix glitch in comparing dummy indices and symbolic parameters with
character strings that look like quoted numbers: the comparison
proceeded as though the quotes were not there.  Example:
	set A; data; set A := a 2 c;
	display {i in A: i != '2'};
gave
	set {i in A: i != '2'}  := a c;
(as though the quotes around '2' were dropped) rather than (the correct)
	set {i in A: i != '2'}  := a 2 c;
  Fix bug in _sobj[...]: objectives presented to solvers are permuted
so nonlinear objectives come first; _sobj[...] did not reflect this.
Example:
	set I := 1..2;
	var x{i in I} >= 0 := i;
	minimize zip: sum{i in I} i*x[i];
	minimize zap: sum{i in I} i*x[i]^2;
	s.t. convex: sum{i in I} x[i] = 1;
	print _sobj[1], _sobj[2];
gave "5 9" rather than "9 5".
  Extension to expand command: recognize synonyms (possibly subscripted
_con, _obj, _var, _scon, _sobj, _svar).

19970529
  Fix failure to recompute reduced costs after a relevant change to
$abs_boundtol or $rel_boundtol.

19970606
  Fix a bug with sequences of named problems of increasing sizes: it
was sometimes possible for a memory block to be put on the wrong
free-list, causing unpredictable subsequent havoc.

19970609
  Fix glitch with "check;" in single-step mode.  It elicited a
mysterious (but harmless) message about "bad type 73 in cmdstring".

19970615
  Fix fault that could arise, e.g., if an option command is the
very first command to be executed and it follows a problem
declaration.
  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).

19970721
  Change "arity" to "dimen" in some error messages.
  Fix bug in writing .env files (with "solve" or "write" commands when
$solver_auxfiles or $auxfiles contains 'e') and shell commands
(when $shell_env_file is not empty): names were listed twice.
  Fix bug in generating indexed sets for some declared := right-hand
sides that do not depend on the set's index.  At least two surprising
error messages were possible, depending on the right-hand side.
Examples:
	set A;
	set B{1..2} := A;
	data; set A := a b c;
	display B;
gave
	error processing set A:
		no data for set A
and
	set S dimen 2;
	set T := setof{(i,j) in S} i;
	set U{T} := setof{(i,j) in S} j;
	## probably should be set U{i in T} := setof{(i,j) in S} j;
	data; set S :=
		a b
		a c
		b c;
	display U;
gave
	set::rehash finds duplicate entry

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
  "Invisible" tweak to presolve changes of 19970731.
  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.

19970820
  Fix bug in renumbering variables with certain sequences of commands
that do not cause presolve to run (it runs in some form regardless of
option presolve) and do cause variables to be instantiated "out of
order".
  On Unix systems, adjust printing of commands with -T and -t to appear
on stderr rather than stdout.
  Omit variables and constraints added to linearize piecewise-linear
terms from the synonyms (_var, _con, etc.).  They sometimes caused
faults with "display _con.slack;" and "display _var.rc;".

19970912
  Fix bug with scalar defined variables: linear terms were not merged.
  Fix possible glitch (usually invisible) in distinguishing network
constraints from linear constraints: constraints added to linearize
piecewise-linear terms may sometimes have been misclassified.

19970922
  Fix bug with the let command: assignments to an indexed symbolic
parameter for a subscript for which the parameter previously had no
value could fault.
  Under -R, forbid changing shells.

19970925
  Fix glitches affecting handling of some complementarity constraints
(an extension to be described later).

19971003
  Fix bug with "redeclare ..." of entities on which other entities
depend: the other entities were sometimes not recomputed when the
redeclared entity changed.
  Fix a memory leak: in loops (or scripts) where indexing expressions
of declared entities changed values, memory for the indexing set was
not reclaimed.

19971006
  Fix fault with "set unordered_set := ordered_set;"; example:
	set A ordered; set B := A;
	data; set A := a b c;
	display B;	# fault

19971110
  Fix bug with symbolic-valued "if" expressions whose test could be
lifted to an outer loop: on Sun machines (because of Sun's
calling conventions) and possibly others (with more complex examples),
the expressions appeared to be miscomputed (and could lead to a
subsequent fault).

19971117
  Fix glitch in .nl headers for Microsoft systems that probably only
matters for complementarity solvers: the eqns number was omitted.

19971205
  Fix a bug with recursive parameters involving certain expression
lists, such as those in min and max expressions.  It may be possible
to construct an example where the bug led to an incorrectly computed
result, but this does not seem easy to do.  The bug did cause a
fault on one machine (with a complicated example), but was invisible
on several other platforms.
  Fix glitch with objectives and constraints involving imported
functions with symbolic (string) arguments, which elicited the
surprising error message "unexpected type 0x13c8 in simplify()".
  Fix bug with "write 0;" that could cause a fault or other untoward
behavior with subsequent solve and write commands.

19980102
  Fix presolve bug: if a nonlinear constraint was eliminated but had
two or more unfixed variables at the time the last nonlinear variable
was fixed, the nonlinear expressions were ignored.  Example:
	var x{1..4};
	s.t. c1: x[1] = 2;
	s.t. c2: x[2] = x[1] + 1;
	s.t. c3: x[3] = x[1] + 2*x[2];
	s.t. c4: x[4] = x[1]^2 + x[2] + x[3];
	solve;
	display x, _con.slack;	# x[4] = 11 rather than 15
  Fix an infinite loop (or worse) that could be encountered with a
command-line invocation to write a .nl file, as in
	ampl -obfoo foo.mod foo.dat
(with no commands in the foo.* files).  The bug bit when a common
expression appeared several times in certain contexts.  For example,
"0" is such an expression in the following (silly) example:
	param p in [0,10) default 3;
	param q in [0,10) default 4;
	param r in [0,10) default 5;
	var x := p*Uniform(1,2) + q*r;
	minimize zot: (x-6)^2;

19980127
  Fix bug in handling variable.dual for fixed variables.  Note that
variable.dual is 0 unless it's a defined variable, in which case
variable.dual is the dual value for the defining constraint; defined
variables cannot be fixed.  Usually variable.rc, the reduced cost, is
of greater interest: it's the dual value for bounds on the variable.
  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

19980202
  Fix glitch in user-defined suffixes (to be described later).

19980208
  Fix a bug with card(), first(), and last() that occasionally caused
unpredictable behavior.
  Fix bugs (leading to invalid .nl files) with "option linelim 1"
on some problems with nonlinear defined variables.
  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.

19980212
  Fix bug with let subscripted_set[...] := set_expression when
subscripted_set[...] had no previous value.  If the bug bit, it
could cause unpredictable behavior.
  Fix bugs simplifying nonlinear "if" expressions after presolve
fixes a variable: if the result of the test condition was now known,
it was sometimes misinterpreted; otherwise, expressions whose
evaluation the test condition should prevent sometimes led to error
messages, such as a complaint of division by 0 (for a quotient whose
value presolve had determined to be 0).  Examples:
	var x{1..3} >= 0;
	s.t. fix_x1: x[1] = 0;
	s.t. zot: if x[1] < -1 then 3 / x[1] else x[3] + x[2] == 1;
and
	var x{1..3} >= 0;
	s.t. fix_x1: x[1] = 0;
	s.t. zot: if x[2] < -1 then 3 / x[1] else x[3] + x[2] == 1;
(Both examples give the same error messages, but the causes differ.)

19980216
  Fix bug introduced 19980127 affecting partial drop, restore, fix,
and unfix commands executed before the first solve (or other command
requiring the affected variable, constraint, or objective to be
instantiated).  Example (with multi.* from the AMPL book):
	model multi.mod;
	data multi.dat;
	fix Trans;
	unfix {i in ORIG, j in DEST} Trans[i,j,"bands"];
	solve;	# fault

19980218
  Fix longstanding bug with recomputing sets: an empty set was
sometimes not recomputed.  Example:
	for {s in 1..2} display {i in 0..3: i = 5-s};
  Fix bug introduced sometime between 19950724 and 19961031 in
handling certain recursive parameter and recursive set definitions:
under complicated conditions, a fault or wrong value was possible.

19980302
  Fix bug in handling sets with default value {}: if two such sets
were forced to have their default (empty) values, and then one
was assigned to the other, one of them was sometimes later diagnosed
to have no data.  Example:
	set A  default {};
	set B  default {};
	display A, B;
	let A := B;
	display A, B;	# complaint about A having no data.
  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.

19980305
  Fix bugs in handling user-defined suffixes (a new feature to be
described later) when certain indexing sets change.
  Fix memory fault with the delete command in certain sequences of
commands and declarations.  Example:
	param n default 3;
	var x{i in 1..n} default i;
	minimize silly: sum{i in 1..n} (i - sin(x[i]))^2;
	param q;
	solve;
	param r; let r := silly;
	delete q;
	let n := 4;
	solve;	# fault
  Fix bug introduced sometime between 19950724 and 19961109 in updating
some set expressions that depend on a param with a := assignment whose
right-hand side depends on another param with a value given in a data
section.  The first time the latter param was changed, the set was
not recomputed.  Example:
	param p; param q := p/2;
	param r{i in floor(q)..ceil(q) + 1} := i+1;
	data; param p := 7;
	display r;	# OK
	let p := 23; display r;	# r came out wrong
  Fix a presolve bug with complementarity constraints.  Example:
	var x; var y;
	s.t. equ: x + y = 1;
	s.t. compl: x >= 0 complements y >= 0;
	s.t. inequ: x + 2*y <= 1;
	solve; # error message (rather than "solution determined")

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.

19980313
  Fix bugs with defined variables: in commands, there were miscomputed
if nothing else had forced presolve to run, and under "option linelim 1"
constant terms were added in twice (in expressions computed in an AMPL
session, but not in expressions conveyed to solvers, which saw the
correct expressions).  Example:
	var x; var y = x^2 + 1;
	var z = 3*y + 4;
	minimize zot: y + z;
	print z, zot;		# wrong values: 0, 0
	solve; print z, zot;	# still 0, 0
	reset data;		# clear some internal state
	solve; print z, zot;	# right values: 7, 8
	option linelim 1;
	solve; print z, zot;	# wrong values: 10, 11
  Fix bug with "option foo;" when foo had the value "." -- quotes
around "." were missing.

19980320
  In "expand _con[n];", give an error message (rather than faulting)
if _con[n] arises from linearizing a nonconvex piecewise-linear
expression.  It's necessary to use _scon[...] to see these generated
constraints.
  Adjust some details (to be documented later) of importing functions
from shared libraries.

19980325
  Fix glitch in handling of complementarity constraints with
"solexpand;": non-indexed complementarity constraints were sometimes
omitted from the "solexpand;" listing.
  Fix botch in handling complementarity declarations of the form
	s.t. foo: L <= expr <= U complements v;
where v is a variable: the bounds L and U were mishandled.
  When the solve command cannot open a temporary file, it now tries
to erase the file, then open it again (in case permissions prevented
opening it the first time).  For the benefit of the solver, it also now
tries to remove any previously existing temporary .sol file of the name
the solver will write.
  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).

19980328
  Suppress commands involving an invalid name or suffix.
  Fix glitches with expand _ccon and, for complementarity constraints,
expand _con.
  Warn (rather than faulting) that expand _scvar is not allowed.

19980408
  Fix minor inconsistencies with _scconname in constraint names shown
by "expand _scon;" and "solexpand cc;", where cc is a complementarity
constraint.
  Warnings of discarded subscripts caused compound commands to terminate
but did not inhibit single commands.  Now these warnings no longer halt
compound commands.
  Remove prohibition on "reset data" and "update data" commands
appearing in compound commands.

19980409
  Fix rarely seen presolve bug introduced in version 19980309 that led
to an error message of the form "presolve has k = 55, P.nfc = 51".
  Minor efficiency improvement to some set intersections having
subscripted sets as one or both operands.

19980506
  Fix bug with delete command: deleting any objective, constraint, or
variable other than the most recently declared undeleted objective,
constraint, or variable sometimes led to a subsequent fault.
  Fix bug (that could cause a fault) in testing membership of certain
special names in "system sets", such as _PARS, _VARS, _CONS, etc.

19980512
  Fix glitch in the handling of tables by cvsdisplay and _display:
tables that would be wider than $display_width were not written in
the advertised format.  Work-around: specify a sufficiently large
option display_width.
  Fix one-bit error in decimal-to-binary conversion of certain
denormalized numbers.  For example,
	print 8.44291197326099e-309;
gave
	8.442911973260987e-309
rather than
	8.44291197326099e-309

19980515
  Fix glitch in handling imported functions of a variable number
of arguments.  Sometimes a domain error was erroneously diagnosed.
  Fix bugs with
	param p := random_expression;
	set s := random_set_expression;
The random expressions were computed anew at each command that
referenced the entities in question.  For example,
	param p := Uniform01();
	print p; print p;
gave
	0.6092090562543065
	0.1898730530200304
rather than
	0.6092090562543065
	0.6092090562543065

19980518
  Fix bug with reading large data sections (more than 1024 tokens)
that involve "." (or the current default-value symbol) in the first
half of the tokens.  The default-value symbol was mishandled,
possibly leading to a fault or other untoward behavior.

19980520
  Fix glitch with the expand command's handling of imported functions.
Example:
	function foo; var x{1..4};
	minimize zot: foo({i in 1..3}x[i], x[4]);
	expand zot;	# gave an error message

19980525
  Fix glitch in solve_message and solve_result reported when presolve
fixes all variables and determines that the problem is infeasible.
  When "solve;" fails, set solve_result = '?', solve_result_num = -1,
and solve_message = '?'.
  Fix glitches with the display command's handling of builtin dot
notations for indexed collections of objectives.

19980529
  Fix a glitch that sometimes caused presolve to run unnecessarily,
resulting in surprising show_stats output (with option show_stats 1).

19980605
  Fix bug in handling _svar.*, _scon.*, or _sobj.* when some entities
have been dropped (explicitly or by presolve).
  Fix bug with
	fix{...} var[...] := ...;
when {...} was affected by the assignment, which happened first:
the {...} was recomputed, causing the variables not to be fixed.
  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.
  Fix glitches in "reset data;" and "update data;" that caused
previously declared imported functions to be reported as unavailable
when invoked.

19980611
  Fix bug in computing .astatus values for constraints: the last _nobj
(number of objectives) defining constraints (associated with defined
variables) were classified as "pre" instead of "sub".
  Fix bug in sending statuses to solvers when the problem involves
piecewise-linear terms.  The bug could cause a fault, but was otherwise
harmless.  Workaround: option send_statuses 0; .

19980615
  Fix rarely encountered presolve bug: under unusual circumstances,
rounding errors could cause inequality constraints to be erroneously
deduced never to be tight.  The example that revealed this bug involved
an absurd lower bound of -1e38 on some variables.
  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.
  Fix glitch in error messages for failed "within set" clauses in
set declarations: "within set" didn't appear in the message (and the
attempt to print it might have faulted).
  Fix bug (probably introduced 19950315) in handling == and != clauses
in symbolic parameter declarations: the comparisons were sometimes
botched.
  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.
  Fix a possible memory fault with entities redeclared to be another
kind of entity (including symbolic versus nonsymbolic parameters).
Example:
	param p{1..3} symbolic; #...
	redeclare param p{1..3};
	display p;	# fault

19980622
  Fix glitch in student ampl binaries that could cause a "vT bug"
message if one said "solve;" after the message "Sorry, the student
edition is limited to 300...".
  Fix bug in handling next(dummy), prev(dummy), ord(dummy), etc.,
when the dummy was from a for loop: at the end of the entire compound
command, it was sometimes possible for the set over which the dummy ran
to up on a free list twice, leading to subsequent unpredictable havoc.

19980625
  Fix bug in calling imported functions: the nr (number of real args)
field was not set properly.
  Fix glitch in changes of 19980615 that made _AVAILFUNCS empty
(even though imported functions were available).
  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".
  Fix a bug (possibly causing a fault or surprising output) with
solexpand's handling of constraints introduced by linearization of
piecewise-linear terms.
  Fix bug introduced 19980615 causing a fault in referencing _VARS.
  Fix a bug (sometimes invisible, e.g., to our regression testing) in
the changes of 19980309 in the handling of nonconvex piecewise-linear
terms.
  Rather than faulting, issue an error message on attempts to assign a
symbolic value to a suffix for which no $suffix_table exists.  Example:
	var x; suffix zzz symbolic; let x.zzz := 'abc';

19980717
  Fix fault in expand commands involving a failed consistency check.
Example:
	param p := 3; param q := 2 >= p;
	var x >= q; minimize zot: exp(x);
	expand;	# faulted after the error message about q not >= p
  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
  Fix bug (possible fault or worse) in suffix declarations (including
those by the solve and solution commands) issued after a delete command.
  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.
  Fix bugs in "display _scon.suffix, _svar.suffix;" for some builtin
suffixes (e.g., _scon.dual when some constraints have been eliminated
by presolve).
  Fix bugs in handling multiple objectives: objectives have always
been permuted so nonlinear objectives come first, but the solve
command's "Objective =" message did not reflect this permutation, nor
did the recording of objective.result and objective.message, nor did
some _sobj suffixes.
  Fix bug (possibly leading to a fault) in assignments by the let
command of _obj[i].declared_suffix and _sobj[i].declared_suffix.
  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
  Fix bug (fault) under "option times 1" in handling input with
line numbers from the C preprocessor when a file ends in an
incomplete command.
  Fix bug in "solution" commands that print options (reflecting
that the solution was computed under a different set of options
relevant to presolve): presolve was not run again.  Work-around:
reissue the solution command.
  Fix possible fault in solexpand (of objectives, when presolve
has eliminated one or more constraints) introduced in 19980722.
  Fix bug (possible fault) sometimes seen in problems with defined
variables and piecewise-linear terms.  The bug only bit if
linearizing the piecewise-linear terms increased the number of
constraints to or beyond the next power of 2.
  Fix some bugs with _scon[...].builtin_suffix for constraints added
to linearize nonconvex piecewise-linear terms.
  Record settings of $linelim and $substout in .nl files, and adjust
these options, if necessary, when reading solutions.

19980805
  Fix bug (fault) in computing reduced costs for problems with defined
variables and no objectives.
  Correct glitches in the (temporary) treatment of $substout values 2
and 3.  Permit presolve to fix defined variables even when this leads
to anonymous equality constraints.  For now, at least, turning on
the "4" bit of $substout inhibits this new behavior.  Under option
substout 1, this behavior turns out to have been occurring already
with potential defining constraints.  For example,
	var x; var y = x; s.t. foo: y = 3;
now gets "Solution determined by presolve." whether $substout is 0
(default) or 1.  Previously under default conditions, the problem was
transmitted to the solver.  Now this only happens if $substout is 4.
  Fix bug in "redeclare var ..." and "redeclare s.t. ..." that could
lead to an infinite loop (or worse) upon a subsequent attempt to
delete the var or constraint in question.

19980826
  Fix bug with delete and redeclare of an entity A that depends on an
entity B only referenced by A, after deletions of other entities that
depended on B: after subsequent declarations of two or more entities
that depend on B, chaos could ensue.
  Fix bug introduced in 19980722 that caused "ordered by" or
"circular by" or "within" phrases in subscripted set declarations to
be ignored by "let" commands assigning to subscripts that hitherto
had no value; the bug similarly caused restrictions declared on
subscripted parameters to be ignored.  Example:
	set S ordered := 2 .. 11;
	set T {1..2} ordered by S;
	param p{i in 1..2} >= i;
	data; set T[1] := 8 3 5; param p[1] 7;
	let T[2] := {2, 9, 6, 7};
	let p[2] := -1;
	display T;	# T[2] not ordered correctly
	display p;	# no complaint about p[2]
  Fix fault in the sequence sequence "solve; let ...; display _con;"
when "let ...;" changed some set or param, so some part of the problem
must be reinstantiated, and when presolve had removed one or more
constraints from the original problem.  (The fault arose whenever
something required dual values for the removed constraints to be
computed.)

19980828
  Fix bug in handling recursive parameters: if, due to conditional
expressions, a recursively defined param was not actually used and
an update would require recomputing the param (if it had been used),
a fault ensued.  Example:
	set S ordered;  set T;
	param p{i in S} := if i == first(S) then 1 else p[prev(i)] + 1;
	param q{T};
	param r{i in S} := if i in T then q[i] else p[i];
	var x{S};
	minimize zot: sum{i in S} (x[i] - r[i])^2;
	data;
	set S := a b c;
	param :T: q := a 2.4 b 4.2 c 8.9;
	solve; display x;
	let S := S union {'d'};
	solve; display x;	# fault

19980905
  Adjust "display x;", where x is an indexed variable, so it does not
run presolve.
  Fix a bug with "drop constr[...];" (dropping some but not all
subscripts of an indexed constraint) when defined variables were
declared after the constraint.  The defined variable declarations were
often fairly harmlessly treated as ordinary constraints, but sometimes
an incorrect problem resulted from incorrect variables being
substituted out.
  Fix a bug with the sequence
	solve; var new_var{...}; let{...} new_var[...] := ...;
Sometimes storage got corrupted (depending on the original number of
variables and the size of new_var's indexing set).
  Fix a fault in
	problem foo: something, ...;
	fix something; # or unfix or drop or restore
	delete foo;		# the current problem
	problem foo: ...;	# fault

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

Sat Sep 12 08:40:47 EDT 1998
  Fix glitches in "let" commands that result in certain error messages,
such as about sets having different arities: the next command sometimes
saw the wrong list of dependencies or (with input from stdin) was
sometimes erroneously suppressed.
  Fix bug deleting the current problem under certain circumstances,
as in
	problem zap; var x; minimize zot: (x-1)^2;
	solve; delete zap; # fault
  Fix possible fault with multiple solves when a nonlinear defined
variable is fixed by presolve.

19980928
  Fix bug with "display _scvar;", which showed incorrect values.
  Fix bug (fault) with solexpand complementarity_constraint, as in
	var x; var y;
	test: x >= 0 complements x + y <= 3;
	solexpand test;
  Fix bug (fault) with "expand _scon;" when presolve has resolved all
complementarity conditions.

19981005
  Fix possible fault with "let" assignments to generic synonyms, such
as _var and _con.  If the fault didn't occur, the bug was harmless.

19981009
  Fix fault with sets having a random default expression.  Example:
	set A default 1 .. 10*Uniform01();
	display A; # fault
  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.

19981019
  Fix glitch in distinguishing variable.status and variable.astatus
values "fix" and "unused".
  Fix rarely seen bug that resulted in the error message "invalid refct 0 in opgen".

19981022
  Fix possible fault in computing var.lrc, var.urc, constr.ldual, and
constr.udual when the problem has no objective (i.e., is just the
problem of finding a feasible point).

19981105
  Fix bug in handling imported functions: with some sequences of
commands, incorrect .nl files were generated, leading solvers to fault.
Example:
	function foo;
	var x;
	s.t. Foo: foo(x) >= 0;
	let Foo := 1;	# initial dual variable
	solve;		# fault
In this example, an easy work-around is to provide the initial dual
variable value in the constraint declaration:
	s.t. Foo := 1: foo(x) >= 0;
or in a data section:
	data; var Foo := 1;
  Fix glitch in handling certain problems in which presolve detected
infeasibility: a second solve command sometimes sent a feasible
problem to the solver.  Example:
	set I := 1..2;
	var x{I} >= 0;
	minimize zot: sum{i in I} i*x[i];
	s.t. fixit:  x[1] = 0;
	s.t. bletch: x[1] = 2;

19981109
  Fix bug in parsing some "setof" expressions and literal sets
involving tuples of expressions: the initial components of the
tuples were lost when the last was a string expression.  Examples:
	display setof{i in 1..3} (i, sub('123',i,'x'));
	display {i in 1..3}: {(i, sub('123',i,'x'))};
  Fix glitch with single stepping: a single-step command involving
a bad subscript could terminate execution.
  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.

19981120
  Fix bug (fault or worse) in handling suffixes declared with
restrictions on their values, such as inequalities or "integer":
after an assignment to the suffix, references within an iterated
context might encounter the bug.  Example:
	set I := 1..3;
	var x{i in I} integer;
	suffix foo >= 0 <= 10;
	let{i in I} x[i].foo := i;
	let{i in I} x[i].foo := x[2].foo + 1;	# fault
(If "2" were changed to "i", the fault would go away.  Inserting
"display x.foo;" before the second "let" would also bypass the bug.)
  Fix possible glitch in scaling of CPU times on some systems (that do
not have getrusage()).
  Fix bug in handling models with nonlinear defined variables that
appear in piecewise-linear terms.  Under unpredictable conditions,
an invalid .nl file sometimes resulted.  Unless option linelim 1 (or
command-line option -L) is specified, all defined variables appear
to be nonlinear; specifying option linelim 1 may thus avoid the bug.
  Fix fault (or worse) in references to _var.defeqn or _var.dual after
presolve has found the problem infeasible.
  Fix glitch in _con.defvar: under unusual circumstances, some
components were erroneously reported as nonzero, e.g., when option
substout 1 was in effect and there were two or more candidate defining
constraints for a variable.

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.
  Fix seldom-seen bug in invocations of the form
	ampl -ogfoo boo2
in which something recursive or computed from a default expression
involves something indexed over a set whose definition involves
subscripts: part of the subscript computation may have been latched
prematurely, causing subsequent failure.  Here is "boo2" of the
offending example:
	param n{1..2};
	set IR := {'i','r'};
	param f{i in 1..2, 0..n[i], IR};
	var a{IR};
	var phi{i in 1..2, j in 0..n[i], ir in IR} = f[i,n[i]-j,ir] + (
		if j == 0 then 0
		else if ir == 'i' then
			a['i']*phi[i,j-1,'r'] + a['r']*phi[i,j-1,'i']
		else
			a['r']*phi[i,j-1,'r'] - a['i']*phi[i,j-1,'i']);
	minimize N: (phi[1,n[1],'i']^2 + phi[1,n[1],'r']^2)
			/ (a['r']^2 + 1);
	data;
	param n :=
		1 2
		2 2;
	param f default 0 :=
		[1,*,r] 2 1	1 -3.001	0 2.01
		[2,*,r] 2 1	1 -4.001	0 3.0002
	;
	var a := r 1.001 i 0;

19981218
  Fix bug (possible fault, or worse) in reading solutions of problems
having variables or constraints declared with {if false_condition}.
Forbid assignments to such variables and constraints.
  Include in the $eexit processing error messages for suffixes not
assigned values consistent with restrictions in the suffix declarations.
  Fix glitch in passing initial guesses: before the first solve,
"let" assignments to _var were sometimes ignored (in favor of the
initial guess in the variable's declaration or in a data section).

19981230
  Fix fault in handling constraints or objectives with {if true}
indexing and piecewise-linear terms.

19990112
  Fix bugs with some "redeclare ..." declarations that changed the
type of the declared entity.  Example:
	param p := 3; redeclare var p;
	minimize zot: (p-1)^2;	# error message
  Fix bug with "shell (string_expression);": derived quantities in the
string_expression were not updated.
  Fix glitch in error message for "update data zork;" when zork is not
defined: instead of "s is not defined", say "zork is not defined".
  Fix possible glitches with "show su; show e;" after a reset.
  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
  Fix glitch (possible fault, or worse) in the handling of "hard"
(nonconvex) piecewise-linear terms in version 19990112.
  New addition to reserved-word list: table.

19990129
  Fix bug in command-line invocations of "ampl -o..." when the problem
involves imported functions: an invalid .nl file resulted.

19990202
  Fix (reference-counting) bug in references to any of the sets Reals,
Integers, ASCII, EBCDIC, and Display.  The bug manifested itself in the
second command to reference a particular one of these sets.  Example:
	print if 'A' in Reals then 'yes' else 'no'; # works OK
	print if 'A' in Reals then 'yes' else 'no'; # error or fault
  Fix bug with "redeclare": declaring a new entity, such as a new
variable, then redeclaring another entity to involve the new one
could lead to a subsequent fault in using the redeclared entity if it
had indirect dependencies.  Example:
	model diet.mod; data diet.dat;
	var x; redeclare minimize total_cost:
		sin(x) + sum{j in FOOD} cost[j]*Buy[j];
	write 0;	# fault

19990209
  Fix possible bug with reading (initial guess) data for variables or
constraints in a data section after "update data;" and after the
variables or constraints have been instantiated.  The bug would bite
only under unusual conditions and would have unpredictable consequences.
  ftp://netlib.bell-labs.com/netlib/ampl/student/mswin/samplnt.exe.gz:
fix an infinite loop (due to a compiler bug) in evaluating random
functions, such as Uniform01().

19990225
  Fix a bug in an unadvertised feature: permitting subscripts after
some dot notations rather than within them.  If x is a subscripted
variable, then references to, say, x.lb[i] (or any other built-in
suffix other than sstatus) worked, but x.sstatus[i] and
x.any_declared_suffix[i] could fault.
  Fix bug (possible erroneous "not generated" message) in the let
command's handling of assignments to problem.declared_suffix.
  Fix bug with "display thing.suf_num" -- "_num" was omitted from
the column heading when "suf" was a declared suffix.

19990304
  Obscure bug fixes: when reading files (e.g., stdin under Unix with
manual control-Ds giving partial lines, or in general with very long
input lines), when it appears that a token may be split across two
read() invocations, do not ignore white space (which terminates the
token) at the start of the second read(); and when reading stdin,
give the secondary rather than the primary prompt before the second
read().
  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.)

19990305
  Fix glitch in yesterday's change: a comment at the end of a file
file gave rise to the wrong prompt just after an "include" of the
file.

19990310
  Fix glitch in handling (final) files that do not end with newline.

19990311
  Fix botch in yesterday's change affecting two or more command-line
files.

19990323
  Fix bug (possible subsequent fault, or worse) with redeclaring
imported functions.
  Fix another recently added bug reading files without a final newline.
  Turn {set_expr} into set_expr.
  Fix glitch in prompt after "reset;" when there have been no
declarations but there was a syntax error in a compound command.

19990326
  Fix a memory fault that arose under obscure conditions; absent the
fault, the bug was harmless.  In part, the bug involved "reset data p;"
after assigning some values to a parameter p but never using them.
For the record, here is an example where the bug bit:
	set A; set B := {i in A: i != 2};
	param p{A} >= 0;
	let A := 1..2;
	let{i in B} p[i] := i;
	let A := 3..4;
	display B;
	reset data p;
	let{i in B} p[i] := i+2;
  Fix a bug with reading ASCII format .sol files from files with
carriage-return characters (e.g., text files on Microsoft systems).

19990421
  Fix possible fault in command-line invocations
	ampl -ogfoo foo.mod foo.dat ...
when presolve determines all the variables.
  Fix a bug that led to error messages of the form "presolve has k = 0,
P.nfc = 1" (under complicated and rare conditions).
  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).

19990426
  Fix bug with "option linelim 1;" in models with partially linear
defined variables that (e.g.) appear both linearly in another
defined variable that is only used linearly and nonlinearly in
a constraint or objective: displaying the partially linear defined
variables led to an invalid .nl file.  Example:
	var x{i in 1..4} := i;
	var s = sum{i in 1..4} i*x[i];
	var y{i in 1..2} = x[i]^2 + s;
	var z{i in 1..2} = y[i] - 5;
	minimize zip: sum{i in 1..2} (3*z[i] + y[i]^2);
	option linelim 1;
	write gzap1;	# correct
	display y;
	display z;
	write gzap2;	# was bogus

19990513
  If SIGHUP is being ignored (e.g., by nohup), continue to ignore it.
  Fix glitch with option show_stats 1: in problems with nonlinear
objectives, the "nnn nonlinear objective(s)" line erroneously
mentioned "linear" nonzeros.

19990607
  Table and out-arg extensions, to be described later.
  Fix glitch in "show" command: the example
	param N;
	set S;
	var x{1..N,S};
	var y{1..N};
	minimize zot: sum{i in 1..2} y[i]*sum{j in S} x[i,j];
	data; param N := 2; set S := a b;
	write 0;
	show x;
printed "var x{y.index, S};" rather than "var x{1 .. N, S};".
  Fix a bug that could only bite on Intel processors: under unusual
conditions, nonlinear defined variables sometimes incorrectly caused
generation of NaN values in or after a "solve" or "solution" command.

19990804
  Fix fault in the sequence
	option log_file 'foo';
	var x; reset;
	option log_file 'foo';
	var x; reset;
(i.e., in issuing a redundant "option log_file" command after a
nontrivial reset).
  Fix bug in handling /* ... */ comments longer than about 4300
characters: they were inadvertently treated as end of file.
  Change "amplodbc.dll" to "ampltabl.dll".
  Fix bug in "delete suffix foo;" and "delete table foo;" that could
cause memory corruption.
  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.

19990806
  Fix bug in handling ampltabl.dll (intended for use with the table
extensions, still to be described).
  Fix glitch with "write 0; solve;" -- "solve;" now writes a .nl file.
Note that "write 0;" sets $ampl_funclibs.  If a reference to _SFUNCS
requires it to be recomputed, $ampl_funclibs is now also updated.
  Fix bug with reloading libraries that provide at least one already-
imported and declared function: a fault was then possible with
"display _AVAILFUNC2", "display _AVAILFUNCS", and "show functions".
  Fix bug that sometimes led to a surprising error message involving
"because its declaration had no indexing set_name" during parsing
of table declarations.  Example:
	table T : [i=ABC,j=DEF] a[j,i];
(Note that with the builtin table handlers and sample ODBC handler,
this declaration could be written more simply as
	table T : [DEF,ABC] a;
since these handlers permit the names in table declarations to be
in a different order than those in the external table.)
  Fix bug with "update data" or "read table": adding values to, e.g.,
a param declared without any consistency checks could lead to a fault.
Example:
	set B; param q{B};
	data; set B := a b c d;
	param q := a 10 b 20;
	display q;
	update data q; data; param q := c 30 d 40;
	display q; #faulted
  Fix bug in discarding bad subscripts under some conditions.
Example:
	set A; param p{A}; param q{A};
	data; param :A: p q := a 1 10 b 2 20;
	display p,q;
	update data q; data; param q := c 30 d 40;
	display {i in A} (p[i], q[i], p[i] + q[i]); #faulted
  New system param _version gives the AMPL version number.

19990811
  Fix longstanding bug in handling problems involving subsets
of indexed constraints, such as the stoch2 problem in
http://www.ampl.com/ampl/NEW/LOOP2: sequences of the form
	solve prob1; # involving only some subscripts of a constraint
	let ...;# evaluate something not previously instantiated
		# that also involves dual values of the partially
		# dropped constraint
	solve prob2; # involving different subscripts of the constraint
resulted in wrong dual values subsequently being used in expressions
using dual values of the indexed constraint in question.  The bug
apparently crept in sometime between 19960823 and 19961129.

19990812 --> 19990813
  Names "sampl" and "samplnt" in /netlib/ampl/student/* changed to
"ampl"; /netlib/ampl/student/sun4 changed to
/netlib/ampl/student/solaris.  The old names will continue to work
for a few more weeks; they're linked to the new ones.

19990818
  Fix a fault in handling incorrect -b command-line options.
  Fix bug, introduced in 19990804, in for{i in S} {...}: if i
(the dummy variable of the "for" loop) was all that changed in {...},
then various things didn't get recomputed, leading to surprising
results.  Example:

	set S{1..3};
	for{i in 1..3}
		let S[i] := i..i+3;
	display S;

gave

	set S[1] := 1 2 3 4;
	set S[2] := 1 2 3 4;
	set S[3] := 1 2 3 4;

Since the "let" command can be indexed, there was no need for a "for"
loop in this example, which would better have been written

	set S{1..3};
	let {i in 1..3} S[i] := i..i+3;
	display S;

which gives the expected output

	set S[1] := 1 2 3 4;
	set S[2] := 2 3 4 5;
	set S[3] := 3 4 5 6;

Making something else change in the for loop also resulted in correct
behavior, which explains why we didn't see this bug earlier.  For
instance,

	set S{1..3};
	param j default 0;
	for{i in 1..3} {
		let S[i] := i..i+3;
		let j := j + i;
		}
	display j, S;

worked correctly.
  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).

19990821
  Fix some bugs with the interaction of "load" and "reset".

19990830
  Fix glitch with "objective;", which sometimes responded with a
sequence of "drop" and "restore" commands instead of a single,
equivalent "objective" command.  Example:
	var x;
	minimize foo: sin(x);
	minimize goo: cos(x);
	objective foo;
	objective;

19990831
  Fix bug in "redeclare" of entities on which other entities depend.
Declaring a new entity that depended on the redeclared one caused
memory corruption.  Example:
	model diet.mod;
	redeclare set FOOD ordered;
	data diet.dat;
	param T{j in FOOD} := 199900000000 + ord(j)*1010101.1;
	solve;	# fault

19990908
  Some changes to "tables", an extension we hope to describe soon.

19990913
  Fix glitch in parsing name.suffix[subscripts]: an internal array
was corrupted in a way that could cause subsequent surprising
behavior.  For example, a reference to constraint.dual[subscripts]
in a loop or {command; command...;} block could cause the constraint
to be dropped in the first solve.  Example:

	var x{i in 1..3} >= 0;
	s.t. c{i in 1..2}: x[i] + x[i+1] = 1;
	minimize foo: sum{i in 1..3} i*x[i];
	{ # start block
		solve;
		display x,c;
		print{i in 1..2}: 'c[',i,'].dual = ', c[i].dual;
		print{i in 1..2}: 'c.dual[',i,'] = ', c.dual[i];
		}
	# Printed x = c = 0; c.dua[i] in the last printf caused
	# the trouble.  With the last printf commented out, correctly
	# printed x = 0,1,0 and c = -1,3.

19990916
  "Invisible" portability tweaks to binary <--> decimal conversion
routines.

19990930
  Fix data-section glitch: tables of the form
	param :setname: ... := ... ;
that supply both parameter values and an indexing set didn't record
that setname had been assigned a value.  This permitted
	set A; param p{A}; param q{A};
	data;
	param :A: p :=
	a 1
	b 1.5 ;
	param :A: q :=
	x 3.3
	y 4.2;
	display A;
to get by without an error message.  (A subsequent "display p;" did
produce an error message about invalid subscripts for p.)
  Fix bug in turning {..., (a,b) in {A,B}, ...} into
{..., a in A, b in B, ...}: under apparently rare conditions,
unpredictable behavior was possible; e.g., slices over A or B could
go awry.

19991004
  Fix some glitches with table declarations and "write table".

19991006
  Fix a nasty bug that crept in sometime in the latter half of 1995:
use of a slice in a command could foul up subsequent uses of the
same slice in subsequent independent commands (not part of any
compound command containing the first use).  Example: in
	set A dimen 2;
	data; set A := a b  a c  b c  x z;
	display {('a',i) in A};
	display{i in 1..5} i^2;
	display {('a',i) in A};
the final display incorrectly listed 1 2 3 4 5 rather than b c.

19991027
  Fix bug with "read .. < -;" introduced around 19960401 that could
cause a fault or other unpredictable behavior.
  Fix bug in handling variables subscripted over empty sets after
a solve, subsequent changes to entities in the variables' declarations,
and another solve or something else that caused the variables to be
regenerated.  Example:
	set S default {};
	param p default 0;
	var x{S} >= p;
	var y;
	minimize zot: (y-1)^2 + p*sum{i in S}x[i];
	solve;
	let p := 2;
	solve;
	# unpredictable behavior was now possible
  Fix a bug (fault) in handling duplicate appearances of the same slice,
as in
	param p {w in W, j in 1..n} :=
	   if card {(nw,w) in P[j]} = 1 then sum {(nw,w) in P[j]} nw;
  Fix bug in computing the value of a piecewise-linear function of
a defined variables within an AMPL session (e.g., in a display command,
but not in expressions sent to solvers): if nothing else had caused
the defined variable to be evaluated, the piecewise-linear function
could be miscomputed.  Example:
	var x := 2;
	var y = 3*x + 1;
	var z = <<3; -1,1>> y;
	print z;	# printed 0 rather than 1
	print <<3; -1,1>> y;

19991130
  Fix bug with redeclare: redeclared entities were sometimes not
regenerated.  Example:
	set I := 1..299;
	var x{I} binary;
	maximize zot: sum{i in I} x[i];
	s.t. knapsack: sum{i in I} Uniform01()*x[i] <= 43;
	solve;	# objective 159.0316356
	redeclare set I := 1..300;
	solve;	# gave same objective before bug fix
		# after fix, objective 162.1322059
  Fix bug with if expressions in nonlinear expressions: in some
(complicated) situations in which the test involves only "outer"
dummy variables and the "then" or "else" parts involve inner
dummies, a fault was possible.  Example:
	set A; set B; set C;
	var x{A, B};
	var z{B} >= 2;
	var y{i in A, j in B} = z[j] * (if i in C then 0
					else (x[i,j] - 2)^2);
	minimize zot: sum{i in A, j in B} y[i,j];
	data;
	set A := a b c;
	set B := x y;
	set C := b;
  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.]

19991207
  Fix a bug in presolve's handling of complementarity conditions that
led to error messages of the form "presolve has k = 5, P.nfc = 4".
Workaround: option presolve 1;  example:
	var x1; var x2;
	s.t. c1: x1 + x2 >= 2;
	s.t. c2: x1 - x2 <= 0;
	s.t. c3: 0.1*x1 + x2 <= 1.1;
	s.t. c4: x1 >= 0;
	var y{1..2};
	s.t. foo: y[1] + y[2] >= 3 complements x1 <= 1.02;
	s.t. goo: sum{i in 1..2} (y[i] - i)^2 >= 2;

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.
  Fix theoretically possible glitch in handling "break loopname;" and
"continue loopname;".  Whether the glitch could cause trouble is
system-dependent; most likely, it would never cause trouble.
  In the "context: ..." portion of error messages, omit initial
white space.
  Fix bugs with "load" and "reload": if a function in the loaded
library had been declared inconsistently with the version in the
library, the resulting error message omitted the function's name
and could fault; if the library's funcadd called at_reset or at_exit
and all its addfunc were rejected, a fault was possible when the
functions passed to at_reset or at_exit were finally called (since
the library may have been unloaded).  Now these functions are called
immediately if everything else in the library was rejected.
  Ignore errno settings by imported functions, which should assign
al->Errmsg if something goes wrong.
  In functions imported by a load command, calls on fprintf should
no longer cause an "Error executing..." message.
  Fix obscure presolve bug in handling constraints or objectives
involving a variable that presolve fixes and a nonlinear mod expression
whose left operand starts with unitary minus.  Example (which looped):
	var x; var y;
	minimize zot: exp(-x mod .3) + y;
	s.t. nail_y: 1 = y;
  Fix glitch in handling multiplications by (-1) in some situations
where it would be cleaner to write a simpler expression.  Example:
	var x; minimize zot: -x*-1; solve;
gave "invalid refct 0 in opgen".
  Fix possible fault on machines with 64-bit pointers with "expand;"
and "solexpand;" of models with piecewise-linear terms.

20000204
  Fix some glitches with tables (an extension to be described soon).

20000207
  Fix botch (possible extra text in $AMPLFUNC) in "unload" and "reload".
  Prevent some builtin params (such as _ampl_user_time) and sets
(such as _LIBS) from being assigned.
  Fix bug in the interaction of "close;" and $log_file (that could
cause "writing" to a closed file).

20000208
  Fix another glitch with "unload ...;".

20000209
  Fix a glitch with tables.

20000216
  Fix bug in linearizing nonconvex piecewise-linear terms: if presolve
deduced bounds that permitted eliminating sufficiently many constraints
with "hard" (nonconvex or nonconcave, as appropriate) piecewise-linear
terms, a fault or unpredictable behavior could result.
  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
  Omit an explicit "+ 0" that was in the .nl file for
	var x; var y; minimize zot: sin(x+y+sum{i in 1..0} (x*y)^i);
  Fix glitch in yesterday's .relax implementation: reading .relax
values from a table or OUT args in a function call did not necessarily
affect the next "solve".
  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.
  Distinguish singular and plural in more "option show_stats 1" output.
  Fix glitch with variable.defeqn and constraint.defvar that gave "0"
for linear defined variables.
  Fix bug in handling synonyms: under complicated conditions, a fault
was possible.
  Fix glitch with "solexpand;": if some members of an indexed family of
constraints were dropped, others in the family were sometimes shown
as "dropped" and expanded in the modeler's view rather than the solver's
view.
  Fix glitch in conversion of "nonlinear" linear expressions introduced
20000128: constant terms were sometimes botched.

20000307
  Fix minor glitch with handling a syntax error that terminates reading
a data section: the error message could show too much text.
  Fix possible fault with "display foo;" when foo is indexed by a set
involving a set-valued "if" expression.
  Fix glitch with $presolve_warnings: prior warnings had counted
against $presolve_warnings; now only warnings during the current
invocation of presolve count.
  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.
  Plug a memory leak (somewhat unlikely with default settings) that
occurred when exceeding |$eexit| warnings during presolve caused
presolve to be aborted.

20000309
  Fix minor printf glitch:
	printf "%.0f\n", .1;
printed "0." rather than "0" -- under "%.0f", numbers less than 1
in absolute value that do not round to 1 or -1 should print as "0"
with no trailing decimal point.
  Fix possible infinite loop in cleaning up after "Abandoning compound
command to accept declaration of ...".  If input was directly or
indirectly from stdin (via "include", "model", etc.), return to stdin
for further input; otherwise quit.

20000316
  Fix bug introduced 20000216: suffix declarations appearing after any
variable, constraint, objective, or problem declarations caused internal
inconsistency, sometimes resulting in a fault when needed entities were
not instantiated.
  Fix longstanding bug: some cached values were not updated after
presolve changed relevant variables values.  (They were updated after
"let", "solve" and "solution" commands, which explains why we didn't
notice this sooner.)  For example,
	print _obj[1]; write 0; print _obj[1];
showed the same value twice, even if presolve changed some relevant
variable values.
  Fix a glitch in handling complementarity conditions: if presolve
detects infeasibility, adjust things to avoid the mysterious error
message "presolve has k = ...".
  Fix longstanding bug with iterated "let" assignments to a subscripted
param with a default value and a right-hand side that involves the left-
hand side: if the default value had to be evaluated when the number of
already assigned subscript values was a power of 2, chaos could ensue.
  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.)

20000317
  Fix glitch introduced in the first "correction" of 20000307:
	param p; data; param p := 3;display p;
and
	param p; data param p := 3;
	 model; display p;
(transitions from data mode to model/command mode not begun at the
start of a line) were mishandled.

20000321
  Fix bug with "option substout 1" introduced 20000128: a fault was
possible, e.g.,
	var x >= 0; var y;
	s.t. ybounds: 5 <= y <= 11;
	s.t. ydefn: y = 3*x + 2;
	option substout 1; solve; # fault

20000327
  Tweak to hash-table logic to speed up reading data on some large
examples (with many symbols).
  Correct glitch with complementarity constraints that caused some
linear constraints to appear nonlinear when involved.
  Fix longstanding bug with option linelim 1:  if a constraint or
objective made nonlinear use of a nonlinear defined variable that
depended linearly on certain other variables, and if these other
variables did not otherwise appear in the constraint or objective,
they were omitted from the list of partial-derivatives that could be
nonzero.  Example (variant of Rosenbrock test function): under
"option linelim 1", variable x[2] was omitted from the lists of
possibly nonzero partials for the objective and constraint.
	var x{1..2};
	var f1 = 10*(x[2] - x[1]^2); var f2 = 1 - x[1];
	minimize f: f1^2 + f2^2;
	s.t. zip: f1^2 >= 3;
	data; var x:= 1  -1.2 2   1;

  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.

20000406
  Fix longstanding bug with "option linelim 1" on complementarity
problems: adjustments to the constant term in complementarity
constraints were missed.

20000412
  Fix trouble handling many numeric set members introduced 20000327.
  Fix longstanding bug that could make set member 3000 misbehave.

20000413
  Fix a long-standing bug that could afflict scripts that solve
sequences of complementarity problems when memory got corrupted.
  The "fix" of 20000406 could occasionally lead to corrupted memory;
try again...

20000427
  Fix bug in providing variable and constraint (dual variable) initial
guesses in data sections after the variables or constraints in question
had been instantiated:  providing an incomplete set of values sometimes
led to chaos.
  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.

20000428
  Fix bug in "expand variable;"'s handling complementarity constraints.
Example:
	set I := 1..2; var x{I};
	s.t. goo{i in I}: x[i] complements x[i] == 0;
	expand x;
gave
	Coefficients of x[1]:
		goo[1].L  1
		goo[1].R  1

	Coefficients of x[2]:
		### None ###
  Fix bug with handling partially dropped complementarity constraints:
incorrect names were sometimes generated, and memory could be corrupted.

20000430
  Fix another bug with handling partially dropped complementarity
constraints -- another context where memory could be corrupted.

20000502
  Fix bug (possible fault or wrong constraint or objective subscripts)
with "expand variable"'s handling of partially dropped constraints.
Example:
	model transp.mod; data transp.dat;
	drop Supply['GARY'];
	expand Trans['CLEV','FRA'];	# wrong Supply subscript
  Fix another glitch with partially dropped complementarity constraints.

20000505
  Fix nasty bug with adjusting nonlinear constraints that become
linear due to variables being fixed during presolve: a test to decide
which such constraints might imply further bound adjustments was wrong,
leading to the possibility of incorrectly eliminating constraints.
Work-around: "option linelim 2;" to suppress the adjustments.
  Fix bug with converting previously nonlinear expressions to linear
expressions when the limit $presolve - 1 on extended presolve iterations
is reached and the final iteration made more conversions possible.
A fault was likely.  Temporary fixes: increase option presolve or
specify option linelim 2 (to suppress the conversions).
  Fix some minor memory leaks.
  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.
  Fix bug with computing suffix values (such as _con.status) for
complementarity constraints.  Trouble remains with .sno and .no.

20000512
  Fix another bug with converting previously nonlinear expressions to
linear expressions:  adjustments to constraint bounds due to variables
fixed by presolve were made twice, possibly leading to incorrect
warnings of infeasibilities or incorrect bounds transmitted to solvers.
  Fix possible miscomputations of constraint.no and constraint.sno when
the constraint is partially dropped.
  For complementarity constraints, make .Lno, .Lsno, .Lstatus,
.Lstatus_num, .Lastatus, .Lastatus_num, .Rno, .Rsno, .Rstatus,
.Rstatus_num, .Rastatus, and .Rastatus_num work.
  Adjust the expand command so empty constraint bodies print as "0".
Example:
	var x{i in 1..2}; s.t. zap: sum{i in 2..1} x[i] == 0;
	expand zap;
now prints
	s.t. zap:
		0 = 0;
rather than
	s.t. zap:
		 = 0;

20000515
  Fix bug introduced 20000128 in simplifying nonlinear "min" and "max"
expressions involving a constant term.  The bug only bit when
presolve had eliminated at least one variable.  Example:
	var x{1..2}; minimize zot: (x[1]-7)^2;
	s.t. blat: x[2] = 3;
	s.t. silly: max(x[1], x[2], 1) <= 4;	# got lost

20000516
  Fix longstanding bug in generating nonlinear variables "out of order",
under unusual circumstances, as in
	var w; var x{1..2}; var y{1..10};
	minimize zip: (w-1)^2 + sum{i in 1..2} (i+1 - x[i])^2
			+ sum{i in 1..10} (i+3 - y[i])^2;
	s.t. zap: sum{i in 1..10} y[i]^2 == 4;
	let x[1] := 3; let zap := 4; solexpand;
in which x is generated before w and y and (it turns out) because
of the dual-variable assignment "let zap := ...", y is generated
before w.  Nonlinear references to y were misnumbered, leading in the
above example to an incorrect expansion of "zap" -- and in another
example to a fault.
  Fix glitch with certain dual-variable assignments to hitherto
ungenerated constraints, as in
	var x{1..2}; minimize zip: sum{i in 1..2} (i+1 - x[i])^2;
	s.t. zap: sum{i in 1..2} x[i] == 4;
	let x[1] := 3; let zap := 4;
The last "let" command elicited an erroneous error message about
zap being an ungenerated constraint.

20000528
  Fix obscure bug with "option presolve 1;": if a defined variable
was fixed by presolve and appeared in an equality constraint with
one other variable, then an invalid .nl file resulted.  Example:
	var x{1..2}; var y = x[1] + 1; s.t. zip: y = 1;
	minimize zap: x[1]^2 + x[2]^2 + y^2;
Work around: leave option presolve at its default value (10).

20000602
  Fix a memory leak in computing reduced costs.
  Treat variables in defining declarations (var x = ...) as defined
variables even when bounds are reflected on them.

20000605
  Fix glitch in, e.g., "display objective.result;" introduced in
version 20000512.  Example:
	model dietobj.mod; data dietobj.dat;
	objective total_cost['A&P'];
	solve; objective total_number; solve;
	display total_cost.result, total_number.result;
gave "unexpected case -94 in sdotvalue".
  Fix a longstanding bug that gave an error message of the form
"unexpected type xxxx in ecopy()".  Example:
	var x := 3; var  y = x*sum {a in 1..1, b in 1..1} if a=1 then x;
	display x, y;

20000608
  Bypass a bug with some compilers (e.g., Microsoft Visual C++) that
caused NaN == x to be "true".  This caused "let" assignments whose
left- or right-hand sides were NaN to go awry.  (One must work to
compute NaNs, but assignments involving them should work.)
  Fix a bug with "write table"'s handling of symbolic parameters:
pure numeric values were sometimes converted to decimal strings.
  Fix glitch in the builtin .tab handler in distinguishing '123'
and 123 when reading symbolic parameters from columns after one or
more skipped columns.  Fix another glitch in the same handler that
prevented reading Infinity and NaN in .tab files.
  Fix fault that arose when a symbolic imported function returned NULL.
Turn such a return value into "<null>".
  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.

20000613
  Fix bug in unloading libraries that could make calls enrolled with
at_exit happen at the wrong time.  The problem was revealed in an
example involving a table handler, but could also afflict imported
functions that call at_exit.  The bug could bite either at the end
of execution or during an "unload" or "reload" command.
  Fix a bug with the shell command that afflicted only Win32 binaries
and was probably introduced with the changes of 19990804 to permit
blanks in solver and directory names:  shell commands with arguments
had the arguments treated as part of the command name, resulting in
failure of the shell command.

20000615
  Fix longstanding bug with "close" command applied to a file used in
a "read ...  <filename" command:  the file was usually not closed, and
it was possible for another file to be closed instead.  The most
likely result was possible exhaustion of available file descriptors
(symptom:  inability to open further files) when the "close" command
appeared in a loop.  The bug might also have prevented writing a
"closed" file on some systems.
  Fix a longstanding bug with "display x;", where x is indexed by an
ordered set of arity 1.  The cryptic error message "== in d3comp" could
appear, and a fault was probably also possible.
  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.
  Bypass another appearance of a bug with some compilers (e.g., Microsoft
Visual C++) that caused NaN == x to be "true".  This one was revealed by
	set B; param q{B} symbolic;
	data; param :B: q := a Infinity b Nan; display q;
which got q[b] = Infinity on Win32 systems.

20000616
  Fix glitches with imported functions:  first declaring a function,
then loading a library containing it could get a message like
        Attempt to change the nature of function hypot
	from real valued with at least 0 arguments
	to real valued with 2 arguments
where the only complaint was about the number of arguments.  Now this
sort of message only appears when the function differs in being or not
being random or symbolic.  After redeclaring a function after such a
message, the function was lost and could not be invoked.
  Patch around an apparent bug on some Linux systems whereby the
environment got lost after loading a library.

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.

20000719
  Fix (rarely seen) bug in handling defined variables: if a nonlinear
defined variable (v5 in the example below) had some linear terms and
appeared only in the right-hand sides of linear defined variables
(v7 below, which is linear after x[4] is fixed) used nonlinearly
(in v8), incorrect function values could result.  Example:
	var x{i in 0..4} := .1;
	var v5 = x[3] - x[1]*x[2];
	var v6 = x[2] / x[0];
	var v7 = v5 / x[4];
	var v8 = v6 - x[1]*v7;
	minimize foo: x[2]*v8;
	s.t. fix_x4: x[4] = .099;
In this example, the linear part of v5 was contributed twice to v7.
Specifying "option linelim 0;" bypassed the bug.
  Fix glitch with expressions involving a simple or subscripted
objective, appearing in commands (as opposed to declarations):
if the objective involved one or more defined variables and nothing
else forced the presolve state to be current, the objective value
could be miscomputed.  Example:
	var x; var y = x + 1; minimize zot: y^2;
	print zot; # printed 0 rather than 1

20000724
  Fix longstanding bug with "reset data": rereading an indexed
collection of sets sometimes led to memory corruption.

20000814
  Fix bug with defined variable/bound sequences of the form
	var v1 = nonlinear expression;
	var v2 = const*v1 + const;
	s.t. v2_bound: lowerbound <= v2 <= upperbound;
in which constraint v2_bound appeared to be lost.  Example:
	var x := 1; var y = x^2 + 1; var z = y + 2;
	s.t. zot: z <= 5; minimize foo: (x + 4)^2;
Work-around: option substout 4;
  Recognize command-line option -b? (and fix fault with -bx, where
x is an invalid -b option).

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.
  Fix bugs with redeclaration of an entity assigned values in a
(previous) data sections when the redeclaration declares the same
kind of entity: (1) require "reset data" or "update data" before
accepting new or updated data for in a data section and (2) fix a
bug that could cause memory corruption if enough enw subscript values
were assigned in a subsequent data section.  Example:
	set A; param p{A}; data; param :A: p := a 1 b 2 c 3;
	display p; redeclare param p{A} >= 0; update data A, p;
	data; param :A: p := a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10;
	display p;	# fault or wrong values due to bug
  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.
  Fix bug with use of synonyms in loops:  some expressions were not
re-evaluated, such as 1.._ncons in the display command in the following
example:
	model diet.mod; data diet.dat;
	for{j in NUTR} {
		display j, 1 .. _ncons;
		drop diet[j];
		}
  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
  Fix bug in the error message "can't compute member(0,...)": the
set name should have appeared.
  Fix a bug that gave rise to the error message "OPDIV botch in e2v".
A simple example seems hard to find.
  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"
  Some commands, such a (partial) fix command (involving a hitherto
uninstantiated variable after some other command had instantiated a
variable declared after the one being partially fixed), sometimes
appeared to require instantiating the current problem, possibly
leading to an error message about something that should not have
mattered to the current command.  Example:
	param p; var x{i in 1..3} := i + 4;
	var y; var z = (x[1]-p)^2 + 3;
	minimize zot: z^2 + (y-3)^2;
	let y := 5;	# instantiates y, which was declared after x
	fix x[2];	# error processing var z: no value for p
  Fix a small memory leak.

20001002
  Add "contains" to the reserved-word list.  (Later, it will be a
set-comparison operator, with A contains B <==> B within A.)
  Fix glitches in computing reduced costs (_var.rc) on problems
involving piecewise-linear terms that can be linearized without
use of integer variables (i.e., without special-ordered sets).
  Fix glitch in handling display _con.symbolic_suffix:  adjustments
for complementarity constraints were missing, leading, e.g., to
possibly incorrect values of "display _con.status;".

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.

20001009
  Fix bugs with "unload" and "reload":
1.  In a sequence of the form
	load foo.dll; solve;
	unload foo.dll;
	load foo1.dll; solve;
in which foo.dll and foo1.dll define different functions of the same
name, $ampl_funclibs was not updated for the second "solve", causing
the solver to load foo.dll instead of foo1.dll.  (If other changes
caused presolve to run again, this bug did not bite.)
2.  For all but the last-loaded library, "unload" might not have had
the system actually unload the specified library, which would cause
confusion if one unloaded a library, recompiled it, then loaded it
again.

20001018
  Fix bug in conveying complementarity conditions:  a variable with
two finite bounds was sometimes paired with a one-sided constraint,
possibly leading solvers to an incorrect interpretation of
complementarity conditions.  Example:
	var y; var l{1..2} >= 0;
	s.t. c1: 0 <=  y + 10  complements  l[1] >= 0;
	s.t. c2: 0 <= -y + 20  complements  l[2] >= 0;
	# -20 <= y <= 10 was incorrectly paired with l[1] >= 0
	# Instead, l[1] >= 0 should have been paired with y >= -10

20001025
  Fix bug with complementarity constraints:  when presolve resolved
a complementarity condition, changing an inequality constraint to an
equality, if the constraint involved two or more variables with
infinite bounds and coefficients of suitable signs, presolve could
incorrectly deduce a stronger bound on one of the variables, leading
possibly to transmitting an incorrect problem to solvers.  Example of
incorrect bound deduction (var.lb2 and var.ub2 are the strongest
deduced bounds):

	var x{2..6} >= 0;
	s.t. c1: 4*x[4] + 4 <= x[2] + 3*x[3]	complements x[6] >= 0;
	s.t. c2: x[5] + 5 <= 4*x[6]		complements x[4] >= 0;
	display _svarname, _svar.lb2, _svar.ub2;
	# x[3].lb2 botched: should be 0 but was 1.33333

  Arrange for "drop foo;", "restore foo;", "fix goo;" and "unfix goo;"
not to require generating foo or goo (whereas if, say, foo is
subscripted, as in "drop foo[3];", then generating foo is unavoidable
and all data required to instantiate foo must then be present).  This
was only an issue after references to a subscripted named problem whose
indexing set involved other declared entities.  Example:

	param p; set I := 1..2; problem zork{I};
	var x{1..p}; var y;
	minimize zap: y^2 + sum{i in 1..p} x[i]^2;
	problem zork[1]; drop zap;

  Fix a bug in recovering from missing data in contexts where a new
variable was to have been (re-)instantiated that was declared before
a previously instantiated variable:  if nothing subsequently caused a
variable to be (re-)instantiated, confusion was possible -- misnumbered
variables or an erroneous "no variables used" message.  Example:

	param p; set I := 1..2; problem zork{I};
	var x{1..p}; var y;
	minimize zap: y^2 + sum{i in 1..p} x[i]^2;
	minimize zip: sin(y); problem zork[1]; fix x;
	problem zork[2]; drop zap; solve; # OK
	problem zork[1]; solve; # error generating x: no value for p
	problem zork[2]; solve; # erroneous "No variables used."

20001030
  Fix bug with complementarity conditions:  if (perhaps after some
presolve reductions) one of the constraints in a complementarity
condition was a simple-bound constraint implying that the variable
in question could be fixed, the complementarity condition was not
treated as resolved, leading to a mysterious error message about
"presolve has k = ...".  Example:

	var z{1..2} >= 0;
	s.t. c: z[1] <= 0 complements z[2] <= 0;
	solve; # presolve has k = 2, P.nfc = 0

20001109
  Fix fault with some references to unavailable functions.  Example:

	function zork; var x; minimize f: zork(3)*x;
	solve; # fault when zork is not in amplfunc.dll

20001117
  Fix a bug with the printf command, sprintf function, and formatted
pipe functions:  results (in the case of pipe functions, the formatted
string being sent to the function) over 256 bytes long were sometimes
truncated.  An example where the bug bit:
	printf "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
		{i in 1..9} ('Line ' & i &
	 ' of a very long string intended to illustrate a printf bug');
  Fix bug in handling functions of more than 8 arguments on machines
with 64-bit addressing.  The bug also afflicted imported functions
with more than 2 explicit domains.

20001128
  Fix bug writing tables of zero rows (which were inadvertently
described as having one row, sometimes leading to a fault).
  Fix obscure bug on machines with 64-bit addresses in reading .bit
files (builtin binary table files) written on machines with other
endian-ness (i.e., written on a big-endian machine and read on a
little-endian machine or vice versa).
  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.

20001129
  Fix bug simplifying nonlinear "if" expressions.  Sometimes the
result of comparison operators was erroneously regarded as known;
since the bug was due to initialize a variable in this case, behavior
was system dependent.

20001130
  Fix bug introduced 20000825 in reading .sol files that could lead to
inappropriate option changes (with the relevant option command(s)
printed during solution reading) for $presolve_fixeps,
$presolve_inteps, or $presolve_eps.  If the bug bit (an apparently
rare event), the solution might be read incorrectly.

20001206
  Arrange for
	reset; print 'stuff' >zap; reset;
to close file zap.

20001228
  Fix bugs (faults) with "fix all;" and "fix all[3];", and fix a glitch
that added confusion to the error message that the latter now elicits
(about things that must or cannot be subscripted).

20010102
  Fix a bug with

	let S := {};

within loops.  At the second or subsequent loop execution, it was
possible for S to be misassigned, which led to a fault in the
complicated example that revealed this bug.

20010123
  Arrange for
	reset; print Uniform01(); reset; print Uniform01();
to print the same value twice.  Previously the random number sequence
was only reset if at least one declaration had appeared before "reset;".
  Fix bug that could give error message "unexpected type 0x87 in e2v()"
when constraints or objectives involved the "mod" operator.

20010129
  Fix error-message handling bug that caused

	set I := 1..3; var x{I} >= 0;
	param a{I} default Infinity;
	s.t. bletch: sum{i in I} a[i]*x[i] = 1;
	data; param a := 1 1.2, 3 4.5; write 0;

to elicit error message

	tva == 0 in mgwhere()

Now it gets

	Error executing "write" command
	(file goo, line 4, offset 130):
	error processing constraint bletch:
		can't multiply x[2] by Infinity

  Fix a glitch in handling {if logical_expression} in the ... of
<<...; ...>>, as described on p. 312 of the AMPL book.  For example,

	param p default 3; var x;
	minimize zap: <<1,{if p in interval[0,2.9]} 2, 3;
			-1,{if p in interval[0,2.9]} p, 4,6 >> x;

provoked an erroneous complaint about "iteration over unordered set".
  In iterated commands and expressions, permit {if logical_expression}
wherever indexing expressions were previously allowed.

20010130
  Fix another bug that led to "tva == 0 in mgwhere()".  Example:
	set A; set B{A}; set C := intersect{i in A} B[i];
	data; set A := ; display C;
  For completeness, permit {if logical_expression} as the indexing
in iterated reduction operators (sum, prod, min, max, exists, forall).

20010208
  Fix possible fault with handling identical slices in the same
indexing set.  The fault could occur when a command involving the
index set was executed twice in succession for the same slice.
Example:
	set A dimen 2; data; set A := a 1, a 2, a 3, b 2, b 3;
	for{k in 1..3}
		for{(i,2) in A, (j,2) in A}
			print i,j,k;

(The fault did not occur with "(j,2)" changed to "(j,k)", since
the slices where then different on successive executions of the
inner "for" loop.)
  Fix bug (infinite loop) in "print 2.47032822920623272e-324;".
  Fix bug in handling different slices involving the same expressions
over a subscripted set.  (The fact that the expressions differed was
overlooked in this particular context.)  Example:

	set A{1..2} within 1..3 cross 1..3;
	param p {k in 1..2, i in 1..3}
		:= sum{(i,j) in A[k]} j + 100*sum{(j,i) in A[k]} j;
	# Param p involves two different slices over A[k] in the same
	# context and involving the same expression, in this case "i".
	data; set A[1] := 1 2   1 3; set A[2] := 2 3   3 1;
	display p;	# gave all zeros

20010209
  Fix parsing glitch with single-step mode:  when a stand-alone "if"
command (not within a compound command) was not followed by an "else"
clause, an erroneous "syntax error" message was possible after execution
of the "if" command.  Work-around: add an extra semicolon.  Example:

	param p default 1; option single_step 1;
	if p == 1 then let p := 2;	#extra ; here = work-around
	printf "p = %.g\n", p;	# got "syntax error"

20010212
  Fix bug (fault) handling certain set expressions, such as slices of
subscripted sets, in recursive param and set definitions.  The bug
appears to have been around since at least 19971218.  Example:
script on p. 314 of the AMPL book plus some simple data:

	set nodes; set arcs within nodes cross nodes;
	param max_iter := card(nodes)-1;
	set step {s in 1..max_iter} dimen 2 :=
		if s == 1 then arcs
		else step[s-1] union setof {k in nodes,
			(i,k) in step[s-1], (k,j) in step[s-1]} (i,j);
	set reach := step[max_iter];
	data; set nodes := a b c d e f g h;
	set arcs := a b  a c  b d  c e  f g  f h;
	display step, reach;

This sort of thing is more efficiently done with commands (which also
avoids the bug):

	set nodes; set arcs within nodes cross nodes;
	param t; set reach default arcs;
	data; set nodes := a b c d e f g h;
	set arcs := a b  a c  b d  c e  f g  f h;
	repeat {
		let t := card(reach);
		let reach := reach union setof{k in nodes,
				(i,k) in reach, (k,j) in reach} (i,j);
		} while(card(reach) > t);
	display reach;

20010215
  Fix bug introduced 20010102 in handling named (non-subscripted) sets
that happen to have the same values as other sets, but then are
assigned different values:  the new values appeared to be lost.
Example:

	set A; set B; data; set A := a b; set B := a b;
	display A, B; let B := {'c','d'}; display B; # a b

20010226
  Fix a possible fault or unpredictable behavior with "write b;" (which
should write ".nl").

20010227
  Fix a glitch in the Win32 ampl.exe when the current directory is on
certain 8.3 file systems:  due to changes on 20010226, "solve;" might
elicit an error message about an unwritable file.

20010307
  Fix a rarely seen reference-counting bug that could cause the value
of a seemingly random set to change.  The bug could only bite under the
"right" conditions, which seem hard to capture in a simple example.

20010312
  Fix a glitch that could cause "<hidden>" to appear as the name for
some generated constraints or variables in, e.g., "display _sconname;"
when constraints were added in the course of linearizing nonconvex
piecewise-linear terms.
  Fix bugs in handling very long character strings and single lines
with no white space between tokens.
  For (ephemeral) constraints and variables introduced to linearize
nonconvex piecewise-linear terms, fix bugs in assignments to _svar
and quietly forbid assignments to suffixes (which do not exist in a
general sense for these ephemeral entities).

20010316
  Fix bug introduced 20010307 with "reset data;" or "reset data p;"
after a value has been assigned (via data section or "let") to an
unsubscripted symbolic parameter.  Example:
	param p symbolic; data; param p := 3; print p;
	reset data; # fault

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.
  Eliminate possible faults after a "reset;" while single stepping
or after sequences of the form
	option log_file 'something';
	# declare something and do some stuff
	reset; option log_file ''; # subsequent trouble was possible
  /netlib/ampl/student/mswin/sw.exe.gz:  make complaints about an
"Edit-control bug" less likely (under NT -- W98 has a different bug).

20010328
  Fix a bug (fault) with string-valued function references in
recursive parameter definitions.
  Fix a bug with "sub" and "gsub".  Memory was sometimes corrupted.

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.

20010412
  Fix a glitch parsing multi-line character strings that end with an
even number of backslashes (\).
  Adjust "read table" and outarg processing so (as with "let" and
data sections) values for subscripts for which heretofore there was
no value do not cause recomputations of things that depend on the param
being updated.
  When reading stdin in interactive mode, completely clear the error
indicator when not in the middle of a statement.  Previously the first
command after a declaration error was suppressed.

20010417
  Make the "Too much memory used" message print a positive number when
the number is >= 2^31.
  Fix bug introduced 20001006 in simplifying the product of two
apparently nonlinear expressions.  When the right-hand "nonlinear"
expression turned out to be a constant, the constant was erroneously
assumed to be 0.  Example:
	var x; param t default 0; minimize zap: (1 - x*exp(t*x))^2;
	solve; # said "No variables used."

20010507
  Fix bug in handling uses of nonlinear objective values in commands:
some sequences of commands (instantiating variables in the objectives
but not the objectives themselves) could fault.  Example:

	var x; let x := 5;
	minimize zot: (x-1)^2;
	if zot >= 3 then print 'yes';	# faulted (but "zot.val" was OK)

  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.

20010514
  Fix a glitch with "unused" variables -- ones that do not appear in
the presolved problem.  Under somewhat unusual conditions, "unused"
variables that appeared in constraints deduced always to be slack were
not projected onto their bounds, which could result in infeasible
constraints after the message "Solution determined by presolve."
Example:
	var x{i in 0..3} >= i <= i^2;
	s.t. zot{i in 0..2}: x[i] <= x[i+1] + 1;
	solve;	# Solution determined by presolve
	display x, x.slack, zot.slack;	# x[3] was being left 0

20010517
  Fix a bug that appears to have crept in at version 19980127:  an
incorrect opcode was emitted for character-valued "if" expressions
used as arguments to imported functions, as in

	var x; function foo;
	minimize zot: foo(x, if x >= 3 then 'abc' else 'wxyz');

  Fix a bug computing dual values in some problems involving both
linear and nonlinear defined variables used in certain ways:  it was
possible for some dual values to be miscomputed.  Example:

	set I := 1..3; var x{I};
	var y = sum{i in I} (x[i] - i)^2;
	var z = sum{i in I} i*x[i];
	var w = y + z;
	minimize zot: w;
	s.t. convex: sum{i in I} x[i] == 1;
	s.t. nneg{i in I}: x[i] >= 0;
	solve; display nneg; # nneg[1] should be 0.5, not 0.

20010524
  Fix a bug in handling complementarity problems involving defined
variables that may be split into linear and purely nonlinear parts.

20010613
  Fix bug (fault) with the following erroneous input:
	data; 'stuff'
  Under -R, restrict remove commands to alphanumeric file names
(and depend on directory and file permissions to control what can
and cannot be removed and written).
  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.

20010709
  Fix bugs (possible faults, or worse) with the delete command applied
to variables, constraints, and objectives under the "right" conditions.

20010724
  Fix longstanding bug with display commands iterated over sets of
arity > 1:  a fault or a surprising error message about too much
memory (or worse) was possible.  Example:

	set A; set B dimen 2; param p{A, B};
	data;
	set A := a b;
	set B := (w,x) (w,y) (x,y) (x,z);
	param p
	[a,*,*]: x	y	z :=
	w	1.1	2.2	.
	x	.	2	3.3

	[b,*,*]: x	y	z :=
	w	4.4	5.5	.
	x	.	4	6.6;

	display{(j,k) in B}: sum{i in A} p[i,j,k];

20010816
  Fix bug in handling table declarations with one key column that
coincides with an intermediate string in the list of strings that
precedes the key-spec:  table handlers saw an incorrect list of
strings.  In some cases, this could result in a fault, as in

	set E;
	table Zap IN 'ODBC' 'foo.xls' 'Blop' 'verbose': E <- [Blop];
	read table Zap;
	display E;

  Fix bug with "option substout 1":  constraints of the form
	x = x + stuff_not_involving_x
led to the error message "solve_out bug!".  Example:

	var x; var y := 1; minimize foo: sin(x);
	s.t. zot: x = x + y^2 - 2; option substout 1;
	solve; display x, y;	# solve_out bug!

  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).

20010817
  Fix glitch with update data for subscripted symbolic parameters:
all subscripts were treated as the first subscript.  Example:
	set A; param p{A} symbolic;
	data; param :A: p :=
	a abc
	b def
	c ghi
	z xyz
	;
	display p;
	update data p; data;
	param p := c pqr b jkl;
	display p;	# wrong p['a'], p['c'], and p['b']

  Again adjust things so
	reset; print Uniform01(); reset; print Uniform01();
prints the same value twice -- the previous attempt (20010123)
was wrong.  This change only matters if there were no declarations
before the "reset;".

20010927
  Fix an obscure presolve bug that led to an error message of the form
	presolve has k = 708, P.nfc = 704

20011004
  Fix a glitch in handling /* ... */ comments:  under unusual conditions,
an inappropriate end-of-file message was possible.
  Fix a bug in handling suffix declarations with complicated bounds on
the suffix values: a fault was possible.

20011119
  Fix glitches with printf:
	printf "%3.0f\n", .1;	# gave " 0" rather than "  0"
	printf "%3.-2f\n", 1;	# gave "   00" rather than "  0"
  Ensure that A union B puts members of A first.  Usually it did, but
under some conditions the members of B came first.
  Fix bug with "reset data x;" when x is a recursively defined param
or set:  entities that depended on x were sometimes not recomputed.
Example:
	param p{i in 1..6} := floor(Uniform(1,5)) + if i > 1 then p[i-1];
	set S := setof{i in 1..6} p[i];
	display S;
	reset data p;
	display p;	# S was recomputed correctly without this line.
	display S;	# retained the old values (after "display p;")

20011206
  Fix bug with "solve": with a sequence of commands that first cause
the current problem to be instantiated, then change the values of some
variables, then have a "write" command followed by a "solve" command,
the "solve" command wrote a new (temporary) .nl file rather than using
the one written by the "write" command.  One way this manifests itself
is that the "write" command writes auxiliary files based on $auxfiles,
whereas when the "solve" command writes a temporary file, it writes
auxiliary files based on $($solver)_auxfiles.  Example (using solver
linrc from "Hooking Your Solver to AMPL"):
	model diet.mod; data diet.dat;
	write 0; #instantiate the problem
	let Buy['BEEF'] := 1;
	option auxfiles rc, solver linrc;
	write gdiet; solve;	# names from diet.mod were not shown
  Fix a bug (possible fault, or worse) in simplifying nonlinear
expressions involving piecewise-linear terms when presolve fixes a
variable.  (Such expressions are best avoided when using solvers
that expect continuous derivatives.)
  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.

20011211
  Fix a bug with the "option linelim 1" processing change of 5 days
ago (version 20011206) that could lead to a fault or wrong results.

20011213
  Fix fault in parsing
	{ ... repeat while(...){...}}
(with no semi-colon after the first right-brace, the one meant to end
the repeat loop without the optional trailing while or until clause).
Infer the missing semi-colon.  Example:

	param p default 0;
	for{i in 1..6} {
		repeat while(p < 3) {
			display p;
			let p := p + 1;
			}	# missing ; here
		}

  Fix longstanding bug in handling a nonlinear piecewise-linear
expression applied to a subscripted variable, where the subscript
only involves dummies from an outer context and the expression
appears in an inner one (such as a sum).  The bug led to a surprising
error message ("tva top error") in the following example:

	set I; set K; var b{I} binary; var x{K};
	param np integer > 1;
	set J ordered := 1..np; set J1 ordered := 1 .. np-1;
	param p{J1}; param q{J};
	var d{k in K} = sum{i in I} b[i]*
		<<{j in J1}p[j]; {j in J}q[j]>>x[k];
	minimize zap: sum{k in K} sin(d[k]);
	data; set I := a b; set K := c d; param np := 2;
	param	:	p	q :=
		1	1	2
		2	.	3;
	write 0; # gave "tva top error"

20011231
  Fix bug with single-step mode "next" command:  a fault or surprising
error message was possible, e.g., with "next" applied to the repeat
loop in NEW/LOOP1/steelT.sa6 in the AMPL web site.
  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.)

20020129
  Fix a bug (possible fault) simplifying certain complicated nonlinear
expressions involving constant terms.  A simple example seems hard to
find.
  Fix a bug that led to the surprising error message
	unexpected nonvariable type 5698 = 0x1642 in eput
in a complicated example.

20020409
 Fix a bug simplifying complementarity conditions.  Example:
	var x; var y;
	s.t. foo: x <= 1 complements y >= 0;
	s.t. ylb: y >= 1;
	write 0;
got error message "presolve has k = 0, P.nfc = -1".
  Fix a bug with { cmdlist } at the outermost level.  A fault (or worse)
was possible after a subsequent error message.
  Fix a bug with "reset data foo;" when foo had a := value involving
random functions:  entities that depended indirectly on foo were not
necessarily updated automatically, e.g., at subsequent solve or write
commands.
  Give a less confusing error message for attempts to assign symbolic
suffix values when the corresponding _table option has the wrong form.
  Warn about attempts to delete system entities (such as synonyms and
system sets), rather than silently ignoring delete commands that
mention them.
  Warn of inappropriate use of suffixes on synonyms.
  Fix glitch in display of entity.suffix_num: sometimes "_num" was
omitted.
  Suppose $send_suffixes is 0 or 1.  Then solvers are (and have always
been) instructed not to return any suffix values.  Now if the solver
returns suffix values anyway or a "solution" command sees updated
suffix values, the returned suffix values are ignored.
  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.

20020424
  Fix bug with "let{...} S := set_expr;" when S is a set and the
set_expr involves S:  parts of the set_expr were not recomputed.
(It's generally better to use other constructs, such as setof{...}
or union{...}, but iterated let commands should work on sets.)
  Fix bug handling defined variables when $presolve is 0:  empty
constraints were mishandled, leading perhaps to a fault (or worse).

20020425
  Fix bug introduced 20020424 that affected "let S := set_expr"
with set_expr involving S and the let command contained in a
"for" loop.  During the second and subsequent loop iterations,
set_expr was miscomputed.

20020426
  Refix bug introduced 20020424 that affected "let S := set_expr"
with set_expr involving S and the let command contained in a
"for" loop.  Last night's fix did not work in all cases.

20020503
  Complain about "model ..." within compound commands or during
single stepping.  Previously,
	for{i in S} { model (i & '.mod'); }
could fault.
  Add SnprintF and VsnprintF to AmplExports, to make snprintf and
vsnprintf available to imported functions.

20020508
  To avoid breaking some scripts, again permit "model (...);" within
compound commands when ... does not involve loop dummies.  Note that
the effect is similar to "model; include filename" in that the file
is read before the command is executed.  In particular,
	param p symbolic default 'zip';
	for{i in 1 .. 2} {
		let p := 'zap';
		model (p);
		}
will read file 'zip' once -- and not read 'zap' at all.

20020516
  Fix a memory-corrupting bug with sequences of commands that solve
a problem with nonconvex piecewise-linear terms, update something
(without "reset;"), and solve another such problem.

20020528
  Fix an obscure bug that caused a fault when encountered (in accessing
an "unused" defined variable).  A simple example seems hard to find.

20020602
  Fix possible fault (or worse) in recovering from an error that
terminates a "read" command.
  Fix a bug in read commands:  some expressions involving loop dummies
were not recomputed.  For example, in

	param n := 3;
	param foo{1..n}; param goo{i in 1..n, j in 1..foo[i]};
	data; param foo := 1 4 2 3 3 7;

	read {i in 1..n} ({j in 1..foo[i]} goo[i,j]);
	10 20 30 40
	1 2 3
	100 200 300 400 500 600 700
	display goo;

foo[i] was not recomputed when loop dummy i changed.  This resulted in
the surprising error message "invalid subscript goo[2,4]".

20020622
  Fix some minor storage leaks that become visible with many
repetitions of a "commands" command.  Workaround:  use "include"
when the commands file does not change.
  Suppress the complaint about a scalar variable or parameter not taking
any subscripts when it is iterated as a constant output column in a
table.  Workaround:  add 0 (or, for symbolic param, concatenate "").
  Fix long-standing reference-counting bug in turning {..., {A,B}, ...}
into {..., A,B, ...}.  Workaround:  write the simpler forms yourself.

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.
  Fix bug handling multiple objectives:  when objectives were reordered
because some nonlinear objectives were declared before linear ones,
the sense of optimization (minimize or maximize) was not similarly
reordered.
  Obscure correction:  in block mode, error messages from "read table"
and "write table" will now have "kind" values "read_table" and
"write_table" rather than "read table" and "write table".

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.
  Fix bug in generating variable names after redeclare under complicated
conditions.  Example:

	set I := 1..2; set J := 1..5; param A{I,J} := Uniform01();
	var x{J} >= 0; var u{I};
	dual{j in J}: sum{i in I} A[i,j]*u[i] <= 1;
	con{i in I}: sum{j in J} A[i,j]*x[j] == 1;
	problem p: x, u, dual, con; problem p;
	redeclare s.t. dual{j in J} : sum{i in I} A[i,j]*u[i] <= 1;
	expand _scon[1];	# showed x rather than u as variables

  Fix bug in "display _ccon;", which should give the same results as
"display _ccon.slack;".
  Fix obscure bug with iterated "let" commands involving an entity with
a constant subscript appearing on both sides of the := operator:
expressions involving it on the right-hand side were not recomputed
(as it was erroneously regarded as constant).  Example:

	set A; param p{A} default 4;
	data; set A :=  a b c;
	let{i in 1..10} p['b'] := p['b'] + 1;
	display p;	# showed p['b'] = 5 rather than 14

  Fix similar bugs involving synonyms and declared suffixes.
  Add #ifdef __APPLE__ stuff to funcadd1.c and mac.c for Mac OS X.

20020801
  Fix bug with declared suffixes on subscripted problems (an obscure
feature):  a sequence of the form

	set A; problem foo{A}; suffix zot;
	problem foo[something];
	let foo[something].zot := ...;
	problem foo[something_else];
	let foo[something_else].zot := ...;

could have corrupted memory.
  Tweak to single-step mode: accept a semicolon or white space after
the optional repetition count after "next", "skip", and "step".
  Fix glitches with the display command's handling of $display_width
when formatting 2D tables:  sometimes a column heading $n appeared
unnecessarily (and "$n = ..." lines sometimes incorrectly involved
quotes).
  Fix bug writing .nl files for complementarity problems when
$var_bounds is 2:  incorrect complementarity conditions might have
been indicated.
  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

20020806
  Fix a bug (possible fault or worse) in a sequence of the form
	solve;	# with defined variables that get split
		# into linear and nonlinear parts
	# ...
	solve;	# with no defined variables
  Fix bugs (faults) in handling table declarations involving suffixes
on subscripted entities appearing within expressions, such as
diet[i].slack and _con[i].slack in the "such that" parts of the set
expressions in the following table declarations:
	model diet.mod;
	table ds OUT 'ds.tab': [NUTR]
		{i in NUTR: diet[i].slack > 0} diet[i].slack ~ Slack;
	table dsyn OUT 'dsyn.tab': [I]
		{i in 1.._ncons: _con[i].slack > 0} _con[i].slack ~ Slack;

20020807
  Fix bug in computing cc1.Lbody and cc2.Rbody, where cc1 and cc2 are
complementarity constraints with a single expression (no finite
bounds) to the right and left, respectively, of "complements":  the
constant term (if any) was omitted.  (This did not affect the problem
seen by the solver.)
  Fix bug with "expand _con[n];" when _con[n] is a complementarity
constraint:  for n > 0, the wrong constraint was expanded.

20020814
  Fix faults with
	drop {...} X;
where X is an indexed collection of objectives or constraints; this
includes {if logical_expression} indexing.  Fix analogous faults with
restore, fix, and unfix.
  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.
  Correct error message for

	set S ordered; data; set S := a b c d;
	reset data S; data; set S := a b '3' d '5';
	print next('5',S);

-- the set name "S" got lost in "reset data S", and the error message
showed the entire contents of S.  Now it just mentions "S".
  In error messages for next() and prev(), quote symbolic members (to
distinguish, e.g., 3 and "3").
  Fix bug with recursive set and parameter definitions involving
certain complicated indexing expressions, resulting in a surprising
error message: "cp_lookup: unexpected hit".  Example:

	param N := 100;
	param odd {i in 1..N} :=
	   if i = 1 then 3 else
	      min {j in odd[i-1]+2..odd[i-1]*2 by 2:
	         not exists {k in 1..i-1} j mod odd[k] = 0} j;
	display odd;

  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.

20020819
  Fix some glitches (resulting in surprising error messages) with the
handling of OUT and INOUT arguments in imported functions with certain
signatures, such as (INOUT ...) and (IN, {i in A} (INOUT), OUT).  Also
fix some glitches in "redeclare function ...".
  Fix a bug with switching problems after an explicit environ command:
the change to the environment was sometimes not recorded.

20020820
  Fix bug in handling defined variables that only appear in piecewise-linear
terms:  they were treated as unused in a way that led to surprising appearance
of nonlinearity.  Temporary work-around: "option linelim 5;".
  Correct a botch in yesterday's saving of problem environments.
  tables/ampltabl.dll: report more when SQLNumResultCols fails unexpectedly.

20020823
  Fix a bug in computing dual values for problems with nonconvex
piecewise-linear terms.  Reduced costs for variables appearing in such
terms may not have been right, and a fault was likely if the problem
involved defined variables.
  Fix a glitch with displays of scalars whose descriptions take more
than one line:  only consider the length of the last line when deciding
whether $display_width permits showing the value on the same line.

20020827
  Obscure bug fix to printf.c, fprintf, sprintf:  on systems with IEEE
arithmetic, get an explicitly requested sign of zero right under
format %+e.  Example:  printf "%+e\n", -0;

20020917
  Fix bug in parsing unquoted file names that contain nonalphanumeric
characters (such as /, \, or :) and fall on a block boundary (multiple
of 4096).  Workaround:  quote such file names.

20020924
  Fix bugs with problem command:  if foo is a subscripted problem, and
"problem foo;" reports foo[subscript] current, have "problem foo;"
and "delete problem foo;" discard the subscript.  Fix fault with
"problem foo{1..3}; problem goo;".
  When foo is a subscripted problem whose declaration does not specify
a subscripted environment, have "problem foo;" make foo's environment
current.
  Fix a rarely seen bug in presolve's conversion of nonlinear
expressions to linear expressions (after fixing of some variables).
If the bug bit, it could cause a surprising "vT bug" error message (or
could cause some range estimates in presolve to be overly pessimistic,
which might lead to worse presolve results but was otherwise
harmless).
  Fix bugs handling double inequalities involving string expressions.
Faults were highly likely.

20021002
  Fix bug handling equality complements expression under option presolve 0.
Workarounds:  leave $presolve alone or simply express such constraints as
ordinary equality constraints.
  Fix bug (fault) introduced 20020807 in computing cc.Lbody and cc.Rbody
when cc is a complementarity constraint with a single inequality
constraint on each side of "complements".
  Fix bug introduced 20020807 in computing .slack for complementarity
constraints with a double inequality complementing an expression.
  Fix bug with "expand _scon[n];" when the declared constraint is not
subscripted.

20021009
  Fix an optimization bug with "first" and "last", which could be
erroneously evaluated on an empty set when lifted to an outer
context (in a complicated indexing expression).  If the bug bit,
it resulted in a surprising error message.

20021025
  Fix bug that gave error message "OPDIV botch" when presolve detected
division by zero.  Example:

	var x >= 0; var y;
	minimize zot: x/y;
	s.t. ydef: y = 0;
	solve;

  Fix an obscure bug with "option substout 1;":  after AMPL obtained
a solution from the solver, it did not compute the values of variables
eliminated from the problem sent to the solver until needed.  Changes
affecting or eliminating the defining constraints would then influence
the values computed for such variables.  Now their values are computed
when a "solve" or "solution" command obtains the solution.  Unlike
variables declared with a defining value (= expression), a variable
eliminated by "option substout 1" has never been automatically updated
when something in its defining constraint changes.
  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.
  Fix a bug in processing complementarity constraints that caused
	inequality complements equality
simply to be treated as the equality.  Now an error message results.
(The bug also let some inappropriate operators, such as <, >, and !=,
slip by, which could have led to a subsequent fault.)

20021031
  Fix another bug (possible fault or wrong values) in computing dual
values for problems with piecewise-linear terms.

20021108
  Fix a bug with use of at_exit() or at_reset() in imported functions:
the library was freed before the functions registered with at_exit
or at_reset were called, sometimes leading to a fault.

20021202
  Fix glitch introduced 20021025 with variables involved in
piecewise-linear terms:  after a "solve" or "solution" command, a
change (e.g. by a "let" command) that caused recomputation of defined
variables could result in variables that appear piecewise-linear
terms to have the wrong value.  Using "option pl_linearize 5;" is a
temporary work-around.
  Fix a performance glitch with "let" that caused an assignment to a
numeric param of its current value to be treated as a change to the
param's value.

20030103
  Fix a bug (possibly leading to a fault or incorrect execution)
in turning {..., A cross B, ...} into {..., A, B, ...} in sets and
indexing expressions.  Work-around:  write the latter form.

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.)

20030217
  Fix a bug (introduced 20030204) in the "expand" command's handling
of complementarity constraints:  the wrong constraints were sometimes
shown.

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.

20030310
  Fix a glitch with random number generation in the Linux version
of AMPL (introduced 20030204 by a compiler update):  e.g.,
Uniform01() was often outside [0, 1].

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
  Fix bugs (faults) with references to _svar[n].suffix when _svar[n]
was created by linearization of nonconvex piecewise-linear terms.
  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.

20030414
  Fix bug introduced 20030204 in "option var_bounds 2":  the count of
Jacobian nonzeros was misreported, which could cause some solvers to
fault.

20030502
  Fix a glitch in reading .sol files:  solvers are supposed to be able
to assign suffix values to the current named problem, but such values
were being ignored.

20030508
  Fix glitches with some expressions involving _con, _scon, _obj, and
_sobj when the relevant constraint or objective was partially dropped.
E.g., "let _con[...] := ...;" and "print _obj[...];" were affected.
  Fix a botch (introduced 20030204) in the show command:  it reported
the wrong entity type for some things:  "show e;" said "setvars: ..."
instead of "environments: ...", "show su;" said "xhatBUGs: ..."
instead of "suffixes: ...", and "show t;" said "<NULL>s: ..."
instead of "tables: ...".

20030513
  Fix a longstanding and apparently rarely visible memory-overwrite
bug in the display command's insertion of dummy variable names into
the expressions it echoes.  The offending lines in an example that
revealed the bug were
	display {f in A}: sqrt(cov[f,f]);
	var x{B};
with length(f) in the "right" range of values for some f in A.  In the
example, the bug was revealed at the parsing of x in the "var x{B};"
declaration.

20030514
  Fix a glitch in the "let" command's assigning values to declared
suffixes of objectives:  with some sequences of commands, an
inappropriate error message about "ungenerated ???" appeared.
Example:
	model diet.mod; data diet.dat;
	suffix foo; let Buy['BEEF'].foo := 23;
	let Total_Cost.foo := 8.2;	#error message

20030517
  Fix a bug with "suffix name expr" phrases in variable declarations
(introduced 20030204) that resulted in OUT suffix values not being
transmitted to solvers.

20030527
  Fix a bug in the MS Windows version with option solver settings
that start with a driver letter and colon and do not end in .exe.
(Work-around:  append .exe explicitly.)
  Fix a bug (introduced 20030204) with "expand _con;" (no subscript),
which faulted.
  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.

20030602
  Fix a rarely visible glitch only known to affect Linux binaries
starting with 20030204 (introduced by a compiler update).  The example
behind this fix gave "invalid refct 0 in opgen".

20030605
  Fix memory-overwrite bugs that were possible when an entity with
a 0-dimensional slice was instantiated.  Scripts involving such
declarations were automatically terminated, but instantiations were
possible with interactive commands.  Reduce the Warning about a
0-dimensional slice to a Caution, so scripts involving such slices
may now run.

20030617
  Fix an obscure bug with the interaction of problem declarations,
loops, certain generic synonym references, and commands that should
not depend on the current problem, such as the print command in the
following silly example, in which the print command elicited an error
message about n not having a value:

	var x; minimize zot: (x-2)^2;
	param n; minimize bletch: (x-n)^2;
	problem foo: x, zot;
	problem goo: x, bletch;
	repeat{
		print 'Starting repeat loop';
		problem foo; solve;
		let n := _ncons + 2; problem goo; solve;
		if _ncons > 0 then display _con[1].slack;
		} until n > 0;

20030625
  Fix a rarely seen bug in handling positive values of option
presolve_inteps when "solve" or "solution" read a .sol file.  If the
bug bit, an "option presolve_inteps 0" command appeared, perhaps
followed by a complaint about a wrong number of variables.

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.

20030707
  Fix a glitch, introduced 20030204, in handling function evaluations:
subscripted variables appearing as arguments were treated as "constant",
as were some other kinds of expressions involving variables.  For
example, in

	set A; var x{A};
	function f;
	var y = sum{i in A} f(x[i]);
	minimize zot: y^2;

the "var y =" declaration elicited the incorrect diagnostic

	Caution: y should be "param :=" rather than "var =".

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.

20031112
  Fix a glitch (possible segment fault, probably introduced in version
20030204) in "if" expressions involving variables.

20031202
  Fix a bug (fault) with the Unix/Linux invocation "ampl 2>file".

20040103
  Fix a bug in "write table"'s handling of a possibly subscripted but
otherwise unadorned constraint name:  if the constraint was eliminated
by presolve, its dual value may not have been computed (depending on
the preceding commands).
  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.

20040202
  Banish the inappropriate error message
	"Cannot assign a value to ungenerated ??? p."
that was given for

	set A default {}; var p{A};
	let{i in A} p[i].relax := 1;

  Fix glitch in presolve that caused some initially "nonlinear" variables
to remain counted as nonlinear even though simplifications rendered them
linear.  An example where this happened:

	set I := 1..3;
	var x{I} >= 0 <= 10 integer;
	minimize zot: sum{i in I} i*x[i];
	s.t. cb: x[1] >= x[2]*x[3];
	fix x[3] := 0;

  Fix fault in handling models with piecewise-linear terms, all of which
get eliminated by presolve, and constraints that would be defining
constraints under -S (i.e., option substout 1).  Example:

	var x; var y; var z >= -3 <= 4;
	s.t. foo: y = (x-1)^2;
	minimize zot: y + <<1;-1,1>>z;
	s.t. bletch: z = 2;

20040210:
  Fix glitch in simplifying nonlinear constraints: a variable multiplied by
a variable expression that presolve determined to be zero was still regarded
as appearing nonlinearly when at least one other nonlinear expression
remained in the constraint.  Example:

	var x{1..3} >= 0; var z >= 0 <= 0;
	s.t. zot: z*x[1] + x[2]*x[3] >= 3;
	s.t. zap: x[1] >= x[2] * x[3];
	# x[1] was recorded as a nonlinear variable

  In the example

	set I := 1..3;
	var x{I} >= 0 <= 10 integer;
	minimize zot: sum{i in I} i*x[i];
	s.t. cb: x[1] >= x[2]*x[3];
	fix x[3] := 0;

mentioned in the changes of 20040202, recognize that constraint cb
reduces to a bound on x[1].

20040229
  Minor tweak to change of 20040210 to permit deducing stronger bounds
in some cases after detecting multiplication by zero has made some
nonlinearities go away.
  Fix a glitch in sequences of the form

	write ...;
	shell ...;	# obtain a .sol file for the .nl file just written
	option ...;	# change $presolve and perhaps some presolve tolerances
	solution ...;	# read the .sol file

If $presolve was increased, the solution command might have
inappropriately caused changes to other presolve tolerances.
(Such changes are indicated by the echoing of option commands.)

20040422
  Fix a bug that might have surfaced after an error message about discarded
subscripts immediately followed by "Bailing out after n warnings".
  Fix a fault in the error message for the circular definition of y in

	var x; var y{i in 1..3} = if i == 1 then y[3] else x*y[i-1];
	minimize zot: y[3]; write 0;

  Introduce new error message to diagnose scalar "defined" variables that
involve themselves, as in "var q = q*sin(q);".  As before, such constructs
introduce constraints, but now they elicit an error message saying so.

20040515
  Fix an obscure bug that gave an equally obscure error message:
"unexpected type 0x16e0 in massage()".

20040604
  Fix a bug in simplifying nonlinear constraints after presolve fixed
nonlinear variables appearing in the constraints.  When the bug bit,
inequality constraints might have been treated as equalities in some
bound computations, possibly resulting in incorrect bounds or even the
incorrect fixing of variables, including defined variables.

20040613
  Fix a fault possible with "solve" after some (unusual) sequences of
commands, such as

	model foo.mod; data foo.dat; display someconstr; solve;

where someconstr is a constraint and the .mod and .dat values are what
they claim to be -- files containing a model and data and nothing
else.  [One often sees the bad practice of including commands in .mod
and .dat files.]  Note that the [dual variable] value(s) printed for
someconstr would all be zero unless someconstr's declaration specified
a dual initial guess.

20040821
  When the problem size in the student edition of AMPL is exceeded, have
the error message say "the student edition of AMPL is limited..." rather
than just ""the student edition is limited...".
  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).
  Fix a bug with discarded subscripts, illustrated by

	set A; param p{A};
	data; set A := a b c;
	param p := a 1 d 2 c 3 b 4;
	display p;	# correctly complains about p['d']
	display p['c'];	# incorrectly said "invalid subscript p['d']"

20040827
  Fix a bug that might be revealed by complicated recursive set declarations
and gave the message "cp_lookup: unexpected hit".  Example:

	set A = {1,2};
	set S {s in A} = if s == 1 then {(2,1)}
		else {i in A, j in A: j <= i+1 && exists{k in A}
			((i,k) in S[s-1] || (k,i) in S[s-1])};
	display S;

20040902
  Fix another bug that might be revealed by still more complicated
recursive set declarations and gave the message
"cp_lookup: unexpected hit".

20041110
  Fix a bug (fault) in handling "{if something} expr" in display
commands, e.g.,

	display {if 0 == 0} 1;

20050208
  Fix a bug (fault, or worse) in handling default expressions in
certain situations with common subscript expressions.  An example that
gave the surprising error message "set::rehash finds duplicate entry":

	set A; param p = 27;
	param q{A} default 1;
	var x{A};
	minimize zot: sum{i in A} q[i]*x[i];
	data; set A := a b c d;
	let {i in A: q[i] > 0} q[i] := q[i]*p;
	write 0;

20050424
  Fix glitch with display statement formatting of 2-D tables in
which all row labels are '' (the empty string):  the row labels
were taken to have width 0 instead of 2 (for the quotes).  Example:

	param n; set I = 1..n; param c {I};
	data; param n := 5;
	param c := 1 16  2 22  3 12  4 8  5 5;
	option dis*1col 0;
	option display_transpose -10;
	# columns did not line up right in the following display command:
	display{j in {''},  i in I} c[i];

  Fix glitch with sets and params constructed from random functions:
sometimes the random expressions were surprisingly re-evaluated.  Example:

	set A{1..2} = {Uniform01(), Uniform01()};
	display A;
	display A;	# values had changed

  Fix glitch with {if ...} indexing of objectives and constraints:  after
an "expand" command elicited a complaint about ... being false and a change
that made ... true, an "unexpected ctype" message was possible.  Example:

	var x;
	param N default 1;
	minimize foo{if N >= 2}: (x-1)^N;
	expand foo;
	let N := 2;
	expand foo;	# gave unexpected ctype 536871429 in compile_objectives

  Fix a rarely seen bug that manifested itself only under complicated
circumstances.

20050503
  Fix bug in reflecting bounds on defined:  under conditions hard to
predict (but apparently not often seen), some constraints were
inappropriately relaxed.  To see if the bug bit,
	print min{i in 1.._ncons} _con[i].slack;
which should be non-negative but for roundoff.  Work-around:
	option substout 4;

20050530
  Fix a bug with the read command's handling of iterated arguments: a
fault (or worse) was possible under conditions hard to predict.  An example
where the bug caused a fault:
	set A dimen 2; param E{A};
	set I = setof{(i,j) in A} i;
	set J = setof{(i,j) in A} j;
	param y{I};
	let A := {1..699,1..3};
	read{i in I} y[i] < 'y';
	for{j in J} read{i in I} E[i,j] < ('pred' & j);	#fault

  If a "read" command issued in interactive mode encounters end-of-file,
permit further interactive input.
  Fix bug ("level has impossible levbits") with iterated print, printf,
and read commands with redirections that vary with the iteration.
Example:

	print{i in 2..3}: {j in 1..3} j^i > ('x' & i);

  Fix a bug possible only in interactive mode after an error message (such
as "no value for ...") interrupts processing.  Example:

	set A dimen 2; param E{A};
	set I = setof {(i,j) in A} i;
	set J = setof {(i,j) in A} j;
	var x{J} >= 0;
	set Ap = {(i,j) in A: E[i,j] < 0};
	minimize ssq: sum{i in I} (sum{(i,j) in Ap} E[i,j]*x[j])^2;
	s.t. convex: sum{i in J} x[i] = 1;

	let A := {1..208,1..5};
	solve;
	#ampl: Error executing "solve" command:
	#error processing set Ap:
	#        no value for E[1,1]
	read{j in J}: {i in I} E[i,j] <('foo' & j);
	solve; #Segmentation fault

20050614
  Fix bug with "redeclare":  things were not always recomputed after
"redeclare" should have changed their values.  Example:

	set I := 1..3; set J := 1..4; set B within {I,J};
	param Maj = floor(card(J)) + 1;
	set BV = {i in I: card{(i,j) in B} >= Maj};
	data; set B := (1,2) (1,4) (2,2) (2,3) (2,4) (3,1) (3,3) (3,4);
	display Maj, BV;

	redeclare param Maj = floor(card(J)/2) + 1;
	printf "\nUpdated Maj = %d\n", Maj;
	display BV;	# said "set BV := ;# empty"
			# rather than "set BV := 2 3;"

  Fix bug with a slice on a set not yet given a value.  Example:

	set A dimen 2; param E{A};
	set I = setof {(i,j) in A} i;	set J = setof {(i,j) in A} j;
	var x{J} >= 0;			set Ap = {(i,j) in A: E[i,j] < 0};
	minimize e: sum{i in I} (sum{(i,j) in Ap} E[i,j]*x[j])^2;
	data; set A := a b  a c  a d  b c  c d;
	expand e; # no value for E['a','b']

	data; param E := a b 1.2  a c -2.3  a d 3.4  b c -4.5  c d 5.6;
	expand e; # was "0"; should be (-2.3*x['c'])^2 + (-4.5*x['c'])^2;

20050624
  Fix long-standing bug in the "display" command's handling of
entities indexed over an ordered set of arity 1:  the ordering was
ignored.  Example:

	set WEEKS ordered; param avail{WEEKS} >=0;
	data; set WEEKS := 27sep 04oct 11oct 18oct ;
	param avail := 27sep 40 04oct 40 11oct 32 18oct 40 ;
	display avail;	# listed 04Oct first rather than 27sep

  Fix glitches with complementarity constraints.  Nonlinear defined
variables were sometimes mishandled (a bug that crept into version
20040422).  Assignments of dual values to complementarity constraint
names sometimes led to subsequent faults (or worse).  Note that when
ccname is an unsubscripted complementarity constraint, "let ccname :=
value;" is the same as "let ccname.Ldual := value;".

20050702
  Fix a bug with recomputing reduced costs after a change to $abs_boundtol
or $rel_boundtol that could affect the reduced costs:  dual values for
constraints eliminated by presolve were sometimes miscomputed.  The bug
was revealed by a command sequence of the form

	option abs_boundtol 1e-5;
	solve; display _con;
	option abs_boundtol 0; display _con;
	option abs_boundtol 1e-5; display _con;

in which "display _con" caused reduced costs and dual values for
constraints removed by presolve to be computed.
  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.

20050711
  Fix a bug with assigning values to variables by "read table" or by
calls on imported functions with OUT arguments:  absent a previous
"solve", the newly assigned values were not passed to solvers.

20050818
  Fix a bug (e.g., fault) with iterated printf commands whose format
varies with the iterate.  Example:

	printf{i in 1..10} (if i mod 2 == 0 then "%s\n" else "%s "), i;
	# faulted

20050904
  Fix glitch with use of "integer" or "logical" in recursive
definitions.  Example:

	param factorial{i in Integers} integer =
		if i <= 0 then 1 else i*factorial[i-1];
	display{i in 1..4} factorial[i];

gave the surprising error message "unexpected type 0x6500 in cpexpr()".

20050908
  Fix a botch (fault) introduced 20050818 with simple iterated printf
commands, such as

	printf {i in 1..2} "%d\n", i;

20050910
  Adjust error messages for recursive definitions to show what basic
entity was being instantiated (the one that directly or indirectly
referenced the recursive set or param).  Misleading error messages
were previously possible (as illustrated by a complicated example).

20050927
  Fix a bug in handling nested "if" statements without {} enclosing
"then" parts and no outer "else" part:  following statement was
only executed if the outer "if" was true.  Example:

	if 1 == 2 then if 3 == 4 then display 5;
	display 6;	# was not executed

  Fix a bug with "reset data": supplying larger sets in a data section
sometimes led to a fault in subsequent commands.

  Fix a glitch in simplifying nonlinear expressions that end up being
linear:  simplifications from expr1 * expr2 to constant * linear were
sometimes treated as nonlinear, possibly resulting in the solver
linear constraints marked "nonlinear" or perhaps in presolve not making
as strong deductions as it should.

20051010
  Fix a glitch in "show x;" where x is a nonlinear defined variable:
a double minus sign was sometimes unnecessarily produced.  Example:
	var x; var y = x^2 + 1;
	show y;	# said "var y = --(x^2 + 1)" instead of just "x^2 + 1".

20051012
  Fix a bug in handling conditionally evaluated expressions:  when
such an expression occurred more than once, it was sometimes evaluated
even though a guard condition implied it should not be evaluated.
Example:
	set A; set B ordered; set C;
	param p{A,C};  param q{A};
	param r{i in A} = sum{j in B: j in C && q[i]/p[i,j] < 2.4}
				ord(j)*(q[i]/p[i,j]);
	data;
	set A := a b c;
	set B := x y z;
	set C := x z;
	param p: x	z :=
	a	1.3	2.4
	b	4.9	0.3
	c	.23	.45
	;
	param q := a 5.2 b 6.7 c .23;
	display r;	# gave "invalid subscript p['a','y']"

20051016
  Fix some bugs with logical constraints (a forthcoming feature):
"a ==> b else c" was not handled in presolve, and declaring a suffix
after declaring a logical constraint led to a fault.

20051110
  Fix a bug with problems having both logical constraints (a forthcoming
feature) and defined variables:  incorrect .nl files were written.

20051119
  Fix a bug with suffix declarations or some redeclare statements
appearing after function declarations:  a fault or other confusion was
possible.

20051128
  Fix glitch in writing .row files:  if the model contained both
logical constraints and defined variables, wrong name were emitted
for the logical constraints.
  Fix bug in non-iterated read commands that start with an iterated
item, followed by another item, such as

	read {i in A} p[i], q;

The second and subsequent items (q in the example) were ignored.

20051202
  Fix bug in handling suffixes on constraints when logical constraints
are present.

20060314
  Fix a bug with handling end-of-file in a read command, i.e., in
"read ... <filename;".  A fault, or worse, was possible.
  Fix a bug with handling comparisons whose outcome is known,
such as the test p[i] != ' ' in the following (the result is
always false, since p is restricted by default to numeric values):
	set A; param p{A}; set B = {i in A: p[i] != ' '};
The bug could only bite if the same expression occurred elsewhere;
if the bug bit, the error message "unexpected type 0x4b00 in
same_expr()" appeared.
  Fix a bug with complementarity problems involving defined variables.
The bug caused an invalid .nl file to be generated -- and the solver
to fault.
  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).

20060331
  Fix a typo in an error message ("errror" rather than "error").
  Fix a bug (possible fault, or worse) with "expand" on 64-bit
systems.

20060408
  Fix a bug handling long comments (more than 8192 bytes long)
that start with #.
  Fix bugs handling "let _var[...].relax := ...;".  Sometimes the
assignment appeared not to take effect; other times, iterated such let
commands ran surprisingly slowly.
  Fix bugs in "show;" introduced 20060314.

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;".

20060506
  Fix a glitch ("unexpected subtype 13 in prset") with "show" of
a set with an "ordered by" clause.

20060524
  Fix a bug in handling some complicated expressions where an inner
indexing set depends on outer indexes and the inner indexing set
applies to an expression that only involves dummies over the inner
indexing set.  Examples satisfying this description are not hard
to construct, but finding a simple such example where the bug
bit is not easy.  Here is such an example.  (Writing the example
more sensibly avoids the bug.)

	set I = 1..3;  set A = {I,I};  set B = {I,I,I};
	set C{B} default A;
	param p{B} default 0;
	param q{A} default 0;
	let{(i,j,k) in B:  max(	# faulted
		{(a,b) in A: a == i and b == k} q[a,b],
		{(a,b) in C[i,j,k]} q[a,b] ) > 0} p[i,j,k] := 1;
	display p; #empty

20060626
  Fix glitches in "option show_stats 1" introduced 20060430:
the number of linear variables was sometimes not reported or
reported incorrectly, and "0 constraints" was omitted when there
were no constraints.
  Fix longstanding bug in "option show_stats 1":  for nonlinear
constraints, "linear nonzeros" appeared instead of just "nonzeros".

20060725
  Have "display" honor $display_precision when printing symbolic
parameters having numeric values.
  Fix bug (probably introduced 20060314) in the "show" command's
labeling of environments, suffixes, and tables.
  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.
  Fix some glitches in _slogconname when defined variables are present.
  Fix possible fault after diagnosing "0-dimensional slice".
  Omit warning, "This recursive set declaration must specify dimen
before := or default." and instead infer the appropriate dimen.
  Fix bug (incorrect diagnosis of implicit definition) in checking
membership in some complicated recursively-defined sets.
Example:

   set A;
   set P within {A,A};
   set S{n in 1..card(A)} dimen 2 = if n == 1 then P else S[n-1] union
		setof {k in A, (i,k) in S[n-1], (k,j) in S[n-1]} (i,j);
   data;
   set A := a b c d e f;
   set P := a c  b c  c d  e f;

   print if ('a','c') in S[3] then 'yes' else 'no';
   # said "sorry, no implicit definitions: cannot evaluate S['a']"

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."

20060915
  Fix glitch with "reset data x;" where x is a variable or constraint
with random initial value: in the sequence
	solve; reset data x; solve;
the initial value of x was not resampled for the second solve.  Other
commands that required x's value did (and still do) cause resampling.
  Fix bug (fault or surprising error message) with "printf "%f", 1e75;".

20060930
  Fix a bug (fault or worse) in cleaning up after an error message when
regenerating an indexed variable, constraint, or objective after some
change made regenerating necessary.

20061005
  Fix glitches with imported functions:
1.  If-then-else expressions in constraints and objectives with imported
functions appearing only in the "then" or "else" expressions could result
in a complaint about unavailability of the functions.  They might be
available to the solver, so no complaint should appear.  Example:

	function exact;
	param p symbolic;
	var x >= 0 <= 10;
	minimize zot: (if num(p) == p then p else exact(p))*x;
	data;
	param p := '1234567890123456789';
	write 0;	# "Can't invoke unavailable function exact."

2.  If an if-then-else expression in an argument to an imported functions
evaluated by the solver had a non-constant numeric "then" expression and
a string-valued "else" expression or vice versa, confusion resulted in
that a numeric expression might appear where a symbolic one was expected.
Example:

	function goo; var x;
	minimize zot: x*goo(x, if x >= 3 then 'abc' else x+10);
	# new diagnostic: "solve" or "write" now says
	#   Cannot convert a numerical "then" or "else" to string
        #   in if-then-else expressions that solvers must evaluate.

20061007
  Fix bug in handling chains of comparisons involving more than 2
comparisons.  Example:

	print{i in 1..2}: if 1 < i < i^2 > 3 then 'yes' else 'no';
	# printed "no", then faulted

20061023
  Fix an obscure bug that gave rise to error messages such as
	presolve has k = 167168, P.nfc = 166781
  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.

20061030
  Fix a glitch in the display command's use of $n to stand for the
heading of column n:  sometimes the heading was '$n' rather than
simply $n (unquoted), but the quotes were not accounted for, causing
the headings not to line up with the columns beneath them.  Now the
erroneous quotes are gone.  Example:

	set A; set B;
	param p{A,B};
	data;
	set A := 'pumpkin pie' 'ice cream' 'chocolate sauce'
		 'vanilla cream' 'apple pie' strawberries;
	set B := 'New York' 'San Francisco'
		 'San Diego' 'Washington, D.C.';
	param p : 'New York' 'San Francisco'
		  'San Diego' 'Washington, D.C.' :=
	'pumpkin pie'		12	13	14	15	
	'ice cream'		22	23	24	25
	'chocolate sauce'	32	33	34	35
	'vanilla cream'		42	43	44	45
	'apple pie'		52	53	54	55
	strawberries		62	63	64	65;
	
	option display_width 40;
	display p;
	# heading ended with "'$1'   '$2'   '$3'   '$4' :="
	# instead of with    "$1   $2   $3   $4 :="

20061102
  Fix another bug with recursive set definitions.  A fault
revealed the bug, but wrong results without a fault might
sometimes have been possible.

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.

20061130
  Fix glitch with suffixes on random variables (a forthcoming addition).

20070222
  Fix bug apparently introduced 20061005 in calling user-defined
functions:  numeric dummy arguments, such as i in "f({i in 1..3} i)",
were passed to solvers as strings rather than numbers.

20070301
  Fix glitch in "read" command introduced 20060314 that could cause an
immediate "end of file" error message.
  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.

20070312
  Fix bugs in handling variables declared "in Set_expression":
integer and binary were not always properly distinguished when such
variables could be turned into integer or binary variables; with
"option presolve 0", the "in Set_expression" was ignored; and at one
point in presolve, a test for reducing the domain of a variable
using the "in Set_expression" was applied too soon, possibly causing
variables to be fixed inappropriately.  Examples giving rise to these
troubles had the form

	var x in {0, 1, 2};	# or in {0, 1} for the third bug
	var y >= 1, <= 3;
	maximize obj: y;
	subject to r: y <= 2 * x;

20070317
  Fix a bug with option single_step:  if an error (such as a bad
subscript) was reported during single-stepping, things were sometimes
not properly cleaned up, possibly resulting in a subsequent fault.
  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.

Fix bug in variable.astatus when there are unused defined variables.
Example:

	var x;
	var y;
	var u = 4*x + x^2;	# unused
	var z = 3*x^2 + y^2;
	var w;
	minimize zot: z + w;
	s.t. bletch: exp(z) <= 4.2;
	display _varname, _var.astatus;
	# showed "sub" rather than "unused" for u

20070505
  Fix bug during "reset;" with handling at_exit() registrations by
imported functions:  they were lost.
  Fix bug in handling "table" declarations appearing before a suffix
declaration (including implicit suffix declarations that result from
"solve" commands in which the solver returns a new suffix), or that
appear before certain "delete" commands:  confusion, such as a fault
or surprising error message, could result.  Example:
	set I = 1..3;
	var p{I};
	table pt OUT 'pt.tab': {i in I} --> [eye] , p[i];
	suffix zork;
	write table pt;	# "unexpected type..."
  Fix bug with multiple suffix declarations appearing after some
other declarations and a delete command:  a fault or other confusion
was possible.

20070518
  Fix a bug in presolve's handling of variables declared
"in Set_expression".  Such set expressions in general are unions
of intervals (with point values included as degenerate intervals).
If presolve deduced a bound that would eliminate more than one
interval, it botched a bound update.  Example:
	var x in {0, 2, 4, 8};
	s.t. bletch: x <= 2;	# the bug changed 2 to 4
	maximize obj: x;

20070522
  Fix handling of string expressions in "commands (...);" commands
so ... can involve params declared with "= value" but not yet used
in a command.

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.

20070618
  Fix the bug noted in the second "solve" comment of
	var x;
	minimize f: func(x);
	let x := ...;
	solve;	# with no primal or dual values returned, e.g., gjh
	redeclare minimize f: another_func(x);
	solve;	# value assigned by "let" to x not transmitted.

20070712
  Fix bug in handling imported functions that specify a domain for
INOUT arguments with "..." indexing.  For example,
	function f(Reals IN, ...(Reals INOUT));
encountered the bug when invoked, but
	function f(Reals IN, ...(INOUT));
did not.
  Fix a bug in simplifying certain complex logical expressions that
led to the error message "unexpected type 0x11e03 in lsimplify()".
  Fix a bug with named problems that led to the error message
"named_genall called".
  Fix a bug with "delete" and "purge":  when applied to variables,
constraints and objectives, they did not update problem declarations,
which could have led to a fault or other confusion.

20070802
  Fix a bug (infinite loop) in "redeclare set ..." when neither the
old or new set is subscripted.  Example:

	set S; var x{S} >= 0 <= 1;
	set F = {i in S: x[i] in (0,1)};	#error message
	redeclare set F;			# looped

  Fix a glitch with "show p;" for a param p that had data supplied
in a data section.  Example:

	param p; data; param p := 1.7; show p; # mentioned "random"

  Fix a performance bug:  reduce overhead when params and sets without
constraints on their values are updated.

20070825
  Fix a fault in handling "ordered by ..." in certain situations where
... is a set expression, such as a subscripted set.

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.

20071007
  Adjust computations behind "Too much memory used" message to make
the message more accurate when sbrk(0) proves to be unreliable.

20071111
  Fix bug in handling variables unused in the current problem when
defined variables (also unused) were present that depended on the
unused variables, the unused variables and their defined variables
were mishandled, such that commands involving them might see incorrect
values.  Example:

	var x;
	var g = x^3 - x^2 - x - 1;
	var gp = 3*x^2 - 2*x - 1;
	let x := 2;
	display x, g, gp; # OK so far
	let x := x - g/gp;
	display x,g;	# botched values

(It is more appropriate to use "param" rather than "var" in this
example; doing so would have avoided the bug.)
  Fix a bug with redeclarations:  a fault was sometimes possible.
Example:

	set I;
	param p{I};
	var f;
	param q;
	minimize zot: sum{i in I} (f*q^i - p[i])^2;
	s.t. zotc{i in I}: p[i] == f*q^i;
	delete zot;
	set J;
	redeclare s.t. zotc{i in J}: p[i] == f*q^i; # fault

20071121
  Fix bug with "ordered by":  a fault was possible under the "right"
conditions, as in this example:

	set A ordered; param p{A};
	set S ordered by A default{i in A: p[i] == 0};
	data; param :A: p := a 0  b 1  c 0  d 2;
	display S; # faulted

20071222
  Banish an obscure error message "unexpected subtype 23 in sforce".
  Fix fault with "let Set := (expression involving the Set)", e.g.,

	set A default {};
	for{i in 2..4} {
		let A := A union {j in i .. i^2: j in i+2..i+3 diff A};
		display A;
		}

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.

20080128
  Fix a bug giving an erroneous "no data" message in the following:

	set I  = 1..3;
	minimize zot;
	var x{i in I} integer >= 0 obj zot i;
	set S;
	s.t. zap: sum{i in  S} x[i] = 1;
	let {i in 2..3} x[1].relax := 1;	# no data for S
	let S := 1..2;
	solve;

20080202
  Fix another bug giving an erroneous "no data" message under some
circumstances when a defined variable is involved in column
generation.  Example:

	set I  = 1..3;
	minimize zot;
	var x{i in I} integer >= 0 obj zot i;
	var y obj zot 3 = x[3] + 1;
	set S;
	s.t. zap: sum{i in  S} x[i] = 1;
	let {i in 2..3} x[1].relax := 1;	# no data for S
	let S := 1..2;
	solve;

  Fix a fault arising in a complicated use of defined variables.

20080207
  Fix a bug that crept in sometime in printing certain expressions,
such as iterated piecewise-linear terms.  The bug gave rise to
error message "unexpected type 0x1e600 in prex()".  Example:

    var x{i in 1..3} := i;
    display {i in 1..3} <<{j in 1..i} .5*j; {j in 0..i} (-j)^j>> x[i];

20080216
  Fix a bug (fault or worse) connected with a subscripted defined
variable whose indexing set changes size sufficiently to elicit the
bug.  This also corrects a related (so far not seen) bug with "expand"
and ".astatus" of partially dropped constraints.

20080219
  Fix a bug in handling iterated slopes and breakpoints in
piecewise-linear terms.  When it bit, the bug led to a surprising
error message, or worse.

20080306
  In interactive mode with stdin on the current include stack, have
"include 'unavailable'" return to the command prompt (to reading stdin)
when file 'unavailable' does not exist.
  Fix a bug (fault) in printing the error message "bad subscript
(use before def?) for defined var ..." under the "right" conditions.

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

20080312
  Fix bug in expressions involving the dual value of a subscripted
constraint after earlier subscripts of the constraint were dropped,
and in writing initial guesses for such constraints in .nl files.
  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".)

20080314
  Fix another bug in writing dual initial guesses to .nl files
when there are subscripted constraints, some of which have been
partially dropped.  An invalid .nl file could result.

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;".
  Fix a bug in handling defined variables fixed by presolve:
linear variables were sometimes reported as nonlinear.  Example:

	var x; var y = x + 1;
	var z = 2*x + y;
	s.t. c: z = 12;
	var w; minimize zot: w;
	# erroneously reported to have
	# a nonlinear variable and nonlinear constraint

20080629
  Fix a bug in use of variable values in set expressions (which can
only happen in commands):  if previous changes caused indexing of some
variables to change and nothing had since caused the "collect" phase
to run again, wrong values were sometimes used.  In the very
complicated example that led to finding this bug, an inserted
"display" changed some behavior (because it caused the "collect" phase
to run).  With the fix and "option times 1" to show phases, you will
still not see "collect" running before a command that does not need
it, but correct values are now computed.
  Further adjustment to reporting of memory used to avoid negative
values.
  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.

20080703
  Tweaks for stochastic programming extensions (to be described later).

20080717
  Fix a bug introduced in version 20080616 in the handling of nonlinear
defined variables, e.g., those used in both constraints and objectives.
Example:

	set I = 1..2;
	var x{I} := 1;
	var y{i in I} = x[i]^2 + i;
	minimize zot: sum{i in I} (y[i] - 4)^2;
	s.t. foo: sum{i in I} y[i] <= 7;

20080804
  Fix a bug introduced in version 20060905 in which "update data",
like "reset data", discarded current values.  Now current values are
gain retained by "update data".  Example:

	set I = 1..2; var x{I}; param p{I};
	minimize zot: sum{i in I} (x[i] - p[i])^2;
	data; param p := 1 1  2 2;
	solve;  update data;
	data;  param p := 2 5;
	print sum{i in I} (x[i] + p[i]); # printed 6 rather than 9

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.

20080821
  Fix a glitch that caused mention of unused imported functions in .nl
files when expression simplification (such as multiplication by zero)
caused removal of all references to the functions.  Example:

	function ginv;  function hypot;
	set I = 1..2; var x{I};
	var y{I} >= 0;
	s.t. bletch: sum{i in I} y[i] <= 0;
	minimize foo: hypot({i in I} (x[i] - i)) + y[1]*ginv(y[2]);
	# ginv was listed as required in the .nl file,
	# even though presolve deduces y[1] == 0 and no actual
	# reference to ginv appears in  the .nl  file.

  Fix a glitch with "delete option ...".  Example:

	option zork 'some value', zork;
	delete option zork;
	option z*;	# said option zork ''; # not defined
	# after the bug fix, "option z*;" does not mention zork at all.

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

20080925
  Fix two obscure bugs that should be evident if encountered.
(One only appeared on some PowerPC systems; the other was elicited
in testing a forthcoming extension, not yet announced.)

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
  Fix a bug in handling two-sided constraints involving defined
variables.  If the constraint implied lower and upper bounds on a
defined variable and something else implied a stronger lower bound
on the variable, the constraint was mistakenly dropped during presolve,
even though the side that implied the upper bound should have been
retained.
  Add "q" as synonym for "quit".

20081120
  Fix a bug with recording drop/restore state when a problem
is declared, the drop-restore state then changed, and a second problem
is declared.  The modified drop-restore state was not saved with the
first problem.  Example:

	set S; var x{S} >= 0;
	problem P1: x;
	fix x[2];
	problem P2: x; 	# the fixing of x[2] in P1 was lost

A work-around is to declare problems before explicitly modifying
the drop-restore state.

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
  Fix a bug with _obj[...]: wrong values were reported.
  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).

20081213
  Fix a bug in checking for bad subscripts that led, under complicated
conditions, to the message "sub_check bug!".  Example:

	param N integer; set A := 1 .. N; param p{A} >= 0;
	data;	param N := 4;
		param p := 1 2.5 2 3.4 3 4.7 4 8.9;
	display N, p;
	let p[3] := p[1] + p[2];
	# with p[3] changed to p[2] on the line above
	# failed to report bad subscripts below
	let N := 2; display N, A;
	let p[1] := p[1] + p[2];	# sub_check bug!
	display p;

20090101
  Fix a bug (fault) in the error message for an invalid subscript
in a "while" or "until" clause in a "repeat" command.  Example:

	param p{i in 1..2} = i;
	param q default 1; param c default 0;
	repeat until p[q] > 3 { let q := q + 1 } # faulted

  In error messages, report _cmdno to full precision even when it
exceeds 1e6.

20090130
  Fix bug (fault) in handling empty sequence of commands enclosed in
braces in a file read by "commands" command within a loop.

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