def __and__(self, other): # heavy! res = set() for t1 in self.anf: for t2 in other.anf: res ^= {self._merge_products(t1, t2)} return Bit(res)
def compute_anfs(bit): if bit.is_input(): bit.meta["anf"] = Bit(bit.name()) return if bit.is_const(): bit.meta["anf"] = Bit(bit.value()) return TreeBit = bit.__class__ res = [] for sub in bit.args: if isinstance(sub, TreeBit) and "anf" not in sub.meta: compute_anfs(sub) res.append(sub.meta["anf"]) bit.meta["anf"] = bit.OP.eval(bit.op, res)
def subs(self, lst): if len(lst) == 0: return self if len(lst) > 1: res = self.subs([lst[0]]) return res.subs(lst[1:]) var, bit = lst[0] # print("subs", var, bit) if isinstance(var, Bit): var = var.var() if isinstance(bit, int): bit = Bit(bit) assert isinstance(var, str) assert isinstance(bit, Bit) res = self.anf.copy() for t1 in self.anf: if var in t1: res ^= {t1} i = t1.index(var) t1 = t1[:i] + t1[i + 1:] for t2 in bit.anf: res ^= {self._merge_products(t1, t2)} return Bit(res)
def __xor__(self, other): if not isinstance(other, Bit): other = Bit(other) return Bit(self.anf ^ other.anf)
def test_bit(): from cry.py.anf.symbolic import Bit assert str(Bit(0)) == "0" assert str(Bit(1)) == "1" assert str(Bit("x1")) == "x1" assert str(Bit("x2")) == "x2" assert str(Bit("x1") & Bit("x2")) == "x1*x2" assert str(Bit("x1") ^ Bit("x2")) == "x1 ^ x2" assert str( Bit(1) * Bit("x1") * Bit("x2") * Bit(1) + Bit(0) * Bit("x3") + Bit(1)) == "1 ^ x1*x2" ex = Bit("a") * Bit("b") + Bit("R") * Bit("b") bb = Bit(1) + Bit("Q") + Bit("c") * Bit("b") assert str(ex.subs([("b", bb)]) + 1) \ == "1 ^ Q*R ^ Q*a ^ R ^ R*b*c ^ a ^ a*b*c" assert {Bit(0): 123}[0] == 123
def __eq__(self, other): if isinstance(other, int) or isinstance(other, str): return self == Bit(other) assert isinstance(other, Bit) return self.anf == other.anf
def is_var(self): if len(self.anf) == 1: for t in self.anf: if len(t) == 1: return True return False def var(self): if len(self.anf) == 1: for t in self.anf: if len(t) == 1: return t[0] raise ValueError("Not a single variable!") Bit.ZERO = Bit(0) Bit.ONE = Bit(1) def test_bit(): from cry.py.anf.symbolic import Bit assert str(Bit(0)) == "0" assert str(Bit(1)) == "1" assert str(Bit("x1")) == "x1" assert str(Bit("x2")) == "x2" assert str(Bit("x1") & Bit("x2")) == "x1*x2" assert str(Bit("x1") ^ Bit("x2")) == "x1 ^ x2" assert str( Bit(1) * Bit("x1") * Bit("x2") * Bit(1) + Bit(0) * Bit("x3") + Bit(1)) == "1 ^ x1*x2"