This PR makes `simp` consult its own cache more often, to avoid replicating work. Before, the simp cache was checked upon entry of `simpImpl` only, which then calls `simpLoop`, which recursively iterates the `pre`-lemmas, without checking the cache again. Now, `simpLoop` itself checks the cache. This seems more principled, given that `simpLoop` is actually putting entries into the cache for each of its calls, so it’s more uniform if it checks the cache itself. This avoids repeated rewrites. For example given ``` theorem ab : a = b := testSorry theorem bc : b = c := testSorry example (h : P c) : P b ∧ P a := by simp [ab, bc, h] ``` simp would rewrite `b ==> c` twice (once as part of `b ==> c` and then again as part of `a ==> b ==> c`). And it’d be order dependent: With ``` example (h : P c) : P a ∧ P b := by simp [ab, bc, h] ``` the `a ==> b ==> c` chain would insert `b ==> c` into the cache, and picked up by `simpImpl` when rewriting `P b`. With this change, `b ==> c` is performed only once in both examples. Instruction counts on stdlib and mathlib both show a mild improvement across the board (0.5%), with individual modules improving by up to 4% in stdlib and even more in mathlib. (This does not check the cache before applying `post`, which explains where there are still some repeated rewrites in the trace logs. But I’m less sure about inserting a cache check here and so I am treading carefully here. It’s also going to be at most one `post` application that’s duplicated, because if `post` returns `.visit`, we go back to `pre` and thus a cache check.)
33 lines
1.1 KiB
Text
33 lines
1.1 KiB
Text
def ack : Nat → Nat → Nat
|
|
| 0, y => y+1
|
|
| x+1, 0 => ack x 1
|
|
| x+1, y+1 => ack x (ack (x+1) y)
|
|
termination_by a b => (a, b)
|
|
|
|
/--
|
|
trace: [diag] Diagnostics
|
|
[kernel] unfolded declarations (max: 147, num: 3):
|
|
[kernel] OfNat.ofNat ↦ 147
|
|
[kernel] Add.add ↦ 61
|
|
[kernel] HAdd.hAdd ↦ 61
|
|
use `set_option diagnostics.threshold <num>` to control threshold for reporting counters
|
|
---
|
|
trace: [simp] Diagnostics
|
|
[simp] used theorems (max: 57, num: 1):
|
|
[simp] ack.eq_3 ↦ 57
|
|
[simp] tried theorems (max: 57, num: 1):
|
|
[simp] ack.eq_3 ↦ 57, succeeded: 57
|
|
use `set_option diagnostics.threshold <num>` to control threshold for reporting counters
|
|
---
|
|
trace: [diag] Diagnostics
|
|
[kernel] unfolded declarations (max: 147, num: 3):
|
|
[kernel] OfNat.ofNat ↦ 147
|
|
[kernel] Add.add ↦ 61
|
|
[kernel] HAdd.hAdd ↦ 61
|
|
use `set_option diagnostics.threshold <num>` to control threshold for reporting counters
|
|
-/
|
|
#guard_msgs in
|
|
set_option diagnostics.threshold 50 in
|
|
set_option diagnostics true in
|
|
theorem ex : ack 3 2 = 29 :=
|
|
by simp [ack]
|