
    /hJX                     |    S SK r S SKJrJr  S SKJr  S SKJr   " S S\\S9r " S S	\5      r	 " S
 S\5      r
S	S/rg)    N)ABCMetaabstractmethod)Tree)slice_boundsc                      ^  \ rS rSrSrSU 4S jjr\SS j5       r\S 5       rU 4S jr	U 4S jr
U 4S jrU 4S	 jrU 4S
 jrSU 4S jjrU 4S jr\" \S5      (       a	  S rS rS rS rSrU =r$ )AbstractParentedTree   a{  
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U ]  X5        Ubx  [        U 5       H,  u  p4[        U[        5      (       d  M  U R                  XCSS9  M.     [        U 5       H-  u  p4[        U[        5      (       d  M  U R                  XC5        M/     g g )NTdry_run)super__init__	enumerate
isinstancer   
_setparentselfnodechildrenichild	__class__s        J/var/www/auris/envauris/lib/python3.13/site-packages/nltk/tree/parented.pyr   AbstractParentedTree.__init__.   sw    (  &dOeT**OOEdO; , &dOeT**OOE- ,      c                     g)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   AbstractParentedTree._setparent@       r   c                     g)as  
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   
_delparentAbstractParentedTree._delparentV   r!   r   c                   > [        U[        5      (       a]  [        XSS9u  p#n[        X#U5       H0  n[        X   [        5      (       d  M  U R                  X   U5        M2     [        TU ]  U5        g [        U[        5      (       a`  US:  a  U[        U 5      -  nUS:  a  [        S5      e[        X   [        5      (       a  U R                  X   U5        [        TU ]  U5        g [        U[        [        45      (       a;  [        U5      S:X  a  [        S5      e[        U5      S:X  a  XS   	 g XS      USS  	 g [        [        U 5      R                  < S[        U5      R                  < 35      e)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.    AbstractParentedTree.__delitem__j   sB   eU## ,TT JE5-dgt,,OODGQ/ . G& s##qyT"qy !566$+t,,U3G&e}--5zQ !KLLUqqN qN59- :&&U(<(<> r   c                   > [        U[        5      (       Ga  [        XSS9u  p4n[        U[        [        45      (       d  [        U5      n[        U5       H1  u  pg[        U[        5      (       d  M  U R                  XsXe-  -   SS9  M3     [        X4U5       H0  n[        X   [        5      (       d  M  U R                  X   U5        M2     [        U5       H2  u  pg[        U[        5      (       d  M  U R                  XsXe-  -   5        M4     [        TU ]-  X5        g [        U[        5      (       a  US:  a  U[        U 5      -  nUS:  a  [        S5      eX U   L a  g [        U[        5      (       a  U R                  X!5        [        X   [        5      (       a  U R                  X   U5        [        TU ]-  X5        g [        U[        [        45      (       a?  [        U5      S:X  a  [        S5      e[        U5      S:X  a  X US   '   g X US      USS  '   g [        [!        U 5      R"                  < S[!        U5      R"                  < 35      e)	NTr'   r   r   r)   z,The tree position () may not be assigned to.r*   r+   )r   r,   r   r2   r3   r   r   r   r-   r$   r   __setitem__r/   r0   r1   r4   r5   r6   )	r   r   valuer7   r8   r9   r   r   r   s	           r   r<    AbstractParentedTree.__setitem__   s   eU## ,TT JEedE]33U &e,eT**OOE18+;TOJ - 5-dgt,,OODGQ/ . &e,eT**OOE18+;< - G- s##qyT"qy !566U#%&&-$+t,,U3G-e}--5zQ !OPPUq!&U1X -2U1XuQRy) :&&U(<(<> r   c                    > [        U[        5      (       a  U R                  U[        U 5      5        [        TU ]  U5        g Nr   r   r   r0   r   append)r   r   r   s     r   rB   AbstractParentedTree.append   s.    eT""OOE3t9-ur   c                    > U HB  n[        U[        5      (       a  U R                  U[        U 5      5        [        TU ]  U5        MD     g r@   rA   )r   r   r   r   s      r   extendAbstractParentedTree.extend   s8    E%&&s4y1GN5! r   c                    > US:  a  U[        U 5      -  nUS:  a  Sn[        U[        5      (       a  U R                  X!5        [        TU ]  X5        g Nr   )r0   r   r   r   r   insert)r   r   r   r   s      r   rI   AbstractParentedTree.insert   sK     19SYE19EeT""OOE)u$r   c                    > US:  a  U[        U 5      -  nUS:  a  [        S5      e[        X   [        5      (       a  U R	                  X   U5        [
        TU ]  U5      $ )Nr   r)   )r0   r1   r   r   r$   r   pop)r   r   r   s     r   rL   AbstractParentedTree.pop   sY    19SYE19122dk4((OODK/w{5!!r   c                    > U R                  U5      n[        X   [        5      (       a  U R                  X   U5        [        TU ]  U5        g r@   )r   r   r   r$   r   remove)r   r   r   r   s      r   rO   AbstractParentedTree.remove   s<    

5!dk4((OODK/ur   __getslice__c           	      `    U R                  [        [        SU5      [        SU5      5      5      $ rH   )__getitem__r,   maxr   r7   r8   s      r   rQ   !AbstractParentedTree.__getslice__   &    ##E#a-Q$FGGr   c           	      `    U R                  [        [        SU5      [        SU5      5      5      $ rH   )r.   r,   rT   rU   s      r   __delslice__!AbstractParentedTree.__delslice__  rW   r   c           	      b    U R                  [        [        SU5      [        SU5      5      U5      $ rH   )r<   r,   rT   )r   r7   r8   r=   s       r   __setslice__!AbstractParentedTree.__setslice__  s(    ##E#a-Q$FNNr   c                 0    U R                   [        U 5      4$ )aq  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]]
)_labelr2   r   s    r   __getnewargs__#AbstractParentedTree.__getnewargs__  s     T$Z((r   r   r@   F))r6   
__module____qualname____firstlineno____doc__r   r   r   r$   r.   r<   rB   rE   rI   rL   rO   hasattrr2   rQ   rY   r\   ra   __static_attributes____classcell__r   s   @r   r   r      s    0.$  *  &&P:x
"%" t^$$	H	H	O
) 
)r   r   )	metaclassc                   z   ^  \ rS rSrSrSU 4S jjrS rSU 4S jjrS rS r	S r
S	 rS
 rS rS rSS jrSrU =r$ )ParentedTreei  a  
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                    > S U l          [        TU ]	  X5        UcD  [        U 5       H4  u  p4[	        U[
        5      (       d  M  S Ul         U R                  XC5        M6     g g r@   )_parentr   r   r   r   r   r   r   s        r   r   ParentedTree.__init__'  sW    C(
 &dOeT**$(EMOOE- , r   c                     SSK Jn  U$ )Nr   )ImmutableParentedTree)nltk.tree.immutablert   )r   rt   s     r   _frozen_classParentedTree._frozen_class5  s    =$$r   c                    > U(       d-  [         R                  " U R                  R                   S35        [        TU ]  SS9$ )NzB objects do not support shallow copies. Defaulting to a deep copy.T)deep)warningswarnr   r6   r   copy)r   ry   r   s     r   r|   ParentedTree.copy:  s;    MM>>**++mn w||&&r   c                     U R                   $ )z5The parent of this tree, or None if it has no parent.rq   r`   s    r   parentParentedTree.parentE  s    ||r   c                 x    U R                   c  g[        U R                   5       H  u  pX L d  M  Us  $     S5       e)a  
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!)rq   r   )r   r   r   s      r   parent_indexParentedTree.parent_indexI  s=     <<!$,,/HA} 0 	?>>ur   c                 v    U R                  5       nU R                  (       a  US:  a  U R                  US-
     $ g)z6The left sibling of this tree, or None if it has none.r   r*   N)r   rq   r   r   s     r   left_siblingParentedTree.left_siblingX  s5    ((*<<L1,<<q 011r   c                     U R                  5       nU R                  (       a.  U[        U R                  5      S-
  :  a  U R                  US-      $ g)z7The right sibling of this tree, or None if it has none.r*   N)r   rq   r0   r   s     r   right_siblingParentedTree.right_sibling_  sC    ((*<<LC,=,AB<<q 011r   c                 r    U nUR                  5       b#  UR                  5       nUR                  5       b  M#  U$ )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.
)r   )r   roots     r   r   ParentedTree.rootf  s3     kkm';;=D kkm'r   c                     U R                  5       c  gU R                  5       R                  5       U R                  5       4-   $ )zw
The tree position of this tree, relative to the root of the
tree.  I.e., ``ptree.root[ptree.treeposition] is ptree``.
r   )r   treepositionr   r`   s    r   r   ParentedTree.treepositionq  s9    
 ;;= ;;=--/43D3D3F2HHHr   c                 t    [        U[        5      (       d   eX   UL d   eUR                  U L d   eS Ul        g r@   )r   ro   rq   r#   s      r   r$   ParentedTree._delparent  s@    %....{e###}}$$$ r   c                     [        U[        5      (       d  [        S5      e[        US5      (       a  UR                  b  [        S5      eU(       d  Xl        g g )Nz5Can not insert a non-ParentedTree into a ParentedTreerq   z3Can not insert a subtree that already has a parent.)r   ro   r4   ri   rq   
ValueErrorr   s       r   r   ParentedTree._setparent  sN    %..STT 5)$$)BRSS  M r   r   r@   rc   )r6   re   rf   rg   rh   r   rv   r|   r   r   r   r   r   r   r$   r   rj   rk   rl   s   @r   ro   ro     sE    ".%
'?	I! !r   ro   c                   v   ^  \ rS rSrSrSU 4S jjrS rS rS rS r	S r
S	 rS
 rS rS rS rSS jrSrU =r$ )MultiParentedTreei  a  
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                    > / U l          [        TU ]	  X5        UcD  [        U 5       H4  u  p4[	        U[
        5      (       d  M  / Ul         U R                  XC5        M6     g g r@   )_parentsr   r   r   r   r   r   r   s        r   r   MultiParentedTree.__init__  s[    	 	(
 &dOeT**%'ENOOE- , r   c                     SSK Jn  U$ )Nr   )ImmutableMultiParentedTree)ru   r   )r   r   s     r   rv   MultiParentedTree._frozen_class  s    B))r   c                 ,    [        U R                  5      $ )z
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)
)r2   r   r`   s    r   parentsMultiParentedTree.parents  s     DMM""r   c                 r    U R                  5        VVs/ s H  u  pUS:  d  M  XS-
     PM     snn$ s  snnf )aE  
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   r   r   s      r   left_siblingsMultiParentedTree.left_siblings  sD     $(#;#;#=
#=qy F19#=
 	
 
s   33c                     U R                  5        VVs/ s H   u  pU[        U5      S-
  :  d  M  XS-      PM"     snn$ s  snnf )aH  
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   r0   r   s      r   right_siblings MultiParentedTree.right_siblings  sM     $(#;#;#=
#=Fa( F19#=
 	
 
s   ??c                     U R                    VVVs/ s H!  n[        U5        H  u  p#X0L d  M  X4PM     M#     snnn$ s  snnnf r@   r   r   r   r   r   r   s       r   r   %MultiParentedTree._get_parent_indices  sJ     --
' )& 1} VO 1 '
 	
 
s   >>c                 R    [        U R                  0 5      R                  5       5      $ )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)
)r2   _get_roots_helpervaluesr`   s    r   rootsMultiParentedTree.roots  s#     D**2.55788r   c                     U R                   (       a&  U R                    H  nUR                  U5        M     U$ X[        U 5      '   U$ r@   )r   r   id)r   resultr   s      r   r   #MultiParentedTree._get_roots_helper  s?    ==--((0 (   $2d8r   c                 |    XR                   ;  a  / $ [        U5       VVs/ s H  u  p#X0L d  M  UPM     snn$ s  snnf )a!  
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_indices MultiParentedTree.parent_indices  s8     &I09&0AS0AnuU]E0ASSSs   
88c           
          XL a  S/$ U R                    VVVVs/ s H<  nUR                  U5        H#  n[        U5        H  u  pEXPL d  M  X44-   PM     M%     M>     snnnn$ s  snnnnf )z
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   r   r   treeposr   r   s         r   r   MultiParentedTree.treepositions  su     <4K #mm+F%33D9G&/&7NU=	 #(" '8 #9 #+  s   .A"
A"
c                 *   [        U[        5      (       d   eX   UL d   e[        UR                   Vs/ s H  o3U L d  M	  UPM     sn5      S:X  d   e[	        U 5       H  u  pEXQL d  M  XB:w  d  M    g    UR                  R                  U 5        g s  snf )Nr*   )r   r   r0   r   r   rO   )r   r   r   pr   cs         r   r$   MultiParentedTree._delparent-  s    %!23333{e###u~~;~!dA~;<AAA dODAzaj $ NN!!$' <s   B Bc                     [        U[        5      (       d  [        S5      eU(       d5  UR                   H	  nX@L d  M	    g    UR                  R	                  U 5        g g )Nz?Can not insert a non-MultiParentedTree into a MultiParentedTree)r   r   r4   r   rB   )r   r   r   r   r   s        r   r   MultiParentedTree._setparent;  sT    %!233Q 
 ..> ) %%d+ r   )r   r@   rc   )r6   re   rf   rg   rh   r   rv   r   r   r   r   r   r   r   r   r$   r   rj   rk   rl   s   @r   r   r     sJ    ". *	#
 
 
9T0(, ,r   r   )rz   abcr   r   nltk.tree.treer   	nltk.utilr   r   ro   r   __all__r   r   r   <module>r      sS     '  "})47 })@~!' ~!Br,, r,l r   