-
Notifications
You must be signed in to change notification settings - Fork 438
Metaprogramming for dummies
-
MetaM is the monad you want to use if you modify metavariables.
-
TacticM is the topmost monad for tactic-writing. You can get and set goals, etc
In a do
block (←) takes care of bumping to a stronger monad
- mapM
- (←)
- filterM
- elabTerm
- elabTermForApply
- elabTermEnsuringType
withLocalDeclD
open Lean.Expr
Check whether something is a metavariable: isMVar Create metavariable: Assign metavariable: Check whether it is assigned
Note about delayed assignments (and reference to meta-book)
isFVar fvarId! FVarId.getUserName
isBVar
isLambda lambdaTelescope
isForall forallTelescope
- isApp
- getAppFn
- getAppNumArgs
- getAppArgs
-
Expr.getAppFnArgs
: This is useful if you have an expression and you want to pattern-match
open Lean.Elab.Tactic
getGoals getMainGoal setGoals
open Lean.Elab.Tactic
evalTactic withMainContext liftMetaTactic
Lean.MVarId.apply
Example:
If no universe levels: mvarId.apply (mkConst foo []) If known universe levels: mvarId.apply (mkConst
foo [u,v])
Otherwise: mvarId.apply (← mkConstWithFreshMVarLevels ``foo)
However, see also: Qq
.
- The easy stuff
- Qq (Qq is love, Qq is life).
If you want to build expressions, it's a good idea to use Qq
instead of manually building them from the constructors. The Q(α)
macro is a synonym of Expr
, with the (unchecked?) assertion that any e : Q(α)
typechecks to have type α
. And you can build elements of Q
using q
, and it will automatically, statically, fill in implicits. Instances are looked up in the context of the q
invocation.
Unfortunately, errors generated by Qq
are hard to understand.
- dbg_trace "foo {var}" -- Very lowlevel works everywhere
- logInfo "foo" -- works in any monad that supports logging
- trace[identifier] "foo"
initialize registerTraceClass `identifier