Time Like and Event like Attributes - openmpp/openmpp.github.io GitHub Wiki
Home > Model Development Topics > Time-like and Event-like Attributes
This topic describes the distinction between event-like and time-like attributes, and forbidden uses of time-like attributes in model code.
- Time-like and event-like attributes: Definitions and examples
- Potential issues: How time-like attributes could violate the model specification
- Protection against potential issues: How OpenM++ protects against these issues
- Disabling protection: How to disable OpenM++ run-time protection
An OpenM++ simulation consists of a sequence of events which change values of attributes when the events occur.
Attributes are observed only at events, not between events.
Some attributes, however, can undergo unobserved changes between events.
An example is the built-in attribute time
, which changes continuously between events, even though it is observed only when events occur.
Attributes like time
or age
which undergo unobserved changes between events are called time-like.
Another example of a time-like attribute is the identity attribute
bool first6months = (age <= 0.5);
Logically, the attribute first6months
changes value when age
is exactly equal to 0.5. However, unless there is an event which occurs precisely at that moment, the transition of first6months
from true
to false
will not be observed when it logically occurs. For example, if the first event in the entity occurs at age 1.0, the value of first6months
will become false
at that time, but the transition of first6months
from true
to false
at age 0.5 will not have been noted at the time it logically occurred.
An attribute which changes only at events is called event-like. For example, the attribute
bool is_alive = {true);
is event-like. It has initial value true
and changes to false
when the Mortality
event occurs (code not shown).
All self-scheduling attributes are event-like because they schedule an internal event at appropriate times. For example, self_scheduling_int(age)
is an event-like attribute with value equal to integer age of the entity. It is event-like because it schedules an internal event when age
will attain its next integer value.
A derived attribute which observes a time-like attribute may be event-like. For example, the derived attribute
value_at_first_entrance(is_alive, false, age)
which records age at death is event-like because it observes the value of age
when is_alive
transitions to false
during the Mortality event.
The OpenM++ compiler deduces whether an attribute is event-like or time-like.
The
Symbol Reference
of a model can be consulted to determine if an attribute is time-like.
For example,
the Symbol Reference topic for the age
attribute in RiskPaths
looks like
and indicates, after Kind:, that it is time-like. Attributes not indicated as time-like in the Symbol Reference are event-like.
There are three situations where use of a time-like attribute could violate the model specification and produce unexpected or incorrect model results.
- A time-like filter of an entity table or entity set;
- A time-like dimension of an entity table or entity set;
- The use of a time-like attribute in an event time function.
For situation 1, consider the following table declaration using the time-like attribute first6months
introduced above.
table Host MyTable
[ first6months ]
{
{
duration() //EN duration
}
};
Logically, this table should sum the value 0.5 for each entity which survives to age 0.5 or beyond. But if the first event occurs later, for example when age
is 1.0, the value 1.0 would be summed instead, producing a logically erroneous result given the table specification.
For situation 2, consider a modified version of this table which uses the time-like attribute first6months
as a dimension instead of as a filter. The total duration in the table would be correct, but it would be misclassified between the two cells in the table.
For situation 3, consider if the time-like attribute first6months
is used in an event time function. Assume that the model implements a first tranche of vaccination when an infant is 6 months old. Model code in the time function of the ChildVaccination
event might include a statement like
if (!vaccinated && !first6months) return WAIT(0);
to trigger the ChildVaccination
event when the child is 6 months old. However, the attribute first6months
is time-like and changes value at 6 months of age only if some other event happens to occur at that precise value of age
. If there is no such event, the ChildVaccination
event would be triggered at some later time when the value of first6months
is next updated, perhaps at the first birthday when age
is 1.0.
OpenM++ identifies situations 1 and 2 at build time and issues an error message like
error : the filter of table 'TimeLikeTest' must not be time-like
error : dimension 'first6months' of table 'TimeLikeTest' must not be time-like
OpenM++ identifies situation 3 at run time and halts the simulation with an error message such as the following:
Simulation error: Attempt to access the time-like attribute age
by the event time function of event OneTime
in entity_id 2
when current time is -inf
before enter_simulation
in simulation member 0
with combined seed 1
Modgen-specific: In Modgen parlance a time-like attribute is called a continuously-updated state (CUS). Modgen issues an error message at build time for situations 1 and 2. Modgen attempts to detect situation 3 at build time, by prohibiting some types of C++ code (including links/pointers) in event time functions, and by scanning event time functions for any symbol which has the same name as an attribute. The OpenM++ design takes a different approach, instead imposing no restrictions on model C++ code and detecting situation 3 directly at run-time.
There is some overhead associated with run-time detection of situation 3 which is typically minor. It can be eliminated by disabling run-time detection using the statement
options verify_timelike_attribute_access = off;
If this run-time detection is disabled, the model will write the following warning to the log on every model run:
Warning : prohibited time-like attribute access is not detected with verify_timelike_attribute_access = off