passagemath-brial 10.6.48__cp314-cp314t-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.
- passagemath_brial/__init__.py +3 -0
- passagemath_brial-10.6.48.dist-info/METADATA +97 -0
- passagemath_brial-10.6.48.dist-info/RECORD +40 -0
- passagemath_brial-10.6.48.dist-info/WHEEL +5 -0
- passagemath_brial-10.6.48.dist-info/top_level.txt +3 -0
- passagemath_brial.libs/libbrial-83985df5.so.3.0.7 +0 -0
- passagemath_brial.libs/libbrial_groebner-1ab6687f.so.3.0.7 +0 -0
- passagemath_brial.libs/libgcc_s-2d945d6c.so.1 +0 -0
- passagemath_brial.libs/libm4ri-49c29486.so.2.0.1 +0 -0
- passagemath_brial.libs/libpng16-cbcab1bc.so.16.54.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-314t-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()
|