Recursive predefinitions contains “rec app” markers as mdata in the predefinitions, but sometimes these get in the way of termination checking, when you have ``` [mdata (fun x => f)] arg ``` Therefore, the `preprocess` pass floats them out of applications (originally only for structural recursion, since #2818 also for well-founded recursion). But the code was incomplete: Because `Meta.transform` calls `post` on `f x y` only once (and not also on `f x`) one has to float out of nested applications as well. A consequence of this can be that in a recursive proof, `rw [foo]` does not work although `rw [foo _ _]` does. Also adding the testcase where @david-christiansen and I stumbled over this (Maybe the two preprocess modules can be combined, now that #2973 is landed, will try that in a follow-up).
17 lines
532 B
Text
17 lines
532 B
Text
def zero_out (arr : Array Nat) (i : Nat) : Array Nat :=
|
|
if h : i < arr.size then
|
|
zero_out (arr.set ⟨i, h⟩ 0) (i + 1)
|
|
else
|
|
arr
|
|
termination_by arr.size - i
|
|
decreasing_by simp_wf; apply Nat.sub_succ_lt_self _ _ h
|
|
|
|
-- set_option trace.Elab.definition true
|
|
theorem size_zero_out (arr : Array Nat) (i : Nat) : (zero_out arr i).size = arr.size := by
|
|
unfold zero_out
|
|
split
|
|
· rw [size_zero_out]
|
|
rw [Array.size_set]
|
|
· rfl
|
|
termination_by arr.size - i
|
|
decreasing_by simp_wf; apply Nat.sub_succ_lt_self; assumption
|