l3lab/ntp-mathlib huggingface dataset:
theorem sublistsAux_eq_array_foldl :
    sublistsAux = fun (a : α) (r : List (List α)) =>
      (r.toArray.foldl (init := #[])
        fun r l => (r.push l).push (a :: l)).toList := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
⊢ sublistsAux = fun a r =>
    Array.toList
      (Array.foldl (fun r l => Array.push (Array.push r l) (a :: l)) #[] (toArray r) 0 (Array.size (toArray r)))

Next tactic:
funext a r
theorem sublistsAux_eq_array_foldl :
    sublistsAux = fun (a : α) (r : List (List α)) =>
      (r.toArray.foldl (init := #[])
        fun r l => (r.push l).push (a :: l)).toList := by
  funext a r
  

Proof state:
case h.h
α : Type u
β : Type v
γ : Type w
a : α
r : List (List α)
⊢ sublistsAux a r =
    Array.toList
      (Array.foldl (fun r l => Array.push (Array.push r l) (a :: l)) #[] (toArray r) 0 (Array.size (toArray r)))

Next tactic:
simp only [sublistsAux, Array.foldl_eq_foldl_data, Array.mkEmpty]
theorem sublistsAux_eq_array_foldl :
    sublistsAux = fun (a : α) (r : List (List α)) =>
      (r.toArray.foldl (init := #[])
        fun r l => (r.push l).push (a :: l)).toList := by
  funext a r
  simp only [sublistsAux, Array.foldl_eq_foldl_data, Array.mkEmpty]
  

Proof state:
case h.h
α : Type u
β : Type v
γ : Type w
a : α
r : List (List α)
⊢ foldl (fun r l => r ++ [l, a :: l]) [] r =
    Array.toList (foldl (fun r l => Array.push (Array.push r l) (a :: l)) #[] (toArray r).data)

Next tactic:
have := foldl_hom Array.toList (fun r l => (r.push l).push (a :: l))
    (fun (r : List (List α)) l => r ++ [l, a :: l]) r #[]
    (by simp)
theorem sublistsAux_eq_array_foldl :
    sublistsAux = fun (a : α) (r : List (List α)) =>
      (r.toArray.foldl (init := #[])
        fun r l => (r.push l).push (a :: l)).toList := by
  funext a r
  simp only [sublistsAux, Array.foldl_eq_foldl_data, Array.mkEmpty]
  have := foldl_hom Array.toList (fun r l => (r.push l).push (a :: l))
    (fun (r : List (List α)) l => r ++ [l, a :: l]) r #[]
    (by 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
r : List (List α)
⊢ ∀ (x : Array (List α)) (y : List α),
    (fun r l => r ++ [l, a :: l]) (Array.toList x) y =
      Array.toList ((fun r l => Array.push (Array.push r l) (a :: l)) x y)

Next tactic:
simp
theorem sublistsAux_eq_array_foldl :
    sublistsAux = fun (a : α) (r : List (List α)) =>
      (r.toArray.foldl (init := #[])
        fun r l => (r.push l).push (a :: l)).toList := by
  funext a r
  simp only [sublistsAux, Array.foldl_eq_foldl_data, Array.mkEmpty]
  have := foldl_hom Array.toList (fun r l => (r.push l).push (a :: l))
    (fun (r : List (List α)) l => r ++ [l, a :: l]) r #[]
    (by simp)
  

Proof state:
case h.h
α : Type u
β : Type v
γ : Type w
a : α
r : List (List α)
this :
  foldl (fun r l => r ++ [l, a :: l]) (Array.toList #[]) r =
    Array.toList (foldl (fun r l => Array.push (Array.push r l) (a :: l)) #[] r)
⊢ foldl (fun r l => r ++ [l, a :: l]) [] r =
    Array.toList (foldl (fun r l => Array.push (Array.push r l) (a :: l)) #[] (toArray r).data)

Next tactic:
simpa using this
theorem sublistsAux_eq_bind :
    sublistsAux = fun (a : α) (r : List (List α)) => r.bind fun l => [l, a :: l] :=
  funext <| fun a => funext <| fun r =>
  List.reverseRecOn r
    (by 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
r : List (List α)
⊢ sublistsAux a [] = List.bind [] fun l => [l, a :: l]

Next tactic:
simp [sublistsAux]
theorem sublistsAux_eq_bind :
    sublistsAux = fun (a : α) (r : List (List α)) => r.bind fun l => [l, a :: l] :=
  funext <| fun a => funext <| fun r =>
  List.reverseRecOn r
    (by simp [sublistsAux])
    (fun r l ih => by
      

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
r✝ r : List (List α)
l : List α
ih : sublistsAux a r = List.bind r fun l => [l, a :: l]
⊢ sublistsAux a (r ++ [l]) = List.bind (r ++ [l]) fun l => [l, a :: l]

Next tactic:
rw [append_bind, ← ih, bind_singleton, sublistsAux, foldl_append]
theorem sublistsAux_eq_bind :
    sublistsAux = fun (a : α) (r : List (List α)) => r.bind fun l => [l, a :: l] :=
  funext <| fun a => funext <| fun r =>
  List.reverseRecOn r
    (by simp [sublistsAux])
    (fun r l ih => by
      rw [append_bind, ← ih, bind_singleton, sublistsAux, foldl_append]
      

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
r✝ r : List (List α)
l : List α
ih : sublistsAux a r = List.bind r fun l => [l, a :: l]
⊢ foldl (fun r l => r ++ [l, a :: l]) (foldl (fun r l => r ++ [l, a :: l]) [] r) [l] = sublistsAux a r ++ [l, a :: l]

Next tactic:
simp [sublistsAux]
@[csimp] theorem sublists_eq_sublistsFast : @sublists = @sublistsFast := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
⊢ @sublists = @sublistsFast

Next tactic:
ext α l : 2
@[csimp] theorem sublists_eq_sublistsFast : @sublists = @sublistsFast := by
  ext α l : 2
  

Proof state:
case h.h
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l : List α
⊢ sublists l = sublistsFast l

Next tactic:
trans l.foldr sublistsAux [[]]
@[csimp] theorem sublists_eq_sublistsFast : @sublists = @sublistsFast := by
  ext α l : 2
  trans l.foldr sublistsAux [[]]
  · 

Proof state:
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l : List α
⊢ sublists l = foldr sublistsAux [[]] l

Next tactic:
rw [sublistsAux_eq_bind, sublists]
@[csimp] theorem sublists_eq_sublistsFast : @sublists = @sublistsFast := by
  ext α l : 2
  trans l.foldr sublistsAux [[]]
  · rw [sublistsAux_eq_bind, sublists]
  · 

Proof state:
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l : List α
⊢ foldr sublistsAux [[]] l = sublistsFast l

Next tactic:
simp only [sublistsFast, sublistsAux_eq_array_foldl, Array.foldr_eq_foldr_data]
@[csimp] theorem sublists_eq_sublistsFast : @sublists = @sublistsFast := by
  ext α l : 2
  trans l.foldr sublistsAux [[]]
  · rw [sublistsAux_eq_bind, sublists]
  · simp only [sublistsFast, sublistsAux_eq_array_foldl, Array.foldr_eq_foldr_data]
    

Proof state:
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l : List α
⊢ foldr
      (fun a r =>
        Array.toList
          (Array.foldl (fun r l => Array.push (Array.push r l) (a :: l)) #[] (toArray r) 0 (Array.size (toArray r))))
      [[]] l =
    Array.toList
      (foldr
        (fun a arr =>
          Array.foldl (fun r l => Array.push (Array.push r l) (a :: l)) (Array.mkEmpty (Array.size arr * 2)) arr 0
            (Array.size arr))
        #[[]] l)

Next tactic:
rw [← foldr_hom Array.toList]
@[csimp] theorem sublists_eq_sublistsFast : @sublists = @sublistsFast := by
  ext α l : 2
  trans l.foldr sublistsAux [[]]
  · rw [sublistsAux_eq_bind, sublists]
  · simp only [sublistsFast, sublistsAux_eq_array_foldl, Array.foldr_eq_foldr_data]
    rw [← foldr_hom Array.toList]
    · 

Proof state:
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l : List α
⊢ foldr
      (fun a r =>
        Array.toList
          (Array.foldl (fun r l => Array.push (Array.push r l) (a :: l)) #[] (toArray r) 0 (Array.size (toArray r))))
      [[]] l =
    foldr ?g₂ (Array.toList #[[]]) l

Next tactic:
rfl
@[csimp] theorem sublists_eq_sublistsFast : @sublists = @sublistsFast := by
  ext α l : 2
  trans l.foldr sublistsAux [[]]
  · rw [sublistsAux_eq_bind, sublists]
  · simp only [sublistsFast, sublistsAux_eq_array_foldl, Array.foldr_eq_foldr_data]
    rw [← foldr_hom Array.toList]
    · rfl
    · 

Proof state:
case H
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l : List α
⊢ ∀ (x : α) (y : Array (List α)),
    Array.toList
        (Array.foldl (fun r l => Array.push (Array.push r l) (x :: l)) #[] (toArray (Array.toList y)) 0
          (Array.size (toArray (Array.toList y)))) =
      Array.toList
        (Array.foldl (fun r l => Array.push (Array.push r l) (x :: l)) (Array.mkEmpty (Array.size y * 2)) y 0
          (Array.size y))

Next tactic:
intros _ _
@[csimp] theorem sublists_eq_sublistsFast : @sublists = @sublistsFast := by
  ext α l : 2
  trans l.foldr sublistsAux [[]]
  · rw [sublistsAux_eq_bind, sublists]
  · simp only [sublistsFast, sublistsAux_eq_array_foldl, Array.foldr_eq_foldr_data]
    rw [← foldr_hom Array.toList]
    · rfl
    · intros _ _; 

Proof state:
case H
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l : List α
x✝ : α
y✝ : Array (List α)
⊢ Array.toList
      (Array.foldl (fun r l => Array.push (Array.push r l) (x✝ :: l)) #[] (toArray (Array.toList y✝)) 0
        (Array.size (toArray (Array.toList y✝)))) =
    Array.toList
      (Array.foldl (fun r l => Array.push (Array.push r l) (x✝ :: l)) (Array.mkEmpty (Array.size y✝ * 2)) y✝ 0
        (Array.size y✝))

Next tactic:
congr
@[csimp] theorem sublists_eq_sublistsFast : @sublists = @sublistsFast := by
  ext α l : 2
  trans l.foldr sublistsAux [[]]
  · rw [sublistsAux_eq_bind, sublists]
  · simp only [sublistsFast, sublistsAux_eq_array_foldl, Array.foldr_eq_foldr_data]
    rw [← foldr_hom Array.toList]
    · rfl
    · intros _ _; congr <;> 

Proof state:
case H.e_as.h.e_5.h
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l : List α
x✝ : α
y✝ : Array (List α)
⊢ toArray (Array.toList y✝) = y✝

Next tactic:
simp
@[csimp] theorem sublists_eq_sublistsFast : @sublists = @sublistsFast := by
  ext α l : 2
  trans l.foldr sublistsAux [[]]
  · rw [sublistsAux_eq_bind, sublists]
  · simp only [sublistsFast, sublistsAux_eq_array_foldl, Array.foldr_eq_foldr_data]
    rw [← foldr_hom Array.toList]
    · rfl
    · intros _ _; congr <;> 

Proof state:
case H.e_as.h.e_7.e_a
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l : List α
x✝ : α
y✝ : Array (List α)
⊢ toArray (Array.toList y✝) = y✝

Next tactic:
simp
theorem sublists_append (l₁ l₂ : List α) :
    sublists (l₁ ++ l₂) = (sublists l₂) >>= (fun x => (sublists l₁).map (· ++ x)) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
⊢ sublists (l₁ ++ l₂) = do
    let x ← sublists l₂
    map (fun x_1 => x_1 ++ x) (sublists l₁)

Next tactic:
simp only [sublists, foldr_append]
theorem sublists_append (l₁ l₂ : List α) :
    sublists (l₁ ++ l₂) = (sublists l₂) >>= (fun x => (sublists l₁).map (· ++ x)) := by
  simp only [sublists, foldr_append]
  

Proof state:
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
⊢ foldr (fun a acc => List.bind acc fun x => [x, a :: x])
      (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂) l₁ =
    do
    let x ← foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₁)

Next tactic:
induction l₁
theorem sublists_append (l₁ l₂ : List α) :
    sublists (l₁ ++ l₂) = (sublists l₂) >>= (fun x => (sublists l₁).map (· ++ x)) := by
  simp only [sublists, foldr_append]
  induction l₁
  · 

Proof state:
case nil
α : Type u
β : Type v
γ : Type w
l₂ : List α
⊢ foldr (fun a acc => List.bind acc fun x => [x, a :: x])
      (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂) [] =
    do
    let x ← foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] [])

Next tactic:
case nil => simp
theorem sublists_append (l₁ l₂ : List α) :
    sublists (l₁ ++ l₂) = (sublists l₂) >>= (fun x => (sublists l₁).map (· ++ x)) := by
  simp only [sublists, foldr_append]
  induction l₁
  · 

Proof state:
α : Type u
β : Type v
γ : Type w
l₂ : List α
⊢ foldr (fun a acc => List.bind acc fun x => [x, a :: x])
      (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂) [] =
    do
    let x ← foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] [])

Next tactic:
case nil => simp
theorem sublists_append (l₁ l₂ : List α) :
    sublists (l₁ ++ l₂) = (sublists l₂) >>= (fun x => (sublists l₁).map (· ++ x)) := by
  simp only [sublists, foldr_append]
  induction l₁
  · case nil => 

Proof state:
α : Type u
β : Type v
γ : Type w
l₂ : List α
⊢ foldr (fun a acc => List.bind acc fun x => [x, a :: x])
      (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂) [] =
    do
    let x ← foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] [])

Next tactic:
simp
theorem sublists_append (l₁ l₂ : List α) :
    sublists (l₁ ++ l₂) = (sublists l₂) >>= (fun x => (sublists l₁).map (· ++ x)) := by
  simp only [sublists, foldr_append]
  induction l₁
  · case nil => simp
  · 

Proof state:
case cons
α : Type u
β : Type v
γ : Type w
l₂ : List α
head✝ : α
tail✝ : List α
tail_ih✝ :
  foldr (fun a acc => List.bind acc fun x => [x, a :: x])
      (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂) tail✝ =
    do
    let x ← foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] tail✝)
⊢ foldr (fun a acc => List.bind acc fun x => [x, a :: x])
      (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂) (head✝ :: tail✝) =
    do
    let x ← foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] (head✝ :: tail✝))

Next tactic:
case cons a l₁ ih =>
      rw [foldr_cons, ih]
      simp [List.bind, join_join, Function.comp]
theorem sublists_append (l₁ l₂ : List α) :
    sublists (l₁ ++ l₂) = (sublists l₂) >>= (fun x => (sublists l₁).map (· ++ x)) := by
  simp only [sublists, foldr_append]
  induction l₁
  · case nil => simp
  · 

Proof state:
α : Type u
β : Type v
γ : Type w
l₂ : List α
a : α
l₁ : List α
ih :
  foldr (fun a acc => List.bind acc fun x => [x, a :: x])
      (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂) l₁ =
    do
    let x ← foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₁)
⊢ foldr (fun a acc => List.bind acc fun x => [x, a :: x])
      (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂) (a :: l₁) =
    do
    let x ← foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] (a :: l₁))

Next tactic:
case cons a l₁ ih =>
      rw [foldr_cons, ih]
      simp [List.bind, join_join, Function.comp]
theorem sublists_append (l₁ l₂ : List α) :
    sublists (l₁ ++ l₂) = (sublists l₂) >>= (fun x => (sublists l₁).map (· ++ x)) := by
  simp only [sublists, foldr_append]
  induction l₁
  · case nil => simp
  · case cons a l₁ ih =>
      

Proof state:
α : Type u
β : Type v
γ : Type w
l₂ : List α
a : α
l₁ : List α
ih :
  foldr (fun a acc => List.bind acc fun x => [x, a :: x])
      (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂) l₁ =
    do
    let x ← foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₁)
⊢ foldr (fun a acc => List.bind acc fun x => [x, a :: x])
      (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂) (a :: l₁) =
    do
    let x ← foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] (a :: l₁))

Next tactic:
rw [foldr_cons, ih]
theorem sublists_append (l₁ l₂ : List α) :
    sublists (l₁ ++ l₂) = (sublists l₂) >>= (fun x => (sublists l₁).map (· ++ x)) := by
  simp only [sublists, foldr_append]
  induction l₁
  · case nil => simp
  · case cons a l₁ ih =>
      rw [foldr_cons, ih]
      

Proof state:
α : Type u
β : Type v
γ : Type w
l₂ : List α
a : α
l₁ : List α
ih :
  foldr (fun a acc => List.bind acc fun x => [x, a :: x])
      (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂) l₁ =
    do
    let x ← foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₁)
⊢ (List.bind
      (do
        let x ← foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂
        map (fun x_1 => x_1 ++ x) (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₁))
      fun x => [x, a :: x]) =
    do
    let x ← foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a acc => List.bind acc fun x => [x, a :: x]) [[]] (a :: l₁))

Next tactic:
simp [List.bind, join_join, Function.comp]
theorem sublists_cons (a : α) (l : List α) :
    sublists (a :: l) = sublists l >>= (fun x => [x, a :: x]) :=
  show sublists ([a] ++ l) = _ by
  

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
l : List α
⊢ sublists ([a] ++ l) = do
    let x ← sublists l
    [x, a :: x]

Next tactic:
rw [sublists_append]
theorem sublists_cons (a : α) (l : List α) :
    sublists (a :: l) = sublists l >>= (fun x => [x, a :: x]) :=
  show sublists ([a] ++ l) = _ by
  rw [sublists_append]
  

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
l : List α
⊢ (do
      let x ← sublists l
      map (fun x_1 => x_1 ++ x) (sublists [a])) =
    do
    let x ← sublists l
    [x, a :: x]

Next tactic:
simp only [sublists_singleton, map_cons, bind_eq_bind, nil_append, cons_append, map_nil]
@[simp]
theorem sublists_concat (l : List α) (a : α) :
    sublists (l ++ [a]) = sublists l ++ map (fun x => x ++ [a]) (sublists l) := by
  

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

Next tactic:
rw [sublists_append, sublists_singleton, bind_eq_bind, cons_bind, cons_bind, nil_bind,
     map_id'' append_nil, append_nil]
theorem sublists_reverse (l : List α) : sublists (reverse l) = map reverse (sublists' l) := by
  

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

Next tactic:
induction' l with hd tl ih <;> [rfl;
    simp only [reverse_cons, sublists_append, sublists'_cons, map_append, ih, sublists_singleton,
      map_eq_map, bind_eq_bind, map_map, cons_bind, append_nil, nil_bind, (· ∘ ·)]]
theorem sublists_reverse (l : List α) : sublists (reverse l) = map reverse (sublists' l) := by
  

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

Next tactic:
induction' l with hd tl ih
theorem sublists_reverse (l : List α) : sublists (reverse l) = map reverse (sublists' l) := by
  induction' l with hd tl ih <;> [

Proof state:
case nil
α : Type u
β : Type v
γ : Type w
⊢ sublists (reverse []) = map reverse (sublists' [])

Next tactic:
rfl
theorem sublists_reverse (l : List α) : sublists (reverse l) = map reverse (sublists' l) := by
  induction' l with hd tl ih <;> [rfl;
    

Proof state:
case cons
α : Type u
β : Type v
γ : Type w
hd : α
tl : List α
ih : sublists (reverse tl) = map reverse (sublists' tl)
⊢ sublists (reverse (hd :: tl)) = map reverse (sublists' (hd :: tl))

Next tactic:
simp only [reverse_cons, sublists_append, sublists'_cons, map_append, ih, sublists_singleton,
      map_eq_map, bind_eq_bind, map_map, cons_bind, append_nil, nil_bind, (· ∘ ·)]
theorem sublists_eq_sublists' (l : List α) : sublists l = map reverse (sublists' (reverse l)) := by
  

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

Next tactic:
rw [← sublists_reverse, reverse_reverse]
theorem sublists'_reverse (l : List α) : sublists' (reverse l) = map reverse (sublists l) := by
  

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

Next tactic:
simp only [sublists_eq_sublists', map_map, map_id'' reverse_reverse, Function.comp]
theorem sublists'_eq_sublists (l : List α) : sublists' l = map reverse (sublists (reverse l)) := by
  

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

Next tactic:
rw [← sublists'_reverse, reverse_reverse]
@[simp]
theorem mem_sublists {s t : List α} : s ∈ sublists t ↔ s <+ t := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s t : List α
⊢ s ∈ sublists t ↔ s <+ t

Next tactic:
rw [← reverse_sublist, ← mem_sublists', sublists'_reverse,
    mem_map_of_injective reverse_injective]
@[simp]
theorem length_sublists (l : List α) : length (sublists l) = 2 ^ length l := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
l : List α
⊢ length (sublists l) = 2 ^ length l

Next tactic:
simp only [sublists_eq_sublists', length_map, length_sublists', length_reverse]
theorem map_ret_sublist_sublists (l : List α) : map List.ret l <+ sublists l := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
l : List α
⊢ map List.ret l <+ sublists l

Next tactic:
induction' l using reverseRecOn with l a ih
theorem map_ret_sublist_sublists (l : List α) : map List.ret l <+ sublists l := by
  induction' l using reverseRecOn with l a ih <;>
  

Proof state:
case H0
α : Type u
β : Type v
γ : Type w
⊢ map List.ret [] <+ sublists []

Next tactic:
simp only [map, map_append, sublists_concat]
theorem map_ret_sublist_sublists (l : List α) : map List.ret l <+ sublists l := by
  induction' l using reverseRecOn with l a ih <;>
  

Proof state:
case H1
α : Type u
β : Type v
γ : Type w
l : List α
a : α
ih : map List.ret l <+ sublists l
⊢ map List.ret (l ++ [a]) <+ sublists (l ++ [a])

Next tactic:
simp only [map, map_append, sublists_concat]
theorem map_ret_sublist_sublists (l : List α) : map List.ret l <+ sublists l := by
  induction' l using reverseRecOn with l a ih <;>
  simp only [map, map_append, sublists_concat]
  · 

Proof state:
case H0
α : Type u
β : Type v
γ : Type w
⊢ [] <+ sublists []

Next tactic:
simp only [sublists_nil, sublist_cons]
theorem map_ret_sublist_sublists (l : List α) : map List.ret l <+ sublists l := by
  induction' l using reverseRecOn with l a ih <;>
  simp only [map, map_append, sublists_concat]
  · simp only [sublists_nil, sublist_cons]
  

Proof state:
case H1
α : Type u
β : Type v
γ : Type w
l : List α
a : α
ih : map List.ret l <+ sublists l
⊢ map List.ret l ++ [List.ret a] <+ sublists l ++ map (fun x => x ++ [a]) (sublists l)

Next tactic:
exact ((append_sublist_append_left _).2 <|
              singleton_sublist.2 <| mem_map.2 ⟨[], mem_sublists.2 (nil_sublist _), by rfl⟩).trans
          ((append_sublist_append_right _).2 ih)
theorem map_ret_sublist_sublists (l : List α) : map List.ret l <+ sublists l := by
  induction' l using reverseRecOn with l a ih <;>
  simp only [map, map_append, sublists_concat]
  · simp only [sublists_nil, sublist_cons]
  exact ((append_sublist_append_left _).2 <|
              singleton_sublist.2 <| mem_map.2 ⟨[], mem_sublists.2 (nil_sublist _), by 

Proof state:
α : Type u
β : Type v
γ : Type w
l : List α
a : α
ih : map List.ret l <+ sublists l
⊢ [] ++ [a] = List.ret a

Next tactic:
rfl
theorem sublistsLenAux_append {α β γ : Type*} :
    ∀ (n : ℕ) (l : List α) (f : List α → β) (g : β → γ) (r : List β) (s : List γ),
      sublistsLenAux n l (g ∘ f) (r.map g ++ s) = (sublistsLenAux n l f r).map g ++ s
  | 0, l, f, g, r, s => by 

Proof state:
α✝ : Type u
β✝ : Type v
γ✝ : Type w
α : Type u_1
β : Type u_2
γ : Type u_3
l : List α
f : List α → β
g : β → γ
r : List β
s : List γ
⊢ sublistsLenAux 0 l (g ∘ f) (map g r ++ s) = map g (sublistsLenAux 0 l f r) ++ s

Next tactic:
unfold sublistsLenAux
theorem sublistsLenAux_append {α β γ : Type*} :
    ∀ (n : ℕ) (l : List α) (f : List α → β) (g : β → γ) (r : List β) (s : List γ),
      sublistsLenAux n l (g ∘ f) (r.map g ++ s) = (sublistsLenAux n l f r).map g ++ s
  | 0, l, f, g, r, s => by unfold sublistsLenAux; 

Proof state:
α✝ : Type u
β✝ : Type v
γ✝ : Type w
α : Type u_1
β : Type u_2
γ : Type u_3
l : List α
f : List α → β
g : β → γ
r : List β
s : List γ
⊢ (g ∘ f) [] :: (map g r ++ s) = map g (f [] :: r) ++ s

Next tactic:
simp
theorem sublistsLenAux_append {α β γ : Type*} :
    ∀ (n : ℕ) (l : List α) (f : List α → β) (g : β → γ) (r : List β) (s : List γ),
      sublistsLenAux n l (g ∘ f) (r.map g ++ s) = (sublistsLenAux n l f r).map g ++ s
  | 0, l, f, g, r, s => by unfold sublistsLenAux; simp
  | n + 1, [], f, g, r, s => rfl
  | n + 1, a :: l, f, g, r, s => by
    

Proof state:
α✝ : Type u
β✝ : Type v
γ✝ : Type w
α : Type u_1
β : Type u_2
γ : Type u_3
n : ℕ
a : α
l : List α
f : List α → β
g : β → γ
r : List β
s : List γ
⊢ sublistsLenAux (n + 1) (a :: l) (g ∘ f) (map g r ++ s) = map g (sublistsLenAux (n + 1) (a :: l) f r) ++ s

Next tactic:
unfold sublistsLenAux