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:

  1. Action rules

  2. Wait rules, and

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

  1. Action rules

  2. Wait rules

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

  1. join(Group), an action rule

  2. wait(10), a wait rule

  3. if (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.