Source code for verigym.abstraction.gym_utils.spaces

import math

import gymnasium.spaces
import numpy as np

__all__ = [
    "DummySpace",
    "is_bounded_space",
    "get_n_elements_of_space",
    "infty"
]

infty = math.inf

class DummySpace(gymnasium.spaces.Discrete):
    """
    This is a dummy class inherting from `gym.spaces.Discrete`.
    It is not a functioning space, but can be used for the (rare) cases where a space
    is need eventhough none can be provided (e.g. when testing).
    """
    
    def __init__(self):
        """
            This is a dummy class inherting from `gym.spaces.Space`.
            It is not a functioning space, but can be used for the (rare) cases where a spaces 
            is need
        """
        return super().__init__(n=1)


[docs] def is_bounded_space(space: gymnasium.spaces.Space) -> bool: """Return True if the space has finite (non-infinite) bounds, False otherwise. Parameters ---------- space: The gymnasium space to check. """ if isinstance(space, (gymnasium.spaces.Discrete, gymnasium.spaces.MultiBinary, gymnasium.spaces.MultiDiscrete)): return True if isinstance(space, gymnasium.spaces.Box): bounds_finite = bool(np.any(space.bounded_above) or np.any(space.bounded_below)) return True if bounds_finite else False if isinstance(space, gymnasium.spaces.Dict): return all(is_bounded_space(s) for s in space.spaces.values()) if isinstance(space, gymnasium.spaces.Tuple): return all(is_bounded_space(s) for s in space.spaces) if isinstance(space, gymnasium.spaces.OneOf): return all(is_bounded_space(s) for s in space.spaces) if isinstance(space, gymnasium.spaces.Text): # max_length is a required integer argument in this gymnasium version, # so Text is always bounded over a finite charset. return True # Graph and Sequence have variable structure/length → infinite # if we reach until here, we could not assure that we space is finite return False
[docs] def get_n_elements_of_space(space: gymnasium.spaces.Space) -> int | float: """ Returns the number of elements of a given `gym.Space`. Parameters ---------- space : gymnasium.spaces.Space The gym space. Returns ------- int | float Returns `int` if finite elements and `float('inf')` if infinite. """ if isinstance(space, (gymnasium.spaces.Discrete, DummySpace)): return int(space.n) if isinstance(space, gymnasium.spaces.MultiDiscrete): return np.prod(space.nvec) if isinstance(space, gymnasium.spaces.MultiBinary): return 2**np.prod(space.n) if isinstance(space, gymnasium.spaces.Box): return infty raise ValueError(f"Unsupported gym.Space type. It is not clear / not implemented on how to compute the number of elements in this space. {type(space) = }")