Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
def add_bits_old(bits):
    """Adds n bits
    >>> from polybori import *
    >>> r=Ring(10)
    >>> add_bits_old([r.variable(i) for i in xrange(3)])
    [x(0) + x(1) + x(2), x(0)*x(1) + x(0)*x(2) + x(1)*x(2)]
    >>> add_bits_old([r.variable(i) for i in xrange(4)])
    [x(0) + x(1) + x(2) + x(3), x(0)*x(1) + x(0)*x(2) + x(0)*x(3) + x(1)*x(2) + x(1)*x(3) + x(2)*x(3)]
    """
    bits = list(bits)
    n = len(bits)
    deg_d_monomials = [
        Polynomial(all_monomials_of_degree_d(i, bits)) for i in xrange(n + 1)
    ]
    full = power_set(bits)
    bits_expr = []  # [sum(bits)]
    step = 0
    while n > 2**step:
        to_one = sum(
            [deg_d_monomials[i] for i in xrange(n + 1) if i & 2**step])
        to_one = Polynomial(to_one)
        fun = PartialFunction(ones=to_one, zeros=full.diff(to_one))
        poly = fun.interpolate_smallest_lex()
        bits_expr.append(poly)
        step = step + 1
    return bits_expr
Ejemplo n.º 3
0
def all_monomials_of_degree_d(d, variables):
    variables = Monomial(variables)
    variables = list(variables.variables())
    if not variables:
        assert d == 0
        return BooleConstant(1)
    ring = variables[0].ring()
    if d > len(variables):
        return Polynomial(0, ring)
    if d < 0:
        return Polynomial(1, ring)

    deg_variables = variables[-d:]
    #this ensures sorting by indices
    res = Monomial(deg_variables)

    for i in xrange(1, len(variables) - d + 1):
        deg_variables = variables[-d - i:-i]
        res = Polynomial(res)
        nav = res.navigation()
        navs = []
        while not nav.constant():
            navs.append(BooleSet(nav, ring))
            nav = nav.then_branch()
        acc = Polynomial(1, ring)
        for (nav, v) in reversed(zip(navs, deg_variables)):
            acc = if_then_else(v, acc, nav)
        res = acc
    return res.set()
Ejemplo n.º 4
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
Ejemplo n.º 5
0
 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
Ejemplo n.º 6
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
Ejemplo n.º 7
0
def interred(l, completely=False):
    """computes a new generating system (g1, ...,gn),
    spanning the same ideal modulo field equations.
    The system is interreduced: For i!=j:
    gi.lead() does not divide any leading term of gj.
    If completely is set to True, then also terms in the
    tail are not reducible by other polynomials.
    """
    l = [Polynomial(p) for p in l if not p == 0]
    if not l:
        return []
    ring = l[0].ring()
    l_old = None
    l = tuple(l)
    while l_old != l:
        l_old = l
        l = sorted(l, key=Polynomial.lead)
        g = ReductionStrategy(ring)
        if completely:
            g.opt_red_tail = True
        for p in l:
            p = g.nf(p)
            if not p.is_zero():
                g.add_generator(p)
        l = tuple([e.p for e in g])
    return list(l)
Ejemplo n.º 8
0
def power_set(variables):
    if not variables:
        return BooleConstant(1)
    variables = sorted(set(variables), reverse=True, key=top_index)
    res = Polynomial(1, variables[0].ring()).set()
    for v in variables:
        res = if_then_else(v, res, res)
    return res
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
def gen_strat(polys):
    polys = [Polynomial(p) for p in polys]
    polys = [p for p in polys if not p.is_zero()]
    assert len(set([p.lead() for p in polys])) == len(polys)
    assert polys
    strat = GroebnerStrategy(polys[0].ring())
    for p in polys:
        print "Adding"
        strat.add_generator(p)
    print "finished"
    return strat
Ejemplo n.º 12
0
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
Ejemplo n.º 13
0
def vars_real_divisors(monomial, monomial_set):
    """
    returns all elements of of monomial_set, which result multiplied by a variable in monomial.
    >>> from polybori.PyPolyBoRi import OrderCode
    >>> dp_asc = OrderCode.dp_asc
    >>> from polybori.PyPolyBoRi import Ring
    >>> r=Ring(1000)
    >>> x = r.variable
    >>> b=BooleSet([x(1)*x(2),x(2)])
    >>> vars_real_divisors(x(1)*x(2)*x(3),b)
    {{x(1),x(2)}}
    """
    return BooleSet(Polynomial(monomial_set.divisors_of(monomial)). \
        graded_part(monomial.deg() - 1))
Ejemplo n.º 14
0
def dense_system(I):
    I = (Polynomial(p) for p in I)
    I = (p for p in I if not p.is_zero())
    for p in I:
        d = p.deg()
        if p.deg() == 1:
            continue
        else:
            try:
                if len(p) > 2**d + 5:
                    return True
            except OverflowError:
                return True
    return False
Ejemplo n.º 15
0
def main():
    r = Ring(1000)
    x = Variable = VariableFactory(r)
    from os import system
    from polybori.specialsets import all_monomials_of_degree_d, power_set
    full_set = list(power_set([Variable(i) for i in xrange(15)]))
    from random import Random
    generator = Random(123)
    random_set = sum(generator.sample(full_set, 30))
    full_polynomial = list(
        all_monomials_of_degree_d(3, [Variable(i) for i in xrange(30)]))
    random_poly = sum(generator.sample(full_polynomial, 30))
    polynomials = [
        x(1) * x(2) + x(3), (x(1) + 1) * (x(2) + x(3)),
        (x(1) + 1) * (x(2) + 1) * (x(3) + 1),
        x(1) * x(2) + x(2) * x(3) + x(1) * x(3) + x(1),
        x(0) + x(1) + x(2) + x(3) + x(4) + x(5),
        all_monomials_of_degree_d(3, [x(i) for i in xrange(10)]),
        power_set([x(i) for i in xrange(10)]), random_poly, random_set,
        Polynomial(all_monomials_of_degree_d(3, [x(i) for i in xrange(10)])) +
        Polynomial(power_set([x(i) for i in xrange(10)])),
        Polynomial(power_set([x(i) for i in xrange(10)])) + 1
    ]
    for colored in [True, False]:
        if colored:
            colored_suffix = "_colored"
        else:
            colored_suffix = ""
        for format in ["png", "svg"]:
            for (i, p) in enumerate(polynomials):

                #dot_file=str(i) +colored_suffix+".dot"
                #f=open(dot_file, "w")
                #f.write(dot)
                #f.close()
                out_file = str(i) + colored_suffix + "." + format
                plot(p, out_file, colored=colored, format=format)
Ejemplo n.º 16
0
 def __coerce__(self, other):
     #TODO handle long
     if isinstance(other, int) and other >= 0:
         i = 0
         res = []
         while 2**i <= other:
             and_ = 2**i & other
             if and_:
                 res.append(i)
         return (self,
                 IntegerPolynomial(
                     dict([(i, BooleConstant(1)) for i in res])))
     if not isinstance(other, IntegerPolynomial):
         other = Polynomial(other)
     return (self, IntegerPolynomial(dict([(0, other)])))
Ejemplo n.º 17
0
def gauss_on_linear(I):
    I = (Polynomial(p) for p in I)
    linear = []
    non_linear = []
    for p in I:
        if p.is_zero():
            continue
        if p.deg() <= 1:
            linear.append(p)
        else:
            non_linear.append(p)
    if len(linear) == 0:
        return non_linear
    linear = list(gauss_on_polys(linear))
    return linear + non_linear
Ejemplo n.º 18
0
 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
Ejemplo n.º 19
0
    def register(self, start, context):
        super(AdderBlock, self).register(start, context)
        a = context[self.input1]
        b = context[self.input2]
        self.s = shift(context[self.sums], self.start_index)
        self.c = shift(context[self.carries], self.start_index)
        a = shift(a, self.start_index)
        b = shift(b, self.start_index)
        carries = [Polynomial(a(0).ring().zero())]
        for i in xrange(self.adder_bits):
            #print i, ":"
            c = 1 + (1 + a(i) * b(i)) * (1 + carries[-1] * a(i)) * (
                1 + carries[-1] * b(i))
            carries.append(c)

        self.add_results = [
            a(i) + b(i) + carries[i] for i in xrange(self.adder_bits)
        ]
        self.carries_polys = carries[1:]
Ejemplo n.º 20
0
def from_fast_pickable(l, r):
    """from_fast_pickable(l, ring) undoes the operation to_fast_pickable. The first argument is an object created by to_fast_pickable.
    For the specified format, see the documentation of to_fast_pickable.
    The second argument is ring, in which this polynomial should be created.
    INPUT:
        see OUTPUT of to_fast_pickable
    OUTPUT:
        a list of Boolean polynomials
    EXAMPLES:
        >>> from polybori.PyPolyBoRi import Ring
        >>> r=Ring(1000)
        >>> x = r.variable
        >>> from_fast_pickable([[1], []], r)
        [1]
        >>> from_fast_pickable([[0], []], r)
        [0]
        >>> from_fast_pickable([[2], [(0, 1, 0)]], r)
        [x(0)]
        >>> from_fast_pickable([[2], [(1, 1, 0)]], r)
        [x(1)]
        >>> from_fast_pickable([[2], [(0, 1, 1)]], r)
        [x(0) + 1]
        >>> from_fast_pickable([[2], [(0, 3, 0), (1, 1, 0)]], r)
        [x(0)*x(1)]
        >>> from_fast_pickable([[2], [(0, 3, 3), (1, 1, 0)]], r)
        [x(0)*x(1) + x(1)]
        >>> from_fast_pickable([[2], [(0, 3, 4), (1, 1, 0), (2, 1, 0)]], r)
        [x(0)*x(1) + x(2)]
        >>> from_fast_pickable([[2, 0, 1, 4], [(0, 3, 0), (1, 1, 0), (3, 1, 0)]], r)
        [x(0)*x(1), 0, 1, x(3)]
    """
    i2poly = {0: r.zero(), 1: r.one()}
    (indices, terms) = l

    for i in reversed(xrange(len(terms))):
        (v, t, e) = terms[i]
        t = i2poly[t]
        e = i2poly[e]
        terms[i] = if_then_else(v, t, e)
        i2poly[i + 2] = terms[i]
    return [Polynomial(i2poly[i]) for i in indices]
Ejemplo n.º 21
0
def add_bits(bits):
    """Adds n bit variables, by Lucas theorem
    >>> from polybori import *
    >>> r=Ring(10)
    >>> add_bits([r.variable(i) for i in xrange(3)])
    [x(0) + x(1) + x(2), x(0)*x(1) + x(0)*x(2) + x(1)*x(2)]
    >>> add_bits([r.variable(i) for i in xrange(4)])
    [x(0) + x(1) + x(2) + x(3), x(0)*x(1) + x(0)*x(2) + x(0)*x(3) + x(1)*x(2) + x(1)*x(3) + x(2)*x(3), x(0)*x(1)*x(2)*x(3)]
    >>> add_bits([r.variable(0)])
    [x(0)]
    """
    bits = list(bits)
    if len(bits) < 2:
        return bits
    n = len(bits)

    bits_expr = []  # [sum(bits)]
    step = 0
    while n >= 2**step:
        bits_expr.append(Polynomial(all_monomials_of_degree_d(2**step, bits)))
        step = step + 1
    return bits_expr
Ejemplo n.º 22
0
    print list(all_monomials_of_degree_d(3, [Variable(i) for i in range(4)]))
    print list(all_monomials_of_degree_d(4, [Variable(i) for i in range(4)]))
    print list(all_monomials_of_degree_d(0, []))
    print list(all_monomials_of_degree_d(1, []))
    print list(power_set([Variable(i) for i in range(2)]))
    print list(power_set([Variable(i) for i in range(4)]))
    print list(power_set([]))
    #every monomial in the first 8 var, which is at most linear in the first 5
    print list(
        mod_mon_set(
            power_set([Variable(i) for i in range(8)]),
            all_monomials_of_degree_d(2, [Variable(i) for i in range(5)])))

    #specialized normal form computation
    print Polynomial(
        mod_mon_set(
            (x(1) * x(2) + x(1) + 1).set(),
            all_monomials_of_degree_d(2, [Variable(i) for i in range(1000)])))
    print list(
        mod_mon_set(
            power_set([Variable(i) for i in range(50)]),
            all_monomials_of_degree_d(2, [Variable(i) for i in range(1000)])))


def monomial_from_indices(ring, indices):
    l = sorted(indices, reverse=True)
    res = Monomial(ring)
    for i in l:
        res = res * ring.variable(i)

    return res
Ejemplo n.º 23
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()
Ejemplo n.º 24
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
Ejemplo n.º 25
0
def preprocess(I, prot=True):
    def min_gb(I):
        strat = symmGB_F2_C(I,
                            opt_lazy=False,
                            opt_exchange=False,
                            prot=prot,
                            selection_size=10000,
                            opt_red_tail=True)
        return list(strat.minimalize_and_tail_reduce())

    I = [Polynomial(p) for p in I]
    lin = [p for p in I if p.deg() == 1]
    # lin_strat=symmGB_F2_C(lin, opt_lazy=False,opt_exchange=False,prot=prot,sele
    # ction_size=10000,opt_red_tail=True)
    lin = min_gb(lin)  # list(lin_strat.minimalize_and_tail_reduce())
    for m in sorted([p.lead() for p in lin]):
        print m
    lin_ll = ll_encode(lin)
    square = [p.lead() for p in I if p.deg() == 2 and len(p) == 1]
    assert (len(lin) + len(square) == len(I))
    res = list(lin)
    counter = OccCounter()

    def unique_index(s):
        for idx in s:
            if counter[idx] == 1:
                return idx
        never_come_here = False
        assert never_come_here

    for m in square:
        for idx in m:
            counter.increase(idx)
    systems = dict(((idx, []) for idx in counter.uniques()))
    for m in square:
        u_index = unique_index(m)
        systems[u_index].append(ll_red_nf(m / Variable(u_index), lin_ll))
    rewritings = dict()
    u_var = Variable(u)
    u_im = ll_red_nf(u_var, lin_ll)
    if not u_im.isConstant():
        if u_im != u_var:
            r = u_im.navigation().value()
        else:
            pass
    for u in counter.uniques():
        #print u
        u_var = Variable(u)
        u_im = ll_red_nf(u_var, lin_ll)
        if not u_im.isConstant():
            if u_im != u_var:
                r = u_im.navigation().value()
            else:
                pass
    for u in systems.keys():
        u_var = Variable(u)
        u_im = ll_red_nf(u_var, lin_ll)
        res.extend([u_im * p for p in min_gb(systems[u])])
    #print [u_im*p for p in min_gb(systems[u])]
    print "lin:", len(lin), "res:", len(res), "square:", len(square)
    res = [p for p in (Polynomial(p) for p in res) if not p.is_zero()]
    return res
Ejemplo n.º 26
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
Ejemplo n.º 27
0
 def __init__(self, boolean_polys):
     super(IntegerPolynomial, self).__init__()
     if not isinstance(boolean_polys, dict):
         boolean_polys = dict([(0, Polynomial(boolean_polys))])
     self.boolean_polys = boolean_polys
Ejemplo n.º 28
0
def pickle_bset(self):
    return (BooleSet, (Polynomial(self), ))
Ejemplo n.º 29
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()
Ejemplo n.º 30
0
 def __init__(self, ifpart, thenpart, supposed_to_be_valid=True):
     self.ifpart = [Polynomial(p) for p in ifpart]
     self.thenpart = [Polynomial(p) for p in thenpart]
     self.supposedToBeValid = supposed_to_be_valid