Zulip Chat Archive
Stream: new members
Topic: partial fun eq equivalent total one.
Somo S. (Sep 06 2025 at 08:14):
Is it possible to prove that a partial function is identical to a version of it that has been proven to be total assuming a what is necessary for termination is available as an additional assumed precondition? Here is the example I have been working with as I have been wondering about this. (It seems to me the following should be provable somehow, but I can't seem to think of how):
variable {α : Type u}
def Array.findIdxRev.loop (p : α → Bool) (as : Array α)
(j : Fin as.size) (h : ∃ (j' : Fin as.size), j' ≤ j.val ∧ p as[j']) : Fin as.size :=
if _ : p as[j] then
j
else
Array.findIdxRev.loop p as ⟨j - 1, by grind [Nat.pred_le]⟩ (by grind)
termination_by j.val
decreasing_by grind
partial def Array.findIdxRev.loop! (p : α → Bool) (as : Array α)
(j : Fin as.size) : Fin as.size :=
if _ : p as[j] then
j
else
Array.findIdxRev.loop! p as ⟨j - 1, by grind [Nat.pred_le]⟩
theorem Array.findIdxRev.loop_part_eq_tot {p : α → Bool} {as : Array α}
{j : Fin as.size} (h : ∃ (j' : Fin as.size), j' ≤ j.val ∧ p as[j']) :
Array.findIdxRev.loop! p as j = Array.findIdxRev.loop p as j h := by
sorry
Robin Arnez (Sep 06 2025 at 08:40):
Not with a partial one, but a partial_fixpoint one:
variable {α : Type u}
def Array.findIdxRev.loop (p : α → Bool) (as : Array α)
(j : Fin as.size) (h : ∃ (j' : Fin as.size), j' ≤ j.val ∧ p as[j']) : Fin as.size :=
if _ : p as[j] then
j
else
Array.findIdxRev.loop p as ⟨j - 1, by grind [Nat.pred_le]⟩ (by grind)
termination_by j.val
decreasing_by grind
def Array.findIdxRev.loop! (p : α → Bool) (as : Array α)
(j : Fin as.size) : Fin as.size :=
if _ : p as[j] then
j
else
Array.findIdxRev.loop! p as ⟨j - 1, by grind [Nat.pred_le]⟩
partial_fixpoint
theorem Array.findIdxRev.loop_part_eq_tot {p : α → Bool} {as : Array α}
{j : Fin as.size} (h : ∃ (j' : Fin as.size), j' ≤ j.val ∧ p as[j']) :
Array.findIdxRev.loop! p as j = Array.findIdxRev.loop p as j h := by
fun_induction Array.findIdxRev.loop <;> rw [Array.findIdxRev.loop!] <;>
simp only [*, ↓reduceDIte, Bool.false_eq_true]
Robin Arnez (Sep 06 2025 at 08:40):
partial is completely opaque
Somo S. (Sep 21 2025 at 17:23):
Thanks @Robin Arnez I had no idea about this. This was helpful
Last updated: Dec 20 2025 at 21:32 UTC