Files
lean4/tests/compile_bench/deriv.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

104 lines
2.9 KiB
Lean4
Executable File

/- Benchmark for new code generator -/
inductive Expr
| Val : Int Expr
| Var : String Expr
| Add : Expr Expr Expr
| Mul : Expr Expr Expr
| Pow : Expr Expr Expr
| Ln : Expr Expr
namespace Expr
partial def pown : Int Int Int
| a, 0 => 1
| a, 1 => a
| a, n =>
let b := pown a (n / 2);
b * b * (if n % 2 = 0 then 1 else a)
partial def add : Expr Expr Expr
| Val n, Val m => Val (n + m)
| Val 0, f => f
| f, Val 0 => f
| f, Val n => add (Val n) f
| Val n, Add (Val m) f => add (Val (n+m)) f
| f, Add (Val n) g => add (Val n) (add f g)
| Add f g, h => add f (add g h)
| f, g => Add f g
partial def mul : Expr Expr Expr
| Val n, Val m => Val (n*m)
| Val 0, _ => Val 0
| _, Val 0 => Val 0
| Val 1, f => f
| f, Val 1 => f
| f, Val n => mul (Val n) f
| Val n, Mul (Val m) f => mul (Val (n*m)) f
| f, Mul (Val n) g => mul (Val n) (mul f g)
| Mul f g, h => mul f (mul g h)
| f, g => Mul f g
def pow : Expr Expr Expr
| Val m, Val n => Val (pown m n)
| _, Val 0 => Val 1
| f, Val 1 => f
| Val 0, _ => Val 0
| f, g => Pow f g
def ln : Expr Expr
| Val 1 => Val 0
| f => Ln f
def d (x : String) : Expr Expr
| Val _ => Val 0
| Var y => if x = y then Val 1 else Val 0
| Add f g => add (d x f) (d x g)
| Mul f g => add (mul f (d x g)) (mul g (d x f))
| Pow f g => mul (pow f g) (add (mul (mul g (d x f)) (pow f (Val (-1)))) (mul (ln f) (d x g)))
| Ln f => mul (d x f) (pow f (Val (-1)))
def count : Expr UInt32
| Val _ => 1
| Var _ => 1
| Add f g => count f + count g
| Mul f g => count f + count g
| Pow f g => count f + count g
| Ln f => count f
protected def Expr.toString : Expr String
| Val n => toString n
| Var x => x
| Add f g => "(" ++ Expr.toString f ++ " + " ++ Expr.toString g ++ ")"
| Mul f g => "(" ++ Expr.toString f ++ " * " ++ Expr.toString g ++ ")"
| Pow f g => "(" ++ Expr.toString f ++ " ^ " ++ Expr.toString g ++ ")"
| Ln f => "ln(" ++ Expr.toString f ++ ")"
instance : ToString Expr :=
Expr.toString
def nestAux (s : Nat) (f : Nat Expr IO Expr) : Nat Expr IO Expr
| 0, x => pure x
| m@(n+1), x => f (s - m) x >>= nestAux s f n
def nest (f : Nat Expr IO Expr) (n : Nat) (e : Expr) : IO Expr :=
nestAux n f n e
def deriv (i : Nat) (f : Expr) : IO Expr :=
do
let d := d "x" f;
IO.println (toString (i+1) ++ " count: " ++ (toString $ count d));
pure d
end Expr
open Expr
unsafe def main : List String IO UInt32
| [s] => do
let n := s.toNat!;
let x := Var "x";
let f := pow x x;
_ nest deriv n f;
pure 0
| _ => pure 1