Assertions
Data validity is important
In almost all modeling applications it is important to check the validity of input data prior to its use. For instance, in a transportation model it makes no sense if the total demand exceeds the total supply. In general, data consistency checks guard against unexplainable or even infeasible model results. As a result, these checks are essential to obtain customer acceptance of your application. In rigorous model-based applications it is not uncommon that the error consistency checks form a significant part of the total model text.
Assertion
declaration and attributes
To provide you with a mechanism to implement data validity checks, AIMMS
offers a special Assertion
data type. With it, you can easily
specify and verify logical conditions for all elements in a particular
domain, and take appropriate action when you find an inconsistency.
Assertions can be verified from within the model through the ASSERT
statement, or automatically upon data changes by the user from within
the graphical user interface. The attributes of the Assertion
type
are given in this table.
Attribute |
Value-type |
See also page |
---|---|---|
|
index-domain |
The IndexDomain attribute for Parameters, The IndexDomain attribute for Variables |
|
string |
The Text and Comment attributes, The Text attribute for Parameters |
|
|
|
|
integer |
|
|
logical-expression |
The Definition attribute, The Definition attribute for Parameters |
|
statements |
|
|
comment string |
The Definition
attribute
The Definition
attribute of an Assertion
contains the logical
expression that must be satisfied by every element in the index domain.
If the logical expression is not true for a particular element in the
index domain, the specified action will be undertaken. Examples follow.
Examples
Assertion SupplyExceedsDemand {
Text : Error: Total demand exceeds total supply;
Definition : {
Sum( i in Cities, Supply(i) ) >=
Sum( i in Cities, Demand(i) )
}
}
Assertion CheckTransportData {
IndexDomain : (i,j) | Distance(i,j);
Text : Please supply proper transport data for transport (i,j);
AssertLimit : 3;
Definition : {
UnitTransportCost(i,j) and
MinShipment(i,j) <= MaxShipment(i,j)
}
}
The assertion SupplyExceedsDemand
is a global check. The assertion
CheckTransportData(i,j)
is verified for every pair of cities i
and j
for which Distance(i,j)
assumes a nonzero value. AIMMS
will terminate further verification when the assertion fails for the
third time.
The Text
attribute
The Text
attribute of an Assertion
is the text that is used as
warning or error message when the assertion fails for an element in its
domain. If the text contains indices from the assertions index domain,
these are expanded to identify the elements for which the assertion
failed. If you have overridden the default response by means of the
Action
attribute (see below), then the text attribute is ignored.
The Property
attribute
The Property
attribute of an assertion can only assume the value
WarnOnly
. With it you indicate that a failed assertion should only
result in a warning being triggered, instead of an error. This attribute
is also ignored if the Action
is overridden.
The AssertLimit
attribute
By default, AIMMS will verify an assertion for every element in its
index domain, and call the (default) action for every element for which
the assertion fails. With the AssertLimit
attribute you can limit
the number of verifications that are made. When the number of failed
assertions reaches the AssertLimit
, AIMMS will stop the verification
of any further elemens in the index domain. By default, the
AssertLimit
is set to 1.
The Action
attribute
The default response to a failing assertion is that either an error or a
warning is raised, based on the Property
setting. You can use the
Action
attribute if you want to specify a nondefault response to a
failed assertion. Like the body of a procedure, the Action
attribute
can contain multiple statements which together implement the appropriate
response. During the execution of the statements in the Action
attribute, the indices occurring in the index domain of the assertion
are bound to the currently offending element. This allows you to control
the interaction with the end-user. For instance, you can request that
all detected errors in the index domain are changed appropriately, or
perhaps implement an auto-correct on invalid values.
The FailCount
operator
If you raise an error or call the HALT
statement during the
execution of an Action
attribute, the current model execution will
terminate. When you use it in conjunction with the predefined
FailCount
operator, you can implement a more sophisticated version
of the AssertLimit
. The FailCount
operator evaluates to the
number of failures encountered during the current execution of the
assertion. It cannot be referenced outside the context of an assertion.
Verifying assertions
Assertions can be verified in two ways:
by explicitly calling the
ASSERT
statement during the execution of your model, orautomatically, from within the graphical user interface, when the end-user of your application changes input values in particular graphical objects.
The ASSERT
statement
With the ASSERT
statement you verify assertions at specific places
during the execution of your model. Thus, you can use it, for instance,
during the execution of the MainInitialization
procedure, to verify
the consistency of data that you have read from a database. Or, just
prior to solving a mathematical program, to verify that all currently
accrued data modifications do not result in data inconsistencies. The
syntax of the ASSERT
statement is simple.
Syntax
assert-statement:
Example
The following statement illustrates a basic use of the ASSERT
statement.
assert SupplyExceedsDemand, CheckTransportData;
It will verify the assertion SupplyExceedsDemand
, as well as the
complete assertion CheckTransportData
, i.e. checks are performed
for every element (i
,j
) in its domain.
Sliced verification
AIMMS allows you to explicitly supply a binding domain for an indexed assertion. By doing so, you can limit the assertion verification to the elements in that binding domain. This is useful when you know a priori that the data for only a small subset of the elements in a large index domain has changed. You can use such sliced verification, for instance, during the execution of a procedure that is called upon a single data change in a graphical object on a page.
Example
Assume that CurrentCity
takes the value of the city for which an
end-user has made a specific data change in the graphical user
interface. Then the following ASSERT
statement will verify the
assertion CheckTransportData
for only this specific city.
assert CheckTransportData(CurrentCity,j),
CheckTransportData(i,CurrentCity);