
    h-;                        S r SSKJr  SSKJr  SSKJrJr  SSKr	SSK
Jr  SSKrSSKJr  SSKJr  SS	KJr  SS
KJr   " S S\5      r " S S\\   5      rg)zzImplementation of a space that represents graph information where nodes and edges can be represented with euclidean space.    )annotations)Sequence)Any
NamedTupleN)NDArray)Box)Discrete)MultiDiscrete)Spacec                  8    \ rS rSr% SrS\S'   S\S'   S\S'   Srg	)
GraphInstance   a  A Graph space instance.

* nodes (np.ndarray): an (n x ...) sized array representing the features for n nodes, (...) must adhere to the shape of the node space.
* edges (Optional[np.ndarray]): an (m x ...) sized array representing the features for m edges, (...) must adhere to the shape of the edge space.
* edge_links (Optional[np.ndarray]): an (m x 2) sized array of ints representing the indices of the two nodes that each edge connects.
zNDArray[Any]nodeszNDArray[Any] | Noneedges
edge_links N)__name__
__module____qualname____firstlineno____doc____annotations____static_attributes__r       P/home/james-whalen/.local/lib/python3.13/site-packages/gymnasium/spaces/graph.pyr   r      s     ##r   r   c                     ^  \ rS rSrSr S     SU 4S jjjr\S 5       r      SS jr S   SU 4S jjjr	    S         SS jjr
SS jrSS	 jrSS
 jr    SS jr    SS jrSrU =r$ )Graph   aV  A space representing graph information as a series of ``nodes`` connected with ``edges`` according to an adjacency matrix represented as a series of ``edge_links``.

Example:
    >>> from gymnasium.spaces import Graph, Box, Discrete
    >>> observation_space = Graph(node_space=Box(low=-100, high=100, shape=(3,)), edge_space=Discrete(3), seed=123)
    >>> observation_space.sample(num_nodes=4, num_edges=8)
    GraphInstance(nodes=array([[ 36.47037 , -89.235794, -55.928024],
           [-63.125637, -64.81882 ,  62.4189  ],
           [ 84.669   , -44.68512 ,  63.950912],
           [ 77.97854 ,   2.594091, -51.00708 ]], dtype=float32), edges=array([2, 0, 2, 1, 2, 0, 2, 1]), edge_links=array([[3, 0],
           [0, 0],
           [0, 1],
           [0, 2],
           [1, 0],
           [1, 0],
           [0, 1],
           [0, 2]], dtype=int32))
c                   > [        U[        [        45      (       d   S[        U5       35       eUb.  [        U[        [        45      (       d   S[        U5       35       eXl        X l        [        TU ]  SSU5        g)a?  Constructor of :class:`Graph`.

The argument ``node_space`` specifies the base space that each node feature will use.
This argument must be either a Box or Discrete instance.

The argument ``edge_space`` specifies the base space that each edge feature will use.
This argument must be either a None, Box or Discrete instance.

Args:
    node_space (Union[Box, Discrete]): space of the node features.
    edge_space (Union[None, Box, Discrete]): space of the edge features.
    seed: Optionally, you can use this argument to seed the RNG that is used to sample from the space.
zEValues of the node_space should be instances of Box or Discrete, got NzJValues of the edge_space should be instances of None Box or Discrete, got )
isinstancer   r	   type
node_space
edge_spacesuper__init__)selfr"   r#   seed	__class__s       r   r%   Graph.__init__3   s    & h
 
 	fRSWXbScRde	f 
 !S(O  o[\`ak\l[mno  %$tT*r   c                    g)zDChecks whether this space can be flattened to a :class:`spaces.Box`.Fr   r&   s    r   is_np_flattenableGraph.is_np_flattenableS   s     r   c           	        US:X  d  Uc  g [        U[        5      (       a  [        [        R                  " [	        SU5      UR
                  /-  5      [        R                  " [	        SU5      UR                  /-  5      U4UR                  -   UR                  U R                  S9$ [        U[        5      (       a"  [        UR                  /U-  U R                  S9$ [        S[        U5       S35      e)Nr      )lowhighshapedtyper'   )nvecr'   z9Expects base space to be Box and Discrete, actual space: .)r    r   nparraymaxr0   r1   r2   r3   	np_randomr	   r
   n	TypeErrorr!   )r&   
base_spacenums      r   _generate_sample_spaceGraph._generate_sample_spaceX   s     !8z)j#&&HHSC[JNN+;;<XXc!SkZ__,==>fz/// &&^^  
H-- z||ns&:PPKDQ[L\K]]^_ r   c                  > Uc{  U R                   c*  [        TU ]	  S5      U R                  R                  S5      4$ [        TU ]	  S5      U R                  R                  S5      U R                   R                  S5      4$ [	        U[
        5      (       GaF  U R                   c  [        TU ]	  U5      n[        U R                  R                  [        R                  " [        R                  5      R                  5      5      n[        TU ]	  U5        X R                  R                  U5      4$ [        TU ]	  U5      nU R                  R                  [        R                  " [        R                  5      R                  SS9u  p4[        TU ]	  U5        UU R                  R                  [        U5      5      U R                   R                  [        U5      5      4$ [	        U[        [        45      (       a  U R                   cV  [        U5      S:w  a  [        S[        U5       35      e[        TU ]	  US   5      U R                  R                  US   5      4$ [        U5      S:w  a  [        S	[        U5       35      e[        TU ]	  US   5      U R                  R                  US   5      U R                   R                  US   5      4$ [!        S
[#        U5       35      e)a  Seeds the PRNG of this space and node / edge subspace.

Depending on the type of seed, the subspaces will be seeded differently

* ``None`` - The root, node and edge spaces PRNG are randomly initialized
* ``Int`` - The integer is used to seed the :class:`Graph` space that is used to generate seed values for the node and edge subspaces.
* ``Tuple[int, int]`` - Seeds the :class:`Graph` and node subspace with a particular value. Only if edge subspace isn't specified
* ``Tuple[int, int, int]`` - Seeds the :class:`Graph`, node and edge subspaces with a particular value.

Args:
    seed: An optional int or tuple of ints for this space and the node / edge subspaces. See above for more details.

Returns:
    A tuple of two or three ints depending on if the edge subspace is specified.
N)   )sizerA   zGExpects a tuple of two values for Graph and node space, actual length: r   r/      zOExpects a tuple of three values for Graph, node and edge space, actual length: z3Expects `None`, int or tuple of ints, actual type: )r#   r$   r'   r"   r    intr9   integersr6   iinfoint32r8   listtuplelen
ValueErrorr;   r!   )r&   r'   
super_seed	node_seed	edge_seedr(   s        r   r'   
Graph.seedm   sv   $ <&w|D)4??+?+?+EEE GL&OO((.OO((. 
 c""&"W\$/
 7 78J8N8N OP	T"!??#7#7	#BBB"W\$/
'+~~'>'>HHRXX&** (? ($	 T"OO((Y8OO((Y8 
 tUm,,&t9>$abefjbkalm  w|DG,doo.B.B47.KKKt9>$ijmnrjsitu 
 GLa)OO((a1OO((a1  Ed4j\R r   c                  ^ US:  d
   SU 35       eUb  Ub  [        SU SU 35      eUb  Uu  nmSnOUb  Uu  nmSnOS=n=mnUcK  US:  a!  U R                  R                  X3S-
  -  5      nOSnTb  [        U4S	 j[	        U5       5       5      mO@U R
                  c#  [        R                  R                  S
U S35        US:  d
   SU 35       eUc   eU R                  U R                  U5      nUc   eU R                  U R
                  U5      nUb  Xe0n	UT0n
O0 =pUR                  " S0 U	D6nSnUb  UR                  " S0 U
D6nSnUb1  US:  a+  U R                  R                  SX4S4[        R                  S9n[        XU5      $ )a  Generates a single sample graph with num_nodes between ``1`` and ``10`` sampled from the Graph.

Args:
    mask: An optional tuple of optional node and edge mask that is only possible with Discrete spaces
        (Box spaces don't support sample masks).
        If no ``num_edges`` is provided then the ``edge_mask`` is multiplied by the number of edges
    probability: An optional tuple of optional node and edge probability mask that is only possible with Discrete spaces
        (Box spaces don't support sample probability masks).
        If no ``num_edges`` is provided then the ``edge_mask`` is multiplied by the number of edges
    num_nodes: The number of nodes that will be sampled, the default is `10` nodes
    num_edges: An optional number of edges, otherwise, a random number between `0` and :math:`num_nodes^2`

Returns:
    A :class:`GraphInstance` with attributes `.nodes`, `.edges`, and `.edge_links`.
r   zDThe number of nodes is expected to be greater than 0, actual value: NzIOnly one of `mask` or `probability` can be provided, actual values: mask=z, probability=maskprobabilityr/   c              3  (   >#    U  H  nTv   M	     g 7fNr   ).0_edge_space_masks     r   	<genexpr>Graph.sample.<locals>.<genexpr>   s     'RAQAAQs   zThe number of edges is set (z) but the edge space is None.z@Expects the number of edges to be greater than 0, actual value: rA   )r0   r1   rB   r3   r   )rK   r9   rE   rI   ranger#   gymloggerwarnr>   r"   sampler6   rG   r   )r&   rQ   rR   	num_nodes	num_edgesnode_space_mask	mask_typesampled_node_spacesampled_edge_spacenode_sample_kwargsedge_sample_kwargssampled_nodessampled_edgessampled_edge_linksrW   s                 @r   r^   Graph.sample   s   B M	^QR[Q\]	^  7[\`[aaop{o|}  /3,O_I$/:,O_%I<@@O@o	 1} NN33IQ4OP		*"''RyAQ'R"R&

29+=Z[ Q^QR[Q\]^$$$!88)T!---!88)T "+!="+_!=688*11G4FG).55K8JKM!$Q!%!8!8IN"(( "9 " ];MNNr   c           	       ^  [        U[        5      (       Ga  [        UR                  [        R                  5      (       Ga  [        U 4S jUR                   5       5      (       Ga  [        UR                  [        R                  5      (       GaE  [        UR                  [        R                  5      (       Ga  UR                  c   eUR                  c   eT R                  b  [        U 4S jUR                   5       5      (       a  [        R                  " UR                  R                  [        R                  5      (       a  UR                  R                  [        UR                  5      S4:X  a^  [        R
                  " [        R                  " UR                  S:  UR                  [        UR                  5      :  5      5      (       a  ggUR                  SL =(       a    UR                  SL $ g)z?Return boolean specifying if x is a valid member of this space.c              3  @   >#    U  H  oTR                   ;   v   M     g 7frT   )r"   )rU   noder&   s     r   rX   !Graph.contains.<locals>.<genexpr>  s     C74t.7   Nc              3  @   >#    U  H  oTR                   ;   v   M     g 7frT   )r#   )rU   edger&   s     r   rX   rn     s     "Owt4??#:wro   rA   r   TF)r    r   r   r6   ndarrayallr   r   r#   
issubdtyper3   integerr2   rJ   logical_and)r&   xs   ` r   containsGraph.contains  sO   a''!''2::..C177CCC!!''2::66:bjj< <  !ww222 ||777??6""Oqww"OOO#%==1C1CRZZ#P#P'(||'9'9c!''lA=N'N+-66,.NN010A01s177|0K-.,* ,* 48   !ww$G1<<43GGr   c                <    SU R                    SU R                   S3$ )zA string representation of this space.

The representation will include ``node_space`` and ``edge_space``

Returns:
    A representation of the space
zGraph(z, ))r"   r#   r+   s    r   __repr__Graph.__repr__*  s#     (4??*;1==r   c                    [        U[        5      =(       a9    U R                  UR                  :H  =(       a    U R                  UR                  :H  $ )z5Check whether `other` is equivalent to this instance.)r    r   r"   r#   )r&   others     r   __eq__Graph.__eq__4  sA     ue$ 6E$4$446E$4$44	
r   c                   / nU H  nSUR                   R                  5       0nUR                  bG  UR                  b:  UR                  R                  5       US'   UR                  R                  5       US'   UR	                  U5        M     U$ )zCConvert a batch of samples from this space to a JSONable data type.r   r   r   )r   tolistr   r   append)r&   sample_nret_nr^   rets        r   to_jsonableGraph.to_jsonable<  s     FFLL//12C||'F,=,=,I%||224G$*$5$5$<$<$>L!LL  r   c           
        / nU H  nSU;   a  U R                   c   e[        [        R                  " US   U R                  R
                  S9[        R                  " US   U R                   R
                  S9[        R                  " US   [        R                  S95      nO7[        [        R                  " US   U R                  R
                  S9SS5      nUR                  U5        M     U$ )zCConvert a JSONable data type to a batch of samples from this space.r   Nr   )r3   r   )r#   r   r6   asarrayr"   r3   rG   r   )r&   r   r   r^   r   s        r   from_jsonableGraph.from_jsonableI  s     $&F& 222%JJvgdoo6K6KLJJvgdoo6K6KLJJvl3288D &JJvgdoo6K6KL
 JJu  
r   )r#   r"   rT   )r"   zBox | Discreter#   None | Box | Discreter'   z int | np.random.Generator | None)r<   r   r=   rD   returnzBox | MultiDiscrete | None)r'   z3int | tuple[int, int] | tuple[int, int, int] | Noner   z&tuple[int, int] | tuple[int, int, int])NN
   N)
rQ   ZNone | tuple[NDArray[Any] | tuple[Any, ...] | None, NDArray[Any] | tuple[Any, ...] | None]rR   r   r_   rD   r`   z
int | Noner   r   )rw   r   r   bool)r   str)r   r   r   r   )r   zSequence[GraphInstance]r   z"list[dict[str, list[int | float]]])r   z2Sequence[dict[str, list[list[int] | list[float]]]]r   zlist[GraphInstance])r   r   r   r   r   r%   propertyr,   r>   r'   r^   rx   r|   r   r   r   r   __classcell__)r(   s   @r   r   r      s   . 26	+"+ *+ /	+ +@  /69	#, KODGD	/D DZ   $ZO
ZO
ZO ZO ZO  
!ZOx6>
/	+J	 r   r   )r   
__future__r   collections.abcr   typingr   r   numpyr6   numpy.typingr   	gymnasiumr[   gymnasium.spaces.boxr   gymnasium.spaces.discreter	   gymnasium.spaces.multi_discreter
   gymnasium.spaces.spacer   r   r   r   r   r   <module>r      sH    A " $ "     $ . 9 (
$J 
$~E-  ~r   