Exemple #1
0
def SMerge(a, b, nc, prefix=''):
    a = a[:nc]
    b = b[:nc]
    na = len(a)
    nb = len(b)
    if na == nb == nc == 1:
        if prefix == '':
            prefix = 'c'
        c = exprvars(prefix, 1)
        s = [~a[0] | c[0], ~b[0] | c[0]]
        return (c, s)
    elif (na + nb) <= nc:
        return Merge(a, b, prefix)
    else:
        c = exprvars(prefix + 'c', (1, nc))
        d, sd = SMerge(even(a), even(b), (nc + 1) // 2 + 1, prefix + 'd')
        e, se = SMerge(odd(a), odd(b), (nc + 1) // 2, prefix + 'e')
        v = [d[0]] + list(c)
        sp = []
        for i in range((nc - 1) // 2):
            sp += comp(d[i + 1], e[i], c[2 * i + 1], c[2 * i + 2])
        if nc % 2 == 0:
            sp += [~d[-1] | c[-1], ~e[-1] | c[-1]]
        s = sd + se + sp
        return (v, s)
    def __init__(self, file_enc, file_org):
        self.gate = ''  #gate
        self.ins = []  #inputs
        self.out = ''  #output
        self.netlist = {}  #dictionary of netlist
        self.outputs = []  #output list
        self.inputs = []  #input list
        self.truth_tbl_output = {}  #truth values for each output wires
        self.IpOp_parse_done = 0
        #------------------temp variables--------------#
        self.Ip = pyedaitr.exprvars('Ip', 1)
        self.KeyIp = pyedaitr.exprvars('KeyIp', 1)
        #------------------encA variables--------------#
        self.IpE = pyedaitr.exprvars('Ip', 1)
        self.KeyIpE = pyedaitr.exprvars('KeyIp', 1)
        # #------------------encB variables--------------#
        # self.IpB=pyedaitr.exprvars('Ip',1)
        # self.KeyIpB=pyedaitr.exprvars('KeyIp',1)
        #------------------orgN variables--------------#
        self.IpO = pyedaitr.exprvars('Ip', 1)

        self.y1 = None
        self.y2 = None
        self.xd = None
        self.yd = None

        self.keys = ()
        self.noskeys = 0
        self.nosips = 0

        self.do_mitter_net(file_enc)
        self.do_original_net(file_org)
        self.eliminate_key()
Exemple #3
0
def Merge(a, b, prefix=''):
    na = len(a)
    nb = len(b)
    if na == 0:
        return (b, [])
    elif nb == 0:
        return (a, [])
    elif na == 1 and nb == 1:
        if prefix == '':
            prefix = 'c'
        c = exprvars(prefix, 2)
        s = comp(a[0], b[0], c[0], c[1])
        return (c, s)
    else:
        d, sd = Merge(even(a), even(b), prefix + 'd')
        e, se = Merge(odd(a), odd(b), prefix + 'e')

    if (na % 2) == (nb % 2):
        nc = na + nb - 2
        c = exprvars(prefix + 'c', (1, nc + 1))
        if (na % 2) == 0:
            v = [d[0]] + list(c) + [e[-1]]
        else:
            v = [d[0]] + list(c) + [d[-1]]
    else:
        nc = na + nb - 1
        c = exprvars(prefix + 'c', (1, nc + 1))
        v = [d[0]] + list(c)

    sp = []
    for i in range(nc // 2):
        sp += comp(d[i + 1], e[i], c[2 * i + 1], c[2 * i + 2])
    s = sd + se + sp
    return (v, s)
Exemple #4
0
def halver(g, n, kf, kl, epsilon, xlist=None):
    ninputs = 1 << n

    # input vectors
    xset = set(xlist) if xlist is not None else set(range(ninputs))
    input = [TRUE if v in xset or v == vsort(v) else FALSE for v in range(ninputs)]

    # output vectors
    o = exprvars('o', ninputs)
    output = [TRUE if v == vsort(v) else o[v] if halver_output(n, epsilon, v) else FALSE for v in range(ninputs)]

    d = kl - kf
    c = []

    if g.ndim == 2:
        # ehalvers (opt = 'e')
        m = n//2
        d = d*m
        kf = kf*m
        if d == 0:
            return [Equal(input[v], output[v]).to_cnf() for v in range(ninputs)]
        elif d == 1:
            for v in range(ninputs):
                c += forward_ehalver(g, n, kf, v, input, output)
        elif d > 1:
            s = exprvars('s', d - 1, ninputs)

            # first layer
            tk = s[0]
            for v in range(ninputs):
                c += forward_ehalver(g, n, kf, v, input, tk)

            # intermediate layers
            for k in range(1, d - 1):
                sk = s[k - 1]
                tk = s[k]
                for v in range(ninputs):
                    c += forward_ehalver(g, n, kf + k, v, sk, tk)

            # last layer
            sk = s[d - 2]
            for v in range(ninputs):
                c += forward_ehalver(g, n, kf + d - 1, v, sk, output)

    else:
        # halvers (opt = 'h')
        aux = exprvars('ly', d, n-2, ninputs) if n>2 else [None]
        if d == 1:
            c += forward_depth(g, n, kf, input, output, aux[0])
        else:
            s = exprvars('s', d - 1, ninputs)
            c += forward_depth(g, n, kf, input, s[0], aux[0])
            for k in range(1, d - 1):
                c += forward_depth(g, n, kf + k, s[k - 1], s[k], aux[k])
            c += forward_depth(g, n, kf + d - 1, s[d - 2], output, aux[d-1])

    return c
    def init_pins(self):
        self.IpOp_parse_done = 1
        Nos_keyIps = self.get_nokeys()

        return ([
            pyedaitr.exprvars('Ip',
                              len(self.inputs) - Nos_keyIps),
            pyedaitr.exprvars('Op', len(self.outputs)),
            pyedaitr.exprvars('KeyIp', Nos_keyIps)
        ])
Exemple #6
0
def sorts_x(g, n, kf, kl, x):
    y = vsort(x)
    if x == y:
        return []
    c = []
    first = 0
    last = n
    while x & (1 << first):
        first += 1
    while not (x & (1 << (last - 1))):
        last -= 1

    d = kl - kf
    xl = to_expr(x, n)
    yl = to_expr(y, n)
    if d == 0:
        pass
    elif d == 1:
        for i in range(first, last):
            c += update(g, first, last, kf, i, xl, yl[i])
    else:
        v = exprvars('v{}'.format(x), d - 1, (first, last))
        for i in range(first, last):
            c += update(g, first, last, kf, i, xl, v[0, i])
        for k in range(1, d - 1):
            for i in range(first, last):
                c += update(g, first, last, kf + k, i, v[k - 1], v[k, i])
        for i in range(first, last):
            c += update(g, first, last, kf + d - 1, i, v[d - 2], yl[i])
    return c
 def __init__(self, rows, columns, colors):
     self.rows = rows
     self.columns = columns
     self.colors = colors
     # Create 3d array of boolean variables per each color/cell
     self.vars = pd.exprvars('x', rows, columns, colors)
     self.f_list = []
Exemple #8
0
    def __init__(self, root_group, groups, clueset):
        self.items_per = len(root_group)
        self.root_group = root_group
        self.groups = groups
        self.clueset = clueset

        self.X = exprvars('x', (0, len(self.groups)), (0, self.items_per),
                          (0, self.items_per))
Exemple #9
0
def sorts_backward_size(g, n, kf, kl, xlist, s=0):
    ninputs = 1 << n
    c = []
    xset = set(xlist)

    # Input: TRUE for each input that is not sorted
    input = [TRUE if v != vsort(v) else FALSE for v in range(ninputs)]

    # Output variables
    o = exprvars('o', ninputs)
    if s == 0:
        # All sorted: 0 if already sorted by a prefix
        output = [0 if v in xset else o[v] for v in range(ninputs)]
    elif isinstance(s, (list, set)):
        # Exceptions: 1 to keep inputs in s unsorted
        output = [1 if v in s else 0 for v in range(ninputs)]
    else:
        # Fixed number of exceptions (unsorted inputs)
        output = o
        if s == 1:
            c_size = [Or(*output)]
            c_size += [
                ~output[i] | ~output[j] for i in range(ninputs)
                for j in range(i + 1, ninputs)
            ]
        elif s > 1:
            card, c_size = Card(output, s + 1)
            c_size += [~card[s]]
        c += c_size
    d = kl - kf
    # Backward layer iteration
    if d == 1:
        for v in range(ninputs):
            c += backward_size(g, n, kf, v, input, output)
    else:
        s = exprvars('s', d - 1, ninputs)
        for v in range(ninputs):
            c += backward_size(g, n, kl - 1, v, input, s[0])
        for k in range(1, d - 1):
            for v in range(ninputs):
                c += backward_size(g, n, kl - k - 1, v, s[k - 1], s[k])
        for v in range(ninputs):
            c += backward_size(g, n, kl - d, v, s[d - 2], output)
    return c
Exemple #10
0
def sorts_forward_depth(g, n, kf, kl, xlist, s=0):
    ninputs = 1 << n
    c = []
    xset = set(xlist)
    input = [
        TRUE if v in xset or v == vsort(v) else FALSE for v in range(ninputs)
    ]
    output = [TRUE if v == vsort(v) else FALSE for v in range(ninputs)]
    d = kl - kf
    aux = exprvars('ly', d, n - 2, ninputs) if n > 2 else [None]
    if d == 1:
        c += forward_depth(g, n, kf, input, output, aux[0])
    else:
        s = exprvars('s', d - 1, ninputs)
        c += forward_depth(g, n, kf, input, s[0], aux[0])
        for k in range(1, d - 1):
            c += forward_depth(g, n, kf + k, s[k - 1], s[k], aux[k])
        c += forward_depth(g, n, kf + d - 1, s[d - 2], output, aux[d - 1])
    return c
Exemple #11
0
def HMerge(a, b, prefix=''):
    n = len(a)
    if n == 1:
        if prefix == '':
            prefix = 'c'
        c = exprvars(prefix, 2)
        s = [Or(~a[0], ~b[0], c[1]), ~a[0] | c[0], ~b[0] | c[0]]
        return (c, s)
    else:
        c = exprvars(prefix + 'c', (1, 2 * n - 1))
        d, sd = HMerge(even(a), even(b), prefix + 'd')
        e, se = HMerge(odd(a), odd(b), prefix + 'e')
        v = [d[0]] + [x for x in c] + [e[-1]]
        sp = []
        for i in range(n - 1):
            sp.append(Or(*(~d[i + 1], ~e[i], c[2 * i + 2])))
            sp.append(~d[i + 1] | c[2 * i + 1])
            sp.append(~e[i] | c[2 * i + 1])
        s = sd + se + sp
        return (v, s)
Exemple #12
0
def SMerge(a, b, prefix=''):
    n = len(a)
    if n == 1:
        if prefix == '':
            prefix = 'c'
        c = exprvars(prefix, 2)
        s = [Or(~a[0], ~b[0], c[1]), ~a[0] | c[0], ~b[0] | c[0]]
        return (c, s)
    else:
        c = exprvars(prefix + 'c', (1, n + 1))
        d, sd = SMerge(even(a), even(b), prefix + 'd')
        e, se = SMerge(odd(a), odd(b), prefix + 'e')
        v = [d[0]] + list(c)
        sp = []
        for i in range(n // 2):
            sp.append(Or(~d[i + 1], ~e[i], c[2 * i + 2]))
            sp.append(~d[i + 1] | c[2 * i + 1])
            sp.append(~e[i] | c[2 * i + 1])
        s = sd + se + sp
        return (v, s)
Exemple #13
0
 def test_Card(self):
     # p = 3
     c, s = Card(exprvars('a', 10), 4)
     self.assertEqual("[dd[0], c[1], c[2], c[3]]", str(c))
     # Large range
     for n in range(1, 12):
         for p in range(0, n):
             a = exprvars('a', n)
             c, s = Card(a, p + 1)
             s.append(~c[p])
             for i in range(n + 1):
                 for v in combinations(a, i):
                     g = s[:]
                     vv = list(v) + [~x for x in a if x not in v]
                     g = vv + g
                     constraint = And(*g)
                     point = constraint.satisfy_one()
                     if i > p:
                         self.assertTrue(point is None)
                     else:
                         self.assertFalse(point is None)
Exemple #14
0
def initializationVariables(prs, substr=""):
    dictOfVar = {}
    if (substr == ""):
        # Инициализируем входные переменные
        inputVar = prs.varNames("input")
        inV = bdd.exprvars("inV", len(inputVar) * 2)
        i = 0
        for varName in inputVar:
            if varName not in dictOfVar:
                dictOfVar[varName] = (inV[i], inV[i + 1])
                i += 2
        # Инициализируем выходные переменные
        outputVar = prs.varNames("output")
        outV = bdd.exprvars("outV", len(outputVar) * 2)
        i = 0
        for varName in outputVar:
            if varName not in dictOfVar:
                dictOfVar[varName] = (outV[i], outV[i + 1])
                i += 2
        # Инициализируем промежуточные переменные
        wireVar = prs.varNames("wire")
        wireV = bdd.exprvars("wire", len(wireVar) * 2)
        i = 0
        for varName in wireVar:
            if varName not in dictOfVar:
                dictOfVar[varName] = (wireV[i], wireV[i + 1])
                i += 2
    else:
        # Инициализируем входные переменные
        inputVar = prs.varNames(substr)
        inV = bdd.exprvars("inV", len(inputVar) * 2)
        i = 0
        for varName in inputVar:
            if varName not in dictOfVar:
                dictOfVar[varName] = (inV[i], inV[i + 1])
                i += 2
    return dictOfVar
Exemple #15
0
def sorts_backward_depth(g, n, kf, kl, xlist=None, s=0):
    ninputs = 1 << n
    if xlist is None:
        xlist = range(ninputs)
    xset = set(xlist)
    c = []
    # FALSE for each input that is not sorted
    input = [TRUE if v != vsort(v) else FALSE for v in range(ninputs)]
    # all sorted
    o = exprvars('o', ninputs)
    if s == 0:
        output = [FALSE if v in xset else o[v] for v in range(ninputs)]
    elif isinstance(s, (list, set)):
        output = [TRUE if v in s else FALSE for v in range(ninputs)]
    else:
        output = o
        if s == 1:
            c_size = [Or(*output)]
            c_size += [
                ~output[i] | ~output[j] for i in range(ninputs)
                for j in range(i + 1, ninputs)
            ]
        elif s > 1:
            card, c_size = Card(output, s + 1, prefix='o_')
            c_size += [~card[s]]
        c += c_size
    d = kl - kf
    aux = exprvars('ly', d, n - 2, ninputs) if n > 2 else [None]
    if d == 1:
        c += backward_depth(g, n, kf, input, output, aux[0])
    else:
        s = exprvars('s', d - 1, ninputs)
        c += backward_depth(g, n, kl - 1, input, s[0], aux[0])
        for k in range(1, d - 1):
            c += backward_depth(g, n, kl - k - 1, s[k - 1], s[k], aux[k])
        c += backward_depth(g, n, kl - d, s[d - 2], output, aux[d - 1])
    return c
Exemple #16
0
def connectivity(g, n, d):
    kini = exprzeros(n, n)
    kend = exprones(n, n)
    c = []
    for i in range(n):
        kini[i, i] = expr(1)
    if d == 1:
        for i in range(n):
            c += kupdate(g, n, 0, i, kini, kend)
    else:
        km = exprvars('km', d - 1, n, n)
        for i in range(n):
            c += kupdate(g, n, 0, i, kini, km[0])
        for k in range(1, d - 1):
            for i in range(n):
                c += kupdate(g, n, k, i, km[k - 1], km[k])
        for i in range(n):
            c += kupdate(g, n, d - 1, i, km[d - 2], kend)
    return c
Exemple #17
0
def perform_bin_expr_min(base_tokens: list, wildcard='*'):
    """ Perform binary expression minimization for a list of base tokens

    :param list base_tokens: list of base tokens that have same length.
        Each base token is a list of '0' or '1'.
    :param wildcard: the element to denote "do not care" character

    :returns: list of minimized tokens of '0', '1' or 'wildcard'
    """
    if not base_tokens:
        return []

    dim = len(base_tokens[0])
    X = exprvars('x', dim)
    f = expr(0)  # start of an OR
    for baseToken in base_tokens:
        prod = expr(1)  # start of an AND
        for i in range(dim):
            if baseToken[i] == 1:
                prod = prod & X[i]
            else:
                prod = prod & ~X[i]
        f = f | prod

    # minimize
    fm, = espresso_exprs(f.to_dnf())

    min_tokens = []
    for s in fm.cover:
        min_token = []
        for i in range(dim):
            if X[i] in s:
                min_token.append(1)
            elif ~X[i] in s:
                min_token.append(0)
            else:
                min_token.append(wildcard)

        min_tokens.append(min_token)

    return min_tokens
Exemple #18
0
    def _get_esop_ast(self, bitmap):
        v = exprvars('v', self._nbits)

        def binstr_to_vars(binstr):
            return [
                       (~v[x[1] - 1] if x[0] == '0' else v[x[1] - 1])
                       for x in zip(binstr, reversed(range(1, self._nbits + 1)))
                   ][::-1]

        if self._optimization == 'off':
            expression = Xor(*[
                And(*binstr_to_vars(term)) for term in
                [np.binary_repr(idx, self._nbits) for idx, v in enumerate(bitmap) if v == '1']])
        else:  # self._optimization == 'qm-dlx':
            ones = [i for i, v in enumerate(bitmap) if v == '1']
            if not ones:
                return ('const', 0,)
            dcs = [i for i, v in enumerate(bitmap) if v == '*' or v == '-' or v.lower() == 'x']
            pis = get_prime_implicants(ones=ones, dcs=dcs)
            cover = get_exact_covers(ones, pis)[-1]
            clauses = []
            for c in cover:
                if len(c) == 1:
                    term = np.binary_repr(c[0], self._nbits)
                    clause = And(*[
                        v for i, v in enumerate(binstr_to_vars(term))
                    ])
                elif len(c) > 1:
                    c_or = reduce(operator.or_, c)
                    c_and = reduce(operator.and_, c)
                    _ = np.binary_repr(c_and ^ c_or, self._nbits)[::-1]
                    clause = And(*[
                        v for i, v in enumerate(binstr_to_vars(np.binary_repr(c_and, self._nbits))) if _[i] == '0'
                    ])
                else:
                    raise AquaError('Unexpected cover term size {}.'.format(len(c)))
                if clause:
                    clauses.append(clause)
            expression = Xor(*clauses)
        return expression.to_ast()
Exemple #19
0
def sorts_forward_size(g, n, kf, kl, xlist):
    ninputs = 1 << n
    xset = set(xlist)
    input = [
        TRUE if v in xset or v == vsort(v) else FALSE for v in range(ninputs)
    ]
    output = [TRUE if v == vsort(v) else FALSE for v in range(ninputs)]

    d = kl - kf
    c = []
    if d == 1:
        for v in range(ninputs):
            c += forward_size(g, n, kf, v, input, output)
    else:
        s = exprvars('s', d - 1, ninputs)
        for v in range(ninputs):
            c += forward_size(g, n, kf, v, input, s[0])
        for k in range(1, d - 1):
            for v in range(ninputs):
                c += forward_size(g, n, kf + k, v, s[k - 1], s[k])
        for v in range(ninputs):
            c += forward_size(g, n, kf + d - 1, v, s[d - 2], output)
    return c
Exemple #20
0
    def _get_esop_ast(self, bitmap):
        v = exprvars('v', self._nbits)

        def binstr_to_vars(binstr):
            return [
                       (~v[x[1] - 1] if x[0] == '0' else v[x[1] - 1])
                       for x in zip(binstr, reversed(range(1, self._nbits + 1)))
                   ][::-1]

        if self._optimization == 'off':
            expression = Xor(*[
                And(*binstr_to_vars(term)) for term in
                [np.binary_repr(idx, self._nbits) for idx, v in enumerate(bitmap) if v == '1']])
        else:  # self._optimization == 'qm-dlx':
            ones = [i for i, v in enumerate(bitmap) if v == '1']
            if not ones:
                return ('const', 0,)
            dcs = [i for i, v in enumerate(bitmap) if v == '*' or v == '-' or v.lower() == 'x']
            pis = get_prime_implicants(ones=ones, dcs=dcs)
            cover = get_exact_covers(ones, pis)[-1]
            clauses = []
            for c in cover:
                if len(c) == 1:
                    term = np.binary_repr(c[0], self._nbits)
                    clause = And(*[
                        v for i, v in enumerate(binstr_to_vars(term))
                    ])
                elif len(c) > 1:
                    c_or = reduce(operator.or_, c)
                    c_and = reduce(operator.and_, c)
                    _ = np.binary_repr(c_and ^ c_or, self._nbits)[::-1]
                    clause = And(*[
                        v for i, v in enumerate(binstr_to_vars(np.binary_repr(c_and, self._nbits))) if _[i] == '0'
                    ])
                else:
                    raise AquaError('Unexpected cover term size {}.'.format(len(c)))
                if clause:
                    clauses.append(clause)
            expression = Xor(*clauses)

        raw_ast = expression.to_ast()
        idx_mapping = {
            u: v + 1 for u, v in zip(sorted(expression.usupport), [v.indices[0] for v in sorted(expression.support)])
        }

        if raw_ast[0] == 'and' or raw_ast[0] == 'or' or raw_ast[0] == 'xor':
            clauses = []
            for c in raw_ast[1:]:
                if c[0] == 'lit':
                    clauses.append(('lit', (idx_mapping[c[1]]) if c[1] > 0 else (-idx_mapping[-c[1]])))
                elif (c[0] == 'or' or c[0] == 'and') and (raw_ast[0] != c[0]):
                    clause = []
                    for l in c[1:]:
                        clause.append(('lit', (idx_mapping[l[1]]) if l[1] > 0 else (-idx_mapping[-l[1]])))
                    clauses.append((c[0], *clause))
                else:
                    raise AquaError('Unrecognized logic expression: {}'.format(raw_ast))
        elif raw_ast[0] == 'const' or raw_ast[0] == 'lit':
            return raw_ast
        else:
            raise AquaError('Unrecognized root expression type: {}.'.format(raw_ast[0]))
        ast = (raw_ast[0], *clauses)
        return ast
Exemple #21
0
 def test_SMerge(self):
     a = exprvars('a', 2)
     b = exprvars('b', 2)
     c, _ = SMerge(a, b, 3)
     self.assertEqual(str(c), "[d[0], c[1], c[2]]")
Exemple #22
0
def variables(n, d):
    return exprvars('g', d, n, n)
Exemple #23
0
    # function for change state trigger
    def change_state(self, values):
        if self.check_values(values) == True or self.rule == {}:
            if self.current_state != self.unlocked:
                self.unlock()
        else:
            if self.current_state != self.locked:
                self.lock()

    # function for working with a trigger
    def run_trigger(self, data, values):
        self.change_state(values)
        self.change_last_value(data)
        return self.result_Q

d_tr = DTrigger()
result = d_tr.run_trigger('aaaa', '0')      # write data without rules
print('result_without_rule=', result)       # search result
X = eda.exprvars('X', 2)                    # create a rule truthtable
rule_tt = eda.truthtable(X, '0100')
print('rule_table:\n', rule_tt)             # print a rule truthtable
rule_expr = eda.truthtable2expr(rule_tt)    # create a rule expression

d_tr.add_rule_from_expr(rule_expr)
result = d_tr.run_trigger('bbbb', '11')     # write data with rule and wrong values
print('result_with_rule_and_wrong_key=', result)    # data not write
result = d_tr.run_trigger('bbbb', '01')     # write data with rule and good values
print('result_with_rule_and_good_key=', result)     # data changed

Exemple #24
0
 def test_HSort(self):
     n = 4
     a = exprvars('a', n)
     c, _ = HSort(a)
     self.assertEqual(str(c), "[d[0], c[1], c[2], e[1]]")
Exemple #25
0
def search(n, d, s, u=0, epsilon=1/4, opt='d', solver='picosat', lprefix=None, wsize=0, task=None, nthreads=4):

    if wsize <= 0:
        wsize = n + wsize

    print("n:", n, "d:", d, "s:", s, "u:", u, "opt:", opt, "solver:", solver,
          "wsize:", wsize, "task:", task, "prefix:", lprefix, "nthreads:", nthreads, file=sys.stderr)

    if opt.startswith('h'):
        # Comparator variables
        g = variables(n, d)
        
        # Empty prefix
        c_prefix = []

        # valid constraints
        c_valid = valid_depth1(g, n, d)

        # size constraints
        if s:
            ncard = s
            gcard = [g[k, i, j] for i in range(n) for j in range(i+1, n) for k in range(d)]
            c, c_size = Card(gcard, ncard + 1, prefix='g_')
            if len(c) > ncard:
                c_size += [~c[ncard]]
        else:
            c_size = []

        c_sorts = halver(g, n, 0, d, epsilon)

    elif opt.startswith('e'):
        m = n//2
        g = exprvars('g', d*m, m)
        c_valid = valid_ehalver(g, n, d)
        c_prefix = [g[i, m+i] for i in range(m)]
        d0 = 1
        c_size = []
        net = Network(to_ehalver(c_prefix, g, n, d0))
        xlist = net.outputs(n, range(1<<n))
        c_sorts = halver(g, n, d0, d, epsilon, xlist)

    elif opt.startswith('s1'):
        d = s
        g = variables(n, d)
        c_prefix = []
        c_valid = valid_size1(g, n, d)
        c_size = []
        c_sorts = sorts_backward_size(g, n, 0, d, [], u)

    elif opt.startswith('s'):
        d = s
        g = variables(n, d)

        if lprefix is None:
            lprefix  = [[(0, 1)]]
            c_prefix = [g[k, i, j] if (i, j) in layer else ~g[k, i, j] for k, layer in enumerate(lprefix) for i in range(n-1) for j in range(i+1, n)]
            if n > 3:
                c_prefix.append(Or(g[1, 0, 2], g[1, 2, 3]))
        else:
            c_prefix = [g[k, i, j] if (i, j) in layer else ~g[k, i, j] for k, layer in enumerate(lprefix) for i in range(n-1) for j in range(i+1, n)]
        net = Network(lprefix)
        d0 = len(net)

        c_valid = valid_size(g, n, d0, d)

        c_size = []

        inputs = net.not_sorted(n)
        inputs = [x for x in inputs if window_size(x, n) > 2 and window_size(x, n) <= wsize]
        xlist = net.outputs(n, inputs)

        print("d0:", d0, "len(xlist):", len(xlist), file=sys.stderr)
        c_sorts = sorts(g, n, d0, d, xlist)

    elif opt.startswith('d1'):
        g = variables(n, d)

        c_valid = valid_depth1(g, n, d)

        c_prefix = []

        if s:
            c, c_size = Card([g[k, i, j] for i in range(0, n) for j in range(i+1, n) for k in range(d)], s+1, prefix='g_')
            c_size += [~c[s]]
        else:
            c_size = []

        c_sorts = sorts_backward_depth(g, n, 0, d, None, u)

    else:
        # Comparator variables
        g = variables(n, d)

        # Prefix constraints
        if lprefix is None:
            lprefix  = [[(i, n-i-1) for i in range(n//2)]]
        sprefix = sum(len(layer) for layer in lprefix)
        c_prefix = [g[k, i, j] if (i, j) in layer else ~g[k, i, j] for k, layer in enumerate(lprefix) for i in range(n-1) for j in range(i+1, n)]
        net = Network(lprefix)
        d0 = len(net)

        # valid constraints
        c_valid = valid_depth(g, n, d0, d, s)

        # size constraints
        if s:
            ncard = s - sprefix
            gcard = [g[k, i, j] for i in range(n) for j in range(i+1, n) for k in range(d0, d)]
            c, c_size = Card(gcard, ncard + 1, prefix='g_')
            if len(c) > ncard:
                c_size += [~c[ncard]]
        else:
            c_size = []

        inputs = net.not_sorted(n)
        inputs = [x for x in inputs if window_size(x, n) > 2 and window_size(x, n) <= wsize]
        xlist = net.outputs(n, inputs)
        print("d0:", d0, "len(xlist):", len(xlist), file=sys.stderr)
        c_sorts = sorts(g, n, d0, d, xlist)

    print("c_valid:  ", len(c_valid), elapsed_time(), file=sys.stderr)
    print("c_prefix: ", len(c_prefix), elapsed_time(), file=sys.stderr)
    print("c_size:   ", len(c_size),  elapsed_time(), file=sys.stderr)
    print("c_sorts:  ", len(c_sorts), elapsed_time(), file=sys.stderr)
    clauses = c_valid + c_prefix + c_sorts + c_size
    constraint = And(*clauses)
    print("Is cnf?", constraint.is_cnf(), "Size: ", len(clauses), elapsed_time(), file=sys.stderr)

    while True:
        if solver == "picosat":
            point = constraint.satisfy_one()
            res = point is not None
        else:
            litmap, cnf = expr2dimacscnf(constraint)
            task = task if task is not None else int(time.monotonic())
            dimacscnf = "dimacscnf_{}.txt".format(task)
            litmapcnf = "litmap_{}.txt".format(task)
            with open(dimacscnf, "wt") as fp:
                print(cnf, file=fp)
            with open(litmapcnf, "wt") as fp:
                print(litmap, file=fp)
            ofile = "output_{}_{}_{}_{}.txt".format(n, d, s, task)
            with open(ofile+".log", "wt") as out:
                if solver == "minisat":
                    subprocess.call(["minisat", dimacscnf, ofile], stdout=out)
                elif solver == "glucose":
                    subprocess.call(["../../glucose-syrup-4.1/simp/glucose_release", "-model", dimacscnf], stdout=out)
                elif solver == "glucose-syrup":
                    subprocess.call(["../../glucose-syrup-4.1/parallel/glucose-syrup_release", "-nthreads={}".format(nthreads), "-model", dimacscnf, ofile], stdout=out)
                else:
                    subprocess.call(["../../cryptominisat-5.0.1/cryptominisat5", "-t", str(nthreads), dimacscnf], stdout=out)
            if solver == "minisat":
                res, soln = dimacs.read(ofile, minisat=True)
            else:
                res, soln = dimacs.read(ofile+".log")
            point = ConjNormalForm.soln2point(soln, litmap)

        print("len(point): ", len(point) if point else None, elapsed_time(), file=sys.stderr)

        if res is None:
            return 'UNDETERMINED'
        elif not res:
            return 'UNSATISFIABLE'
        else:
            if opt.startswith('h'):
                net = Halver(to_network(point, g, n, d))
                return net
            elif opt.startswith('e'):
                net = Halver(to_ehalver(point, g, n, d))
                return net
            else:
                net = to_network(point, g, n, d)
                xnew = net.not_sorted(n, log=False)
            
                if len(xnew) == u or opt not in ['d', 's']:
                    return net
                else:
                    m = 16
                    print("Unsorted:", len(xnew), file=sys.stderr)
                    new_clauses = sorts(g, n, d0, d, xnew[:m])
                    clauses += new_clauses
                    constraint = And(*clauses)
Exemple #26
0
 def test_HMerge(self):
     a = exprvars('a', 2)
     b = exprvars('b', 2)
     c, _ = HMerge(a, b)
     self.assertEqual(str(c), "[d[0], c[1], c[2], e[1]]")