From c53d261e2d45dbe82277bb697aa826c12f086f27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 2 Nov 2020 20:48:01 +0100 Subject: [PATCH] some cleanup in pbori --- src/sage/rings/polynomial/pbori/cnf.py | 28 ++++++------- src/sage/rings/polynomial/pbori/fglm.py | 14 +++---- src/sage/rings/polynomial/pbori/frontend.py | 2 + src/sage/rings/polynomial/pbori/gbcore.py | 15 ++++--- src/sage/rings/polynomial/pbori/ll.py | 5 ++- src/sage/rings/polynomial/pbori/nf.py | 4 +- src/sage/rings/polynomial/pbori/parallel.py | 35 ++++++++++------- src/sage/rings/polynomial/pbori/pbori.pyx | 2 +- src/sage/rings/polynomial/pbori/randompoly.py | 39 +++++++------------ .../rings/polynomial/pbori/specialsets.py | 9 +---- 10 files changed, 74 insertions(+), 79 deletions(-) diff --git a/src/sage/rings/polynomial/pbori/cnf.py b/src/sage/rings/polynomial/pbori/cnf.py index 2abd35a45cd..5fd2d925b55 100644 --- a/src/sage/rings/polynomial/pbori/cnf.py +++ b/src/sage/rings/polynomial/pbori/cnf.py @@ -14,9 +14,9 @@ def __init__(self, r, random_seed=16): def zero_blocks(self, f): r""" Divide the zero set of f into blocks. - + TESTS:: - + sage: from sage.rings.polynomial.pbori import * sage: r = declare_ring(["x", "y", "z"], dict()) sage: from sage.rings.polynomial.pbori.cnf import CNFEncoder @@ -79,9 +79,9 @@ def get_val(var): def clauses(self, f): r""" - + TESTS:: - + sage: from sage.rings.polynomial.pbori import * sage: r = declare_ring(["x", "y", "z"], dict()) sage: from sage.rings.polynomial.pbori.cnf import CNFEncoder @@ -99,9 +99,9 @@ def clauses(self, f): def polynomial_clauses(self, f): r""" - + TESTS:: - + sage: from sage.rings.polynomial.pbori import * sage: r = declare_ring(["x", "y", "z"], dict()) sage: from sage.rings.polynomial.pbori.cnf import CNFEncoder @@ -142,9 +142,9 @@ def get_sign(value): def dimacs_encode_polynomial(self, p): r""" - + TESTS:: - + sage: from sage.rings.polynomial.pbori import * sage: d=dict() sage: r = declare_ring(["x", "y", "z"], d) @@ -161,9 +161,9 @@ def dimacs_encode_polynomial(self, p): def dimacs_cnf(self, polynomial_system): r""" - + TESTS:: - + sage: from sage.rings.polynomial.pbori import * sage: r = declare_ring(["x", "y", "z"], dict()) sage: from sage.rings.polynomial.pbori.cnf import CNFEncoder @@ -191,9 +191,9 @@ class CryptoMiniSatEncoder(CNFEncoder): def dimacs_encode_polynomial(self, p): r""" - + TESTS:: - + sage: from sage.rings.polynomial.pbori import * sage: d=dict() sage: r = declare_ring(["x", "y", "z"], d) @@ -229,9 +229,9 @@ def dimacs_encode_polynomial(self, p): def dimacs_cnf(self, polynomial_system): r""" - + TESTS:: - + sage: from sage.rings.polynomial.pbori import * sage: r = declare_ring(["x", "y", "z"], dict()) sage: from sage.rings.polynomial.pbori.cnf import CryptoMiniSatEncoder diff --git a/src/sage/rings/polynomial/pbori/fglm.py b/src/sage/rings/polynomial/pbori/fglm.py index 4add77a89d9..da70c0fabd8 100644 --- a/src/sage/rings/polynomial/pbori/fglm.py +++ b/src/sage/rings/polynomial/pbori/fglm.py @@ -16,9 +16,9 @@ def fglm(I, from_ring, to_ring): It acts independent of the global ring, which is restored at the end of the computation. - + TESTS:: - + sage: from sage.rings.polynomial.pbori import * sage: from sage.rings.polynomial.pbori.PyPolyBoRi import OrderCode sage: dp_asc = OrderCode.dp_asc @@ -40,9 +40,9 @@ def fglm(I, from_ring, to_ring): def vars_real_divisors(monomial, monomial_set): r""" Returns all elements of of monomial_set, which result multiplied by a variable in monomial. - + TESTS:: - + sage: from sage.rings.polynomial.pbori.pbori import * sage: from sage.rings.polynomial.pbori.PyPolyBoRi import OrderCode sage: dp_asc = OrderCode.dp_asc @@ -59,12 +59,12 @@ def vars_real_divisors(monomial, monomial_set): def m_k_plus_one(completed_elements, variables): - r""" + r""" Calculates $m_{k+1}$ from the FGLM algorithm as described in Wichmanns diploma thesis It would be nice to be able to efficiently extract the smallest term of a polynomial. - + TESTS:: - + sage: from sage.rings.polynomial.pbori.pbori import * sage: from sage.rings.polynomial.pbori.PyPolyBoRi import OrderCode sage: dp_asc = OrderCode.dp_asc diff --git a/src/sage/rings/polynomial/pbori/frontend.py b/src/sage/rings/polynomial/pbori/frontend.py index 7c0fc80a3de..a5eeb6f5af7 100644 --- a/src/sage/rings/polynomial/pbori/frontend.py +++ b/src/sage/rings/polynomial/pbori/frontend.py @@ -47,6 +47,7 @@ def block_scheme_names(blocks): return list(context.keys()) + ipbname = 'ipbori' @@ -62,6 +63,7 @@ def declare_ring(blocks, context=None): print(ipbname + """ -- The interactive command line tool of PolyBoRi/BRiAL %s """ % global_context.get("polybori_version", '')) + # Here come the defaults r = Ring(10000) x = VariableFactory(r) diff --git a/src/sage/rings/polynomial/pbori/gbcore.py b/src/sage/rings/polynomial/pbori/gbcore.py index 3c7ccf1c9ee..f73bf8dbbef 100644 --- a/src/sage/rings/polynomial/pbori/gbcore.py +++ b/src/sage/rings/polynomial/pbori/gbcore.py @@ -1,6 +1,6 @@ - -from .nf import * -from .PyPolyBoRi import * +from .nf import GeneratorLimitExceeded, symmGB_F2_C, symmGB_F2_python +from .PyPolyBoRi import (Monomial, Polynomial, + GroebnerStrategy, OrderCode, ll_red_nf_redsb) from .ll import eliminate, ll_encode from copy import copy from itertools import chain @@ -43,11 +43,10 @@ def filter_newstyle_options(func, **options): def owns_one_constant(I): - """Determines whether I contains the constant one polynomial.""" - for p in I: - if p.is_one(): - return True - return False + """ + Determine whether I contains the constant one polynomial. + """ + return any(p.is_one() for p in I) def want_interpolation_gb(G): diff --git a/src/sage/rings/polynomial/pbori/ll.py b/src/sage/rings/polynomial/pbori/ll.py index 208eb365441..c9795ddd3ca 100644 --- a/src/sage/rings/polynomial/pbori/ll.py +++ b/src/sage/rings/polynomial/pbori/ll.py @@ -1,6 +1,9 @@ from sage.rings.polynomial.pbori.pbori import (top_index, if_then_else, substitute_variables) -from .PyPolyBoRi import * +from .PyPolyBoRi import (BooleSet, Polynomial, Monomial, Ring, + BoolePolynomialVector, + ll_red_nf_redsb, ll_red_nf_noredsb, + ll_red_nf_noredsb_single_recursive_call) from .statistics import used_vars_set from .rank import rank diff --git a/src/sage/rings/polynomial/pbori/nf.py b/src/sage/rings/polynomial/pbori/nf.py index 678195ebe5b..9b075914781 100644 --- a/src/sage/rings/polynomial/pbori/nf.py +++ b/src/sage/rings/polynomial/pbori/nf.py @@ -1,5 +1,7 @@ from sage.rings.polynomial.pbori.pbori import mod_mon_set -from .PyPolyBoRi import * +from .PyPolyBoRi import (BooleSet, Monomial, Polynomial, Variable, + GroebnerStrategy, ReductionStrategy, parallel_reduce, + easy_linear_factors, BoolePolynomialVector) from .easy_polynomials import (easy_linear_polynomials as easy_linear_polynomials_func) from .statistics import used_vars_set diff --git a/src/sage/rings/polynomial/pbori/parallel.py b/src/sage/rings/polynomial/pbori/parallel.py index 5bb0e56e92b..04ba312e7d7 100644 --- a/src/sage/rings/polynomial/pbori/parallel.py +++ b/src/sage/rings/polynomial/pbori/parallel.py @@ -19,11 +19,11 @@ def to_fast_pickable(l): Convert a list of polynomials into a builtin Python value, which is fast pickable and compact. INPUT: - + - a list of Boolean polynomials - + OUTPUT: - + It is converted to a tuple consisting of - codes referring to the polynomials - list of conversions of nodes. @@ -108,15 +108,15 @@ def from_fast_pickable(l, r): The second argument is ring, in which this polynomial should be created. INPUT: - + See OUTPUT of to_fast_pickable OUTPUT: - + a list of Boolean polynomials - + EXAMPLES:: - + sage: from sage.rings.polynomial.pbori.frontend import * sage: from sage.rings.polynomial.pbori.parallel import from_fast_pickable sage: r=Ring(1000) @@ -172,24 +172,28 @@ def _encode_polynomial(poly): def pickle_polynomial(self): return (_decode_polynomial, (_encode_polynomial(self), )) + copyreg.pickle(Polynomial, pickle_polynomial) def pickle_bset(self): return (BooleSet, (Polynomial(self), )) + copyreg.pickle(BooleSet, pickle_bset) def pickle_monom(self): return (Monomial, ([var for var in self.variables()], )) + copyreg.pickle(Monomial, pickle_monom) def pickle_var(self): return (Variable, (self.index(), self.ring())) + copyreg.pickle(Variable, pickle_var) @@ -242,8 +246,8 @@ 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 range(nvars) - ]) + varnames = '\n'.join(str(ring.variable(idx)) + for idx in range(nvars)) blocks = list(ring.blocks()) code = (identifier, data, compress(varnames), blocks[:-1]) _polybori_parallel_rings[identifier] = (WeakRingRef(ring), code) @@ -254,24 +258,25 @@ def _encode_ring(ring): def pickle_ring(self): return (_decode_ring, (_encode_ring(self), )) + copyreg.pickle(Ring, pickle_ring) def groebner_basis_first_finished(I, *l): r""" - + INPUT: - + - ``I`` -- ideal - ``l`` -- keyword dictionaries, which will be keyword arguments to groebner_basis. - + OUTPUT: - + - tries to compute ``groebner_basis(I, **kwd)`` for kwd in l - returns the result of the first terminated computation - + EXAMPLES:: - + sage: from sage.rings.polynomial.pbori.PyPolyBoRi import Ring sage: r=Ring(1000) sage: ideal = [r.variable(1)*r.variable(2)+r.variable(2)+r.variable(1)] diff --git a/src/sage/rings/polynomial/pbori/pbori.pyx b/src/sage/rings/polynomial/pbori/pbori.pyx index 4fcb948fe86..ed35782d52f 100644 --- a/src/sage/rings/polynomial/pbori/pbori.pyx +++ b/src/sage/rings/polynomial/pbori/pbori.pyx @@ -1398,7 +1398,7 @@ cdef class BooleanPolynomialRing(MPolynomialRing_base): return R def defining_ideal(self): - """ + r""" Return `I = \subset R` where ``R = self.cover_ring()``, and `x_i` any element in the set of variables of this ring. diff --git a/src/sage/rings/polynomial/pbori/randompoly.py b/src/sage/rings/polynomial/pbori/randompoly.py index a82506f218c..2d2bc1622e3 100644 --- a/src/sage/rings/polynomial/pbori/randompoly.py +++ b/src/sage/rings/polynomial/pbori/randompoly.py @@ -29,21 +29,22 @@ def helper(samples): 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): r""" - 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 + Generate a system, which is sparse in the sense, that each polynomial + contains only a small subset of variables. In each variable that occurrs + in a polynomial it is dense in the terms up to the given degree (every term occurs with probability 1/2). + The system will be satisfiable by at least one solution. TESTS:: - - sage: from sage.rings.polynomial.pbori import * - sage: r=Ring(10) + + sage: from sage.rings.polynomial.pbori import Ring, groebner_basis + sage: r = Ring(10) sage: from sage.rings.polynomial.pbori.randompoly import sparse_random_system - sage: s=sparse_random_system(r, number_of_polynomials = 20, variables_per_polynomial = 3, degree=2, random_seed=123) + sage: s = sparse_random_system(r, number_of_polynomials=20, variables_per_polynomial=3, degree=2, random_seed=int(123)) sage: [p.deg() for p in s] [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] sage: sorted(groebner_basis(s), reverse=True) @@ -74,31 +75,19 @@ def sparse_random_system(ring, number_of_polynomials, return res -def sparse_random_system_data_file_content( - number_of_variables, **kwds): +def sparse_random_system_data_file_content(number_of_variables, **kwds): r""" - TESTS:: - - - sage: from sage.rings.polynomial.pbori import * + sage: from sage.rings.polynomial.pbori.randompoly import sparse_random_system_data_file_content - sage: sparse_random_system_data_file_content(10, number_of_polynomials = 5, variables_per_polynomial = 3, degree=2, random_seed=123) + sage: sparse_random_system_data_file_content(10, number_of_polynomials=5, variables_per_polynomial=3, degree=2, random_seed=int(123)) "declare_ring(['x'+str(i) for in range(10)])\nideal=\\\n[...]\n\n" """ dummy_dict = dict() r = declare_ring(['x' + str(i) for i in range(number_of_variables)], - dummy_dict) + dummy_dict) polynomials = sparse_random_system(r, **kwds) polynomials = pformat(polynomials) res = "declare_ring(['x'+str(i) for in range(%s)])\nideal=\\\n%s\n\n" % ( number_of_variables, polynomials) return res - - -def _test(): - import doctest - doctest.testmod() - -if __name__ == "__main__": - _test() diff --git a/src/sage/rings/polynomial/pbori/specialsets.py b/src/sage/rings/polynomial/pbori/specialsets.py index d6b79edd432..55a99c81049 100644 --- a/src/sage/rings/polynomial/pbori/specialsets.py +++ b/src/sage/rings/polynomial/pbori/specialsets.py @@ -3,12 +3,6 @@ from .PyPolyBoRi import (BooleSet, Polynomial, Monomial, BooleConstant, Variable) -#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): @@ -44,7 +38,7 @@ def all_monomials_of_degree_d(d, variables): return Polynomial(1, ring) deg_variables = variables[-d:] - #this ensures sorting by indices + # this ensures sorting by indices res = Monomial(deg_variables) for i in range(1, len(variables) - d + 1): @@ -71,6 +65,7 @@ def power_set(variables): 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())