ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Tue, 17 Jan 2017 10:02:26 +0100How to dynamically add boolean variables?https://ask.sagemath.org/question/36279/how-to-dynamically-add-boolean-variables/ I want to experiment with Groebner bases for a system of equations in boolean unknowns. In order to simplify equations I would like to dynamically insert new variables for some terms. Is this possible somehow?
An example could be:
F = BooleanPolynomialRing(4, ["x0", "x1", "x2", "x3"])
F.inject_variables()
eqns = [x0 + x1*x2 + x3 + 1, x0 + x1*x2*x3, x0 + 1]
# now add 'y == x1*x2'
eqns = [x0 + y + x3 + 1, x0 + y*x3, x0 + 1] # NameError: name 'y' is not defined
Fri, 13 Jan 2017 09:02:13 +0100https://ask.sagemath.org/question/36279/how-to-dynamically-add-boolean-variables/Answer by tmonteil for <p>I want to experiment with Groebner bases for a system of equations in boolean unknowns. In order to simplify equations I would like to dynamically insert new variables for some terms. Is this possible somehow?</p>
<p>An example could be:</p>
<pre><code>F = BooleanPolynomialRing(4, ["x0", "x1", "x2", "x3"])
F.inject_variables()
eqns = [x0 + x1*x2 + x3 + 1, x0 + x1*x2*x3, x0 + 1]
# now add 'y == x1*x2'
eqns = [x0 + y + x3 + 1, x0 + y*x3, x0 + 1] # NameError: name 'y' is not defined
</code></pre>
https://ask.sagemath.org/question/36279/how-to-dynamically-add-boolean-variables/?answer=36299#post-id-36299I am not sure about the meaning of your question, but is there something wrong with using Python names ?
sage: F = BooleanPolynomialRing(4, ["x0", "x1", "x2", "x3"])
sage: F.inject_variables()
Defining x0, x1, x2, x3
sage: y = x1*x2
sage: eqns = [x0 + y + x3 + 1, x0 + y*x3, x0 + 1]
sage: eqns
[x0 + x1*x2 + x3 + 1, x0 + x1*x2*x3, x0 + 1]
Sun, 15 Jan 2017 13:45:13 +0100https://ask.sagemath.org/question/36279/how-to-dynamically-add-boolean-variables/?answer=36299#post-id-36299Comment by asante for <p>I am not sure about the meaning of your question, but is there something wrong with using Python names ?</p>
<pre><code>sage: F = BooleanPolynomialRing(4, ["x0", "x1", "x2", "x3"])
sage: F.inject_variables()
Defining x0, x1, x2, x3
sage: y = x1*x2
sage: eqns = [x0 + y + x3 + 1, x0 + y*x3, x0 + 1]
sage: eqns
[x0 + x1*x2 + x3 + 1, x0 + x1*x2*x3, x0 + 1]
</code></pre>
https://ask.sagemath.org/question/36279/how-to-dynamically-add-boolean-variables/?comment=36310#post-id-36310Oh, that's actually a good idea, I hadn't thought of this :D
But I still have another concern: I might want to actually add the variable y to the system of equations, so that the Groebner basis algorithms work with y - maybe this has some advantages for Groebner bases? Using an ordinary python variable does not help in this way, right?Mon, 16 Jan 2017 15:22:27 +0100https://ask.sagemath.org/question/36279/how-to-dynamically-add-boolean-variables/?comment=36310#post-id-36310Answer by ndomes for <p>I want to experiment with Groebner bases for a system of equations in boolean unknowns. In order to simplify equations I would like to dynamically insert new variables for some terms. Is this possible somehow?</p>
<p>An example could be:</p>
<pre><code>F = BooleanPolynomialRing(4, ["x0", "x1", "x2", "x3"])
F.inject_variables()
eqns = [x0 + x1*x2 + x3 + 1, x0 + x1*x2*x3, x0 + 1]
# now add 'y == x1*x2'
eqns = [x0 + y + x3 + 1, x0 + y*x3, x0 + 1] # NameError: name 'y' is not defined
</code></pre>
https://ask.sagemath.org/question/36279/how-to-dynamically-add-boolean-variables/?answer=36308#post-id-36308I can't see any method for adding new variables to a boolean polynomial ring. I think you have to define a new ring with additional variables. There seems to be nothing like substitute_expressions. So I used replacing sub-strings as a workaround.
F0 = BooleanPolynomialRing(4,'x')
F0.inject_variables()
eqns = [x0 + x1*x2 + x3 + 1, x0 + x1*x2*x3, x0 + 1]
print eqns, eqns[0].parent()
# defining new ring with additional variable y
F1 = BooleanPolynomialRing(5, 'x0,x1,x2,x3,y')
F1.inject_variables()
# changing ring for all equations
eqns1 = [F1(eq) for eq in eqns]
print eqns1, eqns1[0].parent()
# replacing expressions
eqns2 = [eval(str(eq).replace('x1*x2','y')) for eq in eqns1]
# defining new ring by removing variables
F2 = F1.remove_var(x1,x2)
# changing ring for all equations
eqns2 = [F2(eq) for eq in eqns2]
print eqns2, eqns2[0].parent()
updated answer:
def add_variables(R,new_vars):
"""
R - BooleanPolynomialRing
new_vars - string of comma- or space separated variable names
"""
if ',' in new_vars:
new = new_vars.split(',')
else:
new = new_vars.split(' ')
R_new = BooleanPolynomialRing(R.n_variables()+len(new),list(R.variable_names())+new)
R_new.inject_variables()
return R_newMon, 16 Jan 2017 12:32:12 +0100https://ask.sagemath.org/question/36279/how-to-dynamically-add-boolean-variables/?answer=36308#post-id-36308Comment by asante for <p>I can't see any method for adding new variables to a boolean polynomial ring. I think you have to define a new ring with additional variables. There seems to be nothing like substitute_expressions. So I used replacing sub-strings as a workaround.</p>
<pre><code>F0 = BooleanPolynomialRing(4,'x')
F0.inject_variables()
eqns = [x0 + x1*x2 + x3 + 1, x0 + x1*x2*x3, x0 + 1]
print eqns, eqns[0].parent()
# defining new ring with additional variable y
F1 = BooleanPolynomialRing(5, 'x0,x1,x2,x3,y')
F1.inject_variables()
# changing ring for all equations
eqns1 = [F1(eq) for eq in eqns]
print eqns1, eqns1[0].parent()
# replacing expressions
eqns2 = [eval(str(eq).replace('x1*x2','y')) for eq in eqns1]
# defining new ring by removing variables
F2 = F1.remove_var(x1,x2)
# changing ring for all equations
eqns2 = [F2(eq) for eq in eqns2]
print eqns2, eqns2[0].parent()
</code></pre>
<p>updated answer:</p>
<pre><code>def add_variables(R,new_vars):
"""
R - BooleanPolynomialRing
new_vars - string of comma- or space separated variable names
"""
if ',' in new_vars:
new = new_vars.split(',')
else:
new = new_vars.split(' ')
R_new = BooleanPolynomialRing(R.n_variables()+len(new),list(R.variable_names())+new)
R_new.inject_variables()
return R_new
</code></pre>
https://ask.sagemath.org/question/36279/how-to-dynamically-add-boolean-variables/?comment=36309#post-id-36309Yes, that's what I initially thought of - but my hope was, that there is something more "clever".Mon, 16 Jan 2017 15:20:05 +0100https://ask.sagemath.org/question/36279/how-to-dynamically-add-boolean-variables/?comment=36309#post-id-36309Comment by ndomes for <p>I can't see any method for adding new variables to a boolean polynomial ring. I think you have to define a new ring with additional variables. There seems to be nothing like substitute_expressions. So I used replacing sub-strings as a workaround.</p>
<pre><code>F0 = BooleanPolynomialRing(4,'x')
F0.inject_variables()
eqns = [x0 + x1*x2 + x3 + 1, x0 + x1*x2*x3, x0 + 1]
print eqns, eqns[0].parent()
# defining new ring with additional variable y
F1 = BooleanPolynomialRing(5, 'x0,x1,x2,x3,y')
F1.inject_variables()
# changing ring for all equations
eqns1 = [F1(eq) for eq in eqns]
print eqns1, eqns1[0].parent()
# replacing expressions
eqns2 = [eval(str(eq).replace('x1*x2','y')) for eq in eqns1]
# defining new ring by removing variables
F2 = F1.remove_var(x1,x2)
# changing ring for all equations
eqns2 = [F2(eq) for eq in eqns2]
print eqns2, eqns2[0].parent()
</code></pre>
<p>updated answer:</p>
<pre><code>def add_variables(R,new_vars):
"""
R - BooleanPolynomialRing
new_vars - string of comma- or space separated variable names
"""
if ',' in new_vars:
new = new_vars.split(',')
else:
new = new_vars.split(' ')
R_new = BooleanPolynomialRing(R.n_variables()+len(new),list(R.variable_names())+new)
R_new.inject_variables()
return R_new
</code></pre>
https://ask.sagemath.org/question/36279/how-to-dynamically-add-boolean-variables/?comment=36313#post-id-36313IMHO my proposal is quite "clever" ;-)
Using python functions for more convenience: see updated answer.Mon, 16 Jan 2017 20:07:44 +0100https://ask.sagemath.org/question/36279/how-to-dynamically-add-boolean-variables/?comment=36313#post-id-36313Comment by asante for <p>I can't see any method for adding new variables to a boolean polynomial ring. I think you have to define a new ring with additional variables. There seems to be nothing like substitute_expressions. So I used replacing sub-strings as a workaround.</p>
<pre><code>F0 = BooleanPolynomialRing(4,'x')
F0.inject_variables()
eqns = [x0 + x1*x2 + x3 + 1, x0 + x1*x2*x3, x0 + 1]
print eqns, eqns[0].parent()
# defining new ring with additional variable y
F1 = BooleanPolynomialRing(5, 'x0,x1,x2,x3,y')
F1.inject_variables()
# changing ring for all equations
eqns1 = [F1(eq) for eq in eqns]
print eqns1, eqns1[0].parent()
# replacing expressions
eqns2 = [eval(str(eq).replace('x1*x2','y')) for eq in eqns1]
# defining new ring by removing variables
F2 = F1.remove_var(x1,x2)
# changing ring for all equations
eqns2 = [F2(eq) for eq in eqns2]
print eqns2, eqns2[0].parent()
</code></pre>
<p>updated answer:</p>
<pre><code>def add_variables(R,new_vars):
"""
R - BooleanPolynomialRing
new_vars - string of comma- or space separated variable names
"""
if ',' in new_vars:
new = new_vars.split(',')
else:
new = new_vars.split(' ')
R_new = BooleanPolynomialRing(R.n_variables()+len(new),list(R.variable_names())+new)
R_new.inject_variables()
return R_new
</code></pre>
https://ask.sagemath.org/question/36279/how-to-dynamically-add-boolean-variables/?comment=36317#post-id-36317:)
+1 for your update, this nicely comprehends your first part.Tue, 17 Jan 2017 10:02:26 +0100https://ask.sagemath.org/question/36279/how-to-dynamically-add-boolean-variables/?comment=36317#post-id-36317