1 | //////////////////////////////////////////////////////////////// |
---|
2 | version="version polybori.lib 4.0.0.0 Jun_2013 "; // $Id$ |
---|
3 | category="Miscellaneous"; |
---|
4 | |
---|
5 | // summary description of the library |
---|
6 | |
---|
7 | info=" |
---|
8 | LIBRARY: polybori.lib A Singular Library Interface for PolyBoRi |
---|
9 | AUTHORS: Maximilian Kammermeier: Max0791@gmx.de |
---|
10 | Susanne Scherer: sscherer90@yahoo.de |
---|
11 | |
---|
12 | SEE ALSO: Libraries, pyobject, User defined types |
---|
13 | |
---|
14 | |
---|
15 | @* |
---|
16 | |
---|
17 | OVERVIEW: A library for using @code{PolyBoRi} in the SINGULAR interface, with |
---|
18 | procedures that convert structures (polynomials, rings, ideals) in both |
---|
19 | directions. Therefore, it is possible to compute boolean groebner basis |
---|
20 | via @ref{boolean_std}. Polynomials can be converted to zero-supressed decision |
---|
21 | diagrams (zdd) and vice versa. |
---|
22 | |
---|
23 | For usability it defines the @code{PolyBoRi} types @code{bideal}, @code{bpoly}, |
---|
24 | and @code{bring} which are equivalent to Singular's @code{ideal}, @code{poly}, |
---|
25 | and @code{ring}, as well as @code{bset} which corresponds to the type @code{zdd} |
---|
26 | introduced here. In addition @code{bvar(i)} constructs the Boolean variable corresponding |
---|
27 | to @code{var(i)} from current @code{ring}; |
---|
28 | |
---|
29 | For convenience, the corresponding types can be converted explictely or implicitely |
---|
30 | while assigning. |
---|
31 | Also several SINGULAR operators were overloaded: @code{bring} comes with @code{nvars}, |
---|
32 | @code{bpoly} implements @code{lead}, @code{leadmonom} and @code{leadcoef}. |
---|
33 | Objects of this type may be added and multiplied, too. |
---|
34 | Finally, @code{bideal} yields @code{std} and @code{size} as well as addition and element access. |
---|
35 | |
---|
36 | |
---|
37 | Hence, by using these types @code{PolyBoRi} functionality |
---|
38 | can be carried out seamlessly in SINGULAR: |
---|
39 | |
---|
40 | @code{> LIB \"polybori.lib\";} @* |
---|
41 | @code{> ring r0=2,x(1..4),lp;} @* |
---|
42 | @code{> def x=bvar; // enforce Boolean variables} @* |
---|
43 | |
---|
44 | @code{> bpoly f1=x(1)+x(4);} @* |
---|
45 | @code{> bpoly f2=x(1)+x(3)*x(1);} @* |
---|
46 | @code{> bideal bI=list(f1,f2);} @* |
---|
47 | |
---|
48 | @code{> std(bI);} @* |
---|
49 | @code{_[1] = x(1) + x(4)} @* |
---|
50 | @code{_[2] = x(3)*x(4) + x(4)} @* |
---|
51 | |
---|
52 | |
---|
53 | NOTE: |
---|
54 | @texinfo |
---|
55 | For using this library SINGULAR's @code{python} interface must be available |
---|
56 | on your system. |
---|
57 | Please @code{./configure --with-python} when building SINGULAR for this purpose. |
---|
58 | |
---|
59 | There are prebuilt binary packages for @code{PolyBoRi} available |
---|
60 | from @uref{http://polybori.sf.net/}. |
---|
61 | |
---|
62 | For building your own @code{PolyBoRi} please ensure that you have @code{scons} and a |
---|
63 | development version of the boost libaries installed on you system. |
---|
64 | Then you may execute the following commands in a @code{bash}-style shell |
---|
65 | to build @code{PolyBoRi} available to @code{python}: |
---|
66 | |
---|
67 | @code{PBDIR=/path/to/custom/polybori} @* |
---|
68 | @code{wget http://downloads.sf.net/project/polybori/polybori/\\}@* |
---|
69 | @code{0.8.2/polybori-0.8.2.tar.gz} @* |
---|
70 | @code{tar -xvzf polybori-0.8.2.tar.gz} @* |
---|
71 | @code{cd polybori-0.8.2} @* |
---|
72 | @code{scons install PREFIX=$PBDIR PYINSTALLPREFIX=$PBDIR/python} @* |
---|
73 | @code{export PYTHONPATH=$PBDIR/python:$PYTHONPATH} @* |
---|
74 | @end texinfo |
---|
75 | |
---|
76 | REFERENCES: |
---|
77 | @texinfo |
---|
78 | See @uref{http://polybori.sf.net} for details about @code{PolyBoRi}. |
---|
79 | @end texinfo |
---|
80 | |
---|
81 | PROCEDURES: |
---|
82 | boolean_std(bideal); Singular ideal of boolean groebner basis of I |
---|
83 | |
---|
84 | boolean_poly_ring(ring); convert ring |
---|
85 | boolean_constant(int[, bring]); convert constant |
---|
86 | boolean_poly(poly[, int, bring]) convert polynomial |
---|
87 | direct_boolean_poly(poly[, bring]); convert polynomial direct |
---|
88 | recursive_boolean_poly(poly[, bring]); convert polynomial recursively |
---|
89 | boolean_ideal(ideal[, bring]); convert ideal |
---|
90 | boolean_set(zdd[, bring]); convert zdd |
---|
91 | |
---|
92 | |
---|
93 | from_boolean_constant(bpoly); convert boolean constant |
---|
94 | from_boolean_poly(bpoly[, int]); convert boolean polynomial |
---|
95 | direct_from_boolean_poly(bpoly); convert boolean polynomial direct |
---|
96 | recursive_from_boolean_poly(bpoly); convert boolean polynomial recursively |
---|
97 | from_boolean_ideal(bpoly); convert to ideal |
---|
98 | from_boolean_set(bset); convert to zdd |
---|
99 | |
---|
100 | |
---|
101 | bvar(i); return i-th Boolean variable |
---|
102 | poly2zdd(poly); return zdd of a given polynomial |
---|
103 | zdd2poly(zdd); return polynomial representation of a given zdd |
---|
104 | disp_zdd(zdd); return string with a visualization of a given |
---|
105 | |
---|
106 | KEYWORDS: library, polybori.lib; polybori; polybori.lib; library; pyobject; newstruct; zdd |
---|
107 | |
---|
108 | "; |
---|
109 | |
---|
110 | /////////////////////////////////////////////////////////////////////// |
---|
111 | // initialization of datatypes and constant structures |
---|
112 | |
---|
113 | static proc mod_init() |
---|
114 | "USAGE: mod_init() |
---|
115 | RETURN: none |
---|
116 | NOTE: load PolyBoRi and introduce the structures zdd and bpoly |
---|
117 | SEE ALSO: boolean_ideal, boolean_std |
---|
118 | KEYWORDS: PolyBoRi, Boolean Groebner Basis |
---|
119 | " |
---|
120 | { |
---|
121 | if (typeof(Pyobject)!="package") |
---|
122 | { |
---|
123 | LIB("pyobject.so"); |
---|
124 | } |
---|
125 | if (typeof(zdd_one)=="?unknown type?") |
---|
126 | { |
---|
127 | python_import("polybori"); |
---|
128 | |
---|
129 | // install new types |
---|
130 | |
---|
131 | newstruct("zdd","int idx,def thenBranch,def elseBranch"); |
---|
132 | newstruct("bpoly","pyobject boolpoly"); |
---|
133 | newstruct("bideal","pyobject pylist"); |
---|
134 | newstruct("bring", "pyobject pyring"); |
---|
135 | newstruct("bset", "pyobject pyset"); |
---|
136 | |
---|
137 | // install type operations |
---|
138 | |
---|
139 | system("install", "zdd", "==", zdd_check,2); |
---|
140 | system("install", "bpoly", "==", bpoly_check,2); |
---|
141 | system("install", "bpoly", "*", bpoly_mult,2); |
---|
142 | system("install", "bpoly", "+", bpoly_add,2); |
---|
143 | system("install", "zdd", "print", print_zdd, 1); |
---|
144 | system("install", "bpoly", "print", print_bpoly,1); |
---|
145 | system("install", "bideal", "print", print_bideal,1); |
---|
146 | system("install", "bideal", "size", size_bideal,1); |
---|
147 | system("install", "bpoly", "lead", lead_bpoly, 1); |
---|
148 | system("install", "bpoly", "leadmonom",lead_monom_bpoly, 1); |
---|
149 | system("install", "bpoly", "leadcoef", lead_coef_bpoly, 1); |
---|
150 | system("install", "bideal", "[", op_getitem, 2); |
---|
151 | system("install", "bideal", "+", bideal_add, 2); |
---|
152 | system("install", "bideal", "std", boolean_std, 4); |
---|
153 | |
---|
154 | // install type conversions |
---|
155 | |
---|
156 | // implemented typecasts (both directions) |
---|
157 | // SINGULAR BOOLEAN OBJECTS |
---|
158 | // ring bring |
---|
159 | // poly bpoly |
---|
160 | // zdd bset |
---|
161 | // ideal bideal |
---|
162 | // |
---|
163 | // furthermore, it is possible to switch between poly <-> zdd and bpoly <-> bset |
---|
164 | |
---|
165 | system("install", "bring", "=", ring2bring, 1); |
---|
166 | system("install", "bring", "nvars", nvars_bring, 1); |
---|
167 | |
---|
168 | system("install", "pyobject", "poly", from_boolean_poly, 1); |
---|
169 | system("install", "pyobject", "size", size_pyobject, 1); |
---|
170 | |
---|
171 | system("install", "pyobject", "bideal", pyobject2bideal,1); |
---|
172 | system("install", "bideal", "pyobject", bideal2pyobject,1); |
---|
173 | |
---|
174 | system("install", "bideal", "ideal", bideal2ideal, 4); |
---|
175 | system("install", "bideal", "=", type2bideal, 1); |
---|
176 | |
---|
177 | |
---|
178 | |
---|
179 | system("install", "zdd", "poly", zdd2poly, 1); |
---|
180 | system("install", "zdd", "=", poly2zdd, 1); |
---|
181 | |
---|
182 | system("install", "zdd", "pyobject", boolean_set, 1); |
---|
183 | system("install", "pyobject", "zdd", from_boolean_set, 1); |
---|
184 | |
---|
185 | system("install", "bset", "zdd", bset2zdd, 1); |
---|
186 | system("install", "zdd", "bset", zdd2bset, 1); |
---|
187 | |
---|
188 | system("install", "bpoly", "bset", bpoly2bset, 1); |
---|
189 | system("install", "bset", "bpoly", bset2bpoly, 1); |
---|
190 | |
---|
191 | system("install", "pyobject", "bpoly", pyobject2bpoly,1); |
---|
192 | system("install", "bpoly", "pyobject", bpoly2pyobject,1); |
---|
193 | |
---|
194 | system("install", "bpoly", "poly", bpoly2poly,1); |
---|
195 | system("install", "bpoly", "bideal", bpoly2bideal,1); |
---|
196 | system("install", "bpoly", "=", poly2bpoly,1); |
---|
197 | |
---|
198 | |
---|
199 | |
---|
200 | // initialize constant zdds |
---|
201 | |
---|
202 | zdd zdd_one; |
---|
203 | zdd_one.idx=0; |
---|
204 | zdd_one.thenBranch=int(1); |
---|
205 | zdd_one.elseBranch=int(0); |
---|
206 | zdd zdd_zero; |
---|
207 | zdd_zero.idx=0; |
---|
208 | zdd_zero.thenBranch=int(0); |
---|
209 | zdd_zero.elseBranch=int(0); |
---|
210 | export(zdd_one); |
---|
211 | export(zdd_zero); |
---|
212 | |
---|
213 | python_run("def if_then_else_idx(idx,b,c): return b.set().change(idx).union(c)"); |
---|
214 | python_run("_SINGULAR_RINGS = dict()"); |
---|
215 | python_run("_SINGULAR_RINGS_ACCESSED = 0"); |
---|
216 | python_run("def _SINGULAR_DECACHE_RING(arg): val = arg(); return 0 if val is None else val"); |
---|
217 | } |
---|
218 | } |
---|
219 | |
---|
220 | /////////////////////////////////////////////////////////////////////// |
---|
221 | // computes the leading term of a bpoly |
---|
222 | |
---|
223 | proc lead_bpoly(bpoly pp) |
---|
224 | { |
---|
225 | pyobject zero=0; |
---|
226 | bpoly zero2; |
---|
227 | zero2.boolpoly=zero; |
---|
228 | if (pp==zero2) |
---|
229 | { |
---|
230 | return(0); |
---|
231 | } |
---|
232 | else |
---|
233 | { |
---|
234 | pyobject ppb=pp.boolpoly."lead"(); |
---|
235 | return(ppb); |
---|
236 | } |
---|
237 | } |
---|
238 | |
---|
239 | /////////////////////////////////////////////////////////////////////// |
---|
240 | // computes the leading monomial of a bpoly |
---|
241 | |
---|
242 | proc lead_monom_bpoly(bpoly pp) |
---|
243 | { |
---|
244 | if (pp.boolpoly == 0) { return(0); } |
---|
245 | |
---|
246 | pyobject ppb=pp.boolpoly."lead"(); |
---|
247 | return(ppb); |
---|
248 | } |
---|
249 | |
---|
250 | /////////////////////////////////////////////////////////////////////// |
---|
251 | // computes the leading coefficient of a bpoly |
---|
252 | |
---|
253 | proc lead_coef_bpoly(bpoly pp) |
---|
254 | { |
---|
255 | if (int(pp.is_zero())) { return(0); } |
---|
256 | return(1); |
---|
257 | } |
---|
258 | |
---|
259 | /////////////////////////////////////////////////////////////////////// |
---|
260 | // converts a Singular ring into a Boolean ring |
---|
261 | |
---|
262 | proc ring2bring(def r) |
---|
263 | { |
---|
264 | bring rb; |
---|
265 | rb.pyring = boolean_poly_ring(r); |
---|
266 | return(rb); |
---|
267 | } |
---|
268 | /////////////////////////////////////////////////////////////////////// |
---|
269 | // Generate an ideal from one constructor |
---|
270 | proc bpoly2bideal(bpoly bp) |
---|
271 | { |
---|
272 | pyobject obj = list(bp); |
---|
273 | bideal bI = obj; |
---|
274 | return (bI); |
---|
275 | } |
---|
276 | |
---|
277 | /////////////////////////////////////////////////////////////////////// |
---|
278 | // get number of variables of a Boolean ring |
---|
279 | |
---|
280 | proc nvars_bring(bring rb) |
---|
281 | { |
---|
282 | return (int(rb.pyring.n_variables())); |
---|
283 | } |
---|
284 | |
---|
285 | /////////////////////////////////////////////////////////////////////// |
---|
286 | // get variable of Boolean ring corresponding to current basering |
---|
287 | |
---|
288 | proc bvar(int i) |
---|
289 | "USAGE: bvar(i); int i |
---|
290 | RETURN: i-th variable of Boolean ring corresponding to current basering |
---|
291 | SEE ALSO: boolean_poly_ring, var |
---|
292 | KEYWORDS: PolyBoRi, Boolean Groebner Basis |
---|
293 | EXAMPLE: example bvar; shows an example" |
---|
294 | { |
---|
295 | bpoly re = var(i); |
---|
296 | return (re); |
---|
297 | } |
---|
298 | example |
---|
299 | { "EXAMPLE:"; echo=2; |
---|
300 | ring r = 2,(x,y,z),Dp; |
---|
301 | bvar(1); // -> x |
---|
302 | } |
---|
303 | |
---|
304 | /////////////////////////////////////////////////////////////////////// |
---|
305 | // Internal functions for caching converted ring |
---|
306 | /////////////////////////////////////////////////////////////////////// |
---|
307 | |
---|
308 | |
---|
309 | // Mark cache as accessed and clear garbage every 100 accesses |
---|
310 | static proc bring_mark_cache(list #) |
---|
311 | { |
---|
312 | if (int(python_eval("_SINGULAR_RINGS_ACCESSED >= 100"))) { |
---|
313 | python_run("_SINGULAR_RINGS_ACCESSED = 0"); |
---|
314 | def erased = python_eval("[_k for (_k,_v) in _SINGULAR_RINGS.items() if _v() is None]"); |
---|
315 | erased = python_eval("(lambda _keys: [_SINGULAR_RINGS.pop(_k) for _k in _keys])")(erased); |
---|
316 | } |
---|
317 | python_run("_SINGULAR_RINGS_ACCESSED += 1"); |
---|
318 | } |
---|
319 | |
---|
320 | // look up whether we cached this conversion before |
---|
321 | static proc bring_from_cache(def r) |
---|
322 | { |
---|
323 | bring_mark_cache(); |
---|
324 | def result1 = python_eval("_SINGULAR_RINGS.get('" + string(r) + "', (lambda: None))"); |
---|
325 | def result = python_eval("_SINGULAR_DECACHE_RING")(result1); |
---|
326 | return (result); |
---|
327 | } |
---|
328 | |
---|
329 | // insert computed result into cache |
---|
330 | static proc bring_to_cache(def r, pyobject newring) |
---|
331 | { |
---|
332 | def value = WeakRingRef(newring); |
---|
333 | python_eval("_SINGULAR_RINGS")."__setitem__"(string(r), value); |
---|
334 | } |
---|
335 | |
---|
336 | /////////////////////////////////////////////////////////////////////// |
---|
337 | // converts a Singular ring into a python ring |
---|
338 | |
---|
339 | proc boolean_poly_ring(def r) |
---|
340 | { |
---|
341 | def cached = bring_from_cache(r); |
---|
342 | if (int(cached != int(0))) { return (cached); } |
---|
343 | |
---|
344 | def rl = ringlist(r); |
---|
345 | list blocks; |
---|
346 | string ordering; |
---|
347 | pyobject orders = python_eval("dict(lp=OrderCode.lp)"); |
---|
348 | if (size(rl[3]) >2) |
---|
349 | { |
---|
350 | orders.update(python_eval("dict(Dp=OrderCode.block_dlex)")); |
---|
351 | } |
---|
352 | else |
---|
353 | { |
---|
354 | orders.update(python_eval("dict(Dp=OrderCode.dlex)")); |
---|
355 | } |
---|
356 | |
---|
357 | int i; |
---|
358 | int counter=0; |
---|
359 | for (i=1; i<=size(ringlist(r)[3]); i++) |
---|
360 | { |
---|
361 | if (rl[3][i][1]<>"C") |
---|
362 | { |
---|
363 | ordering=rl[3][i][1]; |
---|
364 | if (counter) { blocks = blocks + list(counter) }; |
---|
365 | counter = counter + size(rl[3][i][2]); |
---|
366 | } |
---|
367 | } |
---|
368 | if(int(orders.has_key(ordering)==0)) |
---|
369 | { |
---|
370 | "// Warning: Unsupported ordering, using 'lp`!"; |
---|
371 | } |
---|
372 | |
---|
373 | def result = Ring(nvars(r), orders.get(ordering, 0), rl[2], blocks); |
---|
374 | bring_to_cache(r, result); |
---|
375 | return (result); |
---|
376 | } |
---|
377 | |
---|
378 | /////////////////////////////////////////////////////////////////////// |
---|
379 | // returns ith entry of a bideal |
---|
380 | |
---|
381 | proc op_getitem(bideal arg, def idx) |
---|
382 | { |
---|
383 | if (typeof(idx) == "int") { return (arg.pylist[idx-1]); } |
---|
384 | |
---|
385 | bideal re = (python_eval("lambda ll, idx: [ll[i] for i in idx]")(arg.pylist, idx-1)); |
---|
386 | return (re); |
---|
387 | } |
---|
388 | |
---|
389 | /////////////////////////////////////////////////////////////////////// |
---|
390 | // concatenate generators of bideals |
---|
391 | |
---|
392 | proc bideal_add(bideal arg1, bideal arg2) |
---|
393 | { |
---|
394 | pyobject tmp = python_eval("lambda x, y: list(sorted(set(x).union(set(y))))"); |
---|
395 | bideal re = tmp(arg1.pylist,arg2.pylist); |
---|
396 | return (re); |
---|
397 | } |
---|
398 | |
---|
399 | /////////////////////////////////////////////////////////////////////// |
---|
400 | // checks the equality of two bpolys |
---|
401 | |
---|
402 | proc bpoly_check(bpoly pb1,bpoly pb2) |
---|
403 | { |
---|
404 | return(pb1.boolpoly==pb2.boolpoly); |
---|
405 | } |
---|
406 | |
---|
407 | /////////////////////////////////////////////////////////////////////// |
---|
408 | // computes the multiplication of two bpolys |
---|
409 | |
---|
410 | proc bpoly_mult(bpoly pb1,bpoly pb2) |
---|
411 | { |
---|
412 | bpoly bpol; |
---|
413 | bpol.boolpoly=pb1.boolpoly*pb2.boolpoly; |
---|
414 | return(bpol); |
---|
415 | } |
---|
416 | |
---|
417 | /////////////////////////////////////////////////////////////////////// |
---|
418 | // computes the addition of two bpolys |
---|
419 | |
---|
420 | proc bpoly_add(bpoly pb1, bpoly pb2) |
---|
421 | { |
---|
422 | bpoly bpol; |
---|
423 | bpol.boolpoly=pb1.boolpoly+pb2.boolpoly; |
---|
424 | return(bpol); |
---|
425 | } |
---|
426 | |
---|
427 | /////////////////////////////////////////////////////////////////////// |
---|
428 | // convert bpoly to pyobject |
---|
429 | |
---|
430 | proc bpoly2pyobject(bpoly pb) |
---|
431 | { |
---|
432 | return(pb.boolpoly); |
---|
433 | } |
---|
434 | |
---|
435 | /////////////////////////////////////////////////////////////////////// |
---|
436 | // convert bideal to pyobject |
---|
437 | |
---|
438 | proc bideal2pyobject(bideal Ib) |
---|
439 | { |
---|
440 | return(Ib.pylist); |
---|
441 | } |
---|
442 | |
---|
443 | /////////////////////////////////////////////////////////////////////// |
---|
444 | // convert poly to bpoly |
---|
445 | |
---|
446 | proc poly2bpoly(poly p) |
---|
447 | { |
---|
448 | bpoly bpol; |
---|
449 | bpol.boolpoly=boolean_poly(p); |
---|
450 | return(bpol); |
---|
451 | } |
---|
452 | |
---|
453 | /////////////////////////////////////////////////////////////////////// |
---|
454 | // convert zdd to bset |
---|
455 | |
---|
456 | proc zdd2bset(zdd ss) |
---|
457 | { |
---|
458 | bset bs; |
---|
459 | bs.pyset=boolean_set(ss); |
---|
460 | return(bs); |
---|
461 | } |
---|
462 | |
---|
463 | /////////////////////////////////////////////////////////////////////// |
---|
464 | // convert bpoly to bset |
---|
465 | |
---|
466 | proc bpoly2bset(bpoly ss) |
---|
467 | { |
---|
468 | bset bs; |
---|
469 | bs.pyset=ss.boolpoly.set(); |
---|
470 | return(bs); |
---|
471 | } |
---|
472 | |
---|
473 | /////////////////////////////////////////////////////////////////////// |
---|
474 | // convert bset to zdd |
---|
475 | |
---|
476 | proc bset2zdd(bset ss) |
---|
477 | { |
---|
478 | zdd bs; |
---|
479 | bs=from_boolean_set(ss.pyset); |
---|
480 | return(bs); |
---|
481 | } |
---|
482 | |
---|
483 | /////////////////////////////////////////////////////////////////////// |
---|
484 | // convert bset to bpoly |
---|
485 | |
---|
486 | proc bset2bpoly(bset ss) |
---|
487 | { |
---|
488 | bpoly pb; |
---|
489 | pb.boolpoly=python_eval("Polynomial")(ss.pyset); |
---|
490 | return(pb); |
---|
491 | } |
---|
492 | |
---|
493 | /////////////////////////////////////////////////////////////////////// |
---|
494 | // convert type (ideal or list) to bideal |
---|
495 | |
---|
496 | proc type2bideal(def I) |
---|
497 | { |
---|
498 | if (typeof(I) == "ideal") { return (boolean_ideal(I)); } |
---|
499 | |
---|
500 | bideal bid; |
---|
501 | pyobject pylist; |
---|
502 | |
---|
503 | if (typeof(I) == "list") |
---|
504 | { |
---|
505 | pylist = python_eval("list()"); |
---|
506 | int i; int nlen=size(I); bpoly elt; |
---|
507 | for (i=1; i <= nlen; i++) { |
---|
508 | elt = I[i]; |
---|
509 | pylist.append(pyobject(elt)); |
---|
510 | } |
---|
511 | } |
---|
512 | else { pylist = I; } |
---|
513 | bid.pylist = pylist; |
---|
514 | return (bid); |
---|
515 | } |
---|
516 | |
---|
517 | /////////////////////////////////////////////////////////////////////// |
---|
518 | // convert bpoly to poly |
---|
519 | |
---|
520 | proc bpoly2poly(bpoly pb) |
---|
521 | { |
---|
522 | poly h=poly(pb.boolpoly); |
---|
523 | return(h); |
---|
524 | } |
---|
525 | |
---|
526 | |
---|
527 | /////////////////////////////////////////////////////////////////////// |
---|
528 | // convert bideal to ideal |
---|
529 | |
---|
530 | proc bideal2ideal(bideal Ib) |
---|
531 | { |
---|
532 | ideal I; |
---|
533 | I=from_boolean_ideal(Ib); |
---|
534 | return(I); |
---|
535 | } |
---|
536 | |
---|
537 | /////////////////////////////////////////////////////////////////////// |
---|
538 | // convert pyobject to bpoly |
---|
539 | |
---|
540 | proc pyobject2bpoly(pyobject pb) |
---|
541 | { |
---|
542 | bpoly bpol; |
---|
543 | bpol.boolpoly=pb; |
---|
544 | return(bpol); |
---|
545 | } |
---|
546 | |
---|
547 | /////////////////////////////////////////////////////////////////////// |
---|
548 | // convert pyobject to bideal |
---|
549 | |
---|
550 | proc pyobject2bideal(pyobject Ib) |
---|
551 | { |
---|
552 | bideal bid; |
---|
553 | bid.pylist=Ib; |
---|
554 | return(bid); |
---|
555 | } |
---|
556 | |
---|
557 | /////////////////////////////////////////////////////////////////////// |
---|
558 | // print bpoly |
---|
559 | |
---|
560 | proc print_bpoly(bpoly pb) |
---|
561 | { |
---|
562 | pb.boolpoly; |
---|
563 | } |
---|
564 | |
---|
565 | /////////////////////////////////////////////////////////////////////// |
---|
566 | // print bideal |
---|
567 | |
---|
568 | proc print_bideal(bideal Ib) |
---|
569 | { |
---|
570 | int nlen = size(Ib); |
---|
571 | for (int i = 1; i <= nlen; i++) |
---|
572 | { |
---|
573 | "_[" + string(i)+"] = " + string(Ib[i]); |
---|
574 | } |
---|
575 | } |
---|
576 | |
---|
577 | /////////////////////////////////////////////////////////////////////// |
---|
578 | // get size of pyobject |
---|
579 | |
---|
580 | proc size_pyobject(pyobject obj) |
---|
581 | { |
---|
582 | return (int(python_eval("len")(obj))); |
---|
583 | } |
---|
584 | |
---|
585 | /////////////////////////////////////////////////////////////////////// |
---|
586 | // get size of bideal |
---|
587 | |
---|
588 | proc size_bideal(bideal Ib) |
---|
589 | { |
---|
590 | return (size(Ib.pylist)); |
---|
591 | } |
---|
592 | |
---|
593 | |
---|
594 | /////////////////////////////////////////////////////////////////////// |
---|
595 | // print zdd |
---|
596 | |
---|
597 | proc print_zdd(zdd ss) |
---|
598 | { |
---|
599 | "zdd: "; |
---|
600 | disp_zdd(ss); |
---|
601 | } |
---|
602 | |
---|
603 | /////////////////////////////////////////////////////////////////////// |
---|
604 | // check equality |
---|
605 | |
---|
606 | proc zdd_check(zdd zdd1,zdd zdd2) |
---|
607 | "USAGE: zdd_check(zdd1,zdd2); zdd zdd1, zdd zdd2 |
---|
608 | RETURN: 0 or 1 " |
---|
609 | { |
---|
610 | if (zdd1.idx != zdd2.idx) { return (int(0)); } |
---|
611 | |
---|
612 | if (zdd1.idx == 0) { return (int(zdd1.thenBranch == zdd2.thenBranch)); } |
---|
613 | |
---|
614 | return (zdd_check(zdd1.thenBranch,zdd2.thenBranch)*zdd_check(zdd1.elseBranch,zdd2.elseBranch)); |
---|
615 | } |
---|
616 | |
---|
617 | /////////////////////////////////////////////////////////////////////// |
---|
618 | |
---|
619 | proc boolean_set(zdd ss,list #) |
---|
620 | "USAGE: boolean_set(ss[, rb]); ss zdd, rb boolean ring |
---|
621 | RETURN: default: boolean set ss in the representation of a Polybori boolean set |
---|
622 | in the ring rb==boolean_poly_ring(basering); optional input: boolean ring rb |
---|
623 | SEE ALSO: boolean_ideal, boolean_std |
---|
624 | KEYWORDS: PolyBoRi, Boolean Groebner Basis |
---|
625 | EXAMPLE: example boolean_set; shows an example" |
---|
626 | { |
---|
627 | pyobject rb; |
---|
628 | rb=check_additional_ring(#); |
---|
629 | pyobject newthen,newelse,unbek,outp; |
---|
630 | if (ss.idx==0) |
---|
631 | { |
---|
632 | if (zdd_check(ss,zdd_one)==1) { return (boolean_constant(1,rb)); } |
---|
633 | return (boolean_constant(0,rb)); |
---|
634 | } |
---|
635 | newthen=(boolean_set(ss.thenBranch,rb)); |
---|
636 | newelse=(boolean_set(ss.elseBranch,rb)); |
---|
637 | outp=if_then_else_idx(ss.idx-1,newthen,newelse); |
---|
638 | return (outp); |
---|
639 | } |
---|
640 | |
---|
641 | example |
---|
642 | { "EXAMPLE:"; echo=2; |
---|
643 | ring rs=0,(x,y,z),Dp; |
---|
644 | poly ps=(x+1)*(y+1)*(z+1); |
---|
645 | zdd fz=ps; |
---|
646 | boolean_set(fz); |
---|
647 | |
---|
648 | poly g=x*y*z+1; |
---|
649 | zdd gz=g; |
---|
650 | boolean_set(gz); |
---|
651 | |
---|
652 | ring R=0,(x(1..4)),Dp; |
---|
653 | def Rb=boolean_poly_ring(R); |
---|
654 | poly h=(x(1)+1)*(x(2)+1)*(x(3)+1)*(x(4)+1); |
---|
655 | zdd hz=h; |
---|
656 | boolean_set(hz); |
---|
657 | } |
---|
658 | |
---|
659 | /////////////////////////////////////////////////////////////////////// |
---|
660 | |
---|
661 | proc from_boolean_set(def s) |
---|
662 | "USAGE: from_boolean_set(sb); sb boolean set |
---|
663 | RETURN: Boolean set sb in the representation of a zdd |
---|
664 | SEE ALSO: boolean_ideal, boolean_std |
---|
665 | KEYWORDS: PolyBoRi, Boolean Groebner Basis |
---|
666 | EXAMPLE: example from_boolean_set; shows an example" |
---|
667 | { |
---|
668 | bpoly bp = s; |
---|
669 | pyobject sb = bp; |
---|
670 | def rb=boolean_poly_ring(basering); |
---|
671 | zdd result; |
---|
672 | def nav=sb.navigation(); |
---|
673 | int ind=int(nav.value()); |
---|
674 | def navout_then=nav.then_branch(); |
---|
675 | def navout_else=nav.else_branch(); |
---|
676 | def pb=Polynomial(sb); |
---|
677 | |
---|
678 | if (int(nav.constant())) |
---|
679 | { |
---|
680 | if (pb==1) { return(zdd_one); } |
---|
681 | return(zdd_zero); |
---|
682 | } |
---|
683 | |
---|
684 | result.idx=ind+1; |
---|
685 | pyobject one=1; |
---|
686 | def substpoly=one*rb.variable(ind); |
---|
687 | |
---|
688 | if (int(navout_then.constant())) |
---|
689 | { |
---|
690 | result.thenBranch=zdd_one; |
---|
691 | } |
---|
692 | else |
---|
693 | { |
---|
694 | result.thenBranch=from_boolean_set(BooleSet(navout_then,rb)); |
---|
695 | } |
---|
696 | if (int(navout_else.constant())) |
---|
697 | { |
---|
698 | if (subst(from_boolean_poly(pb),from_boolean_poly(substpoly),0)==1) |
---|
699 | { |
---|
700 | result.elseBranch=zdd_one; |
---|
701 | } |
---|
702 | else |
---|
703 | { |
---|
704 | result.elseBranch=zdd_zero; |
---|
705 | } |
---|
706 | } |
---|
707 | else |
---|
708 | { |
---|
709 | result.elseBranch=from_boolean_set(BooleSet(navout_else,rb)); |
---|
710 | } |
---|
711 | return(result); |
---|
712 | } |
---|
713 | |
---|
714 | example |
---|
715 | { "EXAMPLE:"; echo=2; |
---|
716 | ring r=0,(x,y,z),Dp; |
---|
717 | poly f=(x+1)*(y+1)*(z+1); |
---|
718 | bpoly fb=f; |
---|
719 | bset fs=fb; |
---|
720 | from_boolean_set(fs); |
---|
721 | |
---|
722 | poly g=x*y*z+1; |
---|
723 | bpoly gb=g; |
---|
724 | bset gs=gb; |
---|
725 | from_boolean_set(gs); |
---|
726 | |
---|
727 | ring R=0,(x(1..4)),Dp; |
---|
728 | poly h=(x(1)+1)*(x(2)+1)*(x(3)+1)*(x(4)+1); |
---|
729 | pyobject hb=boolean_poly(h); |
---|
730 | def hs=hb.set(); |
---|
731 | from_boolean_set(hs); |
---|
732 | } |
---|
733 | |
---|
734 | ////////////////////////////////////////////////////////////////////// |
---|
735 | |
---|
736 | proc direct_from_boolean_poly(def p) |
---|
737 | "USAGE: from_boolean_poly(pb); pb boolean polynomial |
---|
738 | RETURN: polynomial in Singular |
---|
739 | SEE ALSO: from_boolean_ideal, boolean_ideal, boolean_poly, boolean_poly_ring, |
---|
740 | boolean_std |
---|
741 | KEYWORDS: PolyBoRi, Boolean Groebner Basis |
---|
742 | EXAMPLE: example from_boolean_poly; shows an example" |
---|
743 | { |
---|
744 | pyobject pb = p; |
---|
745 | poly result = 0; |
---|
746 | def terms = python_eval("list")(pb.terms()); |
---|
747 | int nlen = size(terms); |
---|
748 | for (int i = 0; i < nlen; i++) |
---|
749 | { |
---|
750 | result=from_boolean_poly_update(result,terms[i]); |
---|
751 | } |
---|
752 | return (result); |
---|
753 | } |
---|
754 | |
---|
755 | example |
---|
756 | { "EXAMPLE:"; echo=2; |
---|
757 | ring r=0,(x,y,z),Dp; |
---|
758 | pyobject rb=boolean_poly_ring(r); |
---|
759 | poly f=x^2+2*y^3+3*z^3; |
---|
760 | bpoly pp=f; |
---|
761 | direct_from_boolean_poly(pp); |
---|
762 | |
---|
763 | poly g=0; |
---|
764 | bpoly pp=g; |
---|
765 | direct_from_boolean_poly(pp); |
---|
766 | } |
---|
767 | |
---|
768 | /////////////////////////////////////////////////////////////////////// |
---|
769 | // one iteration in direct_from_boolean_poly |
---|
770 | |
---|
771 | static proc from_boolean_poly_update(poly ps, pyobject pb) |
---|
772 | "USAGE: from_boolean_poly_update(ps,pb); ps polynomial, pb boolean polynomial, |
---|
773 | RETURN: update of the Singular polynomial in from_boolean_poly in one iteration |
---|
774 | SEE ALSO: from_boolean_poly |
---|
775 | { |
---|
776 | pyobject current = pb."variables"(); |
---|
777 | pyobject vars = python_eval("list")(current); |
---|
778 | int j, index; |
---|
779 | poly term = 1; |
---|
780 | pyobject currentvar; |
---|
781 | int tlen = size(vars); |
---|
782 | for (j = 0; j < tlen; j++) |
---|
783 | { |
---|
784 | currentvar = vars[j]; |
---|
785 | index = int(currentvar.index()); |
---|
786 | term = term * var(index+1); |
---|
787 | } |
---|
788 | return(ps + term); |
---|
789 | } |
---|
790 | |
---|
791 | /////////////////////////////////////////////////////////////////////// |
---|
792 | // return 1, iff int is 1 modulo 2 and 0 else |
---|
793 | |
---|
794 | static proc coeff_check(int const) |
---|
795 | "USAGE: coeff_check(const); const int |
---|
796 | RETURN: 1 iff the coefficient equals 1 modulo 2 and 0 else |
---|
797 | NOTE: helps to handle leading coefficients of rings in arbitrary characteristic |
---|
798 | SEE ALSO: recursive_boolean_poly, boolean_poly |
---|
799 | KEYWORDS: PolyBoRi, Boolean Groebner Basis |
---|
800 | EXAMPLE: example coeff_check; shows an example" |
---|
801 | { |
---|
802 | if (char(basering)==2) { return (const); } |
---|
803 | |
---|
804 | return ((const%2)*(const%2)); |
---|
805 | } |
---|
806 | example |
---|
807 | { "EXAMPLE:"; echo = 2; |
---|
808 | ring R1=5,x(1..4),lp; |
---|
809 | poly f=3*x(1)+x(2)^2; |
---|
810 | coeff_check(int(leadcoef(f))); |
---|
811 | } |
---|
812 | |
---|
813 | /////////////////////////////////////////////////////////////////////// |
---|
814 | |
---|
815 | static proc check_additional_ring(list #) |
---|
816 | "USAGE: check_additional_ring(#); |
---|
817 | NOTE: Help function to check whether an additional ring exists and if it is a |
---|
818 | bring or a ring in python." |
---|
819 | { |
---|
820 | pyobject rb; |
---|
821 | bring rbhelp; |
---|
822 | if (size(#)==0) |
---|
823 | { |
---|
824 | rb=boolean_poly_ring(basering); |
---|
825 | } |
---|
826 | else |
---|
827 | { |
---|
828 | if (typeof(#[1])=="bring") |
---|
829 | { |
---|
830 | rbhelp=#[1]; |
---|
831 | rb=rbhelp.pyring; |
---|
832 | } |
---|
833 | else |
---|
834 | { |
---|
835 | rb=#[1]; |
---|
836 | } |
---|
837 | } |
---|
838 | return(rb); |
---|
839 | } |
---|
840 | /////////////////////////////////////////////////////////////////////// |
---|
841 | |
---|
842 | proc boolean_constant(int const, list #) |
---|
843 | "USAGE: boolean_constant(const[, rb]); const constant and rb boolean ring |
---|
844 | RETURN: default: constant const in the representation of the boolean ring |
---|
845 | rb==boolean_poly_ring(basering); optional input: rb=boolean ring rb |
---|
846 | SEE ALSO: boolean_ideal, boolean_std |
---|
847 | KEYWORDS: PolyBoRi, Boolean Groebner Basis |
---|
848 | EXAMPLE: example boolean_constant; shows an example" |
---|
849 | { |
---|
850 | pyobject rb = check_additional_ring(#); |
---|
851 | if (coeff_check(const)==0) { return (rb.zero()); } |
---|
852 | |
---|
853 | return (rb.one()); |
---|
854 | } |
---|
855 | |
---|
856 | example |
---|
857 | { "EXAMPLE:"; echo = 2; |
---|
858 | ring r=7,(x,y),Dp; |
---|
859 | pyobject rb=boolean_poly_ring(r); |
---|
860 | boolean_constant(int(3)); |
---|
861 | typeof(boolean_constant(int(3))); |
---|
862 | boolean_constant(int(0)); |
---|
863 | typeof(boolean_constant(int(0))); |
---|
864 | } |
---|
865 | |
---|
866 | /////////////////////////////////////////////////////////////////////// |
---|
867 | |
---|
868 | proc boolean_poly(poly ps, list #) |
---|
869 | "USAGE: boolean_poly(ps[, dir, rb]); ps polynomial, dir integer zero or one, rb |
---|
870 | boolean ring |
---|
871 | RETURN: default: polynomial ps in the representation of the boolean ring |
---|
872 | rb==boolean_poly_ring(basering); optional input: boolean ring rb |
---|
873 | NOTE: via the optional input dir, one can choose the computation method (either |
---|
874 | direct[dir==0] or recursive[dir==1]). default: recursive |
---|
875 | SEE ALSO: boolean_ideal, boolean_std |
---|
876 | KEYWORDS: PolyBoRi, Boolean Groebner Basis |
---|
877 | EXAMPLE: example boolean_poly; shows an example" |
---|
878 | { |
---|
879 | if (size(#)==0) |
---|
880 | { |
---|
881 | return(recursive_boolean_poly(ps)); |
---|
882 | } |
---|
883 | if (size(#)==1) |
---|
884 | { |
---|
885 | if (typeof(#[1])=="int") |
---|
886 | { |
---|
887 | if (#[1]==0) { return(direct_boolean_poly(ps)); } |
---|
888 | |
---|
889 | return(recursive_boolean_poly(ps)); |
---|
890 | } |
---|
891 | return(direct_boolean_poly(ps,#[1])); |
---|
892 | } |
---|
893 | if (#[1]==0) { return(direct_boolean_poly(ps,#[2])); } |
---|
894 | |
---|
895 | return(recursive_boolean_poly(ps,#[2])); |
---|
896 | } |
---|
897 | example |
---|
898 | { "EXAMPLE:"; echo = 2; |
---|
899 | ring r=0,x(1..5),Dp; |
---|
900 | poly f=x(2)*(x(3)-x(1))+x(4)*x(5); |
---|
901 | bring rb=r; |
---|
902 | boolean_poly(f); |
---|
903 | boolean_poly(f,0); |
---|
904 | boolean_poly(f,0,boolean_poly_ring(r)); |
---|
905 | boolean_poly(f,0,rb); |
---|
906 | |
---|
907 | |
---|
908 | poly g=0; |
---|
909 | boolean_poly(g); |
---|
910 | |
---|
911 | poly g=1; |
---|
912 | boolean_poly(g); |
---|
913 | } |
---|
914 | |
---|
915 | /////////////////////////////////////////////////////////////////////// |
---|
916 | |
---|
917 | proc from_boolean_poly(def p, list #) |
---|
918 | "USAGE: from_boolean_poly(ps[, dir]); ps polynomial, dir integer zero or one |
---|
919 | RETURN: default: polynomial ps in the representation of the boolean ring |
---|
920 | NOTE: via the optional input dir, one can choose the computation method (either |
---|
921 | direct[dir==0] or recursive[dir==1]). default: direct |
---|
922 | SEE ALSO: boolean_ideal, boolean_std |
---|
923 | KEYWORDS: PolyBoRi, Boolean Groebner Basis |
---|
924 | EXAMPLE: example from_boolean_poly; shows an example" |
---|
925 | { |
---|
926 | pyobject pb = pyobject(p); |
---|
927 | |
---|
928 | if (size(#)==0) { return(direct_from_boolean_poly(pb)); } |
---|
929 | if (#[1]==0) { return(direct_from_boolean_poly(pb)); } |
---|
930 | |
---|
931 | return(recursive_from_boolean_poly(pb)); |
---|
932 | } |
---|
933 | |
---|
934 | example |
---|
935 | { "EXAMPLE:"; echo = 2; |
---|
936 | ring r=0,(x,y,z),Dp; |
---|
937 | def rb=boolean_poly_ring(r); |
---|
938 | poly f=x^2+2*y+5*z^4; |
---|
939 | bpoly pp=f; |
---|
940 | from_boolean_poly(pp); |
---|
941 | from_boolean_poly(pp,1); |
---|
942 | |
---|
943 | ring r2=5,(x,y,z),Dp; |
---|
944 | def rb2=boolean_poly_ring(r2); |
---|
945 | poly f2=x+y+z; |
---|
946 | bpoly pp2=f2; |
---|
947 | from_boolean_poly(pp); |
---|
948 | from_boolean_poly(pp,1); |
---|
949 | } |
---|
950 | |
---|
951 | /////////////////////////////////////////////////////////////////////// |
---|
952 | |
---|
953 | proc direct_boolean_poly(poly ps, list #) |
---|
954 | "USAGE: boolean_poly(ps[, rb]); ps polynomial, rb boolean ring |
---|
955 | RETURN: default: polynomial ps in the representation of the boolean ring |
---|
956 | rb==boolean_poly_ring(basering); optional input: boolean ring rb |
---|
957 | SEE ALSO: boolean_ideal, boolean_std |
---|
958 | KEYWORDS: PolyBoRi, Boolean Groebner Basis |
---|
959 | EXAMPLE: example boolean_poly; shows an example" |
---|
960 | { |
---|
961 | pyobject resultbool,rb; |
---|
962 | rb=check_additional_ring(#); |
---|
963 | |
---|
964 | int nmax= size(ps); |
---|
965 | resultbool = Polynomial(rb.zero()); |
---|
966 | for (int i = 1; i <= nmax; i++) |
---|
967 | { |
---|
968 | if ( coeff_check(int(leadcoef(ps[i]))) == 1 ) |
---|
969 | { |
---|
970 | resultbool=boolean_poly_update(resultbool,ps[i],rb); |
---|
971 | } |
---|
972 | } |
---|
973 | return (resultbool); |
---|
974 | } |
---|
975 | |
---|
976 | example |
---|
977 | { "EXAMPLE:"; echo = 2; |
---|
978 | ring r0=2,x(1..4),lp; |
---|
979 | bring rb=r0; |
---|
980 | poly f=x(1)^2+2*x(2)*(x(3))-x(4)^3; |
---|
981 | direct_boolean_poly(f); |
---|
982 | direct_boolean_poly(f,rb); |
---|
983 | |
---|
984 | ring r1=0,x,Dp; |
---|
985 | poly f=x3+2x+1; |
---|
986 | direct_boolean_poly(f); |
---|
987 | |
---|
988 | ring r2=32003,(x,y,z),Dp; |
---|
989 | poly f=xyz+20*x^2*y-3*xz+15; |
---|
990 | direct_boolean_poly(f); |
---|
991 | } |
---|
992 | |
---|
993 | /////////////////////////////////////////////////////////////////////// |
---|
994 | // one iteration in direct_boolean_poly |
---|
995 | |
---|
996 | static proc boolean_poly_update(def pb, poly ps, pyobject rb) |
---|
997 | "USAGE: boolean_poly_update(pb,ps,rb); pb boolean polynomial, ps polynomial, |
---|
998 | rb boolean ring |
---|
999 | RETURN: update of the boolean polynomial in boolean_poly in one iteration |
---|
1000 | SEE ALSO: boolean_poly |
---|
1001 | { |
---|
1002 | intvec current = leadexp(ps); |
---|
1003 | int j; |
---|
1004 | pyobject term, var_rb; |
---|
1005 | term = python_eval("Monomial")(rb); |
---|
1006 | for (j = 1; j <= size(current); j=j+1) |
---|
1007 | { |
---|
1008 | var_rb = rb.variable(j-1); |
---|
1009 | if (current[j] > 0) { term = term * var_rb; } |
---|
1010 | } |
---|
1011 | return (pb + term); |
---|
1012 | } |
---|
1013 | |
---|
1014 | /////////////////////////////////////////////////////////////////////// |
---|
1015 | |
---|
1016 | proc recursive_boolean_poly(poly ps, list #) |
---|
1017 | "USAGE: boolean_poly(ps[, rb]); ps polynomial, rb boolean ring |
---|
1018 | RETURN: default: polynomial ps in the representation of the boolean ring |
---|
1019 | rb==boolean_poly_ring(basering); optional input: rb boolean ring |
---|
1020 | SEE ALSO: boolean_ideal, boolean_std |
---|
1021 | KEYWORDS: PolyBoRi, Boolean Groebner Basis |
---|
1022 | EXAMPLE: example recursive_boolean_poly; shows an example" |
---|
1023 | { |
---|
1024 | pyobject rb; |
---|
1025 | if (size(#)==0) |
---|
1026 | { |
---|
1027 | #[1]=boolean_poly_ring(basering); |
---|
1028 | #[2]=0; |
---|
1029 | } |
---|
1030 | if (size(#)==1) |
---|
1031 | { |
---|
1032 | #[2]=0; |
---|
1033 | } |
---|
1034 | rb=check_additional_ring(#[1]); |
---|
1035 | if (#[2]==int(rb.n_variables())) |
---|
1036 | { |
---|
1037 | return (boolean_constant(int(leadcoef(ps)),rb)); |
---|
1038 | } |
---|
1039 | else |
---|
1040 | { |
---|
1041 | def xsu=var(#[2]+1); |
---|
1042 | poly p0=subst(ps,xsu,0); |
---|
1043 | poly p1=subst(ps-p0,xsu,1); |
---|
1044 | def ahelp=recursive_boolean_poly(p1,rb,#[2]+1); |
---|
1045 | def bhelp=recursive_boolean_poly(p0,rb,#[2]+1); |
---|
1046 | return (rb.variable(#[2])*ahelp+bhelp); |
---|
1047 | } |
---|
1048 | } |
---|
1049 | |
---|
1050 | example |
---|
1051 | { "EXAMPLE:"; echo = 2; |
---|
1052 | ring r0=2,x(1..4),lp; |
---|
1053 | poly f=x(1)^2+2*x(2)*(x(3))-x(4)^3; |
---|
1054 | recursive_boolean_poly(f); |
---|
1055 | |
---|
1056 | ring r1=0,x,Dp; |
---|
1057 | poly f=x3+2x+1; |
---|
1058 | recursive_boolean_poly(f); |
---|
1059 | |
---|
1060 | ring r2=32003,(x,y,z),Dp; |
---|
1061 | def br2=boolean_poly_ring(r2); |
---|
1062 | bring bbr2=r2; |
---|
1063 | poly f=xyz+20*x^2*y-3*xz+15; |
---|
1064 | recursive_boolean_poly(f,br2); |
---|
1065 | recursive_boolean_poly(f,bbr2); |
---|
1066 | } |
---|
1067 | |
---|
1068 | /////////////////////////////////////////////////////////////////////// |
---|
1069 | |
---|
1070 | proc boolean_ideal(ideal Is, list #) |
---|
1071 | "USAGE: boolean_ideal(Is[, rb]); Is Ideal, rb boolean ring |
---|
1072 | RETURN: default: ideal Is in the representation of the boolean ring |
---|
1073 | rb==boolean_poly_ring(basering); optional input: rb boolean ring |
---|
1074 | SEE ALSO: boolean_std |
---|
1075 | KEYWORDS: PolyBoRi, Boolean Groebner Basis |
---|
1076 | EXAMPLE: example boolean_ideal; shows an example" |
---|
1077 | { |
---|
1078 | pyobject rb; |
---|
1079 | rb=check_additional_ring(#); |
---|
1080 | int len=size(Is); |
---|
1081 | pyobject Ib = python_eval("list()"); |
---|
1082 | for (int i=1; i<=len; i++) |
---|
1083 | { |
---|
1084 | Ib.append(boolean_poly(Is[i],rb)); |
---|
1085 | } |
---|
1086 | bideal re; |
---|
1087 | re.pylist = Ib; |
---|
1088 | |
---|
1089 | return(re); |
---|
1090 | } |
---|
1091 | |
---|
1092 | example |
---|
1093 | { "EXAMPLE:"; echo = 2; |
---|
1094 | ring r0=2,x(1..4),lp; |
---|
1095 | poly f1=x(1)^2+2*x(2)*(x(3))-x(4)^3; |
---|
1096 | poly f2=x(1)^2-x(3)*x(1); |
---|
1097 | poly f3=x(2)+5-2*x(1); |
---|
1098 | poly f4=x(1)*x(2)-x(3); |
---|
1099 | ideal I=f1,f2,f3,f4; |
---|
1100 | boolean_ideal(I); |
---|
1101 | |
---|
1102 | ring r1=0,x,Dp; |
---|
1103 | poly f1=x3+2*x+1; |
---|
1104 | poly f2=x10-x5+2x; |
---|
1105 | poly f3=19; |
---|
1106 | ideal I=f1,f2,f3; |
---|
1107 | boolean_ideal(I); |
---|
1108 | |
---|
1109 | ring r2=32003,(x,y,z),Dp; |
---|
1110 | bring bbr2=r2; |
---|
1111 | poly f1=xyz+20*x^2*y-3*xz+15; |
---|
1112 | poly f2=32002*xy+z2; |
---|
1113 | poly f3=19; |
---|
1114 | ideal I=f1,f2,f3; |
---|
1115 | boolean_ideal(I); |
---|
1116 | boolean_ideal(I,bbr2); |
---|
1117 | } |
---|
1118 | |
---|
1119 | //////////////////////////////////////////////////////////////// |
---|
1120 | |
---|
1121 | proc from_boolean_ideal(bideal I) |
---|
1122 | "USAGE: from_boolean_ideal(I); I boolean ideal |
---|
1123 | RETURN: ideal in Singular |
---|
1124 | SEE ALSO: from_boolean_poly, boolean_ideal, boolean_poly, boolean_std, |
---|
1125 | boolean_poly_ring |
---|
1126 | KEYWORDS: PolyBoRi, Boolean Groebner Basis |
---|
1127 | EXAMPLE: example from_boolean_ideal; shows an example" |
---|
1128 | { |
---|
1129 | ideal re; |
---|
1130 | int i; |
---|
1131 | int nlen = size(I); |
---|
1132 | for (i = 1; i <= nlen; i++) |
---|
1133 | { |
---|
1134 | re[i] = from_boolean_poly(I[i]); |
---|
1135 | } |
---|
1136 | return (re); |
---|
1137 | } |
---|
1138 | |
---|
1139 | example |
---|
1140 | { "EXAMPLE:"; echo=2; |
---|
1141 | ring rs=0,(x,y,z),Dp; |
---|
1142 | def rb3=boolean_poly_ring(rs); |
---|
1143 | poly f1=x+y; |
---|
1144 | poly f2=x+z; |
---|
1145 | bpoly pp =f1; |
---|
1146 | bpoly p = f2; |
---|
1147 | bideal Ib; |
---|
1148 | list K=(p,pp); |
---|
1149 | Ib=K; |
---|
1150 | from_boolean_ideal(Ib); |
---|
1151 | |
---|
1152 | ring rs2=5,(x,y,z),Dp; |
---|
1153 | def rb4=boolean_poly_ring(rs2); |
---|
1154 | poly p1=x+y; |
---|
1155 | poly p2=x+z; |
---|
1156 | poly p3=y+z; |
---|
1157 | bpoly p = p1; |
---|
1158 | bpoly pp = p2; |
---|
1159 | bpoly ppp = p3; |
---|
1160 | bideal Ib; |
---|
1161 | list K=(p,pp,ppp); |
---|
1162 | Ib=K; |
---|
1163 | from_boolean_ideal(Ib); |
---|
1164 | } |
---|
1165 | |
---|
1166 | /////////////////////////////////////////////////////////////////////// |
---|
1167 | |
---|
1168 | proc boolean_std(bideal Is) |
---|
1169 | "USAGE: boolean_std(Is); Is ideal |
---|
1170 | RETURN: Singular ideal of the boolean groebner basis of Is |
---|
1171 | SEE ALSO: from_boolean_poly, boolean_ideal, boolean_poly, from_boolean_ideal, |
---|
1172 | boolean_poly_ring |
---|
1173 | KEYWORDS: PolyBoRi, Boolean Groebner Basis |
---|
1174 | EXAMPLE: example boolean_std; shows an example" |
---|
1175 | { |
---|
1176 | pyobject Ib = Is; |
---|
1177 | |
---|
1178 | def redIb=groebner_basis(Ib); |
---|
1179 | bideal result = redIb; |
---|
1180 | return(result); |
---|
1181 | } |
---|
1182 | |
---|
1183 | example |
---|
1184 | { "EXAMPLE:"; echo = 2; |
---|
1185 | ring r0=2,x(1..4),lp; |
---|
1186 | poly f1=x(1)^2+2*x(2)*(x(3))-x(4)^3; |
---|
1187 | poly f2=x(1)^2-x(3)*x(1); |
---|
1188 | poly f3=x(2)+5-2*x(1); |
---|
1189 | poly f4=x(1)*x(2)-x(3); |
---|
1190 | ideal I=f1,f2,f3,f4; |
---|
1191 | |
---|
1192 | boolean_std(I); // implicitely add x(i)^2-x(i) |
---|
1193 | |
---|
1194 | bideal bI=I; // alternative syntax |
---|
1195 | bideal re = std(bI); // Continue PolyBoRi computations |
---|
1196 | std(re[1..2]); |
---|
1197 | |
---|
1198 | ring r1=0,x,Dp; |
---|
1199 | poly f1=x3+2*x+1; |
---|
1200 | poly f2=x10-x5+2x; |
---|
1201 | poly f3=19; |
---|
1202 | ideal I=f1,f2,f3; |
---|
1203 | boolean_std(I); |
---|
1204 | |
---|
1205 | ring r2=32003,(x,y,z),Dp; |
---|
1206 | poly f1=xz+y+20*x^2*y; |
---|
1207 | poly f2=32002*xy+xz2+y; |
---|
1208 | ideal I=f1,f2; |
---|
1209 | boolean_std(I); |
---|
1210 | |
---|
1211 | ring r2=32003,(x,y,z),Dp; |
---|
1212 | poly f1=xyz+20*x^2*y-3*xz+15; |
---|
1213 | poly f2=32002*xy+z2; |
---|
1214 | poly f3=19*x5y; |
---|
1215 | ideal I=f1,f2,f3; |
---|
1216 | boolean_std(I); |
---|
1217 | } |
---|
1218 | |
---|
1219 | ///////////////////////////////////////////////////////////////////////// |
---|
1220 | |
---|
1221 | proc from_boolean_constant(def p) |
---|
1222 | "USAGE: from_boolean_constant(pb); pb pyobject |
---|
1223 | RETURN: constant polynomial |
---|
1224 | SEE ALSO: boolean_ideal, boolean_std |
---|
1225 | KEYWORDS: PolyBoRi, Boolean Groebner Basis |
---|
1226 | EXAMPLE: example from_boolean_constant; shows an example" |
---|
1227 | { |
---|
1228 | pyobject pb = p; |
---|
1229 | if (pb==0) { return (poly(0)); } |
---|
1230 | |
---|
1231 | return (poly(1)); |
---|
1232 | } |
---|
1233 | |
---|
1234 | example |
---|
1235 | { "EXAMPLE:"; echo = 2; |
---|
1236 | ring rs=0,(x,y,z),Dp; |
---|
1237 | def rsb=boolean_poly_ring(rs); |
---|
1238 | poly f=(x+y)*x+z; |
---|
1239 | bpoly pp=f; |
---|
1240 | from_boolean_constant(0); |
---|
1241 | from_boolean_constant(1); |
---|
1242 | from_boolean_constant(pp); |
---|
1243 | } |
---|
1244 | |
---|
1245 | /////////////////////////////////////////////////////////////////////// |
---|
1246 | |
---|
1247 | proc recursive_from_boolean_poly(def p) |
---|
1248 | "USAGE: recursive_from_boolean_poly(pb); pb boolean polynomial |
---|
1249 | RETURN: polynomial in Singular |
---|
1250 | SEE ALSO: from_boolean_poly, boolean_ideal, boolean_poly, from_boolean_ideal, |
---|
1251 | boolean_poly_ring |
---|
1252 | KEYWORDS: PolyBoRi, Boolean Groebner Basis |
---|
1253 | EXAMPLE: example recursive_from_boolean_poly; shows an example" |
---|
1254 | { |
---|
1255 | pyobject pb = p; |
---|
1256 | |
---|
1257 | if (pb==0) { return(0); } |
---|
1258 | if (pb==1) { return(1); } |
---|
1259 | |
---|
1260 | int idx = int(pb.navigation().value()); |
---|
1261 | def p0=Polynomial(pb.set().subset0(idx)); |
---|
1262 | def p1 = Polynomial(pb.set().subset1(idx)); |
---|
1263 | |
---|
1264 | return (var(idx+1)*recursive_from_boolean_poly(p1)+recursive_from_boolean_poly(p0)); |
---|
1265 | } |
---|
1266 | |
---|
1267 | example |
---|
1268 | { "EXAMPLE:"; echo = 2; |
---|
1269 | ring rs=0,(x,y,z),Dp; |
---|
1270 | def rsb=boolean_poly_ring(rs); |
---|
1271 | poly f=(x+y)*x+z; |
---|
1272 | bpoly pp=f; |
---|
1273 | recursive_from_boolean_poly(pp); |
---|
1274 | |
---|
1275 | ring rs2=2,(x,y,z),Dp; |
---|
1276 | def rsb2=boolean_poly_ring(rs2); |
---|
1277 | poly f2=(x+y)*x+x; |
---|
1278 | bpoly pp2=f2; |
---|
1279 | recursive_from_boolean_poly(pp); |
---|
1280 | } |
---|
1281 | |
---|
1282 | ///////////////////////////////////////////////////////////////////////// |
---|
1283 | |
---|
1284 | proc poly2zdd(poly ps) |
---|
1285 | "USAGE: poly2zdd(poly ps); polynomial ps |
---|
1286 | RETURN: polynomial ps in zdd representation |
---|
1287 | SEE ALSO: boolean_poly, from_boolean_set |
---|
1288 | KEYWORDS: PolyBoRi, zero-supressed decision diagram |
---|
1289 | EXAMPLE: example poly2zdd; shows an example" |
---|
1290 | { |
---|
1291 | pyobject pp=boolean_poly(ps); |
---|
1292 | pyobject pset = pp.set(); |
---|
1293 | zdd result = from_boolean_set(pset); |
---|
1294 | return(result); |
---|
1295 | } |
---|
1296 | |
---|
1297 | example |
---|
1298 | { "EXAMPLE:"; echo = 2; |
---|
1299 | ring r=0,x(1..5),Dp; |
---|
1300 | poly f=(x(1)+1)*(x(2)+1)*(x(3)+1)*x(4)*x(5); |
---|
1301 | poly2zdd(f); |
---|
1302 | |
---|
1303 | poly g=x(3); |
---|
1304 | poly2zdd(g); |
---|
1305 | } |
---|
1306 | |
---|
1307 | ///////////////////////////////////////////////////////////////////////// |
---|
1308 | |
---|
1309 | proc zdd2poly(zdd ss) |
---|
1310 | "USAGE: zdd2poly(ss); zero-supressed decision diagram ss |
---|
1311 | RETURN: zdd ss in polynomial representation |
---|
1312 | SEE ALSO:from_boolean_poly, boolean_set |
---|
1313 | KEYWORDS: PolyBoRi, Boolean Groebner Basis |
---|
1314 | EXAMPLE: example poly2zdd; shows an example" |
---|
1315 | { |
---|
1316 | def ps=boolean_set(ss); |
---|
1317 | return(from_boolean_poly(Polynomial(ps))); |
---|
1318 | } |
---|
1319 | |
---|
1320 | example |
---|
1321 | { "EXAMPLE:"; echo = 2; |
---|
1322 | ring r=0,x(1..5),Dp; |
---|
1323 | poly f=(x(1)+1)*(x(2)+1)*(x(3)+1)*x(4)*x(5); |
---|
1324 | zdd2poly(poly2zdd(f)); |
---|
1325 | |
---|
1326 | poly g=x(3); |
---|
1327 | zdd2poly(poly2zdd(g)); |
---|
1328 | |
---|
1329 | poly g=0; |
---|
1330 | zdd2poly(poly2zdd(0)); |
---|
1331 | |
---|
1332 | poly g=1; |
---|
1333 | zdd2poly(poly2zdd(01)); |
---|
1334 | } |
---|
1335 | |
---|
1336 | ///////////////////////////////////////////////////////////////////////// |
---|
1337 | |
---|
1338 | proc disp_zdd(zdd ss, list #) |
---|
1339 | "USAGE: disp_zdd(ss); zero-supressed decision diagram ss |
---|
1340 | RETURN: string containing visualization of ss |
---|
1341 | NOTE: the resulting string is the visualization of the polynomial that corresponds |
---|
1342 | to ss, but with a additional structure that comes from the zdd. Every reached else- |
---|
1343 | Branch induces a new line in the string. |
---|
1344 | SEE ALSO:zdd2poly, poly2zdd |
---|
1345 | KEYWORDS: Polybori, Boolean Groebner Basis |
---|
1346 | EXAMPLE: example disp_zdd; shows an example" |
---|
1347 | { |
---|
1348 | int dist,i; |
---|
1349 | string str,space; |
---|
1350 | if (size(#)==0) |
---|
1351 | { |
---|
1352 | dist=1; |
---|
1353 | str=" "; |
---|
1354 | } |
---|
1355 | else |
---|
1356 | { |
---|
1357 | dist=#[1]; |
---|
1358 | str=#[2]; |
---|
1359 | } |
---|
1360 | for (i=1;i<=dist+3;i++) |
---|
1361 | { |
---|
1362 | space=space+" "; |
---|
1363 | } |
---|
1364 | if (ss.idx==0) |
---|
1365 | { |
---|
1366 | if (size(space)>5) |
---|
1367 | { |
---|
1368 | return(str); |
---|
1369 | } |
---|
1370 | else |
---|
1371 | { |
---|
1372 | if (ss==zdd_one) |
---|
1373 | { |
---|
1374 | return (1); |
---|
1375 | } |
---|
1376 | else |
---|
1377 | { |
---|
1378 | return (0); |
---|
1379 | } |
---|
1380 | } |
---|
1381 | } |
---|
1382 | else |
---|
1383 | { |
---|
1384 | str=str,"x",string(ss.idx); |
---|
1385 | if (ss.thenBranch.idx!=0) |
---|
1386 | { |
---|
1387 | str=str,"("; |
---|
1388 | str=disp_zdd(ss.thenBranch,dist+3,str); |
---|
1389 | str=str,")"; |
---|
1390 | } |
---|
1391 | if ((ss.elseBranch.idx!=0)||(ss.elseBranch==zdd_one)) |
---|
1392 | { |
---|
1393 | if (ss.elseBranch==zdd_one) |
---|
1394 | { |
---|
1395 | str=str+"+1"; |
---|
1396 | } |
---|
1397 | else |
---|
1398 | { |
---|
1399 | str=str,"+"+newline+space; |
---|
1400 | str=disp_zdd(ss.elseBranch,dist+3,str); |
---|
1401 | } |
---|
1402 | } |
---|
1403 | return(str); |
---|
1404 | } |
---|
1405 | } |
---|
1406 | |
---|
1407 | example |
---|
1408 | { "EXAMPLE:"; echo = 2; |
---|
1409 | ring r1=0,(x,y,z),Dp; |
---|
1410 | poly f1=xyz+xy+xz+yz+y+z+x+1; |
---|
1411 | zdd s1=f1; |
---|
1412 | disp_zdd(s1); |
---|
1413 | |
---|
1414 | ring r2=0,x(1..6),Dp; |
---|
1415 | poly f2=x(1)+x(2)+x(3)+x(5)^2+x(6); |
---|
1416 | zdd s2=f2; |
---|
1417 | disp_zdd(s2); |
---|
1418 | |
---|
1419 | ring r4=0,x(1..6),Dp; |
---|
1420 | poly f2=x(1)+1; |
---|
1421 | zdd s2=f2; |
---|
1422 | disp_zdd(s2); |
---|
1423 | |
---|
1424 | ring r2=0,x(1..6),Dp; |
---|
1425 | poly f2=x(1)*x(2)*(x(3)-x(5)^2*x(6))+3*x(4)*x(5)-3; |
---|
1426 | zdd s2=f2; |
---|
1427 | disp_zdd(s2); |
---|
1428 | |
---|
1429 | poly f4=0; |
---|
1430 | zdd s4=f4; |
---|
1431 | disp_zdd(s4); |
---|
1432 | |
---|
1433 | poly f5=1; |
---|
1434 | zdd s5=f5; |
---|
1435 | disp_zdd(s5); |
---|
1436 | } |
---|