Zulip Chat Archive
Stream: general
Topic: proving termination
Alexandre Rademaker (Aug 29 2024 at 00:34):
any idea about how to prove termination of
def perm₂ : List a → List (List a)
| [] => [[]]
| xs => concatMap (λ p => (perm₂ p.2).map (p.1 :: ·)) (picks xs)
termination_by xs => xs.length
any good documentation about it?
Kim Morrison (Aug 29 2024 at 02:12):
#mwe, please! :-)
Alexandre Rademaker (Aug 29 2024 at 02:22):
Sorry, let me give the remain functions:
def concat1 {a : Type} : List (List a) → List a :=
List.foldr List.append []
def concatMap (f : a → List b) : List a → List b := concat1 ∘ (List.map f)
def picks {a : Type} : List a → List (a × List a)
| [] => []
| (x :: xs) =>
(x, xs) :: ((picks xs).map (λ p => (p.1, x :: p.2)))
def perm : List a → List (List a)
| [] => [[]]
| xs => concatMap (λ p => (perm p.2).map (p.1 :: ·)) (picks xs)
termination_by xs => xs.length
The function picks picks an arbitrary element from a list in all possible ways, returning both the element and what remains. The function perm computes a permutation by picking an arbitrary element of a nonempty list as a first element, and following it with a permutation of the rest of the list.
Daniel Weber (Aug 29 2024 at 02:24):
concatMap
is docs#List.bind, you'll probably have an easier time using it due to existing API (And concat1
is docs#List.join)
Daniel Weber (Aug 29 2024 at 02:31):
To show termination what you can do is map on (picks ps).attach
and prove that all elements of picks ps
are shorter
Alexandre Rademaker (Aug 29 2024 at 02:37):
Can you elaborate on the last step? "map on (picks ps).attach
and prove that all elements of picks ps
are shorter?
Daniel Weber (Aug 29 2024 at 02:42):
You can do something like this
theorem length_lt_of_mem_picks_con {a : Type} (v : a) (l : List a) (l' : a × List a) (h : l' ∈ picks (v :: l)) :
l'.2.length < (v :: l).length := by
sorry
def perm : List a → List (List a)
| [] => [[]]
| x :: xs => concatMap (fun ⟨p, hp⟩ ↦
have : p.2.length < (x :: xs).length := length_lt_of_mem_picks_con x xs p hp
(perm p.2).map (p.1 :: ·))
(picks (x :: xs)).attach
termination_by xs => xs.length
Alexandre Rademaker (Aug 29 2024 at 02:45):
Thank you, testing now. Regarding the concatMap
and concat1
the idea is to show the students how foldr
can be useful.
Alexandre Rademaker (Aug 29 2024 at 03:10):
Hum, length_lt_of_mem_picks_con
is not easy to prove...
Alexandre Rademaker (Aug 29 2024 at 03:40):
Is attach something new? It is working in the https://live.lean-lang.org/ but not on my local machine... I am using 4.10.0
Kim Morrison (Aug 29 2024 at 03:43):
You would need import Batteries
on v4.10.0
.
Alexandre Rademaker (Aug 29 2024 at 03:58):
Maybe it can be easier to upgrade to v4.11-rc2 ... can I just edit the lean-toolchain
? Is there a safer way to upgrade? Sorry... maybe out of the topic.
Kim Morrison (Aug 29 2024 at 04:00):
Yes, just put leanprover/lean4:v4.11.0-rc2
into your lean-toolchain
. If you have dependencies you may need to run lake update
as well. (And if you've pinned your dependencies, move them to a commit that is also using v4.11.0-rc2
.)
Alexandre Rademaker (Aug 29 2024 at 04:09):
Thank you! Nice, now back to the prove of the auxiliary theorem length_lt_of_mem_picks_con
. I am half way to prove it using induction on the l
. But I didn't understand the have : p.2.length < (x :: xs).length := ...
inside the lambda function.. I mean, the presence of this anonymous proposition in the beginning of the lambda body is something automatically used by Lean to check termination?
Andrés Goens (Aug 29 2024 at 05:14):
Alexandre Rademaker said:
I mean, the presence of this anonymous proposition in the beginning of the lambda body is something automatically used by Lean to check termination?
short answer: yes! Lean uses a default tactic to prove termination, and if it fails, it'll tell you what it's proof obligation was that it couldn't prove. If you add that obligation with a have
to the environment, the default tactic for termination will prove the rest for you
Andrés Goens (Aug 29 2024 at 05:15):
(you can remove the have
and look at the error message you get)
Andrés Goens (Aug 29 2024 at 05:21):
there's more details in TPIL: https://leanprover.github.io/theorem_proving_in_lean4/induction_and_recursion.html#well-founded-recursion-and-induction
Alexandre Rademaker (Aug 29 2024 at 10:30):
Thank you
Last updated: May 02 2025 at 03:31 UTC