Previously, the tactic state shown at `decreasing_by` would leak lots of details about the translation, and mention `invImage`, `PSigma` etc. This is not nice. So this introduces `clean_wf`, which is like `simp_wf` but using `simp`'s `only` mode, and runs this unconditionally. This should clean up the goal to a reasonable extent. Previously `simp_wf` was an unrestricted `simp […]` call, but we probably don’t want arbitrary simplification to happen at this point, so this now became `simp only` call. For backwards compatibility, `decreasing_with` begins with `try simp`. The `simp_wf` tactic is still available to not break too much existing code; it’s docstring suggests to no longer use it. With `set_option cleanDecreasingByGoal false` one can disable the use of `clean_wf`. I hope this is only needed for debugging and understanding. Migration advise: If your `decreasing_by` proof begins with `simp_wf`, either remove that (if the proof still goes through), or replace with `simp`. I am a bit anxious about running even `simp only` unconditionally here, as it may do more than some user might want, e.g. because of options like `zetaDelta := true`. We'll see if we need to reign in this tactic some more. I wonder if in corner cases the `simp_wf` tactic might be able to close the goal, and if that is a problem. If so, we may have to promote simp’s internal `mayCloseGoal` parameter to a simp configuration option and use that here. fixes #4928
41 lines
783 B
Text
41 lines
783 B
Text
namespace Ex1
|
|
mutual
|
|
def f : Nat → Bool → Nat
|
|
| n, true => 2 * f n false
|
|
| 0, false => 1
|
|
| n, false => n + g n
|
|
termination_by n b => (n, if b then 2 else 1)
|
|
decreasing_by
|
|
· apply Prod.Lex.right; decide
|
|
· apply Prod.Lex.right; decide
|
|
|
|
def g (n : Nat) : Nat :=
|
|
if h : n ≠ 0 then
|
|
f (n-1) true
|
|
else
|
|
n
|
|
termination_by (n, 0)
|
|
decreasing_by
|
|
apply Prod.Lex.left
|
|
apply Nat.pred_lt
|
|
done -- should fail
|
|
end
|
|
end Ex1
|
|
|
|
|
|
namespace Ex2
|
|
mutual
|
|
def f : Nat → Bool → Nat
|
|
| n, true => 2 * f n false
|
|
| 0, false => 1
|
|
| n, false => n + g (n+1) -- Error
|
|
termination_by n b => (n, if b then 2 else 1)
|
|
|
|
def g (n : Nat) : Nat :=
|
|
if h : n ≠ 0 then
|
|
f (n-1) true
|
|
else
|
|
n
|
|
termination_by (n, 0)
|
|
end
|
|
end Ex2
|