
    g                         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y)z
General binary relations.
    )Optional)S)AppliedPredicateask	PredicateQ)BooleanKind)EqNeGtLtGeLe)	conjunctsNotBinaryRelationAppliedBinaryRelationc                   n    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y)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                 d    t        |      dk(  st        dt        |      z        t        | g| S )N   z0Binary relation takes two arguments, but got %s.)len
ValueErrorr   )selfargss     V/var/www/openai/venv/lib/python3.12/site-packages/sympy/assumptions/relation/binrel.py__call__zBinaryRelation.__call__P   s5    4yA~ORUVZR[[\\$T1D11    c                      | j                   r| S y N)r   r   s    r   reversedzBinaryRelation.reversedU   s    Kr   c                      y r!    r"   s    r   negatedzBinaryRelation.negated[   s    r   c                     |t         j                  u s|t         j                  u ry | j                  }|	 y |r||k(  ry|s||k(  ryy )NTF)r   NaNr   )r   lhsrhs	reflexives       r   _compare_reflexivez!BinaryRelation._compare_reflexive_   sR     !%%<3!%%<%%	
 	 C3Js
r   c                 H    | j                   | }||S |\  }}| j                  |||      }||S | j                  ret        |      t        |      f} | j                  j                  |  | j                  j                  t        |       ur| j                  |||      }|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 #YS	*E$t||$$e,4IDLL4I4I8TY?4[[ll3l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
  
  $r   c                   l    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y	)
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                 p    | 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   s2    
 --((?Ktxx**r   c                     | j                   j                  }|| S t        d | j                  D              s || j                   | j
                         S | S )zE
        Try to return the relationship with signs reversed.
        c              3   @   K   | ]  }|j                   t        u   y wr!   )kindr	   ).0sides     r   	<genexpr>z5AppliedBinaryRelation.reversedsign.<locals>.<genexpr>   s     G499+s   )rD   r#   anyr?   r)   r*   rE   s     r   reversedsignz"AppliedBinaryRelation.reversedsign   sM    
 --((?KGGGDHH9txxi00r   c                 j    | j                   j                  }|t        | d      S  || j                   S )NFevaluate)rD   r&   r   r?   )r   neg_rels     r   r&   zAppliedBinaryRelation.negated   s2    --''?te,,''r   c                 x   t               t        t        j                  t        t        j
                  t        t        j                  t        t        j                  t        t        j                  t        t        j                  i}t        |      D ]L  }|j                  |v r+j!                   |t#        |         |j$                          <j!                  |       N t'        fd| | j(                  fD              ry| j*                  | j(                  j*                  t-        | d      t-        | j(                  d      f}t'        fd|D              ry| j.                  j1                  | j2                  |      }||S t5        d | j2                  D              }| j.                  j1                  ||      S )Nc              3   &   K   | ]  }|v  
 y wr!   r%   rJ   relconj_assumpss     r   rL   z2AppliedBinaryRelation._eval_ask.<locals>.<genexpr>   s     D.Cssl".C   TFrP   c              3   &   K   | ]  }|v  
 y wr!   r%   rU   s     r   rL   z2AppliedBinaryRelation._eval_ask.<locals>.<genexpr>   s     7hssl"hrX   c              3   <   K   | ]  }|j                           y wr!   )simplify)rJ   as     r   rL   z2AppliedBinaryRelation._eval_ask.<locals>.<genexpr>   s     :>aQZZ\>s   )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=   u144QTT2qttRr144QTTR;'Avv$  !5T!W!5qvv!>?  #	 ( DtT]].CDDLL$--"7"7TE9R.07h77 mm  =?J :4>>::}}!!$44r   c                 <    t        |       }|t        d| z        |S )Nz"Cannot determine truth value of %s)r   	TypeError)r   r2   s     r   __bool__zAppliedBinaryRelation.__bool__   s&    $i;@4GHH
r   N)r5   r6   r7   r8   r;   r)   r*   r#   rN   r&   ri   rl   r%   r   r   r   r      su     ! ! ! ! + + 	 	 ( (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>rt      sM     " A A ' 8 8 .4
5uY upM, Mr   