o
    i:                     @   s~  d dl mZ d dl mZ d dl mZ d dlmZ d dlmZ d dl	m
  m  mZ d dlmZ d dlZd dlmZ d dlmZ d	d
lmZ d	dlmZ d dlm
  mZ d dlZdd Zdd Zdd Zdededej de!e!e"df df fddZ#dededej deeej f fddZ$dededej deeej f fddZdededej de%fddZ&dededej ddfdd Z'dS )!    )	_parse_op)
Invocation)solve)SyntaxError)ExpressionIndicatorN)defaultdict)Mapping   )
_is_scalar)Tensorc              	   C   s   t t}| D ],}| D ]%}t|tjr1|jd}||d  t	dd |dd  D |j
f qqi }| D ]1\}}tjdd |D ddd }tj|d	d
}	|D ]\}
}||	|
< qT|	jdkrft|	}	|	||< q9|S )N.r   c                 s       | ]}t |V  qd S Nint).0t r   K/home/ubuntu/.local/lib/python3.10/site-packages/einx/_src/frontend/util.py	<genexpr>       z!_exprs_to_axes.<locals>.<genexpr>r	   c                 S   s   g | ]\}}|qS r   r   )r   coordvaluer   r   r   
<listcomp>       z"_exprs_to_axes.<locals>.<listcomp>)axisint32)dtyper   )r   listnodes
isinstancestage3Axisnamesplitappendtupler   itemsnpamaxzerosshaper   )exprsvaluesrootexprtokensvalues2r#   xsr+   r   r   vr   r   r   _exprs_to_axes   s$   .


r4   c           	   	   C   s   t | ddd |D i d}d| v rt| }t| |dddzt|  dd |d	d
\}}t|||||d	|d\}}W |S  tyI   |rF Y d S w )N	operationc                 S   sB   g | ]}|d urt jjjd |dnt jjjd d tjd ddqS )Nr+   )type)r+   concrete)tracer	signature	classicalr   ConvertibleTensortypesSimpleNamespace)r   r+   r   r   r   r   *   s    z_solve.<locals>.<listcomp>)r#   tensorskwargsz->z7The expression must not contain a '->' operator.
%EXPR%)posmessagez ->T)el_op
invocationallow_concat)
cse_concatcse)r   r   r   get_pos_for_literalr   _solve2	Exception)	descriptiontensor_shapes
parametersreraiserG   rD   	indicatorexprs_in	exprs_outr   r   r   _solve&   s(   rR   c                 C   sX   | d u rd S zt dd | jD W S    Y t| rdS t| r"d S tdt|  d)Nc                 s   r   r   r   )r   xr   r   r   r   D   r   z_get_shape.<locals>.<genexpr>r   zFound z& which is not a valid tensor argument.)r&   r+   r
   callable
ValueErrorr7   )tensorr   r   r   
_get_shape@   s   rW   rK   r?   rM   return.c                 O   s.   t | dd |D |ddd}tdd |D S )aD  Solve for the shapes of the einx expressions under the given constraints.

    Args:
        description: Comma-separated list of tensor expressions in einx notation.
        *tensors: Tensors matching the description string. Accepts ``None`` for unknown
            shapes.
        **parameters: Additional parameters that specify dimension sizes, e.g. ``a=4``.

    Returns:
        A tuple of shapes corresponding to the input tensors.

    Example:
        >>> x = np.random.rand(3, 4)
        >>> einx.solve_shapes("a b, c b a", x, None, c=3)
        ((3, 4), (5, 4, 3))
    c                 S      g | ]}t |qS r   rW   r   rV   r   r   r   r   `   r   z solve_shapes.<locals>.<listcomp>TrN   rG   c                 s   s    | ]}|j V  qd S r   r6   )r   r/   r   r   r   r   a   s    zsolve_shapes.<locals>.<genexpr>)rR   r&   rK   r?   rM   r,   r   r   r   solve_shapesO   s   r^   c                 O   s$   t | dd |D |ddd}t|S )a  Solve for the length of all axes in an expression under the given constraints.

    Args:
        description: Comma-separated list of tensor expressions in einx notation.
        *tensors: Tensors matching the description string. Accepts ``None`` for unknown
            shapes.
        **parameters: Additional parameters that specify dimension sizes, e.g. ``a=4``.

    Returns:
        A mapping from axis name to their lengths. If an axis is used with an ellipsis,
        the lengths are given as a list of integers.

    Example:
        >>> x = np.random.rand(3, 4)
        >>> einx.solve_axes("a b, c b a", x, None, c=3)
        {'a': 3, 'b': 4, 'c': 3}
        >>> einx.solve_axes("a..., c a...", x, None, c=3)
        {'a': array([3, 4], dtype=int32), 'c': 3}
    c                 S   rY   r   rZ   r[   r   r   r   r   x   r   zsolve_axes.<locals>.<listcomp>TFr\   )rR   r4   r]   r   r   r   
solve_axesd   s   r_   c                 O   s   t | g|R i |S )z6This function is an alias for :func:`einx.solve_axes`.)r_   rK   r?   rM   r   r   r   r   |   s   r   c                 O   s*   zt | g|R i | W dS    Y dS )a  Returns whether the given tensors match the einx expression description under the
    given constraints.

    Args:
        description: Comma-separated list of tensor expressions in einx notation.
        *tensors: Tensors matching the description string. Accepts ``None`` for unknown
            shapes.
        **parameters: Additional parameters that specify dimension sizes, e.g. ``a=4``.

    Returns:
        True if the tensors and constraints match the description, False otherwise.

    Example:
        >>> x = np.random.rand(3, 4)
        >>> einx.matches("a b", x)
        True
        >>> einx.matches("a b c", x)
        False
    TF)r^   r`   r   r   r   matches   s
   ra   c                 O   s0   t jdtdd t| dd |D |ddd d S )Nz^einx.check is deprecated and will be removed in a future release. Please call einx.id instead.   )
stacklevelc                 S   rY   r   rZ   r[   r   r   r   r      r   zcheck.<locals>.<listcomp>Tr\   )warningswarnDeprecationWarningrR   r`   r   r   r   check   s    rg   )('einx._src.adapter.einx_from_namedtensorr   r   r   rI   einx._src.frontend.errorsr   einx._src.namedtensorr   einx._src.namedtensor.stage3_srcnamedtensorr!   collectionsr   numpyr(   numpy.typingtypingnptcollections.abcr   apir
   r=   r   einx._src.tracerr9   r4   rR   rW   str	ArrayLiker&   r   r^   r_   boolra   rg   r   r   r   r   <module>   s,    ,&& 