def eliminate_implications(s):
    """Change >>, <<, and <=> into &, |, and ~. That is, return an Expr
    that is equivalent to s, but has only &, |, and ~ as logical operators.
    >>> eliminate_implications(A >> (~B << C))
    ((~B | ~C) | ~A)
    >>> eliminate_implications(A ^ B)
    ((A & ~B) | (~A & B))
    """
    if not s.args or is_symbol(s.op): return s     ## (Atoms are unchanged.)
    args = map(eliminate_implications, s.args)
    a, b = args[0], args[-1]
    if s.op == '>>':
        return (b | ~a)
    elif s.op == '<<':
        return (a | ~b)
    elif s.op == '<=>':
        return (a | ~b) & (b | ~a)
    elif s.op == '^':
        assert len(args) == 2   ## TODO: relax this restriction
        return (a & ~b) | (~a & b)
    else:
        assert s.op in ('&', '|', '~')
        return Expr(s.op, *args)
def eliminate_implications(s):
    """Change >>, <<, and <=> into &, |, and ~. That is, return an Expr
    that is equivalent to s, but has only &, |, and ~ as logical operators.
    >>> eliminate_implications(A >> (~B << C))
    ((~B | ~C) | ~A)
    >>> eliminate_implications(A ^ B)
    ((A & ~B) | (~A & B))
    """
    if not s.args or is_symbol(s.op): return s     ## (Atoms are unchanged.)
    args = map(eliminate_implications, s.args)
    a, b = args[0], args[-1]
    if s.op == '>>':
        return (b | ~a)
    elif s.op == '<<':
        return (a | ~b)
    elif s.op == '<=>':
        return (a | ~b) & (b | ~a)
    elif s.op == '^':
        assert len(args) == 2   ## TODO: relax this restriction
        return (a & ~b) | (~a & b)
    else:
        assert s.op in ('&', '|', '~')
        return Expr(s.op, *args)
def eliminate_implications ( s ) : if not s . args or is_symbol ( s . op ) : return s ## (Atoms are unchanged.) args = map ( eliminate_implications , s . args ) a , b = args [ 0 ] , args [ - 1 ] if s . op == '>>' : return ( b | ~ a ) elif s . op == '<<' : return ( a | ~ b ) elif s . op == '<=>' : return ( a | ~ b ) & ( b | ~ a ) elif s . op == '^' : assert len ( args ) == 2 ## TODO: relax this restriction return ( a & ~ b ) | ( ~ a & b ) else : assert s . op in ( '&' , '|' , '~' ) return Expr ( s . op , * args )
Change >>, <<, and <=> into &, |, and ~. That is, return an Expr
    that is equivalent to s, but has only &, |, and ~ as logical operators.
    >>> eliminate_implications(A >> (~B << C))
    ((~B | ~C) | ~A)
    >>> eliminate_implications(A ^ B)
    ((A & ~B) | (~A & B))
Change >> << and < = > into & | and ~ . That is return an Expr that is equivalent to s but has only & | and ~ as logical operators . >>> eliminate_implications ( A >> ( ~B << C )) (( ~B | ~C ) | ~A ) >>> eliminate_implications ( A ^ B ) (( A & ~B ) | ( ~A & B ))