l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem powerset_cons (a : α) (s) : powerset (a ::ₘ s) = powerset s + map (cons a) (powerset s) :=
  Quotient.inductionOn s fun l => by simp; 

Proof state:
α : Type u_1
a : α
s : Multiset α
l : List α
⊢ List.map ofList (sublists' l) ++ List.map (ofList ∘ List.cons a) (sublists' l) ~
    List.map ofList (sublists' l) ++ List.map ((fun x => a ::ₘ x) ∘ ofList) (sublists' l)

Next tactic:
rfl
@[simp]
theorem mem_powerset {s t : Multiset α} : s ∈ powerset t ↔ s ≤ t :=
  Quotient.inductionOn₂ s t <| by 

Proof state:
α : Type u_1
s t : Multiset α
⊢ ∀ (a b : List α), ⟦a⟧ ∈ powerset ⟦b⟧ ↔ ⟦a⟧ ≤ ⟦b⟧

Next tactic:
simp [Subperm, and_comm]
theorem map_single_le_powerset (s : Multiset α) : s.map singleton ≤ powerset s :=
  Quotient.inductionOn s fun l => by
    

Proof state:
α : Type u_1
s : Multiset α
l : List α
⊢ map singleton ⟦l⟧ ≤ powerset ⟦l⟧

Next tactic:
simp only [powerset_coe, quot_mk_to_coe, coe_le, coe_map]
theorem map_single_le_powerset (s : Multiset α) : s.map singleton ≤ powerset s :=
  Quotient.inductionOn s fun l => by
    simp only [powerset_coe, quot_mk_to_coe, coe_le, coe_map]
    

Proof state:
α : Type u_1
s : Multiset α
l : List α
⊢ List.map singleton l <+~ List.map ofList (sublists l)

Next tactic:
show l.map (((↑) : List α → Multiset α) ∘ List.ret) <+~ (sublists l).map (↑)
theorem map_single_le_powerset (s : Multiset α) : s.map singleton ≤ powerset s :=
  Quotient.inductionOn s fun l => by
    simp only [powerset_coe, quot_mk_to_coe, coe_le, coe_map]
    show l.map (((↑) : List α → Multiset α) ∘ List.ret) <+~ (sublists l).map (↑)
    

Proof state:
α : Type u_1
s : Multiset α
l : List α
⊢ List.map (ofList ∘ List.ret) l <+~ List.map ofList (sublists l)

Next tactic:
rw [← List.map_map]
theorem map_single_le_powerset (s : Multiset α) : s.map singleton ≤ powerset s :=
  Quotient.inductionOn s fun l => by
    simp only [powerset_coe, quot_mk_to_coe, coe_le, coe_map]
    show l.map (((↑) : List α → Multiset α) ∘ List.ret) <+~ (sublists l).map (↑)
    rw [← List.map_map]
    

Proof state:
α : Type u_1
s : Multiset α
l : List α
⊢ List.map ofList (List.map List.ret l) <+~ List.map ofList (sublists l)

Next tactic:
exact ((map_ret_sublist_sublists _).map _).subperm
@[simp]
theorem card_powerset (s : Multiset α) : card (powerset s) = 2 ^ card s :=
  Quotient.inductionOn s <| by 

Proof state:
α : Type u_1
s : Multiset α
⊢ ∀ (a : List α), card (powerset ⟦a⟧) = 2 ^ card ⟦a⟧

Next tactic:
simp
theorem revzip_powersetAux {l : List α} ⦃x⦄ (h : x ∈ revzip (powersetAux l)) : x.1 + x.2 = ↑l := by
  

Proof state:
α : Type u_1
l : List α
x : Multiset α × Multiset α
h : x ∈ revzip (powersetAux l)
⊢ x.1 + x.2 = ↑l

Next tactic:
rw [revzip, powersetAux_eq_map_coe, ← map_reverse, zip_map, ← revzip, List.mem_map] at h
theorem revzip_powersetAux {l : List α} ⦃x⦄ (h : x ∈ revzip (powersetAux l)) : x.1 + x.2 = ↑l := by
  rw [revzip, powersetAux_eq_map_coe, ← map_reverse, zip_map, ← revzip, List.mem_map] at h
  

Proof state:
α : Type u_1
l : List α
x : Multiset α × Multiset α
h : ∃ a ∈ revzip (sublists l), Prod.map ofList ofList a = x
⊢ x.1 + x.2 = ↑l

Next tactic:
simp only [Prod_map, Prod.exists] at h
theorem revzip_powersetAux {l : List α} ⦃x⦄ (h : x ∈ revzip (powersetAux l)) : x.1 + x.2 = ↑l := by
  rw [revzip, powersetAux_eq_map_coe, ← map_reverse, zip_map, ← revzip, List.mem_map] at h
  simp only [Prod_map, Prod.exists] at h
  

Proof state:
α : Type u_1
l : List α
x : Multiset α × Multiset α
h : ∃ a b, (a, b) ∈ revzip (sublists l) ∧ (↑a, ↑b) = x
⊢ x.1 + x.2 = ↑l

Next tactic:
rcases h with ⟨l₁, l₂, h, rfl, rfl⟩
theorem revzip_powersetAux {l : List α} ⦃x⦄ (h : x ∈ revzip (powersetAux l)) : x.1 + x.2 = ↑l := by
  rw [revzip, powersetAux_eq_map_coe, ← map_reverse, zip_map, ← revzip, List.mem_map] at h
  simp only [Prod_map, Prod.exists] at h
  rcases h with ⟨l₁, l₂, h, rfl, rfl⟩
  

Proof state:
case intro.intro.intro.refl
α : Type u_1
l l₁ l₂ : List α
h : (l₁, l₂) ∈ revzip (sublists l)
⊢ (↑l₁, ↑l₂).1 + (↑l₁, ↑l₂).2 = ↑l

Next tactic:
exact Quot.sound (revzip_sublists _ _ _ h)
theorem revzip_powersetAux' {l : List α} ⦃x⦄ (h : x ∈ revzip (powersetAux' l)) :
    x.1 + x.2 = ↑l := by
  

Proof state:
α : Type u_1
l : List α
x : Multiset α × Multiset α
h : x ∈ revzip (powersetAux' l)
⊢ x.1 + x.2 = ↑l

Next tactic:
rw [revzip, powersetAux', ← map_reverse, zip_map, ← revzip, List.mem_map] at h
theorem revzip_powersetAux' {l : List α} ⦃x⦄ (h : x ∈ revzip (powersetAux' l)) :
    x.1 + x.2 = ↑l := by
  rw [revzip, powersetAux', ← map_reverse, zip_map, ← revzip, List.mem_map] at h
  

Proof state:
α : Type u_1
l : List α
x : Multiset α × Multiset α
h : ∃ a ∈ revzip (sublists' l), Prod.map ofList ofList a = x
⊢ x.1 + x.2 = ↑l

Next tactic:
simp only [Prod_map, Prod.exists] at h
theorem revzip_powersetAux' {l : List α} ⦃x⦄ (h : x ∈ revzip (powersetAux' l)) :
    x.1 + x.2 = ↑l := by
  rw [revzip, powersetAux', ← map_reverse, zip_map, ← revzip, List.mem_map] at h
  simp only [Prod_map, Prod.exists] at h
  

Proof state:
α : Type u_1
l : List α
x : Multiset α × Multiset α
h : ∃ a b, (a, b) ∈ revzip (sublists' l) ∧ (↑a, ↑b) = x
⊢ x.1 + x.2 = ↑l

Next tactic:
rcases h with ⟨l₁, l₂, h, rfl, rfl⟩
theorem revzip_powersetAux' {l : List α} ⦃x⦄ (h : x ∈ revzip (powersetAux' l)) :
    x.1 + x.2 = ↑l := by
  rw [revzip, powersetAux', ← map_reverse, zip_map, ← revzip, List.mem_map] at h
  simp only [Prod_map, Prod.exists] at h
  rcases h with ⟨l₁, l₂, h, rfl, rfl⟩
  

Proof state:
case intro.intro.intro.refl
α : Type u_1
l l₁ l₂ : List α
h : (l₁, l₂) ∈ revzip (sublists' l)
⊢ (↑l₁, ↑l₂).1 + (↑l₁, ↑l₂).2 = ↑l

Next tactic:
exact Quot.sound (revzip_sublists' _ _ _ h)
theorem revzip_powersetAux_lemma {α : Type u} [DecidableEq α] (l : List α) {l' : List (Multiset α)}
    (H : ∀ ⦃x : _ × _⦄, x ∈ revzip l' → x.1 + x.2 = ↑l) :
    revzip l' = l'.map fun x => (x, (l : Multiset α) - x) := by
  

Proof state:
α✝ : Type u_1
α : Type u
inst✝ : DecidableEq α
l : List α
l' : List (Multiset α)
H : ∀ ⦃x : Multiset α × Multiset α⦄, x ∈ revzip l' → x.1 + x.2 = ↑l
⊢ revzip l' = List.map (fun x => (x, ↑l - x)) l'

Next tactic:
have :
    Forall₂ (fun (p : Multiset α × Multiset α) (s : Multiset α) => p = (s, ↑l - s)) (revzip l')
      ((revzip l').map Prod.fst) := by
    rw [forall₂_map_right_iff, forall₂_same]
    rintro ⟨s, t⟩ h
    dsimp
    rw [← H h, add_tsub_cancel_left]
theorem revzip_powersetAux_lemma {α : Type u} [DecidableEq α] (l : List α) {l' : List (Multiset α)}
    (H : ∀ ⦃x : _ × _⦄, x ∈ revzip l' → x.1 + x.2 = ↑l) :
    revzip l' = l'.map fun x => (x, (l : Multiset α) - x) := by
  have :
    Forall₂ (fun (p : Multiset α × Multiset α) (s : Multiset α) => p = (s, ↑l - s)) (revzip l')
      ((revzip l').map Prod.fst) := by
    

Proof state:
α✝ : Type u_1
α : Type u
inst✝ : DecidableEq α
l : List α
l' : List (Multiset α)
H : ∀ ⦃x : Multiset α × Multiset α⦄, x ∈ revzip l' → x.1 + x.2 = ↑l
⊢ Forall₂ (fun p s => p = (s, ↑l - s)) (revzip l') (List.map Prod.fst (revzip l'))

Next tactic:
rw [forall₂_map_right_iff, forall₂_same]
theorem revzip_powersetAux_lemma {α : Type u} [DecidableEq α] (l : List α) {l' : List (Multiset α)}
    (H : ∀ ⦃x : _ × _⦄, x ∈ revzip l' → x.1 + x.2 = ↑l) :
    revzip l' = l'.map fun x => (x, (l : Multiset α) - x) := by
  have :
    Forall₂ (fun (p : Multiset α × Multiset α) (s : Multiset α) => p = (s, ↑l - s)) (revzip l')
      ((revzip l').map Prod.fst) := by
    rw [forall₂_map_right_iff, forall₂_same]
    

Proof state:
α✝ : Type u_1
α : Type u
inst✝ : DecidableEq α
l : List α
l' : List (Multiset α)
H : ∀ ⦃x : Multiset α × Multiset α⦄, x ∈ revzip l' → x.1 + x.2 = ↑l
⊢ ∀ x ∈ revzip l', x = (x.1, ↑l - x.1)

Next tactic:
rintro ⟨s, t⟩ h
theorem revzip_powersetAux_lemma {α : Type u} [DecidableEq α] (l : List α) {l' : List (Multiset α)}
    (H : ∀ ⦃x : _ × _⦄, x ∈ revzip l' → x.1 + x.2 = ↑l) :
    revzip l' = l'.map fun x => (x, (l : Multiset α) - x) := by
  have :
    Forall₂ (fun (p : Multiset α × Multiset α) (s : Multiset α) => p = (s, ↑l - s)) (revzip l')
      ((revzip l').map Prod.fst) := by
    rw [forall₂_map_right_iff, forall₂_same]
    rintro ⟨s, t⟩ h
    

Proof state:
case mk
α✝ : Type u_1
α : Type u
inst✝ : DecidableEq α
l : List α
l' : List (Multiset α)
H : ∀ ⦃x : Multiset α × Multiset α⦄, x ∈ revzip l' → x.1 + x.2 = ↑l
s t : Multiset α
h : (s, t) ∈ revzip l'
⊢ (s, t) = ((s, t).1, ↑l - (s, t).1)

Next tactic:
dsimp
theorem revzip_powersetAux_lemma {α : Type u} [DecidableEq α] (l : List α) {l' : List (Multiset α)}
    (H : ∀ ⦃x : _ × _⦄, x ∈ revzip l' → x.1 + x.2 = ↑l) :
    revzip l' = l'.map fun x => (x, (l : Multiset α) - x) := by
  have :
    Forall₂ (fun (p : Multiset α × Multiset α) (s : Multiset α) => p = (s, ↑l - s)) (revzip l')
      ((revzip l').map Prod.fst) := by
    rw [forall₂_map_right_iff, forall₂_same]
    rintro ⟨s, t⟩ h
    dsimp
    

Proof state:
case mk
α✝ : Type u_1
α : Type u
inst✝ : DecidableEq α
l : List α
l' : List (Multiset α)
H : ∀ ⦃x : Multiset α × Multiset α⦄, x ∈ revzip l' → x.1 + x.2 = ↑l
s t : Multiset α
h : (s, t) ∈ revzip l'
⊢ (s, t) = (s, ↑l - s)

Next tactic:
rw [← H h, add_tsub_cancel_left]
theorem revzip_powersetAux_lemma {α : Type u} [DecidableEq α] (l : List α) {l' : List (Multiset α)}
    (H : ∀ ⦃x : _ × _⦄, x ∈ revzip l' → x.1 + x.2 = ↑l) :
    revzip l' = l'.map fun x => (x, (l : Multiset α) - x) := by
  have :
    Forall₂ (fun (p : Multiset α × Multiset α) (s : Multiset α) => p = (s, ↑l - s)) (revzip l')
      ((revzip l').map Prod.fst) := by
    rw [forall₂_map_right_iff, forall₂_same]
    rintro ⟨s, t⟩ h
    dsimp
    rw [← H h, add_tsub_cancel_left]
  

Proof state:
α✝ : Type u_1
α : Type u
inst✝ : DecidableEq α
l : List α
l' : List (Multiset α)
H : ∀ ⦃x : Multiset α × Multiset α⦄, x ∈ revzip l' → x.1 + x.2 = ↑l
this : Forall₂ (fun p s => p = (s, ↑l - s)) (revzip l') (List.map Prod.fst (revzip l'))
⊢ revzip l' = List.map (fun x => (x, ↑l - x)) l'

Next tactic:
rw [← forall₂_eq_eq_eq, forall₂_map_right_iff]
theorem revzip_powersetAux_lemma {α : Type u} [DecidableEq α] (l : List α) {l' : List (Multiset α)}
    (H : ∀ ⦃x : _ × _⦄, x ∈ revzip l' → x.1 + x.2 = ↑l) :
    revzip l' = l'.map fun x => (x, (l : Multiset α) - x) := by
  have :
    Forall₂ (fun (p : Multiset α × Multiset α) (s : Multiset α) => p = (s, ↑l - s)) (revzip l')
      ((revzip l').map Prod.fst) := by
    rw [forall₂_map_right_iff, forall₂_same]
    rintro ⟨s, t⟩ h
    dsimp
    rw [← H h, add_tsub_cancel_left]
  rw [← forall₂_eq_eq_eq, forall₂_map_right_iff]
  

Proof state:
α✝ : Type u_1
α : Type u
inst✝ : DecidableEq α
l : List α
l' : List (Multiset α)
H : ∀ ⦃x : Multiset α × Multiset α⦄, x ∈ revzip l' → x.1 + x.2 = ↑l
this : Forall₂ (fun p s => p = (s, ↑l - s)) (revzip l') (List.map Prod.fst (revzip l'))
⊢ Forall₂ (fun a c => a = (c, ↑l - c)) (revzip l') l'

Next tactic:
simpa using this
theorem revzip_powersetAux_perm_aux' {l : List α} :
    revzip (powersetAux l) ~ revzip (powersetAux' l) := by
  

Proof state:
α : Type u_1
l : List α
⊢ revzip (powersetAux l) ~ revzip (powersetAux' l)

Next tactic:
haveI := Classical.decEq α
theorem revzip_powersetAux_perm_aux' {l : List α} :
    revzip (powersetAux l) ~ revzip (powersetAux' l) := by
  haveI := Classical.decEq α
  

Proof state:
α : Type u_1
l : List α
this : DecidableEq α
⊢ revzip (powersetAux l) ~ revzip (powersetAux' l)

Next tactic:
rw [revzip_powersetAux_lemma l revzip_powersetAux, revzip_powersetAux_lemma l revzip_powersetAux']
theorem revzip_powersetAux_perm_aux' {l : List α} :
    revzip (powersetAux l) ~ revzip (powersetAux' l) := by
  haveI := Classical.decEq α
  rw [revzip_powersetAux_lemma l revzip_powersetAux, revzip_powersetAux_lemma l revzip_powersetAux']
  

Proof state:
α : Type u_1
l : List α
this : DecidableEq α
⊢ List.map (fun x => (x, ↑l - x)) (powersetAux l) ~ List.map (fun x => (x, ↑l - x)) (powersetAux' l)

Next tactic:
exact powersetAux_perm_powersetAux'.map _
theorem revzip_powersetAux_perm {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    revzip (powersetAux l₁) ~ revzip (powersetAux l₂) := by
  

Proof state:
α : Type u_1
l₁ l₂ : List α
p : l₁ ~ l₂
⊢ revzip (powersetAux l₁) ~ revzip (powersetAux l₂)

Next tactic:
haveI := Classical.decEq α
theorem revzip_powersetAux_perm {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    revzip (powersetAux l₁) ~ revzip (powersetAux l₂) := by
  haveI := Classical.decEq α
  

Proof state:
α : Type u_1
l₁ l₂ : List α
p : l₁ ~ l₂
this : DecidableEq α
⊢ revzip (powersetAux l₁) ~ revzip (powersetAux l₂)

Next tactic:
simp only [fun l : List α => revzip_powersetAux_lemma l revzip_powersetAux, coe_eq_coe.2 p,
    ge_iff_le]
theorem revzip_powersetAux_perm {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    revzip (powersetAux l₁) ~ revzip (powersetAux l₂) := by
  haveI := Classical.decEq α
  simp only [fun l : List α => revzip_powersetAux_lemma l revzip_powersetAux, coe_eq_coe.2 p,
    ge_iff_le]
  

Proof state:
α : Type u_1
l₁ l₂ : List α
p : l₁ ~ l₂
this : DecidableEq α
⊢ List.map (fun x => (x, ↑l₂ - x)) (powersetAux l₁) ~ List.map (fun x => (x, ↑l₂ - x)) (powersetAux l₂)

Next tactic:
exact (powersetAux_perm p).map _
theorem powersetCardAux_eq_map_coe {n} {l : List α} :
    powersetCardAux n l = (sublistsLen n l).map (↑) := by
  

Proof state:
α : Type u_1
n : ℕ
l : List α
⊢ powersetCardAux n l = List.map ofList (sublistsLen n l)

Next tactic:
rw [powersetCardAux, sublistsLenAux_eq, append_nil]
@[simp]
theorem mem_powersetCardAux {n} {l : List α} {s} : s ∈ powersetCardAux n l ↔ s ≤ ↑l ∧ card s = n :=
  Quotient.inductionOn s <| by
    

Proof state:
α : Type u_1
n : ℕ
l : List α
s : Multiset α
⊢ ∀ (a : List α), ⟦a⟧ ∈ powersetCardAux n l ↔ ⟦a⟧ ≤ ↑l ∧ card ⟦a⟧ = n

Next tactic:
simp only [quot_mk_to_coe, powersetCardAux_eq_map_coe, List.mem_map, mem_sublistsLen,
      coe_eq_coe, coe_le, Subperm, exists_prop, coe_card]
@[simp]
theorem mem_powersetCardAux {n} {l : List α} {s} : s ∈ powersetCardAux n l ↔ s ≤ ↑l ∧ card s = n :=
  Quotient.inductionOn s <| by
    simp only [quot_mk_to_coe, powersetCardAux_eq_map_coe, List.mem_map, mem_sublistsLen,
      coe_eq_coe, coe_le, Subperm, exists_prop, coe_card]
    

Proof state:
α : Type u_1
n : ℕ
l : List α
s : Multiset α
⊢ ∀ (a : List α), (∃ a_1, (a_1 <+ l ∧ length a_1 = n) ∧ a_1 ~ a) ↔ (∃ l_1, l_1 ~ a ∧ l_1 <+ l) ∧ length a = n

Next tactic:
exact fun l₁ =>
      ⟨fun ⟨l₂, ⟨s, e⟩, p⟩ => ⟨⟨_, p, s⟩, p.symm.length_eq.trans e⟩,
       fun ⟨⟨l₂, p, s⟩, e⟩ => ⟨_, ⟨s, p.length_eq.trans e⟩, p⟩⟩
@[simp]
theorem powersetCardAux_zero (l : List α) : powersetCardAux 0 l = [0] := by
  

Proof state:
α : Type u_1
l : List α
⊢ powersetCardAux 0 l = [0]

Next tactic:
simp [powersetCardAux_eq_map_coe]
@[simp]
theorem powersetCardAux_cons (n : ℕ) (a : α) (l : List α) :
    powersetCardAux (n + 1) (a :: l) =
      powersetCardAux (n + 1) l ++ List.map (cons a) (powersetCardAux n l) := by
  

Proof state:
α : Type u_1
n : ℕ
a : α
l : List α
⊢ powersetCardAux (n + 1) (a :: l) = powersetCardAux (n + 1) l ++ List.map (cons a) (powersetCardAux n l)

Next tactic:
simp [powersetCardAux_eq_map_coe]
@[simp]
theorem powersetCardAux_cons (n : ℕ) (a : α) (l : List α) :
    powersetCardAux (n + 1) (a :: l) =
      powersetCardAux (n + 1) l ++ List.map (cons a) (powersetCardAux n l) := by
  simp [powersetCardAux_eq_map_coe]; 

Proof state:
α : Type u_1
n : ℕ
a : α
l : List α
⊢ List.map (ofList ∘ List.cons a) (sublistsLen n l) = List.map (cons a ∘ ofList) (sublistsLen n l)

Next tactic:
rfl
theorem powersetCardAux_perm {n} {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    powersetCardAux n l₁ ~ powersetCardAux n l₂ := by
  

Proof state:
α : Type u_1
n : ℕ
l₁ l₂ : List α
p : l₁ ~ l₂
⊢ powersetCardAux n l₁ ~ powersetCardAux n l₂

Next tactic:
induction' n with n IHn generalizing l₁ l₂
theorem powersetCardAux_perm {n} {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    powersetCardAux n l₁ ~ powersetCardAux n l₂ := by
  induction' n with n IHn generalizing l₁ l₂
  · 

Proof state:
case zero
α : Type u_1
l₁ l₂ : List α
p : l₁ ~ l₂
⊢ powersetCardAux Nat.zero l₁ ~ powersetCardAux Nat.zero l₂

Next tactic:
simp
theorem powersetCardAux_perm {n} {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    powersetCardAux n l₁ ~ powersetCardAux n l₂ := by
  induction' n with n IHn generalizing l₁ l₂
  · simp
  

Proof state:
case succ
α : Type u_1
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetCardAux n l₁ ~ powersetCardAux n l₂
l₁ l₂ : List α
p : l₁ ~ l₂
⊢ powersetCardAux (Nat.succ n) l₁ ~ powersetCardAux (Nat.succ n) l₂

Next tactic:
induction' p with a l₁ l₂ p IH a b l l₁ l₂ l₃ _ _ IH₁ IH₂
theorem powersetCardAux_perm {n} {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    powersetCardAux n l₁ ~ powersetCardAux n l₂ := by
  induction' n with n IHn generalizing l₁ l₂
  · simp
  induction' p with a l₁ l₂ p IH a b l l₁ l₂ l₃ _ _ IH₁ IH₂
  · 

Proof state:
case succ.nil
α : Type u_1
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetCardAux n l₁ ~ powersetCardAux n l₂
l₁ l₂ : List α
⊢ powersetCardAux (Nat.succ n) [] ~ powersetCardAux (Nat.succ n) []

Next tactic:
rfl
theorem powersetCardAux_perm {n} {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    powersetCardAux n l₁ ~ powersetCardAux n l₂ := by
  induction' n with n IHn generalizing l₁ l₂
  · simp
  induction' p with a l₁ l₂ p IH a b l l₁ l₂ l₃ _ _ IH₁ IH₂
  · rfl
  · 

Proof state:
case succ.cons
α : Type u_1
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetCardAux n l₁ ~ powersetCardAux n l₂
l₁✝ l₂✝ : List α
a : α
l₁ l₂ : List α
p : l₁ ~ l₂
IH : powersetCardAux (Nat.succ n) l₁ ~ powersetCardAux (Nat.succ n) l₂
⊢ powersetCardAux (Nat.succ n) (a :: l₁) ~ powersetCardAux (Nat.succ n) (a :: l₂)

Next tactic:
simp only [powersetCardAux_cons]
theorem powersetCardAux_perm {n} {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    powersetCardAux n l₁ ~ powersetCardAux n l₂ := by
  induction' n with n IHn generalizing l₁ l₂
  · simp
  induction' p with a l₁ l₂ p IH a b l l₁ l₂ l₃ _ _ IH₁ IH₂
  · rfl
  · simp only [powersetCardAux_cons]
    

Proof state:
case succ.cons
α : Type u_1
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetCardAux n l₁ ~ powersetCardAux n l₂
l₁✝ l₂✝ : List α
a : α
l₁ l₂ : List α
p : l₁ ~ l₂
IH : powersetCardAux (Nat.succ n) l₁ ~ powersetCardAux (Nat.succ n) l₂
⊢ powersetCardAux (n + 1) l₁ ++ List.map (cons a) (powersetCardAux n l₁) ~
    powersetCardAux (n + 1) l₂ ++ List.map (cons a) (powersetCardAux n l₂)

Next tactic:
exact IH.append ((IHn p).map _)
theorem powersetCardAux_perm {n} {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    powersetCardAux n l₁ ~ powersetCardAux n l₂ := by
  induction' n with n IHn generalizing l₁ l₂
  · simp
  induction' p with a l₁ l₂ p IH a b l l₁ l₂ l₃ _ _ IH₁ IH₂
  · rfl
  · simp only [powersetCardAux_cons]
    exact IH.append ((IHn p).map _)
  · 

Proof state:
case succ.swap
α : Type u_1
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetCardAux n l₁ ~ powersetCardAux n l₂
l₁ l₂ : List α
a b : α
l : List α
⊢ powersetCardAux (Nat.succ n) (b :: a :: l) ~ powersetCardAux (Nat.succ n) (a :: b :: l)

Next tactic:
simp only [powersetCardAux_cons, append_assoc]
theorem powersetCardAux_perm {n} {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    powersetCardAux n l₁ ~ powersetCardAux n l₂ := by
  induction' n with n IHn generalizing l₁ l₂
  · simp
  induction' p with a l₁ l₂ p IH a b l l₁ l₂ l₃ _ _ IH₁ IH₂
  · rfl
  · simp only [powersetCardAux_cons]
    exact IH.append ((IHn p).map _)
  · simp only [powersetCardAux_cons, append_assoc]
    

Proof state:
case succ.swap
α : Type u_1
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetCardAux n l₁ ~ powersetCardAux n l₂
l₁ l₂ : List α
a b : α
l : List α
⊢ powersetCardAux (n + 1) l ++
      (List.map (cons a) (powersetCardAux n l) ++ List.map (cons b) (powersetCardAux n (a :: l))) ~
    powersetCardAux (n + 1) l ++
      (List.map (cons b) (powersetCardAux n l) ++ List.map (cons a) (powersetCardAux n (b :: l)))

Next tactic:
apply Perm.append_left
theorem powersetCardAux_perm {n} {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    powersetCardAux n l₁ ~ powersetCardAux n l₂ := by
  induction' n with n IHn generalizing l₁ l₂
  · simp
  induction' p with a l₁ l₂ p IH a b l l₁ l₂ l₃ _ _ IH₁ IH₂
  · rfl
  · simp only [powersetCardAux_cons]
    exact IH.append ((IHn p).map _)
  · simp only [powersetCardAux_cons, append_assoc]
    apply Perm.append_left
    

Proof state:
case succ.swap.a
α : Type u_1
n : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetCardAux n l₁ ~ powersetCardAux n l₂
l₁ l₂ : List α
a b : α
l : List α
⊢ List.map (cons a) (powersetCardAux n l) ++ List.map (cons b) (powersetCardAux n (a :: l)) ~
    List.map (cons b) (powersetCardAux n l) ++ List.map (cons a) (powersetCardAux n (b :: l))

Next tactic:
cases n
theorem powersetCardAux_perm {n} {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    powersetCardAux n l₁ ~ powersetCardAux n l₂ := by
  induction' n with n IHn generalizing l₁ l₂
  · simp
  induction' p with a l₁ l₂ p IH a b l l₁ l₂ l₃ _ _ IH₁ IH₂
  · rfl
  · simp only [powersetCardAux_cons]
    exact IH.append ((IHn p).map _)
  · simp only [powersetCardAux_cons, append_assoc]
    apply Perm.append_left
    cases n
    · 

Proof state:
case succ.swap.a.zero
α : Type u_1
l₁ l₂ : List α
a b : α
l : List α
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetCardAux Nat.zero l₁ ~ powersetCardAux Nat.zero l₂
⊢ List.map (cons a) (powersetCardAux Nat.zero l) ++ List.map (cons b) (powersetCardAux Nat.zero (a :: l)) ~
    List.map (cons b) (powersetCardAux Nat.zero l) ++ List.map (cons a) (powersetCardAux Nat.zero (b :: l))

Next tactic:
simp [Perm.swap]
theorem powersetCardAux_perm {n} {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    powersetCardAux n l₁ ~ powersetCardAux n l₂ := by
  induction' n with n IHn generalizing l₁ l₂
  · simp
  induction' p with a l₁ l₂ p IH a b l l₁ l₂ l₃ _ _ IH₁ IH₂
  · rfl
  · simp only [powersetCardAux_cons]
    exact IH.append ((IHn p).map _)
  · simp only [powersetCardAux_cons, append_assoc]
    apply Perm.append_left
    cases n
    · simp [Perm.swap]
    

Proof state:
case succ.swap.a.succ
α : Type u_1
l₁ l₂ : List α
a b : α
l : List α
n✝ : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetCardAux (Nat.succ n✝) l₁ ~ powersetCardAux (Nat.succ n✝) l₂
⊢ List.map (cons a) (powersetCardAux (Nat.succ n✝) l) ++ List.map (cons b) (powersetCardAux (Nat.succ n✝) (a :: l)) ~
    List.map (cons b) (powersetCardAux (Nat.succ n✝) l) ++ List.map (cons a) (powersetCardAux (Nat.succ n✝) (b :: l))

Next tactic:
simp only [powersetCardAux_cons, map_append, List.map_map]
theorem powersetCardAux_perm {n} {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    powersetCardAux n l₁ ~ powersetCardAux n l₂ := by
  induction' n with n IHn generalizing l₁ l₂
  · simp
  induction' p with a l₁ l₂ p IH a b l l₁ l₂ l₃ _ _ IH₁ IH₂
  · rfl
  · simp only [powersetCardAux_cons]
    exact IH.append ((IHn p).map _)
  · simp only [powersetCardAux_cons, append_assoc]
    apply Perm.append_left
    cases n
    · simp [Perm.swap]
    simp only [powersetCardAux_cons, map_append, List.map_map]
    

Proof state:
case succ.swap.a.succ
α : Type u_1
l₁ l₂ : List α
a b : α
l : List α
n✝ : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetCardAux (Nat.succ n✝) l₁ ~ powersetCardAux (Nat.succ n✝) l₂
⊢ List.map (cons a) (powersetCardAux (Nat.succ n✝) l) ++
      (List.map (cons b) (powersetCardAux (n✝ + 1) l) ++ List.map (cons b ∘ cons a) (powersetCardAux n✝ l)) ~
    List.map (cons b) (powersetCardAux (Nat.succ n✝) l) ++
      (List.map (cons a) (powersetCardAux (n✝ + 1) l) ++ List.map (cons a ∘ cons b) (powersetCardAux n✝ l))

Next tactic:
rw [← append_assoc, ← append_assoc,
      (by funext s; simp [cons_swap] : cons b ∘ cons a = cons a ∘ cons b)]
theorem powersetCardAux_perm {n} {l₁ l₂ : List α} (p : l₁ ~ l₂) :
    powersetCardAux n l₁ ~ powersetCardAux n l₂ := by
  induction' n with n IHn generalizing l₁ l₂
  · simp
  induction' p with a l₁ l₂ p IH a b l l₁ l₂ l₃ _ _ IH₁ IH₂
  · rfl
  · simp only [powersetCardAux_cons]
    exact IH.append ((IHn p).map _)
  · simp only [powersetCardAux_cons, append_assoc]
    apply Perm.append_left
    cases n
    · simp [Perm.swap]
    simp only [powersetCardAux_cons, map_append, List.map_map]
    rw [← append_assoc, ← append_assoc,
      (by 

Proof state:
α : Type u_1
l₁ l₂ : List α
a b : α
l : List α
n✝ : ℕ
IHn : ∀ {l₁ l₂ : List α}, l₁ ~ l₂ → powersetCardAux (Nat.succ n✝) l₁ ~ powersetCardAux (Nat.succ n✝) l₂
⊢ cons b ∘ cons a = cons a ∘ cons b

Next tactic:
funext s