Zulip Chat Archive
Stream: mathlib4
Topic: how to get all steps of `simp` tactic
John Smith (Feb 26 2025 at 06:36):
In Lean 4, many simple proofs can be completed directly using the simp
tactic. I am trying to understand how simp
works internally and would like to see all the steps it performs during the simplification process.
I know that by enabling the trace option:
lean
set_option trace.Meta.Tactic.simp true
I can see some traces of the simp
tactic's behavior. However, the trace only shows part of the process, and many details are still omitted.
For example, consider the following code:
lean
import Mathlib set_option trace.Meta.Tactic.simp true
example : 1 + 0 = 1 * 1 := by simp
The trace output is:
[Meta.Tactic.simp.rewrite] add_zero:1000, 1 + 0 ==> 1
[Meta.Tactic.simp.rewrite] mul_one:1000, 1 * 1 ==> 1
[Meta.Tactic.simp.rewrite] eq_self:1000, 1 = 1 ==> True
Based on this information, I tried to manually reproduce the proof:
lean
example : 1 + 0 = 1 * 1 := by
rewrite [add_zero]
rewrite [mul_one]
rewrite [eq_self]
However, Lean 4 gives an error:
Basic.lean:7:27
unsolved goals
⊢ True
This is a simple unsolved goal, but the core issue is that I cannot retrieve the complete steps performed by simp
. Specifically:
- The trace does not show how
simp
closes the final goal (e.g., proving⊢ True
). - Some intermediate steps or implicit reasoning might be missing from the trace.
Questions:
- Is there a way to get all the steps performed by
simp
, including the final step that closes the goal? - Are there additional debugging options or techniques to fully reconstruct what
simp
does?
Any guidance or suggestions would be greatly appreciated!
suhr (Feb 26 2025 at 07:28):
You can just use #print
to look inside the generated code:
import Mathlib
set_option trace.Meta.Tactic.simp true
def foo : 1 + 0 = 1 * 1 := by simp
#print foo
#check of_eq_true
Ruben Van de Velde (Feb 26 2025 at 07:50):
If you want to know how exactly simp
does what it does, I guess you should read the implementation
John Smith (Feb 26 2025 at 07:58):
suhr said:
You can just use
When I tried using #print
to inspect some mathlib lemmas that were proven by simp
, I encountered an issue. The output often contains references to _auxLemma
. However, when I attempt to check these auxiliary lemmas, Lean 4 responds with unknown constant
.
For example:
#print SimpleGraph.isClique_empty
The output is:
theorem SimpleGraph.isClique_empty.{u_1} : ∀ {α : Type u_1} {G : SimpleGraph α}, G.IsClique ∅ := fun {α} {G} ↦ of_eq_true (Mathlib.Data.Set.Pairwise.Basic._auxLemma.1 G.Adj)
But when I try to inspect Mathlib.Data.Set.Pairwise.Basic._auxLemma.1
, Lean 4 gives me the error:
unknown identifier 'Mathlib.Data.Set.Pairwise.Basic._auxLemma'
why this happens? Are these _auxLemma
definitions inaccessible or intentionally hidden? Is there a way to fully explore the steps used by simp
in such cases?
John Smith (Feb 26 2025 at 07:59):
Ruben Van de Velde said:
If you want to know how exactly
simp
does what it does, I guess you should read the implementation
Nice suggestion, I will try
Patrick Massot (Feb 26 2025 at 09:31):
See also https://github.com/nomeata/lean-calcify
John Smith (Feb 27 2025 at 05:57):
Patrick Massot said:
calcify
is a useful tactic for breaking down proofs into clear steps.
However, in complex cases, calcify
may fail, and in other situations, it can still involve auxLemma
.
Is there currently a fully mature explanation tactic or tool that can provide complete transparency into what simp
does?
Kyle Miller (Feb 27 2025 at 06:14):
The step to close the goal is hard-coded. docs#Lean.Meta.simpTargetCore looks to see that the goal is True
, and if so, uses of_eq_true
to turn the proof generated by simp
that p = True
into a proof of p
. (Or, if the simplification was purely definitional, it uses True.intro
directly.)
Kyle Miller (Feb 27 2025 at 06:14):
It's part of the simp
tactic, but not the core simp
algorithm.
Mario Carneiro (Mar 13 2025 at 12:33):
John Smith said:
- The trace does not show how
simp
closes the final goal (e.g., proving⊢ True
).
simp closes the final goal by proving |- True
Mario Carneiro (Mar 13 2025 at 12:33):
it always proves goals by reducing them to True
Last updated: May 02 2025 at 03:31 UTC