File: Mathlib/Data/List/Permutation.lean

full_name: List.permutationsAux2_fst
code: theorem permutationsAux2_fst (t : α) (ts : List α) (r : List β) :
    ∀ (ys : List α) (f : List α → β), (permutationsAux2 t ts r ys f).1 = ys ++ ts
  
goal: (List.permutationsAux2 t ts r ys f).1 = ys ++ ts

full_name: List.permutationsAux2_snd_nil
code: @[simp]
theorem permutationsAux2_snd_nil (t : α) (ts : List α) (r : List β) (f : List α → β) :
    (permutationsAux2 t ts r [] f).2 = r 
goal: (List.permutationsAux2 t ts r [] f).2 = r

full_name: List.permutationsAux2_snd_cons
code: @[simp]
theorem permutationsAux2_snd_cons (t : α) (ts : List α) (r : List β) (y : α) (ys : List α)
    (f : List α → β) :
    (permutationsAux2 t ts r (y :: ys) f).2 =
      f (t :: y :: ys ++ ts) :: (permutationsAux2 t ts r ys fun x : List α => f (y :: x)).2 
goal: (List.permutationsAux2 t ts r (y :: ys) f).2 =
  f (t :: y :: ys ++ ts) :: (List.permutationsAux2 t ts r ys fun x => f (y :: x)).2

full_name: List.permutationsAux2_append
code: /-- The `r` argument to `permutationsAux2` is the same as appending. -/
theorem permutationsAux2_append (t : α) (ts : List α) (r : List β) (ys : List α) (f : List α → β) :
    (permutationsAux2 t ts nil ys f).2 ++ r = (permutationsAux2 t ts r ys f).2 
goal: (List.permutationsAux2 t ts [] ys f).2 ++ r = (List.permutationsAux2 t ts r ys f).2

full_name: List.permutationsAux2_comp_append
code: /-- The `ts` argument to `permutationsAux2` can be folded into the `f` argument. -/
theorem permutationsAux2_comp_append {t : α} {ts ys : List α} {r : List β} (f : List α → β) :
    ((permutationsAux2 t [] r ys) fun x => f (x ++ ts)).2 = (permutationsAux2 t ts r ys f).2 
goal: (List.permutationsAux2 t [] r ys fun x => f (x ++ ts)).2 = (List.permutationsAux2 t ts r ys f).2

full_name: List.map_permutationsAux2'
code: theorem map_permutationsAux2' {α' β'} (g : α → α') (g' : β → β') (t : α) (ts ys : List α)
    (r : List β) (f : List α → β) (f' : List α' → β') (H : ∀ a, g' (f a) = f' (map g a)) :
    map g' (permutationsAux2 t ts r ys f).2 =
      (permutationsAux2 (g t) (map g ts) (map g' r) (map g ys) f').2 
goal: List.map g' (List.permutationsAux2 t ts r ys f).2 =
  (List.permutationsAux2 (g t) (List.map g ts) (List.map g' r) (List.map g ys) f').2

full_name: List.map_permutationsAux2
code: /-- The `f` argument to `permutationsAux2` when `r = []` can be eliminated. -/
theorem map_permutationsAux2 (t : α) (ts : List α) (ys : List α) (f : List α → β) :
    (permutationsAux2 t ts [] ys id).2.map f = (permutationsAux2 t ts [] ys f).2 
goal: List.map f (List.permutationsAux2 t ts [] ys id).2 = (List.permutationsAux2 t ts [] ys f).2

full_name: List.permutationsAux2_snd_eq
code: /-- An expository lemma to show how all of `ts`, `r`, and `f` can be eliminated from
`permutationsAux2`.

`(permutationsAux2 t [] [] ys id).2`, which appears on the RHS, is a list whose elements are
produced by inserting `t` into every non-terminal position of `ys` in order. As an example:
```lean
#eval permutationsAux2 1 [] [] [2, 3, 4] id
-- [[1, 2, 3, 4], [2, 1, 3, 4], [2, 3, 1, 4]]
```
-/
theorem permutationsAux2_snd_eq (t : α) (ts : List α) (r : List β) (ys : List α) (f : List α → β) :
    (permutationsAux2 t ts r ys f).2 =
      ((permutationsAux2 t [] [] ys id).2.map fun x => f (x ++ ts)) ++ r 
goal: (List.permutationsAux2 t ts r ys f).2 = List.map (fun x => f (x ++ ts)) (List.permutationsAux2 t [] [] ys id).2 ++ r

full_name: List.map_map_permutationsAux2
code: theorem map_map_permutationsAux2 {α'} (g : α → α') (t : α) (ts ys : List α) :
    map (map g) (permutationsAux2 t ts [] ys id).2 =
      (permutationsAux2 (g t) (map g ts) [] (map g ys) id).2 
goal: List.map (List.map g) (List.permutationsAux2 t ts [] ys id).2 =
  (List.permutationsAux2 (g t) (List.map g ts) [] (List.map g ys) id).2

full_name: List.map_map_permutations'Aux
code: theorem map_map_permutations'Aux (f : α → β) (t : α) (ts : List α) :
    map (map f) (permutations'Aux t ts) = permutations'Aux (f t) (map f ts) 
goal: List.map (List.map f) (List.permutations'Aux t ts) = List.permutations'Aux (f t) (List.map f ts)

full_name: List.permutations'Aux_eq_permutationsAux2
code: theorem permutations'Aux_eq_permutationsAux2 (t : α) (ts : List α) :
    permutations'Aux t ts = (permutationsAux2 t [] [ts ++ [t]] ts id).2 
goal: List.permutations'Aux t ts = (List.permutationsAux2 t [] [ts ++ [t]] ts id).2

full_name: List.mem_permutationsAux2
code: theorem mem_permutationsAux2 {t : α} {ts : List α} {ys : List α} {l l' : List α} :
    l' ∈ (permutationsAux2 t ts [] ys (l ++ ·)).2 ↔
      ∃ l₁ l₂, l₂ ≠ [] ∧ ys = l₁ ++ l₂ ∧ l' = l ++ l₁ ++ t :: l₂ ++ ts 
goal: l' ∈ (List.permutationsAux2 t ts [] ys fun x => l ++ x).2 ↔
  ∃ l₁ l₂, l₂ ≠ [] ∧ ys = l₁ ++ l₂ ∧ l' = l ++ l₁ ++ t :: l₂ ++ ts

full_name: List.mem_permutationsAux2'
code: theorem mem_permutationsAux2' {t : α} {ts : List α} {ys : List α} {l : List α} :
    l ∈ (permutationsAux2 t ts [] ys id).2 ↔
      ∃ l₁ l₂, l₂ ≠ [] ∧ ys = l₁ ++ l₂ ∧ l = l₁ ++ t :: l₂ ++ ts 
goal: l ∈ (List.permutationsAux2 t ts [] ys id).2 ↔ ∃ l₁ l₂, l₂ ≠ [] ∧ ys = l₁ ++ l₂ ∧ l = l₁ ++ t :: l₂ ++ ts

full_name: List.length_permutationsAux2
code: theorem length_permutationsAux2 (t : α) (ts : List α) (ys : List α) (f : List α → β) :
    length (permutationsAux2 t ts [] ys f).2 = length ys 
goal: (List.permutationsAux2 t ts [] ys f).2.length = ys.length

full_name: List.foldr_permutationsAux2
code: theorem foldr_permutationsAux2 (t : α) (ts : List α) (r L : List (List α)) :
    foldr (fun y r => (permutationsAux2 t ts r y id).2) r L =
      (L.bind fun y => (permutationsAux2 t ts [] y id).2) ++ r 
goal: List.foldr (fun y r => (List.permutationsAux2 t ts r y id).2) r L =
  (L.bind fun y => (List.permutationsAux2 t ts [] y id).2) ++ r

full_name: List.mem_foldr_permutationsAux2
code: theorem mem_foldr_permutationsAux2 {t : α} {ts : List α} {r L : List (List α)} {l' : List α} :
    l' ∈ foldr (fun y r => (permutationsAux2 t ts r y id).2) r L ↔
      l' ∈ r ∨ ∃ l₁ l₂, l₁ ++ l₂ ∈ L ∧ l₂ ≠ [] ∧ l' = l₁ ++ t :: l₂ ++ ts 
goal: l' ∈ List.foldr (fun y r => (List.permutationsAux2 t ts r y id).2) r L ↔
  l' ∈ r ∨ ∃ l₁ l₂, l₁ ++ l₂ ∈ L ∧ l₂ ≠ [] ∧ l' = l₁ ++ t :: l₂ ++ ts

full_name: List.length_foldr_permutationsAux2
code: theorem length_foldr_permutationsAux2 (t : α) (ts : List α) (r L : List (List α)) :
    length (foldr (fun y r => (permutationsAux2 t ts r y id).2) r L) =
      Nat.sum (map length L) + length r 
goal: (List.foldr (fun y r => (List.permutationsAux2 t ts r y id).2) r L).length = Nat.sum (List.map List.length L) + r.length

full_name: List.length_foldr_permutationsAux2'
code: theorem length_foldr_permutationsAux2' (t : α) (ts : List α) (r L : List (List α)) (n)
    (H : ∀ l ∈ L, length l = n) :
    length (foldr (fun y r => (permutationsAux2 t ts r y id).2) r L) = n * length L + length r 
goal: (List.foldr (fun y r => (List.permutationsAux2 t ts r y id).2) r L).length = n * L.length + r.length

full_name: List.permutationsAux_nil
code: @[simp]
theorem permutationsAux_nil (is : List α) : permutationsAux [] is = [] 
goal: [].permutationsAux is = []

full_name: List.permutationsAux_cons
code: @[simp]
theorem permutationsAux_cons (t : α) (ts is : List α) :
    permutationsAux (t :: ts) is =
      foldr (fun y r => (permutationsAux2 t ts r y id).2) (permutationsAux ts (t :: is))
        (permutations is) 
goal: (t :: ts).permutationsAux is =
  List.foldr (fun y r => (List.permutationsAux2 t ts r y id).2) (ts.permutationsAux (t :: is)) is.permutations

full_name: List.permutations_nil
code: @[simp]
theorem permutations_nil : permutations ([] : List α) = [[]] 
goal: [].permutations = [[]]

full_name: List.map_permutationsAux
code: theorem map_permutationsAux (f : α → β) :
    ∀ ts is :
    List α, map (map f) (permutationsAux ts is) = permutationsAux (map f ts) (map f is) 
goal: List.map (List.map f) (ts.permutationsAux is) = (List.map f ts).permutationsAux (List.map f is)

full_name: List.map_permutations
code: theorem map_permutations (f : α → β) (ts : List α) :
    map (map f) (permutations ts) = permutations (map f ts) 
goal: List.map (List.map f) ts.permutations = (List.map f ts).permutations

full_name: List.map_permutations'
code: theorem map_permutations' (f : α → β) (ts : List α) :
    map (map f) (permutations' ts) = permutations' (map f ts) 
goal: List.map (List.map f) ts.permutations' = (List.map f ts).permutations'

full_name: List.permutationsAux_append
code: theorem permutationsAux_append (is is' ts : List α) :
    permutationsAux (is ++ ts) is' =
      (permutationsAux is is').map (· ++ ts) ++ permutationsAux ts (is.reverse ++ is') 
goal: (is ++ ts).permutationsAux is' =
  List.map (fun x => x ++ ts) (is.permutationsAux is') ++ ts.permutationsAux (is.reverse ++ is')

full_name: List.permutations_append
code: theorem permutations_append (is ts : List α) :
    permutations (is ++ ts) = (permutations is).map (· ++ ts) ++ permutationsAux ts is.reverse 
goal: (is ++ ts).permutations = List.map (fun x => x ++ ts) is.permutations ++ ts.permutationsAux is.reverse