lean4-htt/tests/elab/bv_enums.lean
Garmelon 08eb78a5b2
chore: switch to new test/bench suite (#12590)
This PR sets up the new integrated test/bench suite. It then migrates
all benchmarks and some related tests to the new suite. There's also
some documentation and some linting.

For now, a lot of the old tests are left alone so this PR doesn't become
even larger than it already is. Eventually, all tests should be migrated
to the new suite though so there isn't a confusing mix of two systems.
2026-02-25 13:51:53 +00:00

263 lines
5 KiB
Text

import Std.Tactic.BVDecide
import Lean.Elab.Tactic.BVDecide
namespace Ex1
inductive State where
| sa
| sb
| sc
| sd
| se
| sf
| sg
| sh
| si
| sj
| sk
| sl
| sm
| sn
| so
| sp
/-- info: Ex1.State.enumToBitVec✝ : State → BitVec 4 -/
#guard_msgs in
#check State.enumToBitVec
/--
info: Ex1.State.eq_iff_enumToBitVec_eq✝ (x y : State) : x = y ↔ x.enumToBitVec = y.enumToBitVec
-/
#guard_msgs in
#check State.eq_iff_enumToBitVec_eq
/-- info: Ex1.State.enumToBitVec_le✝ (x : State) : x.enumToBitVec ≤ 15#4 -/
#guard_msgs in
#check State.enumToBitVec_le
structure Pair where
x : BitVec 16
s : State
-- large inductive
example (a b c : Pair) (h1 : a = b) (h2 : b.x < c.x) (h3 : b.s = c.s) : a.s = c.s ∧ a.x < c.x := by
bv_decide
end Ex1
namespace Ex2
inductive State where
| s1
| s2
structure Pair where
x : BitVec 16
s : State
h : s = .s1 ↔ x = 0
-- handling constants
example (a : Pair) (h : a.x > 0) : a.s = .s2 := by
bv_decide
/--
error: The prover found a counterexample, consider the following assignment:
x = 0#16
s = State.s1
-/
#guard_msgs in
example (x : BitVec 16) (s : State) (h1 : s = .s1 ↔ x = 0) (h : s = .s1) : x > 0 := by
bv_decide
end Ex2
namespace Ex3
-- adding ≤ domainSize - 1 hypothesis
inductive State where
| s1
| s2
| s3
example (s : State) (h : s ≠ .s1 ∧ s ≠ .s2 ∧ s ≠ .s3) : False := by
bv_decide
structure Pair where
s : State
x : BitVec 16
h1 : s ≠ .s1 ↔ x > 0
h2 : s ≠ .s2 ↔ x > 1
h3 : s ≠ .s3 ↔ x > 2
example (a : Pair) (h : a.x ≥ 100) : False := by
bv_decide
end Ex3
namespace Ex4
-- pattern matching
inductive Foo where
| a
| b
| c
| d
| e
def Foo.f1 : Foo → Foo
| .a => .b
| .b => .c
| .c => .d
| .d => .e
| .e => .a
def Foo.f2 : Foo → Foo
| .a => .c
| _ => .c
def Foo.f3 (f : Foo) (h : f ≠ .a) : Foo :=
match f with
| _ => .c
def Foo.f4 (f : Foo) (h : ∀ f : Foo, f ≠ .a) : Foo :=
match h2 : f with
| .a =>
have : False := by
specialize h f
contradiction
nomatch this
| _ => .c
open Lean Meta
/-- info: true -/
#guard_msgs in
#eval show MetaM _ from do
let res ← Lean.Elab.Tactic.BVDecide.Frontend.Normalize.isSupportedMatch ``Foo.f1.match_1
return res matches some (.simpleEnum ..)
/-- info: true -/
#guard_msgs in
#eval show MetaM _ from do
let res ← Lean.Elab.Tactic.BVDecide.Frontend.Normalize.isSupportedMatch ``Foo.f2.match_1
return res matches some (.enumWithDefault ..)
/-- info: true -/
#guard_msgs in
#eval show MetaM _ from do
let res ← Lean.Elab.Tactic.BVDecide.Frontend.Normalize.isSupportedMatch ``Foo.f3.match_1
return res matches none
/-- info: true -/
#guard_msgs in
#eval show MetaM _ from do
let res ← Lean.Elab.Tactic.BVDecide.Frontend.Normalize.isSupportedMatch ``Foo.f4.match_1
return res matches none
/-- info: true -/
#guard_msgs in
#eval show MetaM _ from do
let res ← Lean.Elab.Tactic.BVDecide.Frontend.Normalize.isSupportedMatch ``Foo.f4.match_3
return res matches none
def Foo.f5 : Foo → BitVec 64
| .a => 37
| .b => 42
| .c => 22
| .d => 11
| .e => 13
example : ∀ (x y : Foo), x.f5 = y.f5 → x = y := by
unfold Foo.f5
bv_decide
example (foo : Foo) : foo.f1 ≠ foo := by
unfold Foo.f1
bv_decide
example (h : f = Foo.a): Foo.a.f1 ≠ f := by
unfold Foo.f1
bv_decide
example (x : Foo) : x.f2 = .c := by
unfold Foo.f2
bv_decide
-- Reordering
def Foo.f6 : Foo → Foo
| .c => .d
| .b => .c
| .a => .b
| .e => .a
| .d => .e
def Foo.f7 : Foo → Foo
| .d => .c
| .a => .c
| .b => .c
| _ => .c
/-- info: true -/
#guard_msgs in
#eval show MetaM _ from do
let res ← Lean.Elab.Tactic.BVDecide.Frontend.Normalize.isSupportedMatch ``Foo.f6.match_1
return res matches some (.simpleEnum ..)
/-- info: true -/
#guard_msgs in
#eval show MetaM _ from do
let res ← Lean.Elab.Tactic.BVDecide.Frontend.Normalize.isSupportedMatch ``Foo.f7.match_1
return res matches some (.enumWithDefault ..)
example (x : Foo) : x.f1 = x.f6 := by
unfold Foo.f1 Foo.f6
bv_decide
example (x : Foo) : x.f2 = x.f7 := by
unfold Foo.f2 Foo.f7
bv_decide
end Ex4
namespace PingPong
inductive Direction where
| goingDown
| goingUp
structure State where
val : UInt16
low : UInt16
high : UInt16
direction : Direction
def State.step (s : State) : State :=
match s.direction with
| .goingDown =>
if s.val = s.low then
{ s with direction := .goingUp }
else
{ s with val := s.val - 1 }
| .goingUp =>
if s.val = s.high then
{ s with direction := .goingDown }
else
{ s with val := s.val + 1 }
def State.steps (s : State) (n : Nat) : State :=
match n with
| 0 => s
| n + 1 => (State.steps s n).step
def Inv (s : State) : Prop := s.low ≤ s.val ∧ s.val ≤ s.high ∧ s.low < s.high
example (s : State) (h : Inv s) (n : Nat) : Inv (State.steps s n) := by
induction n with
| zero => simp only [State.steps, Inv] at *; bv_decide
| succ n ih =>
simp only [State.steps, State.step, Inv] at *
bv_decide
end PingPong