Files
lean4/tests/lean/decEqMutualInductives.lean
Joachim Breitner ccb8568756 feat: linear-size DecidableEq instance (#10152)
This PR introduces an alternative construction for `DecidableEq`
instances that avoids the quadratic overhead of the default
construction.

The usual construction uses a `match` statement that looks at each pair
of constructors, and thus is necessarily quadratic in size. For
inductive data type with dozens of constructors or more, this quickly
becomes slow to process.

The new construction first compares the constructor tags (using the
`.ctorIdx` introduced in #9951), and handles the case of a differing
constructor tag quickly. If the constructor tags match, it uses the
per-constructor-eliminators (#9952) to create a linear-size instance. It
does so by creating a custom “matcher” for a parallel match on the data
types and the `h : x1.ctorIdx = x2.ctorIdx` assumption; this behaves
(and delaborates) like a normal `match` statement, but is implemented in
a bespoke way. This same-constructor-matcher will be useful for
implementing other instances as well.

The new construction produces less efficient code at the moment, so we
use it only for inductive types with 10 or more constructors by default.
The option `deriving.decEq.linear_construction_threshold` can be used to
adjust the threshold; set it to 0 to always use the new construction.
2025-09-03 06:31:49 +00:00

61 lines
1.2 KiB
Lean4

/-! Verify that the derive handler for `DecidableEq` handles mutual inductive types-/
-- Print the generated derivations
set_option trace.Elab.Deriving.decEq true
namespace A
set_option deriving.decEq.linear_construction_threshold 1000
mutual
inductive Tree : Type where
| node : ListTree Tree
inductive ListTree : Type where
| nil : ListTree
| cons : Tree ListTree ListTree
deriving DecidableEq
end
mutual
inductive Foo₁ : Type where
| foo₁₁ : Foo₁
| foo₁₂ : Foo₂ Foo₁
deriving DecidableEq
inductive Foo₂ : Type where
| foo₂ : Foo₃ Foo₂
inductive Foo₃ : Type where
| foo₃ : Foo₁ Foo₃
end
end A
namespace B
set_option deriving.decEq.linear_construction_threshold 0
mutual
inductive Tree : Type where
| node : ListTree Tree
inductive ListTree : Type where
| nil : ListTree
| cons : Tree ListTree ListTree
deriving DecidableEq
end
mutual
inductive Foo₁ : Type where
| foo₁₁ : Foo₁
| foo₁₂ : Foo₂ Foo₁
deriving DecidableEq
inductive Foo₂ : Type where
| foo₂ : Foo₃ Foo₂
inductive Foo₃ : Type where
| foo₃ : Foo₁ Foo₃
end
end B