-- Frap/Sort.lean

inductive Permutation {α : Type} : List α → List α → Prop :=
  | perm_nil : Permutation [] []
  | perm_skip x l l'
      : Permutation l l' → Permutation (x::l) (x::l')
  | perm_swap x y l : Permutation (y::x::l) (x::y::l)
  | perm_trans l l' l''
      : Permutation l l' → Permutation l' l''
        → Permutation l l''

open Permutation

-- Repository definitions used:
content: ...

-- Repository lemmas used:
content: theorem append_assoc (as bs cs : List α)
        : (as ++ bs) ++ cs = as ++ (bs ++ cs)

-- Local definitions used:
content: inductive Permutation {α : Type} : List α → List α → Prop :=
  | perm_nil : Permutation [] []
  | perm_skip x l l'
      : Permutation l l' → Permutation (x::l) (x::l')
  | perm_swap x y l : Permutation (y::x::l) (x::y::l)
  | perm_trans l l' l''
      : Permutation l l' → Permutation l' l''
        → Permutation l l''

-- Local lemmas used:
content: theorem permutation_refl (l : List α) : Permutation l l

content: theorem permutation_symm (l l' : List α)
    : Permutation l l' → Permutation l' l

content: theorem permutation_app_head (l tl tl' : List α)
    : Permutation tl tl' → Permutation (l++tl) (l++tl')

content: theorem permutation_cons_append (l : List α) x
    : Permutation (x :: l) (l ++ [x])

-- Target theorem and proof:
theorem permutation_cons_app (l l₁ l₂ : List α)
    : Permutation l (l₁ ++ l₂)
      → Permutation (a :: l) (l₁ ++ a :: l₂)
:= by
  intro h
  -- a :: l
  -- a :: (l₁ ++ l₂)
  -- l₁ ++ l₂ ++ [a]
  -- l₁ ++ (l₂ ++ [a])
  -- l₁ ++ a :: l₂
  apply perm_trans
  . apply perm_skip; exact h
  . apply perm_trans
    . apply permutation_cons_append
    . rw [List.append_assoc]
      apply permutation_app_head
      apply permutation_symm
      apply permutation_cons_append