I have written the following code in Python where the intent is to make a list of every possible boolean function which takes arguments from the set var_set
. So for instance if var_set
is {"P","Q"}
then all_var_evals(var_set)
should contain four functions. One function would return True
on input "P"
and input "Q"
, another would return True
on input "P"
but False
on input "Q"
, and so on.
def all_var_evals(var_set):
# The bucket is an "accumulator" variable, into which I will place each evaluation as I
# construct them. The bucket will then be returned at the end.
bucket = []
var_list = list(var_set) # Gives the variables an indexing (ordering)
for row in range(2**(len(var_set))): # 2^n evaluations
to_bin = row
func_list = []
while to_bin != 0:
func_list.insert(0, to_bin % 2)
to_bin -= to_bin % 2
to_bin //= 2
while len(func_list) < len(var_list):
func_list.insert(0,0)
def f():
return lambda x: func_list[var_list.index(x)]
bucket.append(f())
return bucket
However, after testing, I find that every function in the list seems to return True
on every input. I assume this is because of some kind of copy issue, like every time func_list
takes new values, every function in the bucket
now points to it. I tried resolving the copy issue by making a closure, hence why it has
def f():
return lambda x: func_list[var_list.index(x)]
However, that did not resolve the issue. Since I've never implemented closures in Python, though, I wasn't sure how they work and after reading up on them, I still can't see how to get the desired behavior.
I also tried using .hardcopy()
in a few different ways, none of which worked.
Not tested, but try to replace
def f():
return lambda x: func_list[var_list.index(x)]
bucket.append(f())
by
bucket.append(lambda x, fl=func_list: fl[var_list.index(x)])