lean4-htt/tests/lean/run/derivingReflBEq.lean
Joachim Breitner fa36fcd448
feat: linear-size BEq instance (#10268)
This PR adds an alternative implementation of `DerivingBEq` based on
comparing `.ctorIdx` and using a dedicated matcher for comparing same
constructors (added in #10152), to avoid the quadratic overhead of the
default match implementation. The new option
`deriving.beq.linear_construction_threshold` sets the constructor count
threshold (10 by default) for using the new construction. Such instances
also allow `deriving ReflBEq, LawfulBeq`, although these proofs for
these properties are still quadratic.
2025-09-18 21:27:25 +00:00

201 lines
5.1 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.

namespace RegularBEq
set_option deriving.beq.linear_construction_threshold 1000
-- set_option trace.Elab.Deriving.lawfulBEq true
inductive L (α : Type u) where
| nil : L α
| cons : α → L α → L α
deriving BEq, ReflBEq, LawfulBEq
/--
info: theorem RegularBEq.instReflBEqL.{u_1} : ∀ {α : Type u_1} [inst : BEq α] [ReflBEq α], ReflBEq (L α)
-/
#guard_msgs in
#print sig instReflBEqL
inductive Vec (α : Type u) : Nat → Type u where
| nil : Vec α 0
| cons : ∀ {n}, α → Vec α n → Vec α (n+1)
deriving BEq, ReflBEq, LawfulBEq
/--
info: theorem RegularBEq.instReflBEqVec.{u_1} : ∀ {α : Type u_1} {a : Nat} [inst : BEq α] [ReflBEq α], ReflBEq (Vec α a)
-/
#guard_msgs in
#print sig instReflBEqVec
inductive Enum
| mk1 | mk2 | mk3
deriving BEq, ReflBEq, LawfulBEq
/-- info: theorem RegularBEq.instReflBEqEnum : ReflBEq Enum -/
#guard_msgs in
#print sig instReflBEqEnum
-- The following type has `Eq.rec`s in its `BEq` implementation,
-- but `simp` seems to handle that just fine
inductive WithHEq (α : Type u) : Nat → Type u where
| nil : WithHEq α 0
| cons : ∀ {n m} , α → WithHEq α n → WithHEq α m → WithHEq α (n+1)
deriving BEq, ReflBEq, LawfulBEq
/--
info: RegularBEq.instReflBEqWithHEq.{u_1} {α✝ : Type u_1} {a✝ : Nat} [BEq α✝] [ReflBEq α✝] : ReflBEq (WithHEq α✝ a✝)
-/
#guard_msgs in
#check instReflBEqWithHEq
/--
info: RegularBEq.instLawfulBEqWithHEq.{u_1} {α✝ : Type u_1} {a✝ : Nat} [BEq α✝] [LawfulBEq α✝] : LawfulBEq (WithHEq α✝ a✝)
-/
#guard_msgs in
#check instLawfulBEqWithHEq
-- No `BEq` derived? Not a great error message yet, but the error location helps, so good enough.
/--
error: failed to synthesize
BEq Foo
Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.
-/
#guard_msgs in
structure Foo where
deriving ReflBEq
-- No `ReflBEq` but `LawfulBEq`? ot a great error message yet.
/--
@ +2:16...25
error: failed to synthesize
ReflBEq Bar
Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.
-/
#guard_msgs (positions := true) in
structure Bar where
deriving BEq, LawfulBEq
/--
@ +5:16...23
error: Deriving `ReflBEq` for mutual inductives is not supported
-/
#guard_msgs (positions := true) in
mutual
inductive Tree (α : Type u) where
| node : TreeList α → Tree α
| leaf : α → Tree α
deriving BEq, ReflBEq, LawfulBEq
inductive TreeList (α : Type u) where
| nil : TreeList α
| cons : Tree α → TreeList α → TreeList α
deriving BEq
end
end RegularBEq
namespace LinearBEq
set_option deriving.beq.linear_construction_threshold 0
-- set_option trace.Elab.Deriving.lawfulBEq true
inductive L (α : Type u) where
| nil : L α
| cons : α → L α → L α
deriving BEq, ReflBEq, LawfulBEq
/--
info: theorem LinearBEq.instReflBEqL.{u_1} : ∀ {α : Type u_1} [inst : BEq α] [ReflBEq α], ReflBEq (L α)
-/
#guard_msgs in
#print sig instReflBEqL
inductive Vec (α : Type u) : Nat → Type u where
| nil : Vec α 0
| cons : ∀ {n}, α → Vec α n → Vec α (n+1)
deriving BEq, ReflBEq, LawfulBEq
/--
info: theorem LinearBEq.instReflBEqVec.{u_1} : ∀ {α : Type u_1} {a : Nat} [inst : BEq α] [ReflBEq α], ReflBEq (Vec α a)
-/
#guard_msgs in
#print sig instReflBEqVec
inductive Enum
| mk1 | mk2 | mk3
deriving BEq, ReflBEq, LawfulBEq
/-- info: theorem LinearBEq.instReflBEqEnum : ReflBEq Enum -/
#guard_msgs in
#print sig instReflBEqEnum
-- The following type has `Eq.rec`s in its `BEq` implementation,
-- but `simp` seems to handle that just fine
inductive WithHEq (α : Type u) : Nat → Type u where
| nil : WithHEq α 0
| cons : ∀ {n m} , α → WithHEq α n → WithHEq α m → WithHEq α (n+1)
deriving BEq, ReflBEq, LawfulBEq
/--
info: LinearBEq.instReflBEqWithHEq.{u_1} {α✝ : Type u_1} {a✝ : Nat} [BEq α✝] [ReflBEq α✝] : ReflBEq (WithHEq α✝ a✝)
-/
#guard_msgs in
#check instReflBEqWithHEq
/--
info: LinearBEq.instLawfulBEqWithHEq.{u_1} {α✝ : Type u_1} {a✝ : Nat} [BEq α✝] [LawfulBEq α✝] : LawfulBEq (WithHEq α✝ a✝)
-/
#guard_msgs in
#check instLawfulBEqWithHEq
-- No `BEq` derived? Not a great error message yet, but the error location helps, so good enough.
/--
error: failed to synthesize
BEq Foo
Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.
-/
#guard_msgs in
structure Foo where
deriving ReflBEq
-- No `ReflBEq` but `LawfulBEq`? ot a great error message yet.
/--
@ +2:16...25
error: failed to synthesize
ReflBEq Bar
Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.
-/
#guard_msgs (positions := true) in
structure Bar where
deriving BEq, LawfulBEq
/--
@ +5:16...23
error: Deriving `ReflBEq` for mutual inductives is not supported
-/
#guard_msgs (positions := true) in
mutual
inductive Tree (α : Type u) where
| node : TreeList α → Tree α
| leaf : α → Tree α
deriving BEq, ReflBEq, LawfulBEq
inductive TreeList (α : Type u) where
| nil : TreeList α
| cons : Tree α → TreeList α → TreeList α
deriving BEq
end
end LinearBEq