Example #1
0
    def zero_blocks(self, f):
        """divides the zero set of f into blocks
        >>> from polybori import *
        >>> r = declare_ring(["x", "y", "z"], dict())
        >>> e = CNFEncoder(r)
        >>> e.zero_blocks(r.variable(0)*r.variable(1)*r.variable(2))
        [{y: 0}, {z: 0}, {x: 0}]
        """
        f = Polynomial(f)
        variables = f.vars_as_monomial()

        space = variables.divisors()
        variables = list(variables.variables())
        zeros = f.zeros_in(space)
        rest = zeros
        res = list()

        def choose_old(s):
            return iter(rest).next()  # somewhat

            #inefficient compared to polynomials lex_lead
        def choose(s):
            indices = []
            assert not s.empty()
            nav = s.navigation()
            while not nav.constant():
                e = nav.else_branch()
                t = nav.then_branch()
                if e.constant() and not e.terminal_one():
                    indices.append(nav.value())
                    nav = t
                else:
                    if self.random_generator.randint(0, 1):
                        indices.append(nav.value())
                        nav = t

                    else:
                        nav = e
            assert nav.terminal_one()
            res = self.one_set
            for i in reversed(indices):
                res = ite(i, res, self.empty_set)
            return iter(res).next()
        while not rest.empty():
            l = choose(rest)
            l_variables = set(l.variables())

            def get_val(var):
                if var in l_variables:
                    return 1
                return 0
            block_dict = dict([(v, get_val(v)) for v in variables])

            l = l.set()
            self.random_generator.shuffle(variables)
            for v in variables:
                candidate = l.change(v.index())
                if candidate.diff(zeros).empty():
                    l = l.union(candidate)
                    del block_dict[v]
            rest = rest.diff(l)
            res.append(block_dict)
        return res
Example #2
0
    def zero_blocks(self, f):
        """divides the zero set of f into blocks
        >>> from polybori import *
        >>> r = declare_ring(["x", "y", "z"], dict())
        >>> e = CNFEncoder(r)
        >>> e.zero_blocks(r.variable(0)*r.variable(1)*r.variable(2))
        [{y: 0}, {z: 0}, {x: 0}]
        """
        f=Polynomial(f)
        variables = f.vars_as_monomial()
    
        space = variables.divisors()
        variables = list(variables.variables())
        zeros = f.zeros_in(space)
        rest = zeros
        res = list()
        
        def choose_old(s):
            return iter(rest).next()# somewhat 
            #inefficient compared to polynomials lex_lead
        def choose(s):
            indices = []
            assert not s.empty()
            nav = s.navigation()
            while not nav.constant():
                e = nav.else_branch()
                t = nav.then_branch()
                if e.constant() and not e.terminal_one():
                    indices.append(nav.value())
                    nav = t
                else:
                    if self.random_generator.randint(0,1):
                        indices.append(nav.value())
                        nav = t
                    
                    else:
                        nav = e
            assert nav.terminal_one()
            res = self.one_set
            for i in reversed(indices):
                res = ite(i, res, self.empty_set)
            return iter(res).next()
        while not rest.empty():
            l = choose(rest)
            l_variables = set(l.variables())
            def get_val(var):
                if var in l_variables:
                    return 1
                return 0
            block_dict = dict([(v, get_val(v)) for v in variables])

            l = l.set()
            self.random_generator.shuffle(variables)
            for v in variables:
                candidate = l.change(v.index())
                if candidate.diff(zeros).empty():
                    l = l.union(candidate)
                    del block_dict[v]
            rest = rest.diff(l)
            res.append(block_dict)
        return res