Zulip Chat Archive

Stream: general

Topic: counting classes and instances


Jeremy Avigad (Oct 16 2023 at 16:39):

Is there an easy way to get a rough (or exact) estimate of the number of classes and instances in Mathlib? grep and wc overcount the occurrences of the word "class" or "instance" in comments. I can try my hand at metaprogramming, but any pointers or hints will be appreciated.

Mac Malone (Oct 16 2023 at 17:00):

A quick-and-dirty approximation for a given namespace:

import Lean.Meta.Instances

open Lean Meta

def countClassesAndInstances [Monad m] [MonadEnv m] (ns := Name.anonymous) : m (Nat × Nat) := do
  let s := classExtension.getState ( getEnv)
  let classes := s.outParamMap.fold (init := #[]) fun a k _ => a.push k
  let classes := classes.filter ns.isPrefixOf
  let s := instanceExtension.getState ( getEnv)
  let instances := s.instanceNames.foldl (init := #[]) fun a k _ => a.push k
  let instances := s.erased.fold (init := instances) fun a k => a.erase k
  let instances := instances.filter ns.isPrefixOf
  return (classes.size, instances.size)

/-
classes: 144
instances: 1526
-/
#eval show CoreM _ from do
  let (numClasses, numInstances)  countClassesAndInstances
  IO.println s!"classes: {numClasses}"
  IO.println s!"instances: {numInstances}"

/-
classes: 35
instances: 772
-/
#eval show CoreM _ from do
  let (numClasses, numInstances)  countClassesAndInstances `Lean
  IO.println s!"classes: {numClasses}"
  IO.println s!"instances: {numInstances}"

Eric Wieser (Oct 16 2023 at 17:05):

With import Mathlib, that's

classes: 22071
instances: 1296

Eric Wieser (Oct 16 2023 at 17:05):

I assume those are backwards and I copied your code just before the edit!

Jeremy Avigad (Oct 16 2023 at 17:16):

Thanks! While waiting, I decided not to be so lazy, so I tried adapting some code that Floris once wrote. I came up with this, which reports almost the same results on an older version of Mathlib, i.e. 1293 classes and 22110 instances:

import Mathlib

open Lean Meta Elab Command

def getClassAndInstanceCounts : MetaM Unit := do
  let classes := classExtension.getState ( getEnv) |>.outParamMap
  let instances := instanceExtension.getState ( getEnv) |>.instanceNames
  logInfo m!"classes: {classes.size}"
  logInfo m!"instances: {instances.size}"

run_cmd liftCoreM <| MetaM.run' <| do
  getClassAndInstanceCounts

I guess Mac is filtering out anonymous classes and instances. I'll check to see how much of a difference that makes..

Jeremy Avigad (Oct 16 2023 at 17:19):

Oh, I see, Mac's code lets us filter for any prefix. Thanks!

Mac Malone (Oct 16 2023 at 17:20):

@Jeremy Avigad It also filters out instances which have been erased, which may or may not be desirable in your use case.

Eric Wieser (Oct 16 2023 at 17:30):

What does it mean for an instance to have been erased?

Floris van Doorn (Oct 16 2023 at 20:11):

I think it means you've written attribute [-instance] Foo. I believe those erasures a local, so it shouldn't matter.

Eric Wieser (Oct 16 2023 at 21:05):

I think attribute [local instance] Foo counts as an erased instance too? My understanding was that local instances were globally registered then globally erased, but that was a guess after a cursory read of the source.


Last updated: Dec 20 2023 at 11:08 UTC