def sparse_random_system(ring, number_of_polynomials, variables_per_polynomial, degree, random_seed=None):
    """
    generates a system, which is sparse in the sense, that each polynomial
    contains only a small subset of variables. In each variable that occurrs in a polynomial it is dense in the terms up to the given degree (every term occurs with probability 1/2).
    The system will be satisfiable by at least one solution.
    >>> from polybori import *
    >>> r=Ring(10)
    >>> s=sparse_random_system(r, number_of_polynomials = 20, variables_per_polynomial = 3, degree=2, random_seed=123)
    >>> [p.deg() for p in s]
    [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
    >>> sorted(groebner_basis(s), reverse=True)
    [x(0), x(1), x(2), x(3), x(4) + 1, x(5), x(6) + 1, x(7), x(8) + 1, x(9)]
    """
    if random_seed is not None:
        set_random_seed(random_seed)
    random_generator = Random(random_seed)
    solutions=[]
    variables = [ring.variable(i) for i in xrange(ring.n_variables())]
    for v in variables:
        solutions.append(v+random_generator.randint(0,1))
    solutions=ll_encode(solutions)
    res = []
    while len(res)<number_of_polynomials:
        variables_as_monomial=Monomial(
            random_generator.sample(
                variables, 
                variables_per_polynomial)
        )
        p=Polynomial(random_set(variables_as_monomial, 2**(variables_per_polynomial-1)))
        p=sum([p.graded_part(i) for i in xrange(degree+1)])
        if p.deg()==degree:
            res.append(p)
    res=[p+ll_red_nf_redsb(p, solutions) for p in res]# evaluate it to guarantee a solution
    return res
 def add_simple_poly(p,i):
     p=Polynomial(p)
     if p.is_zero():
         return
     res_p=Polynomial(res.get(i, Polynomial(0, p.ring())))
     res[i]=res_p+p
     if res[i].is_zero():
         del res[i]
     inter=BooleSet(res_p).intersect(BooleSet(p))
     add_simple_poly(inter, i+1)
     return
Example #3
0
def proofll(ifthen, reductors, redsb=True, prot=True):

    if prot and (not ifthen.supposedToBeValid):
        print "THIS THEOREM IS NOT SUPPOSED TO BE VALID"
    ip_pre = ifthen.ifpart
    ip = []

    for p in ip_pre:
        p = Polynomial(p)
        if p.is_zero():
            continue
        li = list(p.lead().variables())
        if len(li) == 1 and (not (li[0] in list(Polynomial(reductors).lead().
            variables()))):
            assert not Polynomial(reductors).is_zero()
            lead_index = li[0]
            if redsb:
                p = ll_red_nf_redsb(p, reductors)
                reductors = ll_red_nf_redsb(Polynomial(reductors), BooleSet(p.
                    set()))

            p_nav = p.navigation()
            reductors = recursively_insert(p_nav.else_branch(), p_nav.value(),
                reductors)
        else:
            ip.append(p)
    it = ifthen.thenpart
    if prot:
        print "proofing:", ifthen
    ip = logicaland(ip)
    for c in it:
        if prot:
            print "proofing part:", c
        c = logicalor([BooleConstant(1) + ip, c])

        if c.is_zero():
            if prot:
                print "TRUE (trivial)"
            return True
        else:
            c_orig = c
            if redsb:
                c = ll_red_nf_redsb(c, reductors)
            else:
                c = ll_red_nf_noredsb(c, reductors)
            if c.is_zero():
                if prot:
                    print "TRUE"
                return True
            else:
                if prot:
                    print "FAILED"
                    print "can construct COUNTER EXAMPLE with:", find_one(c)
                return False
def all_monomials_of_degree_d_old(d,variables):
    
    if d==0:
        return BooleConstant(1)
    
    if not variables:
        return []
    variables=sorted(set(variables),reverse=True,key=top_index)

    m=variables[-1]
    for v in variables[:-1]:
        m=v+m
    m=m.set()
    i=0
    res=Polynomial(variables[0].ring().one()).set()
    while(i<d):
        i=i+1
        res=res.cartesian_product(m).diff(res)
    return res
def gen_random_poly(ring, l,deg,vars_set,seed=123):

    myrange=vars_set
    r=Random(seed)
    def helper(samples):
        if samples==0:
            return Polynomial(ring.zero())
        if samples==1:
            d=r.randint(0,deg)
            variables=r.sample(myrange,d)
            m=Monomial(ring)
            for v in sorted(set(variables),reverse=True):
                m=m*Variable(v, ring)
            return Polynomial(m)
        assert samples>=2
        return helper(samples/2)+helper(samples-samples/2)
    p=Polynomial(ring.zero())
    while(len(p)<l):
        p=Polynomial(p.set().union(helper(l-len(p)).set()))
    return p
Example #6
0
def plot(p, filename, colored=True, format="png",
    highlight_monomial=None, fontsize=14,
    template_engine='jinja', landscape=False
    ):
    """plots ZDD structure to <filename> in format <format>

    EXAMPLES:

    >>> r=Ring(1000)
    >>> x = r.variable
    >>> plot(x(1)+x(0),"/dev/null", colored=True)
    >>> plot(x(1)+x(0),"/dev/null", colored=False)
    """
    THICK_PEN = 5
    highlight_path = dict()
    if highlight_monomial:
        highlight_path = monomial_path_in_zdd(highlight_monomial, p)

    def display_monomial(m):
        return unicode(m).replace("*", u"⋅")

    def penwidth_else(n):
        if n in highlight_path and highlight_path[n] == ELSE:
            return THICK_PEN
        return 1

    def penwidth_then(n):
        if n in highlight_path and highlight_path[n] == THEN:
            return THICK_PEN
        return 1
    if not colored:
        color_then = "black"
        color_else = "black"
    else:
        color_then = "red"
        color_else = "blue"

    def find_navs(nav):
        if not nav in nodes:
            nodes.add(nav)
            if not nav.constant():
                find_navs(nav.then_branch())
                find_navs(nav.else_branch())
    p = Polynomial(p)
    nodes = set()
    nav = p.navigation()
    find_navs(nav)
    non_constant_nodes = [n for n in nodes if not n.constant()]
    node_to_int = dict([(n, i) for (i, n) in enumerate(nodes)])

    r = p.ring()

    def identifier(n):
        return "n" + str(node_to_int[n])

    def label(n):
        if n.constant():
            if n.terminal_one():
                return "1"
            else:
                return "0"
        else:
            return str(r.variable(n.value()))

    def shape(n):
        if n.constant():
            return "box"
        else:
            return "ellipse"
    renderers = dict(genshi=render_genshi, jinja=render_jinja)

    dot_input = renderers[template_engine](locals())
    if isinstance(dot_input, unicode):
        dot_input = dot_input.encode('utf-8')
    process = Popen(["dot", "-T" + format, "-o", filename], stdin=PIPE,
        stdout=PIPE)

    process.stdin.write(dot_input)
    process.stdin.close()
    process.wait()
Example #7
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