Zulip Chat Archive
Stream: mathlib4
Topic: Useful term elaborators
Floris van Doorn (Apr 19 2024 at 10:43):
We have some nice custom term elaborators, but I rarely use them, and don't know all of them. What are some term elaborators you use in practice, or think are underused? Note: you can write #help term
to see all of them, but that list includes all notation, I believe.
Floris van Doorn (Apr 19 2024 at 10:43):
- I personally use
exact?%
, for the term-mode equivalent ofby exact?
- I might start using
congr(...)
occasionally, to generate congruence lemmas for terms - I believe there was a term elaborator that allows you to have metavariables in
let
/have
tactics, but I don't remember the syntax and it's hard to search for it.
Adam Topaz (Apr 19 2024 at 11:15):
prod_assoc%
is one that I wrote and probably has never been used. reassoc_of%
is used in several category theory proofs.
Eric Wieser (Apr 19 2024 at 11:54):
eval%
is another one, which is handy for things like have : 5! = eval% 5! := by rfl
, though a norm_num
version would be better
Floris van Doorn (Apr 22 2024 at 11:24):
@Kyle Miller I expect you wrote more term elaborators than the ones mentioned so far?
Alex J. Best (Apr 22 2024 at 13:06):
There is also the mod_cast
term elab which basically runs norm_cast on the term before inserting, so one can do e.g simp [mod_cast foo]
or similar
Eric Wieser (Apr 22 2024 at 13:17):
Should we add a %
to its name?
Floris van Doorn (Apr 22 2024 at 13:22):
Also, that description doesn't seem to capture its actual behavior:
import Mathlib
example (n : Nat) : (mod_cast ((n : ℤ) : ℚ)) = 3 := by
-- cast ⋯ ↑↑n = 3
norm_cast
-- cast ⋯ ↑n = 3
It also adds the cast
in the statement, which presumably makes it useless in simp
/rw
. Searching for it in mathlib it seems to be (almost?) exclusively used in term mode.
Alex J. Best (Apr 22 2024 at 13:50):
My description is likely wrong, I haven't used it so much myself.
Alex J. Best (Apr 22 2024 at 13:50):
@Kim Morrison added this iirc?
Kim Morrison (Apr 22 2024 at 13:59):
I remember upstreaming it, but not writing it!
Kyle Miller (Apr 22 2024 at 18:45):
Mathlib term elaborators that I found (including ones already mentioned):
proxy_equiv% t
creates an equivalence_ ≃ t
where_
stands for some sum of products of basic types.derive_fintype% t
derives aFintype t
instance usingproxy_equiv% t
eval% t
evaluatest
and then reflects it back to an expressionprod_assoc%
uses the expected type (such as(α × β) × (γ × δ) ≃ α × (β × γ) × δ
) and derives the equivalencecongr(t)
elaborates to a proof of an Eq, HEq, or Iff, wheret
is a pattern that can be full of$h
"holes", whereh
is an Eq, HEq, or Iff, unifying and generalizing thecongr
/congrFun
/congrArg
functionsType*
andSort*
add a fresh universe level variableu
and elaborate toType u
andSort u
elementwise_of% w
takes a lemmaw
of an equality of morphisms of concrete categories and creates an elementwise versionreassoc_of% w
takes a lemmasw
of an equality of morphisms and creates a "reassoc" lemmaclean% t
elaboratest
and then eliminates identity functions (type hints) fromt
delta% t
elaboratest
and head-delta-reduces itbeta% t
elaboratest
and then head-beta-reduces itfbinop%
is used to elaborate expressions involving products of container-like types
Kyle Miller (Apr 22 2024 at 19:48):
From core:
ext_type% bool t
andext_iff_type% bool t
create extensionality lemmas fort
, where thebool
(iftrue
) flattens the structureeval_prec prec
evaluates a precedence expression as a Nateval_prec prio
evaluates a priority expression as a Natby_elab doSeq
andby_elab fun expectedType? => do doSeq
let you have an inline term elaboratorwith_annotate_term stx e
annotatesstx
with terminfo fore
(for hovers)mod_cast e
runs thenorm_cast
machinery one
include_str "path" / "to" / "file"
elaborates to a string literal containing the contents of the fileshow_term e
elaboratese
and shows the elaborated termby? ...
isshow_term by ...
exact?%
isby exact?
json% jsonExpr
lets you embed a JSON expression to get a docs#Lean.Json value`(...)
syntax quotationslet_fun x := v; b
for "elaboratev
and then elaborateb
withx
as a cdecl (value-free)". (have
is implemented using this)let_delayed x := v; b
elaborates aslet x := v; b
but elaboratesb
before elaboratingv
let_tmp x := v; b
elaborates likelet x := v; b
but eliminates the let ifx
is unused inb
haveI
/letI
are likehave
/let
versions oflet_tmp
but that substitute the value ofx
intob
type_of% e
elaborates to the type ofe
ensure_type_of% ref msg e
elaboratesref
ande
and ensures thate
has the same type asref
hasno_implicit_lambda% e
elaboratese
with the implicit lambda feature turned offclear% id; e
elaboratese
withid
cleared from the local contextlet_mvar% ?m := v; e
assigns the mvar?m
tov
and elaboratese
wait_if_type_mvar% ?m; e
,wait_if_type_contains_mvar% ?m; e
, andwait_if_contains_mvar% ?m; e
are different variations of postponing depending on there being mvars in?m
no_error_if_unused%
is allowed in match arms for Syntaxmatch
h ▸ e
elaboratese
and tries a number of tactics using the type ofe
and the expected type to rewrite usingh
to insert a cast
Kyle Miller (Apr 22 2024 at 19:50):
From Qq:
q(...)
andQ(..)
quotations, with~q(...)
patterns
Kyle Miller (Apr 22 2024 at 19:50):
How I found these: I searched for : term
, @[term_parser
and @[builtin_term_parser
Richard Copley (Apr 22 2024 at 21:32):
Kyle Miller said:
exact?%
isby exact?
I wish! It's by apply?
Kim Morrison (Apr 22 2024 at 22:57):
Richard Copley said:
Kyle Miller said:
exact?%
isby exact?
I wish! It's
by apply?
I think this would be reasonable to change. I'd merge the PR. :-)
Richard Copley (Apr 23 2024 at 01:22):
Thomas Murrills (Apr 23 2024 at 04:29):
Eric Wieser said:
eval%
is another one, which is handy for things likehave : 5! = eval% 5! := by rfl
, though anorm_num
version would be better
#12353 introduces conv%
, and along with it simp%
, push_neg%
, and norm_num%
. (It also introduces ?
variants of these as shortcuts for e.g. show_term …
, so that it’s easy to check the result.)
There are some tentative choices made by that PR worth discussing, but probably in a separate thread. :)
Mario Carneiro (Apr 23 2024 at 04:38):
and a separate PR...
Thomas Murrills (Apr 23 2024 at 04:54):
To be clear, you mean you’d prefer the changes to the command syntax in a separate PR?
Thomas Murrills (Apr 23 2024 at 04:55):
(Or, well, that you think it would be better for them to be in a separate PR, not necessarily exclusively as a matter of personal preference.)
Thomas Murrills (Apr 23 2024 at 05:13):
Continued in #mathlib4 > conv% and changes to #conv (and friends). :)
Last updated: May 02 2025 at 03:31 UTC