Skip to content

Reach-avoid Constraint

masa.common.constraints.reach_avoid.ReachAvoid

ReachAvoid(avoid_label: str, reach_label: str)

Bases: Constraint

Reach target label set while avoiding unsafe label set.

At each step, given a label set labels:

  • reaching condition: reach = (reach_label in labels)
  • avoiding condition: avoid_ok = (avoid_label not in labels)

State updates:

  • reached becomes true once reach is observed,
  • violated becomes true once avoid is violated,
  • satisfied becomes true once reached is true and violated is false.

Parameters:

Name Type Description Default
avoid_label str

Atomic proposition name indicating unsafe/avoid condition.

required
reach_label str

Atomic proposition name indicating the target condition.

required

Attributes:

Name Type Description
avoid_label

Name of unsafe label.

reach_label

Name of target label.

reached

Whether target has been reached at least once.

violated

Whether unsafe has been observed at least once.

satisfied

Whether reach-avoid has been satisfied so far.

Source code in masa/common/constraints/reach_avoid.py
def __init__(self, avoid_label: str, reach_label: str):
    self.avoid_label = avoid_label
    self.reach_label = reach_label

avoid_label instance-attribute

avoid_label = avoid_label

reach_label instance-attribute

reach_label = reach_label

constraint_type property

constraint_type: str

Stable identifier string: "REACH_AVOID".

reset

reset()

Reset episode flags.

Source code in masa/common/constraints/reach_avoid.py
def reset(self):
    """Reset episode flags."""
    self.reached = False
    self.violated = False
    self.satisfied = False

update

update(labels: Iterable[str])

Update reach/avoid flags from the current label set.

Parameters:

Name Type Description Default
labels Iterable[str]

Iterable of atomic propositions for the current step.

required
Source code in masa/common/constraints/reach_avoid.py
def update(self, labels: Iterable[str]):
    """Update reach/avoid flags from the current label set.

    Args:
        labels: Iterable of atomic propositions for the current step.
    """
    self.reach = self.reach_label in labels
    self.avoid = self.avoid_label not in labels

    self.reached = self.reached or self.reach
    self.violated = self.violated or bool(not self.avoid)

    self.satisfied = self.satisfied or (self.reached and bool(not self.violated))

episode_metric

episode_metric() -> Dict[str, float]

End-of-episode metrics.

Returns:

Type Description
Dict[str, float]

Dict containing:

Dict[str, float]
  • "reached": whether the target was ever reached,
Dict[str, float]
  • "violated": whether unsafe was ever visited,
Dict[str, float]
  • "satisfied": 1.0 if satisfied else 0.0.
Source code in masa/common/constraints/reach_avoid.py
def episode_metric(self) -> Dict[str, float]:
    """End-of-episode metrics.

    Returns:
        Dict containing:

        - ``"reached"``: whether the target was ever reached,
        - ``"violated"``: whether unsafe was ever visited,
        - ``"satisfied"``: 1.0 if satisfied else 0.0.
    """
    return {"reached": self.reached, "violated": self.violated, "satisfied": float(self.satisfied)}

step_metric

step_metric() -> Dict[str, float]

Per-step metrics.

Returns:

Type Description
Dict[str, float]

Dict containing:

Dict[str, float]
  • "cost": 1.0 if avoid is violated at this step else 0.0,
Dict[str, float]
  • "violation": 1.0 if avoid violated else 0.0,
Dict[str, float]
  • "reached": 1.0 if reach holds at this step else 0.0.
Source code in masa/common/constraints/reach_avoid.py
def step_metric(self) -> Dict[str, float]:
    """Per-step metrics.

    Returns:
        Dict containing:

        - ``"cost"``: 1.0 if avoid is violated at this step else 0.0,
        - ``"violation"``: 1.0 if avoid violated else 0.0,
        - ``"reached"``: 1.0 if reach holds at this step else 0.0.
    """
    return {"cost": float(not self.avoid), "violation": bool(not self.avoid), "reached": self.reach, "cost_done": bool(not self.avoid or self.reach)}

masa.common.constraints.reach_avoid.ReachAvoidEnv

ReachAvoidEnv(env: Env, avoid_label: str = 'unsafe', reach_label: str = 'target', **kw)

Bases: BaseConstraintEnv

Gymnasium wrapper for the ReachAvoid monitor.

Parameters:

Name Type Description Default
env Env

Base environment (must be a LabelledEnv).

required
avoid_label str

Atomic proposition name for unsafe/avoid condition.

'unsafe'
reach_label str

Atomic proposition name for target condition.

'target'
**kw

Extra keyword arguments forwarded to BaseConstraintEnv.

{}
Source code in masa/common/constraints/reach_avoid.py
def __init__(self, env: gym.Env, avoid_label: str = "unsafe", reach_label: str = "target", **kw):
    super().__init__(env, ReachAvoid(avoid_label=avoid_label, reach_label=reach_label), **kw)