
    g}                         d Z ddlmZ  G d d          Z G d d          Z G d d          Zdd
Zd Zd Zd Z	d Z
d Zd Zd Z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                   *    e Zd ZdZd Zd Zd Z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                 "    || _         || _        d S N)opargs)selfr   r	   s      L/var/www/html/ai-engine/env/lib/python3.11/site-packages/sympy/unify/core.py__init__zCompound.__init__   s    			    c                 ~    t          |           t          |          u o| j        |j        k    o| j        |j        k    S r   )typer   r	   r
   others     r   __eq__zCompound.__eq__   s<    T

d5kk) (dg.A (	UZ'	)r   c                 T    t          t          |           | j        | j        f          S r   )hashr   r   r	   r
   s    r   __hash__zCompound.__hash__"   s!    T$ZZ$)4555r   c                     t          | j                  dd                    t          t           | j                            dS )N[z, ])strr   joinmapr	   r   s    r   __str__zCompound.__str__%   s7    tw<<<<3sDI3F3F)G)G)G)GHHr   N__name__
__module____qualname____doc__r   r   r   r    r   r   r   r      s_           ) ) )6 6 6I I I I Ir   r   c                   *    e Zd ZdZd Zd Zd Zd ZdS )Variablez A Wild token c                     || _         d S r   )arg)r
   r'   s     r   r   zVariable.__init__*   s    r   c                 ^    t          |           t          |          u o| j        |j        k    S r   )r   r'   r   s     r   r   zVariable.__eq__-   s'    DzzT%[[(BTX-BBr   c                 H    t          t          |           | j        f          S r   )r   r   r'   r   s    r   r   zVariable.__hash__0   s    T$ZZ*+++r   c                 0    dt          | j                  z  S )NzVariable(%s)r   r'   r   s    r   r   zVariable.__str__3   s    DH--r   Nr   r#   r   r   r%   r%   (   sY          C C C, , ,. . . . .r   r%   c                   *    e Zd ZdZd Zd Zd Zd ZdS )CondVariablez A wild token that matches conditionally.

    arg   - a wild token.
    valid - an additional constraining function on a match.
    c                 "    || _         || _        d S r   )r'   valid)r
   r'   r/   s      r   r   zCondVariable.__init__<   s    


r   c                 ~    t          |           t          |          u o| j        |j        k    o| j        |j        k    S r   )r   r'   r/   r   s     r   r   zCondVariable.__eq__@   s=    T

d5kk) *EI%*
ek)	+r   c                 T    t          t          |           | j        | j        f          S r   )r   r   r'   r/   r   s    r   r   zCondVariable.__hash__E   s!    T$ZZ4:6777r   c                 0    dt          | j                  z  S )NzCondVariable(%s)r+   r   s    r   r   zCondVariable.__str__H   s    !CMM11r   Nr   r#   r   r   r-   r-   6   sZ         
  + + +
8 8 82 2 2 2 2r   r-   Nc              +   d  K   |pi }| |k    r|V  dS t          | t          t          f          rt          | ||fi |E d{V  dS t          |t          t          f          rt          || |fi |E d{V  dS t          | t                    rt          |t                    ri|                    dd           }|                    dd           }t          | j        |j        |fi |D ]} ||           r ||          rt          | j	                  t          |j	                  k     r| |fn|| f\   ||           r' ||          rt          j	        j	        d          }nt          j	        j	        d          }|D ]6\  }}	fd|D             }
fd	|	D             }t          |
||fi |E d{V  7t          | j	                  t          |j	                  k    rt          | j	        |j	        |fi |E d{V   dS t          |           rt          |          r~t          |           t          |          k    r`t          |           d
k    r|V  dS t          | d
         |d
         |fi |D ]-}t          | dd         |dd         |fi |E d{V  (dS dS dS 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                     dS NFr#   xs    r   <lambda>zunify.<locals>.<lambda>k       U r   is_associativec                     dS r6   r#   r7   s    r   r9   zunify.<locals>.<lambda>l   r:   r   commutativeassociativec                 T    g | ]$}t          t          j        |                    %S r#   unpackr   r   ).0r'   as     r   
<listcomp>zunify.<locals>.<listcomp>u   -    HHH#&!$!4!455HHHr   c                 T    g | ]$}t          t          j        |                    %S r#   r@   )rB   r'   bs     r   rD   zunify.<locals>.<listcomp>v   rE   r   r      )
isinstancer%   r-   	unify_varr   getunifyr   lenr	   allcombinationsis_args)r8   ysfnsr4   r;   sopcombsaaargsbbargsaabbsheadrC   rG   s                @@r   rL   rL   K   s     . 	
RAAvv	A,/	0	0 =Q1,,,,,,,,,,,,,	A,/	0	0 =Q1,,,,,,,,,,,,,	Ax	 	  =Z8%<%< =!1??CC!1??CCqtQ..#.. 	= 	=C~a   =^^A%6%6 =!$QVs16{{!:!:1vvA1!>!$$ K):): K+AFAFMJJEE+AFAFMJJE&+ 9 9NFFHHHHHHHBHHHHHHHB$RS88C88888888889 QVAF++ <<<<<<<<<<<	= 	= 
 =

 =s1vvQ'7'7q66Q;;GGGGGqtQqT14444 = = 122!""u<<<<<<<<<<<<= = = ='7'7= =r   c              +   B  K   | |v rt          ||          ||fi |E d {V  d S t          | |          rd S t          | t                    r*|                     |          rt          || |          V  d S t          | t                    rt          || |          V  d S d S r   )rL   occur_checkrI   r-   r/   assocr%   )varr8   rQ   rR   s       r   rJ   rJ      s      
axx3A-------------	S!		 	C	&	& 399Q<< AsA	C	"	" AsA r   c                       |k    rdS t          |t                    rt           |j                  S t	          |          rt           fd|D                       rdS dS )z# var occurs in subtree owned by x? Tc              3   8   K   | ]}t          |          V  d S r   )r[   )rB   xir]   s     r   	<genexpr>zoccur_check.<locals>.<genexpr>   s-      00{3##000000r   F)rI   r   r[   r	   rO   any)r]   r8   s   ` r   r[   r[      so    
axxt	Ax	 	  >3'''	 >0000a00000=5r   c                 8    |                                  } || |<   | S )z- Return copy of d with key associated to val )copy)dkeyvals      r   r\   r\      s    	AAcFHr   c                 H    t          |           t          t          t          fv S )z Is x a traditional iterable? )r   tuplelistsetr7   s    r   rO   rO      s    77udC(((r   c                 z    t          | t                    r%t          | j                  dk    r| j        d         S | S )NrH   r   )rI   r   rM   r	   r7   s    r   rA   rA      s7    !X 3qv;;!#3#3vayr   c           	   #     K   |dk    rd}|dk    rd}t          |           t          |          k     r| |fn|| f\  }}t          t          t          t          |                              t          |          |          D ]_}||k    r,t	          d | D                       t          ||          fV  4t          | |          t	          d |D                       fV  `d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              3      K   | ]}|fV  d S r   r#   )rB   rC   s     r   ra   z"allcombinations.<locals>.<genexpr>   s$      ((((((((r   c              3      K   | ]}|fV  d S r   r#   )rB   rG   s     r   ra   z"allcombinations.<locals>.<genexpr>   s$      +<+<QQD+<+<+<+<+<+<r   )rM   r   rj   rangeri   	partition)ABro   smbgparts         r   rN   rN      s     F --1vvAaVVQFFBd5R>>**CGGWEEE = =77((a((((()At*<*<<<<<<At$$e+<+<!+<+<+<&<&<<<<<<	= =r   c                 L      t                      f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                 0    g | ]}t          |          S r#   )index)rB   indits     r   rD   zpartition.<locals>.<listcomp>   s!    444U2s^^444r   r   )r}   rx   s   ` r   rs   rs      s0     4884444t444555r   c                 L      t                      f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                      g | ]
}|         S r#   r#   )rB   ir}   s     r   rD   zindex.<locals>.<listcomp>   s    (((qRU(((r   r~   )r}   r|   s   ` r   r{   r{      s0     488((((C((()))r   r   )r"   sympy.utilities.iterablesr   r   r%   r-   rL   rJ   r[   r\   rO   rA   rN   rs   r{   r#   r   r   <module>r      s;   $ , + + + + +I I I I I I I I&. . . . . . . .2 2 2 2 2 2 2 2*5= 5= 5= 5=n      ) ) )  ,= ,= ,=\
6 
6 
6
* 
* 
* 
* 
*r   