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.
623 lines
13 KiB
Text
623 lines
13 KiB
Text
/-!
|
|
# Tests for `simp` of `have` expressions (and some `let` expressions)
|
|
|
|
Note: There are additional stress tests of deep `have`s in tests/lean/run/simpLetFunIssue.lean
|
|
-/
|
|
|
|
set_option linter.unusedSimpArgs false
|
|
|
|
-- Enable simp consistency checks, so that the elaborator type checker is run on generated proofs.
|
|
-- We want this so that we can verify that haves are "elaborator type correct",
|
|
-- since the kernel does not check `nonDep`.
|
|
set_option debug.simp.check.have true
|
|
-- To see the types of `have` binders for verification.
|
|
set_option pp.letVarTypes true
|
|
|
|
/-! Zeta reduction of lets -/
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 5
|
|
⊢ 1 + 4 = n
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 5) :
|
|
let x := 1; let _y := 2; let _z := 3; let w := 4; x + w = n := by
|
|
simp +zeta only
|
|
trace_state
|
|
simp [h]
|
|
|
|
/-! Turning off zeta reduction of lets -/
|
|
/-- error: `simp` made no progress -/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 5) :
|
|
let x := 1; let _y := 2; let _z := 3; let w := 4; x + w = n := by
|
|
simp -zeta -zetaUnused -letToHave only
|
|
|
|
/-! Turning off zeta reduction of lets. Lets can only be dsimped. -/
|
|
/-- error: `simp` made no progress -/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 5) :
|
|
let x := 1; let _y := 2; let _z := 3; let w := 4; x + w = n := by
|
|
simp -zeta -zetaUnused -letToHave only [h]
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 5
|
|
⊢ let x : Nat := 1;
|
|
let _y : Nat := 2;
|
|
let _z : Nat := 3;
|
|
let w : Nat := 4;
|
|
x + w = n
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 5) :
|
|
let x := 1; let _y := 2; let _z := 3; let w := 4 + 0; x + w = n + 0 := by
|
|
simp -zeta -zetaUnused -letToHave only [h, Nat.add_zero]
|
|
trace_state
|
|
simp [h]
|
|
|
|
/-! letToHave -/
|
|
/--
|
|
error: unsolved goals
|
|
n : Nat
|
|
h : n = 5
|
|
⊢ have x : Nat := 1;
|
|
have _y : Nat := 2;
|
|
have _z : Nat := 3;
|
|
have w : Nat := 4;
|
|
x + w = n
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 5) :
|
|
let x := 1; let _y := 2; let _z := 3; let w := 4; x + w = n := by
|
|
simp -zeta -zetaUnused +letToHave only
|
|
|
|
/-! Enabling zetaUnused for lets -/
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 5
|
|
⊢ let x : Nat := 1;
|
|
let w : Nat := 4;
|
|
x + w = n
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 5) :
|
|
let x := 1; let _y := 2; let _z := 3; let w := 4; x + w = n := by
|
|
simp -zeta +zetaUnused -letToHave only
|
|
trace_state
|
|
simp [h]
|
|
|
|
/-! Zeta reduction of haves -/
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 5
|
|
⊢ 1 + 4 = n
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 5) :
|
|
have x := 1; have _y := 2; have _z := 3; have w := 4; x + w = n := by
|
|
simp +zeta only
|
|
trace_state
|
|
simp [h]
|
|
|
|
/-! Turning off zeta reduction of haves, including with specific `zetaHave` option. -/
|
|
/-- error: `simp` made no progress -/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 5) :
|
|
have x := 1; have _y := 2; have _z := 3; have w := 4; x + w = n := by
|
|
simp -zeta -zetaUnused only
|
|
/-- error: `simp` made no progress -/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 5) :
|
|
have x := 1; have _y := 2; have _z := 3; have w := 4; x + w = n := by
|
|
simp -zetaHave -zetaUnused only
|
|
|
|
/-! Enabling zetaUnused for haves, and just haves -/
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 5
|
|
⊢ have x : Nat := 1;
|
|
have w : Nat := 4;
|
|
x + w = n
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 5) :
|
|
have x := 1; have _y := 2; have _z := 3; have w := 4; x + w = n := by
|
|
simp -zeta +zetaUnused only
|
|
trace_state
|
|
simp [h]
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 5
|
|
⊢ have x : Nat := 1;
|
|
have w : Nat := 4;
|
|
x + w = n
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 5) :
|
|
have x := 1; have _y := 2; have _z := 3; have w := 4; x + w = n := by
|
|
simp -zetaHave +zetaUnused only
|
|
trace_state
|
|
simp [h]
|
|
|
|
/-! Zeta reduction, but no zeta reduction of haves. -/
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 5
|
|
⊢ have y : Nat := 2 + 1;
|
|
have _z : Nat := 3 + 1 + y;
|
|
1 + 4 = n
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 5) :
|
|
let x := 1; have y := 2 + x; have _z := 3 + x + y; let w := 4; x + w = n := by
|
|
simp +zeta -zetaHave -zetaUnused -letToHave only
|
|
trace_state
|
|
simp [h]
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 5
|
|
⊢ have y : Nat := 3;
|
|
have _z : Nat := 4 + y;
|
|
5 = n
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 5) :
|
|
let x := 1; have y := 2 + x; have _z := 3 + x + y; let w := 4; x + w = n := by
|
|
simp +zeta -zetaHave -zetaUnused -letToHave [Nat.reduceAdd]
|
|
trace_state
|
|
simp [h]
|
|
|
|
def fix1 (n : Nat) : Fin (n + 1) := 0
|
|
|
|
/-!
|
|
Fixed because appears in type of body.
|
|
-/
|
|
/-- error: `simp` made no progress -/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 5) :
|
|
(have a := n + 1; fix1 a) = 0 := by
|
|
simp -zeta -zetaUnused [h]
|
|
|
|
/-!
|
|
Fixed, but can dsimp value.
|
|
-/
|
|
/--
|
|
trace: n : Nat
|
|
_h : n = 5
|
|
⊢ (have a : Nat := n + 1;
|
|
fix1 a) =
|
|
0
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (_h : n = 5) :
|
|
(have a := n + 0 + 1; fix1 a) = 0 := by
|
|
simp -zeta -zetaUnused [_h]
|
|
trace_state
|
|
simp [fix1]
|
|
|
|
/-!
|
|
Check that zetaUnused doesn't affect this.
|
|
-/
|
|
/--
|
|
trace: n : Nat
|
|
_h : n = 5
|
|
⊢ (have a : Nat := n + 1;
|
|
fix1 a) =
|
|
0
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (_h : n = 5) :
|
|
(have _u0 := 0; have a := n + 0 + 1; have _u1 := 1; fix1 a) = 0 := by
|
|
simp -zeta +zetaUnused [_h]
|
|
trace_state
|
|
simp [fix1]
|
|
|
|
/-!
|
|
Appears in the type of another `have` in telescope, but not fixed.
|
|
-/
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 5
|
|
⊢ (have a : Nat := 6;
|
|
have b : Fin (a + 1) := fix1 a;
|
|
↑b) =
|
|
0
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 5) :
|
|
(have a := 0 + n + 1; have b := 0 + fix1 a + 0; (b : Nat)) = 0 := by
|
|
simp -zeta -zetaUnused [h]
|
|
trace_state
|
|
simp [fix1]
|
|
|
|
/-!
|
|
Check that zetaUnused doesn't affect this.
|
|
-/
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 5
|
|
⊢ (have a : Nat := 6;
|
|
have b : Fin (a + 1) := fix1 a;
|
|
↑b) =
|
|
0
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 5) :
|
|
(have _u0 := 0; have a := 0 + n + 1; have _u1 := 1; have b := 0 + fix1 a + 0; have _u2 := 2; (b : Nat)) = 0 := by
|
|
simp -zeta +zetaUnused [h]
|
|
trace_state
|
|
simp [fix1]
|
|
|
|
/-!
|
|
Transitively unused `have`s.
|
|
-/
|
|
/--
|
|
trace: ⊢ have m : Nat := 1;
|
|
have n : Nat := 1;
|
|
n = m
|
|
-/
|
|
#guard_msgs in
|
|
example :
|
|
have m := 1; have u0 := 0; have u1 := u0; have n := 1; have u2 := u1; have u3 := u2; have _u4 := u3; n = m := by
|
|
simp -zeta
|
|
trace_state
|
|
simp
|
|
|
|
/-!
|
|
Unused, unfixed, fixed, all six permutations, with a changing body.
|
|
-/
|
|
/--
|
|
trace: n : Nat
|
|
⊢ (have a : Nat := n;
|
|
have b : Nat := 0 + n;
|
|
(a, fix1 b)) =
|
|
(n, 0)
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) :
|
|
(have _u1 := 1; have a := 0 + n; have b := 0 + n; (0 + a, fix1 b)) = (n, 0) := by
|
|
simp -zeta
|
|
trace_state
|
|
rfl
|
|
/--
|
|
trace: n : Nat
|
|
⊢ (have a : Nat := n;
|
|
have b : Nat := 0 + n;
|
|
(a, fix1 b)) =
|
|
(n, 0)
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) :
|
|
(have a := 0 + n; have _u1 := 1; have b := 0 + n; (0 + a, fix1 b)) = (n, 0) := by
|
|
simp -zeta
|
|
trace_state
|
|
rfl
|
|
/--
|
|
trace: n : Nat
|
|
⊢ (have a : Nat := n;
|
|
have b : Nat := 0 + n;
|
|
(a, fix1 b)) =
|
|
(n, 0)
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) :
|
|
(have a := 0 + n; have b := 0 + n; have _u1 := 1; (0 + a, fix1 b)) = (n, 0) := by
|
|
simp -zeta
|
|
trace_state
|
|
rfl
|
|
/--
|
|
trace: n : Nat
|
|
⊢ (have b : Nat := 0 + n;
|
|
have a : Nat := n;
|
|
(a, fix1 b)) =
|
|
(n, 0)
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) :
|
|
(have _u1 := 1; have b := 0 + n; have a := 0 + n; (0 + a, fix1 b)) = (n, 0) := by
|
|
simp -zeta
|
|
trace_state
|
|
rfl
|
|
/--
|
|
trace: n : Nat
|
|
⊢ (have b : Nat := 0 + n;
|
|
have a : Nat := n;
|
|
(a, fix1 b)) =
|
|
(n, 0)
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) :
|
|
(have b := 0 + n; have _u1 := 1; have a := 0 + n; (0 + a, fix1 b)) = (n, 0) := by
|
|
simp -zeta
|
|
trace_state
|
|
rfl
|
|
/--
|
|
trace: n : Nat
|
|
⊢ (have b : Nat := 0 + n;
|
|
have a : Nat := n;
|
|
(a, fix1 b)) =
|
|
(n, 0)
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) :
|
|
(have b := 0 + n; have a := 0 + n; have _u1 := 1; (0 + a, fix1 b)) = (n, 0) := by
|
|
simp -zeta
|
|
trace_state
|
|
rfl
|
|
|
|
/-!
|
|
Unused, unfixed, fixed, all six permutations, with an unchanging body.
|
|
-/
|
|
/--
|
|
trace: n : Nat
|
|
⊢ (have a : Nat := n;
|
|
have b : Nat := 0 + n;
|
|
(a, fix1 b)) =
|
|
(n, 0)
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) :
|
|
(have _u1 := 1; have a := 0 + n; have b := 0 + n; (a, fix1 b)) = (n, 0) := by
|
|
simp -zeta
|
|
trace_state
|
|
rfl
|
|
/--
|
|
trace: n : Nat
|
|
⊢ (have a : Nat := n;
|
|
have b : Nat := 0 + n;
|
|
(a, fix1 b)) =
|
|
(n, 0)
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) :
|
|
(have a := 0 + n; have _u1 := 1; have b := 0 + n; (a, fix1 b)) = (n, 0) := by
|
|
simp -zeta
|
|
trace_state
|
|
rfl
|
|
/--
|
|
trace: n : Nat
|
|
⊢ (have a : Nat := n;
|
|
have b : Nat := 0 + n;
|
|
(a, fix1 b)) =
|
|
(n, 0)
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) :
|
|
(have a := 0 + n; have b := 0 + n; have _u1 := 1; (a, fix1 b)) = (n, 0) := by
|
|
simp -zeta
|
|
trace_state
|
|
rfl
|
|
/--
|
|
trace: n : Nat
|
|
⊢ (have b : Nat := 0 + n;
|
|
have a : Nat := n;
|
|
(a, fix1 b)) =
|
|
(n, 0)
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) :
|
|
(have _u1 := 1; have b := 0 + n; have a := 0 + n; (a, fix1 b)) = (n, 0) := by
|
|
simp -zeta
|
|
trace_state
|
|
rfl
|
|
/--
|
|
trace: n : Nat
|
|
⊢ (have b : Nat := 0 + n;
|
|
have a : Nat := n;
|
|
(a, fix1 b)) =
|
|
(n, 0)
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) :
|
|
(have b := 0 + n; have _u1 := 1; have a := 0 + n; (a, fix1 b)) = (n, 0) := by
|
|
simp -zeta
|
|
trace_state
|
|
rfl
|
|
/--
|
|
trace: n : Nat
|
|
⊢ (have b : Nat := 0 + n;
|
|
have a : Nat := n;
|
|
(a, fix1 b)) =
|
|
(n, 0)
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) :
|
|
(have b := 0 + n; have a := 0 + n; have _u1 := 1; (a, fix1 b)) = (n, 0) := by
|
|
simp -zeta
|
|
trace_state
|
|
rfl
|
|
|
|
/-!
|
|
Unused tests: modifying and not modifying body.
|
|
-/
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 1
|
|
⊢ n = 1
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 1) :
|
|
(have _u1 := n; 0 + n) = 1 := by
|
|
simp -zeta
|
|
trace_state
|
|
simp [h]
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 1
|
|
⊢ n = 1
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 1) :
|
|
(have _u1 := n; n) = 1 := by
|
|
simp -zeta
|
|
trace_state
|
|
simp [h]
|
|
|
|
/-!
|
|
Non-fixed tests: modifying and not modifying value and body.
|
|
-/
|
|
/-- error: `simp` made no progress -/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 1) :
|
|
(have m := n; m) = 1 := by
|
|
simp -zeta -zetaUnused
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 1
|
|
⊢ (have m : Nat := n;
|
|
m) =
|
|
1
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 1) :
|
|
(have m := n; 0 + m) = 1 := by
|
|
simp -zeta
|
|
trace_state
|
|
simp [h]
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 1
|
|
⊢ (have m : Nat := n;
|
|
m) =
|
|
1
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 1) :
|
|
(have m := 0 + n; m) = 1 := by
|
|
simp -zeta
|
|
trace_state
|
|
simp [h]
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 1
|
|
⊢ (have m : Nat := n;
|
|
m) =
|
|
1
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 1) :
|
|
(have m := 0 + n; 0 + m) = 1 := by
|
|
simp -zeta
|
|
trace_state
|
|
simp [h]
|
|
|
|
/-!
|
|
Fixed tests: modifying and not modifying body (with simp) and value (with dsimp)
|
|
-/
|
|
/-- error: `simp` made no progress -/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 1) :
|
|
(have m := n; fix1 m) = 1 := by
|
|
simp -zeta -zetaUnused
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 0
|
|
⊢ (have m : Nat := n;
|
|
fix1 m) =
|
|
Fin.ofNat (n + 1) n
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 0) :
|
|
(have m := n; 0 + fix1 m) = Fin.ofNat (n + 1) n := by
|
|
simp -zeta
|
|
trace_state
|
|
simp [h, fix1]
|
|
/-- error: `simp` made no progress -/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 0) :
|
|
(have m := 0 + n; fix1 m) = n := by
|
|
simp -zeta
|
|
trace_state
|
|
simp [h, fix1]; rfl
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 0
|
|
⊢ (have m : Nat := n;
|
|
fix1 m) =
|
|
Fin.ofNat (n + 1) n
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 0) :
|
|
(have m := n + 0; fix1 m) = Fin.ofNat (n + 1) n := by
|
|
simp -zeta
|
|
trace_state
|
|
simp [h, fix1]
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 0
|
|
⊢ (have m : Nat := 0 + n;
|
|
fix1 m) =
|
|
Fin.ofNat (0 + n + 1) n
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 0) :
|
|
(have m := 0 + n; 0 + fix1 m) = Fin.ofNat (0 + n + 1) n := by
|
|
simp -zeta
|
|
trace_state
|
|
simp [h, fix1]
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 0
|
|
⊢ (have m : Nat := n;
|
|
fix1 m) =
|
|
Fin.ofNat (n + 1) n
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 0) :
|
|
(have m := n + 0; 0 + fix1 m) = Fin.ofNat (n + 0 + 1) n := by
|
|
simp -zeta
|
|
trace_state
|
|
simp [h, fix1]
|
|
|
|
/-!
|
|
Stress test
|
|
-/
|
|
def lp (n : Nat) (acc : Nat) :=
|
|
match n with
|
|
| 0 => acc
|
|
| n' + 1 => have k := 0 + acc + n'; lp n' k
|
|
|
|
/--
|
|
trace: n : Nat
|
|
h : n = 190
|
|
⊢ (have k : Nat := 0 + 0 + 19;
|
|
have k : Nat := 0 + k + 18;
|
|
have k : Nat := 0 + k + 17;
|
|
have k : Nat := 0 + k + 16;
|
|
have k : Nat := 0 + k + 15;
|
|
have k : Nat := 0 + k + 14;
|
|
have k : Nat := 0 + k + 13;
|
|
have k : Nat := 0 + k + 12;
|
|
have k : Nat := 0 + k + 11;
|
|
have k : Nat := 0 + k + 10;
|
|
have k : Nat := 0 + k + 9;
|
|
have k : Nat := 0 + k + 8;
|
|
have k : Nat := 0 + k + 7;
|
|
have k : Nat := 0 + k + 6;
|
|
have k : Nat := 0 + k + 5;
|
|
have k : Nat := 0 + k + 4;
|
|
have k : Nat := 0 + k + 3;
|
|
have k : Nat := 0 + k + 2;
|
|
have k : Nat := 0 + k + 1;
|
|
have k : Nat := 0 + k + 0;
|
|
k) =
|
|
n
|
|
-/
|
|
#guard_msgs in
|
|
example (n : Nat) (h : n = 190) : lp 20 0 = n := by
|
|
simp -zeta only [lp]
|
|
trace_state
|
|
simp -zeta only [Nat.zero_add]
|
|
simp only
|
|
simp [h]
|
|
|
|
-- set_option Elab.async false
|
|
-- set_option profiler true
|
|
-- set_option profiler.threshold 2
|
|
-- #time
|
|
set_option debug.simp.check.have false in
|
|
example (n : Nat) (h : n = 4950) : lp 100 0 = n := by
|
|
simp -zeta -zetaUnused only [lp]
|
|
simp -zeta only [Nat.zero_add]
|
|
simp only
|
|
simp [h]
|