Zulip Chat Archive

Stream: Is there code for X?

Topic: Rewrite once


Ben (Nov 22 2022 at 22:02):

Is there a way to rewrite a pattern once. Say I have d : 0 = 0 + 0 if I rw that on goal 0 = 0 I end up with new goal 0 + 0 = 0 + 0. Is there a way to apply it to only get 0 + 0 = 0?

Ben (Nov 22 2022 at 22:04):

Even better a rewrite if I can choose what side of the equality to apply it to

Kevin Buzzard (Nov 22 2022 at 22:19):

Check out the following tactics: tactic#conv_lhs , tactic#conv_rhs and tactic#nth_rewrite . In short there are several ways to do it :-)

Kevin Buzzard (Nov 22 2022 at 22:22):

Did I dream the first two tactics? I can't find them in the docs

Yaël Dillies (Nov 22 2022 at 22:24):

They are part of tactic#conv. So it's docs#tactic.conv.conv_lhs. Also worth mentioning tactic#nth_rewrite_lhs, tactic#nth_rewrite_rhs.

Kyle Miller (Nov 23 2022 at 09:26):

rw has some configuration options too. One is for specifying which occurrences should be rewritten.

example (d : 0 = 0 + 0) : 0 = 0  sorry :=
begin
  rw [d] { occs := occurrences.pos [1]},
  -- ⊢ 0 + 0 = 0 ↔ sorry
end

(I put the iff sorry in there to prevent rw from closing the 0 = 0 goal automatically with refl!)

Kyle Miller (Nov 23 2022 at 09:27):

docs#occurrences gives some explanation. The default is occurrences.all

Scott Morrison (Nov 23 2022 at 13:06):

There is a pretty weird bug/feature in occurrences: if the rule you're rewriting by has variables, they will get "stuck" when traversing the expression, and so it will not find later rewrites with different values of the variables.

Thus:

lemma foo {f :   } (d :  i, f i = i) : f 2  f 3 := begin
  rw [d] { occs := occurrences.pos [2] },
end

fails. This is why nth_rewrite exists, essentially.

Scott Morrison (Nov 23 2022 at 13:07):

I haven't got around to checking how this behaves in Lean 4, however.

Ben (Nov 23 2022 at 13:11):

Wow that is cool, didn't know you could provide arguments to tactics like that! nth_rewrite is also perfect + more readable, but good to know it is possible outside of mathlib

Kyle Miller (Nov 23 2022 at 13:12):

Just to explain this bug/feature (based on my understanding), the occurrences.pos/occurrences.neg is configuring which positions are being rewritten with respect to the positions it would have rewritten without that configuration option. That lemma foo example fails because rw [d] would have only rewritten the f 2 ==> 2.

Kyle Miller (Nov 23 2022 at 13:14):

This is because rw works by (1) finding something it can rewrite to specialize all the variables in the rewrite lemma then (2) looks for all occurrences, then (3) rewrites all the occurrences (configured by occs) simultaneously using a single eq.rec.

Scott Morrison (Nov 23 2022 at 13:14):

Maybe I should have called it a feature/bug rather than a bug/feature. Kyle's description makes is sound much more reasonable, but this behaviour can be annoying when you're trying to do a "weird" rewrite.

Kyle Miller (Nov 23 2022 at 13:15):

This is a good gotcha for occs. I have to admit I've never used it, only nth_rewrite or conv mode!

Kyle Miller (Nov 23 2022 at 13:16):

It seems like rw should have an extra configuration for how it finds the thing to rewrite in the first place...


Last updated: Dec 20 2023 at 11:08 UTC