U
    ‰d/  ã                   @   sŠ   d dl mZmZ d dlmZ d dlmZmZ d dlm	Z	m
Z
 G dd„ deƒZG dd„ deƒZeƒ Zd	d
„ Zdd„ Zefdd„Zdd„ ZdS )é   )ÚunifyÚreify©Úisvar)Ú	_toposortÚfreeze)ÚgroupbyÚfirstc                   @   s4   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ ZdS )Ú
Dispatcherc                 C   s   || _ tƒ | _g | _d S ©N)ÚnameÚdictÚfuncsÚordering)Úselfr   © r   úK/tmp/pip-unpacked-wheel-ua33x9lu/torch/fx/experimental/unification/match.pyÚ__init__   s    zDispatcher.__init__c                 C   s   || j t|ƒ< t| j ƒ| _d S r   )r   r   r   )r   Ú	signatureÚfuncr   r   r   Úadd   s    zDispatcher.addc                 O   s   |   |¡\}}|||ŽS r   )Úresolve)r   ÚargsÚkwargsr   Úsr   r   r   Ú__call__   s    zDispatcher.__call__c                 C   sp   t |ƒ}| jD ]>}t |ƒ|kr qtt|ƒ|ƒ}|dk	r| j| }||f  S qtdt| jƒ d t|ƒ ƒ‚d S )NFz No match found. 
Known matches: z
Input: )Úlenr   r   r   r   ÚNotImplementedErrorÚstr)r   r   Únr   r   Úresultr   r   r   r      s    

ÿÿÿzDispatcher.resolvec                    s   ‡ ‡fdd„}|S )Nc                    s   ˆ   ˆ| ¡ ˆ S r   )r   )r   ©r   r   r   r   Ú_"   s    zDispatcher.register.<locals>._r   )r   r   r"   r   r!   r   Úregister!   s    zDispatcher.registerN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r#   r   r   r   r   r
      s
   r
   c                   @   s   e Zd ZdZdd„ ZdS )ÚVarDispatchera?   A dispatcher that calls functions with variable names
    >>> d = VarDispatcher('d')
    >>> x = var('x')
    >>> @d.register('inc', x)
    ... def f(x):
    ...     return x + 1
    >>> @d.register('double', x)
    ... def f(x):
    ...     return x * 2
    >>> d('inc', 10)
    11
    >>> d('double', 10)
    20
    c                 O   s.   |   |¡\}}tdd„ | ¡ D ƒƒ}|f |ŽS )Nc                 s   s   | ]\}}|j |fV  qd S r   )Útoken©Ú.0ÚkÚvr   r   r   Ú	<genexpr>8   s     z)VarDispatcher.__call__.<locals>.<genexpr>)r   r   Úitems)r   r   r   r   r   Údr   r   r   r   6   s    zVarDispatcher.__call__N)r$   r%   r&   Ú__doc__r   r   r   r   r   r'   '   s   r'   c                     s,   |  dt¡‰|  dt¡‰ ‡ ‡‡fdd„}|S )NÚ	namespacer
   c                    s2   | j }|ˆkrˆ |ƒˆ|< ˆ| }| ˆ| ¡ |S r   )r$   r   )r   r   r/   ©Ú
dispatcherr1   r   r   r   r"   E   s    zmatch.<locals>._)ÚgetÚglobal_namespacer
   )r   r   r"   r   r2   r   ÚmatchA   s    
r6   c                 C   sh   t |ƒrt | ƒsdS t| |ƒ}|dkr*dS tdd„ | ¡ D ƒƒ}t| |ƒ| krRdS t||ƒ|krddS dS )z+ ``a`` is a more specific match than ``b`` TFc                 s   s*   | ]"\}}t |ƒrt |ƒs||fV  qd S r   r   r)   r   r   r   r-   Y   s       zsupercedes.<locals>.<genexpr>N)r   r   r   r.   r   )ÚaÚbr   r   r   r   Ú
supercedesR   s    
r9   c                 C   s,   t | |ƒr(t || ƒr$|| ƒ||ƒkS dS dS )zV A should be checked before B
    Tie broken by tie_breaker, defaults to ``hash``
    TF)r9   )r7   r8   Ztie_breakerr   r   r   Úedgea   s
    

r:   c                    sb   t ttˆ ƒƒ‰ ‡ fdd„ˆ D ƒ}tt|ƒ}ˆ D ]}||kr.g ||< q.tdd„ | ¡ D ƒƒ}t|ƒS )z‚ A sane ordering of signatures to check, first to last
    Topoological sort of edges as given by ``edge`` and ``supercedes``
    c                    s(   g | ] }ˆ D ]}t ||ƒr||f‘qqS r   )r:   ©r*   r7   r8   ©Ú
signaturesr   r   Ú
<listcomp>s   s
       
 zordering.<locals>.<listcomp>c                 s   s$   | ]\}}|d d„ |D ƒfV  qdS )c                 S   s   g | ]\}}|‘qS r   r   r;   r   r   r   r>   x   s     z&ordering.<locals>.<genexpr>.<listcomp>Nr   r)   r   r   r   r-   x   s     zordering.<locals>.<genexpr>)ÚlistÚmapÚtupler   r	   r   r.   r   )r=   Úedgesr   r   r<   r   r   n   s    

r   N)Úcorer   r   Úvariabler   Úutilsr   r   Zunification_toolsr   r	   Úobjectr
   r'   r   r5   r6   r9   Úhashr:   r   r   r   r   r   Ú<module>   s    