Exemple #1
0
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)
Exemple #2
0
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)
Exemple #3
0
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)
Exemple #4
0
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)
Exemple #5
0
def Or(*xs, simplify=True):
    """Expression disjunction (sum, OR) operator

    If *simplify* is ``True``, return a simplified expression.
    """
    xs = [Expression.box(x).node for x in xs]
    y = exprnode.or_(*xs)
    if simplify:
        y = y.simplify()
    return _expr(y)
Exemple #6
0
def Or(*xs, simplify=True):
    """Expression disjunction (sum, OR) operator

    If *simplify* is ``True``, return a simplified expression.
    """
    xs = [Expression.box(x).node for x in xs]
    y = exprnode.or_(*xs)
    if simplify:
        y = y.simplify()
    return _expr(y)
Exemple #7
0
def Nor(*xs, simplify=True):
    """Expression NOR (not OR) operator

    If *simplify* is ``True``, return a simplified expression.
    """
    xs = [Expression.box(x).node for x in xs]
    y = exprnode.not_(exprnode.or_(*xs))
    if simplify:
        y = y.simplify()
    return _expr(y)
Exemple #8
0
def Nor(*xs, simplify=True):
    """Expression NOR (not OR) operator

    If *simplify* is ``True``, return a simplified expression.
    """
    xs = [Expression.box(x).node for x in xs]
    y = exprnode.not_(exprnode.or_(*xs))
    if simplify:
        y = y.simplify()
    return _expr(y)
Exemple #9
0
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)
Exemple #10
0
def Majority(*xs, simplify=True, conj=False):
    """
    Return an expression that means
    "the majority of input functions are 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]
    if conj:
        terms = list()
        for _xs in itertools.combinations(xs, (len(xs) + 1) // 2):
            terms.append(exprnode.or_(*_xs))
        y = exprnode.and_(*terms)
    else:
        terms = list()
        for _xs in itertools.combinations(xs, len(xs) // 2 + 1):
            terms.append(exprnode.and_(*_xs))
        y = exprnode.or_(*terms)
    if simplify:
        y = y.simplify()
    return _expr(y)
Exemple #11
0
def Majority(*xs, simplify=True, conj=False):
    """
    Return an expression that means
    "the majority of input functions are 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]
    if conj:
        terms = list()
        for _xs in itertools.combinations(xs, (len(xs) + 1) // 2):
            terms.append(exprnode.or_(*_xs))
        y = exprnode.and_(*terms)
    else:
        terms = list()
        for _xs in itertools.combinations(xs, len(xs) // 2 + 1):
            terms.append(exprnode.and_(*_xs))
        y = exprnode.or_(*terms)
    if simplify:
        y = y.simplify()
    return _expr(y)
Exemple #12
0
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)
Exemple #13
0
def AchillesHeel(*xs, simplify=True):
    r"""
    Return the Achille's Heel function, defined as:
    :math:`\prod_{i=0}^{n/2-1}{X_{2i} + X_{2i+1}}`.

    If *simplify* is ``True``, return a simplified expression.
    """
    nargs = len(xs)
    if nargs & 1:
        fstr = "expected an even number of arguments, got {}"
        raise ValueError(fstr.format(nargs))
    xs = [Expression.box(x).node for x in xs]
    y = exprnode.and_(*[exprnode.or_(xs[2*i], xs[2*i+1])
                        for i in range(nargs // 2)])
    if simplify:
        y = y.simplify()
    return _expr(y)
Exemple #14
0
def AchillesHeel(*xs, simplify=True):
    r"""
    Return the Achille's Heel function, defined as:
    :math:`\prod_{i=0}^{n/2-1}{X_{2i} + X_{2i+1}}`.

    If *simplify* is ``True``, return a simplified expression.
    """
    nargs = len(xs)
    if nargs & 1:
        fstr = "expected an even number of arguments, got {}"
        raise ValueError(fstr.format(nargs))
    xs = [Expression.box(x).node for x in xs]
    y = exprnode.and_(
        *[exprnode.or_(xs[2 * i], xs[2 * i + 1]) for i in range(nargs // 2)])
    if simplify:
        y = y.simplify()
    return _expr(y)
Exemple #15
0
def Mux(fs, sel, simplify=True):
    """
    Return an expression that multiplexes a sequence of input functions over a
    sequence of select functions.
    """
    # convert Mux([a, b], x) to Mux([a, b], [x])
    if isinstance(sel, Expression):
        sel = [sel]

    if len(sel) < clog2(len(fs)):
        fstr = "expected at least {} select bits, got {}"
        raise ValueError(fstr.format(clog2(len(fs)), len(sel)))

    it = boolfunc.iter_terms(sel)
    y = exprnode.or_(*[exprnode.and_(f.node, *[lit.node for lit in next(it)])
                       for f in fs])
    if simplify:
        y = y.simplify()
    return _expr(y)
Exemple #16
0
def Mux(fs, sel, simplify=True):
    """
    Return an expression that multiplexes a sequence of input functions over a
    sequence of select functions.
    """
    # convert Mux([a, b], x) to Mux([a, b], [x])
    if isinstance(sel, Expression):
        sel = [sel]

    if len(sel) < clog2(len(fs)):
        fstr = "expected at least {} select bits, got {}"
        raise ValueError(fstr.format(clog2(len(fs)), len(sel)))

    it = boolfunc.iter_terms(sel)
    y = exprnode.or_(
        *[exprnode.and_(f.node, *[lit.node for lit in next(it)]) for f in fs])
    if simplify:
        y = y.simplify()
    return _expr(y)
Exemple #17
0
 def __or__(self, other):
     other_node = self.box(other).node
     return _expr(exprnode.or_(self.node, other_node))
Exemple #18
0
 def __or__(self, other):
     other_node = self.box(other).node
     return _expr(exprnode.or_(self.node, other_node))