imprimatur

Views

For authors of papers that use imprimatur: what each view produces, and the macros tex/imprimatur.sty defines for it. Redefine any of these macros to change the style. DESIGN.md §7.3 lists all the planned views. This page covers lean, meta, math, prose, rules, grammar and custom views.

lean: the signature as Lean prints it

The declaration’s signature is printed by Lean’s pretty-printer and set in a monospace font. Each token is wrapped in a semantic macro:

Macro Token Default style
\LeanKeyword theorem, def, instance, fun, … bold
\LeanSort Type, Prop, Sort bold
\LeanConst a name that resolves to a constant plain
\LeanBound a bound variable or universe parameter slanted
\LeanNumber, \LeanString literals plain

The whole view is wrapped in \LeanCode{…}:

There is no verbatim environment, so the view also works inside \leaninline and inside macro arguments.

Settings.

Unicode. Lean prints symbols such as ∀, →, ℕ, Greek letters and subscripts. imprimatur.sty maps the common ones to maths symbols, so pdfLaTeX needs no special fonts. A character the document already maps is left alone. For any other character, add \newunicodechar in the document.

meta: where a result comes from

\LeanMeta{\leanmetasource{Minimal/Basic.lean:13}}{Quot.sound, propext}{\LeanSorryFree}{The docstring.}

The four arguments are:

  1. the source location;
  2. the axioms the declaration depends on;
  3. its sorry status (\LeanSorryFree or \LeanUsesSorry);
  4. its docstring, converted from Markdown (code, bold, emphasis, $maths$).

The source location depends on the profile. The extractor writes \leanmetasource{}, and the splicer fills it in, because the profile is chosen when splicing:

\leanmetasource prints nothing when the location is empty.

math: a declaration as a formula

\LeanMath{2(m + n) = 2m + 2n}

Using the notation in scope (notation.md):

Long formulas. The formula is broken with \LeanBreak at its outermost connectives when it is wider than three quarters of width in imprimatur.toml: 60 characters by default. The fraction is there because mathematics sets wider than monospace. \LeanMath sets the lines as an array.

Variants. notation=named on a block selects the rules of variant named.

prose: a theorem as a sentence

\LeanProse{Let $m, n \in \mathbb{N}$. Assume $2m = 2n$. Then $m = n$.}

The prose is built in four parts:

rules: an inductive predicate as inference rules

\begin{mathpar}

\rulelabel{Beta}{($\longrightarrow$-Beta)}%
\inferrule[($\longrightarrow$-Beta)]
  { }
  { (\lambda{:}t.\, e)\; \val \longrightarrow e[\val] }

\and

\inferrule[($\longrightarrow$-App Left)]
  {
    e_{1} \longrightarrow e_{1}'
  }
  { e_{1}\; e_{2} \longrightarrow e_{1}'\; e_{2} }

\end{mathpar}

The key is an inductive predicate, one constructor, or a latex_group. Each constructor becomes a mathpartir \inferrule, so the document needs \usepackage{mathpartir}:

grammar: an inductive type as a grammar

\begin{LeanGrammar}
\LeanProduction{e}{terms}{x_{i}}{\leanslot{Tm.var}{a variable}}
\LeanAlternative{\lambda{:}\tau.\, e}{\leanslot{Tm.lam}{an abstraction}}
\end{LeanGrammar}

The key is an inductive type (latex_category T => "e" names its metavariable) or a structure (\LeanStructure and \LeanField). Each constructor is one alternative, rendered with the notation in scope applied to metavariables; its description is a slot whose default is the constructor’s docstring, so the paper’s wording survives regeneration. A grammar whose forms are hand-written TeX is better served by a custom view.

Theorem modifiers of math

Option Effect
rule the hypotheses over the conclusion, as \inferrule
forall the statement with its outer quantifiers shown
def a definition as its equation lemmas, aligned
names=full no namespaces left out

Options are written on the block, [view=math, rule], or on a latex_entry.

Custom views

A project adds a view in its notation module:

@[latex_view "paper.theorem"]
def theoremView : Imprimatur.ViewFn := fun key c opts => do …

It gets the key, the declaration it names (if any) and the block’s options, and runs in the renderer’s monad, so Imprimatur.Render.render gives it the notation in scope. The document’s inventory, (← read).document, lists the blocks (with the labels the splicer gives them, and whether they are typeset) and the typeset \labels of the paper in document order, for views that index it. A view’s exception becomes an error for that block. An alias selects it like any view: leantheorem = { view = "paper.theorem" }.