from itertools import product from random import random funcs = [ lambda x1, x2, x3, x4: not x2, lambda x1, x2, x3, x4: x1, lambda x1, x2, x3, x4: x1 ^ x4, lambda x1, x2, x3, x4: x3, ] sequential_sync_funcs = [ lambda x1, x2, x3, x4: not x2, lambda x1, x2, x3, x4: not x2, lambda x1, x2, x3, x4: (not x2) ^ x4, lambda x1, x2, x3, x4: (not x2) ^ x4, ] probabilistic_funcs = [ (1, funcs[0], None), (1, funcs[1], None), (1, funcs[2], None), (0.5, funcs[3], lambda x1, x2, x3, x4: not x3), ] nodes = [] def init(initial_state): global nodes nodes = [bool(i) for i in initial_state] assert len(funcs) == len(nodes) def synchronous_update(): global nodes, funcs temp = nodes.copy() for i in range(len(funcs)): temp[i] = funcs[i](*nodes) nodes = temp def sequential_update(order): global nodes, funcs assert len(order) == len(nodes) for i in order: nodes[i] = funcs[i](*nodes) def probabilistic_update(): global nodes, probabilistic_funcs funcs = probabilistic_funcs temp = nodes.copy() for i in range(len(funcs)): probability, *nodeFuncs = funcs[i] func = nodeFuncs[0] if probability >= random() else nodeFuncs[1] temp[i] = func(*nodes) nodes = temp def state_to_str(): return "".join(str(int(i)) for i in nodes) def simulate(initial_state): print("press ENTER to simulate one step. press 'q' before ENTER to exit") init(initial_state) state = state_to_str() while input() != "q": update() print(state + " -> " + state_to_str(), end="") def get_table(): for i in product((0, 1), repeat=4): init(tuple(i)) state = state_to_str() update() print(state + " -> " + state_to_str()) def update(): # return synchronous_update() # return sequential_update([0, 1, 2, 3]) return probabilistic_update() # return block_sequential_update(...) # return asynchronous_deterministic_update(...) def main(): get_table() # simulate([0,0,0,0]) if __name__ == "__main__": main()