U
    ˜9%e}  ã                   @   sˆ   d Z ddlmZ G dd„ dƒZG dd„ dƒZG dd„ dƒZdd
d„Zdd„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zd	S )aG   Generic Unification algorithm for expression trees with lists of children

This implementation is a direct translation of

Artificial Intelligence: A Modern Approach by Stuart Russel and Peter Norvig
Second edition, section 9.2, page 276

It is modified in the following ways:

1.  We allow associative and commutative Compound expressions. This results in
    combinatorial blowup.
2.  We explore the tree lazily.
3.  We provide generic interfaces to symbolic algebra libraries in Python.

A more traditional version can be found here
http://aima.cs.berkeley.edu/python/logic.html
é    )Úkbinsc                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚCompoundzr A little class to represent an interior node in the tree

    This is analogous to SymPy.Basic for non-Atoms
    c                 C   s   || _ || _d S ©N)ÚopÚargs)Úselfr   r   © r   úO/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/sympy/unify/core.pyÚ__init__   s    zCompound.__init__c                 C   s(   t | ƒt |ƒko&| j|jko&| j|jkS r   )Útyper   r   ©r   Úotherr   r   r	   Ú__eq__   s    
ÿzCompound.__eq__c                 C   s   t t| ƒ| j| jfƒS r   )Úhashr   r   r   ©r   r   r   r	   Ú__hash__"   s    zCompound.__hash__c                 C   s    dt | jƒd tt | jƒ¡f S )Nz%s[%s]z, )Ústrr   ÚjoinÚmapr   r   r   r   r	   Ú__str__%   s    zCompound.__str__N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__r
   r   r   r   r   r   r   r	   r      s
   r   c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚVariablez A Wild token c                 C   s
   || _ d S r   )Úarg)r   r   r   r   r	   r
   *   s    zVariable.__init__c                 C   s   t | ƒt |ƒko| j|jkS r   )r   r   r   r   r   r	   r   -   s    zVariable.__eq__c                 C   s   t t| ƒ| jfƒS r   )r   r   r   r   r   r   r	   r   0   s    zVariable.__hash__c                 C   s   dt | jƒ S )NzVariable(%s)©r   r   r   r   r   r	   r   3   s    zVariable.__str__Nr   r   r   r   r	   r   (   s
   r   c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚCondVariablez… A wild token that matches conditionally.

    arg   - a wild token.
    valid - an additional constraining function on a match.
    c                 C   s   || _ || _d S r   )r   Úvalid)r   r   r   r   r   r	   r
   <   s    zCondVariable.__init__c                 C   s(   t | ƒt |ƒko&| j|jko&| j|jkS r   )r   r   r   r   r   r   r	   r   @   s
    
ÿ
þzCondVariable.__eq__c                 C   s   t t| ƒ| j| jfƒS r   )r   r   r   r   r   r   r   r	   r   E   s    zCondVariable.__hash__c                 C   s   dt | jƒ S )NzCondVariable(%s)r   r   r   r   r	   r   H   s    zCondVariable.__str__Nr   r   r   r   r	   r   6   s
   r   Nc                 +   s0  |pi }| |kr|V  nt | ttfƒrBt| ||f|ŽE dH  nêt |ttfƒrjt|| |f|ŽE dH  nÂt | tƒrªt |tƒrª| ddd„ ¡}| ddd„ ¡}t| j|j|f|ŽD ]ð}|| ƒrx||ƒrxt| j	ƒt|j	ƒk rê| |fn|| f\‰ ‰|| ƒr||ƒrt
ˆ j	ˆj	dƒ}nt
ˆ j	ˆj	dƒ}|D ]D\}}	‡ fd	d
„|D ƒ}
‡fdd
„|	D ƒ}t|
||f|ŽE dH  q0q¶t| j	ƒt|j	ƒkr¶t| j	|j	|f|ŽE dH  q¶n‚t| ƒr,t|ƒr,t| ƒt|ƒkr,t| ƒdkræ|V  nFt| d |d |f|ŽD ],}t| dd… |dd… |f|ŽE dH  qþdS )a
   Unify two expressions.

    Parameters
    ==========

        x, y - expression trees containing leaves, Compounds and Variables.
        s    - a mapping of variables to subtrees.

    Returns
    =======

        lazy sequence of mappings {Variable: subtree}

    Examples
    ========

    >>> from sympy.unify.core import unify, Compound, Variable
    >>> expr    = Compound("Add", ("x", "y"))
    >>> pattern = Compound("Add", ("x", Variable("a")))
    >>> next(unify(expr, pattern, {}))
    {Variable(a): 'y'}
    NÚis_commutativec                 S   s   dS ©NFr   ©Úxr   r   r	   Ú<lambda>k   ó    zunify.<locals>.<lambda>Úis_associativec                 S   s   dS r!   r   r"   r   r   r	   r$   l   r%   ÚcommutativeÚassociativec                    s   g | ]}t tˆ j|ƒƒ‘qS r   ©Úunpackr   r   ©Ú.0r   )Úar   r	   Ú
<listcomp>u   s     zunify.<locals>.<listcomp>c                    s   g | ]}t tˆ j|ƒƒ‘qS r   r)   r+   )Úbr   r	   r.   v   s     r   é   )Ú
isinstancer   r   Ú	unify_varr   ÚgetÚunifyr   Úlenr   ÚallcombinationsÚis_args)r#   ÚyÚsÚfnsr    r&   ZsopZcombsZaaargsZbbargsZaaZbbZsheadr   )r-   r/   r	   r4   K   s6    
(&r4   c                 k   sp   | |kr$t ||  ||f|ŽE d H  nHt| |ƒr0n<t| tƒrT|  |¡rTt|| |ƒV  nt| tƒrlt|| |ƒV  d S r   )r4   Úoccur_checkr1   r   r   Úassocr   )Úvarr#   r9   r:   r   r   r	   r2   ‚   s    

r2   c                    sH   ˆ |krdS t |tƒr"tˆ |jƒS t|ƒrDt‡ fdd„|D ƒƒrDdS dS )z# var occurs in subtree owned by x? Tc                 3   s   | ]}t ˆ |ƒV  qd S r   )r;   )r,   Úxi©r=   r   r	   Ú	<genexpr>“   s     zoccur_check.<locals>.<genexpr>F)r1   r   r;   r   r7   Úany)r=   r#   r   r?   r	   r;   Œ   s    
 r;   c                 C   s   |   ¡ } || |< | S )z- Return copy of d with key associated to val )Úcopy)ÚdÚkeyÚvalr   r   r	   r<   –   s    r<   c                 C   s   t | ƒtttfkS )z Is x a traditional iterable? )r   ÚtupleÚlistÚsetr"   r   r   r	   r7   œ   s    r7   c                 C   s*   t | tƒr"t| jƒdkr"| jd S | S d S )Nr0   r   )r1   r   r5   r   r"   r   r   r	   r*       s    
r*   c                 c   sª   |dkrd}|dkrd}t | ƒt |ƒk r0| |fn|| f\}}tttt |ƒƒƒt |ƒ|dD ]J}||kr†tdd„ | D ƒƒt||ƒfV  qZt| |ƒtdd„ |D ƒƒfV  qZdS )	a  
    Restructure A and B to have the same number of elements.

    Parameters
    ==========

    ordered must be either 'commutative' or 'associative'.

    A and B can be rearranged so that the larger of the two lists is
    reorganized into smaller sublists.

    Examples
    ========

    >>> from sympy.unify.core import allcombinations
    >>> for x in allcombinations((1, 2, 3), (5, 6), 'associative'): print(x)
    (((1,), (2, 3)), ((5,), (6,)))
    (((1, 2), (3,)), ((5,), (6,)))

    >>> for x in allcombinations((1, 2, 3), (5, 6), 'commutative'): print(x)
        (((1,), (2, 3)), ((5,), (6,)))
        (((1, 2), (3,)), ((5,), (6,)))
        (((1,), (3, 2)), ((5,), (6,)))
        (((1, 3), (2,)), ((5,), (6,)))
        (((2,), (1, 3)), ((5,), (6,)))
        (((2, 1), (3,)), ((5,), (6,)))
        (((2,), (3, 1)), ((5,), (6,)))
        (((2, 3), (1,)), ((5,), (6,)))
        (((3,), (1, 2)), ((5,), (6,)))
        (((3, 1), (2,)), ((5,), (6,)))
        (((3,), (2, 1)), ((5,), (6,)))
        (((3, 2), (1,)), ((5,), (6,)))
    r'   é   r(   N)Úorderedc                 s   s   | ]}|fV  qd S r   r   )r,   r-   r   r   r	   r@   Ð   s     z"allcombinations.<locals>.<genexpr>c                 s   s   | ]}|fV  qd S r   r   )r,   r/   r   r   r	   r@   Ò   s     )r5   r   rG   ÚrangerF   Ú	partition)ÚAÚBrJ   ÚsmÚbgÚpartr   r   r	   r6   ¦   s    #$" r6   c                    s   t ˆ ƒ‡ fdd„|D ƒƒS )z× Partition a tuple/list into pieces defined by indices.

    Examples
    ========

    >>> from sympy.unify.core import partition
    >>> partition((10, 20, 30, 40), [[0, 1, 2], [3]])
    ((10, 20, 30), (40,))
    c                    s   g | ]}t ˆ |ƒ‘qS r   )Úindex)r,   Úind©Úitr   r	   r.   Þ   s     zpartition.<locals>.<listcomp>©r   )rU   rQ   r   rT   r	   rL   Ô   s    
rL   c                    s   t ˆ ƒ‡ fdd„|D ƒƒS )z½ Fancy indexing into an indexable iterable (tuple, list).

    Examples
    ========

    >>> from sympy.unify.core import index
    >>> index([10, 20, 30], (1, 2, 0))
    [20, 30, 10]
    c                    s   g | ]}ˆ | ‘qS r   r   )r,   ÚirT   r   r	   r.   ê   s     zindex.<locals>.<listcomp>rV   )rU   rS   r   rT   r	   rR   à   s    
rR   )N)r   Zsympy.utilities.iterablesr   r   r   r   r4   r2   r;   r<   r7   r*   r6   rL   rR   r   r   r   r	   Ú<module>   s   
7

.