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.
266 lines
4.6 KiB
Text
266 lines
4.6 KiB
Text
def f (x : Nat) : IO Nat := do
|
||
IO.println "hello world"
|
||
let aux (y : Nat) (z : Nat) : IO Nat := do
|
||
IO.println "aux started"
|
||
IO.println s!"y: {y}, z: {z}"
|
||
pure (x+y)
|
||
discard <| aux x
|
||
(x + 1) -- It is part of the application since it is indented
|
||
discard <| aux x (x -- parentheses use `withoutPosition`
|
||
-1)
|
||
discard <| aux x x;
|
||
aux x
|
||
x
|
||
|
||
/--
|
||
info: hello world
|
||
aux started
|
||
y: 10, z: 11
|
||
aux started
|
||
y: 10, z: 9
|
||
aux started
|
||
y: 10, z: 10
|
||
aux started
|
||
y: 10, z: 10
|
||
---
|
||
info: 20
|
||
-/
|
||
#guard_msgs in
|
||
#eval f 10
|
||
|
||
def g (xs : List Nat) : StateT Nat Id Nat := do
|
||
let mut xs := xs
|
||
if xs.isEmpty then
|
||
xs := [← get]
|
||
dbg_trace ">>> xs: {xs}"
|
||
return xs.length
|
||
|
||
/--
|
||
info: >>> xs: [1, 2, 3]
|
||
---
|
||
info: 3
|
||
-/
|
||
#guard_msgs in
|
||
#eval g [1, 2, 3] |>.run' 10
|
||
|
||
/--
|
||
info: >>> xs: [10]
|
||
---
|
||
info: 1
|
||
-/
|
||
#guard_msgs in
|
||
#eval g [] |>.run' 10
|
||
|
||
theorem ex1 : (g [1, 2, 4, 5] |>.run' 0) = 4 :=
|
||
rfl
|
||
|
||
theorem ex2 : (g [] |>.run' 0) = 1 :=
|
||
rfl
|
||
|
||
def h (x : Nat) (y : Nat) : Nat := Id.run <| do
|
||
let mut x := x
|
||
let mut y := y
|
||
if x > 0 then
|
||
let y' := x + 1
|
||
x := y'
|
||
else
|
||
y := y + 1
|
||
return x + y
|
||
|
||
theorem ex3 (y : Nat) : h 0 y = 0 + (y + 1) :=
|
||
rfl
|
||
|
||
theorem ex4 (y : Nat) : h 1 y = (1 + 1) + y :=
|
||
rfl
|
||
|
||
def sumOdd (xs : List Nat) (threshold : Nat) : Nat := Id.run <| do
|
||
let mut sum := 0
|
||
for x in xs do
|
||
if x % 2 == 1 then
|
||
sum := sum + x
|
||
if sum > threshold then
|
||
break
|
||
unless x % 2 == 1 do
|
||
continue
|
||
dbg_trace ">> x: {x}"
|
||
return sum
|
||
|
||
/--
|
||
info: >> x: 1
|
||
>> x: 3
|
||
>> x: 5
|
||
---
|
||
info: 16
|
||
-/
|
||
#guard_msgs in
|
||
#eval sumOdd [1, 2, 3, 4, 5, 6, 7, 9, 11, 101] 10
|
||
|
||
theorem ex5 : sumOdd [1, 2, 3, 4, 5, 6, 7, 9, 11, 101] 10 = 16 :=
|
||
rfl
|
||
|
||
-- We need `Id.run` because we still have `Monad Option`
|
||
def find? (xs : List Nat) (p : Nat → Bool) : Option Nat := Id.run do
|
||
let mut result := none
|
||
for x in xs do
|
||
if p x then
|
||
result := x
|
||
break
|
||
return result
|
||
|
||
def sumDiff (ps : List (Nat × Nat)) : Nat := Id.run do
|
||
let mut sum := 0
|
||
for (x, y) in ps do
|
||
sum := sum + x - y
|
||
return sum
|
||
|
||
theorem ex7 : sumDiff [(2, 1), (10, 5)] = 6 :=
|
||
rfl
|
||
|
||
def f1 (x : Nat) : IO Unit := do
|
||
let rec loop : Nat → IO Unit
|
||
| 0 => pure ()
|
||
| x+1 => do IO.println x; loop x
|
||
loop x
|
||
|
||
/--
|
||
info: 9
|
||
8
|
||
7
|
||
6
|
||
5
|
||
4
|
||
3
|
||
2
|
||
1
|
||
0
|
||
-/
|
||
#guard_msgs in
|
||
#eval f1 10
|
||
|
||
partial def f2 (x : Nat) : IO Unit := do
|
||
let rec
|
||
isEven : Nat → Bool
|
||
| 0 => true
|
||
| x+1 => isOdd x,
|
||
isOdd : Nat → Bool
|
||
| 0 => false
|
||
| x+1 => isEven x
|
||
IO.println ("isOdd(" ++ toString x ++ "): " ++ toString (isOdd x))
|
||
|
||
/-- info: isOdd(11): true -/
|
||
#guard_msgs in
|
||
#eval f2 11
|
||
|
||
/-- info: isOdd(10): false -/
|
||
#guard_msgs in
|
||
#eval f2 10
|
||
|
||
def split (xs : List Nat) : List Nat × List Nat := Id.run do
|
||
let mut evens := []
|
||
let mut odds := []
|
||
for x in xs.reverse do
|
||
if x % 2 == 0 then
|
||
evens := x :: evens
|
||
else
|
||
odds := x :: odds
|
||
return (evens, odds)
|
||
|
||
theorem ex8 : split [1, 2, 3, 4] = ([2, 4], [1, 3]) :=
|
||
rfl
|
||
|
||
def f3 (x : Nat) : IO Bool := do
|
||
let y ← cond (x == 0) (do IO.println "hello"; pure true) (pure false);
|
||
pure !y
|
||
|
||
def f4 (x y : Nat) : Nat × Nat := Id.run <| do
|
||
let mut (x, y) := (x, y)
|
||
match x with
|
||
| 0 => y := y + 1
|
||
| _ => x := x + y
|
||
return (x, y)
|
||
|
||
#guard f4 0 10 == (0, 11)
|
||
#guard f4 5 10 == (15,10)
|
||
|
||
theorem ex9 (y : Nat) : f4 0 y = (0, y+1) :=
|
||
rfl
|
||
|
||
theorem ex10 (x y : Nat) : f4 (x+1) y = ((x+1)+y, y) :=
|
||
rfl
|
||
|
||
def f5 (x y : Nat) : Nat × Nat := Id.run <| do
|
||
let mut (x, y) := (x, y)
|
||
match x with
|
||
| 0 => y := y + 1
|
||
| z+1 => dbg_trace "z: {z}"; x := x + y
|
||
return (x, y)
|
||
|
||
/--
|
||
info: z: 4
|
||
---
|
||
info: (11, 6)
|
||
-/
|
||
#guard_msgs in
|
||
#eval f5 5 6
|
||
|
||
theorem ex11 (x y : Nat) : f5 (x+1) y = ((x+1)+y, y) :=
|
||
rfl
|
||
|
||
def f6 (x : Nat) : Nat := Id.run <| do
|
||
let mut x := x
|
||
if x > 10 then
|
||
return 0
|
||
x := x + 1
|
||
return x
|
||
|
||
theorem ex12 : f6 11 = 0 :=
|
||
rfl
|
||
|
||
theorem ex13 : f6 5 = 6 :=
|
||
rfl
|
||
|
||
def findOdd (xs : List Nat) : Nat := Id.run <| do
|
||
for x in xs do
|
||
if x % 2 == 1 then
|
||
return x
|
||
return 0
|
||
|
||
theorem ex14 : findOdd [2, 4, 5, 8, 7] = 5 :=
|
||
rfl
|
||
|
||
theorem ex15 : findOdd [2, 4, 8, 10] = 0 :=
|
||
rfl
|
||
|
||
def f7 (ref : IO.Ref (Option (Nat × Nat))) : IO Nat := do
|
||
let some (x, y) ← ref.get | pure 100
|
||
IO.println (toString x ++ ", " ++ toString y)
|
||
return x+y
|
||
|
||
def f7Test : IO Unit := do
|
||
unless (← f7 (← IO.mkRef (some (10, 20)))) == 30 do throw $ IO.userError "unexpected"
|
||
unless (← f7 (← IO.mkRef none)) == 100 do throw $ IO.userError "unexpected"
|
||
|
||
/-- info: 10, 20 -/
|
||
#guard_msgs in
|
||
#eval f7Test
|
||
|
||
def f8 (x : Nat) : IO Nat := do
|
||
let y ←
|
||
if x == 0 then
|
||
IO.println "x is zero"
|
||
return 100 -- returns from the `do`-block
|
||
else
|
||
pure (x + 1)
|
||
IO.println ("y: " ++ toString y)
|
||
return y
|
||
|
||
def f8Test : IO Unit := do
|
||
unless (← f8 0) == 100 do throw $ IO.userError "unexpected"
|
||
unless (← f8 1) == 2 do throw $ IO.userError "unexpected"
|
||
|
||
/--
|
||
info: x is zero
|
||
y: 2
|
||
-/
|
||
#guard_msgs in
|
||
#eval f8Test
|