Zulip Chat Archive
Stream: new members
Topic: Simplifying real/complex expressions
Simon Jacobsson (Jul 26 2022 at 15:01):
Hello,
Sometimes I get real/complex algebraic expressions like
z * (p / 2) + (z * (p / 2) + p / 2 * (p / 2)) = z * p + p / 2 * (p / 2)
that are obviously equal and that I know I would be able to show are equal if I could rewrite them to some canonical form. For example, if I could automatically
- distribute multiplication over addition
- sort the factors of each term (and collect the numerical coefficients)
- sort the terms (and collect terms that only have different coefficients).
Is it possible to write something like this in Lean? If so, is such a thing maybe already implemented?
I have written something like this in Mathematica once, but there I was able to get the names of variables as strings which I don't know if you can in Lean. Also, in Mathematica, addition is implemented like Plus : [expr] -> expr
and automatically unpacks nested additions, while in Lean I guess you're stuck with the binary operator and have to use the associativity property explicitly each time?
Anne Baanen (Jul 26 2022 at 15:05):
You could try tactic#ring_nf, this does basically the three things you listed.
Anne Baanen (Jul 26 2022 at 15:07):
If your expression contains more complicated divisions, you might want to use tactic#field_simp first, because ring
/ ring_nf
don't know how to deal with those.
Anne Baanen (Jul 26 2022 at 15:09):
Anne Baanen said:
You could try tactic#ring_nf, this does basically the three things you listed.
Sorry, ring_nf
is documented as part of tactic#ring.
Rémy Degenne (Jul 26 2022 at 15:11):
To illustrate what Anne is explaining, here is a proof of your equality:
import analysis.complex.basic
example (z p : ℂ) :
z * (p / 2) + (z * (p / 2) + p / 2 * (p / 2)) = z * p + p / 2 * (p / 2) :=
by ring
Simon Jacobsson (Jul 26 2022 at 15:13):
Okay thank you, I guess ring_nf
is exactly what I was looking for.
Simon Jacobsson (Jul 26 2022 at 15:19):
I'm guessing that, since you only have binary addition in Lean, ring
and ring_nf
must be more advanced than a tactic simp [lemma1, lemma2, ...]
Anne Baanen (Jul 26 2022 at 15:50):
Simon Jacobsson said:
I'm guessing that, since you only have binary addition in Lean,
ring
andring_nf
must be more advanced than a tacticsimp [lemma1, lemma2, ...]
Indeed! They represent expressions as multivariate polynomials in Horner normal form.
Mario Carneiro (Jul 26 2022 at 15:50):
What do you mean by "you only have binary addition in lean"? ring
is what you want in this example, not ring_nf
, but it works roughly as you have described (except it works on multivariate polynomials so it also has to sort monomials)
Anne Baanen (Jul 26 2022 at 15:51):
If you want the gory details, see Proving Equalities in a Commutative Ring Done Right in Coq :)
Mario Carneiro (Jul 26 2022 at 15:51):
and then cross out the word Coq and write Lean :)
Anne Baanen (Jul 26 2022 at 15:52):
Although you can get pretty far if you don't care about coefficients, with simp [add_assoc, mul_assoc, add_comm, add_left_comm, mul_comm, mul_left_comm]
(or is that add_right_comm
? I always forget)
Anne Baanen (Jul 26 2022 at 15:52):
Mario Carneiro said:
and then cross out the word Coq and write Lean :)
Well, Lean doesn't even do the proof by reflection part :grinning:
Mario Carneiro (Jul 26 2022 at 15:53):
true, it's actually quite a bit different such that you might only call the original coq implementation an inspiration rather than an actual port
Mario Carneiro (Jul 26 2022 at 15:54):
(it is add_left_comm
btw)
Simon Jacobsson (Jul 26 2022 at 15:54):
Mario Carneiro said:
What do you mean by "you only have binary addition in lean"?
I just meant that, in e.g. Mathematica, the +
takes a list as an argument and a + b
is shorthand for Plus [a, b]
.
Mario Carneiro (Jul 26 2022 at 15:55):
If you simp [add_assoc, add_left_comm, add_comm]
like anne suggests, you will get an effect equivalent to mathematica's Plus [a, b, c, ...]
: the entire addition chain will get sorted by the term order
Simon Jacobsson (Jul 26 2022 at 15:55):
Anne Baanen said:
If you want the gory details, see Proving Equalities in a Commutative Ring Done Right in Coq :)
I had already opened it in a different tab :)
Mario Carneiro (Jul 26 2022 at 15:56):
the reason this doesn't really work and why ring
is a separate mechanism is that it might not sort -a
next to a
in order to cancel them
Mario Carneiro (Jul 26 2022 at 15:56):
or more generally, 2 * a
and 4 * a
and so on
Patrick Johnson (Jul 26 2022 at 16:01):
Simon Jacobsson said:
I just meant that, in e.g. Mathematica, the
+
takes a list as an argument anda + b
is shorthand forPlus [a, b]
.
We also have docs#list.sum. For example, list.sum [a, b, c]
is definitionally equal to 0 + a + b + c
, although list.sum
doesn't go well with ring
Eric Wieser (Jul 26 2022 at 19:57):
I don't think that's what it's definitionally equal to, I think it's more like a + (b + (c + 0)))
(xref #161)
Last updated: Dec 20 2023 at 11:08 UTC