[SCM] polybori: Polynomials over Boolean Rings branch, master, updated. upstream/0.8.2-50-ge095127

Alexander Dreyer adreyer at gmx.de
Tue Jan 8 10:23:29 UTC 2013


The following commit has been merged in the master branch:
commit e0951277f91b96ebfb126b6ddcf35d82fe882ef6
Author: Alexander Dreyer <adreyer at gmx.de>
Date:   Tue Jan 8 11:12:50 2013 +0100

    Pep8ify python modules

diff --git a/debian/patches/0005-pep8ify-python-modules.patch b/debian/patches/0005-pep8ify-python-modules.patch
new file mode 100644
index 0000000..2bef1b0
--- /dev/null
+++ b/debian/patches/0005-pep8ify-python-modules.patch
@@ -0,0 +1,8524 @@
+From: Alexander Dreyer <adreyer at gmx.de>
+Date: Tue, 8 Jan 2013 11:11:49 +0100
+Subject: pep8ify python modules
+
+---
+ pyroot/polybori/PyPolyBoRi.py                 |  127 +--
+ pyroot/polybori/__init__.py                   |   19 +-
+ pyroot/polybori/addition.py                   |   82 +-
+ pyroot/polybori/blocks.py                     |  705 ++++++++-------
+ pyroot/polybori/check_claims.py               |  288 ++++---
+ pyroot/polybori/cluster.py                    |   68 +-
+ pyroot/polybori/cnf.py                        |   96 ++-
+ pyroot/polybori/coding.py                     |  127 +--
+ pyroot/polybori/context.py                    |   14 +-
+ pyroot/polybori/easy_polynomials.py           |   26 +-
+ pyroot/polybori/fglm.py                       |   25 +-
+ pyroot/polybori/frontend.py                   |   15 +-
+ pyroot/polybori/gbcore.py                     |  590 +++++++------
+ pyroot/polybori/gbrefs.py                     |  152 ++--
+ pyroot/polybori/general_boolean_polynomial.py | 1150 +++++++++++++------------
+ pyroot/polybori/heuristics.py                 |   28 +-
+ pyroot/polybori/interpolate.py                |  155 ++--
+ pyroot/polybori/interred.py                   |   27 +-
+ pyroot/polybori/intersect.py                  |   24 +-
+ pyroot/polybori/intpolys.py                   |   53 +-
+ pyroot/polybori/ll.py                         |  323 +++----
+ pyroot/polybori/memusage.py                   |   10 +-
+ pyroot/polybori/ncf.py                        |   38 +-
+ pyroot/polybori/nf.py                         |  723 ++++++++--------
+ pyroot/polybori/parallel.py                   |  100 ++-
+ pyroot/polybori/parsegat.py                   |  464 +++++-----
+ pyroot/polybori/partial.py                    |   57 +-
+ pyroot/polybori/plot.py                       |  164 ++--
+ pyroot/polybori/randompoly.py                 |   70 +-
+ pyroot/polybori/rank.py                       |   17 +-
+ pyroot/polybori/simplebb.py                   |   50 +-
+ pyroot/polybori/specialsets.py                |  116 +--
+ pyroot/polybori/statistics.py                 |   16 +-
+ 33 files changed, 3152 insertions(+), 2767 deletions(-)
+
+diff --git a/pyroot/polybori/PyPolyBoRi.py b/pyroot/polybori/PyPolyBoRi.py
+index 3aa24e1..dbc4c40 100644
+--- a/pyroot/polybori/PyPolyBoRi.py
++++ b/pyroot/polybori/PyPolyBoRi.py
+@@ -13,12 +13,12 @@ AUTHOR:
+             Examples:
+ 
+             >>> from polybori.frontend import *
+-            >>> r=declare_ring(["x0","x1","x2","y0","y1","y2"], globals())   
+-            >>> x0>x1                                       
++            >>> r=declare_ring(["x0","x1","x2","y0","y1","y2"], globals())
++            >>> x0>x1
+             True
+             >>> x0>x1*x2
+             True
+-            >>> y0>y1                                       
++            >>> y0>y1
+             True
+             >>> y0>y1*y2
+             True
+@@ -80,23 +80,26 @@ except:
+ if _sageify:
+     import weakref
+ 
++
+     class OrderCode:
+         pass
+ 
+     OrderCode.__dict__ = order_dict
+     OrderCode.__module__ = __name__
+ 
++
+     def Ring(n, order='lp', names=None, blocks=[]):
+ 
+         pbnames = names
+         if pbnames is None:
+-            pbnames = ['x(' + str(idx)+ ')' for idx in xrange(n)]
++            pbnames = ['x(' + str(idx) + ')' for idx in xrange(n)]
+         order = TermOrder_from_pb_order(n, order, blocks)
+-        R =  BooleanPolynomialRing(n, names=pbnames, order=order)
++        R = BooleanPolynomialRing(n, names=pbnames, order=order)
+         return R
+ 
+     BoolePolynomialVector = BooleanPolynomialVector
+ 
++
+     #todo: PolyBoRi's original interface uses its WeakRingPtr here
+     def WeakRingRef(ring):
+         return weakref.weakref(ring)
+@@ -106,33 +109,37 @@ if _sageify:
+     Variable = VariableFactory()
+ 
+ 
+-else: # import Polybori's original interface
++else:  # import Polybori's original interface
+     from sys import modules
+     from itertools import chain
+     import re
+     import warnings
+-    compatibility_mode=False
+-    # First try, whether PyPolyBoRi is already in modules (e.g. static profiling)
++    compatibility_mode = False
++    # First try, whether PyPolyBoRi is already in modules (e.g. static
++    # profiling)
+     try:
+         pb = modules["PyPolyBoRi"]
+         for k in dir(pb):
+-            globals()[k]=getattr(pb,k)   
++            globals()[k] = getattr(pb, k)
+     except:
+         from polybori.dynamic.PyPolyBoRi import *
+ 
++
+     def replace_init_proc(cls):
+-        old_init=cls.__init__
+-        def init(self,iteratable=None):
++        old_init = cls.__init__
++
++        def init(self, iteratable=None):
+             old_init(self)
+             if iteratable:
+                 for item in iteratable:
+                     self.append(item)
+-        cls.__init__=init
++        cls.__init__ = init
+ 
+     replace_init_proc(BoolePolynomialVector)
+     replace_init_proc(IntVector)
+ 
+-    monomial_old_init=Monomial.__init__
++    monomial_old_init = Monomial.__init__
++
+ 
+     def fix_monomials():
+         try:
+@@ -150,53 +157,56 @@ else: # import Polybori's original interface
+               - sequence of variables
+             """
+             try:
+-                monomial_old_init(self,arg)
++                monomial_old_init(self, arg)
+             except:
+-                items=sorted((x for x in arg),reverse=True, key=top_index)
+-                prototype=Monomial(items[0])
++                items = sorted((x for x in arg), reverse=True, key=top_index)
++                prototype = Monomial(items[0])
+                 for x in items[1:]:
+-                    prototype*=x
++                    prototype *= x
+ 
+-                monomial_old_init(self,prototype)
++                monomial_old_init(self, prototype)
+ 
+-        Monomial.__init__=monomial_new_init
++        Monomial.__init__ = monomial_new_init
+ 
+     _add_up_polynomials = add_up_polynomials
+-    
++
++
+     def fix_booleset(set_type):
+-        booleset_old_init=set_type.__init__
+-        def booleset_new_init(self,arg=None, second=None):
++        booleset_old_init = set_type.__init__
++
++        def booleset_new_init(self, arg=None, second=None):
+             """
+             Constructor of the class BooleSet (constructs a BooleSet from a CCuddNavigator
+             arg    : of type polybori.dynamic.PyPolyBoRi.CCuddNavigator
+-            second : of type polybori.dynamic.PyPolyBoRi.BooleRing 
++            second : of type polybori.dynamic.PyPolyBoRi.BooleRing
+             """
+             if second != None:
+                 booleset_old_init(self, arg, second)
+             else:
+                 try:
+-                    booleset_old_init(self,arg)
++                    booleset_old_init(self, arg)
+                 except:
+-                    s=set()
+-                    v=BoolePolynomialVector()
++                    s = set()
++                    v = BoolePolynomialVector()
+                     arglist = list(arg)
+                     for i in arglist:
+                         s.add(Monomial(i))
+                     for i in s:
+                         v.append(i)
+-                    p = _add_up_polynomials(v, Polynomial(arglist[0].ring().zero()))
+-                    booleset_old_init(self,p.set())
++                    p = _add_up_polynomials(v, Polynomial(arglist[0].ring().
++                        zero()))
++                    booleset_old_init(self, p.set())
+ 
+         set_type.__init__ = booleset_new_init
+ 
+-
+     fix_booleset(BooleSet)
+ 
+     for k in OrderCode.values:
+-        globals()[str(OrderCode.values[k])]=OrderCode.values[k]
++        globals()[str(OrderCode.values[k])] = OrderCode.values[k]
+ 
+     monomial_cplusplus_div = Monomial.__div__
+ 
++
+     def monomial_python_div(self, arg):
+         try:
+             return monomial_cplusplus_div(self, arg)
+@@ -207,24 +217,31 @@ else: # import Polybori's original interface
+ 
+     variable_cplusplus_div = Variable.__div__
+ 
++
+     def variable_python_div(self, arg):
+         try:
+-            return variable_cplusplus_div(self,arg)
++            return variable_cplusplus_div(self, arg)
+         except ValueError:
+             return Polynomial(0, self.ring())
+ 
+     Variable.__div__ = variable_python_div
+ 
+-    snake_pattern=re.compile('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))')
++    snake_pattern = re.compile('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))')
++
++
+     def to_snake_case(s):
+         return snake_pattern.sub('_\\1', s).lower().strip('_')
+ 
++
+     def warn_snake_case(a, snaked):
+-        warnings.warn("access to %s is deprecated, use %s instead" % (a, snaked), stacklevel=3)
++        warnings.warn("access to %s is deprecated, use %s instead" % (a,
++            snaked), stacklevel=3)
++
++
+     def _strategy_getattr(self, a):
+         if hasattr(self.reduction_strategy, a):
+-            return getattr(self.reduction_strategy,a)
+-        snaked=to_snake_case(a)
++            return getattr(self.reduction_strategy, a)
++        snaked = to_snake_case(a)
+ 
+         if snaked in self.__dict__:
+             warn_snake_case(a, snaked)
+@@ -233,13 +250,15 @@ else: # import Polybori's original interface
+             warn_snake_case(a, snaked)
+             return getattr(self.reduction_strategy, snaked)
+         raise AttributeError
++
++
+     def _strategy_setattr(self, a, v):
+         if a in self.__dict__:
+-            self.__dict__[a]=v
++            self.__dict__[a] = v
+             return
+         if hasattr(self.reduction_strategy, a):
+             return setattr(self.reduction_strategy, a, v)
+-        snaked=to_snake_case(a)
++        snaked = to_snake_case(a)
+         if snaked in self.__dict__:
+             warn_snake_case(a, snaked)
+             return setattr(self, snaked, v)
+@@ -247,10 +266,11 @@ else: # import Polybori's original interface
+         if hasattr(self.reduction_strategy, snaked):
+             warn_snake_case(a, snaked)
+             return setattr(self.reduction_strategy, snaked, v)
+-        self.__dict__[a]=v
++        self.__dict__[a] = v
+     if compatibility_mode:
+-        GroebnerStrategy.__getattr__=_strategy_getattr
+-        GroebnerStrategy.__setattr__=_strategy_setattr
++        GroebnerStrategy.__getattr__ = _strategy_getattr
++        GroebnerStrategy.__setattr__ = _strategy_setattr
++
+ 
+     def weakringref_call(self):
+         if self.is_valid():
+@@ -267,7 +287,7 @@ else: # import Polybori's original interface
+         except:
+             _cpp_ring_init = Ring._libpolybori_init = Ring.__init__
+ 
+-        old_ring_var=Ring.var
++        old_ring_var = Ring.var
+         _cpp_set_variable_name = Ring.set_variable_name
+         _cpp_append_block = Ring.append_block
+         _cpp_change_ordering = Ring.change_ordering
+@@ -276,11 +296,10 @@ else: # import Polybori's original interface
+         _cpp_ring_clone = Ring.clone
+ 
+         def ring_var(self, i):
+-            """Deprecated; use Ring.variable(...). """ 
++            """Deprecated; use Ring.variable(...). """
+             warnings.warn('Ring.var is deprectated; use Ring.variable instead')
+             return old_ring_var(self, i)
+ 
+-
+         def _ring_settings(ring, names, blocks):
+             for (idx, elt) in enumerate(names):
+                 _cpp_set_variable_name(ring, idx, elt)
+@@ -288,9 +307,8 @@ else: # import Polybori's original interface
+             for elt in blocks:
+                 _cpp_append_block(ring, elt)
+ 
+-
+         def _ring_init(self, first, ordering=None, names=[], blocks=[]):
+-            """Ring(n, ordering, names, block) generates a new Boolean 
++            """Ring(n, ordering, names, block) generates a new Boolean
+             polynomial ring with n variables, given  monomial ordering, variable
+             names and block ordering blocks, if given.
+             Further information/call patterns: """""" """
+@@ -300,17 +318,14 @@ else: # import Polybori's original interface
+                 _cpp_ring_init(self, first, ordering)
+             _ring_settings(self, names, blocks)
+ 
+-
+         def _set_variable_name(self, idx, name):
+             """ Deprecated; use Ring.clone(names=...). """
+             warnings.warn('Ring.set_variable_name is deprectated:\
+         use Ring.clone(names=...) instead')
+-            return _cpp_set_variable_name(self, idx, name)    
+-
+-
++            return _cpp_set_variable_name(self, idx, name)
+ 
+         def ring_var(self, i):
+-            """Deprecated; use Ring.variable(...). """ 
++            """Deprecated; use Ring.variable(...). """
+             warnings.warn('Ring.var is deprectated; use Ring.variable instead')
+             return old_ring_var(self, i)
+ 
+@@ -337,7 +352,7 @@ else: # import Polybori's original interface
+             """Deprectated; use Ring.clone(blocks=...). """
+             warnings.warn('Ring.append_block is deprecated:\
+             use Ring.clone(blocks=...) instead')
+-            return _cpp_append_block(self, next_block_start)    
++            return _cpp_append_block(self, next_block_start)
+ 
+         _append_block.__doc__ += _cpp_append_block.__doc__
+ 
+@@ -351,7 +366,7 @@ else: # import Polybori's original interface
+             _set_variable_name.__doc__ += _cpp_set_variable_name.__doc__
+ 
+         Ring.__init__ = _ring_init
+-        Ring.var=ring_var
++        Ring.var = ring_var
+         Ring.set_variable_name = _set_variable_name
+         Ring.clone = _ring_clone
+         Ring.change_ordering = _change_ordering
+@@ -366,6 +381,8 @@ del _os, _sageify
+ 
+ # Common stuff og both interfaces
+ _add_up_polynomials = add_up_polynomials
++
++
+ def add_up_polynomials(polys, init):
+     """
+     Adds up the polynomials in polys (which should be a BoolePolynomialVector or a sequence of ???
+@@ -380,9 +397,7 @@ def add_up_polynomials(polys, init):
+ 
+ _gauss_on_polys = gauss_on_polys
+ 
++
+ def gauss_on_polys(l):
+-    vec=BoolePolynomialVector(l)
++    vec = BoolePolynomialVector(l)
+     return list(_gauss_on_polys(vec))
+-
+-
+-
+diff --git a/pyroot/polybori/__init__.py b/pyroot/polybori/__init__.py
+index 9f05368..b7fbcc6 100644
+--- a/pyroot/polybori/__init__.py
++++ b/pyroot/polybori/__init__.py
+@@ -1,4 +1,4 @@
+-"""The PolyBoRi package implements a framework for computations with Polynomials in Boolean Ring. 
++"""The PolyBoRi package implements a framework for computations with Polynomials in Boolean Ring.
+ 
+ The core of PolyBoRi is a C++ library, which provides high-level data types for Boolean polynomials and monomials,
+ exponent vectors, as well as for the underlying polynomial rings and subsets of the powerset of the Boolean variables.
+@@ -13,24 +13,23 @@ AUTHOR:
+     The PolyBoRi Team, 2007-2011
+ 
+ REFERENCES:
+-M. Brickenstein, A. Dreyer, G. Greuel, M. Wedler, O. Wienand, 
+-New developments in the theory of Groebner bases and applications 
++M. Brickenstein, A. Dreyer, G. Greuel, M. Wedler, O. Wienand,
++New developments in the theory of Groebner bases and applications
+ to formal Verification,  Preprint at http://arxiv.org/abs/0801.1177
+ 
+-M. Brickenstein, A. Dreyer, PolyBoRi: 
+-A Groebner Basis Framework for Boolean Polynomials, 
++M. Brickenstein, A. Dreyer, PolyBoRi:
++A Groebner Basis Framework for Boolean Polynomials,
+ Reports of Fraunhofer ITWM, No. 122, Kaiserslautern, Germany, 2007.
+ http://www.itwm.fraunhofer.de/zentral/download/berichte/bericht122.pdf
+ 
+-M. Brickenstein, A. Dreyer, PolyBoRi: 
++M. Brickenstein, A. Dreyer, PolyBoRi:
+ A framework for Groebner basis computations with Boolean polynomials,
+-Electronic Proceedings of the MEGA 2007 - Effective Methods in Algebraic Geometry, Strobl, Austria, June 2007. 
++Electronic Proceedings of the MEGA 2007 - Effective Methods in Algebraic Geometry, Strobl, Austria, June 2007.
+ http://www.ricam.oeaw.ac.at/mega2007/electronic/electronic.html
+ """
+ 
+ from polybori.PyPolyBoRi import *
+ 
+-
+ # Get all-inclusive groebner routine
+ from polybori.gbcore import groebner_basis
+ from polybori.nf import normal_form
+@@ -42,5 +41,5 @@ from polybori.gbrefs import load_file
+ from polybori.specialsets import *
+ 
+ 
+-def plist(a,b):
+-    return [a,b]
++def plist(a, b):
++    return [a, b]
+diff --git a/pyroot/polybori/addition.py b/pyroot/polybori/addition.py
+index 41fecd6..a44ec3a 100644
+--- a/pyroot/polybori/addition.py
++++ b/pyroot/polybori/addition.py
+@@ -2,6 +2,8 @@ from polybori.PyPolyBoRi import Polynomial, BooleSet, BooleConstant
+ from polybori.partial import PartialFunction
+ from polybori.specialsets import all_monomials_of_degree_d, power_set
+ from polybori.ll import ll_encode, ll_red_nf_redsb
++
++
+ def add_bits_old(bits):
+     """Adds n bits
+     >>> from polybori import *
+@@ -11,21 +13,24 @@ def add_bits_old(bits):
+     >>> 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 = 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
++        step = step + 1
+     return bits_expr
+ 
++
+ def add_bits(bits):
+     """Adds n bit variables, by Lucas theorem
+     >>> from polybori import *
+@@ -37,18 +42,20 @@ def add_bits(bits):
+     >>> add_bits([r.variable(0)])
+     [x(0)]
+     """
+-    bits=list(bits)
+-    if len(bits)<2:
++    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
++    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
+ 
++
+ def add_bit_expressions(bit_expressions):
+     """Adds n bits, which can be arbitrary expressions, the first n variables of the ring    are reversed for usage in this function.
+ 
+@@ -67,12 +74,15 @@ def add_bit_expressions(bit_expressions):
+     bit_variables = []
+     if bit_expressions:
+         ring = bit_expressions[0].ring()
+-        bit_variables=[ring.variable(i) for i in xrange(len(bit_expressions))]
++        bit_variables = [ring.variable(i) for i in xrange(len(bit_expressions)
++            )]
+     for expr in bit_expressions:
+-        assert BooleSet(expr).navigation().value()>=len(bit_variables)
+-    mapping=ll_encode([b+expr for (b, expr) in zip(bit_variables, bit_expressions)])
++        assert BooleSet(expr).navigation().value() >= len(bit_variables)
++    mapping = ll_encode([b + expr for (b, expr) in zip(bit_variables,
++        bit_expressions)])
+     return [ll_red_nf_redsb(p, mapping) for p in add_bits(bit_variables)]
+ 
++
+ def add_words(words):
+     """def adds n words, this words are supposed to consists of list of their bits.
+     >>> from polybori import *
+@@ -88,17 +98,18 @@ def add_words(words):
+     [9, 25, 54, 100, 153, 211, 249, 100]
+     """
+ 
+-    max_word_length=max((len(w) for w in words))
+-    res=[]
+-    while len(words)>0:
+-        words=[w for w in words if len(w)>0]
+-        bits=add_bit_expressions([w[0] for w in words])
+-        words=[w[1:] for w in words]
+-        if len(bits)>0:
++    max_word_length = max((len(w) for w in words))
++    res = []
++    while len(words) > 0:
++        words = [w for w in words if len(w) > 0]
++        bits = add_bit_expressions([w[0] for w in words])
++        words = [w[1:] for w in words]
++        if len(bits) > 0:
+             res.append(bits[0])
+             words.append(bits[1:])
+     return res
+ 
++
+ def multiply_by_addition(word_a, word_b):
+     """Multiply two words
+     >>> from polybori import Ring
+@@ -109,9 +120,9 @@ def multiply_by_addition(word_a, word_b):
+     >>> [p.n_nodes() for p in res]
+     [2, 4, 7, 17, 38, 85, 222, 630, 1358, 1702, 1713, 1430, 875, 214, 0]
+     """
+-    word_a=list(word_a)
+-    word_b=list(word_b)
+-    summands=[]
++    word_a = list(word_a)
++    word_b = list(word_b)
++    summands = []
+     if word_a:
+         zero = word_a[0].ring().zero()
+     elif word_b:
+@@ -120,10 +131,11 @@ def multiply_by_addition(word_a, word_b):
+         zero = BooleConstant(0)
+ 
+     for (i, a) in enumerate(word_a):
+-        summands.append(i*[zero]+[a*b for b in word_b])
++        summands.append(i * [zero] + [a * b for b in word_b])
+ 
+     return add_words(summands)
+ 
++
+ def _test():
+     import doctest
+     doctest.testmod()
+diff --git a/pyroot/polybori/blocks.py b/pyroot/polybori/blocks.py
+index cde7048..6fd16ff 100644
+--- a/pyroot/polybori/blocks.py
++++ b/pyroot/polybori/blocks.py
+@@ -1,413 +1,452 @@
+ import sys
+-if __name__=='__main__':
++if __name__ == '__main__':
+     import pathadjuster
+ 
+ from polybori.PyPolyBoRi import Ring, VariableBlock, Polynomial
+ from polybori.PyPolyBoRi import VariableFactory, MonomialFactory
+-from itertools import chain,islice
++from itertools import chain, islice
+ #class BlockEndException(object):
+   #pass
+   #def __init__(self, arg):
+   # self.arg = arg
+   # pass
+-  
++
+ 
+ class Block(object):
+-  """The block class represents a block of variables <var_name>(start_index,...,start_index+size-1), it is the preferred block type for simple one-dimensional variable sets"""  
+-  def __init__(self, var_name,size,start_index=0,reverse=False):
+-    indices=range(start_index,start_index+size)
+-    if reverse:
+-      indices.reverse()
++    """The block class represents a block of variables
++        <var_name>(start_index,...,start_index+size-1), it is the preferred
++        block type for simple one-dimensional variable sets"""
++
++    def __init__(self, var_name, size, start_index=0, reverse=False):
++        indices = range(start_index, start_index + size)
++        if reverse:
++            indices.reverse()
+     #self.index2pos=dict([(v,k) for (k,v) in enumerate(indices)])
+-    self.names=[var_name+"("+str(i)+")" for i in indices]
+-    self.var_name=var_name
+-    self.start_index=start_index
+-    self.reverse=reverse
+-    self.size=size
+-  def __iter__(self):
+-    return iter(self.names)
+-  def __getitem__(self,i):
+-    return self.names[i]
+-  def __len__(self):
+-    return self.size
+-  
+-  
+-  def register(self, start, context):
+-      #def var_func(i):
+-      #  return Variable(self.index2pos[i]+start)
+-      ring_context = context
+-      while isinstance(ring_context, PrefixedDictProxy):
+-          ring_context = ring_context.wrapped
+-      ring = ring_context['r']
+-
+-      var_func=VariableBlock(self.size,self.start_index,start,self.reverse,
+-                             ring)
+-      var_func.__name__=self.var_name
+-      context[self.var_name]=var_func
++        self.names = [var_name + "(" + str(i) + ")" for i in indices]
++        self.var_name = var_name
++        self.start_index = start_index
++        self.reverse = reverse
++        self.size = size
++
++    def __iter__(self):
++        return iter(self.names)
++
++    def __getitem__(self, i):
++        return self.names[i]
++
++    def __len__(self):
++        return self.size
++
++    def register(self, start, context):
++        #def var_func(i):
++        #  return Variable(self.index2pos[i]+start)
++        ring_context = context
++        while isinstance(ring_context, PrefixedDictProxy):
++            ring_context = ring_context.wrapped
++        ring = ring_context['r']
++
++        var_func = VariableBlock(self.size, self.start_index, start, self.
++            reverse, ring)
++        var_func.__name__ = self.var_name
++        context[self.var_name] = var_func
++
+ 
+ class AlternatingBlock(object):
+-  """The Alternating Block class is used for doing tricky variable schemes,where base names vary, e.g. a(0),b(0),a(1),b(1),a(2),b(2)"""
+-  def __init__(self, var_names, size_per_variable, start_index=0,reverse=False):
+-    self.var_names = var_names
+-    self.size_per_variable = size_per_variable
+-    self.reverse=reverse
+-    indices=range(start_index,start_index+size_per_variable)
+-    
+-    if reverse:
+-      indices.reverse()
+-    names=[]
+-    for i in indices:
+-      for n in var_names:
+-        names.append(n+"("+str(i)+")")
+-    self.indices=indices
+-    self.index2pos=dict([(v,k) for (k,v) in enumerate(indices)])
+-    self.names=names
+-  def __len__(self):
+-    return self.size_per_variable*len(self.var_names)
+-  def __iter__(self):
+-    return iter(self.names)
+-  def __getitem__(self,i):
+-    return self.names[i]
+-  
+-  def register(self,start,context):
+-    def gen_var_func(var_pos):
+-
+-      class var_factory(object):
+-          def __init__(self, ring, index2pos, size):
+-              self.ring = ring
+-              self.index2pos = index2pos
+-              self.size = size
+-          def __call__(self, idx):
+-              return self.ring.variable(self.index2pos[idx]*self.size +
+-                                        var_pos+start)
+-      ring_context = context
+-      while isinstance(ring_context, PrefixedDictProxy):
+-          ring_context = ring_context.wrapped
+-      ring = ring_context['r']
+-
+-      return var_factory(ring, self.index2pos, len(self.var_names))
+-
+-    for (var_pos,n) in enumerate(self.var_names):
+-      var_func=gen_var_func(var_pos)
+-      var_func.__name__=n
+-      context[n]=var_func
+-
+-
+-def shift(f,i):
+-  def g(j):
+-    return f(i+j)
+-  g.__name__=f.__name__
+-  return g
++    """The Alternating Block class is used for doing tricky variable
++        schemes,where base names vary, e.g.
++        a(0),b(0),a(1),b(1),a(2),b(2)"""
++
++    def __init__(self, var_names, size_per_variable, start_index=0,
++        reverse=False):
++        self.var_names = var_names
++        self.size_per_variable = size_per_variable
++        self.reverse = reverse
++        indices = range(start_index, start_index + size_per_variable)
++
++        if reverse:
++            indices.reverse()
++        names = []
++        for i in indices:
++            for n in var_names:
++                names.append(n + "(" + str(i) + ")")
++        self.indices = indices
++        self.index2pos = dict([(v, k) for (k, v) in enumerate(indices)])
++        self.names = names
++
++    def __len__(self):
++        return self.size_per_variable * len(self.var_names)
++
++    def __iter__(self):
++        return iter(self.names)
++
++    def __getitem__(self, i):
++        return self.names[i]
++
++    def register(self, start, context):
++        def gen_var_func(var_pos):
++
++            class var_factory(object):
++                def __init__(self, ring, index2pos, size):
++                    self.ring = ring
++                    self.index2pos = index2pos
++                    self.size = size
++
++                def __call__(self, idx):
++                    return self.ring.variable(self.index2pos[idx] * self.size +
++                                        var_pos + start)
++            ring_context = context
++            while isinstance(ring_context, PrefixedDictProxy):
++                ring_context = ring_context.wrapped
++            ring = ring_context['r']
++
++            return var_factory(ring, self.index2pos, len(self.var_names))
++
++        for (var_pos, n) in enumerate(self.var_names):
++            var_func = gen_var_func(var_pos)
++            var_func.__name__ = n
++            context[n] = var_func
++
++
++def shift(f, i):
++    def g(j):
++        return f(i + j)
++    g.__name__ = f.__name__
++    return g
++
++
+ class AdderBlock(AlternatingBlock):
+-  def __init__(self,adder_bits,sums="s",carries="c",input1="a",input2="b",start_index=0):
+-    AlternatingBlock.__init__(self,(sums,carries,input1,input2),adder_bits,start_index=start_index,reverse=True)
+-    self.input1=input1
+-    self.input2=input2
+-    self.sums=sums
+-    self.carries=carries
+-    self.start_index=start_index
+-    self.adder_bits=adder_bits
+-  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:]
++    def __init__(self, adder_bits, sums="s", carries="c", input1="a",
++        input2="b", start_index=0):
++        AlternatingBlock.__init__(self, (sums, carries, input1, input2),
++            adder_bits, start_index=start_index, reverse=True)
++        self.input1 = input1
++        self.input2 = input2
++        self.sums = sums
++        self.carries = carries
++        self.start_index = start_index
++        self.adder_bits = adder_bits
++
++    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:]
++
+     #def s(i):
+     #  return self.add_results[i-self.start_index]
+     #def c(i):
+     #  return self.carries_polys[i-self.start_index]
+     #context[self.sums]=s
+     #context[self.carries]=c
+-  def implement(self,equations):
+-    for i in xrange(self.adder_bits):
+-      equations.append(self.s(i)+self.add_results[i])
+-      equations.append(self.c(i)+self.carries_polys[i])
+-    pass
++    def implement(self, equations):
++        for i in xrange(self.adder_bits):
++            equations.append(self.s(i) + self.add_results[i])
++            equations.append(self.c(i) + self.carries_polys[i])
++        pass
++
+ 
+-  
+ class HigherOrderBlock(object):
+-  """HigherOrderBlocks are multidimensional blocks of variables, for each dimension a seperate start_index and size can be specified
+-
+-	var_name : variables will be called <var_name>(multiindex), where multiindex is a tuple of the size <size_tuple>
+-	size_tuple : specifies the sizes of the ranges of each component of the multi-indices
+-	start_index_tuple : the multi-indices will be of the form start_index_tuple + a, where a is a multi-index with non-negative components
+-	
+-	"""
+-  def __init__(self, var_name,size_tuple,start_index_tuple=None,reverse=False):
+-    if start_index_tuple is None:
+-      start_index_tuple=len(size_tuple)*(0,)
+-    cart=[()]
+-    assert len(size_tuple)==len(start_index_tuple)
+-    outer_indices=range(len(size_tuple))
+-    outer_indices.reverse()
+-    for i in outer_indices:
+-      s_i=start_index_tuple[i]
+-      s=size_tuple[i]
++    """HigherOrderBlocks are multidimensional blocks of variables, for each dimension a seperate start_index and size can be specified
++
++    var_name : variables will be called <var_name>(multiindex), where multiindex is a tuple of the size <size_tuple>
++    size_tuple : specifies the sizes of the ranges of each component of the multi-indices
++    start_index_tuple : the multi-indices will be of the form start_index_tuple + a, where a is a multi-index with non-negative components
++
++    """
++
++    def __init__(self, var_name, size_tuple, start_index_tuple=None,
++        reverse=False):
++        if start_index_tuple is None:
++            start_index_tuple = len(size_tuple) * (0, )
++        cart = [()]
++        assert len(size_tuple) == len(start_index_tuple)
++        outer_indices = range(len(size_tuple))
++        outer_indices.reverse()
++        for i in outer_indices:
++            s_i = start_index_tuple[i]
++            s = size_tuple[i]
+       #print "cart", cart
+-      cart=[(j,)+ c for j in range(s_i,s_i+s) for c in cart]
+-    if reverse:
+-      cart.reverse()
+-    self.cart=cart
+-    self.cart2index=dict([(v,k) for (k,v) in enumerate(cart)])
+-    self.var_name=var_name
+-    self.names=[var_name+str(c) for c in cart]
+-    pass
+-  def __getitem__(self,i):
+-    return self.names[i]
+-  def __iter__(self):
+-    return iter(self.names)
+-  def __len__(self):
+-    return len(self.names)
+-  
+-  def register(self, start, context):
+-    def var_func(*indices):
+-      return Variable(self.cart2index[indices]+start)
+-    var_func.__name__=self.var_name
+-    context[self.var_name]=var_func
+-
+-
+-class InOutBlock(object):
+-  def __init__(self, out_size, in_size, output="out", input="in",
+-               in_start_index = 0, out_start_index = 0,
+-               out_reverse = False, in_reverse = False):
+-    self.output = Block(var_name = output, start_index = out_start_index,
+-                        size = out_size, reverse = out_reverse)
+-    self.input = Block(var_name = input, start_index = in_start_index,
+-                       size = in_size, reverse = in_reverse)
+-    self.out_start_index = out_start_index;
+-    self.in_start_index = in_start_index;
++            cart = [(j, ) + c for j in range(s_i, s_i + s) for c in cart]
++        if reverse:
++            cart.reverse()
++        self.cart = cart
++        self.cart2index = dict([(v, k) for (k, v) in enumerate(cart)])
++        self.var_name = var_name
++        self.names = [var_name + str(c) for c in cart]
++        pass
+ 
+-  def __iter__(self):
+-    return chain(self.output,self.input)
++    def __getitem__(self, i):
++        return self.names[i]
+ 
+-  def __getitem__(self,i):
+-    if (i < len(self.output)) :
+-      return self.output[i]
+-    else :
+-      return self.input[i - len(self.output)]     
++    def __iter__(self):
++        return iter(self.names)
+ 
+-  def __len__(self):
+-    return len(self.output) + len(self.input)
++    def __len__(self):
++        return len(self.names)
+ 
+-  def register(self,start,context):
+-    self.output.register(start, context)
+-    self.input.register(start + len(self.output), context)
+-    self.out_vars=shift(context[self.output.var_name], self.out_start_index)
+-    self.in_vars=shift(context[self.input.var_name], self.in_start_index)
+-    pass
++    def register(self, start, context):
++        def var_func(*indices):
++            return Variable(self.cart2index[indices] + start)
++        var_func.__name__ = self.var_name
++        context[self.var_name] = var_func
+ 
+ 
++class InOutBlock(object):
++    def __init__(self, out_size, in_size, output="out", input="in",
++               in_start_index=0, out_start_index=0,
++               out_reverse=False, in_reverse=False):
++        self.output = Block(var_name=output, start_index=out_start_index,
++                        size=out_size, reverse=out_reverse)
++        self.input = Block(var_name=input, start_index=in_start_index,
++                       size=in_size, reverse=in_reverse)
++        self.out_start_index = out_start_index
++
++        self.in_start_index = in_start_index
++
++    def __iter__(self):
++        return chain(self.output, self.input)
++
++    def __getitem__(self, i):
++        if (i < len(self.output)):
++            return self.output[i]
++        else:
++            return self.input[i - len(self.output)]
++
++    def __len__(self):
++        return len(self.output) + len(self.input)
++
++    def register(self, start, context):
++        self.output.register(start, context)
++        self.input.register(start + len(self.output), context)
++        self.out_vars = shift(context[self.output.var_name], self.
++            out_start_index)
++        self.in_vars = shift(context[self.input.var_name], self.in_start_index)
++        pass
+ 
+ 
+ class MultiBlock(object):
+-  def __init__(self, sizes = [], var_names = ["v"], start_indices = [], reverses = []):
+-
+-    self.start_indices = start_indices + [0] * (len(var_names) - len(start_indices))
+-    reverses += [False] * (len(var_names) - len(reverses))
+-    sizes  += [1] * (len(var_names) - len(sizes))
+-    
+-    self.blocks = [Block(var_name =  var_names[idx], size = sizes[idx],
+-                         start_index = self.start_indices[idx], reverse = reverses[idx])
+-                   for idx in xrange(len(var_names)) ]
++    def __init__(self, sizes=[], var_names=["v"], start_indices=[], reverses=[
++        ]):
+ 
+-  def __iter__(self):
+-    return chain(*self.blocks)
++        self.start_indices = start_indices + [0] * (len(var_names) - len(
++            start_indices))
++        reverses += [False] * (len(var_names) - len(reverses))
++        sizes += [1] * (len(var_names) - len(sizes))
+ 
+-  def __getitem__(self,i):
+-    return islice(chain(*self.blocks),i,i+1).next()#sum([bl.names for bl in self.blocks])[i]
++        self.blocks = [Block(var_name=var_names[idx], size=sizes[idx],
++            start_index=self.start_indices[idx], reverse=reverses[idx]) for
++            idx in xrange(len(var_names))]
+ 
+-  def __len__(self):
+-    return sum((len(bl) for bl in self.blocks))
++    def __iter__(self):
++        return chain(*self.blocks)
+ 
+-  def register(self,start,context):
+-    offset = 0
+-    for bl in self.blocks:
+-      bl.register(start + offset, context)
+-      offset += len(bl)
++    def __getitem__(self, i):
++        return islice(chain(*self.blocks), i, i + 1).next()
++        # sum([bl.names for bl in self.blocks])[i]
+ 
+-    self.vars = [ shift(context[self.blocks[idx].var_name], self.start_indices[idx])
+-                  for idx in xrange(len(self.blocks)) ]
++    def __len__(self):
++        return sum((len(bl) for bl in self.blocks))
+ 
++    def register(self, start, context):
++        offset = 0
++        for bl in self.blocks:
++            bl.register(start + offset, context)
++            offset += len(bl)
+ 
++        self.vars = [shift(context[self.blocks[idx].var_name], self.
++            start_indices[idx]) for idx in xrange(len(self.blocks))]
+ 
+ 
+ class PrefixedDictProxy(object):
+     """docstring for PrefixedDictProxy"""
+-    def __init__(self, wrapped,prefix):
++
++    def __init__(self, wrapped, prefix):
+         super(PrefixedDictProxy, self).__init__()
+         self.wrapped = wrapped
+-        self.prefix=prefix
+-    def __getitem__(self,k):
++        self.prefix = prefix
++
++    def __getitem__(self, k):
+         try:
+-            return self.wrapped[self.prefix+k]
++            return self.wrapped[self.prefix + k]
+         except KeyError:
+-            print self.prefix,k,list(self.wrapped)
++            print self.prefix, k, list(self.wrapped)
+             raise KeyError
+-    def __setitem__(self,k,v):
+-        self.wrapped[self.prefix+k]=v
+-        
++
++    def __setitem__(self, k, v):
++        self.wrapped[self.prefix + k] = v
++
++
+ class MacroBlock(object):
+-  def __init__(self, prefix):
+-
+-    self.prefix = prefix
+-    self.blocks = []
+-    self.combinations = []
+-    self.connections = []
+-  def declare(self, blocks):
+-    self.blocks = blocks
+- 
+-  def connect(self, combinations):
+-    self.combinations = combinations
+-    
+-  def __iter__(self):
+-    return (self.prefix+"_"+n for n in chain(*self.blocks))
+-
+-  def __getitem__(self, i):
+-    return self.prefix+"_" +islice(chain(*self.blocks),i,i+1).next()
++    def __init__(self, prefix):
++
++        self.prefix = prefix
++        self.blocks = []
++        self.combinations = []
++        self.connections = []
++
++    def declare(self, blocks):
++        self.blocks = blocks
++
++    def connect(self, combinations):
++        self.combinations = combinations
++
++    def __iter__(self):
++        return (self.prefix + "_" + n for n in chain(*self.blocks))
++
++    def __getitem__(self, i):
++        return self.prefix + "_" + islice(chain(*self.blocks), i, i + 1).next()
+     #for bl in self.blocks:
+     #  if i >= len(bl):
+     #    i -= len(bl)
+     #  else:
+     #    return bl[i]
+ 
+-  def __len__(self):
+-    return sum((len(bl) for bl in self.blocks))
++    def __len__(self):
++        return sum((len(bl) for bl in self.blocks))
++
++    def resolve(self, localname):
++        return self.prefix + "_" + localname
+ 
+-  def resolve(self, localname):
+-    return self.prefix+"_"+localname
++    def register(self, start, context):
++        context = PrefixedDictProxy(context, self.prefix + "_")
++        offset = 0
++        for bl in self.blocks:
++            bl.register(start + offset, context)
++            offset += len(bl)
+ 
+-  def register(self,start,context):
+-    context=PrefixedDictProxy(context,self.prefix+"_")
+-    offset = 0
+-    for bl in self.blocks:
+-      bl.register(start + offset, context)
+-      offset += len(bl)
++        for ((con1, indices1), (con2, indices2)) in self.combinations:
++            for idx in xrange(min(len(indices1), len(indices2))):
++                self.connections += [context[con1](indices1[idx]) + context[
++                    con2](indices2[idx])]
+ 
+-    for ( (con1, indices1), (con2, indices2) ) in self.combinations:
+-      for idx in xrange( min(len(indices1), len(indices2)) ):
+-        self.connections += [context[con1](indices1[idx]) + context[con2](indices2[idx])]
++    def implement(self, equations):
++        for bl in self.blocks:
++            if hasattr(bl, "implement"):
++                bl.implement(equations)
++
++        equations += self.connections
+ 
+-  def implement(self,equations):
+-    for bl in self.blocks:
+-      if hasattr(bl, "implement"):      
+-        bl.implement(equations)
+ 
+-    equations += self.connections
+-    
+-    
+-   
+ class IfThen(object):
+-  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
+-  def __str__(self):
+-    return "If(AND("+", ".join([str(p)+" == 0" for p in self.ifpart])+")), THEN " +", ".join([str(p)+" == 0" for p in self.thenpart])
+-def if_then(i,t,supposed_to_be_valid=True):
+-  return IfThen(i,t,supposed_to_be_valid)
+-
+-def declare_ring(blocks,context=None):
+-  """Declare Ring is the preferred function to create a ring and declare a variable scheme, 
++    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
++
++    def __str__(self):
++        return ("If(AND(" + ", ".join([str(p) + " == 0" for p in self.ifpart])
++            + ")), THEN " + ", ".join([str(p) + " == 0" for p in self.thenpart
++            ]))
++
++
++def if_then(i, t, supposed_to_be_valid=True):
++    return IfThen(i, t, supposed_to_be_valid)
++
++
++def declare_ring(blocks, context=None):
++    """Declare Ring is the preferred function to create a ring and declare a variable scheme,
+   the number of variables is automatically determined,
+   usually you pass globals() as context argument to store the ring and the variable mapping.
+   Example
+   declare_ring([Block("x",10),Block("y",5)],globals())
+-  gives  a ring with x(0..9),y(0..4) and registers the ring as r, 
++  gives  a ring with x(0..9),y(0..4) and registers the ring as r,
+   and the variable blocks x and y in the context dictionary globals(), which consists of the global variables of the python module
+   """
+-  if context is None:
+-      context = sys.modules['__main__'].__dict__
+-
+-  def canonicalize(blocks):
+-      for elt in blocks:
+-          if isinstance(elt, str):
+-              yield elt
+-          else:
+-              for subelt in elt:
+-                  yield subelt
+-
+-  blocks=list(blocks)
+-  n=0
+-
+-  for b in blocks:
+-      if isinstance(b,str):
+-          n=n+1
+-      else:
+-          n=n+len(b)
+- 
+-  r=Ring(n, names=canonicalize(blocks))
+-
+-  context["internalVariable"] = VariableFactory(r)
++    if context is None:
++        context = sys.modules['__main__'].__dict__
++
++    def canonicalize(blocks):
++        for elt in blocks:
++            if isinstance(elt, str):
++                yield elt
++            else:
++                for subelt in elt:
++                    yield subelt
++
++    blocks = list(blocks)
++    n = 0
++
++    for b in blocks:
++        if isinstance(b, str):
++            n = n + 1
++        else:
++            n = n + len(b)
++
++    r = Ring(n, names=canonicalize(blocks))
++
++    context["internalVariable"] = VariableFactory(r)
+ #  context["Monomial"] = MonomialFactory(r)
+-  context["r"]=r
+-  declare_block_scheme(blocks,context)
+-  return r
++    context["r"] = r
++    declare_block_scheme(blocks, context)
++    return r
++
+ 
+-def declare_block_scheme(blocks,context):
+-    start=0
+-    block_starts=[]
++def declare_block_scheme(blocks, context):
++    start = 0
++    block_starts = []
+     ring = context["r"]
+     for b in blocks:
+-      if start!=0:
+-          block_starts.append(start)
+-      if isinstance(b,str):
+-        context[b] = context["internalVariable"](start)
++        if start != 0:
++            block_starts.append(start)
++        if isinstance(b, str):
++            context[b] = context["internalVariable"](start)
+         #_cpp_set_variable_name(ring, start, b)
+-        start=start+1
+-      else:
+-        b.register(start,context)
++            start = start + 1
++        else:
++            b.register(start, context)
+         #for (pos,name) in enumerate(b):
+         #    _cpp_set_variable_name(ring, start+pos, name)
+-        start=start+len(b)
+-    context["block_start_hints"]=block_starts
+-    context["number_of_declared_vars"]=start
+-    
+-  
++            start = start + len(b)
++    context["block_start_hints"] = block_starts
++    context["number_of_declared_vars"] = start
++
++
+ def main():
+-  r=Ring(1000)
+-  ablock=AlternatingBlock(["a","b","c"],100)
+-  declare_block_scheme([ablock],globals())
+-  for i in range(10):
+-     print r.variable(i)
+-     
+-  print list(ablock)
+-  declare_block_scheme([
+-    Block(var_name="x",size=100),
+-    HigherOrderBlock("y",(3,4,11,2)),
+-    AlternatingBlock(["a","b","c"],100)],
++    r = Ring(1000)
++    ablock = AlternatingBlock(["a", "b", "c"], 100)
++    declare_block_scheme([ablock], globals())
++    for i in range(10):
++        print r.variable(i)
++
++    print list(ablock)
++    declare_block_scheme([
++    Block(var_name="x", size=100),
++    HigherOrderBlock("y", (3, 4, 11, 2)),
++    AlternatingBlock(["a", "b", "c"], 100)],
+     globals())
+-  for i in range(10):
+-    print x(i)
+-  print y(0,0,0,0)
+-  print y(0,0,0,1)
+-  print y(0,0,1,0)
+-  print y(0,0,1,1)
+-  print a(0),a(1),a(2),b(0),b(1),c(0)
+-  declare_block_scheme([
+-    Block(var_name="x",size=100,reverse=True),
+-    HigherOrderBlock("y",(3,4,11,2),reverse=True),
+-    AlternatingBlock(["a","b","c"],100,reverse=True)],
++    for i in range(10):
++        print x(i)
++    print y(0, 0, 0, 0)
++    print y(0, 0, 0, 1)
++    print y(0, 0, 1, 0)
++    print y(0, 0, 1, 1)
++    print a(0), a(1), a(2), b(0), b(1), c(0)
++    declare_block_scheme([
++    Block(var_name="x", size=100, reverse=True),
++    HigherOrderBlock("y", (3, 4, 11, 2), reverse=True),
++    AlternatingBlock(["a", "b", "c"], 100, reverse=True)],
+     globals())
+-  for i in range(10):
+-    print x(i)
+-  print y(0,0,0,0)
+-  print y(0,0,0,1)
+-  print y(0,0,1,0)
+-  print y(0,0,1,1)
+-  print a(0),a(1),a(2),b(0),b(1),c(0)
+-  declare_block_scheme(["a","b","c"],globals())
+-  print a,b,c
++    for i in range(10):
++        print x(i)
++    print y(0, 0, 0, 0)
++    print y(0, 0, 0, 1)
++    print y(0, 0, 1, 0)
++    print y(0, 0, 1, 1)
++    print a(0), a(1), a(2), b(0), b(1), c(0)
++    declare_block_scheme(["a", "b", "c"], globals())
++    print a, b, c
+ if __name__ == '__main__':
+-   main()
+-
++    main()
+diff --git a/pyroot/polybori/check_claims.py b/pyroot/polybori/check_claims.py
+index bcbcf2f..72111bf 100644
+--- a/pyroot/polybori/check_claims.py
++++ b/pyroot/polybori/check_claims.py
+@@ -12,185 +12,193 @@ from optparse import OptionParser
+ #    import pathadjuster
+ from polybori.PyPolyBoRi import Polynomial, Monomial, BooleConstant, BooleSet
+ from polybori.PyPolyBoRi import recursively_insert
+-from polybori.gbrefs import my_import, load_data, clean_data,load_file
++from polybori.gbrefs import my_import, load_data, clean_data, load_file
+ from polybori.blocks import IfThen
+ from copy import copy
+ from polybori.ll import ll_encode, ll_red_nf_noredsb, ll_red_nf_redsb
+ 
+-def find_one(p,res=None):
++
++def find_one(p, res=None):
+     def zero_nav(n):
+         return n.constant() and (not n.terminal_one())
+     try:
+-        p=p.navigation()
++        p = p.navigation()
+     except AttributeError:
+         pass
+     if res is None:
+-        res=dict()
++        res = dict()
+     if zero_nav(p):
+         raise ValueError
+     if p.terminal_one():
+         return res
+-    else_branch=p.else_branch()
++    else_branch = p.else_branch()
+     if zero_nav(else_branch):
+-        res[Monomial(Variable(p.value()))]=1
+-        find_one(p.then_branch(),res)
++        res[Monomial(Variable(p.value()))] = 1
++        find_one(p.then_branch(), res)
+     else:
+-        res[Monomial(Variable(p.value()))]=0
+-        find_one(else_branch,res)
++        res[Monomial(Variable(p.value()))] = 0
++        find_one(else_branch, res)
+     return res
+ 
+ parser = OptionParser()
+-NF3="nf3"
+-LINEAR_LEAD_NOREDSB="ll"
++NF3 = "nf3"
++LINEAR_LEAD_NOREDSB = "ll"
+ parser.add_option("--method",
+                   action="store", dest="method", type="choice",
+-                  choices=["nf3","linear-lead-redsb",LINEAR_LEAD_NOREDSB],
++                  choices=["nf3", "linear-lead-redsb", LINEAR_LEAD_NOREDSB],
+                   default="linear-lead-redsb",
+                   help="select method")
+ 
+-def my_red_nf(p,strat):
+-  if p.is_zero():
+-    return p
+-  hr=nf3(strat.reduction_strategy,p,p.lead())
+-  if hr.is_zero():
+-    return hr
+-  return red_tail(strat,hr)
++
++def my_red_nf(p, strat):
++    if p.is_zero():
++        return p
++    hr = nf3(strat.reduction_strategy, p, p.lead())
++    if hr.is_zero():
++        return hr
++    return red_tail(strat, hr)
++
++
+ 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
++    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
++
++
+ def logicaland(l):
+-  res=BooleConstant(0)
+-  for p in l:
+-    res=1+(res+1)*(p+1)
+-  return res
++    res = BooleConstant(0)
++    for p in l:
++        res = 1 + (res + 1) * (p + 1)
++    return res
++
+ 
+ def logicalor(l):
+-  res=BooleConstant(1)
+-  for p in l:
+-    res=res*p
+-  return res
+-
+-
+-
+-        
+-def proof(ifthen,strat):
+-  ip=ifthen.ifpart
+-  it=ifthen.thenpart
+-  print "proofing:", ifthen
+-  c=logicalor([1+logicaland(ip),logicaland(it)])
+-  if c.is_zero():
+-    print "TRUE (trivial)"
+-    return
+-  else:
+-    c=nf3(strat.reduction_strategy,c,c.lead())
+-    if c.is_zero():
+-      print "TRUE"
+-      return
+-    else:
+-      print "FALSE"
+-
+-
+-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])
++    res = BooleConstant(1)
++    for p in l:
++        res = res * p
++    return res
++
+ 
++def proof(ifthen, strat):
++    ip = ifthen.ifpart
++    it = ifthen.thenpart
++    print "proofing:", ifthen
++    c = logicalor([1 + logicaland(ip), logicaland(it)])
+     if c.is_zero():
+-      if prot:
+-         print "TRUE (trivial)"
+-      return True
++        print "TRUE (trivial)"
++        return
+     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:
++        c = nf3(strat.reduction_strategy, c, c.lead())
++        if c.is_zero():
+             print "TRUE"
+-        return True
+-      else:
++            return
++        else:
++            print "FALSE"
++
++
++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 "FAILED"
+-            print "can construct COUNTER EXAMPLE with:", find_one(c)
+-        return False
+-        
+-
++            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 to_if_then(p):
+-  if isinstance(p,IfThen):
+-    return p
+-  else:
+-    return IfThen([],[p])
++    if isinstance(p, IfThen):
++        return p
++    else:
++        return IfThen([], [p])
++
++
+ def main(argv=None):
+-     (opts,args)= parser.parse_args()
+-     mydata=load_file(args[0])
+-     claims=mydata.claims
+-     if opts.method==NF3:
+-       strat=gen_strat(mydata.ideal)
+-       for c in claims:
+-         proof(to_if_then(c),strat)
+-       del strat
+-       try:
+-         del c
+-       except NameError:
+-         pass
+-     else:
+-       if opts.method==LINEAR_LEAD_NOREDSB:
+-           reductors=ll_encode(mydata.ideal)
+-           for c in claims:
+-                proofll(to_if_then(c),reductors,redsb=False)
+-           del reductors
+-           try:
++    (opts, args) = parser.parse_args()
++    mydata = load_file(args[0])
++    claims = mydata.claims
++    if opts.method == NF3:
++        strat = gen_strat(mydata.ideal)
++        for c in claims:
++            proof(to_if_then(c), strat)
++        del strat
++        try:
++            del c
++        except NameError:
++            pass
++    else:
++        if opts.method == LINEAR_LEAD_NOREDSB:
++            reductors = ll_encode(mydata.ideal)
++            for c in claims:
++                proofll(to_if_then(c), reductors, redsb=False)
++            del reductors
++            try:
++                del c
++            except NameError:
++                pass
++        else:
++            reductors = ll_encode(mydata.ideal, reduce=True)
++            for c in claims:
++                proofll(to_if_then(c), reductors)
++            del reductors
++            try:
+                 del c
+-           except NameError:
++            except NameError:
+                 pass
+-       else:
+-           reductors=ll_encode(mydata.ideal, reduce=True)
+-           for c in claims:
+-             proofll(to_if_then(c),reductors)
+-           del reductors
+-           try:
+-              del c
+-           except NameError:
+-              pass
+-     return 0
++    return 0
+ 
+ if __name__ == "__main__":
+     sys.exit(main())
+diff --git a/pyroot/polybori/cluster.py b/pyroot/polybori/cluster.py
+index 27f6438..8a5e9b3 100644
+--- a/pyroot/polybori/cluster.py
++++ b/pyroot/polybori/cluster.py
+@@ -10,61 +10,65 @@ Copyright 2011 The PolyBoRi Team. See LICENSE file.
+ import sys
+ import os
+ from polybori.statistics import used_vars, used_vars_set
+-from polybori.PyPolyBoRi import Variable 
++from polybori.PyPolyBoRi import Variable
++
+ 
+ def main():
+     pass
+ 
++
+ class ClusterAlgorithmFailed(Exception):
+     pass
+ 
++
+ class ClusterAlgorithm(object):
+     def __init__(self, ideal, determination_modifier=1):
+         if len(ideal) == 0:
+             raise ValueError, 'ideal generators list should be non empty'
+-        
++
+         self.ideal = ideal
+-        
++
+         self.determination_modifier = determination_modifier
+-        
++
+         self.used_variables_ideal = used_vars_set(ideal)
+-        
++
+         self.number_of_used_variables_in_ideal = len(self.used_variables_ideal)
+         self.used_variables_of_polynomial = dict(
+             [(p, set(p.vars_as_monomial().variables())) for p in ideal])
+         self.variables_introduction_mapping = dict()
+-        
+ 
+-        
+         self.cluster = set()
+         self.used_variables_cluster = set()
+         self.build_variables_usage()
+         self.initialize_variables_introduction_mapping()
+ 
+     def build_variables_usage(self):
+-        self.variables_usage=dict()
++        self.variables_usage = dict()
+         for (p, variables) in self.used_variables_of_polynomial.iteritems():
+             for v in variables:
+                 self.variables_usage.setdefault(v, []).append(p)
+-                
++
+     def initialize_variables_introduction_mapping(self):
+         self._build_variables_introduction_mapping()
+-        
++
+     def _build_variables_introduction_mapping(self):
+         def var_set_to_tuple(s):
+-            return tuple(sorted(s, key = Variable.index))
++            return tuple(sorted(s, key=Variable.index))
+         self.variables_introduction_mapping.clear()
+         for (p, var_set) in self.used_variables_of_polynomial.iteritems():
+             if p in self.cluster:
+                 continue
+-            as_tuple = var_set_to_tuple(var_set.difference(self.used_variables_cluster))
++            as_tuple = var_set_to_tuple(var_set.difference(self.
++                used_variables_cluster))
+             self.variables_introduction_mapping.setdefault(
+                 as_tuple, []).append(p)
++
+     def adjust_variables_introduction_mapping(self, introduced_variables):
+         self._build_variables_introduction_mapping()
+ 
+     def determined_enough(self):
+-        return self.number_of_used_variables_in_cluster+self.determination_modifier<=len(self.cluster)
++        return (self.number_of_used_variables_in_cluster + self.
++            determination_modifier <= len(self.cluster))
+ 
+     def find_cluster(self):
+         p = self.initial_choice()
+@@ -73,38 +77,44 @@ class ClusterAlgorithm(object):
+         while not self.determined_enough():
+             self.increase_cluster()
+         return list(self.cluster)
+-        
+-    
++
+     def add_polynomial_to_cluster(self, p):
+         self.cluster.add(p)
+-        self.used_variables_cluster = set(used_vars_set(self.cluster).variables())
+-        self.number_of_used_variables_in_cluster = len(self.used_variables_cluster)
+-        self.adjust_variables_introduction_mapping(self.used_variables_of_polynomial[p])
+-        
++        self.used_variables_cluster = set(used_vars_set(self.cluster).
++            variables())
++        self.number_of_used_variables_in_cluster = len(self.
++            used_variables_cluster)
++        self.adjust_variables_introduction_mapping(self.
++            used_variables_of_polynomial[p])
++
+     def initial_choice(self):
+         def max_key(entry):
+-            (entry_variable, entry_polynomials)=entry
++            (entry_variable, entry_polynomials) = entry
+             return len(entry_polynomials)
+-        (variable, polynomials)=max(self.variables_usage.iteritems(), key=max_key)
++        (variable, polynomials) = max(self.variables_usage.iteritems(),
++            key=max_key)
++
+         def min_key(p):
+             return len(self.used_variables_of_polynomial[p])
+         return min(polynomials, key=min_key)
++
+     def increase_cluster(self):
+-        introduced_variables_possibilities=self.variables_introduction_mapping.keys()
+-        introduced_variables=min(introduced_variables_possibilities, key=len)
+-        polynomials=self.variables_introduction_mapping[introduced_variables]
+-        assert len(polynomials)>0
++        introduced_variables_possibilities = (self.
++            variables_introduction_mapping.keys())
++        introduced_variables = min(introduced_variables_possibilities, key=len)
++        polynomials = self.variables_introduction_mapping[introduced_variables]
++        assert len(polynomials) > 0
+         for p in polynomials:
+             self.add_polynomial_to_cluster(p)
+-        if len(self.cluster)==len(self.ideal):
++        if len(self.cluster) == len(self.ideal):
+             raise ClusterAlgorithmFailed
+         self.adjust_variables_introduction_mapping(introduced_variables)
+ 
++
+ def find_cluster(ideal):
+-    algorithm=ClusterAlgorithm(ideal)
++    algorithm = ClusterAlgorithm(ideal)
+     return algorithm.find_cluster()
+-    
++
+ 
+ if __name__ == '__main__':
+     main()
+-
+diff --git a/pyroot/polybori/cnf.py b/pyroot/polybori/cnf.py
+index 4b8650a..dc77916 100644
+--- a/pyroot/polybori/cnf.py
++++ b/pyroot/polybori/cnf.py
+@@ -1,14 +1,17 @@
+ from random import Random
+-from polybori.PyPolyBoRi import Monomial, BooleSet, Polynomial, if_then_else as ite,\
+-    lp, gauss_on_polys, ll_red_nf_redsb
++from polybori.PyPolyBoRi import (Monomial, BooleSet, Polynomial, if_then_else
++    as ite, lp, gauss_on_polys, ll_red_nf_redsb)
+ from polybori.ll import ll_encode
+ from polybori.statistics import used_vars_set
++
++
+ class CNFEncoder(object):
+-    def __init__(self, r, random_seed = 16):
++    def __init__(self, r, random_seed=16):
+         self.random_generator = Random(random_seed)
+         self.one_set = r.one().set()
+         self.empty_set = r.zero().set()
+         self.r = r
++
+     def zero_blocks(self, f):
+         """divides the zero set of f into blocks
+         >>> from polybori import *
+@@ -17,17 +20,18 @@ class CNFEncoder(object):
+         >>> e.zero_blocks(r.variable(0)*r.variable(1)*r.variable(2))
+         [{y: 0}, {z: 0}, {x: 0}]
+         """
+-        f=Polynomial(f)
++        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 
++            return iter(rest).next()  # somewhat
++
+             #inefficient compared to polynomials lex_lead
+         def choose(s):
+             indices = []
+@@ -40,10 +44,10 @@ class CNFEncoder(object):
+                     indices.append(nav.value())
+                     nav = t
+                 else:
+-                    if self.random_generator.randint(0,1):
++                    if self.random_generator.randint(0, 1):
+                         indices.append(nav.value())
+                         nav = t
+-                    
++
+                     else:
+                         nav = e
+             assert nav.terminal_one()
+@@ -54,6 +58,7 @@ class CNFEncoder(object):
+         while not rest.empty():
+             l = choose(rest)
+             l_variables = set(l.variables())
++
+             def get_val(var):
+                 if var in l_variables:
+                     return 1
+@@ -86,12 +91,13 @@ class CNFEncoder(object):
+         >>> [sorted(c.iteritems()) for c in e.clauses(r.variable(1)+r.variable(0))]
+         [[(y, 1), (x, 0)], [(y, 0), (x, 1)]]
+         """
+-        f_plus_one = f+1
+-        blocks = self.zero_blocks(f+1)
+-        negated_blocks=[dict([(variable, 1-value) for (variable, value) 
+-            in b.iteritems()]) for b in blocks ]
+-        # we form an expression for a var configuration *not* lying in the block
+-        # it is evaluated to 0 by f, iff it is not lying in any zero block of f+1
++        f_plus_one = f + 1
++        blocks = self.zero_blocks(f + 1)
++        negated_blocks = [dict([(variable, 1 - value) for (variable, value)
++            in b.iteritems()]) for b in blocks]
++        # we form an expression for a var configuration *not* lying in the
++        # block it is evaluated to 0 by f, iff it is not lying in any zero
++        # block of f+1
+         return negated_blocks
+ 
+     def polynomial_clauses(self, f):
+@@ -106,31 +112,33 @@ class CNFEncoder(object):
+         >>> groebner_basis([p], heuristic = False)==groebner_basis(e.polynomial_clauses(p), heuristic = False)
+         True
+         """
++
+         def product(l):
+             res = l[0]
+             for p in l[1:]:
+-                res = res*p
+-            #please care about the order of these multiplications for performance
++                res = res * p
++            # please care about the order of these multiplications for
++            # performance
+             return res
+-        return [product([variable + value for (variable, value) in b.iteritems()]) 
+-            for b in self.clauses(f)]
++        return [product([variable + value for (variable, value)
++                         in b.iteritems()]) for b in self.clauses(f)]
+ 
+     def to_dimacs_index(self, v):
+-        return v.index()+1
+-        
++        return v.index() + 1
++
+     def dimacs_encode_clause(self, c):
+         def get_sign(val):
+-            if value == 1: 
++            if value == 1:
+                 return 1
+             return -1
+-            
++
+         items = sorted(c.iteritems(), reverse=True)
+         return " ".join(
+-        [str(v) for v in 
++        [str(v) for v in
+             [
+-            get_sign(value)*self.to_dimacs_index(variable) 
+-            for (variable, value) in items]+[0]])
+-            
++            get_sign(value) * self.to_dimacs_index(variable)
++            for (variable, value) in items] + [0]])
++
+     def dimacs_encode_polynomial(self, p):
+         """
+          >>> from polybori import *
+@@ -141,7 +149,7 @@ class CNFEncoder(object):
+          ['1 2 -3 0', '1 -2 3 0', '-1 -2 -3 0', '-1 2 3 0']
+             """
+         clauses = self.clauses(p)
+-        res=[]
++        res = []
+         for c in clauses:
+             res.append(self.dimacs_encode_clause(c))
+         return res
+@@ -158,7 +166,8 @@ class CNFEncoder(object):
+         >>> e.dimacs_cnf([r.variable(0)*r.variable(1)*r.variable(2), r.variable(1)+r.variable(0)])
+         'c cnf generated by PolyBoRi\np cnf 3 3\n-1 -2 -3 0\n-1 2 0\n1 -2 0'
+         """
+-        clauses_list = [c for p in polynomial_system for c in self.dimacs_encode_polynomial(p)]
++        clauses_list = [c for p in polynomial_system for c in self.
++            dimacs_encode_polynomial(p)]
+         res = ["c cnf generated by PolyBoRi"]
+         r = polynomial_system[0].ring()
+         n_variables = r.n_variables()
+@@ -166,8 +175,11 @@ class CNFEncoder(object):
+         for c in clauses_list:
+             res.append(c)
+         return "\n".join(res)
++
++
+ class CryptoMiniSatEncoder(CNFEncoder):
+-    group_counter=0
++    group_counter = 0
++
+     def dimacs_encode_polynomial(self, p):
+         r"""
+          >>> from polybori import *
+@@ -184,23 +196,24 @@ class CryptoMiniSatEncoder(CNFEncoder):
+          >>> e.dimacs_encode_polynomial(p+1)
+          ['x1 2 -3 0\nc g 2 x + y + z + 1']
+             """
+-        if p.deg()!=1 or len(p)<=1:
++        if p.deg() != 1 or len(p) <= 1:
+             res = super(CryptoMiniSatEncoder, self).dimacs_encode_polynomial(p)
+         else:
+-            
++
+             if p.has_constant_part():
+                 invert_last = True
+             else:
+                 invert_last = False
+-            variables=list(p.vars_as_monomial().variables())
++            variables = list(p.vars_as_monomial().variables())
+             indices = [self.to_dimacs_index(v) for v in variables]
+             if invert_last:
+-                indices[-1]=-indices[-1]
++                indices[-1] = -indices[-1]
+             indices.append(0)
+-            res = ["x"+" ".join([str(v) for v in indices])]
++            res = ["x" + " ".join([str(v) for v in indices])]
+         self.group_counter = self.group_counter + 1
+-        group_comment="\nc g %s %s" %(self.group_counter, str(p)[:30])
+-        return [c+group_comment for c in res]
++        group_comment = "\nc g %s %s" % (self.group_counter, str(p)[:30])
++        return [c + group_comment for c in res]
++
+     def dimacs_cnf(self, polynomial_system):
+         r"""
+             >>> from polybori import *
+@@ -213,10 +226,13 @@ class CryptoMiniSatEncoder(CNFEncoder):
+             >>> e.dimacs_cnf([r.variable(0)*r.variable(1)*r.variable(2), r.variable(1)+r.variable(0)])
+             'c cnf generated by PolyBoRi\np cnf 3 2\n-1 -2 -3 0\nc g 3 x*y*z\nx1 2 0\nc g 4 x + y\nc v 1 x\nc v 2 y\nc v 3 z'
+             """
+-        uv=list(used_vars_set(polynomial_system).variables())
+-        res=super(CryptoMiniSatEncoder, self).dimacs_cnf(polynomial_system)
+-        res=res+"\n"+"\n".join(["c v %s %s"% (self.to_dimacs_index(v), v) for v in uv])
++        uv = list(used_vars_set(polynomial_system).variables())
++        res = super(CryptoMiniSatEncoder, self).dimacs_cnf(polynomial_system)
++        res = res + "\n" + "\n".join(["c v %s %s" % (self.to_dimacs_index(v),
++            v) for v in uv])
+         return res
++
++
+ def _test():
+     import doctest
+     doctest.testmod()
+diff --git a/pyroot/polybori/coding.py b/pyroot/polybori/coding.py
+index 82323ae..91cb1a8 100644
+--- a/pyroot/polybori/coding.py
++++ b/pyroot/polybori/coding.py
+@@ -3,74 +3,83 @@ from polybori.nf import symmGB_F2_C
+ from polybori.ll import ll_encode
+ from itertools import ifilter
+ 
++
+ class OccCounter(object):
+     def __init__(self):
+-        self.impl=dict()
+-    def __getitem__(self,k):
++        self.impl = dict()
++
++    def __getitem__(self, k):
+         try:
+             return self.impl[k]
+         except KeyError:
+             return 0
+-    def increase(self,k):
++
++    def increase(self, k):
+         try:
+-            self.impl[k]=self.impl[k]+1
++            self.impl[k] = self.impl[k] + 1
+         except KeyError:
+-            self.impl[k]=1
++            self.impl[k] = 1
++
+     def uniques(self):
+         def filter_fun(k):
+-            return self.impl[k]==1
+-        return ifilter(filter_fun,self.impl.keys())
+-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,selection_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
++            return self.impl[k] == 1
++        return ifilter(filter_fun, self.impl.keys())
++
++
++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])])
++    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
++    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
+diff --git a/pyroot/polybori/context.py b/pyroot/polybori/context.py
+index 660e24b..1f1467f 100644
+--- a/pyroot/polybori/context.py
++++ b/pyroot/polybori/context.py
+@@ -1,6 +1,6 @@
+-if __name__=='__main__':
++if __name__ == '__main__':
+     from sys import path as search_path
+-    from os import path as file_path   
++    from os import path as file_path
+     search_path.append(file_path.join(file_path.dirname(__file__), '..'))
+ 
+ 
+@@ -18,6 +18,7 @@ from polybori.PyPolyBoRi import PolynomialFactory, SetFactory
+ from polybori.PyPolyBoRi import Variable, Monomial, Polynomial, BooleSet
+ import polybori
+ 
++
+ class FactoryContext(object):
+     """Temporarily exchange the constructor of a given type with a compatible
+     callable object. It is useful together with the with statement.
+@@ -35,12 +36,14 @@ class FactoryContext(object):
+     ...     print "caught expected exception"
+     caught expected exception
+     """
++
+     def __init__(self, original, factory):
+         self.original = original
+         self.factory = factory
+ 
+     def __enter__(self):
+         self.fallback = self.original.__init__
++
+         def func(orig, *args):
+             try:
+                 self.fallback(orig, self.factory(*args))
+@@ -52,7 +55,8 @@ class FactoryContext(object):
+ 
+     def __exit__(self, type, value, traceback):
+         self.original.__init__ = self.fallback
+-        return False       
++        return False
++
+ 
+ class RingContext(object):
+     """Temporarily fix the ring for constructors of some ring-dependent types
+@@ -73,6 +77,7 @@ class RingContext(object):
+     ...     print "caught expected exception"
+     caught expected exception
+     """
++
+     def __init__(self, ring):
+         self.contexts = (FactoryContext(Variable, VariableFactory(ring)),
+                          FactoryContext(Monomial, MonomialFactory(ring)),
+@@ -91,7 +96,6 @@ class RingContext(object):
+         return result
+ 
+ 
+-if __name__=='__main__':
++if __name__ == '__main__':
+     import doctest
+     doctest.testmod()
+-
+diff --git a/pyroot/polybori/easy_polynomials.py b/pyroot/polybori/easy_polynomials.py
+index 3ede488..28713fc 100644
+--- a/pyroot/polybori/easy_polynomials.py
++++ b/pyroot/polybori/easy_polynomials.py
+@@ -1,9 +1,10 @@
+ from polybori.interpolate import variety_lex_leading_terms, nf_lex_points
+ from polybori.PyPolyBoRi import easy_linear_factors
+ 
++
+ def easy_linear_polynomials(p):
+     """ Get linear polynomials implied by given polynomial.
+-    
++
+     >>> from polybori.frontend import *
+     >>> easy_linear_polynomials(x(1)*x(2) + 1)
+     [x(1) + 1, x(2) + 1]
+@@ -12,20 +13,21 @@ def easy_linear_polynomials(p):
+     >>> easy_linear_polynomials(x(0)*x(1) + x(0)*x(2) + 1)
+     [x(0) + 1, x(1) + x(2) + 1]
+     """
+-    res=[]
+-    if p.deg()>=2:
+-        if p.vars_as_monomial().deg() >8: 
+-            opp=p+1
++    res = []
++    if p.deg() >= 2:
++        if p.vars_as_monomial().deg() > 8:
++            opp = p + 1
+             for q in easy_linear_factors(opp):
+-                res.append(q+1)
++                res.append(q + 1)
+         else:
+-            res= easy_linear_polynomials_via_interpolation(p)
++            res = easy_linear_polynomials_via_interpolation(p)
+     return res
+ 
++
+ def easy_linear_polynomials_via_interpolation(p):
+     """ Get linear polynomials implied by given polynomial using interpolation
+     of the variety.
+-    
++
+     >>> from polybori.frontend import *
+     >>> easy_linear_polynomials_via_interpolation(x(1)*x(2) + 1)
+     [x(1) + 1, x(2) + 1]
+@@ -37,11 +39,11 @@ def easy_linear_polynomials_via_interpolation(p):
+     res = []
+     p_vars = p.vars_as_monomial()
+     space = p_vars.divisors()
+-    zeros = p.zeros_in(space) 
++    zeros = p.zeros_in(space)
+     lex_leads = variety_lex_leading_terms(zeros, p_vars)
+     for m in lex_leads:
+-        if m.deg()==1:
+-            red=m+nf_lex_points(m, zeros)
+-            if red.lead_deg()==1:#normal ordering
++        if m.deg() == 1:
++            red = m + nf_lex_points(m, zeros)
++            if red.lead_deg() == 1:  # normal ordering
+                 res.append(red)
+     return res
+diff --git a/pyroot/polybori/fglm.py b/pyroot/polybori/fglm.py
+index 433158e..13b035e 100644
+--- a/pyroot/polybori/fglm.py
++++ b/pyroot/polybori/fglm.py
+@@ -1,21 +1,24 @@
+ if __name__ == "__main__":
+-    import os, sys
++    import os
++    import sys
+     sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir))
+-    
++
++
+     def _test():
+         import doctest
+         doctest.testmod()
+ 
+-
+-from polybori.PyPolyBoRi import BooleSet, Polynomial, BoolePolynomialVector,\
++from polybori.PyPolyBoRi import BooleSet, Polynomial, BoolePolynomialVector, \
+     FGLMStrategy, Monomial, Ring
+ 
+ from polybori.blocks import declare_ring
+ 
++
+ def _fglm(I, from_ring, to_ring):
+     """Unchecked variant of fglm"""
+-    vec=BoolePolynomialVector(I)
+-    return FGLMStrategy(from_ring,to_ring,vec).main()
++    vec = BoolePolynomialVector(I)
++    return FGLMStrategy(from_ring, to_ring, vec).main()
++
+ 
+ def fglm(I, from_ring, to_ring):
+     """
+@@ -36,7 +39,8 @@ def fglm(I, from_ring, to_ring):
+         if poly.ring().id() != from_ring.id():
+             raise ValueError, "Ideal I must be from the first ring argument"
+     return _fglm(I, from_ring, to_ring)
+-    
++
++
+ def vars_real_divisors(monomial, monomial_set):
+     """
+     returns all elements of of monomial_set, which result multiplied by a variable in monomial.
+@@ -49,7 +53,9 @@ def vars_real_divisors(monomial, monomial_set):
+     >>> 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))
++    return BooleSet(Polynomial(monomial_set.divisors_of(monomial)). \
++        graded_part(monomial.deg() - 1))
++
+ 
+ def m_k_plus_one(completed_elements, variables):
+     """ calculates $m_{k+1}$ from the FGLM algorithm as described in Wichmanns diploma thesis
+@@ -66,7 +72,8 @@ def m_k_plus_one(completed_elements, variables):
+     >>> m_k_plus_one(r2(s).set(),r2(variables).set())
+     x(1)*x(3)
+     """
+-    return sorted(completed_elements.cartesian_product(variables).diff(completed_elements))[0]
++    return sorted(completed_elements.cartesian_product(variables).diff(
++        completed_elements))[0]
+ 
+ 
+ if __name__ == "__main__":
+diff --git a/pyroot/polybori/frontend.py b/pyroot/polybori/frontend.py
+index 0ac27d4..399cdc6 100644
+--- a/pyroot/polybori/frontend.py
++++ b/pyroot/polybori/frontend.py
+@@ -1,7 +1,7 @@
+ # Import basic functionality
+ r"""
+-This module defines an initial ring, and patches the declare_ring to use 
+-a given context. 
++This module defines an initial ring, and patches the declare_ring to use
++a given context.
+ 
+ 
+ >>> x(0)
+@@ -19,7 +19,7 @@ x(9999)
+ 
+ >>> from polybori.frontend import *
+ >>> context = dict(globals())
+->>> polybori_start(context) # doctest: +ELLIPSIS 
++>>> polybori_start(context) # doctest: +ELLIPSIS
+ ipbori...
+ >>> r = context['declare_ring']('abc')
+ >>> context['a']
+@@ -32,6 +32,7 @@ from polybori import *
+ from polybori.blocks import declare_ring as orig_declare_ring
+ from os import environ as env, path as os_path
+ 
++
+ def block_scheme_names(blocks):
+     """Helper for Singular interface."""
+ 
+@@ -41,7 +42,8 @@ def block_scheme_names(blocks):
+ 
+     return context.keys()
+ 
+-ipbname = 'ipbori' 
++ipbname = 'ipbori'
++
+ 
+ def polybori_copyright():
+     print """Copyright (c) 2007-2011 by The PolyBoRi Team.
+@@ -59,16 +61,18 @@ PolyBoRi incorporates the following works:
+   The M4RI Library - http://m4ri.sagemath.org
+     Copyright (C) 2007-2010, Martin Albrecht, Gregory Bard, and The M4RI Team"""
+ 
++
+ def polybori_license():
+     print """ipbori and the PolyBoRi framework are licensed under the terms of
+ the GNU General Public License (GPL) version 2 or later.
+ See http://www.gnu.org/licenses/ for details."""
+ 
++
+ def polybori_start(global_context):
+     def declare_ring(blocks, context=None):
+         if context is None:
+             context = global_context
+-        
++
+         return orig_declare_ring(blocks, context)
+     declare_ring.__doc__ = orig_declare_ring.__doc__
+     global_context["declare_ring"] = declare_ring
+@@ -80,4 +84,3 @@ Type "polybori_copyright()" or "polybori_license()" for more information.
+ # Here come the defaults
+ r = Ring(10000)
+ x = VariableFactory(r)
+-
+diff --git a/pyroot/polybori/gbcore.py b/pyroot/polybori/gbcore.py
+index bb2d6fd..130e30b 100644
+--- a/pyroot/polybori/gbcore.py
++++ b/pyroot/polybori/gbcore.py
+@@ -7,29 +7,32 @@ from copy import copy
+ from itertools import chain
+ from inspect import getargspec
+ from polybori.statistics import used_vars, used_vars_set
+-from polybori.heuristics import dense_system,gauss_on_linear
++from polybori.heuristics import dense_system, gauss_on_linear
+ from polybori.easy_polynomials import easy_linear_polynomials
+ from itertools import chain
+ from polybori.interpolate import lex_groebner_basis_for_polynomial_via_variety
+ from inspect import getargspec
+ from polybori.fglm import _fglm
+ 
++
+ def get_options_from_function(f):
+-    (argnames,varargs,varopts,defaults) = getargspec(f)
++    (argnames, varargs, varopts, defaults) = getargspec(f)
+     return dict(
+         zip(
+-            argnames[-len(defaults):],defaults))
++            argnames[-len(defaults):], defaults))
++
+ 
+ def filter_oldstyle_options(**options):
+     filtered = dict()
+     for key in options.keys():
+-        newkey = key       
++        newkey = key
+         for prefix in ['', 'use_', 'opt_allow_', 'opt_']:
+             newkey = newkey.replace(prefix, '')
+         filtered[newkey] = options[key]
+ 
+     return filtered
+ 
++
+ def filter_newstyle_options(func, **options):
+     allowed = get_options_from_function(func).keys()
+     filtered = dict()
+@@ -39,7 +42,8 @@ def filter_newstyle_options(func, **options):
+                 filtered[prefix + key] = options[key]
+ 
+     return filtered
+-                
++
++
+ def owns_one_constant(I):
+     """Determines whether I contains the constant one polynomial."""
+     for p in I:
+@@ -47,254 +51,284 @@ def owns_one_constant(I):
+             return True
+     return False
+ 
++
+ def want_interpolation_gb(G):
+     if not G:
+         return False
+-    if G[0].ring().get_order_code()!=OrderCode.lp:
++    if G[0].ring().get_order_code() != OrderCode.lp:
+         return False
+-    if len(G)!=1:
++    if len(G) != 1:
+         return False
+-    p=Polynomial(G[0])
+-    if p.lead_deg()<=1:
++    p = Polynomial(G[0])
++    if p.lead_deg() <= 1:
+         return False
+-    if p.set().n_nodes()>1000:
++    if p.set().n_nodes() > 1000:
+         return False
+     return True
+ 
++
+ def ll_is_good(I):
+-    lex_lead=set()
++    lex_lead = set()
+     for p in I:
+         if not p.is_zero():
+-            m=p.lex_lead()
+-            if m.deg()==1:
++            m = p.lex_lead()
++            if m.deg() == 1:
+                 lex_lead.add(iter(m.variables()).next().index())
+-    if len(lex_lead)>=0.8*len(I):
+-        uv=used_vars_set(I).deg()#don't use len here, which will yield 1
+-        if len(lex_lead)>0.9*uv:
+-            if uv- len(lex_lead)>16:
++    if len(lex_lead) >= 0.8 * len(I):
++        uv = used_vars_set(I).deg()  # don't use len here, which will yield 1
++        if len(lex_lead) > 0.9 * uv:
++            if uv - len(lex_lead) > 16:
+                 return "llfirstonthefly"
+             else:
+                 return "llfirst"
+     return False
+-    
++
++
+ def ll_heuristic(d):
+-    d=copy(d)
+-    I=d["I"]
++    d = copy(d)
++    I = d["I"]
+     if (not "llfirstonthefly" in d) and (not "llfirst" in d):
+-        hint=ll_is_good(I)
++        hint = ll_is_good(I)
+         if hint:
+-            d[hint]=True
++            d[hint] = True
+     return d
+ 
+ 
+-
+ def change_order_heuristic(d):
+-    d_orig=d
+-    d=copy(d)
+-    I=d["I"]
++    d_orig = d
++    d = copy(d)
++    I = d["I"]
+     if not I:
+-       return d 
+-    switch_table={OrderCode.lp:OrderCode.dp_asc,OrderCode.dlex:OrderCode.dp_asc}
++        return d
++    switch_table = {OrderCode.lp: OrderCode.dp_asc, OrderCode.dlex: OrderCode.
++        dp_asc}
+     if not "other_ordering_first" in d:
+-        #TODO after ll situation might look much different, so heuristic is on wrong place
+-        code=iter(I).next().ring().get_order_code()
++        # TODO after ll situation might look much different, so heuristic is on
++        # wrong place
++        code = iter(I).next().ring().get_order_code()
+         if code in switch_table:
+-            max_non_linear=len(I)/2
+-            non_linear=0
+-            if code==OrderCode.lp:
++            max_non_linear = len(I) / 2
++            non_linear = 0
++            if code == OrderCode.lp:
+                 for p in I:
+-                    if p.lead_deg()>1:
+-                        non_linear=non_linear+1
+-                        if non_linear>max_non_linear:
++                    if p.lead_deg() > 1:
++                        non_linear = non_linear + 1
++                        if non_linear > max_non_linear:
+                             break
+-            if (non_linear>max_non_linear) or (code!=OrderCode.lp):
+-                other_ordering_opts=copy(d_orig)
+-                other_ordering_opts["switch_to"]=switch_table[code]
+-                d["other_ordering_first"]=other_ordering_opts
++            if (non_linear > max_non_linear) or (code != OrderCode.lp):
++                other_ordering_opts = copy(d_orig)
++                other_ordering_opts["switch_to"] = switch_table[code]
++                d["other_ordering_first"] = other_ordering_opts
+     return d
+ 
+ 
+ def interpolation_gb_heuristic(d):
+-    d=copy(d)
+-    I=d["I"]
+-    if not d.get("other_ordering_opts",False) and want_interpolation_gb(I):
+-        d["interpolation_gb"]=True
+-        d["other_ordering_first"]=False
++    d = copy(d)
++    I = d["I"]
++    if not d.get("other_ordering_opts", False) and want_interpolation_gb(I):
++        d["interpolation_gb"] = True
++        d["other_ordering_first"] = False
+     return d
++
++
+ def linear_algebra_heuristic(d):
+-    d_orig=d
+-    d=copy(d)
+-    I=d["I"]
++    d_orig = d
++    d = copy(d)
++    I = d["I"]
++
+     def want_la():
+         if not I:
+             return False
+-        n_used_vars=None
+-        bound=None
++        n_used_vars = None
++        bound = None
+         if iter(I).next().ring().has_degree_order():
+-            new_bound=200
+-            n_used_vars=used_vars_set(I,bound=new_bound).deg()
+-            if n_used_vars<new_bound:
++            new_bound = 200
++            n_used_vars = used_vars_set(I, bound=new_bound).deg()
++            if n_used_vars < new_bound:
+                 return True
+-            bound=new_bound
++            bound = new_bound
+         if dense_system(I):
+-            new_bound=100
+-            if not (bound and new_bound<bound):
+-                n_used_vars=used_vars_set(I,bound=new_bound).deg()
+-                bound=new_bound
+-            if n_used_vars<bound:
++            new_bound = 100
++            if not (bound and new_bound < bound):
++                n_used_vars = used_vars_set(I, bound=new_bound).deg()
++                bound = new_bound
++            if n_used_vars < bound:
+                 return True
+         return False
+-    if not (("faugere" in d and (not d["faugere"])) or ("noro" in d and d["noro"])):
++    if not (("faugere" in d and (not d["faugere"])) or ("noro" in d and d[
++        "noro"])):
+         if ("faugere" in d and d["faugere"]) or want_la():
+ 
+-            d["faugere"]=True
++            d["faugere"] = True
+             if not "red_tail" in d:
+-                d["red_tail"]=False
++                d["red_tail"] = False
+             if not "selection_size" in d:
+-                d["selection_size"]=10000
++                d["selection_size"] = 10000
+             if not ("ll" in d):
+-                d["ll"]=True
++                d["ll"] = True
+ 
+     return d
+ 
+-def trivial_heuristic(d):   
++
++def trivial_heuristic(d):
+     return d
++
++
+ class HeuristicalFunction(object):
+-    def __call__(self,*args,**kwds):
+-        complete_dict=copy(kwds)
+-        heuristic=True
++    def __call__(self, *args, **kwds):
++        complete_dict = copy(kwds)
++        heuristic = True
+         try:
+-            heuristic=complete_dict["heuristic"]
++            heuristic = complete_dict["heuristic"]
+         except KeyError:
+             pass
+-        for (k,v) in zip(self.argnames,args):
+-            complete_dict[k]=v 
++        for (k, v) in zip(self.argnames, args):
++            complete_dict[k] = v
+         if heuristic:
+-            complete_dict=self.heuristicFunction(complete_dict)
++            complete_dict = self.heuristicFunction(complete_dict)
+         return self.f(**complete_dict)
+-    def __init__(self,f,heuristic_function):
+-        (self.argnames,self.varargs,self.varopts,self.defaults)=getargspec(f)
+-        if hasattr(f,"options"):
+-            self.options=f.options
++
++    def __init__(self, f, heuristic_function):
++        (self.argnames, self.varargs, self.varopts, self.defaults) = (
++            getargspec(f))
++        if hasattr(f, "options"):
++            self.options = f.options
+         else:
+-            self.options=dict(zip(self.argnames[-len(self.defaults):],self.defaults))
+-        self.heuristicFunction=heuristic_function
+-        self.f=f
+-        self.__doc__=f.__doc__
+-        
++            self.options = dict(zip(self.argnames[-len(self.defaults):], self.
++                defaults))
++        self.heuristicFunction = heuristic_function
++        self.f = f
++        self.__doc__ = f.__doc__
++
++
+ def with_heuristic(heuristic_function):
+     def make_wrapper(f):
+-        wrapped=HeuristicalFunction(f,heuristic_function)
+-        wrapped.__name__=f.__name__
++        wrapped = HeuristicalFunction(f, heuristic_function)
++        wrapped.__name__ = f.__name__
+         return wrapped
+     return make_wrapper
+ 
++
+ def clean_polys(I):
+-    I=list(set((Polynomial(p) for p in I if not Polynomial(p).is_zero())))
++    I = list(set((Polynomial(p) for p in I if not Polynomial(p).is_zero())))
+     return I
+ 
++
+ def clean_polys_pre(I):
+-    return (clean_polys(I),None) 
++    return (clean_polys(I), None)
++
+ 
+ def gb_with_pre_post_option(
+-    option,pre=None,
+-    post=None,if_not_option=tuple(),
++    option, pre=None,
++    post=None, if_not_option=tuple(),
+     default=False):
+     def make_wrapper(f):
+         def wrapper(I, **kwds):
+-            prot=kwds.get("prot", False)
++            prot = kwds.get("prot", False)
+             for o in if_not_option:
+-                if (o in kwds and kwds[o]) or (o not in kwds and groebner_basis.options[o]):
+-                    option_set=False
++                if (o in kwds and kwds[o]) or (o not in kwds and
++                    groebner_basis.options[o]):
++                    option_set = False
+             if not "option_set" in locals():
+                 if option in kwds:
+-                    
+-                    option_set=kwds[option]
++
++                    option_set = kwds[option]
+                 else:
+-                    option_set=default
+-            kwds=dict(((o,kwds[o]) for o in kwds if o!=option))
+-            state=None
++                    option_set = default
++            kwds = dict(((o, kwds[o]) for o in kwds if o != option))
++            state = None
+ 
+             if option_set:
+-               if pre:
+-                   pre_args=getargspec(pre)[0]
+-                   if prot:
+-                       print "preprocessing for option:", option
+-
+-                   local_symbols = copy(locals())
+-                   (I, state) = pre(**dict([(k,v) for (k,v) in \
+-                                   local_symbols.iteritems() if k in pre_args]))
+-            I=f(I,**kwds)
++                if pre:
++                    pre_args = getargspec(pre)[0]
++                    if prot:
++                        print "preprocessing for option:", option
++
++                    local_symbols = copy(locals())
++                    (I, state) = pre(**dict([(k, v) for (k, v) in
++                        local_symbols.iteritems() if k in pre_args]))
++            I = f(I, **kwds)
+             if option_set:
+                 if post:
+-                    post_args=getargspec(post)[0]
++                    post_args = getargspec(post)[0]
+                     if prot:
+                         print "postprocessing for option:", option
+                     local_symbols = copy(locals())
+-                    I = post(**dict([(k,v) for (k,v) \
++                    I = post(**dict([(k, v) for (k, v) \
+                             in local_symbols.iteritems() if k in post_args]))
+ 
+             return I
+-        wrapper.__name__=f.__name__
+-        wrapper.__doc__=f.__doc__
+-        if hasattr(f,"options"):
+-            wrapper.options=copy(f.options)
++        wrapper.__name__ = f.__name__
++        wrapper.__doc__ = f.__doc__
++        if hasattr(f, "options"):
++            wrapper.options = copy(f.options)
+         else:
+-            
++
+             wrapper.options = get_options_from_function(f)
+ 
+-        wrapper.options[option]=default
++        wrapper.options[option] = default
+         return wrapper
+     return make_wrapper
+ 
+-def redsb_post(I,state):
+-    if I==[]:
++
++def redsb_post(I, state):
++    if I == []:
+         return []
+     else:
+         return I.minimalize_and_tail_reduce()
+-def minsb_post(I,state):
+-    if I==[]:
++
++
++def minsb_post(I, state):
++    if I == []:
+         return []
+     else:
+         return I.minimalize()
++
++
+ def invert_all(I):
+     return [p.map_every_x_to_x_plus_one() for p in I]
++
++
+ def invert_all_pre(I):
+-    return (invert_all(I),None)
+-def invert_all_post(I,state):
++    return (invert_all(I), None)
++
++
++def invert_all_post(I, state):
+     return invert_all(I)
+-    
+-def llfirst_pre(I,prot):
+-    (eliminated,llnf, I)=eliminate(I,on_the_fly=False,prot=prot)
+-    return (I,eliminated)
++
++
++def llfirst_pre(I, prot):
++    (eliminated, llnf, I) = eliminate(I, on_the_fly=False, prot=prot)
++    return (I, eliminated)
++
+ 
+ def ll_constants_pre(I):
+-    ll_res=[]
+-    
+-    while len([p for p in I if p.lex_lead_deg()==1 and
+-    (p+p.lex_lead()).constant()])>0:
+-        I_new=[]
+-        ll=[]
+-        leads=set()
++    ll_res = []
++
++    while len([p for p in I if p.lex_lead_deg() == 1 and
++    (p + p.lex_lead()).constant()]) > 0:
++        I_new = []
++        ll = []
++        leads = set()
+         for p in I:
+-            if p.lex_lead_deg()==1:
+-                l=p.lead()
++            if p.lex_lead_deg() == 1:
++                l = p.lead()
+                 if not (l in leads) and p.is_singleton_or_pair():
+-                    tail=p+l
+-                    if tail.deg()<=0:
++                    tail = p + l
++                    if tail.deg() <= 0:
+                         ll.append(p)
+                         leads.add(l)
+                         continue
+             I_new.append(p)
+-        encoded=ll_encode(ll)
+-        reduced=[]
++        encoded = ll_encode(ll)
++        reduced = []
+         for p in I_new:
+-            p=ll_red_nf_redsb(p,encoded)
++            p = ll_red_nf_redsb(p, encoded)
+             if not p.is_zero():
+                 reduced.append(p)
+-        I=reduced
++        I = reduced
+         ll_res.extend(ll)
+-    return (I,ll_res)
++    return (I, ll_res)
+ 
+ 
+ def variety_size_from_gb(I):
+@@ -322,9 +356,9 @@ def variety_size_from_gb(I):
+     >>> variety_size_from_gb(mons)
+     1.2676506002282294e+30
+     """
+-    I=[Polynomial(p) for p in I]
+-    I=[p for p in I if not p.is_zero()]
+-    if len(I)==0:
++    I = [Polynomial(p) for p in I]
++    I = [p for p in I if not p.is_zero()]
++    if len(I) == 0:
+         return 1
+ ##     # TODO Here's something wrong! See the example with 5 solutions.
+ ##     # (reverting for now)
+@@ -338,13 +372,14 @@ def variety_size_from_gb(I):
+ ##     return standard_monomials.size_double()*\
+ ##         2**(number_of_used_vars-number_of_used_vars_minimal_leads)
+ 
+-    sm=Monomial(used_vars_set(I)).divisors()
++    sm = Monomial(used_vars_set(I)).divisors()
+     for p in I:
+-        m=p.lead()
+-        sm=sm.diff(sm.multiples_of(m))
++        m = p.lead()
++        sm = sm.diff(sm.multiples_of(m))
+     return sm.size_double()
+ 
+-def other_ordering_pre(I,option_set,kwds):
++
++def other_ordering_pre(I, option_set, kwds):
+     """
+     >>> from polybori.blocks import declare_ring
+     >>> r = declare_ring(['x0', 'x1', 'x2', 'x3', 'x4'], globals())
+@@ -356,38 +391,42 @@ def other_ordering_pre(I,option_set,kwds):
+     if not I:
+         return (I, None)
+ 
+-    main_kwds=kwds
+-    options=option_set
++    main_kwds = kwds
++    options = option_set
+ 
+-    old_ring=iter(I).next().ring()
+-    ocode=old_ring.get_order_code()
++    old_ring = iter(I).next().ring()
++    ocode = old_ring.get_order_code()
+     try:
+         new_ring = old_ring.clone(ordering=options["switch_to"])
+ 
+-        kwds=dict((k,options[k]) for k in options if not (k in ("other_ordering_first","switch_to","I")))
+-        kwds["redsb"]=True
+-        I_orig=I
+-        I=groebner_basis([new_ring(poly) for poly in I],**kwds)
+-        variety_size=variety_size_from_gb(I)
+-        if variety_size<50000:
+-            main_kwds["convert_with_fglm_from_ring"]=new_ring
+-            main_kwds["convert_with_fglm_to_ring"]=old_ring        
++        kwds = dict((k, options[k]) for k in options if not (k in (
++            "other_ordering_first", "switch_to", "I")))
++        kwds["redsb"] = True
++        I_orig = I
++        I = groebner_basis([new_ring(poly) for poly in I], **kwds)
++        variety_size = variety_size_from_gb(I)
++        if variety_size < 50000:
++            main_kwds["convert_with_fglm_from_ring"] = new_ring
++            main_kwds["convert_with_fglm_to_ring"] = old_ring
+         else:
+             I = [old_ring(poly) for poly in I]
+     finally:
+         pass
+ 
+-    return (I,None)
++    return (I, None)
++
++
++def llfirstonthefly_pre(I, prot):
++    (eliminated, llnf, I) = eliminate(I, on_the_fly=True)
++    return (I, eliminated)
+ 
+-def llfirstonthefly_pre(I,prot):
+-    (eliminated,llnf, I)=eliminate(I,on_the_fly=True)
+-    return (I,eliminated)
+ 
+ def gauss_on_linear_pre(I, prot):
+     return (gauss_on_linear(I), None)
+ 
++
+ def easy_linear_polynomials_pre(I):
+-    res=[]
++    res = []
+     for p in I:
+         res.append(p)
+         res.extend(easy_linear_polynomials(p))
+@@ -395,210 +434,231 @@ def easy_linear_polynomials_pre(I):
+     return (list(set(res)), None)
+ 
+ 
+-
+-def llfirst_post(I,state,prot, kwds):
+-    eliminated=state
++def llfirst_post(I, state, prot, kwds):
++    eliminated = state
+     for p in I:
+         if p.is_one():
+             return [p]
+     else:
+-        if len(eliminated)>0:
+-            I=list(chain(I,eliminated))
++        if len(eliminated) > 0:
++            I = list(chain(I, eliminated))
+             #redsb just for safety, as don't know how option is set
+-            kwds=copy(kwds)
++            kwds = copy(kwds)
+             kwds.update(
+-                dict(llfirst = False,
+-                llfirstonthefly = False,
+-                ll_constants = False,
+-                deg_bound = False,
+-                other_ordering_first = False,
+-                eliminate_identical_variables = False, redsb = True))
+-            I=groebner_basis(
++                dict(llfirst=False,
++                llfirstonthefly=False,
++                ll_constants=False,
++                deg_bound=False,
++                other_ordering_first=False,
++                eliminate_identical_variables=False, redsb=True))
++            I = groebner_basis(
+                 I, **kwds
+             )
+     return I
+-            
+ 
+ 
+-def ll_constants_post(I,state):
+-    eliminated=state
++def ll_constants_post(I, state):
++    eliminated = state
+     for p in I:
+         if p.is_one():
+             return [p]
+     else:
+-        if len(eliminated)>0:
+-            I=list(chain(I,eliminated))
++        if len(eliminated) > 0:
++            I = list(chain(I, eliminated))
+             #redsb just for safety, as don't know how option is set
+         return I
+ 
+-def result_to_list_post(I,state):
++
++def result_to_list_post(I, state):
+     return list(I)
+-def fix_deg_bound_post(I,state):
+-    if isinstance(I,GroebnerStrategy):
++
++
++def fix_deg_bound_post(I, state):
++    if isinstance(I, GroebnerStrategy):
+         return I.all_generators()
+     else:
+         return I
+ 
+-def incremental_pre(I,prot, kwds):
++
++def incremental_pre(I, prot, kwds):
+     def sort_key(p):
+-        p=Polynomial(p)
++        p = Polynomial(p)
+         return (p.navigation().value(), -p.deg())
+-    I=sorted(I, key=sort_key)
+-    inc_sys=[]
+-    kwds=copy(kwds)
+-    kwds['incremental']=False
++    I = sorted(I, key=sort_key)
++    inc_sys = []
++    kwds = copy(kwds)
++    kwds['incremental'] = False
+ 
+     for p in I[:-1]:
+         inc_sys.append(p)
+-        inc_sys=groebner_basis(inc_sys, **kwds)
++        inc_sys = groebner_basis(inc_sys, **kwds)
+         if prot:
+             print "incrementally calculating GB, adding generator:", p
+     inc_sys.append(I[:-1])
+-    return (inc_sys,None)
++    return (inc_sys, None)
++
+ 
+ def eliminate_identical_variables_pre(I, prot):
+-    changed=True
+-    ll_system=[]
+-    treated_linears=set()
++    changed = True
++    ll_system = []
++    treated_linears = set()
+     while changed:
+-        changed=False
+-        rules=dict()
++        changed = False
++        rules = dict()
+         for p in I:
+-            t=p+p.lead()
+-            if p.lead_deg()==1:
+-                l=p.lead()
++            t = p + p.lead()
++            if p.lead_deg() == 1:
++                l = p.lead()
+                 if l in treated_linears:
+                     continue
+                 else:
+                     treated_linears.add(l)
+-                if t.deg()>0:
++                if t.deg() > 0:
+                     rules.setdefault(t, [])
+-                    leads=rules[t]
++                    leads = rules[t]
+                     leads.append(l)
++
+         def my_sort_key(l):
+             return l.navigation().value()
+         for (t, leads) in rules.iteritems():
+-            if len(leads)>1:
+-                changed=True
+-                leads=sorted(leads, key=my_sort_key, reverse=True)
+-                chosen=leads[0]
++            if len(leads) > 1:
++                changed = True
++                leads = sorted(leads, key=my_sort_key, reverse=True)
++                chosen = leads[0]
+                 for v in leads[1:]:
+-                    ll_system.append(chosen+v)
+-    if len(ll_system)>0:
+-        ll_encoded=ll_encode(ll_system, reduce=True)
+-        I=set([ll_red_nf_redsb(p, ll_encoded) for p in I])
++                    ll_system.append(chosen + v)
++    if len(ll_system) > 0:
++        ll_encoded = ll_encode(ll_system, reduce=True)
++        I = set([ll_red_nf_redsb(p, ll_encoded) for p in I])
+     return (I, ll_system)
+ 
+- at gb_with_pre_post_option("clean_arguments",pre=clean_polys_pre,default=True)
+- at gb_with_pre_post_option("easy_linear_polynomials", pre=easy_linear_polynomials_pre, default=True)
+- at gb_with_pre_post_option("result_to_list",post=result_to_list_post,default=True)
++
++ at gb_with_pre_post_option("clean_arguments", pre=clean_polys_pre, default=True)
++ at gb_with_pre_post_option("easy_linear_polynomials",
++    pre=easy_linear_polynomials_pre, default=True)
++ at gb_with_pre_post_option("result_to_list", post=result_to_list_post,
++    default=True)
+ @with_heuristic(interpolation_gb_heuristic)
+- at gb_with_pre_post_option("invert",pre=invert_all_pre,post=invert_all_post,default=False)
+- at gb_with_pre_post_option("gauss_on_linear", pre=gauss_on_linear_pre, default=True)
+- at gb_with_pre_post_option("ll_constants", pre=ll_constants_pre,post=ll_constants_post,default=True)
+- at gb_with_pre_post_option("eliminate_identical_variables", pre=eliminate_identical_variables_pre, post=llfirst_post, default=True)
++ at gb_with_pre_post_option("invert", pre=invert_all_pre,
++    post=invert_all_post, default=False)
++ at gb_with_pre_post_option("gauss_on_linear", pre=gauss_on_linear_pre,
++    default=True)
++ at gb_with_pre_post_option("ll_constants", pre=ll_constants_pre,
++    post=ll_constants_post, default=True)
++ at gb_with_pre_post_option("eliminate_identical_variables",
++    pre=eliminate_identical_variables_pre, post=llfirst_post, default=True)
+ @with_heuristic(ll_heuristic)
+- at gb_with_pre_post_option("llfirst",if_not_option=["llfirstonthefly"],pre=llfirst_pre,post=llfirst_post,default=False)
+- at gb_with_pre_post_option("llfirstonthefly",pre=llfirstonthefly_pre,post=llfirst_post,default=False)
+- at gb_with_pre_post_option("incremental",pre=incremental_pre)
++ at gb_with_pre_post_option("llfirst", if_not_option=["llfirstonthefly"],
++    pre=llfirst_pre, post=llfirst_post, default=False)
++ at gb_with_pre_post_option("llfirstonthefly", pre=llfirstonthefly_pre,
++    post=llfirst_post, default=False)
++ at gb_with_pre_post_option("incremental", pre=incremental_pre)
+ @with_heuristic(change_order_heuristic)
+- at gb_with_pre_post_option("other_ordering_first",if_not_option=["interpolation_gb"],pre=other_ordering_pre,default=False)
++ at gb_with_pre_post_option("other_ordering_first", if_not_option=[
++    "interpolation_gb"], pre=other_ordering_pre, default=False)
+ @with_heuristic(linear_algebra_heuristic)
+- at gb_with_pre_post_option("fix_deg_bound",if_not_option=["interpolation_gb"], post=fix_deg_bound_post,default=True)
+- at gb_with_pre_post_option("minsb",post=minsb_post,if_not_option=["redsb","deg_bound","interpolation_gb","convert_with_fglm_from_ring"],default=True)
+- at gb_with_pre_post_option("redsb",post=redsb_post,if_not_option=["deg_bound","interpolation_gb","convert_with_fglm_from_ring"],default=True)
+-def groebner_basis(I, heuristic=True,unique_ideal_generator=False, interpolation_gb=False, 
+-    clean_and_restart_algorithm=False, convert_with_fglm_from_ring=None,
+-    convert_with_fglm_to_ring=None,
+-    modified_linear_algebra=True, preprocessor=None, 
+-    deg_bound = False, implementation = "Python",
+-    full_prot = False, prot = False,
+-    draw_matrices = False, preprocess_only = False,
+-**impl_options):
++ at gb_with_pre_post_option("fix_deg_bound", if_not_option=["interpolation_gb"],
++    post=fix_deg_bound_post, default=True)
++ at gb_with_pre_post_option("minsb", post=minsb_post, if_not_option=["redsb",
++    "deg_bound", "interpolation_gb", "convert_with_fglm_from_ring"],
++    default=True)
++ at gb_with_pre_post_option("redsb", post=redsb_post, if_not_option=["deg_bound",
++    "interpolation_gb", "convert_with_fglm_from_ring"], default=True)
++
++def groebner_basis(I, heuristic=True, unique_ideal_generator=False,
++    interpolation_gb=False, clean_and_restart_algorithm=False,
++    convert_with_fglm_from_ring=None, convert_with_fglm_to_ring=None,
++    modified_linear_algebra=True, preprocessor=None, deg_bound=False,
++    implementation="Python", full_prot=False, prot=False, draw_matrices=False,
++    preprocess_only=False, **impl_options):
+     """Computes a Groebner basis of a given ideal I, w.r.t options."""
+ 
+     if not I:
+         return I
+-    
++
+     if full_prot:
+-        prot=True
++        prot = True
+     if prot:
+-        print "number of passed generators:",len(I)
++        print "number of passed generators:", len(I)
+     if not convert_with_fglm_from_ring is None:
+-        from_ring=convert_with_fglm_from_ring
++        from_ring = convert_with_fglm_from_ring
+         to_ring = convert_with_fglm_to_ring
+         return _fglm(I, from_ring, to_ring)
+ 
+     if interpolation_gb:
+         first = iter(I).next()
+-        if len(I)!=1 or first.ring().get_order_code()!=OrderCode.lp:
++        if len(I) != 1 or first.ring().get_order_code() != OrderCode.lp:
+             raise ValueError
+         return lex_groebner_basis_for_polynomial_via_variety(first)
+     if deg_bound is False:
+-        deg_bound=100000000L
+-    I=[Polynomial(p) for p in I if not p.is_zero()]
++        deg_bound = 100000000L
++    I = [Polynomial(p) for p in I if not p.is_zero()]
+     if unique_ideal_generator and I:
+-        prod=1
++        prod = 1
+         for p in I:
+-            prod=(p+1)*prod
+-        I=[prod + 1]
++            prod = (p + 1) * prod
++        I = [prod + 1]
+ 
+-    if implementation=="Python":
+-        implementation=symmGB_F2_python
++    if implementation == "Python":
++        implementation = symmGB_F2_python
+     else:
+-        implementation=symmGB_F2_C
++        implementation = symmGB_F2_C
+ 
+     # custom preprocessing
+     if preprocessor:
+         I = preprocessor(I)
+-        
++
+     if preprocess_only:
+-      for p in I:
+-        print p
+-      import sys
+-      sys.exit(0)
++        for p in I:
++            print p
++        import sys
++        sys.exit(0)
+ 
+-    def call_algorithm(I,max_generators=None):
++    def call_algorithm(I, max_generators=None):
+         return implementation(I,
+-            deg_bound = deg_bound,
+-            full_prot = False,
+-            prot = False,
+-            max_generators=max_generators, draw_matrices = draw_matrices,
++            deg_bound=deg_bound,
++            full_prot=False,
++            prot=False,
++            max_generators=max_generators, draw_matrices=draw_matrices,
+             **filter_newstyle_options(implementation, **impl_options))
+-    
++
+     if clean_and_restart_algorithm:
+-        for max_generators in [1000,10000,50000,100000,200000,300000,400000,None]:
++        for max_generators in [1000, 10000, 50000, 100000, 200000, 300000,
++            400000, None]:
+             try:
+                 return call_algorithm(I, max_generators=max_generators)
+             except GeneratorLimitExceeded, e:
+-                I=list(e.strat.all_generators())
++                I = list(e.strat.all_generators())
+                 del e.strat
+                 if prot:
+-                    print "generator limit exceeded:", max_generators, "restarting algorithm"
++                    print("generator limit exceeded:", max_generators,
++                        "restarting algorithm")
+     else:
+         return call_algorithm(I)
+ 
+ 
+ def build_groebner_basis_doc_string():
+-    additional_options_from_buchberger = \
+-                             filter_oldstyle_options(**get_options_from_function(symmGB_F2_python))
++    additional_options_from_buchberger = filter_oldstyle_options(**
++        get_options_from_function(symmGB_F2_python))
+     for k in list(additional_options_from_buchberger):
+         if k in groebner_basis.options:
+             del additional_options_from_buchberger[k]
+ 
+-    groebner_basis.__doc__=groebner_basis.__doc__+"\nOptions are:\n"+"\n".join(
+-        (k+"  :  "+repr(groebner_basis.options[k]) for k in groebner_basis.options)) + \
+-"""
++    groebner_basis.__doc__ = (groebner_basis.__doc__ + "\nOptions are:\n" +
++        "\n".join((k + "  :  " + repr(groebner_basis.options[k]) for k in
++        groebner_basis.options)) + """
+ 
+ Turn off heuristic by setting heuristic=False
+   Additional options come from the actual buchberger implementation.
+   In case of our standard Python implementation these are the following:
+ 
+-""" + "\n".join(
+-    (k+"  :  "+repr(additional_options_from_buchberger[k]) for k in additional_options_from_buchberger))
++"""
++        + "\n".join((k + "  :  " + repr(additional_options_from_buchberger[k])
++        for k in additional_options_from_buchberger)))
+ 
+ build_groebner_basis_doc_string()
+ 
++
+ def _test():
+     import doctest
+     doctest.testmod()
+diff --git a/pyroot/polybori/gbrefs.py b/pyroot/polybori/gbrefs.py
+index 4477e9e..2375a02 100644
+--- a/pyroot/polybori/gbrefs.py
++++ b/pyroot/polybori/gbrefs.py
+@@ -5,64 +5,76 @@ import uu
+ import re
+ import imp
+ from polybori.PyPolyBoRi import *
+-AUTO="auto"
+-SINGLE="single"
++AUTO = "auto"
++SINGLE = "single"
++
++
+ #def ref_file_name(f):
+ #    name=re.sub("data/","",f)
+ #    name=sub(r"\.py","",name)
+ #    l=name.split("/")[:-1]
+ def reencode_blocks(block_str):
+-    return str(block_str).replace(",","_")
+-def parse_blocks(block_str,data):
+-    if block_str==AUTO:
++    return str(block_str).replace(",", "_")
++
++
++def parse_blocks(block_str, data):
++    if block_str == AUTO:
+         #print "block starts:",data.block_start_hints
+         return data.block_start_hints
+-    if block_str==SINGLE:
++    if block_str == SINGLE:
+         return []
+     return [int(i) for i in block_str.split(",")]
++
++
+ def load_ref_raw(s):
+-     s=sub("data/","",s)
+-     s=sub(r"data\.","",s)
+-     s=sub(r"\.py","",s)
+-     s=sub(r"\.","/",s)
+-     
+-     ref_file="ref/"+s+".ref"
++    s = sub("data/", "", s)
++    s = sub(r"data\.", "", s)
++    s = sub(r"\.py", "", s)
++    s = sub(r"\.", "/", s)
++
++    ref_file = "ref/" + s + ".ref"
+      #print "loading:", ref_file
+-     res_f=open(ref_file)
+-     res=res_f.read()
+-     res_f.close()
+-     return res
+- 
+-def load_ref(s,ordering="lp",blocks=SINGLE):
+-    return load_ref_gz_uu(s, ordering,blocks)
+-
+-def ordering_suffix(o,blocks=None):
+-    if o=="lp":
++    res_f = open(ref_file)
++    res = res_f.read()
++    res_f.close()
++    return res
++
++
++def load_ref(s, ordering="lp", blocks=SINGLE):
++    return load_ref_gz_uu(s, ordering, blocks)
++
++
++def ordering_suffix(o, blocks=None):
++    if o == "lp":
+         return ""
+     else:
+-        if re.match("block",o):
+-            return "."+o+"_"+reencode_blocks(blocks)
++        if re.match("block", o):
++            return "." + o + "_" + reencode_blocks(blocks)
+         else:
+-            return "."+o
++            return "." + o
++
++
+ def number_of_declared_vars(data):
+     try:
+         return data.number_of_declared_vars
+     except:
+         return data.r.ngens()
+-def load_ref_gz_uu(s,o,b):
+-    s=sub("data/","",s)
+-    s=sub(r"data\.","",s)
+-    s=sub(r"\.py","",s)
+-    s=sub(r"\.","/",s)
+-    
+-    ref_file="ref/"+s+ordering_suffix(o,b)+".ref.gz.uu"
++
++
++def load_ref_gz_uu(s, o, b):
++    s = sub("data/", "", s)
++    s = sub(r"data\.", "", s)
++    s = sub(r"\.py", "", s)
++    s = sub(r"\.", "/", s)
++
++    ref_file = "ref/" + s + ordering_suffix(o, b) + ".ref.gz.uu"
+     #print "loading:", ref_file
+-    res=StringIO()
+-    uu.decode(ref_file,res)
+-    res=res.getvalue()
+-    res=StringIO(res)
+-    res=gzip.GzipFile(fileobj=res,mode="r").read()
+-    res=res.replace(" ","")
++    res = StringIO()
++    uu.decode(ref_file, res)
++    res = res.getvalue()
++    res = StringIO(res)
++    res = gzip.GzipFile(fileobj=res, mode="r").read()
++    res = res.replace(" ", "")
+     #res_f=open(ref_file)
+     #res=res_f.read()
+     #res_f.close()
+@@ -71,26 +83,27 @@ def load_ref_gz_uu(s,o,b):
+ 
+ #def load_ref(s):
+ #    return load_ref_raw(s)
+-    
++
+ def convert_refs(ref_file_orig):
+-    content=open(ref_file_orig).read()
++    content = open(ref_file_orig).read()
+     #buf=StringIO(content)
+-    buf_out=StringIO()
++    buf_out = StringIO()
+     #
+-    zipped=gzip.GzipFile(filename=ref_file_orig, mode="w",fileobj=buf_out)
++    zipped = gzip.GzipFile(filename=ref_file_orig, mode="w", fileobj=buf_out)
+     zipped.write(content)
+     zipped.close()
+-    val=buf_out.getvalue()
+-    out=open(ref_file_orig+".gz.uu","w")
++    val = buf_out.getvalue()
++    out = open(ref_file_orig + ".gz.uu", "w")
+     #print val
+-    uu.encode(out_file=out,in_file=StringIO(val))
++    uu.encode(out_file=out, in_file=StringIO(val))
+     out.close()
+-    
++
++
+ def my_import(name, globals=None, locals=None):
+     if globals is None:
+-        globals={}
++        globals = {}
+     if locals is None:
+-        locals={}
++        locals = {}
+     #print name
+     #print locals, globals
+     mod = __import__(name)
+@@ -99,9 +112,11 @@ def my_import(name, globals=None, locals=None):
+     for comp in components[1:]:
+         mod = getattr(mod, comp)
+     return mod
++
++
+ def dyn_generate(content, name):
+-    module=imp.new_module(name)
+-    import_header="""from polybori.PyPolyBoRi import Variable,Monomial, Polynomial, Ring, OrderCode
++    module = imp.new_module(name)
++    import_header = """from polybori.PyPolyBoRi import Variable,Monomial, Polynomial, Ring, OrderCode
+ from itertools import chain
+ from polybori.blocks import AlternatingBlock,Block,AdderBlock,if_then,HigherOrderBlock,declare_ring as orig_declare_ring,declare_block_scheme,MacroBlock\n
+ def declare_ring(blocks, context=None):
+@@ -109,20 +124,23 @@ def declare_ring(blocks, context=None):
+     context=globals()
+   return orig_declare_ring(blocks,context)
+ """
+-    exec import_header+content in module.__dict__
+-    if hasattr(module,"ideal"):
+-        module.ideal=[Polynomial(p) for p in module.ideal]
++    exec import_header + content in module.__dict__
++    if hasattr(module, "ideal"):
++        module.ideal = [Polynomial(p) for p in module.ideal]
+     return module
+ 
++
+ def clean_data(data):
+-    r=data.r
++    r = data.r
+     for a in dir(data):
+-      if a!="r":
+-        delattr(data,a)
++        if a != "r":
++            delattr(data, a)
++
++
+     #del data.r
+     #del r
+ def load_data(file_name, base_dir="./"):
+-    in_file=file_name
++    in_file = file_name
+     #in_file=sub(r"\.py$","",in_file)
+     #in_file=sub(r"/",".", in_file)
+     #if not re.match("^data",in_file):
+@@ -130,23 +148,23 @@ def load_data(file_name, base_dir="./"):
+     #def x(i):
+     #    return Monomial(Variable(i))
+     if not re.match("^data", in_file):
+-      in_file="data/"+in_file
+-    in_file=sub(r".py$","",in_file)
+-    module_name=sub("/",r"\.",in_file)
+-    in_file=sub(r"\.","/",in_file)
+-    in_file=in_file+".py"
++        in_file = "data/" + in_file
++    in_file = sub(r".py$", "", in_file)
++    module_name = sub("/", r"\.", in_file)
++    in_file = sub(r"\.", "/", in_file)
++    in_file = in_file + ".py"
+     #print in_file
+-    in_file=open(base_dir + in_file).read()
+-    
++    in_file = open(base_dir + in_file).read()
++
+     #print in_file
+     #return my_import(in_file)
+     return dyn_generate(in_file, "pb_data")
+ 
++
+ def load_file(file_name):
+ 
+-    in_file=file_name
+-    
++    in_file = file_name
+ 
+-    in_file=open( in_file).read()
++    in_file = open(in_file).read()
+ 
+     return dyn_generate(in_file, "pb_data")
+diff --git a/pyroot/polybori/general_boolean_polynomial.py b/pyroot/polybori/general_boolean_polynomial.py
+index f4c228d..f01520f 100644
+--- a/pyroot/polybori/general_boolean_polynomial.py
++++ b/pyroot/polybori/general_boolean_polynomial.py
+@@ -3,589 +3,613 @@ import sys
+ import resource
+ from polybori.gbcore import *
+ from polybori.memusage import *
+-from time import time,clock
++from time import time, clock
+ from polybori.PyPolyBoRi import *
+-from polybori.blocks import declare_ring,Block
++from polybori.blocks import declare_ring, Block
+ from math import sqrt
+ from polybori.parallel import groebner_basis_first_finished
+ from optparse import OptionParser
+ from polybori.interred import interred
+ 
++
+ # Just for debugging
+ def print_matrix(A):
+-	res = ""
+-	for i in xrange(len(A)):
+-		for j in xrange(len(A[i])):
+-			res += str(A[i][j]) + " "
+-		res+="\n"
+-	return res
+-
+-# TODO:
+-# Implement constructor to convert Polynomials to GeneralBooleanPolynomial (with e_1 + ... + e_k as coefficient)
++    res = ""
++    for i in xrange(len(A)):
++        for j in xrange(len(A[i])):
++            res += str(A[i][j]) + " "
++        res += "\n"
++    return res
++
++
++# TODO: Implement constructor to convert Polynomials to
++# GeneralBooleanPolynomial (with e_1 + ... + e_k as coefficient)
+ class GeneralBooleanPolynomial:
+-	"""
+-	Class to represent Boolean polynomials over F_2^k
+-	"""
+-	def __init__(self, k, coeff, polynomial):
+-		"""
+-		Construct a GeneralBooleanPolynomial given by coeff * polynomial
+-		Arguments:
+-		   k :           Number of factors of F_2
+-		   coeff :       Array containing natural numbers in {0, ..., k-1} representing an element of F_2^k as a set
+-		   polynomial :  Polynomial
+-		"""
+-		#print "type of polynomials", type(polynomial)
+-		#print "polynomials is int?", isinstance(polynomial, int)
+-		assert isinstance(polynomial, Polynomial) or isinstance(polynomial, Monomial) or isinstance(polynomial, Variable) or isinstance(polynomial, int)
+-		self.polys=[]
+-		self.k = k
+-		self.ring = polynomial.ring()
+-		for i in xrange(k):
+-			if i in coeff:
+-				self.polys.append(polynomial)
+-			else:
+-				self.polys.append(Polynomial(0, self.ring))
+-	
+-	def __len__(self):
+-		"""
+-		Returns the number of factors k in the product of the underlying ring F_2^k
+-		"""
+-		return self.k
+-
+-	def __getitem__(self,k):
+-		"""
+-		Return the k-th component (i.e. the projection to the k-th factor) 
+-		"""
+-		return self.polys[k]
+-
+-	def __setitem__(self,k,value):
+-		"""
+-		Sets the k-th component (i.e. the projection to the k-th factor) 
+-		"""
+-		self.polys[k] = value
+-
+-	def __eq__(self,other):
+-		"""
+-		Tests equality by testing that
+-		 - both objects are defined over the same ring (i.e. the number of factors is the same)
+-		 - the objects are equal in each component
+-		"""
+-		if not len(self) == len(other):
+-			return False
+-		for i in xrange(len(self)):
+-			if self[i] != other[i]:
+-				return False
+-		return True
+-	
+-	def __ne__(self,other):
+-		return not self==other
+-
+-	def __str__(self):
+-		"""
+-		Returns a representation of the polynomial as string
+-		"""
+-		res = ""
+-		# Build a list of all terms occurring
+-		terms = set([])
+-		for i in xrange(self.k):
+-			if not isinstance(self.polys[i], Polynomial):
+-				assert isinstance(self.polys[i], Monomial) or isinstance(self.polys[i], Variable) 
+-				self[i] = Polynomial(self[i])
+-			terms = terms.union( set( self[i].terms() ) )
+-		# Sort the terms
+-		terms = list(terms)
+-		terms.sort()
+-		# Determine the coefficient for each term and build up the string
+-		for t in terms:
+-			comps = [ j for j in xrange(self.k) if t in set( Polynomial(self[j]).terms() ) ]
+-			if len(comps) == self.k :
+-				# We use this simplified notation of the coefficient it 1
+-				res += str(t)+" + "
+-			else:
+-				res += str(comps)+" * "+str(t)+" + "
+-		res = res[0:len(res)-3]
+-		if res == "":
+-			return "0"
+-		else:
+-			return res
+-
+-	def __add__(self, other):
+-		"""
+-		Addition of two GeneralBooleanPolynomial
+-		"""
+-		if not len(self)==len(other):
+-			print "Cannot add polynomials defined over different rings"
+-			print "Len(self)=",len(self)
+-			print "Len(other)=",len(other)
+-			assert len(self) == len(other)
+-		sum = GeneralBooleanPolynomial(self.k, [], Polynomial(0, self.ring))
+-		for i in xrange(self.k):
+-			sum[i] = self[i] + other[i]
+-		return sum
+-	
+-	def __mul__(self, other):
+-		"""
+-		Multiplication of two GeneralBooleanPolynomial
+-		"""
+-		if not len(self)==len(other):
+-			print "Cannot multiply polynomials defined over different rings"
+-			print "Len(self)=",len(self)
+-			print "Len(other)=",len(other)
+-			assert len(self) == len(other)
+-		prod = GeneralBooleanPolynomial(self.k, [], Polynomial(0, self.ring))
+-		for i in xrange(self.k):
+-			prod[i] = Polynomial(self[i]) * Polynomial(other[i])
+-		return prod
+-	
+-	def __sub__(self, other):
+-		"""
+-		Subtraction of two GeneralBooleanPolynomial
+-		"""
+-		if not len(self)==len(other):
+-			print "Cannot subtract polynomials defined over different rings"
+-			print "Len(self)=",len(self)
+-			print "Len(other)=",len(other)
+-			assert len(self) == len(other)
+-		sub = GeneralBooleanPolynomial(self.k, [], Polynomial(1,self.ring))
+-		for i in xrange(self.k):
+-			sub[i] = self[i] - other[i]
+-		return sub
+-
+-	def lc(self):
+-		"""
+-		Returns leading coefficient as constant GeneralBooleanPolynomial
+-		"""
+-		return GeneralBooleanPolynomial(self.k, self.lc_as_set(),
+-						Polynomial(1, self.ring) )
+-	
+-	def lc_as_set_array(self):
+-		"""
+-		Returns leading coefficient as array containing the indices of the
+-		non-zero components of the leading coefficient. 
+-		"""
+-		max_term = 1 
+-		for i in xrange(len(self)):
+-			if not self[i].is_zero():
+-				if self[i].lead() > max_term:
+-					max_term = self[i].lead()
+-		comps = [ j for j in xrange(len(self)) if max_term in set(self[j].terms()) ] 
+-		return comps
+-	
+-	def lc_as_set(self):
+-		"""
+-		Returns leading coefficient as set containing the indices of the
+-		non-zero components of the leading coefficient. 
+-		"""
+-		return set(self.lc_as_set_array())
+-
+-	def lc_binary(self):
+-		"""
+-		Returns leading coefficient as array containing the integers 0 or 1
+-		representing the leading coefficient in a binary form.
+-		"""
+-		lc_set = self.lc_as_set()
+-		lc_binary = [0]*len(self)
+-		for i in xrange(len(self)):
+-			if i in lc_set:
+-				lc_binary[i]=1
+-		return lc_binary
+-
+-	def lt(self):
+-		"""
+-		Leading term in form of a GeneralBooleanPolynomial
+-		"""
+-		max_term = 1 
+-		for i in xrange(self.k):
+-			if not self[i].is_zero():
+-				if self[i].lead() > max_term:
+-					max_term = self[i].lead()
+-		comps = [ j for j in xrange(self.k) if max_term in set(self[j].terms()) ] 
+-		return GeneralBooleanPolynomial(self.k, comps, max_term)
+-	
+-	def lm(self):
+-		"""
+-		Leading monomial in form of a GeneralBooleanPolynomial
+-		"""
+-		max_term = 1
+-		contains_non_zero_term = False
+-		for i in xrange(len(self)):
+-			if not self[i].is_zero():
+-				contains_non_zero_term = True
+-				if self[i].lead() > max_term:
+-					max_term = self[i].lead()
+-		if not contains_non_zero_term:
+-			raise ValueError("lm of zero polynomial is not defined")
+-		return GeneralBooleanPolynomial(self.k, [ i for i in xrange(self.k) ], max_term)
+-	
+-
+-	def constant_part_binary(self):
+-		"""
+-		Constant part as binary tuple indicading which coefficients are non-zero
+-		"""
+-		comps = []
+-		for i in xrange(len(self)):
+-			if self[i].has_constant_part():
+-				comps.append(1)
+-			else:
+-				comps.append(0)
+-		return comps
+-	
+-	def constant_part_as_set_array(self):
+-		"""
+-		Constant part as array containing the indices of the non-zero coefficients of the constant part (sorted increasingly)
+-		"""
+-		res = []
+-		for i in xrange(len(self)):
+-			if self[i].has_constant_part():
+-				res.append(i)
+-		return res 
+-	
+-	def constant_part_as_set(self):
+-		"""
+-		Constant part as set containing the indices of the non-zero coefficients of the constant part
+-		"""
+-		return set(self.constant_part_as_set_array())
+-
+-	def constant_part(self):
+-		"""
+-		Constant part as GeneralBoolenPolynomial
+-		"""
+-		res = GeneralBooleanPolynomial(len(self), [], Polynomial(0, self.ring))
+-		for i in xrange(len(self)):
+-			if self[i].has_constant_part():
+-				res[i] = Polynomial(1, self.ring)
+-			else:
+-				res[i] = Polynomial(0, self.ring)
+-		return res 
+-
+-	def to_expanded_polynomial_ring(self, new_variables):
+-		"""
+-		Returns a representation in form of a Polynomial over a ring with
+-		additional variables, one for each factor in the product of fields
+-		F_2^k
+-		"""
+-		assert self.k == len(new_variables)
+-		return sum( new_variables[i] * self.polys[i] for i in xrange(self.k) )
+-
+-	def is_monomial(self):
+-		"""
+-		Test if self is a Monomial  
+-		"""
+-		# Build a list of all terms occurring
+-		terms = set([])
+-		for i in xrange(self.k):
+-			if not isinstance(self.polys[i], Polynomial):
+-				assert isinstance(self.polys[i], Monomial) or isinstance(self.polys[i], Variable) 
+-				self[i] = Polynomial(self[i])
+-			terms = terms.union( set( self[i].terms() ) )
+-		if len(terms)>1:
+-			return False
+-		else:
+-			return True
+-
+-	def is_zero(self):
+-		"""
+-		Tests if self is zero
+-		"""
+-		for i in xrange(len(self)):
+-			if self[i]!=0:
+-				return False
+-		return True
+-	
+-	def monomial(self):
+-		"""
+-		Returns a PolyBoRi Monomial representing the leading monomial of self, where self should be a monomial
+-		"""
+-		assert self.is_monomial()
+-		for i in xrange(self.k):
+-			if self.polys[i] != Polynomial(0, self.ring):
+-				return self.polys[i].lead()
+-		return Polynomial(0, self.ring)
+-
+-	def divides(self, other):
+-		"""
+-		Tests if self divides other 
+-		"""
+-		assert len(self)==len(other)
+-		assert (self.is_monomial() and other.is_monomial())
+-		self_divides_other = True
+-		for i in xrange(len(self)):
+-			if self[i] == 0:
+-				if other[i]!=0:
+-					return False
+-				else:
+-					continue
+-			if self[i] == 1:
+-				continue
+-			else:
+-				if other[i] == 1:
+-					return False
+-
+-			if other[i] == 0:
+-				continue
+-
+-			assert other[i] == other[i].lead()
+-			other[i] = other[i].lead()
+-			if not other[i] in (Polynomial(self.polys[i]).lead()).divisors() :
+-				return False
+-		return True
++    """
++    Class to represent Boolean polynomials over F_2^k
++    """
++
++    def __init__(self, k, coeff, polynomial):
++        """
++        Construct a GeneralBooleanPolynomial given by coeff * polynomial
++        Arguments:
++           k :           Number of factors of F_2
++           coeff :       Array containing natural numbers in {0, ..., k-1} representing an element of F_2^k as a set
++           polynomial :  Polynomial
++        """
++        #print "type of polynomials", type(polynomial)
++        #print "polynomials is int?", isinstance(polynomial, int)
++        assert isinstance(polynomial, Polynomial) or isinstance(polynomial,
++            Monomial) or isinstance(polynomial, Variable) or isinstance(
++            polynomial, int)
++        self.polys = []
++        self.k = k
++        self.ring = polynomial.ring()
++        for i in xrange(k):
++            if i in coeff:
++                self.polys.append(polynomial)
++            else:
++                self.polys.append(Polynomial(0, self.ring))
++
++    def __len__(self):
++        """
++        Returns the number of factors k in the product of the underlying ring F_2^k
++        """
++        return self.k
++
++    def __getitem__(self, k):
++        """
++        Return the k-th component (i.e. the projection to the k-th factor)
++        """
++        return self.polys[k]
++
++    def __setitem__(self, k, value):
++        """
++        Sets the k-th component (i.e. the projection to the k-th factor)
++        """
++        self.polys[k] = value
++
++    def __eq__(self, other):
++        """
++        Tests equality by testing that
++         - both objects are defined over the same ring (i.e. the number of factors is the same)
++         - the objects are equal in each component
++        """
++        if not len(self) == len(other):
++            return False
++        for i in xrange(len(self)):
++            if self[i] != other[i]:
++                return False
++        return True
++
++    def __ne__(self, other):
++        return not self == other
++
++    def __str__(self):
++        """
++        Returns a representation of the polynomial as string
++        """
++        res = ""
++        # Build a list of all terms occurring
++        terms = set([])
++        for i in xrange(self.k):
++            if not isinstance(self.polys[i], Polynomial):
++                assert isinstance(self.polys[i], Monomial) or isinstance(self.
++                    polys[i], Variable)
++                self[i] = Polynomial(self[i])
++            terms = terms.union(set(self[i].terms()))
++        # Sort the terms
++        terms = list(terms)
++        terms.sort()
++        # Determine the coefficient for each term and build up the string
++        for t in terms:
++            comps = [j for j in xrange(self.k) if t in set(Polynomial(self[j])
++                .terms())]
++            if len(comps) == self.k:
++                # We use this simplified notation of the coefficient it 1
++                res += str(t) + " + "
++            else:
++                res += str(comps) + " * " + str(t) + " + "
++        res = res[0:len(res) - 3]
++        if res == "":
++            return "0"
++        else:
++            return res
++
++    def __add__(self, other):
++        """
++        Addition of two GeneralBooleanPolynomial
++        """
++        if not len(self) == len(other):
++            print "Cannot add polynomials defined over different rings"
++            print "Len(self)=", len(self)
++            print "Len(other)=", len(other)
++            assert len(self) == len(other)
++        sum = GeneralBooleanPolynomial(self.k, [], Polynomial(0, self.ring))
++        for i in xrange(self.k):
++            sum[i] = self[i] + other[i]
++        return sum
++
++    def __mul__(self, other):
++        """
++        Multiplication of two GeneralBooleanPolynomial
++        """
++        if not len(self) == len(other):
++            print "Cannot multiply polynomials defined over different rings"
++            print "Len(self)=", len(self)
++            print "Len(other)=", len(other)
++            assert len(self) == len(other)
++        prod = GeneralBooleanPolynomial(self.k, [], Polynomial(0, self.ring))
++        for i in xrange(self.k):
++            prod[i] = Polynomial(self[i]) * Polynomial(other[i])
++        return prod
++
++    def __sub__(self, other):
++        """
++        Subtraction of two GeneralBooleanPolynomial
++        """
++        if not len(self) == len(other):
++            print "Cannot subtract polynomials defined over different rings"
++            print "Len(self)=", len(self)
++            print "Len(other)=", len(other)
++            assert len(self) == len(other)
++        sub = GeneralBooleanPolynomial(self.k, [], Polynomial(1, self.ring))
++        for i in xrange(self.k):
++            sub[i] = self[i] - other[i]
++        return sub
++
++    def lc(self):
++        """
++        Returns leading coefficient as constant GeneralBooleanPolynomial
++        """
++        return GeneralBooleanPolynomial(self.k, self.lc_as_set(),
++                        Polynomial(1, self.ring))
++
++    def lc_as_set_array(self):
++        """
++        Returns leading coefficient as array containing the indices of the
++        non-zero components of the leading coefficient.
++        """
++        max_term = 1
++        for i in xrange(len(self)):
++            if not self[i].is_zero():
++                if self[i].lead() > max_term:
++                    max_term = self[i].lead()
++        comps = [j for j in xrange(len(self)) if max_term
++                 in set(self[j].terms())]
++        return comps
++
++    def lc_as_set(self):
++        """
++        Returns leading coefficient as set containing the indices of the
++        non-zero components of the leading coefficient.
++        """
++        return set(self.lc_as_set_array())
++
++    def lc_binary(self):
++        """
++        Returns leading coefficient as array containing the integers 0 or 1
++        representing the leading coefficient in a binary form.
++        """
++        lc_set = self.lc_as_set()
++        lc_binary = [0] * len(self)
++        for i in xrange(len(self)):
++            if i in lc_set:
++                lc_binary[i] = 1
++        return lc_binary
++
++    def lt(self):
++        """
++        Leading term in form of a GeneralBooleanPolynomial
++        """
++        max_term = 1
++        for i in xrange(self.k):
++            if not self[i].is_zero():
++                if self[i].lead() > max_term:
++                    max_term = self[i].lead()
++        comps = [j for j in xrange(self.k) if max_term in set(self[j].terms())]
++        return GeneralBooleanPolynomial(self.k, comps, max_term)
++
++    def lm(self):
++        """
++        Leading monomial in form of a GeneralBooleanPolynomial
++        """
++        max_term = 1
++        contains_non_zero_term = False
++        for i in xrange(len(self)):
++            if not self[i].is_zero():
++                contains_non_zero_term = True
++                if self[i].lead() > max_term:
++                    max_term = self[i].lead()
++        if not contains_non_zero_term:
++            raise ValueError("lm of zero polynomial is not defined")
++        return GeneralBooleanPolynomial(self.k, [i for i in xrange(self.k)],
++            max_term)
++
++    def constant_part_binary(self):
++        """
++        Constant part as binary tuple indicading which coefficients are non-zero
++        """
++        comps = []
++        for i in xrange(len(self)):
++            if self[i].has_constant_part():
++                comps.append(1)
++            else:
++                comps.append(0)
++        return comps
++
++    def constant_part_as_set_array(self):
++        """
++        Constant part as array containing the indices of the non-zero coefficients of the constant part (sorted increasingly)
++        """
++        res = []
++        for i in xrange(len(self)):
++            if self[i].has_constant_part():
++                res.append(i)
++        return res
++
++    def constant_part_as_set(self):
++        """
++        Constant part as set containing the indices of the non-zero coefficients of the constant part
++        """
++        return set(self.constant_part_as_set_array())
++
++    def constant_part(self):
++        """
++        Constant part as GeneralBoolenPolynomial
++        """
++        res = GeneralBooleanPolynomial(len(self), [], Polynomial(0, self.ring))
++        for i in xrange(len(self)):
++            if self[i].has_constant_part():
++                res[i] = Polynomial(1, self.ring)
++            else:
++                res[i] = Polynomial(0, self.ring)
++        return res
++
++    def to_expanded_polynomial_ring(self, new_variables):
++        """
++        Returns a representation in form of a Polynomial over a ring with
++        additional variables, one for each factor in the product of fields
++        F_2^k
++        """
++        assert self.k == len(new_variables)
++        return sum(new_variables[i] * self.polys[i] for i in xrange(self.k))
++
++    def is_monomial(self):
++        """
++        Test if self is a Monomial
++        """
++        # Build a list of all terms occurring
++        terms = set([])
++        for i in xrange(self.k):
++            if not isinstance(self.polys[i], Polynomial):
++                assert isinstance(self.polys[i], Monomial) or isinstance(self.
++                    polys[i], Variable)
++                self[i] = Polynomial(self[i])
++            terms = terms.union(set(self[i].terms()))
++        if len(terms) > 1:
++            return False
++        else:
++            return True
++
++    def is_zero(self):
++        """
++        Tests if self is zero
++        """
++        for i in xrange(len(self)):
++            if self[i] != 0:
++                return False
++        return True
++
++    def monomial(self):
++        """
++        Returns a PolyBoRi Monomial representing the leading monomial of self, where self should be a monomial
++        """
++        assert self.is_monomial()
++        for i in xrange(self.k):
++            if self.polys[i] != Polynomial(0, self.ring):
++                return self.polys[i].lead()
++        return Polynomial(0, self.ring)
++
++    def divides(self, other):
++        """
++        Tests if self divides other
++        """
++        assert len(self) == len(other)
++        assert (self.is_monomial() and other.is_monomial())
++        self_divides_other = True
++        for i in xrange(len(self)):
++            if self[i] == 0:
++                if other[i] != 0:
++                    return False
++                else:
++                    continue
++            if self[i] == 1:
++                continue
++            else:
++                if other[i] == 1:
++                    return False
++
++            if other[i] == 0:
++                continue
++
++            assert other[i] == other[i].lead()
++            other[i] = other[i].lead()
++            if not other[i] in (Polynomial(self.polys[i]).lead()).divisors():
++                return False
++        return True
++
+ 
+ # Simple Gaus algorithm
+ # Should really be replaced by something faster (maybe from PolyBoRi)
+-def triangulate_over_F2(A,b):
+-        assert len(A) == len(b)
+-        n = len(b)
+-	m = len(A[0])
+-	print "n: ",n, "m: ",m
+-        print "A, b", A, b
+-        for i in xrange(0,min(n,m)):	# Row
+-		print "i",i
+-		if A[i][i]==0:
+-			# permutate rows
+-			changed = False
+-			for l in range(i,n):
+-				if A[l][i]!=0:
+-					for k in xrange(n):
+-						A[l][k], A[i][k] = A[i][k], A[l][k]
+-					b[l],b[i] = b[i],b[l]
+-				changed = True
+-			if not changed: return -1
+-                for j in xrange(0,i):
+-                        if A[i][j]!=0:
+-                                for k in xrange(j,n):
+-                                        A[i][k] += A[i-1][k]
+-				b[i] += b[i-1]
+-	res_A = [ [ A[i][j]%2 for j in xrange(m) ] for i in xrange(n) ]
+-	res_b = [ b[i]%2 for i in xrange(n) ] 
+-	return (res_A,res_b)
+-
+-	
+-def projection_of_expanded_polynomial(f,e,e_vars):
+-	"""
+-	Compute the projection of the expanded polynomial f to the component
+-	corresponding to the variable e (which is part of e_vars)
+-	"""
+-	for v in e_vars:
+-		if v==e:
+-			# Substitute v by 1
+-			f = Polynomial(f.set().subset0(v.index())) + Polynomial(f.set().subset1(v.index()) )
+-		else:
+-			# Substitute v by 0
+-			f = Polynomial(f.set().subset0(v.index()))
+-	return f
+-			
+-def expanded_polynomial2general_polynomial(polynomial, new_variables, ring ):
+-	"""
+-	Returns a GeneralBooleanPolynomial associated to a Polynomial (polynomial) in
+-	additional variables (new_variables), where the
+-	GeneralBooleanPolynomial in obtained from the projections of polynomial
+-	to the factors of F_2^k (by specialization of the additional variables)
+-	"""
+-	comps = [ projection_of_expanded_polynomial(polynomial, e, new_variables) for e in new_variables ]
+-	sum2 = GeneralBooleanPolynomial(len(new_variables),[0]*len(new_variables) ,Polynomial(0, ring))
+-	for i in xrange(len(new_variables)):
+-		sum2[i] = comps[i]
+-	return sum2
++def triangulate_over_F2(A, b):
++    assert len(A) == len(b)
++    n = len(b)
++    m = len(A[0])
++    print "n: ", n, "m: ", m
++    print "A, b", A, b
++    for i in xrange(0, min(n, m)):    # Row
++        print "i", i
++        if A[i][i] == 0:
++            # permutate rows
++            changed = False
++            for l in range(i, n):
++                if A[l][i] != 0:
++                    for k in xrange(n):
++                        A[l][k], A[i][k] = A[i][k], A[l][k]
++                    b[l], b[i] = b[i], b[l]
++                changed = True
++            if not changed:
++                return -1
++        for j in xrange(0, i):
++            if A[i][j] != 0:
++                for k in xrange(j, n):
++                    A[i][k] += A[i - 1][k]
++                b[i] += b[i - 1]
++    res_A = [[A[i][j] % 2 for j in xrange(m)] for i in xrange(n)]
++    res_b = [b[i] % 2 for i in xrange(n)]
++    return (res_A, res_b)
++
++
++def projection_of_expanded_polynomial(f, e, e_vars):
++    """
++    Compute the projection of the expanded polynomial f to the component
++    corresponding to the variable e (which is part of e_vars)
++    """
++    for v in e_vars:
++        if v == e:
++            # Substitute v by 1
++            f = Polynomial(f.set().subset0(v.index())) + Polynomial(f.set().
++                subset1(v.index()))
++        else:
++            # Substitute v by 0
++            f = Polynomial(f.set().subset0(v.index()))
++    return f
++
++
++def expanded_polynomial2general_polynomial(polynomial, new_variables, ring):
++    """
++    Returns a GeneralBooleanPolynomial associated to a Polynomial (polynomial) in
++    additional variables (new_variables), where the
++    GeneralBooleanPolynomial in obtained from the projections of polynomial
++    to the factors of F_2^k (by specialization of the additional variables)
++    """
++    comps = [projection_of_expanded_polynomial(polynomial, e, new_variables)
++        for e in new_variables]
++    sum2 = GeneralBooleanPolynomial(len(new_variables), [0] * len(
++        new_variables), Polynomial(0, ring))
++    for i in xrange(len(new_variables)):
++        sum2[i] = comps[i]
++    return sum2
++
+ 
+ def reduce_general_boolean_polynomial(F, polynomial):
+-	"""
+-	Computes the reduction of polynomial via the ideal given by F
+-	"""
+-	r = polynomial
+-	s = len(F)
+-	k = len(polynomial)
+-	h = [GeneralBooleanPolynomial( len(polynomial), [0]*len(polynomial), Polynomial(0, self.ring) )]*s
+-	
+-	# Indices i where leading monomial of F[i] divided leading monomial of r
+-
+-	def calc_Is():
+-		ret = []
+-		for i in xrange(s):
+-			if (F[i].is_zero() and not r.is_zero()):
+-				continue
+-			if (F[i].lm()).divides( r.lm() ):
+-				ret.append( i )
+-		return ret
+-	def calc_X():
+-		ret = []
+-		for i in xrange(len(Is)):
+-			ret.append( (r.lm()).monomial() / (F[Is[i]].lm()).monomial() )
+-		return ret
+-	
+-	def included(i, set):
+-		if i in set:
+-			return 1
+-		else:
+-			return 0
+-	
+-	Is = calc_Is()
+-	X  = calc_X()
+-
+-	for f in F:
+-		assert len(f)==len(polynomial)
+-
+-	lm_polynomial = (polynomial.lm()).monomial()
+-	lc_polynomial_binary = polynomial.lc_binary() 
+-
+-	while len(Is) is not 0:
+-		exp = [ F[i].lm() for i in xrange(s) ]
+-		matrix = [ [ included(i, F[j].lc_as_set()) for j in Is] for i in xrange(k) ]
+-
+-		# Compute solution
+-		coeff = [ [0]*len(Is) for j in xrange(k) ]
+-		for j in xrange(k):
+-			if lc_polynomial_binary[j]:
+-				coeff[j][0] = 1
+-
+-		sum = GeneralBooleanPolynomial(k, [0]*k, Polynomial(0, self.ring))
+-		for i in xrange(len(Is)):
+-			c = [coeff[l][i] for l in xrange(k)]
+-			c_set = [l for l in xrange(k) if coeff[l][i]==1 ] 
+-			poly1 = GeneralBooleanPolynomial(k, c_set, X[i])
+-
+-			sum += GeneralBooleanPolynomial(k, c_set, X[i]) * F[Is[i]].lt()
+-
+-		if polynomial.lt() == sum:
+-			r -= sum
+-		else:
+-			break
+-
+-		if r.is_zero():
+-			return r
+-	
+-		Is = calc_Is()
+-		X = calc_X()
+-	return r
++    """
++    Computes the reduction of polynomial via the ideal given by F
++    """
++    r = polynomial
++    s = len(F)
++    k = len(polynomial)
++    h = [GeneralBooleanPolynomial(len(polynomial), [0] * len(polynomial),
++        Polynomial(0, self.ring))] * s
++    # Indices i where leading monomial of F[i] divided leading monomial of r
++
++    def calc_Is():
++        ret = []
++        for i in xrange(s):
++            if (F[i].is_zero() and not r.is_zero()):
++                continue
++            if (F[i].lm()).divides(r.lm()):
++                ret.append(i)
++        return ret
++
++    def calc_X():
++        ret = []
++        for i in xrange(len(Is)):
++            ret.append((r.lm()).monomial() / (F[Is[i]].lm()).monomial())
++        return ret
++
++    def included(i, set):
++        if i in set:
++            return 1
++        else:
++            return 0
++
++    Is = calc_Is()
++    X = calc_X()
++
++    for f in F:
++        assert len(f) == len(polynomial)
++
++    lm_polynomial = (polynomial.lm()).monomial()
++    lc_polynomial_binary = polynomial.lc_binary()
++
++    while len(Is) is not 0:
++        exp = [F[i].lm() for i in xrange(s)]
++        matrix = [[included(i, F[j].lc_as_set()) for j in Is] for i in xrange(
++            k)]
++
++        # Compute solution
++        coeff = [[0] * len(Is) for j in xrange(k)]
++        for j in xrange(k):
++            if lc_polynomial_binary[j]:
++                coeff[j][0] = 1
++
++        sum = GeneralBooleanPolynomial(k, [0] * k, Polynomial(0, self.ring))
++        for i in xrange(len(Is)):
++            c = [coeff[l][i] for l in xrange(k)]
++            c_set = [l for l in xrange(k) if coeff[l][i] == 1]
++            poly1 = GeneralBooleanPolynomial(k, c_set, X[i])
++
++            sum += GeneralBooleanPolynomial(k, c_set, X[i]) * F[Is[i]].lt()
++
++        if polynomial.lt() == sum:
++            r -= sum
++        else:
++            break
++
++        if r.is_zero():
++            return r
++
++        Is = calc_Is()
++        X = calc_X()
++    return r
+ 
+ 
+ def stratified(I):
+-	"""
+-	Tests if I does no contain two polynomials with the same leading monomials
+-	"""
+-	leading_monomials = []
+-	for p in I:
+-		if p.is_zero():
+-			continue
+-		lm = p.lm()
+-		if lm in leading_monomials:
+-			return False
+-		leading_monomials.append(lm)
+-	return True
+-
+-def build_dict_from_array_of_extended_polynomials(A,e_vars):
+-	new_dict = {}
+-	for p in A:
+-		new_dict[p] = expanded_polynomial2general_polynomial(p, e_vars)
+-	return new_dict
++    """
++    Tests if I does no contain two polynomials with the same leading monomials
++    """
++    leading_monomials = []
++    for p in I:
++        if p.is_zero():
++            continue
++        lm = p.lm()
++        if lm in leading_monomials:
++            return False
++        leading_monomials.append(lm)
++    return True
++
++
++def build_dict_from_array_of_extended_polynomials(A, e_vars):
++    new_dict = {}
++    for p in A:
++        new_dict[p] = expanded_polynomial2general_polynomial(p, e_vars)
++    return new_dict
++
+ 
+ def stratify_dict_I_gb_I(dict, e_vars, debug=0):
+-	"""
+-	Wrapper (calls either stratify_dict_I_gb_I_our_alg or stratify_dict_I_gb_I_Inoue
+-	"""
+-	#return stratify_dict_I_gb_I_Inoue(dict, e_vars, debug)
+-	return stratify_dict_I_gb_I_our_alg(dict, e_vars, debug)
++    """
++    Wrapper (calls either stratify_dict_I_gb_I_our_alg or stratify_dict_I_gb_I_Inoue
++    """
++    #return stratify_dict_I_gb_I_Inoue(dict, e_vars, debug)
++    return stratify_dict_I_gb_I_our_alg(dict, e_vars, debug)
++
+ 
+ def stratify_dict_I_gb_I_our_alg(dict, e_vars, debug=0):
+-	"""
+-	Build a stratified Groebner bases for dict
+-	"""
+-	# Ideal for the polynomials of the new basis
+-	A = []
+-	# and their leading monomials
+-	LMs = []
+-	new_dict = {}
+-
+-
+-	while len(dict)>0:
+-		# We copy the keys of dict into I in order to sort them.
+-		# This way the elements are traversed in a unique order.
+-		I = dict.keys()
+-		I.sort()
+-		p = I[0]
+-
+-		p_gb = dict[p]
+-
+-		del dict[p]
+-	
+-		if debug>1:
+-			print "Processing p",p
+-			print "A before proceeding", A
+-
+-		if p_gb.is_zero():
+-			LMs.append(Polynomial(0, self.ring))
+-			A.append(p)
+-			if debug>1:
+-				print "Adding p that becomes zero"
+-			continue
+-		
+-		p_gb_lm = p_gb.lm()
+-
+-		# If the leading monomial of p does not coincide with any of polynomials already in A, then add p to A
+-		if not p_gb_lm in LMs:
+-			A.append(p)
+-			LMs.append(p_gb_lm)
+-			if debug>1:
+-				print "Appending", p, "since its lm is not contained in A yet"
+-			continue
+-
+-		# Index of p_gb_lm in LMs
+-		i = LMs.index(p_gb_lm)
+-
+-		# Polynomial in A with the same lm as p
+-		b = A[i]
+-
+-		# The Polynomial we want to add to A while keeping A stratified
+-		r = p
+-
+-		b_gb = expanded_polynomial2general_polynomial(b,e_vars)
+-		r_gb = expanded_polynomial2general_polynomial(r,e_vars)
+-
+-		# Leading coefficients as GeneralBooleanPolynomial
+-		lc_b_gb = b_gb.lc()
+-		lc_r_gb = r_gb.lc()
+-		unit = GeneralBooleanPolynomial( len(e_vars) , [o for o in xrange( len(e_vars) )], Polynomial(1,p.ring()))
+-
+-		b1_gb = b_gb*(unit+lc_r_gb) + r_gb
+-		r2_gb = r_gb*(unit+lc_r_gb+lc_r_gb*lc_b_gb) + lc_r_gb * b_gb
+-
+-		b1 = b1_gb.to_expanded_polynomial_ring(e_vars)
+-		r2 = r2_gb.to_expanded_polynomial_ring(e_vars)
+-		
+-		A[i] = b1
+-		if debug>1:
+-			print "New polynomial in A (replaced)", A[i]
+-
+-		if r2!=0 and r2 not in A:
+-			dict[r2] = r2_gb
+-
+-	return build_dict_from_array_of_extended_polynomials(A,e_vars)
++    """
++    Build a stratified Groebner bases for dict
++    """
++    # Ideal for the polynomials of the new basis
++    A = []
++    # and their leading monomials
++    LMs = []
++    new_dict = {}
++
++
++    while len(dict) > 0:
++        # We copy the keys of dict into I in order to sort them.
++        # This way the elements are traversed in a unique order.
++        I = dict.keys()
++        I.sort()
++        p = I[0]
++
++        p_gb = dict[p]
++
++        del dict[p]
++
++        if debug > 1:
++            print "Processing p", p
++            print "A before proceeding", A
++
++        if p_gb.is_zero():
++            LMs.append(Polynomial(0, self.ring))
++            A.append(p)
++            if debug > 1:
++                print "Adding p that becomes zero"
++            continue
++
++        p_gb_lm = p_gb.lm()
++
++        # If the leading monomial of p does not coincide with any of
++        # polynomials already in A, then add p to A
++        if not p_gb_lm in LMs:
++            A.append(p)
++            LMs.append(p_gb_lm)
++            if debug > 1:
++                print "Appending", p, "since its lm is not contained in A yet"
++            continue
++
++        # Index of p_gb_lm in LMs
++        i = LMs.index(p_gb_lm)
++
++        # Polynomial in A with the same lm as p
++        b = A[i]
++
++        # The Polynomial we want to add to A while keeping A stratified
++        r = p
++
++        b_gb = expanded_polynomial2general_polynomial(b, e_vars)
++        r_gb = expanded_polynomial2general_polynomial(r, e_vars)
++
++        # Leading coefficients as GeneralBooleanPolynomial
++        lc_b_gb = b_gb.lc()
++        lc_r_gb = r_gb.lc()
++        unit = GeneralBooleanPolynomial(len(e_vars), [o for o in xrange(len(
++            e_vars))], Polynomial(1, p.ring()))
++
++        b1_gb = b_gb * (unit + lc_r_gb) + r_gb
++        r2_gb = r_gb * (unit + lc_r_gb + lc_r_gb * lc_b_gb) + lc_r_gb * b_gb
++
++        b1 = b1_gb.to_expanded_polynomial_ring(e_vars)
++        r2 = r2_gb.to_expanded_polynomial_ring(e_vars)
++
++        A[i] = b1
++        if debug > 1:
++            print "New polynomial in A (replaced)", A[i]
++
++        if r2 != 0 and r2 not in A:
++            dict[r2] = r2_gb
++
++    return build_dict_from_array_of_extended_polynomials(A, e_vars)
++
+ 
+ def stratify_dict_I_gb_I_Inoue(dict, e_vars, debug=0):
+-	"""
+-	Reimplementation of a simple algorithm of Inoue from BGSet
+-	"""
+-	# Ideal for the polynomials of the new basis
+-	A = []
+-	new_dict = {}
+-	while len(dict)>0:
+-		p = dict.keys()[0]
+-		p_gb = dict[p]
+-		del dict[p]
+-		
+-		if p_gb.is_zero():
+-			A.append(p)
+-			continue
+-
+-		p_gb_lm = p_gb.lm()
+-
+-		for f in dict.keys():
+-			f_gb = dict[f]
+-
+-			if f_gb.is_zero():
+-				continue
+-
+-			if p_gb_lm == f_gb.lm():
+-				p = p + f
+-				del dict[f]
+-		A.append(p)
+-	return build_dict_from_array_of_extended_polynomials(A,e_vars)
++    """
++    Reimplementation of a simple algorithm of Inoue from BGSet
++    """
++    # Ideal for the polynomials of the new basis
++    A = []
++    new_dict = {}
++    while len(dict) > 0:
++        p = dict.keys()[0]
++        p_gb = dict[p]
++        del dict[p]
++
++        if p_gb.is_zero():
++            A.append(p)
++            continue
++
++        p_gb_lm = p_gb.lm()
++
++        for f in dict.keys():
++            f_gb = dict[f]
++
++            if f_gb.is_zero():
++                continue
++
++            if p_gb_lm == f_gb.lm():
++                p = p + f
++                del dict[f]
++        A.append(p)
++    return build_dict_from_array_of_extended_polynomials(A, e_vars)
+diff --git a/pyroot/polybori/heuristics.py b/pyroot/polybori/heuristics.py
+index b0818fc..57ecd4f 100644
+--- a/pyroot/polybori/heuristics.py
++++ b/pyroot/polybori/heuristics.py
+@@ -1,34 +1,36 @@
+ from polybori.PyPolyBoRi import Polynomial, gauss_on_polys
+ from polybori.nf import symmGB_F2_python
+ from polybori.interpolate import variety_lex_leading_terms, nf_lex_points
++
++
+ def dense_system(I):
+-    I=(Polynomial(p) for p in I)
+-    I=(p for p in I if not p.is_zero())
++    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:
++        d = p.deg()
++        if p.deg() == 1:
+             continue
+         else:
+             try:
+-                if len(p)>2**d+5:
++                if len(p) > 2 ** d + 5:
+                     return True
+             except OverflowError:
+                 return True
+     return False
+ 
++
+ def gauss_on_linear(I):
+-    I=(Polynomial(p) for p in I)
+-    linear=[]
+-    non_linear=[]
++    I = (Polynomial(p) for p in I)
++    linear = []
++    non_linear = []
+     for p in I:
+         if p.is_zero():
+             continue
+-        if p.deg()<=1:
++        if p.deg() <= 1:
+             linear.append(p)
+         else:
+             non_linear.append(p)
+-    if len(linear)==0:
++    if len(linear) == 0:
+         return non_linear
+-    linear=list(gauss_on_polys(linear))
+-    return linear+non_linear
+-
++    linear = list(gauss_on_polys(linear))
++    return linear + non_linear
+diff --git a/pyroot/polybori/interpolate.py b/pyroot/polybori/interpolate.py
+index aa40aa7..4289561 100644
+--- a/pyroot/polybori/interpolate.py
++++ b/pyroot/polybori/interpolate.py
+@@ -5,109 +5,122 @@ from polybori.randompoly import gen_random_poly
+ from random import Random
+ from time import clock
+ 
++generator = Random()
+ 
+-generator=Random()
+ 
+ def add_up_poly_list(l, init):
+-    v=BoolePolynomialVector()
++    v = BoolePolynomialVector()
+     for p in l:
+         v.append(p)
+     return add_up_polynomials(v, init)
+-def bench_interpolate(degree,nvariables,points):
+-    
+-    d=degree
+-    v=nvariables
+-    c=points
+-    h=len(points)/2
++
++
++def bench_interpolate(degree, nvariables, points):
++
++    d = degree
++    v = nvariables
++    c = points
++    h = len(points) / 2
+     terms = set(c.terms())
+-    part1=generator.sample(terms,h)
+-    part1=add_up_poly_list(part1, Polynomial(c.ring().zero()))
+-    part2=c+part1
+-    p=part1
+-    q=part2
++    part1 = generator.sample(terms, h)
++    part1 = add_up_poly_list(part1, Polynomial(c.ring().zero()))
++    part2 = c + part1
++    p = part1
++    q = part2
+     assert part1.set().intersect(part2).empty()
+-    c1=clock()
+-    res2=interpolate_smallest_lex(p,q)
+-    c2=clock()
+-    print "finished interpolate_smallest_lex(p,q),len:",len(res2),"time",c2-c1
+-    c1=clock()
+-    res1=interpolate(p,q)
+-    c2=clock()
+-    print "finished interpolate(p,q)"+len("_smallest_lex")*" "+",len:",res1.set().size_double(),"time:",c2-c1
++    c1 = clock()
++    res2 = interpolate_smallest_lex(p, q)
++    c2 = clock()
++    print("finished interpolate_smallest_lex(p,q),len:", len(res2), "time", c2
++        - c1)
++    c1 = clock()
++    res1 = interpolate(p, q)
++    c2 = clock()
++    print("finished interpolate(p,q)" + len("_smallest_lex") * " " + ",len:",
++        res1.set().size_double(), "time:", c2 - c1)
+     return res2
+ 
+ 
++def nf_lex_points(f, p):
++    f = Polynomial(f)
++    p = BooleSet(p)
++    z = f.zeros_in(p)
++    return interpolate_smallest_lex(z, p.diff(z))
+ 
+-def nf_lex_points(f,p):
+-    f=Polynomial(f)
+-    p=BooleSet(p)
+-    z=f.zeros_in(p)
+-    return interpolate_smallest_lex(z,p.diff(z))
+ 
+ def gen_random_monomial():
+-    d=generator.randrange(min(6,v+1))
+-    variables=generator.sample(xrange(v),d)
+-    variables=sorted(variables,key=top_index,reverse=True)
+-    m=variables[0]
++    d = generator.randrange(min(6, v + 1))
++    variables = generator.sample(xrange(v), d)
++    variables = sorted(variables, key=top_index, reverse=True)
++    m = variables[0]
+     for x in variables[1:]:
+-        m=x*m
++        m = x * m
+     return m
++
++
+ def gen_random_polynomial(ring, max_len=50):
+-    vec=BoolePolynomialVector()
++    vec = BoolePolynomialVector()
+     for i in xrange(max_len):
+         vec.append(gen_random_monomial(ring))
+     return add_up_polynomials(vec, Polynomial(ring.zero()))
+ 
+ 
+-def gen_random_o_z(points,points_p):
+-    k=generator.randrange(len(points)+1)
+-    ones=generator.sample(points,k)
+-    vec=BoolePolynomialVector()
++def gen_random_o_z(points, points_p):
++    k = generator.randrange(len(points) + 1)
++    ones = generator.sample(points, k)
++    vec = BoolePolynomialVector()
+     for p in ones:
+         vec.append(p)
+-    ones=add_up_polynomials(vec, Polynomial(points_p.ring().zero()))
+-    return interpolate_smallest_lex(points_p.set().diff(ones),ones)
++    ones = add_up_polynomials(vec, Polynomial(points_p.ring().zero()))
++    return interpolate_smallest_lex(points_p.set().diff(ones), ones)
+ 
+-def variety_lex_leading_terms(points,variables):
++
++def variety_lex_leading_terms(points, variables):
+     ring = variables.ring()
+-    standards=BooleSet(ring.zero())
++    standards = BooleSet(ring.zero())
+     assert type(points) == BooleSet, "Points needs to be a BooleSet"
+-    points_tuple=tuple(points)
+-    myvars_div=variables.divisors()
+-    myvars_iter=iter(myvars_div)
+-    if points!=myvars_div:
+-        standards=BooleSet(ring.one())
+-    len_standards=len(standards)
+-    standards_old=standards
+-    while len_standards<len(points):
+-        standards=standards.union(gen_random_o_z(points_tuple,points))
+-        
+-        if standards_old!=standards:
+-            standards=BooleSet(standards).include_divisors()
+-            len_standards=len(standards)
+-            standards_old=standards
+-
+-    leading_terms=BooleSet(myvars_div.diff(standards)).minimal_elements()
++    points_tuple = tuple(points)
++    myvars_div = variables.divisors()
++    myvars_iter = iter(myvars_div)
++    if points != myvars_div:
++        standards = BooleSet(ring.one())
++    len_standards = len(standards)
++    standards_old = standards
++    while len_standards < len(points):
++        standards = standards.union(gen_random_o_z(points_tuple, points))
++
++        if standards_old != standards:
++            standards = BooleSet(standards).include_divisors()
++            len_standards = len(standards)
++            standards_old = standards
++
++    leading_terms = BooleSet(myvars_div.diff(standards)).minimal_elements()
+     return leading_terms
+ 
+-def lex_groebner_basis_points(points,variables):
+-    leads=variety_lex_leading_terms(points,variables)
+-    return [nf_lex_points(l,points)+l for l in leads]
++
++def lex_groebner_basis_points(points, variables):
++    leads = variety_lex_leading_terms(points, variables)
++    return [nf_lex_points(l, points) + l for l in leads]
++
+ 
+ def lex_groebner_basis_for_polynomial_via_variety(p):
+-    variables=p.vars_as_monomial()
+-    return lex_groebner_basis_points(p.zeros_in(variables.divisors()),variables)
+-if __name__=='__main__':
+-    nvariables=100
+-    r = declare_ring([Block("x",nvariables)])
+-    for number_of_points in (100,500,1000,2000,3000,4000,5000,10000,20000,50000,100000):
++    variables = p.vars_as_monomial()
++    return lex_groebner_basis_points(p.zeros_in(variables.divisors()),
++        variables)
++if __name__ == '__main__':
++    nvariables = 100
++    r = declare_ring([Block("x", nvariables)])
++    for number_of_points in (100, 500, 1000, 2000, 3000, 4000, 5000, 10000,
++        20000, 50000, 100000):
+         print "----------"
+-        print "number_of_points:",number_of_points
++        print "number_of_points:", number_of_points
+         print "generate points"
+-        points=gen_random_poly(number_of_points,nvariables,[Variable(i) for i in range(nvariables)])
++        points = gen_random_poly(number_of_points, nvariables, [Variable(i)
++            for i in range(nvariables)])
+         print "points generated"
+-        bench_interpolate(nvariables,nvariables,points)
+-        vars_mon=Monomial(r)
++        bench_interpolate(nvariables, nvariables, points)
++        vars_mon = Monomial(r)
+         for i in reversed(range(nvariables)):
+-            vars_mon=vars_mon*Variable(i, r)
+-        print len(variety_lex_leading_terms(points,vars_mon)), "elements in groebner basis"
++            vars_mon = vars_mon * Variable(i, r)
++        print(len(variety_lex_leading_terms(points, vars_mon)),
++            "elements in groebner basis")
+diff --git a/pyroot/polybori/interred.py b/pyroot/polybori/interred.py
+index 73bd6fc..aaad53e 100644
+--- a/pyroot/polybori/interred.py
++++ b/pyroot/polybori/interred.py
+@@ -1,28 +1,29 @@
+ from polybori.PyPolyBoRi import GroebnerStrategy, Polynomial, ReductionStrategy
+ 
+-def interred(l,completely=False):
+-    """computes a new generating system (g1, ...,gn), 
++
++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: 
++    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]
++    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)
++    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
++            g.opt_red_tail = True
+         for p in l:
+-            p=g.nf(p)
++            p = g.nf(p)
+             if not p.is_zero():
+                 g.add_generator(p)
+-        l=tuple([e.p for e in g])
++        l = tuple([e.p for e in g])
+     return list(l)
+diff --git a/pyroot/polybori/intersect.py b/pyroot/polybori/intersect.py
+index c60597f..838145f 100644
+--- a/pyroot/polybori/intersect.py
++++ b/pyroot/polybori/intersect.py
+@@ -1,16 +1,17 @@
+-# 
++#
+ #  intersect.py
+ #  PolyBoRi
+-#  
++#
+ #  Created by Michael Brickenstein on 2008-09-24.
+ #  Copyright 2008 The PolyBoRi Team
+-# 
++#
+ 
+ from polybori.gbcore import groebner_basis
+ from polybori.statistics import used_vars_set
+ from itertools import chain
+ 
+-def intersect(i,j,**gb_opts):
++
++def intersect(i, j, **gb_opts):
+     """
+     This functions intersects two ideals. The first ring variable is used as helper variable for this
+     intersection. It is assumed, that it doesn't occur in the ideals, and that we have an elimination ordering
+@@ -24,15 +25,18 @@ def intersect(i,j,**gb_opts):
+     """
+     if not i or not j:
+         return []
+-    
+-    uv=used_vars_set(i)*used_vars_set(j)
++
++    uv = used_vars_set(i) * used_vars_set(j)
+     t = iter(i).next().ring().variable(0)
+     if uv.reducible_by(t):
+-        raise ValueError, "First ring variable has to be reserved as helper variable t"
+-    if not t>uv:
++        raise ValueError, \
++            "First ring variable has to be reserved as helper variable t"
++    if not t > uv:
+         raise ValueError, "need elimination ordering for first ring variable"
+-    gb=groebner_basis(list(chain((t*p for p in i),((1+t)*p for p in j))),**gb_opts)
+-    return [p for p in gb if p.navigation().value()>t.index()]
++    gb = groebner_basis(list(chain((t * p for p in i), ((1 + t) * p for p in j
++        ))), **gb_opts)
++    return [p for p in gb if p.navigation().value() > t.index()]
++
+ 
+ def _test():
+     import doctest
+diff --git a/pyroot/polybori/intpolys.py b/pyroot/polybori/intpolys.py
+index 3c4ec18..18e3d4f 100644
+--- a/pyroot/polybori/intpolys.py
++++ b/pyroot/polybori/intpolys.py
+@@ -1,30 +1,34 @@
+-if __name__=='__main__':
++if __name__ == '__main__':
+     from sys import path as search_path
+     from os import path as file_path
+     search_path.append(file_path.join(file_path.dirname(__file__), '..'))
+-    
++
+ from polybori.PyPolyBoRi import Monomial, Polynomial, BooleSet, BooleConstant
+ from polybori.PyPolyBoRi import Variable as VariableType
+ 
++
+ class IntegerPolynomial(object):
+     """Polynomial with positive integer coefficients"""
++
+     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
++            boolean_polys = dict([(0, Polynomial(boolean_polys))])
++        self.boolean_polys = boolean_polys
++
+     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 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([(i, BooleConstant(1)) for i
++                in res])))
++        if not isinstance(other, IntegerPolynomial):
++            other = Polynomial(other)
+         return (self, IntegerPolynomial(dict([(0, other)])))
+ 
+     def __add__(self, other):
+@@ -42,26 +46,29 @@ class IntegerPolynomial(object):
+         {1: x(2), 2: x(1)}
+         """
+         if not isinstance(other, IntegerPolynomial):
+-            (self, other)=coerce(self, other)
+-            return self+other
++            (self, other) = coerce(self, other)
++            return self + other
+         assert isinstance(other, IntegerPolynomial)
+-        def add_simple_poly(p,i):
+-            p=Polynomial(p)
++
++        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
++            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)
++            inter = BooleSet(res_p).intersect(BooleSet(p))
++            add_simple_poly(inter, i + 1)
+             return
+-        res=dict(self.boolean_polys.iteritems())
+-        for (k,p) in other.boolean_polys.iteritems():
+-            add_simple_poly(p=p,i=k)
++        res = dict(self.boolean_polys.iteritems())
++        for (k, p) in other.boolean_polys.iteritems():
++            add_simple_poly(p=p, i=k)
+         return IntegerPolynomial(res)
++
+     def __unicode__(self):
+         return unicode(self.boolean_polys)
++
+     def __repr__(self):
+         return unicode(self)
+ 
+diff --git a/pyroot/polybori/ll.py b/pyroot/polybori/ll.py
+index b3b7c49..face31a 100644
+--- a/pyroot/polybori/ll.py
++++ b/pyroot/polybori/ll.py
+@@ -2,190 +2,203 @@ from polybori.PyPolyBoRi import *
+ from polybori.statistics import used_vars_set
+ 
+ from polybori.rank import rank
+-lead_index=top_index
++lead_index = top_index
++
+ #(p):
+ #  return iter(p.lex_lead()).next().index()#first index
+- 
+-def combine(reductors,p, reduce=None):
+-    p_nav=p.navigation()
+-    assert p_nav.value()<reductors.navigation().value()
+-    p_else=BooleSet(p_nav.else_branch(), p.ring())
++
++def combine(reductors, p, reduce=None):
++    p_nav = p.navigation()
++    assert p_nav.value() < reductors.navigation().value()
++    p_else = BooleSet(p_nav.else_branch(), p.ring())
+     if reduce:
+-        p_else=reduce(p_else,reductors)
+-    return if_then_else(p_nav.value(),reductors,p_else)
+-    
++        p_else = reduce(p_else, reductors)
++    return if_then_else(p_nav.value(), reductors, p_else)
++
+ 
+ def llredsb_Cudd_style(polys):
+ 
+-  if polys:
+-      reductors=Polynomial( polys[0].ring().one()).set()
+-  else:
+-      reductors=None
+-  
+-  linear_lead=sorted(polys,key=lead_index,reverse=True)
+-  assert len(set([p.lex_lead() for p in linear_lead]))==len(polys)
+-  assert len([p for p in polys if p.constant()])==0
+-  assert len([p for p in polys if p.lex_lead_deg()==1])==len(polys)
+-  assert len(set([p.navigation().value() for p in polys]))==len(polys)
+-  for p in linear_lead:
+-        reductors=combine(reductors,p,reduce=ll_red_nf_redsb)
+-  return reductors
++    if polys:
++        reductors = Polynomial(polys[0].ring().one()).set()
++    else:
++        reductors = None
+ 
++    linear_lead = sorted(polys, key=lead_index, reverse=True)
++    assert len(set([p.lex_lead() for p in linear_lead])) == len(polys)
++    assert len([p for p in polys if p.constant()]) == 0
++    assert len([p for p in polys if p.lex_lead_deg() == 1]) == len(polys)
++    assert len(set([p.navigation().value() for p in polys])) == len(polys)
++    for p in linear_lead:
++        reductors = combine(reductors, p, reduce=ll_red_nf_redsb)
++    return reductors
+ 
+ 
+ def ll_encode(polys, reduce=False, prot=False, reduce_by_linear=True):
+-  polys=[Polynomial(p) for p in polys]
+-  linear_lead=sorted(polys,key=lead_index, reverse=True)
+-  assert len(set([p.lex_lead() for p in linear_lead]))==len(polys)
+-  assert len([p for p in polys if p.constant()])==0
+-  assert len([p for p in polys if p.lex_lead_deg()==1])==len(polys)
+-  assert len(set([p.navigation().value() for p in polys]))==len(polys)
+-  if (not reduce) and reduce_by_linear:
+-        linear_polys=[p for p in polys if p.deg()==1]
++    polys = [Polynomial(p) for p in polys]
++    linear_lead = sorted(polys, key=lead_index, reverse=True)
++    assert len(set([p.lex_lead() for p in linear_lead])) == len(polys)
++    assert len([p for p in polys if p.constant()]) == 0
++    assert len([p for p in polys if p.lex_lead_deg() == 1]) == len(polys)
++    assert len(set([p.navigation().value() for p in polys])) == len(polys)
++    if (not reduce) and reduce_by_linear:
++        linear_polys = [p for p in polys if p.deg() == 1]
+         if linear_polys:
+-            linear_ll=ll_encode(linear_polys, reduce=True, reduce_by_linear=False)
+-            polys=[p.lex_lead()+ll_red_nf_redsb(p+p.lex_lead(), linear_ll) for p in polys]
+-  if reduce:
+-      reduce=ll_red_nf_redsb
+-  else:
+-      reduce=None
+-
+-  
+-  if polys:
+-      reductors=Polynomial( polys[0].ring().one()).set()
+-  else:
+-      reductors=None
+-  
+-  
+-  last=None
+-  counter=0
+-  for p in linear_lead:
+-
+-      if prot:
+-          counter=counter+1
+-          progress=(counter*100)/len(linear_lead)
+-          if last!=progress:
+-              print str(progress)+"%"
+-          last=progress
+-      reductors=combine(reductors,p,reduce=reduce)
+-  return reductors
+-
+-def eliminate(polys, on_the_fly=False,prot=False, reduction_function=None, optimized=True):
+-  """There exists an optimized variant, which reorders the variable in a different
++            linear_ll = ll_encode(linear_polys, reduce=True,
++                reduce_by_linear=False)
++            polys = [p.lex_lead() + ll_red_nf_redsb(p + p.lex_lead(),
++                linear_ll) for p in polys]
++    if reduce:
++        reduce = ll_red_nf_redsb
++    else:
++        reduce = None
++
++
++    if polys:
++        reductors = Polynomial(polys[0].ring().one()).set()
++    else:
++        reductors = None
++
++    last = None
++    counter = 0
++    for p in linear_lead:
++
++        if prot:
++            counter = counter + 1
++            progress = (counter * 100) / len(linear_lead)
++            if last != progress:
++                print str(progress) + "%"
++            last = progress
++        reductors = combine(reductors, p, reduce=reduce)
++    return reductors
++
++
++def eliminate(polys, on_the_fly=False, prot=False, reduction_function=None,
++    optimized=True):
++    """There exists an optimized variant, which reorders the variable in a different
+   ring.
+   """
+-  polys=[Polynomial(p) for p in polys]
+-  rest=[]
+-  linear_leads=[]
+-  linear_leading_monomials=set()
+-  for p in polys:
+-    if p.is_zero():
+-      continue
+-    lm=p.lex_lead()
+-    if lm.deg()==1:
+-      
+-      if not (lm in linear_leading_monomials):
+-        linear_leading_monomials.add(lm)
+-        linear_leads.append(p)
+-      else:
+-        rest.append(p)
+-    else:
+-      rest.append(p)
+-  if len(linear_leads)==0:
+-      def identity(p):
+-          return p
+-      return (linear_leads, identity, rest)
+-  if reduction_function is None:
+-      if on_the_fly:
+-          if optimized:
+-              reduction_function = ll_red_nf_noredsb_single_recursive_call
+-          else:
+-              reduction_function = ll_red_nf_noredsb
+-      else:
+-          reduction_function = ll_red_nf_redsb
+-  def llnf(p):
+-      return reduction_function(p,reductors)
+-  reduced_list=[]
+-  if optimized:
+-      (llnf, reduced_list)=eliminate_ll_ranked(
++    polys = [Polynomial(p) for p in polys]
++    rest = []
++    linear_leads = []
++    linear_leading_monomials = set()
++    for p in polys:
++        if p.is_zero():
++            continue
++        lm = p.lex_lead()
++        if lm.deg() == 1:
++
++            if not (lm in linear_leading_monomials):
++                linear_leading_monomials.add(lm)
++                linear_leads.append(p)
++            else:
++                rest.append(p)
++        else:
++            rest.append(p)
++    if len(linear_leads) == 0:
++        def identity(p):
++            return p
++        return (linear_leads, identity, rest)
++    if reduction_function is None:
++        if on_the_fly:
++            if optimized:
++                reduction_function = ll_red_nf_noredsb_single_recursive_call
++            else:
++                reduction_function = ll_red_nf_noredsb
++        else:
++            reduction_function = ll_red_nf_redsb
++
++    def llnf(p):
++        return reduction_function(p, reductors)
++    reduced_list = []
++    if optimized:
++        (llnf, reduced_list) = eliminate_ll_ranked(
+         linear_leads,
+         rest,
+         reduction_function=reduction_function,
+         reduce_ll_system=(not on_the_fly),
+         prot=prot)
+-  else:
+-      reductors=ll_encode(linear_leads,reduce=(not on_the_fly),prot=prot)
+-      for p in rest:
+-          p=reduction_function(p,reductors)
+-          if p.is_one():
+-              reduced_list=[p]
+-              break
+-          else:
+-              reduced_list.append(p)
+-
+-  return (linear_leads,llnf,reduced_list)
+-  
++    else:
++        reductors = ll_encode(linear_leads, reduce=(not on_the_fly), prot=prot)
++        for p in rest:
++            p = reduction_function(p, reductors)
++            if p.is_one():
++                reduced_list = [p]
++                break
++            else:
++                reduced_list.append(p)
++
++    return (linear_leads, llnf, reduced_list)
++
++
+ def construct_map_by_indices(to_ring, idx_mapping):
+-  v=BoolePolynomialVector((max(idx_mapping.keys())+1)*[to_ring.zero()])
+-  for (from_idx, to_idx) in idx_mapping.iteritems():
+-      val = to_ring.variable(to_idx)
+-      v[from_idx]= val
+-  return v
++    v = BoolePolynomialVector((max(idx_mapping.keys()) + 1) * [to_ring.zero()])
++    for (from_idx, to_idx) in idx_mapping.iteritems():
++        val = to_ring.variable(to_idx)
++        v[from_idx] = val
++    return v
+ 
+ 
+ def eliminate_ll_ranked(ll_system, to_reduce,
+                         reduction_function=ll_red_nf_noredsb,
+                         reduce_ll_system=False, prot=False):
+ 
+-  assert(ll_system)
+-  from_ring=ll_system[0].ring()
+-  
+-  ll_ranks=rank(ll_system)
+-  add_vars=set(used_vars_set(to_reduce).variables()).difference(ll_ranks.keys())
+-  for v in add_vars:
+-      ll_ranks[v]=-1
++    assert(ll_system)
++    from_ring = ll_system[0].ring()
++
++    ll_ranks = rank(ll_system)
++    add_vars = set(used_vars_set(to_reduce).variables()).difference(ll_ranks.
++        keys())
++    for v in add_vars:
++        ll_ranks[v] = -1
++
+       #pushing variables ignored by ll to the front means,
+       #that the routines will quickly eliminate them
+       #and they won't give any overhead
+-  def sort_key(v):
+-      return (ll_ranks[v], v.index())
+-  sorted_vars=sorted(ll_ranks.keys(), key=sort_key)
+-  def var_index(v):
+-      return iter(Monomial(v).variables()).next().index()
++    def sort_key(v):
++        return (ll_ranks[v], v.index())
++    sorted_vars = sorted(ll_ranks.keys(), key=sort_key)
++
++    def var_index(v):
++        return iter(Monomial(v).variables()).next().index()
+   #sorted_var_indices=[var_index(v) for v in sorted_vars]
+-  to_ring=Ring(len(sorted_vars))
+-  map_back_indices = dict([(i, var_index(v)) for (i, v) in enumerate(sorted_vars)])
+-  map_from_indices = dict([(var_index(v), i) for (i, v) in enumerate(sorted_vars)])
++    to_ring = Ring(len(sorted_vars))
++    map_back_indices = dict([(i, var_index(v)) for (i, v) in enumerate(
++        sorted_vars)])
++    map_from_indices = dict([(var_index(v), i) for (i, v) in enumerate(
++        sorted_vars)])
+   #dict([(v,k) for (k,v) in enumerate(sorted_var_indices)])
+-  var_names=[str(v) for v in sorted_vars]
+-  try:
+-      for (i, v) in enumerate(sorted_vars):
+-        assert var_names[i]==str(v), (var_names[i], v, var_index(v), i)
++    var_names = [str(v) for v in sorted_vars]
++    try:
++        for (i, v) in enumerate(sorted_vars):
++            assert var_names[i] == str(v), (var_names[i], v, var_index(v), i)
+       #        _set_variable_name(to_ring, i, var_names[i] + "TO")
+-  finally:
+-      pass
+-  try:
+-      map_from_vec=construct_map_by_indices(to_ring, map_from_indices)
+-  finally:
+-      pass
+-  map_back_vec=construct_map_by_indices(from_ring, map_back_indices)
+-  def map_from(p):
+-      res=substitute_variables(to_ring, map_from_vec, p)
+-      #assert str(p)==str(res), (str(p), str(res), list(map_from_vec), list(map_back_vec))
+-      return res
+-  def map_back(p):
+-      return substitute_variables(from_ring, map_back_vec, p)
+-  try:
+-      ll_opt_encoded=ll_encode([map_from(p) for p in ll_system],
++    finally:
++        pass
++    try:
++        map_from_vec = construct_map_by_indices(to_ring, map_from_indices)
++    finally:
++        pass
++    map_back_vec = construct_map_by_indices(from_ring, map_back_indices)
++
++    def map_from(p):
++        res = substitute_variables(to_ring, map_from_vec, p)
++      # assert str(p)==str(res), (str(p), str(res), list(map_from_vec),
++      # list(map_back_vec))
++        return res
++
++    def map_back(p):
++        return substitute_variables(from_ring, map_back_vec, p)
++    try:
++        ll_opt_encoded = ll_encode([map_from(p) for p in ll_system],
+             prot=False,
+             reduce=reduce_ll_system)
+-      
+-      def llnf(p):
+-          return map_back(reduction_function(map_from(p), ll_opt_encoded))
+-      opt_eliminated=[llnf(p) for p in to_reduce]
+-  finally:
+-      pass
+-  return (llnf, opt_eliminated)
++
++        def llnf(p):
++            return map_back(reduction_function(map_from(p), ll_opt_encoded))
++        opt_eliminated = [llnf(p) for p in to_reduce]
++    finally:
++        pass
++    return (llnf, opt_eliminated)
+ 
+ 
+ class RingMap(object):
+@@ -210,6 +223,7 @@ class RingMap(object):
+     ...
+     RuntimeError: Operands come from different manager.
+     """
++
+     def __init__(self, to_ring, from_ring):
+         """Initialize map by two given rings.
+ 
+@@ -220,11 +234,13 @@ class RingMap(object):
+         >>> mapping(x(1)+1)
+         x(1) + 1
+         """
++
+         def vars(ring):
+             return [ring.variable(i) for i in xrange(ring.n_variables())]
++
+         def indices(vars):
+             return dict([(str(v), idx) for (idx, v) in enumerate(vars)])
+-                          
++
+         self.to_ring = to_ring
+         self.from_ring = from_ring
+         to_vars = vars(to_ring)
+@@ -267,6 +283,3 @@ class RingMap(object):
+         x(1) + 1
+         """
+         return substitute_variables(self.from_ring, self.from_map, poly)
+-
+-        
+-    
+diff --git a/pyroot/polybori/memusage.py b/pyroot/polybori/memusage.py
+index 2c30e4e..6095761 100644
+--- a/pyroot/polybori/memusage.py
++++ b/pyroot/polybori/memusage.py
+@@ -1,13 +1,13 @@
+ import os
+ from sys import maxint
+ _proc_status = '/proc/%d/status' % os.getpid()
+-
+ #_scale = {'kB': 1024.0, 'mB': 1024.0*1024.0,
+ #          'KB': 1024.0, 'MB': 1024.0*1024.0}
+ 
+ _scale = {'kB': 1, 'mB': 1024, 'gB': 1024 * 1024,
+           'KB': 1, 'MB': 1024, 'GB': 1024 * 1024}
+ 
++
+ def _VmB(VmKey):
+     '''Private.
+     '''
+@@ -28,6 +28,7 @@ def _VmB(VmKey):
+   #  return float(v[1]) * _scale[v[2]]
+     return int(v[1]) * _scale[v[2]]
+ 
++
+ def memory(since=0):
+     '''Return memory usage in kilobytes.
+     '''
+@@ -39,22 +40,23 @@ def resident(since=0):
+     '''
+     return _VmB('VmRSS:') - since
+ 
++
+ def memorypeak(since=0):
+     '''Return memory usage peak in kilobytes.
+     '''
+     try:
+         return _VmB('VmPeak:') - since
+     except:
+-        return float('nan') # old Linux?
++        return float('nan')  # old Linux?
+ 
+ 
+ def residentpeak(since=0):
+     '''Return resident memory usage peak in kilobytes.
+     '''
+     try:
+-        return _VmB('VmHWM:')  - since
++        return _VmB('VmHWM:') - since
+     except:
+-        return float('nan')  # old Linux?    
++        return float('nan')  # old Linux?
+ 
+ 
+ def stacksize(since=0):
+diff --git a/pyroot/polybori/ncf.py b/pyroot/polybori/ncf.py
+index 5ef7daf..e3325c9 100644
+--- a/pyroot/polybori/ncf.py
++++ b/pyroot/polybori/ncf.py
+@@ -1,39 +1,41 @@
+ from polybori import Polynomial
+-def get_splitting(f,variables):
++
++
++def get_splitting(f, variables):
+     ring = s.ring()
+-    s=f.set()
++    s = f.set()
+     for var_index in variables:
+-        s1=Polynomial(s.subset1(var_index))
+-        s0=Polynomial(s.subset0(var_index))
+-        f1=s0+s1
+-        f0=s0
++        s1 = Polynomial(s.subset1(var_index))
++        s0 = Polynomial(s.subset0(var_index))
++        f1 = s0 + s1
++        f0 = s0
+         var = ring.variable(var_index)
+         if f1.constant():
+-            return dict(b=f1,a=Polynomial(1, ring),x=var,g=f0)
++            return dict(b=f1, a=Polynomial(1, ring), x=var, g=f0)
+         if f0.constant():
+-            return dict(b=f0,a=Polynomial(0, ring),x=var,g=f1)
++            return dict(b=f0, a=Polynomial(0, ring), x=var, g=f1)
+     return None
+ 
+ 
+-def nested_canalyzing_function(f,variables=None):
+-    f=Polynomial(f)
++def nested_canalyzing_function(f, variables=None):
++    f = Polynomial(f)
+     if variables is None:
+-        variables=f.vars_as_monomial()
++        variables = f.vars_as_monomial()
+     if not variables.reducible_by(f.vars_as_monomial()):
+         raise ValueError
+-    if variables!=f.vars_as_monomial():
++    if variables != f.vars_as_monomial():
+         return False
+-    if len(variables)==0:
++    if len(variables) == 0:
+         return True
+-    splitting=get_splitting(f,variables)
++    splitting = get_splitting(f, variables)
+     if splitting is None:
+         return False
+-    rec=nested_canalyzing_function(splitting["g"],variables/splitting["x"])
++    rec = nested_canalyzing_function(splitting["g"], variables / splitting["x"
++        ])
+     if rec:
+         if rec is True:
+-            return (splitting,)
++            return (splitting, )
+         else:
+-            return (splitting,rec)
++            return (splitting, rec)
+     else:
+         return False
+-    
+diff --git a/pyroot/polybori/nf.py b/pyroot/polybori/nf.py
+index 4505c48..681dde8 100644
+--- a/pyroot/polybori/nf.py
++++ b/pyroot/polybori/nf.py
+@@ -1,5 +1,6 @@
+ from polybori.PyPolyBoRi import *
+-from polybori.easy_polynomials import easy_linear_polynomials as easy_linear_polynomials_func
++from polybori.easy_polynomials import (easy_linear_polynomials as
++    easy_linear_polynomials_func)
+ from polybori.statistics import used_vars_set
+ from random import Random
+ from warnings import warn
+@@ -7,77 +8,78 @@ import copy
+ import sys
+ from exceptions import NotImplementedError
+ 
++
+ class GeneratorLimitExceeded(Exception):
+     """docstring for GeneratorLimitExceeded"""
++
+     def __init__(self, strat):
+         #super(GeneratorLimitExceeded, self).__init__()
+         self.strat = strat
+-        
+-        
+-        
+-
+-
+ 
+ #used_polynomials=list()
+ 
+ def pkey(p):
+-    return (p[0],len(p))
+-mat_counter=0
+-def build_and_print_matrices(v,strat):
++    return (p[0], len(p))
++mat_counter = 0
++
++
++def build_and_print_matrices(v, strat):
+     """old solution using PIL, the currently used implementation is done in C++
+     and plots the same matrices, as being calculated"""
+-    treated=BooleSet()
+-    v=list(v)
+-    rows=0
+-    polys_in_mat=[]
+-    if len(v)==0:
++    treated = BooleSet()
++    v = list(v)
++    rows = 0
++    polys_in_mat = []
++    if len(v) == 0:
+         return
+-    while(len(v)>0):
+-        rows=rows+1
+-        p=v[0]
+-        v=v[1:]
++    while(len(v) > 0):
++        rows = rows + 1
++        p = v[0]
++        v = v[1:]
+         #used_polynomials.append(p)
+         for m in list(p.terms()):
+-            m=Monomial(m)
++            m = Monomial(m)
+             if not m in BooleSet(treated):
+-                i=strat.select(m)
+-                if i>=0:
+-                    p2=strat[i]
+-                    p2=p2*(m//p2.lead())
++                i = strat.select(m)
++                if i >= 0:
++                    p2 = strat[i]
++                    p2 = p2 * (m // p2.lead())
+                     v.append(p2)
+         polys_in_mat.append(p)
+-        treated=treated.union(p.set())
+-    m2i=dict([(v,k) for (k,v) in enumerate(list(Polynomial(BooleSet(treated)).terms()))])
++        treated = treated.union(p.set())
++    m2i = dict([(v, k) for (k, v) in enumerate(list(Polynomial(BooleSet(
++        treated)).terms()))])
+     #print polys_in_mat
+     polys_in_mat.sort(key=Polynomial.lead, reverse=True)
+-    polys_in_mat=[[m2i[t] for t in p.terms()] for p in polys_in_mat]
+-    
++    polys_in_mat = [[m2i[t] for t in p.terms()] for p in polys_in_mat]
+ 
+     global mat_counter
+-    mat_counter=mat_counter+1
+-    import Image, ImageDraw
+-    
+-    rows=len(polys_in_mat)
+-    cols=len(m2i)
++    mat_counter = mat_counter + 1
++    import Image
++    import ImageDraw
++
++    rows = len(polys_in_mat)
++    cols = len(m2i)
+     #print cols,rows
+-    im=Image.new("1",(cols,rows),"white")
++    im = Image.new("1", (cols, rows), "white")
+     #im=Image.new("1",(,10000),"white")
+     for i in xrange(len(polys_in_mat)):
+-        p=polys_in_mat[i]
++        p = polys_in_mat[i]
+         for j in p:
+-           assert i<rows
+-           assert j<cols
++            assert i < rows
++            assert j < cols
+ 
+-           im.putpixel((j,i), 0)
++            im.putpixel((j, i), 0)
+ 
+-    file_name=matrix_prefix+str(mat_counter)+".png"
++    file_name = matrix_prefix + str(mat_counter) + ".png"
+     import os
+-    os.system("rm -f "+file_name)
++    os.system("rm -f " + file_name)
+     im.save(file_name)
+     del im
+ 
+-    print "MATRIX_SIZE:", rows,"x",cols
+-    
++    print "MATRIX_SIZE:", rows, "x", cols
++
++
+ def multiply_polynomials(l, ring):
+     """
+     >>> r=Ring(1000)
+@@ -85,129 +87,133 @@ def multiply_polynomials(l, ring):
+     >>> multiply_polynomials([x(3), x(2)+x(5)*x(6), x(0), x(0)+1], r)
+     0
+     """
+-    l=[Polynomial(p) for p in l]
++    l = [Polynomial(p) for p in l]
++
+     def sort_key(p):
+         return p.navigation().value()
+-    l=sorted(l, key=sort_key)
+-    res=Polynomial(ring.one())
++    l = sorted(l, key=sort_key)
++    res = Polynomial(ring.one())
+     for p in l:
+-        res=p*res
++        res = p * res
+     return res
+-    
+-        
+-    
+-    
+-def build_and_print_matrices_deg_colored(v,strat):
++
++
++def build_and_print_matrices_deg_colored(v, strat):
+     """old PIL solution using a different color for each degree"""
+-    if len(v)==0:
++    if len(v) == 0:
+         return
+-    
+-    treated=BooleSet()
+-    v=list(v)
+-    rows=0
+-    polys_in_mat=[]
+-
+-    while(len(v)>0):
+-        rows=rows+1
+-        p=v[0]
+-        v=v[1:]
++
++    treated = BooleSet()
++    v = list(v)
++    rows = 0
++    polys_in_mat = []
++
++    while(len(v) > 0):
++        rows = rows + 1
++        p = v[0]
++        v = v[1:]
+         for m in list(p.terms()):
+-            m=Monomial(m)
++            m = Monomial(m)
+             if not m in BooleSet(treated):
+-                i=strat.select(m)
+-                if i>=0:
+-                    p2=strat[i]
+-                    p2=p2*(m//p2.lead())
++                i = strat.select(m)
++                if i >= 0:
++                    p2 = strat[i]
++                    p2 = p2 * (m // p2.lead())
+                     v.append(p2)
+         polys_in_mat.append(p)
+-        treated=treated.union(p.set())
+-    m2i=dict([(v,k) for (k,v) in enumerate(BooleSet(treated))])
+-    max_deg=max([m.deg() for m in BooleSet(treated)])
+-    if max_deg==0:
+-        max_deg=1
+-    i2deg=dict([(m2i[m],m.deg()) for m in BooleSet(treated)])
+-    polys_in_mat=[[m2i[t] for t in p.terms()] for p in polys_in_mat]
++        treated = treated.union(p.set())
++    m2i = dict([(v, k) for (k, v) in enumerate(BooleSet(treated))])
++    max_deg = max([m.deg() for m in BooleSet(treated)])
++    if max_deg == 0:
++        max_deg = 1
++    i2deg = dict([(m2i[m], m.deg()) for m in BooleSet(treated)])
++    polys_in_mat = [[m2i[t] for t in p.terms()] for p in polys_in_mat]
+     polys_in_mat.sort(key=pkey)
+     global mat_counter
+-    mat_counter=mat_counter+1
+-    import Image, ImageDraw, ImageColor
+-    
+-    rows=len(polys_in_mat)
+-    cols=len(m2i)
+-    im=Image.new("RGB",(cols,rows),"white")
++    mat_counter = mat_counter + 1
++    import Image
++    import ImageDraw
++    import ImageColor
++
++    rows = len(polys_in_mat)
++    cols = len(m2i)
++    im = Image.new("RGB", (cols, rows), "white")
+     for i in xrange(len(polys_in_mat)):
+-        p=polys_in_mat[i]
++        p = polys_in_mat[i]
+         for j in p:
+-           assert i<rows
+-           assert j<cols
+-           im.putpixel((j,i), ImageColor.getrgb("hsl("+str(270-(270*i2deg[j])/max_deg)+",100%,50%)"))
+-    file_name=matrix_prefix+str(mat_counter)+".png"
++            assert i < rows
++            assert j < cols
++            im.putpixel((j, i), ImageColor.getrgb("hsl(" + str(270 - (270 *
++                i2deg[j]) / max_deg) + ",100%,50%)"))
++    file_name = matrix_prefix + str(mat_counter) + ".png"
+     import os
+     os.system("rm -f file_name")
+     im.save(file_name)
+     del im
+-    
+-    
+-    print "MATRIX_SIZE:", rows,"x",cols   
++
++    print "MATRIX_SIZE:", rows, "x", cols
++
+ 
+ def high_probability_polynomials_trick(p, strat):
+-    lead_deg=p.lead_deg()
+-    if lead_deg<=4:
++    lead_deg = p.lead_deg()
++    if lead_deg <= 4:
+         return
+-    
+-    ring =p.ring()
+-    factor=multiply_polynomials(easy_linear_factors(p), ring)
+-    p=p/factor
+-    
++
++    ring = p.ring()
++    factor = multiply_polynomials(easy_linear_factors(p), ring)
++    p = p / factor
++
+     #again, do it twice, it's cheap
+-    lead_deg=p.lead_deg()
+-    if lead_deg<=3:
++    lead_deg = p.lead_deg()
++    if lead_deg <= 3:
+         return
+-    
+-    if lead_deg>9:
++
++    if lead_deg > 9:
+         return
+-    uv=p.vars_as_monomial()
+-        
+-    candidates=[]
+-    
+-    if uv.deg()<=4:
++    uv = p.vars_as_monomial()
++
++    candidates = []
++
++    if uv.deg() <= 4:
+         return
+-    
+-    if not uv.deg()<=lead_deg+1:
++
++    if not uv.deg() <= lead_deg + 1:
+         return
+-        
+-    space=uv.divisors()
+-    
+-    lead=p.lead()
++
++    space = uv.divisors()
++
++    lead = p.lead()
+     for v in lead.variables():
+-        variable_selection=lead//v
+-        vars_reversed=reversed(list(variable_selection.variables()))
++        variable_selection = lead // v
++        vars_reversed = reversed(list(variable_selection.variables()))
+         #it's just a way to loop over the cartesian product
+         for assignment in variable_selection.divisors():
+-            c_p=assignment
++            c_p = assignment
+             for v in vars_reversed:
+                 if not assignment.reducible_by(v):
+-                    c_p=(v+1) * c_p
+-                    
+-            points=(c_p+1).zeros_in(space)
++                    c_p = (v + 1) * c_p
++
++            points = (c_p + 1).zeros_in(space)
+             if p.zeros_in(points).empty():
+-                candidates.append(c_p*factor)
++                candidates.append(c_p * factor)
+         #there many more combinations depending on plugged in values
+     for c in candidates:
+         strat.add_as_you_wish(c)
+-    
+-        
+-def symmGB_F2_python(G,deg_bound=1000000000000,over_deg_bound=0, use_faugere=False,
+-    use_noro=False,opt_lazy=True,opt_red_tail=True,
+-    max_growth=2.0, step_factor=1.0,
+-    implications=False, prot=False,
+-    full_prot=False,selection_size=1000,
+-    opt_exchange=True,
+-    opt_allow_recursion=False,ll=False,
+-    opt_linear_algebra_in_last_block=True, max_generators=None, red_tail_deg_growth=True, matrix_prefix='mat', modified_linear_algebra=True, draw_matrices=False, easy_linear_polynomials=True):
++
++
++def symmGB_F2_python(G, deg_bound=1000000000000, over_deg_bound=0,
++    use_faugere=False, use_noro=False, opt_lazy=True, opt_red_tail=True,
++    max_growth=2.0, step_factor=1.0, implications=False, prot=False,
++    full_prot=False, selection_size=1000, opt_exchange=True,
++    opt_allow_recursion=False, ll=False,
++    opt_linear_algebra_in_last_block=True, max_generators=None,
++    red_tail_deg_growth=True, matrix_prefix='mat',
++    modified_linear_algebra=True, draw_matrices=False,
++    easy_linear_polynomials=True):
+     if use_noro and use_faugere:
+         raise ValueError, 'both use_noro and use_faugere specified'
+-    def add_to_basis(strat,p):
++
++    def add_to_basis(strat, p):
+         if p.is_zero():
+             if prot:
+                 print "-"
+@@ -215,38 +221,40 @@ def symmGB_F2_python(G,deg_bound=1000000000000,over_deg_bound=0, use_faugere=Fal
+             if prot:
+                 if full_prot:
+                     print p
+-                print "Result: ", "deg:", p.deg(), "lm: ", p.lead(), "el: ", p.elength()
+-            if easy_linear_polynomials and p.lead_deg()>2:
+-                lin=easy_linear_polynomials_func(p)
++                print("Result: ", "deg:", p.deg(), "lm: ", p.lead(), "el: ", p
++                    .elength())
++            if easy_linear_polynomials and p.lead_deg() > 2:
++                lin = easy_linear_polynomials_func(p)
+                 for q in lin:
+                     strat.add_generator_delayed(q)
+-            old_len=len(strat)
++            old_len = len(strat)
+             strat.add_as_you_wish(p)
+-            new_len=len(strat)
+-            if new_len==1+old_len:
++            new_len = len(strat)
++            if new_len == 1 + old_len:
+                 high_probability_polynomials_trick(p, strat)
+-                
++
+ 
+             if prot:
+                 print "#Generators:", len(strat)
+-    
+-    if (isinstance(G,list)):
+-        if len(G)==0:
++
++    if (isinstance(G, list)):
++        if len(G) == 0:
+             return []
+-        G=[Polynomial(g) for g in G]  
++        G = [Polynomial(g) for g in G]
+         current_ring = G[0].ring()
+-        strat=GroebnerStrategy(current_ring)
+-        strat.reduction_strategy.opt_red_tail=opt_red_tail
+-        strat.opt_lazy=opt_lazy
+-        strat.opt_exchange=opt_exchange
+-        strat.opt_allow_recursion=opt_allow_recursion
+-        strat.enabled_log=prot
+-        strat.reduction_strategy.opt_ll=ll
+-        strat.opt_modified_linear_algebra=modified_linear_algebra
+-        strat.opt_linear_algebra_in_last_block=opt_linear_algebra_in_last_block
+-        strat.opt_red_by_reduced=False#True
+-        strat.reduction_strategy.opt_red_tail_deg_growth=red_tail_deg_growth
+-        
++        strat = GroebnerStrategy(current_ring)
++        strat.reduction_strategy.opt_red_tail = opt_red_tail
++        strat.opt_lazy = opt_lazy
++        strat.opt_exchange = opt_exchange
++        strat.opt_allow_recursion = opt_allow_recursion
++        strat.enabled_log = prot
++        strat.reduction_strategy.opt_ll = ll
++        strat.opt_modified_linear_algebra = modified_linear_algebra
++        strat.opt_linear_algebra_in_last_block = (
++            opt_linear_algebra_in_last_block)
++        strat.opt_red_by_reduced = False  # True
++        strat.reduction_strategy.opt_red_tail_deg_growth = red_tail_deg_growth
++
+         strat.opt_draw_matrices = draw_matrices
+         strat.matrix_prefix = matrix_prefix
+ 
+@@ -254,97 +262,103 @@ def symmGB_F2_python(G,deg_bound=1000000000000,over_deg_bound=0, use_faugere=Fal
+             if not g.is_zero():
+                 strat.add_generator_delayed(g)
+     else:
+-        strat=G
+-        
++        strat = G
++
+     if prot:
+         print "added delayed"
+-    i=0
++    i = 0
+     try:
+-        while strat.npairs()>0:
+-            if max_generators and len(strat)>max_generators:
++        while strat.npairs() > 0:
++            if max_generators and len(strat) > max_generators:
+                 raise GeneratorLimitExceeded(strat)
+-            i=i+1
++            i = i + 1
+             if prot:
+                 print "Current Degree:", strat.top_sugar()
+-            if (strat.top_sugar()>deg_bound) and (over_deg_bound<=0):
++            if (strat.top_sugar() > deg_bound) and (over_deg_bound <= 0):
+                 return strat
+-            if (strat.top_sugar()>deg_bound):
+-                ps=strat.some_spolys_in_next_degree(over_deg_bound)
+-                over_deg_bound-=len(ps)
++            if (strat.top_sugar() > deg_bound):
++                ps = strat.some_spolys_in_next_degree(over_deg_bound)
++                over_deg_bound -= len(ps)
+             else:
+-                ps=strat.some_spolys_in_next_degree(selection_size)
+-            
++                ps = strat.some_spolys_in_next_degree(selection_size)
++
+             if ps and ps[0].ring().has_degree_order():
+-                ps=[strat.reduction_strategy.cheap_reductions(p) for p in ps]
+-                ps=[p for p in ps if not p.is_zero()]
+-                if len(ps)>0:
+-                    min_deg=min((p.deg() for p in ps))
+-                new_ps=[]
++                ps = [strat.reduction_strategy.cheap_reductions(p) for p in ps]
++                ps = [p for p in ps if not p.is_zero()]
++                if len(ps) > 0:
++                    min_deg = min((p.deg() for p in ps))
++                new_ps = []
+                 for p in ps:
+-                    if p.deg()<=min_deg:
++                    if p.deg() <= min_deg:
+                         new_ps.append(p)
+                     else:
+                         strat.add_generator_delayed(p)
+-                ps=new_ps
+-            
++                ps = new_ps
++
+             if prot:
+                 print "(", strat.npairs(), ")"
+             if prot:
+                 print "start reducing"
+-                print "Chain Crit. : ",strat.chain_criterions, "VC:",strat.variable_chain_criterions,\
+-                "EASYP",strat.easy_product_criterions,"EXTP",strat.extended_product_criterions
++                print("Chain Crit. : ", strat.chain_criterions, "VC:", strat.
++                    variable_chain_criterions, "EASYP", strat.
++                    easy_product_criterions, "EXTP", strat.
++                    extended_product_criterions)
+                 print len(ps), "spolys added"
+-            
++
+             if use_noro or use_faugere:
+-                 v=BoolePolynomialVector()
+-
+-                 for p in ps:
+-                        if not p.is_zero():
+-                            v.append(p)
+-                 if use_noro:
+-                     res=strat.noro_step(v)
+-                 else:
+-                     res=strat.faugere_step_dense(v)
+-            
++                v = BoolePolynomialVector()
++
++                for p in ps:
++                    if not p.is_zero():
++                        v.append(p)
++                if use_noro:
++                    res = strat.noro_step(v)
++                else:
++                    res = strat.faugere_step_dense(v)
++
+             else:
+-                v=BoolePolynomialVector()
++                v = BoolePolynomialVector()
+                 for p in ps:
+-                    p=Polynomial(
++                    p = Polynomial(
+                         mod_mon_set(
+-                        BooleSet(p.set()),strat.reduction_strategy.monomials))
++                        BooleSet(p.set()), strat.reduction_strategy.monomials))
+                     if not p.is_zero():
+                         v.append(p)
+-                if len(v)>100:
+-                   res=parallel_reduce(v,strat,int(step_factor*10),max_growth)
++                if len(v) > 100:
++                    res = parallel_reduce(v, strat, int(step_factor * 10),
++                        max_growth)
+                 else:
+-                   if len(v)>10:
+-                      res=parallel_reduce(v,strat,int(step_factor*30),max_growth)
+-                   else:
+-                      res=parallel_reduce(v,strat,int(step_factor*100), max_growth)
+-            
++                    if len(v) > 10:
++                        res = parallel_reduce(v, strat, int(step_factor * 30),
++                            max_growth)
++                    else:
++                        res = parallel_reduce(v, strat, int(step_factor * 100
++                            ), max_growth)
++
+             if prot:
+                 print "end reducing"
+-            
+ 
+-            if len(res)>0 and res[0].ring().has_degree_order():
+-                res_min_deg=min([p.deg() for p in res])
++
++            if len(res) > 0 and res[0].ring().has_degree_order():
++                res_min_deg = min([p.deg() for p in res])
+                 new_res = []
+                 for p in res:
+-                    if p.deg()==res_min_deg:
++                    if p.deg() == res_min_deg:
+                         new_res.append(p)
+                     else:
+                         strat.add_generator_delayed(p)
+                 res = new_res
++
+             def sort_key(p):
+                 return p.lead()
+-            res_cp=sorted(res, key=sort_key)
++            res_cp = sorted(res, key=sort_key)
+ 
+ 
+             for p in  res_cp:
+-                old_len=len(strat)
+-                add_to_basis(strat,p)
+-                if implications and old_len==len(strat)-1:
+-                    strat.implications(len(strat)-1)
++                old_len = len(strat)
++                add_to_basis(strat, p)
++                if implications and old_len == len(strat) - 1:
++                    strat.implications(len(strat) - 1)
+                 if p.is_one():
+                     if prot:
+                         print "GB is 1"
+@@ -352,269 +366,273 @@ def symmGB_F2_python(G,deg_bound=1000000000000,over_deg_bound=0, use_faugere=Fal
+                 if prot:
+                     print "(", strat.npairs(), ")"
+ 
+-
+             strat.clean_top_by_chain_criterion()
+         return strat
+     except KeyboardInterrupt:
+         #return strat
+         raise
+ 
+-def GPS(G,vars_start, vars_end):
+-    def step(strat,trace,var,val):
+-        print "plugin: ",var,val
++
++def GPS(G, vars_start, vars_end):
++    def step(strat, trace, var, val):
++        print "plugin: ", var, val
+         print "npairs", strat.npairs()
+-        strat=GroebnerStrategy(strat)
++        strat = GroebnerStrategy(strat)
+         print "npairs", strat.npairs()
+-        strat.add_generator_delayed(Polynomial(Monomial(Variable(var, strat.r))+val))
+-        strat=symmGB_F2_python(strat,prot=True,deg_bound=2, over_deg_bound=10)
+-        if var<=vars_start:
+-            strat=symmGB_F2_python(strat, prot=True, opt_lazy=False, redTail=False)
++        strat.add_generator_delayed(Polynomial(Monomial(Variable(var, strat.r)
++            ) + val))
++        strat = symmGB_F2_python(strat, prot=True, deg_bound=2,
++            over_deg_bound=10)
++        if var <= vars_start:
++            strat = symmGB_F2_python(strat, prot=True, opt_lazy=False,
++                redTail=False)
+         if strat.containsOne():
+             pass
+         else:
+-            if var<=vars_start:
++            if var <= vars_start:
+                 #bug: may contain Delayed polynomials
+-                print "!!!!!!! SOLUTION",trace
++                print "!!!!!!! SOLUTION", trace
+                 raise Exception
+                 #yield trace
+             else:
+-                branch(strat,trace+[(var,val)],var-1)
++                branch(strat, trace + [(var, val)], var - 1)
+ 
+-                
+-    def branch(strat,trace, var):
++    def branch(strat, trace, var):
+         while(strat.variableHasValue(var)):
+             #remember to add value to trace
+-            var=var-1
++            var = var - 1
+         step(strat, trace, var, 0)
+         step(strat, trace, var, 1)
+     if G:
+-        strat=GroebnerStrategy(G[0].ring())
++        strat = GroebnerStrategy(G[0].ring())
+         #strat.add_generator(G[0])
+         for g in G[:]:
+             strat.add_generator_delayed(g)
+-        branch(strat,[],vars_end-1)
+-
++        branch(strat, [], vars_end - 1)
+ 
+ 
+-def GPS_with_proof_path(G,proof_path, deg_bound,over_deg_bound):
+-    def step(strat,trace,  proof_path, pos, val):
++def GPS_with_proof_path(G, proof_path, deg_bound, over_deg_bound):
++    def step(strat, trace, proof_path, pos, val):
+         print proof_path
+-        print "plugin: ",pos,val, proof_path[pos]
++        print "plugin: ", pos, val, proof_path[pos]
+         print "npairs", strat.npairs()
+-        strat=GroebnerStrategy(strat)
++        strat = GroebnerStrategy(strat)
+         print "npairs", strat.npairs()
+         print "npairs", strat.npairs()
+-        plug_p=Polynomial(proof_path[pos])+val
+-        plug_p_lead=plug_p.lead()
+-        if len(plug_p)==2 and (plug_p+plug_p_lead).deg()==0:
++        plug_p = Polynomial(proof_path[pos]) + val
++        plug_p_lead = plug_p.lead()
++        if len(plug_p) == 2 and (plug_p + plug_p_lead).deg() == 0:
+             for v in plug_p_lead:
+-                strat.add_generator_delayed(v+1)
++                strat.add_generator_delayed(v + 1)
+         else:
+             strat.add_generator_delayed(plug_p)
+         print "npairs", strat.npairs()
+         print "pos:", pos
+-        strat=symmGB_F2_python(strat,deg_bound=deg_bound, opt_lazy=False,over_deg_bound=over_deg_bound,prot=True)
++        strat = symmGB_F2_python(strat, deg_bound=deg_bound, opt_lazy=False,
++            over_deg_bound=over_deg_bound, prot=True)
+         print "npairs", strat.npairs()
+-        pos=pos+1
+-        if pos>=len(proof_path):
++        pos = pos + 1
++        if pos >= len(proof_path):
+             print "OVER"
+-            strat=symmGB_F2_python(strat,prot=True)
++            strat = symmGB_F2_python(strat, prot=True)
+         if strat.containsOne():
+             pass
+         else:
+-            if pos>=len(proof_path):
++            if pos >= len(proof_path):
+                 print "npairs", strat.npairs()
+                 print "minimized:"
+                 for p in strat.minimalize_and_tail_reduce():
+                     print p
+                 #bug: may contain Delayed polynomials
+-                print "!!!!!!! SOLUTION",trace
++                print "!!!!!!! SOLUTION", trace
+                 raise Exception
+                 #yield trace
+             else:
+-                branch(strat,trace+[(pos,val)],proof_path,pos)
+-                
+-    def branch(strat,trace, proof_path,pos):
+-        
+-        step(strat, trace,  proof_path, pos, 0)
+-        step(strat, trace,  proof_path, pos, 1)
+-    strat=GroebnerStrategy(G[0].ring())
++                branch(strat, trace + [(pos, val)], proof_path, pos)
++
++    def branch(strat, trace, proof_path, pos):
++
++        step(strat, trace, proof_path, pos, 0)
++        step(strat, trace, proof_path, pos, 1)
++    strat = GroebnerStrategy(G[0].ring())
+     strat.add_generator(Polynomial(G[0]))
+     for g in G[1:]:
+         strat.add_generator_delayed(Polynomial(g))
+-    branch(strat,[], proof_path, 0)
++    branch(strat, [], proof_path, 0)
+ 
+ 
+-
+-def GPS_with_suggestions(G,deg_bound,over_deg_bound, opt_lazy=True,opt_red_tail=True,initial_bb=True):
+-    def step(strat,trace, var,val):
++def GPS_with_suggestions(G, deg_bound, over_deg_bound, opt_lazy=True,
++    opt_red_tail=True, initial_bb=True):
++    def step(strat, trace, var, val):
+         print trace
+-        plug_p=val+var
+-        print "plugin: ",len(trace),plug_p
+-        trace=trace+[plug_p]
+-        strat=GroebnerStrategy(strat)
+- 
++        plug_p = val + var
++        print "plugin: ", len(trace), plug_p
++        trace = trace + [plug_p]
++        strat = GroebnerStrategy(strat)
+ 
+-        
+         strat.add_generator_delayed(plug_p)
+         print "npairs", strat.npairs()
+-        
+-        strat=symmGB_F2_python(strat,deg_bound=deg_bound,opt_lazy=opt_lazy,over_deg_bound=over_deg_bound,prot=True)
+-        
++
++        strat = symmGB_F2_python(strat, deg_bound=deg_bound,
++            opt_lazy=opt_lazy, over_deg_bound=over_deg_bound, prot=True)
++
+         #pos=pos+1
+         if not strat.containsOne():
+-            branch(strat,trace)
+-                        
+-    def branch(strat,trace):
++            branch(strat, trace)
++
++    def branch(strat, trace):
+         print "branching"
+-        index=strat.suggestPluginVariable();
+-        if index<0:
+-            uv=set(used_vars_set(strat))
+-            lv=set([iter(p.lead()).next().index() for p in strat if p.lead_deg()==1])
+-            candidates=uv.difference(lv)
+-            if len(candidates)>0:
+-                index=iter(candidates).next().index()
+-        if index>=0:
++        index = strat.suggestPluginVariable()
++
++        if index < 0:
++            uv = set(used_vars_set(strat))
++            lv = set([iter(p.lead()).next().index() for p in strat if p.
++                lead_deg() == 1])
++            candidates = uv.difference(lv)
++            if len(candidates) > 0:
++                index = iter(candidates).next().index()
++        if index >= 0:
+             print "chosen index:", index
+-            step(strat, trace,  Polynomial(Monomial(Variable(index))),0)
+-            step(strat, trace,  Polynomial(Monomial(Variable(index))),1)
++            step(strat, trace, Polynomial(Monomial(Variable(index))), 0)
++            step(strat, trace, Polynomial(Monomial(Variable(index))), 1)
+         else:
+             print "FINAL!!!", index
+-            strat=symmGB_F2_python(strat, prot=True)
++            strat = symmGB_F2_python(strat, prot=True)
+             if not strat.containsOne():
+                 print "TRACE", trace
+                 print "SOLUTION"
+                 for p in strat.minimalize_and_tail_reduce():
+                     print p
+                 raise Exception
++
+     def sort_crit(p):
+         #return (p.deg(),p.lead(),p.elength())
+-        return (p.lead(),p.deg(),p.elength())
++        return (p.lead(), p.deg(), p.elength())
+     if not G:
+-        return 
+-    strat=GroebnerStrategy(G[0].ring())
+-    strat.reduction_strategy.opt_red_tail=opt_red_tail#True
+-    strat.opt_exchange=False
+-    strat.opt_allow_recursion=False
++        return
++    strat = GroebnerStrategy(G[0].ring())
++    strat.reduction_strategy.opt_red_tail = opt_red_tail  # True
++    strat.opt_exchange = False
++    strat.opt_allow_recursion = False
+     #strat.opt_red_tail_deg_growth=False
+-    strat.opt_lazy=opt_lazy
++    strat.opt_lazy = opt_lazy
+     #strat.opt_lazy=True
+-    first_deg_bound=1
+-    G=[Polynomial(p) for p in G]
++    first_deg_bound = 1
++    G = [Polynomial(p) for p in G]
+     G.sort(key=sort_crit)
+-    higher_deg={}
++    higher_deg = {}
+     if initial_bb:
+-      for g in G:
+-          print g
+-          index=strat.select(g.lead())
+-          if p.deg()==1:#(index<0):
+-              strat.add_as_you_wish(g)
+-          else:
+-              first_deg_bound=max(first_deg_bound,g.deg())
+-              strat.add_generator_delayed(g)
+-          print g,len(strat)
++        for g in G:
++            print g
++            index = strat.select(g.lead())
++            if p.deg() == 1:  # (index<0):
++                strat.add_as_you_wish(g)
++            else:
++                first_deg_bound = max(first_deg_bound, g.deg())
++                strat.add_generator_delayed(g)
++            print g, len(strat)
+     else:
+-      for g in G:
+-        strat.add_as_you_wish(g)
++        for g in G:
++            strat.add_as_you_wish(g)
+     if initial_bb:
+-      strat=symmGB_F2_python(strat,deg_bound=max(deg_bound,first_deg_bound), opt_lazy=opt_lazy,over_deg_bound=0,prot=True)
+-    strat.opt_lazy=opt_lazy
++        strat = symmGB_F2_python(strat, deg_bound=max(deg_bound,
++            first_deg_bound), opt_lazy=opt_lazy, over_deg_bound=0, prot=True)
++    strat.opt_lazy = opt_lazy
+     print "INITIALIZED"
+-    branch(strat,[])
+-
++    branch(strat, [])
+ 
+ 
+-def GPS_with_non_binary_proof_path(G,proof_path, deg_bound,over_deg_bound):
+-    def step(strat,trace,  proof_path, pos, choice):
++def GPS_with_non_binary_proof_path(G, proof_path, deg_bound, over_deg_bound):
++    def step(strat, trace, proof_path, pos, choice):
+         print proof_path
+-        print "plugin: ",pos
++        print "plugin: ", pos
+         print "npairs", strat.npairs()
+-        strat=GroebnerStrategy(strat)
++        strat = GroebnerStrategy(strat)
+         print "npairs", strat.npairs()
+         print "npairs", strat.npairs()
+         for p in proof_path[pos][choice]:
+             print p
+             strat.add_generator_delayed(Polynomial(p))
+- 
++
+         print "npairs", strat.npairs()
+         print "pos:", pos
+-        strat=symmGB_F2_python(strat,deg_bound=deg_bound, over_deg_bound=over_deg_bound,prot=True)
++        strat = symmGB_F2_python(strat, deg_bound=deg_bound,
++            over_deg_bound=over_deg_bound, prot=True)
+         print "npairs", strat.npairs()
+-        pos=pos+1
+-        if pos>=len(proof_path):
++        pos = pos + 1
++        if pos >= len(proof_path):
+             print "OVER"
+-            strat=symmGB_F2_python(strat)
++            strat = symmGB_F2_python(strat)
+         if strat.containsOne():
+             pass
+         else:
+-            if pos>=len(proof_path):
++            if pos >= len(proof_path):
+                 print "npairs", strat.npairs()
+                 #strat.to_std_out()
+-                l=[p for p in strat]
+-                strat2=symmGB_F2_python(l)
++                l = [p for p in strat]
++                strat2 = symmGB_F2_python(l)
+                 #strat2.to_std_out()
+                 #bug: may contain Delayed polynomials
+-                print "!!!!!!! SOLUTION",trace
++                print "!!!!!!! SOLUTION", trace
+                 raise Exception
+                 #yield trace
+             else:
+-                branch(strat,trace+[(pos,choice)],proof_path,pos)
++                branch(strat, trace + [(pos, choice)], proof_path, pos)
+                 #workaround because of stack depth
+                 #step(strat,trace+[(var,val)],var-1, 0)
+                 #step(strat,trace+[(var,val)],var-1, 1)
+-                
+-    def branch(strat,trace, proof_path,pos):
++
++    def branch(strat, trace, proof_path, pos):
+         for i in xrange(len(proof_path[pos])):
+-            step(strat, trace,  proof_path, pos, i)
+- 
+-    strat=GroebnerStrategy(G[0].ring())
++            step(strat, trace, proof_path, pos, i)
++
++    strat = GroebnerStrategy(G[0].ring())
+     strat.add_generator(G[0])
+     for g in G[1:]:
+         strat.add_generator_delayed(g)
+-    branch(strat,[], proof_path, 0)
++    branch(strat, [], proof_path, 0)
++
+ 
+-def symmGB_F2_C(G,opt_exchange=True,
+-    deg_bound=1000000000000,opt_lazy=False,
++def symmGB_F2_C(G, opt_exchange=True,
++    deg_bound=1000000000000, opt_lazy=False,
+     over_deg_bound=0, opt_red_tail=True,
+     max_growth=2.0, step_factor=1.0,
+     implications=False, prot=False,
+-    full_prot=False,selection_size=1000,
+-    opt_allow_recursion=False, use_noro=False,use_faugere=False,
+-    ll=False,opt_linear_algebra_in_last_block=True,
+-    max_generators=None, red_tail_deg_growth=True, 
++    full_prot=False, selection_size=1000,
++    opt_allow_recursion=False, use_noro=False, use_faugere=False,
++    ll=False, opt_linear_algebra_in_last_block=True,
++    max_generators=None, red_tail_deg_growth=True,
+     modified_linear_algebra=True, matrix_prefix="",
+     draw_matrices=False):
+     #print implications
+     if use_noro:
+-        raise NotImplementedError, "noro not implemented for symmgb"    
+-    if (isinstance(G,list)):
+-        if len(G)==0:
++        raise NotImplementedError, "noro not implemented for symmgb"
++    if (isinstance(G, list)):
++        if len(G) == 0:
+             return []
+-            
+-            
+-        
+-        G=[Polynomial(g) for g in G]    
+-        strat=GroebnerStrategy(G[0].ring())
+-        strat.reduction_strategy.opt_red_tail=opt_red_tail
+-        strat.enabled_log=prot
+-        strat.opt_lazy=opt_lazy
+-        strat.opt_exchange=opt_exchange
+-        strat.reduction_strategy.opt_ll=ll
+-        strat.opt_allow_recursion=opt_allow_recursion
+-        strat.opt_linear_algebra_in_last_block=opt_linear_algebra_in_last_block
+-        strat.enabled_log=prot
+-        strat.opt_modified_linear_algebra=modified_linear_algebra
+-        strat.matrix_prefix=matrix_prefix
+-        strat.opt_draw_matrices=draw_matrices
+-        strat.reduction_strategy.opt_red_tail_deg_growth=red_tail_deg_growth
++
++        G = [Polynomial(g) for g in G]
++        strat = GroebnerStrategy(G[0].ring())
++        strat.reduction_strategy.opt_red_tail = opt_red_tail
++        strat.enabled_log = prot
++        strat.opt_lazy = opt_lazy
++        strat.opt_exchange = opt_exchange
++        strat.reduction_strategy.opt_ll = ll
++        strat.opt_allow_recursion = opt_allow_recursion
++        strat.opt_linear_algebra_in_last_block = (
++            opt_linear_algebra_in_last_block)
++        strat.enabled_log = prot
++        strat.opt_modified_linear_algebra = modified_linear_algebra
++        strat.matrix_prefix = matrix_prefix
++        strat.opt_draw_matrices = draw_matrices
++        strat.reduction_strategy.opt_red_tail_deg_growth = red_tail_deg_growth
+         #strat.add_generator(G[0])
+-        
+-        
+-        strat.redByReduced=False#True
+-        
++
++        strat.redByReduced = False  # True
++
+         #if PROT:
+         #    print "added first"
+-        for g in G:#[1:]:
++        for g in G:  # [1:]:
+             if not g.is_zero():
+                 strat.add_generator_delayed(g)
+     strat.symmGB_F2()
+@@ -630,20 +648,21 @@ def normal_form(poly, ideal, reduced=True):
+     >>> normal_form(x+y,[x,y])
+     0
+     """
+-    ring=poly.ring()
++    ring = poly.ring()
+     strat = ReductionStrategy(ring)
+-    strat.opt_red_tail=reduced
+-    ideal=[Polynomial(p) for p in ideal if p!=0]
+-    ideal= sorted(ideal, key=Polynomial.lead)
+-    last=None
++    strat.opt_red_tail = reduced
++    ideal = [Polynomial(p) for p in ideal if p != 0]
++    ideal = sorted(ideal, key=Polynomial.lead)
++    last = None
+     for p in ideal:
+-        if p.lead()!=last:
++        if p.lead() != last:
+             strat.add_generator(p)
+         else:
+-            warn("%s will not used for reductions"% p )
+-        last=p.lead()
++            warn("%s will not used for reductions" % p)
++        last = p.lead()
+     return strat.nf(poly)
+ 
++
+ def _test():
+     import doctest
+     doctest.testmod()
+diff --git a/pyroot/polybori/parallel.py b/pyroot/polybori/parallel.py
+index 8e3ac1c..03de588 100644
+--- a/pyroot/polybori/parallel.py
++++ b/pyroot/polybori/parallel.py
+@@ -3,16 +3,18 @@
+ 
+ #  parallel.py
+ #  PolyBoRi
+-#  
++#
+ #  Created by Michael Brickenstein on 2008-10-31.
+ #  Copyright 2008 The PolyBoRi Team
+-# 
++#
+ 
+ from polybori.PyPolyBoRi import if_then_else, CCuddNavigator, BooleSet
+-from polybori.PyPolyBoRi import Polynomial, Ring, WeakRingRef, Monomial, Variable
++from polybori.PyPolyBoRi import (Polynomial, Ring, WeakRingRef, Monomial,
++    Variable)
+ from polybori.gbcore import groebner_basis
+ from zlib import compress, decompress
+-import copy_reg    
++import copy_reg
++
+ 
+ def to_fast_pickable(l):
+     """
+@@ -22,11 +24,11 @@ def to_fast_pickable(l):
+     OUTPUT:
+         It is converted to a tuple consisting of
+         - codes referring to the polynomials
+-        - list of conversions of nodes. 
++        - list of conversions of nodes.
+             The nodes are sorted, that
+             n occurs before n.else_branch(), n.then_branch()
+             Nodes are only listed, if they are not constant.
+-    
++
+         A node is converted in this way:
+             0 -> 0
+             1 -> 1
+@@ -62,44 +64,44 @@ def to_fast_pickable(l):
+         >>> to_fast_pickable([x(0)*x(1), Polynomial(0, r), Polynomial(1, r), x(3)])
+         [[2, 0, 1, 4], [(0, 3, 0), (1, 1, 0), (3, 1, 0)]]
+     """
+-    if len(l)==0:
++    if len(l) == 0:
+         return [[], []]
+-    
+-    f=l[0]
+-    f=f.set()
+-    r=f.ring()
+-    one=r.one().navigation()
+-    zero=r.zero().navigation()
+-    nodes=set()
+-    
++
++    f = l[0]
++    f = f.set()
++    r = f.ring()
++    one = r.one().navigation()
++    zero = r.zero().navigation()
++    nodes = set()
++
+     def find_navs(nav):
+         if not nav in nodes and not nav.constant():
+             nodes.add(nav)
+             find_navs(nav.then_branch())
+             find_navs(nav.else_branch())
+     for f in l:
+-        f_nav=f.set().navigation()
++        f_nav = f.set().navigation()
+         find_navs(f_nav)
+ 
+-    nodes_sorted=sorted(nodes, key=CCuddNavigator.value)
+-    nodes2i={one:1,zero:0}
+-    for (i,n) in enumerate(nodes_sorted):
+-        nodes2i[n]=i+2
++    nodes_sorted = sorted(nodes, key=CCuddNavigator.value)
++    nodes2i = {one: 1, zero: 0}
++    for (i, n) in enumerate(nodes_sorted):
++        nodes2i[n] = i + 2
+ 
+     for i in xrange(len(nodes_sorted)):
+-        n=nodes_sorted[i]
+-        t=nodes2i[n.then_branch()]
+-        e=nodes2i[n.else_branch()]
+-        nodes_sorted[i]=(n.value(),t,e)
++        n = nodes_sorted[i]
++        t = nodes2i[n.then_branch()]
++        e = nodes2i[n.else_branch()]
++        nodes_sorted[i] = (n.value(), t, e)
+ 
+     return [[nodes2i[f.set().navigation()] for f in  l], nodes_sorted]
+ 
+ 
+-def from_fast_pickable(l,r):
++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: 
++    INPUT:
+         see OUTPUT of to_fast_pickable
+     OUTPUT:
+         a list of Boolean polynomials
+@@ -126,17 +128,18 @@ def from_fast_pickable(l,r):
+         >>> 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
++    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]
++        (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]
+ 
++
+ def _calculate_gb_with_keywords(args):
+     (I, kwds_as_single_arg) = args
+     import traceback
+@@ -149,29 +152,35 @@ def _calculate_gb_with_keywords(args):
+ def _decode_polynomial(code):
+     return from_fast_pickable(*code)[0]
+ 
++
+ def _encode_polynomial(poly):
+     return (to_fast_pickable([poly]), poly.ring())
+ 
++
+ def pickle_polynomial(self):
+-    return (_decode_polynomial, (_encode_polynomial(self),))
++    return (_decode_polynomial, (_encode_polynomial(self), ))
+ 
+ copy_reg.pickle(Polynomial, pickle_polynomial)
+ 
++
+ def pickle_bset(self):
+-    return (BooleSet, (Polynomial(self),))
++    return (BooleSet, (Polynomial(self), ))
+ 
+ copy_reg.pickle(BooleSet, pickle_bset)
+ 
++
+ def pickle_monom(self):
+-    return (Monomial, ([var for var in self.variables()],))
++    return (Monomial, ([var for var in self.variables()], ))
+ 
+ copy_reg.pickle(Monomial, pickle_monom)
+ 
++
+ def pickle_var(self):
+     return (Variable, (self.index(), self.ring()))
+ 
+ copy_reg.pickle(Variable, pickle_var)
+ 
++
+ def _decode_ring(code):
+     import os
+     (identifier, data, varnames, blocks) = code
+@@ -182,7 +191,7 @@ def _decode_ring(code):
+     except NameError:
+         _polybori_parallel_rings = dict()
+ 
+-    for key in [key for key in _polybori_parallel_rings 
++    for key in [key for key in _polybori_parallel_rings
+                 if not _polybori_parallel_rings[key][0]()]:
+         del _polybori_parallel_rings[key]
+ 
+@@ -200,7 +209,8 @@ def _decode_ring(code):
+         _polybori_parallel_rings[(ring.id(), os.getpid())] = storage_data
+ 
+     return ring
+-    
++
++
+ def _encode_ring(ring):
+     import os
+     identifier = (ring.id(), os.getpid())
+@@ -211,7 +221,7 @@ def _encode_ring(ring):
+     except NameError:
+         _polybori_parallel_rings = dict()
+ 
+-    for key in [key for key in _polybori_parallel_rings 
++    for key in [key for key in _polybori_parallel_rings
+                 if not _polybori_parallel_rings[key][0]()]:
+         del _polybori_parallel_rings[key]
+ 
+@@ -220,18 +230,21 @@ def _encode_ring(ring):
+     else:
+         nvars = ring.n_variables()
+         data = (nvars, ring.get_order_code())
+-        varnames = '\n'.join([str(ring.variable(idx)) for idx in xrange(nvars)])
++        varnames = '\n'.join([str(ring.variable(idx)) for idx in xrange(nvars)
++            ])
+         blocks = list(ring.blocks())
+         code = (identifier, data, compress(varnames), blocks[:-1])
+         _polybori_parallel_rings[identifier] = (WeakRingRef(ring), code)
+ 
+     return code
+ 
++
+ def pickle_ring(self):
+-    return (_decode_ring, (_encode_ring(self),))
++    return (_decode_ring, (_encode_ring(self), ))
+ 
+ copy_reg.pickle(Ring, pickle_ring)
+ 
++
+ def groebner_basis_first_finished(I, *l):
+     """
+     INPUT:
+@@ -240,7 +253,7 @@ def groebner_basis_first_finished(I, *l):
+     OUTPUT:
+         - tries to compute groebner_basis(I, **kwd) for kwd in l
+         - returns the result of the first terminated computation
+-    EXAMPLES:    
++    EXAMPLES:
+         >>> from polybori.PyPolyBoRi import Ring
+         >>> r=Ring(1000)
+         >>> ideal = [r.variable(1)*r.variable(2)+r.variable(2)+r.variable(1)]
+@@ -257,12 +270,13 @@ def groebner_basis_first_finished(I, *l):
+     pool = Pool(processes=len(l))
+     it = pool.imap_unordered(_calculate_gb_with_keywords,
+                              [(I, kwds) for kwds in l])
+-    res=it.next() 
++    res = it.next()
+ 
+     pool.terminate()
+ 
+     return res
+ 
++
+ def _test():
+     import doctest
+     doctest.testmod()
+diff --git a/pyroot/polybori/parsegat.py b/pyroot/polybori/parsegat.py
+index 8117129..6c199b5 100644
+--- a/pyroot/polybori/parsegat.py
++++ b/pyroot/polybori/parsegat.py
+@@ -1,9 +1,10 @@
+ #import pathadjuster
+-if __name__=='__main__':
++if __name__ == '__main__':
+     from sys import path as search_path
+     from os import path as file_path
+     search_path.append(file_path.join(file_path.dirname(__file__), '..'))
+ 
++
+ def _exists():
+     """PolyBoRi convention: checking optional components for prerequisites here
+ 
+@@ -17,8 +18,6 @@ def _exists():
+ 
+     return True
+ 
+-
+-
+ #from polybori.gbrefs import declare_ring
+ from polybori import *
+ from polybori.ll import ll_encode
+@@ -36,80 +35,93 @@ inter_max = 20000
+ input_max = 2000
+ state_max = 2000
+ 
+-#declare_ring([Block("x",gat_max),Block("xnext",next_max,reverse = True),Block("xoutput",output_max,reverse = True),Block("xinter",inter_max,reverse = True),Block("xinput",input_max,reverse = True),Block("xstate",state_max,reverse = True)],globals())
+-#input order is antitopological
+-#we reverse, when mapping to final variables
++# declare_ring([Block("x",gat_max),Block("xnext",next_max,reverse =
++# True),Block("xoutput",output_max,reverse =
++# True),Block("xinter",inter_max,reverse =
++# True),Block("xinput",input_max,reverse =
++# True),Block("xstate",state_max,reverse = True)],globals()) input order is
++# antitopological we reverse, when mapping to final variables
+ parser.add_option("--forward-iteration",
+-                  action="store_true", dest="forward", default = True,
++                  action="store_true", dest="forward", default=True,
+                   help="switch between forward and backward iteration")
+ 
+ parser.add_option("--backward-iteration",
+-                  action="store_false", dest="forward", default = True,
++                  action="store_false", dest="forward", default=True,
+                   help="switch between forward and backward iteration")
+ 
+ parser.add_option("--include-outputs",
+-                  action="store_true", dest="include_outputs", default = True,
++                  action="store_true", dest="include_outputs", default=True,
+                   help="include circuit outputs")
+ 
+-parser.add_option("--initialize-state",
+-                  action="store", dest="initialize", default="noinit",type="choice",choices=["noinit", "random", "zero"],
+-                  help="initialize state variables/only useful with forward iteration")
+-
++parser.add_option("--initialize-state", action="store", dest="initialize",
++    default="noinit", type="choice", choices=["noinit", "random", "zero"],
++    help="initialize state variables/only useful with forward iteration")
+ 
+ 
+-def parse_identifier(str,log,tokens):
++def parse_identifier(str, log, tokens):
+     return int(tokens[0])
+ 
+ 
+-def throw_away(str,log,tokens):
++def throw_away(str, log, tokens):
+     return "None"
+ 
+ assigned = set()
+ from random import Random
+ 
+ 
+-def add_negated(str,log,tokens):
++def add_negated(str, log, tokens):
+     p = tokens[1]
+     l = p.lead()
+-    if not l in assigned and r.randint(0,200)==0:
++    if not l in assigned and r.randint(0, 200) == 0:
+         assigned.add(l)
+-        print "NEG",p+1
+-        return p+1
++        print "NEG", p + 1
++        return p + 1
+     else:
+         return "NONE"
+ 
++
+ class FamiliarityException(Exception):
+     """docstring for FamiliarityException"""
++
+     def __init__(self):
+         super(FamiliarityException, self).__init__()
+-        
+-def fix_symbol_name(str,log,tokens):
+-    return tokens[0].replace("-","_").replace("]","").replace("[","").replace("/","_")
++
++
++def fix_symbol_name(str, log, tokens):
++    return (tokens[0].replace("-", "_").replace("]", "").replace("[", "").
++        replace("/", "_"))
++
++
+ class DeterminingEquation(object):
+     """docstring for DeterminingEquation"""
++
+     def __init__(self, variable, mapped_to):
+         super(DeterminingEquation, self).__init__()
+         self.variable = variable
+         self.mapped_to = mapped_to
++
+     def _get_equation(self):
+         return self.variable + self.mapped_to
+-    equation=property(_get_equation)
+-# be careful:
+-# for next state/output we directly generate mapped_to + value instead of introducing a variable and mapping it later
++    equation = property(_get_equation)
++
++
++# be careful: for next state/output we directly generate mapped_to + value
++# instead of introducing a variable and mapping it later
+ class VariableManager(object):
+     """docstring for VariableManager"""
+-    def __init__(self,ring, prefix="", initialize="noinit", **kwd):
++
++    def __init__(self, ring, prefix="", initialize="noinit", **kwd):
+         super(VariableManager, self).__init__()
+         self.ring = ring
+-        self.output=[]
+-        self.input=[]
+-        self.state=[]
+-        self.next=[]
++        self.output = []
++        self.input = []
++        self.state = []
++        self.next = []
+         self.deletion_candidates = []
+-        self.intermediate=[]
+-        
+-        self.next_state_equations=[]
+-        self.intermediate_equations=[]
++        self.intermediate = []
++
++        self.next_state_equations = []
++        self.intermediate_equations = []
+         self.__map = dict()
+         self.prefix = prefix
+         self.initialize = initialize
+@@ -118,168 +130,176 @@ class VariableManager(object):
+         self.tails = []
+         for (k, v) in kwd.iteritems():
+             setattr(self, k, v)
++
+     def gauss(self, determining_equations):
+-        l=[]
+-        res=[]
+-        output_set=set(self.output)
++        l = []
++        res = []
++        output_set = set(self.output)
+         for p in determining_equations:
+-            eq=p.equation
+-            if not p.variable in output_set and eq.deg()==1: 
+-                    assert eq.lead()==p.variable
+-                    l.append(eq)
+-                    self.deletion_candidates.append(p.variable)
++            eq = p.equation
++            if not p.variable in output_set and eq.deg() == 1:
++                assert eq.lead() == p.variable
++                l.append(eq)
++                self.deletion_candidates.append(p.variable)
+             else:
+                 res.append(p)
+-        l=gauss_on_polys(l)
++        l = gauss_on_polys(l)
+         for p in l:
+-            res.append(DeterminingEquation(p.lead(),p+p.lead()))
++            res.append(DeterminingEquation(p.lead(), p + p.lead()))
+         return res
++
+     def ideals(self):
+         def sort_key(p):
+             return p.navigation().value()
++
+         def my_sort(l):
+             return sorted(l, key=sort_key)
+         #self.intermediate_equations = self.gauss(self.intermediate_equations)
+-        tail_variables =  set(used_vars_set([e.mapped_to for e in chain(self.next_state_equations, self.intermediate_equations)]).variables())
+-        to_delete=[]
++        tail_variables = set(used_vars_set([e.mapped_to for e in chain(self.
++            next_state_equations, self.intermediate_equations)]).variables())
++        to_delete = []
+         for v in self.deletion_candidates:
+             if not v in tail_variables:
+                 to_delete.append(v)
+-        to_delete=set(to_delete)
+-        self.intermediate_equations=[e for e in self.intermediate_equations
++        to_delete = set(to_delete)
++        self.intermediate_equations = [e for e in self.intermediate_equations
+             if not e.variable in to_delete]
+-        
+-        #we don't delete the variable itself, as we will confuse gluemultipliers,that looks on the lengths of self.intermediate...
++
++        # we don't delete the variable itself, as we will confuse
++        # gluemultipliers,that looks on the lengths of self.intermediate...
+         def equations(determining_equations):
+             return [e.equation for e in determining_equations]
+-        ideal_state=[]
++        ideal_state = []
+         ideal_next_state = equations(self.next_state_equations)
+         ideal_intermediate = equations(self.intermediate_equations)
+-        
+-        if self.initialize!="noinit":
+-            if self.initialize=="zero":
++
++        if self.initialize != "noinit":
++            if self.initialize == "zero":
+                 initializer = zero_fun
+             else:
+                 initializer = random_bit
+             for v in variables:
+-                if str(v)[:1]=="s":
+-                    ideal_state.append(v+initializer())
+-        
++                if str(v)[:1] == "s":
++                    ideal_state.append(v + initializer())
++
+         return [
+             my_sort(self.apply_map(i)) for i in
+-            (ideal_state,ideal_intermediate, ideal_next_state)]
++            (ideal_state, ideal_intermediate, ideal_next_state)]
++
+     def set_variable_name(self, i, name):
+-        _set_variable_name(self.ring, i, self.prefix+name)
+-        
+-    def parse_output_action(self,str,log,tokens):
++        _set_variable_name(self.ring, i, self.prefix + name)
++
++    def parse_output_action(self, str, log, tokens):
+         p = Polynomial(tokens[1])
+         #self.output.append(p)
+         #mapped_to = xoutput(len(self.output)-1)
+         mapped_to = self.xoutput(len(self.output))
+         self.output.append(mapped_to)
+-        self.set_variable_name(mapped_to.index(),"out_"+tokens[2])
++        self.set_variable_name(mapped_to.index(), "out_" + tokens[2])
+         self.tails.append(p)
+         if self.include_outputs:
+-            self.intermediate_equations.append(DeterminingEquation(mapped_to, p))
+-            return mapped_to+p
++            self.intermediate_equations.append(DeterminingEquation(mapped_to,
++                p))
++            return mapped_to + p
+         else:
+             return "NONE"
+-    
+-    
+-    def parse_buffer_action(self,str,log,tokens):
++
++    def parse_buffer_action(self, str, log, tokens):
+         return "NONE"
+-    
+-    def parse_next_state_action(self,str,log,tokens):
++
++    def parse_next_state_action(self, str, log, tokens):
+         p = Polynomial(tokens[1])
+         #self.next.append(p)
+         #mapped_to = xnext(len(self.next)-1)
+         mapped_to = self.xnext(len(self.next))
+         self.next.append(mapped_to)
+-        self.set_variable_name(mapped_to.index(),"nstate_"+tokens[2])
++        self.set_variable_name(mapped_to.index(), "nstate_" + tokens[2])
+         self.next_state_equations.append(DeterminingEquation(mapped_to, p))
+         self.tails.append(p)
+-        return mapped_to+p
+-    def parse_state_action(self,str,log,tokens):
++        return mapped_to + p
++
++    def parse_state_action(self, str, log, tokens):
+         p = self.x(tokens[0])
+         #self.state.append(p)
+         #mapped_to = xstate(len(self.state)-1)
+         mapped_to = self.xstate(len(self.state))
+         self.state.append(mapped_to)
+-        self.set_variable_name(mapped_to.index(),"state_"+tokens[2])
+-        self.map(p,mapped_to)
++        self.set_variable_name(mapped_to.index(), "state_" + tokens[2])
++        self.map(p, mapped_to)
+         return "NONE"
+-    def parse_input_action(self,str,log,tokens):
++
++    def parse_input_action(self, str, log, tokens):
+         p = self.x(tokens[0])
+         #self.input.append(p)
+         #mapped_to = xinput(len(self.input)-1)
+         mapped_to = self.xinput(len(self.input))
+         self.input.append(mapped_to)
+-        self.set_variable_name(mapped_to.index(),"in_"+tokens[2])
+-        self.map(p,mapped_to)
++        self.set_variable_name(mapped_to.index(), "in_" + tokens[2])
++        self.map(p, mapped_to)
+         return "NONE"
+-    
++
+     def evaluates_to_variables(self, signal):
+-        ands=self.ands[signal]
++        ands = self.ands[signal]
+         return list(
+             used_vars_set(ands).variables())
+-    
+-    
++
+     def eval_and_gat(self, lit, inputs=None):
+         if inputs is None:
+-            inputs=self.ands[lit.lex_lead()]
+-        assert len(inputs)>0
+-        res=inputs[0]
++            inputs = self.ands[lit.lex_lead()]
++        assert len(inputs) > 0
++        res = inputs[0]
+         for i in inputs[1:]:
+-            res=res*i
++            res = res * i
+         if lit.has_constant_part():
+-            res=res+1
++            res = res + 1
+         return res
++
+     def simplified_product(self, out, op1, op2):
+-        
+-        if op1.deg()==1 and op2.deg()==1:
+-            op1v=op1.lex_lead()
+-            op2v=op2.lex_lead()
+-        
+-        if op1v not in self.xors\
+-            and op2v not in self.xors\
+-            and op1v in self.ands\
++
++        if op1.deg() == 1 and op2.deg() == 1:
++            op1v = op1.lex_lead()
++            op2v = op2.lex_lead()
++
++        if op1v not in self.xors \
++            and op2v not in self.xors \
++            and op1v in self.ands \
+             and op2v in self.ands:
+-            mapped_to=[p for p in chain(self.ands[op1v], self.ands[op2v])]
++            mapped_to = [p for p in chain(self.ands[op1v], self.ands[op2v])]
+             for p in mapped_to:
+-                if p.deg()!=1:
+-                    return op1*op2
+-            mapped_to=set([p.lex_lead() for p in mapped_to])
++                if p.deg() != 1:
++                    return op1 * op2
++            mapped_to = set([p.lex_lead() for p in mapped_to])
+             #print >>stderr, op1, op2, mapped_to
+-            if len(mapped_to)<=2:
++            if len(mapped_to) <= 2:
+                 #xor pattern
+                 self.deletion_candidates.extend([op1v, op2v])
+-                assert op1.vars_as_monomial().deg()==1
+-                assert op2.vars_as_monomial().deg()==1
+-                op1=self.eval_and_gat(op1)
+-                op2=self.eval_and_gat(op2)
+-                outer_res=self.eval_and_gat(out, [op1, op2])
+-                self.xors[out]=outer_res
++                assert op1.vars_as_monomial().deg() == 1
++                assert op2.vars_as_monomial().deg() == 1
++                op1 = self.eval_and_gat(op1)
++                op2 = self.eval_and_gat(op2)
++                outer_res = self.eval_and_gat(out, [op1, op2])
++                self.xors[out] = outer_res
+             else:
+                 try:
+-                    for (op1, op1v,op2, op2v) in \
+-                        [(op1, op1v,op2, op2v), (op2, op2v,op1, op1v)]:
++                    for (op1, op1v, op2, op2v) in \
++                        [(op1, op1v, op2, op2v), (op2, op2v, op1, op1v)]:
+                         (op1e, op2e) = [
+-                            self.evaluates_to_variables(left_parent) 
++                            self.evaluates_to_variables(left_parent)
+                             for left_parent in (op1v, op2v)]
+-                        for (i,s) in enumerate(op2e):
++                        for (i, s) in enumerate(op2e):
+                             if s in self.xors or s not in self.ands:
+                                 continue
+-                            
+-                            if self.evaluates_to_variables(s)==op1e:
++
++                            if self.evaluates_to_variables(s) == op1e:
+                                 raise FamiliarityException()
+                 except FamiliarityException:
+-                    op1=self.eval_and_gat(op1)
+-                    op2_inputs=list(self.ands[op2v])
+-                    for (i,s2) in enumerate(op2_inputs):
+-                        if s2.lex_lead()==s:
+-                            op2_inputs[i]=self.eval_and_gat(s2)
+-                    op2=self.eval_and_gat(op2, inputs=op2_inputs)
+-                    self.deletion_candidates.extend((s,op1v, op2v))
++                    op1 = self.eval_and_gat(op1)
++                    op2_inputs = list(self.ands[op2v])
++                    for (i, s2) in enumerate(op2_inputs):
++                        if s2.lex_lead() == s:
++                            op2_inputs[i] = self.eval_and_gat(s2)
++                    op2 = self.eval_and_gat(op2, inputs=op2_inputs)
++                    self.deletion_candidates.extend((s, op1v, op2v))
+                 else:
+                     # pattern
+                     # 34 AND ~16 ~15
+@@ -287,89 +307,91 @@ class VariableManager(object):
+                     # 36 AND 16 15
+                     # 37 AND ~14 36
+                     # 38 AND ~37 ~35
+-                    
++
+                     try:
+                         (op1a, op2a) = [self.ands.get(v)
+                             for v in (op1v, op2v)]
+-                        assert len(op1a)==2
+-                        assert len(op2a)==2
+-                        print >>stderr, "+"
+-                        for op1a in [[op1a[0],op1a[1]], op1a]:
++                        assert len(op1a) == 2
++                        assert len(op2a) == 2
++                        print >> stderr, "+"
++                        for op1a in [[op1a[0], op1a[1]], op1a]:
+                             for op2a in [[op2a[0], op2a[1]], op2a]:
+-                                print >>stderr, op1a[0], op2a[0]
+-                                if op1a[0]==op2a[0]+1:
+-                                    print >>stderr, "-"
+-                                    if op1a[1] in self.ands and\
+-                                        op2a[1] in self.ands and\
+-                                        op1a[1] not in self.xors\
++                                print >> stderr, op1a[0], op2a[0]
++                                if op1a[0] == op2a[0] + 1:
++                                    print >> stderr, "-"
++                                    if op1a[1] in self.ands and \
++                                        op2a[1] in self.ands and \
++                                        op1a[1] not in self.xors \
+                                         and op2a[1] not in self.xors:
+-                                            if set(self.ands[op1a[1]])==\
+-                                                set([
+-                                                    1+s for s in self.ands[op2a[1]]
+-                                                ]):
+-                                                raise FamiliarityException
++                                        if set(self.ands[op1a[1]]) == set([1
++                                            + s for s in self.ands[op2a[1]]]):
++                                            raise FamiliarityException
+                     except FamiliarityException:
+-                        self.deletion_candidates.extend([op1v, op2v,op2a[1].lex_lead(), op1a[1].lex_lead()])
++                        self.deletion_candidates.extend([op1v, op2v, op2a[1].
++                            lex_lead(), op1a[1].lex_lead()])
+                         for group in (op2a, op1a):
+                             group[1] = self.eval_and_gat(group[1])
+-                        (op1, op2)=[
++                        (op1, op2) = [
+                             self.eval_and_gat(op, inputs) for (op, inputs)
+                             in [(op1, op1a), (op2, op2a)]]
+-                        
+-                        
+-        return op1*op2
+-    def parse_and_action(self,string,log,tokens):
+-        
++
++        return op1 * op2
++
++    def parse_and_action(self, string, log, tokens):
++
+         inter = self.x(tokens[0])
+         op1 = tokens[2]
+         op2 = tokens[3]
+         #self.intermediate.append(inter)
+         #mapped_to = xinter(len(self.intermediate)-1)
+         mapped_to = self.xinter(len(self.intermediate))
+-        self.ands[inter]=(op1, op2)
++        self.ands[inter] = (op1, op2)
+         self.intermediate.append(mapped_to)
+-        self.set_variable_name(mapped_to.index(),"y"+str(tokens[0]))
+-        self.map(inter,mapped_to)
++        self.set_variable_name(mapped_to.index(), "y" + str(tokens[0]))
++        self.map(inter, mapped_to)
+         tail = self.simplified_product(inter, op1, op2)
+         self.tails.append(tail)
+-        eq = inter+tail
++        eq = inter + tail
+         self.intermediate_equations.append(DeterminingEquation(inter, tail))
+         return eq
+-    def map(self,from_,to):
+-        self.__map[from_]=to
+-    def apply_map(self,eq):
+-        encoded = ll_encode((k+v for (k,v) in self.__map.items()))
+-        return [ll_red_nf_noredsb(p,encoded) for p in eq]
+-    
+-    
+-    def parse_sign(self, str,log,tokens):
+-        if list(tokens)!=[0]:
++
++    def map(self, from_, to):
++        self.__map[from_] = to
++
++    def apply_map(self, eq):
++        encoded = ll_encode((k + v for (k, v) in self.__map.items()))
++        return [ll_red_nf_noredsb(p, encoded) for p in eq]
++
++    def parse_sign(self, str, log, tokens):
++        if list(tokens) != [0]:
+             return [1]
+         else:
+             return tokens
+-    def parse_idenfifier_ref(self, str,log,tokens):
+-        if tokens[1] in (0,1):
++
++    def parse_idenfifier_ref(self, str, log, tokens):
++        if tokens[1] in (0, 1):
+             #from sys import stderr
+             #stderr.write("TOKENS:"+repr(tokens))
+             #stderr.flush()
+-            return Polynomial(tokens[0]+tokens[1])
+-        return tokens[0]+self.x(tokens[1])
+-        
++            return Polynomial(tokens[0] + tokens[1])
++        return tokens[0] + self.x(tokens[1])
++
+ 
+ def generate_gat_bnf(manager):
+ 
+-    from pyparsing import Literal,CaselessLiteral,Word,Combine,Group,Optional,\
+-        ZeroOrMore,Forward,nums,alphas, Or, restOfLine,OneOrMore,restOfLine,\
+-        alphanums
++    from pyparsing import (Literal, CaselessLiteral, Word, Combine, Group,
++        Optional, ZeroOrMore, Forward, nums, alphas, Or, restOfLine,
++        OneOrMore, restOfLine, alphanums)
+ 
+     identifier = Word(nums).setParseAction(parse_identifier)
+-    symbolic_name=(Word(alphanums+"_-[]/",alphanums+"_-[]/")).setParseAction(fix_symbol_name)
++    symbolic_name = (Word(alphanums + "_-[]/", alphanums + "_-[]/")). \
++        setParseAction(fix_symbol_name)
+     meta = ZeroOrMore(
+     Or(
+     [
+     CaselessLiteral("WRITER"),
+     CaselessLiteral("DESIGN"),
+-    CaselessLiteral("ORIGIN")])+restOfLine)
++    CaselessLiteral("ORIGIN")]) + restOfLine)
+     end = CaselessLiteral("END")
+     and_ = CaselessLiteral("AND")
+     input_ = CaselessLiteral("INPUT")
+@@ -377,22 +399,31 @@ def generate_gat_bnf(manager):
+     nstate = CaselessLiteral("NSTATE")
+     output = CaselessLiteral("OUTPUT")
+     buffer_ = CaselessLiteral("BUFFER")
+-    identifier_ref=\
+-        (Optional(Literal("~"),default = 0).setParseAction(
+-        manager.parse_sign)+identifier).setParseAction(
++    identifier_ref = \
++        (Optional(Literal("~"), default=0).setParseAction(
++        manager.parse_sign) + identifier).setParseAction(
+             manager.parse_idenfifier_ref)
+-    
+-    input_line = (identifier + input_ + symbolic_name).setParseAction(manager.parse_input_action)
+-    and_line =(identifier + and_ + identifier_ref+identifier_ref).setParseAction(manager.parse_and_action)
+-    buffer_line = (buffer_ +identifier_ref + symbolic_name).setParseAction(manager.parse_buffer_action)
+-    output_line=(output+ identifier_ref + symbolic_name).setParseAction(manager.parse_output_action)
+-    state_line=(identifier + state + symbolic_name).setParseAction(manager.parse_state_action)
+-    nstate_line=(nstate +identifier_ref + symbolic_name).setParseAction(manager.parse_next_state_action)
+-    assignment = Or([output_line,and_line,input_line,state_line,nstate_line, buffer_line])
+-    
+-    gat = meta+OneOrMore(assignment)+end
++
++    input_line = (identifier + input_ + symbolic_name).setParseAction(manager.
++        parse_input_action)
++    and_line = (identifier + and_ + identifier_ref + identifier_ref). \
++        setParseAction(manager.parse_and_action)
++    buffer_line = (buffer_ + identifier_ref + symbolic_name).setParseAction(
++        manager.parse_buffer_action)
++    output_line = (output + identifier_ref + symbolic_name).setParseAction(
++        manager.parse_output_action)
++    state_line = (identifier + state + symbolic_name).setParseAction(manager. \
++        parse_state_action)
++    nstate_line = (nstate + identifier_ref + symbolic_name).setParseAction(
++        manager.parse_next_state_action)
++    assignment = Or([output_line, and_line, input_line, state_line,
++        nstate_line, buffer_line])
++
++    gat = meta + OneOrMore(assignment) + end
+     return gat
+ generator = Random(123)
++
++
+ def parse(f, manager):
+     f = open(f)
+     content = f.read()
+@@ -400,28 +431,34 @@ def parse(f, manager):
+     parsed = bnf.parseString(content)
+     f.close()
+ 
++
+ def zero_fun():
+     return 0
+ 
++
+ def random_bit():
+-    return generator.randint(0,1)
++    return generator.randint(0, 1)
++
+ 
+-def format_grouped(l,group_size = 10,indent = 0):
++def format_grouped(l, group_size=10, indent=0):
+     s = StringIO()
+     s.write("[")
+-    last = len(l)-1
+-    for (i,e) in enumerate(l):
+-        if i%group_size==0:
+-            s.write("\n"+indent*" ")
++    last = len(l) - 1
++    for (i, e) in enumerate(l):
++        if i % group_size == 0:
++            s.write("\n" + indent * " ")
+         s.write(e)
+-        if i!=last:
++        if i != last:
+             s.write(", ")
+     s.write("]")
+     return s.getvalue()
+ 
+-def generate_three_ideal_output(ideal_state, ideal_intermediate, ideal_next_state, variables):
+-    print "declare_ring("+format_grouped([repr(str(v)) for v in variables],indent = 4) + ")"
+-    print "block_start_hints="+repr(block_starts)
++
++def generate_three_ideal_output(ideal_state, ideal_intermediate,
++    ideal_next_state, variables):
++    print "declare_ring(" + format_grouped([repr(str(v)) for v in variables],
++        indent=4) + ")"
++    print "block_start_hints=" + repr(block_starts)
+     print "ideal_intermediate=["
+     print ",\n".join((str(p) for p in ideal_intermediate))
+     print "]"
+@@ -433,34 +470,34 @@ def generate_three_ideal_output(ideal_state, ideal_intermediate, ideal_next_stat
+     print "]"
+     print "ideal = ideal_state+ideal_next_state+ideal_intermediate"
+ 
+-if __name__=='__main__':
++if __name__ == '__main__':
+     (options, args) = parser.parse_args()
+     kwd_args = dict()
+     ring = declare_ring([
+         "t",
+-        Block("x",gat_max, reverse=True),
+-        Block("xnext",next_max,reverse = True),
+-        Block("xoutput",output_max,reverse = True),
+-        Block("xinter",inter_max,reverse = True),
+-        Block("xinput",input_max,reverse = True),
+-        Block("xstate",state_max,reverse = True)],kwd_args)
+-    
+-    manager = VariableManager(ring = ring, include_outputs = options.include_outputs,
+-        initialize = options.initialize,
+-        **kwd_args
+-    )
+-    
++        Block("x", gat_max, reverse=True),
++        Block("xnext", next_max, reverse=True),
++        Block("xoutput", output_max, reverse=True),
++        Block("xinter", inter_max, reverse=True),
++        Block("xinput", input_max, reverse=True),
++        Block("xstate", state_max, reverse=True)], kwd_args)
++
++    manager = VariableManager(ring=ring, include_outputs=options.
++        include_outputs, initialize=options.initialize, **kwd_args)
++
+     from sys import argv
+     f = args[0]
+-    
++
+     parse(f, manager)
+-    (ideal_state,ideal_intermediate, ideal_next_state)=manager.ideals()
++    (ideal_state, ideal_intermediate, ideal_next_state) = manager.ideals()
+     ideal = ideal_state + ideal_intermediate + ideal_next_state
+-    
+-    variables=[]
++
++    variables = []
+     used_vars = set(used_vars_set(ideal).variables())
+     if not options.forward:
+-        variables = list(chain(reversed(manager.next),reversed(manager.output),reversed(manager.intermediate),reversed(manager.input),reversed(manager.state)))
++        variables = list(chain(reversed(manager.next), reversed(manager.output
++            ), reversed(manager.intermediate), reversed(manager.input),
++            reversed(manager.state)))
+     else:
+         variables = list(
+             chain(reversed(manager.output),
+@@ -468,16 +505,15 @@ if __name__=='__main__':
+             reversed(manager.input),
+             reversed(manager.state),
+             reversed(manager.next)))
+-    variables=["t"]+variables
+-    beginnings=[str(v)[:1] for v in variables]
+-    block_starts=[]
++    variables = ["t"] + variables
++    beginnings = [str(v)[:1] for v in variables]
++    block_starts = []
+     last = beginnings[0]
+-    
+-    for (i,s) in enumerate(beginnings):
+-        if s!=last:
++
++    for (i, s) in enumerate(beginnings):
++        if s != last:
+             block_starts.append(i)
+         last = s
+-    
+-    generate_three_ideal_output(ideal_state,ideal_intermediate, ideal_next_state, variables)
+-
+ 
++    generate_three_ideal_output(ideal_state, ideal_intermediate,
++        ideal_next_state, variables)
+diff --git a/pyroot/polybori/partial.py b/pyroot/polybori/partial.py
+index f3fb64c..d058cd0 100644
+--- a/pyroot/polybori/partial.py
++++ b/pyroot/polybori/partial.py
+@@ -1,36 +1,49 @@
+-from polybori import BooleSet,interpolate_smallest_lex
++from polybori import BooleSet, interpolate_smallest_lex
++
+ 
+ class PartialFunction(object):
+     """docstring for PartialFunction"""
+-    def __init__(self, zeros,ones):
++
++    def __init__(self, zeros, ones):
+         super(PartialFunction, self).__init__()
+         self.zeros = zeros.set()
+         self.ones = ones.set()
++
+     def interpolate_smallest_lex(self):
+-        return interpolate_smallest_lex(self.zeros,self.ones)
++        return interpolate_smallest_lex(self.zeros, self.ones)
++
+     def __str__(self):
+-        return "PartialFunction(zeros="+str(self.zeros)+", ones="+str(self.ones)+")"
++        return "PartialFunction(zeros=" + str(self.zeros) + ", ones=" + str(
++            self.ones) + ")"
++
+     def definedOn(self):
+         return self.zeros.union(self.ones)
+-    def __add__(self,other):
+-        domain=self.definedOn().intersect(other.definedOn())
+-        zeros=self.zeros.intersect(other.zeros).union(self.ones.intersect(other.ones))
+-        ones=self.zeros.intersect(other.ones).union(self.ones.intersect(other.zeros))
++
++    def __add__(self, other):
++        domain = self.definedOn().intersect(other.definedOn())
++        zeros = self.zeros.intersect(other.zeros).union(self.ones.intersect(
++            other.ones))
++        ones = self.zeros.intersect(other.ones).union(self.ones.intersect(
++            other.zeros))
+         assert zeros.diff(domain).empty()
+         assert ones.diff(domain).empty()
+-        return PartialFunction(zeros,ones)
++        return PartialFunction(zeros, ones)
++
+     def __repr__(self):
+         return str(self)
+-        
+-    def __mul__(self,other):
+-        zeros=self.zeros.union(other.zeros)
+-        ones=self.ones.intersect(other.ones)
+-        return PartialFunction(zeros,ones)
+-    def __or__(self,other):
+-        zeros=self.zeros.intersect(other.zeros)
+-        ones=self.ones.union(other.ones)
+-        return PartialFunction(zeros,ones)
+-    def __xor__(self,other):
+-        return self+other
+-    def __and__(self,other):
+-        return self*other
++
++    def __mul__(self, other):
++        zeros = self.zeros.union(other.zeros)
++        ones = self.ones.intersect(other.ones)
++        return PartialFunction(zeros, ones)
++
++    def __or__(self, other):
++        zeros = self.zeros.intersect(other.zeros)
++        ones = self.ones.union(other.ones)
++        return PartialFunction(zeros, ones)
++
++    def __xor__(self, other):
++        return self + other
++
++    def __and__(self, other):
++        return self * other
+diff --git a/pyroot/polybori/plot.py b/pyroot/polybori/plot.py
+index 198f82c..64c8b23 100644
+--- a/pyroot/polybori/plot.py
++++ b/pyroot/polybori/plot.py
+@@ -4,11 +4,12 @@
+ plot.py
+ 
+ Created by Michael Brickenstein on 2008-10-17.
+-Copyright (c) 2008 The PolyBoRi Team. 
++Copyright (c) 2008 The PolyBoRi Team.
+ 
+ 
+ """
+ 
++
+ def _exists():
+     """PolyBoRi convention: checking optional components for prerequisites here
+ 
+@@ -29,21 +30,19 @@ def _exists():
+         out = open(devnull)
+         process = Popen(["dot", "-V"], stderr=out, stdout=out)
+         out.close()
+-    except:                           
+-        return False   
++    except:
++        return False
+ 
+     return True
+ 
+-
+ import sys
+ import os
+ from polybori.PyPolyBoRi import Ring, Polynomial, BooleSet
+ from subprocess import Popen, PIPE
+ 
+-
+-graph_template="""
++graph_template = """
+ digraph polynomial{
+-graph [ 
++graph [
+ ordering="out"
+ #if highlight_monomial
+ , label = "${display_monomial(highlight_monomial)}"
+@@ -62,7 +61,7 @@ ${identifier(n)} -> ${identifier(n.then_branch())} [color="${color_then}", arrow
+ }
+ """
+ 
+-graph_template_jinja="""
++graph_template_jinja = """
+ digraph polynomial{
+ {% if landscape %}
+ rankdir=LR;
+@@ -85,9 +84,9 @@ graph [ ordering="out"
+ }
+ """
+ 
++ELSE = "else"
++THEN = "then"
+ 
+-ELSE="else"
+-THEN="then"
+ 
+ def render_genshi(data_dict):
+     from genshi.template import TextTemplate
+@@ -95,34 +94,38 @@ def render_genshi(data_dict):
+     stream = tmpl.generate(**data_dict)
+     return str(stream)
+ 
++
+ def render_jinja(data_dict):
+     try:
+         from jinja2 import Environment
+     except:
+-        from jinja import Environment        
++        from jinja import Environment
+     env = Environment()
+     tmpl = env.from_string(graph_template_jinja)
+     return tmpl.render(**data_dict)
+-    
++
++
+ def monomial_path_in_zdd(mon, graph):
+-    res=[]
++    res = []
+     if not mon in BooleSet(graph):
+         raise ValueError
+-    graph_nav=BooleSet(graph).navigation()
+-    mon_nav=BooleSet(mon).navigation()
++    graph_nav = BooleSet(graph).navigation()
++    mon_nav = BooleSet(mon).navigation()
+     while not mon_nav.constant():
+-        while graph_nav.value()<mon_nav.value():
++        while graph_nav.value() < mon_nav.value():
+             res.append((graph_nav, ELSE))
+-            graph_nav=graph_nav.else_branch()
+-        assert mon_nav.value()==graph_nav.value()
+-        res.append((graph_nav,THEN))
+-        mon_nav=mon_nav.then_branch()
+-        graph_nav=graph_nav.then_branch()
++            graph_nav = graph_nav.else_branch()
++        assert mon_nav.value() == graph_nav.value()
++        res.append((graph_nav, THEN))
++        mon_nav = mon_nav.then_branch()
++        graph_nav = graph_nav.then_branch()
+     while not graph_nav.constant():
+         res.append((graph_nav, ELSE))
+-        graph_nav=graph_nav.else_branch()
++        graph_nav = graph_nav.else_branch()
+     return dict(res)
+-def plot(p, filename, colored=True,format="png", 
++
++
++def plot(p, filename, colored=True, format="png",
+     highlight_monomial=None, fontsize=14,
+     template_engine='jinja', landscape=False
+     ):
+@@ -135,46 +138,48 @@ def plot(p, filename, colored=True,format="png",
+     >>> plot(x(1)+x(0),"/dev/null", colored=True)
+     >>> plot(x(1)+x(0),"/dev/null", colored=False)
+     """
+-    THICK_PEN=5
+-    highlight_path=dict()
++    THICK_PEN = 5
++    highlight_path = dict()
+     if highlight_monomial:
+-        highlight_path=monomial_path_in_zdd(highlight_monomial, p)
++        highlight_path = monomial_path_in_zdd(highlight_monomial, p)
++
+     def display_monomial(m):
+-        return unicode(m).replace("*",u"⋅")
++        return unicode(m).replace("*", u"⋅")
++
+     def penwidth_else(n):
+-        if n in highlight_path and highlight_path[n]==ELSE:
++        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:
++        if n in highlight_path and highlight_path[n] == THEN:
+             return THICK_PEN
+         return 1
+     if not colored:
+-        color_then="black"
+-        color_else="black"
++        color_then = "black"
++        color_else = "black"
+     else:
+-        color_then="red"
+-        color_else="blue"
+-    
+-    
++        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()
++    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()
++    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])
++        return "n" + str(node_to_int[n])
++
+     def label(n):
+         if n.constant():
+             if n.terminal_one():
+@@ -183,63 +188,66 @@ def plot(p, filename, colored=True,format="png",
+                 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)
++    renderers = dict(genshi=render_genshi, jinja=render_jinja)
+ 
+-    dot_input=renderers[template_engine](locals())
++    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)
++        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()
+-    
+-        
++
++
+ def main():
+-    r=Ring(1000)
++    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)]))
++    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)]),
++    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(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
++    Polynomial(power_set([x(i) for i in xrange(10)])) + 1
+     ]
+-    for colored in [True,False]:
++    for colored in [True, False]:
+         if colored:
+-            colored_suffix="_colored"
++            colored_suffix = "_colored"
+         else:
+-            colored_suffix=""
++            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)
++            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)
+                 #system("dot -Tpng -o "+png_file+" " + dot_file)
+-        
++
+ if __name__ == '__main__':
+     main()
+diff --git a/pyroot/polybori/randompoly.py b/pyroot/polybori/randompoly.py
+index edb9ef8..c240a9d 100644
+--- a/pyroot/polybori/randompoly.py
++++ b/pyroot/polybori/randompoly.py
+@@ -1,32 +1,36 @@
+-from polybori.PyPolyBoRi import Monomial, random_set, Polynomial,\
++from polybori.PyPolyBoRi import Monomial, random_set, Polynomial, \
+ set_random_seed, Ring, ll_red_nf_redsb, Variable
+ from polybori.ll import ll_encode
+ from random import Random
+ from pprint import pprint, pformat
+ from polybori.blocks import declare_ring
+ 
+-def gen_random_poly(ring, l,deg,vars_set,seed=123):
+ 
+-    myrange=vars_set
+-    r=Random(seed)
++def gen_random_poly(ring, l, deg, vars_set, seed=123):
++
++    myrange = vars_set
++    r = Random(seed)
++
+     def helper(samples):
+-        if samples==0:
++        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)
++        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()))
++        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
+ 
+-def sparse_random_system(ring, number_of_polynomials, variables_per_polynomial, degree, random_seed=None):
++
++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).
+@@ -42,38 +46,44 @@ def sparse_random_system(ring, number_of_polynomials, variables_per_polynomial,
+     if random_seed is not None:
+         set_random_seed(random_seed)
+     random_generator = Random(random_seed)
+-    solutions=[]
++    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)
++        solutions.append(v + random_generator.randint(0, 1))
++    solutions = ll_encode(solutions)
+     res = []
+-    while len(res)<number_of_polynomials:
+-        variables_as_monomial=Monomial(
++    while len(res) < number_of_polynomials:
++        variables_as_monomial = Monomial(
+             random_generator.sample(
+-                variables, 
++                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:
++        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
++    res = [p + ll_red_nf_redsb(p, solutions) for p in res]
++    # evaluate it to guarantee a solution
+     return res
+ 
++
+ def sparse_random_system_data_file_content(
+     number_of_variables, **kwds):
+     r"""
+     >>> sparse_random_system_data_file_content(10, number_of_polynomials = 5, variables_per_polynomial = 3, degree=2, random_seed=123) # doctest: +ELLIPSIS
+     "declare_ring(['x'+str(i) for in xrange(10)])\nideal=\\\n[...]\n\n"
+     """
+-    dummy_dict=dict()
+-    r=declare_ring(['x'+str(i) for i in xrange(number_of_variables)], dummy_dict)
++    dummy_dict = dict()
++    r = declare_ring(['x' + str(i) for i in xrange(number_of_variables)],
++        dummy_dict)
+     polynomials = sparse_random_system(r, **kwds)
+     polynomials = pformat(polynomials)
+-    res="declare_ring(['x'+str(i) for in xrange(%s)])\nideal=\\\n%s\n\n" %(number_of_variables, polynomials)
++    res = "declare_ring(['x'+str(i) for in xrange(%s)])\nideal=\\\n%s\n\n" % (
++        number_of_variables, polynomials)
+     return res
+ 
++
+ def _test():
+     import doctest
+     doctest.testmod()
+diff --git a/pyroot/polybori/rank.py b/pyroot/polybori/rank.py
+index 946d84d..43386a4 100644
+--- a/pyroot/polybori/rank.py
++++ b/pyroot/polybori/rank.py
+@@ -1,23 +1,26 @@
+ def input_signals(p):
+-    return list((p+p.lex_lead()).vars_as_monomial().variables())
++    return list((p + p.lex_lead()).vars_as_monomial().variables())
++
++
+ def output_signal(p):
+     return iter(p.lex_lead().variables()).next()
+ 
++
+ def rank(data):
+-    parents=dict()
+-    res=dict()
++    parents = dict()
++    res = dict()
+     for p in data:
+-#        print p, output_signal(p)
+-        out=output_signal(p)
++    #        print p, output_signal(p)
++        out = output_signal(p)
+         parents.setdefault(out, [])
+         for v in input_signals(p):
+             parents.setdefault(v, []).append(out)
++
+     def do_rank(v):
+         if v in res:
+             return res[v]
+-        my_res = res[v] = max([do_rank(p)+1 for p in parents[v]]+ [0])
++        my_res = res[v] = max([do_rank(p) + 1 for p in parents[v]] + [0])
+         return my_res
+     for v in parents.keys():
+         do_rank(v)
+     return res
+-
+diff --git a/pyroot/polybori/simplebb.py b/pyroot/polybori/simplebb.py
+index 73a20ee..c97a7ce 100644
+--- a/pyroot/polybori/simplebb.py
++++ b/pyroot/polybori/simplebb.py
+@@ -1,46 +1,49 @@
+ from polybori.PyPolyBoRi import *
+ from polybori.interred import interred
++
++
+ def buchberger(l):
+     "calculates a (non minimal) Groebner basis"
+-    l=interred(l)
++    l = interred(l)
+     #for making sure, that every polynomial has a different leading term
+     #needed for add_generator
+     if not l:
+         return []
+-    g=GroebnerStrategy(l[0].ring())
++    g = GroebnerStrategy(l[0].ring())
+     for p in l:
+         g.add_generator(p)
+-    while g.npairs()>0:
++    while g.npairs() > 0:
+         g.clean_top_by_chain_criterion()
+-        p=g.next_spoly()
+-        p=g.nf(p)
++        p = g.next_spoly()
++        p = g.nf(p)
+         if not p.is_zero():
+             g.add_generator(p)
+     return list(g)
+ 
+-def less_than_n_solutions(ideal,n):
+-    l=interred(ideal)
++
++def less_than_n_solutions(ideal, n):
++    l = interred(ideal)
+     if not l:
+         return False
+-    g=GroebnerStrategy(l[0].ring())
+-    all_monomials=Monomial([Variable(i) for i 
++    g = GroebnerStrategy(l[0].ring())
++    all_monomials = Monomial([Variable(i) for i
+         in xrange(number_of_variables())]).divisors()
+-    monomials_not_in_leading_ideal=all_monomials
++    monomials_not_in_leading_ideal = all_monomials
+     for p in l:
+         g.add_generator(p)
+-    while g.npairs()>0:
+-        monomials_not_in_leading_ideal=monomials_not_in_leading_ideal\
++    while g.npairs() > 0:
++        monomials_not_in_leading_ideal = monomials_not_in_leading_ideal \
+             % g.reduction_strategy.minimal_leading_terms
+-        if len(monomials_not_in_leading_ideal)<n:
++        if len(monomials_not_in_leading_ideal) < n:
+             return True
+         g.clean_top_by_chain_criterion()
+-        p=g.next_spoly()
+-        p=g.nf(p)
++        p = g.next_spoly()
++        p = g.nf(p)
+         if not p.is_zero():
+             g.add_generator(p)
+-    monomials_not_in_leading_ideal=monomials_not_in_leading_ideal\
++    monomials_not_in_leading_ideal = monomials_not_in_leading_ideal \
+         % g.reduction_strategy.minimal_leading_terms
+-    if len(monomials_not_in_leading_ideal)<n:
++    if len(monomials_not_in_leading_ideal) < n:
+         return True
+     else:
+         return False
+@@ -50,18 +53,19 @@ def gauss(matrix):
+     """Toy Gaussian elimination.
+     Example: gauss([[0,1],[1,1]]) """
+     from gbcore import groebner_basis
++
+     def get_num(idx, vars):
+         if idx in [var.index() for var in vars.variables()]:
+             return 1
+-        return 0;
+-        
++        return 0
++
+     nrows = len(matrix)
+-    ncols = len(matrix[0]) 
+-    eqs = [ sum([matrix[row][col]*Variable(col) for col in xrange(ncols)])
++    ncols = len(matrix[0])
++    eqs = [sum([matrix[row][col] * Variable(col) for col in xrange(ncols)])
+             for row in xrange(nrows)]
+     result = groebner_basis(eqs)
+-    result = result + [BooleConstant(0)]* (nrows - len(result))
+-    
++    result = result + [BooleConstant(0)] * (nrows - len(result))
++
+     return [[get_num(idx, elt.set().vars()) for idx in xrange(ncols)]
+             for elt in result]
+ 
+diff --git a/pyroot/polybori/specialsets.py b/pyroot/polybori/specialsets.py
+index eac6af1..e2f971f 100644
+--- a/pyroot/polybori/specialsets.py
++++ b/pyroot/polybori/specialsets.py
+@@ -1,97 +1,103 @@
+-from polybori.PyPolyBoRi import BooleSet,Polynomial,mod_mon_set, if_then_else, Monomial, top_index, BooleConstant
++from polybori.PyPolyBoRi import (BooleSet, Polynomial, mod_mon_set,
++    if_then_else, Monomial, top_index, BooleConstant)
++
+ 
+ #def all_monomials_of_degree_d(d,variables):
+ #    res=all_monomials_of_degree_d_new(d, variables)
+ #    ref=all_monomials_of_degree_d_old(d, variables)
+ #    assert res==ref, (d, variables)
+ #    return res
+-def all_monomials_of_degree_d_old(d,variables):
+-    
+-    if d==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)
++    variables = sorted(set(variables), reverse=True, key=top_index)
+ 
+-    m=variables[-1]
++    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)
++        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 all_monomials_of_degree_d(d, variables):
+-    variables=Monomial(variables)
+-    variables=list(variables.variables())
++    variables = Monomial(variables)
++    variables = list(variables.variables())
+     if not variables:
+-        assert d==0
++        assert d == 0
+         return BooleConstant(1)
+     ring = variables[0].ring()
+-    if d>len(variables):
++    if d > len(variables):
+         return Polynomial(0, ring)
+-    if d<0:
++    if d < 0:
+         return Polynomial(1, ring)
+ 
+-    deg_variables=variables[-d:]
++    deg_variables = variables[-d:]
+     #this ensures sorting by indices
+-    res=Monomial(deg_variables)
++    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=[]
++    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)
++            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
++            acc = if_then_else(v, acc, nav)
++        res = acc
+     return res.set()
+-    
++
+ 
+ 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()
++    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)
++        res = if_then_else(v, res, res)
+     return res
+- 
+-if __name__=='__main__':
+-    from blocks import declare_ring,Block
+-    r=declare_ring([Block("x",10000)],globals())
+-    print list(all_monomials_of_degree_d(0,[Variable(i) for i in range(100)]))
+-    print list(all_monomials_of_degree_d(1,[Variable(i) for i in range(10)]))
+-    print list(all_monomials_of_degree_d(2,[Variable(i) for i in range(4)]))
+-    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,[]))
++
++if __name__ == '__main__':
++    from blocks import declare_ring, Block
++    r = declare_ring([Block("x", 10000)], globals())
++    print list(all_monomials_of_degree_d(0, [Variable(i) for i in range(100)]))
++    print list(all_monomials_of_degree_d(1, [Variable(i) for i in range(10)]))
++    print list(all_monomials_of_degree_d(2, [Variable(i) for i in range(4)]))
++    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)])))
+-    
++    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)])))
++            (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)
++    l = sorted(indices, reverse=True)
++    res = Monomial(ring)
+     for i in l:
+-        res=res * ring.variable(i)
+-        
++        res = res * ring.variable(i)
++
+     return res
+diff --git a/pyroot/polybori/statistics.py b/pyroot/polybori/statistics.py
+index 378421d..d6ed7b9 100644
+--- a/pyroot/polybori/statistics.py
++++ b/pyroot/polybori/statistics.py
+@@ -1,26 +1,28 @@
+-from polybori.PyPolyBoRi import Monomial,Polynomial,top_index, BooleConstant
++from polybori.PyPolyBoRi import Monomial, Polynomial, top_index, BooleConstant
++
+ 
+ def used_vars(l, bound=None):
+     if not l:
+         return BooleConstant(1)
+     m = Monomial(Polynomial(iter(l).next()).vars_as_monomial())
+     for p in l[1:]:
+-        m=m*Polynomial(p).vars_as_monomial()
++        m = m * Polynomial(p).vars_as_monomial()
+         if bound and len(m) > bound:
+             return m
+     return m
+ 
+-def used_vars_set(l,bound=None):
++
++def used_vars_set(l, bound=None):
+     if not l:
+         return BooleConstant(1)
+-    s=set()
++    s = set()
+     for p in l:
+         s.update(Polynomial(p).vars_as_monomial().variables())
+-        if bound and len(s)>bound:
++        if bound and len(s) > bound:
+             break
+-    sorted_s = sorted(list(s),key=top_index,reverse=True)
++    sorted_s = sorted(list(s), key=top_index, reverse=True)
+     m = Monomial(iter(l).next().ring())
+     for v in sorted_s:
+-        m=v*m
++        m = v * m
+ 
+     return m
+-- 
diff --git a/debian/patches/series b/debian/patches/series
index 010db01..ef2d4b7 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -2,3 +2,4 @@
 0002-Supporting-pkg-config-file.patch
 0003-Upstream-patch-for-broken-PolyGUI.patch
 0004-Drop-unused-files-from-Cudd-due-to-possible-license-.patch
+0005-pep8ify-python-modules.patch

-- 
polybori: Polynomials over Boolean Rings



More information about the debian-science-commits mailing list