Zulip Chat Archive

Stream: Is there code for X?

Topic: rewrite inside a function


Flo (Florent Schaffhauser) (Sep 09 2023 at 11:00):

Hi :wave:

Is there a routine technique to deal with equality between functions in the middle of a proof?

Here is a MWE, where I want to prove that if I divide all members of a list L by a non-zero constant c in a semifield F and then take the sum, it gives me the same result as summing the members of the list and then dividing the result by c... :new_baby:

import Mathlib.Tactic.FieldSimp
import Mathlib.Data.List.BigOperators.Lemmas

def sum_of_list_div {F : Type} [Semifield F]
  (L : List F) (c : F) (hc : c  0) : (L.map (. / c)).sum = (1 / c) * L.sum
    := by
      have aux : (fun x => x / c) = (fun x => c⁻¹ * x)
        := by
          ext x
          field_simp
      rw [aux, List.sum_map_mul_left]
      simp

Is there a standard way to avoid introducing the aux term here? Or to write a shorter definition of that term, one that would fit on a sole line?

Alex J. Best (Sep 09 2023 at 11:12):

I would rewrite using div_eq_mul_inv here, which is an existing lemma.
The only difficulty is that you need to use simp_rw as you are rewriting inside a function.
So you can do

      simp_rw [one_div, div_eq_mul_inv, List.sum_map_mul_right, mul_comm]
      simp

or even just

def sum_of_list_div {F : Type} [Semifield F]
  (L : List F) (c : F) (hc : c  0) : (L.map (. / c)).sum = (1 / c) * L.sum
    := by
      simp [one_div, div_eq_mul_inv, List.sum_map_mul_right, mul_comm]

Bonus: the linter now informs us that hc isn't actually needed for this proof, as 1/ 0= 0 etc so both sides are zero in that case

Flo (Florent Schaffhauser) (Sep 09 2023 at 11:24):

Thanks Alex, it looks really good and is exactly the kind of thing I was hoping for but could not get myself :smile:

Flo (Florent Schaffhauser) (Sep 09 2023 at 11:37):

Maybe a follow-up question would be: is simp_rw the standard way to do rewriting inside a function? Or are there other options?

Anatole Dedecker (Sep 09 2023 at 11:42):

There are other options, but simp_rw is a pretty good one. Depending on the situation you may be able to ust "enter" the function using congr and ext (or the more powerful congrm), but that typically only works if your goal is the equality you want to prove by rewriting. You can always do that in a have statement of course, but it can be a bit cumbersome. Another way is to enter conv mode (do we have some Lean4 documentation on conv?)

Flo (Florent Schaffhauser) (Sep 09 2023 at 11:57):

Thanks Anatole! Do you mean like https://leanprover-community.github.io/extras/conv.html
https://leanprover.github.io/theorem_proving_in_lean4/conv.html? I have not checked it out yet :sweat_smile:

Alex J. Best (Sep 09 2023 at 12:10):

Yes, but https://leanprover.github.io/theorem_proving_in_lean4/conv.html is a better place to read about it seeing as we haven't updated the conv docs on the website to lean 4 yet

Jireh Loreaux (Sep 10 2023 at 02:20):

There's a conv page on the actual mathlib4 docs.

Jireh Loreaux (Sep 10 2023 at 02:20):

https://leanprover-community.github.io/mathlib4_docs/docs/Conv/Guide.html

Jireh Loreaux (Sep 10 2023 at 02:20):

And

Jireh Loreaux (Sep 10 2023 at 02:20):

https://leanprover-community.github.io/mathlib4_docs/docs/Conv/Introduction.html


Last updated: Dec 20 2023 at 11:08 UTC