Zulip Chat Archive

Stream: mathlib4

Topic: Linter for generalizing type class hypotheses


Jovan Gerbscheid (Mar 21 2025 at 00:58):

I made a simple linter that tries to find type class assumptions that can be generalized.

Code

It works by asking whether a hypothesis inst always appears inside the same application or projection. If so, then replace this expression by a new free variable, and check if the result is still type correct. So far it only looks at hypotheses that don't appear in other hypotheses. It also won't necessarily give the most general generalization.

This is similar to #mathlib4 > Elab to generalize type classes for theorems , except this looks at the underlying expressions, instead of modifying the syntax.

Running it on Lean and Batteries yields a few theorems that can be generalized (lean#7611 and batteries#1171)

Running it on Mathlib gives an enormous ~2500 results, after filtering out most unwanted results. Here they are in a file:

Generalizable_hypotheses.md

The filtering is necessary because not everying that the linter finds is a reasonable generalization, such as replacing Nonempty _ by Inhabited _ or by NeZero 1, or replacing NoMaxOrder α by NoMinOrder αᵒᵈ

Vlad Tsyrklevich (Mar 21 2025 at 06:47):

Cool! I think an approach working on Exprs has a lot of advantages, speed being a very important one, and I had begun to regret my original Syntax approach for how slow it was. This seems to be strictly more general than my implementation, since it also covers type classes in variable blocks, and finds about ~3x as many as mine does. One thing I had found I needed was to add some filtering for what generalizations are performed since some generalizations are not meaningful (this was specifically to cover Algebra, Module, and IsTopological* classes, though there may be more.)

Vlad Tsyrklevich (Mar 21 2025 at 06:48):

It also won't necessarily give the most general generalization.

Could you give an example when this is the case?

Vlad Tsyrklevich (Mar 21 2025 at 07:27):

Based on just skimming through the list, some of the following look to me like generalizations that should be excluded:

#check @measurableSet_lineDifferentiableAt_uncurry /- [[SecondCountableTopology
   E] can be generalized to [SecondCountableTopologyEither E E]] -/
#check @Set.instNoZeroDivisors /- [[NoZeroDivisors α] can be generalized to [NoZeroSMulDivisors α α]] -/

Applying this didn't work:

-- Mathlib.Analysis.CStarAlgebra.ContinuousFunctionalCalculus.Isometric
#check @isometry_cfcHom /- [[IsometricContinuousFunctionalCalculus R A
   p] can be generalized to [ContinuousFunctionalCalculus R A p]] -/

It may be worth trying to apply all of these and see if something breaks to find bugs. In my experience, I found that you may want to exclude Mathlib/Tactic, Mathlib/Algebra/Field/IsField.lean, and Mathlib/Data/Int/Cast/Field.lean

Vlad Tsyrklevich (Mar 21 2025 at 07:29):

This also works on instances which is cool, though the volume of hard-to-tell-if-its-useful generalizations with the added difficulty of generalizing type class assumptions in variable blocks led me to not get very far when I tried to see if I could split any out from your list.

Jovan Gerbscheid (Mar 21 2025 at 09:53):

One example of not giving the most general generalization is where Monad m can be replaced by Functor m, but it suggests to replace it with Applicative m.

Vlad Tsyrklevich (Mar 21 2025 at 10:20):

It's not immediately clear to me why that would be the case, e.g. what is the reason why a less general class may be picked?

Jovan Gerbscheid (Mar 21 2025 at 10:21):

I could change the code to also look for the more general one, but currently it just looks for type classes that are "one step away"

Jovan Gerbscheid (Mar 21 2025 at 10:22):

The code doesn't actually use anything about type classes. It is more of a hypothesis generalizer. And at the end it checks that it generalized a type class to a type class.

Jovan Gerbscheid (Mar 21 2025 at 11:02):

Here's an updated version of the document, now with 2092 theorems.

Generalizable_hypotheses.md


Last updated: May 02 2025 at 03:31 UTC