
    Ed                         d Z ddlmZ ddlmZ ddlmZmZmZm	Z	 ddl
mZ ddlmZmZmZmZmZmZ ddlmZmZ dd	gZ G d
 de          Z G d d	e          ZdS )z
General binary relations.
    )Optional)S)AppliedPredicateask	PredicateQ)BooleanKind)EqNeGtLtGeLe)	conjunctsNotBinaryRelationAppliedBinaryRelationc                       e Zd ZU dZdZee         ed<   dZee         ed<   d Z	e
d             Ze
d             Zd Zdd
ZdS )r   a^  
    Base class for all binary relational predicates.

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

    Binary relation takes two arguments and returns ``AppliedBinaryRelation``
    instance. To evaluate it to boolean value, use :obj:`~.ask()` or
    :obj:`~.refine()` function.

    You can add support for new types by registering the handler to dispatcher.
    See :obj:`~.Predicate()` for more information about predicate dispatching.

    Examples
    ========

    Applying and evaluating to boolean value:

    >>> from sympy import Q, ask, sin, cos
    >>> from sympy.abc import x
    >>> Q.eq(sin(x)**2+cos(x)**2, 1)
    Q.eq(sin(x)**2 + cos(x)**2, 1)
    >>> ask(_)
    True

    You can define a new binary relation by subclassing and dispatching.
    Here, we define a relation $R$ such that $x R y$ returns true if
    $x = y + 1$.

    >>> from sympy import ask, Number, Q
    >>> from sympy.assumptions import BinaryRelation
    >>> class MyRel(BinaryRelation):
    ...     name = "R"
    ...     is_reflexive = False
    >>> Q.R = MyRel()
    >>> @Q.R.register(Number, Number)
    ... def _(n1, n2, assumptions):
    ...     return ask(Q.zero(n1 - n2 - 1), assumptions)
    >>> Q.R(2, 1)
    Q.R(2, 1)

    Now, we can use ``ask()`` to evaluate it to boolean value.

    >>> ask(Q.R(2, 1))
    True
    >>> ask(Q.R(1, 2))
    False

    ``Q.R`` returns ``False`` with minimum cost if two arguments have same
    structure because it is antireflexive relation [1] by
    ``is_reflexive = False``.

    >>> ask(Q.R(x, x))
    False

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Reflexive_relation
    Nis_reflexiveis_symmetricc                     t          |          dk    st          dt          |          z            t          | g|R  S )N   z0Binary relation takes two arguments, but got %s.)len
ValueErrorr   )selfargss     Alib/python3.11/site-packages/sympy/assumptions/relation/binrel.py__call__zBinaryRelation.__call__P   sI    4yyA~ 	]ORUVZR[R[[\\\$T1D1111    c                     | j         r| S d S N)r   r   s    r   reversedzBinaryRelation.reversedU   s     	Ktr   c                     d S r!    r"   s    r   negatedzBinaryRelation.negated[   s    tr   c                 ~    |t           j        u s|t           j        u rd S | j        }|n|r||k    rdS |s||k    rdS d S )NTF)r   NaNr   )r   lhsrhs	reflexives       r   _compare_reflexivez!BinaryRelation._compare_reflexive_   sl     !%< 	3!%< 	4%	 	 	C3J 	4 	s
 	5tr   Tc                 4    | j         | }||S |\  }}|                     |||          }||S | j        rat          |          t          |          f} | j        j        |  | j        j        t          |           ur|                     |||          }|S )N)assumptions)r,   handlerr   typedispatchr#   )r   r   r.   retr)   r*   typess          r   evalzBinaryRelation.evalq   s    %d%t, 	J Sll3l== 	J  	F#YYS		*E$t|$e,4IDL4I8TY??4[[ Fll3lEE
r   )T)__name__
__module____qualname____doc__r   r   bool__annotations__r   r   propertyr#   r&   r,   r4   r%   r   r   r   r      s         ; ;z $(L(4.'''#'L(4.'''2 2 2
   X
   X  $     r   c                       e Zd ZdZed             Zed             Zed             Zed             Zed             Z	d Z
d Zd	S )
r   zd
    The class of expressions resulting from applying ``BinaryRelation``
    to the arguments.

    c                     | j         d         S )z#The left-hand side of the relation.r   	argumentsr"   s    r   r)   zAppliedBinaryRelation.lhs        ~a  r   c                     | j         d         S )z$The right-hand side of the relation.   r>   r"   s    r   r*   zAppliedBinaryRelation.rhs   r@   r   c                 N    | j         j        }|| S  || j        | j                  S )zE
        Try to return the relationship with sides reversed.
        )functionr#   r*   r)   r   revfuncs     r   r#   zAppliedBinaryRelation.reversed   s1    
 -( 	Kwtx***r   c                     | j         j        }|| S t          d | j        D                       s || j         | j                   S | S )zE
        Try to return the relationship with signs reversed.
        Nc              3   2   K   | ]}|j         t          u V  d S r!   )kindr	   ).0sides     r   	<genexpr>z5AppliedBinaryRelation.reversedsign.<locals>.<genexpr>   s)      GG49+GGGGGGr   )rD   r#   anyr?   r)   r*   rE   s     r   reversedsignz"AppliedBinaryRelation.reversedsign   s[    
 -( 	KGGGGGGG 	17DH9txi000r   c                 T    | j         j        }|t          | d          S  || j         S )NFevaluate)rD   r&   r   r?   )r   neg_rels     r   r&   zAppliedBinaryRelation.negated   s6    -' 	-te,,,,w''r   c                 ^   t                      t          t          j        t          t          j        t          t          j        t          t          j	        t          t          j        t          t          j        i}t          |          D ]Q}|j        |v r1                     |t#          |                   |j                    <                    |           Rt'          fd| | j        fD                       rdS | j        | j        j        t-          | d          t-          | j        d          f}t'          fd|D                       rdS | j                            | j        |          }||S t5          d | j        D                       }| j                            ||          S )Nc              3       K   | ]}|v V  	d S r!   r%   rJ   relconj_assumpss     r   rL   z2AppliedBinaryRelation._eval_ask.<locals>.<genexpr>   s(      DDssl"DDDDDDr   TFrP   c              3       K   | ]}|v V  	d S r!   r%   rU   s     r   rL   z2AppliedBinaryRelation._eval_ask.<locals>.<genexpr>   s(      77ssl"777777r   c              3   >   K   | ]}|                                 V  d S r!   )simplify)rJ   as     r   rL   z2AppliedBinaryRelation._eval_ask.<locals>.<genexpr>   s*      ::aQZZ\\::::::r   )setr
   r   eqr   ner   gtr   ltr   ger   ler   funcaddr0   r   rM   r#   r&   r   rD   r4   r?   tuple)r   r.   binrelpredsr[   neg_relsr2   r   rW   s          @r   	_eval_askzAppliedBinaryRelation._eval_ask   s   uu14QT2qtRr14QTR;'' 	$ 	$Av$ $  !5T!WW!5qv!>????  #### DDDDtT].CDDDDD 	4L$-"7TE9R9R9R...07777h77777 	5 m  == 	J ::4>:::::}!!$444r   c                 L    t          |           }|t          d| z            |S )Nz"Cannot determine truth value of %s)r   	TypeError)r   r2   s     r   __bool__zAppliedBinaryRelation.__bool__   s/    $ii 	I@4GHHH
r   N)r5   r6   r7   r8   r;   r)   r*   r#   rN   r&   rh   rk   r%   r   r   r   r      s          ! ! X! ! ! X! + + X+ 	 	 X	 ( ( X(5 5 56    r   N)r8   typingr   sympy.core.singletonr   sympy.assumptionsr   r   r   r   sympy.core.kindr	   sympy.core.relationalr
   r   r   r   r   r   sympy.logic.boolalgr   r   __all__r   r   r%   r   r   <module>rs      s0          " " " " " " A A A A A A A A A A A A ' ' ' ' ' ' 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 . . . . . . . .4
5u u u u uY u u upM M M M M, M M M M Mr   