# Condition¶

## Overview¶

Conditions are used to specify when Components are allowed to execute. Conditions can be used to specify a variety of required conditions for execution, including the state of the Component itself (e.g., how many times it has already executed, or the value of one of its attributes), the state of the Composition (e.g., how many TIME_STEP s have occurred in the current TRIAL), or the state of other Components in a Composition (e.g., whether or how many times they have executed). PsyNeuLink provides a number of pre-specified Conditions that can be parametrized (e.g., how many times a Component should be executed). Custom conditions can also be created, by assigning a function to a Condition that can reference any Component or its attributes in PsyNeuLink, thus providing considerable flexibility for scheduling.

Note

Any Component that is part of a collection specified to a Scheduler for execution can be associated with a Condition. Most commonly, these are Mechanisms. However, in some circumstances Projections can be included in the specification to a Scheduler (e.g., for learning) in which case these can also be assigned Conditions.

## Creating Conditions¶

### Pre-specified Conditions¶

Pre-specified Conditions can be instantiated and added to a Scheduler at any time, and take effect immediately for the execution of that Scheduler. Most pre-specified Conditions have one or more arguments that must be specified to achieve the desired behavior. Many Conditions are also associated with an owner attribute (a Components to which the Condition belongs), and a scheduler attribute (that maintains data used to test for satisfaction of the Condition). When pre-specified Conditions are instantiated within a call to the add method of a Scheduler or ConditionSet, the Condition’s owner and scheduler attributes are determined through context and assigned automatically, as in the following example:

my_scheduler.add_condition(A, EveryNPasses(1))


Here, EveryNCalls(A, 2) for example, is assigned the owner B, and the scheduler my_scheduler.

### Custom Conditions¶

Custom Conditions can be created by calling the constructor for the base class (Condition()) or one of the generic classes, and assigning a function to the func argument and any arguments it requires to the args and/or kwargs arguments (for formal or keyword arguments, respectively). The function is called with args and kwargs by the Scheduler on each PASS through its consideration_queue, and the result is used to determine whether the associated Component is allowed to execute on that PASS. Custom Conditions allow arbitrary schedules to be created, in which the execution of each Component can depend on one or more attributes of any other Components in the Composition.

For example, the following script fragment creates a custom Condition in which mech_A is scheduled to wait to execute until a RecurrentTransferMechanism mech_B has “converged” (that is, settled to the point that none of its elements has changed in value more than a specified amount since the previous TIME_STEP):

def converge(mech, thresh):
for val in mech.delta:
if abs(val) >= thresh:
return False
return True
epsilon = 0.01


In the example, a function converge is defined that references the delta attribute of a TransferMechanism (which reports the change in its value). The function is assigned to the standard Condition() with mech_A and epsilon as its arguments, and composite Condition NWhen (which is satisfied the first N times after its condition becomes true), The Condition is assigned to mech_B, thus scheduling it to execute one time when all of the elements of mech_A have changed by less than epsilon.

## Structure¶

The Scheduler associates every Component with a Condition. If a Component has not been explicitly assigned a Condition, it is assigned the Condition Always that causes it to be executed whenever it is under consideration. Condition subclasses (listed below) provide a standard set of Conditions that can be implemented simply by specifying their parameter(s). There are five types:

### List of Pre-specified Conditions¶

Note

The optional TimeScale argument in many Conditions specifies the unit of time over which the Condition operates; the default value is TRIAL for all Conditions except those with “Trial” in their name, for which it is RUN.

Generic Conditions (used to construct custom Conditions):

• While (func, *args, **kwargs) satisfied whenever the specified function (or callable) called with args and/or kwargs evaluates to True. Equivalent to Condition(func, *args, **kwargs)
• WhileNot (func, *args, **kwargs) satisfied whenever the specified function (or callable) called with args and/or kwargs evaluates to False. Equivalent to Not(Condition(func, *args, **kwargs))

Static Conditions (independent of other Conditions, Components or time):

Composite Conditions (based on one or more other Conditions):

• All (*Conditions) satisfied whenever all of the specified Conditions are satisfied.
• Any (*Conditions) satisfied whenever any of the specified Conditions are satisfied.
• Not (Condition) satisfied whenever the specified Condition is not satisfied.
• NWhen (Condition, int) satisfied the first specified number of times the specified Condition is satisfied.

Time-Based Conditions (based on the count of units of time at a specified TimeScale):

Component-Based Conditions (based on the execution or state of other Components):

## Execution¶

When the Scheduler runs, it makes a sequential PASS through its consideration_queue, evaluating each consideration_set in the queue to determine which Components should be assigned to execute. It evaluates the Components in each set by calling the is_satisfied method of the Condition associated with each of those Components. If it returns True, then the Component is assigned to the execution set for the TIME_STEP of execution generated by that PASS. Otherwise, the Component is not executed.

## Class Reference¶

class psyneulink.scheduling.condition.ConditionSet(scheduler=None, conditions=None)

Used in conjunction with a Scheduler to store the Conditions associated with a Components.

Parameters: scheduler (Scheduler) – specifies the Scheduler used to evaluate and maintain a record of the information required to evaluate the Conditions conditions (Dict[Component: Condition]) – specifies an iterable collection of Components and the Conditions associated with each.
scheduler

Scheduler – specifies the Scheduler used to evaluate and maintain a record of the information required to evaluate the Conditions

conditions

Dict[Component: Condition] – the key of each entry is a Component, and its value is the Condition associated with that Component. Conditions can be added to the ConditionSet using the ConditionSet’s add_condition method.

add_condition(owner, condition)

Add a Condition to the ConditionSet.

Parameters: owner (Component) – specifies the Component with which the condition should be associated. condition (Condition) – specifies the Condition, associated with the owner to be added to the ConditionSet.
add_condition_set(conditions)

Add a collection of Conditions to the ConditionSet.

Parameters: conditions (Dict[Component: Condition]) – specifies an iterable collection of Conditions to be added to the ConditionSet, in the form of a dict each entry of which maps a Components (the key) to a Condition (the value).
class psyneulink.scheduling.condition.Condition(func, *args, **kwargs)

Used in conjunction with a Scheduler to specify the condition under which a Components should be allowed to execute.

Parameters: func (callable) – specifies function to be called when the Condition is evaluated, to determine whether it is currently satisfied. args (*args) – specifies formal arguments to pass to func when the Condition is evaluated. kwargs (**kwargs) – specifies keyword arguments to pass to func when the Condition is evaluated.
scheduler

Scheduler – the Scheduler with which the Condition is associated; the Scheduler’s state is used to evaluate whether the Conditions specifications are satisfied.

owner(Component)

the Components with which the Condition is associated, and the execution of which it determines.

is_satisfied()

the function called to determine satisfaction of this Condition.

Returns: True - if the Condition is satisfied False - if the Condition is not satisfied
psyneulink.scheduling.condition.While

alias of Condition

class psyneulink.scheduling.condition.WhileNot(func, *args, **kwargs)
Parameters: func – callable specifies function to be called when the Condition is evaluated, to determine whether it is currently satisfied. args – *args specifies formal arguments to pass to func when the Condition is evaluated. kwargs – **kwargs specifies keyword arguments to pass to func when the Condition is evaluated.

Satisfied when:

• func is False
class psyneulink.scheduling.condition.Always
Parameters: none –

Satisfied when:

• always satisfied.
class psyneulink.scheduling.condition.Never
Parameters: none –

Satisfied when:

• never satisfied.
class psyneulink.scheduling.condition.All(*args)
Parameters: args – one or more Conditions

Satisfied when:

• all of the Conditions in args are satisfied.

Notes

• To initialize with a list (for example):

conditions = [AfterNCalls(mechanism, 5) for mechanism in mechanism_list]


unpack the list to supply its members as args:

composite_condition = All(*conditions)

class psyneulink.scheduling.condition.Any(*args)
Parameters: args – one or more Conditions

Satisfied when:

• one or more of the Conditions in args is satisfied.

Notes

• To initialize with a list (for example):

conditions = [AfterNCalls(mechanism, 5) for mechanism in mechanism_list]


unpack the list to supply its members as args:

composite_condition = All(*conditions)

class psyneulink.scheduling.condition.Not(condition)
Parameters: condition (Condition) – a Condition

Satisfied when:

• condition is not satisfied.
class psyneulink.scheduling.condition.NWhen(condition, n=1)
Parameters: condition (Condition) – a Condition n (int) – the maximum number of times this condition will be satisfied

Satisfied when:

• the first n times condition is satisfied upon evaluation
class psyneulink.scheduling.condition.BeforePass(n, time_scale=<TimeScale.TRIAL: 2>)
Parameters: n (int) – the ‘PASS’ before which the Condition is satisfied time_scale (TimeScale) – the TimeScale used as basis for counting PASSes (default: TimeScale.TRIAL)

Satisfied when:

• at most n-1 PASSes have occurred within one unit of time at the TimeScale specified by time_scale.

Notes

class psyneulink.scheduling.condition.AtPass(n, time_scale=<TimeScale.TRIAL: 2>)
Parameters: n (int) – the PASS at which the Condition is satisfied time_scale (TimeScale) – the TimeScale used as basis for counting PASSes (default: TimeScale.TRIAL)

Satisfied when:

• exactly n PASSes have occurred within one unit of time at the TimeScale specified by time_scale.

Notes

• Counts of TimeScales are zero-indexed (that is, the first ‘PASS’ is pass 0, the second ‘PASS’ is 1, etc.); so, AtPass(1) is satisfied when a single PASS (PASS 0) has occurred, and AtPass(2) is satisfied when two PASSes have occurred (PASS 0 and PASS 1), etc..
class psyneulink.scheduling.condition.AfterPass(n, time_scale=<TimeScale.TRIAL: 2>)
Parameters: n (int) – the PASS after which the Condition is satisfied time_scale (TimeScale) – the TimeScale used as basis for counting PASSes (default: TimeScale.TRIAL)

Satisfied when:

• at least n+1 PASSes have occurred within one unit of time at the TimeScale specified by time_scale.

Notes

class psyneulink.scheduling.condition.AfterNPasses(n, time_scale=<TimeScale.TRIAL: 2>)
Parameters: n (int) – the number of PASSes after which the Condition is satisfied time_scale (TimeScale) – the TimeScale used as basis for counting PASSes (default: TimeScale.TRIAL)

Satisfied when:

• at least n PASSes have occurred within one unit of time at the TimeScale specified by time_scale.
class psyneulink.scheduling.condition.EveryNPasses(n, time_scale=<TimeScale.TRIAL: 2>)
Parameters: n (int) – the frequency of passes with which this condition is satisfied time_scale (TimeScale) – the TimeScale used as basis for counting PASSes (default: TimeScale.TRIAL)

Satisfied when:

• PASS 0
• the specified number of PASSes that has occurred within a unit of time (at the TimeScale specified by time_scale) is evenly divisible by n.
class psyneulink.scheduling.condition.BeforeTrial(n, time_scale=<TimeScale.RUN: 3>)
Parameters: n (int) – the TRIAL before which the Condition is satisfied time_scale (TimeScale) – the TimeScale used as basis for counting TRIALs (default: TimeScale.RUN)

Satisfied when:

• at most n-1 TRIALs have occurred within one unit of time at the TimeScale specified by time_scale.

Notes

class psyneulink.scheduling.condition.AtTrial(n, time_scale=<TimeScale.RUN: 3>)
Parameters: n (int) – the TRIAL at which the Condition is satisfied time_scale (TimeScale) – the TimeScale used as basis for counting TRIALs (default: TimeScale.RUN)

Satisfied when:

• exactly n TRIALs have occurred within one unit of time at the TimeScale specified by time_scale.

Notes

class psyneulink.scheduling.condition.AfterTrial(n, time_scale=<TimeScale.RUN: 3>)
Parameters: n (int) – the TRIAL after which the Condition is satisfied time_scale (TimeScale) – the TimeScale used as basis for counting TRIALs. (default: TimeScale.RUN)

Satisfied when:

• at least n+1 TRIALs have occurred within one unit of time at the TimeScale specified by time_scale.

Notes

class psyneulink.scheduling.condition.AfterNTrials(n, time_scale=<TimeScale.RUN: 3>)
Parameters: n (int) – the number of TRIALs after which the Condition is satisfied time_scale (TimeScale) – the TimeScale used as basis for counting TRIALs (default: TimeScale.RUN)

Satisfied when:

• at least n TRIALs have occured  within one unit of time at the TimeScale specified by time_scale.
class psyneulink.scheduling.condition.BeforeNCalls(dependency, n, time_scale=<TimeScale.TRIAL: 2>)
Parameters: component (Component) – the Component on which the Condition depends n (int) – the number of executions of component before which the Condition is satisfied time_scale (TimeScale) – the TimeScale used as basis for counting executions of component (default – TimeScale.TRIAL)

Satisfied when:

• the Component specified in component has executed at most n-1 times within one unit of time at the TimeScale specified by time_scale.
class psyneulink.scheduling.condition.AtNCalls(dependency, n, time_scale=<TimeScale.TRIAL: 2>)
Parameters: component (Component) – the Component on which the Condition depends n (int) – the number of executions of component at which the Condition is satisfied time_scale (TimeScale) – the TimeScale used as basis for counting executions of component (default – TimeScale.TRIAL)

Satisfied when:

• the Component specified in component has executed exactly n times within one unit of time at the TimeScale specified by time_scale.
class psyneulink.scheduling.condition.AfterCall(dependency, n, time_scale=<TimeScale.TRIAL: 2>)
Parameters: component (Component) – the Component on which the Condition depends n (int) – the number of executions of component after which the Condition is satisfied time_scale (TimeScale) – the TimeScale used as basis for counting executions of component (default – TimeScale.TRIAL)

Satisfied when:

• the Component specified in component has executed at least n+1 times within one unit of time at the TimeScale specified by time_scale.
class psyneulink.scheduling.condition.AfterNCalls(dependency, n, time_scale=<TimeScale.TRIAL: 2>)
Parameters: component (Component) – the Component on which the Condition depends n (int) – the number of executions of component after which the Condition is satisfied time_scale (TimeScale) – the TimeScale used as basis for counting executions of component (default – TimeScale.TRIAL)

Satisfied when:

• the Component specified in component has executed at least n times within one unit of time at the TimeScale specified by time_scale.
class psyneulink.scheduling.condition.AfterNCallsCombined(*dependencies, n=None, time_scale=<TimeScale.TRIAL: 2>)
Parameters: *components (Components) – one or more Components on which the Condition depends n (int) – the number of combined executions of all Components specified in components after which the is satisfied (default (Condition) – None) time_scale (TimeScale) – the TimeScale used as basis for counting executions of component (default – TimeScale.TRIAL)

Satisfied when:

• there have been at least n+1 executions among all of the Components specified in components within one unit of time at the TimeScale specified by time_scale.
class psyneulink.scheduling.condition.EveryNCalls(dependency, n)
Parameters: component (Component) – the Component on which the Condition depends n (int) – the frequency of executions of component at which the Condition is satisfied

Satisfied when:

• the Component specified in component has executed at least n times since the last time the Condition’s owner executed.

Notes

• Scheduler’s count of each other Component that is “useable” by the Component is reset to 0.
class psyneulink.scheduling.condition.JustRan(dependency)
Parameters: component (Component) – the Component on which the Condition depends

Satisfied when:

Notes

class psyneulink.scheduling.condition.AllHaveRun(*dependencies, time_scale=<TimeScale.TRIAL: 2>)
Parameters: *components (Components) – an iterable of Components on which the Condition depends time_scale (TimeScale) – the TimeScale used as basis for counting executions of component (default – TimeScale.TRIAL)

Satisfied when:

• all of the Components specified in components have executed at least once within one unit of time at the TimeScale specified by time_scale.
class psyneulink.scheduling.condition.WhenFinished(dependency)
Parameters: component (Component) – the Component on which the Condition depends

Satisfied when:

Notes

• This is a dynamic Condition: Each Component is responsible for assigning its is_finished attribute on it own, which can occur independently of the execution of other Components. Therefore the satisfaction of this Condition) can vary arbitrarily in time.
class psyneulink.scheduling.condition.WhenFinishedAny(*dependencies)
Parameters: *components (Components) – zero or more Components on which the Condition depends

Satisfied when:

Notes

• This is a convenience class; WhenFinishedAny(A, B, C) is equivalent to Any(WhenFinished(A), WhenFinished(B), WhenFinished(C)). If no components are specified, the condition will default to checking all of its scheduler’s Components.
• This is a dynamic Condition: Each Component is responsible for assigning its is_finished attribute on it own, which can occur independently of the execution of other Components. Therefore the satisfaction of this Condition) can vary arbitrarily in time.
class psyneulink.scheduling.condition.WhenFinishedAll(*dependencies)
Parameters: *components (Components) – zero or more Components on which the Condition depends

Satisfied when:

Notes

• This is a convenience class; WhenFinishedAny(A, B, C) is equivalent to All(WhenFinished(A), WhenFinished(B), WhenFinished(C)). If no components are specified, the condition will default to checking all of its scheduler’s Components.
• This is a dynamic Condition: Each Component is responsible for assigning its is_finished attribute on it own, which can occur independently of the execution of other Components. Therefore the satisfaction of this Condition) can vary arbitrarily in time.