def OneHot(*xs, simplify=True, conj=True): """ Return an expression that means "exactly one input function is true". If *simplify* is ``True``, return a simplified expression. If *conj* is ``True``, return a CNF. Otherwise, return a DNF. """ xs = [Expression.box(x).node for x in xs] terms = list() if conj: for x0, x1 in itertools.combinations(xs, 2): terms.append(exprnode.or_(exprnode.not_(x0), exprnode.not_(x1))) terms.append(exprnode.or_(*xs)) y = exprnode.and_(*terms) else: for i, xi in enumerate(xs): zeros = [exprnode.not_(x) for x in xs[:i] + xs[i+1:]] terms.append(exprnode.and_(xi, *zeros)) y = exprnode.or_(*terms) if simplify: y = y.simplify() return _expr(y)
def OneHot(*xs, simplify=True, conj=True): """ Return an expression that means "exactly one input function is true". If *simplify* is ``True``, return a simplified expression. If *conj* is ``True``, return a CNF. Otherwise, return a DNF. """ xs = [Expression.box(x).node for x in xs] terms = list() if conj: for x0, x1 in itertools.combinations(xs, 2): terms.append(exprnode.or_(exprnode.not_(x0), exprnode.not_(x1))) terms.append(exprnode.or_(*xs)) y = exprnode.and_(*terms) else: for i, xi in enumerate(xs): zeros = [exprnode.not_(x) for x in xs[:i] + xs[i + 1:]] terms.append(exprnode.and_(xi, *zeros)) y = exprnode.or_(*terms) if simplify: y = y.simplify() return _expr(y)
def NHot(n, *xs, simplify=True): """ Return an expression that means "exactly N input functions are true". If *simplify* is ``True``, return a simplified expression. """ if not isinstance(n, int): raise TypeError("expected n to be an int") if not 0 <= n <= len(xs): fstr = "expected 0 <= n <= {}, got {}" raise ValueError(fstr.format(len(xs), n)) xs = [Expression.box(x).node for x in xs] num = len(xs) terms = list() for hot_idxs in itertools.combinations(range(num), n): hot_idxs = set(hot_idxs) _xs = [xs[i] if i in hot_idxs else exprnode.not_(xs[i]) for i in range(num)] terms.append(exprnode.and_(*_xs)) y = exprnode.or_(*terms) if simplify: y = y.simplify() return _expr(y)
def NHot(n, *xs, simplify=True): """ Return an expression that means "exactly N input functions are true". If *simplify* is ``True``, return a simplified expression. """ if not isinstance(n, int): raise TypeError("expected n to be an int") if not 0 <= n <= len(xs): fstr = "expected 0 <= n <= {}, got {}" raise ValueError(fstr.format(len(xs), n)) xs = [Expression.box(x).node for x in xs] num = len(xs) terms = list() for hot_idxs in itertools.combinations(range(num), n): hot_idxs = set(hot_idxs) _xs = [ xs[i] if i in hot_idxs else exprnode.not_(xs[i]) for i in range(num) ] terms.append(exprnode.and_(*_xs)) y = exprnode.or_(*terms) if simplify: y = y.simplify() return _expr(y)
def Unequal(*xs, simplify=True): """Expression inequality operator If *simplify* is ``True``, return a simplified expression. """ xs = [Expression.box(x).node for x in xs] y = exprnode.not_(exprnode.eq(*xs)) if simplify: y = y.simplify() return _expr(y)
def Xnor(*xs, simplify=True): """Expression exclusive nor (XNOR) operator If *simplify* is ``True``, return a simplified expression. """ xs = [Expression.box(x).node for x in xs] y = exprnode.not_(exprnode.xor(*xs)) if simplify: y = y.simplify() return _expr(y)
def Nand(*xs, simplify=True): """Expression NAND (not AND) operator If *simplify* is ``True``, return a simplified expression. """ xs = [Expression.box(x).node for x in xs] y = exprnode.not_(exprnode.and_(*xs)) if simplify: y = y.simplify() return _expr(y)
def Not(x, simplify=True): """Expression negation operator If *simplify* is ``True``, return a simplified expression. """ x = Expression.box(x).node y = exprnode.not_(x) if simplify: y = y.simplify() return _expr(y)
def OneHot0(*xs, simplify=True, conj=True): """ Return an expression that means "at most one input function is true". If *simplify* is ``True``, return a simplified expression. If *conj* is ``True``, return a CNF. Otherwise, return a DNF. """ xs = [Expression.box(x).node for x in xs] terms = list() if conj: for x0, x1 in itertools.combinations(xs, 2): terms.append(exprnode.or_(exprnode.not_(x0), exprnode.not_(x1))) y = exprnode.and_(*terms) else: for _xs in itertools.combinations(xs, len(xs) - 1): terms.append(exprnode.and_(*[exprnode.not_(x) for x in _xs])) y = exprnode.or_(*terms) if simplify: y = y.simplify() return _expr(y)
def __invert__(self): return _expr(exprnode.not_(self.node))