Zulip Chat Archive
Stream: metaprogramming / tactics
Topic: Help with writing tactic `setm`
Gareth Ma (Mar 21 2024 at 19:29):
bump
Thomas Murrills (Mar 21 2024 at 19:33):
Btw, I think I also included (some/all of) these utilities in a PR for refine?
, but it was requested that the refine?
PR be split into utils and refine?
itself, and then that the meta utils PR be split further into individual API contributions: #8503
Thomas Murrills (Mar 21 2024 at 19:36):
(I haven’t had the motivation to do so since, but maybe this would prompt that.)
And reflecting on it now, I think some of these would maybe be “better” as modifications to core than as mathlib4 contributions which just copy a core function and add more functionality which could be easily included in the core implementation but just isn’t. But I’m not sure how fast those PRs would move, or if they’d be welcome at all…
Thomas Murrills (Mar 21 2024 at 19:44):
But looking back at this thread, just using Kyle’s implementation might be quickest for getting something in. I forget if there was some advantage conferred by using this alternative strategy besides being less bespoke after introducing metaprogramming infrastructure.
Gareth Ma (Mar 21 2024 at 19:44):
I imagine modifying core will be very very slow.
Gareth Ma (Mar 21 2024 at 19:44):
FYI I bumped this thread because of https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/too.20many.20FunLikes/near/428202012
Thomas Murrills (Mar 21 2024 at 19:46):
It’s not always very slow—plus, now(?) there’s code ownership for certain parts, giving those code owners the ability to review and merge things using their own judgment, which I imagine speeds things up a bit.
Gareth Ma (Mar 21 2024 at 19:48):
My only experience was looking at https://github.com/leanprover/lean4/issues/2414
Gareth Ma (Mar 21 2024 at 19:48):
But the code ownership part sounds good
Thomas Murrills (Mar 21 2024 at 19:49):
In any case I do think that in this specific case the Kyle way is definitely the most efficient way to get it landing, even considering recent speedups. :)
Gareth Ma (Mar 21 2024 at 19:50):
I will reread it and see what I can do lol, it's been a while since I wrote any metaprogramming
Thomas Murrills (Mar 21 2024 at 20:18):
Also, would it be possible to change the name of this topic to something setm
related? :eyes:
Gareth Ma (Mar 21 2024 at 20:25):
:skull: :skull: Yes yes definitely
Gareth Ma (Mar 21 2024 at 20:28):
Screenshot-2024-03-21-at-20.27.54.png
I can't rename the thread because I can't move some messages. I think it's because the messages are more than 7 days old.
Gareth Ma (Mar 21 2024 at 20:29):
Can you or others with permission do it for me? The new thread can be called setm development thread
or something
Bhavik Mehta (Nov 09 2024 at 16:59):
Has there been progress on this tactic / the PR? I just came across a case where this would be useful to me!
Kyle Miller (Nov 10 2024 at 00:37):
In case it's helpful, in lean4#6022 the change
tactic will be able to assign named metavariables, for example
example (x y z : Nat) : x + y = z := by
change ?a = _
let w := ?a
-- now `w : Nat := x + y`
Bhavik Mehta (Nov 10 2024 at 23:49):
oh interesting! does that mean there's an alternative (simpler?) implementation of setm
available as a combination change + let
?
Jireh Loreaux (Nov 22 2024 at 18:00):
I also just found a need for setm
. @Kyle Miller will it be as simple as a change + set
macro? Also, note that on the live server on the latest nightly, the change
has red squiggles underneath, but no error message appears:
import Lean
example (x y z : Nat) (h : x + y = z) : x + y = z := by
change ?a = _
let w := ?a
-- now `w : Nat := x + y`
exact h
Kyle Miller (Nov 22 2024 at 18:15):
I think that's a transient error Jireh. I've heard that somehow the live server can get into a state where the squiggles are from a union of multiple versions running simultaneously.
Kyle Miller (Nov 22 2024 at 18:16):
I just checked myself, and I didn't get squiggles.
Kyle Miller (Nov 22 2024 at 18:19):
Can you remind me what setm
is supposed to do to the goal? If it's supposed to be a = z
in the end, then you can do it with a different order:
example (x y z : Nat) (h : x + y = z) : x + y = z := by
let a : ?_ := ?a
change a = _
/-
a : Nat := x + y
⊢ a = z
-/
exact h
Jireh Loreaux (Nov 28 2024 at 04:58):
It should also replace x + y
with a
in h
, just like the set
tactic. This can be accomplished with change
+ set
like so (I just copied the set
tactic file into the below so it will work on the nightly without Mathlib):
import Lean.Elab.Tactic.ElabTerm
namespace Mathlib.Tactic
open Lean Elab Elab.Tactic Meta
syntax setArgsRest := ppSpace ident (" : " term)? " := " term (" with " "← "? ident)?
syntax (name := setTactic) "set" "!"? setArgsRest : tactic
macro "set!" rest:setArgsRest : tactic => `(tactic| set ! $rest:setArgsRest)
elab_rules : tactic
| `(tactic| set%$tk $[!%$rw]? $a:ident $[: $ty:term]? := $val:term $[with $[←%$rev]? $h:ident]?) =>
withMainContext do
let (ty, vale) ← match ty with
| some ty =>
let ty ← Term.elabType ty
pure (ty, ← elabTermEnsuringType val ty)
| none =>
let val ← elabTerm val none
pure (← inferType val, val)
let fvar ← liftMetaTacticAux fun goal ↦ do
let (fvar, goal) ← (← goal.define a.getId ty vale).intro1P
pure (fvar, [goal])
withMainContext <|
Term.addTermInfo' (isBinder := true) a (mkFVar fvar)
if rw.isNone then
evalTactic (← `(tactic| try rewrite [show $(← Term.exprToSyntax vale) = $a from rfl] at *))
match h, rev with
| some h, some none =>
evalTactic (← `(tactic| have%$tk
$h : $a = ($(← Term.exprToSyntax vale) : $(← Term.exprToSyntax ty)) := rfl))
| some h, some (some _) =>
evalTactic (← `(tactic| have%$tk
$h : ($(← Term.exprToSyntax vale) : $(← Term.exprToSyntax ty)) = $a := rfl))
| _, _ => pure ()
end Mathlib.Tactic
example (x y z : Nat) (h : x + y = z) : x + y = z := by
change ?a = _
set a := ?a
exact h
Last updated: May 02 2025 at 03:31 UTC