Trace messages #
Trace messages explain to the user what problem Lean solved and what steps it took. Think of trace messages like a figure in a paper.
They are shown in the editor as a collapsible tree,
usually as [class.name] message ▸
.
Every trace node has a class name, a message, and an array of children.
This module provides the API to produce trace messages,
the key entry points are:
registerTraceMessage `class.name
registers a trace class- ``withTraceNode
class.name (fun result => return msg) do body
produces a trace message containing the trace messages in `body` as children trace[class.name] msg
produces a trace message without children
Users can enable trace options for a class using
set_option trace.class.name true
.
This only enables trace messages for the class.name
trace class
as well as child classes that are explicitly marked as inherited
(see registerTraceClass
).
Internally, trace messages are stored as MessageData
:
.trace cls msg #[.trace .., .trace ..]
When writing trace messages, try to follow these guidelines:
- Expansion progressively increases detail. Each level of expansion (of the trace node in the editor) should reveal more details. For example, the unexpanded node should show the top-level goal. Expanding it should show a list of steps. Expanding one of the steps then shows what happens during that step.
- One trace message per step.
The
[trace.class]
marker functions as a visual bullet point, making it easy to identify the different steps at a glance. - Outcome first. The top-level trace message should already show whether the action failed or succeeded, as opposed to a "success" trace message that comes pages later.
- Be concise. Keep messages short. Avoid repetitive text. (This is also why the editor plugins abbreviate the common prefixes.)
- Emoji are concisest. Several helper functions in this module help with a consistent emoji language.
- Good defaults.
Setting
set_option trace.Meta.synthInstance true
(etc.) should produce great trace messages out-of-the-box, without needing extra options to tweak it.
Equations
- Lean.instInhabitedTraceElem = { default := { ref := default, msg := default } }
Equations
- Lean.instInhabitedTraceState = { default := { traces := default } }
- modifyTraceState : (Lean.TraceState → Lean.TraceState) → m Unit
- getTraceState : m Lean.TraceState
Instances
Equations
- Lean.instMonadTrace m n = { modifyTraceState := fun f => liftM (Lean.modifyTraceState f), getTraceState := liftM Lean.getTraceState }
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Equations
- Lean.isTracingEnabledFor cls = do let inherited ← liftM (ST.Ref.get Lean.inheritedTraceOptions) let a ← Lean.getOptions pure (Lean.checkTraceOption inherited a cls)
Equations
- Lean.modifyTraces f = Lean.modifyTraceState fun s => { traces := f s.traces }
Equations
- Lean.setTraceState s = Lean.modifyTraceState fun x => s
Equations
- Lean.addRawTrace msg = do let ref ← Lean.getRef let msg ← Lean.addMessageContext msg Lean.modifyTraces fun a => Lean.PersistentArray.push a { ref := ref, msg := msg }
Equations
- One or more equations did not get rendered due to their size.
Equations
- Lean.trace cls msg = do let a ← Lean.isTracingEnabledFor cls if a = true then Lean.addTrace cls (msg ()) else pure PUnit.unit
Equations
- Lean.traceM cls mkMsg = do let a ← Lean.isTracingEnabledFor cls if a = true then do let msg ← mkMsg Lean.addTrace cls msg else pure PUnit.unit
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Registers a trace class.
By default, trace classes are not inherited;
that is, set_option trace.foo true
does not imply set_option trace.foo.bar true
.
Calling registerTraceClass `foo.bar (inherited := true)
enables this inheritance
on an opt-in basis.
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
Equations
- Lean.exceptBoolEmoji _fun_discr = match _fun_discr with | Except.error a => Lean.bombEmoji | Except.ok true => Lean.checkEmoji | Except.ok false => Lean.crossEmoji
Equations
- Lean.exceptOptionEmoji _fun_discr = match _fun_discr with | Except.error a => Lean.bombEmoji | Except.ok (some val) => Lean.checkEmoji | Except.ok none => Lean.crossEmoji