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/havetactics, 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% tcreates an equivalence_ ≃ twhere_stands for some sum of products of basic types.derive_fintype% tderives aFintype tinstance usingproxy_equiv% teval% tevaluatestand 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, wheretis a pattern that can be full of$h"holes", wherehis an Eq, HEq, or Iff, unifying and generalizing thecongr/congrFun/congrArgfunctionsType*andSort*add a fresh universe level variableuand elaborate toType uandSort uelementwise_of% wtakes a lemmawof an equality of morphisms of concrete categories and creates an elementwise versionreassoc_of% wtakes a lemmaswof an equality of morphisms and creates a "reassoc" lemmaclean% telaboratestand then eliminates identity functions (type hints) fromtdelta% telaboratestand head-delta-reduces itbeta% telaboratestand 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 tandext_iff_type% bool tcreate extensionality lemmas fort, where thebool(iftrue) flattens the structureeval_prec precevaluates a precedence expression as a Nateval_prec prioevaluates a priority expression as a Natby_elab doSeqandby_elab fun expectedType? => do doSeqlet you have an inline term elaboratorwith_annotate_term stx eannotatesstxwith terminfo fore(for hovers)mod_cast eruns thenorm_castmachinery oneinclude_str "path" / "to" / "file"elaborates to a string literal containing the contents of the fileshow_term eelaborateseand shows the elaborated termby? ...isshow_term by ...exact?%isby exact?json% jsonExprlets you embed a JSON expression to get a docs#Lean.Json value`(...)syntax quotationslet_fun x := v; bfor "elaboratevand then elaboratebwithxas a cdecl (value-free)". (haveis implemented using this)let_delayed x := v; belaborates aslet x := v; bbut elaboratesbbefore elaboratingvlet_tmp x := v; belaborates likelet x := v; bbut eliminates the let ifxis unused inbhaveI/letIare likehave/letversions oflet_tmpbut that substitute the value ofxintobtype_of% eelaborates to the type ofeensure_type_of% ref msg eelaboratesrefandeand ensures thatehas the same type asrefhasno_implicit_lambda% eelaboratesewith the implicit lambda feature turned offclear% id; eelaboratesewithidcleared from the local contextlet_mvar% ?m := v; eassigns the mvar?mtovand elaboratesewait_if_type_mvar% ?m; e,wait_if_type_contains_mvar% ?m; e, andwait_if_contains_mvar% ?m; eare different variations of postponing depending on there being mvars in?mno_error_if_unused%is allowed in match arms for Syntaxmatchh ▸ eelaborateseand tries a number of tactics using the type ofeand the expected type to rewrite usinghto 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_numversion 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