ó
~9­\c           @  s  d  Z  d d l m Z m Z d d l m Z m Z d „  Z e d „ Z	 d „  Z
 d „  Z d „  Z d	 „  Z d
 e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ e e j d <e e j d <e e j d <d S(   s”   Logic expressions handling

NOTE
----

at present this is mainly needed for facts.py , feel free however to improve
this stuff for general purpose.
iÿÿÿÿ(   t   print_functiont   division(   t   ranget   string_typesc         C  sa   t  } } xP |  D]H } | t k r6 | r- d St } q | t  k rU | rL d St } q d Sq W| S(   sè   Return True if all args are True, False if they
    are all False, else None.

    >>> from sympy.core.logic import _torf
    >>> _torf((True, True))
    True
    >>> _torf((False, False))
    False
    >>> _torf((True, False))
    N(   t   Falset   True(   t   argst   sawTt   sawFt   a(    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyt   _torf   s    
		c         C  sT   t  } xF |  D]> } | t k r% q n  | d k r5 d S| rE | rE d St } q W| S(   sí  Return True if all args are True, None if there is any None else False
    unless ``quick_exit`` is True (then return None as soon as a second False
    is seen.

     ``_fuzzy_group`` is like ``fuzzy_and`` except that it is more
    conservative in returning a False, waiting to make sure that all
    arguments are True or False and returning None if any arguments are
    None. It also has the capability of permiting only a single False and
    returning None if more than one is seen. For example, the presence of a
    single transcendental amongst rationals would indicate that the group is
    no longer rational; but a second transcendental in the group would make the
    determination impossible.


    Examples
    ========

    >>> from sympy.core.logic import _fuzzy_group

    By default, multiple Falses mean the group is broken:

    >>> _fuzzy_group([False, False, True])
    False

    If multiple Falses mean the group status is unknown then set
    `quick_exit` to True so None can be returned when the 2nd False is seen:

    >>> _fuzzy_group([False, False, True], quick_exit=True)

    But if only a single False is seen then the group is known to
    be broken:

    >>> _fuzzy_group([False, True, True], quick_exit=True)
    False

    N(   R   R   t   None(   R   t
   quick_exitt	   saw_otherR	   (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyt   _fuzzy_group(   s    %
c         C  s0   |  d k r d S|  t t f k r, t |  ƒ Sd S(   s‡  Return True, False or None according to x.

    Whereas bool(x) returns True or False, fuzzy_bool allows
    for the None value and non-false values (which become None), too.

    Examples
    ========

    >>> from sympy.core.logic import fuzzy_bool
    >>> from sympy.abc import x
    >>> fuzzy_bool(x), fuzzy_bool(None)
    (None, None)
    >>> bool(x), bool(None)
    (True, False)

    N(   R   R   R   t   bool(   t   x(    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyt
   fuzzy_boolY   s    c         C  sF   t  } x9 |  D]1 } t | ƒ } | t k r/ t S| r | } q q W| S(   sÌ  Return True (all True), False (any False) or None.

    Examples
    ========

    >>> from sympy.core.logic import fuzzy_and
    >>> from sympy import Dummy

    If you had a list of objects to test the commutivity of
    and you want the fuzzy_and logic applied, passing an
    iterator will allow the commutativity to only be computed
    as many times as necessary. With this list, False can be
    returned after analyzing the first symbol:

    >>> syms = [Dummy(commutative=False), Dummy()]
    >>> fuzzy_and(s.is_commutative for s in syms)
    False

    That False would require less work than if a list of pre-computed
    items was sent:

    >>> fuzzy_and([s.is_commutative for s in syms])
    False
    (   R   R   R   (   R   t   rvt   ai(    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyt	   fuzzy_andp   s    c         C  s   |  d k r |  S|  Sd S(   sò   
    Not in fuzzy logic

    Return None if `v` is None else `not v`.

    Examples
    ========

    >>> from sympy.core.logic import fuzzy_not
    >>> fuzzy_not(True)
    False
    >>> fuzzy_not(None)
    >>> fuzzy_not(False)
    True

    N(   R   (   t   v(    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyt	   fuzzy_not”   s    c         C  s   t  t d „  |  Dƒ ƒ ƒ S(   s³  
    Or in fuzzy logic. Returns True (any True), False (all False), or None

    See the docstrings of fuzzy_and and fuzzy_not for more info.  fuzzy_or is
    related to the two by the standard De Morgan's law.

    >>> from sympy.core.logic import fuzzy_or
    >>> fuzzy_or([True, False])
    True
    >>> fuzzy_or([True, None])
    True
    >>> fuzzy_or([False, False])
    False
    >>> print(fuzzy_or([False, None]))
    None

    c         s  s   |  ] } t  | ƒ Vq d  S(   N(   R   (   t   .0t   i(    (    s/   lib/python2.7/site-packages/sympy/core/logic.pys	   <genexpr>½   s    (   R   R   (   R   (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyt   fuzzy_or«   s    t   Logicc           B  sq   e  Z d  Z i  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d „  Z e Z e d	 „  ƒ Z RS(
   s   Logical expressionc         G  s   t  j |  ƒ } | | _ | S(   N(   t   objectt   __new__R   (   t   clsR   t   obj(    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyR   Å   s    	c         C  s   |  j  S(   N(   R   (   t   self(    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyt   __getnewargs__Ê   s    c         C  s#   t  t |  ƒ j f t |  j ƒ ƒ S(   N(   t   hasht   typet   __name__t   tupleR   (   R   (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyt   __hash__Í   s    c         C  s-   t  | t |  ƒ ƒ s t S|  j | j k Sd  S(   N(   t
   isinstanceR"   R   R   (   R	   t   b(    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyt   __eq__Ð   s    c         C  s-   t  | t |  ƒ ƒ s t S|  j | j k Sd  S(   N(   R&   R"   R   R   (   R	   R'   (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyt   __ne__Ö   s    c         C  s   |  j  | ƒ d k r t St S(   Niÿÿÿÿ(   t   __cmp__R   R   (   R   t   other(    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyt   __lt__Ü   s    c         C  se   t  |  ƒ t  | ƒ k	 r? t t  |  ƒ ƒ } t t  | ƒ ƒ } n |  j } | j } | | k | | k  S(   N(   R"   t   strR   (   R   R+   R	   R'   (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyR*   á   s    		c         C  s*   d |  j  j d j d „  |  j Dƒ ƒ f S(   Ns   %s(%s)s   , c         s  s   |  ] } t  | ƒ Vq d  S(   N(   R-   (   R   R	   (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pys	   <genexpr>ì   s    (   t	   __class__R#   t   joinR   (   R   (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyt   __str__ê   s    c         C  s  d } d } x.|  j ƒ  D] } | d k r{ | d k	 rP t d | | f ƒ ‚ n  | d k ro t d | ƒ ‚ n  | } q n  d | k s“ d | k r¢ t d ƒ ‚ n  | d d k ræ t | ƒ d	 k rÓ t d
 ƒ ‚ n  t | d	 ƒ } n  | rt j | | | ƒ } d } q n  | d k	 r3t d | | f ƒ ‚ n  | } q W| d k	 r\t d |  ƒ ‚ n  | d k r{t d |  ƒ ‚ n  | S(   sn   Logic from string with space around & and | but none after !.

           e.g.

           !a & b | c
        s   &|s   double op forbidden: "%s %s"s+   %s cannot be in the beginning of expressiont   &t   |s#   & and | must have space around themi    t   !i   s   do not include space after "!"s    missing op between "%s" and "%s"s#   premature end-of-expression in "%s"s   "%s" is emptyN(   R   t   splitt
   ValueErrort   lent   NotR   t	   op_2class(   t   textt   lexprt   schedopt   term(    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyt
   fromstringð   s>    
(   R#   t
   __module__t   __doc__R8   R   R    R%   R(   R)   R,   R*   R0   t   __repr__t   staticmethodR=   (    (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyR   À   s   									t
   AndOr_Basec           B  s    e  Z d  „  Z e d „  ƒ Z RS(   c         G  sÞ   g  } xD | D]< } | |  j  k r& | S| |  j  k r< q n  | j | ƒ q Wt t |  j | ƒ ƒ d t ƒ} x' | D] } t | ƒ | k ru |  j  Squ Wt | ƒ d k r´ | j ƒ  St | ƒ d k rÎ |  j  St	 j
 |  | Œ S(   Nt   keyi   i    (   t	   op_x_notxt   appendt   sortedt   sett   flattenR!   R7   R6   t   popR   R   (   R   R   t   bargsR	   (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyR   %  s     !
c         C  s›   t  | ƒ } g  } xv t rŠ y | j d ƒ } Wn t k
 rB Pn Xt | t ƒ rz t | |  ƒ rz | j | j ƒ q qz n  | j | ƒ q Wt	 | ƒ } | S(   Ni    (
   t   listR   RI   t
   IndexErrorR&   R   t   extendR   RE   R$   (   R   R   t
   args_queuet   rest   arg(    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyRH   ;  s    		(   R#   R>   R   t   classmethodRH   (    (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyRB   #  s   	t   Andc           B  s    e  Z e Z d  „  Z d „  Z RS(   c         C  s&   t  g  |  j D] } t | ƒ ^ q Œ  S(   N(   t   OrR   R7   (   R   R	   (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyt   _eval_propagate_notS  s    c         C  sà   xÙ t  t |  j ƒ ƒ D]¾ } |  j | } t | t ƒ r |  j |  |  j | d } g  | j D] } t | | f Œ  ^ q^ } xD t  t | ƒ ƒ D]0 } t | | t ƒ r | | j ƒ  | | <q q Wt | Œ  } | Sq W|  Sd  S(   Ni   (   R   R6   R   R&   RS   RR   R   t   expand(   R   R   RP   t   arestR	   t   ortermst   jRO   (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyRU   X  s    )(   R#   R>   R   RD   RT   RU   (    (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyRR   P  s   	RS   c           B  s   e  Z e Z d  „  Z RS(   c         C  s&   t  g  |  j D] } t | ƒ ^ q Œ  S(   N(   RR   R   R7   (   R   R	   (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyRT   o  s    (   R#   R>   R   RD   RT   (    (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyRS   l  s   R7   c           B  s    e  Z d  „  Z e d „  ƒ Z RS(   c         C  sƒ   t  | t ƒ r t j |  | ƒ St  | t ƒ r3 | St  | t ƒ rM | j d St  | t ƒ rl | j ƒ  } | St d | f ƒ ‚ d  S(   Ni    s   Not: unknown argument %r(	   R&   R   R   R   R   R7   R   RT   R5   (   R   RP   (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyR   v  s    c         C  s   |  j  d S(   Ni    (   R   (   R   (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyRP   ‡  s    (   R#   R>   R   t   propertyRP   (    (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyR7   t  s   	R1   R2   R3   N(   R?   t
   __future__R    R   t   sympy.core.compatibilityR   R   R
   R   R   R   R   R   R   R   R   RB   RR   RS   R7   R8   (    (    (    s/   lib/python2.7/site-packages/sympy/core/logic.pyt   <module>   s    	1		$		c-