When I write something like rw [add_comm] Lean implicitly infers the two arguments {a b} for add_comm and then applies the rewrite a + b = b + a for some a and b. Is there a way to see in the InfoView or other tool, what the inferred a and b precisely are. Kind hoped hovering over add_comm would do that, but it doesn't seem too.
I know that, of course, I can work those backwards from the resulting rewrite in the local goals, but it require a bit of extra work from me (imagine the theorem being {a b}: <some messy expression with a b> applied to an <even messier expression that contains the theorems messy subexpression>).
Indeed, but it's really ugly. Would be nice if LSP could show what it inferred.
Another way i use sometimes is make the rw fail to show what it infers since error message show it.
Just for fun, this shows the instantiated version of the theorem when you hover, although you lose the old hover. I could just logInfo the instantiated version but I wouldn't want the blue squiggles under everything.
The new version is rw' with your example at the bottom:
I just changed one line but had to copy everything over
importLeanimportMathlibnamespaceRwopenLeanMetaElabTacticParserTacticsyntax(name:=rewriteSeq')"rewrite'"optConfigrwRuleSeq(location)?:tactic/--`rw` is like `rewrite`, but also tries to close the goal by "cheap" (reducible) `rfl` afterwards.-/macro(name:=rwSeq')"rw' "c:optConfigs:rwRuleSeql:(location)?:tactic=>matchswith|`(rwRuleSeq|[$rs,*]%$rbrak)=>-- We show the `rfl` state on `]``(tactic|(rewrite'$c[$rs,*]$(l)?;with_annotate_state$rbrak(try(with_reduciblerfl))))|_=>Macro.throwUnsupported/--Runs `Lean.MVarId.rewrite`, and also handles filtering out the old metavariables in the rewrite result.This should be used from within `withSynthesize`.Use `finishElabRewrite` once elaboration is complete to make final updates to `RewriteResult`.-/defelabRewrite(mvarId:MVarId)(e:Expr)(stx:Syntax)(symm:Bool:=false)(config:={:Rewrite.Config}):TacticMRewriteResult:=doletmvarCounterSaved:=(←getMCtx).mvarCounterletthm←withEnableInfoTreefalse<|elabTermstxnonetrueifthm.hasSyntheticSorrythenthrowAbortTacticunless←occursCheckmvarIdthmdothrowErrorAtstx"Occurs check failed: Expression{indentExpr thm}\ncontains the goal {Expr.mvar mvarId}"letr←mvarId.rewriteethmsymm(config:=config)discard<|Lean.Elab.Term.addTermInfostxr.eqProof.getAppArgs.back!letmctx←getMCtxletmvarIds:=r.mvarIds.filterfunmvarId=>(mctx.getDeclmvarId|>.index)>=mvarCounterSavedreturn{rwithmvarIds}/--Makes new goals be synthetic opaque, to be done once elaboration of the rewrite theorem is complete.Workaround note: we are only doing this for proof goals, not data goals,since there are many downstream cases of tactic proofs that later assign data goals by unification.-/deffinishElabRewrite(r:RewriteResult):MetaMRewriteResult:=doletmvarIds←r.mvarIds.filterM(not<$>·.isAssigned)mvarIds.forMfunnewMVarId=>newMVarId.withContextdoif←Meta.isProp(←newMVarId.getType)thennewMVarId.setKind.syntheticOpaquereturn{rwithmvarIds}defrewriteTarget(stx:Syntax)(symm:Bool)(config:Rewrite.Config:={}):TacticMUnit:=doletr←Term.withSynthesize<|withMainContextdoelabRewrite(←getMainGoal)(←getMainTarget)stxsymm(config:=config)letr←finishElabRewriterletmvarId'←(←getMainGoal).replaceTargetEqr.eNewr.eqProofreplaceMainGoal(mvarId'::r.mvarIds)defrewriteLocalDecl(stx:Syntax)(symm:Bool)(fvarId:FVarId)(config:Rewrite.Config:={}):TacticMUnit:=withMainContextdo-- Note: we cannot execute `replaceLocalDecl` inside `Term.withSynthesize`.-- See issues #2711 and #2727.letrwResult←Term.withSynthesize<|withMainContextdoletlocalDecl←fvarId.getDeclelabRewrite(←getMainGoal)localDecl.typestxsymm(config:=config)letrwResult←finishElabRewriterwResultletreplaceResult←(←getMainGoal).replaceLocalDeclfvarIdrwResult.eNewrwResult.eqProofreplaceMainGoal(replaceResult.mvarId::rwResult.mvarIds)defwithRWRulesSeq(token:Syntax)(rwRulesSeqStx:Syntax)(x:(symm:Bool)→(term:Syntax)→TacticMUnit):TacticMUnit:=doletlbrak:=rwRulesSeqStx[0]letrules:=rwRulesSeqStx[1].getArgs-- show initial state up to (incl.) `[`withTacticInfoContext(mkNullNode#[token,lbrak])(pure())letnumRules:=(rules.size+1)/2foriin*...numRulesdoletrule:=rules[i*2]!letsep:=rules.getD(i*2+1)Syntax.missing-- show rule state up to (incl.) next `,`withTacticInfoContext(mkNullNode#[rule,sep])do-- show errors on rulewithRefruledoletsymm:=!rule[0].isNoneletterm:=rule[1]letprocessId(id:Syntax):TacticMUnit:=do-- See if we can interpret `id` as a hypothesis first.if(←withMainContext<|Term.isLocalIdent?id).isSomethenxsymmtermelse-- Try to get equation theorems for `id`.letdeclName←tryrealizeGlobalConstNoOverloadidcatch_=>return(←xsymmterm)letsomeeqThms←getEqnsFor?declName|xsymmtermlethint:=ifeqThms.size=1thenm!""else.hint'm!"Try rewriting with `{Name.str declName unfoldThmSuffix}`"letrecgo:ListName→TacticMUnit|[]=>throwErrorm!"Failed to rewrite using equation theorems for `{.ofConstName declName}`"++hint|eqThm::eqThms=>(xsymm(mkCIdentFromideqThm))<|>goeqThmsdiscard<|Term.addTermInfoid(←mkConstWithFreshMVarLevelsdeclName)(lctx?:=←getLCtx)goeqThms.toListmatchtermwith|`($id:ident)=>processIdid|`(@$id:ident)=>processIdid|_=>xsymmterm@[tacticrewriteSeq']defevalRewriteSeq:Tactic:=funstx=>doletcfg←elabRewriteConfigstx[1]letloc:=expandOptLocationstx[3]withRWRulesSeqstx[0]stx[2]funsymmterm=>dowithLocationloc(rewriteLocalDecltermsymm·cfg)(rewriteTargettermsymmcfg)(throwTacticEx`rewrite·"Did not find an occurrence of the pattern in the current goal")endRwexample(xy:Nat):x+y=y+x:=byrw'[add_comm]