lean4-htt/tests/elab/cbv1.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

225 lines
4.6 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 Std
set_option cbv.warning false
def function (n : Nat) : Nat := match n with
| 0 => 0 + 1
| Nat.succ n => function n + 1
termination_by (n,0)
example : function 150 = 151 := by
conv =>
lhs
cbv
example : ((1,1).1,1).1 = 1 := by
conv =>
lhs
cbv
def f : Unit -> Nat × Nat := fun _ => (1, 2)
example : (f ()).2 = 2 := by
conv =>
lhs
cbv
def g : Unit → (Nat → Nat) × (Nat → Nat) := fun _ => (fun x => x + 1, fun x => x + 3)
example : (g ()).1 6 = 7 := by
conv =>
lhs
cbv
example : "abx" ++ "c" = "a" ++ "bxc" := by
conv =>
lhs
cbv
conv =>
rhs
cbv
example : instHAdd.1 2 2 = 4 := by
conv =>
lhs
cbv
example : (fun y : Nat → Nat => (fun x => y x)) Nat.succ 1 = 2 := by
conv =>
lhs
cbv
example : (Std.TreeMap.empty.insert "a" "b" : Std.TreeMap String String).toList = [("a", "b")] := by
conv =>
lhs
cbv
theorem array_test : (List.replicate 200 5 : List Nat).reverse = List.replicate 200 5 := by
conv =>
lhs
cbv
conv =>
rhs
cbv
def testFun (l : List Nat) : Nat := Id.run do
let mut i := 0
for _ in l do
i := i + 1
return i
-- Possibly a good benchmark for dealing with let expressions
example : testFun [1,2,3,4,5] = 5 := by
conv =>
lhs
cbv
example : "ab".length + "ab".length = ("ab" ++ "ab").length := by
conv =>
lhs
cbv
conv =>
rhs
cbv
example : (((Std.TreeMap.empty : Std.TreeMap Nat Nat).insert 2 4).toList ++ [(5, 6)]).reverse = [(5,6), (2,4)] := by
conv =>
lhs
cbv
def h := ()
example : h = () := by
conv =>
lhs
cbv
def IsSubseq (s₁ : String) (s₂ : String) : Prop :=
List.Sublist s₁.toList s₂.toList
def vowels : List Char := ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']
def removeVowels (s : String) : String :=
String.ofList (s.toList.filter (· ∉ vowels))
example : removeVowels "abcdef" = "bcdf" := by
conv =>
lhs
cbv
rfl
example : removeVowels "abcdef\nghijklm" = "bcdf\nghjklm" := by
conv =>
lhs
cbv
rfl
example : removeVowels "aaaaa" = "" := by
conv =>
lhs
cbv
rfl
example : removeVowels "aaBAA" = "B" := by
conv =>
lhs
cbv
rfl
example : removeVowels "zbcd" = "zbcd" := by
conv =>
lhs
cbv
rfl
def Nat.factorial : Nat → Nat
| 0 => 1
| .succ n => Nat.succ n * factorial n
notation:10000 n "!" => Nat.factorial n
def Nat.brazilianFactorial : Nat → Nat
| .zero => 1
| .succ n => (Nat.succ n)! * brazilianFactorial n
def special_factorial (n : Nat) : Nat :=
special_factorial.go n 1 1 0
where
go (n fact brazilFact curr : Nat) : Nat :=
if _h: curr >= n
then brazilFact
else
let fact' := (curr + 1) * fact
let brazilFact' := fact' * brazilFact
special_factorial.go n fact' brazilFact' (Nat.succ curr)
termination_by n - curr
example : Nat.brazilianFactorial 4 = 288 := by
conv =>
lhs
cbv
example : special_factorial 4 = 288 := by
conv =>
lhs
cbv
example : Nat.brazilianFactorial 5 = 34560 := by
conv =>
lhs
cbv
example : Nat.brazilianFactorial 7 = 125411328000 := by
conv =>
lhs
cbv
attribute [cbv_opaque] Std.DHashMap.emptyWithCapacity
attribute [cbv_opaque] Std.DHashMap.insert
attribute [cbv_opaque] Std.DHashMap.getEntry
attribute [cbv_opaque] Std.DHashMap.contains
attribute [cbv_eval] Std.DHashMap.contains_emptyWithCapacity
attribute [cbv_eval] Std.DHashMap.contains_insert
example : ((Std.DHashMap.emptyWithCapacity : Std.DHashMap Nat (fun _ => Nat)).insert 5 3).contains 5 = true := by
conv =>
lhs
cbv
@[cbv_opaque] def opaque_const : Nat := Nat.zero
@[cbv_eval] theorem opaque_fn_spec : opaque_const = 0 := by rfl
example : opaque_const = 0 := by conv => lhs; cbv
def myAdd (m n : Nat) := match m with
| 0 => n
| m' + 1 => (myAdd m' n) + 1
@[cbv_eval] theorem myAdd_test : myAdd 22 23 = 45 := by rfl
theorem fast_path : myAdd 22 23 = 45 := by conv => lhs; cbv
/--
info: theorem fast_path : myAdd 22 23 = 45 :=
Eq.mpr
(id
((fun a a_1 e_a =>
Eq.rec (motive := fun a_2 e_a => ∀ (a_3 : Nat), (a = a_3) = (a_2 = a_3)) (fun a_2 => Eq.refl (a = a_2)) e_a)
(myAdd 22 23) 45 (Eq.trans myAdd_test (Eq.refl 45)) 45))
(Eq.refl 45)
-/
#guard_msgs in
#print fast_path
theorem slow_path : myAdd 0 1 = 1 := by conv => lhs; cbv
/--
info: theorem slow_path : myAdd 0 1 = 1 :=
Eq.mpr
(id
((fun a a_1 e_a =>
Eq.rec (motive := fun a_2 e_a => ∀ (a_3 : Nat), (a = a_3) = (a_2 = a_3)) (fun a_2 => Eq.refl (a = a_2)) e_a)
(myAdd 0 1) 1 (Eq.trans (myAdd.eq_1 1) (Eq.refl 1)) 1))
(Eq.refl 1)
-/
#guard_msgs in
#print slow_path