
\c           @  s  d  Z  d d l m Z m Z d d l m Z 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 m Z m Z m Z d d	 l m Z m Z 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! m" Z" d d l# m$ Z$ m% Z% d d l& m' Z' d   Z( d e f d     YZ) d e) f d     YZ* d e e e*  f d     YZ+ d e e e*  f d     YZ, e+   Z- e,   Z. e- e _- e. e _. d   e  e/ <d e e) f d     YZ0 d e e0 f d     YZ1 d e e0 f d     YZ2 d  e0 f d!     YZ3 d" e0 f d#     YZ4 d$ e0 f d%     YZ5 d& e0 f d'     YZ6 d( e0 f d)     YZ7 d* e0 f d+     YZ8 d, e0 f d-     YZ9 d. e0 f d/     YZ: d0   Z; d1   Z< d2   Z= d3   Z> d4   Z? e@ d5  ZA eB d6  ZC eB d7  ZD e@ d8  ZE d9   ZF d:   ZG d;   ZH d<   ZI d=   ZJ d>   ZK d?   ZL dR d@  ZN e@ dA  ZO dB   ZP dC   ZQ dD   ZR dE   ZS dF   ZT dG   ZU dH   ZV dR dI  ZW dR dJ  ZX dK   ZY dR e@ eB dL  ZZ dM   Z[ dN   Z\ dO   Z] dP   Z^ dQ   Z_ dR S(S   s"   
Boolean algebra module for SymPy
i(   t   print_functiont   division(   t   defaultdict(   t   combinationst   product(   t   Add(   t   Basic(   t   cacheit(   t   orderedt   ranget   with_metaclasst   as_int(   t   Applicationt
   Derivativet	   count_ops(   t   Number(   t	   LatticeOp(   t	   Singletont   S(   t	   convertert   _sympifyt   sympify(   t   siftt   ibin(   t
   filldedentc         C  s   d d l  m } |  t k r# t j S|  t k r6 t j St |  |  rr |  j } | d k r^ |  S| rk t j St j St |  t
  r |  St d |    d S(   s  Like bool, return the Boolean value of an expression, e,
    which can be any instance of Boolean or bool.

    Examples
    ========

    >>> from sympy import true, false, nan
    >>> from sympy.logic.boolalg import as_Boolean
    >>> from sympy.abc import x
    >>> as_Boolean(1) is true
    True
    >>> as_Boolean(x)
    x
    >>> as_Boolean(2)
    Traceback (most recent call last):
    ...
    TypeError: expecting bool or Boolean, not `2`.
    i(   t   Symbols$   expecting bool or Boolean, not `%s`.N(   t   sympy.core.symbolR   t   TrueR   t   truet   Falset   falset
   isinstancet   is_zerot   Nonet   Booleant	   TypeError(   t   eR   t   z(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt
   as_Boolean   s    	R"   c           B  s   e  Z d  Z g  Z d   Z e Z d   Z e Z d   Z d   Z	 d   Z
 e
 Z e	 Z d   Z e Z d   Z e d  Z d	   Z e d
    Z RS(   sD   A boolean object is an object for which logic operations make sense.c         C  s   t  |  |  S(   s   Overloading for & operator(   t   And(   t   selft   other(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   __and__=   s    c         C  s   t  |  |  S(   s   Overloading for |(   t   Or(   R(   R)   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   __or__C   s    c         C  s
   t  |   S(   s   Overloading for ~(   t   Not(   R(   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt
   __invert__I   s    c         C  s   t  |  |  S(   s   Overloading for >>(   t   Implies(   R(   R)   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt
   __rshift__M   s    c         C  s   t  | |   S(   s   Overloading for <<(   R/   (   R(   R)   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt
   __lshift__Q   s    c         C  s   t  |  |  S(   N(   t   Xor(   R(   R)   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   __xor__X   s    c         C  s   d d l  m } d d l m } |  j |  s> | j |  rM t d   n  |  j   | j   k o~ | t t |  |    S(   s  
        Returns True if the given formulas have the same truth table.
        For two formulas to be equal they must have the same literals.

        Examples
        ========

        >>> from sympy.abc import A, B, C
        >>> from sympy.logic.boolalg import And, Or, Not
        >>> (A >> B).equals(~B >> ~A)
        True
        >>> Not(And(A, B, C)).equals(And(Not(A), Not(B), Not(C)))
        False
        >>> Not(And(A, Not(A))).equals(Or(B, Not(B)))
        False
        i(   t   satisfiable(   t
   Relationals   handling of relationals(	   t   sympy.logic.inferenceR4   t   sympy.core.relationalR5   t   hast   NotImplementedErrort   atomsR-   t
   Equivalent(   R(   R)   R4   R5   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   equals]   s    c         C  s   |  S(   N(    (   R(   t   simplify(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   to_nnfv   s    c         C  s   d d l  m } d d l m } |  j } t |  d k r | j   } i  } x |  j |  D]s } | | |  d	 k r] | j	   } | t
 j t
 j t
 j f k r | j |  | | <q] n  t t d    q] q] W|  j |  j	   St d   d S(
   s  
        Rewrites Boolean expression in terms of real sets.

        Examples
        ========

        >>> from sympy import Symbol, Eq, Or, And
        >>> x = Symbol('x', real=True)
        >>> Eq(x, 0).as_set()
        {0}
        >>> (x > 0).as_set()
        Interval.open(0, oo)
        >>> And(-2 < x, x < 2).as_set()
        Interval.open(-2, 2)
        >>> Or(x < -2, 2 < x).as_set()
        Union(Interval.open(-oo, -2), Interval.open(2, oo))
        i(   t   periodicity(   R5   i   i    s   
                        as_set is not implemented for relationals
                        with periodic solutions
                        sG   Sorry, as_set has not yet been implemented for multivariate expressionsN(   i    N(   t   sympy.calculus.utilR?   R7   R5   t   free_symbolst   lent   popR:   R!   t   _eval_as_setR   t   EmptySett   UniversalSett   Realst   as_relationalR9   R   t   subs(   R(   R?   R5   t   freet   xt   repst   rt   s(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   as_setz   s     	c         C  sf   d d l  m } m } t   j g  |  j D]6 } | j sV | j sV t | | | f  r) | j	 ^ q)   S(   Ni(   t   Eqt   Ne(
   R7   RP   RQ   t   sett   uniont   argst
   is_Booleant	   is_SymbolR   t   binary_symbols(   R(   RP   RQ   t   i(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyRW      s    (   t   __name__t
   __module__t   __doc__t	   __slots__R*   t   __rand__R,   t   __ror__R.   R0   R1   t   __rrshift__t   __rlshift__R3   t   __rxor__R<   R   R>   RO   t   propertyRW   (    (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR"   8   s"   								(t   BooleanAtomc           B  s   e  Z d  Z e Z e Z d Z d   Z d   Z e	 d    Z
 d d  Z e Z e Z e Z e Z e Z e Z e Z e Z e Z e Z e Z e Z e Z e Z e Z d   Z e Z e Z e Z RS(   s5   
    Base class of BooleanTrue and BooleanFalse.
    i   c         O  s   |  S(   N(    (   R(   t   at   kw(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR=      s    c         O  s   |  S(   N(    (   R(   Rd   Re   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   expand   s    c         C  s   |  S(   N(    (   R(   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt	   canonical   s    c         C  s   t  d   d  S(   Ns(   BooleanAtom not allowed in this context.(   R#   (   R(   R)   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   _noop   s    c         C  s&   d d l  m } t | d    d  S(   Ni(   R   s   
            A Boolean argument can only be used in
            Eq and Ne; all other relationals expect
            real expressions.
        (   t   sympy.utilities.miscR   R#   (   R(   R)   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   __lt__   s    N(    RY   RZ   R[   R   RU   t   is_Atomt   _op_priorityR=   Rf   Rb   Rg   R!   Rh   t   __add__t   __radd__t   __sub__t   __rsub__t   __mul__t   __rmul__t   __pow__t   __rpow__t   __rdiv__t   __truediv__t   __div__t   __rtruediv__t   __mod__t   __rmod__t   _eval_powerRj   t   __le__t   __gt__t   __ge__(    (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyRc      s6   			t   BooleanTruec           B  s>   e  Z d  Z d   Z e Z d   Z e d    Z d   Z RS(   sd  
    SymPy version of True, a singleton that can be accessed via S.true.

    This is the SymPy version of True, for use in the logic module. The
    primary advantage of using true instead of True is that shorthand boolean
    operations like ~ and >> will work as expected on this class, whereas with
    True they act bitwise on 1. Functions in the logic module will return this
    class when they evaluate to true.

    Notes
    =====

    There is liable to be some confusion as to when ``True`` should
    be used and when ``S.true`` should be used in various contexts
    throughout SymPy. An important thing to remember is that
    ``sympify(True)`` returns ``S.true``. This means that for the most
    part, you can just use ``True`` and it will automatically be converted
    to ``S.true`` when necessary, similar to how you can generally use 1
    instead of ``S.One``.

    The rule of thumb is:

    "If the boolean in question can be replaced by an arbitrary symbolic
    ``Boolean``, like ``Or(x, y)`` or ``x > 1``, use ``S.true``.
    Otherwise, use ``True``"

    In other words, use ``S.true`` only on those contexts where the
    boolean is being used as a symbolic representation of truth.
    For example, if the object ends up in the ``.args`` of any expression,
    then it must necessarily be ``S.true`` instead of ``True``, as
    elements of ``.args`` must be ``Basic``. On the other hand,
    ``==`` is not a symbolic operation in SymPy, since it always returns
    ``True`` or ``False``, and does so in terms of structural equality
    rather than mathematical, so it should return ``True``. The assumptions
    system should use ``True`` and ``False``. Aside from not satisfying
    the above rule of thumb, the assumptions system uses a three-valued logic
    (``True``, ``False``, ``None``), whereas ``S.true`` and ``S.false``
    represent a two-valued logic. When in doubt, use ``True``.

    "``S.true == True is True``."

    While "``S.true is True``" is ``False``, "``S.true == True``"
    is ``True``, so if there is any doubt over whether a function or
    expression will return ``S.true`` or ``True``, just use ``==``
    instead of ``is`` to do the comparison, and it will work in either
    case.  Finally, for boolean flags, it's better to just use ``if x``
    instead of ``if x is True``. To quote PEP 8:

    Don't compare boolean values to ``True`` or ``False``
    using ``==``.

    * Yes:   ``if greeting:``
    * No:    ``if greeting == True:``
    * Worse: ``if greeting is True:``

    Examples
    ========

    >>> from sympy import sympify, true, false, Or
    >>> sympify(True)
    True
    >>> _ is True, _ is true
    (False, True)

    >>> Or(true, false)
    True
    >>> _ is true
    True

    Python operators give a boolean result for true but a
    bitwise result for True

    >>> ~true, ~True
    (False, -2)
    >>> true >> true, True >> True
    (True, 0)

    Python operators give a boolean result for true but a
    bitwise result for True

    >>> ~true, ~True
    (False, -2)
    >>> true >> true, True >> True
    (True, 0)

    See Also
    ========
    sympy.logic.boolalg.BooleanFalse

    c         C  s   t  S(   N(   R   (   R(   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   __nonzero__9  s    c         C  s
   t  t  S(   N(   t   hashR   (   R(   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   __hash__>  s    c         C  s   t  j S(   N(   R   R   (   R(   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   negatedA  s    c         C  s   t  j S(   s   
        Rewrite logic operators and relationals in terms of real sets.

        Examples
        ========

        >>> from sympy import true
        >>> true.as_set()
        UniversalSet()
        (   R   RF   (   R(   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyRO   E  s    (	   RY   RZ   R[   R   t   __bool__R   Rb   R   RO   (    (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR      s   Z		t   BooleanFalsec           B  s>   e  Z d  Z d   Z e Z d   Z e d    Z d   Z RS(   s  
    SymPy version of False, a singleton that can be accessed via S.false.

    This is the SymPy version of False, for use in the logic module. The
    primary advantage of using false instead of False is that shorthand boolean
    operations like ~ and >> will work as expected on this class, whereas with
    False they act bitwise on 0. Functions in the logic module will return this
    class when they evaluate to false.

    Notes
    ======
    See note in :py:class`sympy.logic.boolalg.BooleanTrue`

    Examples
    ========

    >>> from sympy import sympify, true, false, Or
    >>> sympify(False)
    False
    >>> _ is False, _ is false
    (False, True)

    >>> Or(true, false)
    True
    >>> _ is true
    True

    Python operators give a boolean result for false but a
    bitwise result for False

    >>> ~false, ~False
    (True, -1)
    >>> false >> false, False >> False
    (True, 0)

    See Also
    ========
    sympy.logic.boolalg.BooleanTrue

    c         C  s   t  S(   N(   R   (   R(   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR   |  s    c         C  s
   t  t  S(   N(   R   R   (   R(   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     s    c         C  s   t  j S(   N(   R   R   (   R(   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     s    c         C  s   t  j S(   s   
        Rewrite logic operators and relationals in terms of real sets.

        Examples
        ========

        >>> from sympy import false
        >>> false.as_set()
        EmptySet()
        (   R   RE   (   R(   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyRO     s    (	   RY   RZ   R[   R   R   R   Rb   R   RO   (    (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR   S  s   (		c         C  s   |  r t  j St  j S(   N(   R   R   R   (   RK   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   <lambda>  t    t   BooleanFunctionc           B  s   e  Z d  Z e Z d   Z d e e e d  Z d   Z	 e	 Z
 e	 Z e	 Z e d    Z e d  Z e d    Z d   Z d	   Z d d
  Z RS(   su   Boolean function is a function that lives in a boolean space
    It is used as base class for And, Or, Not, etc.
    c         C  sM   |  j  g  |  j D]* } | j d | d | d | d |  ^ q   } t |  S(   Nt   ratiot   measuret   rationalt   inverse(   t   funcRT   t   _eval_simplifyt   simplify_logic(   R(   R   R   R   R   Rd   t   rv(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     s    	:g333333?c         C  s   |  j  | | | |  S(   N(   R   (   R(   R   R   R   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR=     s    c         C  s&   d d l  m } t | d    d  S(   Ni(   R   s   
            A Boolean argument can only be used in
            Eq and Ne; all other relationals expect
            real expressions.
        (   Ri   R   R#   (   R(   R)   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyRj     s    c         G  s_  d d l  m } m } m } g  | D] } t |  ^ q# } t   j g  | D] } | j ^ qK   } t   j g  | D] } | j |  ^ qs   } i  } x | D] }	 x | D] }
 |	 | k r |	 |
 j	 k r t
 |
 | | f  rt j |
 j k pt j |
 j k s4t j | |
 <q4q7t t d |	 |
 f    q q Wq Wg  | D] } | j |  ^ qFS(   Ni(   R5   RP   RQ   s   
                            Incompatible use of binary symbol `%s` as a
                            real variable in `%s`
                            (   R7   R5   RP   RQ   R&   RR   RS   RW   R:   RA   R   R   R   RT   R   R#   R   RI   (   R(   RT   R5   RP   RQ   RX   t   bint   relRL   RK   RM   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   binary_check_and_simplify  s    (.!c         C  s   |  j  d | |  j  S(   NR=   (   t   _to_nnfRT   (   R(   R=   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR>     s    c         O  s   | j  d t  } t g   } x | D] } t |  sI | j |  } n  | r t | |   rj | j } n	 | f } xD | D], } t |  | k r |  j S| j	 |  qz Wq% | j	 |  q% W|  |   S(   NR=   (
   t   getR   RR   t
   is_literalR>   R   RT   R-   t   zerot   add(   t   clsRT   t   kwargsR=   t   argsett   argRd   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     s    	c         O  s    | j  d t  t |  | |  S(   Nt   evaluate(   t
   setdefaultR   R   (   R(   t   symbolst   assumptions(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   diff  s    c         C  s   d d l  m } d d l m } | |  j k ri | d | |  j | d  |  j | d   f d t f  S| |  j k r{ n t j	 Sd  S(   Ni(   RP   (   t	   Piecewisei    i   (
   R7   RP   t$   sympy.functions.elementary.piecewiseR   RW   RI   R   RA   R   t   Zero(   R(   RK   RP   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   _eval_derivative  s    *c           s  d d l  m   m } | d k r7 | d k	 r7 | } n  t } t | j   f d   d t \ } }	 t |  d k rz | St | j d   d t \ } }
 g  | D] } | j ^ q } x| rft |  d k rft	 } t
 t |   } g  } xt t |  d  D]\ \ } } \ } } xt |  D]\ } \ } } g  } | j | |  } | j |  } | r| j | | f  n  | j | j |  } | j |  } | r| j | | f  n  | j | | j  } | j |  } | r | j | | f  n  | j | j | j  } | j |  } | rC| j | | f  n  | r+x | D]~ \ } } | j |  } | | k r{| St | t  sP| |  | |  } | d k r| j | | | | f f  qqPqPWq+q+WqW| r t
 t t | d	 d
     } | d \ } } | \ } } } | | =| | =| d k sJ| | k rZ| j |  n  t } q q W| j g  t |  D] } | |  ^ qz|	 |
   } | S(   s  
        Replace patterns of Relational

        Parameters
        ==========

        rv : Expr
            Boolean expression

        patterns : tuple
            Tuple of tuples, with (pattern to simplify, simplified pattern)

        measure : function
            Simplification measure

        dominatingvalue : boolean or None
            The dominating value for the function of consideration.
            For example, for And S.false is dominating. As soon as one
            expression is S.false in And, the whole expression is S.false.

        replacementvalue : boolean or None, optional
            The resulting value for the whole expression if one argument
            evaluates to dominatingvalue.
            For example, for Nand S.false is dominating, but in this case
            the resulting value is S.true. Default is None. If replacementvalue
            is None and dominatingvalue is not None,
            replacementvalue = dominatingvalue
        i(   R5   t
   _canonicalc           s   t  |     S(   N(   R   (   RX   (   R5   (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR   #  R   t   binaryi   c         S  s   t  d   |  j D  S(   Nc         s  s   |  ] } | j  t k	 Vq d  S(   N(   t   is_realR   (   t   .0RN   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pys	   <genexpr>'  s   (   t   allRA   (   RX   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR   '  s   	i   i    t   keyc         S  s   |  d S(   Ni    (    (   t   pair(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR   ^  R   N(   R7   R5   R   R!   R   R   RT   RB   Rg   R   t   listR   R   t	   enumerateR   t   matcht   appendt   reversedRI   R   t   ITEt   sorted(   R(   R   t   patternsR   t   dominatingvaluet   replacementvalueR   t   changedt   Relt   nonRelt
   nonRealRelRX   t   resultst   pit   jt   pjt   kt   patternt   simpt   rest   oldexprt   tmprest   npt
   costsavingt   costt   replacementt   newrel(    (   R5   s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt"   _apply_patternbased_simplification  sp    	.10N(   RY   RZ   R[   R   RU   R   R   R   R=   Rj   R|   R~   R}   t   classmethodR   R>   R   R   R   R!   R   (    (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     s   					R'   c           B  sA   e  Z d  Z e Z e Z d Z e	 d    Z
 d   Z d   Z RS(   s  
    Logical AND function.

    It evaluates its arguments in order, giving False immediately
    if any of them are False, and True if they are all True.

    Examples
    ========

    >>> from sympy.core import symbols
    >>> from sympy.abc import x, y
    >>> from sympy.logic.boolalg import And
    >>> x & y
    x & y

    Notes
    =====

    The ``&`` operator is provided as a convenience, but note that its use
    here is different from its normal use in Python, which is bitwise
    and. Hence, ``And(a, b)`` and ``a & b`` will return different things if
    ``a`` and ``b`` are integers.

    >>> And(x, y).subs(x, 1)
    y

    c           s   g  } g  } t  j |   } x t |  D]y } | j r | j } | | k rR q( n  | j j   t   f d   | D  r t j g S| j	 |  n  | j	 |  q( Wt
 j | t  S(   Nc         3  s   |  ] } |   k Vq d  S(   N(    (   R   RM   (   t   nc(    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pys	   <genexpr>  s    (   R   R   R   t   is_RelationalRg   R   t   anyR   R   R   R   t   _new_args_filterR'   (   R   RT   t   newargsR   RK   t   c(    (   R   s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     s    		
c           sX  d d l  m   m  d d l m } t t |   j | | | |  } t | t  sZ | St	 | j
  f d   d t \ } } | s | St	 |   f d   d t \ }	 }
 |	 s | Si  } i  } |	 rt	 t g  |	 D] } | j | f ^ q  d    } g  }	 xd | k rx| j d  D]\ } } | j   } | j | k s]| | j j k ryt | | j t d	 t |  \ } } | j | | |  } | |  | | |  k r| } n |	 j |  w$Wqt k
 rqXn  | | k r|	 j | j | j | |   q$| j | | <|	 j |  q$Wt t  } x^ | D]V } xM | | D]A \ } } | j |  } | j } | t |  j | | f  qYWqHW| } qWn  x8 | D]0 } |	 j g  | | D] \ } } | ^ q qWg  |
 D] } | j |  ^ q}
 | j g  |	 |
 D] } | j ^ q|   } t   } |  j | | | t  S(
   Ni(   t   EqualityR5   (   t   linear_coeffsc           s   t  |     S(   N(   R   (   RX   (   R5   (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     R   R   c           s   t  |     S(   N(   R   (   RX   (   R   (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     R   c         S  s   t  |  d  S(   Ni    (   RB   (   RK   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     R   i   R   (   R7   R   R5   t   sympy.solvers.solvesetR   t   superR'   R   R   R   RT   R   R   RA   RC   t   lhst   rhst   rewriteR   R   R   R   t
   ValueErrorR   R   RI   RB   t   extendRg   t   simplify_patterns_andR   (   R(   R   R   R   R   R   R   R   R   t   eqsR)   RL   t   siftedRX   RJ   R$   RK   t   mt   bt   enewt   resiftedR   t   ft   eiR   (    (   R   R5   s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     sh    $"!!	#	%."-	c         C  s6   d d l  m } | g  |  j D] } | j   ^ q   S(   Ni(   t   Intersection(   t   sympy.sets.setsR   RT   RO   (   R(   R   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyRD     s    N(   RY   RZ   R[   R   R   R   t   identityR!   t   nargsR   R   R   RD   (    (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR'   q  s   	<R+   c           B  s;   e  Z d  Z e Z e Z e d    Z d   Z	 d   Z
 RS(   s}  
    Logical OR function

    It evaluates its arguments in order, giving True immediately
    if any of them are True, and False if they are all False.

    Examples
    ========

    >>> from sympy.core import symbols
    >>> from sympy.abc import x, y
    >>> from sympy.logic.boolalg import Or
    >>> x | y
    x | y

    Notes
    =====

    The ``|`` operator is provided as a convenience, but note that its use
    here is different from its normal use in Python, which is bitwise
    or. Hence, ``Or(a, b)`` and ``a | b`` will return different things if
    ``a`` and ``b`` are integers.

    >>> Or(x, y).subs(x, 0)
    y

    c           s   g  } g  } t  j |   } x | D]y } | j r | j } | | k rL q" n  | j j   t   f d   | D  r~ t j g S| j |  n  | j |  q" Wt	 j
 | t  S(   Nc         3  s   |  ] } |   k Vq d  S(   N(    (   R   RM   (   R   (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pys	   <genexpr>  s    (   R   R   R   Rg   R   R   R   R   R   R   R   R+   (   R   RT   R   R   RK   R   (    (   R   s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     s    		
c         C  s6   d d l  m } | g  |  j D] } | j   ^ q   S(   Ni(   t   Union(   R   R   RT   RO   (   R(   R   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyRD     s    c         C  sV   t  t |   j | | | |  } t | t  s4 | St   } |  j | | | t j  S(   N(   R   R+   R   R   t   simplify_patterns_orR   R   R   (   R(   R   R   R   R   R   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     s    	(   RY   RZ   R[   R   R   R   R   R   R   RD   R   (    (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR+     s   	R-   c           B  s8   e  Z d  Z e Z e d    Z d   Z e d  Z RS(   sI  
    Logical Not function (negation)


    Returns True if the statement is False
    Returns False if the statement is True

    Examples
    ========

    >>> from sympy.logic.boolalg import Not, And, Or
    >>> from sympy.abc import x, A, B
    >>> Not(True)
    False
    >>> Not(False)
    True
    >>> Not(And(True, False))
    True
    >>> Not(Or(True, False))
    False
    >>> Not(And(And(True, x), Or(x, False)))
    ~x
    >>> ~x
    ~x
    >>> Not(And(Or(A, B), Or(~A, ~B)))
    ~((A | B) & (~A | ~B))

    Notes
    =====

    - The ``~`` operator is provided as a convenience, but note that its use
      here is different from its normal use in Python, which is bitwise
      not. In particular, ``~a`` and ``Not(a)`` will be different if ``a`` is
      an integer. Furthermore, since bools in Python subclass from ``int``,
      ``~True`` is the same as ``~1`` which is ``-2``, which has a boolean
      value of True.  To avoid this issue, use the SymPy boolean types
      ``true`` and ``false``.

    >>> from sympy import true
    >>> ~True
    -2
    >>> ~true
    False

    c         C  s  d d l  m } m } m } m } m } m } t | t  sO | t	 t
 f k r] | rY t St S| j rq | j d St | |  r | | j   St | |  r | | j   St | |  r | | j   St | |  r | | j   St | |  r | | j   St | |  r| | j   Sd  S(   Ni(   R   t   GreaterThant   LessThant   StrictGreaterThant   StrictLessThant
   Unequalityi    (   t   sympyR   R   R   R   R   R   R   R   R   R   R   R   t   is_NotRT   (   R   R   R   R   R   R   R   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   evalT  s"    .!	c         C  s   |  j  d j   j t j  S(   s   
        Rewrite logic operators and relationals in terms of real sets.

        Examples
        ========

        >>> from sympy import Not, Symbol
        >>> x = Symbol('x')
        >>> Not(x > 0).as_set()
        Interval(-oo, 0)
        i    (   RT   RO   t
   complementR   RG   (   R(   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyRD   k  s    c         C  s  t  |   r |  S|  j d } | j | j } } | t k rc t j d | g  | D] } | ^ qO  S| t k r t j d | g  | D] } | ^ q  S| t k r | \ } } t j | | d | S| t k rt j t |   t g  | D] } | ^ q   d | S| t k rg  } x} t	 d t
 |  d d  D]_ }	 xV t | |	  D]E }
 g  | D] } | |
 k rr| n | ^ qY} | j t |    qLWq6Wt j d | |  S| t k r| \ } } } t j t | |  t | |  d | St d |   d  S(   Ni    R=   i   i   s!   Illegal operator %s in expression(   R   RT   R   R'   R+   R   R/   R;   R2   R	   RB   R   R   R   R   (   R(   R=   t   exprR   RT   R   Rd   R   t   resultRX   t   negRN   t   clauseR   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR>   y  s2    ''/#,+(	   RY   RZ   R[   R   R   R   R   RD   R>   (    (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR-   #  s
   -	R2   c           B  sA   e  Z d  Z d   Z e e d     Z e d  Z d   Z	 RS(   sg  
    Logical XOR (exclusive OR) function.


    Returns True if an odd number of the arguments are True and the rest are
    False.

    Returns False if an even number of the arguments are True and the rest are
    False.

    Examples
    ========

    >>> from sympy.logic.boolalg import Xor
    >>> from sympy import symbols
    >>> x, y = symbols('x y')
    >>> Xor(True, False)
    True
    >>> Xor(True, True)
    False
    >>> Xor(True, False, True, True, False)
    True
    >>> Xor(True, False, True, False)
    False
    >>> x ^ y
    Xor(x, y)

    Notes
    =====

    The ``^`` operator is provided as a convenience, but note that its use
    here is different from its normal use in Python, which is bitwise xor. In
    particular, ``a ^ b`` and ``Xor(a, b)`` will be different if ``a`` and
    ``b`` are integers.

    >>> Xor(x, y).subs(y, 0)
    x

    c         O  s  t  g   } t t |   j |  | |  } x | j D] } t | t  s[ | t t f k rp | r4 t	 } qp q4 n  t | t  r xe | j
 D]. } | | k r | j |  n | j |  q Wq4 | | k r | j |  q4 | j |  q4 Wg  | D]' } | j r | | j | j j f ^ q } t }	 g  }
 x t |  D] \ } \ } } } x_ t | d t |   D]A } | | d  \ } } | | k r|	 }	 Pqg| | k rgPqgqgWq8|
 j | | f  q8W|	 rt	 | k r| j t	  n | j t	  n  x. |
 D]& \ } } | j |  | j |  qWt |  d k r>t St |  d k rZ| j   St | k r| j t  t t |    St t |   | _ t |  | _ | Sd  S(   Ni   i   i    (   RR   R   R2   t   __new__t   _argsR   R   R   R   R   RT   t   removeR   R   Rg   R   R   R	   RB   R   R   RC   R-   t   tupleR   t	   frozensett   _argset(   R   RT   R   R   t   objR   Rd   RM   R   t   oddR   RX   R   R   R   t   rjt   cjR   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     sT    !	/1" +
c         C  s   t  t |  j   S(   N(   R   R   R   (   R(   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyRT     s    c         C  s   g  } x t  d t |  j  d d  D]e } x\ t |  j |  D]H } g  |  j D] } | | k rh | n | ^ qO } | j t |    q? Wq& Wt j d | |  S(   Ni    i   i   R=   (   R	   RB   RT   R   R   R+   R'   R   (   R(   R=   RT   RX   R   RN   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR>     s    &/c         C  su   |  j  g  |  j D]* } | j d | d | d | d |  ^ q   } t | t  sV | St   } |  j | | | d   S(   NR   R   R   R   (   R   RT   R   R   R2   t   simplify_patterns_xorR   R!   (   R(   R   R   R   R   Rd   R   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     s    	:	(
   RY   RZ   R[   R   Rb   R   RT   R   R>   R   (    (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR2     s   '	0t   Nandc           B  s   e  Z d  Z e d    Z RS(   s  
    Logical NAND function.

    It evaluates its arguments in order, giving True immediately if any
    of them are False, and False if they are all True.

    Returns True if any of the arguments are False
    Returns False if all arguments are True

    Examples
    ========

    >>> from sympy.logic.boolalg import Nand
    >>> from sympy import symbols
    >>> x, y = symbols('x y')
    >>> Nand(False, True)
    True
    >>> Nand(True, True)
    False
    >>> Nand(x, y)
    ~(x & y)

    c         G  s   t  t |    S(   N(   R-   R'   (   R   RT   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR   )  s    (   RY   RZ   R[   R   R   (    (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR    s   t   Norc           B  s   e  Z d  Z e d    Z RS(   s*  
    Logical NOR function.

    It evaluates its arguments in order, giving False immediately if any
    of them are True, and True if they are all False.

    Returns False if any argument is True
    Returns True if all arguments are False

    Examples
    ========

    >>> from sympy.logic.boolalg import Nor
    >>> from sympy import symbols
    >>> x, y = symbols('x y')

    >>> Nor(True, False)
    False
    >>> Nor(True, True)
    False
    >>> Nor(False, True)
    False
    >>> Nor(False, False)
    True
    >>> Nor(x, y)
    ~(x | y)

    c         G  s   t  t |    S(   N(   R-   R+   (   R   RT   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR   K  s    (   RY   RZ   R[   R   R   (    (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR  .  s   t   Xnorc           B  s   e  Z d  Z e d    Z RS(   s  
    Logical XNOR function.

    Returns False if an odd number of the arguments are True and the rest are
    False.

    Returns True if an even number of the arguments are True and the rest are
    False.

    Examples
    ========

    >>> from sympy.logic.boolalg import Xnor
    >>> from sympy import symbols
    >>> x, y = symbols('x y')
    >>> Xnor(True, False)
    False
    >>> Xnor(True, True)
    True
    >>> Xnor(True, False, True, True, False)
    False
    >>> Xnor(True, False, True, False)
    True

    c         G  s   t  t |    S(   N(   R-   R2   (   R   RT   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR   j  s    (   RY   RZ   R[   R   R   (    (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR  P  s   R/   c           B  s)   e  Z d  Z e d    Z e d  Z RS(   s  
    Logical implication.

    A implies B is equivalent to !A v B

    Accepts two Boolean arguments; A and B.
    Returns False if A is True and B is False
    Returns True otherwise.

    Examples
    ========

    >>> from sympy.logic.boolalg import Implies
    >>> from sympy import symbols
    >>> x, y = symbols('x y')

    >>> Implies(True, False)
    False
    >>> Implies(False, False)
    True
    >>> Implies(True, True)
    True
    >>> Implies(False, True)
    True
    >>> x >> y
    Implies(x, y)
    >>> y << x
    Implies(x, y)

    Notes
    =====

    The ``>>`` and ``<<`` operators are provided as a convenience, but note
    that their use here is different from their normal use in Python, which is
    bit shifts. Hence, ``Implies(a, b)`` and ``a >> b`` will return different
    things if ``a`` and ``b`` are integers.  In particular, since Python
    considers ``True`` and ``False`` to be integers, ``True >> True`` will be
    the same as ``1 >> 1``, i.e., 0, which has a truth value of False.  To
    avoid this issue, use the SymPy objects ``true`` and ``false``.

    >>> from sympy import true, false
    >>> True >> False
    1
    >>> true >> false
    False

    c         G  sR  yk g  } xR | D]J } t  | t  s1 | d k rM | j | rC t n t  q | j |  q W| \ } } Wn3 t k
 r t d t |  t |  f   n X| t k s | t k s | t k s | t k r t t	 |  |  S| | k r t
 j S| j r>| j r>| j | j k r"t
 j S| j j | j k rN| Sn t j |  |  Sd  S(   Ni    i   s:   %d operand(s) used for an Implies (pairs are required): %s(   i    i   (   R   R   R   R   R   R   RB   t   strR+   R-   R   R   R   Rg   R   R   R   (   R   RT   R   RK   t   At   B(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     s*     0c         C  s&   |  j  \ } } t j | | d | S(   NR=   (   RT   R+   R   (   R(   R=   Rd   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR>     s    (   RY   RZ   R[   R   R   R   R>   (    (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR/   o  s   /R;   c           B  s8   e  Z d  Z d   Z e e d     Z e d  Z RS(   s  
    Equivalence relation.

    Equivalent(A, B) is True iff A and B are both True or both False

    Returns True if all of the arguments are logically equivalent.
    Returns False otherwise.

    Examples
    ========

    >>> from sympy.logic.boolalg import Equivalent, And
    >>> from sympy.abc import x, y
    >>> Equivalent(False, False, False)
    True
    >>> Equivalent(True, False, False)
    False
    >>> Equivalent(x, And(x, True))
    True
    c         O  sW  d d l  m } g  | D] } t |  ^ q } t |  } xX | D]P } t | t  si | t t g k rB | j |  | j	 | r t n t  qB qB Wg  } x? | D]7 } t | |  r | j
 | | j | j j f  q q Wg  }	 x t |  D] \ }
 \ } } } xh t |
 d t |   D]M } | | d  \ } } | | k rJt S| | k r |	 j
 | | f  Pq q Wq Wx; |	 D]3 \ } } | j |  | j |  | j	 t  q|Wt |  d k rt St | k r| j t  t |   St | k r#| j t  t g  | D] } | ^ q  St |  } t t |   j |  |  } | | _ | S(   Ni(   R5   i   i   (   R7   R5   R   RR   R   R   R   R   t   discardR   R   Rg   R   R   R	   RB   R   R   R   R'   R   R   R;   R   R   (   R   RT   t   optionsR5   R   R   RK   R   RM   R   RX   R   R   R   R   R   Rd   R   R   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     sH    ! &" 
	c         C  s   t  t |  j   S(   N(   R   R   R   (   R(   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyRT     s    c         C  s   g  } x> t  |  j |  j d  D]# \ } } | j t | |   q  W| j t |  j d |  j d   t j d | |  S(   Ni   ii    R=   (   t   zipRT   R   R+   R'   R   (   R(   R=   RT   Rd   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR>     s
    &%(	   RY   RZ   R[   R   Rb   R   RT   R   R>   (    (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR;     s
   	'R   c           B  sD   e  Z d  Z d   Z e d    Z e d  Z d   Z d   Z	 RS(   s  
    If then else clause.

    ITE(A, B, C) evaluates and returns the result of B if A is true
    else it returns the result of C. All args must be Booleans.

    Examples
    ========

    >>> from sympy.logic.boolalg import ITE, And, Xor, Or
    >>> from sympy.abc import x, y, z
    >>> ITE(True, False, True)
    False
    >>> ITE(Or(True, False), And(True, True), Xor(True, True))
    True
    >>> ITE(x, y, z)
    ITE(x, y, z)
    >>> ITE(True, x, y)
    x
    >>> ITE(False, x, y)
    y
    >>> ITE(x, y, y)
    y

    Trying to use non-Boolean args will generate a TypeError:

    >>> ITE(True, [], ())
    Traceback (most recent call last):
    ...
    TypeError: expecting bool, Boolean or ITE, not `[]`

    c         O  s  d d l  m } m } t |  d k r7 t d   n  | \ } } } t | | | f  rkt t | | f  \ } } t   j	 g  | | f D] } | j
 ^ q   }	 t t | j  |	  d k r| }
 | j t j k r | j } ne | j t j k r| j } nG | j t j k r$| j } n( | j t j k rC| j } n	 t j } t |
 |  rh| } qhqn t j | | |  \ } } } d  } | j d t  r|  j | | |  } n  | d  k rt j |  | | | d t } n  | S(   Ni(   RP   RQ   i   s   expecting exactly 3 argsi   R   (   R7   RP   RQ   RB   R   R   t   mapR&   RR   RS   RW   RT   R   R   R   R   R   R   R   R!   R   R   R   R   R   (   R   RT   R   RP   RQ   Rd   R   R   RX   R   t   _aR   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR   (  s8    .	!c         G  s  d d l  m } m } | \ } } } t | | | f  r | } t j | j k ry | j t j k rm | j n | j } nA t j	 | j k r | j t j	 k r | j n | j } n d  } | d  k	 r t | |  r | } q n  | t j k r | S| t j	 k r| S| | k r| S| t j k r:| t j	 k r:| S| t j	 k rb| t j k rbt |  S| | | g | k r|  | | | d t Sd  S(   Ni(   RP   RQ   R   (   R7   RP   RQ   R   R   R   RT   R   R   R   R!   R-   R   (   R   RT   RP   RQ   Rd   R   R   R  (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR   N  s.    ')
c         C  s;   |  j  \ } } } t j t | |  t | |  d | S(   NR=   (   RT   R'   R   R+   (   R(   R=   Rd   R   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR>   m  s    c         C  s   |  j    j   S(   N(   R>   RO   (   R(   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyRD   q  s    c         O  s5   d d l  m } | | d | d f | d t f  S(   Ni(   R   i   i    i   (   t   sympy.functionsR   R   (   R(   RT   R   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   _eval_rewrite_as_Piecewiset  s    (
   RY   RZ   R[   R   R   R   R   R>   RD   R  (    (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     s    	&	c         C  s   t  j |   S(   s  Return a list of the conjuncts in the expr s.

    Examples
    ========

    >>> from sympy.logic.boolalg import conjuncts
    >>> from sympy.abc import A, B
    >>> conjuncts(A & B)
    frozenset({A, B})
    >>> conjuncts(A | B)
    frozenset({A | B})

    (   R'   t	   make_args(   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt	   conjuncts{  s    c         C  s   t  j |   S(   s  Return a list of the disjuncts in the sentence s.

    Examples
    ========

    >>> from sympy.logic.boolalg import disjuncts
    >>> from sympy.abc import A, B
    >>> disjuncts(A | B)
    frozenset({A, B})
    >>> disjuncts(A & B)
    frozenset({A & B})

    (   R+   R  (   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt	   disjuncts  s    c         C  s   t  |  t t f  S(   sa  
    Given a sentence s consisting of conjunctions and disjunctions
    of literals, return an equivalent sentence in CNF.

    Examples
    ========

    >>> from sympy.logic.boolalg import distribute_and_over_or, And, Or, Not
    >>> from sympy.abc import A, B, C
    >>> distribute_and_over_or(Or(A, And(Not(B), Not(C))))
    (A | ~B) & (A | ~C)
    (   t   _distributeR'   R+   (   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   distribute_and_over_or  s    c         C  s   t  |  t t f  S(   s  
    Given a sentence s consisting of conjunctions and disjunctions
    of literals, return an equivalent sentence in DNF.

    Note that the output is NOT simplified.

    Examples
    ========

    >>> from sympy.logic.boolalg import distribute_or_over_and, And, Or, Not
    >>> from sympy.abc import A, B, C
    >>> distribute_or_over_and(And(Or(Not(A), B), C))
    (B & C) | (C & ~A)
    (   R  R+   R'   (   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   distribute_or_over_and  s    c      
   C  sF  t  |  d |  d  r x: |  d j D]# } t  | |  d  r% | } Pq% q% W|  d S|  d g  |  d j D] } | | k	 ri | ^ qi   } |  d t t t g  | j D]* } |  d | |  |  d |  d f ^ q     St  |  d |  d  r:|  d t t t g  |  d j D] } | |  d |  d f ^ q    S|  d Sd S(   sC   
    Distributes info[1] over info[2] with respect to info[0].
    i    i   i   N(   R   RT   R   R  R  (   t   infoR   t   conjRd   t   restR   RK   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR    s    6>5c         C  s    t  |  |  r |  S|  j |  S(   s  
    Converts expr to Negation Normal Form.
    A logical expression is in Negation Normal Form (NNF) if it
    contains only And, Or and Not, and Not is applied only to literals.
    If simplify is True, the result contains no redundant clauses.

    Examples
    ========

    >>> from sympy.abc import A, B, C, D
    >>> from sympy.logic.boolalg import Not, Equivalent, to_nnf
    >>> to_nnf(Not((~A & ~B) | (C & D)))
    (A | B) & (~C | ~D)
    >>> to_nnf(Equivalent(A >> B, B >> A))
    (A | ~B | (A & ~B)) & (B | ~A | (B & ~A))
    (   t   is_nnfR>   (   R   R=   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR>     s    c         C  s[   t  |   }  t |  t  s |  S| r5 t |  d t  St |   rE |  St |   }  t |   S(   s  
    Convert a propositional logical sentence s to conjunctive normal form.
    That is, of the form ((A | ~B | ...) & (B | C | ...) & ...)
    If simplify is True, the expr is evaluated to its simplest CNF form  using
    the Quine-McCluskey algorithm.

    Examples
    ========

    >>> from sympy.logic.boolalg import to_cnf
    >>> from sympy.abc import A, B, D
    >>> to_cnf(~(A | B) | D)
    (D | ~A) & (D | ~B)
    >>> to_cnf((A | B) & (A | ~A), True)
    A | B

    t   cnf(   R   R   R   R   R   t   is_cnft   eliminate_implicationsR  (   R   R=   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   to_cnf  s    c         C  s[   t  |   }  t |  t  s |  S| r5 t |  d t  St |   rE |  St |   }  t |   S(   s  
    Convert a propositional logical sentence s to disjunctive normal form.
    That is, of the form ((A & ~B & ...) | (B & C & ...) | ...)
    If simplify is True, the expr is evaluated to its simplest DNF form using
    the Quine-McCluskey algorithm.

    Examples
    ========

    >>> from sympy.logic.boolalg import to_dnf
    >>> from sympy.abc import A, B, C
    >>> to_dnf(B & (A | C))
    (A & B) | (B & C)
    >>> to_dnf((A & B) | (A & ~B) | (B & C) | (~B & C), True)
    A | C

    t   dnf(   R   R   R   R   R   t   is_dnfR  R  (   R   R=   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   to_dnf  s    c         C  s   t  |   }  t |   r t S|  g } x | r | j   }  |  j t t f k r | r |  j } x' | D] } t |  | k re t	 Sqe Wn  | j
 |  j  q( t |   s( t	 Sq( Wt S(   sW  
    Checks if expr is in Negation Normal Form.
    A logical expression is in Negation Normal Form (NNF) if it
    contains only And, Or and Not, and Not is applied only to literals.
    If simpified is True, checks if result contains no redundant clauses.

    Examples
    ========

    >>> from sympy.abc import A, B, C
    >>> from sympy.logic.boolalg import Not, is_nnf
    >>> is_nnf(A & B | ~C)
    True
    >>> is_nnf((A | ~A) & (B | C))
    False
    >>> is_nnf((A | ~A) & (B | C), False)
    True
    >>> is_nnf(Not(A & B) | C)
    False
    >>> is_nnf((A >> B) & (B >> A))
    False
    (   R   R   R   RC   R   R'   R+   RT   R-   R   R   (   R   t
   simplifiedt   stackRT   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR  .  s     			c         C  s   t  |  t t  S(   s(  
    Test whether or not an expression is in conjunctive normal form.

    Examples
    ========

    >>> from sympy.logic.boolalg import is_cnf
    >>> from sympy.abc import A, B, C
    >>> is_cnf(A | B | C)
    True
    >>> is_cnf(A & B & C)
    True
    >>> is_cnf((A & B) | C)
    False

    (   t   _is_formR'   R+   (   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR  \  s    c         C  s   t  |  t t  S(   sM  
    Test whether or not an expression is in disjunctive normal form.

    Examples
    ========

    >>> from sympy.logic.boolalg import is_dnf
    >>> from sympy.abc import A, B, C
    >>> is_dnf(A | B | C)
    True
    >>> is_dnf(A & B & C)
    True
    >>> is_dnf((A & B) | C)
    True
    >>> is_dnf(A & (B | C))
    False

    (   R"  R+   R'   (   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR  p  s    c         C  sS  t  |   }  |  j r t St |  |  rs xD |  j D]9 } t | t  r^ | j d j sk t Sq2 | j s2 t Sq2 Wt St |  t  r |  j d j s t Sn  t |  |  s t Sx |  j D] } | j r q n  t | t  r | j d j st Sn t | |  st SxD | j D]9 } t | t  r:| j d j sGt Sq| j st SqWq Wt S(   sE   
    Test whether or not an expression is of the required form.

    i    (   R   Rk   R   R   RT   R-   R   (   R   t	   function1t	   function2t   litR   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR"    s>    				c         C  s   t  |  d t S(   s  
    Change >>, <<, and Equivalent into &, |, and ~. That is, return an
    expression that is equivalent to s, but has only &, |, and ~ as logical
    operators.

    Examples
    ========

    >>> from sympy.logic.boolalg import Implies, Equivalent,          eliminate_implications
    >>> from sympy.abc import A, B, C
    >>> eliminate_implications(Implies(A, B))
    B | ~A
    >>> eliminate_implications(Equivalent(A, B))
    (A | ~B) & (B | ~A)
    >>> eliminate_implications(Equivalent(A, B, C))
    (A | ~C) & (B | ~A) & (C | ~B)
    R=   (   R>   R   (   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR    s    c         C  s6   t  |  t  r$ t  |  j d t  St  |  t  Sd S(   sz  
    Returns True if expr is a literal, else False.

    Examples
    ========

    >>> from sympy import Or, Q
    >>> from sympy.abc import A, B
    >>> from sympy.logic.boolalg import is_literal
    >>> is_literal(A)
    True
    >>> is_literal(~A)
    True
    >>> is_literal(Q.zero(A))
    True
    >>> is_literal(A + B)
    True
    >>> is_literal(Or(A, B))
    False
    i    N(   R   R-   RT   R   (   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     s    c      	     sv   t  t t  t t d t   d       d     g  |  D]. } t    f d   t j |  D  ^ qD S(   s	  
    Takes clauses in CNF format and puts them into an integer representation.

    Examples
    ========

    >>> from sympy.logic.boolalg import to_int_repr
    >>> from sympy.abc import x, y
    >>> to_int_repr([x | y, y], [x, y]) == [{1, 2}, {2}]
    True

    i   c         S  s+   t  |  t  r | |  j d S| |  Sd  S(   Ni    (   R   R-   RT   (   R   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   append_symbol  s    c         3  s   |  ] }   |   Vq d  S(   N(    (   R   R   (   R&  R   (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pys	   <genexpr>  s    (   t   dictR   R
  R	   RB   RR   R+   R  (   t   clausesR   R   (    (   R&  R   s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   to_int_repr  s    4	c         C  s+   t  d j t t t t |      d  S(   sB  
    Return an integer corresponding to the base-2 digits given by ``term``.

    Parameters
    ==========

    term : a string or list of ones and zeros

    Examples
    ========

    >>> from sympy.logic.boolalg import term_to_integer
    >>> term_to_integer([1, 0, 0])
    4
    >>> term_to_integer('100')
    4

    R   i   (   t   intt   joinR   R  R  (   t   term(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   term_to_integer  s    c         C  sC   d j  t t |    t t | p$ d    } t t t |   S(   s  
    Return a list of the base-2 digits in the integer, ``k``.

    Parameters
    ==========

    k : int
    n_bits : int
        If ``n_bits`` is given and the number of digits in the binary
        representation of ``k`` is smaller than ``n_bits`` then left-pad the
        list with 0s.

    Examples
    ========

    >>> from sympy.logic.boolalg import integer_to_term
    >>> integer_to_term(4)
    [1, 0, 0]
    >>> integer_to_term(4, 6)
    [0, 0, 0, 1, 0, 0]
    s	   {0:0{1}b}i    (   t   formatt   absR   R   R  R*  (   R   t   n_bitsRN   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   integer_to_term  s    0c         c  s   g  | D] } t  |  ^ q } t  |   }  t |  t  rL t |   rL d St d d g d t |  } xQ | D]I } t |  } |  j t t	 | |    } | r | | f Vqq | Vqq Wd S(   s  
    Return a generator of all possible configurations of the input variables,
    and the result of the boolean expression for those values.

    Parameters
    ==========

    expr : string or boolean expression
    variables : list of variables
    input : boolean (default True)
        indicates whether to return the input combinations.

    Examples
    ========

    >>> from sympy.logic.boolalg import truth_table
    >>> from sympy.abc import x,y
    >>> table = truth_table(x >> y, [x, y])
    >>> for t in table:
    ...     print('{0} -> {1}'.format(*t))
    [0, 0] -> True
    [0, 1] -> True
    [1, 0] -> False
    [1, 1] -> True

    >>> table = truth_table(x | y, [x, y])
    >>> list(table)
    [([0, 0], False), ([0, 1], True), ([1, 0], True), ([1, 1], True)]

    If input is false, truth_table returns only a list of truth values.
    In this case, the corresponding input values of variables can be
    deduced from the index of a given output.

    >>> from sympy.logic.boolalg import integer_to_term
    >>> vars = [y, x]
    >>> values = truth_table(x >> y, vars, input=False)
    >>> values = list(values)
    >>> values
    [True, False, True, True]

    >>> for i, value in enumerate(values):
    ...     print('{0} -> {1}'.format(list(zip(
    ...     vars, integer_to_term(i, len(vars)))), value))
    [(y, 0), (x, 0)] -> True
    [(y, 0), (x, 1)] -> False
    [(y, 1), (x, 0)] -> True
    [(y, 1), (x, 1)] -> True

    Ni    i   t   repeat(
   R   R   R   R   R   RB   R   t   xreplaceR'  R
  (   R   t	   variablest   inputt   vt   tableR,  t   value(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   truth_table5  s    2c         C  s^   d } xQ t  t |  |   D]: \ } \ } } | | k r | d k rO | } qV d Sq q W| S(   sk   
    Checks if a pair of minterms differs by only one bit. If yes, returns
    index, else returns -1.
    i(   R   R
  (   t   minterm1t   minterm2t   indexRK   RX   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   _check_pairx  s    (	c         C  ss   g  } x` t  |   D]R \ } } | d k rE | j t | |   q | d k r | j | |  q q Wt |   S(   sh   
    Converts a term in the expansion of a function from binary to its
    variable form (for SOP).
    i    i   (   R   R   R-   R'   (   t   mintermR4  t   tempRX   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   _convert_to_varsSOP  s    c         C  ss   g  } x` t  |   D]R \ } } | d k rE | j t | |   q | d k r | j | |  q q Wt |   S(   sh   
    Converts a term in the expansion of a function from binary to its
    variable form (for POS).
    i   i    (   R   R   R-   R+   (   t   maxtermR4  R?  RX   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   _convert_to_varsPOS  s    c   
      C  s  g  } t  t t |     } x t |  d   D] \ } } x t |  | d  D]q \ } } t | |  } | d k rP d | | <| | | d <| } d | | <| | k r | j |  q qP qP Wq/ W| j g  g  | D] }	 |	 d k	 r |	 ^ q D] } |  | ^ q  | S(   s   
    Reduces a set of minterms, if possible, to a simplified set of minterms
    with one less variable in the terms using QM method.
    ii   i   N(   R   R	   RB   R   R=  R!   R   R   (
   t   termst   simplified_termst   todoRX   t   tit   j_it   tjR<  t   newtermt   _(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   _simplified_pairs  s    !
=c         C  sA   x: t  |  D], \ } } | d k r | |  | k r t Sq Wt S(   sq   
    Return True if a binary term is satisfied by the given term. Used
    for recognizing prime implicants.
    i   (   R   R   R   (   R>  R,  RX   RK   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   _compare_term  s    c         C  s  t  |  rg  t t  |   D] } d g t  |   ^ q } xW t |   D]I \ } } x: t |  D], \ } } t | |  rd d | | | <qd qd WqK Wt t t  |     } t t t  |    }	 d }
 d } x|	 |
 k s | | k rz|	 }
 | } xt |  D] \ } } |	 | d k	 r
g  g  | D] } | d k	 r0| ^ q0D] } | | ^ qL} x t |  D] \ } } | | k ro|	 | d k	 rog  g  | D] } | d k	 r| ^ qD] } | | ^ q} t d   t | |  D  rd |	 | <qqoqoWq
q
Wxgt t  |    D]S} | | d k	 r g  t t  |   D] } | | | ^ qI} g  g  |
 D] } | d k	 rm| ^ qmD] } | | ^ q} x t t  |    D] } | | k r| | d k	 rg  t t  |   D] } | | | ^ q} g  g  |
 D] } | d k	 r| ^ qD] } | | ^ q'} t d   t | |  D  rld | | <qlqqWq q Wq Wg  g  | D] } | d k	 r| ^ qD] } |  | ^ q}  |  Sg  Sd S(   s   
    After the truth table has been sufficiently simplified, use the prime
    implicant table method to recognize and eliminate redundant pairs,
    and return the essential arguments.
    i    i   c         s  s!   |  ] \ } } | | k Vq d  S(   N(    (   R   Rd   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pys	   <genexpr>  s    c         s  s!   |  ] \ } } | | k Vq d  S(   N(    (   R   Rd   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pys	   <genexpr>  s    N(   RB   R	   R   RL  R   R!   R   R
  (   t   l1RC  t   nt	   dommatrixt   primeit   primet   termiR,  t   ndprimeimplicantst   ndtermst
   oldndtermst   oldndprimeimplicantst   rowit   rowRJ  RX   t   row2it   row2t   coliRd   t   colt   col2it   col2(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   _rem_redundancy  sT    29,-9*9<c   
      C  sd  g  } t  |  } xK|  D]C} t | t  rG | j t | |   q t | t  r t |  } x! | j   D] } | j |  qo Wx t	 d d g d t  |  D]L } t t
 | |   } | j |  | j g  | D] }	 | |	 ^ q  q Wq t | t t f  rPt  |  | k r:t d j | |    n  | j t |   q t d   q W| S(   Ni    i   R2  sL   Each term must contain {} bits as there are
{} variables (or be an integer).s2   A term list can only contain lists, ints or dicts.(   RB   R   R*  R   R   R'  R   t   keysR   R   R
  t   updateR   R   R.  R#   (
   t	   inputlistR4  t   binlistt   bitst   valt   nonspecvarsR   t   tt   dR6  (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   _input_to_binlist  s(    %+	c   	      C  s   g  |  D] } t  |  ^ q }  | g  k r/ t St | |   } t | pJ g  |   } x- | D]% } | | k rZ t d |   qZ qZ Wd } | | } x" | | k r | } t |  } q Wt | |  } t g  | D] } t | |   ^ q   S(   sq  
    The SOPform function uses simplified_pairs and a redundant group-
    eliminating algorithm to convert the list of all input combos that
    generate '1' (the minterms) into the smallest Sum of Products form.

    The variables must be given as the first argument.

    Return a logical Or function (i.e., the "sum of products" or "SOP"
    form) that gives the desired outcome. If there are inputs that can
    be ignored, pass them as a list, too.

    The result will be one of the (perhaps many) functions that satisfy
    the conditions.

    Examples
    ========

    >>> from sympy.logic import SOPform
    >>> from sympy import symbols
    >>> w, x, y, z = symbols('w x y z')
    >>> minterms = [[0, 0, 0, 1], [0, 0, 1, 1],
    ...             [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 1, 1]]
    >>> dontcares = [[0, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 1]]
    >>> SOPform([w, x, y, z], minterms, dontcares)
    (y & z) | (z & ~w)

    The terms can also be represented as integers:

    >>> minterms = [1, 3, 7, 11, 15]
    >>> dontcares = [0, 2, 5]
    >>> SOPform([w, x, y, z], minterms, dontcares)
    (y & z) | (z & ~w)

    They can also be specified using dicts, which does not have to be fully
    specified:

    >>> minterms = [{w: 0, x: 1}, {y: 1, z: 1, x: 0}]
    >>> SOPform([w, x, y, z], minterms)
    (x & ~w) | (y & z & ~x)

    Or a combination:

    >>> minterms = [4, 7, 11, [1, 1, 1, 1]]
    >>> dontcares = [{w : 0, x : 0, y: 0}, 5]
    >>> SOPform([w, x, y, z], minterms, dontcares)
    (w & y & z) | (x & y & z) | (~w & ~y)

    References
    ==========

    .. [1] en.wikipedia.org/wiki/Quine-McCluskey_algorithm

    s#   %s in minterms is also in dontcaresN(	   R   R   Ri  R   R!   RK  R_  R+   R@  (	   R4  t   mintermst	   dontcaresR6  Rh  t   oldt   newt	   essentialRK   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   SOPform  s    6
c         C  sP  g  |  D] } t  |  ^ q }  | g  k r/ t St | |   } t | pJ g  |   } x- | D]% } | | k rZ t d |   qZ qZ Wg  } xZ t d d g d t |   D]: } t |  } | | k r | | k r | j |  q q Wd } | | } x" | | k r| } t	 |  } q Wt
 | |  }	 t g  |	 D] }
 t |
 |   ^ q4  S(   sj  
    The POSform function uses simplified_pairs and a redundant-group
    eliminating algorithm to convert the list of all input combinations
    that generate '1' (the minterms) into the smallest Product of Sums form.

    The variables must be given as the first argument.

    Return a logical And function (i.e., the "product of sums" or "POS"
    form) that gives the desired outcome. If there are inputs that can
    be ignored, pass them as a list, too.

    The result will be one of the (perhaps many) functions that satisfy
    the conditions.

    Examples
    ========

    >>> from sympy.logic import POSform
    >>> from sympy import symbols
    >>> w, x, y, z = symbols('w x y z')
    >>> minterms = [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 1],
    ...             [1, 0, 1, 1], [1, 1, 1, 1]]
    >>> dontcares = [[0, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 1]]
    >>> POSform([w, x, y, z], minterms, dontcares)
    z & (y | ~w)

    The terms can also be represented as integers:

    >>> minterms = [1, 3, 7, 11, 15]
    >>> dontcares = [0, 2, 5]
    >>> POSform([w, x, y, z], minterms, dontcares)
    z & (y | ~w)

    They can also be specified using dicts, which does not have to be fully
    specified:

    >>> minterms = [{w: 0, x: 1}, {y: 1, z: 1, x: 0}]
    >>> POSform([w, x, y, z], minterms)
    (x | y) & (x | z) & (~w | ~x)

    Or a combination:

    >>> minterms = [4, 7, 11, [1, 1, 1, 1]]
    >>> dontcares = [{w : 0, x : 0, y: 0}, 5]
    >>> POSform([w, x, y, z], minterms, dontcares)
    (w | x) & (y | ~w) & (z | ~y)


    References
    ==========

    .. [1] en.wikipedia.org/wiki/Quine-McCluskey_algorithm

    s#   %s in minterms is also in dontcaresi    i   R2  N(   R   R   Ri  R   R   RB   R   R   R!   RK  R_  R'   RB  (   R4  Rj  Rk  R6  Rh  t   maxtermsRg  Rl  Rm  Rn  RK   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   POSformg  s(    7%
c         C  s3   t  |  t  s |  h St   j d   |  j D   S(   s   Helper to find logical predicates in BooleanFunctions.

    A logical predicate is defined here as anything within a BooleanFunction
    that is not a BooleanFunction itself.

    c         s  s   |  ] } t  |  Vq d  S(   N(   t   _find_predicates(   R   RX   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pys	   <genexpr>  s    (   R   R   RR   RS   RT   (   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyRr    s    c         C  s  | d k r t d   n  t |   }  | r t |   } d d l m } g  | D] } | |  ^ qP } |  j t t | |    }  n  t	 |  t
  s |  St |   } | r t |  d k r |  St | d   d t \ } } | | } g  }	 g  | D] }
 |
 t k rd	 n d
 ^ q } xd t d
 d	 g d t |  D]D } |  j t t | |    t k r=|	 j | t |   q=q=Wt |	  d t |  d	 k } | d k s| d k r| rt | |	  St | |	  S(   sg  
    This function simplifies a boolean function to its simplified version
    in SOP or POS form. The return type is an Or or And object in SymPy.

    Parameters
    ==========

    expr : string or boolean expression

    form : string ('cnf' or 'dnf') or None (default).
        If 'cnf' or 'dnf', the simplest expression in the corresponding
        normal form is returned; if None, the answer is returned
        according to the form with fewest args (in CNF by default).

    deep : boolean (default True)
        Indicates whether to recursively simplify any
        non-boolean functions contained within the input.

    force : boolean (default False)
        As the simplifications require exponential time in the number of
        variables, there is by default a limit on expressions with 8 variables.
        When the expression has more than 8 variables only symbolical
        simplification (controlled by ``deep``) is made. By setting force to ``True``, this limit
        is removed. Be aware that this can lead to very long simplification times.

    Examples
    ========

    >>> from sympy.logic import simplify_logic
    >>> from sympy.abc import x, y, z
    >>> from sympy import S
    >>> b = (~x & ~y & ~z) | ( ~x & ~y & z)
    >>> simplify_logic(b)
    ~x & ~y

    >>> S(b)
    (z & ~x & ~y) | (~x & ~y & ~z)
    >>> simplify_logic(_)
    ~x & ~y

    R  R  s   form can be cnf or dnf onlyi(   R=   i   c         S  s   |  t  t f k S(   N(   R   R   (   RK   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     R   R   i   i    R2  i   N(   NR  R  (   R!   R   R   Rr  t   sympy.simplify.simplifyR=   R3  R'  R
  R   R   RB   R   R   R   R   R   Ro  Rq  (   R   t   formt   deept   forceR4  R=   R6  RN   R   t
   truthtableRX   Rg  t   big(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR     s0    +!
+%$ c   
      C  s  |  j  } t t t | g  | D] } d g d ^ q    } x |  j D] } | j rn | | d c d 7<qH | j r | | j d d c d 7<qH t | j  t d   | j D  } xx | j D]m } | j r | | d c d 7<| | d c | 7<q | j r&| | j d d c d 7<q t	 d   q WqH Wt
 t  } x= t t | j     D]# \ } }	 | t |	  j |  q_W| S(	   s  
    Assign a 5-item fingerprint to each symbol in the equation:
    [
    # of times it appeared as a Symbol,
    # of times it appeared as a Not(symbol),
    # of times it appeared as a Symbol in an And or Or,
    # of times it appeared as a Not(Symbol) in an And or Or,
    sum of the number of arguments with which it appeared
    as a Symbol, counting Symbol as 1 and Not(Symbol) as 2
    and counting self as 1
    ]

    >>> from sympy.logic.boolalg import _finger as finger
    >>> from sympy import And, Or, Not
    >>> from sympy.abc import a, b, x, y
    >>> eq = Or(And(Not(y), a), And(Not(y), b), And(x, y))
    >>> dict(finger(eq))
    {(0, 0, 1, 0, 2): [x], (0, 0, 1, 0, 3): [a, b], (0, 0, 1, 2, 2): [y]}
    >>> dict(finger(x & ~y))
    {(0, 1, 0, 0, 0): [y], (1, 0, 0, 0, 0): [x]}

    The equation must not have more than one level of nesting:

    >>> dict(finger(And(Or(x, y), y)))
    {(0, 0, 1, 0, 2): [x], (1, 0, 1, 0, 2): [y]}
    >>> dict(finger(And(Or(x, And(a, x)), y)))
    Traceback (most recent call last):
    ...
    NotImplementedError: unexpected level of nesting

    So y and x have unique fingerprints, but a and b do not.
    i    i   i   c         s  s   |  ] } t  | t  Vq d  S(   N(   R   R-   (   R   t   ai(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pys	   <genexpr>4	  s    i   ii   s   unexpected level of nesting(   RA   R'  R   R
  RT   RV   R   RB   t   sumR9   R   R   t   itert   itemsR   R   (
   t   eqR   t   fiRh  Rd   t   oRy  t   invR   R6  (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   _finger	  s&    !	5		&		%c         C  sD   d   } t  |   } t  |  } | | |  } | r@ | | f S| S(   s  
    Return the simplified version of bool1, and the mapping of variables
    that makes the two expressions bool1 and bool2 represent the same
    logical behaviour for some correspondence between the variables
    of each.
    If more than one mappings of this sort exist, one of them
    is returned.
    For example, And(x, y) is logically equivalent to And(a, b) for
    the mapping {x: a, y:b} or {x: b, y:a}.
    If no such mapping exists, return False.

    Examples
    ========

    >>> from sympy import SOPform, bool_map, Or, And, Not, Xor
    >>> from sympy.abc import w, x, y, z, a, b, c, d
    >>> function1 = SOPform([x, z, y],[[1, 0, 1], [0, 0, 1]])
    >>> function2 = SOPform([a, b, c],[[1, 0, 1], [1, 0, 0]])
    >>> bool_map(function1, function2)
    (y & ~z, {y: a, z: b})

    The results are not necessarily unique, but they are canonical. Here,
    ``(w, z)`` could be ``(a, d)`` or ``(d, a)``:

    >>> eq =  Or(And(Not(y), w), And(Not(y), z), And(x, y))
    >>> eq2 = Or(And(Not(c), a), And(Not(c), d), And(b, c))
    >>> bool_map(eq, eq2)
    ((x & y) | (w & ~y) | (z & ~y), {w: a, x: b, y: c, z: d})
    >>> eq = And(Xor(a, b), c, And(c,d))
    >>> bool_map(eq, eq.subs(c, x))
    (c & d & (a | b) & (~a | ~b), {a: a, b: b, c: d, d: x})

    c         S  s  |  j  | j  k r d St |  j  t | j  k r8 d S|  j rL i | |  6St |   } t |  } t |  t |  k r t Si  } x{ | j   D]m } | | k r t St | |  t | |  k r t Sx0 t | |  D] \ } } | | | | | <q Wq W| S(   s6  Return the mapping that equates variables between two
        simplified boolean expressions if possible.

        By "simplified" we mean that a function has been denested
        and is either an And (or an Or) whose arguments are either
        symbols (x), negated symbols (Not(x)), or Or (or an And) whose
        arguments are only symbols or negated symbols. For example,
        And(x, Not(y), Or(w, Not(z))).

        Basic.match is not robust enough (see issue 4835) so this is
        a workaround that is valid for simplified boolean expressions
        N(	   t	   __class__R!   RB   RT   RV   R  R   R`  R   (   R#  R$  t   f1t   f2t	   matchdictR   RX   RK   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR   f	  s&    	 (   R   (   t   bool1t   bool2R   Rd   R   R   (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   bool_mapC	  s    #	)
c          C  s  d d l  m }  m } d d l m } d d l m } m } m } m	 } m
 } m } | d  }	 | d  }
 | d  } t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   t j f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   t j f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   t j f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   t j f t | |	 |
  | |	 |
   t j f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |   | |	 | |
 |   f t | |	 |
  | |	 |   t |
 | k | |	 |
  | |	 |   f t | |	 |
  | |	 |   | |	 | |
 |   f t | |	 |
  | |	 |   | |	 |  |
 |   f t | |	 |
  | |	 |   t |
 | k  | |	 |
  | |	 |   f t | |	 |
  | |	 |   | |	 |  |
 |   f t | |	 |
  | |	 |
   t | |	 t d   | |
 t d    f f } | S(	   Ni(   t   Mint   Max(   t   Wild(   RP   RQ   t   Get   Gtt   Let   LtRd   R   R   i    (   t(   sympy.functions.elementary.miscellaneousR  R  t
   sympy.coreR  R7   RP   RQ   R  R  R  R  R'   R   R   R   (   R  R  R  RP   RQ   R  R  R  R  Rd   R   R   t   _matchers_and(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR   	  s8    .-'-'--'-''----6H66H6Rc          C  sB  d d l  m }  m } d d l m } d d l m } m } m } m	 } m
 } m } | d  }	 | d  }
 | d  } t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   t j f t | |	 |
  | |	 |
   t j f t | |	 |
  | |	 |
   t j f t | |	 |
  | |	 |
   t j f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   t j f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |   | |	 |  |
 |   f t | |	 |
  | |	 |   t |
 | k | |	 |  | |	 |
   f t | |	 |
  | |	 |   | |	 |  |
 |   f t | |	 |
  | |	 |   | |	 | |
 |   f t | |	 |
  | |	 |   t |
 | k | |	 |
  | |	 |   f t | |	 |
  | |	 |   | |	 | |
 |   f f } | S(   Ni(   R  R  (   R  (   RP   RQ   R  R  R  R  Rd   R   R   (   R  R  R  R  R  R7   RP   RQ   R  R  R  R  R+   R   R   R   (   R  R  R  RP   RQ   R  R  R  R  Rd   R   R   t   _matchers_or(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR   	  s6    .-----''''---'-6H66H<c          C  s  d d l  m }  m } d d l m } d d l m } m } m } m	 } m
 } m } | d  }	 | d  }
 | d  } t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   t j f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   t j f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |
   | |	 |
  f t | |	 |
  | |	 |   t | |	 |  |
 |   | |	 | |
 |    f t | |	 |
  | |	 |   t |
 | k t | |	 |  | |	 |
   t | |	 |
  | |	 |    f t | |	 |
  | |	 |   t | |	 |  |
 |   | |	 | |
 |    f t | |	 |
  | |	 |   t | |	 | |
 |   | |	 |  |
 |    f t | |	 |
  | |	 |   t |
 | k  t | |	 |  | |	 |
   t | |	 |
  | |	 |    f t | |	 |
  | |	 |   t | |	 | |
 |   | |	 |  |
 |    f f } | S(   Ni(   R  R  (   R  (   RP   RQ   R  R  R  R  Rd   R   R   (   R  R  R  R  R  R7   RP   RQ   R  R  R  R  R2   R   R   R'   R   (   R  R  R  RP   RQ   R  R  R  R  Rd   R   R   t   _matchers_xor(    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyR  	  sF    .------'-'-----3*$33*$9N(`   R[   t
   __future__R    R   t   collectionsR   t	   itertoolsR   R   t   sympy.core.addR   t   sympy.core.basicR   t   sympy.core.cacheR   t   sympy.core.compatibilityR   R	   R
   R   t   sympy.core.functionR   R   R   t   sympy.core.numbersR   t   sympy.core.operationsR   t   sympy.core.singletonR   R   t   sympy.core.sympifyR   R   R   t   sympy.utilities.iterablesR   R   Ri   R   R&   R"   Rc   R   R   R   R   t   boolR   R'   R+   R-   R2   R  R  R  R/   R;   R   R  R  R  R  R  R   R>   R   R  R  R  R  R  R"  R  R   R)  R-  R!   R1  R9  R=  R@  RB  RK  RL  R_  Ri  Ro  Rq  Rr  R   R  R  R   R   R  (    (    (    s2   lib/python2.7/site-packages/sympy/logic/boolalg.pyt   <module>   s   "	"r4uC				s?{s"OIt					!!.			1				C						=	IO	I	8	T	#	