# Assigning values error

I am trying to program a toy buchberger algorithm but got stuck.

import itertools
R.<x,y,z> = PolynomialRing(QQ, order="Degrevlex")
I=ideal(x^3-2*x*y+y^4,x^2*y-2*y^2+x);

def s_poly(f1,f2):
return lcm(f1.lm(),f2.lm())*(1/f1.lt()*f1-1/f2.lt()*f2)

def buchberger(G):
F = list(G.gens())
pairs=list(itertools.combinations(F, r=2))
while pairs:
f1,f2 = pairs.pop()
h = s_poly(f1, f2).reduce()
if h != 0:
pairs.append((f, h) for f in F)
F.append(h)
return F

B=buchberger(I)


It throws an error:

ValueError: too many values to unpack (expected 2)


At the line where I .pop the elements. Weird thing is that if I just run the commands:

pairs=[(x**2,x**3)]
f,g =pairs.pop()


I get f=x^2, g=x^3 as a result an no error message.

When pairs is empty it notifies me that I can't pop from an empty list.

edit retag close merge delete

1

You example is not complete, for which G do you get an error ? Also, how is s_poly defined ?

1

should be pairs.extend((f, h) for f in F), no ?

Another error not yet pointed out: it should be s_poly(f1, f2).reduce(F) (and s_poly should be defined by manually expanding the parentheses and using polynomial division //, so that you don't land in the fraction field).

Sort by » oldest newest most voted

I see 3 issues in your code:

First, the append method for lists adds an element as the last entry of the list, for example if L = [1,2,3], then L.append([4,5,6]) will lead to L being equal to [1,2,3,[4,5,6]] (see the lists are nested). Here, it seems you want to catenate a new list of pairs to the existing list, hence you should probably replace pairs.append((f, h) for f in F) with pairs += [(f, h) for f in F]

Now that this error is fixed, another error appears:

AttributeError: 'NoneType' object has no attribute 'lm'


This is due to the following fact: in the line h = s_poly(f1, f2).reduce(), the reduce method works in place, which means that the object to which it is applied is modified, but nothing is returned, hence h will be None after that line. If you want to reduce s_poly(f1, f2) and give it the name h, you should do something like:

h = s_poly(f1, f2)
h.reduce()


Now that this error is fixed, another error appears:

AttributeError: 'sage.rings.fraction_field_element.FractionFieldElement' object has no attribute 'lm'


The reason is that when you divide polynomials with eachother in the definition of s_poly, the parent of what is returned is a fraction field. It seems that you want to deal with fractions that are actually polynomials, so that their denominator is 1. If you want to work with actual polynomials and not fractions that look like polynomials, you can convert them back to genuine polynomials (that is, elements of the ring R), for example by replacing return lcm(f1.lm(),f2.lm())*(1/f1.lt()*f1-1/f2.lt()*f2) with return R(lcm(f1.lm(),f2.lm())*(1/f1.lt()*f1-1/f2.lt()*f2)) in the definition of s_poly. By doing that, there is no need to reduce anymore, so you can just define h = s_poly(f1, f2).

more

The error seems to be that one of the "pairs" has more than two elements.

To debug, you could try replacing

        f,g = pairs.pop()


with

        fg = pairs.pop()
try:
f, g = fg
except ValueError:
print(f'Error assigning "pair": f, g = {fg}')
raise
`
more