An Explicit Example of the Proof of the Nullstellensatz
11 Jan 2022 - Tags: sage
I’m in an algebraic geometry class right now, and a friend was struggling conceptually with the proof of the strong nullstellensatz. I thought it might be helpful to see a concrete example of the idea, since the proof is actually quite constructive! Which brings us to this post:
Formally, we’re going to assume the weak nullstellensatz, and use it to show the strong nullstellensatz. That is, we’ll assume
The Weak Nullstellensatz
Purely algebraically, this says:
“The only way
and we’ll show
The Strong Nullstellensatz
Again, purely algebraically, this says:
“The only way
Both of these are theorems of the form “the obvious issue is the only one”.
Obviously if
Similarly, it’s obvious that if
Now, it turns out the weak nullstellensatz has computational content. That
is, if
For instance, let’s take a simple example:
First, let’s check that these polynomials really don’t have any points in common:
xxxxxxxxxx
# make a polynomial ring with generators x,y
# over QQbar, the algebraic closure of QQ.
R.<x,y> = QQbar[]
f1, f2, f3, f4 = x*y - 1, x+y, x*y^3, y*x^3
I = ideal(f1,f2,f3,f4)
I.variety() # should print out [], the empty set
Next we can see that they generate the ideal
xxxxxxxxxx
R.<x,y> = QQbar[]
f1, f2, f3, f4 = x*y - 1, x+y, x*y^3, y*x^3
I = ideal(f1,f2,f3,f4)
I == ideal(1)
Of course, this means we should be able to write
xxxxxxxxxx
R.<x,y> = QQbar[]
f1, f2, f3, f4 = x*y - 1, x+y, x*y^3, y*x^3
I = ideal(f1,f2,f3,f4)
R(1).lift(I) # prints [y^2 - 1, y, -1, 0]
and indeed, these are the coefficients to get
xxxxxxxxxx
R.<x,y> = QQbar[]
f1, f2, f3, f4 = x*y - 1, x+y, x*y^3, y*x^3
# should give 1
(y^2 - 1) * f1 + y * f2 + (-1) * f3 + 0 * f4
So now what about the strong nullstellensatz?
Let’s take
Then we expect
We’ll add a variable
Indeed, if
But then, by the weak nullstellensatz, that means these three polynomials
must generate the ideal
Indeed,
xxxxxxxxxx
R.<x,y,z> = QQbar[]
f1, f2 = x^2 + 2*x + 1, y
g = y*x + x + 1
p1,p2,p3 = var('p_1, p_2, p_3')
coeffs = R(1).lift(ideal(f1,f2,g*z-1))
show(p1 == coeffs[0])
show(p2 == coeffs[1])
show(p3 == coeffs[2])
So we know that
or
Now for the slick trick! We’re working in an ideal containing
Of course, we can clear the denominators by multiplying through by
So we found that, for some
It turns out that this is exactly how the proof goes in general!
Say you give me polynomials
Then we look at the ideal (in
which must equal
Then a computation, which sage will happily do for us, gives us polynomials
Then we plug in
This is a polynomial with
Notice that the
Another quick post today! Hopefully other people find this helpful too ^_^.
I do have a few bigger ones in the pipeline, but I won’t say exactly what. I’ve learned that saying what post you’re planning to write next is a guaranteed way to not actually write it, haha.
See you soon!
-
If you’re interested in this, you’ll want to read about gröbner bases. The actual algorithm for computing with these is buchberger’s algorithm.
I really liked Adams and Loustaunau’s An Introduction to Gröbner Bases, which is a very polite introduction. I’ve heard great things about Cox, Little, and O’Shea’s Ideals, Varieties, and Algorithms: An Introduction to Computational Algebraic Geometry and Commutative Algebra, though I haven’t gotten around to reading it myself. ↩
-
There’s a lot to be said about precisely why this trick works. It’s really because we’re looking at the homomorphism
sending
, , and .This is quickly seen to be injective, so it preserves and reflects truth. We solve our problem in
, but recover a formula of polynomials in and that gets reflected back to under this embedding.For more information about this technique of “permanence of identities”, you can see this blog post of mine. ↩