lean4-htt/tests/lean/run/hasNotBit.lean
Joachim Breitner 27e5e21bfe
perf: use Nat-based bitmask in sparse cases construction (#11200)
This PR changes how sparse case expressions represent the
none-of-the-above information. Instead of of many `x.ctorIdx ≠ i`
hypotheses, it introduces a single `Nat.hasNotBit mask x.ctorIdx`
hypothesis which compresses that information into a bitmask. This avoids
a quadratic overhead during splitter generation, where all n assumptions
would be refined through `.subst` and `.cases` constructions for all n
assumption of the splitter alternative.

The definition of `Nat.hasNotBit` uses `Nat.rightShift` which is fiddly
to get to reduce well, especially on open terms and with `Meta.whnf`.
Some experimentation was needed to find proof terms that work, these are
all put together in the `Lean.Meta.HasNotBit` module.

Fixes #11183

---------

Co-authored-by: Rob23oba <152706811+Rob23oba@users.noreply.github.com>
2025-11-17 10:05:18 +00:00

125 lines
3.4 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.

import Lean
open Lean Meta
/-!
Testing Elab and Kernel reduction behavior with regards to Nat.shiftRight.
-/
example : [x].ctorIdx = 1 := rfl
example : Nat.land 1 (Nat.shiftRight 8 1) = 0 := rfl
-- The WHNF reduction does not reduce here:
/--
error: Type mismatch
Eq.refl 0
has type
0 = 0
but is expected to have type
Nat.land 1 (Nat.shiftRight 8 [x].ctorIdx) = 0
-/
#guard_msgs in
example : Nat.land 1 (Nat.shiftRight 8 ([x].ctorIdx)) = 0 := Eq.refl 0
example : Nat.land 1 (Nat.shiftRight 8 ([x].ctorIdx)) = 0 :=
@id (Nat.land 1 (Nat.shiftRight 8 1) = 0) (Eq.refl 0)
elab "refl0" : tactic =>
Lean.Elab.Tactic.closeMainGoalUsing `refl0 fun _ _ =>
Lean.Meta.mkEqRefl (Lean.mkRawNatLit 0)
/--
error: (kernel) declaration type mismatch, '_example' has type
∀ {α : Type u_1} {x : α}, 0 = 0
but it is expected to have type
∀ {α : Type u_1} {x : α}, Nat.land 1 (Nat.shiftRight 8 [x].ctorIdx) = 0
-/
#guard_msgs in
example : Nat.land 1 (Nat.shiftRight 8 ([x].ctorIdx)) = 0 := by
refl0
elab "eagerrefl0" : tactic =>
Lean.Elab.Tactic.closeMainGoalUsing `refl0 fun _ _ => do
Lean.Meta.mkAppM `eagerReduce #[← Lean.Meta.mkEqRefl (Lean.mkRawNatLit 0)]
/--
error: (kernel) declaration type mismatch, '_example' has type
∀ {α : Type u_1} {x : α}, 0 = 0
but it is expected to have type
∀ {α : Type u_1} {x : α}, Nat.land 1 (Nat.shiftRight 8 [x].ctorIdx) = 0
-/
#guard_msgs in
example : Nat.land 1 (Nat.shiftRight 8 ([x].ctorIdx)) = 0 := by
eagerrefl0
-- A variant that uses the expected (unreduced) type as the first argument to eagerReduce
elab "eagerrefl0'" : tactic =>
Lean.Elab.Tactic.closeMainGoalUsing `refl0 fun goal _ => do
let u ← getLevel goal
return mkApp2 (mkConst ``eagerReduce [u]) goal (← mkEqRefl (mkRawNatLit 0))
/--
error: (kernel) application type mismatch
eagerReduce (Eq.refl 0)
argument has type
0 = 0
but function has type
Nat.land 1 (Nat.shiftRight 8 [x].ctorIdx) = 0 → Nat.land 1 (Nat.shiftRight 8 [x].ctorIdx) = 0
-/
#guard_msgs in
example : Nat.land 1 (Nat.shiftRight 8 ([x].ctorIdx)) = 0 := by
eagerrefl0'
/--
error: Application type mismatch: The argument
Eq.refl true
has type
true = true
but is expected to have type
(Nat.land 1 (Nat.shiftRight 8 [x].ctorIdx)).beq 0 = true
in the application
Nat.eq_of_beq_eq_true (Eq.refl true)
-/
#guard_msgs in
example : Nat.land 1 (Nat.shiftRight 8 ([x].ctorIdx)) = 0 :=
Nat.eq_of_beq_eq_true (Eq.refl true)
/--
error: Application type mismatch: The argument
Eq.refl true
has type
true = true
but is expected to have type
(Nat.land 1 (Nat.shiftRight 8 [x].ctorIdx)).beq 0 = true
in the application
eagerReduce (Eq.refl true)
-/
#guard_msgs in
example : Nat.land 1 (Nat.shiftRight 8 ([x].ctorIdx)) = 0 :=
Nat.eq_of_beq_eq_true (eagerReduce (Eq.refl true))
elab "reflTrue" : tactic =>
Lean.Elab.Tactic.closeMainGoalUsing `refl0 fun _ _ =>
Lean.Meta.mkEqRefl (Lean.mkConst ``Bool.true)
-- This works! (But why?)
example : Nat.land 1 (Nat.shiftRight 8 ([x].ctorIdx)) = 0 :=
Nat.eq_of_beq_eq_true (by reflTrue)
/--
error: Type mismatch
Eq.refl true
has type
true = true
but is expected to have type
(Nat.land 1 (Nat.shiftRight 8 [x].ctorIdx)).beq 0 = true
-/
#guard_msgs in
example : Nat.beq (Nat.land 1 (Nat.shiftRight 8 ([x].ctorIdx))) 0 := Eq.refl true
-- This also works (But why?)
example : Nat.beq (Nat.land 1 (Nat.shiftRight 8 ([x].ctorIdx))) 0 := by reflTrue