running.t
running.t

Reputation: 5709

Is there an implication logical operator in python?

I would like to write a statement in python with logical implication. Something like:

if x => y:
  do_sth()

Of course, I know I could use:

if (x and y) or not x:
  do_sth()

But is there a logical operator for this in python?

Upvotes: 28

Views: 36528

Answers (10)

Zen
Zen

Reputation: 143

Although it looks terrible, you can represent "A implies B" in Python by "A <= B".

from itertools import product

print("A        B        A => B")
for t in product([True, False], [True, False]):
    print(f"{str(t[0]):5}    {str(t[1]):5}    {str(t[0] <= t[1]):5}")

enter image description here

Upvotes: 0

einy
einy

Reputation: 33

You can use == (which is an ARITHMETICAL operator) instead of logic equivalency as well as use <= (which is an ARITHMETICAL operator) instead of logic implication. But you get onto a minefield in this case, because:

  1. you should be sure that your arguments are pure int 0 or 1 only,
  2. precedence of arithmetical <= and == is HIGHER than precedence of logical not (but it should be even lower than precedence of or in a world of logic),
  3. an "arrow" you see as <= looks opposite to an actual direction of implication (which can be confusing).

Be careful.

Upvotes: 0

butichex
butichex

Reputation: 9

You can use the comparison operator <= to get an implication for two variables. Examples:

A   B   A <- B  A <= B
0   0   1       1
0   1   1       1
1   0   0       0
1   1   1       1

Upvotes: 1

Luka Dragar
Luka Dragar

Reputation: 3

I found XOR to be a good solution. you can change A implies B to not A or B. Then you use xor to negate A like this

A^1 or B

Since A xor(^) 1 is equal to not A

Upvotes: 0

Gilly
Gilly

Reputation: 1809

I would argue a more readable one-liner would be

x_implies_y = y if x else True

In your original example:

if (y if x else True): do_sth()

Upvotes: 3

David Zaragoza
David Zaragoza

Reputation: 149

There is a converse implication operator:

if y ** x:
  do_sth()

This reads: If y is implied by x.

Credits to https://github.com/cosmologicon/pywat

Upvotes: 11

Adam Sosnowski
Adam Sosnowski

Reputation: 1284

Just because it's funny: x => y could be bool(x) <= bool(y) in python.

Upvotes: 22

SylvainD
SylvainD

Reputation: 1763

Additional details based on what I have found here and there as I was looking for an implication operator : you can use a clever hack to define your own operators. Here is a running example annotated with sources leading me to this result.

#!/usr/bin/python

# From http://code.activestate.com/recipes/384122/ (via http://stackoverflow.com/questions/932328/python-defining-my-own-operators)
class Infix:
    def __init__(self, function):
        self.function = function
    def __ror__(self, other):
        return Infix(lambda x, self=self, other=other: self.function(other, x))
    def __rlshift__(self, other):
        return Infix(lambda x, self=self, other=other: self.function(other, x))
    def __or__(self, other):
        return self.function(other)
    def __rshift__(self, other):
        return self.function(other)
    def __call__(self, value1, value2):
        return self.function(value1, value2)

from itertools import product

booleans = [False,True]

# http://stackoverflow.com/questions/16405892/is-there-an-implication-logical-operator-in-python
# http://jacob.jkrall.net/lost-operator/
operators=[
    (Infix(lambda p,q: False),                  "F"),
    (Infix(lambda p,q: True),                   "T"),
    (Infix(lambda p,q: p and q),                "&"),
    (Infix(lambda p,q: p or q)           ,      "V"),
    (Infix(lambda p,q: p != q)           ,      "^"),
    (Infix(lambda p,q: ((not p) or not q)),     "nad"),
    (Infix(lambda p,q: ((not p) and not q)),    "nor"),
    (Infix(lambda p,q: ((not p) or q)),         "=>"),
    ]

for op,sym in operators:
    print "\nTruth tables for %s" % sym

    print "\np\tq\tp %s q\tq %s p" % (sym,sym)
    for p,q in product(booleans,repeat=2):
        print "%d\t%d\t%d\t%d" % (p,q,p |op| q,q |op| p)

    print "\np\tq\tr\tp %s q\tq %s r\t(p %s q) %s r\tp %s (q %s r)\tp %s q %s r" % (sym,sym,sym,sym,sym,sym,sym,sym)
    for p,q,r in product(booleans,repeat=3):
        print "%d\t%d\t%d\t%d\t%d\t%d\t\t%d\t\t%d" % (p,q,r,p |op| q,q |op| r, (p |op| q) |op| r, p |op| (q |op| r), p |op| q |op| r)
        assert( (p |op| q) |op| r == p |op| q |op| r)

Upvotes: 3

Gareth Latty
Gareth Latty

Reputation: 88977

Your question asks if there is a single logical operator for this in Python, the simple answer is no: The docs list boolean operations, and Python simply doesn't have anything like that.

Obviously, as Juampi's answer points out, there are logically equivalent operations that are a little shorter, but no single operators as you asked.

Upvotes: 6

Juan Pablo Rinaldi
Juan Pablo Rinaldi

Reputation: 3504

p => q is the same as not(p) or q, so you could try that!

Upvotes: 47

Related Questions