
    \h-                         S r SSKJr  SSKJr  SSKJrJrJrJ	r	J
r
   " S S\5      r " S S	\\S
9r " S S\5      r\" 5       r " S S\5      r\" 5       r " S S\5      r\" 5       r " S S5      rg)ax  
Module to efficiently partition SymPy objects.

This system is introduced because class of SymPy object does not always
represent the mathematical classification of the entity. For example,
``Integral(1, x)`` and ``Integral(Matrix([1,2]), x)`` are both instance
of ``Integral`` class. However the former is number and the latter is
matrix.

One way to resolve this is defining subclass for each mathematical type,
such as ``MatAdd`` for the addition between matrices. Basic algebraic
operation such as addition or multiplication take this approach, but
defining every class for every mathematical object is not scalable.

Therefore, we define the "kind" of the object and let the expression
infer the kind of itself from its arguments. Function and class can
filter the arguments by their kind, and behave differently according to
the type of itself.

This module defines basic kinds for core objects. Other kinds such as
``ArrayKind`` or ``MatrixKind`` can be found in corresponding modules.

.. notes::
       This approach is experimental, and can be replaced or deleted in the future.
       See https://github.com/sympy/sympy/pull/20549.
    )defaultdict   )cacheit)
Dispatcherambiguity_warn#ambiguity_register_error_ignore_dupstr_signatureRaiseNotImplementedErrorc                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )KindMeta$   z
Metaclass for ``Kind``.

Assigns empty ``dict`` as class attribute ``_inst`` for every class,
in order to endow singleton-like behavior.
c                 .   > 0 US'   [         TU ]  XX#5      $ )N_instsuper__new__)clsclsnamebasesdct	__class__s       G/var/www/auris/envauris/lib/python3.13/site-packages/sympy/core/kind.pyr   KindMeta.__new__+   s    GwsU88     __name__
__module____qualname____firstlineno____doc__r   __static_attributes____classcell__r   s   @r   r   r   $   s    9 9r   r   c                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )Kind0   a  
Base class for kinds.

Kind of the object represents the mathematical classification that
the entity falls into. It is expected that functions and classes
recognize and filter the argument by its kind.

Kind of every object must be carefully selected so that it shows the
intention of design. Expressions may have different kind according
to the kind of its arguments. For example, arguments of ``Add``
must have common kind since addition is group operator, and the
resulting ``Add()`` has the same kind.

For the performance, each kind is as broad as possible and is not
based on set theory. For example, ``NumberKind`` includes not only
complex number but expression containing ``S.Infinity`` or ``S.NaN``
which are not strictly number.

Kind may have arguments as parameter. For example, ``MatrixKind()``
may be constructed with one element which represents the kind of its
elements.

``Kind`` behaves in singleton-like fashion. Same signature will
return the same object.

c                    > XR                   ;   a  U R                   U   nU$ [        TU ]	  U 5      nX R                   U'   U$ N)r   r   r   )r   argsinstr   s      r   r   Kind.__new__K   sA    9999T?D  7?3'D"IIdOr   r   r   r$   s   @r   r&   r&   0   s    4 r   r&   )	metaclassc                   2   ^  \ rS rSrSrU 4S jrS rSrU =r$ )_UndefinedKindT   z
Default kind for all SymPy object. If the kind is not defined for
the object, or if the object cannot infer the kind from its
arguments, this will be returned.

Examples
========

>>> from sympy import Expr
>>> Expr().kind
UndefinedKind
c                 "   > [         TU ]  U 5      $ r)   r   r   r   s    r   r   _UndefinedKind.__new__a       ws##r   c                     g)NUndefinedKindr   selfs    r   __repr___UndefinedKind.__repr__d   s    r   r   	r   r   r   r    r!   r   r9   r"   r#   r$   s   @r   r/   r/   T   s    $ r   r/   c                   2   ^  \ rS rSrSrU 4S jrS rSrU =r$ )_NumberKindj   a  
Kind for all numeric object.

This kind represents every number, including complex numbers,
infinity and ``S.NaN``. Other objects such as quaternions do not
have this kind.

Most ``Expr`` are initially designed to represent the number, so
this will be the most common kind in SymPy core. For example
``Symbol()``, which represents a scalar, has this kind as long as it
is commutative.

Numbers form a field. Any operation between number-kind objects will
result this kind as well.

Examples
========

>>> from sympy import S, oo, Symbol
>>> S.One.kind
NumberKind
>>> (-oo).kind
NumberKind
>>> S.NaN.kind
NumberKind

Commutative symbol are treated as number.

>>> x = Symbol('x')
>>> x.kind
NumberKind
>>> Symbol('y', commutative=False).kind
UndefinedKind

Operation between numbers results number.

>>> (x+1).kind
NumberKind

See Also
========

sympy.core.expr.Expr.is_Number : check if the object is strictly
subclass of ``Number`` class.

sympy.core.expr.Expr.is_number : check if the object is number
without any free symbol.

c                 "   > [         TU ]  U 5      $ r)   r   r2   s    r   r   _NumberKind.__new__   r4   r   c                     g)N
NumberKindr   r7   s    r   r9   _NumberKind.__repr__   s    r   r   r;   r$   s   @r   r=   r=   j   s    0b$ r   r=   c                   2   ^  \ rS rSrSrU 4S jrS rSrU =r$ )_BooleanKind   a  
Kind for boolean objects.

SymPy's ``S.true``, ``S.false``, and built-in ``True`` and ``False``
have this kind. Boolean number ``1`` and ``0`` are not relevant.

Examples
========

>>> from sympy import S, Q
>>> S.true.kind
BooleanKind
>>> Q.even(3).kind
BooleanKind
c                 "   > [         TU ]  U 5      $ r)   r   r2   s    r   r   _BooleanKind.__new__   r4   r   c                     g)NBooleanKindr   r7   s    r   r9   _BooleanKind.__repr__   s    r   r   r;   r$   s   @r   rE   rE      s    $ r   rE   c                   T    \ rS rSrSrSS jrS rS rS r\	S 5       r
\S	 5       rS
rg)KindDispatcher   a  
Dispatcher to select a kind from multiple kinds by binary dispatching.

.. notes::
   This approach is experimental, and can be replaced or deleted in
   the future.

Explanation
===========

SymPy object's :obj:`sympy.core.kind.Kind()` vaguely represents the
algebraic structure where the object belongs to. Therefore, with
given operation, we can always find a dominating kind among the
different kinds. This class selects the kind by recursive binary
dispatching. If the result cannot be determined, ``UndefinedKind``
is returned.

Examples
========

Multiplication between numbers return number.

>>> from sympy import NumberKind, Mul
>>> Mul._kind_dispatcher(NumberKind, NumberKind)
NumberKind

Multiplication between number and unknown-kind object returns unknown kind.

>>> from sympy import UndefinedKind
>>> Mul._kind_dispatcher(NumberKind, UndefinedKind)
UndefinedKind

Any number and order of kinds is allowed.

>>> Mul._kind_dispatcher(UndefinedKind, NumberKind)
UndefinedKind
>>> Mul._kind_dispatcher(NumberKind, UndefinedKind, NumberKind)
UndefinedKind

Since matrix forms a vector space over scalar field, multiplication
between matrix with numeric element and number returns matrix with
numeric element.

>>> from sympy.matrices import MatrixKind
>>> Mul._kind_dispatcher(MatrixKind(NumberKind), NumberKind)
MatrixKind(NumberKind)

If a matrix with number element and another matrix with unknown-kind
element are multiplied, we know that the result is matrix but the
kind of its elements is unknown.

>>> Mul._kind_dispatcher(MatrixKind(NumberKind), MatrixKind(UndefinedKind))
MatrixKind(UndefinedKind)

Parameters
==========

name : str

commutative : bool, optional
    If True, binary dispatch will be automatically registered in
    reversed order as well.

doc : str, optional

Nc                 H    Xl         X0l        X l        [        U5      U l        g r)   )namedoccommutativer   _dispatcher)r8   rP   rR   rQ   s       r   __init__KindDispatcher.__init__  s    	&%d+r   c                      SU R                   -  $ )Nz<dispatched %s>)rP   r7   s    r   r9   KindDispatcher.__repr__  s     499,,r   c                   ^ ^^ TR                  SS5      nU(       d  T R                  (       a  [        nO[        nTR	                  US9  [        T5      S:X  d&  [        S[        T5      < S[        T5      < S35      eUU U4S jnU$ )	z
Register the binary dispatcher for two kind classes.

If *self.commutative* is ``True``, signature in reversed order is
automatically registered as well.
on_ambiguityN)rY      z+Only binary dispatch is supported, but got z	 types: <z>.c                    > TR                   R                  " TU 40 TD6  TR                  (       a1  TR                   R                  " [        [	        T5      5      U 40 TD6  g g r)   )rS   addrR   tuplereversed)funckwargsr8   typess    r   _"KindDispatcher.register.<locals>._  sP      77  $$U8E?%;TLVL  r   )poprR   r   r   updatelenRuntimeErrorr	   )r8   ra   r`   rY   rb   s   ```  r   registerKindDispatcher.register
  sq     zz.$7B-<05zQE
M%0 
	M r   c                     U R                   (       a  [        U5      nO&/ nS nU H  nXELd  M	  UR                  U5        UnM     U R                  " U40 UD6$ r)   )rR   	frozensetappenddispatch_kinds)r8   r*   r`   kindsprevas         r   __call__KindDispatcher.__call__%  sU    dOEED=LLOD  ""53F33r   c                 F   [        U5      S:X  a)  Uu  n[        U[        5      (       d  [        SU-  5      eU$ [	        U5       H  u  pE[        U[        5      (       d  [        SU-  5      eUS:X  a  UnM2  Wn[        U5      [        U5      pXepU R                  R                  Xx5      nUc.  U R                  (       a  U R                  R                  X5      nXpUc  [        nOU" X5      n[        U[        5      (       a  M  [        SR                  XeU5      5      e   W$ )Nr   z%s is not a kind.r   z=Dispatcher for {!r} and {!r} must return a Kind, but got {!r})rf   
isinstancer&   rg   	enumeratetyperS   dispatchrR   r6   format)r8   rn   r`   resultikind	prev_kindt1t2k1k2r_   s               r   rm   KindDispatcher.dispatch_kinds1  s    u:?GFfd++"#6#?@@M&FAdD))"#6#=>>Av"	i$t*B"B''008<D$4$4++44R<D<*F!"\F!&$//&W^^! - '6 r   c                    SU R                   -  S/nU R                  (       a  UR                  U R                  5        SnUS[        U5      -  -  nUR                  U5        / n[	        [
        5      nU R                  R                  S S S2    H/  nU R                  R                  U   nXF   R                  U5        M1     UR                  5        H  u  puSR                  S U 5       5      n[        U[        5      (       a  UR                  U5        ME  SU-  nUS	[        U5      -  S
-   -  nUR                  (       a  X'R                  R                  5       -  nOX'R                  -  nUR                  U5        M     U(       aF  SnUS[        U5      -  -  nUR                  U5        S
R                  U5      nUR                  U5        SR                  U5      $ )NzKind dispatcher : %sz`Note that support for this is experimental. See the docs for :class:`KindDispatcher` for detailszRegistered kind classes
=z, c              3   >   #    U  H  nS [        U5      -  v   M     g7f)z<%s>N)r	   ).0sigs     r   	<genexpr>)KindDispatcher.__doc__.<locals>.<genexpr>n  s      M-*<!<s   zInputs: %s
-
zAmbiguous kind classes
z

)rP   rQ   rl   rf   r   listrS   orderingfuncsitemsjoinrt   r
   r!   stripr   )	r8   docssamb_sigstyp_sigssigskeyr_   sigs_strs	            r   r!   KindDispatcher.__doc__W  s    #TYY.n

 88KK!'	S3q6\At$$$--dd3D""((.CM  & 4 #..*JDyy M MMH$ 899))As1v$$A||\\''))]]"KKN +  *As1vAKKN		(#AKKN{{4  r   )rS   rR   rQ   rP   )FN)r   r   r   r    r!   rT   r9   rh   rq   r   rm   propertyr"   r   r   r   rM   rM      sF    AD,-6
4 # #J ,! ,!r   rM   N)r!   collectionsr   cacher   !sympy.multipledispatch.dispatcherr   r   r   r	   r
   rv   r   objectr&   r/   r6   r=   rB   rE   rJ   rM   r   r   r   <module>r      s   6 $ - -
	9t 	9!6X !HT &  6$ 6p ]
4 , nF! F!r   