JL iJXddlZddlmZmZddlmZddlmZGddeeZGdd eZ Gd d eZ d d gZ y) N)ABCMetaabstractmethod)Tree) slice_boundsceZdZdZdfd ZeddZedZfdZfdZ fdZ fdZ fd Z dfd Z fd Zeed r d ZdZdZdZxZS)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. ct||||ot|D]*\}}t|ts|j ||d,t|D](\}}t|ts|j ||*yy)NTdry_run)super__init__ enumerate isinstancer _setparentselfnodechildrenichild __class__s X/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/nltk/tree/parented.pyr zAbstractParentedTree.__init__.s x(  &dO <5eT*OOE1dO; <&dO .5eT*OOE1- . cy)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. Nrrindexr s rrzAbstractParentedTree._setparent@rcy)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``. Nrrrrs r _delparentzAbstractParentedTree._delparentVrrct|tr]t||d\}}}t|||D]+}t||ts|j |||-t ||yt|tr[|dkr|t|z }|dkr tdt||tr|j |||t ||yt|ttfr;t|dk(r tdt|dk(r||d=y||d|dd=ytt|jdt|j)NT allow_steprindex out of rangez(The tree position () may not be deleted. indices must be integers, not )rslicerrangerr!r __delitem__intlen IndexErrorlisttuple TypeErrortype__name__)rrstartstopsteprrs rr*z AbstractParentedTree.__delitem__jsJ eU # ,T5T J E45$- 0d1gt,OODGQ/ 0 G  &s #qyT"qy !566$u+t,U U3 G  & e} -5zQ !KLLUqqNqN59-:&&U (<(<> rcXt|trt||d\}}}t|ttfs t|}t |D]0\}}t|t s|j||||zzd2t|||D]+}t||t s|j|||-t |D].\}}t|t s|j||||zz0t|-||yt|tr|dkr|t|z }|dkr td|||uryt|t r|j||t||t r|j|||t|-||yt|ttfr?t|dk(r tdt|dk(r |||d<y|||d|dd<ytt!|j"dt!|j") NTr#r rr%z,The tree position () may not be assigned to.r&r')rr(rr.r/rrrr)r!r __setitem__r+r,r-r0r1r2) rrvaluer3r4r5rrrs rr7z AbstractParentedTree.__setitem__s eU # ,T5T J E4edE]3U &e, K5eT*OOE51t8+;TOJ K5$- 0d1gt,OODGQ/ 0 &e, =5eT*OOE51t8+;< = G u -s #qyT"qy !566U #%&u-$u+t,U U3 G u - e} -5zQ !OPPUq!&U1X-2U1XuQRy):&&U (<(<> rczt|tr|j|t|t||yNrrrr,r append)rrrs rr<zAbstractParentedTree.appends+ eT " OOE3t9 - urc|D]<}t|tr|j|t|t||>yr:r;)rrrrs rextendzAbstractParentedTree.extends: "E%&s4y1 GN5 ! "rc|dkr|t|z }|dkrd}t|tr|j||t|||yNr)r,rrrr insert)rrrrs rrAzAbstractParentedTree.insertsL 19 SY E 19E eT " OOE5 ) ue$rc|dkr|t|z }|dkr tdt||tr|j |||t ||S)Nrr%)r,r-rrr!r pop)rrrs rrCzAbstractParentedTree.popsZ 19 SY E 1912 2 d5k4 ( OODK /w{5!!rc|j|}t||tr|j|||t||yr:)rrrr!r remove)rrrrs rrEzAbstractParentedTree.removes= 5! d5k4 ( OODK / ur __getslice__c `|jttd|td|Sr@) __getitem__r(maxrr3r4s rrFz!AbstractParentedTree.__getslice__&##E#a-Q$FG Grc `|jttd|td|Sr@)r*r(rIrJs r __delslice__z!AbstractParentedTree.__delslice__rKrc b|jttd|td||Sr@)r7r(rI)rr3r4r8s r __setslice__z!AbstractParentedTree.__setslice__s(##E#a-Q$FN Nrc0|jt|fS)aMethod 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.rs r__getnewargs__z#AbstractParentedTree.__getnewargs__s T$Z((rr:F))r2 __module__ __qualname____doc__r rrr!r*r7r<r>rArCrEhasattrr.rFrMrOrS __classcell__rs@rrrs}0 .$  *    &&P:x " %"t^$ H H O )rr) metaclasscheZdZdZd fd ZdZdfd ZdZdZdZ dZ d Z d Z d Z dd ZxZS) 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. cd|_ t| |||>t|D]/\}}t |t sd|_|j ||1yyr:)_parentr r rrrrrs rr zParentedTree.__init__'s_ C x(   &dO .5eT*$(EMOOE1- . rcddlm}|S)Nr)ImmutableParentedTree)nltk.tree.immutablerb)rrbs r _frozen_classzParentedTree._frozen_class5s =$$rc|s,tj|jjdt|dS)NzB objects do not support shallow copies. Defaulting to a deep copy.T)deep)warningswarnrr2r copy)rrfrs rrizParentedTree.copy:s; MM>>**++mn w||&&rc|jS)z5The parent of this tree, or None if it has no parent.)r`rRs rparentzParentedTree.parentEs ||rct|jyt|jD] \}}||us |cSJd)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)rrrs r parent_indexzParentedTree.parent_indexIsF << !$,,/ HAu}  ?>>urcj|j}|jr|dkDr|j|dz Sy)z6The left sibling of this tree, or None if it has none.rr&N)rmr`rrms r left_siblingzParentedTree.left_siblingXs5((* <t|D]/\}}t |t sg|_|j ||1yyr:)_parentsr r rrrrrs rr zMultiParentedTree.__init__sc   x(   &dO .5eT*%'ENOOE1- . rcddlm}|S)Nr)ImmutableMultiParentedTree)rcr)rrs rrdzMultiParentedTree._frozen_classs B))rc,t|jS)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}rRs rparentszMultiParentedTree.parentssDMM""rcj|jDcgc]\}}|dkDr||dz c}}Scc}}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) rr&)_get_parent_indicesrrkrs r left_siblingszMultiParentedTree.left_siblingssA$(#;#;#= qy 519    s/c|jDcgc]\}}|t|dz kr||dz c}}Scc}}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&)rr,rs rright_siblingsz MultiParentedTree.right_siblingssJ$(#;#;#= F a( 519    s#;c~|jDcgc]}t|D] \}}||ur||fc}}}Scc}}}wr:r}rrrkrrs rrz%MultiParentedTree._get_parent_indicessV--   )& 1 u}UO    s"8cRt|jijS)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_helpervaluesrRs rrootszMultiParentedTree.rootss#D**2.55788rc|jr$|jD]}|j||S||t|<|Sr:)r}rid)rresultrks rrz#MultiParentedTree._get_roots_helpersF ==-- 1((0 1  $F2d8  rct||jvrgSt|Dcgc] \}}||us |c}}Scc}}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 rrs rparent_indicesz MultiParentedTree.parent_indicess8  &I09&0ASnueUd]ES SSs 44c ||urdgS|jDcgc]5}|j|D]}t|D]\}}||ur||fz!7c}}}}Scc}}}}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)rrtrktreeposrrs rrzMultiParentedTree.treepositionss 4<4K#mm%33D9&/&7 #UED= 5(""" s:A ct|tsJ|||usJt|jDcgc] }||us| c}dk(sJt |D]\}}||us ||k7sy|jj |ycc}w)Nr&)rr{r,r}rrE)rrrprcs rr!zMultiParentedTree._delparent-s%!2333E{e###u~~;!dA;<AAAdO (DAqEza5j ( NN ! !$ ' ,%%d+ rr:rT)r2rVrWrXr rdrrrrrrrrr!rrZr[s@rr{r{sE". * #   9 T0 ( ,rr{) rgabcrrnltk.tree.treer nltk.utilrrr^r{__all__rrrrsS'" })47})@~!'~!Br,,r,l r