Zulip Chat Archive
Stream: new members
Topic: Termination of a sorting function
Sílvio Zacomelli (Nov 15 2024 at 16:09):
Hello. As the title states, I have this sort function:
mutual
def qsort [LE α] [DecidableEq α] [DecidableRel (@LE.le α _)] (y : List α) : List α :=
if h₁ : y = [] then []
else
let x::xs := y
help x xs [] []
termination_by y
def help (x : α) (ys us vs: List α) [LE α] [DecidableEq α] [DecidableRel (@LE.le α _)] : List α:=
if h₂ : ys = [] then
(qsort us) ++ [x] ++ (qsort vs)
else
let y::xs := ys
if h₃ : x ≤ y then
help x xs us (y::vs)
else
help x xs (y::us) vs
termination_by ys
end
As you can tell by the code, Lean fails in proving it's termination. Indeed, I had tried to prove it using the length of the lists before figuring out that (obviously) the length of y doesn't change (it's a sort function). Then, I've tried the approach of using a new parameter to track the "number of unsorted elements" of the list. This idea is shown in the code below:
mutual
def qsort₁ [LE α] [DecidableEq α] [DecidableRel (@LE.le α _)] (n : Nat) (y : List α) : List α :=
if h₁ : n = 0 then y else
if h₂ : y.length = 0 then []
else
let x::xs := y
help₁ n x xs [] []
termination_by n
def help₁ (t : Nat) (x : α) (ys us vs: List α) [LE α] [DecidableEq α] [DecidableRel (@LE.le α _)] : List α:=
if h₃ : t = 0 then x::ys else
if h₄ : ys = [] then
(qsort₁ (t - 1 - vs.length) us) ++ [x] ++ (qsort₁ (t- 1 - us.length) vs)
else
let y::xs := ys
if h₅ : x ≤ y then
help₁ t x xs us (y::vs)
else
help₁ t x xs (y::us) vs
termination_by t
end
But I haven't had any luck with it either. In both cases, Lean asks me to make impossible proofs. How do I prove this termination?
Last updated: May 02 2025 at 03:31 UTC