o
    8VaN                     @   s   d 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 deZG d
d deZdS )z
General binary relations.
    )S)AppliedPredicateask	PredicateQ)BooleanKind)EqNeGtLtGeLe)	conjunctsNotBinaryRelationAppliedBinaryRelationc                   @   sJ   e Zd ZdZdZdZdd Zedd Zedd Z	d	d
 Z
d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
    Nc                 G   s,   t |dkstdt | t| g|R  S )N   z0Binary relation takes two arguments, but got %s.)len
ValueErrorr   )selfargs r   C/usr/lib/python3/dist-packages/sympy/assumptions/relation/binrel.py__call__O   s   zBinaryRelation.__call__c                 C   s   | j r| S d S N)is_symmetricr   r   r   r   reversedT   s   zBinaryRelation.reversedc                 C   s   d S r   r   r   r   r   r   negatedZ   s   zBinaryRelation.negatedc                 C   sP   |t ju s
|t ju rd S | j}|d u r	 d S |r||krdS |s&||kr&dS d S )NTF)r   ZNaNis_reflexive)r   lhsrhsZ	reflexiver   r   r   _compare_reflexive^   s   z!BinaryRelation._compare_reflexiveTc                 C   s   | j | }|d ur|S |\}}| j|||d}|d ur|S | jr>t|t|f}| jj| | jjt| ur>| j|||d}|S )N)assumptions)r"   Zhandlerr   typedispatchr   )r   r   r#   retr    r!   typesr   r   r   evalp   s   
zBinaryRelation.eval)T)__name__
__module____qualname____doc__r   r   r   propertyr   r   r"   r(   r   r   r   r   r      s    =

c                   @   s\   e Zd ZdZedd Zedd Zedd Zedd	 Zed
d Z	dd Z
dd ZdS )r   zd
    The class of expressions resulting from applying ``BinaryRelation``
    to the arguments.

    c                 C   
   | j d S )z#The left-hand side of the relation.r   	argumentsr   r   r   r   r          
zAppliedBinaryRelation.lhsc                 C   r.   )z$The right-hand side of the relation.   r/   r   r   r   r   r!      r1   zAppliedBinaryRelation.rhsc                 C   s"   | j j}|du r
| S || j| jS )zE
        Try to return the relationship with sides reversed.
        N)functionr   r!   r    r   Zrevfuncr   r   r   r      s   zAppliedBinaryRelation.reversedc                 C   s>   | j j}|du r
| S tdd | jD s|| j | j S | S )zE
        Try to return the relationship with signs reversed.
        Nc                 s   s    | ]}|j tu V  qd S r   )kindr   ).0Zsider   r   r   	<genexpr>   s    z5AppliedBinaryRelation.reversedsign.<locals>.<genexpr>)r3   r   anyr0   r    r!   r4   r   r   r   reversedsign   s   z"AppliedBinaryRelation.reversedsignc                 C   s&   | j j}|d u rt| ddS || j S )NFZevaluate)r3   r   r   r0   )r   Zneg_relr   r   r   r      s   
zAppliedBinaryRelation.negatedc                    s  t   ttjttjttjttj	t
tjttji}t|D ]}|j|v r. ||j |j  q | qt fdd| | jfD rDdS | j| jjt| ddt| jddf}t fdd|D rcdS | j| j|}|d urq|S tdd | jD }| j||S )Nc                 3       | ]}| v V  qd S r   r   r6   ZrelZconj_assumpsr   r   r7          z2AppliedBinaryRelation._eval_ask.<locals>.<genexpr>TFr:   c                 3   r;   r   r   r<   r=   r   r   r7      r>   c                 s   s    | ]}|  V  qd S r   )Zsimplify)r6   ar   r   r   r7      r>   )setr   r   eqr	   ner
   gtr   ltr   ger   ler   funcaddr   r8   r   r   r   r3   r(   r0   tuple)r   r#   Zbinrelpredsr?   Zneg_relsr&   r   r   r=   r   	_eval_ask   s$   (
zAppliedBinaryRelation._eval_askc                 C   s    t | }|d u rtd|  |S )Nz"Cannot determine truth value of %s)r   	TypeError)r   r&   r   r   r   __bool__   s   zAppliedBinaryRelation.__bool__N)r)   r*   r+   r,   r-   r    r!   r   r9   r   rJ   rL   r   r   r   r   r      s    


	

N)r,   Zsympyr   Zsympy.assumptionsr   r   r   r   Zsympy.core.kindr   Zsympy.core.relationalr   r	   r
   r   r   r   Zsympy.logic.boolalgr   r   __all__r   r   r   r   r   r   <module>   s     x