This is part of #3983. Fine-grained equational lemmas are useful even for non-recursive functions, so this adds them. The new option `eqns.nonrecursive` can be set to `false` to have the old behavior. ### Breaking channge This is a breaking change: Previously, `rw [Option.map]` would rewrite `Option.map f o` to `match o with … `. Now this rewrite will fail because the equational lemmas require constructors here (like they do for, say, `List.map`). Remedies: * Split on `o` before rewriting. * Use `rw [Option.map.eq_def]`, which rewrites any (saturated) application of `Option.map` * Use `set_option eqns.nonrecursive false` when *defining* the function in question. ### Interaction with simp The `simp` tactic so far had a special provision for non-recursive functions so that `simp [f]` will try to use the equational lemmas, but will also unfold `f` else, so less breakage here (but maybe performance improvements with functions with many cases when applied to a constructor, as the simplifier will no longer unfold to a large `match`-statement and then collapse it right away). For projection functions and functions marked `[reducible]`, `simp [f]` won’t use the equational theorems, and will only use its internal unfolding machinery. ### Implementation notes It uses the same `mkEqnTypes` function as for recursive functions, so we are close to a consistency here. There is still the wrinkle that for recursive functions we don't split matches without an interesting recursive call inside. Unifying that is future work.
55 lines
951 B
Text
55 lines
951 B
Text
/-! Tests that options affecting equational theorems work as expected. -/
|
|
|
|
namespace Test1
|
|
def nonrecfun : Bool → Nat
|
|
| false => 0
|
|
| true => 0
|
|
|
|
/--
|
|
info: equations:
|
|
theorem Test1.nonrecfun.eq_1 : nonrecfun false = 0
|
|
theorem Test1.nonrecfun.eq_2 : nonrecfun true = 0
|
|
-/
|
|
#guard_msgs in
|
|
#print equations nonrecfun
|
|
|
|
end Test1
|
|
|
|
namespace Test2
|
|
|
|
set_option eqns.nonrecursive false in
|
|
def nonrecfun : Bool → Nat
|
|
| false => 0
|
|
| true => 0
|
|
|
|
/--
|
|
info: equations:
|
|
theorem Test2.nonrecfun.eq_def : ∀ (x : Bool),
|
|
nonrecfun x =
|
|
match x with
|
|
| false => 0
|
|
| true => 0
|
|
-/
|
|
#guard_msgs in
|
|
#print equations nonrecfun
|
|
|
|
end Test2
|
|
|
|
namespace Test3
|
|
|
|
def nonrecfun : Bool → Nat
|
|
| false => 0
|
|
| true => 0
|
|
|
|
-- should have no effect
|
|
set_option eqns.nonrecursive false
|
|
|
|
/--
|
|
info: equations:
|
|
theorem Test3.nonrecfun.eq_1 : nonrecfun false = 0
|
|
theorem Test3.nonrecfun.eq_2 : nonrecfun true = 0
|
|
-/
|
|
#guard_msgs in
|
|
#print equations nonrecfun
|
|
|
|
end Test3
|