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
93 lines
1.9 KiB
Text
93 lines
1.9 KiB
Text
namespace Ex1
|
||
mutual
|
||
def f : Nat → α → α → α
|
||
| 0, a, b => a
|
||
| n, a, b => g a n b |>.1
|
||
termination_by n _ _ => (n, 2)
|
||
decreasing_by
|
||
apply Prod.Lex.right
|
||
decide
|
||
|
||
def g : α → Nat → α → (α × α)
|
||
| a, 0, b => (a, b)
|
||
| a, n, b => (h a b n, a)
|
||
termination_by _ n _ => (n, 1)
|
||
decreasing_by
|
||
apply Prod.Lex.right
|
||
decide
|
||
|
||
def h : α → α → Nat → α
|
||
| _a, b, 0 => b
|
||
| a, b, n+1 => f n a b
|
||
termination_by _ _ n => (n, 0)
|
||
decreasing_by
|
||
apply Prod.Lex.left
|
||
apply Nat.lt_succ_self
|
||
end
|
||
|
||
#guard f 5 'a' 'b' = 'a'
|
||
|
||
/--
|
||
info: @[irreducible] def Ex1.f.{u_1} : {α : Type u_1} → Nat → α → α → α :=
|
||
fun {α} a a_1 a_2 => f._mutual (PSum.inl ⟨a, ⟨a_1, a_2⟩⟩)
|
||
-/
|
||
#guard_msgs in
|
||
#print f
|
||
|
||
/--
|
||
info: @[irreducible] def Ex1.g.{u_1} : {α : Type u_1} → α → Nat → α → α × α :=
|
||
fun {α} a a_1 a_2 => f._mutual (PSum.inr (PSum.inl ⟨a, ⟨a_1, a_2⟩⟩))
|
||
-/
|
||
#guard_msgs in
|
||
#print g
|
||
|
||
/--
|
||
info: @[irreducible] def Ex1.h.{u_1} : {α : Type u_1} → α → α → Nat → α :=
|
||
fun {α} a a_1 a_2 => f._mutual (PSum.inr (PSum.inr ⟨a, ⟨a_1, a_2⟩⟩))
|
||
-/
|
||
#guard_msgs in
|
||
#print h
|
||
|
||
#print f._mutual
|
||
end Ex1
|
||
|
||
namespace Ex2
|
||
mutual
|
||
def f : Nat → α → α → α
|
||
| 0, a, b => a
|
||
| n, a, b => g a n b |>.1
|
||
termination_by n _ _ => (n, 2)
|
||
|
||
def g : α → Nat → α → (α × α)
|
||
| a, 0, b => (a, b)
|
||
| a, n, b => (h a b n, a)
|
||
termination_by _ n _ => (n, 1)
|
||
|
||
def h : α → α → Nat → α
|
||
| a, b, 0 => b
|
||
| a, b, n+1 => f n a b
|
||
termination_by _ _ n => (n, 0)
|
||
end
|
||
|
||
#print f._mutual
|
||
|
||
end Ex2
|
||
|
||
namespace Ex3
|
||
mutual
|
||
def f : Nat → α → α → α
|
||
| 0, a, b => a
|
||
| n, a, b => g a n b |>.1
|
||
|
||
def g : α → Nat → α → (α × α)
|
||
| a, 0, b => (a, b)
|
||
| a, n, b => (h a b n, a)
|
||
|
||
def h : α → α → Nat → α
|
||
| a, b, 0 => b
|
||
| a, b, n+1 => f n a b
|
||
end
|
||
|
||
#print f._mutual
|
||
|
||
end Ex3
|