# 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 of`TotalCostFunction`

as input parameters of the definition of`TotalCost`

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