l3lab/ntp-mathlib huggingface dataset:
theorem nodup_sublistsLen (n : ℕ) {l : List α} (h : Nodup l) : (sublistsLen n l).Nodup := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
n : ℕ
l : List α
h : Nodup l
⊢ Nodup (sublistsLen n l)

Next tactic:
have : Pairwise (· ≠ ·) l.sublists' := Pairwise.imp
    (fun h => Lex.to_ne (by convert h using 3; simp [swap, eq_comm])) h.sublists'
theorem nodup_sublistsLen (n : ℕ) {l : List α} (h : Nodup l) : (sublistsLen n l).Nodup := by
  have : Pairwise (· ≠ ·) l.sublists' := Pairwise.imp
    (fun h => Lex.to_ne (by 

Proof state:
α : Type u
β : Type v
γ : Type w
n : ℕ
l : List α
h✝ : Nodup l
a✝ b✝ : List α
h : Lex (swap fun x x_1 => x ≠ x_1) a✝ b✝
⊢ Lex (fun x x_1 => x ≠ x_1) a✝ b✝

Next tactic:
convert h using 3
theorem nodup_sublistsLen (n : ℕ) {l : List α} (h : Nodup l) : (sublistsLen n l).Nodup := by
  have : Pairwise (· ≠ ·) l.sublists' := Pairwise.imp
    (fun h => Lex.to_ne (by convert h using 3; 

Proof state:
case h.e'_2.h.e'_4.h.h
α : Type u
β : Type v
γ : Type w
n : ℕ
l : List α
h✝ : Nodup l
a✝ b✝ : List α
h : Lex (swap fun x x_1 => x ≠ x_1) a✝ b✝
x✝ : α
⊢ (fun x => ¬x = x✝) = fun x => x✝ ≠ x

Next tactic:
simp [swap, eq_comm]
theorem nodup_sublistsLen (n : ℕ) {l : List α} (h : Nodup l) : (sublistsLen n l).Nodup := by
  have : Pairwise (· ≠ ·) l.sublists' := Pairwise.imp
    (fun h => Lex.to_ne (by convert h using 3; simp [swap, eq_comm])) h.sublists'
  

Proof state:
α : Type u
β : Type v
γ : Type w
n : ℕ
l : List α
h : Nodup l
this : Pairwise (fun x x_1 => x ≠ x_1) (sublists' l)
⊢ Nodup (sublistsLen n l)

Next tactic:
exact this.sublist (sublistsLen_sublist_sublists' _ _)
theorem sublists_map (f : α → β) : ∀ (l : List α),
    sublists (map f l) = map (map f) (sublists l)
  | [] => by 

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
⊢ sublists (map f []) = map (map f) (sublists [])

Next tactic:
simp
theorem sublists_map (f : α → β) : ∀ (l : List α),
    sublists (map f l) = map (map f) (sublists l)
  | [] => by simp
  | a::l => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
l : List α
⊢ sublists (map f (a :: l)) = map (map f) (sublists (a :: l))

Next tactic:
rw [map_cons, sublists_cons, bind_eq_bind, sublists_map f l, sublists_cons,
      bind_eq_bind, map_eq_bind, map_eq_bind]
theorem sublists_map (f : α → β) : ∀ (l : List α),
    sublists (map f l) = map (map f) (sublists l)
  | [] => by simp
  | a::l => by
    rw [map_cons, sublists_cons, bind_eq_bind, sublists_map f l, sublists_cons,
      bind_eq_bind, map_eq_bind, map_eq_bind]
    

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
l : List α
⊢ (List.bind (List.bind (sublists l) fun x => [map f x]) fun x => [x, f a :: x]) =
    List.bind (List.bind (sublists l) fun x => [x, a :: x]) fun x => [map f x]

Next tactic:
induction sublists l
theorem sublists_map (f : α → β) : ∀ (l : List α),
    sublists (map f l) = map (map f) (sublists l)
  | [] => by simp
  | a::l => by
    rw [map_cons, sublists_cons, bind_eq_bind, sublists_map f l, sublists_cons,
      bind_eq_bind, map_eq_bind, map_eq_bind]
    induction sublists l <;> 

Proof state:
case nil
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
l : List α
⊢ (List.bind (List.bind [] fun x => [map f x]) fun x => [x, f a :: x]) =
    List.bind (List.bind [] fun x => [x, a :: x]) fun x => [map f x]

Next tactic:
simp [*]
theorem sublists_map (f : α → β) : ∀ (l : List α),
    sublists (map f l) = map (map f) (sublists l)
  | [] => by simp
  | a::l => by
    rw [map_cons, sublists_cons, bind_eq_bind, sublists_map f l, sublists_cons,
      bind_eq_bind, map_eq_bind, map_eq_bind]
    induction sublists l <;> 

Proof state:
case cons
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
l head✝ : List α
tail✝ : List (List α)
tail_ih✝ :
  (List.bind (List.bind tail✝ fun x => [map f x]) fun x => [x, f a :: x]) =
    List.bind (List.bind tail✝ fun x => [x, a :: x]) fun x => [map f x]
⊢ (List.bind (List.bind (head✝ :: tail✝) fun x => [map f x]) fun x => [x, f a :: x]) =
    List.bind (List.bind (head✝ :: tail✝) fun x => [x, a :: x]) fun x => [map f x]

Next tactic:
simp [*]
theorem sublists'_map (f : α → β) : ∀ (l : List α),
    sublists' (map f l) = map (map f) (sublists' l)
  | [] => by 

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
⊢ sublists' (map f []) = map (map f) (sublists' [])

Next tactic:
simp
theorem sublists'_map (f : α → β) : ∀ (l : List α),
    sublists' (map f l) = map (map f) (sublists' l)
  | [] => by simp
  | a::l => by 

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
l : List α
⊢ sublists' (map f (a :: l)) = map (map f) (sublists' (a :: l))

Next tactic:
simp [map_cons, sublists'_cons, sublists'_map f l, Function.comp]
theorem sublists_perm_sublists' (l : List α) : sublists l ~ sublists' l := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
l : List α
⊢ sublists l ~ sublists' l

Next tactic:
rw [← finRange_map_get l, sublists_map, sublists'_map]
theorem sublists_perm_sublists' (l : List α) : sublists l ~ sublists' l := by
  rw [← finRange_map_get l, sublists_map, sublists'_map]
  

Proof state:
α : Type u
β : Type v
γ : Type w
l : List α
⊢ map (map (get l)) (sublists (finRange (length l))) ~ map (map (get l)) (sublists' (finRange (length l)))

Next tactic:
apply Perm.map
theorem sublists_perm_sublists' (l : List α) : sublists l ~ sublists' l := by
  rw [← finRange_map_get l, sublists_map, sublists'_map]
  apply Perm.map
  

Proof state:
case p
α : Type u
β : Type v
γ : Type w
l : List α
⊢ sublists (finRange (length l)) ~ sublists' (finRange (length l))

Next tactic:
apply (perm_ext_iff_of_nodup _ _).mpr
theorem sublists_perm_sublists' (l : List α) : sublists l ~ sublists' l := by
  rw [← finRange_map_get l, sublists_map, sublists'_map]
  apply Perm.map
  apply (perm_ext_iff_of_nodup _ _).mpr
  · 

Proof state:
case p
α : Type u
β : Type v
γ : Type w
l : List α
⊢ ∀ (a : List (Fin (length l))), a ∈ sublists (finRange (length l)) ↔ a ∈ sublists' (finRange (length l))

Next tactic:
simp
theorem sublists_perm_sublists' (l : List α) : sublists l ~ sublists' l := by
  rw [← finRange_map_get l, sublists_map, sublists'_map]
  apply Perm.map
  apply (perm_ext_iff_of_nodup _ _).mpr
  · simp
  · 

Proof state:
α : Type u
β : Type v
γ : Type w
l : List α
⊢ Nodup (sublists (finRange (length l)))

Next tactic:
exact nodup_sublists.mpr (nodup_finRange _)
theorem sublists_perm_sublists' (l : List α) : sublists l ~ sublists' l := by
  rw [← finRange_map_get l, sublists_map, sublists'_map]
  apply Perm.map
  apply (perm_ext_iff_of_nodup _ _).mpr
  · simp
  · exact nodup_sublists.mpr (nodup_finRange _)
  · 

Proof state:
α : Type u
β : Type v
γ : Type w
l : List α
⊢ Nodup (sublists' (finRange (length l)))

Next tactic:
exact (nodup_sublists'.mpr (nodup_finRange _))
theorem sublists_cons_perm_append (a : α) (l : List α) :
    sublists (a :: l) ~ sublists l ++ map (cons a) (sublists l) :=
  Perm.trans (sublists_perm_sublists' _) <| by
  

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
l : List α
⊢ sublists' (a :: l) ~ sublists l ++ map (cons a) (sublists l)

Next tactic:
rw [sublists'_cons]
theorem sublists_cons_perm_append (a : α) (l : List α) :
    sublists (a :: l) ~ sublists l ++ map (cons a) (sublists l) :=
  Perm.trans (sublists_perm_sublists' _) <| by
  rw [sublists'_cons];
  

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
l : List α
⊢ sublists' l ++ map (cons a) (sublists' l) ~ sublists l ++ map (cons a) (sublists l)

Next tactic:
exact Perm.append (sublists_perm_sublists' _).symm (Perm.map _ (sublists_perm_sublists' _).symm)
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
l : List α
⊢ ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ revzip (sublists l) → l₁ ++ l₂ ~ l

Next tactic:
rw [revzip]
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  

Proof state:
α : Type u
β : Type v
γ : Type w
l : List α
⊢ ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists l) (reverse (sublists l)) → l₁ ++ l₂ ~ l

Next tactic:
induction' l using List.reverseRecOn with l' a ih
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l using List.reverseRecOn with l' a ih
  · 

Proof state:
case H0
α : Type u
β : Type v
γ : Type w
⊢ ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists []) (reverse (sublists [])) → l₁ ++ l₂ ~ []

Next tactic:
intro l₁ l₂ h
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l using List.reverseRecOn with l' a ih
  · intro l₁ l₂ h
    

Proof state:
case H0
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
h : (l₁, l₂) ∈ zip (sublists []) (reverse (sublists []))
⊢ l₁ ++ l₂ ~ []

Next tactic:
simp? at h says
      simp only [sublists_nil, reverse_cons, reverse_nil, nil_append, zip_cons_cons, zip_nil_right,
        mem_singleton, Prod.mk.injEq] at h
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l using List.reverseRecOn with l' a ih
  · intro l₁ l₂ h
    simp? at h says
      

Proof state:
case H0
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
h : (l₁, l₂) ∈ zip (sublists []) (reverse (sublists []))
⊢ l₁ ++ l₂ ~ []

Next tactic:
simp only [sublists_nil, reverse_cons, reverse_nil, nil_append, zip_cons_cons, zip_nil_right,
        mem_singleton, Prod.mk.injEq] at h
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l using List.reverseRecOn with l' a ih
  · intro l₁ l₂ h
    simp? at h says
      simp only [sublists_nil, reverse_cons, reverse_nil, nil_append, zip_cons_cons, zip_nil_right,
        mem_singleton, Prod.mk.injEq] at h
    

Proof state:
case H0
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
h : l₁ = [] ∧ l₂ = []
⊢ l₁ ++ l₂ ~ []

Next tactic:
simp [h]
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l using List.reverseRecOn with l' a ih
  · intro l₁ l₂ h
    simp? at h says
      simp only [sublists_nil, reverse_cons, reverse_nil, nil_append, zip_cons_cons, zip_nil_right,
        mem_singleton, Prod.mk.injEq] at h
    simp [h]
  · 

Proof state:
case H1
α : Type u
β : Type v
γ : Type w
l' : List α
a : α
ih : ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists l') (reverse (sublists l')) → l₁ ++ l₂ ~ l'
⊢ ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists (l' ++ [a])) (reverse (sublists (l' ++ [a]))) → l₁ ++ l₂ ~ l' ++ [a]

Next tactic:
intro l₁ l₂ h
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l using List.reverseRecOn with l' a ih
  · intro l₁ l₂ h
    simp? at h says
      simp only [sublists_nil, reverse_cons, reverse_nil, nil_append, zip_cons_cons, zip_nil_right,
        mem_singleton, Prod.mk.injEq] at h
    simp [h]
  · intro l₁ l₂ h
    

Proof state:
case H1
α : Type u
β : Type v
γ : Type w
l' : List α
a : α
ih : ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists l') (reverse (sublists l')) → l₁ ++ l₂ ~ l'
l₁ l₂ : List α
h : (l₁, l₂) ∈ zip (sublists (l' ++ [a])) (reverse (sublists (l' ++ [a])))
⊢ l₁ ++ l₂ ~ l' ++ [a]

Next tactic:
rw [sublists_concat, reverse_append, zip_append, ← map_reverse, zip_map_right,
      zip_map_left] at * <;> [skip; simp]
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l using List.reverseRecOn with l' a ih
  · intro l₁ l₂ h
    simp? at h says
      simp only [sublists_nil, reverse_cons, reverse_nil, nil_append, zip_cons_cons, zip_nil_right,
        mem_singleton, Prod.mk.injEq] at h
    simp [h]
  · intro l₁ l₂ h
    

Proof state:
case H1
α : Type u
β : Type v
γ : Type w
l' : List α
a : α
ih : ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists l') (reverse (sublists l')) → l₁ ++ l₂ ~ l'
l₁ l₂ : List α
h : (l₁, l₂) ∈ zip (sublists (l' ++ [a])) (reverse (sublists (l' ++ [a])))
⊢ l₁ ++ l₂ ~ l' ++ [a]

Next tactic:
rw [sublists_concat, reverse_append, zip_append, ← map_reverse, zip_map_right,
      zip_map_left] at *
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l using List.reverseRecOn with l' a ih
  · intro l₁ l₂ h
    simp? at h says
      simp only [sublists_nil, reverse_cons, reverse_nil, nil_append, zip_cons_cons, zip_nil_right,
        mem_singleton, Prod.mk.injEq] at h
    simp [h]
  · intro l₁ l₂ h
    rw [sublists_concat, reverse_append, zip_append, ← map_reverse, zip_map_right,
      zip_map_left] at * <;> [

Proof state:
case H1
α : Type u
β : Type v
γ : Type w
l' : List α
a : α
ih : ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists l') (reverse (sublists l')) → l₁ ++ l₂ ~ l'
l₁ l₂ : List α
h :
  (l₁, l₂) ∈
    map (Prod.map id fun x => x ++ [a]) (zip (sublists l') (reverse (sublists l'))) ++
      map (Prod.map (fun x => x ++ [a]) id) (zip (sublists l') (reverse (sublists l')))
⊢ l₁ ++ l₂ ~ l' ++ [a]

Next tactic:
skip
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l using List.reverseRecOn with l' a ih
  · intro l₁ l₂ h
    simp? at h says
      simp only [sublists_nil, reverse_cons, reverse_nil, nil_append, zip_cons_cons, zip_nil_right,
        mem_singleton, Prod.mk.injEq] at h
    simp [h]
  · intro l₁ l₂ h
    rw [sublists_concat, reverse_append, zip_append, ← map_reverse, zip_map_right,
      zip_map_left] at * <;> [skip; 

Proof state:
case H1
α : Type u
β : Type v
γ : Type w
l' : List α
a : α
ih : ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists l') (reverse (sublists l')) → l₁ ++ l₂ ~ l'
l₁ l₂ : List α
h :
  (l₁, l₂) ∈
    zip (sublists l' ++ map (fun x => x ++ [a]) (sublists l'))
      (reverse (map (fun x => x ++ [a]) (sublists l')) ++ reverse (sublists l'))
⊢ length (sublists l') = length (reverse (map (fun x => x ++ [a]) (sublists l')))

Next tactic:
simp
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l using List.reverseRecOn with l' a ih
  · intro l₁ l₂ h
    simp? at h says
      simp only [sublists_nil, reverse_cons, reverse_nil, nil_append, zip_cons_cons, zip_nil_right,
        mem_singleton, Prod.mk.injEq] at h
    simp [h]
  · intro l₁ l₂ h
    rw [sublists_concat, reverse_append, zip_append, ← map_reverse, zip_map_right,
      zip_map_left] at * <;> [skip; simp]
    

Proof state:
case H1
α : Type u
β : Type v
γ : Type w
l' : List α
a : α
ih : ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists l') (reverse (sublists l')) → l₁ ++ l₂ ~ l'
l₁ l₂ : List α
h :
  (l₁, l₂) ∈
    map (Prod.map id fun x => x ++ [a]) (zip (sublists l') (reverse (sublists l'))) ++
      map (Prod.map (fun x => x ++ [a]) id) (zip (sublists l') (reverse (sublists l')))
⊢ l₁ ++ l₂ ~ l' ++ [a]

Next tactic:
simp only [Prod.mk.inj_iff, mem_map, mem_append, Prod.map_mk, Prod.exists] at h
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l using List.reverseRecOn with l' a ih
  · intro l₁ l₂ h
    simp? at h says
      simp only [sublists_nil, reverse_cons, reverse_nil, nil_append, zip_cons_cons, zip_nil_right,
        mem_singleton, Prod.mk.injEq] at h
    simp [h]
  · intro l₁ l₂ h
    rw [sublists_concat, reverse_append, zip_append, ← map_reverse, zip_map_right,
      zip_map_left] at * <;> [skip; simp]
    simp only [Prod.mk.inj_iff, mem_map, mem_append, Prod.map_mk, Prod.exists] at h
    

Proof state:
case H1
α : Type u
β : Type v
γ : Type w
l' : List α
a : α
ih : ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists l') (reverse (sublists l')) → l₁ ++ l₂ ~ l'
l₁ l₂ : List α
h :
  (∃ a_1 b, (a_1, b) ∈ zip (sublists l') (reverse (sublists l')) ∧ id a_1 = l₁ ∧ b ++ [a] = l₂) ∨
    ∃ a_1 b, (a_1, b) ∈ zip (sublists l') (reverse (sublists l')) ∧ a_1 ++ [a] = l₁ ∧ id b = l₂
⊢ l₁ ++ l₂ ~ l' ++ [a]

Next tactic:
rcases h with (⟨l₁, l₂', h, rfl, rfl⟩ | ⟨l₁', l₂, h, rfl, rfl⟩)
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l using List.reverseRecOn with l' a ih
  · intro l₁ l₂ h
    simp? at h says
      simp only [sublists_nil, reverse_cons, reverse_nil, nil_append, zip_cons_cons, zip_nil_right,
        mem_singleton, Prod.mk.injEq] at h
    simp [h]
  · intro l₁ l₂ h
    rw [sublists_concat, reverse_append, zip_append, ← map_reverse, zip_map_right,
      zip_map_left] at * <;> [skip; simp]
    simp only [Prod.mk.inj_iff, mem_map, mem_append, Prod.map_mk, Prod.exists] at h
    rcases h with (⟨l₁, l₂', h, rfl, rfl⟩ | ⟨l₁', l₂, h, rfl, rfl⟩)
    · 

Proof state:
case H1.inl.intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
l' : List α
a : α
ih : ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists l') (reverse (sublists l')) → l₁ ++ l₂ ~ l'
l₁ l₂' : List α
h : (l₁, l₂') ∈ zip (sublists l') (reverse (sublists l'))
⊢ id l₁ ++ (l₂' ++ [a]) ~ l' ++ [a]

Next tactic:
rw [← append_assoc]
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l using List.reverseRecOn with l' a ih
  · intro l₁ l₂ h
    simp? at h says
      simp only [sublists_nil, reverse_cons, reverse_nil, nil_append, zip_cons_cons, zip_nil_right,
        mem_singleton, Prod.mk.injEq] at h
    simp [h]
  · intro l₁ l₂ h
    rw [sublists_concat, reverse_append, zip_append, ← map_reverse, zip_map_right,
      zip_map_left] at * <;> [skip; simp]
    simp only [Prod.mk.inj_iff, mem_map, mem_append, Prod.map_mk, Prod.exists] at h
    rcases h with (⟨l₁, l₂', h, rfl, rfl⟩ | ⟨l₁', l₂, h, rfl, rfl⟩)
    · rw [← append_assoc]
      

Proof state:
case H1.inl.intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
l' : List α
a : α
ih : ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists l') (reverse (sublists l')) → l₁ ++ l₂ ~ l'
l₁ l₂' : List α
h : (l₁, l₂') ∈ zip (sublists l') (reverse (sublists l'))
⊢ id l₁ ++ l₂' ++ [a] ~ l' ++ [a]

Next tactic:
exact (ih _ _ h).append_right _
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l using List.reverseRecOn with l' a ih
  · intro l₁ l₂ h
    simp? at h says
      simp only [sublists_nil, reverse_cons, reverse_nil, nil_append, zip_cons_cons, zip_nil_right,
        mem_singleton, Prod.mk.injEq] at h
    simp [h]
  · intro l₁ l₂ h
    rw [sublists_concat, reverse_append, zip_append, ← map_reverse, zip_map_right,
      zip_map_left] at * <;> [skip; simp]
    simp only [Prod.mk.inj_iff, mem_map, mem_append, Prod.map_mk, Prod.exists] at h
    rcases h with (⟨l₁, l₂', h, rfl, rfl⟩ | ⟨l₁', l₂, h, rfl, rfl⟩)
    · rw [← append_assoc]
      exact (ih _ _ h).append_right _
    · 

Proof state:
case H1.inr.intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
l' : List α
a : α
ih : ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists l') (reverse (sublists l')) → l₁ ++ l₂ ~ l'
l₁' l₂ : List α
h : (l₁', l₂) ∈ zip (sublists l') (reverse (sublists l'))
⊢ l₁' ++ [a] ++ id l₂ ~ l' ++ [a]

Next tactic:
rw [append_assoc]
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l using List.reverseRecOn with l' a ih
  · intro l₁ l₂ h
    simp? at h says
      simp only [sublists_nil, reverse_cons, reverse_nil, nil_append, zip_cons_cons, zip_nil_right,
        mem_singleton, Prod.mk.injEq] at h
    simp [h]
  · intro l₁ l₂ h
    rw [sublists_concat, reverse_append, zip_append, ← map_reverse, zip_map_right,
      zip_map_left] at * <;> [skip; simp]
    simp only [Prod.mk.inj_iff, mem_map, mem_append, Prod.map_mk, Prod.exists] at h
    rcases h with (⟨l₁, l₂', h, rfl, rfl⟩ | ⟨l₁', l₂, h, rfl, rfl⟩)
    · rw [← append_assoc]
      exact (ih _ _ h).append_right _
    · rw [append_assoc]
      

Proof state:
case H1.inr.intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
l' : List α
a : α
ih : ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists l') (reverse (sublists l')) → l₁ ++ l₂ ~ l'
l₁' l₂ : List α
h : (l₁', l₂) ∈ zip (sublists l') (reverse (sublists l'))
⊢ l₁' ++ ([a] ++ id l₂) ~ l' ++ [a]

Next tactic:
apply (perm_append_comm.append_left _).trans
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l using List.reverseRecOn with l' a ih
  · intro l₁ l₂ h
    simp? at h says
      simp only [sublists_nil, reverse_cons, reverse_nil, nil_append, zip_cons_cons, zip_nil_right,
        mem_singleton, Prod.mk.injEq] at h
    simp [h]
  · intro l₁ l₂ h
    rw [sublists_concat, reverse_append, zip_append, ← map_reverse, zip_map_right,
      zip_map_left] at * <;> [skip; simp]
    simp only [Prod.mk.inj_iff, mem_map, mem_append, Prod.map_mk, Prod.exists] at h
    rcases h with (⟨l₁, l₂', h, rfl, rfl⟩ | ⟨l₁', l₂, h, rfl, rfl⟩)
    · rw [← append_assoc]
      exact (ih _ _ h).append_right _
    · rw [append_assoc]
      apply (perm_append_comm.append_left _).trans
      

Proof state:
case H1.inr.intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
l' : List α
a : α
ih : ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists l') (reverse (sublists l')) → l₁ ++ l₂ ~ l'
l₁' l₂ : List α
h : (l₁', l₂) ∈ zip (sublists l') (reverse (sublists l'))
⊢ l₁' ++ (id l₂ ++ [a]) ~ l' ++ [a]

Next tactic:
rw [← append_assoc]
theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l using List.reverseRecOn with l' a ih
  · intro l₁ l₂ h
    simp? at h says
      simp only [sublists_nil, reverse_cons, reverse_nil, nil_append, zip_cons_cons, zip_nil_right,
        mem_singleton, Prod.mk.injEq] at h
    simp [h]
  · intro l₁ l₂ h
    rw [sublists_concat, reverse_append, zip_append, ← map_reverse, zip_map_right,
      zip_map_left] at * <;> [skip; simp]
    simp only [Prod.mk.inj_iff, mem_map, mem_append, Prod.map_mk, Prod.exists] at h
    rcases h with (⟨l₁, l₂', h, rfl, rfl⟩ | ⟨l₁', l₂, h, rfl, rfl⟩)
    · rw [← append_assoc]
      exact (ih _ _ h).append_right _
    · rw [append_assoc]
      apply (perm_append_comm.append_left _).trans
      rw [← append_assoc]
      

Proof state:
case H1.inr.intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
l' : List α
a : α
ih : ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists l') (reverse (sublists l')) → l₁ ++ l₂ ~ l'
l₁' l₂ : List α
h : (l₁', l₂) ∈ zip (sublists l') (reverse (sublists l'))
⊢ l₁' ++ id l₂ ++ [a] ~ l' ++ [a]

Next tactic:
exact (ih _ _ h).append_right _
theorem revzip_sublists' (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists' → l₁ ++ l₂ ~ l := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
l : List α
⊢ ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ revzip (sublists' l) → l₁ ++ l₂ ~ l

Next tactic:
rw [revzip]
theorem revzip_sublists' (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists' → l₁ ++ l₂ ~ l := by
  rw [revzip]
  

Proof state:
α : Type u
β : Type v
γ : Type w
l : List α
⊢ ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists' l) (reverse (sublists' l)) → l₁ ++ l₂ ~ l

Next tactic:
induction' l with a l IH
theorem revzip_sublists' (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists' → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l with a l IH <;> 

Proof state:
case nil
α : Type u
β : Type v
γ : Type w
⊢ ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists' []) (reverse (sublists' [])) → l₁ ++ l₂ ~ []

Next tactic:
intro l₁ l₂ h
theorem revzip_sublists' (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists' → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l with a l IH <;> 

Proof state:
case cons
α : Type u
β : Type v
γ : Type w
a : α
l : List α
IH : ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists' l) (reverse (sublists' l)) → l₁ ++ l₂ ~ l
⊢ ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists' (a :: l)) (reverse (sublists' (a :: l))) → l₁ ++ l₂ ~ a :: l

Next tactic:
intro l₁ l₂ h
theorem revzip_sublists' (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l.sublists' → l₁ ++ l₂ ~ l := by
  rw [revzip]
  induction' l with a l IH <;> intro l₁ l₂ h
  · 

Proof state:
case nil
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
h : (l₁, l₂) ∈ zip (sublists' []) (reverse (sublists' []))
⊢ l₁ ++ l₂ ~ []

Next tactic:
simp at h