Zulip Chat Archive

Stream: lean4

Topic: Slow interaction


Joachim Breitner (May 20 2023 at 17:54):

Sorry for the vague question, but maybe there are obvious remidies to try: lean in vscode is getting slower and slower as I progress with my proof, that it is almost not interactive anymore. I have 550 lines, the current lemma is 80 lines, so not huge. Any quick ideas?

Ruben Van de Velde (May 20 2023 at 17:57):

80 lines in a proof is quite a lot already

Henrik Böving (May 20 2023 at 17:58):

use save while interactively writing it. Generally speaking Lean is (right now) not as smart as Coq about proof editing and will re-elaborate all of your proof script every time that it is edited, you can however manually instruct it to create checkpoints in your proof. It will then only re-elaborate stuff after those checkpoints.

So for example I can go

  tac1
  tac2
  tac3
  tac4
  save
  tac5
  <edit>

now it will only ree-lab tac5 + the stuff you added

Joachim Breitner (May 20 2023 at 18:02):

Thanks! Although even with save based on the colour flashes it re-processes more than it ought. Maybe it’s just normal and I’m spoiled, and I should write smaller lemmas :-)

Henrik Böving (May 20 2023 at 18:04):

The colour flashes are not telling the truth in this case. It says that it is re-relaborating the whole section of your file, which is correct, but save should cache the part above so it should go through faster regardless.

Henrik Böving (May 20 2023 at 18:06):

You can measure with a stopwatch if it actually works I guess :D

Kevin Buzzard (May 20 2023 at 18:23):

80 lines is really long. Open a random mathlib file and I bet that no proof in it is anywhere near that long.

Joachim Breitner (May 20 2023 at 19:48):

It’s only one page in the paper I’m mechanizing :-)

Kevin Buzzard (May 20 2023 at 20:19):

That doesn't mean it has to be one proof!

Joachim Breitner (May 20 2023 at 20:26):

True… but at least during initial development I’d prefer to be able to just plow ahead, without having to break it up just because it overwhealms lean. (I may be slightly spoiled by other tools here, and have somewhat unreasonable first expectations)

Kevin Buzzard (May 20 2023 at 20:32):

This might just be the price you pay for using a more complex type theory. Doesn't AFP compile in like 10 seconds or something? And Mathlib is half the size but takes 6 hours.

Joachim Breitner (May 20 2023 at 20:35):

Nah, AFP certainly takes a long time, too. And I’m not sure if type theory is to be blamed here; maybe I am just too optimistic about how much processing lean can re-use as I edit in leafs in a structured proofs.

Kevin Buzzard (May 20 2023 at 20:38):

I would be interested to know if the save thing actually makes your life any better. I hadn't realised that it was working, I just remember people talking about it.

Joachim Breitner (May 20 2023 at 20:39):

(I hope zulip will collapse this message, lest I be more impolite than I intend to)…
So I shouldn’t be expecting that I can write my proofs like this then ;-)

lemma lemma1
  p (hp1 : phi_le p) (hp2 : p < 1) :
   n, v p (n+1) + 1  v p (n+2)
        v p (n+2) < (n+2) - ((1-p)/p)^(n+3) := by
  intro n
  rw [phi_le] at hp1
  have hp3 : 1 < 2 * p := by nlinarith
  induction n using Nat.case_strong_induction_on
  case hz =>
    norm_num
    constructor
    . rw [ v_2 _ (le_of_lt hp2) ]
      nlinarith
    . apply lt_of_mul_lt_mul_right _ (by nlinarith : 0  p^3)
      rw [ v_2 _ (le_of_lt hp2), sub_mul, sub_mul, div_mul_cancel ]
      case h => nlinarith
      apply lt_of_sub_neg
      rw [(by nlinarith :
        3 * p * p ^ 3 - p ^ 3 * p ^ 3 - (2 * p^3 - (1 - p) ^ 3)
        = - (p-1)^2 * (p^4 + 2*p^3 + p -1 )) ]
      apply mul_neg_of_neg_of_pos
      . nlinarith
      . have : 1 < 2 * p := by nlinarith
        calc
          p ^ 4 + 2 * p ^ 3 + p - 1  2 * p ^ 3 + p - 1 := by nlinarith
          _ > p ^ 2 + p - 1 := by nlinarith
          _  0 := by nlinarith
  case hi n IH =>
    simp only [<- add_one, add_assoc, cast_add]
    norm_num
    rewrite [(?eq :
      v p (n + 3) = v p (n + 2) + 1 + p^(n+3) * (n+2 - v p (n+2)) - (1-p)^(n+3))]
    case eq =>
      trans
      . apply v_eq_v_simp p (by nlinarith) hp2
        . intro i hi1 hi2
          unfold pointless
          have : i - 1  n := by nat_intervals
          replace IH : _ := (IH (i - 1) this).1
          rw [(by cases i; simp at hi1; simp : i - 1 + 1 = i)] at IH
          rw [(by cases i; simp at hi1; simp : i - 1 + 2 = i + 1)] at IH
          exact IH
      . unfold v_simp
        rw [if_neg]; case hnc => linarith
        rw [max_eq_left]
        . simp; left; linarith
        . simp_rw [cast_add]
          have : v p (1 + (n + 1))  v p 1 + (n + 1 : ) := by
            apply iter_fast_growth_add _ 1 (n+2)
            . intro i hi1 hi2
              have : i - 1  n := by nat_intervals
              replace IH : _ := (IH (i - 1) this).1
              rw [(by cases i; simp at hi1; simp : i - 1 + 1 = i)] at IH
              rw [(by cases i; simp at hi1; simp : i - 1 + 2 = i + 1)] at IH
              exact IH
            . exact (le_refl _)
            . linarith
          simp [cast_add] at this
          rw [cast_ofNat]
          rw [(by linarith : 1 + (n + 1) = n + 2)] at this
          rw [(by linarith : n + 3 - 2 + p = p + (n + 1))]
          simp [this]

    specialize IH n (le_refl _)
    cases' IH  with IH1 IH2
    constructor
    case left =>
      suffices : (1 - p) ^ (n + 3)  p ^ (n + 3) * (n + 2 - v p (n + 2))
      linarith
      rw [  mul_inv_le_iff,  div_eq_mul_inv,  div_pow ]
      linarith
      cases hp1; positivity
    case right =>
      calc
        v p (n + 2) + 1 + p ^ (n + 3) * (n + 2 - v p (n + 2)) - (1 - p) ^ (n + 3)
          = (1 - p^(n+3)) * v p (n + 2) + 1 + p ^ (n + 3) * (n + 2) - (1 - p) ^ (n + 3) := by
          ring
        _ < (1 - p^(n+3)) * (n + 2 - ((1 - p) / p) ^ (n + 3)) + 1 + p ^ (n + 3) * (n + 2) - (1 - p) ^ (n + 3) := by
          -- congr_rel!
          apply sub_lt_sub_right
          apply add_lt_add_right
          apply add_lt_add_right
          apply mul_lt_mul_of_pos_left
          . exact IH2
          . apply lt_sub_right_of_add_lt
            rw [zero_add]
            apply pow_lt_one
            . linarith
            . exact hp2
            . simp
        _ = n + 3 - ((1 - p) / p) ^ (n + 3) := by
          simp_rw [mul_add, mul_sub, sub_mul, one_mul,  mul_pow]
          rw [mul_div_cancel']
          ring
          linarith
        _  n + 3 - ((1 - p) / p) ^ (n + 4) := by
          -- congr_rel
          apply sub_le_sub_left
          rw [ _root_.pow_succ ]
          apply mul_le_of_le_one_left
          . apply pow_nonneg
            apply div_nonneg
            linarith
            linarith
          . rw [ div_le_iff ]
            linarith
            linarith
        _ = n + 3 - (1 - p) ^ (n + 4) / p ^ (n + 4) := by
          rw [ div_pow ]

Joachim Breitner (May 20 2023 at 20:40):

It didn't noticably help here. When I was at the bottom of that proof, even with save I was tempted to switch to zulip and chat while waiting for the next apply to be processed, or the next tooltip to appear.

Kevin Buzzard (May 20 2023 at 20:42):

linarith and nlinarith might be quite costly tactics (esp nlinarith, at least in Lean 3). As is ring if you don't use it as a finishing tactic. I have no idea about the concept of compiling tactics but I thought that one of the perks of Lean 4 was that you were supposed to be able to compile tactics. Question which indicates that I have no understanding of what's going on: is nlinarith a compiled tactic? If not, what happens if you compile it (if that is indeed possible)?

Henrik Böving (May 20 2023 at 20:44):

Tactics in Isabelle too can be compiled that's not really a unique advantage of Lean. The compile tactics things can be enable with the precompiledModules flag in lake although I do remember I think it might have been Sebastian or Gabriel mentioning that the performance impact was not that crazy.

Joachim Breitner (May 20 2023 at 20:45):

My feeling is that it is less about tactics being slow, but rather that they are more often re-run than needed, i.e. not robust enough incremental editing.
It seems that an empty . to structure the proofs throws the parser off a bit (or something like that), the next character fixes that, but by then lean has thrown away all the work it did on the lines above.

Damiano Testa (May 20 2023 at 20:46):

For me, the most effective way of speeding up proofs while I'm writing them is to sorry out as much as I can, put #exit after the proof and . before it (the dot might be a Lean3 thing, I do not remember).

Kevin Buzzard (May 20 2023 at 21:00):

Yeah in Lean 3 if you really wanted to write a long proof then the trick was to get a costly part of it compiling and then sorry it out, and only unsorry at the very end. I was hoping that save would save us from having to do this.

Eric Wieser (May 21 2023 at 06:32):

Do we have an easy way to sorry things out?

Eric Wieser (May 21 2023 at 06:32):

In lean3 you could replace { with sorry {

Eric Wieser (May 21 2023 at 06:32):

I don't know how to do that with \.

Mario Carneiro (May 21 2023 at 08:59):

stop is the lean 4 spelling of sorry {

Kevin Buzzard (May 21 2023 at 09:15):

@Joachim Breitner do save and stop together solve your problems? It would be great to actually have a way of writing 80 line proofs. I kind of like the idea that in general there is a policy of "lots of small proofs, not one big proof", but perhaps that policy is partly driven by the issue which you have discovered, namely that right now "one big proof" is very inconvenient to work with. As you observe, there is not obviously a reason why this should be the case; why should we be recompiling all of a long and possibly inefficient (if we're experimenting) proof every time someone presses a button?

Joachim Breitner (May 22 2023 at 16:14):

Putting stop in various other branches of the proof certainly helps (from 7 second to 1.5 seconds until lean tells me after adding one letter that linarithx isn’t a tactic). So thanks, I’ll keep that in mind!
(save doesn’t seem to be needed and doesn't seem to do much in my simple experiments.)


Last updated: Dec 20 2023 at 11:08 UTC