| Proposed New AMPL Features | Draft of February 4, 1997 |
Other aspects of an advanced user interface would be visible to users through changes to the AMPL language as described below. The main topics are:
- Communication with solvers through memory rather than files.
- Solvers requesting additional information from AMPL, such as the name of a variable that will be mentioned in an error message, or priorities for integer variables.
- Solvers remaining active after they have returned a solution, to wait for additional instructions from AMPL.
- AMPL requesting additional information from solvers, such as sensitivity or infeasibility analysis at the optimal solution.
- Fast changing and re-solving of problem instances, by keeping the solver active and sending it only the changes.
To keep things simple, the following discussion assumes that information about an optimal solution is returned to AMPL by a solve command. If instead the solution command is used to restore a solution from a previously saved .sol file, then the discussion applies to the solve whose results are recorded in the file.
Thus it would be desirable to let users define new qualifiers. If we denote these by the term "suffix", for example, the we would have a suffix command to define new suffixes and would extend the current dot notation to use them:
Existing AMPL utility commands would be extended to apply to suffix names where appropriate. For example:
- suffix suffix-name
for-phraseopt inout-phraseopt type-phraseopt restriction-phraseopt ... ;
- Defines a new suffix for use with AMPL model components. One or more of the indicated phrases might appear, in any order, to restrict the use of the suffix in various ways.
The type-phrase (such as integer) and restriction-phrase (such as >= 0) would limit the range of values that a suffixed entity can take. They would have the same syntax and meaning as in parameter declarations. Suffixes of type symbolic would not be implemented initially.
The for-phrase and inout-phrase are discussed further below.
- variable-ref.suffix-name
constraint-ref.suffix-name
objective-ref.suffix-name
problem-ref.suffix-name
- Refers to an auxiliary value associated with the named component and suffix.
By default a defined suffix could be used with all variables, constraints, objectives, and named problems, in any context where an AMPL variable may appear. Its use could be restricted to particular component types by use of one or more for-phrases:
- purge suffix-name ;
- Removes the previous definition of the indicated suffix, and any values associated with it.
for varA major purpose of user-defined suffixes or qualifiers would be to pass additional information between AMPL and solvers. The inout-phrase would specify how the suffix is allowed to be used for this purpose:
for con
for obj
for prob
Any invocation of solve would cause all values associated with suffixes of type OUT or INOUT to be passed to the current solver. Mechanisms for more selective passing of this information could be introduced, but initially the passing of these values could be avoided only by using purge to remove an unwanted suffix's definition.
- INOUT (the default)
- Values associated with the suffix are passed "out" to any solver (when invoked by solve) and are copied back "in" from the solver when it terminates. For solvers based on the simplex method, basis statuses would be of this kind, since the solver would read their values to determine an initial basis, and at termination would change their values to specify the optimal basis.
- OUT
- Values associated with the suffix are passed to a solver, but are not copied back when the solver terminates. For integer programming solvers based on a branch-and-bound procedure, priorities and branching directions would be of this kind, since their only purpose is to direct the actions of the solver when it is searching for an optimal solution.
- IN
- Values associated with the suffix are not passed to any solver, but are copied from a solver when it terminates. Suffixes representing supplementary information on sensitivity, unboundedness and infeasibility would be of this kind, since they convey information that it determined only at the end of a solver's run.
- LOCAL
- Values associated with the suffix are neither passed to nor copied from any solver. Suffixes of this kind would be used only for the modeler's convenience in maintaining certain values associated with all components of one or more types.
Suffixes of type IN could be assigned new values only by a solver, not by an AMPL let statement. (All of the current built-in suffixes would thus be treated as having this type.)
Where suffixes are integer codes for basis statuses and similar information, it is desirable to let users work with corresponding mnemonic strings instead. For this purpose, an associated AMPL option would be defined to represent a table of integer values and corresponding strings. The name of this option would be determined from the name of the suffix:
option suffix-name_table table-spec ;In the case of a suffix named sstatus, for example, the associated option would be sstatus_table. The table-spec is a multi-line string that has the form of a table; several examples are shown in the discussion of statuses below.
For example, a solver directive might be provided to request that sensitivity analysis routines be run after an optimal solution is determined. When turned on, this directive would have the effect of causing appropriate suffixes for the additional sensitivity information to be defined when results were returned by the solver. The user would thus be able to get sensitivity information without knowing anything about the suffix command.
A solver-defined suffix of this kind could be of type IN or INOUT. The type would be specified as part of the solver's output. (Additional options, to suppress solver-defined suffixes and discard the associated values, might later be added.)
Three predefined suffixes are proposed for making reference to statuses of variables and constraints. Their use can be summarized as follows, where we denote by ref either a variable-ref or a constraint-ref:
A component's .astatus can be regarded as being set by AMPL, while its .sstatus is set by the solver or user. The .astatus would distinguish which variables and constraints AMPL would send to the solver, whereas the .sstatus would be sent to the solver along with the variables and constraints and would be used to suggest a starting point for the optimizing algorithm. The .status suffix would provide an easy way to get a quick summary of the most relevant status information, by typing something as short as display Buy.status. (The same suffixes could apply also to objectives, though with somewhat different meanings -- objective and problem suffixes are discussed separately below.)
- ref.astatus
- The "AMPL status" of a variable or constraint -- whether it is currently active, and why it was removed if not.
- ref.sstatus
- The "solver status" of a variable or constraint -- typically, its status in an optimal basis returned by the most recent solve.
- ref.status
- If ref.astatus is not '' (an empty string) then ref.astatus, otherwise ref.sstatus.
Values of .astatus supported by AMPL would be as follows:
Variables of type 'unused' are eliminated from the problem even under the setting option presolve 0. They are treated specially so that no variables of type 'pre' appear when the presolve phase has been turned off. (There could be an analogous special status for constraints, but currently there don't appear to be any kinds of constraints that are eliminated from a problem under the setting option presolve 0.)
.astatus Interpretation Variables Constraints '' '' Normal state (active in the current problem) 'fix' Fixed by a fix or problem command 'drop' Dropped by a drop or problem command 'pre' 'pre' Fixed or dropped by AMPL's presolve phase 'sub' 'sub' Eliminated by substitution, as the result of a defined variable or a constraint interpreted as a definition 'unused' Not appearing in any declared constraint or objective
AMPL would also define the following standard values for .sstatus:
The .sstatus of a constraint would normally pertain to a slack or artificial variable that the solver associates with the constraint. The index number shown in the table is intended as a concise alternative to the .sstatus string, for use by AMPL in communicating with solvers; users would see the index number only in exceptional cases (discussed further below).
Index .sstatus Intended interpretation 0 'none' Not yet assigned any status 1 'bas' Basic 2 'sup' Superbasic 3 'low' Nonbasic <= (usually =) lower bound 4 'upp' Nonbasic >= (usually =) upper bound 5 'equ' Nonbasic at equal lower and upper bounds 6 'btw' Nonbasic between bounds
(including nonbasic "free" variables)
A new option sstatus_table would provide a concise summary of the .sstatus values in use. AMPL would initialize it to the following table in the form of a string:
'\ 0 none not assigned any status\ 1 bas basic\ 2 sup superbasic\ 3 low nonbasic <= (normally =) lower bound\ 4 upp nonbasic >= (normally =) upper bound\ 5 equ nonbasic at equal lower and upper bounds\ 6 btw nonbasic between bounds\ 'To employ a different arrangement of statuses, a solver would overwrite this default sstatus_table with its own string representing a table; and it would return its own choice of integer index value (not necessarily limited to the range of 0-6) for each variable and constraint. (A user could do the same thing, though this would be less common.) The new sstatus_table would subsequently be used by AMPL to retrieve the status strings (like 'bas' and 'upp') that a command like display Buy.status would exhibit. The sstatus index values would thus normally continue to remain invisible to users. The only exception would occur if the solver were to return an index value that did not appear in the table.
For completeness a corresponding astatus_table would also be initialized. It would not be subject to change by the solver, however.
When creating a variable or constraint, AMPL would set its .astatus to '' and its .sstatus to 'none'. Statuses of 'none' would indicate to a solver that it should pick statuses on its own, such as by a built-in crash procedure. At each solve, AMPL's default action would be to send all statuses to any simplex-based solver, and to overwrite them with the (usually optimal) statuses returned by the solver. This behavior could be overridden by either of the following:
A solver might also recognize a variety of directives to ignore statuses or to treat them in some special way. These would vary from one solver to the next, however.
- reset statuses;
- Set all .astatus values back to '' and all .sstatus values back to 'none'.
- option send_statuses i;
- If i is 1 (the default), send all .sstatus values to any solver. If i is 0, do not send these values.
Values of .astatus for objectives and problems would be much the same as the previously defined values for variables and constraints:
AMPL would also define the following standard .sstatus values, which are necessarily quite different from those for variables and constraints:
.astatus Interpretation Objectives Problems '' '' Current, by default or through the effects of a restore, objective or problem command 'drop' Not current, by default or through the effects of a drop or objective command 'non' Not current, by default or through the effects of a problem command 'pre' 'pre' Objective value determined by presolve
Following a solve, the .sstatus of the current objective and of the current problem would be set the same. Although in principle one or the other would be redundant, in practice there are situations in which each each relates to the status much better than the other:
Index .sstatus Intended interpretation 0 'none' Not yet assigned any status 7 'min' Minimized by most recent solve 8 'max' Maximized by most recent solve 9 '+unbdd' Found to be unbounded above by most recent solve 10 '-unbdd' Found to be unbounded below by most recent solve 11 'infeas' Not optimized at most recent solve because no feasible solution could be found
This sort of solver "termination status" is different from the statuses of individual model components discussed above. It is simpler in routine use, but can be specialized to deal with a broader variety of termination states that vary considerably from one solver to the next. Our overall design goal remains the same, however; we want to have a standard arrangement that works well with most solvers, while providing enough flexibility to accommodate the many different algorithms and implementations to which AMPL might be hooked.
Several predefined quantities would be provided to report the termination status associated with the most recent solve, in complementary ways:
- solve_code
- A numerical value representing the outcome of the most recent solve.
- solve_status
- A (preferably short) character string representing the outcome of the most recent solve.
- solve_message
- A (potentially long) character string describing the outcome of the most recent solve, such as
'CPLEX 3.0: optimal integer solution; objective 235625\ 684 simplex iterations\ 126 branch-and-bound nodes'- show_solve_message
- Number of lines of the solve_message string to be displayed. A value of zero suppresses the message entirely.
- solve_status_table
- A character string that provides a table relating solve_code values to solve_status strings.
Before the first solve, solve_code would be -1; solve_status and solve_message would be empty strings. In cases where a solver terminates without returning solver status information -- because it is a version that predates this new feature, or has aborted without writing results -- solve_code would be set by AMPL to -1, and solve_status would be '?'.
The value of solve_status_table would be initialized to
'\ 0 solved\ 100 solved?\ 200 infeasible\ 300 unbounded\ 400 limit\ 500 failure'In each line, the number would be the minimum solve_code to be associated with the indicated solve_status. The solve_code values 0 through 99 would be associated with a solve_status of 'solved', for instance, and 300-399 would be associated with 'unbounded'. Thus a script that needed to test for a finite optimum might use a simple and easily understood test like
if solve_status = 'solved' then ...The same thing could be achieved by testing solve_code < 100, but this is undesirably cryptic and solver-dependent. Instead, the solve_code values are mainly intended to provide a finer distinction, if needed, between different situations covered by the same solve_status. For example, CPLEX's "optimal with unscaled infeasibilities" and "optimal integer solution within mipgap" would have separate nonzero solve_code values < 100. The initial value of solve_status_table shown above is intended to suggest an AMPL-standard framework for relating solve_code and solve_status, but solvers would have the option of returning an alternative table reflecting a different numbering scheme.
- solve_exitcode
- The operating system exit code returned by the most recent solve command.
- shell_exitcode
- The operating system exit code returned by the most recent shell command (unrelated to the solver's activity, but noted here for completeness).
Return to the AMPL proposed new features page.
Return to the AMPL update page.