Zulip Chat Archive
Stream: general
Topic: Print all instances on a type
Nir Paz (Nov 04 2023 at 10:46):
When learning about a new type I like to see what instances are defined on it (until now by grepping mathlib), is there a way to show all of them? It looks like lean3 had #print instances
, but it doesn't work anymore.
Alex J. Best (Nov 04 2023 at 11:22):
There isn't a command for that (yet) as far as I know. But you can visit the docs which does have a list for each type in mathlib eg docs#Nat, under the heading " Instances for "
Nir Paz (Nov 04 2023 at 12:04):
Thanks, this is great!
Adam Topaz (Nov 04 2023 at 13:59):
We also have the #synth
command if you want to check whether a type has a particular instance
Riccardo Brasca (Nov 04 2023 at 14:04):
Alex J. Best said:
There isn't a command for that (yet) as far as I know. But you can visit the docs which does have a list for each type in mathlib eg docs#Nat, under the heading " Instances for "
Something must be a little wrong, since I see instances like this one
Riccardo Brasca (Nov 04 2023 at 14:04):
Maybe because there is "nat" in the name?
Adam Topaz (Nov 04 2023 at 14:05):
yeah that looks like a bug in doc-gen4
Eric Wieser (Nov 04 2023 at 14:07):
I would be very sad to find out that the instance list is using name matching...
Eric Wieser (Nov 04 2023 at 14:07):
In Lean3 it genuinely checked the types
Adam Topaz (Nov 04 2023 at 14:08):
ping @Henrik Böving
Henrik Böving (Nov 04 2023 at 14:08):
Quack
Riccardo Brasca (Nov 04 2023 at 14:09):
It also lists docs#IccManifold
Alex J. Best (Nov 04 2023 at 14:15):
EuclideanHalfSpace at least has a nat in the type, maye the DoldKan instance does too?
Henrik Böving (Nov 04 2023 at 14:15):
doc-gen4 does check if "Nat occurs anywhere within the type of the instance":
def getInstanceTypes (typ : Expr) : MetaM (Array Name) := do
let (_, _, tail) ← forallMetaTelescopeReducing typ
let args := tail.getAppArgs
let (_, names) ← args.mapM (Expr.forEach · findName) |>.run .empty
return names
where
findName : Expr → StateRefT (Array Name) MetaM Unit
| .const name _ => modify (·.push name)
| .sort .zero => modify (·.push "_builtin_prop")
| .sort (.succ _) => modify (·.push "_builtin_typeu")
| .sort _ => modify (·.push "_builtin_sortu")
| _ => return ()
def InstanceInfo.ofDefinitionVal (v : DefinitionVal) : MetaM InstanceInfo := do
let mut info ← DefinitionInfo.ofDefinitionVal v
let some className ← isClass? v.type | panic! s!"isClass? on {v.name} returned none"
if let some instAttr ← getDefaultInstance v.name className then
info := { info with attrs := info.attrs.push instAttr }
let typeNames ← getInstanceTypes v.type
return {
toDefinitionInfo := info,
className,
typeNames
}
Henrik Böving (Nov 04 2023 at 14:15):
I can turn this down and e.g. use a telescope and only look at the type at the end of an arrow if you want? Or something else entirely?
Eric Wieser (Nov 04 2023 at 14:23):
Maybe we want two headings, "instances for this type" and "instances involving this type, where the former is only things with an explicit argument equal to (an application of) the type?
Kyle Miller (Nov 04 2023 at 18:03):
Maybe this is a possibility?
import Lean
open Lean Meta
def getInstanceTypes (typ : Expr) : MetaM (Array Name) := do
let (_, _, tail) ← forallMetaTelescopeReducing typ
let args := tail.getAppArgs
let (_, bis, _) ← forallMetaTelescopeReducing (← inferType tail.getAppFn)
let (_, names) ← (bis.zip args).mapM findName |>.run .empty
return names
where
findName : BinderInfo × Expr → StateRefT (Array Name) MetaM Unit
| (.default, .sort .zero) => modify (·.push "_builtin_prop")
| (.default, .sort (.succ _)) => modify (·.push "_builtin_typeu")
| (.default, .sort _) => modify (·.push "_builtin_sortu")
| (.default, e) =>
match e.getAppFn with
| .const name .. => modify (·.push name)
| _ => return ()
| _ => return ()
set_option autoImplicit true
def foo (t1 t2 : Type) : Prop := True
theorem baz : foo Nat (Fin n) := trivial
#eval do getInstanceTypes (← inferType (.const ``baz []))
-- #[`Nat, `Fin]
Kyle Miller (Nov 04 2023 at 18:04):
It takes each explicit argument and returns its head constant
Henrik Böving (Nov 05 2023 at 08:58):
I added this algorithm to doc-gen, it'll be up on mathlib4_docs in a bit (when this ends: https://github.com/leanprover-community/mathlib4_docs/actions/runs/6760311745/job/18373945758) so you can see if its more to your liking
Last updated: Dec 20 2023 at 11:08 UTC