[GOAL]
a✝ b✝ : ℤ
n : ℕ
a b : ℤ
⊢ natAbs a = natAbs b ↔ a * a = b * b
[PROOFSTEP]
rw [← abs_eq_iff_mul_self_eq, abs_eq_natAbs, abs_eq_natAbs]
[GOAL]
a✝ b✝ : ℤ
n : ℕ
a b : ℤ
⊢ natAbs a = natAbs b ↔ ↑(natAbs a) = ↑(natAbs b)
[PROOFSTEP]
exact Int.coe_nat_inj'.symm
[GOAL]
a✝ b✝ : ℤ
n : ℕ
a b : ℤ
⊢ natAbs a < natAbs b ↔ a * a < b * b
[PROOFSTEP]
rw [← abs_lt_iff_mul_self_lt, abs_eq_natAbs, abs_eq_natAbs]
[GOAL]
a✝ b✝ : ℤ
n : ℕ
a b : ℤ
⊢ natAbs a < natAbs b ↔ ↑(natAbs a) < ↑(natAbs b)
[PROOFSTEP]
exact Int.ofNat_lt.symm
[GOAL]
a✝ b✝ : ℤ
n : ℕ
a b : ℤ
⊢ natAbs a ≤ natAbs b ↔ a * a ≤ b * b
[PROOFSTEP]
rw [← abs_le_iff_mul_self_le, abs_eq_natAbs, abs_eq_natAbs]
[GOAL]
a✝ b✝ : ℤ
n : ℕ
a b : ℤ
⊢ natAbs a ≤ natAbs b ↔ ↑(natAbs a) ≤ ↑(natAbs b)
[PROOFSTEP]
exact Int.ofNat_le.symm
[GOAL]
a✝ b✝ : ℤ
n : ℕ
a b c : ℤ
h : a * b ∣ c
⊢ b ∣ c / a
[PROOFSTEP]
rcases eq_or_ne a 0 with (rfl | ha)
[GOAL]
case inl
a b✝ : ℤ
n : ℕ
b c : ℤ
h : 0 * b ∣ c
⊢ b ∣ c / 0
[PROOFSTEP]
simp only [Int.ediv_zero, dvd_zero]
[GOAL]
case inr
a✝ b✝ : ℤ
n : ℕ
a b c : ℤ
h : a * b ∣ c
ha : a ≠ 0
⊢ b ∣ c / a
[PROOFSTEP]
rcases h with ⟨d, rfl⟩
[GOAL]
case inr.intro
a✝ b✝ : ℤ
n : ℕ
a b : ℤ
ha : a ≠ 0
d : ℤ
⊢ b ∣ a * b * d / a
[PROOFSTEP]
refine' ⟨d, _⟩
[GOAL]
case inr.intro
a✝ b✝ : ℤ
n : ℕ
a b : ℤ
ha : a ≠ 0
d : ℤ
⊢ a * b * d / a = b * d
[PROOFSTEP]
rw [mul_assoc, Int.mul_ediv_cancel_left _ ha]
[GOAL]
a b : ℤ
n : ℕ
m x : ℤ
h1 : m ∣ x
h2 : |x| < m
⊢ x = 0
[PROOFSTEP]
by_cases hm : m = 0
[GOAL]
case pos
a b : ℤ
n : ℕ
m x : ℤ
h1 : m ∣ x
h2 : |x| < m
hm : m = 0
⊢ x = 0
[PROOFSTEP]
subst m
[GOAL]
case pos
a b : ℤ
n : ℕ
x : ℤ
h1 : 0 ∣ x
h2 : |x| < 0
⊢ x = 0
[PROOFSTEP]
exact zero_dvd_iff.mp h1
[GOAL]
case neg
a b : ℤ
n : ℕ
m x : ℤ
h1 : m ∣ x
h2 : |x| < m
hm : ¬m = 0
⊢ x = 0
[PROOFSTEP]
rcases h1 with ⟨d, rfl⟩
[GOAL]
case neg.intro
a b : ℤ
n : ℕ
m : ℤ
hm : ¬m = 0
d : ℤ
h2 : |m * d| < m
⊢ m * d = 0
[PROOFSTEP]
apply mul_eq_zero_of_right
[GOAL]
case neg.intro.h
a b : ℤ
n : ℕ
m : ℤ
hm : ¬m = 0
d : ℤ
h2 : |m * d| < m
⊢ d = 0
[PROOFSTEP]
rw [← abs_lt_one_iff, ← mul_lt_iff_lt_one_right (abs_pos.mpr hm), ← abs_mul]
[GOAL]
case neg.intro.h
a b : ℤ
n : ℕ
m : ℤ
hm : ¬m = 0
d : ℤ
h2 : |m * d| < m
⊢ |m * d| < |m|
[PROOFSTEP]
exact lt_of_lt_of_le h2 (le_abs_self m)


[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
⊢ ∀ (r₁ r₂ : List (List α)),
    sublists'Aux a r₁ r₂ =
      Array.toList
        (Array.foldl (fun r l => Array.push r (a :: l)) (toArray r₂) (toArray r₁) 0 (Array.size (toArray r₁)))
[PROOFSTEP]
intro r₁ r₂
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
r₁ r₂ : List (List α)
⊢ sublists'Aux a r₁ r₂ =
    Array.toList (Array.foldl (fun r l => Array.push r (a :: l)) (toArray r₂) (toArray r₁) 0 (Array.size (toArray r₁)))
[PROOFSTEP]
rw [sublists'Aux, Array.foldl_eq_foldl_data]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
r₁ r₂ : List (List α)
⊢ foldl (fun r l => r ++ [a :: l]) r₂ r₁ =
    Array.toList (foldl (fun r l => Array.push r (a :: l)) (toArray r₂) (toArray r₁).data)
[PROOFSTEP]
have := List.foldl_hom Array.toList (fun r l => r.push (a :: l)) (fun r l => r ++ [a :: l]) r₁ r₂.toArray (by simp)
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
r₁ r₂ : List (List α)
⊢ ∀ (x : Array (List α)) (y : List α),
    (fun r l => r ++ [a :: l]) (Array.toList x) y = Array.toList ((fun r l => Array.push r (a :: l)) x y)
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
r₁ r₂ : List (List α)
this :
  foldl (fun r l => r ++ [a :: l]) (Array.toList (toArray r₂)) r₁ =
    Array.toList (foldl (fun r l => Array.push r (a :: l)) (toArray r₂) r₁)
⊢ foldl (fun r l => r ++ [a :: l]) r₂ r₁ =
    Array.toList (foldl (fun r l => Array.push r (a :: l)) (toArray r₂) (toArray r₁).data)
[PROOFSTEP]
simpa using this
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ sublists' l = foldr (fun a r => sublists'Aux a r r) [[]] l
[PROOFSTEP]
simp only [sublists', sublists'Aux_eq_array_foldl]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ Array.toList
      (foldr (fun a arr => Array.foldl (fun r l => Array.push r (a :: l)) arr arr 0 (Array.size arr)) #[[]] l) =
    foldr
      (fun a r =>
        Array.toList
          (Array.foldl (fun r l => Array.push r (a :: l)) (toArray r) (toArray r) 0 (Array.size (toArray r))))
      [[]] l
[PROOFSTEP]
rw [← List.foldr_hom Array.toList]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ foldr ?g₂ (Array.toList #[[]]) l =
    foldr
      (fun a r =>
        Array.toList
          (Array.foldl (fun r l => Array.push r (a :: l)) (toArray r) (toArray r) 0 (Array.size (toArray r))))
      [[]] l
[PROOFSTEP]
rfl
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
l : List α
⊢ ∀ (x : α) (y : Array (List α)),
    Array.toList
        (Array.foldl (fun r l => Array.push r (x :: l)) (toArray (Array.toList y)) (toArray (Array.toList y)) 0
          (Array.size (toArray (Array.toList y)))) =
      Array.toList (Array.foldl (fun r l => Array.push r (x :: l)) y y 0 (Array.size y))
[PROOFSTEP]
intros _ _
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
l : List α
x✝ : α
y✝ : Array (List α)
⊢ Array.toList
      (Array.foldl (fun r l => Array.push r (x✝ :: l)) (toArray (Array.toList y✝)) (toArray (Array.toList y✝)) 0
        (Array.size (toArray (Array.toList y✝)))) =
    Array.toList (Array.foldl (fun r l => Array.push r (x✝ :: l)) y✝ y✝ 0 (Array.size y✝))
[PROOFSTEP]
congr
[GOAL]
case H.e_as.h.e_4.h
α : Type u
β : Type v
γ : Type w
l : List α
x✝ : α
y✝ : Array (List α)
⊢ toArray (Array.toList y✝) = y✝
[PROOFSTEP]
simp
[GOAL]
case H.e_as.h.e_5.h
α : Type u
β : Type v
γ : Type w
l : List α
x✝ : α
y✝ : Array (List α)
⊢ toArray (Array.toList y✝) = y✝
[PROOFSTEP]
simp
[GOAL]
case H.e_as.h.e_7.e_a
α : Type u
β : Type v
γ : Type w
l : List α
x✝ : α
y✝ : Array (List α)
⊢ toArray (Array.toList y✝) = y✝
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
r₁ x✝ : List (List α)
⊢ sublists'Aux a [] x✝ = x✝ ++ map (cons a) []
[PROOFSTEP]
simp [sublists'Aux]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
r₁✝ r₁ : List (List α)
l : List α
ih : ∀ (r₂ : List (List α)), sublists'Aux a r₁ r₂ = r₂ ++ map (cons a) r₁
r₂ : List (List α)
⊢ sublists'Aux a (r₁ ++ [l]) r₂ = r₂ ++ map (cons a) (r₁ ++ [l])
[PROOFSTEP]
rw [map_append, map_singleton, ← append_assoc, ← ih, sublists'Aux, foldl_append, foldl]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
r₁✝ r₁ : List (List α)
l : List α
ih : ∀ (r₂ : List (List α)), sublists'Aux a r₁ r₂ = r₂ ++ map (cons a) r₁
r₂ : List (List α)
⊢ foldl (fun r l => r ++ [a :: l]) (foldl (fun r l => r ++ [a :: l]) r₂ r₁ ++ [a :: l]) [] =
    sublists'Aux a r₁ r₂ ++ [a :: l]
[PROOFSTEP]
simp [sublists'Aux]
  -- Porting note: simp can prove `sublists'_singleton`
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
l : List α
⊢ sublists' (a :: l) = sublists' l ++ map (cons a) (sublists' l)
[PROOFSTEP]
simp [sublists'_eq_sublists'Aux, foldr_cons, sublists'Aux_eq_map]
[GOAL]
α : Type u
β : Type v
γ : Type w
s t : List α
⊢ s ∈ sublists' t ↔ s <+ t
[PROOFSTEP]
induction' t with a t IH generalizing s
[GOAL]
case nil
α : Type u
β : Type v
γ : Type w
s✝ s : List α
⊢ s ∈ sublists' [] ↔ s <+ []
[PROOFSTEP]
simp only [sublists'_nil, mem_singleton]
[GOAL]
case nil
α : Type u
β : Type v
γ : Type w
s✝ s : List α
⊢ s = [] ↔ s <+ []
[PROOFSTEP]
exact ⟨fun h => by rw [h], eq_nil_of_sublist_nil⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝ s : List α
h : s = []
⊢ s <+ []
[PROOFSTEP]
rw [h]
[GOAL]
case cons
α : Type u
β : Type v
γ : Type w
s✝ : List α
a : α
t : List α
IH : ∀ {s : List α}, s ∈ sublists' t ↔ s <+ t
s : List α
⊢ s ∈ sublists' (a :: t) ↔ s <+ a :: t
[PROOFSTEP]
simp only [sublists'_cons, mem_append, IH, mem_map]
[GOAL]
case cons
α : Type u
β : Type v
γ : Type w
s✝ : List α
a : α
t : List α
IH : ∀ {s : List α}, s ∈ sublists' t ↔ s <+ t
s : List α
⊢ (s <+ t ∨ ∃ a_1, a_1 <+ t ∧ a :: a_1 = s) ↔ s <+ a :: t
[PROOFSTEP]
constructor
[GOAL]
case cons.mp
α : Type u
β : Type v
γ : Type w
s✝ : List α
a : α
t : List α
IH : ∀ {s : List α}, s ∈ sublists' t ↔ s <+ t
s : List α
⊢ (s <+ t ∨ ∃ a_1, a_1 <+ t ∧ a :: a_1 = s) → s <+ a :: t
[PROOFSTEP]
intro h
[GOAL]
case cons.mpr
α : Type u
β : Type v
γ : Type w
s✝ : List α
a : α
t : List α
IH : ∀ {s : List α}, s ∈ sublists' t ↔ s <+ t
s : List α
⊢ s <+ a :: t → s <+ t ∨ ∃ a_2, a_2 <+ t ∧ a :: a_2 = s
[PROOFSTEP]
intro h
[GOAL]
case cons.mp
α : Type u
β : Type v
γ : Type w
s✝ : List α
a : α
t : List α
IH : ∀ {s : List α}, s ∈ sublists' t ↔ s <+ t
s : List α
h : s <+ t ∨ ∃ a_1, a_1 <+ t ∧ a :: a_1 = s
⊢ s <+ a :: t
case cons.mpr
α : Type u
β : Type v
γ : Type w
s✝ : List α
a : α
t : List α
IH : ∀ {s : List α}, s ∈ sublists' t ↔ s <+ t
s : List α
h : s <+ a :: t
⊢ s <+ t ∨ ∃ a_1, a_1 <+ t ∧ a :: a_1 = s
[PROOFSTEP]
rcases h with (h | ⟨s, h, rfl⟩)
[GOAL]
case cons.mp.inl
α : Type u
β : Type v
γ : Type w
s✝ : List α
a : α
t : List α
IH : ∀ {s : List α}, s ∈ sublists' t ↔ s <+ t
s : List α
h : s <+ t
⊢ s <+ a :: t
[PROOFSTEP]
exact sublist_cons_of_sublist _ h
[GOAL]
case cons.mp.inr.intro.intro
α : Type u
β : Type v
γ : Type w
s✝ : List α
a : α
t : List α
IH : ∀ {s : List α}, s ∈ sublists' t ↔ s <+ t
s : List α
h : s <+ t
⊢ a :: s <+ a :: t
[PROOFSTEP]
exact h.cons_cons _
[GOAL]
case cons.mpr
α : Type u
β : Type v
γ : Type w
s✝ : List α
a : α
t : List α
IH : ∀ {s : List α}, s ∈ sublists' t ↔ s <+ t
s : List α
h : s <+ a :: t
⊢ s <+ t ∨ ∃ a_1, a_1 <+ t ∧ a :: a_1 = s
[PROOFSTEP]
cases' h with _ _ _ h s _ _ h
[GOAL]
case cons.mpr.cons
α : Type u
β : Type v
γ : Type w
s✝ : List α
a : α
t : List α
IH : ∀ {s : List α}, s ∈ sublists' t ↔ s <+ t
s : List α
h : s <+ t
⊢ s <+ t ∨ ∃ a_1, a_1 <+ t ∧ a :: a_1 = s
[PROOFSTEP]
exact Or.inl h
[GOAL]
case cons.mpr.cons₂
α : Type u
β : Type v
γ : Type w
s✝ : List α
a : α
t : List α
IH : ∀ {s : List α}, s ∈ sublists' t ↔ s <+ t
s : List α
h : s <+ t
⊢ a :: s <+ t ∨ ∃ a_1, a_1 <+ t ∧ a :: a_1 = a :: s
[PROOFSTEP]
exact Or.inr ⟨s, h, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
l : List α
⊢ length (sublists' (a :: l)) = 2 ^ length (a :: l)
[PROOFSTEP]
simp_arith only [sublists'_cons, length_append, length_sublists' l, length_map, length, Nat.pow_succ', mul_succ,
  mul_zero, zero_add]
[GOAL]
α : 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)))
[PROOFSTEP]
funext a r
[GOAL]
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)))
[PROOFSTEP]
simp only [sublistsAux, Array.foldl_eq_foldl_data, Array.mkEmpty]
[GOAL]
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)
[PROOFSTEP]
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)
[GOAL]
α : 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)
[PROOFSTEP]
simp
[GOAL]
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)
[PROOFSTEP]
simpa using this
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
r : List (List α)
⊢ sublistsAux a [] = List.bind [] fun l => [l, a :: l]
[PROOFSTEP]
simp [sublistsAux]
[GOAL]
α : 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]
[PROOFSTEP]
rw [append_bind, ← ih, bind_singleton, sublistsAux, foldl_append]
[GOAL]
α : 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]
[PROOFSTEP]
simp [sublistsAux]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ sublists l = foldr sublistsAux [[]] l
[PROOFSTEP]
simp only [sublists, sublistsAux_eq_array_foldl, Array.foldr_eq_foldr_data]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ 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) =
    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
[PROOFSTEP]
rw [← foldr_hom Array.toList]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ foldr ?g₂ (Array.toList #[[]]) l =
    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
[PROOFSTEP]
rfl
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
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))
[PROOFSTEP]
intros _ _
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
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✝))
[PROOFSTEP]
congr
[GOAL]
case H.e_as.h.e_5.h
α : Type u
β : Type v
γ : Type w
l : List α
x✝ : α
y✝ : Array (List α)
⊢ toArray (Array.toList y✝) = y✝
[PROOFSTEP]
simp
[GOAL]
case H.e_as.h.e_7.e_a
α : Type u
β : Type v
γ : Type w
l : List α
x✝ : α
y✝ : Array (List α)
⊢ toArray (Array.toList y✝) = y✝
[PROOFSTEP]
simp
[GOAL]
α : 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₁)
[PROOFSTEP]
simp only [sublists_eq_sublistsAux, foldr_append, sublistsAux_eq_bind]
[GOAL]
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
⊢ foldr (fun a r => List.bind r fun l => [l, a :: l]) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂) l₁ =
    do
    let x ← foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₁)
[PROOFSTEP]
induction l₁
[GOAL]
case nil
α : Type u
β : Type v
γ : Type w
l₂ : List α
⊢ foldr (fun a r => List.bind r fun l => [l, a :: l]) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂) [] =
    do
    let x ← foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] [])
[PROOFSTEP]
case nil => simp
[GOAL]
α : Type u
β : Type v
γ : Type w
l₂ : List α
⊢ foldr (fun a r => List.bind r fun l => [l, a :: l]) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂) [] =
    do
    let x ← foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] [])
[PROOFSTEP]
case nil => simp
[GOAL]
α : Type u
β : Type v
γ : Type w
l₂ : List α
⊢ foldr (fun a r => List.bind r fun l => [l, a :: l]) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂) [] =
    do
    let x ← foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] [])
[PROOFSTEP]
simp
[GOAL]
case cons
α : Type u
β : Type v
γ : Type w
l₂ : List α
head✝ : α
tail✝ : List α
tail_ih✝ :
  foldr (fun a r => List.bind r fun l => [l, a :: l]) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂)
      tail✝ =
    do
    let x ← foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] tail✝)
⊢ foldr (fun a r => List.bind r fun l => [l, a :: l]) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂)
      (head✝ :: tail✝) =
    do
    let x ← foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] (head✝ :: tail✝))
[PROOFSTEP]
case cons a l₁ ih =>
  rw [foldr_cons, ih]
  simp [List.bind, join_join, Function.comp]
[GOAL]
α : Type u
β : Type v
γ : Type w
l₂ : List α
a : α
l₁ : List α
ih :
  foldr (fun a r => List.bind r fun l => [l, a :: l]) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂) l₁ =
    do
    let x ← foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₁)
⊢ foldr (fun a r => List.bind r fun l => [l, a :: l]) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂)
      (a :: l₁) =
    do
    let x ← foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] (a :: l₁))
[PROOFSTEP]
case cons a l₁ ih =>
  rw [foldr_cons, ih]
  simp [List.bind, join_join, Function.comp]
[GOAL]
α : Type u
β : Type v
γ : Type w
l₂ : List α
a : α
l₁ : List α
ih :
  foldr (fun a r => List.bind r fun l => [l, a :: l]) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂) l₁ =
    do
    let x ← foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₁)
⊢ foldr (fun a r => List.bind r fun l => [l, a :: l]) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂)
      (a :: l₁) =
    do
    let x ← foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] (a :: l₁))
[PROOFSTEP]
rw [foldr_cons, ih]
[GOAL]
α : Type u
β : Type v
γ : Type w
l₂ : List α
a : α
l₁ : List α
ih :
  foldr (fun a r => List.bind r fun l => [l, a :: l]) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂) l₁ =
    do
    let x ← foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₁)
⊢ (List.bind
      (do
        let x ← foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂
        map (fun x_1 => x_1 ++ x) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₁))
      fun l => [l, a :: l]) =
    do
    let x ← foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] l₂
    map (fun x_1 => x_1 ++ x) (foldr (fun a r => List.bind r fun l => [l, a :: l]) [[]] (a :: l₁))
[PROOFSTEP]
simp [List.bind, join_join, Function.comp]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
l : List α
⊢ sublists ([a] ++ l) = do
    let x ← sublists l
    [x, a :: x]
[PROOFSTEP]
rw [sublists_append]
[GOAL]
α : 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]
[PROOFSTEP]
simp only [sublists_singleton, map_cons, bind_eq_bind, nil_append, cons_append, map_nil]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
a : α
⊢ sublists (l ++ [a]) = sublists l ++ map (fun x => x ++ [a]) (sublists l)
[PROOFSTEP]
rw [sublists_append, sublists_singleton, bind_eq_bind, cons_bind, cons_bind, nil_bind, map_id' append_nil, append_nil]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ sublists (reverse l) = map reverse (sublists' l)
[PROOFSTEP]
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, (· ∘ ·)]]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ sublists (reverse l) = map reverse (sublists' l)
[PROOFSTEP]
induction' l with hd tl ih
[GOAL]
case nil
α : Type u
β : Type v
γ : Type w
⊢ sublists (reverse []) = map reverse (sublists' [])
[PROOFSTEP]
rfl
[GOAL]
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))
[PROOFSTEP]
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, (· ∘ ·)]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ sublists l = map reverse (sublists' (reverse l))
[PROOFSTEP]
rw [← sublists_reverse, reverse_reverse]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ sublists' (reverse l) = map reverse (sublists l)
[PROOFSTEP]
simp only [sublists_eq_sublists', map_map, map_id' reverse_reverse, Function.comp]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ sublists' l = map reverse (sublists (reverse l))
[PROOFSTEP]
rw [← sublists'_reverse, reverse_reverse]
[GOAL]
α : Type u
β : Type v
γ : Type w
s t : List α
⊢ s ∈ sublists t ↔ s <+ t
[PROOFSTEP]
rw [← reverse_sublist, ← mem_sublists', sublists'_reverse, mem_map_of_injective reverse_injective]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ length (sublists l) = 2 ^ length l
[PROOFSTEP]
simp only [sublists_eq_sublists', length_map, length_sublists', length_reverse]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ map List.ret l <+ sublists l
[PROOFSTEP]
induction' l using reverseRecOn with l a ih
[GOAL]
case H0
α : Type u
β : Type v
γ : Type w
⊢ map List.ret [] <+ sublists []
[PROOFSTEP]
simp only [map, map_append, sublists_concat]
[GOAL]
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])
[PROOFSTEP]
simp only [map, map_append, sublists_concat]
[GOAL]
case H0
α : Type u
β : Type v
γ : Type w
⊢ [] <+ sublists []
[PROOFSTEP]
simp only [sublists_nil, sublist_cons]
[GOAL]
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)
[PROOFSTEP]
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)
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
a : α
ih : map List.ret l <+ sublists l
⊢ [] ++ [a] = List.ret a
[PROOFSTEP]
rfl
[GOAL]
α✝ : 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
[PROOFSTEP]
unfold sublistsLenAux
[GOAL]
α✝ : 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
[PROOFSTEP]
simp
[GOAL]
α✝ : 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
[PROOFSTEP]
unfold sublistsLenAux
[GOAL]
α✝ : 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 (Nat.add n 0 + 1) l (g ∘ f) (sublistsLenAux (Nat.add n 0) l ((g ∘ f) ∘ cons a) (map g r ++ s)) =
    map g (sublistsLenAux (Nat.add n 0 + 1) l f (sublistsLenAux (Nat.add n 0) l (f ∘ cons a) r)) ++ s
[PROOFSTEP]
simp only [show (g ∘ f) ∘ List.cons a = g ∘ f ∘ List.cons a by rfl, sublistsLenAux_append, sublistsLenAux_append]
[GOAL]
α✝ : 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 γ
⊢ (g ∘ f) ∘ cons a = g ∘ f ∘ cons a
[PROOFSTEP]
rfl
[GOAL]
α✝ : Type u
β✝ : Type v
γ : Type w
α : Type u_1
β : Type u_2
l : List α
n : ℕ
f : List α → β
r : List β
⊢ sublistsLenAux n l f r = map f (sublistsLen n l) ++ r
[PROOFSTEP]
rw [sublistsLen, ← sublistsLenAux_append]
[GOAL]
α✝ : Type u
β✝ : Type v
γ : Type w
α : Type u_1
β : Type u_2
l : List α
n : ℕ
f : List α → β
r : List β
⊢ sublistsLenAux n l f r = sublistsLenAux n l (f ∘ id) (map f [] ++ r)
[PROOFSTEP]
rfl
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l : List α
f : List α → β
r : List β
⊢ sublistsLenAux 0 l f r = f [] :: r
[PROOFSTEP]
cases l
[GOAL]
case nil
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
f : List α → β
r : List β
⊢ sublistsLenAux 0 [] f r = f [] :: r
[PROOFSTEP]
rfl
[GOAL]
case cons
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
f : List α → β
r : List β
head✝ : α
tail✝ : List α
⊢ sublistsLenAux 0 (head✝ :: tail✝) f r = f [] :: r
[PROOFSTEP]
rfl
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
n : ℕ
a : α
l : List α
⊢ sublistsLen (n + 1) (a :: l) = sublistsLen (n + 1) l ++ map (cons a) (sublistsLen n l)
[PROOFSTEP]
rw [sublistsLen, sublistsLenAux, sublistsLenAux_eq, sublistsLenAux_eq, map_id, append_nil]
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
n : ℕ
a : α
l : List α
⊢ sublistsLen (n + 1) l ++ map (id ∘ cons a) (sublistsLen n l) = sublistsLen (n + 1) l ++ map (cons a) (sublistsLen n l)
[PROOFSTEP]
rfl
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l : List α
⊢ length (sublistsLen 0 l) = Nat.choose (length l) 0
[PROOFSTEP]
simp
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
n✝ : ℕ
⊢ length (sublistsLen (n✝ + 1) []) = Nat.choose (length []) (n✝ + 1)
[PROOFSTEP]
simp
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
n : ℕ
a : α
l : List α
⊢ length (sublistsLen (n + 1) (a :: l)) = Nat.choose (length (a :: l)) (n + 1)
[PROOFSTEP]
rw [sublistsLen_succ_cons, length_append, length_sublistsLen (n + 1) l, length_map, length_sublistsLen n l, length_cons,
  Nat.choose_succ_succ, add_comm]
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l : List α
⊢ sublistsLen 0 l <+ sublists' l
[PROOFSTEP]
simp
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
n : ℕ
a : α
l : List α
⊢ sublistsLen (n + 1) (a :: l) <+ sublists' (a :: l)
[PROOFSTEP]
rw [sublistsLen_succ_cons, sublists'_cons]
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
n : ℕ
a : α
l : List α
⊢ sublistsLen (n + 1) l ++ map (cons a) (sublistsLen n l) <+ sublists' l ++ map (cons a) (sublists' l)
[PROOFSTEP]
exact (sublistsLen_sublist_sublists' _ _).append ((sublistsLen_sublist_sublists' _ _).map _)
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
n : ℕ
l₁ l₂ : List α
h : l₁ <+ l₂
⊢ sublistsLen n l₁ <+ sublistsLen n l₂
[PROOFSTEP]
induction' n with n IHn generalizing l₁ l₂
[GOAL]
case zero
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l₁✝ l₂✝ : List α
h✝ : l₁✝ <+ l₂✝
l₁ l₂ : List α
h : l₁ <+ l₂
⊢ sublistsLen zero l₁ <+ sublistsLen zero l₂
[PROOFSTEP]
simp
[GOAL]
case succ
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l₁✝ l₂✝ : List α
h✝ : l₁✝ <+ l₂✝
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → sublistsLen n l₁ <+ sublistsLen n l₂
l₁ l₂ : List α
h : l₁ <+ l₂
⊢ sublistsLen (succ n) l₁ <+ sublistsLen (succ n) l₂
[PROOFSTEP]
induction' h with l₁ l₂ a _ IH l₁ l₂ a s IH
[GOAL]
case succ.slnil
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l₁✝ l₂✝ : List α
h : l₁✝ <+ l₂✝
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → sublistsLen n l₁ <+ sublistsLen n l₂
l₁ l₂ : List α
⊢ sublistsLen (succ n) [] <+ sublistsLen (succ n) []
[PROOFSTEP]
rfl
[GOAL]
case succ.cons
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l₁✝¹ l₂✝¹ : List α
h : l₁✝¹ <+ l₂✝¹
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → sublistsLen n l₁ <+ sublistsLen n l₂
l₁✝ l₂✝ l₁ l₂ : List α
a : α
a✝ : l₁ <+ l₂
IH : sublistsLen (succ n) l₁ <+ sublistsLen (succ n) l₂
⊢ sublistsLen (succ n) l₁ <+ sublistsLen (succ n) (a :: l₂)
[PROOFSTEP]
refine' IH.trans _
[GOAL]
case succ.cons
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l₁✝¹ l₂✝¹ : List α
h : l₁✝¹ <+ l₂✝¹
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → sublistsLen n l₁ <+ sublistsLen n l₂
l₁✝ l₂✝ l₁ l₂ : List α
a : α
a✝ : l₁ <+ l₂
IH : sublistsLen (succ n) l₁ <+ sublistsLen (succ n) l₂
⊢ sublistsLen (succ n) l₂ <+ sublistsLen (succ n) (a :: l₂)
[PROOFSTEP]
rw [sublistsLen_succ_cons]
[GOAL]
case succ.cons
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l₁✝¹ l₂✝¹ : List α
h : l₁✝¹ <+ l₂✝¹
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → sublistsLen n l₁ <+ sublistsLen n l₂
l₁✝ l₂✝ l₁ l₂ : List α
a : α
a✝ : l₁ <+ l₂
IH : sublistsLen (succ n) l₁ <+ sublistsLen (succ n) l₂
⊢ sublistsLen (succ n) l₂ <+ sublistsLen (n + 1) l₂ ++ map (cons a) (sublistsLen n l₂)
[PROOFSTEP]
apply sublist_append_left
[GOAL]
case succ.cons₂
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l₁✝¹ l₂✝¹ : List α
h : l₁✝¹ <+ l₂✝¹
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → sublistsLen n l₁ <+ sublistsLen n l₂
l₁✝ l₂✝ l₁ l₂ : List α
a : α
s : l₁ <+ l₂
IH : sublistsLen (succ n) l₁ <+ sublistsLen (succ n) l₂
⊢ sublistsLen (succ n) (a :: l₁) <+ sublistsLen (succ n) (a :: l₂)
[PROOFSTEP]
simp [sublistsLen_succ_cons]
[GOAL]
case succ.cons₂
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l₁✝¹ l₂✝¹ : List α
h : l₁✝¹ <+ l₂✝¹
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → sublistsLen n l₁ <+ sublistsLen n l₂
l₁✝ l₂✝ l₁ l₂ : List α
a : α
s : l₁ <+ l₂
IH : sublistsLen (succ n) l₁ <+ sublistsLen (succ n) l₂
⊢ sublistsLen (n + 1) l₁ ++ map (cons a) (sublistsLen n l₁) <+ sublistsLen (n + 1) l₂ ++ map (cons a) (sublistsLen n l₂)
[PROOFSTEP]
exact IH.append ((IHn s).map _)
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l l' : List α
h : l' ∈ sublistsLen 0 l
⊢ length l' = 0
[PROOFSTEP]
simp_all
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
n : ℕ
a : α
l l' : List α
h : l' ∈ sublistsLen (n + 1) (a :: l)
⊢ length l' = n + 1
[PROOFSTEP]
rw [sublistsLen_succ_cons, mem_append, mem_map] at h
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
n : ℕ
a : α
l l' : List α
h : l' ∈ sublistsLen (n + 1) l ∨ ∃ a_1, a_1 ∈ sublistsLen n l ∧ a :: a_1 = l'
⊢ length l' = n + 1
[PROOFSTEP]
rcases h with (h | ⟨l', h, rfl⟩)
[GOAL]
case inl
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
n : ℕ
a : α
l l' : List α
h : l' ∈ sublistsLen (n + 1) l
⊢ length l' = n + 1
[PROOFSTEP]
exact length_of_sublistsLen h
[GOAL]
case inr.intro.intro
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
n : ℕ
a : α
l l' : List α
h : l' ∈ sublistsLen n l
⊢ length (a :: l') = n + 1
[PROOFSTEP]
exact congr_arg (· + 1) (length_of_sublistsLen h)
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l l' : List α
h : l' <+ l
⊢ l' ∈ sublistsLen (length l') l
[PROOFSTEP]
induction' h with l₁ l₂ a s IH l₁ l₂ a s IH
[GOAL]
case slnil
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l l' : List α
⊢ [] ∈ sublistsLen (length []) []
[PROOFSTEP]
simp
[GOAL]
case cons
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l l' l₁ l₂ : List α
a : α
s : l₁ <+ l₂
IH : l₁ ∈ sublistsLen (length l₁) l₂
⊢ l₁ ∈ sublistsLen (length l₁) (a :: l₂)
[PROOFSTEP]
cases' l₁ with b l₁
[GOAL]
case cons.nil
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l l' l₂ : List α
a : α
s : [] <+ l₂
IH : [] ∈ sublistsLen (length []) l₂
⊢ [] ∈ sublistsLen (length []) (a :: l₂)
[PROOFSTEP]
simp
[GOAL]
case cons.cons
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l l' l₂ : List α
a b : α
l₁ : List α
s : b :: l₁ <+ l₂
IH : b :: l₁ ∈ sublistsLen (length (b :: l₁)) l₂
⊢ b :: l₁ ∈ sublistsLen (length (b :: l₁)) (a :: l₂)
[PROOFSTEP]
rw [length, sublistsLen_succ_cons]
[GOAL]
case cons.cons
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l l' l₂ : List α
a b : α
l₁ : List α
s : b :: l₁ <+ l₂
IH : b :: l₁ ∈ sublistsLen (length (b :: l₁)) l₂
⊢ b :: l₁ ∈ sublistsLen (length l₁ + 1) l₂ ++ map (cons a) (sublistsLen (length l₁) l₂)
[PROOFSTEP]
exact mem_append_left _ IH
[GOAL]
case cons₂
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l l' l₁ l₂ : List α
a : α
s : l₁ <+ l₂
IH : l₁ ∈ sublistsLen (length l₁) l₂
⊢ a :: l₁ ∈ sublistsLen (length (a :: l₁)) (a :: l₂)
[PROOFSTEP]
rw [length, sublistsLen_succ_cons]
[GOAL]
case cons₂
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l l' l₁ l₂ : List α
a : α
s : l₁ <+ l₂
IH : l₁ ∈ sublistsLen (length l₁) l₂
⊢ a :: l₁ ∈ sublistsLen (length l₁ + 1) l₂ ++ map (cons a) (sublistsLen (length l₁) l₂)
[PROOFSTEP]
exact mem_append_right _ (mem_map.2 ⟨_, IH, rfl⟩)
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
l : List α
⊢ sublistsLen (length (a :: l)) (a :: l) = [a :: l]
[PROOFSTEP]
simp only [length, sublistsLen_succ_cons, sublistsLen_length, map, sublistsLen_of_length_lt (lt_succ_self _),
  nil_append]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
a : α
l : List α
H₁ : ∀ (a' : α), a' ∈ l → R a a'
H₂ : Pairwise R l
⊢ Pairwise (Lex (swap R)) (List.sublists' (a :: l))
[PROOFSTEP]
simp only [sublists'_cons, pairwise_append, pairwise_map, mem_sublists', mem_map, exists_imp, and_imp]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
a : α
l : List α
H₁ : ∀ (a' : α), a' ∈ l → R a a'
H₂ : Pairwise R l
⊢ Pairwise (Lex (swap R)) (List.sublists' l) ∧
    Pairwise (fun a_1 b => Lex (swap R) (a :: a_1) (a :: b)) (List.sublists' l) ∧
      ∀ (a_1 : List α), a_1 <+ l → ∀ (b x : List α), x <+ l → a :: x = b → Lex (swap R) a_1 b
[PROOFSTEP]
refine' ⟨H₂.sublists', H₂.sublists'.imp fun l₁ => Lex.cons l₁, _⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
a : α
l : List α
H₁ : ∀ (a' : α), a' ∈ l → R a a'
H₂ : Pairwise R l
⊢ ∀ (a_1 : List α), a_1 <+ l → ∀ (b x : List α), x <+ l → a :: x = b → Lex (swap R) a_1 b
[PROOFSTEP]
rintro l₁ sl₁ x l₂ _ rfl
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
a : α
l : List α
H₁ : ∀ (a' : α), a' ∈ l → R a a'
H₂ : Pairwise R l
l₁ : List α
sl₁ : l₁ <+ l
l₂ : List α
a✝ : l₂ <+ l
⊢ Lex (swap R) l₁ (a :: l₂)
[PROOFSTEP]
cases' l₁ with b l₁
[GOAL]
case nil
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
a : α
l : List α
H₁ : ∀ (a' : α), a' ∈ l → R a a'
H₂ : Pairwise R l
l₂ : List α
a✝ : l₂ <+ l
sl₁ : [] <+ l
⊢ Lex (swap R) [] (a :: l₂)
[PROOFSTEP]
constructor
[GOAL]
case cons
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
a : α
l : List α
H₁ : ∀ (a' : α), a' ∈ l → R a a'
H₂ : Pairwise R l
l₂ : List α
a✝ : l₂ <+ l
b : α
l₁ : List α
sl₁ : b :: l₁ <+ l
⊢ Lex (swap R) (b :: l₁) (a :: l₂)
[PROOFSTEP]
exact Lex.rel (H₁ _ <| sl₁.subset <| mem_cons_self _ _)
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
l : List α
H : Pairwise R l
⊢ Pairwise (fun l₁ l₂ => Lex R (reverse l₁) (reverse l₂)) (sublists l)
[PROOFSTEP]
have := (pairwise_reverse.2 H).sublists'
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
l : List α
H : Pairwise R l
this : Pairwise (Lex (swap fun b a => R a b)) (sublists' (reverse l))
⊢ Pairwise (fun l₁ l₂ => Lex R (reverse l₁) (reverse l₂)) (sublists l)
[PROOFSTEP]
rwa [sublists'_reverse, pairwise_map] at this
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
h✝ : Nodup l
l₁ l₂ : List α
h : Lex (fun x x_1 => x ≠ x_1) (reverse l₁) (reverse l₂)
⊢ l₁ ≠ l₂
[PROOFSTEP]
simpa using h.to_ne
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ Nodup (sublists' l) ↔ Nodup l
[PROOFSTEP]
rw [sublists'_eq_sublists, nodup_map_iff reverse_injective, nodup_sublists, nodup_reverse]
[GOAL]
α : Type u
β : Type v
γ : Type w
n : ℕ
l : List α
h : Nodup l
⊢ Nodup (sublistsLen n l)
[PROOFSTEP]
have : Pairwise (· ≠ ·) l.sublists' :=
  Pairwise.imp (fun h => Lex.to_ne (by convert h using 3; simp [swap, eq_comm])) h.sublists'
[GOAL]
α : 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✝
[PROOFSTEP]
convert h using 3
[GOAL]
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
[PROOFSTEP]
simp [swap, eq_comm]
[GOAL]
α : 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)
[PROOFSTEP]
exact this.sublist (sublistsLen_sublist_sublists' _ _)
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
⊢ sublists (map f []) = map (map f) (sublists [])
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
l : List α
⊢ sublists (map f (a :: l)) = map (map f) (sublists (a :: l))
[PROOFSTEP]
rw [map_cons, sublists_cons, bind_eq_bind, sublists_map f l, sublists_cons, bind_eq_bind, map_eq_bind, map_eq_bind]
[GOAL]
α : 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]
[PROOFSTEP]
induction sublists l
[GOAL]
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]
[PROOFSTEP]
simp [*]
  --Porting note: new theorem
[GOAL]
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]
[PROOFSTEP]
simp [*]
  --Porting note: new theorem
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
⊢ sublists' (map f []) = map (map f) (sublists' [])
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
l : List α
⊢ sublists' (map f (a :: l)) = map (map f) (sublists' (a :: l))
[PROOFSTEP]
simp [map_cons, sublists'_cons, sublists'_map f l, Function.comp]
  --Porting note: moved because it is now used to prove `sublists_cons_perm_append`
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ sublists l ~ sublists' l
[PROOFSTEP]
rw [← finRange_map_get l, sublists_map, sublists'_map]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ map (map (get l)) (sublists (finRange (length l))) ~ map (map (get l)) (sublists' (finRange (length l)))
[PROOFSTEP]
refine' Perm.map _ _
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ sublists (finRange (length l)) ~ sublists' (finRange (length l))
[PROOFSTEP]
exact (perm_ext (nodup_sublists.2 (nodup_finRange _)) (nodup_sublists'.2 (nodup_finRange _))).2 (by simp)
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ ∀ (a : List (Fin (length l))), a ∈ sublists (finRange (length l)) ↔ a ∈ sublists' (finRange (length l))
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
l : List α
⊢ sublists' (a :: l) ~ sublists l ++ map (cons a) (sublists l)
[PROOFSTEP]
rw [sublists'_cons]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
l : List α
⊢ sublists' l ++ map (cons a) (sublists' l) ~ sublists l ++ map (cons a) (sublists l)
[PROOFSTEP]
exact Perm.append (sublists_perm_sublists' _).symm (Perm.map _ (sublists_perm_sublists' _).symm)
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ revzip (sublists l) → l₁ ++ l₂ ~ l
[PROOFSTEP]
rw [revzip]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists l) (reverse (sublists l)) → l₁ ++ l₂ ~ l
[PROOFSTEP]
induction' l using List.reverseRecOn with l' a ih
[GOAL]
case H0
α : Type u
β : Type v
γ : Type w
⊢ ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists []) (reverse (sublists [])) → l₁ ++ l₂ ~ []
[PROOFSTEP]
intro l₁ l₂ h
[GOAL]
case H0
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
h : (l₁, l₂) ∈ zip (sublists []) (reverse (sublists []))
⊢ l₁ ++ l₂ ~ []
[PROOFSTEP]
simp at h
[GOAL]
case H0
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
h : l₁ = [] ∧ l₂ = []
⊢ l₁ ++ l₂ ~ []
[PROOFSTEP]
simp [h]
[GOAL]
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]
[PROOFSTEP]
intro l₁ l₂ h
[GOAL]
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]
[PROOFSTEP]
rw [sublists_concat, reverse_append, zip_append, ← map_reverse, zip_map_right, zip_map_left] at * <;> [skip; simp]
[GOAL]
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]
[PROOFSTEP]
rw [sublists_concat, reverse_append, zip_append, ← map_reverse, zip_map_right, zip_map_left] at *
[GOAL]
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]
[PROOFSTEP]
skip
[GOAL]
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')))
[PROOFSTEP]
simp
[GOAL]
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]
[PROOFSTEP]
simp only [Prod.mk.inj_iff, mem_map, mem_append, Prod.map_mk, Prod.exists] at h
[GOAL]
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]
[PROOFSTEP]
rcases h with (⟨l₁, l₂', h, rfl, rfl⟩ | ⟨l₁', l₂, h, rfl, rfl⟩)
[GOAL]
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]
[PROOFSTEP]
rw [← append_assoc]
[GOAL]
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]
[PROOFSTEP]
exact (ih _ _ h).append_right _
[GOAL]
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]
[PROOFSTEP]
rw [append_assoc]
[GOAL]
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]
[PROOFSTEP]
apply (perm_append_comm.append_left _).trans
[GOAL]
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]
[PROOFSTEP]
rw [← append_assoc]
[GOAL]
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]
[PROOFSTEP]
exact (ih _ _ h).append_right _
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ revzip (sublists' l) → l₁ ++ l₂ ~ l
[PROOFSTEP]
rw [revzip]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists' l) (reverse (sublists' l)) → l₁ ++ l₂ ~ l
[PROOFSTEP]
induction' l with a l IH
[GOAL]
case nil
α : Type u
β : Type v
γ : Type w
⊢ ∀ (l₁ l₂ : List α), (l₁, l₂) ∈ zip (sublists' []) (reverse (sublists' [])) → l₁ ++ l₂ ~ []
[PROOFSTEP]
intro l₁ l₂ h
[GOAL]
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
[PROOFSTEP]
intro l₁ l₂ h
[GOAL]
case nil
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
h : (l₁, l₂) ∈ zip (sublists' []) (reverse (sublists' []))
⊢ l₁ ++ l₂ ~ []
[PROOFSTEP]
simp at h
[GOAL]
case nil
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
h : l₁ = [] ∧ l₂ = []
⊢ l₁ ++ l₂ ~ []
[PROOFSTEP]
simp [h]
[GOAL]
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 α
h : (l₁, l₂) ∈ zip (sublists' (a :: l)) (reverse (sublists' (a :: l)))
⊢ l₁ ++ l₂ ~ a :: l
[PROOFSTEP]
rw [sublists'_cons, reverse_append, zip_append, ← map_reverse, zip_map_right, zip_map_left] at * <;> [simp at h ; simp]
[GOAL]
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 α
h : (l₁, l₂) ∈ zip (sublists' (a :: l)) (reverse (sublists' (a :: l)))
⊢ l₁ ++ l₂ ~ a :: l
[PROOFSTEP]
rw [sublists'_cons, reverse_append, zip_append, ← map_reverse, zip_map_right, zip_map_left] at *
[GOAL]
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 α
h :
  (l₁, l₂) ∈
    map (Prod.map id (cons a)) (zip (sublists' l) (reverse (sublists' l))) ++
      map (Prod.map (cons a) id) (zip (sublists' l) (reverse (sublists' l)))
⊢ l₁ ++ l₂ ~ a :: l
[PROOFSTEP]
simp at h
[GOAL]
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 α
h :
  (l₁, l₂) ∈
    zip (sublists' l ++ map (cons a) (sublists' l)) (reverse (map (cons a) (sublists' l)) ++ reverse (sublists' l))
⊢ length (sublists' l) = length (reverse (map (cons a) (sublists' l)))
[PROOFSTEP]
simp
[GOAL]
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 α
h :
  (∃ a_1 b, (a_1, b) ∈ zip (sublists' l) (reverse (sublists' l)) ∧ a_1 = l₁ ∧ a :: b = l₂) ∨
    ∃ a_1, (a_1, l₂) ∈ zip (sublists' l) (reverse (sublists' l)) ∧ a :: a_1 = l₁
⊢ l₁ ++ l₂ ~ a :: l
[PROOFSTEP]
rcases h with (⟨l₁, l₂', h, rfl, rfl⟩ | ⟨l₁', h, rfl⟩)
[GOAL]
case cons.inl.intro.intro.intro.intro
α : 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 α
h : (l₁, l₂') ∈ zip (sublists' l) (reverse (sublists' l))
⊢ l₁ ++ a :: l₂' ~ a :: l
[PROOFSTEP]
exact perm_middle.trans ((IH _ _ h).cons _)
[GOAL]
case cons.inr.intro.intro
α : 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 α
h : (l₁', l₂) ∈ zip (sublists' l) (reverse (sublists' l))
⊢ a :: l₁' ++ l₂ ~ a :: l
[PROOFSTEP]
exact (IH _ _ h).cons _
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
l : List α
⊢ (List.bind (range (length l + 1)) fun n => sublistsLen n l) ~ sublists' l
[PROOFSTEP]
induction' l with h tl l_ih
[GOAL]
case nil
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
⊢ (List.bind (range (length [] + 1)) fun n => sublistsLen n []) ~ sublists' []
[PROOFSTEP]
simp [range_succ]
[GOAL]
case cons
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
h : α
tl : List α
l_ih : (List.bind (range (length tl + 1)) fun n => sublistsLen n tl) ~ sublists' tl
⊢ (List.bind (range (length (h :: tl) + 1)) fun n => sublistsLen n (h :: tl)) ~ sublists' (h :: tl)
[PROOFSTEP]
simp_rw [range_succ_eq_map, length, cons_bind, map_bind, sublistsLen_succ_cons, sublists'_cons, List.sublistsLen_zero,
  List.singleton_append]
[GOAL]
case cons
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
h : α
tl : List α
l_ih : (List.bind (range (length tl + 1)) fun n => sublistsLen n tl) ~ sublists' tl
⊢ ([] :: List.bind (range (length tl + 1)) fun a => sublistsLen (a + 1) tl ++ map (cons h) (sublistsLen a tl)) ~
    sublists' tl ++ map (cons h) (sublists' tl)
[PROOFSTEP]
refine' ((bind_append_perm (range (tl.length + 1)) _ _).symm.cons _).trans _
[GOAL]
case cons
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
h : α
tl : List α
l_ih : (List.bind (range (length tl + 1)) fun n => sublistsLen n tl) ~ sublists' tl
⊢ [] ::
      ((List.bind (range (length tl + 1)) fun a => sublistsLen (a + 1) tl) ++
        List.bind (range (length tl + 1)) fun a => map (cons h) (sublistsLen a tl)) ~
    sublists' tl ++ map (cons h) (sublists' tl)
[PROOFSTEP]
simp_rw [← List.bind_map, ← cons_append]
[GOAL]
case cons
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
h : α
tl : List α
l_ih : (List.bind (range (length tl + 1)) fun n => sublistsLen n tl) ~ sublists' tl
⊢ ([] :: List.bind (range (length tl + 1)) fun a => sublistsLen (a + 1) tl) ++
      map (cons h) (List.bind (range (length tl + 1)) fun a => sublistsLen a tl) ~
    sublists' tl ++ map (cons h) (sublists' tl)
[PROOFSTEP]
rw [← List.singleton_append, ← List.sublistsLen_zero tl]
[GOAL]
case cons
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
h : α
tl : List α
l_ih : (List.bind (range (length tl + 1)) fun n => sublistsLen n tl) ~ sublists' tl
⊢ (sublistsLen 0 tl ++ List.bind (range (length tl + 1)) fun a => sublistsLen (a + 1) tl) ++
      map (cons h) (List.bind (range (length tl + 1)) fun a => sublistsLen a tl) ~
    sublists' tl ++ map (cons h) (sublists' tl)
[PROOFSTEP]
refine' Perm.append _ (l_ih.map _)
[GOAL]
case cons
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
h : α
tl : List α
l_ih : (List.bind (range (length tl + 1)) fun n => sublistsLen n tl) ~ sublists' tl
⊢ (sublistsLen 0 tl ++ List.bind (range (length tl + 1)) fun a => sublistsLen (a + 1) tl) ~ sublists' tl
[PROOFSTEP]
rw [List.range_succ, append_bind, bind_singleton, sublistsLen_of_length_lt (Nat.lt_succ_self _), append_nil, ←
  List.map_bind (fun n => sublistsLen n tl) Nat.succ, ← cons_bind 0 _ fun n => sublistsLen n tl, ← range_succ_eq_map]
[GOAL]
case cons
α✝ : Type u
β : Type v
γ : Type w
α : Type u_1
h : α
tl : List α
l_ih : (List.bind (range (length tl + 1)) fun n => sublistsLen n tl) ~ sublists' tl
⊢ (List.bind (range (length tl + 1)) fun n => sublistsLen n tl) ~ sublists' tl
[PROOFSTEP]
exact l_ih


[GOAL]
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
m : Multiset α
a : α
x✝ : List α
⊢ count a (dedup (Quot.mk Setoid.r x✝)) = if a ∈ Quot.mk Setoid.r x✝ then 1 else 0
[PROOFSTEP]
simp only [quot_mk_to_coe'', coe_dedup, mem_coe, List.mem_dedup, coe_nodup, coe_count]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
m : Multiset α
a : α
x✝ : List α
⊢ List.count a (List.dedup x✝) = if a ∈ x✝ then 1 else 0
[PROOFSTEP]
apply List.count_dedup _ _
[GOAL]
α : Type u_1
β : Type u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
m : Multiset α
f : α → Multiset β
⊢ dedup (bind (dedup m) f) = dedup (bind m f)
[PROOFSTEP]
ext x
[GOAL]
case a
α : Type u_1
β : Type u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
m : Multiset α
f : α → Multiset β
x : β
⊢ count x (dedup (bind (dedup m) f)) = count x (dedup (bind m f))
[PROOFSTEP]
simp_rw [count_dedup]
[GOAL]
case a
α : Type u_1
β : Type u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
m : Multiset α
f : α → Multiset β
x : β
⊢ (if x ∈ bind (dedup m) f then 1 else 0) = if x ∈ bind m f then 1 else 0
[PROOFSTEP]
refine if_congr ?_ rfl rfl
[GOAL]
case a
α : Type u_1
β : Type u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
m : Multiset α
f : α → Multiset β
x : β
⊢ x ∈ bind (dedup m) f ↔ x ∈ bind m f
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
s : Multiset α
⊢ s ≤ dedup s ↔ Nodup s
[PROOFSTEP]
rw [le_dedup, and_iff_right le_rfl]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
s t : Multiset α
⊢ dedup s = dedup t ↔ ∀ (a : α), a ∈ s ↔ a ∈ t
[PROOFSTEP]
simp [Nodup.ext]
[GOAL]
α : Type u_1
β : Type u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
f : α → β
s : Multiset α
⊢ dedup (map f (dedup s)) = dedup (map f s)
[PROOFSTEP]
simp [dedup_ext]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
s : Multiset α
n : ℕ
h0 : n ≠ 0
⊢ dedup (n • s) = dedup s
[PROOFSTEP]
ext a
[GOAL]
case a
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
s : Multiset α
n : ℕ
h0 : n ≠ 0
a : α
⊢ count a (dedup (n • s)) = count a (dedup s)
[PROOFSTEP]
by_cases h : a ∈ s
[GOAL]
case pos
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
s : Multiset α
n : ℕ
h0 : n ≠ 0
a : α
h : a ∈ s
⊢ count a (dedup (n • s)) = count a (dedup s)
[PROOFSTEP]
simp [h, h0]
[GOAL]
case neg
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
s : Multiset α
n : ℕ
h0 : n ≠ 0
a : α
h : ¬a ∈ s
⊢ count a (dedup (n • s)) = count a (dedup s)
[PROOFSTEP]
simp [h, h0]
[GOAL]
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
s t : Multiset α
hno : Nodup s
⊢ s ≤ Multiset.dedup t ↔ s ≤ t
[PROOFSTEP]
simp [le_dedup, hno]
[GOAL]
α : Type u_1
s t : Multiset α
n : ℕ
h : Nodup s
hn : n ≠ 0
⊢ s ≤ n • t ↔ s ≤ t
[PROOFSTEP]
classical
rw [← h.le_dedup_iff_le, Iff.comm, ← h.le_dedup_iff_le]
simp [hn]
[GOAL]
α : Type u_1
s t : Multiset α
n : ℕ
h : Nodup s
hn : n ≠ 0
⊢ s ≤ n • t ↔ s ≤ t
[PROOFSTEP]
rw [← h.le_dedup_iff_le, Iff.comm, ← h.le_dedup_iff_le]
[GOAL]
α : Type u_1
s t : Multiset α
n : ℕ
h : Nodup s
hn : n ≠ 0
⊢ s ≤ Multiset.dedup t ↔ s ≤ Multiset.dedup (n • t)
[PROOFSTEP]
simp [hn]


[GOAL]
X✝ : Type u
Y : Type v
inst✝² : TopologicalSpace X✝
inst✝¹ : TopologicalSpace Y
x₀ x₁ : X✝
X : Type u
inst✝ : TopologicalSpace X
x : X
⊢ Group (FundamentalGroup X x)
[PROOFSTEP]
dsimp only [FundamentalGroup]
[GOAL]
X✝ : Type u
Y : Type v
inst✝² : TopologicalSpace X✝
inst✝¹ : TopologicalSpace Y
x₀ x₁ : X✝
X : Type u
inst✝ : TopologicalSpace X
x : X
⊢ Group (Aut x)
[PROOFSTEP]
infer_instance
[GOAL]
X✝ : Type u
Y : Type v
inst✝² : TopologicalSpace X✝
inst✝¹ : TopologicalSpace Y
x₀ x₁ : X✝
X : Type u
inst✝ : TopologicalSpace X
x : X
⊢ Inhabited (FundamentalGroup X x)
[PROOFSTEP]
dsimp only [FundamentalGroup]
[GOAL]
X✝ : Type u
Y : Type v
inst✝² : TopologicalSpace X✝
inst✝¹ : TopologicalSpace Y
x₀ x₁ : X✝
X : Type u
inst✝ : TopologicalSpace X
x : X
⊢ Inhabited (Aut x)
[PROOFSTEP]
infer_instance