Zulip Chat Archive
Stream: general
Topic: compute_total_degree
Bolton Bailey (Aug 29 2023 at 21:50):
I saw #6221 on the queue and I thought it might be useful to have something similar for my project (which currently lives in #5297) to compute total degrees of MvPolynomials. @Damiano Testa does this PR work for MvPolynomials/do you think it would be easy for me to basically replicate declaration-by-declaration for MvPolynomials?
Damiano Testa (Aug 30 2023 at 04:57):
The PR certainly does not work out of the box for MvPolynomials. It would certainly be possible to adapt it, but I do not know how easy it would be.
Damiano Testa (Aug 30 2023 at 04:58):
If/when the current PR gets merged, I will take a look at MvPolynomials, but Polynomials seem like the natural initial testing ground!
Bolton Bailey (Aug 30 2023 at 23:27):
Is this tactic usable to introduce new hypotheses? Can I write something like ccompute_degree (X^2 + X + 1) as hd
and have hd : degree (X^2 + X + 1) = 2
appear in my hypotheses?
Damiano Testa (Aug 31 2023 at 02:50):
At the moment, no, but you can write
have hd : degree (X ^ 2 + X + 1) = 2 := by compute_degree
and it will try to compute the degree. It should be easy to add this functionality, but I did not want to make the PR longer to simplify the review process.
Damiano Testa (Aug 31 2023 at 02:52):
Note that, internally, the tactic does not use the value that you give for the expected degree and computes its own guess, so the = 2
in the example is really superfluous information.
Damiano Testa (Aug 31 2023 at 02:53):
However, in its current form, the tactic requires that something be present (and it should tell you that it expected to see a 2
, if you give it a different number.
Bolton Bailey (Aug 31 2023 at 19:30):
Right ok. My goal is a tactic that takes an equality p = q
of MvPolynomials and then applies the Schwartz-Zippel lemma to "prove" the equality by generating a probabilistic test of the fact that p-q = 0
. The S-Z lemma depends on having an upper bound on the total degree, so it seems like at some point I will want to be able to produce a proof of an upper bound without necessarily having the degree to start with (in fact, the point is that p-q
has degree 0 but that we don't know this at the start, only that we have a particular bound on the degree).
Bolton Bailey (Aug 31 2023 at 19:33):
Thinking about it more, I guess one approach is just to hard-code a large number like 10^24 as the degree bound, and this would work pretty consistently for the use cases I imagine, but would not actually require knowing the degree. But if I wanted to use the test for very high-degree polynomials, it could eat into the soundness of the test, so I might want to just run code to tell me a degree bound at that point.
Bolton Bailey (Aug 31 2023 at 19:37):
I guess the point is that computing totalDegree = x
would seem to be disanalogous to the single-variable polynomial setting, but I don't need to do that. I just need to be able to prove goals of the form totalDegree <= 10^24
, and this seems like it could work exactly the same way it does in the single variable setting (this I take it is by recursively bounding the degree of subexpressions).
Damiano Testa (Aug 31 2023 at 21:14):
Proving upper bounds on the degree is much simpler than computing the degree. The tactic could be significantly shorter if that is all you wanted.
Making it work for total_degree
should not be hard, but would also require a substantial amount of changes, since currently all the matching and lemmas are about Polynomial
s.
Damiano Testa (Aug 31 2023 at 21:16):
Are the polynomials that you produce "actual" polynomials, in the same sense that 3
is a natural number, or are they polynomials in the sense that n
is a natural number?
Bolton Bailey (Aug 31 2023 at 21:46):
My goal is to be able to "prove" the things that ring
does, but asymptotically faster. I want to convert ring expressions into polynomials over their atoms and prove them equivalent as polynomials.
Damiano Testa (Sep 01 2023 at 11:00):
If they are "black box" polynomials, the current tactic will not really be very useful. compute_degree
expects something like natDegree (C 4 * X ^ 8 + 5) = 7
, with atomic building blocks such as X, C _, monomial _ _
and then "algebraic operations" combining them.
It attempts to do something meaningful with expressions such as f : R[X]
, but it won't use anything from context to make even the most trivial estimate as to what the degree of f
could be.
Damiano Testa (Sep 01 2023 at 11:00):
Do you have a sample of what kinds of expressions you would like to pass to the tactic?
Bolton Bailey (Sep 01 2023 at 19:07):
What I would like to do is something like the following:
- I start with an expression like
\forall (a b : R), (a + b)^2 = a^2 + 2 * a * b + b^2
-
I transform the atoms into evaluations of MvPolynomials (is this what the Qq library is for?) something like
let f (quoted_z : TypeOfExpressions) : R := <quoted_a maps to a, quoted_b maps to b and so forth>
Now the goal is equivalent to
(eval f (X quoted_a) + eval f (X quoted_b))^2 = (eval f (X quoted_a) )^2 + 2 * (eval f (X quoted_a) ) * (eval f (X quoted_b)) + (eval f (X quoted_b))^2
Which simplifies to
eval f (X quoted_a + X quoted_b)^2 = eval f (X quoted_a)^2 + C 2 * X quoted_a * X quoted_b + (X quoted_b)^2
-
Apply
congr
to reduce to
(X quoted_a + X quoted_b)^2 = (X quoted_a)^2 + C 2 * X quoted_a * X quoted_b + (X quoted_b)^2
- Bound the degree of these polynomials (which are over the type of quoted expressions) and prove them equal.
Bolton Bailey (Sep 01 2023 at 19:10):
So I think all I need really is X
and C
, I don't need monomial
.
Damiano Testa (Sep 02 2023 at 09:59):
I had some Lean 3 code for converting (some) atoms in an algebraic expression in independent variables of a polynomial. It would have to be rewritten, but my recollection is that it was fairly easy to write an implementation that works most of the time, but tricky to do it robustly.
Damiano Testa (Sep 02 2023 at 10:01):
With respect to the computation of the degree of multi-variable polynomials, I am fairly confident that this is easier to automate robustly. The compute_degree
tactic got a make-over (thanks Kyle!) and hopefully will be merged soon. Once that one is in, I will take a look into extending it to also work for multivariable polynomials.
Damiano Testa (Sep 02 2023 at 10:03):
On the topic of getting the tactic to take an optional polynomial as an argument and having compute_degree h : pol
leave h : degree pol = ...
in context, this should not be hard. There is the small question of passing the information of whether you want the natDegree
or the degree
, whether you want to name or not the resulting hypothesis, but technically everything should be there.
Damiano Testa (Sep 02 2023 at 10:04):
What I think would make the extension easier to use is to allow underscores in the term pol
and let the tactic guess that you want to compute the degree of the first subexpression of something in context that unifies with what you gave it. Here is an example.
Damiano Testa (Sep 02 2023 at 10:08):
In context, there is hm : Monic (X ^ 3 + (2 * X ^ 2 + 5))
. Writing
compute_degree _
adds the hypothesisdegree (X ^ 3 + (2 * X ^ 2 + 5)) = 3
to the context;compute_degree 2 * _ + _
adds the hypothesisdegree (2 * X ^ 2 + 5) = 2
to the context.
This should also be relatively straightforward. Still, I would wait for this until the current version of the tactic is merged!
Damiano Testa (Sep 02 2023 at 10:10):
In fact, regardless of the underscores, maybe this extension could be called have_degree/have_natDegree
, rather that compute_degree
.
Damiano Testa (Sep 02 2023 at 14:42):
compute_degree
got merged! Thank you, Kyle!
If you have a goal of the form natDegree (reasonably explicit polynomial) = n
(or variations with degree
or ≤
, then chances are that compute_degree
will make progress on it! And compute_degree!
will try harder.
If you use it and you have questions, bug reports, suggestions, do let me know!
Eric Rodriguez (Nov 27 2023 at 18:34):
Hi Damiano, been loving compute_degree
! Is it an easy modification for it to support stuff like (A : R) \smul X ^ n : R[X]
? I see it has support for monomial
, and likely I should be writing things in that sort of form...
Damiano Testa (Nov 27 2023 at 20:39):
Eric, I am very happy that you enjoy compute_degree
!
I think that adding support for \smul
should be relatively straightforward, since the lemmas docs#Polynomial.natDegree_smul_le and docs#Polynomial.degree_smul_le are already in place.
The lemma docs#Polynomial.natDegree_smul_ite seems to be missing, so the whole PR is probably a couple of extra lines of tactic code, the extra lemma and a couple of tests.
If you can supply a "real-world" test for the tactic, I can take care of the rest of the PR! :wink:
Damiano Testa (Nov 27 2023 at 21:16):
#8666 waiting for a good test!
Michael Stoll (Nov 27 2023 at 21:19):
Can compute_degree
perhaps be taught to also deal with goals of the form Monic f
?
Damiano Testa (Nov 27 2023 at 21:21):
Michael, it certainly can, and it is probably also quite a simple extension. I wonder if maybe the name of the tactic should change, though.
Damiano Testa (Nov 27 2023 at 21:30):
The tactic essentially breaks up the degree computation in two parts:
- the easy part is showing an inequality and this normally is always successful;
- the hard part is showing that the coefficient of top degree is non-zero and this is where the tactic typically can get stuck.
Also, when faced with a goal degree f = n
, the tactic does not actually use the information that n
is given, but replaces straight away the actual degree with a metavariable. This means that it is able to get its own estimate of the degree and to compare it with the given one. So, when trying to prove monicity, you would still begin with a metavariable for the degree and close the final goal with rfl
to get the actual degree.
To prove monic, you then have a goal of coeff ... = 1
instead of coeff ... ≠ 0
: such goals probably get stuck in similar ways! So, I expect a similar performance of Monic f
and degree f = n
.
Damiano Testa (Nov 27 2023 at 21:31):
This addition is slightly lengthier than the support for smul
, but probably still quite short.
Damiano Testa (Nov 27 2023 at 22:33):
@Michael Stoll, do you have some use-case for the monic extension? It might be that this simple-minded macro already goes a long way to proving monicity.
open Polynomial
macro "monicity" : tactic =>
`(tactic| (apply monic_of_natDegree_le_of_coeff_eq_one <;> compute_degree))
macro "monicity!" : tactic =>
`(tactic| (apply monic_of_natDegree_le_of_coeff_eq_one <;> compute_degree!))
example {R} [Semiring R] [Nontrivial R] : Monic (1 * X ^ 5 + X ^ 6 * monomial 10 1 : R[X]) := by
monicity!
Michael Stoll (Nov 27 2023 at 22:36):
In the context of my seminar, one project is to formalize Eisenstein integers, and one possibility would start somewhat like the following.
import Mathlib
open BigOperators Polynomial
noncomputable
abbrev minpol := (X^2 + X + 1 : ℤ[X])
abbrev EisensteinInt := AdjoinRoot minpol
namespace EisensteinInt
open AdjoinRoot
lemma deg_minpol_eq_two : natDegree minpol = 2 := by
simp only [minpol]
compute_degree!
lemma monic_minpol : Monic minpol := by
simp only [minpol, Monic, leadingCoeff, deg_minpol_eq_two]
compute_degree
This is where the question came up.
Eric Rodriguez (Nov 27 2023 at 22:38):
Damiano Testa said:
Michael Stoll, do you have some use-case for the monic extension? It might be that this simple-minded macro already goes a long way to proving monicity.
macro "monicity" : tactic => `(tactic| (apply monic_of_natDegree_le_of_coeff_eq_one <;> compute_degree)) macro "monicity!" : tactic => `(tactic| (apply monic_of_natDegree_le_of_coeff_eq_one <;> compute_degree!)) example {R} [Semiring R] [Nontrivial R] : Monic (1 * X ^ 5 + X ^ 6 * monomial 10 1 : R[X]) := by monicity!
may be worth PRing this straight away!
I also got reminded by Michael's proofs that leadingCoeff
is another good target. If you're looking for a new name, maybe norm_poly
to match norm_num
in some way?
Damiano Testa (Nov 27 2023 at 22:42):
#8668 adds monicity
.
Damiano Testa (Nov 27 2023 at 22:42):
As for the name, I remember that maybe it was suggested that compute_degree
might be a norm_num
extension. Maybe this is even more the case for all of these auxiliary tactics/macros that are based on it.
Damiano Testa (Nov 27 2023 at 22:44):
By the way, while I think that the extension to support smul
is probably quite robust (at least, as robust as the rest of compute_degree
), I feel a little less confident about the monicity
macro.
Damiano Testa (Nov 27 2023 at 22:46):
@Michael Stoll, with the two macros above, this also works
lemma monic_minpol : Monic minpol := by
unfold minpol
monicity
Last updated: Dec 20 2023 at 11:08 UTC