Chapter 4: Conditions and States
Agents in FRED are subject to a set of conditions that represent the aspects of interest to the model. Each condition consists of a set of states that represent the agent’s current status within that condition.
Conditions
To build a model in FRED, you first need to decide what conditions you want to track within the population. Conditions might represent communicable diseases like influenza, economic conditions such as poverty, or behaviors such as drug use or vaccine uptake. Models can include as many conditions as needed. Conditions are composed of properties and states, with each state containing a set of rules for what an agent does when they enter the state and how to proceed from state to state. An agent must be in exactly one state in each condition.
condition blocks
Conditions are defined within a condition block, such as:
condition INFLUENZA { ... }
The block of code within the brackets defines the properties and states of the condition. The complete set of properties and their default values are shown below:
condition <condition_name> {
# initial states
start_state = Excluded
meta_start_state = Excluded
group_start_state = Excluded
# transmission properties
transmission_mode = none | proximity | network | environmental
transmissibility = 0
exposed_state = none
transmission_network_name = none
# output properties
output = 1
enable_agent_records = 1
}
Note
If an exposed_state
is specified, then it is required that
transmissibility > 0
. Transmission is described in detail in
Chapter 13.
Note
All properties must be set using a literal, i.e. propeties cannot be set using an expression containing a variable or function.
naming rules and conventions
Each condition within a model must be given a unique name, but state
names may appear in more than one condition. The “full name” of a
state includes its condition name and is written
<condition_name>.<state_name>
, for example:
INFLUENZA.Susceptible
. Condition and state names must contain only
alphanumeric characters and underscores, with no other punctuation or
special characters.
By convention, condition names are written in all caps, while state names
are in camel case. For example, the INFLUENZA
condition might have states
called Susceptible
, HighlyInfectious
, and Recovered
. While this
convention is not enforced, it is considered good pratice to maintain.
States
States define the meaning of a condition. Within the states of a condition, agents may perform any number of actions, and after spending a specified amount of time within the state, decide on upon its next state within the condition. Along these lines, there are three major categories of rules within states:
Action rules
Wait rules, and
Transition rules.
state blocks
Each state is defined by a state block that includes the rules associated with the state:
state <state_name> {
<action_rules>
<wait_rules>
<transition_rules>
}
rules
Actions, wait rules, and transition rules are described in detail in Chapters 10, 11, and 12 respectively. In this section, we provide a brief overview of the role rules play within states.
Note
Categories of rules are always executed in a fixed order: action rules, followed by wait rules, followed by transition rules.
Action rules answers the question: what happens to the agent or what does the agent do when it enters this state? For example, entering a state might change an agent’s susceptibility to a transmissible condition if the state contain the action rule:
INF.sus = 0.0
Wait rules control how long an agent stays in a given state, expressed in hours. For example, an agent might spend two days in a particular state via the following rule:
wait(48)
Transition rules control how an agent moves from one state to the next. For example, an agent may transition to a new state:
next(Infectious)
Together, the rules above may be combined to create a “latent” state in a
condition, INF
, representing an infectious disease:
state Latent {
INF.sus = 0.0
wait(48)
next(Infectious)
}
All rules can be qualified by one or more tests (i.e. predicates):
[ if (<test1> & <test2> & ... <testN>) then ] <action/wait/transition_rule>
The predicate within the brackets is optional; however, if a predicate is present, then the rest of the rule only applies if all the tests are true for a particular agent.
For example, a transition rule may be predicated on an agent’s sex:
if (sex == female) then next (Susceptible)
For convenience, FRED interprets an empty state block such as
state <state_name> { }
as
state <state_name> {
wait()
next()
}
This means that the given state has no actions, all agents wait indefinitely, and there are no transitions to other states. This configuration is common among terminal states.
rule execution order
FRED executes the rules within a state by first sorting them into the following categories:
Action rules
Wait rules
Transition rules
The rules are then processed in order, starting with action rules.
For example, in the state S
below:
state S {
wait(10)
if (age > 16) then next(Dropout)
join(Group)
}
the rules will be interpreted as:
state S {
join(Group)
wait(10)
if (age > 16) then next(Dropout)
default(Stay_in_School)
}
and will be executed in the order:
join(Group)
, an action rulewait(10)
, a wait ruleif (age > 16) then next(Dropout)
, a transition rule
Rules within the action and wait categories are executed in the order that they appear in the code. Transition rules are evaluated in a special way described in chapter 12.
the start_state
All ordinary agents begin in the indicated start_state
. You can set
start_state
to any state in the condition, but if start_state
is not
defined explicitly, the default value for start_state will be Excluded
.
One common pattern is for the start_state
to exclude agents for whom the
condition does not apply. For example, suppose a model includes a PREGNANCY
condition. This condition does not apply to males, so the model can include
rules in the Start
state to exclude male agents from the condition, as
shown below:
condition PREGNANCY {
start_state = Start
state Start {
wait(0)
if (sex == male) then next(Excluded)
default(S1)
}
state S1 {
...
}
...
}
Note
When individual agents are born in a simulation, they will begin in the
start_state
of each condition.
the Excluded
state
The Excluded
state is automatically included in every condition,
and cannot be redefined. Excluded
represents a “does not apply”
state. For example, if there is a condition called PREGNANCY
,
then the start_state
could include a rule that transitions all
males to Excluded
.
Ordinary agents, group agents, and the Meta agent all begin in the
Excluded
state by default. To override this default, specify a
state name in the meta_start_state
for the Meta agent, or
group_start_state
for admin agents:
meta_start_state = <some_state>
group_start_state = <some_other_state>
If new group agents are created (by creating a new site that has group agents),
the new group agent begins in the group_start_state
for each condition, or to
Excluded
if the condition has no group_start_state
.
The Excluded
state does not have any action rules and always assumes
wait()
, that is, an infinite wait time. The above implies that any
transition rules included in Excluded
will be ignored.
Warning
It is legal to transition from Excluded
to another state through the
set_state()
action or a send()
action.