I was staring at a logic table the other day, and I asked myself, "what if one wanted to play with exotic logics; how might one do it?" I did some searching but not being too sure of what to look for and carried away with my own enthusiasm for the idea, I didn't find much. What I've come up with is, no doubt, inefficient, naive, poor python style, and probably wrong in fundamental ways too subtle for me, but here it is:
import itertools import operator class Logic(): """class of generic logic operators""" @staticmethod def lsd(rdx, n): """yield up base rdx digits of n in least significant order""" while n > 0: q, r = divmod(n, rdx) n = q yield r @staticmethod def rdxn(rdx, seq): """reduce a sequence of numbers by powers of rdx""" return reduce(operator.add, map(operator.mul, seq, (pow(rdx, i) for i in range(len(seq))))) @staticmethod def pute(rdx, opr, arg): """a logical primitive which returns 0 or 1.""" if arg < 0: return 0 o = tuple(lsd(rdx, opr)) try: return o[arg] except IndexError: return 0 @staticmethod def make_puter(rdx, opr): """return a function based on pute.""" o = tuple(Logic.lsd(rdx, opr)) def puter(arg): if arg < 0: return 0 try: return o[arg] except IndexError: return 0 return puter @staticmethod def make_inputs(rdx, *args): """yield a stripe of rdxn digits from args.""" largs = [Logic.lsd(rdx, a) for a in args] for i in itertools.izip_longest(*largs, fillvalue=0): yield Logic.rdxn(rdx, i) @staticmethod def compute(rdx, opr, *args): """return a number computed from opr of rdx.""" puter = Logic.make_puter(rdx, opr) inputs = Logic.make_inputs(rdx, *args) outputs = [puter(i) for i in inputs] return Logic.rdxn(rdx, outputs) @staticmethod def make_computer(rdx, opr): """return a computer of opr, rdx.""" def computer(*args): puter = Logic.make_puter(rdx, opr) inputs = Logic.make_inputs(rdx, *args) outputs = [puter(i) for i in inputs] return Logic.rdxn(rdx, outputs) return computer def __init__(self, rdx, opr): self._computer = Logic.make_computer(rdx, opr) def __call__(self, *args): return self._computer(*args) This seemed to be working for the limited tests I did on it, while I was doing them. The following checked out last time I tried: >>> and_ = Logic(2, 8) >>> or_ = Logic(2, 14) >>> xor = Logic(2, 6) I have no idea how to validate the results of the trinary and beyond logics. Thanks for reading and trying this out. Corrections? Criticism? Comments? -- William Clifford -- http://mail.python.org/mailman/listinfo/python-list