l3lab/ntp-mathlib huggingface dataset:
/-- This rather technical-looking lemma exists because it is exactly what is needed to establish a
uniqueness result for root data. See the doc string of `Module.Dual.eq_of_preReflection_mapsTo` for
further remarks. -/
lemma Dual.eq_of_preReflection_mapsTo' [CharZero R] [NoZeroSMulDivisors R M]
    {x : M} (hx : x ≠ 0) {Φ : Set M} (hΦ₁ : Φ.Finite) (hx' : x ∈ span R Φ) {f g : Dual R M}
    (hf₁ : f x = 2) (hf₂ : MapsTo (preReflection x f) Φ Φ)
    (hg₁ : g x = 2) (hg₂ : MapsTo (preReflection x g) Φ Φ) :
    (span R Φ).subtype.dualMap f = (span R Φ).subtype.dualMap g := by
  set Φ' : Set (span R Φ) := range (inclusion <| Submodule.subset_span (R := R) (s := Φ))
  rw [← finite_coe_iff] at hΦ₁
  have hΦ'₁ : Φ'.Finite := finite_range (inclusion Submodule.subset_span)
  have hΦ'₂ : span R Φ' = ⊤ := by simp
  

Proof state:
R : Type u_1
M : Type u_2
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
x✝ : M
f✝ : Dual R M
y : M
inst✝¹ : CharZero R
inst✝ : NoZeroSMulDivisors R M
x : M
hx : x ≠ 0
Φ : Set M
hΦ₁ : _root_.Finite ↑Φ
hx' : x ∈ span R Φ
f g : Dual R M
hf₁ : f x = 2
hf₂ : MapsTo (⇑(preReflection x f)) Φ Φ
hg₁ : g x = 2
hg₂ : MapsTo (⇑(preReflection x g)) Φ Φ
Φ' : Set ↥(span R Φ) := range (inclusion (_ : Φ ⊆ ↑(span R Φ)))
hΦ'₁ : Set.Finite Φ'
hΦ'₂ : span R Φ' = ⊤
⊢ (LinearMap.dualMap (Submodule.subtype (span R Φ))) f = (LinearMap.dualMap (Submodule.subtype (span R Φ))) g

Next tactic:
let x' : span R Φ := ⟨x, hx'⟩
/-- This rather technical-looking lemma exists because it is exactly what is needed to establish a
uniqueness result for root data. See the doc string of `Module.Dual.eq_of_preReflection_mapsTo` for
further remarks. -/
lemma Dual.eq_of_preReflection_mapsTo' [CharZero R] [NoZeroSMulDivisors R M]
    {x : M} (hx : x ≠ 0) {Φ : Set M} (hΦ₁ : Φ.Finite) (hx' : x ∈ span R Φ) {f g : Dual R M}
    (hf₁ : f x = 2) (hf₂ : MapsTo (preReflection x f) Φ Φ)
    (hg₁ : g x = 2) (hg₂ : MapsTo (preReflection x g) Φ Φ) :
    (span R Φ).subtype.dualMap f = (span R Φ).subtype.dualMap g := by
  set Φ' : Set (span R Φ) := range (inclusion <| Submodule.subset_span (R := R) (s := Φ))
  rw [← finite_coe_iff] at hΦ₁
  have hΦ'₁ : Φ'.Finite := finite_range (inclusion Submodule.subset_span)
  have hΦ'₂ : span R Φ' = ⊤ := by simp
  let x' : span R Φ := ⟨x, hx'⟩
  

Proof state:
R : Type u_1
M : Type u_2
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
x✝ : M
f✝ : Dual R M
y : M
inst✝¹ : CharZero R
inst✝ : NoZeroSMulDivisors R M
x : M
hx : x ≠ 0
Φ : Set M
hΦ₁ : _root_.Finite ↑Φ
hx' : x ∈ span R Φ
f g : Dual R M
hf₁ : f x = 2
hf₂ : MapsTo (⇑(preReflection x f)) Φ Φ
hg₁ : g x = 2
hg₂ : MapsTo (⇑(preReflection x g)) Φ Φ
Φ' : Set ↥(span R Φ) := range (inclusion (_ : Φ ⊆ ↑(span R Φ)))
hΦ'₁ : Set.Finite Φ'
hΦ'₂ : span R Φ' = ⊤
x' : ↥(span R Φ) := { val := x, property := hx' }
⊢ (LinearMap.dualMap (Submodule.subtype (span R Φ))) f = (LinearMap.dualMap (Submodule.subtype (span R Φ))) g

Next tactic:
have hx' : x' ≠ 0 := Subtype.ne_of_val_ne hx
/-- This rather technical-looking lemma exists because it is exactly what is needed to establish a
uniqueness result for root data. See the doc string of `Module.Dual.eq_of_preReflection_mapsTo` for
further remarks. -/
lemma Dual.eq_of_preReflection_mapsTo' [CharZero R] [NoZeroSMulDivisors R M]
    {x : M} (hx : x ≠ 0) {Φ : Set M} (hΦ₁ : Φ.Finite) (hx' : x ∈ span R Φ) {f g : Dual R M}
    (hf₁ : f x = 2) (hf₂ : MapsTo (preReflection x f) Φ Φ)
    (hg₁ : g x = 2) (hg₂ : MapsTo (preReflection x g) Φ Φ) :
    (span R Φ).subtype.dualMap f = (span R Φ).subtype.dualMap g := by
  set Φ' : Set (span R Φ) := range (inclusion <| Submodule.subset_span (R := R) (s := Φ))
  rw [← finite_coe_iff] at hΦ₁
  have hΦ'₁ : Φ'.Finite := finite_range (inclusion Submodule.subset_span)
  have hΦ'₂ : span R Φ' = ⊤ := by simp
  let x' : span R Φ := ⟨x, hx'⟩
  have hx' : x' ≠ 0 := Subtype.ne_of_val_ne hx
  

Proof state:
R : Type u_1
M : Type u_2
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
x✝ : M
f✝ : Dual R M
y : M
inst✝¹ : CharZero R
inst✝ : NoZeroSMulDivisors R M
x : M
hx : x ≠ 0
Φ : Set M
hΦ₁ : _root_.Finite ↑Φ
hx'✝ : x ∈ span R Φ
f g : Dual R M
hf₁ : f x = 2
hf₂ : MapsTo (⇑(preReflection x f)) Φ Φ
hg₁ : g x = 2
hg₂ : MapsTo (⇑(preReflection x g)) Φ Φ
Φ' : Set ↥(span R Φ) := range (inclusion (_ : Φ ⊆ ↑(span R Φ)))
hΦ'₁ : Set.Finite Φ'
hΦ'₂ : span R Φ' = ⊤
x' : ↥(span R Φ) := { val := x, property := hx'✝ }
hx' : x' ≠ 0
⊢ (LinearMap.dualMap (Submodule.subtype (span R Φ))) f = (LinearMap.dualMap (Submodule.subtype (span R Φ))) g

Next tactic:
have this : ∀ {F : Dual R M}, MapsTo (preReflection x F) Φ Φ →
      MapsTo (preReflection x' ((span R Φ).subtype.dualMap F)) Φ' Φ' := by
    intro F hF ⟨y, hy⟩ hy'
    simp only [range_inclusion, SetLike.coe_sort_coe, mem_setOf_eq] at hy' ⊢
    exact hF hy'
/-- This rather technical-looking lemma exists because it is exactly what is needed to establish a
uniqueness result for root data. See the doc string of `Module.Dual.eq_of_preReflection_mapsTo` for
further remarks. -/
lemma Dual.eq_of_preReflection_mapsTo' [CharZero R] [NoZeroSMulDivisors R M]
    {x : M} (hx : x ≠ 0) {Φ : Set M} (hΦ₁ : Φ.Finite) (hx' : x ∈ span R Φ) {f g : Dual R M}
    (hf₁ : f x = 2) (hf₂ : MapsTo (preReflection x f) Φ Φ)
    (hg₁ : g x = 2) (hg₂ : MapsTo (preReflection x g) Φ Φ) :
    (span R Φ).subtype.dualMap f = (span R Φ).subtype.dualMap g := by
  set Φ' : Set (span R Φ) := range (inclusion <| Submodule.subset_span (R := R) (s := Φ))
  rw [← finite_coe_iff] at hΦ₁
  have hΦ'₁ : Φ'.Finite := finite_range (inclusion Submodule.subset_span)
  have hΦ'₂ : span R Φ' = ⊤ := by simp
  let x' : span R Φ := ⟨x, hx'⟩
  have hx' : x' ≠ 0 := Subtype.ne_of_val_ne hx
  have this : ∀ {F : Dual R M}, MapsTo (preReflection x F) Φ Φ →
      MapsTo (preReflection x' ((span R Φ).subtype.dualMap F)) Φ' Φ' := by
    

Proof state:
R : Type u_1
M : Type u_2
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
x✝ : M
f✝ : Dual R M
y : M
inst✝¹ : CharZero R
inst✝ : NoZeroSMulDivisors R M
x : M
hx : x ≠ 0
Φ : Set M
hΦ₁ : _root_.Finite ↑Φ
hx'✝ : x ∈ span R Φ
f g : Dual R M
hf₁ : f x = 2
hf₂ : MapsTo (⇑(preReflection x f)) Φ Φ
hg₁ : g x = 2
hg₂ : MapsTo (⇑(preReflection x g)) Φ Φ
Φ' : Set ↥(span R Φ) := range (inclusion (_ : Φ ⊆ ↑(span R Φ)))
hΦ'₁ : Set.Finite Φ'
hΦ'₂ : span R Φ' = ⊤
x' : ↥(span R Φ) := { val := x, property := hx'✝ }
hx' : x' ≠ 0
⊢ ∀ {F : Dual R M},
    MapsTo (⇑(preReflection x F)) Φ Φ →
      MapsTo (⇑(preReflection x' ((LinearMap.dualMap (Submodule.subtype (span R Φ))) F))) Φ' Φ'

Next tactic:
intro F hF ⟨y, hy⟩ hy'
/-- This rather technical-looking lemma exists because it is exactly what is needed to establish a
uniqueness result for root data. See the doc string of `Module.Dual.eq_of_preReflection_mapsTo` for
further remarks. -/
lemma Dual.eq_of_preReflection_mapsTo' [CharZero R] [NoZeroSMulDivisors R M]
    {x : M} (hx : x ≠ 0) {Φ : Set M} (hΦ₁ : Φ.Finite) (hx' : x ∈ span R Φ) {f g : Dual R M}
    (hf₁ : f x = 2) (hf₂ : MapsTo (preReflection x f) Φ Φ)
    (hg₁ : g x = 2) (hg₂ : MapsTo (preReflection x g) Φ Φ) :
    (span R Φ).subtype.dualMap f = (span R Φ).subtype.dualMap g := by
  set Φ' : Set (span R Φ) := range (inclusion <| Submodule.subset_span (R := R) (s := Φ))
  rw [← finite_coe_iff] at hΦ₁
  have hΦ'₁ : Φ'.Finite := finite_range (inclusion Submodule.subset_span)
  have hΦ'₂ : span R Φ' = ⊤ := by simp
  let x' : span R Φ := ⟨x, hx'⟩
  have hx' : x' ≠ 0 := Subtype.ne_of_val_ne hx
  have this : ∀ {F : Dual R M}, MapsTo (preReflection x F) Φ Φ →
      MapsTo (preReflection x' ((span R Φ).subtype.dualMap F)) Φ' Φ' := by
    intro F hF ⟨y, hy⟩ hy'
    

Proof state:
R : Type u_1
M : Type u_2
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
x✝ : M
f✝ : Dual R M
y✝ : M
inst✝¹ : CharZero R
inst✝ : NoZeroSMulDivisors R M
x : M
hx : x ≠ 0
Φ : Set M
hΦ₁ : _root_.Finite ↑Φ
hx'✝ : x ∈ span R Φ
f g : Dual R M
hf₁ : f x = 2
hf₂ : MapsTo (⇑(preReflection x f)) Φ Φ
hg₁ : g x = 2
hg₂ : MapsTo (⇑(preReflection x g)) Φ Φ
Φ' : Set ↥(span R Φ) := range (inclusion (_ : Φ ⊆ ↑(span R Φ)))
hΦ'₁ : Set.Finite Φ'
hΦ'₂ : span R Φ' = ⊤
x' : ↥(span R Φ) := { val := x, property := hx'✝ }
hx' : x' ≠ 0
F : Dual R M
hF : MapsTo (⇑(preReflection x F)) Φ Φ
y : M
hy : y ∈ span R Φ
hy' : { val := y, property := hy } ∈ Φ'
⊢ (preReflection x' ((LinearMap.dualMap (Submodule.subtype (span R Φ))) F)) { val := y, property := hy } ∈ Φ'

Next tactic:
simp only [range_inclusion, SetLike.coe_sort_coe, mem_setOf_eq] at hy' ⊢
/-- This rather technical-looking lemma exists because it is exactly what is needed to establish a
uniqueness result for root data. See the doc string of `Module.Dual.eq_of_preReflection_mapsTo` for
further remarks. -/
lemma Dual.eq_of_preReflection_mapsTo' [CharZero R] [NoZeroSMulDivisors R M]
    {x : M} (hx : x ≠ 0) {Φ : Set M} (hΦ₁ : Φ.Finite) (hx' : x ∈ span R Φ) {f g : Dual R M}
    (hf₁ : f x = 2) (hf₂ : MapsTo (preReflection x f) Φ Φ)
    (hg₁ : g x = 2) (hg₂ : MapsTo (preReflection x g) Φ Φ) :
    (span R Φ).subtype.dualMap f = (span R Φ).subtype.dualMap g := by
  set Φ' : Set (span R Φ) := range (inclusion <| Submodule.subset_span (R := R) (s := Φ))
  rw [← finite_coe_iff] at hΦ₁
  have hΦ'₁ : Φ'.Finite := finite_range (inclusion Submodule.subset_span)
  have hΦ'₂ : span R Φ' = ⊤ := by simp
  let x' : span R Φ := ⟨x, hx'⟩
  have hx' : x' ≠ 0 := Subtype.ne_of_val_ne hx
  have this : ∀ {F : Dual R M}, MapsTo (preReflection x F) Φ Φ →
      MapsTo (preReflection x' ((span R Φ).subtype.dualMap F)) Φ' Φ' := by
    intro F hF ⟨y, hy⟩ hy'
    simp only [range_inclusion, SetLike.coe_sort_coe, mem_setOf_eq] at hy' ⊢
    

Proof state:
R : Type u_1
M : Type u_2
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
x✝ : M
f✝ : Dual R M
y✝ : M
inst✝¹ : CharZero R
inst✝ : NoZeroSMulDivisors R M
x : M
hx : x ≠ 0
Φ : Set M
hΦ₁ : _root_.Finite ↑Φ
hx'✝ : x ∈ span R Φ
f g : Dual R M
hf₁ : f x = 2
hf₂ : MapsTo (⇑(preReflection x f)) Φ Φ
hg₁ : g x = 2
hg₂ : MapsTo (⇑(preReflection x g)) Φ Φ
Φ' : Set ↥(span R Φ) := range (inclusion (_ : Φ ⊆ ↑(span R Φ)))
hΦ'₁ : Set.Finite Φ'
hΦ'₂ : span R Φ' = ⊤
x' : ↥(span R Φ) := { val := x, property := hx'✝ }
hx' : x' ≠ 0
F : Dual R M
hF : MapsTo (⇑(preReflection x F)) Φ Φ
y : M
hy : y ∈ span R Φ
hy' : y ∈ Φ
⊢ ↑((preReflection { val := x, property := hx'✝ } ((LinearMap.dualMap (Submodule.subtype (span R Φ))) F))
        { val := y, property := hy }) ∈
    Φ

Next tactic:
exact hF hy'
/-- This rather technical-looking lemma exists because it is exactly what is needed to establish a
uniqueness result for root data. See the doc string of `Module.Dual.eq_of_preReflection_mapsTo` for
further remarks. -/
lemma Dual.eq_of_preReflection_mapsTo' [CharZero R] [NoZeroSMulDivisors R M]
    {x : M} (hx : x ≠ 0) {Φ : Set M} (hΦ₁ : Φ.Finite) (hx' : x ∈ span R Φ) {f g : Dual R M}
    (hf₁ : f x = 2) (hf₂ : MapsTo (preReflection x f) Φ Φ)
    (hg₁ : g x = 2) (hg₂ : MapsTo (preReflection x g) Φ Φ) :
    (span R Φ).subtype.dualMap f = (span R Φ).subtype.dualMap g := by
  set Φ' : Set (span R Φ) := range (inclusion <| Submodule.subset_span (R := R) (s := Φ))
  rw [← finite_coe_iff] at hΦ₁
  have hΦ'₁ : Φ'.Finite := finite_range (inclusion Submodule.subset_span)
  have hΦ'₂ : span R Φ' = ⊤ := by simp
  let x' : span R Φ := ⟨x, hx'⟩
  have hx' : x' ≠ 0 := Subtype.ne_of_val_ne hx
  have this : ∀ {F : Dual R M}, MapsTo (preReflection x F) Φ Φ →
      MapsTo (preReflection x' ((span R Φ).subtype.dualMap F)) Φ' Φ' := by
    intro F hF ⟨y, hy⟩ hy'
    simp only [range_inclusion, SetLike.coe_sort_coe, mem_setOf_eq] at hy' ⊢
    exact hF hy'
  

Proof state:
R : Type u_1
M : Type u_2
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
x✝ : M
f✝ : Dual R M
y : M
inst✝¹ : CharZero R
inst✝ : NoZeroSMulDivisors R M
x : M
hx : x ≠ 0
Φ : Set M
hΦ₁ : _root_.Finite ↑Φ
hx'✝ : x ∈ span R Φ
f g : Dual R M
hf₁ : f x = 2
hf₂ : MapsTo (⇑(preReflection x f)) Φ Φ
hg₁ : g x = 2
hg₂ : MapsTo (⇑(preReflection x g)) Φ Φ
Φ' : Set ↥(span R Φ) := range (inclusion (_ : Φ ⊆ ↑(span R Φ)))
hΦ'₁ : Set.Finite Φ'
hΦ'₂ : span R Φ' = ⊤
x' : ↥(span R Φ) := { val := x, property := hx'✝ }
hx' : x' ≠ 0
this :
  ∀ {F : Dual R M},
    MapsTo (⇑(preReflection x F)) Φ Φ →
      MapsTo (⇑(preReflection x' ((LinearMap.dualMap (Submodule.subtype (span R Φ))) F))) Φ' Φ'
⊢ (LinearMap.dualMap (Submodule.subtype (span R Φ))) f = (LinearMap.dualMap (Submodule.subtype (span R Φ))) g

Next tactic:
exact eq_of_preReflection_mapsTo hx' hΦ'₁ hΦ'₂ hf₁ (this hf₂) hg₁ (this hg₂)
/-- A pair `(t₁, t₂)` of multisets is contained in `antidiagonal s`
    if and only if `t₁ + t₂ = s`. -/
@[simp]
theorem mem_antidiagonal {s : Multiset α} {x : Multiset α × Multiset α} :
    x ∈ antidiagonal s ↔ x.1 + x.2 = s :=
  Quotient.inductionOn s <| fun l ↦ by
    

Proof state:
α : Type u_1
β : Type u_2
s : Multiset α
x : Multiset α × Multiset α
l : List α
⊢ x ∈ antidiagonal ⟦l⟧ ↔ x.1 + x.2 = ⟦l⟧

Next tactic:
dsimp only [quot_mk_to_coe, antidiagonal_coe]
/-- A pair `(t₁, t₂)` of multisets is contained in `antidiagonal s`
    if and only if `t₁ + t₂ = s`. -/
@[simp]
theorem mem_antidiagonal {s : Multiset α} {x : Multiset α × Multiset α} :
    x ∈ antidiagonal s ↔ x.1 + x.2 = s :=
  Quotient.inductionOn s <| fun l ↦ by
    dsimp only [quot_mk_to_coe, antidiagonal_coe]
    

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

Next tactic:
refine' ⟨fun h => revzip_powersetAux h, fun h ↦ _⟩
/-- A pair `(t₁, t₂)` of multisets is contained in `antidiagonal s`
    if and only if `t₁ + t₂ = s`. -/
@[simp]
theorem mem_antidiagonal {s : Multiset α} {x : Multiset α × Multiset α} :
    x ∈ antidiagonal s ↔ x.1 + x.2 = s :=
  Quotient.inductionOn s <| fun l ↦ by
    dsimp only [quot_mk_to_coe, antidiagonal_coe]
    refine' ⟨fun h => revzip_powersetAux h, fun h ↦ _⟩
    

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

Next tactic:
haveI := Classical.decEq α
/-- A pair `(t₁, t₂)` of multisets is contained in `antidiagonal s`
    if and only if `t₁ + t₂ = s`. -/
@[simp]
theorem mem_antidiagonal {s : Multiset α} {x : Multiset α × Multiset α} :
    x ∈ antidiagonal s ↔ x.1 + x.2 = s :=
  Quotient.inductionOn s <| fun l ↦ by
    dsimp only [quot_mk_to_coe, antidiagonal_coe]
    refine' ⟨fun h => revzip_powersetAux h, fun h ↦ _⟩
    haveI := Classical.decEq α
    

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

Next tactic:
simp only [revzip_powersetAux_lemma l revzip_powersetAux, h.symm, ge_iff_le, mem_coe,
      List.mem_map, mem_powersetAux]
/-- A pair `(t₁, t₂)` of multisets is contained in `antidiagonal s`
    if and only if `t₁ + t₂ = s`. -/
@[simp]
theorem mem_antidiagonal {s : Multiset α} {x : Multiset α × Multiset α} :
    x ∈ antidiagonal s ↔ x.1 + x.2 = s :=
  Quotient.inductionOn s <| fun l ↦ by
    dsimp only [quot_mk_to_coe, antidiagonal_coe]
    refine' ⟨fun h => revzip_powersetAux h, fun h ↦ _⟩
    haveI := Classical.decEq α
    simp only [revzip_powersetAux_lemma l revzip_powersetAux, h.symm, ge_iff_le, mem_coe,
      List.mem_map, mem_powersetAux]
    

Proof state:
α : Type u_1
β : Type u_2
s : Multiset α
x : Multiset α × Multiset α
l : List α
h : x.1 + x.2 = ↑l
this : DecidableEq α
⊢ ∃ a ≤ x.1 + x.2, (a, x.1 + x.2 - a) = x

Next tactic:
cases' x with x₁ x₂
/-- A pair `(t₁, t₂)` of multisets is contained in `antidiagonal s`
    if and only if `t₁ + t₂ = s`. -/
@[simp]
theorem mem_antidiagonal {s : Multiset α} {x : Multiset α × Multiset α} :
    x ∈ antidiagonal s ↔ x.1 + x.2 = s :=
  Quotient.inductionOn s <| fun l ↦ by
    dsimp only [quot_mk_to_coe, antidiagonal_coe]
    refine' ⟨fun h => revzip_powersetAux h, fun h ↦ _⟩
    haveI := Classical.decEq α
    simp only [revzip_powersetAux_lemma l revzip_powersetAux, h.symm, ge_iff_le, mem_coe,
      List.mem_map, mem_powersetAux]
    cases' x with x₁ x₂
    

Proof state:
case mk
α : Type u_1
β : Type u_2
s : Multiset α
l : List α
this : DecidableEq α
x₁ x₂ : Multiset α
h : (x₁, x₂).1 + (x₁, x₂).2 = ↑l
⊢ ∃ a ≤ (x₁, x₂).1 + (x₁, x₂).2, (a, (x₁, x₂).1 + (x₁, x₂).2 - a) = (x₁, x₂)

Next tactic:
exact ⟨x₁, le_add_right _ _, by rw [add_tsub_cancel_left x₁ x₂]⟩
/-- A pair `(t₁, t₂)` of multisets is contained in `antidiagonal s`
    if and only if `t₁ + t₂ = s`. -/
@[simp]
theorem mem_antidiagonal {s : Multiset α} {x : Multiset α × Multiset α} :
    x ∈ antidiagonal s ↔ x.1 + x.2 = s :=
  Quotient.inductionOn s <| fun l ↦ by
    dsimp only [quot_mk_to_coe, antidiagonal_coe]
    refine' ⟨fun h => revzip_powersetAux h, fun h ↦ _⟩
    haveI := Classical.decEq α
    simp only [revzip_powersetAux_lemma l revzip_powersetAux, h.symm, ge_iff_le, mem_coe,
      List.mem_map, mem_powersetAux]
    cases' x with x₁ x₂
    exact ⟨x₁, le_add_right _ _, by 

Proof state:
α : Type u_1
β : Type u_2
s : Multiset α
l : List α
this : DecidableEq α
x₁ x₂ : Multiset α
h : (x₁, x₂).1 + (x₁, x₂).2 = ↑l
⊢ (x₁, (x₁, x₂).1 + (x₁, x₂).2 - x₁) = (x₁, x₂)

Next tactic:
rw [add_tsub_cancel_left x₁ x₂]
@[simp]
theorem antidiagonal_map_fst (s : Multiset α) : (antidiagonal s).map Prod.fst = powerset s :=
  Quotient.inductionOn s <| fun l ↦ by 

Proof state:
α : Type u_1
β : Type u_2
s : Multiset α
l : List α
⊢ map Prod.fst (antidiagonal ⟦l⟧) = powerset ⟦l⟧

Next tactic:
simp [powersetAux']
@[simp]
theorem antidiagonal_map_snd (s : Multiset α) : (antidiagonal s).map Prod.snd = powerset s :=
  Quotient.inductionOn s <| fun l ↦ by 

Proof state:
α : Type u_1
β : Type u_2
s : Multiset α
l : List α
⊢ map Prod.snd (antidiagonal ⟦l⟧) = powerset ⟦l⟧

Next tactic:
simp [powersetAux']
@[simp]
theorem antidiagonal_cons (a : α) (s) :
    antidiagonal (a ::ₘ s) =
      map (Prod.map id (cons a)) (antidiagonal s) + map (Prod.map (cons a) id) (antidiagonal s) :=
  Quotient.inductionOn s <| fun l ↦ by
    

Proof state:
α : Type u_1
β : Type u_2
a : α
s : Multiset α
l : List α
⊢ antidiagonal (a ::ₘ ⟦l⟧) =
    map (Prod.map id (cons a)) (antidiagonal ⟦l⟧) + map (Prod.map (cons a) id) (antidiagonal ⟦l⟧)

Next tactic:
simp only [revzip, reverse_append, quot_mk_to_coe, coe_eq_coe, powersetAux'_cons, cons_coe,
      coe_map, antidiagonal_coe', coe_add]
@[simp]
theorem antidiagonal_cons (a : α) (s) :
    antidiagonal (a ::ₘ s) =
      map (Prod.map id (cons a)) (antidiagonal s) + map (Prod.map (cons a) id) (antidiagonal s) :=
  Quotient.inductionOn s <| fun l ↦ by
    simp only [revzip, reverse_append, quot_mk_to_coe, coe_eq_coe, powersetAux'_cons, cons_coe,
      coe_map, antidiagonal_coe', coe_add]
    

Proof state:
α : Type u_1
β : Type u_2
a : α
s : Multiset α
l : List α
⊢ zip (powersetAux' l ++ List.map (cons a) (powersetAux' l))
      (reverse (List.map (cons a) (powersetAux' l)) ++ reverse (powersetAux' l)) ~
    List.map (fun x => Prod.map id (cons a) x) (zip (powersetAux' l) (reverse (powersetAux' l))) ++
      List.map (fun x => Prod.map (cons a) id x) (zip (powersetAux' l) (reverse (powersetAux' l)))

Next tactic:
rw [← zip_map, ← zip_map, zip_append, (_ : _ ++ _ = _)]
@[simp]
theorem antidiagonal_cons (a : α) (s) :
    antidiagonal (a ::ₘ s) =
      map (Prod.map id (cons a)) (antidiagonal s) + map (Prod.map (cons a) id) (antidiagonal s) :=
  Quotient.inductionOn s <| fun l ↦ by
    simp only [revzip, reverse_append, quot_mk_to_coe, coe_eq_coe, powersetAux'_cons, cons_coe,
      coe_map, antidiagonal_coe', coe_add]
    rw [← zip_map, ← zip_map, zip_append, (_ : _ ++ _ = _)]
    · 

Proof state:
α : Type u_1
β : Type u_2
a : α
s : Multiset α
l : List α
⊢ zip (powersetAux' l) (reverse (List.map (cons a) (powersetAux' l))) ++
      zip (List.map (cons a) (powersetAux' l)) (reverse (powersetAux' l)) =
    zip (List.map id (powersetAux' l)) (List.map (cons a) (reverse (powersetAux' l))) ++
      zip (List.map (cons a) (powersetAux' l)) (List.map id (reverse (powersetAux' l)))

Next tactic:
congr
@[simp]
theorem antidiagonal_cons (a : α) (s) :
    antidiagonal (a ::ₘ s) =
      map (Prod.map id (cons a)) (antidiagonal s) + map (Prod.map (cons a) id) (antidiagonal s) :=
  Quotient.inductionOn s <| fun l ↦ by
    simp only [revzip, reverse_append, quot_mk_to_coe, coe_eq_coe, powersetAux'_cons, cons_coe,
      coe_map, antidiagonal_coe', coe_add]
    rw [← zip_map, ← zip_map, zip_append, (_ : _ ++ _ = _)]
    · congr; 

Proof state:
case e_a.e_a
α : Type u_1
β : Type u_2
a : α
s : Multiset α
l : List α
⊢ powersetAux' l = List.map id (powersetAux' l)
case e_a.e_a
α : Type u_1
β : Type u_2
a : α
s : Multiset α
l : List α
⊢ reverse (List.map (cons a) (powersetAux' l)) = List.map (cons a) (reverse (powersetAux' l))
case e_a.e_a
α : Type u_1
β : Type u_2
a : α
s : Multiset α
l : List α
⊢ reverse (powersetAux' l) = List.map id (reverse (powersetAux' l))

Next tactic:
simp
@[simp]
theorem antidiagonal_cons (a : α) (s) :
    antidiagonal (a ::ₘ s) =
      map (Prod.map id (cons a)) (antidiagonal s) + map (Prod.map (cons a) id) (antidiagonal s) :=
  Quotient.inductionOn s <| fun l ↦ by
    simp only [revzip, reverse_append, quot_mk_to_coe, coe_eq_coe, powersetAux'_cons, cons_coe,
      coe_map, antidiagonal_coe', coe_add]
    rw [← zip_map, ← zip_map, zip_append, (_ : _ ++ _ = _)]
    · congr; simp; 

Proof state:
case e_a.e_a
α : Type u_1
β : Type u_2
a : α
s : Multiset α
l : List α
⊢ reverse (List.map (cons a) (powersetAux' l)) = List.map (cons a) (reverse (powersetAux' l))
case e_a.e_a
α : Type u_1
β : Type u_2
a : α
s : Multiset α
l : List α
⊢ reverse (powersetAux' l) = List.map id (reverse (powersetAux' l))

Next tactic:
rw [map_reverse]
@[simp]
theorem antidiagonal_cons (a : α) (s) :
    antidiagonal (a ::ₘ s) =
      map (Prod.map id (cons a)) (antidiagonal s) + map (Prod.map (cons a) id) (antidiagonal s) :=
  Quotient.inductionOn s <| fun l ↦ by
    simp only [revzip, reverse_append, quot_mk_to_coe, coe_eq_coe, powersetAux'_cons, cons_coe,
      coe_map, antidiagonal_coe', coe_add]
    rw [← zip_map, ← zip_map, zip_append, (_ : _ ++ _ = _)]
    · congr; simp; rw [map_reverse]; 

Proof state:
case e_a.e_a
α : Type u_1
β : Type u_2
a : α
s : Multiset α
l : List α
⊢ reverse (powersetAux' l) = List.map id (reverse (powersetAux' l))

Next tactic:
simp
@[simp]
theorem antidiagonal_cons (a : α) (s) :
    antidiagonal (a ::ₘ s) =
      map (Prod.map id (cons a)) (antidiagonal s) + map (Prod.map (cons a) id) (antidiagonal s) :=
  Quotient.inductionOn s <| fun l ↦ by
    simp only [revzip, reverse_append, quot_mk_to_coe, coe_eq_coe, powersetAux'_cons, cons_coe,
      coe_map, antidiagonal_coe', coe_add]
    rw [← zip_map, ← zip_map, zip_append, (_ : _ ++ _ = _)]
    · congr; simp; rw [map_reverse]; simp
    · 

Proof state:
α : Type u_1
β : Type u_2
a : α
s : Multiset α
l : List α
⊢ length (powersetAux' l) = length (reverse (List.map (cons a) (powersetAux' l)))

Next tactic:
simp
theorem antidiagonal_eq_map_powerset [DecidableEq α] (s : Multiset α) :
    s.antidiagonal = s.powerset.map fun t ↦ (s - t, t) := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
s : Multiset α
⊢ antidiagonal s = map (fun t => (s - t, t)) (powerset s)

Next tactic:
induction' s using Multiset.induction_on with a s hs
theorem antidiagonal_eq_map_powerset [DecidableEq α] (s : Multiset α) :
    s.antidiagonal = s.powerset.map fun t ↦ (s - t, t) := by
  induction' s using Multiset.induction_on with a s hs
  · 

Proof state:
case empty
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
⊢ antidiagonal 0 = map (fun t => (0 - t, t)) (powerset 0)

Next tactic:
simp only [antidiagonal_zero, powerset_zero, zero_tsub, map_singleton]
theorem antidiagonal_eq_map_powerset [DecidableEq α] (s : Multiset α) :
    s.antidiagonal = s.powerset.map fun t ↦ (s - t, t) := by
  induction' s using Multiset.induction_on with a s hs
  · simp only [antidiagonal_zero, powerset_zero, zero_tsub, map_singleton]
  · 

Proof state:
case cons
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
a : α
s : Multiset α
hs : antidiagonal s = map (fun t => (s - t, t)) (powerset s)
⊢ antidiagonal (a ::ₘ s) = map (fun t => (a ::ₘ s - t, t)) (powerset (a ::ₘ s))

Next tactic:
simp_rw [antidiagonal_cons, powerset_cons, map_add, hs, map_map, Function.comp, Prod.map_mk,
      id.def, sub_cons, erase_cons_head]