ó
¦–Õ\c           @` s  d  d l  m Z m Z m Z d  d l m Z d  d l m Z m Z d „  Z	 d „  Z
 d e f d „  ƒ  YZ d e f d	 „  ƒ  YZ e d
 ƒ Z e d ƒ Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d „  Z d „  Z i e d 6e d 6Z d „  Z d „  Z d S(   i    (   t   absolute_importt   divisiont   print_function(   t   deque(   t   istaskt   subsc         C` s/   t  |  ƒ r |  d St |  t ƒ r' t S|  Sd S(   s#   Return the top level node of a taski    N(   R   t
   isinstancet   list(   t   task(    (    s+   lib/python2.7/site-packages/dask/rewrite.pyt   head   s
    c         C` s/   t  |  ƒ r |  d St |  t ƒ r' |  Sd Sd S(   s&   Get the arguments for the current taski   N(    (   R   R   R   (   R   (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyt   args   s
    t	   Traverserc           B` sM   e  Z d  Z d d „ Z d „  Z d „  Z d „  Z e d „  ƒ Z	 d „  Z
 RS(   s£  Traverser interface for tasks.

    Class for storing the state while performing a preorder-traversal of a
    task.

    Parameters
    ----------
    term : task
        The task to be traversed

    Attributes
    ----------
    term
        The current element in the traversal
    current
        The head of the current element in the traversal. This is simply `head`
        applied to the attribute `term`.
    c         C` s1   | |  _  | s$ t t g ƒ |  _ n	 | |  _ d  S(   N(   t   termR   t   ENDt   _stack(   t   selfR   t   stack(    (    s+   lib/python2.7/site-packages/dask/rewrite.pyt   __init__2   s    	c         c` s,   x% |  j  t k	 r' |  j  V|  j ƒ  q Wd  S(   N(   t   currentR   t   next(   R   (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyt   __iter__9   s    c         C` s   t  |  j t |  j ƒ ƒ S(   s…   Copy the traverser in its current state.

        This allows the traversal to be pushed onto a stack, for easy
        backtracking.(   R   R   R   R   (   R   (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyt   copy>   s    c         C` sU   t  |  j ƒ } | s* |  j j ƒ  |  _ n' | d |  _ |  j j t | d ƒ ƒ d S(   s3   Proceed to the next term in the preorder traversal.i    i   N(   R
   R   R   t   popt   extendt   reversed(   R   t   subterms(    (    s+   lib/python2.7/site-packages/dask/rewrite.pyR   F   s
    c         C` s   t  |  j ƒ S(   N(   R	   R   (   R   (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyR   Q   s    c         C` s   |  j  j ƒ  |  _ d S(   s<   Skip over all subterms of the current level in the traversalN(   R   R   R   (   R   (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyt   skipU   s    N(   t   __name__t
   __module__t   __doc__t   NoneR   R   R   R   t   propertyR   R   (    (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyR      s   			t   Tokenc           B` s    e  Z d  Z d „  Z d „  Z RS(   s[   A token object.

    Used to express certain objects in the traversal of a task or pattern.c         C` s   | |  _  d  S(   N(   t   name(   R   R!   (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyR   _   s    c         C` s   |  j  S(   N(   R!   (   R   (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyt   __repr__b   s    (   R   R   R   R   R"   (    (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyR    Z   s   	t   ?t   endt   Nodec           B` sA   e  Z d  Z d Z d d d „ Z e d „  ƒ Z e d „  ƒ Z RS(   s   A Discrimination Net node.c         C` s:   | r | n i  } | r | n g  } t  j |  | | f ƒ S(   N(   t   tuplet   __new__(   t   clst   edgest   patterns(    (    s+   lib/python2.7/site-packages/dask/rewrite.pyR'   r   s    c         C` s   |  d S(   s@   A dictionary, where the keys are edges, and the values are nodesi    (    (   R   (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyR)   w   s    c         C` s   |  d S(   s8   A list of all patterns that currently match at this nodei   (    (   R   (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyR*   |   s    (    N(	   R   R   R   t	   __slots__R   R'   R   R)   R*   (    (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyR%   m   s
   t   RewriteRulec           B` s5   e  Z d  Z d d „ Z d „  Z d „  Z d „  Z RS(   så  A rewrite rule.

    Expresses `lhs` -> `rhs`, for variables `vars`.

    Parameters
    ----------
    lhs : task
        The left-hand-side of the rewrite rule.
    rhs : task or function
        The right-hand-side of the rewrite rule. If it's a task, variables in
        `rhs` will be replaced by terms in the subject that match the variables
        in `lhs`. If it's a function, the function will be called with a dict
        of such matches.
    vars: tuple, optional
        Tuple of variables found in the lhs. Variables can be represented as
        any hashable object; a good convention is to use strings. If there are
        no variables, this can be omitted.

    Examples
    --------
    Here's a `RewriteRule` to replace all nested calls to `list`, so that
    `(list, (list, 'x'))` is replaced with `(list, 'x')`, where `'x'` is a
    variable.

    >>> lhs = (list, (list, 'x'))
    >>> rhs = (list, 'x')
    >>> variables = ('x',)
    >>> rule = RewriteRule(lhs, rhs, variables)

    Here's a more complicated rule that uses a callable right-hand-side. A
    callable `rhs` takes in a dictionary mapping variables to their matching
    values. This rule replaces all occurrences of `(list, 'x')` with `'x'` if
    `'x'` is a list itself.

    >>> lhs = (list, 'x')
    >>> def repl_list(sd):
    ...     x = sd['x']
    ...     if isinstance(x, list):
    ...         return x
    ...     else:
    ...         return (list, x)
    >>> rule = RewriteRule(lhs, repl_list, variables)
    c         C` s¤   t  | t ƒ s t d ƒ ‚ n  | |  _ t | ƒ r? | |  _ n |  j |  _ | |  _ g  t | ƒ D] } | | k ra | ^ qa |  _	 t t
 t |  j	 ƒ ƒ ƒ |  _ d  S(   Ns!   vars must be a tuple of variables(   R   R&   t	   TypeErrort   lhst   callableR   t   _applyt   rhsR   t   _varlistt   sortedt   sett   vars(   R   R.   R1   R5   t   t(    (    s+   lib/python2.7/site-packages/dask/rewrite.pyR   ¯   s    		.c         C` s<   |  j  } x, | j ƒ  D] \ } } t | | | ƒ } q W| S(   N(   R1   t   itemsR   (   R   t   sub_dictR   t   keyt   val(    (    s+   lib/python2.7/site-packages/dask/rewrite.pyR0   ¼   s    	c         C` s   d j  |  j |  j |  j ƒ S(   Ns   RewriteRule({0}, {1}, {2})(   t   formatR.   R1   R5   (   R   (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyt   __str__Â   s    c         C` s
   t  |  ƒ S(   N(   t   str(   R   (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyR"   Æ   s    (    (   R   R   R   R   R0   R<   R"   (    (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyR,   ‚   s
   +		t   RuleSetc           B` s>   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d d „ Z RS(   s?  A set of rewrite rules.

    Forms a structure for fast rewriting over a set of rewrite rules. This
    allows for syntactic matching of terms to patterns for many patterns at
    the same time.

    Examples
    --------

    >>> def f(*args): pass
    >>> def g(*args): pass
    >>> def h(*args): pass
    >>> from operator import add

    >>> rs = RuleSet(                 # Make RuleSet with two Rules
    ...         RewriteRule((add, 'x', 0), 'x', ('x',)),
    ...         RewriteRule((f, (g, 'x'), 'y'),
    ...                     (h, 'x', 'y'),
    ...                     ('x', 'y')))

    >>> rs.rewrite((add, 2, 0))       # Apply ruleset to single task
    2

    >>> rs.rewrite((f, (g, 'a', 3)))  # doctest: +SKIP
    (h, 'a', 3)

    >>> dsk = {'a': (add, 2, 0),      # Apply ruleset to full dask graph
    ...        'b': (f, (g, 'a', 3))}

    >>> from toolz import valmap
    >>> valmap(rs.rewrite, dsk)  # doctest: +SKIP
    {'a': 2,
     'b': (h, 'a', 3)}

    Attributes
    ----------
    rules : list
        A list of `RewriteRule`s included in the `RuleSet`.
    c         G` s7   t  ƒ  |  _ g  |  _ x | D] } |  j | ƒ q Wd S(   s—   Create a `RuleSet` for a number of rules

        Parameters
        ----------
        rules
            One or more instances of RewriteRule
        N(   R%   t   _nett   rulest   add(   R   R@   t   p(    (    s+   lib/python2.7/site-packages/dask/rewrite.pyR   ó   s    	c         C` sÛ   t  | t ƒ s t d ƒ ‚ n  | j } |  j } t |  j ƒ } xn t | j ƒ D]] } | } | | k rp t	 } n  | | j
 k r | j
 | } qO t ƒ  | j
 | <| j
 | } qO W| j
 | j j | ƒ |  j j | ƒ d S(   se   Add a rule to the RuleSet.

        Parameters
        ----------
        rule : RewriteRule
        s$   rule must be instance of RewriteRuleN(   R   R,   R-   R5   R?   t   lenR@   R   R.   t   VARR)   R%   R*   t   append(   R   t   ruleR5   t	   curr_nodet   indR6   t	   prev_node(    (    s+   lib/python2.7/site-packages/dask/rewrite.pyRA      s    			c         c` sz   t  | ƒ } xg t | |  j ƒ D]S \ } } xD | D]< } |  j | } t | | ƒ } | d k	 r2 | | f Vq2 q2 Wq Wd S(   sl  A generator that lazily finds matchings for term from the RuleSet.

        Parameters
        ----------
        term : task

        Yields
        ------
        Tuples of `(rule, subs)`, where `rule` is the rewrite rule being
        matched, and `subs` is a dictionary mapping the variables in the lhs
        of the rule to their matching values in the term.N(   R   t   _matchR?   R@   t   _process_matchR   (   R   R   t   St   mt   symst   iRF   R   (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyt   iter_matches  s    c         C` s4   x- |  j  | ƒ D] \ } } | j | ƒ } Pq W| S(   s7   Apply the rewrite rules in RuleSet to top level of term(   RP   R   (   R   R   RF   t   sd(    (    s+   lib/python2.7/site-packages/dask/rewrite.pyt   _rewrite0  s    t	   bottom_upc         C` s   t  | |  | ƒ S(   se  Apply the `RuleSet` to `task`.

        This applies the most specific matching rule in the RuleSet to the
        task, using the provided strategy.

        Parameters
        ----------
        term: a task
            The task to be rewritten
        strategy: str, optional
            The rewriting strategy to use. Options are "bottom_up" (default),
            or "top_level".

        Examples
        --------
        Suppose there was a function `add` that returned the sum of 2 numbers,
        and another function `double` that returned twice its input:

        >>> add = lambda x, y: x + y
        >>> double = lambda x: 2*x

        Now suppose `double` was *significantly* faster than `add`, so
        you'd like to replace all expressions `(add, x, x)` with `(double,
        x)`, where `x` is a variable. This can be expressed as a rewrite rule:

        >>> rule = RewriteRule((add, 'x', 'x'), (double, 'x'), ('x',))
        >>> rs = RuleSet(rule)

        This can then be applied to terms to perform the rewriting:

        >>> term = (add, (add, 2, 2), (add, 2, 2))
        >>> rs.rewrite(term)  # doctest: +SKIP
        (double, (double, 2))

        If we only wanted to apply this to the top level of the term, the
        `strategy` kwarg can be set to "top_level".

        >>> rs.rewrite(term)  # doctest: +SKIP
        (double, (add, 2, 2))
        (   t
   strategies(   R   R   t   strategy(    (    s+   lib/python2.7/site-packages/dask/rewrite.pyt   rewrite;  s    )(   R   R   R   R   RA   RP   RR   RV   (    (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyR>   Ê   s   '				c         C` s   |  j  | ƒ S(   N(   RR   (   t   netR   (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyt
   _top_levelg  s    c         ` s…   t  | ƒ r> t | ƒ f t ‡  f d †  t | ƒ Dƒ ƒ } n: t | t ƒ rx g  t | ƒ D] } t ˆ  | ƒ ^ qZ } n  ˆ  j | ƒ S(   Nc         3` s   |  ] } t  ˆ  | ƒ Vq d  S(   N(   t
   _bottom_up(   t   .0R6   (   RW   (    s+   lib/python2.7/site-packages/dask/rewrite.pys	   <genexpr>m  s    (   R   R	   R&   R
   R   R   RY   RR   (   RW   R   R6   (    (   RW   s+   lib/python2.7/site-packages/dask/rewrite.pyRY   k  s
    2+t	   top_levelRS   c         c` s0  t  ƒ  } t } d } xt r+|  j t k r> | j | f Vn  y[ | j j |  j d ƒ } | r˜ | r˜ | j	 |  j
 ƒ  | | f ƒ | } |  j ƒ  w n  Wn t k
 r¬ n X| j j t d ƒ } | rô t } | |  j f } |  j ƒ  | } q n  y | j ƒ  \ }  } } t } Wq t k
 r'd SXq Wd S(   s;   Structural matching of term S to discrimination net node N.N(    (   R   t   Falset   TrueR   R   R*   R)   t   getR   RE   R   R   R-   RD   R   R   R   t	   Exception(   RL   t   NR   t   restore_state_flagt   matchest   n(    (    s+   lib/python2.7/site-packages/dask/rewrite.pyRJ   w  s6    		



c         C` s„   i  } |  j  } t | ƒ t | ƒ k s6 t d ƒ ‚ n  xG t | | ƒ D]6 \ } } | | k rr | | | k rr d S| | | <qF W| S(   sÉ  Process a match to determine if it is correct, and to find the correct
    substitution that will convert the term into the pattern.

    Parameters
    ----------
    rule : RewriteRule
    syms : iterable
        Iterable of subterms that match a corresponding variable.

    Returns
    -------
    A dictionary of {vars : subterms} describing the substitution to make the
    pattern equivalent with the term. Returns `None` if the match is
    invalid.s/   length of varlist doesn't match length of syms.N(   R2   RC   t   RuntimeErrort   zipR   (   RF   RN   R   t   varlistt   vt   s(    (    s+   lib/python2.7/site-packages/dask/rewrite.pyRK     s    	N(   t
   __future__R    R   R   t   collectionsR   t	   dask.coreR   R   R	   R
   t   objectR   R    RD   R   R&   R%   R,   R>   RX   RY   RT   RJ   RK   (    (    (    s+   lib/python2.7/site-packages/dask/rewrite.pyt   <module>   s"   		<H		

	&