
    Ri                     h    d Z ddlmZ  G d de      Z G d de      Z G d d      Z G d	 d
      Zy)aN  Linked list functionality for use in Bio.Nexus.

Provides functionality of a linked list.
Each node has one (or none) predecessor, and an arbitrary number of successors.
Nodes can store arbitrary data in a NodeData class.

Subclassed by Nexus.Trees to store phylogenetic trees.

Bug reports to Frank Kauff (fkauff@biologie.uni-kl.de)
    )Optionalc                       e Zd ZdZy)ChainExceptionz1Provision for the management of Chain exceptions.N__name__
__module____qualname____doc__     G/home/agent/.friday_env/lib/python3.12/site-packages/Bio/Nexus/Nodes.pyr   r      s    ;r   r   c                       e Zd ZdZy)NodeExceptionz0Provision for the management of Node exceptions.Nr   r   r   r   r   r      s    :r   r   c                   v    e Zd ZdZddZdefdZdee   fdZdddd	edz  defd
Z	d Z
d Zd Zd Zd Zd Zy)Chainz0Stores a list of nodes that are linked together.returnNc                      i | _         d| _        y)zInitialize a node chain.N)chainidselfs    r   __init__zChain.__init__!   s    &(
r   c                 D    | xj                   dz  c_         | j                   S )z/Get a new id for a node in the chain (PRIVATE).   r   r   s    r   _get_idzChain._get_id&   s    1wwr   c                 H    t        | j                  j                               S )zReturn a list of all node ids.)listr   keysr   s    r   all_idszChain.all_ids+   s    DJJOO%&&r   nodeNodeprevc                    |%|| j                   vrt        dt        |      z         | j                         }|j	                  |       |j                  |       || j                   |   j                  |       || j                   |<   |S )zAttach node to another.zUnknown predecessor: )r   r   strr   set_idset_prevadd_succ)r   r"   r$   r   s       r   addz	Chain.add/   sy    DJJ 6 !83t9!DEEBKKOMM$

4 ))"-!DJJrN	r   c                    || j                   vrt        dt        |      z         | j                   |   j                         }| j                   |   j	                  |       | j                   |   j                         }|D ]   }| j                   |   j                  |       " | j                   |   j                  |       | j                   |   }| j                  |       |S )z=Delete node from chain and relinks successors to predecessor.Unknown ID: )	r   r   r&   get_prevremove_succget_succr(   r)   kill)r   r   prev_idsucc_idsir"   s         r   collapsezChain.collapse<   s    TZZ #b'!9::**R.))+

7''+::b>**, 	,AJJqM""7+	,

7$$X.zz"~		"r   c                 h    || j                   vrt        dt        |      z         | j                   |= y)z>Kill a node from chain without caring to what it is connected.r,   N)r   r   r&   r   r   s     r   r0   z
Chain.killJ   s-    TZZ #b'!9::

2r   c                 J   || j                   vrt        dt        |      z         | j                   |   j                  }|N| j                   |   j                  j                  | j                   |   j                  j                  |             d| j                   |   _        |S )z%Disconnect node from his predecessor.r,   N)r   r   r&   r$   succpopindex)r   r   r1   s      r   unlinkzChain.unlinkQ   s    TZZ #b'!9::jjn))G"

7#((,,TZZ-@-E-E-K-KB-OP"&DJJrNNr   c                 F   || j                   vrt        dt        |      z         || j                   vrt        dt        |      z         | j                  |       | j                   |   j                  j                  |       | j                   |   j                  |       y)zConnect son to parent.r,   N)r   r   r&   r;   r8   appendr(   )r   parentchilds      r   linkz
Chain.link\   s    

" #e*!<==4::% #f+!=>>KKJJv##**51JJu&&v.r   c                     ||k(  s|| j                   |   j                         v ry| j                   |   j                         D ]  }| j                  ||      s y y)z+Check if grandchild is a subnode of parent.TF)r   r/   is_parent_of)r   r>   
grandchildsns       r   rB   zChain.is_parent_ofg   s_    :F1C1L1L1N#Njj(113 $$R4 r   c                    || j                   vs|| j                   vrt        d      | j                  ||      r||k(  rg S | j                   |   j                         D ],  }| j                  ||      s|g| j	                  ||      z   c S  y)zQReturn a list of all node_ids between two nodes (excluding start, including end).zUnknown node.N)r   r   rB   r/   trace)r   startfinishrD   s       r   rF   zChain.tracer   s    

"fDJJ&>00  /5F?I**U#,,. 	5B  V,tdjjV444	5r   )r   NN)r   r   r	   r
   r   intr   r   r!   r*   r4   r0   r;   r@   rB   rF   r   r   r   r   r      sb    :
 
'c ' cDj C 		/	5r   r   c                   T    e Zd ZdZddZd Zd Zd Zd Zd Z	d	 Z
d
 Zd Zd Zd Zy)r#   zA single node.Nc                 <    d| _         || _        d| _        g | _        y)z>Represent a node with one predecessor and multiple successors.N)r   datar$   r8   r   rM   s     r   r   zNode.__init__   s    			r   c                 @    | j                   t        d      || _         y)z%Set the id of a node, if not set yet.NzNode id cannot be changed.)r   r   r6   s     r   r'   zNode.set_id   s    77 <==r   c                     | j                   S )zReturn the node's id.r   r   s    r   get_idzNode.get_id   s    wwr   c                     | j                   S )z'Return a list of the node's successors.)r8   r   s    r   r/   zNode.get_succ       yyr   c                     | j                   S )z(Return the id of the node's predecessor.r$   r   s    r   r-   zNode.get_prev   rS   r   c                     t        |t        g             r| j                  j                  |       y| j                  j	                  |       y)z'Add a node id to the node's successors.N)
isinstancetyper8   extendr=   r6   s     r   r)   zNode.add_succ   s4    b$r(#IIR IIR r   c                 :    | j                   j                  |       y)z,Remove a node id from the node's successors.N)r8   remover6   s     r   r.   zNode.remove_succ   s    		r   c                 R    t        |t        g             st        d      || _        y)zSet the node's successors.z$Node successor must be of list type.N)rW   rX   r   r8   )r   new_succs     r   set_succzNode.set_succ   s#    (DH- FGG	r   c                     || _         y)zSet the node's predecessor.NrU   r6   s     r   r(   zNode.set_prev   s	    	r   c                     | j                   S )zReturn a node's data.rM   r   s    r   get_datazNode.get_data   rS   r   c                     || _         y)zSet a node's data.Nra   rN   s     r   set_datazNode.set_data   s	    	r   rI   )r   r   r	   r
   r   r'   rQ   r/   r-   r)   r.   r^   r(   rb   rd   r   r   r   r#   r#   }   s<    !r   r#   N)r
   typingr   	Exceptionr   r   r   r#   r   r   r   <module>rg      s>   	 <Y <;I ;\5 \5~7 7r   