polyrith Tactic #
In this file, the polyrith
tactic is created. This tactic, which
works over field
s, attempts to prove a multivariate polynomial target over said
field by using multivariable polynomial hypotheses/proof terms over the same field.
Used as is, the tactic makes use of those hypotheses in the local context that are
over the same field as the target. However, the user can also specifiy which hypotheses
from the local context to use, along with proof terms that might not already be in the
local context. Note: since this tactic uses SageMath via an API call done in Python,
it can only be used with a working internet connection, and with a local installation of Python.
Implementation Notes #
The tactic linear_combination
is often used to prove such goals by allowing the user to
specify a coefficient for each hypothesis. If the target polynomial can be written as a
linear combination of the hypotheses with the chosen coefficients, then the linear_combination
tactic succeeds. In other words, linear_combination
is a certificate checker, and it is left
to the user to find a collection of good coefficients. The polyrith
tactic automates this
process using the theory of Groebner bases.
Polyrith does this by first parsing the relevant hypotheses into a form that Python can understand.
It then calls a Python file that uses the SageMath API to compute the coefficients. These
coefficients are then sent back to Lean, which parses them into pexprs. The information is then
given to the linear_combination
tactic, which completes the process by checking the certificate.
polyrith
calls an external python script scripts/polyrith_sage.py
. Because this is not a Lean
file, changes to this script may not be noticed during Lean compilation if you have already
generated olean files. If you are modifying this python script, you likely know what you're doing;
remember to force recompilation of any files that call polyrith
.
TODO #
- Give Sage more information about the specific ring being used for the coefficients. For now,
we always use ℚ (or
QQ
in Sage). - Handle
•
terms. - Support local Sage installations.
References #
- See the book Ideals, Varieties, and Algorithms by David Cox, John Little, and Donal O'Shea for the background theory on Groebner bases
- This code was heavily inspired by the code for the tactic
linarith
, which was written by Robert Lewis, who advised me on this project as part of a Computer Science independant study at Brown University.
Poly Datatype #
- const : ℚ → polyrith.poly
- var : ℕ → polyrith.poly
- add : polyrith.poly → polyrith.poly → polyrith.poly
- sub : polyrith.poly → polyrith.poly → polyrith.poly
- mul : polyrith.poly → polyrith.poly → polyrith.poly
- pow : polyrith.poly → ℕ → polyrith.poly
- neg : polyrith.poly → polyrith.poly
A datatype representing the semantics of multivariable polynomials.
Each poly
can be converted into a string.
Instances for polyrith.poly
Parsing algorithms #
The following section contains code that can convert an expr
of type Prop
into a poly
object
(provided that it is an equality)
Un-Parsing algorithms #
The following section contains code that can convert an a poly
object into a pexpr
.
Parsing SageMath output into a poly #
The following section contains code that can convert a string of appropriate format into
a poly
object. This is used later on to convert the coefficients given by Sage into
poly
objects.
A schema for success messages from the python script
Instances for polyrith.sage_json_success
- polyrith.sage_json_success.has_sizeof_inst
- polyrith.sage_json_success.non_null_json_serializable
- polyrith.sage_json_success.inhabited
A schema for failure messages from the python script
Instances for polyrith.sage_json_failure
- polyrith.sage_json_failure.has_sizeof_inst
- polyrith.sage_json_failure.non_null_json_serializable
- polyrith.sage_json_failure.inhabited
Parsing context into poly #
The following section contains code that collects hypotheses of the appropriate type
from the context (and from the list of hypotheses and proof terms specified by the user)
and converts them into poly
objects.
Connecting with Python #
The following section contains code that allows lean to communicate with a python script.
Connecting with Python #
The following section contains code that allows lean to communicate with a python script.
Interactivity #
Attempts to prove polynomial equality goals through polynomial arithmetic
on the hypotheses (and additional proof terms if the user specifies them).
It proves the goal by generating an appropriate call to the tactic
linear_combination
. If this call succeeds, the call to linear_combination
is suggested to the user.
polyrith
will use all relevant hypotheses in the local context.polyrith [t1, t2, t3]
will add proof terms t1, t2, t3 to the local context.polyrith only [h1, h2, h3, t1, t2, t3]
will use only local hypothesesh1
,h2
,h3
, and proofst1
,t2
,t3
. It will ignore the rest of the local context.
Notes:
- This tactic only works with a working internet connection, since it calls Sage using the SageCell web API at https://sagecell.sagemath.org/. Many thanks to the Sage team and organization for allowing this use.
- This tactic assumes that the user has
python3
installed and available on the path. (Test by opening a terminal and executingpython3 --version
.) It also assumes that therequests
library is installed:python3 -m pip install requests
.
Examples:
example (x y : ℚ) (h1 : x*y + 2*x = 1) (h2 : x = y) :
x*y = -2*y + 1 :=
by polyrith
-- Try this: linear_combination h1 - 2 * h2
example (x y z w : ℚ) (hzw : z = w) : x*z + 2*y*z = x*w + 2*y*w :=
by polyrith
-- Try this: linear_combination (2 * y + x) * hzw
constant scary : ∀ a b : ℚ, a + b = 0
example (a b c d : ℚ) (h : a + b = 0) (h2: b + c = 0) : a + b + c + d = 0 :=
by polyrith only [scary c d, h]
-- Try this: linear_combination scary c d + h
```