U
    ZÊ¹j©  ã                   @   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| f|žŽ S )Né   z0Binary relation takes two arguments, but got %s.)ÚlenÚ
ValueErrorr   )ÚselfÚargs© r   ú`/var/www/html/bwave/python/venv/lib/python3.8/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ks|t jkrd S | j}|d k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 k	r|S |\}}| j|||d�}|d k	r:|S | jr|t|ƒt|ƒf}| jj|Ž | jjt|ƒŽ k	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k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k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kV  qd S r   )Úkindr   )Ú.0Zsider   r   r   Ú	<genexpr>ª   s     z5AppliedBinaryRelation.reversedsign.<locals>.<genexpr>)r6   r   Úanyr4   r"   r#   r7   r   r   r   Úreversedsign¢   s    z"AppliedBinaryRelation.reversedsignc                 C   s&   | j j}|d k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|kr^ˆ  |t|ƒ |jŽ ¡ q6ˆ  |¡ q6t‡ fdd„| | jfD ƒƒrŠdS | j| jjt| dd�t| jdd�f}t‡ fdd„|D ƒƒrÈdS | j | j|¡}|d k	rä|S tdd„ | jD ƒƒ}| j ||¡S )Nc                 3   s   | ]}|ˆ kV  qd S r   r   ©r9   Úrel©Zconj_assumpsr   r   r:   À   s     z2AppliedBinaryRelation._eval_ask.<locals>.<genexpr>TFr=   c                 3   s   | ]}|ˆ kV  qd S r   r   r?   rA   r   r   r:   Ä   s     c                 s   s   | ]}|  ¡ V  qd S r   )Úsimplify)r9   Úar   r   r   r:   Í   s     )Úsetr	   r   Úeqr
   Úner   Úgtr   Últr   Úger   Úler   ÚfuncÚaddr'   r   r;   r   r    r   r6   r+   r4   Útuple)r   r%   ZbinrelpredsrC   Zneg_relsr)   r   r   rA   r   Ú	_eval_askµ   s$    (
ÿzAppliedBinaryRelation._eval_askc                 C   s    t | ƒ}|d k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    rN   rP   r   r   r   r   r   ‡   s   


	

N)r/   Útypingr   Zsympy.core.singletonr   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