Beispiel #1
0
    def encode(self, edges, constraints):
        # let var_of([i, j]) represent transaction i before j
        # var represents ordering relation
        var_of = make_var_of_edge(self.ordering)
        n = self.total_nodes

        s = self.solver

        for edge in edges:
            s.add(var_of(edge)) # known WR edges must be ordered

        for constraint in constraints:
            # Notice how constraints line up to axioms
            t1 = constraint[1][1]
            t2 = constraint[0][1]
            t3 = constraint[0][0]

            s.add(Implies(var_of([t2, t3]), var_of([t2, t1]))) # Axiom for Serializability

        # Strict total ordering: 1) transitive, 2. trichotomous (asymmetric and semi-connex)
        # asymmetric = irreflexive and antisymmetric
        for begin in range(n):
            s.add(Not(var_of([begin, begin]))) # irreflexive
            for end in range(n):
                if begin != end:
                    s.add(Xor(var_of([begin, end]), var_of([end, begin]))) # asymmetric and semi-connex
                for middle in range(n):
                    if begin != middle and end != middle:
                        begin_middle_end = And(var_of([begin, middle]), var_of([middle, end]))
                        s.add(Implies(begin_middle_end, var_of([begin, end]))) # transitive

            self.print_progress(begin, n)
        print()
Beispiel #2
0
    def make_dimacs_cnf(self, edges, constraints):
        # writes it to temp file
        var_of = make_var_of_edge(self.adjacency)
        str_var_of = lambda edge: str(var_of(
            edge))  # encode_polygraph for dimacs expects strings
        ordering_of = lambda node: self.ordering[node]
        n = self.total_nodes

        self.cnf = self.encode_polygraph(str_var_of, edges, constraints)

        formula = TRUE
        for begin in range(n):
            for end in range(n):
                # could precompute the formula and fill in the vars
                implies_ordering = Implies(
                    var_of([begin, end]),
                    lex(ordering_of(begin), ordering_of(end)))
                formula = And(implies_ordering, formula)
            self.print_progress(begin, n)
        print()

        ordering_cnf = simplify_cnf(to_tseitin_cnf_iterative(formula))
        self.cnf.and_cnf(ordering_cnf)

        dimacs = to_dimacs(simplify_cnf(self.cnf))
        return dimacs
Beispiel #3
0
    def _encode_and_write(self, edges, constraints, filename):
        # writes it to temp file
        var_of = make_var_of_edge(self.adjacency)
        n = self.total_nodes
        cnf = self.encode_polygraph(var_of, edges, constraints)

        for i in range(n):
            for j in range(n):

                lessunr_cnf = self._lessunr_circuit(i, j, n, self.adjacency,
                                                    self.ordering, self.aux_U)
                cnf.and_cnf(lessunr_cnf)

                # 2. unary circuit
                if j >= 1:
                    cnf.add_clause(
                        Clause([
                            literal(self.ordering[i][j - 1], False),
                            literal(self.ordering[i][j])
                        ]))

            self.print_progress(i, n)
        print()

        self.cnf = cnf

        folder = Path(filename).parent
        folder.mkdir(parents=True, exist_ok=True)
        print('writing to file: ' + self.filename)

        dimacs = to_dimacs(self.cnf)
        with open(self.filename, 'w') as f:
            f.write(dimacs)

        print('done writing encoding.')
Beispiel #4
0
    def encode(self, edges, constraints):
        var_of = make_var_of_edge(self.adjacency)
        n = self.total_nodes

        self.encode_polygraph(var_of, edges, constraints)
        s = self.solver

        for begin in range(n):
            s.add(Not(var_of([begin, begin])))
            for end in range(n):
                for mid in range(n):
                    connecting = And(var_of([begin, mid]), var_of([mid, end]))
                    s.add(Implies(connecting, var_of([begin, end])))
            self.print_progress(begin, n)
        print()
Beispiel #5
0
    def encode(self, edges, constraints):
        var_of = make_var_of_edge(self.adjacency)
        n = self.total_nodes

        self.encode_polygraph(var_of, edges, constraints)
        s = self.solver

        R = Function('R', IntSort(), IntSort(), BoolSort()) # relation
        TC_R = TransitiveClosure(R)

        for begin in range(n):
            s.add(Not(TC_R(begin, begin)))
            for end in range(n):
                if begin != end:
                    s.add(Implies(var_of([begin, end]), R(begin, end)))
            self.print_progress(begin, n)
        print()
Beispiel #6
0
    def encode(self, edges, constraints):
        var_of = make_var_of_edge(self.adjacency)
        dist_of = lambda node: self.dists_to_leaf[node]

        n = self.total_nodes
        s = self.solver

        self.encode_polygraph(var_of, edges, constraints)

        for begin in range(n):
            is_leaf = True
            at_least_one = False

            s.add(Not(var_of([begin, begin])))
            # s.add(UGE(dist_of(begin), 0))
            # s.add(ULE(dist_of(begin), n - 1))

            for end in range(n):
                if begin != end:
                    # If there is an edge from begin to end, begin is not a leaf
                    is_leaf = And(Not(var_of([begin, end])), is_leaf)

                    # children of <begin> are closer to leaf nodes
                    s.add(
                        var_of([begin, end]) == UGT(dist_of(begin), dist_of(
                            end)))

                    # at least one child has distance dist_of(begin) - 1
                    equals = dist_of(end) == (dist_of(begin) - 1)
                    at_least_one = Or(at_least_one,
                                      And(var_of([begin, end]), equals))

            s.add(is_leaf == (dist_of(begin) == 0))
            s.add(Or(is_leaf, at_least_one))

            self.print_progress(begin, n)
        print()