
    gJX                         d dl Z d dlmZmZ d dlmZ d dlmZ  G d dee      Z G d d	e      Z	 G d
 de      Z
d	dgZy)    N)ABCMetaabstractmethod)Tree)slice_boundsc                        e Zd ZdZd fd	Zedd       Zed        Z fdZ fdZ	 fdZ
 fdZ fd	Zd fd
	Z fdZ eed      r	d Zd Zd Zd Z xZS )AbstractParentedTreea  
    An abstract base class for a ``Tree`` that automatically maintains
    pointers to parent nodes.  These parent pointers are updated
    whenever any change is made to a tree's structure.  Two subclasses
    are currently defined:

      - ``ParentedTree`` is used for tree structures where each subtree
        has at most one parent.  This class should be used in cases
        where there is no"sharing" of subtrees.

      - ``MultiParentedTree`` is used for tree structures where a
        subtree may have zero or more parents.  This class should be
        used in cases where subtrees may be shared.

    Subclassing
    ===========
    The ``AbstractParentedTree`` class redefines all operations that
    modify a tree's structure to call two methods, which are used by
    subclasses to update parent information:

      - ``_setparent()`` is called whenever a new child is added.
      - ``_delparent()`` is called whenever a child is removed.
    c                    t         |   ||       |ot        |       D ]*  \  }}t        |t              s| j                  ||d       , t        |       D ](  \  }}t        |t              s| j                  ||       * y y )NTdry_run)super__init__	enumerate
isinstancer   
_setparentselfnodechildrenichild	__class__s        G/var/www/openai/venv/lib/python3.12/site-packages/nltk/tree/parented.pyr   zAbstractParentedTree.__init__.   s{    x(  &dO5eT*OOE1dO; , &dO5eT*OOE1- ,      c                      y)a  
        Update the parent pointer of ``child`` to point to ``self``.  This
        method is only called if the type of ``child`` is ``Tree``;
        i.e., it is not called when adding a leaf to a tree.  This method
        is always called before the child is actually added to the
        child list of ``self``.

        :type child: Tree
        :type index: int
        :param index: The index of ``child`` in ``self``.
        :raise TypeError: If ``child`` is a tree with an impropriate
            type.  Typically, if ``child`` is a tree, then its type needs
            to match the type of ``self``.  This prevents mixing of
            different tree types (single-parented, multi-parented, and
            non-parented).
        :param dry_run: If true, the don't actually set the child's
            parent pointer; just check for any error conditions, and
            raise an exception if one is found.
        N r   r   indexr   s       r   r   zAbstractParentedTree._setparent@       r   c                      y)a  
        Update the parent pointer of ``child`` to not point to self.  This
        method is only called if the type of ``child`` is ``Tree``; i.e., it
        is not called when removing a leaf from a tree.  This method
        is always called before the child is actually removed from the
        child list of ``self``.

        :type child: Tree
        :type index: int
        :param index: The index of ``child`` in ``self``.
        Nr   r   r   r   s      r   
_delparentzAbstractParentedTree._delparentV   r   r   c                    t        |t              r]t        | |d      \  }}}t        |||      D ]+  }t        | |   t              s| j                  | |   |       - t        |   |       y t        |t              r[|dk  r|t        |       z  }|dk  rt        d      t        | |   t              r| j                  | |   |       t        |   |       y t        |t        t        f      r;t        |      dk(  rt        d      t        |      dk(  r| |d   = y | |d      |dd  = y t        t        |       j                  dt        |      j                        )NT
allow_stepr   index out of rangez(The tree position () may not be deleted.    indices must be integers, not )r   slicer   ranger   r!   r   __delitem__intlen
IndexErrorlisttuple	TypeErrortype__name__)r   r   startstopstepr   r   s         r   r*   z AbstractParentedTree.__delitem__j   sE   eU# ,T5T JE45$-d1gt,OODGQ/ . G& s#qyT"qy !566$u+t,UU3G&e}-5zQ !KLLUqqN qN59- :&&U(<(<> r   c                 X   t        |t              rt        | |d      \  }}}t        |t        t        f      st        |      }t        |      D ]0  \  }}t        |t              s| j                  ||||z  z   d       2 t        |||      D ]+  }t        | |   t              s| j                  | |   |       - t        |      D ].  \  }}t        |t              s| j                  ||||z  z          0 t        | -  ||       y t        |t              r|dk  r|t        |       z  }|dk  rt        d      || |   u ry t        |t              r| j                  ||       t        | |   t              r| j                  | |   |       t        | -  ||       y t        |t        t        f      r?t        |      dk(  rt        d      t        |      dk(  r	|| |d   <   y || |d      |dd  <   y t        t!        |       j"                  dt!        |      j"                        )	NTr#   r
   r   r%   z,The tree position () may not be assigned to.r&   r'   )r   r(   r   r.   r/   r   r   r   r)   r!   r   __setitem__r+   r,   r-   r0   r1   r2   )	r   r   valuer3   r4   r5   r   r   r   s	           r   r7   z AbstractParentedTree.__setitem__   s   eU# ,T5T JE4edE]3U &e,5eT*OOE51t8+;TOJ - 5$-d1gt,OODGQ/ . &e,5eT*OOE51t8+;< - Gu- s#qyT"qy !566U#%&u-$u+t,UU3Gu-e}-5zQ !OPPUq!&U1X -2U1XuQRy) :&&U(<(<> r   c                 z    t        |t              r| j                  |t        |              t        |   |       y Nr   r   r   r,   r   append)r   r   r   s     r   r<   zAbstractParentedTree.append   s+    eT"OOE3t9-ur   c                     |D ]<  }t        |t              r| j                  |t        |              t        |   |       > y r:   r;   )r   r   r   r   s      r   extendzAbstractParentedTree.extend   s5    E%&s4y1GN5! r   c                     |dk  r|t        |       z  }|dk  rd}t        |t              r| j                  ||       t        |   ||       y Nr   )r,   r   r   r   r   insert)r   r   r   r   s      r   rA   zAbstractParentedTree.insert   sL     19SYE19EeT"OOE5)ue$r   c                     |dk  r|t        |       z  }|dk  rt        d      t        | |   t              r| j	                  | |   |       t
        |   |      S )Nr   r%   )r,   r-   r   r   r!   r   pop)r   r   r   s     r   rC   zAbstractParentedTree.pop   sZ    19SYE19122d5k4(OODK/w{5!!r   c                     | j                  |      }t        | |   t              r| j                  | |   |       t        |   |       y r:   )r   r   r   r!   r   remove)r   r   r   r   s      r   rE   zAbstractParentedTree.remove   s=    

5!d5k4(OODK/ur   __getslice__c           	      `    | j                  t        t        d|      t        d|                  S r@   )__getitem__r(   maxr   r3   r4   s      r   rF   z!AbstractParentedTree.__getslice__   &    ##E#a-Q$FGGr   c           	      `    | j                  t        t        d|      t        d|                  S r@   )r*   r(   rI   rJ   s      r   __delslice__z!AbstractParentedTree.__delslice__  rK   r   c           	      b    | j                  t        t        d|      t        d|            |      S r@   )r7   r(   rI   )r   r3   r4   r8   s       r   __setslice__z!AbstractParentedTree.__setslice__  s(    ##E#a-Q$FNNr   c                 0    | j                   t        |       fS )a  Method used by the pickle module when un-pickling.
        This method provides the arguments passed to ``__new__``
        upon un-pickling. Without this method, ParentedTree instances
        cannot be pickled and unpickled in Python 3.7+ onwards.

        :return: Tuple of arguments for ``__new__``, i.e. the label
            and the children of this node.
        :rtype: Tuple[Any, List[AbstractParentedTree]]
        )_labelr.   r   s    r   __getnewargs__z#AbstractParentedTree.__getnewargs__  s     T$Z((r   r:   F))r2   
__module____qualname____doc__r   r   r   r!   r*   r7   r<   r>   rA   rC   rE   hasattrr.   rF   rM   rO   rS   __classcell__r   s   @r   r   r      s}    0.$  *  &&P:x
"%" t^$	H	H	O
)r   r   )	metaclassc                   h     e Zd ZdZd fd	Zd Zd fd	Zd Zd Zd Z	d Z
d	 Zd
 Zd ZddZ xZS )ParentedTreea  
    A ``Tree`` that automatically maintains parent pointers for
    single-parented trees.  The following are methods for querying
    the structure of a parented tree: ``parent``, ``parent_index``,
    ``left_sibling``, ``right_sibling``, ``root``, ``treeposition``.

    Each ``ParentedTree`` may have at most one parent.  In
    particular, subtrees may not be shared.  Any attempt to reuse a
    single ``ParentedTree`` as a child of more than one parent (or
    as multiple children of the same parent) will cause a
    ``ValueError`` exception to be raised.

    ``ParentedTrees`` should never be used in the same tree as ``Trees``
    or ``MultiParentedTrees``.  Mixing tree implementations may result
    in incorrect parent pointers and in ``TypeError`` exceptions.
    c                     d | _         	 t        | 	  ||       |>t        |       D ]/  \  }}t	        |t
              sd |_         | j                  ||       1 y y r:   )_parentr   r   r   r   r   r   r   s        r   r   zParentedTree.__init__'  sZ    Cx(
 &dO5eT*$(EMOOE1- , r   c                     ddl m} |S )Nr   )ImmutableParentedTree)nltk.tree.immutablerb   )r   rb   s     r   _frozen_classzParentedTree._frozen_class5  s    =$$r   c                     |s,t        j                  | j                  j                   d       t        |   d      S )NzB objects do not support shallow copies. Defaulting to a deep copy.T)deep)warningswarnr   r2   r   copy)r   rf   r   s     r   ri   zParentedTree.copy:  s;    MM>>**++mn w||&&r   c                     | j                   S )z5The parent of this tree, or None if it has no parent.)r`   rR   s    r   parentzParentedTree.parentE  s    ||r   c                 t    | j                   yt        | j                         D ]  \  }}|| u s|c S  J d       )aD  
        The index of this tree in its parent.  I.e.,
        ``ptree.parent()[ptree.parent_index()] is ptree``.  Note that
        ``ptree.parent_index()`` is not necessarily equal to
        ``ptree.parent.index(ptree)``, since the ``index()`` method
        returns the first child that is equal to its argument.
        Nz&expected to find self in self._parent!)r`   r   )r   r   r   s      r   parent_indexzParentedTree.parent_indexI  sA     <<!$,,/HAu} 0 	?>>ur   c                 j    | j                         }| j                  r|dkD  r| j                  |dz
     S y)z6The left sibling of this tree, or None if it has none.r   r&   N)rm   r`   r   rm   s     r   left_siblingzParentedTree.left_siblingX  s5    ((*<<L1,<<q 011r   c                     | j                         }| j                  r-|t        | j                        dz
  k  r| j                  |dz      S y)z7The right sibling of this tree, or None if it has none.r&   N)rm   r`   r,   ro   s     r   right_siblingzParentedTree.right_sibling_  sC    ((*<<LC,=,AB<<q 011r   c                 l    | }|j                         !|j                         }|j                         !|S )z
        The root of this tree.  I.e., the unique ancestor of this tree
        whose parent is None.  If ``ptree.parent()`` is None, then
        ``ptree`` is its own root.
        )rk   )r   roots     r   rt   zParentedTree.rootf  s3     kkm';;=D kkm'r   c                     | j                         y| j                         j                         | j                         fz   S )z
        The tree position of this tree, relative to the root of the
        tree.  I.e., ``ptree.root[ptree.treeposition] is ptree``.
        r   )rk   treepositionrm   rR   s    r   rv   zParentedTree.treepositionq  s9    
 ;;= ;;=--/43D3D3F2HHHr   c                 h    t        |t              sJ | |   |u sJ |j                  | u sJ d |_        y r:   )r   r^   r`   r    s      r   r!   zParentedTree._delparent  s?    %...E{e###}}$$$ r   c                     t        |t              st        d      t        |d      r|j                  t        d      |s| |_        y y )Nz5Can not insert a non-ParentedTree into a ParentedTreer`   z3Can not insert a subtree that already has a parent.)r   r^   r0   rY   r`   
ValueErrorr   s       r   r   zParentedTree._setparent  sJ    %.STT 5)$)BRSS  EM r   r:   rT   )r2   rV   rW   rX   r   rd   ri   rk   rm   rp   rr   rt   rv   r!   r   rZ   r[   s   @r   r^   r^     s@    ".%
'?	I!r   r^   c                   h     e Zd ZdZd fd	Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd ZddZ xZS )MultiParentedTreea  
    A ``Tree`` that automatically maintains parent pointers for
    multi-parented trees.  The following are methods for querying the
    structure of a multi-parented tree: ``parents()``, ``parent_indices()``,
    ``left_siblings()``, ``right_siblings()``, ``roots``, ``treepositions``.

    Each ``MultiParentedTree`` may have zero or more parents.  In
    particular, subtrees may be shared.  If a single
    ``MultiParentedTree`` is used as multiple children of the same
    parent, then that parent will appear multiple times in its
    ``parents()`` method.

    ``MultiParentedTrees`` should never be used in the same tree as
    ``Trees`` or ``ParentedTrees``.  Mixing tree implementations may
    result in incorrect parent pointers and in ``TypeError`` exceptions.
    c                     g | _         	 t        | 	  ||       |>t        |       D ]/  \  }}t	        |t
              sg |_         | j                  ||       1 y y r:   )_parentsr   r   r   r   r   r   r   s        r   r   zMultiParentedTree.__init__  s^    	 	x(
 &dO5eT*%'ENOOE1- , r   c                     ddl m} |S )Nr   )ImmutableMultiParentedTree)rc   r   )r   r   s     r   rd   zMultiParentedTree._frozen_class  s    B))r   c                 ,    t        | j                        S )a  
        The set of parents of this tree.  If this tree has no parents,
        then ``parents`` is the empty set.  To check if a tree is used
        as multiple children of the same parent, use the
        ``parent_indices()`` method.

        :type: list(MultiParentedTree)
        )r.   r}   rR   s    r   parentszMultiParentedTree.parents  s     DMM""r   c                 j    | j                         D cg c]  \  }}|dkD  r||dz
      c}}S c c}}w )a}  
        A list of all left siblings of this tree, in any of its parent
        trees.  A tree may be its own left sibling if it is used as
        multiple contiguous children of the same parent.  A tree may
        appear multiple times in this list if it is the left sibling
        of this tree with respect to multiple parents.

        :type: list(MultiParentedTree)
        r   r&   )_get_parent_indicesr   rk   r   s      r   left_siblingszMultiParentedTree.left_siblings  sF     $(#;#;#=
#=qy 519#=
 	
 
s   /c                     | j                         D cg c]  \  }}|t        |      dz
  k  r||dz        c}}S c c}}w )a  
        A list of all right siblings of this tree, in any of its parent
        trees.  A tree may be its own right sibling if it is used as
        multiple contiguous children of the same parent.  A tree may
        appear multiple times in this list if it is the right sibling
        of this tree with respect to multiple parents.

        :type: list(MultiParentedTree)
        r&   )r   r,   r   s      r   right_siblingsz MultiParentedTree.right_siblings  sO     $(#;#;#=
#=Fa( 519#=
 	
 
s   #;c                 ~    | j                   D cg c]  }t        |      D ]  \  }}|| u r||f  c}}}S c c}}}w r:   r}   r   r   rk   r   r   s       r   r   z%MultiParentedTree._get_parent_indices  sN     --
' )& 1u} UO 1 '
 	
 
s   "8c                 R    t        | j                  i       j                               S )z
        The set of all roots of this tree.  This set is formed by
        tracing all possible parent paths until trees with no parents
        are found.

        :type: list(MultiParentedTree)
        )r.   _get_roots_helpervaluesrR   s    r   rootszMultiParentedTree.roots  s#     D**2.55788r   c                     | j                   r$| j                   D ]  }|j                  |        |S | |t        |       <   |S r:   )r}   r   id)r   resultrk   s      r   r   z#MultiParentedTree._get_roots_helper  sA    ==--((0 (   $F2d8r   c                 t    || j                   vrg S t        |      D cg c]  \  }}|| u s| c}}S c c}}w )aY  
        Return a list of the indices where this tree occurs as a child
        of ``parent``.  If this child does not occur as a child of
        ``parent``, then the empty list is returned.  The following is
        always true::

          for parent_index in ptree.parent_indices(parent):
              parent[parent_index] is ptree
        r   r   s       r   parent_indicesz MultiParentedTree.parent_indices  s>     &I09&0AS0AnueUd]E0ASSSs   44c           
          | |u rdgS | j                   D cg c]5  }|j                  |      D ]  }t        |      D ]  \  }}|| u r||fz    ! 7 c}}}}S c c}}}}w )a  
        Return a list of all tree positions that can be used to reach
        this multi-parented tree starting from ``root``.  I.e., the
        following is always true::

          for treepos in ptree.treepositions(root):
              root[treepos] is ptree
        r   )r}   treepositionsr   )r   rt   rk   treeposr   r   s         r   r   zMultiParentedTree.treepositions  s{     4<4K #mm+F%33D9G&/&7NUED=	 5(" '8 #9 #+  s   :A
c                    t        |t              sJ | |   |u sJ t        |j                  D cg c]	  }|| u s| c}      dk(  sJ t	        |       D ]  \  }}||u s||k7  s y  |j                  j                  |        y c c}w )Nr&   )r   r{   r,   r}   r   rE   )r   r   r   pr   cs         r   r!   zMultiParentedTree._delparent-  s    %!2333E{e###u~~;~!dA~;<AAA dODAqEza5j $ NN!!$' <s
   	BBc                     t        |t              st        d      |s3|j                  D ]  }|| u s y  |j                  j	                  |        y y )Nz?Can not insert a non-MultiParentedTree into a MultiParentedTree)r   r{   r0   r}   r<   )r   r   r   r   rk   s        r   r   zMultiParentedTree._setparent;  sS    %!23Q 
 ..T> ) %%d+ r   r:   rT   )r2   rV   rW   rX   r   rd   r   r   r   r   r   r   r   r   r!   r   rZ   r[   s   @r   r{   r{     sE    ". *	#
 
 
9T0(,r   r{   )rg   abcr   r   nltk.tree.treer   	nltk.utilr   r   r^   r{   __all__r   r   r   <module>r      sS     '  "})47 })@~!' ~!Br,, r,l r   