# Exotic Logics

William Clifford mr.william.clifford at gmail.com
Wed Jun 17 01:46:14 EDT 2009

```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"""
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?