Source code for pyec.util.TernaryString

from numpy import *
import copy

def binary(x, digits=10):
   ret = ""
   num = x
   mask = 1L
   for i in xrange(digits):
      ret += str(num & mask)
      num >>= 1
   return ret

[docs]class TernaryString(object): """A ternary string with three values: True, False, and Unknown""" def __init__(self, base, known): """ base is an (integer) object whose bytes are treated as a bit string known is a mask to determine which values are indefinite """ self.base = base self.known = known def __str__(self): return str(self.known & self.base) def __repr__(self): return repr(self.known & self.base) def __eq__(self, x): if isinstance(x, TernaryString): return (self.known == x.known) and ((self.base & self.known) == (x.base & x.known)) else: return (self.known & self.base) == (self.known & x) def __ne__(self, x): return (self.known != x.known) or ((self.base & self.known) != (x.base & x.known)) def __lt__(self, x): """Test whether the known portions are known and equal in the other""" return self.__le__(x) and self.__ne__(x) def __le__(self, x): """Test whether the known portions are known and equal in the other""" return ((self.known & x.known) == self.known) \ and ((self.base & self.known) == (x.base & self.known)) def __gt__(self, x): return self.__ge__(x) and self.__ne__(x) def __ge__(self, x): """Test whether the known portions are known and equal in the other""" return ((self.known & x.known) == x.known) \ and ((self.base & x.known) == (x.base & x.known)) def __add__(self, x): return TernaryString(self.base | x.base, self.known | x.known) def __mult__(self, x): if isinstance(x, TernaryString): return TernaryString(self.base & x.base, self.known & x.known) elif isinstance(x, ndarray): y = zeros(len(x)) for i in xrange(len(y)): if self[i]: y[i] = x[i] return y return None def __getitem__(self, i): """True if index i is known and equal to 1, else False""" if isinstance(i, slice): base = copy.copy(self.base) known = copy.copy(self.known) if i.stop: mask = ((1L) << (i.stop + 1)) - 1L known &= mask if i.start: base >>= i.start known >>= i.start return TernaryString(base, known) return ((self.base & (1L << i)) & self.known) != 0L def __setitem__(self, i, val): mask = 1L << i val = bool(val) if val: self.known |= mask self.base |= mask else: self.known |= mask self.base &= ~mask
[docs] def distance(self, x, upTo): """hamming distance""" mask = 1L z = (self.base & ~x.base) | (~self.base & x.base) total = 0 for i in xrange(upTo): if (mask & z) > 0: total += 1 mask <<= 1 return total
def toArray(self, numBits): x = [] for i in xrange(numBits): x.append(self[i] and 1.0 or 0.0) return array(x) @classmethod def fromArray(cls, arr): ret = TernaryString(0L, 0L) for i in xrange(len(arr)): ret[i] = arr[i] > 0.0 return ret """ TODO: __len__, __getitem__, __setitem__, __str__ """