a
    RG5d                     @   s   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 deZG d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                   @   sd   e Zd ZU dZdZee ed< dZee ed< 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
    Nis_reflexiveis_symmetricc                 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   ]/var/www/html/django/DPS/env/lib/python3.9/site-packages/sympy/assumptions/relation/binrel.py__call__P   s    zBinaryRelation.__call__c                 C   s   | j r
| S d S N)r   r   r   r   r   reversedU   s    zBinaryRelation.reversedc                 C   s   d S r   r   r   r   r   r   negated[   s    zBinaryRelation.negatedc                 C   sL   |t ju s|t ju rd S | j}|d u r(n |r8||kr8dS |sH||krHdS d S )NTF)r   NaNr   )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$   handlerr   typedispatchr   )r   r   r%   retr"   r#   typesr   r   r   evalq   s    
zBinaryRelation.eval)T)__name__
__module____qualname____doc__r   r   bool__annotations__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   s
   | j d S )z#The left-hand side of the relation.r   	argumentsr   r   r   r   r"      s    zAppliedBinaryRelation.lhsc                 C   s
   | j d S )z$The right-hand side of the relation.   r3   r   r   r   r   r#      s    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   ).0sider   r   r   	<genexpr>       z5AppliedBinaryRelation.reversedsign.<locals>.<genexpr>)r6   r   anyr4   r"   r#   r7   r   r   r   reversedsign   s    z"AppliedBinaryRelation.reversedsignc                 C   s&   | j j}|d u rt| ddS || j S )NFevaluate)r6   r    r   r4   )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 ]2}|j|v r^ |t| |j  q6 | q6t fdd| | jfD rdS | j| jjt| ddt| jddf}t fdd|D rdS | j| j|}|d ur|S tdd | jD }| j||S )Nc                 3   s   | ]}| v V  qd S r   r   r9   relZconj_assumpsr   r   r;      r<   z2AppliedBinaryRelation._eval_ask.<locals>.<genexpr>TFr?   c                 3   s   | ]}| v V  qd S r   r   rA   rC   r   r   r;      r<   c                 s   s   | ]}|  V  qd S r   )simplify)r9   ar   r   r   r;      r<   )setr	   r   eqr
   ner   gtr   ltr   ger   ler   funcaddr'   r   r=   r   r    r   r6   r+   r4   tuple)r   r%   binrelpredsrE   Zneg_relsr)   r   r   rC   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/   r2   r"   r#   r   r>   r    rQ   rS   r   r   r   r   r      s   


	

N)r/   typingr   Zsympy.core.singletonr   sympy.assumptionsr   r   r   r   Zsympy.core.kindr   sympy.core.relationalr	   r
   r   r   r   r   sympy.logic.boolalgr   r   __all__r   r   r   r   r   r   <module>   s    x