B
    ™‘[Ä#  ã               @   sÜ   d dl mZmZ d dlmZ d dlmZ d dlmZ d dl	m
Z
 d dlmZ d dlmZ d dlmZ d d	lmZmZ d d
lmZmZ d dlmZmZmZmZmZmZ d dlmZ d dl m!Z! d dl"m#Z# G dd„ deƒZ$dS )é    )Úprint_functionÚdivision)ÚS)ÚContains)ÚBasic)ÚTuple)ÚExpr)ÚLambda)Ú
fuzzy_bool)ÚSymbolÚDummy)ÚAndÚ
as_Boolean)ÚSetÚIntervalÚIntersectionÚEmptySetÚUnionÚ	FiniteSet)Úsift)Ú
filldedent)Údispatchc               @   sh   e Zd ZdZejf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dd„ZdS )ÚConditionSeta  
    Set of elements which satisfies a given condition.

    {x | condition(x) is True for x in S}

    Examples
    ========

    >>> from sympy import Symbol, S, ConditionSet, pi, Eq, sin, Interval
    >>> from sympy.abc import x, y, z

    >>> sin_sols = ConditionSet(x, Eq(sin(x), 0), Interval(0, 2*pi))
    >>> 2*pi in sin_sols
    True
    >>> pi/2 in sin_sols
    False
    >>> 3*pi in sin_sols
    False
    >>> 5 in ConditionSet(x, x**2 > 4, S.Reals)
    True

    If the value is not in the base set, the result is false:

    >>> 5 in ConditionSet(x, x**2 > 4, Interval(2, 4))
    False

    Notes
    =====

    Symbols with assumptions should be avoided or else the
    condition may evaluate without consideration of the set:

    >>> n = Symbol('n', negative=True)
    >>> cond = (n > 0); cond
    False
    >>> ConditionSet(n, cond, S.Integers)
    EmptySet()

    In addition, substitution of a dummy symbol can only be
    done with a generic symbol with matching commutativity
    or else a symbol that has identical assumptions. If the
    base set contains the dummy symbol it is logically distinct
    and will be the target of substitution.

    >>> c = ConditionSet(x, x < 1, {x, z})
    >>> c.subs(x, y)
    ConditionSet(x, x < 1, {y, z})

    A second substitution is needed to change the dummy symbol, too:

    >>> _.subs(x, y)
    ConditionSet(y, y < 1, {y, z})

    And trying to replace the dummy symbol with anything but a symbol
    is ignored: the only change possible will be in the base set:

    >>> ConditionSet(y, y < 1, {y, z}).subs(y, 1)
    ConditionSet(y, y < 1, {z})
    >>> _.subs(y, 1)
    ConditionSet(y, y < 1, {z})

    Notes
    =====

    If no base set is specified, the universal set is implied:

    >>> ConditionSet(x, x < 1).base_set
    UniversalSet()

    Although expressions other than symbols may be used, this
    is discouraged and will raise an error if the expression
    is not found in the condition:

    >>> ConditionSet(x + 1, x + 1 < 1, S.Integers)
    ConditionSet(x + 1, x + 1 < 1, Integers)

    >>> ConditionSet(x + 1, x < 1, S.Integers)
    Traceback (most recent call last):
    ...
    ValueError: non-symbol dummy not recognized in condition

    Although the name is usually respected, it must be replaced if
    the base set is another ConditionSet and the dummy symbol
    and appears as a free symbol in the base set and the dummy symbol
    of the base set appears as a free symbol in the condition:

    >>> ConditionSet(x, x < y, ConditionSet(y, x + y < 2, S.Integers))
    ConditionSet(lambda, (lambda < y) & (lambda + x < 2), Integers)

    The best way to do anything with the dummy symbol is to access
    it with the sym property.

    >>> _.subs(_.sym, Symbol('_x'))
    ConditionSet(_x, (_x < y) & (_x + x < 2), Integers)
    c       
         sö  t ˆttfƒr.tˆŽ ‰tˆ Ž ‰ t | ˆˆ |¡S tˆ ƒ‰ t |tƒrJt|Ž }nt |tƒs\t	dƒ‚ˆ t
jkrlt
jS ˆ t
jkrz|S t |tƒrˆ|S d }t |tƒrØt|‡ ‡fdd„ƒ}|d  rÌt|d Ž }t|d  Ž }nt|d Ž S t || ƒrœ|j\}}}ˆ|krtˆ |ƒ‰ n–ˆ|jkr(tˆ | |ˆi¡ƒ‰ nt|ˆ jkrNtˆ  ˆ|i¡|ƒ‰ |‰nNtdƒ}|ˆ jksn||jkrztt|ƒƒ}tˆ  ˆ|i¡| ||i¡ƒ‰ |‰t ˆtƒsÎtdƒ}|ˆ  ˆ|i¡jkrÎtdƒ‚t | ˆˆ |¡}	|d krì|	S t||	ƒS )Nzexpecting set for base_setc                s   t ˆ  ˆ| ¡ƒS )N)r
   Úsubs)Ú_)Ú	conditionÚsym© ú6lib/python3.7/site-packages/sympy/sets/conditionset.pyÚ<lambda>‰   s   z&ConditionSet.__new__.<locals>.<lambda>TÚlambdaz,non-symbol dummy not recognized in condition)Ú
isinstancer   Útupler   r   Ú__new__r   Úsetr   Ú	TypeErrorr   Zfalser   Útruer   Úargsr   Úfree_symbolsZxreplacer   r   ÚstrÚ
ValueErrorr   )
Úclsr   r   Úbase_setZknowZsiftedÚsÚcZdumÚrvr   )r   r   r   r#   s   s^    







zConditionSet.__new__c             C   s
   | j d S )Nr   )r'   )Úselfr   r   r   r   «   s    zConditionSet.<lambda>c             C   s
   | j d S )Né   )r'   )r0   r   r   r   r   ¬   s    c             C   s
   | j d S )Né   )r'   )r0   r   r   r   r   ­   s    c             C   s   | j \}}}|j|j |jB S )N)r'   r(   )r0   r-   r.   Úbr   r   r   r(   ¯   s    zConditionSet.free_symbolsc             C   s    t t| j| jƒ|ƒ| j |¡ƒS )N)r   r	   r   r   r,   Úcontains)r0   Úotherr   r   r   r4   ´   s    zConditionSet.containsc             C   sð   t | jtƒs| S | j\}}}||kr¨| ||¡}t |tƒrš|j|jks`t|jƒdkrŽ|j|jkrŽ|| j	krx|  
|||¡S |  
|| ||¡|¡S ttdƒƒ‚|  
|||¡S | j ||¡}| j	 ||¡}|tjkràt|t||ƒ|ƒS |  
| j||¡S )Nr1   zð
                    A dummy symbol can only be
                    replaced with a symbol having the same
                    assumptions or one having a single assumption
                    having the same commutativity.
                )r!   r   r   r'   r   r   Zassumptions0ÚlenZis_commutativer,   Úfuncr*   r   r   r   r&   r   r   )r0   ÚoldÚnewr   ZcondÚbaser   r   r   Ú
_eval_subs¸   s(    


zConditionSet._eval_subsNc             C   s|   t || jƒsdS t | jtƒt |jtƒkr,dS |r8tdƒ‚|}t | jtƒrtt |jtƒrt| | j|j |j| j¡|j¡}| |kS )NFz)symbol arg not supported for ConditionSet)r!   r7   r   r   r*   r   r   r,   )r0   r5   ZsymbolÚor   r   r   Údummy_eqá   s    zConditionSet.dummy_eq)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ZUniversalSetr#   Úpropertyr   r   r,   r(   r4   r;   r=   r   r   r   r   r      s   _8)r   N)%Z
__future__r   r   Zsympyr   Zsympy.sets.containsr   Zsympy.core.basicr   Zsympy.core.containersr   Zsympy.core.exprr   Zsympy.core.functionr	   Zsympy.core.logicr
   Zsympy.core.symbolr   r   Zsympy.logic.boolalgr   r   Zsympy.sets.setsr   r   r   r   r   r   Zsympy.utilities.iterablesr   Zsympy.utilities.miscr   Zsympy.multipledispatchr   r   r   r   r   r   Ú<module>   s    