user3425706
user3425706

Reputation:

Getting the return value of functions passed in as variables

I am currently trying to write a function which takes as its parameters two truth functions and returns a boolean based on whether or not they are logically equivalent. For example, let say the main function is

def logical_equiv(function1, function2):
    #function1 and function2 are truth functions

I have done a check to see if the two functions passed in are the same by doing

def logical_equiv(function1, function2):
    if function1 == function2:
         return True

But how do I check the actual return value of function1 and function2? To be clearer, let say function1 takes two parameters P and Q, then returned (not P) or (not Q) and function2 also takes two parameters P and Q then returned not(P and Q), how would i check that in my logical_equiv function? I tried doing

def logical_equiv(function1, function2):
     if function1 == (not P) or (not Q):
          #do something

But this returns the errorNameError: name 'P' is not defined Printing out the function from logical_equiv returns a memory address.

Upvotes: 0

Views: 71

Answers (2)

AChampion
AChampion

Reputation: 30258

If you want to see if they are logically equivalent using the same arguments:

def logical_equiv(function1, function2, *args):
    return function1(*args) == function2(*args)

Then:

>>> func1 = lambda P, Q: (not P) or (not Q)
>>> func2 = lambda P, Q: not(P and Q)
>>> logical_equiv(func1, func2, True, False)
True

This could be extended to any number of arguments:

>>> func1 = lambda P, Q, R: (not P) or (not Q) or (not R)
>>> func2 = lambda P, Q, R: not(P and Q and R)
>>> logical_equiv(func1, func2, True, False, True)
True

If you need to test all valid combinations of [True, False] for n parameters, then you can do:

from itertools import product
def logical_equiv(f1, f2):
    n = f1.__code__.co_argcount        # @dopstart
    if n != f2.__code__.co_argcount:
        return False
    return all(f1(*args) == f2(*args) for args in product([True, False], repeat=n))

>>> func1 = lambda P, Q, R: (not P) or (not Q) or (not R)
>>> func2 = lambda P, Q, R: not(P and Q and R)
>>> logical_equiv(func1, func2)
True

Upvotes: 2

WilHall
WilHall

Reputation: 11994

I think you would want to do:

def logical_equiv(function1, function2):
     if function1() in [(not P), (not Q)]:
          #do something

Of course, you need to define P and Q. Remember, function1 is just a reference to the function, whereas function1() calls the function, returning its value.

Additionally, to check if the output of function1 and function2 are equivalent, just do:

if function1() == function2():
    ...

Upvotes: 0

Related Questions