l3lab/ntp-mathlib huggingface dataset:
/-- An odd function on a linear ordered additive commutative group is strictly monotone on the whole
group provided that it is strictly monotone on `Set.Ici 0`. -/
theorem strictMono_of_odd_strictMonoOn_nonneg {f : G → H} (h₁ : ∀ x, f (-x) = -f x)
    (h₂ : StrictMonoOn f (Ici 0)) : StrictMono f := by
  refine' StrictMonoOn.Iic_union_Ici (fun x hx y hy hxy => neg_lt_neg_iff.1 _) h₂
  

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : LinearOrderedAddCommGroup G
inst✝ : OrderedAddCommGroup H
f : G → H
h₁ : ∀ (x : G), f (-x) = -f x
h₂ : StrictMonoOn f (Ici 0)
x : G
hx : x ∈ Iic 0
y : G
hy : y ∈ Iic 0
hxy : x < y
⊢ -f y < -f x

Next tactic:
rw [← h₁, ← h₁]
/-- An odd function on a linear ordered additive commutative group is strictly monotone on the whole
group provided that it is strictly monotone on `Set.Ici 0`. -/
theorem strictMono_of_odd_strictMonoOn_nonneg {f : G → H} (h₁ : ∀ x, f (-x) = -f x)
    (h₂ : StrictMonoOn f (Ici 0)) : StrictMono f := by
  refine' StrictMonoOn.Iic_union_Ici (fun x hx y hy hxy => neg_lt_neg_iff.1 _) h₂
  rw [← h₁, ← h₁]
  

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : LinearOrderedAddCommGroup G
inst✝ : OrderedAddCommGroup H
f : G → H
h₁ : ∀ (x : G), f (-x) = -f x
h₂ : StrictMonoOn f (Ici 0)
x : G
hx : x ∈ Iic 0
y : G
hy : y ∈ Iic 0
hxy : x < y
⊢ f (-y) < f (-x)

Next tactic:
exact h₂ (neg_nonneg.2 hy) (neg_nonneg.2 hx) (neg_lt_neg hxy)
/-- An odd function on a linear ordered additive commutative group is monotone on the whole group
provided that it is monotone on `Set.Ici 0`. -/
theorem monotone_of_odd_of_monotoneOn_nonneg {f : G → H} (h₁ : ∀ x, f (-x) = -f x)
    (h₂ : MonotoneOn f (Ici 0)) : Monotone f := by
  

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : LinearOrderedAddCommGroup G
inst✝ : OrderedAddCommGroup H
f : G → H
h₁ : ∀ (x : G), f (-x) = -f x
h₂ : MonotoneOn f (Ici 0)
⊢ Monotone f

Next tactic:
refine' MonotoneOn.Iic_union_Ici (fun x hx y hy hxy => neg_le_neg_iff.1 _) h₂
/-- An odd function on a linear ordered additive commutative group is monotone on the whole group
provided that it is monotone on `Set.Ici 0`. -/
theorem monotone_of_odd_of_monotoneOn_nonneg {f : G → H} (h₁ : ∀ x, f (-x) = -f x)
    (h₂ : MonotoneOn f (Ici 0)) : Monotone f := by
  refine' MonotoneOn.Iic_union_Ici (fun x hx y hy hxy => neg_le_neg_iff.1 _) h₂
  

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : LinearOrderedAddCommGroup G
inst✝ : OrderedAddCommGroup H
f : G → H
h₁ : ∀ (x : G), f (-x) = -f x
h₂ : MonotoneOn f (Ici 0)
x : G
hx : x ∈ Iic 0
y : G
hy : y ∈ Iic 0
hxy : x ≤ y
⊢ -f y ≤ -f x

Next tactic:
rw [← h₁, ← h₁]
/-- An odd function on a linear ordered additive commutative group is monotone on the whole group
provided that it is monotone on `Set.Ici 0`. -/
theorem monotone_of_odd_of_monotoneOn_nonneg {f : G → H} (h₁ : ∀ x, f (-x) = -f x)
    (h₂ : MonotoneOn f (Ici 0)) : Monotone f := by
  refine' MonotoneOn.Iic_union_Ici (fun x hx y hy hxy => neg_le_neg_iff.1 _) h₂
  rw [← h₁, ← h₁]
  

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : LinearOrderedAddCommGroup G
inst✝ : OrderedAddCommGroup H
f : G → H
h₁ : ∀ (x : G), f (-x) = -f x
h₂ : MonotoneOn f (Ici 0)
x : G
hx : x ∈ Iic 0
y : G
hy : y ∈ Iic 0
hxy : x ≤ y
⊢ f (-y) ≤ f (-x)

Next tactic:
exact h₂ (neg_nonneg.2 hy) (neg_nonneg.2 hx) (neg_le_neg hxy)
/-- Inserts an element into the term of `Sym α n`, increasing the length by one.
-/
@[match_pattern]
def cons (a : α) (s : Sym α n) : Sym α n.succ :=
  ⟨a ::ₘ s.1, by 

Proof state:
α : Type u_1
β : Type u_2
n n' m : ℕ
s✝ : Sym α n
a✝ b a : α
s : Sym α n
⊢ Multiset.card (a ::ₘ ↑s) = Nat.succ n

Next tactic:
rw [Multiset.card_cons, s.2]
@[simp]
theorem ofVector_cons (a : α) (v : Vector α n) : ↑(Vector.cons a v) = a ::ₛ (↑v : Sym α n) := by
  

Proof state:
α : Type u_1
β : Type u_2
n n' m : ℕ
s : Sym α n
a✝ b a : α
v : Vector α n
⊢ ofVector (a ::ᵥ v) = a ::ₛ ofVector v

Next tactic:
cases v
@[simp]
theorem ofVector_cons (a : α) (v : Vector α n) : ↑(Vector.cons a v) = a ::ₛ (↑v : Sym α n) := by
  cases v
  

Proof state:
case mk
α : Type u_1
β : Type u_2
n n' m : ℕ
s : Sym α n
a✝ b a : α
val✝ : List α
property✝ : List.length val✝ = n
⊢ ofVector (a ::ᵥ { val := val✝, property := property✝ }) = a ::ₛ ofVector { val := val✝, property := property✝ }

Next tactic:
rfl
theorem cons_of_coe_eq (a : α) (v : Vector α n) : a ::ₛ (↑v : Sym α n) = ↑(a ::ᵥ v) :=
  Subtype.ext <| by
    

Proof state:
α : Type u_1
β : Type u_2
n n' m : ℕ
s : Sym α n
a✝ b a : α
v : Vector α n
⊢ ↑(a ::ₛ ofVector v) = ↑(ofVector (a ::ᵥ v))

Next tactic:
cases v
theorem cons_of_coe_eq (a : α) (v : Vector α n) : a ::ₛ (↑v : Sym α n) = ↑(a ::ᵥ v) :=
  Subtype.ext <| by
    cases v
    

Proof state:
case mk
α : Type u_1
β : Type u_2
n n' m : ℕ
s : Sym α n
a✝ b a : α
val✝ : List α
property✝ : List.length val✝ = n
⊢ ↑(a ::ₛ ofVector { val := val✝, property := property✝ }) = ↑(ofVector (a ::ᵥ { val := val✝, property := property✝ }))

Next tactic:
rfl
@[simp]
theorem erase_mk [DecidableEq α] (m : Multiset α)
    (hc : Multiset.card m = n + 1) (a : α) (h : a ∈ m) :
    (mk m hc).erase a h =mk (m.erase a)
        (by 

Proof state:
α : Type u_1
β : Type u_2
n n' m✝ : ℕ
s : Sym α n
a✝ b : α
inst✝ : DecidableEq α
m : Multiset α
hc : Multiset.card m = n + 1
a : α
h : a ∈ m
⊢ Multiset.card (Multiset.erase m a) = n

Next tactic:
rw [Multiset.card_erase_of_mem h, hc]
@[simp]
theorem erase_mk [DecidableEq α] (m : Multiset α)
    (hc : Multiset.card m = n + 1) (a : α) (h : a ∈ m) :
    (mk m hc).erase a h =mk (m.erase a)
        (by rw [Multiset.card_erase_of_mem h, hc]; 

Proof state:
α : Type u_1
β : Type u_2
n n' m✝ : ℕ
s : Sym α n
a✝ b : α
inst✝ : DecidableEq α
m : Multiset α
hc : Multiset.card m = n + 1
a : α
h : a ∈ m
⊢ Nat.pred (n + 1) = n

Next tactic:
rfl
/-- Multisets of cardinality n are equivalent to length-n vectors up to permutations.
-/
def symEquivSym' {α : Type*} {n : ℕ} : Sym α n ≃ Sym' α n :=
  Equiv.subtypeQuotientEquivQuotientSubtype _ _ (fun _ => by 

Proof state:
α✝ : Type u_1
β : Type u_2
n✝ n' m : ℕ
s : Sym α✝ n✝
a b : α✝
α : Type u_3
n : ℕ
x✝ : List α
⊢ List.length x✝ = n ↔ Multiset.card ⟦x✝⟧ = n

Next tactic:
rfl
/-- Multisets of cardinality n are equivalent to length-n vectors up to permutations.
-/
def symEquivSym' {α : Type*} {n : ℕ} : Sym α n ≃ Sym' α n :=
  Equiv.subtypeQuotientEquivQuotientSubtype _ _ (fun _ => by rfl) fun _ _ => by 

Proof state:
α✝ : Type u_1
β : Type u_2
n✝ n' m : ℕ
s : Sym α✝ n✝
a b : α✝
α : Type u_3
n : ℕ
x✝¹ x✝ : { l // List.length l = n }
⊢ Setoid.r x✝¹ x✝ ↔ ↑x✝¹ ≈ ↑x✝

Next tactic:
rfl
theorem cons_equiv_eq_equiv_cons (α : Type*) (n : ℕ) (a : α) (s : Sym α n) :
    (a::symEquivSym' s) = symEquivSym' (a ::ₛ s) := by
  

Proof state:
α✝ : Type u_1
β : Type u_2
n✝ n' m : ℕ
s✝ : Sym α✝ n✝
a✝ b : α✝
α : Type u_3
n : ℕ
a : α
s : Sym α n
⊢ (a :: symEquivSym' s) = symEquivSym' (a ::ₛ s)

Next tactic:
rcases s with ⟨⟨l⟩, _⟩
theorem cons_equiv_eq_equiv_cons (α : Type*) (n : ℕ) (a : α) (s : Sym α n) :
    (a::symEquivSym' s) = symEquivSym' (a ::ₛ s) := by
  rcases s with ⟨⟨l⟩, _⟩
  

Proof state:
case mk.mk
α✝ : Type u_1
β : Type u_2
n✝ n' m : ℕ
s : Sym α✝ n✝
a✝ b : α✝
α : Type u_3
n : ℕ
a : α
val✝ : Multiset α
l : List α
property✝ : Multiset.card (Quot.mk Setoid.r l) = n
⊢ (a :: symEquivSym' { val := Quot.mk Setoid.r l, property := property✝ }) =
    symEquivSym' (a ::ₛ { val := Quot.mk Setoid.r l, property := property✝ })

Next tactic:
rfl
theorem eq_replicate_iff : s = replicate n a ↔ ∀ b ∈ s, b = a := by
  

Proof state:
α : Type u_1
β : Type u_2
n n' m : ℕ
s : Sym α n
a b : α
⊢ s = replicate n a ↔ ∀ b ∈ s, b = a

Next tactic:
erw [Subtype.ext_iff, Multiset.eq_replicate]
theorem eq_replicate_iff : s = replicate n a ↔ ∀ b ∈ s, b = a := by
  erw [Subtype.ext_iff, Multiset.eq_replicate]
  

Proof state:
α : Type u_1
β : Type u_2
n n' m : ℕ
s : Sym α n
a b : α
⊢ (Multiset.card ↑s = n ∧ ∀ b ∈ ↑s, b = a) ↔ ∀ b ∈ s, b = a

Next tactic:
exact and_iff_right s.2
theorem exists_cons_of_mem {s : Sym α (n + 1)} {a : α} (h : a ∈ s) : ∃ t, s = a ::ₛ t := by
  

Proof state:
α : Type u_1
β : Type u_2
n n' m : ℕ
s✝ : Sym α n
a✝ b : α
s : Sym α (n + 1)
a : α
h : a ∈ s
⊢ ∃ t, s = a ::ₛ t

Next tactic:
obtain ⟨m, h⟩ := Multiset.exists_cons_of_mem h
theorem exists_cons_of_mem {s : Sym α (n + 1)} {a : α} (h : a ∈ s) : ∃ t, s = a ::ₛ t := by
  obtain ⟨m, h⟩ := Multiset.exists_cons_of_mem h
  

Proof state:
case intro
α : Type u_1
β : Type u_2
n n' m✝ : ℕ
s✝ : Sym α n
a✝ b : α
s : Sym α (n + 1)
a : α
h✝ : a ∈ s
m : Multiset α
h : ↑s = a ::ₘ m
⊢ ∃ t, s = a ::ₛ t

Next tactic:
have : Multiset.card m = n := by
    apply_fun Multiset.card at h
    rw [s.2, Multiset.card_cons, add_left_inj] at h
    exact h.symm
theorem exists_cons_of_mem {s : Sym α (n + 1)} {a : α} (h : a ∈ s) : ∃ t, s = a ::ₛ t := by
  obtain ⟨m, h⟩ := Multiset.exists_cons_of_mem h
  have : Multiset.card m = n := by
    

Proof state:
α : Type u_1
β : Type u_2
n n' m✝ : ℕ
s✝ : Sym α n
a✝ b : α
s : Sym α (n + 1)
a : α
h✝ : a ∈ s
m : Multiset α
h : ↑s = a ::ₘ m
⊢ Multiset.card m = n

Next tactic:
apply_fun Multiset.card at h
theorem exists_cons_of_mem {s : Sym α (n + 1)} {a : α} (h : a ∈ s) : ∃ t, s = a ::ₛ t := by
  obtain ⟨m, h⟩ := Multiset.exists_cons_of_mem h
  have : Multiset.card m = n := by
    apply_fun Multiset.card at h
    

Proof state:
α : Type u_1
β : Type u_2
n n' m✝ : ℕ
s✝ : Sym α n
a✝ b : α
s : Sym α (n + 1)
a : α
h✝ : a ∈ s
m : Multiset α
h : Multiset.card ↑s = Multiset.card (a ::ₘ m)
⊢ Multiset.card m = n

Next tactic:
rw [s.2, Multiset.card_cons, add_left_inj] at h
theorem exists_cons_of_mem {s : Sym α (n + 1)} {a : α} (h : a ∈ s) : ∃ t, s = a ::ₛ t := by
  obtain ⟨m, h⟩ := Multiset.exists_cons_of_mem h
  have : Multiset.card m = n := by
    apply_fun Multiset.card at h
    rw [s.2, Multiset.card_cons, add_left_inj] at h
    

Proof state:
α : Type u_1
β : Type u_2
n n' m✝ : ℕ
s✝ : Sym α n
a✝ b : α
s : Sym α (n + 1)
a : α
h✝ : a ∈ s
m : Multiset α
h : n = Multiset.card m
⊢ Multiset.card m = n

Next tactic:
exact h.symm
theorem exists_cons_of_mem {s : Sym α (n + 1)} {a : α} (h : a ∈ s) : ∃ t, s = a ::ₛ t := by
  obtain ⟨m, h⟩ := Multiset.exists_cons_of_mem h
  have : Multiset.card m = n := by
    apply_fun Multiset.card at h
    rw [s.2, Multiset.card_cons, add_left_inj] at h
    exact h.symm
  

Proof state:
case intro
α : Type u_1
β : Type u_2
n n' m✝ : ℕ
s✝ : Sym α n
a✝ b : α
s : Sym α (n + 1)
a : α
h✝ : a ∈ s
m : Multiset α
h : ↑s = a ::ₘ m
this : Multiset.card m = n
⊢ ∃ t, s = a ::ₛ t

Next tactic:
use ⟨m, this⟩
theorem exists_cons_of_mem {s : Sym α (n + 1)} {a : α} (h : a ∈ s) : ∃ t, s = a ::ₛ t := by
  obtain ⟨m, h⟩ := Multiset.exists_cons_of_mem h
  have : Multiset.card m = n := by
    apply_fun Multiset.card at h
    rw [s.2, Multiset.card_cons, add_left_inj] at h
    exact h.symm
  use ⟨m, this⟩
  

Proof state:
case h
α : Type u_1
β : Type u_2
n n' m✝ : ℕ
s✝ : Sym α n
a✝ b : α
s : Sym α (n + 1)
a : α
h✝ : a ∈ s
m : Multiset α
h : ↑s = a ::ₘ m
this : Multiset.card m = n
⊢ s = a ::ₛ { val := m, property := this }

Next tactic:
apply Subtype.ext
theorem exists_cons_of_mem {s : Sym α (n + 1)} {a : α} (h : a ∈ s) : ∃ t, s = a ::ₛ t := by
  obtain ⟨m, h⟩ := Multiset.exists_cons_of_mem h
  have : Multiset.card m = n := by
    apply_fun Multiset.card at h
    rw [s.2, Multiset.card_cons, add_left_inj] at h
    exact h.symm
  use ⟨m, this⟩
  apply Subtype.ext
  

Proof state:
case h.a
α : Type u_1
β : Type u_2
n n' m✝ : ℕ
s✝ : Sym α n
a✝ b : α
s : Sym α (n + 1)
a : α
h✝ : a ∈ s
m : Multiset α
h : ↑s = a ::ₘ m
this : Multiset.card m = n
⊢ ↑s = ↑(a ::ₛ { val := m, property := this })

Next tactic:
exact h
theorem exists_eq_cons_of_succ (s : Sym α n.succ) : ∃ (a : α) (s' : Sym α n), s = a ::ₛ s' := by
  

Proof state:
α : Type u_1
β : Type u_2
n n' m : ℕ
s✝ : Sym α n
a b : α
s : Sym α (Nat.succ n)
⊢ ∃ a s', s = a ::ₛ s'

Next tactic:
obtain ⟨a, ha⟩ := exists_mem s
theorem exists_eq_cons_of_succ (s : Sym α n.succ) : ∃ (a : α) (s' : Sym α n), s = a ::ₛ s' := by
  obtain ⟨a, ha⟩ := exists_mem s
  

Proof state:
case intro
α : Type u_1
β : Type u_2
n n' m : ℕ
s✝ : Sym α n
a✝ b : α
s : Sym α (Nat.succ n)
a : α
ha : a ∈ s
⊢ ∃ a s', s = a ::ₛ s'

Next tactic:
classical exact ⟨a, s.erase a ha, (cons_erase ha).symm⟩
theorem exists_eq_cons_of_succ (s : Sym α n.succ) : ∃ (a : α) (s' : Sym α n), s = a ::ₛ s' := by
  obtain ⟨a, ha⟩ := exists_mem s
  classical 

Proof state:
case intro
α : Type u_1
β : Type u_2
n n' m : ℕ
s✝ : Sym α n
a✝ b : α
s : Sym α (Nat.succ n)
a : α
ha : a ∈ s
⊢ ∃ a s', s = a ::ₛ s'

Next tactic:
exact ⟨a, s.erase a ha, (cons_erase ha).symm⟩
instance [Subsingleton α] (n : ℕ) : Subsingleton (Sym α n) :=
  ⟨by
    

Proof state:
α : Type u_1
β : Type u_2
n✝ n' m : ℕ
s : Sym α n✝
a b : α
inst✝ : Subsingleton α
n : ℕ
⊢ ∀ (a b : Sym α n), a = b

Next tactic:
cases n
instance [Subsingleton α] (n : ℕ) : Subsingleton (Sym α n) :=
  ⟨by
    cases n
    · 

Proof state:
case zero
α : Type u_1
β : Type u_2
n n' m : ℕ
s : Sym α n
a b : α
inst✝ : Subsingleton α
⊢ ∀ (a b : Sym α Nat.zero), a = b

Next tactic:
simp [eq_iff_true_of_subsingleton]
instance [Subsingleton α] (n : ℕ) : Subsingleton (Sym α n) :=
  ⟨by
    cases n
    · simp [eq_iff_true_of_subsingleton]
    · 

Proof state:
case succ
α : Type u_1
β : Type u_2
n n' m : ℕ
s : Sym α n
a b : α
inst✝ : Subsingleton α
n✝ : ℕ
⊢ ∀ (a b : Sym α (Nat.succ n✝)), a = b

Next tactic:
intro s s'
instance [Subsingleton α] (n : ℕ) : Subsingleton (Sym α n) :=
  ⟨by
    cases n
    · simp [eq_iff_true_of_subsingleton]
    · intro s s'
      

Proof state:
case succ
α : Type u_1
β : Type u_2
n n' m : ℕ
s✝ : Sym α n
a b : α
inst✝ : Subsingleton α
n✝ : ℕ
s s' : Sym α (Nat.succ n✝)
⊢ s = s'

Next tactic:
obtain ⟨b, -⟩ := exists_mem s
instance [Subsingleton α] (n : ℕ) : Subsingleton (Sym α n) :=
  ⟨by
    cases n
    · simp [eq_iff_true_of_subsingleton]
    · intro s s'
      obtain ⟨b, -⟩ := exists_mem s
      

Proof state:
case succ.intro
α : Type u_1
β : Type u_2
n n' m : ℕ
s✝ : Sym α n
a b✝ : α
inst✝ : Subsingleton α
n✝ : ℕ
s s' : Sym α (Nat.succ n✝)
b : α
⊢ s = s'

Next tactic:
rw [eq_replicate_of_subsingleton b s', eq_replicate_of_subsingleton b s]
instance (n : ℕ) [IsEmpty α] : IsEmpty (Sym α n.succ) :=
  ⟨fun s => by
    

Proof state:
α : Type u_1
β : Type u_2
n✝ n' m : ℕ
s✝ : Sym α n✝
a b : α
n : ℕ
inst✝ : IsEmpty α
s : Sym α (Nat.succ n)
⊢ False

Next tactic:
obtain ⟨a, -⟩ := exists_mem s
instance (n : ℕ) [IsEmpty α] : IsEmpty (Sym α n.succ) :=
  ⟨fun s => by
    obtain ⟨a, -⟩ := exists_mem s
    

Proof state:
case intro
α : Type u_1
β : Type u_2
n✝ n' m : ℕ
s✝ : Sym α n✝
a✝ b : α
n : ℕ
inst✝ : IsEmpty α
s : Sym α (Nat.succ n)
a : α
⊢ False

Next tactic:
exact isEmptyElim a
/-- A function `α → β` induces a function `Sym α n → Sym β n` by applying it to every element of
the underlying `n`-tuple. -/
def map {n : ℕ} (f : α → β) (x : Sym α n) : Sym β n :=
  ⟨x.val.map f, by 

Proof state:
α : Type u_1
β : Type u_2
n✝ n' m : ℕ
s : Sym α n✝
a b : α
n : ℕ
f : α → β
x : Sym α n
⊢ Multiset.card (Multiset.map f ↑x) = n

Next tactic:
simpa [Multiset.card_map] using x.property
/-- Note: `Sym.map_id` is not simp-normal, as simp ends up unfolding `id` with `Sym.map_congr` -/
@[simp]
theorem map_id' {α : Type*} {n : ℕ} (s : Sym α n) : Sym.map (fun x : α => x) s = s := by
  

Proof state:
α✝ : Type u_1
β : Type u_2
n✝ n' m : ℕ
s✝ : Sym α✝ n✝
a b : α✝
α : Type u_3
n : ℕ
s : Sym α n
⊢ map (fun x => x) s = s

Next tactic:
ext
/-- Note: `Sym.map_id` is not simp-normal, as simp ends up unfolding `id` with `Sym.map_congr` -/
@[simp]
theorem map_id' {α : Type*} {n : ℕ} (s : Sym α n) : Sym.map (fun x : α => x) s = s := by
  ext; 

Proof state:
case h
α✝ : Type u_1
β : Type u_2
n✝ n' m : ℕ
s✝ : Sym α✝ n✝
a b : α✝
α : Type u_3
n : ℕ
s : Sym α n
⊢ ↑(map (fun x => x) s) = ↑s

Next tactic:
simp [Sym.map]
/-- Note: `Sym.map_id` is not simp-normal, as simp ends up unfolding `id` with `Sym.map_congr` -/
@[simp]
theorem map_id' {α : Type*} {n : ℕ} (s : Sym α n) : Sym.map (fun x : α => x) s = s := by
  ext; simp [Sym.map]; 

Proof state:
case h
α✝ : Type u_1
β : Type u_2
n✝ n' m : ℕ
s✝ : Sym α✝ n✝
a b : α✝
α : Type u_3
n : ℕ
s : Sym α n
⊢ { val := ↑s, property := (_ : (fun s => Multiset.card s = n) ↑s) } = s

Next tactic:
rfl
theorem map_id {α : Type*} {n : ℕ} (s : Sym α n) : Sym.map id s = s := by
  

Proof state:
α✝ : Type u_1
β : Type u_2
n✝ n' m : ℕ
s✝ : Sym α✝ n✝
a b : α✝
α : Type u_3
n : ℕ
s : Sym α n
⊢ map id s = s

Next tactic:
ext
theorem map_id {α : Type*} {n : ℕ} (s : Sym α n) : Sym.map id s = s := by
  ext; 

Proof state:
case h
α✝ : Type u_1
β : Type u_2
n✝ n' m : ℕ
s✝ : Sym α✝ n✝
a b : α✝
α : Type u_3
n : ℕ
s : Sym α n
⊢ ↑(map id s) = ↑s

Next tactic:
simp [Sym.map]
theorem map_id {α : Type*} {n : ℕ} (s : Sym α n) : Sym.map id s = s := by
  ext; simp [Sym.map]; 

Proof state:
case h
α✝ : Type u_1
β : Type u_2
n✝ n' m : ℕ
s✝ : Sym α✝ n✝
a b : α✝
α : Type u_3
n : ℕ
s : Sym α n
⊢ { val := ↑s, property := (_ : (fun s => Multiset.card s = n) ↑s) } = s

Next tactic:
rfl
@[simp]
theorem map_map {α β γ : Type*} {n : ℕ} (g : β → γ) (f : α → β) (s : Sym α n) :
    Sym.map g (Sym.map f s) = Sym.map (g ∘ f) s :=
  Subtype.ext <| by 

Proof state:
α✝ : Type u_1
β✝ : Type u_2
n✝ n' m : ℕ
s✝ : Sym α✝ n✝
a b : α✝
α : Type u_3
β : Type u_4
γ : Type u_5
n : ℕ
g : β → γ
f : α → β
s : Sym α n
⊢ ↑(map g (map f s)) = ↑(map (g ∘ f) s)

Next tactic:
dsimp only [Sym.map]
@[simp]
theorem map_map {α β γ : Type*} {n : ℕ} (g : β → γ) (f : α → β) (s : Sym α n) :
    Sym.map g (Sym.map f s) = Sym.map (g ∘ f) s :=
  Subtype.ext <| by dsimp only [Sym.map]; 

Proof state:
α✝ : Type u_1
β✝ : Type u_2
n✝ n' m : ℕ
s✝ : Sym α✝ n✝
a b : α✝
α : Type u_3
β : Type u_4
γ : Type u_5
n : ℕ
g : β → γ
f : α → β
s : Sym α n
⊢ Multiset.map g (Multiset.map f ↑s) = Multiset.map (g ∘ f) ↑s

Next tactic:
simp
@[simp]
theorem map_mk {f : α → β} {m : Multiset α} {hc : Multiset.card m = n} :
    map f (mk m hc) = mk (m.map f) (by 

Proof state:
α : Type u_1
β : Type u_2
n n' m✝ : ℕ
s : Sym α n
a b : α
f : α → β
m : Multiset α
hc : Multiset.card m = n
⊢ Multiset.card (Multiset.map f m) = n

Next tactic:
simp [hc]
/-- Mapping an equivalence `α ≃ β` using `Sym.map` gives an equivalence between `Sym α n` and
`Sym β n`. -/
@[simps]
def equivCongr (e : α ≃ β) : Sym α n ≃ Sym β n where
  toFun := map e
  invFun := map e.symm
  left_inv x := by 

Proof state:
α : Type u_1
β : Type u_2
n n' m : ℕ
s : Sym α n
a b : α
e : α ≃ β
x : Sym α n
⊢ map (⇑e.symm) (map (⇑e) x) = x

Next tactic:
rw [map_map, Equiv.symm_comp_self, map_id]
/-- Mapping an equivalence `α ≃ β` using `Sym.map` gives an equivalence between `Sym α n` and
`Sym β n`. -/
@[simps]
def equivCongr (e : α ≃ β) : Sym α n ≃ Sym β n where
  toFun := map e
  invFun := map e.symm
  left_inv x := by rw [map_map, Equiv.symm_comp_self, map_id]
  right_inv x := by 

Proof state:
α : Type u_1
β : Type u_2
n n' m : ℕ
s : Sym α n
a b : α
e : α ≃ β
x : Sym β n
⊢ map (⇑e) (map (⇑e.symm) x) = x

Next tactic:
rw [map_map, Equiv.self_comp_symm, map_id]
/-- "Attach" a proof that `a ∈ s` to each element `a` in `s` to produce
an element of the symmetric power on `{x // x ∈ s}`. -/
def attach (s : Sym α n) : Sym { x // x ∈ s } n :=
  ⟨s.val.attach, by 

Proof state:
α : Type u_1
β : Type u_2
n n' m : ℕ
s✝ : Sym α n
a b : α
s : Sym α n
⊢ Multiset.card (Multiset.attach ↑s) = n

Next tactic:
conv_rhs => rw [← s.2, ← Multiset.card_attach]
/-- "Attach" a proof that `a ∈ s` to each element `a` in `s` to produce
an element of the symmetric power on `{x // x ∈ s}`. -/
def attach (s : Sym α n) : Sym { x // x ∈ s } n :=
  ⟨s.val.attach, by conv_rhs => 

Proof state:
α : Type u_1
β : Type u_2
n n' m : ℕ
s✝ : Sym α n
a b : α
s : Sym α n
| n

Next tactic:
rw [← s.2, ← Multiset.card_attach]
/-- Append a pair of `Sym` terms. -/
def append (s : Sym α n) (s' : Sym α n') : Sym α (n + n') :=
  ⟨s.1 + s'.1, by 

Proof state:
α : Type u_1
β : Type u_2
n n' m : ℕ
s✝ : Sym α n
a b : α
s : Sym α n
s' : Sym α n'
⊢ Multiset.card (↑s + ↑s') = n + n'

Next tactic:
rw [map_add, s.2, s'.2]
theorem append_comm (s : Sym α n') (s' : Sym α n') :
    s.append s' = Sym.cast (add_comm _ _) (s'.append s) := by
  

Proof state:
α : Type u_1
β : Type u_2
n n' m : ℕ
s✝ : Sym α n
a b : α
s s' : Sym α n'
⊢ append s s' = (Sym.cast (_ : n' + n' = n' + n')) (append s' s)

Next tactic:
ext
theorem append_comm (s : Sym α n') (s' : Sym α n') :
    s.append s' = Sym.cast (add_comm _ _) (s'.append s) := by
  ext
  

Proof state:
case h
α : Type u_1
β : Type u_2
n n' m : ℕ
s✝ : Sym α n
a b : α
s s' : Sym α n'
⊢ ↑(append s s') = ↑((Sym.cast (_ : n' + n' = n' + n')) (append s' s))

Next tactic:
simp [append, add_comm]
theorem mem_fill_iff {a b : α} {i : Fin (n + 1)} {s : Sym α (n - i)} :
    a ∈ Sym.fill b i s ↔ (i : ℕ) ≠ 0 ∧ a = b ∨ a ∈ s := by
  

Proof state:
α : Type u_1
β : Type u_2
n n' m : ℕ
s✝ : Sym α n
a✝ b✝ a b : α
i : Fin (n + 1)
s : Sym α (n - ↑i)
⊢ a ∈ fill b i s ↔ ↑i ≠ 0 ∧ a = b ∨ a ∈ s

Next tactic:
rw [fill, mem_cast, mem_append_iff, or_comm, mem_replicate]
/-- Remove every `a` from a given `Sym α n`.
Yields the number of copies `i` and a term of `Sym α (n - i)`. -/
def filterNe [DecidableEq α] (a : α) (m : Sym α n) : Σi : Fin (n + 1), Sym α (n - i) :=
  ⟨⟨m.1.count a, (count_le_card _ _).trans_lt <| by 

Proof state:
α : Type u_1
β : Type u_2
n n' m✝ : ℕ
s : Sym α n
a✝ b : α
inst✝ : DecidableEq α
a : α
m : Sym α n
⊢ card ↑m < n + 1

Next tactic:
rw [m.2, Nat.lt_succ_iff]
/-- Remove every `a` from a given `Sym α n`.
Yields the number of copies `i` and a term of `Sym α (n - i)`. -/
def filterNe [DecidableEq α] (a : α) (m : Sym α n) : Σi : Fin (n + 1), Sym α (n - i) :=
  ⟨⟨m.1.count a, (count_le_card _ _).trans_lt <| by rw [m.2, Nat.lt_succ_iff]⟩,
    m.1.filter (a ≠ ·),
    eq_tsub_of_add_eq <|
      Eq.trans
        (by
          

Proof state:
α : Type u_1
β : Type u_2
n n' m✝ : ℕ
s : Sym α n
a✝ b : α
inst✝ : DecidableEq α
a : α
m : Sym α n
⊢ card (filter (fun x => a ≠ x) ↑m) + ↑{ val := count a ↑m, isLt := (_ : count a ↑m < n + 1) } = card ↑m

Next tactic:
rw [← countP_eq_card_filter, add_comm]
/-- Remove every `a` from a given `Sym α n`.
Yields the number of copies `i` and a term of `Sym α (n - i)`. -/
def filterNe [DecidableEq α] (a : α) (m : Sym α n) : Σi : Fin (n + 1), Sym α (n - i) :=
  ⟨⟨m.1.count a, (count_le_card _ _).trans_lt <| by rw [m.2, Nat.lt_succ_iff]⟩,
    m.1.filter (a ≠ ·),
    eq_tsub_of_add_eq <|
      Eq.trans
        (by
          rw [← countP_eq_card_filter, add_comm]
          

Proof state:
α : Type u_1
β : Type u_2
n n' m✝ : ℕ
s : Sym α n
a✝ b : α
inst✝ : DecidableEq α
a : α
m : Sym α n
⊢ ↑{ val := count a ↑m, isLt := (_ : count a ↑m < n + 1) } + countP (fun x => a ≠ x) ↑m = card ↑m

Next tactic:
simp only [eq_comm, Ne.def, count]
/-- Remove every `a` from a given `Sym α n`.
Yields the number of copies `i` and a term of `Sym α (n - i)`. -/
def filterNe [DecidableEq α] (a : α) (m : Sym α n) : Σi : Fin (n + 1), Sym α (n - i) :=
  ⟨⟨m.1.count a, (count_le_card _ _).trans_lt <| by rw [m.2, Nat.lt_succ_iff]⟩,
    m.1.filter (a ≠ ·),
    eq_tsub_of_add_eq <|
      Eq.trans
        (by
          rw [← countP_eq_card_filter, add_comm]
          simp only [eq_comm, Ne.def, count]
          

Proof state:
α : Type u_1
β : Type u_2
n n' m✝ : ℕ
s : Sym α n
a✝ b : α
inst✝ : DecidableEq α
a : α
m : Sym α n
⊢ countP (fun x => a = x) ↑m + countP (fun x => ¬a = x) ↑m = card ↑m

Next tactic:
rw [← card_eq_countP_add_countP _ _]
theorem sigma_sub_ext {m₁ m₂ : Σi : Fin (n + 1), Sym α (n - i)} (h : (m₁.2 : Multiset α) = m₂.2) :
    m₁ = m₂ :=
  Sigma.subtype_ext
    (Fin.ext <| by
      

Proof state:
α : Type u_1
β : Type u_2
n n' m : ℕ
s : Sym α n
a b : α
m₁ m₂ : (i : Fin (n + 1)) × Sym α (n - ↑i)
h : ↑m₁.snd = ↑m₂.snd
⊢ ↑m₁.fst = ↑m₂.fst

Next tactic:
rw [← Nat.sub_sub_self (Nat.le_of_lt_succ m₁.1.is_lt), ← m₁.2.2, val_eq_coe, h,
        ← val_eq_coe, m₂.2.2, Nat.sub_sub_self (Nat.le_of_lt_succ m₂.1.is_lt)]
theorem fill_filterNe [DecidableEq α] (a : α) (m : Sym α n) :
    (m.filterNe a).2.fill a (m.filterNe a).1 = m :=
  Sym.ext
    (by
      

Proof state:
α : Type u_1
β : Type u_2
n n' m✝ : ℕ
s : Sym α n
a✝ b : α
inst✝ : DecidableEq α
a : α
m : Sym α n
⊢ ↑(fill a (filterNe a m).fst (filterNe a m).snd) = ↑m

Next tactic:
rw [coe_fill, filterNe, ← val_eq_coe, Subtype.coe_mk, Fin.val_mk]