
    g`U                     J   d Z ddlmZ ddlmZmZmZmZ ddlm	Z	m
Z
mZmZmZmZ ddlmZmZmZmZmZmZmZmZmZmZmZmZ ddlmZ ddlmZ  G d d	e      Z  G d
 de      Z! G d de      Z" G d de      Z# G d de      Z$ G d de      Z% G d de      Z& G d de      Z' G d de      Z( e        e$        e%        e#       gZ) e        e(        e&        e#       gZ* e        e(        e'        e#       gZ+ G d de      Z, G d de,      Z- G d de,      Z. G d  d!e,      Z/ G d" d#e!      Z0d$ Z1d%d%d%d%d&e,d'fd(Z2d) Z3e4d*k(  rYdd+l5m6Z6  e2         e7         e6d,      Z8 e,e8d-.      Z9d/Z:e:jw                         Z<e9j{                  e<      Z>e>D ]
  Z? e7e?        y0y0)1z`
Extension of chart parsing implementation to handle grammars with
feature structures as nodes.
    )perf_counter)TYPE
FeatStructfind_variablesunify)CFGFeatStructNonterminalNonterminal
Productionis_nonterminalis_terminal)BottomUpPredictCombineRuleBottomUpPredictRuleCachedTopDownPredictRuleChartChartParserEdgeIEmptyPredictRuleFundamentalRuleLeafInitRuleSingleEdgeFundamentalRuleTopDownInitRuleTreeEdge)logic)Treec                   Z     e Zd ZdZd
dZed        ZddZd Zd Z	d Z
d Z fd	Z xZS )FeatureTreeEdgea  
    A specialized tree edge that allows shared variable bindings
    between nonterminals on the left-hand side and right-hand side.

    Each ``FeatureTreeEdge`` contains a set of ``bindings``, i.e., a
    dictionary mapping from variables to values.  If the edge is not
    complete, then these bindings are simply stored.  However, if the
    edge is complete, then the constructor applies these bindings to
    every nonterminal in the edge whose symbol implements the
    interface ``SubstituteBindingsI``.
    c                 B   |i }|t        |      k(  r5|r3| j                  ||      }|D cg c]  }| j                  ||       }}i }t        j                  | ||||       || _        | j
                  t        t        |j                                     f| _        yc c}w )az  
        Construct a new edge.  If the edge is incomplete (i.e., if
        ``dot<len(rhs)``), then store the bindings as-is.  If the edge
        is complete (i.e., if ``dot==len(rhs)``), then apply the
        bindings to all nonterminals in ``lhs`` and ``rhs``, and then
        clear the bindings.  See ``TreeEdge`` for a description of
        the other arguments.
        N)	len_bindr   __init__	_bindings_comparison_keytuplesorteditems)selfspanlhsrhsdotbindingselts          L/var/www/openai/venv/lib/python3.12/site-packages/nltk/parse/featurechart.pyr!   zFeatureTreeEdge.__init__;   s     H #c(?x**S(+C8;<4::c8,C<H 	$c34! $ 4 4eF8>>CS<T6UV =s   Bc                 \    t        ||f| j                         | j                         d      S )a)  
        :return: A new ``TreeEdge`` formed from the given production.
            The new edge's left-hand side and right-hand side will
            be taken from ``production``; its span will be
            ``(index,index)``; and its dot position will be ``0``.
        :rtype: TreeEdge
        r   )r(   r)   r*   r+   )r   r)   r*   )
productionindexs     r.   from_productionzFeatureTreeEdge.from_productionV   s-     Z^^%5:>>;KQR
 	
    c                     t        | j                  d   |f| j                  | j                  | j                  dz   |      S )a  
        :return: A new ``FeatureTreeEdge`` formed from this edge.
            The new edge's dot position is increased by ``1``,
            and its end index will be replaced by ``new_end``.
        :rtype: FeatureTreeEdge
        :param new_end: The new end index.
        :type new_end: int
        :param bindings: Bindings for the new edge.
        :type bindings: dict
        r      )r(   r)   r*   r+   r,   )r   _span_lhs_rhs_dot)r'   new_endr,   s      r.   move_dot_forwardz FeatureTreeEdge.move_dot_forwardc   s=     **Q-)						A
 	
r3   c                 H    t        |t              s|S |j                  |      S N)
isinstancer	   substitute_bindings)r'   ntr,   s      r.   r    zFeatureTreeEdge._bindv   s#    "34I%%h//r3   c                 V    | j                  | j                         | j                        S r=   )r    nextsymr"   r'   s    r.   next_with_bindingsz"FeatureTreeEdge.next_with_bindings{   s    zz$,,.$..99r3   c                 6    | j                   j                         S )zC
        Return a copy of this edge's bindings dictionary.
        )r"   copyrC   s    r.   r,   zFeatureTreeEdge.bindings~   s     ~~""$$r3   c                     t        | j                  gt        | j                        z   t        | j                  j                               z   t        | j                  j                               z   t              S )z`
        :return: The set of variables used by this edge.
        :rtype: set(Variable)
        fs_class)r   r7   listr8   r"   keysvaluesr   rC   s    r.   	variableszFeatureTreeEdge.variables   se    
 YYK499o4>>&&()* 4>>((*+,  
 	
r3   c                     | j                         rt        | 	         S ddj                  d t	        | j
                  j                               D              z  }t        | 	          d| S )Nz{%s}z, c              3   &   K   | ]	  }d |z    yw)z%s: %rN ).0items     r.   	<genexpr>z*FeatureTreeEdge.__str__.<locals>.<genexpr>   s      *,JD4,Js    )is_completesuper__str__joinr%   r"   r&   )r'   r,   	__class__s     r.   rW   zFeatureTreeEdge.__str__   sk    7?$$		 *,24>>3G3G3I,J* ! H go'((44r3   )r   Nr=   )__name__
__module____qualname____doc__r!   staticmethodr2   r;   r    rD   r,   rM   rW   __classcell__)rY   s   @r.   r   r   .   sE    
W6 

 


&0
:%
5 5r3   r   c                   2    e Zd ZdZd Zd Zd Zd ZefdZ	y)FeatureChartzQ
    A Chart for feature grammars.
    :see: ``Chart`` for more information.
    c                 :    i k(  rt         j                        S t        j                               }t	        |      }| j
                  vr j                  |       t	         fd|D              }t         j
                  |   j                  |g             S )z
        Returns an iterator over the edges in this chart.
        See ``Chart.select`` for more information about the
        ``restrictions`` on the edges.
        c              3   F   K   | ]  }j                  |           y wr=   )_get_type_if_possible)rQ   keyrestrictionsr'   s     r.   rS   z&FeatureChart.select.<locals>.<genexpr>   s%      
EOcD&&|C'89Zs   !)iter_edgesr%   rK   r$   _indexes
_add_indexget)r'   rf   
restr_keysvalss   ``  r.   selectzFeatureChart.select   s     2$$ L--/0
:&
 T]]*OOJ' 
EO
 
 DMM*-11$;<<r3   c                     |D ]   }t        t        |      rt        d|z         i x} j                  |<    j                  D ]8  t         fd|D              }|j                  |g       j                         : y)z
        A helper function for ``select``, which creates a new index for
        a given set of attributes (aka restriction keys).
        zBad restriction: %sc              3   ^   K   | ]$  }j                   t        |                    & y wr=   rd   getattrrQ   re   edger'   s     r.   rS   z*FeatureChart._add_index.<locals>.<genexpr>   -      LVS**+=74+=+?@J   *-N)hasattrr   
ValueErrorri   rh   r$   
setdefaultappend)r'   rl   re   r1   rm   rt   s   `    @r.   rj   zFeatureChart._add_index   s     C5#& !6!<== 
 -/.j) KKD LV D T2&--d3	  r3   c                       j                   j                         D ];  \  }}t         fd|D              }|j                  |g       j	                         = y)zs
        A helper function for ``insert``, which registers the new
        edge with all existing indexes.
        c              3   ^   K   | ]$  }j                   t        |                    & y wr=   rq   rs   s     r.   rS   z6FeatureChart._register_with_indexes.<locals>.<genexpr>   ru   rv   N)ri   r&   r$   ry   rz   )r'   rt   rl   r1   rm   s   ``   r.   _register_with_indexesz#FeatureChart._register_with_indexes   sU    
 "&!4!4!6J LV D T2&--d3	 "7r3   c                 H    t        |t              rt        |v r	|t           S |S )z
        Helper function which returns the ``TYPE`` feature of the ``item``,
        if it exists, otherwise it returns the ``item`` itself
        )r>   dictr   )r'   rR   s     r.   rd   z"FeatureChart._get_type_if_possible   s#    
 dD!ddl:Kr3   c              #   ,  K   | j                  d| j                        D ]n  }t        |t              s|j	                         t
           |t
           k(  s6t        |j	                         |d      sS| j                  |d|      E d {    p y 7 w)Nr   )startendTrename_vars)complete
tree_class)rn   _num_leavesr>   r   r)   r   r   trees)r'   r   r   rt   s       r.   parseszFeatureChart.parses   st     KKaT-=-=K>DD/2XXZ%t4488:u$?::dTj:QQQ ? Rs"   1B!BB3B
BBN)
rZ   r[   r\   r]   rn   rj   r}   rd   r   r   rP   r3   r.   ra   ra      s&    
=.4(	4 (, Rr3   ra   c                       e Zd ZdZd Zy)FeatureFundamentalRulea  
    A specialized version of the fundamental rule that operates on
    nonterminals whose symbols are ``FeatStructNonterminal``s.  Rather
    than simply comparing the nonterminals for equality, they are
    unified.  Variable bindings from these unifications are collected
    and stored in the chart using a ``FeatureTreeEdge``.  When a
    complete edge is generated, these bindings are applied to all
    nonterminals in the edge.

    The fundamental rule states that:

    - ``[A -> alpha \* B1 beta][i:j]``
    - ``[B2 -> gamma \*][j:k]``

    licenses the edge:

    - ``[A -> alpha B3 \* beta][i:j]``

    assuming that B1 and B2 can be unified to generate B3.
    c              #     K   |j                         |j                         k(  r0|j                         r |j                         rt	        |t
              sy |j                         }|j                         }t	        |t
              r~t        |      sy |j                         t           |j                         t           k7  ry |j                         }|j                  |j                               }t        |||d      }|y ||k7  ry |j                         }|j                  |j                         |      }	|j                  |	||      r|	 y y w)N	used_varsFr   )r   r   is_incompleterU   r>   r   r)   rB   r   r   r,   rename_variablesrM   r   r;   insert_with_backpointer)
r'   chartgrammar	left_edge
right_edgefoundrB   r,   resultnew_edges
             r.   applyzFeatureFundamentalRule.apply  s1     MMOz//11'')&&(9o6 ##%j/2!'*  "4(JNN,<T,BB ))+H **Y5H5H5J*KE 7E8GF~% ))+H --jnn.>I ((9jIN Js   EENrZ   r[   r\   r]   r   rP   r3   r.   r   r      s    *%r3   r   c                   *    e Zd ZdZ e       Zd Zd Zy) FeatureSingleEdgeFundamentalRulez
    A specialized version of the completer / single edge fundamental rule
    that operates on nonterminals whose symbols are ``FeatStructNonterminal``.
    Rather than simply comparing the nonterminals for equality, they are
    unified.
    c              #      K   | j                   }|j                  |j                         d|j                               D ]  }|j	                  ||||      E d {      y 7 w)NF)r   rU   rB   )_fundamental_rulern   r   r)   r   )r'   r   r   r   frr   s         r.   _apply_completez0FeatureSingleEdgeFundamentalRule._apply_complete?  s`     ##  "z~~?O & 
I xxw	:FFF
 G   AA#A!A#c              #      K   | j                   }|j                  |j                         d|j                               D ]  }|j	                  ||||      E d {      y 7 w)NT)r   rU   r)   )r   rn   r   rB   r   )r'   r   r   r   r   r   s         r.   _apply_incompletez2FeatureSingleEdgeFundamentalRule._apply_incompleteF  s_     ##,,--/t9J9J9L ' 
J xxw	:FFF
 Gr   N)rZ   r[   r\   r]   r   r   r   r   rP   r3   r.   r   r   5  s     /0GGr3   r   c                       e Zd Zd Zy)FeatureTopDownInitRulec              #      K   |j                  |j                               D ]/  }t        j                  |d      }|j	                  |d      s,| 1 y w)Nr)   r   rP   )productionsr   r   r2   insert)r'   r   r   prodr   s        r.   r   zFeatureTopDownInitRule.applyT  sI     ''GMMO'<D&66tQ?H||Hb) =s   AAANrZ   r[   r\   r   rP   r3   r.   r   r   S  s    r3   r   c                       e Zd ZdZd Zy)FeatureTopDownPredictRulea  
    A specialized version of the (cached) top down predict rule that operates
    on nonterminals whose symbols are ``FeatStructNonterminal``.  Rather
    than simply comparing the nonterminals for equality, they are
    unified.

    The top down expand rule states that:

    - ``[A -> alpha \* B1 beta][i:j]``

    licenses the edge:

    - ``[B2 -> \* gamma][j:j]``

    for each grammar production ``B2 -> gamma``, assuming that B1
    and B2 can be unified.
    c              #     K   |j                         ry |j                         |j                         }}t        |      sy |j	                         }| j
                  j                  ||fd      }|d   |u r|d   |u ry |j                  |      D ]  }|j                         rG|j                         d   }	t        |	      r)||j                         k\  rE|	|j                  |      k7  rZt        |j                         |d      swt        j                  ||j                               }
|j!                  |
d      s|
  ||f| j
                  ||f<   y w)N)NNr   r5   r   Tr   rP   )rU   rB   r   r   rD   _donerk   r   r*   r   
num_leavesleafr   r)   r   r2   r   )r'   r   r   rt   rB   r1   nextsym_with_bindingsdoner   firstr   s              r.   r   zFeatureTopDownPredictRule.applyn  s7    g&
 !% 7 7 9zz~~4e<lK7eQ7 2''G'4D xxz
1u% 0 0 22 

5 11  TXXZ!6DI*::4L<<"-"N! 5& 5:73C

(%/0s   DE6E=ENr   rP   r3   r.   r   r   [  s    $"Dr3   r   c                       e Zd Zd Zy)FeatureBottomUpPredictRulec              #   L  K   |j                         ry |j                  |j                               D ]l  }t        |t              r|j                         d   }t        |      s2t        j                  ||j                               }|j                  |d      si| n y w)Nr*   r   rP   )
r   r   r)   r>   r   r*   r   r2   r   r   )r'   r   r   rt   r   _nextr   s          r.   r   z FeatureBottomUpPredictRule.apply  s     ''DHHJ'7D$0
1%e,&66tTZZ\JH||Hb) 8s   BB$B$Nr   rP   r3   r.   r   r     s    r3   r   c                       e Zd Zd Zy)!FeatureBottomUpPredictCombineRulec              #   <  K   |j                         ry |j                         }|j                  |      D ]  }i }t        |t              rt|j                         d   }t        |      s4t        |j                         f|j                         z   t              }|j                  |      }t        |||d      }	|	t        j                  ||j                               j                  |j                         |      }
|j                  |
|f      s|
  y w)Nr   r   rH   r   Fr   )r   r)   r   r>   r   r*   r   r   r   r   r   r2   r   r;   r   r   )r'   r   r   rt   r   r   r,   r   r   r   r   s              r.   r   z'FeatureBottomUpPredictCombineRule.apply  s     
''E'2DH$0
1%e, +XXZMDHHJ.	 ...CueX5I>&66djjltxxz84  ||Htg.- 3s   DDDNr   rP   r3   r.   r   r     s    r3   r   c                       e Zd Zd Zy)FeatureEmptyPredictRulec              #      K   |j                  d      D ]P  }t        |j                         dz         D ]/  }t        j	                  ||      }|j                  |d      s,| 1 R y w)NT)emptyr5   rP   )r   ranger   r   r2   r   )r'   r   r   r   r1   r   s         r.   r   zFeatureEmptyPredictRule.apply  s`     ''d'3Du//1A56*::4G<<"-"N 7 4s   AA) 	A)Nr   rP   r3   r.   r   r     s    #r3   r   c                       e Zd ZedefdZy)FeatureChartParser   c                 :    t        j                  | |f|||d| y )N)strategytrace_chart_widthchart_class)r   r!   )r'   r   r   r   r   parser_argss         r.   r!   zFeatureChartParser.__init__  s2     		
 /#	
 	
r3   N)rZ   r[   r\   BU_LC_FEATURE_STRATEGYra   r!   rP   r3   r.   r   r     s     ( 
r3   r   c                       e Zd Zd Zy)FeatureTopDownChartParserc                 <    t        j                  | |t        fi | y r=   )r   r!   TD_FEATURE_STRATEGYr'   r   r   s      r.   r!   z"FeatureTopDownChartParser.__init__      ##D'3FV+Vr3   NrZ   r[   r\   r!   rP   r3   r.   r   r         Wr3   r   c                       e Zd Zd Zy)FeatureBottomUpChartParserc                 <    t        j                  | |t        fi | y r=   )r   r!   BU_FEATURE_STRATEGYr   s      r.   r!   z#FeatureBottomUpChartParser.__init__  r   r3   Nr   rP   r3   r.   r   r     r   r3   r   c                       e Zd Zd Zy)$FeatureBottomUpLeftCornerChartParserc                 <    t        j                  | |t        fi | y r=   )r   r!   r   r   s      r.   r!   z-FeatureBottomUpLeftCornerChartParser.__init__  s     ##'1	
5@	
r3   Nr   rP   r3   r.   r   r     s    
r3   r   c                   .    e Zd ZdZd Zd Zd Zd Zd Zy)InstantiateVarsCharta?  
    A specialized chart that 'instantiates' variables whose names
    start with '@', by replacing them with unique new variables.
    In particular, whenever a complete edge is added to the chart, any
    variables in the edge's ``lhs`` whose names start with '@' will be
    replaced by unique new ``Variable``.
    c                 0    t         j                  | |       y r=   )ra   r!   )r'   tokenss     r.   r!   zInstantiateVarsChart.__init__  s    dF+r3   c                 L    t               | _        t        j                  |        y r=   )set_instantiatedra   
initializerC   s    r.   r   zInstantiateVarsChart.initialize  s     U%r3   c                 p    || j                   v ry| j                  |       t        j                  | ||      S )NF)r   instantiate_edgera   r   )r'   rt   child_pointer_lists      r.   r   zInstantiateVarsChart.insert  s7    4%%%d#""4/ABBr3   c                    t        |t              sy|j                         sy|| j                  v ry| j	                  |      }|sy| j
                  j                  |       |j                         j                  |      |_	        y)a^  
        If the edge is a ``FeatureTreeEdge``, and it is complete,
        then instantiate all variables whose names start with '@',
        by replacing them with unique new variables.

        Note that instantiation is done in-place, since the
        parsing algorithms might already hold a reference to
        the edge for future use.
        N)
r>   r   rU   _edge_to_cpls	inst_varsr   addr)   r?   r7   )r'   rt   r   s      r.   r   z%InstantiateVarsChart.instantiate_edge%  su     $0!4%%% NN4(	 	t$HHJ229=	r3   c                     |j                         j                         D ci c]2  }|j                  j                  d      r|t	        j
                         4 c}S c c}w )N@)r)   rM   name
startswithr   unique_variable)r'   rt   vars      r.   r   zInstantiateVarsChart.inst_varsB  sX     xxz++-
-xx""3' &&((-
 	
 
s   7AN)	rZ   r[   r\   r]   r!   r   r   r   r   rP   r3   r.   r   r     s!    ,&C>:
r3   r   c                  0    ddl m}  | j                  d      S )Nr   FeatureGrammara  
S  -> NP VP
PP -> Prep NP
NP -> NP PP
VP -> VP PP
VP -> Verb NP
VP -> Verb
NP -> Det[pl=?x] Noun[pl=?x]
NP -> "John"
NP -> "I"
Det -> "the"
Det -> "my"
Det[-pl] -> "a"
Noun[-pl] -> "dog"
Noun[-pl] -> "cookie"
Verb -> "ate"
Verb -> "saw"
Prep -> "with"
Prep -> "under"
)nltk.grammarr   
fromstringr   s    r.   demo_grammarr   O  s    +$$	 r3   Tr5   z$I saw John with a dog with my cookiec                    dd l }dd l}t                t               }	|rt        |	       t                t        d|j                         |rt        d|       |j                         }
t               } ||	|      }|j                  |
      }t        |j                  |	j                                     }| rt        dt               |z
  z         |r|D ]  }t        |        y t        dt        |             y )Nr   *z	Sentence:tracezTime: %sz	Nr trees:)systimeprintr   rZ   splitr   chart_parserJ   r   r   r   )print_timesprint_grammarprint_treesprint_sentencer   parsersentr   r   r   r   tcpr   r   trees                   r.   demor  j  s     	GnGg	#vk4 ZZ\FA	u	%BNN6"Egmmo./EjLNQ./0D$K  	k3u:&r3   c                     dd l } | j                  dd       dd l}|j                  d      }|j	                         j                  dd      j                  d       |j	                         j                  dd      j                  d       y )Nr   zfor i in range(1): demo()z/tmp/profile.outr   cum<   )profilerunpstatsStats
strip_dirs
sort_statsprint_stats)r  r  ps      r.   run_profiler    si    KK+-?@'(ALLNfe,88<LLNeV,88<r3   __main__)loadz!grammars/book_grammars/feat0.fcfg   r   zKim likes childrenN)@r]   r   r   nltk.featstructr   r   r   r   r   r   r	   r
   r   r   r   nltk.parse.chartr   r   r   r   r   r   r   r   r   r   r   r   nltk.semr   	nltk.treer   r   ra   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  rZ   	nltk.datar  r   r   r  r  r   r   parser   r  rP   r3   r.   <module>r     s    C C      j5h j5hMR5 MRj;_ ;|G'@ G<_ 5D 8 5Dz!4 (B <#. # N$&	  N $&	  N%'$&	 
 
&W 2 W
W!3 W

+= 
8
< 8
@8 
	/'D= zF	G67G	G1	-BDZZ\FHHVEd  r3   