Ñò
=[¿Kc        
   @   s  d  Z  d d k Z d d k Z d d k Z d d k Z d d k l Z d d k l Z l	 Z	 l
 Z
 l Z d d k Td e f d „  ƒ  YZ d e f d	 „  ƒ  YZ d
 „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z e d j o e ƒ  n d S(   sv   
Tree class voor DOP-parser. Class is met name bedoeld voor het maken van
een PCFG-grammatica op basis van DOP-bomen.
iÿÿÿÿN(   t   ImmutableProbabilisticMixIn(   t   WeightedGrammart   Nonterminalt
   Productiont   WeightedProduction(   t   *t   DopTreec           B   sÑ   e  Z d  Z d 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 d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d d e d „ Z d „  Z RS(   s†  
    Tree class. Op basis van celex_parses worden hierarchische lijsten van
    tree-objecten gemaakt.

    @leaves Geeft alle terminal-leaves terug uit de boom
    @subtrees Geeft alle mogelijke subbomen uit de afleiding
    @treepositions Geeft alle posities in de boom terug
    (terminals en non-terminals).
    @frontier Geeft alle mogelijke permutaties voor een bepaalde subboom.
    c         C   s/   | d  j o d  St i |  | ƒ | |  _ d  S(   N(   t   Nonet   listt   __init__t   _node(   t   selft   nodet   rhs(    (    s   dop_tree.pyR	      s     c         C   s   |  i  S(   N(   R
   (   R   (    (    s   dop_tree.pyR   $   s    c         C   sƒ   t  | t t f ƒ o t i |  | ƒ St | ƒ d j o |  St | ƒ d j o |  t | d ƒ S|  t | d ƒ | d Sd  S(   Ni    i   (   t
   isinstancet   intt   sliceR   t   __getitem__t   len(   R   t   index(    (    s   dop_tree.pyR   &   s    c         C   sŒ   t  | t t f ƒ o t i |  | | ƒ St | ƒ d j o t d ƒ ‚ n< t | ƒ d j o | |  | d <n | |  | d | d <d  S(   Ni    s,   The tree position () may not be assigned to.i   (   R   R   R   R   t   __setitem__R   t
   IndexError(   R   R   t   value(    (    s   dop_tree.pyR   1   s    c         C   sƒ   t  | t t f ƒ o t i |  | ƒ St | ƒ d j o t d ƒ ‚ n6 t | ƒ d j o |  | d =n |  | d | d =d  S(   Ni    s(   The tree position () may not be deleted.i   (   R   R   R   R   t   __delitem__R   R   (   R   R   (    (    s   dop_tree.pyR   =   s    c         C   s3   d i  d „  |  Dƒ ƒ } d |  i i |  i | f S(   Ns   , c         s   s   x |  ] } t  | ƒ Vq Wd  S(   N(   t   repr(   t   .0t   c(    (    s   dop_tree.pys	   <genexpr>I   s   	 s   %s(%r, [%s])(   t   joint	   __class__t   __name__R
   (   R   t   childstr(    (    s   dop_tree.pyt   __repr__H   s    c         C   s
   |  i  ƒ  S(   N(   t   pprint_flat(   R   (    (    s   dop_tree.pyt   __str__M   s    c         C   s8   t  | t ƒ p t S|  i | i j o t i |  | ƒ S(   N(   R   R   t   FalseR
   R   t   __eq__(   R   t   other(    (    s   dop_tree.pyR#   P   s     c         C   s   |  | j S(   N(    (   R   R$   (    (    s   dop_tree.pyt   __ne__T   s    c         C   s    y t  |  | ƒ SWn d SXd  S(   Niÿÿÿÿ(   t   cmp(   R   R$   (    (    s   dop_tree.pyt   __cmp__W   s    c         C   sO   g  } xB |  D]: } t  | t ƒ o | i | i ƒ  ƒ q | i | ƒ q W| S(   s@   
        Geeft alle terminal leaves van een boom terug.
        (   R   R   t   extendt   leavest   append(   R   R)   t   child(    (    s   dop_tree.pyR)   ]   s     c         c   sf   | p | |  ƒ o	 |  Vn xA |  D]9 } t  | t ƒ o# x  | i | ƒ D] } | VqK Wq% q% Wd S(   sT  
        Haal alle subbomen uit een parse. Deze subbomen bevatten nog geen
        lege knopen. Uit een parse als:

        (N (N (N post) (N zegel)) (N (V (Aff ver) (V koop)) (Aff er)))

        kunnen we de volgende subbomen halen:

        1. (N (N (N post) (N zegel)) (N (V (Aff ver) (V koop)) (Aff er)))
        2. (N (N post) (N zegel))
        3. (N post)
        4. (N zegel)
        5. (N (V (Aff ver) (V koop)) (Aff er))
        6. (V (Aff ver) (V koop)
        7. (Aff ver)
        8. (V koop)
        9. (Aff er)

        De functie geeft een Generator-object terug.
        
        N(   R   R   t   subtrees(   R   t   filterR+   t   subtree(    (    s   dop_tree.pyR,   i   s    	  c            s   g  } | i  d ƒ xg t |  ƒ D]Y \ ‰  } t | t ƒ o- | i ƒ  } | i ‡  f d †  | Dƒ ƒ q  | i  ˆ  f ƒ q  W| S(   s8    De posities van van knopen in de boom in tuple-formaat c         3   s    x |  ] } ˆ  f | Vq Wd  S(   N(    (   R   t   p(   t   i(    s   dop_tree.pys	   <genexpr>   s   	 (    (   R*   t	   enumerateR   R   t   treepositionsR(   (   R   t	   positionsR+   t   childpos(    (   R0   s   dop_tree.pyR2   †   s     !c         c   sœ   x• |  i  ƒ  D]‡ } | d j ot t |  | t ƒ o" t i |  ƒ } d | | <| Vq” t |  | t ƒ o& t i |  ƒ } d g | | (| Vq” q q Wd S(   s   Hulp functie voor frontier()t    N(    (   R2   R   t   strt   copyt   deepcopyR   (   R   t   post   f(    (    s   dop_tree.pyt   rec_frontier’   s     
	c            s{   t  |  ƒ d j o |  Sd } |  g ‰  xI | t  ˆ  ƒ j  o5 ˆ  i ‡  f d †  ˆ  | i ƒ  Dƒ ƒ | d 7} q* Wˆ  Sd S(   sd   Frontier-operatie. Op basis van de indeces gegeven door
        self.treepositions worden alle permutaties van de boom opgevraagd. Voorbeeld:
        - (N (N loon) (V (Aff be) (V heers) (Aff ing)))
        - (N (N ) (V (Aff be) (V heers) (Aff ing)))
        - (N (N loon) (V ))
        - (N (N loon) (V (Aff ) (V heers) (Aff ing)))
          etc.
        i   i    c         3   s*   x# |  ] } | ˆ  j o	 | Vq q Wd  S(   N(    (   R   t   t(   t   trees(    s   dop_tree.pys	   <genexpr>­   s   	 N(   R   R(   R;   (   R   R0   (    (   R=   s   dop_tree.pyt   frontierŸ   s    	 	 'c         C   s–   t  i  ƒ  } g  } xd |  i ƒ  D]V } t i | i ƒ  ƒ } t | ƒ d j o | i d „  | Dƒ ƒ q | i | ƒ q Wt  i  ƒ  | Gt | ƒ GH| S(   sO    Generator voor alle permutaties voor alle subbomen van een bepaalde afleiding i   c         s   s   x |  ] } | Vq Wd  S(   N(    (   R   R<   (    (    s   dop_tree.pys	   <genexpr>¸   s   	 (   t   timeR,   R7   R8   R>   R   R(   R*   (   R   t   t1t   boment   treeR=   (    (    s   dop_tree.pyt   print_frontier±   s     c         C   sƒ   x| |  i  ƒ  D]n } | d j o[ t |  | t ƒ oC |  | d d j o* |  | i t t i ƒ  ƒ f |  | _ qw q{ q q W|  S(   s<  
        Geeft alle niet-root en nonterminals een unieke code. Dat zijn
        dus alle internal nodes. Een boom als:

        (N (V (Aff ver) (V koop)) (Aff ))
        wordt:
        (N (V1 (Aff2 ver) (V3 koop)) (Aff ))

        Hiermee zorgen we dat in de herschrijfregels (Chomsky normal form)
        (1) de waarschijnlijkheid van een boom behouden blijft (alle unieke
        regels krijgen dezelfde waarschijnlijkheid 1.0 en (2) dat het boomkarakter
        behouden blijft aangezien een unieke regel als Aff2 --> ver alleen in deze
        parse voorkomt.
        i    R5   (    (   R2   R   R   R
   R6   t   uuidt   uuid4(   R   R9   (    (    s   dop_tree.pyt   goodman_reduction¾   s     6c         C   s~   g  } |  i  ƒ  d g j o) | t t |  i ƒ t |  ƒ ƒ g 7} n x2 |  D]* } t | t ƒ o | | i ƒ  7} qL qL W| S(   su   
        Geeft voor elke subboom met frontieroperatie de Chomsky Normal Form
        herschrijfregels terug.
        R5   (   R)   R   R   R
   t   child_namesR   R   t   productions(   R   t   prodsR+   (    (    s   dop_tree.pyRH   Ô   s    ) R5   s   ()c      	   C   s  g  } x¦ |  D]ž } t  | t ƒ o  | i | i | | | ƒ ƒ q t  | t ƒ o | i d i | ƒ ƒ q t  | t ƒ o | o | i d | ƒ q | i d | ƒ q Wt  |  i t ƒ o, d | d |  i | d i | ƒ | d f Sd | d |  i | d i | ƒ | d f Sd	 S(
   sp   
        Print boom in formaat:
        
        (N (N nest) (V (Aff be) (N scherm)) (Aff er))
        
        t   /s   %ss   %rs   %s%s%s %s%si    t    i   s   %s%r%s %s%sN(	   R   R   R*   R    t   tupleR   R6   R
   t
   basestring(   R   t   nodesept   parenst   quotest	   childstrsR+   (    (    s   dop_tree.pyR    á   s      c         C   s   d |  i  d d d d ƒ S(   sV   
        Functie om een latex-output te geven (Afhankelijkheid LaTeX = qtree)
        s   \Tree RN   R5   RO   s   [.s    ](   s   [.s    ](   R    (   R   (    (    s   dop_tree.pyt   pprint_latex_qtreeú   s    N(   R   t
   __module__t   __doc__R   R	   R   R   R   R   R   R!   R#   R%   R'   R)   R,   R2   R;   R>   RC   RF   RH   R"   R    RR   (    (    (    s   dop_tree.pyR      s*   
																t   groupbyc           B   s&   e  Z d  Z d „  d „ Z e i Z RS(   sœ   
    Groepeer-class. Groepeert een lijst als ['a', 'b', 'a', 'c', 'c'] in
    afzonderlijke lijsten met identieke items: [['a', 'a'], ['b'], ['c', 'c']
    c         C   s   |  S(    (    (   t   x(    (    s   dop_tree.pyt   <lambda>  s    c         C   s@   x9 | D]1 } | | ƒ } |  i  t | ƒ g  ƒ i | ƒ q Wd  S(   N(   t
   setdefaultR6   R*   (   R   t   seqt   keyR   t   k(    (    s   dop_tree.pyR	     s     (   R   RS   RT   R	   t   dictt	   iteritemst   __iter__(    (    (    s   dop_tree.pyRU      s   c         C   s2   g  } |  D]  } | i  ƒ  D] } | | q q ~ S(   s9   Extraheer voor alle parses alle frontier-bomen + subbomen(   RC   (   RH   t   _[1]t
   productionR/   (    (    s   dop_tree.pyt   get_frontiers  s    c         c   s^   g  } t  |  ƒ D] \ } } | | q ~ } x* | D]" } x t | ƒ D] } | VqG Wq4 Wd S(   s1   Geef Goodman-trees terug voor alle frontier-bomenN(   RU   t   get_goodman(   t	   frontiersR_   R[   t   gt   sorted_frontier_listst   sorted_frontier_listt   goodman_frontier(    (    s   dop_tree.pyt   get_productions  s    -  c         C   s;   |  d i  ƒ  } x$ t t |  ƒ ƒ D] } | |  | <q# W|  S(   s*   Geef identieke bomen dezelfde unieke codesi    (   RF   t   rangeR   (   Rf   t   frontier_listR0   (    (    s   dop_tree.pyRb     s
     c         C   s2   g  } |  D]  } | i  ƒ  D] } | | q q ~ S(   s3   Geef Chomsky herschrijfregels terug van alle bomen.(   RH   (   t   goodman_frontiersR_   Rg   t   goodman(    (    s   dop_tree.pyt   make_productions  s    c         C   sR   g  } xE |  D]= } t  | t ƒ o | i t | i ƒ ƒ q | i | ƒ q W| S(   s(   Geef alle knoopnamen terug uit een boom.(   R   R   R*   R   R
   (   RB   t   namesR+   (    (    s   dop_tree.pyRG   "  s     c   	      C   sÖ   t  i  ƒ  } h  } h  } xN |  D]F } | i | i ƒ  d ƒ d | | i ƒ  <| i | d ƒ d | | <q Wg  } | D]@ } | t | i ƒ  | i ƒ  d t | | ƒ | | i ƒ  ƒqt ~ } t d ƒ } t | | ƒ S(   s~   
    Geeft de waarschijnlijkheid van een boom in production-rewrite-formaat.
    Input is lijst van productions per tree.
    i    i   t   probt   W(   R?   t   gett   lhsR   R   t   floatR   R   (	   RH   R@   t   pcountt   lcountt   prodR_   R/   RI   t   N(    (    s   dop_tree.pyt   induce_probabilities,  s     &Mc         C   sC  d \ } } t  i | ƒ t  i | ƒ } } d | | f } d | | f } t  i d | | | | f ƒ } d g  f g } x± | i |  ƒ D]  }	 |	 i ƒ  }
 |
 d | j o' |
 d i ƒ  } | i | g  f ƒ q‰ |
 | j o4 | i ƒ  \ } } | d d i t	 | | ƒ ƒ q‰ | d d i |
 ƒ q‰ W| d d d } | S(   s÷   
    Maak van string een lijst van tree-classes. Inputstrings zijn van het formaat:

    postzegelverkoper -->
    (N (N (N post) (N zegel)) (N (V (Aff ver) (V koop)) (Aff er)))

    De output van celex_parser.pprint_parse is in dit formaat. 
    s   ()s
   [^\s%s%s]+s   %s\s*(%s)?|%s|(%s)i    i   iÿÿÿÿN(
   t   ret   escapet   compileR   t   finditert   groupt   lstripR*   t   popR   (   t   stringt   open_bt   close_bt   open_patternt   close_patternt   node_patternt   leaf_patternt   token_ret   stackt   matcht   tokenR   t   childrenRB   (    (    s   dop_tree.pyt   parse@  s(    		 "c    
      C   s±   d d d d d d g }  g  } |  D] } | t  | ƒ q# ~ } t | ƒ } t | ƒ } t | ƒ } t | ƒ } t | ƒ } | i d ƒ x" | i d i ƒ  ƒ D] }	 |	 GHqž Wd  S(	   Ns$   (A (Aff on) (A (V dank) (Aff baar)))s$   (A (Aff on) (A (V vind) (Aff baar)))s#   (N (V (Aff be) (V vind)) (Aff ing))sQ   (N (N (N (P aan) (N deel)) (V houd) (Aff er)) (Aff s) (N (V vergader) (Aff ing)))sD   (N (N (P aan) (N (Aff ge) (N zicht))) (Aff s) (N (V lig) (Aff ing)))sg   (N (N (A (V (P aan) (V spreek)) (Aff elijk)) (Aff heid)) (Aff s) (N (V (Aff ver) (A zeker)) (Aff ing)))i   s   on dank baar(	   RŒ   Ra   Rh   Rm   Rx   t   InsideChartParsert   tracet   nbest_parset   split(
   t   oefenwoordenR_   t   woordRH   Rc   RI   t   produst   grammart   inside_parserRB   (    (    s   dop_tree.pyt   mainb  s     	' t   __main__(   RT   Ry   R7   RD   R?   t   nltk.probabilityR    t   dop_grammarR   R   R   R   t
   dop_pchartR   R   R\   RU   Ra   Rh   Rb   Rm   RG   Rx   RŒ   R–   R   (    (    (    s   dop_tree.pyt   <module>
   s    0"
í					
		"	