Expressions and Statements Allowed in Definitions
Complicated definitions
In most applications, the functional relationship between input and output identifiers in the definition of a set or a parameter can be expressed as an ordinary string-valued, set-valued, set element-valued or numerical expression. In rare occasions where a functional relationship cannot be written as a single symbolic statement, a function or procedure can be used instead.
Allowed definitions
In summary, you may use one of the following items in set and parameter definitions:
a string-valued expression,
a set-valued expression,
an element-valued expression,
a numerical expression,
a call to a function, or
a call to a procedure.
Limited selfreferencing allowed
Under some conditions, expressions used in the definition of a particular parameter can contain references to the parameter itself. Such self-referencing is allowed if the serial computation of the definition over all elements in the index domain of the parameter does not result in a cyclic reference to the parameter at the individual level. This is useful, for instance, when expressing stock balances in a functional manner with the use of lag operators.
Example
The following definition illustrates a valid example of a self-reference.
Parameter Stock {
IndexDomain : t;
Definition : {
if ( t = FirstPeriod ) then BeginStock
else Stock(t-1) + Supply(t) - Demand(t) endif
}
}
If t
is an index into a set Periods =
{0..3}
, and
FirstPeriod
equals 0
, then at the individual level the
assignments with self-references are:
Stock(0) := BeginStock ;
Stock(1) := Stock(0) + Supply(1) - Demand(1) ;
Stock(2) := Stock(1) + Supply(2) - Demand(2) ;
Stock(3) := Stock(2) + Supply(3) - Demand(3) ;
Since there is no cyclic reference, the above definition is allowed.
Functions and procedures
You can use a call to either a function or a procedure to compute those definitions that cannot be expressed as a single statement. If you use a procedure, then
for sets, no arguments are allowed,
for parameters, some input arguments and at most one output argument are allowed.
In addition, the procedure cannot have any side-effects on other global sets or parameters. This means that no direct assignments to other global sets or parameters are allowed.
Arguments and global references
The identifiers referenced in the actual arguments of a procedure call, as well as the global identifiers that are referenced in the body of the procedure, will be considered as input parameters for the computation of the current definition. That is, data changes to any of these input identifiers will trigger the re-execution of the procedure to make the definition up-to-date. The same applies to functions used inside definitions.
Examples
The following two examples illustrate the use of functions and procedures in definitions.
Consider a function
TotalCostFunction
which has a single argument for individual cost coefficients. Then the following declaration illustrates a definition with a function reference.Parameter TotalCost { Definition : TotalCostFunction( CostCoefficient ); }
AIMMS will consider the actual argument
CostCoefficient
, as well any other global identifier referenced in the body ofTotalCostFunction
as input parameters of the definition ofTotalCost
.Similarly, consider a procedure
TotalCostProcedure
which performs the same computation as the function above, but returns the result via a (single) output argument. Then the following declaration illustrates an equivalent definition with a procedure reference.Parameter TotalCost { Definition : TotalCostProcedure( CostCoefficient, TotalCost ); }
One procedure for several definitions
Whenever the values of a number of identifiers are computed simultaneously inside a single procedure without arguments, then this procedure must be referenced inside the definition of each and all of the corresponding identifiers. If you do not reference the procedure for all corresponding identifiers, a compile-time error will result. All other global identifiers used inside the body of the procedure count as input identifiers.
Example
Consider a procedure ComputeCosts
which computes the value of the
global parameters FixedCost(m,p)
and VariableCost(m,p)
simultaneously. Then the following example illustrates a valid use of
ComputeCosts
inside a definition.
Parameter FixedCost {
IndexDomain : (m,p);
Definition : ComputeCosts;
}
Parameter VariableCost {
IndexDomain : (m,p);
Definition : ComputeCosts;
}
Omitting ComputeCosts
in either definition will result in a
compile-time error.