States module¶
¶
AdaptiveProbabilisticState
¶
Special probabilistic state that allows modifaction of weights.
modifiers: List[float]
property
readonly
¶
The weight modifiers assigned to the transitions.
name: str
inherited
property
readonly
¶
The name (including the prefix) of the state instance
Names must be unique within a state machine.
name_only: str
inherited
property
readonly
¶
The name of the state instance (names must be uniq within a state machine).
name_prefix: Optional[str]
inherited
property
readonly
¶
The name prefix of the state instance.
probabilities: List[float]
property
readonly
¶
The propabilities based on the weights and modifiers
transitions: List[cr_kyoushi.simulation.transitions.Transition]
inherited
property
readonly
¶
List of all possible transitions
originating from this state
transitions_map: Dict[str, cr_kyoushi.simulation.transitions.Transition]
inherited
property
readonly
¶
List of all possible transitions
originating from this state
weights: Sequence[float]
inherited
property
readonly
¶
The weight assigned to the transitions.
__init__(self, name, transitions, weights, modifiers=None, name_prefix=None)
special
¶
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name |
str |
The name of the state |
required |
transitions |
List[cr_kyoushi.simulation.transitions.Transition] |
The list of transitions |
required |
weights |
Sequence[float] |
The list of weights to assign to the transitions in propability notation |
required |
modifiers |
Optional[Sequence[float]] |
List of multiplicative modifiers for each weight. Will default to all 1 if not set. |
None |
name_prefix |
Optional[str] |
A prefix for the state name |
None |
Source code in simulation/states.py
def __init__(
self,
name: str,
transitions: List[Transition],
weights: Sequence[float],
modifiers: Optional[Sequence[float]] = None,
name_prefix: Optional[str] = None,
):
"""
Args:
name: The name of the state
transitions: The list of transitions
weights: The list of weights to assign to the transitions in propability notation
modifiers: List of multiplicative modifiers for each weight.
Will default to all 1 if not set.
name_prefix: A prefix for the state name
"""
super().__init__(name, transitions, weights, name_prefix)
if modifiers is None:
modifiers = [1.0] * len(self.weights)
self._modifiers = dict(zip(transitions, list(modifiers)))
self.__modifiers_org: Tuple[float, ...] = tuple(self.modifiers)
adapt_after(self, log, context, selected)
¶
Hook to update the weight modifiers after the transition selection.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
log |
BoundLogger |
The logger for the sm context |
required |
context |
Union[pydantic.main.BaseModel, Dict[str, Any]] |
The state machine context |
required |
selected |
Optional[cr_kyoushi.simulation.transitions.Transition] |
The transition selected in this next call |
required |
Source code in simulation/states.py
def adapt_after(
self,
log: BoundLogger,
context: Context,
selected: Optional[Transition],
):
"""Hook to update the weight modifiers after the transition selection.
Args:
log: The logger for the sm context
context: The state machine context
selected: The transition selected in this next call
"""
adapt_before(self, log, context)
¶
Hook to update the weight modifiers before the transition selection.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
log |
BoundLogger |
The logger for the sm context |
required |
context |
Union[pydantic.main.BaseModel, Dict[str, Any]] |
The state machine context |
required |
Source code in simulation/states.py
def adapt_before(self, log: BoundLogger, context: Context):
"""Hook to update the weight modifiers before the transition selection.
Args:
log: The logger for the sm context
context: The state machine context
"""
next(self, log, context)
¶
Selects the next state transition.
The selection logic depends on the state implementation. It might
rely on the state machine context
and/or execution environment information to select transitions based on complex conditions.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
log |
BoundLogger |
The bound logger initialized with transition specific information |
required |
context |
Union[pydantic.main.BaseModel, Dict[str, Any]] |
State machine context which can be used for complex selection logic |
required |
Returns:
Type | Description |
---|---|
Optional[cr_kyoushi.simulation.transitions.Transition] |
The selected |
Source code in simulation/states.py
def next(self, log: BoundLogger, context: Context) -> Optional[Transition]:
if len(self.transitions) > 0:
self.adapt_before(log, context)
selected = np.random.choice(
a=np.array(self.transitions), p=self.probabilities
)
self.adapt_after(log, context, selected)
return selected
return None
reset(self)
¶
Resets the modifiers to their original state
Source code in simulation/states.py
def reset(self):
"""Resets the modifiers to their original state"""
self._modifiers = dict(zip(self.transitions, self.__modifiers_org))
ChoiceState
¶
Simple boolean choice state decides between two transitions
name: str
inherited
property
readonly
¶
The name (including the prefix) of the state instance
Names must be unique within a state machine.
name_only: str
inherited
property
readonly
¶
The name of the state instance (names must be uniq within a state machine).
name_prefix: Optional[str]
inherited
property
readonly
¶
The name prefix of the state instance.
no: Transition
property
readonly
¶
The transition that is returned when the decision function returns False
transitions: List[cr_kyoushi.simulation.transitions.Transition]
inherited
property
readonly
¶
List of all possible transitions
originating from this state
transitions_map: Dict[str, cr_kyoushi.simulation.transitions.Transition]
inherited
property
readonly
¶
List of all possible transitions
originating from this state
yes: Transition
property
readonly
¶
The transition that is returned when the decision function returns True
__init__(self, name, decision_function, yes, no, name_prefix=None)
special
¶
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name |
str |
The state name |
required |
decision_function |
Callable[[structlog.stdlib.BoundLogger, Union[pydantic.main.BaseModel, Dict[str, Any]]], bool] |
Context function that decides a yes/no question. |
required |
yes |
Transition |
The transition to return when the decision function returns |
required |
no |
Transition |
The transition to return when the decision function returns |
required |
name_prefix |
Optional[str] |
A prefix for the state name |
None |
Source code in simulation/states.py
def __init__(
self,
name: str,
decision_function: Callable[[BoundLogger, Context], bool],
yes: Transition,
no: Transition,
name_prefix: Optional[str] = None,
):
"""
Args:
name: The state name
decision_function: Context function that decides a yes/no question.
yes: The transition to return when the decision function returns `True`
no: The transition to return when the decision function returns `False`
name_prefix: A prefix for the state name
"""
super().__init__(name, [yes, no], name_prefix)
self.__decision_function: Callable[
[BoundLogger, Context], bool
] = decision_function
next(self, log, context)
¶
Selects the next state transition.
The selection logic depends on the state implementation. It might
rely on the state machine context
and/or execution environment information to select transitions based on complex conditions.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
log |
BoundLogger |
The bound logger initialized with transition specific information |
required |
context |
Union[pydantic.main.BaseModel, Dict[str, Any]] |
State machine context which can be used for complex selection logic |
required |
Returns:
Type | Description |
---|---|
Optional[cr_kyoushi.simulation.transitions.Transition] |
The selected |
Source code in simulation/states.py
def next(self, log: BoundLogger, context: Context) -> Optional[Transition]:
return self.yes if self.__decision_function(log, context) else self.no
EquallyRandomState
¶
Special type of probabilistic state using an equal random distribution for all transitions
name: str
inherited
property
readonly
¶
The name (including the prefix) of the state instance
Names must be unique within a state machine.
name_only: str
inherited
property
readonly
¶
The name of the state instance (names must be uniq within a state machine).
name_prefix: Optional[str]
inherited
property
readonly
¶
The name prefix of the state instance.
transitions: List[cr_kyoushi.simulation.transitions.Transition]
inherited
property
readonly
¶
List of all possible transitions
originating from this state
transitions_map: Dict[str, cr_kyoushi.simulation.transitions.Transition]
inherited
property
readonly
¶
List of all possible transitions
originating from this state
weights: Sequence[float]
inherited
property
readonly
¶
The weight assigned to the transitions.
__init__(self, name, transitions, name_prefix=None)
special
¶
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name |
str |
The state name |
required |
transitions |
List[cr_kyoushi.simulation.transitions.Transition] |
The list of transitions |
required |
name_prefix |
Optional[str] |
A prefix for the state name |
None |
Exceptions:
Type | Description |
---|---|
ValueError |
If there are transitions with duplicate names |
Source code in simulation/states.py
def __init__(
self,
name: str,
transitions: List[Transition],
name_prefix: Optional[str] = None,
):
"""
Args:
name: The state name
transitions: The list of transitions
name_prefix: A prefix for the state name
Raises:
ValueError: If there are transitions with duplicate names
"""
# create even random distribution
probability = 1.0 / len(transitions)
weights = [probability for i in range(0, len(transitions))]
# initialize using super
super().__init__(name, transitions, weights, name_prefix)
next(self, log, context)
inherited
¶
Selects the next state transition.
The selection logic depends on the state implementation. It might
rely on the state machine context
and/or execution environment information to select transitions based on complex conditions.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
log |
BoundLogger |
The bound logger initialized with transition specific information |
required |
context |
Union[pydantic.main.BaseModel, Dict[str, Any]] |
State machine context which can be used for complex selection logic |
required |
Returns:
Type | Description |
---|---|
Optional[cr_kyoushi.simulation.transitions.Transition] |
The selected |
Source code in simulation/states.py
def next(self, log: BoundLogger, context: Context) -> Optional[Transition]:
if len(self.transitions) > 0:
return np.random.choice(a=np.array(self.transitions), p=self.weights)
return None
FinalState
¶
State with not further transitions which can be used as final state of a state machine
name: str
inherited
property
readonly
¶
The name (including the prefix) of the state instance
Names must be unique within a state machine.
name_only: str
inherited
property
readonly
¶
The name of the state instance (names must be uniq within a state machine).
name_prefix: Optional[str]
inherited
property
readonly
¶
The name prefix of the state instance.
transitions: List[cr_kyoushi.simulation.transitions.Transition]
inherited
property
readonly
¶
List of all possible transitions
originating from this state
transitions_map: Dict[str, cr_kyoushi.simulation.transitions.Transition]
inherited
property
readonly
¶
List of all possible transitions
originating from this state
__init__(self, name, name_prefix=None)
special
¶
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name |
str |
The state name |
required |
name_prefix |
Optional[str] |
A prefix for the state name |
None |
Source code in simulation/states.py
def __init__(self, name: str, name_prefix: Optional[str] = None):
"""
Args:
name: The state name
name_prefix: A prefix for the state name
"""
super().__init__(name, [], name_prefix)
next(self, log, context)
¶
Selects the next state transition.
The selection logic depends on the state implementation. It might
rely on the state machine context
and/or execution environment information to select transitions based on complex conditions.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
log |
BoundLogger |
The bound logger initialized with transition specific information |
required |
context |
Union[pydantic.main.BaseModel, Dict[str, Any]] |
State machine context which can be used for complex selection logic |
required |
Returns:
Type | Description |
---|---|
Optional[cr_kyoushi.simulation.transitions.Transition] |
The selected |
Source code in simulation/states.py
def next(self, log: BoundLogger, context: Context) -> Optional[Transition]:
return None
ProbabilisticState
¶
A state that uses a propability table to select its successor
name: str
inherited
property
readonly
¶
The name (including the prefix) of the state instance
Names must be unique within a state machine.
name_only: str
inherited
property
readonly
¶
The name of the state instance (names must be uniq within a state machine).
name_prefix: Optional[str]
inherited
property
readonly
¶
The name prefix of the state instance.
transitions: List[cr_kyoushi.simulation.transitions.Transition]
inherited
property
readonly
¶
List of all possible transitions
originating from this state
transitions_map: Dict[str, cr_kyoushi.simulation.transitions.Transition]
inherited
property
readonly
¶
List of all possible transitions
originating from this state
weights: Sequence[float]
property
readonly
¶
The weight assigned to the transitions.
__init__(self, name, transitions, weights, name_prefix=None)
special
¶
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name |
str |
The state name |
required |
transitions |
List[cr_kyoushi.simulation.transitions.Transition] |
The list of transitions |
required |
weights |
Sequence[float] |
The list of weights to assign to the transitions in probability notation. |
required |
name_prefix |
Optional[str] |
A prefix for the state name |
None |
Exceptions:
Type | Description |
---|---|
ValueError |
If there are transitions with duplicate names |
ValueError |
If the weights and transitions list lengths do not match |
ValueError |
If the given weights do not sum up to 1 |
Source code in simulation/states.py
def __init__(
self,
name: str,
transitions: List[Transition],
weights: Sequence[float],
name_prefix: Optional[str] = None,
):
"""
Args:
name: The state name
transitions: The list of transitions
weights: The list of weights to assign to the transitions in probability notation.
name_prefix: A prefix for the state name
Raises:
ValueError: If there are transitions with duplicate names
ValueError: If the weights and transitions list lengths do not match
ValueError: If the given weights do not sum up to 1
"""
# initial base properties
super().__init__(name, transitions, name_prefix)
# convert weights to cumulative weights
self.__weights = weights
# verify that given weights and transitions are sound
self.__verify_weights()
next(self, log, context)
¶
Selects the next state transition.
The selection logic depends on the state implementation. It might
rely on the state machine context
and/or execution environment information to select transitions based on complex conditions.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
log |
BoundLogger |
The bound logger initialized with transition specific information |
required |
context |
Union[pydantic.main.BaseModel, Dict[str, Any]] |
State machine context which can be used for complex selection logic |
required |
Returns:
Type | Description |
---|---|
Optional[cr_kyoushi.simulation.transitions.Transition] |
The selected |
Source code in simulation/states.py
def next(self, log: BoundLogger, context: Context) -> Optional[Transition]:
if len(self.transitions) > 0:
return np.random.choice(a=np.array(self.transitions), p=self.weights)
return None
RoundRobinState
¶
name: str
inherited
property
readonly
¶
The name (including the prefix) of the state instance
Names must be unique within a state machine.
name_only: str
inherited
property
readonly
¶
The name of the state instance (names must be uniq within a state machine).
name_prefix: Optional[str]
inherited
property
readonly
¶
The name prefix of the state instance.
transitions: List[cr_kyoushi.simulation.transitions.Transition]
inherited
property
readonly
¶
List of all possible transitions
originating from this state
transitions_map: Dict[str, cr_kyoushi.simulation.transitions.Transition]
inherited
property
readonly
¶
List of all possible transitions
originating from this state
__init__(self, name, transitions, name_prefix=None)
special
¶
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name |
str |
The state name |
required |
transitions |
List[cr_kyoushi.simulation.transitions.Transition] |
List of transitions to cycle through |
required |
name_prefix |
Optional[str] |
A prefix for the state name |
None |
Exceptions:
Type | Description |
---|---|
ValueError |
If there are transitions with duplicate names |
Source code in simulation/states.py
def __init__(
self,
name: str,
transitions: List[Transition],
name_prefix: Optional[str] = None,
):
"""
Args:
name (str): The state name
transitions (List[Transition]): List of transitions to cycle through
name_prefix: A prefix for the state name
Raises:
ValueError: If there are transitions with duplicate names
"""
super().__init__(name, transitions, name_prefix)
self.transition_cycle = cycle(transitions)
next(self, log, context)
¶
Selects the next state transition.
The selection logic depends on the state implementation. It might
rely on the state machine context
and/or execution environment information to select transitions based on complex conditions.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
log |
BoundLogger |
The bound logger initialized with transition specific information |
required |
context |
Union[pydantic.main.BaseModel, Dict[str, Any]] |
State machine context which can be used for complex selection logic |
required |
Returns:
Type | Description |
---|---|
Optional[cr_kyoushi.simulation.transitions.Transition] |
The selected |
Source code in simulation/states.py
def next(self, log: BoundLogger, context: Context) -> Optional[Transition]:
try:
return next(self.transition_cycle)
except StopIteration:
return None
SequentialState
¶
Simple sequential state only having one possible transition
name: str
inherited
property
readonly
¶
The name (including the prefix) of the state instance
Names must be unique within a state machine.
name_only: str
inherited
property
readonly
¶
The name of the state instance (names must be uniq within a state machine).
name_prefix: Optional[str]
inherited
property
readonly
¶
The name prefix of the state instance.
transitions: List[cr_kyoushi.simulation.transitions.Transition]
inherited
property
readonly
¶
List of all possible transitions
originating from this state
transitions_map: Dict[str, cr_kyoushi.simulation.transitions.Transition]
inherited
property
readonly
¶
List of all possible transitions
originating from this state
__init__(self, name, transition, name_prefix=None)
special
¶
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name |
str |
The state name |
required |
transition |
Transition |
The target transition |
required |
name_prefix |
Optional[str] |
A prefix for the state name |
None |
Exceptions:
Type | Description |
---|---|
ValueError |
If transition is None |
Source code in simulation/states.py
def __init__(
self,
name: str,
transition: Transition,
name_prefix: Optional[str] = None,
):
"""
Args:
name: The state name
transition: The target transition
name_prefix: A prefix for the state name
Raises:
ValueError: If transition is None
"""
if transition is None:
raise ValueError("Transition must not be None")
super().__init__(name, [transition], name_prefix)
self.__transition = transition
next(self, log, context)
¶
Selects the next state transition.
The selection logic depends on the state implementation. It might
rely on the state machine context
and/or execution environment information to select transitions based on complex conditions.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
log |
BoundLogger |
The bound logger initialized with transition specific information |
required |
context |
Union[pydantic.main.BaseModel, Dict[str, Any]] |
State machine context which can be used for complex selection logic |
required |
Returns:
Type | Description |
---|---|
Optional[cr_kyoushi.simulation.transitions.Transition] |
The selected |
Source code in simulation/states.py
def next(self, log: BoundLogger, context: Context) -> Optional[Transition]:
return self.__transition
State
¶
A State contains various transitions to other states
name: str
property
readonly
¶
The name (including the prefix) of the state instance
Names must be unique within a state machine.
name_only: str
property
readonly
¶
The name of the state instance (names must be uniq within a state machine).
name_prefix: Optional[str]
property
readonly
¶
The name prefix of the state instance.
transitions: List[cr_kyoushi.simulation.transitions.Transition]
property
readonly
¶
List of all possible transitions
originating from this state
transitions_map: Dict[str, cr_kyoushi.simulation.transitions.Transition]
property
readonly
¶
List of all possible transitions
originating from this state
__init__(self, name, transitions, name_prefix=None)
special
¶
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name |
str |
The state name |
required |
transitions |
List[cr_kyoushi.simulation.transitions.Transition] |
List of possible transitions |
required |
name_prefix |
Optional[str] |
A prefix for the state name |
None |
Exceptions:
Type | Description |
---|---|
ValueError |
If there are transitions with duplicate names |
Source code in simulation/states.py
def __init__(
self,
name: str,
transitions: List[Transition],
name_prefix: Optional[str] = None,
):
"""
Args:
name: The state name
transitions: List of possible transitions
name_prefix: A prefix for the state name
Raises:
ValueError: If there are transitions with duplicate names
"""
self._name = name
self._transitions = {t.name: t for t in transitions}
self._name_prefix: Optional[str] = name_prefix
if len(self._transitions) < len(transitions):
raise ValueError("Transition names must be unique")
next(self, log, context)
¶
Selects the next state transition.
The selection logic depends on the state implementation. It might
rely on the state machine context
and/or execution environment information to select transitions based on complex conditions.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
log |
BoundLogger |
The bound logger initialized with transition specific information |
required |
context |
Union[pydantic.main.BaseModel, Dict[str, Any]] |
State machine context which can be used for complex selection logic |
required |
Returns:
Type | Description |
---|---|
Optional[cr_kyoushi.simulation.transitions.Transition] |
The selected |
Source code in simulation/states.py
@abstractmethod
def next(self, log: BoundLogger, context: Context) -> Optional[Transition]:
"""Selects the next state transition.
The selection logic depends on the state implementation. It might
rely on the [`state machine context`][cr_kyoushi.simulation.sm.Statemachine.context]
and/or execution environment information to select transitions based on complex conditions.
Args:
log: The bound logger initialized with transition specific information
context (Context): State machine context which can be used for complex selection logic
Returns:
The selected [`Transition`][cr_kyoushi.simulation.transitions.Transition]
or None if no transition is available.
"""
...