示例#1
0
    def __init__(self, dimacs_cnf, mct_mode='basic'):
        self.validate(locals())
        super().__init__()
        self._mct_mode = mct_mode

        ls = [
            l.strip() for l in dimacs_cnf.split('\n')
            if len(l) > 0 and not l.strip()[0] == 'c'
        ]
        headers = [l for l in ls if l[0] == 'p']
        if len(headers) == 1:
            p, sig, nv, nc = headers[0].split()
            assert p == 'p' and sig == 'cnf'
        else:
            raise ValueError('Invalid cnf format for SAT.')
        h_nv, h_nc = int(nv), int(nc)
        cs = [
            c.strip()
            for c in ' '.join([l for l in ls if not l[0] == 'p']).split(' 0')
            if len(c) > 0
        ]
        cnf_expr = [[int(v) for v in c.split() if not int(v) == 0] for c in cs
                    if (len(c.replace('0', '')) > 0) and (
                        '0' <= c[0] <= '9' or c[0] == '-')]
        self._cnf = CNF(cnf_expr)

        if not h_nv == self._cnf.num_variables:
            logger.warning(
                'Inaccurate variable count {} in cnf header, actual count is {}.'
                .format(h_nv, nv))
        if not h_nc == self._cnf.num_clauses:
            logger.warning(
                'Inaccurate clause count {} in cnf header, actual count is {}.'
                .format(h_nc, nc))
示例#2
0
    def _process_expr(self):
        self._num_vars = self._expr.degree
        ast = self._expr.to_cnf().to_ast()
        ast = LogicExpressionOracle._normalize_literal_indices(
            ast, self._expr.usupport)

        if self._optimization == 'off':
            self._nf = CNF(ast, num_vars=self._num_vars)
        else:  # self._optimization == 'espresso':
            expr_dnf = self._expr.to_dnf()
            if expr_dnf.is_zero() or expr_dnf.is_one():
                self._nf = CNF(('const', 0 if expr_dnf.is_zero() else 1),
                               num_vars=self._num_vars)
            else:
                expr_dnf_m = espresso_exprs(expr_dnf)[0]
                expr_dnf_m_ast = LogicExpressionOracle._normalize_literal_indices(
                    expr_dnf_m.to_ast(), expr_dnf_m.usupport)
                if isinstance(expr_dnf_m, AndOp):
                    self._nf = CNF(expr_dnf_m_ast, num_vars=self._num_vars)
                elif isinstance(expr_dnf_m, OrOp):
                    self._nf = DNF(expr_dnf_m_ast, num_vars=self._num_vars)
                else:
                    raise AquaError(
                        'Unexpected espresso optimization result expr: {}'.
                        format(expr_dnf_m))
示例#3
0
class SAT(Oracle):

    CONFIGURATION = {
        'name': 'SAT',
        'description': 'Satisfiability Oracle',
        'input_schema': {
            '$schema': 'http://json-schema.org/schema#',
            'id': 'sat_oracle_schema',
            'type': 'object',
            'properties': {
                'dimacs_cnf': {
                    'type': 'string',
                },
                'mct_mode': {
                    'type': 'string',
                    'default': 'basic',
                    'oneOf': [{
                        'enum': ['basic', 'advanced']
                    }]
                },
            },
            'additionalProperties': False
        }
    }

    def __init__(self, dimacs_cnf, mct_mode='basic'):
        self.validate(locals())
        super().__init__()
        self._mct_mode = mct_mode

        ls = [
            l.strip() for l in dimacs_cnf.split('\n')
            if len(l) > 0 and not l.strip()[0] == 'c'
        ]
        headers = [l for l in ls if l[0] == 'p']
        if len(headers) == 1:
            p, sig, nv, nc = headers[0].split()
            assert p == 'p' and sig == 'cnf'
        else:
            raise ValueError('Invalid cnf format for SAT.')
        h_nv, h_nc = int(nv), int(nc)
        cs = [
            c.strip()
            for c in ' '.join([l for l in ls if not l[0] == 'p']).split(' 0')
            if len(c) > 0
        ]
        cnf_expr = [[int(v) for v in c.split() if not int(v) == 0] for c in cs
                    if (len(c.replace('0', '')) > 0) and (
                        '0' <= c[0] <= '9' or c[0] == '-')]
        self._cnf = CNF(cnf_expr)

        if not h_nv == self._cnf.num_variables:
            logger.warning(
                'Inaccurate variable count {} in cnf header, actual count is {}.'
                .format(h_nv, nv))
        if not h_nc == self._cnf.num_clauses:
            logger.warning(
                'Inaccurate clause count {} in cnf header, actual count is {}.'
                .format(h_nc, nc))

    @property
    def variable_register(self):
        return self._cnf.qr_variable

    @property
    def ancillary_register(self):
        return self._cnf.qr_ancilla

    @property
    def outcome_register(self):
        return self._cnf.qr_outcome

    def construct_circuit(self):
        return self._cnf.construct_circuit(mct_mode=self._mct_mode)

    def evaluate_classically(self, assignment):
        assignment_set = set(assignment)
        for clause in self._cnf.expr:
            if assignment_set.isdisjoint(clause):
                return False
        return True

    def interpret_measurement(self, top_measurement=None):
        return [(var + 1) * (int(tf) * 2 - 1) for tf, var in zip(
            top_measurement[::-1], range(len(top_measurement)))]