Zulip Chat Archive
Stream: lean4
Topic: inspect expressions
Damiano Testa (Aug 01 2023 at 10:46):
Dear All,
I often find myself wanting how a term of some inductive type is build out of its constructors. Is there a command that prints this information?
I would especially like this to work on Expr
s, since my main motivation is as a help to debug meta-code.
My current approach is a simple-minded recursion into Expr
s. Here is an example:
example : 3 ≠ 0 := by
inspect
/-
inspect: '3 ≠ 0'
'Ne' -- app
|-'Nat' -- const
|-'OfNat.ofNat' -- app
| |-'Nat' -- const
| |-'3' -- natLit
| |-'instOfNatNat' -- app
| | |-'3' -- natLit
|-'OfNat.ofNat' -- app
| |-'Nat' -- const
| |-'0' -- natLit
| |-'instOfNatNat' -- app
| | |-'0' -- natLit
-/
Damiano Testa (Aug 01 2023 at 10:47):
Before I try anything deeper, is this already available, in some form or other?
Thanks!
Damiano Testa (Aug 01 2023 at 10:55):
In case you are wondering, this is the simple-minded code that I used for the example above:
inspect
Kyle Miller (Aug 01 2023 at 11:00):
Mathlib.Tactic.Explode
has a command that's meant for showing the structure of proofs. By default it filters out anything that's not a proof though, and it flattens out the hierarchical structure of an expression, which is probably not what you want.
Kyle Miller (Aug 01 2023 at 11:04):
Here's something that simple that also gives you the Expr
structure of an expression:
import Mathlib.Tactic.ToExpr
open Lean Elab Tactic
elab "inspect" : tactic =>
withMainContext do
let ty ← instantiateMVars (← getMainTarget)
logInfo m!"{toExpr ty}"
example : 3 ≠ 0 := by
inspect
/-
Expr.app
(Expr.app (Expr.app (Expr.const `Ne [Level.succ Level.zero]) (Expr.const `Nat []))
(Expr.app
(Expr.app (Expr.app (Expr.const `OfNat.ofNat [Level.zero]) (Expr.const `Nat [])) (Expr.lit (Literal.natVal 3)))
(Expr.app (Expr.const `instOfNatNat []) (Expr.lit (Literal.natVal 3)))))
(Expr.app
(Expr.app (Expr.app (Expr.const `OfNat.ofNat [Level.zero]) (Expr.const `Nat [])) (Expr.lit (Literal.natVal 0)))
(Expr.app (Expr.const `instOfNatNat []) (Expr.lit (Literal.natVal 0))))
-/
Damiano Testa (Aug 01 2023 at 11:06):
Kyle, thank you! This is close, and, had I known about it, I would have probably stuck with Explode
ToExpr
.
Damiano Testa (Aug 01 2023 at 11:06):
I think that I prefer inspect
, but Explode
ToExpr
is good to know!
Kyle Miller (Aug 01 2023 at 11:07):
(It might be nice to tweak the ToExpr
instance to use mkApp*
functions. It's a derived instance though, so I'm not sure the best way to do this...)
Damiano Testa (Aug 01 2023 at 11:07):
(Mostly, my preference is out of aesthetics, the information about proofs is likely rarely relevant for my intended application anyway.)
Damiano Testa (Aug 01 2023 at 11:14):
As far as I can tell, ToExpr
works for several of the other inductives that I would like. For the moment, I will debug with a combination of inspect
and ToExpr
.
To be fair, it is rare that I need to inspect
much more than just the head-symbol, but I still find that displaying the information line-by-line is better suited for my application.
Last updated: Dec 20 2023 at 11:08 UTC