Zulip Chat Archive
Stream: lean4
Topic: Implementing a custom rewrite
Vladimir Gladstein (Feb 26 2024 at 05:26):
Hey! I am defining my own rewrite tactic srw
, the simplified version of which would be just a regular rw
where lemmas are listed not in square brackets, but just one by one.
The idea how I am going to implement that is:
having:
srw a b at l
I want it to be equivalent to
rw [a] at l; rw [b] at l
In other words, my elaboration function for srw
(show below) takes a sequence of lemmas rs
, and a location l
, and
- first pairs each lemma with a location
l
, yielding a syntax of categorysrwRuleLoc
- then for each
srwRuleLoc
it elaborates it by calling an originalrw
(implemented inelab_rules
)
The implementation is shown below:
declare_syntax_cat srwRule
declare_syntax_cat srwRules
declare_syntax_cat srwRuleLoc
declare_syntax_cat srwRulesLoc
syntax (name:= srwRule) term:max : srwRule
syntax srwRule (location)? : srwRuleLoc
syntax (ppSpace colGt (srwRule))* : srwRules
syntax (name:= srwRulesLoc) (ppSpace colGt (srwRuleLoc))* : srwRulesLoc
syntax (name := srw) "srw" srwRules (location)? : tactic
-- rewriting a term with location
elab_rules : tactic
| `(srwRuleLoc| $t:term $l:location ?) =>
try do
evalTactic $ <- `(tactic| rw [$t:term] $(l)?)
catch | ex => throwErrorAt t ex.toMessageData
-- having an object of category `srwRule and a location, return `srwRuleLoc
def insertLocation (l : Option (TSyntax `Lean.Parser.Tactic.location)) (x : TSyntax `srwRule) : MacroM Syntax := do
if x.raw.isOfKind `srwRule then
let y <- `(srwRuleLoc| $(⟨x.raw.setKind `srwRule⟩):srwRule $l:location ?)
return y.raw
else return x.raw
-- elaborate each rewrite term one by one
elab "srw" rs:srwRules l:(location)? : tactic =>
match rs with
| `(srwRules| $[$rs] *) => do
let rs <- rs.mapM (liftMacroM $ insertLocation l ·)
for r in rs do evalTactic rs
| _ => throwError ""
example : (True /\ False) /\ (True /\ True) = False := by
srw true_and true_and -- the goal doesn't update withinh each rewrite separately
The problem with this code is that goal doesn't update within each rewrite rule. I guess this is because evalTactic
will srwRuleLoc
syntax with the context info, but not srwRule
.
What would be the better way to fix it without changing elab_rules
?
There is a reason why I want to treat each rule as a separate rewrite (In future, I want to specify a location for each rewrite separately). And the there is a reason why I don't want to add withTacticInfoContext t do
to elab_rules
(I want it to be extensible, such that if someone else wants to extend it they would not have to think about annotations)
Last updated: May 02 2025 at 03:31 UTC