passagemath-brial 10.6.31rc3__cp314-cp314-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-brial might be problematic. Click here for more details.
- passagemath_brial-10.6.31rc3.dist-info/METADATA +97 -0
- passagemath_brial-10.6.31rc3.dist-info/RECORD +39 -0
- passagemath_brial-10.6.31rc3.dist-info/WHEEL +5 -0
- passagemath_brial-10.6.31rc3.dist-info/top_level.txt +2 -0
- passagemath_brial.libs/libbrial-83985df5.so.3.0.7 +0 -0
- passagemath_brial.libs/libbrial_groebner-a6504217.so.3.0.7 +0 -0
- passagemath_brial.libs/libgcc_s-2d945d6c.so.1 +0 -0
- passagemath_brial.libs/libm4ri-5e907cd2.so.1.0.0 +0 -0
- passagemath_brial.libs/libpng16-09496a15.so.16.43.0 +0 -0
- passagemath_brial.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
- sage/all__sagemath_brial.py +9 -0
- sage/libs/all__sagemath_brial.py +1 -0
- sage/libs/polybori/__init__.pxd +2 -0
- sage/libs/polybori/decl.pxd +401 -0
- sage/libs/polybori/pb_wrap.h +133 -0
- sage/rings/all__sagemath_brial.py +1 -0
- sage/rings/polynomial/all__sagemath_brial.py +1 -0
- sage/rings/polynomial/pbori/PyPolyBoRi.py +123 -0
- sage/rings/polynomial/pbori/__init__.py +44 -0
- sage/rings/polynomial/pbori/blocks.py +443 -0
- sage/rings/polynomial/pbori/cnf.py +241 -0
- sage/rings/polynomial/pbori/easy_polynomials.py +56 -0
- sage/rings/polynomial/pbori/fglm.py +93 -0
- sage/rings/polynomial/pbori/frontend.py +70 -0
- sage/rings/polynomial/pbori/gbcore.py +634 -0
- sage/rings/polynomial/pbori/gbrefs.py +127 -0
- sage/rings/polynomial/pbori/heuristics.py +35 -0
- sage/rings/polynomial/pbori/interpolate.py +115 -0
- sage/rings/polynomial/pbori/interred.py +35 -0
- sage/rings/polynomial/pbori/ll.py +292 -0
- sage/rings/polynomial/pbori/nf.py +662 -0
- sage/rings/polynomial/pbori/parallel.py +298 -0
- sage/rings/polynomial/pbori/pbori.cpython-314-aarch64-linux-musl.so +0 -0
- sage/rings/polynomial/pbori/pbori.pxd +127 -0
- sage/rings/polynomial/pbori/pbori.pyx +8107 -0
- sage/rings/polynomial/pbori/randompoly.py +105 -0
- sage/rings/polynomial/pbori/rank.py +27 -0
- sage/rings/polynomial/pbori/specialsets.py +112 -0
- sage/rings/polynomial/pbori/statistics.py +31 -0
|
@@ -0,0 +1,662 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-brial
|
|
2
|
+
# sage.doctest: needs sage.rings.polynomial.pbori
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from warnings import warn
|
|
5
|
+
|
|
6
|
+
from sage.rings.polynomial.pbori.pbori import mod_mon_set
|
|
7
|
+
from .pbori import (BooleSet, GroebnerStrategy, ReductionStrategy,
|
|
8
|
+
parallel_reduce, easy_linear_factors)
|
|
9
|
+
from .PyPolyBoRi import (Monomial, Polynomial, Variable,
|
|
10
|
+
BoolePolynomialVector)
|
|
11
|
+
from .easy_polynomials import (easy_linear_polynomials as
|
|
12
|
+
easy_linear_polynomials_func)
|
|
13
|
+
from .statistics import used_vars_set
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class GeneratorLimitExceeded(Exception):
|
|
17
|
+
r"""
|
|
18
|
+
Docstring for GeneratorLimitExceeded
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, strat):
|
|
22
|
+
self.strat = strat
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def pkey(p):
|
|
26
|
+
return (p[0], len(p))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
mat_counter = 0
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def build_and_print_matrices(v, strat):
|
|
33
|
+
r"""
|
|
34
|
+
Old solution using PIL, the currently used implementation is done in C++
|
|
35
|
+
and plots the same matrices, as being calculated
|
|
36
|
+
"""
|
|
37
|
+
treated = BooleSet()
|
|
38
|
+
v = list(v)
|
|
39
|
+
if not v:
|
|
40
|
+
return
|
|
41
|
+
rows = 0
|
|
42
|
+
polys_in_mat = []
|
|
43
|
+
while v:
|
|
44
|
+
rows = rows + 1
|
|
45
|
+
p = v[0]
|
|
46
|
+
v = v[1:]
|
|
47
|
+
for m in list(p.terms()):
|
|
48
|
+
mom = Monomial(m)
|
|
49
|
+
if mom not in BooleSet(treated):
|
|
50
|
+
i = strat.select(mom)
|
|
51
|
+
if i >= 0:
|
|
52
|
+
p2 = strat[i]
|
|
53
|
+
p2 = p2 * (mom // p2.lead())
|
|
54
|
+
v.append(p2)
|
|
55
|
+
polys_in_mat.append(p)
|
|
56
|
+
treated = treated.union(p.set())
|
|
57
|
+
m2i = {v: k
|
|
58
|
+
for k, v in enumerate(list(Polynomial(BooleSet(treated)).terms()))}
|
|
59
|
+
polys_in_mat.sort(key=Polynomial.lead, reverse=True)
|
|
60
|
+
polys_in_mat = [[m2i[t] for t in p.terms()] for p in polys_in_mat]
|
|
61
|
+
|
|
62
|
+
global mat_counter
|
|
63
|
+
mat_counter = mat_counter + 1
|
|
64
|
+
from PIL import Image
|
|
65
|
+
|
|
66
|
+
rows = len(polys_in_mat)
|
|
67
|
+
cols = len(m2i)
|
|
68
|
+
im = Image.new("1", (cols, rows), "white")
|
|
69
|
+
for i, pi in enumerate(polys_in_mat):
|
|
70
|
+
for j in pi:
|
|
71
|
+
assert i < rows
|
|
72
|
+
assert j < cols
|
|
73
|
+
im.putpixel((j, i), 0)
|
|
74
|
+
|
|
75
|
+
file_name = Path(strat.matrix_prefix + str(mat_counter) + ".png")
|
|
76
|
+
file_name.unlink(missing_ok=True)
|
|
77
|
+
im.save(file_name)
|
|
78
|
+
del im
|
|
79
|
+
|
|
80
|
+
print("MATRIX_SIZE:", rows, "x", cols)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def multiply_polynomials(l, ring):
|
|
84
|
+
r"""
|
|
85
|
+
|
|
86
|
+
TESTS::
|
|
87
|
+
|
|
88
|
+
sage: from sage.rings.polynomial.pbori import *
|
|
89
|
+
sage: r = Ring(1000)
|
|
90
|
+
sage: x = r.variable
|
|
91
|
+
sage: from sage.rings.polynomial.pbori.nf import multiply_polynomials
|
|
92
|
+
sage: multiply_polynomials([x(3), x(2)+x(5)*x(6), x(0), x(0)+1], r)
|
|
93
|
+
0
|
|
94
|
+
"""
|
|
95
|
+
l = [Polynomial(p) for p in l]
|
|
96
|
+
|
|
97
|
+
def sort_key(p):
|
|
98
|
+
return p.navigation().value()
|
|
99
|
+
l = sorted(l, key=sort_key)
|
|
100
|
+
res = Polynomial(ring.one())
|
|
101
|
+
for p in l:
|
|
102
|
+
res = p * res
|
|
103
|
+
return res
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def build_and_print_matrices_deg_colored(v, strat):
|
|
107
|
+
r"""
|
|
108
|
+
old PIL solution using a different color for each degree
|
|
109
|
+
"""
|
|
110
|
+
if not v:
|
|
111
|
+
return
|
|
112
|
+
|
|
113
|
+
treated = BooleSet()
|
|
114
|
+
v = list(v)
|
|
115
|
+
rows = 0
|
|
116
|
+
polys_in_mat = []
|
|
117
|
+
|
|
118
|
+
while v:
|
|
119
|
+
rows = rows + 1
|
|
120
|
+
p = v[0]
|
|
121
|
+
v = v[1:]
|
|
122
|
+
for m in list(p.terms()):
|
|
123
|
+
mom = Monomial(m)
|
|
124
|
+
if m not in BooleSet(treated):
|
|
125
|
+
i = strat.select(mom)
|
|
126
|
+
if i >= 0:
|
|
127
|
+
p2 = strat[i]
|
|
128
|
+
p2 = p2 * (mom // p2.lead())
|
|
129
|
+
v.append(p2)
|
|
130
|
+
polys_in_mat.append(p)
|
|
131
|
+
treated = treated.union(p.set())
|
|
132
|
+
m2i = {v: k for k, v in enumerate(BooleSet(treated))}
|
|
133
|
+
max_deg = max(m.deg() for m in BooleSet(treated))
|
|
134
|
+
if max_deg == 0:
|
|
135
|
+
max_deg = 1
|
|
136
|
+
i2deg = {m2i[m]: m.deg() for m in BooleSet(treated)}
|
|
137
|
+
polys_in_mat = [[m2i[t] for t in p.terms()] for p in polys_in_mat]
|
|
138
|
+
polys_in_mat.sort(key=pkey)
|
|
139
|
+
global mat_counter
|
|
140
|
+
mat_counter = mat_counter + 1
|
|
141
|
+
from PIL import Image
|
|
142
|
+
from PIL import ImageColor
|
|
143
|
+
|
|
144
|
+
rows = len(polys_in_mat)
|
|
145
|
+
cols = len(m2i)
|
|
146
|
+
im = Image.new("RGB", (cols, rows), "white")
|
|
147
|
+
for i in range(len(polys_in_mat)):
|
|
148
|
+
p = polys_in_mat[i]
|
|
149
|
+
for j in p:
|
|
150
|
+
assert i < rows
|
|
151
|
+
assert j < cols
|
|
152
|
+
hsl = str(270 - (270 * i2deg[j]) / max_deg)
|
|
153
|
+
im.putpixel((j, i), ImageColor.getrgb("hsl(" + hsl + ",100%,50%)"))
|
|
154
|
+
file_name = Path(strat.matrix_prefix + str(mat_counter) + ".png")
|
|
155
|
+
file_name.unlink(missing_ok=True)
|
|
156
|
+
im.save(file_name)
|
|
157
|
+
del im
|
|
158
|
+
|
|
159
|
+
print("MATRIX_SIZE:", rows, "x", cols)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def high_probability_polynomials_trick(p, strat):
|
|
163
|
+
lead_deg = p.lead_deg()
|
|
164
|
+
if lead_deg <= 4:
|
|
165
|
+
return
|
|
166
|
+
|
|
167
|
+
ring = p.ring()
|
|
168
|
+
factor = multiply_polynomials(easy_linear_factors(p), ring)
|
|
169
|
+
p = p / factor
|
|
170
|
+
|
|
171
|
+
# again, do it twice, it's cheap
|
|
172
|
+
lead_deg = p.lead_deg()
|
|
173
|
+
if lead_deg <= 3:
|
|
174
|
+
return
|
|
175
|
+
|
|
176
|
+
if lead_deg > 9:
|
|
177
|
+
return
|
|
178
|
+
uv = p.vars_as_monomial()
|
|
179
|
+
|
|
180
|
+
candidates = []
|
|
181
|
+
|
|
182
|
+
if uv.deg() <= 4:
|
|
183
|
+
return
|
|
184
|
+
|
|
185
|
+
if not uv.deg() <= lead_deg + 1:
|
|
186
|
+
return
|
|
187
|
+
|
|
188
|
+
space = uv.divisors()
|
|
189
|
+
|
|
190
|
+
lead = p.lead()
|
|
191
|
+
for v in lead.variables():
|
|
192
|
+
variable_selection = lead // v
|
|
193
|
+
vars_reversed = list(reversed(variable_selection.variables()))
|
|
194
|
+
# it's just a way to loop over the cartesian product
|
|
195
|
+
for assignment in variable_selection.divisors():
|
|
196
|
+
c_p = assignment
|
|
197
|
+
for var in vars_reversed:
|
|
198
|
+
if not assignment.reducible_by(var):
|
|
199
|
+
c_p = (var + 1) * c_p
|
|
200
|
+
|
|
201
|
+
points = (c_p + 1).zeros_in(space)
|
|
202
|
+
if p.zeros_in(points).empty():
|
|
203
|
+
candidates.append(c_p * factor)
|
|
204
|
+
# there many more combinations depending on plugged in values
|
|
205
|
+
for c in candidates:
|
|
206
|
+
strat.add_as_you_wish(c)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def symmGB_F2_python(G, deg_bound=1000000000000, over_deg_bound=0,
|
|
210
|
+
use_faugere=False, use_noro=False,
|
|
211
|
+
opt_lazy=True, opt_red_tail=True,
|
|
212
|
+
max_growth=2.0, step_factor=1.0,
|
|
213
|
+
implications=False, prot=False,
|
|
214
|
+
full_prot=False, selection_size=1000, opt_exchange=True,
|
|
215
|
+
opt_allow_recursion=False, ll=False,
|
|
216
|
+
opt_linear_algebra_in_last_block=True,
|
|
217
|
+
max_generators=None,
|
|
218
|
+
red_tail_deg_growth=True, matrix_prefix='mat',
|
|
219
|
+
modified_linear_algebra=True, draw_matrices=False,
|
|
220
|
+
easy_linear_polynomials=True):
|
|
221
|
+
if use_noro and use_faugere:
|
|
222
|
+
raise ValueError('both use_noro and use_faugere specified')
|
|
223
|
+
|
|
224
|
+
def add_to_basis(strat, p):
|
|
225
|
+
if p.is_zero():
|
|
226
|
+
if prot:
|
|
227
|
+
print("-")
|
|
228
|
+
else:
|
|
229
|
+
if prot:
|
|
230
|
+
if full_prot:
|
|
231
|
+
print(p)
|
|
232
|
+
print("Result: ", "deg:", p.deg(), "lm: ",
|
|
233
|
+
p.lead(), "el: ", p.elength())
|
|
234
|
+
if easy_linear_polynomials and p.lead_deg() > 2:
|
|
235
|
+
lin = easy_linear_polynomials_func(p)
|
|
236
|
+
for q in lin:
|
|
237
|
+
strat.add_generator_delayed(q)
|
|
238
|
+
old_len = len(strat)
|
|
239
|
+
strat.add_as_you_wish(p)
|
|
240
|
+
new_len = len(strat)
|
|
241
|
+
if new_len == 1 + old_len:
|
|
242
|
+
high_probability_polynomials_trick(p, strat)
|
|
243
|
+
|
|
244
|
+
if prot:
|
|
245
|
+
print("#Generators:", len(strat))
|
|
246
|
+
|
|
247
|
+
if isinstance(G, list):
|
|
248
|
+
if not G:
|
|
249
|
+
return []
|
|
250
|
+
G = [Polynomial(g) for g in G]
|
|
251
|
+
current_ring = G[0].ring()
|
|
252
|
+
strat = GroebnerStrategy(current_ring)
|
|
253
|
+
strat.reduction_strategy.opt_red_tail = opt_red_tail
|
|
254
|
+
strat.opt_lazy = opt_lazy
|
|
255
|
+
strat.opt_exchange = opt_exchange
|
|
256
|
+
strat.opt_allow_recursion = opt_allow_recursion
|
|
257
|
+
strat.enabled_log = prot
|
|
258
|
+
strat.reduction_strategy.opt_ll = ll
|
|
259
|
+
strat.opt_modified_linear_algebra = modified_linear_algebra
|
|
260
|
+
strat.opt_linear_algebra_in_last_block = (
|
|
261
|
+
opt_linear_algebra_in_last_block)
|
|
262
|
+
strat.opt_red_by_reduced = False # True
|
|
263
|
+
strat.reduction_strategy.opt_red_tail_deg_growth = red_tail_deg_growth
|
|
264
|
+
|
|
265
|
+
strat.opt_draw_matrices = draw_matrices
|
|
266
|
+
strat.matrix_prefix = matrix_prefix
|
|
267
|
+
|
|
268
|
+
for g in G:
|
|
269
|
+
if not g.is_zero():
|
|
270
|
+
strat.add_generator_delayed(g)
|
|
271
|
+
else:
|
|
272
|
+
strat = G
|
|
273
|
+
|
|
274
|
+
if prot:
|
|
275
|
+
print("added delayed")
|
|
276
|
+
i = 0
|
|
277
|
+
try:
|
|
278
|
+
while strat.npairs() > 0:
|
|
279
|
+
if max_generators and len(strat) > max_generators:
|
|
280
|
+
raise GeneratorLimitExceeded(strat)
|
|
281
|
+
i = i + 1
|
|
282
|
+
if prot:
|
|
283
|
+
print("Current Degree:", strat.top_sugar())
|
|
284
|
+
if (strat.top_sugar() > deg_bound) and (over_deg_bound <= 0):
|
|
285
|
+
return strat
|
|
286
|
+
if (strat.top_sugar() > deg_bound):
|
|
287
|
+
ps = strat.some_spolys_in_next_degree(over_deg_bound)
|
|
288
|
+
over_deg_bound -= len(ps)
|
|
289
|
+
else:
|
|
290
|
+
ps = strat.some_spolys_in_next_degree(selection_size)
|
|
291
|
+
|
|
292
|
+
if ps and ps[0].ring().has_degree_order():
|
|
293
|
+
ps = [strat.reduction_strategy.cheap_reductions(p) for p in ps]
|
|
294
|
+
ps = [p for p in ps if not p.is_zero()]
|
|
295
|
+
if ps:
|
|
296
|
+
min_deg = min(p.deg() for p in ps)
|
|
297
|
+
new_ps = []
|
|
298
|
+
for p in ps:
|
|
299
|
+
if p.deg() <= min_deg:
|
|
300
|
+
new_ps.append(p)
|
|
301
|
+
else:
|
|
302
|
+
strat.add_generator_delayed(p)
|
|
303
|
+
ps = new_ps
|
|
304
|
+
|
|
305
|
+
if prot:
|
|
306
|
+
print("(", strat.npairs(), ")")
|
|
307
|
+
if prot:
|
|
308
|
+
print("start reducing")
|
|
309
|
+
print("Chain Crit. : ", strat.chain_criterions, "VC:", strat.
|
|
310
|
+
variable_chain_criterions, "EASYP", strat.
|
|
311
|
+
easy_product_criterions, "EXTP", strat.
|
|
312
|
+
extended_product_criterions)
|
|
313
|
+
print(len(ps), "spolys added")
|
|
314
|
+
|
|
315
|
+
if use_noro or use_faugere:
|
|
316
|
+
v = BoolePolynomialVector()
|
|
317
|
+
|
|
318
|
+
for p in ps:
|
|
319
|
+
if not p.is_zero():
|
|
320
|
+
v.append(p)
|
|
321
|
+
res = strat.noro_step(v) if use_noro else strat.faugere_step_dense(v)
|
|
322
|
+
|
|
323
|
+
else:
|
|
324
|
+
v = BoolePolynomialVector()
|
|
325
|
+
for p in ps:
|
|
326
|
+
rp = Polynomial(mod_mon_set(
|
|
327
|
+
BooleSet(p.set()),
|
|
328
|
+
strat.reduction_strategy.monomials))
|
|
329
|
+
if not rp.is_zero():
|
|
330
|
+
v.append(rp)
|
|
331
|
+
if len(v) > 100:
|
|
332
|
+
res = parallel_reduce(v, strat, int(step_factor * 10),
|
|
333
|
+
max_growth)
|
|
334
|
+
elif len(v) > 10:
|
|
335
|
+
res = parallel_reduce(v, strat, int(step_factor * 30),
|
|
336
|
+
max_growth)
|
|
337
|
+
else:
|
|
338
|
+
res = parallel_reduce(v, strat, int(step_factor * 100),
|
|
339
|
+
max_growth)
|
|
340
|
+
|
|
341
|
+
if prot:
|
|
342
|
+
print("end reducing")
|
|
343
|
+
|
|
344
|
+
if res and res[0].ring().has_degree_order():
|
|
345
|
+
res_min_deg = min([p.deg() for p in res])
|
|
346
|
+
new_res = []
|
|
347
|
+
for p in res:
|
|
348
|
+
if p.deg() == res_min_deg:
|
|
349
|
+
new_res.append(p)
|
|
350
|
+
else:
|
|
351
|
+
strat.add_generator_delayed(p)
|
|
352
|
+
res = new_res
|
|
353
|
+
|
|
354
|
+
def sort_key(p):
|
|
355
|
+
return p.lead()
|
|
356
|
+
res_cp = sorted(res, key=sort_key)
|
|
357
|
+
|
|
358
|
+
for p in res_cp:
|
|
359
|
+
old_len = len(strat)
|
|
360
|
+
add_to_basis(strat, p)
|
|
361
|
+
if implications and old_len == len(strat) - 1:
|
|
362
|
+
strat.implications(len(strat) - 1)
|
|
363
|
+
if p.is_one():
|
|
364
|
+
if prot:
|
|
365
|
+
print("GB is 1")
|
|
366
|
+
return strat
|
|
367
|
+
if prot:
|
|
368
|
+
print("(", strat.npairs(), ")")
|
|
369
|
+
|
|
370
|
+
strat.clean_top_by_chain_criterion()
|
|
371
|
+
return strat
|
|
372
|
+
except KeyboardInterrupt:
|
|
373
|
+
raise
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
def GPS(G, vars_start, vars_end):
|
|
377
|
+
def step(strat, trace, var, val):
|
|
378
|
+
print("plugin: ", var, val)
|
|
379
|
+
print("npairs", strat.npairs())
|
|
380
|
+
strat = GroebnerStrategy(strat)
|
|
381
|
+
print("npairs", strat.npairs())
|
|
382
|
+
strat.add_generator_delayed(Polynomial(
|
|
383
|
+
Monomial(Variable(var, strat.r)) + val))
|
|
384
|
+
strat = symmGB_F2_python(strat, prot=True, deg_bound=2,
|
|
385
|
+
over_deg_bound=10)
|
|
386
|
+
if var <= vars_start:
|
|
387
|
+
strat = symmGB_F2_python(strat, prot=True, opt_lazy=False,
|
|
388
|
+
opt_red_tail=False)
|
|
389
|
+
if strat.containsOne():
|
|
390
|
+
pass
|
|
391
|
+
else:
|
|
392
|
+
if var <= vars_start:
|
|
393
|
+
# bug: may contain Delayed polynomials
|
|
394
|
+
print("!!!!!!! SOLUTION", trace)
|
|
395
|
+
raise Exception
|
|
396
|
+
# yield trace
|
|
397
|
+
branch(strat, trace + [(var, val)], var - 1)
|
|
398
|
+
|
|
399
|
+
def branch(strat, trace, var):
|
|
400
|
+
while strat.variableHasValue(var):
|
|
401
|
+
# remember to add value to trace
|
|
402
|
+
var -= 1
|
|
403
|
+
step(strat, trace, var, 0)
|
|
404
|
+
step(strat, trace, var, 1)
|
|
405
|
+
if G:
|
|
406
|
+
strat = GroebnerStrategy(G[0].ring())
|
|
407
|
+
# strat.add_generator(G[0])
|
|
408
|
+
for g in G[:]:
|
|
409
|
+
strat.add_generator_delayed(g)
|
|
410
|
+
branch(strat, [], vars_end - 1)
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
def GPS_with_proof_path(G, proof_path, deg_bound, over_deg_bound):
|
|
414
|
+
def step(strat, trace, proof_path, pos, val):
|
|
415
|
+
print(proof_path)
|
|
416
|
+
print("plugin: ", pos, val, proof_path[pos])
|
|
417
|
+
print("npairs", strat.npairs())
|
|
418
|
+
strat = GroebnerStrategy(strat)
|
|
419
|
+
print("npairs", strat.npairs())
|
|
420
|
+
print("npairs", strat.npairs())
|
|
421
|
+
plug_p = Polynomial(proof_path[pos]) + val
|
|
422
|
+
plug_p_lead = plug_p.lead()
|
|
423
|
+
if len(plug_p) == 2 and (plug_p + plug_p_lead).deg() == 0:
|
|
424
|
+
for v in plug_p_lead:
|
|
425
|
+
strat.add_generator_delayed(v + 1)
|
|
426
|
+
else:
|
|
427
|
+
strat.add_generator_delayed(plug_p)
|
|
428
|
+
print("npairs", strat.npairs())
|
|
429
|
+
print("pos:", pos)
|
|
430
|
+
strat = symmGB_F2_python(strat, deg_bound=deg_bound, opt_lazy=False,
|
|
431
|
+
over_deg_bound=over_deg_bound, prot=True)
|
|
432
|
+
print("npairs", strat.npairs())
|
|
433
|
+
pos = pos + 1
|
|
434
|
+
if pos >= len(proof_path):
|
|
435
|
+
print("OVER")
|
|
436
|
+
strat = symmGB_F2_python(strat, prot=True)
|
|
437
|
+
if strat.containsOne():
|
|
438
|
+
pass
|
|
439
|
+
else:
|
|
440
|
+
if pos >= len(proof_path):
|
|
441
|
+
print("npairs", strat.npairs())
|
|
442
|
+
print("minimized:")
|
|
443
|
+
for p in strat.minimalize_and_tail_reduce():
|
|
444
|
+
print(p)
|
|
445
|
+
# bug: may contain Delayed polynomials
|
|
446
|
+
print("!!!!!!! SOLUTION", trace)
|
|
447
|
+
raise Exception
|
|
448
|
+
# yield trace
|
|
449
|
+
branch(strat, trace + [(pos, val)], proof_path, pos)
|
|
450
|
+
|
|
451
|
+
def branch(strat, trace, proof_path, pos):
|
|
452
|
+
|
|
453
|
+
step(strat, trace, proof_path, pos, 0)
|
|
454
|
+
step(strat, trace, proof_path, pos, 1)
|
|
455
|
+
strat = GroebnerStrategy(G[0].ring())
|
|
456
|
+
strat.add_generator(Polynomial(G[0]))
|
|
457
|
+
for g in G[1:]:
|
|
458
|
+
strat.add_generator_delayed(Polynomial(g))
|
|
459
|
+
branch(strat, [], proof_path, 0)
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
def GPS_with_suggestions(G, deg_bound, over_deg_bound, opt_lazy=True,
|
|
463
|
+
opt_red_tail=True, initial_bb=True):
|
|
464
|
+
def step(strat, trace, var, val):
|
|
465
|
+
print(trace)
|
|
466
|
+
plug_p = val + var
|
|
467
|
+
print("plugin: ", len(trace), plug_p)
|
|
468
|
+
trace = trace + [plug_p]
|
|
469
|
+
strat = GroebnerStrategy(strat)
|
|
470
|
+
|
|
471
|
+
strat.add_generator_delayed(plug_p)
|
|
472
|
+
print("npairs", strat.npairs())
|
|
473
|
+
|
|
474
|
+
strat = symmGB_F2_python(strat, deg_bound=deg_bound,
|
|
475
|
+
opt_lazy=opt_lazy,
|
|
476
|
+
over_deg_bound=over_deg_bound, prot=True)
|
|
477
|
+
|
|
478
|
+
if not strat.containsOne():
|
|
479
|
+
branch(strat, trace)
|
|
480
|
+
|
|
481
|
+
def branch(strat, trace):
|
|
482
|
+
print("branching")
|
|
483
|
+
index = strat.suggestPluginVariable()
|
|
484
|
+
|
|
485
|
+
if index < 0:
|
|
486
|
+
uv = set(used_vars_set(strat))
|
|
487
|
+
lv = {next(iter(p.lead())).index()
|
|
488
|
+
for p in strat if p.lead_deg() == 1}
|
|
489
|
+
candidates = uv.difference(lv)
|
|
490
|
+
if candidates:
|
|
491
|
+
index = next(iter(candidates)).index()
|
|
492
|
+
if index >= 0:
|
|
493
|
+
print("chosen index:", index)
|
|
494
|
+
step(strat, trace, Polynomial(Monomial(Variable(index))), 0)
|
|
495
|
+
step(strat, trace, Polynomial(Monomial(Variable(index))), 1)
|
|
496
|
+
else:
|
|
497
|
+
print("FINAL!!!", index)
|
|
498
|
+
strat = symmGB_F2_python(strat, prot=True)
|
|
499
|
+
if not strat.containsOne():
|
|
500
|
+
print("TRACE", trace)
|
|
501
|
+
print("SOLUTION")
|
|
502
|
+
for p in strat.minimalize_and_tail_reduce():
|
|
503
|
+
print(p)
|
|
504
|
+
raise Exception
|
|
505
|
+
|
|
506
|
+
def sort_crit(p):
|
|
507
|
+
return (p.lead(), p.deg(), p.elength())
|
|
508
|
+
if not G:
|
|
509
|
+
return
|
|
510
|
+
strat = GroebnerStrategy(G[0].ring())
|
|
511
|
+
strat.reduction_strategy.opt_red_tail = opt_red_tail # True
|
|
512
|
+
strat.opt_exchange = False
|
|
513
|
+
strat.opt_allow_recursion = False
|
|
514
|
+
strat.opt_lazy = opt_lazy
|
|
515
|
+
first_deg_bound = 1
|
|
516
|
+
G = [Polynomial(p) for p in G]
|
|
517
|
+
G.sort(key=sort_crit)
|
|
518
|
+
if initial_bb:
|
|
519
|
+
for g in G:
|
|
520
|
+
print(g)
|
|
521
|
+
if g.deg() == 1: # (index<0):
|
|
522
|
+
strat.add_as_you_wish(g)
|
|
523
|
+
else:
|
|
524
|
+
first_deg_bound = max(first_deg_bound, g.deg())
|
|
525
|
+
strat.add_generator_delayed(g)
|
|
526
|
+
print(g, len(strat))
|
|
527
|
+
else:
|
|
528
|
+
for g in G:
|
|
529
|
+
strat.add_as_you_wish(g)
|
|
530
|
+
if initial_bb:
|
|
531
|
+
strat = symmGB_F2_python(strat, deg_bound=max(deg_bound,
|
|
532
|
+
first_deg_bound),
|
|
533
|
+
opt_lazy=opt_lazy, over_deg_bound=0,
|
|
534
|
+
prot=True)
|
|
535
|
+
strat.opt_lazy = opt_lazy
|
|
536
|
+
print("INITIALIZED")
|
|
537
|
+
branch(strat, [])
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
def GPS_with_non_binary_proof_path(G, proof_path, deg_bound, over_deg_bound):
|
|
541
|
+
def step(strat, trace, proof_path, pos, choice):
|
|
542
|
+
print(proof_path)
|
|
543
|
+
print("plugin: ", pos)
|
|
544
|
+
print("npairs", strat.npairs())
|
|
545
|
+
strat = GroebnerStrategy(strat)
|
|
546
|
+
print("npairs", strat.npairs())
|
|
547
|
+
print("npairs", strat.npairs())
|
|
548
|
+
for p in proof_path[pos][choice]:
|
|
549
|
+
print(p)
|
|
550
|
+
strat.add_generator_delayed(Polynomial(p))
|
|
551
|
+
|
|
552
|
+
print("npairs", strat.npairs())
|
|
553
|
+
print("pos:", pos)
|
|
554
|
+
strat = symmGB_F2_python(strat, deg_bound=deg_bound,
|
|
555
|
+
over_deg_bound=over_deg_bound, prot=True)
|
|
556
|
+
print("npairs", strat.npairs())
|
|
557
|
+
pos = pos + 1
|
|
558
|
+
if pos >= len(proof_path):
|
|
559
|
+
print("OVER")
|
|
560
|
+
strat = symmGB_F2_python(strat)
|
|
561
|
+
if strat.containsOne():
|
|
562
|
+
pass
|
|
563
|
+
else:
|
|
564
|
+
if pos >= len(proof_path):
|
|
565
|
+
print("npairs", strat.npairs())
|
|
566
|
+
# bug: may contain Delayed polynomials
|
|
567
|
+
print("!!!!!!! SOLUTION", trace)
|
|
568
|
+
raise Exception
|
|
569
|
+
# yield trace
|
|
570
|
+
branch(strat, trace + [(pos, choice)], proof_path, pos)
|
|
571
|
+
# workaround because of stack depth
|
|
572
|
+
# step(strat,trace+[(var,val)],var-1, 0)
|
|
573
|
+
# step(strat,trace+[(var,val)],var-1, 1)
|
|
574
|
+
|
|
575
|
+
def branch(strat, trace, proof_path, pos):
|
|
576
|
+
for i in range(len(proof_path[pos])):
|
|
577
|
+
step(strat, trace, proof_path, pos, i)
|
|
578
|
+
|
|
579
|
+
strat = GroebnerStrategy(G[0].ring())
|
|
580
|
+
strat.add_generator(G[0])
|
|
581
|
+
for g in G[1:]:
|
|
582
|
+
strat.add_generator_delayed(g)
|
|
583
|
+
branch(strat, [], proof_path, 0)
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
def symmGB_F2_C(G, opt_exchange=True,
|
|
587
|
+
deg_bound=1000000000000, opt_lazy=False,
|
|
588
|
+
over_deg_bound=0, opt_red_tail=True,
|
|
589
|
+
max_growth=2.0, step_factor=1.0,
|
|
590
|
+
implications=False, prot=False,
|
|
591
|
+
full_prot=False, selection_size=1000,
|
|
592
|
+
opt_allow_recursion=False, use_noro=False, use_faugere=False,
|
|
593
|
+
ll=False, opt_linear_algebra_in_last_block=True,
|
|
594
|
+
max_generators=None, red_tail_deg_growth=True,
|
|
595
|
+
modified_linear_algebra=True, matrix_prefix='',
|
|
596
|
+
draw_matrices=False):
|
|
597
|
+
if use_noro:
|
|
598
|
+
raise NotImplementedError("noro not implemented for symmgb")
|
|
599
|
+
if isinstance(G, list):
|
|
600
|
+
if not G:
|
|
601
|
+
return []
|
|
602
|
+
|
|
603
|
+
G = [Polynomial(g) for g in G]
|
|
604
|
+
strat = GroebnerStrategy(G[0].ring())
|
|
605
|
+
strat.reduction_strategy.opt_red_tail = opt_red_tail
|
|
606
|
+
strat.enabled_log = prot
|
|
607
|
+
strat.opt_lazy = opt_lazy
|
|
608
|
+
strat.opt_exchange = opt_exchange
|
|
609
|
+
strat.reduction_strategy.opt_ll = ll
|
|
610
|
+
strat.opt_allow_recursion = opt_allow_recursion
|
|
611
|
+
strat.opt_linear_algebra_in_last_block = (
|
|
612
|
+
opt_linear_algebra_in_last_block)
|
|
613
|
+
strat.enabled_log = prot
|
|
614
|
+
strat.opt_modified_linear_algebra = modified_linear_algebra
|
|
615
|
+
strat.matrix_prefix = matrix_prefix
|
|
616
|
+
strat.opt_draw_matrices = draw_matrices
|
|
617
|
+
strat.reduction_strategy.opt_red_tail_deg_growth = red_tail_deg_growth
|
|
618
|
+
|
|
619
|
+
strat.redByReduced = False # True
|
|
620
|
+
|
|
621
|
+
for g in G: # [1:]:
|
|
622
|
+
if not g.is_zero():
|
|
623
|
+
strat.add_generator_delayed(g)
|
|
624
|
+
strat.symmGB_F2()
|
|
625
|
+
return strat
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
def normal_form(poly, ideal, reduced=True):
|
|
629
|
+
r"""
|
|
630
|
+
Simple normal form computation of a polynomial against an ideal.
|
|
631
|
+
|
|
632
|
+
TESTS::
|
|
633
|
+
|
|
634
|
+
sage: from sage.rings.polynomial.pbori import declare_ring, normal_form
|
|
635
|
+
sage: r=declare_ring(['x','y'], globals())
|
|
636
|
+
sage: normal_form(x+y, [y],reduced=True)
|
|
637
|
+
x
|
|
638
|
+
sage: normal_form(x+y,[x,y])
|
|
639
|
+
0
|
|
640
|
+
"""
|
|
641
|
+
ring = poly.ring()
|
|
642
|
+
strat = ReductionStrategy(ring)
|
|
643
|
+
strat.opt_red_tail = reduced
|
|
644
|
+
ideal = [Polynomial(p) for p in ideal if p != 0]
|
|
645
|
+
ideal = sorted(ideal, key=Polynomial.lead)
|
|
646
|
+
last = None
|
|
647
|
+
for p in ideal:
|
|
648
|
+
if p.lead() != last:
|
|
649
|
+
strat.add_generator(p)
|
|
650
|
+
else:
|
|
651
|
+
warn("%s will not used for reductions" % p)
|
|
652
|
+
last = p.lead()
|
|
653
|
+
return strat.nf(poly)
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
def _test():
|
|
657
|
+
import doctest
|
|
658
|
+
doctest.testmod()
|
|
659
|
+
|
|
660
|
+
|
|
661
|
+
if __name__ == "__main__":
|
|
662
|
+
_test()
|