[CONTACT]

[ABOUT]

[POLICY]

[ADVERTISE]

Complete AMPL fix and change

Found at: ftp.icm.edu.pl:70/packages/netlib/ampl/fixlog

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

		
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.

		
20090316
  Fix a couple of bugs with "break" commands in a file read by a
"commands" command and pertaining to a loop in which the
"commands" command appears.
  Fix a glitch with "write" commands involving a string expression
in parentheses:  the entities in the expression were not brought up
to date.  Example:

		
	param q symbolic = 'abc';
	var x; minimize zot: x^2;
	write ('g' & q);	# complained about q having no value

		
  Fix a bug in processing "param-data-alternate" tables (see p. 476
of the AMPL book) tables with a subscripted set-name.  An erroneous
error message about the subscript was given.

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

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

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

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

		
20090323
  Fix a glitch that gave rise to error message "unexpected nonvariable
type ... in eput".  Example:

		
	var x >= 0 <= 0; var y;
	minimize zot: sqrt(x*(x-y)+y);
	solve; # unexpected nonvariable type 8194 = 0x2002 in eput

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

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

		
and a defined-variable variant

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

		
20090327
  Print a warning and ignore "reset data" and "update data" commands
applied to builtin params and sets.  This fixes a fault with, e.g.,

		
	reset data _solve_time; solve; #faulted

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

		
  Fix a bug (fault) with min({i in S} expr(i)) and max({i in S} expr(i))
in contexts where the expression could be discarded after use, as in the
following example:

		
	set S; param p{S};
	data; param :S: p := a 1 b 2.5 c 2.4;
	display max({s in S} p[s]);

		
Workaround for the above example:

		
	display max{s in S} p[s];

		
  Fix a bug with certain references (e.g., to .sno in the example below)
whose values were needed before something else forced full instantiation
of the problem.  Example:

		
	var x; minimize zot{i in 1..2}: i*x^2; display zot.sno; # faulted

		
20090611
  Fix bugs (likely causing faults) with partially dropped
complementarity constraints appearing in problem declarations and
expand commands.

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

		
20090811
  Fix a fault with a complicated expression mistakenly using
& (the string concatenation operator) rather than && (logical and).
  Add a warning about comparisons with strings and one of the operators
<, <=, >=, > (to catch some instances of use of & rather than &&).

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

		
20091014
  In the MS Windows AMPL binaries, fix a glitch with "solve" and
"shell" commands in handling explicit paths containing blanks, and fix
a possible bug in determining the environment passed to solvers and
shell processes.

		
20091101
  Fix a glitch that (on some systems) caused this example:

		
	var x >= -900 <= -800 := -860;
	var y = x*exp(x); minimize zot: (x + 870)^2 + y;
	solve;

		
to give error message

		
	Error differentiating =y: can't compute exp(-870).

		
20091112
  Fix an erroneous bad-subscript message that arose under complicated
conditions.
  In single-step mode, try to tolerate some syntax errors more
gracefully when reading stdin (assumed to be a human typing).
  Exclude defined variables (and their defining constraints) from
the count of constraints used in deciding whether a problem is
small enough for the student version.

		
20091120
  Fix bugs with "solexpand _con[n];" when _con[n] is a defining
constraint for a "var ...  = ..."  declaration (of a defined
variable).  Linear terms were omitted and the constant term had the
wrong sign.  A fault was also possible when presolve had not
removed any ordinary constraints.  Example:

		
	var x; var y = 3*x + x^2;
	minimize zot: exp(y);
	solexpand _con[1];

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

		
20091123
  Fix a bug with suffixes on constraints with indexing {if ...}.
The example that led to finding the bug produced an invalid .nl file
on which the solver issued a "bad line ..." error message.

		
20100122
  Fix glitch with printf's handling of negative numbers with %a or %A.
The sign was ignored that the exponent was wrong.

		
20100226
  Fix a bug in the expand command's printing of complementarity
constraints (which erroneously included an Infinity).

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

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

		
20100330
  Fix a bug (fault) with "reset data;" when (e.g.) two params indexed
by the same set were affected.  Example:

		
	set S; param n_min{S}; param n_max{S};
	table foo "nutrients.tab" IN: S <- [NUTR], n_min, n_max;
	read table foo;
	display n_min, n_max;
	reset data;	# faulted

		
20100402
  Fix a bug (possible fault or worse) in handling nonconvex
piecewise-linear terms.  Values for introduced variables that were
then eliminated by substitution were mistakenly stored after
"solve" with a possibly out-of-bounds subscript.  (Whether this
caused trouble was problem-dependent.)  Work-around:
"option pl_linearize 5;".
  Fix a bug with applying piecewise-linear operators to defined
variables.  Incorrect problem transforms sometimes resulted.

		
20100429
  Fix a bug (fault) in handling valid input followed (e.g.) by an
empty line and "*/" without a newline at the end of file.

		
20100705
  Fix trouble that could arise in 32-bit binaries after they execute
more than 2^31 commands.

		
20100708
  Fix a bug introduced 20100228 in the "commands" command:  when
used inside a loop, a fault (or worse) was possible.

		
20100715
  Fix a glitch in the regular expression functions (sub and gsub):
^ only matched the beginning of the string and not the beginnings of
internal lines (i.e., the text following a \n character).  Now it
also matches the character following each \n (just as $ matches the
end of each internal line as well as the end of the string).

		
Example: before the bug fix,
    num0(sub(solve_message, '(.|\n)*\n([0-9]+) MIP(.|\n)*', '\2'))
was the only way to extract the number of MIP simplex iterations
from the solve_message returned by cplex.  The bug fix lets us replace
the first \n with ^:
    num0(sub(solve_message, '(.|\n)*^([0-9]+) MIP(.|\n)*', '\2'))

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

		
20100915
  Fix a bug (fault) with variables declared to be in a union of more
than two intervals.
  Fix bugs (e.g, possible fault) in cleaning up after a solve with
piecewise-linear terms or variables in unions of intervals, and with
models that had both piecewise-linear terms and variables in unions
of intervals.

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

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

		
used to print "0.31376060558952107" thrice.  Now the third "print"
gives a different value (0.8653543517772044).  Best practice (least
confusing) is to adjust option randseed before declaring problems or
new environments, in which case the this change to environment
processing makes no difference.
  Fix a bug with _ampl_time and related quantities, such as
_ampl_elapsed_time:  they were only computed once and appeared to
be constant thereafter.
  Fix a bug that could cause assignments to variable.relax not
to take effect until completion of the outermost containing loop.
(Insertion of "display somevariable.astatus;" after such assignments
was a work-around; the choice of variable did not matter.)
  New builtin suffix "int" on variables is 0 for a continuous variable
and 1 for an integer or binary variable (unless $relax_integrality is
nonzero or the variable's .relax suffix is positive, in which case .int
is 0 and solvers will see the variable as continuous).

		
20101103
  Work around getenv() trouble seen on a version of Linux.
The bug would cause a solver not to be found after a change to
option PATH.

		
20101105
  Fix a bug in converting decimal strings of more than 40 significant
digits when the first appears after the decimal point.  Example:

		
	print .010000000000000000057612911342378542997169;

		
gave 4.008336720017946e-292 rather than 0.01.

		
20101125:
  Fix a bug (fault) with unsubscripted symbolic variables (a forthcoming
feature, not yet described).

		
20101203:
  Fix a bug (fault, rarely seen) affecting 64-bit binaries.

		
20101206
  Fix a bug (fault) possible with some uses of random variables (a
forthcoming feature).

		
20110112
  Fix a rarely seen bug (fault) that bit under the "right" conditions
when making adjustments for new suffixes.

		
20110121
  Fix a rarely seen parse error on a command after an in-line data
section.
  Add warning that variables in subscripts are not yet allowed.

		
201102109
  Fix a rarely seen bug that caused a fault in a complicated example.
  Fix a bug in "table write":  symbolic params with numeric values were
sometimes treated as having the corresponding string value.
  Add an error message for table declarations that involve row-index
dummy variables in OUT or INOUT columns and do not specify "set -->"
or "set <-->", as in the following example.

		
	set S; set T = 1..4; param p{S,T};
	table goo:
	  S <-- [r ~ R], {t in T} < p[r,t] ~ ("col" & t) >;

		
Previously "write table goo" faulted (but worked fine with "S <--"
changed to "S <-->" or "S -->").

		
20110222
  Fix a bug with solexpand applied to a defining constraint:
a spurious "complements" sometimes appeared and a constant term
was possibly lost.

		
20110306
  Fix glitches with iterated columns in table declarations, i.e., with
	indexing < colg_1 [, colg_2, ...] >
The indexing set was treated as the empty set in some situations,
which might have caused "read table" not to read the columns in
question or have caused "write table" to fault.
  Fix a glitch in the processing of "include filename" where filename
is not quoted.  If a nonblank character immediately followed filename,
as in "include foo;" (in which semicolon is the nonblank character),
that character was sometimes seen at the wrong time.  For example,
"if 1 < 0 then include f;" was treated as "if 1 < 0 then; include f".
(Recall that an include phrase, such here as "include f", is processed
before parsing; that is, "include" is unaware of the context in which
it appears.)

		
20110321
  Fix "sd botch in ordered_genall" in the following example:
	set S ordered by 1..10 default 1..10; display S;

		
20110413
  Fix a fault that could arise in a complicated example with fixing
and unfixing a defined variable within a bigger loop.  Such fixing
and unfixing is not allowed, but in the example, the bug bit before
an error message about the inappropriate operation was issued.

		
20110419
  Fix a fault in the "objective" command that was possible with some
forms of iterated objectives.  Example:

		
	set A dimen 2; var x;
	minimize Obj{(i,'N') in A}: x^i;
	data; set A := 1 x  2 N;
	objective;	# faulted

		
20110524
  Fix a bug (fault or worse) with some models having both defined
variables and logical constraints.
  Fix a bug in simplifying logical constraints with constant logical
expressions; the wrong truth value sometimes appeared in a platform-
dependent way.

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

		
20110614
  Fix a glitch in computing Jacobian sparsity in some problems in
which a nonlinear defined variable appears linearly in a nonlinear
constraint and "option substout 1" is specified.  Example:

		
	set I = 1..2; var x{I}; var y{I};
	s.t. c1: y[1] = x[1] + 1;
	s.t. ydef: y[2] = y[1] + x[2] - x[1];
	minimize zot: y[2]^2;
	s.t. bletch{i in I}: x[i]*y[i] >= 3;

		
With $substout = 1, bletch[2] was incorrectly indicated to depend
on x[1].  Aside from sparsity issues, this was harmless.

		
20110630
  Omit "Highest address used = ..." from "Too much memory" message;
the "highest address" seems pointless when virtual memory is used.
  Fix two bugs in handling complementarity constraints.  In a
command-line invocation of the form
	ampl -obfoo foo.mod foo.dat
complementarities might sometimes have been misidentified, and
"complementarities" of the form v complements expr1 == expr2 (which
should just be simplified to expr1 == expr2) may have been conveyed as
complementarities (which seemed not to bother the "path" solver).

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

		
	c:  L <= expr1 <= U complements expr2

		
with L and U finite to

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

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

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

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

		
20110722
  Fix some bugs with logical constraints.  Problem commands did not
cause logical constraints to be dropped or restored when they should
have been.  The "delete suffix ..."  command ignored logical
constraints.  The "drop;" command did not show dropped logical
constraints.  The "delete lcon;" command, for lcon a logical
constraint, misbehaved.  For a logical constraint lcon, "expand lcon;"
and "solexpand lcon;" sometimes printed an extraneous Infinity.

		
20110725
  Fix a bug with redeclarations involving variables.  Input of the
form
	# ...
	write bfoo1;
	var newvar;
	redeclare minimize o: ... /* involving newvar */;
	write bfoo2;
could have resulted in an incorrect foo2.nl.

		
20110813
  Fix glitches in "show f;" when f is a pipe function.
  Fix a fault with empty slices that arose under rare conditions.
  In equality constraints in which one side involves numeric variables,
assume the other side must also be numeric.  This matters when the
other side involves an if-then-else expressions whose "then" or "else"
expression consists only of a dummy variable, such as

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

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

		
20110825
  Fix a parsing bug: an include phrase following an "if" command that
could be followed by an "else" command (which might be in the included
file), but is followed by something else was mishandled.

		
20110901
  Fix a parsing bug ("syntax error") seen in the following example:

		
	param p; var x{1..2};
	minimize zot: sum{i in 1..2} (1-x[i])^2;
	data goo.dat;
	if p > 3 then commands goo1.mod;
	expand;

		
Changing "expand;" to "expand ;" or ";expand;" worked around the bug.

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

		
20110908
  Fix a bug with complementarity constraints.  With certain (somewhat
rare) problem dimensions, an incorrect .nl file was generated.  An
example where this bug bit:

		
	var x {1..2} >= 0; minimize obj: x[1] + x[2];
	subj to con: x[1] <= 3 complements x[2] <= 5;

		
20110909
  Fix a memory leak seen in a script involving a number of solves of
large problems.
  Arrange for printing variables not to require instantiating
constraints.  With some command sequences, "ampl -t ..." or
"ampl -T ..." or the equivalent "option times 1;" or
"option gentimes 1;" will produce less output than before.

		
20110913
  Fix a rarely seen bug that caused a fault in recent 32-bit Windows
binaries.

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

		
20111015
  Fix a bug sometimes seen with "show" after a redeclaration:  wrong
variable names were sometimes reported (depending on details of the
redeclaration).  Example:

		
	var x; var y;
	minimize zap: x + y;
	s.t. C: 2*y <= 5;
	expand C;	# OK
	param p default 2;
	redeclare s.t. C: p*y <= 5;
	expand C;	# mentioned x rather than y

		
20111016
  Fix more variable-reordering trouble with redeclare (not caught
by yesterday's example).  Example:

		
	var w; var x; var y; var z;
	minimize foo: w + 2*x + 3*y + 4*z;
	s.t. c1: x + 5*y <= 37;
	s.t. c2: y + 6*z >= 43;
	s.t. c3: 4 <= z + 7*x <= 19;
	expand;
	redeclare var y = x^2 + z; # "xrenumber bug" with version 20111015
	expand;	# wrong constraint c3 prior to 20111015

		
20111107
  Supply missing initialization of SnprintF and VsnprintF in the
AmplExports structure passed to imported functions and table handlers.
(They have long been provided to imported functions used by solvers.)
  When imported functions or table handlers see ae->ASLdate >= 20111028
and ae->asl == 0, ae->Getenv(0) returns a char** value for the complete
current environment.
  On Unix-like systems, set FD_CLOEXEC when opening files, to prevent
child processes (e.g., from "solve" or "shell" commands) from seeing
irrelevant open file descriptors, a bit of tidiness seldom relevant in
practice.
  Fix the obscure glitch that prompts were preceded by # after reading
a file that ended in an incomplete #comment line (one without a
terminating newline character).  The # persisted until the next
complete comment had been read.  Now the # should only appear if
you manually enter an incomplete comment (e.g., under Unix or Linux,
by typing control-D at the end of a # comment line).
  Fix a bug (e.g., fault) that bit under complicated conditions, e.g.,
with solving sequences of named problems.

		
20111110
  Fix bugs (giving a surprising error message or fault) with updating
sets over which subscripted objectives and problems are indexed.

		
20111121
  Fix a bug with testing membership in "system sets", i.e., any of
_CONS, _ENVS, _FUNCS, _LOGCONS, _OBJS, _PARS, _PROBS, _RANDVARS,
_SETS, _SUFFIXES, _SYMVARS, _SYSTEM_SUFFIXES, _TABLES, _VARS or
_VARSETS.  The test sometimes came out wrong.  Example:

		
	reset; print if 'XX' in _SETS then 'yes' else 'no';
	# printed yes rather than no

		
  Add a warning about "data;" not being allowed in a compound command.
Other error messages are likely to appear after the new warning.
Note that "data filename;" and "data (filename_expr);" may appear in
a compound statement.

		
20111216
  For the -ix command-line option, in addition to allowing multiple
files on separate lines of a suitably quoted x, allow multiple files
on the same line if each file name is enclosed in single or double
quotes.  Add a brief explanation of multiple files to the "-i?"
output.
  Fix a bug (introduced 20110531) with "option substout 1":  an
incorrect .nl file was sometimes generated when several constraints
could be chosen to define a particular variable.  Here is an example
in which the bug bit, giving a .nl file incorrectly containing
"nonlinear" constraints:

		
	option substout 1;
	var x >= 3;
	var y{i in 1..2} >= i;
	var z;
	var v = z + 3;
	var w = v + x;
	s.t. c{i in 1..2}: z = x + i*y[i];
	minimize foo: x + z;

		
20120104
  Fix a bug that could lead to an error message of the form
"presolve has k = 11, P.nfc = 17".

		
20120117
  Fix a glitch that caused the unload command not to fully
unload the specified library.  It's not clear whether this
ever caused any visible symptoms other perhaps than some
memory not being reclaimed.
  New builtin suffix ".sense_num" on objectives is -1 for
minimization and 1 for maximization.  New builtin suffix
".sense" is a symbolic version of ".sense_num" with default
values "minimize" and "maximize" given by option sense_table.

		
20120126
  Fix glitches with _obj.sense.
  Adjust "load" command to facilitate using a 32-bit AMPL binary
  Adjust "load" command to facilitate using a 32-bit AMPL binary
with a 64-bit solver binary or vice versa:  for a 64-bit AMPL,
if the library name involves '.' and the final '.' is
preceded by "_32", change the "32" to "64".  Otherwise, if the
library fails to load and there is a '.' in the name, insert
"_64" before the final '.' unless it is already preceded by
"_64".  (For a 32-bit AMPL, the rules are similar, with the roles
of "32" and "64" reversed.)  The builtin set _LIBS still shows
the names by which libraries were loaded, whereas option AMPLFUNC
reflects the adjusted names.  The unload command operates on
names in _LIBS.  Temporarily, at least, you can suppress the new
behavior by specifying "option map_32_64 0;".
  Under MS Windows, add a test to the "load" command to ignore
shared libraries (DLLs) compiled for the wrong number of address
bits.  (With more sensible operating systems, such libraries
simply fail to load.)
  Fix a bug with option AMPLFUNC:  after a sequence of the form

		
	load 'something';
	load 'more';
	unload 'something'; # or 'more'
	load 'another';

		
option AMPLFUNC did not show the new library.
  Change the default value for $ampl_libpath from "" to the
directory containing the AMPL binary and (if different) the
current directory.  Absent command-line option -i (invoke
ampl "-i?" for details), or an incoming $AMPLFUNC value, look
for both amplfunc.dll and ampltabl.dll at startup by the AMPL
search rules (rather, for ampltabl.dll, than by system-dependent
rules).

		
20120131
  Fix a possible fault during startup that could happen with version
20120126 on Unix-like systems.
  Fix a bug in simplifying a piecewise-linear term applied to a
variable with a negative upper bound greater than the first negative
breakpoint when the term has only two negative breakpoints and at
least one positive one (after simplification for common slopes).
Wrong information was transmitted to the solver.

		
20120208
  Fix an obscure and rarely seen bug that arose under complicated
conditions with repeated solves involving several entities having
the same indexing when the size of the common index set changed.
The example that revealed the bug faulted.

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

		
20120217
  Fix the bug that after, e.g., "display _VARS;", _VARS was not
updated after subsequent variable declarations or deletions.

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

		
20120317
  Fix a bug (possible fault) in handling very long error messages.
  Fix a similar bug with long error messages in the ODBC table handler.
  Map NaNs in sets to a specific quiet NaN and fix a bug in testing
whether NaN is a set member.  Here is an example that now works and
previously misbehaved:
    set S; param p{S}; data; param :S: p := NaN 37; print p[NaN];

		
20120328
  Fix a bug (possible fault) with variables and constraints indexed
over a subscripted set.  The fault was only possible if such a
variable or constraint had to be regenerated.

		
20120406
  Remove ampl_libpath from the default _LOCAL_OPTIONS (thus making
$ampl_libpath available for possible use by the proxy table handle).
  Fix a glitch introduced 20120214 (on Unix-like systems) with a
"shell;" command:  the AMPL process could die from a SIGTTIN signal.

		
20120505
  Fix a presolve bug with logical constraints (e.g., indicator
constraints) that bit under complicated conditions.
  Fix a bug in the expand command's processing of a logical constraint
that could cause it incorrectly to indicate whether presolve had
removed the constraint.

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

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

		
20120516
  Fix a bug with "redeclare" that gave error message "xrenumber bug"
when the redeclared entity depended on something declared after
something that depended on the entity.  Example:

		
	param p default 6; param q = p + 1;
	param r = 2*q; display p, q, r;
	param s default 3;
	redeclare param q = p + s + 1; # "xrenumber bug"
	display q;

		
20120517
  Fix a bug (fault) with some logical "atmost" expressions.

		
20120522
  Fix a bug (giving "corrupted del_mblk arg") in "reset data p;"
when p is a scalar param whose current value was computed from
a default expression.  The bug was exposed (previously harmless)
was exposed by the changes of 20120214.  Example:

		
	param p default 3;
	reset data p;	# OK
	print p;	# value computed from default expression
	reset data p;	# "bug: corrupted del_mblk arg"

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

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

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

		
20120604
  Fix two bugs in handling a problem with logical constraints that
get converted to algebraic constraints:  an incorrect .nl file was
produced, and _logconname was miscomputed.

		
20120614
  Fix a bug with piecewise-linear terms.  When constraints added to
linearize such terms increased the total number of constraints
beyond the next power of two, a fault was sometimes possible.

		
20120619
  Fix a glitch that gave rise to "bug: corrupted del_mblk arg"
after a very large number of commands.

		
20120629
  Fix another bug that could only bite after a very large number of
commands.  Note that using iterated commands, such as iterated "let",
"printf", "drop", etc.  commands, rather than "for" loops, where
appropriate can greatly reduce the number of commands executed and
give much faster executions.  Using slices suitably sometimes also
greatly speeds up execution.

		
20120804
  Fix a glitch that gave error message "opnumber 243 in opgen"
under complicated conditions.

		
20120831
  Fix a glitch that gave rise to error message "sysset_en_IN called"
in the following command:

		
	print if 'foo' in _AVAILFUNCS then 'yes' else 'no';

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

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

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

		
20120911
  Fix a bug in simplifying "and", "or", and comparison expressions
when the result is constant (true or false).  The example revealing
the bug was of the form
	s.t. foo: x == 1 ==> 0 == 0;
(with one of the zeros being an empty sum).

		
20121005
  Use execve (on Unix-like systems) rather than execv when an invoked
program appears to require interpretation by /bin/sh because the initial
attempt to execute the program directly with execve failed.  The idea is
to supply the same environment in both cases.  This change should mostly
be invisible.

		
20121012
  Fix a fault in simplifying logical expressions under complicated
conditions.  Example:

		
	var x{1..4} >= 1;
	s.t. fa: forall {i in 1..4} x[i] == 1 or x[4]^2 >= 1;
	s.t. b1: x[2] + x[3] <= 2;
	write 0; # fault

		
20121017
  Fix a bug with a "solve" involving no logical constraints after a
solve with one or more logical constraints.  The bug could cause a
fault or other surprising behavior.

		
20121021
  Fix a bug (sometimes leading to a surprising "solve_out:..." error
message and/or an invalid .nl file) with problems containing both
logical constraints and "var ... in ..."  declarations, such as

		
	var x{S} in {0, 4, 6};

		
20121024
  Fix a bug with "var ... in ... union integer [...,...];", as in

		
	var x in {2.5} union integer [3,5];
	minimize zot: (x - 4.3)^2;

		
The integer interval was treated as a continuous interval.  Now,
when appropriate, "var ... in integer [...,...] ..." will treat
the variable as an integer variable.

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

		
20121120
  Fix bugs (faults) with min() and max(), which now return Infinity
and -Infinity, respectively.

		
20121210
  Fix a possible minor glitch (irrelevant "_32" or "_64") in an
error message about the failure of a "load" command.
  Fix potential trouble (not yet actually seen) with generic
synonyms in 64-bit binaries.

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

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

		
20130201
  Fix a bug (e.g., fault) with read commands having nested indexings
in which an inner indexing involves an outer dummy variable.

		
20130207
  Fix a bug with $ampl_libpath after a command sequence of the form

		
	# nontrivial declarations and/or commands
	reset;
	reset options;
	# option ampl_libpath might now have been bogus

		
20130218
  Fix a bug in deducing reduced costs involving nonlinear if-then-else
expressions whose "if" test has a "count" expression.  Such expressions
are unlikely in practice, but here is an example:

		
	var x := 3;
	minimize f: if count(sin(x) > .1, cos(x)>.1, tan(x) < -.1) >= 2
			then x^2 else x^3;
	display x, f, x.rc;	# x.rc was wrong
	let x := 3.1;
	display x, f, x.rc;	# x.rc was accidentally right

		
  Fix a bug with default expressions for scalar params:  if evaluation
of the default expression failed, e.g., due to a missing value, the
param subsequently appeared to have an unpredictable value.  This was
only an issue in an interactive session, such as

		
	ampl: param a;
	ampl: param b default a + 1;
	ampl: print b;
	Error executing "print" command:
	errror during evaluation of b:
		no value for a
	ampl: print b;
	0	# a potentially random value

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

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

		
20130221
  Fix a bug, leading to "unexpected type ... in lsimplify()", with <==>
in logical constraints.  Example:

		
	var x{1..2};
	s.t. c: x[1] == 1 <==> x[2] == 2;

		
  Fix bugs with logical expressions involving "not" (i.e., "!") and
inequalities involving NaNs.  For example,

		
	param p; data; param p := NaN;
	print if !(p > 3) then "yes" else "no";
	# incorrectly printed "no"

		
  Similarly, in the (silly) model

		
	var x; s.t. c: 1 < 2 ==> !(x > 4);

		
render c as the logical constraint !(x > 4) rather than the arithmetic
constraint x <= 4.

		
20130222
  Fix a bug with multiple t-headers in data sections, leading to error
message "irregular : ... : header".  Here is an example, previously
rejected, of multiple t-headers for set and param data:

		
	set ORIG; set DEST; set PROD;
	set ROUTES within {ORIG,DEST,PROD};
	param cost{ROUTES};

		
	data;
	set ROUTES
	        :  FRA   FRA   DET   DET   LAN   LAN   WIN
	        : bands coils bands coils bands coils bands :=
	GARY        -     -     -     -     -     +     -
	CLEV        +     +     +     +     +     +     -
	PITT        +     -     -     -     -     -     +

		
	        :  WIN   STL   STL   FRE   FRE   LAF   LAF
	        : coils bands coils bands coils bands coils :=
	GARY        -     -     +     -     -     -     +
	CLEV        +     +     +     -     -     +     -
	PITT        -     +     -     +     +     -     - ;

		
	param cost:  FRA   DET   LAN   WIN   STL   FRE   LAF
	          : bands bands bands bands bands bands bands :=
	       CLEV   27     9    12     .    26     .    17
	       PITT   24     .     .    13    28    99     .

		
	          :  FRA   DET   LAN   WIN   STL   FRE   LAF
	          : coils coils coils coils coils coils coils :=
	       GARY    .     .    11     .    16     .     8
	       CLEV   23     8    10     9    21     .     .
	       PITT    .     .     .     .     .    81     . ;

		
	set ORIG := GARY CLEV PITT ;
	set DEST := FRA DET LAN WIN STL FRE LAF ;
	set PROD := bands coils ;

		
	display cost;

		
Note that there is a mistake on line 4 of p. 476 of the AMPL book:
the colon before the first "t-header" should be omitted.

		
20130226
  Fix a bug with fixing variables that appear in complementarity
constraints when the fixing should cause the constraints to be
removed by presolve.  Example:

		
	var x{1..7};
	s.t. c{i in 1..6}: x[i] >= 0 complements x[i+1] >= 0;
	fix{i in 1..3} x[i];
	solve;	# gave error message "presolve has k = 6, P.nfc = 7"

		
20130327
  Fix a bug involving imported functions and defined variables,
illustrated by the example:

		
	load amplgsl.dll;
	function gsl_cdf_ugaussian_P;
	param y default 0;
	var theta;
	var z = gsl_cdf_ugaussian_P(theta*y);
	display z;

		
which said "z = 0" rather than "z = 0.5".  The bug was that after 0
was substituted for theta*y (since y has its default value 0),
gsl_cdf_ugaussian_P(0) was ignored.

		
20130408
  Fix a bug with "option linelim 0;" that affected some complicated
examples involving linear and nonlinear defined variables.  The linear
variables were sometimes evaluated after nonlinear variables that used
them, leading to wrong values for the nonlinear defined variables.
Note that "option linelim 0" can lead to substantially faster
processing of some problems, but makes linear defined variables
appears as nonlinear.  For some nonlinear solvers, this makes no
difference, but it cannot be used with purely linear solvers.
  Somewhat improve performance in handling many linear defined
variables with the default "option linelim 1".  In one example, time
to invoke the solver was reduced by 16%.
  The "temporary" debugging interpretation of the "4" bit of $linelim,
describe in the change-log entry of 20011206, is rescinded.  (Version
20130407 had a glitch in this change.)

		
20130409
  Fix a bug giving "unexpected type 0x960c in augment_incidence()"
with nonlinear defined variables involving an if-then-else expression
whose "if" test is constant.

		
20130417
  Fix a bug "solve" involving complementarity constraints, followed
by "fix" command(s) that remove all complementarity constraints,
followed by a "solve":  an incorrect .nl file was written for the
second "solve".
  Fix an optimization bug with tests of the forms

		
	expr != numeric_expression
	expr == numeric_expression
	numeric_expression != expr
	numeric_expression == expr

		
If expr was not numeric, the numeric_expression was not evaluated, so an
error in it was not detected.  Example:

		
	set S = {'abc'}; print{i in S, j in S: i != j+1}: i,j;

		
printed "abc abc" rather than complaining that j+1 cannot be evaluated.
  Fix an obscure bug with complementarity constraints that led to an
error message of the form "presolve has k = nnn, P.nfc = mmm".

		
20130422
  Fix a bug (possible fault) with logical constraints when presolve
eliminates all of them.

		
20130427
  Fix a bug with logical constraints:  on problems having both logical and
algebraic constraints, when presolve eliminated all logical constraints
but not all algebraic constraints, a fault was possible.  Now, on other
problems, "Solution determined by presolve" is more often possible.
  Fix a bug with "display _logcon;" on problems having both logical and
arithmetic constraints:  wrong values were displayed.  The bug did not
affect, e.g., "display {i in 1 .. _nlogcons} _logcon[i];".

		
20130501
  Fix some bugs (infinite loop, fault, or surprising error message
"nonvariable type ... in eput") in simplifying some complicated
logical expressions.

		
20130502
  Fix a bug with loop invariants having internal dummy variables.
In the following example, the inner sum was moved to the wrong
place, giving a fault:

		
  set I; set J; set S within {I,J} default {};;
  param p{i in I} = sum{z in {0}: sum{j in J: (i,j) in S} 1 > 0} 1;
  let I := 1..10; let J := I;
  display p;

		
In this example, "sum{j in J: (i,j) in S} 1" is a bizarre way of
writing what more clearly and efficiently would be written
"card{(i,j) in S}"; making this change bypassed the bug, as did
changing the inner sum to the clumsier "sum{(i,j) in S} 1".

		
20130506
  Fix a glitch with error recovery:  after an error message about
"no value for ...", supplying the data and then trying to solve
sometimes led to an invalid .nl file.  Example (typed on stdin):

		
	set I = 1..2; var x{I} >= 0; param p{I};
	s.t. c: sum{i in I} x[i] + sum{i in I} 2*x[i] <= 3;
	minimize zot: sum{i in I} p[i];
	solve; # error processing objective zot: no value for p[1]
	data; param p := 1 -1 2 -2; solve; # bad line 22 of ....nl

		
  Fix a glitch giving an "unexpected nonvariable type..." error
message when option presolve 0 is unwisely used with certain
logical constraints involving "exists" or "forall".

		
20130510
  Fix a glitch with _ncons, which incorrectly gave the number of
algebraic constraints plus the number of logical constraints
rather than just the number of algebraic constraints, i.e.,
_ncons was high by _nlogcons.

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

		
20130530
  Add an error message that symbolic variables are not yet available.
  Fix a fault with deleting check commands.  Example:
	param p; check p > 3; delete check 1; # faulted

		
20130608
  Fix a glitch (fault after 2 "reset;" invocations after the relevant
"load" command) with imported libraries that make no addfunc(...) calls.

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

		
20130624
  Fix more trouble with "load" that may only matter for MS Windows.

		
20130625
  Fix trouble introduced 20130624 with the incoming $AMPLFUNC.

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

		
20130731
  Fix a bug with inserting "_64" or substituting "_64" for "_32" in
file names given to "load" commands with the 64-bit MS Windows binary
and vice versa with the 32-bit MS Windows binary.

		
20130809
  Fix a parsing glitch with entities named "end".  In some contexts,
such as "redeclare", "read table", "reset", "show", "suffix",
"update", and "write table", "end" was treated as an "end" command.
  Fix a bug (fault) that was possible under some conditions with
a set of variables indexed over the empty set.
  Fix a bug (wrong values; possible fault) in writing suffix values
to .nl files for complementarity constraints involving expressions
of more than one variable on both sides of "complements".  The .nl
file has two constraints for each such complementarity constraint,
and both get the same suffix value.

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

		
20130816
  Fix a bug (fault) with several entities (e.g., constraints) using,
using iterated quantities, such as sums, over the same subscripted
set with a constant subscript.

		
20130903
  Fix a fault that was possible with some problem instances involving
piecewise-linear terms.

		
20130906
  Fix a bug that kept suffixes on logical constraints from being
transmitted to the .nl file.

		
20130921
  Fix a possible fault (or worse) with instances having
piecewise-linear terms whose linearization caused the number of
variables to grow beyond the next power of 2.
  Fix a bug unlikely to bother many people:  a fault with duplicate
false constraints:
	c: 0; d: 0; display c; # faulted

		
20130926
  Fix a bug (eventual fault or worse) with an increase (above the next
higher power of 2) in cardinality of the indexing set of a defined
variable, some of whose values had been used in printing or other
commands.

		
20131002
  Fix a glitch with "ampl -b4 ..." in the error message for an
unavailable solver:  part of the error message did not appear.

		
20131010
  Fix a bug with two or more entities indexed over a subscripted
set with constant subscripts in the entity declarations.  The
first-used subscript might have been used instead of the correct
subscript in subsequent instantiations of the affected entities.
  Have "write ...", including "write 0;", set solve_result_num = 299
if presolve finds the problem infeasible.
  Fix a rarely seen bug introduced with the changes of 20130408
for option linelim 0.  A faulty .nl file was sometimes produced,
with defined variables incorrectly ordered.  Defined variables
may sometimes now appear in a different sequence in the .nl file.

		
20131012
  Fix a bug that might have bitten after a "problem" command and
before the next "solve" or "solution" command.  If the "problem"
command changed the constraints to be enforced or variables
allowed to vary, if previous commands had caused presolve to run,
and if nothing else had caused the need to run presolve again,
commands such as printing and "let" commands that involved
entities that depend on presolve might have used wrong values
of some of those quantities.

		
20131018
  Fix a bug with inserting "_32" or "_64" (as appropriate) before
the final "."  in filenames seen by load commands when the portion
of the name before the "." was only one or two characters long
(such as "cp.dll").  Alternatively, if a given library name has
"_32" or "_64" before the final "." and fails to load (perhaps
after changing "32" to "64" or vice versa, as appropriate), try
omitting the "_32" or "_64".
  When a solution is read by "solve" or "solution" and no dual
variables are present but could have been, and when presolve
has removed some constraints, delay the computation of dual
variables for the removed constraints until something, such
as a request to print dual values, requires them to be computed
from the then current primal and dual variable values (possibly left
over from a previous "solve" or still at their initial values).

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

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

		
20131122
  Fix a bug with "redeclare" that with some commands caused a
delay in computing the redeclared value.  Example:

		
	var x := 1; var y := 2; var z = y^2 + 1;
	display x, y, z;
	redeclare var z = 3*x + 4*y^2;
	display x, y, z;	# z was wrong
	display z;		# z was now right

		
20131203
  Fix a fault that was sometimes possible with named problems.

		
20131212
  Fix an infinite loop that was possible in interactive AMPL sessions
after an error.
  Fix a bug (e.g., fault) that was possible with some instances after
"option presolve 0;" following a "solve;" of a larger problem.

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

		
20140205
  Fix bugs in simplifying logical constraints.  The bugs could give an
error message about "unexpected nonvariable type" or could result in a
.nl file that could cause some solvers to complain about an invalid
indicator constraint.

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

		
20140224
  Fix a bug with defined variables in tables:  wrong values may have
been transmitted by "write table".  Explicitly subscripted defined
variables and those with a ".val" suffix were not affected by the bug.
  Fix a bug (fault) with "solexpand _con;".

		
20140312
  Fix a bug (fault) that crept into version 20140220.
  Fix a bug with "read" commands in compound statements (e.g., loops)
that are executed after a "solve" or "solution" command that
introduces new suffixes.
  New option cmdtrace: "option cmdtrace 1;" turns on printing of the
name of each command executed and, when the command comes from a file
other than stdin, the filename and line number of the command.

		
20140320
  Fix a bug with problems with general complementarity conditions
(expr1 >= 0 complements expr2 >= 0 where neither expression is
linear in just one variable) and some partially linear nonlinear
defined variables.  The example that revealed the bug resulted in
an invalid .nl file.

		
20140328
  Fix a bug with sets that appear in loops and involve defined
variables, illustrated by the following example.

		
	set K; var x {K}; var y {k in K} = x[k];
	data; set K := 1 2; var x := 1 1 2 0;
	for{i in 1..2}{
		display x, y;
		display {k in K : x[k] == 1};
		display {k in K : y[k] == 1};	#was wrong in 2nd iter
		let x[2] := i;
		}

		
  Fix a bug with problem declarations involving iterated entities.
Changes to things that indirectly affected the sets over which the
entities were iterated did not cause the drop/restore state to be
updated.
  Fix a fault that was possible in interactive sessions with "show x;"
after an error message about the wrong number of indices in the
declaration of x.

		
20140330
  Work around Microsoft bugs that caused Infinity^2 to give 0.

		
20140331
  Fix a bug (causing an error message "Can't evaluate _con[...]")
with "expand _con;" when logical constraints are present.
Use "expand _logcon" to see the logical constraints before presolve.

		
20140409
  Fix a glitch whereby some commands, such as "fix", that should not
require the current problem to be fully instantiated, nonetheless
did so, possibly leading to an error message about "no value" for
sets or parameters involved with variables, constraints, or objectives
not involved with the current command.

		
20140505
  Fix a bug ("corrupted del_mblk arg") with some sequences of solves
of subscripted problems.

		
20140513
  Fix a bug that could corrupt memory after a "solve" when "let"
assigns to a variable that is not in the current problem but was
declared before a variable that is in the current problem.
  Fix a bug with sequences of commands in which the first of two sets
that previously had the same value is assigned another value.  In some
cases a computed value changed when it should not have been affected.
Example:
	set A; set B; set C;
	set D = A union C;
	set E = B union C;
	data; set A := a b c; set B := a b c; set C := x y;
	display D, E;
	update data A; data; set A := p q r;
	display D, E; # E was wrong

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

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

		
20140704
  Fix a fault after the error message "nonconstant left-most expression
in double inequality constraint".

		
20140711
  Fix a glitch on 64-bit MS Windows whereby
	printf "%x\n", 0xabcd1234;
printed "ffffffffabcd1234" rather than "abcd1234".

		
20140827
  Fix a bug revealed by the following example:
	var x := 3; var y;
	s.t. ydef: y = x^2 + 1;
	minimize zot: (y-4)^2;
	print zot;	# faulted

		
20140804
  Fix a bug with "option substout 1;", which did not detect and cope
with circular dependencies.  Example:
	option substout 1;
	var x; var y = x^2 + 1;
	s.t. zap: x = y;
	display y; # printed 0 rather than 1

		
20140908
  Fix a rarely seen fault (or unpredictable behavior) and a bug that
gave rise to the error message "named_genall called".

		
20140923
  Fix a possible fault with
	# various declarations
	minimize f: /* nonlinear expression */
	# more declarations and data
	display f;
	solve;

		
20140925
  Fix an fault that arose under unusual and complicated conditions.

		
20140926
  Fix a possible fault with "let" commands assigning to synonyms, e.g.,
	let{i in 1 .. _nvars: _var[i] <= 0} _var[i] := .1;

		
20141016
  Fix a bug with updating dependencies for commands when "solve" or
"solution" command within a loop causes a new suffix to be introduced.
In the example that revealed the bug, a command of the form
"reset data foo;" appeared to be ignored after the new suffix appeared.
  On Unix-like systems, arrange to catch and report surprise SIGPIPE
signals.

		
20141020
  Redo bug fix with updating dependencies for commands when "solve" or
"solution" command within a loop causes a new suffix to be introduced
to make the fix work in more cases.

		
20141024
  Fix a glitch with "solexpand":  when some but not all members of an
array of constraints were dropped, "solexpand" sometimes incorrectly
commented that constraints were eliminated by presolve.
  Do not regard "q" as "quit" if followed on the same line by other
text, other than ";".
  Fix a glitch with "not alldiff{...}...".

		
20141030
  Fix a "yacc stack overflow" that was possible with unusual models.

		
20141104
  Fix a bug that gave a surprising "presolve has k = ..., P.nfv = ..."
message instead of "Solution determined by presolve; ...".

		
20141117
  Tweak error message for failed evaluations an imported functions
to mention "gradient" or "Hessian" if appropriate (i.e., if Errmsg
starts with ' or ", in which case the initial ' or " is not printed).
  Fix a memory leak with for{...}{...} loops.
  Fix a bug with new suffixes returned by solvers:  if subsequent
commands increased the number of components of the suffixed variable,
constraint, or objective beyond the next power of 2, memory corruption
could result.  In the example behind this bug fix, memory corruption
caused the error message "bug:  corrupted del mblk arg".

		
20141124
  Fix a bug with expressions involving values of dropped objectives
or of constraint bodies of dropped constraints when the expressions
appear in commands, such as printing commands, and previous commands,
such as "let" commands, have changed something involving variables
involved in the expressions.  Under some conditions -- without a
"solve", "solution", or "write" command, including "write 0;", being
executed after the changes -- the expressions were not computed
correctly.
  Fix a bug with "solve; display v;" when v is a defined variable.
Under some conditions, v was not recomputed to reflect the results
of the solve.
  Fix two bugs with redirecting a printing command (display, print,
or printf) to a file that cannot be created.  The next command could
elicit a surprising error messages, such as "... contexts remain open".

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

		
20141206
  Fix a couple of small memory leaks that accumulate over many commands.
  Fix a bug evaluating dropped objectives that depend on defined
variables.  Example:

		
	var x := 2; minimize foo: (x-3)^2;
	var xi{i in 1..3} = x^i;
	minimize o{i in 1..3}: xi[i];
	problem p: x, foo; display o, xi; # o was shown as all zeros.

		
20141216
  Fix a bug introduced 20141206 with defined variables not appearing
in the current problem (i.e., not in any constraint or objective):
such a variable was sometimes miscomputed.  Example:

		
	param p default 0; set I = 0..1;
	var x{i in I} >= 0 := i;
	s.t. c: sum{i in I} x[i] = 1;
	var y = x[0]; var z = p*y;
	print z;  # printed 1 rather than 0

		
20141228
  Fix a bug introduced in version 20140220 that sometimes bit with
defined variables involving piecewise-linear terms, leading to
incorrect results.

		
20141231
  To work around a Microsoft bug, set $ampl_funclibs to "-" rather
than "" when "solve" does not involve imported functions.

		
20150127
  Fix a glitch with format %.0e that caused
	printf "%.e\n", 4.7;
to print "4e+00" rather than "5e+00".
  Fix a fault with "show table_name;" when table table_name involves
nested indexings.  Example:

		
	set S; set T; param p{S, T};
	table mytab :  [S], {j in T}<{i in S} p[i,j]~(i&j)>;
	show table mytab; # faulted

		
20150131
  Fix a possible fault with loops involving indexed collections of
objectives and increases to the cardinality of the indexing sets of
those objectives.

		
20150213
  Extend simplification of logical constraints so a constraint of
the form
	logical_condition ==> linear_constraint
in which logical_condition is found always to be true is reduced
in more cases to a linear rather than a nonlinear constraint.
  Fix a glitch in the reported number of eliminated algebraic
constraints in the output of "option show_stats 1" when logical
constraints are converted to algebraic constraints.

		
20150214
  Fix a bug that bit under complicated conditions and gave error
message "tva top error".

		
20150302
  Fix a bug in assigning suffixes to subscripted problems by "solve"
and "solution" commands.  Suffixes were assigned to the problem's
first subscript rather than the current one.

		
20150312
  Fix a glitch in processing UTF8-encoded Unicode that caused declared
names starting with a non-ASCII character to be mishandled.

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

		
20150325
  Fix a bug (possible infinite loop) with a constraint of the form
"1 ==> algebraic_constraint" when the algebraic_constraint involved
a complicated sum.

		
20150327
  Fix a bug (possible fault) that could bite during cleanup after an
error message arising during instantiation of a defined variable.

		
20150415
  Fix some bugs that could affect models with logical constraints,
defined variables, and piecewise-linear terms, and fix a bug with
"option presolve 0" applied to such models.

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

		
20150430
  Fix a bug with logical constraints that bit under complicated
conditions.

		
20150501
  Redo yesterday's bug fix.

		
20150505
  Fix some glitches with error processing.

		
20150516
  Fix a glitch with v.lb, v.ub, v.lslack, v.uslack, and v.slack
where v is a variable instantiated without need of presolve and
after one or more other variables have been instantiated.
Example:
	var x <= 0; var y <= 0; display y.lb; display x.ub;
	# x.ub was wrong (with separate display commands)
	# but all went well with "display y.lb, x.ub;"

		
20150630
  Fix a glitch with output redirections, which could get lost
during computation of duals for eliminated constraints.

		
20150721
  Fix bugs with defined variables that are used as the only
variable in an equality constraint.  Solvers saw correct
problems, but commands (such as display and print) that used
expressions involving the defined variables saw incorrect
values for those variables.  Example:
	var x := 2;
	var y = (if x >= 1 then (x-1)^2) + 2.5;
	s.t. c: y = 17.5;
	display x, y, y.defeqn;
	# gave y = -16 rather than 3.5
	# and y.defeqn = 0 rather than 1
  Fix a bug in the indexarity functions: scalar variables gave
-1 rather than 0.  Example:
	var x; print indexarity('x'); # printed -1 rather than 0

		
20150815
  Fix glitches in detecting domain or range errors in "math" functions
such as log and exp on some systems, mainly MacOSX and hpux-ia64.

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

		
20150910
  Fix a bug with deducing that a defined variable has a fixed value.
If the number of variables was sufficiently more than the number of
constraints, memory corruption was possible.

		
20150923
  Fix a bug with defined variables in scripts that change the
cardinality of indexing sets of variables declared before the
defined variables.  A fault or other wrong behavior was possible.

		
20150925
  Fix some trouble (possible fault) with the update of 20150923.

		
20150928
  Fix another bug similar to that in the update of 20150923.

		
20151010
  Fix bugs with some complicated uses of defined variables and
piecewise-linear terms.  Examples:

		
	var x;
	var y = x + 3;
	s.t. c: y = 7;
	minimize o: <<4;-2, 3>> x;
	write 0;
	display x, y, o; # printed "y = 3" rather than "y = 7"

		
and (illustrating a separate bug)

		
	node n{1..3};
	arc a{i in 0..2} from {if i >= 1} n[i] to {if i < 2} n[i+1];
	s.t. c: a[1] = 3;
	var x = a[2] + 1;
	var y;
	minimize o: x + <<7;-1,1>> y;
	solve;
	display o, x, y; # o and y were 11 and -7 rather than -3 and 7

		
20151015
  Fix a bug (possible fault) with dropping all constraints and
objectives that use a defined variable.
  Fix a bug with evaluating piecewise-linear terms in problems
involving defined variables fixed by presolve.  A wrong value might
have been computed, e.g., for use in display.

		
20151026
  Fix bugs that caused faults under complicated conditions.

		
20151029
  Fix some trouble updating variables under complicated conditions.
  Fix a glitch with "xref": named problems were listed twice.

		
20151104
  Fix bugs with problems involving complementarity constraints and
defined variables.  Under complicated conditions, incorrect .nl files
were written.
  Complain in more cases about objectives and constraints involving
NaNs or bounds with inappropriately signed Infinity.  (There was
already a complaint about linear expressions with a Nan or Infinity
as a coefficient.)

		
20151118
  Fix a bug with "expand c;" when c is a constraint of the form
	double-inequality complements expression
or
	expression complements double-inequality.
If the expression involved a constant term, the constant term did not
appear in the "expand" output.  Example:

		
	var x{1..3};
	s.t. c: 3 <= x[1] <= 5 complements 123 + x[2] + 2*x[3];
	expand c; # 123 did not appear; it did appear in "solexpand c;"

		
20151120
  Fix a bug with introduced 20151104 in handling complementarity
constraints involving an explicit upper bound of +Infinity.  An
incorrect error message about the Infinity was given.

		
20151130
  Fix a bug with "read table" or "write table" that gave error message
"1 contexts remain open after compile!" under complicated conditions.
  Disallow defined variables in IN or INOUT table declarations.

		
20151203
  Fix a bug with computing values of defined variables eliminated by
presolve:  the linear parts were ignored.

		
20151216
  Fix a bug with using variables when params could be used:
an assignment to an otherwise unused variable of a value involving
a defined variable used in the problem just solved generally
used 0 as the value of the defined variable.  Example:

		
	var F; # could be param F, as solvers do not see it
	set I = 1..2; var x{I};
	var f = sum{i in I} (x[i] - i)^2;
	minimize o: f;
	s.t. vex: sum{i in I} x[i] = 1;
	solve; display f; # f = 2 (correct value)
	let F := f; display F; # F was zero

		
20151222
  Fix a bug with reading large data sections (more than 16 or 32
kilobytes of values and subscripts for 32- and 64-bit binaries,
respectively):  data corruption or a fault was sometimes possible.

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

		
20160121
  Fix a possible fault with "display foo;" when foo has a named
2-dimensional indexing set that is also the indexing set of an
indexed collection of ordered sets.
  Fix possible trouble in the update of 20160119 during "reset;"
when option log_file is not "".

		
20160131
  Fix a rarely seen bug in changing the size of the indexing
set of an indexed variable.
  Fix some bugs in the changes of 20160119.
  Fix a bug with "reset;" after "option log_file" specifies an
invalid file.

		
20160201
  Fix a fault that arose under complicated conditions.
  Fix trouble with "option log_File" when the solver faults.

		
20160207
  Fix a fault with an invalid subscript message occurring after
generation of a newly instantiationed variable declared before
previously instantiated variables (an obscure situation).

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

		
20160221
  Fix a bug (possible fault) with the interaction of blockmode (used
with some API variants), option log_file, and shell or solve commands.
  New builtin function date(fmt,t) returns a string representing time
t (as returned by the builtin time() function), formatted according to
fmt (a character string).  Either or both t and fmt may be omitted;
time() is assumed if t is omitted and "%Y%m%d %H:%M:%S" is assumed if
fmt is omitted; otherwise, date(t,fmt) and date(fmt,t) are treated
alike.  The expected usual usage is simply date(), i.e., omitting
both arguments, as in

		
	print date();

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

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

		
Also available on some systems are

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

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

		
20160310
  Fix glitches with floating-point values in hexadecimal notation
(use of which is supported but very unlikely):  some values that
should overflow to (appropriately signed) Infinity, such as 0x1p1025,
were mishandled, and values greater than 0x1p-1075 and less than
0x1.0000000000001p-1075 where treated as zero rather than the smallest
denormal number.
  Fix a bug with with the current environment:  after an environ
command changed the environment, a problem command specifying the
current problem did not change the environment back to the problem's
environment.

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

		
20160513
  Fix a bug introduced in 20150721 that caused some defined variables
involving linear uses of other defined variables to be miscomputed in
the AMPL session (but not by solvers).  Example:

		
	var w >=0.5 <=1 :=1;
	var x = sum{i in 0..4} w^i;
	var y = x;		# linear use of defined var x
	var z = exp(y/w);	# = exp(x/w) worked correctly
	maximize o: z;
	display x, y, z, objective; # z and o were wrong

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

		
20160530
  Fix a bug in reading .sol files involving partially dropped
logical constraints:  memory corruption was possible.
  Extend option infeas_clear so "option infeas_clear 3;" allows
"write" and "solve" commands to proceed when presolve detects
infeasibility.  In short, possible values for infeas_clear are now
	0 ==> always suppress "solve" and "write"
	1 ==> allow a second "solve" or "write" to proceed when
		reading stdin in interactive mode (default)
	2 ==> always allow a second "solve" or "write" to proceed
	3 ==> always allow "solve" or "write" to proceed
  Suppress some unlikely option commands issued while reading .sol
files when they have no effect.

		
20160602
  Fix a bug with some suffixes (of length 4-7) on synonyms.  When
the bug bit, memory corruption was possible.

		
20160609, 20160614
  Fix a rarely seen bug in which the right-hand side of a "let"
command involved a defined variable whose value was miscomputed.

		
20160712
  Fix a bug with models having both "var in set" declarations
and logical constraints.  Incorrect .nl files or faults with
"solexpand" were sometimes possible.  Example:

		
	var x{1..2} integer in {11, 22};
	s.t. c: alldiff{i in 1..2} x[i]; solexpand; #fault

		
20060714
  Fix a bug with constraints, objectives, and defined variables
involving a nonlinear expression of the form

		
	sum{i in S} if ... then i else ...
or
	sum{i in S} if ... then ... else i

		
in which "if ..."  involved variables.  An incorrect "if" operator
could appear in the .nl file, which on some systems might lead to
incorrect nonlinear evaluations in solvers.  (On at least one system,
a 32-bit Linux system, the bug was invisible.)

		
20160803
  Change the message "xxx is not defined" from a warning to a fatal
error (which terminates execution).

		
20160829
  Fix a parsing glitch:  do a better job of treating comments
delimited by /* and */ as white space.  Example:
	print if 1 < 2 then 3/*comment*/ else 4;
	# erroneously complained "3else is not defined"; now prints 3

		
20160907
  Fix a glitch in the update of 20160829, which led to an inappropriate
"syntax error" under complicated conditions.

		
20160920
  Rather than always terminating execution after an error message of the
form "nnn is not defined", when this message appears after a "model",
"data", or "commands" command or include phrase issued in interactive
mode, return to interactive input (after ignoring the rest of the
offending input file).

		
20161005
  Fix a bug that could bite after some error messages, such as (the
unlikely) "cannot multiply ... by Infinity".  No examples of the bug
actually biting are known.

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

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

		
20161107
  Fix a glitch (surprising error message) in 64-bit binaries with
models having defined variables and at most one constraint or
objective, but not one constraint and one objective.

		
20161110
  Fix a parsing glitch (surprising error message) that could arise
with a model or data command immediately following a compound command
(at the outermost level) of the form
	for{i in ...} repeat { ... } while ... p[i] ... ;
where the test in the while clause involves an entity subscripted by
a dummy variable instantiated in the for{...}.

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

		
20161220
  Fix a bug with defined variables: nonlinear expressions all of whose
variables were fixed by presolve were effectively ignored.  Example:

		
	var x >= 0; var y = sqrt(x);
	s.t. c: x == 1; print y; # printed 0 rather than 1

		
20161231
  Fix a rarely seen bug with defined variables fixed by presolve that
led to the error message "bug: corrupted del_mblk arg".

		
20170111
  Fix a bug with handling more than 64 output files from file
redirections (">filename" or ">>filename"):  a fault was possible
in "solve" or "shell" commands on Unix-like systems, such as Linux.
  Adjust history processing on Unix-like systems so when the current
input line is nonempty, control-D behave like "Delete", deleting the
character under the cursor.  Also arrange for the tab key to do
filname-completion (when unambiguous, except on 32-bit Sparc Solaris).

		
20170126
  Fix some bugs with tab completions, and extend ambiguous matches
over the unambiguous part.

		
20170207
  Fix a bug that could only bite a script running more than 4294967296
(i.e., 2^32) commands.

		
20170412
  Under -Rw, disable history.
  Fix a glitch (surprising error message) in computing reduced costs
involving an imported function with a string valued "if ... then ...
else" argument.

		
20170531
  Allow an optional comma between phrases in a set declaration
(as already allowed in param, variable, objective, and constraint
declarations -- none of which is described in the AMPL book).
  Allow commas to separate values in "read" commands.
  Fix a fault with complicated uses of piecewise-linear terms
in iterated constraints.
  Fix some bugs (leading to invalid .nl files) with complicated
uses of defined variables.

		
20170613
  Fix another bug with defined variables; the bug resulted in
an incorrect .nl file.  Example:

		
	var x{i in 1..2} := i;
	var y1 = x[1] + x[2]^2;	# nonlinear defined variable
	var y2 = 2*y1 + 1;	# linear use of y1
	minimize o: 1/y2;	# nonlinear use of y2

		
20170614
  Fix a fault that was possible under complicated conditions.

		
20170616
  Honor "ordered" in

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

		
and in

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

		
20170621
  In commands of the form

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

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

		
20170628
  Fix a fault that arose under complicated conditions.
  Fix a nasty bug with defined variables that led to wrong
objectives and constraints:  when a defined variable had both
a linear and a nonlinear part, wrong linear parts were sometimes
transmitted to the .nl file under the default option linelim 1.
Example:
	var x := 3; var y = 2*x + (x-1)^2;
	minimize foo: 3*x + y;  # behaved as 5*x + y

		
20170630
  Fix a botch in the changes of 20170621 that could cause a fault
in a "commands" command.

		
20170706
  Extend the change of 20170621 so in the context of

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

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

		
20170711
  More fixes to "break" commands in nests of "commands" commands.

		
20170717
  Fix a possible fault in "display p;" when p has an indexing set
in which later set expressions depend on earlier ones.  Example:

		
	set A; set B{A} ordered;
	param p{i in A, B[i]}; data;
	set A := 1 2;
	set B[1] := a b c;
	set B[2] := c a b;
	param p : a b c :=
	1 11 12 13
	2 21 22 23;
	display p; # faulted

		
20170718
  Fix a another possible fault in "display p;" when p has an indexing
set involving three or more set expressions and some later set
expressions depend on earlier ones.  Whether the bug bit depended
on the relative sizes of the component sets.  Example:

		
	set A; set B{A} ordered; set C;
	param p{i in A, B[i], C} := Normal01();
	data;
	set A := 1 2 3;
	set B[1] := a b c;
	set B[2] := c a b;
	set B[3] := b c a;
	set C := W X Y Z;
	display p; # faulted

		
20170724
  Fix bugs with "break commands;" and "break all;" that could bite if
the command terminated a loop with dummy variables.

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

		
20170902
  Fix a bug with reading ".tab" tables with rows more than 2000 characters
long.  An occasional value might have been misread as 0.

		
20170914
  Fix a bug with a subscripted defined variable subject to bound
constraints when the indexing set, after being instantiated for one
"solve", increased in size beyond the next power of 2 for a subsequent
"solve".
  Add a Caution for "(numeric expression) & (numeric expression)", which
converts both numeric values to strings and concatenates them.  Since
dummy variables may have string or numeric values, the new Caution is not
given for "A & B" when A or B is a dummy variable.

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

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

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

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

		
20171002
  Have printf format %q quote ".".
  Fix a glitch that sometimes caused "write table" to run presolve
unnecessarily, which could cause a spurious "Solution determined
by presolve" message to appear.
  Fix a bug in the handling of synonym _con by "write table".

		
20171028
  Fix a bug with "ampl foo" when file foo ends with an incomplete
data section (no final semicolon) whose last line is incomplete,
i.e., does not end with a newline character.  With some versions of
MS Windows, the 64-bit ampl.exe faulted on such examples.

		
20171103
  Fix a bug that, under complicated conditions involving "unfix",
gave error message "... presolve finds no feasible solution possible."
Example:
	var x >= 2 := 10;
	minimize f: x;
	fix x;
	s.t. c: x <= 5;
	display c.slack;
	unfix x;
	display c.slack;
	solve; # ... presolve finds no feasible solution possible.

		
20171107
  Fix a glitch with "reset;" under -R:  $PATH could have been corrupted.

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

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

		
20171209
  Fix unlikely trouble with reduced-cost computations when
"option allow_NaN 1" is in effect and with exp(...)  expressions that
underflow to zero.
  Fix a bug with defined variables whose value is a linear expression
plus a defined variable involving a nonconvex piecewise-linear term.
The linear expression got lost.  Example:

		
	var y >= -10;
	var z = 3*y;
	s.t. xb: -1 <= z <= 16;
	var pl =  <<2,3,5,9,12;1,-1,1,-1,1,-1>> z;
	var c = 4*z + 3*pl;
	minimize pd: c;	# the 4*z part got lost

		
  Fix another bug with nonconvex piecewise-linear terms illustrated
by the example

		
	var x >= -1 <= 16;
	minimize pl: <<2,3,5,9,12;1,-1,1,-1,1,-1>> x;
	s.t. q: (x-6)^2 <= 200;

		
which resulted in an invalid .nl file.
  Fix an infinite loop involving unusual use of defined variables.

		
20171212
  Fix an obscure fault, hitherto not seen, involving piecewise linear
terms.

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

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

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

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

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

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

		
20180417
  "Invisible" tweak to yesterday's changes.

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

		
20180503
  When single-stepping, try to recover from input errors rather
than simply exiting.
  Fix a bug, introduced 20171122, with "param :setname: parname"
followed by a : ... := table (called a value-table on p. 476 of
the AMPL book).  For example,
	set S dimen 2; param p{S};
	data; param :S: p
		: X Y Z :=
		A 1 2 3
		B 4 . 6;
	display S, p;
will now work again.

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

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

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

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

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

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

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

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

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

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

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

		
20180820
  Fix a bug seen in scripts of the form

		
	repeat {
		solve;
		break;
		}
	print solve_exitcode;

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

		
	256*(exit_value) + termination_code

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		
are treated alike.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		
20190927
  Fix an obscure fault.

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

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

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

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

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

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

		
20200110
  Fix a fault with "option;" after adding a new option to another
environment that is not in the current one.
  Add a Caution about ignoring a duplicate ":=" in a data section.
The example that caused this addition led to a fault (now avoided).

		
20200123
  Fix a seemingly invisible bug with "let _con[i] := ...".
  Fix a bug with \ in data sections.  Example:
	param p symbolic;
	data;
	param p := "x\
\\
y";	# erroneous error message about missing "

		
20200501
  Fix a bug with _nvars after a "delete variable" command.
  Fix an obscure display bug that gave error message
"corrupted del_mblk arg".

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

		
20201019
  Fix a bug (fault) with a set of variables indexed over the
empty set.
  Have the delete command recover more memory from constraints
and variables.

		
20201031
  Fix a glitch (possible fault) in interactive mode connected
with an error message for a wrong number of subscripts.  Example:
	ampl: set S1 := 1..3;
	ampl: set S2 := 1..3;
	ampl: param a {S1,S2};
	ampl: let a[1] := 1;
	# fault
  For entities with restricted domains (e.g., params with an "in"
clause), check the restrictions at the end of "let".
Example:
	set A := {'a', 'aa', 'aaa'};
	param a symbolic in A;
	let a := 'bcd';
	display a; # no longer reached

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

		
20201123
  Fix a bug with some subscripted generic synonyms after some of
the entities in question have been dropped/fixed.  Wrong values
were computed.  Example:

		
	model diet.mod
	data diet.dat
	solve;
	drop diet['B1'];
	display _conname, _con, _con.body, _con.slack;
	display {i in 1.._ncons} (_conname[i], _con[i], _con[i].body, _con[i].slack);
	# _con[i].body and _con[i].slack were wrong for i > 1.

		
  Fix a bug with _ccon[something].astatus and _ccon[something].status,
which gave "Bug: bad case 6 in f_OPSYNDOTSYM".

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

		
20210215
  Fix a bug illustrated by:

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

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

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

		
then the interactive input

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

		
produced error messages

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		
rather than

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

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

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

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

		
with an erroneous offset.

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

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

		
now gives

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

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

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

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

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

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

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

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

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

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

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

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

		
Changing the third line to

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

		
was a work-around.

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

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

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

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

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

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

		
got the surprising error message

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

		
Now the second line elicits the error message

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

		
This example can be restated as

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

		
Previously the second line of the little example

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

		
elicited the surprising error message

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

		
Not it gets

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

		
The example can be rewritten (without complaint) as

		
	var x in {0,3,5};

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

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

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

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

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

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

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

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

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

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

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

		
produced

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

		
Now it produces

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		
	c2.lno = 0
	c2.sno = 1

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

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

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

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

		
	count(list_of_expressions)
	count {indexing} (list_of_expressions)

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

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

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

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

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

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

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

		
gives output

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

		
	indexarity('test') = 3

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

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

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

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

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

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

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

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

		
should print

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

		
rather than

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

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

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

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

		
.

NEW PAGES:

[ODDNUGGET]

[GOPHER]