Zulip Chat Archive

Stream: new members

Topic: Need help proving termination!


Igor Shimanogov (Apr 22 2025 at 15:48):

Hey guys! Looking forward to help mathlib. For the firsts contribution I came up with idea of proving equalent condition of List commutativity (Lyndon-Schutzenberger lemma). Can some one help me to fancify my proof and prooving that recursion is terminating? Best regards!
https://gist.github.com/MrSumato/275a10e182044f915dea2e54cb879d8b

Johannes Tantow (Apr 22 2025 at 16:06):

I think you need to rewrite your proof as -- t is smaller then p! is not necessarily true. It should be possible that p, q and t are all empty and hence the theorem does not terminate.

Johannes Tantow (Apr 22 2025 at 16:07):

also #mwe . If you post your code directly here, then others only have to click the button and not have to copy to the live-lean.

Igor Shimanogov (Apr 22 2025 at 22:45):

Thx for the comments!
I managed to finish the proof and showed that it is terminating.

import Mathlib.Data.Prod.Basic
import Mathlib.Data.Nat.Init

universe u

variable {α : Type u} {v u w : List α} {n m : Nat}

def repeatList : Nat  List α  List α
  | Nat.zero, _ => []
  | Nat.succ p, l => l ++ repeatList p l

def repeat_list_homo : repeatList n w ++ repeatList m w = repeatList (n+m) w := by
  induction n with
  | zero => simp [repeatList]
  | succ p ih => simp [repeatList, List.append_assoc, ih, Nat.add_assoc, Nat.add_comm]

def prefix_if_concat_comm : (u ++ v = v ++ u)  (v <+: u  u <+: v) := by
  intro h
  rw [List.append_eq_append_iff] at h
  cases h with
  | inl r =>
    right
    obtain as, h₁, h₂ := r
    rw [h₁]
    exact List.prefix_append u as
  | inr l =>
    left
    obtain as, h₁, h₂ := l
    rw [h₁]
    exact List.prefix_append v as

theorem lyndon_schutzenberger {q p : List α} : (q ++ p = p ++ q)  ( w k l, q = repeatList k w  p = repeatList l w) := by
  constructor
  -- Forward direction (u++v=v++u → ∃w k l...)
  · intro h
    have pr := prefix_if_concat_comm h
    match p, q with
      | [], smth =>
        exists smth, 1, 0
        constructor
        simp [repeatList]
        simp [repeatList]
      | smth, [] =>
        exists smth, 0, 1
      | hp :: tp, hq :: tq =>
        cases pr with
        | inr qp =>
          cases qp with
          | intro t ht =>
            rw [ ht]
            rw [ ht, List.append_assoc, List.append_cancel_left_eq] at h
            have bb := lyndon_schutzenberger.mp h
            cases bb with | intro wc wct =>
            cases wct with | intro kc kct =>
            cases kct with | intro lc lct =>
            cases lct with
            | intro left right =>
              exists wc, kc, (kc+lc)
              constructor
              assumption
              simp [left, right, repeat_list_homo]
        | inl pq =>
          cases pq with
            | intro t ht =>
              rw [ ht]
              rw [ ht, List.append_assoc, List.append_cancel_left_eq] at h
              have bb := lyndon_schutzenberger.mp h.symm
              cases bb with | intro wc wct =>
              cases wct with | intro kc kct =>
              cases kct with | intro lc lct =>
              cases lct with
              | intro left right =>
                exists wc, (kc+lc), kc
                constructor
                simp [left, right, repeat_list_homo]
                assumption

  -- Reverse direction (∃w k l... → u++v=v++u)
  · rintro w, k, l, rfl, rfl
    simp [repeat_list_homo, Nat.add_comm]

termination_by (p++q).length
decreasing_by

  have n : (hp :: tp).length + t.length = (hq :: tq).length := by
      rw [ List.length_append]
      exact congrArg List.length ht
  rw [List.length_append, Nat.add_comm, n, List.length_append, List.length_cons]
  simp

  have n : (hq :: tq).length + t.length = (hp :: tp).length := by
     rw [ List.length_append]
     exact congrArg List.length ht
  rw [List.length_append, Nat.add_comm, n, List.length_append, List.length_cons]
  simp

So I have some followup questions. Is it enough for the first contribution? What part of Mathlib it belongs to? How I can made this proof cleaner or shorter?


Last updated: May 02 2025 at 03:31 UTC