mirror of
https://github.com/leanprover/lean4.git
synced 2026-03-17 18:34:06 +00:00
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.
61 lines
1.2 KiB
Lean4
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
|