Zulip Chat Archive
Stream: lean4
Topic: Rewriting in a let-body
Wojciech Nawrocki (Jun 21 2022 at 00:37):
Is it possible to rewrite in the value (not the type) of a let
binding in the local context? I couldn't get this to work in Lean 3 either. For example
def f (a b : Nat) : Nat := a + b
example : f 1 2 = f 2 1 := by
let x := f 1
have : f 1 = fun x => 1 + x := rfl
/- tactic 'rewrite' failed, did not find instance of the pattern in the target expression
f 1
x : ℕ → ℕ := f 1
this : f 1 = fun x => 1 + x
⊢ f 1 2 = f 2 1 -/
rw [this] at x
Mac (Jun 21 2022 at 00:50):
Could you elaborate on your use case a bit more (i.e., what your goal is)? Is there a reason why a solution like the following is insufficient?
def f (a b : Nat) : Nat := a + b
example : f 1 2 = f 2 1 := by
let x := f 1
have h : x = f 1 := rfl
have : f 1 = fun x => 1 + x := rfl
rw [this] at h
/-
x : Nat → Nat := f 1
h : x = fun x => 1 + x
this : f 1 = fun x => 1 + x
⊢ f 1 2 = f 2 1
-/
Wojciech Nawrocki (Jun 21 2022 at 01:31):
I am using let-bindings in the context to represent auxiliary functions in a tactic which will then be encoded by a further tactic. However I want to control how this encoding goes by rewriting the the bodies of these auxiliaries. Basically I can go with the let-equals solution you propose or even a custom data structure, it's just that using the let-bodies was very convenient, which is why I wondered if I can rewrite in them.
Tomas Skrivan (Jun 21 2022 at 10:16):
I would be also quite interested in doing the rewrites directly in the let bindings. My application would be to do source code transformation in the tactic mode.
Currently I'm doing something vaguely similar and to do the rewriting I encode the value in the type.
Define an auxiliary type
def Aux {α : Type u} (a : α) := α
Then you can have the value f 1
in the type Aux (f 1)
and do the rewrites.
An example:
def Aux {α : Type u} (a : α) := α
def aux {α} (a : α) : Aux a := a
def f (a b : Nat) : Nat := a + b
example : f 1 2 = f 2 1 := by
have h : f 1 = fun x => x + 1 := by conv => rhs; enter[x]; rw [Nat.add_comm];
let x : Aux (f 1) := by
rw[h]; -- desired rewrite
apply aux _ -- finish definition of Aux
have test_rewrite : x = fun x => x + 1 := rfl
admit
So the general idea is to instead of writing:
let x := <x definition>
rw [<x rewrite>] at x
write
let x : Aux <x definition> := by rw [<x rewrite>]; apply aux _
That is ugly though. We can define a macro of the form term "rewrite_by" convSeq
and write ((f 1) rewrite_by rw[h])
instead.
Full code
open Lean.Parser.Tactic.Conv
syntax term "rewrite_by" convSeq : term
macro_rules
| `($x rewrite_by $rw:convSeq) =>
`((by (conv => enter[1]; $rw) (apply aux _) : Aux $x))
def f' (a b : Nat) : Nat := a + b
example : f' 1 2 = f' 2 1 := by
have h : f' 1 = fun x => x + 1 := by conv => rhs; enter[x]; rw [Nat.add_comm];
let x := ((f' 1) rewrite_by rw[h])
have test_rewrite : x = fun x => x + 1 := rfl
admit
Tomas Skrivan (Jun 21 2022 at 10:19):
(I have modified the statement from f 1 = fun x => 1 + x
to f 1 = fun x => x + 1
such that it is not solvable by rfl
and the test_rewrite
fails if the rewrite rw[h]
is not done)
Tomas Skrivan (Jun 21 2022 at 10:25):
The unfortunate thing is that the resulting definition of x
looks rather ugly in the goal view:
x : Aux (f 1) := Eq.mpr (_ : Aux (f 1) = Aux fun x => x + 1) (aux fun x => x + 1)
Not sure what to do about it. To make sense of this definition I would suggest looking at the intermediate stages of(paste it to the code above)
have test_rewrite : x = fun x => x + 1 := by simp only [Eq.mpr]; unfold aux; rfl
Sebastian Ullrich (Jun 21 2022 at 10:38):
Perhaps we should default pp.proofs.withType
to false in the info view, assuming hover gives the same information
Tomas Skrivan (Jun 21 2022 at 10:49):
I do not have a strong opinion about that and I do not think this is a strong case for or against. For example, if you make the a
argument in aux
implicit then the the goal view shows x : Aux (f 1) := Eq.mpr _ aux
. You completely loose the information about the actual definition fun x => x + 1
.
I think this case needs a custom tailored solution to force Lean to show something nice an useful.
Last updated: Dec 20 2023 at 11:08 UTC