lean4-htt/tests/lean/run/linearDecEq.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

39 lines
1.2 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-!
Tests for deriving decidable equality using the linear-size parallel match construction that takes
`x1.ctorIdx = x2.ctorIdx` as assumption.
-/
-- We always want to use the new construction in this test
set_option deriving.decEq.linear_construction_threshold 0
inductive EmptyType : Type
deriving DecidableEq
structure SimpleStruct where
field : Bool
deriving DecidableEq
inductive DependentStruct1 : Nat → Type where
| mk (n : Nat) (x : Fin n): DependentStruct1 n
deriving DecidableEq
/--
error: Dependent elimination failed: Failed to solve equation
Decidable.rec (fun h => (fun x => 1) h) (fun h => (fun x => 0) h) (instDecidableEqBool b✝ true) =
Decidable.rec (fun h => (fun x => 1) h) (fun h => (fun x => 0) h) (instDecidableEqBool b true)
-/
#guard_msgs in
inductive DependentStruct2 : Nat → Type where
| mk (b : Bool) : DependentStruct2 (if b then 0 else 1)
deriving DecidableEq
inductive Vec (α : Type u) : Nat → Type u
| nil : Vec α 0
| cons : α → {n : Nat} → Vec α n → Vec α (n+1)
deriving DecidableEq
inductive Test (α : Type)
| mk₀
| mk₁ : (n : Nat) → (α × α) → List α → Vec α n → Test α
| mk₂ : Test αα → Test α
deriving DecidableEq