Zulip Chat Archive

Stream: lean4

Topic: How to `generalize` in specific locations in the goal


Gustavo Goretkin (Mar 05 2025 at 09:47):

I have a goal:

transduce_helper StateMachineType.Moore i o moore moore.s0 is =
  transduce_helper StateMachineType.Mealey i o
    { state_space := moore.state_space, s0 := moore.s0, transition := moore.transition,
      output := fun x x_1 => moore.output x }
    moore.s0 is

I want to generalize moore.s0 = s on 2 of the 3 occurrences. I want to leave s0 := moore.s0 alone.

The way I'm doing it now is

  generalize H : moore.s0 = s
  conv =>
    rhs
    rw [ H]
    congr
    . rw [H]
    . skip
  clear H

Is there a more straightforward way?

Gustavo Goretkin (Mar 05 2025 at 09:50):

The full context is here: https://gist.github.com/goretkin/623625fbeefe930a135d1390c81f70ce

Kyle Miller (Mar 05 2025 at 11:15):

Maybe you can use the rw (occs := [1,2]) [...] syntax? That rewrites just occurrences 1 and 2 for example.

The generalize syntax doesn't give any access to occs

Gustavo Goretkin (Mar 05 2025 at 12:41):

Thanks, I will try that! How do I split up what generalize H : foo = bar int o two pieces so that I have an H I can give to rw (occs := .pos [1, 2]) [H] (or i might be missing the bigger picture)

Robin Arnez (Mar 05 2025 at 13:18):

You can use the set! tactic: set! bar := foo with H and then rewrite or conv or whatever

Robin Arnez (Mar 05 2025 at 13:22):

Actually that might not work quite how you'd like...

Robin Arnez (Mar 05 2025 at 13:22):

I'm assuming you want to generalize because of induction?

Robin Arnez (Mar 05 2025 at 13:23):

Then perhaps it is simpler to avoid generalization and use let rec instead

Gustavo Goretkin (Mar 05 2025 at 18:40):

I ended up doing

  generalize H : moore.s0 = s
  rewrite (config := {occs := .pos [2]}) [ H]
  clear H
  revert s

which is nicer than what I had before.

Gustavo Goretkin (Mar 05 2025 at 18:41):

I don't see the set! tactic

Kyle Miller (Mar 05 2025 at 18:49):

A hack is you could do generalize H : moore.s0 = s at h where h is some hypothesis that doesn't contain moore.s0. That will prevent moore.s0 from being replaced in the goal. I'm not recommending this though.

There's also doing something like let s := moore.s0, then using change to replace certain occurrences, and then clear_value s. It's not that great of an experience.

Are you on an old Lean? You should be able to write

rewrite (occs := [2]) [ H]

these days.

Kyle Miller (Mar 05 2025 at 18:53):

Robin's suggestion of set! is a mathlib tactic. It's in Mathlib.Tactic.Set. The ! causes set to not rewrite.


Last updated: May 02 2025 at 03:31 UTC