
:>"^                 @   sb   d  Z  Gd d   d e  Z Gd d   d e  Z Gd d   d e  Z Gd d   d e  Z d	 S)
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)
c               @   s   e  Z d  Z d Z d S)ChainExceptionz1Provision for the management of Chain exceptions.N)__name__
__module____qualname____doc__ r   r   4/tmp/pip-build-ww9dw3qa/biopython/Bio/Nexus/Nodes.pyr      s   r   c               @   s   e  Z d  Z d Z d S)NodeExceptionz0Provision for the management of Node exceptions.N)r   r   r   r   r   r   r   r   r      s   r   c               @   s   e  Z d  Z d Z d d   Z d d   Z d d   Z d d	 d
  Z d d   Z d d   Z	 d d   Z
 d d   Z d d   Z d d   Z d S)Chainz0Stores a list of nodes that are linked together.c             C   s   i  |  _  d |  _ d S)zInitialize a node chain.   N)chainid)selfr   r   r   __init__#   s    	zChain.__init__c             C   s   |  j  d 7_  |  j  S)z/Get a new id for a node in the chain (PRIVATE).r
   )r   )r   r   r   r   _get_id(   s    zChain._get_idc             C   s   t  |  j j    S)zReturn a list of all node ids.)listr   keys)r   r   r   r   all_ids-   s    zChain.all_idsNc             C   s   | d k	 r4 | |  j  k r4 t d t |    nS |  j   } | j |  | j |  | d k	 rz |  j  | j |  | |  j  | <| S)zAttach node to another.NzUnknown predecessor: )r   r   strr   set_idset_prevadd_succ)r   nodeprevr   r   r   r   add1   s    z	Chain.addc             C   s   | |  j  k r% t d t |    |  j  | j   } |  j  | j |  |  j  | j   } x" | D] } |  j  | j |  qf W|  j  | j |  |  j  | } |  j |  | S)z=Delete node from chain and relinks successors to predecessor.zUnknown ID: )	r   r   r   get_prevremove_succget_succr   r   kill)r   r   prev_idZsucc_idsir   r   r   r   collapse>   s    zChain.collapsec             C   s6   | |  j  k r( t d t |    n
 |  j  | =d S)z>Kill a node from chain without caring to what it is connected.zUnknown ID: N)r   r   r   )r   r   r   r   r   r   L   s    z
Chain.killc             C   s   | |  j  k r( t d t |    nZ |  j  | j } | d k	 rn |  j  | j j |  j  | j j |   d |  j  | _ | Sd S)z%Disconnect node from his predecessor.zUnknown ID: N)r   r   r   r   succpopindex)r   r   r   r   r   r   unlinkS   s    *zChain.unlinkc             C   s   | |  j  k r( t d t |    n` | |  j  k rP t d t |    n8 |  j |  |  j  | j j |  |  j  | j |  d S)zConnect son to parent.zUnknown ID: N)r   r   r   r%   r"   appendr   )r   parentchildr   r   r   link^   s    z
Chain.linkc             C   se   | | k s% | |  j  | j   k r) d Sx5 |  j  | j   D] } |  j | |  r= d Sq= Wd Sd S)z+Check if grandchild is a subnode of parent.TFN)r   r   is_parent_of)r   r'   Z
grandchildsnr   r   r   r*   i   s    %zChain.is_parent_ofc             C   s   | |  j  k s | |  j  k r* t d   |  j | |  sI | | k rM g  SxD |  j  | j   D]/ } |  j | |  ra | g |  j | |  Sqa Wd S)zQReturn a list of all node_ids between two nodes (excluding start, including end).zUnknown node.N)r   r   r*   r   trace)r   startfinishr+   r   r   r   r,   t   s    zChain.trace)r   r   r   r   r   r   r   r   r!   r   r%   r)   r*   r,   r   r   r   r   r	       s   r	   c               @   s   e  Z d  Z d Z d d d  Z d d   Z d d   Z d	 d
   Z d d   Z d d   Z	 d d   Z
 d d   Z d d   Z d d   Z d d   Z d S)NodezA single node.Nc             C   s(   d |  _  | |  _ d |  _ g  |  _ d S)z>Represent a node with one predecessor and multiple successors.N)r   datar   r"   )r   r0   r   r   r   r      s    			zNode.__init__c             C   s(   |  j  d k	 r t d   | |  _  d S)z%Set the id of a node, if not set yet.NzNode id cannot be changed.)r   r   )r   r   r   r   r   r      s    zNode.set_idc             C   s   |  j  S)zReturn the node's id.)r   )r   r   r   r   get_id   s    zNode.get_idc             C   s   |  j  S)z'Return a list of the node's successors.)r"   )r   r   r   r   r      s    zNode.get_succc             C   s   |  j  S)z(Return the id of the node's predecessor.)r   )r   r   r   r   r      s    zNode.get_prevc             C   s<   t  | t g    r( |  j j |  n |  j j |  d S)z'Add a node id to the node's successors.N)
isinstancetyper"   extendr&   )r   r   r   r   r   r      s    zNode.add_succc             C   s   |  j  j |  d S)z,Remove a node id from the node's successors.N)r"   remove)r   r   r   r   r   r      s    zNode.remove_succc             C   s.   t  | t g    s! t d   | |  _ d S)zSet the node's successors.z$Node successor must be of list type.N)r2   r3   r   r"   )r   Znew_succr   r   r   set_succ   s    zNode.set_succc             C   s   | |  _  d S)zSet the node's predecessor.N)r   )r   r   r   r   r   r      s    zNode.set_prevc             C   s   |  j  S)zReturn a node's data.)r0   )r   r   r   r   get_data   s    zNode.get_datac             C   s   | |  _  d S)zSet a node's data.N)r0   )r   r0   r   r   r   set_data   s    zNode.set_data)r   r   r   r   r   r   r1   r   r   r   r   r6   r   r7   r8   r   r   r   r   r/      s   r/   N)r   	Exceptionr   r   objectr	   r/   r   r   r   r   <module>   s   _